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"
2019-09-09 03:07:54 +02:00
# 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
2017-09-18 21:28:55 +02:00
static berryfix_t * berry_fix_mb_manager ;
2017-09-18 14:52:57 +02:00
// Static ROM declarations
2017-09-18 21:28:55 +02:00
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 \n Ruby/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 \n Game Boy Advance system matches this. \n {COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button. \n NO: Turn off the power and try again. " ) ;
static const u8 sText_TurnOffPowerHoldingStartSelect [ ] = _ ( " Please turn on the power of POKéMON \n Ruby/Sapphire while holding START and \n SELECT simultaneously. Then, ensure \n the 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 \n unplug the Game Boy Advance Game \n Link Cable. " ) ;
static const u8 sText_PleaseFollowInstructionsOnScreen [ ] = _ ( " Please follow the instructions on your \n POKé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
2020-02-07 23:12:27 +01:00
static const struct BgTemplate sBerryFixBgTemplates [ ] = {
2017-09-18 21:10:25 +02:00
{
2020-02-07 23:12:27 +01:00
. bg = 0 ,
. charBaseIndex = 0 ,
. mapBaseIndex = 30 ,
. screenSize = 0 ,
. paletteMode = 0 ,
. priority = 0 ,
. baseTile = 0
} ,
{
. bg = 1 ,
. charBaseIndex = 1 ,
. mapBaseIndex = 31 ,
. screenSize = 0 ,
. paletteMode = 0 ,
. priority = 1 ,
. baseTile = 0
2017-09-18 21:10:25 +02:00
}
} ;
2020-02-07 23:12:27 +01:00
static const struct WindowTemplate sBerryFixWindowTemplates [ ] = {
{
. bg = 0 ,
. tilemapLeft = 2 ,
. tilemapTop = 4 ,
. width = 26 ,
. height = 2 ,
. paletteNum = 15 ,
. baseBlock = 1
} ,
{
. bg = 0 ,
. tilemapLeft = 1 ,
. tilemapTop = 11 ,
. width = 28 ,
. height = 8 ,
. paletteNum = 15 ,
. baseBlock = 53
} ,
{
. bg = 0 ,
. tilemapLeft = 0 ,
. tilemapTop = 8 ,
. width = 30 ,
. height = 2 ,
. paletteNum = 15 ,
. baseBlock = 277
} ,
{
. bg = 0 ,
. tilemapLeft = 8 ,
. tilemapTop = 0 ,
. width = 14 ,
. height = 2 ,
. paletteNum = 15 ,
. baseBlock = 337
} ,
DUMMY_WIN_TEMPLATE
2017-09-18 21:10:25 +02:00
} ;
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
} ;
2020-02-07 23:12:27 +01:00
static const struct {
const u32 * gfx ;
const u32 * tilemap ;
const u16 * pltt ;
} sBerryFixGraphics [ ] = {
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
{
2020-02-07 23:12:27 +01:00
DisableInterrupts ( 0xFFFF ) ; // all
EnableInterrupts ( INTR_FLAG_VBLANK ) ;
2017-09-18 14:52:57 +02:00
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 ) ;
2017-09-18 21:28:55 +02:00
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
}
2017-09-18 21:28:55 +02:00
static void berry_fix_main ( void )
2017-09-18 14:52:57 +02:00
{
2017-09-18 21:28:55 +02:00
switch ( berry_fix_mb_manager - > state )
2017-09-18 14:52:57 +02:00
{
case 0 :
2017-09-18 21:28:55 +02:00
berry_fix_gpu_set ( ) ;
berry_fix_mb_manager - > state = 1 ;
2017-09-18 14:52:57 +02:00
break ;
case 1 :
2017-09-18 21:28:55 +02:00
if ( berry_fix_text_update ( 5 ) = = 5 & & ( gMain . newKeys & A_BUTTON ) )
2017-09-18 14:52:57 +02:00
{
2017-09-18 21:28:55 +02:00
berry_fix_mb_manager - > state = 2 ;
2017-09-18 14:52:57 +02:00
}
break ;
case 2 :
2017-09-18 21:28:55 +02:00
if ( berry_fix_text_update ( 0 ) = = 0 & & ( gMain . newKeys & A_BUTTON ) )
2017-09-18 14:52:57 +02:00
{
2017-09-18 21:28:55 +02:00
berry_fix_mb_manager - > state = 3 ;
2017-09-18 14:52:57 +02:00
}
break ;
case 3 :
2017-09-18 21:28:55 +02:00
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 ;
2017-09-18 21:28:55 +02:00
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 :
2017-09-18 21:28:55 +02:00
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
{
2017-09-18 21:28:55 +02:00
berry_fix_mb_manager - > unk2 = 0 ;
2017-09-18 14:52:57 +02:00
}
2017-09-18 21:28:55 +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 ) ;
2017-09-18 21:28:55 +02:00
berry_fix_mb_manager - > state = 5 ;
2017-09-18 14:52:57 +02:00
}
break ;
case 5 :
2017-09-18 21:28:55 +02:00
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
}
2017-09-18 21:28:55 +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 :
2017-09-18 21:28:55 +02:00
if ( berry_fix_text_update ( 3 ) = = 3 & & gMain . newKeys & A_BUTTON )
2017-09-18 14:52:57 +02:00
{
DoSoftReset ( ) ;
}
break ;
case 7 :
2017-09-18 21:28:55 +02:00
if ( berry_fix_text_update ( 4 ) = = 4 & & gMain . newKeys & A_BUTTON )
2017-09-18 14:52:57 +02:00
{
2017-09-18 21:28:55 +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
2017-09-18 21:28:55 +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 ) ;
2020-02-07 23:12:27 +01:00
InitBgsFromTemplates ( 0 , sBerryFixBgTemplates , ARRAY_COUNT ( sBerryFixBgTemplates ) ) ;
2017-09-18 17:26:45 +02:00
ChangeBgX ( 0 , 0 , 0 ) ;
ChangeBgY ( 0 , 0 , 0 ) ;
ChangeBgX ( 1 , 0 , 0 ) ;
ChangeBgY ( 1 , 0 , 0 ) ;
2020-02-07 23:12:27 +01:00
InitWindows ( sBerryFixWindowTemplates ) ;
2017-09-18 17:26:45 +02:00
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 ) ;
2019-03-02 23:25:39 +01:00
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
2017-09-18 21:28:55 +02:00
static int berry_fix_text_update ( int checkval )
2017-09-18 19:54:39 +02:00
{
2017-09-18 21:28:55 +02:00
if ( berry_fix_mb_manager - > unk1 = = checkval )
2017-09-18 20:07:34 +02:00
{
return checkval ;
}
2017-09-18 21:28:55 +02:00
if ( berry_fix_mb_manager - > unk1 = = 6 )
2017-09-18 20:07:34 +02:00
{
2017-09-18 21:28:55 +02:00
berry_fix_text_print ( checkval ) ;
berry_fix_mb_manager - > unk1 = checkval ;
2017-09-18 20:07:34 +02:00
}
else
{
2017-09-18 21:28:55 +02:00
berry_fix_bg_hide ( ) ;
berry_fix_mb_manager - > unk1 = 6 ;
2017-09-18 20:07:34 +02:00
}
2017-09-18 21:28:55 +02:00
return berry_fix_mb_manager - > unk1 ;
2017-09-18 19:54:39 +02:00
}
2017-09-18 21:28:55 +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 ) ;
2019-03-02 23:25:39 +01:00
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 ) ;
2020-02-07 23:12:27 +01:00
LZ77UnCompVram ( sBerryFixGraphics [ scene ] . gfx , ( void * ) BG_CHAR_ADDR ( 1 ) ) ;
LZ77UnCompVram ( sBerryFixGraphics [ scene ] . tilemap , ( void * ) BG_SCREEN_ADDR ( 31 ) ) ;
CpuCopy32 ( sBerryFixGraphics [ scene ] . pltt , ( void * ) BG_PLTT , 0x100 ) ;
2017-09-18 20:04:00 +02:00
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 ) ;
}