From 2e019d2c6b5a861a2f2b79f7fa0279eb4c8ccf07 Mon Sep 17 00:00:00 2001 From: cawtds Date: Mon, 20 May 2024 21:19:31 +0200 Subject: [PATCH] added metric units and optional imperial --- include/pokedex.h | 2 + include/strings.h | 5 + src/pokedex_screen.c | 337 +++++++++++++++++++++++++++---------------- src/string_util.c | 50 +++---- src/strings.c | 5 + 5 files changed, 252 insertions(+), 147 deletions(-) diff --git a/include/pokedex.h b/include/pokedex.h index f5d5756aa..1095fa7a9 100644 --- a/include/pokedex.h +++ b/include/pokedex.h @@ -122,6 +122,8 @@ u16 GetKantoPokedexCount(u8); bool16 HasAllHoennMons(void); bool16 HasAllKantoMons(void); bool16 HasAllMons(void); +u8* ConvertMonHeightToString(u32 height); +u8* ConvertMonWeightToString(u32 weight); u8 DexScreen_RegisterMonToPokedex(u16 species); diff --git a/include/strings.h b/include/strings.h index 185e0ca69..7e4eaa932 100644 --- a/include/strings.h +++ b/include/strings.h @@ -1034,6 +1034,11 @@ extern const u8 gText_Area[]; extern const u8 gText_Size[]; extern const u8 gText_AreaUnknown[]; +extern const u8 gText_UnkHeight[]; +extern const u8 gText_UnkHeightMetric[]; +extern const u8 gText_UnkWeight[]; +extern const u8 gText_UnkWeightMetric[]; + // daycare extern const u8 gText_Lv[]; extern const u8 gDaycareText_GetAlongVeryWell[]; diff --git a/src/pokedex_screen.c b/src/pokedex_screen.c index d82efc29d..17eeaebe6 100644 --- a/src/pokedex_screen.c +++ b/src/pokedex_screen.c @@ -138,6 +138,15 @@ static void ItemPrintFunc_OrderedListMenu(u8 windowId, u32 itemId, u8 y); static void Task_DexScreen_RegisterNonKantoMonBeforeNationalDex(u8 taskId); static void Task_DexScreen_RegisterMonToPokedex(u8 taskId); +static u8* GetUnknownMonHeightString(void); +static u8* GetUnknownMonWeightString(void); +static u8* ReplaceDecimalSeparator(const u8* originalString); +static u8* ConvertMonHeightToImperialString(u32 height); +static u8* ConvertMonHeightToMetricString(u32 height); +static u8* ConvertMonWeightToImperialString(u32 weight); +static u8* ConvertMonWeightToMetricString(u32 weight); +static u8* ConvertMeasurementToMetricString(u32 num, u32* index); + const u32 sCategoryMonInfoBgTiles[] = INCBIN_U32("graphics/pokedex/mini_page.4bpp.lz"); const u32 sKantoDexTiles[] = INCBIN_U32("graphics/pokedex/kanto_dex_bgtiles.4bpp.lz"); const u32 sNatDexTiles[] = INCBIN_U32("graphics/pokedex/national_dex_bgtiles.4bpp.lz"); @@ -2707,151 +2716,235 @@ void DexScreen_PrintMonCategory(u8 windowId, u16 species, u8 x, u8 y) void DexScreen_PrintMonHeight(u8 windowId, u16 species, u8 x, u8 y) { - u16 height; - u32 inches, feet; - const u8 *labelText; - u8 buffer[32]; - u8 i; - u16 natDexNum = SpeciesToNationalPokedexNum(species); + u8* heightString; - height = gSpeciesInfo[species].height; - labelText = gText_HT; + if (DexScreen_GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT, FALSE)) + heightString = ConvertMonHeightToString(gSpeciesInfo[species].height); + else + heightString = GetUnknownMonHeightString(); - i = 0; - buffer[i++] = EXT_CTRL_CODE_BEGIN; - buffer[i++] = EXT_CTRL_CODE_MIN_LETTER_SPACING; - buffer[i++] = 5; - buffer[i++] = CHAR_SPACE; + DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, gText_HT, x, y, 0); + x += 30; + DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, heightString, x, y, 0); + Free(heightString); +} - if (DexScreen_GetSetPokedexFlag(natDexNum, FLAG_GET_CAUGHT, FALSE)) +u8* ConvertMonHeightToString(u32 height) +{ + if (UNITS == UNITS_IMPERIAL) + return ConvertMonHeightToImperialString(height); + else + return ConvertMonHeightToMetricString(height); +} + +static u8* ConvertMonHeightToImperialString(u32 height) +{ + u32 inches, feet, index = 0; + u8* heightString = Alloc(WEIGHT_HEIGHT_STR_MEM); + + inches = (height * 10000) / CM_PER_INCH_FACTOR; + if (inches % 10 >= 5) + inches += 10; + feet = inches / INCHES_IN_FOOT_FACTOR; + inches = (inches - (feet * INCHES_IN_FOOT_FACTOR)) / 10; + + heightString[index++] = EXT_CTRL_CODE_BEGIN; + heightString[index++] = EXT_CTRL_CODE_CLEAR_TO; + + if (feet / 10 == 0) { - inches = 10000 * height / 254; // actually tenths of inches here - if (inches % 10 >= 5) - inches += 10; - feet = inches / 120; - inches = (inches - (feet * 120)) / 10; - if (feet / 10 == 0) - { - buffer[i++] = 0; - buffer[i++] = feet + CHAR_0; - } - else - { - buffer[i++] = feet / 10 + CHAR_0; - buffer[i++] = feet % 10 + CHAR_0; - } - buffer[i++] = CHAR_SGL_QUOTE_RIGHT; - buffer[i++] = inches / 10 + CHAR_0; - buffer[i++] = inches % 10 + CHAR_0; - buffer[i++] = CHAR_DBL_QUOTE_RIGHT; - buffer[i++] = EOS; + heightString[index++] = 15; + heightString[index++] = feet + CHAR_0; } else { - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_SGL_QUOTE_RIGHT; - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_DBL_QUOTE_RIGHT; + heightString[index++] = 10; + heightString[index++] = feet / 10 + CHAR_0; + heightString[index++] = (feet % 10) + CHAR_0; + } + heightString[index++] = CHAR_SGL_QUOTE_RIGHT; + heightString[index++] = (inches / 10) + CHAR_0; + heightString[index++] = (inches % 10) + CHAR_0; + heightString[index++] = CHAR_DBL_QUOTE_RIGHT; + heightString[index++] = EOS; + + return heightString; +} + +static u8* ConvertMonHeightToMetricString(u32 height) +{ + u32 index = 0; + u8* heightString = ConvertMeasurementToMetricString(height, &index); + + heightString[index++] = CHAR_m; + heightString[index++] = EOS; + return heightString; +} + +static u8* ConvertMeasurementToMetricString(u32 num, u32* index) +{ + u8* string = Alloc(WEIGHT_HEIGHT_STR_MEM); + bool32 outputted = FALSE; + u32 result; + + result = num / 1000; + if (result == 0) + { + string[(*index)++] = CHAR_SPACER; + outputted = FALSE; + } + else + { + string[(*index)++] = CHAR_0 + result; + outputted = TRUE; } - buffer[i++] = EOS; - DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, labelText, x, y, 0); - x += 30; - DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, buffer, x, y, 0); + result = (num % 1000) / 100; + if (result == 0 && !outputted) + { + string[(*index)++] = CHAR_SPACER; + outputted = FALSE; + } + else + { + string[(*index)++] = CHAR_0 + result; + outputted = TRUE; + } + + string[(*index)++] = CHAR_0 + ((num % 1000) % 100) / 10; + string[(*index)++] = CHAR_DEC_SEPARATOR; + string[(*index)++] = CHAR_0 + ((num % 1000) % 100) % 10; + string[(*index)++] = CHAR_SPACE; + + return string; } void DexScreen_PrintMonWeight(u8 windowId, u16 species, u8 x, u8 y) { - u16 weight; - u32 lbs; - bool8 output; - const u8 * labelText; - const u8 * lbsText; - u8 buffer[32]; - u8 i; - u32 j; - u16 natDexNum = SpeciesToNationalPokedexNum(species); + u8* weightString; - weight = gSpeciesInfo[species].weight; - labelText = gText_WT; - lbsText = gText_Lbs; + if (DexScreen_GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT, FALSE)) + weightString = ConvertMonWeightToString(gSpeciesInfo[species].weight); + else + weightString = GetUnknownMonWeightString(); - i = 0; - buffer[i++] = EXT_CTRL_CODE_BEGIN; - buffer[i++] = EXT_CTRL_CODE_MIN_LETTER_SPACING; - buffer[i++] = 5; + DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, gText_WT, x, y, 0); + x += 30; + DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, weightString, x, y, 0); + Free(weightString); +} - if (DexScreen_GetSetPokedexFlag(natDexNum, FLAG_GET_CAUGHT, FALSE)) +u8* ConvertMonWeightToString(u32 weight) +{ + if (UNITS == UNITS_IMPERIAL) + return ConvertMonWeightToImperialString(weight); + else + return ConvertMonWeightToMetricString(weight); +} + +static u8* ConvertMonWeightToImperialString(u32 weight) +{ + u8* weightString = Alloc(WEIGHT_HEIGHT_STR_MEM); + bool32 output = FALSE; + u32 index = 0, lbs = (weight * 100000) / DECAGRAMS_IN_POUND; + + if (lbs % 10u >= 5) + lbs += 10; + + if ((weightString[index] = (lbs / 100000) + CHAR_0) == CHAR_0 && !output) { - lbs = (weight * 100000) / 4536; // Convert to hundredths of lb - - // Round up to the nearest 0.1 lb - if (lbs % 10 >= 5) - lbs += 10; - - output = FALSE; - - if ((buffer[i] = (lbs / 100000) + CHAR_0) == CHAR_0 && !output) - { - buffer[i++] = CHAR_SPACE; - } - else - { - output = TRUE; - i++; - } - - lbs %= 100000; - if ((buffer[i] = (lbs / 10000) + CHAR_0) == CHAR_0 && !output) - { - buffer[i++] = CHAR_SPACE; - } - else - { - output = TRUE; - i++; - } - - lbs %= 10000; - if ((buffer[i] = (lbs / 1000) + CHAR_0) == CHAR_0 && !output) - { - buffer[i++] = CHAR_SPACE; - } - else - { - output = TRUE; - i++; - } - - lbs %= 1000; - buffer[i++] = (lbs / 100) + CHAR_0; - lbs %= 100; - buffer[i++] = CHAR_PERIOD; - buffer[i++] = (lbs / 10) + CHAR_0; + weightString[index++] = CHAR_SPACER; } else { - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_QUESTION_MARK; - buffer[i++] = CHAR_PERIOD; - buffer[i++] = CHAR_QUESTION_MARK; + output = TRUE; + index++; } - buffer[i++] = CHAR_SPACE; - buffer[i++] = EXT_CTRL_CODE_BEGIN; - buffer[i++] = EXT_CTRL_CODE_MIN_LETTER_SPACING; - buffer[i++] = 0; - for (j = 0; j < 33 - i && lbsText[j] != EOS; j++) - buffer[i + j] = lbsText[j]; + lbs %= 100000; + if ((weightString[index] = (lbs / 10000) + CHAR_0) == CHAR_0 && !output) + { + weightString[index++] = CHAR_SPACER; + } + else + { + output = TRUE; + index++; + } - buffer[i + j] = EOS; - DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, labelText, x, y, 0); - x += 30; - DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, buffer, x, y, 0); + lbs %= 10000; + if ((weightString[index] = (lbs / 1000) + CHAR_0) == CHAR_0 && !output) + { + weightString[index++] = CHAR_SPACER; + } + else + { + output = TRUE; + index++; + } + + lbs %= 1000; + weightString[index++] = (lbs / 100) + CHAR_0; + lbs %= 100; + weightString[index++] = CHAR_DEC_SEPARATOR; + weightString[index++] = (lbs / 10) + CHAR_0; + weightString[index++] = CHAR_SPACE; + weightString[index++] = CHAR_l; + weightString[index++] = CHAR_b; + weightString[index++] = CHAR_s; + weightString[index++] = CHAR_PERIOD; + weightString[index++] = EOS; + + return weightString; +} + +static u8* ConvertMonWeightToMetricString(u32 weight) +{ + u32 index = 0; + u8* weightString = ConvertMeasurementToMetricString(weight, &index); + + weightString[index++] = CHAR_k; + weightString[index++] = CHAR_g; + weightString[index++] = CHAR_PERIOD; + weightString[index++] = EOS; + return weightString; +} + +static u8* GetUnknownMonHeightString(void) +{ + if (UNITS == UNITS_IMPERIAL) + return ReplaceDecimalSeparator(gText_UnkHeight); + else + return ReplaceDecimalSeparator(gText_UnkHeightMetric); +} + +static u8* GetUnknownMonWeightString(void) +{ + if (UNITS == UNITS_IMPERIAL) + return ReplaceDecimalSeparator(gText_UnkWeight); + else + return ReplaceDecimalSeparator(gText_UnkWeightMetric); +} + +static u8* ReplaceDecimalSeparator(const u8* originalString) +{ + bool32 replaced = FALSE; + u32 length = StringLength(originalString), i; + u8* modifiedString = Alloc(WEIGHT_HEIGHT_STR_MEM); + + for (i = 0; i < length; i++) + { + if ((originalString[i] != CHAR_PERIOD) || replaced) + { + modifiedString[i] = originalString[i]; + continue; + } + + modifiedString[i] = CHAR_DEC_SEPARATOR; + replaced = TRUE; + } + modifiedString[length] = EOS; + return modifiedString; } void DexScreen_PrintMonFlavorText(u8 windowId, u16 species, u8 x, u8 y) diff --git a/src/string_util.c b/src/string_util.c index 4744e231c..0516db5b3 100644 --- a/src/string_util.c +++ b/src/string_util.c @@ -599,31 +599,31 @@ u8 GetExtCtrlCodeLength(u8 code) { static const u8 lengths[] = { - 1, - 2, - 2, - 2, - 4, - 2, - 2, - 1, - 2, - 1, - 1, - 3, - 2, - 2, - 2, - 1, - 3, - 2, - 2, - 2, - 2, - 1, - 1, - 1, - 1, + [0] = 1, + [EXT_CTRL_CODE_COLOR] = 2, + [EXT_CTRL_CODE_HIGHLIGHT] = 2, + [EXT_CTRL_CODE_SHADOW] = 2, + [EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW] = 4, + [EXT_CTRL_CODE_PALETTE] = 2, + [EXT_CTRL_CODE_FONT] = 2, + [EXT_CTRL_CODE_RESET_FONT] = 1, + [EXT_CTRL_CODE_PAUSE] = 2, + [EXT_CTRL_CODE_PAUSE_UNTIL_PRESS] = 1, + [EXT_CTRL_CODE_WAIT_SE] = 1, + [EXT_CTRL_CODE_PLAY_BGM] = 3, + [EXT_CTRL_CODE_ESCAPE] = 2, + [EXT_CTRL_CODE_SHIFT_RIGHT] = 2, + [EXT_CTRL_CODE_SHIFT_DOWN] = 2, + [EXT_CTRL_CODE_FILL_WINDOW] = 1, + [EXT_CTRL_CODE_PLAY_SE] = 3, + [EXT_CTRL_CODE_CLEAR] = 2, + [EXT_CTRL_CODE_SKIP] = 2, + [EXT_CTRL_CODE_CLEAR_TO] = 2, + [EXT_CTRL_CODE_MIN_LETTER_SPACING] = 2, + [EXT_CTRL_CODE_JPN] = 1, + [EXT_CTRL_CODE_ENG] = 1, + [EXT_CTRL_CODE_PAUSE_MUSIC] = 1, + [EXT_CTRL_CODE_RESUME_MUSIC] = 1, }; u8 length = 0; diff --git a/src/strings.c b/src/strings.c index 58be4fede..8b258325d 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1354,3 +1354,8 @@ const u8 gText_BasePointsResetToZero[] = _("{STR_VAR_1}'s base points\nwere all const u8 gText_PkmnFriendlyBaseVar2Fell[] = _("{STR_VAR_1} turned friendly.\nThe base {STR_VAR_2} fell!{PAUSE_UNTIL_PRESS}"); const u8 gText_PkmnAdoresBaseVar2Fell[] = _("{STR_VAR_1} adores you!\nThe base {STR_VAR_2} fell!{PAUSE_UNTIL_PRESS}"); const u8 gText_PkmnFriendlyBaseVar2CantFall[] = _("{STR_VAR_1} turned friendly.\nThe base {STR_VAR_2} can't fall!{PAUSE_UNTIL_PRESS}"); + +const u8 gText_UnkHeight[] = _("{CLEAR_TO 0x0A}??'??”"); +const u8 gText_UnkHeightMetric[] = _("???.? m"); +const u8 gText_UnkWeight[] = _("????.? lbs."); +const u8 gText_UnkWeightMetric[] = _("???.? kg.");