mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Fix inconsistent mapping between sSm64CharMap and str_ascii_to_dialog (#892)
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run
This fixes inconsistent mappings between `sSm64CharMap` and `str_ascii_to_dialog` (used in `smlua_text_utils_dialog_replace`) to make the `text` field of `dialogEntry` consistent `str_ascii_to_dialog` now also has mappings for the interpunct (`•`) and the double opening (`<<`) and closing (`>>`) quotes, which were missing before.
This commit is contained in:
parent
c9db7006a3
commit
3d458d0212
5 changed files with 15 additions and 188 deletions
|
|
@ -3,100 +3,6 @@ extern "C" {
|
|||
#include "game/scroll_targets.h"
|
||||
}
|
||||
|
||||
//
|
||||
// String
|
||||
//
|
||||
|
||||
static const struct { const char *mStr; u8 mChar64; s32 mWidth; } sSm64CharMap[] = {
|
||||
{ "0", 0x00, 7 }, { "1", 0x01, 7 }, { "2", 0x02, 7 }, { "3", 0x03, 7 }, { "4", 0x04, 7 }, { "5", 0x05, 7 },
|
||||
{ "6", 0x06, 7 }, { "7", 0x07, 7 }, { "8", 0x08, 7 }, { "9", 0x09, 7 }, { "A", 0x0A, 6 }, { "B", 0x0B, 6 },
|
||||
{ "C", 0x0C, 6 }, { "D", 0x0D, 6 }, { "E", 0x0E, 6 }, { "F", 0x0F, 6 }, { "G", 0x10, 6 }, { "H", 0x11, 6 },
|
||||
{ "I", 0x12, 5 }, { "J", 0x13, 6 }, { "K", 0x14, 6 }, { "L", 0x15, 5 }, { "M", 0x16, 8 }, { "N", 0x17, 8 },
|
||||
{ "O", 0x18, 6 }, { "P", 0x19, 6 }, { "Q", 0x1A, 6 }, { "R", 0x1B, 6 }, { "S", 0x1C, 6 }, { "T", 0x1D, 5 },
|
||||
{ "U", 0x1E, 6 }, { "V", 0x1F, 6 }, { "W", 0x20, 8 }, { "X", 0x21, 7 }, { "Y", 0x22, 6 }, { "Z", 0x23, 6 },
|
||||
{ "a", 0x24, 6 }, { "b", 0x25, 5 }, { "c", 0x26, 5 }, { "d", 0x27, 6 }, { "e", 0x28, 5 }, { "f", 0x29, 5 },
|
||||
{ "g", 0x2A, 6 }, { "h", 0x2B, 5 }, { "i", 0x2C, 4 }, { "j", 0x2D, 5 }, { "k", 0x2E, 5 }, { "l", 0x2F, 3 },
|
||||
{ "m", 0x30, 7 }, { "n", 0x31, 5 }, { "o", 0x32, 5 }, { "p", 0x33, 5 }, { "q", 0x34, 6 }, { "r", 0x35, 5 },
|
||||
{ "s", 0x36, 5 }, { "t", 0x37, 5 }, { "u", 0x38, 5 }, { "v", 0x39, 5 }, { "w", 0x3A, 7 }, { "x", 0x3B, 7 },
|
||||
{ "y", 0x3C, 5 }, { "z", 0x3D, 5 }, { "\'", 0x3E, 4 }, { ".", 0x3F, 4 }, { "^", 0x50, 8 }, { "|", 0x51, 8 },
|
||||
{ "<", 0x52, 8 }, { ">", 0x53, 8 }, { "[A]", 0x54, 7 }, { "[B]", 0x55, 7 }, { "[C]", 0x56, 6 }, { "[Z]", 0x57, 7 },
|
||||
{ "[R]", 0x58, 7 }, { ",", 0x6F, 4 }, { " ", 0x9E, 5 }, { "-", 0x9F, 6 }, { "/", 0xD0, 10 }, { "[%]", 0xE0, 7 },
|
||||
{ "(", 0xE1, 5 }, { ")(", 0xE2, 10 }, { ")", 0xE3, 5 }, { "+", 0xE4, 9 }, { "&", 0xE5, 8 }, { ":", 0xE6, 4 },
|
||||
{ "!", 0xF2, 5 }, { "%", 0xF3, 7 }, { "?", 0xF4, 7 }, { "~", 0xF7, 8 }, { "$", 0xF9, 8 }, { "@", 0xFA, 10 },
|
||||
{ "*", 0xFB, 6 }, { "=", 0xFD, 10 }, { "\n", 0xFE, 0 },
|
||||
};
|
||||
|
||||
static const char *DynOS_String_AddChar64(u8 *aStr64, const char *pStr, s32 &aIndex) {
|
||||
for (const auto &c : sSm64CharMap) {
|
||||
if (strstr(pStr, c.mStr) == pStr) {
|
||||
aStr64[aIndex++] = c.mChar64;
|
||||
return pStr + strlen(c.mStr);
|
||||
}
|
||||
}
|
||||
|
||||
// Put a space by default
|
||||
aStr64[aIndex++] = 0x9E;
|
||||
return pStr + 1;
|
||||
}
|
||||
|
||||
u8 *DynOS_String_Convert(const char *aString, bool aHeapAlloc) {
|
||||
|
||||
// Allocation
|
||||
static u8 sStringBuffer[8][2048];
|
||||
static u32 sStringBufferIndex = 0;
|
||||
u8 *_Str64;
|
||||
if (aHeapAlloc) {
|
||||
_Str64 = New<u8>(2048);
|
||||
} else {
|
||||
_Str64 = sStringBuffer[sStringBufferIndex];
|
||||
sStringBufferIndex = (sStringBufferIndex + 1) % 8;
|
||||
}
|
||||
|
||||
// Conversion
|
||||
memset(_Str64, 0xFF, 2048);
|
||||
const char *pStr = aString;
|
||||
for (s32 i = 0; *pStr != 0 && i < 2047;) {
|
||||
pStr = DynOS_String_AddChar64(_Str64, pStr, i);
|
||||
}
|
||||
return _Str64;
|
||||
}
|
||||
|
||||
u8 *DynOS_String_Decapitalize(u8 *aStr64) {
|
||||
bool _WasSpace = true;
|
||||
for (u8 *pStr64 = aStr64; *pStr64 != 0xFF; pStr64++) {
|
||||
if (*pStr64 >= 10 && *pStr64 <= 35) {
|
||||
if (_WasSpace) _WasSpace = false;
|
||||
else *pStr64 += 26;
|
||||
} else if (*pStr64 >= 63) {
|
||||
_WasSpace = true;
|
||||
}
|
||||
}
|
||||
return aStr64;
|
||||
}
|
||||
|
||||
s32 DynOS_String_Length(const u8 *aStr64) {
|
||||
s32 _Length = 0;
|
||||
for (; aStr64 && *aStr64 != 255; aStr64++, _Length++);
|
||||
return _Length;
|
||||
}
|
||||
|
||||
s32 DynOS_String_WidthChar64(u8 aChar64) {
|
||||
for (const auto &c : sSm64CharMap) {
|
||||
if (c.mChar64 == aChar64) {
|
||||
return c.mWidth;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 DynOS_String_Width(const u8 *aStr64) {
|
||||
s32 _Width = 0;
|
||||
for (; *aStr64 != 0xFF; aStr64++) {
|
||||
_Width += DynOS_String_WidthChar64(*aStr64);
|
||||
}
|
||||
return _Width;
|
||||
}
|
||||
|
||||
//
|
||||
// Scroll Targets
|
||||
//
|
||||
|
|
|
|||
|
|
@ -448,86 +448,6 @@ void render_multi_text_string(s16 *xPos, s16 *yPos, s8 multiTextID)
|
|||
}
|
||||
#endif
|
||||
|
||||
u8 str_ascii_char_to_dialog(char c) {
|
||||
switch (c) {
|
||||
case '/': return 0xD0;
|
||||
case '>': return 0x53;
|
||||
case '<': return 0x52;
|
||||
case '|': return 0x51;
|
||||
case '^': return 0x50;
|
||||
case '\n': return 0xFE;
|
||||
case '$': return 0xF9;
|
||||
case '~': return 0xF7;
|
||||
case '?': return 0xF4;
|
||||
case '%': return 0xF3;
|
||||
case '!': return 0xF2;
|
||||
case ':': return 0xE6;
|
||||
case '&': return 0xE5;
|
||||
case '+': return 0xE4;
|
||||
case ')': return 0xE3;
|
||||
case '(': return 0xE1;
|
||||
case '-': return 0x9F;
|
||||
case ' ': return 0x9E;
|
||||
case ',': return 0x6F;
|
||||
case '.': return 0x3F;
|
||||
case '@': return 0xFA;
|
||||
case '*': return 0xFB;
|
||||
case '=': return 0xFD;
|
||||
case '\'': return 0x3E;
|
||||
case '\0': return DIALOG_CHAR_TERMINATOR;
|
||||
default: return ((u8)c < 0xF0) ? ASCII_TO_DIALOG(c) : c;
|
||||
}
|
||||
}
|
||||
|
||||
void str_ascii_to_dialog(const char* string, u8* dialog, u16 length) {
|
||||
const char* c = string;
|
||||
u8* d = dialog;
|
||||
u16 converted = 0;
|
||||
|
||||
while (*c != '\0' && converted < (length - 1)) {
|
||||
if (!strncmp(c, "you", 3) && (c[3] < 'a' || c[3] > 'z')) {
|
||||
*d = 0xD2;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "the", 3) && (c[3] < 'a' || c[3] > 'z')) {
|
||||
*d = 0xD1;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "[R]", 3)) {
|
||||
*d = 0x58;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "[Z]", 3)) {
|
||||
*d = 0x57;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "[C]", 3)) {
|
||||
*d = 0x56;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "[B]", 3)) {
|
||||
*d = 0x55;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "[A]", 3)) {
|
||||
*d = 0x54;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "[Z]", 3)) {
|
||||
*d = 0x57;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, ")(", 2)) {
|
||||
*d = 0xE2;
|
||||
c += 1;
|
||||
} else if (!strncmp(c, "[%]", 3)) {
|
||||
*d = 0xE0;
|
||||
c += 2;
|
||||
} else if (!strncmp(c, "★", 2)) {
|
||||
*d = 0xFA;
|
||||
c += 2;
|
||||
} else {
|
||||
*d = str_ascii_char_to_dialog(*c);
|
||||
}
|
||||
d++;
|
||||
c++;
|
||||
converted++;
|
||||
}
|
||||
*d = DIALOG_CHAR_TERMINATOR;
|
||||
}
|
||||
|
||||
f32 get_generic_dialog_width(u8* dialog) {
|
||||
#ifdef VERSION_JP
|
||||
return 0;
|
||||
|
|
@ -551,7 +471,7 @@ f32 get_generic_dialog_width(u8* dialog) {
|
|||
|
||||
f32 get_generic_ascii_string_width(const char* ascii) {
|
||||
u8 dialog[256] = { DIALOG_CHAR_TERMINATOR };
|
||||
str_ascii_to_dialog(ascii, dialog, strlen(ascii));
|
||||
convert_string_ascii_to_sm64(dialog, ascii, false);
|
||||
return get_generic_dialog_width(dialog);
|
||||
}
|
||||
|
||||
|
|
@ -567,13 +487,13 @@ f32 get_generic_dialog_height(u8* dialog) {
|
|||
|
||||
f32 get_generic_ascii_string_height(const char* ascii) {
|
||||
u8 dialog[256] = { DIALOG_CHAR_TERMINATOR };
|
||||
str_ascii_to_dialog(ascii, dialog, strlen(ascii));
|
||||
convert_string_ascii_to_sm64(dialog, ascii, false);
|
||||
return get_generic_dialog_height(dialog);
|
||||
}
|
||||
|
||||
void print_generic_ascii_string(s16 x, s16 y, const char* ascii) {
|
||||
u8 dialog[256] = { DIALOG_CHAR_TERMINATOR };
|
||||
str_ascii_to_dialog(ascii, dialog, strlen(ascii));
|
||||
convert_string_ascii_to_sm64(dialog, ascii, false);
|
||||
print_generic_string(x, y, dialog);
|
||||
}
|
||||
|
||||
|
|
@ -2637,7 +2557,7 @@ void render_pause_camera_options(s16 x, s16 y, s8 *index, s16 xIndex) {
|
|||
|
||||
void render_pause_course_options(s16 x, s16 y, s8 *index, s16 yIndex) {
|
||||
u8 TEXT_EXIT_TO_CASTLE[16] = { DIALOG_CHAR_TERMINATOR };
|
||||
str_ascii_to_dialog("EXIT TO CASTLE", TEXT_EXIT_TO_CASTLE, 15);
|
||||
convert_string_ascii_to_sm64(TEXT_EXIT_TO_CASTLE, "EXIT TO CASTLE", false);
|
||||
|
||||
#ifdef VERSION_EU
|
||||
u8 textContinue[][10] = {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ const struct { const char *str; u8 c; u8 menu; } sSm64CharMap[] = {
|
|||
{ "z", 0x3D, 0 },
|
||||
|
||||
// Punctuation
|
||||
{ "...", 0xE6, 0 }, // ellipsis
|
||||
{ ":", 0xE6, 0 }, // colon
|
||||
{ ")(", 0xE2, 0 }, // close-open parentheses
|
||||
{ "<<", 0xF5, 0 }, // double quote open
|
||||
{ ">>", 0xF6, 0 }, // double quote close
|
||||
|
|
@ -67,16 +67,17 @@ const struct { const char *str; u8 c; u8 menu; } sSm64CharMap[] = {
|
|||
{ "[C]", 0x56, 0 }, // bold C
|
||||
{ "[Z]", 0x57, 0 }, // bold Z
|
||||
{ "[R]", 0x58, 0 }, // bold R
|
||||
{ "<->", 0xE4, 0 }, // left-right arrow
|
||||
{ "+", 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
|
||||
{ "$", 0xF9, 1 }, // coin
|
||||
{ "★", 0xFA, 1 }, // star filled
|
||||
{ "@", 0xFA, 1 }, // star filled (both ★ and @ match 0xFA)
|
||||
{ "*", 0xFB, 1 }, // multiply
|
||||
{ "•", 0xFC, 0 },
|
||||
{ "$", 0xFD, 0 }, // star empty
|
||||
{ "•", 0xFC, 0 }, // interpunct (unused)
|
||||
{ "=", 0xFD, 0 }, // star empty
|
||||
{ "\n", 0xFE, 1 }, // New line
|
||||
{ NULL, 0xFF, 1 }, // Null terminator
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +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);
|
||||
/* |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
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ static bool sReplacedDialog[DIALOG_COUNT] = { 0 };
|
|||
#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[];
|
||||
void convert_string_sm64_to_ascii(char *strAscii, const u8 *str64);
|
||||
|
||||
static size_t measure_converted_sm64_string(const u8* str64) {
|
||||
size_t len = 0;
|
||||
|
|
@ -146,9 +145,8 @@ void smlua_text_utils_shutdown(void) {
|
|||
}
|
||||
|
||||
static u8* smlua_text_utils_convert(const char* str) {
|
||||
s32 len = strlen(str);
|
||||
u8* dialogStr = calloc(len + 2, sizeof(u8));
|
||||
str_ascii_to_dialog(str, dialogStr, len + 1);
|
||||
u8* dialogStr = calloc(strlen(str) + 2, sizeof(u8));
|
||||
convert_string_ascii_to_sm64(dialogStr, str, false);
|
||||
return dialogStr;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue