Match paired-single/quantization (psq) functions (#89)

* Match rspLoadMatrix

* Match frameSetLookAt

* Match frameSetLight

* Match handwritten PSMTX44MultVecNoW

* Match frameLoadVertex

* Format and small fixes

* Missed some bools

* Decode some float constants
This commit is contained in:
cadmic
2024-05-03 11:34:22 -07:00
committed by GitHub
parent fdd4bec8df
commit af6e395b6c
8 changed files with 719 additions and 55 deletions
+156 -7
View File
@@ -13,12 +13,13 @@ extern "C" {
#define OS_FASTCAST_U8 2
#define OS_FASTCAST_U16 3
#define OS_FASTCAST_S8 4
#define OS_FASTCAST_S16 5
// clang-format off
static inline void OSInitFastCast(void) {
#ifdef __MWERKS__
asm
{
// clang-format off
asm {
li r3, OS_GQR_U8
oris r3, r3, OS_GQR_U8
mtspr GQR2, r3
@@ -34,12 +35,160 @@ static inline void OSInitFastCast(void) {
li r3, OS_GQR_S16
oris r3, r3, OS_GQR_S16
mtspr GQR5, r3
}
#else
}
// clang-format off
#endif
}
// clang-format off
static inline f32 __OSu8tof32(register u8* arg) {
register f32 ret;
#ifdef __MWERKS__
// clang-format off
asm {
psq_l ret, 0(arg), 1, OS_FASTCAST_U8
}
// clang-format on
#else
ret = (f32)*arg;
#endif
return ret;
}
static inline f32 __OSu16tof32(register u16* arg) {
register f32 ret;
#ifdef __MWERKS__
// clang-format off
asm {
psq_l ret, 0(arg), 1, OS_FASTCAST_U16
}
// clang-format on
#else
ret = (f32)*arg;
#endif
return ret;
}
static inline f32 __OSs8tof32(register s8* arg) {
register f32 ret;
#ifdef __MWERKS__
// clang-format off
asm {
psq_l ret, 0(arg), 1, OS_FASTCAST_S8
}
// clang-format on
#else
ret = (f32)*arg;
#endif
return ret;
}
static inline f32 __OSs16tof32(register s16* arg) {
register f32 ret;
#ifdef __MWERKS__
// clang-format off
asm {
psq_l ret, 0(arg), 1, OS_FASTCAST_S16
}
// clang-format on
#else
ret = (f32)*arg;
#endif
return ret;
}
static inline void OSu8tof32(u8* in, f32* out) { *out = __OSu8tof32(in); }
static inline void OSu16tof32(u16* in, f32* out) { *out = __OSu16tof32(in); }
static inline void OSs8tof32(s8* in, f32* out) { *out = __OSs8tof32(in); }
static inline void OSs16tof32(s16* in, f32* out) { *out = __OSs16tof32(in); }
static inline u8 __OSf32tou8(register f32 arg) {
f32 a;
register f32* ptr = &a;
u8 r;
#ifdef __MWERKS__
// clang-format off
asm {
psq_st arg, 0(ptr), 1, OS_FASTCAST_U8
}
// clang-format on
r = *(u8*)ptr;
#else
r = (u8)arg;
#endif
return r;
}
static inline u16 __OSf32tou16(register f32 arg) {
f32 a;
register f32* ptr = &a;
u16 r;
#ifdef __MWERKS__
// clang-format off
asm {
psq_st arg, 0(ptr), 1, OS_FASTCAST_U16
}
// clang-format on
r = *(u16*)ptr;
#else
r = (u16)arg;
#endif
return r;
}
static inline s8 __OSf32tos8(register f32 arg) {
f32 a;
register f32* ptr = &a;
s8 r;
#ifdef __MWERKS__
// clang-format off
asm {
psq_st arg, 0(ptr), 1, OS_FASTCAST_S8
}
// clang-format on
r = *(s8*)ptr;
#else
r = (s8)arg;
#endif
return r;
}
static inline s16 __OSf32tos16(register f32 arg) {
f32 a;
register f32* ptr = &a;
s16 r;
#ifdef __MWERKS__
// clang-format off
asm {
psq_st arg, 0(ptr), 1, OS_FASTCAST_S16
}
// clang-format on
r = *(s16*)ptr;
#else
r = (s16)arg;
#endif
return r;
}
static inline void OSf32tou8(f32* in, u8* out) { *out = __OSf32tou8(*in); }
static inline void OSf32tou16(f32* in, u16* out) { *out = __OSf32tou16(*in); }
static inline void OSf32tos8(f32* in, s8* out) { *out = __OSf32tos8(*in); }
static inline void OSf32tos16(f32* in, s16* out) { *out = __OSf32tos16(*in); }
#ifdef __cplusplus
}
+8 -8
View File
@@ -133,16 +133,16 @@ typedef struct FrameBuffer {
} FrameBuffer; // size = 0x14
// __anon_0x274AD
typedef struct Vect3F {
typedef struct Vec3f {
/* 0x0 */ f32 x;
/* 0x4 */ f32 y;
/* 0x8 */ f32 z;
} Vect3F; // size = 0xC
} Vec3f; // size = 0xC
// __anon_0x23CAB
typedef struct Light {
/* 0x00 */ bool bTransformed;
/* 0x04 */ Vect3F rVecOrigTowards;
/* 0x04 */ Vec3f rVecOrigTowards;
/* 0x10 */ f32 rColorR;
/* 0x14 */ f32 rColorG;
/* 0x18 */ f32 rColorB;
@@ -160,10 +160,10 @@ typedef struct Light {
// __anon_0x23EDB
typedef struct LookAt {
/* 0x00 */ bool bTransformed;
/* 0x04 */ Vect3F rS;
/* 0x10 */ Vect3F rT;
/* 0x1C */ Vect3F rSRaw;
/* 0x28 */ Vect3F rTRaw;
/* 0x04 */ Vec3f rS;
/* 0x10 */ Vec3f rT;
/* 0x1C */ Vec3f rSRaw;
/* 0x28 */ Vec3f rTRaw;
} LookAt; // size = 0x34
// __anon_0x23FC4
@@ -171,7 +171,7 @@ typedef struct Vertex {
/* 0x00 */ f32 rSum;
/* 0x04 */ f32 rS;
/* 0x08 */ f32 rT;
/* 0x0C */ Vect3F vec;
/* 0x0C */ Vec3f vec;
/* 0x18 */ u8 anColor[4];
} Vertex; // size = 0x1C
+9 -9
View File
@@ -64,7 +64,7 @@ typedef struct __anon_0x575BD {
typedef struct __anon_0x57890 {
/* 0x00 */ s32 iDL;
/* 0x04 */ s32 bValid;
/* 0x04 */ bool bValid;
/* 0x08 */ struct __anon_0x575BD task;
/* 0x48 */ s32 nCountVertex;
/* 0x4C */ __anon_0x60B3F eTypeUCode;
@@ -107,9 +107,9 @@ typedef struct __anon_0x57E56 {
/* 0x0 */ u8 nRed;
/* 0x1 */ u8 nGreen;
/* 0x2 */ u8 nBlue;
/* 0x3 */ char rVectorX;
/* 0x4 */ char rVectorY;
/* 0x5 */ char rVectorZ;
/* 0x3 */ s8 rVectorX;
/* 0x4 */ s8 rVectorY;
/* 0x5 */ s8 rVectorZ;
} __anon_0x57E56; // size = 0x6
typedef struct __anon_0x58107 {
@@ -215,11 +215,11 @@ typedef struct Rsp {
/* 0x39C8 */ s32* dctBuf;
} Rsp; // size = 0x39CC
s32 rspInvalidateCache(Rsp* pRSP, s32 nOffset0, s32 nOffset1);
s32 rspEnableABI(Rsp* pRSP, s32 bFlag);
s32 rspFrameComplete(Rsp* pRSP);
s32 rspUpdate(Rsp* pRSP, RspUpdateMode eMode);
s32 rspEvent(Rsp* pRSP, s32 nEvent, void* pArgument);
bool rspInvalidateCache(Rsp* pRSP, s32 nOffset0, s32 nOffset1);
bool rspEnableABI(Rsp* pRSP, bool bFlag);
bool rspFrameComplete(Rsp* pRSP);
bool rspUpdate(Rsp* pRSP, RspUpdateMode eMode);
bool rspEvent(Rsp* pRSP, s32 nEvent, void* pArgument);
extern _XL_OBJECTTYPE gClassRSP;
+2
View File
@@ -10,6 +10,8 @@
#define OFFSETOF(p, field) ((u8*)&(p)->field - (u8*)(p))
#define SQ(x) ((x) * (x))
// Adds no-ops to increase a function's size, preventing automatic inlining
#define NO_INLINE() \
(void)0; \
+22 -7
View File
@@ -121,6 +121,8 @@ _MATH_INLINE float powf(float __x, float __y) { return pow(__x, __y); }
#define FP_NORMAL 4
#define FP_SUBNORMAL 5
double __frsqrte(double x);
static inline int __fpclassifyf(float x) {
switch ((*(_INT32*)&x) & 0x7f800000) {
case 0x7f800000: {
@@ -174,13 +176,10 @@ extern inline float sqrtf(float x) {
volatile float y;
if (x > 0.0f) {
double guess = __frsqrte((double)x); /* returns an approximation to */
guess = _half * guess * (_three - guess * guess * x); /* now have 12 sig bits
*/
guess = _half * guess * (_three - guess * guess * x); /* now have 24 sig bits
*/
guess = _half * guess * (_three - guess * guess * x); /* now have 32 sig bits
*/
double guess = __frsqrte((double)x); /* returns an approximation to */
guess = _half * guess * (_three - guess * guess * x); /* now have 12 sig bits */
guess = _half * guess * (_three - guess * guess * x); /* now have 24 sig bits */
guess = _half * guess * (_three - guess * guess * x); /* now have 32 sig bits */
y = (float)(x * guess);
return y;
}
@@ -203,6 +202,22 @@ _MATH_INLINE double sqrt(double x) {
return INFINITY;
}
_MATH_INLINE float _inv_sqrtf(float x) {
const float _half = .5f;
const float _three = 3.0f;
if (x > 0.0f) {
float guess = __frsqrte((double)x); /* returns an approximation to */
guess = _half * guess * (_three - guess * guess * x); /* now have 8 sig bits */
guess = _half * guess * (_three - guess * guess * x); /* now have 16 sig bits */
guess = _half * guess * (_three - guess * guess * x); /* now have >24 sig bits */
return guess;
} else if (x) {
return NAN;
}
return INFINITY;
}
static inline float ldexpf(float x, int exp) { return (float)ldexp((double)x, exp); }
static inline double scalbn(double x, int n) { return ldexp(x, n); }
static inline float scalbnf(float x, int n) { return (float)ldexpf(x, n); }
+392 -7
View File
@@ -9,6 +9,7 @@
#include "emulator/xlHeap.h"
#include "emulator/xlObject.h"
#include "macros.h"
#include "math.h"
const s32 D_800D31C0[] = {
0x00000006, 0x00000000, 0x00000005, 0x00020000, 0x00000004, 0x00030000, 0x00000003, 0x00038000,
@@ -415,17 +416,15 @@ const f32 D_80135F7C = 0.25999999046325684;
const f32 D_80135F80 = 8.4399995803833;
const f64 D_80135F88 = 8.44;
// TODO: caused by inline asm somewhere, remove when that function is matched
#pragma peephole off
static bool frameDrawSetupSP(Frame* pFrame, s32* pnColors, bool* pbFlag, s32 nVertexCount);
static bool frameDrawSetupDP(Frame* pFrame, s32* pnColors, bool* pbFlag, s32);
static bool frameDrawRectFill(Frame* pFrame, Rectangle* pRectangle);
static bool frameDrawTriangle_Setup(Frame* pFrame, Primitive* pPrimitive);
static bool frameDrawRectTexture_Setup(Frame* pFrame, Rectangle* pRectangle);
inline bool frameGetMatrixHint(Frame* pFrame, u32 nAddress, s32* piHint);
static inline bool frameGetMatrixHint(Frame* pFrame, u32 nAddress, s32* piHint);
static inline bool frameResetCache(Frame* pFrame);
static bool frameSetupCache(Frame* pFrame);
void PSMTX44MultVecNoW(Mtx44 m, Vec3f* src, Vec3f* dst);
inline bool frameSetProjection(Frame* pFrame, s32 iHint) {
MatrixHint* pHint = &pFrame->aMatrixHint[iHint];
@@ -2137,7 +2136,314 @@ bool frameGetMatrix(Frame* pFrame, Mtx44 matrix, FrameMatrixType eType, bool bPu
return true;
}
// TODO: move these paired-single/quantization functions to a separate header
// along with the GQR initialization in xlMain()?
inline void s16tof32(register s16* in, register f32* out) { OSs16tof32(in, out); }
inline void s16tof32Pair(register s16* in, register f32* out) {
#ifdef __MWERKS__
// clang-format off
asm {
psq_l f1, 0(in), 0, OS_FASTCAST_S16
psq_st f1, 0(out), 0, 0
}
// clang-format on
#else
out[0] = (f32)in[0];
out[1] = (f32)in[1];
#endif
}
inline void s8tof32Scaled128(register s8* in, register f32* out) {
#ifdef __MWERKS__
// clang-format off
asm {
psq_l f1, 0(in), 1, 6
stfs f1, 0(out)
}
// clang-format on
#else
*out = (f32)*in / 128.0f;
#endif
}
inline void s8tof32Scaled128Pair(register s8* in, register f32* out) {
#ifdef __MWERKS__
// clang-format off
asm {
psq_l f1, 0(in), 0, 6
psq_st f1, 0(out), 0, 0
}
// clang-format on
#else
out[0] = (f32)in[0] / 128.0f;
out[1] = (f32)in[1] / 128.0f;
#endif
}
inline void s16tof32Scaled32Pair(register s16* src, register f32* dst) {
#ifdef __MWERKS__
// clang-format off
asm {
psq_l f1, 0(src), 0, 7
psq_st f1, 0(dst), 0, 0
}
// clang-format on
#else
dst[0] = (f32)src[0] / 32.0f;
dst[1] = (f32)src[1] / 32.0f;
#endif
}
// Matches but data doesn't
#ifndef NON_MATCHING
#pragma GLOBAL_ASM("asm/non_matchings/frame/frameLoadVertex.s")
#else
bool frameLoadVertex(Frame* pFrame, void* pBuffer, s32 iVertex0, s32 nCount) {
f32 mag;
s32 iLight;
s32 nLight;
s32 nTexGen;
f32 colorS;
f32 colorT;
f32 rS;
f32 rT;
f32 arNormal[3];
f32 arPosition[3];
Vertex* pVertex;
u32 nData32;
Light* aLight;
Light* pLight;
s32 iVertex1;
// f32 rScale;
// f32 rScaleST;
s8* pnData8;
s16* pnData16;
Mtx44Ptr matrixView;
Mtx44Ptr matrixModel;
f32 rColorR;
f32 rColorG;
f32 rColorB;
f32 rDiffuse;
f32 rInverseW;
f32 rInverseLength;
Vec3f vec;
f32 distance;
pnData8 = pBuffer;
pnData16 = pBuffer;
iVertex1 = iVertex0 + nCount - 1;
if (iVertex0 < 0 || iVertex0 >= 80 || iVertex1 < 0 || iVertex1 >= 80) {
return false;
}
matrixModel = pFrame->aMatrixModel[pFrame->iMatrixModel];
if (pFrame->nMode & 0x08000000) {
// TODO: volatile hacks
if (!(*(volatile u32*)&pFrame->nMode & 0x400000)) {
PSMTX44Concat(matrixModel, pFrame->matrixProjectionExtra, pFrame->matrixView);
pFrame->nMode |= 0x400000;
if (pFrame->iHintProjection != -1) {
if (!frameScaleMatrix(pFrame->matrixView, pFrame->matrixView,
pFrame->aMatrixHint[pFrame->iHintProjection].rScale)) {
return false;
}
}
}
matrixView = pFrame->matrixView;
// TODO: volatile hacks
} else if (!(*(volatile u32*)&pFrame->nMode & 0x400000) && pFrame->iHintProjection != -1) {
if (!frameScaleMatrix(pFrame->matrixView, matrixModel, pFrame->aMatrixHint[pFrame->iHintProjection].rScale)) {
return false;
}
pFrame->nMode |= 0x400000;
matrixView = pFrame->matrixView;
} else {
matrixView = matrixModel;
}
if (pFrame->aMode[1] & 0x20) {
nLight = pFrame->nCountLight;
nTexGen = pFrame->aMode[1] & 0x180;
aLight = pFrame->aLight;
for (iLight = 0; iLight < nLight; iLight++) {
pLight = &aLight[iLight];
if (!pLight->bTransformed || !(pFrame->nMode & 0x200000)) {
PSMTX44MultVecNoW(matrixModel, &pLight->rVecOrigTowards, &vec);
rInverseLength = _inv_sqrtf(SQ(vec.x) + SQ(vec.y) + SQ(vec.z));
pLight->rVectorX = vec.x * rInverseLength;
pLight->rVectorY = vec.y * rInverseLength;
pLight->rVectorZ = vec.z * rInverseLength;
pLight->bTransformed = true;
}
}
if (nTexGen != 0 && (!pFrame->lookAt.bTransformed || !(pFrame->nMode & 0x200000))) {
if (!(pFrame->nMode & 0x01000000)) {
pFrame->lookAt.rSRaw.x = 0.0f;
pFrame->lookAt.rSRaw.y = 1.0f;
pFrame->lookAt.rSRaw.z = 0.0f;
}
if (!(pFrame->nMode & 0x02000000)) {
pFrame->lookAt.rTRaw.x = 1.0f;
pFrame->lookAt.rTRaw.y = 0.0f;
pFrame->lookAt.rTRaw.z = 0.0f;
}
PSMTX44MultVecNoW(matrixModel, &pFrame->lookAt.rSRaw, &pFrame->lookAt.rS);
PSMTX44MultVecNoW(matrixModel, &pFrame->lookAt.rTRaw, &pFrame->lookAt.rT);
mag = SQ(pFrame->lookAt.rS.x) + SQ(pFrame->lookAt.rS.y) + SQ(pFrame->lookAt.rS.z);
if (mag > 0.0f) {
rInverseLength = _inv_sqrtf(mag);
pFrame->lookAt.rS.x *= rInverseLength;
pFrame->lookAt.rS.y *= rInverseLength;
pFrame->lookAt.rS.z *= rInverseLength;
}
mag = SQ(pFrame->lookAt.rT.x) + SQ(pFrame->lookAt.rT.y) + SQ(pFrame->lookAt.rT.z);
if (mag > 0.0f) {
rInverseLength = _inv_sqrtf(mag);
pFrame->lookAt.rT.x *= rInverseLength;
pFrame->lookAt.rT.y *= rInverseLength;
pFrame->lookAt.rT.z *= rInverseLength;
}
pFrame->lookAt.bTransformed = true;
}
pFrame->nMode |= 0x200000;
} else {
nTexGen = 0;
nLight = 0;
}
pVertex = &pFrame->aVertex[iVertex0];
while (nCount-- != 0) {
s16tof32Pair(&pnData16[0], &arPosition[0]);
s16tof32(&pnData16[2], &arPosition[2]);
pVertex->rSum = arPosition[0] + arPosition[1] + arPosition[2];
rInverseW = 1.0f / (matrixView[0][3] * arPosition[0] + matrixView[1][3] * arPosition[1] +
matrixView[2][3] * arPosition[2] + matrixView[3][3]);
pVertex->vec.x = rInverseW * (arPosition[0] * matrixView[0][0] + arPosition[1] * matrixView[1][0] +
arPosition[2] * matrixView[2][0] + matrixView[3][0]);
pVertex->vec.y = rInverseW * (arPosition[0] * matrixView[0][1] + arPosition[1] * matrixView[1][1] +
arPosition[2] * matrixView[2][1] + matrixView[3][1]);
pVertex->vec.z = rInverseW * (arPosition[0] * matrixView[0][2] + arPosition[1] * matrixView[1][2] +
arPosition[2] * matrixView[2][2] + matrixView[3][2]);
if (nLight != 0) {
s8tof32Scaled128Pair(&pnData8[12], &arNormal[0]);
s8tof32Scaled128(&pnData8[14], &arNormal[2]);
iLight = nLight;
pLight = &aLight[iLight];
if (gpSystem->eTypeROM == SRT_STARFOX) {
while ((rColorR = pLight->rColorR) + (rColorG = pLight->rColorG) + (rColorB = pLight->rColorB) ==
0.0f) {
pLight++;
}
pLight = &aLight[iLight];
} else {
rColorR = pLight->rColorR;
rColorG = pLight->rColorG;
rColorB = pLight->rColorB;
}
while (--iLight >= 0) {
pLight--;
if ((pFrame->aMode[1] & 0x800) && pLight->kc != 0.0f) {
distance = sqrtf(SQ(pLight->coordX - arPosition[0]) + SQ(pLight->coordY - arPosition[1]) +
SQ(pLight->coordZ - arPosition[2]));
pLight->rVectorX = (pLight->coordX - arPosition[0]) / distance;
pLight->rVectorY = (pLight->coordY - arPosition[1]) / distance;
pLight->rVectorZ = (pLight->coordZ - arPosition[2]) / distance;
rDiffuse = (pLight->rVectorX * arNormal[0] + pLight->rVectorY * arNormal[1] +
pLight->rVectorZ * arNormal[2]) /
(pLight->kc + pLight->kl * distance + pLight->kq * distance * distance);
if (rDiffuse > 1.0f) {
rDiffuse = 1.0f;
}
} else {
rDiffuse = pLight->rVectorX * arNormal[0] + pLight->rVectorY * arNormal[1] +
pLight->rVectorZ * arNormal[2];
}
if (rDiffuse > 0.0f) {
rColorR += pLight->rColorR * rDiffuse;
rColorG += pLight->rColorG * rDiffuse;
rColorB += pLight->rColorB * rDiffuse;
}
}
OSf32tou8(&rColorR, &pVertex->anColor[0]);
OSf32tou8(&rColorG, &pVertex->anColor[1]);
OSf32tou8(&rColorB, &pVertex->anColor[2]);
pVertex->anColor[3] = pnData8[15];
if (nTexGen != 0) {
rS = arNormal[0] * pFrame->lookAt.rS.x + arNormal[1] * pFrame->lookAt.rS.y +
arNormal[2] * pFrame->lookAt.rS.z;
rT = arNormal[0] * pFrame->lookAt.rT.x + arNormal[1] * pFrame->lookAt.rT.y +
arNormal[2] * pFrame->lookAt.rT.z;
if (nTexGen & 0x100) {
colorS = rS * rS * rS;
colorS = (0.22673f * colorS) + colorS;
rS = ((1.0f / (f32)M_PI) * rS) + colorS;
colorT = rT * rT * rT;
colorT = (0.22673f * colorT) + colorT;
rT = ((1.0f / (f32)M_PI) * rT) + colorT;
} else {
rS *= 0.5f;
rT *= 0.5f;
}
pVertex->rS = rS + 0.5f;
pVertex->rT = rT + 0.5f;
}
} else {
nData32 = *(u32*)&pnData8[12];
pVertex->anColor[0] = nData32 >> 24;
pVertex->anColor[1] = nData32 >> 16;
pVertex->anColor[2] = nData32 >> 8;
pVertex->anColor[3] = nData32;
if (nTexGen != 0) {
s8tof32Scaled128Pair(&pnData8[12], &arNormal[0]);
s8tof32Scaled128(&pnData8[14], &arNormal[2]);
rS = arNormal[0] * pFrame->lookAt.rS.x + arNormal[1] * pFrame->lookAt.rS.y +
arNormal[2] * pFrame->lookAt.rS.z;
rT = arNormal[0] * pFrame->lookAt.rT.x + arNormal[1] * pFrame->lookAt.rT.y +
arNormal[2] * pFrame->lookAt.rT.z;
if (nTexGen & 0x100) {
colorS = rS * rS * rS;
colorS = (0.22673f * colorS) + colorS;
rS = ((1.0f / (f32)M_PI) * rS) + colorS;
colorT = rT * rT * rT;
colorT = (0.22673f * colorT) + colorT;
rT = ((1.0f / (f32)M_PI) * rT) + colorT;
} else {
rS *= 0.5f;
rT *= 0.5f;
}
pVertex->rS = rS + 0.5f;
pVertex->rT = rT + 0.5f;
}
}
if (nTexGen == 0) {
s16tof32Scaled32Pair(&pnData16[4], &pVertex->rS);
}
pVertex++;
pnData8 += 0x10;
pnData16 += 0x8;
}
return true;
}
#endif
#pragma GLOBAL_ASM("asm/non_matchings/frame/frameCullDL.s")
@@ -2150,9 +2456,63 @@ bool frameSetLightCount(Frame* pFrame, s32 nCount) {
return true;
}
// Matches but data doesn't
#ifndef NON_MATCHING
#pragma GLOBAL_ASM("asm/non_matchings/frame/frameSetLight.s")
#else
bool frameSetLight(Frame* pFrame, s32 iLight, s8* pData) {
Light* pLight;
#pragma GLOBAL_ASM("asm/non_matchings/frame/frameSetLookAt.s")
if (iLight >= 0 && iLight < 8) {
pLight = &pFrame->aLight[iLight];
pLight->bTransformed = false;
if (pData[3] != 0) {
pLight->kc = (u8)pData[3] * 0.0078125f + 0.0625f;
pLight->kl = (u8)pData[7] / 4096.0f;
pLight->kq = (u8)pData[14] / 4194304.0f;
pLight->coordX = *(s16*)&pData[8];
pLight->coordY = *(s16*)&pData[10];
pLight->coordZ = *(s16*)&pData[12];
} else {
pLight->kc = 0.0f;
}
OSu8tof32((u8*)&pData[0], &pLight->rColorR);
OSu8tof32((u8*)&pData[1], &pLight->rColorG);
OSu8tof32((u8*)&pData[2], &pLight->rColorB);
s8tof32Scaled128(&pData[8], &pLight->rVecOrigTowards.x);
s8tof32Scaled128(&pData[9], &pLight->rVecOrigTowards.y);
s8tof32Scaled128(&pData[10], &pLight->rVecOrigTowards.z);
return true;
} else {
return false;
}
}
#endif
bool frameSetLookAt(Frame* pFrame, s32 iLookAt, s8* pData) {
switch (iLookAt) {
case 0:
s8tof32Scaled128(&pData[8], &pFrame->lookAt.rSRaw.x);
s8tof32Scaled128(&pData[9], &pFrame->lookAt.rSRaw.y);
s8tof32Scaled128(&pData[10], &pFrame->lookAt.rSRaw.z);
pFrame->nMode |= 0x01000000;
break;
case 1:
s8tof32Scaled128(&pData[8], &pFrame->lookAt.rTRaw.x);
s8tof32Scaled128(&pData[9], &pFrame->lookAt.rTRaw.y);
s8tof32Scaled128(&pData[10], &pFrame->lookAt.rTRaw.z);
pFrame->nMode |= 0x02000000;
break;
default:
return false;
}
pFrame->lookAt.bTransformed = false;
return true;
}
#pragma GLOBAL_ASM("asm/non_matchings/frame/frameSetViewport.s")
@@ -2233,7 +2593,7 @@ bool frameSetMatrixHint(Frame* pFrame, FrameMatrixProjection eProjection, s32 nA
}
if (eProjection == 1) {
rScale = 0.0f;
rNear = 0.0f;
}
pFrame->aMatrixHint[iHint].nCount = 4;
@@ -2308,4 +2668,29 @@ bool frameGetTextureInfo(Frame* pFrame, TextureInfo* pInfo) {
}
#endif
#pragma GLOBAL_ASM("asm/non_matchings/frame/PSMTX44MultVecNoW.s")
ASM void PSMTX44MultVecNoW(Mtx44 m, Vec3f* src, Vec3f* dst) {
#ifdef __MWERKS__ // clang-format off
nofralloc
psq_l f0, 0(r4), 0, 0
psq_l f1, 8(r4), 1, 0
psq_l f4, 0(r3), 0, 0
psq_l f5, 8(r3), 0, 0
psq_l f6, 16(r3), 0, 0
psq_l f7, 24(r3), 0, 0
psq_l f8, 32(r3), 0, 0
psq_l f9, 40(r3), 0, 0
ps_mul f4, f0, f4
ps_madd f2, f1, f5, f4
ps_mul f6, f0, f6
ps_madd f3, f1, f7, f6
ps_mul f8, f0, f8
ps_sum0 f2, f2, f2, f2
ps_madd f9, f1, f9, f8
ps_sum1 f2, f3, f2, f3
ps_sum0 f3, f9, f9, f9
psq_st f2, 0(r5), 0, 0
psq_st f3, 8(r5), 1, 0
blr
#endif // clang-format on
}
+129
View File
@@ -1,5 +1,9 @@
#include "emulator/rsp.h"
#include "emulator/cpu.h"
#include "emulator/ram.h"
#include "emulator/rdp.h"
#include "emulator/rsp_jumptables.h"
#include "emulator/system.h"
_XL_OBJECTTYPE gClassRSP = {
"RSP",
@@ -315,7 +319,132 @@ const f32 D_80136074 = 1.52587890625e-05;
#pragma GLOBAL_ASM("asm/non_matchings/rsp/rspParseGBI_F3DEX2.s")
// Matches but data doesn't
#ifndef NON_MATCHING
#pragma GLOBAL_ASM("asm/non_matchings/rsp/rspLoadMatrix.s")
#else
static bool rspLoadMatrix(Rsp* pRSP, s32 nAddress, Mtx44 matrix) {
s32* pMtx;
s32 nDataA;
s32 nDataB;
f32 rScale;
f32 rUpper;
f32 rLower;
u16 nUpper;
u16 nLower;
rScale = 1.0f / 65536.0f;
if (!ramGetBuffer(SYSTEM_RAM(pRSP->pHost), &pMtx, nAddress, NULL)) {
return false;
}
nDataA = pMtx[0];
nDataB = pMtx[8];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[0][0] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[0][1] = rUpper + rLower * rScale;
nDataA = pMtx[1];
nDataB = pMtx[9];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[0][2] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[0][3] = rUpper + rLower * rScale;
nDataA = pMtx[2];
nDataB = pMtx[10];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[1][0] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[1][1] = rUpper + rLower * rScale;
nDataA = pMtx[3];
nDataB = pMtx[11];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[1][2] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[1][3] = rUpper + rLower * rScale;
nDataA = pMtx[4];
nDataB = pMtx[12];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[2][0] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[2][1] = rUpper + rLower * rScale;
nDataA = pMtx[5];
nDataB = pMtx[13];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[2][2] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[2][3] = rUpper + rLower * rScale;
nDataA = pMtx[6];
nDataB = pMtx[14];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[3][0] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[3][1] = rUpper + rLower * rScale;
nDataA = pMtx[7];
nDataB = pMtx[15];
nUpper = nDataA >> 16;
nLower = nDataB >> 16;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[3][2] = rUpper + rLower * rScale;
nUpper = nDataA & 0xFFFF;
nLower = nDataB & 0xFFFF;
OSs16tof32((s16*)&nUpper, &rUpper);
OSu16tof32(&nLower, &rLower);
matrix[3][3] = rUpper + rLower * rScale;
return true;
}
#endif
#pragma GLOBAL_ASM("asm/non_matchings/rsp/rspFindUCode.s")
+1 -17
View File
@@ -155,23 +155,7 @@ int main(int nCount, char** aszArgument) {
__PADDisableRecalibration(true);
OSInitAlarm();
#ifdef __MWERKS__
asm {
li r3, 4
oris r3, r3, 4
mtspr GQR2, r3
li r3, 5
oris r3, r3, 5
mtspr GQR3, r3
li r3, 6
oris r3, r3, 6
mtspr GQR4, r3
li r3, 7
oris r3, r3, 7
mtspr GQR5, r3
}
#endif
OSInitFastCast();
nSizeHeap = 0;