From 2b580ab41602d94578387c03de25aa52a36a5b0f Mon Sep 17 00:00:00 2001 From: gheskett Date: Mon, 26 Jul 2021 04:08:08 -0500 Subject: [PATCH] Add colored text --- README.md | 3 ++ charmap.txt | 1 + src/game/ingame_menu.c | 82 ++++++++++++++++++++++++++++++++++++++++-- src/game/ingame_menu.h | 1 + 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6a93e258..07eadafb 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,9 @@ This is a fork of the ultrasm64 repo by CrashOveride which includes the followin - ia8 coins (64x64), the vanilla coin texture is upgraded to accomodate. * - Skybox size modifier. You can have 2x, 3x and 4x size skyboxes (you can select the skybox size in `config.h`.) Please note that this might affect console performance, especially 4x mode. 2x or 3x mode is recommended if aiming for console. By CowQuack * - You can set the black border size to different values for console and emulator. It's set to 0 by default for both. * +- Colored ia4 text support. Format: "@XXXXXXXX[YOUR TEXT]@--------" (By ArcticJaguar725) + - Example Text: "@FF0000FFRED @00FF00FFGREEN @0000FFFFBLUE @FFFFFF00INVISIBLE @--------NORMAL" + - NOTE: It is not mandatory to reset the text color with "@--------", but text will need to be recolored each time it scrolls in a dialog box, or the custom color will reset. # UltraSM64 diff --git a/charmap.txt b/charmap.txt index 49aaee55..a1581c13 100644 --- a/charmap.txt +++ b/charmap.txt @@ -220,6 +220,7 @@ 'ィ' = 0xD6 'ゥ' = 0xD7 'ォ' = 0xD8 +'@' = 0xDF '[%]' = 0xE0 '(' = 0xE1 '(' = 0xE1 diff --git a/src/game/ingame_menu.c b/src/game/ingame_menu.c index 9cd458a8..ce25a4ab 100644 --- a/src/game/ingame_menu.c +++ b/src/game/ingame_menu.c @@ -270,10 +270,51 @@ void print_generic_string(s16 x, s16 y, const u8 *str) { s32 strPos = 0; u8 lineNum = 1; + s16 colorLoop; + u8 rgbaColors[4] = {0, 0, 0, 0}; + u8 customColor = FALSE; + u8 diffTmp = 0; + create_dl_translation_matrix(MENU_MTX_PUSH, x, y, 0.0f); while (str[strPos] != DIALOG_CHAR_TERMINATOR) { + if (customColor == TRUE) { + gDPSetEnvColor(gDisplayListHead++, rgbaColors[0], rgbaColors[1], rgbaColors[2], rgbaColors[3]); + } + else { + if (customColor == 2) { + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); // TODO: Is it possible to retrieve the original color that was set before print_generic_string was called? + customColor = FALSE; + } + } + switch (str[strPos]) { + case DIALOG_CHAR_COLOR: + customColor = TRUE; + strPos++; + for (colorLoop = strPos + 8; strPos < colorLoop; ++strPos) { + diffTmp = 0; + if (str[strPos] >= 0x24 && str[strPos] <= 0x29) { + diffTmp = 0x1A; + } + else if (str[strPos] >= 0x10) { + customColor = 2; + if (str[strPos] == 0x9F) + strPos = colorLoop; + else + strPos = colorLoop - 8; + break; + break; + } + if ((8 - (colorLoop - strPos)) % 2 == 0) { + rgbaColors[(8 - (colorLoop - strPos)) / 2] = ((str[strPos] - diffTmp) & 0x0F) << 4; + } + else { + rgbaColors[(8 - (colorLoop - strPos)) / 2] += ((str[strPos] - diffTmp) & 0x0F); + } + } + strPos--; + break; case DIALOG_CHAR_DAKUTEN: mark = DIALOG_MARK_DAKUTEN; break; @@ -671,7 +712,7 @@ void render_dialog_box_type(struct DialogEntry *dialog, s8 linesPerBox) { gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); } -void change_and_flash_dialog_text_color_lines(s8 colorMode, s8 lineNum) { +void change_and_flash_dialog_text_color_lines(s8 colorMode, s8 lineNum, u8 *customColor) { u8 colorFade; if (colorMode == 1) { @@ -688,6 +729,10 @@ void change_and_flash_dialog_text_color_lines(s8 colorMode, s8 lineNum) { } else { switch (gDialogBoxType) { case DIALOG_TYPE_ROTATE: + if (*customColor == 2) { + gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, 255); + *customColor = FALSE; + } break; case DIALOG_TYPE_ZOOM: gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 255); @@ -780,6 +825,10 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l u8 strChar; + s16 colorLoop; + u8 rgbaColors[4] = {0, 0, 0, 0}; + u8 customColor = FALSE; + u8 *str = segmented_to_virtual(dialog->str); s8 lineNum = 1; @@ -812,7 +861,12 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l create_dl_translation_matrix(MENU_MTX_PUSH, X_VAL3, 2 - lineNum * Y_VAL3, 0); while (pageState == DIALOG_PAGE_STATE_NONE) { - change_and_flash_dialog_text_color_lines(colorMode, lineNum); + if (customColor == TRUE) { + gDPSetEnvColor(gDisplayListHead++, rgbaColors[0], rgbaColors[1], rgbaColors[2], rgbaColors[3]); + } + else { + change_and_flash_dialog_text_color_lines(colorMode, lineNum, &customColor); + } strChar = str[strIdx]; switch (strChar) { @@ -820,6 +874,30 @@ void handle_dialog_text_and_pages(s8 colorMode, struct DialogEntry *dialog, s8 l pageState = DIALOG_PAGE_STATE_END; gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW); break; + case DIALOG_CHAR_COLOR: + customColor = TRUE; + strIdx++; + for (colorLoop = strIdx + 8; strIdx < colorLoop; ++strIdx) { + if (str[strIdx] >= 0x24 && str[strIdx] <= 0x29) { + str[strIdx] -= 0x1A; + } + else if (str[strIdx] >= 0x10) { + customColor = 2; + if (str[strIdx] == 0x9F) + strIdx = colorLoop; + else + strIdx = colorLoop - 8; + break; + } + if ((8 - (colorLoop - strIdx)) % 2 == 0) { + rgbaColors[(8 - (colorLoop - strIdx)) / 2] = (str[strIdx] & 0x0F) << 4; + } + else { + rgbaColors[(8 - (colorLoop - strIdx)) / 2] += (str[strIdx] & 0x0F); + } + } + strIdx--; + break; case DIALOG_CHAR_NEWLINE: lineNum++; handle_dialog_scroll_page_state(lineNum, totalLines, &pageState, &xMatrix, &linePos); diff --git a/src/game/ingame_menu.h b/src/game/ingame_menu.h index 53df5e31..1102d2f5 100644 --- a/src/game/ingame_menu.h +++ b/src/game/ingame_menu.h @@ -98,6 +98,7 @@ enum DialogSpecialChars { #endif DIALOG_CHAR_PERIOD = 0x6E, DIALOG_CHAR_COMMA = 0x6F, + DIALOG_CHAR_COLOR = 0xDF, DIALOG_CHAR_SPACE = 0x9E, DIALOG_CHAR_STAR_COUNT = 0xE0, // number of stars DIALOG_CHAR_UMLAUT = 0xE9,