34 for (i = 0; i < 9; i += 3) {
48 for (; key->pad < model->
frame; key++) {
63 if (i == 6 && (prev.vx == 0 || prev.vy == 0 || prev.vz == 0 || cur.vx == 0 || cur.vy == 0 || cur.vz == 0)) {
68 diff.vx = cur.vx - prev.vx;
69 diff.vy = cur.vy - prev.vy;
70 diff.vz = cur.vz - prev.vz;
96 for (i = 0; i < 9; i += 3) {
112 if (key->pad == frame) {
116 if (key->pad >= frame) {
125 span = cur.pad - prev.pad;
126 gte_lddp(((frame - prev.pad) << 12) / span);
127 diff.vx = cur.vx - prev.vx;
128 diff.vy = cur.vy - prev.vy;
129 diff.vz = cur.vz - prev.vz;
148 if (model->
move.
xy != 0 || model->
move.
v.vz != 0) {
156 model->
move.
v.vz = 0;
157 model->
move.
v.vy = 0;
158 model->
move.
v.vx = 0;
162 for (i = 1, bone++; i < model->
boneCount; i++, bone++) {
166 for (i = 1, bone++; i < model->
boneCount; i++, bone++) {
177 for (i = 0; i < model->
boneCount; i++, bone++) {
193 if (restart != 1 && model->
motion == motion) {
202 while (step->
index != 0x7FFF) {
216 if (step->
index != 0) {
221 for (i = 0; i < n; i++) {
224 model->
keyframes[count] = (((i + 1) << 12) / (n + 1)) | 0x8000;
228 for (i = 0; i < n; i++) {
253 for (i = 1, bone++; i < model->
boneCount; i++, bone++) {
310 switch (model->
state) {
318 for (b = 0, linked = model->
bones; b < model->
boneCount; b++, linked++) {
367 for (i = 0, bone = model->
bones; i < model->
boneCount; i++, bone++) {
368 scale.vx = bone->
scale.vx;
369 scale.vy = bone->
scale.vy;
370 scale.vz = bone->
scale.vz;
371 if ((scale.vx | scale.vy | scale.vz) <= 48) {
375 RotMatrixZYX_gte(&bone->
rot, &bone->
local);
376 ScaleMatrix(&bone->
local, &scale);
383 for (j = 0; j < 2; j++) {
385 for (d = 0, drawn = model->
bones; d < model->
boneCount; d++, drawn++) {
386 if (d != 0 && drawn->
visible) {
415 for (i = 0; i < 2; i++) {
421 children[j + 1]->
color = *color;
437 for (i = 0; i < 2; i++) {
453 s32 high = file & 0xFFFF0000;
455 s32 count = entry[1] + 1;
482 for (i = 1; i < count; i++) {
509 s32 count = normal->
x;
518 gte_CompMatrix(&GsLIGHTWSMATRIX, &mesh->
matrix, &light);
544 s32 count = vertex->
x;
571 *depth++ = z >> shift;
598 setSemiTrans(state->
prim.
gt4, 1);
607 setSemiTrans(state->
prim.
gt3, 1);
628 setSemiTrans(state->
prim.
ft4, 1);
637 setSemiTrans(state->
prim.
ft3, 1);
670 for (i = 0; i < 9; ) {
674 x = layer->
env.clip.x - 64;
676 w = layer->
env.clip.w + 128;
677 right = x + w - layer->
offsetX;
678 y = layer->
env.clip.y - 64;
680 h = layer->
env.clip.h + 128;
681 bottom = y + h - layer->
offsetY;
687 if (screen.vx >= left && screen.vx <= right && screen.vy >= top && screen.vy <= bottom) {
701 state->
u = state->
cmd[1] + (state->
cmd[2] << 8);
702 state->
v = state->
cmd[3];
705 cy = state->
cmd[5] + y;
707 state->
clut = getClut(cx, cy);
708 state->
tpage = getTPage(tp, state->
abr ? state->
abr - 1 : 0, x + (state->
cmd[2] << 6), y);
745 if (state->
sxy[0] == state->
sxy[1] || state->
sxy[0] == state->
sxy[2] ||
746 state->
sxy[1] == state->
sxy[2]) {
749 if (state->
quad && (state->
sxy[0] == state->
sxy[3] || state->
sxy[1] == state->
sxy[3] ||
750 state->
sxy[2] == state->
sxy[3])) {
758 p = state->
cmd + (state->
quad + 3);
768 q = state->
cmd + (state->
lit ? k + (state->
quad + 3) : k);
769 state->
uv[0][0] = q[0] + state->
u;
770 state->
uv[0][1] = q[1] + state->
v;
771 state->
uv[1][0] = q[2] + state->
u;
772 state->
uv[1][1] = q[3] + state->
v;
773 state->
uv[2][0] = q[4] + state->
u;
774 state->
uv[2][1] = q[5] + state->
v;
776 state->
uv[3][0] = q[6] + state->
u;
777 state->
uv[3][1] = q[7] + state->
v;
780 otz = state->
depth[i0];
781 z1 = state->
depth[i1];
782 z2 = state->
depth[i2];
784 gte_AverageZ4(otz, z1, z2, state->
depth[i3], &otz);
786 gte_AverageZ3(otz, z1, z2, &otz);
806 }
while (*state->
cmd == 0);
823 gte_CompMatrix(&GsWSMATRIX, &mesh->
matrix, &m);
838 while (*state.
cmd != 0xFF) {
881 state.
color[lo - 2].r = state.
cmd[1];
882 state.
color[lo - 2].g = state.
cmd[2];
883 state.
color[lo - 2].b = state.
cmd[3];
900static inline u_long
linkTag(u_long tag, u_long addr) {
901 u_long word = tag & 0xFF000000;
919 gte_CompMatrix(&GsWSMATRIX, &mesh->
matrix, &m);
934 while (*state.
cmd != 0xFF) {
1013 }
while (*state.
cmd == 0);
1040 switch (mesh->
state) {
Battle FIGHTSTG_battle
the battle: its fighters, speed and drawing functions
#define BATTLE_TASK_MODEL
a model (FIGHTSTG_updateModel)
FIGHTSTG.PRO: the battle.
GfxState GFX
GFX: the graphics state and its methods.
#define TASK_INIT
Tasks: every game object is a task, a heap block that starts with this header and is updated once per...
Face * FIGHTSTG_createFace(Model *model, s32 fighter)
Creates the face of fighter's model, with its parts (FIGHTSTG_fighterCache.getFace); none for fighter...
FileCache FILE_CACHE
The file cache.
The GTE instructions that C can't say, as the SDK's inline_c.h has them but with the real encodings i...
#define gte_rtps()
V0 through RT and TR, then the perspective (SXY2, SZ3)
#define gte_lddp(r0)
the interpolation factor (IR0)
#define gte_ldv0(r0)
an SVECTOR into V0
#define gte_rtv0()
MAC1-MAC3 = RT * V0 >> 12.
#define gte_SetLightMatrix(r0)
a MATRIX's rotation into the GTE's light matrix (L)
#define gte_ldsv(r0)
an SVECTOR into IR1-IR3
#define gte_stopz(r0)
MAC0 into a word.
#define gte_strgb(r0)
RGB2 into a word.
#define gte_stszotz(r0)
SZ3 / 4 into a word, the depth in the ordering table.
#define gte_stsv(r0)
IR1-IR3 into an SVECTOR.
#define gte_SetTransMatrix(r0)
a MATRIX's translation into the GTE (TR)
#define gte_ncs()
the color of V0 as a normal under the lights (RGB2)
#define gte_stsxy(r0)
SXY2 into a word.
#define gte_stflg(r0)
the flags into a word
#define gte_nclip()
MAC0 = the winding of SXY0-SXY2, which side of a polygon faces us.
#define gte_stlvnl(r0)
MAC1-MAC3 into a VECTOR.
#define gte_ldsxy3(r0, r1, r2)
three screen points (SXY0-SXY2)
#define gte_SetRotMatrix(r0)
a MATRIX's rotation into the GTE (RT)
#define gte_gpf12()
IR1-IR3 = IR0 * IR1-IR3 >> 12.
#define gte_ldv0_unaligned(r0)
an SVECTOR that may not be word aligned into V0
Heap HEAP
The functions that return what a call left in v0 (allocMemHigh, findTask) and the ones that take othe...
MATRIX IDENTITY_MATRIX
the root bone's parent (src/engine/data/matrices.c)
void FIGHTSTG_saveBlendPose(Model *model)
Saves each bone's pose as the one a blend starts from.
s32 FIGHTSTG_isMotionDone(Model *model)
Model.isMotionDone.
void FIGHTSTG_drawMeshWireframe(Mesh *mesh, Layer *layer)
Draws a Mesh as wireframe: each polygon of its command runs as a green LINE_F4 through its screen poi...
void FIGHTSTG_addMeshPolyGT(MeshDrawState *state)
Adds the polygon in state as a gouraud-shaded textured triangle or quad; the colors,...
void FIGHTSTG_blendBone(Model *model, ModelBone *bone)
Blends a bone's position, rotation and scale from the saved pose (FIGHTSTG_saveBlendPose) towards the...
s32 FIGHTSTG_unused0
the variables that end the file: zeros after camera_task.c's data, which the objects after this one r...
void FIGHTSTG_queueMeshWireframe(Mesh *mesh, s32 layerId, MATRIX *matrix)
Mesh.drawWireframe: has the layer draw the Mesh as wireframe (FIGHTSTG_drawMeshWireframe) with MATRIX...
void FIGHTSTG_setModelColor(Model *model, s32 mode, CVECTOR *color)
Model.setColor: sets the color mode, and the color unless COLOR is NULL, of the meshes of each bone b...
static void drawMeshPolygons(MeshDrawState *state)
Draws a run of polygons: adds each one that faces the camera to the ordering table,...
Model * FIGHTSTG_createModel(s32 file, s32 motionFile, Vec2 texPos, ModelControl *control, s32 hasIdle)
Creates a model (registered as BATTLE_TASK_MODEL) from the bone list in FILE: each bone's parent,...
static void setMeshTexture(MeshDrawState *state)
Sets the texture page, the CLUT and the UV offset from a command's bytes.
s32 FIGHTSTG_isMeshOnScreen(Mesh *mesh, Layer *layer)
Whether a Mesh may be on screen: the screen positions of the 9 points of its bounds against the layer...
void FIGHTSTG_projectMesh(Mesh *mesh, Layer *layer)
The screen positions of a Mesh's vertices and their depths in the layer's ordering table.
u_long FIGHTSTG_cursorBarOt[2]
and their ordering table
void FIGHTSTG_queueMeshDraw(Mesh *mesh, s32 layerId, MATRIX *matrix)
Mesh.draw: has the layer draw the Mesh (FIGHTSTG_drawMesh) with MATRIX.
void FIGHTSTG_updateMesh(Mesh *mesh)
The Mesh's task: frees its screen positions, depths and colors when killed.
Model * FIGHTSTG_createIdlingModel(s32 file, s32 motionFile, Vec2 texPos, ModelControl *control)
A model whose motions go back to its idle motion (FIGHTSTG_createModel): the fighters'.
void FIGHTSTG_drawMesh(void *arg, Layer *layer)
A layer callback that draws a Mesh: walks its command bytes (see MeshDrawState), setting its texture ...
void FIGHTSTG_addMeshPolyFT(MeshDrawState *state)
The same as a flat-shaded textured triangle or quad.
DR_MOVE FIGHTSTG_cursorBarMoves[4]
FIGHTSTG_drawCursorBar draws its bar with them.
void FIGHTSTG_lightMesh(Mesh *mesh)
The colors of a Mesh's normals under the lights, through its matrix.
BattleEvent FIGHTSTG_newEvent
what FIGHTSTG_pushEvent is given
void FIGHTSTG_updateModel(Model *model, Mesh **children)
The model's task: loads its textures and makes its meshes and face, then each frame follows its contr...
void FIGHTSTG_poseBones(Model *model, Mesh **children)
Moves the root bone by the model's move along its rotation, then poses (FIGHTSTG_poseBone) or blends ...
Model * FIGHTSTG_createPlainModel(s32 file, s32 motionFile, Vec2 texPos, ModelControl *control)
A model whose motions just end (FIGHTSTG_createModel)
static u_long linkTag(u_long tag, u_long addr)
A primitive tag's word with its address replaced: the top byte of tag and the low 24 bits of addr.
RECT FIGHTSTG_fighterCameraRect
FIGHTSTG_updatePartnerView's layer.
CameraView FIGHTSTG_fighterView
the view FIGHTSTG_getFighterView makes
void FIGHTSTG_setBoneNoBoundsCheck(Model *model, s32 bone, s32 value)
Model.setBoneNoBoundsCheck: sets bone's Mesh noBoundsCheck when either of the control's layers is ena...
s32 FIGHTSTG_partnerIdleMotion
the partner's idle motion while stage 0x1D is up
void FIGHTSTG_poseBone(Model *model, ModelBone *bone, s32 frame)
Sets a bone's position, rotation and scale to their keys at FRAME, interpolated between the keys arou...
void FIGHTSTG_setMotion(Model *model, s32 motion, s32 restart)
Model.setMotion: lays out the motion's keyframes.
Mesh * FIGHTSTG_createMesh(void *archive, Vec2 texPos)
Creates a Mesh from an archive: its vertices (entry 0), normals (1), commands (2) and bounds (5)
void FIGHTSTG_stepMotion(Model *model)
Steps a model's motion by the frames gone by, blending into a new pose where a keyframe has 0x8000,...
An event of the battle, as it is queued (FIGHTSTG_pushEvent)
s32 frames
since the last update
Where the battle camera looks from and to, as a GsRVIEW2 with the transform of its coordinate system.
void *(* getArchiveEntry)(s32 index, void *archive)
void *(* getEntry)(u32 fileAndIndex)
struct Layer *(* getLayer)(s32 id)
void(* setPrim)(void *next)
void *(* alloc)(s32 size, s32 tag)
A drawing layer (GFX.funcs.createLayer): a DRAWENV with a pair of ordering tables,...
u_long *(* getOt)(struct Layer *)
A Mesh's drawing state while its drawer (FIGHTSTG_drawMesh) walks its command bytes: a high nibble of...
s32 abr
the semi-transparency mode + 1, 0 for opaque
s32 unk8
the 0xA nibble: on the disc, 0 but in two effect meshes; nothing reads it
CVECTOR colors[4]
the polygon's vertex colors
s32 sxy[4]
the polygon's screen points
s32 unk4
the 0xB nibble: on the disc, 1 on the textured polygons that are not lit and 0 on those that are; not...
union MeshDrawState::@2 prim
u_long * tag
the primitive's first word
Draws one bone of a Model (FIGHTSTG_createMesh), from the parts of an archive.
ShortVec3 * normals
the count in [0].x, then the normals
CVECTOR * colors
its normals' colors under the lights
ShortVec3 * bounds
9 points (FIGHTSTG_isMeshOnScreen)
void(* drawWireframe)(struct Mesh *mesh, s32 layerId, MATRIX *matrix)
s32 colorMode
Model.setColor's.
ShortVec3 * vertices
the count in [0].x, then the vertices
u8 * commands
see MeshDrawState
s32 * depth
and their depths in the ordering table
void(* draw)(struct Mesh *mesh, s32 layerId, MATRIX *matrix)
s32 * screen
where its vertices land on screen
One part of a Model: a mesh (Mesh) placed by a matrix relative to its parent's.
SVECTOR prevPos
the pose the motion blends from
s32 visible
0 while its scale is tiny
s32 keyFile
its keys' file: positions, rotations and scales by frame
s32 file
the mesh's file and index
What drives a Model, owned by whoever created it.
s32 restart
play it again from the start
s32 wireframe
they are drawn as wireframe (Mesh.drawWireframe)
s32 layerId
the layer its meshes are drawn in
struct ModelControl::@3 layers[2]
the model is drawn once for each one enabled
s32 motion
the motion to play
s32 fighter
the Models task's
A 3D model (FIGHTSTG_createModel), registered with id 0x11: a tree of bones, each drawn by a Mesh chi...
s32 xy
vx and vy as one word
Vec2 texPos
where its textures go in VRAM
u16 blendSources[0x640]
and the one it blends from, 0xFFFF for the saved pose
u16 blendTargets[0x640]
the frame a blending keyframe blends into
SVECTOR v
moves the root bone, along its rotation
s32(* isMotionDone)(struct Model *model)
s32 toIdle
the motion ends in the idle motion
s32 idleFrames[2]
where the two idle motions start
void(* setColor)()
(model, mode, color): its meshes'
void(* setMotion)(struct Model *model, s32 motion, s32 restart)
void(* setBoneNoBoundsCheck)()
s32 hasIdle
it goes back to its idle motion
s32 blend
how far, in 4096ths
void(* nextState)(struct Model *task)
s32 blendTarget
the frame it blends into, 0 for none
A motion in the motions' archive: its keyframes, step by step.
s16 index
0x7FFF ends them
s16 count
frames, 0 for the last one
s16 endFrame
the frame it ends on; 0: it blends into the next one
A position or rotation, without the SVECTOR pad.
Uploads TIM images to VRAM (initTimLoader); acts on TIM_LOADER.
void(* setImagePos)()
(x, y)
void(* loadArchive)()
(archive): each image 64 halfwords to the right
void * createTask(void(*update)(), s32 size, s32 childrenSize)
createTaskWithId for a task nothing needs to find
void * createTaskWithId(void(*update)(), s32 size, s32 childrenSize, s32 id)
Allocates a zeroed task of size bytes (header included) with room for childrenSize / 4 child tasks.
void initTimLoader(TimLoader *obj)
Clears a TIM loader, gives it its methods and binds it.