From: hgn Date: Sat, 22 Mar 2025 16:28:06 +0000 (+0000) Subject: Board exporter dialogue X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=645810b4658f22c15805a4aeee4d07e9513789f7;p=carveJwlIkooP6JGAAIwe30JlM.git Board exporter dialogue --- diff --git a/build.c b/build.c index 8024a3b..634262a 100644 --- a/build.c +++ b/build.c @@ -89,8 +89,8 @@ void build_game_metadata(void) "Aaron", "ch_aaron.mdl", "content_skaterift/playermodels/skaterift_aaron/addon.inf", 0 ); write_generic_addon_inf( k_addon_type_player, - "J", "ch_j.mdl", - "content_skaterift/playermodels/skaterift_j/addon.inf", 0 ); + "JC", "ch_john.mdl", + "content_skaterift/playermodels/skaterift_john/addon.inf", 0 ); write_generic_addon_inf( k_addon_type_player, "Ela", "ch_ela.mdl", "content_skaterift/playermodels/skaterift_ela/addon.inf", 0 ); diff --git a/content_skaterift/playermodels/skaterift_john/addon.inf b/content_skaterift/playermodels/skaterift_john/addon.inf new file mode 100644 index 0000000..bb48fd9 Binary files /dev/null and b/content_skaterift/playermodels/skaterift_john/addon.inf differ diff --git a/src/addon.c b/src/addon.c index 164699b..eac4fcb 100644 --- a/src/addon.c +++ b/src/addon.c @@ -451,15 +451,9 @@ addon_reg *addon_mount_local_addon( const char *folder, enum addon_type type, co } else { - /* create our own content commands */ - vg_msg msg; - vg_msg_init( &msg, reg->metadata, sizeof(reg->metadata) ); - - u32 content_count = 0; - - vg_strcat( &folder_path, "" ); - vg_warn( "Creating own metadata for: %s\n", folder_path.buffer ); - + vg_strcat( &folder_path, "" ); /* NOTE: this looks fucky because try_load_metadata edits the buffer, this sets it + back. to remove the addon.inf which it appened to that buffer (but not + edit the vg_str)....... */ vg_dir subdir; enum dir_open_result result = vg_dir_open(&subdir, folder_path.buffer); if( result != k_dir_open_ok ) @@ -468,6 +462,18 @@ addon_reg *addon_mount_local_addon( const char *folder, enum addon_type type, co return NULL; } + /* create our own content commands */ + vg_msg msg; + vg_msg_init( &msg, reg->metadata, sizeof(reg->metadata) ); + vg_msg_frame( &msg, "workshop" ); + { + vg_msg_wkvstr( &msg, "title", reg->alias.foldername ); + vg_msg_wkvstr( &msg, "author", "Custom Mod" ); + } + vg_msg_end_frame( &msg ); + + u32 content_count = 0; + while( vg_dir_next_entry(&subdir) ) { if( vg_dir_entry_type(&subdir) == k_vg_entry_type_file ) @@ -488,7 +494,9 @@ addon_reg *addon_mount_local_addon( const char *folder, enum addon_type type, co } vg_dir_close(&subdir); - if( !content_count ) return NULL; + if( !content_count ) + return NULL; + if( msg.error == k_vg_msg_error_OK ) reg->metadata_len = msg.cur.co; else diff --git a/src/board_maker.c b/src/board_maker.c index af05a51..77c6eb3 100644 --- a/src/board_maker.c +++ b/src/board_maker.c @@ -134,6 +134,22 @@ static void _board_maker_init_thread( void *_ ) static void _board_maker_export(void) { + char folder[ 128 ]; + vg_str folder_str; + vg_strnull( &folder_str, folder, sizeof(folder) ); + vg_strcat( &folder_str, _board_maker.export_path ); + char *slash = vg_strch( &folder_str, '/' ); + if( slash ) + slash[0] = '\0'; + else + { + _board_maker.export_success = 0; + _board_maker.export_message = "???"; + _board_maker.ui_state = k_board_maker_ui_state_export_signal_done; + return; + } + vg_make_directory( folder ); + mdl_compiler compiler; mdl_compiler_init( &compiler ); @@ -156,6 +172,10 @@ static void _board_maker_export(void) { free( raw_data ); free( qoi_data ); + + _board_maker.export_success = 0; + _board_maker.export_message = "Texture failed to compress"; + _board_maker.ui_state = k_board_maker_ui_state_export_signal_done; return; } @@ -197,8 +217,12 @@ static void _board_maker_export(void) ref_submesh->indice_count ); } - af_write( &compiler.af, "/tmp/hello.mdl", MDL_VERSION_NR ); + af_write( &compiler.af, _board_maker.export_path, MDL_VERSION_NR ); mdl_compiler_free( &compiler ); + + _board_maker.export_success = 1; + _board_maker.export_message = "Export done!"; + _board_maker.ui_state = k_board_maker_ui_state_export_signal_done; } /* update loop */ @@ -470,6 +494,45 @@ struct ui_enum_opt _board_maker_wrap_opts[] = { 1, "Repeat" } }; +static void _board_maker_exit_modal_close( u32 args ) +{ + if( args & UI_MODAL_CANCEL ) {} + else + { + if( world_clear_event( k_world_event_board_maker ) ) + _board_maker_close(); + } +} + +static void _board_maker_confirm_overwrite( u32 args ) +{ + if( args & UI_MODAL_CANCEL ) {} + else + { + _board_maker.state = k_board_maker_state_export; + } +} + +static void _board_maker_export_path_changed( ui_context *ctx, char *buf, u32 len, void *userdata ) +{ + if( strlen(buf) < 3 ) + _board_maker.can_export = 0; + else + _board_maker.can_export = 1; + + for( u32 i=0; ifont = &vgf_default_large; + ui_standard_widget( ctx, export_rect, title_row, 1 ); + ui_text( ctx, title_row, "Export board", 1, k_ui_align_middle_center, 0 ); + ctx->font = &vgf_default_small; + ui_info( ctx, export_rect, "This will export your board to disk." ); + ui_info( ctx, export_rect, "It will appear to use in skate shops!" ); + + /* export name */ + struct ui_textbox_callbacks callbacks = + { + .change = _board_maker_export_path_changed + }; + ui_textbox( ctx, export_rect, "File name:", + _board_maker.export_name, sizeof(_board_maker.export_name), 1, 0, &callbacks ); + + /* options buttons */ + ui_rect bottom_row; + ui_split( export_rect, k_ui_axis_h, -32, 8, export_rect, bottom_row ); + + ui_rect ok_box, cancel_box; + ui_split( bottom_row, k_ui_axis_v, -120, 8, bottom_row, ok_box ); + ui_split( bottom_row, k_ui_axis_v, -120, 8, bottom_row, cancel_box ); + + if( _board_maker.can_export ) + { + if( ui_button_text( ctx, ok_box, "Export", 1 ) == k_ui_button_click ) + { + strcpy( _board_maker.export_path, "boards/" ); + strcat( _board_maker.export_path, _board_maker.export_name ); + strcat( _board_maker.export_path, "/board.mdl" ); + + if( vg_path_exists( _board_maker.export_path ) ) + { + const struct ui_modal_callbacks callbacks = + { + .close = _board_maker_confirm_overwrite + }; + ui_start_modal( ctx, "Overwrite existing file?", "Overwrite", UI_MODAL_OK|UI_MODAL_CANCEL, &callbacks ); + } + else + { + _board_maker.state = k_board_maker_state_export; + } + } + } + else + { + // TODO: standardize me + ui_fill( ctx, ok_box, ui_colour( ctx, k_ui_bg ) ); + ui_text( ctx, ok_box, "Export", 1, k_ui_align_middle_center, ui_colour( ctx, k_ui_bg+3 ) ); + } + + if( ui_button_text( ctx, cancel_box, "Cancel", 1 ) == k_ui_button_click ) + { + _board_maker.ui_state = k_board_maker_ui_state_default; + } + + return; + } + ui_rect root = { 8, 8, 200, 600 }, panel; ui_panel( ctx, root, panel ); @@ -489,11 +631,6 @@ void _board_maker_ui( ui_context *ctx ) bool main_clickable = clickable; -#if 0 - if( _board_maker.ui_state != k_board_maker_ui_state_default ) - main_clickable = 0; -#endif - ui_info( ctx, panel, "Wheels" ); ui_rect w1, w2, w3, w4, wheel_row; ui_standard_widget( ctx, panel, wheel_row, 1 ); @@ -535,6 +672,13 @@ void _board_maker_ui( ui_context *ctx ) ui_fill( ctx, bib, colour ); } + ui_rect export_box; + ui_standard_widget( ctx, panel, export_box, 2 ); + if( ui_button_text( ctx, export_box, "Export", 1 ) == k_ui_button_click ) + { + _board_maker.ui_state = k_board_maker_ui_state_export; + } + ui_rect quit_box; ui_split( panel, k_ui_axis_h, -24, 0, panel, quit_box ); @@ -689,10 +833,11 @@ void _board_maker_ui( ui_context *ctx ) if( quit_me ) { - _board_maker.state = k_board_maker_state_export; - - //if( world_clear_event( k_world_event_board_maker ) ) - // _board_maker_close(); + const struct ui_modal_callbacks callbacks = + { + .close = _board_maker_exit_modal_close + }; + ui_start_modal( ctx, "Exit board maker?", "EXIT", UI_MODAL_OK|UI_MODAL_CANCEL, &callbacks ); } } diff --git a/src/board_maker.h b/src/board_maker.h index c8c0ef3..0494715 100644 --- a/src/board_maker.h +++ b/src/board_maker.h @@ -81,12 +81,19 @@ struct _board_maker k_board_maker_ui_state_default, k_board_maker_ui_state_pick_colour, k_board_maker_ui_state_edit_decal, - k_board_maker_ui_state_pick_image + k_board_maker_ui_state_pick_image, + k_board_maker_ui_state_export, + k_board_maker_ui_state_export_signal_done, } ui_state; enum board_maker_ui_state ui_image_picker_return_state; struct vg_filebrowser *browser; + char export_name[100]; + char export_path[128]; + bool can_export; + bool export_success; + const char *export_message; } extern _board_maker; diff --git a/src/ent_skateshop.c b/src/ent_skateshop.c index 74308ce..d82c621 100644 --- a/src/ent_skateshop.c +++ b/src/ent_skateshop.c @@ -606,7 +606,8 @@ fade_out:; vg_msg msg; vg_msg_init( &msg, reg->metadata, reg->metadata_len ); - if( vg_msg_seekframe( &msg, "workshop" ) ){ + if( vg_msg_seekframe( &msg, "workshop" ) ) + { const char *title = vg_msg_getkvstr( &msg, "title" ); if( title ) _skateshop.render.item_title = title; diff --git a/src/workshop.c b/src/workshop.c index 6c3e7eb..16b6d7f 100644 --- a/src/workshop.c +++ b/src/workshop.c @@ -57,12 +57,9 @@ static void workshop_reset_submission_data(void) workshop_form.submission.description[0] = '\0'; workshop_form.submission.title[0] = '\0'; workshop_form.submission.author[0] = '\0'; - workshop_form.submission.submission_type_selection = - k_addon_type_none; + workshop_form.submission.submission_type_selection = k_addon_type_none; workshop_form.submission.type = k_addon_type_none; - - workshop_form.submission.visibility = - k_ERemoteStoragePublishedFileVisibilityPublic; + workshop_form.submission.visibility = k_ERemoteStoragePublishedFileVisibilityPublic; workshop_form.addon_folder[0] = '\0'; player_board_unload( &workshop_form.board_model ); @@ -413,8 +410,7 @@ static void workshop_op_submit( ui_context *ctx ) { if( !workshop_form.submission.title[0] ) { - ui_start_modal( ctx, "Cannot submit because a title is required\n", - UI_MODAL_WARN ); + ui_start_modal( ctx, "Cannot submit because a title is required\n", NULL, UI_MODAL_WARN, NULL ); workshop_form.op = k_workshop_op_none; return; } @@ -424,9 +420,7 @@ static void workshop_op_submit( ui_context *ctx ) { if( !workshop_form.submission.description[0] ) { - ui_start_modal( ctx, - "Cannot submit because a description is required\n", - UI_MODAL_WARN ); + ui_start_modal( ctx, "Cannot submit because a description is required\n", NULL, UI_MODAL_WARN, NULL ); workshop_form.op = k_workshop_op_none; return; } @@ -436,8 +430,7 @@ static void workshop_op_submit( ui_context *ctx ) { if( workshop_form.file_intent == k_workshop_form_file_intent_none ) { - ui_start_modal( ctx, "Cannot submit because the file is " - "empty or unspecified\n", UI_MODAL_WARN ); + ui_start_modal( ctx, "Cannot submit because the file is empty or unspecified\n", NULL, UI_MODAL_WARN, NULL ); workshop_form.op = k_workshop_op_none; return; } @@ -570,7 +563,7 @@ static void workshop_op_load_model( ui_context *ctx ) else { ui_start_modal( ctx, "There is no ent_swspreview in the level. \n" - "Cannot publish here\n", UI_MODAL_BAD ); + "Cannot publish here\n", NULL, UI_MODAL_BAD, NULL ); workshop_form.op = k_workshop_op_none; return; } @@ -579,7 +572,7 @@ static void workshop_op_load_model( ui_context *ctx ) else { ui_start_modal( ctx, "Don't know how to prepare for this item type. \n" - "Please contact the developers.\n", UI_MODAL_BAD ); + "Please contact the developers.\n", NULL, UI_MODAL_BAD, NULL ); workshop_form.op = k_workshop_op_none; return; } @@ -615,7 +608,7 @@ static void workshop_form_async_imageload( void *data, u32 len ) snprintf( workshop_form.error_msg, sizeof(workshop_form.error_msg), "Preview image could not be loaded. Reason: %s\n", stbi_failure_reason() ); - ui_start_modal( &vg_ui.ctx, workshop_form.error_msg, UI_MODAL_BAD ); + ui_start_modal( &vg_ui.ctx, workshop_form.error_msg, NULL, UI_MODAL_BAD, NULL ); } workshop_form.op = k_workshop_op_none; } @@ -862,8 +855,7 @@ int workshop_submit_command( int argc, const char *argv[] ) { if( !steam_ready ) { - ui_start_modal( &vg_ui.ctx, - "Steam API is not initialized\n", UI_MODAL_BAD ); + ui_start_modal( &vg_ui.ctx, "Steam API is not initialized\n", NULL, UI_MODAL_BAD, NULL ); return 0; }