From f24a8cdd8ea6c3d762d26de2fc0700599bedbcad Mon Sep 17 00:00:00 2001 From: hgn Date: Sat, 29 Apr 2023 15:03:04 +0100 Subject: [PATCH] boards now pickable --- ent_skateshop.c | 212 +++++++++++++++++++++++++----------------------- ent_skateshop.h | 78 ++++++++++++++++++ highscores.h | 21 +++-- input.h | 7 ++ player.h | 3 +- player_common.c | 15 ++++ player_render.c | 6 +- player_skate.c | 3 +- player_walk.c | 4 + 9 files changed, 232 insertions(+), 117 deletions(-) create mode 100644 ent_skateshop.h diff --git a/ent_skateshop.c b/ent_skateshop.c index 6cf47dc..3ebc9f0 100644 --- a/ent_skateshop.c +++ b/ent_skateshop.c @@ -1,82 +1,11 @@ #ifndef ENT_SKATESHOP_C #define ENT_SKATESHOP_C +#include "ent_skateshop.h" #include "world.h" #include "player.h" #include "gui.h" -#define MAX_LOCAL_BOARDS 64 -#define BILL_TIN_BOARDS 1 -#define MAX_DYNAMIC_BOARDS 9 - -struct{ - v3f look_target; - ent_skateshop *ptr_ent; - - int active; - float factive; - - enum skateshop_loc{ - k_skateshop_loc_page__viewing, - - k_skateshop_loc_select_use, - k_skateshop_loc_select_cancel, - k_skateshop_loc_select_upload, - k_skateshop_loc_page__selected, - - k_skateshop_loc_page__upload, - } - interface_loc; - - struct dynamic_board - { - enum dynamic_board_state{ - k_dynamic_board_state_none, - k_dynamic_board_state_loaded, - k_dynamic_board_state_loading, - } - state; - - u32 ref_count; - - struct player_board board; - - u32 registry_id; - - double last_use_time; - } - *dynamic_boards, - *localplayer_slot; - - struct shop_view_slot - { - struct dynamic_board *db; - float view_blend; - } - shop_view_slots[6]; - - struct board_registry - { - int workshop; - u64 uid; - - struct dynamic_board *dynamic; - - char filename[64]; /* if workshop, string version of uid. */ - u32 filename_hash; - - int ghost; - } - *registry; - u32 registry_count; - - int loading; - float interaction_cooldown; - - u32 selected_registry_id; -} -static global_skateshop; - static inline int const_str_eq( u32 hash, const char *str, const char *cmp ) { if( hash == vg_strdjb2(cmp) ) @@ -127,8 +56,6 @@ struct dynamic_board *skateshop_lru_alloc( u32 id ) } if( min_board ){ - localplayer.board = NULL; /* temp */ - if( min_board->state == k_dynamic_board_state_loaded ){ struct board_registry *other = &global_skateshop.registry[min_board->registry_id]; @@ -167,22 +94,45 @@ void skateshop_board_registry_path( struct board_registry *reg, char path[256] ) } } +/* we can only keep using a viewslot pointer for multiple frames if we watch it + * using this function */ +VG_STATIC void watch_dynamic_board( struct dynamic_board *db ) +{ + if( db->ref_count >= 32 ){ + vg_fatal_error( "dynamic board watch missmatch (limit is 32)\n" ); + } + + db->last_use_time = vg.time; + db->ref_count ++; +} + +/* after this is called, the calling code only has access to the pointer for the + * duration of a frame */ +VG_STATIC void unwatch_dynamic_board( struct dynamic_board *db ) +{ + if( db->ref_count == 0 ){ + vg_fatal_error( "dynamic board unwatch missmatch (no watchers)\n" ); + } + + db->ref_count --; +} + VG_STATIC void skateshop_async_board_complete( void *payload, u32 size ) { struct dynamic_board *db = payload; - if( db == global_skateshop.localplayer_slot ){ - localplayer.board = &db->board; - db->ref_count ++; - } - else{ - for( u32 i=0; iref_count ++; - } + /* all possible view slots are 'listening' for this event, + * which must be checked here */ + for( u32 i=0; ilast_use_time = vg.time; db->state = k_dynamic_board_state_loaded; @@ -229,20 +179,25 @@ VG_STATIC int skateshop_use_board( int argc, const char *argv[] ) struct board_registry *reg = &global_skateshop.registry[i]; if( const_str_eq( hash, argv[0], reg->filename ) ){ - if( reg->dynamic ){ struct dynamic_board *db = reg->dynamic; if( db->state == k_dynamic_board_state_loaded ){ - localplayer.board = &db->board; - db->last_use_time = vg.time; + localplayer.board_view_slot = db; + watch_dynamic_board( db ); } else{ vg_fatal_error( "Invalid state while loading board\n" ); } } else{ + if( localplayer.board_view_slot ){ + unwatch_dynamic_board( localplayer.board_view_slot ); + localplayer.board_view_slot = NULL; + } + struct dynamic_board *db = skateshop_lru_alloc( i ); + localplayer.board_view_slot = db; db->state = k_dynamic_board_state_loading; skateshop_loader_start( skateshop_thread1_refresh ); } @@ -326,6 +281,7 @@ VG_STATIC void global_skateshop_exit(void) vg_info( "exit skateshop\n" ); localplayer.immobile = 0; global_skateshop.active = 0; + srinput.ignore_input_frames = 2; } VG_STATIC void skateshop_request_viewpage( u32 page ) @@ -441,8 +397,18 @@ VG_STATIC void global_skateshop_preupdate(void) if( global_skateshop.interface_loc <= k_skateshop_loc_page__viewing ){ gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" ); - gui_helper_action( button_display_string( k_srbind_maccept ), "pick" ); gui_helper_action( button_display_string( k_srbind_mback ), "exit" ); + + u32 reg_id = global_skateshop.selected_registry_id; + struct board_registry *picker = &global_skateshop.registry[ reg_id ]; + + int pick_availible = 0; + if( picker->dynamic && + (picker->dynamic->state == k_dynamic_board_state_loaded ) ) + { + pick_availible = 1; + gui_helper_action( button_display_string( k_srbind_maccept ), "pick" ); + } int moved = 0; @@ -469,6 +435,21 @@ VG_STATIC void global_skateshop_preupdate(void) return; } + if( pick_availible && button_down( k_srbind_maccept ) ){ + vg_info( "chose board from skateshop (%u)\n", reg_id ); + + if( localplayer.board_view_slot ){ + unwatch_dynamic_board( localplayer.board_view_slot ); + localplayer.board_view_slot = NULL; + } + + localplayer.board_view_slot = picker->dynamic; + watch_dynamic_board( localplayer.board_view_slot ); + + global_skateshop_exit(); + return; + } + if( button_down( k_srbind_mback ) ){ global_skateshop_exit(); return; @@ -511,6 +492,11 @@ VG_STATIC void skateshop_render(void) world_instance *world = get_active_world(); u32 slot_count = vg_list_size(global_skateshop.shop_view_slots); + + ent_marker *mark_rack = mdl_arritm( &world->ent_marker, + mdl_entity_id_id(shop->id_rack)), + *mark_display = mdl_arritm( &world->ent_marker, + mdl_entity_id_id(shop->id_display)); for( u32 i=0; ient_marker, - mdl_entity_id_id(shop->id_rack)), - *display = mdl_arritm( &world->ent_marker, - mdl_entity_id_id(shop->id_display)); - - mdl_transform_mul( &rack->transform, &xform, &xform ); + mdl_transform_mul( &mark_rack->transform, &xform, &xform ); if( slot->db->registry_id == global_skateshop.selected_registry_id ){ selected = 1.0f; } float t = slot->view_blend; - v3_lerp( xform.co, display->transform.co, t, xform.co ); - q_nlerp( xform.q, display->transform.q, t, xform.q ); - v3_lerp( xform.s, display->transform.s, t, xform.s ); + v3_lerp( xform.co, mark_display->transform.co, t, xform.co ); + q_nlerp( xform.q, mark_display->transform.q, t, xform.q ); + v3_lerp( xform.s, mark_display->transform.s, t, xform.s ); m4x3f mmdl; mdl_transform_m4x3( &xform, mmdl ); @@ -554,10 +535,11 @@ set_fade_amt:; slot->view_blend = vg_lerpf( slot->view_blend, selected, rate ); } - ent_marker *info = mdl_arritm( &world->ent_marker, + ent_marker *mark_info = mdl_arritm( &world->ent_marker, mdl_entity_id_id(shop->id_info)); - m4x3f mtext; - mdl_transform_m4x3( &info->transform, mtext ); + m4x3f mtext, mrack; + mdl_transform_m4x3( &mark_info->transform, mtext ); + mdl_transform_m4x3( &mark_rack->transform, mrack ); const char *text_title = "Fish - Title"; const char *text_author = "by Shaniqua"; @@ -565,10 +547,12 @@ set_fade_amt:; m4x3f mlocal, mmdl; m4x3_identity( mlocal ); - float scale = 0.2f; + /* Skin title + * ----------------------------------------------------------------- */ + float scale = 0.2f, + thickness = 0.03f; - mlocal[0][0] = scale; mlocal[1][1] = scale; - mlocal[2][2] = 0.03f; + m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } ); mlocal[3][0] = -font3d_string_width(&world_global.font,0,text_title); mlocal[3][0] *= scale*0.5f; mlocal[3][1] = 0.1f; @@ -579,13 +563,35 @@ set_fade_amt:; shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} ); font3d_simple_draw( &world_global.font, 0, text_title, &main_camera, mmdl ); + /* Author name + * ----------------------------------------------------------------- */ scale *= 0.4f; - mlocal[0][0] = scale; mlocal[1][1] = scale; + m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } ); mlocal[3][0] = -font3d_string_width(&world_global.font,0,text_author); mlocal[3][0] *= scale*0.5f; mlocal[3][1] = 0.0f; m4x3_mul( mtext, mlocal, mmdl ); font3d_simple_draw( &world_global.font, 0, text_author, &main_camera, mmdl ); + + /* Selection counter + * ------------------------------------------------------------------ */ + scale = 0.4f; + m3x3_zero( mlocal ); + v3_zero( mlocal[3] ); + mlocal[0][0] = -scale; + mlocal[1][2] = -scale; + mlocal[2][1] = -thickness; + mlocal[3][2] = -0.7f; + m4x3_mul( mrack, mlocal, mmdl ); + + char buf[16]; + int i=0; + i+=highscore_intl( buf+i, global_skateshop.selected_registry_id+1, 3 ); + buf[i++] = '/'; + i+=highscore_intl( buf+i, global_skateshop.registry_count, 3 ); + buf[i++] = '\0'; + + font3d_simple_draw( &world_global.font, 0, buf, &main_camera, mmdl ); } #endif /* ENT_SKATESHOP_C */ diff --git a/ent_skateshop.h b/ent_skateshop.h new file mode 100644 index 0000000..e7acd43 --- /dev/null +++ b/ent_skateshop.h @@ -0,0 +1,78 @@ +#ifndef ENT_SKATESHOP_H +#define ENT_SKATESHOP_H + +#include "world.h" +#include "player.h" + +#define MAX_LOCAL_BOARDS 64 +#define BILL_TIN_BOARDS 1 +#define MAX_DYNAMIC_BOARDS 9 + +struct{ + v3f look_target; + ent_skateshop *ptr_ent; + + int active; + float factive; + + enum skateshop_loc{ + k_skateshop_loc_page__viewing, + + k_skateshop_loc_select_use, + k_skateshop_loc_select_cancel, + k_skateshop_loc_select_upload, + k_skateshop_loc_page__selected, + + k_skateshop_loc_page__upload, + } + interface_loc; + + struct dynamic_board + { + enum dynamic_board_state{ + k_dynamic_board_state_none, + k_dynamic_board_state_loaded, + k_dynamic_board_state_loading, + } + state; + + u32 ref_count; + + struct player_board board; + + u32 registry_id; + + double last_use_time; + } + *dynamic_boards; + + struct shop_view_slot + { + struct dynamic_board *db; + float view_blend; + } + shop_view_slots[6]; + + struct board_registry + { + int workshop; + u64 uid; + + struct dynamic_board *dynamic; + + char filename[64]; /* if workshop, string version of uid. */ + u32 filename_hash; + + int ghost; + } + *registry; + u32 registry_count; + + int loading; + float interaction_cooldown; + + u32 selected_registry_id; +} +static global_skateshop; + +#endif /* ENT_SKATESHOP_H */ diff --git a/highscores.h b/highscores.h index 079e4d8..3a20717 100644 --- a/highscores.h +++ b/highscores.h @@ -478,13 +478,14 @@ VG_STATIC void highscore_strr( char *buf, const char *str, int len, int width ) } } -/* Print integer (padded with: alt), right aligned into buf(width: len) */ -VG_STATIC void highscore_intr( char *buf, int value, int len, char alt ) +/* Print integer (padded with: alt), right aligned into buf(width: len) + * returns number of digits (not including alt), that were written to buf */ +VG_STATIC int highscore_intr( char *buf, int value, int len, char alt ) { int i=0; while(value){ if( i>=len ) - return; + return i; buf[ len-1 - (i ++) ] = '0' + (value % 10); value /= 10; @@ -492,16 +493,18 @@ VG_STATIC void highscore_intr( char *buf, int value, int len, char alt ) for( ;i=len ) break; @@ -513,9 +516,9 @@ VG_STATIC void highscore_intl( char *buf, int value, int len ) i = len; for( int j=0; jstate == k_dynamic_board_state_loaded ){ + board = &vs->board; + } + } + + return board; +} + #endif /* PLAYER_COMMON_C */ diff --git a/player_render.c b/player_render.c index 3372424..f34aa16 100644 --- a/player_render.c +++ b/player_render.c @@ -5,6 +5,7 @@ #include "player_render.h" #include "camera.h" #include "player_model.h" +#include "ent_skateshop.h" #include "shaders/model_character_view.h" #include "shaders/model_board_view.h" @@ -159,8 +160,7 @@ VG_STATIC void player__pre_render( player_instance *player ) _player_post_animate[ player->subsystem ]( player ); struct player_avatar *av = player->playeravatar; - - struct player_board *board = player->board; + struct player_board *board = player_get_player_board( player ); v3f vp0, vp1; @@ -438,7 +438,7 @@ PLAYER_API void player__render( camera *cam, player_instance *player ) mesh_bind( &player->playermodel->mesh ); mesh_draw( &player->playermodel->mesh ); - struct player_board *board = player->board; + struct player_board *board = player_get_player_board( player ); render_board( cam, world, board, player->playeravatar->sk.final_mtx[ player->playeravatar->id_board], diff --git a/player_skate.c b/player_skate.c index d1be6b8..e1971b2 100644 --- a/player_skate.c +++ b/player_skate.c @@ -5,6 +5,7 @@ #include "audio.h" #include "vg/vg_perlin.h" #include "menu.h" +#include "ent_skateshop.h" VG_STATIC void player__skate_bind( player_instance *player ) { @@ -2966,7 +2967,7 @@ VG_STATIC void player__skate_animate( player_instance *player, q_mul( kf_board->q, qtrick, kf_board->q ); q_normalize( kf_board->q ); - struct player_board *board = player->board; + struct player_board *board = player_get_player_board( player ); if( board ){ /* foot weight distribution */ diff --git a/player_walk.c b/player_walk.c index 1845906..be2195f 100644 --- a/player_walk.c +++ b/player_walk.c @@ -69,6 +69,7 @@ VG_STATIC void player_walk_generic_to_skate( player_instance *player, VG_STATIC void player_walk_drop_in_to_skate( player_instance *player ) { + player->immobile = 0; player->subsystem = k_player_subsystem_skate; struct player_walk *w = &player->_walk; @@ -282,6 +283,9 @@ VG_STATIC void player__walk_pre_update( player_instance *player ) player->subsystem = k_player_subsystem_drive; } else{ + if( !player_get_player_board(player) ) + return; + if( w->state.activity == k_walk_activity_ground ){ if( player_walk_scan_for_drop_in( player ) ){ w->state.outro_type = k_walk_outro_drop_in; -- 2.25.1