8 #include "ent_miniworld.h"
12 #include "shaders/model_menu.h"
14 struct global_menu menu
= { .skip_starter
= 0 };
16 void menu_at_begin(void)
18 if( menu
.skip_starter
) return;
20 skaterift
.activity
= k_skaterift_menu
;
21 menu
.page
= k_menu_page_starter
;
26 vg_console_reg_var( "skip_starter_menu", &menu
.skip_starter
,
27 k_var_dtype_i32
, VG_VAR_PERSISTENT
);
30 void menu_open( enum menu_page page
)
32 skaterift
.activity
= k_skaterift_menu
;
34 if( page
!= k_menu_page_any
)
40 bool menu_viewing_map(void)
42 return (skaterift
.activity
== k_skaterift_menu
) &&
43 (menu
.page
== k_menu_page_main
) &&
44 (menu
.main_index
== k_menu_main_map
);
47 static void menu_decor_select( ui_rect rect
)
49 ui_px b
= vg_ui
.font
->sx
, hb
= b
/2;
50 ui_rect a0
= { rect
[0] - 20 - hb
, rect
[1] + rect
[3]/2 - hb
, b
,b
},
51 a1
= { rect
[0] + rect
[2] + 20 + hb
, rect
[1] + rect
[3]/2 - hb
, b
,b
};
53 ui_text( a0
, "\x95", 1, k_ui_align_middle_center
, 0 );
54 ui_text( a1
, "\x93", 1, k_ui_align_middle_center
, 0 );
57 static void menu_standard_widget( ui_rect inout_panel
, ui_rect rect
, ui_px s
)
59 ui_split( inout_panel
, k_ui_axis_h
, vg_ui
.font
->sy
*s
*2,
60 2, rect
, inout_panel
);
63 static bool menu_slider( ui_rect inout_panel
, bool select
, const char *label
,
64 const f32 min
, const f32 max
, f32
*value
,
68 menu_standard_widget( inout_panel
, rect
, 1 );
69 ui_label( rect
, label
, 1, 8, box
);
72 enum ui_button_state state
= ui_slider_base( box
, min
, max
, value
, &t
),
74 k_ui_button_holding_inside
|
75 k_ui_button_holding_outside
|
77 mask_brighter
= mask_using
| k_ui_button_hover
;
79 if( menu
.input_mode
== k_menu_input_mode_keys
)
83 f32 m
= axis_state( k_sraxis_mbrowse_h
);
86 *value
+= m
* vg
.time_frame_delta
* ((max
-min
) / 2.0f
);
87 *value
= vg_clampf( *value
, min
, max
);
90 menu_decor_select( rect
);
91 state
|= k_ui_button_hover
;
95 ui_rect line
= { box
[0], box
[1], t
* (f32
)box
[2], box
[3] };
96 ui_fill( line
, state
&mask_brighter
? GUI_COL_ACTIVE
: GUI_COL_NORM
);
97 ui_fill( (ui_rect
){ box
[0]+line
[2], box
[1], box
[2]-line
[2], box
[3] },
100 ui_outline( box
, 1, state
? GUI_COL_HI
: GUI_COL_ACTIVE
, 0 );
101 ui_slider_text( box
, NULL
, *value
);
103 return (state
& mask_using
) && 1;
106 static enum ui_button_state
menu_button( ui_rect inout_panel
, bool select
,
110 menu_standard_widget( inout_panel
, rect
, 1 );
112 enum ui_button_state state
= k_ui_button_none
;
114 if( menu
.input_mode
== k_menu_input_mode_keys
)
118 menu_decor_select( rect
);
120 if( button_down( k_srbind_maccept
) )
121 state
= k_ui_button_click
;
126 state
= ui_button_base( rect
);
130 if( state
== k_ui_button_click
)
132 ui_fill( rect
, GUI_COL_DARK
);
134 else if( state
== k_ui_button_holding_inside
)
136 ui_fill( rect
, GUI_COL_DARK
);
138 else if( state
== k_ui_button_holding_outside
)
140 ui_fill( rect
, GUI_COL_DARK
);
141 ui_outline( rect
, 1, GUI_COL_CLICK
, 0 );
143 else if( state
== k_ui_button_hover
)
145 ui_fill( rect
, GUI_COL_ACTIVE
);
146 ui_outline( rect
, 1, GUI_COL_CLICK
, 0 );
149 ui_fill( rect
, select
? GUI_COL_ACTIVE
: GUI_COL_NORM
);
151 ui_text( rect
, text
, 1, k_ui_align_middle_center
, 0 );
157 if( button_down( k_srbind_mopen
) )
159 if( skaterift
.activity
== k_skaterift_default
)
161 menu_open( k_menu_page_main
);
166 if( skaterift
.activity
!= k_skaterift_menu
)
169 /* get buttons inputs
170 * -------------------------------------------------------------------*/
171 int ml
= button_down( k_srbind_mleft
),
172 mr
= button_down( k_srbind_mright
),
173 mu
= button_down( k_srbind_mup
),
174 md
= button_down( k_srbind_mdown
),
177 enter
= button_down( k_srbind_maccept
);
181 menu
.input_mode
= k_menu_input_mode_keys
;
185 * --------------------------------------------------------------------*/
186 menu
.mouse_dist
+= v2_length( vg
.mouse_delta
); /* TODO: Move to UI */
187 if( menu
.mouse_dist
> 10.0f
)
189 menu
.input_mode
= k_menu_input_mode_mouse
;
190 menu
.mouse_dist
= 0.0f
;
193 if( ui_clicking(UI_MOUSE_LEFT
) || ui_clicking(UI_MOUSE_RIGHT
) )
195 menu
.input_mode
= k_menu_input_mode_mouse
;
198 if( menu
.input_mode
== k_menu_input_mode_mouse
)
202 * ------------------------------------------------------------*/
203 vg_ui
.wants_mouse
= 1;
206 if( skaterift
.activity
!= k_skaterift_menu
) return;
210 * -------------------------------------------------------------------*/
212 ui_font_face( &vgf_default_title
);
213 ui_px height
= vg_ui
.font
->ch
+ 16;
214 ui_rect topbar
= { 0, 0, vg
.window_x
, height
};
216 const char *opts
[] = {
217 [k_menu_main_main
] = "Menu",
218 [k_menu_main_map
] = "Map",
219 [k_menu_main_settings
] = "Settings"
223 u8 lb_down
= 0, rb_down
= 0;
224 vg_exec_input_program( k_vg_input_type_button_u8
,
226 vg_joy_button
, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
, vg_end
228 vg_exec_input_program( k_vg_input_type_button_u8
,
230 vg_joy_button
, SDL_CONTROLLER_BUTTON_LEFTSHOULDER
, vg_end
233 if( menu
.repeater
> 0.0f
)
235 menu
.repeater
-= vg_minf( vg
.time_frame_delta
, 0.5f
);
239 if( lb_down
!= rb_down
)
241 menu
.main_index
+= rb_down
;
242 menu
.main_index
-= lb_down
;
243 menu
.repeater
+= 0.2f
;
245 if( menu
.main_index
== -1 )
248 if( menu
.main_index
== vg_list_size(opts
) )
253 ui_px x
= 0, spacer
= 8;
254 for( u32 draw
=0; draw
<2; draw
++ )
256 if( menu
.input_mode
== k_menu_input_mode_keys
)
260 ui_rect inf_lb
= { x
, 0, 32, height
};
261 ui_fill( inf_lb
, lb_down
? GUI_COL_NORM
: GUI_COL_NORM
);
262 ui_text( inf_lb
, "\x91", 1, k_ui_align_middle_center
, 0 );
267 for( i32 i
=0; i
<vg_list_size(opts
); i
++ )
269 ui_rect box
= { x
, 0, ui_text_line_width(opts
[i
]) + 32, height
};
273 enum ui_button_state state
= ui_button_base( box
);
274 if( state
== k_ui_button_click
)
276 ui_fill( box
, GUI_COL_DARK
);
279 else if( state
== k_ui_button_holding_inside
)
281 ui_fill( box
, GUI_COL_DARK
);
283 else if( state
== k_ui_button_holding_outside
)
285 ui_fill( box
, GUI_COL_DARK
);
286 ui_outline( box
, 1, GUI_COL_CLICK
, 0 );
288 else if( state
== k_ui_button_hover
)
290 ui_fill( box
, GUI_COL_NORM
);
291 ui_outline( box
, 1, GUI_COL_ACTIVE
, 0 );
294 ui_fill( box
, i
==menu
.main_index
? GUI_COL_ACTIVE
: GUI_COL_NORM
);
296 ui_text( box
, opts
[i
], 1, k_ui_align_middle_center
, 0 );
299 x
+= box
[2] + spacer
;
302 if( menu
.input_mode
== k_menu_input_mode_keys
)
306 ui_rect inf_rb
= { x
, 0, 32, height
};
307 ui_fill( inf_rb
, rb_down
? GUI_COL_NORM
: GUI_COL_NORM
);
308 ui_text( inf_rb
, "\x92", 1, k_ui_align_middle_center
, 0 );
314 ui_fill( (ui_rect
){ x
+8,0, vg
.window_x
-(x
+8),height
}, GUI_COL_NORM
);
317 x
= vg
.window_x
/2 - x
/2;
318 ui_fill( (ui_rect
){ 0, 0, x
-8, height
}, GUI_COL_NORM
);
322 if( menu
.main_index
== k_menu_main_map
)
324 ui_font_face( &vgf_default_large
);
325 ui_rect title
= { vg
.window_x
/2 - 512/2, height
+8, 512, 64 };
331 ui_fill( (ui_rect
){ x
,y
, 0,height
},
332 world_static
.active_instance
? GUI_COL_DARK
: GUI_COL_ACTIVE
);
336 vg_strnull( &str
, buf
, sizeof(buf
) );
337 vg_strcat( &str
, "Hub World" );
339 if( world_static
.active_instance
&&
340 (vg_input
.display_input_method
== k_input_method_controller
) )
342 vg_strcat( &str
, " (" );
343 vg_input_string( &str
, input_button_list
[k_srbind_mhub
], 1 );
344 vg_strcat( &str
, ")" );
347 ui_px w
= ui_text( (ui_rect
){ x
+8, y
, 1000, height
}, buf
, 1,
348 k_ui_align_middle_left
, 0 );
357 world_instance
*world
= &world_static
.instances
[1];
358 if( world
->status
== k_world_status_loaded
)
360 const char *world_name
=
361 mdl_pstr( &world
->meta
, world
->info
.pstr_name
);
363 vg_strnull( &str
, buf
, sizeof(buf
) );
364 vg_strcat( &str
, world_name
);
366 if( !world_static
.active_instance
&&
367 (vg_input
.display_input_method
== k_input_method_controller
) )
369 vg_strcat( &str
, " (" );
370 vg_input_string( &str
, input_button_list
[k_srbind_mhub
], 1 );
371 vg_strcat( &str
, ")" );
374 vs
= ui_fill( (ui_rect
){ x
,y
, 1000,height
},
375 world_static
.active_instance
? GUI_COL_ACTIVE
: GUI_COL_DARK
);
376 w
= ui_text( (ui_rect
){ x
+16,y
, 1000,height
}, buf
,
377 1, k_ui_align_middle_left
, 0 );
379 w
= w
*vg_ui
.font
->sx
+ 8*3;
382 if( button_down( k_srbind_mhub
) ||
383 ui_button_base( (ui_rect
){0,y
,x
,height
} ) == k_ui_button_click
)
385 world_switch_instance( world_static
.active_instance
^ 0x1 );
386 skaterift
.activity
= k_skaterift_default
;
387 world_map
.view_ready
= 0;
397 if( button_down( k_srbind_mback
) )
399 skaterift
.activity
= k_skaterift_default
;
403 ui_rect list
= { vg
.window_x
/2 - 512/2, height
+64,
404 512, vg
.window_y
-height
-128 };
406 if( (mv
< 0) && (menu
.main_row
<2) ) menu
.main_row
++;
407 if( (mv
> 0) && (menu
.main_row
>0) ) menu
.main_row
--;
410 * -------------------------------------------------------------------*/
412 if( menu
.main_index
== k_menu_main_main
)
414 if( menu_button( list
, menu
.main_row
== 0, "Thing 1" ) ==
420 if( menu_button( list
, menu
.main_row
== 1, "Thing 2" ) ==
426 if( menu_button( list
, menu
.main_row
== 2, "Quit Game" ) ==
432 else if( menu
.main_index
== k_menu_main_settings
)
434 ui_font_face( &vgf_default_large
);
436 menu_slider( list
, menu
.main_row
==0, "Yo", 0, 20, &tester
, NULL
);
440 vg_ui
.frosting
= 0.015f
;
441 ui_flush( k_ui_shader_colour
, vg
.window_x
, vg
.window_y
);
442 vg_ui
.frosting
= 0.0f
;
444 ui_font_face( &vgf_default_small
);