menu upgrades
authorhgn <hgodden00@gmail.com>
Tue, 19 Sep 2023 01:26:10 +0000 (02:26 +0100)
committerhgn <hgodden00@gmail.com>
Tue, 19 Sep 2023 01:26:10 +0000 (02:26 +0100)
blender_export.py
entity.h
font.h
maps_src/mp_spawn/main.mdl
menu.h
models_src/rs_font.mdl
models_src/rs_icons.mdl [new file with mode: 0644]
models_src/rs_menu.mdl
respawn.c

index 2e202adac8c6a4032867003b036952697a7d1807..239bfd03afa2f394f50694b2336aec4d8fa6c6de 100644 (file)
@@ -410,7 +410,8 @@ class ent_menuitem_slider(Structure):
 #}
 class ent_menuitem_button(Structure):
 #{
-   _fields_ = [("pstr",c_uint32)]
+   _fields_ = [("pstr",c_uint32),
+               ("stack_behaviour",c_uint32)]
 #}
 class ent_menuitem_checkmark(Structure):
 #{
@@ -424,13 +425,19 @@ class ent_menuitem_page(Structure):
                ("id_entrypoint",c_uint32),
                ("id_viewpoint",c_uint32)]
 #}
+class ent_menuitem_binding(Structure):
+#{
+   _fields_ = [("pstr_bind",c_uint32),
+               ("font_variant",c_uint32)]
+#}
 class ent_menuitem_anon_union(Union):
 #{
    _fields_ = [("slider",ent_menuitem_slider),
                ("button",ent_menuitem_button),
                ("checkmark",ent_menuitem_checkmark),
                ("page",ent_menuitem_page),
-               ("visual",ent_menuitem_visual)]
+               ("visual",ent_menuitem_visual),
+               ("binding",ent_menuitem_binding)]
 #}
 class ent_menuitem(Structure):
 #{
@@ -1324,6 +1331,7 @@ def sr_compile_menus( collection ):
       if item.type == 1 or item.type == 2:#{
          item_button = item._anonymous_union.button
          item_button.pstr = sr_compile_string( obj_data.string )
+         item_button.stack_behaviour = int( obj_data.stack_behaviour )
       #}
       elif item.type == 0:#{
          item_visual = item._anonymous_union.visual
@@ -1351,6 +1359,11 @@ def sr_compile_menus( collection ):
          item_page.id_entrypoint = sr_entity_id( obj_data.newloc )
          item_page.id_viewpoint = sr_entity_id( obj_data.camera )
       #}
+      elif item.type == 6:#{
+         item_binding = item._anonymous_union.binding
+         item_binding.pstr_bind = sr_compile_string( obj_data.string )
+         item_binding.font_variant = obj_data.font_variant
+      #}
 
       if obj_data.link0:
          item.id_links[0] = sr_entity_id( obj_data.link0 )
@@ -3129,6 +3142,10 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
    newloc: bpy.props.PointerProperty( \
            type=bpy.types.Object, name="New location", \
            poll=lambda self,obj: sr_filter_ent_type(obj,['ent_menuitem']))
+   stack_behaviour: bpy.props.EnumProperty( name='Stack Behaviour',
+                                 items=[('0','append',''),
+                                        ('1','replace','')])
+
    camera: bpy.props.PointerProperty( \
            type=bpy.types.Object, name="Camera", \
            poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera']))
@@ -3147,6 +3164,8 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
            type=bpy.types.Object, name="Checked", \
            poll=lambda self,obj: sr_filter_ent_type(obj,['ent_menuitem']))
 
+   font_variant: bpy.props.IntProperty( name="Font Variant" )
+
    string: bpy.props.StringProperty( name="String" )
    tipo: bpy.props.EnumProperty( name='Type',
                                  items=[('0','visual',''),
@@ -3154,7 +3173,8 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
                                         ('2','page button',''),
                                         ('3','toggle', ''),
                                         ('4','slider',''),
-                                        ('5','page','')])
+                                        ('5','page',''),
+                                        ('6','binding','')])
 
    @staticmethod
    def sr_inspector( layout, data ):
@@ -3172,7 +3192,7 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
       #}
       elif data.tipo == '2':#{
          box.prop( data, 'string', text='Page' )
-         box.prop( data, 'newloc' )
+         box.prop( data, 'stack_behaviour' )
       #}
       elif data.tipo == '3':#{
          box.prop( data, 'string', text='Data (i32)' )
@@ -3195,6 +3215,11 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
          box.prop( data, 'camera', text='Viewpoint' )
          return
       #}
+      elif data.tipo == '6':#{
+         box.prop( data, 'string', text='ID' )
+         box.prop( data, 'font_variant' )
+         return
+      #}
       
       box = box.box()
       box.label( text="Links" )
index ce9424ab1f9ed46de28a4f76dbdc3f8aa9369c01..06b2c6e19e8bfd510d18d6cae6dfab7b23eabedf 100644 (file)
--- a/entity.h
+++ b/entity.h
@@ -299,9 +299,15 @@ enum ent_menuitem_type{
    k_ent_menuitem_type_toggle       = 3,
    k_ent_menuitem_type_slider       = 4,
    k_ent_menuitem_type_page         = 5,
+   k_ent_menuitem_type_binding      = 6,
    k_ent_menuitem_type_disabled     = 90
 };
 
+enum ent_menuitem_stack_behaviour{
+   k_ent_menuitem_stack_append  = 0,
+   k_ent_menuitem_stack_replace = 1
+};
+
 typedef struct ent_menuitem ent_menuitem;
 struct ent_menuitem{
    u32 type, groups, 
@@ -332,7 +338,8 @@ struct ent_menuitem{
       slider;
 
       struct{
-         u32 pstr;
+         u32 pstr,
+             stack_behaviour;
       }
       button;
 
@@ -349,6 +356,12 @@ struct ent_menuitem{
              id_viewpoint;   /* ent_camera */
       }
       page;
+
+      struct{
+         u32 pstr_bind,
+             font_variant;
+      }
+      binding;
    };
 };
 
diff --git a/font.h b/font.h
index 4361e934795fc881bc71e886d86139bb013a66a7..20f6454558ca9535e908fc23d39eefae8f01b497 100644 (file)
--- a/font.h
+++ b/font.h
@@ -280,8 +280,10 @@ float font3d_string_width( font3d *font, u32 variant_id, const char *text )
 {
    if( !text ) return 0.0f;
    float width = 0.0f;
+
+   const u8 *buf = (const u8 *)text;
    for( int i=0;; i++ ){
-      u32 c = text[i];
+      u32 c = buf[i];
       if(!c) break;
 
       ent_glyph *glyph = font3d_glyph( font, variant_id, c );
index b07b85f23a1948f8a417131f9200f8e0d07d5a22..23b872afdff1a55c4392d8bcb91bc344b0e9b670 100644 (file)
Binary files a/maps_src/mp_spawn/main.mdl and b/maps_src/mp_spawn/main.mdl differ
diff --git a/menu.h b/menu.h
index 2071440c365c2bd24a89ab102deb59a94e819e57..fa2d5812dd5a31c4892b76a9015f7733105d1eff 100644 (file)
--- a/menu.h
+++ b/menu.h
@@ -10,6 +10,7 @@
 #include "input.h"
 #include "workshop.h"
 #include "respawn.h"
+#include "gui.h"
 
 #define MENU_STACK_SIZE 8
 
@@ -165,7 +166,6 @@ static void menu_init(void){
  * Drop back a page until we're at the bottom which then we jus quit
  */
 static void menu_back_page(void){
-   vg_info( "menu_back_page()\n" );
    menu.page_depth --;
    if( menu.page_depth == 0 ){
       menu_close();
@@ -183,11 +183,16 @@ static void menu_back_page(void){
 /*
  * Open page to the string identifier
  */
-static void menu_open_page( const char *name ){
-   if( menu.page_depth >= MENU_STACK_SIZE )
-      vg_fatal_error( "Stack overflow\n" );
-
-   vg_info( "Try to open %s\n", name );
+static void menu_open_page( const char *name, 
+                            enum ent_menuitem_stack_behaviour stackmode ){
+   if( stackmode == k_ent_menuitem_stack_append ){
+      if( menu.page_depth >= MENU_STACK_SIZE )
+         vg_fatal_error( "Stack overflow\n" );
+   }
+   else{
+      if( menu.page_depth == 0 )
+         vg_fatal_error( "Stack underflow\n" );
+   }
 
    u32 hash = vg_strdjb2( name );
    for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
@@ -198,12 +203,17 @@ static void menu_open_page( const char *name ){
             u32 new_page = __builtin_ctz( item->groups );
 
             if( new_page == menu.page ){
-               menu_back_page();
+               if( stackmode != k_ent_menuitem_stack_replace )
+                  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_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;
+               
+               if( stackmode == k_ent_menuitem_stack_append )
+                  menu.page_depth ++;
+
                menu.page = __builtin_ctz( item->groups );
 
                if( menu.input_mode == k_menu_input_mode_keys ){
@@ -217,8 +227,6 @@ static void menu_open_page( const char *name ){
                   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;
          }
@@ -263,7 +271,8 @@ static void menu_trigger_item( ent_menuitem *item ){
       }
    }
    else if( item->type == k_ent_menuitem_type_page_button ){
-      menu_open_page( mdl_pstr( &menu.model, item->button.pstr ) );
+      menu_open_page( mdl_pstr( &menu.model, item->button.pstr ),
+                      item->button.stack_behaviour );
    }
    else if( item->type == k_ent_menuitem_type_toggle ){
       if( item->pi32 ){
@@ -314,7 +323,7 @@ static void menu_update(void){
       if( skaterift.activity == k_skaterift_default ){
          skaterift.activity = k_skaterift_menu;
          menu.page = 0xffffffff;
-         menu_open_page( "Main Menu" );
+         menu_open_page( "Main Menu", k_ent_menuitem_stack_append );
          return;
       }
    }
@@ -422,6 +431,7 @@ static void menu_update(void){
 
          if( item->type == k_ent_menuitem_type_page ) continue;
          if( item->type == k_ent_menuitem_type_visual ) continue;
+         if( item->type == k_ent_menuitem_type_binding ) continue;
          if( !(item->groups & (0x1<<menu.page)) ) continue;
 
          ent_menuitem *ray_item = item;
@@ -564,6 +574,8 @@ static void menu_update(void){
    }
 }
 
+VG_STATIC void menu_binding_string( char buf[128], u32 pstr );
+
 /*
  * Run from vg_gui when active
  */
@@ -662,6 +674,9 @@ VG_STATIC void menu_render(void){
    ui_hex_to_norm( ui_colour( k_ui_fg ), white );
    ui_hex_to_norm( ui_colour( k_ui_orange+k_ui_brighter ), blue );
 
+   ent_menuitem *text_list[ 8 ];
+   u32 text_count = 0;
+
    for( u32 i=0; i<mdl_arrcount(&menu.items); i++ ){
       ent_menuitem *item = mdl_arritm( &menu.items, i );
 
@@ -669,6 +684,15 @@ VG_STATIC void menu_render(void){
       if(   item->type == k_ent_menuitem_type_page ) continue;
       if( !(item->groups & (0x1 << menu.page)) ) continue;
 
+      if(   item->type == k_ent_menuitem_type_binding ){
+         if( text_count < vg_list_size(text_list) )
+            text_list[ text_count ++ ] = item;
+         else
+            vg_fatal_error( "Text list overflow" );
+
+         continue;  
+      }
+
       int selected = 0;
       
       if( menu.loc ){
@@ -683,10 +707,15 @@ VG_STATIC void menu_render(void){
          }
       }
 
-      item->factive = vg_lerpf( item->factive, selected, rate );
-      v4f colour;
-      v4_lerp( white, blue, item->factive, colour );
-      shader_model_menu_uColour( colour );
+      if( item->type == k_ent_menuitem_type_visual ){
+         shader_model_menu_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
+      }
+      else{
+         v4f colour;
+         item->factive = vg_lerpf( item->factive, selected, rate );
+         v4_lerp( white, blue, item->factive, colour );
+         shader_model_menu_uColour( colour );
+      }
 
       f32 scale = 1.0f+item->factive*0.1f;
 
@@ -724,6 +753,65 @@ VG_STATIC void menu_render(void){
          mdl_draw_submesh( mdl_arritm( &menu.model.submeshs, index ));
       }
    }
+
+   if( !text_count ) return;
+
+   char buf[ 128 ];
+
+   m4x3f local;
+   m4x3_identity( local );
+
+   font3d_bind( &gui.font, &menu.view );
+   for( u32 i=0; i<text_count; i++ ){
+      ent_menuitem *item = text_list[ i ];
+      m4x3f transform;
+      mdl_transform_m4x3( &item->transform, transform );
+
+      u32 variant = item->binding.font_variant;
+      menu_binding_string( buf, item->binding.pstr_bind );
+      f32 offset = font3d_string_width( &gui.font, variant, buf );
+
+      local[3][0] = -0.5f * offset;
+      m4x3_mul( transform, local, transform );
+
+      font3d_simple_draw( &gui.font, variant, k_font_shader_default, buf, 
+                          &menu.view, transform );
+   }
+}
+
+VG_STATIC void menu_binding_string( char buf[128], u32 pstr ){
+   vg_strncpy( "error", buf, 128, k_strncpy_allow_cutoff );
+
+   if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_jump" ) ){
+      vg_strncpy( button_display_string(k_srbind_jump), buf, 128, 
+                  k_strncpy_allow_cutoff );
+   }
+   else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick0" ) ){
+      vg_str str;
+      vg_strnull( &str, buf, 128 );
+      vg_strcat( &str, "SHUVIT " );
+      vg_strcat( &str, button_display_string(k_srbind_trick0) );
+   }
+   else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick1" ) ){
+      vg_str str;
+      vg_strnull( &str, buf, 128 );
+      vg_strcat( &str, "KICKFLIP " );
+      vg_strcat( &str, button_display_string(k_srbind_trick1) );
+   }
+   else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_trick2" ) ){
+      vg_str str;
+      vg_strnull( &str, buf, 128 );
+      vg_strcat( &str, "TREFLIP " );
+      vg_strcat( &str, button_display_string(k_srbind_trick2) );
+   }
+   else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_grab" ) ){
+      vg_strncpy( axis_display_string(k_sraxis_grab), buf, 128,
+                  k_strncpy_allow_cutoff );
+   }
+   else if( MDL_CONST_PSTREQ( &menu.model, pstr, "bind_grab_mod" ) ){
+      vg_strncpy( joystick_display_string(k_srjoystick_grab, 2), buf, 128,
+                  k_strncpy_allow_cutoff );
+   }
 }
 
 #endif /* MENU_H */
index 00199821d9746e85f220dbddc9626ab13195ee3c..7d2d8084a07476f0543800827b25f2c942071cd1 100644 (file)
Binary files a/models_src/rs_font.mdl and b/models_src/rs_font.mdl differ
diff --git a/models_src/rs_icons.mdl b/models_src/rs_icons.mdl
new file mode 100644 (file)
index 0000000..e41da35
Binary files /dev/null and b/models_src/rs_icons.mdl differ
index 74e5e8822c0f7a51bf08125b99b15166ff15f50d..8fde8f748fff903f948eb8eb50bd510c192558b1 100644 (file)
Binary files a/models_src/rs_menu.mdl and b/models_src/rs_menu.mdl differ
index 0cee183b94755a9300bb21e69d599707acea82dc..b6e3874907f7d0a368714ff96bc5b7f95929f785 100644 (file)
--- a/respawn.c
+++ b/respawn.c
@@ -87,7 +87,7 @@ VG_STATIC void respawn_chooser_pre_update(void){
       srinput.enabled = 0;
       skaterift.activity = k_skaterift_menu;
       menu.page = 0xffffffff;
-      menu_open_page( "Main Menu" );
+      menu_open_page( "Main Menu", k_ent_menuitem_stack_append );
       return;
    }