diff options
author | camthesaxman <cameronghall@cox.net> | 2018-01-10 12:12:55 -0600 |
---|---|---|
committer | camthesaxman <cameronghall@cox.net> | 2018-01-10 12:12:55 -0600 |
commit | beac14a9a0ab072186fa99afcfcc0d844b77a68d (patch) | |
tree | bfe15d4e6b8a2179de8dfc5c48caec85779c3d82 /src/scanline_effect.c | |
parent | f9f0e84b70f1b313200acd6f0d180413e34517da (diff) |
label more of scanline_effect.c
Diffstat (limited to 'src/scanline_effect.c')
-rw-r--r-- | src/scanline_effect.c | 170 |
1 files changed, 96 insertions, 74 deletions
diff --git a/src/scanline_effect.c b/src/scanline_effect.c index e9cf0d02a..0fa5b024d 100644 --- a/src/scanline_effect.c +++ b/src/scanline_effect.c @@ -4,27 +4,26 @@ #include "trig.h" #include "scanline_effect.h" -// Control value to ransfer a single 16-bit value at HBlank -#define HBLANK_DMA_CONTROL_16BIT (((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1) +static void CopyValue16Bit(void); +static void CopyValue32Bit(void); -static void sub_80896F4(void); -static void sub_8089714(void); - -extern u16 gUnknown_030041B0; -extern u16 gBattle_BG1_Y; -extern u16 gUnknown_030041B8; -extern u16 gBattle_BG2_Y; -extern u16 gBattle_BG2_X; extern u16 gBattle_BG0_Y; extern u16 gBattle_BG0_X; extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; +extern u16 gUnknown_030041B0; +extern u16 gUnknown_030041B8; -extern u8 gUnknown_0202FFA4; +EWRAM_DATA static u8 gUnknown_0202FFA4 = 0; -extern struct ScanlineEffect gScanlineEffect; +struct ScanlineEffect gScanlineEffect; -// Is this a struct? -extern u16 gUnknown_03004DE0[][0x3C0]; +// Per-scanline register values. +// This is double buffered so that it can be safely written to at any time +// without overwriting the buffer that the DMA is currently reading +u16 gScanlineEffectRegBuffers[2][0x3C0]; void ScanlineEffect_Stop(void) { @@ -39,11 +38,11 @@ void ScanlineEffect_Stop(void) void dp12_8087EA4(void) { - CpuFill16(0, gUnknown_03004DE0, 0x780 * 2); - gScanlineEffect.src[0] = 0; - gScanlineEffect.src[1] = 0; - gScanlineEffect.dest = 0; - gScanlineEffect.unkC = 0; + CpuFill16(0, gScanlineEffectRegBuffers, sizeof(gScanlineEffectRegBuffers)); + gScanlineEffect.src[0] = NULL; + gScanlineEffect.src[1] = NULL; + gScanlineEffect.dmaDest = NULL; + gScanlineEffect.dmaControl = 0; gScanlineEffect.srcBank = 0; gScanlineEffect.unk15 = 0; gScanlineEffect.unk16 = 0; @@ -51,31 +50,35 @@ void dp12_8087EA4(void) gScanlineEffect.taskId = 0xFF; } -void sub_80895F8(struct UnknownTaskStruct unk) +void ScanlineEffect_SetParams(struct ScanlineEffectParams params) { - if (unk.control == HBLANK_DMA_CONTROL_16BIT) // 16 bit + if (params.dmaControl == SCANLINE_EFFECT_DMACNT_16BIT) // 16-bit { - gScanlineEffect.src[0] = &gUnknown_03004DE0[0][1]; - gScanlineEffect.src[1] = &gUnknown_03004DE0[1][1]; - gScanlineEffect.unk10 = sub_80896F4; + // Set the DMA src to the value for the second scanline because the + // first DMA transfer occurs in HBlank *after* the first scanline is drawn + gScanlineEffect.src[0] = (u16 *)gScanlineEffectRegBuffers[0] + 1; + gScanlineEffect.src[1] = (u16 *)gScanlineEffectRegBuffers[1] + 1; + gScanlineEffect.setFirstScanlineReg = CopyValue16Bit; } else // assume 32-bit { - gScanlineEffect.src[0] = &gUnknown_03004DE0[0][2]; - gScanlineEffect.src[1] = &gUnknown_03004DE0[1][2]; - gScanlineEffect.unk10 = sub_8089714; + // Set the DMA src to the value for the second scanline because the + // first DMA transfer occurs in HBlank *after* the first scanline is drawn + gScanlineEffect.src[0] = (u32 *)gScanlineEffectRegBuffers[0] + 1; + gScanlineEffect.src[1] = (u32 *)gScanlineEffectRegBuffers[1] + 1; + gScanlineEffect.setFirstScanlineReg = CopyValue32Bit; } - gScanlineEffect.unkC = unk.control; - gScanlineEffect.dest = unk.dest; - gScanlineEffect.unk15 = unk.unk8; - gScanlineEffect.unk16 = unk.unk9; - gScanlineEffect.unk17 = unk.unk9; + gScanlineEffect.dmaControl = params.dmaControl; + gScanlineEffect.dmaDest = params.dmaDest; + gScanlineEffect.unk15 = params.unk8; + gScanlineEffect.unk16 = params.unk9; + gScanlineEffect.unk17 = params.unk9; } -void ScanlineEffect_TransferDma(void) +void ScanlineEffect_InitHBlankDmaTransfer(void) { - if (gScanlineEffect.unk15) + if (gScanlineEffect.unk15 != 0) { if (gScanlineEffect.unk15 == 3) { @@ -86,28 +89,44 @@ void ScanlineEffect_TransferDma(void) else { DmaStop(0); - DmaSet(0, gScanlineEffect.src[gScanlineEffect.srcBank], gScanlineEffect.dest, gScanlineEffect.unkC); - gScanlineEffect.unk10(); + // Set DMA to copy to dest register on each HBlank for the next frame. + // The HBlank DMA transfers do not occurr during VBlank, so the transfer + // will begin on the HBlank after the first scanline + DmaSet(0, gScanlineEffect.src[gScanlineEffect.srcBank], gScanlineEffect.dmaDest, gScanlineEffect.dmaControl); + // Manually set the reg for the first scanline + gScanlineEffect.setFirstScanlineReg(); + // Swap current buffer gScanlineEffect.srcBank ^= 1; } } } -static void sub_80896F4(void) +// These two functions are used to copy the register for the first scanline, +// depending whether it is a 16-bit register or a 32-bit register. + +static void CopyValue16Bit(void) { - u16 *dest = (u16 *)gScanlineEffect.dest; - u16 *src = (u16 *)&gUnknown_03004DE0[gScanlineEffect.srcBank]; + u16 *dest = (u16 *)gScanlineEffect.dmaDest; + u16 *src = (u16 *)&gScanlineEffectRegBuffers[gScanlineEffect.srcBank]; + *dest = *src; } -static void sub_8089714(void) +static void CopyValue32Bit(void) { - u32 *dest = (u32 *)gScanlineEffect.dest; - u32 *src = (u32 *)&gUnknown_03004DE0[gScanlineEffect.srcBank]; + u32 *dest = (u32 *)gScanlineEffect.dmaDest; + u32 *src = (u32 *)&gScanlineEffectRegBuffers[gScanlineEffect.srcBank]; + *dest = *src; } -static void task00_for_dp12(u8 taskId) +#define tStartLine data[0] +#define tEndLine data[1] +#define framesUntilMove data[4] +#define tDelayInterval data[5] +#define tRegOffset data[6] + +static void TaskFunc_UpdateWavePerFrame(u8 taskId) { int value = 0; @@ -120,7 +139,7 @@ static void task00_for_dp12(u8 taskId) { if (gTasks[taskId].data[7]) { - switch (gTasks[taskId].data[6]) + switch (gTasks[taskId].tRegOffset) { case 0x0: value = gBattle_BG0_X; @@ -148,15 +167,16 @@ static void task00_for_dp12(u8 taskId) break; } } - if (gTasks[taskId].data[4]) + if (gTasks[taskId].framesUntilMove != 0) { int i; int offset; - gTasks[taskId].data[4]--; + + gTasks[taskId].framesUntilMove--; offset = gTasks[taskId].data[3] + 320; - for (i = gTasks[taskId].data[0]; i < gTasks[taskId].data[1]; i++) + for (i = gTasks[taskId].tStartLine; i < gTasks[taskId].tEndLine; i++) { - gUnknown_03004DE0[gScanlineEffect.srcBank][i] = gUnknown_03004DE0[0][offset] + value; + gScanlineEffectRegBuffers[gScanlineEffect.srcBank][i] = gScanlineEffectRegBuffers[0][offset] + value; offset++; } } @@ -164,18 +184,17 @@ static void task00_for_dp12(u8 taskId) { int i; int offset; - gTasks[taskId].data[4] = gTasks[taskId].data[5]; + + gTasks[taskId].framesUntilMove = gTasks[taskId].tDelayInterval; offset = gTasks[taskId].data[3] + 320; - for (i = gTasks[taskId].data[0]; i < gTasks[taskId].data[1]; i++) + for (i = gTasks[taskId].tStartLine; i < gTasks[taskId].tEndLine; i++) { - gUnknown_03004DE0[gScanlineEffect.srcBank][i] = gUnknown_03004DE0[0][offset] + value; + gScanlineEffectRegBuffers[gScanlineEffect.srcBank][i] = gScanlineEffectRegBuffers[0][offset] + value; offset++; } gTasks[taskId].data[3]++; if (gTasks[taskId].data[3] == gTasks[taskId].data[2]) - { gTasks[taskId].data[3] = 0; - } } } } @@ -193,44 +212,47 @@ static void GenerateWave(u16 *buffer, u8 frequency, u8 amplitude, u8 unused) } } -u8 ScanlineEffect_InitWave(u8 a1, u8 a2, u8 frequency, u8 amplitude, u8 a5, u8 a6, u8 a7) +// Initializes a background "wave" effect that affects scanlines startLine (inclusive) to endLine (exclusive). +// 'frequency' and 'amplitude' control the frequency and amplitude of the wave. +// 'delayInterval' controls how fast the wave travels up the screen. The wave will shift upwards one scanline every 'delayInterval'+1 frames. +// 'regOffset' is the offset of the video register to modify. +u8 ScanlineEffect_InitWave(u8 startLine, u8 endLine, u8 frequency, u8 amplitude, u8 delayInterval, u8 regOffset, bool8 a7) { int i; int offset; - struct UnknownTaskStruct unk; + struct ScanlineEffectParams params; u8 taskId; dp12_8087EA4(); - unk.dest = (void *)(REG_ADDR_BG0HOFS + a6); - unk.control = HBLANK_DMA_CONTROL_16BIT; - unk.unk8 = 1; - unk.unk9 = 0; - - sub_80895F8(unk); + params.dmaDest = (void *)(REG_ADDR_BG0HOFS + regOffset); + params.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT; + params.unk8 = 1; + params.unk9 = 0; + ScanlineEffect_SetParams(params); - taskId = CreateTask(task00_for_dp12, 0); + taskId = CreateTask(TaskFunc_UpdateWavePerFrame, 0); - gTasks[taskId].data[0] = a1; - gTasks[taskId].data[1] = a2; - gTasks[taskId].data[2] = 256 / frequency; - gTasks[taskId].data[3] = 0; - gTasks[taskId].data[4] = a5; - gTasks[taskId].data[5] = a5; - gTasks[taskId].data[6] = a6; - gTasks[taskId].data[7] = a7; + gTasks[taskId].tStartLine = startLine; + gTasks[taskId].tEndLine = endLine; + gTasks[taskId].data[2] = 256 / frequency; + gTasks[taskId].data[3] = 0; + gTasks[taskId].framesUntilMove = delayInterval; + gTasks[taskId].tDelayInterval = delayInterval; + gTasks[taskId].tRegOffset = regOffset; + gTasks[taskId].data[7] = a7; gScanlineEffect.taskId = taskId; gUnknown_0202FFA4 = 0; - GenerateWave(&gUnknown_03004DE0[0][320], frequency, amplitude, a2 - a1); + GenerateWave(&gScanlineEffectRegBuffers[0][320], frequency, amplitude, endLine - startLine); offset = 320; - for (i = a1; i < a2; i++) + for (i = startLine; i < endLine; i++) { - gUnknown_03004DE0[0][i] = gUnknown_03004DE0[0][offset]; - gUnknown_03004DE0[1][i] = gUnknown_03004DE0[0][offset]; + gScanlineEffectRegBuffers[0][i] = gScanlineEffectRegBuffers[0][offset]; + gScanlineEffectRegBuffers[1][i] = gScanlineEffectRegBuffers[0][offset]; offset++; } |