Animations (#727)

* decomp 5 animator functions

* animation script disasm

* cleaning up

* improvements in animation disasm

* TODO
This commit is contained in:
Unnunu 2022-06-09 16:49:57 +03:00 committed by GitHub
parent 59119c0949
commit accf5a60f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 7239 additions and 3355 deletions

View File

@ -643,7 +643,7 @@ typedef struct Entity {
SimpleSpringData* simpleSpring;
s32* unk;
} dataBuf;
/* 0x44 */ Mtx* vertexData;
/* 0x44 */ Vec3s* vertexData;
/* 0x48 */ Vec3f position;
/* 0x54 */ Vec3f scale;
/* 0x60 */ Vec3f rotation;
@ -680,7 +680,7 @@ typedef struct Shadow {
/* 0x07 */ char unk_07;
/* 0x08 */ s16 entityModelID;
/* 0x0A */ s16 vertexSegment;
/* 0x0C */ Vtx* vertexArray;
/* 0x0C */ Vec3s* vertexArray;
/* 0x10 */ Vec3f position;
/* 0x1C */ Vec3f scale;
/* 0x28 */ Vec3f rotation;
@ -1158,8 +1158,8 @@ typedef struct ModelAnimator {
/* 0x000 */ u32 flags;
/* 0x004 */ s8 renderMode;
/* 0x005 */ char unk_05[3];
/* 0x008 */ s8* animReadPos;
/* 0x00C */ s8* savedReadPos;
/* 0x008 */ s16* animReadPos;
/* 0x00C */ s16* savedReadPos;
/* 0x010 */ AnimatorNode* rootNode;
/* 0x014 */ u8 nextUniqueID;
/* 0x015 */ u8 staticNodeIDs[0x7A]; // ?
@ -1167,13 +1167,13 @@ typedef struct ModelAnimator {
/* 0x090 */ f32 nextUpdateTime;
/* 0x094 */ f32 timeScale;
/* 0x098 */ Mtx mtx;
/* 0x0D8 */ Vtx** vertexArray;
/* 0x0DC */ s8* animationBuffer;
/* 0x0D8 */ Vec3s* vertexArray;
/* 0x0DC */ s16* animationBuffer;
/* 0x0E0 */ StaticAnimatorNode* staticNodes[0x7A];
/* 0x2C8 */ StaticAnimatorNode** staticRoot;
/* 0x2CC */ s32 treeIndexPos;
/* 0x2D0 */ s32 savedTreePos;
/* 0x2D4 */ void (*fpRenderCallback)(void);
/* 0x2D4 */ void (*fpRenderCallback)(void*);
/* 0x2D8 */ s32 renderCallbackArg;
/* 0x2DC */ char unk_2DC[4];
} ModelAnimator; // size = 0x2E0

View File

@ -3258,63 +3258,26 @@ enum MoveActionTips {
MOVE_ACTION_TIP_20 = 20
};
enum AnimatorNodeFlags {
ANIMATOR_NODE_FLAGS_0 = 0x00000000,
ANIMATOR_NODE_FLAGS_1 = 0x00000001,
ANIMATOR_NODE_FLAGS_2 = 0x00000002,
ANIMATOR_NODE_FLAGS_4 = 0x00000004,
ANIMATOR_NODE_FLAGS_8 = 0x00000008,
ANIMATOR_NODE_FLAGS_10 = 0x00000010,
ANIMATOR_NODE_FLAGS_20 = 0x00000020,
ANIMATOR_NODE_FLAGS_40 = 0x00000040,
ANIMATOR_NODE_FLAGS_80 = 0x00000080,
ANIMATOR_NODE_FLAGS_100 = 0x00000100,
ANIMATOR_NODE_FLAGS_200 = 0x00000200,
ANIMATOR_NODE_FLAGS_400 = 0x00000400,
ANIMATOR_NODE_FLAGS_800 = 0x00000800,
ANIMATOR_NODE_FLAGS_1000 = 0x00001000,
ANIMATOR_NODE_FLAGS_2000 = 0x00002000,
ANIMATOR_NODE_FLAGS_4000 = 0x00004000,
ANIMATOR_NODE_FLAGS_8000 = 0x00008000,
ANIMATOR_NODE_FLAGS_10000 = 0x00010000,
ANIMATOR_NODE_FLAGS_20000 = 0x00020000,
ANIMATOR_NODE_FLAGS_40000 = 0x00040000,
ANIMATOR_NODE_FLAGS_80000 = 0x00080000,
ANIMATOR_NODE_FLAGS_100000 = 0x00100000,
ANIMATOR_NODE_FLAGS_200000 = 0x00200000,
ANIMATOR_NODE_FLAGS_400000 = 0x00400000,
ANIMATOR_NODE_FLAGS_800000 = 0x00800000,
ANIMATOR_NODE_FLAGS_1000000 = 0x01000000,
ANIMATOR_NODE_FLAGS_2000000 = 0x02000000,
ANIMATOR_NODE_FLAGS_4000000 = 0x04000000,
ANIMATOR_NODE_FLAGS_8000000 = 0x08000000,
ANIMATOR_NODE_FLAGS_10000000 = 0x10000000,
ANIMATOR_NODE_FLAGS_20000000 = 0x20000000,
ANIMATOR_NODE_FLAGS_40000000 = 0x40000000,
ANIMATOR_NODE_FLAGS_80000000 = 0x80000000,
};
enum ModelAnimatorFlags {
MODEL_ANIMATOR_FLAGS_0 = 0x00000000,
MODEL_ANIMATOR_FLAGS_1 = 0x00000001,
MODEL_ANIMATOR_FLAGS_2 = 0x00000002,
MODEL_ANIMATOR_FLAGS_4 = 0x00000004,
MODEL_ANIMATOR_FLAGS_8 = 0x00000008,
MODEL_ANIMATOR_FLAGS_10 = 0x00000010,
MODEL_ANIMATOR_FLAGS_CAM_0 = 0x00000001,
MODEL_ANIMATOR_FLAGS_CAM_1 = 0x00000002,
MODEL_ANIMATOR_FLAGS_CAM_2 = 0x00000004,
MODEL_ANIMATOR_FLAGS_CAM_3 = 0x00000008,
MODEL_ANIMATOR_FLAGS_ENABLED = 0x00000010,
MODEL_ANIMATOR_FLAGS_20 = 0x00000020,
MODEL_ANIMATOR_FLAGS_40 = 0x00000040,
MODEL_ANIMATOR_FLAGS_80 = 0x00000080,
MODEL_ANIMATOR_FLAGS_100 = 0x00000100,
MODEL_ANIMATOR_FLAGS_200 = 0x00000200,
MODEL_ANIMATOR_FLAGS_400 = 0x00000400,
MODEL_ANIMATOR_FLAGS_UPDATE_PENDING = 0x00000040,
MODEL_ANIMATOR_FLAGS_HIDDEN = 0x00000080,
MODEL_ANIMATOR_FLAGS_FLIP_Z = 0x00000100,
MODEL_ANIMATOR_FLAGS_FLIP_Y = 0x00000200,
MODEL_ANIMATOR_FLAGS_FLIP_X = 0x00000400,
MODEL_ANIMATOR_FLAGS_800 = 0x00000800,
MODEL_ANIMATOR_FLAGS_1000 = 0x00001000,
MODEL_ANIMATOR_FLAGS_HAS_MODEL = 0x00001000,
MODEL_ANIMATOR_FLAGS_2000 = 0x00002000,
MODEL_ANIMATOR_FLAGS_4000 = 0x00004000,
MODEL_ANIMATOR_FLAGS_8000 = 0x00008000,
MODEL_ANIMATOR_FLAGS_10000 = 0x00010000,
MODEL_ANIMATOR_FLAGS_20000 = 0x00020000,
MODEL_ANIMATOR_FLAGS_40000 = 0x00040000,
MODEL_ANIMATOR_FLAGS_MESH = 0x00008000,
MODEL_ANIMATOR_FLAGS_CULL_BACK = 0x00010000,
MODEL_ANIMATOR_FLAGS_NO_FLIP = 0x00020000,
MODEL_ANIMATOR_FLAGS_FREEZE_ANIMATION = 0x00040000,
MODEL_ANIMATOR_FLAGS_80000 = 0x00080000,
MODEL_ANIMATOR_FLAGS_100000 = 0x00100000,
MODEL_ANIMATOR_FLAGS_200000 = 0x00200000,

View File

@ -815,7 +815,7 @@ void show_foreground_models(void);
void hide_foreground_models(void);
void btl_set_state(s32 battleState);
void draw_entity_model_A(s32, Mtx*);
void draw_entity_model_B(s32, Mtx*, s32, s32);
void draw_entity_model_B(s32, Mtx*, s32, Vec3s*);
void draw_entity_model_C(s32, Mtx*);
void draw_entity_model_D(s32, Mtx*, s32, Vtx*);
void draw_entity_model_E(s32, Mtx*);

View File

@ -167,9 +167,9 @@ void animator_node_update_model_transform(ModelAnimator* animator, f32 (*flipMtx
void delete_model_animator_node(AnimatorNode* node);
void delete_model_animator_nodes(ModelAnimator* animator);
void delete_model_animator(ModelAnimator* animator);
void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32 vtxSegment, Vtx* vertexArray);
void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32 vtxSegment, Vec3s* vertexArray);
void appendGfx_animator(ModelAnimator* animator);
ModelAnimator* set_animator_render_callback(s32 animModelID, s32 callbackArg, s32 callbackFunc);
ModelAnimator* set_animator_render_callback(s32 animModelID, s32 callbackArg, void (*callbackFunc)(void*));
void reload_mesh_animator_tree(ModelAnimator* animator);
s32 step_mesh_animator(ModelAnimator* animator);
#endif

View File

@ -1,12 +1,16 @@
#include "model.h"
#include "animation_script.h"
s8 D_8014C250[] = {0x00, 0x01, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
AnimScript gAnimScriptDefault = {
AS_WAIT, 60,
AS_END,
};
extern s32 gAnimCount;
typedef struct DisplayListBufferHandle {
/* 0x0 */ s32 mode;
/* 0x4 */ Gfx* addr;
/* 0x0 */ s32 ttl;
/* 0x4 */ void* addr;
} DisplayListBufferHandle; // size = 0x8
typedef DisplayListBufferHandle AnimatedMeshVertexCopyList[0x60];
@ -22,25 +26,42 @@ extern s32 gAnimModelFogB;
extern s32 gAnimModelFogA;
extern s32 gAnimModelFogStart;
extern s32 gAnimModelFogEnd;
extern s32 D_80153A60;
extern s32 gAnimVtxSegment;
extern Matrix4f gAnimRotMtx;
extern Matrix4f gAnimScaleMtx;
extern Matrix4f gAnimTranslateMtx;
extern Matrix4f gAnimRotScaleMtx;
extern StaticAnimatorNode** gAnimTreeRoot;
// reg swap
#ifdef NON_EQUIVALENT
extern Gfx D_8014B7F8[];
extern Gfx D_8014B820[];
extern Gfx D_8014B848[];
extern Gfx D_8014B870[];
extern Gfx D_8014B898[];
extern Gfx D_8014B8C0[];
extern Gfx D_8014B8E8[];
extern Gfx D_8014BE78[];
extern Gfx D_8014BEA0[];
extern Gfx D_8014BEC8[];
extern Gfx D_8014BEF0[];
extern Gfx D_8014BF18[];
extern Gfx D_8014BF40[];
extern Gfx D_8014BF68[];
void appendGfx_animator_node(ModelAnimator*, AnimatorNode*, Matrix4f);
// copy Vtx array from node->fcData.vtxList, but overwrite xyz coordinates with ones from buffer
// if animator has own vertexArray, buffer is offset within it
Vtx* animator_copy_vertices_to_buffer(ModelAnimator* animator, AnimatorNode* node, Vec3s* buffer, s32 vtxCount,
s32 overhead, s32 startIdx) {
DisplayListBufferHandle* handle;
Vtx* bufferMem;
Vtx* phi_v1;
Vtx* nodeVtxList;
s32 i;
for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
handle = &D_801533C0[i];
if (handle->mode < 0) {
if (handle->ttl < 0) {
break;
}
}
@ -52,27 +73,25 @@ Vtx* animator_copy_vertices_to_buffer(ModelAnimator* animator, AnimatorNode* nod
ASSERT(bufferMem != NULL);
handle->mode = 3;
phi_v1 = &node->fcData.vtxList[startIdx];
handle->ttl = 3;
nodeVtxList = &node->fcData.vtxList[startIdx];
if (animator->vertexArray != NULL) {
buffer = ((s32)buffer & 0xFFFFFF) + (s32)animator->vertexArray;
i = ((s32)buffer & 0xFFFFFF); // needed to match
buffer = (Vec3s*)(i + (s32)animator->vertexArray);
}
for (i = 0; i < vtxCount; i++) {
*bufferMem = *phi_v1;
*bufferMem = *nodeVtxList;
bufferMem->v.ob[0] = buffer->x;
bufferMem->v.ob[1] = buffer->y;
bufferMem->v.ob[2] = buffer->z;
bufferMem++;
buffer++;
phi_v1++;
nodeVtxList++;
}
return handle->addr;
}
#else
INCLUDE_ASM(s32, "B4580", animator_copy_vertices_to_buffer);
#endif
void animator_make_mirrorZ(Matrix4f mtx) {
guMtxIdentF(mtx);
@ -127,16 +146,16 @@ AnimatorNode* get_animator_child_with_id(AnimatorNode* node, s32 id) {
return NULL;
}
AnimatorNode* get_animator_child_for_model(AnimatorNode* node, s32 id) {
AnimatorNode* get_animator_child_for_model(AnimatorNode* node, s32 modelId) {
s32 i;
if (node->fcData.modelID == id) {
if (node->fcData.modelID == modelId) {
return node;
}
for (i = 0; i < ARRAY_COUNT(node->children); i++) {
if (node->children[i] != NULL) {
AnimatorNode* child = get_animator_child_for_model(node->children[i], id);
AnimatorNode* child = get_animator_child_for_model(node->children[i], modelId);
if (child != NULL) {
return child;
@ -165,11 +184,11 @@ void clear_animator_list(void) {
if (!gGameStatusPtr->isBattle) {
gCurrentAnimMeshListPtr = &D_801539C0;
for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
D_801533C0[i].mode = -1;
D_801533C0[i].ttl = -1;
}
for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
D_801536C0[i].mode = -1;
D_801536C0[i].ttl = -1;
}
} else {
gCurrentAnimMeshListPtr = &D_80153A00;
@ -209,7 +228,7 @@ void reset_animator_list(void) {
void delete_model_animator_node(AnimatorNode* node) {
s32 i;
node->flags = ANIMATOR_NODE_FLAGS_0;
node->flags = 0;
for (i = 0; i < ARRAY_COUNT(node->children); i++) {
if (node->children[i] != NULL) {
@ -251,7 +270,7 @@ void delete_model_animator(ModelAnimator* animator) {
}
}
s32 create_model_animator(s8* animPos) {
s32 create_model_animator(s16* animPos) {
ModelAnimator* animator;
s32 i, j;
@ -268,14 +287,14 @@ s32 create_model_animator(s8* animPos) {
ASSERT(animator != NULL);
animator->flags = MODEL_ANIMATOR_FLAGS_40 | MODEL_ANIMATOR_FLAGS_10 | MODEL_ANIMATOR_FLAGS_4 | MODEL_ANIMATOR_FLAGS_2 | MODEL_ANIMATOR_FLAGS_1;
animator->flags = MODEL_ANIMATOR_FLAGS_UPDATE_PENDING | MODEL_ANIMATOR_FLAGS_ENABLED | MODEL_ANIMATOR_FLAGS_CAM_2 | MODEL_ANIMATOR_FLAGS_CAM_1 | MODEL_ANIMATOR_FLAGS_CAM_0;
animator->renderMode = RENDER_MODE_ALPHATEST;
animator->nextUpdateTime = 1.0f;
animator->timeScale = 1.0f;
animator->animReadPos = animPos;
if (animPos == NULL) {
animator->animReadPos = D_8014C250;
animator->animReadPos = gAnimScriptDefault;
}
animator->savedReadPos = animPos;
@ -295,7 +314,7 @@ s32 create_model_animator(s8* animPos) {
return i;
}
s32 create_mesh_animator(s32 animPos, s8* animBuffer) {
s32 create_mesh_animator(s32 animPos, s16* animBuffer) {
ModelAnimator* animator;
s32 i, j;
@ -312,7 +331,7 @@ s32 create_mesh_animator(s32 animPos, s8* animBuffer) {
ASSERT(animator != NULL);
animator->flags = MODEL_ANIMATOR_FLAGS_40 | MODEL_ANIMATOR_FLAGS_10 | MODEL_ANIMATOR_FLAGS_4 | MODEL_ANIMATOR_FLAGS_2 | MODEL_ANIMATOR_FLAGS_1;
animator->flags = MODEL_ANIMATOR_FLAGS_UPDATE_PENDING | MODEL_ANIMATOR_FLAGS_ENABLED | MODEL_ANIMATOR_FLAGS_CAM_2 | MODEL_ANIMATOR_FLAGS_CAM_1 | MODEL_ANIMATOR_FLAGS_CAM_0;
animator->renderMode = RENDER_MODE_ALPHATEST;
animator->vertexArray = NULL;
animator->fpRenderCallback = NULL;
@ -322,8 +341,8 @@ s32 create_mesh_animator(s32 animPos, s8* animBuffer) {
animator->nextUpdateTime = 1.0f;
animator->timeScale = 1.0f;
animPos = (animPos & 0xFFFFFF) + (s32)animator->animationBuffer;
animator->animReadPos = (s8*)animPos;
animator->savedReadPos = (s8*)animPos;
animator->animReadPos = (s16*)animPos;
animator->savedReadPos = (s16*)animPos;
for (j = 0; j < ARRAY_COUNT(animator->staticNodeIDs); j++) {
animator->staticNodeIDs[j] = j + 1;
@ -345,7 +364,7 @@ AnimatorNode* add_anim_node(ModelAnimator* animator, s32 parentNodeID, AnimatorN
ret = heap_malloc(sizeof(*ret));
ASSERT(ret != NULL);
ret->flags = ANIMATOR_NODE_FLAGS_10;
ret->flags = MODEL_ANIMATOR_FLAGS_ENABLED;
ret->displayList = nodeBP->displayList;
ret->basePos.x = nodeBP->basePos.x;
ret->basePos.y = nodeBP->basePos.y;
@ -417,11 +436,11 @@ void update_model_animator(s32 animatorID) {
if (animator != NULL && animator->flags != 0) {
s32 temp = 0;
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_40000)) {
animator->flags &= ~MODEL_ANIMATOR_FLAGS_40;
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_FREEZE_ANIMATION)) {
animator->flags &= ~MODEL_ANIMATOR_FLAGS_UPDATE_PENDING;
animator->nextUpdateTime -= animator->timeScale;
if (animator->nextUpdateTime <= 0.0f) {
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_8000)) {
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_MESH)) {
do {
temp = step_model_animator(animator);
} while (temp > 0);
@ -440,20 +459,20 @@ void update_model_animator(s32 animatorID) {
animator_update_model_transforms(animator, NULL);
for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
if (D_801533C0[i].mode >= 0) {
D_801533C0[i].mode--;
if (D_801533C0[i].mode == 0) {
D_801533C0[i].mode = -1;
if (D_801533C0[i].ttl >= 0) {
D_801533C0[i].ttl--;
if (D_801533C0[i].ttl == 0) {
D_801533C0[i].ttl = -1;
general_heap_free(D_801533C0[i].addr);
}
}
}
for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
if (D_801536C0[i].mode >= 0) {
D_801536C0[i].mode--;
if (D_801536C0[i].mode == 0) {
D_801536C0[i].mode = -1;
if (D_801536C0[i].ttl >= 0) {
D_801536C0[i].ttl--;
if (D_801536C0[i].ttl == 0) {
D_801536C0[i].ttl = -1;
general_heap_free(D_801536C0[i].addr);
}
}
@ -474,11 +493,11 @@ void update_model_animator_with_transform(s32 animatorID, Mtx* mtx) {
if (animator != NULL && animator->flags != 0) {
s32 temp = 0;
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_40000)) {
animator->flags &= ~MODEL_ANIMATOR_FLAGS_40;
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_FREEZE_ANIMATION)) {
animator->flags &= ~MODEL_ANIMATOR_FLAGS_UPDATE_PENDING;
animator->nextUpdateTime -= animator->timeScale;
if (animator->nextUpdateTime <= 0.0f) {
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_8000)) {
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_MESH)) {
do {
temp = step_model_animator(animator);
} while (temp > 0);
@ -497,20 +516,20 @@ void update_model_animator_with_transform(s32 animatorID, Mtx* mtx) {
animator_update_model_transforms(animator, mtx);
for (i = 0; i < ARRAY_COUNT(D_801533C0); i++) {
if (D_801533C0[i].mode >= 0) {
D_801533C0[i].mode--;
if (D_801533C0[i].mode == 0) {
D_801533C0[i].mode = -1;
if (D_801533C0[i].ttl >= 0) {
D_801533C0[i].ttl--;
if (D_801533C0[i].ttl == 0) {
D_801533C0[i].ttl = -1;
general_heap_free(D_801533C0[i].addr);
}
}
}
for (i = 0; i < ARRAY_COUNT(D_801536C0); i++) {
if (D_801536C0[i].mode >= 0) {
D_801536C0[i].mode--;
if (D_801536C0[i].mode == 0) {
D_801536C0[i].mode = -1;
if (D_801536C0[i].ttl >= 0) {
D_801536C0[i].ttl--;
if (D_801536C0[i].ttl == 0) {
D_801536C0[i].ttl = -1;
general_heap_free(D_801536C0[i].addr);
}
}
@ -521,20 +540,118 @@ void update_model_animator_with_transform(s32 animatorID, Mtx* mtx) {
}
}
INCLUDE_ASM(s32, "B4580", step_model_animator);
s32 step_model_animator(ModelAnimator* animator) {
s16* args = animator->animReadPos;
AnimatorNode* node;
f32 x, y, z;
s32 flags;
s32 nodeId;
switch (*args++) {
case AS_END:
return -1;
case AS_SET_RENDER_MODE:
animator->renderMode = *args++;
animator->animReadPos = args;
return 1;
case AS_WAIT:
animator->nextUpdateTime = *args++;
animator->animReadPos = args;
break;
case AS_END_LOOP:
animator->animReadPos = animator->savedReadPos;
return 1;
case AS_LOOP:
animator->animReadPos = animator->savedReadPos = args;
return 1;
case AS_SET_FLAGS:
flags = *args++;
animator->animReadPos = args;
animator->flags |= flags & 0xFFFF;
return 1;
case AS_SET_NODE_FLAGS:
node = get_animator_child_with_id(animator->rootNode, animator->staticNodeIDs[*args++ - 1]);
flags = *args++;
node->flags |= flags;
animator->animReadPos = args;
return 1;
case AS_CLEAR_NODE_FLAGS:
node = get_animator_child_with_id(animator->rootNode, animator->staticNodeIDs[*args++ - 1]);
flags = *args++;
node->flags &= ~flags;
animator->animReadPos = args;
return 1;
case AS_OP_19:
animator->flags |= MODEL_ANIMATOR_FLAGS_NO_FLIP;
animator->animReadPos = args;
return 1;
case AS_SET_ROTATION:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = (f32)*args++ * 180.0 / 32767.0;
y = (f32)*args++ * 180.0 / 32767.0;
z = (f32)*args++ * 180.0 / 32767.0;
animator->animReadPos = args;
node = get_animator_child_with_id(animator->rootNode, nodeId);
ASSERT(node != NULL);
node->rotation.x = x;
node->rotation.y = y;
node->rotation.z = z;
return 1;
case AS_ADD_ROTATION:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = (f32)*args++ * 180.0 / 32767.0;
y = (f32)*args++ * 180.0 / 32767.0;
z = (f32)*args++ * 180.0 / 32767.0;
animator->animReadPos = args;
node = get_animator_child_with_id(animator->rootNode, nodeId);
ASSERT(node != NULL);
node->rotation.x += x;
node->rotation.y += y;
node->rotation.z += z;
return 1;
case AS_SET_POS:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = *args++;
y = *args++;
z = *args++;
animator->animReadPos = args;
node = get_animator_child_with_id(animator->rootNode, nodeId);
ASSERT(node != NULL);
node->pos.x = x;
node->pos.y = y;
node->pos.z = z;
return 1;
case AS_SET_SCALE:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = (f32)*args++ * 180.0 / 32767.0;
y = (f32)*args++ * 180.0 / 32767.0;
z = (f32)*args++ * 180.0 / 32767.0;
animator->animReadPos = args;
node = get_animator_child_with_id(animator->rootNode, nodeId);
ASSERT(node != NULL);
node->scale.x = x;
node->scale.y = y;
node->scale.z = z;
return 1;
}
return 0;
}
void animator_update_model_transforms(ModelAnimator* animator, Mtx* rootTransform) {
Matrix4f flipMtx;
if (animator->rootNode != NULL) {
switch (animator->flags & (MODEL_ANIMATOR_FLAGS_100 | MODEL_ANIMATOR_FLAGS_200 | MODEL_ANIMATOR_FLAGS_400)) {
case 0x100:
switch (animator->flags & (MODEL_ANIMATOR_FLAGS_FLIP_Z | MODEL_ANIMATOR_FLAGS_FLIP_Y | MODEL_ANIMATOR_FLAGS_FLIP_X)) {
case MODEL_ANIMATOR_FLAGS_FLIP_Z:
animator_make_mirrorZ(flipMtx);
break;
case 0x200:
case MODEL_ANIMATOR_FLAGS_FLIP_Y:
animator_make_mirrorY(flipMtx);
break;
case 0x400:
case MODEL_ANIMATOR_FLAGS_FLIP_X:
animator_make_mirrorX(flipMtx);
break;
default:
@ -556,13 +673,13 @@ void animator_node_update_model_transform(ModelAnimator* animator, f32 (*flipMtx
guMtxCatF(gAnimScaleMtx, gAnimRotMtx, gAnimRotScaleMtx);
guMtxCatF(gAnimRotScaleMtx, gAnimTranslateMtx, sp10);
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_20000)) {
if (!(animator->flags & MODEL_ANIMATOR_FLAGS_NO_FLIP)) {
guMtxCatF(sp10, flipMtx, sp10);
}
copy_matrix(sp10, node->mtx);
if (node->flags & ANIMATOR_NODE_FLAGS_1000) {
if (node->flags & MODEL_ANIMATOR_FLAGS_HAS_MODEL) {
Model* model = get_model_from_list_index(get_model_list_index_from_tree_index(node->fcData.modelID));
copy_matrix(sp10, model->transformMatrix);
@ -587,13 +704,13 @@ void render_animated_model(s32 animatorID, Mtx* rootTransform) {
animatorID &= ~0x800;
animator = (*gCurrentAnimMeshListPtr)[animatorID];
if (animator != NULL && animator->flags != 0 && !(animator->flags & MODEL_ANIMATOR_FLAGS_40) &&
animator->flags & (1 << gCurrentCamID) && !(animator->flags & MODEL_ANIMATOR_FLAGS_80))
if (animator != NULL && animator->flags != 0 && !(animator->flags & MODEL_ANIMATOR_FLAGS_UPDATE_PENDING) &&
animator->flags & (1 << gCurrentCamID) && !(animator->flags & MODEL_ANIMATOR_FLAGS_HIDDEN))
{
animator->mtx = *rootTransform;
animator->vertexArray = NULL;
rtPtr->appendGfxArg = animator;
rtPtr->appendGfx = &appendGfx_animator;
rtPtr->appendGfx = (void (*)(void*))appendGfx_animator;
rtPtr->distance = 0;
rtPtr->renderMode = animator->renderMode;
queue_render_task(rtPtr);
@ -601,7 +718,7 @@ void render_animated_model(s32 animatorID, Mtx* rootTransform) {
}
}
void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32 vtxSegment, Vtx* vertexArray) {
void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32 vtxSegment, Vec3s* vertexArray) {
RenderTask rt;
RenderTask* rtPtr = &rt;
@ -610,14 +727,14 @@ void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32
animatorID &= ~0x800;
animator = (*gCurrentAnimMeshListPtr)[animatorID];
if (animator != NULL && animator->flags != 0 && !(animator->flags & MODEL_ANIMATOR_FLAGS_40) &&
animator->flags & (1 << gCurrentCamID) && !(animator->flags & MODEL_ANIMATOR_FLAGS_80))
if (animator != NULL && animator->flags != 0 && !(animator->flags & MODEL_ANIMATOR_FLAGS_UPDATE_PENDING) &&
animator->flags & (1 << gCurrentCamID) && !(animator->flags & MODEL_ANIMATOR_FLAGS_HIDDEN))
{
animator->mtx = *rootTransform;
D_80153A60 = vtxSegment;
gAnimVtxSegment = vtxSegment;
animator->vertexArray = vertexArray;
rtPtr->appendGfxArg = animator;
rtPtr->appendGfx = &appendGfx_animator;
rtPtr->appendGfx = (void (*)(void*))appendGfx_animator;
rtPtr->distance = 0;
rtPtr->renderMode = animator->renderMode;
queue_render_task(rtPtr);
@ -625,15 +742,198 @@ void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32
}
}
INCLUDE_ASM(s32, "B4580", appendGfx_animator);
void appendGfx_animator(ModelAnimator* animator) {
Matrix4f sp10;
if (animator->vertexArray != NULL) {
gSPSegment(gMasterGfxPos++, gAnimVtxSegment, VIRTUAL_TO_PHYSICAL(animator->vertexArray));
}
gDisplayContext->matrixStack[gMatrixListPos] = animator->mtx;
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
//TODO find better match
switch (gAnimModelFogEnabled != 0) {
case FALSE:
switch (animator->renderMode) {
case RENDER_MODE_SURFACE_OPA:
gSPDisplayList(gMasterGfxPos++, D_8014B7F8);
break;
case RENDER_MODE_DECAL_OPA:
gSPDisplayList(gMasterGfxPos++, D_8014B820);
break;
case RENDER_MODE_INTERSECTING_OPA:
gSPDisplayList(gMasterGfxPos++, D_8014B848);
break;
case RENDER_MODE_ALPHATEST:
gSPDisplayList(gMasterGfxPos++, D_8014B870);
break;
case RENDER_MODE_SURFACE_XLU_LAYER1:
gSPDisplayList(gMasterGfxPos++, D_8014B898);
break;
case RENDER_MODE_DECAL_XLU:
gSPDisplayList(gMasterGfxPos++, D_8014B8C0);
break;
case RENDER_MODE_INTERSECTING_XLU:
gSPDisplayList(gMasterGfxPos++, D_8014B8E8);
break;
}
break;
case TRUE:
switch (animator->renderMode) {
case RENDER_MODE_SURFACE_OPA:
gSPDisplayList(gMasterGfxPos++, D_8014BE78);
break;
case RENDER_MODE_DECAL_OPA:
gSPDisplayList(gMasterGfxPos++, D_8014BEA0);
break;
case RENDER_MODE_INTERSECTING_OPA:
gSPDisplayList(gMasterGfxPos++, D_8014BEC8);
break;
case RENDER_MODE_ALPHATEST:
gSPDisplayList(gMasterGfxPos++, D_8014BEF0);
break;
case RENDER_MODE_SURFACE_XLU_LAYER1:
gSPDisplayList(gMasterGfxPos++, D_8014BF18);
break;
case RENDER_MODE_DECAL_XLU:
gSPDisplayList(gMasterGfxPos++, D_8014BF40);
break;
case RENDER_MODE_INTERSECTING_XLU:
gSPDisplayList(gMasterGfxPos++, D_8014BF68);
break;
}
gDPSetFogColor(gMasterGfxPos++, gAnimModelFogR, gAnimModelFogG, gAnimModelFogB, gAnimModelFogA);
gSPFogPosition(gMasterGfxPos++, gAnimModelFogStart, gAnimModelFogEnd);
break;
}
guMtxL2F(sp10, &animator->mtx);
appendGfx_animator_node(animator, animator->rootNode, sp10);
gSPPopMatrix(gMasterGfxPos++, G_MTX_MODELVIEW);
}
#ifdef NON_EQUIVALENT
void appendGfx_animator_node(ModelAnimator* animator, AnimatorNode* node, Matrix4f mtx) {
s32 i, dlSize, bufferIdx;
DisplayListBufferHandle* bufferHandle;
Gfx* gfxPos;
s32 j;
u32 w0,w1;
s32 totalVtxCount;
s32 cmd;
if (node->flags & MODEL_ANIMATOR_FLAGS_HIDDEN) {
for (i = 0; i < ARRAY_COUNT(node->children); i++) {
if (node->children[i] != NULL) {
guMtxCatF(node->mtx, mtx, node->mtx);
appendGfx_animator_node(animator, node->children[i], node->mtx);
}
}
return;
}
guMtxCatF(node->mtx, mtx, node->mtx);
guMtxF2L(node->mtx, &gDisplayContext->matrixStack[gMatrixListPos]);
gSPMatrix(gMasterGfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPPipeSync(gMasterGfxPos++);
gSPTexture(gMasterGfxPos++, 0, 0, 0, G_TX_RENDERTILE, G_OFF);
gDPSetTextureLOD(gMasterGfxPos++, G_TL_TILE);
gDPSetTextureLUT(gMasterGfxPos++, G_TT_NONE);
gSPClearGeometryMode(gMasterGfxPos++, G_LIGHTING);
if (animator->flags & MODEL_ANIMATOR_FLAGS_CULL_BACK) {
gSPSetGeometryMode(gMasterGfxPos++, G_CULL_BACK);
}
if (!gAnimModelFogEnabled) {
gDPSetCombineMode(gMasterGfxPos++, G_CC_DECALRGBA, G_CC_DECALRGBA);
} else {
gDPSetCombineLERP(gMasterGfxPos++, TEXEL0, 0, SHADE, 0, TEXEL0, 0, 0, TEXEL0, COMBINED, 0, SHADE, 0, 0, 0, 0, COMBINED);
}
gDPPipeSync(gMasterGfxPos++);
if (animator->fpRenderCallback != NULL) {
animator->fpRenderCallback(animator->renderCallbackArg);
}
gDPPipeSync(gMasterGfxPos++);
if (node->displayList != NULL) {
if (node->vertexStartOffset < 0) {
gSPDisplayList(gMasterGfxPos++, node->displayList);
} else {
dlSize = 0;
if (node->displayList[dlSize].words.w0 >> 0x18 != G_ENDDL) {
while (TRUE) {
w0 = node->displayList[dlSize++].words.w0;
cmd = w0 >> 0x18;
if (cmd == G_ENDDL) {
break;
}
}
}
for (bufferIdx = 0; bufferIdx < ARRAY_COUNT(D_801536C0); bufferIdx++) {
bufferHandle = &D_801536C0[bufferIdx];
if (bufferHandle->ttl < 0) {
break;
}
}
ASSERT(bufferIdx < ARRAY_COUNT(D_801536C0));
gfxPos = general_heap_malloc(dlSize * sizeof(Gfx));
bufferHandle->addr = gfxPos;
ASSERT(gfxPos != NULL);
bufferHandle->ttl = 3;
totalVtxCount = 0;
j = 0;
do {
w0 = ((s32*)node->displayList)[j++];
w1 = ((s32*)node->displayList)[j++];
cmd = w0 >> 0x18;
if (cmd == G_ENDDL) {
break;
}
if (cmd == G_VTX) {
s32 startIdx = _SHIFTR(w0,1,7);
s32 vtxCount = _SHIFTR(w0,12,8);
startIdx -= vtxCount;
if (node->fcData.vtxList == NULL) {
Vtx* newBuffer = &((Vtx*)w1)[node->vertexStartOffset + totalVtxCount];
gSPVertex(gfxPos++, newBuffer, vtxCount, startIdx);
} else {
// if node->fcData.vtxList != NULL, all vertex buffers in gSPVertex commands are pointers to Vec3s, not to Vtx
Vtx* newBuffer = animator_copy_vertices_to_buffer(animator, node, w1 + (node->vertexStartOffset + totalVtxCount) * 0x6, vtxCount, startIdx, totalVtxCount);
gSPVertex(gfxPos++, newBuffer, vtxCount, startIdx);
}
totalVtxCount += vtxCount;
} else {
Gfx* temp = gfxPos++;
temp->words.w0 = w0;
temp->words.w1 = w1;
}
} while (TRUE);
gSPEndDisplayList(gfxPos++);
gSPDisplayList(gMasterGfxPos++, bufferHandle->addr);
}
}
gDPPipeSync(gMasterGfxPos++);
for (i = 0; i < ARRAY_COUNT(node->children); i++) {
if (node->children[i] != NULL) {
appendGfx_animator_node(animator, node->children[i], node->mtx);
}
}
}
#else
INCLUDE_ASM(s32, "B4580", appendGfx_animator_node);
#endif
AnimatorNode* get_animator_node_for_tree_index(ModelAnimator* animator, s32 treeIndex);
INCLUDE_ASM(s32, "B4580", get_animator_node_for_tree_index);
// AnimatorNode* get_animator_node_for_tree_index(ModelAnimator* animator, s32 arg1) {
// return get_animator_child_with_id(animator->rootNode, animator->unk_14[arg1]);
// }
AnimatorNode* get_animator_node_for_tree_index(ModelAnimator* animator, s32 arg1) {
return get_animator_child_with_id(animator->rootNode, animator->staticNodeIDs[arg1 - 1]);
}
AnimatorNode* get_animator_node_with_id(ModelAnimator* animator, s32 id) {
return get_animator_child_for_model(animator->rootNode, id);
@ -652,7 +952,7 @@ ModelAnimator* get_animator_by_index(s32 animModelID) {
return (*gCurrentAnimMeshListPtr)[animModelID & ~0x800];
}
ModelAnimator* set_animator_render_callback(s32 animModelID, s32 callbackArg, s32 callbackFunc) {
ModelAnimator* set_animator_render_callback(s32 animModelID, s32 callbackArg, void (*callbackFunc)(void*)) {
ModelAnimator* ret = (*gCurrentAnimMeshListPtr)[animModelID & ~0x800];
ret->fpRenderCallback = callbackFunc;
@ -714,8 +1014,8 @@ void play_model_animation(s32 index, s32 animPos) {
if (animator->animationBuffer != NULL) {
animPos = (animPos & 0xFFFFFF) + (s32)animator->animationBuffer; // TODO: array access?
}
animator->animReadPos = (s8*)animPos;
animator->savedReadPos = (s8*)animPos;
animator->animReadPos = (s16*)animPos;
animator->savedReadPos = (s16*)animPos;
animator->treeIndexPos = 0;
animator->nextUpdateTime = 1.0f;
}
@ -729,8 +1029,8 @@ void play_model_animation_starting_from(s32 index, s32 animPos, s32 framesToSkip
animPos = (animPos & 0xFFFFFF) + (s32)animator->animationBuffer; // TODO: array access?
}
animator->animReadPos = (s8*)animPos;
animator->savedReadPos = (s8*)animPos;
animator->animReadPos = (s16*)animPos;
animator->savedReadPos = (s16*)animPos;
animator->treeIndexPos = 0;
animator->nextUpdateTime = 1.0f;
@ -758,7 +1058,7 @@ void load_model_animator_node(StaticAnimatorNode* node, ModelAnimator* animator,
if (node->modelID != 0) {
newNode->fcData.modelID = node->modelID - 1;
newNode->flags |= ANIMATOR_NODE_FLAGS_1000;
newNode->flags |= MODEL_ANIMATOR_FLAGS_HAS_MODEL;
}
i = 0;
@ -825,7 +1125,7 @@ void load_mesh_animator_tree(s32 index, StaticAnimatorNode** tree) {
}
load_mesh_animator_node(*gAnimTreeRoot, animator, 0, nodeIDs);
animator->flags |= MODEL_ANIMATOR_FLAGS_8000;
animator->flags |= MODEL_ANIMATOR_FLAGS_MESH;
}
}
@ -877,4 +1177,139 @@ void reload_mesh_animator_tree(ModelAnimator* animator) {
set_animator_tree_to_node_map(animator, nodeIDs, ARRAY_COUNT(nodeIDs));
}
INCLUDE_ASM(s32, "B4580", step_mesh_animator);
s32 step_mesh_animator(ModelAnimator* animator) {
s16* args = animator->animReadPos;
s16* oldPos = animator->animReadPos;
AnimatorNode* node;
f32 x, y, z;
s32 flags;
s32 nodeId;
switch (*args++) {
case AS_END:
return -1;
case AS_SET_RENDER_MODE:
animator->renderMode = *args++;
animator->animReadPos = args;
return 1;
case AS_WAIT:
args++;
animator->animReadPos = args;
return 1;
case AS_END_LOOP:
animator->animReadPos = animator->savedReadPos;
animator->treeIndexPos = animator->savedTreePos;
reload_mesh_animator_tree(animator);
return 1;
case AS_OP_4:
animator->animReadPos = animator->savedReadPos;
animator->treeIndexPos = animator->savedTreePos;
break;
case AS_LOOP:
animator->animReadPos = animator->savedReadPos = args;
animator->savedTreePos = animator->treeIndexPos;
return 1;
case AS_SET_FLAGS:
flags = *args++;
animator->animReadPos = args;
animator->flags |= flags & 0xFFFF;
return 1;
case AS_SET_NODE_FLAGS:
node = get_animator_child_with_id(animator->rootNode, animator->staticNodeIDs[*args++ - 1]);
flags = *args++;
node->flags |= flags;
animator->animReadPos = args;
return 1;
case AS_CLEAR_NODE_FLAGS:
node = get_animator_child_with_id(animator->rootNode, animator->staticNodeIDs[*args++ - 1]);
flags = *args++;
node->flags &= ~flags;
animator->animReadPos = args;
return 1;
case AS_OP_19:
animator->flags |= MODEL_ANIMATOR_FLAGS_NO_FLIP;
animator->animReadPos = args;
return 1;
case AS_SET_ROTATION:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = (f32)*args++ * 180.0 / 32767.0;
y = (f32)*args++ * 180.0 / 32767.0;
z = (f32)*args++ * 180.0 / 32767.0;
animator->animReadPos = args;
if (nodeId != 0xFF) {
node = get_animator_child_with_id(animator->rootNode, nodeId);
if (node != NULL) {
node->rotation.x = x;
node->rotation.y = y;
node->rotation.z = z;
return 1;
} else {
animator->animReadPos = oldPos;
animator->treeIndexPos++;
break;
}
}
return 1;
case AS_ADD_ROTATION:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = (f32)*args++ * 180.0 / 32767.0;
y = (f32)*args++ * 180.0 / 32767.0;
z = (f32)*args++ * 180.0 / 32767.0;
animator->animReadPos = args;
if (nodeId != 0xFF) {
node = get_animator_child_with_id(animator->rootNode, nodeId);
if (node != NULL) {
node->rotation.x += x;
node->rotation.y += y;
node->rotation.z += z;
return 1;
} else {
animator->animReadPos = oldPos;
animator->treeIndexPos++;
break;
}
}
return 1;
case AS_SET_POS:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = *args++;
y = *args++;
z = *args++;
animator->animReadPos = args;
if (nodeId != 0xFF) {
node = get_animator_child_with_id(animator->rootNode, nodeId);
if (node != NULL) {
node->pos.x = x;
node->pos.y = y;
node->pos.z = z;
return 1;
} else {
animator->animReadPos = oldPos;
animator->treeIndexPos++;
break;
}
}
return 1;
case AS_SET_SCALE:
nodeId = animator->staticNodeIDs[*args++ - 1];
x = (f32)*args++ * 180.0 / 32767.0;
y = (f32)*args++ * 180.0 / 32767.0;
z = (f32)*args++ * 180.0 / 32767.0;
animator->animReadPos = args;
if (nodeId != 0xFF) {
node = get_animator_child_with_id(animator->rootNode, nodeId);
if (node != NULL) {
node->scale.x = x;
node->scale.y = y;
node->scale.z = z;
return 1;
} else {
animator->animReadPos = oldPos;
animator->treeIndexPos++;
break;
}
}
return 1;
}
return 0;
}

35
src/animation_script.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef ANIMATION_SCRIPT_H
#define ANIMATION_SCRIPT_H
#include "common.h"
typedef s16 AnimScript[];
enum {
AS_END,
AS_WAIT,
AS_OP_2,
AS_END_LOOP,
AS_OP_4,
AS_SET_ROTATION,
AS_ADD_ROTATION,
AS_OP_7,
AS_SET_POS,
AS_OP_9,
AS_LOOP,
AS_OP_11,
AS_OP_12,
AS_OP_13,
AS_SET_FLAGS,
AS_SET_NODE_FLAGS,
AS_CLEAR_NODE_FLAGS,
AS_SET_SCALE,
AS_SET_RENDER_MODE,
AS_OP_19,
};
#define _AS_ROUND(x) ((int) (x < 0 ? x - 0.5 : x + 0.5))
#define AS_F(x) (_AS_ROUND((x) * 32767.0 / 180.0))
#endif

View File

@ -112,25 +112,14 @@ BSS s8 D_801539C0[0x40];
BSS s8 D_80153A00[0x40];
BSS s32 gCurrentAnimMeshListPtr;
BSS s32 gAnimModelFogEnabled;
BSS s8 gAnimModelFogR;
BSS char D_80153A49;
BSS char D_80153A4A;
BSS s8 D_80153A4B;
BSS s8 gAnimModelFogG;
BSS char D_80153A4D;
BSS char D_80153A4E;
BSS s8 D_80153A4F;
BSS s8 gAnimModelFogB;
BSS char D_80153A51;
BSS char D_80153A52;
BSS s8 D_80153A53;
BSS s8 gAnimModelFogA;
BSS char D_80153A55;
BSS char D_80153A56;
BSS s8 D_80153A57;
BSS s32 gAnimModelFogR;
BSS s32 gAnimModelFogG;
BSS s32 gAnimModelFogB;
BSS s32 gAnimModelFogA;
BSS s32 gAnimModelFogStart;
BSS s32 gAnimModelFogEnd;
BSS s8 D_80153A60[0x8];
BSS s32 gAnimVtxSegment;
BSS char D_80153A64[0x4];
BSS s8 gAnimRotMtx[0x40];
BSS s8 gAnimScaleMtx[0x40];
BSS s8 gAnimTranslateMtx[0x40];

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
#include "common.h"
#include "map.h"
#include "animation_script.h"
#define NAMESPACE dgb_01
@ -30,7 +31,7 @@ extern EvtScript N(80244AD0);
extern EvtScript N(main);
extern EvtScript N(makeEntities);
extern StaticAnimatorNode* N(D_80252F4C_C107CC)[];
extern EvtScript N(D_802539A0_C11220);
extern AnimScript N(D_802539A0_C11220);
extern NpcGroupList N(npcGroupList_80246E50);
extern NpcGroupList N(npcGroupList_80246ED4);
extern NpcGroupList N(npcGroupList_80246E8C);

59
tools/disasm_animation.py Executable file
View File

@ -0,0 +1,59 @@
#! /usr/bin/python3
import struct
def read(f):
return struct.unpack('>h', f.read(2))[0]
def i2f(x):
return round(x * 180 / 32767 * 200) / 200
def parse(f):
print('AnimScript script = {')
indent = ' '
while True:
op = read(f)
if op == 0:
print(f'{indent}AS_END,')
break
if op == 1:
print(f'{indent}AS_WAIT, {read(f)},')
elif op == 3:
indent = indent[:-4]
print(f'{indent}AS_END_LOOP,')
elif op == 5:
print(f'{indent}AS_SET_ROTATION, {read(f)}, AS_F({i2f(read(f))}), AS_F({i2f(read(f))}), AS_F({i2f(read(f))}),')
elif op == 6:
print(f'{indent}AS_ADD_ROTATION, {read(f)}, AS_F({i2f(read(f))}), AS_F({i2f(read(f))}), AS_F({i2f(read(f))}),')
elif op == 8:
print(f'{indent}AS_SET_POS, {read(f)}, {read(f)}, {read(f)}, {read(f)},')
elif op == 10:
print(f'{indent}AS_LOOP,')
indent += ' '
elif op == 14:
print(f'{indent}AS_SET_FLAGS, {read(f)},')
elif op == 15:
print(f'{indent}AS_SET_NODE_FLAGS, {read(f)}, {read(f)},')
elif op == 16:
print(f'{indent}AS_CLEAR_NODE_FLAGS, {read(f)}, {read(f)},')
elif op == 17:
print(f'{indent}AS_SET_SCALE, {read(f)}, AS_F({i2f(read(f))}), AS_F({i2f(read(f))}), AS_F({i2f(read(f))}),')
elif op == 18:
print(f'{indent}AS_SET_RENDER_MODE, {read(f)}')
elif op == 19:
print(f'{indent}AS_OP_19,')
else:
raise Exception(str(f'Unknown opcode {op}'))
print('};')
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("file", type=str, help="File to dissassemble from")
parser.add_argument("offset", help="Offset to start dissassembling from")
args = parser.parse_args()
offset = int(args.offset, 16)
with open(args.file, "rb") as f:
f.seek(offset)
parse(f)

View File

@ -1,97 +0,0 @@
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
glabel animator_copy_vertices_to_buffer
/* B4580 8011DE80 27BDFFD8 */ addiu $sp, $sp, -0x28
/* B4584 8011DE84 AFB40020 */ sw $s4, 0x20($sp)
/* B4588 8011DE88 0080A02D */ daddu $s4, $a0, $zero
/* B458C 8011DE8C AFB3001C */ sw $s3, 0x1c($sp)
/* B4590 8011DE90 00A0982D */ daddu $s3, $a1, $zero
/* B4594 8011DE94 AFB00010 */ sw $s0, 0x10($sp)
/* B4598 8011DE98 00C0802D */ daddu $s0, $a2, $zero
/* B459C 8011DE9C AFB20018 */ sw $s2, 0x18($sp)
/* B45A0 8011DEA0 00E0902D */ daddu $s2, $a3, $zero
/* B45A4 8011DEA4 0000282D */ daddu $a1, $zero, $zero
/* B45A8 8011DEA8 3C038015 */ lui $v1, %hi(D_801533C0)
/* B45AC 8011DEAC 246333C0 */ addiu $v1, $v1, %lo(D_801533C0)
/* B45B0 8011DEB0 AFBF0024 */ sw $ra, 0x24($sp)
/* B45B4 8011DEB4 AFB10014 */ sw $s1, 0x14($sp)
/* B45B8 8011DEB8 000510C0 */ sll $v0, $a1, 3
.L8011DEBC:
/* B45BC 8011DEBC 00438821 */ addu $s1, $v0, $v1
/* B45C0 8011DEC0 8E220000 */ lw $v0, ($s1)
/* B45C4 8011DEC4 04400006 */ bltz $v0, .L8011DEE0
/* B45C8 8011DEC8 28A20060 */ slti $v0, $a1, 0x60
/* B45CC 8011DECC 24A50001 */ addiu $a1, $a1, 1
/* B45D0 8011DED0 28A20060 */ slti $v0, $a1, 0x60
/* B45D4 8011DED4 1440FFF9 */ bnez $v0, .L8011DEBC
/* B45D8 8011DED8 000510C0 */ sll $v0, $a1, 3
/* B45DC 8011DEDC 28A20060 */ slti $v0, $a1, 0x60
.L8011DEE0:
/* B45E0 8011DEE0 14400003 */ bnez $v0, .L8011DEF0
/* B45E4 8011DEE4 00000000 */ nop
.L8011DEE8:
/* B45E8 8011DEE8 080477BA */ j .L8011DEE8
/* B45EC 8011DEEC 00000000 */ nop
.L8011DEF0:
/* B45F0 8011DEF0 8FA40038 */ lw $a0, 0x38($sp)
/* B45F4 8011DEF4 02442021 */ addu $a0, $s2, $a0
/* B45F8 8011DEF8 0C00AB0A */ jal general_heap_malloc
/* B45FC 8011DEFC 00042100 */ sll $a0, $a0, 4
/* B4600 8011DF00 0040382D */ daddu $a3, $v0, $zero
/* B4604 8011DF04 14E00003 */ bnez $a3, .L8011DF14
/* B4608 8011DF08 AE270004 */ sw $a3, 4($s1)
.L8011DF0C:
/* B460C 8011DF0C 080477C3 */ j .L8011DF0C
/* B4610 8011DF10 00000000 */ nop
.L8011DF14:
/* B4614 8011DF14 24020003 */ addiu $v0, $zero, 3
/* B4618 8011DF18 AE220000 */ sw $v0, ($s1)
/* B461C 8011DF1C 8FA2003C */ lw $v0, 0x3c($sp)
/* B4620 8011DF20 8E6300FC */ lw $v1, 0xfc($s3)
/* B4624 8011DF24 8E8400D8 */ lw $a0, 0xd8($s4)
/* B4628 8011DF28 00021100 */ sll $v0, $v0, 4
/* B462C 8011DF2C 10800005 */ beqz $a0, .L8011DF44
/* B4630 8011DF30 00621821 */ addu $v1, $v1, $v0
/* B4634 8011DF34 3C0200FF */ lui $v0, 0xff
/* B4638 8011DF38 3442FFFF */ ori $v0, $v0, 0xffff
/* B463C 8011DF3C 02022824 */ and $a1, $s0, $v0
/* B4640 8011DF40 00A48021 */ addu $s0, $a1, $a0
.L8011DF44:
/* B4644 8011DF44 1A400019 */ blez $s2, .L8011DFAC
/* B4648 8011DF48 0000282D */ daddu $a1, $zero, $zero
/* B464C 8011DF4C 26060004 */ addiu $a2, $s0, 4
/* B4650 8011DF50 24E40004 */ addiu $a0, $a3, 4
.L8011DF54:
/* B4654 8011DF54 8C680000 */ lw $t0, ($v1)
/* B4658 8011DF58 8C690004 */ lw $t1, 4($v1)
/* B465C 8011DF5C 8C6A0008 */ lw $t2, 8($v1)
/* B4660 8011DF60 8C6B000C */ lw $t3, 0xc($v1)
/* B4664 8011DF64 ACE80000 */ sw $t0, ($a3)
/* B4668 8011DF68 ACE90004 */ sw $t1, 4($a3)
/* B466C 8011DF6C ACEA0008 */ sw $t2, 8($a3)
/* B4670 8011DF70 ACEB000C */ sw $t3, 0xc($a3)
/* B4674 8011DF74 96020000 */ lhu $v0, ($s0)
/* B4678 8011DF78 26100006 */ addiu $s0, $s0, 6
/* B467C 8011DF7C 24630010 */ addiu $v1, $v1, 0x10
/* B4680 8011DF80 24A50001 */ addiu $a1, $a1, 1
/* B4684 8011DF84 A4E20000 */ sh $v0, ($a3)
/* B4688 8011DF88 94C2FFFE */ lhu $v0, -2($a2)
/* B468C 8011DF8C 24E70010 */ addiu $a3, $a3, 0x10
/* B4690 8011DF90 A482FFFE */ sh $v0, -2($a0)
/* B4694 8011DF94 94C20000 */ lhu $v0, ($a2)
/* B4698 8011DF98 24C60006 */ addiu $a2, $a2, 6
/* B469C 8011DF9C A4820000 */ sh $v0, ($a0)
/* B46A0 8011DFA0 00B2102A */ slt $v0, $a1, $s2
/* B46A4 8011DFA4 1440FFEB */ bnez $v0, .L8011DF54
/* B46A8 8011DFA8 24840010 */ addiu $a0, $a0, 0x10
.L8011DFAC:
/* B46AC 8011DFAC 8E220004 */ lw $v0, 4($s1)
/* B46B0 8011DFB0 8FBF0024 */ lw $ra, 0x24($sp)
/* B46B4 8011DFB4 8FB40020 */ lw $s4, 0x20($sp)
/* B46B8 8011DFB8 8FB3001C */ lw $s3, 0x1c($sp)
/* B46BC 8011DFBC 8FB20018 */ lw $s2, 0x18($sp)
/* B46C0 8011DFC0 8FB10014 */ lw $s1, 0x14($sp)
/* B46C4 8011DFC4 8FB00010 */ lw $s0, 0x10($sp)
/* B46C8 8011DFC8 03E00008 */ jr $ra
/* B46CC 8011DFCC 27BD0028 */ addiu $sp, $sp, 0x28

View File

@ -1,391 +0,0 @@
.set noat # allow manual use of $at
.set noreorder # don't insert nops after branches
.section .rodata
dlabel jtbl_8014FEE0
.word .L8011F63C_B5D3C, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F66C_B5D6C, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F69C_B5D9C, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F6CC_B5DCC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F6FC_B5DFC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F9FC_B60FC, .L8011F72C_B5E2C, .L8011F9FC_B60FC, .L8011F9FC_B60FC