mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-21 05:43:42 -07:00
Merge branch 'develop' into 3DProjectiles
This commit is contained in:
commit
14df96eacd
489 changed files with 125389 additions and 1776 deletions
1560
soh/assets/xml/GC_NMQ_D/audio/Audio.xml
Normal file
1560
soh/assets/xml/GC_NMQ_D/audio/Audio.xml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,21 +1,21 @@
|
|||
<Root>
|
||||
<File Name="object_mag" Segment="6">
|
||||
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160"/>
|
||||
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16"/>
|
||||
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16"/>
|
||||
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16"/>
|
||||
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32"/>
|
||||
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8"/>
|
||||
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8"/>
|
||||
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16"/>
|
||||
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
|
||||
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
|
||||
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16" Offset="0x19A00"/>
|
||||
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x1A400"/>
|
||||
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x1A700"/>
|
||||
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1AF00"/>
|
||||
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1B700"/>
|
||||
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1BF00"/>
|
||||
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1C700"/>
|
||||
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1CF00"/>
|
||||
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1D700"/>
|
||||
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1DF00"/>
|
||||
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1E700"/>
|
||||
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1EF00"/>
|
||||
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1F300"/>
|
||||
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1F540"/>
|
||||
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1F840"/>
|
||||
</File>
|
||||
</Root>
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
<Scene Name="sasatest_scene" Offset="0x0"/>
|
||||
</File>
|
||||
<File Name="sasatest_room_0" Segment="3">
|
||||
<Array Name="gSasatestRoom0Vtx_00370" Count="289" Offset="0x370">
|
||||
<Vtx/>
|
||||
</Array>
|
||||
<Room Name="sasatest_room_0" Offset="0x0"/>
|
||||
</File>
|
||||
</Root>
|
||||
|
|
1560
soh/assets/xml/GC_NMQ_PAL_F/audio/Audio.xml
Normal file
1560
soh/assets/xml/GC_NMQ_PAL_F/audio/Audio.xml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,21 +1,21 @@
|
|||
<Root>
|
||||
<File Name="object_mag" Segment="6">
|
||||
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160"/>
|
||||
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16"/>
|
||||
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16"/>
|
||||
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16"/>
|
||||
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64"/>
|
||||
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32"/>
|
||||
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8"/>
|
||||
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8"/>
|
||||
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16"/>
|
||||
<Texture Name="gTitleZeldaShieldLogoMQTex" OutName="title_zelda_shield_logo_mq" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
|
||||
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
|
||||
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16" Offset="0x19A00"/>
|
||||
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x1A400"/>
|
||||
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x1A700"/>
|
||||
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1AF00"/>
|
||||
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1B700"/>
|
||||
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1BF00"/>
|
||||
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1C700"/>
|
||||
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1CF00"/>
|
||||
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1D700"/>
|
||||
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1DF00"/>
|
||||
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1E700"/>
|
||||
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1EF00"/>
|
||||
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1F300"/>
|
||||
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1F540"/>
|
||||
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1F840"/>
|
||||
</File>
|
||||
</Root>
|
||||
|
|
|
@ -1322,18 +1322,9 @@ void SkinMatrix_SetTranslateRotateZYX(MtxF* dest, s16 rotX, s16 rotY, s16 rotZ,
|
|||
f32 translateZ);
|
||||
Mtx* SkinMatrix_MtxFToNewMtx(GraphicsContext* gfxCtx, MtxF* src);
|
||||
void SkinMatrix_SetRotateAxis(MtxF* mf, s16 angle, f32 axisX, f32 axisY, f32 axisZ);
|
||||
void Sram_InitNewSave(void);
|
||||
void Sram_InitDebugSave(void);
|
||||
void Sram_OpenSave(SramContext* sramCtx);
|
||||
void Sram_WriteSave(SramContext* sramCtx);
|
||||
void Sram_VerifyAndLoadAllSaves(FileChooseContext* fileChoose, SramContext* sramCtx);
|
||||
void Sram_InitSave(FileChooseContext* fileChoose, SramContext* sramCtx);
|
||||
void Sram_EraseSave(FileChooseContext* fileChoose, SramContext* sramCtx);
|
||||
void Sram_CopySave(FileChooseContext* fileChoose, SramContext* sramCtx);
|
||||
void Sram_WriteSramHeader(SramContext* sramCtx);
|
||||
void Sram_InitSram(GameState* gameState, SramContext* sramCtx);
|
||||
void Sram_Alloc(GameState* gameState, SramContext* sramCtx);
|
||||
void Sram_Init(GlobalContext* globalCtx, SramContext* sramCtx);
|
||||
void Sram_OpenSave();
|
||||
void Sram_InitSave(FileChooseContext* fileChoose);
|
||||
void Sram_InitSram(GameState* gameState);
|
||||
void SsSram_ReadWrite(uintptr_t addr, void* dramAddr, size_t size, s32 direction);
|
||||
void func_800A9F30(PadMgr*, s32);
|
||||
void func_800A9F6C(f32, u8, u8, u8);
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
#define _AudiotableSegmentRomStart "Audiotable"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define _icon_item_gameover_staticSegmentRomStart 0
|
||||
#define _icon_item_gameover_staticSegmentRomEnd 0
|
||||
#define _icon_item_staticSegmentRomStart 0
|
||||
#define _icon_item_staticSegmentRomEnd 0
|
||||
#define _map_i_staticSegmentRomStart 0
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#include "ichain.h"
|
||||
#include "regs.h"
|
||||
|
||||
#define AUDIO_HEAP_SIZE 0x38000
|
||||
//#define AUDIO_HEAP_SIZE 0x38000
|
||||
#define AUDIO_HEAP_SIZE 0x3800000 // The original audio heap size was too small. The heap would exceed capacity and corrupt everything in its path.
|
||||
#define SYSTEM_HEAP_SIZE (1024 * 1024 * 4)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1071,10 +1072,6 @@ typedef struct {
|
|||
/* 0x01 */ u8 room;
|
||||
} EntranceEntry;
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u8* readBuff;
|
||||
} SramContext; // size = 0x4
|
||||
|
||||
#define SRAM_SIZE 0x8000
|
||||
#define SRAM_HEADER_SIZE 0x10
|
||||
|
||||
|
@ -1119,7 +1116,6 @@ typedef struct {
|
|||
/* 0x0000 */ GameState state;
|
||||
/* 0x00A4 */ u8* staticSegment;
|
||||
/* 0x00A8 */ View view;
|
||||
/* 0x01D0 */ SramContext sramCtx;
|
||||
/* 0x01D4 */ u16 unk_1D4; // not used in mq dbg (some sort of timer that doesn't seem to affect anything)
|
||||
/* 0x01D6 */ s16 coverAlpha;
|
||||
/* 0x01D8 */ s16 addAlpha; // not used in mq dbg
|
||||
|
@ -1205,7 +1201,6 @@ typedef struct GlobalContext {
|
|||
/* 0x01C24 */ ActorContext actorCtx;
|
||||
/* 0x01D64 */ CutsceneContext csCtx; // "demo_play"
|
||||
/* 0x01DB4 */ SoundSource soundSources[16];
|
||||
/* 0x01F74 */ SramContext sramCtx;
|
||||
/* 0x01F78 */ SkyboxContext skyboxCtx;
|
||||
/* 0x020D8 */ MessageContext msgCtx; // "message"
|
||||
/* 0x104F0 */ InterfaceContext interfaceCtx; // "parameter"
|
||||
|
@ -1279,7 +1274,6 @@ typedef struct {
|
|||
/* 0x000AC */ u8* parameterSegment;
|
||||
/* 0x000B0 */ char unk_B0[0x8];
|
||||
/* 0x000B8 */ View view;
|
||||
/* 0x001E0 */ SramContext sramCtx;
|
||||
/* 0x001E4 */ char unk_1E4[0x4];
|
||||
/* 0x001E8 */ SkyboxContext skyboxCtx;
|
||||
/* 0x00348 */ MessageContext msgCtx;
|
||||
|
@ -1290,13 +1284,6 @@ typedef struct {
|
|||
/* 0x1C9EC */ Vtx* keyboardVtx;
|
||||
/* 0x1C9F0 */ Vtx* nameEntryVtx;
|
||||
/* 0x1C9F4 */ u8 n64ddFlag;
|
||||
/* 0x1C9F6 */ u16 deaths[3];
|
||||
/* 0x1C9FC */ u8 fileNames[3][8];
|
||||
/* 0x1CA14 */ u16 healthCapacities[3];
|
||||
/* 0x1CA1C */ u32 questItems[3];
|
||||
/* 0x1CA28 */ s16 n64ddFlags[3];
|
||||
/* 0x1CA2E */ s8 defense[3];
|
||||
/* 0x1CA32 */ u16 health[3];
|
||||
/* 0x1CA38 */ s16 buttonIndex;
|
||||
/* 0x1CA3A */ s16 confirmButtonIndex; // 0: yes, 1: quit
|
||||
/* 0x1CA3C */ s16 menuMode;
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
|
||||
#define AIBUF_LEN 0x580
|
||||
|
||||
#define CALC_RESAMPLE_FREQ(sampleRate) ((float)sampleRate / (s32)gAudioContext.audioBufferParameters.frequency)
|
||||
|
||||
extern bool gUseLegacySD;
|
||||
extern char* fontMap[256];
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ ADSR_STATE_DISABLED,
|
||||
/* 1 */ ADSR_STATE_INITIAL,
|
||||
|
@ -120,7 +125,8 @@ typedef struct {
|
|||
/* 0x08 */ s16 book[1]; // size 8 * order * npredictors. 8-byte aligned
|
||||
} AdpcmBook; // size >= 0x8
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
/* 0x00 */ u32 codec : 4;
|
||||
|
@ -135,6 +141,8 @@ typedef struct {
|
|||
/* 0x04 */ u8* sampleAddr;
|
||||
/* 0x08 */ AdpcmLoop* loop;
|
||||
/* 0x0C */ AdpcmBook* book;
|
||||
u32 sampleRateMagicValue; // For wav samples only...
|
||||
s32 sampleRate; // For wav samples only...
|
||||
} SoundFontSample; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
|
@ -226,6 +234,7 @@ typedef struct {
|
|||
/* 0x08 */ Instrument** instruments;
|
||||
/* 0x0C */ Drum** drums;
|
||||
/* 0x10 */ SoundFontSound* soundEffects;
|
||||
s32 fntIndex;
|
||||
} SoundFont; // size = 0x14
|
||||
|
||||
typedef struct {
|
||||
|
@ -680,7 +689,6 @@ typedef struct {
|
|||
union{
|
||||
u32 opArgs;
|
||||
struct {
|
||||
// OTRTODO: struct members swapped for quick audio
|
||||
u8 arg2;
|
||||
u8 arg1;
|
||||
u8 arg0;
|
||||
|
@ -1061,6 +1069,16 @@ typedef enum {
|
|||
/* -1 */ OCARINA_NOTE_INVALID = 0xFF
|
||||
} OcarinaNoteIdx;
|
||||
|
||||
typedef struct {
|
||||
char* seqData;
|
||||
int32_t seqDataSize;
|
||||
uint8_t seqNumber;
|
||||
uint8_t medium;
|
||||
uint8_t cachePolicy;
|
||||
int32_t numFonts;
|
||||
uint8_t fonts[16];
|
||||
} SequenceData;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -68,7 +68,6 @@ typedef struct {
|
|||
/* 0x0010 */ s32 nightFlag;
|
||||
/* 0x0014 */ s32 totalDays;
|
||||
/* 0x0018 */ s32 bgsDayCount; // increments with totalDays, can be cleared with `Environment_ClearBgsDayCount`
|
||||
/* 0x001C */ char newf[6]; // string "ZELDAZ". start of `info` substruct, originally called "information"
|
||||
/* 0x0022 */ u16 deaths;
|
||||
/* 0x0024 */ char playerName[8];
|
||||
/* 0x002C */ s16 n64ddFlag;
|
||||
|
@ -80,7 +79,6 @@ typedef struct {
|
|||
/* 0x0036 */ u16 swordHealth;
|
||||
/* 0x0038 */ u16 naviTimer;
|
||||
/* 0x003A */ u8 magicAcquired;
|
||||
/* 0x003B */ char unk_3B[0x01];
|
||||
/* 0x003C */ u8 doubleMagic;
|
||||
/* 0x003D */ u8 doubleDefense;
|
||||
/* 0x003E */ u8 bgsFlag;
|
||||
|
@ -88,30 +86,23 @@ typedef struct {
|
|||
/* 0x0040 */ ItemEquips childEquips;
|
||||
/* 0x004A */ ItemEquips adultEquips;
|
||||
/* 0x0054 */ u32 unk_54; // this may be incorrect, currently used for alignement
|
||||
/* 0x0058 */ char unk_58[0x0E];
|
||||
/* 0x0066 */ s16 savedSceneNum;
|
||||
/* 0x0068 */ ItemEquips equips;
|
||||
/* 0x0074 */ Inventory inventory;
|
||||
/* 0x00D4 */ SavedSceneFlags sceneFlags[124];
|
||||
/* 0x0E64 */ FaroresWindData fw;
|
||||
/* 0x0E8C */ char unk_E8C[0x10];
|
||||
/* 0x0E9C */ s32 gsFlags[6];
|
||||
/* 0x0EB4 */ char unk_EB4[0x4];
|
||||
/* 0x0EB8 */ s32 highScores[7];
|
||||
/* 0x0ED4 */ u16 eventChkInf[14]; // "event_chk_inf"
|
||||
/* 0x0EF0 */ u16 itemGetInf[4]; // "item_get_inf"
|
||||
/* 0x0EF8 */ u16 infTable[30]; // "inf_table"
|
||||
/* 0x0F34 */ char unk_F34[0x04];
|
||||
/* 0x0F38 */ u32 worldMapAreaData; // "area_arrival"
|
||||
/* 0x0F3C */ char unk_F3C[0x4];
|
||||
/* 0x0F40 */ u8 scarecrowCustomSongSet;
|
||||
/* 0x0F41 */ u8 scarecrowCustomSong[0x360];
|
||||
/* 0x12A1 */ char unk_12A1[0x24];
|
||||
/* 0x12C5 */ u8 scarecrowSpawnSongSet;
|
||||
/* 0x12C6 */ u8 scarecrowSpawnSong[0x80];
|
||||
/* 0x1346 */ char unk_1346[0x02];
|
||||
/* 0x1348 */ HorseData horseData;
|
||||
/* 0x1352 */ u16 checksum; // "check_sum"
|
||||
/* 0x1354 */ s32 fileNum; // "file_no"
|
||||
/* 0x1358 */ char unk_1358[0x0004];
|
||||
/* 0x135C */ s32 gameMode;
|
||||
|
@ -120,13 +111,11 @@ typedef struct {
|
|||
/* 0x1368 */ RespawnData respawn[3]; // "restart_data"
|
||||
/* 0x13BC */ f32 entranceSpeed;
|
||||
/* 0x13C0 */ u16 entranceSound;
|
||||
/* 0x13C2 */ char unk_13C2[0x0001];
|
||||
/* 0x13C3 */ u8 unk_13C3;
|
||||
/* 0x13C4 */ s16 dogParams;
|
||||
/* 0x13C6 */ u8 textTriggerFlags;
|
||||
/* 0x13C7 */ u8 showTitleCard;
|
||||
/* 0x13C8 */ s16 nayrusLoveTimer;
|
||||
/* 0x13CA */ char unk_13CA[0x0002];
|
||||
/* 0x13CC */ s16 rupeeAccumulator;
|
||||
/* 0x13CE */ s16 timer1State;
|
||||
/* 0x13D0 */ s16 timer1Value;
|
||||
|
@ -134,7 +123,6 @@ typedef struct {
|
|||
/* 0x13D4 */ s16 timer2Value;
|
||||
/* 0x13D6 */ s16 timerX[2];
|
||||
/* 0x13DA */ s16 timerY[2];
|
||||
/* 0x13DE */ char unk_13DE[0x0002];
|
||||
/* 0x13E0 */ u8 seqId;
|
||||
/* 0x13E1 */ u8 natureAmbienceId;
|
||||
/* 0x13E2 */ u8 buttonStatus[5];
|
||||
|
@ -152,14 +140,11 @@ typedef struct {
|
|||
/* 0x1402 */ u16 mapIndex; // intended for maps/minimaps but commonly used as the dungeon index
|
||||
/* 0x1404 */ u16 minigameState;
|
||||
/* 0x1406 */ u16 minigameScore; // "yabusame_total"
|
||||
/* 0x1408 */ char unk_1408[0x0001];
|
||||
/* 0x1409 */ u8 language; // NTSC 0: Japanese; 1: English | PAL 0: English; 1: German; 2: French
|
||||
/* 0x140A */ u8 audioSetting;
|
||||
/* 0x140B */ char unk_140B[0x0001];
|
||||
/* 0x140C */ u8 zTargetSetting; // 0: Switch; 1: Hold
|
||||
/* 0x140E */ u16 forcedSeqId; // immediately start playing the sequence if set
|
||||
/* 0x1410 */ u8 unk_1410; // transition related
|
||||
/* 0x1411 */ char unk_1411[0x0001];
|
||||
/* 0x1412 */ u16 nextCutsceneIndex;
|
||||
/* 0x1414 */ u8 cutsceneTrigger;
|
||||
/* 0x1415 */ u8 chamberCutsceneNum;
|
||||
|
@ -169,7 +154,6 @@ typedef struct {
|
|||
/* 0x141A */ u16 skyboxTime;
|
||||
/* 0x141C */ u8 dogIsLost;
|
||||
/* 0x141D */ u8 nextTransition;
|
||||
/* 0x141E */ char unk_141E[0x0002];
|
||||
/* 0x1420 */ s16 worldMapArea;
|
||||
/* 0x1422 */ s16 sunsSongState; // controls the effects of suns song
|
||||
/* 0x1424 */ s16 healthAccumulator;
|
||||
|
|
11
soh/soh.sln
11
soh/soh.sln
|
@ -5,6 +5,7 @@ VisualStudioVersion = 16.0.31112.23
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soh", "soh.vcxproj", "{31348AA7-8DC5-4FA7-955F-E80855CADE9E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055} = {78424708-1F6E-4D4B-920C-FB6D26847055}
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908} = {A2E01C3E-D647-45D1-9788-043DEBC1A908}
|
||||
EndProjectSection
|
||||
|
@ -13,6 +14,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libultraship", "..\libultra
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "..\ZAPDTR\ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "..\StormLib\StormLib_vs19.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
|
@ -45,6 +48,14 @@ Global
|
|||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.ActiveCfg = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.Build.0 = DebugUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.ActiveCfg = ReleaseUS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.Build.0 = ReleaseUS|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -74,13 +74,13 @@
|
|||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(ProjectDir)assets;$(ProjectDir)build;$(ProjectDir)include;$(ProjectDir)src;$(ProjectDir);$(ProjectDir)..\libultraship\libultraship\Lib\libjpeg\include;$(ProjectDir)..\libultraship\libultraship;$(ProjectDir)..\libultraship\libultraship\Lib\spdlog\include;$(ProjectDir)..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\libultraship\libultraship\Lib\Fast3D\U64\PR;$(ProjectDir)..\libultraship\libultraship\Lib\SDL;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(OutDir);$(ProjectDir)..\libultraship\libultraship;$(ProjectDir)..\libultraship\libultraship\Lib\SDL\lib\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLEW\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLFW;$(LibraryPath)</LibraryPath>
|
||||
<LibraryPath>$(OutDir);$(ProjectDir)..\libultraship\libultraship;$(ProjectDir)..\libultraship\libultraship\Lib\SDL\lib\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLEW\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLFW;$(ProjectDir)..\StormLib\bin\StormLib\Win32\DebugUS\;$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(Configuration)Obj\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)assets;$(ProjectDir)build;$(ProjectDir)include;$(ProjectDir)src;$(ProjectDir);$(ProjectDir)..\libultraship\libultraship\Lib\libjpeg\include;$(ProjectDir)..\libultraship\libultraship;$(ProjectDir)..\libultraship\libultraship\Lib\spdlog\include;$(ProjectDir)..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\libultraship\libultraship\Lib\Fast3D\U64\PR;$(ProjectDir)..\libultraship\libultraship\Lib\SDL;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(OutDir);$(ProjectDir)..\libultraship\libultraship;$(ProjectDir)..\libultraship\libultraship\Lib\SDL\lib\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLEW\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLFW;$(LibraryPath)</LibraryPath>
|
||||
<LibraryPath>$(OutDir);$(ProjectDir)..\libultraship\libultraship;$(ProjectDir)..\libultraship\libultraship\Lib\SDL\lib\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLEW\x86;$(ProjectDir)..\libultraship\libultraship\Lib\GLFW;$(ProjectDir)..\StormLib\bin\StormLib\Win32\ReleaseUS\;$(LibraryPath)</LibraryPath>
|
||||
<IntDir>$(Configuration)Obj\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -173,6 +173,7 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="soh\Enhancements\debugger\actorViewer.cpp" />
|
||||
<ClCompile Include="soh\frame_interpolation.cpp" />
|
||||
<ClCompile Include="soh\Enhancements\bootcommands.c" />
|
||||
<ClCompile Include="soh\Enhancements\debugconsole.cpp" />
|
||||
|
@ -185,6 +186,7 @@
|
|||
<ClCompile Include="soh\GbiWrap.cpp" />
|
||||
<ClCompile Include="soh\gu_pc.c" />
|
||||
<ClCompile Include="soh\OTRGlobals.cpp" />
|
||||
<ClCompile Include="soh\SaveManager.cpp" />
|
||||
<ClCompile Include="soh\stubs.c" />
|
||||
<ClCompile Include="soh\util.cpp" />
|
||||
<ClCompile Include="soh\z_message_OTR.cpp" />
|
||||
|
@ -879,6 +881,7 @@
|
|||
<ClCompile Include="src\overlays\misc\ovl_map_mark_data\z_map_mark_data.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="soh\Enhancements\debugger\actorViewer.h" />
|
||||
<ClInclude Include="soh\frame_interpolation.h" />
|
||||
<ClInclude Include="include\alloca.h" />
|
||||
<ClInclude Include="include\bgm.h" />
|
||||
|
@ -933,8 +936,10 @@
|
|||
<ClInclude Include="soh\Enhancements\debugger\debugSaveEditor.h" />
|
||||
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h" />
|
||||
<ClInclude Include="soh\gameconsole.h" />
|
||||
<ClInclude Include="soh\Lib\nlohmann\json.hpp" />
|
||||
<ClInclude Include="soh\OTRAudio.h" />
|
||||
<ClInclude Include="soh\OTRGlobals.h" />
|
||||
<ClInclude Include="soh\SaveManager.h" />
|
||||
<ClInclude Include="soh\util.h" />
|
||||
<ClInclude Include="src\overlays\actors\ovl_Arms_Hook\z_arms_hook.h" />
|
||||
<ClInclude Include="src\overlays\actors\ovl_Arrow_Fire\z_arrow_fire.h" />
|
||||
|
|
|
@ -82,6 +82,12 @@
|
|||
<Filter Include="Source Files\soh\Enhancements\debugger">
|
||||
<UniqueIdentifier>{04fc1c52-49ff-48e2-ae23-2c00867374f8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\soh\Lib">
|
||||
<UniqueIdentifier>{dbcf07c4-80b1-4c88-ac54-2bbdd8f53ee4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\soh\Lib\nlohmann">
|
||||
<UniqueIdentifier>{9c880c8e-492b-48f6-b230-1fd269ea74b1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\boot\assert.c">
|
||||
|
@ -2184,8 +2190,12 @@
|
|||
<ClCompile Include="soh\Enhancements\debugger\colViewer.cpp">
|
||||
<Filter>Source Files\soh\Enhancements\debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="soh\Enhancements\debugger\actorViewer.cpp">
|
||||
<Filter>Source Files\soh\Enhancements\debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="soh\Enhancements\debugger\ImGuiHelpers.cpp">
|
||||
<Filter>Source Files\soh\Enhancements\debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="soh\frame_interpolation.cpp">
|
||||
<Filter>Source Files\soh</Filter>
|
||||
</ClCompile>
|
||||
|
@ -2195,6 +2205,9 @@
|
|||
<ClCompile Include="soh\Enhancements\savestates.cpp">
|
||||
<Filter>Source Files\soh\Enhancements</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="soh\SaveManager.cpp">
|
||||
<Filter>Source Files\soh</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\overlays\actors\ovl_kaleido_scope\z_kaleido_scope.h">
|
||||
|
@ -3748,8 +3761,12 @@
|
|||
<ClInclude Include="soh\Enhancements\debugger\colViewer.h">
|
||||
<Filter>Header Files\soh\Enhancements\debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\Enhancements\debugger\actorViewer.h">
|
||||
<Filter>Header Files\soh\Enhancements\debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\Enhancements\debugger\ImGuiHelpers.h">
|
||||
<Filter>Header Files\soh\Enhancements\debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\frame_interpolation.h">
|
||||
<Filter>Header Files\soh</Filter>
|
||||
</ClInclude>
|
||||
|
@ -3759,20 +3776,17 @@
|
|||
<ClInclude Include="soh\OTRAudio.h">
|
||||
<Filter>Source Files\soh</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\Lib\nlohmann\json.hpp">
|
||||
<Filter>Source Files\soh\Lib\nlohmann</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="soh\SaveManager.h">
|
||||
<Filter>Source Files\soh</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="include\macro.inc">
|
||||
<Filter>Header Files\include</Filter>
|
||||
</None>
|
||||
<Image Include="SHIPOFHARKINIAN.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resource.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="SHIPOFHARKINIAN.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
<None Include="include\macro.inc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -25,16 +25,22 @@ void BootCommands_Init()
|
|||
CVar_RegisterS32("gDebugEnabled", 0);
|
||||
CVar_RegisterS32("gPauseLiveLink", 0);
|
||||
CVar_RegisterS32("gMinimalUI", 0);
|
||||
CVar_RegisterS32("gRedGanonBlood", 0);
|
||||
CVar_RegisterS32("gHoverFishing", 0);
|
||||
CVar_RegisterS32("gRumbleEnabled", 0);
|
||||
CVar_RegisterS32("gUniformLR", 1);
|
||||
CVar_RegisterS32("gUniformLR", 0);
|
||||
CVar_RegisterS32("gTwoHandedIdle", 0);
|
||||
CVar_RegisterS32("gDekuNutUpgradeFix", 1);
|
||||
CVar_RegisterS32("gDekuNutUpgradeFix", 0);
|
||||
CVar_RegisterS32("gNaviTextFix", 0);
|
||||
CVar_RegisterS32("gNewDrops", 0);
|
||||
CVar_RegisterS32("gVisualAgony", 0);
|
||||
CVar_RegisterS32("gLanguages", 0); //0 = English / 1 = German / 2 = French
|
||||
CVar_RegisterS32("gGravediggingTourFix", 1);
|
||||
CVar_RegisterS32("gHudColors", 1); //0 = N64 / 1 = NGC / 2 = Custom
|
||||
CVar_RegisterS32("gUseNaviCol", 0);
|
||||
CVar_RegisterS32("gUseTunicsCol", 0);
|
||||
CVar_RegisterS32("gGuardVision", 0);
|
||||
CVar_RegisterS32("gTimeFlowFileSelect", 0);
|
||||
}
|
||||
|
||||
//void BootCommands_ParseBootArgs(char* str)
|
||||
|
|
779
soh/soh/Enhancements/debugger/actorViewer.cpp
Normal file
779
soh/soh/Enhancements/debugger/actorViewer.cpp
Normal file
|
@ -0,0 +1,779 @@
|
|||
#include "actorViewer.h"
|
||||
#include "../../util.h"
|
||||
#include "../libultraship/SohImGuiImpl.h"
|
||||
#include "ImGuiHelpers.h"
|
||||
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <Cvar.h>
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
#include "z64math.h"
|
||||
#include "variables.h"
|
||||
#include "functions.h"
|
||||
#include "macros.h"
|
||||
extern GlobalContext* gGlobalCtx;
|
||||
|
||||
#include "textures/icon_item_static/icon_item_static.h"
|
||||
#include "textures/icon_item_24_static/icon_item_24_static.h"
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
u16 id;
|
||||
u16 params;
|
||||
Vec3f pos;
|
||||
Vec3s rot;
|
||||
} ActorInfo;
|
||||
|
||||
typedef enum {
|
||||
LIST,
|
||||
TARGET,
|
||||
HELD,
|
||||
INTERACT
|
||||
} RetrievalMethod;
|
||||
|
||||
std::array<const char*, 12> acMapping = {
|
||||
"Switch",
|
||||
"Background (Prop type 1)",
|
||||
"Player",
|
||||
"Bomb",
|
||||
"NPC",
|
||||
"Enemy",
|
||||
"Prop type 2",
|
||||
"Item/Action",
|
||||
"Misc.",
|
||||
"Boss",
|
||||
"Door",
|
||||
"Chest"
|
||||
};
|
||||
|
||||
// https://wiki.cloudmodding.com/oot/Actor_List_(Variables)
|
||||
std::map<u16, const char*> actorDescriptions = {
|
||||
{ ACTOR_PLAYER, "Link" },
|
||||
{ ACTOR_EN_TEST, "Stalfos" },
|
||||
{ ACTOR_EN_GIRLA, "Shop Items" },
|
||||
{ ACTOR_EN_PART, "Body Parts" },
|
||||
{ ACTOR_EN_LIGHT, "Decorative Flames" },
|
||||
{ ACTOR_EN_DOOR, "Door" },
|
||||
{ ACTOR_EN_BOX, "Treasure Chest" },
|
||||
{ ACTOR_BG_DY_YOSEIZO, "Great Fairy" },
|
||||
{ ACTOR_BG_HIDAN_FIREWALL, "Proximity activated Fire Wall" },
|
||||
{ ACTOR_EN_POH, "Poe" },
|
||||
{ ACTOR_EN_OKUTA, "Octorok" },
|
||||
{ ACTOR_BG_YDAN_SP, "Webs" },
|
||||
{ ACTOR_EN_BOM, "Bomb" },
|
||||
{ ACTOR_EN_WALLMAS, "Wallmaster" },
|
||||
{ ACTOR_EN_DODONGO, "Dodongo" },
|
||||
{ ACTOR_EN_FIREFLY, "Keese" },
|
||||
{ ACTOR_EN_HORSE, "Rideable Horse" },
|
||||
{ ACTOR_EN_ITEM00, "Collectibles" },
|
||||
{ ACTOR_EN_ARROW, "Arrow" },
|
||||
{ ACTOR_EN_ELF, "Fairy" },
|
||||
{ ACTOR_EN_NIW, "Cucco" },
|
||||
{ ACTOR_EN_TITE, "Tektite" },
|
||||
{ ACTOR_EN_REEBA, "Leever" },
|
||||
{ ACTOR_EN_PEEHAT, "Peahat and Larva" },
|
||||
{ ACTOR_EN_BUTTE, "Butterfly" },
|
||||
{ ACTOR_EN_INSECT, "Bugs" },
|
||||
{ ACTOR_EN_FISH, "Fish" },
|
||||
{ ACTOR_EN_HOLL, "Room changing plane" },
|
||||
{ ACTOR_EN_SCENE_CHANGE, "ovl_En_Scene_Change (broken)" },
|
||||
{ ACTOR_EN_ZF, "Lizalfos and Dinolfos" },
|
||||
{ ACTOR_EN_HATA, "Wooden Flagpole with Red Cloth" },
|
||||
{ ACTOR_BOSS_DODONGO, "King Dodongo" },
|
||||
{ ACTOR_BOSS_GOMA, "Gohma" },
|
||||
{ ACTOR_EN_ZL1, "Child Princess Zelda (at window)" },
|
||||
{ ACTOR_EN_VIEWER, "Cutscene Actors" },
|
||||
{ ACTOR_EN_GOMA, "Gohma Larva" },
|
||||
{ ACTOR_BG_PUSHBOX, "Cube" },
|
||||
{ ACTOR_EN_BUBBLE, "Shabom" },
|
||||
{ ACTOR_DOOR_SHUTTER, "Shutter Door" },
|
||||
{ ACTOR_EN_DODOJR, "Baby Dodongo" },
|
||||
{ ACTOR_EN_BDFIRE, "Empty" },
|
||||
{ ACTOR_EN_BOOM, "Boomerang" },
|
||||
{ ACTOR_EN_TORCH2, "Dark Link" },
|
||||
{ ACTOR_EN_BILI, "Biri" },
|
||||
{ ACTOR_EN_TP, "Electric Tailpasaran" },
|
||||
{ ACTOR_EN_ST, "Skulltula" },
|
||||
{ ACTOR_EN_BW, "Torch Slug" },
|
||||
{ ACTOR_EN_A_OBJ, "Gameplay_keep items" },
|
||||
{ ACTOR_EN_EIYER, "Stinger (Land)" },
|
||||
{ ACTOR_EN_RIVER_SOUND, "Ambient Sound Effects" },
|
||||
{ ACTOR_EN_HORSE_NORMAL, "Horse" },
|
||||
{ ACTOR_EN_OSSAN, "Shopkeeper" },
|
||||
{ ACTOR_BG_TREEMOUTH, "Great Deku Tree's Jaw" },
|
||||
{ ACTOR_BG_DODOAGO, "Dodongo's Cavern Mega Dodongo" },
|
||||
{ ACTOR_BG_HIDAN_DALM, "Megaton Hammer Statue" },
|
||||
{ ACTOR_BG_HIDAN_HROCK, "Huge stone spike platform (Fire Temple)" },
|
||||
{ ACTOR_EN_HORSE_GANON, "Ganondorf's Horse" },
|
||||
{ ACTOR_BG_HIDAN_ROCK, "Stone Blocks (Fire Temple)" },
|
||||
{ ACTOR_BG_HIDAN_RSEKIZOU, "Spinning Stone Flamethrower (Fire Temple)" },
|
||||
{ ACTOR_BG_HIDAN_SEKIZOU, "Stationary Flamethrower Statue (Fire Temple)" },
|
||||
{ ACTOR_BG_HIDAN_SIMA, "Stone Platform (Fire Temple)" },
|
||||
{ ACTOR_BG_HIDAN_SYOKU, "Stone Elevator (Fire Temple)" },
|
||||
{ ACTOR_EN_XC, "Sheik" },
|
||||
{ ACTOR_BG_HIDAN_CURTAIN, "Flame Circle" },
|
||||
{ ACTOR_BG_SPOT00_HANEBASI, "Drawbridge Objects" },
|
||||
{ ACTOR_EN_MB, "Moblins" },
|
||||
{ ACTOR_EN_BOMBF, "Bombflower" },
|
||||
{ ACTOR_EN_ZL2, "Adult Zelda (Cutscenes)" },
|
||||
{ ACTOR_BG_HIDAN_FSLIFT, "Hookshot Elevator Platform (Fire Temple)" },
|
||||
{ ACTOR_EN_OE2, "Unused NPC" },
|
||||
{ ACTOR_BG_YDAN_HASI, "Deku Tree Puzzle elements" },
|
||||
{ ACTOR_BG_YDAN_MARUTA, "Rotating Spiked Log (Deku Tree)" },
|
||||
{ ACTOR_BOSS_GANONDROF, "Phantom Ganon" },
|
||||
{ ACTOR_EN_AM, "Armos Statue" },
|
||||
{ ACTOR_EN_DEKUBABA, "Deku Baba" },
|
||||
{ ACTOR_EN_M_FIRE1, "Thrown Deku Nut" },
|
||||
{ ACTOR_EN_M_THUNDER, "Spin Attack" },
|
||||
{ ACTOR_BG_DDAN_JD, "Rising Stone Platform (Dodongo's Cavern)" },
|
||||
{ ACTOR_BG_BREAKWALL, "Bombable Wall" },
|
||||
{ ACTOR_EN_JJ, "Lord Jabu-Jabu" },
|
||||
{ ACTOR_EN_HORSE_ZELDA, "Zelda's Horse" },
|
||||
{ ACTOR_BG_DDAN_KD, "Stone Stairs (Dodongo's Cavern)" },
|
||||
{ ACTOR_DOOR_WARP1, "Warp Portal" },
|
||||
{ ACTOR_OBJ_SYOKUDAI, "Torch" },
|
||||
{ ACTOR_ITEM_B_HEART, "Heart container" },
|
||||
{ ACTOR_EN_DEKUNUTS, "Mad Scrub" },
|
||||
{ ACTOR_BG_MENKURI_KAITEN, "Rotating Stone Ring Platform" },
|
||||
{ ACTOR_BG_MENKURI_EYE, "Eye Statue" },
|
||||
{ ACTOR_EN_VALI, "Bari" },
|
||||
{ ACTOR_BG_MIZU_MOVEBG, "Water Temple Background Actors" },
|
||||
{ ACTOR_BG_MIZU_WATER, "Water Plane (Water Temple)" },
|
||||
{ ACTOR_ARMS_HOOK, "Hookshot" },
|
||||
{ ACTOR_EN_FHG, "Phantom Ganon's Horse" },
|
||||
{ ACTOR_BG_MORI_HINERI, "Twisted Hallway Rooms" },
|
||||
{ ACTOR_EN_BB, "Bubble" },
|
||||
{ ACTOR_BG_TOKI_HIKARI, "Windows (Temple of Time)" },
|
||||
{ ACTOR_EN_YUKABYUN, "Flying Floor Tile" },
|
||||
{ ACTOR_BG_TOKI_SWD, "Master Sword" },
|
||||
{ ACTOR_EN_FHG_FIRE, "Empty" },
|
||||
{ ACTOR_BG_MJIN, "Warp Song Pad" },
|
||||
{ ACTOR_BG_HIDAN_KOUSI, "Sliding Metal Gate" },
|
||||
{ ACTOR_DOOR_TOKI, "Door of Time Collision" },
|
||||
{ ACTOR_BG_HIDAN_HAMSTEP, "Stone Steps and Platforms (Fire Temple)" },
|
||||
{ ACTOR_EN_BIRD, "Brown Bird" },
|
||||
{ ACTOR_EN_WOOD02, "Trees and Bushes" },
|
||||
{ ACTOR_EN_LIGHTBOX, "Large noisy stone" },
|
||||
{ ACTOR_EN_PU_BOX, "Stone cube" },
|
||||
{ ACTOR_EN_TRAP, "Metal Spike Trap" },
|
||||
{ ACTOR_EN_AROW_TRAP, "Arrow Trap" },
|
||||
{ ACTOR_EN_VASE, "Orange Pot" },
|
||||
{ ACTOR_EN_TA, "Talon" },
|
||||
{ ACTOR_EN_TK, "Dampe (Alive)" },
|
||||
{ ACTOR_BG_MORI_BIGST, "Large Round Platform (Forest Temple)" },
|
||||
{ ACTOR_BG_MORI_ELEVATOR, "Elevator (Forest Temple)" },
|
||||
{ ACTOR_BG_MORI_KAITENKABE, "Rotatable Walls (Forest Temple)" },
|
||||
{ ACTOR_BG_MORI_RAKKATENJO, "Falling Ceiling (Forest Temple)" },
|
||||
{ ACTOR_EN_VM, "Beamos" },
|
||||
{ ACTOR_DEMO_EFFECT, "Spiritual Stones, Medallions, Triforce" },
|
||||
{ ACTOR_DEMO_KANKYO, "Temple of Time Objects" },
|
||||
{ ACTOR_BG_HIDAN_FWBIG, "Large Fire Wall (Fire Temple)" },
|
||||
{ ACTOR_EN_FLOORMAS, "Floormaster" },
|
||||
{ ACTOR_EN_HEISHI1, "Castle Courtyard Guards" },
|
||||
{ ACTOR_EN_RD, "Redead and Gibdo" },
|
||||
{ ACTOR_EN_PO_SISTERS, "Poe Sisters" },
|
||||
{ ACTOR_BG_HEAVY_BLOCK, "Golden Gauntlets Pillar" },
|
||||
{ ACTOR_BG_PO_EVENT, "Poe Sisters' Paintings and Puzzle Block" },
|
||||
{ ACTOR_OBJ_MURE, "Fish, Bugs, Butterflies Group Spawner" },
|
||||
{ ACTOR_EN_SW, "Skullwalltula and Gold Skulltulas" },
|
||||
{ ACTOR_BOSS_FD, "Volvagia (Flying)" },
|
||||
{ ACTOR_OBJECT_KANKYO, "Environmental Effects" },
|
||||
{ ACTOR_EN_DU, "Darunia" },
|
||||
{ ACTOR_EN_FD, "Flare Dancer" },
|
||||
{ ACTOR_EN_HORSE_LINK_CHILD, "Young Epona" },
|
||||
{ ACTOR_DOOR_ANA, "Grotto Entrance" },
|
||||
{ ACTOR_BG_SPOT02_OBJECTS, "Graveyard Actors" },
|
||||
{ ACTOR_BG_HAKA, "Gravestone" },
|
||||
{ ACTOR_MAGIC_WIND, "Farore's Wind" },
|
||||
{ ACTOR_MAGIC_FIRE, "Din's Fire" },
|
||||
{ ACTOR_EN_RU1, "Ruto (Child)" },
|
||||
{ ACTOR_BOSS_FD2, "Volvagia (Hole Form)" },
|
||||
{ ACTOR_EN_FD_FIRE, "Flare Dancer Fire Attack" },
|
||||
{ ACTOR_EN_DH, "Dead Hand" },
|
||||
{ ACTOR_EN_DHA, "Dead Hand's Hand" },
|
||||
{ ACTOR_EN_RL, "Rauru" },
|
||||
{ ACTOR_EN_ENCOUNT1, "Enemy Spawner" },
|
||||
{ ACTOR_DEMO_DU, "Darunia (Cutscenes)" },
|
||||
{ ACTOR_DEMO_IM, "Impa (Cutscenes)" },
|
||||
{ ACTOR_DEMO_TRE_LGT, "Treasure Chest Light" },
|
||||
{ ACTOR_EN_FW, "Flare Dancer Core" },
|
||||
{ ACTOR_BG_VB_SIMA, "Volvagia Platform" },
|
||||
{ ACTOR_EN_VB_BALL, "Volvagia Rocks and Bones" },
|
||||
{ ACTOR_BG_HAKA_MEGANE, "Shadow Temple Fake Walls" },
|
||||
{ ACTOR_BG_HAKA_MEGANEBG, "Platforms (Shadow Temple)" },
|
||||
{ ACTOR_BG_HAKA_SHIP, "River Boat (Shadow Temple)" },
|
||||
{ ACTOR_BG_HAKA_SGAMI, "Spinning Scythe Trap" },
|
||||
{ ACTOR_EN_HEISHI2, "Hyrulian Guards" },
|
||||
{ ACTOR_EN_ENCOUNT2, "Falling Rock Spawner" },
|
||||
{ ACTOR_EN_FIRE_ROCK, "Falling Burning Rocks" },
|
||||
{ ACTOR_EN_BROB, "Flobbery Muscle Block (Jabu-Jabu's Belly)" },
|
||||
{ ACTOR_MIR_RAY, "Reflectable Light Beam" },
|
||||
{ ACTOR_BG_SPOT09_OBJ, "Gerudo Valley Objects" },
|
||||
{ ACTOR_BG_SPOT18_OBJ, "Statue (Darunia's Room)" },
|
||||
{ ACTOR_BOSS_VA, "Barinade" },
|
||||
{ ACTOR_BG_HAKA_TUBO, "Giant Skull Jar (Shadow Temple)" },
|
||||
{ ACTOR_BG_HAKA_TRAP, "Shadow Temple Traps" },
|
||||
{ ACTOR_BG_HAKA_HUTA, "Coffin Lid" },
|
||||
{ ACTOR_BG_HAKA_ZOU, "Bird Statue and Wall (Shadow Temple)" },
|
||||
{ ACTOR_BG_SPOT17_FUNEN, "Smoke Cone (Death Mountain Crater)" },
|
||||
{ ACTOR_EN_SYATEKI_ITM, "Shooting Gallery Game" },
|
||||
{ ACTOR_EN_SYATEKI_MAN, "Shooting Gallery Man" },
|
||||
{ ACTOR_EN_TANA, "Shop Shelves" },
|
||||
{ ACTOR_EN_NB, "Nabooru" },
|
||||
{ ACTOR_BOSS_MO, "Morpha" },
|
||||
{ ACTOR_EN_SB, "Shell Blade" },
|
||||
{ ACTOR_EN_BIGOKUTA, "Big Octo" },
|
||||
{ ACTOR_EN_KAREBABA, "Withered Deku Baba" },
|
||||
{ ACTOR_BG_BDAN_OBJECTS, "Inside Jabu-Jabu's Belly Objects" },
|
||||
{ ACTOR_DEMO_SA, "Saria (Cutscenes)" },
|
||||
{ ACTOR_DEMO_GO, "Gorons (Cutscene)" },
|
||||
{ ACTOR_EN_IN, "Ingo" },
|
||||
{ ACTOR_EN_TR, "Koume and Kotake" },
|
||||
{ ACTOR_BG_SPOT16_BOMBSTONE, "Dodongo's Cavern Entrance Blocking Rock" },
|
||||
{ ACTOR_BG_HIDAN_KOWARERUKABE, "Bombable Walls (Fire Temple)" },
|
||||
{ ACTOR_BG_BOMBWALL, "2D Bombable Wall" },
|
||||
{ ACTOR_BG_SPOT08_ICEBLOCK, "Ice Platform (Zora's Fountain)" },
|
||||
{ ACTOR_EN_RU2, "Ruto (Adult)" },
|
||||
{ ACTOR_OBJ_DEKUJR, "Deku Tree Sprout" },
|
||||
{ ACTOR_BG_MIZU_UZU, "Water Vortex Effect (Water Temple)" },
|
||||
{ ACTOR_BG_SPOT06_OBJECTS, "Lake Hylia Objects" },
|
||||
{ ACTOR_BG_ICE_OBJECTS, "Pushable Ice Block (Ice Cavern)" },
|
||||
{ ACTOR_BG_HAKA_WATER, "Bottom of the Well Water Level Changer" },
|
||||
{ ACTOR_EN_MA2, "Malon (Adult, Ingo's Ranch)" },
|
||||
{ ACTOR_EN_BOM_CHU, "Bombchu" },
|
||||
{ ACTOR_EN_HORSE_GAME_CHECK, "Horseback Minigames" },
|
||||
{ ACTOR_BOSS_TW, "Twinrova" },
|
||||
{ ACTOR_EN_RR, "Like-Like" },
|
||||
{ ACTOR_EN_BA, "Tentacle (Inside Jabu-Jabu's Belly)" },
|
||||
{ ACTOR_EN_BX, "Electrified Tentacle (Inside Jabu-Jabu's Belly)" },
|
||||
{ ACTOR_EN_ANUBICE, "Anubis (Body)" },
|
||||
{ ACTOR_EN_ANUBICE_FIRE, "Anubis Fire Attack" },
|
||||
{ ACTOR_BG_MORI_HASHIGO, "Ladder (Forest Temple)" },
|
||||
{ ACTOR_BG_MORI_HASHIRA4, "Forest Temple Objects" },
|
||||
{ ACTOR_BG_MORI_IDOMIZU, "Well Water (Forest Temple)" },
|
||||
{ ACTOR_BG_SPOT16_DOUGHNUT, "Cloud Ring (Death Mountain)" },
|
||||
{ ACTOR_BG_BDAN_SWITCH, "Switches (Inside Lord Jabu-Jabu)" },
|
||||
{ ACTOR_EN_MA1, "Malon (Child)" },
|
||||
{ ACTOR_BOSS_GANON, "Ganondorf" },
|
||||
{ ACTOR_BOSS_SST, "Bongo Bongo" },
|
||||
{ ACTOR_EN_NY, "Spike (Enemy)" },
|
||||
{ ACTOR_EN_FR, "Frog Song Spot and Frogs" },
|
||||
{ ACTOR_ITEM_SHIELD, "Deku Shield" },
|
||||
{ ACTOR_BG_ICE_SHELTER, "Red Ice" },
|
||||
{ ACTOR_EN_ICE_HONO, "Blue Fire Flames" },
|
||||
{ ACTOR_ITEM_OCARINA, "Ocarina of Time" },
|
||||
{ ACTOR_MAGIC_DARK, "Nayru's Love" },
|
||||
{ ACTOR_DEMO_6K, "Sages, Balls of Light (Cutscene)" },
|
||||
{ ACTOR_EN_ANUBICE_TAG, "Anubis Spawn" },
|
||||
{ ACTOR_BG_HAKA_GATE, "Truth Spinner Puzzle (Shadow Temple)" },
|
||||
{ ACTOR_BG_SPOT15_SAKU, "Hyrule Castle Gate" },
|
||||
{ ACTOR_BG_JYA_GOROIWA, "Rolling Boulder (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_ZURERUKABE, "Sliding, Climbable Brick Wall (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_COBRA, "Rotatable Cobra Mirror (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_KANAAMI, "Climbable Metal Grating Bridge (Spirit Temple)" },
|
||||
{ ACTOR_FISHING, "Fishing Pond Man and Fish" },
|
||||
{ ACTOR_OBJ_OSHIHIKI, "Pushable Block" },
|
||||
{ ACTOR_BG_GATE_SHUTTER, "Gate to Death Mountain Trail" },
|
||||
{ ACTOR_EFF_DUST, "Dust Effects" },
|
||||
{ ACTOR_BG_SPOT01_FUSYA, "Windmill Sails (Kakariko Village)" },
|
||||
{ ACTOR_BG_SPOT01_IDOHASHIRA, "Well Crossbeam (Kakariko Village)" },
|
||||
{ ACTOR_BG_SPOT01_IDOMIZU, "Well Water (Kakariko Village)" },
|
||||
{ ACTOR_BG_PO_SYOKUDAI, "Golden Torch (Poe Sisters)" },
|
||||
{ ACTOR_BG_GANON_OTYUKA, "Falling Platform (Ganondorf Fight)" },
|
||||
{ ACTOR_BG_SPOT15_RRBOX, "Milk Crate" },
|
||||
{ ACTOR_BG_UMAJUMP, "Obstacle Fence (Lon Lon Ranch)" },
|
||||
{ ACTOR_ARROW_FIRE, "Fire Arrow" },
|
||||
{ ACTOR_ARROW_ICE, "Ice Arrow" },
|
||||
{ ACTOR_ARROW_LIGHT, "Light Arrow" },
|
||||
{ ACTOR_ITEM_ETCETERA, "Collectible Items" },
|
||||
{ ACTOR_OBJ_KIBAKO, "Small Liftable Crate" },
|
||||
{ ACTOR_OBJ_TSUBO, "Breakable Pot" },
|
||||
{ ACTOR_EN_WONDER_ITEM, "Invisible Collectible" },
|
||||
{ ACTOR_EN_IK, "Iron Knuckle" },
|
||||
{ ACTOR_DEMO_IK, "Iron Knuckle armor pieces (Spirit Temple Nabooru fight)" },
|
||||
{ ACTOR_EN_SKJ, "Skullkid" },
|
||||
{ ACTOR_EN_SKJNEEDLE, "Skullkid Needle Attack" },
|
||||
{ ACTOR_EN_G_SWITCH, "Silver Rupee" },
|
||||
{ ACTOR_DEMO_EXT, "Magic Vortex" },
|
||||
{ ACTOR_DEMO_SHD, "Bongo Bongo's Shadow" },
|
||||
{ ACTOR_EN_DNS, "Business Scrub" },
|
||||
{ ACTOR_ELF_MSG, "Navi Message" },
|
||||
{ ACTOR_EN_HONOTRAP, "Stone Eye (Fire Trap) and Flame" },
|
||||
{ ACTOR_EN_TUBO_TRAP, "Flying Pot" },
|
||||
{ ACTOR_OBJ_ICE_POLY, "Ice spawned by red ice? frozen actors" },
|
||||
{ ACTOR_BG_SPOT03_TAKI, "Zora's River Waterfall" },
|
||||
{ ACTOR_BG_SPOT07_TAKI, "Zora's Domain Waterfall and Ice" },
|
||||
{ ACTOR_EN_FZ, "Frezzard" },
|
||||
{ ACTOR_EN_PO_RELAY, "Dampe's Ghost" },
|
||||
{ ACTOR_BG_RELAY_OBJECTS, "Windmill Objects" },
|
||||
{ ACTOR_EN_DIVING_GAME, "Zora Diving Game" },
|
||||
{ ACTOR_EN_KUSA, "Bush/Grass" },
|
||||
{ ACTOR_OBJ_BEAN, "Bean Plant Spot" },
|
||||
{ ACTOR_OBJ_BOMBIWA, "Brown Bombable Boulder" },
|
||||
{ ACTOR_OBJ_SWITCH, "Switches" },
|
||||
{ ACTOR_OBJ_ELEVATOR, "Huge Stone Elevator" },
|
||||
{ ACTOR_OBJ_LIFT, "Square Collapsing Platform" },
|
||||
{ ACTOR_OBJ_HSBLOCK, "Stone Hookshot Target" },
|
||||
{ ACTOR_EN_OKARINA_TAG, "Ocarina Music Staff Spot" },
|
||||
{ ACTOR_EN_YABUSAME_MARK, "Horseback Archery Target" },
|
||||
{ ACTOR_EN_GOROIWA, "Rolling Boulder" },
|
||||
{ ACTOR_EN_EX_RUPPY, "Sparkling Rupee" },
|
||||
{ ACTOR_EN_TORYO, "Boss Carpenter" },
|
||||
{ ACTOR_EN_DAIKU, "Carpenters" },
|
||||
{ ACTOR_EN_NWC, "Cucco Chick" },
|
||||
{ ACTOR_EN_BLKOBJ, "Dark Link's Illusion Room" },
|
||||
{ ACTOR_ITEM_INBOX, "Zelda's Magic to Open Gates" },
|
||||
{ ACTOR_EN_GE1, "White Clothed Gerudo" },
|
||||
{ ACTOR_OBJ_BLOCKSTOP, "Pushblock Stop" },
|
||||
{ ACTOR_EN_SDA, "Dynamic Shadow" },
|
||||
{ ACTOR_EN_CLEAR_TAG, "Arwing" },
|
||||
{ ACTOR_EN_NIW_LADY, "Cucco Lady" },
|
||||
{ ACTOR_EN_GM, "Medigoron" },
|
||||
{ ACTOR_EN_MS, "Bean Salesman" },
|
||||
{ ACTOR_EN_HS, "Carpenter's Son" },
|
||||
{ ACTOR_BG_INGATE, "Ingo's Gates (Lon Lon Ranch)" },
|
||||
{ ACTOR_EN_KANBAN, "Square Signpost" },
|
||||
{ ACTOR_EN_HEISHI3, "Hyrule Castle Guard" },
|
||||
{ ACTOR_EN_SYATEKI_NIW, "Cucco (Minigames)" },
|
||||
{ ACTOR_EN_ATTACK_NIW, "Cucco (Attacking)" },
|
||||
{ ACTOR_BG_SPOT01_IDOSOKO, "Stone Blocking Entrance to Bottom of the Well" },
|
||||
{ ACTOR_EN_SA, "Saria" },
|
||||
{ ACTOR_EN_WONDER_TALK, "Checkable Spot (Green Navi)" },
|
||||
{ ACTOR_BG_GJYO_BRIDGE, "Rainbow Bridge to Ganon's Castle" },
|
||||
{ ACTOR_EN_DS, "Potion Shop Granny" },
|
||||
{ ACTOR_EN_MK, "Lakeside Professor" },
|
||||
{ ACTOR_EN_BOM_BOWL_MAN, "Bombchu Bowling Alley Lady" },
|
||||
{ ACTOR_EN_BOM_BOWL_PIT, "Bombchu Bowling Alley Final Target" },
|
||||
{ ACTOR_EN_OWL, "Kaepora Gaebora" },
|
||||
{ ACTOR_EN_ISHI, "Liftable Rock" },
|
||||
{ ACTOR_OBJ_HANA, "Uninteractable Flowers, Rocks, Grass" },
|
||||
{ ACTOR_OBJ_LIGHTSWITCH, "Sun Emblem Switch (Spirit Temple)" },
|
||||
{ ACTOR_OBJ_MURE2, "Rock/Bush groups" },
|
||||
{ ACTOR_EN_GO, "Gorons 1" },
|
||||
{ ACTOR_EN_FU, "Windmill Man" },
|
||||
{ ACTOR_EN_CHANGER, "Treasure Box Shop Minigame" },
|
||||
{ ACTOR_BG_JYA_MEGAMI, "Statue Face (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_LIFT, "Chain Platform (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_BIGMIRROR, "Large Circular Mirror (Spirt Temple)" },
|
||||
{ ACTOR_BG_JYA_BOMBCHUIWA, "Light Blocking Rock (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_AMISHUTTER, "Sliding Circular Metal Grate (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_BOMBIWA, "Bombable Rock Wall (Spirit Temple)" },
|
||||
{ ACTOR_BG_SPOT18_BASKET, "Big Goron Pot" },
|
||||
{ ACTOR_EN_GANON_ORGAN, "Ganon's Organ and surroundings" },
|
||||
{ ACTOR_EN_SIOFUKI, "Water Spout" },
|
||||
{ ACTOR_EN_STREAM, "Water Vortex" },
|
||||
{ ACTOR_EN_MM, "Running Man (Child Era)" },
|
||||
{ ACTOR_EN_KO, "Kokiri Children" },
|
||||
{ ACTOR_EN_KZ, "King Zora" },
|
||||
{ ACTOR_EN_WEATHER_TAG, "Proximity Weather Effects" },
|
||||
{ ACTOR_BG_SST_FLOOR, "Bongo Bongo's Drum" },
|
||||
{ ACTOR_EN_ANI, "Kakariko Village Rooftop Man" },
|
||||
{ ACTOR_EN_EX_ITEM, "Minigame Displayed Items" },
|
||||
{ ACTOR_BG_JYA_IRONOBJ, "Iron Knuckles Room Stuff (Spirit Temple)" },
|
||||
{ ACTOR_EN_JS, "Magic Carpet Man" },
|
||||
{ ACTOR_EN_JSJUTAN, "Magic Carpet Man Carpet" },
|
||||
{ ACTOR_EN_CS, "Graveyard Boy" },
|
||||
{ ACTOR_EN_MD, "Mido" },
|
||||
{ ACTOR_EN_HY, "Market NPCs" },
|
||||
{ ACTOR_EN_GANON_MANT, "Ganondorf's Cape" },
|
||||
{ ACTOR_EN_OKARINA_EFFECT, "Song of Storms Storm Manager" },
|
||||
{ ACTOR_EN_MAG, "Title Screen Manager" },
|
||||
{ ACTOR_DOOR_GERUDO, "Cell Door (Gerudo Fortress)" },
|
||||
{ ACTOR_ELF_MSG2, "Navi Information Spot (Targetable, Green)" },
|
||||
{ ACTOR_DEMO_GT, "Ganon's Tower Collapsing (Cutscene Objects)" },
|
||||
{ ACTOR_EN_PO_FIELD, "Big/Small Poe Spawn Point" },
|
||||
{ ACTOR_EFC_ERUPC, "Lava Particle Fountain (Death Mountain panorama)" },
|
||||
{ ACTOR_BG_ZG, "Metal Bars (Ganon's Castle)" },
|
||||
{ ACTOR_EN_HEISHI4, "Hyrule Guard" },
|
||||
{ ACTOR_EN_ZL3, "Adult Zelda" },
|
||||
{ ACTOR_BOSS_GANON2, "Ganon" },
|
||||
{ ACTOR_EN_KAKASI, "Pierre the Scarecrow" },
|
||||
{ ACTOR_EN_TAKARA_MAN, "Treasure Box Shop Man" },
|
||||
{ ACTOR_OBJ_MAKEOSHIHIKI, "Push Block Puzzles" },
|
||||
{ ACTOR_OCEFF_SPOT, "Sun's Song Effect" },
|
||||
{ ACTOR_END_TITLE, "The End message" },
|
||||
{ ACTOR_EN_TORCH, "Grotto Treasure Chest" },
|
||||
{ ACTOR_DEMO_EC, "Credits Revelers in Lon Lon" },
|
||||
{ ACTOR_SHOT_SUN, "Lake Hylia Sun Hitbox, Big Fairy Spawner" },
|
||||
{ ACTOR_EN_DY_EXTRA, "Spiral Beams (Great Fairy Fountains)" },
|
||||
{ ACTOR_EN_WONDER_TALK2, "Dialog Spot" },
|
||||
{ ACTOR_EN_GE2, "Patrolling Gerudo" },
|
||||
{ ACTOR_OBJ_ROOMTIMER, "Room Timer" },
|
||||
{ ACTOR_EN_SSH, "Cursed Skulltula People" },
|
||||
{ ACTOR_EN_STH, "Uncursed Skulltula People" },
|
||||
{ ACTOR_OCEFF_WIPE, "Zelda's Lullaby and Song of Time Ocarina Effect" },
|
||||
{ ACTOR_OCEFF_STORM, "Song of Storm Ocarina Effect" },
|
||||
{ ACTOR_EN_WEIYER, "Stinger (Water)" },
|
||||
{ ACTOR_BG_SPOT05_SOKO, "Sacred Forest Meadow Objects" },
|
||||
{ ACTOR_BG_JYA_1FLIFT, "Stone Elevator (Spirit Temple)" },
|
||||
{ ACTOR_BG_JYA_HAHENIRON, "Chunks of Iron Knucle Chair and Pillar" },
|
||||
{ ACTOR_BG_SPOT12_GATE, "Gerudo Fortress Wooden Gate" },
|
||||
{ ACTOR_BG_SPOT12_SAKU, "Gerudo Fortress Training Area Gate" },
|
||||
{ ACTOR_EN_HINTNUTS, "Hint Deku Scrubs (Deku Tree)" },
|
||||
{ ACTOR_EN_NUTSBALL, "Deku Scrub Nut Attack" },
|
||||
{ ACTOR_BG_SPOT00_BREAK, "Broken Drawbridge, Fences" },
|
||||
{ ACTOR_EN_SHOPNUTS, "Grounded Sales Scrub" },
|
||||
{ ACTOR_EN_IT, "Dampe's Minigame Collectibles" },
|
||||
{ ACTOR_EN_GELDB, "Gerudo Fighter" },
|
||||
{ ACTOR_OCEFF_WIPE2, "Epona's Song Ocarina Effect" },
|
||||
{ ACTOR_OCEFF_WIPE3, "Saria's Song Ocarina Effect" },
|
||||
{ ACTOR_EN_NIW_GIRL, "Girl Chasing Cucco" },
|
||||
{ ACTOR_EN_DOG, "Dog" },
|
||||
{ ACTOR_EN_SI, "Gold Skulltula Token" },
|
||||
{ ACTOR_BG_SPOT01_OBJECTS2, "Kakariko Village Objects" },
|
||||
{ ACTOR_OBJ_COMB, "Beehive" },
|
||||
{ ACTOR_BG_SPOT11_BAKUDANKABE, "Destructible Wall (Desert Colossus)" },
|
||||
{ ACTOR_OBJ_KIBAKO2, "Large Crate" },
|
||||
{ ACTOR_EN_DNT_DEMO, "Deku Mask Panel Trigger" },
|
||||
{ ACTOR_EN_DNT_JIJI, "Deku Mask Panel Head Judge" },
|
||||
{ ACTOR_EN_DNT_NOMAL, "Deku Game?" },
|
||||
{ ACTOR_EN_GUEST, "Happy Mask Shop Customer" },
|
||||
{ ACTOR_BG_BOM_GUARD, "Bombchu Bowling Alley Aiming Area" },
|
||||
{ ACTOR_EN_HS2, "Carpenter's Son (Child Era)" },
|
||||
{ ACTOR_DEMO_KEKKAI, "Ganon's Tower Magic Barriers" },
|
||||
{ ACTOR_BG_SPOT08_BAKUDANKABE, "Destructible Wall (Zora's Fountain)" },
|
||||
{ ACTOR_BG_SPOT17_BAKUDANKABE, "Destructible Wall (Death Mountain Crater)" },
|
||||
{ ACTOR_OBJ_MURE3, "Rupee Patterns" },
|
||||
{ ACTOR_EN_TG, "Entwined Lovers (Honey & Darling)" },
|
||||
{ ACTOR_EN_MU, "Haggling Townspeople" },
|
||||
{ ACTOR_EN_GO2, "Gorons 2" },
|
||||
{ ACTOR_EN_WF, "Wolfos" },
|
||||
{ ACTOR_EN_SKB, "Stalchild" },
|
||||
{ ACTOR_DEMO_GJ, "Ganon Battle Rubble" },
|
||||
{ ACTOR_DEMO_GEFF, "Ganon's Tower Rubble Fragment" },
|
||||
{ ACTOR_BG_GND_FIREMEIRO, "Sinking Lava Platform (Ganon's Castle)" },
|
||||
{ ACTOR_BG_GND_DARKMEIRO, "Clear block" },
|
||||
{ ACTOR_BG_GND_SOULMEIRO, "Web-Blocked Ceiling Hole (Inside Ganon's Castle)" },
|
||||
{ ACTOR_BG_GND_NISEKABE, "Ganon's Castle Fake Walls" },
|
||||
{ ACTOR_BG_GND_ICEBLOCK, "Pushable Square Ice Block (Inside Ganon's Castle)" },
|
||||
{ ACTOR_EN_GB, "Poe Collector and Surroundings" },
|
||||
{ ACTOR_EN_GS, "Gossip Stone" },
|
||||
{ ACTOR_BG_MIZU_BWALL, "Bombable Stone Wall" },
|
||||
{ ACTOR_BG_MIZU_SHUTTER, "Metal Gate (Water Temple)" },
|
||||
{ ACTOR_EN_DAIKU_KAKARIKO, "Carpenters (Kakariko)" },
|
||||
{ ACTOR_BG_BOWL_WALL, "Bombchu Bowling Alley Wall" },
|
||||
{ ACTOR_EN_WALL_TUBO, "Bombchu Bowling Alley Bullseyes" },
|
||||
{ ACTOR_EN_PO_DESERT, "Poe Guide (Desert Wasteland)" },
|
||||
{ ACTOR_EN_CROW, "Guay" },
|
||||
{ ACTOR_DOOR_KILLER, "Fake Door" },
|
||||
{ ACTOR_BG_SPOT11_OASIS, "Oasis (Desert Colossus)" },
|
||||
{ ACTOR_BG_SPOT18_FUTA, "Goron Jar Lid" },
|
||||
{ ACTOR_BG_SPOT18_SHUTTER, "Sliding Doors (Goron City)" },
|
||||
{ ACTOR_EN_MA3, "Malon (Adult, Lon Lon Ranch)" },
|
||||
{ ACTOR_EN_COW, "Cow" },
|
||||
{ ACTOR_BG_ICE_TURARA, "Icicles" },
|
||||
{ ACTOR_BG_ICE_SHUTTER, "Vertical Ice Bars (Ice Cavern)" },
|
||||
{ ACTOR_EN_KAKASI2, "Pierre the Scarecrow Spawn" },
|
||||
{ ACTOR_EN_KAKASI3, "Bonooru the Scarecrow" },
|
||||
{ ACTOR_OCEFF_WIPE4, "Scarecrow's Song Ocarina Effect" },
|
||||
{ ACTOR_EN_EG, "Void-out Trigger (Tower Collapse)" },
|
||||
{ ACTOR_BG_MENKURI_NISEKABE, "False Stone Walls (Gerudo Training Grounds)" },
|
||||
{ ACTOR_EN_ZO, "Zora" },
|
||||
{ ACTOR_OBJ_MAKEKINSUTA, "Skulltula Sprouting from Bean Spot" },
|
||||
{ ACTOR_EN_GE3, "Gerudo Fortress Leader" },
|
||||
{ ACTOR_OBJ_TIMEBLOCK, "Time Block" },
|
||||
{ ACTOR_OBJ_HAMISHI, "Bronze Boulder" },
|
||||
{ ACTOR_EN_ZL4, "Zelda (Child)" },
|
||||
{ ACTOR_EN_MM2, "Running Man (Adult Era)" },
|
||||
{ ACTOR_BG_JYA_BLOCK, "Silver Block (Child Era)" },
|
||||
{ ACTOR_OBJ_WARP2BLOCK, "Navi Infospot (Green, Time Block)" }
|
||||
};
|
||||
|
||||
const std::string GetActorDescription(u16 id) {
|
||||
return actorDescriptions[id] != NULL ? actorDescriptions[id] : "???";
|
||||
}
|
||||
|
||||
template <typename T> void DrawGroupWithBorder(T&& drawFunc) {
|
||||
// First group encapsulates the inner portion and border
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImVec2 padding = ImGui::GetStyle().FramePadding;
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
ImGui::SetCursorScreenPos(ImVec2(p0.x + padding.x, p0.y + padding.y));
|
||||
|
||||
// Second group encapsulates just the inner portion
|
||||
ImGui::BeginGroup();
|
||||
|
||||
drawFunc();
|
||||
|
||||
ImGui::Dummy(padding);
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImVec2 p1 = ImGui::GetItemRectMax();
|
||||
p1.x += padding.x;
|
||||
ImVec4 borderCol = ImGui::GetStyle().Colors[ImGuiCol_Border];
|
||||
ImGui::GetWindowDrawList()->AddRect(
|
||||
p0, p1, IM_COL32(borderCol.x * 255, borderCol.y * 255, borderCol.z * 255, borderCol.w * 255));
|
||||
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
void PopulateActorDropdown(int i, std::vector<Actor*>& data) {
|
||||
if (data.size() != 0) {
|
||||
data.clear();
|
||||
}
|
||||
if (gGlobalCtx != nullptr) {
|
||||
ActorListEntry currList = gGlobalCtx->actorCtx.actorLists[i];
|
||||
Actor* currAct = currList.head;
|
||||
if (currAct != nullptr) {
|
||||
while (currAct != nullptr) {
|
||||
data.push_back(currAct);
|
||||
currAct = currAct->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawActorViewer(bool& open) {
|
||||
if (!open) {
|
||||
CVar_SetS32("gActorViewerEnabled", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("Actor Viewer", &open, ImGuiWindowFlags_NoFocusOnAppearing)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
static Actor display;
|
||||
static const Actor empty{};
|
||||
static Actor* fetch = NULL;
|
||||
static ActorInfo newActor = {0,0, {0, 0, 0}, {0, 0, 0}};
|
||||
static ActorOverlay* dispOverlay;
|
||||
static bool needs_reset = false;
|
||||
static ImU16 one = 1;
|
||||
static int actor;
|
||||
static int category = 0;
|
||||
static RetrievalMethod rm;
|
||||
static std::string filler = "Please select";
|
||||
static std::vector<Actor*> list;
|
||||
static u16 lastSceneId = 0;
|
||||
|
||||
if (gGlobalCtx != nullptr) {
|
||||
needs_reset = lastSceneId != gGlobalCtx->sceneNum;
|
||||
if (needs_reset) {
|
||||
display = empty;
|
||||
fetch = nullptr;
|
||||
dispOverlay = nullptr;
|
||||
actor = category = 0;
|
||||
filler = "Please Select";
|
||||
list.clear();
|
||||
needs_reset = false;
|
||||
}
|
||||
lastSceneId = gGlobalCtx->sceneNum;
|
||||
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
|
||||
for (int i = 0; i < acMapping.size(); i++) {
|
||||
if (ImGui::Selectable(acMapping[i])) {
|
||||
category = i;
|
||||
PopulateActorDropdown(category, list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Actor", filler.c_str())) {
|
||||
if (gGlobalCtx != nullptr && lastSceneId != gGlobalCtx->sceneNum) {
|
||||
PopulateActorDropdown(category, list);
|
||||
lastSceneId = gGlobalCtx->sceneNum;
|
||||
}
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
std::string label = std::to_string(i) + ": " + list[i]->overlayEntry->name;
|
||||
std::string description = GetActorDescription(list[i]->id);
|
||||
if (description != "")
|
||||
label += " (" + description + ")";
|
||||
|
||||
if (ImGui::Selectable(label.c_str())) {
|
||||
rm = LIST;
|
||||
display = *list[i];
|
||||
actor = i;
|
||||
filler = label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Selected Actor")) {
|
||||
dispOverlay = display.overlayEntry;
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Name: %s", dispOverlay != nullptr ? dispOverlay->name : "???");
|
||||
ImGui::Text("Description: %s", dispOverlay != nullptr ? GetActorDescription(display.id).c_str() : "???");
|
||||
ImGui::Text("Category: %s", dispOverlay != nullptr ? acMapping[display.category] : "???");
|
||||
ImGui::Text("ID: %d", display.id);
|
||||
ImGui::Text("Parameters: %d", display.params);
|
||||
});
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Actor Position");
|
||||
ImGui::InputScalar("x pos", ImGuiDataType_Float, &display.world.pos.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("y pos", ImGuiDataType_Float, &display.world.pos.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("z pos", ImGuiDataType_Float, &display.world.pos.z);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("Actor Rotation");
|
||||
ImGui::InputScalar("x rot", ImGuiDataType_S16, &display.world.rot.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("y rot", ImGuiDataType_S16, &display.world.rot.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("z rot", ImGuiDataType_S16, &display.world.rot.z);
|
||||
});
|
||||
|
||||
if (display.category == ACTORCAT_BOSS || display.category == ACTORCAT_ENEMY) {
|
||||
ImGui::InputScalar("Enemy Health", ImGuiDataType_U8, &display.colChkInfo.health);
|
||||
InsertHelpHoverText("Some actors might not use this!");
|
||||
}
|
||||
|
||||
if (ImGui::Button("Refresh")) {
|
||||
PopulateActorDropdown(category, list);
|
||||
switch (rm) {
|
||||
case INTERACT:
|
||||
case HELD:
|
||||
case TARGET:
|
||||
display = *fetch;
|
||||
break;
|
||||
case LIST:
|
||||
display = *list[actor];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Button("Go to Actor")) {
|
||||
Player* player = GET_PLAYER(gGlobalCtx);
|
||||
Math_Vec3f_Copy(&player->actor.world.pos, &display.world.pos);
|
||||
Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Fetch from Target")) {
|
||||
Player* player = GET_PLAYER(gGlobalCtx);
|
||||
fetch = player->targetActor;
|
||||
if (fetch != NULL) {
|
||||
display = *fetch;
|
||||
category = fetch->category;
|
||||
PopulateActorDropdown(category, list);
|
||||
rm = TARGET;
|
||||
}
|
||||
}
|
||||
InsertHelpHoverText("Grabs actor with target arrow above it. You might need C-Up for enemies");
|
||||
if (ImGui::Button("Fetch from Held")) {
|
||||
Player* player = GET_PLAYER(gGlobalCtx);
|
||||
fetch = player->heldActor;
|
||||
if (fetch != NULL) {
|
||||
display = *fetch;
|
||||
category = fetch->category;
|
||||
PopulateActorDropdown(category, list);
|
||||
rm = HELD;
|
||||
}
|
||||
}
|
||||
InsertHelpHoverText("Grabs actor that Link is holding");
|
||||
if (ImGui::Button("Fetch from Interaction")) {
|
||||
Player* player = GET_PLAYER(gGlobalCtx);
|
||||
fetch = player->interactRangeActor;
|
||||
if (fetch != NULL) {
|
||||
display = *fetch;
|
||||
category = fetch->category;
|
||||
PopulateActorDropdown(category, list);
|
||||
rm = INTERACT;
|
||||
}
|
||||
}
|
||||
InsertHelpHoverText("Grabs actor from \"interaction range\"");
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("New...")) {
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
||||
|
||||
ImGui::Text(GetActorDescription(newActor.id).c_str());
|
||||
ImGui::InputScalar("ID", ImGuiDataType_S16, &newActor.id, &one);
|
||||
ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &one);
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("New Actor Position");
|
||||
ImGui::InputScalar("posX", ImGuiDataType_Float, &newActor.pos.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("posY", ImGuiDataType_Float, &newActor.pos.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("posZ", ImGuiDataType_Float, &newActor.pos.z);
|
||||
});
|
||||
|
||||
DrawGroupWithBorder([&]() {
|
||||
ImGui::Text("New Actor Rotation");
|
||||
ImGui::InputScalar("rotX", ImGuiDataType_S16, &newActor.rot.x);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("rotY", ImGuiDataType_S16, &newActor.rot.y);
|
||||
ImGui::SameLine();
|
||||
ImGui::InputScalar("rotZ", ImGuiDataType_S16, &newActor.rot.z);
|
||||
});
|
||||
|
||||
if (ImGui::Button("Fetch from Link")) {
|
||||
Player* player = GET_PLAYER(gGlobalCtx);
|
||||
Vec3f newPos = player->actor.world.pos;
|
||||
Vec3s newRot = player->actor.world.rot;
|
||||
newActor.pos = newPos;
|
||||
newActor.rot = newRot;
|
||||
}
|
||||
|
||||
if (ImGui::Button("Spawn")) {
|
||||
if (newActor.id >= 0 && newActor.id < ACTOR_ID_MAX && gActorOverlayTable[newActor.id].initInfo != NULL) {
|
||||
Actor_Spawn(&gGlobalCtx->actorCtx, gGlobalCtx, newActor.id, newActor.pos.x, newActor.pos.y,
|
||||
newActor.pos.z, newActor.rot.x, newActor.rot.y, newActor.rot.z, newActor.params);
|
||||
} else {
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Button("Spawn as Child")) {
|
||||
Actor* parent = &display;
|
||||
if (parent != NULL) {
|
||||
if (newActor.id >= 0 && newActor.id < ACTOR_ID_MAX &&
|
||||
gActorOverlayTable[newActor.id].initInfo != NULL) {
|
||||
Actor_SpawnAsChild(&gGlobalCtx->actorCtx, parent, gGlobalCtx, newActor.id, newActor.pos.x,
|
||||
newActor.pos.y, newActor.pos.z, newActor.rot.x, newActor.rot.y,
|
||||
newActor.rot.z, newActor.params);
|
||||
} else {
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Button("Reset")) {
|
||||
newActor = { 0, 0, { 0, 0, 0 }, { 0, 0, 0 } };
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("Global Context needed for actor info!");
|
||||
if (needs_reset) {
|
||||
fetch = nullptr;
|
||||
dispOverlay = nullptr;
|
||||
actor = category = 0;
|
||||
filler = "Please Select";
|
||||
list.clear();
|
||||
needs_reset = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void InitActorViewer() {
|
||||
SohImGui::AddWindow("Developer Tools", "Actor Viewer", DrawActorViewer);
|
||||
}
|
3
soh/soh/Enhancements/debugger/actorViewer.h
Normal file
3
soh/soh/Enhancements/debugger/actorViewer.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void InitActorViewer();
|
|
@ -6,6 +6,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <Cvar.h>
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
|
@ -15,40 +16,27 @@ extern "C" {
|
|||
extern GlobalContext* gGlobalCtx;
|
||||
}
|
||||
|
||||
enum class ColRenderSetting {
|
||||
Disabled,
|
||||
Solid,
|
||||
Transparent,
|
||||
NumSettings
|
||||
};
|
||||
enum class ColRenderSetting { Disabled, Solid, Transparent };
|
||||
|
||||
std::string ColRenderSettingNames[] = {
|
||||
std::vector<std::string> ColRenderSettingNames = {
|
||||
"Disabled",
|
||||
"Solid",
|
||||
"Transparent",
|
||||
};
|
||||
|
||||
static ColRenderSetting showSceneColSetting = ColRenderSetting::Disabled;
|
||||
static ColRenderSetting showBgActorSetting = ColRenderSetting::Disabled;
|
||||
static ColRenderSetting showColCheckSetting = ColRenderSetting::Disabled;
|
||||
static ColRenderSetting showWaterboxSetting = ColRenderSetting::Disabled;
|
||||
ImVec4 scene_col;
|
||||
ImVec4 hookshot_col;
|
||||
ImVec4 entrance_col;
|
||||
ImVec4 specialSurface_col;
|
||||
ImVec4 interactable_col;
|
||||
ImVec4 slope_col;
|
||||
ImVec4 void_col;
|
||||
|
||||
static uint32_t sceneColor = 0xFFFFFFFF;
|
||||
static uint32_t hookshotColor = 0x8080FFFF;
|
||||
static uint32_t entranceColor = 0x00FF00FF;
|
||||
static uint32_t specialSurfaceColor = 0xC0FFC0FF;
|
||||
static uint32_t interactableColor = 0xC000C0FF;
|
||||
static uint32_t slopeColor = 0xFFFF80FF;
|
||||
static uint32_t voidColor = 0xFF0000FF;
|
||||
ImVec4 oc_col;
|
||||
ImVec4 ac_col;
|
||||
ImVec4 at_col;
|
||||
|
||||
static uint32_t ocColor = 0xFFFFFFFF;
|
||||
static uint32_t acColor = 0x0000FFFF;
|
||||
static uint32_t atColor = 0xFF0000FF;
|
||||
|
||||
static uint32_t waterboxColor = 0x0000FFFF;
|
||||
|
||||
static bool applyAsDecal = false;
|
||||
static bool isShaded = false;
|
||||
ImVec4 waterbox_col;
|
||||
|
||||
static std::vector<Gfx> opaDl;
|
||||
static std::vector<Gfx> xluDl;
|
||||
|
@ -62,38 +50,10 @@ static std::vector<Vtx> cylinderVtx;
|
|||
static std::vector<Gfx> sphereGfx;
|
||||
static std::vector<Vtx> sphereVtx;
|
||||
|
||||
// Create a dropdown menu to set a ColRenderSetting
|
||||
void DrawColRenderSetting(const std::string& name, ColRenderSetting& setting) {
|
||||
if (ImGui::BeginCombo(name.c_str(), ColRenderSettingNames[static_cast<int>(setting)].c_str())) {
|
||||
for (int32_t settingIndex = 0; settingIndex < static_cast<int>(ColRenderSetting::NumSettings); settingIndex++) {
|
||||
if (ImGui::Selectable(ColRenderSettingNames[settingIndex].c_str())) {
|
||||
setting = static_cast<ColRenderSetting>(settingIndex);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a color picker box
|
||||
void DrawColorPicker(const std::string& name, uint32_t& color) {
|
||||
float colorAsFloat[4];
|
||||
colorAsFloat[0] = ((color >> 24) & 0xFF) / 255.0f;
|
||||
colorAsFloat[1] = ((color >> 16) & 0xFF) / 255.0f;
|
||||
colorAsFloat[2] = ((color >> 8) & 0xFF) / 255.0f;
|
||||
colorAsFloat[3] = (color & 0xFF) / 255.0f;
|
||||
if (ImGui::ColorEdit4(name.c_str(), colorAsFloat, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) {
|
||||
color = static_cast<uint8_t>(colorAsFloat[3] * 255) |
|
||||
static_cast<uint8_t>(colorAsFloat[2] * 255) << 8 |
|
||||
static_cast<uint8_t>(colorAsFloat[1] * 255) << 16 |
|
||||
static_cast<uint8_t>(colorAsFloat[0] * 255) << 24;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(name.c_str());
|
||||
}
|
||||
|
||||
// Draws the ImGui window for the collision viewer
|
||||
void DrawColViewerWindow(bool& open) {
|
||||
if (!open) {
|
||||
CVar_SetS32("gCollisionViewerEnabled", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -102,16 +62,17 @@ void DrawColViewerWindow(bool& open) {
|
|||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
SohImGui::EnhancementCheckbox("Enabled", "gColViewerEnabled");
|
||||
|
||||
DrawColRenderSetting("Scene", showSceneColSetting);
|
||||
DrawColRenderSetting("Bg Actors", showBgActorSetting);
|
||||
DrawColRenderSetting("Col Check", showColCheckSetting);
|
||||
DrawColRenderSetting("Waterbox", showWaterboxSetting);
|
||||
SohImGui::EnhancementCombo("Scene", "gColViewerScene", ColRenderSettingNames);
|
||||
SohImGui::EnhancementCombo("Bg Actors", "gColViewerBgActors", ColRenderSettingNames);
|
||||
SohImGui::EnhancementCombo("Col Check", "gColViewerColCheck", ColRenderSettingNames);
|
||||
SohImGui::EnhancementCombo("Waterbox", "gColViewerWaterbox", ColRenderSettingNames);
|
||||
|
||||
ImGui::Checkbox("Apply as decal", &applyAsDecal);
|
||||
SohImGui::EnhancementCheckbox("Apply as decal", "gColViewerDecal");
|
||||
InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring "
|
||||
"with the scene geometry, but can cause other artifacts.");
|
||||
ImGui::Checkbox("Shaded", &isShaded);
|
||||
SohImGui::EnhancementCheckbox("Shaded", "gColViewerShaded");
|
||||
InsertHelpHoverText("Applies the scene's shading to the collision display.");
|
||||
|
||||
// This has to be duplicated in both code paths due to the nature of ImGui::IsItemHovered()
|
||||
|
@ -119,17 +80,20 @@ void DrawColViewerWindow(bool& open) {
|
|||
if (ImGui::TreeNode("Colors")) {
|
||||
InsertHelpHoverText(colorHelpText);
|
||||
|
||||
DrawColorPicker("Normal", sceneColor);
|
||||
DrawColorPicker("Hookshot", hookshotColor);
|
||||
DrawColorPicker("Entrance", entranceColor);
|
||||
DrawColorPicker("Special Surface (Grass/Sand/Etc)", specialSurfaceColor);
|
||||
DrawColorPicker("Interactable (Vines/Crawlspace/Etc)", interactableColor);
|
||||
DrawColorPicker("Slope", slopeColor);
|
||||
DrawColorPicker("Void", voidColor);
|
||||
DrawColorPicker("OC", ocColor);
|
||||
DrawColorPicker("AC", acColor);
|
||||
DrawColorPicker("AT", atColor);
|
||||
DrawColorPicker("Waterbox", waterboxColor);
|
||||
SohImGui::EnhancementColor("Normal", "gColViewerColorNormal", scene_col, ImVec4(255, 255, 255, 255), false);
|
||||
SohImGui::EnhancementColor("Hookshot", "gColViewerColorHookshot", hookshot_col, ImVec4(128, 128, 255, 255),
|
||||
false);
|
||||
SohImGui::EnhancementColor("Entrance", "gColViewerColorEntrance", entrance_col, ImVec4(0, 255, 0, 255), false);
|
||||
SohImGui::EnhancementColor("Special Surface (Grass/Sand/Etc)", "gColViewerColorSpecialSurface",
|
||||
specialSurface_col, ImVec4(192, 255, 192, 255), false);
|
||||
SohImGui::EnhancementColor("Interactable (Vines/Crawlspace/Etc)", "gColViewerColorInteractable",
|
||||
interactable_col, ImVec4(192, 0, 192, 255), false);
|
||||
SohImGui::EnhancementColor("Slope", "gColViewerColorSlope", slope_col, ImVec4(255, 255, 128, 255), false);
|
||||
SohImGui::EnhancementColor("Void", "gColViewerColorVoid", void_col, ImVec4(255, 0, 0, 255), false);
|
||||
SohImGui::EnhancementColor("OC", "gColViewerColorOC", oc_col, ImVec4(255, 255, 255, 255), false);
|
||||
SohImGui::EnhancementColor("AC", "gColViewerColorAC", ac_col, ImVec4(0, 0, 255, 255), false);
|
||||
SohImGui::EnhancementColor("AT", "gColViewerColorAT", at_col, ImVec4(255, 0, 0, 255), false);
|
||||
SohImGui::EnhancementColor("Waterbox", "gColViewerColorWaterbox", waterbox_col, ImVec4(0, 0, 255, 255), false);
|
||||
|
||||
ImGui::TreePop();
|
||||
} else {
|
||||
|
@ -161,13 +125,12 @@ void CalcTriNorm(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, Vec3f& norm)
|
|||
.n = {.ob = { x, y, z }, .tc = { qs105(s), qs105(t) }, .n = { nx, ny, nz }, .a = ca } \
|
||||
}
|
||||
|
||||
|
||||
void CreateCylinderData() {
|
||||
constexpr int32_t CYL_DIVS = 12;
|
||||
cylinderGfx.reserve(5 + CYL_DIVS * 2);
|
||||
cylinderVtx.reserve(2 + CYL_DIVS * 2);
|
||||
|
||||
cylinderVtx.push_back(gdSPDefVtxN(0, 0, 0, 0, 0, 0, -127, 0, 0xFF)); // Bottom center vertex
|
||||
cylinderVtx.push_back(gdSPDefVtxN(0, 0, 0, 0, 0, 0, -127, 0, 0xFF)); // Bottom center vertex
|
||||
cylinderVtx.push_back(gdSPDefVtxN(0, 128, 0, 0, 0, 0, 127, 0, 0xFF)); // Top center vertex
|
||||
// Create two rings of vertices
|
||||
for (int i = 0; i < CYL_DIVS; ++i) {
|
||||
|
@ -210,9 +173,10 @@ void CreateCylinderData() {
|
|||
cylinderGfx.push_back(gsSPEndDisplayList());
|
||||
}
|
||||
|
||||
// This subdivides a face into four tris by placing new verticies at the midpoints of the sides (Like a triforce!), then blowing up the
|
||||
// verticies so they are on the unit sphere
|
||||
void CreateSphereFace(std::vector<std::tuple<size_t, size_t, size_t>>& faces, int32_t v0Index, int32_t v1Index, int32_t v2Index) {
|
||||
// This subdivides a face into four tris by placing new verticies at the midpoints of the sides (Like a triforce!), then
|
||||
// blowing up the verticies so they are on the unit sphere
|
||||
void CreateSphereFace(std::vector<std::tuple<size_t, size_t, size_t>>& faces, int32_t v0Index, int32_t v1Index,
|
||||
int32_t v2Index) {
|
||||
size_t nextIndex = sphereVtx.size();
|
||||
|
||||
size_t v01Index = nextIndex;
|
||||
|
@ -248,9 +212,9 @@ void CreateSphereFace(std::vector<std::tuple<size_t, size_t, size_t>>& faces, in
|
|||
}
|
||||
}
|
||||
|
||||
// Creates a sphere following the idea in here: http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html
|
||||
// Spcifically, create a icosahedron by realizing that the points can be placed on 3 rectangles that are on each unit plane.
|
||||
// Then, subdividing each face.
|
||||
// Creates a sphere following the idea in here:
|
||||
// http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html Spcifically, create a icosahedron by
|
||||
// realizing that the points can be placed on 3 rectangles that are on each unit plane. Then, subdividing each face.
|
||||
void CreateSphereData() {
|
||||
std::vector<Vec3f> base;
|
||||
|
||||
|
@ -351,7 +315,7 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
|
|||
alpha = 0xFF;
|
||||
}
|
||||
|
||||
if (applyAsDecal) {
|
||||
if (CVar_GetS32("gColViewerDecal", 0) != 0) {
|
||||
rm |= ZMODE_DEC;
|
||||
} else if (setting == ColRenderSetting::Transparent) {
|
||||
rm |= ZMODE_XLU;
|
||||
|
@ -363,7 +327,7 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
|
|||
gfx.push_back(gsDPSetCycleType(G_CYC_1CYCLE));
|
||||
gfx.push_back(gsDPSetRenderMode(rm | blc1, rm | blc2));
|
||||
|
||||
if (isShaded) {
|
||||
if (CVar_GetS32("gColViewerShaded", 0) != 0) {
|
||||
gfx.push_back(gsDPSetCombineMode(G_CC_MODULATERGB_PRIM_ENVA, G_CC_MODULATERGB_PRIM_ENVA));
|
||||
gfx.push_back(gsSPLoadGeometryMode(G_CULL_BACK | G_ZBUFFER | G_LIGHTING));
|
||||
} else {
|
||||
|
@ -376,10 +340,16 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
|
|||
|
||||
// Draws a dynapoly structure (scenes or Bg Actors)
|
||||
void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
|
||||
uint32_t color = sceneColor;
|
||||
uint32_t lastColor = color;
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, (color >> 24) & 0xFF, (color >> 16) & 0xFF, (color >> 8) & 0xFF,
|
||||
(color >> 0) & 0xFF));
|
||||
uint32_t colorR = CVar_GetS32("gColViewerColorNormalR", 255);
|
||||
uint32_t colorG = CVar_GetS32("gColViewerColorNormalG", 255);
|
||||
uint32_t colorB = CVar_GetS32("gColViewerColorNormalB", 255);
|
||||
uint32_t colorA = 255;
|
||||
|
||||
uint32_t lastColorR = colorR;
|
||||
uint32_t lastColorG = colorG;
|
||||
uint32_t lastColorB = colorB;
|
||||
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, colorR, colorG, colorB, colorA));
|
||||
|
||||
// This keeps track of if we have processed a poly, but not drawn it yet so we can batch them.
|
||||
// This saves several hundred commands in larger scenes
|
||||
|
@ -389,34 +359,49 @@ void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
|
|||
CollisionPoly* poly = &col->polyList[i];
|
||||
|
||||
if (SurfaceType_IsHookshotSurface(&gGlobalCtx->colCtx, poly, bgId)) {
|
||||
color = hookshotColor;
|
||||
colorR = CVar_GetS32("gColViewerColorHookshotR", 128);
|
||||
colorG = CVar_GetS32("gColViewerColorHookshotG", 128);
|
||||
colorB = CVar_GetS32("gColViewerColorHookshotB", 255);
|
||||
} else if (func_80041D94(&gGlobalCtx->colCtx, poly, bgId) > 0x01) {
|
||||
color = interactableColor;
|
||||
colorR = CVar_GetS32("gColViewerColorInteractableR", 192);
|
||||
colorG = CVar_GetS32("gColViewerColorInteractableG", 0);
|
||||
colorB = CVar_GetS32("gColViewerColorInteractableB", 192);
|
||||
} else if (func_80041E80(&gGlobalCtx->colCtx, poly, bgId) == 0x0C) {
|
||||
color = voidColor;
|
||||
colorR = CVar_GetS32("gColViewerColorVoidR", 255);
|
||||
colorG = CVar_GetS32("gColViewerColorVoidG", 0);
|
||||
colorB = CVar_GetS32("gColViewerColorVoidB", 0);
|
||||
} else if (SurfaceType_GetSceneExitIndex(&gGlobalCtx->colCtx, poly, bgId) ||
|
||||
func_80041E80(&gGlobalCtx->colCtx, poly, bgId) == 0x05) {
|
||||
color = entranceColor;
|
||||
colorR = CVar_GetS32("gColViewerColorEntranceR", 0);
|
||||
colorG = CVar_GetS32("gColViewerColorEntranceG", 255);
|
||||
colorB = CVar_GetS32("gColViewerColorEntranceB", 0);
|
||||
} else if (func_80041D4C(&gGlobalCtx->colCtx, poly, bgId) != 0 ||
|
||||
SurfaceType_IsWallDamage(&gGlobalCtx->colCtx, poly, bgId)) {
|
||||
color = specialSurfaceColor;
|
||||
colorR = CVar_GetS32("gColViewerColorSpecialSurfaceR", 192);
|
||||
colorG = CVar_GetS32("gColViewerColorSpecialSurfaceG", 255);
|
||||
colorB = CVar_GetS32("gColViewerColorSpecialSurfaceB", 192);
|
||||
} else if (SurfaceType_GetSlope(&gGlobalCtx->colCtx, poly, bgId) == 0x01) {
|
||||
color = slopeColor;
|
||||
colorR = CVar_GetS32("gColViewerColorSlopeR", 255);
|
||||
colorG = CVar_GetS32("gColViewerColorSlopeG", 255);
|
||||
colorB = CVar_GetS32("gColViewerColorSlopeB", 128);
|
||||
} else {
|
||||
color = sceneColor;
|
||||
colorR = CVar_GetS32("gColViewerColorNormalR", 255);
|
||||
colorG = CVar_GetS32("gColViewerColorNormalG", 255);
|
||||
colorB = CVar_GetS32("gColViewerColorNormalB", 255);
|
||||
}
|
||||
|
||||
if (lastColor != color) {
|
||||
if (colorR != lastColorR || colorG != lastColorG || colorB != lastColorB) {
|
||||
// Color changed, flush previous poly
|
||||
if (previousPoly) {
|
||||
dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0));
|
||||
dl.push_back(gsSP1Triangle(0, 1, 2, 0));
|
||||
previousPoly = false;
|
||||
}
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, (color >> 24) & 0xFF, (color >> 16) & 0xFF, (color >> 8) & 0xFF,
|
||||
(color >> 0) & 0xFF));
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, colorR, colorG, colorB, colorA));
|
||||
}
|
||||
lastColor = color;
|
||||
lastColorR = colorR;
|
||||
lastColorG = colorG;
|
||||
lastColorB = colorB;
|
||||
|
||||
Vec3s* va = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)];
|
||||
Vec3s* vb = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)];
|
||||
|
@ -450,7 +435,9 @@ void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
|
|||
|
||||
// Draws the scene
|
||||
void DrawSceneCollision() {
|
||||
if (showSceneColSetting == ColRenderSetting::Disabled) {
|
||||
ColRenderSetting showSceneColSetting = (ColRenderSetting)CVar_GetS32("gColViewerScene", 0);
|
||||
|
||||
if (showSceneColSetting == ColRenderSetting::Disabled || CVar_GetS32("gColViewerEnabled", 0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -463,7 +450,8 @@ void DrawSceneCollision() {
|
|||
|
||||
// Draws all Bg Actors
|
||||
void DrawBgActorCollision() {
|
||||
if (showBgActorSetting == ColRenderSetting::Disabled) {
|
||||
ColRenderSetting showBgActorSetting = (ColRenderSetting)CVar_GetS32("gColViewerBgActors", 0);
|
||||
if (showBgActorSetting == ColRenderSetting::Disabled || CVar_GetS32("gColViewerEnabled", 0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -489,7 +477,6 @@ void DrawBgActorCollision() {
|
|||
dl.push_back(gsSPPopMatrix(G_MTX_MODELVIEW));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Draws a quad
|
||||
|
@ -588,7 +575,8 @@ void DrawColCheckList(std::vector<Gfx>& dl, Collider** objects, int32_t count) {
|
|||
|
||||
// Draws all Col Check objects
|
||||
void DrawColCheckCollision() {
|
||||
if (showColCheckSetting == ColRenderSetting::Disabled) {
|
||||
ColRenderSetting showColCheckSetting = (ColRenderSetting)CVar_GetS32("gColViewerColCheck", 0);
|
||||
if (showColCheckSetting == ColRenderSetting::Disabled || CVar_GetS32("gColViewerEnabled", 0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -598,16 +586,15 @@ void DrawColCheckCollision() {
|
|||
|
||||
CollisionCheckContext& col = gGlobalCtx->colChkCtx;
|
||||
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, (ocColor >> 24) & 0xFF, (ocColor >> 16) & 0xFF, (ocColor >> 8) & 0xFF,
|
||||
(ocColor >> 0) & 0xFF));
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, CVar_GetS32("gColViewerColorOCR", 255), CVar_GetS32("gColViewerColorOCG", 255),
|
||||
CVar_GetS32("gColViewerColorOCB", 255), 255));
|
||||
DrawColCheckList(dl, col.colOC, col.colOCCount);
|
||||
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, (acColor >> 24) & 0xFF, (acColor >> 16) & 0xFF, (acColor >> 8) & 0xFF,
|
||||
(acColor >> 0) & 0xFF));
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, CVar_GetS32("gColViewerColorACR", 0), CVar_GetS32("gColViewerColorACG", 0),
|
||||
CVar_GetS32("gColViewerColorACB", 255), 255));
|
||||
DrawColCheckList(dl, col.colAC, col.colACCount);
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, CVar_GetS32("gColViewerColorATR", 255), CVar_GetS32("gColViewerColorATG", 0),
|
||||
CVar_GetS32("gColViewerColorATB", 0), 255));
|
||||
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, (atColor >> 24) & 0xFF, (atColor >> 16) & 0xFF, (atColor >> 8) & 0xFF,
|
||||
(atColor >> 0) & 0xFF));
|
||||
DrawColCheckList(dl, col.colAT, col.colATCount);
|
||||
}
|
||||
|
||||
|
@ -641,15 +628,18 @@ extern "C" f32 zdWaterBoxMinY;
|
|||
|
||||
// Draws all waterboxes
|
||||
void DrawWaterboxList() {
|
||||
if (showWaterboxSetting == ColRenderSetting::Disabled) {
|
||||
ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVar_GetS32("gColViewerWaterbox", 0);
|
||||
if (showWaterboxSetting == ColRenderSetting::Disabled || CVar_GetS32("gColViewerEnabled", 0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Gfx>& dl = (showWaterboxSetting == ColRenderSetting::Transparent) ? xluDl : opaDl;
|
||||
InitGfx(dl, showWaterboxSetting);
|
||||
dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH));
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, (waterboxColor >> 24) & 0xFF, (waterboxColor >> 16) & 0xFF,
|
||||
(waterboxColor >> 8) & 0xFF, (waterboxColor >> 0) & 0xFF));
|
||||
|
||||
dl.push_back(gsDPSetPrimColor(0, 0, CVar_GetS32("gColViewerColorWaterboxR", 0),
|
||||
CVar_GetS32("gColViewerColorWaterboxG", 0),
|
||||
CVar_GetS32("gColViewerColorWaterboxB", 255), 255));
|
||||
|
||||
CollisionHeader* col = gGlobalCtx->colCtx.colHeader;
|
||||
for (int32_t waterboxIndex = 0; waterboxIndex < col->numWaterBoxes; waterboxIndex++) {
|
||||
|
@ -664,8 +654,7 @@ void DrawWaterboxList() {
|
|||
}
|
||||
|
||||
// Resets a vector for the next frame and returns the capacity
|
||||
template<typename T>
|
||||
size_t ResetVector(T& vec) {
|
||||
template <typename T> size_t ResetVector(T& vec) {
|
||||
size_t oldSize = vec.size();
|
||||
vec.clear();
|
||||
// Reserve slightly more space than last frame to account for variance (such as different amounts of bg actors)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <bit>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <Cvar.h>
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
|
@ -1316,6 +1317,9 @@ void DrawPlayerTab() {
|
|||
case ITEM_SWORD_BGS:
|
||||
curSword = "Biggoron's Sword";
|
||||
break;
|
||||
case ITEM_FISHING_POLE:
|
||||
curSword = "Fishing Pole";
|
||||
break;
|
||||
case ITEM_NONE:
|
||||
curSword = "None";
|
||||
break;
|
||||
|
@ -1463,6 +1467,11 @@ void DrawPlayerTab() {
|
|||
|
||||
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_BGS);
|
||||
}
|
||||
if (ImGui::Selectable("Fishing Pole")) {
|
||||
player->currentSwordItem = ITEM_FISHING_POLE;
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_FISHING_POLE;
|
||||
Inventory_ChangeEquipment(EQUIP_SWORD, PLAYER_SWORD_MASTER);
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
|
||||
}
|
||||
|
@ -1536,6 +1545,7 @@ void DrawPlayerTab() {
|
|||
|
||||
void DrawSaveEditor(bool& open) {
|
||||
if (!open) {
|
||||
CVar_SetS32("gSaveEditorEnabled", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#include "debugger.h"
|
||||
#include "debugSaveEditor.h"
|
||||
#include "colViewer.h"
|
||||
#include "actorViewer.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void Debug_Init(void) {
|
||||
InitSaveEditor();
|
||||
InitColViewer();
|
||||
InitActorViewer();
|
||||
}
|
||||
|
||||
void Debug_Draw(void) {
|
||||
|
|
|
@ -264,6 +264,9 @@ typedef struct SaveStateInfo {
|
|||
uint8_t sKankyoIsSpawned_copy;
|
||||
int16_t sTrailingFairies_copy;
|
||||
|
||||
// z_en_heishi1
|
||||
uint32_t sHeishi1PlayerIsCaughtCopy;
|
||||
|
||||
|
||||
//Misc static data
|
||||
// z_map_exp
|
||||
|
@ -616,6 +619,8 @@ void SaveState::SaveOverlayStaticData(void) {
|
|||
info->D_80B5A4BC_copy = D_80B5A4BC;
|
||||
info->sKankyoIsSpawned_copy = sKankyoIsSpawned;
|
||||
info->sTrailingFairies_copy = sTrailingFairies;
|
||||
|
||||
info->sHeishi1PlayerIsCaughtCopy = sHeishi1PlayerIsCaught;
|
||||
|
||||
}
|
||||
|
||||
|
@ -686,6 +691,8 @@ void SaveState::LoadOverlayStaticData(void) {
|
|||
D_80B5A4BC = info->D_80B5A4BC_copy;
|
||||
sKankyoIsSpawned = info->sKankyoIsSpawned_copy;
|
||||
sTrailingFairies = info->sTrailingFairies_copy;
|
||||
|
||||
sHeishi1PlayerIsCaught = info->sHeishi1PlayerIsCaughtCopy;
|
||||
}
|
||||
|
||||
void SaveState::SaveMiscCodeData(void) {
|
||||
|
|
|
@ -200,6 +200,9 @@ extern "C" s16 sPlayerInitialPosX;
|
|||
extern "C" s16 sPlayerInitialPosZ;
|
||||
extern "C" s16 sPlayerInitialDirection;
|
||||
|
||||
// z_en_heishi1
|
||||
extern "C" s32 sHeishi1PlayerIsCaught;
|
||||
|
||||
// code_800EC960
|
||||
// Related to ocarina
|
||||
extern "C" u8 sOcarinaInpEnabled;
|
||||
|
|
21
soh/soh/Lib/nlohmann/LICENSE.MIT
Normal file
21
soh/soh/Lib/nlohmann/LICENSE.MIT
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2013-2022 Niels Lohmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
22091
soh/soh/Lib/nlohmann/json.hpp
Normal file
22091
soh/soh/Lib/nlohmann/json.hpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,7 @@
|
|||
#include "OTRGlobals.h"
|
||||
#include "OTRAudio.h"
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include "GlobalCtx2.h"
|
||||
|
@ -36,14 +37,17 @@
|
|||
#include <Utils/StringHelper.h>
|
||||
|
||||
#include <SDL2/SDL_scancode.h>
|
||||
#include <Audio.h>
|
||||
|
||||
OTRGlobals* OTRGlobals::Instance;
|
||||
SaveManager* SaveManager::Instance;
|
||||
|
||||
OTRGlobals::OTRGlobals() {
|
||||
|
||||
context = Ship::GlobalCtx2::CreateInstance("Ship of Harkinian");
|
||||
gSaveStateMgr = std::make_shared<SaveStateMgr>();
|
||||
context->GetWindow()->Init();
|
||||
CheckSaveFile(SRAM_SIZE);
|
||||
}
|
||||
|
||||
OTRGlobals::~OTRGlobals() {
|
||||
|
@ -57,10 +61,19 @@ extern "C" void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
|
|||
extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
|
||||
extern "C" int AudioPlayer_Buffered(void);
|
||||
extern "C" int AudioPlayer_GetDesiredBuffered(void);
|
||||
extern "C" void ResourceMgr_CacheDirectory(const char* resName);
|
||||
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path);
|
||||
|
||||
// C->C++ Bridge
|
||||
extern "C" void OTRAudio_Init()
|
||||
{
|
||||
// Precache all our samples, sequences, etc...
|
||||
ResourceMgr_CacheDirectory("audio");
|
||||
}
|
||||
|
||||
extern "C" void InitOTR() {
|
||||
OTRGlobals::Instance = new OTRGlobals();
|
||||
SaveManager::Instance = new SaveManager();
|
||||
auto t = OTRGlobals::Instance->context->GetResourceManager()->LoadFile("version");
|
||||
|
||||
if (!t->bHasLoadError)
|
||||
|
@ -72,6 +85,7 @@ extern "C" void InitOTR() {
|
|||
|
||||
clearMtx = (uintptr_t)&gMtxClear;
|
||||
OTRMessage_Init();
|
||||
OTRAudio_Init();
|
||||
DebugConsole_Init();
|
||||
Debug_Init();
|
||||
}
|
||||
|
@ -189,11 +203,16 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
|
|||
//AudioMgr_ThreadEntry(&gAudioMgr);
|
||||
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
|
||||
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
|
||||
#define SAMPLES_HIGH 560
|
||||
#define SAMPLES_LOW 528
|
||||
//#define SAMPLES_HIGH 560
|
||||
//#define SAMPLES_LOW 528
|
||||
// PAL values
|
||||
//#define SAMPLES_HIGH 656
|
||||
//#define SAMPLES_LOW 624
|
||||
|
||||
// 44KHZ values
|
||||
#define SAMPLES_HIGH 752
|
||||
#define SAMPLES_LOW 720
|
||||
|
||||
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
|
||||
#define NUM_AUDIO_CHANNELS 2
|
||||
int samples_left = AudioPlayer_Buffered();
|
||||
|
@ -312,6 +331,22 @@ extern "C" void ResourceMgr_InvalidateCache() {
|
|||
OTRGlobals::Instance->context->GetResourceManager()->InvalidateResourceCache();
|
||||
}
|
||||
|
||||
// OTRTODO: There is probably a more elegant way to go about this...
|
||||
extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) {
|
||||
auto lst = OTRGlobals::Instance->context->GetResourceManager()->ListFiles(searchMask);
|
||||
char** result = (char**)malloc(lst->size() * sizeof(char*));
|
||||
|
||||
for (int i = 0; i < lst->size(); i++) {
|
||||
char* str = (char*)malloc(lst.get()[0][i].size() + 1);
|
||||
memcpy(str, lst.get()[0][i].data(), lst.get()[0][i].size());
|
||||
str[lst.get()[0][i].size()] = '\0';
|
||||
result[i] = str;
|
||||
}
|
||||
|
||||
*resultSize = lst->size();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" void ResourceMgr_LoadFile(const char* resName) {
|
||||
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(resName);
|
||||
|
@ -530,12 +565,249 @@ extern "C" CollisionHeader* ResourceMgr_LoadColByName(const char* path)
|
|||
return (CollisionHeader*)colHeader;
|
||||
}
|
||||
|
||||
extern "C" Vtx * ResourceMgr_LoadVtxByName(const char* path)
|
||||
extern "C" Vtx* ResourceMgr_LoadVtxByName(const char* path)
|
||||
{
|
||||
auto res = std::static_pointer_cast<Ship::Array>(OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
|
||||
return (Vtx*)res->vertices.data();
|
||||
}
|
||||
|
||||
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path)
|
||||
{
|
||||
auto file = std::static_pointer_cast<Ship::AudioSequence>(OTRGlobals::Instance->context->GetResourceManager()
|
||||
->LoadResource(path));
|
||||
|
||||
SequenceData seqData;
|
||||
seqData.seqNumber = file->seqNumber;
|
||||
seqData.medium = file->medium;
|
||||
seqData.cachePolicy = file->cachePolicy;
|
||||
seqData.numFonts = file->fonts.size();
|
||||
|
||||
for (int i = 0; i < seqData.numFonts; i++)
|
||||
seqData.fonts[i] = file->fonts[i];
|
||||
|
||||
seqData.seqData = file->seqData.data();
|
||||
seqData.seqDataSize = file->seqData.size();
|
||||
|
||||
return seqData;
|
||||
}
|
||||
|
||||
std::map<std::string, SoundFontSample*> cachedCustomSFs;
|
||||
|
||||
extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(const char* path)
|
||||
{
|
||||
if (std::string(path) == "")
|
||||
return nullptr;
|
||||
|
||||
if (cachedCustomSFs.find(path) != cachedCustomSFs.end())
|
||||
return cachedCustomSFs[path];
|
||||
|
||||
// Check if our file is actually a wav...
|
||||
auto sampleRaw = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(path);
|
||||
uint32_t* strem = (uint32_t*)sampleRaw->buffer.get();
|
||||
uint8_t* strem2 = (uint8_t*)strem;
|
||||
|
||||
if (strem2[0] == 'R' && strem2[1] == 'I' && strem2[2] == 'F' && strem2[3] == 'F')
|
||||
{
|
||||
SoundFontSample* sampleC = (SoundFontSample*)malloc(sizeof(SoundFontSample));
|
||||
|
||||
*strem++; // RIFF
|
||||
*strem++; // size
|
||||
*strem++; // WAVE
|
||||
|
||||
*strem++; // fmt
|
||||
int fmtChunkSize = *strem++;
|
||||
*strem++; // wFormatTag + wChannels
|
||||
int32_t sampleRate = *strem++; // dwSamplesPerSec
|
||||
// OTRTODO: Make sure wav format is what the audio driver wants!
|
||||
|
||||
strem = (uint32_t*)&strem2[0x0C + fmtChunkSize + 8 + 4];
|
||||
sampleC->size = *strem++;
|
||||
sampleC->sampleAddr = (uint8_t*)strem;
|
||||
sampleC->codec = CODEC_S16;
|
||||
|
||||
// OTRTODO: Grab loop data from wav
|
||||
sampleC->loop = (AdpcmLoop*)malloc(sizeof(AdpcmLoop));
|
||||
sampleC->loop->start = 0;
|
||||
sampleC->loop->end = sampleC->size / 2; // OTRTODO: This calculation is probably incorrect... Sometimes it goes past the sample, sometimes it stops too early...
|
||||
sampleC->loop->count = 0;
|
||||
sampleC->sampleRateMagicValue = 'RIFF';
|
||||
sampleC->sampleRate = sampleRate;
|
||||
|
||||
cachedCustomSFs[path] = sampleC;
|
||||
return sampleC;
|
||||
}
|
||||
|
||||
auto sample = std::static_pointer_cast<Ship::AudioSample>(
|
||||
OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
|
||||
|
||||
if (sample == nullptr)
|
||||
return NULL;
|
||||
|
||||
if (sample->cachedGameAsset != nullptr)
|
||||
{
|
||||
SoundFontSample* sampleC = (SoundFontSample*)sample->cachedGameAsset;
|
||||
return (SoundFontSample*)sample->cachedGameAsset;
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundFontSample* sampleC = (SoundFontSample*)malloc(sizeof(SoundFontSample));
|
||||
|
||||
sampleC->sampleAddr = sample->data.data();
|
||||
|
||||
sampleC->size = sample->data.size();
|
||||
sampleC->codec = sample->codec;
|
||||
sampleC->medium = sample->medium;
|
||||
sampleC->unk_bit26 = sample->unk_bit26;
|
||||
sampleC->unk_bit25 = sample->unk_bit25;
|
||||
|
||||
sampleC->book = (AdpcmBook*)malloc(sizeof(AdpcmBook) + (sample->book.books.size() * sizeof(int16_t)));
|
||||
sampleC->book->npredictors = sample->book.npredictors;
|
||||
sampleC->book->order = sample->book.order;
|
||||
|
||||
for (int i = 0; i < sample->book.books.size(); i++)
|
||||
sampleC->book->book[i] = sample->book.books[i];
|
||||
|
||||
sampleC->loop = (AdpcmLoop*)malloc(sizeof(AdpcmLoop));
|
||||
sampleC->loop->start = sample->loop.start;
|
||||
sampleC->loop->end = sample->loop.end;
|
||||
sampleC->loop->count = sample->loop.count;
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
sampleC->loop->state[i] = 0;
|
||||
|
||||
for (int i = 0; i < sample->loop.states.size(); i++)
|
||||
sampleC->loop->state[i] = sample->loop.states[i];
|
||||
|
||||
sample->cachedGameAsset = sampleC;
|
||||
return sampleC;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) {
|
||||
auto soundFont =
|
||||
std::static_pointer_cast<Ship::AudioSoundFont>(OTRGlobals::Instance->context->GetResourceManager()->LoadResource(path));
|
||||
|
||||
if (soundFont == nullptr)
|
||||
return NULL;
|
||||
|
||||
if (soundFont->cachedGameAsset != nullptr)
|
||||
{
|
||||
return (SoundFont*)soundFont->cachedGameAsset;
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundFont* soundFontC = (SoundFont*)malloc(sizeof(SoundFont));
|
||||
|
||||
soundFontC->fntIndex = soundFont->id;
|
||||
soundFontC->numDrums = soundFont->drums.size();
|
||||
soundFontC->numInstruments = soundFont->instruments.size();
|
||||
soundFontC->numSfx = soundFont->soundEffects.size();
|
||||
soundFontC->sampleBankId1 = soundFont->data1 >> 8;
|
||||
soundFontC->sampleBankId2 = soundFont->data1 & 0xFF;
|
||||
|
||||
soundFontC->drums = (Drum**)malloc(sizeof(Drum*) * soundFont->drums.size());
|
||||
|
||||
for (int i = 0; i < soundFont->drums.size(); i++)
|
||||
{
|
||||
Drum* drum = (Drum*)malloc(sizeof(Drum));
|
||||
|
||||
drum->releaseRate = soundFont->drums[i].releaseRate;
|
||||
drum->pan = soundFont->drums[i].pan;
|
||||
drum->loaded = 0;
|
||||
|
||||
if (soundFont->drums[i].env.size() == 0)
|
||||
drum->envelope = NULL;
|
||||
else
|
||||
{
|
||||
drum->envelope = (AdsrEnvelope*)malloc(sizeof(AdsrEnvelope) * soundFont->drums[i].env.size());
|
||||
|
||||
for (int k = 0; k < soundFont->drums[i].env.size(); k++)
|
||||
{
|
||||
drum->envelope[k].delay = BOMSWAP16(soundFont->drums[i].env[k]->delay);
|
||||
drum->envelope[k].arg = BOMSWAP16(soundFont->drums[i].env[k]->arg);
|
||||
}
|
||||
}
|
||||
|
||||
drum->sound.sample = ResourceMgr_LoadAudioSample(soundFont->drums[i].sampleFileName.c_str());
|
||||
drum->sound.tuning = soundFont->drums[i].tuning;
|
||||
|
||||
soundFontC->drums[i] = drum;
|
||||
}
|
||||
|
||||
soundFontC->instruments = (Instrument**)malloc(sizeof(Instrument*) * soundFont->instruments.size());
|
||||
|
||||
for (int i = 0; i < soundFont->instruments.size(); i++) {
|
||||
|
||||
if (soundFont->instruments[i].isValidEntry)
|
||||
{
|
||||
Instrument* inst = (Instrument*)malloc(sizeof(Instrument));
|
||||
|
||||
inst->loaded = 0;
|
||||
inst->releaseRate = soundFont->instruments[i].releaseRate;
|
||||
inst->normalRangeLo = soundFont->instruments[i].normalRangeLo;
|
||||
inst->normalRangeHi = soundFont->instruments[i].normalRangeHi;
|
||||
|
||||
if (soundFont->instruments[i].env.size() == 0)
|
||||
inst->envelope = NULL;
|
||||
else
|
||||
{
|
||||
inst->envelope = (AdsrEnvelope*)malloc(sizeof(AdsrEnvelope) * soundFont->instruments[i].env.size());
|
||||
|
||||
for (int k = 0; k < soundFont->instruments[i].env.size(); k++)
|
||||
{
|
||||
inst->envelope[k].delay = BOMSWAP16(soundFont->instruments[i].env[k]->delay);
|
||||
inst->envelope[k].arg = BOMSWAP16(soundFont->instruments[i].env[k]->arg);
|
||||
}
|
||||
}
|
||||
if (soundFont->instruments[i].lowNotesSound != nullptr)
|
||||
{
|
||||
inst->lowNotesSound.sample =
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].lowNotesSound->sampleFileName.c_str());
|
||||
inst->lowNotesSound.tuning = soundFont->instruments[i].lowNotesSound->tuning;
|
||||
} else {
|
||||
inst->lowNotesSound.sample = NULL;
|
||||
inst->lowNotesSound.tuning = 0;
|
||||
}
|
||||
|
||||
if (soundFont->instruments[i].normalNotesSound != nullptr) {
|
||||
inst->normalNotesSound.sample =
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].normalNotesSound->sampleFileName.c_str());
|
||||
inst->normalNotesSound.tuning = soundFont->instruments[i].normalNotesSound->tuning;
|
||||
|
||||
} else {
|
||||
inst->normalNotesSound.sample = NULL;
|
||||
inst->normalNotesSound.tuning = 0;
|
||||
}
|
||||
|
||||
if (soundFont->instruments[i].highNotesSound != nullptr) {
|
||||
inst->highNotesSound.sample =
|
||||
ResourceMgr_LoadAudioSample(soundFont->instruments[i].highNotesSound->sampleFileName.c_str());
|
||||
inst->highNotesSound.tuning = soundFont->instruments[i].highNotesSound->tuning;
|
||||
} else {
|
||||
inst->highNotesSound.sample = NULL;
|
||||
inst->highNotesSound.tuning = 0;
|
||||
}
|
||||
|
||||
soundFontC->instruments[i] = inst;
|
||||
} else
|
||||
{
|
||||
soundFontC->instruments[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
soundFontC->soundEffects = (SoundFontSound*)malloc(sizeof(SoundFontSound) * soundFont->soundEffects.size());
|
||||
|
||||
for (int i = 0; i < soundFont->soundEffects.size(); i++)
|
||||
{
|
||||
soundFontC->soundEffects[i].sample = ResourceMgr_LoadAudioSample(soundFont->soundEffects[i]->sampleFileName.c_str());
|
||||
soundFontC->soundEffects[i].tuning = soundFont->soundEffects[i]->tuning;
|
||||
}
|
||||
|
||||
soundFont->cachedGameAsset = soundFontC;
|
||||
return soundFontC;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int ResourceMgr_OTRSigCheck(char* imgData)
|
||||
{
|
||||
uintptr_t i = (uintptr_t)(imgData);
|
||||
|
@ -570,6 +842,7 @@ extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) {
|
|||
for (int i = 0; i < res->rotationValues.size(); i++)
|
||||
animNormal->frameData[i] = res->rotationValues[i];
|
||||
|
||||
|
||||
animNormal->jointIndices = (JointIndex*)malloc(res->rotationIndices.size() * sizeof(Vec3s));
|
||||
|
||||
for (int i = 0; i < res->rotationIndices.size(); i++) {
|
||||
|
@ -814,6 +1087,71 @@ extern "C" s32* ResourceMgr_LoadCSByName(const char* path)
|
|||
return (s32*)res->commands.data();
|
||||
}
|
||||
|
||||
std::filesystem::path GetSaveFile(Ship::ConfigFile& Conf) {
|
||||
std::string fileName = Conf.get("SAVE").get("Save Filename");
|
||||
|
||||
if (fileName.empty()) {
|
||||
Conf["SAVE"]["Save Filename"] = "oot_save.sav";
|
||||
Conf.Save();
|
||||
}
|
||||
std::filesystem::path saveFile = std::filesystem::absolute(fileName);
|
||||
|
||||
if (!std::filesystem::exists(saveFile.parent_path())) {
|
||||
std::filesystem::create_directories(saveFile.parent_path());
|
||||
}
|
||||
|
||||
return saveFile;
|
||||
}
|
||||
|
||||
std::filesystem::path GetSaveFile() {
|
||||
std::shared_ptr<Ship::ConfigFile> pConf = OTRGlobals::Instance->context->GetConfig();
|
||||
Ship::ConfigFile& Conf = *pConf.get();
|
||||
|
||||
return GetSaveFile(Conf);
|
||||
}
|
||||
|
||||
void OTRGlobals::CheckSaveFile(size_t sramSize) {
|
||||
std::shared_ptr<Ship::ConfigFile> pConf = context->GetConfig();
|
||||
Ship::ConfigFile& Conf = *pConf.get();
|
||||
|
||||
std::filesystem::path savePath = GetSaveFile(Conf);
|
||||
std::fstream saveFile(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
|
||||
if (saveFile.fail()) {
|
||||
saveFile.open(savePath, std::fstream::in | std::fstream::out | std::fstream::binary | std::fstream::app);
|
||||
for (int i = 0; i < sramSize; ++i) {
|
||||
saveFile.write("\0", 1);
|
||||
}
|
||||
}
|
||||
saveFile.close();
|
||||
}
|
||||
|
||||
extern "C" void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size) {
|
||||
OTRGlobals::Instance->context->ReadSaveFile(GetSaveFile(), addr, dramAddr, size);
|
||||
}
|
||||
|
||||
extern "C" void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size) {
|
||||
OTRGlobals::Instance->context->WriteSaveFile(GetSaveFile(), addr, dramAddr, size);
|
||||
}
|
||||
|
||||
/* Remember to free after use of value */
|
||||
extern "C" char* Config_getValue(char* category, char* key) {
|
||||
std::shared_ptr<Ship::ConfigFile> pConf = OTRGlobals::Instance->context->GetConfig();
|
||||
Ship::ConfigFile& Conf = *pConf.get();
|
||||
|
||||
std::string data = Conf.get(std::string(category)).get(std::string(key));
|
||||
char* retval = (char*)malloc(data.length()+1);
|
||||
strcpy(retval, data.c_str());
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern "C" bool Config_setValue(char* category, char* key, char* value) {
|
||||
std::shared_ptr<Ship::ConfigFile> pConf = OTRGlobals::Instance->context->GetConfig();
|
||||
Ship::ConfigFile& Conf = *pConf.get();
|
||||
Conf[std::string(category)][std::string(key)] = std::string(value);
|
||||
return Conf.Save();
|
||||
}
|
||||
|
||||
std::wstring StringToU16(const std::string& s) {
|
||||
std::vector<unsigned long> result;
|
||||
size_t i = 0;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "GlobalCtx2.h"
|
||||
#include "SaveManager.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "Enhancements/savestates.h"
|
||||
|
@ -19,13 +20,13 @@ public:
|
|||
~OTRGlobals();
|
||||
|
||||
private:
|
||||
|
||||
void CheckSaveFile(size_t sramSize);
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
void InitOTR();
|
||||
void Graph_ProcessFrame(void (*run_one_game_iter)(void));
|
||||
void OTRAudio_Init();
|
||||
void InitAudio();
|
||||
void Graph_StartFrame();
|
||||
void Graph_ProcessGfxCommands(Gfx* commands);
|
||||
void OTRLogString(const char* src);
|
||||
|
@ -35,6 +36,7 @@ uint16_t OTRGetPixelDepth(float x, float y);
|
|||
int32_t OTRGetLastScancode();
|
||||
uint32_t ResourceMgr_GetGameVersion();
|
||||
void ResourceMgr_CacheDirectory(const char* resName);
|
||||
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
|
||||
void ResourceMgr_LoadFile(const char* resName);
|
||||
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
|
||||
char* ResourceMgr_LoadTexByName(const char* texPath);
|
||||
|
@ -45,8 +47,17 @@ Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
|
|||
Gfx* ResourceMgr_LoadGfxByName(const char* path);
|
||||
Gfx* ResourceMgr_PatchGfxByName(const char* path, int size);
|
||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
||||
|
||||
Vtx* ResourceMgr_LoadVtxByName(const char* path);
|
||||
SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path);
|
||||
SequenceData ResourceMgr_LoadSeqByName(const char* path);
|
||||
SoundFontSample* ResourceMgr_LoadAudioSample(const char* path);
|
||||
CollisionHeader* ResourceMgr_LoadColByName(const char* path);
|
||||
void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
||||
void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size);
|
||||
char* Config_getValue(char* category, char* key);
|
||||
bool Config_setValue(char* category, char* key, char* value);
|
||||
|
||||
uint64_t GetPerfCounter();
|
||||
struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path);
|
||||
int ResourceMgr_OTRSigCheck(char* imgData);
|
||||
|
|
1217
soh/soh/SaveManager.cpp
Normal file
1217
soh/soh/SaveManager.cpp
Normal file
File diff suppressed because it is too large
Load diff
149
soh/soh/SaveManager.h
Normal file
149
soh/soh/SaveManager.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
#pragma once
|
||||
|
||||
#include <ultra64/gbi.h>
|
||||
|
||||
typedef struct {
|
||||
u8 valid;
|
||||
u16 deaths;
|
||||
char playerName[8];
|
||||
u16 healthCapacity;
|
||||
u32 questItems;
|
||||
s8 defense;
|
||||
u16 health;
|
||||
u8 n64ddFlag;
|
||||
} SaveFileMetaInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
|
||||
#include "Lib/nlohmann/json.hpp"
|
||||
|
||||
class SaveManager {
|
||||
public:
|
||||
static SaveManager* Instance;
|
||||
|
||||
using InitFunc = void(*)(bool isDebug);
|
||||
using LoadFunc = void(*)();
|
||||
using SaveFunc = void(*)();
|
||||
using PostFunc = void(*)(int version);
|
||||
|
||||
SaveManager();
|
||||
|
||||
void Init();
|
||||
void InitFile(bool isDebug);
|
||||
void SaveFile(int fileNum);
|
||||
void SaveGlobal();
|
||||
void LoadFile(int fileNum);
|
||||
|
||||
// Adds a function that is called when we are intializing a save, including when we are loading a save.
|
||||
void AddInitFunction(InitFunc func);
|
||||
|
||||
// Adds a function to handling loading a section
|
||||
void AddLoadFunction(const std::string& name, int version, LoadFunc func);
|
||||
|
||||
// Adds a function that is called when saving. This should only be called once for each function, the version is filled in automatically.
|
||||
void AddSaveFunction(const std::string& name, int version, SaveFunc func);
|
||||
|
||||
// Adds a function to be called after loading is complete. This is to handle any cleanup required from loading old versions.
|
||||
void AddPostFunction(const std::string& name, PostFunc func);
|
||||
|
||||
void CopyZeldaFile(int from, int to);
|
||||
void DeleteZeldaFile(int fileNum);
|
||||
|
||||
// Use a name of "" to save to an array. You must be in a SaveArray callback.
|
||||
template<typename T>
|
||||
void SaveData(const std::string& name, const T& data) {
|
||||
if (name == "") {
|
||||
assert((*currentJsonContext).is_array());
|
||||
(*currentJsonContext).push_back(data);
|
||||
} else {
|
||||
(*currentJsonContext)[name.c_str()] = data;
|
||||
}
|
||||
}
|
||||
|
||||
// In the SaveArrayFunc func, the name must be "" to save to the array.
|
||||
using SaveArrayFunc = std::function<void(size_t)>;
|
||||
void SaveArray(const std::string& name, const size_t size, SaveArrayFunc func);
|
||||
|
||||
using SaveStructFunc = std::function<void()>;
|
||||
void SaveStruct(const std::string& name, SaveStructFunc func);
|
||||
|
||||
// Use a name of "" to load from an array. You must be in a LoadArray callback.
|
||||
template<typename T> void LoadData(const std::string& name, T& data, const T& defaultValue = T{}) {
|
||||
if (name == "") {
|
||||
if (currentJsonArrayContext == currentJsonContext->end()) {
|
||||
// This array member is past the data in the json file. Therefore, default construct it
|
||||
data = defaultValue;
|
||||
} else {
|
||||
currentJsonArrayContext.value().get_to(data);
|
||||
}
|
||||
} else if (!currentJsonContext->contains(name.c_str())) {
|
||||
data = defaultValue;
|
||||
} else {
|
||||
(*currentJsonContext)[name.c_str()].get_to(data);
|
||||
}
|
||||
}
|
||||
|
||||
// In the LoadArrayFunc func, the name must be "" to load from the array.
|
||||
using LoadArrayFunc = std::function<void(size_t)>;
|
||||
void LoadArray(const std::string& name, const size_t size, LoadArrayFunc func);
|
||||
|
||||
using LoadStructFunc = std::function<void()>;
|
||||
void LoadStruct(const std::string& name, LoadStructFunc func);
|
||||
|
||||
static const int MaxFiles = 3;
|
||||
std::array<SaveFileMetaInfo, MaxFiles> fileMetaInfo;
|
||||
|
||||
private:
|
||||
std::filesystem::path GetFileName(int fileNum);
|
||||
|
||||
void ConvertFromUnversioned();
|
||||
void CreateDefaultGlobal();
|
||||
|
||||
void InitMeta(int slotNum);
|
||||
static void InitFileImpl(bool isDebug);
|
||||
static void InitFileNormal();
|
||||
static void InitFileDebug();
|
||||
|
||||
static void LoadBaseVersion1();
|
||||
static void SaveBase();
|
||||
|
||||
std::vector<InitFunc> initFuncs;
|
||||
|
||||
using SectionLoadHandler = std::map<int, LoadFunc>;
|
||||
std::map<std::string, SectionLoadHandler> sectionLoadHandlers;
|
||||
|
||||
using SectionSaveHandler = std::pair<int, SaveFunc>;
|
||||
std::map<std::string, SectionSaveHandler> sectionSaveHandlers;
|
||||
|
||||
std::map<std::string, PostFunc> postHandlers;
|
||||
|
||||
nlohmann::json* currentJsonContext = nullptr;
|
||||
nlohmann::json::iterator currentJsonArrayContext;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// TODO feature parity to the C++ interface. We need Save_AddInitFunction and Save_AddPostFunction at least
|
||||
|
||||
typedef void (*Save_LoadFunc)(void);
|
||||
typedef void (*Save_SaveFunc)(void);
|
||||
|
||||
void Save_Init(void);
|
||||
void Save_InitFile(int isDebug);
|
||||
void Save_SaveFile(void);
|
||||
void Save_SaveGlobal(void);
|
||||
void Save_LoadGlobal(void);
|
||||
void Save_AddLoadFunction(char* name, int version, Save_LoadFunc func);
|
||||
void Save_AddSaveFunction(char* name, int version, Save_SaveFunc func);
|
||||
SaveFileMetaInfo* Save_GetSaveMetaInfo(int fileNum);
|
||||
void Save_CopyFile(int from, int to);
|
||||
void Save_DeleteFile(int fileNum);
|
||||
|
||||
#endif
|
|
@ -445,7 +445,9 @@ void osViExtendVStart(u32 arg0)
|
|||
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
AudioTable gSoundFontTable = { 0 };
|
||||
#else
|
||||
AudioTable gSoundFontTable = { 0x0026,
|
||||
0x0000,
|
||||
0x00000000,
|
||||
|
@ -795,7 +797,11 @@ AudioTable gSoundFontTable = { 0x0026,
|
|||
},
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
AudioTable gSequenceTable = { 0 };
|
||||
#else
|
||||
AudioTable gSequenceTable = { 0x006E,
|
||||
0x0000,
|
||||
0x00000000,
|
||||
|
@ -1585,7 +1591,7 @@ AudioTable gSequenceTable = { 0x006E,
|
|||
0x0000,
|
||||
},
|
||||
{
|
||||
0x00000028,
|
||||
0x00000028,
|
||||
0x00000000,
|
||||
0x02,
|
||||
0x02,
|
||||
|
@ -1791,9 +1797,12 @@ AudioTable gSequenceTable = { 0x006E,
|
|||
0x0000,
|
||||
0x0000,
|
||||
},
|
||||
}
|
||||
};
|
||||
} };
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
AudioTable gSampleBankTable = { 0 };
|
||||
#else
|
||||
AudioTable gSampleBankTable = { 0x0007,
|
||||
0x0000,
|
||||
0x00000000,
|
||||
|
@ -1864,7 +1873,11 @@ AudioTable gSampleBankTable = { 0x0007,
|
|||
},
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
u8 gSequenceFontTable[1] = { 0 };
|
||||
#else
|
||||
u8 gSequenceFontTable[0x1C0] = {
|
||||
0xDC,
|
||||
0x00,
|
||||
|
@ -2100,3 +2113,4 @@ u8 gSequenceFontTable[0x1C0] = {
|
|||
0x03, 0x01, 0x1F, 0x01, 0x20, 0x01, 0x20, 0x01, 0x09, 0x01, 0x21, 0x01, 0x22, 0x01, 0x21, 0x01, 0x09, 0x01, 0x20,
|
||||
0x01, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
#endif
|
|
@ -544,16 +544,10 @@ u8 gDefaultShortNoteGateTimeTable[] = {
|
|||
};
|
||||
|
||||
AdsrEnvelope gDefaultEnvelope[] = {
|
||||
// OTRTODO: Byteswapped manually for quick audio support.
|
||||
{ 0x0100, 0x007D },
|
||||
{ 0xE803, 0x007D },
|
||||
{ 0xFFFF, 0x0000 },
|
||||
{ 0x0000, 0x0000 },
|
||||
/* { 1, 32000 },
|
||||
{ 1000, 32000 },
|
||||
{ -1, 0 },
|
||||
{ 0, 0 },
|
||||
*/
|
||||
};
|
||||
|
||||
NoteSubEu gZeroNoteSub = { 0 };
|
||||
|
|
|
@ -10,6 +10,8 @@ void AudioHeap_DiscardSampleCaches(void);
|
|||
void AudioHeap_DiscardSampleBank(s32 sampleBankId);
|
||||
void AudioHeap_DiscardSampleBanks(void);
|
||||
|
||||
extern bool gUseLegacySD;
|
||||
|
||||
f32 func_800DDE20(f32 arg0) {
|
||||
return 256.0f * gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled / arg0;
|
||||
}
|
||||
|
@ -1201,7 +1203,11 @@ void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) {
|
|||
}
|
||||
}
|
||||
|
||||
void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample) {
|
||||
void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample)
|
||||
{
|
||||
if (!gUseLegacySD)
|
||||
return;
|
||||
|
||||
if (sample != NULL) {
|
||||
if (sample->sampleAddr == entry->allocatedAddr) {
|
||||
sample->sampleAddr = entry->sampleAddr;
|
||||
|
|
|
@ -10,7 +10,8 @@ const s16 D_8014A6C0[] = {
|
|||
0x0030, // gTatumsPerBeat
|
||||
};
|
||||
|
||||
const AudioContextInitSizes D_8014A6C4 = { 0x37F00, 0xE0E0, 0xBCE0 };
|
||||
//const AudioContextInitSizes D_8014A6C4 = { 0x37F00, 0xE0E0, 0xBCE0 };
|
||||
const AudioContextInitSizes D_8014A6C4 = { 0x37F000, 0xE0E00, 0xBCE00 }; // OTRTODO: This might be overkill...
|
||||
|
||||
ReverbSettings D_80133420[][3] = {
|
||||
{
|
||||
|
@ -67,22 +68,22 @@ ReverbSettings D_80133420[][3] = {
|
|||
};
|
||||
|
||||
AudioSpec gAudioSpecs[18] = {
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 },
|
||||
{ 32000, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 },
|
||||
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 23, 4, 0, 0, 2, D_80133420[4], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 23, 4, 0, 0, 2, D_80133420[5], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[6], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[7], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[9], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 23, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 28, 3, 0, 0, 2, D_80133420[10], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x2800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0x4800, 0, 0x4000, 0, 0, 0, 0 },
|
||||
{ 44100, 1, 28, 3, 0, 0, 1, D_80133420[11], 0x300, 0x200, 0x7FFF, 0, 0, 0, 0x4000, 0x4800, 0, 0, 0 },
|
||||
{ 44100, 1, 22, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 22, 4, 0, 0, 2, D_80133420[8], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 44100, 1, 16, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 22050, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },
|
||||
{ 32000, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 },
|
||||
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[2], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3600, 0x2600, 0, 0, 0 },
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
#define MK_ASYNC_MSG(retData, tableType, id, status) (((retData) << 24) | ((tableType) << 16) | ((id) << 8) | (status))
|
||||
#define ASYNC_TBLTYPE(v) ((u8)(v >> 16))
|
||||
|
@ -37,14 +38,14 @@ void AudioLoad_ProcessAsyncLoads(s32 resetStatus);
|
|||
void AudioLoad_ProcessAsyncLoadUnkMedium(AudioAsyncLoad* asyncLoad, s32 resetStatus);
|
||||
void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus);
|
||||
void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo, s32 temporary);
|
||||
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo);
|
||||
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo, int fontId);
|
||||
void AudioLoad_DiscardFont(s32 fontId);
|
||||
u32 AudioLoad_TrySyncLoadSampleBank(u32 sampleBankId, u32* outMedium, s32 noLoad);
|
||||
void* AudioLoad_SyncLoad(u32 tableType, u32 tableId, s32* didAllocate);
|
||||
u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 tableId);
|
||||
void* AudioLoad_SearchCaches(s32 tableType, s32 id);
|
||||
AudioTable* AudioLoad_GetLoadTable(s32 tableType);
|
||||
void AudioLoad_SyncDma(u32 devAddr, u8* addr, size_t size, s32 medium);
|
||||
void AudioLoad_SyncDma(uintptr_t devAddr, u8* addr, size_t size, s32 medium);
|
||||
void AudioLoad_SyncDmaUnkMedium(u32 devAddr, u8* addr, size_t size, s32 unkMediumParam);
|
||||
s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, u32 devAddr, void* ramAddr, size_t size,
|
||||
OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType);
|
||||
|
@ -74,6 +75,14 @@ void* sUnusedHandler = NULL;
|
|||
|
||||
s32 gAudioContextInitalized = false;
|
||||
|
||||
char* sequenceMap[256];
|
||||
char* fontMap[256];
|
||||
|
||||
uintptr_t fontStart;
|
||||
uint32_t fontOffsets[8192];
|
||||
|
||||
bool gUseLegacySD = false;
|
||||
|
||||
void AudioLoad_DecreaseSampleDmaTtls(void) {
|
||||
u32 i;
|
||||
|
||||
|
@ -278,8 +287,11 @@ void AudioLoad_InitSampleDmaBuffers(s32 arg0) {
|
|||
}
|
||||
|
||||
s32 AudioLoad_IsFontLoadComplete(s32 fontId) {
|
||||
return true;
|
||||
|
||||
if (fontId == 0xFF) {
|
||||
return true;
|
||||
|
||||
} else if (gAudioContext.fontLoadStatus[fontId] >= 2) {
|
||||
return true;
|
||||
} else if (gAudioContext.fontLoadStatus[AudioLoad_GetRealTableIndex(FONT_TABLE, fontId)] >= 2) {
|
||||
|
@ -352,6 +364,9 @@ void AudioLoad_InitTable(AudioTable* table, uintptr_t romAddr, u16 unkMediumPara
|
|||
|
||||
for (i = 0; i < table->numEntries; i++) {
|
||||
if ((table->entries[i].size != 0) && (table->entries[i].medium == MEDIUM_CART)) {
|
||||
if (romAddr == fontStart)
|
||||
fontOffsets[i] = table->entries[i].romAddr;
|
||||
|
||||
table->entries[i].romAddr += romAddr;
|
||||
}
|
||||
}
|
||||
|
@ -360,7 +375,7 @@ void AudioLoad_InitTable(AudioTable* table, uintptr_t romAddr, u16 unkMediumPara
|
|||
SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) {
|
||||
char pad[0x8];
|
||||
s32 index;
|
||||
SoundFontData* font;
|
||||
SoundFontData* font = NULL;
|
||||
s32 numFonts;
|
||||
s32 fontId;
|
||||
s32 i;
|
||||
|
@ -375,6 +390,7 @@ SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) {
|
|||
|
||||
while (numFonts > 0) {
|
||||
fontId = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
font = AudioLoad_SyncLoadFont(fontId);
|
||||
numFonts--;
|
||||
}
|
||||
|
@ -400,7 +416,8 @@ void AudioLoad_SyncLoadSeqParts(s32 seqId, s32 arg1) {
|
|||
s32 AudioLoad_SyncLoadSample(SoundFontSample* sample, s32 fontId) {
|
||||
void* sampleAddr;
|
||||
|
||||
if (sample->unk_bit25 == 1) {
|
||||
if (sample->unk_bit25 == 1)
|
||||
{
|
||||
if (sample->medium != MEDIUM_RAM) {
|
||||
sampleAddr = AudioHeap_AllocSampleCache(sample->size, fontId, (void*)sample->sampleAddr, sample->medium,
|
||||
CACHE_PERSISTENT);
|
||||
|
@ -466,13 +483,26 @@ void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* ret
|
|||
u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) {
|
||||
s32 index;
|
||||
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
if (!gUseLegacySD)
|
||||
{
|
||||
if (seqId == 255)
|
||||
return NULL;
|
||||
|
||||
*outNumFonts = gAudioContext.sequenceFontTable[index++];
|
||||
if (*outNumFonts == 0) {
|
||||
return NULL;
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||
|
||||
if (sDat.numFonts == 0)
|
||||
return NULL;
|
||||
|
||||
return sDat.fonts;
|
||||
} else {
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
|
||||
*outNumFonts = gAudioContext.sequenceFontTable[index++];
|
||||
if (*outNumFonts == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return &gAudioContext.sequenceFontTable[index];
|
||||
}
|
||||
return &gAudioContext.sequenceFontTable[index];
|
||||
}
|
||||
|
||||
void AudioLoad_DiscardSeqFonts(s32 seqId) {
|
||||
|
@ -544,30 +574,52 @@ s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) {
|
|||
s32 numFonts;
|
||||
s32 fontId;
|
||||
|
||||
if (seqId >= gAudioContext.numSequences) {
|
||||
if (gUseLegacySD && seqId >= gAudioContext.numSequences) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
AudioSeq_SequencePlayerDisable(seqPlayer);
|
||||
|
||||
fontId = 0xFF;
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
numFonts = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
while (numFonts > 0) {
|
||||
fontId = gAudioContext.sequenceFontTable[index++];
|
||||
AudioLoad_SyncLoadFont(fontId);
|
||||
numFonts--;
|
||||
if (gUseLegacySD) {
|
||||
index = ((u16*)gAudioContext.sequenceFontTable)[seqId];
|
||||
numFonts = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
while (numFonts > 0) {
|
||||
fontId = gAudioContext.sequenceFontTable[index++];
|
||||
|
||||
AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds...
|
||||
|
||||
numFonts--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SequenceData seqData2 = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||
|
||||
for (int i = 0; i < seqData2.numFonts; i++)
|
||||
{
|
||||
fontId = seqData2.fonts[i];
|
||||
AudioLoad_SyncLoadFont(fontId); // NOTE: If this is commented out, then enemies will play child link sounds...
|
||||
numFonts--;
|
||||
}
|
||||
}
|
||||
|
||||
seqData = AudioLoad_SyncLoadSeq(seqId);
|
||||
|
||||
if (seqData == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
AudioSeq_ResetSequencePlayer(seqPlayer);
|
||||
seqPlayer->seqId = seqId;
|
||||
seqPlayer->defaultFont = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId);
|
||||
|
||||
if (gUseLegacySD)
|
||||
seqPlayer->defaultFont = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId);
|
||||
else
|
||||
seqPlayer->defaultFont = fontId;
|
||||
|
||||
seqPlayer->seqData = seqData;
|
||||
seqPlayer->enabled = 1;
|
||||
seqPlayer->scriptState.pc = seqData;
|
||||
|
@ -637,8 +689,18 @@ SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) {
|
|||
if (gAudioContext.fontLoadStatus[realFontId] == 1) {
|
||||
return NULL;
|
||||
}
|
||||
sampleBankId1 = gAudioContext.soundFonts[realFontId].sampleBankId1;
|
||||
sampleBankId2 = gAudioContext.soundFonts[realFontId].sampleBankId2;
|
||||
|
||||
if (!gUseLegacySD) {
|
||||
SoundFont* sf = ResourceMgr_LoadAudioSoundFont
|
||||
(fontMap[fontId]);
|
||||
|
||||
sampleBankId1 = sf->sampleBankId1;
|
||||
sampleBankId2 = sf->sampleBankId2;
|
||||
} else {
|
||||
|
||||
sampleBankId1 = gAudioContext.soundFonts[realFontId].sampleBankId1;
|
||||
sampleBankId2 = gAudioContext.soundFonts[realFontId].sampleBankId2;
|
||||
}
|
||||
|
||||
relocInfo.sampleBankId1 = sampleBankId1;
|
||||
relocInfo.sampleBankId2 = sampleBankId2;
|
||||
|
@ -681,13 +743,38 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
|
|||
if (ret != NULL) {
|
||||
*didAllocate = false;
|
||||
status = 2;
|
||||
} else {
|
||||
table = AudioLoad_GetLoadTable(tableType);
|
||||
size = table->entries[realId].size;
|
||||
size = ALIGN16(size);
|
||||
medium = table->entries[id].medium;
|
||||
cachePolicy = table->entries[id].cachePolicy;
|
||||
romAddr = table->entries[realId].romAddr;
|
||||
} else
|
||||
{
|
||||
char* seqData = 0;
|
||||
SoundFont* fnt;
|
||||
|
||||
if (!gUseLegacySD && tableType == SEQUENCE_TABLE)
|
||||
{
|
||||
SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[id]);
|
||||
seqData = sData.seqData;
|
||||
size = sData.seqDataSize;
|
||||
medium = sData.medium;
|
||||
cachePolicy = sData.cachePolicy;
|
||||
romAddr = 0;
|
||||
}
|
||||
else if (!gUseLegacySD && tableType == FONT_TABLE)
|
||||
{
|
||||
fnt = ResourceMgr_LoadAudioSoundFont(fontMap[id]);
|
||||
size = sizeof(SoundFont);
|
||||
medium = 2;
|
||||
cachePolicy = 0;
|
||||
romAddr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
table = AudioLoad_GetLoadTable(tableType);
|
||||
size = table->entries[realId].size;
|
||||
size = ALIGN16(size);
|
||||
medium = table->entries[id].medium;
|
||||
cachePolicy = table->entries[id].cachePolicy;
|
||||
romAddr = table->entries[realId].romAddr;
|
||||
}
|
||||
|
||||
switch (cachePolicy) {
|
||||
case 0:
|
||||
ret = AudioHeap_AllocPermanent(tableType, realId, size);
|
||||
|
@ -720,7 +807,14 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
|
|||
if (medium == MEDIUM_UNK) {
|
||||
AudioLoad_SyncDmaUnkMedium(romAddr, ret, size, (s16)table->unkMediumParam);
|
||||
} else {
|
||||
AudioLoad_SyncDma(romAddr, ret, size, medium);
|
||||
if (!gUseLegacySD && tableType == SEQUENCE_TABLE && seqData != NULL) {
|
||||
AudioLoad_SyncDma(seqData, ret, size, medium);
|
||||
} else if (!gUseLegacySD && tableType == FONT_TABLE) {
|
||||
AudioLoad_SyncDma(fnt, ret, size, medium);
|
||||
}
|
||||
else {
|
||||
AudioLoad_SyncDma(romAddr, ret, size, medium);
|
||||
}
|
||||
}
|
||||
|
||||
status = cachePolicy == 0 ? 5 : 2;
|
||||
|
@ -743,9 +837,16 @@ void* AudioLoad_SyncLoad(u32 tableType, u32 id, s32* didAllocate) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id) {
|
||||
u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id)
|
||||
{
|
||||
if ((tableType == SEQUENCE_TABLE || tableType == FONT_TABLE) && !gUseLegacySD) {
|
||||
return id;
|
||||
}
|
||||
|
||||
AudioTable* table = AudioLoad_GetLoadTable(tableType);
|
||||
|
||||
// If the size is 0, then this entry actually redirects to another entry.
|
||||
// The rom address is actually an index into the same table where the "real" data is.
|
||||
if (table->entries[id].size == 0) {
|
||||
id = table->entries[id].romAddr;
|
||||
}
|
||||
|
@ -796,29 +897,64 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo
|
|||
Drum* drum;
|
||||
SoundFontSound* sfx;
|
||||
s32 i;
|
||||
s32 numDrums = gAudioContext.soundFonts[fontId].numDrums;
|
||||
s32 numInstruments = gAudioContext.soundFonts[fontId].numInstruments;
|
||||
s32 numSfx = gAudioContext.soundFonts[fontId].numSfx;
|
||||
SoundFont* sf = NULL;
|
||||
|
||||
s32 numDrums = 0;
|
||||
s32 numInstruments = 0;
|
||||
s32 numSfx = 0;
|
||||
|
||||
if (gUseLegacySD) {
|
||||
numDrums = gAudioContext.soundFonts[fontId].numDrums;
|
||||
numInstruments = gAudioContext.soundFonts[fontId].numInstruments;
|
||||
numSfx = gAudioContext.soundFonts[fontId].numSfx;
|
||||
} else {
|
||||
sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]);
|
||||
numDrums = sf->numDrums;
|
||||
numInstruments = sf->numInstruments;
|
||||
numSfx = sf->numSfx;
|
||||
}
|
||||
|
||||
void** ptrs = (void**)mem;
|
||||
|
||||
|
||||
#define BASE_OFFSET(x) (void*)((u32)(x) + (u32)(mem))
|
||||
|
||||
reloc2 = ptrs[0];
|
||||
if (1) {}
|
||||
if ((reloc2 != 0) && (numDrums != 0)) {
|
||||
if ((reloc2 != 0 || !gUseLegacySD) && (numDrums != 0))
|
||||
{
|
||||
ptrs[0] = BASE_OFFSET(reloc2);
|
||||
for (i = 0; i < numDrums; i++) {
|
||||
reloc = ((Drum**)ptrs[0])[i];
|
||||
for (i = 0; i < numDrums; i++)
|
||||
{
|
||||
if (gUseLegacySD)
|
||||
reloc = ((Drum**)ptrs[0])[i];
|
||||
|
||||
if (reloc != 0) {
|
||||
reloc = BASE_OFFSET(reloc);
|
||||
if (reloc != 0 || !gUseLegacySD)
|
||||
{
|
||||
if (gUseLegacySD)
|
||||
{
|
||||
reloc = BASE_OFFSET(reloc);
|
||||
((Drum**)ptrs[0])[i] = drum = reloc;
|
||||
}
|
||||
|
||||
((Drum**)ptrs[0])[i] = drum = reloc;
|
||||
if (!drum->loaded) {
|
||||
AudioLoad_RelocateSample(&drum->sound, mem, relocInfo);
|
||||
reloc = drum->envelope;
|
||||
drum->envelope = BASE_OFFSET(reloc);
|
||||
drum->loaded = 1;
|
||||
if (!gUseLegacySD)
|
||||
drum = sf->drums[i];
|
||||
|
||||
if (!drum->loaded)
|
||||
{
|
||||
if (!gUseLegacySD)
|
||||
{
|
||||
AudioLoad_RelocateSample(&sf->drums[i]->sound, mem, relocInfo, fontOffsets[fontId]);
|
||||
//reloc = drum->envelope;
|
||||
drum->loaded = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioLoad_RelocateSample(&drum->sound, mem, relocInfo, fontOffsets[fontId]);
|
||||
reloc = drum->envelope;
|
||||
drum->envelope = BASE_OFFSET(reloc);
|
||||
drum->loaded = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -826,39 +962,56 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo
|
|||
|
||||
reloc2 = ptrs[1];
|
||||
if (1) {}
|
||||
if ((reloc2 != 0) && (numSfx != 0)) {
|
||||
if ((reloc2 != 0 || !gUseLegacySD) && (numSfx != 0)) {
|
||||
ptrs[1] = BASE_OFFSET(reloc2);
|
||||
for (i = 0; i < numSfx; i++) {
|
||||
reloc = (SoundFontSound*)ptrs[1] + i;
|
||||
if (reloc != 0) {
|
||||
sfx = reloc;
|
||||
if (sfx->sample != NULL) {
|
||||
AudioLoad_RelocateSample(sfx, mem, relocInfo);
|
||||
if (reloc != 0 || !gUseLegacySD)
|
||||
{
|
||||
if (!gUseLegacySD) {
|
||||
AudioLoad_RelocateSample(&sf->soundEffects[i].sample, mem, relocInfo, fontOffsets[fontId]);
|
||||
} else {
|
||||
sfx = reloc;
|
||||
if (sfx->sample != NULL) {
|
||||
AudioLoad_RelocateSample(sfx, mem, relocInfo, fontOffsets[fontId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (numInstruments > 0x7E) {
|
||||
numInstruments = 0x7E;
|
||||
}
|
||||
|
||||
for (i = 2; i <= 2 + numInstruments - 1; i++) {
|
||||
if (ptrs[i] != NULL) {
|
||||
int startI = gUseLegacySD ? 2 : 0;
|
||||
int startEC = gUseLegacySD ? 2 + numInstruments - 1 : numInstruments - 1;
|
||||
//for (i = 2; i <= 2 + numInstruments - 1; i++) {
|
||||
for (i = startI; i <= startEC; i++) {
|
||||
if (!gUseLegacySD || ptrs[i] != NULL)
|
||||
{
|
||||
ptrs[i] = BASE_OFFSET(ptrs[i]);
|
||||
|
||||
inst = ptrs[i];
|
||||
if (!inst->loaded) {
|
||||
if (inst->normalRangeLo != 0) {
|
||||
AudioLoad_RelocateSample(&inst->lowNotesSound, mem, relocInfo);
|
||||
if (gUseLegacySD)
|
||||
inst = ptrs[i];
|
||||
else
|
||||
inst = sf->instruments[i];
|
||||
|
||||
if (inst != NULL && !inst->loaded) {
|
||||
if (inst->normalRangeLo != 0)
|
||||
{
|
||||
AudioLoad_RelocateSample(&inst->lowNotesSound, mem, relocInfo, fontOffsets[fontId]);
|
||||
}
|
||||
AudioLoad_RelocateSample(&inst->normalNotesSound, mem, relocInfo);
|
||||
AudioLoad_RelocateSample(&inst->normalNotesSound, mem, relocInfo, fontOffsets[fontId]);
|
||||
if (inst->normalRangeHi != 0x7F) {
|
||||
AudioLoad_RelocateSample(&inst->highNotesSound, mem, relocInfo);
|
||||
AudioLoad_RelocateSample(&inst->highNotesSound, mem, relocInfo, fontOffsets[fontId]);
|
||||
}
|
||||
|
||||
reloc = inst->envelope;
|
||||
inst->envelope = BASE_OFFSET(reloc);
|
||||
|
||||
if (gUseLegacySD)
|
||||
inst->envelope = BASE_OFFSET(reloc);
|
||||
|
||||
inst->loaded = 1;
|
||||
}
|
||||
}
|
||||
|
@ -866,12 +1019,14 @@ void AudioLoad_RelocateFont(s32 fontId, SoundFontData* mem, RelocInfo* relocInfo
|
|||
|
||||
#undef BASE_OFFSET
|
||||
|
||||
gAudioContext.soundFonts[fontId].drums = ptrs[0];
|
||||
gAudioContext.soundFonts[fontId].soundEffects = ptrs[1];
|
||||
gAudioContext.soundFonts[fontId].instruments = (Instrument**)(ptrs + 2);
|
||||
if (gUseLegacySD) {
|
||||
gAudioContext.soundFonts[fontId].drums = ptrs[0];
|
||||
gAudioContext.soundFonts[fontId].soundEffects = ptrs[1];
|
||||
gAudioContext.soundFonts[fontId].instruments = (Instrument**)(ptrs + 2);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioLoad_SyncDma(u32 devAddr, u8* addr, size_t size, s32 medium) {
|
||||
void AudioLoad_SyncDma(uintptr_t devAddr, u8* addr, size_t size, s32 medium) {
|
||||
OSMesgQueue* msgQueue = &gAudioContext.syncDmaQueue;
|
||||
OSIoMesg* ioMesg = &gAudioContext.syncDmaIoMesg;
|
||||
size = ALIGN16(size);
|
||||
|
@ -1054,7 +1209,6 @@ s32 AudioLoad_AssertValidAddr(uintptr_t ramAddr, uintptr_t startAddr, size_t siz
|
|||
#define BASE_ROM_OFFSET(x) (void*)((u32)(x) + (u32)(romAddr))
|
||||
|
||||
void AudioLoad_InitSwapFontSampleHeaders(SoundFontSample* sample, uintptr_t romAddr) {
|
||||
// OTRTODO: This will be removed when we actually extract the data.
|
||||
size_t maxSoundFontSize = 0x3AA0; // soundFont 0 is the largest size at 0x3AA0
|
||||
AdpcmLoop* loop;
|
||||
AdpcmBook* book;
|
||||
|
@ -1270,17 +1424,64 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
|
|||
uintptr_t bankStart = ResourceMgr_LoadFileRaw(_AudiobankSegmentRomStart);
|
||||
uintptr_t tableStart = ResourceMgr_LoadFileRaw(_AudiotableSegmentRomStart);
|
||||
|
||||
// If we have the old audioseq files present (and this is a 32-bit build), use the legacy audio system
|
||||
if (seqStart != NULL && bankStart != NULL && tableStart != NULL)
|
||||
gUseLegacySD = true;
|
||||
|
||||
fontStart = bankStart;
|
||||
|
||||
AudioLoad_InitTable(gAudioContext.sequenceTable, seqStart, 0);
|
||||
AudioLoad_InitTable(gAudioContext.soundFontTable, bankStart, 0);
|
||||
AudioLoad_InitTable(gAudioContext.sampleBankTable, tableStart, 0);
|
||||
numFonts = gAudioContext.soundFontTable->numEntries;
|
||||
gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont));
|
||||
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
AudioLoad_InitSoundFontMeta(i);
|
||||
if (gUseLegacySD)
|
||||
numFonts = gAudioContext.soundFontTable->numEntries;
|
||||
|
||||
if (gUseLegacySD)
|
||||
{
|
||||
gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont));
|
||||
|
||||
for (i = 0; i < numFonts; i++) {
|
||||
AudioLoad_InitSoundFontMeta(i);
|
||||
}
|
||||
|
||||
AudioLoad_InitSwapFont();
|
||||
} else {
|
||||
int seqListSize = 0;
|
||||
char** seqList = ResourceMgr_ListFiles("audio/sequences*", &seqListSize);
|
||||
|
||||
for (int i = 0; i < seqListSize; i++)
|
||||
{
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(seqList[i]);
|
||||
|
||||
char* str = malloc(strlen(seqList[i]) + 1);
|
||||
strcpy(str, seqList[i]);
|
||||
|
||||
sequenceMap[sDat.seqNumber] = str;
|
||||
}
|
||||
|
||||
free(seqList);
|
||||
|
||||
int fntListSize = 0;
|
||||
char** fntList = ResourceMgr_ListFiles("audio/fonts*", &fntListSize);
|
||||
|
||||
for (int i = 0; i < fntListSize; i++)
|
||||
{
|
||||
SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fntList[i]);
|
||||
|
||||
char* str = malloc(strlen(fntList[i]) + 1);
|
||||
strcpy(str, fntList[i]);
|
||||
|
||||
fontMap[sf->fntIndex] = str;
|
||||
}
|
||||
|
||||
numFonts = fntListSize;
|
||||
|
||||
free(fntList);
|
||||
gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont));
|
||||
|
||||
}
|
||||
|
||||
AudioLoad_InitSwapFont();
|
||||
|
||||
if (temp_v0_3 = AudioHeap_Alloc(&gAudioContext.audioInitPool, D_8014A6C4.permanentPoolSize), temp_v0_3 == NULL) {
|
||||
// cast away const from D_8014A6C4
|
||||
|
@ -1300,7 +1501,6 @@ void AudioLoad_InitSlowLoads(void) {
|
|||
s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) {
|
||||
SoundFontSample* sample;
|
||||
AudioSlowLoad* slowLoad;
|
||||
|
||||
sample = AudioLoad_GetFontSample(fontId, instId);
|
||||
if (sample == NULL) {
|
||||
*isDone = 0;
|
||||
|
@ -1454,28 +1654,42 @@ s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone) {
|
|||
AudioTable* seqTable;
|
||||
size_t size;
|
||||
|
||||
if (seqId >= gAudioContext.numSequences) {
|
||||
if (gUseLegacySD && seqId >= gAudioContext.numSequences) {
|
||||
*isDone = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
seqId = AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId);
|
||||
|
||||
seqTable = AudioLoad_GetLoadTable(SEQUENCE_TABLE);
|
||||
|
||||
slowLoad = &gAudioContext.slowLoads[gAudioContext.slowLoadPos];
|
||||
if (slowLoad->status == LOAD_STATUS_DONE) {
|
||||
slowLoad->status = LOAD_STATUS_WAITING;
|
||||
}
|
||||
|
||||
|
||||
slowLoad->sample.sampleAddr = NULL;
|
||||
slowLoad->isDone = isDone;
|
||||
size = seqTable->entries[seqId].size;
|
||||
size = ALIGN16(size);
|
||||
|
||||
if (!gUseLegacySD)
|
||||
{
|
||||
SequenceData sData = ResourceMgr_LoadSeqByName(sequenceMap[seqId]);
|
||||
char* seqData = sData.seqData;
|
||||
size = sData.seqDataSize;
|
||||
slowLoad->curDevAddr = seqData;
|
||||
slowLoad->medium = sData.medium;
|
||||
} else {
|
||||
size = seqTable->entries[seqId].size;
|
||||
size = ALIGN16(size);
|
||||
slowLoad->curDevAddr = seqTable->entries[seqId].romAddr;
|
||||
slowLoad->medium = seqTable->entries[seqId].medium;
|
||||
}
|
||||
|
||||
slowLoad->curRamAddr = ramAddr;
|
||||
slowLoad->status = LOAD_STATUS_START;
|
||||
slowLoad->bytesRemaining = size;
|
||||
slowLoad->ramAddr = ramAddr;
|
||||
slowLoad->curDevAddr = seqTable->entries[seqId].romAddr;
|
||||
slowLoad->medium = seqTable->entries[seqId].medium;
|
||||
slowLoad->seqOrFontId = seqId;
|
||||
|
||||
if (slowLoad->medium == MEDIUM_UNK) {
|
||||
|
@ -1687,44 +1901,52 @@ void AudioLoad_AsyncDmaUnkMedium(u32 devAddr, void* ramAddr, size_t size, s16 ar
|
|||
|
||||
#define RELOC(v, base) (reloc = (void*)((u32)(v) + (u32)(base)))
|
||||
|
||||
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo) {
|
||||
// OTRTODO: This is hack to detect whether or not the sample has been relocated.
|
||||
void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, RelocInfo* relocInfo, int fontId) {
|
||||
size_t maxSoundBankSize = 0x3EB2A0; // sample bank 0 is largest size at 0x3EB2A0
|
||||
if ((uintptr_t)mem <= maxSoundBankSize) {
|
||||
// OTRTODO: This can be removed once we have properly byteswapped files on the disk.
|
||||
assert("mem for sound font bank is too low.");
|
||||
if (gUseLegacySD)
|
||||
{
|
||||
// NOTE: This is hack to detect whether or not the sample has been relocated.
|
||||
if ((uintptr_t)mem <= maxSoundBankSize) {
|
||||
assert("mem for sound font bank is too low.");
|
||||
}
|
||||
}
|
||||
|
||||
SoundFontSample* sample;
|
||||
void* reloc;
|
||||
|
||||
// OTRTODO: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works.
|
||||
if ((uintptr_t)sound->sample < maxSoundBankSize) {
|
||||
sample = sound->sample = RELOC(sound->sample, mem);
|
||||
if (sample->size != 0 && sample->unk_bit25 != 1) {
|
||||
sample->loop = RELOC(sample->loop, mem);
|
||||
sample->book = RELOC(sample->book, mem);
|
||||
// NOTE: Seems precarious to assume the RAM is never <= 0x3EB2A0, but it largely works.
|
||||
if ((uintptr_t)sound->sample < maxSoundBankSize || !gUseLegacySD)
|
||||
{
|
||||
if (!gUseLegacySD) {
|
||||
SoundFontSample* sample2 = sound;
|
||||
} else {
|
||||
sample = sound->sample = RELOC(sound->sample, mem);
|
||||
|
||||
// Resolve the sample medium 2-bit bitfield into a real value based on relocInfo.
|
||||
switch (sample->medium) {
|
||||
case 0:
|
||||
sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr1);
|
||||
sample->medium = relocInfo->medium1;
|
||||
break;
|
||||
case 1:
|
||||
sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr2);
|
||||
sample->medium = relocInfo->medium2;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
// Invalid? This leaves sample->medium as MEDIUM_CART and MEDIUM_DISK_DRIVE
|
||||
// respectively, and the sampleAddr unrelocated.
|
||||
break;
|
||||
}
|
||||
if (sample->size != 0 && sample->unk_bit25 != 1) {
|
||||
sample->loop = RELOC(sample->loop, mem);
|
||||
sample->book = RELOC(sample->book, mem);
|
||||
|
||||
sample->unk_bit25 = 1;
|
||||
if (sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) {
|
||||
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
||||
// Resolve the sample medium 2-bit bitfield into a real value based on relocInfo.
|
||||
switch (sample->medium) {
|
||||
case 0:
|
||||
sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr1);
|
||||
sample->medium = relocInfo->medium1;
|
||||
break;
|
||||
case 1:
|
||||
sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr2);
|
||||
sample->medium = relocInfo->medium2;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
// Invalid? This leaves sample->medium as MEDIUM_CART and MEDIUM_DISK_DRIVE
|
||||
// respectively, and the sampleAddr unrelocated.
|
||||
break;
|
||||
}
|
||||
|
||||
sample->unk_bit25 = 1;
|
||||
if (sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) {
|
||||
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1949,8 +2171,10 @@ s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) {
|
|||
void AudioLoad_AddUsedSample(SoundFontSound* sound) {
|
||||
SoundFontSample* sample = sound->sample;
|
||||
|
||||
if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) {
|
||||
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
||||
if (sample != NULL) {
|
||||
if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) {
|
||||
gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1977,9 +2201,17 @@ void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, RelocInfo* relocInfo
|
|||
|
||||
gAudioContext.numUsedSamples = 0;
|
||||
|
||||
numDrums = gAudioContext.soundFonts[fontId].numDrums;
|
||||
numInstruments = gAudioContext.soundFonts[fontId].numInstruments;
|
||||
numSfx = gAudioContext.soundFonts[fontId].numSfx;
|
||||
if (!gUseLegacySD) {
|
||||
SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]);
|
||||
|
||||
numDrums = sf->numDrums;
|
||||
numInstruments = sf->numInstruments;
|
||||
numSfx = sf->numSfx;
|
||||
} else {
|
||||
numDrums = gAudioContext.soundFonts[fontId].numDrums;
|
||||
numInstruments = gAudioContext.soundFonts[fontId].numInstruments;
|
||||
numSfx = gAudioContext.soundFonts[fontId].numSfx;
|
||||
}
|
||||
|
||||
for (i = 0; i < numInstruments; i++) {
|
||||
instrument = Audio_GetInstrumentInner(fontId, i);
|
||||
|
@ -2024,6 +2256,7 @@ void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, RelocInfo* relocInfo
|
|||
}
|
||||
|
||||
sample = gAudioContext.usedSamples[i];
|
||||
|
||||
if (sample->medium == MEDIUM_RAM) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2100,10 +2333,19 @@ void AudioLoad_LoadPermanentSamples(void) {
|
|||
for (i = 0; i < gAudioContext.permanentPool.count; i++) {
|
||||
RelocInfo relocInfo;
|
||||
|
||||
if (gAudioContext.permanentCache[i].tableType == FONT_TABLE) {
|
||||
if (gAudioContext.permanentCache[i].tableType == FONT_TABLE)
|
||||
{
|
||||
fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioContext.permanentCache[i].id);
|
||||
relocInfo.sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1;
|
||||
relocInfo.sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2;
|
||||
//fontId = gAudioContext.permanentCache[i].id;
|
||||
|
||||
if (!gUseLegacySD) {
|
||||
SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]);
|
||||
relocInfo.sampleBankId1 = sf->sampleBankId1;
|
||||
relocInfo.sampleBankId2 = sf->sampleBankId2;
|
||||
} else {
|
||||
relocInfo.sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1;
|
||||
relocInfo.sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2;
|
||||
}
|
||||
|
||||
if (relocInfo.sampleBankId1 != 0xFF) {
|
||||
relocInfo.sampleBankId1 = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, relocInfo.sampleBankId1);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "global.h"
|
||||
#include "Cvar.h"
|
||||
|
||||
extern bool gUseLegacySD;
|
||||
|
||||
void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) {
|
||||
f32 volRight, volLeft;
|
||||
s32 smallPanIndex;
|
||||
|
@ -284,7 +286,18 @@ void Audio_ProcessNotes(void) {
|
|||
}
|
||||
|
||||
subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale;
|
||||
subAttrs.frequency *= gAudioContext.audioBufferParameters.resampleRate;
|
||||
|
||||
f32 resampRate = gAudioContext.audioBufferParameters.resampleRate;
|
||||
|
||||
if (!gUseLegacySD && !noteSubEu2->bitField1.isSyntheticWave && noteSubEu2->sound.soundFontSound != NULL &&
|
||||
noteSubEu2->sound.soundFontSound->sample != NULL &&
|
||||
noteSubEu2->sound.soundFontSound->sample->sampleRateMagicValue == 'RIFF') {
|
||||
resampRate = CALC_RESAMPLE_FREQ(noteSubEu2->sound.soundFontSound->sample->sampleRate);
|
||||
}
|
||||
|
||||
subAttrs.frequency *= resampRate;
|
||||
|
||||
|
||||
subAttrs.velocity *= scale;
|
||||
Audio_InitNoteSub(note, noteSubEu2, &subAttrs);
|
||||
noteSubEu->bitField1.bookOffset = bookOffset;
|
||||
|
@ -307,7 +320,7 @@ SoundFontSound* Audio_InstrumentGetSound(Instrument* instrument, s32 semitone) {
|
|||
|
||||
Instrument* Audio_GetInstrumentInner(s32 fontId, s32 instId) {
|
||||
Instrument* inst;
|
||||
|
||||
|
||||
if (fontId == 0xFF) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -317,16 +330,31 @@ Instrument* Audio_GetInstrumentInner(s32 fontId, s32 instId) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (instId >= gAudioContext.soundFonts[fontId].numInstruments) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000;
|
||||
return NULL;
|
||||
int instCnt = 0;
|
||||
|
||||
if (gUseLegacySD) {
|
||||
instCnt = gAudioContext.soundFonts[fontId].numInstruments;
|
||||
inst = gAudioContext.soundFonts[fontId].instruments[instId];
|
||||
|
||||
if (instId >= gAudioContext.soundFonts[fontId].numInstruments)
|
||||
if (instId >= instCnt) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]);
|
||||
|
||||
if (instId >= sf->numInstruments)
|
||||
return NULL;
|
||||
|
||||
inst = sf->instruments[instId];
|
||||
}
|
||||
|
||||
inst = gAudioContext.soundFonts[fontId].instruments[instId];
|
||||
if (inst == NULL) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x1000000;
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
@ -343,12 +371,17 @@ Drum* Audio_GetDrum(s32 fontId, s32 drumId) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (drumId >= gAudioContext.soundFonts[fontId].numDrums) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000;
|
||||
return NULL;
|
||||
}
|
||||
if (gUseLegacySD) {
|
||||
if (drumId >= gAudioContext.soundFonts[fontId].numDrums) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drum = gAudioContext.soundFonts[fontId].drums[drumId];
|
||||
drum = gAudioContext.soundFonts[fontId].drums[drumId];
|
||||
} else {
|
||||
SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]);
|
||||
drum = sf->drums[drumId];
|
||||
}
|
||||
|
||||
if (drum == NULL) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x5000000;
|
||||
|
@ -369,12 +402,17 @@ SoundFontSound* Audio_GetSfx(s32 fontId, s32 sfxId) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (sfxId >= gAudioContext.soundFonts[fontId].numSfx) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000;
|
||||
return NULL;
|
||||
}
|
||||
if (gUseLegacySD) {
|
||||
if (sfxId >= gAudioContext.soundFonts[fontId].numSfx) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sfx = &gAudioContext.soundFonts[fontId].soundEffects[sfxId];
|
||||
sfx = &gAudioContext.soundFonts[fontId].soundEffects[sfxId];
|
||||
} else {
|
||||
SoundFont* sf = ResourceMgr_LoadAudioSoundFont(fontMap[fontId]);
|
||||
sfx = &sf->soundEffects[sfxId];
|
||||
}
|
||||
|
||||
if (sfx == NULL) {
|
||||
gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x5000000;
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
|
||||
extern bool gUseLegacySD;
|
||||
extern char* sequenceMap[256];
|
||||
|
||||
#define PORTAMENTO_IS_SPECIAL(x) ((x).mode & 0x80)
|
||||
#define PORTAMENTO_MODE(x) ((x).mode & ~0x80)
|
||||
#define PORTAMENTO_MODE_1 1
|
||||
|
@ -938,8 +941,16 @@ u8 AudioSeq_GetInstrument(SequenceChannel* channel, u8 instId, Instrument** inst
|
|||
*instOut = NULL;
|
||||
return 0;
|
||||
}
|
||||
adsr->envelope = inst->envelope;
|
||||
adsr->releaseRate = inst->releaseRate;
|
||||
|
||||
if (inst->envelope != NULL)
|
||||
{
|
||||
adsr->envelope = inst->envelope;
|
||||
adsr->releaseRate = (inst->releaseRate);
|
||||
}
|
||||
else {
|
||||
adsr->envelope = gDefaultEnvelope;
|
||||
}
|
||||
|
||||
*instOut = inst;
|
||||
instId += 2;
|
||||
return instId;
|
||||
|
@ -1052,9 +1063,15 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||
command = (u8)parameters[0];
|
||||
|
||||
if (seqPlayer->defaultFont != 0xFF) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
if (gUseLegacySD) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
}
|
||||
else {
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
||||
command = sDat.fonts[sDat.numFonts - result - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
||||
|
@ -1162,10 +1179,17 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||
result = (u8)parameters[0];
|
||||
command = (u8)parameters[0];
|
||||
|
||||
if (seqPlayer->defaultFont != 0xFF) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
if (seqPlayer->defaultFont != 0xFF)
|
||||
{
|
||||
if (gUseLegacySD) {
|
||||
offset = ((u16*)gAudioContext.sequenceFontTable)[seqPlayer->seqId];
|
||||
lowBits = gAudioContext.sequenceFontTable[offset];
|
||||
command = gAudioContext.sequenceFontTable[offset + lowBits - result];
|
||||
}
|
||||
else {
|
||||
SequenceData sDat = ResourceMgr_LoadSeqByName(sequenceMap[seqPlayer->seqId]);
|
||||
command = sDat.fonts[sDat.numFonts - result - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, command)) {
|
||||
|
@ -1322,14 +1346,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
|
|||
break;
|
||||
case 0xB2:
|
||||
offset = (u16)parameters[0];
|
||||
// OTRTODO: Byteswap added for quick audio
|
||||
channel->unk_22 = BOMSWAP16(*(u16*)(seqPlayer->seqData + (uintptr_t)(offset + scriptState->value * 2)));
|
||||
break;
|
||||
case 0xB4:
|
||||
channel->dynTable = (void*)&seqPlayer->seqData[channel->unk_22];
|
||||
break;
|
||||
case 0xB5:
|
||||
// OTRTODO: Byteswap added for quick audio
|
||||
channel->unk_22 = BOMSWAP16(((u16*)(channel->dynTable))[scriptState->value]);
|
||||
break;
|
||||
case 0xB6:
|
||||
|
|
|
@ -440,11 +440,11 @@ void func_800DBE64(void) {
|
|||
void func_800DBE6C(void) {
|
||||
}
|
||||
|
||||
void AudioSynth_LoadFilter(Acmd* cmd, s32 flags, s32 countOrBuf, s32 addr) {
|
||||
void AudioSynth_LoadFilter(Acmd* cmd, s32 flags, s32 countOrBuf, uintptr_t addr) {
|
||||
aFilter(cmd, flags, countOrBuf, addr);
|
||||
}
|
||||
|
||||
void AudioSynth_LoadFilterCount(Acmd* cmd, s32 count, s32 addr) {
|
||||
void AudioSynth_LoadFilterCount(Acmd* cmd, s32 count, uintptr_t addr) {
|
||||
aFilter(cmd, 2, count, addr);
|
||||
}
|
||||
|
||||
|
@ -561,6 +561,9 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
|
|||
NoteSubEu* noteSubEu2;
|
||||
s32 unk14;
|
||||
|
||||
//if (aiBufLen == 0)
|
||||
//return;
|
||||
|
||||
t = gAudioContext.numNotes * updateIndex;
|
||||
count = 0;
|
||||
if (gAudioContext.numSynthesisReverbs == 0) {
|
||||
|
@ -749,8 +752,10 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
cmd = AudioSynth_LoadWaveSamples(cmd, noteSubEu, synthState, nSamplesToLoad);
|
||||
noteSamplesDmemAddrBeforeResampling = DMEM_UNCOMPRESSED_NOTE + (synthState->samplePosInt * 2);
|
||||
synthState->samplePosInt += nSamplesToLoad;
|
||||
} else {
|
||||
} else
|
||||
{
|
||||
audioFontSample = noteSubEu->sound.soundFontSound->sample;
|
||||
|
||||
loopInfo = audioFontSample->loop;
|
||||
loopEndPos = loopInfo->end;
|
||||
sampleAddr = audioFontSample->sampleAddr;
|
||||
|
@ -822,6 +827,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
noteFinished = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (audioFontSample->codec) {
|
||||
case CODEC_ADPCM:
|
||||
|
@ -848,6 +854,9 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
goto skip;
|
||||
case CODEC_S16:
|
||||
AudioSynth_ClearBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, (samplesLenAdjusted * 2) + 0x20);
|
||||
AudioSynth_LoadBuffer(cmd++, DMEM_UNCOMPRESSED_NOTE, ALIGN16(nSamplesToLoad * 2),
|
||||
audioFontSample->sampleAddr + (synthState->samplePosInt * 2));
|
||||
|
||||
flags = A_CONTINUE;
|
||||
skipBytes = 0;
|
||||
nSamplesProcessed = samplesLenAdjusted;
|
||||
|
@ -860,7 +869,8 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
if (nFramesToDecode != 0) {
|
||||
frameIndex = (synthState->samplePosInt + skipInitialSamples - nFirstFrameSamplesToIgnore) / 16;
|
||||
sampleDataOffset = frameIndex * frameSize;
|
||||
if (audioFontSample->medium == MEDIUM_RAM) {
|
||||
if (audioFontSample->medium == MEDIUM_RAM)
|
||||
{
|
||||
sampleData = (u8*)(sampleDataStart + sampleDataOffset + sampleAddr);
|
||||
} else if (audioFontSample->medium == MEDIUM_UNK) {
|
||||
return cmd;
|
||||
|
@ -1024,7 +1034,8 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
|
|||
unk7 = noteSubEu->unk_07;
|
||||
unkE = noteSubEu->unk_0E;
|
||||
buf = &synthState->synthesisBuffers->panSamplesBuffer[0x18];
|
||||
if (unk7 != 0 && noteSubEu->unk_0E != 0) {
|
||||
if (unk7 != 0 && noteSubEu->unk_0E != 0)
|
||||
{
|
||||
AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_SCRATCH2, aiBufLen * 2);
|
||||
thing = DMEM_SCRATCH2 - unk7;
|
||||
if (synthState->unk_1A != 0) {
|
||||
|
|
|
@ -213,11 +213,7 @@ AudioTask* func_800E5000(void) {
|
|||
task = &gAudioContext.currTask->task.t;
|
||||
task->type = M_AUDTASK;
|
||||
task->flags = 0;
|
||||
//task->ucode_boot = D_801120C0;
|
||||
task->ucode_boot_size = 0x1000;
|
||||
//task->ucode_data_size = ((rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64)) - 1;
|
||||
//task->ucode = D_801120C0;
|
||||
//task->ucode_data = rspAspMainDataStart;
|
||||
task->ucode_size = 0x1000;
|
||||
task->dram_stack = NULL;
|
||||
task->dram_stack_size = 0;
|
||||
|
|
|
@ -363,7 +363,11 @@ void Audio_ProcessSeqCmd(u32 cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
void Audio_QueueSeqCmd(u32 cmd) {
|
||||
extern f32 D_80130F24;
|
||||
extern f32 D_80130F28;
|
||||
|
||||
void Audio_QueueSeqCmd(u32 cmd)
|
||||
{
|
||||
sAudioSeqCmds[sSeqCmdWrPos++] = cmd;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ s32 sShrinkWindowVal = 0;
|
|||
s32 sShrinkWindowCurrentVal = 0;
|
||||
|
||||
void ShrinkWindow_SetVal(s32 value) {
|
||||
if (CVar_GetS32("gDisableBlackBars", 0)) {
|
||||
sShrinkWindowVal = 0;
|
||||
return;
|
||||
}
|
||||
if (HREG(80) == 0x13 && HREG(81) == 1) {
|
||||
osSyncPrintf("shrink_window_setval(%d)\n", value);
|
||||
}
|
||||
|
@ -17,6 +21,10 @@ u32 ShrinkWindow_GetVal(void) {
|
|||
}
|
||||
|
||||
void ShrinkWindow_SetCurrentVal(s32 currentVal) {
|
||||
if (CVar_GetS32("gDisableBlackBars", 0)) {
|
||||
sShrinkWindowCurrentVal = 0;
|
||||
return;
|
||||
}
|
||||
if (HREG(80) == 0x13 && HREG(81) == 1) {
|
||||
osSyncPrintf("shrink_window_setnowval(%d)\n", currentVal);
|
||||
}
|
||||
|
|
|
@ -339,19 +339,19 @@ void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, Gl
|
|||
if (CVar_GetS32("gUseNaviCol",0) != 1 ) {
|
||||
if (actorCategory == ACTORCAT_PLAYER) {
|
||||
naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 255;
|
||||
naviColor->outer.r = 115; naviColor->outer.g = 230; naviColor->outer.b = 255;
|
||||
naviColor->outer.r = 0; naviColor->outer.g = 0; naviColor->outer.b = 255;
|
||||
}
|
||||
if (actorCategory == ACTORCAT_NPC) {
|
||||
naviColor->inner.r = 100; naviColor->inner.g = 100; naviColor->inner.b = 255;
|
||||
naviColor->outer.r = 90; naviColor->outer.g = 90; naviColor->outer.b = 255;
|
||||
naviColor->inner.r = 150; naviColor->inner.g = 150; naviColor->inner.b = 255;
|
||||
naviColor->outer.r = 150; naviColor->outer.g = 150; naviColor->outer.b = 255;
|
||||
}
|
||||
if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) {
|
||||
naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 0;
|
||||
naviColor->outer.r = 220; naviColor->outer.g = 220; naviColor->outer.b = 0;
|
||||
naviColor->outer.r = 220; naviColor->outer.g = 155; naviColor->outer.b = 0;
|
||||
}
|
||||
if (actorCategory == ACTORCAT_PROP) {
|
||||
naviColor->inner.r = 0; naviColor->inner.g = 255; naviColor->inner.b = 90;
|
||||
naviColor->outer.r = 0; naviColor->outer.g = 220; naviColor->outer.b = 0;
|
||||
naviColor->inner.r = 0; naviColor->inner.g = 255; naviColor->inner.b = 0;
|
||||
naviColor->outer.r = 0; naviColor->outer.g = 255; naviColor->outer.b = 0;
|
||||
}
|
||||
} else {
|
||||
if (actorCategory == ACTORCAT_PLAYER) {
|
||||
|
@ -1163,7 +1163,9 @@ void Actor_Init(Actor* actor, GlobalContext* globalCtx) {
|
|||
actor->uncullZoneForward = 1000.0f;
|
||||
actor->uncullZoneScale = 350.0f;
|
||||
actor->uncullZoneDownward = 700.0f;
|
||||
if (CVar_GetS32("gDisableDrawDistance", 0) != 0) {
|
||||
if (CVar_GetS32("gDisableDrawDistance", 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
|
||||
&& actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
|
||||
&& actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA) { // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
|
||||
actor->uncullZoneForward = 32767.0f;
|
||||
actor->uncullZoneScale = 32767.0f;
|
||||
actor->uncullZoneDownward = 32767.0f;
|
||||
|
@ -2690,7 +2692,9 @@ s32 func_800314B0(GlobalContext* globalCtx, Actor* actor) {
|
|||
s32 func_800314D4(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3) {
|
||||
f32 var;
|
||||
|
||||
if (CVar_GetS32("gDisableDrawDistance", 0) != 0) {
|
||||
if (CVar_GetS32("gDisableDrawDistance", 0) != 0 && actor->id != ACTOR_EN_TORCH2 && actor->id != ACTOR_EN_BLKOBJ // Extra check for Dark Link and his room
|
||||
&& actor->id != ACTOR_EN_HORSE // Check for Epona, else if we call her she will spawn at the other side of the map + we can hear her during the title screen sequence
|
||||
&& actor->id != ACTOR_EN_HORSE_GANON && actor->id != ACTOR_EN_HORSE_ZELDA) { // check for Zelda's and Ganondorf's horses that will always be scene during cinematic whith camera paning
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -7532,7 +7532,7 @@ Vec3s Camera_Update(Camera* camera) {
|
|||
BINANG_TO_DEGF(camera->camDir.x), camera->camDir.y, BINANG_TO_DEGF(camera->camDir.y));
|
||||
}
|
||||
|
||||
if (camera->timer != -1 && CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_DRIGHT)) {
|
||||
if (camera->timer != -1 && CHECK_BTN_ALL(D_8015BD7C->state.input[0].press.button, BTN_DRIGHT) && CVar_GetS32("gDebugCamera", 0)) {
|
||||
camera->timer = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,9 @@
|
|||
#include <string.h>
|
||||
|
||||
SaveContext gSaveContext;
|
||||
u32 D_8015FA88;
|
||||
u32 D_8015FA8C;
|
||||
|
||||
void SaveContext_Init(void) {
|
||||
memset(&gSaveContext, 0, sizeof(gSaveContext));
|
||||
D_8015FA88 = 0;
|
||||
D_8015FA8C = 0;
|
||||
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
|
||||
gSaveContext.natureAmbienceId = NATURE_ID_DISABLED;
|
||||
gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
|
||||
|
|
|
@ -896,6 +896,9 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
|
||||
if (this->unk_15A > 0) {
|
||||
this->unk_15A--;
|
||||
if (CVar_GetS32("gDropsDontDie", 0) && (this->unk_154 <= 0)) {
|
||||
this->unk_15A++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((this->unk_15A > 0) && (this->unk_15A < 41) && (this->unk_154 <= 0)) {
|
||||
|
|
|
@ -2093,9 +2093,14 @@ void func_80075B44(GlobalContext* globalCtx) {
|
|||
case 7:
|
||||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_1 << 4 | NATURE_CHANNEL_CRITTER_3,
|
||||
CHANNEL_IO_PORT_1, 0);
|
||||
if (globalCtx->envCtx.unk_EE[0] == 0 && globalCtx->envCtx.unk_F2[0] == 0) {
|
||||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5,
|
||||
CHANNEL_IO_PORT_1, 1);
|
||||
if (globalCtx->envCtx.unk_EE[0] == 0 && globalCtx->envCtx.unk_F2[0] == 0)
|
||||
{
|
||||
// OTRTODO: This is where corrupt audio happens. Commenting this out seems to not introduce any side effects?
|
||||
// Further investigation is needed...
|
||||
|
||||
if (gUseLegacySD)
|
||||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5,
|
||||
CHANNEL_IO_PORT_1, 1);
|
||||
}
|
||||
globalCtx->envCtx.unk_E0++;
|
||||
break;
|
||||
|
|
|
@ -755,22 +755,23 @@ void Minimap_Draw(GlobalContext* globalCtx) {
|
|||
if (((globalCtx->sceneNum != SCENE_SPOT01) && (globalCtx->sceneNum != SCENE_SPOT04) &&
|
||||
(globalCtx->sceneNum != SCENE_SPOT08)) ||
|
||||
(LINK_AGE_IN_YEARS != YEARS_ADULT)) {
|
||||
bool Map0 = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2 == 0;
|
||||
s16 IconSize = 8;
|
||||
s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex]+Right_MM_Margin;
|
||||
s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex]+Bottom_MM_Margin;
|
||||
s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex] + (Map0 ? 0 : Right_MM_Margin);
|
||||
s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex] + (Map0 ? 0 : Bottom_MM_Margin);
|
||||
//gFixDungeonMinimapIcon fix both Y position of visible icon and hide these non needed.
|
||||
if (CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){
|
||||
if (CVar_GetS32("gFixDungeonMinimapIcon", 0) != 0){
|
||||
//No idea why and how Original value work but this does actually fix them all.
|
||||
PosY = PosY+1024;
|
||||
}
|
||||
s16 TopLeftX = OTRGetRectDimensionFromRightEdge(PosX) << 2;
|
||||
s16 TopLeftX = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX) : OTRGetRectDimensionFromRightEdge(PosX)) << 2;
|
||||
s16 TopLeftY = PosY << 2;
|
||||
s16 TopLeftW = OTRGetRectDimensionFromRightEdge(PosX + IconSize) << 2;
|
||||
s16 TopLeftW = (Map0 ? OTRGetRectDimensionFromLeftEdge(PosX + IconSize) : OTRGetRectDimensionFromRightEdge(PosX + IconSize)) << 2;
|
||||
s16 TopLeftH = (PosY + IconSize) << 2;
|
||||
if ((gMapData->owEntranceFlag[sEntranceIconMapIndex] == 0xFFFF) ||
|
||||
((gMapData->owEntranceFlag[sEntranceIconMapIndex] != 0xFFFF) &&
|
||||
(gSaveContext.infTable[26] & gBitFlags[gMapData->owEntranceFlag[mapIndex]]))) {
|
||||
if (gMapData->owEntranceIconPosY[sEntranceIconMapIndex] << 2 != 0 && CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){
|
||||
if (!Map0 || !CVar_GetS32("gFixDungeonMinimapIcon", 0)) {
|
||||
gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b,
|
||||
IconSize, IconSize, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
|
||||
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
|
|
@ -2935,7 +2935,7 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
const s16 rCUpBtnX = OTRGetRectDimensionFromRightEdge(R_C_UP_BTN_X+Right_HUD_Margin);
|
||||
const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X+Right_HUD_Margin);
|
||||
const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X+Right_HUD_Margin-!!CVar_GetS32("gNaviTextFix", 0));
|
||||
if (CVar_GetS32("gHudColors", 1) == 0) {
|
||||
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), temp);
|
||||
} else if (CVar_GetS32("gHudColors", 1) == 1) {
|
||||
|
|
|
@ -240,7 +240,6 @@ void Gameplay_Init(GameState* thisx) {
|
|||
globalCtx->cameraPtrs[MAIN_CAM]->uid = 0;
|
||||
globalCtx->activeCamera = MAIN_CAM;
|
||||
func_8005AC48(&globalCtx->mainCamera, 0xFF);
|
||||
Sram_Init(globalCtx, &globalCtx->sramCtx);
|
||||
func_80112098(globalCtx);
|
||||
Message_Init(globalCtx);
|
||||
GameOver_Init(globalCtx);
|
||||
|
|
|
@ -360,7 +360,8 @@ s32 Player_ActionToModelGroup(Player* this, s32 actionParam) {
|
|||
void Player_SetModelsForHoldingShield(Player* this) {
|
||||
if ((this->stateFlags1 & 0x400000) &&
|
||||
((this->itemActionParam < 0) || (this->itemActionParam == this->heldItemActionParam))) {
|
||||
if (!Player_HoldsTwoHandedWeapon(this) && !Player_IsChildWithHylianShield(this)) {
|
||||
if ((CVar_GetS32("gShieldTwoHanded", 0) && (this->heldItemActionParam != PLAYER_AP_STICK) ||
|
||||
!Player_HoldsTwoHandedWeapon(this)) && !Player_IsChildWithHylianShield(this)) {
|
||||
this->rightHandType = 10;
|
||||
this->rightHandDLists = &sPlayerDListGroups[10][(void)0, gSaveContext.linkAge];
|
||||
if (this->sheathType == 18) {
|
||||
|
|
|
@ -3,242 +3,14 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
// these are the main substructs of save context.
|
||||
// we are going to hold off on splitting save context until later on,
|
||||
// so these temporary structs will live here for now.
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ char newf[6]; // string "ZELDAZ"
|
||||
/* 0x06 */ s16 deaths;
|
||||
/* 0x08 */ char playerName[8];
|
||||
/* 0x10 */ s16 n64ddFlag;
|
||||
/* 0x12 */ s16 healthCapacity; // "max_life"
|
||||
/* 0x14 */ s16 health; // "now_life"
|
||||
/* 0x16 */ s8 magicLevel;
|
||||
/* 0x17 */ s8 magic;
|
||||
/* 0x18 */ s16 rupees;
|
||||
/* 0x1A */ u16 swordHealth;
|
||||
/* 0x1C */ u16 naviTimer;
|
||||
/* 0x1E */ u8 magicAcquired;
|
||||
/* 0x1F */ u8 unk_1F;
|
||||
/* 0x20 */ u8 doubleMagic;
|
||||
/* 0x21 */ u8 doubleDefense;
|
||||
/* 0x22 */ u8 bgsFlag;
|
||||
/* 0x23 */ u8 ocarinaGameRoundNum;
|
||||
/* 0x24 */ ItemEquips childEquips;
|
||||
/* 0x2E */ ItemEquips adultEquips;
|
||||
/* 0x38 */ u32 unk_38; // this may be incorrect, currently used for alignement
|
||||
/* 0x3C */ char unk_3C[0x0E];
|
||||
/* 0x4A */ s16 savedSceneNum;
|
||||
} SavePlayerData; // size = 0x4C
|
||||
|
||||
typedef struct {
|
||||
/* 0x0000 */ SavePlayerData playerData; // "S_Private" substruct name
|
||||
/* 0x004C */ ItemEquips equips;
|
||||
/* 0x0058 */ Inventory inventory;
|
||||
/* 0x00B8 */ SavedSceneFlags sceneFlags[124];
|
||||
/* 0x0E48 */ FaroresWindData fw;
|
||||
/* 0x0E70 */ char unk_E70[0x10];
|
||||
/* 0x0E80 */ s32 gsFlags[6];
|
||||
/* 0x0E98 */ char unk_E98[0x10];
|
||||
/* 0x0EA8 */ s32 horseRaceRecord;
|
||||
/* 0x0EAC */ char unk_EAC[0x0C];
|
||||
/* 0x0EB8 */ u16 eventChkInf[14]; // "event_chk_inf"
|
||||
/* 0x0ED4 */ u16 itemGetInf[4]; // "item_get_inf"
|
||||
/* 0x0EDC */ u16 infTable[30]; // "inf_table"
|
||||
/* 0x0F18 */ char unk_F18[0x04];
|
||||
/* 0x0F1C */ u32 worldMapAreaData; // "area_arrival"
|
||||
/* 0x0F20 */ char unk_F20[0x4];
|
||||
/* 0x0F24 */ u8 scarecrowCustomSongSet;
|
||||
/* 0x0F25 */ u8 scarecrowCustomSong[0x360];
|
||||
/* 0x1285 */ char unk_1285[0x24];
|
||||
/* 0x12A9 */ u8 scarecrowSpawnSongSet;
|
||||
/* 0x12AA */ u8 scarecrowSpawnSong[0x80];
|
||||
/* 0x132A */ char unk_132A[0x02];
|
||||
/* 0x132C */ HorseData horseData;
|
||||
/* 0x1336 */ u16 checksum; // "check_sum"
|
||||
} SaveInfo; // size = 0x1338
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ s32 entranceIndex;
|
||||
/* 0x04 */ s32 linkAge; // 0: Adult; 1: Child
|
||||
/* 0x08 */ s32 cutsceneIndex;
|
||||
/* 0x0C */ u16 dayTime; // "zelda_time"
|
||||
/* 0x10 */ s32 nightFlag;
|
||||
/* 0x14 */ s32 totalDays;
|
||||
/* 0x18 */ s32 unk_18; // increments with totalDays, gets reset by goron for bgs and one other use
|
||||
/* 0x1C */ SaveInfo info; // "information"
|
||||
} Save; // size = 0x1354
|
||||
|
||||
#define SAVE_PLAYER_DATA (*((SavePlayerData*)&gSaveContext.newf))
|
||||
#define SAVE_INFO (*((SaveInfo*)&gSaveContext.newf))
|
||||
|
||||
#define SLOT_SIZE (sizeof(SaveContext) + 0x28)
|
||||
#define CHECKSUM_SIZE (sizeof(Save) / 2)
|
||||
|
||||
#define DEATHS OFFSETOF(SaveContext, deaths)
|
||||
#define NAME OFFSETOF(SaveContext, playerName)
|
||||
#define N64DD OFFSETOF(SaveContext, n64ddFlag)
|
||||
#define HEALTH_CAP OFFSETOF(SaveContext, healthCapacity)
|
||||
#define QUEST OFFSETOF(SaveContext, inventory.questItems)
|
||||
#define DEFENSE OFFSETOF(SaveContext, inventory.defenseHearts)
|
||||
#define HEALTH OFFSETOF(SaveContext, health)
|
||||
|
||||
#define SLOT_OFFSET(index) (SRAM_HEADER_SIZE + 0x10 + (index * SLOT_SIZE))
|
||||
|
||||
u16 gSramSlotOffsets[] = {
|
||||
SLOT_OFFSET(0),
|
||||
SLOT_OFFSET(1),
|
||||
SLOT_OFFSET(2),
|
||||
// the latter three saves are backup saves for the former saves
|
||||
SLOT_OFFSET(3),
|
||||
SLOT_OFFSET(4),
|
||||
SLOT_OFFSET(5),
|
||||
};
|
||||
|
||||
static u8 sZeldaMagic[] = { '\0', '\0', '\0', '\x98', '\x09', '\x10', '\x21', 'Z', 'E', 'L', 'D', 'A' };
|
||||
|
||||
static SavePlayerData sNewSavePlayerData = {
|
||||
{ '\0', '\0', '\0', '\0', '\0', '\0' }, // newf
|
||||
0, // deaths
|
||||
{ 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName
|
||||
0, // n64ddFlag
|
||||
0x30, // healthCapacity
|
||||
0x30, // defense
|
||||
0, // magicLevel
|
||||
0x30, // magic
|
||||
0, // rupees
|
||||
0, // swordHealth
|
||||
0, // naviTimer
|
||||
0, // magicAcquired
|
||||
0, // unk_1F
|
||||
0, // doubleMagic
|
||||
0, // doubleDefense
|
||||
0, // bgsFlag
|
||||
0, // ocarinaGameRoundNum
|
||||
{
|
||||
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
|
||||
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
|
||||
0, // equipment
|
||||
}, // childEquips
|
||||
{
|
||||
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
|
||||
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
|
||||
0, // equipment
|
||||
}, // adultEquips
|
||||
0, // unk_38
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C
|
||||
0x34, // savedSceneNum
|
||||
};
|
||||
|
||||
static ItemEquips sNewSaveEquips = {
|
||||
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
|
||||
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
|
||||
0x1100, // equipment
|
||||
};
|
||||
|
||||
static Inventory sNewSaveInventory = {
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, // items
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ammo
|
||||
0x1100, // equipment
|
||||
0, // upgrades
|
||||
0, // questItems
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems
|
||||
{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
}, // dungeonKeys
|
||||
0, // defenseHearts
|
||||
0, // gsTokens
|
||||
};
|
||||
|
||||
static u16 sNewSaveChecksum = 0;
|
||||
|
||||
/**
|
||||
* Initialize new save.
|
||||
* This save has an empty inventory with 3 hearts and single magic.
|
||||
*/
|
||||
void Sram_InitNewSave(void) {
|
||||
SaveContext* temp = &gSaveContext;
|
||||
|
||||
memset(&SAVE_INFO, 0, sizeof(SaveInfo));
|
||||
gSaveContext.totalDays = 0;
|
||||
gSaveContext.bgsDayCount = 0;
|
||||
|
||||
SAVE_PLAYER_DATA = sNewSavePlayerData;
|
||||
gSaveContext.equips = sNewSaveEquips;
|
||||
gSaveContext.inventory = sNewSaveInventory;
|
||||
|
||||
temp->checksum = sNewSaveChecksum;
|
||||
gSaveContext.horseData.scene = SCENE_SPOT00;
|
||||
gSaveContext.horseData.pos.x = -1840;
|
||||
gSaveContext.horseData.pos.y = 72;
|
||||
gSaveContext.horseData.pos.z = 5497;
|
||||
gSaveContext.horseData.angle = -0x6AD9;
|
||||
gSaveContext.magicLevel = 0;
|
||||
gSaveContext.infTable[29] = 1;
|
||||
gSaveContext.sceneFlags[5].swch = 0x40000000;
|
||||
Save_InitFile(false);
|
||||
}
|
||||
|
||||
static SavePlayerData sDebugSavePlayerData = {
|
||||
{ 'Z', 'E', 'L', 'D', 'A', 'Z' }, // newf
|
||||
0, // deaths
|
||||
{ 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName ( "LINK" )
|
||||
0, // n64ddFlag
|
||||
0xE0, // healthCapacity
|
||||
0xE0, // health
|
||||
0, // magicLevel
|
||||
0x30, // magic
|
||||
150, // rupees
|
||||
8, // swordHealth
|
||||
0, // naviTimer
|
||||
1, // magicAcquired
|
||||
0, // unk_1F
|
||||
0, // doubleMagic
|
||||
0, // doubleDefense
|
||||
0, // bgsFlag
|
||||
0, // ocarinaGameRoundNum
|
||||
{
|
||||
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
|
||||
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
|
||||
0, // equipment
|
||||
}, // childEquips
|
||||
{
|
||||
{ ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }, // buttonItems
|
||||
{ SLOT_NONE, SLOT_NONE, SLOT_NONE }, // cButtonSlots
|
||||
0, // equipment
|
||||
}, // adultEquips
|
||||
0, // unk_38
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // unk_3C
|
||||
0x51, // savedSceneNum
|
||||
};
|
||||
|
||||
static ItemEquips sDebugSaveEquips = {
|
||||
{ ITEM_SWORD_MASTER, ITEM_BOW, ITEM_BOMB, ITEM_OCARINA_FAIRY }, // buttonItems
|
||||
{ SLOT_BOW, SLOT_BOMB, SLOT_OCARINA }, // cButtonSlots
|
||||
0x1122, // equipment
|
||||
};
|
||||
|
||||
static Inventory sDebugSaveInventory = {
|
||||
{
|
||||
ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_BOW, ITEM_ARROW_FIRE, ITEM_DINS_FIRE,
|
||||
ITEM_SLINGSHOT, ITEM_OCARINA_FAIRY, ITEM_BOMBCHU, ITEM_HOOKSHOT, ITEM_ARROW_ICE, ITEM_FARORES_WIND,
|
||||
ITEM_BOOMERANG, ITEM_LENS, ITEM_BEAN, ITEM_HAMMER, ITEM_ARROW_LIGHT, ITEM_NAYRUS_LOVE,
|
||||
ITEM_BOTTLE, ITEM_POTION_RED, ITEM_POTION_GREEN, ITEM_POTION_BLUE, ITEM_POCKET_EGG, ITEM_WEIRD_EGG,
|
||||
}, // items
|
||||
{ 50, 50, 10, 30, 1, 1, 30, 1, 50, 1, 1, 1, 1, 1, 1, 1 }, // ammo
|
||||
0x7777, // equipment
|
||||
0x125249, // upgrades
|
||||
0x1E3FFFF, // questItems
|
||||
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // dungeonItems
|
||||
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, // dungeonKeys
|
||||
0, // defenseHearts
|
||||
0, // gsTokens
|
||||
};
|
||||
|
||||
static u16 sDebugSaveChecksum = 0;
|
||||
|
||||
/**
|
||||
* Initialize debug save. This is also used on the Title Screen
|
||||
* This save has a mostly full inventory with 10 hearts and single magic.
|
||||
|
@ -249,40 +21,7 @@ static u16 sDebugSaveChecksum = 0;
|
|||
* and set water level in Water Temple to lowest level.
|
||||
*/
|
||||
void Sram_InitDebugSave(void) {
|
||||
SaveContext* temp = &gSaveContext;
|
||||
|
||||
memset(&SAVE_INFO, 0, sizeof(SaveInfo));
|
||||
gSaveContext.totalDays = 0;
|
||||
gSaveContext.bgsDayCount = 0;
|
||||
|
||||
SAVE_PLAYER_DATA = sDebugSavePlayerData;
|
||||
gSaveContext.equips = sDebugSaveEquips;
|
||||
gSaveContext.inventory = sDebugSaveInventory;
|
||||
|
||||
temp->checksum = sDebugSaveChecksum;
|
||||
gSaveContext.horseData.scene = SCENE_SPOT00;
|
||||
gSaveContext.horseData.pos.x = -1840;
|
||||
gSaveContext.horseData.pos.y = 72;
|
||||
gSaveContext.horseData.pos.z = 5497;
|
||||
gSaveContext.horseData.angle = -0x6AD9;
|
||||
gSaveContext.infTable[0] |= 0x5009;
|
||||
gSaveContext.eventChkInf[0] |= 0x123F;
|
||||
gSaveContext.eventChkInf[8] |= 1;
|
||||
gSaveContext.eventChkInf[12] |= 0x10;
|
||||
|
||||
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI;
|
||||
Inventory_ChangeEquipment(EQUIP_SWORD, 1);
|
||||
if (gSaveContext.fileNum == 0xFF) {
|
||||
gSaveContext.equips.buttonItems[1] = ITEM_SLINGSHOT;
|
||||
gSaveContext.equips.cButtonSlots[0] = SLOT_SLINGSHOT;
|
||||
Inventory_ChangeEquipment(EQUIP_SHIELD, 1);
|
||||
}
|
||||
}
|
||||
|
||||
gSaveContext.entranceIndex = 0xCD;
|
||||
gSaveContext.magicLevel = 0;
|
||||
gSaveContext.sceneFlags[5].swch = 0x40000000;
|
||||
Save_InitFile(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -295,7 +34,7 @@ void Sram_InitDebugSave(void) {
|
|||
* - Give and equip master sword if player is adult and doesnt have kokiri sword (bug?)
|
||||
* - Revert any trade items that spoil
|
||||
*/
|
||||
void Sram_OpenSave(SramContext* sramCtx) {
|
||||
void Sram_OpenSave() {
|
||||
static s16 dungeonEntrances[] = {
|
||||
0x0000, 0x0004, 0x0028, 0x0169, 0x0165, 0x0010, 0x0082, 0x0037,
|
||||
0x0098, 0x0088, 0x041B, 0x0008, 0x0486, 0x0467, 0x0179, 0x056C,
|
||||
|
@ -304,15 +43,7 @@ void Sram_OpenSave(SramContext* sramCtx) {
|
|||
u16 j;
|
||||
u8* ptr;
|
||||
|
||||
osSyncPrintf("個人File作成\n"); // "Create personal file"
|
||||
i = gSramSlotOffsets[gSaveContext.fileNum];
|
||||
osSyncPrintf("ぽいんと=%x(%d)\n", i, gSaveContext.fileNum); // "Point="
|
||||
|
||||
memcpy(&gSaveContext, sramCtx->readBuff + i, sizeof(Save));
|
||||
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
osSyncPrintf("SCENE_DATA_ID = %d SceneNo = %d\n", gSaveContext.savedSceneNum,
|
||||
((void)0, gSaveContext.entranceIndex));
|
||||
Save_LoadFile();
|
||||
|
||||
switch (gSaveContext.savedSceneNum) {
|
||||
case SCENE_YDAN:
|
||||
|
@ -446,232 +177,7 @@ void Sram_OpenSave(SramContext* sramCtx) {
|
|||
gSaveContext.magicLevel = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents of the Save Context to a main and backup slot in SRAM.
|
||||
* Note: The whole Save Context is written even though only the `save` substruct is read back later
|
||||
*/
|
||||
void Sram_WriteSave(SramContext* sramCtx) {
|
||||
u16 offset;
|
||||
u16 checksum;
|
||||
u16 j;
|
||||
u16* ptr;
|
||||
|
||||
gSaveContext.checksum = 0;
|
||||
|
||||
ptr = (u16*)&gSaveContext;
|
||||
checksum = 0;
|
||||
j = 0;
|
||||
|
||||
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
|
||||
if (++j == 0x20) {
|
||||
j = 0;
|
||||
}
|
||||
checksum += *ptr++;
|
||||
}
|
||||
|
||||
gSaveContext.checksum = checksum;
|
||||
|
||||
ptr = (u16*)&gSaveContext;
|
||||
checksum = 0;
|
||||
|
||||
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
|
||||
if (++j == 0x20) {
|
||||
j = 0;
|
||||
}
|
||||
checksum += *ptr++;
|
||||
}
|
||||
|
||||
offset = gSramSlotOffsets[gSaveContext.fileNum];
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
|
||||
|
||||
ptr = (u16*)&gSaveContext;
|
||||
checksum = 0;
|
||||
|
||||
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
|
||||
if (++j == 0x20) {
|
||||
j = 0;
|
||||
}
|
||||
checksum += *ptr++;
|
||||
}
|
||||
|
||||
offset = gSramSlotOffsets[gSaveContext.fileNum + 3];
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* For all 3 slots, verify that the checksum is correct. If corrupted, attempt to load a backup save.
|
||||
* If backup is also corrupted, default to a new save (or debug save for slot 0 on debug rom).
|
||||
*
|
||||
* After verifying all 3 saves, pass relevant data to File Select to be displayed.
|
||||
*/
|
||||
void Sram_VerifyAndLoadAllSaves(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
|
||||
u16 i;
|
||||
u16 newChecksum;
|
||||
u16 slotNum;
|
||||
u16 offset;
|
||||
u16 j;
|
||||
u16 oldChecksum;
|
||||
u16* ptr;
|
||||
u16 dayTime;
|
||||
|
||||
osSyncPrintf("SRAM START─LOAD\n");
|
||||
memset(sramCtx->readBuff,0, SRAM_SIZE);
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
|
||||
|
||||
dayTime = ((void)0, gSaveContext.dayTime);
|
||||
|
||||
for (slotNum = 0; slotNum < 3; slotNum++) {
|
||||
offset = gSramSlotOffsets[slotNum];
|
||||
osSyncPrintf("ぽいんと=%x(%d) SAVE_MAX=%d\n", offset, gSaveContext.fileNum, sizeof(Save));
|
||||
memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save));
|
||||
|
||||
oldChecksum = gSaveContext.checksum;
|
||||
gSaveContext.checksum = 0;
|
||||
ptr = (u16*)&gSaveContext;
|
||||
osSyncPrintf("\n============= S(%d) =============\n", slotNum);
|
||||
|
||||
for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++, offset += 2) {
|
||||
newChecksum += *ptr++;
|
||||
}
|
||||
|
||||
// "SAVE checksum calculation"
|
||||
osSyncPrintf("\nSAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum);
|
||||
|
||||
if (newChecksum != oldChecksum) {
|
||||
// checksum didnt match, try backup save
|
||||
osSyncPrintf("ERROR!!! = %x(%d)\n", gSramSlotOffsets[slotNum], slotNum);
|
||||
offset = gSramSlotOffsets[slotNum + 3];
|
||||
memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save));
|
||||
|
||||
oldChecksum = gSaveContext.checksum;
|
||||
gSaveContext.checksum = 0;
|
||||
ptr = (u16*)&gSaveContext;
|
||||
osSyncPrintf("================= BACK─UP ========================\n");
|
||||
|
||||
for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++, offset += 2) {
|
||||
newChecksum += *ptr++;
|
||||
}
|
||||
// "(B) SAVE checksum calculation"
|
||||
osSyncPrintf("\n(B)SAVEチェックサム計算 j=%x mmm=%x ", newChecksum, oldChecksum);
|
||||
|
||||
if (newChecksum != oldChecksum) {
|
||||
// backup save didnt work, make new save
|
||||
osSyncPrintf("ERROR!!! = %x(%d+3)\n", gSramSlotOffsets[slotNum + 3], slotNum);
|
||||
memset(&gSaveContext.entranceIndex, 0, sizeof(s32));
|
||||
memset(&gSaveContext.linkAge, 0, sizeof(s32));
|
||||
memset(&gSaveContext.cutsceneIndex, 0, sizeof(s32));
|
||||
// note that gSaveContext.dayTime is not actually the sizeof(s32)
|
||||
memset(&gSaveContext.dayTime, 0, sizeof(s32));
|
||||
memset(&gSaveContext.nightFlag, 0, sizeof(s32));
|
||||
memset(&gSaveContext.totalDays, 0, sizeof(s32));
|
||||
memset(&gSaveContext.bgsDayCount, 0, sizeof(s32));
|
||||
|
||||
if (!slotNum && CVar_GetS32("gDebugEnabled", 0)) {
|
||||
Sram_InitDebugSave();
|
||||
gSaveContext.newf[0] = 'Z';
|
||||
gSaveContext.newf[1] = 'E';
|
||||
gSaveContext.newf[2] = 'L';
|
||||
gSaveContext.newf[3] = 'D';
|
||||
gSaveContext.newf[4] = 'A';
|
||||
gSaveContext.newf[5] = 'Z';
|
||||
osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1],
|
||||
gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4],
|
||||
gSaveContext.newf[5]);
|
||||
} else {
|
||||
Sram_InitNewSave();
|
||||
}
|
||||
|
||||
ptr = (u16*)&gSaveContext;
|
||||
osSyncPrintf("\n--------------------------------------------------------------\n");
|
||||
|
||||
for (i = newChecksum = j = 0; i < CHECKSUM_SIZE; i++) {
|
||||
osSyncPrintf("%x ", *ptr);
|
||||
if (++j == 0x20) {
|
||||
osSyncPrintf("\n");
|
||||
j = 0;
|
||||
}
|
||||
newChecksum += *ptr++;
|
||||
}
|
||||
|
||||
gSaveContext.checksum = newChecksum;
|
||||
osSyncPrintf("\nCheck_Sum=%x(%x)\n", gSaveContext.checksum, newChecksum);
|
||||
|
||||
i = gSramSlotOffsets[slotNum + 3];
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + i, &gSaveContext, SLOT_SIZE, OS_WRITE);
|
||||
|
||||
osSyncPrintf("????#%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1],
|
||||
gSaveContext.newf[2], gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]);
|
||||
osSyncPrintf("\nぽいんと=%x(%d+3) check_sum=%x(%x)\n", i, slotNum, gSaveContext.checksum,
|
||||
newChecksum);
|
||||
}
|
||||
|
||||
i = gSramSlotOffsets[slotNum];
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + i, &gSaveContext, SLOT_SIZE, OS_WRITE);
|
||||
|
||||
osSyncPrintf("ぽいんと=%x(%d) check_sum=%x(%x)\n", i, slotNum, gSaveContext.checksum, newChecksum);
|
||||
} else {
|
||||
osSyncPrintf("\nSAVEデータ OK!!!!\n"); // "SAVE data OK! ! ! !"
|
||||
}
|
||||
}
|
||||
|
||||
memset(sramCtx->readBuff,0, SRAM_SIZE);
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
|
||||
gSaveContext.dayTime = dayTime;
|
||||
|
||||
osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, 64DD=%x, HEART=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD,
|
||||
DEFENSE);
|
||||
|
||||
memcpy(&fileChooseCtx->deaths[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEATHS, sizeof(fileChooseCtx->deaths[0]));
|
||||
memcpy(&fileChooseCtx->deaths[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEATHS, sizeof(fileChooseCtx->deaths[0]));
|
||||
memcpy(&fileChooseCtx->deaths[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEATHS, sizeof(fileChooseCtx->deaths[0]));
|
||||
|
||||
memcpy(&fileChooseCtx->fileNames[0], sramCtx->readBuff + SLOT_OFFSET(0) + NAME,
|
||||
sizeof(fileChooseCtx->fileNames[0]));
|
||||
memcpy(&fileChooseCtx->fileNames[1], sramCtx->readBuff + SLOT_OFFSET(1) + NAME,
|
||||
sizeof(fileChooseCtx->fileNames[0]));
|
||||
memcpy(&fileChooseCtx->fileNames[2], sramCtx->readBuff + SLOT_OFFSET(2) + NAME,
|
||||
sizeof(fileChooseCtx->fileNames[0]));
|
||||
|
||||
memcpy(&fileChooseCtx->healthCapacities[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH_CAP,
|
||||
sizeof(fileChooseCtx->healthCapacities[0]));
|
||||
memcpy(&fileChooseCtx->healthCapacities[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH_CAP,
|
||||
sizeof(fileChooseCtx->healthCapacities[0]));
|
||||
memcpy(&fileChooseCtx->healthCapacities[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH_CAP,
|
||||
sizeof(fileChooseCtx->healthCapacities[0]));
|
||||
|
||||
memcpy(&fileChooseCtx->questItems[0], sramCtx->readBuff + SLOT_OFFSET(0) + QUEST,
|
||||
sizeof(fileChooseCtx->questItems[0]));
|
||||
memcpy(&fileChooseCtx->questItems[1], sramCtx->readBuff + SLOT_OFFSET(1) + QUEST,
|
||||
sizeof(fileChooseCtx->questItems[0]));
|
||||
memcpy(&fileChooseCtx->questItems[2], sramCtx->readBuff + SLOT_OFFSET(2) + QUEST,
|
||||
sizeof(fileChooseCtx->questItems[0]));
|
||||
|
||||
memcpy(&fileChooseCtx->n64ddFlags[0], sramCtx->readBuff + SLOT_OFFSET(0) + N64DD,
|
||||
sizeof(fileChooseCtx->n64ddFlags[0]));
|
||||
memcpy(&fileChooseCtx->n64ddFlags[1], sramCtx->readBuff + SLOT_OFFSET(1) + N64DD,
|
||||
sizeof(fileChooseCtx->n64ddFlags[0]));
|
||||
memcpy(&fileChooseCtx->n64ddFlags[2], sramCtx->readBuff + SLOT_OFFSET(2) + N64DD,
|
||||
sizeof(fileChooseCtx->n64ddFlags[0]));
|
||||
|
||||
memcpy(&fileChooseCtx->defense[0], sramCtx->readBuff + SLOT_OFFSET(0) + DEFENSE,
|
||||
sizeof(fileChooseCtx->defense[0]));
|
||||
memcpy(&fileChooseCtx->defense[1], sramCtx->readBuff + SLOT_OFFSET(1) + DEFENSE,
|
||||
sizeof(fileChooseCtx->defense[0]));
|
||||
memcpy(&fileChooseCtx->defense[2], sramCtx->readBuff + SLOT_OFFSET(2) + DEFENSE,
|
||||
sizeof(fileChooseCtx->defense[0]));
|
||||
|
||||
memcpy(&fileChooseCtx->health[0], sramCtx->readBuff + SLOT_OFFSET(0) + HEALTH, sizeof(fileChooseCtx->health[0]));
|
||||
memcpy(&fileChooseCtx->health[1], sramCtx->readBuff + SLOT_OFFSET(1) + HEALTH, sizeof(fileChooseCtx->health[0]));
|
||||
memcpy(&fileChooseCtx->health[2], sramCtx->readBuff + SLOT_OFFSET(2) + HEALTH, sizeof(fileChooseCtx->health[0]));
|
||||
|
||||
osSyncPrintf("f_64dd=%d, %d, %d\n", fileChooseCtx->n64ddFlags[0], fileChooseCtx->n64ddFlags[1],
|
||||
fileChooseCtx->n64ddFlags[2]);
|
||||
osSyncPrintf("heart_status=%d, %d, %d\n", fileChooseCtx->defense[0], fileChooseCtx->defense[1],
|
||||
fileChooseCtx->defense[2]);
|
||||
osSyncPrintf("now_life=%d, %d, %d\n", fileChooseCtx->health[0], fileChooseCtx->health[1], fileChooseCtx->health[2]);
|
||||
}
|
||||
|
||||
void Sram_InitSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
|
||||
void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
u16 offset;
|
||||
u16 j;
|
||||
u16* ptr;
|
||||
|
@ -693,189 +199,14 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
|
|||
}
|
||||
|
||||
for (offset = 0; offset < 8; offset++) {
|
||||
gSaveContext.playerName[offset] = fileChooseCtx->fileNames[fileChooseCtx->buttonIndex][offset];
|
||||
gSaveContext.playerName[offset] = Save_GetSaveMetaInfo(fileChooseCtx->buttonIndex)->playerName[offset];
|
||||
}
|
||||
|
||||
gSaveContext.newf[0] = 'Z';
|
||||
gSaveContext.newf[1] = 'E';
|
||||
gSaveContext.newf[2] = 'L';
|
||||
gSaveContext.newf[3] = 'D';
|
||||
gSaveContext.newf[4] = 'A';
|
||||
gSaveContext.newf[5] = 'Z';
|
||||
|
||||
gSaveContext.n64ddFlag = fileChooseCtx->n64ddFlag;
|
||||
osSyncPrintf("64DDフラグ=%d\n", fileChooseCtx->n64ddFlag);
|
||||
osSyncPrintf("newf=%x,%x,%x,%x,%x,%x\n", gSaveContext.newf[0], gSaveContext.newf[1], gSaveContext.newf[2],
|
||||
gSaveContext.newf[3], gSaveContext.newf[4], gSaveContext.newf[5]);
|
||||
osSyncPrintf("\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
|
||||
|
||||
ptr = (u16*)&gSaveContext;
|
||||
j = 0;
|
||||
checksum = 0;
|
||||
|
||||
for (offset = 0; offset < CHECKSUM_SIZE; offset++) {
|
||||
osSyncPrintf("%x ", *ptr);
|
||||
checksum += *ptr++;
|
||||
if (++j == 0x20) {
|
||||
osSyncPrintf("\n");
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gSaveContext.checksum = checksum;
|
||||
osSyncPrintf("\nチェックサム=%x\n", gSaveContext.checksum); // "Checksum = %x"
|
||||
|
||||
offset = gSramSlotOffsets[gSaveContext.fileNum];
|
||||
osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum);
|
||||
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
|
||||
|
||||
offset = gSramSlotOffsets[gSaveContext.fileNum + 3];
|
||||
osSyncPrintf("I=%x no=%d\n", offset, gSaveContext.fileNum + 3);
|
||||
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE);
|
||||
|
||||
osSyncPrintf("SAVE終了\n"); // "SAVE end"
|
||||
osSyncPrintf("z_common_data.file_no = %d\n", gSaveContext.fileNum);
|
||||
osSyncPrintf("SAVECT=%x, NAME=%x, LIFE=%x, ITEM=%x, SAVE_64DD=%x\n", DEATHS, NAME, HEALTH_CAP, QUEST, N64DD);
|
||||
|
||||
j = gSramSlotOffsets[gSaveContext.fileNum];
|
||||
|
||||
memcpy(&fileChooseCtx->deaths[gSaveContext.fileNum], sramCtx->readBuff + j + DEATHS,
|
||||
sizeof(fileChooseCtx->deaths[0]));
|
||||
memcpy(&fileChooseCtx->fileNames[gSaveContext.fileNum], sramCtx->readBuff + j + NAME,
|
||||
sizeof(fileChooseCtx->fileNames[0]));
|
||||
memcpy(&fileChooseCtx->healthCapacities[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH_CAP,
|
||||
sizeof(fileChooseCtx->healthCapacities[0]));
|
||||
memcpy(&fileChooseCtx->questItems[gSaveContext.fileNum], sramCtx->readBuff + j + QUEST,
|
||||
sizeof(fileChooseCtx->questItems[0]));
|
||||
memcpy(&fileChooseCtx->n64ddFlags[gSaveContext.fileNum], sramCtx->readBuff + j + N64DD,
|
||||
sizeof(fileChooseCtx->n64ddFlags[0]));
|
||||
memcpy(&fileChooseCtx->defense[gSaveContext.fileNum], sramCtx->readBuff + j + DEFENSE,
|
||||
sizeof(fileChooseCtx->defense[0]));
|
||||
memcpy(&fileChooseCtx->health[gSaveContext.fileNum], sramCtx->readBuff + j + HEALTH,
|
||||
sizeof(fileChooseCtx->health[0]));
|
||||
|
||||
osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]);
|
||||
osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->defense[gSaveContext.fileNum]);
|
||||
osSyncPrintf("now_life[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->health[gSaveContext.fileNum]);
|
||||
Save_SaveFile();
|
||||
}
|
||||
|
||||
void Sram_EraseSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
|
||||
s32 offset;
|
||||
void Sram_InitSram(GameState* gameState) {
|
||||
Save_Init();
|
||||
|
||||
Sram_InitNewSave();
|
||||
|
||||
offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex];
|
||||
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
|
||||
|
||||
memcpy(&fileChooseCtx->n64ddFlags[fileChooseCtx->selectedFileIndex], sramCtx->readBuff + offset + N64DD,
|
||||
sizeof(fileChooseCtx->n64ddFlags[0]));
|
||||
|
||||
offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex + 3];
|
||||
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000) + offset, &gSaveContext, SLOT_SIZE, OS_WRITE);
|
||||
|
||||
osSyncPrintf("CLEAR終了\n");
|
||||
}
|
||||
|
||||
void Sram_CopySave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) {
|
||||
s32 offset;
|
||||
|
||||
osSyncPrintf("READ=%d(%x) COPY=%d(%x)\n", fileChooseCtx->selectedFileIndex,
|
||||
gSramSlotOffsets[fileChooseCtx->selectedFileIndex], fileChooseCtx->copyDestFileIndex,
|
||||
gSramSlotOffsets[fileChooseCtx->copyDestFileIndex]);
|
||||
|
||||
offset = gSramSlotOffsets[fileChooseCtx->selectedFileIndex];
|
||||
memcpy(&gSaveContext, sramCtx->readBuff + offset, sizeof(Save));
|
||||
|
||||
offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex];
|
||||
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
|
||||
|
||||
offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex + 3];
|
||||
memcpy(sramCtx->readBuff + offset, &gSaveContext, sizeof(Save));
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE);
|
||||
|
||||
offset = gSramSlotOffsets[fileChooseCtx->copyDestFileIndex];
|
||||
|
||||
memcpy(&fileChooseCtx->deaths[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + DEATHS,
|
||||
sizeof(fileChooseCtx->deaths[0]));
|
||||
memcpy(&fileChooseCtx->fileNames[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + NAME,
|
||||
sizeof(fileChooseCtx->fileNames[0]));
|
||||
memcpy(&fileChooseCtx->healthCapacities[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + HEALTH_CAP,
|
||||
sizeof(fileChooseCtx->healthCapacities[0]));
|
||||
memcpy(&fileChooseCtx->questItems[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + QUEST,
|
||||
sizeof(fileChooseCtx->questItems[0]));
|
||||
memcpy(&fileChooseCtx->n64ddFlags[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + N64DD,
|
||||
sizeof(fileChooseCtx->n64ddFlags[0]));
|
||||
memcpy(&fileChooseCtx->defense[fileChooseCtx->copyDestFileIndex], sramCtx->readBuff + offset + DEFENSE,
|
||||
sizeof(fileChooseCtx->defense[0]));
|
||||
memcpy(&fileChooseCtx->health[fileChooseCtx->copyDestFileIndex], (sramCtx->readBuff + offset) + HEALTH,
|
||||
sizeof(fileChooseCtx->health[0]));
|
||||
|
||||
osSyncPrintf("f_64dd[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->n64ddFlags[gSaveContext.fileNum]);
|
||||
osSyncPrintf("heart_status[%d]=%d\n", gSaveContext.fileNum, fileChooseCtx->defense[gSaveContext.fileNum]);
|
||||
osSyncPrintf("COPY終了\n"); // "Copy end"
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the first 16 bytes of the read buffer to the SRAM header
|
||||
*/
|
||||
void Sram_WriteSramHeader(SramContext* sramCtx) {
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_HEADER_SIZE, OS_WRITE);
|
||||
}
|
||||
|
||||
void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
|
||||
u16 i;
|
||||
|
||||
osSyncPrintf("sram_initialize( Game *game, Sram *sram )\n");
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
|
||||
|
||||
for (i = 0; i < ARRAY_COUNTU(sZeldaMagic) - 3; i++) {
|
||||
if (sZeldaMagic[i + SRAM_HEADER_MAGIC] != sramCtx->readBuff[i + SRAM_HEADER_MAGIC]) {
|
||||
osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !"
|
||||
gSaveContext.language = CVar_GetS32("gLanguages", 0);
|
||||
memcpy(sramCtx->readBuff, sZeldaMagic, sizeof(sZeldaMagic));
|
||||
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language;
|
||||
Sram_WriteSramHeader(sramCtx);
|
||||
}
|
||||
}
|
||||
|
||||
gSaveContext.audioSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3;
|
||||
gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_ZTARGET] & 1;
|
||||
gSaveContext.language = CVar_GetS32("gLanguages", 0);
|
||||
|
||||
if (gSaveContext.language >= LANGUAGE_MAX) {
|
||||
gSaveContext.language = LANGUAGE_ENG;
|
||||
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language;
|
||||
Sram_WriteSramHeader(sramCtx);
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ANY(gameState->input[2].cur.button, BTN_DRIGHT)) {
|
||||
memset(sramCtx->readBuff, 0,SRAM_SIZE);
|
||||
for (i = 0; i < CHECKSUM_SIZE; i++) {
|
||||
sramCtx->readBuff[i] = i;
|
||||
}
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_WRITE);
|
||||
osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !"
|
||||
}
|
||||
|
||||
// "GOOD! GOOD! Size = %d + %d = %d"
|
||||
osSyncPrintf("GOOD!GOOD! サイズ=%d + %d = %d\n", sizeof(SaveInfo), 4, sizeof(SaveInfo) + 4);
|
||||
osSyncPrintf(VT_FGCOL(BLUE));
|
||||
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
|
||||
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
|
||||
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
|
||||
osSyncPrintf(VT_RST);
|
||||
func_800F6700(gSaveContext.audioSetting);
|
||||
}
|
||||
|
||||
void Sram_Alloc(GameState* gameState, SramContext* sramCtx) {
|
||||
sramCtx->readBuff = GameState_Alloc(gameState, SRAM_SIZE, "../z_sram.c", 1294);
|
||||
ASSERT(sramCtx->readBuff != NULL, "sram->read_buff != NULL", "../z_sram.c", 1295);
|
||||
}
|
||||
|
||||
void Sram_Init(GlobalContext* globalCtx, SramContext* sramCtx) {
|
||||
}
|
||||
|
|
|
@ -58,38 +58,13 @@ void SsSram_Dma(void* dramAddr, size_t size, s32 direction) {
|
|||
|
||||
void SsSram_ReadWrite(uintptr_t addr, void* dramAddr, size_t size, s32 direction) {
|
||||
osSyncPrintf("ssSRAMReadWrite:%08x %08x %08x %d\n", addr, (uintptr_t)dramAddr, size, direction);
|
||||
//Check to see if the file exists
|
||||
FILE* saveFile;
|
||||
saveFile = fopen("oot_save.sav", "rb");
|
||||
|
||||
if (saveFile == NULL) {
|
||||
|
||||
saveFile = fopen("oot_save.sav", "wb");
|
||||
fseek(saveFile, 0, SEEK_SET);
|
||||
assert(saveFile != NULL); // OTRTODO LOG
|
||||
uint8_t zero = 0;
|
||||
|
||||
for (uint32_t i = 0; i < SRAM_SIZE; i++) {
|
||||
fwrite(&zero, 1, 1, saveFile);
|
||||
}
|
||||
fclose(saveFile);
|
||||
} else {
|
||||
fclose(saveFile);
|
||||
}
|
||||
|
||||
switch (direction) {
|
||||
case OS_WRITE: {
|
||||
saveFile = fopen("oot_save.sav", "r+b");
|
||||
rewind(saveFile);
|
||||
fseek(saveFile, addr, SEEK_SET);
|
||||
fwrite(dramAddr, size, 1, saveFile);
|
||||
fclose(saveFile);
|
||||
Ctx_WriteSaveFile(addr, dramAddr, size);
|
||||
} break;
|
||||
case OS_READ: {
|
||||
saveFile = fopen("oot_save.sav", "rb+");
|
||||
rewind(saveFile);
|
||||
fseek(saveFile, addr, SEEK_SET);
|
||||
fread(dramAddr, size, 1, saveFile);
|
||||
fclose(saveFile);
|
||||
Ctx_ReadSaveFile(addr, dramAddr, size);
|
||||
} break;
|
||||
}
|
||||
//SsSram_Init(addr, DEVICE_TYPE_SRAM, PI_DOMAIN2, 5, 0xD, 2, 0xC, 0);
|
||||
|
|
|
@ -1209,19 +1209,15 @@ void BossGanon_ShatterWindows(u8 windowShatterState) {
|
|||
}
|
||||
|
||||
void BossGanon_DeathAndTowerCutscene(BossGanon* this, GlobalContext* globalCtx) {
|
||||
const bool originalBlood = CVar_GetS32("gOriginalBlood", 1);
|
||||
static Color_RGBA8 bloodPrimColor = { 0, 120, 0, 255 };
|
||||
static Color_RGBA8 bloodEnvColor = { 0, 120, 0, 255 };
|
||||
|
||||
static Color_RGBA8 bloodPrimColor = { 120, 0, 0, 255 };
|
||||
static Color_RGBA8 bloodEnvColor = { 120, 0, 0, 255 };
|
||||
if(CVar_GetS32("gRedGanonBlood", 0)) {
|
||||
bloodPrimColor.r = 120;
|
||||
bloodPrimColor.g = 0;
|
||||
|
||||
if(!originalBlood) {
|
||||
bloodPrimColor.r = 0;
|
||||
bloodPrimColor.g = 120;
|
||||
bloodPrimColor.b = 0;
|
||||
|
||||
bloodEnvColor.r = 0;
|
||||
bloodEnvColor.g = 120;
|
||||
bloodEnvColor.b = 0;
|
||||
bloodEnvColor.r = 120;
|
||||
bloodEnvColor.g = 0;
|
||||
}
|
||||
|
||||
s16 i;
|
||||
|
|
|
@ -1456,6 +1456,17 @@ void func_80901020(BossGanon2* this, GlobalContext* globalCtx) {
|
|||
void func_8090109C(BossGanon2* this, GlobalContext* globalCtx) {
|
||||
u8 i;
|
||||
|
||||
static Color_RGBA8 sPrimColor = { 0, 120, 0, 255 };
|
||||
static Color_RGBA8 sEnvColor = { 0, 120, 0, 255 };
|
||||
|
||||
if(CVar_GetS32("gRedGanonBlood", 0)) {
|
||||
sPrimColor.r = 120;
|
||||
sPrimColor.g = 0;
|
||||
|
||||
sEnvColor.r = 120;
|
||||
sEnvColor.g = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 70; i++) {
|
||||
Vec3f velocity;
|
||||
Vec3f accel;
|
||||
|
|
|
@ -238,10 +238,6 @@ static ColliderJntSphInit sJntSphInit2 = {
|
|||
sJntSphItemsInit2,
|
||||
};
|
||||
|
||||
static Color_RGBA8 sPrimColor = { 0, 120, 0, 255 };
|
||||
|
||||
static Color_RGBA8 sEnvColor = { 0, 120, 0, 255 };
|
||||
|
||||
static Vec3f D_8090702C[] = {
|
||||
{ 10.0f, -10.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, -60.0f },
|
||||
|
|
|
@ -110,7 +110,7 @@ void ElfMsg_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|||
|
||||
s32 ElfMsg_GetMessageId(ElfMsg* this) {
|
||||
// Negative message ID forces link to talk to Navi
|
||||
if (this->actor.params & 0x8000) {
|
||||
if (this->actor.params & 0x8000 || CVar_GetS32("gNoForcedNavi", 0) != 0) {
|
||||
return (this->actor.params & 0xFF) + 0x100;
|
||||
} else {
|
||||
return -((this->actor.params & 0xFF) + 0x100);
|
||||
|
|
|
@ -118,7 +118,7 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
func_809DEE9C(this);
|
||||
this->actionFunc = func_809DF96C;
|
||||
if (globalCtx->sceneNum == SCENE_LINK_HOME) {
|
||||
if (!LINK_IS_ADULT) {
|
||||
if (!LINK_IS_ADULT && !CVar_GetS32("gCowOfTime", 0)) {
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -452,7 +452,7 @@ s32 EnGirlA_CanBuy_DekuNuts(GlobalContext* globalCtx, EnGirlA* this) {
|
|||
if (gSaveContext.rupees < this->basePrice) {
|
||||
return CANBUY_RESULT_NEED_RUPEES;
|
||||
}
|
||||
if (Item_CheckObtainability(ITEM_NUT) == ITEM_NONE) {
|
||||
if ((Item_CheckObtainability(ITEM_NUT) == ITEM_NONE) && !CVar_GetS32("gFastDrops", 0)) {
|
||||
return CANBUY_RESULT_SUCCESS_FANFARE;
|
||||
}
|
||||
return CANBUY_RESULT_SUCCESS;
|
||||
|
@ -465,7 +465,7 @@ s32 EnGirlA_CanBuy_DekuSticks(GlobalContext* globalCtx, EnGirlA* this) {
|
|||
if (gSaveContext.rupees < this->basePrice) {
|
||||
return CANBUY_RESULT_NEED_RUPEES;
|
||||
}
|
||||
if (Item_CheckObtainability(ITEM_STICK) == ITEM_NONE) {
|
||||
if ((Item_CheckObtainability(ITEM_STICK) == ITEM_NONE) && !CVar_GetS32("gFastDrops", 0)) {
|
||||
return CANBUY_RESULT_SUCCESS_FANFARE;
|
||||
}
|
||||
return CANBUY_RESULT_SUCCESS;
|
||||
|
@ -652,7 +652,7 @@ s32 EnGirlA_CanBuy_DekuSeeds(GlobalContext* globalCtx, EnGirlA* this) {
|
|||
if (gSaveContext.rupees < this->basePrice) {
|
||||
return CANBUY_RESULT_NEED_RUPEES;
|
||||
}
|
||||
if (Item_CheckObtainability(ITEM_SEEDS) == ITEM_NONE) {
|
||||
if ((Item_CheckObtainability(ITEM_SEEDS) == ITEM_NONE) && !CVar_GetS32("gFastDrops", 0)) {
|
||||
return CANBUY_RESULT_SUCCESS_FANFARE;
|
||||
}
|
||||
return CANBUY_RESULT_SUCCESS;
|
||||
|
|
|
@ -29,7 +29,7 @@ void EnHeishi1_TurnTowardLink(EnHeishi1* this, GlobalContext* globalCtx);
|
|||
void EnHeishi1_Kick(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
void EnHeishi1_WaitNight(EnHeishi1* this, GlobalContext* globalCtx);
|
||||
|
||||
static s32 sPlayerIsCaught = false;
|
||||
s32 sHeishi1PlayerIsCaught = false;
|
||||
|
||||
const ActorInit En_Heishi1_InitVars = {
|
||||
0,
|
||||
|
@ -154,7 +154,7 @@ void EnHeishi1_Walk(EnHeishi1* this, GlobalContext* globalCtx) {
|
|||
Audio_PlayActorSound2(&this->actor, NA_SE_EV_KNIGHT_WALK);
|
||||
}
|
||||
|
||||
if (!sPlayerIsCaught) {
|
||||
if (!sHeishi1PlayerIsCaught) {
|
||||
path = &globalCtx->setupPathList[this->path];
|
||||
pointPos = SEGMENTED_TO_VIRTUAL(path->points);
|
||||
pointPos += this->waypoint;
|
||||
|
@ -259,7 +259,7 @@ void EnHeishi1_Wait(EnHeishi1* this, GlobalContext* globalCtx) {
|
|||
s32 i;
|
||||
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
if (!sPlayerIsCaught) {
|
||||
if (!sHeishi1PlayerIsCaught) {
|
||||
switch (this->headBehaviorDecided) {
|
||||
case false:
|
||||
this->headDirection++;
|
||||
|
@ -352,7 +352,7 @@ void EnHeishi1_Kick(EnHeishi1* this, GlobalContext* globalCtx) {
|
|||
globalCtx->nextEntranceIndex = 0x4FA;
|
||||
globalCtx->sceneLoadFlag = 0x14;
|
||||
this->loadStarted = true;
|
||||
sPlayerIsCaught = false;
|
||||
sHeishi1PlayerIsCaught = false;
|
||||
globalCtx->fadeTransition = 0x2E;
|
||||
gSaveContext.nextTransition = 0x2E;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ void EnHeishi1_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
if (this->type != 5) {
|
||||
path = this->path * 2;
|
||||
if ((sCamDataIdxs[path] == activeCam->camDataIdx) || (sCamDataIdxs[path + 1] == activeCam->camDataIdx)) {
|
||||
if (!sPlayerIsCaught) {
|
||||
if (!sHeishi1PlayerIsCaught) {
|
||||
if ((this->actionFunc == EnHeishi1_Walk) || (this->actionFunc == EnHeishi1_Wait)) {
|
||||
Vec3f searchBallVel;
|
||||
Vec3f searchBallAccel = { 0.0f, 0.0f, 0.0f };
|
||||
|
@ -459,7 +459,7 @@ void EnHeishi1_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
// "Discovered!"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST);
|
||||
func_8002DF54(globalCtx, &this->actor, 1);
|
||||
sPlayerIsCaught = true;
|
||||
sHeishi1PlayerIsCaught = true;
|
||||
this->actionFunc = EnHeishi1_SetupMoveToLink;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1080,7 +1080,15 @@ void func_80A98DB4(EnKo* this, GlobalContext* globalCtx) {
|
|||
dist = this->actor.xzDistToPlayer;
|
||||
}
|
||||
|
||||
Math_SmoothStepToF(&this->modelAlpha, (this->appearDist < dist) ? 0.0f : 255.0f, 0.3f, 40.0f, 1.0f);
|
||||
if (CVar_GetS32("gDisableKokiriDrawDistance", 0) != 0) {
|
||||
this->appearDist = 32767.0f;
|
||||
Math_SmoothStepToF(&this->modelAlpha, (this->appearDist < dist) ? 0.0f : 255.0f, 0.3f, 40.0f, 1.0f);
|
||||
f32 test = this->appearDist;
|
||||
} else {
|
||||
this->appearDist = 180.0f;
|
||||
Math_SmoothStepToF(&this->modelAlpha, (this->appearDist < dist) ? 0.0f : 255.0f, 0.3f, 40.0f, 1.0f);
|
||||
}
|
||||
|
||||
if (this->modelAlpha < 10.0f) {
|
||||
this->actor.flags &= ~ACTOR_FLAG_0;
|
||||
} else {
|
||||
|
|
|
@ -613,10 +613,18 @@ void func_80AAB5A4(EnMd* this, GlobalContext* globalCtx) {
|
|||
f32 temp;
|
||||
|
||||
if (globalCtx->sceneNum != SCENE_KOKIRI_HOME4) {
|
||||
temp = (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !(gSaveContext.eventChkInf[1] & 0x1000) &&
|
||||
(globalCtx->sceneNum == SCENE_SPOT04))
|
||||
? 100.0f
|
||||
: 400.0f;
|
||||
if (CVar_GetS32("gDisableKokiriDrawDistance", 0) != 0) {
|
||||
temp = (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !(gSaveContext.eventChkInf[1] & 0x1000) &&
|
||||
(globalCtx->sceneNum == SCENE_SPOT04))
|
||||
? 100.0f
|
||||
: 32767.0f;
|
||||
} else {
|
||||
temp = (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && !(gSaveContext.eventChkInf[1] & 0x1000) &&
|
||||
(globalCtx->sceneNum == SCENE_SPOT04))
|
||||
? 100.0f
|
||||
: 400.0f;
|
||||
}
|
||||
|
||||
this->alpha = func_80034DD4(&this->actor, globalCtx, this->alpha, temp);
|
||||
this->actor.shape.shadowAlpha = this->alpha;
|
||||
} else {
|
||||
|
|
|
@ -727,7 +727,12 @@ void EnSa_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
if (this->actionFunc != func_80AF68E4) {
|
||||
this->alpha = func_80034DD4(&this->actor, globalCtx, this->alpha, 400.0f);
|
||||
if (CVar_GetS32("gDisableKokiriDrawDistance", 0) != 0) {
|
||||
this->alpha = func_80034DD4(&this->actor, globalCtx, this->alpha, 32767);
|
||||
}
|
||||
else {
|
||||
this->alpha = func_80034DD4(&this->actor, globalCtx, this->alpha, 400.0f);
|
||||
}
|
||||
} else {
|
||||
this->alpha = 255;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,9 @@ void func_80AFB768(EnSi* this, GlobalContext* globalCtx) {
|
|||
if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) {
|
||||
this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER;
|
||||
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
|
||||
player->actor.freezeTimer = 10;
|
||||
if (CVar_GetS32("gSkulltulaFreeze", 0) != 1) {
|
||||
player->actor.freezeTimer = 20;
|
||||
}
|
||||
Message_StartTextbox(globalCtx, 0xB4, NULL);
|
||||
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
||||
this->actionFunc = func_80AFB950;
|
||||
|
@ -116,7 +118,6 @@ void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) {
|
|||
|
||||
if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_13)) {
|
||||
Item_Give(globalCtx, ITEM_SKULL_TOKEN);
|
||||
player->actor.freezeTimer = 10;
|
||||
Message_StartTextbox(globalCtx, 0xB4, NULL);
|
||||
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
|
||||
this->actionFunc = func_80AFB950;
|
||||
|
@ -126,7 +127,7 @@ void func_80AFB89C(EnSi* this, GlobalContext* globalCtx) {
|
|||
void func_80AFB950(EnSi* this, GlobalContext* globalCtx) {
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
|
||||
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING) {
|
||||
if (Message_GetState(&globalCtx->msgCtx) != TEXT_STATE_CLOSING && CVar_GetS32("gSkulltulaFreeze", 0) != 1) {
|
||||
player->actor.freezeTimer = 10;
|
||||
} else {
|
||||
SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF);
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
#include "objects/object_tk/object_tk.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
|
||||
#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19
|
||||
#define ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE 0x1000
|
||||
|
||||
bool heartPieceSpawned;
|
||||
|
||||
void EnTk_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnTk_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
@ -505,6 +509,7 @@ void EnTk_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|||
this->currentReward = -1;
|
||||
this->currentSpot = NULL;
|
||||
this->actionFunc = EnTk_Rest;
|
||||
heartPieceSpawned = false;
|
||||
}
|
||||
|
||||
void EnTk_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
|
@ -611,13 +616,23 @@ void EnTk_Dig(EnTk* this, GlobalContext* globalCtx) {
|
|||
* Upgrade the purple rupee reward to the heart piece if this
|
||||
* is the first grand prize dig.
|
||||
*/
|
||||
if (!(gSaveContext.itemGetInf[1] & 0x1000)) {
|
||||
gSaveContext.itemGetInf[1] |= 0x1000;
|
||||
// If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true.
|
||||
// Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true.
|
||||
// If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag.
|
||||
if (!heartPieceSpawned &&
|
||||
(!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) ||
|
||||
CVar_GetS32("gGravediggingTourFix", 0) &&
|
||||
!Flags_GetCollectible(globalCtx, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) {
|
||||
this->currentReward = 4;
|
||||
gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE;
|
||||
heartPieceSpawned = true;
|
||||
}
|
||||
}
|
||||
|
||||
Item_DropCollectible(globalCtx, &rewardPos, rewardParams[this->currentReward]);
|
||||
EnItem00* reward = Item_DropCollectible(globalCtx, &rewardPos, rewardParams[this->currentReward]);
|
||||
if (this->currentReward == 4) {
|
||||
reward->collectibleFlag = COLLECTFLAG_GRAVEDIGGING_HEART_PIECE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -140,8 +140,9 @@ void OceffStorm_Draw2(Actor* thisx, GlobalContext* globalCtx) {
|
|||
gSPDisplayList(POLY_XLU_DISP++, sMaterialDL);
|
||||
gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, scroll * 8, scroll * 4, 64, 64, 1,
|
||||
scroll * 4, scroll * 4, 64, 64));
|
||||
gSPTextureRectangle(POLY_XLU_DISP++, 0, 0, (SCREEN_WIDTH << 2), (SCREEN_HEIGHT << 2), G_TX_RENDERTILE, 0, 0, 140,
|
||||
(1 << 15) | (31 << 10) | 884);
|
||||
gSPWideTextureRectangle(POLY_XLU_DISP++, OTRGetRectDimensionFromLeftEdge(0) << 2, 0,
|
||||
OTRGetRectDimensionFromRightEdge(SCREEN_WIDTH) << 2, 0x03C0, G_TX_RENDERTILE, 0, 0, 0x008C,
|
||||
-0x008C);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_oceff_storm.c", 477);
|
||||
}
|
||||
|
|
|
@ -351,6 +351,7 @@ s32 func_80852F38(GlobalContext* globalCtx, Player* this);
|
|||
s32 func_80852FFC(GlobalContext* globalCtx, Actor* actor, s32 csMode);
|
||||
void func_80853080(Player* this, GlobalContext* globalCtx);
|
||||
s32 Player_InflictDamage(GlobalContext* globalCtx, s32 damage);
|
||||
s32 Player_InflictDamageModified(GlobalContext* globalCtx, s32 damage, u8 modified);
|
||||
void func_80853148(GlobalContext* globalCtx, Actor* actor);
|
||||
|
||||
// .bss part 1
|
||||
|
@ -2106,10 +2107,10 @@ LinkAnimationHeader* func_808346C4(GlobalContext* globalCtx, Player* this) {
|
|||
func_808323B4(globalCtx, this);
|
||||
|
||||
if (this->unk_870 < 0.5f) {
|
||||
return D_808543A4[Player_HoldsTwoHandedWeapon(this)];
|
||||
return D_808543A4[Player_HoldsTwoHandedWeapon(this) && !(CVar_GetS32("gShieldTwoHanded", 0) && (this->heldItemActionParam != PLAYER_AP_STICK))];
|
||||
}
|
||||
else {
|
||||
return D_808543AC[Player_HoldsTwoHandedWeapon(this)];
|
||||
return D_808543AC[Player_HoldsTwoHandedWeapon(this) && !(CVar_GetS32("gShieldTwoHanded", 0) && (this->heldItemActionParam != PLAYER_AP_STICK))];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2779,22 +2780,24 @@ void func_80835F44(GlobalContext* globalCtx, Player* this, s32 item) {
|
|||
if (actionParam >= PLAYER_AP_BOOTS_KOKIRI) {
|
||||
u16 bootsValue = actionParam - PLAYER_AP_BOOTS_KOKIRI + 1;
|
||||
if (CUR_EQUIP_VALUE(EQUIP_BOOTS) == bootsValue) {
|
||||
Inventory_ChangeEquipment(EQUIP_BOOTS, 1);
|
||||
Inventory_ChangeEquipment(EQUIP_BOOTS, PLAYER_BOOTS_KOKIRI + 1);
|
||||
} else {
|
||||
Inventory_ChangeEquipment(EQUIP_BOOTS, bootsValue);
|
||||
}
|
||||
Player_SetEquipmentData(globalCtx, this);
|
||||
func_808328EC(this, CUR_EQUIP_VALUE(EQUIP_BOOTS) == PLAYER_BOOTS_IRON + 1 ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (actionParam >= PLAYER_AP_TUNIC_KOKIRI) {
|
||||
u16 tunicValue = actionParam - PLAYER_AP_TUNIC_KOKIRI + 1;
|
||||
if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == tunicValue) {
|
||||
Inventory_ChangeEquipment(EQUIP_TUNIC, 1);
|
||||
Inventory_ChangeEquipment(EQUIP_TUNIC, PLAYER_TUNIC_KOKIRI + 1);
|
||||
} else {
|
||||
Inventory_ChangeEquipment(EQUIP_TUNIC, tunicValue);
|
||||
}
|
||||
Player_SetEquipmentData(globalCtx, this);
|
||||
func_808328EC(this, NA_SE_PL_CHANGE_ARMS);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3514,12 +3517,22 @@ void func_80837AFC(Player* this, s32 timer) {
|
|||
this->unk_88F = 0;
|
||||
}
|
||||
|
||||
s32 func_80837B18(GlobalContext* globalCtx, Player* this, s32 damage) {
|
||||
s32 func_80837B18_modified(GlobalContext* globalCtx, Player* this, s32 damage, u8 modified) {
|
||||
if ((this->invincibilityTimer != 0) || (this->actor.category != ACTORCAT_PLAYER)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Health_ChangeBy(globalCtx, damage);
|
||||
s32 modifiedDamage = damage;
|
||||
if (modified)
|
||||
{
|
||||
modifiedDamage *= CVar_GetS32("gDamageMul", 1);
|
||||
}
|
||||
|
||||
return Health_ChangeBy(globalCtx, modifiedDamage);
|
||||
}
|
||||
|
||||
s32 func_80837B18(GlobalContext* globalCtx, Player* this, s32 damage) {
|
||||
return func_80837B18_modified(globalCtx, this, damage, true);
|
||||
}
|
||||
|
||||
void func_80837B60(Player* this) {
|
||||
|
@ -3707,7 +3720,7 @@ s32 func_8083816C(s32 arg0) {
|
|||
}
|
||||
|
||||
void func_8083819C(Player* this, GlobalContext* globalCtx) {
|
||||
if (this->currentShield == PLAYER_SHIELD_DEKU) {
|
||||
if (this->currentShield == PLAYER_SHIELD_DEKU && (CVar_GetS32("gFireproofDekuShield", 0) == 0)) {
|
||||
Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_SHIELD, this->actor.world.pos.x,
|
||||
this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 1);
|
||||
Inventory_DeleteEquipment(globalCtx, EQUIP_SHIELD);
|
||||
|
@ -3745,7 +3758,7 @@ s32 func_808382DC(Player* this, GlobalContext* globalCtx) {
|
|||
|
||||
if (this->unk_A86 != 0) {
|
||||
if (!Player_InBlockingCsMode(globalCtx, this)) {
|
||||
Player_InflictDamage(globalCtx, -16);
|
||||
Player_InflictDamageModified(globalCtx, -16 * CVar_GetS32("gVoidDamageMul", 1), false);
|
||||
this->unk_A86 = 0;
|
||||
}
|
||||
}
|
||||
|
@ -5468,8 +5481,8 @@ s32 func_8083C6B8(GlobalContext* globalCtx, Player* this) {
|
|||
sp24 = this->actor.world.pos;
|
||||
sp24.y += 50.0f;
|
||||
|
||||
if (!(this->actor.bgCheckFlags & 1) || (this->actor.world.pos.z > 1300.0f) ||
|
||||
BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &sp24, 20.0f)) {
|
||||
if (CVar_GetS32("gHoverFishing", 0) ? 0 : !(this->actor.bgCheckFlags & 1) ||
|
||||
(this->actor.world.pos.z > 1300.0f) || BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &sp24, 20.0f)) {
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
@ -6155,7 +6168,12 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) {
|
|||
|
||||
iREG(67) = false;
|
||||
|
||||
if ((Item_CheckObtainability(giEntry->itemId) == ITEM_NONE) || (globalCtx->sceneNum == SCENE_BOWLING)) {
|
||||
s32 drop = giEntry->objectId;
|
||||
|
||||
if ((globalCtx->sceneNum == SCENE_BOWLING) || !(CVar_GetS32("gFastDrops", 0) &&
|
||||
((drop == OBJECT_GI_BOMB_1) || (drop == OBJECT_GI_NUTS) || (drop == OBJECT_GI_STICK) ||
|
||||
(drop == OBJECT_GI_SEED) || (drop == OBJECT_GI_MAGICPOT) || (drop == OBJECT_GI_ARROW))) &&
|
||||
(Item_CheckObtainability(giEntry->itemId) == ITEM_NONE)) {
|
||||
func_808323B4(globalCtx, this);
|
||||
func_8083AE40(this, giEntry->objectId);
|
||||
|
||||
|
@ -6179,6 +6197,9 @@ s32 func_8083E5A8(Player* this, GlobalContext* globalCtx) {
|
|||
if (this->getItemId != GI_NONE) {
|
||||
GetItemEntry* giEntry = &sGetItemTable[-this->getItemId - 1];
|
||||
EnBox* chest = (EnBox*)interactedActor;
|
||||
if(CVar_GetS32("gFastChests", 0) != 0) {
|
||||
giEntry->gi = -1 * abs(giEntry->gi);
|
||||
}
|
||||
|
||||
if (giEntry->itemId != ITEM_NONE) {
|
||||
if (((Item_CheckObtainability(giEntry->itemId) == ITEM_NONE) && (giEntry->field & 0x40)) ||
|
||||
|
@ -8274,7 +8295,7 @@ s32 func_80843E64(GlobalContext* globalCtx, Player* this) {
|
|||
|
||||
impactInfo = &D_80854600[impactIndex];
|
||||
|
||||
if (Player_InflictDamage(globalCtx, impactInfo->damage)) {
|
||||
if (Player_InflictDamageModified(globalCtx, impactInfo->damage * CVar_GetS32("gFallDamageMul", 1), false)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -11621,7 +11642,7 @@ void func_8084BF1C(Player* this, GlobalContext* globalCtx) {
|
|||
phi_f2 = -1.0f;
|
||||
}
|
||||
|
||||
this->skelAnime.playSpeed = phi_f2 * phi_f0;
|
||||
this->skelAnime.playSpeed = phi_f2 * phi_f0 + phi_f2 * CVar_GetS32("gClimbSpeed", 0);
|
||||
|
||||
if (this->unk_850 >= 0) {
|
||||
if ((this->actor.wallPoly != NULL) && (this->actor.wallBgId != BGCHECK_SCENE)) {
|
||||
|
@ -14824,9 +14845,13 @@ void func_80853080(Player* this, GlobalContext* globalCtx) {
|
|||
}
|
||||
|
||||
s32 Player_InflictDamage(GlobalContext* globalCtx, s32 damage) {
|
||||
return Player_InflictDamageModified(globalCtx, damage, true);
|
||||
}
|
||||
|
||||
s32 Player_InflictDamageModified(GlobalContext* globalCtx, s32 damage, u8 modified) {
|
||||
Player* this = GET_PLAYER(globalCtx);
|
||||
|
||||
if (!Player_InBlockingCsMode(globalCtx, this) && !func_80837B18(globalCtx, this, damage)) {
|
||||
if (!Player_InBlockingCsMode(globalCtx, this) && !func_80837B18_modified(globalCtx, this, damage, modified)) {
|
||||
this->stateFlags2 &= ~PLAYER_STATE2_7;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
*/
|
||||
|
||||
#include "z_eff_ss_solder_srch_ball.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
#include <math.h>
|
||||
|
||||
#define rUnused regs[1]
|
||||
|
||||
u32 EffectSsSolderSrchBall_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx);
|
||||
void EffectSsSolderSrchBall_Update(GlobalContext* globalCtx, u32 index, EffectSs* this);
|
||||
void EffectSsSolderSrchBall_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this);
|
||||
|
||||
EffectSsInit Effect_Ss_Solder_Srch_Ball_InitVars = {
|
||||
EFFECT_SS_SOLDER_SRCH_BALL,
|
||||
|
@ -23,6 +26,7 @@ u32 EffectSsSolderSrchBall_Init(GlobalContext* globalCtx, u32 index, EffectSs* t
|
|||
this->velocity = initParams->velocity;
|
||||
this->accel = initParams->accel;
|
||||
this->update = EffectSsSolderSrchBall_Update;
|
||||
this->draw = EffectSsSolderSrchBall_Draw;
|
||||
this->life = 100;
|
||||
this->rUnused = initParams->unused;
|
||||
this->actor = initParams->linkDetected; // actor field was incorrectly used as a pointer to something else
|
||||
|
@ -53,3 +57,198 @@ void EffectSsSolderSrchBall_Update(GlobalContext* globalCtx, u32 index, EffectSs
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vtxn_f2l(Vtx* r, Vec3f* v) {
|
||||
r->n.ob[0] = floorf(0.5f + v->x * 128.f);
|
||||
r->n.ob[1] = floorf(0.5f + v->y * 128.f);
|
||||
r->n.ob[2] = floorf(0.5f + v->z * 128.f);
|
||||
r->n.flag = 0;
|
||||
r->n.tc[0] = 0;
|
||||
r->n.tc[1] = 0;
|
||||
r->n.n[0] = v->x * 127.f;
|
||||
r->n.n[1] = v->y * 127.f;
|
||||
r->n.n[2] = v->z * 127.f;
|
||||
r->n.a = 0xFF;
|
||||
}
|
||||
|
||||
static void ico_sph_subdivide_edge(Vec3f* r, Vec3f* a, Vec3f* b) {
|
||||
Math_Vec3f_Sum(a, b, r);
|
||||
Math_Vec3f_Scale(r, (1.0f / Math3D_Vec3fMagnitude(r)));
|
||||
}
|
||||
|
||||
static void draw_ico_sphere(Gfx** p_gfx_p, f32 x, f32 y, f32 z, f32 radius, GraphicsContext* gfxCtx) {
|
||||
static Gfx* p_sph_gfx = NULL;
|
||||
static Vtx sph_vtx[42];
|
||||
static Gfx sph_gfx[45];
|
||||
Gfx* sph_gfx_p;
|
||||
s32 i;
|
||||
|
||||
if (!p_sph_gfx) {
|
||||
Vec3f vtx[42];
|
||||
s32 r0_n = 1, r0_m = r0_n / 5, r0_i = 0 + 0;
|
||||
s32 r1_n = 5, r1_m = r1_n / 5, r1_i = r0_i + r0_n;
|
||||
s32 r2_n = 10, r2_m = r2_n / 5, r2_i = r1_i + r1_n;
|
||||
s32 r3_n = 10, r3_m = r3_n / 5, r3_i = r2_i + r2_n;
|
||||
s32 r4_n = 10, r4_m = r4_n / 5, r4_i = r3_i + r3_n;
|
||||
s32 r5_n = 5, r5_m = r5_n / 5, r5_i = r4_i + r4_n;
|
||||
s32 r6_n = 1, r6_m = r6_n / 5, r6_i = r5_i + r5_n;
|
||||
|
||||
vtx[r0_i + (0 * r0_m + 0) % r0_n].x = 0.0f;
|
||||
vtx[r0_i + (0 * r0_m + 0) % r0_n].y = 1.0f;
|
||||
vtx[r0_i + (0 * r0_m + 0) % r0_n].z = 0.0f;
|
||||
|
||||
vtx[r6_i + (0 * r6_m + 0) % r6_n].x = 0.0f;
|
||||
vtx[r6_i + (0 * r6_m + 0) % r6_n].y = -1.0f;
|
||||
vtx[r6_i + (0 * r6_m + 0) % r6_n].z = 0.0f;
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
f32 a_xz = 2.f * M_PI / 10.f;
|
||||
f32 a_y = atanf(1.0f / 2.0f);
|
||||
|
||||
vtx[r2_i + (i * r2_m + 0) % r2_n].x = cosf(a_xz * (i * r2_m + 0)) * cosf(a_y * 1.f);
|
||||
vtx[r2_i + (i * r2_m + 0) % r2_n].y = sinf(a_y * 1.f);
|
||||
vtx[r2_i + (i * r2_m + 0) % r2_n].z = -sinf(a_xz * (i * r2_m + 0)) * cosf(a_y * 1.f);
|
||||
|
||||
vtx[r4_i + (i * r4_m + 0) % r4_n].x = cosf(a_xz * (i * r4_m + 1)) * cosf(a_y * -1.f);
|
||||
vtx[r4_i + (i * r4_m + 0) % r4_n].y = sinf(a_y * -1.f);
|
||||
vtx[r4_i + (i * r4_m + 0) % r4_n].z = -sinf(a_xz * (i * r4_m + 1)) * cosf(a_y * -1.f);
|
||||
}
|
||||
for (i = 0; i < 5; ++i) {
|
||||
ico_sph_subdivide_edge(&vtx[r1_i + (i * r1_m + 0) % r1_n], &vtx[r0_i + (i * r0_m + 0) % r0_n],
|
||||
&vtx[r2_i + (i * r2_m + 0) % r2_n]);
|
||||
ico_sph_subdivide_edge(&vtx[r2_i + (i * r2_m + 1) % r2_n], &vtx[r2_i + (i * r2_m + 0) % r2_n],
|
||||
&vtx[r2_i + (i * r2_m + 2) % r2_n]);
|
||||
ico_sph_subdivide_edge(&vtx[r3_i + (i * r3_m + 0) % r3_n], &vtx[r2_i + (i * r2_m + 0) % r2_n],
|
||||
&vtx[r4_i + (i * r4_m + 0) % r4_n]);
|
||||
ico_sph_subdivide_edge(&vtx[r3_i + (i * r3_m + 1) % r3_n], &vtx[r4_i + (i * r4_m + 0) % r4_n],
|
||||
&vtx[r2_i + (i * r2_m + 2) % r2_n]);
|
||||
ico_sph_subdivide_edge(&vtx[r4_i + (i * r4_m + 1) % r4_n], &vtx[r4_i + (i * r4_m + 0) % r4_n],
|
||||
&vtx[r4_i + (i * r4_m + 2) % r4_n]);
|
||||
ico_sph_subdivide_edge(&vtx[r5_i + (i * r5_m + 0) % r5_n], &vtx[r4_i + (i * r4_m + 0) % r4_n],
|
||||
&vtx[r6_i + (i * r6_m + 0) % r6_n]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 42; ++i)
|
||||
vtxn_f2l(&sph_vtx[i], &vtx[i]);
|
||||
|
||||
p_sph_gfx = sph_gfx;
|
||||
sph_gfx_p = p_sph_gfx;
|
||||
|
||||
gSPSetGeometryMode(sph_gfx_p++, G_CULL_BACK | G_SHADING_SMOOTH);
|
||||
|
||||
gSPVertex(sph_gfx_p++, &sph_vtx[r0_i], r0_n + r1_n + r2_n + r3_n, r0_i - r0_i);
|
||||
r3_i -= r0_i;
|
||||
r2_i -= r0_i;
|
||||
r1_i -= r0_i;
|
||||
r0_i -= r0_i;
|
||||
for (i = 0; i < 5; ++i) {
|
||||
s32 v[24];
|
||||
v[0] = r0_i + (i * r0_m + 0) % r0_n;
|
||||
v[1] = r1_i + (i * r1_m + 0) % r1_n;
|
||||
v[2] = r1_i + (i * r1_m + 1) % r1_n;
|
||||
v[3] = r1_i + (i * r1_m + 0) % r1_n;
|
||||
v[4] = r2_i + (i * r2_m + 0) % r2_n;
|
||||
v[5] = r2_i + (i * r2_m + 1) % r2_n;
|
||||
v[6] = r1_i + (i * r1_m + 0) % r1_n;
|
||||
v[7] = r2_i + (i * r2_m + 1) % r2_n;
|
||||
v[8] = r1_i + (i * r1_m + 1) % r1_n;
|
||||
v[9] = r1_i + (i * r1_m + 1) % r1_n;
|
||||
v[10] = r2_i + (i * r2_m + 1) % r2_n;
|
||||
v[11] = r2_i + (i * r2_m + 2) % r2_n;
|
||||
v[12] = r2_i + (i * r2_m + 0) % r2_n;
|
||||
v[13] = r3_i + (i * r3_m + 0) % r3_n;
|
||||
v[14] = r2_i + (i * r2_m + 1) % r2_n;
|
||||
v[15] = r2_i + (i * r2_m + 1) % r2_n;
|
||||
v[16] = r3_i + (i * r3_m + 0) % r3_n;
|
||||
v[17] = r3_i + (i * r3_m + 1) % r3_n;
|
||||
v[18] = r2_i + (i * r2_m + 1) % r2_n;
|
||||
v[19] = r3_i + (i * r3_m + 1) % r3_n;
|
||||
v[20] = r2_i + (i * r2_m + 2) % r2_n;
|
||||
v[21] = r2_i + (i * r2_m + 2) % r2_n;
|
||||
v[22] = r3_i + (i * r3_m + 1) % r3_n;
|
||||
v[23] = r3_i + (i * r3_m + 2) % r3_n;
|
||||
gSP2Triangles(sph_gfx_p++, v[0], v[1], v[2], 0, v[3], v[4], v[5], 0);
|
||||
gSP2Triangles(sph_gfx_p++, v[6], v[7], v[8], 0, v[9], v[10], v[11], 0);
|
||||
gSP2Triangles(sph_gfx_p++, v[12], v[13], v[14], 0, v[15], v[16], v[17], 0);
|
||||
gSP2Triangles(sph_gfx_p++, v[18], v[19], v[20], 0, v[21], v[22], v[23], 0);
|
||||
}
|
||||
|
||||
gSPVertex(sph_gfx_p++, &sph_vtx[r4_i], r4_n + r5_n + r6_n, r4_i - r4_i);
|
||||
r6_i -= r4_i;
|
||||
r5_i -= r4_i;
|
||||
r4_i -= r4_i;
|
||||
for (i = 0; i < 5; ++i) {
|
||||
s32 v[24];
|
||||
v[0] = r3_i + (i * r3_m + 1) % r3_n;
|
||||
v[1] = r4_i + (i * r4_m + 0) % r4_n;
|
||||
v[2] = r4_i + (i * r4_m + 1) % r4_n;
|
||||
v[3] = r3_i + (i * r3_m + 1) % r3_n;
|
||||
v[4] = r4_i + (i * r4_m + 1) % r4_n;
|
||||
v[5] = r3_i + (i * r3_m + 2) % r3_n;
|
||||
v[6] = r3_i + (i * r3_m + 2) % r3_n;
|
||||
v[7] = r4_i + (i * r4_m + 1) % r4_n;
|
||||
v[8] = r4_i + (i * r4_m + 2) % r4_n;
|
||||
v[9] = r3_i + (i * r3_m + 2) % r3_n;
|
||||
v[10] = r4_i + (i * r4_m + 2) % r4_n;
|
||||
v[11] = r3_i + (i * r3_m + 3) % r3_n;
|
||||
v[12] = r4_i + (i * r4_m + 0) % r4_n;
|
||||
v[13] = r5_i + (i * r5_m + 0) % r5_n;
|
||||
v[14] = r4_i + (i * r4_m + 1) % r4_n;
|
||||
v[15] = r4_i + (i * r4_m + 1) % r4_n;
|
||||
v[16] = r5_i + (i * r5_m + 0) % r5_n;
|
||||
v[17] = r5_i + (i * r5_m + 1) % r5_n;
|
||||
v[18] = r4_i + (i * r4_m + 1) % r4_n;
|
||||
v[19] = r5_i + (i * r5_m + 1) % r5_n;
|
||||
v[20] = r4_i + (i * r4_m + 2) % r4_n;
|
||||
v[21] = r5_i + (i * r5_m + 0) % r5_n;
|
||||
v[22] = r6_i + (i * r6_m + 0) % r6_n;
|
||||
v[23] = r5_i + (i * r5_m + 1) % r5_n;
|
||||
gSP2Triangles(sph_gfx_p++, v[0], v[1], v[2], 0, v[3], v[4], v[5], 0);
|
||||
gSP2Triangles(sph_gfx_p++, v[6], v[7], v[8], 0, v[9], v[10], v[11], 0);
|
||||
gSP2Triangles(sph_gfx_p++, v[12], v[13], v[14], 0, v[15], v[16], v[17], 0);
|
||||
gSP2Triangles(sph_gfx_p++, v[18], v[19], v[20], 0, v[21], v[22], v[23], 0);
|
||||
}
|
||||
|
||||
gSPClearGeometryMode(sph_gfx_p++, G_CULL_BACK | G_SHADING_SMOOTH);
|
||||
gSPEndDisplayList(sph_gfx_p++);
|
||||
}
|
||||
Matrix_Push();
|
||||
Matrix_Translate(x, y, z, MTXMODE_NEW);
|
||||
Matrix_Scale(radius / 128.0f, radius / 128.0f, radius / 128.0f, MTXMODE_APPLY);
|
||||
gSPMatrix((*p_gfx_p)++, Matrix_NewMtx(gfxCtx, __FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH);
|
||||
gSPDisplayList((*p_gfx_p)++, p_sph_gfx);
|
||||
gSPPopMatrix((*p_gfx_p)++, G_MTX_MODELVIEW);
|
||||
Matrix_Pop();
|
||||
}
|
||||
|
||||
void EffectSsSolderSrchBall_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) {
|
||||
if (CVar_GetS32("gGuardVision", 0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
|
||||
u32 rm;
|
||||
u32 blc1;
|
||||
u32 blc2;
|
||||
s16* seenLink = this->actor;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx, __FILE__, __LINE__);
|
||||
rm = Z_CMP | IM_RD | CVG_DST_FULL | FORCE_BL | ZMODE_XLU;
|
||||
blc1 = GBL_c1(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA);
|
||||
blc2 = GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA);
|
||||
|
||||
gSPLoadGeometryMode(POLY_XLU_DISP++, G_ZBUFFER | G_SHADE | G_LIGHTING);
|
||||
gSPTexture(POLY_XLU_DISP++, 0, 0, 0, G_TX_RENDERTILE, G_OFF);
|
||||
gDPPipeSync(POLY_XLU_DISP++);
|
||||
gDPSetCycleType(POLY_XLU_DISP++, G_CYC_1CYCLE);
|
||||
gDPSetRenderMode(POLY_XLU_DISP++, rm | blc1, rm | blc2);
|
||||
gDPSetCombineLERP(POLY_XLU_DISP++, PRIMITIVE, 0, SHADE, 0, 0, 0, 0, ENVIRONMENT, PRIMITIVE, 0, SHADE, 0, 0, 0,
|
||||
0, ENVIRONMENT);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255);
|
||||
if (*seenLink) {
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 0, 0, 255);
|
||||
}
|
||||
draw_ico_sphere(&POLY_XLU_DISP, this->pos.x, this->pos.y, this->pos.z, 30.0f, gfxCtx);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, __FILE__, __LINE__);
|
||||
}
|
|
@ -5,17 +5,6 @@
|
|||
#include "global.h"
|
||||
#include "vt.h"
|
||||
|
||||
|
||||
#define GET_NEWF(sramCtx, slotNum, index) (sramCtx->readBuff[gSramSlotOffsets[slotNum] + OFFSETOF(SaveContext, newf[index])])
|
||||
|
||||
#define SLOT_OCCUPIED(sramCtx, slotNum) \
|
||||
((GET_NEWF(sramCtx, slotNum, 0) == 'Z') || \
|
||||
(GET_NEWF(sramCtx, slotNum, 1) == 'E') || \
|
||||
(GET_NEWF(sramCtx, slotNum, 2) == 'L') || \
|
||||
(GET_NEWF(sramCtx, slotNum, 3) == 'D') || \
|
||||
(GET_NEWF(sramCtx, slotNum, 4) == 'A') || \
|
||||
(GET_NEWF(sramCtx, slotNum, 5) == 'Z'))
|
||||
|
||||
// Init mode: Initial setup as the file select is starting up, fades and slides in various menu elements
|
||||
// Config mode: Handles the bulk of the file select, various configuration tasks like picking a file, copy/erase, and the options menu
|
||||
// Select mode: Displays the selected file with various details about it, and allows the player to confirm and open it
|
||||
|
|
|
@ -64,9 +64,6 @@ void FileChoose_InitModeUpdate(GameState* thisx) {
|
|||
this->menuMode = FS_MENU_MODE_CONFIG;
|
||||
this->configMode = CM_FADE_IN_START;
|
||||
this->nextTitleLabel = FS_TITLE_OPEN_FILE;
|
||||
osSyncPrintf("Sram Start─Load 》》》》》 ");
|
||||
Sram_VerifyAndLoadAllSaves(this, &this->sramCtx);
|
||||
osSyncPrintf("終了!!!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +77,6 @@ void FileChoose_InitModeDraw(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_FadeInMenuElements(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
|
||||
this->titleAlpha[0] += VREG(1);
|
||||
|
@ -89,7 +85,7 @@ void FileChoose_FadeInMenuElements(GameState* thisx) {
|
|||
for (i = 0; i < 3; i++) {
|
||||
this->fileButtonAlpha[i] = this->windowAlpha;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->windowAlpha;
|
||||
this->connectorAlpha[i] += VREG(1);
|
||||
if (this->connectorAlpha[i] >= 255) {
|
||||
|
@ -176,18 +172,12 @@ void FileChoose_FinishFadeIn(GameState* thisx) {
|
|||
void FileChoose_UpdateMainMenu(GameState* thisx) {
|
||||
static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E };
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
Input* input = &this->state.input[0];
|
||||
bool dpad = CVar_GetS32("gDpadPauseName", 0);
|
||||
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
if (this->buttonIndex <= FS_BTN_MAIN_FILE_3) {
|
||||
osSyncPrintf("REGCK_ALL[%x]=%x,%x,%x,%x,%x,%x\n", this->buttonIndex,
|
||||
GET_NEWF(sramCtx, this->buttonIndex, 0), GET_NEWF(sramCtx, this->buttonIndex, 1),
|
||||
GET_NEWF(sramCtx, this->buttonIndex, 2), GET_NEWF(sramCtx, this->buttonIndex, 3),
|
||||
GET_NEWF(sramCtx, this->buttonIndex, 4), GET_NEWF(sramCtx, this->buttonIndex, 5));
|
||||
|
||||
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
|
||||
if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
this->configMode = CM_ROTATE_TO_NAME_ENTRY;
|
||||
this->kbdButton = FS_KBD_BTN_NONE;
|
||||
|
@ -199,16 +189,14 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
|
|||
this->newFileNameCharCount = 0;
|
||||
this->nameEntryBoxPosX = 120;
|
||||
this->nameEntryBoxAlpha = 0;
|
||||
memcpy(&this->fileNames[this->buttonIndex][0], &emptyName, 8);
|
||||
} else if (this->n64ddFlags[this->buttonIndex] == this->n64ddFlag) {
|
||||
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, &emptyName, 8);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
this->actionTimer = 8;
|
||||
this->selectMode = SM_FADE_MAIN_TO_SELECT;
|
||||
this->selectedFileIndex = this->buttonIndex;
|
||||
this->menuMode = FS_MENU_MODE_SELECT;
|
||||
this->nextTitleLabel = FS_TITLE_OPEN_FILE;
|
||||
} else if (!this->n64ddFlags[this->buttonIndex]) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
} else {
|
||||
if (this->warningLabel == FS_WARNING_NONE) {
|
||||
|
@ -254,11 +242,12 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
|
|||
}
|
||||
|
||||
if (this->buttonIndex == FS_BTN_MAIN_COPY) {
|
||||
if (!SLOT_OCCUPIED(sramCtx, 0) && !SLOT_OCCUPIED(sramCtx, 1) && !SLOT_OCCUPIED(sramCtx, 2)) {
|
||||
if (!Save_GetSaveMetaInfo(0)->valid && !Save_GetSaveMetaInfo(1)->valid && !Save_GetSaveMetaInfo(2)->valid) {
|
||||
this->warningButtonIndex = this->buttonIndex;
|
||||
this->warningLabel = FS_WARNING_NO_FILE_COPY;
|
||||
this->emptyFileTextAlpha = 255;
|
||||
} else if (SLOT_OCCUPIED(sramCtx, 0) && SLOT_OCCUPIED(sramCtx, 1) && SLOT_OCCUPIED(sramCtx, 2)) {
|
||||
} else if (Save_GetSaveMetaInfo(0)->valid && Save_GetSaveMetaInfo(1)->valid &&
|
||||
Save_GetSaveMetaInfo(2)->valid) {
|
||||
this->warningButtonIndex = this->buttonIndex;
|
||||
this->warningLabel = FS_WARNING_NO_EMPTY_FILES;
|
||||
this->emptyFileTextAlpha = 255;
|
||||
|
@ -266,7 +255,7 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
|
|||
this->warningLabel = FS_WARNING_NONE;
|
||||
}
|
||||
} else if (this->buttonIndex == FS_BTN_MAIN_ERASE) {
|
||||
if (!SLOT_OCCUPIED(sramCtx, 0) && !SLOT_OCCUPIED(sramCtx, 1) && !SLOT_OCCUPIED(sramCtx, 2)) {
|
||||
if (!Save_GetSaveMetaInfo(0)->valid && !Save_GetSaveMetaInfo(1)->valid && !Save_GetSaveMetaInfo(2)->valid) {
|
||||
this->warningButtonIndex = this->buttonIndex;
|
||||
this->warningLabel = FS_WARNING_NO_FILE_ERASE;
|
||||
this->emptyFileTextAlpha = 255;
|
||||
|
@ -379,48 +368,6 @@ void FileChoose_PulsateCursor(GameState* thisx) {
|
|||
static s16 cursorAlphaTargets[] = { 70, 200 };
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
s16 alphaStep;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
Input* debugInput = &this->state.input[2];
|
||||
|
||||
if (CHECK_BTN_ALL(debugInput->press.button, BTN_DLEFT)) {
|
||||
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_ENG;
|
||||
*((u8*)0x80000002) = LANGUAGE_ENG;
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
|
||||
osSyncPrintf("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
|
||||
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
|
||||
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
|
||||
osSyncPrintf("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
|
||||
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
|
||||
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
|
||||
} else if (CHECK_BTN_ALL(debugInput->press.button, BTN_DUP)) {
|
||||
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_GER;
|
||||
*((u8*)0x80000002) = LANGUAGE_GER;
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
|
||||
osSyncPrintf("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
|
||||
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
|
||||
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
|
||||
osSyncPrintf("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
|
||||
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
|
||||
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
|
||||
} else if (CHECK_BTN_ALL(debugInput->press.button, BTN_DRIGHT)) {
|
||||
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_FRA;
|
||||
*((u8*)0x80000002) = LANGUAGE_FRA;
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, 3, OS_WRITE);
|
||||
osSyncPrintf("1:read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
|
||||
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
|
||||
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
|
||||
osSyncPrintf("read_buff[]=%x, %x, %x, %x\n", sramCtx->readBuff[SRAM_HEADER_SOUND],
|
||||
sramCtx->readBuff[SRAM_HEADER_ZTARGET], sramCtx->readBuff[SRAM_HEADER_LANGUAGE],
|
||||
sramCtx->readBuff[SRAM_HEADER_MAGIC]);
|
||||
}
|
||||
|
||||
alphaStep = ABS(this->highlightColor[3] - cursorAlphaTargets[this->highlightPulseDir]) / XREG(35);
|
||||
|
||||
|
@ -510,7 +457,6 @@ void FileChoose_SetWindowContentVtx(GameState* thisx) {
|
|||
s16 phi_a1;
|
||||
s16 phi_ra;
|
||||
s16 temp_t1;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
|
||||
this->windowContentVtx = Graph_Alloc(this->state.gfxCtx, 0x288 * sizeof(Vtx));
|
||||
|
||||
|
@ -648,7 +594,7 @@ void FileChoose_SetWindowContentVtx(GameState* thisx) {
|
|||
phi_ra = 0x2C;
|
||||
|
||||
for (phi_t5 = 0; phi_t5 < 3; phi_t5++, phi_ra -= WREG(38)) {
|
||||
if (SLOT_OCCUPIED(sramCtx, phi_t5)) {
|
||||
if (Save_GetSaveMetaInfo(phi_t5)->valid) {
|
||||
phi_t0 = this->windowPosX - WREG(39);
|
||||
|
||||
if ((this->configMode == 0xF) && (phi_t5 == this->copyDestFileIndex)) {
|
||||
|
@ -822,8 +768,9 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
|
|||
sNamePrimColors[isActive][2], this->nameAlpha[fileIndex]);
|
||||
|
||||
for (i = 0, vtxOffset = 0; vtxOffset < 0x20; i++, vtxOffset += 4) {
|
||||
FileChoose_DrawCharacter(this->state.gfxCtx,
|
||||
sp54->fontBuf + this->fileNames[fileIndex][i] * FONT_CHAR_TEX_SIZE, vtxOffset);
|
||||
FileChoose_DrawCharacter(
|
||||
this->state.gfxCtx, sp54->fontBuf + Save_GetSaveMetaInfo(fileIndex)->playerName[i] * FONT_CHAR_TEX_SIZE,
|
||||
vtxOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -834,7 +781,8 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
|
|||
gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 255, 255, 255, this->fileInfoAlpha[fileIndex]);
|
||||
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex]] + 0x24, 12, 0);
|
||||
|
||||
FileChoose_SplitNumber(this->deaths[fileIndex], &deathCountSplit[0], &deathCountSplit[1], &deathCountSplit[2]);
|
||||
FileChoose_SplitNumber(Save_GetSaveMetaInfo(fileIndex)->deaths, &deathCountSplit[0], &deathCountSplit[1],
|
||||
&deathCountSplit[2]);
|
||||
|
||||
// draw death count
|
||||
for (i = 0, vtxOffset = 0; i < 3; i++, vtxOffset += 4) {
|
||||
|
@ -844,7 +792,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
|
|||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
|
||||
heartType = (this->defense[fileIndex] == 0) ? 0 : 1;
|
||||
heartType = (Save_GetSaveMetaInfo(fileIndex)->defense == 0) ? 0 : 1;
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
|
||||
|
@ -854,7 +802,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
|
|||
gDPSetEnvColor(POLY_OPA_DISP++, sHeartEnvColors[heartType][0], sHeartEnvColors[heartType][1],
|
||||
sHeartEnvColors[heartType][2], 255);
|
||||
|
||||
i = this->healthCapacities[fileIndex] / 0x10;
|
||||
i = Save_GetSaveMetaInfo(fileIndex)->healthCapacity / 0x10;
|
||||
|
||||
// draw hearts
|
||||
for (vtxOffset = 0, j = 0; j < i; j++, vtxOffset += 4) {
|
||||
|
@ -867,7 +815,7 @@ void FileChoose_DrawFileInfo(GameState* thisx, s16 fileIndex, s16 isActive) {
|
|||
|
||||
// draw quest items
|
||||
for (vtxOffset = 0, j = 0; j < 9; j++, vtxOffset += 4) {
|
||||
if (this->questItems[fileIndex] & gBitFlags[sQuestItemFlags[j]]) {
|
||||
if (Save_GetSaveMetaInfo(fileIndex)->questItems & gBitFlags[sQuestItemFlags[j]]) {
|
||||
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[D_8081284C[fileIndex] + vtxOffset] + 0x80, 4, 0);
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, sQuestItemRed[j], sQuestItemGreen[j], sQuestItemBlue[j],
|
||||
|
@ -976,8 +924,14 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
|||
// draw file info box (large box when a file is selected)
|
||||
for (fileIndex = 0; fileIndex < 3; fileIndex++, temp += 20) {
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->fileInfoAlpha[fileIndex]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->fileInfoAlpha[fileIndex]);
|
||||
}
|
||||
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 20, 0);
|
||||
|
||||
for (quadVtxIndex = 0, i = 0; i < 5; i++, quadVtxIndex += 4) {
|
||||
|
@ -992,27 +946,46 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
|||
// draw file button
|
||||
gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 20, 0);
|
||||
|
||||
isActive = ((this->n64ddFlag == this->n64ddFlags[i]) || (this->nameBoxAlpha[i] == 0)) ? 0 : 1;
|
||||
isActive = ((this->n64ddFlag == Save_GetSaveMetaInfo(i)->n64ddFlag) || (this->nameBoxAlpha[i] == 0)) ? 0 : 1;
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->fileButtonAlpha[i]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
|
||||
sWindowContentColors[isActive][2], this->fileButtonAlpha[i]);
|
||||
}
|
||||
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
|
||||
sWindowContentColors[isActive][2], this->fileButtonAlpha[i]);
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, sFileButtonTextures[gSaveContext.language][i], G_IM_FMT_IA, G_IM_SIZ_16b,
|
||||
64, 16, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
G_TX_NOLOD, G_TX_NOLOD);
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
|
||||
|
||||
// draw file name box
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
|
||||
sWindowContentColors[isActive][2], this->nameBoxAlpha[i]);
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->nameBoxAlpha[i]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
|
||||
sWindowContentColors[isActive][2], this->nameBoxAlpha[i]);
|
||||
}
|
||||
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelNameBoxTex, G_IM_FMT_IA, G_IM_SIZ_16b, 108, 16, 0,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 4, 6, 7, 5, 0);
|
||||
|
||||
// draw disk label for 64DD
|
||||
if (this->n64ddFlags[i]) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
|
||||
sWindowContentColors[isActive][2], this->nameAlpha[i]);
|
||||
if (Save_GetSaveMetaInfo(i)->n64ddFlag) {
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 0),
|
||||
CVar_GetS32("gCCFileChoosePrimG", 200), CVar_GetS32("gCCFileChoosePrimB", 255),
|
||||
this->nameAlpha[i]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0],
|
||||
sWindowContentColors[isActive][1], sWindowContentColors[isActive][2],
|
||||
this->nameAlpha[i]);
|
||||
}
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelDISKButtonTex, G_IM_FMT_IA, G_IM_SIZ_16b, 44, 16, 0,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
@ -1020,21 +993,27 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
|||
}
|
||||
|
||||
// draw connectors
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
|
||||
sWindowContentColors[isActive][2], this->connectorAlpha[i]);
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100),
|
||||
CVar_GetS32("gCCFileChoosePrimG", 150), CVar_GetS32("gCCFileChoosePrimB", 255),
|
||||
this->connectorAlpha[i]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1],
|
||||
sWindowContentColors[isActive][2], this->connectorAlpha[i]);
|
||||
}
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelConnectorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 24, 16, 0,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 12, 14, 15, 13, 0);
|
||||
|
||||
if (this->n64ddFlags[i]) {
|
||||
if (Save_GetSaveMetaInfo(i)->n64ddFlag) {
|
||||
gSP1Quadrangle(POLY_OPA_DISP++, 16, 18, 19, 17, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// draw file info
|
||||
for (fileIndex = 0; fileIndex < 3; fileIndex++) {
|
||||
isActive = ((this->n64ddFlag == this->n64ddFlags[fileIndex]) || (this->nameBoxAlpha[fileIndex] == 0)) ? 0 : 1;
|
||||
isActive = ((this->n64ddFlag == Save_GetSaveMetaInfo(fileIndex)->n64ddFlag) || (this->nameBoxAlpha[fileIndex] == 0)) ? 0 : 1;
|
||||
FileChoose_DrawFileInfo(&this->state, fileIndex, isActive);
|
||||
}
|
||||
|
||||
|
@ -1047,8 +1026,14 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
|||
// draw primary action buttons (copy/erase)
|
||||
for (quadVtxIndex = 0, i = 0; i < 2; i++, quadVtxIndex += 4) {
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->actionButtonAlpha[i]);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->actionButtonAlpha[i]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->actionButtonAlpha[i]);
|
||||
}
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, sActionButtonTextures[gSaveContext.language][i], G_IM_FMT_IA, G_IM_SIZ_16b,
|
||||
64, 16, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
@ -1061,8 +1046,13 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
|||
for (quadVtxIndex = 0, i = 0; i < 2; i++, quadVtxIndex += 4) {
|
||||
temp = this->confirmButtonTexIndices[i];
|
||||
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->confirmButtonAlpha[i]);
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->confirmButtonAlpha[i]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->confirmButtonAlpha[i]);
|
||||
}
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, sActionButtonTextures[gSaveContext.language][temp], G_IM_FMT_IA,
|
||||
G_IM_SIZ_16b, 64, 16, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
|
||||
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
@ -1071,8 +1061,14 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
|||
|
||||
// draw options button
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->optionButtonAlpha);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->optionButtonAlpha);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->optionButtonAlpha);
|
||||
}
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, sOptionsButtonTextures[gSaveContext.language], G_IM_FMT_IA, G_IM_SIZ_16b, 64,
|
||||
16, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
@ -1087,8 +1083,15 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
|
|||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineLERP(POLY_OPA_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0,
|
||||
PRIMITIVE, 0);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->highlightColor[0], this->highlightColor[1],
|
||||
this->highlightColor[2], this->highlightColor[3]);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 155),
|
||||
CVar_GetS32("gCCFileChoosePrimG", 255), CVar_GetS32("gCCFileChoosePrimB", 255),
|
||||
this->highlightColor[3]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->highlightColor[0], this->highlightColor[1],
|
||||
this->highlightColor[2], this->highlightColor[3]);
|
||||
}
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelBigButtonHighlightTex, G_IM_FMT_I, G_IM_SIZ_8b, 72, 24, 0,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
|
@ -1143,8 +1146,14 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
|
|||
if ((this->configMode != CM_NAME_ENTRY) && (this->configMode != CM_START_NAME_ENTRY)) {
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->windowAlpha);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
}
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
|
||||
|
||||
Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
|
||||
|
@ -1175,8 +1184,14 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
|
|||
if ((this->configMode >= CM_ROTATE_TO_NAME_ENTRY) && (this->configMode <= CM_NAME_ENTRY_TO_MAIN)) {
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->windowAlpha);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
}
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
|
||||
|
||||
Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
|
||||
|
@ -1203,8 +1218,14 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
|
|||
if ((this->configMode >= CM_MAIN_TO_OPTIONS) && (this->configMode <= CM_OPTIONS_TO_MAIN)) {
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->windowAlpha);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
}
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
|
||||
|
||||
Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
|
||||
|
@ -1242,7 +1263,6 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_FadeMainToSelect(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
|
@ -1251,7 +1271,7 @@ void FileChoose_FadeMainToSelect(GameState* thisx) {
|
|||
this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
|
||||
this->optionButtonAlpha = this->fileButtonAlpha[i];
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->nameAlpha[i] = this->nameBoxAlpha[i] = this->fileButtonAlpha[i];
|
||||
this->connectorAlpha[i] -= 31;
|
||||
}
|
||||
|
@ -1372,7 +1392,6 @@ void FileChoose_FadeOutFileInfo(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_MoveSelectedFileToSlot(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 yStep;
|
||||
s16 i;
|
||||
|
||||
|
@ -1394,7 +1413,7 @@ void FileChoose_MoveSelectedFileToSlot(GameState* thisx) {
|
|||
this->actionButtonAlpha[FS_BTN_ACTION_COPY] = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] =
|
||||
this->optionButtonAlpha = this->fileButtonAlpha[i];
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
this->connectorAlpha[i] += 31;
|
||||
}
|
||||
|
@ -1445,14 +1464,14 @@ void FileChoose_LoadGame(GameState* thisx) {
|
|||
if (this->buttonIndex == FS_BTN_SELECT_FILE_1 && CVar_GetS32("gDebugEnabled", 0)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
gSaveContext.fileNum = this->buttonIndex;
|
||||
Sram_OpenSave(&this->sramCtx);
|
||||
Sram_OpenSave();
|
||||
gSaveContext.gameMode = 0;
|
||||
SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext);
|
||||
this->state.running = false;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
gSaveContext.fileNum = this->buttonIndex;
|
||||
Sram_OpenSave(&this->sramCtx);
|
||||
Sram_OpenSave();
|
||||
gSaveContext.gameMode = 0;
|
||||
SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext);
|
||||
this->state.running = false;
|
||||
|
@ -1555,8 +1574,14 @@ void FileChoose_SelectModeDraw(GameState* thisx) {
|
|||
FileChoose_SetWindowContentVtx(&this->state);
|
||||
|
||||
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), this->windowAlpha);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->windowAlpha);
|
||||
}
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
|
||||
|
||||
Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW);
|
||||
|
@ -1601,6 +1626,10 @@ void FileChoose_Main(GameState* thisx) {
|
|||
};
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
Input* input = &this->state.input[0];
|
||||
|
||||
if (CVar_GetS32("gTimeFlowFileSelect", 0) != 0) {
|
||||
gSaveContext.skyboxTime += 0x10;
|
||||
}
|
||||
|
||||
OPEN_DISPS(this->state.gfxCtx, "../z_file_choose.c", 2898);
|
||||
|
||||
|
@ -1615,6 +1644,52 @@ void FileChoose_Main(GameState* thisx) {
|
|||
this->stickRelX = input->rel.stick_x;
|
||||
this->stickRelY = input->rel.stick_y;
|
||||
|
||||
if (CVar_GetS32("gDpadHoldChange", 1) && CVar_GetS32("gDpadPauseName", 0)) {
|
||||
if (CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) {
|
||||
this->inputTimerX = 10;
|
||||
this->stickXDir = -1;
|
||||
} else if (--(this->inputTimerX) < 0) {
|
||||
this->inputTimerX = XREG(6);
|
||||
input->press.button |= BTN_DLEFT;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DLEFT)) {
|
||||
this->stickXDir = 0;
|
||||
} else if (CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) {
|
||||
this->inputTimerX = 10;
|
||||
this->stickXDir = 1;
|
||||
} else if (--(this->inputTimerX) < 0) {
|
||||
this->inputTimerX = XREG(6);
|
||||
input->press.button |= BTN_DRIGHT;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DRIGHT)) {
|
||||
this->stickXDir = 0;
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(input->cur.button, BTN_DDOWN)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
|
||||
this->inputTimerY = 10;
|
||||
this->stickYDir = -1;
|
||||
} else if (--(this->inputTimerY) < 0) {
|
||||
this->inputTimerY = XREG(6);
|
||||
input->press.button |= BTN_DDOWN;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DDOWN)) {
|
||||
this->stickYDir = 0;
|
||||
} else if (CHECK_BTN_ALL(input->cur.button, BTN_DUP)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) {
|
||||
this->inputTimerY = 10;
|
||||
this->stickYDir = -1;
|
||||
} else if (--(this->inputTimerY) < 0) {
|
||||
this->inputTimerY = XREG(6);
|
||||
input->press.button |= BTN_DUP;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DUP)) {
|
||||
this->stickYDir = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->stickRelX < -30) {
|
||||
if (this->stickXDir == -1) {
|
||||
this->inputTimerX--;
|
||||
|
@ -1645,7 +1720,7 @@ void FileChoose_Main(GameState* thisx) {
|
|||
|
||||
if (this->stickRelY < -30) {
|
||||
if (this->stickYDir == -1) {
|
||||
this->inputTimerY -= 1;
|
||||
this->inputTimerY--;
|
||||
if (this->inputTimerY < 0) {
|
||||
this->inputTimerY = 2;
|
||||
} else {
|
||||
|
@ -1657,7 +1732,7 @@ void FileChoose_Main(GameState* thisx) {
|
|||
}
|
||||
} else if (this->stickRelY > 30) {
|
||||
if (this->stickYDir == 1) {
|
||||
this->inputTimerY -= 1;
|
||||
this->inputTimerY--;
|
||||
if (this->inputTimerY < 0) {
|
||||
this->inputTimerY = 2;
|
||||
} else {
|
||||
|
@ -1685,7 +1760,14 @@ void FileChoose_Main(GameState* thisx) {
|
|||
|
||||
gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
|
||||
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 100, 255, 255, this->controlsAlpha);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChooseTextPrimR", 0),
|
||||
CVar_GetS32("gCCFileChooseTextPrimG", 100), CVar_GetS32("gCCFileChooseTextPrimB", 255),
|
||||
this->controlsAlpha);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 100, 255, 255, this->controlsAlpha);
|
||||
}
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, controlsTextures[gSaveContext.language], G_IM_FMT_IA, G_IM_SIZ_8b, 144, 16,
|
||||
0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
|
@ -1704,9 +1786,6 @@ void FileChoose_Main(GameState* thisx) {
|
|||
void FileChoose_InitContext(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
EnvironmentContext* envCtx = &this->envCtx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
|
||||
Sram_Alloc(&this->state, sramCtx);
|
||||
|
||||
ZREG(7) = 32;
|
||||
ZREG(8) = 22;
|
||||
|
@ -1859,17 +1938,6 @@ void FileChoose_InitContext(GameState* thisx) {
|
|||
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
|
||||
gSaveContext.buttonStatus[3] = gSaveContext.buttonStatus[4] = BTN_ENABLED;
|
||||
|
||||
this->n64ddFlags[0] = this->n64ddFlags[1] = this->n64ddFlags[2] = this->defense[0] = this->defense[1] =
|
||||
this->defense[2] = 0;
|
||||
|
||||
SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ);
|
||||
|
||||
gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE];
|
||||
|
||||
if (gSaveContext.language >= LANGUAGE_MAX) {
|
||||
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language = LANGUAGE_ENG;
|
||||
}
|
||||
}
|
||||
|
||||
void FileChoose_Destroy(GameState* thisx) {
|
||||
|
|
|
@ -60,7 +60,6 @@ void FileChoose_SetupCopySource(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_SelectCopySource(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
Input* input = &this->state.input[0];
|
||||
bool dpad = CVar_GetS32("gDpadPauseName", 0);
|
||||
|
||||
|
@ -73,7 +72,7 @@ void FileChoose_SelectCopySource(GameState* thisx) {
|
|||
this->warningLabel = FS_WARNING_NONE;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
|
||||
if (SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
|
||||
if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
|
||||
this->actionTimer = 8;
|
||||
this->selectedFileIndex = this->buttonIndex;
|
||||
this->configMode = CM_SETUP_COPY_DEST_1;
|
||||
|
@ -102,7 +101,7 @@ void FileChoose_SelectCopySource(GameState* thisx) {
|
|||
}
|
||||
|
||||
if (this->buttonIndex != FS_BTN_COPY_QUIT) {
|
||||
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
|
||||
if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
|
||||
this->warningLabel = FS_WARNING_FILE_EMPTY;
|
||||
this->warningButtonIndex = this->buttonIndex;
|
||||
this->emptyFileTextAlpha = 255;
|
||||
|
@ -173,7 +172,6 @@ void FileChoose_SetupCopyDest2(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_SelectCopyDest(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
Input* input = &this->state.input[0];
|
||||
bool dpad = CVar_GetS32("gDpadPauseName", 0);
|
||||
|
||||
|
@ -185,7 +183,7 @@ void FileChoose_SelectCopyDest(GameState* thisx) {
|
|||
this->configMode = CM_EXIT_TO_COPY_SOURCE_1;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
|
||||
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
|
||||
if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
|
||||
this->copyDestFileIndex = this->buttonIndex;
|
||||
this->nextTitleLabel = FS_TITLE_COPY_CONFIRM;
|
||||
this->actionTimer = 8;
|
||||
|
@ -227,7 +225,7 @@ void FileChoose_SelectCopyDest(GameState* thisx) {
|
|||
}
|
||||
|
||||
if (this->buttonIndex != FS_BTN_COPY_QUIT) {
|
||||
if (SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
|
||||
if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
|
||||
this->warningLabel = FS_WARNING_FILE_IN_USE;
|
||||
this->warningButtonIndex = this->buttonIndex;
|
||||
this->emptyFileTextAlpha = 255;
|
||||
|
@ -264,7 +262,6 @@ void FileChoose_ExitToCopySource1(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_ExitToCopySource2(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
s16 yStep;
|
||||
|
||||
|
@ -298,7 +295,6 @@ void FileChoose_ExitToCopySource2(GameState* thisx) {
|
|||
void FileChoose_SetupCopyConfirm1(GameState* thisx) {
|
||||
static s16 D_808124A4[] = { -56, -40, -24, 0 };
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
s16 yStep;
|
||||
|
||||
|
@ -309,7 +305,7 @@ void FileChoose_SetupCopyConfirm1(GameState* thisx) {
|
|||
if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) {
|
||||
this->fileButtonAlpha[i] -= 25;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->connectorAlpha[i] -= 31;
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
}
|
||||
|
@ -359,7 +355,6 @@ void FileChoose_SetupCopyConfirm2(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_CopyConfirm(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
Input* input = &this->state.input[0];
|
||||
u16 dayTime;
|
||||
bool dpad = CVar_GetS32("gDpadPauseName", 0);
|
||||
|
@ -372,7 +367,7 @@ void FileChoose_CopyConfirm(GameState* thisx) {
|
|||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
|
||||
dayTime = gSaveContext.dayTime;
|
||||
Sram_CopySave(this, sramCtx);
|
||||
Save_CopyFile(this->selectedFileIndex, this->copyDestFileIndex);
|
||||
gSaveContext.dayTime = dayTime;
|
||||
this->fileInfoAlpha[this->copyDestFileIndex] = this->nameAlpha[this->copyDestFileIndex] = 0;
|
||||
this->nextTitleLabel = FS_TITLE_COPY_COMPLETE;
|
||||
|
@ -392,7 +387,6 @@ void FileChoose_CopyConfirm(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_ReturnToCopyDest(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
s16 yStep;
|
||||
|
||||
|
@ -404,7 +398,7 @@ void FileChoose_ReturnToCopyDest(GameState* thisx) {
|
|||
if ((i != this->copyDestFileIndex) && (i != this->selectedFileIndex)) {
|
||||
this->fileButtonAlpha[i] += 25;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
this->connectorAlpha[i] += 31;
|
||||
}
|
||||
|
@ -535,7 +529,6 @@ void FileChoose_CopyAnim4(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_CopyAnim5(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
s16 yStep;
|
||||
|
||||
|
@ -553,7 +546,7 @@ void FileChoose_CopyAnim5(GameState* thisx) {
|
|||
if (i != this->buttonIndex) {
|
||||
this->fileButtonAlpha[i] += 25;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
this->connectorAlpha[i] += 31;
|
||||
}
|
||||
|
@ -572,7 +565,7 @@ void FileChoose_CopyAnim5(GameState* thisx) {
|
|||
this->fileButtonAlpha[i] = 200;
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->connectorAlpha[i];
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->connectorAlpha[i] = 255;
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
}
|
||||
|
@ -681,7 +674,6 @@ void FileChoose_SetupEraseSelect(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_EraseSelect(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
Input* input = &this->state.input[0];
|
||||
bool dpad = CVar_GetS32("gDpadPauseName", 0);
|
||||
|
||||
|
@ -694,7 +686,7 @@ void FileChoose_EraseSelect(GameState* thisx) {
|
|||
this->warningLabel = FS_WARNING_NONE;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
|
||||
if (SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
|
||||
if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
|
||||
this->actionTimer = 8;
|
||||
this->selectedFileIndex = this->buttonIndex;
|
||||
this->configMode = CM_SETUP_ERASE_CONFIRM_1;
|
||||
|
@ -721,7 +713,7 @@ void FileChoose_EraseSelect(GameState* thisx) {
|
|||
}
|
||||
|
||||
if (this->buttonIndex != FS_BTN_ERASE_QUIT) {
|
||||
if (!SLOT_OCCUPIED(sramCtx, this->buttonIndex)) {
|
||||
if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) {
|
||||
this->warningLabel = FS_WARNING_FILE_EMPTY;
|
||||
this->warningButtonIndex = this->buttonIndex;
|
||||
this->emptyFileTextAlpha = 255;
|
||||
|
@ -741,7 +733,6 @@ void FileChoose_EraseSelect(GameState* thisx) {
|
|||
void FileChoose_SetupEraseConfirm1(GameState* thisx) {
|
||||
static s16 D_808124AC[] = { 0, 16, 32 };
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
s16 yStep;
|
||||
|
||||
|
@ -749,7 +740,7 @@ void FileChoose_SetupEraseConfirm1(GameState* thisx) {
|
|||
if (i != this->buttonIndex) {
|
||||
this->fileButtonAlpha[i] -= 25;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->connectorAlpha[i] -= 31;
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
}
|
||||
|
@ -775,7 +766,7 @@ void FileChoose_SetupEraseConfirm1(GameState* thisx) {
|
|||
if (i != this->buttonIndex) {
|
||||
this->fileButtonAlpha[i] = 0;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->connectorAlpha[i] = 0;
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i] = 0;
|
||||
}
|
||||
|
@ -831,7 +822,7 @@ void FileChoose_EraseConfirm(GameState* thisx) {
|
|||
this->actionTimer = 8;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) {
|
||||
this->n64ddFlags[this->selectedFileIndex] = this->connectorAlpha[this->selectedFileIndex] = 0;
|
||||
Save_GetSaveMetaInfo(this->selectedFileIndex)->n64ddFlag = this->connectorAlpha[this->selectedFileIndex] = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
this->actionTimer = 8;
|
||||
this->configMode = CM_ERASE_ANIM_1;
|
||||
|
@ -869,7 +860,6 @@ void FileChoose_ExitToEraseSelect1(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_ExitToEraseSelect2(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
s16 yStep;
|
||||
|
||||
|
@ -885,7 +875,7 @@ void FileChoose_ExitToEraseSelect2(GameState* thisx) {
|
|||
if (i != this->buttonIndex) {
|
||||
this->fileButtonAlpha[i] += 25;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
this->connectorAlpha[i] += 31;
|
||||
}
|
||||
|
@ -915,7 +905,6 @@ void FileChoose_ExitToEraseSelect2(GameState* thisx) {
|
|||
void FileChoose_EraseAnim1(GameState* thisx) {
|
||||
static s16 D_80813800;
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
|
||||
if (sEraseDelayTimer == 0) {
|
||||
if (this->actionTimer == 8) {
|
||||
|
@ -935,7 +924,7 @@ void FileChoose_EraseAnim1(GameState* thisx) {
|
|||
D_80813800 += 2;
|
||||
|
||||
if (this->actionTimer == 0) {
|
||||
Sram_EraseSave(this, sramCtx);
|
||||
Save_DeleteFile(this->selectedFileIndex);
|
||||
this->titleLabel = this->nextTitleLabel;
|
||||
this->titleAlpha[0] = 255;
|
||||
this->titleAlpha[1] = this->connectorAlpha[this->selectedFileIndex] = 0;
|
||||
|
@ -981,7 +970,6 @@ void FileChoose_EraseAnim2(GameState* thisx) {
|
|||
*/
|
||||
void FileChoose_EraseAnim3(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
s16 i;
|
||||
s16 yStep;
|
||||
|
||||
|
@ -998,7 +986,7 @@ void FileChoose_EraseAnim3(GameState* thisx) {
|
|||
for (i = 0; i < 3; i++) {
|
||||
this->fileButtonAlpha[i] += 25;
|
||||
|
||||
if (SLOT_OCCUPIED(sramCtx, i)) {
|
||||
if (Save_GetSaveMetaInfo(i)->valid) {
|
||||
this->nameBoxAlpha[i] = this->nameAlpha[i] = this->fileButtonAlpha[i];
|
||||
this->connectorAlpha[i] += 31;
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
|
|||
s16 phi_t1;
|
||||
u8 temp;
|
||||
s16 phi_v0;
|
||||
char* filename = Save_GetSaveMetaInfo(this->buttonIndex)->playerName;
|
||||
|
||||
if (1) {}
|
||||
if (1) {}
|
||||
|
@ -133,7 +134,14 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
|
|||
|
||||
phi_s0 = 0x10;
|
||||
for (phi_t1 = 0; phi_t1 < 2; phi_t1++, phi_s0 += 4) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2], 255);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100), CVar_GetS32("gCCFileChoosePrimG", 150),
|
||||
CVar_GetS32("gCCFileChoosePrimB", 255), 255);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
255);
|
||||
}
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, sBackspaceEndTextures[gSaveContext.language][phi_t1], G_IM_FMT_IA,
|
||||
G_IM_SIZ_16b, sBackspaceEndWidths[phi_t1], 16, 0, G_TX_NOMIRROR | G_TX_WRAP,
|
||||
|
@ -145,7 +153,7 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
|
|||
|
||||
for (phi_s0 = 0, phi_t1 = 0; phi_t1 < 44; phi_t1 += 4, phi_s0++) {
|
||||
if ((phi_s0 > 0) && (phi_s0 < 9)) {
|
||||
temp = this->fileNames[this->buttonIndex][phi_s0 - 1];
|
||||
temp = filename[phi_s0 - 1];
|
||||
|
||||
this->nameEntryVtx[phi_t1].v.ob[0] = this->nameEntryVtx[phi_t1 + 2].v.ob[0] =
|
||||
D_808125EC[phi_s0] + this->nameEntryBoxPosX + D_808124C0[temp];
|
||||
|
@ -195,8 +203,15 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
|
|||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE,
|
||||
ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->nameEntryBoxAlpha);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100),
|
||||
CVar_GetS32("gCCFileChoosePrimG", 150), CVar_GetS32("gCCFileChoosePrimB", 255),
|
||||
this->nameEntryBoxAlpha);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2],
|
||||
this->nameEntryBoxAlpha);
|
||||
}
|
||||
gSPVertex(POLY_OPA_DISP++, this->nameEntryVtx, 4, 0);
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelNameBoxTex, G_IM_FMT_IA, G_IM_SIZ_16b, 108, 16, 0,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
|
@ -209,8 +224,7 @@ void FileChoose_SetNameEntryVtx(GameState* thisx) {
|
|||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->nameEntryBoxAlpha);
|
||||
|
||||
for (phi_v0 = 0, phi_s0 = 0; phi_s0 < 0x20; phi_s0 += 4, phi_v0++) {
|
||||
FileChoose_DrawCharacter(this->state.gfxCtx,
|
||||
font->fontBuf + this->fileNames[this->buttonIndex][phi_v0] * FONT_CHAR_TEX_SIZE,
|
||||
FileChoose_DrawCharacter(this->state.gfxCtx, font->fontBuf + filename[phi_v0] * FONT_CHAR_TEX_SIZE,
|
||||
phi_s0);
|
||||
}
|
||||
|
||||
|
@ -267,6 +281,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
s16 tmp;
|
||||
u16 dayTime;
|
||||
s16 validName;
|
||||
char* filename = Save_GetSaveMetaInfo(this->buttonIndex)->playerName;
|
||||
|
||||
OPEN_DISPS(this->state.gfxCtx, "../z_file_nameset_PAL.c", 368);
|
||||
|
||||
|
@ -318,8 +333,15 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineLERP(POLY_OPA_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, 0,
|
||||
PRIMITIVE, 0);
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->highlightColor[0], this->highlightColor[1], this->highlightColor[2],
|
||||
this->highlightColor[3]);
|
||||
|
||||
if (CVar_GetS32("gHudColors", 1) == 2) {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, CVar_GetS32("gCCFileChoosePrimR", 100),
|
||||
CVar_GetS32("gCCFileChoosePrimG", 150), CVar_GetS32("gCCFileChoosePrimB", 255),
|
||||
this->highlightColor[3]);
|
||||
} else {
|
||||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->highlightColor[0], this->highlightColor[1],
|
||||
this->highlightColor[2], this->highlightColor[3]);
|
||||
}
|
||||
gDPLoadTextureBlock(POLY_OPA_DISP++, gFileSelCharHighlightTex, G_IM_FMT_I, G_IM_SIZ_8b, 24, 24, 0,
|
||||
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
|
@ -354,12 +376,12 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
this->kbdY = 5;
|
||||
this->kbdX = 4;
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||
if ((this->newFileNameCharCount == 7) && (this->fileNames[this->buttonIndex][7] != 0x3E)) {
|
||||
if ((this->newFileNameCharCount == 7) && (filename[7] != 0x3E)) {
|
||||
for (i = this->newFileNameCharCount; i < 7; i++) {
|
||||
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
|
||||
filename[i] = filename[i + 1];
|
||||
}
|
||||
|
||||
this->fileNames[this->buttonIndex][i] = 0x3E;
|
||||
filename[i] = 0x3E;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else {
|
||||
this->newFileNameCharCount--;
|
||||
|
@ -369,10 +391,10 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
this->configMode = CM_NAME_ENTRY_TO_MAIN;
|
||||
} else {
|
||||
for (i = this->newFileNameCharCount; i < 7; i++) {
|
||||
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
|
||||
filename[i] = filename[i + 1];
|
||||
}
|
||||
|
||||
this->fileNames[this->buttonIndex][i] = 0x3E;
|
||||
filename[i] = 0x3E;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
}
|
||||
|
@ -390,7 +412,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
this->fileNames[this->buttonIndex][this->newFileNameCharCount] = D_808123F0[this->charIndex];
|
||||
filename[this->newFileNameCharCount] = D_808123F0[this->charIndex];
|
||||
this->newFileNameCharCount++;
|
||||
|
||||
if (this->newFileNameCharCount > 7) {
|
||||
|
@ -399,12 +421,12 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
}
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_A) && (this->charPage != this->kbdButton)) {
|
||||
if (this->kbdButton == FS_KBD_BTN_BACKSPACE) {
|
||||
if ((this->newFileNameCharCount == 7) && (this->fileNames[this->buttonIndex][7] != 0x3E)) {
|
||||
if ((this->newFileNameCharCount == 7) && (filename[7] != 0x3E)) {
|
||||
for (i = this->newFileNameCharCount; i < 7; i++) {
|
||||
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
|
||||
filename[i] = filename[i + 1];
|
||||
}
|
||||
|
||||
this->fileNames[this->buttonIndex][i] = 0x3E;
|
||||
filename[i] = 0x3E;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
} else {
|
||||
|
@ -415,10 +437,10 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
}
|
||||
|
||||
for (i = this->newFileNameCharCount; i < 7; i++) {
|
||||
this->fileNames[this->buttonIndex][i] = this->fileNames[this->buttonIndex][i + 1];
|
||||
filename[i] = filename[i + 1];
|
||||
}
|
||||
|
||||
this->fileNames[this->buttonIndex][i] = 0x3E;
|
||||
filename[i] = 0x3E;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
}
|
||||
|
@ -426,7 +448,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
validName = false;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (this->fileNames[this->buttonIndex][i] != 0x3E) {
|
||||
if (filename[i] != 0x3E) {
|
||||
validName = true;
|
||||
break;
|
||||
}
|
||||
|
@ -437,7 +459,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
|
|||
&D_801333E8);
|
||||
gSaveContext.fileNum = this->buttonIndex;
|
||||
dayTime = ((void)0, gSaveContext.dayTime);
|
||||
Sram_InitSave(this, &this->sramCtx);
|
||||
Sram_InitSave(this);
|
||||
gSaveContext.dayTime = dayTime;
|
||||
this->configMode = CM_NAME_ENTRY_TO_MAIN;
|
||||
this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200;
|
||||
|
@ -655,20 +677,15 @@ static u8 sSelectedSetting;
|
|||
*/
|
||||
void FileChoose_UpdateOptionsMenu(GameState* thisx) {
|
||||
FileChooseContext* this = (FileChooseContext*)thisx;
|
||||
SramContext* sramCtx = &this->sramCtx;
|
||||
Input* input = &this->state.input[0];
|
||||
bool dpad = CVar_GetS32("gDpadPauseName", 0);
|
||||
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
this->configMode = CM_OPTIONS_TO_MAIN;
|
||||
sramCtx->readBuff[0] = gSaveContext.audioSetting;
|
||||
sramCtx->readBuff[1] = gSaveContext.zTargetSetting;
|
||||
osSyncPrintf("SAVE");
|
||||
Sram_WriteSramHeader(sramCtx);
|
||||
Save_SaveGlobal();
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
osSyncPrintf("sram->read_buff[2] = J_N = %x\n", sramCtx->readBuff[2]);
|
||||
osSyncPrintf("sram->read_buff[2] = J_N = %x\n", &sramCtx->readBuff[2]);
|
||||
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
|
||||
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
|
||||
osSyncPrintf("Na_SetSoundOutputMode = %d\n", gSaveContext.audioSetting);
|
||||
|
|
|
@ -224,7 +224,7 @@ void Title_Main(GameState* thisx) {
|
|||
|
||||
if (CVar_GetS32("gSkipLogoTitle",0)!=0) {
|
||||
gSaveContext.language = CVar_GetS32("gLanguages", 0);
|
||||
Sram_InitSram(&this->state, &this->sramCtx);
|
||||
Sram_InitSram(&this->state);
|
||||
s16 selectedfile = CVar_GetS32("gSaveFileID", 0);
|
||||
if (selectedfile == 4) {
|
||||
selectedfile = 0xFF;
|
||||
|
@ -242,13 +242,13 @@ void Title_Main(GameState* thisx) {
|
|||
}
|
||||
if (selectedfile == 0xFF) {
|
||||
gSaveContext.fileNum = selectedfile;
|
||||
Sram_OpenSave(&this->sramCtx);
|
||||
Sram_OpenSave();
|
||||
gSaveContext.gameMode = 0;
|
||||
this->state.running = false;
|
||||
SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext);
|
||||
} else {
|
||||
gSaveContext.fileNum = selectedfile;
|
||||
Sram_OpenSave(&this->sramCtx);
|
||||
Sram_OpenSave();
|
||||
gSaveContext.gameMode = 0;
|
||||
this->state.running = false;
|
||||
//return;
|
||||
|
@ -322,7 +322,7 @@ void Title_Main(GameState* thisx) {
|
|||
void Title_Destroy(GameState* thisx) {
|
||||
TitleContext* this = (TitleContext*)thisx;
|
||||
|
||||
Sram_InitSram(&this->state, &this->sramCtx);
|
||||
Sram_InitSram(&this->state);
|
||||
}
|
||||
|
||||
void Title_Init(GameState* thisx) {
|
||||
|
@ -346,7 +346,6 @@ void Title_Init(GameState* thisx) {
|
|||
this->state.destroy = Title_Destroy;
|
||||
this->exit = false;
|
||||
gSaveContext.fileNum = 0xFF;
|
||||
Sram_Alloc(&this->state, &this->sramCtx);
|
||||
this->ult = 0;
|
||||
this->unk_1D4 = 0x14;
|
||||
this->coverAlpha = 255;
|
||||
|
|
|
@ -640,9 +640,13 @@ void KaleidoScope_DrawDebugEditor(GlobalContext* globalCtx) {
|
|||
|
||||
// Handles exiting the inventory editor with the L button
|
||||
// The editor is opened with `debugState` set to 1, and becomes closable after a frame once `debugState` is set to 2
|
||||
s16 Debug_BTN = BTN_L;
|
||||
if (CVar_GetS32("gNGCKaleidoSwitcher", 0) != 0) {
|
||||
Debug_BTN = BTN_Z;
|
||||
}
|
||||
if (pauseCtx->debugState == 1) {
|
||||
pauseCtx->debugState = 2;
|
||||
} else if ((pauseCtx->debugState == 2) && CHECK_BTN_ALL(input->press.button, BTN_L)) {
|
||||
} else if ((pauseCtx->debugState == 2) && CHECK_BTN_ALL(input->press.button, Debug_BTN)) {
|
||||
pauseCtx->debugState = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,8 +98,8 @@ void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) {
|
|||
f32 scale;
|
||||
Input* input = &globalCtx->state.input[0];
|
||||
s16 RotationSpeed = 150 * CVar_GetS32("gPauseLiveLinkRotationSpeed", 0);
|
||||
bool AllowCRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 2) ? true : false;
|
||||
bool AllowDPadRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 1) ? true : false;
|
||||
u8 AllowCRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 2) ? true : false;
|
||||
u8 AllowDPadRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 1) ? true : false;
|
||||
|
||||
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
|
||||
pos.x = 2.0f;
|
||||
|
@ -120,19 +120,19 @@ void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) {
|
|||
|
||||
link_kaleido_rot.x = link_kaleido_rot.z = 0;
|
||||
|
||||
if (AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DLEFT) ||
|
||||
AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CLEFT)) {
|
||||
if ((AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) ||
|
||||
(AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CLEFT))) {
|
||||
link_kaleido_rot.y = link_kaleido_rot.y - RotationSpeed;
|
||||
} else if (AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT) ||
|
||||
AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CRIGHT)) {
|
||||
} else if ((AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) ||
|
||||
(AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CRIGHT))) {
|
||||
link_kaleido_rot.y = link_kaleido_rot.y + RotationSpeed;
|
||||
}
|
||||
|
||||
if (AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DUP) ||
|
||||
AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
|
||||
if ((AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DUP)) ||
|
||||
(AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) {
|
||||
link_kaleido_rot.y = 32300;
|
||||
} else if (AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CUP) ||
|
||||
AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) {
|
||||
} else if ((AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CUP)) ||
|
||||
(AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CDOWN))) {
|
||||
link_kaleido_rot.y = 32300;
|
||||
}
|
||||
|
||||
|
@ -635,7 +635,8 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
|
|||
KaleidoScope_DrawQuadTextureRGBA32(globalCtx->state.gfxCtx, gBiggoronSwordIconTex, 32, 32, point);
|
||||
} else if ((i == 0) && (k == 2) && (gBitFlags[bit + 1] & gSaveContext.inventory.equipment)) {
|
||||
KaleidoScope_DrawQuadTextureRGBA32(globalCtx->state.gfxCtx, gBrokenGiantsKnifeIconTex, 32, 32, point);
|
||||
} else if (gBitFlags[bit] & gSaveContext.inventory.equipment) {
|
||||
}
|
||||
if (gBitFlags[bit] & gSaveContext.inventory.equipment) {
|
||||
int itemId = ITEM_SWORD_KOKIRI + temp;
|
||||
bool not_acquired = (gItemAgeReqs[itemId] != 9) && (gItemAgeReqs[itemId] != gSaveContext.linkAge);
|
||||
if (not_acquired) {
|
||||
|
|
|
@ -930,7 +930,14 @@ void KaleidoScope_SwitchPage(PauseContext* pauseCtx, u8 pt) {
|
|||
}
|
||||
|
||||
void KaleidoScope_HandlePageToggles(PauseContext* pauseCtx, Input* input) {
|
||||
if (CVar_GetS32("gDebugEnabled", 0) && (pauseCtx->debugState == 0) && CHECK_BTN_ALL(input->press.button, BTN_L)) {
|
||||
s16 Debug_BTN = BTN_L;
|
||||
s16 PageLeft_BTN = BTN_Z;
|
||||
if (CVar_GetS32("gNGCKaleidoSwitcher", 0) != 0) {
|
||||
Debug_BTN = BTN_Z;
|
||||
PageLeft_BTN = BTN_L;
|
||||
}
|
||||
|
||||
if (CVar_GetS32("gDebugEnabled", 0) && (pauseCtx->debugState == 0) && CHECK_BTN_ALL(input->press.button, Debug_BTN)) {
|
||||
pauseCtx->debugState = 1;
|
||||
return;
|
||||
}
|
||||
|
@ -940,14 +947,14 @@ void KaleidoScope_HandlePageToggles(PauseContext* pauseCtx, Input* input) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_Z)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, PageLeft_BTN)) {
|
||||
KaleidoScope_SwitchPage(pauseCtx, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
bool dpad = CVar_GetS32("gDpadPauseName", 0);
|
||||
if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) {
|
||||
if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) {
|
||||
if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->cur.button, BTN_DLEFT))) {
|
||||
pauseCtx->pageSwitchTimer++;
|
||||
if ((pauseCtx->pageSwitchTimer >= 10) || (pauseCtx->pageSwitchTimer == 0)) {
|
||||
KaleidoScope_SwitchPage(pauseCtx, 0);
|
||||
|
@ -956,7 +963,7 @@ void KaleidoScope_HandlePageToggles(PauseContext* pauseCtx, Input* input) {
|
|||
pauseCtx->pageSwitchTimer = -1;
|
||||
}
|
||||
} else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT) {
|
||||
if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) {
|
||||
if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT))) {
|
||||
pauseCtx->pageSwitchTimer++;
|
||||
if ((pauseCtx->pageSwitchTimer >= 10) || (pauseCtx->pageSwitchTimer == 0)) {
|
||||
KaleidoScope_SwitchPage(pauseCtx, 2);
|
||||
|
@ -1115,6 +1122,7 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) {
|
|||
static s16 D_8082AD4C = 0;
|
||||
static s16 D_8082AD50 = 0;
|
||||
PauseContext* pauseCtx = &globalCtx->pauseCtx;
|
||||
Input* input = &globalCtx->state.input[0];
|
||||
s16 stepR;
|
||||
s16 stepG;
|
||||
s16 stepB;
|
||||
|
@ -1155,6 +1163,52 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
if (CVar_GetS32("gDpadHoldChange", 1) && CVar_GetS32("gDpadPauseName", 0)) {
|
||||
if (CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) {
|
||||
D_8082AD44 = XREG(8);
|
||||
D_8082AD4C = -1;
|
||||
} else if (--D_8082AD44 < 0) {
|
||||
D_8082AD44 = XREG(6);
|
||||
input->press.button |= BTN_DLEFT;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DLEFT)) {
|
||||
D_8082AD4C = 0;
|
||||
} else if (CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) {
|
||||
D_8082AD44 = XREG(8);
|
||||
D_8082AD4C = 1;
|
||||
} else if (--D_8082AD44 < 0) {
|
||||
D_8082AD44 = XREG(6);
|
||||
input->press.button |= BTN_DRIGHT;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DRIGHT)) {
|
||||
D_8082AD4C = 0;
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(input->cur.button, BTN_DDOWN)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
|
||||
D_8082AD48 = XREG(8);
|
||||
D_8082AD50 = -1;
|
||||
} else if (--D_8082AD48 < 0) {
|
||||
D_8082AD48 = XREG(6);
|
||||
input->press.button |= BTN_DDOWN;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DDOWN)) {
|
||||
D_8082AD50 = 0;
|
||||
} else if (CHECK_BTN_ALL(input->cur.button, BTN_DUP)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) {
|
||||
D_8082AD48 = XREG(8);
|
||||
D_8082AD50 = 1;
|
||||
} else if (--D_8082AD48 < 0) {
|
||||
D_8082AD48 = XREG(6);
|
||||
input->press.button |= BTN_DUP;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->rel.button, BTN_DUP)) {
|
||||
D_8082AD50 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pauseCtx->stickRelX < -30) {
|
||||
if (D_8082AD4C == -1) {
|
||||
if (--D_8082AD44 < 0) {
|
||||
|
@ -3725,7 +3779,7 @@ void KaleidoScope_Update(GlobalContext* globalCtx)
|
|||
&D_801333E8);
|
||||
Gameplay_SaveSceneFlags(globalCtx);
|
||||
gSaveContext.savedSceneNum = globalCtx->sceneNum;
|
||||
Sram_WriteSave(&globalCtx->sramCtx);
|
||||
Save_SaveFile();
|
||||
pauseCtx->unk_1EC = 4;
|
||||
D_8082B25C = 3;
|
||||
}
|
||||
|
@ -3965,7 +4019,7 @@ void KaleidoScope_Update(GlobalContext* globalCtx)
|
|||
pauseCtx->promptChoice = 0;
|
||||
Gameplay_SaveSceneFlags(globalCtx);
|
||||
gSaveContext.savedSceneNum = globalCtx->sceneNum;
|
||||
Sram_WriteSave(&globalCtx->sramCtx);
|
||||
Save_SaveFile();
|
||||
pauseCtx->state = 0xF;
|
||||
D_8082B25C = 3;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue