From c3ea79ededd96494ca99f39e7de2daadbbd566f2 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 15 Jan 2025 13:14:31 +0100 Subject: [PATCH 01/11] Remove gDecompressionBuffer from battle_main.c --- src/battle_main.c | 67 ----------------------------------------------- 1 file changed, 67 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 5dba22a160c5..9b293d410a23 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -121,8 +121,6 @@ static void HandleEndTurn_BattleLost(void); static void HandleEndTurn_RanFromBattle(void); static void HandleEndTurn_MonFled(void); static void HandleEndTurn_FinishBattle(void); -static void SpriteCB_UnusedBattleInit(struct Sprite *sprite); -static void SpriteCB_UnusedBattleInit_Main(struct Sprite *sprite); static u32 Crc32B (const u8 *data, u32 size); static u32 GeneratePartyHash(const struct Trainer *trainer, u32 i); static s32 Factorial(s32); @@ -255,17 +253,6 @@ static const struct ScanlineEffectParams sIntroScanlineParams32Bit = ®_BG3HOFS, SCANLINE_EFFECT_DMACNT_32BIT, 1 }; -const struct SpriteTemplate gUnusedBattleInitSprite = -{ - .tileTag = 0, - .paletteTag = 0, - .oam = &gDummyOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_UnusedBattleInit, -}; - static const u8 sText_ShedinjaJpnName[] = _("ヌケニン"); // Nukenin const struct OamData gOamData_BattleSpriteOpponentSide = @@ -1788,60 +1775,6 @@ void CB2_QuitRecordedBattle(void) } } -#define sState data[0] -#define sDelay data[4] - -static void SpriteCB_UnusedBattleInit(struct Sprite *sprite) -{ - sprite->sState = 0; - sprite->callback = SpriteCB_UnusedBattleInit_Main; -} - -static void SpriteCB_UnusedBattleInit_Main(struct Sprite *sprite) -{ - u16 *arr = (u16 *)gDecompressionBuffer; - - switch (sprite->sState) - { - case 0: - sprite->sState++; - sprite->data[1] = 0; - sprite->data[2] = 0x281; - sprite->data[3] = 0; - sprite->sDelay = 1; - // fall through - case 1: - sprite->sDelay--; - if (sprite->sDelay == 0) - { - s32 i; - s32 r2; - s32 r0; - - sprite->sDelay = 2; - r2 = sprite->data[1] + sprite->data[3] * 32; - r0 = sprite->data[2] - sprite->data[3] * 32; - for (i = 0; i < 29; i += 2) - { - arr[r2 + i] = 0x3D; - arr[r0 + i] = 0x3D; - } - sprite->data[3]++; - if (sprite->data[3] == 21) - { - sprite->sState++; - sprite->data[1] = 32; - } - } - break; - case 2: - sprite->data[1]--; - if (sprite->data[1] == 20) - SetMainCallback2(CB2_InitBattle); - break; - } -} - static u32 Crc32B (const u8 *data, u32 size) { s32 i, j; From 8c79e974c194bf73575bd27a94f3305292b750f1 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 15 Jan 2025 16:27:57 +0100 Subject: [PATCH 02/11] more gDecompression removal --- include/bg.h | 3 ++- include/decompress.h | 10 +++++--- src/battle_anim.c | 15 ++++++----- src/battle_transition.c | 4 +-- src/bg.c | 10 +++++++- src/decompress.c | 56 +++++++++++++++++++++-------------------- src/field_effect.c | 17 +++++++++++-- src/main_menu.c | 4 +-- src/menu.c | 5 ++++ src/roulette.c | 38 +++++++--------------------- src/trade.c | 10 ++------ 11 files changed, 88 insertions(+), 84 deletions(-) diff --git a/include/bg.h b/include/bg.h index f981ed4b8c13..89ffc8d8ebda 100644 --- a/include/bg.h +++ b/include/bg.h @@ -80,7 +80,8 @@ u8 Unused_AdjustBgMosaic(u8 val, u32 mode); void SetBgTilemapBuffer(u32 bg, void *tilemap); void UnsetBgTilemapBuffer(u32 bg); void *GetBgTilemapBuffer(u32 bg); -void CopyToBgTilemapBuffer(u32 bg, const void *src, u16 mode, u16 destOffset); +void CopyToBgTilemapBuffer(u32 bg, const void *src, u32 mode, u32 destOffset); +void DecompressAndCopyToBgTilemapBuffer(u32 bg, const u32 *src, u32 mode, u32 destOffset); void CopyBgTilemapBufferToVram(u32 bg); void CopyToBgTilemapBufferRect(u32 bg, const void *src, u8 destX, u8 destY, u8 width, u8 height); void CopyToBgTilemapBufferRect_ChangePalette(u32 bg, const void *src, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette); diff --git a/include/decompress.h b/include/decompress.h index 178ab9a6ebc3..66bc22d935c5 100644 --- a/include/decompress.h +++ b/include/decompress.h @@ -3,16 +3,18 @@ #include "sprite.h" -extern u8 ALIGNED(4) gDecompressionBuffer[0x4000]; +#define MAX_DECOMPRESSION_BUFFER_SIZE 0x4000 + +extern u8 ALIGNED(4) gDecompressionBuffer[MAX_DECOMPRESSION_BUFFER_SIZE]; void LZDecompressWram(const u32 *src, void *dest); void LZDecompressVram(const u32 *src, void *dest); u32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize); -u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src); -u16 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s32 offset); -void LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer); +u32 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src); +u32 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s32 offset); +u32 LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer); bool8 LoadCompressedSpriteSheetUsingHeap(const struct CompressedSpriteSheet *src); void LoadCompressedSpritePalette(const struct CompressedSpritePalette *src); diff --git a/src/battle_anim.c b/src/battle_anim.c index 3e079647d202..cb4de465cc8e 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -12,6 +12,7 @@ #include "gpu_regs.h" #include "graphics.h" #include "main.h" +#include "malloc.h" #include "m4a.h" #include "palette.h" #include "pokemon.h" @@ -1570,17 +1571,15 @@ void LoadMoveBg(u16 bgId) { if (IsContest()) { + void *decompressionBuffer = Alloc(0x800); const u32 *tilemap = gBattleAnimBackgroundTable[bgId].tilemap; - void *dmaSrc; - void *dmaDest; - - LZDecompressWram(tilemap, gDecompressionBuffer); - RelocateBattleBgPal(GetBattleBgPaletteNum(), (void *)gDecompressionBuffer, 0x100, FALSE); - dmaSrc = gDecompressionBuffer; - dmaDest = (void *)BG_SCREEN_ADDR(26); - DmaCopy32(3, dmaSrc, dmaDest, 0x800); + + LZDecompressWram(tilemap, decompressionBuffer); + RelocateBattleBgPal(GetBattleBgPaletteNum(), decompressionBuffer, 0x100, FALSE); + DmaCopy32(3, decompressionBuffer, (void *)BG_SCREEN_ADDR(26), 0x800); LZDecompressVram(gBattleAnimBackgroundTable[bgId].image, (void *)BG_SCREEN_ADDR(4)); LoadCompressedPalette(gBattleAnimBackgroundTable[bgId].palette, BG_PLTT_ID(GetBattleBgPaletteNum()), PLTT_SIZE_4BPP); + Free(decompressionBuffer); } else { diff --git a/src/battle_transition.c b/src/battle_transition.c index fbaa5cc0de34..1afbe7a026ad 100644 --- a/src/battle_transition.c +++ b/src/battle_transition.c @@ -2526,13 +2526,13 @@ static void Mugshots_CreateTrainerPics(struct Task *task) task->tOpponentSpriteId = CreateTrainerSprite(trainerPicId, gTrainerSprites[trainerPicId].mugshotCoords.x - 32, gTrainerSprites[trainerPicId].mugshotCoords.y + 42, - 0, gDecompressionBuffer); + 0, NULL); gReservedSpritePaletteCount = 12; task->tPlayerSpriteId = CreateTrainerSprite(PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender), DISPLAY_WIDTH + 32, 106, - 0, gDecompressionBuffer); + 0, NULL); opponentSprite = &gSprites[task->tOpponentSpriteId]; playerSprite = &gSprites[task->tPlayerSpriteId]; diff --git a/src/bg.c b/src/bg.c index 27a5fb0501bd..5f973c388bbf 100644 --- a/src/bg.c +++ b/src/bg.c @@ -3,6 +3,7 @@ #include "bg.h" #include "dma3.h" #include "gpu_regs.h" +#include "menu.h" #define DISPCNT_ALL_BG_AND_MODE_BITS (DISPCNT_BG_ALL_ON | 0x7) @@ -865,7 +866,7 @@ void *GetBgTilemapBuffer(u32 bg) return sGpuBgConfigs2[bg].tilemap; } -void CopyToBgTilemapBuffer(u32 bg, const void *src, u16 mode, u16 destOffset) +void CopyToBgTilemapBuffer(u32 bg, const void *src, u32 mode, u32 destOffset) { if (!IsInvalidBg(bg) && !IsTileMapOutsideWram(bg)) { @@ -876,6 +877,13 @@ void CopyToBgTilemapBuffer(u32 bg, const void *src, u16 mode, u16 destOffset) } } +void DecompressAndCopyToBgTilemapBuffer(u32 bg, const u32 *src, u32 mode, u32 destOffset) +{ + void *buffer = malloc_and_decompress(src, NULL); + + CopyToBgTilemapBuffer(bg, buffer, mode, destOffset); +} + void CopyBgTilemapBufferToVram(u32 bg) { u16 sizeToLoad; diff --git a/src/decompress.c b/src/decompress.c index 284bce48d331..8c1043dfbb02 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -5,6 +5,7 @@ #include "pokemon.h" #include "pokemon_sprite_visualizer.h" #include "text.h" +#include "menu.h" EWRAM_DATA ALIGNED(4) u8 gDecompressionBuffer[0x4000] = {0}; @@ -40,66 +41,67 @@ u32 IsLZ77Data(const void *ptr, u32 minSize, u32 maxSize) return 0; } -u16 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src) +static inline u32 DoLoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src, void *buffer) { struct SpriteSheet dest; - LZ77UnCompWram(src->data, gDecompressionBuffer); - dest.data = gDecompressionBuffer; + dest.data = buffer; dest.size = src->size; dest.tag = src->tag; return LoadSpriteSheet(&dest); } +u32 LoadCompressedSpriteSheet(const struct CompressedSpriteSheet *src) +{ + void *buffer = malloc_and_decompress(src->data, NULL); + u32 ret = DoLoadCompressedSpriteSheet(src, buffer); + Free(buffer); + + return ret; +} + +u32 LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer) +{ + LZ77UnCompWram(src->data, buffer); + return DoLoadCompressedSpriteSheet(src, buffer); +} + // This can be used for either compressed or uncompressed sprite sheets -u16 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s32 offset) +u32 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s32 offset) { struct SpriteTemplate myTemplate; struct SpriteFrameImage myImage; u32 size; // Check for LZ77 header and read uncompressed size, or fallback if not compressed (zero size) - if ((size = IsLZ77Data(template->images->data, TILE_SIZE_4BPP, sizeof(gDecompressionBuffer))) == 0) + if ((size = IsLZ77Data(template->images->data, TILE_SIZE_4BPP, MAX_DECOMPRESSION_BUFFER_SIZE)) == 0) return LoadSpriteSheetByTemplate(template, 0, offset); - LZ77UnCompWram(template->images->data, gDecompressionBuffer); - myImage.data = gDecompressionBuffer; + void *buffer = malloc_and_decompress(template->images->data, NULL); + myImage.data = buffer; myImage.size = size + offset; myTemplate.images = &myImage; myTemplate.tileTag = template->tileTag; - return LoadSpriteSheetByTemplate(&myTemplate, 0, offset); -} - -void LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer) -{ - struct SpriteSheet dest; - - LZ77UnCompWram(src->data, buffer); - dest.data = buffer; - dest.size = src->size; - dest.tag = src->tag; - LoadSpriteSheet(&dest); + u32 ret = LoadSpriteSheetByTemplate(&myTemplate, 0, offset); + Free(buffer); + return ret; } void LoadCompressedSpritePalette(const struct CompressedSpritePalette *src) { - struct SpritePalette dest; - - LZ77UnCompWram(src->data, gDecompressionBuffer); - dest.data = (void *) gDecompressionBuffer; - dest.tag = src->tag; - LoadSpritePalette(&dest); + LoadCompressedSpritePaletteWithTag(src->data, src->tag); } void LoadCompressedSpritePaletteWithTag(const u32 *pal, u16 tag) { struct SpritePalette dest; + void *buffer = malloc_and_decompress(pal, NULL); - LZ77UnCompWram(pal, gDecompressionBuffer); - dest.data = (void *) gDecompressionBuffer; + dest.data = buffer; dest.tag = tag; LoadSpritePalette(&dest); + Free(buffer); } void LoadCompressedSpritePaletteOverrideBuffer(const struct CompressedSpritePalette *src, void *buffer) diff --git a/src/field_effect.c b/src/field_effect.c index 45631be6a348..3d6e6e67cba6 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -14,6 +14,7 @@ #include "fldeff.h" #include "gpu_regs.h" #include "main.h" +#include "malloc.h" #include "mirage_tower.h" #include "menu.h" #include "metatile_behavior.h" @@ -897,8 +898,20 @@ bool8 FieldEffectActiveListContains(u8 id) u8 CreateTrainerSprite(u8 trainerSpriteID, s16 x, s16 y, u8 subpriority, u8 *buffer) { struct SpriteTemplate spriteTemplate; + bool32 alloced = FALSE; + + // Allocate memory for buffer + if (buffer == NULL) + { + buffer = Alloc(TRAINER_PIC_SIZE + PLTT_SIZEOF(16)); + alloced = TRUE; + } + LoadCompressedSpritePaletteOverrideBuffer(&gTrainerSprites[trainerSpriteID].palette, buffer); LoadCompressedSpriteSheetOverrideBuffer(&gTrainerSprites[trainerSpriteID].frontPic, buffer); + if (alloced) + Free(buffer); + spriteTemplate.tileTag = gTrainerSprites[trainerSpriteID].frontPic.tag; spriteTemplate.paletteTag = gTrainerSprites[trainerSpriteID].palette.tag; spriteTemplate.oam = &sOam_64x64; @@ -3940,7 +3953,7 @@ static void Task_MoveDeoxysRock(u8 taskId) u8 FldEff_CaveDust(void) { u8 spriteId; - + SetSpritePosToOffsetMapCoords((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8); spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_CAVE_DUST], gFieldEffectArguments[0], gFieldEffectArguments[1], 0xFF); if (spriteId != MAX_SPRITES) @@ -3948,7 +3961,7 @@ u8 FldEff_CaveDust(void) gSprites[spriteId].coordOffsetEnabled = TRUE; gSprites[spriteId].data[0] = 22; } - + return spriteId; } diff --git a/src/main_menu.c b/src/main_menu.c index bae80e543a0a..c8132c6df87c 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -1915,12 +1915,12 @@ static void AddBirchSpeechObjects(u8 taskId) gSprites[lotadSpriteId].oam.priority = 0; gSprites[lotadSpriteId].invisible = TRUE; gTasks[taskId].tLotadSpriteId = lotadSpriteId; - brendanSpriteId = CreateTrainerSprite(FacilityClassToPicIndex(FACILITY_CLASS_BRENDAN), 120, 60, 0, &gDecompressionBuffer[0]); + brendanSpriteId = CreateTrainerSprite(FacilityClassToPicIndex(FACILITY_CLASS_BRENDAN), 120, 60, 0, NULL); gSprites[brendanSpriteId].callback = SpriteCB_Null; gSprites[brendanSpriteId].invisible = TRUE; gSprites[brendanSpriteId].oam.priority = 0; gTasks[taskId].tBrendanSpriteId = brendanSpriteId; - maySpriteId = CreateTrainerSprite(FacilityClassToPicIndex(FACILITY_CLASS_MAY), 120, 60, 0, &gDecompressionBuffer[TRAINER_PIC_SIZE]); + maySpriteId = CreateTrainerSprite(FacilityClassToPicIndex(FACILITY_CLASS_MAY), 120, 60, 0, NULL); gSprites[maySpriteId].callback = SpriteCB_Null; gSprites[maySpriteId].invisible = TRUE; gSprites[maySpriteId].oam.priority = 0; diff --git a/src/menu.c b/src/menu.c index d9b331a8b2fd..a6d6a3892643 100644 --- a/src/menu.c +++ b/src/menu.c @@ -1943,7 +1943,12 @@ void task_free_buf_after_copying_tile_data_to_vram(u8 taskId) void *malloc_and_decompress(const void *src, u32 *size) { + u32 sizeLocal; // If size is passed as NULL, because we don't care about knowing the size void *ptr; + + if (size == NULL) + size = &sizeLocal; + u8 *sizeAsBytes = (u8 *)size; u8 *srcAsBytes = (u8 *)src; diff --git a/src/roulette.c b/src/roulette.c index f4e6012a8dcd..c72b1b78766b 100644 --- a/src/roulette.c +++ b/src/roulette.c @@ -3521,17 +3521,10 @@ static void CreateGridSprites(void) { u8 i, j; u8 spriteId; - struct SpriteSheet s; - LZ77UnCompWram(sSpriteSheet_Headers.data, gDecompressionBuffer); - s.data = gDecompressionBuffer; - s.size = sSpriteSheet_Headers.size; - s.tag = sSpriteSheet_Headers.tag; - LoadSpriteSheet(&s); - LZ77UnCompWram(sSpriteSheet_GridIcons.data, gDecompressionBuffer); - s.data = gDecompressionBuffer; - s.size = sSpriteSheet_GridIcons.size; - s.tag = sSpriteSheet_GridIcons.tag; - LoadSpriteSheet(&s); + + LoadCompressedSpriteSheet(&sSpriteSheet_Headers); + LoadCompressedSpriteSheet(&sSpriteSheet_GridIcons); + for (i = 0; i < NUM_BOARD_COLORS; i++) { u8 y = i * 24; @@ -3656,13 +3649,8 @@ static void CreateWheelIconSprites(void) { u8 i, j; u16 angle; - struct SpriteSheet s; - LZ77UnCompWram(sSpriteSheet_WheelIcons.data, gDecompressionBuffer); - s.data = gDecompressionBuffer; - s.size = sSpriteSheet_WheelIcons.size; - s.tag = sSpriteSheet_WheelIcons.tag; - LoadSpriteSheet(&s); + LoadCompressedSpriteSheet(&sSpriteSheet_WheelIcons); angle = 15; for (i = 0; i < NUM_BOARD_COLORS; i++) @@ -3702,12 +3690,7 @@ static void CreateInterfaceSprites(void) u8 i; for (i = 0; i < ARRAY_COUNT(sSpriteSheets_Interface) - 1; i++) { - struct SpriteSheet s; - LZ77UnCompWram(sSpriteSheets_Interface[i].data, gDecompressionBuffer); - s.data = gDecompressionBuffer; - s.size = sSpriteSheets_Interface[i].size; - s.tag = sSpriteSheets_Interface[i].tag; - LoadSpriteSheet(&s); + LoadCompressedSpriteSheet(&sSpriteSheets_Interface[i]); } sRoulette->spriteIds[SPR_CREDIT] = CreateSprite(&sSpriteTemplate_Credit, 208, 16, 4); gSprites[sRoulette->spriteIds[SPR_CREDIT]].animPaused = TRUE; @@ -3850,12 +3833,9 @@ static void SpriteCB_GridSquare(struct Sprite *sprite) static void CreateWheelCenterSprite(void) { u8 spriteId; - struct SpriteSheet s; - LZ77UnCompWram(sSpriteSheet_WheelCenter.data, gDecompressionBuffer); - s.data = gDecompressionBuffer; - s.size = sSpriteSheet_WheelCenter.size; - s.tag = sSpriteSheet_WheelCenter.tag; - LoadSpriteSheet(&s); + + LoadCompressedSpriteSheet(&sSpriteSheet_WheelCenter); + // This sprite id isn't saved because it doesn't need to be referenced again // but by virtue of creation order it's SPR_WHEEL_CENTER spriteId = CreateSprite(&sSpriteTemplate_WheelCenter, 116, 80, 81); diff --git a/src/trade.c b/src/trade.c index 04b1977c17b0..8ba22eac977d 100644 --- a/src/trade.c +++ b/src/trade.c @@ -2959,17 +2959,11 @@ static void TradeAnimInit_LoadGfx(void) SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE)); SetBgTilemapBuffer(3, Alloc(BG_SCREEN_SIZE)); DeactivateAllTextPrinters(); - // Doing the graphics load... + // Doing the graphics load. DecompressAndLoadBgGfxUsingHeap(0, gBattleTextboxTiles, 0, 0, 0); - LZDecompressWram(gBattleTextboxTilemap, gDecompressionBuffer); - CopyToBgTilemapBuffer(0, gDecompressionBuffer, BG_SCREEN_SIZE, 0); + DecompressAndCopyToBgTilemapBuffer(0, gBattleTextboxTilemap, BG_SCREEN_SIZE, 0); LoadCompressedPalette(gBattleTextboxPalette, BG_PLTT_ID(0), PLTT_SIZE_4BPP); InitWindows(sTradeSequenceWindowTemplates); - // ... and doing the same load again - DecompressAndLoadBgGfxUsingHeap(0, gBattleTextboxTiles, 0, 0, 0); - LZDecompressWram(gBattleTextboxTilemap, gDecompressionBuffer); - CopyToBgTilemapBuffer(0, gDecompressionBuffer, BG_SCREEN_SIZE, 0); - LoadCompressedPalette(gBattleTextboxPalette, BG_PLTT_ID(0), PLTT_SIZE_4BPP); } static void CB2_InitInGameTrade(void) From 94ce8b846165bd501dfbf12b4c045b73046a49ce Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Jan 2025 11:13:40 +0100 Subject: [PATCH 03/11] berry images decompression buffer --- include/item_menu_icons.h | 16 ++++-- src/battle_gfx_sfx_util.c | 13 +++-- src/berry_blender.c | 106 ++++++++++++++++++++++---------------- src/berry_tag_screen.c | 7 +-- src/contest_link.c | 1 - src/item_menu_icons.c | 90 ++++++++++++++++++++++---------- src/palette.c | 8 +-- 7 files changed, 155 insertions(+), 86 deletions(-) diff --git a/include/item_menu_icons.h b/include/item_menu_icons.h index d01dcccf5f26..dbffa65f7340 100644 --- a/include/item_menu_icons.h +++ b/include/item_menu_icons.h @@ -17,9 +17,19 @@ void RemoveBagItemIconSprite(u8 id); void CreateItemMenuSwapLine(void); void SetItemMenuSwapLineInvisibility(bool8 invisible); void UpdateItemMenuSwapLinePos(u8 y); -u8 CreateBerryTagSprite(u8 id, s16 x, s16 y); -void FreeBerryTagSpritePalette(void); -u8 CreateSpinningBerrySprite(u8 berryId, u8 x, u8 y, bool8 startAffine); + +// Note: Because of removing gDecompressionBuffer and allowing to create more than berry sprite at a time, the memory for gfx is allocated dynamically. +// For CreateBerryTagSprite and CreateSpinningBerrySprite the allocated ptr is stored in two last data fields(data[6], data[7]), so make sure to NOT put anything in there! +// The corresponding code has already been edited in berry_tag_screen.c and berry_blender.c +#define BERRY_ICON_GFX_PTR_DATA_ID 6 +u32 CreateBerryTagSprite(u32 id, s32 x, s32 y); +u32 CreateSpinningBerrySprite(u32 berryId, s32 x, s32 y, bool32 startAffine); +// Needs to call either of these always after creating a Berry Icon sprite, because it frees allocated memory! +void DestroyBerryIconSprite(u32 spriteId, u32 berryId, bool32 freePal); +void DestroyBerryIconSpritePtr(struct Sprite *sprite, u32 berryId, bool32 freePal); + +void FreeBerryIconSpritePalette(u32 berryId); // Unused atm, because it's also handled by DestroyBerryIconSprite. Leaving it as it still may be useful in some custom cases. + u8 CreateBerryFlavorCircleSprite(s16 x); #endif // GUARD_ITEM_MENU_ICONS_H diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 7677c9f38c38..945fa660ca28 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -6,6 +6,7 @@ #include "constants/battle_anim.h" #include "battle_interface.h" #include "main.h" +#include "menu.h" #include "dma3.h" #include "malloc.h" #include "graphics.h" @@ -655,9 +656,10 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler) else lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, isShiny, personalityValue); - LZDecompressWram(lzPaletteData, gDecompressionBuffer); - LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP); - LoadPalette(gDecompressionBuffer, BG_PLTT_ID(8) + BG_PLTT_ID(battler), PLTT_SIZE_4BPP); + void *buffer = malloc_and_decompress(lzPaletteData, NULL); + LoadPalette(buffer, paletteOffset, PLTT_SIZE_4BPP); + LoadPalette(buffer, BG_PLTT_ID(8) + BG_PLTT_ID(battler), PLTT_SIZE_4BPP); + Free(buffer); // transform's pink color if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies != SPECIES_NONE) @@ -975,8 +977,9 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo DmaCopy32(3, src, dst, MON_PIC_SIZE); paletteOffset = OBJ_PLTT_ID(battlerAtk); lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, isShiny, personalityValue); - LZDecompressWram(lzPaletteData, gDecompressionBuffer); - LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP); + void *buffer = malloc_and_decompress(lzPaletteData, NULL); + LoadPalette(buffer, paletteOffset, PLTT_SIZE_4BPP); + Free(buffer); if (!megaEvo) { diff --git a/src/berry_blender.c b/src/berry_blender.c index bf094b6fb98a..9d428c694941 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -1126,68 +1126,84 @@ static void CB2_LoadBerryBlender(void) UpdatePaletteFade(); } -#define sTargetY data[0] -#define sX data[1] -#define sY data[2] -#define sBounceSpeed data[3] -#define sYUpSpeed data[4] -#define sBounces data[5] -#define sXSpeed data[6] -#define sYDownSpeed data[7] +// Because of changing how Berry sprites are generated, we have to leave data[6] and data[7] untouched as it has an allocated memory ptr for berry's gfx. +struct BerrySpriteData +{ + s16 sTargetY; // data0 + s16 sX; // data1 + s16 sY; // data2 + + s8 sBounceSpeed; // data3 + u8 berryId; // data3 + + s8 sYUpSpeed; // data4 + s8 sBounces; // data4 + + s8 sXSpeed; // data5 + s8 sYDownSpeed; // data5 +}; + +static inline struct BerrySpriteData *GetBerrySpriteDataAsStructPtr(struct Sprite *sprite) +{ + return (void *)(&sprite->data[0]); +} // For throwing berries into the machine static void SpriteCB_Berry(struct Sprite *sprite) { - sprite->sX += sprite->sXSpeed; - sprite->sY -= sprite->sYUpSpeed; - sprite->sY += sprite->sYDownSpeed; - sprite->sTargetY += sprite->sYDownSpeed; - sprite->sYUpSpeed--; + struct BerrySpriteData *spriteData = GetBerrySpriteDataAsStructPtr(sprite); + + spriteData->sX += spriteData->sXSpeed; + spriteData->sY -= spriteData->sYUpSpeed; + spriteData->sY += spriteData->sYDownSpeed; + spriteData->sTargetY += spriteData->sYDownSpeed; + spriteData->sYUpSpeed--; - if (sprite->sTargetY < sprite->sY) + if (spriteData->sTargetY < spriteData->sY) { - sprite->sBounceSpeed = sprite->sYUpSpeed = sprite->sBounceSpeed - 1; + spriteData->sBounceSpeed = spriteData->sYUpSpeed = spriteData->sBounceSpeed - 1; - if (++sprite->sBounces > 3) - DestroySprite(sprite); + if (++spriteData->sBounces > 3) + { + DestroyBerryIconSpritePtr(sprite, spriteData->berryId, TRUE); + return; + } else + { PlaySE(SE_BALL_TRAY_EXIT); + } } - sprite->x = sprite->sX; - sprite->y = sprite->sY; + sprite->x = spriteData->sX; + sprite->y = spriteData->sY; } -static void SetBerrySpriteData(struct Sprite *sprite, s16 x, s16 y, s16 bounceSpeed, s16 xSpeed, s16 ySpeed) +static void SetBerrySpriteData(struct Sprite *sprite, s32 x, s32 y, s32 bounceSpeed, s32 xSpeed, s32 ySpeed, u32 berryId) { - sprite->sTargetY = y; - sprite->sX = x; - sprite->sY = y; - sprite->sBounceSpeed = bounceSpeed; - sprite->sYUpSpeed = 10; - sprite->sBounces = 0; - sprite->sXSpeed = xSpeed; - sprite->sYDownSpeed = ySpeed; + struct BerrySpriteData *spriteData = GetBerrySpriteDataAsStructPtr(sprite); + + spriteData->sTargetY = y; + spriteData->sX = x; + spriteData->sY = y; + spriteData->sBounceSpeed = bounceSpeed; + spriteData->sYUpSpeed = 10; + spriteData->sBounces = 0; + spriteData->sXSpeed = xSpeed; + spriteData->sYDownSpeed = ySpeed; + spriteData->berryId = berryId; sprite->callback = SpriteCB_Berry; } -#undef sTargetY -#undef sX -#undef sY -#undef sBounceSpeed -#undef sYUpSpeed -#undef sBounces -#undef sXSpeed -#undef sYDownSpeed - -static void CreateBerrySprite(u16 itemId, u8 playerId) +static void CreateBerrySprite(u32 itemId, u32 playerId) { - u8 spriteId = CreateSpinningBerrySprite(ITEM_TO_BERRY(itemId) - 1, 0, 80, playerId & 1); + u32 berryId = ITEM_TO_BERRY(itemId) - 1; + u32 spriteId = CreateSpinningBerrySprite(berryId, 0, 80, playerId & 1); SetBerrySpriteData(&gSprites[spriteId], sBerrySpriteData[playerId][0], sBerrySpriteData[playerId][1], sBerrySpriteData[playerId][2], sBerrySpriteData[playerId][3], - sBerrySpriteData[playerId][4]); + sBerrySpriteData[playerId][4], + berryId); } static void ConvertItemToBlenderBerry(struct BlenderBerry* berry, u16 itemId) @@ -1612,6 +1628,9 @@ static void PrintPlayerNames(void) } } +// This is a small little addition, that basically speeds up the animation where all players' berries are thrown into the blender. Self-explanatory I hope! +#define BERRY_BLENDER_THROW_ALL_BERRIES_AT_ONCE TRUE + static void CB2_StartBlenderLocal(void) { s32 i, j; @@ -1676,13 +1695,14 @@ static void CB2_StartBlenderLocal(void) u32 playerId = sPlayerIdMap[sBerryBlender->numPlayers - 2][i]; if (sBerryBlender->playerToThrowBerry == playerId) { - CreateBerrySprite(sBerryBlender->chosenItemId[sBerryBlender->playerToThrowBerry], i); - break; + CreateBerrySprite(sBerryBlender->chosenItemId[sBerryBlender->playerToThrowBerry++], i); + // If we're throwing all at once, continue the loop. If not, break out of the loop(vanilla behavior). + if (!BERRY_BLENDER_THROW_ALL_BERRIES_AT_ONCE) + break; } } sBerryBlender->framesToWait = 0; sBerryBlender->mainState++; - sBerryBlender->playerToThrowBerry++; break; case 12: if (++sBerryBlender->framesToWait > 60) diff --git a/src/berry_tag_screen.c b/src/berry_tag_screen.c index fcd322ce3374..1f9d403ea5de 100644 --- a/src/berry_tag_screen.c +++ b/src/berry_tag_screen.c @@ -43,6 +43,7 @@ struct BerryTagScreenStruct { u16 tilemapBuffers[3][0x400]; u16 berryId; + u16 currentSpriteBerryId; u8 berrySpriteId; u8 flavorCircleIds[FLAVOR_COUNT]; u16 gfxState; @@ -466,13 +467,13 @@ static void PrintBerryDescription2(void) static void CreateBerrySprite(void) { - sBerryTag->berrySpriteId = CreateBerryTagSprite(sBerryTag->berryId - 1, 56, 64); + sBerryTag->currentSpriteBerryId = sBerryTag->berryId - 1; + sBerryTag->berrySpriteId = CreateBerryTagSprite(sBerryTag->currentSpriteBerryId, 56, 64); } static void DestroyBerrySprite(void) { - DestroySprite(&gSprites[sBerryTag->berrySpriteId]); - FreeBerryTagSpritePalette(); + DestroyBerryIconSprite(sBerryTag->berrySpriteId, sBerryTag->currentSpriteBerryId, TRUE); } static void CreateFlavorCircleSprites(void) diff --git a/src/contest_link.c b/src/contest_link.c index 9a960e00ac93..f2a571c3e9e8 100644 --- a/src/contest_link.c +++ b/src/contest_link.c @@ -21,7 +21,6 @@ static void Task_LinkContest_InitFlags(u8); bool32 LinkContest_SendBlock(void *src, u16 size) { - memcpy(gDecompressionBuffer, src, size); if (SendBlock(BitmaskAllOtherLinkPlayers(), gDecompressionBuffer, size)) return TRUE; else diff --git a/src/item_menu_icons.c b/src/item_menu_icons.c index 4e6339ba3096..29cdb224bbe4 100644 --- a/src/item_menu_icons.c +++ b/src/item_menu_icons.c @@ -6,9 +6,12 @@ #include "item_menu.h" #include "item_icon.h" #include "item_menu_icons.h" +#include "malloc.h" #include "menu_helpers.h" +#include "menu.h" #include "sprite.h" #include "window.h" +#include "util.h" #include "constants/items.h" enum { @@ -269,18 +272,13 @@ static const union AnimCmd *const sBerryPicSpriteAnimTable[] = sAnim_BerryPic }; -static const struct SpriteFrameImage sBerryPicSpriteImageTable[] = -{ - {&gDecompressionBuffer[0], 0x800}, -}; - static const struct SpriteTemplate sBerryPicSpriteTemplate = { .tileTag = TAG_NONE, .paletteTag = TAG_BERRY_PIC_PAL, .oam = &sBerryPicOamData, .anims = sBerryPicSpriteAnimTable, - .images = sBerryPicSpriteImageTable, + .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; @@ -319,7 +317,7 @@ static const struct SpriteTemplate sBerryPicRotatingSpriteTemplate = .paletteTag = TAG_BERRY_PIC_PAL, .oam = &sBerryPicRotatingOamData, .anims = sBerryPicSpriteAnimTable, - .images = sBerryPicSpriteImageTable, + .images = NULL, .affineAnims = sBerryPicRotatingAnimCmds, .callback = SpriteCallbackDummy, }; @@ -640,47 +638,83 @@ static void ArrangeBerryGfx(void *src, void *dest) } } -static void LoadBerryGfx(u8 berryId) +#define BERRY_SPRITE_SIZE ((64*64)/2) // 0x800 + +struct BerryDynamicGfx { - struct CompressedSpritePalette pal; + ALIGNED(4) u8 gfx[BERRY_SPRITE_SIZE]; + struct SpriteFrameImage images[1]; +}; - if (berryId == ITEM_TO_BERRY(ITEM_ENIGMA_BERRY_E_READER) - 1 && IsEnigmaBerryValid()) - { - // unknown empty if statement - } +static struct BerryDynamicGfx *LoadBerryGfx(u8 berryId) +{ + struct CompressedSpritePalette pal; pal.data = sBerryPicTable[berryId].pal; - pal.tag = TAG_BERRY_PIC_PAL; + pal.tag = TAG_BERRY_PIC_PAL + berryId; LoadCompressedSpritePalette(&pal); - LZDecompressWram(sBerryPicTable[berryId].tiles, &gDecompressionBuffer[0x1000]); - ArrangeBerryGfx(&gDecompressionBuffer[0x1000], &gDecompressionBuffer[0]); + struct BerryDynamicGfx *gfxAlloced = Alloc(sizeof(struct BerryDynamicGfx)); + void *buffer = malloc_and_decompress(sBerryPicTable[berryId].tiles, NULL); + ArrangeBerryGfx(buffer, gfxAlloced->gfx); + Free(buffer); + + return gfxAlloced; } -u8 CreateBerryTagSprite(u8 id, s16 x, s16 y) +static u32 CreateBerrySprite(const struct SpriteTemplate *sprTemplate, u32 berryId, s32 x, s32 y) { - LoadBerryGfx(id); - return CreateSprite(&sBerryPicSpriteTemplate, x, y, 0); + u32 spriteId; + struct BerryDynamicGfx *dynamicGfx = LoadBerryGfx(berryId); + struct SpriteTemplate newSprTemplate = *sprTemplate; + + newSprTemplate.paletteTag += berryId; + newSprTemplate.images = dynamicGfx->images; + + dynamicGfx->images[0].data = dynamicGfx->gfx; + dynamicGfx->images[0].size = BERRY_SPRITE_SIZE; + dynamicGfx->images[0].relativeFrames = FALSE; + + spriteId = CreateSprite(&newSprTemplate, x, y, 0); + StoreWordInTwoHalfwords((u16 *) &gSprites[spriteId].data[BERRY_ICON_GFX_PTR_DATA_ID], (u32) dynamicGfx); + return spriteId; } -void FreeBerryTagSpritePalette(void) +u32 CreateBerryTagSprite(u32 id, s32 x, s32 y) { - FreeSpritePaletteByTag(TAG_BERRY_PIC_PAL); + return CreateBerrySprite(&sBerryPicSpriteTemplate, id, x, y); } // For throwing berries into the Berry Blender -u8 CreateSpinningBerrySprite(u8 berryId, u8 x, u8 y, bool8 startAffine) +u32 CreateSpinningBerrySprite(u32 berryId, s32 x, s32 y, bool32 startAffine) { - u8 spriteId; - - FreeSpritePaletteByTag(TAG_BERRY_PIC_PAL); - LoadBerryGfx(berryId); - spriteId = CreateSprite(&sBerryPicRotatingSpriteTemplate, x, y, 0); - if (startAffine == TRUE) + u32 spriteId = CreateBerrySprite(&sBerryPicRotatingSpriteTemplate, berryId, x, y); + if (startAffine) StartSpriteAffineAnim(&gSprites[spriteId], 1); return spriteId; } +void DestroyBerryIconSprite(u32 spriteId, u32 berryId, bool32 freePal) +{ + DestroyBerryIconSpritePtr(&gSprites[spriteId], berryId, freePal); +} + +void DestroyBerryIconSpritePtr(struct Sprite *sprite, u32 berryId, bool32 freePal) +{ + u32 gfxBuffer; + + LoadWordFromTwoHalfwords((u16 *) &sprite->data[BERRY_ICON_GFX_PTR_DATA_ID], &gfxBuffer); + Free((void *)gfxBuffer); + DestroySprite(sprite); + if (freePal) + FreeBerryIconSpritePalette(berryId); +} + +void FreeBerryIconSpritePalette(u32 berryId) +{ + FreeSpritePaletteByTag(TAG_BERRY_PIC_PAL + berryId); +} + u8 CreateBerryFlavorCircleSprite(s16 x) { return CreateSprite(&sBerryCheckCircleSpriteTemplate, x, 116, 0); diff --git a/src/palette.c b/src/palette.c index 2526479ca8df..f9a074d41e66 100644 --- a/src/palette.c +++ b/src/palette.c @@ -2,6 +2,8 @@ #include "palette.h" #include "util.h" #include "decompress.h" +#include "malloc.h" +#include "menu.h" #include "gpu_regs.h" #include "task.h" #include "constants/rgb.h" @@ -40,9 +42,9 @@ static const u8 sRoundedDownGrayscaleMap[] = { void LoadCompressedPalette(const u32 *src, u32 offset, u32 size) { - LZDecompressWram(src, gDecompressionBuffer); - CpuCopy16(gDecompressionBuffer, &gPlttBufferUnfaded[offset], size); - CpuCopy16(gDecompressionBuffer, &gPlttBufferFaded[offset], size); + void *buffer = malloc_and_decompress(src, NULL); + LoadPalette(buffer, offset, size); + Free(buffer); } void LoadPalette(const void *src, u32 offset, u32 size) From 67d5c03b0a29cd27512062904defe4ae643c8565 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Jan 2025 12:22:44 +0100 Subject: [PATCH 04/11] more gDecompressionBuffer --- include/item_menu_icons.h | 8 ++++---- src/fldeff_sweetscent.c | 29 +++++++++++++++++++++++++---- src/pokemon_sprite_visualizer.c | 7 ++++--- src/pokenav_main_menu.c | 17 +++++++++-------- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/include/item_menu_icons.h b/include/item_menu_icons.h index dbffa65f7340..c0eb67a6aa05 100644 --- a/include/item_menu_icons.h +++ b/include/item_menu_icons.h @@ -18,17 +18,17 @@ void CreateItemMenuSwapLine(void); void SetItemMenuSwapLineInvisibility(bool8 invisible); void UpdateItemMenuSwapLinePos(u8 y); -// Note: Because of removing gDecompressionBuffer and allowing to create more than berry sprite at a time, the memory for gfx is allocated dynamically. -// For CreateBerryTagSprite and CreateSpinningBerrySprite the allocated ptr is stored in two last data fields(data[6], data[7]), so make sure to NOT put anything in there! +// Note: Because of removing gDecompressionBuffer and allowing to create more than one berry sprite at a time, the memory for gfx is allocated dynamically. +// For CreateBerryTagSprite and CreateSpinningBerrySprite, the allocated ptr is stored in two last data fields(data[6], data[7]), so make sure to NOT put anything in there! // The corresponding code has already been edited in berry_tag_screen.c and berry_blender.c #define BERRY_ICON_GFX_PTR_DATA_ID 6 u32 CreateBerryTagSprite(u32 id, s32 x, s32 y); u32 CreateSpinningBerrySprite(u32 berryId, s32 x, s32 y, bool32 startAffine); -// Needs to call either of these always after creating a Berry Icon sprite, because it frees allocated memory! +// Needs to always call either of these after creating a Berry Icon sprite, because it frees allocated memory! void DestroyBerryIconSprite(u32 spriteId, u32 berryId, bool32 freePal); void DestroyBerryIconSpritePtr(struct Sprite *sprite, u32 berryId, bool32 freePal); -void FreeBerryIconSpritePalette(u32 berryId); // Unused atm, because it's also handled by DestroyBerryIconSprite. Leaving it as it still may be useful in some custom cases. +void FreeBerryIconSpritePalette(u32 berryId); // Unused atm, because it's also handled by DestroyBerryIconSprite. Leaving it as it is, because it may still be useful in some custom cases. u8 CreateBerryFlavorCircleSprite(s16 x); diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c index a5b2740458bf..cb533396d1e9 100644 --- a/src/fldeff_sweetscent.c +++ b/src/fldeff_sweetscent.c @@ -7,6 +7,7 @@ #include "field_screen_effect.h" #include "field_weather.h" #include "fldeff.h" +#include "malloc.h" #include "mirage_tower.h" #include "palette.h" #include "party_menu.h" @@ -15,6 +16,7 @@ #include "sprite.h" #include "task.h" #include "wild_encounter.h" +#include "util.h" #include "constants/field_effects.h" #include "constants/rgb.h" #include "constants/songs.h" @@ -47,20 +49,36 @@ bool8 FldEff_SweetScent(void) return FALSE; } +#define tPalBuffer1 data[1] +#define tPalBuffer2 data[2] + void StartSweetScentFieldEffect(void) { - u8 taskId; + void *palBuffer; + u32 taskId; u32 palettes = ~(1 << (gSprites[GetPlayerAvatarSpriteId()].oam.paletteNum + 16) | (1 << 13) | (1 << 14) | (1 << 15)); PlaySE(SE_M_SWEET_SCENT); - CpuFastCopy(gPlttBufferUnfaded, gDecompressionBuffer, PLTT_SIZE); + palBuffer = Alloc(PLTT_SIZE); + CpuFastCopy(gPlttBufferUnfaded, palBuffer, PLTT_SIZE); CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_SIZE); BeginNormalPaletteFade(palettes, 4, 0, 8, RGB_RED); taskId = CreateTask(TrySweetScentEncounter, 0); gTasks[taskId].data[0] = 0; + StoreWordInTwoHalfwords((u16 *)&gTasks[taskId].tPalBuffer1, (u32) palBuffer); FieldEffectActiveListRemove(FLDEFF_SWEET_SCENT); } +static void FreeDestroyTask(u32 taskId) +{ + u32 palBuffer; + + LoadWordFromTwoHalfwords((u16 *)&gTasks[taskId].tPalBuffer1, &palBuffer); + Free((void *) palBuffer); + + DestroyTask(taskId); +} + static void TrySweetScentEncounter(u8 taskId) { if (!gPaletteFade.active) @@ -72,7 +90,7 @@ static void TrySweetScentEncounter(u8 taskId) gTasks[taskId].data[0] = 0; if (SweetScentWildEncounter() == TRUE) { - DestroyTask(taskId); + FreeDestroyTask(taskId); } else { @@ -95,6 +113,9 @@ static void FailSweetScentEncounter(u8 taskId) CpuFastCopy(gDecompressionBuffer, gPlttBufferUnfaded, PLTT_SIZE); SetWeatherPalStateIdle(); ScriptContext_SetupScript(EventScript_FailSweetScent); - DestroyTask(taskId); + FreeDestroyTask(taskId); } } + +#undef tPalBuffer1 +#undef tPalBuffer2 diff --git a/src/pokemon_sprite_visualizer.c b/src/pokemon_sprite_visualizer.c index c6bb39faaff8..3e245d3eb831 100644 --- a/src/pokemon_sprite_visualizer.c +++ b/src/pokemon_sprite_visualizer.c @@ -743,10 +743,11 @@ static void BattleLoadOpponentMonSpriteGfxCustom(u16 species, bool8 isFemale, bo { const u32 *lzPaletteData = GetMonSpritePalFromSpecies(species, isShiny, isFemale); u16 paletteOffset = OBJ_PLTT_ID(battlerId); + void *buffer = malloc_and_decompress(lzPaletteData, NULL); - LZDecompressWram(lzPaletteData, gDecompressionBuffer); - LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP); - LoadPalette(gDecompressionBuffer, BG_PLTT_ID(8) + BG_PLTT_ID(battlerId), PLTT_SIZE_4BPP); + LoadPalette(buffer, paletteOffset, PLTT_SIZE_4BPP); + LoadPalette(buffer, BG_PLTT_ID(8) + BG_PLTT_ID(battlerId), PLTT_SIZE_4BPP); + Free(buffer); } static void SetConstSpriteValues(struct PokemonSpriteVisualizer *data) diff --git a/src/pokenav_main_menu.c b/src/pokenav_main_menu.c index 4c4777e5d523..8952d01906d0 100644 --- a/src/pokenav_main_menu.c +++ b/src/pokenav_main_menu.c @@ -17,14 +17,15 @@ struct Pokenav_MainMenu { void (*loopTask)(u32); u32 (*isLoopTaskActiveFunc)(void); - u32 unused; u32 currentTaskId; u32 helpBarWindowId; u32 palettes; struct Sprite *spinningPokenav; struct Sprite *leftHeaderSprites[2]; struct Sprite *submenuLeftHeaderSprites[2]; - u8 tilemapBuffer[BG_SCREEN_SIZE]; + ALIGNED(4) u8 tilemapBuffer[BG_SCREEN_SIZE]; + ALIGNED(4) u8 leftHeaderMenuBuffer[0x1000]; + ALIGNED(4) u8 leftHeaderSubMenuBuffer[0x1000]; }; // This struct uses a 32bit tag, and doesn't have a size field. @@ -378,13 +379,11 @@ void SetActiveMenuLoopTasks(void *createLoopTask, void *isLoopTaskActive) // Fix struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU); menu->loopTask = createLoopTask; menu->isLoopTaskActiveFunc = isLoopTaskActive; - menu->unused = 0; } void RunMainMenuLoopedTask(u32 state) { struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU); - menu->unused = 0; menu->loopTask(state); } @@ -686,8 +685,8 @@ static void LoadLeftHeaderGfxForMenu(u32 menuGfxId) tag = sMenuLeftHeaderSpriteSheets[menuGfxId].tag; size = GetDecompressedDataSize(sMenuLeftHeaderSpriteSheets[menuGfxId].data); LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], OBJ_PLTT_ID(IndexOfSpritePaletteTag(1)), PLTT_SIZE_4BPP); - LZ77UnCompWram(sMenuLeftHeaderSpriteSheets[menuGfxId].data, gDecompressionBuffer); - RequestDma3Copy(gDecompressionBuffer, (void *)OBJ_VRAM0 + (GetSpriteTileStartByTag(2) * 32), size, 1); + LZ77UnCompWram(sMenuLeftHeaderSpriteSheets[menuGfxId].data, menu->leftHeaderMenuBuffer); + RequestDma3Copy(menu->leftHeaderMenuBuffer, (void *)OBJ_VRAM0 + (GetSpriteTileStartByTag(2) * 32), size, 1); menu->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + sMenuLeftHeaderSpriteSheets[menuGfxId].size; if (menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_OUT || menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_IN) @@ -698,16 +697,18 @@ static void LoadLeftHeaderGfxForMenu(u32 menuGfxId) static void LoadLeftHeaderGfxForSubMenu(u32 menuGfxId) { + struct Pokenav_MainMenu *menu; u32 size, tag; if (menuGfxId >= POKENAV_GFX_MENUS_END - POKENAV_GFX_SUBMENUS_START) return; + menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU); tag = sPokenavSubMenuLeftHeaderSpriteSheets[menuGfxId].tag; size = GetDecompressedDataSize(sPokenavSubMenuLeftHeaderSpriteSheets[menuGfxId].data); LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], OBJ_PLTT_ID(IndexOfSpritePaletteTag(2)), PLTT_SIZE_4BPP); - LZ77UnCompWram(sPokenavSubMenuLeftHeaderSpriteSheets[menuGfxId].data, &gDecompressionBuffer[0x1000]); - RequestDma3Copy(&gDecompressionBuffer[0x1000], (void *)OBJ_VRAM0 + 0x800 + (GetSpriteTileStartByTag(2) * 32), size, 1); + LZ77UnCompWram(sPokenavSubMenuLeftHeaderSpriteSheets[menuGfxId].data, menu->leftHeaderSubMenuBuffer); + RequestDma3Copy(menu->leftHeaderSubMenuBuffer, (void *)OBJ_VRAM0 + 0x800 + (GetSpriteTileStartByTag(2) * 32), size, 1); } void ShowLeftHeaderGfx(u32 menuGfxId, bool32 isMain, bool32 isOnRightSide) From 326ed736ba84c50dad1b9eb2bd0b11f206e70390 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Jan 2025 13:24:32 +0100 Subject: [PATCH 05/11] remove gdecompression buffer from credits --- src/credits.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/credits.c b/src/credits.c index 5d5a80cf78ed..de9a4dd00d70 100644 --- a/src/credits.c +++ b/src/credits.c @@ -272,16 +272,6 @@ static const union AnimCmd *const sAnims_Rival[] = sAnim_Rival_Still, }; -#define MONBG_OFFSET (MON_PIC_SIZE * 3) -static const struct SpriteSheet sSpriteSheet_MonBg[] = { - { gDecompressionBuffer, MONBG_OFFSET, TAG_MON_BG }, - {}, -}; -static const struct SpritePalette sSpritePalette_MonBg[] = { - { (const u16 *)&gDecompressionBuffer[MONBG_OFFSET], TAG_MON_BG }, - {}, -}; - static const struct OamData sOamData_MonBg = { .y = DISPLAY_HEIGHT, @@ -534,6 +524,8 @@ static void Task_ReadyShowMons(u8 taskId) } } +#define MONBG_OFFSET (MON_PIC_SIZE * 3) + static void Task_LoadShowMons(u8 taskId) { switch (gMain.state) @@ -541,8 +533,11 @@ static void Task_LoadShowMons(u8 taskId) default: case 0: { - u16 i; + s32 i; u16 *temp; + u8 *buffer = Alloc(MONBG_OFFSET + PLTT_SIZEOF(16)); + struct SpriteSheet bgSheet = { buffer, MONBG_OFFSET, TAG_MON_BG }; + struct SpritePalette bgPalette = { (u16 *) &buffer[MONBG_OFFSET], TAG_MON_BG }; ResetSpriteData(); ResetAllPicSprites(); @@ -553,20 +548,22 @@ static void Task_LoadShowMons(u8 taskId) LoadPalette(gBirchBagGrass_Pal + 1, BG_PLTT_ID(0) + 1, PLTT_SIZEOF(2 * 16 - 1)); for (i = 0; i < MON_PIC_SIZE; i++) - gDecompressionBuffer[i] = 0x11; - for (i = 0; i < MON_PIC_SIZE; i++) - (gDecompressionBuffer + MON_PIC_SIZE)[i] = 0x22; - for (i = 0; i < MON_PIC_SIZE; i++) - (gDecompressionBuffer + MON_PIC_SIZE * 2)[i] = 0x33; + { + buffer[i] = 0x11; + (buffer + MON_PIC_SIZE)[i] = 0x22; + (buffer + MON_PIC_SIZE * 2)[i] = 0x33; + } - temp = (u16 *)(&gDecompressionBuffer[MONBG_OFFSET]); + temp = (u16 *)(&buffer[MONBG_OFFSET]); temp[0] = RGB_BLACK; temp[1] = RGB(31, 31, 20); // light yellow temp[2] = RGB(31, 20, 20); // light red temp[3] = RGB(20, 20, 31); // light blue - LoadSpriteSheet(sSpriteSheet_MonBg); - LoadSpritePalette(sSpritePalette_MonBg); + LoadSpriteSheet(&bgSheet); + LoadSpritePalette(&bgPalette); + + Free(buffer); gMain.state++; break; From 47a0a23987701f4c2564f9f43b680c43b6b0252c Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Jan 2025 15:52:27 +0100 Subject: [PATCH 06/11] remove gdecompressbuffer from berry crm scrcmd --- asm/macros/event.inc | 2 +- src/berry_crush.c | 10 +++++----- src/fldeff_sweetscent.c | 10 +++++++--- src/scrcmd.c | 18 ++++++++++++++---- 4 files changed, 27 insertions(+), 13 deletions(-) mode change 100755 => 100644 src/berry_crush.c diff --git a/asm/macros/event.inc b/asm/macros/event.inc index b9c5d875b3eb..6168064dddb5 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1820,7 +1820,7 @@ .4byte \text .endm - @ Equivalent to fadescreen but copies gPlttBufferUnfaded to gDecompressionBuffer on the fade out + @ Equivalent to fadescreen but copies gPlttBufferUnfaded to an allocated buffer on the fade out @ and the reverse on the fade in, in effect saving gPlttBufferUnfaded to restore it. .macro fadescreenswapbuffers mode:req .byte 0xdc diff --git a/src/berry_crush.c b/src/berry_crush.c old mode 100755 new mode 100644 index 1f997708a751..8010639840a9 --- a/src/berry_crush.c +++ b/src/berry_crush.c @@ -1941,12 +1941,10 @@ static void DrawPlayerNameWindows(struct BerryCrushGame *game) // Each player name window border uses a color that corresponds to a slot of the crusher lid static void CopyPlayerNameWindowGfxToBg(struct BerryCrushGame *game) { - u8 i = 0; - u8 *windowGfx; - - LZ77UnCompWram(gBerryCrush_TextWindows_Tilemap, gDecompressionBuffer); + s32 i; + u8 *windowGfx = malloc_and_decompress(gBerryCrush_TextWindows_Tilemap, NULL); - for (windowGfx = gDecompressionBuffer; i < game->playerCount; i++) + for (i = 0; i < game->playerCount; i++) { CopyToBgTilemapBufferRect( 3, @@ -1958,6 +1956,8 @@ static void CopyPlayerNameWindowGfxToBg(struct BerryCrushGame *game) ); } CopyBgTilemapBufferToVram(3); + + Free(windowGfx); } static void CreateGameSprites(struct BerryCrushGame *game) diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c index cb533396d1e9..1be00baebca2 100644 --- a/src/fldeff_sweetscent.c +++ b/src/fldeff_sweetscent.c @@ -69,13 +69,17 @@ void StartSweetScentFieldEffect(void) FieldEffectActiveListRemove(FLDEFF_SWEET_SCENT); } -static void FreeDestroyTask(u32 taskId) +static void *GetPalBufferPtr(u32 taskId) { u32 palBuffer; LoadWordFromTwoHalfwords((u16 *)&gTasks[taskId].tPalBuffer1, &palBuffer); - Free((void *) palBuffer); + return (void *) palBuffer; +} +static void FreeDestroyTask(u32 taskId) +{ + Free(GetPalBufferPtr(taskId)); DestroyTask(taskId); } @@ -110,7 +114,7 @@ static void FailSweetScentEncounter(u8 taskId) { if (!gPaletteFade.active) { - CpuFastCopy(gDecompressionBuffer, gPlttBufferUnfaded, PLTT_SIZE); + CpuFastCopy(GetPalBufferPtr(taskId), gPlttBufferUnfaded, PLTT_SIZE); SetWeatherPalStateIdle(); ScriptContext_SetupScript(EventScript_FailSweetScent); FreeDestroyTask(taskId); diff --git a/src/scrcmd.c b/src/scrcmd.c index 54585aa5037f..3449216efba9 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -818,6 +818,8 @@ bool8 ScrCmd_fadescreenspeed(struct ScriptContext *ctx) return TRUE; } +static EWRAM_DATA u32 *sPalBuffer = NULL; + bool8 ScrCmd_fadescreenswapbuffers(struct ScriptContext *ctx) { u8 mode = ScriptReadByte(ctx); @@ -829,13 +831,21 @@ bool8 ScrCmd_fadescreenswapbuffers(struct ScriptContext *ctx) case FADE_TO_BLACK: case FADE_TO_WHITE: default: - CpuCopy32(gPlttBufferUnfaded, gDecompressionBuffer, PLTT_SIZE); - FadeScreen(mode, 0); + if (sPalBuffer == NULL) + { + sPalBuffer = Alloc(PLTT_SIZE); + CpuCopy32(gPlttBufferUnfaded, sPalBuffer, PLTT_SIZE); + FadeScreen(mode, 0); + } break; case FADE_FROM_BLACK: case FADE_FROM_WHITE: - CpuCopy32(gDecompressionBuffer, gPlttBufferUnfaded, PLTT_SIZE); - FadeScreen(mode, 0); + if (sPalBuffer != NULL) + { + CpuCopy32(sPalBuffer, gPlttBufferUnfaded, PLTT_SIZE); + FadeScreen(mode, 0); + FREE_AND_SET_NULL(sPalBuffer); + } break; } From 6de7ebae29b700b202f31dc59c0f9a21759966e0 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Jan 2025 20:58:07 +0100 Subject: [PATCH 07/11] remove gdecompression buffer from link contest link union ruum --- src/contest_link.c | 2 +- src/link.c | 11 ++--------- src/union_room.c | 13 +++++++------ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/contest_link.c b/src/contest_link.c index f2a571c3e9e8..3ddbd82b1aa9 100644 --- a/src/contest_link.c +++ b/src/contest_link.c @@ -21,7 +21,7 @@ static void Task_LinkContest_InitFlags(u8); bool32 LinkContest_SendBlock(void *src, u16 size) { - if (SendBlock(BitmaskAllOtherLinkPlayers(), gDecompressionBuffer, size)) + if (SendBlock(BitmaskAllOtherLinkPlayers(), src, size)) return TRUE; else return FALSE; diff --git a/src/link.c b/src/link.c index 501aacad2ca9..fe633c58d7cf 100644 --- a/src/link.c +++ b/src/link.c @@ -555,18 +555,11 @@ static void ProcessRecvCmds(u8 unused) { if (sBlockRecv[i].size > BLOCK_BUFFER_SIZE) { - u16 *buffer; - u16 j; - - buffer = (u16 *)gDecompressionBuffer; - for (j = 0; j < CMD_LENGTH - 1; j++) - { - buffer[(sBlockRecv[i].pos / 2) + j] = gRecvCmds[i][j + 1]; - } + // Too large block was sent. } else { - u16 j; + u32 j; for (j = 0; j < CMD_LENGTH - 1; j++) { diff --git a/src/union_room.c b/src/union_room.c index ac4c61035a2e..3337cdec93ca 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -2464,18 +2464,19 @@ static void ScheduleFieldMessageAndExit(const u8 *src) StringExpandPlaceholders(gStringVar4, src); } +#define PLAYER_LIST_BUFFER_SIZE (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)) + +// Note: This probably could be alloced instead, but I'm not familiar enough with the union room system. +static EWRAM_DATA ALIGNED(4) u8 sPlayerListBuffer[PLAYER_LIST_BUFFER_SIZE]; + static void CopyPlayerListToBuffer(struct WirelessLink_URoom *uroom) { - memcpy(&gDecompressionBuffer[sizeof(gDecompressionBuffer) - (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer))], - uroom->playerList, - MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); + memcpy(sPlayerListBuffer, uroom->playerList, PLAYER_LIST_BUFFER_SIZE); } static void CopyPlayerListFromBuffer(struct WirelessLink_URoom *uroom) { - memcpy(uroom->playerList, - &gDecompressionBuffer[sizeof(gDecompressionBuffer) - (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer))], - MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); + memcpy(uroom->playerList, sPlayerListBuffer, PLAYER_LIST_BUFFER_SIZE); } static void Task_RunUnionRoom(u8 taskId) From 3f2082c5541b348710a1e2be023929700204d1d3 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Jan 2025 21:20:16 +0100 Subject: [PATCH 08/11] remove decomp buffer from save failed screeen --- src/save_failed_screen.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/save_failed_screen.c b/src/save_failed_screen.c index 9bd981facc35..08cc1aaeb9fe 100644 --- a/src/save_failed_screen.c +++ b/src/save_failed_screen.c @@ -1,6 +1,7 @@ #include "global.h" #include "text.h" #include "main.h" +#include "malloc.h" #include "palette.h" #include "graphics.h" #include "gpu_regs.h" @@ -171,6 +172,15 @@ static void VBlankCB(void) TransferPlttBuffer(); } +struct SaveFailedBuffers +{ + ALIGNED(4) u8 tilemapBuffer[BG_SCREEN_SIZE]; + ALIGNED(4) u8 window1TileData[0x200]; + ALIGNED(4) u8 window2TileData[0x200]; +}; + +static EWRAM_DATA struct SaveFailedBuffers *sSaveFailedBuffers = NULL; + static void CB2_SaveFailedScreen(void) { switch (gMain.state) @@ -178,6 +188,7 @@ static void CB2_SaveFailedScreen(void) case 0: default: SetVBlankCallback(NULL); + sSaveFailedBuffers = Alloc(sizeof(*sSaveFailedBuffers)); SetGpuReg(REG_OFFSET_DISPCNT, 0); SetGpuReg(REG_OFFSET_BG3CNT, 0); SetGpuReg(REG_OFFSET_BG2CNT, 0); @@ -200,14 +211,14 @@ static void CB2_SaveFailedScreen(void) LZ77UnCompVram(sSaveFailedClockGfx, (void *)(OBJ_VRAM0 + 0x20)); ResetBgsAndClearDma3BusyFlags(0); InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); - SetBgTilemapBuffer(0, (void *)&gDecompressionBuffer[0x2000]); - CpuFill32(0, &gDecompressionBuffer[0x2000], 0x800); + SetBgTilemapBuffer(0, sSaveFailedBuffers->tilemapBuffer); + CpuFill32(0, sSaveFailedBuffers->tilemapBuffer, BG_SCREEN_SIZE); LoadBgTiles(0, gTextWindowFrame1_Gfx, 0x120, 0x214); InitWindows(sDummyWindowTemplate); sWindowIds[TEXT_WIN_ID] = AddWindowWithoutTileMap(sWindowTemplate_Text); - SetWindowAttribute(sWindowIds[TEXT_WIN_ID], 7, (u32)&gDecompressionBuffer[0x2800]); + SetWindowAttribute(sWindowIds[TEXT_WIN_ID], 7, (u32)&sSaveFailedBuffers->window1TileData); sWindowIds[CLOCK_WIN_ID] = AddWindowWithoutTileMap(sWindowTemplate_Clock); - SetWindowAttribute(sWindowIds[CLOCK_WIN_ID], 7, (u32)&gDecompressionBuffer[0x3D00]); + SetWindowAttribute(sWindowIds[CLOCK_WIN_ID], 7, (u32)&sSaveFailedBuffers->window2TileData); DeactivateAllTextPrinters(); ResetSpriteData(); ResetTasks(); @@ -318,6 +329,7 @@ static void CB2_ReturnToTitleScreen(void) { if (!UpdatePaletteFade()) { + TRY_FREE_AND_SET_NULL(sSaveFailedBuffers); if (gGameContinueCallback == NULL) // no callback exists, so do a soft reset. { DoSoftReset(); From 0df38fd4152deb0225ee6a230dc11f36e395f284 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Jan 2025 21:25:25 +0100 Subject: [PATCH 09/11] free buffer --- src/bg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bg.c b/src/bg.c index 5f973c388bbf..73b5be14e81d 100644 --- a/src/bg.c +++ b/src/bg.c @@ -3,6 +3,7 @@ #include "bg.h" #include "dma3.h" #include "gpu_regs.h" +#include "malloc.h" #include "menu.h" #define DISPCNT_ALL_BG_AND_MODE_BITS (DISPCNT_BG_ALL_ON | 0x7) @@ -882,6 +883,7 @@ void DecompressAndCopyToBgTilemapBuffer(u32 bg, const u32 *src, u32 mode, u32 de void *buffer = malloc_and_decompress(src, NULL); CopyToBgTilemapBuffer(bg, buffer, mode, destOffset); + Free(buffer); } void CopyBgTilemapBufferToVram(u32 bg) From 096f31ad5a10360145f3694731c69f0770a5dc46 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 17 Jan 2025 11:35:21 +0100 Subject: [PATCH 10/11] remove gDecompBuffer from Hall of fAME --- include/hall_of_fame.h | 17 +++++++++ include/mystery_gift_client.h | 1 + src/ereader_screen.c | 25 +++---------- src/hall_of_fame.c | 69 ++++++++++++++++------------------- src/mystery_event_menu.c | 4 ++ src/mystery_gift_client.c | 4 +- src/save.c | 25 +++++++++---- 7 files changed, 78 insertions(+), 67 deletions(-) diff --git a/include/hall_of_fame.h b/include/hall_of_fame.h index f1f4567135d1..53c913b86a4c 100644 --- a/include/hall_of_fame.h +++ b/include/hall_of_fame.h @@ -1,6 +1,23 @@ #ifndef GUARD_HALL_OF_FAME_H #define GUARD_HALL_OF_FAME_H +struct HallofFameMon +{ + u32 tid; + u32 personality; + u16 isShiny:1; + u16 species:15; + u8 lvl; + u8 nickname[POKEMON_NAME_LENGTH]; +}; + +struct HallofFameTeam +{ + struct HallofFameMon mon[PARTY_SIZE]; +}; + +extern struct HallofFameTeam *gHoFSaveBuffer; + void CB2_DoHallOfFameScreen(void); void CB2_DoHallOfFameScreenDontSaveData(void); void CB2_DoHallOfFamePC(void); diff --git a/include/mystery_gift_client.h b/include/mystery_gift_client.h index 8214d69eff98..a17778f41a34 100644 --- a/include/mystery_gift_client.h +++ b/include/mystery_gift_client.h @@ -81,6 +81,7 @@ struct MysteryGiftClient void * msg; struct MysteryGiftLink link; bool32 isWonderNews; + ALIGNED(4) u8 bufferScript[MG_LINK_BUFFER_SIZE]; }; void MysteryGiftClient_Create(bool32 isWonderNews); diff --git a/src/ereader_screen.c b/src/ereader_screen.c index ef1f45d49a0b..2e5bbe117698 100644 --- a/src/ereader_screen.c +++ b/src/ereader_screen.c @@ -18,17 +18,10 @@ struct EReaderTaskData { u16 timer; - u16 unused1; - u16 unused2; - u16 unused3; u8 state; u8 textState; - u8 unused4; - u8 unused5; - u8 unused6; - u8 unused7; u8 status; - u8 *unusedBuffer; + u8 *buffer; }; struct EReaderData @@ -98,7 +91,6 @@ static u8 EReader_Transfer(struct EReaderData *eReader) static void OpenEReaderLink(void) { - memset(gDecompressionBuffer, 0, 0x2000); gLinkType = LINKTYPE_EREADER_EM; OpenLink(); SetSuppressLinkErrorMessage(TRUE); @@ -251,16 +243,9 @@ void CreateEReaderTask(void) data = (struct EReaderTaskData *)gTasks[taskId].data; data->state = 0; data->textState = 0; - data->unused4 = 0; - data->unused5 = 0; - data->unused6 = 0; - data->unused7 = 0; data->timer = 0; - data->unused1 = 0; - data->unused2 = 0; - data->unused3 = 0; data->status = 0; - data->unusedBuffer = AllocZeroed(CLIENT_MAX_MSG_SIZE); + data->buffer = AllocZeroed(0x2000); } static void ResetTimer(u16 *timer) @@ -471,7 +456,7 @@ static void Task_EReader(u8 taskId) } break; case ER_STATE_VALIDATE_CARD: - data->status = ValidateTrainerHillData((struct EReaderTrainerHillSet *)gDecompressionBuffer); + data->status = ValidateTrainerHillData((struct EReaderTrainerHillSet *)data->buffer); SetCloseLinkCallbackAndType(data->status); data->state = ER_STATE_WAIT_DISCONNECT; break; @@ -485,7 +470,7 @@ static void Task_EReader(u8 taskId) } break; case ER_STATE_SAVE: - if (TryWriteTrainerHill((struct EReaderTrainerHillSet *)&gDecompressionBuffer)) + if (TryWriteTrainerHill((struct EReaderTrainerHillSet *)data->buffer)) { MG_AddMessageTextPrinter(gJPText_ConnectionComplete); ResetTimer(&data->timer); @@ -525,7 +510,7 @@ static void Task_EReader(u8 taskId) data->state = ER_STATE_START; break; case ER_STATE_END: - Free(data->unusedBuffer); + Free(data->buffer); DestroyTask(taskId); SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen); break; diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c index 1c3b00f2ef1b..1a8906d975f0 100644 --- a/src/hall_of_fame.c +++ b/src/hall_of_fame.c @@ -38,21 +38,6 @@ #define HALL_OF_FAME_MAX_TEAMS 30 #define TAG_CONFETTI 1001 -struct HallofFameMon -{ - u32 tid; - u32 personality; - u16 isShiny:1; - u16 species:15; - u8 lvl; - u8 nickname[POKEMON_NAME_LENGTH]; -}; - -struct HallofFameTeam -{ - struct HallofFameMon mon[PARTY_SIZE]; -}; - STATIC_ASSERT(sizeof(struct HallofFameTeam) * HALL_OF_FAME_MAX_TEAMS <= SECTOR_DATA_SIZE * NUM_HOF_SECTORS, HallOfFameFreeSpace); struct HofGfx @@ -66,6 +51,7 @@ struct HofGfx static EWRAM_DATA u32 sHofFadePalettes = 0; static EWRAM_DATA struct HallofFameTeam *sHofMonPtr = NULL; static EWRAM_DATA struct HofGfx *sHofGfxPtr = NULL; +EWRAM_DATA struct HallofFameTeam *gHoFSaveBuffer = NULL; static void ClearVramOamPltt_LoadHofPal(void); static void LoadHofGfx(void); @@ -416,13 +402,19 @@ static bool8 InitHallOfFameScreen(void) #define tPlayerSpriteID data[4] #define tMonSpriteId(i) data[i + 5] +static void AllocateHoFTeams(void) +{ + sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr)); + gHoFSaveBuffer = Alloc(SECTOR_SIZE * NUM_HOF_SECTORS); +} + void CB2_DoHallOfFameScreen(void) { if (!InitHallOfFameScreen()) { u8 taskId = CreateTask(Task_Hof_InitMonData, 0); gTasks[taskId].tDontSaveData = FALSE; - sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr)); + AllocateHoFTeams(); } } @@ -432,7 +424,7 @@ void CB2_DoHallOfFameScreenDontSaveData(void) { u8 taskId = CreateTask(Task_Hof_InitMonData, 0); gTasks[taskId].tDontSaveData = TRUE; - sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr)); + AllocateHoFTeams(); } } @@ -486,16 +478,16 @@ static void Task_Hof_InitMonData(u8 taskId) static void Task_Hof_InitTeamSaveData(u8 taskId) { u16 i; - struct HallofFameTeam *lastSavedTeam = (struct HallofFameTeam *)(gDecompressionBuffer); + struct HallofFameTeam *lastSavedTeam = gHoFSaveBuffer; if (!gHasHallOfFameRecords) { - memset(gDecompressionBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS); + memset(gHoFSaveBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS); } else { if (LoadGameSave(SAVE_HALL_OF_FAME) != SAVE_STATUS_OK) - memset(gDecompressionBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS); + memset(gHoFSaveBuffer, 0, SECTOR_SIZE * NUM_HOF_SECTORS); } for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++) @@ -505,8 +497,8 @@ static void Task_Hof_InitTeamSaveData(u8 taskId) } if (i >= HALL_OF_FAME_MAX_TEAMS) { - struct HallofFameTeam *afterTeam = (struct HallofFameTeam *)(gDecompressionBuffer); - struct HallofFameTeam *beforeTeam = (struct HallofFameTeam *)(gDecompressionBuffer); + struct HallofFameTeam *afterTeam = gHoFSaveBuffer; + struct HallofFameTeam *beforeTeam = gHoFSaveBuffer; afterTeam++; for (i = 0; i < HALL_OF_FAME_MAX_TEAMS - 1; i++, beforeTeam++, afterTeam++) { @@ -522,6 +514,13 @@ static void Task_Hof_InitTeamSaveData(u8 taskId) gTasks[taskId].func = Task_Hof_TrySaveData; } +static void FreeAllHoFMem(void) +{ + TRY_FREE_AND_SET_NULL(sHofGfxPtr); + TRY_FREE_AND_SET_NULL(sHofMonPtr); + TRY_FREE_AND_SET_NULL(gHoFSaveBuffer); +} + static void Task_Hof_TrySaveData(u8 taskId) { gGameContinueCallback = CB2_DoHallOfFameScreenDontSaveData; @@ -531,8 +530,7 @@ static void Task_Hof_TrySaveData(u8 taskId) UnsetBgTilemapBuffer(3); FreeAllWindowBuffers(); - TRY_FREE_AND_SET_NULL(sHofGfxPtr); - TRY_FREE_AND_SET_NULL(sHofMonPtr); + FreeAllHoFMem(); DestroyTask(taskId); } @@ -772,10 +770,7 @@ static void Task_Hof_HandleExit(u8 taskId) UnsetBgTilemapBuffer(3); ResetBgsAndClearDma3BusyFlags(0); DestroyTask(taskId); - - TRY_FREE_AND_SET_NULL(sHofGfxPtr); - TRY_FREE_AND_SET_NULL(sHofMonPtr); - + FreeAllHoFMem(); StartCredits(); } } @@ -807,6 +802,7 @@ void CB2_DoHallOfFamePC(void) SetVBlankCallback(NULL); ClearVramOamPltt_LoadHofPal(); sHofGfxPtr = AllocZeroed(sizeof(*sHofGfxPtr)); + AllocateHoFTeams(); gMain.state = 1; break; case 1: @@ -823,7 +819,7 @@ void CB2_DoHallOfFamePC(void) case 3: if (!LoadHofBgs()) { - struct HallofFameTeam *fameTeam = (struct HallofFameTeam *)(gDecompressionBuffer); + struct HallofFameTeam *fameTeam = gHoFSaveBuffer; fameTeam->mon[0] = sDummyFameMon; ComputerScreenOpenEffect(0, 0, 0); SetVBlankCallback(VBlankCB_HallOfFame); @@ -852,7 +848,6 @@ void CB2_DoHallOfFamePC(void) gTasks[taskId].tMonSpriteId(i) = SPRITE_NONE; } - sHofMonPtr = AllocZeroed(SECTOR_SIZE * NUM_HOF_SECTORS); SetMainCallback2(CB2_HallOfFame); } break; @@ -871,8 +866,7 @@ static void Task_HofPC_CopySaveData(u8 taskId) u16 i; struct HallofFameTeam *savedTeams; - CpuCopy16(gDecompressionBuffer, sHofMonPtr, SECTOR_SIZE * NUM_HOF_SECTORS); - savedTeams = sHofMonPtr; + savedTeams = gHoFSaveBuffer; for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++) { if (savedTeams->mon[0].species == SPECIES_NONE) @@ -892,7 +886,7 @@ static void Task_HofPC_CopySaveData(u8 taskId) static void Task_HofPC_DrawSpritesPrintText(u8 taskId) { - struct HallofFameTeam *savedTeams = sHofMonPtr; + struct HallofFameTeam *savedTeams = gHoFSaveBuffer; struct HallofFameMon* currMon; u16 i; @@ -958,7 +952,7 @@ static void Task_HofPC_DrawSpritesPrintText(u8 taskId) static void Task_HofPC_PrintMonInfo(u8 taskId) { - struct HallofFameTeam *savedTeams = sHofMonPtr; + struct HallofFameTeam *savedTeams = gHoFSaveBuffer; struct HallofFameMon* currMon; u16 i; u16 currMonID; @@ -1047,7 +1041,7 @@ static void Task_HofPC_HandlePaletteOnExit(u8 taskId) struct HallofFameTeam *fameTeam; CpuCopy16(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_SIZE); - fameTeam = (struct HallofFameTeam *)(gDecompressionBuffer); + fameTeam = gHoFSaveBuffer; fameTeam->mon[0] = sDummyFameMon; ComputerScreenCloseEffect(0, 0, 0); gTasks[taskId].func = Task_HofPC_HandleExit; @@ -1057,7 +1051,7 @@ static void Task_HofPC_HandleExit(u8 taskId) { if (!IsComputerScreenCloseEffectActive()) { - u8 i; + s32 i; for (i = 0; i < PARTY_SIZE; i++) { @@ -1079,8 +1073,7 @@ static void Task_HofPC_HandleExit(u8 taskId) ResetBgsAndClearDma3BusyFlags(0); DestroyTask(taskId); - TRY_FREE_AND_SET_NULL(sHofGfxPtr); - TRY_FREE_AND_SET_NULL(sHofMonPtr); + FreeAllHoFMem(); ReturnFromHallOfFamePC(); } diff --git a/src/mystery_event_menu.c b/src/mystery_event_menu.c index 67ec7855adef..82a9cf18314b 100644 --- a/src/mystery_event_menu.c +++ b/src/mystery_event_menu.c @@ -255,10 +255,14 @@ static void CB2_MysteryEventMenu(void) case 11: if (gReceivedRemoteLinkPlayers == 0) { + // No clue what is going on here, and from where gDecompressionBuffer gets actually populated with mystery event script. + /* u16 status = RunMysteryEventScript(gDecompressionBuffer); CpuFill32(0, gDecompressionBuffer, 0x7D4); + if (!GetEventLoadMessage(gStringVar4, status)) TrySavingData(SAVE_NORMAL); + */ gMain.state++; } break; diff --git a/src/mystery_gift_client.c b/src/mystery_gift_client.c index 62ab85b43df3..3663df43d5e8 100644 --- a/src/mystery_gift_client.c +++ b/src/mystery_gift_client.c @@ -238,7 +238,7 @@ static u32 Client_Run(struct MysteryGiftClient * client) #endif //FREE_BATTLE_TOWER_E_READER break; case CLI_RUN_BUFFER_SCRIPT: - memcpy(gDecompressionBuffer, client->recvBuffer, MG_LINK_BUFFER_SIZE); + memcpy(client->bufferScript, client->recvBuffer, MG_LINK_BUFFER_SIZE); client->funcId = FUNC_RUN_BUFFER; client->funcState = 0; break; @@ -279,7 +279,7 @@ static u32 Client_RunMysteryEventScript(struct MysteryGiftClient * client) static u32 Client_RunBufferScript(struct MysteryGiftClient * client) { // exec arbitrary code - u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)gDecompressionBuffer; + u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)client->bufferScript; if (func(&client->param, gSaveBlock2Ptr, gSaveBlock1Ptr) == 1) { client->funcId = FUNC_RUN; diff --git a/src/save.c b/src/save.c index 7d7d1e42926b..65e496b0d0dc 100644 --- a/src/save.c +++ b/src/save.c @@ -7,6 +7,7 @@ #include "decompress.h" #include "load_save.h" #include "overworld.h" +#include "hall_of_fame.h" #include "pokemon_storage_system.h" #include "main.h" #include "trainer_hill.h" @@ -716,7 +717,6 @@ u8 HandleSavingData(u8 saveType) { u8 i; u32 *backupVar = gTrainerHillVBlankCounter; - u8 *tempAddr; gTrainerHillVBlankCounter = NULL; UpdateSaveAddresses(); @@ -737,9 +737,12 @@ u8 HandleSavingData(u8 saveType) WriteSaveSectorOrSlot(FULL_SAVE_SLOT, gRamSaveSectorLocations); // Save the Hall of Fame - tempAddr = gDecompressionBuffer; - HandleWriteSectorNBytes(SECTOR_ID_HOF_1, tempAddr, SECTOR_DATA_SIZE); - HandleWriteSectorNBytes(SECTOR_ID_HOF_2, tempAddr + SECTOR_DATA_SIZE, SECTOR_DATA_SIZE); + if (gHoFSaveBuffer != NULL) + { + u8 *tempAddr = (void *) gHoFSaveBuffer; + HandleWriteSectorNBytes(SECTOR_ID_HOF_1, tempAddr, SECTOR_DATA_SIZE); + HandleWriteSectorNBytes(SECTOR_ID_HOF_2, tempAddr + SECTOR_DATA_SIZE, SECTOR_DATA_SIZE); + } break; case SAVE_NORMAL: default: @@ -897,9 +900,17 @@ u8 LoadGameSave(u8 saveType) gGameContinueCallback = 0; break; case SAVE_HALL_OF_FAME: - status = TryLoadSaveSector(SECTOR_ID_HOF_1, gDecompressionBuffer, SECTOR_DATA_SIZE); - if (status == SAVE_STATUS_OK) - status = TryLoadSaveSector(SECTOR_ID_HOF_2, &gDecompressionBuffer[SECTOR_DATA_SIZE], SECTOR_DATA_SIZE); + if (gHoFSaveBuffer != NULL) + { + u8 *hofData = (u8 *) gHoFSaveBuffer; + status = TryLoadSaveSector(SECTOR_ID_HOF_1, hofData, SECTOR_DATA_SIZE); + if (status == SAVE_STATUS_OK) + status = TryLoadSaveSector(SECTOR_ID_HOF_2, &hofData[SECTOR_DATA_SIZE], SECTOR_DATA_SIZE); + } + else + { + status = SAVE_STATUS_ERROR; + } break; } From d99501f4b2d3eb897f62f7b8b4f40fbd88c02e13 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 17 Jan 2025 11:49:38 +0100 Subject: [PATCH 11/11] gDecompressionBuffer is no more --- include/decompress.h | 6 ++---- include/sprite.h | 6 +++--- src/decompress.c | 12 ++++++------ src/event_object_movement.c | 14 +++++++++----- src/sprite.c | 10 +++++----- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/include/decompress.h b/include/decompress.h index 66bc22d935c5..1c6ab7ee2476 100644 --- a/include/decompress.h +++ b/include/decompress.h @@ -5,8 +5,6 @@ #define MAX_DECOMPRESSION_BUFFER_SIZE 0x4000 -extern u8 ALIGNED(4) gDecompressionBuffer[MAX_DECOMPRESSION_BUFFER_SIZE]; - void LZDecompressWram(const u32 *src, void *dest); void LZDecompressVram(const u32 *src, void *dest); @@ -17,8 +15,8 @@ u32 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s u32 LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer); bool8 LoadCompressedSpriteSheetUsingHeap(const struct CompressedSpriteSheet *src); -void LoadCompressedSpritePalette(const struct CompressedSpritePalette *src); -void LoadCompressedSpritePaletteWithTag(const u32 *pal, u16 tag); +u32 LoadCompressedSpritePalette(const struct CompressedSpritePalette *src); +u32 LoadCompressedSpritePaletteWithTag(const u32 *pal, u16 tag); void LoadCompressedSpritePaletteOverrideBuffer(const struct CompressedSpritePalette *src, void *buffer); bool8 LoadCompressedSpritePaletteUsingHeap(const struct CompressedSpritePalette *src); diff --git a/include/sprite.h b/include/sprite.h index 937ed42ced5f..48e448bf1c07 100644 --- a/include/sprite.h +++ b/include/sprite.h @@ -316,10 +316,10 @@ u16 GetSpriteTileTagByTileStart(u16 start); void RequestSpriteSheetCopy(const struct SpriteSheet *sheet); u16 LoadSpriteSheetDeferred(const struct SpriteSheet *sheet); void FreeAllSpritePalettes(void); -u8 LoadSpritePalette(const struct SpritePalette *palette); +u32 LoadSpritePalette(const struct SpritePalette *palette); void LoadSpritePalettes(const struct SpritePalette *palettes); -u8 AllocSpritePalette(u16 tag); -u8 IndexOfSpritePaletteTag(u16 tag); +u32 AllocSpritePalette(u16 tag); +u32 IndexOfSpritePaletteTag(u16 tag); u16 GetSpritePaletteTagByPaletteNum(u8 paletteNum); void FreeSpritePaletteByTag(u16 tag); void SetSubspriteTables(struct Sprite *sprite, const struct SubspriteTable *subspriteTables); diff --git a/src/decompress.c b/src/decompress.c index 8c1043dfbb02..c8513825898b 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -7,8 +7,6 @@ #include "text.h" #include "menu.h" -EWRAM_DATA ALIGNED(4) u8 gDecompressionBuffer[0x4000] = {0}; - void LZDecompressWram(const u32 *src, void *dest) { LZ77UnCompWram(src, dest); @@ -88,20 +86,22 @@ u32 LoadCompressedSpriteSheetByTemplate(const struct SpriteTemplate *template, s return ret; } -void LoadCompressedSpritePalette(const struct CompressedSpritePalette *src) +u32 LoadCompressedSpritePalette(const struct CompressedSpritePalette *src) { - LoadCompressedSpritePaletteWithTag(src->data, src->tag); + return LoadCompressedSpritePaletteWithTag(src->data, src->tag); } -void LoadCompressedSpritePaletteWithTag(const u32 *pal, u16 tag) +u32 LoadCompressedSpritePaletteWithTag(const u32 *pal, u16 tag) { + u32 index; struct SpritePalette dest; void *buffer = malloc_and_decompress(pal, NULL); dest.data = buffer; dest.tag = tag; - LoadSpritePalette(&dest); + index = LoadSpritePalette(&dest); Free(buffer); + return index; } void LoadCompressedSpritePaletteOverrideBuffer(const struct CompressedSpritePalette *src, void *buffer) diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 581cd946204c..17985973e210 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -2055,15 +2055,19 @@ static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny) spritePalette.data = gSpeciesInfo[species].overworldPalette; } - // Check if pal data must be decompressed if (IsLZ77Data(spritePalette.data, PLTT_SIZE_4BPP, PLTT_SIZE_4BPP)) { - // IsLZ77Data guarantees word-alignment, so casting this is safe - LZ77UnCompWram((u32*)spritePalette.data, gDecompressionBuffer); - spritePalette.data = (void*)gDecompressionBuffer; + struct CompressedSpritePalette compSpritePalette; + + compSpritePalette.data = (const void *) spritePalette.data; + compSpritePalette.tag = spritePalette.tag; + paletteNum = LoadCompressedSpritePalette(&compSpritePalette); + } + else + { + paletteNum = LoadSpritePalette(&spritePalette); } - paletteNum = LoadSpritePalette(&spritePalette); } else #endif //OW_POKEMON_OBJECT_EVENTS == TRUE && OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE diff --git a/src/sprite.c b/src/sprite.c index 14e9409c6649..2842de58473d 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -1569,9 +1569,9 @@ void FreeAllSpritePalettes(void) sSpritePaletteTags[i] = TAG_NONE; } -u8 LoadSpritePalette(const struct SpritePalette *palette) +u32 LoadSpritePalette(const struct SpritePalette *palette) { - u8 index = IndexOfSpritePaletteTag(palette->tag); + u32 index = IndexOfSpritePaletteTag(palette->tag); if (index != 0xFF) return index; @@ -1603,9 +1603,9 @@ void DoLoadSpritePalette(const u16 *src, u16 paletteOffset) LoadPalette(src, OBJ_PLTT_OFFSET + paletteOffset, PLTT_SIZE_4BPP); } -u8 AllocSpritePalette(u16 tag) +u32 AllocSpritePalette(u16 tag) { - u8 index = IndexOfSpritePaletteTag(TAG_NONE); + u32 index = IndexOfSpritePaletteTag(TAG_NONE); if (index == 0xFF) { return 0xFF; @@ -1617,7 +1617,7 @@ u8 AllocSpritePalette(u16 tag) } } -u8 IndexOfSpritePaletteTag(u16 tag) +u32 IndexOfSpritePaletteTag(u16 tag) { u32 i; for (i = gReservedSpritePaletteCount; i < 16; i++)