mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Implement all of emu64, mostly matching
This commit is contained in:
+37
-10
@@ -7,13 +7,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MTX_PS
|
||||
|
||||
/////////////// TYPE DEFINES ///////////////
|
||||
#define MTXDegToRad(a) ((a)*0.01745329252f)
|
||||
#define MTXDegToRad(a) ((a) * 0.01745329252f)
|
||||
|
||||
typedef struct {
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
} Vec;
|
||||
|
||||
typedef f32 Mtx34[3][4];
|
||||
@@ -25,7 +27,7 @@ typedef f32 PSQuaternion[4];
|
||||
typedef Mtx34 GC_Mtx; // TODO: fix this
|
||||
|
||||
typedef struct Quaternion {
|
||||
f32 x, y, z, w;
|
||||
f32 x, y, z, w;
|
||||
} Quaternion;
|
||||
|
||||
////////////////////////////////////////////
|
||||
@@ -50,6 +52,9 @@ void PSMTXScale(GC_Mtx mtx, f32 xS, f32 yS, f32 zS);
|
||||
void PSMTXScaleApply(const GC_Mtx src, GC_Mtx dest, f32 xS, f32 yS, f32 zS);
|
||||
void PSMTXQuat(GC_Mtx mtx, const PSQuaternion* quat);
|
||||
|
||||
void PSVECNormalize(const Vec* src, Vec* dst);
|
||||
void PSMTXMultVec(const GC_Mtx m, const Vec* src, Vec* dst);
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//// PAIRED SINGLE MATRIX VEC FUNCTIONS ////
|
||||
@@ -72,15 +77,37 @@ void C_MTXLightOrtho(GC_Mtx mtx, f32 t, f32 b, f32 l, f32 r, f32 scaleS, f32 sca
|
||||
////////////////////////////////////////////
|
||||
|
||||
////////////// MATRIX INLINES //////////////
|
||||
static inline void MTXSetPosition(GC_Mtx mtx, const Vec* pos)
|
||||
{
|
||||
mtx[0][3] = pos->x;
|
||||
mtx[1][3] = pos->y;
|
||||
mtx[2][3] = pos->z;
|
||||
static inline void MTXSetPosition(GC_Mtx mtx, const Vec* pos) {
|
||||
mtx[0][3] = pos->x;
|
||||
mtx[1][3] = pos->y;
|
||||
mtx[2][3] = pos->z;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
#ifdef MTX_PS
|
||||
#define MTXIdentity PSMTXIdentity
|
||||
#define MTXCopy PSMTXCopy
|
||||
#define MTXConcat PSMTXConcat
|
||||
#define MTXConcatArray PSMTXConcatArray
|
||||
#define MTXTranspose PSMTXTranspose
|
||||
#define MTXInverse PSMTXInverse
|
||||
#define MTXInvXpose PSMTXInvXpose
|
||||
|
||||
#define MTXScale PSMTXScale
|
||||
#define MTXTrans PSMTXTrans
|
||||
|
||||
#define MTXMultVec PSMTXMultVec
|
||||
#else
|
||||
#define MTXIdentity C_MTXIdentity
|
||||
#define MTXCopy C_MTXCopy
|
||||
#define MTXConcat C_MTXConcat
|
||||
#define MTXConcatArray C_MTXConcatArray
|
||||
#define MTXTranspose C_MTXTranspose
|
||||
#define MTXInverse C_MTXInverse
|
||||
#define MTXInvXpose C_MTXInvXpose
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -99,6 +99,22 @@ static inline void OSf32tos8(f32* f, s8* out) {
|
||||
*out = __OSf32tos8(*f);
|
||||
}
|
||||
|
||||
static inline float __OSs16tof32(register s16* s) {
|
||||
register float f;
|
||||
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
asm {
|
||||
psq_l f, 0(s), 1, 5
|
||||
}
|
||||
#endif // clang-format on
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static inline void OSs16tof32(register s16* s, volatile register f32* f) {
|
||||
*f = __OSs16tof32(s);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+780
-413
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern u8 FrameCansel;
|
||||
|
||||
extern void emu64_set_ucode_info(int count, ucode_info* ucode_info);
|
||||
extern void emu64_set_first_ucode(void* ucode);
|
||||
extern void emu64_taskstart(Gfx* gfx);
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
#define TEX_CACHE_ALIGNMENT (32-1) /* 32 byte alignment */
|
||||
#define TEX_CACHE_ALIGNMENT (32 - 1) /* 32 byte alignment */
|
||||
#define NUM_TEXTURE_CACHE_DATA 10
|
||||
#define TEXTURE_CACHE_LIST_SIZE 256
|
||||
#define TMEM_ENTRIES 128
|
||||
|
||||
#define TEX_CACHE_ALIGN(n)((n + TEX_CACHE_ALIGNMENT) & ~TEX_CACHE_ALIGNMENT)
|
||||
#define TEX_CACHE_ALIGN(n) ((n + TEX_CACHE_ALIGNMENT) & ~TEX_CACHE_ALIGNMENT)
|
||||
|
||||
/* These would be initialized by the linker. TODO: Is there a better way to do this? */
|
||||
extern void* _data_segment_start;
|
||||
@@ -22,16 +22,16 @@ typedef struct {
|
||||
void* addr;
|
||||
Gloadblock loadblock;
|
||||
Gloadtile loadtile;
|
||||
Gsetimg_new setimg;
|
||||
Gsetimg2 setimg2;
|
||||
} tmem_t;
|
||||
|
||||
typedef struct {
|
||||
void* start; /* Start RAM address of cache */
|
||||
void* end; /* End RAM address of cache */
|
||||
void* end; /* End RAM address of cache */
|
||||
} texture_cache_data_entry_t;
|
||||
|
||||
typedef struct {
|
||||
void* original; /* Original RAM address */
|
||||
void* original; /* Original RAM address */
|
||||
void* converted; /* Converted RAM address */
|
||||
} texture_cache_entry_t;
|
||||
|
||||
@@ -49,19 +49,17 @@ typedef struct {
|
||||
|
||||
typedef struct texture_cache_s {
|
||||
texture_cache_funcs* funcs; /* Pointer to texture cache funcs */
|
||||
u8* buffer_start; /* Start address of cache buffer */
|
||||
u8* buffer_end; /* End address of cache buffer */
|
||||
u8* buffer_current; /* Current write position of the cache buffer */
|
||||
u8* last_alloc_end; /* Points to end address from last cache alloc */
|
||||
u8* last_alloc_start; /* Points to the start address from last cache alloc */
|
||||
bool is_overflow; /* Set to true when the cache is full */
|
||||
u32 buffer_pos; /* Write index into cache buffer */
|
||||
u8* buffer_start; /* Start address of cache buffer */
|
||||
u8* buffer_end; /* End address of cache buffer */
|
||||
u8* buffer_current; /* Current write position of the cache buffer */
|
||||
u8* last_alloc_end; /* Points to end address from last cache alloc */
|
||||
u8* last_alloc_start; /* Points to the start address from last cache alloc */
|
||||
bool is_overflow; /* Set to true when the cache is full */
|
||||
u32 buffer_pos; /* Write index into cache buffer */
|
||||
} texture_cache_t;
|
||||
|
||||
/* TMEM map */
|
||||
//static tmem_t tmem_map[TMEM_ENTRIES];
|
||||
|
||||
|
||||
// static tmem_t tmem_map[TMEM_ENTRIES];
|
||||
|
||||
/* Shared alloc function */
|
||||
void* texture_cache_alloc(texture_cache_t* cache, u32 size);
|
||||
@@ -74,7 +72,6 @@ int texture_cache_data_entry(void* original, void* converted);
|
||||
#define TEX_BUFFER_BSS_SIZE 0x1000
|
||||
|
||||
extern texture_cache_t* texture_cache_select(void* address);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ extern "C" {
|
||||
#define G_DECAL_EQUAL 0x20
|
||||
#define G_DECAL_ALWAYS 0x30
|
||||
#define G_DECAL_SPECIAL 0x40
|
||||
#define G_DECAL_ALL G_DECAL_ALWAYS | G_DECAL_SPECIAL
|
||||
#define G_DECAL_ALL (G_DECAL_ALWAYS | G_DECAL_SPECIAL)
|
||||
|
||||
/* Indicies for G_SPECIAL_1 */
|
||||
#define G_SPECIAL_NONE 0
|
||||
@@ -192,7 +192,7 @@ extern "C" {
|
||||
#define COMBINER_TEV_GET_Ad1(words)((words.w0 >> 0) & 7)
|
||||
|
||||
typedef struct {
|
||||
int cmd:8;
|
||||
unsigned int cmd:8;
|
||||
unsigned int a0:4;
|
||||
unsigned int c0:5;
|
||||
unsigned int Aa0:3;
|
||||
@@ -273,12 +273,12 @@ typedef struct {
|
||||
unsigned int sl:14; /* Start of S coordinate */
|
||||
unsigned int slen:10; /* Length of S coordinate */
|
||||
|
||||
unsigned int isDolphin:1; /* If true, format is Gsettilesize_dolphin. If false, format is Gsettilesize2 */
|
||||
s8 isDolphin:1; /* If true, format is Gsettilesize_Dolphin. If false, format is Gsettilesize2 */
|
||||
unsigned int pad:4;
|
||||
unsigned int tile:3; /* Tile descriptor */
|
||||
unsigned int tl:14; /* Start of T coordinate */
|
||||
unsigned int tlen:10; /* Length of T coordinate */
|
||||
} Gsettilesize_dolphin;
|
||||
} Gsettilesize_Dolphin;
|
||||
|
||||
typedef struct {
|
||||
int cmd:8; /* Command */
|
||||
@@ -314,8 +314,9 @@ typedef struct {
|
||||
unsigned int level:3;
|
||||
unsigned int tile:3;
|
||||
unsigned int on:8; /* Should be 7 bits w/ 1 bit padding, but emulator doesn't do this */
|
||||
unsigned short s:16;
|
||||
unsigned short t:16;
|
||||
|
||||
unsigned short s;
|
||||
unsigned short t;
|
||||
} Gtexture_internal;
|
||||
|
||||
typedef struct {
|
||||
@@ -334,6 +335,229 @@ typedef struct {
|
||||
unsigned int data;
|
||||
} Gmovemem;
|
||||
|
||||
typedef struct Gsettexedgealpha {
|
||||
unsigned int cmd:8;
|
||||
unsigned int unused0:24;
|
||||
|
||||
unsigned int unused1:24;
|
||||
unsigned int tex_edge_alpha:8;
|
||||
} Gsettexedgealpha;
|
||||
|
||||
typedef struct {
|
||||
int cmd:8;
|
||||
unsigned int x0:10;
|
||||
unsigned int x0frac:2;
|
||||
unsigned int y0:10;
|
||||
unsigned int y0frac:2;
|
||||
unsigned int pad:8;
|
||||
unsigned int x1:10;
|
||||
unsigned int x1frac:2;
|
||||
unsigned int y1:10;
|
||||
unsigned int y1frac:2;
|
||||
} Gscissor;
|
||||
|
||||
typedef struct {
|
||||
int cmd:8;
|
||||
unsigned int x0:10;
|
||||
unsigned int x0frac:2;
|
||||
unsigned int y0:10;
|
||||
unsigned int y0frac:2;
|
||||
unsigned int pad:8;
|
||||
unsigned int x1:10;
|
||||
unsigned int x1frac:2;
|
||||
unsigned int y1:10;
|
||||
unsigned int y1frac:2;
|
||||
} Gfillrect2;
|
||||
|
||||
typedef struct Gnoop {
|
||||
unsigned int cmd: 8;
|
||||
unsigned int tag: 8;
|
||||
unsigned int param0: 16;
|
||||
|
||||
unsigned int param1;
|
||||
} Gnoop;
|
||||
|
||||
typedef struct Gmtx {
|
||||
unsigned int cmd: 8;
|
||||
unsigned int par: 8;
|
||||
unsigned int pad: 8;
|
||||
unsigned int type: 8;
|
||||
|
||||
unsigned int addr;
|
||||
} Gmtx;
|
||||
|
||||
typedef struct Gvtx {
|
||||
unsigned int cmd: 8;
|
||||
unsigned int pad0: 4;
|
||||
unsigned int n: 8;
|
||||
unsigned int pad1: 4;
|
||||
unsigned int vn:8;
|
||||
|
||||
unsigned int addr;
|
||||
} Gvtx;
|
||||
|
||||
typedef struct Gline3D_new {
|
||||
unsigned int cmd: 8;
|
||||
unsigned int v0: 8;
|
||||
unsigned int v1: 8;
|
||||
unsigned int wd: 8;
|
||||
|
||||
unsigned int pad;
|
||||
} Gline3D_new;
|
||||
|
||||
typedef struct Gtri1 {
|
||||
unsigned int cmd: 8;
|
||||
unsigned int v0: 8;
|
||||
unsigned int v1: 8;
|
||||
unsigned int v2: 8;
|
||||
|
||||
unsigned int pad;
|
||||
} Gtri1;
|
||||
|
||||
typedef struct Gtri2 {
|
||||
int cmd: 8;
|
||||
unsigned int t0v0: 8;
|
||||
unsigned int t0v1: 8;
|
||||
unsigned int t0v2: 8;
|
||||
|
||||
unsigned int pad: 8;
|
||||
unsigned int t1v0: 8;
|
||||
unsigned int t1v1: 8;
|
||||
unsigned int t1v2: 8;
|
||||
} Gtri2;
|
||||
|
||||
typedef struct Gtrin_independ {
|
||||
unsigned int cmd: 8; // 32
|
||||
unsigned int count: 7; // 24
|
||||
unsigned int f2v2: 5; // 17
|
||||
unsigned int f2v1: 5; // 12
|
||||
unsigned int f2v0: 5; // 7
|
||||
unsigned int f1v2_1: 2; // 2
|
||||
|
||||
unsigned int f1v2_0: 3; // 32
|
||||
unsigned int f1v1: 5; // 29
|
||||
unsigned int f1v0: 5; // 24
|
||||
unsigned int f0v2: 5; // 19
|
||||
unsigned int f0v1: 5; // 14
|
||||
unsigned int f0v0: 5; // 9
|
||||
unsigned int pad: 3; // 4
|
||||
unsigned int is7bit: 1; // 1
|
||||
} Gtrin_independ;
|
||||
|
||||
typedef struct Gtrin {
|
||||
unsigned int f3v2: 5; // 32
|
||||
unsigned int f3v1: 5; // 27
|
||||
unsigned int f3v0: 5; // 22
|
||||
unsigned int f2v2: 5; // 17
|
||||
unsigned int f2v1: 5; // 12
|
||||
unsigned int f2v0: 5; // 7
|
||||
unsigned int f1v2_1: 2; // 2
|
||||
|
||||
unsigned int f1v2_0: 3; // 32
|
||||
unsigned int f1v1: 5; // 29
|
||||
unsigned int f1v0: 5; // 24
|
||||
unsigned int f0v2: 5; // 19
|
||||
unsigned int f0v1: 5; // 14
|
||||
unsigned int f0v0: 5; // 9
|
||||
unsigned int pad: 3; // 32
|
||||
unsigned int is7bit: 1; // 1
|
||||
} Gtrin;
|
||||
|
||||
typedef struct Gtrin_7b {
|
||||
unsigned int f2v2: 7; // 32
|
||||
unsigned int f2v1: 7; // 25
|
||||
unsigned int f2v0: 7; // 18
|
||||
unsigned int f1v2: 7; // 11
|
||||
unsigned int f1v1_1: 4; // 4
|
||||
|
||||
unsigned int f1v1_0: 3; // 32
|
||||
unsigned int f1v0: 7; // 29
|
||||
unsigned int f0v2: 7; // 22
|
||||
unsigned int f0v1: 7; // 15
|
||||
unsigned int f0v0: 7; // 8
|
||||
unsigned int is7bit: 1; // 1
|
||||
} Gtrin_7b;
|
||||
|
||||
typedef struct Gquad_independ {
|
||||
unsigned int cmd: 8; // 32
|
||||
unsigned int count: 7; // 24
|
||||
unsigned int unused: 5; // 17
|
||||
unsigned int f1v3: 5; // 12
|
||||
unsigned int f1v2: 5; // 7
|
||||
unsigned int f1v1_1: 2; // 2
|
||||
|
||||
unsigned int f1v1_0: 3; // 32
|
||||
unsigned int f1v0: 5; // 29
|
||||
unsigned int f0v3: 5; // 24
|
||||
unsigned int f0v2: 5; // 19
|
||||
unsigned int f0v1: 5; // 14
|
||||
unsigned int f0v0: 5; // 9
|
||||
unsigned int pad: 3; // 4
|
||||
unsigned int is7bit: 1; // 1
|
||||
} Gquad_independ;
|
||||
|
||||
typedef struct Gquad {
|
||||
unsigned int f2v3: 5; // 32
|
||||
unsigned int f2v2: 5; // 27
|
||||
unsigned int f2v1: 5; // 22
|
||||
unsigned int f2v0: 5; // 17
|
||||
unsigned int f1v3: 5; // 12
|
||||
unsigned int f1v2: 5; // 7
|
||||
unsigned int f1v1_1: 2; // 2
|
||||
|
||||
unsigned int f1v1_0: 3; // 32
|
||||
unsigned int f1v0: 5; // 29
|
||||
unsigned int f0v3: 5; // 24
|
||||
unsigned int f0v2: 5; // 19
|
||||
unsigned int f0v1: 5; // 14
|
||||
unsigned int f0v0: 5; // 9
|
||||
unsigned int pad: 3; // 4
|
||||
unsigned int is7bit: 1; // 1
|
||||
} Gquad;
|
||||
|
||||
typedef struct Gquad_7b {
|
||||
unsigned int f1v3: 7; // 32
|
||||
unsigned int f1v2: 7; // 25
|
||||
unsigned int f1v1: 7; // 18
|
||||
unsigned int f1v0_1: 4; // 11
|
||||
unsigned int f1v0_0: 3; // 7
|
||||
unsigned int pad: 4; // 4
|
||||
|
||||
unsigned int f0v3: 7; // 32
|
||||
unsigned int f0v2: 7; // 25
|
||||
unsigned int f0v1: 7; // 18
|
||||
unsigned int f0v0: 7; // 11
|
||||
unsigned int pad0: 3; // 4
|
||||
unsigned int is7bit: 1; // 1
|
||||
} Gquad_7b;
|
||||
|
||||
typedef struct Gquad0 {
|
||||
int cmd: 8;
|
||||
unsigned int v0: 8;
|
||||
unsigned int v1: 8;
|
||||
unsigned int v2: 8;
|
||||
|
||||
unsigned int pad: 24;
|
||||
unsigned int v3: 8;
|
||||
} Gquad0;
|
||||
|
||||
typedef struct Gculldl {
|
||||
int cmd: 8;
|
||||
unsigned int pad0: 8;
|
||||
unsigned int vstart: 16;
|
||||
|
||||
unsigned int pad1: 16;
|
||||
unsigned int vend: 16;
|
||||
} Gculldl;
|
||||
|
||||
typedef struct Gspecial1 {
|
||||
int cmd: 8;
|
||||
int mode: 8;
|
||||
unsigned int param0: 16;
|
||||
|
||||
unsigned int param1;
|
||||
} Gspecial1;
|
||||
|
||||
typedef struct {
|
||||
unsigned char col[3];
|
||||
unsigned char kc;
|
||||
@@ -363,22 +587,52 @@ typedef struct {
|
||||
} combiner_tev_alpha;
|
||||
|
||||
/* New Command Macros */
|
||||
#define gDPParam2(cmd, tag, param, extra) \
|
||||
do { \
|
||||
Gfx* _g = (Gfx*)(pkt); \
|
||||
_g->words.w0 = (u32)(_SHIFTL(cmd, 24, 8) | _SHIFTL(tag, 16, 8) | _SHIFTL(param, 0, 16)); \
|
||||
_g->words.w1 = (u32)(extra); \
|
||||
} while(0)
|
||||
|
||||
#define gsDPParam2(cmd, tag, param, extra) \
|
||||
{{ \
|
||||
_SHIFTL(cmd, 24, 8) | _SHIFTL(tag, 16, 8) | _SHIFTL(param, 0, 16), extra \
|
||||
}}
|
||||
|
||||
#define gsDPNoOpTag2(tag, param, extra) gsDPParam2(G_NOOP, tag, param, extra)
|
||||
#define gDPNoOpTag2(tag, param, extra) gDPParam2(G_NOOP, tag, param, extra)
|
||||
#define gsDPNoOpTag2(tag, param, extra) gsDPParam2(G_NOOP, tag, param, extra)
|
||||
|
||||
#define gDPNoOpHere() gDPNoOpTag2(G_TAG_HERE, __LINE__, __FILE__)
|
||||
#define gsDPNoOpHere() gsDPNoOpTag2(G_TAG_HERE, __LINE__, __FILE__)
|
||||
|
||||
#define gDPNoOpString(str, param) gDPNoOpTag2(G_TAG_STRING, param, str)
|
||||
#define gsDPNoOpString(str, param) gsDPNoOpTag2(G_TAG_STRING, param, str)
|
||||
|
||||
#define gDPNoOpWord(word, param) gDPNoOpTag2(G_TAG_WORD, param, word)
|
||||
#define gsDPNoOpWord(word, param) gsDPNoOpTag2(G_TAG_WORD, param, word)
|
||||
|
||||
#define gDPNoOpFloat(float, param) gDPNoOpTag2(G_TAG_FLOAT, param, float)
|
||||
#define gsDPNoOpFloat(float, param) gsDPNoOpTag2(G_TAG_FLOAT, param, float)
|
||||
|
||||
#define gDPNoOpQuiet() gDPNoOpTag2(G_TAG_INFO, 0, 0)
|
||||
#define gsDPNoOpQuiet() gsDPNoOpTag2(G_TAG_INFO, 0, 0)
|
||||
|
||||
#define gDPNoOpVerbose() gDPNoOpTag2(G_TAG_INFO, 0xF, 0)
|
||||
#define gsDPNoOpVerbose() gsDPNoOpTag2(G_TAG_INFO, 0xF, 0)
|
||||
|
||||
#define gDPNoOpCallBack(callback, param) gDPNoOpTag2(G_TAG_CALLBACK, param, callback)
|
||||
#define gsDPNoOpCallBack(callback, param) gsDPNoOpTag2(G_TAG_CALLBACK, param, callback)
|
||||
|
||||
#define gDPNoOpOpenDisp() gDPNoOpTag2(G_TAG_OPENDISP, __LINE__, __FILE__)
|
||||
#define gsDPNoOpOpenDisp() gsDPNoOpTag2(G_TAG_OPENDISP, __LINE__, __FILE__)
|
||||
|
||||
#define gDPNoOpCloseDisp() gDPNoOpTag2(G_TAG_CLOSEDISP, __LINE__, __FILE__)
|
||||
#define gsDPNoOpCloseDisp() gsDPNoOpTag2(G_TAG_CLOSEDISP, __LINE__, __FILE__)
|
||||
|
||||
#define gDPNoOpFill() gDPNoOpTag2(G_TAG_FILL, 0, 0)
|
||||
#define gsDPNoOpFill() gsDPNoOpTag2(G_TAG_FILL, 0, 0)
|
||||
|
||||
#define gDPNoOpTag3(tag, extra, param) gDPNoOpTag2(tag, param, extra)
|
||||
#define gsDPNoOpTag3(tag, extra, param) gsDPNoOpTag2(tag, param, extra)
|
||||
|
||||
#define G_TLUT_DOLPHIN 2
|
||||
|
||||
+7
-1
@@ -17,8 +17,14 @@ typedef struct __va_list_struct {
|
||||
|
||||
typedef _va_list_struct __va_list[1];
|
||||
|
||||
void* __va_arg(_va_list_struct* list, int type);
|
||||
|
||||
#define __va_start(list, fmt) __builtin_va_info(&list)
|
||||
#define __va_arg(list, type) (*((type*)__va_arg(ap, _var_arg_typeof(type))))
|
||||
#ifdef __MWERKS__
|
||||
#define __va_arg(list, type) (*((type*)__va_arg(list, _var_arg_typeof(type))))
|
||||
#else
|
||||
#define __va_arg(list, type) 0
|
||||
#endif
|
||||
#define va_start __va_start
|
||||
#define va_arg __va_arg
|
||||
#define va_end __va_end
|
||||
|
||||
+4169
-198
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,485 @@
|
||||
#include "emu64.hpp"
|
||||
|
||||
#include "boot.h"
|
||||
|
||||
static const char kakko[] = "/\\/\\||||||||\\/\\/";
|
||||
|
||||
void emu64::disp_matrix(GC_Mtx mtx) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (mtx != nullptr) {
|
||||
for (int x = 0; x < 4; x++) {
|
||||
this->Printf("%10.3f", mtx[i][x]);
|
||||
}
|
||||
}
|
||||
|
||||
this->Printf("\n", kakko[3 + i * 4]);
|
||||
}
|
||||
}
|
||||
|
||||
const char* emu64::segchk(u32 segment) {
|
||||
static char str[64];
|
||||
char buf[30];
|
||||
const char str0[] = "anime_4_txt+%4u";
|
||||
const char str1[] = "anime_6_model+sizeof(Mtx)*%2u";
|
||||
|
||||
u32 partial_addr = (u32)seg2k0(segment);
|
||||
u32 addr = convert_partial_address(partial_addr);
|
||||
|
||||
str[0] = '\0';
|
||||
if (segment == partial_addr) {
|
||||
if (addr == partial_addr) {
|
||||
snprintf(str, sizeof(str), "0x%08x", segment);
|
||||
} else {
|
||||
snprintf(str, sizeof(str), "0x%08x /* PADDR=0x%08x */", segment, partial_addr);
|
||||
}
|
||||
} else {
|
||||
const char* s;
|
||||
if (SEG_EQUALS(segment, SOFTSPRITE_MTX_SEG)) {
|
||||
s = "softsprite_mtx";
|
||||
} else if (SEG_EQUALS(segment, ANIME_1_TXT_SEG)) {
|
||||
s = "anime_1_txt";
|
||||
} else if (SEG_EQUALS(segment, ANIME_2_TXT_SEG)) {
|
||||
s = "anime_2_txt";
|
||||
} else if (SEG_EQUALS(segment, ANIME_3_TXT_SEG)) {
|
||||
s = "anime_3_txt";
|
||||
} else if (SEG_EQUALS(segment, ANIME_4_TXT_SEG)) {
|
||||
s = "anime_4_txt";
|
||||
} else if (SEG_EQUALS(segment, ANIME_5_TXT_SEG)) {
|
||||
s = "anime_5_txt";
|
||||
} else if (SEG_EQUALS(segment, ANIME_6_TXT_SEG)) {
|
||||
s = "anime_6_txt";
|
||||
} else if (SEG_EQUALS(segment, ANIME_1_TXT_SEG)) {
|
||||
s = "anime_1_model";
|
||||
} else if (SEG_EQUALS(segment, ANIME_2_TXT_SEG)) {
|
||||
s = "anime_2_model";
|
||||
} else if (SEG_EQUALS(segment, ANIME_3_TXT_SEG)) {
|
||||
s = "anime_3_model";
|
||||
} else if (SEG_EQUALS(segment, ANIME_4_TXT_SEG)) {
|
||||
s = "anime_4_model";
|
||||
} else if (SEG_EQUALS(segment, ANIME_5_TXT_SEG)) {
|
||||
s = "anime_5_model";
|
||||
} else if (SEG_EQUALS(segment, ANIME_6_TXT_SEG)) {
|
||||
s = "anime_6_model";
|
||||
} else if (segment > SEG_2_SEGADDR(ANIME_4_TXT_SEG) && segment < (SEG_2_SEGADDR(ANIME_4_TXT_SEG) + 0x800)) {
|
||||
snprintf(buf, sizeof(buf) - 1, str0, segment - SEG_2_SEGADDR(ANIME_4_TXT_SEG));
|
||||
s = buf;
|
||||
} else {
|
||||
if (segment > 0xD000000 && segment < 0xD000408) {
|
||||
int comb = segment - 0x0D000000;
|
||||
snprintf(buf, sizeof(buf) - 1, str1, comb / (int)sizeof(Mtx));
|
||||
s = buf;
|
||||
} else {
|
||||
s = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr == partial_addr) {
|
||||
if (s != nullptr) {
|
||||
snprintf(str, sizeof(str), "%s /* 0x%08x */", s, partial_addr);
|
||||
} else {
|
||||
snprintf(str, sizeof(str), "0x%08x /* ### 0x%08x */", segment, partial_addr);
|
||||
}
|
||||
} else {
|
||||
if (s != nullptr) {
|
||||
snprintf(str, sizeof(str), "%s /* 0x%08x PADDR=0x%08x */", s, partial_addr, addr);
|
||||
} else {
|
||||
snprintf(str, sizeof(str), "0x%08x /* ### 0x%08x PADDR=0x%08x */", segment, partial_addr, addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
const char* emu64::combine_name(u32 param, u32 type) {
|
||||
const char* ret;
|
||||
switch (param) {
|
||||
case 0:
|
||||
ret = "COMBINED";
|
||||
break;
|
||||
case 1:
|
||||
ret = "TEXEL0";
|
||||
break;
|
||||
case 2:
|
||||
ret = "TEXEL1";
|
||||
break;
|
||||
case 3:
|
||||
ret = "PRIMITIVE";
|
||||
break;
|
||||
case 4:
|
||||
ret = "SHADE";
|
||||
break;
|
||||
case 5:
|
||||
ret = "ENVIRONMENT";
|
||||
break;
|
||||
case 6:
|
||||
ret = (type == COMBINER_PARAM_B) ? "CENTER" : ((type == COMBINER_PARAM_C) ? "SCALE" : "1");
|
||||
break;
|
||||
case 7:
|
||||
ret = (type == COMBINER_PARAM_A)
|
||||
? "NOISE"
|
||||
: ((type == COMBINER_PARAM_B) ? "K4" : ((type == COMBINER_PARAM_C) ? "COMBINED_ALPHA" : "0"));
|
||||
break;
|
||||
default:
|
||||
if (type == COMBINER_PARAM_C) {
|
||||
switch (param) {
|
||||
case 8:
|
||||
ret = "TEXEL0_ALPHA";
|
||||
break;
|
||||
case 9:
|
||||
ret = "TEXEL1_ALPHA";
|
||||
break;
|
||||
case 10:
|
||||
ret = "PRIMITIVE_ALPHA";
|
||||
break;
|
||||
case 11:
|
||||
ret = "SHADE_ALPHA";
|
||||
break;
|
||||
case 12:
|
||||
ret = "ENV_ALPHA";
|
||||
break;
|
||||
case 13:
|
||||
ret = "LOD_FRACTION";
|
||||
break;
|
||||
case 14:
|
||||
ret = "PRIM_LOD_FRAC";
|
||||
break;
|
||||
case 15:
|
||||
ret = "K5";
|
||||
break;
|
||||
default:
|
||||
ret = "0";
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = "0";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* emu64::combine_alpha(int param, int type) {
|
||||
const char* ret;
|
||||
|
||||
switch (param) {
|
||||
case 0:
|
||||
ret = (type == COMBINER_PARAM_C) ? "LOD_FRACTION" : "COMBINED";
|
||||
break;
|
||||
case 1:
|
||||
ret = "TEXEL0";
|
||||
break;
|
||||
case 2:
|
||||
ret = "TEXEL1";
|
||||
break;
|
||||
case 3:
|
||||
ret = "PRIMITIVE";
|
||||
break;
|
||||
case 4:
|
||||
ret = "SHADE";
|
||||
break;
|
||||
case 5:
|
||||
ret = "ENVIRONMENT";
|
||||
break;
|
||||
case 6:
|
||||
ret = (type == COMBINER_PARAM_C) ? "PRIM_LOD_FRAC" : "1";
|
||||
break;
|
||||
case 7:
|
||||
ret = "0";
|
||||
break;
|
||||
/* There should be a default case here, but they forgot it. */
|
||||
/* It returns a pointer to the emu64 class instead. */
|
||||
#ifdef EMU64_FIX_COMBINE_NAME_RETURN_VALUES
|
||||
default:
|
||||
ret = "0";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* emu64::combine_tev_color_name(u32 color_param) {
|
||||
const char* ret;
|
||||
|
||||
switch (color_param) {
|
||||
case 0:
|
||||
ret = "COMBINED";
|
||||
break;
|
||||
case 1:
|
||||
ret = "COMBINED_ALPHA";
|
||||
break;
|
||||
case 2:
|
||||
ret = "(FILL)";
|
||||
break;
|
||||
case 3:
|
||||
ret = "PRIM_LOD_FRAC";
|
||||
break;
|
||||
case 4:
|
||||
ret = "PRIMITIVE";
|
||||
break;
|
||||
case 5:
|
||||
ret = "PRIMITIVE_ALPHA";
|
||||
break;
|
||||
case 6:
|
||||
ret = "ENVIRONMENT";
|
||||
break;
|
||||
case 7:
|
||||
ret = "ENV_ALPHA";
|
||||
break;
|
||||
case 8:
|
||||
ret = "TEXEL0";
|
||||
break;
|
||||
case 9:
|
||||
ret = "TEXEL0_ALPHA";
|
||||
break;
|
||||
case 10:
|
||||
ret = "SHADE";
|
||||
break;
|
||||
case 11:
|
||||
ret = "SHADE_ALPHA";
|
||||
break;
|
||||
case 12:
|
||||
ret = "1";
|
||||
break;
|
||||
case 13:
|
||||
ret = "(HALF)";
|
||||
break;
|
||||
case 14:
|
||||
ret = "(KONST)";
|
||||
break;
|
||||
case 15:
|
||||
ret = "0";
|
||||
break;
|
||||
/* There should be a default case here, but they forgot it. */
|
||||
/* It returns a pointer to the emu64 class instead. */
|
||||
#ifdef EMU64_FIX_COMBINE_NAME_RETURN_VALUES
|
||||
default:
|
||||
ret = "0";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
const char* emu64::combine_tev_alpha_name(u32 alpha_param) {
|
||||
const char* ret;
|
||||
|
||||
switch (alpha_param) {
|
||||
case 0:
|
||||
ret = "COMBINED";
|
||||
break;
|
||||
case 1:
|
||||
ret = "PRIM_LOD_FRAC";
|
||||
break;
|
||||
case 2:
|
||||
ret = "PRIMITIVE";
|
||||
break;
|
||||
case 3:
|
||||
ret = "ENVIRONMENT";
|
||||
break;
|
||||
case 4:
|
||||
ret = "TEXEL0";
|
||||
break;
|
||||
case 5:
|
||||
ret = "SHADE";
|
||||
break;
|
||||
case 6:
|
||||
ret = "1";
|
||||
break;
|
||||
case 7:
|
||||
ret = "0";
|
||||
break;
|
||||
/* There should be a default case here, but they forgot it. */
|
||||
/* It returns a pointer to the emu64 class instead. */
|
||||
#ifdef EMU64_FIX_COMBINE_NAME_RETURN_VALUES
|
||||
default:
|
||||
ret = "0";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
u32 value;
|
||||
char* name;
|
||||
u32 mask;
|
||||
} GeometryModeParameterInfo;
|
||||
|
||||
#define NUM_GEOMETRYMODE_FLAGS 16
|
||||
static const GeometryModeParameterInfo geomtbl[NUM_GEOMETRYMODE_FLAGS] = {
|
||||
{ G_ZBUFFER, "G_ZBUFFER", G_ZBUFFER },
|
||||
{ G_TEXTURE_ENABLE, "G_TEXTURE_ENABLE", G_TEXTURE_ENABLE },
|
||||
{ G_SHADE, "G_SHADE", G_SHADE },
|
||||
{ G_SHADING_SMOOTH, "G_SHADING_SMOOTH", G_SHADING_SMOOTH },
|
||||
{ G_CULL_FRONT, "G_CULL_FRONT", G_CULL_FRONT },
|
||||
{ G_CULL_BACK, "G_CULL_BACK", G_CULL_BACK },
|
||||
{ G_FOG, "G_FOG", G_FOG },
|
||||
{ G_LIGHTING, "G_LIGHTING", G_LIGHTING },
|
||||
{ G_TEXTURE_GEN, "G_TEXTURE_GEN", G_TEXTURE_GEN },
|
||||
{ G_TEXTURE_GEN_LINEAR, "G_TEXTURE_GEN_LINEAR", G_TEXTURE_GEN_LINEAR },
|
||||
{ G_LOD, "G_LOD", G_LOD },
|
||||
{ G_LIGHTING_POSITIONAL, "G_LIGHTING_POSITIONAL", G_LIGHTING_POSITIONAL },
|
||||
{ G_DECAL_EQUAL, "G_DECAL_EQUAL", G_DECAL_ALWAYS },
|
||||
{ G_DECAL_GEQUAL, "G_DECAL_GEQUAL", G_DECAL_ALWAYS },
|
||||
{ G_DECAL_ALWAYS, "G_DECAL_ALWAYS", G_DECAL_ALWAYS },
|
||||
{ G_DECAL_SPECIAL, "G_DECAL_SPECIAL", G_DECAL_SPECIAL }
|
||||
};
|
||||
|
||||
void emu64::print_geomflags(u32 flags) {
|
||||
u32 i;
|
||||
int empty = TRUE;
|
||||
|
||||
for (i = 0; i < NUM_GEOMETRYMODE_FLAGS; i++) {
|
||||
if ((flags & geomtbl[i].mask) == geomtbl[i].value) {
|
||||
if (empty) {
|
||||
empty = FALSE;
|
||||
} else {
|
||||
this->Printf("|");
|
||||
}
|
||||
|
||||
this->Printf("%s", geomtbl[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty) {
|
||||
this->Printf("0");
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
u32 value;
|
||||
u32 mask;
|
||||
} RendermodeInfo;
|
||||
|
||||
void emu64::show_render(u32 data) {
|
||||
static const RendermodeInfo flags[] = {
|
||||
{ "AA_EN", AA_EN, AA_EN },
|
||||
{ "Z_CMP", Z_CMP, Z_CMP },
|
||||
{ "Z_UPD", Z_UPD, Z_UPD },
|
||||
{ "IM_RD", IM_RD, IM_RD },
|
||||
{ "CLR_ON_CVG", CLR_ON_CVG, CLR_ON_CVG },
|
||||
{ "CVG_DST_CLAMP", CVG_DST_CLAMP, CVG_DST_SAVE },
|
||||
{ "CVG_DST_WRAP", CVG_DST_WRAP, CVG_DST_SAVE },
|
||||
{ "CVG_DST_FULL", CVG_DST_FULL, CVG_DST_SAVE },
|
||||
{ "CVG_DST_SAVE", CVG_DST_SAVE, CVG_DST_SAVE },
|
||||
{ "ZMODE_OPA", ZMODE_OPA, ZMODE_DEC },
|
||||
{ "ZMODE_INTER", ZMODE_INTER, ZMODE_DEC },
|
||||
{ "ZMODE_XLU", ZMODE_XLU, ZMODE_DEC },
|
||||
{ "ZMODE_DEC", ZMODE_DEC, ZMODE_DEC },
|
||||
{ "CVG_X_ALPHA", CVG_X_ALPHA, CVG_X_ALPHA },
|
||||
{ "ALPHA_CVG_SEL", ALPHA_CVG_SEL, ALPHA_CVG_SEL },
|
||||
{ "FORCE_BL", FORCE_BL, FORCE_BL },
|
||||
};
|
||||
|
||||
static const char* const m[4][4] = {
|
||||
{ "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG" },
|
||||
{ "G_BL_A_SHADE", "G_BL_0", "G_BL_A_IN", "G_BL_A_FOG" },
|
||||
{ "G_BL_CLR_IN", "G_BL_CLR_MEM", "G_BL_CLR_BL", "G_BL_CLR_FOG" },
|
||||
{ "G_BL_A_MEM", "G_BL_0", "G_BL_1MA", "G_BL_1" },
|
||||
};
|
||||
|
||||
EMU64_LOG("\ngsDPSetRenderBlender(\n");
|
||||
|
||||
u32 c1 = (data >> 18) & 0x3333;
|
||||
u32 c2 = (data >> 16) & 0x3333;
|
||||
|
||||
for (u32 i = 0; i < ARRAY_COUNT(flags); i++) {
|
||||
if ((data & flags[i].mask) == flags[i].value) {
|
||||
this->Printf("%s|", flags[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
this->Printf("\nGBL_c1(%s, %s, %s, %s)|", m[0][(c1 >> 12) & 3], m[1][(c1 >> 8) & 3], m[2][(c1 >> 4) & 3],
|
||||
m[3][c1 & 3]);
|
||||
|
||||
this->Printf("\nGBL_c2(%s, %s, %s, %s)", m[0][(c2 >> 12) & 3], m[1][(c2 >> 8) & 3], m[2][(c2 >> 4) & 3],
|
||||
m[3][c2 & 3]);
|
||||
|
||||
EMU64_LOG("\n),");
|
||||
}
|
||||
|
||||
void emu64::show_vtx(Vtx* vtx, int count, int begin) {
|
||||
for (int i = 0; i < count; i++, vtx++) {
|
||||
if ((this->geometry_mode & G_LIGHTING) != 0) {
|
||||
Vtx_tn* p_vtx = &vtx->n;
|
||||
|
||||
// clang-format off
|
||||
this->Printf(
|
||||
"\n{{%6d, %6d, %6d, %d, %6d, %6d, %4d, %4d, %4d, %3d}}, /* vc%02d */",
|
||||
p_vtx->ob[0], p_vtx->ob[1], p_vtx->ob[2], /* Position */
|
||||
p_vtx->flag, /* Flag */
|
||||
p_vtx->tc[0], p_vtx->tc[1], /* Texture Coordinates */
|
||||
p_vtx->n[0], p_vtx->n[1], p_vtx->n[2], /* Normal */
|
||||
p_vtx->a, /* Alpha */
|
||||
begin + i /* Vertex # */
|
||||
);
|
||||
// clang-format on
|
||||
} else {
|
||||
Vtx_t* p_vtx = &vtx->v;
|
||||
|
||||
// clang-format off
|
||||
this->Printf(
|
||||
"\n{{%6d, %6d, %6d, %d, %6d, %6d, %4d, %4d, %4d, %3d}}, /* vn%02d */",
|
||||
p_vtx->ob[0], p_vtx->ob[1], p_vtx->ob[2], /* Position */
|
||||
p_vtx->flag, /* Flag */
|
||||
p_vtx->tc[0], p_vtx->tc[1], /* Texture Coordinates */
|
||||
p_vtx->cn[0], p_vtx->cn[1], p_vtx->cn[2], p_vtx->cn[3], /* Color */
|
||||
begin + i /* Vertex # */
|
||||
);
|
||||
// clang-format on
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void emu64::print_combine(u64 cmd) {
|
||||
Gsetcombine_new* combine = (Gsetcombine_new*)&cmd;
|
||||
this->Printf0(
|
||||
"gsDPSetCombineLERP(%s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s),",
|
||||
this->combine_name(combine->a0, COMBINER_PARAM_A), this->combine_name(combine->b0, COMBINER_PARAM_B),
|
||||
this->combine_name(combine->c0, COMBINER_PARAM_C), this->combine_name(combine->d0, COMBINER_PARAM_D),
|
||||
this->combine_alpha(combine->Aa0, COMBINER_PARAM_A), this->combine_alpha(combine->Ab0, COMBINER_PARAM_B),
|
||||
this->combine_alpha(combine->Ac0, COMBINER_PARAM_C), this->combine_alpha(combine->Ad0, COMBINER_PARAM_D),
|
||||
this->combine_name(combine->a1, COMBINER_PARAM_A), this->combine_name(combine->b1, COMBINER_PARAM_B),
|
||||
this->combine_name(combine->c1, COMBINER_PARAM_C), this->combine_name(combine->d1, COMBINER_PARAM_D),
|
||||
this->combine_alpha(combine->Aa1, COMBINER_PARAM_A), this->combine_alpha(combine->Ab1, COMBINER_PARAM_B),
|
||||
this->combine_alpha(combine->Ac1, COMBINER_PARAM_C), this->combine_alpha(combine->Ad1, COMBINER_PARAM_D));
|
||||
}
|
||||
|
||||
void emu64::print_combine_tev(u64 combine_tev) {
|
||||
Gsetcombine_tev* c_tev = (Gsetcombine_tev*)&combine_tev;
|
||||
|
||||
this->Printf0("gsDPSetCombineTev(%s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s),",
|
||||
this->combine_tev_color_name(c_tev->a0), this->combine_tev_color_name(c_tev->b0),
|
||||
this->combine_tev_color_name(c_tev->c0), this->combine_tev_color_name(c_tev->d0),
|
||||
this->combine_tev_alpha_name(c_tev->Aa0), this->combine_tev_alpha_name(c_tev->Ab0),
|
||||
this->combine_tev_alpha_name(c_tev->Ac0), this->combine_tev_alpha_name(c_tev->Ad0),
|
||||
this->combine_tev_color_name(c_tev->a1), this->combine_tev_color_name(c_tev->b1),
|
||||
this->combine_tev_color_name(c_tev->c1), this->combine_tev_color_name(c_tev->d1),
|
||||
this->combine_tev_alpha_name(c_tev->Aa1), this->combine_tev_alpha_name(c_tev->Ab1),
|
||||
this->combine_tev_alpha_name(c_tev->Ac1), this->combine_tev_alpha_name(c_tev->Ad1));
|
||||
}
|
||||
|
||||
void emu64::print_guMtxXFM1F_dol2(MtxP mtx, GXProjectionType type, float x, float y, float z) {
|
||||
if (type == GX_PERSPECTIVE) {
|
||||
float s = -1.0f / z;
|
||||
|
||||
float x0 = mtx[0][0] * x * s - mtx[0][2];
|
||||
float y0 = mtx[1][1] * y * s - mtx[1][2];
|
||||
float z0 = mtx[2][3] * s - mtx[2][2];
|
||||
|
||||
EMU64_LOGF("%8.3f * %8.3f * %8.3f - %8.3f = %8.3f\n", mtx[0][0], x, s, mtx[0][2], x0);
|
||||
EMU64_LOGF("%8.3f * %8.3f * %8.3f - %8.3f = %8.3f\n", mtx[1][1], y, s, mtx[1][2], y0);
|
||||
EMU64_LOGF("%8.3f * %8.3f - %8.3f = %8.3f\n", mtx[2][3], s, mtx[2][2], z0);
|
||||
} else {
|
||||
float x0 = mtx[0][0] * x + mtx[0][3];
|
||||
float y0 = mtx[1][1] * y + mtx[1][3];
|
||||
float z0 = mtx[2][2] * z + mtx[2][3];
|
||||
|
||||
EMU64_LOGF("%8.3f * %8.3f + %8.3f = %8.3f\n", mtx[0][0], x, mtx[0][3], x0);
|
||||
EMU64_LOGF("%8.3f * %8.3f + %8.3f = %8.3f\n", mtx[1][1], x, mtx[1][3], y0);
|
||||
EMU64_LOGF("%8.3f * %8.3f + %8.3f = %8.3f\n", mtx[2][2], x, mtx[2][3], z0);
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
#include "emu64.hpp"
|
||||
|
||||
const char* emu64::combine_name(u32 param, u32 type) {
|
||||
switch (param) {
|
||||
case 0:
|
||||
return "COMBINED";
|
||||
case 1:
|
||||
return "TEXEL0";
|
||||
case 2:
|
||||
return "TEXEL1";
|
||||
case 3:
|
||||
return "PRIMITIVE";
|
||||
case 4:
|
||||
return "SHADE";
|
||||
case 5:
|
||||
return "ENVIRONMENT";
|
||||
case 6:
|
||||
if (type == COMBINER_PARAM_B) {
|
||||
return "CENTER";
|
||||
} else if (type == COMBINER_PARAM_C) {
|
||||
return "SCALE";
|
||||
} else {
|
||||
return "1";
|
||||
}
|
||||
case 7:
|
||||
if (type == COMBINER_PARAM_A) {
|
||||
return "NOISE";
|
||||
} else if (type == COMBINER_PARAM_B) {
|
||||
return "K4";
|
||||
} else if (type == COMBINER_PARAM_C) {
|
||||
return "COMBINED_ALPHA";
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
if (type != COMBINER_PARAM_C) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
switch (param) {
|
||||
case 8:
|
||||
return "TEXEL0_ALPHA";
|
||||
case 9:
|
||||
return "TEXEL1_ALPHA";
|
||||
case 10:
|
||||
return "PRIMITIVE_ALPHA";
|
||||
case 11:
|
||||
return "SHADE_ALPHA";
|
||||
case 12:
|
||||
return "ENV_ALPHA";
|
||||
case 13:
|
||||
return "LOD_FRACTION";
|
||||
case 14:
|
||||
return "PRIM_LOD_FRAC";
|
||||
case 15:
|
||||
return "K5";
|
||||
default:
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
const char* emu64::combine_alpha(int param, int type) {
|
||||
switch (param) {
|
||||
case 0:
|
||||
return type == COMBINER_PARAM_C ? "LOD_FRACTION" : "COMBINED";
|
||||
case 1:
|
||||
return "TEXEL0";
|
||||
case 2:
|
||||
return "TEXEL1";
|
||||
case 3:
|
||||
return "PRIMITIVE";
|
||||
case 4:
|
||||
return "SHADE";
|
||||
case 5:
|
||||
return "ENVIRONMENT";
|
||||
case 6:
|
||||
return type == COMBINER_PARAM_C ? "PRIM_LOD_FRAC" : "1";
|
||||
case 7:
|
||||
return "0";
|
||||
}
|
||||
|
||||
/* There should be a default case here, but they forgot it. */
|
||||
/* It returns a pointer to the emu64 class instead. */
|
||||
#ifdef EMU64_FIX_COMBINE_NAME_RETURN_VALUES
|
||||
return "0";
|
||||
#endif
|
||||
}
|
||||
|
||||
void emu64::print_combine(u64 combine) {
|
||||
Gsetcombine_new* setcombine = (Gsetcombine_new*)&combine;
|
||||
this->Printf0(
|
||||
"gsDPSetCombineLERP(%s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s, %s,%s,%s,%s),",
|
||||
this->combine_name(setcombine->a0, COMBINER_PARAM_A), this->combine_name(setcombine->b0, COMBINER_PARAM_B),
|
||||
this->combine_name(setcombine->c0, COMBINER_PARAM_C), this->combine_name(setcombine->d0, COMBINER_PARAM_D),
|
||||
|
||||
this->combine_alpha(setcombine->Aa0, COMBINER_PARAM_A), this->combine_alpha(setcombine->Ab0, COMBINER_PARAM_B),
|
||||
this->combine_alpha(setcombine->Ac0, COMBINER_PARAM_C), this->combine_alpha(setcombine->Ad0, COMBINER_PARAM_D),
|
||||
|
||||
this->combine_name(setcombine->a1, COMBINER_PARAM_A), this->combine_name(setcombine->b1, COMBINER_PARAM_B),
|
||||
this->combine_name(setcombine->c1, COMBINER_PARAM_C), this->combine_name(setcombine->d1, COMBINER_PARAM_D),
|
||||
|
||||
this->combine_alpha(setcombine->Aa1, COMBINER_PARAM_A), this->combine_alpha(setcombine->Ab1, COMBINER_PARAM_B),
|
||||
this->combine_alpha(setcombine->Ac1, COMBINER_PARAM_C), this->combine_alpha(setcombine->Ad1, COMBINER_PARAM_D));
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
#include "libforest/emu64/emu64.hpp"
|
||||
|
||||
#include "boot.h"
|
||||
#include "terminal.h"
|
||||
#include "MSL_C/w_math.h"
|
||||
|
||||
u32 emu64::seg2k0(u32 segadr) {
|
||||
u32 k0;
|
||||
|
||||
if ((segadr >> 28) == 0) {
|
||||
if (segadr < 0x03000000) {
|
||||
this->Printf0(VT_COL(RED, WHITE) "segadr=%08x" VT_RST "\n", segadr);
|
||||
this->panic("segadr is over 0x03000000.", __FILE__, 20);
|
||||
k0 = segadr + 0x80000000;
|
||||
} else {
|
||||
k0 = (u32)this->segments[(segadr >> 24) & 0xF] + (segadr & 0xFFFFFF);
|
||||
}
|
||||
this->resolved_addresses++;
|
||||
} else {
|
||||
k0 = segadr;
|
||||
}
|
||||
|
||||
if ((k0 >> 31) == 0 || k0 < 0x80000000 || k0 >= 0x83000000) {
|
||||
this->Printf0("異常なアドレスです。%08x -> %08x\n", segadr, k0);
|
||||
this->panic("異常なアドレスです。", __FILE__, 77);
|
||||
this->abnormal_addresses++;
|
||||
}
|
||||
|
||||
return k0;
|
||||
}
|
||||
|
||||
/* @unused void guMtxXFMWF(MtxP, float, float, float, float, float, float*, float*, float*, float*) */
|
||||
|
||||
/* @unused void guMtxXFM1F(MtxP, float, float, float, float, float*, float*, float*) */
|
||||
|
||||
void guMtxXFM1F_dol(MtxP mtx, float x, float y, float z, float* ox, float* oy, float* oz) {
|
||||
*ox = mtx[0][0] * x + mtx[0][1] * y + mtx[0][2] * z + mtx[0][3];
|
||||
*oy = mtx[1][0] * x + mtx[1][1] * y + mtx[1][2] * z + mtx[1][3];
|
||||
*oz = mtx[2][0] * x + mtx[2][1] * y + mtx[2][2] * z + mtx[2][3];
|
||||
}
|
||||
|
||||
void guMtxXFM1F_dol7(MtxP mtx, float x, float y, float z, float* ox, float* oy, float* oz) {
|
||||
GC_Mtx inv;
|
||||
|
||||
PSMTXInverse(mtx, inv);
|
||||
*ox = inv[0][0] * x + inv[0][1] * y + inv[0][2] * z + inv[0][3];
|
||||
*oy = inv[1][0] * x + inv[1][1] * y + inv[1][2] * z + inv[1][3];
|
||||
*oz = inv[2][0] * x + inv[2][1] * y + inv[2][2] * z + inv[2][3];
|
||||
}
|
||||
|
||||
void guMtxXFM1F_dol2(MtxP mtx, GXProjectionType type, float x, float y, float z, float* ox, float* oy, float* oz) {
|
||||
if (type == GX_PERSPECTIVE) {
|
||||
f32 s = -1.0f / z;
|
||||
|
||||
*ox = mtx[0][0] * x * s - mtx[0][2];
|
||||
*oy = mtx[1][1] * y * s - mtx[1][2];
|
||||
*oz = mtx[2][3] * s - mtx[2][2];
|
||||
} else {
|
||||
*ox = mtx[0][0] * x + mtx[0][3];
|
||||
*oy = mtx[1][1] * y + mtx[1][3];
|
||||
*oz = mtx[2][2] * z + mtx[2][3];
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxXFM1F_dol2w(MtxP mtx, GXProjectionType type, float x, float y, float z, float* ox, float* oy, float* oz,
|
||||
float* ow) {
|
||||
if (type == GX_PERSPECTIVE) {
|
||||
*ox = mtx[0][0] * x + mtx[0][2] * z;
|
||||
*oy = mtx[1][1] * y + mtx[1][2] * z;
|
||||
*oz = mtx[2][3] + mtx[2][2] * z;
|
||||
*ow = -z;
|
||||
} else {
|
||||
*ox = mtx[0][0] * x + mtx[0][3];
|
||||
*oy = mtx[1][1] * y + mtx[1][3];
|
||||
*oz = mtx[2][2] * z + mtx[2][3];
|
||||
*ow = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float guMtxXFM1F_dol3(MtxP mtx, GXProjectionType type, float z) {
|
||||
if (type == GX_PERSPECTIVE) {
|
||||
return -mtx[2][3] / (z + mtx[2][2]);
|
||||
} else {
|
||||
return (z - mtx[2][3]) / mtx[2][2];
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxXFM1F_dol6w(MtxP mtx, GXProjectionType type, float x, float y, float z, float w, float* ox, float* oy,
|
||||
float* oz, float* ow) {
|
||||
if (type == GX_PERSPECTIVE) {
|
||||
float xScale = mtx[0][0];
|
||||
float yScale = mtx[1][1];
|
||||
float zScale = mtx[2][2];
|
||||
|
||||
float xRatioScaling = mtx[0][2];
|
||||
float yRatioScaling = mtx[1][2];
|
||||
float zSkew = mtx[2][3];
|
||||
|
||||
*ox = (yScale * zSkew * (x + xRatioScaling * w)) / (xScale * (yScale * zSkew));
|
||||
*oy = (xScale * zSkew * (y + yRatioScaling * w)) / (xScale * (yScale * zSkew));
|
||||
*oz = -w;
|
||||
*ow = (xScale * yScale * (z + zScale * w)) / (xScale * (yScale * zSkew));
|
||||
} else {
|
||||
float xScale = mtx[0][0];
|
||||
float xSkew = mtx[0][3];
|
||||
|
||||
float yScale = mtx[1][1];
|
||||
float ySkew = mtx[1][3];
|
||||
|
||||
float zScale = mtx[2][2];
|
||||
float zSkew = mtx[2][3];
|
||||
|
||||
float n = 1.0f / (xScale * yScale * zScale);
|
||||
|
||||
*ox = n * (yScale * zScale * (x - xSkew));
|
||||
*oy = n * (zScale * xScale * (y - ySkew));
|
||||
*oz = n * (xScale * yScale * (z - zSkew));
|
||||
*ow = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxXFM1F_dol6w1(MtxP mtx, GXProjectionType type, float x, float y, float z, float w, float* ox, float* oy,
|
||||
float* oz) {
|
||||
if (type == GX_PERSPECTIVE) {
|
||||
float xScale = mtx[0][0];
|
||||
float yScale = mtx[1][1];
|
||||
float zScale = mtx[2][2];
|
||||
|
||||
float xRatioScaling = mtx[0][2];
|
||||
float yRatioScaling = mtx[1][2];
|
||||
float zSkew = mtx[2][3];
|
||||
|
||||
float temp_f7 = 1.0f / (xScale * yScale * (z + (zScale * w)));
|
||||
|
||||
*ox = temp_f7 * (yScale * zSkew * (x + (xRatioScaling * w)));
|
||||
*oy = temp_f7 * (xScale * zSkew * (y + (yRatioScaling * w)));
|
||||
*oz = temp_f7 * (yScale * zSkew * xScale * -w);
|
||||
} else {
|
||||
float translateX = mtx[0][3];
|
||||
float translateY = mtx[1][3];
|
||||
float translateZ = mtx[2][3];
|
||||
|
||||
float scaleX = mtx[0][0];
|
||||
float scaleY = mtx[1][1];
|
||||
float scaleZ = mtx[2][2];
|
||||
|
||||
*ox = (x - translateX) / scaleX;
|
||||
*oy = (y - translateY) / scaleY;
|
||||
*oz = (z - translateZ) / scaleZ;
|
||||
}
|
||||
}
|
||||
|
||||
/* @unused void guMtxXFMWL(N64Mtx*, float, float, float, float, float*, float*, float*, float*) */
|
||||
|
||||
void guMtxNormalize(GC_Mtx mtx) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float magnitude = sqrtf(mtx[i][0] * mtx[i][0] + mtx[i][1] * mtx[i][1] + mtx[i][2] * mtx[i][2]);
|
||||
|
||||
mtx[i][0] *= 1.0f / magnitude;
|
||||
mtx[i][1] *= 1.0f / magnitude;
|
||||
mtx[i][2] *= 1.0f / magnitude;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Mtx -> N64Mtx, GC_Mtx -> Mtx */
|
||||
void N64Mtx_to_DOLMtx(const Mtx* n64, MtxP gc) {
|
||||
s16* fixed = ((s16*)n64) + 0;
|
||||
u16* frac = ((u16*)n64) + 16;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
gc[0][i] = fastcast_float(&fixed[0]) + fastcast_float(&frac[0]) * (1.0f / 65536.0f);
|
||||
gc[1][i] = fastcast_float(&fixed[1]) + fastcast_float(&frac[1]) * (1.0f / 65536.0f);
|
||||
gc[2][i] = fastcast_float(&fixed[2]) + fastcast_float(&frac[2]) * (1.0f / 65536.0f);
|
||||
|
||||
fixed += 4;
|
||||
frac += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* @unused my_guMtxL2F(MtxP, const N64Mtx*) */
|
||||
Reference in New Issue
Block a user