marioparty4/src/REL/option/sound.c
2025-04-14 15:57:29 +02:00

1724 lines
58 KiB
C
Executable file

#include "REL/option.h"
#include "ext_math.h"
#include "game/data.h"
#include "game/esprite.h"
#include "game/gamework_data.h"
#include "game/hsfman.h"
#include "game/hsfmotion.h"
#include "game/memory.h"
#include "game/msm.h"
#include "game/process.h"
#include "game/window.h"
#include "dolphin.h"
#include "math.h"
#ifndef __MWERKS__
#include <game/audio.h>
#endif
typedef struct {
/* 0x000 */ omObjData *object[26];
/* 0x068 */ OptionWindow *window[13];
/* 0x09C */ s32 execMode;
/* 0x0A0 */ s16 sprite[19];
/* 0x0C8 */ s32 changeTimer;
/* 0x0CC */ s32 selectedOption;
/* 0x0D0 */ s32 soundMode;
/* 0x0D4 */ s32 page;
/* 0x0D8 */ s32 cursorPos;
/* 0x0DC */ s32 prevCursorPos;
/* 0x0E0 */ s16 sndGrpSet;
/* 0x0E4 */ BOOL optionSelected;
/* 0x0E8 */ BOOL doneF;
/* 0x0EC */ BOOL cameraDoneF;
/* 0x0F0 */ s16 bgMusicStat;
/* 0x0F2 */ s16 seqStat;
/* 0x0F4 */ s16 streamStat;
/* 0x0F6 */ s16 fxStat;
/* 0x0F8 */ s32 cursorDelay;
/* 0x0FC */ s32 pageDelta;
/* 0x100 */ s32 cursorDelta;
/* 0x104 */ float cursorTime;
/* 0x108 */ float cursorSpeed;
/* 0x10C */ Process *noteSpawner;
} SoundWork; // Size 0x110
typedef struct {
/* 0x00 */ BOOL enabled;
/* 0x04 */ s32 type;
/* 0x08 */ s32 side;
/* 0x0C */ float pos;
/* 0x10 */ float speed;
} NoteWork; // Size 0x14
typedef struct {
/* 0x00 */ BOOL enabled;
/* 0x04 */ s32 nameMess;
/* 0x08 */ s16 type;
/* 0x0A */ s16 sndGrpSet;
/* 0x0C */ s32 id;
} SndSelData; // Size 0x10
#define NUM_NOTES 16
#define MODE_DISABLED 0
#define MODE_HANDLE_INITIAL_SCREEN 1
#define MODE_HANDLE_OPTION_SEL 2
#define MODE_HANDLE_SOUND 3
#define MODE_HANDLE_MUSIC 4
#define MODE_HANDLE_VOICE 5
#define SOUND_MODE_STEREO 0
#define SOUND_MODE_MONO 1
#define NUM_BOARDS 6
#define NOTE_TYPE_QUAVER 0
#define NOTE_TYPE_QUARTER 1
#define NOTE_SIDE_LEFT 0
#define NOTE_SIDE_RIGHT 1
static void ExecZoom(omObjData *object);
static void ExecOptionSel(omObjData *object);
static void ExecOutputMode(omObjData *object);
static void ExecMusic(omObjData *object);
static void ExecVoice(omObjData *object);
static void LightSetCurr(omObjData *object, s32 id);
static void LightSetNone(omObjData *object);
static omObjData *CreateHand(void);
static void KillHand(omObjData *object);
static omObjData *CreateOutputModeHand(void);
static void KillOutputModeHand(omObjData *object);
static omObjData *CreateSystem(void);
static void KillSystem(omObjData *system);
static omObjData *CreateLightObj(s32 id, BOOL off);
static void KillLightObj(omObjData *indicator);
static void LightDispOff(omObjData *object);
static void LightDispOn(omObjData *object);
static void CreateSpr(omObjData *object);
static void KillSpr(omObjData *object);
static void OptionSelDisp(omObjData *object);
static void OptionSelHide(omObjData *object);
static void OutputModeDisp(omObjData *object);
static void OutputModeHide(omObjData *object);
static void MusicPageDisp(omObjData *object, s32 page);
static void MusicPageHide(omObjData *object);
static void VoicePageDisp(omObjData *object, s32 character);
static void VoicePageHide(omObjData *object);
static omObjData *CreateNoteObj(s32 type);
static void KillNote(omObjData *note);
static void HandleNote(omObjData *note);
static void CreateNote(omObjData *object, s32 type, s32 side, s32 color);
static void CreateNoteSpawner(omObjData *object);
static void KillNoteSpawner(omObjData *object);
static void ExecNoteSpawner(void);
static void OptionPlaySound(omObjData *object);
static void FadeSound(omObjData *object);
omObjData *optionSound;
static const s32 musicPageNameTbl[] = {
MAKE_MESSID(47, 70),
MAKE_MESSID(47, 81),
MAKE_MESSID(47, 172),
MAKE_MESSID(47, 92),
MAKE_MESSID(47, 101),
MAKE_MESSID(47, 109),
MAKE_MESSID(47, 119),
MAKE_MESSID(47, 173),
MAKE_MESSID(47, 174),
MAKE_MESSID(47, 129),
MAKE_MESSID(47, 140),
MAKE_MESSID(47, 149),
MAKE_MESSID(47, 156),
MAKE_MESSID(47, 176),
};
static const SndSelData musicTbl[14][10] = {
{
{ TRUE, MAKE_MESSID(47, 71), 1, 0, 20 },
{ TRUE, MAKE_MESSID(47, 72), 2, 79, 43 },
{ TRUE, MAKE_MESSID(47, 73), 3, 81, 44 },
{ TRUE, MAKE_MESSID(47, 74), 29, 80, 45 },
{ TRUE, MAKE_MESSID(47, 76), 30, 82, 47 },
{ TRUE, MAKE_MESSID(47, 78), 1, 0, 12 },
{ TRUE, MAKE_MESSID(47, 77), 4, 83, 48 },
{ TRUE, MAKE_MESSID(47, 80), 11, 90, 40 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 79), 1, 0, 5 },
{ TRUE, MAKE_MESSID(47, 170), 33, 0, 12 },
{ TRUE, MAKE_MESSID(47, 82), 33, 0, 7 },
{ TRUE, MAKE_MESSID(47, 83), 33, 0, 4 },
{ TRUE, MAKE_MESSID(47, 171), 33, 0, 10 },
{ TRUE, MAKE_MESSID(47, 84), 33, 0, 9 },
{ TRUE, MAKE_MESSID(47, 85), 33, 0, 1 },
{ TRUE, MAKE_MESSID(47, 86), 33, 0, 3 },
{ TRUE, MAKE_MESSID(47, 87), 33, 0, 2 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 88), 33, 0, 5 },
{ TRUE, MAKE_MESSID(47, 89), 33, 0, 6 },
{ TRUE, MAKE_MESSID(47, 90), 33, 0, 11 },
{ TRUE, MAKE_MESSID(47, 91), 33, 0, 8 },
{ TRUE, MAKE_MESSID(47, 125), 1, 0, 2 },
{ TRUE, MAKE_MESSID(47, 126), 1, 0, 6 },
{ TRUE, MAKE_MESSID(47, 127), 1, 0, 9 },
{ TRUE, MAKE_MESSID(47, 128), 1, 0, 10 },
{ TRUE, MAKE_MESSID(47, 124), 12, 93, 49 },
{ TRUE, MAKE_MESSID(47, 123), 12, 93, 50 },
},
{
{ TRUE, MAKE_MESSID(47, 93), 5, 84, 13 },
{ TRUE, MAKE_MESSID(47, 94), 5, 84, 14 },
{ TRUE, MAKE_MESSID(47, 95), 5, 84, 15 },
{ TRUE, MAKE_MESSID(47, 96), 5, 84, 16 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 97), 6, 85, 17 },
{ TRUE, MAKE_MESSID(47, 98), 6, 85, 18 },
{ TRUE, MAKE_MESSID(47, 99), 6, 85, 19 },
{ TRUE, MAKE_MESSID(47, 100), 6, 85, 20 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 102), 7, 86, 21 },
{ TRUE, MAKE_MESSID(47, 103), 7, 86, 22 },
{ TRUE, MAKE_MESSID(47, 104), 7, 86, 23 },
{ TRUE, MAKE_MESSID(47, 105), 7, 86, 24 },
{ TRUE, MAKE_MESSID(47, 106), 7, 86, 25 },
{ TRUE, MAKE_MESSID(47, 107), 7, 86, 26 },
{ TRUE, MAKE_MESSID(47, 108), 7, 86, 27 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 110), 8, 87, 28 },
{ TRUE, MAKE_MESSID(47, 111), 8, 87, 30 },
{ TRUE, MAKE_MESSID(47, 112), 8, 87, 29 },
{ TRUE, MAKE_MESSID(47, 113), 8, 87, 31 },
{ TRUE, MAKE_MESSID(47, 114), 8, 87, 32 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 115), 9, 88, 33 },
{ TRUE, MAKE_MESSID(47, 116), 9, 88, 34 },
{ TRUE, MAKE_MESSID(47, 117), 9, 88, 35 },
{ TRUE, MAKE_MESSID(47, 118), 9, 88, 36 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 120), 10, 89, 37 },
{ TRUE, MAKE_MESSID(47, 121), 10, 89, 38 },
{ TRUE, MAKE_MESSID(47, 122), 10, 89, 39 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 130), 13, 94, 59 },
{ TRUE, MAKE_MESSID(47, 131), 13, 94, 57 },
{ TRUE, MAKE_MESSID(47, 132), 14, 95, 67 },
{ TRUE, MAKE_MESSID(47, 133), 15, 96, 68 },
{ TRUE, MAKE_MESSID(47, 134), 16, 97, 69 },
{ TRUE, MAKE_MESSID(47, 135), 17, 98, 70 },
{ TRUE, MAKE_MESSID(47, 136), 18, 99, 71 },
{ TRUE, MAKE_MESSID(47, 137), 19, 100, 72 },
{ TRUE, MAKE_MESSID(47, 138), 20, 101, 73 },
{ TRUE, MAKE_MESSID(47, 139), 21, 102, 74 },
},
{
{ TRUE, MAKE_MESSID(47, 141), 22, 103, 75 },
{ TRUE, MAKE_MESSID(47, 142), 23, 104, 76 },
{ TRUE, MAKE_MESSID(47, 143), 24, 105, 77 },
{ TRUE, MAKE_MESSID(47, 144), 13, 94, 58 },
{ TRUE, MAKE_MESSID(47, 175), 13, 94, 60 },
{ TRUE, MAKE_MESSID(47, 145), 1, 0, 1 },
{ TRUE, MAKE_MESSID(47, 146), 1, 0, 3 },
{ TRUE, MAKE_MESSID(47, 147), 1, 0, 4 },
{ TRUE, MAKE_MESSID(47, 148), 1, 0, 11 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 152), 25, 106, 61 },
{ TRUE, MAKE_MESSID(47, 150), 25, 106, 62 },
{ TRUE, MAKE_MESSID(47, 151), 25, 106, 63 },
{ TRUE, MAKE_MESSID(47, 155), 26, 107, 65 },
{ TRUE, MAKE_MESSID(47, 153), 26, 107, 64 },
{ TRUE, MAKE_MESSID(47, 154), 26, 107, 66 },
{ TRUE, MAKE_MESSID(47, 164), 1, 0, 13 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 157), 27, 108, 51 },
{ TRUE, MAKE_MESSID(47, 158), 27, 108, 53 },
{ TRUE, MAKE_MESSID(47, 159), 27, 108, 54 },
{ TRUE, MAKE_MESSID(47, 160), 27, 108, 52 },
{ TRUE, MAKE_MESSID(47, 161), 27, 108, 55 },
{ TRUE, MAKE_MESSID(47, 162), 27, 108, 56 },
{ TRUE, MAKE_MESSID(47, 163), 1, 0, 7 },
{ TRUE, MAKE_MESSID(47, 165), 1, 0, 22 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 177), 32, 92, 46 },
{ TRUE, MAKE_MESSID(47, 178), 31, 91, 41 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
{ FALSE, MAKE_MESSID(47, 69), 0, 0, 0 },
},
};
static const s32 voiceCharNameTbl[12] = {
MAKE_MESSID(0, 0),
MAKE_MESSID(0, 1),
MAKE_MESSID(0, 2),
MAKE_MESSID(0, 3),
MAKE_MESSID(0, 4),
MAKE_MESSID(0, 5),
MAKE_MESSID(0, 6),
MAKE_MESSID(0, 7),
MAKE_MESSID(47, 34),
MAKE_MESSID(47, 44),
MAKE_MESSID(47, 55),
MAKE_MESSID(47, 62),
};
static const SndSelData voiceTbl[12][10] = {
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2217 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2219 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2216 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2223 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2220 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2221 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2222 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2218 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2208 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2210 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2207 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2214 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2211 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2212 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2213 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2209 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2226 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2228 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2225 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2232 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2229 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2230 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2231 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2227 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2253 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2255 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2252 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2259 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2256 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2257 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2258 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2254 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2244 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2246 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2243 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2250 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2247 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2248 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2249 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2245 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2199 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2201 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2198 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2205 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2202 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2203 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2204 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2200 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2190 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2192 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2189 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2196 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2193 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2194 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2195 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2191 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 26), 28, 109, 2235 },
{ TRUE, MAKE_MESSID(47, 27), 28, 109, 2237 },
{ TRUE, MAKE_MESSID(47, 28), 28, 109, 2234 },
{ TRUE, MAKE_MESSID(47, 29), 28, 109, 2241 },
{ TRUE, MAKE_MESSID(47, 30), 28, 109, 2238 },
{ TRUE, MAKE_MESSID(47, 31), 28, 109, 2239 },
{ TRUE, MAKE_MESSID(47, 32), 28, 109, 2240 },
{ TRUE, MAKE_MESSID(47, 33), 28, 109, 2236 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 35), 28, 109, 54 },
{ TRUE, MAKE_MESSID(47, 36), 28, 109, 55 },
{ TRUE, MAKE_MESSID(47, 37), 28, 109, 56 },
{ TRUE, MAKE_MESSID(47, 38), 28, 109, 67 },
{ TRUE, MAKE_MESSID(47, 39), 28, 109, 68 },
{ TRUE, MAKE_MESSID(47, 40), 28, 109, 69 },
{ TRUE, MAKE_MESSID(47, 41), 28, 109, 64 },
{ TRUE, MAKE_MESSID(47, 42), 28, 109, 65 },
{ TRUE, MAKE_MESSID(47, 43), 28, 109, 66 },
{ FALSE, MAKE_MESSID(47, 24), 0, 0, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 45), 28, 109, 75 },
{ TRUE, MAKE_MESSID(47, 46), 28, 109, 76 },
{ TRUE, MAKE_MESSID(47, 47), 28, 109, 77 },
{ TRUE, MAKE_MESSID(47, 48), 28, 109, 70 },
{ TRUE, MAKE_MESSID(47, 49), 28, 109, 71 },
{ TRUE, MAKE_MESSID(47, 50), 28, 109, 72 },
{ TRUE, MAKE_MESSID(47, 51), 28, 109, 58 },
{ TRUE, MAKE_MESSID(47, 52), 28, 109, 59 },
{ TRUE, MAKE_MESSID(47, 53), 28, 109, 60 },
{ TRUE, MAKE_MESSID(47, 54), 28, 109, 61 },
},
{
{ TRUE, MAKE_MESSID(47, 56), 28, 109, 62 },
{ TRUE, MAKE_MESSID(47, 57), 28, 109, 63 },
{ TRUE, MAKE_MESSID(47, 58), 28, 109, 79 },
{ TRUE, MAKE_MESSID(47, 59), 28, 109, 80 },
{ TRUE, MAKE_MESSID(47, 60), 28, 109, 73 },
{ TRUE, MAKE_MESSID(47, 61), 28, 109, 74 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
{
{ TRUE, MAKE_MESSID(47, 63), 28, 109, 36 },
{ TRUE, MAKE_MESSID(47, 64), 28, 109, 37 },
{ TRUE, MAKE_MESSID(47, 65), 28, 109, 38 },
{ TRUE, MAKE_MESSID(47, 67), 28, 109, 40 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
{ FALSE, MAKE_MESSID(47, 24), 28, 109, 0 },
},
};
static BOOL musicPageOn[14] = { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE };
static omObjFunc execModeTbl[] = { NULL, ExecZoom, ExecOptionSel, ExecOutputMode, ExecMusic, ExecVoice };
static s32 choiceMess[] = { MAKE_MESSID(47, 8), MAKE_MESSID(47, 10), MAKE_MESSID(47, 9) };
omObjData *OptionSoundCreate(void)
{
omObjData *object;
SoundWork *work;
s32 i;
object = omAddObjEx(optionObjMan, 1003, 0, 0, 1, NULL);
work = HuMemDirectMallocNum(HEAP_SYSTEM, sizeof(SoundWork), MEMORY_DEFAULT_NUM);
object->data = work;
work->selectedOption = 0;
work->doneF = FALSE;
work->optionSelected = FALSE;
work->bgMusicStat = -2;
work->seqStat = -1;
work->streamStat = -1;
work->fxStat = -1;
work->noteSpawner = NULL;
switch (GWGameStat.sound_mode) {
case 0:
work->soundMode = SOUND_MODE_MONO;
break;
case 2:
default:
work->soundMode = SOUND_MODE_STEREO;
break;
}
work->object[0] = CreateSystem();
for (i = 0; i < 6; i++) {
work->object[i + 1] = CreateLightObj(i % 3, (i / 3) > 0);
}
LightSetNone(object);
work->object[7] = CreateHand();
work->object[8] = CreateOutputModeHand();
for (i = 0; i < NUM_NOTES; i++) {
work->object[i + 10] = CreateNoteObj((i / 8) == 0 ? NOTE_TYPE_QUAVER : NOTE_TYPE_QUARTER);
}
CreateSpr(object);
OptionSoundExecModeSet(object, MODE_DISABLED);
for (i = 0; i < NUM_BOARDS; i++) {
musicPageOn[i + 3] = (GWGameStat.board_play_count[i] != 0) ? TRUE : FALSE;
}
musicPageOn[11] = (GWGameStat.musicAllF != 0) ? TRUE : FALSE;
musicPageOn[12] = (GWGameStat.musicAllF != 0) ? TRUE : FALSE;
musicPageOn[13] = (GWGameStat.musicAllF != 0) ? TRUE : FALSE;
return object;
}
void OptionSoundKill(omObjData *object)
{
SoundWork *work = object->data;
s32 i;
KillHand(work->object[7]);
KillOutputModeHand(work->object[8]);
KillSystem(work->object[0]);
for (i = 0; i < 6; i++) {
KillLightObj(work->object[i + 1]);
}
for (i = 0; i < 16; i++) {
KillNote(work->object[i + 10]);
}
KillSpr(object);
HuMemDirectFree(work);
}
void OptionSoundExecModeSet(omObjData *object, s32 execMode)
{
SoundWork *work = object->data;
work->execMode = execMode;
object->func = execModeTbl[execMode];
object->unk10 = 0;
object->unk10 = 0;
}
s32 OptionSoundExecModeGet(omObjData *object)
{
SoundWork *work = object->data;
return work->execMode;
}
static void ExecZoom(omObjData *object)
{
SoundWork *work = object->data;
s32 i;
switch (object->unk10) {
case 0:
if (!work->doneF) {
work->window[0] = OptionWinCreate(0);
work->window[1] = OptionWinCreate(1);
work->window[2] = OptionWinCreate(2);
for (i = 0; i < 10; i++) {
work->window[i + 3] = OptionWinCreate(3);
}
OptionCameraFocusSet(optionCamera, 0.0f, 120.0f, -600.0f, 0x28);
OptionCameraTargetSet(optionCamera, 0.0f, 120.0f, -350.0f, 0x28);
work->doneF = TRUE;
work->selectedOption = 0;
work->optionSelected = FALSE;
object->unk10 = 1;
}
else {
object->unk10 = 2;
}
break;
case 1:
if (OptionCameraDoneCheck(optionCamera) == 0) {
OptionSoundExecModeSet(object, MODE_HANDLE_OPTION_SEL);
}
break;
case 2:
for (i = 0; i < 13; i++) {
OptionWinKill(work->window[i]);
}
OptionCameraFocusSet(optionCamera, 0.0f, 120.0f, -600.0f, 0x28);
OptionCameraTargetSet(optionCamera, 0.0f, 120.0f, 0.0f, 0x28);
work->doneF = FALSE;
work->optionSelected = FALSE;
OptionSoundExecModeSet(object, MODE_DISABLED);
break;
}
}
static void ExecOptionSel(omObjData *object)
{
SoundWork *work = object->data;
switch (object->unk10) {
case 0:
LightSetNone(object);
work->cursorPos = work->selectedOption;
if (!work->optionSelected) {
OptionRumbleMotionShowStart(optionRumble);
}
else {
OutputModeHide(object);
MusicPageHide(object);
VoicePageHide(object);
}
work->optionSelected = FALSE;
work->cameraDoneF = FALSE;
object->unk10 = 1;
/* fallthrough */
case 1:
OptionSelDisp(object);
OptionWinAnimIn(work->window[1]);
OptionWinMesSet(work->window[1], MAKE_MESSID(47, 168));
OptionWinAnimIn(work->window[0]);
OptionWinMesSet(work->window[0], choiceMess[work->cursorPos]);
if (!work->cameraDoneF) {
Hu3DModelAttrReset(work->object[7]->model[0], HU3D_ATTR_DISPOFF);
work->cameraDoneF = TRUE;
}
omSetTra(work->object[7], -34.0f + 40.0f * work->cursorPos, 120.0f, -500.0f);
object->unk10 = 2;
/* fallthrough */
case 2:
if (work->window[0]->state == 0 && work->window[1]->state == 0) {
if (OptionPadCheck(PAD_BUTTON_A)) {
work->selectedOption = work->cursorPos;
work->optionSelected = TRUE;
LightSetCurr(object, work->selectedOption);
HuAudFXPlay(2);
object->unk10 = 3;
}
else if (OptionPadCheck(PAD_BUTTON_B)) {
HuAudFXPlay(3);
object->unk10 = 3;
}
else if (OptionPadDStkRepCheck(1) && work->cursorPos > 0) {
work->cursorPos--;
HuAudFXPlay(0);
object->unk10 = 1;
}
else if (OptionPadDStkRepCheck(2) && work->cursorPos < 2) {
work->cursorPos++;
HuAudFXPlay(0);
object->unk10 = 1;
}
}
break;
case 3:
OptionWinAnimOut(work->window[1]);
OptionWinAnimOut(work->window[0]);
if (!work->optionSelected) {
OptionRumbleMotionHideStart(optionRumble);
}
Hu3DModelAttrSet(work->object[7]->model[0], HU3D_ATTR_DISPOFF);
object->unk10 = 4;
/* fallthrough */
case 4:
if ((work->optionSelected || !OptionRumbleMotionCheck(optionRumble)) && work->window[0]->state == 0 && work->window[1]->state == 0) {
if (work->optionSelected) {
switch (work->selectedOption) {
case 0:
OptionSoundExecModeSet(object, MODE_HANDLE_SOUND);
break;
case 1:
OptionSoundExecModeSet(object, MODE_HANDLE_MUSIC);
break;
case 2:
OptionSoundExecModeSet(object, MODE_HANDLE_VOICE);
break;
}
}
else {
OptionSelHide(object);
OptionSoundExecModeSet(object, MODE_HANDLE_INITIAL_SCREEN);
}
}
break;
}
}
static const s32 outputModeTbl[] = { 2, 0 };
static const s32 soundModeTbl[] = { 1, 0 };
static const s32 soundModeNameTbl[] = { MAKE_MESSID(47, 11), MAKE_MESSID(47, 12) };
static void ExecOutputMode(omObjData *object)
{
SoundWork *work = object->data;
Vec pos;
switch (object->unk10) {
case 0:
OptionSelHide(object);
work->optionSelected = FALSE;
work->cursorPos = work->soundMode;
work->cameraDoneF = FALSE;
work->optionSelected = FALSE;
CreateNoteSpawner(object);
object->unk10 = 1;
/* fallthrough */
case 1:
OutputModeDisp(object);
OptionWinAnimIn(work->window[1]);
OptionWinMesSet(work->window[1], MAKE_MESSID(47, 168));
OptionWinAnimIn(work->window[0]);
OptionWinMesSet(work->window[0], soundModeNameTbl[work->soundMode]);
if (!work->cameraDoneF) {
Hu3DModelAttrReset(work->object[8]->model[0], HU3D_ATTR_DISPOFF);
work->cameraDoneF = TRUE;
}
pos.x = -38.0f;
pos.y = 140.0f - 15.0f * work->cursorPos;
pos.z = -500.0f;
omSetTra(work->object[8], pos.x, pos.y, pos.z);
object->unk10 = 2;
/* fallthrough */
case 2:
if (work->window[0]->state == 0 && work->window[1]->state == 0) {
if (OptionPadCheck(PAD_BUTTON_A)) {
work->soundMode = work->cursorPos;
if (work->soundMode == SOUND_MODE_STEREO) {
HuAudFXPlay(0x841);
}
else {
HuAudFXPlay(0x842);
}
GWGameStat.sound_mode = outputModeTbl[work->cursorPos];
msmSysSetOutputMode(outputModeTbl[work->cursorPos]);
OSSetSoundMode(soundModeTbl[work->cursorPos]);
work->optionSelected = TRUE;
OutputModeDisp(object);
work->changeTimer = 0;
object->unk10 = 3;
}
else if (OptionPadCheck(PAD_BUTTON_B)) {
HuAudFXPlay(3);
object->unk10 = 4;
}
else if (OptionPadDStkRepCheck(8) != 0 && work->cursorPos > 0) {
work->cursorPos--;
HuAudFXPlay(0);
object->unk10 = 1;
}
else if (OptionPadDStkRepCheck(4) != 0 && work->cursorPos < 1) {
work->cursorPos++;
HuAudFXPlay(0);
object->unk10 = 1;
}
}
break;
case 3:
if (work->changeTimer++ >= 60) {
object->unk10 = 4;
return;
}
break;
case 4:
KillNoteSpawner(object);
OptionWinAnimOut(work->window[1]);
OptionWinAnimOut(work->window[0]);
Hu3DModelAttrSet(work->object[8]->model[0], HU3D_ATTR_DISPOFF);
object->unk10 = 5;
/* fallthrough */
case 5:
if (work->window[0]->state == 0 && work->window[1]->state == 0) {
work->optionSelected = FALSE;
OutputModeDisp(object);
work->optionSelected = TRUE;
OptionSoundExecModeSet(object, MODE_HANDLE_OPTION_SEL);
}
break;
}
}
static void ExecMusic(omObjData *object)
{
SoundWork *work = object->data;
float oldX;
float oldY;
float x;
float y;
float newX;
float newY;
s32 i;
s32 cursorPosNew;
s32 cursorPosOld;
cursorPosOld = work->cursorPos;
switch (object->unk10) {
case 0:
OptionSelHide(object);
work->page = 0;
work->cursorDelta = 0;
work->pageDelta = 0;
espBankSet(work->sprite[14], 0);
espBankSet(work->sprite[15], 2);
espPosSet(work->sprite[14], 36.0f, 222.0f);
espPosSet(work->sprite[15], 544.0f, 222.0f);
OptionFadeSprite(work->sprite[14], 1, 5);
OptionFadeSprite(work->sprite[15], 1, 5);
work->cursorDelay = 0;
object->unk10 = 1;
/* fallthrough */
case 1:
work->cursorPos = 0;
work->prevCursorPos = 0;
if (work->pageDelta != 0) {
do {
work->page += work->pageDelta;
if (work->page >= 14) {
work->page = 0;
}
else if (work->page < 0) {
work->page = 13;
}
} while (!musicPageOn[work->page]);
HuAudFXPlay(0x840);
if (work->pageDelta > 0) {
espBankSet(work->sprite[15], 3);
}
else {
espBankSet(work->sprite[14], 1);
}
work->cursorDelay = 5;
work->pageDelta = 0;
}
object->unk10 = 2;
/* fallthrough */
case 2:
if (work->cursorDelta != 0) {
cursorPosNew = work->cursorPos + work->cursorDelta;
if (cursorPosNew > 9) {
cursorPosNew = 9;
}
else if (cursorPosNew < 0) {
cursorPosNew = 0;
}
if (!musicTbl[work->page][cursorPosNew].enabled) {
if (work->cursorPos < 5) {
for (i = cursorPosNew; i >= 5; i--) {
if (musicTbl[work->page][i].enabled) {
cursorPosNew = i;
break;
}
}
if (i < 5) {
cursorPosNew = work->cursorPos;
}
}
else {
cursorPosNew = work->cursorPos;
}
}
work->prevCursorPos = work->cursorPos;
if (work->cursorPos != cursorPosNew) {
work->cursorPos = cursorPosNew;
HuAudFXPlay(0x840);
}
work->cursorDelta = 0;
}
object->unk10 = 3;
/* fallthrough */
case 3:
MusicPageDisp(object, work->page);
OptionWinAnimIn(work->window[0]);
OptionWinMesSet(work->window[0], MAKE_MESSID(47, 10));
OptionWinAnimIn(work->window[1]);
OptionWinMesSet(work->window[1], MAKE_MESSID(47, 18));
espDispOn(work->sprite[18]);
work->cursorTime = 0.0f;
work->cursorSpeed = 0.0625f;
if (work->cursorDelay > 0) {
object->unk10 = 5;
}
else {
object->unk10 = 4;
}
/* fallthrough */
case 4:
oldX = 166.0f + 244.0f * (work->prevCursorPos / 5);
oldY = 144.0f + 29.0f * (work->prevCursorPos % 5);
newX = 166.0f + 244.0f * (work->cursorPos / 5);
newY = 144.0f + 29.0f * (work->cursorPos % 5);
x = oldX + work->cursorTime * (newX - oldX);
y = oldY + work->cursorTime * (newY - oldY);
espPosSet(work->sprite[18], x, y);
if ((work->cursorTime += work->cursorSpeed) < 1.0f) {
break;
}
espPosSet(work->sprite[18], 166.0f + 244.0f * (work->cursorPos / 5), 144.0f + 29.0f * (work->cursorPos % 5));
object->unk10 = 6;
break;
case 5:
if (work->cursorDelay > 0) {
work->cursorDelay--;
break;
}
espBankSet(work->sprite[14], 0);
espBankSet(work->sprite[15], 2);
object->unk10 = 6;
/* fallthrough */
case 6:
if (work->window[0]->state == 0 && work->window[1]->state == 0) {
if (OptionPadCheck(PAD_BUTTON_A)) {
if (work->bgMusicStat == -2) {
HuAudFadeOut(0x64);
work->bgMusicStat = -1;
}
else if (work->bgMusicStat != -1) {
HuAudSeqFadeOut(work->bgMusicStat, 0x64);
work->bgMusicStat = -1;
}
OptionPlaySound(object);
}
else if (OptionPadCheck(PAD_BUTTON_B)) {
HuAudFXPlay(3);
work->changeTimer = 0;
object->unk10 = 7;
}
else {
if (OptionPadDStkCheck(1) != 0 && work->cursorPos >= 5) {
work->cursorDelta -= 5;
}
else if (OptionPadDStkCheck(2) != 0 && work->cursorPos < 5) {
work->cursorDelta += 5;
}
if (OptionPadDStkCheck(8) != 0 && work->cursorPos % 5 > 0) {
work->cursorDelta--;
}
else if (OptionPadDStkCheck(4) != 0 && work->cursorPos % 5 < 4) {
work->cursorDelta++;
}
if (work->cursorDelta != 0) {
object->unk10 = 2;
}
else if (OptionPadCheck(PAD_TRIGGER_L)) {
work->pageDelta = -1;
}
else if (OptionPadCheck(PAD_TRIGGER_R)) {
work->pageDelta = 1;
}
if (work->pageDelta != 0) {
object->unk10 = 1;
}
}
}
break;
case 7:
OptionWinAnimOut(work->window[1]);
OptionWinAnimOut(work->window[0]);
FadeSound(object);
OptionFadeSprite(work->sprite[14], 0, 5);
OptionFadeSprite(work->sprite[15], 0, 5);
object->unk10 = 8;
/* fallthrough */
case 8:
if (work->window[0]->state == 0 && work->window[1]->state == 0) {
espDispOff(work->sprite[18]);
if (work->bgMusicStat == -1) {
work->bgMusicStat = HuAudSeqPlay(0x2D);
}
OptionSoundExecModeSet(object, MODE_HANDLE_OPTION_SEL);
}
break;
}
}
static void ExecVoice(omObjData *object)
{
SoundWork *work = object->data;
float oldX;
float oldY;
float x;
float y;
float newX;
float newY;
s32 i;
s32 cursorPosNew;
switch (object->unk10) {
case 0:
OptionSelHide(object);
work->page = 0;
work->cursorDelta = 0;
work->pageDelta = 0;
espBankSet(work->sprite[14], 0);
espBankSet(work->sprite[15], 2);
espPosSet(work->sprite[14], 36.0f, 222.0f);
espPosSet(work->sprite[15], 544.0f, 222.0f);
OptionFadeSprite(work->sprite[14], 1, 5);
OptionFadeSprite(work->sprite[15], 1, 5);
work->cursorDelay = 0;
object->unk10 = 3;
/* fallthrough */
case 1:
work->cursorPos = 0;
work->prevCursorPos = 0;
if (work->pageDelta != 0) {
work->page += work->pageDelta;
if (work->page > 11) {
work->page = 0;
}
else if (work->page < 0) {
work->page = 11;
}
HuAudFXPlay(0x840);
if (work->pageDelta > 0) {
espBankSet(work->sprite[15], 3);
}
else {
espBankSet(work->sprite[14], 1);
}
work->cursorDelay = 5;
work->pageDelta = 0;
}
object->unk10 = 2;
/* fallthrough */
case 2:
if (work->cursorDelta != 0) {
cursorPosNew = work->cursorPos + work->cursorDelta;
if (cursorPosNew > 9) {
cursorPosNew = 9;
}
else if (cursorPosNew < 0) {
cursorPosNew = 0;
}
if (!voiceTbl[work->page][cursorPosNew].enabled) {
if (work->cursorPos < 5) {
for (i = cursorPosNew; i >= 5; i--) {
if (voiceTbl[work->page][i].enabled) {
cursorPosNew = i;
break;
}
}
if (i < 5) {
cursorPosNew = work->cursorPos;
}
}
else {
cursorPosNew = work->cursorPos;
}
}
work->prevCursorPos = work->cursorPos;
if (work->cursorPos != cursorPosNew) {
work->cursorPos = cursorPosNew;
HuAudFXPlay(0x840);
}
work->cursorDelta = 0;
}
object->unk10 = 3;
/* fallthrough */
case 3:
VoicePageDisp(object, work->page);
OptionWinAnimIn(work->window[0]);
OptionWinMesSet(work->window[0], MAKE_MESSID(47, 9));
OptionWinAnimIn(work->window[1]);
OptionWinMesSet(work->window[1], MAKE_MESSID(47, 18));
espDispOn(work->sprite[18]);
work->cursorTime = 0.0f;
work->cursorSpeed = 0.0625f;
if (work->cursorDelay > 0) {
object->unk10 = 5;
}
else {
object->unk10 = 4;
}
/* fallthrough */
case 4:
oldX = 166.0f + 244.0f * (work->prevCursorPos / 5);
oldY = 144.0f + 29.0f * (work->prevCursorPos % 5);
newX = 166.0f + 244.0f * (work->cursorPos / 5);
newY = 144.0f + 29.0f * (work->cursorPos % 5);
x = oldX + work->cursorTime * (newX - oldX);
y = oldY + work->cursorTime * (newY - oldY);
espPosSet(work->sprite[18], x, y);
if ((work->cursorTime += work->cursorSpeed) < 1.0f) {
break;
}
espPosSet(work->sprite[18], 166.0f + 244.0f * (work->cursorPos / 5), 144.0f + 29.0f * (work->cursorPos % 5));
object->unk10 = 6;
break;
case 5:
if (work->cursorDelay > 0) {
work->cursorDelay--;
break;
}
espBankSet(work->sprite[14], 0);
espBankSet(work->sprite[15], 2);
object->unk10 = 6;
/* fallthrough */
case 6:
if (work->window[0]->state == 0 && work->window[1]->state == 0) {
if (OptionPadCheck(PAD_BUTTON_A)) {
OptionPlaySound(object);
}
else if (OptionPadCheck(PAD_BUTTON_B)) {
HuAudFXPlay(3);
work->changeTimer = 0;
object->unk10 = 7;
}
else {
if (OptionPadDStkCheck(1) != 0 && work->cursorPos >= 5) {
work->cursorDelta -= 5;
}
else if (OptionPadDStkCheck(2) != 0 && work->cursorPos < 5) {
work->cursorDelta += 5;
}
if (OptionPadDStkCheck(8) != 0 && work->cursorPos % 5 > 0) {
work->cursorDelta--;
}
else if (OptionPadDStkCheck(4) != 0 && work->cursorPos % 5 < 4) {
work->cursorDelta++;
}
if (work->cursorDelta != 0) {
object->unk10 = 2;
}
else if (OptionPadCheck(PAD_TRIGGER_L)) {
work->pageDelta = -1;
}
else if (OptionPadCheck(PAD_TRIGGER_R)) {
work->pageDelta = 1;
}
if (work->pageDelta != 0) {
object->unk10 = 1;
}
}
}
break;
case 7:
OptionWinAnimOut(work->window[1]);
OptionWinAnimOut(work->window[0]);
FadeSound(object);
OptionFadeSprite(work->sprite[14], 0, 5);
OptionFadeSprite(work->sprite[15], 0, 5);
object->unk10 = 8;
/* fallthrough */
case 8:
if (work->window[0]->state == 0 && work->window[1]->state == 0) {
espDispOff(work->sprite[18]);
OptionSoundExecModeSet(object, MODE_HANDLE_OPTION_SEL);
}
break;
}
}
static void LightSetCurr(omObjData *object, s32 id)
{
SoundWork *work = object->data;
switch (id) {
case 0:
LightDispOff(work->object[1]);
LightDispOff(work->object[5]);
LightDispOff(work->object[6]);
LightDispOn(work->object[4]);
LightDispOn(work->object[2]);
LightDispOn(work->object[3]);
break;
case 1:
LightDispOff(work->object[4]);
LightDispOff(work->object[2]);
LightDispOff(work->object[6]);
LightDispOn(work->object[1]);
LightDispOn(work->object[5]);
LightDispOn(work->object[3]);
break;
case 2:
LightDispOff(work->object[4]);
LightDispOff(work->object[5]);
LightDispOff(work->object[3]);
LightDispOn(work->object[1]);
LightDispOn(work->object[2]);
LightDispOn(work->object[6]);
break;
}
}
static void LightSetNone(omObjData *object)
{
SoundWork *work = object->data;
LightDispOff(work->object[4]);
LightDispOff(work->object[5]);
LightDispOff(work->object[6]);
LightDispOn(work->object[1]);
LightDispOn(work->object[2]);
LightDispOn(work->object[3]);
}
static omObjData *CreateHand(void)
{
omObjData *object;
object = omAddObjEx(optionObjMan, 1003, 1, 0, 1, NULL);
object->model[0] = Hu3DModelCreateFile(DATA_MAKE_NUM(DATADIR_OPTION, 13));
Hu3DModelLayerSet(object->model[0], 2);
Hu3DModelAttrSet(object->model[0], HU3D_MOTATTR_LOOP);
omSetRot(object, -80.0f, 45.0f, 0.0f);
omSetSca(object, 0.6f, 0.6f, 0.6f);
Hu3DModelAttrSet(object->model[0], HU3D_ATTR_DISPOFF);
return object;
}
static void KillHand(omObjData *object)
{
s32 i;
for (i = 0; i < 1; i++) {
Hu3DModelKill(object->model[i]);
}
}
static omObjData *CreateOutputModeHand(void)
{
omObjData *object;
object = omAddObjEx(optionObjMan, 1003, 1, 0, 1, NULL);
object->model[0] = Hu3DModelCreateFile(DATA_MAKE_NUM(DATADIR_OPTION, 14));
Hu3DModelLayerSet(object->model[0], 2);
Hu3DModelAttrSet(object->model[0], HU3D_MOTATTR_LOOP);
omSetRot(object, 0.0f, -90.0f, 0.0f);
omSetSca(object, 0.6f, 0.6f, 0.6f);
Hu3DModelAttrSet(object->model[0], HU3D_ATTR_DISPOFF);
return object;
}
static void KillOutputModeHand(omObjData *object)
{
s32 i;
for (i = 0; i < 1; i++) {
Hu3DModelKill(object->model[i]);
}
}
static omObjData *CreateSystem(void)
{
omObjData *system;
system = omAddObjEx(optionObjMan, 1003, 1, 0, 1, NULL);
system->model[0] = Hu3DModelCreateFile(DATA_MAKE_NUM(DATADIR_OPTION, 3));
Hu3DModelAttrSet(system->model[0], HU3D_MOTATTR_LOOP);
Hu3DModelLayerSet(system->model[0], 0);
return system;
}
static void KillSystem(omObjData *system)
{
s32 i;
for (i = 0; i < 1; i++) {
Hu3DModelKill(system->model[i]);
}
}
static const Vec lightPosTbl[3] = { { -40.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 40.0f, 0.0f, 0.0f } };
static omObjData *CreateLightObj(s32 id, BOOL off)
{
omObjData *object;
object = omAddObjEx(optionObjMan, 1003, 1, 0, 1, NULL);
if (off) {
object->model[0] = Hu3DModelCreateFile(DATA_MAKE_NUM(DATADIR_OPTION, 5));
}
else {
object->model[0] = Hu3DModelCreateFile(DATA_MAKE_NUM(DATADIR_OPTION, 4));
}
Hu3DModelAttrSet(object->model[0], HU3D_MOTATTR_LOOP);
Hu3DModelLayerSet(object->model[0], 0);
omSetTra(object, lightPosTbl[id].x, lightPosTbl[id].y, lightPosTbl[id].z);
return object;
}
static void KillLightObj(omObjData *object)
{
s32 i;
for (i = 0; i < 1; i++) {
Hu3DModelKill(object->model[i]);
}
}
static void LightDispOff(omObjData *indicator)
{
Hu3DModelAttrReset(indicator->model[0], HU3D_ATTR_DISPOFF);
}
static void LightDispOn(omObjData *indicator)
{
Hu3DModelAttrSet(indicator->model[0], HU3D_ATTR_DISPOFF);
}
static s32 spriteDataTbl[] = {
DATA_MAKE_NUM(DATADIR_OPTION, 38),
DATA_MAKE_NUM(DATADIR_OPTION, 39),
DATA_MAKE_NUM(DATADIR_OPTION, 40),
DATA_MAKE_NUM(DATADIR_OPTION, 35),
DATA_MAKE_NUM(DATADIR_OPTION, 36),
DATA_MAKE_NUM(DATADIR_OPTION, 37),
DATA_MAKE_NUM(DATADIR_OPTION, 41),
DATA_MAKE_NUM(DATADIR_OPTION, 43),
DATA_MAKE_NUM(DATADIR_OPTION, 42),
DATA_MAKE_NUM(DATADIR_OPTION, 44),
DATA_MAKE_NUM(DATADIR_OPTION, 45),
DATA_MAKE_NUM(DATADIR_OPTION, 46),
DATA_MAKE_NUM(DATADIR_OPTION, 47),
DATA_MAKE_NUM(DATADIR_OPTION, 48),
DATA_MAKE_NUM(DATADIR_OPTION, 49),
DATA_MAKE_NUM(DATADIR_OPTION, 49),
DATA_MAKE_NUM(DATADIR_OPTION, 63),
DATA_MAKE_NUM(DATADIR_OPTION, 64),
DATA_MAKE_NUM(DATADIR_OPTION, 65),
};
static void CreateSpr(omObjData *object)
{
SoundWork *work = object->data;
s32 i;
for (i = 0; i < 19; i++) {
work->sprite[i] = espEntry(spriteDataTbl[i], 0, 0);
espDrawNoSet(work->sprite[i], 0x40);
espDispOff(work->sprite[i]);
}
espBankSet(work->sprite[14], 0);
espBankSet(work->sprite[15], 2);
HuSprExecLayerSet(0x40, 1);
}
static void KillSpr(omObjData *object)
{
SoundWork *work = object->data;
s32 i;
for (i = 0; i < 19; i++) {
espKill(work->sprite[i]);
}
}
static void OptionSelDisp(omObjData *object)
{
SoundWork *work = object->data;
float x = 288.0f;
float y = 188.0f;
espPosSet(work->sprite[12], 288.0f, 72.0f);
espPosSet(work->sprite[0], x + -112.0f, y);
espPosSet(work->sprite[3], x + -112.0f, y);
espPosSet(work->sprite[1], x, y);
espPosSet(work->sprite[4], x, y);
espPosSet(work->sprite[2], x + 112.0f, y);
espPosSet(work->sprite[5], x + 112.0f, y);
espDispOn(work->sprite[12]);
switch (work->cursorPos) {
case 0:
espDispOn(work->sprite[3]);
espDispOn(work->sprite[1]);
espDispOn(work->sprite[2]);
espDispOff(work->sprite[0]);
espDispOff(work->sprite[4]);
espDispOff(work->sprite[5]);
break;
case 1:
espDispOn(work->sprite[0]);
espDispOn(work->sprite[4]);
espDispOn(work->sprite[2]);
espDispOff(work->sprite[3]);
espDispOff(work->sprite[1]);
espDispOff(work->sprite[5]);
break;
case 2:
espDispOn(work->sprite[0]);
espDispOn(work->sprite[1]);
espDispOn(work->sprite[5]);
espDispOff(work->sprite[3]);
espDispOff(work->sprite[4]);
espDispOff(work->sprite[2]);
break;
}
}
static void OptionSelHide(omObjData *object)
{
static const s32 sprHideTbl[] = { 12, 0, 1, 2, 3, 4, 5 };
SoundWork *work = object->data;
s32 i;
for (i = 0; i < 7; i++) {
espDispOff(work->sprite[sprHideTbl[i]]);
}
}
static void OutputModeDisp(omObjData *object)
{
SoundWork *work = object->data;
float x = 290.0f;
float y = 192.0f;
espPosSet(work->sprite[13], 288.0f, 72.0f);
espPosSet(work->sprite[6], x, y - 32.0f);
espPosSet(work->sprite[7], x, y - 32.0f);
espPosSet(work->sprite[8], x, y + 32.0f);
espPosSet(work->sprite[9], x, y + 32.0f);
switch (work->cursorPos) {
case 0:
espPosSet(work->sprite[17], x, y - 32.0f);
break;
case 1:
espPosSet(work->sprite[17], x, y + 32.0f);
break;
}
espDispOn(work->sprite[13]);
switch (work->cursorPos) {
case 0:
espDispOn(work->sprite[6]);
espDispOn(work->sprite[9]);
espDispOff(work->sprite[7]);
espDispOff(work->sprite[8]);
break;
case 1:
espDispOn(work->sprite[7]);
espDispOn(work->sprite[8]);
espDispOff(work->sprite[6]);
espDispOff(work->sprite[9]);
break;
}
if (work->optionSelected) {
espDispOn(work->sprite[17]);
}
else {
espDispOff(work->sprite[17]);
}
}
static void OutputModeHide(omObjData *object)
{
static const s32 sprHideTbl[] = { 13, 6, 7, 8, 9 };
SoundWork *work = object->data;
s32 i;
for (i = 0; i < 5; i++) {
espDispOff(work->sprite[sprHideTbl[i]]);
}
}
static void MusicPageDisp(omObjData *object, s32 page)
{
SoundWork *work = object->data;
s32 i;
espPosSet(work->sprite[10], 288.0f, 72.0f);
espDispOn(work->sprite[10]);
OptionWinDispOn(work->window[2]);
for (i = 0; i < 10; i++) {
OptionWinDispOn(work->window[i + 3]);
OptionWinPosSet(work->window[i + 3], 52.0f + 244.0f * (i / 5), 124.0f + 29.0f * (i % 5));
}
OptionWinMesSet(work->window[2], musicPageNameTbl[page]);
for (i = 0; i < 10; i++) {
OptionWinMesSet(work->window[i + 3], musicTbl[page][i].nameMess);
}
}
static void MusicPageHide(omObjData *object)
{
static const s32 sprHideTbl[] = { 10 };
SoundWork *work = object->data;
s32 i;
for (i = 0; i < 1; i++) {
espDispOff(work->sprite[sprHideTbl[i]]);
}
OptionWinDispOff(work->window[2]);
for (i = 0; i < 10; i++) {
OptionWinDispOff(work->window[i + 3]);
}
}
static void VoicePageDisp(omObjData *object, s32 character)
{
SoundWork *work = object->data;
s32 i;
espPosSet(work->sprite[11], 288.0f, 72.0f);
espDispOn(work->sprite[11]);
OptionWinDispOn(work->window[2]);
for (i = 0; i < 10; i++) {
OptionWinDispOn(work->window[i + 3]);
OptionWinPosSet(work->window[i + 3], 52.0f + 244.0f * (i / 5), 124.0f + 29.0f * (i % 5));
}
OptionWinMesSet(work->window[2], voiceCharNameTbl[character]);
for (i = 0; i < 10; i++) {
OptionWinMesSet(work->window[i + 3], voiceTbl[character][i].nameMess);
}
}
static void VoicePageHide(omObjData *object)
{
static const s32 sprHideTbl[] = { 11, 0 };
SoundWork *work = object->data;
s32 i;
for (i = 0; i < 1; i++) {
espDispOff(work->sprite[sprHideTbl[i]]);
}
OptionWinDispOff(work->window[2]);
for (i = 0; i < 10; i++) {
OptionWinDispOff(work->window[i + 3]);
}
}
static s32 noteMdlTbl[] = { DATA_MAKE_NUM(DATADIR_OPTION, 7), DATA_MAKE_NUM(DATADIR_OPTION, 8) };
static omObjData *CreateNoteObj(s32 type)
{
omObjData *note;
NoteWork *noteWork;
note = omAddObjEx(optionObjMan, 1003, 1, 0, 1, NULL);
noteWork = HuMemDirectMallocNum(HEAP_SYSTEM, sizeof(NoteWork), MEMORY_DEFAULT_NUM);
note->data = noteWork;
noteWork->enabled = FALSE;
noteWork->type = type;
note->model[0] = Hu3DModelCreateFile(noteMdlTbl[type]);
Hu3DModelAttrSet(note->model[0], HU3D_MOTATTR_LOOP);
Hu3DModelLayerSet(note->model[0], 2);
Hu3DModelAttrReset(note->model[0], HU3D_ATTR_ZWRITE_OFF);
return note;
}
static void KillNote(omObjData *note)
{
NoteWork *noteWork = note->data;
s32 i;
for (i = 0; i < 1; i++) {
Hu3DModelKill(note->model[i]);
}
HuMemDirectFree(noteWork);
}
static void HandleNote(omObjData *note)
{
NoteWork *noteWork = note->data;
float time;
float scale;
float angle;
float zRot;
float radius;
float x;
float z;
float y;
float tplvl;
Hu3DModelAttrReset(note->model[0], HU3D_ATTR_DISPOFF);
time = sind(45.0f * noteWork->pos);
time = time * time;
switch (noteWork->side) {
case NOTE_SIDE_LEFT:
angle = 174.5f + 7.0f * time;
zRot = -15.0 + 30.0 * sind(1440.0f * time);
break;
case NOTE_SIDE_RIGHT:
angle = 185.5f - (7.0f * time);
zRot = 15.0 - 30.0 * sind(1440.0f * time);
break;
}
tplvl = sind(180.0f * noteWork->pos);
radius = 500.0f - 25.0f * time;
x = radius * -sind(angle);
z = radius * cosd(angle);
y = 160.0f - 15.0f * noteWork->pos;
scale = 0.5 + 2.0 * sind(90.0f * time);
omSetTra(note, x, y, z);
Hu3DModelTPLvlSet(note->model[0], tplvl);
omSetSca(note, scale, scale, scale);
omSetRot(note, 0.0f, 0.0f, zRot);
if ((noteWork->pos += noteWork->speed) < 1.0f) {
return;
}
noteWork->enabled = FALSE;
Hu3DModelAttrSet(note->model[0], HU3D_ATTR_DISPOFF);
note->func = NULL;
note->unk10 = 0;
}
static void CreateNote(omObjData *object, s32 type, s32 side, s32 color)
{
omObjData *noteObj;
NoteWork *note;
s32 i;
for (i = 0; i < NUM_NOTES; i++) {
noteObj = ((SoundWork *)object->data)->object[i + 10];
note = noteObj->data;
if (!note->enabled && note->type == type) {
break;
}
}
if (i != NUM_NOTES) {
Hu3DMotionTimeSet(noteObj->model[0], 2.0f * color);
Hu3DMotionStartEndSet(noteObj->model[0], 2.0f * color, 2.0f * color + 1.0f);
note->enabled = TRUE;
note->side = side;
note->pos = 0.0f;
note->speed = 0.011111111f;
noteObj->func = HandleNote;
noteObj->unk10 = 0;
}
}
static void CreateNoteSpawner(omObjData *object)
{
SoundWork *work = object->data;
work->noteSpawner = HuPrcChildCreate(ExecNoteSpawner, 0x64, 0x2000, 0, HuPrcCurrentGet());
work->noteSpawner->user_data = object;
}
static void KillNoteSpawner(omObjData *object)
{
SoundWork *work = object->data;
HuPrcKill(work->noteSpawner);
}
static void ExecNoteSpawner(void)
{
omObjData *object;
SoundWork *work;
s32 type;
s32 color;
object = HuPrcCurrentGet()->user_data;
work = object->data;
while (TRUE) {
switch (work->cursorPos) {
case 0:
type = NOTE_TYPE_QUARTER;
color = frandmod(7);
CreateNote(object, type, NOTE_SIDE_LEFT, color);
type = NOTE_TYPE_QUAVER;
color = frandmod(7);
CreateNote(object, type, NOTE_SIDE_RIGHT, color);
break;
case 1:
type = NOTE_TYPE_QUAVER;
color = frandmod(7);
CreateNote(object, type, NOTE_SIDE_LEFT, color);
CreateNote(object, type, NOTE_SIDE_RIGHT, color);
break;
}
HuPrcSleep(24);
}
}
static void OptionPlaySound(omObjData *object)
{
SoundWork *work = object->data;
SndSelData *sndSelData;
if (work->selectedOption == 1) {
sndSelData = (SndSelData *)&musicTbl[work->page][work->cursorPos];
}
else {
sndSelData = (SndSelData *)&voiceTbl[work->page][work->cursorPos];
}
if (sndSelData->enabled) {
FadeSound(object);
switch (sndSelData->type) {
case 1:
work->streamStat = HuAudSStreamPlay(sndSelData->id);
break;
case 28:
if (sndSelData->sndGrpSet != work->sndGrpSet) {
HuAudSndGrpSetSet(sndSelData->sndGrpSet);
}
work->fxStat = HuAudFXPlay(sndSelData->id);
break;
default:
if (sndSelData->sndGrpSet != work->sndGrpSet && sndSelData->sndGrpSet != 2) {
HuAudSndGrpSetSet(sndSelData->sndGrpSet);
}
work->seqStat = HuAudSeqPlay(sndSelData->id);
break;
}
work->sndGrpSet = sndSelData->sndGrpSet;
HuPrcSleep(40);
}
}
static void FadeSound(omObjData *object)
{
SoundWork *work = object->data;
if (work->seqStat != -1) {
HuAudSeqFadeOut(work->seqStat, 0x64);
work->seqStat = -1;
}
if (work->streamStat != -1) {
HuAudSStreamFadeOut(work->streamStat, 0x64);
work->streamStat = -1;
}
if (work->fxStat != -1) {
HuAudFXFadeOut(work->fxStat, 0x64);
work->fxStat = -1;
}
HuPrcSleep(20);
}