mirror of
https://github.com/SAT-R/sa2.git
synced 2026-10-28 09:43:38 +00:00
sa1: reference water_effects from sa2
This commit is contained in:
1 parent
15e38aff6c
commit
67ecd33583
11 files changed
+148
-562
No files matched your search
@@ -4,7 +4,7 @@
|
||||
#include "core.h"
|
||||
#include "game/shared/stage/player.h"
|
||||
|
||||
extern void sub_804C40C(void);
|
||||
extern void InitWaterPalettes(void);
|
||||
|
||||
struct Task *SpawnDrowningCountdownNum(Player *p, s32 countdown);
|
||||
struct Task *SpawnAirBubbles(s32 p0, s32 p1, s32 p2, s32 p3);
|
||||
|
||||
@@ -272,6 +272,7 @@ SA2_C_FILES := \
|
||||
src/game/shared/stage/collision_1.c \
|
||||
src/game/shared/stage/collision_2.c \
|
||||
src/game/shared/stage/collision_3.c \
|
||||
src/game/shared/stage/water_effects.c \
|
||||
src/game/sa1/ui/game_2_0.c \
|
||||
src/game/sa1/ui/game_2_1.c \
|
||||
src/game/sa1/ui/stage_results.c \
|
||||
|
||||
@@ -269,7 +269,7 @@ _08055622:
|
||||
cmp r0, #1
|
||||
bhi _08055672
|
||||
bl LoadPalette423Anim
|
||||
bl sub_804C40C
|
||||
bl InitWaterPalettes
|
||||
_08055672:
|
||||
ldr r0, [r4, #0x20]
|
||||
bl TaskDestroy
|
||||
@@ -332,7 +332,7 @@ _08055708:
|
||||
lsrs r0, r0, #0x18
|
||||
cmp r0, #1
|
||||
bhi _0805571A
|
||||
bl sub_804C40C
|
||||
bl InitWaterPalettes
|
||||
_0805571A:
|
||||
add sp, #4
|
||||
pop {r3, r4, r5}
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ SECTIONS {
|
||||
sa2/src/game/sa1/stage/player_super_sonic.o(.text);
|
||||
sa2/src/game/shared/stage/item_tasks.o(.text);
|
||||
sa2/src/game/shared/stage/underwater_effects.o(.text);
|
||||
src/game/shared/stage/water_effects.o(.text);
|
||||
sa2/src/game/shared/stage/water_effects.o(.text);
|
||||
sa2/src/game/shared/stage/screen_shake.o(.text);
|
||||
|
||||
/* NOTE: input_recorder was not part of the engine in this version */
|
||||
|
||||
Vendored
+1
-1
@@ -898,7 +898,7 @@ thumb_func 0x0804c12c sub_804C12C
|
||||
thumb_func 0x0804c1c0 sub_804C1C0
|
||||
thumb_func 0x0804c2e8 sub_804C2E8
|
||||
thumb_func 0x0804c3cc sub_804C3CC
|
||||
thumb_func 0x0804c40c sub_804C40C
|
||||
thumb_func 0x0804c40c InitWaterPalettes
|
||||
thumb_func 0x0804c598 sub_804C598
|
||||
thumb_func 0x0804c5d8 sub_804C5D8
|
||||
thumb_func 0x0804c668 sub_804C668
|
||||
|
||||
@@ -1,501 +0,0 @@
|
||||
#include "global.h"
|
||||
#include "core.h"
|
||||
#include "flags.h"
|
||||
#include "malloc_vram.h"
|
||||
#include "task.h"
|
||||
#include "trig.h"
|
||||
#include "bg_triangles.h"
|
||||
|
||||
#if (GAME == GAME_SA2)
|
||||
#include "game/boost_effect.h"
|
||||
#endif
|
||||
#include "game/globals.h"
|
||||
#include "game/shared/stage/player.h"
|
||||
#include "game/shared/stage/camera.h"
|
||||
#include "game/shared/stage/mp_sprite_task.h"
|
||||
#include "data/sa1/sprite_data.h"
|
||||
#include "game/shared/stage/water_effects.h"
|
||||
|
||||
#include "constants/sa1/animations.h"
|
||||
#include "constants/sa1/zones.h"
|
||||
#include "constants/sa1/vram_hardcoded.h"
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 x;
|
||||
/* 0x04 */ s32 y;
|
||||
/* 0x08 */ u8 filler0[0x14];
|
||||
/* 0x1C */ Sprite s;
|
||||
/* 0x4C */ u8 filler4C[0xC];
|
||||
} RunOnWaterEffect; /* size: 0x58 */
|
||||
|
||||
// TODO: Make static again
|
||||
void Task_StageWaterTask(void);
|
||||
static void Task_RunOnWaterEffect(void);
|
||||
void TaskDestructor_WaterSurface(struct Task *);
|
||||
void SA2_LABEL(sub_8011A4C)(void);
|
||||
void SA2_LABEL(VCountIntr_8011ACC)(void);
|
||||
static void TaskDestructor_RunOnWaterEffect(struct Task *);
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
// SA2 allocates these in the Task, to save global memory.
|
||||
// Water is only used in one stage, after all.
|
||||
u16 sPaletteBuffer[(16 * 2) * 16] = { 0 };
|
||||
#endif
|
||||
Water gWater = { 0 };
|
||||
|
||||
#define WATER_MASK_COLOR_A 0x7BDE
|
||||
#define WATER_MASK_COLOR_B 0x739C
|
||||
#define WATER_MASK_A ((WATER_MASK_COLOR_A << 16) | WATER_MASK_COLOR_A)
|
||||
#define WATER_MASK_B ((WATER_MASK_COLOR_B << 16) | WATER_MASK_COLOR_B)
|
||||
|
||||
#define WATER_SURFACE_SPRITE_COUNT ((DISPLAY_WIDTH + 16) / 16)
|
||||
|
||||
#define WATER_MASK_PALETTE_CHUNK(in, waterMask) \
|
||||
({ \
|
||||
u32 temp1, temp2; \
|
||||
temp1 = (in); \
|
||||
temp2 = temp1; \
|
||||
temp2 = ((temp2 & WATER_MASK_A) + (((temp1 & WATER_MASK_B) + (WATER_MASK_B & (waterMask))) >> 1)); \
|
||||
temp2 >>= 1; \
|
||||
})
|
||||
|
||||
#if (GAME == GAME_SA2)
|
||||
static const u16 gUnknown_080D550C[NUM_CHARACTERS] = {
|
||||
SA2_ANIM_UNDERWATER_1UP_SONIC, SA2_ANIM_UNDERWATER_1UP_CREAM, SA2_ANIM_UNDERWATER_1UP_TAILS,
|
||||
SA2_ANIM_UNDERWATER_1UP_KNUCKLES, SA2_ANIM_UNDERWATER_1UP_AMY,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if (GAME == GAME_SA2)
|
||||
static void inline CopyPalette(u32 *dst, u32 *src, s32 length)
|
||||
{
|
||||
u32 r2 = length >> 4;
|
||||
|
||||
while (r2-- > 0) {
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void MaskPaletteWithUnderwaterColor_inline(u32 *dst, u32 *src, u32 mask, s32 size)
|
||||
{
|
||||
u32 k = (size >> 4);
|
||||
while (k-- > 0) {
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
}
|
||||
}
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
void sub_804C40C(void)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)&sPaletteBuffer[0], (u32 *)&gObjPalette[0], water->mask, 16 * 16);
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)&sPaletteBuffer[16 * 16], (u32 *)&gBgPalette[0], water->mask, 16 * 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (GAME == GAME_SA2)
|
||||
void InitWaterPalettes(void)
|
||||
{
|
||||
u16 animId, character;
|
||||
const ACmd **animation;
|
||||
u32 pal;
|
||||
|
||||
Water *water = &gWater;
|
||||
WaterData *wd = TASK_DATA(water->t);
|
||||
|
||||
if (IS_MULTI_PLAYER) {
|
||||
u8 i = 0, j = 0;
|
||||
for (; j < 4; j++) {
|
||||
if ((gMultiplayerConnections >> j) & 0x1) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
character = gMultiplayerCharacters[j];
|
||||
animId = gUnknown_080D550C[character];
|
||||
animation = gAnimations[animId];
|
||||
pal = animation[0]->pal.palId;
|
||||
#ifndef NON_MATCHING
|
||||
{
|
||||
const u16 *src = gSpritePalettes[pal];
|
||||
CopyPalette((u32 *)wd->pal[j], (u32 *)src, 16);
|
||||
};
|
||||
#else
|
||||
CopyPalette((u32 *)wd->pal[j], (u32 *)gSpritePalettes[pal], 16);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
character = gPlayer.character;
|
||||
|
||||
animId = gUnknown_080D550C[character];
|
||||
animation = gAnimations[animId];
|
||||
pal = animation[0]->pal.palId;
|
||||
CopyPalette((u32 *)wd->pal[0], (u32 *)gSpritePalettes[pal], 16);
|
||||
|
||||
character = gPlayer.character;
|
||||
animId = sCharacterPalettesBoostEffect[character];
|
||||
animation = gAnimations[animId];
|
||||
pal = animation[0]->pal.palId;
|
||||
CopyPalette((u32 *)wd->pal[1], (u32 *)gSpritePalettes[pal], 16);
|
||||
}
|
||||
|
||||
animId = SA2_ANIM_PALETTE_554;
|
||||
animation = gAnimations[animId];
|
||||
pal = (animation[0]->pal.palId + 4);
|
||||
CopyPalette((u32 *)wd->pal[4], (u32 *)gSpritePalettes[pal], 12 * 16);
|
||||
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)wd->pal[16], (u32 *)gBgPalette, water->mask, 16 * 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
void LoadPalette423Anim(void)
|
||||
{
|
||||
Sprite s;
|
||||
s.graphics.dest = NULL;
|
||||
s.graphics.anim = SA1_ANIM_LOAD_PALETTE_423;
|
||||
s.variant = 0;
|
||||
s.oamFlags = 0;
|
||||
s.frameFlags = 0;
|
||||
s.graphics.size = 0;
|
||||
s.prevVariant = -1;
|
||||
s.qAnimDelay = Q(0);
|
||||
s.animSpeed = SPRITE_ANIM_SPEED(1.0);
|
||||
s.palId = 0;
|
||||
|
||||
UpdateSpriteAnimation(&s);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CreateStageWaterTask(s32 waterLevel, u32 p1, u32 mask)
|
||||
{
|
||||
gWater.currentWaterLevel = waterLevel;
|
||||
gWater.targetWaterLevel = waterLevel;
|
||||
gWater.SA2_LABEL(unk2) = 0xFF;
|
||||
gWater.SA2_LABEL(unk1) = -1;
|
||||
gWater.unk8 = mask & 0x100;
|
||||
gWater.mask = p1;
|
||||
|
||||
if (waterLevel >= 0) {
|
||||
Sprite *s = &gWater.s;
|
||||
s->graphics.dest = VRAM_RESERVED_WATER_SURFACE;
|
||||
s->graphics.size = 0;
|
||||
s->graphics.anim = SA1_ANIM_WATER_SURFACE;
|
||||
s->variant = 0;
|
||||
s->prevVariant |= -1;
|
||||
s->oamFlags = SPRITE_OAM_ORDER(0);
|
||||
s->qAnimDelay = 0;
|
||||
s->animSpeed = SPRITE_ANIM_SPEED(1.0);
|
||||
s->palId = 0;
|
||||
s->frameFlags = SPRITE_FLAG(PRIORITY, 0);
|
||||
UpdateSpriteAnimation(s);
|
||||
|
||||
gWater.t = TaskCreate(Task_StageWaterTask, sizeof(WaterData), 0xFFFE, 0, TaskDestructor_WaterSurface);
|
||||
}
|
||||
}
|
||||
|
||||
void Task_StageWaterTask(void)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
struct Camera *cam = &gCamera;
|
||||
bool32 active;
|
||||
Sprite *s;
|
||||
|
||||
#if (HAS_RUN_ON_WATER)
|
||||
if ((gCurrentLevel == LEVEL_INDEX(ZONE_1, ACT_1)) && (I(gPlayer.qWorldX) > 6665) && (I(gPlayer.qWorldX) <= 10650)) {
|
||||
water->isActive = TRUE;
|
||||
} else {
|
||||
water->isActive = FALSE;
|
||||
}
|
||||
|
||||
if (water->isActive != TRUE) {
|
||||
gFlags &= ~MOVESTATE_IN_WATER;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gStageTime & 1) {
|
||||
if (water->currentWaterLevel != water->targetWaterLevel) {
|
||||
if (water->currentWaterLevel < water->targetWaterLevel)
|
||||
water->currentWaterLevel++;
|
||||
else if (water->currentWaterLevel > water->targetWaterLevel)
|
||||
water->currentWaterLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
if (water->currentWaterLevel <= cam->y) {
|
||||
water->SA2_LABEL(unk2) = 0;
|
||||
} else if (water->currentWaterLevel < cam->y + DISPLAY_HEIGHT) {
|
||||
water->SA2_LABEL(unk2) = water->currentWaterLevel - cam->y;
|
||||
} else {
|
||||
water->SA2_LABEL(unk2) = 0xFF;
|
||||
}
|
||||
|
||||
gVBlankCallbacks[gNumVBlankCallbacks++] = SA2_LABEL(sub_8011A4C);
|
||||
gFlags |= FLAGS_EXECUTE_VBLANK_CALLBACKS;
|
||||
|
||||
if (water->SA2_LABEL(unk1) > 0 && water->SA2_LABEL(unk1) < DISPLAY_HEIGHT) {
|
||||
s = &water->s;
|
||||
s->x = -((cam->x + ((gStageTime + 1) >> 2)) & 15);
|
||||
s->y = water->SA2_LABEL(unk2) + 1;
|
||||
s->frameFlags |= (SPRITE_FLAG_MASK_19 | SPRITE_FLAG_MASK_18);
|
||||
UpdateSpriteAnimation(s);
|
||||
|
||||
if (gStageTime & 0x2) {
|
||||
u16 y = s->y - 1;
|
||||
if (y < DISPLAY_WIDTH - 1) {
|
||||
s32 count = WATER_SURFACE_SPRITE_COUNT;
|
||||
do {
|
||||
DisplaySprite(s);
|
||||
s->x += 16;
|
||||
} while (--count >= 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (water->SA2_LABEL(unk2) > 0 && water->SA2_LABEL(unk2) < DISPLAY_HEIGHT) {
|
||||
gIntrTable[INTR_INDEX_VCOUNT] = SA2_LABEL(VCountIntr_8011ACC);
|
||||
gVCountSetting = water->SA2_LABEL(unk2) - 1;
|
||||
gFlags |= FLAGS_40;
|
||||
} else {
|
||||
gIntrTable[INTR_INDEX_VCOUNT] = gIntrTableTemplate[INTR_INDEX_VCOUNT];
|
||||
gFlags &= ~FLAGS_40;
|
||||
}
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
if (water->SA2_LABEL(unk2) >= DISPLAY_HEIGHT) {
|
||||
gFlags &= ~FLAGS_EXECUTE_HBLANK_COPY;
|
||||
} else {
|
||||
#ifndef NON_MATCHING
|
||||
UNUSED u32 _;
|
||||
#endif
|
||||
u32 r5, i;
|
||||
s32 r3 = CLAMP_SIN_PERIOD(((gStageTime * 4) + (((gBgScrollRegs[3][1] + water->SA2_LABEL(unk2)) % 32u) << 6)));
|
||||
|
||||
SA2_LABEL(sub_8007738)
|
||||
(3, 0, 32, r3, 2, 64, (((gStageTime * 2 + (((gBgScrollRegs[3][1] + water->SA2_LABEL(unk2)) % 32u) << 5))) + 0x100) & ONE_CYCLE, 10,
|
||||
32, gBgScrollRegs[3][0], gBgScrollRegs[3][1]);
|
||||
|
||||
for (r5 = 32, i = 1; r5 < DISPLAY_HEIGHT; i++, r5 += 32) {
|
||||
DmaCopy32(3, gBgOffsetsHBlankPrimary, gBgOffsetsHBlankPrimary + ((gHBlankCopySize << 5) * i), (gHBlankCopySize << 5));
|
||||
}
|
||||
|
||||
if (water->SA2_LABEL(unk2)) {
|
||||
gFlags &= ~FLAGS_EXECUTE_HBLANK_COPY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (HAS_RUN_ON_WATER)
|
||||
void CreateRunOnWaterEffect(void)
|
||||
{
|
||||
struct Task *t = TaskCreate(Task_RunOnWaterEffect, sizeof(RunOnWaterEffect), 0x4001, 0, TaskDestructor_RunOnWaterEffect);
|
||||
RunOnWaterEffect *effect = TASK_DATA(t);
|
||||
Sprite *s = &effect->s;
|
||||
s->graphics.dest = VramMalloc(12);
|
||||
s->graphics.size = 0;
|
||||
s->graphics.anim = SA2_ANIM_WATER_RUNNING_PARTICLES;
|
||||
s->variant = 0;
|
||||
s->prevVariant = -1;
|
||||
s->oamFlags = SPRITE_OAM_ORDER(7);
|
||||
s->qAnimDelay = 0;
|
||||
s->animSpeed = SPRITE_ANIM_SPEED(1.0);
|
||||
s->palId = 0;
|
||||
s->frameFlags = SPRITE_FLAG(PRIORITY, 2);
|
||||
}
|
||||
|
||||
static void Task_RunOnWaterEffect(void)
|
||||
{
|
||||
RunOnWaterEffect *effect = TASK_DATA(gCurTask);
|
||||
Sprite *s = &effect->s;
|
||||
Player *p = &gPlayer;
|
||||
u32 newMovestate;
|
||||
|
||||
if ((p->moveState & (MOVESTATE_20000 | MOVESTATE_DEAD)) != MOVESTATE_20000) {
|
||||
TaskDestroy(gCurTask);
|
||||
return;
|
||||
}
|
||||
|
||||
effect->x = I(p->qWorldX);
|
||||
effect->y = gWater.currentWaterLevel;
|
||||
|
||||
s->x = effect->x - gCamera.x;
|
||||
s->y = effect->y - gCamera.y;
|
||||
|
||||
if (!(p->moveState & MOVESTATE_FACING_LEFT)) {
|
||||
s->frameFlags &= ~SPRITE_FLAG_MASK_X_FLIP;
|
||||
} else {
|
||||
s->frameFlags |= SPRITE_FLAG_MASK_X_FLIP;
|
||||
}
|
||||
|
||||
UpdateSpriteAnimation(s);
|
||||
DisplaySprite(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
void unused_DestroygWaterTask(void)
|
||||
{
|
||||
TaskDestroy(gWater.t);
|
||||
gWater.t = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Task *CreateWaterfallSurfaceHitEffect(s32 x, s32 y)
|
||||
{
|
||||
struct Task *t = CreateMultiplayerSpriteTask(x, y, 0x10, 0, Task_UpdateMpSpriteTaskSprite, TaskDestructor_MultiplayerSpriteTask);
|
||||
MultiplayerSpriteTask *ts = TASK_DATA(t);
|
||||
Sprite *s = &ts->s;
|
||||
|
||||
s->graphics.dest = VramMalloc(12);
|
||||
s->graphics.anim = SA1_ANIM_WATER_FALL_HIT_SURFACE;
|
||||
s->variant = 0;
|
||||
s->oamFlags = SPRITE_OAM_ORDER(7);
|
||||
s->frameFlags = SPRITE_FLAG(PRIORITY, 2);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// At the bottom of the file in SA1!
|
||||
#if (GAME == GAME_SA2)
|
||||
UNUSED void MaskPaletteWithUnderwaterColor(u32 *dst, u32 *src, u32 mask, s32 size)
|
||||
{
|
||||
#ifndef NON_MATCHING
|
||||
u32 k = (size >> 4);
|
||||
while (k-- > 0) {
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
}
|
||||
#else
|
||||
MaskPaletteWithUnderwaterColor_inline(dst, src, mask, size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void TaskDestructor_WaterSurface(struct Task *t)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
|
||||
gFlags &= ~FLAGS_40;
|
||||
gIntrTable[INTR_INDEX_VCOUNT] = gIntrTableTemplate[INTR_INDEX_VCOUNT];
|
||||
water->t = NULL;
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
DmaFill32(3, 0, sPaletteBuffer, 60 * 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SA2_LABEL(sub_8011A4C)(void)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
#ifdef BUG_FIX
|
||||
if (water->t)
|
||||
#endif
|
||||
{
|
||||
#if (GAME == GAME_SA1)
|
||||
WaterData *wd = TASK_DATA(water->t);
|
||||
#endif
|
||||
u32 unk2;
|
||||
unk2 = water->SA2_LABEL(unk2);
|
||||
water->SA2_LABEL(unk1) = unk2;
|
||||
water->unk8 &= ~0x1;
|
||||
|
||||
// TODO: This surely can be matched differently!
|
||||
unk2 <<= 24;
|
||||
|
||||
if (!unk2) {
|
||||
#if (GAME == GAME_SA1)
|
||||
DmaCopy32(3, &sPaletteBuffer[16 * 16], BG_PLTT, 29 * 16);
|
||||
DmaCopy32(3, &sPaletteBuffer, OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#elif (GAME == GAME_SA2)
|
||||
DmaCopy32(3, &wd->pal[16], PLTT, 29 * 16);
|
||||
DmaCopy32(3, &wd->pal[0], OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#endif
|
||||
REG_DISPCNT &= ~DISPCNT_BG0_ON;
|
||||
gFlags |= (FLAGS_UPDATE_SPRITE_PALETTES | FLAGS_UPDATE_BACKGROUND_PALETTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SA2_LABEL(VCountIntr_8011ACC)(void)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
#ifdef BUG_FIX
|
||||
if (water->t)
|
||||
#endif
|
||||
{
|
||||
#if (GAME == GAME_SA1)
|
||||
DmaCopy32(0, &sPaletteBuffer[16 * 16], BG_PLTT, 29 * 16);
|
||||
DmaCopy32(0, &sPaletteBuffer, OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#elif (GAME == GAME_SA2)
|
||||
WaterData *wd = TASK_DATA(water->t);
|
||||
|
||||
DmaCopy32(3, &wd->pal[16], PLTT, 29 * 16);
|
||||
DmaCopy32(3, &wd->pal[0], OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#endif
|
||||
|
||||
REG_DISPCNT &= ~DISPCNT_BG0_ON;
|
||||
gFlags |= (FLAGS_UPDATE_SPRITE_PALETTES | FLAGS_UPDATE_BACKGROUND_PALETTES);
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
{
|
||||
DmaSet(0, gBgOffsetsHBlankSecondary, (void *)®_BG3HOFS, //
|
||||
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | (gHBlankCopySize >> 1));
|
||||
}
|
||||
#endif
|
||||
REG_IF = INTR_FLAG_VCOUNT;
|
||||
}
|
||||
}
|
||||
|
||||
// Further up in SA2!
|
||||
#if (GAME == GAME_SA1)
|
||||
UNUSED void MaskPaletteWithUnderwaterColor(u32 *dst, u32 *src, u32 mask, s32 size)
|
||||
{
|
||||
u32 k = (size >> 4);
|
||||
while (k-- > 0) {
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HAS_RUN_ON_WATER)
|
||||
static void TaskDestructor_RunOnWaterEffect(struct Task *t)
|
||||
{
|
||||
RunOnWaterEffect *effect = TASK_DATA(t);
|
||||
Sprite *s = &effect->s;
|
||||
VramFree(s->graphics.dest);
|
||||
}
|
||||
|
||||
static void SA2_LABEL(sub_8011B54)(u32 *dst, u32 *src, s32 size) { CopyPalette(dst, src, size); }
|
||||
#endif
|
||||
+1
-1
@@ -66,7 +66,7 @@ sa2/src/game/sa1/stage/player_super_sonic.o(.data);
|
||||
sa2/src/game/shared/stage/underwater_effects.o(.data);
|
||||
|
||||
. = 0x00005C80;
|
||||
src/game/shared/stage/water_effects.o(.data);
|
||||
sa2/src/game/shared/stage/water_effects.o(.data);
|
||||
|
||||
. = 0x000060D0;
|
||||
sa2/src/input_recorder.o(.data);
|
||||
|
||||
@@ -185,7 +185,7 @@ void CreateEntity_EggSpider(MapEntity *me, u16 regionX, u16 regionY, u8 id)
|
||||
}
|
||||
|
||||
t = TaskCreate(Task_EggSpiderInit, sizeof(EggSpider), 0x2000U, 0U, TaskDestructor_8031CB4);
|
||||
TaskCreate(sub_804C40C, 0U, 0xFFFDU, 0U, NULL);
|
||||
TaskCreate(InitWaterPalettes, 0U, 0xFFFDU, 0U, NULL);
|
||||
|
||||
boss = TASK_DATA(t);
|
||||
s = &boss->s;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "constants/sa1/vram_hardcoded.h"
|
||||
#include "constants/sa1/zones.h"
|
||||
|
||||
extern void sub_804C40C(void); // TODO: Move to correct Header!
|
||||
extern void InitWaterPalettes(void); // TODO: Move to correct Header!
|
||||
|
||||
void StageUI_DrawTimer(u32 courseTime);
|
||||
void sub_8053BAC(void);
|
||||
|
||||
@@ -537,7 +537,7 @@ NONMATCH("asm/non_matching/game/sa1/stage/stage_ui__Task_8055458.inc", void Task
|
||||
|
||||
if (gCurrentLevel == LEVEL_INDEX(ZONE_4, ACT_1) || gCurrentLevel == LEVEL_INDEX(ZONE_4, ACT_2)) {
|
||||
LoadPalette423Anim();
|
||||
sub_804C40C();
|
||||
InitWaterPalettes();
|
||||
}
|
||||
|
||||
TaskDestroy(strcMain->task20);
|
||||
@@ -559,7 +559,7 @@ NONMATCH("asm/non_matching/game/sa1/stage/stage_ui__Task_8055458.inc", void Task
|
||||
}
|
||||
} else if (gCurrentLevel == LEVEL_INDEX(ZONE_4, ACT_1) || gCurrentLevel == LEVEL_INDEX(ZONE_4, ACT_2)) {
|
||||
//_08055708
|
||||
sub_804C40C();
|
||||
InitWaterPalettes();
|
||||
}
|
||||
}
|
||||
END_NONMATCH
|
||||
|
||||
@@ -4,16 +4,32 @@
|
||||
#include "malloc_vram.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
#include "trig.h"
|
||||
#include "bg_triangles.h"
|
||||
#endif
|
||||
|
||||
#include "game/globals.h"
|
||||
#include "game/sa2/stage/boost_effect.h"
|
||||
#include "game/shared/stage/player.h"
|
||||
#include "game/shared/stage/camera.h"
|
||||
#include "game/shared/stage/mp_sprite_task.h"
|
||||
#include "data/sa2/sprite_data.h"
|
||||
#include "game/shared/stage/water_effects.h"
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
#include "data/sa1/sprite_data.h"
|
||||
|
||||
#include "constants/sa1/animations.h"
|
||||
#include "constants/sa1/zones.h"
|
||||
#include "constants/sa1/vram_hardcoded.h"
|
||||
#elif (GAME == GAME_SA2)
|
||||
#include "game/sa2/stage/boost_effect.h"
|
||||
|
||||
#include "data/sa2/sprite_data.h"
|
||||
|
||||
#include "constants/sa2/animations.h"
|
||||
#include "constants/sa2/zones.h"
|
||||
#include "constants/sa2/vram_hardcoded.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 x;
|
||||
@@ -26,10 +42,15 @@ typedef struct {
|
||||
static void Task_StageWaterTask(void);
|
||||
static void Task_RunOnWaterEffect(void);
|
||||
static void TaskDestructor_WaterSurface(struct Task *);
|
||||
static void sub_8011A4C(void);
|
||||
static void VCountIntr_8011ACC(void);
|
||||
static void TaskDestructor_8011B3C(struct Task *);
|
||||
static void SA2_LABEL(sub_8011A4C)(void);
|
||||
static void SA2_LABEL(VCountIntr_8011ACC)(void);
|
||||
static void TaskDestructor_RunOnWaterEffect(struct Task *);
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
// SA2 allocates these in the Task, to save global memory.
|
||||
// Water is only used in one stage, after all.
|
||||
u16 sPaletteBuffer[(16 * 2) * 16] = { 0 };
|
||||
#endif
|
||||
Water gWater = {};
|
||||
|
||||
#define WATER_MASK_COLOR_A 0x7BDE
|
||||
@@ -48,6 +69,7 @@ Water gWater = {};
|
||||
temp2 >>= 1; \
|
||||
})
|
||||
|
||||
#if (GAME == GAME_SA2)
|
||||
static const u16 gUnknown_080D550C[NUM_CHARACTERS] = {
|
||||
SA2_ANIM_UNDERWATER_1UP_SONIC, SA2_ANIM_UNDERWATER_1UP_CREAM, SA2_ANIM_UNDERWATER_1UP_TAILS,
|
||||
SA2_ANIM_UNDERWATER_1UP_KNUCKLES, SA2_ANIM_UNDERWATER_1UP_AMY,
|
||||
@@ -68,6 +90,7 @@ static void inline CopyPalette(u32 *dst, u32 *src, s32 length)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void MaskPaletteWithUnderwaterColor_inline(u32 *dst, u32 *src, u32 mask, s32 size)
|
||||
{
|
||||
@@ -84,17 +107,6 @@ static inline void MaskPaletteWithUnderwaterColor_inline(u32 *dst, u32 *src, u32
|
||||
}
|
||||
}
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
void sub_804C40C(void)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)&sPaletteBuffer[0], (u32 *)&gObjPalette[0], water->mask, 16 * 16);
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)&sPaletteBuffer[16 * 16], (u32 *)&gBgPalette[0], water->mask, 16 * 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (GAME == GAME_SA2)
|
||||
void InitWaterPalettes(void)
|
||||
{
|
||||
u16 animId, character;
|
||||
@@ -103,7 +115,10 @@ void InitWaterPalettes(void)
|
||||
|
||||
Water *water = &gWater;
|
||||
WaterData *wd = TASK_DATA(water->t);
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)&sPaletteBuffer[0], (u32 *)&gObjPalette[0], water->mask, 16 * 16);
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)&sPaletteBuffer[16 * 16], (u32 *)&gBgPalette[0], water->mask, 16 * 16);
|
||||
#elif (GAME == GAME_SA2)
|
||||
if (IS_MULTI_PLAYER) {
|
||||
u8 i = 0, j = 0;
|
||||
for (; j < 4; j++) {
|
||||
@@ -146,9 +161,9 @@ void InitWaterPalettes(void)
|
||||
pal = (animation[0]->pal.palId + 4);
|
||||
CopyPalette((u32 *)wd->pal[4], (u32 *)gSpritePalettes[pal], 12 * PALETTE_LEN_4BPP);
|
||||
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)wd->pal[16], (u32 *)&GET_PALETTE_COLOR_BG(0, 0), water->mask, 16 * PALETTE_LEN_4BPP);
|
||||
}
|
||||
MaskPaletteWithUnderwaterColor_inline((u32 *)wd->pal[16], (u32 *)gBgPalette, water->mask, 16 * 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
void LoadPalette423Anim(void)
|
||||
@@ -180,9 +195,13 @@ void CreateStageWaterTask(s32 waterLevel, u32 p1, u32 mask)
|
||||
|
||||
if (waterLevel >= 0) {
|
||||
Sprite *s = &gWater.s;
|
||||
s->graphics.dest = (void *)(OBJ_VRAM0 + 0x2980);
|
||||
s->graphics.dest = VRAM_RESERVED_WATER_SURFACE;
|
||||
s->graphics.size = 0;
|
||||
#if (GAME == GAME_SA1)
|
||||
s->graphics.anim = SA1_ANIM_WATER_SURFACE;
|
||||
#elif (GAME == GAME_SA2)
|
||||
s->graphics.anim = SA2_ANIM_WATER_SURFACE;
|
||||
#endif
|
||||
s->variant = 0;
|
||||
s->prevVariant |= -1;
|
||||
s->oamFlags = SPRITE_OAM_ORDER(0);
|
||||
@@ -202,15 +221,8 @@ static void Task_StageWaterTask(void)
|
||||
struct Camera *cam = &gCamera;
|
||||
bool32 active;
|
||||
Sprite *s;
|
||||
u8 unk1;
|
||||
#ifndef NON_MATCHING
|
||||
register u8 unk2_0 asm("r0");
|
||||
register u8 unk2_2 asm("r2");
|
||||
#else
|
||||
u8 unk2_0;
|
||||
u8 unk2_2;
|
||||
#endif
|
||||
|
||||
#if (HAS_RUN_ON_WATER)
|
||||
if ((gCurrentLevel == LEVEL_INDEX(ZONE_1, ACT_1)) && (I(gPlayer.qWorldX) > 6665) && (I(gPlayer.qWorldX) <= 10650)) {
|
||||
water->isActive = TRUE;
|
||||
} else {
|
||||
@@ -221,6 +233,7 @@ static void Task_StageWaterTask(void)
|
||||
gFlags &= ~MOVESTATE_IN_WATER;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gStageTime & 1) {
|
||||
if (water->currentWaterLevel != water->targetWaterLevel) {
|
||||
@@ -232,27 +245,25 @@ static void Task_StageWaterTask(void)
|
||||
}
|
||||
|
||||
if (water->currentWaterLevel <= cam->y) {
|
||||
water->unk2 = 0;
|
||||
water->SA2_LABEL(unk2) = 0;
|
||||
} else if (water->currentWaterLevel < cam->y + DISPLAY_HEIGHT) {
|
||||
water->unk2 = water->currentWaterLevel - cam->y;
|
||||
water->SA2_LABEL(unk2) = water->currentWaterLevel - cam->y;
|
||||
} else {
|
||||
water->unk2 = 0xFF;
|
||||
water->SA2_LABEL(unk2) = -1;
|
||||
}
|
||||
|
||||
gVBlankCallbacks[gNumVBlankCallbacks++] = sub_8011A4C;
|
||||
gVBlankCallbacks[gNumVBlankCallbacks++] = SA2_LABEL(sub_8011A4C);
|
||||
gFlags |= FLAGS_EXECUTE_VBLANK_CALLBACKS;
|
||||
|
||||
unk1 = water->unk1 - 1;
|
||||
if (unk1 < DISPLAY_HEIGHT - 1) {
|
||||
if (water->SA2_LABEL(unk1) > 0 && water->SA2_LABEL(unk1) < DISPLAY_HEIGHT) {
|
||||
s = &water->s;
|
||||
s->x = -((cam->x + ((gStageTime + 1) >> 2)) & 15);
|
||||
s->y = water->unk2 + 1;
|
||||
s->y = water->SA2_LABEL(unk2) + 1;
|
||||
s->frameFlags |= (SPRITE_FLAG_MASK_19 | SPRITE_FLAG_MASK_18);
|
||||
UpdateSpriteAnimation(s);
|
||||
|
||||
if (gStageTime & 0x2) {
|
||||
u16 y = s->y - 1;
|
||||
if (y < DISPLAY_WIDTH - 1) {
|
||||
if (gStageTime & 2) {
|
||||
if (s->y > 0 && s->y < DISPLAY_WIDTH) {
|
||||
s32 count = WATER_SURFACE_SPRITE_COUNT;
|
||||
do {
|
||||
DisplaySprite(s);
|
||||
@@ -262,20 +273,44 @@ static void Task_StageWaterTask(void)
|
||||
}
|
||||
}
|
||||
|
||||
unk2_0 = (water->unk2);
|
||||
if ((unk2_2 = unk2_0 - 1) < DISPLAY_HEIGHT - 1) {
|
||||
gIntrTable[INTR_INDEX_VCOUNT] = VCountIntr_8011ACC;
|
||||
gVCountSetting = unk2_2;
|
||||
if (water->SA2_LABEL(unk2) > 0 && water->SA2_LABEL(unk2) < DISPLAY_HEIGHT) {
|
||||
gIntrTable[INTR_INDEX_VCOUNT] = SA2_LABEL(VCountIntr_8011ACC);
|
||||
gVCountSetting = water->SA2_LABEL(unk2) - 1;
|
||||
gFlags |= FLAGS_40;
|
||||
} else {
|
||||
gIntrTable[INTR_INDEX_VCOUNT] = gIntrTableTemplate[INTR_INDEX_VCOUNT];
|
||||
gFlags &= ~FLAGS_40;
|
||||
}
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
if (water->SA2_LABEL(unk2) >= DISPLAY_HEIGHT) {
|
||||
gFlags &= ~FLAGS_EXECUTE_HBLANK_COPY;
|
||||
} else {
|
||||
#ifndef NON_MATCHING
|
||||
UNUSED u32 _;
|
||||
#endif
|
||||
u32 r5, i;
|
||||
s32 r3 = CLAMP_SIN_PERIOD(((gStageTime * 4) + (((gBgScrollRegs[3][1] + water->SA2_LABEL(unk2)) % 32u) << 6)));
|
||||
|
||||
SA2_LABEL(sub_8007738)
|
||||
(3, 0, 32, r3, 2, 64, (((gStageTime * 2 + (((gBgScrollRegs[3][1] + water->SA2_LABEL(unk2)) % 32u) << 5))) + 0x100) & ONE_CYCLE, 10,
|
||||
32, gBgScrollRegs[3][0], gBgScrollRegs[3][1]);
|
||||
|
||||
for (r5 = 32, i = 1; r5 < DISPLAY_HEIGHT; i++, r5 += 32) {
|
||||
DmaCopy32(3, gBgOffsetsHBlankPrimary, gBgOffsetsHBlankPrimary + ((gHBlankCopySize << 5) * i), (gHBlankCopySize << 5));
|
||||
}
|
||||
|
||||
if (water->SA2_LABEL(unk2)) {
|
||||
gFlags &= ~FLAGS_EXECUTE_HBLANK_COPY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (HAS_RUN_ON_WATER)
|
||||
void CreateRunOnWaterEffect(void)
|
||||
{
|
||||
struct Task *t = TaskCreate(Task_RunOnWaterEffect, sizeof(RunOnWaterEffect), 0x4001, 0, TaskDestructor_8011B3C);
|
||||
struct Task *t = TaskCreate(Task_RunOnWaterEffect, sizeof(RunOnWaterEffect), 0x4001, 0, TaskDestructor_RunOnWaterEffect);
|
||||
RunOnWaterEffect *effect = TASK_DATA(t);
|
||||
Sprite *s = &effect->s;
|
||||
s->graphics.dest = VramMalloc(12);
|
||||
@@ -317,6 +352,15 @@ static void Task_RunOnWaterEffect(void)
|
||||
UpdateSpriteAnimation(s);
|
||||
DisplaySprite(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
void unused_DestroygWaterTask(void)
|
||||
{
|
||||
TaskDestroy(gWater.t);
|
||||
gWater.t = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Task *CreateWaterfallSurfaceHitEffect(s32 x, s32 y)
|
||||
{
|
||||
@@ -325,7 +369,11 @@ struct Task *CreateWaterfallSurfaceHitEffect(s32 x, s32 y)
|
||||
Sprite *s = &ts->s;
|
||||
|
||||
s->graphics.dest = VramMalloc(12);
|
||||
#if (GAME == GAME_SA1)
|
||||
s->graphics.anim = SA1_ANIM_WATER_FALL_HIT_SURFACE;
|
||||
#elif (GAME == GAME_SA2)
|
||||
s->graphics.anim = SA2_ANIM_WATER_FALL_HIT_SURFACE;
|
||||
#endif
|
||||
s->variant = 0;
|
||||
s->oamFlags = SPRITE_OAM_ORDER(7);
|
||||
s->frameFlags = SPRITE_FLAG(PRIORITY, 2);
|
||||
@@ -333,6 +381,8 @@ struct Task *CreateWaterfallSurfaceHitEffect(s32 x, s32 y)
|
||||
return t;
|
||||
}
|
||||
|
||||
// At the bottom of the file in SA1!
|
||||
#if (GAME == GAME_SA2)
|
||||
UNUSED void MaskPaletteWithUnderwaterColor(u32 *dst, u32 *src, u32 mask, s32 size)
|
||||
{
|
||||
#ifndef NON_MATCHING
|
||||
@@ -351,6 +401,7 @@ UNUSED void MaskPaletteWithUnderwaterColor(u32 *dst, u32 *src, u32 mask, s32 siz
|
||||
MaskPaletteWithUnderwaterColor_inline(dst, src, mask, size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void TaskDestructor_WaterSurface(struct Task *t)
|
||||
{
|
||||
@@ -359,9 +410,12 @@ static void TaskDestructor_WaterSurface(struct Task *t)
|
||||
gFlags &= ~FLAGS_40;
|
||||
gIntrTable[INTR_INDEX_VCOUNT] = gIntrTableTemplate[INTR_INDEX_VCOUNT];
|
||||
water->t = NULL;
|
||||
#if (GAME == GAME_SA1)
|
||||
DmaFill32(3, 0, sPaletteBuffer, 60 * 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void sub_8011A4C(void)
|
||||
static void SA2_LABEL(sub_8011A4C)(void)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
#ifdef BUG_FIX
|
||||
@@ -369,24 +423,28 @@ static void sub_8011A4C(void)
|
||||
#endif
|
||||
{
|
||||
WaterData *wd = TASK_DATA(water->t);
|
||||
u32 unk2;
|
||||
unk2 = water->unk2;
|
||||
water->unk1 = unk2;
|
||||
u32 unk2 = water->SA2_LABEL(unk2);
|
||||
water->SA2_LABEL(unk1) = unk2;
|
||||
water->unk8 &= ~0x1;
|
||||
|
||||
// TODO: This surely can be matched differently!
|
||||
unk2 <<= 24;
|
||||
|
||||
if (!unk2) {
|
||||
#if (GAME == GAME_SA1)
|
||||
DmaCopy32(3, &sPaletteBuffer[16 * 16], BG_PLTT, 29 * 16);
|
||||
DmaCopy32(3, &sPaletteBuffer, OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#elif (GAME == GAME_SA2)
|
||||
DmaCopy32(3, &wd->pal[16], PLTT, 29 * 16);
|
||||
DmaCopy32(3, &wd->pal[0], OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#endif
|
||||
REG_DISPCNT &= ~DISPCNT_BG0_ON;
|
||||
gFlags |= (FLAGS_UPDATE_SPRITE_PALETTES | FLAGS_UPDATE_BACKGROUND_PALETTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void VCountIntr_8011ACC(void)
|
||||
static void SA2_LABEL(VCountIntr_8011ACC)(void)
|
||||
{
|
||||
Water *water = &gWater;
|
||||
#ifdef BUG_FIX
|
||||
@@ -394,21 +452,49 @@ static void VCountIntr_8011ACC(void)
|
||||
#endif
|
||||
{
|
||||
WaterData *wd = TASK_DATA(water->t);
|
||||
|
||||
#if (GAME == GAME_SA1)
|
||||
DmaCopy32(0, &sPaletteBuffer[16 * 16], BG_PLTT, 29 * 16);
|
||||
DmaCopy32(0, &sPaletteBuffer, OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#elif (GAME == GAME_SA2)
|
||||
DmaCopy32(3, &wd->pal[16], PLTT, 29 * 16);
|
||||
DmaCopy32(3, &wd->pal[0], OBJ_PLTT, OBJ_PLTT_SIZE);
|
||||
#endif
|
||||
|
||||
REG_DISPCNT &= ~DISPCNT_BG0_ON;
|
||||
gFlags |= (FLAGS_UPDATE_SPRITE_PALETTES | FLAGS_UPDATE_BACKGROUND_PALETTES);
|
||||
#if (GAME == GAME_SA1)
|
||||
DmaSet(0, gBgOffsetsHBlankSecondary, (void *)®_BG3HOFS, //
|
||||
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | (gHBlankCopySize >> 1));
|
||||
#endif
|
||||
REG_IF = INTR_FLAG_VCOUNT;
|
||||
}
|
||||
}
|
||||
|
||||
static void TaskDestructor_8011B3C(struct Task *t)
|
||||
// Further up in SA2!
|
||||
#if (GAME == GAME_SA1)
|
||||
UNUSED void MaskPaletteWithUnderwaterColor(u32 *dst, u32 *src, u32 mask, s32 size)
|
||||
{
|
||||
u32 k = (size >> 4);
|
||||
while (k-- > 0) {
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
*dst++ = WATER_MASK_PALETTE_CHUNK(*src++, mask);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HAS_RUN_ON_WATER)
|
||||
static void TaskDestructor_RunOnWaterEffect(struct Task *t)
|
||||
{
|
||||
RunOnWaterEffect *effect = TASK_DATA(t);
|
||||
Sprite *s = &effect->s;
|
||||
VramFree(s->graphics.dest);
|
||||
}
|
||||
|
||||
static void sub_8011B54(u32 *dst, u32 *src, s32 size) { CopyPalette(dst, src, size); }
|
||||
static void SA2_LABEL(sub_8011B54)(u32 *dst, u32 *src, s32 size) { CopyPalette(dst, src, size); }
|
||||
#endif
|
||||
Reference in new issue
Block a user