1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-03 06:24:30 +00:00

Merge commit 'd314cfe923^' into doc_pause_menu

This commit is contained in:
Dragorn421 2023-09-20 18:49:54 +02:00
commit 6b3e8d46cd
No known key found for this signature in database
GPG key ID: 381AEBAF3D429335
74 changed files with 3491 additions and 3210 deletions

View file

@ -95,8 +95,8 @@ AS := $(MIPS_BINUTILS_PREFIX)as
LD := $(MIPS_BINUTILS_PREFIX)ld
OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy
OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump
EMULATOR = mupen64plus
EMU_FLAGS = --noosd
EMULATOR ?=
EMU_FLAGS ?=
INC := -Iinclude -Isrc -Ibuild -I.
@ -269,11 +269,14 @@ setup:
python3 extract_baserom.py
python3 extract_assets.py -j$(N_THREADS)
test: $(ROM)
run: $(ROM)
ifeq ($(EMULATOR),)
$(error Emulator path not set. Set EMULATOR in the Makefile or define it as an environment variable)
endif
$(EMULATOR) $(EMU_FLAGS) $<
.PHONY: all clean setup test distclean assetclean
.PHONY: all clean setup run distclean assetclean
#### Various Recipes ####

View file

@ -1,14 +1,14 @@
<Root>
<File Name="object_cow" Segment="6">
<!-- Cow Body Skeleton -->
<Skeleton Name="gCowBodySkel" Type="Flex" LimbType="Standard" Offset="0x4010"/>
<Skeleton Name="gCowBodySkel" Type="Flex" LimbType="Standard" LimbNone="COW_LIMB_NONE" LimbMax="COW_LIMB_MAX" EnumName="CowLimb" Offset="0x4010"/>
<!-- Cow Body Limbs -->
<Limb Name="gCowRootLimb" LimbType="Standard" Offset="0x3FC0"/>
<Limb Name="gCowHeadLimb" LimbType="Standard" Offset="0x3FCC"/>
<Limb Name="gCowJawLimb" LimbType="Standard" Offset="0x3FD8"/>
<Limb Name="gCowNoseLimb" LimbType="Standard" Offset="0x3FE4"/>
<Limb Name="gCowNoseRingLimb" LimbType="Standard" Offset="0x3FF0"/>
<Limb Name="gCowRootLimb" LimbType="Standard" EnumName="COW_LIMB_ROOT" Offset="0x3FC0"/>
<Limb Name="gCowHeadLimb" LimbType="Standard" EnumName="COW_LIMB_HEAD" Offset="0x3FCC"/>
<Limb Name="gCowJawLimb" LimbType="Standard" EnumName="COW_LIMB_JAW" Offset="0x3FD8"/>
<Limb Name="gCowNoseLimb" LimbType="Standard" EnumName="COW_LIMB_NOSE" Offset="0x3FE4"/>
<Limb Name="gCowNoseRingLimb" LimbType="Standard" EnumName="COW_LIMB_NOSE_RING" Offset="0x3FF0"/>
<!-- Cow Body Limb DisplayLists -->
<DList Name="gCowTorsoDL" Offset="0x1A80"/>
@ -18,14 +18,14 @@
<DList Name="gCowNoseRingDL" Offset="0x2628"/>
<!-- Cow Tail Skeleton -->
<Skeleton Name="gCowTailSkel" Type="Flex" LimbType="Standard" Offset="0x4C30"/>
<Skeleton Name="gCowTailSkel" Type="Flex" LimbType="Standard" LimbNone="COW_TAIL_LIMB_NONE" LimbMax="COW_TAIL_LIMB_MAX" EnumName="CowTailLimb" Offset="0x4C30"/>
<!-- Cow Tail Limbs -->
<Limb Name="gCowTailRootLimb" LimbType="Standard" Offset="0x4BE0"/>
<Limb Name="gCowTailUpperLimb" LimbType="Standard" Offset="0x4BEC"/>
<Limb Name="gCowTailMiddleLimb" LimbType="Standard" Offset="0x4BF8"/>
<Limb Name="gCowTailLowerLimb" LimbType="Standard" Offset="0x4C04"/>
<Limb Name="gCowTailEndLimb" LimbType="Standard" Offset="0x4C10"/>
<Limb Name="gCowTailRootLimb" LimbType="Standard" EnumName="COW_TAIL_LIMB_ROOT" Offset="0x4BE0"/>
<Limb Name="gCowTailUpperLimb" LimbType="Standard" EnumName="COW_TAIL_LIMB_UPPER" Offset="0x4BEC"/>
<Limb Name="gCowTailMiddleLimb" LimbType="Standard" EnumName="COW_TAIL_LIMB_MIDDLE" Offset="0x4BF8"/>
<Limb Name="gCowTailLowerLimb" LimbType="Standard" EnumName="COW_TAIL_LIMB_LOWER" Offset="0x4C04"/>
<Limb Name="gCowTailEndLimb" LimbType="Standard" EnumName="COW_TAIL_LIMB_END" Offset="0x4C10"/>
<!-- Cow Tail Limb DisplayLists -->
<DList Name="gCowTailConnectionDL" Offset="0x46F0"/>

View file

@ -0,0 +1,9 @@
<Root>
<File Name="ovl_Effect_Ss_Fhg_Flash" BaseAddress="0x809A4660" RangeStart="0xA60" RangeEnd="0xF18">
<Array Name="sShockVtx" Count="4" Offset="0xA60">
<Vtx/>
</Array>
<DList Name="sShockDL" Offset="0xAA0"/>
<Texture Name="sShockTex" OutName="shock" Format="i8" Width="32" Height="32" Offset="0xB18"/>
</File>
</Root>

View file

@ -184,9 +184,9 @@ void EffectSs_Insert(PlayState* play, EffectSs* effectSs);
void EffectSs_Spawn(PlayState* play, s32 type, s32 priority, void* initParams);
void EffectSs_UpdateAll(PlayState* play);
void EffectSs_DrawAll(PlayState* play);
s16 func_80027DD4(s16 arg0, s16 arg1, s32 arg2);
s16 func_80027E34(s16 arg0, s16 arg1, f32 arg2);
u8 func_80027E84(u8 arg0, u8 arg1, f32 arg2);
s16 EffectSs_LerpInv(s16 a, s16 b, s32 weightInv);
s16 EffectSs_LerpS16(s16 a, s16 b, f32 weight);
u8 EffectSs_LerpU8(u8 a, u8 b, f32 weight);
void EffectSs_DrawGEffect(PlayState* play, EffectSs* this, void* texture);
void EffectSsDust_Spawn(PlayState* play, u16 drawFlags, Vec3f* pos, Vec3f* velocity, Vec3f* accel,
Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life,
@ -230,12 +230,12 @@ void EffectSsBomb_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* acc
void EffectSsBomb2_SpawnFade(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel);
void EffectSsBomb2_SpawnLayered(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
s16 scaleStep);
void EffectSsBlast_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 scaleStepDecay, s16 life);
void EffectSsBlast_SpawnWhiteCustomScale(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
void EffectSsBlast_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* innerColor,
Color_RGBA8* outerColor, s16 scale, s16 scaleStep, s16 scaleStepDecay, s16 life);
void EffectSsBlast_SpawnWhiteShockwaveSetScale(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
s16 scaleStep, s16 life);
void EffectSsBlast_SpawnShockwave(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel,
Color_RGBA8* primColor, Color_RGBA8* envColor, s16 life);
void EffectSsBlast_SpawnShockwaveSetColor(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel,
Color_RGBA8* innerColor, Color_RGBA8* outerColor, s16 life);
void EffectSsBlast_SpawnWhiteShockwave(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel);
void EffectSsGSpk_SpawnAccel(PlayState* play, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel,
Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep);
@ -1365,14 +1365,6 @@ void ListAlloc_Free(ListAlloc* this, void* data);
void ListAlloc_FreeAll(ListAlloc* this);
void Main_LogSystemHeap(void);
void Main(void* arg);
void SpeedMeter_InitImpl(SpeedMeter* this, u32 arg1, u32 y);
void SpeedMeter_Init(SpeedMeter* this);
void SpeedMeter_Destroy(SpeedMeter* this);
void SpeedMeter_DrawTimeEntries(SpeedMeter* this, GraphicsContext* gfxCtx);
void SpeedMeter_InitAllocEntry(SpeedMeterAllocEntry* this, u32 maxval, u32 val, u16 backColor, u16 foreColor, u32 ulx,
u32 lrx, u32 uly, u32 lry);
void SpeedMeter_DrawAllocEntry(SpeedMeterAllocEntry* this, GraphicsContext* gfxCtx);
void SpeedMeter_DrawAllocEntries(SpeedMeter* meter, GraphicsContext* gfxCtx, GameState* state);
void SysCfb_Init(s32 n64dd);
void* SysCfb_GetFbPtr(s32 idx);
void* SysCfb_GetFbEnd(void);

164
include/gfx.h Normal file
View file

@ -0,0 +1,164 @@
#ifndef GFX_H
#define GFX_H
#include "ultra64.h"
#include "ultra64/gbi.h"
#include "sched.h"
#include "thga.h"
// Texture memory size, 4 KiB
#define TMEM_SIZE 0x1000
typedef struct {
/* 0x00000 */ u16 headMagic; // GFXPOOL_HEAD_MAGIC
/* 0x00008 */ Gfx polyOpaBuffer[0x17E0];
/* 0x0BF08 */ Gfx polyXluBuffer[0x800];
/* 0x0FF08 */ Gfx overlayBuffer[0x400];
/* 0x11F08 */ Gfx workBuffer[0x80];
/* 0x11308 */ Gfx unusedBuffer[0x20];
/* 0x12408 */ u16 tailMagic; // GFXPOOL_TAIL_MAGIC
} GfxPool; // size = 0x12410
typedef struct GraphicsContext {
/* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0"
/* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1"
/* 0x0008 */ char unk_008[0x08]; // Unused, could this be pointers to "Zelda 2" / "Zelda 3"
/* 0x0010 */ Gfx* overlayBuffer; // Pointer to "Zelda 4"
/* 0x0014 */ u32 unk_014;
/* 0x0018 */ char unk_018[0x20];
/* 0x0038 */ OSMesg msgBuff[0x08];
/* 0x0058 */ OSMesgQueue* schedMsgQueue;
/* 0x005C */ OSMesgQueue queue;
/* 0x0078 */ OSScTask task;
/* 0x00E0 */ char unk_0E0[0xD0];
/* 0x01B0 */ Gfx* workBuffer;
/* 0x01B4 */ TwoHeadGfxArena work;
/* 0x01C4 */ char unk_01C4[0xC0];
/* 0x0284 */ OSViMode* viMode;
/* 0x0288 */ char unk_0288[0x20]; // Unused, could this be Zelda 2/3 ?
/* 0x02A8 */ TwoHeadGfxArena overlay; // "Zelda 4"
/* 0x02B8 */ TwoHeadGfxArena polyOpa; // "Zelda 0"
/* 0x02C8 */ TwoHeadGfxArena polyXlu; // "Zelda 1"
/* 0x02D8 */ u32 gfxPoolIdx;
/* 0x02DC */ u16* curFrameBuffer;
/* 0x02E0 */ char unk_2E0[0x04];
/* 0x02E4 */ u32 viFeatures;
/* 0x02E8 */ s32 fbIdx;
/* 0x02EC */ void (*callback)(struct GraphicsContext*, void*);
/* 0x02F0 */ void* callbackParam;
/* 0x02F4 */ f32 xScale;
/* 0x02F8 */ f32 yScale;
/* 0x02FC */ char unk_2FC[0x04];
} GraphicsContext; // size = 0x300
typedef enum {
/* 0 */ SETUPDL_0,
/* 1 */ SETUPDL_1,
/* 2 */ SETUPDL_2,
/* 3 */ SETUPDL_3,
/* 4 */ SETUPDL_4,
/* 5 */ SETUPDL_5,
/* 6 */ SETUPDL_6,
/* 7 */ SETUPDL_7,
/* 8 */ SETUPDL_8,
/* 9 */ SETUPDL_9,
/* 10 */ SETUPDL_10,
/* 11 */ SETUPDL_11,
/* 12 */ SETUPDL_12,
/* 13 */ SETUPDL_13,
/* 14 */ SETUPDL_14,
/* 15 */ SETUPDL_15,
/* 16 */ SETUPDL_16,
/* 17 */ SETUPDL_17,
/* 18 */ SETUPDL_18,
/* 19 */ SETUPDL_19,
/* 20 */ SETUPDL_20,
/* 21 */ SETUPDL_21,
/* 22 */ SETUPDL_22,
/* 23 */ SETUPDL_23,
/* 24 */ SETUPDL_24,
/* 25 */ SETUPDL_25,
/* 26 */ SETUPDL_26,
/* 27 */ SETUPDL_27,
/* 28 */ SETUPDL_28,
/* 29 */ SETUPDL_29,
/* 30 */ SETUPDL_30,
/* 31 */ SETUPDL_31,
/* 32 */ SETUPDL_32,
/* 33 */ SETUPDL_33,
/* 34 */ SETUPDL_34,
/* 35 */ SETUPDL_35,
/* 36 */ SETUPDL_36,
/* 37 */ SETUPDL_37,
/* 38 */ SETUPDL_38,
/* 39 */ SETUPDL_39,
/* 40 */ SETUPDL_40,
/* 41 */ SETUPDL_41,
/* 42 */ SETUPDL_42,
/* 43 */ SETUPDL_43,
/* 44 */ SETUPDL_44,
/* 45 */ SETUPDL_45,
/* 46 */ SETUPDL_46,
/* 47 */ SETUPDL_47,
/* 48 */ SETUPDL_48,
/* 49 */ SETUPDL_49,
/* 50 */ SETUPDL_50,
/* 51 */ SETUPDL_51,
/* 52 */ SETUPDL_52,
/* 53 */ SETUPDL_53,
/* 54 */ SETUPDL_54,
/* 55 */ SETUPDL_55,
/* 56 */ SETUPDL_56,
/* 57 */ SETUPDL_57,
/* 58 */ SETUPDL_58,
/* 59 */ SETUPDL_59,
/* 60 */ SETUPDL_60,
/* 61 */ SETUPDL_61,
/* 62 */ SETUPDL_62,
/* 63 */ SETUPDL_63,
/* 64 */ SETUPDL_64,
/* 65 */ SETUPDL_65,
/* 66 */ SETUPDL_66,
/* 67 */ SETUPDL_67,
/* 68 */ SETUPDL_68,
/* 69 */ SETUPDL_69,
/* 70 */ SETUPDL_70,
/* 71 */ SETUPDL_MAX
} SetupDL;
#define UCODE_NULL 0
#define UCODE_F3DZEX 1
#define UCODE_UNK 2
#define UCODE_S2DEX 3
typedef struct {
/* 0x00 */ u32 type;
/* 0x04 */ void* ptr;
} UCodeInfo; // size = 0x8
typedef struct {
/* 0x00 */ uintptr_t segments[NUM_SEGMENTS];
/* 0x40 */ Gfx* dlStack[18];
/* 0x88 */ s32 dlDepth;
/* 0x8C */ u32 dlCnt;
/* 0x90 */ u32 vtxCnt;
/* 0x94 */ u32 spvtxCnt;
/* 0x98 */ u32 tri1Cnt;
/* 0x9C */ u32 tri2Cnt;
/* 0xA0 */ u32 quadCnt;
/* 0xA4 */ u32 lineCnt;
/* 0xA8 */ u32 loaducodeCnt;
/* 0xAC */ u32 pipeSyncRequired;
/* 0xB0 */ u32 tileSyncRequired;
/* 0xB4 */ u32 loadSyncRequired;
/* 0xB8 */ u32 syncErr;
/* 0xBC */ s32 enableLog;
/* 0xC0 */ s32 ucodeType;
/* 0xC4 */ s32 ucodeInfoCount;
/* 0xC8 */ UCodeInfo* ucodeInfo;
/* 0xCC */ u32 modeH;
/* 0xD0 */ u32 modeL;
/* 0xD4 */ u32 geometryMode;
} UCodeDisas; // size = 0xD8
#endif

80
include/jpeg.h Normal file
View file

@ -0,0 +1,80 @@
#ifndef JPEG_H
#define JPEG_H
#include "ultra64.h"
#include "sched.h"
typedef struct {
/* 0x00 */ u16 table[8*8];
} JpegQuantizationTable; // size = 0x80
typedef struct {
/* 0x00 */ u8 codeOffs[16];
/* 0x10 */ u16 codesA[16];
/* 0x30 */ u16 codesB[16];
/* 0x50 */ u8* symbols;
} JpegHuffmanTable; // size = 0x54
// this struct might be inaccurate but it's not used outside jpegutils.c anyways
typedef struct {
/* 0x000 */ u8 codeOffs[16];
/* 0x010 */ u16 dcCodes[120];
/* 0x100 */ u16 acCodes[256];
} JpegHuffmanTableOld; // size = 0x300
typedef union {
struct {
/* 0x00 */ u32 address;
/* 0x04 */ u32 mbCount;
/* 0x08 */ u32 mode;
/* 0x0C */ u32 qTableYPtr;
/* 0x10 */ u32 qTableUPtr;
/* 0x14 */ u32 qTableVPtr;
/* 0x18 */ u32 mbSize; // This field is used by the microcode to save the macroblock size during a yield
};
long long int force_structure_alignment;
} JpegTaskData; // size = 0x20
typedef struct {
/* 0x000 */ JpegTaskData taskData;
/* 0x020 */ u64 yieldData[0x200 / sizeof(u64)];
/* 0x220 */ JpegQuantizationTable qTableY;
/* 0x2A0 */ JpegQuantizationTable qTableU;
/* 0x320 */ JpegQuantizationTable qTableV;
/* 0x3A0 */ u8 codesLengths[0x110];
/* 0x4B0 */ u16 codes[0x108];
/* 0x6C0 */ u16 data[4][0x180];
} JpegWork; // size = 0x12C0
typedef struct {
/* 0x00 */ void* imageData;
/* 0x04 */ u8 mode;
/* 0x05 */ u8 unk_05;
/* 0x08 */ JpegHuffmanTable* hTablePtrs[4];
/* 0x18 */ u8 unk_18;
} JpegDecoder; // size = 0x1C
typedef struct {
/* 0x00 */ u8 dqtCount;
/* 0x04 */ u8* dqtPtr[3];
/* 0x10 */ u8 dhtCount;
/* 0x14 */ u8* dhtPtr[4];
/* 0x24 */ void* imageData;
/* 0x28 */ u32 mode; // 0 if Y V0 is 1 and 2 if Y V0 is 2
/* 0x30 */ OSScTask scTask;
/* 0x98 */ OSMesgQueue mq;
/* 0xB0 */ OSMesg msg;
/* 0xB4 */ JpegWork* workBuf;
} JpegContext; // size = 0xB8
typedef struct {
/* 0x00 */ u32 byteIdx;
/* 0x04 */ u8 bitIdx;
/* 0x05 */ u8 dontSkip;
/* 0x08 */ u32 curWord;
/* 0x0C */ s16 unk_0C;
/* 0x0E */ s16 unk_0E;
/* 0x10 */ s16 unk_10;
} JpegDecoderState; // size = 0x14
#endif

33
include/prerender.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef PRERENDER_H
#define PRERENDER_H
#include "ultra64/ultratypes.h"
typedef struct ListAlloc {
/* 0x00 */ struct ListAlloc* prev;
/* 0x04 */ struct ListAlloc* next;
} ListAlloc; // size = 0x8
typedef struct {
/* 0x00 */ s32 width;
/* 0x04 */ s32 height;
/* 0x08 */ s32 widthSave;
/* 0x0C */ s32 heightSave;
/* 0x10 */ u16* fbuf;
/* 0x14 */ u16* fbufSave;
/* 0x18 */ u8* cvgSave;
/* 0x1C */ u16* zbuf;
/* 0x20 */ u16* zbufSave;
/* 0x24 */ s32 ulxSave;
/* 0x28 */ s32 ulySave;
/* 0x2C */ s32 lrxSave;
/* 0x30 */ s32 lrySave;
/* 0x34 */ s32 ulx;
/* 0x38 */ s32 uly;
/* 0x3C */ s32 lrx;
/* 0x40 */ s32 lry;
/* 0x44 */ ListAlloc alloc;
/* 0x4C */ u32 unk_4C;
} PreRender; // size = 0x50
#endif

View file

@ -106,6 +106,7 @@
#define R_MESSAGE_DEBUGGER_TEXTID YREG(79)
#define R_C_UP_ICON_X YREG(88)
#define R_C_UP_ICON_Y YREG(89)
#define R_EPONAS_SONG_PLAYED DREG(53)
#define R_MAGIC_FILL_COLOR(i) ZREG(0 + (i))
#define R_PAUSE_SWITCH_PAGE_FRAME_ADVANCE_ON ZREG(13)
#define R_PAUSE_CURSOR_L_R_SELECTED_PRIM_TIMER ZREG(28)

35
include/speedmeter.h Normal file
View file

@ -0,0 +1,35 @@
#ifndef SPEEDMETER_H
#define SPEEDMETER_H
#include "ultra64/ultratypes.h"
struct GraphicsContext;
struct GameState;
typedef struct {
/* 0x00 */ char unk_00[0x18];
/* 0x18 */ s32 unk_18;
/* 0x1C */ s32 y;
} SpeedMeter; // size = 0x20
typedef struct {
/* 0x00 */ s32 maxval;
/* 0x04 */ s32 val;
/* 0x08 */ u16 backColor;
/* 0x0A */ u16 foreColor;
/* 0x0C */ s32 ulx;
/* 0x10 */ s32 lrx;
/* 0x14 */ s32 uly;
/* 0x18 */ s32 lry;
} SpeedMeterAllocEntry; // size = 0x1C
void SpeedMeter_InitImpl(SpeedMeter* this, u32 arg1, u32 y);
void SpeedMeter_Init(SpeedMeter* this);
void SpeedMeter_Destroy(SpeedMeter* this);
void SpeedMeter_DrawTimeEntries(SpeedMeter* this, struct GraphicsContext* gfxCtx);
void SpeedMeter_InitAllocEntry(SpeedMeterAllocEntry* this, u32 maxval, u32 val, u16 backColor, u16 foreColor, u32 ulx,
u32 lrx, u32 uly, u32 lry);
void SpeedMeter_DrawAllocEntry(SpeedMeterAllocEntry* this, struct GraphicsContext* gfxCtx);
void SpeedMeter_DrawAllocEntries(SpeedMeter* meter, struct GraphicsContext* gfxCtx, struct GameState* state);
#endif

View file

@ -27,9 +27,12 @@
#include "z64message.h"
#include "z64pause.h"
#include "z64skin.h"
#include "z64game.h"
#include "z64transition.h"
#include "z64transition_instances.h"
#include "z64interface.h"
#include "z64skybox.h"
#include "z64sram.h"
#include "z64view.h"
#include "alignment.h"
#include "seqcmd.h"
@ -47,6 +50,10 @@
#include "mempak.h"
#include "tha.h"
#include "thga.h"
#include "speedmeter.h"
#include "gfx.h"
#include "jpeg.h"
#include "prerender.h"
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
@ -85,17 +92,9 @@
#define STACK_TOP(stack) \
((u8*)(stack) + sizeof(stack))
// Texture memory size, 4 KiB
#define TMEM_SIZE 0x1000
// NOTE: Once we start supporting other builds, this can be changed with an ifdef
#define REGION_NATIVE REGION_EU
typedef struct{
/* 0x00 */ char unk[0x4];
/* 0x04 */ MtxF mf;
} HorseStruct;
typedef struct {
/* 0x00 */ s32 regPage; // 0: no page selected (reg editor is not active); 1: first page; `REG_PAGES`: last page
/* 0x04 */ s32 regGroup; // Indexed from 0 to `REG_GROUPS`-1. Each group has its own character to identify it.
@ -105,123 +104,6 @@ typedef struct {
/* 0x14 */ s16 data[REG_GROUPS * REGS_PER_GROUP]; // Accessed through *REG macros, see regs.h
} RegEditor; // size = 0x15D4
typedef struct {
/* 0x00000 */ u16 headMagic; // GFXPOOL_HEAD_MAGIC
/* 0x00008 */ Gfx polyOpaBuffer[0x17E0];
/* 0x0BF08 */ Gfx polyXluBuffer[0x800];
/* 0x0FF08 */ Gfx overlayBuffer[0x400];
/* 0x11F08 */ Gfx workBuffer[0x80];
/* 0x11308 */ Gfx unusedBuffer[0x20];
/* 0x12408 */ u16 tailMagic; // GFXPOOL_TAIL_MAGIC
} GfxPool; // size = 0x12410
typedef struct GraphicsContext {
/* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0"
/* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1"
/* 0x0008 */ char unk_008[0x08]; // Unused, could this be pointers to "Zelda 2" / "Zelda 3"
/* 0x0010 */ Gfx* overlayBuffer; // Pointer to "Zelda 4"
/* 0x0014 */ u32 unk_014;
/* 0x0018 */ char unk_018[0x20];
/* 0x0038 */ OSMesg msgBuff[0x08];
/* 0x0058 */ OSMesgQueue* schedMsgQueue;
/* 0x005C */ OSMesgQueue queue;
/* 0x0078 */ OSScTask task;
/* 0x00E0 */ char unk_0E0[0xD0];
/* 0x01B0 */ Gfx* workBuffer;
/* 0x01B4 */ TwoHeadGfxArena work;
/* 0x01C4 */ char unk_01C4[0xC0];
/* 0x0284 */ OSViMode* viMode;
/* 0x0288 */ char unk_0288[0x20]; // Unused, could this be Zelda 2/3 ?
/* 0x02A8 */ TwoHeadGfxArena overlay; // "Zelda 4"
/* 0x02B8 */ TwoHeadGfxArena polyOpa; // "Zelda 0"
/* 0x02C8 */ TwoHeadGfxArena polyXlu; // "Zelda 1"
/* 0x02D8 */ u32 gfxPoolIdx;
/* 0x02DC */ u16* curFrameBuffer;
/* 0x02E0 */ char unk_2E0[0x04];
/* 0x02E4 */ u32 viFeatures;
/* 0x02E8 */ s32 fbIdx;
/* 0x02EC */ void (*callback)(struct GraphicsContext*, void*);
/* 0x02F0 */ void* callbackParam;
/* 0x02F4 */ f32 xScale;
/* 0x02F8 */ f32 yScale;
/* 0x02FC */ char unk_2FC[0x04];
} GraphicsContext; // size = 0x300
typedef enum {
/* 0 */ SETUPDL_0,
/* 1 */ SETUPDL_1,
/* 2 */ SETUPDL_2,
/* 3 */ SETUPDL_3,
/* 4 */ SETUPDL_4,
/* 5 */ SETUPDL_5,
/* 6 */ SETUPDL_6,
/* 7 */ SETUPDL_7,
/* 8 */ SETUPDL_8,
/* 9 */ SETUPDL_9,
/* 10 */ SETUPDL_10,
/* 11 */ SETUPDL_11,
/* 12 */ SETUPDL_12,
/* 13 */ SETUPDL_13,
/* 14 */ SETUPDL_14,
/* 15 */ SETUPDL_15,
/* 16 */ SETUPDL_16,
/* 17 */ SETUPDL_17,
/* 18 */ SETUPDL_18,
/* 19 */ SETUPDL_19,
/* 20 */ SETUPDL_20,
/* 21 */ SETUPDL_21,
/* 22 */ SETUPDL_22,
/* 23 */ SETUPDL_23,
/* 24 */ SETUPDL_24,
/* 25 */ SETUPDL_25,
/* 26 */ SETUPDL_26,
/* 27 */ SETUPDL_27,
/* 28 */ SETUPDL_28,
/* 29 */ SETUPDL_29,
/* 30 */ SETUPDL_30,
/* 31 */ SETUPDL_31,
/* 32 */ SETUPDL_32,
/* 33 */ SETUPDL_33,
/* 34 */ SETUPDL_34,
/* 35 */ SETUPDL_35,
/* 36 */ SETUPDL_36,
/* 37 */ SETUPDL_37,
/* 38 */ SETUPDL_38,
/* 39 */ SETUPDL_39,
/* 40 */ SETUPDL_40,
/* 41 */ SETUPDL_41,
/* 42 */ SETUPDL_42,
/* 43 */ SETUPDL_43,
/* 44 */ SETUPDL_44,
/* 45 */ SETUPDL_45,
/* 46 */ SETUPDL_46,
/* 47 */ SETUPDL_47,
/* 48 */ SETUPDL_48,
/* 49 */ SETUPDL_49,
/* 50 */ SETUPDL_50,
/* 51 */ SETUPDL_51,
/* 52 */ SETUPDL_52,
/* 53 */ SETUPDL_53,
/* 54 */ SETUPDL_54,
/* 55 */ SETUPDL_55,
/* 56 */ SETUPDL_56,
/* 57 */ SETUPDL_57,
/* 58 */ SETUPDL_58,
/* 59 */ SETUPDL_59,
/* 60 */ SETUPDL_60,
/* 61 */ SETUPDL_61,
/* 62 */ SETUPDL_62,
/* 63 */ SETUPDL_63,
/* 64 */ SETUPDL_64,
/* 65 */ SETUPDL_65,
/* 66 */ SETUPDL_66,
/* 67 */ SETUPDL_67,
/* 68 */ SETUPDL_68,
/* 69 */ SETUPDL_69,
/* 70 */ SETUPDL_70,
/* 71 */ SETUPDL_MAX
} SetupDL;
typedef struct {
/* 0x00 */ u8 seqId;
/* 0x01 */ u8 natureAmbienceId;
@ -300,143 +182,12 @@ typedef struct {
/* 0x013C */ void* absoluteSpace; // Space used to allocate actor overlays with alloc type ACTOROVL_ALLOC_ABSOLUTE
} ActorContext; // size = 0x140
typedef struct {
/* 0x00 */ char unk_00[0x4];
/* 0x04 */ void* script;
/* 0x08 */ u8 state;
/* 0x0C */ f32 timer;
/* 0x10 */ u16 curFrame; // current frame of the script that is running
/* 0x12 */ u16 unk_12; // set but never used
/* 0x14 */ s32 subCamId;
/* 0x18 */ u16 camEyeSplinePointsAppliedFrame; // stores the frame the cam eye spline points data was last applied on
/* 0x1A */ u8 camAtReady; // cam `at` data is ready to be applied
/* 0x1B */ u8 camEyeReady; // cam `eye` data is ready to be applied
/* 0x1C */ CutsceneCameraPoint* camAtPoints;
/* 0x20 */ CutsceneCameraPoint* camEyePoints;
/* 0x24 */ CsCmdActorCue* playerCue;
/* 0x28 */ CsCmdActorCue* actorCues[10]; // "npcdemopnt"
} CutsceneContext; // size = 0x50
typedef struct {
/* 0x00 */ u16 countdown;
/* 0x04 */ Vec3f worldPos;
/* 0x10 */ Vec3f projectedPos;
} SfxSource; // size = 0x1C
typedef enum {
/* 0x00 */ DO_ACTION_ATTACK,
/* 0x01 */ DO_ACTION_CHECK,
/* 0x02 */ DO_ACTION_ENTER,
/* 0x03 */ DO_ACTION_RETURN,
/* 0x04 */ DO_ACTION_OPEN,
/* 0x05 */ DO_ACTION_JUMP,
/* 0x06 */ DO_ACTION_DECIDE,
/* 0x07 */ DO_ACTION_DIVE,
/* 0x08 */ DO_ACTION_FASTER,
/* 0x09 */ DO_ACTION_THROW,
/* 0x0A */ DO_ACTION_NONE, // in do_action_static, the texture at this position is NAVI, however this value is in practice the "No Action" value
/* 0x0B */ DO_ACTION_CLIMB,
/* 0x0C */ DO_ACTION_DROP,
/* 0x0D */ DO_ACTION_DOWN,
/* 0x0E */ DO_ACTION_SAVE,
/* 0x0F */ DO_ACTION_SPEAK,
/* 0x10 */ DO_ACTION_NEXT,
/* 0x11 */ DO_ACTION_GRAB,
/* 0x12 */ DO_ACTION_STOP,
/* 0x13 */ DO_ACTION_PUTAWAY,
/* 0x14 */ DO_ACTION_REEL,
/* 0x15 */ DO_ACTION_1,
/* 0x16 */ DO_ACTION_2,
/* 0x17 */ DO_ACTION_3,
/* 0x18 */ DO_ACTION_4,
/* 0x19 */ DO_ACTION_5,
/* 0x1A */ DO_ACTION_6,
/* 0x1B */ DO_ACTION_7,
/* 0x1C */ DO_ACTION_8,
/* 0x1D */ DO_ACTION_MAX
} DoAction;
// TODO extract this information from the texture definitions themselves
#define DO_ACTION_TEX_WIDTH 48
#define DO_ACTION_TEX_HEIGHT 16
#define DO_ACTION_TEX_SIZE ((DO_ACTION_TEX_WIDTH * DO_ACTION_TEX_HEIGHT) / 2) // (sizeof(gCheckDoActionENGTex))
typedef struct {
/* 0x0000 */ View view;
/* 0x0128 */ Vtx* actionVtx;
/* 0x012C */ Vtx* beatingHeartVtx;
/* 0x0130 */ u8* parameterSegment;
/* 0x0134 */ u8* doActionSegment;
/* 0x0138 */ u8* iconItemSegment;
/* 0x013C */ u8* mapSegment;
/* 0x0140 */ u8 mapPalette[32];
/* 0x0160 */ DmaRequest dmaRequest_160;
/* 0x0180 */ DmaRequest dmaRequest_180;
/* 0x01A0 */ char unk_1A0[0x20];
/* 0x01C0 */ OSMesgQueue loadQueue;
/* 0x01D8 */ OSMesg loadMsg;
/* 0x01DC */ Viewport viewport;
/* 0x01EC */ s16 unk_1EC;
/* 0x01EE */ u16 unk_1EE;
/* 0x01F0 */ u16 unk_1F0;
/* 0x01F4 */ f32 unk_1F4;
/* 0x01F8 */ s16 naviCalling;
/* 0x01FA */ s16 unk_1FA;
/* 0x01FC */ s16 unk_1FC;
/* 0x01FE */ s16 heartColorOscillator;
/* 0x0200 */ s16 heartColorOscillatorDirection;
/* 0x0202 */ s16 beatingHeartPrim[3];
/* 0x0208 */ s16 beatingHeartEnv[3];
/* 0x020E */ s16 heartsPrimR[2];
/* 0x0212 */ s16 heartsPrimG[2];
/* 0x0216 */ s16 heartsPrimB[2];
/* 0x021A */ s16 heartsEnvR[2];
/* 0x021E */ s16 heartsEnvG[2];
/* 0x0222 */ s16 heartsEnvB[2];
/* 0x0226 */ s16 unk_226; // Used only in unused functions
/* 0x0228 */ s16 unk_228; // Used only in unused functions
/* 0x022A */ s16 beatingHeartOscillator;
/* 0x022C */ s16 beatingHeartOscillatorDirection;
/* 0x022E */ s16 unk_22E;
/* 0x0230 */ s16 lensMagicConsumptionTimer; // When lens is active, 1 unit of magic is consumed every time the timer reaches 0
/* 0x0232 */ s16 counterDigits[4]; // used for key and rupee counters
/* 0x023A */ u8 numHorseBoosts;
/* 0x023C */ u16 unk_23C;
/* 0x023E */ u16 hbaAmmo; // ammo while playing the horseback archery minigame
/* 0x0240 */ u16 unk_240;
/* 0x0242 */ u16 unk_242;
/* 0x0224 */ u16 unk_244; // screen fill alpha?
/* 0x0246 */ u16 aAlpha; // also carrots alpha
/* 0x0248 */ u16 bAlpha; // also HBA score alpha
/* 0x024A */ u16 cLeftAlpha;
/* 0x024C */ u16 cDownAlpha;
/* 0x024E */ u16 cRightAlpha;
/* 0x0250 */ u16 healthAlpha; // also max C-Up alpha
/* 0x0252 */ u16 magicAlpha; // also Rupee and Key counters alpha
/* 0x0254 */ u16 minimapAlpha;
/* 0x0256 */ s16 startAlpha;
/* 0x0258 */ s16 unk_258;
/* 0x025A */ s16 unk_25A;
/* 0x025C */ s16 mapRoomNum;
/* 0x025E */ s16 mapPaletteIndex; // "map_palete_no"
/* 0x0260 */ u8 unk_260;
/* 0x0261 */ u8 unk_261;
struct {
/* 0x0262 */ u8 hGauge; // "h_gage"; unknown?
/* 0x0263 */ u8 bButton; // "b_button"
/* 0x0264 */ u8 aButton; // "a_button"
/* 0x0265 */ u8 bottles; // "c_bottle"
/* 0x0266 */ u8 tradeItems; // "c_warasibe"
/* 0x0267 */ u8 hookshot; // "c_hook"
/* 0x0268 */ u8 ocarina; // "c_ocarina"
/* 0x0269 */ u8 warpSongs; // "c_warp"
/* 0x026A */ u8 sunsSong; // "m_sunmoon"
/* 0x026B */ u8 farores; // "m_wind"
/* 0x026C */ u8 dinsNayrus; // "m_magic"; din's fire and nayru's love
/* 0x026D */ u8 all; // "another"; enables all item restrictions
} restrictions;
} InterfaceContext; // size = 0x270
typedef struct {
/* 0x00 */ void* loadedRamAddr;
/* 0x04 */ uintptr_t vromStart;
@ -470,24 +221,6 @@ typedef struct {
/* 0x00 */ u16 state;
} GameOverContext; // size = 0x2
typedef struct {
/* 0x00 */ s16 id;
/* 0x04 */ void* segment;
/* 0x08 */ DmaRequest dmaRequest;
/* 0x28 */ OSMesgQueue loadQueue;
/* 0x40 */ OSMesg loadMsg;
} ObjectStatus; // size = 0x44
typedef struct {
/* 0x0000 */ void* spaceStart;
/* 0x0004 */ void* spaceEnd; // original name: "endSegment"
/* 0x0008 */ u8 num; // number of objects in bank
/* 0x0009 */ u8 unk_09;
/* 0x000A */ u8 mainKeepIndex; // "gameplay_keep" index in bank
/* 0x000B */ u8 subKeepIndex; // "gameplay_field_keep" or "gameplay_dangeon_keep" index in bank
/* 0x000C */ ObjectStatus status[OBJECT_EXCHANGE_BANK_MAX];
} ObjectContext; // size = 0x518
typedef enum {
/* 0 */ LENS_MODE_HIDE_ACTORS, // lens actors are visible by default, and hidden by using lens (for example, fake walls)
/* 1 */ LENS_MODE_SHOW_ACTORS // lens actors are invisible by default, and shown by using lens (for example, invisible enemies)
@ -549,182 +282,6 @@ typedef struct {
/* 0x290 */ OcLine* colLine[COLLISION_CHECK_OC_LINE_MAX];
} CollisionCheckContext; // size = 0x29C
typedef struct ListAlloc {
/* 0x00 */ struct ListAlloc* prev;
/* 0x04 */ struct ListAlloc* next;
} ListAlloc; // size = 0x8
typedef struct {
/* 0x00 */ s32 width;
/* 0x04 */ s32 height;
/* 0x08 */ s32 widthSave;
/* 0x0C */ s32 heightSave;
/* 0x10 */ u16* fbuf;
/* 0x14 */ u16* fbufSave;
/* 0x18 */ u8* cvgSave;
/* 0x1C */ u16* zbuf;
/* 0x20 */ u16* zbufSave;
/* 0x24 */ s32 ulxSave;
/* 0x28 */ s32 ulySave;
/* 0x2C */ s32 lrxSave;
/* 0x30 */ s32 lrySave;
/* 0x34 */ s32 ulx;
/* 0x38 */ s32 uly;
/* 0x3C */ s32 lrx;
/* 0x40 */ s32 lry;
/* 0x44 */ ListAlloc alloc;
/* 0x4C */ u32 unk_4C;
} PreRender; // size = 0x50
#define TRANS_TRIGGER_OFF 0 // transition is not active
#define TRANS_TRIGGER_START 20 // start transition (exiting an area)
#define TRANS_TRIGGER_END -20 // transition is ending (arriving in a new area)
typedef enum {
/* 0 */ TRANS_MODE_OFF,
/* 1 */ TRANS_MODE_SETUP,
/* 2 */ TRANS_MODE_INSTANCE_INIT,
/* 3 */ TRANS_MODE_INSTANCE_RUNNING,
/* 4 */ TRANS_MODE_FILL_WHITE_INIT,
/* 5 */ TRANS_MODE_FILL_IN,
/* 6 */ TRANS_MODE_FILL_OUT,
/* 7 */ TRANS_MODE_FILL_BROWN_INIT,
/* 8 */ TRANS_MODE_08, // unused
/* 9 */ TRANS_MODE_09, // unused
/* 10 */ TRANS_MODE_INSTANT,
/* 11 */ TRANS_MODE_INSTANCE_WAIT,
/* 12 */ TRANS_MODE_SANDSTORM_INIT,
/* 13 */ TRANS_MODE_SANDSTORM,
/* 14 */ TRANS_MODE_SANDSTORM_END_INIT,
/* 15 */ TRANS_MODE_SANDSTORM_END,
/* 16 */ TRANS_MODE_CS_BLACK_FILL_INIT,
/* 17 */ TRANS_MODE_CS_BLACK_FILL
} TransitionMode;
typedef enum {
/* 0 */ TRANS_TYPE_WIPE,
/* 1 */ TRANS_TYPE_TRIFORCE,
/* 2 */ TRANS_TYPE_FADE_BLACK,
/* 3 */ TRANS_TYPE_FADE_WHITE,
/* 4 */ TRANS_TYPE_FADE_BLACK_FAST,
/* 5 */ TRANS_TYPE_FADE_WHITE_FAST,
/* 6 */ TRANS_TYPE_FADE_BLACK_SLOW,
/* 7 */ TRANS_TYPE_FADE_WHITE_SLOW,
/* 8 */ TRANS_TYPE_WIPE_FAST,
/* 9 */ TRANS_TYPE_FILL_WHITE2,
/* 10 */ TRANS_TYPE_FILL_WHITE,
/* 11 */ TRANS_TYPE_INSTANT,
/* 12 */ TRANS_TYPE_FILL_BROWN,
/* 13 */ TRANS_TYPE_FADE_WHITE_CS_DELAYED,
/* 14 */ TRANS_TYPE_SANDSTORM_PERSIST,
/* 15 */ TRANS_TYPE_SANDSTORM_END,
/* 16 */ TRANS_TYPE_CS_BLACK_FILL,
/* 17 */ TRANS_TYPE_FADE_WHITE_INSTANT,
/* 18 */ TRANS_TYPE_FADE_GREEN,
/* 19 */ TRANS_TYPE_FADE_BLUE,
// transition types 20 - 31 are unused
// transition types 32 - 55 are constructed using the TRANS_TYPE_CIRCLE macro
/* 56 */ TRANS_TYPE_MAX = 56
} TransitionType;
#define TRANS_NEXT_TYPE_DEFAULT 0xFF // when `nextTransitionType` is set to default, the type will be taken from the entrance table for the ending transition
typedef enum {
/* 0 */ TCA_NORMAL,
/* 1 */ TCA_WAVE,
/* 2 */ TCA_RIPPLE,
/* 3 */ TCA_STARBURST
} TransitionCircleAppearance;
typedef enum {
/* 0 */ TCC_BLACK,
/* 1 */ TCC_WHITE,
/* 2 */ TCC_GRAY,
/* 3 */ TCC_SPECIAL // color varies depending on appearance. unused and appears broken
} TransitionCircleColor;
typedef enum {
/* 0 */ TCS_FAST,
/* 1 */ TCS_SLOW
} TransitionCircleSpeed;
#define TC_SET_PARAMS (1 << 7)
#define TRANS_TYPE_CIRCLE(appearance, color, speed) ((1 << 5) | ((color & 3) << 3) | ((appearance & 3) << 1) | (speed & 1))
typedef struct {
union {
TransitionFade fade;
TransitionCircle circle;
TransitionTriforce triforce;
TransitionWipe wipe;
} instanceData;
/* 0x228 */ s32 transitionType;
/* 0x22C */ void* (*init)(void* transition);
/* 0x230 */ void (*destroy)(void* transition);
/* 0x234 */ void (*update)(void* transition, s32 updateRate);
/* 0x238 */ void (*draw)(void* transition, Gfx** gfxP);
/* 0x23C */ void (*start)(void* transition);
/* 0x240 */ void (*setType)(void* transition, s32 type);
/* 0x244 */ void (*setColor)(void* transition, u32 color);
/* 0x248 */ void (*setUnkColor)(void* transition, u32 color);
/* 0x24C */ s32 (*isDone)(void* transition);
} TransitionContext; // size = 0x250
typedef struct {
/* 0x00 */ u8* readBuff;
} SramContext; // size = 0x4
#define SRAM_SIZE 0x8000
#define SRAM_HEADER_SIZE 0x10
typedef enum {
/* 0x00 */ SRAM_HEADER_SOUND,
/* 0x01 */ SRAM_HEADER_ZTARGET,
/* 0x02 */ SRAM_HEADER_LANGUAGE,
/* 0x03 */ SRAM_HEADER_MAGIC // must be the value of `sZeldaMagic` for save to be considered valid
} SramHeaderField;
typedef struct GameAllocEntry {
/* 0x00 */ struct GameAllocEntry* next;
/* 0x04 */ struct GameAllocEntry* prev;
/* 0x08 */ u32 size;
/* 0x0C */ u32 unk_0C;
} GameAllocEntry; // size = 0x10
typedef struct {
/* 0x00 */ GameAllocEntry base;
/* 0x10 */ GameAllocEntry* head;
} GameAlloc; // size = 0x14
// Used in Graph_GetNextGameState in graph.c
#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) enumName,
#define DEFINE_GAMESTATE(typeName, enumName, name) DEFINE_GAMESTATE_INTERNAL(typeName, enumName)
typedef enum {
#include "tables/gamestate_table.h"
GAMESTATE_ID_MAX
} GameStateId;
#undef DEFINE_GAMESTATE
#undef DEFINE_GAMESTATE_INTERNAL
struct GameState;
typedef void (*GameStateFunc)(struct GameState* gameState);
typedef struct GameState {
/* 0x00 */ GraphicsContext* gfxCtx;
/* 0x04 */ GameStateFunc main;
/* 0x08 */ GameStateFunc destroy; // "cleanup"
/* 0x0C */ GameStateFunc init;
/* 0x10 */ u32 size;
/* 0x14 */ Input input[MAXCONTROLLERS];
/* 0x74 */ TwoHeadArena tha;
/* 0x84 */ GameAlloc alloc;
/* 0x98 */ u32 running;
/* 0x9C */ u32 frames;
/* 0xA0 */ u32 inPreNMIState;
} GameState; // size = 0xA4
typedef struct {
/* 0x00 */ GameState state;
} SetupState; // size = 0xA4
@ -1212,114 +769,6 @@ typedef struct {
/* 0x10 */ OSTime resetTime;
} PreNmiBuff; // size = 0x18 (actually osAppNMIBuffer is 0x40 bytes large but the rest is unused)
#define UCODE_NULL 0
#define UCODE_F3DZEX 1
#define UCODE_UNK 2
#define UCODE_S2DEX 3
typedef struct {
/* 0x00 */ u32 type;
/* 0x04 */ void* ptr;
} UCodeInfo; // size = 0x8
typedef struct {
/* 0x00 */ uintptr_t segments[NUM_SEGMENTS];
/* 0x40 */ Gfx* dlStack[18];
/* 0x88 */ s32 dlDepth;
/* 0x8C */ u32 dlCnt;
/* 0x90 */ u32 vtxCnt;
/* 0x94 */ u32 spvtxCnt;
/* 0x98 */ u32 tri1Cnt;
/* 0x9C */ u32 tri2Cnt;
/* 0xA0 */ u32 quadCnt;
/* 0xA4 */ u32 lineCnt;
/* 0xA8 */ u32 loaducodeCnt;
/* 0xAC */ u32 pipeSyncRequired;
/* 0xB0 */ u32 tileSyncRequired;
/* 0xB4 */ u32 loadSyncRequired;
/* 0xB8 */ u32 syncErr;
/* 0xBC */ s32 enableLog;
/* 0xC0 */ s32 ucodeType;
/* 0xC4 */ s32 ucodeInfoCount;
/* 0xC8 */ UCodeInfo* ucodeInfo;
/* 0xCC */ u32 modeH;
/* 0xD0 */ u32 modeL;
/* 0xD4 */ u32 geometryMode;
} UCodeDisas; // size = 0xD8
typedef struct {
/* 0x00 */ u16 table[8*8];
} JpegQuantizationTable; // size = 0x80
typedef struct {
/* 0x00 */ u8 codeOffs[16];
/* 0x10 */ u16 codesA[16];
/* 0x30 */ u16 codesB[16];
/* 0x50 */ u8* symbols;
} JpegHuffmanTable; // size = 0x54
// this struct might be inaccurate but it's not used outside jpegutils.c anyways
typedef struct {
/* 0x000 */ u8 codeOffs[16];
/* 0x010 */ u16 dcCodes[120];
/* 0x100 */ u16 acCodes[256];
} JpegHuffmanTableOld; // size = 0x300
typedef union {
struct {
/* 0x00 */ u32 address;
/* 0x04 */ u32 mbCount;
/* 0x08 */ u32 mode;
/* 0x0C */ u32 qTableYPtr;
/* 0x10 */ u32 qTableUPtr;
/* 0x14 */ u32 qTableVPtr;
/* 0x18 */ u32 mbSize; // This field is used by the microcode to save the macroblock size during a yield
};
long long int force_structure_alignment;
} JpegTaskData; // size = 0x20
typedef struct {
/* 0x000 */ JpegTaskData taskData;
/* 0x020 */ u64 yieldData[0x200 / sizeof(u64)];
/* 0x220 */ JpegQuantizationTable qTableY;
/* 0x2A0 */ JpegQuantizationTable qTableU;
/* 0x320 */ JpegQuantizationTable qTableV;
/* 0x3A0 */ u8 codesLengths[0x110];
/* 0x4B0 */ u16 codes[0x108];
/* 0x6C0 */ u16 data[4][0x180];
} JpegWork; // size = 0x12C0
typedef struct {
/* 0x00 */ void* imageData;
/* 0x04 */ u8 mode;
/* 0x05 */ u8 unk_05;
/* 0x08 */ JpegHuffmanTable* hTablePtrs[4];
/* 0x18 */ u8 unk_18;
} JpegDecoder; // size = 0x1C
typedef struct {
/* 0x00 */ u8 dqtCount;
/* 0x04 */ u8* dqtPtr[3];
/* 0x10 */ u8 dhtCount;
/* 0x14 */ u8* dhtPtr[4];
/* 0x24 */ void* imageData;
/* 0x28 */ u32 mode; // 0 if Y V0 is 1 and 2 if Y V0 is 2
/* 0x30 */ OSScTask scTask;
/* 0x98 */ OSMesgQueue mq;
/* 0xB0 */ OSMesg msg;
/* 0xB4 */ JpegWork* workBuf;
} JpegContext; // size = 0xB8
typedef struct {
/* 0x00 */ u32 byteIdx;
/* 0x04 */ u8 bitIdx;
/* 0x05 */ u8 dontSkip;
/* 0x08 */ u32 curWord;
/* 0x0C */ s16 unk_0C;
/* 0x0E */ s16 unk_0E;
/* 0x10 */ s16 unk_10;
} JpegDecoderState; // size = 0x14
typedef enum {
/* 0 */ VI_MODE_EDIT_STATE_INACTIVE,
/* 1 */ VI_MODE_EDIT_STATE_ACTIVE,
@ -1370,69 +819,4 @@ typedef struct {
/* 0x08 */ Color_RGBA8_u32 envColor;
} struct_80166500; // size = 0x10
typedef struct {
/* 0x00 */ char unk_00[0x18];
/* 0x18 */ s32 unk_18;
/* 0x1C */ s32 y;
} SpeedMeter; // size = 0x20
typedef struct {
/* 0x00 */ s32 maxval;
/* 0x04 */ s32 val;
/* 0x08 */ u16 backColor;
/* 0x0A */ u16 foreColor;
/* 0x0C */ s32 ulx;
/* 0x10 */ s32 lrx;
/* 0x14 */ s32 uly;
/* 0x18 */ s32 lry;
} SpeedMeterAllocEntry; // size = 0x1C
typedef struct {
/* 0x00 */ volatile OSTime* time;
/* 0x04 */ u8 x;
/* 0x05 */ u8 y;
/* 0x06 */ u16 color;
} SpeedMeterTimeEntry; // size = 0x08
typedef struct {
/* 0x00 */ u32 value;
/* 0x04 */ const char* name;
} F3dzexConst; // size = 0x8
typedef struct {
/* 0x00 */ u32 value;
/* 0x04 */ const char* setName;
/* 0x08 */ const char* unsetName;
} F3dzexFlag; // size = 0x0C
typedef struct {
/* 0x00 */ const char* name;
/* 0x04 */ u32 value;
/* 0x08 */ u32 mask;
} F3dzexRenderMode; // size = 0x0C
typedef struct {
/* 0x00 */ const char* name;
/* 0x04 */ u32 value;
} F3dzexSetModeMacroValue; // size = 0x8
typedef struct {
/* 0x00 */ const char* name;
/* 0x04 */ u32 shift;
/* 0x08 */ u32 len;
/* 0x0C */ F3dzexSetModeMacroValue values[4];
} F3dzexSetModeMacro; // size = 0x2C
typedef struct {
/* 0x00 */ u16* value;
/* 0x04 */ const char* name;
} FlagSetEntry; // size = 0x08
#define ROM_FILE(name) \
{ (uintptr_t)_##name##SegmentRomStart, (uintptr_t)_##name##SegmentRomEnd }
#define ROM_FILE_EMPTY(name) \
{ (uintptr_t)_##name##SegmentRomStart, (uintptr_t)_##name##SegmentRomStart }
#define ROM_FILE_UNSET \
{ 0 }
#endif

View file

@ -88,8 +88,12 @@ typedef enum {
/* 1 */ ANIMTAPER_ACCEL
} AnimationTapers;
#define ANIM_FLAG_0 (1 << 0) // (no effect outside of player) Related to scaling an animation from/to child/adult
#define ANIM_FLAG_UPDATE_Y (1 << 1)
#define ANIM_FLAG_PLAYER_2 (1 << 2) // (player-only) Related to scaling an animation from/to child/adult
#define ANIM_FLAG_PLAYER_SETMOVE (1 << 3) // (player-only) Call AnimationContext_SetMoveActor
#define ANIM_FLAG_NO_MOVE (1 << 4)
#define ANIM_FLAG_PLAYER_7 (1 << 7) // (player-only)
typedef struct SkelAnime {
/* 0x00 */ u8 limbCount; // Number of limbs in the skeleton
@ -287,7 +291,7 @@ typedef struct {
typedef struct {
/* 0x000 */ struct Actor* actor;
/* 0x004 */ struct SkelAnime* skelAnime;
/* 0x008 */ f32 unk_08;
/* 0x008 */ f32 diffScaleY;
} AnimEntryMoveActor; // size = 0xC
typedef union {
@ -317,7 +321,7 @@ void AnimationContext_SetCopyAll(struct PlayState* play, s32 vecCount, Vec3s* ds
void AnimationContext_SetCopyTrue(struct PlayState* play, s32 vecCount, Vec3s* dst, Vec3s* src, u8* copyFlag);
void AnimationContext_SetCopyFalse(struct PlayState* play, s32 vecCount, Vec3s* dst, Vec3s* src, u8* copyFlag);
void AnimationContext_SetInterp(struct PlayState* play, s32 vecCount, Vec3s* base, Vec3s* mod, f32 weight);
void AnimationContext_SetMoveActor(struct PlayState* play, struct Actor* actor, SkelAnime* skelAnime, f32 arg3);
void AnimationContext_SetMoveActor(struct PlayState* play, struct Actor* actor, SkelAnime* skelAnime, f32 moveDiffScaleY);
void AnimationContext_SetNextQueue(struct PlayState* play);
void AnimationContext_DisableQueue(struct PlayState* play);

View file

@ -1,16 +1,13 @@
#ifndef Z_BGCHECK_H
#define Z_BGCHECK_H
#ifndef Z64BGCHECK_H
#define Z64BGCHECK_H
#include "ultra64/ultratypes.h"
#include "z64math.h"
struct PlayState;
struct Actor;
struct DynaPolyActor;
#define COLPOLY_NORMAL_FRAC (1.0f / SHT_MAX)
#define COLPOLY_SNORMAL(x) ((s16)((x) * SHT_MAX))
#define COLPOLY_GET_NORMAL(n) ((n)*COLPOLY_NORMAL_FRAC)
#define COLPOLY_VIA_FLAG_TEST(vIA, flags) ((vIA) & (((flags)&7) << 13))
#define COLPOLY_VTX_INDEX(vI) ((vI)&0x1FFF)
#define DYNAPOLY_INVALIDATE_LOOKUP (1 << 0)
#define BGACTOR_NEG_ONE -1
@ -27,10 +24,30 @@ struct DynaPolyActor;
#define FUNC_80041EA4_VOID_OUT 12
typedef struct {
Vec3f scale;
Vec3s rot;
Vec3f pos;
} ScaleRotPos;
/* 0x00 */ Vec3f scale;
/* 0x0C */ Vec3s rot;
/* 0x14 */ Vec3f pos;
} ScaleRotPos; // size = 0x20
// Macros for `CollisionPoly`
#define COLPOLY_NORMAL_FRAC (1.0f / SHT_MAX)
#define COLPOLY_SNORMAL(x) ((s16)((x) * SHT_MAX))
#define COLPOLY_GET_NORMAL(n) ((n)*COLPOLY_NORMAL_FRAC)
#define COLPOLY_VTX_CHECK_FLAGS_ANY(vI, flags) ((vI) & (((flags) & 7) << 13))
#define COLPOLY_VTX_FLAGS_MASKED(vI) ((vI) & 0xE000)
#define COLPOLY_VTX_INDEX(vI) ((vI) & 0x1FFF)
#define COLPOLY_VTX(vtxId, flags) ((((flags) & 7) << 13) | ((vtxId) & 0x1FFF))
// flags for flags_vIA
// poly exclusion flags (xpFlags)
#define COLPOLY_IGNORE_NONE 0
#define COLPOLY_IGNORE_CAMERA (1 << 0)
#define COLPOLY_IGNORE_ENTITY (1 << 1)
#define COLPOLY_IGNORE_PROJECTILES (1 << 2)
// flags for flags_vIB
#define COLPOLY_IS_FLOOR_CONVEYOR (1 << 0)
typedef struct {
/* 0x00 */ u16 type;
@ -39,7 +56,7 @@ typedef struct {
struct {
/* 0x02 */ u16 flags_vIA; // 0xE000 is poly exclusion flags (xpFlags), 0x1FFF is vtxId
/* 0x04 */ u16 flags_vIB; // 0xE000 is flags, 0x1FFF is vtxId
// 0x2000 = poly IsConveyor surface
// 0x2000 = poly IsFloorConveyor surface
/* 0x06 */ u16 vIC;
};
};
@ -75,29 +92,18 @@ typedef struct {
// Macros for `WaterBox.properties`
#define WATERBOX_BGCAM_INDEX_SHIFT 0
#define WATERBOX_BGCAM_INDEX_MASK 0x000000FF
#define WATERBOX_BGCAM_INDEX(properties) \
(((properties) >> WATERBOX_BGCAM_INDEX_SHIFT) & (WATERBOX_BGCAM_INDEX_MASK >> WATERBOX_BGCAM_INDEX_SHIFT))
#define WATERBOX_LIGHT_INDEX_SHIFT 8
#define WATERBOX_LIGHT_INDEX_MASK 0x00001F00
#define WATERBOX_LIGHT_INDEX(properties) \
(((properties) >> WATERBOX_LIGHT_INDEX_SHIFT) & (WATERBOX_LIGHT_INDEX_MASK >> WATERBOX_LIGHT_INDEX_SHIFT))
#define WATERBOX_LIGHT_INDEX_NONE 0x1F // warns and defaults to 0
#define WATERBOX_ROOM_SHIFT 13
#define WATERBOX_ROOM_MASK 0x0007E000
#define WATERBOX_ROOM(properties) (((properties) >> WATERBOX_ROOM_SHIFT) & (WATERBOX_ROOM_MASK >> WATERBOX_ROOM_SHIFT))
#define WATERBOX_ROOM(properties) (((properties) >> 13) & 0x3F)
#define WATERBOX_ROOM_ALL 0x3F // value for "room index" indicating "all rooms"
#define WATERBOX_FLAG_19_SHIFT 19
#define WATERBOX_FLAG_19 (1 << WATERBOX_FLAG_19_SHIFT)
#define WATERBOX_FLAG_19 (1 << 19)
#define WATERBOX_PROPERTIES(bgCamIndex, lightIndex, room, setFlag19) \
((((bgCamIndex) << WATERBOX_BGCAM_INDEX_SHIFT) & WATERBOX_BGCAM_INDEX_MASK) | \
(((lightIndex) << WATERBOX_LIGHT_INDEX_SHIFT) & WATERBOX_LIGHT_INDEX_MASK) | \
(((room) << WATERBOX_ROOM_SHIFT) & WATERBOX_ROOM_MASK) | (((setFlag19) & 1) << WATERBOX_FLAG_19_SHIFT))
#define WATERBOX_PROPERTIES(bgCamIndex, lightIndex, room, setFlag19) \
((((bgCamIndex) & 0xFF) << 0) | \
(((lightIndex) & 0x1F) << 8) | \
(((room) & 0x3F) << 13) | \
(((setFlag19) & 1) << 19))
typedef struct {
/* 0x00 */ s16 xMin;
@ -213,6 +219,27 @@ typedef enum {
} ConveyorSpeed;
#define CONVEYOR_DIRECTION_TO_BINANG(conveyorDirection) ((conveyorDirection) * (0x10000 / 64))
#define CONVEYOR_DIRECTION_FROM_BINANG(conveyorDirectionBinang) ((conveyorDirectionBinang) * (64 / 0x10000))
#define SURFACETYPE0(bgCamIndex, exitIndex, floorType, unk18, wallType, floorProperty, isSoft, isHorseBlocked) \
((((bgCamIndex) & 0xFF) << 0) | \
(((exitIndex) & 0x1F) << 8) | \
(((floorType) & 0x1F) << 13) | \
(((unk18) & 0x07) << 18) | \
(((wallType) & 0x1F) << 21) | \
(((floorProperty) & 0x0F) << 26) | \
(((isSoft) & 1) << 30) | \
(((isHorseBlocked) & 1) << 31))
#define SURFACETYPE1(material, floorEffect, lightSetting, echo, canHookshot, conveyorSpeed, conveyorDirection, unk27) \
((((material) & 0x0F) << 0) | \
(((floorEffect) & 0x03) << 4) | \
(((lightSetting) & 0x1F) << 6) | \
(((echo) & 0x3F) << 11) | \
(((canHookshot) & 1) << 17) | \
(((conveyorSpeed) & 0x07) << 18) | \
(((conveyorDirection) & 0x3F) << 21) | \
(((unk27) & 1) << 27))
typedef struct {
u32 data[2];

View file

@ -1,12 +1,11 @@
#ifndef Z_COLLISION_CHECK_H
#define Z_COLLISION_CHECK_H
#ifndef Z64COLLISION_CHECK_H
#define Z64COLLISION_CHECK_H
#define COLLISION_CHECK_AT_MAX 50
#define COLLISION_CHECK_AC_MAX 60
#define COLLISION_CHECK_OC_MAX 50
#define COLLISION_CHECK_OC_LINE_MAX 3
// From z64.h
struct Actor;
typedef struct {

View file

@ -513,4 +513,21 @@ typedef struct {
/* 0x8 */ s16 relativeToPlayer;
} CutsceneCameraMove; // size = 0xC
typedef struct {
/* 0x00 */ char unk_00[0x4];
/* 0x04 */ void* script;
/* 0x08 */ u8 state;
/* 0x0C */ f32 timer;
/* 0x10 */ u16 curFrame; // current frame of the script that is running
/* 0x12 */ u16 unk_12; // set but never used
/* 0x14 */ s32 subCamId;
/* 0x18 */ u16 camEyeSplinePointsAppliedFrame; // stores the frame the cam eye spline points data was last applied on
/* 0x1A */ u8 camAtReady; // cam `at` data is ready to be applied
/* 0x1B */ u8 camEyeReady; // cam `eye` data is ready to be applied
/* 0x1C */ CutsceneCameraPoint* camAtPoints;
/* 0x20 */ CutsceneCameraPoint* camEyePoints;
/* 0x24 */ CsCmdActorCue* playerCue;
/* 0x28 */ CsCmdActorCue* actorCues[10]; // "npcdemopnt"
} CutsceneContext; // size = 0x50
#endif

View file

@ -22,6 +22,18 @@ typedef struct {
/* 0x0C */ uintptr_t romEnd;
} DmaEntry;
typedef struct {
/* 0x00 */ uintptr_t vromStart;
/* 0x04 */ uintptr_t vromEnd;
} RomFile; // size = 0x8
#define ROM_FILE(name) \
{ (uintptr_t)_##name##SegmentRomStart, (uintptr_t)_##name##SegmentRomEnd }
#define ROM_FILE_EMPTY(name) \
{ (uintptr_t)_##name##SegmentRomStart, (uintptr_t)_##name##SegmentRomStart }
#define ROM_FILE_UNSET \
{ 0 }
extern DmaEntry gDmaDataTable[];
extern u32 gDmaMgrVerbose;

51
include/z64game.h Normal file
View file

@ -0,0 +1,51 @@
#ifndef Z64GAME_H
#define Z64GAME_H
// This file is named "game" after game.c for now, this may change later with the system name
#include "ultra64/ultratypes.h"
#include "padmgr.h"
#include "tha.h"
struct GraphicsContext;
typedef struct GameAllocEntry {
/* 0x00 */ struct GameAllocEntry* next;
/* 0x04 */ struct GameAllocEntry* prev;
/* 0x08 */ u32 size;
/* 0x0C */ u32 unk_0C;
} GameAllocEntry; // size = 0x10
typedef struct {
/* 0x00 */ GameAllocEntry base;
/* 0x10 */ GameAllocEntry* head;
} GameAlloc; // size = 0x14
// Used in Graph_GetNextGameState in graph.c
#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) enumName,
#define DEFINE_GAMESTATE(typeName, enumName, name) DEFINE_GAMESTATE_INTERNAL(typeName, enumName)
typedef enum {
#include "tables/gamestate_table.h"
GAMESTATE_ID_MAX
} GameStateId;
#undef DEFINE_GAMESTATE
#undef DEFINE_GAMESTATE_INTERNAL
struct GameState;
typedef void (*GameStateFunc)(struct GameState* gameState);
typedef struct GameState {
/* 0x00 */ struct GraphicsContext* gfxCtx;
/* 0x04 */ GameStateFunc main;
/* 0x08 */ GameStateFunc destroy; // "cleanup"
/* 0x0C */ GameStateFunc init;
/* 0x10 */ u32 size;
/* 0x14 */ Input input[MAXCONTROLLERS];
/* 0x74 */ TwoHeadArena tha;
/* 0x84 */ GameAlloc alloc;
/* 0x98 */ u32 running;
/* 0x9C */ u32 frames;
/* 0xA0 */ u32 inPreNMIState;
} GameState; // size = 0xA4
#endif

View file

@ -29,6 +29,120 @@ extern u8 _icon_item_24_staticSegmentRomStart[];
#define GET_QUEST_ICON_VROM(itemId) \
((uintptr_t)_icon_item_24_staticSegmentRomStart + (((itemId)-ITEM_MEDALLION_FOREST) * QUEST_ICON_SIZE))
typedef enum {
/* 0x00 */ DO_ACTION_ATTACK,
/* 0x01 */ DO_ACTION_CHECK,
/* 0x02 */ DO_ACTION_ENTER,
/* 0x03 */ DO_ACTION_RETURN,
/* 0x04 */ DO_ACTION_OPEN,
/* 0x05 */ DO_ACTION_JUMP,
/* 0x06 */ DO_ACTION_DECIDE,
/* 0x07 */ DO_ACTION_DIVE,
/* 0x08 */ DO_ACTION_FASTER,
/* 0x09 */ DO_ACTION_THROW,
/* 0x0A */ DO_ACTION_NONE, // in do_action_static, the texture at this position is NAVI, however this value is in practice the "No Action" value
/* 0x0B */ DO_ACTION_CLIMB,
/* 0x0C */ DO_ACTION_DROP,
/* 0x0D */ DO_ACTION_DOWN,
/* 0x0E */ DO_ACTION_SAVE,
/* 0x0F */ DO_ACTION_SPEAK,
/* 0x10 */ DO_ACTION_NEXT,
/* 0x11 */ DO_ACTION_GRAB,
/* 0x12 */ DO_ACTION_STOP,
/* 0x13 */ DO_ACTION_PUTAWAY,
/* 0x14 */ DO_ACTION_REEL,
/* 0x15 */ DO_ACTION_1,
/* 0x16 */ DO_ACTION_2,
/* 0x17 */ DO_ACTION_3,
/* 0x18 */ DO_ACTION_4,
/* 0x19 */ DO_ACTION_5,
/* 0x1A */ DO_ACTION_6,
/* 0x1B */ DO_ACTION_7,
/* 0x1C */ DO_ACTION_8,
/* 0x1D */ DO_ACTION_MAX
} DoAction;
// TODO extract this information from the texture definitions themselves
#define DO_ACTION_TEX_WIDTH 48
#define DO_ACTION_TEX_HEIGHT 16
#define DO_ACTION_TEX_SIZE ((DO_ACTION_TEX_WIDTH * DO_ACTION_TEX_HEIGHT) / 2) // (sizeof(gCheckDoActionENGTex))
typedef struct {
/* 0x0000 */ View view;
/* 0x0128 */ Vtx* actionVtx;
/* 0x012C */ Vtx* beatingHeartVtx;
/* 0x0130 */ u8* parameterSegment;
/* 0x0134 */ u8* doActionSegment;
/* 0x0138 */ u8* iconItemSegment;
/* 0x013C */ u8* mapSegment;
/* 0x0140 */ u8 mapPalette[32];
/* 0x0160 */ DmaRequest dmaRequest_160;
/* 0x0180 */ DmaRequest dmaRequest_180;
/* 0x01A0 */ char unk_1A0[0x20];
/* 0x01C0 */ OSMesgQueue loadQueue;
/* 0x01D8 */ OSMesg loadMsg;
/* 0x01DC */ Viewport viewport;
/* 0x01EC */ s16 unk_1EC;
/* 0x01EE */ u16 unk_1EE;
/* 0x01F0 */ u16 unk_1F0;
/* 0x01F4 */ f32 unk_1F4;
/* 0x01F8 */ s16 naviCalling;
/* 0x01FA */ s16 unk_1FA;
/* 0x01FC */ s16 unk_1FC;
/* 0x01FE */ s16 heartColorOscillator;
/* 0x0200 */ s16 heartColorOscillatorDirection;
/* 0x0202 */ s16 beatingHeartPrim[3];
/* 0x0208 */ s16 beatingHeartEnv[3];
/* 0x020E */ s16 heartsPrimR[2];
/* 0x0212 */ s16 heartsPrimG[2];
/* 0x0216 */ s16 heartsPrimB[2];
/* 0x021A */ s16 heartsEnvR[2];
/* 0x021E */ s16 heartsEnvG[2];
/* 0x0222 */ s16 heartsEnvB[2];
/* 0x0226 */ s16 unk_226; // Used only in unused functions
/* 0x0228 */ s16 unk_228; // Used only in unused functions
/* 0x022A */ s16 beatingHeartOscillator;
/* 0x022C */ s16 beatingHeartOscillatorDirection;
/* 0x022E */ s16 unk_22E;
/* 0x0230 */ s16 lensMagicConsumptionTimer; // When lens is active, 1 unit of magic is consumed every time the timer reaches 0
/* 0x0232 */ s16 counterDigits[4]; // used for key and rupee counters
/* 0x023A */ u8 numHorseBoosts;
/* 0x023C */ u16 unk_23C;
/* 0x023E */ u16 hbaAmmo; // ammo while playing the horseback archery minigame
/* 0x0240 */ u16 unk_240;
/* 0x0242 */ u16 unk_242;
/* 0x0224 */ u16 unk_244; // screen fill alpha?
/* 0x0246 */ u16 aAlpha; // also carrots alpha
/* 0x0248 */ u16 bAlpha; // also HBA score alpha
/* 0x024A */ u16 cLeftAlpha;
/* 0x024C */ u16 cDownAlpha;
/* 0x024E */ u16 cRightAlpha;
/* 0x0250 */ u16 healthAlpha; // also max C-Up alpha
/* 0x0252 */ u16 magicAlpha; // also Rupee and Key counters alpha
/* 0x0254 */ u16 minimapAlpha;
/* 0x0256 */ s16 startAlpha;
/* 0x0258 */ s16 unk_258;
/* 0x025A */ s16 unk_25A;
/* 0x025C */ s16 mapRoomNum;
/* 0x025E */ s16 mapPaletteIndex; // "map_palete_no"
/* 0x0260 */ u8 unk_260;
/* 0x0261 */ u8 unk_261;
struct {
/* 0x0262 */ u8 hGauge; // "h_gage"; unknown?
/* 0x0263 */ u8 bButton; // "b_button"
/* 0x0264 */ u8 aButton; // "a_button"
/* 0x0265 */ u8 bottles; // "c_bottle"
/* 0x0266 */ u8 tradeItems; // "c_warasibe"
/* 0x0267 */ u8 hookshot; // "c_hook"
/* 0x0268 */ u8 ocarina; // "c_ocarina"
/* 0x0269 */ u8 warpSongs; // "c_warp"
/* 0x026A */ u8 sunsSong; // "m_sunmoon"
/* 0x026B */ u8 farores; // "m_wind"
/* 0x026C */ u8 dinsNayrus; // "m_magic"; din's fire and nayru's love
/* 0x026D */ u8 all; // "another"; enables all item restrictions
} restrictions;
} InterfaceContext; // size = 0x270
/**
* Button HUD Positions (Upper Left)
*/

View file

@ -1,8 +1,29 @@
#ifndef Z64OBJECT_H
#define Z64OBJECT_H
#include "ultra64.h"
#include "z64dma.h"
#define OBJECT_EXCHANGE_BANK_MAX 19
typedef struct {
/* 0x00 */ s16 id;
/* 0x04 */ void* segment;
/* 0x08 */ DmaRequest dmaRequest;
/* 0x28 */ OSMesgQueue loadQueue;
/* 0x40 */ OSMesg loadMsg;
} ObjectStatus; // size = 0x44
typedef struct {
/* 0x0000 */ void* spaceStart;
/* 0x0004 */ void* spaceEnd; // original name: "endSegment"
/* 0x0008 */ u8 num; // number of objects in bank
/* 0x0009 */ u8 unk_09;
/* 0x000A */ u8 mainKeepIndex; // "gameplay_keep" index in bank
/* 0x000B */ u8 subKeepIndex; // "gameplay_field_keep" or "gameplay_dangeon_keep" index in bank
/* 0x000C */ ObjectStatus status[OBJECT_EXCHANGE_BANK_MAX];
} ObjectContext; // size = 0x518
#define DEFINE_OBJECT(_0, enum) enum,
#define DEFINE_OBJECT_NULL(_0, enum) enum,
#define DEFINE_OBJECT_UNSET(enum) enum,

View file

@ -350,6 +350,18 @@ typedef enum {
/* 0x06 */ HS_DAMPE_RACE
} HighScores;
// the score value for the fishing minigame also stores many flags.
#define HS_FISH_LENGTH_CHILD 0x7F // mask for record length of catch as child.
#define HS_FISH_LENGTH_ADULT 0x7F000000 // mask for record length of catch as adult.
#define HS_FISH_PLAYED_CHILD 0x100 // set when first talking to owner as child
#define HS_FISH_PLAYED_ADULT 0x200 // set when first talking to owner as adult
#define HS_FISH_PRIZE_CHILD 0x400 // won the Piece of Heart
#define HS_FISH_PRIZE_ADULT 0x800 // won the Golden Scale
#define HS_FISH_STOLE_HAT 0x1000 // Pond owner is visibly bald as Adult Link.
#define HS_FISH_CHEAT_CHILD 0x80 // used Sinking Lure as child to catch record fish
#define HS_FISH_CHEAT_ADULT 0x80000000 // used Sinking Lure as adult to catch record fish
#define HS_FISH_PLAYED 0x10000 // incremented for every play. controls weather.
typedef enum {
/* 0 */ SUNSSONG_INACTIVE,
/* 1 */ SUNSSONG_START, // the suns ocarina effect signals that the song has finished playing
@ -413,7 +425,7 @@ typedef enum {
#define EVENTCHKINF_1B 0x1B
#define EVENTCHKINF_1C 0x1C
#define EVENTCHKINF_1D 0x1D
#define EVENTCHKINF_1E 0x1E
#define EVENTCHKINF_HORSE_RACE_COW_UNLOCK 0x1E
#define EVENTCHKINF_20 0x20
#define EVENTCHKINF_21 0x21
#define EVENTCHKINF_22 0x22

View file

@ -2,14 +2,10 @@
#define Z64SCENE_H
#include "z64.h"
#include "z64dma.h" // for RomFile
#include "command_macros_base.h"
typedef struct {
/* 0x00 */ uintptr_t vromStart;
/* 0x04 */ uintptr_t vromEnd;
} RomFile; // size = 0x8
typedef struct {
/* 0x00 */ RomFile sceneFile;
/* 0x08 */ RomFile titleFile;

View file

@ -5,7 +5,7 @@
#include "ultra64/gbi.h"
#include "z64math.h"
#include "z64scene.h" // for RomFile
#include "z64dma.h" // for RomFile
struct GameState;
struct GraphicsContext;

20
include/z64sram.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef Z64SRAM_H
#define Z64SRAM_H
#include "ultra64/ultratypes.h"
typedef struct {
/* 0x00 */ u8* readBuff;
} SramContext; // size = 0x4
#define SRAM_SIZE 0x8000
#define SRAM_HEADER_SIZE 0x10
typedef enum {
/* 0x00 */ SRAM_HEADER_SOUND,
/* 0x01 */ SRAM_HEADER_ZTARGET,
/* 0x02 */ SRAM_HEADER_LANGUAGE,
/* 0x03 */ SRAM_HEADER_MAGIC // must be the value of `sZeldaMagic` for save to be considered valid
} SramHeaderField;
#endif

View file

@ -1,85 +1,84 @@
#ifndef Z64TRANSITION_H
#define Z64TRANSITION_H
#include "ultra64.h"
#include "color.h"
#include "ultra64/ultratypes.h"
#include "ultra64/gbi.h" // for Gfx
#include "z64transition_instances.h"
typedef struct {
/* 0x0 */ f32 x;
/* 0x4 */ f32 y;
} TransitionTileVtxData; // size = 0x8
typedef struct {
/* 0x00 */ s32 cols;
/* 0x04 */ s32 rows;
/* 0x08 */ s32 frame;
/* 0x0C */ TransitionTileVtxData* vtxData;
/* 0x10 */ Vtx* vtxFrame1;
/* 0x14 */ Vtx* vtxFrame2;
/* 0x18 */ Mtx projection;
/* 0x58 */ Mtx modelView;
/* 0x98 */ Mtx unk_98;
/* 0xD8 */ Gfx* gfx; // "gfxtbl"
/* 0xDC */ u16* zBuffer;
} TransitionTile; // size = 0xE0
#define TRANS_TRIGGER_OFF 0 // transition is not active
#define TRANS_TRIGGER_START 20 // start transition (exiting an area)
#define TRANS_TRIGGER_END -20 // transition is ending (arriving in a new area)
typedef enum {
/* 1 */ TRANS_INSTANCE_TYPE_FILL_OUT = 1,
/* 2 */ TRANS_INSTANCE_TYPE_FILL_IN
} TransitionInstanceType;
/* 0 */ TRANS_MODE_OFF,
/* 1 */ TRANS_MODE_SETUP,
/* 2 */ TRANS_MODE_INSTANCE_INIT,
/* 3 */ TRANS_MODE_INSTANCE_RUNNING,
/* 4 */ TRANS_MODE_FILL_WHITE_INIT,
/* 5 */ TRANS_MODE_FILL_IN,
/* 6 */ TRANS_MODE_FILL_OUT,
/* 7 */ TRANS_MODE_FILL_BROWN_INIT,
/* 8 */ TRANS_MODE_08, // unused
/* 9 */ TRANS_MODE_09, // unused
/* 10 */ TRANS_MODE_INSTANT,
/* 11 */ TRANS_MODE_INSTANCE_WAIT,
/* 12 */ TRANS_MODE_SANDSTORM_INIT,
/* 13 */ TRANS_MODE_SANDSTORM,
/* 14 */ TRANS_MODE_SANDSTORM_END_INIT,
/* 15 */ TRANS_MODE_SANDSTORM_END,
/* 16 */ TRANS_MODE_CS_BLACK_FILL_INIT,
/* 17 */ TRANS_MODE_CS_BLACK_FILL
} TransitionMode;
typedef enum {
/* 0 */ TRANS_TYPE_WIPE,
/* 1 */ TRANS_TYPE_TRIFORCE,
/* 2 */ TRANS_TYPE_FADE_BLACK,
/* 3 */ TRANS_TYPE_FADE_WHITE,
/* 4 */ TRANS_TYPE_FADE_BLACK_FAST,
/* 5 */ TRANS_TYPE_FADE_WHITE_FAST,
/* 6 */ TRANS_TYPE_FADE_BLACK_SLOW,
/* 7 */ TRANS_TYPE_FADE_WHITE_SLOW,
/* 8 */ TRANS_TYPE_WIPE_FAST,
/* 9 */ TRANS_TYPE_FILL_WHITE2,
/* 10 */ TRANS_TYPE_FILL_WHITE,
/* 11 */ TRANS_TYPE_INSTANT,
/* 12 */ TRANS_TYPE_FILL_BROWN,
/* 13 */ TRANS_TYPE_FADE_WHITE_CS_DELAYED,
/* 14 */ TRANS_TYPE_SANDSTORM_PERSIST,
/* 15 */ TRANS_TYPE_SANDSTORM_END,
/* 16 */ TRANS_TYPE_CS_BLACK_FILL,
/* 17 */ TRANS_TYPE_FADE_WHITE_INSTANT,
/* 18 */ TRANS_TYPE_FADE_GREEN,
/* 19 */ TRANS_TYPE_FADE_BLUE,
// transition types 20 - 31 are unused
// transition types 32 - 55 are constructed using the TRANS_TYPE_CIRCLE macro
/* 56 */ TRANS_TYPE_MAX = 56
} TransitionType;
#define TRANS_NEXT_TYPE_DEFAULT 0xFF // when `nextTransitionType` is set to default, the type will be taken from the entrance table for the ending transition
#define TC_SET_PARAMS (1 << 7)
#define TRANS_TYPE_CIRCLE(appearance, color, speed) ((1 << 5) | ((color & 3) << 3) | ((appearance & 3) << 1) | (speed & 1))
typedef struct {
/* 0x000 */ Color_RGBA8_u32 color;
/* 0x004 */ Color_RGBA8_u32 unkColor;
/* 0x008 */ u8 direction;
/* 0x009 */ u8 frame;
/* 0x00A */ u8 isDone;
/* 0x00C */ u16 texX;
/* 0x00E */ u16 texY;
/* 0x010 */ u16 normal;
/* 0x018 */ Mtx projection;
/* 0x058 */ Mtx lookAt;
/* 0x098 */ Mtx modelView[2][3];
} TransitionWipe; // size = 0x218
#define TRANS_INSTANCE_TYPE_FADE_FLASH 3
typedef struct {
/* 0x000 */ u8 type;
/* 0x001 */ u8 isDone;
/* 0x002 */ u8 direction;
/* 0x004 */ Color_RGBA8_u32 color;
/* 0x008 */ u16 timer;
} TransitionFade; // size = 0xC
typedef struct {
/* 0x000 */ Color_RGBA8_u32 color;
/* 0x004 */ Color_RGBA8_u32 unkColor;
/* 0x008 */ s32 texX;
/* 0x00C */ s32 texY;
/* 0x010 */ s32 speed;
/* 0x014 */ u8 direction;
/* 0x015 */ u8 colorType;
/* 0x016 */ u8 speedType;
/* 0x017 */ u8 appearanceType;
/* 0x018 */ u8 isDone;
/* 0x019 */ u8 frame;
/* 0x01A */ u16 normal;
/* 0x020 */ Mtx projection;
/* 0x060 */ Mtx lookAt;
/* 0x0A0 */ void* texture;
/* 0x0A8 */ Mtx modelView[2][3];
} TransitionCircle; // size = 0x228;
typedef struct {
/* 0x000 */ Color_RGBA8_u32 color;
/* 0x004 */ f32 transPos;
/* 0x008 */ f32 step;
/* 0x00C */ s32 state;
/* 0x010 */ s32 type;
/* 0x018 */ Mtx projection;
/* 0x058 */ s32 frame;
/* 0x060 */ Mtx modelView[2][3];
} TransitionTriforce; // size = 0x1E0;
union {
TransitionFade fade;
TransitionCircle circle;
TransitionTriforce triforce;
TransitionWipe wipe;
} instanceData;
/* 0x228 */ s32 transitionType;
/* 0x22C */ void* (*init)(void* transition);
/* 0x230 */ void (*destroy)(void* transition);
/* 0x234 */ void (*update)(void* transition, s32 updateRate);
/* 0x238 */ void (*draw)(void* transition, Gfx** gfxP);
/* 0x23C */ void (*start)(void* transition);
/* 0x240 */ void (*setType)(void* transition, s32 type);
/* 0x244 */ void (*setColor)(void* transition, u32 color);
/* 0x248 */ void (*setUnkColor)(void* transition, u32 color);
/* 0x24C */ s32 (*isDone)(void* transition);
} TransitionContext; // size = 0x250
#endif

View file

@ -0,0 +1,104 @@
#ifndef Z64TRANSITION_INSTANCES_H
#define Z64TRANSITION_INSTANCES_H
#include "ultra64.h"
#include "color.h"
typedef struct {
/* 0x0 */ f32 x;
/* 0x4 */ f32 y;
} TransitionTileVtxData; // size = 0x8
typedef struct {
/* 0x00 */ s32 cols;
/* 0x04 */ s32 rows;
/* 0x08 */ s32 frame;
/* 0x0C */ TransitionTileVtxData* vtxData;
/* 0x10 */ Vtx* vtxFrame1;
/* 0x14 */ Vtx* vtxFrame2;
/* 0x18 */ Mtx projection;
/* 0x58 */ Mtx modelView;
/* 0x98 */ Mtx unk_98;
/* 0xD8 */ Gfx* gfx; // "gfxtbl"
/* 0xDC */ u16* zBuffer;
} TransitionTile; // size = 0xE0
typedef enum {
/* 1 */ TRANS_INSTANCE_TYPE_FILL_OUT = 1,
/* 2 */ TRANS_INSTANCE_TYPE_FILL_IN
} TransitionInstanceType;
typedef struct {
/* 0x000 */ Color_RGBA8_u32 color;
/* 0x004 */ Color_RGBA8_u32 unkColor;
/* 0x008 */ u8 direction;
/* 0x009 */ u8 frame;
/* 0x00A */ u8 isDone;
/* 0x00C */ u16 texX;
/* 0x00E */ u16 texY;
/* 0x010 */ u16 normal;
/* 0x018 */ Mtx projection;
/* 0x058 */ Mtx lookAt;
/* 0x098 */ Mtx modelView[2][3];
} TransitionWipe; // size = 0x218
#define TRANS_INSTANCE_TYPE_FADE_FLASH 3
typedef struct {
/* 0x000 */ u8 type;
/* 0x001 */ u8 isDone;
/* 0x002 */ u8 direction;
/* 0x004 */ Color_RGBA8_u32 color;
/* 0x008 */ u16 timer;
} TransitionFade; // size = 0xC
typedef enum {
/* 0 */ TCA_NORMAL,
/* 1 */ TCA_WAVE,
/* 2 */ TCA_RIPPLE,
/* 3 */ TCA_STARBURST
} TransitionCircleAppearance;
typedef enum {
/* 0 */ TCC_BLACK,
/* 1 */ TCC_WHITE,
/* 2 */ TCC_GRAY,
/* 3 */ TCC_SPECIAL // color varies depending on appearance. unused and appears broken
} TransitionCircleColor;
typedef enum {
/* 0 */ TCS_FAST,
/* 1 */ TCS_SLOW
} TransitionCircleSpeed;
typedef struct {
/* 0x000 */ Color_RGBA8_u32 color;
/* 0x004 */ Color_RGBA8_u32 unkColor;
/* 0x008 */ s32 texX;
/* 0x00C */ s32 texY;
/* 0x010 */ s32 speed;
/* 0x014 */ u8 direction;
/* 0x015 */ u8 colorType;
/* 0x016 */ u8 speedType;
/* 0x017 */ u8 appearanceType;
/* 0x018 */ u8 isDone;
/* 0x019 */ u8 frame;
/* 0x01A */ u16 normal;
/* 0x020 */ Mtx projection;
/* 0x060 */ Mtx lookAt;
/* 0x0A0 */ void* texture;
/* 0x0A8 */ Mtx modelView[2][3];
} TransitionCircle; // size = 0x228;
typedef struct {
/* 0x000 */ Color_RGBA8_u32 color;
/* 0x004 */ f32 transPos;
/* 0x008 */ f32 step;
/* 0x00C */ s32 state;
/* 0x010 */ s32 type;
/* 0x018 */ Mtx projection;
/* 0x058 */ s32 frame;
/* 0x060 */ Mtx modelView[2][3];
} TransitionTriforce; // size = 0x1E0;
#endif

View file

@ -1,5 +1,10 @@
#include "global.h"
typedef struct {
/* 0x00 */ u16* value;
/* 0x04 */ const char* name;
} FlagSetEntry; // size = 0x08
void FlagSet_Update(PlayState* play) {
static s32 entryIdx = 0;
static u32 curBit = 0;

View file

@ -56,6 +56,13 @@ volatile OSTime D_8016A578;
// Accumulator for `gRDPTimeTotal`
volatile OSTime gRDPTimeAcc;
typedef struct {
/* 0x00 */ volatile OSTime* time;
/* 0x04 */ u8 x;
/* 0x05 */ u8 y;
/* 0x06 */ u16 color;
} SpeedMeterTimeEntry; // size = 0x08
SpeedMeterTimeEntry* sSpeedMeterTimeEntryPtr;
SpeedMeterTimeEntry sSpeedMeterTimeEntryArray[] = {

View file

@ -1,5 +1,34 @@
#include "global.h"
typedef struct {
/* 0x00 */ u32 value;
/* 0x04 */ const char* name;
} F3dzexConst; // size = 0x8
typedef struct {
/* 0x00 */ u32 value;
/* 0x04 */ const char* setName;
/* 0x08 */ const char* unsetName;
} F3dzexFlag; // size = 0x0C
typedef struct {
/* 0x00 */ const char* name;
/* 0x04 */ u32 value;
/* 0x08 */ u32 mask;
} F3dzexRenderMode; // size = 0x0C
typedef struct {
/* 0x00 */ const char* name;
/* 0x04 */ u32 value;
} F3dzexSetModeMacroValue; // size = 0x8
typedef struct {
/* 0x00 */ const char* name;
/* 0x04 */ u32 shift;
/* 0x08 */ u32 len;
/* 0x0C */ F3dzexSetModeMacroValue values[4];
} F3dzexSetModeMacro; // size = 0x2C
typedef void (*UcodeDisasCallback)(UCodeDisas*, u32);
#define F3DZEX_CONST(name) \

View file

@ -41,12 +41,6 @@ void BgCheck_ResetPolyCheckTbl(SSNodeList* nodeList, s32 numPolys);
#define BGCHECK_IGNORE_WALL (1 << 1)
#define BGCHECK_IGNORE_FLOOR (1 << 2)
// poly exclusion flags (xpFlags)
#define COLPOLY_IGNORE_NONE 0
#define COLPOLY_IGNORE_CAMERA (1 << 0)
#define COLPOLY_IGNORE_ENTITY (1 << 1)
#define COLPOLY_IGNORE_PROJECTILES (1 << 2)
// raycast down flags (downChkFlags)
#define BGCHECK_RAYCAST_DOWN_CHECK_CEILINGS (1 << 0)
#define BGCHECK_RAYCAST_DOWN_CHECK_WALLS (1 << 1)
@ -579,7 +573,7 @@ f32 BgCheck_RaycastDownStaticList(CollisionContext* colCtx, u16 xpFlags, SSList*
while (true) {
polyId = curNode->polyId;
if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[polyId].flags_vIA, xpFlags) ||
if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[polyId].flags_vIA, xpFlags) ||
((groundChk & BGCHECK_GROUND_CHECK_ON) && colCtx->colHeader->polyList[polyId].normal.y < 0)) {
if (curNode->next == SS_NULL) {
break;
@ -735,7 +729,7 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16
nz = COLPOLY_GET_NORMAL(curPoly->normal.z);
normalXZ = sqrtf(SQ(nx) + SQ(nz));
planeDist = Math3D_DistPlaneToPos(nx, ny, nz, curPoly->dist, &resultPos);
if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags)) {
if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -816,7 +810,7 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16
nz = COLPOLY_GET_NORMAL(curPoly->normal.z);
normalXZ = sqrtf(SQ(nx) + SQ(nz));
planeDist = Math3D_DistPlaneToPos(nx, ny, nz, curPoly->dist, &resultPos);
if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags)) {
if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -916,7 +910,7 @@ s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionConte
while (true) {
curPolyId = curNode->polyId;
if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) {
if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -977,8 +971,8 @@ s32 BgCheck_CheckLineAgainstSSList(SSList* ssList, CollisionContext* colCtx, u16
polyId = curNode->polyId;
checkedPoly = &colCtx->polyNodes.polyCheckTbl[polyId];
if (*checkedPoly == true || COLPOLY_VIA_FLAG_TEST(polyList[polyId].flags_vIA, xpFlags1) ||
!(xpFlags2 == 0 || COLPOLY_VIA_FLAG_TEST(polyList[polyId].flags_vIA, xpFlags2))) {
if (*checkedPoly == true || COLPOLY_VTX_CHECK_FLAGS_ANY(polyList[polyId].flags_vIA, xpFlags1) ||
!(xpFlags2 == 0 || COLPOLY_VTX_CHECK_FLAGS_ANY(polyList[polyId].flags_vIA, xpFlags2))) {
if (curNode->next == SS_NULL) {
break;
@ -1064,7 +1058,7 @@ s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext
while (true) {
curPolyId = node->polyId;
curPoly = &polyList[curPolyId];
if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) {
if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) {
if (node->next == SS_NULL) {
break;
} else {
@ -2964,10 +2958,10 @@ void DynaPoly_AddBgActorToLookup(PlayState* play, DynaCollisionContext* dyna, s3
*newPoly = pbgdata->polyList[i];
// Yeah, this is all kinds of fake, but my God, it matches.
newPoly->flags_vIA =
(COLPOLY_VTX_INDEX(newPoly->flags_vIA) + *vtxStartIndex) | ((*newPoly).flags_vIA & 0xE000);
newPoly->flags_vIB =
(COLPOLY_VTX_INDEX(newPoly->flags_vIB) + *vtxStartIndex) | ((*newPoly).flags_vIB & 0xE000);
newPoly->flags_vIA = (COLPOLY_VTX_INDEX(newPoly->flags_vIA) + *vtxStartIndex) |
COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIA);
newPoly->flags_vIB = (COLPOLY_VTX_INDEX(newPoly->flags_vIB) + *vtxStartIndex) |
COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIB);
newPoly->vIC = *vtxStartIndex + newPoly->vIC;
dVtxList = dyna->vtxList;
vtxA.x = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].x;
@ -3116,7 +3110,7 @@ f32 BgCheck_RaycastDownDynaList(DynaRaycastDown* dynaRaycastDown, u32 listType)
while (true) {
id = curNode->polyId;
if (COLPOLY_VIA_FLAG_TEST(polyList[id].flags_vIA, dynaRaycastDown->xpFlags)) {
if (COLPOLY_VTX_CHECK_FLAGS_ANY(polyList[id].flags_vIA, dynaRaycastDown->xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -3319,7 +3313,7 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo
ASSERT(!IS_ZERO(normalXZ), "!IS_ZERO(ac_size)", "../z_bgcheck.c", 7382);
planeDist = Math3D_DistPlaneToPos(nx, ny, nz, poly->dist, &resultPos);
if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags)) {
if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -3392,7 +3386,7 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo
ASSERT(!IS_ZERO(normalXZ), "!IS_ZERO(ac_size)", "../z_bgcheck.c", 7489);
planeDist = Math3D_DistPlaneToPos(nx, ny, nz, poly->dist, &resultPos);
if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags)) {
if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -3548,7 +3542,7 @@ s32 BgCheck_CheckDynaCeilingList(CollisionContext* colCtx, u16 xpFlags, DynaColl
while (true) {
polyId = curNode->polyId;
poly = &dyna->polyList[polyId];
if (COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags)) {
if (COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -3648,7 +3642,7 @@ s32 BgCheck_CheckLineAgainstBgActorSSList(DynaLineTest* dynaLineTest) {
while (true) {
polyId = curNode->polyId;
curPoly = &dynaLineTest->dyna->polyList[polyId];
if (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, dynaLineTest->xpFlags)) {
if (COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, dynaLineTest->xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -3781,7 +3775,7 @@ s32 BgCheck_SphVsFirstDynaPolyList(CollisionContext* colCtx, u16 xpFlags, Collis
while (true) {
curPolyId = curNode->polyId;
curPoly = &dyna->polyList[curPolyId];
if (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags)) {
if (COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
break;
} else {
@ -4155,7 +4149,7 @@ s32 SurfaceType_IsIgnoredByEntities(CollisionContext* colCtx, CollisionPoly* pol
if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) {
return true;
}
flags = poly->flags_vIA & 0x4000;
flags = COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, COLPOLY_IGNORE_ENTITY);
return !!flags;
}
@ -4169,7 +4163,7 @@ s32 SurfaceType_IsIgnoredByProjectiles(CollisionContext* colCtx, CollisionPoly*
if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) {
return true;
}
flags = poly->flags_vIA & 0x8000;
flags = COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, COLPOLY_IGNORE_PROJECTILES);
return !!flags;
}
@ -4188,7 +4182,7 @@ s32 SurfaceType_IsFloorConveyor(CollisionContext* colCtx, CollisionPoly* poly, s
if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) {
return true;
}
flags = poly->flags_vIB & 0x2000;
flags = COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIB, COLPOLY_IS_FLOOR_CONVEYOR);
return !!flags;
}
@ -4318,7 +4312,7 @@ s32 WaterBox_GetSurface2(PlayState* play, CollisionContext* colCtx, Vec3f* pos,
* WaterBox get BgCam index
*/
u32 WaterBox_GetBgCamIndex(CollisionContext* colCtx, WaterBox* waterBox) {
u32 bgCamIndex = WATERBOX_BGCAM_INDEX(waterBox->properties);
u32 bgCamIndex = waterBox->properties & 0xFF;
return bgCamIndex;
}
@ -4341,7 +4335,7 @@ u16 WaterBox_GetBgCamSetting(CollisionContext* colCtx, WaterBox* waterBox) {
* WaterBox get lighting settings
*/
u32 WaterBox_GetLightIndex(CollisionContext* colCtx, WaterBox* waterBox) {
u32 lightIndex = WATERBOX_LIGHT_INDEX(waterBox->properties);
u32 lightIndex = (waterBox->properties >> 8) & 0x1F;
return lightIndex;
}

View file

@ -295,9 +295,9 @@ void EffectBlure_GetComputedValues(EffectBlure* this, s32 index, f32 ratio, Vec3
switch (this->calcMode) {
case 1:
vec1->x = func_80027E34(elem->p1.x, elem->p2.x, ratio);
vec1->y = func_80027E34(elem->p1.y, elem->p2.y, ratio);
vec1->z = func_80027E34(elem->p1.z, elem->p2.z, ratio);
vec1->x = EffectSs_LerpS16(elem->p1.x, elem->p2.x, ratio);
vec1->y = EffectSs_LerpS16(elem->p1.y, elem->p2.y, ratio);
vec1->z = EffectSs_LerpS16(elem->p1.z, elem->p2.z, ratio);
vec2->x = elem->p2.x;
vec2->y = elem->p2.y;
vec2->z = elem->p2.z;
@ -307,19 +307,19 @@ void EffectBlure_GetComputedValues(EffectBlure* this, s32 index, f32 ratio, Vec3
vec1->x = elem->p1.x;
vec1->y = elem->p1.y;
vec1->z = elem->p1.z;
vec2->x = func_80027E34(elem->p2.x, elem->p1.x, ratio);
vec2->y = func_80027E34(elem->p2.y, elem->p1.y, ratio);
vec2->z = func_80027E34(elem->p2.z, elem->p1.z, ratio);
vec2->x = EffectSs_LerpS16(elem->p2.x, elem->p1.x, ratio);
vec2->y = EffectSs_LerpS16(elem->p2.y, elem->p1.y, ratio);
vec2->z = EffectSs_LerpS16(elem->p2.z, elem->p1.z, ratio);
break;
case 3:
ratio *= 0.5f;
vec1->x = func_80027E34(elem->p1.x, elem->p2.x, ratio);
vec1->y = func_80027E34(elem->p1.y, elem->p2.y, ratio);
vec1->z = func_80027E34(elem->p1.z, elem->p2.z, ratio);
vec2->x = func_80027E34(elem->p2.x, elem->p1.x, ratio);
vec2->y = func_80027E34(elem->p2.y, elem->p1.y, ratio);
vec2->z = func_80027E34(elem->p2.z, elem->p1.z, ratio);
vec1->x = EffectSs_LerpS16(elem->p1.x, elem->p2.x, ratio);
vec1->y = EffectSs_LerpS16(elem->p1.y, elem->p2.y, ratio);
vec1->z = EffectSs_LerpS16(elem->p1.z, elem->p2.z, ratio);
vec2->x = EffectSs_LerpS16(elem->p2.x, elem->p1.x, ratio);
vec2->y = EffectSs_LerpS16(elem->p2.y, elem->p1.y, ratio);
vec2->z = EffectSs_LerpS16(elem->p2.z, elem->p1.z, ratio);
ratio *= 2.0f;
break;
@ -356,14 +356,14 @@ void EffectBlure_GetComputedValues(EffectBlure* this, s32 index, f32 ratio, Vec3
color1->r = color1->g = color1->b = color1->a = 255;
color2->r = color2->g = color2->b = color2->a = 255;
} else {
color1->r = func_80027E84(this->p1StartColor[0], this->p1EndColor[0], ratio);
color1->g = func_80027E84(this->p1StartColor[1], this->p1EndColor[1], ratio);
color1->b = func_80027E84(this->p1StartColor[2], this->p1EndColor[2], ratio);
color1->a = func_80027E84(this->p1StartColor[3], this->p1EndColor[3], ratio);
color2->r = func_80027E84(this->p2StartColor[0], this->p2EndColor[0], ratio);
color2->g = func_80027E84(this->p2StartColor[1], this->p2EndColor[1], ratio);
color2->b = func_80027E84(this->p2StartColor[2], this->p2EndColor[2], ratio);
color2->a = func_80027E84(this->p2StartColor[3], this->p2EndColor[3], ratio);
color1->r = EffectSs_LerpU8(this->p1StartColor[0], this->p1EndColor[0], ratio);
color1->g = EffectSs_LerpU8(this->p1StartColor[1], this->p1EndColor[1], ratio);
color1->b = EffectSs_LerpU8(this->p1StartColor[2], this->p1EndColor[2], ratio);
color1->a = EffectSs_LerpU8(this->p1StartColor[3], this->p1EndColor[3], ratio);
color2->r = EffectSs_LerpU8(this->p2StartColor[0], this->p2EndColor[0], ratio);
color2->g = EffectSs_LerpU8(this->p2StartColor[1], this->p2EndColor[1], ratio);
color2->b = EffectSs_LerpU8(this->p2StartColor[2], this->p2EndColor[2], ratio);
color2->a = EffectSs_LerpU8(this->p2StartColor[3], this->p2EndColor[3], ratio);
}
}
@ -618,18 +618,18 @@ void EffectBlure_DrawElemHermiteInterpolation(EffectBlure* this, EffectBlureElem
vtx[j1].v.ob[0] = Math_FNearbyIntF(sp158.x);
vtx[j1].v.ob[1] = Math_FNearbyIntF(sp158.y);
vtx[j1].v.ob[2] = Math_FNearbyIntF(sp158.z);
vtx[j1].v.cn[0] = func_80027E84(sp1A4.r, sp19C.r, temp_f28);
vtx[j1].v.cn[1] = func_80027E84(sp1A4.g, sp19C.g, temp_f28);
vtx[j1].v.cn[2] = func_80027E84(sp1A4.b, sp19C.b, temp_f28);
vtx[j1].v.cn[3] = func_80027E84(sp1A4.a, sp19C.a, temp_f28);
vtx[j1].v.cn[0] = EffectSs_LerpU8(sp1A4.r, sp19C.r, temp_f28);
vtx[j1].v.cn[1] = EffectSs_LerpU8(sp1A4.g, sp19C.g, temp_f28);
vtx[j1].v.cn[2] = EffectSs_LerpU8(sp1A4.b, sp19C.b, temp_f28);
vtx[j1].v.cn[3] = EffectSs_LerpU8(sp1A4.a, sp19C.a, temp_f28);
vtx[j2].v.ob[0] = Math_FNearbyIntF(sp14C.x);
vtx[j2].v.ob[1] = Math_FNearbyIntF(sp14C.y);
vtx[j2].v.ob[2] = Math_FNearbyIntF(sp14C.z);
vtx[j2].v.cn[0] = func_80027E84(sp1A0.r, sp198.r, temp_f28);
vtx[j2].v.cn[1] = func_80027E84(sp1A0.g, sp198.g, temp_f28);
vtx[j2].v.cn[2] = func_80027E84(sp1A0.b, sp198.b, temp_f28);
vtx[j2].v.cn[3] = func_80027E84(sp1A0.a, sp198.a, temp_f28);
vtx[j2].v.cn[0] = EffectSs_LerpU8(sp1A0.r, sp198.r, temp_f28);
vtx[j2].v.cn[1] = EffectSs_LerpU8(sp1A0.g, sp198.g, temp_f28);
vtx[j2].v.cn[2] = EffectSs_LerpU8(sp1A0.b, sp198.b, temp_f28);
vtx[j2].v.cn[3] = EffectSs_LerpU8(sp1A0.a, sp198.a, temp_f28);
}
gSPVertex(POLY_XLU_DISP++, vtx, 16, 0);
@ -957,9 +957,9 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
switch (this->calcMode) {
case 1:
vtx[j].v.ob[0] = func_80027E34(elem->p1.x, elem->p2.x, ratio);
vtx[j].v.ob[1] = func_80027E34(elem->p1.y, elem->p2.y, ratio);
vtx[j].v.ob[2] = func_80027E34(elem->p1.z, elem->p2.z, ratio);
vtx[j].v.ob[0] = EffectSs_LerpS16(elem->p1.x, elem->p2.x, ratio);
vtx[j].v.ob[1] = EffectSs_LerpS16(elem->p1.y, elem->p2.y, ratio);
vtx[j].v.ob[2] = EffectSs_LerpS16(elem->p1.z, elem->p2.z, ratio);
vtx[j + 1].v.ob[0] = elem->p2.x;
vtx[j + 1].v.ob[1] = elem->p2.y;
vtx[j + 1].v.ob[2] = elem->p2.z;
@ -968,18 +968,18 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
vtx[j].v.ob[0] = elem->p1.x;
vtx[j].v.ob[1] = elem->p1.y;
vtx[j].v.ob[2] = elem->p1.z;
vtx[j + 1].v.ob[0] = func_80027E34(elem->p2.x, elem->p1.x, ratio);
vtx[j + 1].v.ob[1] = func_80027E34(elem->p2.y, elem->p1.y, ratio);
vtx[j + 1].v.ob[2] = func_80027E34(elem->p2.z, elem->p1.z, ratio);
vtx[j + 1].v.ob[0] = EffectSs_LerpS16(elem->p2.x, elem->p1.x, ratio);
vtx[j + 1].v.ob[1] = EffectSs_LerpS16(elem->p2.y, elem->p1.y, ratio);
vtx[j + 1].v.ob[2] = EffectSs_LerpS16(elem->p2.z, elem->p1.z, ratio);
break;
case 3:
ratio = ratio * 0.5f;
vtx[j].v.ob[0] = func_80027E34(elem->p1.x, elem->p2.x, ratio);
vtx[j].v.ob[1] = func_80027E34(elem->p1.y, elem->p2.y, ratio);
vtx[j].v.ob[2] = func_80027E34(elem->p1.z, elem->p2.z, ratio);
vtx[j + 1].v.ob[0] = func_80027E34(elem->p2.x, elem->p1.x, ratio);
vtx[j + 1].v.ob[1] = func_80027E34(elem->p2.y, elem->p1.y, ratio);
vtx[j + 1].v.ob[2] = func_80027E34(elem->p2.z, elem->p1.z, ratio);
vtx[j].v.ob[0] = EffectSs_LerpS16(elem->p1.x, elem->p2.x, ratio);
vtx[j].v.ob[1] = EffectSs_LerpS16(elem->p1.y, elem->p2.y, ratio);
vtx[j].v.ob[2] = EffectSs_LerpS16(elem->p1.z, elem->p2.z, ratio);
vtx[j + 1].v.ob[0] = EffectSs_LerpS16(elem->p2.x, elem->p1.x, ratio);
vtx[j + 1].v.ob[1] = EffectSs_LerpS16(elem->p2.y, elem->p1.y, ratio);
vtx[j + 1].v.ob[2] = EffectSs_LerpS16(elem->p2.z, elem->p1.z, ratio);
ratio = ratio + ratio;
break;
case 0:
@ -996,19 +996,19 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
vtx[j].v.flag = 0;
vtx[j].v.tc[0] = 0;
vtx[j].v.tc[1] = 0;
vtx[j].v.cn[0] = func_80027E84(this->p1StartColor[0], this->p1EndColor[0], ratio);
vtx[j].v.cn[1] = func_80027E84(this->p1StartColor[1], this->p1EndColor[1], ratio);
vtx[j].v.cn[2] = func_80027E84(this->p1StartColor[2], this->p1EndColor[2], ratio);
vtx[j].v.cn[3] = func_80027E84(this->p1StartColor[3], this->p1EndColor[3], ratio);
vtx[j].v.cn[0] = EffectSs_LerpU8(this->p1StartColor[0], this->p1EndColor[0], ratio);
vtx[j].v.cn[1] = EffectSs_LerpU8(this->p1StartColor[1], this->p1EndColor[1], ratio);
vtx[j].v.cn[2] = EffectSs_LerpU8(this->p1StartColor[2], this->p1EndColor[2], ratio);
vtx[j].v.cn[3] = EffectSs_LerpU8(this->p1StartColor[3], this->p1EndColor[3], ratio);
j++;
vtx[j].v.flag = 0;
vtx[j].v.tc[0] = 0;
vtx[j].v.tc[1] = 0;
vtx[j].v.cn[0] = func_80027E84(this->p2StartColor[0], this->p2EndColor[0], ratio);
vtx[j].v.cn[1] = func_80027E84(this->p2StartColor[1], this->p2EndColor[1], ratio);
vtx[j].v.cn[2] = func_80027E84(this->p2StartColor[2], this->p2EndColor[2], ratio);
vtx[j].v.cn[3] = func_80027E84(this->p2StartColor[3], this->p2EndColor[3], ratio);
vtx[j].v.cn[0] = EffectSs_LerpU8(this->p2StartColor[0], this->p2EndColor[0], ratio);
vtx[j].v.cn[1] = EffectSs_LerpU8(this->p2StartColor[1], this->p2EndColor[1], ratio);
vtx[j].v.cn[2] = EffectSs_LerpU8(this->p2StartColor[2], this->p2EndColor[2], ratio);
vtx[j].v.cn[3] = EffectSs_LerpU8(this->p2StartColor[3], this->p2EndColor[3], ratio);
j++;
}
}

View file

@ -324,16 +324,25 @@ void EffectSs_DrawAll(PlayState* play) {
}
}
s16 func_80027DD4(s16 arg0, s16 arg1, s32 arg2) {
s16 ret = (arg2 == 0) ? arg1 : (arg0 + (s32)((arg1 - arg0) / (f32)arg2));
/**
* Lerp from `a` (weightInv == inf) to `b` (weightInv == 1 or 0).
*/
s16 EffectSs_LerpInv(s16 a, s16 b, s32 weightInv) {
s16 ret = (weightInv == 0) ? b : (a + (s32)((b - a) / (f32)weightInv));
return ret;
}
s16 func_80027E34(s16 arg0, s16 arg1, f32 arg2) {
return (arg1 - arg0) * arg2 + arg0;
/**
* Lerp from `a` (weight == 0) to `b` (weight == 1).
*/
s16 EffectSs_LerpS16(s16 a, s16 b, f32 weight) {
return (b - a) * weight + a;
}
u8 func_80027E84(u8 arg0, u8 arg1, f32 arg2) {
return arg2 * ((f32)arg1 - (f32)arg0) + arg0;
/**
* Lerp from `a` (weight == 0) to `b` (weight == 1).
*/
u8 EffectSs_LerpU8(u8 a, u8 b, f32 weight) {
return weight * ((f32)b - (f32)a) + a;
}

View file

@ -46,7 +46,7 @@ void EffectSs_DrawGEffect(PlayState* play, EffectSs* this, void* texture) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
s32 pad1;
Mtx* mtx;
void* object = play->objectCtx.status[this->rgObjBankIdx].segment;
@ -56,8 +56,8 @@ void EffectSs_DrawGEffect(PlayState* play, EffectSs* this, void* texture) {
scale = this->rgScale * 0.0025f;
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetScale(&mfScale, scale, scale, scale);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
gSegments[6] = VIRTUAL_TO_PHYSICAL(object);
gSPSegment(POLY_XLU_DISP++, 0x06, object);
@ -316,15 +316,26 @@ void EffectSsBomb2_SpawnLayered(PlayState* play, Vec3f* pos, Vec3f* velocity, Ve
// EffectSsBlast Spawn Functions
void EffectSsBlast_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 scaleStepDecay, s16 life) {
/**
* Spawn a ring-shaped shockwave effect.
*
* @param pos Position from which to find collision to draw the shockwave along.
* @param innerColor Color on the inside of the ring. Alpha is effect's alpha.
* @param outerColor Color on the outside of the ring.
* @param scale How large the shockwave is initially. The shockwave will be `scale*64/400` units wide.
* @param scaleStep How much to increase `scale` by each frame.
* @param scaleStepDecay How much to decrease `scaleStep` by each frame
* (should be a divisor of `scaleStep`, or small enough that `scaleStep` won't go negative).
*/
void EffectSsBlast_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* innerColor,
Color_RGBA8* outerColor, s16 scale, s16 scaleStep, s16 scaleStepDecay, s16 life) {
EffectSsBlastParams initParams;
Math_Vec3f_Copy(&initParams.pos, pos);
Math_Vec3f_Copy(&initParams.velocity, velocity);
Math_Vec3f_Copy(&initParams.accel, accel);
Color_RGBA8_Copy(&initParams.primColor, primColor);
Color_RGBA8_Copy(&initParams.envColor, envColor);
Color_RGBA8_Copy(&initParams.innerColor, innerColor);
Color_RGBA8_Copy(&initParams.outerColor, outerColor);
initParams.scale = scale;
initParams.scaleStep = scaleStep;
initParams.scaleStepDecay = scaleStepDecay;
@ -333,24 +344,39 @@ void EffectSsBlast_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* ac
EffectSs_Spawn(play, EFFECT_SS_BLAST, 128, &initParams);
}
void EffectSsBlast_SpawnWhiteCustomScale(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
s16 scaleStep, s16 life) {
static Color_RGBA8 primColor = { 255, 255, 255, 255 };
static Color_RGBA8 envColor = { 200, 200, 200, 0 };
/**
* Spawn a white shockwave effect.
*
* @see EffectSsBlast_Spawn
*/
void EffectSsBlast_SpawnWhiteShockwaveSetScale(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale,
s16 scaleStep, s16 life) {
static Color_RGBA8 innerColor = { 255, 255, 255, 255 };
static Color_RGBA8 outerColor = { 200, 200, 200, 0 };
EffectSsBlast_Spawn(play, pos, velocity, accel, &primColor, &envColor, scale, scaleStep, 35, life);
EffectSsBlast_Spawn(play, pos, velocity, accel, &innerColor, &outerColor, scale, scaleStep, 35, life);
}
void EffectSsBlast_SpawnShockwave(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor,
Color_RGBA8* envColor, s16 life) {
EffectSsBlast_Spawn(play, pos, velocity, accel, primColor, envColor, 100, 375, 35, life);
/**
* Spawn a shockwave effect, quickly expanding.
*
* @see EffectSsBlast_Spawn
*/
void EffectSsBlast_SpawnShockwaveSetColor(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel,
Color_RGBA8* innerColor, Color_RGBA8* outerColor, s16 life) {
EffectSsBlast_Spawn(play, pos, velocity, accel, innerColor, outerColor, 100, 375, 35, life);
}
/**
* Spawn a white shockwave effect, quickly expanding, for 10 frames.
*
* @see EffectSsBlast_Spawn
*/
void EffectSsBlast_SpawnWhiteShockwave(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel) {
static Color_RGBA8 primColor = { 255, 255, 255, 255 };
static Color_RGBA8 envColor = { 200, 200, 200, 0 };
static Color_RGBA8 innerColor = { 255, 255, 255, 255 };
static Color_RGBA8 outerColor = { 200, 200, 200, 0 };
EffectSsBlast_SpawnShockwave(play, pos, velocity, accel, &primColor, &envColor, 10);
EffectSsBlast_SpawnShockwaveSetColor(play, pos, velocity, accel, &innerColor, &outerColor, 10);
}
// EffectSsGSpk Spawn Functions
@ -745,12 +771,12 @@ void EffectSsFhgFlash_SpawnLightBall(PlayState* play, Vec3f* pos, Vec3f* velocit
}
/**
* Spawn a shock effect
* Spawn a purple shock effect (a ball of electrical arcs).
*
* param determines where the ligntning should go
* 0: don't attach to any actor. spawns at the position specified by pos
* 1: spawn at one of Player's body parts, chosen at random
* 2: spawn at one of Phantom Ganon's body parts, chosen at random
* @param actor If param is `FHGFLASH_SHOCK_PG`, the Phantom Ganon actor. Unused otherwise.
* @param pos If param is `FHGFLASH_SHOCK_NO_ACTOR`, the position of the effect. Unused otherwise.
* @param scale The effect will be around `scale*20/100` units wide (randomized).
* @param param Determines what the effect attaches to. See `FhgFlashLightningParam`.
*/
void EffectSsFhgFlash_SpawnShock(PlayState* play, Actor* actor, Vec3f* pos, s16 scale, u8 param) {
EffectSsFhgFlashInitParams initParams;

View file

@ -2486,7 +2486,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
} else {
Message_CloseTextbox(play);
if (msgCtx->lastPlayedSong == OCARINA_SONG_EPONAS) {
DREG(53) = 1;
R_EPONAS_SONG_PLAYED = true;
}
osSyncPrintf(VT_FGCOL(YELLOW));
osSyncPrintf("☆☆☆ocarina=%d message->ocarina_no=%d ", msgCtx->lastPlayedSong,

View file

@ -1064,12 +1064,12 @@ s32 Player_OverrideLimbDrawGameplayCommon(PlayState* play, s32 limbIndex, Gfx**
sCurBodyPartPos = &this->bodyPartsPos[-1];
if (!LINK_IS_ADULT) {
if (!(this->skelAnime.moveFlags & 4) || (this->skelAnime.moveFlags & 1)) {
if (!(this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_2) || (this->skelAnime.moveFlags & ANIM_FLAG_0)) {
pos->x *= 0.64f;
pos->z *= 0.64f;
}
if (!(this->skelAnime.moveFlags & 4) || (this->skelAnime.moveFlags & 2)) {
if (!(this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_2) || (this->skelAnime.moveFlags & ANIM_FLAG_UPDATE_Y)) {
pos->y *= 0.64f;
}
}

View file

@ -914,13 +914,13 @@ void AnimationContext_SetCopyFalse(PlayState* play, s32 vecCount, Vec3s* dst, Ve
/**
* Requests moving an actor according to the translation of its root limb
*/
void AnimationContext_SetMoveActor(PlayState* play, Actor* actor, SkelAnime* skelAnime, f32 arg3) {
void AnimationContext_SetMoveActor(PlayState* play, Actor* actor, SkelAnime* skelAnime, f32 moveDiffScaleY) {
AnimationEntry* entry = AnimationContext_AddEntry(&play->animationCtx, ANIMENTRY_MOVEACTOR);
if (entry != NULL) {
entry->data.move.actor = actor;
entry->data.move.skelAnime = skelAnime;
entry->data.move.unk_08 = arg3;
entry->data.move.diffScaleY = moveDiffScaleY;
}
}
@ -1011,7 +1011,7 @@ void AnimationContext_MoveActor(PlayState* play, AnimationEntryData* data) {
SkelAnime_UpdateTranslation(entry->skelAnime, &diff, actor->shape.rot.y);
actor->world.pos.x += diff.x * actor->scale.x;
actor->world.pos.y += diff.y * actor->scale.y * entry->unk_08;
actor->world.pos.y += diff.y * actor->scale.y * entry->diffScaleY;
actor->world.pos.z += diff.z * actor->scale.z;
}

View file

@ -7,7 +7,9 @@
#include "global.h"
// Self-hosted memcmp.
// Self-hosted libc memory functions, gcc assumes these exist even in a freestanding
// environment and there is no way to tell it otherwise.
int memcmp(void* s1, const void* s2, size_t n) {
u8* m1 = (u8*)s1;
u8* m2 = (u8*)s2;
@ -35,177 +37,212 @@ void* memset(void* str, s32 c, size_t n) {
return str;
}
// These functions convert c to an unsigned integer, rounding toward zero. Negative values
// all become zero.
u32 __fixunssfdi(f32 a) {
if (a < 0.0f) {
a = 0.0f;
// Conversions involving 64-bit integer types required by the O32 MIPS ABI.
// f32 -> u64, negative values become 0
u64 __fixunssfdi(f32 a) {
if (a > 0.0f) {
register union {
f64 f;
u64 i;
} m;
__asm__ ("cvt.l.s %0, %1" : "=f"(m.f) : "f"(a));
return m.i;
}
return (u32)a;
return 0;
}
u32 __fixunsdfdi(f64 a) {
if (a < 0.0) {
a = 0.0;
// f64 -> u64, negative values become 0
u64 __fixunsdfdi(f64 a) {
if (a > 0.0) {
register union {
f64 f;
u64 i;
} m;
__asm__ ("cvt.l.d %0, %1" : "=f"(m.f) : "f"(a));
return m.i;
}
return (u32)a;
return 0;
}
// These functions convert c to a signed integer, rounding toward zero.
s32 __fixsfdi(f32 c) {
return (s32)c;
// f32 -> s64
s64 __fixsfdi(f32 c) {
register union {
f64 f;
s64 i;
} m;
__asm__ ("cvt.l.s %0, %1" : "=f"(m.f) : "f"(c));
return m.i;
}
s32 __fixdfdi(f64 c) {
return (s32)c;
// f64 -> s64
s64 __fixdfdi(f64 c) {
register union {
f64 f;
s64 i;
} m;
__asm__ ("cvt.l.d %0, %1" : "=f"(m.f) : "f"(c));
return m.i;
}
// These functions convert c, a signed integer, to floating point.
f32 __floatdisf(s32 c) {
return (f32)c;
// s64 -> f32
f32 __floatdisf(s64 c) {
register union {
f64 f;
s64 i;
} m;
register f32 v;
m.i = c;
__asm__ ("cvt.s.l %0, %1" : "=f"(v) : "f"(m.f));
return v;
}
f64 __floatdidf(s32 c) {
return (f64)c;
// s64 -> f64
f64 __floatdidf(s64 c) {
register union {
f64 f;
s64 i;
} m;
register f64 v;
m.i = c;
__asm__ ("cvt.d.l %0, %1" : "=f"(v) : "f"(m.f));
return v;
}
// These functions convert c, an unsigned integer, to floating point.
f32 __floatundisf(u32 c) {
return (f32)c;
// u64 -> f32
f32 __floatundisf(u64 c) {
register union {
f64 f;
u64 i;
} m;
register f32 v;
m.i = c;
__asm__ ("cvt.s.l %0, %1" : "=f"(v) : "f"(m.f));
if ((s64)c < 0) {
// cvt.s.l assumes signed input, adjust output
v += 4294967296.0f; // 2^32
}
return v;
}
f64 __floatundidf(u32 c) {
return (f64)c;
// u64 -> f64
f64 __floatundidf(u64 c) {
register union {
f64 f;
u64 i;
} m;
register f64 v;
m.i = c;
__asm__ ("cvt.d.l %0, %1" : "=f"(v) : "f"(m.f));
if ((s64)c < 0) {
// cvt.d.l assumes signed input, adjust output
v += 18446744073709551616.0; // 2^64
}
return v;
}
f32 __powisf2(f32 a, s32 b) {
const s32 recip = b < 0;
f32 r = 1;
// Compute x^m by binary exponentiation
while (1) {
if (b & 1) {
r *= a;
f32 __powisf2(f32 x, s32 m) {
u32 n = (m < 0) ? -m : m;
f32 y = (n % 2 != 0) ? x : 1.0f;
while (n >>= 1) {
x = x * x;
if (n % 2 != 0) {
y = y * x;
}
b /= 2;
if (b == 0) {
break;
}
a *= a;
}
return recip ? 1 / r : r;
return (m < 0) ? (1.0f / y) : y;
}
// Compute division and modulo of 64-bit signed and unsigned integers
__asm__(" \n\
.set push \n\
.set noat \n\
.set noreorder \n\
.set gp=64 \n\
\n\
.global __umoddi3 \n\
__umoddi3: \n\
.type __umoddi3, @function \n\
.ent __umoddi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddivu $zero, $t6, $t7 \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
mfhi $v0 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
.type __umoddi3, @function \n\
.ent __umoddi3 \n\
sw $a0, 0x0($sp) \n\
sw $a1, 0x4($sp) \n\
sw $a2, 0x8($sp) \n\
sw $a3, 0xC($sp) \n\
ld $t6, 0($sp) \n\
ld $t7, 8($sp) \n\
dremu $v0, $t6, $t7 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __umoddi3 \n\
.size __umoddi3, . - __umoddi3 \n\
.end __umoddi3 \n\
.size __umoddi3, . - __umoddi3 \n\
\n\
.global __udivdi3 \n\
__udivdi3: \n\
.type __udivdi3, @function \n\
.ent __udivdi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddivu $zero, $t6, $t7 \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
mflo $v0 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
.type __udivdi3, @function \n\
.ent __udivdi3 \n\
sw $a0, 0x0($sp) \n\
sw $a1, 0x4($sp) \n\
sw $a2, 0x8($sp) \n\
sw $a3, 0xC($sp) \n\
ld $t6, 0($sp) \n\
ld $t7, 8($sp) \n\
ddivu $v0, $t6, $t7 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __udivdi3 \n\
.size __udivdi3, . - __udivdi3 \n\
.end __udivdi3 \n\
.size __udivdi3, . - __udivdi3 \n\
\n\
.global __moddi3 \n\
__moddi3: \n\
.type __moddi3, @function \n\
.ent __moddi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddivu $zero, $t6, $t7 \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
mfhi $v0 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
.type __moddi3, @function \n\
.ent __moddi3 \n\
sw $a0, 0x0($sp) \n\
sw $a1, 0x4($sp) \n\
sw $a2, 0x8($sp) \n\
sw $a3, 0xC($sp) \n\
ld $t6, 0($sp) \n\
ld $t7, 8($sp) \n\
drem $v0, $t6, $t7 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __moddi3 \n\
.size __moddi3, . - __moddi3 \n\
.end __moddi3 \n\
.size __moddi3, . - __moddi3 \n\
\n\
.global __divdi3 \n\
__divdi3: \n\
.type __divdi3, @function \n\
.ent __divdi3 \n\
sw $a0, ($sp) \n\
sw $a1, 4($sp) \n\
sw $a2, 8($sp) \n\
sw $a3, 0xc($sp) \n\
.type __divdi3, @function \n\
.ent __divdi3 \n\
sw $a0, 0x0($sp) \n\
sw $a1, 0x4($sp) \n\
sw $a2, 0x8($sp) \n\
sw $a3, 0xC($sp) \n\
ld $t6, 0($sp) \n\
ld $t7, 8($sp) \n\
ld $t6, ($sp) \n\
ddiv $zero, $t6, $t7 \n\
nop \n\
bnez $t7, 1f \n\
nop \n\
break 7 \n\
1: \n\
daddiu $at, $zero, -1 \n\
bne $t7, $at, 2f \n\
daddiu $at, $zero, 1 \n\
dsll32 $at, $at, 0x1f \n\
bne $t6, $at, 2f \n\
nop \n\
break 6 \n\
2: \n\
mflo $v0 \n\
ddiv $v0, $t6, $t7 \n\
dsll32 $v1, $v0, 0 \n\
dsra32 $v1, $v1, 0 \n\
jr $ra \n\
dsra32 $v0, $v0, 0 \n\
.end __divdi3 \n\
.size __divdi3, . - __divdi3 \n\
.end __divdi3 \n\
.size __divdi3, . - __divdi3 \n\
\n\
.set pop \n\
\n");

View file

@ -4161,7 +4161,7 @@ void BossGanon_LightBall_Draw(Actor* thisx, PlayState* play) {
}
} else if (this->unk_1A8 == 0) {
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_RotateZ((this->actor.shape.rot.z / 32768.0f) * 3.1416f, MTXMODE_APPLY);
Matrix_RotateZ((this->actor.shape.rot.z / (f32)0x8000) * 3.1416f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_boss_ganon.c", 9907),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gGanondorfSquareDL);

View file

@ -176,19 +176,19 @@ void DemoEc_UpdateBgFlags(DemoEc* this, PlayState* play) {
}
void func_8096D594(DemoEc* this, PlayState* play) {
this->skelAnime.moveFlags |= 3;
this->skelAnime.moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}
void func_8096D5D4(DemoEc* this, PlayState* play) {
this->skelAnime.baseTransl = this->skelAnime.jointTable[0];
this->skelAnime.prevTransl = this->skelAnime.jointTable[0];
this->skelAnime.moveFlags |= 3;
this->skelAnime.moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}
void func_8096D64C(DemoEc* this, PlayState* play) {
this->skelAnime.moveFlags |= 3;
this->skelAnime.moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}
@ -1083,7 +1083,7 @@ void DemoEc_UpdateFishingOwner(DemoEc* this, PlayState* play) {
void DemoEc_FishingOwnerPostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx, Gfx** gfx) {
DemoEc* this = (DemoEc*)thisx;
if ((limbIndex == 8) && !(HIGH_SCORE(HS_FISHING) & 0x1000)) {
if ((limbIndex == 8) && !(HIGH_SCORE(HS_FISHING) & HS_FISH_STOLE_HAT)) {
gSPDisplayList((*gfx)++, SEGMENTED_TO_VIRTUAL(gFishingOwnerHatDL));
}
}

View file

@ -51,12 +51,12 @@ s32 DemoIk_CheckForCue(PlayState* play, u16 cueId, s32 cueChannel) {
}
void DemoIk_SetMove(DemoIk* this, PlayState* play) {
this->skelAnime.moveFlags |= 1;
this->skelAnime.moveFlags |= ANIM_FLAG_0;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}
void DemoIk_EndMove(DemoIk* this) {
this->skelAnime.moveFlags &= ~1;
this->skelAnime.moveFlags &= ~ANIM_FLAG_0;
}
f32 DemoIk_GetCurFrame(DemoIk* this) {

View file

@ -69,10 +69,10 @@ void EnBomBowlMan_Init(Actor* thisx, PlayState* play2) {
for (i = 0; i < 2; i++) {
cucco = (EnSyatekiNiw*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SYATEKI_NIW, cuccoSpawnPos[i].x,
cuccoSpawnPos[i].y, cuccoSpawnPos[i].z, 0, 0, 0, 1);
cuccoSpawnPos[i].y, cuccoSpawnPos[i].z, 0, 0, 0,
SYATEKI_MINIGAME_ALLEY);
if (cucco != NULL) {
cucco->unk_2F4 = cuccoScales[i];
cucco->scale = cuccoScales[i];
cucco->collider.dim.radius = (s16)cuccoColliderDims[i][0];
cucco->collider.dim.height = (s16)cuccoColliderDims[i][1];
}

View file

@ -5,7 +5,6 @@
*/
#include "z_en_cow.h"
#include "assets/objects/object_cow/object_cow.h"
#define FLAGS (ACTOR_FLAG_0 | ACTOR_FLAG_3)
@ -13,17 +12,19 @@ void EnCow_Init(Actor* thisx, PlayState* play);
void EnCow_Destroy(Actor* thisx, PlayState* play);
void EnCow_Update(Actor* thisx, PlayState* play2);
void EnCow_Draw(Actor* thisx, PlayState* play);
void func_809DFE98(Actor* thisx, PlayState* play);
void func_809E0070(Actor* thisx, PlayState* play);
void func_809DF494(EnCow* this, PlayState* play);
void func_809DF6BC(EnCow* this, PlayState* play);
void func_809DF778(EnCow* this, PlayState* play);
void func_809DF7D8(EnCow* this, PlayState* play);
void func_809DF870(EnCow* this, PlayState* play);
void func_809DF8FC(EnCow* this, PlayState* play);
void func_809DF96C(EnCow* this, PlayState* play);
void func_809DFA84(EnCow* this, PlayState* play);
void EnCow_TalkEnd(EnCow* this, PlayState* play);
void EnCow_GiveMilkEnd(EnCow* this, PlayState* play);
void EnCow_GiveMilkWait(EnCow* this, PlayState* play);
void EnCow_GiveMilk(EnCow* this, PlayState* play);
void EnCow_CheckForEmptyBottle(EnCow* this, PlayState* play);
void EnCow_UpdateAnimation(EnCow* this, PlayState* play);
void EnCow_Talk(EnCow* this, PlayState* play);
void EnCow_Idle(EnCow* this, PlayState* play);
void EnCow_DrawTail(Actor* thisx, PlayState* play);
void EnCow_UpdateTail(Actor* thisx, PlayState* play);
void EnCow_IdleTail(EnCow* this, PlayState* play);
ActorInit En_Cow_InitVars = {
ACTOR_EN_COW,
@ -57,45 +58,50 @@ static ColliderCylinderInit sCylinderInit = {
{ 30, 40, 0, { 0, 0, 0 } },
};
static Vec3f D_809E010C = { 0.0f, -1300.0f, 1100.0f };
static Vec3f sHeadFocusOffset = { 0.0f, -1300.0f, 1100.0f };
void func_809DEE00(Vec3f* vec, s16 rotY) {
void EnCow_RotateY(Vec3f* vec, s16 rotY) {
f32 xCalc;
f32 rotCalcTemp;
rotCalcTemp = Math_CosS(rotY);
xCalc = (Math_SinS(rotY) * vec->z) + (rotCalcTemp * vec->x);
rotCalcTemp = Math_SinS(rotY);
vec->z = (Math_CosS(rotY) * vec->z) + (-rotCalcTemp * vec->x);
vec->x = xCalc;
}
void func_809DEE9C(EnCow* this) {
void EnCow_SetColliderPos(EnCow* this) {
Vec3f vec;
vec.y = 0.0f;
vec.x = 0.0f;
vec.z = 30.0f;
func_809DEE00(&vec, this->actor.shape.rot.y);
this->colliders[0].dim.pos.x = this->actor.world.pos.x + vec.x;
this->colliders[0].dim.pos.y = this->actor.world.pos.y;
this->colliders[0].dim.pos.z = this->actor.world.pos.z + vec.z;
EnCow_RotateY(&vec, this->actor.shape.rot.y);
this->colliders[COW_COLLIDER_FRONT].dim.pos.x = this->actor.world.pos.x + vec.x;
this->colliders[COW_COLLIDER_FRONT].dim.pos.y = this->actor.world.pos.y;
this->colliders[COW_COLLIDER_FRONT].dim.pos.z = this->actor.world.pos.z + vec.z;
vec.x = 0.0f;
vec.y = 0.0f;
vec.z = -20.0f;
func_809DEE00(&vec, this->actor.shape.rot.y);
this->colliders[1].dim.pos.x = this->actor.world.pos.x + vec.x;
this->colliders[1].dim.pos.y = this->actor.world.pos.y;
this->colliders[1].dim.pos.z = this->actor.world.pos.z + vec.z;
EnCow_RotateY(&vec, this->actor.shape.rot.y);
this->colliders[COW_COLLIDER_REAR].dim.pos.x = this->actor.world.pos.x + vec.x;
this->colliders[COW_COLLIDER_REAR].dim.pos.y = this->actor.world.pos.y;
this->colliders[COW_COLLIDER_REAR].dim.pos.z = this->actor.world.pos.z + vec.z;
}
void func_809DEF94(EnCow* this) {
void EnCow_SetTailPos(EnCow* this) {
Vec3f vec;
VEC_SET(vec, 0.0f, 57.0f, -36.0f);
EnCow_RotateY(&vec, this->actor.shape.rot.y);
func_809DEE00(&vec, this->actor.shape.rot.y);
this->actor.world.pos.x += vec.x;
this->actor.world.pos.y += vec.y;
this->actor.world.pos.z += vec.z;
@ -106,188 +112,216 @@ void EnCow_Init(Actor* thisx, PlayState* play) {
s32 pad;
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f);
switch (this->actor.params) {
case 0:
SkelAnime_InitFlex(play, &this->skelAnime, &gCowBodySkel, NULL, this->jointTable, this->morphTable, 6);
switch (COW_GET_TYPE(this)) {
case COW_TYPE_BODY:
SkelAnime_InitFlex(play, &this->skelAnime, &gCowBodySkel, NULL, this->jointTable, this->morphTable,
COW_LIMB_MAX);
Animation_PlayLoop(&this->skelAnime, &gCowBodyChewAnim);
Collider_InitCylinder(play, &this->colliders[0]);
Collider_SetCylinder(play, &this->colliders[0], &this->actor, &sCylinderInit);
Collider_InitCylinder(play, &this->colliders[1]);
Collider_SetCylinder(play, &this->colliders[1], &this->actor, &sCylinderInit);
func_809DEE9C(this);
this->actionFunc = func_809DF96C;
Collider_InitCylinder(play, &this->colliders[COW_COLLIDER_FRONT]);
Collider_SetCylinder(play, &this->colliders[COW_COLLIDER_FRONT], &this->actor, &sCylinderInit);
Collider_InitCylinder(play, &this->colliders[COW_COLLIDER_REAR]);
Collider_SetCylinder(play, &this->colliders[COW_COLLIDER_REAR], &this->actor, &sCylinderInit);
EnCow_SetColliderPos(this);
this->actionFunc = EnCow_Idle;
if (play->sceneId == SCENE_LINKS_HOUSE) {
if (!LINK_IS_ADULT) {
Actor_Kill(&this->actor);
return;
}
if (!GET_EVENTCHKINF(EVENTCHKINF_1E)) {
if (!GET_EVENTCHKINF(EVENTCHKINF_HORSE_RACE_COW_UNLOCK)) {
Actor_Kill(&this->actor);
return;
}
}
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_COW, this->actor.world.pos.x,
this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 1);
this->unk_278 = Rand_ZeroFloat(1000.0f) + 40.0f;
this->unk_27A = 0;
this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0,
COW_TYPE_TAIL);
this->animationTimer = Rand_ZeroFloat(1000.0f) + 40.0f;
this->breathTimer = 0;
this->actor.targetMode = 6;
DREG(53) = 0;
R_EPONAS_SONG_PLAYED = false;
break;
case 1:
SkelAnime_InitFlex(play, &this->skelAnime, &gCowTailSkel, NULL, this->jointTable, this->morphTable, 6);
case COW_TYPE_TAIL:
SkelAnime_InitFlex(play, &this->skelAnime, &gCowTailSkel, NULL, this->jointTable, this->morphTable,
COW_TAIL_LIMB_MAX);
Animation_PlayLoop(&this->skelAnime, &gCowTailIdleAnim);
this->actor.update = func_809DFE98;
this->actor.draw = func_809E0070;
this->actionFunc = func_809DFA84;
func_809DEF94(this);
this->actor.update = EnCow_UpdateTail;
this->actor.draw = EnCow_DrawTail;
this->actionFunc = EnCow_IdleTail;
EnCow_SetTailPos(this);
this->actor.flags &= ~ACTOR_FLAG_0;
this->unk_278 = ((u32)(Rand_ZeroFloat(1000.0f)) & 0xFFFF) + 40.0f;
this->animationTimer = (u16)Rand_ZeroFloat(1000.0f) + 40.0f;
break;
}
this->actor.colChkInfo.mass = MASS_IMMOVABLE;
Actor_SetScale(&this->actor, 0.01f);
this->unk_276 = 0;
this->cowFlags = 0;
}
void EnCow_Destroy(Actor* thisx, PlayState* play) {
EnCow* this = (EnCow*)thisx;
if (this->actor.params == 0) {
Collider_DestroyCylinder(play, &this->colliders[0]);
Collider_DestroyCylinder(play, &this->colliders[1]);
if (COW_GET_TYPE(this) == COW_TYPE_BODY) {
Collider_DestroyCylinder(play, &this->colliders[COW_COLLIDER_FRONT]);
Collider_DestroyCylinder(play, &this->colliders[COW_COLLIDER_REAR]);
}
}
void func_809DF494(EnCow* this, PlayState* play) {
if (this->unk_278 > 0) {
this->unk_278--;
void EnCow_UpdateAnimation(EnCow* this, PlayState* play) {
if (this->animationTimer > 0) {
this->animationTimer--;
} else {
this->unk_278 = Rand_ZeroFloat(500.0f) + 40.0f;
this->animationTimer = Rand_ZeroFloat(500.0f) + 40.0f;
Animation_Change(&this->skelAnime, &gCowBodyChewAnim, 1.0f, this->skelAnime.curFrame,
Animation_GetLastFrame(&gCowBodyChewAnim), ANIMMODE_ONCE, 1.0f);
}
if ((this->actor.xzDistToPlayer < 150.0f) && !(this->unk_276 & 2)) {
this->unk_276 |= 2;
if (this->skelAnime.animation == &gCowBodyChewAnim) {
this->unk_278 = 0;
if (this->actor.xzDistToPlayer < 150.0f) {
if (!(this->cowFlags & COW_FLAG_PLAYER_NEARBY)) {
this->cowFlags |= COW_FLAG_PLAYER_NEARBY;
if (this->skelAnime.animation == &gCowBodyChewAnim) {
this->animationTimer = 0;
}
}
}
this->unk_27A++;
if (this->unk_27A > 48) {
this->unk_27A = 0;
this->breathTimer++;
if (this->breathTimer > 48) {
this->breathTimer = 0;
}
// (1.0f / 100.0f) instead of 0.01f below is necessary so 0.01f doesn't get reused mistakenly
if (this->unk_27A < 0x20) {
this->actor.scale.x = ((Math_SinS(this->unk_27A << 0xA) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
if (this->breathTimer < 32) {
this->actor.scale.x = ((Math_SinS(this->breathTimer * 0x0400) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
} else {
this->actor.scale.x = 0.01f;
}
if (this->unk_27A >= 0x11) {
this->actor.scale.y = ((Math_SinS((this->unk_27A << 0xA) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
if (this->breathTimer > 16) {
this->actor.scale.y = ((Math_SinS((this->breathTimer * 0x0400) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f;
} else {
this->actor.scale.y = 0.01f;
}
}
void func_809DF6BC(EnCow* this, PlayState* play) {
void EnCow_TalkEnd(EnCow* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) {
this->actor.flags &= ~ACTOR_FLAG_16;
Message_CloseTextbox(play);
this->actionFunc = func_809DF96C;
this->actionFunc = EnCow_Idle;
}
}
void func_809DF730(EnCow* this, PlayState* play) {
void EnCow_GiveMilkEnd(EnCow* this, PlayState* play) {
if (Actor_TextboxIsClosing(&this->actor, play)) {
this->actor.flags &= ~ACTOR_FLAG_16;
this->actionFunc = func_809DF96C;
this->actionFunc = EnCow_Idle;
}
}
void func_809DF778(EnCow* this, PlayState* play) {
void EnCow_GiveMilkWait(EnCow* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
this->actor.parent = NULL;
this->actionFunc = func_809DF730;
this->actionFunc = EnCow_GiveMilkEnd;
} else {
Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f);
}
}
void func_809DF7D8(EnCow* this, PlayState* play) {
void EnCow_GiveMilk(EnCow* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) {
this->actor.flags &= ~ACTOR_FLAG_16;
Message_CloseTextbox(play);
this->actionFunc = func_809DF778;
this->actionFunc = EnCow_GiveMilkWait;
Actor_OfferGetItem(&this->actor, play, GI_MILK, 10000.0f, 100.0f);
}
}
void func_809DF870(EnCow* this, PlayState* play) {
void EnCow_CheckForEmptyBottle(EnCow* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)) {
if (Inventory_HasEmptyBottle()) {
Message_ContinueTextbox(play, 0x2007);
this->actionFunc = func_809DF7D8;
this->actionFunc = EnCow_GiveMilk;
} else {
Message_ContinueTextbox(play, 0x2013);
this->actionFunc = func_809DF6BC;
this->actionFunc = EnCow_TalkEnd;
}
}
}
void func_809DF8FC(EnCow* this, PlayState* play) {
void EnCow_Talk(EnCow* this, PlayState* play) {
if (Actor_ProcessTalkRequest(&this->actor, play)) {
this->actionFunc = func_809DF870;
this->actionFunc = EnCow_CheckForEmptyBottle;
} else {
this->actor.flags |= ACTOR_FLAG_16;
func_8002F2CC(&this->actor, play, 170.0f);
this->actor.textId = 0x2006;
}
func_809DF494(this, play);
EnCow_UpdateAnimation(this, play);
}
void func_809DF96C(EnCow* this, PlayState* play) {
void EnCow_Idle(EnCow* this, PlayState* play) {
if ((play->msgCtx.ocarinaMode == OCARINA_MODE_00) || (play->msgCtx.ocarinaMode == OCARINA_MODE_04)) {
if (DREG(53) != 0) {
if (this->unk_276 & 4) {
this->unk_276 &= ~0x4;
DREG(53) = 0;
// There is a complex interaction between `R_EPONAS_SONG_PLAYED` and `COW_FLAG_FAILED_TO_GIVE_MILK` to allow
// multiple cows to try and give milk on the same frame.
// `COW_FLAG_FAILED_TO_GIVE_MILK` gets set if this cow is not in range with the player to interact.
// In the case of a failure, `R_EPONAS_SONG_PLAYED` is not set to false in case another cow can succeed.
// On the following frame, if both `R_EPONAS_SONG_PLAYED` and `COW_FLAG_FAILED_TO_GIVE_MILK` are set, the
// first cow that updates can assume all other cows also failed and can safely unset `R_EPONAS_SONG_PLAYED`.
// All cows also unset their own `COW_FLAG_FAILED_TO_GIVE_MILK` flag.
if (R_EPONAS_SONG_PLAYED) {
if (this->cowFlags & COW_FLAG_FAILED_TO_GIVE_MILK) {
this->cowFlags &= ~COW_FLAG_FAILED_TO_GIVE_MILK;
R_EPONAS_SONG_PLAYED = false;
} else {
if ((this->actor.xzDistToPlayer < 150.0f) &&
(ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 0x61A8)) {
DREG(53) = 0;
this->actionFunc = func_809DF8FC;
(ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 25000)) {
R_EPONAS_SONG_PLAYED = false;
this->actionFunc = EnCow_Talk;
this->actor.flags |= ACTOR_FLAG_16;
func_8002F2CC(&this->actor, play, 170.0f);
this->actor.textId = 0x2006;
} else {
this->unk_276 |= 4;
this->cowFlags |= COW_FLAG_FAILED_TO_GIVE_MILK;
}
}
} else {
this->unk_276 &= ~0x4;
this->cowFlags &= ~COW_FLAG_FAILED_TO_GIVE_MILK;
}
}
func_809DF494(this, play);
EnCow_UpdateAnimation(this, play);
}
void func_809DFA84(EnCow* this, PlayState* play) {
if (this->unk_278 > 0) {
this->unk_278--;
void EnCow_IdleTail(EnCow* this, PlayState* play) {
if (this->animationTimer > 0) {
this->animationTimer--;
} else {
this->unk_278 = Rand_ZeroFloat(200.0f) + 40.0f;
this->animationTimer = Rand_ZeroFloat(200.0f) + 40.0f;
Animation_Change(&this->skelAnime, &gCowTailIdleAnim, 1.0f, this->skelAnime.curFrame,
Animation_GetLastFrame(&gCowTailIdleAnim), ANIMMODE_ONCE, 1.0f);
}
if ((this->actor.xzDistToPlayer < 150.0f) &&
(ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) >= 0x61A9) && !(this->unk_276 & 2)) {
this->unk_276 |= 2;
if (this->skelAnime.animation == &gCowTailIdleAnim) {
this->unk_278 = 0;
(ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) > 25000)) {
if (!(this->cowFlags & COW_FLAG_PLAYER_NEARBY)) {
this->cowFlags |= COW_FLAG_PLAYER_NEARBY;
if (this->skelAnime.animation == &gCowTailIdleAnim) {
this->animationTimer = 0;
}
}
}
}
@ -299,10 +333,12 @@ void EnCow_Update(Actor* thisx, PlayState* play2) {
s16 targetY;
Player* player = GET_PLAYER(play);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliders[0].base);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliders[1].base);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliders[COW_COLLIDER_FRONT].base);
CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliders[COW_COLLIDER_REAR].base);
Actor_MoveXZGravity(thisx);
Actor_UpdateBgCheckInfo(play, thisx, 0.0f, 0.0f, 0.0f, UPDBGCHECKINFO_FLAG_2);
if (SkelAnime_Update(&this->skelAnime)) {
if (this->skelAnime.animation == &gCowBodyChewAnim) {
Actor_PlaySfx(thisx, NA_SE_EV_COW_CRY);
@ -313,7 +349,9 @@ void EnCow_Update(Actor* thisx, PlayState* play2) {
ANIMMODE_LOOP, 1.0f);
}
}
this->actionFunc(this, play);
if ((thisx->xzDistToPlayer < 150.0f) &&
(ABS(Math_Vec3f_Yaw(&thisx->world.pos, &player->actor.world.pos)) < 0xC000)) {
targetX = Math_Vec3f_Pitch(&thisx->focus.pos, &player->actor.focus.pos);
@ -330,16 +368,16 @@ void EnCow_Update(Actor* thisx, PlayState* play2) {
} else if (targetY < -0x2500) {
targetY = -0x2500;
}
} else {
targetY = 0;
targetX = 0;
}
Math_SmoothStepToS(&this->someRot.x, targetX, 0xA, 0xC8, 0xA);
Math_SmoothStepToS(&this->someRot.y, targetY, 0xA, 0xC8, 0xA);
Math_SmoothStepToS(&this->headRot.x, targetX, 10, 200, 10);
Math_SmoothStepToS(&this->headRot.y, targetY, 10, 200, 10);
}
void func_809DFE98(Actor* thisx, PlayState* play) {
void EnCow_UpdateTail(Actor* thisx, PlayState* play) {
EnCow* this = (EnCow*)thisx;
s32 pad;
@ -352,27 +390,30 @@ void func_809DFE98(Actor* thisx, PlayState* play) {
ANIMMODE_LOOP, 1.0f);
}
}
this->actionFunc(this, play);
}
s32 EnCow_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
EnCow* this = (EnCow*)thisx;
if (limbIndex == 2) {
rot->y += this->someRot.y;
rot->x += this->someRot.x;
if (limbIndex == COW_LIMB_HEAD) {
rot->y += this->headRot.y;
rot->x += this->headRot.x;
}
if (limbIndex == 5) {
if (limbIndex == COW_LIMB_NOSE_RING) {
*dList = NULL;
}
return false;
}
void EnCow_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
EnCow* this = (EnCow*)thisx;
if (limbIndex == 2) {
Matrix_MultVec3f(&D_809E010C, &this->actor.focus.pos);
if (limbIndex == COW_LIMB_HEAD) {
Matrix_MultVec3f(&sHeadFocusOffset, &this->actor.focus.pos);
}
}
@ -384,7 +425,7 @@ void EnCow_Draw(Actor* thisx, PlayState* play) {
EnCow_OverrideLimbDraw, EnCow_PostLimbDraw, this);
}
void func_809E0070(Actor* thisx, PlayState* play) {
void EnCow_DrawTail(Actor* thisx, PlayState* play) {
EnCow* this = (EnCow*)thisx;
Gfx_SetupDL_37Opa(play->state.gfxCtx);

View file

@ -3,6 +3,23 @@
#include "ultra64.h"
#include "global.h"
#include "assets/objects/object_cow/object_cow.h"
#define COW_FLAG_PLAYER_NEARBY (1 << 1)
#define COW_FLAG_FAILED_TO_GIVE_MILK (1 << 2)
#define COW_GET_TYPE(thisx) ((thisx)->actor.params)
typedef enum {
/* 0 */ COW_TYPE_BODY,
/* 1 */ COW_TYPE_TAIL
} CowType;
typedef enum {
/* 0 */ COW_COLLIDER_FRONT,
/* 1 */ COW_COLLIDER_REAR,
/* 2 */ COW_COLLIDER_MAX
} CowCollider;
struct EnCow;
@ -10,14 +27,14 @@ typedef void (*EnCowActionFunc)(struct EnCow*, PlayState*);
typedef struct EnCow {
/* 0x0000 */ Actor actor;
/* 0x014C */ ColliderCylinder colliders[2];
/* 0x014C */ ColliderCylinder colliders[COW_COLLIDER_MAX];
/* 0x01E4 */ SkelAnime skelAnime;
/* 0x0228 */ Vec3s jointTable[6];
/* 0x024C */ Vec3s morphTable[6];
/* 0x0270 */ Vec3s someRot;
/* 0x0276 */ u16 unk_276;
/* 0x0278 */ u16 unk_278;
/* 0x027A */ u16 unk_27A;
/* 0x0228 */ Vec3s jointTable[COW_LIMB_MAX];
/* 0x024C */ Vec3s morphTable[COW_LIMB_MAX];
/* 0x0270 */ Vec3s headRot;
/* 0x0276 */ u16 cowFlags;
/* 0x0278 */ u16 animationTimer;
/* 0x027A */ u16 breathTimer;
/* 0x027C */ EnCowActionFunc actionFunc;
} EnCow; // size = 0x0280

View file

@ -743,7 +743,7 @@ void EnHorse_Init(Actor* thisx, PlayState* play2) {
AREG(6) = 0;
Actor_ProcessInitChain(&this->actor, sInitChain);
EnHorse_ClearDustFlags(&this->dustFlags);
DREG(53) = 0;
R_EPONAS_SONG_PLAYED = false;
this->riderPos = this->actor.world.pos;
this->noInputTimer = 0;
this->noInputTimerMax = 0;
@ -1735,8 +1735,8 @@ void EnHorse_SetFollowAnimation(EnHorse* this, PlayState* play);
void EnHorse_Inactive(EnHorse* this, PlayState* play2) {
PlayState* play = play2;
if (DREG(53) != 0 && this->type == HORSE_EPONA) {
DREG(53) = 0;
if (R_EPONAS_SONG_PLAYED && this->type == HORSE_EPONA) {
R_EPONAS_SONG_PLAYED = false;
if (EnHorse_Spawn(this, play) != 0) {
Audio_PlaySfxGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
@ -1810,8 +1810,8 @@ void EnHorse_Idle(EnHorse* this, PlayState* play) {
this->actor.speed = 0.0f;
EnHorse_IdleAnimSounds(this, play);
if (DREG(53) && this->type == HORSE_EPONA) {
DREG(53) = 0;
if (R_EPONAS_SONG_PLAYED && this->type == HORSE_EPONA) {
R_EPONAS_SONG_PLAYED = false;
if (!func_80A5BBBC(play, this, &this->actor.world.pos)) {
if (EnHorse_Spawn(this, play)) {
Audio_PlaySfxGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
@ -1905,7 +1905,7 @@ void EnHorse_FollowPlayer(EnHorse* this, PlayState* play) {
f32 distToPlayer;
f32 angleDiff;
DREG(53) = 0;
R_EPONAS_SONG_PLAYED = false;
distToPlayer = Actor_WorldDistXZToActor(&this->actor, &GET_PLAYER(play)->actor);
// First rotate if the player is behind
@ -2597,7 +2597,7 @@ void EnHorse_FleePlayer(EnHorse* this, PlayState* play) {
s32 animFinished;
s16 yaw;
if (DREG(53) || this->type == HORSE_HNI) {
if (R_EPONAS_SONG_PLAYED || this->type == HORSE_HNI) {
EnHorse_StartIdleRidable(this);
Audio_PlaySfxGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);

View file

@ -358,7 +358,7 @@ void func_80A6A068(EnHorseLinkChild* this, PlayState* play) {
return;
}
if ((GET_EVENTCHKINF(EVENTCHKINF_16) && (DREG(53) != 0)) ||
if ((GET_EVENTCHKINF(EVENTCHKINF_16) && R_EPONAS_SONG_PLAYED) ||
((play->sceneId == SCENE_LON_LON_RANCH) && (gSaveContext.save.cutsceneIndex == 0xFFF1))) {
func_80A6A4DC(this);
} else {
@ -434,7 +434,7 @@ void func_80A6A068(EnHorseLinkChild* this, PlayState* play) {
void func_80A6A4DC(EnHorseLinkChild* this) {
this->action = 5;
this->animationIdx = Rand_ZeroOne() > 0.5f ? 0 : 1;
DREG(53) = 0;
R_EPONAS_SONG_PLAYED = false;
Animation_Change(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A695A4(this), 0.0f,
Animation_GetLastFrame(sAnimations[this->animationIdx]), ANIMMODE_ONCE, 0.0f);
}
@ -442,8 +442,8 @@ void func_80A6A4DC(EnHorseLinkChild* this) {
void func_80A6A5A4(EnHorseLinkChild* this, PlayState* play) {
s16 yawDiff;
if (DREG(53) != 0) {
DREG(53) = 0;
if (R_EPONAS_SONG_PLAYED) {
R_EPONAS_SONG_PLAYED = false;
Audio_PlaySfxGeneral(NA_SE_EV_KID_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
func_80A6A724(this);

View file

@ -339,7 +339,7 @@ void func_80A795C8(EnIn* this, PlayState* play) {
void func_80A79690(SkelAnime* skelAnime, EnIn* this, PlayState* play) {
if (skelAnime->baseTransl.y < skelAnime->jointTable[0].y) {
skelAnime->moveFlags |= 3;
skelAnime->moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, skelAnime, 1.0f);
}
}

View file

@ -87,7 +87,7 @@ u16 EnMa3_GetTextId(PlayState* play, Actor* thisx) {
HIGH_SCORE(HS_HORSE_RACE) = 180;
}
if (!GET_EVENTCHKINF(EVENTCHKINF_1E) && (((void)0, gSaveContext.timerSeconds) < 50)) {
if (!GET_EVENTCHKINF(EVENTCHKINF_HORSE_RACE_COW_UNLOCK) && (((void)0, gSaveContext.timerSeconds) < 50)) {
return 0x208F;
}
@ -128,7 +128,7 @@ s16 EnMa3_UpdateTalkState(PlayState* play, Actor* thisx) {
if (Message_ShouldAdvance(play)) {
SET_INFTABLE(INFTABLE_B9);
if (play->msgCtx.choiceIndex == 0) {
if (GET_EVENTCHKINF(EVENTCHKINF_1E)) {
if (GET_EVENTCHKINF(EVENTCHKINF_HORSE_RACE_COW_UNLOCK)) {
Message_ContinueTextbox(play, 0x2091);
} else if (HIGH_SCORE(HS_HORSE_RACE) == 0) {
Message_ContinueTextbox(play, 0x2092);
@ -145,7 +145,7 @@ s16 EnMa3_UpdateTalkState(PlayState* play, Actor* thisx) {
talkState = NPC_TALK_STATE_IDLE;
break;
case 0x208F:
SET_EVENTCHKINF(EVENTCHKINF_1E);
SET_EVENTCHKINF(EVENTCHKINF_HORSE_RACE_COW_UNLOCK);
FALLTHROUGH;
case 0x2004:
case 0x2012:

View file

@ -745,7 +745,7 @@ void EnNb_InitDemo6KInConfrontation(EnNb* this, PlayState* play) {
}
void func_80AB2688(EnNb* this, PlayState* play) {
this->skelAnime.moveFlags |= 1;
this->skelAnime.moveFlags |= ANIM_FLAG_0;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}

View file

@ -229,7 +229,7 @@ void EnNiw_Init(Actor* thisx, PlayState* play) {
case 0xD:
case 0xE:
Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit2);
if (play->sceneId == SCENE_LINKS_HOUSE && !GET_EVENTCHKINF(EVENTCHKINF_1E)) {
if (play->sceneId == SCENE_LINKS_HOUSE && !GET_EVENTCHKINF(EVENTCHKINF_HORSE_RACE_COW_UNLOCK)) {
Actor_Kill(&this->actor);
}
break;

View file

@ -390,17 +390,17 @@ s32 EnRu1_UpdateSkelAnime(EnRu1* this) {
}
void func_80AEB364(EnRu1* this, PlayState* play) {
this->skelAnime.moveFlags |= 1;
this->skelAnime.moveFlags |= ANIM_FLAG_0;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}
void func_80AEB3A4(EnRu1* this, PlayState* play) {
this->skelAnime.moveFlags |= 1;
this->skelAnime.moveFlags |= ANIM_FLAG_0;
func_80AEB364(this, play);
}
void func_80AEB3CC(EnRu1* this) {
this->skelAnime.moveFlags &= ~0x1;
this->skelAnime.moveFlags &= ~ANIM_FLAG_0;
}
void func_80AEB3DC(EnRu1* this, PlayState* play) {
@ -461,7 +461,7 @@ void func_80AEB6E0(EnRu1* this, PlayState* play) {
SkelAnime* skelAnime = &this->skelAnime;
if (skelAnime->baseTransl.y < skelAnime->jointTable[0].y) {
skelAnime->moveFlags |= 3;
skelAnime->moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, skelAnime, 1.0f);
}
}
@ -472,13 +472,13 @@ void func_80AEB738(EnRu1* this, PlayState* play) {
skelAnime->baseTransl = skelAnime->jointTable[0];
skelAnime->prevTransl = skelAnime->jointTable[0];
if (skelAnime->baseTransl.y < skelAnime->jointTable[0].y) {
skelAnime->moveFlags |= 3;
skelAnime->moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, skelAnime, 1.0f);
}
}
void func_80AEB7D0(EnRu1* this) {
this->skelAnime.moveFlags &= ~0x3;
this->skelAnime.moveFlags &= ~(ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y);
}
f32 func_80AEB7E0(CsCmdActorCue* cue, PlayState* play) {

View file

@ -122,7 +122,7 @@ void EnSsh_SpawnShockwave(EnSsh* this, PlayState* play) {
pos.x = this->actor.world.pos.x;
pos.y = this->actor.floorHeight;
pos.z = this->actor.world.pos.z;
EffectSsBlast_SpawnWhiteCustomScale(play, &pos, &zeroVec, &zeroVec, 100, 220, 8);
EffectSsBlast_SpawnWhiteShockwaveSetScale(play, &pos, &zeroVec, &zeroVec, 100, 220, 8);
}
s32 EnSsh_CreateBlureEffect(PlayState* play) {

View file

@ -161,7 +161,7 @@ void EnSt_SpawnBlastEffect(EnSt* this, PlayState* play) {
blastPos.y = this->actor.floorHeight;
blastPos.z = this->actor.world.pos.z;
EffectSsBlast_SpawnWhiteCustomScale(play, &blastPos, &zeroVec, &zeroVec, 100, 220, 8);
EffectSsBlast_SpawnWhiteShockwaveSetScale(play, &blastPos, &zeroVec, &zeroVec, 100, 220, 8);
}
void EnSt_SpawnDeadEffect(EnSt* this, PlayState* play) {

File diff suppressed because it is too large Load diff

View file

@ -9,15 +9,15 @@ struct EnSyatekiNiw;
typedef void (*EnSyatekiNiwActionFunc)(struct EnSyatekiNiw*, PlayState*);
typedef struct {
/* 0x00 */ u8 unk_00;
/* 0x0C */ Vec3f unk_04;
/* 0x10 */ Vec3f unk_10;
/* 0x1C */ Vec3f unk_1C;
/* 0x28 */ s16 unk_28;
/* 0x2A */ s16 unk_2A;
/* 0x2C */ f32 unk_2C;
/* 0x30 */ f32 unk_30;
/* 0x34 */ u8 unk_34;
/* 0x00 */ u8 state;
/* 0x0C */ Vec3f pos;
/* 0x10 */ Vec3f vel;
/* 0x1C */ Vec3f accel;
/* 0x28 */ s16 lifespan;
/* 0x2A */ s16 rotPulse;
/* 0x2C */ f32 scale;
/* 0x30 */ f32 rot;
/* 0x34 */ u8 timer;
} EnSyatekiNiwEffect; // size = 0x38
#define EN_SYATEKI_NIW_EFFECT_COUNT 5
@ -28,46 +28,51 @@ typedef struct EnSyatekiNiw {
/* 0x0190 */ Vec3s jointTable[16];
/* 0x01F0 */ Vec3s morphTable[16];
/* 0x0250 */ EnSyatekiNiwActionFunc actionFunc;
/* 0x0254 */ s16 unk_254;
/* 0x0256 */ s16 unk_256;
/* 0x0258 */ s16 unk_258;
/* 0x025A */ s16 unk_25A;
/* 0x025C */ s16 unk_25C;
/* 0x025E */ s16 unk_25E;
/* 0x0260 */ s16 unk_260;
/* 0x0262 */ s16 unk_262;
/* 0x0264 */ f32 unk_264;
/* 0x0268 */ f32 unk_268;
/* 0x026C */ f32 unk_26C;
/* 0x0254 */ s16 peckTimer; // intervals of bobbing head on ground
/* 0x0256 */ s16 timer1; // sometimes set alongside peckTimer, never read.
/* 0x0258 */ s16 flapTimer; // intervals of beating wings
/* 0x025A */ s16 archeryTimer;
/* 0x025C */ s16 hopTimer; // intervals of jumping
/* 0x025E */ s16 movementTimer; // intervals of changing location
/* 0x0260 */ s16 sootTimer; // cucco is covered in soot, smoke emmits
/* 0x0262 */ s16 cluckTimer; // intervals of clucking SFX
/* 0x0264 */ f32 headRotXTarget;
/* 0x0268 */ f32 rightWingRotXTarget;
/* 0x026C */ f32 leftWingRotXTarget;
/* 0x0270 */ char unk_270[0x8];
/* 0x0278 */ f32 unk_278;
/* 0x027C */ f32 unk_27C;
/* 0x0284 */ f32 unk_280;
/* 0x0280 */ f32 unk_284;
/* 0x0288 */ f32 unk_288;
/* 0x028C */ s16 unk_28C;
/* 0x028E */ s16 unk_28E;
/* 0x0290 */ s16 unk_290;
/* 0x0292 */ s16 unk_292;
/* 0x0294 */ s16 unk_294;
/* 0x0296 */ s16 unk_296;
/* 0x0298 */ s16 unk_298;
/* 0x029C */ s16 unk_29A;
/* 0x029C */ s16 unk_29C;
/* 0x029E */ s16 unk_29E;
/* 0x02A0 */ s16 unk_2A0;
/* 0x02A4 */ Vec3f unk_2A4;
/* 0x02B0 */ Vec3f unk_2B0;
/* 0x02BC */ Vec3f unk_2BC;
/* 0x02C8 */ Vec3f unk_2C8;
/* 0x02D4 */ f32 unk_2D4;
/* 0x02D8 */ f32 unk_2D8;
/* 0x02DC */ Vec3f unk_2DC;
/* 0x02E8 */ Vec3f unk_2E8;
/* 0x02F4 */ f32 unk_2F4;
/* 0x02F8 */ u8 unk_2F8;
/* 0x0278 */ f32 rightWingRotYTarget;
/* 0x027C */ f32 rightWingRotZTarget;
/* 0x0284 */ f32 leftWingRotYTarget;
/* 0x0280 */ f32 leftWingRotZTarget;
/* 0x0288 */ f32 unkArcheryFloat; // set, but never used. another rot target?
/* 0x028C */ s16 lifetime; // always ticks up, never read
/* 0x028E */ s16 headRotXState;
/* 0x0290 */ s16 unk_290; // set to 0, never read.
/* 0x0292 */ s16 wingsRotState;
/* 0x0294 */ s16 targetPosTimer;
/* 0x0296 */ s16 archeryAnimationType;
/* 0x0298 */ s16 rotYFlip;
/* 0x029C */ s16 archeryState; // state index for "Archery" action
/* 0x029C */ s16 isFalling; // set when hit in archery game
/* 0x029E */ s16 minigameType; // uses EnSyatekiMinigame from params
/* 0x02A0 */ s16 spawnFeathers; // triggers feather particles
/* 0x02A4 */ Vec3f leftWingRot;
/* 0x02B0 */ Vec3f rightWingRot;
/* 0x02BC */ Vec3f headRot;
/* 0x02C8 */ Vec3f posRotStep;
/* 0x02D4 */ f32 focusYOffset;
/* 0x02D8 */ f32 removeStateYaw;
/* 0x02DC */ Vec3f initPos;
/* 0x02E8 */ Vec3f targetPos;
/* 0x02F4 */ f32 scale;
/* 0x02F8 */ u8 unkAlleyHitByte; // Set when hit in Bombchu Alley. Never read.
/* 0x02FC */ ColliderCylinder collider;
/* 0x0348 */ EnSyatekiNiwEffect effects[EN_SYATEKI_NIW_EFFECT_COUNT];
/* 0x0348 */ EnSyatekiNiwEffect effects[EN_SYATEKI_NIW_EFFECT_COUNT]; // feather particles
} EnSyatekiNiw; // size = 0x0460
typedef enum {
SYATEKI_MINIGAME_ARCHERY, // unused archery game behavior
SYATEKI_MINIGAME_ALLEY // Bombchu Alley behavior
} EnSyatekiMinigame;
#endif

View file

@ -1592,7 +1592,7 @@ void func_8086318C(EnTest* this, PlayState* play) {
void EnTest_SetupRecoil(EnTest* this) {
this->swordState = 0;
this->skelAnime.moveFlags = 2;
this->skelAnime.moveFlags = ANIM_FLAG_UPDATE_Y;
this->unk_7C8 = 0x13;
this->skelAnime.playSpeed = -1.0f;
this->skelAnime.startFrame = this->skelAnime.curFrame;

View file

@ -249,25 +249,25 @@ void func_80B3C8CC(EnXc* this, PlayState* play) {
SkelAnime* skelAnime = &this->skelAnime;
if (skelAnime->jointTable[0].y >= skelAnime->baseTransl.y) {
skelAnime->moveFlags |= 3;
skelAnime->moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, skelAnime, 1.0f);
}
}
void func_80B3C924(EnXc* this, PlayState* play) {
this->skelAnime.moveFlags |= 3;
this->skelAnime.moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}
void func_80B3C964(EnXc* this, PlayState* play) {
this->skelAnime.baseTransl = this->skelAnime.jointTable[0];
this->skelAnime.prevTransl = this->skelAnime.jointTable[0];
this->skelAnime.moveFlags |= 3;
this->skelAnime.moveFlags |= ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}
void func_80B3C9DC(EnXc* this) {
this->skelAnime.moveFlags &= ~0x3;
this->skelAnime.moveFlags &= ~(ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y);
}
void func_80B3C9EC(EnXc* this) {

View file

@ -345,7 +345,7 @@ void func_80B4B834(CsCmdActorCue* cue, Vec3f* dest) {
}
void func_80B4B874(EnZl1* this, PlayState* play) {
this->skelAnime.moveFlags |= 1;
this->skelAnime.moveFlags |= ANIM_FLAG_0;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}

View file

@ -298,7 +298,7 @@ void EnZl4_UpdateFace(EnZl4* this) {
}
void EnZl4_SetMove(EnZl4* this, PlayState* play) {
this->skelAnime.moveFlags |= 1;
this->skelAnime.moveFlags |= ANIM_FLAG_0;
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime, 1.0f);
}

File diff suppressed because it is too large Load diff

View file

@ -9,50 +9,48 @@ struct Fishing;
typedef struct Fishing {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x004];
/* 0x0150 */ u8 unk_150;
/* 0x0151 */ u8 unk_151;
/* 0x0150 */ u8 isLoach;
/* 0x0151 */ u8 lilyTimer; // if near lily and >0, lily moves. Move more if >20
/* 0x0152 */ u8 unk_152;
/* 0x0154 */ s16 unk_154;
/* 0x0156 */ u8 unk_156;
/* 0x0157 */ u8 unk_157;
/* 0x0158 */ s16 unk_158;
/* 0x015A */ s16 unk_15A;
/* 0x015C */ s16 unk_15C;
/* 0x0158 */ s16 fishState; // negative index for loach behavior
/* 0x015A */ s16 fishStateNext;
/* 0x015C */ s16 stateAndTimer; // fish use as timer that's AND'd, owner as talking state
/* 0x015E */ s16 unk_15E;
/* 0x0160 */ s16 unk_160;
/* 0x0162 */ s16 unk_162;
/* 0x0164 */ s16 unk_164;
/* 0x0166 */ s16 unk_166;
/* 0x0168 */ s16 unk_168;
/* 0x016A */ s16 unk_16A;
/* 0x016C */ s16 unk_16C;
/* 0x0160 */ s16 unk_160; // fish use as rotateX, owner as index of eye texture
/* 0x0162 */ s16 unk_162; // fish use as rotateY, owner as index of eye texture
/* 0x0164 */ s16 unk_164; // fish use as rotateZ, owner as rotation of head
/* 0x0166 */ Vec3s rotationTarget;
/* 0x016C */ s16 fishLimb23RotYDelta;
/* 0x016E */ s16 unk_16E;
/* 0x0170 */ s16 unk_170;
/* 0x0172 */ s16 unk_172;
/* 0x0174 */ s16 unk_174;
/* 0x0176 */ s16 unk_176;
/* 0x0170 */ s16 fishLimbDRotZDelta;
/* 0x0172 */ s16 fishLimbEFRotYDelta;
/* 0x0174 */ s16 fishLimb89RotYDelta;
/* 0x0176 */ s16 fishLimb4RotYDelta;
/* 0x0178 */ s16 unk_178;
/* 0x017A */ s16 unk_17A[4];
/* 0x017A */ s16 timerArray[4];
/* 0x0184 */ f32 unk_184;
/* 0x0188 */ f32 unk_188;
/* 0x018C */ f32 unk_18C;
/* 0x0190 */ f32 unk_190;
/* 0x0194 */ f32 unk_194;
/* 0x0198 */ f32 unk_198;
/* 0x019C */ f32 unk_19C;
/* 0x01A0 */ s16 unk_1A0;
/* 0x01A2 */ s16 unk_1A2;
/* 0x01A4 */ s16 unk_1A4;
/* 0x01A8 */ f32 unk_1A8;
/* 0x01AC */ f32 unk_1AC;
/* 0x01B0 */ f32 unk_1B0;
/* 0x01B4 */ Vec3f unk_1B4;
/* 0x0188 */ f32 speedTarget;
/* 0x018C */ f32 fishLimbRotPhase;
/* 0x0190 */ f32 unk_190; // fishLimbRotPhaseStep target
/* 0x0194 */ f32 unk_194; // fishLimbRotPhaseMag target
/* 0x0198 */ f32 fishLimbRotPhaseStep;
/* 0x019C */ f32 fishLimbRotPhaseMag;
/* 0x01A0 */ s16 bumpTimer; // set when hitting a wall.
/* 0x01A2 */ s16 unk_1A2; // "scared" timer?
/* 0x01A4 */ s16 unk_1A4; // "scared" timer? set at same time as above
/* 0x01A8 */ f32 perception; // how easily they are drawn to the lure.
/* 0x01AC */ f32 fishLength; // fish are (x^2*.0036+.5) lbs, loach double that.
/* 0x01B0 */ f32 rotationStep;
/* 0x01B4 */ Vec3f fishTargetPos;
/* 0x01C0 */ Vec3f fishMouthPos;
/* 0x01CC */ s16 unk_1CC[3];
/* 0x01D2 */ u8 unk_1D2;
/* 0x01D3 */ u8 unk_1D3;
/* 0x01D4 */ u8 unk_1D4;
/* 0x01D5 */ u8 unk_1D5;
/* 0x01CC */ s16 loachRotYDelta[3]; // adds rotation to the loach limb 3-5.
/* 0x01D2 */ u8 bubbleTime; // spawn bubbles while >0
/* 0x01D3 */ u8 isAquariumMessage;
/* 0x01D4 */ u8 aquariumWaitTimer;
/* 0x01D5 */ u8 keepState; // case-switch and keeping or releasing a fish
/* 0x01D8 */ SkelAnime skelAnime;
/* 0x021C */ LightNode* lightNode;
/* 0x0220 */ LightInfo lightInfo;
@ -60,4 +58,8 @@ typedef struct Fishing {
/* 0x0250 */ ColliderJntSphElement colliderElements[12];
} Fishing; // size = 0x0550
#define EN_FISH_OWNER 1 // param for owner of pond. default if params<100
#define EN_FISH_PARAM 100 // param base for fish in pond.
#define EN_FISH_AQUARIUM 200 // param for record fish in tank.
#endif

View file

@ -1867,8 +1867,8 @@ void func_80832DBC(Player* this) {
func_808322FC(this);
this->skelAnime.jointTable[0].x = this->skelAnime.baseTransl.x;
this->skelAnime.jointTable[0].z = this->skelAnime.baseTransl.z;
if (this->skelAnime.moveFlags & 8) {
if (this->skelAnime.moveFlags & 2) {
if (this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_SETMOVE) {
if (this->skelAnime.moveFlags & ANIM_FLAG_UPDATE_Y) {
this->skelAnime.jointTable[0].y = this->skelAnime.prevTransl.y;
}
} else {
@ -1905,17 +1905,20 @@ void func_80832E48(Player* this, s32 flags) {
func_808322FC(this);
}
#define FLAG_FUNC_80832F54_8 (1 << 8)
#define FLAG_FUNC_80832F54_9 (1 << 9)
void func_80832F54(PlayState* play, Player* this, s32 flags) {
if (flags & 0x200) {
if (flags & FLAG_FUNC_80832F54_9) {
func_80832D20(this);
} else if ((flags & 0x100) || (this->skelAnime.moveFlags != 0)) {
} else if ((flags & FLAG_FUNC_80832F54_8) || (this->skelAnime.moveFlags != 0)) {
func_80832CFC(this);
} else {
this->skelAnime.prevTransl = this->skelAnime.jointTable[0];
this->skelAnime.prevRot = this->actor.shape.rot.y;
}
this->skelAnime.moveFlags = flags;
this->skelAnime.moveFlags = flags & 0xFF;
Player_ZeroSpeedXZ(this);
AnimationContext_DisableQueue(play);
}
@ -1934,7 +1937,7 @@ void func_80833064(PlayState* play, Player* this, LinkAnimationHeader* anim, s32
}
void func_8083308C(PlayState* play, Player* this, LinkAnimationHeader* anim) {
func_80833064(play, this, anim, 0x1C);
func_80833064(play, this, anim, ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE);
}
void func_808330AC(PlayState* play, Player* this, LinkAnimationHeader* anim, s32 flags, f32 playbackSpeed) {
@ -1951,7 +1954,7 @@ void func_80833114(PlayState* play, Player* this, LinkAnimationHeader* anim, s32
}
void func_8083313C(PlayState* play, Player* this, LinkAnimationHeader* anim) {
func_80833114(play, this, anim, 0x1C);
func_80833114(play, this, anim, ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE);
}
void func_8083315C(PlayState* play, Player* this) {
@ -2884,8 +2887,8 @@ s32 func_80835588(Player* this, PlayState* play) {
void func_808355DC(Player* this) {
this->stateFlags1 |= PLAYER_STATE1_17;
if (!(this->skelAnime.moveFlags & 0x80) && (this->actor.bgCheckFlags & BGCHECKFLAG_PLAYER_WALL_INTERACT) &&
(D_80853608 < 0x2000)) {
if (!(this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_7) &&
(this->actor.bgCheckFlags & BGCHECKFLAG_PLAYER_WALL_INTERACT) && (D_80853608 < 0x2000)) {
this->yaw = this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
}
@ -3263,7 +3266,9 @@ s32 func_80836670(Player* this, PlayState* play) {
func_80835C58(play, this, func_80850AEC, 1);
this->stateFlags3 |= PLAYER_STATE3_7;
func_80832264(play, this, &gPlayerAnim_link_hook_fly_start);
func_80832F54(play, this, 0x9B);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE |
ANIM_FLAG_PLAYER_7);
func_80832224(this);
this->yaw = this->actor.shape.rot.y;
this->actor.bgCheckFlags &= ~BGCHECKFLAG_GROUND;
@ -3782,7 +3787,7 @@ void func_80837948(PlayState* play, Player* this, s32 arg2) {
func_808322D0(play, this, D_80854190[arg2].unk_00);
if ((arg2 != PLAYER_MWA_FLIPSLASH_START) && (arg2 != PLAYER_MWA_JUMPSLASH_START)) {
func_80832F54(play, this, 0x209);
func_80832F54(play, this, FLAG_FUNC_80832F54_9 | ANIM_FLAG_0 | ANIM_FLAG_PLAYER_SETMOVE);
}
this->yaw = this->actor.shape.rot.y;
@ -3827,7 +3832,7 @@ s32 func_80837B18(PlayState* play, Player* this, s32 damage) {
void func_80837B60(Player* this) {
this->skelAnime.prevTransl = this->skelAnime.jointTable[0];
func_80832E48(this, 3);
func_80832E48(this, ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y);
}
void func_80837B9C(Player* this, PlayState* play) {
@ -4686,7 +4691,9 @@ s32 func_80839800(Player* this, PlayState* play) {
}
func_80832224(this);
func_80832F54(play, this, 0x28F);
func_80832F54(play, this,
FLAG_FUNC_80832F54_9 | ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_2 |
ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_PLAYER_7);
// If this door is the second half of a double door (spawned as child)
if (doorActor->parent != NULL) {
@ -4989,7 +4996,9 @@ s32 func_8083A6AC(Player* this, PlayState* play) {
this->actor.shape.rot.y = this->yaw;
this->stateFlags1 |= PLAYER_STATE1_21;
func_80832F54(play, this, 0x9F);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE |
ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
this->unk_850 = -1;
this->unk_84F = sp50;
@ -5034,7 +5043,7 @@ void func_8083AA10(Player* this, PlayState* play) {
return;
}
if (!(this->stateFlags3 & PLAYER_STATE3_1) && !(this->skelAnime.moveFlags & 0x80) &&
if (!(this->stateFlags3 & PLAYER_STATE3_1) && !(this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_7) &&
(func_8084411C != this->func_674) && (func_80844A44 != this->func_674)) {
if ((D_80853604 == FLOOR_PROPERTY_7) || (this->meleeWeaponState != 0)) {
@ -5659,7 +5668,7 @@ s32 func_8083C2B0(Player* this, PlayState* play) {
LinkAnimation_Change(play, &this->skelAnime, anim, 1.0f, frame, frame, ANIMMODE_ONCE, 0.0f);
if (Player_IsChildWithHylianShield(this)) {
func_80832F54(play, this, 4);
func_80832F54(play, this, ANIM_FLAG_PLAYER_2);
}
Player_PlaySfx(this, NA_SE_IT_SHIELD_POSTURE);
@ -6310,7 +6319,9 @@ s32 func_8083E0FC(Player* this, PlayState* play) {
Actor_MountHorse(play, this, &rideActor->actor);
func_80832264(play, this, D_80854578[temp].anim);
func_80832F54(play, this, 0x9B);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE |
ANIM_FLAG_PLAYER_7);
this->actor.parent = this->rideActor;
func_80832224(this);
Actor_DisableLens(play);
@ -6465,7 +6476,9 @@ s32 func_8083E5A8(Player* this, PlayState* play) {
if ((giEntry->itemId != ITEM_NONE) && (giEntry->gi >= 0) &&
(Item_CheckObtainability(giEntry->itemId) == ITEM_NONE)) {
func_808322D0(play, this, this->ageProperties->unk_98);
func_80832F54(play, this, 0x28F);
func_80832F54(play, this,
FLAG_FUNC_80832F54_9 | ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_2 |
ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_PLAYER_7);
chest->unk_1F4 = 1;
Camera_ChangeSetting(Play_GetCamera(play, CAM_ID_MAIN), CAM_SET_SLOW_CHEST_CS);
} else {
@ -6641,7 +6654,9 @@ s32 func_8083EC18(Player* this, PlayState* play, u32 interactWallFlags) {
func_80832224(this);
Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.world.pos);
func_80832264(play, this, sp30);
func_80832F54(play, this, 0x9F);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE |
ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
return true;
}
@ -6720,7 +6735,9 @@ s32 Player_TryEnteringCrawlspace(Player* this, PlayState* play, u32 interactWall
func_80832224(this);
this->actor.prevPos = this->actor.world.pos;
func_80832264(play, this, &gPlayerAnim_link_child_tunnel_start);
func_80832F54(play, this, 0x9D);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE |
ANIM_FLAG_PLAYER_7);
return true;
}
@ -6808,7 +6825,9 @@ s32 Player_TryLeavingCrawlspace(Player* this, PlayState* play) {
// Leaving a crawlspace forwards
this->actor.shape.rot.y = this->actor.wallYaw + 0x8000;
func_80832264(play, this, &gPlayerAnim_link_child_tunnel_end);
func_80832F54(play, this, 0x9D);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE |
ANIM_FLAG_PLAYER_7);
OnePointCutscene_Init(play, 9601, 999, NULL, CAM_ID_MAIN);
} else {
// Leaving a crawlspace backwards
@ -6816,7 +6835,9 @@ s32 Player_TryLeavingCrawlspace(Player* this, PlayState* play) {
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_link_child_tunnel_start, -1.0f,
Animation_GetLastFrame(&gPlayerAnim_link_child_tunnel_start), 0.0f, ANIMMODE_ONCE,
0.0f);
func_80832F54(play, this, 0x9D);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE |
ANIM_FLAG_PLAYER_7);
OnePointCutscene_Init(play, 9602, 999, NULL, CAM_ID_MAIN);
}
@ -8226,7 +8247,7 @@ void func_80843188(Player* this, PlayState* play) {
LinkAnimation_Change(play, &this->skelAnime, &gPlayerAnim_clink_normal_defense_ALL, 1.0f,
Animation_GetLastFrame(&gPlayerAnim_clink_normal_defense_ALL), 0.0f,
ANIMMODE_ONCE, 0.0f);
func_80832F54(play, this, 4);
func_80832F54(play, this, ANIM_FLAG_PLAYER_2);
} else {
if (this->itemAction < 0) {
func_8008EC70(this);
@ -9525,7 +9546,9 @@ void func_808467D4(PlayState* play, Player* this) {
this->yaw = this->actor.shape.rot.y = -0x8000;
LinkAnimation_Change(play, &this->skelAnime, this->ageProperties->unk_A0, 2.0f / 3.0f, 0.0f, 0.0f, ANIMMODE_ONCE,
0.0f);
func_80832F54(play, this, 0x28F);
func_80832F54(play, this,
FLAG_FUNC_80832F54_9 | ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_2 |
ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_PLAYER_7);
if (LINK_IS_ADULT) {
func_80846720(play, this, 0);
}
@ -9534,7 +9557,8 @@ void func_808467D4(PlayState* play, Player* this) {
void func_808468A8(PlayState* play, Player* this) {
func_80835C58(play, this, func_8084F9A0, 0);
func_80832F54(play, this, 0x9B);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
}
void func_808468E8(PlayState* play, Player* this) {
@ -10579,7 +10603,9 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
func_8083A360(play, this);
this->stateFlags1 |= PLAYER_STATE1_23;
func_80832264(play, this, &gPlayerAnim_link_uma_wait_1);
func_80832F54(play, this, 0x9B);
func_80832F54(play, this,
ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE |
ANIM_FLAG_PLAYER_7);
this->unk_850 = 99;
}
@ -10604,7 +10630,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
func_8084FF7C(this);
}
if (!(this->skelAnime.moveFlags & 0x80)) {
if (!(this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_7)) {
if (((this->actor.bgCheckFlags & BGCHECKFLAG_GROUND) && (D_808535E4 == FLOOR_TYPE_5) &&
(this->currentBoots != PLAYER_BOOTS_IRON)) ||
((this->currentBoots == PLAYER_BOOTS_HOVER) &&
@ -10787,9 +10813,10 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
Player_UpdateCamAndSeqModes(play, this);
if (this->skelAnime.moveFlags & 8) {
AnimationContext_SetMoveActor(play, &this->actor, &this->skelAnime,
(this->skelAnime.moveFlags & 4) ? 1.0f : this->ageProperties->unk_08);
if (this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_SETMOVE) {
AnimationContext_SetMoveActor(
play, &this->actor, &this->skelAnime,
(this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_2) ? 1.0f : this->ageProperties->unk_08);
}
func_808368EC(this, play);
@ -11579,7 +11606,7 @@ void func_8084BDFC(Player* this, PlayState* play) {
this->stateFlags2 |= PLAYER_STATE2_6;
if (LinkAnimation_Update(play, &this->skelAnime)) {
func_80832E48(this, 1);
func_80832E48(this, ANIM_FLAG_0);
func_8083C0E8(this, play);
return;
}
@ -13936,7 +13963,8 @@ void func_808510D4(PlayState* play, Player* this, void* anim) {
}
void func_808510F4(PlayState* play, Player* this, void* anim) {
func_8083303C(play, this, anim, 0x9C);
func_8083303C(play, this, anim,
ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
}
void func_80851114(PlayState* play, Player* this, void* anim) {
@ -13944,7 +13972,8 @@ void func_80851114(PlayState* play, Player* this, void* anim) {
}
void func_80851134(PlayState* play, Player* this, void* anim) {
func_808330EC(play, this, anim, 0x9C);
func_808330EC(play, this, anim,
ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
}
void func_80851154(PlayState* play, Player* this, void* anim) {
@ -14189,7 +14218,9 @@ void func_808519EC(PlayState* play, Player* this, CsCmdActorCue* cue) {
Math_Vec3f_Copy(&this->actor.world.pos, &D_80855198);
this->actor.shape.rot.y = -0x8000;
func_808322D0(play, this, this->ageProperties->unk_9C);
func_80832F54(play, this, 0x28F);
func_80832F54(play, this,
FLAG_FUNC_80832F54_9 | ANIM_FLAG_0 | ANIM_FLAG_UPDATE_Y | ANIM_FLAG_PLAYER_2 |
ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_PLAYER_7);
}
static struct_808551A4 D_808551A4[] = {
@ -14299,17 +14330,20 @@ void func_80851E28(PlayState* play, Player* this, CsCmdActorCue* cue) {
}
void func_80851E64(PlayState* play, Player* this, CsCmdActorCue* cue) {
func_80833064(play, this, &gPlayerAnim_link_swimer_swim_get, 0x98);
func_80833064(play, this, &gPlayerAnim_link_swimer_swim_get,
ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
}
void func_80851E90(PlayState* play, Player* this, CsCmdActorCue* cue) {
func_8083303C(play, this, &gPlayerAnim_clink_op3_negaeri, 0x9C);
func_8083303C(play, this, &gPlayerAnim_clink_op3_negaeri,
ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
func_80832698(this, NA_SE_VO_LI_GROAN);
}
void func_80851ECC(PlayState* play, Player* this, CsCmdActorCue* cue) {
if (LinkAnimation_Update(play, &this->skelAnime)) {
func_808330EC(play, this, &gPlayerAnim_clink_op3_wait2, 0x9C);
func_808330EC(play, this, &gPlayerAnim_clink_op3_wait2,
ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
}
}
@ -14335,7 +14369,8 @@ static struct_80832924 D_808551BC[] = {
void func_80851FB0(PlayState* play, Player* this, CsCmdActorCue* cue) {
if (LinkAnimation_Update(play, &this->skelAnime)) {
func_808330EC(play, this, &gPlayerAnim_clink_op3_wait3, 0x9C);
func_808330EC(play, this, &gPlayerAnim_clink_op3_wait3,
ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
this->unk_850 = 1;
} else if (this->unk_850 == 0) {
func_80832924(this, D_808551BC);
@ -14358,7 +14393,8 @@ void func_80852048(PlayState* play, Player* this, CsCmdActorCue* cue) {
}
void func_80852080(PlayState* play, Player* this, CsCmdActorCue* cue) {
func_80833064(play, this, &gPlayerAnim_clink_demo_futtobi, 0x9D);
func_80833064(play, this, &gPlayerAnim_clink_demo_futtobi,
ANIM_FLAG_0 | ANIM_FLAG_PLAYER_2 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
func_80832698(this, NA_SE_VO_LI_FALL_L);
}
@ -14406,7 +14442,7 @@ void func_80852234(PlayState* play, Player* this, CsCmdActorCue* cue) {
}
void func_8085225C(PlayState* play, Player* this, CsCmdActorCue* cue) {
func_80832F54(play, this, 0x98);
func_80832F54(play, this, ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE | ANIM_FLAG_PLAYER_7);
}
void func_80852280(PlayState* play, Player* this, CsCmdActorCue* cue) {
@ -14644,7 +14680,7 @@ void func_80852B4C(PlayState* play, Player* this, CsCmdActorCue* cue, struct_808
arg3->func(play, this, cue);
}
if ((D_80858AA0 & 4) && !(this->skelAnime.moveFlags & 4)) {
if ((D_80858AA0 & ANIM_FLAG_PLAYER_2) && !(this->skelAnime.moveFlags & ANIM_FLAG_PLAYER_2)) {
this->skelAnime.morphTable[0].y /= this->ageProperties->unk_08;
D_80858AA0 = 0;
}
@ -14831,7 +14867,7 @@ void func_80853148(PlayState* play, Actor* actor) {
}
if (this->skelAnime.animation == &gPlayerAnim_link_normal_backspace) {
func_80832F54(play, this, 0x19);
func_80832F54(play, this, ANIM_FLAG_0 | ANIM_FLAG_PLAYER_SETMOVE | ANIM_FLAG_NO_MOVE);
}
func_80832224(this);

View file

@ -7,15 +7,15 @@
#include "z_eff_ss_blast.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define rPrimColorR regs[0]
#define rPrimColorG regs[1]
#define rPrimColorB regs[2]
#define rPrimColorA regs[3]
#define rEnvColorR regs[4]
#define rEnvColorG regs[5]
#define rEnvColorB regs[6]
#define rEnvColorA regs[7]
#define rAlphaTarget regs[8]
#define rInnerColorR regs[0]
#define rInnerColorG regs[1]
#define rInnerColorB regs[2]
#define rInnerColorA regs[3]
#define rOuterColorR regs[4]
#define rOuterColorG regs[5]
#define rOuterColorB regs[6]
#define rOuterColorA regs[7]
#define rAlphaStep regs[8]
#define rScale regs[9]
#define rScaleStep regs[10]
#define rScaleStepDecay regs[11]
@ -40,15 +40,15 @@ u32 EffectSsBlast_Init(PlayState* play, u32 index, EffectSs* this, void* initPar
this->life = initParams->life;
this->draw = EffectSsBlast_Draw;
this->update = EffectSsBlast_Update;
this->rPrimColorR = initParams->primColor.r;
this->rPrimColorG = initParams->primColor.g;
this->rPrimColorB = initParams->primColor.b;
this->rPrimColorA = initParams->primColor.a;
this->rEnvColorR = initParams->envColor.r;
this->rEnvColorG = initParams->envColor.g;
this->rEnvColorB = initParams->envColor.b;
this->rEnvColorA = initParams->envColor.a;
this->rAlphaTarget = initParams->primColor.a / initParams->life;
this->rInnerColorR = initParams->innerColor.r;
this->rInnerColorG = initParams->innerColor.g;
this->rInnerColorB = initParams->innerColor.b;
this->rInnerColorA = initParams->innerColor.a;
this->rOuterColorR = initParams->outerColor.r;
this->rOuterColorG = initParams->outerColor.g;
this->rOuterColorB = initParams->outerColor.b;
this->rOuterColorA = initParams->outerColor.a;
this->rAlphaStep = initParams->innerColor.a / initParams->life;
this->rScale = initParams->scale;
this->rScaleStep = initParams->scaleStep;
this->rScaleStepDecay = initParams->scaleStepDecay;
@ -59,18 +59,19 @@ void EffectSsBlast_Draw(PlayState* play, u32 index, EffectSs* this) {
GraphicsContext* gfxCtx = play->state.gfxCtx;
MtxF mf;
s32 pad;
f32 radius;
f32 scale;
OPEN_DISPS(gfxCtx, "../z_eff_ss_blast.c", 170);
radius = this->rScale * 0.0025f;
scale = this->rScale * (1 / 400.0f);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, this->rEnvColorA);
gDPSetEnvColor(POLY_XLU_DISP++, this->rOuterColorR, this->rOuterColorG, this->rOuterColorB, this->rOuterColorA);
func_800BFCB8(play, &mf, &this->pos);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, this->rPrimColorA);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rInnerColorR, this->rInnerColorG, this->rInnerColorB,
this->rInnerColorA);
Matrix_Put(&mf);
Matrix_Scale(radius, radius, radius, MTXMODE_APPLY);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_eff_ss_blast.c", 199),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, this->gfx);
@ -79,9 +80,9 @@ void EffectSsBlast_Draw(PlayState* play, u32 index, EffectSs* this) {
}
void EffectSsBlast_Update(PlayState* play, u32 index, EffectSs* this) {
Math_StepToS(&this->rPrimColorA, 0, this->rAlphaTarget);
this->rScale += this->rScaleStep;
Math_StepToS(&this->rInnerColorA, 0, this->rAlphaStep);
this->rScale += this->rScaleStep;
if (this->rScaleStep != 0) {
this->rScaleStep -= this->rScaleStepDecay;
}

View file

@ -8,8 +8,8 @@ typedef struct {
/* 0x00 */ Vec3f pos;
/* 0x0C */ Vec3f velocity;
/* 0x18 */ Vec3f accel;
/* 0x24 */ Color_RGBA8 primColor;
/* 0x28 */ Color_RGBA8 envColor;
/* 0x24 */ Color_RGBA8 innerColor;
/* 0x28 */ Color_RGBA8 outerColor;
/* 0x2C */ s16 scale;
/* 0x2E */ s16 scaleStep;
/* 0x30 */ s16 scaleStepDecay;

View file

@ -7,8 +7,10 @@
#include "z_eff_ss_bomb.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define EFFSSBOMB_LIFESPAN 20
#define rScale regs[0]
#define rTexIdx regs[1]
#define rTexIndex regs[1]
u32 EffectSsBomb_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx);
void EffectSsBomb_Draw(PlayState* play, u32 index, EffectSs* this);
@ -26,31 +28,32 @@ u32 EffectSsBomb_Init(PlayState* play, u32 index, EffectSs* this, void* initPara
Math_Vec3f_Copy(&this->velocity, &initParams->velocity);
Math_Vec3f_Copy(&this->accel, &initParams->accel);
this->gfx = SEGMENTED_TO_VIRTUAL(gEffBombExplosion1DL);
this->life = 20;
this->life = EFFSSBOMB_LIFESPAN;
this->draw = EffectSsBomb_Draw;
this->update = EffectSsBomb_Update;
this->rScale = 100;
this->rTexIdx = 0;
this->rTexIndex = 0;
return 1;
}
static void* sExplosionTextures[] = {
gEffBombExplosion1Tex,
gEffBombExplosion2Tex,
gEffBombExplosion3Tex,
gEffBombExplosion4Tex,
};
void EffectSsBomb_Draw(PlayState* play, u32 index, EffectSs* this) {
static void* explosionTextures[] = {
gEffBombExplosion1Tex,
gEffBombExplosion2Tex,
gEffBombExplosion3Tex,
gEffBombExplosion4Tex,
};
GraphicsContext* gfxCtx = play->state.gfxCtx;
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
Mtx* mtx;
s32 pad;
f32 scale;
s16 color;
s16 intensity;
if (1) {}
@ -60,8 +63,8 @@ void EffectSsBomb_Draw(PlayState* play, u32 index, EffectSs* this) {
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
@ -69,12 +72,13 @@ void EffectSsBomb_Draw(PlayState* play, u32 index, EffectSs* this) {
if (mtx != NULL) {
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(explosionTextures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sExplosionTextures[this->rTexIndex]));
gDPPipeSync(POLY_XLU_DISP++);
Gfx_SetupDL_61Xlu(gfxCtx);
color = this->life * 12.75f;
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, color, color, color, color);
intensity = this->life * ((f32)255 / EFFSSBOMB_LIFESPAN);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, intensity, intensity, intensity, intensity);
gDPPipeSync(POLY_XLU_DISP++);
//! @bug env color is not set but used in gEffBombExplosion1DL
gSPDisplayList(POLY_XLU_DISP++, this->gfx);
gDPPipeSync(POLY_XLU_DISP++);
}
@ -83,11 +87,11 @@ void EffectSsBomb_Draw(PlayState* play, u32 index, EffectSs* this) {
}
void EffectSsBomb_Update(PlayState* play, u32 index, EffectSs* this) {
if ((this->life < 21) && (this->life > 16)) {
this->rTexIdx = (20 - this->life);
if ((this->life <= EFFSSBOMB_LIFESPAN) && (this->life > (EFFSSBOMB_LIFESPAN - ARRAY_COUNT(sExplosionTextures)))) {
this->rTexIndex = (EFFSSBOMB_LIFESPAN - this->life);
} else {
this->rScale += 0;
this->rTexIdx = 3;
this->rTexIndex = ARRAY_COUNT(sExplosionTextures) - 1;
}
this->accel.x = ((Rand_ZeroOne() * 0.4f) - 0.2f);

View file

@ -8,7 +8,7 @@
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define rScale regs[0]
#define rTexIdx regs[1]
#define rTexIndex regs[1]
#define rPrimColorR regs[2]
#define rPrimColorG regs[3]
#define rPrimColorB regs[4]
@ -68,7 +68,7 @@ void EffectSsBomb2_DrawFade(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
Mtx* mtx;
s32 pad;
f32 scale;
@ -78,8 +78,8 @@ void EffectSsBomb2_DrawFade(PlayState* play, u32 index, EffectSs* this) {
scale = this->rScale * 0.01f;
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);
@ -89,7 +89,7 @@ void EffectSsBomb2_DrawFade(PlayState* play, u32 index, EffectSs* this) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB,
this->rPrimColorA);
gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, 0);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(textures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(textures[this->rTexIndex]));
gSPDisplayList(POLY_XLU_DISP++, this->gfx);
}
@ -108,7 +108,7 @@ void EffectSsBomb2_DrawLayered(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
MtxF mtx2F;
Mtx* mtx2;
Mtx* mtx;
@ -124,8 +124,8 @@ void EffectSsBomb2_DrawLayered(PlayState* play, u32 index, EffectSs* this) {
scale = this->rScale * 0.01f;
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);
@ -139,7 +139,7 @@ void EffectSsBomb2_DrawLayered(PlayState* play, u32 index, EffectSs* this) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB,
this->rPrimColorA);
gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, 0);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(textures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(textures[this->rTexIndex]));
gSPDisplayList(POLY_XLU_DISP++, gEffBombExplosion2DL);
gSPDisplayList(POLY_XLU_DISP++, gEffBombExplosion3DL);
@ -167,7 +167,7 @@ void EffectSsBomb2_DrawLayered(PlayState* play, u32 index, EffectSs* this) {
void EffectSsBomb2_Update(PlayState* play, u32 index, EffectSs* this) {
s32 divisor;
this->rTexIdx = (23 - this->life) / 3;
this->rTexIndex = (23 - this->life) / 3;
this->rScale += this->rScaleStep;
if (this->rScaleStep == 30) {
@ -178,21 +178,21 @@ void EffectSsBomb2_Update(PlayState* play, u32 index, EffectSs* this) {
if ((this->life < 23) && (this->life > 13)) {
divisor = this->life - 13;
this->rPrimColorR = func_80027DD4(this->rPrimColorR, 255, divisor);
this->rPrimColorG = func_80027DD4(this->rPrimColorG, 255, divisor);
this->rPrimColorB = func_80027DD4(this->rPrimColorB, 150, divisor);
this->rPrimColorA = func_80027DD4(this->rPrimColorA, 255, divisor);
this->rEnvColorR = func_80027DD4(this->rEnvColorR, 150, divisor);
this->rEnvColorG = func_80027DD4(this->rEnvColorG, 0, divisor);
this->rEnvColorB = func_80027DD4(this->rEnvColorB, 0, divisor);
this->rPrimColorR = EffectSs_LerpInv(this->rPrimColorR, 255, divisor);
this->rPrimColorG = EffectSs_LerpInv(this->rPrimColorG, 255, divisor);
this->rPrimColorB = EffectSs_LerpInv(this->rPrimColorB, 150, divisor);
this->rPrimColorA = EffectSs_LerpInv(this->rPrimColorA, 255, divisor);
this->rEnvColorR = EffectSs_LerpInv(this->rEnvColorR, 150, divisor);
this->rEnvColorG = EffectSs_LerpInv(this->rEnvColorG, 0, divisor);
this->rEnvColorB = EffectSs_LerpInv(this->rEnvColorB, 0, divisor);
} else if ((this->life < 14) && (this->life > -1)) {
divisor = this->life + 1;
this->rPrimColorR = func_80027DD4(this->rPrimColorR, 50, divisor);
this->rPrimColorG = func_80027DD4(this->rPrimColorG, 50, divisor);
this->rPrimColorB = func_80027DD4(this->rPrimColorB, 50, divisor);
this->rPrimColorA = func_80027DD4(this->rPrimColorA, 150, divisor);
this->rEnvColorR = func_80027DD4(this->rEnvColorR, 10, divisor);
this->rEnvColorG = func_80027DD4(this->rEnvColorG, 10, divisor);
this->rEnvColorB = func_80027DD4(this->rEnvColorB, 10, divisor);
this->rPrimColorR = EffectSs_LerpInv(this->rPrimColorR, 50, divisor);
this->rPrimColorG = EffectSs_LerpInv(this->rPrimColorG, 50, divisor);
this->rPrimColorB = EffectSs_LerpInv(this->rPrimColorB, 50, divisor);
this->rPrimColorA = EffectSs_LerpInv(this->rPrimColorA, 150, divisor);
this->rEnvColorR = EffectSs_LerpInv(this->rEnvColorR, 10, divisor);
this->rEnvColorG = EffectSs_LerpInv(this->rEnvColorG, 10, divisor);
this->rEnvColorB = EffectSs_LerpInv(this->rEnvColorB, 10, divisor);
}
}

View file

@ -8,7 +8,7 @@
#include "assets/objects/object_dodongo/object_dodongo.h"
#define rScale regs[0]
#define rTexIdx regs[1]
#define rTexIndex regs[1]
#define rPrimColorR regs[2]
#define rPrimColorG regs[3]
#define rPrimColorB regs[4]
@ -48,7 +48,7 @@ u32 EffectSsDFire_Init(PlayState* play, u32 index, EffectSs* this, void* initPar
this->rObjBankIdx = objBankIndex;
this->draw = EffectSsDFire_Draw;
this->update = EffectSsDFire_Update;
this->rTexIdx = ((s16)(play->state.frames % 4) ^ 3);
this->rTexIndex = ((s16)(play->state.frames % 4) ^ 3);
this->rPrimColorR = 255;
this->rPrimColorG = 255;
this->rPrimColorB = 50;
@ -68,7 +68,7 @@ void EffectSsDFire_Draw(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
s32 pad;
void* object;
Mtx* mtx;
@ -84,8 +84,8 @@ void EffectSsDFire_Draw(PlayState* play, u32 index, EffectSs* this) {
scale = this->rScale / 100.0f;
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);
@ -96,7 +96,7 @@ void EffectSsDFire_Draw(PlayState* play, u32 index, EffectSs* this) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB,
this->rPrimColorA);
gSegments[6] = VIRTUAL_TO_PHYSICAL(object);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sTextures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sTextures[this->rTexIndex]));
gSPDisplayList(POLY_XLU_DISP++, this->gfx);
}
}
@ -105,8 +105,8 @@ void EffectSsDFire_Draw(PlayState* play, u32 index, EffectSs* this) {
}
void EffectSsDFire_Update(PlayState* play, u32 index, EffectSs* this) {
this->rTexIdx++;
this->rTexIdx &= 3;
this->rTexIndex++;
this->rTexIndex &= 3;
this->rScale += this->rScaleStep;
if (this->rFadeDelay >= this->life) {

View file

@ -15,7 +15,7 @@
#define rEnvColorG regs[5]
#define rEnvColorB regs[6]
#define rEnvColorA regs[7]
#define rTexIdx regs[8] // this reg is also used to set specific colors in the fire update function
#define rTexIndex regs[8] // this reg is also used to set specific colors in the fire update function
#define rScale regs[9]
#define rScaleStep regs[10]
#define rDrawFlags regs[11]
@ -67,7 +67,7 @@ u32 EffectSsDust_Init(PlayState* play, u32 index, EffectSs* this, void* initPara
this->rPrimColorA = initParams->primColor.a;
this->rEnvColorA = initParams->envColor.a;
this->rTexIdx = 0;
this->rTexIndex = 0;
this->rScale = initParams->scale;
this->rScaleStep = initParams->scaleStep;
this->rLifespan = initParams->life;
@ -84,7 +84,7 @@ void EffectSsDust_Draw(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
s32 pad;
Mtx* mtx;
f32 scale;
@ -94,8 +94,8 @@ void EffectSsDust_Draw(PlayState* play, u32 index, EffectSs* this) {
scale = this->rScale * 0.0025f;
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);
@ -103,7 +103,7 @@ void EffectSsDust_Draw(PlayState* play, u32 index, EffectSs* this) {
if (mtx != NULL) {
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPPipeSync(POLY_XLU_DISP++);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTextures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(dustTextures[this->rTexIndex]));
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0);
gDPPipeSync(POLY_XLU_DISP++);
@ -134,12 +134,12 @@ void EffectSsDust_Update(PlayState* play, u32 index, EffectSs* this) {
if ((this->life <= this->rLifespan) && (this->life >= (this->rLifespan - 7))) {
if (this->rLifespan >= 5) {
this->rTexIdx = this->rLifespan - this->life;
this->rTexIndex = this->rLifespan - this->life;
} else {
this->rTexIdx = ((this->rLifespan - this->life) * (8 / this->rLifespan));
this->rTexIndex = (this->rLifespan - this->life) * (8 / this->rLifespan);
}
} else {
this->rTexIdx = 7;
this->rTexIndex = 7;
}
this->rScale += this->rScaleStep;
@ -150,7 +150,7 @@ void EffectSsDust_UpdateFire(PlayState* play, u32 index, EffectSs* this) {
this->accel.x = (Rand_ZeroOne() * 0.4f) - 0.2f;
this->accel.z = (Rand_ZeroOne() * 0.4f) - 0.2f;
switch (this->rTexIdx) {
switch (this->rTexIndex) {
case 0:
this->rPrimColorR = 255;
this->rPrimColorG = 150;
@ -181,8 +181,8 @@ void EffectSsDust_UpdateFire(PlayState* play, u32 index, EffectSs* this) {
break;
}
if (this->rTexIdx < 7) {
this->rTexIdx++;
if (this->rTexIndex < 7) {
this->rTexIndex++;
}
this->rScale += this->rScaleStep;

View file

@ -25,15 +25,16 @@ EffectSsInit Effect_Ss_Fhg_Flash_InitVars = {
EffectSsFhgFlash_Init,
};
static UNK_TYPE D_809A5178[258];
static Gfx D_809A5100[15];
// Should eventually come from assets/overlays/ovl_Effect_Ss_Fhg_Flash/ovl_Effect_Ss_Fhg_Flash.h
//! TODO: investigate having ZAPD forward declare static variables
static Gfx sShockDL[15];
u32 EffectSsFhgFlash_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx) {
EffectSsFhgFlashInitParams* initParams = (EffectSsFhgFlashInitParams*)initParamsx;
s32 pad;
s32 objBankIdx;
Vec3f zeroVec = { 0.0f, 0.0f, 0.0f };
Vec3f sp34 = { 0.0f, -1000.0f, 0.0f };
Vec3f farAwayVec = { 0.0f, -1000.0f, 0.0f };
uintptr_t oldSeg6;
if (initParams->type == FHGFLASH_LIGHTBALL) {
@ -69,17 +70,17 @@ u32 EffectSsFhgFlash_Init(PlayState* play, u32 index, EffectSs* this, void* init
this->rParam = initParams->param;
if (initParams->param != FHGFLASH_SHOCK_NO_ACTOR) {
this->pos = sp34;
this->gfx = SEGMENTED_TO_VIRTUAL(D_809A5100);
this->pos = farAwayVec; // Set the initial position to where the effect cannot be seen
this->gfx = SEGMENTED_TO_VIRTUAL(sShockDL);
} else {
this->pos = initParams->pos;
this->gfx = SEGMENTED_TO_VIRTUAL(D_809A5100);
this->gfx = SEGMENTED_TO_VIRTUAL(sShockDL);
}
}
return 1;
}
static Color_RGB8 sColors[] = {
static Color_RGB8 sLightBallColors[] = {
{ 165, 255, 61 }, { 0, 255, 255 }, { 255, 40, 0 }, { 255, 255, 0 }, { 0, 0, 255 },
{ 255, 0, 255 }, { 255, 150, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
};
@ -101,10 +102,11 @@ void EffectSsFhgFlash_DrawLightBall(PlayState* play, u32 index, EffectSs* this)
gSPSegment(POLY_XLU_DISP++, 0x06, object);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, this->rAlpha);
gDPSetEnvColor(POLY_XLU_DISP++, sColors[this->rParam].r, sColors[this->rParam].g, sColors[this->rParam].b, 0);
gDPSetEnvColor(POLY_XLU_DISP++, sLightBallColors[this->rParam].r, sLightBallColors[this->rParam].g,
sLightBallColors[this->rParam].b, 0);
gDPPipeSync(POLY_XLU_DISP++);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_RotateZ((this->rXZRot / 32768.0f) * 3.1416f, MTXMODE_APPLY);
Matrix_RotateZ((this->rXZRot / (f32)0x8000) * 3.1416f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_eff_fhg_flash.c", 326),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, this->gfx);
@ -126,7 +128,7 @@ void EffectSsFhgFlash_DrawShock(PlayState* play, u32 index, EffectSs* this) {
if (this->rParam != FHGFLASH_SHOCK_NO_ACTOR) {
Gfx_SetupDL_44Xlu(play->state.gfxCtx);
Matrix_RotateX((this->rXZRot / 32768.0f) * 1.1416f, MTXMODE_APPLY);
Matrix_RotateX((this->rXZRot / (f32)0x8000) * 1.1416f, MTXMODE_APPLY);
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_AA_ZB_XLU_DECAL2);
} else {
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
@ -137,7 +139,7 @@ void EffectSsFhgFlash_DrawShock(PlayState* play, u32 index, EffectSs* this) {
gDPPipeSync(POLY_XLU_DISP++);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, this->rAlpha);
gDPSetEnvColor(POLY_XLU_DISP++, 0, 255, 155, 0);
Matrix_RotateZ((this->rXZRot / 32768.0f) * 3.1416f, MTXMODE_APPLY);
Matrix_RotateZ((this->rXZRot / (f32)0x8000) * 3.1416f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_eff_fhg_flash.c", 395),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, this->gfx);
@ -172,10 +174,10 @@ void EffectSsFhgFlash_UpdateShock(PlayState* play, u32 index, EffectSs* this) {
s16 randBodyPart;
Player* player;
BossGanondrof* phantomGanon;
s16 rand;
s16 rotStep;
rand = (Rand_ZeroOne() * 20000.0f);
this->rXZRot = (this->rXZRot + rand) + 0x4000;
rotStep = Rand_ZeroOne() * 20000.0f;
this->rXZRot += rotStep + 0x4000;
if (this->rParam == FHGFLASH_SHOCK_PLAYER) {
player = GET_PLAYER(play);
@ -201,55 +203,4 @@ void EffectSsFhgFlash_UpdateShock(PlayState* play, u32 index, EffectSs* this) {
}
}
static Vtx D_809A50C0[4] = {
VTX(-10, -10, 0, 0, 1024, 0xFF, 0xFF, 0xFF, 0xFF),
VTX(10, -10, 0, 1024, 1024, 0xFF, 0xFF, 0xFF, 0xFF),
VTX(10, 10, 0, 1024, 0, 0xFF, 0xFF, 0xFF, 0xFF),
VTX(-10, 10, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF),
};
static Gfx D_809A5100[15] = {
gsDPPipeSync(),
gsDPSetTextureLUT(G_TT_NONE),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON),
gsDPLoadTextureBlock(D_809A5178, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_MIRROR | G_TX_WRAP,
G_TX_MIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
gsDPSetCombineLERP(PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0, 0,
COMBINED),
gsSPClearGeometryMode(G_CULL_BACK | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR),
gsSPVertex(D_809A50C0, 4, 0),
gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0),
gsSPEndDisplayList(),
};
static UNK_TYPE D_809A5178[258] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x005B3000, 0x00000000, 0x00000000,
0x00000000, 0x000B0000, 0x07000000, 0x00000000, 0x00000000, 0x005BB64B, 0x3A000000, 0x00000000, 0x00000000,
0x005B0000, 0x00000000, 0x00000000, 0x00000000, 0x001E00B6, 0xFF5B0000, 0x00000000, 0x00000000, 0x00251F0C,
0x07000000, 0x0A000000, 0x00000000, 0x00000000, 0xB6FF0000, 0x00000000, 0x00000000, 0x00255B00, 0x071F1E14,
0x0A000000, 0x00000000, 0x00000000, 0x00457350, 0x00000000, 0x00000000, 0x00295B8C, 0x5B5B0000, 0x00000000,
0x00000000, 0x00000000, 0x00455C39, 0x0F000000, 0x00000000, 0x0000A1FF, 0x5B000000, 0x00000000, 0x00000000,
0x00000000, 0x005B5B00, 0x00000000, 0x00000000, 0x005B311C, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x5BB60000, 0x00000000, 0x00000000, 0x5BB63100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFB60000,
0x00000000, 0x00000046, 0xEA310000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0072B646, 0x00000000,
0x0000B6A1, 0x81000000, 0x00000000, 0x00000000, 0x00000000, 0x000C0000, 0x00172E19, 0xBDAB5D41, 0x366BEAEA,
0x81000000, 0x00000000, 0x00000000, 0x00000000, 0x06000000, 0x00000074, 0xFFFF0500, 0x0A2342B6, 0xFF000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x005B0000, 0x03030100, 0x00FF0700, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00020503, 0x00000000, 0x00466200, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00076200, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00002962, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00003EA1, 0x62000000, 0x00000000, 0x00000000, 0x0000002E, 0xB6350000,
0x00000000, 0x00000000, 0x000000EA, 0x46000000, 0x00000000, 0x00000000, 0x00002EFF, 0xFF5A0000, 0x00000000,
0x00000000, 0x000000FF, 0xFF001700, 0x00000000, 0x00000000, 0x01015BFF, 0xA1A10000, 0x00000000, 0x00000000,
0x00030046, 0x97732100, 0x00000000, 0x00000000, 0x040CB65E, 0x4A5B4600, 0x00000000, 0x00000003, 0x0C0E8C46,
0x1C035C00, 0x00000000, 0x00000017, 0x134F5B00, 0x00000046, 0x46000000, 0x00000000, 0x34D20000, 0x0401005B,
0x00000000, 0x00000000, 0x5BB60000, 0x00000000, 0x30FCB600, 0x0000A1E7, 0x00000001, 0x0100141E, 0x5B000000,
0x00000000, 0x00000000, 0x00000000, 0x0000A1FF, 0x5B46FF00, 0x00000100, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x000000FC, 0xFFA13100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0xB6000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
};
#include "assets/overlays/ovl_Effect_Ss_Fhg_Flash/ovl_Effect_Ss_Fhg_Flash.c"

View file

@ -32,11 +32,9 @@ typedef enum {
} FhgFlashLightBallParam;
typedef enum {
/* 0x00 */ FHGFLASH_SHOCK_NO_ACTOR,
/* 0x01 */ FHGFLASH_SHOCK_PLAYER,
/* 0x02 */ FHGFLASH_SHOCK_PG
/* 0x00 */ FHGFLASH_SHOCK_NO_ACTOR, // Don't attach to any actor. Stays at a fixed position.
/* 0x01 */ FHGFLASH_SHOCK_PLAYER, // Move to a random Player body part every frame.
/* 0x02 */ FHGFLASH_SHOCK_PG // Move to a random Phantom Ganon body part every frame.
} FhgFlashLightningParam;
#endif

View file

@ -13,7 +13,7 @@
#define rEnvColorR regs[3]
#define rEnvColorG regs[4]
#define rEnvColorA regs[5]
#define rTexIdx regs[6]
#define rTexIndex regs[6]
#define rTimer regs[7]
#define rUpdateRate regs[8]
#define rDrawMode regs[9]
@ -54,7 +54,7 @@ u32 EffectSsGMagma2_Init(PlayState* play, u32 index, EffectSs* this, void* initP
this->draw = EffectSsGMagma2_Draw;
this->update = EffectSsGMagma2_Update;
this->gfx = SEGMENTED_TO_VIRTUAL(object_kingdodongo_DL_025A90);
this->rTexIdx = 0;
this->rTexIndex = 0;
this->rDrawMode = initParams->drawMode;
this->rUpdateRate = initParams->updateRate;
this->rScale = initParams->scale;
@ -97,7 +97,7 @@ void EffectSsGMagma2_Draw(PlayState* play, u32 index, EffectSs* this) {
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, 0, this->rPrimColorA);
gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, 0, this->rEnvColorA);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sTextures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sTextures[this->rTexIndex]));
gSPDisplayList(POLY_XLU_DISP++, this->gfx);
CLOSE_DISPS(gfxCtx, "../z_eff_ss_g_magma2.c", 311);
@ -108,9 +108,9 @@ void EffectSsGMagma2_Update(PlayState* play, u32 index, EffectSs* this) {
if (this->rTimer >= 10) {
this->rTimer -= 10;
this->rTexIdx++;
this->rTexIndex++;
if (this->rTexIdx >= 10) {
if (this->rTexIndex >= 10) {
this->life = 0;
}

View file

@ -15,7 +15,7 @@
#define rEnvColorG regs[5]
#define rEnvColorB regs[6]
#define rEnvColorA regs[7]
#define rTexIdx regs[8]
#define rTexIndex regs[8]
#define rScale regs[9]
#define rScaleStep regs[10]
@ -57,7 +57,7 @@ u32 EffectSsGSpk_Init(PlayState* play, u32 index, EffectSs* this, void* initPara
this->rEnvColorG = initParams->envColor.g;
this->rEnvColorB = initParams->envColor.b;
this->rEnvColorA = initParams->envColor.a;
this->rTexIdx = 0;
this->rTexIndex = 0;
this->rScale = initParams->scale;
this->rScaleStep = initParams->scaleStep;
this->actor = initParams->actor;
@ -76,7 +76,7 @@ void EffectSsGSpk_Draw(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
Mtx* mtx;
f32 scale;
s32 pad;
@ -86,14 +86,14 @@ void EffectSsGSpk_Draw(PlayState* play, u32 index, EffectSs* this) {
scale = this->rScale * 0.0025f;
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);
if (mtx != NULL) {
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sparkTextures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sparkTextures[this->rTexIndex]));
Gfx_SetupDL_60NoCDXlu(gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, 255);
gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, this->rEnvColorA);
@ -122,8 +122,8 @@ void EffectSsGSpk_Update(PlayState* play, u32 index, EffectSs* this) {
this->vec.x += this->accel.x;
this->vec.z += this->accel.z;
this->rTexIdx++;
this->rTexIdx &= 3;
this->rTexIndex++;
this->rTexIndex &= 3;
this->rScale += this->rScaleStep;
}
@ -137,7 +137,7 @@ void EffectSsGSpk_UpdateNoAccel(PlayState* play, u32 index, EffectSs* this) {
}
}
this->rTexIdx++;
this->rTexIdx &= 3;
this->rTexIndex++;
this->rTexIndex &= 3;
this->rScale += this->rScaleStep;
}

View file

@ -7,7 +7,7 @@
#include "z_eff_ss_hitmark.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define rTexIdx regs[0]
#define rTexIndex regs[0]
#define rType regs[1]
#define rPrimColorR regs[2]
#define rPrimColorG regs[3]
@ -56,7 +56,7 @@ u32 EffectSsHitMark_Init(PlayState* play, u32 index, EffectSs* this, void* initP
this->draw = EffectSsHitMark_Draw;
this->update = EffectSsHitMark_Update;
colorIdx = initParams->type * 4;
this->rTexIdx = 0;
this->rTexIndex = 0;
this->rType = initParams->type;
this->rPrimColorR = sColors[colorIdx].r;
this->rPrimColorG = sColors[colorIdx].g;
@ -74,7 +74,7 @@ void EffectSsHitMark_Draw(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfResult;
MtxF mfTrans11DA0;
MtxF mfTransBillboard;
Mtx* mtx;
f32 scale;
s32 pad;
@ -84,15 +84,15 @@ void EffectSsHitMark_Draw(PlayState* play, u32 index, EffectSs* this) {
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
scale = this->rScale / 100.0f;
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);
if (mtx != NULL) {
gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sTextures[(this->rType * 8) + (this->rTexIdx)]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sTextures[(this->rType * 8) + (this->rTexIndex)]));
Gfx_SetupDL_61Xlu(gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, 255);
gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, 0);
@ -105,18 +105,18 @@ void EffectSsHitMark_Update(PlayState* play, u32 index, EffectSs* this) {
s32 colorIdx;
if (this->rType == EFFECT_HITMARK_DUST) {
this->rTexIdx = (15 - this->life) / 2;
this->rTexIndex = (15 - this->life) / 2;
} else {
this->rTexIdx = 7 - this->life;
this->rTexIndex = 7 - this->life;
}
if (this->rTexIdx != 0) {
if (this->rTexIndex != 0) {
colorIdx = this->rType * 4 + 2;
this->rPrimColorR = func_80027DD4(this->rPrimColorR, sColors[colorIdx].r, this->life + 1);
this->rPrimColorG = func_80027DD4(this->rPrimColorG, sColors[colorIdx].g, this->life + 1);
this->rPrimColorB = func_80027DD4(this->rPrimColorB, sColors[colorIdx].b, this->life + 1);
this->rEnvColorR = func_80027DD4(this->rEnvColorR, sColors[colorIdx + 1].r, this->life + 1);
this->rEnvColorG = func_80027DD4(this->rEnvColorG, sColors[colorIdx + 1].g, this->life + 1);
this->rEnvColorB = func_80027DD4(this->rEnvColorB, sColors[colorIdx + 1].b, this->life + 1);
this->rPrimColorR = EffectSs_LerpInv(this->rPrimColorR, sColors[colorIdx].r, this->life + 1);
this->rPrimColorG = EffectSs_LerpInv(this->rPrimColorG, sColors[colorIdx].g, this->life + 1);
this->rPrimColorB = EffectSs_LerpInv(this->rPrimColorB, sColors[colorIdx].b, this->life + 1);
this->rEnvColorR = EffectSs_LerpInv(this->rEnvColorR, sColors[colorIdx + 1].r, this->life + 1);
this->rEnvColorG = EffectSs_LerpInv(this->rEnvColorG, sColors[colorIdx + 1].g, this->life + 1);
this->rEnvColorB = EffectSs_LerpInv(this->rEnvColorB, sColors[colorIdx + 1].b, this->life + 1);
}
}

View file

@ -81,8 +81,8 @@ void EffectSsKiraKira_Draw(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfRotY;
MtxF mfScale;
MtxF mfTrans11DA0;
MtxF mfTrans11DA0RotY;
MtxF mfTransBillboard;
MtxF mfTransBillboardRotY;
MtxF mfResult;
Mtx* mtx;
@ -94,9 +94,9 @@ void EffectSsKiraKira_Draw(PlayState* play, u32 index, EffectSs* this) {
SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
SkinMatrix_SetRotateZYX(&mfRotY, 0, 0, this->rYaw);
SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfRotY, &mfTrans11DA0RotY);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0RotY, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfRotY, &mfTransBillboardRotY);
SkinMatrix_MtxFMtxFMult(&mfTransBillboardRotY, &mfScale, &mfResult);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);

View file

@ -76,8 +76,8 @@ void EffectSsLightning_Draw(PlayState* play, u32 index, EffectSs* this) {
MtxF mfTrans;
MtxF mfScale;
MtxF mfRotate;
MtxF mfTrans11DA0;
MtxF mfTrans11DA0Rotate;
MtxF mfTransBillboard;
MtxF mfTransBillboardRotate;
Mtx* mtx;
f32 yScale;
s16 texIdx;
@ -96,9 +96,9 @@ void EffectSsLightning_Draw(PlayState* play, u32 index, EffectSs* this) {
xzScale = yScale * 0.6f;
SkinMatrix_SetScale(&mfScale, xzScale, yScale, xzScale);
SkinMatrix_SetRotateZYX(&mfRotate, this->vec.x, this->vec.y, this->rYaw);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTrans11DA0);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfRotate, &mfTrans11DA0Rotate);
SkinMatrix_MtxFMtxFMult(&mfTrans11DA0Rotate, &mfScale, &mfResult);
SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfRotate, &mfTransBillboardRotate);
SkinMatrix_MtxFMtxFMult(&mfTransBillboardRotate, &mfScale, &mfResult);
gSPMatrix(POLY_XLU_DISP++, &gMtxClear, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);

View file

@ -15,7 +15,7 @@
#define rEnvColorG regs[5]
#define rEnvColorB regs[6]
#define rEnvColorA regs[7]
#define rTexIdx regs[8]
#define rTexIndex regs[8]
#define rScale regs[9]
u32 EffectSsSibuki2_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx);
@ -45,7 +45,7 @@ u32 EffectSsSibuki2_Init(PlayState* play, u32 index, EffectSs* this, void* initP
this->rEnvColorG = 100;
this->rEnvColorB = 100;
this->rEnvColorA = 255;
this->rTexIdx = 0;
this->rTexIndex = 0;
return 1;
}
@ -68,14 +68,14 @@ void EffectSsSibuki2_Draw(PlayState* play, u32 index, EffectSs* this) {
Gfx_SetupDL_25Opa(gfxCtx);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, this->rPrimColorA);
gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, this->rEnvColorA);
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(bubbleTextures[this->rTexIdx]));
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(bubbleTextures[this->rTexIndex]));
gSPDisplayList(POLY_XLU_DISP++, SEGMENTED_TO_VIRTUAL(gEffUnusedBubblesDL));
CLOSE_DISPS(gfxCtx, "../z_eff_ss_sibuki2.c", 198);
}
void EffectSsSibuki2_Update(PlayState* play, u32 index, EffectSs* this) {
if (this->rTexIdx < 8) {
this->rTexIdx++;
if (this->rTexIndex < 8) {
this->rTexIndex++;
}
}

View file

@ -219,7 +219,8 @@ static void write_ld_script(FILE *fout)
// Debugging sections
fputs(
// mdebug debug sections
// mdebug sections
" .pdr : { *(.pdr) }" "\n"
" .mdebug : { *(.mdebug) }" "\n"
" .mdebug.abi32 : { *(.mdebug.abi32) }" "\n"
// DWARF debug sections
@ -249,8 +250,16 @@ static void write_ld_script(FILE *fout)
// DWARF 3
" .debug_pubtypes 0 : { *(.debug_pubtypes) }" "\n"
" .debug_ranges 0 : { *(.debug_ranges) }" "\n"
// DWARF Extension
// DWARF 5
" .debug_addr 0 : { *(.debug_addr) }" "\n"
" .debug_line_str 0 : { *(.debug_line_str) }" "\n"
" .debug_loclists 0 : { *(.debug_loclists) }" "\n"
" .debug_macro 0 : { *(.debug_macro) }" "\n"
" .debug_names 0 : { *(.debug_names) }" "\n"
" .debug_rnglists 0 : { *(.debug_rnglists) }" "\n"
" .debug_str_offsets 0 : { *(.debug_str_offsets) }" "\n"
" .debug_sup 0 : { *(.debug_sup) }\n"
// gnu attributes
" .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }" "\n", fout);
// Discard all other sections not mentioned above