- if( menu.page_depth >= MENU_STACK_SIZE )
- vg_fatal_error( "Stack overflow\n" );
-
- vg_info( "Try to open %s\n", name );
-
- u32 hash = vg_strdjb2( name );
- for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
- ent_menuitem *item = mdl_arritm( &menu.items, i );
-
- if( item->type == k_ent_menuitem_type_page ){
- if( mdl_pstreq( &menu.model, item->page.pstr_name, name, hash ) ){
- u32 new_page = __builtin_ctz( item->groups );
-
- if( new_page == menu.page ){
- menu_back_page();
- }
- else{
- menu.page_stack[ menu.page_depth ].page = menu.page;
- menu.page_stack[ menu.page_depth ].cam = menu.cam;
- menu.page_stack[ menu.page_depth ++ ].loc = menu.loc;
- menu.page = __builtin_ctz( item->groups );
-
- if( menu.input_mode == k_menu_input_mode_keys ){
- if( item->page.id_entrypoint ){
- u32 id = mdl_entity_id_id( item->page.id_entrypoint );
- menu.loc = mdl_arritm( &menu.items, id );
- }
- }
-
- if( item->page.id_viewpoint ){
- u32 id = mdl_entity_id_id( item->page.id_viewpoint );
- menu.cam = mdl_arritm( &menu.cameras, id );
- }
- vg_info( "menu page: %u (%p,%p)\n",
- menu.page, menu.loc, menu.cam );
- }
- return;
- }
- }
- }
-}
-
-/*
- * activate a pressable type
- */
-static void menu_trigger_item( ent_menuitem *item )
-{
- if ( item->type == k_ent_menuitem_type_event_button ){
- u32 q = item->button.pstr;
-
- if( MDL_CONST_PSTREQ( &menu.model, q, "quit" ) ){
- vg.window_should_close = 1;
- }
- else if( MDL_CONST_PSTREQ( &menu.model, q, "reset" ) ){
- localplayer_cmd_respawn( 0, NULL );
-
- menu.page_depth = 0;
- menu.active = 0;
- menu.page = 0xffffffff;
- }
- }
- else if( item->type == k_ent_menuitem_type_page_button ){
- menu_open_page( mdl_pstr( &menu.model, item->button.pstr ) );
- }
- else if( item->type == k_ent_menuitem_type_toggle ){
- if( item->pi32 ){
- *item->pi32 = *item->pi32 ^ 0x1;
- }
- }
-}
-
-static f32 menu_slider_snap( f32 value, f32 old, f32 notch )
-{
- f32 const k_epsilon = 0.0125f;
-
- if( fabsf(notch-value) < k_epsilon ){
- if( fabsf(notch-old) > k_epsilon ){
- audio_lock();
- audio_oneshot( &audio_ui[0], 1.0f, 0.0f );
- audio_unlock();
- }
-
- return notch;
- }
- else
- return value;
-}
-
-/*
- * Run from vg_gui every frame
- */
-static void menu_update(void)
-{
- if( button_down( k_srbind_mopen ) ){
- if( !menu.active && !menu.disable_open ){
- menu.active = 1;
- menu.page = 0xffffffff;
- menu_open_page( "Main Menu" );
- return;
- }
- }
-
- menu.factive = vg_lerpf( menu.factive, menu.active,
- vg.time_frame_delta * 6.0f );
-
- if( !menu.active ) return;
-
- enum menu_input_mode prev_mode = menu.input_mode;
-
- /* get buttons inputs
- * -------------------------------------------------------------------*/
- int ml = button_down( k_srbind_mleft ),
- mr = button_down( k_srbind_mright ),
- mu = button_down( k_srbind_mup ),
- md = button_down( k_srbind_mdown ),
- mh = ml-mr,
- mv = mu-md,
- enter = button_down( k_srbind_maccept ),
- escape = button_down( k_srbind_mback );
-
- if( mh||mv||enter ){
- menu.input_mode = k_menu_input_mode_keys;
- }
-
- /* get mouse inputs
- * --------------------------------------------------------------------*/
- menu.mouse_dist += v2_length( vg.mouse_delta ); /* TODO: Move to UI */
- menu.mouse_track += vg.time_frame_delta;
- if( menu.mouse_track > 0.1f ){
- menu.mouse_track = fmodf( menu.mouse_track, 0.1f );
- if( menu.mouse_dist > 10.0f ){
- menu.input_mode = k_menu_input_mode_mouse;
- menu.mouse_dist = 0.0f;
- }
- }
-
- if( ui_clicking(UI_MOUSE_LEFT) || ui_clicking(UI_MOUSE_RIGHT) ){
- menu.input_mode = k_menu_input_mode_mouse;
- }
-
- if( menu.input_mode == k_menu_input_mode_mouse ){
- /*
- * handle mouse input
- * ------------------------------------------------------------*/
- vg_ui.wants_mouse = 1;
-
- /*
- * this raycasting is super cumbersome because all the functions were
- * designed for other purposes. we dont care though.
- */
- m4x4f inverse;
- m4x4_inv( menu.view.mtx.p, inverse );
- v4f coords;
- coords[0] = vg_ui.mouse[0];
- coords[1] = vg.window_y - vg_ui.mouse[1];
- v2_div( coords, (v2f){ vg.window_x, vg.window_y }, coords );
- v2_muls( coords, 2.0f, coords );
- v2_add( coords, (v2f){-1.0f,-1.0f}, coords );
- coords[2] = 1.0f;
- coords[3] = 1.0f;
- m4x4_mulv( inverse, coords, coords );
- v3f ray;
- m3x3_mulv( menu.view.transform, coords, ray );
- v3_normalize( ray );
-
- if( menu.loc && (menu.loc->type == k_ent_menuitem_type_slider) &&
- ui_clicking(UI_MOUSE_LEFT) && menu.loc->pf32 ){
-
- u32 il = mdl_entity_id_id( menu.loc->slider.id_min ),
- ir = mdl_entity_id_id( menu.loc->slider.id_max );
- ent_marker *ml = mdl_arritm( &menu.markers, il ),
- *mr = mdl_arritm( &menu.markers, ir );
-
- v3f q2;
- v3_muladds( menu.view.pos, ray, 100.0f, q2 );