summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2020-03-10 14:02:03 -0400
committerGriffinR <griffin.g.richards@gmail.com>2020-03-10 14:02:03 -0400
commita495379ff06f8976cc51b2d6f31a3b4277469537 (patch)
tree30d59033a9720420675ee8e0431e94dbf00c20ed /src
parent31b0cbe9b40d84798e5f3ee2f77f3cdc3543c5c5 (diff)
Document pokedex cry screen
Diffstat (limited to 'src')
-rw-r--r--src/pokedex.c26
-rw-r--r--src/pokedex_cry_screen.c355
2 files changed, 215 insertions, 166 deletions
diff --git a/src/pokedex.c b/src/pokedex.c
index 7532f0c99..ba05969ae 100644
--- a/src/pokedex.c
+++ b/src/pokedex.c
@@ -3568,14 +3568,14 @@ static void Task_LoadCryScreen(u8 taskId)
break;
case 6:
{
- struct CryRelatedStruct sp4;
-
- sp4.unk0 = 0x4020;
- sp4.unk2 = 0x1F;
- sp4.paletteNo = 8;
- sp4.yPos = 0x1E;
- sp4.xPos = 0xC;
- if (LoadCryWaveformWindow(&sp4, 2))
+ struct CryScreenWindow waveformWindow;
+
+ waveformWindow.unk0 = 0x4020;
+ waveformWindow.unk2 = 31;
+ waveformWindow.paletteNo = 8;
+ waveformWindow.yPos = 30;
+ waveformWindow.xPos = 12;
+ if (LoadCryWaveformWindow(&waveformWindow, 2))
{
gMain.state++;
gDexCryScreenState = 0;
@@ -3584,12 +3584,12 @@ static void Task_LoadCryScreen(u8 taskId)
break;
case 7:
{
- struct CryRelatedStruct spC;
+ struct CryScreenWindow cryMeter;
- spC.paletteNo = 9;
- spC.xPos = 0x12;
- spC.yPos = 3;
- if (LoadCryMeter(&spC, 3))
+ cryMeter.paletteNo = 9;
+ cryMeter.xPos = 18;
+ cryMeter.yPos = 3;
+ if (LoadCryMeter(&cryMeter, 3))
gMain.state++;
CopyWindowToVram(WIN_VU_METER, 2);
CopyWindowToVram(WIN_INFO, 3);
diff --git a/src/pokedex_cry_screen.c b/src/pokedex_cry_screen.c
index 02ce18d05..0a6f639ae 100644
--- a/src/pokedex_cry_screen.c
+++ b/src/pokedex_cry_screen.c
@@ -9,35 +9,53 @@
#include "trig.h"
#include "window.h"
-struct PokedexCryVolumeMeter {
- s8 unk0;
- s8 unk1;
- u8 unk2;
- u16 needleSpriteId;
+// Cry meter needle positions
+//
+// 0
+// 32 . . -32
+// . .
+// 64 . . -64
+// . .
+// . .
+// 96 . . -96
+// 127
+//
+#define MIN_NEEDLE_POS 32
+#define MAX_NEEDLE_POS -32
+
+#define NEEDLE_MOVE_INCREMENT 5
+
+#define WAVEFORM_WINDOW_HEIGHT 56
+
+struct PokedexCryMeterNeedle {
+ s8 rotation;
+ s8 targetRotation;
+ u8 moveIncrement;
+ u16 spriteId;
};
struct PokedexCryScreen
{
- u8 unk0[16];
- u8 unk10;
- u8 unk11;
- u8 unk12;
- u16 unk14;
- u8 unk16;
+ u8 cryWaveformBuffer[16];
+ u8 cryState;
+ u8 playhead;
+ u8 waveformPreviousY;
+ u16 unk; // Never read
+ u8 playStartPos;
u16 species;
- u8 unk1A;
- u8 unk1B;
+ u8 cryOverrideCountdown;
+ u8 cryRepeatDelay;
};
static void PlayCryScreenCry(u16);
-static void sub_81455A8(void);
+static void BufferCryWaveformSegment(void);
static void DrawWaveformFlatline(void);
-static void sub_8145648(u8);
+static void AdvancePlayhead(u8);
static void DrawWaveformSegment(u8, u8);
-static void sub_8145814(u8);
-static void sub_8145824(u8, s16, u8);
+static void DrawWaveformWindow(u8);
+static void ShiftWaveformOver(u8, s16, bool8);
static void SpriteCB_CryMeterNeedle(struct Sprite *);
-static void sub_8145B24(s8);
+static void SetCryMeterNeedleTarget(s8);
// IWRAM common
u8 gDexCryScreenState;
@@ -45,7 +63,7 @@ u8 gDexCryScreenState;
// EWRAM vars
static EWRAM_DATA struct PokedexCryScreen *sDexCryScreen = NULL;
static EWRAM_DATA u8 *sCryWaveformWindowTiledata = NULL;
-static EWRAM_DATA struct PokedexCryVolumeMeter *sCryVolumeMeter = NULL;
+static EWRAM_DATA struct PokedexCryMeterNeedle *sCryMeterNeedle = NULL;
static const u16 sCryMeterNeedle_Pal[] = INCBIN_U16("graphics/pokedex/cry_meter_needle.gbapal");
static const u8 sCryMeterNeedle_Gfx[] = INCBIN_U8("graphics/pokedex/cry_meter_needle.4bpp");
@@ -54,7 +72,7 @@ static const u16 sCryMeter_Tilemap[] = INCBIN_U16("graphics/pokedex/cry_meter_ma
static const u16 sCryMeter_Pal[] = INCBIN_U16("graphics/pokedex/cry_meter.gbapal");
static const u8 sCryMeter_Gfx[] = INCBIN_U8("graphics/pokedex/cry_meter.4bpp.lz");
-const u16 gUnknown_085B8770[][72] =
+static const u16 sWaveformOffsets[][72] =
{
{
0x0000, 0x0004, 0x0008, 0x000C, 0x0010, 0x0014, 0x0018, 0x001C,
@@ -139,18 +157,21 @@ const u16 gUnknown_085B8770[][72] =
}
};
-static const u16 sCryScreenBg_Pal[] = INCBIN_U16("graphics/pokedex/85B8C10.gbapal");
-static const u8 sCryScreenBg_Gfx[] = INCBIN_U8("graphics/pokedex/85B8C10.4bpp");
+static const u16 sCryScreenBg_Pal[] = INCBIN_U16("graphics/pokedex/cry_screen_bg.gbapal");
+static const u8 sCryScreenBg_Gfx[] = INCBIN_U8("graphics/pokedex/cry_screen_bg.4bpp");
-const u8 gUnknown_085B8C30[] = {0xF0, 0x0F};
-const u8 gUnknown_085B8C32[][16] =
+static const u8 sWaveformTileDataNybbleMasks[] = {0xF0, 0x0F};
+
+// Waveform is blue in the middle (8) grading to white at peaks (15)
+// Split into two arrays for the two vertical slice halves
+static const u8 sWaveformColor[][16] =
{
{
- 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+ 15, 14, 13, 12, 11, 10, 9, 8,
+ 8, 9, 10, 11, 12, 13, 14, 15,
}, {
- 0xF0, 0xE0, 0xD0, 0xC0, 0xB0, 0xA0, 0x90, 0x80,
- 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0
+ 15 << 4, 14 << 4, 13 << 4, 12 << 4, 11 << 4, 10 << 4, 9 << 4, 8 << 4,
+ 8 << 4, 9 << 4, 10 << 4, 11 << 4, 12 << 4, 13 << 4, 14 << 4, 15 << 4,
}
};
@@ -202,7 +223,7 @@ static const struct SpritePalette sCryMeterNeedleSpritePalettes[] =
{}
};
-bool8 LoadCryWaveformWindow(struct CryRelatedStruct *arg0, u8 windowId)
+bool8 LoadCryWaveformWindow(struct CryScreenWindow *window, u8 windowId)
{
u8 i;
u8 finished = FALSE;
@@ -216,28 +237,28 @@ bool8 LoadCryWaveformWindow(struct CryRelatedStruct *arg0, u8 windowId)
sCryWaveformWindowTiledata = (u8*)GetWindowAttribute(windowId, WINDOW_TILE_DATA);
}
- sDexCryScreen->unk14 = arg0->unk0;
- sDexCryScreen->unk16 = arg0->yPos;
- sDexCryScreen->unk1A = 0;
- sDexCryScreen->unk1B = 0;
- sDexCryScreen->unk10 = 0;
- sDexCryScreen->unk12 = 28;
- sDexCryScreen->unk11 = 0;
- sub_8145824(windowId, -8 * arg0->xPos, 1);
+ sDexCryScreen->unk = window->unk0;
+ sDexCryScreen->playStartPos = window->yPos;
+ sDexCryScreen->cryOverrideCountdown = 0;
+ sDexCryScreen->cryRepeatDelay = 0;
+ sDexCryScreen->cryState = 0;
+ sDexCryScreen->waveformPreviousY = WAVEFORM_WINDOW_HEIGHT / 2;
+ sDexCryScreen->playhead = 0;
+ ShiftWaveformOver(windowId, -8 * window->xPos, TRUE); // Does nothing
for (i = 0; i < 224; i++)
CopyToWindowPixelBuffer(windowId, sCryScreenBg_Gfx, TILE_SIZE_4BPP, i);
gDexCryScreenState++;
break;
case 1:
- for (i = 0; i < sDexCryScreen->unk16 * 8; i++)
+ for (i = 0; i < sDexCryScreen->playStartPos * 8; i++)
DrawWaveformSegment(i, 0);
gDexCryScreenState++;
break;
case 2:
- sub_8145814(windowId);
- LoadPalette(sCryScreenBg_Pal, arg0->paletteNo * 16, 32);
+ DrawWaveformWindow(windowId);
+ LoadPalette(sCryScreenBg_Pal, window->paletteNo * 16, 32);
finished = TRUE;
break;
}
@@ -247,17 +268,20 @@ bool8 LoadCryWaveformWindow(struct CryRelatedStruct *arg0, u8 windowId)
void UpdateCryWaveformWindow(u8 windowId)
{
- u8 var0;
+ u8 waveformIdx;
+
+ DrawWaveformWindow(windowId);
+ AdvancePlayhead(windowId);
- sub_8145814(windowId);
- sub_8145648(windowId);
- if (sDexCryScreen->unk1B)
- sDexCryScreen->unk1B--;
+ // Cry cant be replayed until this counter is done
+ if (sDexCryScreen->cryRepeatDelay)
+ sDexCryScreen->cryRepeatDelay--;
- if (sDexCryScreen->unk1A)
+ // Once a cry replay has started, it waits for this countdown before playing
+ if (sDexCryScreen->cryOverrideCountdown)
{
- sDexCryScreen->unk1A--;
- if (!sDexCryScreen->unk1A)
+ sDexCryScreen->cryOverrideCountdown--;
+ if (!sDexCryScreen->cryOverrideCountdown)
{
PlayCryScreenCry(sDexCryScreen->species);
DrawWaveformFlatline();
@@ -265,47 +289,51 @@ void UpdateCryWaveformWindow(u8 windowId)
}
}
- if (sDexCryScreen->unk10 == 0)
+ // No cry playing
+ if (sDexCryScreen->cryState == 0)
{
DrawWaveformFlatline();
return;
}
- if (sDexCryScreen->unk10 == 1)
+ // Cry playing, buffer waveform
+ if (sDexCryScreen->cryState == 1)
{
- sub_81455A8();
+ BufferCryWaveformSegment();
}
- else if (sDexCryScreen->unk10 > 8)
+ else if (sDexCryScreen->cryState > 8)
{
+ // Buffered waveform exhausted, end or buffer more
if (!IsCryPlaying())
{
DrawWaveformFlatline();
- sDexCryScreen->unk10 = 0;
+ sDexCryScreen->cryState = 0;
return;
}
- sub_81455A8();
- sDexCryScreen->unk10 = 1;
+ BufferCryWaveformSegment();
+ sDexCryScreen->cryState = 1;
}
- var0 = 2 * (sDexCryScreen->unk10 - 1);
- DrawWaveformSegment(sDexCryScreen->unk16 * 8 + sDexCryScreen->unk11 - 2, sDexCryScreen->unk0[var0]);
- DrawWaveformSegment(sDexCryScreen->unk16 * 8 + sDexCryScreen->unk11 - 1, sDexCryScreen->unk0[var0 + 1]);
- sDexCryScreen->unk10++;
+ // Draw cry
+ waveformIdx = 2 * (sDexCryScreen->cryState - 1);
+ DrawWaveformSegment(sDexCryScreen->playStartPos * 8 + sDexCryScreen->playhead - 2, sDexCryScreen->cryWaveformBuffer[waveformIdx]);
+ DrawWaveformSegment(sDexCryScreen->playStartPos * 8 + sDexCryScreen->playhead - 1, sDexCryScreen->cryWaveformBuffer[waveformIdx + 1]);
+ sDexCryScreen->cryState++;
}
void CryScreenPlayButton(u16 species)
{
- if (gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_PAUSE && !sDexCryScreen->unk1A)
+ if (gMPlayInfo_BGM.status & MUSICPLAYER_STATUS_PAUSE && !sDexCryScreen->cryOverrideCountdown)
{
- if (!sDexCryScreen->unk1B)
+ if (!sDexCryScreen->cryRepeatDelay)
{
- sDexCryScreen->unk1B = 4;
+ sDexCryScreen->cryRepeatDelay = 4;
if (IsCryPlaying() == TRUE)
{
StopCry();
sDexCryScreen->species = species;
- sDexCryScreen->unk1A = 2;
+ sDexCryScreen->cryOverrideCountdown = 2;
}
else
{
@@ -317,11 +345,11 @@ void CryScreenPlayButton(u16 species)
static void PlayCryScreenCry(u16 species)
{
- PlayCry2(species, 0, 0x7d, 10);
- sDexCryScreen->unk10 = 1;
+ PlayCry2(species, 0, 125, 10);
+ sDexCryScreen->cryState = 1;
}
-static void sub_81455A8(void)
+static void BufferCryWaveformSegment(void)
{
u8 i;
s8 *baseBuffer;
@@ -333,102 +361,113 @@ static void sub_81455A8(void)
baseBuffer = gSoundInfo.pcmBuffer + (gSoundInfo.pcmDmaPeriod + 1 - gPcmDmaCounter) * gSoundInfo.pcmSamplesPerVBlank;
buffer = baseBuffer + 0x630;
- for (i = 0; i < ARRAY_COUNT(sDexCryScreen->unk0); i++)
- sDexCryScreen->unk0[i] = buffer[i * 2] * 2;
+ for (i = 0; i < ARRAY_COUNT(sDexCryScreen->cryWaveformBuffer); i++)
+ sDexCryScreen->cryWaveformBuffer[i] = buffer[i * 2] * 2;
}
static void DrawWaveformFlatline(void)
{
- DrawWaveformSegment(sDexCryScreen->unk16 * 8 + sDexCryScreen->unk11 - 2, 0);
- DrawWaveformSegment(sDexCryScreen->unk16 * 8 + sDexCryScreen->unk11 - 1, 0);
+ DrawWaveformSegment(sDexCryScreen->playStartPos * 8 + sDexCryScreen->playhead - 2, 0);
+ DrawWaveformSegment(sDexCryScreen->playStartPos * 8 + sDexCryScreen->playhead - 1, 0);
}
-static void sub_8145648(u8 windowId)
+static void AdvancePlayhead(u8 windowId)
{
u8 i;
u16 offset;
- sub_8145824(windowId, sDexCryScreen->unk11, 0);
- sDexCryScreen->unk11 += 2;
- offset = (sDexCryScreen->unk11 / 8 + sDexCryScreen->unk16 + 1) % 32;
+ ShiftWaveformOver(windowId, sDexCryScreen->playhead, FALSE);
+ sDexCryScreen->playhead += 2;
+ offset = (sDexCryScreen->playhead / 8 + sDexCryScreen->playStartPos + 1) % 32;
for (i = 0; i < 7; i++)
CopyToWindowPixelBuffer(windowId, sCryScreenBg_Gfx, TILE_SIZE_4BPP, offset + (i * TILE_SIZE_4BPP));
}
-static void DrawWaveformSegment(u8 a0, u8 a1)
+// Waveform segments are drawn in alternate vertical slices
+// Note that the waveform isnt put on screen until DrawWaveformWindow
+static void DrawWaveformSegment(u8 position, u8 amplitude)
{
- u8 sp0;
- u8 r6;
- u8 r8;
- u16 offset;
- u16 r1;
- u8 i;
+ // Position is a bitfield containing the play start pos, the playhead pos, and which vertical slice half to draw
+ #define PLAY_START_POS (position >> 3)
+ #define PLAYHEAD_POS (position & ((1 << 3) - 1))
+ #define VERT_SLICE (position & 1)
- r1 = (a1 + 127) * 256;
- i = r1 / 1152.0;
- if (i > 55)
- i = 55;
- sp0 = i;
- r6 = a0 & 1;
- if (i > sDexCryScreen->unk12)
+ u8 currentPointY;
+ u8 nybble;
+ u16 offset;
+ u16 temp;
+ u8 y;
+
+ temp = (amplitude + 127) * 256;
+ y = temp / 1152.0;
+ if (y > WAVEFORM_WINDOW_HEIGHT - 1)
+ y = WAVEFORM_WINDOW_HEIGHT - 1;
+ currentPointY = y;
+ nybble = VERT_SLICE;
+ if (y > sDexCryScreen->waveformPreviousY)
{
+ // Current point lower than previous point, draw point and draw line up to previous
do
{
- offset = gUnknown_085B8770[a0 & 0x7][i] + (a0 / 8) * TILE_SIZE_4BPP;
- sCryWaveformWindowTiledata[offset] &= gUnknown_085B8C30[r6];
- sCryWaveformWindowTiledata[offset] |= gUnknown_085B8C32[r6][((i / 3) - 1) & 0x0F];
- i--;
- } while (i > sDexCryScreen->unk12);
+ offset = sWaveformOffsets[PLAYHEAD_POS][y] + PLAY_START_POS * TILE_SIZE_4BPP;
+ sCryWaveformWindowTiledata[offset] &= sWaveformTileDataNybbleMasks[nybble];
+ sCryWaveformWindowTiledata[offset] |= sWaveformColor[nybble][((y / 3) - 1) & 0x0F];
+ y--;
+ } while (y > sDexCryScreen->waveformPreviousY);
}
else
{
+ // Current point higher than previous point, draw point and draw line down to previous
do
{
- offset = gUnknown_085B8770[a0 & 0x7][i] + (a0 / 8) * TILE_SIZE_4BPP;
- sCryWaveformWindowTiledata[offset] &= gUnknown_085B8C30[r6];
- sCryWaveformWindowTiledata[offset] |= gUnknown_085B8C32[r6][((i / 3) - 1) & 0x0F];
- i++;
- } while (i < sDexCryScreen->unk12);
+ offset = sWaveformOffsets[PLAYHEAD_POS][y] + PLAY_START_POS * TILE_SIZE_4BPP;
+ sCryWaveformWindowTiledata[offset] &= sWaveformTileDataNybbleMasks[nybble];
+ sCryWaveformWindowTiledata[offset] |= sWaveformColor[nybble][((y / 3) - 1) & 0x0F];
+ y++;
+ } while (y < sDexCryScreen->waveformPreviousY);
}
- sDexCryScreen->unk12 = sp0;
+ sDexCryScreen->waveformPreviousY = currentPointY;
}
-static void sub_8145814(u8 windowId)
+static void DrawWaveformWindow(u8 windowId)
{
CopyWindowToVram(windowId, 2);
}
-static void sub_8145824(u8 windowId, s16 arg1, u8 arg2)
+// rsVertical is leftover from a very different version of this function in RS
+// In RS, when TRUE it would use VOFS and when FALSE it would use HOFS (only FALSE was used)
+// Here when TRUE it does nothing
+static void ShiftWaveformOver(u8 windowId, s16 offset, bool8 rsVertical)
{
- if (!arg2)
+ if (!rsVertical)
{
u8 bg = GetWindowAttribute(windowId, WINDOW_BG);
- ChangeBgX(bg, arg1 << 8, 0);
+ ChangeBgX(bg, offset << 8, 0);
}
}
-bool8 LoadCryMeter(struct CryRelatedStruct *arg0, u8 windowId)
+bool8 LoadCryMeter(struct CryScreenWindow *window, u8 windowId)
{
bool8 finished = FALSE;
switch (gDexCryScreenState)
{
case 0:
- if (!sCryVolumeMeter)
- sCryVolumeMeter = AllocZeroed(sizeof(*sCryVolumeMeter));
+ if (!sCryMeterNeedle)
+ sCryMeterNeedle = AllocZeroed(sizeof(*sCryMeterNeedle));
CopyToWindowPixelBuffer(windowId, sCryMeter_Gfx, 0, 0);
- LoadPalette(sCryMeter_Pal, arg0->paletteNo * 16, 32);
+ LoadPalette(sCryMeter_Pal, window->paletteNo * 16, 32);
gDexCryScreenState++;
break;
case 1:
LoadSpriteSheets(sCryMeterNeedleSpriteSheets);
LoadSpritePalettes(sCryMeterNeedleSpritePalettes);
- sCryVolumeMeter->needleSpriteId = CreateSprite(&sCryMeterNeedleSpriteTemplate, 40 + arg0->xPos * 8, 56 + arg0->yPos * 8, 1);
- sCryVolumeMeter->unk0 = 32;
- sCryVolumeMeter->unk1 = 32;
- sCryVolumeMeter->unk2 = 0;
+ sCryMeterNeedle->spriteId = CreateSprite(&sCryMeterNeedleSpriteTemplate, 40 + window->xPos * 8, 56 + window->yPos * 8, 1);
+ sCryMeterNeedle->rotation = MIN_NEEDLE_POS;
+ sCryMeterNeedle->targetRotation = MIN_NEEDLE_POS;
+ sCryMeterNeedle->moveIncrement = 0;
finished = TRUE;
break;
}
@@ -438,92 +477,102 @@ bool8 LoadCryMeter(struct CryRelatedStruct *arg0, u8 windowId)
void FreeCryScreen(void)
{
- FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[sCryVolumeMeter->needleSpriteId].oam.paletteNum));
- DestroySprite(gSprites + sCryVolumeMeter->needleSpriteId);
+ FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[sCryMeterNeedle->spriteId].oam.paletteNum));
+ DestroySprite(gSprites + sCryMeterNeedle->spriteId);
FREE_AND_SET_NULL(sDexCryScreen);
- FREE_AND_SET_NULL(sCryVolumeMeter);
+ FREE_AND_SET_NULL(sCryMeterNeedle);
}
static void SpriteCB_CryMeterNeedle(struct Sprite *sprite)
{
u16 i;
- s8 r3;
+ s8 peakAmplitude;
s16 x;
s16 y;
struct ObjAffineSrcData affine;
struct OamMatrix matrix;
- u8 *var0;
+ u8 amplitude;
- gSprites[sCryVolumeMeter->needleSpriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
- gSprites[sCryVolumeMeter->needleSpriteId].oam.affineParam = 0;
- switch (sDexCryScreen->unk10)
+ gSprites[sCryMeterNeedle->spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
+ gSprites[sCryMeterNeedle->spriteId].oam.affineParam = 0;
+
+ // While no cry is playing, cryState is 0
+ // While cry is playing, cryState loops 1-8
+ switch (sDexCryScreen->cryState)
{
case 0:
- sCryVolumeMeter->unk1 = 32;
- if (sCryVolumeMeter->unk0 > 0)
+ sCryMeterNeedle->targetRotation = MIN_NEEDLE_POS;
+ if (sCryMeterNeedle->rotation > 0)
{
- if (sCryVolumeMeter->unk2 != 1)
- sCryVolumeMeter->unk2--;
+ if (sCryMeterNeedle->moveIncrement != 1)
+ sCryMeterNeedle->moveIncrement--;
}
else
- sCryVolumeMeter->unk2 = 5;
+ {
+ sCryMeterNeedle->moveIncrement = NEEDLE_MOVE_INCREMENT;
+ }
break;
case 2:
- r3 = 0;
- for (i = 0; i < ARRAY_COUNT(sDexCryScreen->unk0); i++)
+ peakAmplitude = 0;
+ for (i = 0; i < ARRAY_COUNT(sDexCryScreen->cryWaveformBuffer); i++)
{
- if (r3 < sDexCryScreen->unk0[i])
- r3 = sDexCryScreen->unk0[i];
+ if (peakAmplitude < sDexCryScreen->cryWaveformBuffer[i])
+ peakAmplitude = sDexCryScreen->cryWaveformBuffer[i];
}
- sub_8145B24(r3 * 0xd0 / 0x100);
+ SetCryMeterNeedleTarget(peakAmplitude * 208 / 256);
break;
case 6:
- var0 = &sDexCryScreen->unk0[10];
- sub_8145B24(*var0 * 0xd0 / 0x100);
+ // To introduce some randomness, needle jumps to set pos in waveform rather than peak
+ amplitude = sDexCryScreen->cryWaveformBuffer[10];
+ SetCryMeterNeedleTarget(amplitude * 208 / 256);
break;
}
- if (sCryVolumeMeter->unk0 == sCryVolumeMeter->unk1)
+ if (sCryMeterNeedle->rotation == sCryMeterNeedle->targetRotation)
{
- // empty block
+ // Empty, needle has reached target
}
- else if (sCryVolumeMeter->unk0 < sCryVolumeMeter->unk1)
+ else if (sCryMeterNeedle->rotation < sCryMeterNeedle->targetRotation)
{
- sCryVolumeMeter->unk0 += sCryVolumeMeter->unk2;
- if (sCryVolumeMeter->unk0 > sCryVolumeMeter->unk1)
+ // Rotate needle left
+ sCryMeterNeedle->rotation += sCryMeterNeedle->moveIncrement;
+ if (sCryMeterNeedle->rotation > sCryMeterNeedle->targetRotation)
{
- sCryVolumeMeter->unk0 = sCryVolumeMeter->unk1;
- sCryVolumeMeter->unk1 = 0;
+ sCryMeterNeedle->rotation = sCryMeterNeedle->targetRotation;
+ sCryMeterNeedle->targetRotation = 0;
}
}
else
{
- sCryVolumeMeter->unk0 -= sCryVolumeMeter->unk2;
- if (sCryVolumeMeter->unk0 < sCryVolumeMeter->unk1)
+ // Rotate needle right
+ sCryMeterNeedle->rotation -= sCryMeterNeedle->moveIncrement;
+ if (sCryMeterNeedle->rotation < sCryMeterNeedle->targetRotation)
{
- sCryVolumeMeter->unk0 = sCryVolumeMeter->unk1;
- sCryVolumeMeter->unk1 = 0;
+ sCryMeterNeedle->rotation = sCryMeterNeedle->targetRotation;
+ sCryMeterNeedle->targetRotation = 0;
}
}
- affine.xScale = 0x100;
- affine.yScale = 0x100;
- affine.rotation = sCryVolumeMeter->unk0 * 256;
+ affine.xScale = 256;
+ affine.yScale = 256;
+ affine.rotation = sCryMeterNeedle->rotation * 256;
ObjAffineSet(&affine, &matrix, 1, 2);
SetOamMatrix(0, matrix.a, matrix.b, matrix.c, matrix.d);
- x = gSineTable[((sCryVolumeMeter->unk0 + 0x7F) & 0xFF)];
- y = gSineTable[((sCryVolumeMeter->unk0 + 0x7F) & 0xFF) + 64];
+ x = gSineTable[((sCryMeterNeedle->rotation + 0x7F) & 0xFF)];
+ y = gSineTable[((sCryMeterNeedle->rotation + 0x7F) & 0xFF) + 64];
sprite->pos2.x = x * 24 / 256;
sprite->pos2.y = y * 24 / 256;
}
-static void sub_8145B24(s8 a0)
+static void SetCryMeterNeedleTarget(s8 offset)
{
- u16 r2 = (0x20 - a0) & 0xff;
- if (r2 > 0x20 && r2 < 0xe0)
- r2 = 0xe0;
+ u16 rotation = (MIN_NEEDLE_POS - offset) & 0xFF;
+
+ // Min is positive, max is negative. Make sure needle hasnt moved out of bounds
+ if (rotation > MIN_NEEDLE_POS && rotation < (u8)MAX_NEEDLE_POS)
+ rotation = (u8)MAX_NEEDLE_POS;
- sCryVolumeMeter->unk1 = r2;
- sCryVolumeMeter->unk2 = 5;
+ sCryMeterNeedle->targetRotation = rotation;
+ sCryMeterNeedle->moveIncrement = NEEDLE_MOVE_INCREMENT;
}