22d7ce43ff7705e16dce7512fb4eef136971b77d — octaspire 8 days ago v0.457.0
Stdlib: add 'cos' and 'sin' functions, Bounce: add level pass effects
M dev/include/octaspire/dern/octaspire_dern_config.h => dev/include/octaspire/dern/octaspire_dern_config.h +1 -1
@@ 18,7 18,7 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "456"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "457"
  #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \

M dev/include/octaspire/dern/octaspire_dern_stdlib.h => dev/include/octaspire/dern/octaspire_dern_stdlib.h +10 -0
@@ 222,6 222,16 @@ octaspire_dern_value_t *arguments,
      octaspire_dern_value_t *environment);
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_cos(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sin(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,

M dev/src/octaspire_dern_stdlib.c => dev/src/octaspire_dern_stdlib.c +108 -0
@@ 6005,6 6005,114 @@ return smallestArgVal;
  }
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_cos(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "cos";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 1;
+ 
+     if (numArgs < numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * argVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(argVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(argVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(argVal->typeTag));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         cos(octaspire_dern_value_as_number_get_value(argVal)));
+ }
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sin(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "sin";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 1;
+ 
+     if (numArgs < numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * argVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(argVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(argVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(argVal->typeTag));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         sin(octaspire_dern_value_as_number_get_value(argVal)));
+ }
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,

M dev/src/octaspire_dern_vm.c => dev/src/octaspire_dern_vm.c +26 -0
@@ 863,6 863,32 @@ abort();
      }
  
+     // cos
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "cos",
+         octaspire_dern_vm_builtin_cos,
+         1,
+         "Return cosine of the argument (measured in radians)",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
+     // sin
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "sin",
+         octaspire_dern_vm_builtin_sin,
+         1,
+         "Return sine of the argument (measured in radians)",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
      // +=
      if (!octaspire_dern_vm_create_and_register_new_builtin(
          self,

M release/games/octaspire-bounce.dern => release/games/octaspire-bounce.dern +69 -17
@@ 1,5 1,6 @@-(require 'dern_sdl2)
  (require 'dern_chipmunk)
+ (require 'dern_easing)
+ (require 'dern_sdl2)
  
  (sdl2-Init 'VIDEO)
  


@@ 286,10 287,22 @@ (define bounce-level-index as {D+0} [current level index])
  (define bounce-level-count as {D+2} [total number of levels])
  
+ (define bounce-level-passed as false [is level passed])
+ (define bounce-pass-star-delta as {D+0} [helper variable for star effect])
+ (define bounce-pass-star-alpha as {D+0} [helper variable for star effect])
+ 
+ (define bounce-level-pass as (fn ()
+   (= bounce-level-passed true)
+   (easing-add 'out-expo bounce-pass-star-alpha {X+0} {X+FF}  {D+3} [])
+   (easing-add 'out-expo bounce-pass-star-delta {D+0} {D+100} {D+5} [(bounce-level-next)]))
+   [show level passed animations] '() howto-no)
+ 
  (define bounce-level-next as (fn ()
    (++ bounce-level-index)
    (= bounce-level-index (mod bounce-level-index bounce-level-count))
-   (println [next level {}] bounce-level-index)
+   (= bounce-level-passed false)
+   (= bounce-pass-star-delta {D+0})
+   (= bounce-pass-star-alpha {D+0})
    (bounce-level-load bounce-level-index))
    [load next level or the first all passed] '() howto-no)
  


@@ 316,7 329,7 @@   (define bounce-star-angle as {D+0} [angle of the star])
  
- (define bounce-render as (fn ()
+ (define bounce-render-game as (fn ()
    (define bounce-ball-pos as (chipmunk-cpBodyGetPosition bounce-ball) [position of the ball])
    (define ball-x          as (* {D+10} (chipmunk-cpv-get-x bounce-ball-pos)) [x component])
    (define ball-y          as (* {D+10} (chipmunk-cpv-get-y bounce-ball-pos)) [y component])


@@ 337,7 350,28 @@ (bounce-slope-draw i))
    (sdl2-glColor4ub {X+99} {X+FF} {X+0} {X+FF})
    (sdl2-gl-ortho-star-rotated {D+1470} {D+1145} {D+40} {D+5} bounce-star-angle)
-   (sdl2-glColor4ub {X+FF} {X+FF} {X+FF} {X+FF})
+   (sdl2-glColor4ub {X+FF} {X+FF} {X+FF} {X+FF}))
+   [render game] '() howto-no)
+ 
+ (define bounce-render-pass as (fn ()
+   (bounce-render-game)
+   (define x as {D+1470} [x])
+   (define y as {D+1145} [y])
+   (define delta as bounce-pass-star-delta [star movement])
+   (define angle as (* {D+0.5} bounce-star-angle) [angle])
+   (define num-stars as {D+8} [number of stars])
+   (define star-step as (/ {D+6.28318530718} num-stars) [angle per star])
+   (sdl2-glColor4ub {X+99} {X+FF} {X+0} bounce-pass-star-alpha)
+   (for i from {D+0} to num-stars
+     (define tmp-angle as (* i star-step) [angle for this loop iteration])
+     (sdl2-gl-ortho-star-rotated (+ x (* delta (cos tmp-angle))) (+ y (* delta (sin tmp-angle))) {D+30} {D+5} angle))
+   (sdl2-glColor4ub {X+FF} {X+FF} {X+FF} {X+FF}))
+   [render level passed effects] '() howto-no)
+ 
+ (define bounce-render as (fn ()
+   (if bounce-level-passed
+         (bounce-render-pass)
+     (bounce-render-game))
    (sdl2-GL-SwapWindow bounce-window))
    [render] '() howto-no)
  


@@ 351,7 385,8 @@ key while a jump key is held down cancels the jump. !#
  (define current-jump-key as [] [currently held jump key, if any])
  
- (define bounce-handle-keydown as (fn (key)
+ (define bounce-handle-keydown as (fn (event)
+   (define key as (ln@ event {D+1}) [key])
    (if (ln@ event {D+4}) (return)) ; don't handle repeat events.
    (if (== key [r]) (do (bounce-game-over) (return)))
    (if (not bounce-ball-on-platform) (return))


@@ 360,30 395,27 @@ (= current-jump-key key)
          (= bounce-key-down-duration (ln@ event {D+3})))
        (= current-jump-key [])))
-   [handle keydown-event] '(key [key]) howto-no)
+   [handle keydown-event] '(event [event]) howto-no)
  
- (define bounce-handle-keyup as (fn (key)
+ (define bounce-handle-keyup as (fn (event)
+   (define key as (ln@ event {D+1}) [key])
    (if (not bounce-ball-on-platform) (return))
    (if (== key current-jump-key)
        (do
          (= bounce-key-down-duration (- (ln@ event {D+3}) bounce-key-down-duration))
          (= current-jump-key [])
          (bounce-ball-apply-impulse (chipmunk-cpv {D+0} (min (/ bounce-key-down-duration {D+3}) {D+250}))))))
-   [handle keydup-event] '(key [key]) howto-no)
+   [handle keydup-event] '(event [event]) howto-no)
  
- (while bounce-running
-   (sdl2-TimerUpdate)
-   (define dt as (sdl2-TimerGetSeconds) [dt])
-   (sdl2-TimerReset)
-   (bounce-render)
+ (define bounce-update-game as (fn (dt)
    (+= bounce-star-angle {D+0.02})
    (if (< bounce-window-zoom {D+1}) (+= bounce-window-zoom {D+0.05}))
    (define event as (sdl2-PollEvent) [event from sdl2])
    (define type  as nil [type of event])
    (if (and (!= event nil) (> (len event) {D+0})) (= type (ln@ event {D+0})))
    (select (== type 'QUIT)    (= bounce-running false)
-           (== type 'KEYDOWN) (bounce-handle-keydown (ln@ event {D+1}))
-           (== type 'KEYUP)   (bounce-handle-keyup   (ln@ event {D+1})))
+           (== type 'KEYDOWN) (bounce-handle-keydown event)
+           (== type 'KEYUP)   (bounce-handle-keyup   event))
    (for i in bounce-platforms
      (bounce-platform-update i))
    (chipmunk-cpSpaceStep bounce-space {D+0.01})


@@ 391,12 423,32 @@ (define ball-x   as (chipmunk-cpv-get-x ball-pos) [x component])
    (define ball-y   as (chipmunk-cpv-get-y ball-pos) [y component])
    (if (< ball-y {D-240}) (bounce-game-over))
-   (if (and (> ball-x {D+135}) (< ball-x {D+160}) (> ball-y {D+130}) (< ball-y {D+160})) (bounce-level-next))
+   (if (and (> ball-x {D+135}) (< ball-x {D+160}) (> ball-y {D+130}) (< ball-y {D+160})) (bounce-level-pass)))
+   [update game] '(dt [dt]) howto-no)
+ 
+ (define bounce-update-pass as (fn (dt)
+   (easing-update {D+0.02})
+   (+= bounce-star-angle {D+0.02}))
+   [update level pass effects] '(dt [dt]) howto-no)
+ 
+ (define bounce-update as (fn (dt)
+     (if bounce-level-passed
+         (bounce-update-pass dt)
+       (bounce-update-game dt)))
+   [update] '(dt [dt]) howto-no)
+ 
+ (while bounce-running
+   (sdl2-TimerUpdate)
+   (define dt as (sdl2-TimerGetSeconds) [dt])
+   (sdl2-TimerReset)
+   (bounce-render)
+   (bounce-update dt)
    (sdl2-TimerUpdate)
    (define current-frame-duration as (sdl2-TimerGetSeconds) [current frame duration])
    (if (> bounce-target-frame-duration current-frame-duration) (do
      (define delay-in-seconds as (- bounce-target-frame-duration current-frame-duration) [time to sleep])
      (if (> delay-in-seconds {D+0})
-       (sdl2-Delay delay-in-seconds)))))
+         (sdl2-Delay delay-in-seconds))))
+   (= dt (sdl2-TimerGetSeconds)))
  
  (sdl2-Quit)

M release/octaspire-dern-amalgamated.c => release/octaspire-dern-amalgamated.c +145 -1
@@ 26214,7 26214,7 @@ #define OCTASPIRE_DERN_CONFIG_H
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_MAJOR "0"
- #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "456"
+ #define OCTASPIRE_DERN_CONFIG_VERSION_MINOR "457"
  #define OCTASPIRE_DERN_CONFIG_VERSION_PATCH "0"
  
  #define OCTASPIRE_DERN_CONFIG_VERSION_STR "Octaspire Dern version " \


@@ 28156,6 28156,16 @@ octaspire_dern_value_t *arguments,
      octaspire_dern_value_t *environment);
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_cos(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sin(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment);
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,


@@ 39717,6 39727,114 @@ return smallestArgVal;
  }
  
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_cos(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "cos";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 1;
+ 
+     if (numArgs < numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * argVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(argVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(argVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(argVal->typeTag));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         cos(octaspire_dern_value_as_number_get_value(argVal)));
+ }
+ 
+ octaspire_dern_value_t *octaspire_dern_vm_builtin_sin(
+     octaspire_dern_vm_t *vm,
+     octaspire_dern_value_t *arguments,
+     octaspire_dern_value_t *environment)
+ {
+     size_t const stackLength = octaspire_dern_vm_get_stack_length(vm);
+ 
+     octaspire_helpers_verify_true(
+         arguments->typeTag == OCTASPIRE_DERN_VALUE_TAG_VECTOR);
+ 
+     octaspire_helpers_verify_true(
+         environment->typeTag == OCTASPIRE_DERN_VALUE_TAG_ENVIRONMENT);
+ 
+     char   const * const dernFuncName = "sin";
+     size_t const numArgs = octaspire_dern_value_get_length(arguments);
+     size_t const numExpectedArgs = 1;
+ 
+     if (numArgs < numExpectedArgs)
+     {
+         octaspire_helpers_verify_true(
+             stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "Builtin '%s' expects %zu arguments. "
+             "%zu arguments were given.",
+             dernFuncName,
+             numExpectedArgs,
+             numArgs);
+     }
+ 
+     octaspire_dern_value_t * argVal =
+         octaspire_dern_value_as_vector_get_element_at(arguments, 0);
+ 
+     octaspire_helpers_verify_not_null(argVal);
+ 
+     octaspire_helpers_verify_true(
+         stackLength == octaspire_dern_vm_get_stack_length(vm));
+ 
+     if (!octaspire_dern_value_is_number(argVal))
+     {
+         return octaspire_dern_vm_create_new_value_error_format(
+             vm,
+             "First argument to builtin '%s' should be a number. "
+             "Type '%s' was given.",
+             dernFuncName,
+             octaspire_dern_value_helper_get_type_as_c_string(argVal->typeTag));
+     }
+ 
+     return octaspire_dern_vm_create_new_value_real(
+         vm,
+         sin(octaspire_dern_value_as_number_get_value(argVal)));
+ }
+ 
  octaspire_dern_value_t *octaspire_dern_vm_builtin_plus_equals(
      octaspire_dern_vm_t *vm,
      octaspire_dern_value_t *arguments,


@@ 49051,6 49169,32 @@ abort();
      }
  
+     // cos
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "cos",
+         octaspire_dern_vm_builtin_cos,
+         1,
+         "Return cosine of the argument (measured in radians)",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
+     // sin
+     if (!octaspire_dern_vm_create_and_register_new_builtin(
+         self,
+         "sin",
+         octaspire_dern_vm_builtin_sin,
+         1,
+         "Return sine of the argument (measured in radians)",
+         false,
+         env))
+     {
+         abort();
+     }
+ 
      // +=
      if (!octaspire_dern_vm_create_and_register_new_builtin(
          self,