Files
Pokemon-Firered/src/new_menu_helpers.c
T
2019-06-26 04:52:34 +08:00

309 lines
7.8 KiB
C

#include "global.h"
#include "malloc.h"
#include "dma3.h"
#include "task.h"
#include "bg.h"
#include "gpu_regs.h"
#include "window.h"
#include "menu.h"
#include "menu_helpers.h"
#include "new_menu_helpers.h"
#include "quest_log.h"
#include "text.h"
#include "field_specials.h"
static EWRAM_DATA bool8 gUnknown_203AB58[4] = {FALSE}; // knizz: bgmaps_that_need_syncing
static EWRAM_DATA u16 gUnknown_203AB5C = {0};
static EWRAM_DATA void *gUnknown_203AB60[0x20] = {NULL};
extern const struct WindowTemplate sStandardTextBox_WindowTemplates[];
EWRAM_DATA u8 sStartMenuWindowId;
u16 CopyDecompressedTileDataToVram(u8 bgId, const void *src, u16 size, u16 offset, u8 mode);
void TaskFreeBufAfterCopyingTileDataToVram(u8 taskId);
void ClearScheduledBgCopiesToVram(void)
{
memset(gUnknown_203AB58, 0, sizeof(gUnknown_203AB58));
}
void ScheduleBgCopyTilemapToVram(u8 bgId)
{
gUnknown_203AB58[bgId] = TRUE;
}
void DoScheduledBgTilemapCopiesToVram(void)
{
if (gUnknown_203AB58[0] == TRUE)
{
CopyBgTilemapBufferToVram(0);
gUnknown_203AB58[0] = FALSE;
}
if (gUnknown_203AB58[1] == TRUE)
{
CopyBgTilemapBufferToVram(1);
gUnknown_203AB58[1] = FALSE;
}
if (gUnknown_203AB58[2] == TRUE)
{
CopyBgTilemapBufferToVram(2);
gUnknown_203AB58[2] = FALSE;
}
if (gUnknown_203AB58[3] == TRUE)
{
CopyBgTilemapBufferToVram(3);
gUnknown_203AB58[3] = FALSE;
}
}
void ResetTempTileDataBuffers(void)
{
int i;
for (i = 0; i < (s32)ARRAY_COUNT(gUnknown_203AB60); i++)
{
gUnknown_203AB60[i] = NULL;
}
gUnknown_203AB5C = 0;
}
bool8 FreeTempTileDataBuffersIfPossible(void)
{
int i;
if (!IsDma3ManagerBusyWithBgCopy())
{
if (gUnknown_203AB5C)
{
for (i = 0; i < gUnknown_203AB5C; i++)
{
FREE_AND_SET_NULL(gUnknown_203AB60[i]);
}
gUnknown_203AB5C = 0;
}
return FALSE;
}
else
{
return TRUE;
}
}
void *DecompressAndCopyTileDataToVram(u8 bgId, const void *src, u32 size, u16 offset, u8 mode)
{
u32 sizeOut;
if (gUnknown_203AB5C < ARRAY_COUNT(gUnknown_203AB60))
{
void *ptr = MallocAndDecompress(src, &sizeOut);
if (!size)
size = sizeOut;
if (ptr)
{
CopyDecompressedTileDataToVram(bgId, ptr, size, offset, mode);
gUnknown_203AB60[gUnknown_203AB5C++] = ptr;
}
return ptr;
}
return NULL;
}
void *DecompressAndCopyTileDataToVram2(u8 bgId, const void *src, u32 size, u16 offset, u8 mode)
{
u32 sizeOut;
if (gUnknown_203AB5C < ARRAY_COUNT(gUnknown_203AB60))
{
void *ptr = MallocAndDecompress(src, &sizeOut);
if (sizeOut > size)
sizeOut = size;
if (ptr)
{
CopyDecompressedTileDataToVram(bgId, ptr, sizeOut, offset, mode);
gUnknown_203AB60[gUnknown_203AB5C++] = ptr;
}
return ptr;
}
return NULL;
}
void DecompressAndLoadBgGfxUsingHeap(u8 bgId, const void *src, u32 size, u16 offset, u8 mode)
{
u32 sizeOut;
void *ptr = MallocAndDecompress(src, &sizeOut);
if (!size)
size = sizeOut;
if (ptr)
{
u8 taskId = CreateTask(TaskFreeBufAfterCopyingTileDataToVram, 0);
gTasks[taskId].data[0] = CopyDecompressedTileDataToVram(bgId, ptr, size, offset, mode);
SetWordTaskArg(taskId, 1, (u32)ptr);
}
}
void DecompressAndLoadBgGfxUsingHeap2(u8 bgId, const void *src, u32 size, u16 offset, u8 mode)
{
u32 sizeOut;
void *ptr = MallocAndDecompress(src, &sizeOut);
if (sizeOut > size)
sizeOut = size;
if (ptr)
{
u8 taskId = CreateTask(TaskFreeBufAfterCopyingTileDataToVram, 0);
gTasks[taskId].data[0] = CopyDecompressedTileDataToVram(bgId, ptr, sizeOut, offset, mode);
SetWordTaskArg(taskId, 1, (u32)ptr);
}
}
void TaskFreeBufAfterCopyingTileDataToVram(u8 taskId)
{
if (!CheckForSpaceForDma3Request(gTasks[taskId].data[0]))
{
Free((void *)GetWordTaskArg(taskId, 1));
DestroyTask(taskId);
}
}
void *MallocAndDecompress(const void *src, u32 *size)
{
void *ptr;
u8 *sizeAsBytes = (u8 *)size;
u8 *srcAsBytes = (u8 *)src;
sizeAsBytes[0] = srcAsBytes[1];
sizeAsBytes[1] = srcAsBytes[2];
sizeAsBytes[2] = srcAsBytes[3];
sizeAsBytes[3] = 0;
ptr = Alloc(*size);
if (ptr)
LZ77UnCompWram(src, ptr);
return ptr;
}
u16 CopyDecompressedTileDataToVram(u8 bgId, const void *src, u16 size, u16 offset, u8 mode)
{
switch (mode)
{ // different to EM
case 1:
break;
case 0:
default:
return LoadBgTiles(bgId, src, size, offset);
}
return LoadBgTilemap(bgId, src, size, offset);
}
void SetBgRectPal(u8 bgId, u8 left, u8 top, u8 width, u8 height, u8 palette)
{
u8 i;
u8 j;
u16 *ptr = GetBgTilemapBuffer(bgId);
for (i = top; i < top + height; i++)
{
for (j = left; j < left + width; j++)
{
ptr[(i * 32) + j] = (ptr[(i * 32) + j] & 0xFFF) | (palette << 12);
}
}
}
void CopyRectIntoAltRect(u8 bgId, u16 *dest, u8 left, u8 top, u8 width, u8 height)
{
u8 i;
u8 j;
const u16 *src = GetBgTilemapBuffer(bgId);
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
dest[(i * width) + j] = src[(i + top) * 32 + j + left];
}
}
}
void ResetBgPositions(void)
{
ChangeBgX(0, 0, 0);
ChangeBgX(1, 0, 0);
ChangeBgX(2, 0, 0);
ChangeBgX(3, 0, 0);
ChangeBgY(0, 0, 0);
ChangeBgY(1, 0, 0);
ChangeBgY(2, 0, 0);
ChangeBgY(3, 0, 0);
}
void InitStandardTextBoxWindows(void)
{
InitWindows(sStandardTextBox_WindowTemplates);
sStartMenuWindowId = 0xFF;
MapNamePopupWindowIdSetDummy();
}
void FreeAllOverworldWindowBuffers(void)
{
FreeAllWindowBuffers();
}
void ResetBg0(void)
{
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
DeactivateAllTextPrinters();
sub_80F6E9C();
}
u16 RunTextPrinters_CheckPrinter0Active(void)
{
RunTextPrinters();
return IsTextPrinterActive(0);
}
u16 AddTextPrinterParameterized2(u8 windowId, u8 fontId, const u8 *str, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16), u8 fgColor, u8 bgColor, u8 shadowColor)
{
struct TextPrinterTemplate printer;
printer.currentChar = str;
printer.windowId = windowId;
printer.fontId = fontId;
printer.x = 0;
printer.y = 1;
printer.currentX = 0;
printer.currentY = 1;
printer.letterSpacing = 1; // different to EM
printer.lineSpacing = 1; // different to EM
printer.unk = 0;
printer.fgColor = fgColor;
printer.bgColor = bgColor;
printer.shadowColor = shadowColor;
gTextFlags.useAlternateDownArrow = 0;
return AddTextPrinter(&printer, speed, callback);
}
void AddTextPrinterDiffStyle(bool8 allowSkippingDelayWithButtonPress)
{
u8 result;
void *nptr = NULL; // This is required for matching
gTextFlags.canABSpeedUpPrint = allowSkippingDelayWithButtonPress;
result = ContextNpcGetTextColor();
if (!result)
AddTextPrinterParameterized2(0, 4, gStringVar4, GetTextSpeedSetting(), nptr, 8, 1, 3);
else if (result == 1)
AddTextPrinterParameterized2(0, 5, gStringVar4, GetTextSpeedSetting(), nptr, 4, 1, 3);
else
AddTextPrinterParameterized2(0, 2, gStringVar4, GetTextSpeedSetting(), nptr, 2, 1, 3);
}
void AddTextPrinterForMessage(bool8 allowSkippingDelayWithButtonPress)
{
gTextFlags.canABSpeedUpPrint = allowSkippingDelayWithButtonPress;
AddTextPrinterParameterized2(0, 2, gStringVar4, GetTextSpeedSetting(), NULL, 2, 1, 3);
}
void AddTextPrinterWithCustomSpeedForMessage(bool8 allowSkippingDelayWithButtonPress, u8 speed)
{
gTextFlags.canABSpeedUpPrint = allowSkippingDelayWithButtonPress;
AddTextPrinterParameterized2(0, 2, gStringVar4, speed, NULL, 2, 1, 3);
}