BooBoo Updates Thread
Posted by
tremblin on 2024-12-05, 11:21pm
A new first parameter has been added to joystick events - the joystick index (0=1st, 1=2nd joystick, ...)
This is released as 2.2.14.
Replies (24)
Posted by
tremblin on 2024-12-10, 6:11pm
Updated the demos downloads to the latest version of BooBoo/scripts.
Posted by
tremblin on 2024-12-10, 8:39pm
Only difference from before is everything between 2.1 and 2.2.14 which was pretty much 2-3 small things each revision mostly. The games didn't change. But a few API they use changed slightly and was corrected in the games and launcher.
Posted by
tremblin on 2024-12-11, 8:59pm
https://cmykilluminati.net/media/stuff/gui_transitions.mp4You can now customize the GUI transitions (git) and I added an example to tinker with it, shown above.
Posted by
tremblin on 2024-12-11, 9:43pm
I removed all the "fit" widgets stuff, as it's always confusing.
Posted by
tremblin on 2024-12-12, 2:25am
EDIT: this is the updated code from 2.2.15 which supports keyboard/joystick input
number exited
= exited FALSE
vector groups
vector_add groups 0
vector_add groups 1
number font
font_load font "vga.ttf" 12 1
map c c_both c_left c_right ll lr l1 l2 l3 l4 l5 r1 r2 r3 r4 r5 bcycle ; widget userdata
number wc wc_both wc_left wc_right wll wlr wl1 wl2 wl3 wl4 wl5 wr1 wr2 wr3 wr4 wr5 wbcycle ; widgets
function start_gui
{
map_set c "draw" draw_window
map_set c "event" null_event
map_set c_both "draw" draw_nothing
map_set c_both "event" null_event
map_set c_left "draw" draw_nothing
map_set c_left "event" null_event
map_set c_right "draw" draw_nothing
map_set c_right "event" null_event
call_result ll mklabel "IN"
call_result lr mklabel "OUT"
pointer g1 g2
address g1 [groups 0]
address g2 [groups 1]
call_result l1 mkradio g1 0 "Enlarge"
call_result l2 mkradio g1 1 "Shrink"
call_result l3 mkradio g1 2 "Appear"
call_result l4 mkradio g1 3 "Slide"
call_result l5 mkradio g1 4 "V. Slide"
call_result r1 mkradio g2 0 "Enlarge"
call_result r2 mkradio g2 1 "Shrink"
call_result r3 mkradio g2 2 "Appear"
call_result r4 mkradio g2 3 "Slide"
call_result r5 mkradio g2 4 "V. Slide"
call_result bcycle mkbutton "Cycle GUI" cycle_gui
widget_create wll 1 30 ll
widget_set_accepts_focus wll FALSE
widget_create wl1 200 30 l1
widget_create wl2 200 30 l2
widget_create wl3 200 30 l3
widget_create wl4 200 30 l4
widget_create wl5 200 30 l5
widget_create wc_left 200 100 c_left
widget_set_accepts_focus wc_left FALSE
widget_set_parent wll wc_left
widget_set_parent wl1 wc_left
widget_set_parent wl2 wc_left
widget_set_parent wl3 wc_left
widget_set_parent wl4 wc_left
widget_set_parent wl5 wc_left
widget_create wlr 1 30 lr
widget_set_accepts_focus wlr FALSE
widget_create wr1 200 30 r1
widget_create wr2 200 30 r2
widget_create wr3 200 30 r3
widget_create wr4 200 30 r4
widget_create wr5 200 30 r5
widget_create wc_right 200 150 c_right
widget_set_accepts_focus wc_right FALSE
widget_set_parent wlr wc_right
widget_set_parent wr1 wc_right
widget_set_parent wr2 wc_right
widget_set_parent wr3 wc_right
widget_set_parent wr4 wc_right
widget_set_parent wr5 wc_right
widget_create wc_both 400 180 c_both
widget_set_accepts_focus wc_both FALSE
widget_set_parent wc_left wc_both
widget_set_parent wc_right wc_both
widget_create wc 400 210 c
widget_set_accepts_focus wc FALSE
widget_set_parent wc_both wc
widget_create wbcycle 400 30 bcycle
widget_set_break_line wbcycle TRUE
widget_set_parent wbcycle wc
gui_start wc
}
call start_gui
gui_set_focus wl1
function draw_nothing x y w h focussed data
{
}
function draw_window x y w h focussed data
{
filled_rectangle 0 0 255 255 0 0 255 255 0 0 255 255 0 0 255 255 x y w h
}
function draw_button x y w h focussed data
{
number r g b
if (== focussed TRUE) yellow white
= r 255
= g 255
= b 0
:yellow
= r 255
= g 255
= b 255
:white
number tw th
font_width font tw [data "text"]
font_height font th
number xx yy
= xx (+ x (/ w 2))
- xx (/ tw 2)
= yy (+ y (/ h 2))
- yy (/ th 2)
number ox oy
if (== [data "down"] TRUE) offset no_offset
= ox 5
= oy 5
:offset
= ox 0
= oy 0
:no_offset
+ x ox
+ y oy
+ xx ox
+ yy oy
filled_rectangle 0 0 255 255 0 0 255 255 0 255 255 255 0 255 255 255 x y w h
rectangle r g b 255 x y w h 2
font_draw font r g b 255 [data "text"] xx yy
}
function draw_label x y w h focussed data
{
number tw th
font_width font tw [data "text"]
font_height font th
number xx yy
= xx (+ x (/ w 2))
- xx (/ tw 2)
= yy (+ y (/ h 2))
- yy (/ th 2)
filled_rectangle 0 0 255 255 0 0 255 255 0 255 255 255 0 255 255 255 x y w h
font_draw font 255 255 255 255 [data "text"] xx yy
}
function draw_radio x y w h focussed data
{
number tw th cy
font_width font tw [data "text"]
font_height font th
number xx yy
= xx (+ x 20)
= yy (+ y (/ h 2))
= cy yy
- yy (/ th 2)
filled_rectangle 0 0 255 255 0 0 255 255 0 0 255 255 0 0 255 255 x y w h
font_draw font 255 255 255 255 [data "text"] (+ xx 20) yy
circle 255 255 255 255 (+ xx 10) cy 7 1 -1
if (== `[data "group"] [data "index"]) check
filled_circle 255 255 255 255 (+ xx 10) cy 5 -1
:check
if (== focussed 1) draw_focus
rectangle 255 255 0 255 x y w h 2
:draw_focus
}
function null_event type a b c d x y w h focussed ~data
{
}
function button_event type a b c d x y w h focussed ~data
{
if (&& (== type EVENT_MOUSE_DOWN) (== a 1) (== b FALSE)) down
number on_button
call_result on_button owned x y w h c d
if (== on_button TRUE) really_down
map_set data "down" TRUE
:really_down
:down
if (&& (== [data "down"] TRUE) (== type EVENT_MOUSE_UP)) up
number on_button
call_result on_button owned x y w h c d
if (== on_button TRUE) really_up
call [data "callback"]
:really_up
map_set data "down" FALSE
:up
if (&& (== TRUE focussed) (== FALSE b) (|| (&& (== type EVENT_KEY_DOWN) (== KEY_RETURN a)) (&& (== type EVENT_JOY_DOWN) (== b JOY_A)))) down2
map_set data "down" TRUE
:down2
if (&& (== [data "down"] TRUE) (== TRUE focussed) (|| (&& (== type EVENT_KEY_UP) (== KEY_RETURN a)) (&& (== type EVENT_JOY_UP) (== b JOY_A)))) play_it
call [data "callback"]
map_set data "down" FALSE
:play_it
}
function radio_event type a b c d x y w h focussed ~data
{
if (&& (== type EVENT_MOUSE_DOWN) (== a 1) (== b FALSE)) down
number on_button
call_result on_button owned x y w h c d
if (== on_button TRUE) really_down
= `[data "group"] [data "index"]
:really_down
:down
if (&& (== TRUE focussed) (== FALSE b) (|| (&& (== type EVENT_KEY_DOWN) (== KEY_RETURN a)) (&& (== type EVENT_JOY_DOWN) (== b JOY_A)))) down2
= `[data "group"] [data "index"]
:down2
}
function mkbutton text callback
{
map m
map_set m "text" text
map_set m "draw" draw_button
map_set m "event" button_event
map_set m "callback" callback
map_set m "down" FALSE
return m
}
function mklabel text
{
map m
map_set m "text" text
map_set m "draw" draw_label
map_set m "event" null_event
return m
}
function mkradio group index text
{
map m
map_set m "text" text
map_set m "draw" draw_radio
map_set m "event" radio_event
map_set m "group" group
map_set m "index" index
return m
}
function owned wx wy ww wh x y
{
if (|| (< x wx) (< y wy) (>= x (+ wx ww)) (>= y (+ wy wh))) nope
return FALSE
:nope
return TRUE
}
function gui_event id type a b c d x y w h focussed ~data
{
call [data "event"] type a b c d x y w h focussed data
}
function gui_draw id x y w h focussed data
{
call [data "draw"] x y w h focussed data
}
function cycle_gui
{
gui_set_transition_types [groups 0] [groups 1]
gui_exit
= exited TRUE
}
function event type a b c d
{
if (== exited FALSE) no
return
:no
if (&& (== type EVENT_KEY_DOWN) (== a KEY_SPACE)) again
= exited FALSE
call start_gui
:again
}
function draw
{
if (== exited FALSE) back
return
:back
font_draw font 255 255 255 255 "Press SPACE to restart GUI" 10 10
}
This is the code for the video 2 posts above...
You can see the limitation of no pointers. The groups global could be put as a pointer into wl1..wl5 etc but instead it has to be a global. I also made an example for myself with a checkbox, and it could be improved with pointers too. But it's a question of simplicity vs. adding pointers, I had a pointer type at one point but it worked kinda weird... I've thought about it and I could add them back with a dereference operator but it adds a lot of complexity both to learning BooBoo (which can be educational) and it bloats the code. I think there's tonnes of games that could be made as it is so I'm not leaning toward adding pointers but who knows.
The api for pointers I had in mind was something like
pointer p ; define a pointer
address p some_var ; take the address of some_var
; now assigning to p without a dereference is undefined
= p some_num ; undefined
; but you could assign to the value pointed to by p (some_var) with a dereference
= ^p some_num
; Assigning to pointer itself can only be done on untyped destinations:
= some_num p ; undefined or error
= [v 0] p ; [v 0] now points to some_var
; Now if you were to do:
= [v 0] 10
; ^ That replaces the pointer with a number, but
= ^[v 0] 10
; some 'some_var' to 10
Posted by
tremblin on 2024-12-12, 4:18am
A few things could be done with that example like kb/joystick control of radio buttons, which'll probably just look like the focus has been lost and won't respond to input until a focus rectangle is drawn in draw_radio and kb/joystick events are handled in radio_event.
EDIT: This was done for 2.2.15
Posted by
tremblin on 2024-12-12, 6:42am
number n
= n 10
pointer p
address p n
= !p 20
print "%\n" n
print "%\n" !p
map m
= [m "foo"] p
= ![m "foo"] 30
print "%\n" n
= [m "foo"] 40
print "%\n" [m "foo"]
address p [m "foo"]
= !p 50
print "%\n" [m "foo"]
This pointers example is working in git. It prints:
20
20
30
40
50
Posted by
tremblin on 2024-12-12, 6:46am
Might still be some corner cases missing for pointer support, but basically all there.
Posted by
tremblin on 2024-12-12, 9:15am
2.2.15 is released:
- Change Nooskewl example to the canonical animation
- Don't add game engine constants to CLI build namespace
- Configurable GUI transitions with example
- Remove FIT_X/FIT_Y stuff from GUI API
- Add pointer type with CLI example
Posted by
tremblin on 2024-12-12, 9:20am
The dereference operator is a backtick (`), the documentation online is updated.
Posted by
tremblin on 2024-12-12, 10:03am
Pointers work with functions too... actually you could always use function pointers stuff into typeless variables, now you can do it two ways:
function foo
{
print "FOO\n"
}
pointer p
address p foo
call `p
call bar foo
function bar bazoo
{
call bazoo
}
Prints FOO twice.
The second "call bar foo" was always supported, as well you can directly store functions into vectors/maps:
map m
= [m "callback"] foo
call [m "callback"] ; print FOO
Whereas if you're using pointers...
pointer p
address p foo
map m
= [m "callback"] p
call `[m "callback"] ; call [m "callback"] will probably crash or (should eventually, once everything is buttoned up) throw an error
Functions are just a type of variable like number, map etc except there isn't a way to define a variable of that type other than declaring a function. Same with labels. You can pass labels into a vector if you wanted although I think it's useless, you can also pass them into functions, since labels inside functions are out of scope, and you can't jump out of a function, it's also useless, but I can see using them in pointers to maybe have some use:
pointer p
address p bar
goto `p
:foo
print "FOO\n"
goto done
:bar
print "BAR\n"
goto done
:baz
print "BAZ\n"
goto done
:done
This prints BAR
Posted by
tremblin on 2024-12-12, 10:46am
(due to not much use without it, labels and functions can be seen if they're declared after that point, as the compiler has 2 passes)
Posted by
tremblin on 2024-12-13, 8:23pm
I added Fade and None to GUI transitions... they all work without resizing the window, due to the automatic placement of "black bars" I still need to fix some of the transitions when the window is resized.
Posted by
tremblin on 2024-12-13, 9:33pm
vector_reserve
fade, none gui transitions
fix transitions for black bars
custom black bars - set projection, pass a user function
target (left/right/top/bottom) x, y, w, h
This is my todo list.
Posted by
tremblin on 2024-12-13, 9:51pm
The only time you, as a user, has to deal with "black bar" crap is with shaders while targetting the backbuffer. You should be able to avoid it altogether with shaders, by using a render target the size of your buffer. It's only an issue with some types of shaders, like if you are using gl_FragCoord. You would expect the renderable area to have a 0->1 gl_FragCoord however the black bars account for some of that space. You can work around it in your shaders, using the BooBoo functions to get the offset of the black bars and passing them into shaders.
Posted by
tremblin on 2024-12-14, 8:51am
I fixed all the GUI transitions including the new fade. I removed appear. It's not really a general purpose transition and was only there for Dog-O which uses it for its menus. It also requires a shader so the D3D port requires one fewer external shader now.
When the window is "tall" now the drawing area is centred instead of offset to the top. The intention of offset it upwards is to allow touch controls, but I don't intend to work on Android/Apple again.
Posted by
tremblin on 2024-12-14, 9:45pm
Posted by
tremblin on 2024-12-14, 9:49pm
Here's the code for it, but this example doesn't include the moving triangle, for simplicity of demonstration:
number iv ih it
image_load iv "vert.png"
image_load ih "horiz.png"
image_load it "tile.png"
number v_w v_h h_w h_h t_w t_h
image_size iv v_w v_h
image_size ih h_w h_h
image_size it t_w t_h
function draw_black_bar type x y w h
{
number scale
= scale 3
number scr_w scr_h
get_screen_size scr_w scr_h
number xx yy
if (== type BAR_TOP) top (== type BAR_BOTTOM) bottom (== type BAR_LEFT) left right
= xx w
/ xx (* h_w scale)
floor xx
+ xx 1
* xx (* h_w scale)
- xx w
/ xx 2
neg xx
= yy (- (+ y h) (* h_h scale))
call htile ih xx yy w h scale
= xx w
/ xx (* t_w scale)
floor xx
+ xx 1
* xx (* t_w scale)
- xx w
/ xx 2
neg xx
if (> yy 0) tile
:again
- yy (* t_h scale)
call htile it xx yy w h scale
? yy 0
jg again
:tile
:top
= xx w
/ xx (* h_w scale)
floor xx
+ xx 1
* xx (* h_w scale)
- xx w
/ xx 2
neg xx
= yy y
call htile ih xx yy w h scale
= xx w
/ xx (* t_w scale)
floor xx
+ xx 1
* xx (* t_w scale)
- xx w
/ xx 2
neg xx
+ yy (* h_h scale)
if (< yy scr_h) tile2
:again2
call htile it xx yy w h scale
+ yy (* t_h scale)
? yy scr_h
jl again2
:tile2
:bottom
= yy h
/ yy (* v_h scale)
floor yy
+ yy 1
* yy (* v_h scale)
- yy h
/ yy 2
neg yy
= xx (- (+ x w) (* v_w scale))
call vtile iv xx yy w h scale
= yy h
/ yy (* t_h scale)
floor yy
+ yy 1
* yy (* t_h scale)
- yy h
/ yy 2
neg yy
if (> xx 0) tile3
:again3
- xx (* t_w scale)
call vtile it xx yy w h scale
? xx 0
jg again3
:tile3
:left
= yy h
/ yy (* v_h scale)
floor yy
+ yy 1
* yy (* v_h scale)
- yy h
/ yy 2
neg yy
= xx x
call vtile iv xx yy w h scale
= yy h
/ yy (* t_h scale)
floor yy
+ yy 1
* yy (* t_h scale)
- yy h
/ yy 2
neg yy
+ xx (* v_w scale)
if (< xx scr_w) tile4
:again4
call vtile it xx yy w h scale
+ xx (* t_w scale)
? xx scr_w
jl again4
:tile4
:right
}
function htile img x y w h scale
{
number img_w img_h
image_size img img_w img_h
:top
image_stretch_region img 255 255 255 255 0 0 img_w img_h x y (* img_w scale) (* img_h scale) 0 0
+ x (* img_w scale)
? x w
jl top
}
function vtile img x y w h scale
{
number img_w img_h
image_size img img_w img_h
:top
image_stretch_region img 255 255 255 255 0 0 img_w img_h x y (* img_w scale) (* img_h scale) 0 0
+ y (* img_h scale)
? y h
jl top
}
draw_black_bar gets called 0 or 2 times depending what needs to be drawn, every time the screen is cleared which happens automatically after draw is called.
Posted by
tremblin on 2024-12-14, 11:26pm
Posted by
tremblin on 2024-12-14, 11:34pm
2.2.16 is uploaded with these changes since 2.2.15:
- Added function and label pointers CLI examples
- Remove "Appear" gui transition, add None and Fade
- Support for drawing your own custom "black bars" for wide/tall aspect ratios
- Fixes
Posted by
tremblin on 2024-12-15, 4:25am
In that example, It looks like about half the code is to get the tiling centred rather than starting at the top left with a full tile and ending up with probably half a tile on the bottom. Roughly half the lines of code are for that reason.
= xx w
/ xx (* h_w scale)
floor xx
+ xx 1
* xx (* h_w scale)
- xx w
/ xx 2
neg xx
All that which is repeated slightly differently 8 times is to get the thing centred.
You could also write it like:
= xx (/ w (* h_w scale))
floor xx
= xx (/ (- (* (+ xx 1) (* h_w scale)) w) 2)
neg xx
Posted by
tremblin on 2024-12-15, 4:35am
or just * -1 instead of neg. Then it's 3 lines.
Posted by
tremblin on 2024-12-16, 12:02am
https://cmykilluminati.net/media/stuff/blackbarsdefault.mp4There is now a gradient drawn by default instead of black bars, you can still override it.
My microphone is blaring on Linux.
Posted by
tremblin on 2024-12-18, 4:01am
I've enabled multisampling in git. 4 samples. 16 samples doesn't work on my RX 6400 so likely wouldn't be widely supported, 8 might, but 4 looks good anyway and should be widely supported.
Here's a multisampled thick triangle.
Post a Reply
Please log in to reply.