diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 49d4fd3405d..b3c7ce050a6 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1823,7 +1823,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 SCR_OP_FADESCREENSWAPBUFFERS diff --git a/include/bg.h b/include/bg.h index f981ed4b8c1..89ffc8d8ebd 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/config/overworld.h b/include/config/overworld.h index 5b774ec5580..87c62435085 100644 --- a/include/config/overworld.h +++ b/include/config/overworld.h @@ -113,4 +113,7 @@ #define OW_UNION_DISABLE_CHECK FALSE // When TRUE, the nurse does not inform the player if there is a trainer waiting in the Union Room. This speeds up the loading of the Pokémon Center. #define OW_FLAG_MOVE_UNION_ROOM_CHECK 0 // If this flag is set, the game will only check if players are in the Union Room while healing Pokémon, and not when players enter the Pokémon Center. This speeds up the loading of the Pokémon Center. This is ignored if OW_UNION_DISABLE_CHECK is TRUE. +// Berry Blender +#define BERRY_BLENDER_THROW_ALL_BERRIES_AT_ONCE TRUE // 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! + #endif // GUARD_CONFIG_OVERWORLD_H diff --git a/include/decompress.h b/include/decompress.h index 178ab9a6ebc..1c6ab7ee247 100644 --- a/include/decompress.h +++ b/include/decompress.h @@ -3,20 +3,20 @@ #include "sprite.h" -extern u8 ALIGNED(4) gDecompressionBuffer[0x4000]; +#define MAX_DECOMPRESSION_BUFFER_SIZE 0x4000 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); -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/hall_of_fame.h b/include/hall_of_fame.h index f1f4567135d..53c913b86a4 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/item_menu_icons.h b/include/item_menu_icons.h index d01dcccf5f2..c0eb67a6aa0 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 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 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 is, because it may still be useful in some custom cases. + u8 CreateBerryFlavorCircleSprite(s16 x); #endif // GUARD_ITEM_MENU_ICONS_H diff --git a/include/mystery_gift_client.h b/include/mystery_gift_client.h index 8214d69eff9..a17778f41a3 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/include/sprite.h b/include/sprite.h index 6a7b585bf38..138c2ea5069 100644 --- a/include/sprite.h +++ b/include/sprite.h @@ -317,10 +317,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/battle_anim.c b/src/battle_anim.c index 640e0044ea6..c12a88bec7c 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_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 7677c9f38c3..945fa660ca2 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/battle_main.c b/src/battle_main.c index 0f778018552..3cf2598b012 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; diff --git a/src/battle_transition.c b/src/battle_transition.c index fbaa5cc0de3..1afbe7a026a 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/berry_blender.c b/src/berry_blender.c index bf094b6fb98..0a6eaaa2bf4 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); - if (sprite->sTargetY < sprite->sY) + spriteData->sX += spriteData->sXSpeed; + spriteData->sY -= spriteData->sYUpSpeed; + spriteData->sY += spriteData->sYDownSpeed; + spriteData->sTargetY += spriteData->sYDownSpeed; + spriteData->sYUpSpeed--; + + 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) @@ -1676,13 +1692,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_crush.c b/src/berry_crush.c old mode 100755 new mode 100644 index 1f997708a75..8010639840a --- 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/berry_tag_screen.c b/src/berry_tag_screen.c index fcd322ce337..1f9d403ea5d 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/bg.c b/src/bg.c index 27a5fb0501b..73b5be14e81 100644 --- a/src/bg.c +++ b/src/bg.c @@ -3,6 +3,8 @@ #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) @@ -865,7 +867,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 +878,14 @@ 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); + Free(buffer); +} + void CopyBgTilemapBufferToVram(u32 bg) { u16 sizeToLoad; diff --git a/src/contest_link.c b/src/contest_link.c index 9a960e00ac9..3ddbd82b1aa 100644 --- a/src/contest_link.c +++ b/src/contest_link.c @@ -21,8 +21,7 @@ static void Task_LinkContest_InitFlags(u8); bool32 LinkContest_SendBlock(void *src, u16 size) { - memcpy(gDecompressionBuffer, src, size); - if (SendBlock(BitmaskAllOtherLinkPlayers(), gDecompressionBuffer, size)) + if (SendBlock(BitmaskAllOtherLinkPlayers(), src, size)) return TRUE; else return FALSE; diff --git a/src/credits.c b/src/credits.c index 9269460e928..c06a6fca9b3 100644 --- a/src/credits.c +++ b/src/credits.c @@ -270,16 +270,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, @@ -529,6 +519,8 @@ static void Task_ReadyShowMons(u8 taskId) } } +#define MONBG_OFFSET (MON_PIC_SIZE * 3) + static void Task_LoadShowMons(u8 taskId) { switch (gMain.state) @@ -536,8 +528,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(); @@ -548,20 +543,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; diff --git a/src/decompress.c b/src/decompress.c index 284bce48d33..8c2f335614b 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -5,8 +5,7 @@ #include "pokemon.h" #include "pokemon_sprite_visualizer.h" #include "text.h" - -EWRAM_DATA ALIGNED(4) u8 gDecompressionBuffer[0x4000] = {0}; +#include "menu.h" void LZDecompressWram(const u32 *src, void *dest) { @@ -40,66 +39,69 @@ 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) +{ + LZDecompressWram(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) +u32 LoadCompressedSpritePalette(const struct CompressedSpritePalette *src) { - struct SpritePalette dest; - - LZ77UnCompWram(src->data, gDecompressionBuffer); - dest.data = (void *) gDecompressionBuffer; - dest.tag = src->tag; - LoadSpritePalette(&dest); + 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); - LZ77UnCompWram(pal, gDecompressionBuffer); - dest.data = (void *) gDecompressionBuffer; + 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/ereader_screen.c b/src/ereader_screen.c index ef1f45d49a0..2e5bbe11769 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/event_object_movement.c b/src/event_object_movement.c index 7b652b4eec2..70566188f6e 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/field_effect.c b/src/field_effect.c index 65ec704adde..cbb2e561629 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" @@ -896,8 +897,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; @@ -3939,7 +3952,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) @@ -3947,7 +3960,7 @@ u8 FldEff_CaveDust(void) gSprites[spriteId].coordOffsetEnabled = TRUE; gSprites[spriteId].data[0] = 22; } - + return spriteId; } diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c index a5b2740458b..1be00baebca 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,40 @@ 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 *GetPalBufferPtr(u32 taskId) +{ + u32 palBuffer; + + LoadWordFromTwoHalfwords((u16 *)&gTasks[taskId].tPalBuffer1, &palBuffer); + return (void *) palBuffer; +} + +static void FreeDestroyTask(u32 taskId) +{ + Free(GetPalBufferPtr(taskId)); + DestroyTask(taskId); +} + static void TrySweetScentEncounter(u8 taskId) { if (!gPaletteFade.active) @@ -72,7 +94,7 @@ static void TrySweetScentEncounter(u8 taskId) gTasks[taskId].data[0] = 0; if (SweetScentWildEncounter() == TRUE) { - DestroyTask(taskId); + FreeDestroyTask(taskId); } else { @@ -92,9 +114,12 @@ static void FailSweetScentEncounter(u8 taskId) { if (!gPaletteFade.active) { - CpuFastCopy(gDecompressionBuffer, gPlttBufferUnfaded, PLTT_SIZE); + CpuFastCopy(GetPalBufferPtr(taskId), gPlttBufferUnfaded, PLTT_SIZE); SetWeatherPalStateIdle(); ScriptContext_SetupScript(EventScript_FailSweetScent); - DestroyTask(taskId); + FreeDestroyTask(taskId); } } + +#undef tPalBuffer1 +#undef tPalBuffer2 diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c index 1c3b00f2ef1..1a8906d975f 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/item_menu_icons.c b/src/item_menu_icons.c index 4e6339ba309..29cdb224bbe 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/link.c b/src/link.c index 501aacad2ca..fe633c58d7c 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/main_menu.c b/src/main_menu.c index bae80e543a0..c8132c6df87 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 d9b331a8b2f..a6d6a389264 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/mystery_event_menu.c b/src/mystery_event_menu.c index 67ec7855ade..82a9cf18314 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 62ab85b43df..3663df43d5e 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/palette.c b/src/palette.c index 2526479ca8d..f9a074d41e6 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) diff --git a/src/pokemon_sprite_visualizer.c b/src/pokemon_sprite_visualizer.c index 4323e833a0c..5c29dfd906c 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 4c4777e5d52..d2765b67061 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); + LZDecompressWram(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); + LZDecompressWram(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) diff --git a/src/roulette.c b/src/roulette.c index f4e6012a8dc..c72b1b78766 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/save.c b/src/save.c index 7d7d1e42926..65e496b0d0d 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; } diff --git a/src/save_failed_screen.c b/src/save_failed_screen.c index 9bd981facc3..08cc1aaeb9f 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(); diff --git a/src/scrcmd.c b/src/scrcmd.c index b2bb99cf996..c8e817718a9 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; } diff --git a/src/sprite.c b/src/sprite.c index 2e021f5cbff..eb458cb6169 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -1567,9 +1567,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; @@ -1601,9 +1601,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; @@ -1615,7 +1615,7 @@ u8 AllocSpritePalette(u16 tag) } } -u8 IndexOfSpritePaletteTag(u16 tag) +u32 IndexOfSpritePaletteTag(u16 tag) { u32 i; for (i = gReservedSpritePaletteCount; i < 16; i++) diff --git a/src/trade.c b/src/trade.c index 04b1977c17b..8ba22eac977 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) diff --git a/src/union_room.c b/src/union_room.c index ac4c61035a2..3337cdec93c 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)