mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Compare commits
9 commits
d375d042b0
...
91aca3a3fc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91aca3a3fc | ||
|
|
fcef8699f2 | ||
|
|
c4c7f6c1b9 | ||
|
|
184bb8671d | ||
|
|
7865f1ba32 | ||
|
|
a8be244775 | ||
|
|
327b9be6f9 | ||
|
|
19c87a42ad | ||
|
|
c5019d1876 |
23 changed files with 317 additions and 148 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" ],
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Výběr souboru"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Průhlednost Textu"
|
||||
BACKGROUND_OPACITY = "Průhlednost pozadí"
|
||||
CHAT_SCALE = "Velikost Chatu"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Pouze lokální model hráče"
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Bestand selecteren"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Chat tekst doorzichtigheid"
|
||||
BACKGROUND_OPACITY = "Chat achtergrond doorzichtigheid"
|
||||
CHAT_SCALE = "Chat grootte"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Alleen lokaal spelermodel"
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "File Select"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Chat text opacity"
|
||||
BACKGROUND_OPACITY = "Chat background opacity"
|
||||
CHAT_SCALE = "Chat scale"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Local Player Model Only"
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Sélection de fichier"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Opacité du texte du tchat"
|
||||
BACKGROUND_OPACITY = "Opacité du fond du tchat"
|
||||
CHAT_SCALE = "Échelle du tchat"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Modèle de joueur local seulement"
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Dateiauswahl"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Chat-Textopazität"
|
||||
BACKGROUND_OPACITY = "Opazität des Chat-Hintergrunds"
|
||||
CHAT_SCALE = "Chat-Größe"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Nur lokales Spielermodell"
|
||||
|
|
|
|||
|
|
@ -187,6 +187,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Selezione file"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Opacità testo della chat"
|
||||
BACKGROUND_OPACITY = "Opacità sfondo della chat"
|
||||
CHAT_SCALE = "Grandezza della chat"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Solo modello del giocatore locale"
|
||||
|
|
|
|||
|
|
@ -190,6 +190,11 @@ MARIO_THEME = "マリオ"
|
|||
ODYSSEY_THEME = "オデッセイ風"
|
||||
FILE_SELECT_THEME = "ファイルセレクト風"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "チャットテキストの不透明度"
|
||||
BACKGROUND_OPACITY = "チャットの背景の不透明度"
|
||||
CHAT_SCALE = "チャットスケール"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "ローカルのキャラモデルに限定"
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Wybór Pliku"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Nieprzezroczystość tekstu czatu"
|
||||
BACKGROUND_OPACITY = "Nieprzezroczystość tła czatu"
|
||||
CHAT_SCALE = "Skala czatu"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Tylko lokalny model gracza"
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Seletor de Arquivo"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Opacidade do texto do chat"
|
||||
BACKGROUND_OPACITY = "Opacidade do fundo do chat"
|
||||
CHAT_SCALE = "Tamanho do chat"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Apenas modelo do jogador local"
|
||||
|
|
|
|||
|
|
@ -188,6 +188,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Одиссеи"
|
||||
FILE_SELECT_THEME = "Выбор файла"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Непрозрачность текста чата"
|
||||
BACKGROUND_OPACITY = "Непрозрачность фона чата"
|
||||
CHAT_SCALE = "Масштаб чата"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Только локальная модель игрока"
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ MARIO_THEME = "Mario"
|
|||
ODYSSEY_THEME = "Odyssey"
|
||||
FILE_SELECT_THEME = "Selección de archivo"
|
||||
|
||||
[CHAT_DISPLAY]
|
||||
TEXT_OPACITY = "Opacidad del texto del chat"
|
||||
BACKGROUND_OPACITY = "Opacidad del fondo del chat"
|
||||
CHAT_SCALE = "Escala del chat"
|
||||
|
||||
[DYNOS]
|
||||
DYNOS = "DYNOS"
|
||||
LOCAL_PLAYER_MODEL_ONLY = "Solo modelo de jugador local"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
*str64 = 0xFF;
|
||||
shouldResizeString = true;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
*strAscii = 0;
|
||||
shouldResizeString = true;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -207,6 +207,9 @@ bool configDjuiThemeCenter = true;
|
|||
bool configDjuiThemeGradients = true;
|
||||
unsigned int configDjuiThemeFont = FONT_NORMAL;
|
||||
unsigned int configDjuiScale = 0;
|
||||
unsigned int configDjuiChatAlpha = 255;
|
||||
unsigned int configDjuiBaseAlpha = 127;
|
||||
unsigned int configDjuiChatSize = 100;
|
||||
// other
|
||||
unsigned int configRulesVersion = 0;
|
||||
bool configCompressOnStartup = false;
|
||||
|
|
@ -362,6 +365,9 @@ static const struct ConfigOption options[] = {
|
|||
{.name = "djui_theme_gradients", .type = CONFIG_TYPE_BOOL, .boolValue = &configDjuiThemeGradients},
|
||||
{.name = "djui_theme_font", .type = CONFIG_TYPE_UINT, .uintValue = &configDjuiThemeFont},
|
||||
{.name = "djui_scale", .type = CONFIG_TYPE_UINT, .uintValue = &configDjuiScale},
|
||||
{.name = "djui_chat_alpha", .type = CONFIG_TYPE_UINT, .uintValue = &configDjuiChatAlpha},
|
||||
{.name = "djui_base_alpha", .type = CONFIG_TYPE_UINT, .uintValue = &configDjuiBaseAlpha},
|
||||
{.name = "djui_chat_size", .type = CONFIG_TYPE_UINT, .uintValue = &configDjuiChatSize},
|
||||
// other
|
||||
{.name = "rules_version", .type = CONFIG_TYPE_UINT, .uintValue = &configRulesVersion},
|
||||
{.name = "compress_on_startup", .type = CONFIG_TYPE_BOOL, .boolValue = &configCompressOnStartup},
|
||||
|
|
@ -789,6 +795,10 @@ NEXT_OPTION:
|
|||
if (configDjuiTheme >= DJUI_THEME_MAX) { configDjuiTheme = 0; }
|
||||
if (configDjuiScale >= 5) { configDjuiScale = 0; }
|
||||
|
||||
if (configDjuiChatAlpha > 255) { configDjuiChatAlpha = 255; }
|
||||
if (configDjuiBaseAlpha > 255) { configDjuiBaseAlpha = 255; }
|
||||
if (configDjuiChatSize > 200) { configDjuiChatSize = 200; }
|
||||
|
||||
if (gCLIOpts.fullscreen == 1) {
|
||||
configWindow.fullscreen = true;
|
||||
} else if (gCLIOpts.fullscreen == 2) {
|
||||
|
|
|
|||
|
|
@ -168,6 +168,9 @@ extern bool configDjuiThemeCenter;
|
|||
extern bool configDjuiThemeGradients;
|
||||
extern unsigned int configDjuiThemeFont;
|
||||
extern unsigned int configDjuiScale;
|
||||
extern unsigned int configDjuiChatAlpha;
|
||||
extern unsigned int configDjuiBaseAlpha;
|
||||
extern unsigned int configDjuiChatSize;
|
||||
// other
|
||||
extern unsigned int configRulesVersion;
|
||||
extern bool configCompressOnStartup;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
static bool djui_chat_message_render(struct DjuiBase* base) {
|
||||
struct DjuiChatMessage* chatMessage = (struct DjuiChatMessage*)base;
|
||||
struct DjuiBase* ctBase = &chatMessage->message->base;
|
||||
struct DjuiTheme* theme = gDjuiThemes[configDjuiTheme];
|
||||
|
||||
f32 seconds = clock_elapsed() - chatMessage->createTime;
|
||||
f32 f = 1.0f;
|
||||
|
|
@ -24,15 +25,15 @@ static bool djui_chat_message_render(struct DjuiBase* base) {
|
|||
}
|
||||
|
||||
if (gDjuiChatBoxFocus) {
|
||||
djui_base_set_color(base, 0, 0, 0, 120);
|
||||
djui_base_set_color(ctBase, 255, 255, 255, 255);
|
||||
djui_base_set_color(base, theme->threePanels.rectColor.r, theme->threePanels.rectColor.g, theme->threePanels.rectColor.b, configDjuiBaseAlpha);
|
||||
djui_base_set_color(ctBase, theme->interactables.textColor.r, theme->interactables.textColor.g, theme->interactables.textColor.b, configDjuiChatAlpha);
|
||||
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(base, 1.0f, chatMessage->base.height.value);
|
||||
} else if (f <= 0.1f) {
|
||||
return false;
|
||||
} else {
|
||||
djui_base_set_color(base, 0, 0, 0, 180 * f);
|
||||
djui_base_set_color(ctBase, 255, 255, 255, 255 * f);
|
||||
djui_base_set_color(base, theme->threePanels.rectColor.r, theme->threePanels.rectColor.g, theme->threePanels.rectColor.b, configDjuiBaseAlpha * f);
|
||||
djui_base_set_color(ctBase, theme->interactables.textColor.r, theme->interactables.textColor.g, theme->interactables.textColor.b, configDjuiChatAlpha * f);
|
||||
djui_base_set_size_type(base, DJUI_SVT_ABSOLUTE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(base, chatMessage->messageWidth, chatMessage->base.height.value);
|
||||
}
|
||||
|
|
@ -73,10 +74,11 @@ void djui_chat_message_create(const char* message) {
|
|||
if (gDjuiChatBox == NULL || gDjuiChatBox->chatFlow == NULL) { return; }
|
||||
struct DjuiChatMessage* chatMessage = calloc(1, sizeof(struct DjuiChatMessage));
|
||||
struct DjuiBase* base = &chatMessage->base;
|
||||
f32 chatScale = (configDjuiChatSize * 0.01);
|
||||
djui_base_init(&gDjuiChatBox->chatFlow->base, base, djui_chat_message_render, djui_chat_message_destroy);
|
||||
djui_base_set_size_type(base, DJUI_SVT_RELATIVE, DJUI_SVT_ABSOLUTE);
|
||||
djui_base_set_size(base, 1.0f, 0);
|
||||
djui_base_set_color(base, 0, 0, 0, 64);
|
||||
djui_base_set_size(base, chatScale, 0);
|
||||
djui_base_set_color(base, 0, 0, 0, configDjuiBaseAlpha);
|
||||
djui_base_set_padding(base, 2, 4, 2, 4);
|
||||
djui_base_set_alignment(base, DJUI_HALIGN_LEFT, DJUI_VALIGN_BOTTOM);
|
||||
|
||||
|
|
@ -86,15 +88,17 @@ void djui_chat_message_create(const char* message) {
|
|||
struct DjuiBase* ctBase = &chatText->base;
|
||||
djui_base_set_size_type(ctBase, DJUI_SVT_ABSOLUTE, DJUI_SVT_RELATIVE);
|
||||
djui_base_set_size(ctBase, maxTextWidth, 1.0f);
|
||||
djui_base_set_color(ctBase, 255, 255, 255, 255);
|
||||
djui_base_set_location(ctBase, 0, 0);
|
||||
djui_text_set_alignment(chatText, DJUI_HALIGN_LEFT, DJUI_VALIGN_TOP);
|
||||
djui_base_set_color(&chatText->base, 255, 255, 255, configDjuiChatAlpha);
|
||||
|
||||
chatMessage->message = chatText;
|
||||
chatText->fontScale *= chatScale;
|
||||
chatMessage->createTime = clock_elapsed();
|
||||
|
||||
// figure out chat message height
|
||||
chatText->base.comp.width = maxTextWidth;
|
||||
f32 messageHeight = djui_text_count_lines(chatText, 10) * (chatText->font->lineHeight * chatText->font->defaultFontScale) + 8;
|
||||
f32 messageHeight = djui_text_count_lines(chatText, 10) * (chatText->font->lineHeight * chatText->font->defaultFontScale * chatScale) + 8 * chatScale;
|
||||
djui_base_set_size(base, 1.0f, messageHeight);
|
||||
gDjuiChatBox->chatFlow->base.height.value += messageHeight + gDjuiChatBox->chatFlow->margin.value;
|
||||
if (!gDjuiChatBox->scrolling) {
|
||||
|
|
|
|||
|
|
@ -142,6 +142,10 @@ void djui_panel_main_menu_create(struct DjuiBase* caller) {
|
|||
char* djuiFontChoices[2] = {DLANG(DJUI_THEMES, FONT_NORMAL), DLANG(DJUI_THEMES, FONT_ALIASED)};
|
||||
djui_selectionbox_create(body, DLANG(DJUI_THEMES, DJUI_FONT), djuiFontChoices, 2, &configDjuiThemeFont, djui_panel_menu_options_djui_setting_change);
|
||||
|
||||
djui_slider_create(body, DLANG(CHAT_DISPLAY, TEXT_OPACITY), &configDjuiChatAlpha, 0, 255, NULL);
|
||||
djui_slider_create(body, DLANG(CHAT_DISPLAY, BACKGROUND_OPACITY), &configDjuiBaseAlpha, 0, 255, NULL);
|
||||
djui_slider_create(body, DLANG(CHAT_DISPLAY, CHAT_SCALE), &configDjuiChatSize, 0, 200, NULL);
|
||||
|
||||
if (gDjuiInMainMenu) {
|
||||
// copy sound choices from gMainMenuSounds
|
||||
int numSounds = sizeof(gMainMenuSounds) / sizeof(gMainMenuSounds[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