2020-05-19 14:39:01 +02:00
# ifndef _SM64_TYPES_H_
# define _SM64_TYPES_H_
2019-08-25 06:46:40 +02:00
// This file contains various data types used in Super Mario 64 that don't yet
// have an appropriate header.
# include <ultra64.h>
2019-11-03 20:36:27 +01:00
# include "macros.h"
2019-08-25 06:46:40 +02:00
2020-02-03 06:51:26 +01:00
// Certain functions are marked as having return values, but do not
// actually return a value. This causes undefined behavior, which we'd rather
// avoid on modern GCC. This only impacts -O2 and can matter for both the function
// itself and functions that call it.
# ifdef AVOID_UB
# define BAD_RETURN(cmd) void
# else
# define BAD_RETURN(cmd) cmd
# endif
2019-08-25 06:46:40 +02:00
struct Controller
{
/*0x00*/ s16 rawStickX ; //
/*0x02*/ s16 rawStickY ; //
/*0x04*/ float stickX ; // [-64, 64] positive is right
/*0x08*/ float stickY ; // [-64, 64] positive is up
/*0x0C*/ float stickMag ; // distance from center [0, 64]
/*0x10*/ u16 buttonDown ;
/*0x12*/ u16 buttonPressed ;
/*0x14*/ OSContStatus * statusData ;
/*0x18*/ OSContPad * controllerData ;
2020-04-03 20:57:26 +02:00
/*0x1C*/ int port ;
2020-06-20 16:22:33 +02:00
/*ext */ s16 extStickX ; // additional (right) stick values
/*ext */ s16 extStickY ;
2019-08-25 06:46:40 +02:00
} ;
typedef f32 Vec2f [ 2 ] ;
typedef f32 Vec3f [ 3 ] ; // X, Y, Z, where Y is up
typedef s16 Vec3s [ 3 ] ;
typedef s32 Vec3i [ 3 ] ;
typedef f32 Vec4f [ 4 ] ;
typedef s16 Vec4s [ 4 ] ;
typedef f32 Mat4 [ 4 ] [ 4 ] ;
2019-11-03 20:36:27 +01:00
typedef uintptr_t GeoLayout ;
typedef uintptr_t LevelScript ;
typedef s16 Movtex ;
typedef s16 MacroObject ;
typedef s16 Collision ;
typedef s16 Trajectory ;
typedef s16 PaintingData ;
typedef uintptr_t BehaviorScript ;
2019-08-25 06:46:40 +02:00
enum SpTaskState {
SPTASK_STATE_NOT_STARTED ,
SPTASK_STATE_RUNNING ,
SPTASK_STATE_INTERRUPTED ,
SPTASK_STATE_FINISHED ,
SPTASK_STATE_FINISHED_DP
} ;
struct SPTask
{
/*0x00*/ OSTask task ;
/*0x40*/ OSMesgQueue * msgqueue ;
/*0x44*/ OSMesg msg ;
/*0x48*/ enum SpTaskState state ;
} ; // size = 0x4C, align = 0x8
struct VblankHandler
{
OSMesgQueue * queue ;
OSMesg msg ;
} ;
# define ANIM_FLAG_NOLOOP (1 << 0) // 0x01
# define ANIM_FLAG_FORWARD (1 << 1) // 0x02
# define ANIM_FLAG_2 (1 << 2) // 0x04
# define ANIM_FLAG_HOR_TRANS (1 << 3) // 0x08
# define ANIM_FLAG_VERT_TRANS (1 << 4) // 0x10
# define ANIM_FLAG_5 (1 << 5) // 0x20
# define ANIM_FLAG_6 (1 << 6) // 0x40
# define ANIM_FLAG_7 (1 << 7) // 0x80
struct Animation {
/*0x00*/ s16 flags ;
/*0x02*/ s16 unk02 ;
/*0x04*/ s16 unk04 ;
/*0x06*/ s16 unk06 ;
/*0x08*/ s16 unk08 ;
/*0x0A*/ s16 unk0A ;
2019-11-03 20:36:27 +01:00
/*0x0C*/ const s16 * values ;
/*0x10*/ const u16 * index ;
2019-08-25 06:46:40 +02:00
/*0x14*/ u32 length ; // only used with Mario animations to determine how much to load. 0 otherwise.
} ;
2019-11-03 20:36:27 +01:00
# define ANIMINDEX_NUMPARTS(animindex) (sizeof(animindex) / sizeof(u16) / 6 - 1)
2019-08-25 06:46:40 +02:00
struct GraphNode
{
/*0x00*/ s16 type ; // structure type
/*0x02*/ s16 flags ; // hi = drawing layer, lo = rendering modes
/*0x04*/ struct GraphNode * prev ;
/*0x08*/ struct GraphNode * next ;
/*0x0C*/ struct GraphNode * parent ;
/*0x10*/ struct GraphNode * children ;
} ;
// struct AnimInfo?
struct GraphNodeObject_sub
{
/*0x00 0x38*/ s16 animID ;
/*0x02 0x3A*/ s16 animYTrans ;
/*0x04 0x3C*/ struct Animation * curAnim ;
/*0x08 0x40*/ s16 animFrame ;
/*0x0A 0x42*/ u16 animTimer ;
/*0x0C 0x44*/ s32 animFrameAccelAssist ;
/*0x10 0x48*/ s32 animAccel ;
2020-07-29 03:28:12 +02:00
s16 prevAnimFrame ;
s16 prevAnimID ;
u32 prevAnimFrameTimestamp ;
struct Animation * prevAnimPtr ;
2019-08-25 06:46:40 +02:00
} ;
struct GraphNodeObject
{
/*0x00*/ struct GraphNode node ;
/*0x14*/ struct GraphNode * sharedChild ;
/*0x18*/ s8 unk18 ;
/*0x19*/ s8 unk19 ;
/*0x1A*/ Vec3s angle ;
/*0x20*/ Vec3f pos ;
2020-07-29 03:28:12 +02:00
Vec3s prevAngle ;
Vec3f prevPos ;
u32 prevTimestamp ;
Vec3f prevShadowPos ;
u32 prevShadowPosTimestamp ;
2019-08-25 06:46:40 +02:00
/*0x2C*/ Vec3f scale ;
2020-07-29 03:28:12 +02:00
Vec3f prevScale ;
u32 prevScaleTimestamp ;
2019-08-25 06:46:40 +02:00
/*0x38*/ struct GraphNodeObject_sub unk38 ;
/*0x4C*/ struct SpawnInfo * unk4C ;
2020-07-04 17:18:55 +02:00
/*0x50*/ Mat4 * throwMatrix ; // matrix ptr
2020-07-29 03:28:12 +02:00
Mat4 prevThrowMatrix ;
u32 prevThrowMatrixTimestamp ;
Mat4 * throwMatrixInterpolated ;
2019-08-25 06:46:40 +02:00
/*0x54*/ Vec3f cameraToObject ;
2020-07-29 03:28:12 +02:00
u32 skipInterpolationTimestamp ;
2019-08-25 06:46:40 +02:00
} ;
struct ObjectNode
{
struct GraphNodeObject gfx ;
struct ObjectNode * next ;
struct ObjectNode * prev ;
} ;
2019-11-03 20:36:27 +01:00
// NOTE: Since ObjectNode is the first member of Object, it is difficult to determine
// whether some of these pointers point to ObjectNode or Object.
2019-08-25 06:46:40 +02:00
struct Object
{
/*0x000*/ struct ObjectNode header ;
/*0x068*/ struct Object * parentObj ;
/*0x06C*/ struct Object * prevObj ;
/*0x070*/ u32 collidedObjInteractTypes ;
/*0x074*/ s16 activeFlags ;
/*0x076*/ s16 numCollidedObjs ;
/*0x078*/ struct Object * collidedObjs [ 4 ] ;
/*0x088*/
union
{
// Object fields. See object_fields.h.
u32 asU32 [ 0x50 ] ;
s32 asS32 [ 0x50 ] ;
s16 asS16 [ 0x50 ] [ 2 ] ;
f32 asF32 [ 0x50 ] ;
2019-11-03 20:36:27 +01:00
# if !IS_64_BIT
2019-08-25 06:46:40 +02:00
s16 * asS16P [ 0x50 ] ;
s32 * asS32P [ 0x50 ] ;
2019-10-05 21:08:05 +02:00
struct Animation * * asAnims [ 0x50 ] ;
2019-08-25 06:46:40 +02:00
struct Waypoint * asWaypoint [ 0x50 ] ;
struct ChainSegment * asChainSegment [ 0x50 ] ;
struct Object * asObject [ 0x50 ] ;
struct Surface * asSurface [ 0x50 ] ;
void * asVoidPtr [ 0x50 ] ;
2019-11-03 20:36:27 +01:00
const void * asConstVoidPtr [ 0x50 ] ;
# endif
2019-08-25 06:46:40 +02:00
} rawData ;
2019-11-03 20:36:27 +01:00
# if IS_64_BIT
union {
s16 * asS16P [ 0x50 ] ;
s32 * asS32P [ 0x50 ] ;
struct Animation * * asAnims [ 0x50 ] ;
struct Waypoint * asWaypoint [ 0x50 ] ;
struct ChainSegment * asChainSegment [ 0x50 ] ;
struct Object * asObject [ 0x50 ] ;
struct Surface * asSurface [ 0x50 ] ;
void * asVoidPtr [ 0x50 ] ;
const void * asConstVoidPtr [ 0x50 ] ;
} ptrData ;
# endif
2019-10-05 21:08:05 +02:00
/*0x1C8*/ u32 unused1 ;
2020-04-03 20:57:26 +02:00
/*0x1CC*/ const BehaviorScript * curBhvCommand ;
/*0x1D0*/ u32 bhvStackIndex ;
/*0x1D4*/ uintptr_t bhvStack [ 8 ] ;
/*0x1F4*/ s16 bhvDelayTimer ;
2019-08-25 06:46:40 +02:00
/*0x1F6*/ s16 respawnInfoType ;
/*0x1F8*/ f32 hitboxRadius ;
/*0x1FC*/ f32 hitboxHeight ;
/*0x200*/ f32 hurtboxRadius ;
/*0x204*/ f32 hurtboxHeight ;
/*0x208*/ f32 hitboxDownOffset ;
2019-11-03 20:36:27 +01:00
/*0x20C*/ const BehaviorScript * behavior ;
2020-08-02 04:03:26 +02:00
/*0x210*/ u32 heldByPlayerIndex ;
2019-08-25 06:46:40 +02:00
/*0x214*/ struct Object * platform ;
/*0x218*/ void * collisionData ;
/*0x21C*/ Mat4 transform ;
/*0x25C*/ void * respawnInfo ;
} ;
struct ObjectHitbox
{
/*0x00*/ u32 interactType ;
/*0x04*/ u8 downOffset ;
/*0x05*/ s8 damageOrCoinValue ;
/*0x06*/ s8 health ;
/*0x07*/ s8 numLootCoins ;
/*0x08*/ s16 radius ;
/*0x0A*/ s16 height ;
/*0x0C*/ s16 hurtboxRadius ;
/*0x0E*/ s16 hurtboxHeight ;
} ;
struct Waypoint
{
s16 flags ;
Vec3s pos ;
} ;
struct Surface
{
/*0x00*/ s16 type ;
/*0x02*/ s16 force ;
/*0x04*/ s8 flags ;
/*0x05*/ s8 room ;
/*0x06*/ s16 lowerY ;
/*0x08*/ s16 upperY ;
/*0x0A*/ Vec3s vertex1 ;
/*0x10*/ Vec3s vertex2 ;
/*0x16*/ Vec3s vertex3 ;
/*0x1C*/ struct {
f32 x ;
f32 y ;
f32 z ;
} normal ;
/*0x28*/ f32 originOffset ;
/*0x2C*/ struct Object * object ;
2020-07-29 03:28:12 +02:00
Vec3s prevVertex1 ;
Vec3s prevVertex2 ;
Vec3s prevVertex3 ;
u32 modifiedTimestamp ;
2019-08-25 06:46:40 +02:00
} ;
struct MarioBodyState
{
/*0x00*/ u32 action ;
2020-02-03 06:51:26 +01:00
/*0x04*/ s8 capState ; /// see MarioCapGSCId
2019-08-25 06:46:40 +02:00
/*0x05*/ s8 eyeState ;
/*0x06*/ s8 handState ;
2020-02-03 06:51:26 +01:00
/*0x07*/ s8 wingFlutter ; /// whether Mario's wing cap wings are fluttering
2019-08-25 06:46:40 +02:00
/*0x08*/ s16 modelState ;
/*0x0A*/ s8 grabPos ;
2020-02-03 06:51:26 +01:00
/*0x0B*/ u8 punchState ; /// 2 bits for type of punch, 6 bits for punch animation timer
/*0x0C*/ Vec3s torsoAngle ;
/*0x12*/ Vec3s headAngle ;
/*0x18*/ Vec3f heldObjLastPosition ; /// also known as HOLP
2019-10-05 21:08:05 +02:00
u8 padding [ 4 ] ;
} ;
2019-11-03 20:36:27 +01:00
struct OffsetSizePair
2019-10-05 21:08:05 +02:00
{
u32 offset ;
u32 size ;
2019-08-25 06:46:40 +02:00
} ;
struct MarioAnimDmaRelatedThing
{
2019-10-05 21:08:05 +02:00
u32 count ;
u8 * srcAddr ;
2019-11-03 20:36:27 +01:00
struct OffsetSizePair anim [ 1 ] ; // dynamic size
2019-08-25 06:46:40 +02:00
} ;
struct MarioAnimation
{
struct MarioAnimDmaRelatedThing * animDmaTable ;
2019-10-05 21:08:05 +02:00
u8 * currentAnimAddr ;
2019-08-25 06:46:40 +02:00
struct Animation * targetAnim ;
u8 padding [ 4 ] ;
} ;
struct MarioState
{
/*0x00*/ u16 unk00 ;
/*0x02*/ u16 input ;
/*0x04*/ u32 flags ;
/*0x08*/ u32 particleFlags ;
/*0x0C*/ u32 action ;
/*0x10*/ u32 prevAction ;
2019-10-05 21:08:05 +02:00
/*0x14*/ u32 terrainSoundAddend ;
2019-08-25 06:46:40 +02:00
/*0x18*/ u16 actionState ;
/*0x1A*/ u16 actionTimer ;
/*0x1C*/ u32 actionArg ;
/*0x20*/ f32 intendedMag ;
/*0x24*/ s16 intendedYaw ;
/*0x26*/ s16 invincTimer ;
/*0x28*/ u8 framesSinceA ;
/*0x29*/ u8 framesSinceB ;
/*0x2A*/ u8 wallKickTimer ;
/*0x2B*/ u8 doubleJumpTimer ;
/*0x2C*/ Vec3s faceAngle ;
/*0x32*/ Vec3s angleVel ;
/*0x38*/ s16 slideYaw ;
/*0x3A*/ s16 twirlYaw ;
/*0x3C*/ Vec3f pos ;
/*0x48*/ Vec3f vel ;
/*0x54*/ f32 forwardVel ;
/*0x58*/ f32 slideVelX ;
/*0x5C*/ f32 slideVelZ ;
/*0x60*/ struct Surface * wall ;
/*0x64*/ struct Surface * ceil ;
/*0x68*/ struct Surface * floor ;
/*0x6C*/ f32 ceilHeight ;
/*0x70*/ f32 floorHeight ;
/*0x74*/ s16 floorAngle ;
/*0x76*/ s16 waterLevel ;
/*0x78*/ struct Object * interactObj ;
/*0x7C*/ struct Object * heldObj ;
/*0x80*/ struct Object * usedObj ;
/*0x84*/ struct Object * riddenObj ;
/*0x88*/ struct Object * marioObj ;
/*0x8C*/ struct SpawnInfo * spawnInfo ;
/*0x90*/ struct Area * area ;
2020-01-03 16:38:57 +01:00
/*0x94*/ struct PlayerCameraState * statusForCamera ;
2019-08-25 06:46:40 +02:00
/*0x98*/ struct MarioBodyState * marioBodyState ;
/*0x9C*/ struct Controller * controller ;
/*0xA0*/ struct MarioAnimation * animation ;
/*0xA4*/ u32 collidedObjInteractTypes ;
/*0xA8*/ s16 numCoins ;
/*0xAA*/ s16 numStars ;
/*0xAC*/ s8 numKeys ; // Unused key mechanic
/*0xAD*/ s8 numLives ;
/*0xAE*/ s16 health ;
/*0xB0*/ s16 unkB0 ;
/*0xB2*/ u8 hurtCounter ;
/*0xB3*/ u8 healCounter ;
/*0xB4*/ u8 squishTimer ;
/*0xB5*/ u8 fadeWarpOpacity ;
/*0xB6*/ u16 capTimer ;
2020-06-02 18:44:34 +02:00
/*0xB8*/ s16 prevNumStarsForDialog ;
2019-08-25 06:46:40 +02:00
/*0xBC*/ f32 peakHeight ;
/*0xC0*/ f32 quicksandDepth ;
/*0xC4*/ f32 unkC4 ;
2020-08-09 02:13:11 +02:00
/*0xC8*/ struct Object * heldByObj ;
2019-08-25 06:46:40 +02:00
} ;
2020-08-03 08:02:29 +02:00
# define PLAY_MODE_NORMAL 0
# define PLAY_MODE_PAUSED 2
# define PLAY_MODE_CHANGE_AREA 3
# define PLAY_MODE_CHANGE_LEVEL 4
# define PLAY_MODE_FRAME_ADVANCE 5
# define PLAY_MODE_SYNC_LEVEL 6
2020-08-07 07:52:32 +02:00
// NOTE: this defines the maximum number of players...
// HOWEVER, simply increasing this to 3 will not magically work
// many things will have to be overhauled!
# define MAX_PLAYERS 2
2020-08-08 03:01:58 +02:00
// still deciding to increase it?
// networking will have to be rewritten to have more than one destination. 'reliable' messages would need to be sent per-player
// things that base priority on whether they are the host or not would need priority based on player index instead
// player 2's mario2.geo file will need a different one for player 3, 4, 5, etc... and will need values within it adjusted in a similar manner (diff them)
// read all of the code surrounding a search through the entire codebase of the following:
// gLuigiObject
// gMarioObject
// gMarioState[0]
// gMarioState[1]
// luigi
2020-08-07 07:52:32 +02:00
2020-06-02 18:44:34 +02:00
# endif // _SM64_TYPES_H_