From: hgn Date: Tue, 19 Sep 2023 07:17:43 +0000 (+0100) Subject: gui icons X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;ds=inline;h=56af37b4982b027cac13133eadadfc71ce8947bb;hp=53597f45307d8a2120e3a0bbe71797b216e8750b;p=carveJwlIkooP6JGAAIwe30JlM.git gui icons --- diff --git a/gui.h b/gui.h index 8013cb0..433ba83 100644 --- a/gui.h +++ b/gui.h @@ -5,6 +5,16 @@ #include "input.h" #include "player.h" +enum gui_icon { + k_gui_icon_tick = 0, + k_gui_icon_exclaim, + k_gui_icon_board, + k_gui_icon_world, + k_gui_icon_rift, + + k_gui_icon_count, +}; + struct{ struct gui_helper{ const char *bindstr, *text; @@ -12,6 +22,13 @@ struct{ helpers[4]; u32 helper_count; + struct icon_call { + enum gui_icon icon; + v4f location; + } + icon_draw_buffer[32]; + u32 icon_draw_count; + char location[64]; f64 location_time; @@ -28,6 +45,12 @@ struct{ k_guitrick_type_isc } trick_type; + + mdl_context model_icons; + GLuint icons_texture; + glmesh icons_mesh; + + mdl_submesh *icons[ k_gui_icon_count ]; } static gui; @@ -89,6 +112,37 @@ void gui_draw(void) m4x4_mul( ortho.mtx.p, ortho.mtx.v, ortho.mtx.pv ); /* HACK */ camera_finalize( &ortho ); + + + + + /* icons */ + font3d_bind( &gui.font, &ortho ); + m4x3f mmdl; + m4x3_identity( mmdl ); + shader_model_font_uMdl( mmdl ); + + mesh_bind( &gui.icons_mesh ); + shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} ); + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, gui.icons_texture ); + shader_model_font_uTexMain( 0 ); + + for( u32 i=0; ilocation ); + + mdl_submesh *sm = gui.icons[ call->icon ]; + if( sm ) + mdl_draw_submesh( sm ); + } + + gui.icon_draw_count = 0; + + + + + gui.factive = vg_lerpf( gui.factive, gui.helper_count?1.0f:0.0f, vg.time_frame_delta*2.0f ); @@ -122,7 +176,6 @@ void gui_draw(void) f32 dy = ft/0.79f, scale = dy*0x1p-4f*0.5f; - m4x3f mmdl; m3x3_identity( mmdl ); m3x3_scale( mmdl, (v3f){scale,scale,scale} ); v3_zero( mmdl[3] ); @@ -144,7 +197,6 @@ void gui_draw(void) float dy = ft/0.79f, scale = dy*0x1p-4f*0.75f; - m4x3f mmdl; m3x3_identity( mmdl ); m3x3_scale( mmdl, (v3f){scale,scale,scale} ); v3_zero( mmdl[3] ); @@ -213,11 +265,58 @@ VG_STATIC int gui_showtrick_ccmd( int argc, const char *argv[] ){ return 1; } -VG_STATIC void gui_init(void) -{ +VG_STATIC void gui_draw_icon( enum gui_icon icon, v2f co, f32 size ){ + if( gui.icon_draw_count == vg_list_size(gui.icon_draw_buffer) ) + return; + + struct icon_call *call = &gui.icon_draw_buffer[ gui.icon_draw_count ++ ]; + + call->icon = icon; + call->location[0] = co[0] * (f32)vg.window_x; + call->location[1] = co[1] * (f32)vg.window_y; + call->location[2] = 0.0f; + call->location[3] = size * (f32)vg.window_x; +} + +static mdl_submesh *gui_find_icon( const char *name ){ + mdl_mesh *mesh = mdl_find_mesh( &gui.model_icons, name ); + if( mesh ){ + if( mesh->submesh_count ){ + return mdl_arritm( &gui.model_icons.submeshs, mesh->submesh_start ); + } + } + + return NULL; +} + +VG_STATIC void gui_init(void){ font3d_load( &gui.font, "models/rs_font.mdl", vg_mem.rtmemory ); vg_console_reg_cmd( "gui_location", gui_location_print_ccmd, NULL ); vg_console_reg_cmd( "showtrick", gui_showtrick_ccmd, NULL ); + + /* load icons */ + void *alloc = vg_mem.rtmemory; + mdl_open( &gui.model_icons, "models/rs_icons.mdl", alloc ); + mdl_load_metadata_block( &gui.model_icons, alloc ); + + gui.icons[ k_gui_icon_tick ] = gui_find_icon( "icon_tick" ); + gui.icons[ k_gui_icon_exclaim ] = gui_find_icon( "icon_exclaim" ); + gui.icons[ k_gui_icon_board ] = gui_find_icon( "icon_board" ); + gui.icons[ k_gui_icon_world ] = gui_find_icon( "icon_world" ); + gui.icons[ k_gui_icon_rift ] = gui_find_icon( "icon_rift" ); + + vg_linear_clear( vg_mem.scratch ); + if( !mdl_arrcount( &gui.model_icons.textures ) ) + vg_fatal_error( "No texture in menu file" ); + mdl_texture *tex0 = mdl_arritm( &gui.model_icons.textures, 0 ); + void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size ); + mdl_fread_pack_file( &gui.model_icons, &tex0->file, data ); + vg_tex2d_load_qoi_async( data, tex0->file.pack_size, + VG_TEX2D_LINEAR|VG_TEX2D_CLAMP, + &gui.icons_texture ); + + mdl_async_load_glmesh( &gui.model_icons, &gui.icons_mesh ); + mdl_close( &gui.model_icons ); } #endif /* GUI_H */ diff --git a/maps_src/mp_mtzero/main.mdl b/maps_src/mp_mtzero/main.mdl index 1dbaed8..29eebf3 100644 Binary files a/maps_src/mp_mtzero/main.mdl and b/maps_src/mp_mtzero/main.mdl differ diff --git a/maps_src/mp_spawn/main.mdl b/maps_src/mp_spawn/main.mdl index 23b872a..b5614cf 100644 Binary files a/maps_src/mp_spawn/main.mdl and b/maps_src/mp_spawn/main.mdl differ diff --git a/models_src/rs_icons.mdl b/models_src/rs_icons.mdl index e41da35..92858f2 100644 Binary files a/models_src/rs_icons.mdl and b/models_src/rs_icons.mdl differ diff --git a/models_src/rs_menu.mdl b/models_src/rs_menu.mdl index 8fde8f7..04b4c17 100644 Binary files a/models_src/rs_menu.mdl and b/models_src/rs_menu.mdl differ diff --git a/respawn.c b/respawn.c index b6e3874..50ddea2 100644 --- a/respawn.c +++ b/respawn.c @@ -73,6 +73,16 @@ VG_STATIC void respawn_chooser_gohome(void){ gui_location_print_ccmd( 1, (const char *[]){ "Invalid home ID" } ); } +VG_STATIC void respawn_map_draw_icon( camera *cam, + enum gui_icon icon, v3f pos ){ + v4f v; + v3_copy( pos, v ); + v[3] = 1.0f; + m4x4_mulv( cam->mtx.pv, v, v ); + v2_divs( v, v[3], v ); + + gui_draw_icon( icon, (v2f){ v[0]*0.5f+0.5f,v[1]*0.5f+0.5f }, 1.0f ); +} VG_STATIC void respawn_chooser_pre_update(void){ if( skaterift.activity != k_skaterift_respawning ) return; @@ -173,6 +183,7 @@ VG_STATIC void respawn_chooser_pre_update(void){ v3_copy( spawn->transform.co, v ); v[3] = 1.0f; m4x4_mulv( cam->mtx.pv, v, v ); + v2_divs( v, v[3], v ); f32 d2 = v2_length2(v); if( d2 < closest2 ){ @@ -181,8 +192,33 @@ VG_STATIC void respawn_chooser_pre_update(void){ } } - if( respawn_chooser.spawn ){ - vg_line_cross( respawn_chooser.spawn->transform.co, VG__GREEN, 5.0f ); + /* icons + * ---------------------*/ + for( u32 i=0; ient_challenge); i++ ){ + ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i ); + + enum gui_icon icon = k_gui_icon_exclaim; + if( challenge->status ) + icon = k_gui_icon_tick; + + respawn_map_draw_icon( cam, icon, challenge->transform.co ); + } + + for( u32 i=0; ient_skateshop); i++ ){ + ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i ); + if( shop->type == k_skateshop_type_boardshop ){ + respawn_map_draw_icon( cam, k_gui_icon_board, shop->transform.co ); + } + else if( shop->type == k_skateshop_type_worldshop ){ + respawn_map_draw_icon( cam, k_gui_icon_world, shop->transform.co ); + } + } + + for( u32 i=0; ient_gate); i++ ){ + ent_gate *gate = mdl_arritm( &world->ent_gate, i ); + if( gate->flags & k_ent_gate_nonlocal ){ + respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0] ); + } } } diff --git a/world_gate.c b/world_gate.c index 765a099..b4760b4 100644 --- a/world_gate.c +++ b/world_gate.c @@ -321,8 +321,8 @@ VG_STATIC void world_link_nonlocal_async( void *payload, u32 size ){ if( other->status != k_world_status_loaded ) continue; vg_info( "Checking world %u for key matches\n", i ); - for( u32 j=0; jent_gate ); j++ ){ - ent_gate *gate2 = mdl_arritm( &other->ent_gate, j ); + for( u32 k=0; kent_gate ); k++ ){ + ent_gate *gate2 = mdl_arritm( &other->ent_gate, k ); if( !(gate2->flags & k_ent_gate_nonlocal) ) continue; if( gate2->flags & k_ent_gate_linked ) continue; @@ -345,11 +345,7 @@ VG_STATIC void world_link_nonlocal_async( void *payload, u32 size ){ v4_copy( gate->q[0], gate2->q[1] ); v4_copy( gate2->q[0], gate->q[1] ); - if( world->meta.info.version >= 102 ){ - gate->flags |= k_ent_gate_flip; - gate2->flags |= k_ent_gate_flip; - } - else { + if( world->meta.info.version < 102 ){ /* LEGACY BEHAVIOUR: v101 * this would flip both the client worlds portal's entrance and * exit. effectively the clients portal would be the opposite @@ -360,6 +356,7 @@ VG_STATIC void world_link_nonlocal_async( void *payload, u32 size ){ q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); q_mul( gate->q[0], qflip, gate->q[0] ); q_mul( gate->q[1], qflip, gate->q[1] ); + q_mul( gate2->q[1], qflip, gate2->q[1] ); } gate_transform_update( gate ); @@ -367,8 +364,7 @@ VG_STATIC void world_link_nonlocal_async( void *payload, u32 size ){ goto matched; } - } -matched:; + } matched:; } } diff --git a/world_load.c b/world_load.c index 2ca957a..ee7df7d 100644 --- a/world_load.c +++ b/world_load.c @@ -265,6 +265,11 @@ static void skaterift_change_world_start( addon_reg *reg ){ if( world_static.active_instance != 0 ) vg_error( "Cannot change worlds while in non-root world\n" ); else{ + if( world_static.addon_client == reg ){ + vg_warn( "World is already loaded\n" ); + return; + } + char buf[76]; addon_alias_uid( ®->alias, buf ); vg_info( "switching to: %s\n", buf ); @@ -291,6 +296,8 @@ static void skaterift_change_world_start( addon_reg *reg ){ /* console command for the above function */ static int skaterift_change_world_command( int argc, const char *argv[] ){ + if( !vg_loader_availible() ) return 0; + if( argc == 1 ){ addon_alias q; q.type = k_addon_type_world;