Merge branch 'master' of github.com:pret/pokeemerald into dump_maps

This commit is contained in:
Diegoisawesome
2017-10-27 02:02:36 -05:00
234 changed files with 23165 additions and 36367 deletions

View File

@@ -205,9 +205,6 @@ extern const u8 BattleScript_ActionSwitch[];
extern const u8 BattleScript_PrintFailedToRunString[];
// functions
extern void HandleLinkBattleSetup(void); // rom_3
extern void SetUpBattleVarsAndBirchZigzagoon(void); // rom_3
extern void sub_8032768(void); // rom_3
extern void dp12_8087EA4(void);
extern void sub_80356D0(void);
extern void GetFrontierTrainerName(u8* dst, u16 trainerId); // battle tower
@@ -4075,7 +4072,7 @@ static void HandleTurnActionSelectionState(void)
if (gBattleMons[GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON)].status2 & STATUS2_MULTIPLETURNS
|| gBattleMons[GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON)].status2 & STATUS2_RECHARGE)
{
Emit_x32(0);
EmitCmd50(0);
MarkBufferBankForExecution(gActiveBank);
return;
}
@@ -4103,7 +4100,7 @@ static void HandleTurnActionSelectionState(void)
{
RecordedBattle_ClearBankAction(GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON), 3);
}
Emit_x32(0);
EmitCmd50(0);
MarkBufferBankForExecution(gActiveBank);
return;
}

View File

@@ -39,7 +39,7 @@ static bool8 ShouldSwitchIfPerishSong(void)
&& gDisableStructs[gActiveBank].perishSong1 == 0)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
EmitCmd33(1, 2, 0);
return TRUE;
}
@@ -121,7 +121,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
{
// we found a mon
*(gBattleStruct->field_294 + gActiveBank) = i;
EmitCmd_x21(1, 2, 0);
EmitCmd33(1, 2, 0);
return TRUE;
}
}
@@ -221,7 +221,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
{
// we found a mon
*(gBattleStruct->field_294 + gActiveBank) = i;
EmitCmd_x21(1, 2, 0);
EmitCmd33(1, 2, 0);
return TRUE;
}
}
@@ -241,13 +241,13 @@ static bool8 ShouldSwitchIfNaturalCure(void)
if ((gUnknown_02024250[gActiveBank] == 0 || gUnknown_02024250[gActiveBank] == 0xFFFF) && Random() & 1)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
EmitCmd33(1, 2, 0);
return TRUE;
}
else if (gBattleMoves[gUnknown_02024250[gActiveBank]].power == 0 && Random() & 1)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
EmitCmd33(1, 2, 0);
return TRUE;
}
@@ -258,7 +258,7 @@ static bool8 ShouldSwitchIfNaturalCure(void)
if (Random() & 1)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
EmitCmd33(1, 2, 0);
return TRUE;
}
@@ -426,7 +426,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE && Random() % moduloPercent == 0)
{
*(gBattleStruct->field_294 + gActiveBank) = i;
EmitCmd_x21(1, 2, 0);
EmitCmd33(1, 2, 0);
return TRUE;
}
}
@@ -611,7 +611,7 @@ void AI_TrySwitchOrUseItem(void)
}
}
EmitCmd_x21(1, 0, (gActiveBank ^ BIT_SIDE) << 8);
EmitCmd33(1, 0, (gActiveBank ^ BIT_SIDE) << 8);
}
#define TYPE_FORESIGHT 0xFE
@@ -940,7 +940,7 @@ static bool8 ShouldUseItem(void)
if (shouldUse)
{
EmitCmd_x21(1, 1, 0);
EmitCmd33(1, 1, 0);
*(gBattleStruct->field_C0 + (gActiveBank / 2) * 2) = item;
gBattleResources->battleHistory->trainerItems[i] = 0;
return shouldUse;

1850
src/battle_anim.c Normal file

File diff suppressed because it is too large Load Diff

1551
src/battle_controllers.c Normal file

File diff suppressed because it is too large Load Diff

2632
src/battle_interface.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -349,7 +349,7 @@ static void atk51_switch_handle_order(void);
static void atk52_switch_in_effects(void);
static void atk53_trainer_slide(void);
static void atk54_effectiveness_sound(void);
static void atk55_play_sound(void);
static void atk55_play_fanfare(void);
static void atk56_fainting_cry(void);
static void atk57(void);
static void atk58_return_to_ball(void);
@@ -601,7 +601,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atk52_switch_in_effects,
atk53_trainer_slide,
atk54_effectiveness_sound,
atk55_play_sound,
atk55_play_fanfare,
atk56_fainting_cry,
atk57,
atk58_return_to_ball,
@@ -909,7 +909,7 @@ static const u8 sUnknown_0831C2E8[] = INCBIN_U8("graphics/battle_interface/unk_b
static const u8 sRubyLevelUpStatBoxStats[] =
{
MON_DATA_MAX_HP, MON_DATA_SPATK, MON_DATA_ATK,
MON_DATA_SPDEF, MON_DATA_DEF, MON_DATA_SPD
MON_DATA_SPDEF, MON_DATA_DEF, MON_DATA_SPEED
};
#define MON_ICON_LVLUP_BOX_TAG 0xD75A
@@ -3610,7 +3610,7 @@ static void atk23_getexp(void)
BATTLE_LVLUP_STATS->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP);
BATTLE_LVLUP_STATS->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK);
BATTLE_LVLUP_STATS->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF);
BATTLE_LVLUP_STATS->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD);
BATTLE_LVLUP_STATS->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED);
BATTLE_LVLUP_STATS->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK);
BATTLE_LVLUP_STATS->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF);
@@ -3649,8 +3649,8 @@ static void atk23_getexp(void)
gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK);
gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF);
// Why is this duplicated?
gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD);
gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD);
gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED);
gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED);
gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK);
gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF);
@@ -3664,8 +3664,8 @@ static void atk23_getexp(void)
gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK);
gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF);
// Duplicated again, but this time there's no Sp Defense
gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD);
gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPD);
gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED);
gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED);
gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK);
}
@@ -5308,7 +5308,7 @@ static void atk4B_return_atk_to_ball(void)
gActiveBank = gBankAttacker;
if (!(gHitMarker & HITMARKER_FAINTED(gActiveBank)))
{
EmitReturnPokeToBall(0, 0);
EmitReturnMonToBall(0, 0);
MarkBufferBankForExecution(gActiveBank);
}
gBattlescriptCurrInstr++;
@@ -5627,7 +5627,7 @@ static void atk50_openpartyscreen(void)
{
gAbsentBankFlags |= gBitTable[gActiveBank];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank));
Emit_x2A(0);
EmitCmd42(0);
MarkBufferBankForExecution(gActiveBank);
}
else if (!gSpecialStatuses[gActiveBank].flag40)
@@ -5649,7 +5649,7 @@ static void atk50_openpartyscreen(void)
{
gAbsentBankFlags |= gBitTable[gActiveBank];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank));
Emit_x2A(0);
EmitCmd42(0);
MarkBufferBankForExecution(gActiveBank);
}
else if (!gSpecialStatuses[gActiveBank].flag40)
@@ -5670,7 +5670,7 @@ static void atk50_openpartyscreen(void)
{
gAbsentBankFlags |= gBitTable[gActiveBank];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank));
Emit_x2A(0);
EmitCmd42(0);
MarkBufferBankForExecution(gActiveBank);
}
else if (!gSpecialStatuses[gActiveBank].flag40)
@@ -5692,7 +5692,7 @@ static void atk50_openpartyscreen(void)
{
gAbsentBankFlags |= gBitTable[gActiveBank];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank));
Emit_x2A(0);
EmitCmd42(0);
MarkBufferBankForExecution(gActiveBank);
}
else if (!gSpecialStatuses[gActiveBank].flag40)
@@ -5755,7 +5755,7 @@ static void atk50_openpartyscreen(void)
{
gAbsentBankFlags |= gBitTable[gActiveBank];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank));
Emit_x2A(0);
EmitCmd42(0);
MarkBufferBankForExecution(gActiveBank);
}
else if (!gSpecialStatuses[gActiveBank].flag40)
@@ -5771,7 +5771,7 @@ static void atk50_openpartyscreen(void)
{
gAbsentBankFlags |= gBitTable[gActiveBank];
gHitMarker &= ~(HITMARKER_FAINTED(gActiveBank));
Emit_x2A(0);
EmitCmd42(0);
MarkBufferBankForExecution(gActiveBank);
}
else if (!gSpecialStatuses[gActiveBank].flag40)
@@ -6031,10 +6031,10 @@ static void atk54_effectiveness_sound(void)
gBattlescriptCurrInstr += 3;
}
static void atk55_play_sound(void)
static void atk55_play_fanfare(void)
{
gActiveBank = gBankAttacker;
EmitPlaySound(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1), 0);
EmitPlayFanfareOrBGM(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1), FALSE);
MarkBufferBankForExecution(gActiveBank);
gBattlescriptCurrInstr += 3;
@@ -6052,7 +6052,7 @@ static void atk56_fainting_cry(void)
static void atk57(void)
{
gActiveBank = GetBankByIdentity(0);
Emit_x37(0, gBattleOutcome);
EmitCmd55(0, gBattleOutcome);
MarkBufferBankForExecution(gActiveBank);
gBattlescriptCurrInstr += 1;
@@ -6061,7 +6061,7 @@ static void atk57(void)
static void atk58_return_to_ball(void)
{
gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]);
EmitReturnPokeToBall(0, 1);
EmitReturnMonToBall(0, 1);
MarkBufferBankForExecution(gActiveBank);
gBattlescriptCurrInstr += 2;
@@ -7137,7 +7137,7 @@ static void atk76_various(void)
gDisableStructs[1].truantUnknownBit = 1;
break;
case 13:
EmitCmd13(0);
EmitCmd19(0);
MarkBufferBankForExecution(gActiveBank);
break;
case 14:
@@ -7162,7 +7162,7 @@ static void atk76_various(void)
gActiveBank = 1;
if (gBattleMons[gActiveBank].hp != 0)
{
EmitReturnPokeToBall(0, 0);
EmitReturnMonToBall(0, 0);
MarkBufferBankForExecution(gActiveBank);
}
break;
@@ -7172,7 +7172,7 @@ static void atk76_various(void)
gActiveBank = 3;
if (gBattleMons[gActiveBank].hp != 0)
{
EmitReturnPokeToBall(0, 0);
EmitReturnMonToBall(0, 0);
MarkBufferBankForExecution(gActiveBank);
}
}
@@ -7197,7 +7197,7 @@ static void atk76_various(void)
gBattleOutcome = BATTLE_OPPONENT_TELEPORTED;
break;
case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC:
EmitPlaySound(0, BGM_KACHI1, 1);
EmitPlayFanfareOrBGM(0, BGM_KACHI1, TRUE);
MarkBufferBankForExecution(gActiveBank);
break;
}

209
src/clear_save_data_screen.c Executable file
View File

@@ -0,0 +1,209 @@
#include "global.h"
#include "task.h"
#include "menu.h"
#include "text.h"
#include "sound.h"
#include "main.h"
#include "save.h"
#include "palette.h"
#include "gpu_regs.h"
#include "bg.h"
#include "text_window.h"
#include "songs.h"
extern u8 gText_ClearAllSaveData[];
extern u8 gText_ClearingData[];
extern u16 gUnknown_0860F074[];
static void Task_DoClearSaveDataScreenYesNo(u8);
static void Task_ClearSaveDataScreenYesNoChoice(u8);
static void Task_ClearSaveData(u8);
static bool8 SetupClearSaveDataScreen(void);
static void CB2_FadeAndDoReset(void);
static void InitClearSaveDataScreenWindows(void);
static const struct BgTemplate sClearSaveBgTemplates[2] =
{
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0,
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0,
},
};
static const struct WindowTemplate sClearSaveTextWindow[] =
{
{
.priority = 0,
.tilemapLeft = 3,
.tilemapTop = 15,
.width = 26,
.height = 4,
.paletteNum = 15,
.baseBlock = 11,
},
DUMMY_WIN_TEMPLATE
};
static const struct WindowTemplate sClearSaveYesNo[] =
{
{
.priority = 0,
.tilemapLeft = 3,
.tilemapTop = 2,
.width = 5,
.height = 4,
.paletteNum = 15,
.baseBlock = 115,
}
};
void CB2_InitClearSaveDataScreen(void)
{
if(SetupClearSaveDataScreen())
CreateTask(Task_DoClearSaveDataScreenYesNo, 0);
}
static void Task_DoClearSaveDataScreenYesNo(u8 taskId)
{
SetWindowBorderStyle(0, 0, 2, 14);
PrintTextOnWindow(0, 1, gText_ClearAllSaveData, 0, 1, 0, 0);
CreateYesNoMenu(sClearSaveYesNo, 2, 14, 1);
gTasks[taskId].func = Task_ClearSaveDataScreenYesNoChoice;
}
static void Task_ClearSaveDataScreenYesNoChoice(u8 taskId)
{
switch(sub_8198C58())
{
case 0:
FillWindowPixelBuffer(0, 17);
PrintTextOnWindow(0, 1, gText_ClearingData, 0, 1, 0, 0);
gTasks[taskId].func = Task_ClearSaveData;
break;
case 1:
case -1:
PlaySE(SE_SELECT);
DestroyTask(taskId);
SetMainCallback2(CB2_FadeAndDoReset);
}
}
static void Task_ClearSaveData(u8 taskId)
{
ClearSaveData();
DestroyTask(taskId);
SetMainCallback2(CB2_FadeAndDoReset);
}
static void MainCB(void)
{
RunTasks();
UpdatePaletteFade();
}
static void VBlankCB(void)
{
TransferPlttBuffer();
}
static bool8 SetupClearSaveDataScreen(void)
{
u16 i;
switch(gMain.state)
{
case 0:
default:
SetVBlankCallback(NULL);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
SetGpuReg(REG_OFFSET_BG3HOFS, 0);
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuReg(REG_OFFSET_WIN0H, 0);
SetGpuReg(REG_OFFSET_WIN0V, 0);
SetGpuReg(REG_OFFSET_WININ, 0);
SetGpuReg(REG_OFFSET_WINOUT, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE);
DmaFill32(3, 0, (void *)OAM, OAM_SIZE);
DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2);
ResetPaletteFade();
gPlttBufferUnfaded[0] = 0x7fff;
gPlttBufferFaded[0] = 0x7fff;
gPlttBufferUnfaded[1] = 0x3945;
gPlttBufferFaded[1] = 0x3945;
for (i = 0; i < 0x10; i++)
((u16 *)(VRAM + 0x20))[i] = 0x1111;
for (i = 0; i < 0x400; i++)
((u16 *)(VRAM + 0xF000))[i] = 0x0001;
ResetTasks();
ResetSpriteData();
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sClearSaveBgTemplates, ARRAY_COUNT(sClearSaveBgTemplates));
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(3);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
InitClearSaveDataScreenWindows();
BeginNormalPaletteFade(0x0000FFFF, 0, 0x10, 0, 0xFFFF);
EnableInterrupts(1);
SetVBlankCallback(VBlankCB);
gMain.state = 1;
break;
case 1:
UpdatePaletteFade();
if(!gPaletteFade.active)
{
SetMainCallback2(MainCB);
return TRUE;
}
}
return FALSE;
}
static void CB2_FadeAndDoReset(void)
{
switch(gMain.state)
{
case 0:
default:
BeginNormalPaletteFade(0x0000FFFF, 0, 0, 0x10, 0xFFFF);
gMain.state = 1;
break;
case 1:
UpdatePaletteFade();
if(!gPaletteFade.active)
{
FreeAllWindowBuffers();
DoSoftReset();
}
}
}
static void InitClearSaveDataScreenWindows(void)
{
InitWindows(sClearSaveTextWindow);
DeactivateAllTextPrinters();
FillWindowPixelBuffer(0, 0);
sub_80987D4(0, 0, 2, 224);
LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
}

View File

@@ -5,12 +5,12 @@
#include "text_window.h"
#include "string_util.h"
#include "menu.h"
#include "international_string_util.h"
#define MAX_COINS 9999
EWRAM_DATA u8 sCoinsWindowId = 0;
extern s32 GetStringRightAlignXOffset(u8 fontId, u8 *str, s32 totalWidth);
extern void sub_819746C(u8 windowId, bool8 copyToVram);
extern const u8 gText_Coins[];

View File

@@ -465,7 +465,7 @@ u32 sub_8034974(void* ptr)
return (ptr_[3] << 16) | (ptr_[2] << 8) | (ptr_[1]);
}
bool8 LoadCompressedObjectPicUsingHeap(struct CompressedSpriteSheet* src)
bool8 LoadCompressedObjectPicUsingHeap(const struct CompressedSpriteSheet* src)
{
struct SpriteSheet dest;
void* buffer;

2781
src/decoration.c Normal file

File diff suppressed because it is too large Load Diff

189
src/decoration_inventory.c Normal file
View File

@@ -0,0 +1,189 @@
// Includes
#include "global.h"
#include "decoration.h"
#include "decoration_inventory.h"
// Static type declarations
// Static RAM declarations
EWRAM_DATA struct DecorationInventory gDecorationInventories[8] = {};
// Static ROM declarations
// .rodata
// .text
#define SET_DECOR_INV(i, ptr) {\
gDecorationInventories[i].items = ptr;\
gDecorationInventories[i].size = sizeof(ptr);\
}
void SetDecorationInventoriesPointers(void)
{
SET_DECOR_INV(0, gSaveBlock1Ptr->decorDesk);
SET_DECOR_INV(1, gSaveBlock1Ptr->decorChair);
SET_DECOR_INV(2, gSaveBlock1Ptr->decorPlant);
SET_DECOR_INV(3, gSaveBlock1Ptr->decorOrnament);
SET_DECOR_INV(4, gSaveBlock1Ptr->decorMat);
SET_DECOR_INV(5, gSaveBlock1Ptr->decorPoster);
SET_DECOR_INV(6, gSaveBlock1Ptr->decorDoll);
SET_DECOR_INV(7, gSaveBlock1Ptr->decorCushion);
sub_8126968();
}
static void ClearDecorationInventory(u8 idx)
{
u8 i;
for (i = 0; i < gDecorationInventories[idx].size; i ++)
{
gDecorationInventories[idx].items[i] = DECOR_NONE;
}
}
void ClearDecorationInventories(void)
{
u8 idx;
for (idx = 0; idx < 8; idx ++)
{
ClearDecorationInventory(idx);
}
}
s8 GetFirstEmptyDecorSlot(u8 idx)
{
s8 i;
for (i = 0; i < (s8)gDecorationInventories[idx].size; i ++)
{
if (gDecorationInventories[idx].items[i] == DECOR_NONE)
{
return i;
}
}
return -1;
}
bool8 CheckHasDecoration(u8 decor)
{
u8 i;
u8 category;
category = gDecorations[decor].category;
for (i = 0; i < gDecorationInventories[category].size; i ++)
{
if (gDecorationInventories[category].items[i] == decor)
{
return TRUE;
}
}
return FALSE;
}
bool8 DecorationAdd(u8 decor)
{
u8 category;
s8 idx;
if (decor == DECOR_NONE)
{
return FALSE;
}
category = gDecorations[decor].category;
idx = GetFirstEmptyDecorSlot(category);
if (idx == -1)
{
return FALSE;
}
gDecorationInventories[category].items[idx] = decor;
return TRUE;
}
bool8 DecorationCheckSpace(u8 decor)
{
if (decor == DECOR_NONE)
{
return FALSE;
}
if (GetFirstEmptyDecorSlot(gDecorations[decor].category) == -1)
{
return FALSE;
}
return TRUE;
}
s8 DecorationRemove(u8 decor)
{
u8 i;
u8 idx;
i = 0;
if (decor == DECOR_NONE)
{
return 0;
}
for (i = 0; i < gDecorationInventories[gDecorations[decor].category].size; i ++)
{
idx = gDecorations[decor].category;
if (gDecorationInventories[idx].items[i] == decor)
{
gDecorationInventories[idx].items[i] = DECOR_NONE;
CondenseDecorationCategoryN(idx);
return 1;
}
}
return 0;
}
void CondenseDecorationCategoryN(u8 idx)
{
u8 i;
u8 j;
u8 tmp;
for (i = 0; i < gDecorationInventories[idx].size; i ++)
{
for (j = i + 1; j < gDecorationInventories[idx].size; j ++)
{
if (gDecorationInventories[idx].items[j] != DECOR_NONE && (gDecorationInventories[idx].items[i] == DECOR_NONE || gDecorationInventories[idx].items[i] > gDecorationInventories[idx].items[j]))
{
tmp = gDecorationInventories[idx].items[i];
gDecorationInventories[idx].items[i] = gDecorationInventories[idx].items[j];
gDecorationInventories[idx].items[j] = tmp;
}
}
}
}
u8 CountDecorationCategoryN(u8 idx)
{
u8 i;
u8 ct;
ct = 0;
for (i = 0; i < gDecorationInventories[idx].size; i ++)
{
if (gDecorationInventories[idx].items[i] != DECOR_NONE)
{
ct ++;
}
}
return ct;
}
u8 CountDecorations(void)
{
u8 idx;
u8 ct;
ct = 0;
for (idx = 0; idx < 8; idx ++)
{
ct += CountDecorationCategoryN(idx);
}
return ct;
}

View File

@@ -462,7 +462,7 @@ static void VBlankCB_EggHatch(void)
TransferPlttBuffer();
}
static void EggHatch(void)
void EggHatch(void)
{
ScriptContext2_Enable();
CreateTask(Task_EggHatch, 10);

View File

@@ -0,0 +1,57 @@
#include "global.h"
#include "international_string_util.h"
#include "text.h"
extern s32 convert_pixel_width_to_tile_width(s32 a0); // script menu
s32 GetStringCenterAlignXOffset(s32 fontId, const u8 *str, s32 totalWidth)
{
return GetStringCenterAlignXOffsetWithLetterSpacing(fontId, str, totalWidth, 0);
}
s32 GetStringRightAlignXOffset(s32 fontId, const u8 *str, s32 totalWidth)
{
return GetStringWidthDifference(fontId, str, totalWidth, 0);
}
s32 GetStringCenterAlignXOffsetWithLetterSpacing(s32 fontId, const u8 *str, s32 totalWidth, s32 letterSpacing)
{
return GetStringWidthDifference(fontId, str, totalWidth, letterSpacing) / 2;
}
s32 GetStringWidthDifference(s32 fontId, const u8 *str, s32 totalWidth, s32 letterSpacing)
{
s32 stringWidth = GetStringWidth(fontId, str, letterSpacing);
if (totalWidth > stringWidth)
return totalWidth - stringWidth;
else
return 0;
}
s32 GetMaxWidthInMenuTable(const struct MenuAction *str, s32 arg1)
{
s32 i, var;
for (var = 0, i = 0; i < arg1; i++)
{
s32 stringWidth = GetStringWidth(1, str[i].text, 0);
if (stringWidth > var)
var = stringWidth;
}
return convert_pixel_width_to_tile_width(var);
}
s32 sub_81DB3D8(const struct MenuAction *str, u8* arg1, s32 arg2)
{
s32 i, var;
for (var = 0, i = 0; i < arg2; i++)
{
s32 stringWidth = GetStringWidth(1, str[arg1[i]].text, 0);
if (stringWidth > var)
var = stringWidth;
}
return convert_pixel_width_to_tile_width(var);
}

4
src/librfu_intr.c Normal file
View File

@@ -0,0 +1,4 @@
#include "global.h"
#include "main.h"
//TODO: decompile asm/librfu_intr.s to here

109
src/librfu_rfu.c Normal file
View File

@@ -0,0 +1,109 @@
#include "global.h"
#include "main.h"
#include "librfu.h"
struct RfuUnk1
{
u8 unk_0[0x14];
u32 unk_14;
u32 unk_18;
struct RfuIntrStruct unk_1c;
};
struct RfuUnk2
{
u8 unk_0[0x68];
u32 unk_68;
u32 unk_6c;
u8 unk_70[0x70];
};
struct RfuUnk3
{
u32 unk_0;
u32 unk_4;
u8 unk_8[0xD4];
u32 unk_dc;
};
extern u32 *gUnknown_03007890;
extern u32 *gUnknown_03007894;
extern struct RfuUnk3* gUnknown_03007898;
extern struct RfuUnk2* gUnknown_03007880[4];
extern struct RfuUnk1* gUnknown_03007870[4];
extern void* sub_82E53F4;
extern void rfu_STC_clearAPIVariables(void);
// Nonmatching, only register differences
/*u16 rfu_initializeAPI(u32 *unk0, u16 unk1, IntrFunc *interrupt, bool8 copyInterruptToRam)
{
u16 i;
u16 *v13;
u16 *v12;
u16 num;
if (((u32)unk0 & 0xF000000) == 0x2000000 && copyInterruptToRam)
{
return 2;
}
if ((u32)unk0 & 3)
return 2;
// Nintendo pls, just use a ternary for once
if (copyInterruptToRam)
{
// An assert/debug print may have existed before, ie
// printf("%s %u < %u", "somefile.c:12345", unk1, num)
// to push this into r3?
num = 0xe64;
if (unk1 < num)
return 1;
}
if (copyInterruptToRam == FALSE)
{
num = 0x504; // same as above, this should be r3 not r0
if (unk1 < num)
return 1;
}
gUnknown_03007890 = unk0;
gUnknown_03007894 = unk0 + (0xB4 / sizeof(u32));
gUnknown_03007898 = (struct RfuUnk3*)(unk0 + (0xDC / sizeof(u32)));
gUnknown_03007880[0] = (struct RfuUnk2*)(unk0 + (0x1BC / sizeof(u32)));
gUnknown_03007870[0] = (struct RfuUnk1*)(unk0 + (0x37C / sizeof(u32)));
for (i = 1; i < 4; i++, num)
{
gUnknown_03007880[i] = (struct RfuUnk2*)&gUnknown_03007880[i-1]->unk_70;
gUnknown_03007870[i] = (struct RfuUnk1*)&gUnknown_03007870[i-1]->unk_1c;
}
gUnknown_03007898->unk_dc = (u32)&gUnknown_03007870[3]->unk_1c;
STWI_init_all(&gUnknown_03007870[3]->unk_1c, interrupt, copyInterruptToRam);
rfu_STC_clearAPIVariables();
for (i = 0; i < 4; i++)
{
gUnknown_03007880[i]->unk_68 = 0;
gUnknown_03007880[i]->unk_6c = 0;
gUnknown_03007870[i]->unk_14 = 0;
gUnknown_03007870[i]->unk_18 = 0;
}
// Not matching, register differences
v12 = (u16*)((u32)&sub_82E53F4 & ~1);
v13 = (u16*)gUnknown_03007898->unk_8;
for (i = 47; i != 0xFFFF; i--)
{
*v13 = *v12;
++v12;
++v13;
}
gUnknown_03007898->unk_4 = (u32)(&gUnknown_03007898->unk_8[1]);
return 0;
}*/

687
src/librfu_stwi.c Normal file
View File

@@ -0,0 +1,687 @@
#include "global.h"
#include "librfu.h"
extern IntrFunc IntrSIO32(void);
extern void STWI_stop_timer(void);
void STWI_init_Callback_M(void);
void STWI_init_Callback_S(void);
void STWI_set_Callback_M(void * callback);
void STWI_set_Callback_S(void * callback);
u16 STWI_init(u8 request);
int STWI_start_Command(void);
void STWI_intr_timer(void);
void STWI_set_timer(u8 unk);
int STWI_restart_Command(void);
int STWI_reset_ClockCounter(void);
void STWI_init_all(struct RfuIntrStruct *interruptStruct, IntrFunc *interrupt, bool8 copyInterruptToRam)
{
// If we're copying our interrupt into RAM, DMA it to block1 and use
// block2 for our RfuStruct, otherwise block1 holds the RfuStruct.
// interrupt usually is a pointer to gIntrTable[1]
if (copyInterruptToRam == TRUE)
{
*interrupt = (IntrFunc)interruptStruct->block1;
DmaCopy16(3, &IntrSIO32, interruptStruct->block1, 0x960);
gRfuState = (struct RfuStruct*)interruptStruct->block2;
}
else
{
*interrupt = (IntrFunc)IntrSIO32;
gRfuState = (struct RfuStruct*)interruptStruct->block1;
}
gRfuState->rxPacket = (union RfuPacket*)interruptStruct->rxPacketAlloc;
gRfuState->txPacket = (union RfuPacket*)interruptStruct->txPacketAlloc;
gRfuState->msMode = 1;
gRfuState->unk_0 = 0;
gRfuState->txParams = 0;
gRfuState->unk_5 = 0;
gRfuState->unk_7 = 0;
gRfuState->unk_8 = 0;
gRfuState->unk_9 = 0;
gRfuState->timerState = 0;
gRfuState->timerActive = 0;
gRfuState->unk_12 = 0;
gRfuState->unk_15 = 0;
gRfuState->unk_2c = 0;
REG_RCNT = 0x100; //TODO: mystery bit?
REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
STWI_init_Callback_M();
STWI_init_Callback_S();
IntrEnable(INTR_FLAG_SERIAL);
}
void STWI_init_timer(IntrFunc *interrupt, int timerSelect)
{
*interrupt = STWI_intr_timer;
gRfuState->timerSelect = timerSelect;
IntrEnable(INTR_FLAG_TIMER0 << gRfuState->timerSelect);
}
void AgbRFU_SoftReset(void)
{
vu16 *timerL;
vu16 *timerH;
REG_RCNT = 0x8000;
REG_RCNT = 0x80A0; // all these bits are undocumented
timerL = &REG_TMCNT_L(gRfuState->timerSelect);
timerH = &REG_TMCNT_H(gRfuState->timerSelect);
*timerH = 0;
*timerL = 0;
*timerH = 0x83;
while (*timerL <= 0x11)
REG_RCNT = 0x80A2;
*timerH = 3;
REG_RCNT = 0x80A0;
REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
gRfuState->unk_0 = 0;
gRfuState->txParams = 0;
gRfuState->unk_5 = 0;
gRfuState->activeCommand = 0;
gRfuState->unk_7 = 0;
gRfuState->unk_8 = 0;
gRfuState->unk_9 = 0;
gRfuState->timerState = 0;
gRfuState->timerActive = 0;
gRfuState->unk_12 = 0;
gRfuState->msMode = 1;
gRfuState->unk_15 = 0;
gRfuState->unk_2c = 0;
}
void STWI_set_MS_mode(u8 mode)
{
gRfuState->msMode = mode;
}
u16 STWI_read_status(u8 index)
{
switch (index)
{
case 0:
return gRfuState->unk_12;
case 1:
return gRfuState->msMode;
case 2:
return gRfuState->unk_0;
case 3:
return gRfuState->activeCommand;
default:
return 0xFFFF;
}
}
void STWI_init_Callback_M(void)
{
STWI_set_Callback_M(0);
}
void STWI_init_Callback_S(void)
{
STWI_set_Callback_S(0);
}
void STWI_set_Callback_M(void *callback)
{
gRfuState->callbackM = callback;
}
void STWI_set_Callback_S(void *callback)
{
gRfuState->callbackS = callback;
}
void STWI_set_Callback_ID(u32 id)
{
gRfuState->callbackID = id;
}
u16 STWI_poll_CommandEnd(void)
{
while (gRfuState->unk_2c == TRUE)
;
return gRfuState->unk_12;
}
void STWI_send_ResetREQ(void)
{
if (!STWI_init(RFU_RESET))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_LinkStatusREQ(void)
{
if (!STWI_init(RFU_LINK_STATUS))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_VersionStatusREQ(void)
{
if (!STWI_init(RFU_VERSION_STATUS))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_SystemStatusREQ(void)
{
if (!STWI_init(RFU_SYSTEM_STATUS))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_SlotStatusREQ(void)
{
if (!STWI_init(RFU_SLOT_STATUS))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_ConfigStatusREQ(void)
{
if (!STWI_init(RFU_CONFIG_STATUS))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_GameConfigREQ(u8 * unk1, u8 *data)
{
u8 *packetBytes;
int i;
if (!STWI_init(RFU_GAME_CONFIG))
{
gRfuState->txParams = 6;
//TODO: what is unk1
packetBytes = gRfuState->txPacket->rfuPacket8.data;
packetBytes += sizeof(u32);
*(u16*)packetBytes = *(u16*)unk1;
packetBytes += sizeof(u16);
unk1 += sizeof(u16);
for (i = 0; i < 14; i++)
{
*packetBytes = *unk1;
packetBytes++;
unk1++;
}
for (i = 0; i < 8; i++)
{
*packetBytes = *data;
packetBytes++;
data++;
}
STWI_start_Command();
}
}
void STWI_send_SystemConfigREQ(u16 unk1, u8 unk2, u8 unk3)
{
if (!STWI_init(RFU_SYSTEM_CONFIG))
{
u8 *packetBytes;
gRfuState->txParams = 1;
packetBytes = gRfuState->txPacket->rfuPacket8.data;
packetBytes += sizeof(u32);
*packetBytes++ = unk3;
*packetBytes++ = unk2;
*(u16*)packetBytes = unk1;
STWI_start_Command();
}
}
void STWI_send_SC_StartREQ(void)
{
if (!STWI_init(RFU_SC_START))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_SC_PollingREQ(void)
{
if (!STWI_init(RFU_SC_POLLING))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_SC_EndREQ(void)
{
if (!STWI_init(RFU_SC_END))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_SP_StartREQ(void)
{
if (!STWI_init(RFU_SP_START))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_SP_PollingREQ(void)
{
if (!STWI_init(RFU_SP_POLLING))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_SP_EndREQ(void)
{
if (!STWI_init(RFU_SP_END))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_CP_StartREQ(u16 unk1)
{
if (!STWI_init(RFU_CP_START))
{
gRfuState->txParams = 1;
gRfuState->txPacket->rfuPacket32.data[0] = unk1;
STWI_start_Command();
}
}
void STWI_send_CP_PollingREQ(void)
{
if (!STWI_init(RFU_CP_POLLING))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_CP_EndREQ(void)
{
if (!STWI_init(RFU_CP_END))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_DataTxREQ(void *in, u8 size)
{
if (!STWI_init(RFU_DATA_TX))
{
u8 txParams = (size / sizeof(u32));
if (size & (sizeof(u32) - 1))
txParams += 1;
gRfuState->txParams = txParams;
CpuCopy32(in, gRfuState->txPacket->rfuPacket32.data, gRfuState->txParams * sizeof(u32));
STWI_start_Command();
}
}
void STWI_send_DataTxAndChangeREQ(void *in, u8 size)
{
if (!STWI_init(RFU_DATA_TX_AND_CHANGE))
{
u8 txParams = (size / sizeof(u32));
if (size & (sizeof(u32) - 1))
txParams += 1;
gRfuState->txParams = txParams;
CpuCopy32(in, gRfuState->txPacket->rfuPacket32.data, gRfuState->txParams * sizeof(u32));
STWI_start_Command();
}
}
void STWI_send_DataRxREQ(void)
{
if (!STWI_init(RFU_DATA_RX))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_MS_ChangeREQ(void)
{
if (!STWI_init(RFU_MS_CHANGE))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_DataReadyAndChangeREQ(u8 unk)
{
if (!STWI_init(RFU_DATA_READY_AND_CHANGE))
{
if (!unk)
{
gRfuState->txParams = 0;
}
else
{
u8 *packetBytes;
gRfuState->txParams = 1;
packetBytes = gRfuState->txPacket->rfuPacket8.data;
packetBytes += sizeof(u32);
*packetBytes++ = unk;
*packetBytes++ = 0;
*packetBytes++ = 0;
*packetBytes = 0;
}
STWI_start_Command();
}
}
void STWI_send_DisconnectedAndChangeREQ(u8 unk0, u8 unk1)
{
if (!STWI_init(RFU_DISCONNECTED_AND_CHANGE))
{
u8 *packetBytes;
gRfuState->txParams = 1;
packetBytes = gRfuState->txPacket->rfuPacket8.data;
packetBytes += sizeof(u32);
*packetBytes++ = unk0;
*packetBytes++ = unk1;
*packetBytes++ = 0;
*packetBytes = 0;
STWI_start_Command();
}
}
void STWI_send_ResumeRetransmitAndChangeREQ(void)
{
if (!STWI_init(RFU_RESUME_RETRANSMIT_AND_CHANGE))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_DisconnectREQ(u8 unk)
{
if (!STWI_init(RFU_DISCONNECT))
{
gRfuState->txParams = 1;
gRfuState->txPacket->rfuPacket32.data[0] = unk;
STWI_start_Command();
}
}
void STWI_send_TestModeREQ(u8 unk0, u8 unk1)
{
if (!STWI_init(RFU_TEST_MODE))
{
gRfuState->txParams = 1;
gRfuState->txPacket->rfuPacket32.data[0] = unk0 | (unk1 << 8);
STWI_start_Command();
}
}
void STWI_send_CPR_StartREQ(u16 unk0, u16 unk1, u8 unk2)
{
u32 *packetData;
u32 arg1;
if (!STWI_init(RFU_CPR_START))
{
gRfuState->txParams = 2;
arg1 = unk1 | (unk0 << 16);
packetData = gRfuState->txPacket->rfuPacket32.data;
packetData[0] = arg1;
packetData[1] = unk2;
STWI_start_Command();
}
}
void STWI_send_CPR_PollingREQ(void)
{
if (!STWI_init(RFU_CPR_POLLING))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_CPR_EndREQ(void)
{
if (!STWI_init(RFU_CPR_END))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_send_StopModeREQ(void)
{
if (!STWI_init(RFU_STOP_MODE))
{
gRfuState->txParams = 0;
STWI_start_Command();
}
}
void STWI_intr_timer(void)
{
switch (gRfuState->timerState)
{
//TODO: Make an enum for these
case 2:
gRfuState->timerActive = 1;
STWI_set_timer(50);
break;
case 1:
case 4:
STWI_stop_timer();
STWI_restart_Command();
break;
case 3:
gRfuState->timerActive = 1;
STWI_stop_timer();
STWI_reset_ClockCounter();
if (gRfuState->callbackM)
gRfuState->callbackM(255, 0);
break;
}
}
void STWI_set_timer(u8 unk)
{
vu16 *timerL;
vu16 *timerH;
timerL = &REG_TMCNT_L(gRfuState->timerSelect);
timerH = &REG_TMCNT_H(gRfuState->timerSelect);
REG_IME = 0;
switch (unk)
{
case 50:
*timerL = 0xFCCB;
gRfuState->timerState = 1;
break;
case 80:
*timerL = 0xFAE0;
gRfuState->timerState = 2;
break;
case 100:
*timerL = 0xF996;
gRfuState->timerState = 3;
break;
case 130:
*timerL = 0xF7AD;
gRfuState->timerState = 4;
break;
}
*timerH = TIMER_ENABLE | TIMER_INTR_ENABLE | TIMER_1024CLK;
REG_IF = INTR_FLAG_TIMER0 << gRfuState->timerSelect;
REG_IME = 1;
}
void STWI_stop_timer(void)
{
gRfuState->timerState = 0;
REG_TMCNT_L(gRfuState->timerSelect) = 0;
REG_TMCNT_H(gRfuState->timerSelect) = 0;
}
u16 STWI_init(u8 request)
{
if (!REG_IME)
{
gRfuState->unk_12 = 6;
if (gRfuState->callbackM)
gRfuState->callbackM(request, gRfuState->unk_12);
return TRUE;
}
else if (gRfuState->unk_2c == TRUE)
{
gRfuState->unk_12 = 2;
gRfuState->unk_2c = FALSE;
if (gRfuState->callbackM)
gRfuState->callbackM(request, gRfuState->unk_12);
return TRUE;
}
else if(!gRfuState->msMode)
{
gRfuState->unk_12 = 4;
if (gRfuState->callbackM)
gRfuState->callbackM(request, gRfuState->unk_12, gRfuState);
return TRUE;
}
else
{
gRfuState->unk_2c = TRUE;
gRfuState->activeCommand = request;
gRfuState->unk_0 = 0;
gRfuState->txParams = 0;
gRfuState->unk_5 = 0;
gRfuState->unk_7 = 0;
gRfuState->unk_8 = 0;
gRfuState->unk_9 = 0;
gRfuState->timerState = 0;
gRfuState->timerActive = 0;
gRfuState->unk_12 = 0;
gRfuState->unk_15 = 0;
REG_RCNT = 0x100;
REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
return FALSE;
}
}
int STWI_start_Command()
{
u16 imeTemp;
// Yes, it matters that it's casted to a u32...
*(u32*)gRfuState->txPacket->rfuPacket8.data = 0x99660000 | (gRfuState->txParams << 8) | gRfuState->activeCommand;
REG_SIODATA32 = gRfuState->txPacket->rfuPacket32.command;
gRfuState->unk_0 = 0;
gRfuState->unk_5 = 1;
imeTemp = REG_IME;
REG_IME = 0;
REG_IE |= (INTR_FLAG_TIMER0 << gRfuState->timerSelect);
REG_IE |= INTR_FLAG_SERIAL;
REG_IME = imeTemp;
REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_MULTI_BUSY | SIO_115200_BPS;
return 0;
}
int STWI_restart_Command(void)
{
if (gRfuState->unk_15 <= 1)
{
gRfuState->unk_15++;
STWI_start_Command();
}
else
{
if (gRfuState->activeCommand == RFU_MS_CHANGE || gRfuState->activeCommand == RFU_DATA_TX_AND_CHANGE || gRfuState->activeCommand == RFU_UNK35 || gRfuState->activeCommand == RFU_RESUME_RETRANSMIT_AND_CHANGE)
{
gRfuState->unk_12 = 1;
gRfuState->unk_2c = 0;
if (gRfuState->callbackM)
gRfuState->callbackM(gRfuState->activeCommand, gRfuState->unk_12);
}
else
{
gRfuState->unk_12 = 1;
gRfuState->unk_2c = 0;
if (gRfuState->callbackM)
gRfuState->callbackM(gRfuState->activeCommand, gRfuState->unk_12);
gRfuState->unk_0 = 4; //TODO: what's 4
}
}
return 0;
}
int STWI_reset_ClockCounter()
{
gRfuState->unk_0 = 5; //TODO: what is 5
gRfuState->txParams = 0;
gRfuState->unk_5 = 0;
REG_SIODATA32 = (1 << 31);
REG_SIOCNT = 0;
REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
REG_SIOCNT = (SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS) + 0x7F;
return 0;
}

577
src/mail.c Normal file
View File

@@ -0,0 +1,577 @@
// Includes
#include "global.h"
#include "main.h"
#include "overworld.h"
#include "task.h"
#include "unknown_task.h"
#include "palette.h"
#include "menu.h"
#include "menu_helpers.h"
#include "text.h"
#include "text_window.h"
#include "string_util.h"
#include "international_string_util.h"
#include "strings.h"
#include "gpu_regs.h"
#include "bg.h"
#include "pokemon_icon.h"
#include "species.h"
#include "malloc.h"
#include "easy_chat.h"
#include "mail_data.h"
#include "mail.h"
// Static type declarations
struct UnkMailStruct
{
u32 numEasyChatWords:2;
u32 xOffset:6;
u32 lineHeight:8;
};
struct MailLayout
{
u8 numSubStructs;
u8 signatureYPos;
u8 signatureWidth;
u8 wordsXPos;
u8 wordsYPos;
const struct UnkMailStruct *var8;
};
struct MailGraphics
{
const u16 *palette;
const u8 *tiles;
const u8 *tileMap;
u16 var0C;
u16 var0E;
u16 color10;
u16 color12;
};
// Static RAM declarations
static EWRAM_DATA struct
{
/*0x0000*/ u8 strbuf[8][64];
/*0x0200*/ u8 playerName[12];
/*0x020C*/ MainCallback callback;
/*0x0210*/ MainCallback callback2;
/*0x0214*/ struct MailStruct *mail;
/*0x0218*/ bool8 flag;
/*0x0219*/ u8 signatureWidth;
/*0x021a*/ u8 mailType;
/*0x021b*/ u8 animsActive;
/*0x021c*/ u8 monIconSprite;
/*0x021d*/ u8 language;
/*0x021e*/ bool8 playerIsSender;
/*0x0220*/ void (*parserSingle)(u8 *dest, u16 word);
/*0x0224*/ void (*parserMultiple)(u8 *dest, const u16 *src, u16 length1, u16 length2);
/*0x0228*/ const struct MailLayout *layout;
/*0x022c*/ u8 bg1TilemapBuffer[0x1000];
/*0x122c*/ u8 bg2TilemapBuffer[0x1000];
} *gUnknown_0203A134 = NULL;
// Static ROM declarations
void sub_81219F0(void);
void sub_8121A1C(void);
void sub_8121B1C(void);
void sub_8121C50(void);
void sub_8121C64(void);
void sub_8121C98(void);
void sub_8121CC0(void);
void sub_8121D00(void);
// .rodata
const struct BgTemplate gUnknown_0859F290[] = {
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.priority = 0
}, {
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 30,
.priority = 1
}, {
.bg = 2,
.charBaseIndex = 0,
.mapBaseIndex = 29,
.priority = 2
}
};
const struct WindowTemplate gUnknown_0859F29C[] = {
{
.priority = 0,
.tilemapLeft = 2,
.tilemapTop = 3,
.width = 26,
.height = 15,
.paletteNum = 15,
.baseBlock = 1
},
DUMMY_WIN_TEMPLATE
};
const u8 gUnknown_0859F2AC[] = {
0,
10,
11
};
const u16 gUnknown_0859F2B0[][2] = {
{ 0x6ACD, 0x51A5 },
{ 0x45FC, 0x38D4 }
};
extern const u16 gUnknown_08DBE818[];
extern const u16 gUnknown_08DBE838[];
extern const u16 gUnknown_08DBE858[];
extern const u16 gUnknown_08DBE878[];
extern const u16 gUnknown_08DBE898[];
extern const u16 gUnknown_08DBE8B8[];
extern const u16 gUnknown_08DBE8D8[];
extern const u16 gUnknown_08DBE8F8[];
extern const u16 gUnknown_08DBE918[];
extern const u16 gUnknown_08DBE938[];
extern const u16 gUnknown_08DBE958[];
extern const u16 gUnknown_08DBE978[];
extern const u8 gUnknown_08DBE998[];
extern const u8 gUnknown_08DBFBA4[];
extern const u8 gUnknown_08DBEB38[];
extern const u8 gUnknown_08DBFC7C[];
extern const u8 gUnknown_08DBEC74[];
extern const u8 gUnknown_08DBFD5C[];
extern const u8 gUnknown_08DBEE84[];
extern const u8 gUnknown_08DBFE68[];
extern const u8 gUnknown_08DBEF5C[];
extern const u8 gUnknown_08DBFF44[];
extern const u8 gUnknown_08DBF154[];
extern const u8 gUnknown_08DC0034[];
extern const u8 gUnknown_08DBF2D4[];
extern const u8 gUnknown_08DC0114[];
extern const u8 gUnknown_08DBF37C[];
extern const u8 gUnknown_08DC01F4[];
extern const u8 gUnknown_08DBF50C[];
extern const u8 gUnknown_08DC0300[];
extern const u8 gUnknown_08DBF64C[];
extern const u8 gUnknown_08DC03F0[];
extern const u8 gUnknown_08DBF7B4[];
extern const u8 gUnknown_08DC04E8[];
extern const u8 gUnknown_08DBF904[];
extern const u8 gUnknown_08DC0600[];
const struct MailGraphics gUnknown_0859F2B8[] = {
{
gUnknown_08DBE818, gUnknown_08DBE998, gUnknown_08DBFBA4, 0x02c0, 0x0000, 0x294a, 0x6739
}, {
gUnknown_08DBE838, gUnknown_08DBEB38, gUnknown_08DBFC7C, 0x02e0, 0x0000, 0x7fff, 0x4631
}, {
gUnknown_08DBE858, gUnknown_08DBEC74, gUnknown_08DBFD5C, 0x0400, 0x0000, 0x294a, 0x6739
}, {
gUnknown_08DBE878, gUnknown_08DBEE84, gUnknown_08DBFE68, 0x01e0, 0x0000, 0x7fff, 0x4631
}, {
gUnknown_08DBE898, gUnknown_08DBEF5C, gUnknown_08DBFF44, 0x02e0, 0x0000, 0x7fff, 0x4631
}, {
gUnknown_08DBE8B8, gUnknown_08DBF154, gUnknown_08DC0034, 0x0300, 0x0000, 0x294a, 0x6739
}, {
gUnknown_08DBE8D8, gUnknown_08DBF2D4, gUnknown_08DC0114, 0x0140, 0x0000, 0x7fff, 0x4631
}, {
gUnknown_08DBE8F8, gUnknown_08DBF37C, gUnknown_08DC01F4, 0x0300, 0x0000, 0x7fff, 0x4631
}, {
gUnknown_08DBE918, gUnknown_08DBF50C, gUnknown_08DC0300, 0x0220, 0x0000, 0x294a, 0x6739
}, {
gUnknown_08DBE938, gUnknown_08DBF64C, gUnknown_08DC03F0, 0x0340, 0x0000, 0x294a, 0x6739
}, {
gUnknown_08DBE958, gUnknown_08DBF7B4, gUnknown_08DC04E8, 0x02a0, 0x0000, 0x294a, 0x6739
}, {
gUnknown_08DBE978, gUnknown_08DBF904, gUnknown_08DC0600, 0x0520, 0x0000, 0x294a, 0x6739
}
};
const struct UnkMailStruct Unknown_0859F3A8[] = {
{ .numEasyChatWords = 3, .lineHeight = 16 },
{ .numEasyChatWords = 3, .lineHeight = 16 },
{ .numEasyChatWords = 3, .lineHeight = 16 }
};
const struct MailLayout gUnknown_0859F3B4[] = {
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x08, 0x00, 0x02, 0x04, Unknown_0859F3A8 },
{ 0x03, 0x00, 0x00, 0x02, 0x00, Unknown_0859F3A8 }
};
const struct UnkMailStruct Unknown_0859F444[] = {
{ .numEasyChatWords = 2, .lineHeight = 16 },
{ .numEasyChatWords = 2, .lineHeight = 16 },
{ .numEasyChatWords = 2, .lineHeight = 16 },
{ .numEasyChatWords = 2, .lineHeight = 16 },
{ .numEasyChatWords = 1, .lineHeight = 16 }
};
const struct MailLayout gUnknown_0859F458[] = {
{ 0x05, 0x07, 0x58, 0x0b, 0x1e, Unknown_0859F444 },
{ 0x05, 0x0a, 0x60, 0x09, 0x1e, Unknown_0859F444 },
{ 0x05, 0x0c, 0x68, 0x05, 0x1e, Unknown_0859F444 },
{ 0x05, 0x05, 0x60, 0x08, 0x1e, Unknown_0859F444 },
{ 0x05, 0x0a, 0x60, 0x09, 0x1e, Unknown_0859F444 },
{ 0x05, 0x09, 0x70, 0x05, 0x1e, Unknown_0859F444 },
{ 0x05, 0x0c, 0x68, 0x09, 0x1e, Unknown_0859F444 },
{ 0x05, 0x0d, 0x68, 0x0d, 0x1e, Unknown_0859F444 },
{ 0x05, 0x09, 0x60, 0x09, 0x1e, Unknown_0859F444 },
{ 0x05, 0x09, 0x60, 0x09, 0x1e, Unknown_0859F444 },
{ 0x05, 0x11, 0x68, 0x0f, 0x1e, Unknown_0859F444 },
{ 0x05, 0x09, 0x60, 0x05, 0x1e, Unknown_0859F444 }
};
// What the heck are these meant to be? Call them u16 for now.
const u16 Unknown_0859F4E8[] = {
0x00, 0x4000, 0x00, 0x00
};
const u16 Unknown_0859F4F0[] = {
0x00, 0x00, -1, 0x00
};
const u16 Unknown_0859F4F8[] = {
0x04, 0x00, -1, 0x00
};
const u16 Unknown_0859F500[] = {
0x00, 0x40, -1, 0x00
};
const u16 *const gUnknown_0859F508[] = {
Unknown_0859F4F0,
Unknown_0859F4F8,
Unknown_0859F500
};
// .text
void sub_8121478(struct MailStruct *mail, MainCallback callback, bool8 flag) {
u16 buffer[2];
u16 species;
gUnknown_0203A134 = calloc(1, sizeof(*gUnknown_0203A134));
gUnknown_0203A134->language = LANGUAGE_ENGLISH;
gUnknown_0203A134->playerIsSender = TRUE;
gUnknown_0203A134->parserSingle = CopyEasyChatWord;
gUnknown_0203A134->parserMultiple = ConvertEasyChatWordsToString;
if (mail->itemId >= ITEM_ORANGE_MAIL && mail->itemId <= ITEM_RETRO_MAIL) {
gUnknown_0203A134->mailType = mail->itemId - ITEM_ORANGE_MAIL;
}
else
{
gUnknown_0203A134->mailType = 0;
flag = FALSE;
}
switch (gUnknown_0203A134->playerIsSender)
{
case FALSE:
default:
gUnknown_0203A134->layout = &gUnknown_0859F3B4[gUnknown_0203A134->mailType];
break;
case TRUE:
gUnknown_0203A134->layout = &gUnknown_0859F458[gUnknown_0203A134->mailType];
break;
}
species = sub_80D45E8(mail->species, buffer);
if (species >= SPECIES_BULBASAUR && species < NUM_SPECIES)
{
switch (gUnknown_0203A134->mailType)
{
default:
gUnknown_0203A134->animsActive = 0;
break;
case ITEM_BEAD_MAIL - ITEM_ORANGE_MAIL:
gUnknown_0203A134->animsActive = 1;
break;
case ITEM_DREAM_MAIL - ITEM_ORANGE_MAIL:
gUnknown_0203A134->animsActive = 2;
break;
}
}
else
{
gUnknown_0203A134->animsActive = 0;
}
gUnknown_0203A134->mail = mail;
gUnknown_0203A134->callback = callback;
gUnknown_0203A134->flag = flag;
SetMainCallback2(sub_81219F0);
}
bool8 sub_81215EC(void)
{
u16 icon;
switch (gMain.state)
{
case 0:
SetVBlankCallback(NULL);
remove_some_task();
SetGpuReg(REG_OFFSET_DISPCNT, 0x0000);
break;
case 1:
CpuFill16(0, (void *)OAM, OAM_SIZE);
break;
case 2:
ResetPaletteFade();
break;
case 3:
ResetTasks();
break;
case 4:
ResetSpriteData();
break;
case 5:
FreeAllSpritePalettes();
reset_temp_tile_data_buffers();
SetGpuReg(REG_OFFSET_BG0HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG0VOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG1HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG1VOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG2VOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG2HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG3HOFS, 0x0000);
SetGpuReg(REG_OFFSET_BG3VOFS, 0x0000);
SetGpuReg(REG_OFFSET_BLDCNT, 0x0000);
SetGpuReg(REG_OFFSET_BLDALPHA, 0x0000);
break;
case 6:
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_0859F290, 3);
SetBgTilemapBuffer(1, gUnknown_0203A134->bg1TilemapBuffer);
SetBgTilemapBuffer(2, gUnknown_0203A134->bg2TilemapBuffer);
break;
case 7:
InitWindows(gUnknown_0859F29C);
DeactivateAllTextPrinters();
break;
case 8:
decompress_and_copy_tile_data_to_vram(1, gUnknown_0859F2B8[gUnknown_0203A134->mailType].tiles, 0, 0, 0);
break;
case 9:
if (free_temp_tile_data_buffers_if_possible())
{
return FALSE;
}
break;
case 10:
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(2, 1, 0, 0, 30, 20);
CopyToBgTilemapBuffer(1, gUnknown_0859F2B8[gUnknown_0203A134->mailType].tileMap, 0, 0);
break;
case 11:
CopyBgTilemapBufferToVram(0);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
break;
case 12:
LoadPalette(sub_8098C64(), 240, 32);
gPlttBufferUnfaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10;
gPlttBufferFaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10;
gPlttBufferUnfaded[251] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color12;
gPlttBufferFaded[251] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color12;
LoadPalette(gUnknown_0859F2B8[gUnknown_0203A134->mailType].palette, 0, 32);
gPlttBufferUnfaded[10] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][0];
gPlttBufferFaded[10] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][0];
gPlttBufferUnfaded[11] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][1];
gPlttBufferFaded[11] = gUnknown_0859F2B0[gSaveBlock2Ptr->playerGender][1];
break;
case 13:
if (gUnknown_0203A134->flag)
{
sub_8121A1C();
}
break;
case 14:
if (gUnknown_0203A134->flag)
{
sub_8121B1C();
RunTextPrinters();
}
break;
case 15:
if (sub_8087598() == TRUE)
{
return FALSE;
}
break;
case 16:
SetVBlankCallback(sub_8121C50);
gPaletteFade.bufferTransferDisabled = TRUE;
break;
case 17:
icon = sub_80D2E84(gUnknown_0203A134->mail->species);
switch (gUnknown_0203A134->animsActive)
{
case 1:
sub_80D2F68(icon);
gUnknown_0203A134->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x60, 0x80, 0, 0);
break;
case 2:
sub_80D2F68(icon);
gUnknown_0203A134->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x28, 0x80, 0, 0);
break;
}
break;
case 18:
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(1);
ShowBg(2);
BeginNormalPaletteFade(-1, 0, 16, 0, 0);
gPaletteFade.bufferTransferDisabled = FALSE;
gUnknown_0203A134->callback2 = sub_8121C98;
return TRUE;
default:
return FALSE;
}
gMain.state ++;
return FALSE;
}
void sub_81219F0(void)
{
do
{
if (sub_81215EC() == TRUE)
{
SetMainCallback2(sub_8121C64);
break;
}
} while (sub_81221AC() != TRUE);
}
void sub_8121A1C(void)
{
u16 i;
u8 total;
u8 *ptr;
total = 0;
for (i = 0; i < gUnknown_0203A134->layout->numSubStructs; i ++)
{
ConvertEasyChatWordsToString(gUnknown_0203A134->strbuf[i], &gUnknown_0203A134->mail->words[total], gUnknown_0203A134->layout->var8[i].numEasyChatWords, 1);
total += gUnknown_0203A134->layout->var8[i].numEasyChatWords;
}
ptr = StringCopy(gUnknown_0203A134->playerName, gUnknown_0203A134->mail->playerName);
if (!gUnknown_0203A134->playerIsSender)
{
StringCopy(ptr, gText_FromSpace);
gUnknown_0203A134->signatureWidth = gUnknown_0203A134->layout->signatureWidth - (StringLength(gUnknown_0203A134->playerName) * 8 - 0x60);
}
else
{
sub_81DB52C(gUnknown_0203A134->playerName);
gUnknown_0203A134->signatureWidth = gUnknown_0203A134->layout->signatureWidth;
}
}
void sub_8121B1C(void)
{
u16 i;
u8 strbuf[0x20];
u8 y;
u8 *bufptr;
s32 box_x;
s32 box_y;
y = 0;
PutWindowTilemap(0);
PutWindowTilemap(1);
FillWindowPixelBuffer(0, 0);
FillWindowPixelBuffer(1, 0);
for (i = 0; i < gUnknown_0203A134->layout->numSubStructs; i ++)
{
if (gUnknown_0203A134->strbuf[i][0] == EOS || gUnknown_0203A134->strbuf[i][0] == CHAR_SPACE)
{
continue;
}
box_print(0, 1, gUnknown_0203A134->layout->var8[i].xOffset + gUnknown_0203A134->layout->wordsYPos, y + gUnknown_0203A134->layout->wordsXPos, gUnknown_0859F2AC, 0, gUnknown_0203A134->strbuf[i]);
y += gUnknown_0203A134->layout->var8[i].lineHeight;
}
bufptr = StringCopy(strbuf, gText_FromSpace);
StringCopy(bufptr, gUnknown_0203A134->playerName);
box_x = GetStringCenterAlignXOffset(1, strbuf, gUnknown_0203A134->signatureWidth) + 0x68;
box_y = gUnknown_0203A134->layout->signatureYPos + 0x58;
box_print(0, 1, box_x, box_y, gUnknown_0859F2AC, 0, strbuf);
CopyWindowToVram(0, 3);
CopyWindowToVram(1, 3);
}
void sub_8121C50(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
void sub_8121C64(void)
{
if (gUnknown_0203A134->animsActive != 0)
{
AnimateSprites();
BuildOamBuffer();
}
gUnknown_0203A134->callback2();
}
void sub_8121C98(void)
{
if (!UpdatePaletteFade())
{
gUnknown_0203A134->callback2 = sub_8121CC0;
}
}
void sub_8121CC0(void)
{
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
BeginNormalPaletteFade(-1, 0, 0, 16, 0);
gUnknown_0203A134->callback2 = sub_8121D00;
}
}
void sub_8121D00(void)
{
if (!UpdatePaletteFade())
{
SetMainCallback2(gUnknown_0203A134->callback);
switch (gUnknown_0203A134->animsActive)
{
case 1:
case 2:
sub_80D2FF0(sub_80D2E84(gUnknown_0203A134->mail->species));
sub_80D2EF8(&gSprites[gUnknown_0203A134->monIconSprite]);
}
memset(gUnknown_0203A134, 0, sizeof(*gUnknown_0203A134));
ResetPaletteFade();
UnsetBgTilemapBuffer(0);
UnsetBgTilemapBuffer(1);
ResetBgsAndClearDma3BusyFlags(0);
FreeAllWindowBuffers();
free(gUnknown_0203A134);
gUnknown_0203A134 = NULL;
}
}

View File

@@ -33,7 +33,7 @@ void ZeroMonData(struct Pokemon *mon)
SetMonData(mon, MON_DATA_MAX_HP, &arg);
SetMonData(mon, MON_DATA_ATK, &arg);
SetMonData(mon, MON_DATA_DEF, &arg);
SetMonData(mon, MON_DATA_SPD, &arg);
SetMonData(mon, MON_DATA_SPEED, &arg);
SetMonData(mon, MON_DATA_SPATK, &arg);
SetMonData(mon, MON_DATA_SPDEF, &arg);
arg = 255;
@@ -128,7 +128,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
SetBoxMonData(boxMon, MON_DATA_HP_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_ATK_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_DEF_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_SPD_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &fixedIV);
}
@@ -147,7 +147,7 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
value = Random();
iv = value & 0x1F;
SetBoxMonData(boxMon, MON_DATA_SPD_IV, &iv);
SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &iv);
iv = (value & 0x3E0) >> 5;
SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv);
iv = (value & 0x7C00) >> 10;
@@ -234,7 +234,7 @@ void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u
SetMonData(mon, MON_DATA_HP_IV, &ivs[0]);
SetMonData(mon, MON_DATA_ATK_IV, &ivs[1]);
SetMonData(mon, MON_DATA_DEF_IV, &ivs[2]);
SetMonData(mon, MON_DATA_SPD_IV, &ivs[3]);
SetMonData(mon, MON_DATA_SPEED_IV, &ivs[3]);
SetMonData(mon, MON_DATA_SPATK_IV, &ivs[4]);
SetMonData(mon, MON_DATA_SPDEF_IV, &ivs[5]);
CalculateMonStats(mon);
@@ -305,7 +305,7 @@ void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src)
SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
SetMonData(mon, MON_DATA_SPD_EV, &src->speedEV);
SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV);
SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
value = src->altAbility;
@@ -317,7 +317,7 @@ void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src)
value = src->defenseIV;
SetMonData(mon, MON_DATA_DEF_IV, &value);
value = src->speedIV;
SetMonData(mon, MON_DATA_SPD_IV, &value);
SetMonData(mon, MON_DATA_SPEED_IV, &value);
value = src->spAttackIV;
SetMonData(mon, MON_DATA_SPATK_IV, &value);
value = src->spDefenseIV;
@@ -369,7 +369,7 @@ void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lv
SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
SetMonData(mon, MON_DATA_SPD_EV, &src->speedEV);
SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV);
SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
value = src->altAbility;
@@ -381,7 +381,7 @@ void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lv
value = src->defenseIV;
SetMonData(mon, MON_DATA_DEF_IV, &value);
value = src->speedIV;
SetMonData(mon, MON_DATA_SPD_IV, &value);
SetMonData(mon, MON_DATA_SPEED_IV, &value);
value = src->spAttackIV;
SetMonData(mon, MON_DATA_SPATK_IV, &value);
value = src->spDefenseIV;

View File

@@ -330,7 +330,7 @@ u32 GetMonData(struct Pokemon *mon, s32 field, u8* data)
if (!ret)
ret = mon->defense;
break;
case MON_DATA_SPD:
case MON_DATA_SPEED:
ret = GetDeoxysStat(mon, STAT_SPD);
if (!ret)
ret = mon->speed;
@@ -351,7 +351,7 @@ u32 GetMonData(struct Pokemon *mon, s32 field, u8* data)
case MON_DATA_DEF2:
ret = mon->defense;
break;
case MON_DATA_SPD2:
case MON_DATA_SPEED2:
ret = mon->speed;
break;
case MON_DATA_SPATK2:
@@ -512,7 +512,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data)
case MON_DATA_DEF_EV:
retVal = substruct2->defenseEV;
break;
case MON_DATA_SPD_EV:
case MON_DATA_SPEED_EV:
retVal = substruct2->speedEV;
break;
case MON_DATA_SPATK_EV:
@@ -566,7 +566,7 @@ u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data)
case MON_DATA_DEF_IV:
retVal = substruct3->defenseIV;
break;
case MON_DATA_SPD_IV:
case MON_DATA_SPEED_IV:
retVal = substruct3->speedIV;
break;
case MON_DATA_SPATK_IV:
@@ -747,7 +747,7 @@ void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg)
case MON_DATA_DEF:
SET16(mon->defense);
break;
case MON_DATA_SPD:
case MON_DATA_SPEED:
SET16(mon->speed);
break;
case MON_DATA_SPATK:
@@ -880,7 +880,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
case MON_DATA_DEF_EV:
SET8(substruct2->defenseEV);
break;
case MON_DATA_SPD_EV:
case MON_DATA_SPEED_EV:
SET8(substruct2->speedEV);
break;
case MON_DATA_SPATK_EV:
@@ -940,7 +940,7 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
case MON_DATA_DEF_IV:
SET8(substruct3->defenseIV);
break;
case MON_DATA_SPD_IV:
case MON_DATA_SPEED_IV:
SET8(substruct3->speedIV);
break;
case MON_DATA_SPATK_IV:
@@ -1329,7 +1329,7 @@ void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex)
gBattleMons[bank].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL);
gBattleMons[bank].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL);
gBattleMons[bank].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL);
gBattleMons[bank].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPD_IV, NULL);
gBattleMons[bank].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL);
gBattleMons[bank].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL);
gBattleMons[bank].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL);
gBattleMons[bank].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL);
@@ -1339,7 +1339,7 @@ void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex)
gBattleMons[bank].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL);
gBattleMons[bank].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL);
gBattleMons[bank].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL);
gBattleMons[bank].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPD, NULL);
gBattleMons[bank].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL);
gBattleMons[bank].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL);
gBattleMons[bank].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL);
gBattleMons[bank].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL);

View File

@@ -57,7 +57,7 @@ static u32 GetMonSizeHash(struct Pokemon *pkmn)
u16 hpIV = GetMonData(pkmn, MON_DATA_HP_IV) & 0xF;
u16 attackIV = GetMonData(pkmn, MON_DATA_ATK_IV) & 0xF;
u16 defenseIV = GetMonData(pkmn, MON_DATA_DEF_IV) & 0xF;
u16 speedIV = GetMonData(pkmn, MON_DATA_SPD_IV) & 0xF;
u16 speedIV = GetMonData(pkmn, MON_DATA_SPEED_IV) & 0xF;
u16 spAtkIV = GetMonData(pkmn, MON_DATA_SPATK_IV) & 0xF;
u16 spDefIV = GetMonData(pkmn, MON_DATA_SPDEF_IV) & 0xF;
u32 hibyte = ((attackIV ^ defenseIV) * hpIV) ^ (personality & 0xFF);

3679
src/pokemon_summary_screen.c Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -336,9 +336,9 @@ static void CreateHealthboxSprite(u8 bank)
UpdateHealthboxAttribute(gHealthBoxesIds[bank], &gPlayerParty[gBattlePartyID[bank]], HEALTHBOX_ALL);
if (GetBankIdentity(bank) == IDENTITY_OPPONENT_MON2 || GetBankIdentity(bank) == IDENTITY_PLAYER_MON2)
nullsub_30(gHealthBoxesIds[bank], TRUE);
DummyBattleInterfaceFunc(gHealthBoxesIds[bank], TRUE);
else
nullsub_30(gHealthBoxesIds[bank], FALSE);
DummyBattleInterfaceFunc(gHealthBoxesIds[bank], FALSE);
if (GetBankSide(bank) != SIDE_PLAYER)
{

View File

@@ -139,7 +139,7 @@ static void ClearAllPokeblockFeeders(void)
memset(sPokeblockFeeders, 0, sizeof(sPokeblockFeeders));
}
static void GetPokeblockFeederInFront(void)
void GetPokeblockFeederInFront(void)
{
s16 x, y;
u16 i;

View File

@@ -594,7 +594,7 @@ u8 CreateSpriteAt(u8 index, const struct SpriteTemplate *template, s16 x, s16 y,
return index;
}
u8 CreateSpriteAndAnimate(struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority)
u8 CreateSpriteAndAnimate(const struct SpriteTemplate *template, s16 x, s16 y, u8 subpriority)
{
u8 i;

View File

@@ -207,7 +207,7 @@ static bool32 PrintStartMenuItemsMultistep(s16 *index, u32 n)
do
{
if (sStartMenuItems[sCurrentStartMenuActions[_index]].func == StartMenu_PlayerName)
if (sStartMenuItems[sCurrentStartMenuActions[_index]].func.u8_void == StartMenu_PlayerName)
{
}

View File

@@ -2353,7 +2353,7 @@ void sub_80EDFB4(TVShow *show)
show->secretBaseVisit.move = sTV_SecretBaseVisitMonsTemp[j].move;
}
void sub_80EE104(void)
void TV_PutSecretBaseVisitOnTheAir(void)
{
TVShow *show;

257
src/walda_phrase.c Normal file
View File

@@ -0,0 +1,257 @@
#include "global.h"
#include "walda_phrase.h"
#include "string_util.h"
#include "event_data.h"
#include "naming_screen.h"
#include "main.h"
#include "text.h"
#include "new_game.h"
extern void (*gFieldCallback)(void);
extern const u8 gText_Peekaboo[];
extern u8 *GetWaldaPhrasePtr(void);
extern bool32 IsWaldaPhraseEmpty(void);
extern void sub_80AF168(void);
extern void c2_exit_to_overworld_2_switch(void);
extern void SetWaldaPhrase(const u8 *src);
extern void SetWaldaWallpaperPatternId(u8 patternId);
extern void SetWaldaWallpaperIconId(u8 iconId);
extern void SetWaldaWallpaperColors(u16 backgroundColor, u16 foregroundColor);
extern void SetWaldaWallpaperLockedOrUnlocked(bool32 unlocked);
// this file's functions
static void CB2_HandleGivenWaldaPhrase(void);
static u32 GetWaldaPhraseInputCase(u8 *inputPtr);
static bool32 TryCalculateWallpaper(u16* backgroundClr, u16 *foregroundClr, u8 *iconId, u8 *patternId, u16 trainerId, u8 *phrase);
static void sub_81D9D5C(u8 *array, u8 *letterTableIds, u32 arg2, u32 arg3, u32 loopCount);
static u32 sub_81D9DAC(u8 *array, u32 arg1, u32 loopCount);
static void sub_81D9C90(u8 *array, s32 arg1, s32 arg2);
static void sub_81D9CDC(u8 *array, u32 loopCount, u8 arg2);
// only consonants are allowed, no vowels, some lowercase letters are missing
static const u8 sWaldaLettersTable[] =
{
CHAR_B, CHAR_C, CHAR_D, CHAR_F, CHAR_G, CHAR_H, CHAR_J, CHAR_K, CHAR_L, CHAR_M, CHAR_N, CHAR_P, CHAR_Q, CHAR_R, CHAR_S, CHAR_T, CHAR_V, CHAR_W, CHAR_Z,
CHAR_b, CHAR_c, CHAR_d, CHAR_f, CHAR_g, CHAR_h, CHAR_j, CHAR_k, CHAR_m, CHAR_n, CHAR_p, CHAR_q, CHAR_s
};
enum
{
PHRASE_GIVEN_NEW,
PHRASE_NO_CHANGE,
PHRASE_FIRST_ATTEMPT
};
u16 TryBufferWaldaPhrase(void)
{
if (IsWaldaPhraseEmpty())
return FALSE;
StringCopy(gStringVar1, GetWaldaPhrasePtr());
return TRUE;
}
void DoWaldaNamingScreen(void)
{
StringCopy(gStringVar2, GetWaldaPhrasePtr());
DoNamingScreen(NAMING_SCREEN_WALDA, gStringVar2, 0, 0, 0, CB2_HandleGivenWaldaPhrase);
}
static void CB2_HandleGivenWaldaPhrase(void)
{
gSpecialVar_0x8004 = GetWaldaPhraseInputCase(gStringVar2);
switch (gSpecialVar_0x8004)
{
case PHRASE_FIRST_ATTEMPT:
if (IsWaldaPhraseEmpty())
SetWaldaPhrase(gText_Peekaboo);
else
gSpecialVar_0x8004 = PHRASE_NO_CHANGE;
break;
case PHRASE_GIVEN_NEW:
SetWaldaPhrase(gStringVar2);
break;
case PHRASE_NO_CHANGE:
break;
}
StringCopy(gStringVar1, GetWaldaPhrasePtr());
gFieldCallback = sub_80AF168;
SetMainCallback2(c2_exit_to_overworld_2_switch);
}
static u32 GetWaldaPhraseInputCase(u8 *inputPtr)
{
if (inputPtr[0] == EOS)
return PHRASE_FIRST_ATTEMPT;
if (StringCompare(inputPtr, GetWaldaPhrasePtr()) == 0)
return PHRASE_NO_CHANGE;
return PHRASE_GIVEN_NEW;
}
u16 TryGetWallpaperWithWaldaPhrase(void)
{
u16 backgroundClr, foregroundClr;
u8 patternId, iconId;
u16 trainerId = ReadUnalignedWord(gSaveBlock2Ptr->playerTrainerId);
gScriptResult = TryCalculateWallpaper(&backgroundClr, &foregroundClr, &iconId, &patternId, trainerId, GetWaldaPhrasePtr());
if (gScriptResult)
{
SetWaldaWallpaperPatternId(patternId);
SetWaldaWallpaperIconId(iconId);
SetWaldaWallpaperColors(backgroundClr, foregroundClr);
}
SetWaldaWallpaperLockedOrUnlocked(gScriptResult);
return (bool8)(gScriptResult);
}
static u8 GetLetterTableId(u8 letter)
{
s32 i;
for (i = 0; i < ARRAY_COUNT(sWaldaLettersTable); i++)
{
if (sWaldaLettersTable[i] == letter)
return i;
}
return ARRAY_COUNT(sWaldaLettersTable);
}
static bool32 TryCalculateWallpaper(u16* backgroundClr, u16 *foregroundClr, u8 *iconId, u8 *patternId, u16 trainerId, u8 *phrase)
{
s32 i;
ALIGNED(2) u8 array[12];
u8 charsByTableId[16];
u16 *ptr;
if (StringLength(phrase) != 15)
return FALSE;
for (i = 0; i < 15; i++)
{
charsByTableId[i] = GetLetterTableId(phrase[i]);
if (charsByTableId[i] == ARRAY_COUNT(sWaldaLettersTable))
return FALSE;
}
for (i = 0; i < 14; i++)
{
sub_81D9D5C(array, charsByTableId, (5 * i), 3 + (8 * i), 5);
}
sub_81D9D5C(array, charsByTableId, 70, 115, 2);
if (sub_81D9DAC(array, 0, 3) != sub_81D9DAC(charsByTableId, 117, 3))
return FALSE;
sub_81D9C90(array, 9, 21);
sub_81D9C90(array, 8, array[8] & 0xF);
sub_81D9CDC(array, 8, array[8] >> 4);
if (array[6] != (array[0] ^ array[2] ^ array[4] ^ (trainerId >> 8)))
return FALSE;
if (array[7] != (array[1] ^ array[3] ^ array[5] ^ (trainerId & 0xFF)))
return FALSE;
ptr = (u16*)(&array[0]);
*backgroundClr = *ptr;
ptr = (u16*)(&array[2]);
*foregroundClr = *ptr;
*iconId = array[4];
*patternId = array[5];
return TRUE;
}
static void sub_81D9C90(u8 *array, s32 arg1, s32 arg2)
{
s32 i, j;
u8 var1, var2;
for (i = arg2 - 1; i != -1; i--)
{
var1 = (array[0] & 0x80) >> 7;
var1++; var1--; // needed to match
for (j = arg1 - 1; j >= 0; j--)
{
var2 = array[j] & 0x80;
array[j] <<= 1;
array[j] |= var1;
var1 = var2 >> 7;
}
}
}
static void sub_81D9CDC(u8 *array, u32 loopCount, u8 arg2)
{
u32 i;
arg2 |= (arg2 << 4);
for (i = 0; i < loopCount; i++)
{
array[i] ^= arg2;
}
}
static bool8 sub_81D9D0C(u8 *array, u32 arg1)
{
u32 arrayId = arg1 >> 3;
u32 bits = 0x80 >> (7 & arg1);
return ((array[arrayId] & bits) != 0);
}
static void sub_81D9D28(u8 *array, u32 arg1)
{
u32 arrayId = arg1 >> 3;
u8 bits = 0x80 >> (7 & arg1);
array[arrayId] |= bits;
}
static void sub_81D9D40(u8 *array, u32 arg1)
{
u32 arrayId = arg1 >> 3;
u8 bits = ~(0x80 >> (7 & arg1));
array[arrayId] &= bits;
}
static void sub_81D9D5C(u8 *array, u8 *letterTableIds, u32 arg2, u32 arg3, u32 loopCount)
{
u32 i;
for (i = 0; i < loopCount; i++)
{
if (sub_81D9D0C(letterTableIds, arg3 + i))
sub_81D9D28(array, arg2 + i);
else
sub_81D9D40(array, arg2 + i);
}
}
static u32 sub_81D9DAC(u8 *array, u32 arg1, u32 loopCount)
{
u32 ret, i;
for (ret = 0, i = 0; i < loopCount; i++)
{
ret <<= 1;
ret |= sub_81D9D0C(array, arg1 + i);
}
return ret;
}