From fc8ee625b68d061027384e74b95d5f5fd9a1e2f0 Mon Sep 17 00:00:00 2001 From: gruxor Date: Fri, 21 Jul 2023 15:51:03 -0400 Subject: [PATCH] Fixed outstanding UB with -fanalyzer on modern --- Makefile | 2 +- include/overworld.h | 2 +- src/battle_gfx_sfx_util.c | 7 +- src/fieldmap.c | 29 +- src/overworld.c | 13 +- src/pokemon.c | 1112 +++++++++++++++++++------------------ 6 files changed, 594 insertions(+), 571 deletions(-) diff --git a/Makefile b/Makefile index c4964e42eb..f107a09d44 100644 --- a/Makefile +++ b/Makefile @@ -118,7 +118,7 @@ LIBPATH := -L ../../tools/agbcc/lib LIB := $(LIBPATH) -lgcc -lc -L../../libagbsyscall -lagbsyscall else CC1 = $(shell $(PATH_MODERNCC) --print-prog-name=cc1) -quiet -override CFLAGS += -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast +override CFLAGS += -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast -std=gnu17 -fanalyzer ROM := $(MODERN_ROM_NAME) OBJ_DIR := $(MODERN_OBJ_DIR_NAME) LIBPATH := -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libgcc.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libnosys.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libc.a))" diff --git a/include/overworld.h b/include/overworld.h index adaa6aad04..bda2046ec7 100644 --- a/include/overworld.h +++ b/include/overworld.h @@ -67,7 +67,7 @@ void LoadObjEventTemplatesFromHeader(void); void LoadSaveblockObjEventScripts(void); void SetObjEventTemplateCoords(u8 localId, s16 x, s16 y); void SetObjEventTemplateMovementType(u8 localId, u8 movementType); -const struct MapLayout *GetMapLayout(void); +const struct MapLayout *GetMapLayout(u16 mapLayoutId); void ApplyCurrentWarp(void); struct MapHeader const *const Overworld_GetMapHeaderByGroupAndId(u16 mapGroup, u16 mapNum); struct MapHeader const *const GetDestinationWarpMapHeader(void); diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index bf3422c135..24011d6709 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -1210,8 +1210,11 @@ void AllocateMonSpritesGfx(void) for (j = 0; j < 4; j++) { - gMonSpritesGfxPtr->frameImages[i][j].data = gMonSpritesGfxPtr->sprites.ptr[i] + (j * MON_PIC_SIZE); - gMonSpritesGfxPtr->frameImages[i][j].size = MON_PIC_SIZE; + if (gMonSpritesGfxPtr->sprites.ptr[i] + (j * MON_PIC_SIZE)) + { + gMonSpritesGfxPtr->frameImages[i][j].data = gMonSpritesGfxPtr->sprites.ptr[i] + (j * MON_PIC_SIZE); + gMonSpritesGfxPtr->frameImages[i][j].size = MON_PIC_SIZE; + } } gMonSpritesGfxPtr->templates[i].images = gMonSpritesGfxPtr->frameImages[i]; diff --git a/src/fieldmap.c b/src/fieldmap.c index bdacf7ab25..225b1ce69e 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -621,8 +621,8 @@ bool32 CanCameraMoveInDirection(int direction) static void SetPositionFromConnection(const struct MapConnection *connection, int direction, int x, int y) { - struct MapHeader const *mapHeader; - mapHeader = GetMapHeaderFromConnection(connection); + struct MapHeader const *mapHeader = GetMapHeaderFromConnection(connection); + switch (direction) { case CONNECTION_EAST: @@ -641,6 +641,9 @@ static void SetPositionFromConnection(const struct MapConnection *connection, in gSaveBlock1Ptr->pos.x -= connection->offset; gSaveBlock1Ptr->pos.y = mapHeader->mapLayout->height; break; + default: + DebugPrintfLevel(MGBA_LOG_WARN, "SetPositionFromConnection was passed an invalid direction (%d)!", direction); + break; } } @@ -663,14 +666,20 @@ bool8 CameraMove(int x, int y) old_x = gSaveBlock1Ptr->pos.x; old_y = gSaveBlock1Ptr->pos.y; connection = GetIncomingConnection(direction, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y); - SetPositionFromConnection(connection, direction, x, y); - LoadMapFromCameraTransition(connection->mapGroup, connection->mapNum); - gCamera.active = TRUE; - gCamera.x = old_x - gSaveBlock1Ptr->pos.x; - gCamera.y = old_y - gSaveBlock1Ptr->pos.y; - gSaveBlock1Ptr->pos.x += x; - gSaveBlock1Ptr->pos.y += y; - MoveMapViewToBackup(direction); + if (connection) + { + SetPositionFromConnection(connection, direction, x, y); + LoadMapFromCameraTransition(connection->mapGroup, connection->mapNum); + gCamera.active = TRUE; + gCamera.x = old_x - gSaveBlock1Ptr->pos.x; + gCamera.y = old_y - gSaveBlock1Ptr->pos.y; + gSaveBlock1Ptr->pos.x += x; + gSaveBlock1Ptr->pos.y += y; + MoveMapViewToBackup(direction); + } + else + DebugPrintfLevel(MGBA_LOG_WARN, "GetIncomingConnection returned an invalid connection inside CameraMove!"); + } return gCamera.active; } diff --git a/src/overworld.c b/src/overworld.c index bb1b98611b..0152a48579 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -556,12 +556,9 @@ static void InitMapView(void) InitTilesetAnimations(); } -const struct MapLayout *GetMapLayout(void) +const struct MapLayout *GetMapLayout(u16 mapLayoutId) { - u16 mapLayoutId = gSaveBlock1Ptr->mapLayoutId; - if (mapLayoutId) - return gMapLayouts[mapLayoutId - 1]; - return NULL; + return gMapLayouts[mapLayoutId - 1]; } void ApplyCurrentWarp(void) @@ -618,13 +615,13 @@ static void LoadCurrentMapData(void) sLastMapSectionId = gMapHeader.regionMapSectionId; gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum); gSaveBlock1Ptr->mapLayoutId = gMapHeader.mapLayoutId; - gMapHeader.mapLayout = GetMapLayout(); + gMapHeader.mapLayout = GetMapLayout(gMapHeader.mapLayoutId); } static void LoadSaveblockMapHeader(void) { gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum); - gMapHeader.mapLayout = GetMapLayout(); + gMapHeader.mapLayout = GetMapLayout(gMapHeader.mapLayoutId); } static void SetPlayerCoordsFromWarp(void) @@ -1020,7 +1017,7 @@ u8 GetFlashLevel(void) void SetCurrentMapLayout(u16 mapLayoutId) { gSaveBlock1Ptr->mapLayoutId = mapLayoutId; - gMapHeader.mapLayout = GetMapLayout(); + gMapHeader.mapLayout = GetMapLayout(mapLayoutId); } void SetObjectEventLoadFlag(u8 flag) diff --git a/src/pokemon.c b/src/pokemon.c index 4347d7a0ee..929e8ee89d 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4771,329 +4771,337 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) boxMon->isEgg = TRUE; substruct3->isEgg = TRUE; } - } - switch (field) - { - case MON_DATA_PERSONALITY: - retVal = boxMon->personality; - break; - case MON_DATA_OT_ID: - retVal = boxMon->otId; - break; - case MON_DATA_NICKNAME: - { - if (boxMon->isBadEgg) + switch (field) { - for (retVal = 0; - retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS; - data[retVal] = gText_BadEgg[retVal], retVal++) {} + case MON_DATA_SPECIES: + retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species; + break; + case MON_DATA_HELD_ITEM: + retVal = substruct0->heldItem; + break; + case MON_DATA_EXP: + retVal = substruct0->experience; + break; + case MON_DATA_PP_BONUSES: + retVal = substruct0->ppBonuses; + break; + case MON_DATA_FRIENDSHIP: + retVal = substruct0->friendship; + break; + case MON_DATA_MOVE1: + case MON_DATA_MOVE2: + case MON_DATA_MOVE3: + case MON_DATA_MOVE4: + retVal = substruct1->moves[field - MON_DATA_MOVE1]; + break; + case MON_DATA_PP1: + case MON_DATA_PP2: + case MON_DATA_PP3: + case MON_DATA_PP4: + retVal = substruct1->pp[field - MON_DATA_PP1]; + break; + case MON_DATA_HP_EV: + retVal = substruct2->hpEV; + break; + case MON_DATA_ATK_EV: + retVal = substruct2->attackEV; + break; + case MON_DATA_DEF_EV: + retVal = substruct2->defenseEV; + break; + case MON_DATA_SPEED_EV: + retVal = substruct2->speedEV; + break; + case MON_DATA_SPATK_EV: + retVal = substruct2->spAttackEV; + break; + case MON_DATA_SPDEF_EV: + retVal = substruct2->spDefenseEV; + break; + case MON_DATA_COOL: + retVal = substruct2->cool; + break; + case MON_DATA_BEAUTY: + retVal = substruct2->beauty; + break; + case MON_DATA_CUTE: + retVal = substruct2->cute; + break; + case MON_DATA_SMART: + retVal = substruct2->smart; + break; + case MON_DATA_TOUGH: + retVal = substruct2->tough; + break; + case MON_DATA_SHEEN: + retVal = substruct2->sheen; + break; + case MON_DATA_POKERUS: + retVal = substruct3->pokerus; + break; + case MON_DATA_MET_LOCATION: + retVal = substruct3->metLocation; + break; + case MON_DATA_MET_LEVEL: + retVal = substruct3->metLevel; + break; + case MON_DATA_MET_GAME: + retVal = substruct3->metGame; + break; + case MON_DATA_POKEBALL: + retVal = substruct0->pokeball; + break; + case MON_DATA_OT_GENDER: + retVal = substruct3->otGender; + break; + case MON_DATA_HP_IV: + retVal = substruct3->hpIV; + break; + case MON_DATA_ATK_IV: + retVal = substruct3->attackIV; + break; + case MON_DATA_DEF_IV: + retVal = substruct3->defenseIV; + break; + case MON_DATA_SPEED_IV: + retVal = substruct3->speedIV; + break; + case MON_DATA_SPATK_IV: + retVal = substruct3->spAttackIV; + break; + case MON_DATA_SPDEF_IV: + retVal = substruct3->spDefenseIV; + break; + case MON_DATA_IS_EGG: + retVal = substruct3->isEgg; + break; + case MON_DATA_ABILITY_NUM: + retVal = substruct3->abilityNum; + break; + case MON_DATA_COOL_RIBBON: + retVal = substruct3->coolRibbon; + break; + case MON_DATA_BEAUTY_RIBBON: + retVal = substruct3->beautyRibbon; + break; + case MON_DATA_CUTE_RIBBON: + retVal = substruct3->cuteRibbon; + break; + case MON_DATA_SMART_RIBBON: + retVal = substruct3->smartRibbon; + break; + case MON_DATA_TOUGH_RIBBON: + retVal = substruct3->toughRibbon; + break; + case MON_DATA_CHAMPION_RIBBON: + retVal = substruct3->championRibbon; + break; + case MON_DATA_WINNING_RIBBON: + retVal = substruct3->winningRibbon; + break; + case MON_DATA_VICTORY_RIBBON: + retVal = substruct3->victoryRibbon; + break; + case MON_DATA_ARTIST_RIBBON: + retVal = substruct3->artistRibbon; + break; + case MON_DATA_EFFORT_RIBBON: + retVal = substruct3->effortRibbon; + break; + case MON_DATA_MARINE_RIBBON: + retVal = substruct3->marineRibbon; + break; + case MON_DATA_LAND_RIBBON: + retVal = substruct3->landRibbon; + break; + case MON_DATA_SKY_RIBBON: + retVal = substruct3->skyRibbon; + break; + case MON_DATA_COUNTRY_RIBBON: + retVal = substruct3->countryRibbon; + break; + case MON_DATA_NATIONAL_RIBBON: + retVal = substruct3->nationalRibbon; + break; + case MON_DATA_EARTH_RIBBON: + retVal = substruct3->earthRibbon; + break; + case MON_DATA_WORLD_RIBBON: + retVal = substruct3->worldRibbon; + break; + case MON_DATA_UNUSED_RIBBONS: + retVal = substruct3->unusedRibbons; + break; + case MON_DATA_MODERN_FATEFUL_ENCOUNTER: + retVal = substruct3->modernFatefulEncounter; + break; + case MON_DATA_SPECIES_OR_EGG: + retVal = substruct0->species; + if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg)) + retVal = SPECIES_EGG; + break; + case MON_DATA_IVS: + retVal = substruct3->hpIV + | (substruct3->attackIV << 5) + | (substruct3->defenseIV << 10) + | (substruct3->speedIV << 15) + | (substruct3->spAttackIV << 20) + | (substruct3->spDefenseIV << 25); + break; + case MON_DATA_KNOWN_MOVES: + if (substruct0->species && !substruct3->isEgg) + { + u16 *moves = (u16 *)data; + s32 i = 0; - data[retVal] = EOS; - } - else if (boxMon->isEgg) - { - StringCopy(data, gText_EggNickname); - retVal = StringLength(data); - } - else if (boxMon->language == LANGUAGE_JAPANESE) - { - data[0] = EXT_CTRL_CODE_BEGIN; - data[1] = EXT_CTRL_CODE_JPN; - - for (retVal = 2, i = 0; - i < 5 && boxMon->nickname[i] != EOS; - data[retVal] = boxMon->nickname[i], retVal++, i++) {} - - data[retVal++] = EXT_CTRL_CODE_BEGIN; - data[retVal++] = EXT_CTRL_CODE_ENG; - data[retVal] = EOS; - } - else - { - for (retVal = 0; - retVal < POKEMON_NAME_LENGTH; - data[retVal] = boxMon->nickname[retVal], retVal++){} - - data[retVal] = EOS; - } - break; - } - case MON_DATA_LANGUAGE: - retVal = boxMon->language; - break; - case MON_DATA_SANITY_IS_BAD_EGG: - retVal = boxMon->isBadEgg; - break; - case MON_DATA_SANITY_HAS_SPECIES: - retVal = boxMon->hasSpecies; - break; - case MON_DATA_SANITY_IS_EGG: - retVal = boxMon->isEgg; - break; - case MON_DATA_OT_NAME: - { - retVal = 0; - - while (retVal < PLAYER_NAME_LENGTH) - { - data[retVal] = boxMon->otName[retVal]; - retVal++; - } - - data[retVal] = EOS; - break; - } - case MON_DATA_MARKINGS: - retVal = boxMon->markings; - break; - case MON_DATA_CHECKSUM: - retVal = boxMon->checksum; - break; - case MON_DATA_ENCRYPT_SEPARATOR: - retVal = boxMon->unknown; - break; - case MON_DATA_SPECIES: - retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species; - break; - case MON_DATA_HELD_ITEM: - retVal = substruct0->heldItem; - break; - case MON_DATA_EXP: - retVal = substruct0->experience; - break; - case MON_DATA_PP_BONUSES: - retVal = substruct0->ppBonuses; - break; - case MON_DATA_FRIENDSHIP: - retVal = substruct0->friendship; - break; - case MON_DATA_MOVE1: - case MON_DATA_MOVE2: - case MON_DATA_MOVE3: - case MON_DATA_MOVE4: - retVal = substruct1->moves[field - MON_DATA_MOVE1]; - break; - case MON_DATA_PP1: - case MON_DATA_PP2: - case MON_DATA_PP3: - case MON_DATA_PP4: - retVal = substruct1->pp[field - MON_DATA_PP1]; - break; - case MON_DATA_HP_EV: - retVal = substruct2->hpEV; - break; - case MON_DATA_ATK_EV: - retVal = substruct2->attackEV; - break; - case MON_DATA_DEF_EV: - retVal = substruct2->defenseEV; - break; - case MON_DATA_SPEED_EV: - retVal = substruct2->speedEV; - break; - case MON_DATA_SPATK_EV: - retVal = substruct2->spAttackEV; - break; - case MON_DATA_SPDEF_EV: - retVal = substruct2->spDefenseEV; - break; - case MON_DATA_COOL: - retVal = substruct2->cool; - break; - case MON_DATA_BEAUTY: - retVal = substruct2->beauty; - break; - case MON_DATA_CUTE: - retVal = substruct2->cute; - break; - case MON_DATA_SMART: - retVal = substruct2->smart; - break; - case MON_DATA_TOUGH: - retVal = substruct2->tough; - break; - case MON_DATA_SHEEN: - retVal = substruct2->sheen; - break; - case MON_DATA_POKERUS: - retVal = substruct3->pokerus; - break; - case MON_DATA_MET_LOCATION: - retVal = substruct3->metLocation; - break; - case MON_DATA_MET_LEVEL: - retVal = substruct3->metLevel; - break; - case MON_DATA_MET_GAME: - retVal = substruct3->metGame; - break; - case MON_DATA_POKEBALL: - retVal = substruct0->pokeball; - break; - case MON_DATA_OT_GENDER: - retVal = substruct3->otGender; - break; - case MON_DATA_HP_IV: - retVal = substruct3->hpIV; - break; - case MON_DATA_ATK_IV: - retVal = substruct3->attackIV; - break; - case MON_DATA_DEF_IV: - retVal = substruct3->defenseIV; - break; - case MON_DATA_SPEED_IV: - retVal = substruct3->speedIV; - break; - case MON_DATA_SPATK_IV: - retVal = substruct3->spAttackIV; - break; - case MON_DATA_SPDEF_IV: - retVal = substruct3->spDefenseIV; - break; - case MON_DATA_IS_EGG: - retVal = substruct3->isEgg; - break; - case MON_DATA_ABILITY_NUM: - retVal = substruct3->abilityNum; - break; - case MON_DATA_COOL_RIBBON: - retVal = substruct3->coolRibbon; - break; - case MON_DATA_BEAUTY_RIBBON: - retVal = substruct3->beautyRibbon; - break; - case MON_DATA_CUTE_RIBBON: - retVal = substruct3->cuteRibbon; - break; - case MON_DATA_SMART_RIBBON: - retVal = substruct3->smartRibbon; - break; - case MON_DATA_TOUGH_RIBBON: - retVal = substruct3->toughRibbon; - break; - case MON_DATA_CHAMPION_RIBBON: - retVal = substruct3->championRibbon; - break; - case MON_DATA_WINNING_RIBBON: - retVal = substruct3->winningRibbon; - break; - case MON_DATA_VICTORY_RIBBON: - retVal = substruct3->victoryRibbon; - break; - case MON_DATA_ARTIST_RIBBON: - retVal = substruct3->artistRibbon; - break; - case MON_DATA_EFFORT_RIBBON: - retVal = substruct3->effortRibbon; - break; - case MON_DATA_MARINE_RIBBON: - retVal = substruct3->marineRibbon; - break; - case MON_DATA_LAND_RIBBON: - retVal = substruct3->landRibbon; - break; - case MON_DATA_SKY_RIBBON: - retVal = substruct3->skyRibbon; - break; - case MON_DATA_COUNTRY_RIBBON: - retVal = substruct3->countryRibbon; - break; - case MON_DATA_NATIONAL_RIBBON: - retVal = substruct3->nationalRibbon; - break; - case MON_DATA_EARTH_RIBBON: - retVal = substruct3->earthRibbon; - break; - case MON_DATA_WORLD_RIBBON: - retVal = substruct3->worldRibbon; - break; - case MON_DATA_UNUSED_RIBBONS: - retVal = substruct3->unusedRibbons; - break; - case MON_DATA_MODERN_FATEFUL_ENCOUNTER: - retVal = substruct3->modernFatefulEncounter; - break; - case MON_DATA_SPECIES_OR_EGG: - retVal = substruct0->species; - if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg)) - retVal = SPECIES_EGG; - break; - case MON_DATA_IVS: - retVal = substruct3->hpIV - | (substruct3->attackIV << 5) - | (substruct3->defenseIV << 10) - | (substruct3->speedIV << 15) - | (substruct3->spAttackIV << 20) - | (substruct3->spDefenseIV << 25); - break; - case MON_DATA_KNOWN_MOVES: - if (substruct0->species && !substruct3->isEgg) - { - u16 *moves = (u16 *)data; - s32 i = 0; - - while (moves[i] != MOVES_COUNT) - { - u16 move = moves[i]; - if (substruct1->moves[0] == move - || substruct1->moves[1] == move - || substruct1->moves[2] == move - || substruct1->moves[3] == move) - retVal |= gBitTable[i]; - i++; + while (moves[i] != MOVES_COUNT) + { + u16 move = moves[i]; + if (substruct1->moves[0] == move + || substruct1->moves[1] == move + || substruct1->moves[2] == move + || substruct1->moves[3] == move) + retVal |= gBitTable[i]; + i++; + } + } + break; + case MON_DATA_RIBBON_COUNT: + retVal = 0; + if (substruct0->species && !substruct3->isEgg) + { + retVal += substruct3->coolRibbon; + retVal += substruct3->beautyRibbon; + retVal += substruct3->cuteRibbon; + retVal += substruct3->smartRibbon; + retVal += substruct3->toughRibbon; + retVal += substruct3->championRibbon; + retVal += substruct3->winningRibbon; + retVal += substruct3->victoryRibbon; + retVal += substruct3->artistRibbon; + retVal += substruct3->effortRibbon; + retVal += substruct3->marineRibbon; + retVal += substruct3->landRibbon; + retVal += substruct3->skyRibbon; + retVal += substruct3->countryRibbon; + retVal += substruct3->nationalRibbon; + retVal += substruct3->earthRibbon; + retVal += substruct3->worldRibbon; + } + break; + case MON_DATA_RIBBONS: + retVal = 0; + if (substruct0->species && !substruct3->isEgg) + { + retVal = substruct3->championRibbon + | (substruct3->coolRibbon << 1) + | (substruct3->beautyRibbon << 4) + | (substruct3->cuteRibbon << 7) + | (substruct3->smartRibbon << 10) + | (substruct3->toughRibbon << 13) + | (substruct3->winningRibbon << 16) + | (substruct3->victoryRibbon << 17) + | (substruct3->artistRibbon << 18) + | (substruct3->effortRibbon << 19) + | (substruct3->marineRibbon << 20) + | (substruct3->landRibbon << 21) + | (substruct3->skyRibbon << 22) + | (substruct3->countryRibbon << 23) + | (substruct3->nationalRibbon << 24) + | (substruct3->earthRibbon << 25) + | (substruct3->worldRibbon << 26); + } + break; + default: + break; } - } - break; - case MON_DATA_RIBBON_COUNT: - retVal = 0; - if (substruct0->species && !substruct3->isEgg) + } + else + { + switch (field) { - retVal += substruct3->coolRibbon; - retVal += substruct3->beautyRibbon; - retVal += substruct3->cuteRibbon; - retVal += substruct3->smartRibbon; - retVal += substruct3->toughRibbon; - retVal += substruct3->championRibbon; - retVal += substruct3->winningRibbon; - retVal += substruct3->victoryRibbon; - retVal += substruct3->artistRibbon; - retVal += substruct3->effortRibbon; - retVal += substruct3->marineRibbon; - retVal += substruct3->landRibbon; - retVal += substruct3->skyRibbon; - retVal += substruct3->countryRibbon; - retVal += substruct3->nationalRibbon; - retVal += substruct3->earthRibbon; - retVal += substruct3->worldRibbon; - } - break; - case MON_DATA_RIBBONS: - retVal = 0; - if (substruct0->species && !substruct3->isEgg) + case MON_DATA_PERSONALITY: + retVal = boxMon->personality; + break; + case MON_DATA_OT_ID: + retVal = boxMon->otId; + break; + case MON_DATA_NICKNAME: { - retVal = substruct3->championRibbon - | (substruct3->coolRibbon << 1) - | (substruct3->beautyRibbon << 4) - | (substruct3->cuteRibbon << 7) - | (substruct3->smartRibbon << 10) - | (substruct3->toughRibbon << 13) - | (substruct3->winningRibbon << 16) - | (substruct3->victoryRibbon << 17) - | (substruct3->artistRibbon << 18) - | (substruct3->effortRibbon << 19) - | (substruct3->marineRibbon << 20) - | (substruct3->landRibbon << 21) - | (substruct3->skyRibbon << 22) - | (substruct3->countryRibbon << 23) - | (substruct3->nationalRibbon << 24) - | (substruct3->earthRibbon << 25) - | (substruct3->worldRibbon << 26); + if (boxMon->isBadEgg) + { + for (retVal = 0; + retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS; + data[retVal] = gText_BadEgg[retVal], retVal++) {} + + data[retVal] = EOS; + } + else if (boxMon->isEgg) + { + StringCopy(data, gText_EggNickname); + retVal = StringLength(data); + } + else if (boxMon->language == LANGUAGE_JAPANESE) + { + data[0] = EXT_CTRL_CODE_BEGIN; + data[1] = EXT_CTRL_CODE_JPN; + + for (retVal = 2, i = 0; + i < 5 && boxMon->nickname[i] != EOS; + data[retVal] = boxMon->nickname[i], retVal++, i++) {} + + data[retVal++] = EXT_CTRL_CODE_BEGIN; + data[retVal++] = EXT_CTRL_CODE_ENG; + data[retVal] = EOS; + } + else + { + for (retVal = 0; + retVal < POKEMON_NAME_LENGTH; + data[retVal] = boxMon->nickname[retVal], retVal++){} + + data[retVal] = EOS; + } + break; + } + case MON_DATA_LANGUAGE: + retVal = boxMon->language; + break; + case MON_DATA_SANITY_IS_BAD_EGG: + retVal = boxMon->isBadEgg; + break; + case MON_DATA_SANITY_HAS_SPECIES: + retVal = boxMon->hasSpecies; + break; + case MON_DATA_SANITY_IS_EGG: + retVal = boxMon->isEgg; + break; + case MON_DATA_OT_NAME: + { + retVal = 0; + + while (retVal < PLAYER_NAME_LENGTH) + { + data[retVal] = boxMon->otName[retVal]; + retVal++; + } + + data[retVal] = EOS; + break; + } + case MON_DATA_MARKINGS: + retVal = boxMon->markings; + break; + case MON_DATA_CHECKSUM: + retVal = boxMon->checksum; + break; + case MON_DATA_ENCRYPT_SEPARATOR: + retVal = boxMon->unknown; + break; + default: + break; } - break; - default: - break; } if (field > MON_DATA_ENCRYPT_SEPARATOR) @@ -5176,242 +5184,248 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) EncryptBoxMon(boxMon); return; } - } - switch (field) - { - case MON_DATA_PERSONALITY: - SET32(boxMon->personality); - break; - case MON_DATA_OT_ID: - SET32(boxMon->otId); - break; - case MON_DATA_NICKNAME: - { - s32 i; - for (i = 0; i < POKEMON_NAME_LENGTH; i++) - boxMon->nickname[i] = data[i]; - break; + switch (field) + { + case MON_DATA_SPECIES: + { + SET16(substruct0->species); + if (substruct0->species) + boxMon->hasSpecies = TRUE; + else + boxMon->hasSpecies = FALSE; + break; + } + case MON_DATA_HELD_ITEM: + SET16(substruct0->heldItem); + break; + case MON_DATA_EXP: + SET32(substruct0->experience); + break; + case MON_DATA_PP_BONUSES: + SET8(substruct0->ppBonuses); + break; + case MON_DATA_FRIENDSHIP: + SET8(substruct0->friendship); + break; + case MON_DATA_MOVE1: + case MON_DATA_MOVE2: + case MON_DATA_MOVE3: + case MON_DATA_MOVE4: + SET16(substruct1->moves[field - MON_DATA_MOVE1]); + break; + case MON_DATA_PP1: + case MON_DATA_PP2: + case MON_DATA_PP3: + case MON_DATA_PP4: + SET8(substruct1->pp[field - MON_DATA_PP1]); + break; + case MON_DATA_HP_EV: + SET8(substruct2->hpEV); + break; + case MON_DATA_ATK_EV: + SET8(substruct2->attackEV); + break; + case MON_DATA_DEF_EV: + SET8(substruct2->defenseEV); + break; + case MON_DATA_SPEED_EV: + SET8(substruct2->speedEV); + break; + case MON_DATA_SPATK_EV: + SET8(substruct2->spAttackEV); + break; + case MON_DATA_SPDEF_EV: + SET8(substruct2->spDefenseEV); + break; + case MON_DATA_COOL: + SET8(substruct2->cool); + break; + case MON_DATA_BEAUTY: + SET8(substruct2->beauty); + break; + case MON_DATA_CUTE: + SET8(substruct2->cute); + break; + case MON_DATA_SMART: + SET8(substruct2->smart); + break; + case MON_DATA_TOUGH: + SET8(substruct2->tough); + break; + case MON_DATA_SHEEN: + SET8(substruct2->sheen); + break; + case MON_DATA_POKERUS: + SET8(substruct3->pokerus); + break; + case MON_DATA_MET_LOCATION: + SET8(substruct3->metLocation); + break; + case MON_DATA_MET_LEVEL: + { + u8 metLevel = *data; + substruct3->metLevel = metLevel; + break; + } + case MON_DATA_MET_GAME: + SET8(substruct3->metGame); + break; + case MON_DATA_POKEBALL: + { + u8 pokeball = *data; + substruct0->pokeball = pokeball; + break; + } + case MON_DATA_OT_GENDER: + SET8(substruct3->otGender); + break; + case MON_DATA_HP_IV: + SET8(substruct3->hpIV); + break; + case MON_DATA_ATK_IV: + SET8(substruct3->attackIV); + break; + case MON_DATA_DEF_IV: + SET8(substruct3->defenseIV); + break; + case MON_DATA_SPEED_IV: + SET8(substruct3->speedIV); + break; + case MON_DATA_SPATK_IV: + SET8(substruct3->spAttackIV); + break; + case MON_DATA_SPDEF_IV: + SET8(substruct3->spDefenseIV); + break; + case MON_DATA_IS_EGG: + SET8(substruct3->isEgg); + if (substruct3->isEgg) + boxMon->isEgg = TRUE; + else + boxMon->isEgg = FALSE; + break; + case MON_DATA_ABILITY_NUM: + SET8(substruct3->abilityNum); + break; + case MON_DATA_COOL_RIBBON: + SET8(substruct3->coolRibbon); + break; + case MON_DATA_BEAUTY_RIBBON: + SET8(substruct3->beautyRibbon); + break; + case MON_DATA_CUTE_RIBBON: + SET8(substruct3->cuteRibbon); + break; + case MON_DATA_SMART_RIBBON: + SET8(substruct3->smartRibbon); + break; + case MON_DATA_TOUGH_RIBBON: + SET8(substruct3->toughRibbon); + break; + case MON_DATA_CHAMPION_RIBBON: + SET8(substruct3->championRibbon); + break; + case MON_DATA_WINNING_RIBBON: + SET8(substruct3->winningRibbon); + break; + case MON_DATA_VICTORY_RIBBON: + SET8(substruct3->victoryRibbon); + break; + case MON_DATA_ARTIST_RIBBON: + SET8(substruct3->artistRibbon); + break; + case MON_DATA_EFFORT_RIBBON: + SET8(substruct3->effortRibbon); + break; + case MON_DATA_MARINE_RIBBON: + SET8(substruct3->marineRibbon); + break; + case MON_DATA_LAND_RIBBON: + SET8(substruct3->landRibbon); + break; + case MON_DATA_SKY_RIBBON: + SET8(substruct3->skyRibbon); + break; + case MON_DATA_COUNTRY_RIBBON: + SET8(substruct3->countryRibbon); + break; + case MON_DATA_NATIONAL_RIBBON: + SET8(substruct3->nationalRibbon); + break; + case MON_DATA_EARTH_RIBBON: + SET8(substruct3->earthRibbon); + break; + case MON_DATA_WORLD_RIBBON: + SET8(substruct3->worldRibbon); + break; + case MON_DATA_UNUSED_RIBBONS: + SET8(substruct3->unusedRibbons); + break; + case MON_DATA_MODERN_FATEFUL_ENCOUNTER: + SET8(substruct3->modernFatefulEncounter); + break; + case MON_DATA_IVS: + { + u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + substruct3->hpIV = ivs & MAX_IV_MASK; + substruct3->attackIV = (ivs >> 5) & MAX_IV_MASK; + substruct3->defenseIV = (ivs >> 10) & MAX_IV_MASK; + substruct3->speedIV = (ivs >> 15) & MAX_IV_MASK; + substruct3->spAttackIV = (ivs >> 20) & MAX_IV_MASK; + substruct3->spDefenseIV = (ivs >> 25) & MAX_IV_MASK; + break; + } + default: + break; + } } - case MON_DATA_LANGUAGE: - SET8(boxMon->language); - break; - case MON_DATA_SANITY_IS_BAD_EGG: - SET8(boxMon->isBadEgg); - break; - case MON_DATA_SANITY_HAS_SPECIES: - SET8(boxMon->hasSpecies); - break; - case MON_DATA_SANITY_IS_EGG: - SET8(boxMon->isEgg); - break; - case MON_DATA_OT_NAME: + else { - s32 i; - for (i = 0; i < PLAYER_NAME_LENGTH; i++) - boxMon->otName[i] = data[i]; - break; - } - case MON_DATA_MARKINGS: - SET8(boxMon->markings); - break; - case MON_DATA_CHECKSUM: - SET16(boxMon->checksum); - break; - case MON_DATA_ENCRYPT_SEPARATOR: - SET16(boxMon->unknown); - break; - case MON_DATA_SPECIES: - { - SET16(substruct0->species); - if (substruct0->species) - boxMon->hasSpecies = TRUE; - else - boxMon->hasSpecies = FALSE; - break; - } - case MON_DATA_HELD_ITEM: - SET16(substruct0->heldItem); - break; - case MON_DATA_EXP: - SET32(substruct0->experience); - break; - case MON_DATA_PP_BONUSES: - SET8(substruct0->ppBonuses); - break; - case MON_DATA_FRIENDSHIP: - SET8(substruct0->friendship); - break; - case MON_DATA_MOVE1: - case MON_DATA_MOVE2: - case MON_DATA_MOVE3: - case MON_DATA_MOVE4: - SET16(substruct1->moves[field - MON_DATA_MOVE1]); - break; - case MON_DATA_PP1: - case MON_DATA_PP2: - case MON_DATA_PP3: - case MON_DATA_PP4: - SET8(substruct1->pp[field - MON_DATA_PP1]); - break; - case MON_DATA_HP_EV: - SET8(substruct2->hpEV); - break; - case MON_DATA_ATK_EV: - SET8(substruct2->attackEV); - break; - case MON_DATA_DEF_EV: - SET8(substruct2->defenseEV); - break; - case MON_DATA_SPEED_EV: - SET8(substruct2->speedEV); - break; - case MON_DATA_SPATK_EV: - SET8(substruct2->spAttackEV); - break; - case MON_DATA_SPDEF_EV: - SET8(substruct2->spDefenseEV); - break; - case MON_DATA_COOL: - SET8(substruct2->cool); - break; - case MON_DATA_BEAUTY: - SET8(substruct2->beauty); - break; - case MON_DATA_CUTE: - SET8(substruct2->cute); - break; - case MON_DATA_SMART: - SET8(substruct2->smart); - break; - case MON_DATA_TOUGH: - SET8(substruct2->tough); - break; - case MON_DATA_SHEEN: - SET8(substruct2->sheen); - break; - case MON_DATA_POKERUS: - SET8(substruct3->pokerus); - break; - case MON_DATA_MET_LOCATION: - SET8(substruct3->metLocation); - break; - case MON_DATA_MET_LEVEL: - { - u8 metLevel = *data; - substruct3->metLevel = metLevel; - break; - } - case MON_DATA_MET_GAME: - SET8(substruct3->metGame); - break; - case MON_DATA_POKEBALL: - { - u8 pokeball = *data; - substruct0->pokeball = pokeball; - break; - } - case MON_DATA_OT_GENDER: - SET8(substruct3->otGender); - break; - case MON_DATA_HP_IV: - SET8(substruct3->hpIV); - break; - case MON_DATA_ATK_IV: - SET8(substruct3->attackIV); - break; - case MON_DATA_DEF_IV: - SET8(substruct3->defenseIV); - break; - case MON_DATA_SPEED_IV: - SET8(substruct3->speedIV); - break; - case MON_DATA_SPATK_IV: - SET8(substruct3->spAttackIV); - break; - case MON_DATA_SPDEF_IV: - SET8(substruct3->spDefenseIV); - break; - case MON_DATA_IS_EGG: - SET8(substruct3->isEgg); - if (substruct3->isEgg) - boxMon->isEgg = TRUE; - else - boxMon->isEgg = FALSE; - break; - case MON_DATA_ABILITY_NUM: - SET8(substruct3->abilityNum); - break; - case MON_DATA_COOL_RIBBON: - SET8(substruct3->coolRibbon); - break; - case MON_DATA_BEAUTY_RIBBON: - SET8(substruct3->beautyRibbon); - break; - case MON_DATA_CUTE_RIBBON: - SET8(substruct3->cuteRibbon); - break; - case MON_DATA_SMART_RIBBON: - SET8(substruct3->smartRibbon); - break; - case MON_DATA_TOUGH_RIBBON: - SET8(substruct3->toughRibbon); - break; - case MON_DATA_CHAMPION_RIBBON: - SET8(substruct3->championRibbon); - break; - case MON_DATA_WINNING_RIBBON: - SET8(substruct3->winningRibbon); - break; - case MON_DATA_VICTORY_RIBBON: - SET8(substruct3->victoryRibbon); - break; - case MON_DATA_ARTIST_RIBBON: - SET8(substruct3->artistRibbon); - break; - case MON_DATA_EFFORT_RIBBON: - SET8(substruct3->effortRibbon); - break; - case MON_DATA_MARINE_RIBBON: - SET8(substruct3->marineRibbon); - break; - case MON_DATA_LAND_RIBBON: - SET8(substruct3->landRibbon); - break; - case MON_DATA_SKY_RIBBON: - SET8(substruct3->skyRibbon); - break; - case MON_DATA_COUNTRY_RIBBON: - SET8(substruct3->countryRibbon); - break; - case MON_DATA_NATIONAL_RIBBON: - SET8(substruct3->nationalRibbon); - break; - case MON_DATA_EARTH_RIBBON: - SET8(substruct3->earthRibbon); - break; - case MON_DATA_WORLD_RIBBON: - SET8(substruct3->worldRibbon); - break; - case MON_DATA_UNUSED_RIBBONS: - SET8(substruct3->unusedRibbons); - break; - case MON_DATA_MODERN_FATEFUL_ENCOUNTER: - SET8(substruct3->modernFatefulEncounter); - break; - case MON_DATA_IVS: - { - u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - substruct3->hpIV = ivs & MAX_IV_MASK; - substruct3->attackIV = (ivs >> 5) & MAX_IV_MASK; - substruct3->defenseIV = (ivs >> 10) & MAX_IV_MASK; - substruct3->speedIV = (ivs >> 15) & MAX_IV_MASK; - substruct3->spAttackIV = (ivs >> 20) & MAX_IV_MASK; - substruct3->spDefenseIV = (ivs >> 25) & MAX_IV_MASK; - break; - } - default: - break; + switch (field) + { + case MON_DATA_PERSONALITY: + SET32(boxMon->personality); + break; + case MON_DATA_OT_ID: + SET32(boxMon->otId); + break; + case MON_DATA_NICKNAME: + { + s32 i; + for (i = 0; i < POKEMON_NAME_LENGTH; i++) + boxMon->nickname[i] = data[i]; + break; + } + case MON_DATA_LANGUAGE: + SET8(boxMon->language); + break; + case MON_DATA_SANITY_IS_BAD_EGG: + SET8(boxMon->isBadEgg); + break; + case MON_DATA_SANITY_HAS_SPECIES: + SET8(boxMon->hasSpecies); + break; + case MON_DATA_SANITY_IS_EGG: + SET8(boxMon->isEgg); + break; + case MON_DATA_OT_NAME: + { + s32 i; + for (i = 0; i < PLAYER_NAME_LENGTH; i++) + boxMon->otName[i] = data[i]; + break; + } + case MON_DATA_MARKINGS: + SET8(boxMon->markings); + break; + case MON_DATA_CHECKSUM: + SET16(boxMon->checksum); + break; + case MON_DATA_ENCRYPT_SEPARATOR: + SET16(boxMon->unknown); + break; + } } if (field > MON_DATA_ENCRYPT_SEPARATOR)