* Will be the dereference operator but address will remain @
Category: BooBoo
-
I will be adding constants
All the so called constants will be real constants. const will be the same as var except it will take a constant value after the variable name. This only affects the = operation as builtins can still change constants if they don’t check, however none of the builtin API will do so, so they will effectively be constant.
-
BooBoo 3.0.1
- Add -limits command line switch to disable instruction per second limit
- Add rest of casts (vector, map, function, label, pointer)
- Fix joystick events
-
New additions to BooBoo
There are now 2 and will currently be more casts. e.g.:
var foo /* ... some code where foo may or may not be converted to a vector, like vector_add but foo may still never have been set */ some_func fooIf some_func is expecting a vector and foo hasn’t been typed to vector yet, this might create an error depending what some_func does. So to get around this you can use:
some_func (vector foo)Or:
/* this way, setting it right away is preferable to avoid a vector copy */ var foo = foo (vector foo)number and string already exist in 3.0.0. 3.0.1 will have vector, map, function, label and pointer.
-
BooBoo 3.0.0 is released
- Fix broken joystick
- Add srand and time
- Move all builtins that return values to expression ops
- Remove some examples, update the rest to new API (and fix some bugs)
- Ditched type safety, var is now used to declare all variables
- Add instructions per second counter with +debug command line switch (and a font)
As I said, I would be limiting operations per second. CoinHunt blows away everything else at 6 million instructions per second while firing rapidly. It can be designed much better (linked lists and BSPs for example.) DOOMED only reaches the hundreds of thousands barely. So I set the limit to 10 million instruction per second. CoinHunt (with changes I made) runs well on Celeron N5095 at 6 million and that’s a low end but modern computer so I think 10 million is good.
I will probably add a command line switch to disable the limit in the next version.
-
Artificial limitations will be imposed

I’ve added an instructions/second counter (need +debug command line switch). The cube example is really lightweight, while the town example gives a little over 7,000 instructions per second. I’m going to take the heaviest example and multiply it by 5 or 10 and set a limit. This will make games run everywhere, well optimised and of a certain small arcadey distinction. The result is averaged every 5 seconds.
You can optimise for lower instruction counts, e.g.:
= x (* x 2) = x (+ x 1)Is 2 instructions but:
= x (+ (* x 2) 1)Is 1 and does the same thing.
-
town example running BooBoo 3
This is the new code:
var music = music (mml_load "music/town.mml") mml_play music 0.5 1 var pickup = pickup (mml_load "sfx/pickup.mml") var W H = W 240 = H 135 resize W H var sprite = sprite (sprite_load "pleasant") var apple_img carrot_img = apple_img (image_load "misc/apple.png") = carrot_img (image_load "misc/carrot.png") var tilemap = tilemap (tilemap_load "map.wm3") var anim var frame vector_add frame 8 vector_add frame 7 vector_add anim frame vector_clear frame vector_add frame 12 vector_add frame 7 vector_add anim frame tilemap_set_animated_tiles tilemap 500 4 3 anim var collectibles var groups = groups (tilemap_get_groups tilemap) var num_groups = num_groups (vector_size groups) var i for i 0 (< i num_groups) 1 next_group var group = group [groups i] var c if (& [group 0] 1) apple carrot vector_add c apple_img :apple vector_add c carrot_img :carrot vector_add c [group 1] vector_add c [group 2] vector_add collectibles c :next_group var TILE_SIZE px py dir_x dir_y moving move_count MOVE_TIME = TILE_SIZE 16 = px 19 = py 11 = moving 0 = MOVE_TIME 20 = dir_x 0 = dir_y 1 function suffix_from_dirs dx dy { if (&& (== dx 0) (== dy 1)) south (&& (== dx 0) (== dy -1)) north (&& (== dx 1) (== dy 0)) east west return "_s" :south return "_n" :north return "_e" :east return "_w" :west } function draw { var ox oy sx sy = ox (- (+ (/ TILE_SIZE 2) (* px TILE_SIZE)) (/ W 2)) = oy (- (+ (/ TILE_SIZE 2) (* py TILE_SIZE)) (/ H 2)) = sx (* px TILE_SIZE) = sy (* py TILE_SIZE) if (== moving 1) draw_moving var dx dy = dx dir_x = dy dir_y var inc = inc TILE_SIZE var p = p (/ move_count MOVE_TIME) = inc (* inc p) = dx (* dx inc) = dy (* dy inc) = ox (+ ox dx) = oy (+ oy dy) = sx (+ sx dx) = sy (+ sy dy) :draw_moving var map_w map_h explode (tilemap_size tilemap) map_w map_h = map_w (* map_w TILE_SIZE) = map_h (* map_h TILE_SIZE) if (< ox 0) too_left (> ox (- map_w W)) too_right = ox 0 :too_left = ox (- map_w W) :too_right if (< oy 0) too_up (> oy (- map_h H)) too_down = oy 0 :too_up = oy (- map_h H) :too_down var layers = layers (tilemap_num_layers tilemap) tilemap_draw tilemap 0 1 (* ox -1) (* oy -1) var i var sz = sz (vector_size collectibles) for i 0 (< i sz) 1 next_collectible var c = c [collectibles i] var dx dy = dx (- (* [c 1] TILE_SIZE) ox) = dy (- (* [c 2] TILE_SIZE) oy) image_draw [c 0] 255 255 255 255 dx dy 0 0 :next_collectible sprite_draw sprite 255 255 255 255 (- sx ox) (- sy oy) 0 0 tilemap_draw tilemap 2 (- layers 1) (* ox -1) (* oy -1) } function run { include "poll_joystick.inc" var map_w map_h explode (tilemap_size tilemap) map_w map_h if (== moving 1) do_moving not_moving = move_count (+ move_count 1) if (>= move_count MOVE_TIME) done_moving if (== dir_x -1) check_l (== dir_x 1) check_r (== dir_y -1) check_u (== dir_y 1) check_d if (!= joy_l 1) done_l = moving 0 :done_l :check_l if (!= joy_r 1) done_r = moving 0 :done_r :check_r if (!= joy_u 1) done_u = moving 0 :done_u :check_u if (!= joy_d 1) done_d = moving 0 :done_d :check_d = px (+ px dir_x) = py (+ py dir_y) = move_count 0 if (== moving 1) check_solids2 var xx var yy = xx px = yy py = xx (+ xx dir_x) = yy (+ yy dir_y) var s = s (tilemap_is_solid tilemap xx yy) if (== s 1) stop = moving 0 :stop :check_solids2 if (== moving 0) stand var suffix call_result suffix suffix_from_dirs dir_x dir_y var a = a "stand" = a (+ a suffix) sprite_set_animation sprite a :stand :done_moving :do_moving if (== joy_l 1) go_left (== joy_r 1) go_right (== joy_u 1) go_up (== joy_d 1) go_down = moving 1 = move_count 0 = dir_x -1 = dir_y 0 :go_left = moving 1 = move_count 0 = dir_x 1 = dir_y 0 :go_right = moving 1 = move_count 0 = dir_x 0 = dir_y -1 :go_up = moving 1 = move_count 0 = dir_x 0 = dir_y 1 :go_down if (== moving 1) check_solids var xx yy = xx px = yy py = xx (+ xx dir_x) = yy (+ yy dir_y) if (== 0 (&& (>= xx 0) (>= yy 0) (< xx map_w) (< yy map_h))) cant_move continue_check = moving 0 :cant_move var solid = solid (tilemap_is_solid tilemap xx yy) if (== 1 solid) cant_move2 = moving 0 :cant_move2 :continue_check :check_solids var suffix call_result suffix suffix_from_dirs dir_x dir_y var a if (== moving 1) walk stand2 = a "walk" = a (+ a suffix) sprite_set_animation sprite a :walk = a "stand" = a (+ a suffix) sprite_set_animation sprite a :stand2 :not_moving ? joy_a 1 jne no_pickup var dx dy = dx (+ px dir_x) = dy (+ py dir_y) var i sz = sz (vector_size collectibles) for i 0 (< i sz) 1 next_pickup_check var c = c [collectibles i] var cx cy = cx [c 1] = cy [c 2] if (&& (== cx dx) (== cy dy)) pick_it_up mml_play pickup 1 0 vector_erase collectibles i goto no_pickup :pick_it_up :next_pickup_check :no_pickup }This is now poll_joystick.inc, with joystick_poll removed (and joystick renamed to joy):
var joy_x1 joy_y1 joy_x2 joy_y2 joy_x3 joy_y3 joy_l joy_r joy_u joy_d joy_a joy_b joy_x joy_y joy_lb joy_rb joy_ls joy_rs joy_back joy_start = joy_x1 (joy_get_axis 0 JOY_LEFTX) = joy_y1 (joy_get_axis 0 JOY_LEFTY) = joy_x2 (joy_get_axis 0 JOY_RIGHTX) = joy_y2 (joy_get_axis 0 JOY_RIGHTY) = joy_x3 (joy_get_axis 0 JOY_TRIGGERLEFT) = joy_y3 (joy_get_axis 0 JOY_TRIGGERRIGHT) = joy_a (joy_get_button 0 JOY_A) = joy_b (joy_get_button 0 JOY_B) = joy_x (joy_get_button 0 JOY_X) = joy_y (joy_get_button 0 JOY_Y) = joy_u (joy_get_button 0 JOY_U) = joy_d (joy_get_button 0 JOY_D) = joy_l (joy_get_button 0 JOY_L) = joy_r (joy_get_button 0 JOY_R) = joy_ls (joy_get_button 0 JOY_LS) = joy_rs (joy_get_button 0 JOY_RS) = joy_lb (joy_get_button 0 JOY_LB) = joy_rb (joy_get_button 0 JOY_RB) = joy_back (joy_get_button 0 JOY_BACK) = joy_start (joy_get_button 0 JOY_START) ; This provides some keyboard support mapped to joystick var _key_l _key_r _key_u _key_d _key_a _key_b _key_back = _key_l (key_get KEY_LEFT) = _key_r (key_get KEY_RIGHT) = _key_u (key_get KEY_UP) = _key_d (key_get KEY_DOWN) = _key_a (key_get KEY_Z) = _key_b (key_get KEY_X) = _key_back (key_get KEY_ESCAPE) = joy_l (|| (== _key_l 1) (== joy_l 1)) = joy_r (|| (== _key_r 1) (== joy_r 1)) = joy_u (|| (== _key_u 1) (== joy_u 1)) = joy_d (|| (== _key_d 1) (== joy_d 1)) = joy_a (|| (== _key_a 1) (== joy_a 1)) = joy_b (|| (== _key_b 1) (== joy_b 1)) = joy_back (|| (== _key_back 1) (== joy_back 1)) -
Half of examples are being deleted
Because some of them just aren’t good, and there’s too many to convert to the new syntax.
-
Ditching type safety
From now on all variables will be declared with “var” (instead of number, vector, pointer, etc…) Their types will be based on how you use them. And they can change.
-
Redoing all the examples is the hardest part
Of releasing BooBoo 3. Normal builtins vs expression ops is fairly straightforward to convert.
