New Animated Material types (#192)

* don't use playstate everywhere

* add color/textime cycle and start event system

* implement inventory events

* improvements and add time event

* add obtained flag

* move event handler to its own file

* header stuff

* implement magic level

* add getfreezetype and default texture

* add multitexture type (and improvements)

* add texture, event and surface swap

* added oscillating water (thanks kenton!) and start implementing the first freeze type

* fix drawevent

* improvements and fixes

* more improvements

* misc stuff

* little changes

* note

* removed condition type for age

* fixed cond enum names

* small fix

* initialize sceneMaterialAnimCamParams properly

* fixes related to animated materials changes

* improvements and fixes

* make sure everything is initialized !

* add color switch type
This commit is contained in:
Yanis
2025-11-26 16:01:42 +01:00
committed by GitHub
parent 52a24754ee
commit 3505a2e1ac
18 changed files with 1549 additions and 194 deletions

View File

@@ -90,9 +90,11 @@ List of every HackerOoT contributors, from most recent to oldest contribution:
- HailToDodongo
- CrashOverride95
- Trueffell
- Yanis42
- Yanis002
- kurethedead
- zelllll
- ariahiro64
- ghost
- krm01
New Animated Materials types based on [z64rom](https://github.com/z64dev/z64rom/blob/main/project/src/lib_user/library/SceneRender.c). Special thanks to Nokaubure, rankaisija, z64me and the other contributors from that project.

View File

@@ -20,7 +20,7 @@ SceneCmd example_scene_header00[] = {
SCENE_CMD_PLAYER_ENTRY_LIST(7, example_scene_header00_playerEntryList),
SCENE_CMD_CUTSCENE_DATA(gExampleCS),
#if ENABLE_ANIMATED_MATERIALS
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial),
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial, MATERIAL_CAM_PARAMS(ANIM_MAT_CAMERA_TYPE_NONE, false)),
#endif
#if ENABLE_CUTSCENE_IMPROVEMENTS
SCENE_CMD_ACTOR_CUTSCENE_LIST(2, debug1_scene_header00_ActorCutsceneList),
@@ -222,9 +222,9 @@ AnimatedMatColorParams debug1_scene_header00_AnimatedMaterialColorParams_02 = {
};
AnimatedMaterial debug1_scene_header00_AnimatedMaterial[] = {
{ 1 /* 8 */, 1, debug1_scene_header00_AnimatedMaterialTexScrollParams_00 },
{ 2 /* 9 */, 1, debug1_scene_header00_AnimatedMaterialTexScrollParams_01 },
{ -3 /* 10 */, 4, &debug1_scene_header00_AnimatedMaterialColorParams_02 }
{ MATERIAL_SEGMENT_NUM(0x08), ANIM_MAT_TYPE_TWO_TEX_SCROLL, debug1_scene_header00_AnimatedMaterialTexScrollParams_00 },
{ MATERIAL_SEGMENT_NUM(0x09), ANIM_MAT_TYPE_TWO_TEX_SCROLL, debug1_scene_header00_AnimatedMaterialTexScrollParams_01 },
{ LAST_MATERIAL_SEGMENT_NUM(0x0A), ANIM_MAT_TYPE_COLOR_NON_LINEAR_INTERP, &debug1_scene_header00_AnimatedMaterialColorParams_02 }
};
#endif
@@ -265,7 +265,7 @@ SceneCmd example_scene_header01[] = {
SCENE_CMD_SPAWN_LIST(example_scene_header01_entranceList),
SCENE_CMD_PLAYER_ENTRY_LIST(7, example_scene_header01_playerEntryList),
#if ENABLE_ANIMATED_MATERIALS
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial),
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial, MATERIAL_CAM_PARAMS(ANIM_MAT_CAMERA_TYPE_NONE, false)),
#endif
#if ENABLE_CUTSCENE_IMPROVEMENTS
SCENE_CMD_ACTOR_CUTSCENE_LIST(2, debug1_scene_header00_ActorCutsceneList),
@@ -413,7 +413,7 @@ SceneCmd example_scene_header02[] = {
SCENE_CMD_SPAWN_LIST(example_scene_header02_entranceList),
SCENE_CMD_PLAYER_ENTRY_LIST(7, example_scene_header02_playerEntryList),
#if ENABLE_ANIMATED_MATERIALS
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial),
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial, MATERIAL_CAM_PARAMS(ANIM_MAT_CAMERA_TYPE_NONE, false)),
#endif
#if ENABLE_CUTSCENE_IMPROVEMENTS
SCENE_CMD_ACTOR_CUTSCENE_LIST(2, debug1_scene_header00_ActorCutsceneList),
@@ -561,7 +561,7 @@ SceneCmd example_scene_header03[] = {
SCENE_CMD_SPAWN_LIST(example_scene_header03_entranceList),
SCENE_CMD_PLAYER_ENTRY_LIST(7, example_scene_header03_playerEntryList),
#if ENABLE_ANIMATED_MATERIALS
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial),
SCENE_CMD_ANIMATED_MATERIAL_LIST(debug1_scene_header00_AnimatedMaterial, MATERIAL_CAM_PARAMS(ANIM_MAT_CAMERA_TYPE_NONE, false)),
#endif
#if ENABLE_CUTSCENE_IMPROVEMENTS
SCENE_CMD_ACTOR_CUTSCENE_LIST(2, debug1_scene_header00_ActorCutsceneList),

View File

@@ -6,6 +6,7 @@
#include "animation.h"
#include "z_math.h"
#include "collision_check.h"
#include "animated_materials.h"
#define ACTOR_NUMBER_MAX 200
@@ -247,8 +248,8 @@ typedef struct Actor {
/* 0x130 */ ActorFunc update; // Update Routine. Called by `Actor_UpdateAll`
/* 0x134 */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw`
/* 0x138 */ struct ActorOverlay* overlayEntry; // Pointer to the overlay table entry for this actor
#if DEBUG_FEATURES
/* 0x13C */ char dbgPad[0x10];
#if ENABLE_ANIMATED_MATERIALS
/* 0x13C */ AnimatedMatContext animMatCtx;
#endif
} Actor; // size = 0x14C
@@ -284,6 +285,9 @@ typedef struct DynaPolyActor {
/* 0x15C */ u32 transformFlags;
/* 0x160 */ u8 interactFlags;
/* 0x162 */ s16 unk_162;
#if ENABLE_ANIMATED_MATERIALS
AnimatedMatPolyContext animMatPolyCtx;
#endif
} DynaPolyActor; // size = 0x164
typedef struct BodyBreak {

View File

@@ -3,86 +3,321 @@
#include "ultra64.h"
#include "config.h"
#include "command_macros_base.h"
#include "color.h"
#include "bgcheck.h"
#include "libc64/malloc.h"
#if ENABLE_ANIMATED_MATERIALS
/*
* 0000 0000 0000 1111: type (see AnimatedMatCameraType)
* 0000 0000 0001 0000: execute on event
*/
#define MATERIAL_CAM_TYPE(params) ((params) & 0x0F)
#define MATERIAL_CAM_ON_EVENT(params) (((params) >> 4) & 1)
#define MATERIAL_CAM_PARAMS(type, onEvent) ((((onEvent) & 1) << 4) | ((type) & 0x0F))
#define MATERIAL_SEGMENT_NUM(n) (n)
#define LAST_MATERIAL_SEGMENT_NUM(n) -MATERIAL_SEGMENT_NUM(n)
typedef enum AnimatedMatType {
/* 0 */ ANIM_MAT_TYPE_TEX_SCROLL,
/* 1 */ ANIM_MAT_TYPE_TWO_TEX_SCROLL,
/* 2 */ ANIM_MAT_TYPE_COLOR,
/* 3 */ ANIM_MAT_TYPE_COLOR_LERP,
/* 4 */ ANIM_MAT_TYPE_COLOR_NON_LINEAR_INTERP,
/* 5 */ ANIM_MAT_TYPE_TEX_CYCLE,
/* 6 */ ANIM_MAT_TYPE_MAX
// vanilla types
/* 0 */ ANIM_MAT_TYPE_TEX_SCROLL,
/* 1 */ ANIM_MAT_TYPE_TWO_TEX_SCROLL,
/* 2 */ ANIM_MAT_TYPE_COLOR,
/* 3 */ ANIM_MAT_TYPE_COLOR_LERP,
/* 4 */ ANIM_MAT_TYPE_COLOR_NON_LINEAR_INTERP,
/* 5 */ ANIM_MAT_TYPE_TEX_CYCLE,
/* 6 */ ANIM_MAT_TYPE_NONE,
/* 7 */ ANIM_MAT_TYPE_COLOR_CYCLE, // like TYPE_COLOR except it takes a keyframe array to set draw durations
/* 8 */ ANIM_MAT_TYPE_TEX_TIMED_CYCLE,
/* 9 */ ANIM_MAT_TYPE_TEXTURE,
/* 10 */ ANIM_MAT_TYPE_MULTITEXTURE,
/* 11 */ ANIM_MAT_TYPE_EVENT,
/* 12 */ ANIM_MAT_TYPE_SURFACE_SWAP,
/* 13 */ ANIM_MAT_TYPE_OSCILLATING_TWO_TEX,
/* 14 */ ANIM_MAT_TYPE_COLOR_SWITCH, // like TYPE_TEXTURE except it's for colors
/* 15 */ ANIM_MAT_TYPE_MAX
} AnimatedMatType;
typedef struct {
/* 0x0 */ u8 r;
/* 0x1 */ u8 g;
/* 0x2 */ u8 b;
/* 0x3 */ u8 a;
/* 0x4 */ u8 lodFrac;
} F3DPrimColor; // size = 0x5
typedef enum AnimatedMatCameraType {
ANIM_MAT_CAMERA_TYPE_NONE,
ANIM_MAT_CAMERA_TYPE_SHAKE, // collapse-like screen
ANIM_MAT_CAMERA_TYPE_DISTORTION, // jabu-like screen
ANIM_MAT_CAMERA_TYPE_MAX,
} AnimatedMatCameraType;
typedef struct {
/* 0x0 */ u8 r;
/* 0x1 */ u8 g;
/* 0x2 */ u8 b;
/* 0x3 */ u8 a;
} F3DEnvColor; // size = 0x4
/* 0x00 */ u8 r;
/* 0x01 */ u8 g;
/* 0x02 */ u8 b;
/* 0x03 */ u8 a;
/* 0x04 */ u8 lodFrac;
} F3DPrimColor; // size = 0x05
typedef struct {
/* 0x0 */ u16 keyFrameLength;
/* 0x2 */ u16 keyFrameCount;
/* 0x4 */ F3DPrimColor* primColors;
/* 0x8 */ F3DEnvColor* envColors;
/* 0xC */ u16* keyFrames;
/* 0x00 */ u8 r;
/* 0x01 */ u8 g;
/* 0x02 */ u8 b;
/* 0x03 */ u8 a;
} F3DEnvColor; // size = 0x04
typedef struct {
/* 0x00 */ u16 keyFrameLength;
/* 0x02 */ u16 keyFrameCount;
/* 0x04 */ F3DPrimColor* primColors;
/* 0x08 */ F3DEnvColor* envColors;
/* 0x0C */ u16* keyFrames;
} AnimatedMatColorParams; // size = 0x10
typedef struct {
/* 0x0 */ s8 xStep;
/* 0x1 */ s8 yStep;
/* 0x2 */ u8 width;
/* 0x3 */ u8 height;
} AnimatedMatTexScrollParams; // size = 0x4
/* 0x00 */ s8 xStep;
/* 0x01 */ s8 yStep;
/* 0x02 */ u8 width;
/* 0x03 */ u8 height;
} AnimatedMatTexScrollParams; // size = 0x04
typedef struct {
/* 0x0 */ u16 keyFrameLength;
/* 0x4 */ TexturePtr* textureList;
/* 0x8 */ u8* textureIndexList;
} AnimatedMatTexCycleParams; // size = 0xC
/* 0x00 */ u16 keyFrameLength;
/* 0x04 */ TexturePtr* textureList;
/* 0x08 */ u8* textureIndexList;
} AnimatedMatTexCycleParams; // size = 0x0C
typedef struct {
/* 0x0 */ s8 segment;
/* 0x2 */ AnimatedMatType type;
/* 0x4 */ void* params;
} AnimatedMaterial; // size = 0x8
typedef struct AnimatedMatTexTimedCycleKeyframe {
TexturePtr texture; // texture to draw
u16 displayTime; // how long it lasts before going on the next one
} AnimatedMatTexTimedCycleKeyframe;
typedef struct AnimatedMatTexTimedCycleParams {
u16 keyframeLength; // how many keyframes
AnimatedMatTexTimedCycleKeyframe* keyframeList; // array of keyframes
} AnimatedMatTexTimedCycleParams;
typedef struct AnimatedMatTextureParams {
TexturePtr textures[2];
} AnimatedMatTextureParams;
typedef struct AnimatedMatColorSwitchParams {
F3DPrimColor primColors[2];
F3DEnvColor envColors[2];
u8 useEnvColor[2];
} AnimatedMatColorSwitchParams;
typedef struct AnimatedMatMultiTextureParams {
s16 minPrimAlpha; // minimum opacity of both textures
s16 maxPrimAlpha; // maximum opacity of both textures
s16 minEnvAlpha; // minimum opacity of texture2
s16 maxEnvAlpha; // maximum opacity of texture2
u8 speed; // transition/blending speed
TexturePtr texture1; // optional, texture reference (can be NULL)
TexturePtr texture2; // optional, texture reference (can be NULL)
u8 segment1; // optional, segment number of the texture reference for texture1
u8 segment2; // optional, segment number of the texture reference for texture2
} AnimatedMatMultiTextureParams;
// note: the new settings will apply to all tris from the list!
typedef struct AnimatedMatSurfaceSwapParams {
SurfaceType surface; // the new surface settings
s16 surfaceType; // surface type index to change
u16 flags_vIA; // new poly flags to apply
u16 flags_vIB; // new poly flags to apply
AnimatedMatMultiTextureParams* textureParams; // required for a texture blend transition
u16 triIndices[]; // index list of the triangles to edit, -1 means the list is over
} AnimatedMatSurfaceSwapParams;
struct GameState;
struct PlayState;
struct EventScriptEntry;
Gfx* AnimatedMat_TexScroll(struct PlayState* play, AnimatedMatTexScrollParams* params);
void AnimatedMat_DrawTexScroll(struct PlayState* play, s32 segment, void* params);
Gfx* AnimatedMat_TwoLayerTexScroll(struct PlayState* play, AnimatedMatTexScrollParams* params);
void AnimatedMat_DrawTwoTexScroll(struct PlayState* play, s32 segment, void* params);
void AnimatedMat_SetColor(struct PlayState* play, s32 segment, F3DPrimColor* primColorResult, F3DEnvColor* envColor);
void AnimatedMat_DrawColor(struct PlayState* play, s32 segment, void* params);
s32 AnimatedMat_Lerp(s32 min, s32 max, f32 norm);
void AnimatedMat_DrawColorLerp(struct PlayState* play, s32 segment, void* params);
void AnimatedMat_DrawColorNonLinearInterp(struct PlayState* play, s32 segment, void* params);
void AnimatedMat_DrawTexCycle(struct PlayState* play, s32 segment, void* params);
void AnimatedMat_DrawMain(struct PlayState* play, AnimatedMaterial* matAnim, f32 alphaRatio, u32 step, u32 flags);
void AnimatedMat_Draw(struct PlayState* play, AnimatedMaterial* matAnim);
void AnimatedMat_DrawOpa(struct PlayState* play, AnimatedMaterial* matAnim);
void AnimatedMat_DrawXlu(struct PlayState* play, AnimatedMaterial* matAnim);
void AnimatedMat_DrawAlpha(struct PlayState* play, AnimatedMaterial* matAnim, f32 alphaRatio);
void AnimatedMat_DrawAlphaOpa(struct PlayState* play, AnimatedMaterial* matAnim, f32 alphaRatio);
void AnimatedMat_DrawAlphaXlu(struct PlayState* play, AnimatedMaterial* matAnim, f32 alphaRatio);
void AnimatedMat_DrawStep(struct PlayState* play, AnimatedMaterial* matAnim, u32 step);
void AnimatedMat_DrawStepOpa(struct PlayState* play, AnimatedMaterial* matAnim, u32 step);
void AnimatedMat_DrawStepXlu(struct PlayState* play, AnimatedMaterial* matAnim, u32 step);
void AnimatedMat_DrawAlphaStep(struct PlayState* play, AnimatedMaterial* matAnim, f32 alphaRatio, u32 step);
void AnimatedMat_DrawAlphaStepOpa(struct PlayState* play, AnimatedMaterial* matAnim, f32 alphaRatio, u32 step);
void AnimatedMat_DrawAlphaStepXlu(struct PlayState* play, AnimatedMaterial* matAnim, f32 alphaRatio, u32 step);
typedef struct AnimatedMaterial {
/* 0x00 */ s8 segment;
/* 0x02 */ AnimatedMatType type;
/* 0x04 */ void* params;
/* 0x08 */ struct EventScriptEntry* eventEntry; // optional
} AnimatedMaterial;
// we need a way to revert back to the original state
// but since we're editing the scene data directly we need to allocate and populate a backup list
typedef struct CollisionPolyBackup {
SurfaceType surfaceType;
u16 flags_vIA;
u16 flags_vIB;
} CollisionPolyBackup;
// doing it this way to save space, holds runtime informations for each running type
typedef struct AnimatedMatState {
u8 prevAllowDraw;
u8 actionType;
union {
struct {
s32 step;
};
struct {
s32 curFrame;
u8 timer;
};
struct {
u8 firstTime;
s16 primAlpha;
s16 envAlpha;
};
s32 _words[2];
};
} AnimatedMatState;
typedef struct AnimatedMatPolyContext {
CollisionPolyBackup* polyBackupList;
s16 triCount;
} AnimatedMatPolyContext;
typedef struct AnimatedMatContext {
AnimatedMatState* stateList;
} AnimatedMatContext;
void AnimatedMat_InitSurfaceSwap(struct GameState* gameState, AnimatedMatPolyContext* animMatPolyCtx, void* params);
void AnimatedMat_Init(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim);
void AnimatedMat_DrawMain(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim, f32 alphaRatio, u32 step,
u32 flags);
void AnimatedMat_Draw(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, u32 gameplayFrames, AnimatedMaterial* matAnim);
void AnimatedMat_DrawOpa(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, u32 gameplayFrames, AnimatedMaterial* matAnim);
void AnimatedMat_DrawXlu(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, u32 gameplayFrames, AnimatedMaterial* matAnim);
void AnimatedMat_DrawAlpha(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, u32 gameplayFrames, AnimatedMaterial* matAnim,
f32 alphaRatio);
void AnimatedMat_DrawAlphaOpa(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, u32 gameplayFrames, AnimatedMaterial* matAnim,
f32 alphaRatio);
void AnimatedMat_DrawAlphaXlu(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, u32 gameplayFrames, AnimatedMaterial* matAnim,
f32 alphaRatio);
void AnimatedMat_DrawStep(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim, u32 step);
void AnimatedMat_DrawStepOpa(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim, u32 step);
void AnimatedMat_DrawStepXlu(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim, u32 step);
void AnimatedMat_DrawAlphaStep(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim, f32 alphaRatio,
u32 step);
void AnimatedMat_DrawAlphaStepOpa(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim, f32 alphaRatio,
u32 step);
void AnimatedMat_DrawAlphaStepXlu(struct GameState* gameState, AnimatedMatContext* animMatCtx,
AnimatedMatPolyContext* animMatPolyCtx, AnimatedMaterial* matAnim, f32 alphaRatio,
u32 step);
// macros for convenience
#define ActorAnimatedMat_Init(this, play, ptr) AnimatedMat_Init(&(play)->state, &(this)->actor.animMatCtx, NULL, (ptr))
#define ActorAnimatedMat_Draw(this, play, ptr) \
AnimatedMat_Draw(&(play)->state, &(this)->actor.animMatCtx, NULL, (play)->gameplayFrames, (ptr))
#define ActorAnimatedMat_DrawOpa(this, play, ptr) \
AnimatedMat_DrawOpa(&(play)->state, &(this)->actor.animMatCtx, NULL, (play)->gameplayFrames, (ptr))
#define ActorAnimatedMat_DrawXlu(this, play, ptr) \
AnimatedMat_DrawXlu(&(play)->state, &(this)->actor.animMatCtx, NULL, (play)->gameplayFrames, (ptr))
#define ActorAnimatedMat_DrawAlpha(this, play, ptr) \
AnimatedMat_DrawAlpha(&(play)->state, &(this)->actor.animMatCtx, NULL, (play)->gameplayFrames, (ptr))
#define ActorAnimatedMat_DrawAlphaOpa(this, play, ptr) \
AnimatedMat_DrawAlphaOpa(&(play)->state, &(this)->actor.animMatCtx, NULL, (play)->gameplayFrames, (ptr))
#define ActorAnimatedMat_DrawAlphaXlu(this, play, ptr) \
AnimatedMat_DrawAlphaXlu(&(play)->state, &(this)->actor.animMatCtx, NULL, (play)->gameplayFrames, (ptr))
#define ActorAnimatedMat_DrawStep(this, play, ptr, step) \
AnimatedMat_DrawStep(&(play)->state, &(this)->actor.animMatCtx, NULL, (ptr), (step))
#define ActorAnimatedMat_DrawStepOpa(this, play, ptr, step) \
AnimatedMat_DrawStepOpa(&(play)->state, &(this)->actor.animMatCtx, NULL, (ptr), (step))
#define ActorAnimatedMat_DrawStepXlu(this, play, ptr, step) \
AnimatedMat_DrawStepXlu(&(play)->state, &(this)->actor.animMatCtx, NULL, (ptr), (step))
#define ActorAnimatedMat_DrawAlphaStep(this, play, ptr, alphaRatio, step) \
AnimatedMat_DrawAlphaStep(&(play)->state, &(this)->actor.animMatCtx, NULL, (ptr), (alphaRatio), (step))
#define ActorAnimatedMat_DrawAlphaStepOpa(this, play, ptr, alphaRatio, step) \
AnimatedMat_DrawAlphaStepOpa(&(play)->state, &(this)->actor.animMatCtx, NULL, (ptr), (alphaRatio), (step))
#define ActorAnimatedMat_DrawAlphaStepXlu(this, play, ptr, alphaRatio, step) \
AnimatedMat_DrawAlphaStepXlu(&(play)->state, &(this)->actor.animMatCtx, NULL, (ptr), (alphaRatio), (step))
#define ActorAnimatedMat_Destroy(this) \
{ \
if (this->actor.animMatCtx.stateList != NULL) { \
SYSTEM_ARENA_FREE(this->actor.animMatCtx.stateList); \
} \
}
#define DynaActorAnimatedMat_Init(this, play, ptr) \
AnimatedMat_Init(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (ptr))
#define DynaActorAnimatedMat_Draw(this, play, ptr) \
AnimatedMat_Draw(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (play)->gameplayFrames, \
(ptr))
#define DynaActorAnimatedMat_DrawOpa(this, play, ptr) \
AnimatedMat_DrawOpa(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, \
(play)->gameplayFrames, (ptr))
#define DynaActorAnimatedMat_DrawXlu(this, play, ptr) \
AnimatedMat_DrawXlu(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, \
(play)->gameplayFrames, (ptr))
#define DynaActorAnimatedMat_DrawAlpha(this, play, ptr) \
AnimatedMat_DrawAlpha(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, \
(play)->gameplayFrames, (ptr))
#define DynaActorAnimatedMat_DrawAlphaOpa(this, play, ptr) \
AnimatedMat_DrawAlphaOpa(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, \
(play)->gameplayFrames, (ptr))
#define DynaActorAnimatedMat_DrawAlphaXlu(this, play, ptr) \
AnimatedMat_DrawAlphaXlu(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, \
(play)->gameplayFrames, (ptr))
#define DynaActorAnimatedMat_DrawStep(this, play, ptr, step) \
AnimatedMat_DrawStep(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (ptr), (step))
#define DynaActorAnimatedMat_DrawStepOpa(this, play, ptr, step) \
AnimatedMat_DrawStepOpa(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (ptr), (step))
#define DynaActorAnimatedMat_DrawStepXlu(this, play, ptr, step) \
AnimatedMat_DrawStepXlu(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (ptr), (step))
#define DynaActorAnimatedMat_DrawAlphaStep(this, play, ptr, alphaRatio, step) \
AnimatedMat_DrawAlphaStep(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (ptr), \
(alphaRatio), (step))
#define DynaActorAnimatedMat_DrawAlphaStepOpa(this, play, ptr, alphaRatio, step) \
AnimatedMat_DrawAlphaStepOpa(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (ptr), \
(alphaRatio), (step))
#define DynaActorAnimatedMat_DrawAlphaStepXlu(this, play, ptr, alphaRatio, step) \
AnimatedMat_DrawAlphaStepXlu(&(play)->state, &(this)->actor.animMatCtx, &(this)->dyna.animMatPolyCtx, (ptr), \
(alphaRatio), (step))
#define DynaActorAnimatedMat_Destroy(this) \
{ \
if (this->dyna.actor.animMatCtx.stateList != NULL) { \
SYSTEM_ARENA_FREE(this->dyna.actor.animMatCtx.stateList); \
} \
\
if (this->dyna.animMatPolyCtx.polyBackupList != NULL) { \
SYSTEM_ARENA_FREE(this->dyna.animMatPolyCtx.polyBackupList); \
} \
}
#endif

252
include/event_manager.h Normal file
View File

@@ -0,0 +1,252 @@
#ifndef EVENT_MANAGER_H
#define EVENT_MANAGER_H
#include "ultra64.h"
#include "config.h"
#include "command_macros_base.h"
typedef enum EventCondition {
EVENT_COND_NONE,
EVENT_COND_EQUAL, // b == a
EVENT_COND_DIFF, // b != a
EVENT_COND_INFERIOR, // b < a
EVENT_COND_SUPERIOR, // b > a
EVENT_COND_INFERIOR_EQ, // b <= a
EVENT_COND_SUPERIOR_EQ, // b >= a
} EventCondition;
typedef enum EventFlagType {
EVENT_FLAG_TYPE_SWITCH_FLAG,
EVENT_FLAG_TYPE_EVENTCHKINF_FLAG,
EVENT_FLAG_TYPE_INF_FLAG,
EVENT_FLAG_TYPE_COLLECTIBLE_FLAG,
EVENT_FLAG_TYPE_TREASURE_FLAG,
EVENT_FLAG_TYPE_TEMPCLEAR_FLAG,
EVENT_FLAG_TYPE_CLEAR_FLAG,
EVENT_FLAG_TYPE_MAX,
} EventFlagType;
typedef enum EventInvType {
EVENT_INV_TYPE_ITEMS,
EVENT_INV_TYPE_EQUIPMENT,
EVENT_INV_TYPE_QUEST,
EVENT_INV_TYPE_DUNGEON_ITEMS,
EVENT_INV_TYPE_DUNGEON_KEYS,
EVENT_INV_TYPE_GS_TOKENS,
EVENT_INV_TYPE_MAX,
} EventInvType;
typedef enum EventGameType {
EVENT_GAME_TYPE_AGE,
EVENT_GAME_TYPE_HEALTH,
EVENT_GAME_TYPE_RUPEES,
EVENT_GAME_TYPE_MAGIC,
EVENT_GAME_TYPE_INVENTORY,
EVENT_GAME_TYPE_MAX,
} EventGameType;
typedef enum EventTimeType {
EVENT_TIME_TYPE_CLOCK,
EVENT_TIME_TYPE_CONDITIONAL,
EVENT_TIME_TYPE_DAY,
EVENT_TIME_TYPE_NIGHT,
EVENT_TIME_TYPE_MAX,
} EventTimeType;
// only used by the system using this
//! TODO: add a type that can let a draw to complete its loop before freezing
typedef enum EventActionType {
EVENT_ACTION_TYPE_NONE, // no special behavior
EVENT_ACTION_TYPE_INVERTED, // inverts the event behavior
EVENT_ACTION_TYPE_INVERTED_KEEP, // same as above but allows to continue to draw the last state
} EventActionType;
typedef enum EventType {
EVENT_TYPE_NONE,
EVENT_TYPE_FLAG,
EVENT_TYPE_GAME,
EVENT_TYPE_TIME,
EVENT_TYPE_MAX,
} EventType;
typedef union EventData {
s32 i;
f32 f;
s16 s[2];
s8 b[4];
} EventData;
typedef union EventFlag {
struct {
u32 type; // see EventFlagType
u32 flag;
};
s32 _words[2];
} EventFlag;
typedef union EventGame {
struct {
u8 type; // see EventGameType
u8 condType; // see EventCondition
union {
// EVENT_GAME_TYPE_AGE
s8 age;
// EVENT_GAME_TYPE_HEALTH
s16 health;
// EVENT_GAME_TYPE_RUPEES
s16 rupees;
// EVENT_GAME_TYPE_MAGIC
s8 magic;
// EVENT_GAME_TYPE_INVENTORY
struct {
u8 type; // see EventInvType
union {
u8 itemId;
u8 upgradeType;
u8 unused;
u8 sceneId;
u8 questItem;
};
union {
// EVENT_INV_TYPE_ITEMS and EVENT_INV_TYPE_DUNGEON_KEYS
struct {
u8 obtained;
union {
s8 amount; // EVENT_INV_TYPE_ITEMS: -1 means no ammo check
// EVENT_INV_TYPE_EQUIPMENT
u8 swordHealth; // -1 means no sword health check
u8 upgradeValue;
};
};
// EVENT_INV_TYPE_DUNGEON_ITEMS
// EVENT_INV_TYPE_GS_TOKENS
s16 gsTokens;
};
} inventory;
};
};
s32 _words[2];
} EventGame;
typedef union EventTime {
struct {
u8 type; // see EventTimeType
u8 isClock; // set to true to check for a specific time range
union {
u8 isRange;
u8 nightFlag; // 0 for day, 1 for night
};
struct {
u8 condType;
u8 hour;
u8 minute;
} clocks[2];
};
s32 _words[3];
} EventTime;
typedef struct EventScriptEntry {
EventData* script; // list of events to process, must be the same size as keyframeList
u8 actionType; // see EventActionType
} EventScriptEntry;
struct GameState;
u8 EventManager_GetFreezeType(void);
u8 EventManager_ProcessScript(struct GameState* gameState, EventScriptEntry* eventEntry);
// useful macros to declare an event entry
// generic flag macro
#define EVENT_FLAG(type, flag) EVENT_TYPE_FLAG, CMD_W((type)), CMD_W((flag))
// specific flag macros
#define EVENT_SWITCH_FLAG(flag) EVENT_FLAG(EVENT_FLAG_TYPE_SWITCH_FLAG, (flag))
#define EVENT_EVENTCHKINF_FLAG(flag) EVENT_FLAG(EVENT_FLAG_TYPE_EVENTCHKINF_FLAG, (flag))
#define EVENT_INF_FLAG(flag) EVENT_FLAG(EVENT_FLAG_TYPE_INF_FLAG, (flag))
#define EVENT_COLLECTIBLE_FLAG(flag) EVENT_FLAG(EVENT_FLAG_TYPE_COLLECTIBLE_FLAG, (flag))
#define EVENT_TREASURE_FLAG(flag) EVENT_FLAG(EVENT_FLAG_TYPE_TREASURE_FLAG, (flag))
#define EVENT_TEMPCLEAR_FLAG(flag) EVENT_FLAG(EVENT_FLAG_TYPE_TEMPCLEAR_FLAG, (flag))
#define EVENT_CLEAR_FLAG(flag) EVENT_FLAG(EVENT_FLAG_TYPE_CLEAR_FLAG, (flag))
// age macro
#define EVENT_AGE(age) EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_AGE, 0, (age), 0), CMD_W(0)
// health macro
#define EVENT_HEALTH(condType, amount) \
EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_HEALTH, (condType), 0, (amount)), CMD_W(0)
// rupees macro
#define EVENT_RUPEES(condType, amount) \
EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_RUPEES, (condType), 0, (amount)), CMD_W(0)
// magic macro
#define EVENT_MAGIC(condType, amount) \
EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_MAGIC, (condType), 0, (amount)), CMD_W(0)
// generic item macro
#define EVENT_ITEM_BASE(condType, itemId, obtained, amount) \
EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_INVENTORY, (condType), EVENT_INV_TYPE_ITEMS, (itemId)), \
CMD_BBH((obtained), (amount), 0)
// item macro (either the player has the item or not)
#define EVENT_ITEM(itemId, obtained) EVENT_ITEM_BASE(EVENT_COND_NONE, itemId, obtained, -1)
// ammo macro (same as above but also check the amount)
#define EVENT_ITEM_AMMO(condType, itemId, amount) EVENT_ITEM_BASE(condType, itemId, true, amount)
// generic equipment macro
#define EVENT_EQUIPMENT_BASE(condType, itemIdOrUpgradeType, obtained, healthOrUpgrade) \
EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_INVENTORY, (condType), EVENT_INV_TYPE_EQUIPMENT, (itemIdOrUpgradeType)), \
CMD_BBH((obtained), (healthOrUpgrade), 0)
// equipment macro (either the player has the equipment or not)
#define EVENT_EQUIPMENT(itemId, obtained) EVENT_EQUIPMENT_BASE(EVENT_COND_NONE, itemId, obtained, -1)
// biggoron sword macro (same as above but also check the sword's health)
#define EVENT_EQUIPMENT_BGS(condType, swordHealth) \
EVENT_EQUIPMENT_BASE(condType, ITEM_SWORD_BIGGORON, true, swordHealth)
// upgrade macro
#define EVENT_EQUIPMENT_UPG(condType, upgradeType, upgradeValue) \
EVENT_EQUIPMENT_BASE(condType, upgradeType, true, upgradeValue)
// quest items
#define EVENT_QUEST_ITEM(questItem, obtained) \
EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_INVENTORY, EVENT_COND_NONE, EVENT_INV_TYPE_QUEST, (questItem)), \
CMD_BBH((obtained), 0, 0)
// skulltula tokens
#define EVENT_GS_TOKEN(condType, gsTokens) \
EVENT_TYPE_GAME, CMD_BBBB(EVENT_GAME_TYPE_INVENTORY, (condType), EVENT_INV_TYPE_GS_TOKENS, 0), CMD_HH((gsTokens), 0)
// generic time macro
#define EVENT_TIME(type, isClock, isRangeOrNightFlag, condType1, hour1, minute1, condType2, hour2, minute2) \
EVENT_TYPE_TIME, CMD_BBBB((type), (isClock), (isRangeOrNightFlag), (condType1)), \
CMD_BBBB((hour1), (minute1), (condType2), (hour2)), CMD_BBH((minute2), 0, 0)
// specific time of day
#define EVENT_TIME_CLOCK(condType, hour, minute) \
EVENT_TIME(EVENT_TIME_TYPE_CLOCK, true, false, condType, hour, minute, 0, 0, 0)
// conditional clock (for example: time1 != CLOCK_TIME(10, 0) && time2 < CLOCK_TIME(15, 0)
#define EVENT_TIME_CONDITIONAL(condType1, hour1, minute1, condType2, hour2, minute2) \
EVENT_TIME(EVENT_TIME_TYPE_CONDITIONAL, true, true, condType1, hour1, minute1, condType2, hour2, minute2)
// check if this is currently daytime
#define EVENT_TIME_DAY() EVENT_TIME(EVENT_TIME_TYPE_DAY, false, 0, 0, 0, 0, 0, 0, 0)
// checks if the this is currently nighttime
#define EVENT_TIME_NIGHT() EVENT_TIME(EVENT_TIME_TYPE_NIGHT, false, 1, 0, 0, 0, 0, 0, 0)
// the process will end whenever this is the next type (or if an unknown type is found)
#define EVENT_END() EVENT_TYPE_NONE
#endif

View File

@@ -133,6 +133,7 @@ void Graph_ThreadEntry(void*);
extern u64 gMojiFontTLUTs[4][4]; // original name: "moji_tlut"
extern u64 gMojiFontTex[]; // original name: "font_ff"
extern Gfx* gPrevTaskWorkBuffer;
/**
* `x` vertex x

View File

@@ -129,6 +129,9 @@ typedef struct PlayState {
/* 0x1242C */ SceneTableEntry* loadedScene;
#if ENABLE_ANIMATED_MATERIALS
AnimatedMaterial* sceneMaterialAnims;
AnimatedMatContext sceneAnimMatCtx;
AnimatedMatPolyContext sceneAnimMatPolyCtx;
u16 sceneMaterialAnimCamParams;
#endif
#if ENABLE_CUTSCENE_IMPROVEMENTS
ActorCsCamInfo* actorCsCamList;

View File

@@ -236,9 +236,9 @@ typedef struct SCmdOccPlaneCandList {
#endif
#if ENABLE_ANIMATED_MATERIALS
typedef struct {
typedef struct SCmdTextureAnimations {
/* 0x0 */ u8 code;
/* 0x1 */ u8 data1;
/* 0x2 */ u8 camParams;
/* 0x4 */ void* segment;
} SCmdTextureAnimations; // size = 0x8
#endif
@@ -603,8 +603,8 @@ typedef enum SceneCommandTypeID {
#endif
#if ENABLE_ANIMATED_MATERIALS
#define SCENE_CMD_ANIMATED_MATERIAL_LIST(matAnimList) \
{ SCENE_CMD_ID_ANIMATED_MATERIAL_LIST, 0, CMD_PTR(matAnimList) }
#define SCENE_CMD_ANIMATED_MATERIAL_LIST(matAnimList, camParams) \
{ SCENE_CMD_ID_ANIMATED_MATERIAL_LIST, camParams, CMD_PTR(matAnimList) }
#endif
#if ENABLE_CUTSCENE_IMPROVEMENTS

View File

@@ -64,8 +64,8 @@ Mtx* Matrix_Finalize(struct GraphicsContext* gfxCtx);
#endif
#define MATRIX_FINALIZE_AND_LOAD(pkt, gfxCtx, file, line) \
gSPMatrix(pkt, MATRIX_FINALIZE(gfxCtx, file, line), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW)
#define MATRIX_FINALIZE_AND_LOAD(pkt, gfxCtx, ...) \
gSPMatrix(pkt, MATRIX_FINALIZE(gfxCtx, __FILE__, __LINE__), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW)
/* Vector operations */

View File

@@ -835,6 +835,7 @@ beginseg
include "$(BUILD_DIR)/src/code/rainbow.o"
include "$(BUILD_DIR)/src/code/helpers.o"
include "$(BUILD_DIR)/src/code/event_manager.o"
#if ENABLE_ANIMATED_MATERIALS
include "$(BUILD_DIR)/src/code/animated_materials.o"
#endif

File diff suppressed because it is too large Load Diff

275
src/code/event_manager.c Normal file
View File

@@ -0,0 +1,275 @@
#include "segmented_address.h"
#include "play_state.h"
#include "printf.h"
#include "save.h"
#include "array_count.h"
#include "event_manager.h"
#define STRINGIFY(s) #s
#define EXPAND_AND_STRINGIFY(s) STRINGIFY(s)
#define log(...) PRINTF("Line " EXPAND_AND_STRINGIFY(__LINE__) " - " __VA_ARGS__);
static u8 EventManager_UnsignedCondition(u8 condType, u32 a, u32 b);
static u8 EventManager_SignedCondition(u8 condType, s32 a, s32 b);
static void EventManager_ProcessFlag(GameState* gameState, EventFlag* event, u8* pabFlags);
static void EventManager_ProcessGame(GameState* gameState, EventGame* event, u8* pabGame);
static void EventManager_ProcessTime(GameState* gameState, EventTime* event, u8* pabTime);
static u8 EventManager_Validate(u8* pabType, u8 length);
static u8 sEventActionType = EVENT_ACTION_TYPE_NONE;
// probably dumb
#define EventManager_ConditionImpl(condType, a, b) \
{ \
switch ((condType)) { \
case EVENT_COND_EQUAL: \
return (b) == (a); \
case EVENT_COND_DIFF: \
return (b) != (a); \
case EVENT_COND_INFERIOR: \
return (b) < (a); \
case EVENT_COND_SUPERIOR: \
return (b) > (a); \
case EVENT_COND_INFERIOR_EQ: \
return (b) <= (a); \
case EVENT_COND_SUPERIOR_EQ: \
return (b) >= (a); \
default: \
break; \
} \
}
// most likely unnecessary but to make sure it's fine
static u8 EventManager_UnsignedCondition(u8 condType, u32 a, u32 b) {
EventManager_ConditionImpl(condType, a, b);
return true;
}
static u8 EventManager_SignedCondition(u8 condType, s32 a, s32 b) {
EventManager_ConditionImpl(condType, a, b);
return true;
}
// performs the necessary checks to handle flag events
static void EventManager_ProcessFlag(GameState* gameState, EventFlag* event, u8* pabFlags) {
PlayState* play = (PlayState*)gameState;
u8 allowDraw = true;
// make sure this is the play state
if (gSaveContext.gameMode == GAMEMODE_NORMAL) {
switch (event->type) {
case EVENT_FLAG_TYPE_SWITCH_FLAG:
allowDraw = Flags_GetSwitch(play, event->flag) != 0;
break;
case EVENT_FLAG_TYPE_EVENTCHKINF_FLAG:
allowDraw = Flags_GetEventChkInf(event->flag) != 0;
break;
case EVENT_FLAG_TYPE_INF_FLAG:
allowDraw = Flags_GetInfTable(event->flag) != 0;
break;
case EVENT_FLAG_TYPE_COLLECTIBLE_FLAG:
allowDraw = Flags_GetCollectible(play, event->flag) != 0;
break;
case EVENT_FLAG_TYPE_TREASURE_FLAG:
allowDraw = Flags_GetTreasure(play, event->flag) != 0;
break;
case EVENT_FLAG_TYPE_TEMPCLEAR_FLAG:
allowDraw = Flags_GetTempClear(play, event->flag) != 0;
break;
case EVENT_FLAG_TYPE_CLEAR_FLAG:
allowDraw = Flags_GetClear(play, event->flag) != 0;
break;
default:
break;
}
}
pabFlags[event->type] = allowDraw;
}
// performs the necessary checks to handle game events
static void EventManager_ProcessGame(GameState* gameState, EventGame* event, u8* pabGame) {
u8 allowDraw = true;
u8 value;
switch (event->type) {
case EVENT_GAME_TYPE_AGE:
allowDraw = event->age == gSaveContext.save.linkAge;
break;
case EVENT_GAME_TYPE_HEALTH:
allowDraw =
EventManager_SignedCondition(event->condType, event->health, gSaveContext.save.info.playerData.health);
break;
case EVENT_GAME_TYPE_RUPEES:
allowDraw =
EventManager_SignedCondition(event->condType, event->rupees, gSaveContext.save.info.playerData.rupees);
break;
case EVENT_GAME_TYPE_MAGIC:
allowDraw =
EventManager_SignedCondition(event->condType, event->magic, gSaveContext.save.info.playerData.magic);
break;
case EVENT_GAME_TYPE_INVENTORY:
if (event->inventory.itemId == ITEM_NONE) {
break;
}
switch (event->inventory.type) {
case EVENT_INV_TYPE_ITEMS:
value = gSaveContext.save.info.inventory.items[event->inventory.itemId];
allowDraw = event->inventory.obtained ? value != ITEM_NONE : value == ITEM_NONE;
if (event->inventory.amount >= 0) {
allowDraw = allowDraw && EventManager_SignedCondition(event->condType, event->inventory.amount,
AMMO(event->inventory.itemId));
}
break;
case EVENT_INV_TYPE_EQUIPMENT:
// swords, shields, tunics and boots
if (event->inventory.itemId >= ITEM_SWORD_KOKIRI && event->inventory.itemId <= ITEM_BOOTS_HOVER) {
u8 itemId = event->inventory.itemId - ITEM_SWORD_KOKIRI;
value = CHECK_OWNED_EQUIP(itemId / 3, itemId % 3);
allowDraw = event->inventory.obtained ? value : !value;
if (event->inventory.itemId == ITEM_SWORD_BIGGORON && event->inventory.swordHealth != (u8)-1) {
allowDraw = allowDraw &&
EventManager_UnsignedCondition(event->condType, event->inventory.swordHealth,
gSaveContext.save.info.playerData.swordHealth);
}
break;
}
// upgrades
if (event->inventory.upgradeType < UPG_MAX) {
allowDraw = EventManager_UnsignedCondition(event->condType, event->inventory.upgradeValue,
CUR_UPG_VALUE(event->inventory.upgradeType));
break;
}
break;
case EVENT_INV_TYPE_QUEST:
value = CHECK_QUEST_ITEM(event->inventory.questItem);
allowDraw = event->inventory.obtained ? value : !value;
break;
//! TODO: improve how dungeon items are handled in the game
// case EVENT_INV_TYPE_DUNGEON_ITEMS:
// break;
// case EVENT_INV_TYPE_DUNGEON_KEYS:
// if (event->inventory.sceneId < ARRAY_COUNT(gSaveContext.save.info.inventory.dungeonKeys)) {
// allowDraw = EventManager_SignedCondition(event->condType, event->inventory.amount,
// gSaveContext.save.info.inventory.dungeonKeys[event->inventory.sceneId]);
// }
// break;
case EVENT_INV_TYPE_GS_TOKENS:
if (!CHECK_QUEST_ITEM(QUEST_SKULL_TOKEN)) {
allowDraw = false;
break;
}
allowDraw = EventManager_SignedCondition(event->condType, event->inventory.gsTokens,
gSaveContext.save.info.inventory.gsTokens);
break;
default:
break;
}
break;
default:
break;
}
pabGame[event->type] = allowDraw;
}
// performs the necessary checks to handle time events
static void EventManager_ProcessTime(GameState* gameState, EventTime* event, u8* pabTime) {
u8 allowDraw = true;
if (event->isClock) {
allowDraw = EventManager_UnsignedCondition(event->clocks[0].condType,
CLOCK_TIME(event->clocks[0].hour, event->clocks[0].minute),
gSaveContext.save.dayTime);
if (event->isRange) {
allowDraw =
allowDraw && EventManager_UnsignedCondition(event->clocks[1].condType,
CLOCK_TIME(event->clocks[1].hour, event->clocks[1].minute),
gSaveContext.save.dayTime);
}
} else {
allowDraw = event->nightFlag == gSaveContext.save.nightFlag;
}
pabTime[event->type] = allowDraw;
}
// returns false if a bool is in the array
static u8 EventManager_Validate(u8* pabType, u8 length) {
u8 i;
for (i = 0; i < length; i++) {
if (!pabType[i]) {
return false;
}
}
return true;
}
u8 EventManager_GetFreezeType(void) {
return sEventActionType;
}
// returns true when it should draw, otherwise returns false
u8 EventManager_ProcessScript(GameState* gameState, EventScriptEntry* eventEntry) {
static u8 abFlag[EVENT_FLAG_TYPE_MAX];
static u8 abGame[EVENT_GAME_TYPE_MAX];
static u8 abTime[EVENT_TIME_TYPE_MAX];
u8* script;
s32 eventType;
s32 i;
script = SEGMENTED_TO_VIRTUAL(eventEntry->script);
sEventActionType = eventEntry->actionType;
memset(abFlag, true, sizeof(abFlag));
memset(abGame, true, sizeof(abGame));
memset(abTime, true, sizeof(abTime));
do {
memcpy(&eventType, script, sizeof(eventType));
script += sizeof(eventType);
switch (eventType) {
case EVENT_TYPE_NONE:
break;
case EVENT_TYPE_FLAG:
EventManager_ProcessFlag(gameState, (void*)script, abFlag);
script += sizeof(EventFlag);
break;
case EVENT_TYPE_GAME:
EventManager_ProcessGame(gameState, (void*)script, abGame);
script += sizeof(EventGame);
break;
case EVENT_TYPE_TIME:
EventManager_ProcessTime(gameState, (void*)script, abTime);
script += sizeof(EventTime);
break;
default:
eventType = EVENT_TYPE_NONE;
break;
}
} while (eventType != EVENT_TYPE_NONE);
if (!EventManager_Validate(abFlag, ARRAY_COUNT(abFlag))) {
return false;
}
if (!EventManager_Validate(abGame, ARRAY_COUNT(abGame))) {
return false;
}
if (!EventManager_Validate(abTime, ARRAY_COUNT(abTime))) {
return false;
}
return true;
}

View File

@@ -72,6 +72,8 @@ UCodeInfo D_8012D248[3] = {
{ UCODE_TYPE_S2DEX, gspS2DEX2d_fifoTextStart },
};
Gfx* gPrevTaskWorkBuffer = NULL;
void Graph_FaultClient(void) {
void* nextFb = osViGetNextFramebuffer();
void* newFb = (SysCfb_GetFbPtr(0) != nextFb) ? SysCfb_GetFbPtr(0) : SysCfb_GetFbPtr(1);
@@ -210,7 +212,6 @@ void Graph_Destroy(GraphicsContext* gfxCtx) {
void Graph_TaskSet00(GraphicsContext* gfxCtx) {
#if DEBUG_FEATURES
static Gfx* sPrevTaskWorkBuffer = NULL;
#endif
OSTask_t* task = &gfxCtx->task.list.t;
OSScTask* scTask = &gfxCtx->task;
@@ -236,11 +237,11 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
LogUtils_LogHexDump(gGfxSPTaskYieldBuffer, sizeof(gGfxSPTaskYieldBuffer));
SREG(6) = -1;
if (sPrevTaskWorkBuffer != NULL) {
if (gPrevTaskWorkBuffer != NULL) {
R_HREG_MODE = HREG_MODE_UCODE_DISAS;
R_UCODE_DISAS_TOGGLE = 1;
R_UCODE_DISAS_LOG_LEVEL = 2;
Graph_DisassembleUCode(sPrevTaskWorkBuffer);
Graph_DisassembleUCode(gPrevTaskWorkBuffer);
}
#endif
@@ -250,7 +251,7 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_NOBLOCK);
#if DEBUG_FEATURES
sPrevTaskWorkBuffer = gfxCtx->workBuffer;
gPrevTaskWorkBuffer = gfxCtx->workBuffer;
#endif
}

View File

@@ -983,6 +983,12 @@ void Actor_Destroy(Actor* actor, PlayState* play) {
PRINTF(T("Actorクラス デストラクトがありません [%s]\n", "No Actor class destruct [%s]\n") ACTOR_RST, name);
#endif
}
#if ENABLE_ANIMATED_MATERIALS
if (actor->animMatCtx.stateList != NULL) {
SYSTEM_ARENA_FREE(actor->animMatCtx.stateList);
}
#endif
}
/**

View File

@@ -469,9 +469,6 @@ void Environment_Init(PlayState* play2, EnvironmentContext* envCtx, s32 unused)
sLightningBolts[i].state = LIGHTNING_BOLT_INACTIVE;
}
play->roomCtx.drawParams[0] = 0;
play->roomCtx.drawParams[1] = 0;
for (i = 0; i < ARRAY_COUNT(play->csCtx.actorCues); i++) {
play->csCtx.actorCues[i] = NULL;
}
@@ -1009,21 +1006,20 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex
}
#if CAN_SHOW_TIME_INFOS
if (R_ENABLE_ARENA_DBG != 0 || CREG(2) != 0) {
Gfx* displayList;
Gfx* prevDisplayList;
Gfx* displayList;
Gfx* prevDisplayList;
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 1682);
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 1682);
prevDisplayList = POLY_OPA_DISP;
displayList = Gfx_Open(POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, displayList);
Environment_PrintDebugInfo(play, &displayList);
gSPEndDisplayList(displayList++);
Gfx_Close(prevDisplayList, displayList);
POLY_OPA_DISP = displayList;
CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 1690);
}
prevDisplayList = POLY_OPA_DISP;
displayList = Gfx_Open(POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, displayList);
Environment_PrintDebugInfo(play, &displayList);
gSPEndDisplayList(displayList++);
Gfx_Close(prevDisplayList, displayList);
POLY_OPA_DISP = displayList;
CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 1690);
#endif
if ((envCtx->lightSettingOverride != LIGHT_SETTING_OVERRIDE_NONE) &&

View File

@@ -50,6 +50,7 @@
#include "occlusionplanes.h"
#include "libu64/gfxprint.h"
#include "debug.h"
#include "animated_materials.h"
#if CAN_INCLUDE_EXAMPLE_SCENE
#include "assets/scenes/example/example_scene.h"
@@ -269,6 +270,16 @@ void Play_Destroy(GameState* thisx) {
this->state.gfxCtx->callback = NULL;
this->state.gfxCtx->callbackParam = NULL;
#if ENABLE_ANIMATED_MATERIALS
if (this->sceneAnimMatCtx.stateList != NULL) {
SYSTEM_ARENA_FREE(this->sceneAnimMatCtx.stateList);
}
if (this->sceneAnimMatPolyCtx.polyBackupList != NULL) {
SYSTEM_ARENA_FREE(this->sceneAnimMatPolyCtx.polyBackupList);
}
#endif
#if IS_MOTION_BLUR_ENABLED
Play_DestroyMotionBlur();
#endif
@@ -1881,6 +1892,9 @@ void Play_InitScene(PlayState* this, s32 spawn) {
#if ENABLE_ANIMATED_MATERIALS
this->sceneMaterialAnims = NULL;
this->sceneMaterialAnimCamParams = MATERIAL_CAM_PARAMS(ANIM_MAT_CAMERA_TYPE_NONE, false);
this->sceneAnimMatCtx.stateList = NULL;
this->sceneAnimMatPolyCtx.polyBackupList = NULL;
#endif
#if ENABLE_CUTSCENE_IMPROVEMENTS
@@ -1897,6 +1911,10 @@ void Play_InitScene(PlayState* this, s32 spawn) {
gSaveContext.worldMapArea = WORLD_MAP_AREA_HYRULE_FIELD;
Scene_ExecuteCommands(this, this->sceneSegment);
Play_InitEnvironment(this, this->skyboxId);
#if ENABLE_ANIMATED_MATERIALS
AnimatedMat_Init(&this->state, &this->sceneAnimMatCtx, &this->sceneAnimMatPolyCtx, this->sceneMaterialAnims);
#endif
}
void Play_SpawnScene(PlayState* this, s32 sceneId, s32 spawn) {

View File

@@ -526,6 +526,7 @@ void Scene_SetTransitionForNextEntrance(PlayState* play) {
#if ENABLE_ANIMATED_MATERIALS
void Scene_CommandAnimatedMaterials(PlayState* play, SceneCmd* cmd) {
play->sceneMaterialAnims = SEGMENTED_TO_VIRTUAL(cmd->textureAnimations.segment);
play->sceneMaterialAnimCamParams = cmd->textureAnimations.camParams;
}
#endif

View File

@@ -1754,7 +1754,8 @@ void Scene_DrawConfigBesitu(PlayState* play) {
* Allows the usage of the animated material system in scenes.
*/
void Scene_DrawConfigMatAnim(PlayState* play) {
AnimatedMat_Draw(play, play->sceneMaterialAnims);
AnimatedMat_Draw(&play->state, &play->sceneAnimMatCtx, &play->sceneAnimMatPolyCtx, play->gameplayFrames,
play->sceneMaterialAnims);
}
/**
@@ -1762,7 +1763,8 @@ void Scene_DrawConfigMatAnim(PlayState* play) {
* rather than always animating like `Scene_DrawConfigMatAnim`.
*/
void Scene_DrawConfigMatAnimManualStep(PlayState* play) {
AnimatedMat_DrawStep(play, play->sceneMaterialAnims, play->roomCtx.drawParams[0]);
AnimatedMat_DrawStep(&play->state, &play->sceneAnimMatCtx, &play->sceneAnimMatPolyCtx, play->sceneMaterialAnims,
play->roomCtx.drawParams[0]);
}
#endif