mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	Compare commits
	
		
			5 commits
		
	
	
		
			01fa72a304
			...
			d3cc77fe72
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d3cc77fe72 | ||
|   | fcef8699f2 | ||
|   | c4c7f6c1b9 | ||
|   | f87c1c8b74 | ||
|   | d7afad9389 | 
					 12 changed files with 311 additions and 141 deletions
				
			
		|  | @ -131,7 +131,7 @@ override_disallowed_functions = { | |||
|     "src/pc/lua/utils/smlua_audio_utils.h":     [ "smlua_audio_utils_override", "audio_custom_shutdown", "smlua_audio_custom_deinit", "audio_sample_destroy_pending_copies", "audio_custom_update_volume" ], | ||||
|     "src/pc/djui/djui_hud_utils.h":             [ "djui_hud_render_texture_raw", "djui_hud_render_texture_tile_raw" ], | ||||
|     "src/pc/lua/utils/smlua_level_utils.h":     [ "smlua_level_util_reset" ], | ||||
|     "src/pc/lua/utils/smlua_text_utils.h":      [ "smlua_text_utils_init", "smlua_text_utils_shutdown", "get_dialog_text_ascii", "smlua_text_utils_dialog_get_unmodified"], | ||||
|     "src/pc/lua/utils/smlua_text_utils.h":      [ "smlua_text_utils_init", "smlua_text_utils_shutdown", "smlua_text_utils_dialog_get_unmodified"], | ||||
|     "src/pc/lua/utils/smlua_anim_utils.h":      [ "smlua_anim_util_reset", "smlua_anim_util_register_animation" ], | ||||
|     "src/pc/lua/utils/smlua_gfx_utils.h":       [ "gfx_allocate_internal", "vtx_allocate_internal", "gfx_get_length_no_sentinel" ], | ||||
|     "src/pc/network/lag_compensation.h":        [ "lag_compensation_clear" ], | ||||
|  |  | |||
|  | @ -471,9 +471,10 @@ f32 get_generic_dialog_width(u8* dialog) { | |||
| } | ||||
| 
 | ||||
| f32 get_generic_ascii_string_width(const char* ascii) { | ||||
|     u8 dialog[256] = { DIALOG_CHAR_TERMINATOR }; | ||||
|     convert_string_ascii_to_sm64(dialog, ascii, false); | ||||
|     return get_generic_dialog_width(dialog); | ||||
|     u8 *str = convert_string_ascii_to_sm64(NULL, ascii, false); | ||||
|     f32 width = get_generic_dialog_width(str); | ||||
|     free(str); | ||||
|     return width; | ||||
| } | ||||
| 
 | ||||
| f32 get_generic_dialog_height(u8* dialog) { | ||||
|  | @ -487,15 +488,16 @@ f32 get_generic_dialog_height(u8* dialog) { | |||
| } | ||||
| 
 | ||||
| f32 get_generic_ascii_string_height(const char* ascii) { | ||||
|     u8 dialog[256] = { DIALOG_CHAR_TERMINATOR }; | ||||
|     convert_string_ascii_to_sm64(dialog, ascii, false); | ||||
|     return get_generic_dialog_height(dialog); | ||||
|     u8 *str = convert_string_ascii_to_sm64(NULL, ascii, false); | ||||
|     f32 height = get_generic_dialog_height(str); | ||||
|     free(str); | ||||
|     return height; | ||||
| } | ||||
| 
 | ||||
| void print_generic_ascii_string(s16 x, s16 y, const char* ascii) { | ||||
|     u8 dialog[256] = { DIALOG_CHAR_TERMINATOR }; | ||||
|     convert_string_ascii_to_sm64(dialog, ascii, false); | ||||
|     print_generic_string(x, y, dialog); | ||||
|     u8 *str = convert_string_ascii_to_sm64(NULL, ascii, false); | ||||
|     print_generic_string(x, y, str); | ||||
|     free(str); | ||||
| } | ||||
| 
 | ||||
| #if defined(VERSION_JP) || defined(VERSION_SH) | ||||
|  | @ -1077,9 +1079,8 @@ void handle_special_dialog_text(s32 dialogID) { // dialog ID tables, in order | |||
|     } | ||||
| } | ||||
| 
 | ||||
| static u8 sHookString[255]; | ||||
| static bool sOverrideDialogString = false; | ||||
| void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii, bool menu); | ||||
| static u8 *sOverrideDialogHookString = NULL; | ||||
| 
 | ||||
| bool handle_dialog_hook(s32 dialogId) { | ||||
|     bool openDialogBox = true; | ||||
|     const char *dialogTextOverride = NULL; | ||||
|  | @ -1088,8 +1089,13 @@ bool handle_dialog_hook(s32 dialogId) { | |||
|         if (gCamera->cutscene == CUTSCENE_READ_MESSAGE) { gCamera->cutscene = 0; } | ||||
|         return false; | ||||
|     } | ||||
|     sOverrideDialogString = dialogTextOverride != NULL; | ||||
|     if (sOverrideDialogString) { convert_string_ascii_to_sm64(sHookString, dialogTextOverride, false); } | ||||
| 
 | ||||
|     free(sOverrideDialogHookString); | ||||
|     if (dialogTextOverride != NULL) { | ||||
|         sOverrideDialogHookString = convert_string_ascii_to_sm64(NULL, dialogTextOverride, false); | ||||
|     } else { | ||||
|         sOverrideDialogHookString = NULL; | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
|  | @ -1443,7 +1449,7 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l | |||
| 
 | ||||
|     u8 strChar; | ||||
| 
 | ||||
|     u8 *str = sOverrideDialogString ? sHookString : segmented_to_virtual(dialog->str); | ||||
|     u8 *str = sOverrideDialogHookString != NULL ? sOverrideDialogHookString : segmented_to_virtual(dialog->str); | ||||
|     s8 lineNum = 1; | ||||
| 
 | ||||
|     s8 totalLines; | ||||
|  | @ -2179,7 +2185,7 @@ void do_cutscene_handler(void) { | |||
| void print_peach_letter_message(void) { | ||||
|     struct DialogEntry *dialog = dialog_table_get(gDialogID); | ||||
| 
 | ||||
|     const u8* str = sOverrideDialogString ? sHookString : dialog->str; | ||||
|     const u8* str = sOverrideDialogHookString != NULL ? sOverrideDialogHookString : dialog->str; | ||||
| 
 | ||||
|     create_dl_translation_matrix(MENU_MTX_PUSH, 97.0f, 118.0f, 0); | ||||
| 
 | ||||
|  |  | |||
|  | @ -138,8 +138,6 @@ void create_dl_translation_matrix(s8 pushOp, f32 x, f32 y, f32 z); | |||
| void create_dl_rotation_matrix(s8 pushOp, f32 a, f32 x, f32 y, f32 z); | ||||
| void create_dl_ortho_matrix(void); | ||||
| void render_generic_char(u8 c); | ||||
| u8 str_ascii_char_to_dialog(char c); | ||||
| void str_ascii_to_dialog(const char* string, u8* dialog, u16 length); | ||||
| f32 get_generic_dialog_width(u8* dialog); | ||||
| f32 get_generic_ascii_string_width(const char* ascii); | ||||
| f32 get_generic_dialog_height(u8* dialog); | ||||
|  |  | |||
|  | @ -17,107 +17,229 @@ extern s32 gInGameLanguage; | |||
| #include "eu_translation.h" | ||||
| #endif | ||||
| 
 | ||||
| const struct { const char *str; u8 c; u8 menu; } sSm64CharMap[] = { | ||||
| 
 | ||||
|     // Digits
 | ||||
|     { "0", 0x00, 1 }, { "1", 0x01, 1 }, { "2", 0x02, 1 }, { "3", 0x03, 1 }, { "4", 0x04, 1 }, | ||||
|     { "5", 0x05, 1 }, { "6", 0x06, 1 }, { "7", 0x07, 1 }, { "8", 0x08, 1 }, { "9", 0x09, 1 }, | ||||
| 
 | ||||
|     // Capital letters
 | ||||
|     { "A", 0x0A, 1 }, { "B", 0x0B, 1 }, { "C", 0x0C, 1 }, { "D", 0x0D, 1 }, { "E", 0x0E, 1 }, | ||||
|     { "F", 0x0F, 1 }, { "G", 0x10, 1 }, { "H", 0x11, 1 }, { "I", 0x12, 1 }, { "J", 0x13, 1 }, | ||||
|     { "K", 0x14, 1 }, { "L", 0x15, 1 }, { "M", 0x16, 1 }, { "N", 0x17, 1 }, { "O", 0x18, 1 }, | ||||
|     { "P", 0x19, 1 }, { "Q", 0x1A, 1 }, { "R", 0x1B, 1 }, { "S", 0x1C, 1 }, { "T", 0x1D, 1 }, | ||||
|     { "U", 0x1E, 1 }, { "V", 0x1F, 1 }, { "W", 0x20, 1 }, { "X", 0x21, 1 }, { "Y", 0x22, 1 }, | ||||
|     { "Z", 0x23, 1 }, | ||||
| 
 | ||||
|     // Letters
 | ||||
|     { "a", 0x24, 0 }, { "b", 0x25, 0 }, { "c", 0x26, 0 }, { "d", 0x27, 0 }, { "e", 0x28, 0 }, | ||||
|     { "f", 0x29, 0 }, { "g", 0x2A, 0 }, { "h", 0x2B, 0 }, { "i", 0x2C, 0 }, { "j", 0x2D, 0 }, | ||||
|     { "k", 0x2E, 0 }, { "l", 0x2F, 0 }, { "m", 0x30, 0 }, { "n", 0x31, 0 }, { "o", 0x32, 0 }, | ||||
|     { "p", 0x33, 0 }, { "q", 0x34, 0 }, { "r", 0x35, 0 }, { "s", 0x36, 0 }, { "t", 0x37, 0 }, | ||||
|     { "u", 0x38, 0 }, { "v", 0x39, 0 }, { "w", 0x3A, 0 }, { "x", 0x3B, 0 }, { "y", 0x3C, 0 }, | ||||
|     { "z", 0x3D, 0 }, | ||||
| 
 | ||||
|     // Punctuation
 | ||||
|     { ":",   0xE6, 0 }, // colon
 | ||||
|     { ")(",  0xE2, 0 }, // close-open parentheses
 | ||||
|     { "<<",  0xF5, 0 }, // double quote open
 | ||||
|     { ">>",  0xF6, 0 }, // double quote close
 | ||||
|     { "\'",  0x3E, 1 }, // apostrophe
 | ||||
|     { ".",   0x3F, 1 }, // period
 | ||||
|     { ",",   0x6F, 1 }, // comma
 | ||||
|     { " ",   0x9E, 1 }, // space
 | ||||
|     { "-",   0x9F, 1 }, // dash
 | ||||
|     { "(",   0xE1, 0 }, // open parentheses
 | ||||
|     { ")",   0xE3, 0 }, // close parentheses
 | ||||
|     { "&",   0xE5, 1 }, // ampersand
 | ||||
|     { "!",   0xF2, 1 }, // exclamation mark
 | ||||
|     { "%",   0xF3, 0 }, // percent
 | ||||
|     { "?",   0xF4, 1 }, // question mark
 | ||||
|     { "~",   0xF7, 0 }, // tilde
 | ||||
| 
 | ||||
|     // Symbols
 | ||||
|     { "/",   0xD0, 0 }, | ||||
|     { "the", 0xD1, 0 }, | ||||
|     { "you", 0xD2, 0 }, | ||||
|     { "[%]", 0xE0, 0 }, // The number of extra stars required to unlock a star door
 | ||||
|     { "[A]", 0x54, 0 }, // bold A
 | ||||
|     { "[B]", 0x55, 0 }, // bold B
 | ||||
|     { "[C]", 0x56, 0 }, // bold C
 | ||||
|     { "[Z]", 0x57, 0 }, // bold Z
 | ||||
|     { "[R]", 0x58, 0 }, // bold R
 | ||||
|     { "+",   0xE4, 0 }, // left-right arrow
 | ||||
|     { "^",   0x50, 0 }, // up arrow
 | ||||
|     { "|",   0x51, 0 }, // down arrow
 | ||||
|     { "<",   0x52, 0 }, // left arrow
 | ||||
|     { ">",   0x53, 0 }, // right arrow
 | ||||
|     { "$",   0xF9, 1 }, // coin
 | ||||
|     { "★",   0xFA, 1 }, // star filled
 | ||||
|     { "@",   0xFA, 1 }, // star filled (both ★ and @ match 0xFA)
 | ||||
|     { "*",   0xFB, 1 }, // multiply
 | ||||
|     { "•",   0xFC, 0 }, // interpunct (unused)
 | ||||
|     { "=",   0xFD, 0 }, // star empty
 | ||||
|     { "\n",  0xFE, 1 }, // New line
 | ||||
|     { NULL,  0xFF, 1 }, // Null terminator
 | ||||
| struct Sm64Char { | ||||
|     const char *str; | ||||
|     u32 len; | ||||
|     u8 c; | ||||
|     bool menu; | ||||
| }; | ||||
| 
 | ||||
| #define SM64_CHAR(_str, _c, _menu) { \ | ||||
|     .str = _str, \ | ||||
|     .len = sizeof(_str) - 1, \ | ||||
|     .c = _c, \ | ||||
|     .menu = _menu, \ | ||||
| } | ||||
| 
 | ||||
| static const struct Sm64Char sSm64CharMap[] = { | ||||
| 
 | ||||
|     // Digits
 | ||||
|     SM64_CHAR("0", 0x00, true), | ||||
|     SM64_CHAR("1", 0x01, true), | ||||
|     SM64_CHAR("2", 0x02, true), | ||||
|     SM64_CHAR("3", 0x03, true), | ||||
|     SM64_CHAR("4", 0x04, true), | ||||
|     SM64_CHAR("5", 0x05, true), | ||||
|     SM64_CHAR("6", 0x06, true), | ||||
|     SM64_CHAR("7", 0x07, true), | ||||
|     SM64_CHAR("8", 0x08, true), | ||||
|     SM64_CHAR("9", 0x09, true), | ||||
| 
 | ||||
|     // Capital letters
 | ||||
|     SM64_CHAR("A", 0x0A, true), | ||||
|     SM64_CHAR("B", 0x0B, true), | ||||
|     SM64_CHAR("C", 0x0C, true), | ||||
|     SM64_CHAR("D", 0x0D, true), | ||||
|     SM64_CHAR("E", 0x0E, true), | ||||
|     SM64_CHAR("F", 0x0F, true), | ||||
|     SM64_CHAR("G", 0x10, true), | ||||
|     SM64_CHAR("H", 0x11, true), | ||||
|     SM64_CHAR("I", 0x12, true), | ||||
|     SM64_CHAR("J", 0x13, true), | ||||
|     SM64_CHAR("K", 0x14, true), | ||||
|     SM64_CHAR("L", 0x15, true), | ||||
|     SM64_CHAR("M", 0x16, true), | ||||
|     SM64_CHAR("N", 0x17, true), | ||||
|     SM64_CHAR("O", 0x18, true), | ||||
|     SM64_CHAR("P", 0x19, true), | ||||
|     SM64_CHAR("Q", 0x1A, true), | ||||
|     SM64_CHAR("R", 0x1B, true), | ||||
|     SM64_CHAR("S", 0x1C, true), | ||||
|     SM64_CHAR("T", 0x1D, true), | ||||
|     SM64_CHAR("U", 0x1E, true), | ||||
|     SM64_CHAR("V", 0x1F, true), | ||||
|     SM64_CHAR("W", 0x20, true), | ||||
|     SM64_CHAR("X", 0x21, true), | ||||
|     SM64_CHAR("Y", 0x22, true), | ||||
|     SM64_CHAR("Z", 0x23, true), | ||||
| 
 | ||||
|     // Letters
 | ||||
|     SM64_CHAR("a", 0x24, false), | ||||
|     SM64_CHAR("b", 0x25, false), | ||||
|     SM64_CHAR("c", 0x26, false), | ||||
|     SM64_CHAR("d", 0x27, false), | ||||
|     SM64_CHAR("e", 0x28, false), | ||||
|     SM64_CHAR("f", 0x29, false), | ||||
|     SM64_CHAR("g", 0x2A, false), | ||||
|     SM64_CHAR("h", 0x2B, false), | ||||
|     SM64_CHAR("i", 0x2C, false), | ||||
|     SM64_CHAR("j", 0x2D, false), | ||||
|     SM64_CHAR("k", 0x2E, false), | ||||
|     SM64_CHAR("l", 0x2F, false), | ||||
|     SM64_CHAR("m", 0x30, false), | ||||
|     SM64_CHAR("n", 0x31, false), | ||||
|     SM64_CHAR("o", 0x32, false), | ||||
|     SM64_CHAR("p", 0x33, false), | ||||
|     SM64_CHAR("q", 0x34, false), | ||||
|     SM64_CHAR("r", 0x35, false), | ||||
|     SM64_CHAR("s", 0x36, false), | ||||
|     SM64_CHAR("t", 0x37, false), | ||||
|     SM64_CHAR("u", 0x38, false), | ||||
|     SM64_CHAR("v", 0x39, false), | ||||
|     SM64_CHAR("w", 0x3A, false), | ||||
|     SM64_CHAR("x", 0x3B, false), | ||||
|     SM64_CHAR("y", 0x3C, false), | ||||
|     SM64_CHAR("z", 0x3D, false), | ||||
| 
 | ||||
|     // Punctuation
 | ||||
|     SM64_CHAR(":",   0xE6, false), // colon
 | ||||
|     SM64_CHAR(")(",  0xE2, false), // close-open parentheses
 | ||||
|     SM64_CHAR("<<",  0xF5, false), // double quote open
 | ||||
|     SM64_CHAR(">>",  0xF6, false), // double quote close
 | ||||
|     SM64_CHAR("\'",  0x3E, true ), // apostrophe
 | ||||
|     SM64_CHAR(".",   0x3F, true ), // period
 | ||||
|     SM64_CHAR(",",   0x6F, true ), // comma
 | ||||
|     SM64_CHAR(" ",   0x9E, true ), // space
 | ||||
|     SM64_CHAR("-",   0x9F, true ), // dash
 | ||||
|     SM64_CHAR("(",   0xE1, false), // open parentheses
 | ||||
|     SM64_CHAR(")",   0xE3, false), // close parentheses
 | ||||
|     SM64_CHAR("&",   0xE5, true ), // ampersand
 | ||||
|     SM64_CHAR("!",   0xF2, true ), // exclamation mark
 | ||||
|     SM64_CHAR("%",   0xF3, false), // percent
 | ||||
|     SM64_CHAR("?",   0xF4, true ), // question mark
 | ||||
|     SM64_CHAR("~",   0xF7, false), // tilde
 | ||||
| 
 | ||||
|     // Symbols
 | ||||
|     SM64_CHAR("/",   0xD0, false), | ||||
|     SM64_CHAR("the", 0xD1, false), | ||||
|     SM64_CHAR("you", 0xD2, false), | ||||
|     SM64_CHAR("[%]", 0xE0, false), // The number of extra stars required to unlock a star door
 | ||||
|     SM64_CHAR("[A]", 0x54, false), // bold A
 | ||||
|     SM64_CHAR("[B]", 0x55, false), // bold B
 | ||||
|     SM64_CHAR("[C]", 0x56, false), // bold C
 | ||||
|     SM64_CHAR("[Z]", 0x57, false), // bold Z
 | ||||
|     SM64_CHAR("[R]", 0x58, false), // bold R
 | ||||
|     SM64_CHAR("+",   0xE4, false), // left-right arrow
 | ||||
|     SM64_CHAR("^",   0x50, false), // up arrow
 | ||||
|     SM64_CHAR("|",   0x51, false), // down arrow
 | ||||
|     SM64_CHAR("<",   0x52, false), // left arrow
 | ||||
|     SM64_CHAR(">",   0x53, false), // right arrow
 | ||||
|     SM64_CHAR("$",   0xF9, true ), // coin
 | ||||
|     SM64_CHAR("★",   0xFA, true ), // star filled
 | ||||
|     SM64_CHAR("@",   0xFA, true ), // star filled (both ★ and @ match 0xFA)
 | ||||
|     SM64_CHAR("*",   0xFB, true ), // multiply
 | ||||
|     SM64_CHAR("•",   0xFC, false), // interpunct (unused)
 | ||||
|     SM64_CHAR("=",   0xFD, false), // star empty
 | ||||
|     SM64_CHAR("\n",  0xFE, true ), // New line
 | ||||
| //  SM64_CHAR(NULL,  0xFF, true ), // Null terminator
 | ||||
| }; | ||||
| 
 | ||||
| #define ASCII_TO_SM64_MAX_CHAR_SIZE     1 | ||||
| #define SM64_TO_ASCII_MAX_CHAR_SIZE     4 | ||||
| 
 | ||||
| static const char *ascii_to_sm64_char(u8 *str64, const char *strAscii, bool menu) { | ||||
|     for (s32 i = 0; sSm64CharMap[i].str != NULL; ++i) { | ||||
|         if (menu && !sSm64CharMap[i].menu) { continue; } | ||||
|         if (strstr(strAscii, sSm64CharMap[i].str) == strAscii) { | ||||
|             *str64 = sSm64CharMap[i].c; | ||||
|             return strAscii + strlen(sSm64CharMap[i].str); | ||||
|     for (u32 i = 0; i < ARRAY_COUNT(sSm64CharMap); ++i) { | ||||
|         const struct Sm64Char *ch = &sSm64CharMap[i]; | ||||
|         if (menu && !ch->menu) { | ||||
|             continue; | ||||
|         } | ||||
|         if (memcmp(strAscii, ch->str, ch->len) == 0) { | ||||
|             *str64 = ch->c; | ||||
|             return strAscii + ch->len; | ||||
|         } | ||||
|     } | ||||
|     *str64 = 0x9E; | ||||
|     return strAscii + 1; | ||||
| } | ||||
| 
 | ||||
| static char *sm64_to_ascii_char(char *strAscii, const u8 *str64) { | ||||
|     for (s32 i = 0; sSm64CharMap[i].str != NULL; ++i) { | ||||
|         if (sSm64CharMap[i].c == *str64) { | ||||
|             s32 l = strlen(sSm64CharMap[i].str); | ||||
|             memcpy(strAscii, sSm64CharMap[i].str, l); | ||||
|             return strAscii + l; | ||||
| static char *sm64_to_ascii_char(char *strAscii, u8 c) { | ||||
|     for (u32 i = 0; i < ARRAY_COUNT(sSm64CharMap); ++i) { | ||||
|         const struct Sm64Char *ch = &sSm64CharMap[i]; | ||||
|         if (ch->c == c) { | ||||
|             memcpy(strAscii, ch->str, ch->len); | ||||
|             return strAscii + ch->len; | ||||
|         } | ||||
|     } | ||||
|     *strAscii = ' '; | ||||
|     return strAscii + 1; | ||||
| } | ||||
| 
 | ||||
| void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii, bool menu) { | ||||
|     for (; *strAscii != 0; str64++) { | ||||
|         strAscii = ascii_to_sm64_char(str64, strAscii, menu); | ||||
| u8 *convert_string_ascii_to_sm64(u8 *str64, const char *strAscii, bool menu) { | ||||
|     if (!strAscii) { return str64; } | ||||
| 
 | ||||
|     // allocate string with maximum size
 | ||||
|     bool shouldResizeString = false; | ||||
|     if (!str64) { | ||||
|         str64 = malloc(ASCII_TO_SM64_MAX_CHAR_SIZE * strlen(strAscii) + 1); | ||||
|         if (!str64) { | ||||
|             return NULL; | ||||
|         } | ||||
|         shouldResizeString = true; | ||||
|     } | ||||
|     *str64 = 0xFF; | ||||
| 
 | ||||
|     // convert string
 | ||||
|     u8 *str64End = str64; | ||||
|     for (; *strAscii != 0; str64End++) { | ||||
|         strAscii = ascii_to_sm64_char(str64End, strAscii, menu); | ||||
|     } | ||||
|     *(str64End++) = 0xFF; | ||||
| 
 | ||||
|     // resize string if it was allocated by this function
 | ||||
|     if (shouldResizeString) { | ||||
|         u8 *resizedStr64 = realloc(str64, (size_t) (str64End - str64)); | ||||
|         if (resizedStr64) { | ||||
|             str64 = resizedStr64; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return str64; | ||||
| } | ||||
| 
 | ||||
| void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64) { | ||||
|     for (; *str64 != 0xFF; str64++) { | ||||
|         strAscii = sm64_to_ascii_char(strAscii, str64); | ||||
| static inline size_t strlen64(const u8 *str64) { | ||||
|     const u8 *str64Begin = str64; | ||||
|     for (; *str64 != 0xFF; str64++); | ||||
|     return (size_t) (str64 - str64Begin); | ||||
| } | ||||
| 
 | ||||
| char *convert_string_sm64_to_ascii(char *strAscii, const u8 *str64) { | ||||
|     if (!str64) { return strAscii; } | ||||
| 
 | ||||
|     // allocate string with maximum size
 | ||||
|     bool shouldResizeString = false; | ||||
|     if (!strAscii) { | ||||
|         strAscii = malloc(SM64_TO_ASCII_MAX_CHAR_SIZE * strlen64(str64) + 1); | ||||
|         if (!strAscii) { | ||||
|             return NULL; | ||||
|         } | ||||
|         shouldResizeString = true; | ||||
|     } | ||||
|     *strAscii = 0; | ||||
| 
 | ||||
|     // convert string
 | ||||
|     char *strAsciiEnd = strAscii; | ||||
|     for (; *str64 != 0xFF; str64++) { | ||||
|         strAsciiEnd = sm64_to_ascii_char(strAsciiEnd, *str64); | ||||
|     } | ||||
|     *(strAsciiEnd++) = 0; | ||||
| 
 | ||||
|     // resize string if it was allocated by this function
 | ||||
|     if (shouldResizeString) { | ||||
|         char *resizedStrAscii = realloc(strAscii, (size_t) (strAsciiEnd - strAscii)); | ||||
|         if (resizedStrAscii) { | ||||
|             strAscii = resizedStrAscii; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return strAscii; | ||||
| } | ||||
| 
 | ||||
| static void capitalize_string_ascii(char *strAscii) { | ||||
|  |  | |||
|  | @ -7,8 +7,8 @@ void **get_course_name_table(void); | |||
| void **get_course_name_table_original(void); | ||||
| void **get_act_name_table(void); | ||||
| void **get_act_name_table_original(void); | ||||
| void convert_string_ascii_to_sm64(u8 *str64, const char *strAscii, bool menu); | ||||
| void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64); | ||||
| u8 *convert_string_ascii_to_sm64(u8 *str64, const char *strAscii, bool menu); | ||||
| char *convert_string_sm64_to_ascii(char *strAscii, const u8 *str64); | ||||
| /* |description|
 | ||||
| Returns the name of the level corresponding to `courseNum`, `levelNum` and `areaIndex` as an ASCII (human readable) string. | ||||
| Set `charCase` to 1 to capitalize or -1 to decapitalize the returned string | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include "game/segment2.h" | ||||
| #include "pc/lua/utils/smlua_text_utils.h" | ||||
| #include "game/memory.h" | ||||
| #include "game/level_info.h" | ||||
| #include "pc/platform.h" | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
|  | @ -22,7 +23,7 @@ void dialog_table_init(void) { | |||
|         } | ||||
| 
 | ||||
|         memcpy(dialog, dialogOrig, sizeof(struct DialogEntry)); | ||||
|         dialog->text = get_dialog_text_ascii(dialog); | ||||
|         dialog->text = convert_string_sm64_to_ascii(NULL, dialog->str); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										70
									
								
								src/pc/djui/djui_panel_client_server_settings.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/pc/djui/djui_panel_client_server_settings.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| #include <stdio.h> | ||||
| #include "djui.h" | ||||
| #include "djui_panel.h" | ||||
| #include "djui_panel_menu.h" | ||||
| #include "game/save_file.h" | ||||
| #include "pc/network/network.h" | ||||
| #include "pc/utils/misc.h" | ||||
| #include "pc/configfile.h" | ||||
| #include "djui_inputbox.h" | ||||
| 
 | ||||
| void djui_panel_client_server_settings_create(struct DjuiBase* caller) { | ||||
|     struct DjuiThreePanel* panel = djui_panel_menu_create(DLANG(HOST_SETTINGS, SETTINGS), false); | ||||
|     struct DjuiBase* body = djui_three_panel_get_body(panel); | ||||
|     { | ||||
|         char* iChoices[3] = { DLANG(HOST_SETTINGS, NONSOLID), DLANG(HOST_SETTINGS, SOLID), DLANG(HOST_SETTINGS, FRIENDLY_FIRE) }; | ||||
|         struct DjuiSelectionbox* selectionbox1 = djui_selectionbox_create(body, DLANG(HOST_SETTINGS, PLAYER_INTERACTION), iChoices, 3, &gServerSettings.playerInteractions, NULL); | ||||
|         djui_base_set_enabled(&selectionbox1->base, false); | ||||
| 
 | ||||
|         unsigned int sKnockbackIndex = (gServerSettings.playerKnockbackStrength <= 20) | ||||
|                         ? 0 | ||||
|                         : ((gServerSettings.playerKnockbackStrength <= 40) ? 1 : 2); | ||||
|         char* kChoices[3] = { DLANG(HOST_SETTINGS, WEAK), DLANG(HOST_SETTINGS, NORMAL), DLANG(HOST_SETTINGS, TOO_MUCH) }; | ||||
|         struct DjuiSelectionbox* selectionbox2 = djui_selectionbox_create(body, DLANG(HOST_SETTINGS, KNOCKBACK_STRENGTH), kChoices, 3, &sKnockbackIndex, NULL); | ||||
|         djui_base_set_enabled(&selectionbox2->base, false); | ||||
| 
 | ||||
|         char* pChoices[2] = { DLANG(HOST_SETTINGS, CLASSIC_PVP), DLANG(HOST_SETTINGS, REVAMPED_PVP) }; | ||||
|         struct DjuiSelectionbox* selectionbox3 = djui_selectionbox_create(body, DLANG(HOST_SETTINGS, PVP_MODE), pChoices, 2, &gServerSettings.pvpType, NULL); | ||||
|         djui_base_set_enabled(&selectionbox3->base, false); | ||||
| 
 | ||||
|         unsigned int sStayInLevelAfterStar = gServerSettings.stayInLevelAfterStar; | ||||
|         char* lChoices[3] = { DLANG(HOST_SETTINGS, LEAVE_LEVEL), DLANG(HOST_SETTINGS, STAY_IN_LEVEL), DLANG(HOST_SETTINGS, NONSTOP) }; | ||||
|         struct DjuiSelectionbox* selectionbox4 = djui_selectionbox_create(body, DLANG(HOST_SETTINGS, ON_STAR_COLLECTION), lChoices, 3, &sStayInLevelAfterStar, NULL); | ||||
|         djui_base_set_enabled(&selectionbox4->base, false); | ||||
| 
 | ||||
|         char* bChoices[3] = { DLANG(HOST_SETTINGS, BOUNCY_BOUNDS_OFF), DLANG(HOST_SETTINGS, BOUNCY_BOUNDS_ON), DLANG(HOST_SETTINGS, BOUNCY_BOUNDS_ON_CAP) }; | ||||
|         struct DjuiSelectionbox* selectionbox5 = djui_selectionbox_create(body, DLANG(HOST_SETTINGS, BOUNCY_LEVEL_BOUNDS), bChoices, 3, &gServerSettings.bouncyLevelBounds, NULL); | ||||
|         djui_base_set_enabled(&selectionbox5->base, false); | ||||
| 
 | ||||
|         struct DjuiCheckbox* checkbox1 = djui_checkbox_create(body, DLANG(HOST_SETTINGS, SKIP_INTRO_CUTSCENE), (bool*)&gServerSettings.skipIntro, NULL); | ||||
|         djui_base_set_enabled(&checkbox1->base, false); | ||||
|         struct DjuiCheckbox* checkbox2 = djui_checkbox_create(body, DLANG(HOST_SETTINGS, PAUSE_ANYWHERE), (bool*)&gServerSettings.pauseAnywhere, NULL); | ||||
|         djui_base_set_enabled(&checkbox2->base, false); | ||||
|         struct DjuiCheckbox* checkbox3 = djui_checkbox_create(body, DLANG(HOST_SETTINGS, BUBBLE_ON_DEATH), (bool*)&gServerSettings.bubbleDeath, NULL); | ||||
|         djui_base_set_enabled(&checkbox3->base, false); | ||||
|         struct DjuiCheckbox* checkbox4 = djui_checkbox_create(body, DLANG(HOST_SETTINGS, NAMETAGS), (bool*)&gServerSettings.nametags, NULL); | ||||
|         djui_base_set_enabled(&checkbox4->base, false); | ||||
| 
 | ||||
|         struct DjuiRect* rect1 = djui_rect_container_create(body, 32); | ||||
|         { | ||||
|             struct DjuiText* text1 = djui_text_create(&rect1->base, DLANG(HOST_SETTINGS, AMOUNT_OF_PLAYERS)); | ||||
|             djui_base_set_size_type(&text1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); | ||||
|             djui_base_set_color(&text1->base, 220, 220, 220, 255); | ||||
|             djui_base_set_size(&text1->base, 0.585f, 64); | ||||
|             djui_base_set_alignment(&text1->base, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP); | ||||
|             djui_text_set_drop_shadow(text1, 64, 64, 64, 100); | ||||
| 
 | ||||
|             struct DjuiInputbox* inputbox1 = djui_inputbox_create(&rect1->base, 32); | ||||
|             djui_base_set_size_type(&inputbox1->base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE); | ||||
|             djui_base_set_size(&inputbox1->base, 0.45f, 32); | ||||
|             djui_base_set_alignment(&inputbox1->base, DJUI_HALIGN_RIGHT, DJUI_VALIGN_TOP); | ||||
|             char limitString[32] = { 0 }; | ||||
|             snprintf(limitString, 32, "%d", gServerSettings.maxPlayers); | ||||
|             djui_inputbox_set_text(inputbox1, limitString); | ||||
|             djui_base_set_enabled(&inputbox1->base, false); | ||||
|         } | ||||
| 
 | ||||
|         djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back); | ||||
|     } | ||||
|     djui_panel_add(caller, panel, NULL); | ||||
| } | ||||
							
								
								
									
										4
									
								
								src/pc/djui/djui_panel_client_server_settings.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/pc/djui/djui_panel_client_server_settings.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | |||
| #pragma once | ||||
| #include "djui.h" | ||||
| 
 | ||||
| void djui_panel_client_server_settings_create(struct DjuiBase* caller); | ||||
|  | @ -96,4 +96,4 @@ void djui_panel_host_settings_create(struct DjuiBase* caller) { | |||
|         djui_button_create(body, DLANG(MENU, BACK), DJUI_BUTTON_STYLE_BACK, djui_panel_menu_back); | ||||
|     } | ||||
|     djui_panel_add(caller, panel, NULL); | ||||
| } | ||||
| } | ||||
|  | @ -5,6 +5,7 @@ | |||
| #include "djui_panel_dynos.h" | ||||
| #include "djui_panel_options.h" | ||||
| #include "djui_panel_host.h" | ||||
| #include "djui_panel_client_server_settings.h" | ||||
| #include "djui_panel_menu.h" | ||||
| #include "djui_panel_confirm.h" | ||||
| #include "djui_panel_mod_menu.h" | ||||
|  | @ -70,6 +71,8 @@ void djui_panel_pause_create(struct DjuiBase* caller) { | |||
| 
 | ||||
|         if (gNetworkType == NT_SERVER) { | ||||
|             djui_button_create(body, DLANG(PAUSE, SERVER_SETTINGS), DJUI_BUTTON_STYLE_NORMAL, djui_panel_host_create); | ||||
|         } else { | ||||
|             djui_button_create(body, DLANG(PAUSE, SERVER_SETTINGS), DJUI_BUTTON_STYLE_NORMAL, djui_panel_client_server_settings_create); | ||||
|         } | ||||
| 
 | ||||
|         struct Mod* addedMods[MAX_HOOKED_MOD_MENU_ELEMENTS] = { 0 }; | ||||
|  |  | |||
|  | @ -19,36 +19,6 @@ extern s32 gInGameLanguage; | |||
| 
 | ||||
| #define INVALID_COURSE_NUM(courseNum) (smlua_level_util_get_info_from_course_num(courseNum) == NULL && !COURSE_IS_VALID_COURSE(courseNum)) | ||||
| 
 | ||||
| extern const struct { const char *str; u8 c; u8 menu; } sSm64CharMap[]; | ||||
| 
 | ||||
| static size_t measure_converted_sm64_string(const u8* str64) { | ||||
|     size_t len = 0; | ||||
|      | ||||
|     for (size_t i = 0; str64[i] != 0xFF; i++) { | ||||
|         for (s32 j = 0; sSm64CharMap[j].str != NULL; j++) { | ||||
|             if (sSm64CharMap[j].c == str64[i]) { | ||||
|                 len += strlen(sSm64CharMap[j].str); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return len; | ||||
| } | ||||
| 
 | ||||
| char* get_dialog_text_ascii(struct DialogEntry *dialog) { | ||||
|     if (!dialog) { return NULL; } | ||||
| 
 | ||||
|     size_t len = measure_converted_sm64_string(dialog->str); | ||||
| 
 | ||||
|     char* asciiStr = malloc(len + 1); | ||||
|     if (!asciiStr) { return NULL; } | ||||
| 
 | ||||
|     convert_string_sm64_to_ascii(asciiStr, dialog->str); | ||||
| 
 | ||||
|     return asciiStr; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
| --------------------------------------------------- | ||||
| Mapping gReplacedCourseActNameTable <-> seg2 tables | ||||
|  | @ -136,9 +106,7 @@ void smlua_text_utils_shutdown(void) { | |||
| } | ||||
| 
 | ||||
| static u8* smlua_text_utils_convert(const char* str) { | ||||
|     u8* dialogStr = calloc(strlen(str) + 2, sizeof(u8)); | ||||
|     convert_string_ascii_to_sm64(dialogStr, str, false); | ||||
|     return dialogStr; | ||||
|     return convert_string_ascii_to_sm64(NULL, str, false); | ||||
| } | ||||
| 
 | ||||
| // Checks the first 3 characters
 | ||||
|  | @ -261,7 +229,7 @@ void smlua_text_utils_dialog_restore(enum DialogId dialogId) { | |||
|     free(dialog->text); | ||||
| 
 | ||||
|     memcpy(dialog, dialogOrig, sizeof(struct DialogEntry)); | ||||
|     dialog->text = get_dialog_text_ascii(dialog); | ||||
|     dialog->text = convert_string_sm64_to_ascii(NULL, dialog->str); | ||||
| } | ||||
| 
 | ||||
| bool smlua_text_utils_dialog_is_replaced(enum DialogId dialogId) { | ||||
|  |  | |||
|  | @ -27,8 +27,6 @@ struct CourseActNames { | |||
| 
 | ||||
| extern struct CourseActNames gReplacedCourseActNameTable[]; // indexed by COURSE_* constants
 | ||||
| 
 | ||||
| char* get_dialog_text_ascii(struct DialogEntry *dialog); | ||||
| 
 | ||||
| void smlua_text_utils_init(void); | ||||
| void smlua_text_utils_shutdown(void); | ||||
| /* |description|Resets every modified dialog back to vanilla|descriptionEnd|*/ | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue