pokeemerald/src/berry_fix_program.c

308 lines
9.8 KiB
C
Raw Normal View History

2017-09-18 14:52:57 +02:00
#include "global.h"
#include "gpu_regs.h"
2017-09-18 17:26:45 +02:00
#include "multiboot.h"
#include "malloc.h"
2017-09-18 17:26:45 +02:00
#include "bg.h"
2018-10-21 09:24:57 +02:00
#include "graphics.h"
2017-09-18 14:52:57 +02:00
#include "main.h"
#include "sprite.h"
#include "task.h"
2018-01-29 17:47:12 +01:00
#include "scanline_effect.h"
2017-09-18 17:26:45 +02:00
#include "window.h"
2017-11-19 22:48:46 +01:00
#include "text.h"
2017-09-18 17:26:45 +02:00
#include "menu.h"
2017-09-18 14:52:57 +02:00
#include "m4a.h"
// Static type declarations
typedef struct {
u8 state;
u8 unk1;
u16 unk2;
struct MultiBootParam mb;
} berryfix_t;
// Static RAM declarations
static berryfix_t *berry_fix_mb_manager;
2017-09-18 14:52:57 +02:00
// Static ROM declarations
static void berry_fix_main(void);
static void berry_fix_gpu_set(void);
static int berry_fix_text_update(int);
static void berry_fix_text_print(int);
static void berry_fix_bg_hide(void);
2017-09-18 14:52:57 +02:00
// .rodata
2019-12-10 19:48:20 +01:00
static const u8 sText_BerryProgramUpdate[] = _("Berry Program Update");
static const u8 sText_RubySapphire[] = _("Ruby/Sapphire");
static const u8 sText_Emerald[] = _("Emerald");
2017-09-18 21:10:25 +02:00
2019-12-10 19:48:20 +01:00
static const u8 sText_BerryProgramWillBeUpdatedPressA[] = _("The Berry Program on your POKéMON\nRuby/Sapphire Game Pak will be updated.\n{COLOR RED}{SHADOW LIGHT_RED}Press the A Button.");
static const u8 sText_EnsureGBAConnectionMatches[] = _("Please ensure the connection of your\nGame Boy Advance system matches this.\n{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\nNO: Turn off the power and try again.");
static const u8 sText_TurnOffPowerHoldingStartSelect[] = _("Please turn on the power of POKéMON\nRuby/Sapphire while holding START and\nSELECT simultaneously. Then, ensure\nthe picture above appears.");
static const u8 sText_TransmittingPleaseWait[] = _("Transmitting. Please wait.\n{COLOR RED}{SHADOW LIGHT_RED}Please do not turn off the power or\nunplug the Game Boy Advance Game\nLink Cable.");
static const u8 sText_PleaseFollowInstructionsOnScreen[] = _("Please follow the instructions on your\nPOKéMON Ruby/Sapphire screen.");
static const u8 sText_TransmissionFailureTryAgain[] = _("Transmission failure.\n{COLOR RED}{SHADOW LIGHT_RED}Please try again.");
2017-09-18 21:10:25 +02:00
static const struct BgTemplate gUnknown_08618108[] = {
2017-09-18 21:10:25 +02:00
{
0, 0, 30, 0, 0, 0
}, {
1, 1, 31, 0, 0, 1
}
};
static const struct WindowTemplate gUnknown_08618110[] = {
2017-09-18 21:10:25 +02:00
{0, 2, 4, 26, 2, 15, 0x001},
{0, 1, 11, 28, 8, 15, 0x035},
{0, 0, 8, 30, 2, 15, 0x115},
{0, 8, 0, 14, 2, 15, 0x151},
{-1}
};
2017-12-17 23:45:27 +01:00
static const u16 sUnknown_08618138[] = {
2017-09-18 21:10:25 +02:00
0x7fff, 0x7fff, 0x318c, 0x675a,
0x043c, 0x3aff, 0x0664, 0x4bd2,
0x6546, 0x7b14, 0x7fff, 0x318c,
2018-12-26 13:43:07 +01:00
0x675a, 0, 0, 0
2017-09-18 21:10:25 +02:00
};
2019-12-10 19:48:20 +01:00
static const u8 sBerryProgramTextColors[] = {TEXT_DYNAMIC_COLOR_1, TEXT_DYNAMIC_COLOR_2, TEXT_DYNAMIC_COLOR_3};
static const u8 sGameTitleTextColors[] = { TEXT_COLOR_TRANSPARENT, TEXT_DYNAMIC_COLOR_1, TEXT_DYNAMIC_COLOR_4};
2017-09-18 21:10:25 +02:00
2019-12-10 19:48:20 +01:00
static const u8 *const sBerryProgramTexts[] = {
sText_EnsureGBAConnectionMatches,
sText_TurnOffPowerHoldingStartSelect,
sText_TransmittingPleaseWait,
sText_PleaseFollowInstructionsOnScreen,
sText_TransmissionFailureTryAgain,
sText_BerryProgramWillBeUpdatedPressA
2017-09-18 21:10:25 +02:00
};
2018-10-21 09:24:57 +02:00
static const void *const gUnknown_08618178[][3] = {
2017-09-18 21:10:25 +02:00
{
2017-12-30 07:09:06 +01:00
gBerryFixGameboy_Gfx,
gBerryFixGameboy_Tilemap,
gBerryFixGameboy_Pal
2017-09-18 21:10:25 +02:00
}, {
2017-12-30 07:09:06 +01:00
gBerryFixGameboyLogo_Gfx,
gBerryFixGameboyLogo_Tilemap,
gBerryFixGameboyLogo_Pal
2017-09-18 21:10:25 +02:00
}, {
2017-12-30 07:09:06 +01:00
gBerryFixGbaTransfer_Gfx,
gBerryFixGbaTransfer_Tilemap,
gBerryFixGbaTransfer_Pal
2017-09-18 21:10:25 +02:00
}, {
2017-12-30 07:09:06 +01:00
gBerryFixGbaTransferHighlight_Gfx,
gBerryFixGbaTransferHighlight_Tilemap,
gBerryFixGbaTransferHighlight_Pal
2017-09-18 21:10:25 +02:00
}, {
2017-12-30 07:09:06 +01:00
gBerryFixGbaTransferError_Gfx,
gBerryFixGbaTransferError_Tilemap,
gBerryFixGbaTransferError_Pal
2017-09-18 21:10:25 +02:00
}, {
2017-12-30 07:09:06 +01:00
gBerryFixWindow_Gfx,
gBerryFixWindow_Tilemap,
gBerryFixWindow_Pal
2017-09-18 21:10:25 +02:00
},
};
2017-09-25 23:26:45 +02:00
extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3BF4];
2017-09-18 14:52:57 +02:00
extern const u8 gMultiBootProgram_BerryGlitchFix_End[];
// .text
2018-02-04 16:11:00 +01:00
void CB2_InitBerryFixProgram(void)
2017-09-18 14:52:57 +02:00
{
DisableInterrupts(0xFFFF);
EnableInterrupts(0x0001);
m4aSoundVSyncOff();
SetVBlankCallback(NULL);
ResetSpriteData();
ResetTasks();
2018-01-16 18:59:06 +01:00
ScanlineEffect_Stop();
2018-12-26 13:43:07 +01:00
SetGpuReg(REG_OFFSET_DISPCNT, 0);
berry_fix_mb_manager = AllocZeroed(0x50);
berry_fix_mb_manager->state = 0;
berry_fix_mb_manager->unk1 = 6;
SetMainCallback2(berry_fix_main);
2017-09-18 14:52:57 +02:00
}
static void berry_fix_main(void)
2017-09-18 14:52:57 +02:00
{
switch (berry_fix_mb_manager->state)
2017-09-18 14:52:57 +02:00
{
case 0:
berry_fix_gpu_set();
berry_fix_mb_manager->state = 1;
2017-09-18 14:52:57 +02:00
break;
case 1:
if (berry_fix_text_update(5) == 5 && (gMain.newKeys & A_BUTTON))
2017-09-18 14:52:57 +02:00
{
berry_fix_mb_manager->state = 2;
2017-09-18 14:52:57 +02:00
}
break;
case 2:
if (berry_fix_text_update(0) == 0 && (gMain.newKeys & A_BUTTON))
2017-09-18 14:52:57 +02:00
{
berry_fix_mb_manager->state = 3;
2017-09-18 14:52:57 +02:00
}
break;
case 3:
if (berry_fix_text_update(1) == 1)
2017-09-18 14:52:57 +02:00
{
2017-09-25 23:26:45 +02:00
berry_fix_mb_manager->mb.masterp = gMultiBootProgram_BerryGlitchFix_Start;
berry_fix_mb_manager->mb.server_type = 0;
MultiBootInit(&berry_fix_mb_manager->mb);
berry_fix_mb_manager->unk2 = 0;
berry_fix_mb_manager->state = 4;
2017-09-18 14:52:57 +02:00
}
break;
case 4:
MultiBootMain(&berry_fix_mb_manager->mb);
if (berry_fix_mb_manager->mb.probe_count != 0 || (!(berry_fix_mb_manager->mb.response_bit & 2) || !(berry_fix_mb_manager->mb.client_bit & 2)))
2017-09-18 14:52:57 +02:00
{
berry_fix_mb_manager->unk2 = 0;
2017-09-18 14:52:57 +02:00
}
else if (++ berry_fix_mb_manager->unk2 > 180)
2017-09-18 14:52:57 +02:00
{
2017-09-25 23:26:45 +02:00
MultiBootStartMaster(&berry_fix_mb_manager->mb, gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE, (u32)(gMultiBootProgram_BerryGlitchFix_End - (gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE)), 4, 1);
berry_fix_mb_manager->state = 5;
2017-09-18 14:52:57 +02:00
}
break;
case 5:
if (berry_fix_text_update(2) == 2) {
MultiBootMain(&berry_fix_mb_manager->mb);
if (MultiBootCheckComplete(&berry_fix_mb_manager->mb)) {
berry_fix_mb_manager->state = 6;
2017-09-18 14:52:57 +02:00
}
else if (!(berry_fix_mb_manager->mb.client_bit & 2)) {
berry_fix_mb_manager->state = 7;
2017-09-18 14:52:57 +02:00
}
}
break;
case 6:
if (berry_fix_text_update(3) == 3 && gMain.newKeys & A_BUTTON)
2017-09-18 14:52:57 +02:00
{
DoSoftReset();
}
break;
case 7:
if (berry_fix_text_update(4) == 4 && gMain.newKeys & A_BUTTON)
2017-09-18 14:52:57 +02:00
{
berry_fix_mb_manager->state = 1;
2017-09-18 14:52:57 +02:00
}
break;
}
}
2017-09-18 17:26:45 +02:00
static void berry_fix_gpu_set(void)
2017-09-18 17:26:45 +02:00
{
2018-02-07 15:02:47 +01:00
s32 width, left;
2017-09-18 17:26:45 +02:00
2018-12-26 13:43:07 +01:00
SetGpuReg(REG_OFFSET_BG0CNT, 0);
SetGpuReg(REG_OFFSET_BG1CNT, 0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
SetGpuReg(REG_OFFSET_BG1HOFS, 0);
SetGpuReg(REG_OFFSET_BG1VOFS, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
2017-09-18 17:26:45 +02:00
DmaFill32(3, 0, VRAM, VRAM_SIZE);
DmaFill32(3, 0, OAM, OAM_SIZE);
DmaFill32(3, 0, PLTT, PLTT_SIZE);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_08618108, ARRAY_COUNT(gUnknown_08618108));
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
ChangeBgX(1, 0, 0);
ChangeBgY(1, 0, 0);
InitWindows(gUnknown_08618110);
DeactivateAllTextPrinters();
2017-12-17 23:45:27 +01:00
DmaCopy32(3, sUnknown_08618138, BG_PLTT + 0x1E0, 0x20);
2017-09-18 17:26:45 +02:00
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP);
FillWindowPixelBuffer(2, PIXEL_FILL(0));
FillWindowPixelBuffer(3, PIXEL_FILL(0));
FillWindowPixelBuffer(0, PIXEL_FILL(0xA));
2017-09-18 17:26:45 +02:00
2019-12-10 19:48:20 +01:00
width = GetStringWidth(0, sText_Emerald, 0);
2018-02-07 15:02:47 +01:00
left = (0x78 - width) / 2;
2019-12-10 19:48:20 +01:00
AddTextPrinterParameterized3(2, 0, left, 3, sGameTitleTextColors, TEXT_SPEED_FF, sText_Emerald);
2018-02-07 15:02:47 +01:00
2019-12-10 19:48:20 +01:00
width = GetStringWidth(0, sText_RubySapphire, 0);
2018-02-07 15:02:47 +01:00
left = (0x78 - width) / 2 + 0x78;
2019-12-10 19:48:20 +01:00
AddTextPrinterParameterized3(2, 0, left, 3, sGameTitleTextColors, TEXT_SPEED_FF, sText_RubySapphire);
2018-02-07 15:02:47 +01:00
2019-12-10 19:48:20 +01:00
width = GetStringWidth(0, sText_RubySapphire, 0);
2018-02-07 15:02:47 +01:00
left = (0x70 - width) / 2;
2019-12-10 19:48:20 +01:00
AddTextPrinterParameterized3(3, 0, left, 0, sGameTitleTextColors, TEXT_SPEED_FF, sText_RubySapphire);
2018-02-07 15:02:47 +01:00
2019-12-10 19:48:20 +01:00
width = GetStringWidth(1, sText_BerryProgramUpdate, 0);
2018-02-07 15:02:47 +01:00
left = (0xD0 - width) / 2;
2019-12-10 19:48:20 +01:00
AddTextPrinterParameterized3(0, 1, left, 2, sBerryProgramTextColors, TEXT_SPEED_FF, sText_BerryProgramUpdate);
2017-09-18 17:26:45 +02:00
CopyWindowToVram(2, 2);
CopyWindowToVram(3, 2);
CopyWindowToVram(0, 2);
}
2017-09-18 19:54:39 +02:00
static int berry_fix_text_update(int checkval)
2017-09-18 19:54:39 +02:00
{
if (berry_fix_mb_manager->unk1 == checkval)
2017-09-18 20:07:34 +02:00
{
return checkval;
}
if (berry_fix_mb_manager->unk1 == 6)
2017-09-18 20:07:34 +02:00
{
berry_fix_text_print(checkval);
berry_fix_mb_manager->unk1 = checkval;
2017-09-18 20:07:34 +02:00
}
else
{
berry_fix_bg_hide();
berry_fix_mb_manager->unk1 = 6;
2017-09-18 20:07:34 +02:00
}
return berry_fix_mb_manager->unk1;
2017-09-18 19:54:39 +02:00
}
static void berry_fix_text_print(int scene)
2017-09-18 20:04:00 +02:00
{
FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32);
FillWindowPixelBuffer(1, PIXEL_FILL(0xA));
2019-12-10 19:48:20 +01:00
AddTextPrinterParameterized3(1, 1, 0, 0, sBerryProgramTextColors, -1, sBerryProgramTexts[scene]);
2017-09-18 20:04:00 +02:00
PutWindowTilemap(1);
CopyWindowToVram(1, 2);
switch (scene)
{
case 0:
case 2:
case 3:
case 4:
PutWindowTilemap(2);
break;
case 1:
PutWindowTilemap(3);
break;
case 5:
PutWindowTilemap(0);
break;
}
CopyBgTilemapBufferToVram(0);
LZ77UnCompVram(gUnknown_08618178[scene][0], (void *)BG_CHAR_ADDR(1));
LZ77UnCompVram(gUnknown_08618178[scene][1], (void *)BG_SCREEN_ADDR(31));
CpuCopy32(gUnknown_08618178[scene][2], (void *)BG_PLTT, 0x100);
ShowBg(0);
ShowBg(1);
}
2017-09-18 20:07:34 +02:00
2018-02-07 15:02:47 +01:00
static void berry_fix_bg_hide(void)
2017-09-18 20:07:34 +02:00
{
HideBg(0);
HideBg(1);
}