mirror of
https://github.com/SAT-R/sa2.git
synced 2026-10-28 09:43:38 +00:00
Implement some additional (still very WIP) OpenGL 1.1 rendering (#232)
* Render sprites with OpenGL directly (but graphics still get generated on-the-fly) * Some Modelview mtx tests * Some data documentation * Very WIP changes * Some more prep for tilemap rendering * Draw back chunks * Apply X/Y flips where needed * Render 2nd chunk layer * Document palette IDs in all uses of gObjPalette * Some VRAM Heap documentation * Use MetatileIndexType in Background::metatileMap * Stretch Sonic Team logo on entire screen. Keep gBgScrollRegs in mind for positioning BGs * Formatter. Fix realloc in win32. Fix crash in Zone 4 * Render 8BPP tilemaps * Some crash fixes * Minor priority documentation * Address explicit gVramHeapState size in initialization * Streamline most uses of gObjPalette * Streamline most uses of gBgPalette
This commit is contained in:
1 parent
91288fb33e
commit
2d42c0efae
40 files changed
+806
-300
No files matched your search
+10
-3
@@ -251,7 +251,7 @@ extern u8 gIwramHeap[TASK_HEAP_SIZE];
|
||||
|
||||
extern void *gVramHeapStartAddr;
|
||||
extern u16 gVramHeapMaxTileSlots;
|
||||
extern u16 gVramHeapState[256];
|
||||
extern u16 gVramHeapState[OBJ_VRAM_TOTAL_SIZE / VRAM_HEAP_SEGMENT_SIZE];
|
||||
|
||||
extern bool8 gExecSoundMain;
|
||||
|
||||
@@ -264,11 +264,18 @@ extern u16 gDispCnt;
|
||||
#define WINREG_WININ 4
|
||||
#define WINREG_WINOUT 5
|
||||
|
||||
#define PALETTE_LEN_4BPP 16u
|
||||
#define GET_PALETTE_COLOR_OBJ(_paletteId, _colorId) gObjPalette[(_paletteId)*PALETTE_LEN_4BPP + (_colorId)]
|
||||
#define GET_PALETTE_COLOR_BG(_paletteId, _colorId) gBgPalette[(_paletteId)*PALETTE_LEN_4BPP + (_colorId)]
|
||||
#define SET_PALETTE_COLOR_OBJ(_paletteId, _colorId, _color) GET_PALETTE_COLOR_OBJ(_paletteId, _colorId) = (_color);
|
||||
#define SET_PALETTE_COLOR_BG(_paletteId, _colorId, _color) GET_PALETTE_COLOR_BG(_paletteId, _colorId) = (_color);
|
||||
|
||||
extern winreg_t gWinRegs[6];
|
||||
extern struct BlendRegs gBldRegs;
|
||||
extern BgAffineReg gBgAffineRegs[NUM_AFFINE_BACKGROUNDS];
|
||||
extern u16 gObjPalette[OBJ_PLTT_SIZE / sizeof(u16)];
|
||||
extern u16 gBgPalette[BG_PLTT_SIZE / sizeof(u16)];
|
||||
extern u16 gObjPalette[16 * PALETTE_LEN_4BPP];
|
||||
extern u16 gBgPalette[16 * PALETTE_LEN_4BPP];
|
||||
|
||||
extern u16 gBgCntRegs[4];
|
||||
|
||||
// TODO: Turn this into a struct-array?
|
||||
|
||||
@@ -82,6 +82,7 @@ extern uint8_t OAM[OAM_SIZE];
|
||||
#define OBJ_VRAM0 &VRAM[0x10000]
|
||||
#define OBJ_VRAM1 &VRAM[0x14000]
|
||||
|
||||
#define OBJ_VRAM_TOTAL_SIZE (VRAM_SIZE - BG_VRAM_SIZE)
|
||||
#else
|
||||
#define DISPLAY_WIDTH 240
|
||||
#define DISPLAY_HEIGHT 160
|
||||
@@ -118,8 +119,10 @@ extern uint8_t OAM[OAM_SIZE];
|
||||
#define OAM 0x7000000
|
||||
#define OAM_SIZE (OAM_ENTRY_COUNT*sizeof(OamData))
|
||||
|
||||
#define OBJ_VRAM_TOTAL_SIZE (VRAM_SIZE - BG_VRAM_SIZE)
|
||||
#endif
|
||||
|
||||
|
||||
#if WIDESCREEN_HACK
|
||||
#define WIN_REG_SIZE 4
|
||||
#define WIN_RANGE(a, b) (((a) << 16) | (b))
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
#if !PLATFORM_GBA
|
||||
#ifdef _WIN32
|
||||
void *Platform_malloc(size_t numBytes);
|
||||
void *Platform_realloc(void *ptr, size_t numBytes);
|
||||
void Platform_free(void *ptr);
|
||||
#define malloc(numBytes) Platform_malloc(numBytes)
|
||||
#define calloc(count, size) Platform_malloc(count *size)
|
||||
#define realloc(ptr, size) Platform_realloc(ptr, size)
|
||||
#define free(numBytes) Platform_free(numBytes)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#define VRAM_HEAP_SEGMENT_SIZE 0x80
|
||||
#define VRAM_TILE_SLOTS_PER_SEGMENT (VRAM_HEAP_SEGMENT_SIZE / TILE_SIZE_4BPP)
|
||||
#define VRAM_HEAP_TILE_SIZE TILE_SIZE_4BPP
|
||||
#define VRAM_HEAP_SEGMENT_SIZE (4 * VRAM_HEAP_TILE_SIZE)
|
||||
#define VRAM_TILE_SLOTS_PER_SEGMENT (VRAM_HEAP_SEGMENT_SIZE / VRAM_HEAP_TILE_SIZE)
|
||||
|
||||
// TODO: Find out where these numbers come from
|
||||
#if (ENGINE == ENGINE_1)
|
||||
|
||||
@@ -22,5 +22,8 @@ extern void Platform_LZDecompressUnsafe(unsigned char *src, unsigned char *dest)
|
||||
extern void Platform_RLDecompressUnsafe(unsigned char *src, unsigned char *dest);
|
||||
|
||||
extern void Platform_QueueAudio(const void *data, u32 numBytes);
|
||||
extern void Platform_ProcessBackgroundsCopyQueue(void);
|
||||
// TODO: Re-enable once #include-ing global.h/core.h/sprite.h does not result in compilation errors.
|
||||
// void Platform_TransformSprite(Sprite *s, SpriteTransform *transform);
|
||||
|
||||
#endif // GUARD_SA2_PLATFORM_H
|
||||
@@ -4,7 +4,9 @@
|
||||
#include "sprite.h" // for Sprite
|
||||
|
||||
void OpenGL_OnInit();
|
||||
void OpenGL_ProcessBackgroundsCopyQueue();
|
||||
void OpenGL_DisplaySprite(Sprite *sprite, u8 oamPaletteNum);
|
||||
void OpenGL_TransformSprite(Sprite *sprite, SpriteTransform *transform);
|
||||
void OpenGL_Render(void *tempBufferPixels, int windowWidth, int windowHeight);
|
||||
|
||||
#endif // GUARD_PLATFORM_SHARED_OPENGL_H
|
||||
+1
-1
@@ -118,7 +118,7 @@ typedef struct {
|
||||
/* 0x36 */ u16 prevScrollY;
|
||||
|
||||
/* Only used by stage maps (they are encoded as Tilemaps) */
|
||||
/* 0x38 */ const u16 *metatileMap;
|
||||
/* 0x38 */ const MetatileIndexType *metatileMap;
|
||||
/* 0x3C */ u16 mapWidth;
|
||||
/* 0x3E */ u16 mapHeight;
|
||||
} Background; /* size = 0x40 */
|
||||
|
||||
+10
-2
@@ -4,6 +4,7 @@
|
||||
#include "sprite.h"
|
||||
#include "trig.h"
|
||||
#include "lib/m4a/m4a.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "animation_commands.h"
|
||||
|
||||
@@ -54,7 +55,7 @@ void DrawBackground(Background *background)
|
||||
background->paletteOffset = mapHeader->tileset.palOffset;
|
||||
|
||||
if (!(background->flags & BACKGROUND_DISABLE_PALETTE_UPDATE)) {
|
||||
DmaCopy16(3, pal, gBgPalette + background->paletteOffset, palSize * sizeof(*pal));
|
||||
DmaCopy16(3, pal, &GET_PALETTE_COLOR_BG(0, background->paletteOffset), palSize * sizeof(*pal));
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
background->flags ^= BACKGROUND_DISABLE_PALETTE_UPDATE;
|
||||
}
|
||||
@@ -72,6 +73,7 @@ void DrawBackground(Background *background)
|
||||
|
||||
// (85.37%) https://decomp.me/scratch/617Jb
|
||||
// (87.46%) https://decomp.me/scratch/1CFim
|
||||
// TODO: ProcessBackgroundsCopyQueue might be a good name for this function?
|
||||
NONMATCH("asm/non_matching/engine/sub_8002B20.inc", bool32 sub_8002B20(void))
|
||||
{
|
||||
u16 sp00;
|
||||
@@ -90,6 +92,7 @@ NONMATCH("asm/non_matching/engine/sub_8002B20.inc", bool32 sub_8002B20(void))
|
||||
|
||||
#if (RENDERER == RENDERER_OPENGL)
|
||||
// TEMP
|
||||
Platform_ProcessBackgroundsCopyQueue();
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
@@ -1289,7 +1292,12 @@ static AnimCmdResult animCmd_GetPalette_BG(void *cursor, Sprite *s)
|
||||
if (!(s->frameFlags & SPRITE_FLAG_MASK_18)) {
|
||||
s32 paletteIndex = cmd->palId;
|
||||
|
||||
DmaCopy32(3, &gRefSpriteTables->palettes[paletteIndex * 16], &gBgPalette[s->palId * 16 + cmd->insertOffset], cmd->numColors * 2);
|
||||
// NOTE:
|
||||
// For some reason, this only matches with a size of:
|
||||
// (cmd->numColors * 2), not (cmd->numColors * sizeof(u16))
|
||||
// Same goes for sprite.c version called animCmd_GetPalette()...
|
||||
DmaCopy32(3, &gRefSpriteTables->palettes[paletteIndex * 16], &GET_PALETTE_COLOR_BG(s->palId, cmd->insertOffset),
|
||||
cmd->numColors * 2);
|
||||
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
}
|
||||
|
||||
+4
-4
@@ -622,12 +622,12 @@ void UpdateScreenDma(void)
|
||||
DmaCopy32(3, gBgCntRegs, (void *)REG_ADDR_BG0CNT, sizeof(gBgCntRegs));
|
||||
|
||||
if (gFlags & FLAGS_UPDATE_BACKGROUND_PALETTES) {
|
||||
DmaCopy32(3, gBgPalette, (void *)BG_PLTT, BG_PLTT_SIZE);
|
||||
DmaCopy32(3, gBgPalette, (void *)BG_PLTT, sizeof(gBgPalette));
|
||||
gFlags ^= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
}
|
||||
|
||||
if (gFlags & FLAGS_UPDATE_SPRITE_PALETTES) {
|
||||
DmaCopy32(3, gObjPalette, (void *)OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
DmaCopy32(3, gObjPalette, (void *)OBJ_PLTT, sizeof(gObjPalette));
|
||||
gFlags ^= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
|
||||
@@ -761,12 +761,12 @@ void UpdateScreenCpuSet(void)
|
||||
CpuCopy32(gBgCntRegs, (void *)REG_ADDR_BG0CNT, sizeof(gBgCntRegs));
|
||||
|
||||
if (gFlags & FLAGS_UPDATE_BACKGROUND_PALETTES) {
|
||||
CpuFastCopy(gBgPalette, (void *)BG_PLTT, BG_PLTT_SIZE);
|
||||
CpuFastCopy(gBgPalette, (void *)BG_PLTT, sizeof(gBgPalette));
|
||||
gFlags ^= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
}
|
||||
|
||||
if (gFlags & FLAGS_UPDATE_SPRITE_PALETTES) {
|
||||
CpuFastCopy(gObjPalette, (void *)OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
CpuFastCopy(gObjPalette, (void *)OBJ_PLTT, sizeof(gObjPalette));
|
||||
gFlags ^= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ static inline void sub_8015B64_inline(AnimId anim, u16 palId)
|
||||
#endif
|
||||
numColors = *pAnim % 256u;
|
||||
|
||||
DmaCopy32(3, &gRefSpriteTables->palettes[animPalId * 16], &gObjPalette[insertOffset], numColors * sizeof(u16));
|
||||
DmaCopy32(3, &gRefSpriteTables->palettes[animPalId * 16], &GET_PALETTE_COLOR_OBJ(0, insertOffset), numColors * sizeof(u16));
|
||||
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ static const HammertankFunc sBossStateHandlers[] = {
|
||||
[EGG_HAMMER_TANK_II_STATE_DRAG] = StateHandler_HammerDrag, [EGG_HAMMER_TANK_II_STATE_RETRACT] = StateHandler_HammerRetract,
|
||||
};
|
||||
|
||||
static const u16 gUnknown_080D7AD0[][16] = {
|
||||
static const u16 gUnknown_080D7AD0[][PALETTE_LEN_4BPP] = {
|
||||
INCBIN_U16("graphics/80D7AD0.gbapal"),
|
||||
INCBIN_U16("graphics/80D7AF0.gbapal"),
|
||||
};
|
||||
@@ -1613,8 +1613,8 @@ static void HandleBossHitPalette(EggHammerTankII *boss)
|
||||
if (boss->timerInvulnerability > 0) {
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[8 * 16 + i] = gUnknown_080D7AD0[(boss->timerInvulnerability & 4) >> 2][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D7AD0[(boss->timerInvulnerability & 4) >> 2][i]);
|
||||
}
|
||||
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
|
||||
@@ -152,7 +152,7 @@ static const u16 gUnknown_080D7B4E[][2] = {
|
||||
|
||||
static const BossFunction sBossModeTasks[] = { HandleCannonBombTrigger, HandleCannonlessBombTrigger };
|
||||
|
||||
static const u16 gUnknown_080D7B70[][16] = {
|
||||
static const u16 gUnknown_080D7B70[][PALETTE_LEN_4BPP] = {
|
||||
INCBIN_U16("graphics/80D7B70.gbapal"),
|
||||
INCBIN_U16("graphics/80D7B90.gbapal"),
|
||||
};
|
||||
@@ -575,23 +575,23 @@ static void UpdateBomberTankPalette(EggBomberTank *boss)
|
||||
{
|
||||
u8 i;
|
||||
if (boss->bossHitTimer != 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[i + 0x80] = gUnknown_080D7B70[(gStageTime & 2) >> 1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D7B70[(gStageTime & 2) >> 1][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[i + 0x80] = gUnknown_080D7B70[1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D7B70[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (boss->cannonHitTimer != 0) {
|
||||
boss->cannonHitTimer--;
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[i + 0xD0] = gUnknown_080D7B70[(gStageTime & 2) >> 1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(13, i, gUnknown_080D7B70[(gStageTime & 2) >> 1][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[i + 0xD0] = gUnknown_080D7B70[1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(13, i, gUnknown_080D7B70[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ const u8 *const gUnknown_080D7ED4[] = {
|
||||
|
||||
const s8 gUnknown_080D7F10[EGGTOTEM_NUM_PLATFORMS] = { 14, 14, 8 };
|
||||
|
||||
const s16 gUnknown_080D7F14[2][16] = {
|
||||
const s16 gUnknown_080D7F14[2][PALETTE_LEN_4BPP] = {
|
||||
INCBIN_U16("graphics/boss_3_a.gbapal"),
|
||||
INCBIN_U16("graphics/boss_3_b.gbapal"),
|
||||
};
|
||||
@@ -1504,24 +1504,24 @@ void sub_8040F14(EggTotem *totem)
|
||||
u8 i;
|
||||
|
||||
if (totem->unk35 != 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[128 + i] = gUnknown_080D7F14[((gStageTime & 0x2) / 2u)][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D7F14[((gStageTime & 0x2) / 2u)][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[128 + i] = gUnknown_080D7F14[1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D7F14[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (totem->unk36 > 0) {
|
||||
totem->unk36--;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[176 + i] = gUnknown_080D7F14[((gStageTime & 0x2) / 2u)][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(11, i, gUnknown_080D7F14[((gStageTime & 0x2) / 2u)][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[176 + i] = gUnknown_080D7F14[1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(11, i, gUnknown_080D7F14[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#define RESERVED_EXPLOSION_TILES_VRAM (void *)(OBJ_VRAM0 + 0x2980)
|
||||
|
||||
static const u16 sPalAeroEggHit[2][16] = {
|
||||
static const u16 sPalAeroEggHit[2][PALETTE_LEN_4BPP] = {
|
||||
[PAL_BOSS_4_DEFAULT] = INCBIN_U16("graphics/boss_4_a.gbapal"),
|
||||
[PAL_BOSS_4_HIT] = INCBIN_U16("graphics/boss_4_b.gbapal"),
|
||||
};
|
||||
@@ -761,12 +761,12 @@ static void sub_8042560(AeroEgg *boss)
|
||||
u8 i;
|
||||
|
||||
if (boss->main.unk16 != 0) {
|
||||
for (i = 0; i < ARRAY_COUNT(sPalAeroEggHit[PAL_BOSS_4_DEFAULT]); i++) {
|
||||
gObjPalette[128 + i] = sPalAeroEggHit[((gStageTime & 0x2) >> 1)][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, sPalAeroEggHit[((gStageTime & 0x2) >> 1)][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_COUNT(sPalAeroEggHit[PAL_BOSS_4_HIT]); i++) {
|
||||
gObjPalette[128 + i] = sPalAeroEggHit[PAL_BOSS_4_HIT][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, sPalAeroEggHit[PAL_BOSS_4_HIT][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-10
@@ -149,7 +149,7 @@ static const TileInfo gUnknown_080D7FB0[] = {
|
||||
{ 2, SA2_ANIM_EGG_SAUCER_SMACK_PARTICLE_UP, 0 }, { 4, SA2_ANIM_EGG_SAUCER_SMACK_PARTICLE_UP_RIGHT, 0 },
|
||||
};
|
||||
|
||||
static const u16 gUnknown_080D7FF0[][16] = {
|
||||
static const u16 gUnknown_080D7FF0[][PALETTE_LEN_4BPP] = {
|
||||
INCBIN_U16("graphics/80D7FF0.gbapal"),
|
||||
INCBIN_U16("graphics/80D8010.gbapal"),
|
||||
};
|
||||
@@ -1293,6 +1293,7 @@ static void sub_8044CBC(EggSaucer *boss)
|
||||
s->prevVariant = -1;
|
||||
}
|
||||
}
|
||||
|
||||
boss->unk36[0][boss->unkB6] = boss->unkB8;
|
||||
boss->unk36[1][boss->unkB6] = boss->unkBA;
|
||||
|
||||
@@ -1756,27 +1757,27 @@ void sub_8045898(EggSaucer *boss)
|
||||
if (boss->unk15 == 0) {
|
||||
val = (gStageTime & 2) >> 1;
|
||||
if (boss->unk13 != 0) {
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
gObjPalette[i + 0x80] = gUnknown_080D7FF0[val][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D7FF0[val][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
gObjPalette[i + 0x80] = gUnknown_080D7FF0[1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D7FF0[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (boss->unk1F != 0) {
|
||||
boss->unk1F--;
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
gObjPalette[i + 0x90] = gUnknown_080D7FF0[val][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(9, i, gUnknown_080D7FF0[val][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
gObjPalette[i + 0x90] = gUnknown_080D7FF0[1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(9, i, gUnknown_080D7FF0[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
gFlags |= 2;
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ static const u16 gUnknown_080D809E[][10] = {
|
||||
{ 257, 257, 257, 257, 257, 256, 256, 256, 222, 222 },
|
||||
};
|
||||
|
||||
static const u16 sPalettes[][16] = {
|
||||
static const u16 sPalettes[][PALETTE_LEN_4BPP] = {
|
||||
INCBIN_U16("graphics/80D80C6.gbapal"), // hit palette
|
||||
INCBIN_U16("graphics/80D80E6.gbapal"), // normal palette
|
||||
};
|
||||
@@ -1164,16 +1164,16 @@ static void SetPalette(EggGoRound *boss)
|
||||
{
|
||||
u8 i;
|
||||
if (boss->invincibilityTimer > 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[128 + i] = sPalettes[(gStageTime & 2) / 2][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, sPalettes[(gStageTime & 2) / 2][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[128 + i] = sPalettes[1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, i, sPalettes[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
gFlags |= 2;
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
|
||||
static void HandleCollisions(EggGoRound *boss)
|
||||
|
||||
@@ -1160,8 +1160,8 @@ static void sub_804931C(EggFrog *boss)
|
||||
if (boss->unk16 != 0) {
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
gBgPalette[i + 0xB0] = gUnknown_080D8796[(boss->unk16 & 2) >> 1][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_BG(11, i, gUnknown_080D8796[(boss->unk16 & 2) >> 1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ const u16 gUnknown_080D8888[2][2] = { { Q(188), Q(110) }, { Q(162), Q(110) } };
|
||||
static const EggRoboFn sArmFuncs[8]
|
||||
= { sub_804B43C, sub_804B594, sub_804B734, sub_804B984, sub_804BC44, sub_804BE6C, sub_804BAC0, sub_804C240 };
|
||||
|
||||
const u16 sArmPalettes[2][16] = {
|
||||
const u16 sArmPalettes[2][PALETTE_LEN_4BPP] = {
|
||||
INCBIN_U16("graphics/boss_8_a.gbapal"),
|
||||
INCBIN_U16("graphics/boss_8_b.gbapal"),
|
||||
};
|
||||
@@ -2009,31 +2009,31 @@ static void sub_804CA70(SuperEggRoboZ *boss)
|
||||
|
||||
if (boss->unkB != 0) {
|
||||
for (i = 0; i < ARRAY_COUNT(sArmPalettes[0]); i++) {
|
||||
gObjPalette[8 * 16 + i] = sArmPalettes[pal][i];
|
||||
SET_PALETTE_COLOR_OBJ(8, i, sArmPalettes[pal][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_COUNT(sArmPalettes[0]); i++) {
|
||||
gObjPalette[8 * 16 + i] = sArmPalettes[0][i];
|
||||
SET_PALETTE_COLOR_OBJ(8, i, sArmPalettes[0][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (boss->unk3E[0] > 0) {
|
||||
for (i = 0; i < ARRAY_COUNT(sArmPalettes[0]); i++) {
|
||||
gObjPalette[9 * 16 + i] = sArmPalettes[pal][i];
|
||||
SET_PALETTE_COLOR_OBJ(9, i, sArmPalettes[pal][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_COUNT(sArmPalettes[0]); i++) {
|
||||
gObjPalette[9 * 16 + i] = sArmPalettes[0][i];
|
||||
SET_PALETTE_COLOR_OBJ(9, i, sArmPalettes[0][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (boss->unk3E[1] > 0) {
|
||||
for (i = 0; i < ARRAY_COUNT(sArmPalettes[0]); i++) {
|
||||
gObjPalette[12 * 16 + i] = sArmPalettes[pal][i];
|
||||
SET_PALETTE_COLOR_OBJ(12, i, sArmPalettes[pal][i]);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_COUNT(sArmPalettes[0]); i++) {
|
||||
gObjPalette[12 * 16 + i] = sArmPalettes[0][i];
|
||||
SET_PALETTE_COLOR_OBJ(12, i, sArmPalettes[0][i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-22
@@ -321,7 +321,7 @@ const TA53_Data1 gUnknown_080D8DCC[6] = {
|
||||
};
|
||||
|
||||
const TA53_Rocket_Callback gUnknown_080D8E14[3] = { sub_804E974, sub_804EB6C, sub_804EC6C };
|
||||
const u8 sRGB_080D8E20[4][16][3] = {
|
||||
const u8 sRGB_080D8E20[4][PALETTE_LEN_4BPP][3] = {
|
||||
{
|
||||
{ 0, 0, 0 },
|
||||
{ 2, 2, 28 },
|
||||
@@ -1385,8 +1385,8 @@ void sub_804E4CC(struct TA53_unk48 *unk48)
|
||||
b = sRGB_080D8E20[3][c][2];
|
||||
b = ((b * r6) >> 12) & 0x1F;
|
||||
|
||||
gObjPalette[c + 8 * 16] = RGB16_REV(r, g, b);
|
||||
gBgPalette[c] = RGB16_REV(r, g, b);
|
||||
SET_PALETTE_COLOR_OBJ(8, c, RGB16_REV(r, g, b));
|
||||
SET_PALETTE_COLOR_BG(0, c, RGB16_REV(r, g, b));
|
||||
}
|
||||
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
@@ -1407,7 +1407,12 @@ void sub_804E4CC(struct TA53_unk48 *unk48)
|
||||
g = ((g * r6) >> 9) & 0x1F;
|
||||
b = sRGB_080D8E20[i][c][2];
|
||||
b = ((b * r6) >> 9) & 0x1F;
|
||||
gBgPalette[0x70 + c + (i * 16)] = RGB16_REV(r, g, b);
|
||||
#ifndef NON_MATCHING
|
||||
// TODO: This should work...
|
||||
gBgPalette[7 * PALETTE_LEN_4BPP + c + (i * PALETTE_LEN_4BPP)] = RGB16_REV(r, g, b);
|
||||
#else
|
||||
SET_PALETTE_COLOR_BG(7, c + (i * PALETTE_LEN_4BPP), RGB16_REV(r, g, b));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2870,31 +2875,24 @@ void sub_8050958(TA53Boss *boss)
|
||||
if (boss->unkD > 0) {
|
||||
if (--boss->unkD == 0) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[i + 8 * 16] = gUnknown_080D8EF0[1][i];
|
||||
gBgPalette[i + 0 * 16] = gObjPalette[i + 8 * 16];
|
||||
SET_PALETTE_COLOR_OBJ(8, i, gUnknown_080D8EF0[1][i]);
|
||||
SET_PALETTE_COLOR_BG(0, i, gUnknown_080D8EF0[1][i]);
|
||||
}
|
||||
} else {
|
||||
// _080509B0
|
||||
u16 r6 = (gStageTime >> 1) % 16u;
|
||||
u16 r6 = (gStageTime >> 1) % PALETTE_LEN_4BPP;
|
||||
|
||||
if (boss->lives < 4) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[8 * 16 + ((i + r6) % 16u)] = gUnknown_080D8EF0[0][i] >> 5;
|
||||
gBgPalette[0 * 16 + ((i + r6) % 16u)] = gObjPalette[8 * 16 + ((i + r6) % 16u)];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, ((i + r6) % PALETTE_LEN_4BPP), gUnknown_080D8EF0[0][i] >> 5);
|
||||
SET_PALETTE_COLOR_BG(0, ((i + r6) % PALETTE_LEN_4BPP), gUnknown_080D8EF0[0][i] >> 5);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
u32 r0;
|
||||
u32 r2;
|
||||
u32 colId;
|
||||
u16 *objPalTgt = &gObjPalette[0];
|
||||
u32 objPalId;
|
||||
|
||||
colId = ((i + r6) % 16u);
|
||||
objPalId = 8 * 16 + colId;
|
||||
objPalTgt[objPalId] = ((gUnknown_080D8EF0[0][i] << 5) | (gUnknown_080D8EF0[0][i] >> 5)) | gUnknown_080D8EF0[0][i];
|
||||
gBgPalette[0 * 16 + colId]
|
||||
= ((gUnknown_080D8EF0[0][i] << 5) | (gUnknown_080D8EF0[0][i] >> 5)) | gUnknown_080D8EF0[0][i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(8, ((i + r6) % PALETTE_LEN_4BPP),
|
||||
((gUnknown_080D8EF0[0][i] << 5) | (gUnknown_080D8EF0[0][i] >> 5)) | gUnknown_080D8EF0[0][i]);
|
||||
SET_PALETTE_COLOR_BG(0, ((i + r6) % PALETTE_LEN_4BPP),
|
||||
((gUnknown_080D8EF0[0][i] << 5) | (gUnknown_080D8EF0[0][i] >> 5)) | gUnknown_080D8EF0[0][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,11 +515,11 @@ void CreateCharacterSelectionScreen(u8 initialSelection, bool8 allUnlocked)
|
||||
s->frameFlags = 0;
|
||||
UpdateSpriteAnimation(s);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[i + 240] = 0;
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(15, i, 0);
|
||||
}
|
||||
|
||||
gFlags |= 0x2;
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
|
||||
static void Task_FadeInAndStartRollInAnim(void)
|
||||
|
||||
@@ -834,9 +834,9 @@ void sub_8090F6C(struct ExtraEndingCutScene *scene)
|
||||
if (scene->unk37F != 0) {
|
||||
scene->unk37F--;
|
||||
if (scene->unk37E <= 3) {
|
||||
DmaCopy32(3, gUnknown_080E15C8[scene->unk37E], &gObjPalette[0x30], sizeof(gUnknown_080E15C8[0]));
|
||||
DmaCopy32(3, gUnknown_080E15C8[scene->unk37E], &GET_PALETTE_COLOR_OBJ(3, 0), sizeof(gUnknown_080E15C8[0]));
|
||||
} else {
|
||||
DmaCopy32(3, gUnknown_080E15C8[6 - scene->unk37E], &gObjPalette[0x30], sizeof(gUnknown_080E15C8[0]));
|
||||
DmaCopy32(3, gUnknown_080E15C8[6 - scene->unk37E], &GET_PALETTE_COLOR_OBJ(3, 0), sizeof(gUnknown_080E15C8[0]));
|
||||
}
|
||||
} else {
|
||||
scene->unk37E++;
|
||||
|
||||
@@ -504,7 +504,7 @@ void CreateFinalEndingLandingCutScene(void)
|
||||
|
||||
if (!(gLoadedSaveGame->chaosEmeralds[gSelectedCharacter] & CHAOS_EMERALDS_COMPLETED)) {
|
||||
memcpy(unk1AF4, gUnknown_080E1AF4, sizeof(unk1AF4));
|
||||
DmaCopy32(3, unk1AF4, &gBgPalette[32], sizeof(unk1AF4));
|
||||
DmaCopy32(3, unk1AF4, &GET_PALETTE_COLOR_BG(2, 0), sizeof(unk1AF4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const u8 gUnknown_080E0234[] = {
|
||||
103, 104, 112, 114, 115, 117, 119, 120, 128, 130, 131, 133, 135, 136, 144, 146, 147, 149, 151, 152,
|
||||
};
|
||||
|
||||
const u16 gUnknown_080E0270[] = INCBIN_U16("graphics/80E0270.gbapal");
|
||||
const u16 gUnknown_080E0270[PALETTE_LEN_4BPP] = INCBIN_U16("graphics/80E0270.gbapal");
|
||||
|
||||
#ifndef COLLECT_RINGS_ROM
|
||||
#define NUM_TILES 9
|
||||
@@ -85,8 +85,8 @@ void CreateCollectRingsTimeDisplay(void)
|
||||
UpdateSpriteAnimation(s);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[i + 0x70] = gUnknown_080E0270[i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(7, i, gUnknown_080E0270[i]);
|
||||
}
|
||||
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
|
||||
@@ -602,22 +602,22 @@ void sub_8081AD4(struct SinglePakConnectScreen *connectScreen)
|
||||
background->flags = BACKGROUND_FLAGS_BG_ID(0);
|
||||
DrawBackground(background);
|
||||
|
||||
CpuFill16(0, &gBgPalette[17], 30);
|
||||
CpuFill16(0, &GET_PALETTE_COLOR_BG(1, 1), RGB16_REV(30, 0, 0));
|
||||
|
||||
gDispCnt |= 0x2200;
|
||||
temp = 0x1f01;
|
||||
gDispCnt |= (DISPCNT_BG1_ON | DISPCNT_WIN0_ON);
|
||||
temp = BGCNT_SCREENBASE(31) | BGCNT_PRIORITY(1);
|
||||
gBgScrollRegs[1][0] = 0;
|
||||
gBgScrollRegs[1][1] = 0;
|
||||
gWinRegs[0] = 0x2828;
|
||||
gWinRegs[2] = 0x8890;
|
||||
gWinRegs[4] = 2;
|
||||
gWinRegs[5] = 1;
|
||||
gWinRegs[WINREG_WIN0H] = WIN_RANGE(40, 40);
|
||||
gWinRegs[WINREG_WIN0V] = WIN_RANGE(136, 144);
|
||||
gWinRegs[WINREG_WININ] = 2;
|
||||
gWinRegs[WINREG_WINOUT] = 1;
|
||||
gBgCntRegs[1] = temp;
|
||||
|
||||
CpuFill16(0xF3FF, (void *)BG_SCREEN_ADDR(31), 2049);
|
||||
CpuFill16(0xFFFF, (void *)VRAM + 1023 * TILE_SIZE_4BPP, TILE_SIZE_4BPP);
|
||||
|
||||
gBgPalette[255] = RGB_RED;
|
||||
SET_PALETTE_COLOR_BG(15, 15, RGB_RED);
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,8 +182,8 @@ void Task_PauseMenuInit(void)
|
||||
m4aSongNumStart(SE_PAUSE_SCREEN);
|
||||
|
||||
gFlags |= FLAGS_PAUSE_GAME;
|
||||
DmaCopy16(3, &gObjPalette[249], pm->pal64, sizeof(pm->pal64));
|
||||
DmaCopy16(3, &gObjPalette[252], pm->pal6A, sizeof(pm->pal6A));
|
||||
DmaCopy16(3, &GET_PALETTE_COLOR_OBJ(15, +9), pm->pal64, sizeof(pm->pal64));
|
||||
DmaCopy16(3, &GET_PALETTE_COLOR_OBJ(15, +12), pm->pal6A, sizeof(pm->pal6A));
|
||||
|
||||
gCurTask->main = Task_PauseMenuUpdate;
|
||||
}
|
||||
@@ -200,7 +200,7 @@ void sub_800AE58(void)
|
||||
{
|
||||
DmaCopy16(3, &Tileset_zone_1_act_1_fg[(4 * 16 * TILE_SIZE_4BPP) / sizeof(u16)], (void *)(OBJ_VRAM1 + 0x3EC0), 0x140);
|
||||
|
||||
gObjPalette[1] = RGB_WHITE;
|
||||
GET_PALETTE_COLOR_OBJ(0, 1) = RGB_WHITE;
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
gFlags &= ~FLAGS_PAUSE_GAME;
|
||||
}
|
||||
@@ -22,7 +22,7 @@ void CreateUnusedFlashTask(void)
|
||||
INIT_BG_SPRITES_LAYER_64(2);
|
||||
|
||||
TaskCreate(Task_UnusedFlashTask, 0, 0x1000, 0, NULL);
|
||||
gBgPalette[1] = RGB_WHITE;
|
||||
SET_PALETTE_COLOR_BG(0, 1, RGB_WHITE);
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,13 @@ static void Task_LoadStage(void);
|
||||
|
||||
void CreateUnusedLevelSelect(void)
|
||||
{
|
||||
#ifdef BUG_FIX
|
||||
// You can come into a situation where a backgorund gets put onto the queue,
|
||||
// but the memory gets free'd.
|
||||
// So we need to make sure the Background Copy Queue is clear.
|
||||
PAUSE_BACKGROUNDS_QUEUE();
|
||||
PAUSE_GRAPHICS_QUEUE();
|
||||
#endif
|
||||
struct Task *t = TaskCreate(Task_UnusedLevelSelectInit, sizeof(LevelSelect), 0x2000, 0, NULL);
|
||||
gMultiplayerMissingHeartbeats[3] = 0;
|
||||
gMultiplayerMissingHeartbeats[2] = 0;
|
||||
@@ -140,7 +147,7 @@ static void Task_Poll(void)
|
||||
static void Task_UnusedLevelSelectInit(void)
|
||||
{
|
||||
LevelSelect *levelSelect = TASK_DATA(gCurTask);
|
||||
gBgPalette[1] = RGB_WHITE;
|
||||
SET_PALETTE_COLOR_BG(0, 1, RGB_WHITE);
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
|
||||
levelSelect->vram += RenderText(levelSelect->vram, Tileset_DebugAscii, 6, 14, 0, "STAGE", 0);
|
||||
|
||||
@@ -335,8 +335,8 @@ static void HandlePaused(struct SpecialStageUI *ui)
|
||||
sub_806CA88(s, 1, pauseMenuVariants[lang][0], pauseMenuVariants[lang][1], 0x1000, (DISPLAY_WIDTH / 2), (DISPLAY_HEIGHT / 2), 0,
|
||||
pauseMenuVariants[lang][2], 0);
|
||||
|
||||
DmaCopy16(3, &gObjPalette[249], ui->pauseMenuPalette1, sizeof(ui->pauseMenuPalette1));
|
||||
DmaCopy16(3, &gObjPalette[252], ui->pauseMenuPalette2, sizeof(ui->pauseMenuPalette2));
|
||||
DmaCopy16(3, &GET_PALETTE_COLOR_OBJ(15, 9), ui->pauseMenuPalette1, sizeof(ui->pauseMenuPalette1));
|
||||
DmaCopy16(3, &GET_PALETTE_COLOR_OBJ(15, 12), ui->pauseMenuPalette2, sizeof(ui->pauseMenuPalette2));
|
||||
ui->wasPaused = TRUE;
|
||||
m4aMPlayAllStop();
|
||||
m4aSongNumStart(SE_PAUSE_SCREEN);
|
||||
|
||||
@@ -201,6 +201,13 @@ void InitSpecialStageScreenVram(void)
|
||||
{
|
||||
gSpecialStageVramPointer = (void *)OBJ_VRAM0;
|
||||
gSpecialStageSubMenuVramPointer = NULL;
|
||||
#ifdef BUG_FIX
|
||||
// You can come into a situation where a backgorund gets put onto the queue,
|
||||
// but the memory gets free'd.
|
||||
// So we need to make sure the Background Copy Queue is clear.
|
||||
PAUSE_BACKGROUNDS_QUEUE();
|
||||
PAUSE_GRAPHICS_QUEUE();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SpecialStageDrawBackground(Background *background, u32 a, u32 b, u8 tilemapId, u16 d, u16 e, u16 palOffset, u8 bg_id, u16 scrollX,
|
||||
|
||||
+37
-38
@@ -783,8 +783,8 @@ void RenderMetatileLayers(s32 x, s32 y)
|
||||
void CreateStageBg_Zone1(void)
|
||||
{
|
||||
Background *background = &gStageBackgroundsRam.unk0;
|
||||
gDispCnt |= 0x100;
|
||||
gBgCntRegs[0] = 0x1B0F;
|
||||
gDispCnt |= DISPCNT_BG0_ON;
|
||||
gBgCntRegs[0] = BGCNT_SCREENBASE(27) | BGCNT_CHARBASE(3) | BGCNT_PRIORITY(3);
|
||||
|
||||
#ifndef COLLECT_RINGS_ROM
|
||||
if (gGameMode != GAME_MODE_MULTI_PLAYER_COLLECT_RINGS) {
|
||||
@@ -795,8 +795,8 @@ void CreateStageBg_Zone1(void)
|
||||
background->graphics.dest = (void *)BG_SCREEN_ADDR(24);
|
||||
background->layoutVram = (void *)BG_SCREEN_ADDR(27);
|
||||
|
||||
background->targetTilesX = 0x20;
|
||||
background->targetTilesY = 0x20;
|
||||
background->targetTilesX = 256 / TILE_WIDTH;
|
||||
background->targetTilesY = 256 / TILE_WIDTH;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@@ -807,8 +807,8 @@ void CreateStageBg_Zone1(void)
|
||||
background->graphics.dest = (void *)BG_SCREEN_ADDR(24);
|
||||
background->layoutVram = (void *)BG_SCREEN_ADDR(27);
|
||||
|
||||
background->targetTilesX = 0x20;
|
||||
background->targetTilesY = 0x1E;
|
||||
background->targetTilesX = 256 / TILE_WIDTH;
|
||||
background->targetTilesY = 240 / TILE_WIDTH;
|
||||
}
|
||||
|
||||
DrawBackground(background);
|
||||
@@ -999,10 +999,8 @@ const u8 gUnknown_080D5B20[16][3] = {
|
||||
{ 255, 5, 6 }, //
|
||||
};
|
||||
|
||||
// TODO: This data is unused in this module
|
||||
// But the place that references this is
|
||||
// further down in code than the .rodata after this.
|
||||
const u8 gUnknown_080D5B50[DISPLAY_HEIGHT] = { // 0-105
|
||||
// NOTE: Only values > 105 appear to be used.
|
||||
const u8 gUnknown_080D5B50[DISPLAY_HEIGHT] = { // 0-94
|
||||
10, 10, 10, //
|
||||
10, 10, 10, //
|
||||
10, 10, 10, //
|
||||
@@ -1034,13 +1032,11 @@ const u8 gUnknown_080D5B50[DISPLAY_HEIGHT] = { // 0-105
|
||||
10, 10, 10, //
|
||||
10, 10, 10, //
|
||||
10, 10, 10, //
|
||||
10, 10, 8, //
|
||||
8, 8, 8, //
|
||||
7, 7, 7, //
|
||||
7, 6, 6, //
|
||||
|
||||
// 106-159 | This data appears to be unused
|
||||
6, 6, 6, //
|
||||
10, 10, 8, 8, 8, 8, // 95-98
|
||||
7, 7, 7, 7, // 99-102
|
||||
6, 6, 6, // 103-104
|
||||
/* 105-159 */
|
||||
6, 6, //
|
||||
6, 6, 6, //
|
||||
5, 5, 5, //
|
||||
5, 5, 5, //
|
||||
@@ -1070,8 +1066,8 @@ static s16 sUnknown_03000408;
|
||||
void CreateStageBg_Zone3(void)
|
||||
{
|
||||
Background *background = &gStageBackgroundsRam.unk0;
|
||||
gDispCnt |= 0x100;
|
||||
gBgCntRegs[0] = 0x1B0F;
|
||||
gDispCnt |= DISPCNT_BG0_ON;
|
||||
gBgCntRegs[0] = BGCNT_SCREENBASE(27) | BGCNT_CHARBASE(3) | BGCNT_PRIORITY(3);
|
||||
|
||||
*background = gStageCameraBgTemplates[3];
|
||||
|
||||
@@ -1189,7 +1185,7 @@ void CreateStageBg_Zone4(void)
|
||||
{
|
||||
Background *background = &gStageBackgroundsRam.unk0;
|
||||
const Background *templates;
|
||||
gBgCntRegs[0] = 0x1B0F;
|
||||
gBgCntRegs[0] = BGCNT_SCREENBASE(27) | BGCNT_CHARBASE(3) | BGCNT_PRIORITY(3);
|
||||
|
||||
*background = gStageCameraBgTemplates[CAMBG_BACK_B_LAYER];
|
||||
|
||||
@@ -1238,8 +1234,13 @@ void StageBgUpdate_Zone4Acts12(s32 cameraX, s32 cameraY)
|
||||
gBldRegs.bldAlpha = 0xc0c;
|
||||
}
|
||||
|
||||
#ifdef BUG_FIX
|
||||
UpdateBgAnimationTiles(&gStageBackgroundsRam.unk0);
|
||||
DrawBackground(&gStageBackgroundsRam.unk0);
|
||||
#else
|
||||
DrawBackground(&gStageBackgroundsRam.unk0);
|
||||
UpdateBgAnimationTiles(&gStageBackgroundsRam.unk0);
|
||||
#endif
|
||||
|
||||
if ((gStageTime % 16u) == 0) {
|
||||
gBgScrollRegs[0][0] = (gBgScrollRegs[0][0] - 1) & 0xff;
|
||||
@@ -1465,7 +1466,7 @@ const u8 gUnknown_080D5C02[2][16][3] = {
|
||||
void CreateStageBg_Zone6_Acts(void)
|
||||
{
|
||||
gDispCnt |= DISPCNT_BG0_ON;
|
||||
gBgCntRegs[0] = 0x1a0f;
|
||||
gBgCntRegs[0] = BGCNT_SCREENBASE(26) | BGCNT_CHARBASE(3) | BGCNT_PRIORITY(3);
|
||||
INIT_BG_SPRITES_LAYER_32(0);
|
||||
DmaFill32(3, 0, BG_SCREEN_ADDR(24), sizeof(Background));
|
||||
gBgScrollRegs[0][0] = 0;
|
||||
@@ -1486,7 +1487,7 @@ void CreateStageBg_Zone6_Boss(void)
|
||||
{
|
||||
Background *background = &gStageBackgroundsRam.unk0;
|
||||
gDispCnt |= DISPCNT_BG0_ON;
|
||||
gBgCntRegs[0] = 0x1a0f;
|
||||
gBgCntRegs[0] = BGCNT_SCREENBASE(26) | BGCNT_CHARBASE(3) | BGCNT_PRIORITY(3);
|
||||
INIT_BG_SPRITES_LAYER_32(0);
|
||||
DmaFill32(3, 0, BG_SCREEN_ADDR(24), sizeof(Background));
|
||||
gBgScrollRegs[0][0] = 0;
|
||||
@@ -1611,7 +1612,7 @@ NONMATCH("asm/non_matching/game/stage/background/sub_801D24C.inc", void sub_801D
|
||||
}
|
||||
// _0801D4A2
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
s32 b, g, r;
|
||||
r = (p0 * gUnknown_080D5C02[1][i][0]) >> 4;
|
||||
r &= 0x1F;
|
||||
@@ -1622,7 +1623,7 @@ NONMATCH("asm/non_matching/game/stage/background/sub_801D24C.inc", void sub_801D
|
||||
b = (p0 * gUnknown_080D5C02[1][i][2]) >> 4;
|
||||
b &= 0x1F;
|
||||
|
||||
gBgPalette[15 * 16 + i] = ((b << 10) + (g << 5) + (r << 0));
|
||||
SET_PALETTE_COLOR_BG(15, i, RGB16_REV(r, g, b));
|
||||
}
|
||||
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
@@ -1663,7 +1664,7 @@ NONMATCH("asm/non_matching/game/stage/background/StageBgUpdate_Zone6Acts12.inc",
|
||||
r5 = 5;
|
||||
}
|
||||
|
||||
gBgPalette[0] = RGB_BLACK;
|
||||
SET_PALETTE_COLOR_BG(0, 0, RGB_BLACK);
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
|
||||
switch (r5) {
|
||||
@@ -1722,7 +1723,7 @@ NONMATCH("asm/non_matching/game/stage/background/StageBgUpdate_Zone6Acts12.inc",
|
||||
gBgCntRegs[3] |= BGCNT_PRIORITY(2);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
gBgPalette[(15 * 16) + i] = RGB_BLACK;
|
||||
SET_PALETTE_COLOR_BG(15, i, RGB_BLACK);
|
||||
}
|
||||
|
||||
// jumps to _0801D8EE for this
|
||||
@@ -1755,7 +1756,7 @@ NONMATCH("asm/non_matching/game/stage/background/StageBgUpdate_Zone6Acts12.inc",
|
||||
u32 green = ((gUnknown_080D5C02[0][i][1] * r6) >> 5) & 0x1F;
|
||||
u32 blue = ((gUnknown_080D5C02[0][i][2] * r6) >> 5) & 0x1F;
|
||||
|
||||
gBgPalette[(15 * 16) + i] = ((blue << 10) | (green << 5) | red);
|
||||
SET_PALETTE_COLOR_BG(15, i, RGB16_REV(red, blue, green));
|
||||
}
|
||||
|
||||
// jumps to _0801D83C for this
|
||||
@@ -1773,7 +1774,7 @@ NONMATCH("asm/non_matching/game/stage/background/StageBgUpdate_Zone6Acts12.inc",
|
||||
u32 green = gUnknown_080D5C02[0][i][1];
|
||||
u32 blue = gUnknown_080D5C02[0][i][2];
|
||||
|
||||
gBgPalette[(15 * 16) + i] = ((blue << 10) | (green << 5) | red);
|
||||
SET_PALETTE_COLOR_BG(15, i, RGB16_REV(red, blue, green));
|
||||
}
|
||||
|
||||
// _0801D83C
|
||||
@@ -1799,7 +1800,7 @@ NONMATCH("asm/non_matching/game/stage/background/StageBgUpdate_Zone6Acts12.inc",
|
||||
u32 green = ((gUnknown_080D5C02[0][i][1] * r6) >> 4) & 0x1F;
|
||||
u32 blue = ((gUnknown_080D5C02[0][i][2] * r6) >> 4) & 0x1F;
|
||||
|
||||
gBgPalette[(15 * 16) + i] = ((blue << 10) | (green << 5) | red);
|
||||
SET_PALETTE_COLOR_BG(15, i, RGB16_REV(red, blue, green));
|
||||
}
|
||||
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
@@ -1808,7 +1809,7 @@ NONMATCH("asm/non_matching/game/stage/background/StageBgUpdate_Zone6Acts12.inc",
|
||||
case 7: {
|
||||
s8 i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
gBgPalette[(15 * 16) + i] = RGB_BLACK;
|
||||
SET_PALETTE_COLOR_BG(15, i, RGB_BLACK);
|
||||
}
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
gDispCnt &= ~(DISPCNT_BG0_ON);
|
||||
@@ -2034,9 +2035,7 @@ NONMATCH("asm/non_matching/game/stage/background/Zone7BgUpdate_Inside.inc", void
|
||||
#else
|
||||
{ // Draw the "ceiling" movement
|
||||
for (lineY = 0; lineY < 8; lineY++) {
|
||||
dst = gBgPalette;
|
||||
dst += 209;
|
||||
dst[lineY] = sPalette_Zone7BgCeiling[((x >> 4) & 0x7) + 1];
|
||||
SET_PALETTE_COLOR_BG(13, lineY + 1, sPalette_Zone7BgCeiling[((x >> 4) & 0x7) + 1]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2136,7 +2135,7 @@ const u16 sZone7BgTransitionRegions[2][NUM_ZONE7_BG_TRANSITION_POSITIONS] = {
|
||||
{ 1344, 2616, 9432, 15192, 18552, 19892, 23158, 25848 }, // ACT 2
|
||||
};
|
||||
|
||||
const u16 gUnknown_080D5CC2[16] = INCBIN_U16("graphics/080D5CC2.gbapal");
|
||||
const u16 gUnknown_080D5CC2[PALETTE_LEN_4BPP] = INCBIN_U16("graphics/080D5CC2.gbapal");
|
||||
|
||||
void CreateStageBg_ZoneFinal_0(void)
|
||||
{
|
||||
@@ -2187,7 +2186,7 @@ void CreateStageBg_ZoneFinal_0(void)
|
||||
gBgScrollRegs[3][1] = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(gUnknown_080D5CC2); i++) {
|
||||
gBgPalette[i] = gUnknown_080D5CC2[i];
|
||||
SET_PALETTE_COLOR_BG(0, i, gUnknown_080D5CC2[i]);
|
||||
}
|
||||
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
@@ -2316,9 +2315,9 @@ void StageBgUpdate_Zone5ActBoss(UNUSED s32 a, UNUSED s32 b)
|
||||
|
||||
void StageBgUpdate_Zone6ActBoss(UNUSED s32 a, UNUSED s32 b)
|
||||
{
|
||||
gBgCntRegs[0] |= 0x3;
|
||||
gBgCntRegs[3] &= ~0x3;
|
||||
gBgCntRegs[3] |= 0x2;
|
||||
gBgCntRegs[0] |= BGCNT_PRIORITY(3);
|
||||
gBgCntRegs[3] &= ~BGCNT_PRIORITY(3);
|
||||
gBgCntRegs[3] |= BGCNT_PRIORITY(2);
|
||||
gBgScrollRegs[0][0] = (gBgScrollRegs[0][0] - 2) & 0xFF;
|
||||
gBgScrollRegs[0][1] = (gBgScrollRegs[0][1] + 1) & 0xFF;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ static const u8 sGettingReadyAnimationDuration[NUM_CHARACTERS]
|
||||
= { [CHARACTER_SONIC] = 40, [CHARACTER_CREAM] = 55, [CHARACTER_TAILS] = 52, [CHARACTER_KNUCKLES] = 40, [CHARACTER_AMY] = 40 };
|
||||
|
||||
// Each byte represents one RGB channel (0-31)
|
||||
static const u8 gUnknown_080D6FF5[NUM_CHARACTERS + 1][16][3] = {
|
||||
static const u8 gUnknown_080D6FF5[NUM_CHARACTERS + 1][PALETTE_LEN_4BPP][3] = {
|
||||
{
|
||||
{ 0x00, 0x17, 0x06 },
|
||||
{ 0x16, 0x16, 0x16 },
|
||||
@@ -731,13 +731,13 @@ static void Task_802F9F8(void)
|
||||
|
||||
if (IS_SINGLE_PLAYER) {
|
||||
// _0802FA4C+8
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
r = gUnknown_080D6FF5[gSelectedCharacter][i][0];
|
||||
r = (r * frameCounter) / 16u;
|
||||
g = ((gUnknown_080D6FF5[gSelectedCharacter][i][1] * frameCounter) / 16u);
|
||||
b = ((gUnknown_080D6FF5[gSelectedCharacter][i][2] * frameCounter) / 16u);
|
||||
|
||||
gObjPalette[i] = RGB16_REV(r, g, b);
|
||||
SET_PALETTE_COLOR_OBJ(0, i, RGB16_REV(r, g, b));
|
||||
|
||||
if (gCheese != NULL) {
|
||||
r = gUnknown_080D6FF5[5][i][0];
|
||||
@@ -745,7 +745,7 @@ static void Task_802F9F8(void)
|
||||
g = ((gUnknown_080D6FF5[5][i][1] * frameCounter) / 16u);
|
||||
b = ((gUnknown_080D6FF5[5][i][2] * frameCounter) / 16u);
|
||||
|
||||
gObjPalette[14 * 16 + i] = RGB16_REV(r, g, b);
|
||||
SET_PALETTE_COLOR_OBJ(14, i, RGB16_REV(r, g, b));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -754,25 +754,25 @@ static void Task_802F9F8(void)
|
||||
|
||||
for (sid = 0; sid < MULTI_SIO_PLAYERS_MAX; sid++) {
|
||||
if (GetBit(gMultiplayerConnections, sid)) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
r = gUnknown_080D6FF5[(gMultiplayerCharacters)[sid]][i][0];
|
||||
r = (r * frameCounter) / 16u;
|
||||
g = ((gUnknown_080D6FF5[(gMultiplayerCharacters)[sid]][i][1] * frameCounter) / 16u);
|
||||
b = ((gUnknown_080D6FF5[(gMultiplayerCharacters)[sid]][i][2] * frameCounter) / 16u);
|
||||
|
||||
gObjPalette[sid * 16 + i] = RGB16_REV(r, g, b);
|
||||
SET_PALETTE_COLOR_OBJ(sid, i, RGB16_REV(r, g, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gCheese != NULL) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
r = gUnknown_080D6FF5[5][i][0];
|
||||
r = (r * frameCounter) / 16u;
|
||||
g = ((gUnknown_080D6FF5[5][i][1] * frameCounter) / 16u);
|
||||
b = ((gUnknown_080D6FF5[5][i][2] * frameCounter) / 16u);
|
||||
|
||||
gObjPalette[14 * 16 + i] = RGB16_REV(r, g, b);
|
||||
SET_PALETTE_COLOR_OBJ(14, i, RGB16_REV(r, g, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1234,7 +1234,7 @@ static void Task_UpdateStageLoadingScreen(void)
|
||||
IntroBackgrounds *introBackgrounds = TASK_DATA(gCurTask);
|
||||
u32 counter = introBackgrounds->controller->counter;
|
||||
|
||||
gBgPalette[0] = sZoneLoadingCharacterColors[gSelectedCharacter];
|
||||
SET_PALETTE_COLOR_BG(0, 0, sZoneLoadingCharacterColors[gSelectedCharacter]);
|
||||
|
||||
gFlags |= FLAGS_UPDATE_BACKGROUND_PALETTES;
|
||||
|
||||
|
||||
@@ -849,4 +849,4 @@ static void sub_802C9B0(struct SuperSonic *sonic)
|
||||
}
|
||||
}
|
||||
|
||||
bool32 sub_802C9E0(void) { return FALSE; }
|
||||
bool32 sub_802C9E0(void) { return FALSE; }
|
||||
+3
-3
@@ -43,7 +43,7 @@ const u16 sAnims1UpIcons[][3]
|
||||
[CHARACTER_KNUCKLES] = { ONE_UP_ICON_TILE_COUNT, SA2_ANIM_LIFE_COUNTER, SA2_ANIM_VARIANT_LIFE_COUNTER_KNUCKLES },
|
||||
[CHARACTER_AMY] = { ONE_UP_ICON_TILE_COUNT, SA2_ANIM_LIFE_COUNTER, SA2_ANIM_VARIANT_LIFE_COUNTER_AMY } };
|
||||
|
||||
const u16 sPalette1UpIcons[] = INCBIN_U16("graphics/ui_icon_1_up.gbapal");
|
||||
const u16 sPalette1UpIcons[PALETTE_LEN_4BPP] = INCBIN_U16("graphics/ui_icon_1_up.gbapal");
|
||||
|
||||
const u32 sOrdersOfMagnitude[6] = {
|
||||
100000, 10000, 1000, 100, 10, 1,
|
||||
@@ -219,8 +219,8 @@ struct Task *CreateStageUI(void)
|
||||
s->frameFlags = 0;
|
||||
ui->ringCurrentFrame = 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
gObjPalette[0x70 + i] = sPalette1UpIcons[i];
|
||||
for (i = 0; i < PALETTE_LEN_4BPP; i++) {
|
||||
SET_PALETTE_COLOR_OBJ(7, i, sPalette1UpIcons[i]);
|
||||
}
|
||||
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
|
||||
+23
-22
@@ -21,6 +21,7 @@
|
||||
#include "game/stage/screen_fade.h"
|
||||
#include "game/time_attack/lobby.h"
|
||||
#include "game/time_attack/mode_select.h"
|
||||
#include "game/sa1_sa2_shared/camera.h" // TILE_WIDTH
|
||||
|
||||
#include "data/recordings.h"
|
||||
|
||||
@@ -415,8 +416,8 @@ static void CreateTitleScreenWithoutIntro(TitleScreen *titleScreen)
|
||||
bg0->unk20 = 0;
|
||||
bg0->unk22 = 0;
|
||||
bg0->unk24 = 0;
|
||||
bg0->targetTilesX = 26;
|
||||
bg0->targetTilesY = 10;
|
||||
bg0->targetTilesX = 208 / TILE_WIDTH;
|
||||
bg0->targetTilesY = 80 / TILE_WIDTH;
|
||||
bg0->paletteOffset = 0;
|
||||
bg0->flags = BACKGROUND_FLAG_4 | BACKGROUND_FLAGS_BG_ID(2);
|
||||
|
||||
@@ -441,8 +442,8 @@ static void CreateTitleScreenWithoutIntro(TitleScreen *titleScreen)
|
||||
config40->unk20 = 0;
|
||||
config40->unk22 = 0;
|
||||
config40->unk24 = 0;
|
||||
config40->targetTilesX = 0x20;
|
||||
config40->targetTilesY = 0x40;
|
||||
config40->targetTilesX = 256 / TILE_WIDTH;
|
||||
config40->targetTilesY = 512 / TILE_WIDTH;
|
||||
config40->paletteOffset = 0;
|
||||
config40->flags = BACKGROUND_FLAGS_BG_ID(1);
|
||||
|
||||
@@ -461,9 +462,9 @@ static void InitTitleScreenBackgrounds(TitleScreen *titleScreen)
|
||||
gDispCnt = DISPCNT_MODE_1;
|
||||
gDispCnt |= DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON;
|
||||
|
||||
gBgCntRegs[0] = 0x1f04;
|
||||
gBgCntRegs[1] = 0x9d0a;
|
||||
gBgCntRegs[2] = 0x7a81;
|
||||
gBgCntRegs[0] = BGCNT_16COLOR | BGCNT_TXT256x256 | BGCNT_SCREENBASE(31) | BGCNT_CHARBASE(1) | BGCNT_PRIORITY(0);
|
||||
gBgCntRegs[1] = BGCNT_16COLOR | BGCNT_TXT256x512 | BGCNT_SCREENBASE(29) | BGCNT_CHARBASE(2) | BGCNT_PRIORITY(2);
|
||||
gBgCntRegs[2] = BGCNT_256COLOR | BGCNT_AFF256x256 | BGCNT_WRAP | BGCNT_SCREENBASE(26) | BGCNT_CHARBASE(0) | BGCNT_PRIORITY(1);
|
||||
INIT_BG_SPRITES_LAYER_32(0);
|
||||
INIT_BG_SPRITES_LAYER_32(1);
|
||||
INIT_BG_SPRITES_LAYER_32(2);
|
||||
@@ -489,8 +490,8 @@ static void InitTitleScreenBackgrounds(TitleScreen *titleScreen)
|
||||
bg80->unk20 = 0;
|
||||
bg80->unk22 = 0;
|
||||
bg80->unk24 = 0;
|
||||
bg80->targetTilesX = 30;
|
||||
bg80->targetTilesY = 20;
|
||||
bg80->targetTilesX = DISPLAY_WIDTH / TILE_WIDTH;
|
||||
bg80->targetTilesY = DISPLAY_HEIGHT / TILE_WIDTH;
|
||||
bg80->paletteOffset = 0;
|
||||
bg80->flags = 0;
|
||||
|
||||
@@ -508,8 +509,8 @@ static void InitTitleScreenBackgrounds(TitleScreen *titleScreen)
|
||||
bg0->unk20 = 0;
|
||||
bg0->unk22 = 0;
|
||||
bg0->unk24 = 0;
|
||||
bg0->targetTilesX = 32;
|
||||
bg0->targetTilesY = 32;
|
||||
bg0->targetTilesX = 256 / TILE_WIDTH;
|
||||
bg0->targetTilesY = 256 / TILE_WIDTH;
|
||||
bg0->paletteOffset = 0;
|
||||
bg0->flags = BACKGROUND_FLAG_4 | BACKGROUND_FLAGS_BG_ID(2);
|
||||
|
||||
@@ -683,8 +684,8 @@ static void Task_IntroStartSonicTeamLogoAnim(void)
|
||||
bg->unk20 = 0;
|
||||
bg->unk22 = 0;
|
||||
bg->unk24 = 0;
|
||||
bg->targetTilesX = 30;
|
||||
bg->targetTilesY = 20;
|
||||
bg->targetTilesX = DISPLAY_WIDTH / 8;
|
||||
bg->targetTilesY = DISPLAY_HEIGHT / 8;
|
||||
bg->paletteOffset = 0;
|
||||
bg->flags = 0x10;
|
||||
DrawBackground(bg);
|
||||
@@ -795,13 +796,13 @@ static void Task_IntroPanSkyAnim(void)
|
||||
}
|
||||
|
||||
gBgScrollRegs[1][1] -= titleScreen->introPanUpVelocity;
|
||||
if (gBgScrollRegs[1][1] < 0xAF) {
|
||||
gBgScrollRegs[1][1] = 0xAF;
|
||||
if (gBgScrollRegs[1][1] < 175) {
|
||||
gBgScrollRegs[1][1] = 175;
|
||||
}
|
||||
|
||||
if (gBgScrollRegs[1][1] < 0x15F) {
|
||||
gDispCnt &= 0xFBFF;
|
||||
gDispCnt &= 0xBFFF;
|
||||
if (gBgScrollRegs[1][1] < 351) {
|
||||
gDispCnt &= ~DISPCNT_BG2_ON;
|
||||
gDispCnt &= ~DISPCNT_WIN1_ON;
|
||||
} else {
|
||||
titleScreen->wavesTopOffset += titleScreen->introPanUpVelocity;
|
||||
WavesBackgroundAnim(titleScreen);
|
||||
@@ -845,7 +846,7 @@ static void Task_IntroPanSkyAnim(void)
|
||||
bg0->flags = 0x10;
|
||||
DrawBackground(bg0);
|
||||
|
||||
gBgScrollRegs[0][1] = 0x4F;
|
||||
gBgScrollRegs[0][1] = 79;
|
||||
gCurTask->main = Task_IntroSkyAnim;
|
||||
|
||||
titleScreen->animFrame = 0;
|
||||
@@ -944,11 +945,11 @@ static void Task_IntroSkyAnim(void)
|
||||
|
||||
DrawBackground(bg0);
|
||||
|
||||
gBgCntRegs[2] &= 0xDFFF;
|
||||
gBgCntRegs[2] &= ~DISPCNT_WIN0_ON;
|
||||
gCurTask->main = Task_IntroFadeInTitleScreenAnim;
|
||||
|
||||
gDispCnt |= 0x400;
|
||||
gDispCnt &= 0xFEFF;
|
||||
gDispCnt |= DISPCNT_BG2_ON;
|
||||
gDispCnt &= ~DISPCNT_BG0_ON;
|
||||
|
||||
gBldRegs.bldAlpha = 0x1000;
|
||||
gBldRegs.bldCnt = 0x244;
|
||||
|
||||
@@ -109,10 +109,10 @@ void InitWaterPalettes(void)
|
||||
#ifndef NON_MATCHING
|
||||
{
|
||||
const u16 *src = gSpritePalettes[pal];
|
||||
CopyPalette((u32 *)wd->pal[j], (u32 *)src, 16);
|
||||
CopyPalette((u32 *)wd->pal[j], (u32 *)src, PALETTE_LEN_4BPP);
|
||||
};
|
||||
#else
|
||||
CopyPalette((u32 *)wd->pal[j], (u32 *)gSpritePalettes[pal], 16);
|
||||
CopyPalette((u32 *)wd->pal[j], (u32 *)gSpritePalettes[pal], PALETTE_LEN_4BPP);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
@@ -121,21 +121,21 @@ void InitWaterPalettes(void)
|
||||
animId = gUnknown_080D550C[character];
|
||||
animation = gAnimations[animId];
|
||||
pal = animation[0]->pal.palId;
|
||||
CopyPalette((u32 *)wd->pal[0], (u32 *)gSpritePalettes[pal], 16);
|
||||
CopyPalette((u32 *)wd->pal[0], (u32 *)gSpritePalettes[pal], PALETTE_LEN_4BPP);
|
||||
|
||||
character = gPlayer.character;
|
||||
animId = sCharacterPalettesBoostEffect[character];
|
||||
animation = gAnimations[animId];
|
||||
pal = animation[0]->pal.palId;
|
||||
CopyPalette((u32 *)wd->pal[1], (u32 *)gSpritePalettes[pal], 16);
|
||||
CopyPalette((u32 *)wd->pal[1], (u32 *)gSpritePalettes[pal], PALETTE_LEN_4BPP);
|
||||
}
|
||||
|
||||
animId = SA2_ANIM_PALETTE_554;
|
||||
animation = gAnimations[animId];
|
||||
pal = (animation[0]->pal.palId + 4);
|
||||
CopyPalette((u32 *)wd->pal[4], (u32 *)gSpritePalettes[pal], 12 * 16);
|
||||
CopyPalette((u32 *)wd->pal[4], (u32 *)gSpritePalettes[pal], 12 * PALETTE_LEN_4BPP);
|
||||
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)wd->pal[16], (u32 *)gBgPalette, water->mask, 16 * 16);
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)wd->pal[16], (u32 *)&GET_PALETTE_COLOR_BG(0, 0), water->mask, 16 * PALETTE_LEN_4BPP);
|
||||
}
|
||||
|
||||
void CreateStageWaterTask(s32 waterLevel, u32 p1, u32 mask)
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ SoundMain:
|
||||
ldr r3, [r0, o_SoundInfo_ident]
|
||||
cmp r2, r3
|
||||
beq SoundMain_1
|
||||
bx lr @ Exit the function if ident doesn't match ID_NUMBER.
|
||||
bx lr @ Exit the function if ident does not match ID_NUMBER.
|
||||
SoundMain_1:
|
||||
adds r3, 1
|
||||
str r3, [r0, o_SoundInfo_ident]
|
||||
|
||||
+39
-5
@@ -8,15 +8,48 @@
|
||||
#define HEAP_END ewram_end
|
||||
#endif
|
||||
|
||||
/* --- HOW THIS WORKS ---
|
||||
*
|
||||
* gVramHeapState[] represents (or *can* represent) the entire Object Tiles memory range in VRAM (0x06010000 -> 0x06018000).
|
||||
* Whereby each u16 word in gVramHeapState contains a reserved number of segments.
|
||||
* Each segment in SA2: 4 tiles * size-per-tile = (4 * 0x20 | 0x80) [segment tile-count might vary per game]
|
||||
*
|
||||
* I say *can*, because in practice, there's a much smaller available heap.
|
||||
* In practice it starts at:
|
||||
* 0x06013200 in SA1
|
||||
* 0x06013A00 in SA2
|
||||
* 0x06012C50 in SA3
|
||||
* ( OBJ_VRAM1 - (VRAM_HEAP_TILE_COUNT * TILE_SIZE_4BPP) )
|
||||
*
|
||||
* Take this representation for example:
|
||||
*
|
||||
* Imagine every digit being a u16 word.
|
||||
* 0000000000000000
|
||||
* ^
|
||||
* This is basically an entirely empty VRAM heap, so starting with the first byte, some number of segments could be reserved.
|
||||
* Note that VramResetHeapState() just clears the entire gVramHeapState[], so anything allocated before would be allocateable by a new
|
||||
* VramMalloc() call.
|
||||
*
|
||||
* Below, each * is a word reserved by the segment-count preceding it, so those cannot be allocated.
|
||||
* 6*****4***000000
|
||||
* ^ ^
|
||||
* | |
|
||||
* +-----+--- 6 allocated segments (24 tiles)
|
||||
* |
|
||||
* 4 allocated segments (16 tiles)
|
||||
*
|
||||
* Note that the count itself is part of the number of allocated segments
|
||||
*/
|
||||
|
||||
void *VramMalloc(u32 numTiles)
|
||||
{
|
||||
u16 i, j;
|
||||
u32 count = numTiles;
|
||||
count = (count + (VRAM_TILE_SLOTS_PER_SEGMENT - 1)) / VRAM_TILE_SLOTS_PER_SEGMENT; // round up
|
||||
u32 segCount = numTiles;
|
||||
segCount = (segCount + (VRAM_TILE_SLOTS_PER_SEGMENT - 1)) / VRAM_TILE_SLOTS_PER_SEGMENT; // round up
|
||||
|
||||
for (i = 0; i < gVramHeapMaxTileSlots / VRAM_TILE_SLOTS_PER_SEGMENT; i++) {
|
||||
if (gVramHeapState[i] == 0) {
|
||||
for (j = 0; j < count; j++) {
|
||||
for (j = 0; j < segCount; j++) {
|
||||
if (i + j >= (gVramHeapMaxTileSlots / VRAM_TILE_SLOTS_PER_SEGMENT)) {
|
||||
return HEAP_END;
|
||||
}
|
||||
@@ -25,8 +58,8 @@ void *VramMalloc(u32 numTiles)
|
||||
}
|
||||
}
|
||||
|
||||
if (j == count) {
|
||||
gVramHeapState[i] = count;
|
||||
if (j == segCount) {
|
||||
gVramHeapState[i] = segCount;
|
||||
return (void *)(gVramHeapStartAddr + i * VRAM_HEAP_SEGMENT_SIZE);
|
||||
}
|
||||
} else {
|
||||
@@ -36,6 +69,7 @@ void *VramMalloc(u32 numTiles)
|
||||
return HEAP_END;
|
||||
}
|
||||
|
||||
// Clear the entire gVramHeapState[], leading to zero tiles being allocated (even if OBJ_VRAM is populated)
|
||||
void VramResetHeapState(void) { DmaFill16(3, 0, gVramHeapState, sizeof(gVramHeapState)); }
|
||||
|
||||
void VramFree(void *addr)
|
||||
|
||||
+494
-91
@@ -1,8 +1,14 @@
|
||||
#include <malloc.h> // realloc
|
||||
//#include <malloc.h> // realloc
|
||||
#include <stdio.h> // printf
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <math.h> // sinf/cosf
|
||||
#include "global.h" // TEMP for PLTT
|
||||
#include "core.h" // temp?
|
||||
#include "tilemap.h" // struct Tile
|
||||
#include "platform/shared/opengl.h"
|
||||
#include "trig.h" // ONE_CYCLE
|
||||
#include "game/sa1_sa2_shared/globals.h" // gCurrentLevel - TEMP: this shouldn't be exposed to the OpenGL backend...
|
||||
|
||||
// NOTE: This is NOT final at all. EXPERIMENTAL!!!!!
|
||||
|
||||
@@ -11,16 +17,40 @@
|
||||
// TEMP
|
||||
static GLuint sTempTextureHandles[3] = { 0 };
|
||||
|
||||
#define NUM_RGB_CHANNELS 4
|
||||
u8 tempRgbaPalette[16 * 32][NUM_RGB_CHANNELS] = {};
|
||||
u8 tempRgbaFrame[DISPLAY_WIDTH * DISPLAY_HEIGHT][NUM_RGB_CHANNELS] = {};
|
||||
#define TILES_PER_CHUNK_AXIS 12
|
||||
#define TILES_PER_CHUNK (SQUARE(TILES_PER_CHUNK_AXIS))
|
||||
#define TILE_SIZE_PIXELS (8 * 8)
|
||||
#define TILE_SIZE_RGBA (TILE_SIZE_PIXELS * sizeof(u32))
|
||||
#define CHUNK_SIZE_RGBA (TILES_PER_CHUNK * TILE_SIZE_RGBA)
|
||||
#define CHUNK_SIZE_TEXCOORD (TILES_PER_CHUNK * sizeof(ChunkTileVertex))
|
||||
#define NUM_RGB_CHANNELS 4
|
||||
// u8 tempRgbaFrame[DISPLAY_WIDTH * DISPLAY_HEIGHT][NUM_RGB_CHANNELS] = {};
|
||||
|
||||
typedef struct ColorRGBA {
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
} ColorRGBA;
|
||||
typedef struct {
|
||||
u8 *data;
|
||||
int width, height;
|
||||
} TextureBuffer;
|
||||
static TextureBuffer sDynTextureBuffer = { 0 };
|
||||
|
||||
ColorRGBA tempRgbaPalette[16 * 32] = {};
|
||||
static Background *sActiveBackgrounds[4] = { 0 };
|
||||
|
||||
void Debug_PrintMatrix(float *mtx)
|
||||
{
|
||||
printf("%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n"
|
||||
"%f %f %f %f\n\n",
|
||||
mtx[0], mtx[1], mtx[2], mtx[3], mtx[4], mtx[5], mtx[6], mtx[7], mtx[8], mtx[9], mtx[10], mtx[11], mtx[12], mtx[13], mtx[14],
|
||||
mtx[15]);
|
||||
}
|
||||
|
||||
static void TempConvertPLTTToRGBA8(void)
|
||||
{
|
||||
// Convert PLTT from ABGR1555 -> RGBA8
|
||||
@@ -30,14 +60,14 @@ static void TempConvertPLTTToRGBA8(void)
|
||||
float g = (float)((color & 0x3E0) >> 5) / 31.0;
|
||||
float b = (float)((color & 0x7C00) >> 10) / 31.0;
|
||||
|
||||
tempRgbaPalette[i][0] = r * 255.0;
|
||||
tempRgbaPalette[i][1] = g * 255.0;
|
||||
tempRgbaPalette[i][2] = b * 255.0;
|
||||
tempRgbaPalette[i][3] = 1 * 255.0;
|
||||
tempRgbaPalette[i].r = r * 255.0;
|
||||
tempRgbaPalette[i].g = g * 255.0;
|
||||
tempRgbaPalette[i].b = b * 255.0;
|
||||
tempRgbaPalette[i].a = 1 * 255.0;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 *TempConvertPLTTEntryToRGBA8(u8 paletteId)
|
||||
static ColorRGBA *TempConvertPLTTEntryToRGBA8(u8 paletteId)
|
||||
{
|
||||
// Convert PLTT from ABGR1555 -> RGBA8
|
||||
u16 *pal4BPP = &PLTT[(paletteId + 16) * 16];
|
||||
@@ -49,13 +79,13 @@ static u8 *TempConvertPLTTEntryToRGBA8(u8 paletteId)
|
||||
float g = (float)((color & 0x3E0) >> 5) / 31.0;
|
||||
float b = (float)((color & 0x7C00) >> 10) / 31.0;
|
||||
|
||||
tempRgbaPalette[paletteId * 16 + i][0] = r * 255.0;
|
||||
tempRgbaPalette[paletteId * 16 + i][1] = g * 255.0;
|
||||
tempRgbaPalette[paletteId * 16 + i][2] = b * 255.0;
|
||||
tempRgbaPalette[paletteId * 16 + i][3] = 1 * 255.0;
|
||||
tempRgbaPalette[paletteId * 16 + i].r = r * 255.0;
|
||||
tempRgbaPalette[paletteId * 16 + i].g = g * 255.0;
|
||||
tempRgbaPalette[paletteId * 16 + i].b = b * 255.0;
|
||||
tempRgbaPalette[paletteId * 16 + i].a = 1 * 255.0;
|
||||
}
|
||||
|
||||
return tempRgbaPalette[paletteId * 16];
|
||||
return &tempRgbaPalette[paletteId * 16];
|
||||
}
|
||||
|
||||
// TODO: This should be done offline.
|
||||
@@ -71,28 +101,362 @@ static void TempConvert4bppToRGBA8_DynTextureBuffer(const u8 *bitmap4bpp, int wi
|
||||
} else {
|
||||
printf("realloc: w 0x%X, h 0x%X, full: 0x%X\n", width, height, (u32)(width * height * sizeof(u32)));
|
||||
}
|
||||
|
||||
sDynTextureBuffer.width = width;
|
||||
sDynTextureBuffer.height = height;
|
||||
}
|
||||
|
||||
u8 *texturePalette = TempConvertPLTTEntryToRGBA8(paletteId);
|
||||
|
||||
sDynTextureBuffer.width = width;
|
||||
sDynTextureBuffer.height = height;
|
||||
ColorRGBA *texturePalette = TempConvertPLTTEntryToRGBA8(paletteId);
|
||||
|
||||
u16 widthInTiles = width >> 3;
|
||||
|
||||
int numSourcePixels = width * height;
|
||||
for (int frameY = 0; frameY < height; frameY++) {
|
||||
for (int frameX = 0; frameX < width; frameX++) {
|
||||
u8 colorIndex = ((frameY & 0x7) * 8 + (frameX & 0x7));
|
||||
int tileIndex = (frameY >> 3) * widthInTiles + (frameX >> 3);
|
||||
int tileColorIndex = ((frameY & 0x7) * 8 + (frameX & 0x7)) + (tileIndex * (8 * 8));
|
||||
int targetColorIndex = ((frameY * width) + frameX);
|
||||
|
||||
bool8 doShift = (colorIndex & 1);
|
||||
u8 textureColorId = bitmap4bpp[colorIndex >> 1] & (0xF << (doShift * 4));
|
||||
bool8 doShift = (targetColorIndex & 1);
|
||||
int textureColorId = bitmap4bpp[tileColorIndex >> 1] & (0xF << (doShift * 4));
|
||||
textureColorId >>= doShift * 4;
|
||||
|
||||
sDynTextureBuffer.data[colorIndex * 4 + 0] = tempRgbaPalette[textureColorId][0];
|
||||
sDynTextureBuffer.data[colorIndex * 4 + 1] = tempRgbaPalette[textureColorId][1];
|
||||
sDynTextureBuffer.data[colorIndex * 4 + 2] = tempRgbaPalette[textureColorId][2];
|
||||
sDynTextureBuffer.data[colorIndex * 4 + 3] = 0xFF;
|
||||
sDynTextureBuffer.data[targetColorIndex * 4 + 0] = texturePalette[textureColorId].r;
|
||||
sDynTextureBuffer.data[targetColorIndex * 4 + 1] = texturePalette[textureColorId].g;
|
||||
sDynTextureBuffer.data[targetColorIndex * 4 + 2] = texturePalette[textureColorId].b;
|
||||
sDynTextureBuffer.data[targetColorIndex * 4 + 3] = (textureColorId == 0) ? 0x00 : 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct ChunkTileVertex {
|
||||
u8 x, y;
|
||||
} ChunkTileVertex;
|
||||
|
||||
typedef struct ChunkGfx {
|
||||
ChunkTileVertex *tileVerts;
|
||||
u8 *rgbaChunks;
|
||||
u16 count;
|
||||
u16 capacity;
|
||||
} ChunkGfx;
|
||||
|
||||
static ChunkGfx sChunkGfx = { 0 };
|
||||
#define RENDERED_CHUNKS_W ((DISPLAY_WIDTH / 96) + 2)
|
||||
#define RENDERED_CHUNKS_H ((DISPLAY_HEIGHT / 96) + 2)
|
||||
#define RENDERED_CHUNKS (RENDERED_CHUNKS_W * RENDERED_CHUNKS_H)
|
||||
|
||||
// Set of chunks that have to be drawn this frame
|
||||
typedef struct ChunkSet {
|
||||
u16 *items;
|
||||
u16 count, capacity;
|
||||
} ChunkSet;
|
||||
static ChunkSet sChunkSet = { 0 };
|
||||
|
||||
// TODO: minY should be from upper-left corner, not bottom-left!
|
||||
void OpenGL_RenderRGBABuffer(u8 *buffer, u16 bufferWidth, u16 bufferHeight, float minX, float minY, float maxX, float maxY)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, sTempTextureHandles[2]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // downscale filtering
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // upscale filtering
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
{
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex2f(minX, maxY);
|
||||
glTexCoord2f(1.0, 1.0);
|
||||
glVertex2f(maxX, minY);
|
||||
glTexCoord2f(0.0, 1.0);
|
||||
glVertex2f(minX, minY);
|
||||
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex2f(minX, maxY);
|
||||
glTexCoord2f(1.0, 0.0);
|
||||
glVertex2f(maxX, maxY);
|
||||
glTexCoord2f(1.0, 1.0);
|
||||
glVertex2f(maxX, minY);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void CreateChunkSet(void)
|
||||
{
|
||||
const int defaultCap = 16;
|
||||
void *mem = malloc(defaultCap * sizeof(*sChunkSet.items));
|
||||
sChunkSet.items = mem;
|
||||
sChunkSet.items[0] = 0;
|
||||
sChunkSet.count = 1; // initialize to 1, to skip zero-filled chunk (which always exists)
|
||||
sChunkSet.capacity = defaultCap;
|
||||
}
|
||||
|
||||
void FindUniqueChunks(ChunkSet *set, Background *bg, u16 mapChunkX, u16 mapChunkY, u8 screenChunkWidth, u8 screenChunkHeight)
|
||||
{
|
||||
for (int y = 0; y < screenChunkHeight; y++) {
|
||||
for (int x = 0; x < screenChunkWidth; x++) {
|
||||
u32 screenChunkIndex = (mapChunkY + y) * bg->mapWidth + (mapChunkX + x);
|
||||
const u16 *chunk = &bg->metatileMap[screenChunkIndex];
|
||||
const u16 chunkId = *chunk;
|
||||
bool8 isInSet = FALSE;
|
||||
|
||||
// Find chunk ID in set
|
||||
for (int setI = 0; setI < set->count; setI++) {
|
||||
if (set->items[setI] == chunkId) {
|
||||
isInSet = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add if not inside
|
||||
if (!isInSet) {
|
||||
while (set->count + 1 >= set->capacity) {
|
||||
set->items = realloc(set->items, set->capacity * 2 * sizeof(*set->items));
|
||||
set->capacity *= 2;
|
||||
}
|
||||
|
||||
set->items[set->count] = chunkId;
|
||||
set->count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTilemap(ColorRGBA *dstBuffer, Background *bg, int chunkIndex)
|
||||
{
|
||||
const u8 *tileset = bg->graphics.src;
|
||||
int chunkTileCount = bg->xTiles * bg->yTiles;
|
||||
u8 bgId = bg->flags & BACKGROUND_FLAGS_MASK_BG_ID;
|
||||
bool8 mapIs4BPP = (gBgCntRegs[bgId] & BGCNT_256COLOR) ? FALSE : TRUE;
|
||||
|
||||
if (!(bg->flags & BACKGROUND_FLAG_IS_LEVEL_MAP)) {
|
||||
// NOTE(Jace): Non-stage maps do not have any "chunks",
|
||||
// but chunks themselves get rendered like all other tilemaps
|
||||
chunkIndex = 0;
|
||||
}
|
||||
|
||||
for (int tileIdY = 0; tileIdY < bg->yTiles; tileIdY++) {
|
||||
for (int tileIdX = 0; tileIdX < bg->xTiles; tileIdX++) {
|
||||
// int tileId = tileIdY * bg->xTiles + tileIdX;
|
||||
ColorRGBA *dstTileRGBA = &dstBuffer[tileIdY * 8 * (bg->xTiles * 8) + tileIdX * 8];
|
||||
|
||||
if (mapIs4BPP) {
|
||||
int tileInChunkIndex = (chunkIndex * chunkTileCount) + tileIdY * bg->xTiles + tileIdX;
|
||||
Tile tile = *(const Tile *)&bg->layout[tileInChunkIndex];
|
||||
const u8 *srcTile4BPP = &tileset[(tile.index * TILE_SIZE_PIXELS) >> 1];
|
||||
|
||||
for (int tileLoopY = 0; tileLoopY < 8; tileLoopY++) {
|
||||
int tileY = (tile.yFlip) ? (7 - tileLoopY) : tileLoopY;
|
||||
for (int tileLoopX = 0; tileLoopX < 8; tileLoopX++) {
|
||||
int tileX = (tile.xFlip) ? (7 - tileLoopX) : tileLoopX;
|
||||
|
||||
int targetColorIndex = ((tileY * 8) + tileX);
|
||||
bool8 doShift = (targetColorIndex & 1);
|
||||
int colorId = srcTile4BPP[targetColorIndex >> 1] & (0xF << (doShift * 4));
|
||||
colorId >>= doShift * 4;
|
||||
|
||||
ColorRGBA *tilePalette = (ColorRGBA *)(&tempRgbaPalette[tile.pal * 16 + colorId]);
|
||||
int dstTileIndex = tileLoopY * (bg->xTiles * 8) + tileLoopX;
|
||||
dstTileRGBA[dstTileIndex].r = tilePalette->r;
|
||||
dstTileRGBA[dstTileIndex].g = tilePalette->g;
|
||||
dstTileRGBA[dstTileIndex].b = tilePalette->b;
|
||||
dstTileRGBA[dstTileIndex].a = (colorId == 0) ? 0x00 : 0xFF;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 8BPP
|
||||
u8 tile = ((const u8 *)bg->layout)[tileIdY * bg->xTiles + tileIdX];
|
||||
const u8 *srcTile8BPP = &tileset[tile * TILE_SIZE_PIXELS];
|
||||
|
||||
for (int tileLoopY = 0; tileLoopY < 8; tileLoopY++) {
|
||||
int tileY = tileLoopY;
|
||||
for (int tileLoopX = 0; tileLoopX < 8; tileLoopX++) {
|
||||
int tileX = tileLoopX;
|
||||
|
||||
int targetColorIndex = ((tileY * 8) + tileX);
|
||||
int colorId = srcTile8BPP[targetColorIndex];
|
||||
|
||||
ColorRGBA *tilePalette = (ColorRGBA *)(&tempRgbaPalette[colorId]);
|
||||
int dstTileIndex = tileLoopY * (bg->xTiles * 8) + tileLoopX;
|
||||
dstTileRGBA[dstTileIndex].r = tilePalette->r;
|
||||
dstTileRGBA[dstTileIndex].g = tilePalette->g;
|
||||
dstTileRGBA[dstTileIndex].b = tilePalette->b;
|
||||
dstTileRGBA[dstTileIndex].a = (colorId == 0) ? 0x00 : 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CacheUncachedUniqueChunks(Background *bg, ChunkSet *set, ChunkGfx *gfx)
|
||||
{
|
||||
// if (!(bg->flags & (BACKGROUND_DISABLE_TILESET_UPDATE | BACKGROUND_DISABLE_PALETTE_UPDATE)))
|
||||
{
|
||||
for (int chunkSetItemIndex = 0; chunkSetItemIndex < sChunkSet.count; chunkSetItemIndex++) {
|
||||
int chunkIndex = sChunkSet.items[chunkSetItemIndex];
|
||||
if (chunkIndex == 0)
|
||||
continue;
|
||||
|
||||
ColorRGBA *chunkRGBA = (ColorRGBA *)(&gfx->rgbaChunks[chunkSetItemIndex * CHUNK_SIZE_RGBA]);
|
||||
const u8 *tileset4BPP = &((const u8 *)bg->graphics.src)[0];
|
||||
RenderTilemap(chunkRGBA, bg, chunkIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u16 GetChunkSetIndexFromChunkId(ChunkSet *set, u16 chunkId)
|
||||
{
|
||||
for (int i = 0; i < set->count; i++) {
|
||||
if (set->items[i] == chunkId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RenderScreenChunks(ChunkSet *set, ChunkGfx *gfx, Background *bg, s16 mapChunkX, s16 mapChunkY, s16 screenX, s16 screenY,
|
||||
u8 screenChunkWidth, u8 screenChunkHeight)
|
||||
{
|
||||
for (int chunkY = 0; chunkY < screenChunkHeight; chunkY++) {
|
||||
int chunkPosIndexY = (mapChunkY + chunkY);
|
||||
if (chunkPosIndexY >= bg->mapHeight) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int chunkX = 0; chunkX < screenChunkWidth; chunkX++) {
|
||||
int chunkPosIndexX = (mapChunkX + chunkX);
|
||||
if (chunkPosIndexX >= bg->mapWidth) {
|
||||
break;
|
||||
}
|
||||
int chunkPosIndex = chunkPosIndexY * bg->mapWidth + chunkPosIndexX;
|
||||
int chunkSetIndex = GetChunkSetIndexFromChunkId(set, bg->metatileMap[chunkPosIndex]);
|
||||
int chunkStartIndex = chunkSetIndex * CHUNK_SIZE_RGBA;
|
||||
int chunkScreenX = (screenX + (chunkX * 96));
|
||||
int chunkScreenY = DISPLAY_HEIGHT - (screenY + (chunkY * 96));
|
||||
OpenGL_RenderRGBABuffer(&gfx->rgbaChunks[chunkStartIndex], 96, 96, chunkScreenX, chunkScreenY, chunkScreenX + 96,
|
||||
chunkScreenY + 96);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateChunkGfx(ChunkGfx *gfx, Background *bg)
|
||||
{
|
||||
u32 mapWidthPixels = bg->mapWidth * 96;
|
||||
u32 mapHeightPixels = bg->mapHeight * 96;
|
||||
u16 mapChunkX = bg->scrollX / 96;
|
||||
u16 mapChunkY = bg->scrollY / 96;
|
||||
s16 screenX = -(bg->scrollX % 96u);
|
||||
s16 screenY = 96 - (bg->scrollY % 96u);
|
||||
u8 screenChunkWidth = MIN(bg->mapWidth - mapChunkX, RENDERED_CHUNKS_W);
|
||||
u8 screenChunkHeight = MIN(bg->mapHeight - mapChunkY, RENDERED_CHUNKS_H);
|
||||
// bool8 updateAll = TRUE;
|
||||
|
||||
if (sChunkGfx.tileVerts == NULL || sChunkGfx.rgbaChunks == NULL) {
|
||||
const int DEFAULT_CAP = 16;
|
||||
gfx->tileVerts = calloc(RENDERED_CHUNKS, CHUNK_SIZE_TEXCOORD * DEFAULT_CAP);
|
||||
gfx->rgbaChunks = calloc(RENDERED_CHUNKS, 96 * 96 * NUM_RGB_CHANNELS * DEFAULT_CAP);
|
||||
gfx->count = 1; // initialize to 1, to skip zero-filled chunk (which always exists)
|
||||
gfx->capacity = DEFAULT_CAP;
|
||||
}
|
||||
|
||||
// TODO/PERFORMANCE:
|
||||
// This should probably be two sets, like a "Double Buffer",
|
||||
// with the previous set not getting reset and chunks from it getting copied over if needed.
|
||||
// Both would somehow have to be reset on a stage transition
|
||||
// (more accurately: when the tileset/tilemap changes), though!
|
||||
sChunkSet.count = 1; // initialize to 1, to skip zero-filled chunk (which always exists)
|
||||
FindUniqueChunks(&sChunkSet, bg, mapChunkX, mapChunkY, screenChunkWidth, screenChunkHeight);
|
||||
|
||||
TempConvertPLTTToRGBA8();
|
||||
CacheUncachedUniqueChunks(bg, &sChunkSet, &sChunkGfx);
|
||||
|
||||
// Draw metatile RGBA graphics
|
||||
RenderScreenChunks(&sChunkSet, gfx, bg, mapChunkX, mapChunkY, screenX, screenY, screenChunkWidth, screenChunkHeight);
|
||||
|
||||
#if 0
|
||||
// NOTE: Need to call glEnableClientState(GL_TEXTURE_COORD_ARRAY) first!
|
||||
//
|
||||
// Call using this:
|
||||
void glTexCoordPointer(2, // coordinates per vertex
|
||||
GL_BYTE, // data type of each vertex coordinate
|
||||
0, // stride (0 = tightly packed)
|
||||
chunkIndex*CHUNK_SIZE_TEXCOORD);
|
||||
#endif
|
||||
}
|
||||
|
||||
Background *SwitchActiveBackground(Background *bg)
|
||||
{
|
||||
u8 bgId = bg->flags & BACKGROUND_FLAGS_MASK_BG_ID;
|
||||
|
||||
Background *prev = sActiveBackgrounds[bgId];
|
||||
sActiveBackgrounds[bgId] = bg;
|
||||
return prev;
|
||||
}
|
||||
|
||||
// TODO/TEMP: The VRAM memory mimmicking the GBA, used by the software-renderer, shall not be part "hardware renderers".
|
||||
// We need to initialize all sprites and tilemaps without hardcoded values (as happens in the base games).
|
||||
#define IN_VRAM(ptr) (((ptr) >= (void *)&VRAM[0]) && ((ptr) < (void *)&VRAM[VRAM_SIZE]))
|
||||
|
||||
void OpenGL_ProcessBackgroundsCopyQueue(void)
|
||||
{
|
||||
// 'renderOrder' contains one background ID in each slot.
|
||||
u8 renderOrder[4] = { 0 };
|
||||
u8 orderIndex = 0;
|
||||
bool8 needsUpdate[4] = { 0 };
|
||||
|
||||
while (gBackgroundsCopyQueueCursor != gBackgroundsCopyQueueIndex) {
|
||||
Background *bg = gBackgroundsCopyQueue[gBackgroundsCopyQueueCursor];
|
||||
INC_BACKGROUNDS_QUEUE_CURSOR(gBackgroundsCopyQueueCursor);
|
||||
|
||||
if ((bg->flags & BACKGROUND_FLAG_20) && (bg->scrollX == bg->prevScrollX) && bg->scrollY == bg->prevScrollY)
|
||||
continue;
|
||||
|
||||
Background *prev = SwitchActiveBackground(bg);
|
||||
u8 bgId = bg->flags & BACKGROUND_FLAGS_MASK_BG_ID;
|
||||
needsUpdate[bgId] = (prev != bg);
|
||||
}
|
||||
|
||||
for (int prioIndex = 3; prioIndex >= 0; prioIndex--) {
|
||||
for (int bgId = 3; bgId >= 0; bgId--) {
|
||||
u8 bgPrio = gBgCntRegs[bgId] & BGCNT_PRIORITY(0x3);
|
||||
if (bgPrio == prioIndex) {
|
||||
renderOrder[orderIndex] = bgId;
|
||||
|
||||
if (++orderIndex == 4) {
|
||||
goto loopBreak;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loopBreak:
|
||||
|
||||
for (orderIndex = 0; orderIndex < 4; orderIndex++) {
|
||||
u8 bgId = renderOrder[orderIndex];
|
||||
Background *bg = sActiveBackgrounds[bgId];
|
||||
s16 bgScrollX = gBgScrollRegs[bgId][0];
|
||||
s16 bgScrollY = gBgScrollRegs[bgId][1];
|
||||
|
||||
if (gDispCnt & (DISPCNT_BG0_ON << bgId)) {
|
||||
if (bg->flags & BACKGROUND_FLAG_IS_LEVEL_MAP) {
|
||||
UpdateChunkGfx(&sChunkGfx, bg);
|
||||
} else {
|
||||
// TEMP!!!
|
||||
// DON'T MALLOC AND FREE TILEMAPS ALL THE TIME!!!
|
||||
// (Also currently it's possible to get corrupted Background pointers, leading to crashes)
|
||||
if (needsUpdate[bgId]) {
|
||||
if (bg->graphics.dest && !IN_VRAM(bg->graphics.dest)) {
|
||||
free(bg->graphics.dest);
|
||||
}
|
||||
bg->graphics.dest = malloc((bg->xTiles * 8) * (bg->yTiles * 8) * TILE_SIZE_RGBA);
|
||||
}
|
||||
TempConvertPLTTToRGBA8();
|
||||
RenderTilemap(bg->graphics.dest, bg, 0);
|
||||
OpenGL_RenderRGBABuffer(bg->graphics.dest, bg->xTiles * 8, bg->yTiles * 8, bgScrollX, bgScrollY,
|
||||
bgScrollX + bg->targetTilesX * 8, bgScrollY + bg->targetTilesY * 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,6 +466,11 @@ void OpenGL_OnInit()
|
||||
// Enable texturing
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// Enable blending via Alpha Test
|
||||
// TODO: Maybe only do this for sprites?
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_EQUAL, 1.0);
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
|
||||
@@ -109,14 +478,78 @@ void OpenGL_OnInit()
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glGenTextures(2, &sTempTextureHandles[0]);
|
||||
glGenTextures(3, &sTempTextureHandles[0]);
|
||||
|
||||
// TODO: Maybe this shuld be done in the platform layers?
|
||||
CreateChunkSet();
|
||||
}
|
||||
|
||||
void OpenGL_TransformSprite(Sprite *sprite, SpriteTransform *transform)
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
s16 rotation = (transform->rotation & ONE_CYCLE);
|
||||
float rotNormalized = (((float)rotation) / 1024.0f);
|
||||
float theta = -(2.0f * M_PI * rotNormalized);
|
||||
float sinTheta = sinf(theta);
|
||||
float cosTheta = cosf(theta);
|
||||
float modelViewMatrix[] = {
|
||||
#if 01
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0, //
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0, //
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0, //
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1, //
|
||||
#else
|
||||
+cosTheta,
|
||||
+sinTheta,
|
||||
0,
|
||||
0,
|
||||
-sinTheta,
|
||||
+cosTheta,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
#endif
|
||||
};
|
||||
|
||||
// glLoadMatrixf(modelViewMatrix);
|
||||
// glTranslatef(transform->x, transform->y, 0);
|
||||
|
||||
// Debug_PrintMatrix(modelViewMatrix);
|
||||
|
||||
// TODO: This doesn't happen in the original TransformSprite() procedure!
|
||||
SPRITE_FLAG_SET(sprite, ROT_SCALE_ENABLE);
|
||||
}
|
||||
|
||||
void OpenGL_DisplaySprite(Sprite *sprite, u8 oamPaletteNum)
|
||||
{
|
||||
const SpriteOffset *dims = sprite->dimensions;
|
||||
int x = sprite->x;
|
||||
int y = sprite->y;
|
||||
|
||||
if (dims != (void *)-1) {
|
||||
if (!(sprite->oamFlags & SPRITE_FLAG_MASK_ROT_SCALE_ENABLE)) {
|
||||
// glMatrixMode(GL_MODELVIEW);
|
||||
// glLoadIdentity();
|
||||
}
|
||||
// Convert vertices screenspace -> unit space
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
#if 0
|
||||
@@ -124,57 +557,55 @@ void OpenGL_DisplaySprite(Sprite *sprite, u8 oamPaletteNum)
|
||||
#else
|
||||
float a = 2.0f / DISPLAY_WIDTH;
|
||||
float b = 2.0f / DISPLAY_HEIGHT;
|
||||
float projMtx[] = { a, 0, 0, 0, 0, b, 0, 0, 0, 0, 1, 0, -1, -1, 0, 1 };
|
||||
float projMtx[] = { +a, 0, 0, 0, //
|
||||
0, +b, 0, 0, //
|
||||
0, 0, 0, 0, //
|
||||
-1, -1, 0, +1 }; //
|
||||
glLoadMatrixf(projMtx);
|
||||
#endif
|
||||
|
||||
TempConvert4bppToRGBA8_DynTextureBuffer(sprite->graphics.src, dims->width, dims->height, sprite->palId + oamPaletteNum);
|
||||
|
||||
// glGenTextures(1, &sTempTextureHandles[2]);
|
||||
glBindTexture(GL_TEXTURE_2D, sTempTextureHandles[2]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dims->width, dims->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, sDynTextureBuffer.data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // downscale filtering
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // upscale filtering
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
// glClearColor((float)tempRgbaPalette[1][0] / 255.,
|
||||
// (float)tempRgbaPalette[1][1] / 255.,
|
||||
// (float)tempRgbaPalette[1][2] / 255.,
|
||||
// 1.0);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
float minX = sprite->x - (dims->width >> 1);
|
||||
#if 0
|
||||
x -= (sprite->frameFlags & SPRITE_FLAG_MASK_X_FLIP) ? dims->width - dims->offsetX : dims->offsetX;
|
||||
y -= (sprite->frameFlags & SPRITE_FLAG_MASK_Y_FLIP) ? dims->height - dims->offsetY : dims->offsetY;
|
||||
#else
|
||||
x -= dims->offsetX;
|
||||
y -= dims->offsetY;
|
||||
#endif
|
||||
x += (dims->width >> 1);
|
||||
y += (dims->height >> 1);
|
||||
float minX = x - (dims->width >> 1);
|
||||
float maxX = minX + dims->width;
|
||||
|
||||
float minY = sprite->y - (dims->height >> 1);
|
||||
float minY = (DISPLAY_HEIGHT - y) - (dims->height >> 1);
|
||||
float maxY = minY + dims->height;
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
{
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex2f(minX, maxY);
|
||||
glTexCoord2f(1.0, 1.0);
|
||||
glVertex2f(maxX, minY);
|
||||
glTexCoord2f(0.0, 1.0);
|
||||
glVertex2f(minX, minY);
|
||||
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex2f(minX, maxY);
|
||||
glTexCoord2f(1.0, 0.0);
|
||||
glVertex2f(maxX, maxY);
|
||||
glTexCoord2f(1.0, 1.0);
|
||||
glVertex2f(maxX, minY);
|
||||
if (sprite->frameFlags & SPRITE_FLAG_MASK_X_FLIP) {
|
||||
float temp = minX;
|
||||
minX = maxX;
|
||||
maxX = temp;
|
||||
}
|
||||
glEnd();
|
||||
|
||||
if (sprite->frameFlags & SPRITE_FLAG_MASK_Y_FLIP) {
|
||||
float temp = minY;
|
||||
minY = maxY;
|
||||
maxY = temp;
|
||||
}
|
||||
|
||||
OpenGL_RenderRGBABuffer(sDynTextureBuffer.data, dims->width, dims->height, minX, minY, maxX, maxY);
|
||||
}
|
||||
|
||||
// TODO: This doesn't happen in the original DisplaySprite() procedure!
|
||||
SPRITE_FLAG_CLEAR(sprite, ROT_SCALE_ENABLE);
|
||||
}
|
||||
|
||||
void OpenGL_Render(void *tempBufferPixels, int viewportWidth, int viewportHeight)
|
||||
{
|
||||
glViewport(0, 0, viewportWidth, viewportHeight);
|
||||
|
||||
Background **bgQueue = &gBackgroundsCopyQueue[0];
|
||||
// __debugbreak();
|
||||
#if 0
|
||||
// Don't convert input-vertices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
@@ -195,6 +626,7 @@ void OpenGL_Render(void *tempBufferPixels, int viewportWidth, int viewportHeight
|
||||
|
||||
// TempConvertPLTTToRGBA8();
|
||||
|
||||
#if 0
|
||||
// Convert the "software-rendered" image from ABGR1555 -> RGBA8
|
||||
for (int i = 0; i < ARRAY_COUNT(tempRgbaFrame); i++) {
|
||||
u16 color = ((u16 *)tempBufferPixels)[i];
|
||||
@@ -208,6 +640,7 @@ void OpenGL_Render(void *tempBufferPixels, int viewportWidth, int viewportHeight
|
||||
tempRgbaFrame[i][3] = 1 * 255.0;
|
||||
}
|
||||
|
||||
// Update palette
|
||||
glBindTexture(GL_TEXTURE_2D, sTempTextureHandles[0]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempRgbaPalette);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // downscale filtering
|
||||
@@ -215,35 +648,5 @@ void OpenGL_Render(void *tempBufferPixels, int viewportWidth, int viewportHeight
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, sTempTextureHandles[1]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempRgbaFrame);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // downscale filtering
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // upscale filtering
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glClearColor(1.0, 1.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, sTempTextureHandles[1]);
|
||||
glBegin(GL_TRIANGLES);
|
||||
{
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex2f(0.0, +DISPLAY_HEIGHT);
|
||||
glTexCoord2f(1.0, 1.0);
|
||||
glVertex2f(+DISPLAY_WIDTH, 0);
|
||||
glTexCoord2f(0.0, 1.0);
|
||||
glVertex2f(0, 0);
|
||||
|
||||
glTexCoord2f(0.0, 0.0);
|
||||
glVertex2f(0, DISPLAY_HEIGHT);
|
||||
glTexCoord2f(1.0, 0.0);
|
||||
glVertex2f(DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
||||
glTexCoord2f(1.0, 1.0);
|
||||
glVertex2f(DISPLAY_WIDTH, 0);
|
||||
}
|
||||
glEnd();
|
||||
#endif
|
||||
}
|
||||
@@ -123,7 +123,7 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR lpCmdLine,
|
||||
DWORD threadId;
|
||||
|
||||
#if 01
|
||||
REG_KEYINPUT &= ~START_BUTTON;
|
||||
// REG_KEYINPUT &= ~START_BUTTON;
|
||||
while (sRunning) {
|
||||
memset(sImageBuffer, 0, sizeof(sImageBuffer));
|
||||
|
||||
@@ -320,16 +320,26 @@ static void Win32_ProcessPendingMessages(HWND window)
|
||||
// Converts GBA -> Win32 RGB value
|
||||
#define RGB_SHIFT(value) (((value >> 10) & 0x1F) | (value & 0x3E0) | (((value & 0x1F) << 10)))
|
||||
|
||||
void Platform_ProcessBackgroundsCopyQueue(void)
|
||||
{
|
||||
#if (RENDERER == RENDERER_OPENGL)
|
||||
OpenGL_ProcessBackgroundsCopyQueue();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Platform_TransformSprite(Sprite *s, SpriteTransform *transform) { OpenGL_TransformSprite(s, transform); }
|
||||
|
||||
void Platform_DisplaySprite(Sprite *sprite, u8 oamPaletteNum)
|
||||
{
|
||||
if (sprite->graphics.src == NULL)
|
||||
if (sprite->graphics.src == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (RENDERER == RENDERER_OPENGL)
|
||||
// TEMP - Currently the display buffer gets drawn in software, but we should load the assets as a textures and let OpenGL render
|
||||
// everything
|
||||
// OpenGL_DisplaySprite(sprite, oamPaletteNum);
|
||||
// return;
|
||||
// TEMP - Currently the display buffer gets drawn in software, but we should load the assets as a textures and let OpenGL render
|
||||
// everything
|
||||
OpenGL_DisplaySprite(sprite, oamPaletteNum);
|
||||
return;
|
||||
#endif
|
||||
|
||||
const SpriteOffset *dims = sprite->dimensions;
|
||||
@@ -344,6 +354,12 @@ void Platform_DisplaySprite(Sprite *sprite, u8 oamPaletteNum)
|
||||
x = sprite->x;
|
||||
y = sprite->y;
|
||||
|
||||
// Effectively unused, but here for accuracy's sake
|
||||
if (sprite->frameFlags & SPRITE_FLAG_GLOBAL_OFFSET) {
|
||||
x -= gSpriteOffset.x;
|
||||
y -= gSpriteOffset.y;
|
||||
}
|
||||
|
||||
{
|
||||
// TEMP - from sprite.c
|
||||
sprWidth = dims->width;
|
||||
@@ -376,7 +392,7 @@ void Platform_DisplaySprite(Sprite *sprite, u8 oamPaletteNum)
|
||||
u16 widthInTiles = dims->width >> 3;
|
||||
|
||||
for (int frameY = 0; frameY < dims->height; frameY++) {
|
||||
s32 finalY = (tempY + frameY);
|
||||
s32 finalY = (sprite->frameFlags & SPRITE_FLAG_MASK_Y_FLIP) ? (tempY + dims->height - 1 - frameY) : (tempY + frameY);
|
||||
|
||||
if (finalY < 0)
|
||||
continue;
|
||||
@@ -386,7 +402,7 @@ void Platform_DisplaySprite(Sprite *sprite, u8 oamPaletteNum)
|
||||
|
||||
for (int frameX = 0; frameX < dims->width; frameX++) {
|
||||
|
||||
s32 finalX = (tempX + frameX);
|
||||
s32 finalX = (sprite->frameFlags & SPRITE_FLAG_MASK_X_FLIP) ? (tempX + dims->width - 1 - frameX) : (tempX + frameX);
|
||||
|
||||
if (finalX < 0)
|
||||
continue;
|
||||
@@ -446,7 +462,15 @@ void VBlankIntrWait()
|
||||
}
|
||||
|
||||
void *Platform_malloc(size_t numBytes) { return HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, numBytes); }
|
||||
|
||||
void *Platform_realloc(void *ptr, size_t numBytes)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
// HeapReAlloc returns NULL when called with NULL, unlike C std realloc().
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, numBytes);
|
||||
} else {
|
||||
return HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, ptr, numBytes);
|
||||
}
|
||||
}
|
||||
void Platform_free(void *ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
|
||||
|
||||
void Platform_QueueAudio(const u8 *data, u32 numBytes) { }
|
||||
+11
-5
@@ -11,6 +11,7 @@
|
||||
|
||||
#if !PLATFORM_GBA && !PLATFORM_SDL
|
||||
extern void Platform_DisplaySprite(Sprite *sprite, u8 oamPaletteNum);
|
||||
extern void Platform_TransformSprite(Sprite *sprite, SpriteTransform *transform);
|
||||
#endif
|
||||
|
||||
#define ReadInstruction(script, cursor) ((void *)(script) + (cursor * sizeof(s32)))
|
||||
@@ -325,10 +326,11 @@ static AnimCmdResult animCmd_GetPalette(void *cursor, Sprite *s)
|
||||
s32 paletteIndex = cmd->palId;
|
||||
|
||||
if (gFlags & FLAGS_20000) {
|
||||
CopyPalette(&gRefSpriteTables->palettes[paletteIndex * 16], s->palId * 16 + cmd->insertOffset, cmd->numColors);
|
||||
CopyPalette(&gRefSpriteTables->palettes[paletteIndex * PALETTE_LEN_4BPP], s->palId * PALETTE_LEN_4BPP + cmd->insertOffset,
|
||||
cmd->numColors);
|
||||
} else {
|
||||
DmaCopy16(3, &gRefSpriteTables->palettes[paletteIndex * 16], &gObjPalette[s->palId * 16 + cmd->insertOffset],
|
||||
cmd->numColors * 2);
|
||||
DmaCopy16(3, &gRefSpriteTables->palettes[paletteIndex * PALETTE_LEN_4BPP], &GET_PALETTE_COLOR_OBJ(s->palId, cmd->insertOffset),
|
||||
cmd->numColors * sizeof(u16));
|
||||
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
@@ -393,7 +395,10 @@ NONMATCH("asm/non_matching/engine/TransformSprite.inc", void TransformSprite(Spr
|
||||
// sp24 = s
|
||||
UnkSpriteStruct big;
|
||||
const SpriteOffset *dimensions = s->dimensions;
|
||||
|
||||
#if PORTABLE && (RENDERER != RENDERER_SOFTWARE)
|
||||
Platform_TransformSprite(s, transform);
|
||||
return;
|
||||
#endif
|
||||
if (dimensions != (SpriteOffset *)-1) {
|
||||
s16 res;
|
||||
s16 x16, y16;
|
||||
@@ -1059,7 +1064,8 @@ static AnimCmdResult animCmd_GetPalette(void *cursor, Sprite *s)
|
||||
if (!(s->frameFlags & SPRITE_FLAG_MASK_18)) {
|
||||
s32 paletteIndex = cmd->palId;
|
||||
|
||||
DmaCopy32(3, &gRefSpriteTables->palettes[paletteIndex * 16], &gObjPalette[s->palId * 16 + cmd->insertOffset], cmd->numColors * 2);
|
||||
DmaCopy32(3, &gRefSpriteTables->palettes[paletteIndex * PALETTE_LEN_4BPP], &GET_PALETTE_COLOR_OBJ(s->palId, cmd->insertOffset),
|
||||
cmd->numColors * 2);
|
||||
|
||||
gFlags |= FLAGS_UPDATE_SPRITE_PALETTES;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user