mirror of https://github.com/zeldaret/mm.git
				
				
				
			
		
			
				
	
	
		
			291 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			291 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
| #ifndef Z64OCARINA_H
 | |
| #define Z64OCARINA_H
 | |
| 
 | |
| #include "PR/ultratypes.h"
 | |
| 
 | |
| typedef enum OcarinaSongId {
 | |
|     /*  0 */ OCARINA_SONG_SONATA,
 | |
|     /*  1 */ OCARINA_SONG_GORON_LULLABY,
 | |
|     /*  2 */ OCARINA_SONG_NEW_WAVE,
 | |
|     /*  3 */ OCARINA_SONG_ELEGY,
 | |
|     /*  4 */ OCARINA_SONG_OATH,
 | |
|     /*  5 */ OCARINA_SONG_SARIAS,
 | |
|     /*  6 */ OCARINA_SONG_TIME,
 | |
|     /*  7 */ OCARINA_SONG_HEALING,
 | |
|     /*  8 */ OCARINA_SONG_EPONAS,
 | |
|     /*  9 */ OCARINA_SONG_SOARING,
 | |
|     /* 10 */ OCARINA_SONG_STORMS,
 | |
|     /* 11 */ OCARINA_SONG_SUNS,
 | |
|     /* 12 */ OCARINA_SONG_INVERTED_TIME,
 | |
|     /* 13 */ OCARINA_SONG_DOUBLE_TIME,
 | |
|     /* 14 */ OCARINA_SONG_GORON_LULLABY_INTRO,
 | |
|     /* 15 */ OCARINA_SONG_WIND_FISH_HUMAN, // "Ballad of the Wind Fish"
 | |
|     /* 16 */ OCARINA_SONG_WIND_FISH_GORON,
 | |
|     /* 17 */ OCARINA_SONG_WIND_FISH_ZORA,
 | |
|     /* 18 */ OCARINA_SONG_WIND_FISH_DEKU,
 | |
|     /* 19 */ OCARINA_SONG_EVAN_PART1,
 | |
|     /* 20 */ OCARINA_SONG_EVAN_PART2,
 | |
|     /* 21 */ OCARINA_SONG_ZELDAS_LULLABY,
 | |
|     /* 22 */ OCARINA_SONG_SCARECROW_SPAWN,
 | |
|     /* 23 */ OCARINA_SONG_TERMINA_WALL,
 | |
|     /* 24 */ OCARINA_SONG_MAX,
 | |
|     /* 24 */ OCARINA_SONG_SCARECROW_LONG = OCARINA_SONG_MAX // anything larger than 24 is considered the long scarecrow's song
 | |
| } OcarinaSongId;
 | |
| 
 | |
| typedef enum OcarinaSongActionId {
 | |
|     /* 0x00 */ OCARINA_ACTION_0, // acts like free play but never set
 | |
|     /* 0x01 */ OCARINA_ACTION_FREE_PLAY,
 | |
|     /* 0x02 */ OCARINA_ACTION_DEMONSTRATE_SONATA, // Song demonstrated/previewed by another actor/teacher
 | |
|     /* 0x03 */ OCARINA_ACTION_DEMONSTRATE_GORON_LULLABY,
 | |
|     /* 0x04 */ OCARINA_ACTION_DEMONSTRATE_NEW_WAVE,
 | |
|     /* 0x05 */ OCARINA_ACTION_DEMONSTRATE_ELEGY,
 | |
|     /* 0x06 */ OCARINA_ACTION_DEMONSTRATE_OATH,
 | |
|     /* 0x07 */ OCARINA_ACTION_DEMONSTRATE_SARIAS,
 | |
|     /* 0x08 */ OCARINA_ACTION_DEMONSTRATE_TIME,
 | |
|     /* 0x09 */ OCARINA_ACTION_DEMONSTRATE_HEALING,
 | |
|     /* 0x0A */ OCARINA_ACTION_DEMONSTRATE_EPONAS,
 | |
|     /* 0x0B */ OCARINA_ACTION_DEMONSTRATE_SOARING,
 | |
|     /* 0x0C */ OCARINA_ACTION_DEMONSTRATE_STORMS,
 | |
|     /* 0x0D */ OCARINA_ACTION_DEMONSTRATE_SUNS,
 | |
|     /* 0x0E */ OCARINA_ACTION_DEMONSTRATE_INVERTED_TIME,
 | |
|     /* 0x0F */ OCARINA_ACTION_DEMONSTRATE_DOUBLE_TIME,
 | |
|     /* 0x10 */ OCARINA_ACTION_DEMONSTRATE_GORON_LULLABY_INTRO,
 | |
|     /* 0x11 */ OCARINA_ACTION_11,
 | |
|     /* 0x12 */ OCARINA_ACTION_PROMPT_SONATA, // User plays back song through inputing 1 note at a time, as a tutorial. Each note is verified.
 | |
|     /* 0x13 */ OCARINA_ACTION_PROMPT_GORON_LULLABY,
 | |
|     /* 0x14 */ OCARINA_ACTION_PROMPT_NEW_WAVE,
 | |
|     /* 0x15 */ OCARINA_ACTION_PROMPT_ELEGY,
 | |
|     /* 0x16 */ OCARINA_ACTION_PROMPT_OATH,
 | |
|     /* 0x17 */ OCARINA_ACTION_PROMPT_SARIAS,
 | |
|     /* 0x18 */ OCARINA_ACTION_PROMPT_TIME,
 | |
|     /* 0x19 */ OCARINA_ACTION_PROMPT_HEALING,
 | |
|     /* 0x1A */ OCARINA_ACTION_PROMPT_EPONAS,
 | |
|     /* 0x1B */ OCARINA_ACTION_PROMPT_SOARING,
 | |
|     /* 0x1C */ OCARINA_ACTION_PROMPT_STORMS,
 | |
|     /* 0x1D */ OCARINA_ACTION_PROMPT_SUNS,
 | |
|     /* 0x1E */ OCARINA_ACTION_PROMPT_INVERTED_TIME,
 | |
|     /* 0x1F */ OCARINA_ACTION_PROMPT_DOUBLE_TIME,
 | |
|     /* 0x20 */ OCARINA_ACTION_PROMPT_GORON_LULLABY_INTRO,
 | |
|     /* 0x21 */ OCARINA_ACTION_21,
 | |
|     /* 0x22 */ OCARINA_ACTION_CHECK_SONATA, // Once the entire song is played, checks for a specific song. Broken as playing any dungeon song will softlock.
 | |
|     /* 0x23 */ OCARINA_ACTION_CHECK_GORON_LULLABY,
 | |
|     /* 0x24 */ OCARINA_ACTION_CHECK_NEW_WAVE,
 | |
|     /* 0x25 */ OCARINA_ACTION_CHECK_ELEGY,
 | |
|     /* 0x26 */ OCARINA_ACTION_CHECK_OATH,
 | |
|     /* 0x27 */ OCARINA_ACTION_CHECK_SARIAS,
 | |
|     /* 0x28 */ OCARINA_ACTION_CHECK_TIME,
 | |
|     /* 0x29 */ OCARINA_ACTION_CHECK_HEALING,
 | |
|     /* 0x2A */ OCARINA_ACTION_CHECK_EPONAS,
 | |
|     /* 0x2B */ OCARINA_ACTION_CHECK_SOARING,
 | |
|     /* 0x2C */ OCARINA_ACTION_CHECK_STORMS,
 | |
|     /* 0x2D */ OCARINA_ACTION_CHECK_SUNS,
 | |
|     /* 0x2E */ OCARINA_ACTION_CHECK_INVERTED_TIME,
 | |
|     /* 0x2F */ OCARINA_ACTION_CHECK_DOUBLE_TIME,
 | |
|     /* 0x30 */ OCARINA_ACTION_CHECK_GORON_LULLABY_INTRO,
 | |
|     /* 0x31 */ OCARINA_ACTION_CHECK_SCARECROW_SPAWN, // TODO: Verify (may include more)
 | |
|     /* 0x32 */ OCARINA_ACTION_FREE_PLAY_DONE, 
 | |
|     /* 0x33 */ OCARINA_ACTION_SCARECROW_LONG_RECORDING,
 | |
|     /* 0x34 */ OCARINA_ACTION_SCARECROW_LONG_DEMONSTRATION,
 | |
|     /* 0x35 */ OCARINA_ACTION_SCARECROW_SPAWN_RECORDING,
 | |
|     /* 0x36 */ OCARINA_ACTION_SCARECROW_SPAWN_DEMONSTRATION,
 | |
|     /* 0x37 */ OCARINA_ACTION_37,
 | |
|     /* 0x38 */ OCARINA_ACTION_CHECK_NOTIME,
 | |
|     /* 0x39 */ OCARINA_ACTION_CHECK_NOTIME_DONE,
 | |
|     /* 0x3A */ OCARINA_ACTION_3A, // Monkey Instrument Prompt
 | |
|     /* 0x3B */ OCARINA_ACTION_3B,
 | |
|     /* 0x3C */ OCARINA_ACTION_3C,
 | |
|     /* 0x3D */ OCARINA_ACTION_DEMONSTRATE_EVAN_PART1_FIRST_HALF, // Evan Part 1 demonstrate first half (Japa)
 | |
|     /* 0x3E */ OCARINA_ACTION_DEMONSTRATE_EVAN_PART2_FIRST_HALF, // Evan Part 2 demonstrate first half (Japa)
 | |
|     /* 0x3F */ OCARINA_ACTION_DEMONSTRATE_EVAN_PART1_SECOND_HALF, // Evan Part 1 demonstrate second half (Diary)
 | |
|     /* 0x40 */ OCARINA_ACTION_DEMONSTRATE_EVAN_PART2_SECOND_HALF, // Evan Part 2 demonstrate second half (Diary)
 | |
|     /* 0x41 */ OCARINA_ACTION_PROMPT_EVAN_PART1_SECOND_HALF, // Evan Part 1 prompt second half (Japa)
 | |
|     /* 0x42 */ OCARINA_ACTION_PROMPT_EVAN_PART2_SECOND_HALF, // Evan Part 2 prompt second half (Japa)
 | |
|     /* 0x43 */ OCARINA_ACTION_PROMPT_WIND_FISH_HUMAN,
 | |
|     /* 0x44 */ OCARINA_ACTION_PROMPT_WIND_FISH_GORON,
 | |
|     /* 0x45 */ OCARINA_ACTION_PROMPT_WIND_FISH_ZORA,
 | |
|     /* 0x46 */ OCARINA_ACTION_PROMPT_WIND_FISH_DEKU,
 | |
|     /* 0x47 */ OCARINA_ACTION_TIMED_PROMPT_SONATA, // Playing back a particular song, but must also time the notes properly. Not fully implemented
 | |
|     /* 0x48 */ OCARINA_ACTION_TIMED_PROMPT_GORON_LULLABY,
 | |
|     /* 0x49 */ OCARINA_ACTION_TIMED_PROMPT_NEW_WAVE,
 | |
|     /* 0x4A */ OCARINA_ACTION_TIMED_PROMPT_ELEGY,
 | |
|     /* 0x4B */ OCARINA_ACTION_TIMED_PROMPT_OATH,
 | |
|     /* 0x4C */ OCARINA_ACTION_TIMED_PROMPT_SARIAS,
 | |
|     /* 0x4D */ OCARINA_ACTION_TIMED_PROMPT_TIME,
 | |
|     /* 0x4E */ OCARINA_ACTION_TIMED_PROMPT_HEALING,
 | |
|     /* 0x4F */ OCARINA_ACTION_TIMED_PROMPT_EPONAS,
 | |
|     /* 0x50 */ OCARINA_ACTION_TIMED_PROMPT_SOARING,
 | |
|     /* 0x51 */ OCARINA_ACTION_TIMED_PROMPT_STORMS
 | |
| } OcarinaSongActionId;
 | |
| 
 | |
| typedef enum OcarinaMode {
 | |
|     /* 0x00 */ OCARINA_MODE_NONE,
 | |
|     /* 0x01 */ OCARINA_MODE_ACTIVE,
 | |
|     /* 0x02 */ OCARINA_MODE_WARP,
 | |
|     /* 0x03 */ OCARINA_MODE_EVENT,
 | |
|     /* 0x04 */ OCARINA_MODE_END,
 | |
|     /* 0x05 */ OCARINA_MODE_PLAYED_TIME, // Played Time
 | |
|     /* 0x06 */ OCARINA_MODE_PLAYED_HEALING,
 | |
|     /* 0x07 */ OCARINA_MODE_PLAYED_EPONAS,
 | |
|     /* 0x08 */ OCARINA_MODE_PLAYED_SOARING,
 | |
|     /* 0x09 */ OCARINA_MODE_PLAYED_STORMS,
 | |
|     /* 0x0A */ OCARINA_MODE_PLAYED_SUNS,
 | |
|     /* 0x0B */ OCARINA_MODE_PLAYED_INVERTED_TIME,
 | |
|     /* 0x0C */ OCARINA_MODE_PLAYED_DOUBLE_TIME,
 | |
|     /* 0x0D */ OCARINA_MODE_PLAYED_SCARECROW_SPAWN,
 | |
|     /* 0x0E */ OCARINA_MODE_E,
 | |
|     /* 0x0F */ OCARINA_MODE_F,
 | |
|     /* 0x10 */ OCARINA_MODE_10,
 | |
|     /* 0x11 */ OCARINA_MODE_11, // End memory/scarecrow from OoT
 | |
|     /* 0x12 */ OCARINA_MODE_PROCESS_SOT, // Song of Time related
 | |
|     /* 0x13 */ OCARINA_MODE_PROCESS_INVERTED_TIME, // Inverted Song of Time related
 | |
|     /* 0x14 */ OCARINA_MODE_14,
 | |
|     /* 0x15 */ OCARINA_MODE_PROCESS_DOUBLE_TIME, // Song of Double Time related
 | |
|     /* 0x16 */ OCARINA_MODE_APPLY_SOT, // Apply
 | |
|     /* 0x17 */ OCARINA_MODE_17,
 | |
|     /* 0x18 */ OCARINA_MODE_APPLY_INV_SOT_FAST,
 | |
|     /* 0x19 */ OCARINA_MODE_APPLY_INV_SOT_SLOW,
 | |
|     /* 0x1A */ OCARINA_MODE_APPLY_DOUBLE_SOT,
 | |
|     /* 0x1B */ OCARINA_MODE_1B,
 | |
|     /* 0x1C */ OCARINA_MODE_WARP_TO_GREAT_BAY_COAST,
 | |
|     /* 0x1D */ OCARINA_MODE_WARP_TO_ZORA_CAPE,
 | |
|     /* 0x1E */ OCARINA_MODE_WARP_TO_SNOWHEAD,
 | |
|     /* 0x1F */ OCARINA_MODE_WARP_TO_MOUNTAIN_VILLAGE,
 | |
|     /* 0x20 */ OCARINA_MODE_WARP_TO_SOUTH_CLOCK_TOWN,
 | |
|     /* 0x21 */ OCARINA_MODE_WARP_TO_MILK_ROAD,
 | |
|     /* 0x22 */ OCARINA_MODE_WARP_TO_WOODFALL,
 | |
|     /* 0x23 */ OCARINA_MODE_WARP_TO_SOUTHERN_SWAMP,
 | |
|     /* 0x24 */ OCARINA_MODE_WARP_TO_IKANA_CANYON,
 | |
|     /* 0x25 */ OCARINA_MODE_WARP_TO_STONE_TOWER,
 | |
|     /* 0x26 */ OCARINA_MODE_WARP_TO_ENTRANCE,
 | |
|     /* 0x27 */ OCARINA_MODE_PROCESS_RESTRICTED_SONG, // Variants of Song of Time, Soaring, or Elegy restricted
 | |
|     /* 0x28 */ OCARINA_MODE_28,
 | |
|     /* 0x29 */ OCARINA_MODE_29,
 | |
|     /* 0x2A */ OCARINA_MODE_PLAYED_FULL_EVAN_SONG
 | |
| } OcarinaMode;
 | |
| 
 | |
| typedef enum OcarinaButtonIndex {
 | |
|     /*  0 */ OCARINA_BTN_A,
 | |
|     /*  1 */ OCARINA_BTN_C_DOWN,
 | |
|     /*  2 */ OCARINA_BTN_C_RIGHT,
 | |
|     /*  3 */ OCARINA_BTN_C_LEFT,
 | |
|     /*  4 */ OCARINA_BTN_C_UP,
 | |
|     /*  5 */ OCARINA_BTN_C_RIGHT_OR_C_LEFT,
 | |
|     /* -1 */ OCARINA_BTN_INVALID = 0xFF
 | |
| } OcarinaButtonIndex;
 | |
| 
 | |
| // Uses scientific pitch notation relative to middle C
 | |
| // https://en.wikipedia.org/wiki/Scientific_pitch_notation
 | |
| typedef enum OcarinaPitch {
 | |
|     /* 0x0 */ OCARINA_PITCH_C4,
 | |
|     /* 0x1 */ OCARINA_PITCH_DFLAT4,
 | |
|     /* 0x2 */ OCARINA_PITCH_D4,
 | |
|     /* 0x3 */ OCARINA_PITCH_EFLAT4,
 | |
|     /* 0x4 */ OCARINA_PITCH_E4,
 | |
|     /* 0x5 */ OCARINA_PITCH_F4,
 | |
|     /* 0x6 */ OCARINA_PITCH_GFLAT4,
 | |
|     /* 0x7 */ OCARINA_PITCH_G4,
 | |
|     /* 0x8 */ OCARINA_PITCH_AFLAT4,
 | |
|     /* 0x9 */ OCARINA_PITCH_A4,
 | |
|     /* 0xA */ OCARINA_PITCH_BFLAT4,
 | |
|     /* 0xB */ OCARINA_PITCH_B4,
 | |
|     /* 0xC */ OCARINA_PITCH_C5,
 | |
|     /* 0xD */ OCARINA_PITCH_DFLAT5,
 | |
|     /* 0xE */ OCARINA_PITCH_D5,
 | |
|     /* 0xF */ OCARINA_PITCH_EFLAT5,
 | |
|     /*  -1 */ OCARINA_PITCH_NONE = 0xFF
 | |
| } OcarinaPitch;
 | |
| 
 | |
| typedef enum OcarinaInstrumentId {
 | |
|     /*  0 */ OCARINA_INSTRUMENT_OFF,
 | |
|     /*  1 */ OCARINA_INSTRUMENT_DEFAULT,
 | |
|     /*  2 */ OCARINA_INSTRUMENT_FEMALE_VOICE,
 | |
|     /*  3 */ OCARINA_INSTRUMENT_WHISTLING_FLUTE,
 | |
|     /*  4 */ OCARINA_INSTRUMENT_HARP,
 | |
|     /*  5 */ OCARINA_INSTRUMENT_IKANA_KING,
 | |
|     /*  6 */ OCARINA_INSTRUMENT_TATL, // Sounds like bells
 | |
|     /*  7 */ OCARINA_INSTRUMENT_GORON_DRUMS,
 | |
|     /*  8 */ OCARINA_INSTRUMENT_ZORA_GUITAR,
 | |
|     /*  9 */ OCARINA_INSTRUMENT_DEKU_PIPES,
 | |
|     /* 10 */ OCARINA_INSTRUMENT_MONKEY,
 | |
|     /* 11 */ OCARINA_INSTRUMENT_DEKU_TRUMPET, // Pull out ocarina for captured monkey
 | |
|     /* 12 */ OCARINA_INSTRUMENT_ELDER_GORON_DRUMS,
 | |
|     /* 13 */ OCARINA_INSTRUMENT_PIANO,
 | |
|     /* 14 */ OCARINA_INSTRUMENT_BASS_GUITAR,
 | |
|     /* 15 */ OCARINA_INSTRUMENT_BABY_SINGING,
 | |
|     /* 16 */ OCARINA_INSTRUMENT_AMPLIFIED_GUITAR // Related to WEEKEVENTREG_41_20
 | |
| } OcarinaInstrumentId;
 | |
| 
 | |
| typedef enum OcarinaRecordingState {
 | |
|     /*  0 */ OCARINA_RECORD_OFF,
 | |
|     /*  1 */ OCARINA_RECORD_SCARECROW_LONG,
 | |
|     /*  2 */ OCARINA_RECORD_SCARECROW_SPAWN,
 | |
|     /* -1 */ OCARINA_RECORD_REJECTED = 0xFF
 | |
| } OcarinaRecordingState;
 | |
| 
 | |
| typedef enum OcarinaError {
 | |
|     /*    0 */ OCARINA_ERROR_NONE,
 | |
|     /*    1 */ OCARINA_ERROR_1,
 | |
|     /*    2 */ OCARINA_ERROR_2,
 | |
|     /*    3 */ OCARINA_ERROR_3,
 | |
|     /*    4 */ OCARINA_ERROR_BEND,
 | |
|     /*    5 */ OCARINA_ERROR_5,
 | |
|     /* 0xFF */ OCARINA_ERROR_INACTIVE = 0xFF // Song not available
 | |
| } OcarinaError;
 | |
| 
 | |
| /**
 | |
|  * bFlat4Flag Note:
 | |
|  * Flag for resolving whether (pitch = OCARINA_PITCH_BFLAT4) 
 | |
|  * gets mapped to either C_RIGHT and C_LEFT
 | |
|  * 
 | |
|  * This is required as C_RIGHT and C_LEFT are the only notes
 | |
|  * that map to two semitones apart (OCARINA_PITCH_A4 and OCARINA_PITCH_B4)
 | |
|  *      0x40 - BTN_Z is pressed to lower note by a semitone
 | |
|  *      0x80 - BTN_R is pressed to raise note by a semitone
 | |
|  */ 
 | |
| #define OCARINA_BUTTON_MASK_PITCH 0x3F
 | |
| #define OCARINA_BUTTON_MASK_FLAG 0xC0
 | |
| #define OCARINA_BUTTON_FLAG_BFLAT_LOWER 0x40
 | |
| #define OCARINA_BUTTON_FLAG_BFLAT_RAISE 0x80
 | |
| 
 | |
| typedef struct {
 | |
|     /* 0x0 */ u8 pitch; // number of semitones above middle C
 | |
|     /* 0x2 */ u16 length; // number of frames the note is sustained
 | |
|     /* 0x4 */ u8 volume;
 | |
|     /* 0x5 */ u8 vibrato;
 | |
|     /* 0x6 */ s8 bend; // frequency multiplicative offset from the pitch defined by pitch
 | |
|     /* 0x7 */ u8 bFlat4Flag; // See note above
 | |
| } OcarinaNote;  // size = 0x8
 | |
| 
 | |
| typedef struct {
 | |
|     /* 0x0 */ u8 numButtons;
 | |
|     /* 0x1 */ u8 buttonIndex[8];
 | |
| } OcarinaSongButtons; // size = 0x9
 | |
| 
 | |
| typedef struct OcarinaStaff {
 | |
|     /* 0x0 */ u8 buttonIndex;
 | |
|     /* 0x1 */ u8 state;   // original name: "status"
 | |
|     /* 0x2 */ u8 pos;     // original name: "locate"
 | |
| } OcarinaStaff; // size = 0x3
 | |
| 
 | |
| void AudioOcarina_SetSongStartingPos(void);
 | |
| void AudioOcarina_StartAtSongStartingPos(u32 ocarinaFlags);
 | |
| void AudioOcarina_StartForSongCheck(u32 ocarinaFlags, u8 ocarinaStaffPlayingPosStart);
 | |
| void AudioOcarina_StartWithSongNoteLengths(u32 ocarinaFlags);
 | |
| void AudioOcarina_StartDefault(u32 ocarinaFlags);
 | |
| u8 func_8019B5AC(void);
 | |
| void AudioOcarina_ResetAndReadInput(void);
 | |
| void AudioOcarina_SetOcarinaDisableTimer(u8 unused, u8 timer);
 | |
| void AudioOcarina_SetInstrument(u8 ocarinaInstrumentId);
 | |
| void AudioOcarina_SetPlaybackSong(s8 songIndexPlusOne, u8 playbackState);
 | |
| void AudioOcarina_SetRecordingState(u8 recordingState);
 | |
| OcarinaStaff* AudioOcarina_GetRecordingStaff(void);
 | |
| OcarinaStaff* AudioOcarina_GetPlayingStaff(void);
 | |
| OcarinaStaff* AudioOcarina_GetPlaybackStaff(void);
 | |
| void AudioOcarina_TerminaWallGenerateNotes(void);
 | |
| void AudioOcarina_PlayLongScarecrowSong(void);
 | |
| 
 | |
| extern u8* gScarecrowSpawnSongPtr;
 | |
| extern OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX];
 | |
| 
 | |
| #endif
 |