pokeemmo/src/decompress_error_handler.c
hedara90 29fb4f292a
Fixed decompression error reporter OOB window creation (#8199)
Co-authored-by: Hedara <hedara90@gmail.com>
2025-11-10 17:26:08 +01:00

197 lines
4.8 KiB
C

#include "decompress_error_handler.h"
#include "global.h"
#include "data.h"
#include "menu.h"
#include "menu_helpers.h"
#include "malloc.h"
#include "palette.h"
#include "graphics.h"
#include "gpu_regs.h"
#include "bg.h"
#include "main.h"
#include "text_window.h"
#include "string_util.h"
#include "constants/rgb.h"
static EWRAM_DATA u32 sErrorAddress;
static EWRAM_DATA enum CompressionError sCompressionError;
static const struct BgTemplate sBgTemplates[3] =
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0,
},
{
.bg = 2,
.charBaseIndex = 0,
.mapBaseIndex = 14,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0,
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 15,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0,
},
};
static void DecompressErrorScreenTextPrint(u32 window, const u8 *text, u8 x, u8 y)
{
u8 color[3];
color[0] = TEXT_COLOR_TRANSPARENT;
color[1] = TEXT_DYNAMIC_COLOR_6;
color[2] = TEXT_COLOR_LIGHT_GRAY;
AddTextPrinterParameterized4(window, FONT_NORMAL, x * 8, y * 8 + 1, 0, 0, color, 0, text);
}
static void GetHexStringFromU32(u8 *str, u32 value)
{
str[0] = CHAR_0;
str[1] = CHAR_x;
str[10] = EOS;
for (u32 i = 0; i < 8; i++)
{
u8 currChar = 0;
switch ((value >> (4*i)) & 0xF)
{
case 0:
currChar = CHAR_0;
break;
case 1:
currChar = CHAR_1;
break;
case 2:
currChar = CHAR_2;
break;
case 3:
currChar = CHAR_3;
break;
case 4:
currChar = CHAR_4;
break;
case 5:
currChar = CHAR_5;
break;
case 6:
currChar = CHAR_6;
break;
case 7:
currChar = CHAR_7;
break;
case 8:
currChar = CHAR_8;
break;
case 9:
currChar = CHAR_9;
break;
case 10:
currChar = CHAR_A;
break;
case 11:
currChar = CHAR_B;
break;
case 12:
currChar = CHAR_C;
break;
case 13:
currChar = CHAR_D;
break;
case 14:
currChar = CHAR_E;
break;
case 15:
currChar = CHAR_F;
break;
}
u32 pos = 9 - i;
str[pos] = currChar;
}
}
static const struct WindowTemplate sTextWin =
{
.bg = 0,
.tilemapLeft = 3,
.tilemapTop = 2,
.width = 24,
.height = 16,
.paletteNum = 15,
.baseBlock = 1,
};
void DecompressionError_CB2(void)
{
if (sErrorAddress == 0)
return;
ResetVramOamAndBgCntRegs();
ResetAllBgsCoordinates();
FreeAllWindowBuffers();
SetGpuReg(REG_OFFSET_DISPCNT, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BG0CNT, 0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
DmaFill16(3, 0, VRAM, VRAM_SIZE);
DmaFill32(3, 0, OAM, OAM_SIZE);
DmaFill16(3, 0, PLTT, PLTT_SIZE);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates));
LoadBgTiles(0, gTextWindowFrame1_Gfx, 0x120, 0x214);
DeactivateAllTextPrinters();
ResetTasks();
ResetPaletteFade();
LoadPalette(gTextWindowFrame1_Pal, 0xE0, 0x20);
LoadPalette(gStandardMenuPalette, 0xF0, 0x20);
u32 window = AddWindow(&sTextWin);
DrawStdFrameWithCustomTileAndPalette(window, TRUE, 0x214, 0xE);
static const u8 romCheckFailMessage[] =_(
"{COLOR RED}ERROR! {COLOR DARK_GRAY}Decompression Failed!\n"
"\n"
"Address:\n"
"Error:\n");
DecompressErrorScreenTextPrint(window, romCheckFailMessage, 1, 0);
u8 addressStr[11];
u8 errorStr[11];
GetHexStringFromU32(addressStr, sErrorAddress);
GetHexStringFromU32(errorStr, sCompressionError);
DecompressErrorScreenTextPrint(window, addressStr, 7, 4);
DecompressErrorScreenTextPrint(window, errorStr, 7, 6);
TransferPlttBuffer();
*(u16*)PLTT = RGB(17, 18, 31);
ShowBg(0);
sErrorAddress = 0;
// This loop is apparently needed to prevent the game from doing
// stupid stuff with data it couldn't decompress
while(TRUE)
sCompressionError++;
}
void DecompressionError(const u32 *src, enum CompressionError error)
{
sErrorAddress = (u32)src;
sCompressionError = error;
SetMainCallback2(DecompressionError_CB2);
DecompressionError_CB2();
}
void DoDecompressionError(void)
{
DecompressionError((u32 *)0x12345678, HEADER_ERROR);
}