Decompile trainer hill

This commit is contained in:
DizzyEggg 2019-01-13 12:12:27 +01:00
parent 37d7348e01
commit 11a49a7f02
24 changed files with 991 additions and 2290 deletions

File diff suppressed because it is too large Load Diff

View File

@ -79,7 +79,7 @@ void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId);
u8 SetFacilityPtrsGetLevel(void);
u8 GetFrontierEnemyMonLevel(u8 lvlMode);
s32 GetHighestLevelInPlayerParty(void);
u8 sub_81660B8(u8 facilityClass);
u8 FacilityClassToGraphicsId(u8 facilityClass);
bool32 ValidateBattleTowerRecord(u8 recordId); // unused
void sub_8166188(void);

View File

@ -11,6 +11,7 @@ enum
bool8 ShowFieldMessage(const u8 *message);
bool8 sub_8098238(const u8 *message);
bool8 sub_80982B8(void);
bool8 ShowFieldAutoScrollMessage(const u8 *message);
void HideFieldMessageBox(void);
bool8 IsFieldMessageBoxHidden(void);

View File

@ -378,7 +378,8 @@ struct BattleFrontier
/*0xEE0*/ u8 field_EE0;
/*0xEE1*/ u8 field_EE1[2][PLAYER_NAME_LENGTH + 1];
/*0xEF1*/ u8 field_EF1[2][4];
/*0xEF9*/ u8 field_EF9;
/*0xEF9*/ u8 field_EF9_0:7;
/*0xEF9*/ u8 field_EF9_1:1;
/*0xEFA*/ u8 field_EFA;
/*0xEFB*/ u8 field_EFB;
/*0xEFC*/ struct FrontierMonData field_EFC[3];
@ -792,6 +793,21 @@ struct UnkSaveSubstruct_3b98
u8 trainerName[PLAYER_NAME_LENGTH + 1];
};
struct SaveTrainerHill
{
/*0x3D64*/ u32 field_3D64;
/*0x3D68*/ u32 field_3D68;
/*0x3D6C*/ u8 field_3D6C;
/*0x3D6D*/ u8 unused;
/*0x3D6E*/ u16 field_3D6E_0a:1; // 1
/*0x3D6E*/ u16 field_3D6E_0b:1; // 2
/*0x3D6E*/ u16 field_3D6E_0c:1; // 4
/*0x3D6E*/ u16 field_3D6E_0d:1; // 8
/*0x3D6E*/ u16 field_3D6E_0e:1; // x10
/*0x3D6E*/ u16 field_3D6E_0f:1; // x20
/*0x3D6E*/ u16 field_3D6E_1:2; // x40, x80 = xC0
};
struct SaveBlock1
{
/*0x00*/ struct Coords16 pos;
@ -869,13 +885,15 @@ struct SaveBlock1
/*0x31A8*/ u8 giftRibbons[52];
/*0x31DC*/ struct Roamer roamer;
/*0x31F8*/ struct EnigmaBerry enigmaBerry;
/*0x322C*/ u8 field_322C[1276];
/*0x322C*/ u8 field_322C[1260];
/*0x3718*/ u32 field_3718[4];
/*0x3728*/ struct RamScript ramScript;
/*0x3B14*/ struct RecordMixingGift recordMixingGift;
/*0x3B24*/ u8 seen2[DEX_FLAGS_NO];
/*0x3B58*/ LilycoveLady lilycoveLady;
/*0x3B98*/ struct UnkSaveSubstruct_3b98 unk_3B98[20];
/*0x3C88*/ u8 filler_3C88[0xE8];
/*0x3C88*/ u8 filler_3C88[0xDC];
/*0x3D64*/ struct SaveTrainerHill trainerHill;
/*0x3D70*/ struct WaldaPhrase waldaPhrase;
// sizeof: 0x3D88
};

View File

@ -61,6 +61,8 @@ void SetHBlankCallback(IntrCallback callback);
void SetVCountCallback(IntrCallback callback);
void SetSerialCallback(IntrCallback callback);
void InitFlashTimer(void);
void sub_80008DC(u32 *var);
void sub_80008E8(void);
void DoSoftReset(void);
void ClearPokemonCrySongs(void);
void RestoreSerialTimer3IntrHandlers(void);

View File

@ -451,8 +451,8 @@ void CreateMaleMon(struct Pokemon *mon, u16 species, u8 level);
void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32 ivs, u32 personality);
void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId);
void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 evSpread);
void sub_806819C(struct Pokemon *mon, struct BattleTowerPokemon *src);
void sub_8068338(struct Pokemon *mon, struct BattleTowerPokemon *src, bool8 lvl50);
void CreateBattleTowerMon(struct Pokemon *mon, struct BattleTowerPokemon *src);
void CreateBattleTowerMon2(struct Pokemon *mon, struct BattleTowerPokemon *src, bool8 lvl50);
void CreateApprenticeMon(struct Pokemon *mon, const struct Apprentice *src, u8 monId);
void CreateMonWithEVSpreadNatureOTID(struct Pokemon *mon, u16 species, u8 level, u8 nature, u8 fixedIV, u8 evSpread, u32 otId);
void sub_80686FC(struct Pokemon *mon, struct BattleTowerPokemon *dest);

View File

@ -292,6 +292,7 @@ SECTIONS {
asm/pokenav.o(.text);
src/pokenav_match_call.o(.text);
asm/pokenav.o(.text.after.match.call);
src/trainer_hill.o(.text);
src/rayquaza_scene.o(.text);
src/walda_phrase.o(.text);
src/contest_link_81D9DE4.o(.text);

View File

@ -1080,7 +1080,7 @@ void ResetApprenticeStruct(struct Apprentice *apprentice)
u8 i;
for (i = 0; i < 6; i++)
apprentice->easyChatWords[i] |= 0xFFFF;
apprentice->easyChatWords[i] = 0xFFFF;
apprentice->playerName[0] = EOS;
apprentice->id = 16;
@ -1094,7 +1094,7 @@ void ResetAllApprenticeData(void)
for (i = 0; i < 4; i++)
{
for (j = 0; j < 6; j++)
gSaveBlock2Ptr->apprentices[i].easyChatWords[j] |= 0xFFFF;
gSaveBlock2Ptr->apprentices[i].easyChatWords[j] = 0xFFFF;
gSaveBlock2Ptr->apprentices[i].id = 16;
gSaveBlock2Ptr->apprentices[i].playerName[0] = EOS;
gSaveBlock2Ptr->apprentices[i].lvlMode = 0;

View File

@ -1450,7 +1450,7 @@ void ClearBattleAnimationVars(void)
// Clear index array.
for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++)
sAnimSpriteIndexArray[i] |= 0xFFFF;
sAnimSpriteIndexArray[i] = 0xFFFF;
// Clear anim args.
for (i = 0; i < ANIM_ARGS_COUNT; i++)
@ -1511,7 +1511,7 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo
gAnimScriptCallback = RunAnimScriptCommand;
for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++)
sAnimSpriteIndexArray[i] |= 0xFFFF;
sAnimSpriteIndexArray[i] = 0xFFFF;
if (isMoveAnim)
{
@ -1572,7 +1572,7 @@ static void ClearSpriteIndex(u16 index)
{
if (sAnimSpriteIndexArray[i] == index)
{
sAnimSpriteIndexArray[i] |= 0xFFFF;
sAnimSpriteIndexArray[i] = 0xFFFF;
return;
}
}
@ -1779,7 +1779,7 @@ static void ScriptCmd_end(void)
{
FreeSpriteTilesByTag(gBattleAnimPicTable[sAnimSpriteIndexArray[i]].tag);
FreeSpritePaletteByTag(gBattleAnimPicTable[sAnimSpriteIndexArray[i]].tag);
sAnimSpriteIndexArray[i] |= 0xFFFF; // set terminator.
sAnimSpriteIndexArray[i] = 0xFFFF; // set terminator.
}
}

View File

@ -3548,7 +3548,7 @@ static void sub_8190400(u8 taskId)
SetVBlankCallback(VblankCb0_BattleDome);
sBattleDomeStruct = AllocZeroed(sizeof(*sBattleDomeStruct));
for (i = 0; i < DOME_TOURNAMENT_TRAINERS_COUNT; i++)
sBattleDomeStruct->arr[i] |= 0xFF;
sBattleDomeStruct->arr[i] = 0xFF;
LoadMonIconPalettes();
i = CreateTask(sub_8190CD4, 0);
gTasks[i].data[0] = 0;

View File

@ -198,9 +198,9 @@ static void sub_81A5E94(void)
gUnknown_03001288 = FALSE;
for (i = 0; i < 6; i++)
gSaveBlock2Ptr->frontier.field_E70[i].monId |= 0xFFFF;
gSaveBlock2Ptr->frontier.field_E70[i].monId = 0xFFFF;
for (i = 0; i < 3; i++)
gUnknown_03006298[i] |= 0xFFFF;
gUnknown_03006298[i] = 0xFFFF;
SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1);
gTrainerBattleOpponent_A = 0;

View File

@ -1446,7 +1446,7 @@ static void sub_81A84B4(void)
u8 i;
for (i = 0; i < 14; i++)
gSaveBlock2Ptr->frontier.field_CB4[i] |= 0xFFFF;
gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF;
}
static void sub_81A84EC(void)

View File

@ -1537,7 +1537,7 @@ void sub_81AA1D8(void)
u8 var0, var1;
for (i = 0; i < 8; i++)
gSaveBlock2Ptr->frontier.field_CB4[i] |= 0xFFFF;
gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF;
id = sub_81AA9E4();
sub_81AA33C(&var0, &var1);

View File

@ -1888,7 +1888,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount)
else if (trainerId == TRAINER_EREADER)
{
for (i = firstMonId; i < firstMonId + 3; i++)
sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]);
CreateBattleTowerMon(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]);
return;
}
else if (trainerId == TRAINER_FRONTIER_BRAIN)
@ -1904,7 +1904,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount)
if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j].species != 0
&& gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j].level <= level)
{
sub_8068338(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j], FALSE);
CreateBattleTowerMon2(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j], FALSE);
}
}
return;
@ -2075,7 +2075,7 @@ static void FillFactoryFrontierTrainerParty(u16 trainerId, u8 firstMonId)
else if (trainerId == TRAINER_EREADER)
{
for (i = firstMonId; i < firstMonId + 3; i++)
sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]);
CreateBattleTowerMon(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]);
return;
}
else if (trainerId == TRAINER_FRONTIER_BRAIN)
@ -2276,7 +2276,7 @@ void DoSpecialTrainerBattle(void)
case SPECIAL_BATTLE_EREADER:
ZeroEnemyPartyMons();
for (i = 0; i < 3; i++)
sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i]);
CreateBattleTowerMon(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i]);
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_EREADER_TRAINER;
gTrainerBattleOpponent_A = 0;
CreateTask(Task_StartBattleAfterTransition, 1);
@ -3258,7 +3258,7 @@ static void FillPartnerParty(u16 trainerId)
if (monData.nickname[0] == EXT_CTRL_CODE_BEGIN && monData.nickname[1] == EXT_CTRL_CODE_JPN)
trainerName[5] = EOS;
}
sub_8068338(&gPlayerParty[3 + i], &monData, TRUE);
CreateBattleTowerMon2(&gPlayerParty[3 + i], &monData, TRUE);
SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_NAME, trainerName);
j = IsFrontierTrainerFemale(trainerId + TRAINER_RECORD_MIXING_FRIEND);
SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j);
@ -3663,7 +3663,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount)
}
}
u8 sub_81660B8(u8 facilityClass)
u8 FacilityClassToGraphicsId(u8 facilityClass)
{
u8 trainerObjectGfxId;
u8 i;

View File

@ -1827,7 +1827,7 @@ void sub_81A3ACC(void)
s32 i;
for (i = 0; i < 20; i++)
gSaveBlock2Ptr->frontier.field_CB4[i] |= 0xFFFF;
gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF;
}
static void sub_81A3B00(void)

View File

@ -4524,7 +4524,7 @@ void sub_80115EC(s32 a0)
if ((a0 >> i) & 1)
{
gUnknown_03005000.unk_cea[i] = 0;
gUnknown_03005000.unk_cee[i] |= 0xFF;
gUnknown_03005000.unk_cee[i] = 0xFF;
}
}
}

View File

@ -1563,7 +1563,7 @@ static void InitPartyMenu(u8 a, u8 b, u8 c, u8 d, u8 e, TaskFunc task, MainCallb
for (i = 0; i <= 15; i++)
gUnknown_0203CEC4->data[i] = 0;
for (i = 0; i < 3; i++)
gUnknown_0203CEC4->unkC[i] |= 0xFF;
gUnknown_0203CEC4->unkC[i] = 0xFF;
if (d == 0)
gUnknown_0203CEC8.unk9 = 0;
@ -1851,10 +1851,10 @@ static void PartyMenuInitHelperStructs(u8 a)
gUnknown_0203CEDC[i].unk0 = &gUnknown_086156C4[1];
gUnknown_0203CEDC[i].unk4 = gUnknown_08615704[a][i];
gUnknown_0203CEDC[i].windowId = i;
gUnknown_0203CEDC[i].unk9 |= 0xFF;
gUnknown_0203CEDC[i].unkA |= 0xFF;
gUnknown_0203CEDC[i].unkB |= 0xFF;
gUnknown_0203CEDC[i].unkC |= 0xFF;
gUnknown_0203CEDC[i].unk9 = 0xFF;
gUnknown_0203CEDC[i].unkA = 0xFF;
gUnknown_0203CEDC[i].unkB = 0xFF;
gUnknown_0203CEDC[i].unkC = 0xFF;
}
gUnknown_0203CEDC[0].unk0 = &gUnknown_086156C4[0];
if (a == 3)

View File

@ -1264,7 +1264,7 @@ static void ResetPokedexView(struct PokedexView *pokedexView)
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
pokedexView->pokedexList[i].dexNum |= 0xFFFF;
pokedexView->pokedexList[i].dexNum = 0xFFFF;
pokedexView->pokedexList[i].seen = 0;
pokedexView->pokedexList[i].owned = 0;
}
@ -1281,7 +1281,7 @@ static void ResetPokedexView(struct PokedexView *pokedexView)
pokedexView->seenCount = 0;
pokedexView->ownCount = 0;
for (i = 0; i < 4; i++)
pokedexView->unk61E[i] |= 0xFFFF;
pokedexView->unk61E[i] = 0xFFFF;
pokedexView->unk628 = 0;
pokedexView->unk62A = 0;
pokedexView->unk62C = 0;
@ -2030,7 +2030,7 @@ void sub_80BC8D4(u8 dexMode, u8 sortMode)
for (i = sPokedexView->pokemonListCount; i < NATIONAL_DEX_COUNT; i++)
{
sPokedexView->pokedexList[i].dexNum |= 0xFFFF;
sPokedexView->pokedexList[i].dexNum = 0xFFFF;
sPokedexView->pokedexList[i].seen = FALSE;
sPokedexView->pokedexList[i].owned = FALSE;
}
@ -2437,7 +2437,7 @@ u8 sub_80BDA40(void)
if (sPokedexView->unk61E[i] != 0xFFFF)
{
FreeAndDestroyMonPicSprite(sPokedexView->unk61E[i]);
sPokedexView->unk61E[i] |= 0xFFFF;
sPokedexView->unk61E[i] = 0xFFFF;
}
}
return FALSE;

View File

@ -2745,7 +2745,7 @@ void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedI
CalculateMonStats(mon);
}
void sub_806819C(struct Pokemon *mon, struct BattleTowerPokemon *src)
void CreateBattleTowerMon(struct Pokemon *mon, struct BattleTowerPokemon *src)
{
s32 i;
u8 nickname[30];
@ -2799,7 +2799,7 @@ void sub_806819C(struct Pokemon *mon, struct BattleTowerPokemon *src)
CalculateMonStats(mon);
}
void sub_8068338(struct Pokemon *mon, struct BattleTowerPokemon *src, bool8 lvl50)
void CreateBattleTowerMon2(struct Pokemon *mon, struct BattleTowerPokemon *src, bool8 lvl50)
{
s32 i;
u8 nickname[30];

View File

@ -124,7 +124,7 @@ void sub_8184DA4(u8 arg0)
{
for (j = 0; j < BATTLER_RECORD_SIZE; j++)
{
sBattleRecords[i][j] |= 0xFF;
sBattleRecords[i][j] = 0xFF;
}
sBattleFlags = gBattleTypeFlags;
sAI_Scripts = gBattleResources->ai->aiFlags;
@ -206,7 +206,7 @@ void RecordedBattle_ClearBattlerAction(u8 battlerId, u8 bytesToClear)
for (i = 0; i < bytesToClear; i++)
{
sRecordedBytesNo[battlerId]--;
sBattleRecords[battlerId][sRecordedBytesNo[battlerId]] |= 0xFF;
sBattleRecords[battlerId][sRecordedBytesNo[battlerId]] = 0xFF;
if (sRecordedBytesNo[battlerId] == 0)
break;
}

View File

@ -82,7 +82,7 @@ bool32 sub_8034C54(u32 count)
for (i = 0; i < count; i++)
{
gUnknown_02022E10->array[i].isActive = FALSE;
gUnknown_02022E10->array[i].firstOamId |= 0xFF;
gUnknown_02022E10->array[i].firstOamId = 0xFF;
}
return TRUE;

View File

@ -1407,7 +1407,7 @@ static void sub_80E2578(void)
for (i = 0; i < ARRAY_COUNT(gUnknown_03001124); i++)
{
gUnknown_03001124[i] |= 0xFF;
gUnknown_03001124[i] = 0xFF;
}
GetFontAttribute(1, FONTATTR_MAX_LETTER_WIDTH);

927
src/trainer_hill.c Normal file
View File

@ -0,0 +1,927 @@
#include "global.h"
#include "alloc.h"
#include "battle.h"
#include "battle_tower.h"
#include "battle_setup.h"
#include "event_data.h"
#include "fieldmap.h"
#include "field_message_box.h"
#include "international_string_util.h"
#include "item.h"
#include "main.h"
#include "menu.h"
#include "overworld.h"
#include "palette.h"
#include "pokemon.h"
#include "script.h"
#include "string_util.h"
#include "text.h"
#include "window.h"
#include "util.h"
#include "constants/event_object_movement_constants.h"
#include "constants/maps.h"
#define HILL_TRAINER_NAME_LENGTH 11
#define HILL_MAX_TIME 215999 // 60 * 60 * 60 - 1
struct TrHillStruct1
{
u8 name[2][HILL_TRAINER_NAME_LENGTH];
u8 facilityClass[2];
};
struct TrainerHillTrainer
{
u8 name[HILL_TRAINER_NAME_LENGTH];
u8 facilityClass;
u32 field_18;
u16 speechBefore[6];
u16 speechWin[6];
u16 speechLose[6];
u16 speechAfter[6];
struct BattleTowerPokemon mons[PARTY_SIZE];
};
struct TrHillStruct5
{
u8 unk0;
u8 unk1;
struct TrainerHillTrainer trainers[2];
u8 data[0x100];
u16 unk3A0[2];
u8 data2[0x20 - 4];
u8 coords[2]; // x first 4 bits, y last 4 bites
u8 direction; // array of 4 bites for each trainer
u8 range; // array of 4 bites for each trainer
};
struct TrHillStruct4
{
u8 unkField_0;
u8 unkField_1;
u8 unkField_2;
u8 unkField_3;
u8 unkField_4;
u8 unkField_5;
u8 unkField_6;
struct TrHillStruct5 unk0[4];
};
struct TrHillStruct2
{
u8 layoutId;
struct TrHillStruct4 unk4;
};
extern struct TrHillStruct2 *gUnknown_0203CF54;
extern struct TrHillStruct1 *gUnknown_0203CF58;
// This file's functions.
void sub_81D56B0(void);
void sub_81D5710(void);
bool32 sub_81D5F48(void);
void nullsub_2(void);
void sub_81D5DF4(u32 *dst, u32 val);
bool32 sub_81D3B34(void);
u16 sub_81D6640(void);
u32 sub_81D5DF0(u32 *src);
u8 GetCurrentTrainerHillMapId(void);
u8 sub_81D6490(void);
void sub_81D642C(struct Pokemon *mon, u8 level);
bool32 sub_81D6534(void);
// const data
extern void (* const gUnknown_0862A618[])(void);
extern const struct TrHillStruct4 *const gUnknown_0862A5F8[];
extern const u16 gUnknown_0862A5D4[];
extern const u8 gText_TimeBoard[];
extern const u8 gText_TimeCleared[];
extern const u8 gText_XMinYDotZSec[];
extern const u8 gUnknown_0862A5F4[];
extern const u8 *const gUnknown_0862A660[];
extern const struct EventObjectTemplate gUnknown_0862A670;
extern const u32 gUnknown_0862A688[4];
extern const u8 gUnknown_0862A698[][3];
extern const u16 *const *const gUnknown_0862A5CC[];
struct
{
u8 trainerClass;
u8 musicId;
} extern const gUnknown_0862A3B4[0x36];
extern const u8 EventScript_2C83F0[];
void sp194_trainer_tower(void)
{
sub_81D56B0();
gUnknown_0862A618[gSpecialVar_0x8004]();
sub_81D5710();
}
void sub_81D54BC(void)
{
s32 i;
gSaveBlock2Ptr->frontier.field_EF9_1 = 0;
gSaveBlock2Ptr->frontier.field_EF9_0 = 0;
gSaveBlock1Ptr->trainerHill.field_3D68 = 0;
for (i = 0; i < 4; i++)
sub_81D5DF4(&gSaveBlock1Ptr->field_3718[i], HILL_MAX_TIME);
}
u8 sub_81D5520(void)
{
return gMapHeader.mapLayoutId - 159;
}
u8 GetTrainerHillOpponentClass(u16 trainerId)
{
u8 id = trainerId - 1;
return gFacilityClassToTrainerClass[gUnknown_0203CF58->facilityClass[id]];
}
void GetTrainerHillTrainerName(u8 *dst, u16 trainerId)
{
s32 i;
u8 id = trainerId - 1;
for (i = 0; i < HILL_TRAINER_NAME_LENGTH; i++)
dst[i] = gUnknown_0203CF58->name[id][i];
}
u8 GetTrainerHillTrainerFrontSpriteId(u16 trainerId)
{
u8 id, facilityClass;
sub_81D56B0();
id = trainerId - 1;
facilityClass = gUnknown_0203CF54->unk4.unk0[gUnknown_0203CF54->layoutId].trainers[id].facilityClass;
sub_81D5710();
return gFacilityClassToPicIndex[facilityClass];
}
void sub_81D55D0(void)
{
s32 i, j;
sub_81D56B0();
gUnknown_0203CF58 = AllocZeroed(sizeof(*gUnknown_0203CF58));
for (i = 0; i < 2; i++)
{
for (j = 0; j < HILL_TRAINER_NAME_LENGTH; j++)
{
gUnknown_0203CF58->name[i][j] = gUnknown_0203CF54->unk4.unk0[gUnknown_0203CF54->layoutId].trainers[i].name[j];
}
gUnknown_0203CF58->facilityClass[i] = gUnknown_0203CF54->unk4.unk0[gUnknown_0203CF54->layoutId].trainers[i].facilityClass;
}
sub_80008DC(&gSaveBlock1Ptr->trainerHill.field_3D64);
sub_81D5710();
}
void sub_81D5694(void)
{
if (gUnknown_0203CF58 != NULL)
FREE_AND_SET_NULL(gUnknown_0203CF58);
}
void sub_81D56B0(void)
{
if (gUnknown_0203CF54 == NULL)
{
gUnknown_0203CF54 = AllocZeroed(sizeof(*gUnknown_0203CF54));
gUnknown_0203CF54->layoutId = gMapHeader.mapLayoutId - 159;
CpuCopy32(gUnknown_0862A5F8[gSaveBlock1Ptr->trainerHill.field_3D6E_1], &gUnknown_0203CF54->unk4, sizeof(gUnknown_0203CF54->unk4));
nullsub_2();
}
}
void sub_81D5710(void)
{
if (gUnknown_0203CF54 != NULL)
FREE_AND_SET_NULL(gUnknown_0203CF54);
}
void CopyTrainerHillTrainerText(u8 which, u16 trainerId)
{
u8 id, layoutId;
sub_81D56B0();
layoutId = sub_81D5520();
id = trainerId - 1;
switch (which)
{
case 2:
FrontierSpeechToString(gUnknown_0203CF54->unk4.unk0[layoutId].trainers[id].speechBefore);
break;
case 3:
FrontierSpeechToString(gUnknown_0203CF54->unk4.unk0[layoutId].trainers[id].speechWin);
break;
case 4:
FrontierSpeechToString(gUnknown_0203CF54->unk4.unk0[layoutId].trainers[id].speechLose);
break;
case 5:
FrontierSpeechToString(gUnknown_0203CF54->unk4.unk0[layoutId].trainers[id].speechAfter);
break;
}
sub_81D5710();
}
void sub_81D581C(void)
{
nullsub_2();
if (!sub_81D3B34())
gSaveBlock1Ptr->trainerHill.field_3D6E_0f = 1;
else
gSaveBlock1Ptr->trainerHill.field_3D6E_0f = 0;
gSaveBlock1Ptr->trainerHill.field_3D6C = 0;
sub_80008DC(&gSaveBlock1Ptr->trainerHill.field_3D64);
gSaveBlock1Ptr->trainerHill.field_3D64 = 0;
gSaveBlock1Ptr->trainerHill.field_3D6E_0c = 0;
gSaveBlock1Ptr->trainerHill.field_3D6E_0b = 0;
gSaveBlock1Ptr->trainerHill.field_3D6E_0e = 0;
gSaveBlock2Ptr->frontier.field_EE0 = 0;
gBattleOutcome = 0;
gSaveBlock1Ptr->trainerHill.field_3D6E_0a = 0;
}
void sub_81D58D8(void)
{
sub_80008E8();
gSpecialVar_Result = 0;
if (gSaveBlock1Ptr->trainerHill.field_3D6E_0c)
gSpecialVar_Result++;
if (gSaveBlock1Ptr->trainerHill.field_3D6E_0a && gSaveBlock1Ptr->trainerHill.field_3D6E_0b)
gSpecialVar_Result++;
gSaveBlock1Ptr->trainerHill.field_3D6E_0c = 1;
}
void sub_81D5924(void)
{
u16 itemId = sub_81D6640();
if (gUnknown_0203CF54->unk4.unkField_2 != 4 || gSaveBlock1Ptr->trainerHill.field_3D6E_0a)
{
gSpecialVar_Result = 2;
}
else if (AddBagItem(itemId, 1) == TRUE)
{
CopyItemName(itemId, gStringVar2);
gSaveBlock1Ptr->trainerHill.field_3D6E_0a = 1;
gSaveBlock2Ptr->frontier.field_EF9_0 = 0;
gSpecialVar_Result = 0;
}
else
{
gSpecialVar_Result = 1;
}
}
void sub_81D59D0(void)
{
if (gSaveBlock1Ptr->trainerHill.field_3D6E_0b)
{
gSpecialVar_Result = 2;
}
else if (sub_81D5DF0(&gSaveBlock1Ptr->trainerHill.field_3D68) > gSaveBlock1Ptr->trainerHill.field_3D64)
{
sub_81D5DF4(&gSaveBlock1Ptr->trainerHill.field_3D68, gSaveBlock1Ptr->trainerHill.field_3D64);
gSaveBlock1Ptr->field_3718[gSaveBlock1Ptr->trainerHill.field_3D6E_1] = gSaveBlock1Ptr->trainerHill.field_3D68;
gSpecialVar_Result = 0;
}
else
{
gSpecialVar_Result = 1;
}
gSaveBlock1Ptr->trainerHill.field_3D6E_0b = 1;
}
void sub_81D5A70(void)
{
if (!gSaveBlock1Ptr->trainerHill.field_3D6E_0c)
{
if (gSaveBlock1Ptr->trainerHill.field_3D64 >= HILL_MAX_TIME)
gSaveBlock1Ptr->trainerHill.field_3D64 = HILL_MAX_TIME;
else
sub_80008DC(&gSaveBlock1Ptr->trainerHill.field_3D64);
}
}
void sub_81D5AB4(void)
{
gSaveBlock1Ptr->trainerHill.field_3D6E_0d = 1;
}
void sub_81D5AD0(void)
{
if (gSaveBlock1Ptr->trainerHill.field_3D6E_0d)
{
gSaveBlock1Ptr->trainerHill.field_3D6E_0d = 0;
gSpecialVar_Result = 0;
}
else if (gSaveBlock1Ptr->trainerHill.field_3D6E_0e)
{
gSaveBlock1Ptr->trainerHill.field_3D6E_0e = 0;
gSpecialVar_Result = 1;
}
else
{
gSpecialVar_Result = 2;
}
}
void sub_81D5B2C(void)
{
s32 total, minutes, secondsWhole, secondsFraction;
total = gSaveBlock1Ptr->trainerHill.field_3D64;
if (total >= HILL_MAX_TIME)
total = HILL_MAX_TIME;
minutes = total / (60 * 60);
total %= (60 * 60);
secondsWhole = total / 60;
total %= 60;
secondsFraction = (total * 168) / 100;
ConvertIntToDecimalStringN(gStringVar1, minutes, STR_CONV_MODE_RIGHT_ALIGN, 2);
ConvertIntToDecimalStringN(gStringVar2, secondsWhole, STR_CONV_MODE_RIGHT_ALIGN, 2);
ConvertIntToDecimalStringN(gStringVar3, secondsFraction, STR_CONV_MODE_LEADING_ZEROS, 2);
}
void sub_81D5BBC(void)
{
sub_81D56B0();
if (gUnknown_0203CF54->unk4.unkField_2 != 4)
{
ConvertIntToDecimalStringN(gStringVar1, gUnknown_0203CF54->unk4.unkField_2, STR_CONV_MODE_LEFT_ALIGN, 1);
gSpecialVar_Result = 0;
}
else
{
gSpecialVar_Result = 1;
}
sub_81D5710();
}
void sub_81D5C00(void)
{
sub_81D56B0();
gSpecialVar_Result = 0;
sub_81D5710();
}
bool8 sub_81D5C18(void)
{
if (VarGet(VAR_0x40D6) == 0)
return FALSE;
else if (gSaveBlock1Ptr->trainerHill.field_3D6E_0c)
return FALSE;
else if (GetCurrentTrainerHillMapId() != 0)
return TRUE;
else
return FALSE;
}
void sub_81D5C5C(void)
{
if (!sub_81D5C18())
gSpecialVar_Result = 0;
else
gSpecialVar_Result = 1;
}
void nullsub_129(void)
{
}
void nullsub_2(void)
{
}
void PrintOnTrainerHillRecordsWindow(void)
{
s32 i, x, y;
u32 total, minutes, secondsWhole, secondsFraction;
sub_81D56B0();
FillWindowPixelBuffer(0, 0);
x = GetStringCenterAlignXOffset(1, gText_TimeBoard, 0xD0);
AddTextPrinterParameterized3(0, 1, x, 2, gUnknown_0862A5F4, TEXT_SPEED_FF, gText_TimeBoard);
y = 18;
for (i = 0; i < 4; i++)
{
AddTextPrinterParameterized3(0, 1, 0, y, gUnknown_0862A5F4, TEXT_SPEED_FF, gUnknown_0862A660[i]);
y += 15;
total = sub_81D5DF0(&gSaveBlock1Ptr->field_3718[i]);
minutes = total / (60 * 60);
total %= (60 * 60);
ConvertIntToDecimalStringN(gStringVar1, minutes, STR_CONV_MODE_RIGHT_ALIGN, 2);
secondsWhole = total / 60;
total %= 60;
ConvertIntToDecimalStringN(gStringVar2, secondsWhole, STR_CONV_MODE_RIGHT_ALIGN, 2);
secondsFraction = (total * 168) / 100;
ConvertIntToDecimalStringN(gStringVar3, secondsFraction, STR_CONV_MODE_LEADING_ZEROS, 2);
StringExpandPlaceholders(StringCopy(gStringVar4, gText_TimeCleared), gText_XMinYDotZSec);
x = GetStringRightAlignXOffset(1, gStringVar4, 0xD0);
AddTextPrinterParameterized3(0, 1, x, y, gUnknown_0862A5F4, TEXT_SPEED_FF, gStringVar4);
y += 17;
}
PutWindowTilemap(0);
CopyWindowToVram(0, 3);
sub_81D5710();
}
// In fire red the counter had to be xored by the encryption key in Sav2.
u32 sub_81D5DF0(u32 *src)
{
return *src;
}
void sub_81D5DF4(u32 *dst, u32 val)
{
*dst = val;
}
void sub_81D5DF8(void)
{
u8 i, layoutId;
struct EventObjectTemplate *eventTemplates = gSaveBlock1Ptr->eventObjectTemplates;
if (!sub_81D5F48())
return;
sub_81D56B0();
for (i = 0; i < 2; i++)
gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF;
CpuFill32(0, gSaveBlock1Ptr->eventObjectTemplates, sizeof(gSaveBlock1Ptr->eventObjectTemplates));
layoutId = sub_81D5520();
for (i = 0; i < 2; i++)
{
u8 bits;
eventTemplates[i] = gUnknown_0862A670;
eventTemplates[i].localId = i + 1;
eventTemplates[i].graphicsId = FacilityClassToGraphicsId(gUnknown_0203CF54->unk4.unk0[layoutId].trainers[i].facilityClass);
eventTemplates[i].x = gUnknown_0203CF54->unk4.unk0[layoutId].coords[i] & 0xF;
eventTemplates[i].y = ((gUnknown_0203CF54->unk4.unk0[layoutId].coords[i] >> 4) & 0xF) + 5;
bits = i << 2;
eventTemplates[i].movementType = ((gUnknown_0203CF54->unk4.unk0[layoutId].direction >> bits) & 0xF) + MOVEMENT_TYPE_FACE_UP;
eventTemplates[i].trainerRange_berryTreeId = (gUnknown_0203CF54->unk4.unk0[layoutId].range >> bits) & 0xF;
eventTemplates[i].script = EventScript_2C83F0;
gSaveBlock2Ptr->frontier.field_CB4[i] = i + 1;
}
sub_81D5710();
}
bool32 sub_81D5F48(void)
{
sub_81D56B0();
sub_81D5710();
return TRUE;
}
// Functionally equivalent.
#ifdef NONMATCHING
u32 sub_81D5F58(u8 layoutId, u32 bit, u32 arg2, u32 arg3)
{
u32 var0, var1, var2, var3;
var0 = (gUnknown_0203CF54->unk4.unk0[layoutId].unk3A0[arg2] >> (15 - bit)) & 1;
var1 = gUnknown_0203CF54->unk4.unk0[layoutId].data[arg2 * arg3 + bit];
var3 = 0x200;
var2 = 0x3000;
return ((var0 << 10) | var2) | (var1 | var3);
}
#else
NAKED
u32 sub_81D5F58(u8 layoutId, u32 bit, u32 arg2, u32 arg3)
{
asm_unified("\n\
push {r4,r5,lr}\n\
lsls r0, 24\n\
lsrs r0, 24\n\
ldr r4, =gUnknown_0203CF54\n\
ldr r4, [r4]\n\
mov r12, r4\n\
lsls r4, r2, 1\n\
lsls r5, r0, 4\n\
subs r5, r0\n\
lsls r5, 3\n\
subs r5, r0\n\
lsls r5, 3\n\
adds r4, r5\n\
movs r0, 0xE8\n\
lsls r0, 2\n\
add r0, r12\n\
adds r0, r4\n\
ldrh r0, [r0]\n\
movs r4, 0xF\n\
subs r4, r1\n\
asrs r0, r4\n\
movs r4, 0x1\n\
ands r0, r4\n\
muls r2, r3\n\
adds r2, r1\n\
adds r2, r5\n\
movs r1, 0xA8\n\
lsls r1, 2\n\
add r1, r12\n\
adds r1, r2\n\
ldrb r1, [r1]\n\
movs r2, 0x80\n\
lsls r2, 2\n\
adds r3, r2, 0\n\
movs r2, 0xC0\n\
lsls r2, 6\n\
lsls r0, 10\n\
orrs r0, r2\n\
orrs r1, r3\n\
orrs r0, r1\n\
pop {r4,r5}\n\
pop {r1}\n\
bx r1\n\
.pool");
}
#endif // NONMATCHING
void sub_81D5FB4(u16 *mapArg)
{
s32 i, j;
u16 *src, *dst;
u8 layoutId = GetCurrentTrainerHillMapId();
if (layoutId == 6)
{
InitMapFromSavedGame();
return;
}
sub_81D56B0();
if (layoutId == 5)
{
InitMapFromSavedGame();
sub_81D5710();
return;
}
layoutId = sub_81D5520();
src = gMapHeader.mapLayout->map;
gBackupMapLayout.map = mapArg;
gBackupMapLayout.width = 31;
gBackupMapLayout.height = 35;
dst = mapArg + 224;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 16; j++)
dst[j] = src[j];
dst += 31;
src += 16;
}
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
dst[j] = sub_81D5F58(layoutId, j, i, 0x10);
dst += 31;
}
mapheader_run_script_with_tag_x1();
sub_81D5710();
}
bool32 InTrainerHill(void)
{
bool32 ret;
if (gMapHeader.mapLayoutId == 0x19F
|| gMapHeader.mapLayoutId == 0x1A0
|| gMapHeader.mapLayoutId == 0x1A1
|| gMapHeader.mapLayoutId == 0x1A2)
ret = TRUE;
else
ret = FALSE;
return ret;
}
u8 GetCurrentTrainerHillMapId(void)
{
u8 ret;
if (gMapHeader.mapLayoutId == 0x19F)
ret = 1;
else if (gMapHeader.mapLayoutId == 0x1A0)
ret = 2;
else if (gMapHeader.mapLayoutId == 0x1A1)
ret = 3;
else if (gMapHeader.mapLayoutId == 0x1A2)
ret = 4;
else if (gMapHeader.mapLayoutId == 0x1A3)
ret = 5;
else if (gMapHeader.mapLayoutId == 0x19E)
ret = 6;
else
ret = 0;
return ret;
}
bool32 sub_81D6100(void)
{
bool32 ret;
if (gMapHeader.mapLayoutId == 0x1A3)
ret = TRUE;
else
ret = FALSE;
return ret;
}
const struct WarpEvent* sub_81D6120(void)
{
const struct MapHeader *header = Overworld_GetMapHeaderByGroupAndId(MAP_GROUP(TRAINER_HILL_4F), MAP_NUM(TRAINER_HILL_4F));
return &header->events->warps[1];
}
const struct WarpEvent* sub_81D6134(u8 warpEventId)
{
u8 id;
const struct MapHeader *header;
if (warpEventId == 1)
return &gMapHeader.events->warps[1];
id = sub_81D6490();
if ((u8)(id - 1) >= 4)
id = 4;
header = Overworld_GetMapHeaderByGroupAndId(MAP_GROUP(TRAINER_HILL_4F), gUnknown_0862A688[id - 1]);
return &header->events->warps[0];
}
u16 sub_81D6180(u8 localId)
{
return gSaveBlock2Ptr->frontier.field_CB4[localId - 1];
}
bool8 GetTrainerHillTrainerFlag(u8 eventObjectId)
{
u32 layoutId = sub_81D5520() * 2;
u8 bitId = gEventObjects[eventObjectId].localId - 1 + layoutId;
return gSaveBlock2Ptr->frontier.field_EE0 & gBitTable[bitId];
}
void sub_81D61E8(void)
{
u8 i;
u8 layoutId = sub_81D5520() * 2;
for (i = 0; i < 2; i++)
{
if (gSaveBlock2Ptr->frontier.field_CB4[i] == gTrainerBattleOpponent_A)
{
gSaveBlock2Ptr->frontier.field_EE0 |= gBitTable[layoutId + i];
break;
}
}
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
for (i = 0; i < 2; i++)
{
if (gSaveBlock2Ptr->frontier.field_CB4[i] == gTrainerBattleOpponent_B)
{
gSaveBlock2Ptr->frontier.field_EE0 |= gBitTable[layoutId + i];
break;
}
}
}
}
const u8 *sub_81D62AC(void)
{
return EventScript_2C83F0;
}
void sub_81D62B4(void)
{
CopyTrainerHillTrainerText(5, gSpecialVar_LastTalked);
sub_80982B8();
}
void sub_81D62CC(u16 trainerId, u8 firstMonId)
{
u8 trId, level;
s32 i, layoutId, arrId;
if ((u16)(trainerId - 1) > 1)
return;
trId = trainerId - 1;
sub_81D56B0();
level = GetHighestLevelInPlayerParty();
layoutId = sub_81D5520();
for (i = firstMonId, arrId = 0; i < firstMonId + 3; i++, arrId++)
{
u8 id = gUnknown_0862A698[trId][arrId];
struct Pokemon *mon = &gEnemyParty[i];
CreateBattleTowerMon(mon, &gUnknown_0203CF54->unk4.unk0[layoutId].trainers[trId].mons[id]);
sub_81D642C(mon, level);
}
sub_81D5710();
}
void sub_81D6384(void)
{
ZeroEnemyPartyMons();
sub_81D62CC(gTrainerBattleOpponent_A, 0);
}
void sub_81D639C(void)
{
ZeroEnemyPartyMons();
sub_81D62CC(gTrainerBattleOpponent_A, 0);
sub_81D62CC(gTrainerBattleOpponent_B, 3);
}
// This function is unused, but my best guess is
// it was supposed to return AI scripts for trainer
// hill trainers.
u32 sub_81D63C4(void)
{
return 7;
}
u8 sub_81D63C8(u16 trainerId)
{
s32 i;
u8 trId, facilityClass;
sub_81D56B0();
trId = trainerId - 1;
facilityClass = gUnknown_0203CF54->unk4.unk0[gUnknown_0203CF54->layoutId].trainers[trId].facilityClass;
sub_81D5710();
for (i = 0; i < ARRAY_COUNT(gUnknown_0862A3B4); i++)
{
if (gUnknown_0862A3B4[i].trainerClass == gFacilityClassToTrainerClass[facilityClass])
return gUnknown_0862A3B4[i].musicId;
}
return 0;
}
void sub_81D642C(struct Pokemon *mon, u8 level)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u32 exp = gExperienceTables[gBaseStats[species].growthRate][level];
SetMonData(mon, MON_DATA_EXP, &exp);
SetMonData(mon, MON_DATA_LEVEL, &level);
CalculateMonStats(mon);
}
u8 sub_81D6490(void)
{
u8 ret;
sub_81D56B0();
ret = gUnknown_0203CF54->unk4.unkField_2;
sub_81D5710();
return ret;
}
void sub_81D64AC(void)
{
gSaveBlock2Ptr->frontier.field_EE0 = 0xFF;
}
void sub_81D64C0(void)
{
if (sub_81D6534() == TRUE)
LoadPalette(gUnknown_0862A5D4, 0x70, 0x20);
}
void sub_81D64DC(void)
{
gSpecialVar_Result = gSaveBlock2Ptr->frontier.field_EF9_1;
}
void sub_81D64FC(void)
{
gSaveBlock2Ptr->frontier.field_EF9_1 = 1;
}
void sub_81D6518(void)
{
gSaveBlock2Ptr->frontier.field_EF9_1 = 0;
}
bool32 sub_81D6534(void)
{
if (!sub_81D5C18() || GetCurrentTrainerHillMapId() == 6)
return FALSE;
sub_81D5C00();
if (gSpecialVar_Result == 0)
return FALSE;
else
return TRUE;
}
void sub_81D6568(void)
{
if (gSaveBlock1Ptr->trainerHill.field_3D6E_0d)
gSpecialVar_Result = 0;
else
gSpecialVar_Result = 1;
}
void sub_81D65A0(void)
{
gSaveBlock1Ptr->trainerHill.field_3D6E_1 = gSpecialVar_0x8005;
gSaveBlock1Ptr->trainerHill.field_3D68 = gSaveBlock1Ptr->field_3718[gSpecialVar_0x8005];
}
u8 sub_81D65E8(u8 arg0)
{
u8 var, i, modBy;
var = 0;
for (i = 0; i < 4; i++)
{
var ^= gUnknown_0203CF54->unk4.unk0[i].unk0 & 0x1F;
var ^= gUnknown_0203CF54->unk4.unk0[i].unk1 & 0x1F;
}
if (arg0)
modBy = 10;
else
modBy = 5;
var %= modBy;
return var;
}
u16 sub_81D6640(void)
{
u8 i;
const u16 *ptr;
s32 var = 0, var2, minutes, id;
for (i = 0; i < 4; i++)
{
var += gUnknown_0203CF54->unk4.unk0[i].unk0;
var += gUnknown_0203CF54->unk4.unk0[i].unk1;
}
var2 = var / 256;
var2 %= 2;
if (FlagGet(FLAG_SYS_GAME_CLEAR) && gUnknown_0203CF54->unk4.unkField_0 == 8)
i = sub_81D65E8(1);
else
i = sub_81D65E8(0);
if (gSaveBlock1Ptr->trainerHill.field_3D6E_1 == 3)
i = (i + 1) % 10;
ptr = gUnknown_0862A5CC[var2][i];
minutes = (signed)(gSaveBlock1Ptr->trainerHill.field_3D64) / (60 * 60);
if (minutes < 12)
id = 0;
else if (minutes < 13)
id = 1;
else if (minutes < 14)
id = 2;
else if (minutes < 16)
id = 3;
else if (minutes < 18)
id = 4;
else
id = 5;
return ptr[id];
}

View File

@ -109,7 +109,7 @@ static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8
{
if (paletteTag == 0xFFFF)
{
sCreatingSpriteTemplate.paletteTag |= 0xFFFF;
sCreatingSpriteTemplate.paletteTag = 0xFFFF;
LoadCompressedPalette(GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x100 + paletteSlot * 0x10, 0x20);
}
else
@ -122,7 +122,7 @@ static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8
{
if (paletteTag == 0xFFFF)
{
sCreatingSpriteTemplate.paletteTag |= 0xFFFF;
sCreatingSpriteTemplate.paletteTag = 0xFFFF;
LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, 0x100 + paletteSlot * 0x10, 0x20);
}
else