Remove gDecompressionBuffer (#6029)

This commit is contained in:
DizzyEggg 2025-01-23 09:47:14 +01:00 committed by GitHub
parent a1c47a931f
commit 4e0eab9e27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 452 additions and 391 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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
{

View File

@ -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)
{

View File

@ -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 =
&REG_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;

View File

@ -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];

View File

@ -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)

10
src/berry_crush.c Executable file → Normal file
View File

@ -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;
s32 i;
u8 *windowGfx = malloc_and_decompress(gBerryCrush_TextWindows_Tilemap, NULL);
LZ77UnCompWram(gBerryCrush_TextWindows_Tilemap, gDecompressionBuffer);
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)

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);
u32 ret = LoadSpriteSheetByTemplate(&myTemplate, 0, offset);
Free(buffer);
return ret;
}
void LoadCompressedSpriteSheetOverrideBuffer(const struct CompressedSpriteSheet *src, void *buffer)
u32 LoadCompressedSpritePalette(const struct CompressedSpritePalette *src)
{
struct SpriteSheet dest;
return LoadCompressedSpritePaletteWithTag(src->data, src->tag);
}
u32 LoadCompressedSpritePaletteWithTag(const u32 *pal, u16 tag)
{
u32 index;
struct SpritePalette dest;
void *buffer = malloc_and_decompress(pal, NULL);
LZ77UnCompWram(src->data, buffer);
dest.data = buffer;
dest.size = src->size;
dest.tag = src->tag;
LoadSpriteSheet(&dest);
}
void LoadCompressedSpritePalette(const struct CompressedSpritePalette *src)
{
struct SpritePalette dest;
LZ77UnCompWram(src->data, gDecompressionBuffer);
dest.data = (void *) gDecompressionBuffer;
dest.tag = src->tag;
LoadSpritePalette(&dest);
}
void LoadCompressedSpritePaletteWithTag(const u32 *pal, u16 tag)
{
struct SpritePalette dest;
LZ77UnCompWram(pal, gDecompressionBuffer);
dest.data = (void *) gDecompressionBuffer;
dest.tag = tag;
LoadSpritePalette(&dest);
index = LoadSpritePalette(&dest);
Free(buffer);
return index;
}
void LoadCompressedSpritePaletteOverrideBuffer(const struct CompressedSpritePalette *src, void *buffer)

View File

@ -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;

View File

@ -2056,15 +2056,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

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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
{
ALIGNED(4) u8 gfx[BERRY_SPRITE_SIZE];
struct SpriteFrameImage images[1];
};
static struct BerryDynamicGfx *LoadBerryGfx(u8 berryId)
{
struct CompressedSpritePalette pal;
if (berryId == ITEM_TO_BERRY(ITEM_ENIGMA_BERRY_E_READER) - 1 && IsEnigmaBerryValid())
{
// unknown empty if statement
}
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);

View File

@ -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++)
{

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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++)

View File

@ -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)

View File

@ -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)