diff --git a/lang/Czech.ini b/lang/Czech.ini index 28e75468..be6904af 100644 --- a/lang/Czech.ini +++ b/lang/Czech.ini @@ -178,6 +178,9 @@ SAVE_TITLE = "UKLADACI SLOT" ERASE_TITLE = "SMAZAT" CONFIRM = "Opravdu chcete smazat tento slot?" ERASE = "Smazat" +EDIT = "Upravit" +EDIT_TITLE = "EDIT" +EDIT_NAME = "Upravit název souboru uložené hry @:" [HOST_SETTINGS] SETTINGS = "NASTAVENI" diff --git a/lang/Dutch.ini b/lang/Dutch.ini index 27386fea..5a1f4f26 100644 --- a/lang/Dutch.ini +++ b/lang/Dutch.ini @@ -178,6 +178,9 @@ SAVE_TITLE = "OPSLAAN" ERASE_TITLE = "VERWIJDEREN" CONFIRM = "Weet je zeker dat je dit opslag slot wilt verwijderen" ERASE = "Verwijderen" +EDIT = "Bewerken" +EDIT_TITLE = "BEWERKEN" +EDIT_NAME = "Bewerk de naam van het opgeslagen bestand @:" [HOST_SETTINGS] SETTINGS = "INSTELLINGEN" diff --git a/lang/English.ini b/lang/English.ini index e8c21400..b9687b75 100644 --- a/lang/English.ini +++ b/lang/English.ini @@ -178,6 +178,9 @@ SAVE_TITLE = "SAVE" ERASE_TITLE = "ERASE" CONFIRM = "Are you sure you want to erase this save slot?" ERASE = "Erase" +EDIT = "Edit" +EDIT_TITLE = "EDIT" +EDIT_NAME = "Edit Save File @'s Name:" [HOST_SETTINGS] SETTINGS = "SETTINGS" diff --git a/lang/French.ini b/lang/French.ini index ae8a6590..4af0f5fd 100644 --- a/lang/French.ini +++ b/lang/French.ini @@ -178,6 +178,9 @@ SAVE_TITLE = "SAUVEGARDE" ERASE_TITLE = "EFFACER" CONFIRM = "Êtes-vous sûr de vouloir supprimer cette sauvegarde ?" ERASE = "Effacer" +EDIT = "Modifier" +EDIT_TITLE = "MODIFIER" +EDIT_NAME = "Modifier le nom du fichier de sauvegarde @ :" [HOST_SETTINGS] SETTINGS = "PARAMÈTRES" diff --git a/lang/German.ini b/lang/German.ini index a2b962af..b5bd0e2b 100644 --- a/lang/German.ini +++ b/lang/German.ini @@ -178,6 +178,9 @@ SAVE_TITLE = "SPEICHERN" ERASE_TITLE = "LÖSCHEN" CONFIRM = "Möchtest du diesen Speicherplatz wirklich löschen?" ERASE = "Löschen" +EDIT = "Bearbeiten" +EDIT_TITLE = "BEARBEITEN" +EDIT_NAME = "Bearbeiten Sie den Namen der gespeicherten Datei @:" [HOST_SETTINGS] SETTINGS = "EINSTELLUNGEN" diff --git a/lang/Italian.ini b/lang/Italian.ini index df36c6bf..ac1df3ae 100644 --- a/lang/Italian.ini +++ b/lang/Italian.ini @@ -176,6 +176,9 @@ SAVE_TITLE = "SALVATAGGIO" ERASE_TITLE = "CANCELLA" CONFIRM = "Sei sicuro di voler cancellare questo slot di salvataggio?" ERASE = "cancella" +EDIT = "Modifica" +EDIT_TITLE = "MODIFICA" +EDIT_NAME = "Modifica il nome del file di salvataggio @:" [HOST_SETTINGS] SETTINGS = "OPZIONI" diff --git a/lang/Polish.ini b/lang/Polish.ini index 3ae7f035..9c496e76 100644 --- a/lang/Polish.ini +++ b/lang/Polish.ini @@ -178,6 +178,9 @@ SAVE_TITLE = "ZAPISY" ERASE_TITLE = "USUN" CONFIRM = "Czy na pewno chcesz skasowac ten zapis?" ERASE = "skasuj" +EDIT = "Edytuj" +EDIT_TITLE = "EDYTUJ" +EDIT_NAME = "Edytuj nazwę pliku zapisu @:" [HOST_SETTINGS] SETTINGS = "USTAWIENIA" diff --git a/lang/Portuguese.ini b/lang/Portuguese.ini index c56443df..5c9658d8 100644 --- a/lang/Portuguese.ini +++ b/lang/Portuguese.ini @@ -176,6 +176,9 @@ WARNING = "\\#ffffa0\\Aviso:\\#dcdcdc\\ Você tem 10 ou mais mods ativados, desa [HOST_SAVE] SAVE_TITLE = "SALVAR" ERASE_TITLE = "APAGAR" +EDIT = "Editar" +EDIT_TITLE = "EDITAR" +EDIT_NAME = "Editar nome do arquivo salvo @:" CONFIRM = "Quer mesmo apagar o progresso?" ERASE = "Apagar" diff --git a/lang/Russian.ini b/lang/Russian.ini index 12fb0b6c..ecc0d521 100644 --- a/lang/Russian.ini +++ b/lang/Russian.ini @@ -177,6 +177,9 @@ SAVE_TITLE = "SAVE" ERASE_TITLE = "ERASE" CONFIRM = "Вы уверены, что хотите удалить этот слот сохранения?" ERASE = "Удалить" +EDIT = "Редактировать" +EDIT_TITLE = "РЕДАКТИРОВАТЬ" +EDIT_NAME = "Редактировать имя файла сохранения @:" [HOST_SETTINGS] SETTINGS = "SETTINGS" diff --git a/lang/Spanish.ini b/lang/Spanish.ini index 4699add0..bf6b4f2e 100644 --- a/lang/Spanish.ini +++ b/lang/Spanish.ini @@ -178,6 +178,9 @@ SAVE_TITLE = "RANURAS DE\nGUARDADO" ERASE_TITLE = "BORRAR" CONFIRM = "¿Seguro que quieres borrar esta partida?" ERASE = "Borrar" +EDIT = "Editar" +EDIT_TITLE = "EDITAR" +EDIT_NAME = "Editar nombre del archivo guardado @:" [HOST_SETTINGS] SETTINGS = "AJUSTES" diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 42707116..1a2fdbe0 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -19,6 +19,7 @@ #include "network/moderator_list.h" #include "debuglog.h" #include "djui/djui_hud_utils.h" +#include "game/save_file.h" #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) @@ -56,6 +57,14 @@ struct FunctionConfigOption { *Config options and default values */ +static_assert(NUM_SAVE_FILES == 4); // update this if more save slots are added +char configSaveNames[4][MAX_SAVE_NAME_STRING] = { + "Super Mario 64", + "Super Mario 64", + "Super Mario 64", + "Super Mario 64" +}; + // Video/audio stuff ConfigWindow configWindow = { .x = WAPI_WIN_CENTERPOS, @@ -418,11 +427,36 @@ static void dynos_pack_write(FILE* file) { } } +static void save_name_read(char** tokens, int numTokens) { + if (numTokens < 2) { return; } + char fullSaveName[MAX_SAVE_NAME_STRING] = { 0 }; + int index = 0; + for (int i = 1; i < numTokens; i++) { + if (i == 1) { + index = atoi(tokens[i]); + } else { + if (i > 2) { + strncat(fullSaveName, " ", MAX_SAVE_NAME_STRING - 1); + } + strncat(fullSaveName, tokens[i], MAX_SAVE_NAME_STRING - 1); + } + + } + strncpy(configSaveNames[index], fullSaveName, MAX_SAVE_NAME_STRING); +} + +static void save_name_write(FILE* file) { + for (int i = 0; i < NUM_SAVE_FILES; i++) { + fprintf(file, "%s %d %s\n", "save-name:", i, configSaveNames[i]); + } +} + static const struct FunctionConfigOption functionOptions[] = { { .name = "enable-mod:", .read = enable_mod_read, .write = enable_mod_write }, { .name = "ban:", .read = ban_read, .write = ban_write }, { .name = "moderator:", .read = moderator_read, .write = moderator_write }, { .name = "dynos-pack:", .read = dynos_pack_read, .write = dynos_pack_write }, + { .name = "save-name:", .read = save_name_read, .write = save_name_write } }; // Reads an entire line from a file (excluding the newline character) and returns an allocated string diff --git a/src/pc/configfile.h b/src/pc/configfile.h index 850b7200..17050e5e 100644 --- a/src/pc/configfile.h +++ b/src/pc/configfile.h @@ -12,6 +12,7 @@ #define MAX_VOLUME 127 #define MAX_CONFIG_STRING 64 #define MAX_PLAYER_STRING 60 +#define MAX_SAVE_NAME_STRING 32 #define DEFAULT_PORT 7777 #define DEFAULT_COOPNET_IP "net.coop64.us" @@ -27,6 +28,8 @@ typedef struct { unsigned int msaa; } ConfigWindow; +extern char configSaveNames[4][MAX_SAVE_NAME_STRING]; + extern ConfigWindow configWindow; extern unsigned int configFiltering; extern unsigned int configMasterVolume; diff --git a/src/pc/djui/djui_panel_host.c b/src/pc/djui/djui_panel_host.c index 9a006b81..e66ef83c 100644 --- a/src/pc/djui/djui_panel_host.c +++ b/src/pc/djui/djui_panel_host.c @@ -173,8 +173,8 @@ void djui_panel_host_create(struct DjuiBase* caller) { djui_base_set_alignment(&text1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP); djui_text_set_drop_shadow(text1, 64, 64, 64, 100); - char starString[32] = { 0 }; - snprintf(starString, 32, "%c x%d", '~' + 1, save_file_get_total_star_count(configHostSaveSlot - 1, 0, 24)); + char starString[64] = { 0 }; + snprintf(starString, 64, "%c x%d - %s", '~' + 1, save_file_get_total_star_count(configHostSaveSlot - 1, 0, 24), configSaveNames[configHostSaveSlot]); struct DjuiButton* button1 = djui_button_create(&rect2->base, starString, DJUI_BUTTON_STYLE_NORMAL, djui_panel_host_save_create); djui_base_set_size(&button1->base, 0.45f, 32); djui_base_set_alignment(&button1->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); diff --git a/src/pc/djui/djui_panel_host_save.c b/src/pc/djui/djui_panel_host_save.c index a2338e81..045051a7 100644 --- a/src/pc/djui/djui_panel_host_save.c +++ b/src/pc/djui/djui_panel_host_save.c @@ -6,13 +6,61 @@ #include "game/save_file.h" #include "pc/configfile.h" +static struct DjuiInputbox* sSaveNameInputBox = NULL; static struct DjuiBase* sSaveButtonCaller = NULL; -static struct DjuiButton* sSaveButtons[4] = { NULL }; -static s32 sEraseButtonTag = 0; +static struct DjuiButton* sSaveButtons[NUM_SAVE_FILES] = { NULL }; +static s32 sButtonTag = 0; + +static char* sSaveLetters[] = { "A", "B", "C", "D" }; + +static void djui_panel_host_save_update_button(struct DjuiButton* button, int slot); + +static void djui_panel_host_save_save_name_change(UNUSED struct DjuiBase* caller) { + strncpy(configSaveNames[sButtonTag], sSaveNameInputBox->buffer, MAX_SAVE_NAME_STRING); + if (strlen(sSaveNameInputBox->buffer) >= 64) { + djui_inputbox_set_text(sSaveNameInputBox, configSaveNames[sButtonTag]); + } +} + +static void djui_panel_edit_back(struct DjuiBase* caller) { + djui_panel_host_save_update_button(sSaveButtons[sButtonTag], sButtonTag); + djui_panel_menu_back(caller); +} + +static void djui_panel_edit_create(struct DjuiBase* caller) { + struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(HOST_SAVE, EDIT_TITLE)); + struct DjuiBase* body = djui_three_panel_get_body(panel); + { + struct DjuiRect* rect1 = djui_rect_container_create(body, 32); + { + char buffer[64] = { 0 }; + djui_language_replace(DLANG(HOST_SAVE, EDIT_NAME), buffer, 64, '@', sSaveLetters[sButtonTag]); + struct DjuiText* text = djui_text_create(&rect1->base, buffer); + djui_base_set_size_type(&text->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_color(&text->base, 220, 220, 220, 255); + djui_base_set_size(&text->base, 0.585f, 64); + djui_base_set_alignment(&text->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP); + djui_text_set_drop_shadow(text, 64, 64, 64, 100); + + sSaveNameInputBox = djui_inputbox_create(&rect1->base, MAX_SAVE_NAME_STRING); + djui_base_set_size_type(&sSaveNameInputBox->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); + djui_base_set_size(&sSaveNameInputBox->base, 0.45f, 32); + djui_base_set_alignment(&sSaveNameInputBox->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); + char saveName[MAX_SAVE_NAME_STRING] = { 0 }; + strncpy(saveName, configSaveNames[sButtonTag], MAX_SAVE_NAME_STRING); + djui_inputbox_set_text(sSaveNameInputBox, saveName); + djui_interactable_hook_value_change(&sSaveNameInputBox->base, djui_panel_host_save_save_name_change); + } + + djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_edit_back); + } + + djui_panel_add(caller, panel, NULL); +} static void djui_panel_host_save_update_button(struct DjuiButton* button, int slot) { - char starString[32] = { 0 }; - snprintf(starString, 32, "%c x%d", '~' + 1, save_file_get_total_star_count(slot, 0, 24)); + char starString[64] = { 0 }; + snprintf(starString, 64, "%c x%d - %s", '~' + 1, save_file_get_total_star_count(slot, 0, 24), configSaveNames[slot]); djui_text_set_text(button->text, starString); } @@ -23,38 +71,50 @@ static void djui_panel_host_save_button_click(struct DjuiBase* caller) { } static void djui_panel_host_save_erase_yes(struct DjuiBase* caller) { - save_file_erase(sEraseButtonTag); - djui_panel_host_save_update_button(sSaveButtons[sEraseButtonTag], sEraseButtonTag); + save_file_erase(sButtonTag); + djui_panel_host_save_update_button(sSaveButtons[sButtonTag], sButtonTag); djui_panel_menu_back(caller); } static void djui_panel_host_save_erase(struct DjuiBase* caller) { - sEraseButtonTag = caller->tag; + sButtonTag = caller->tag; djui_panel_confirm_create(caller, DLANG(HOST_SAVE, ERASE_TITLE), DLANG(HOST_SAVE, CONFIRM), djui_panel_host_save_erase_yes); } +static void djui_panel_host_save_edit(struct DjuiBase* caller) { + sButtonTag = caller->tag; + djui_panel_edit_create(caller); +} + void djui_panel_host_save_create(struct DjuiBase* caller) { sSaveButtonCaller = caller; struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(HOST_SAVE, SAVE_TITLE)); struct DjuiBase* body = djui_three_panel_get_body(panel); { - for (int i = 0; i < 4; i++) { + for (int i = 0; i < NUM_SAVE_FILES; i++) { struct DjuiRect* rect1 = djui_rect_container_create(body, 32); { struct DjuiButton* button1 = djui_button_create(&rect1->base, "", DJUI_BUTTON_STYLE_NORMAL, djui_panel_host_save_button_click); djui_panel_host_save_update_button(button1, i); - djui_base_set_size(&button1->base, 0.74f, 32); + djui_base_set_size(&button1->base, 0.6f, 32); button1->base.tag = i; sSaveButtons[i] = button1; struct DjuiButton* button2 = djui_button_create(&rect1->base, DLANG(HOST_SAVE, ERASE), DJUI_BUTTON_STYLE_NORMAL, djui_panel_host_save_erase); button2->base.tag = i; - djui_base_set_size(&button2->base, 0.24f, 32); - djui_base_set_alignment(&button2->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); + djui_base_set_size(&button2->base, 0.19f, 32); + djui_base_set_alignment(&button2->base, DJUI_HALIGN_CENTER, DJUI_VALIGN_TOP); + djui_base_set_location(&button2->base, 127, 0); + djui_base_set_enabled(&button2->base, gDjuiInMainMenu); + + struct DjuiButton* button3 = djui_button_create(&rect1->base, DLANG(HOST_SAVE, EDIT), DJUI_BUTTON_STYLE_NORMAL, djui_panel_host_save_edit); + button3->base.tag = i; + djui_base_set_size(&button3->base, 0.19f, 32); + djui_base_set_alignment(&button3->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); } } } diff --git a/tools/append_lang_keys.py b/tools/append_lang_keys.py index 51f2b679..d55327c1 100644 --- a/tools/append_lang_keys.py +++ b/tools/append_lang_keys.py @@ -10,16 +10,20 @@ def add_new_key(ini_path, section, search_key, new_key): with open(ini_path, "r", encoding="utf-8") as f: lines = f.readlines() + added = False for line in lines: if line.startswith("["): current_section = line.replace("[", "").replace("]", "").replace("\n", "") - elif line.startswith(search_key) and current_section == section: + elif line.startswith(search_key) and current_section == section and not added: + added = True line += f'{new_key} = "{new_value}"\n' out.append(line) with open(ini_path, "w", encoding="utf-8") as f: f.writelines(out) -for file in os.listdir("./lang/"): +files = os.listdir("./lang/") +files.sort() +for file in files: if file.endswith(".ini"): add_new_key("./lang/" + file, sys.argv[1], sys.argv[2], sys.argv[3]) \ No newline at end of file