diff --git a/Core/HLE/sceGe.cpp b/Core/HLE/sceGe.cpp index 81667a448e..1fcfc23b64 100644 --- a/Core/HLE/sceGe.cpp +++ b/Core/HLE/sceGe.cpp @@ -518,49 +518,17 @@ u32 sceGeRestoreContext(u32 ctxAddr) { return 0; } -static void __GeCopyMatrix(u32 matrixPtr, float *mtx, u32 size) { - for (u32 i = 0; i < size / sizeof(float); ++i) { - Memory::Write_U32(toFloat24(mtx[i]), matrixPtr + i * sizeof(float)); - } -} - static int sceGeGetMtx(int type, u32 matrixPtr) { - if (!Memory::IsValidAddress(matrixPtr)) { - ERROR_LOG(SCEGE, "sceGeGetMtx(%d, %08x) - bad matrix ptr", type, matrixPtr); - return -1; + int size = type == GE_MTX_PROJECTION ? 16 : 12; + if (!Memory::IsValidRange(matrixPtr, size * sizeof(float))) { + return hleLogError(SCEGE, -1, "bad matrix ptr"); } - INFO_LOG(SCEGE, "sceGeGetMtx(%d, %08x)", type, matrixPtr); - switch (type) { - case GE_MTX_BONE0: - case GE_MTX_BONE1: - case GE_MTX_BONE2: - case GE_MTX_BONE3: - case GE_MTX_BONE4: - case GE_MTX_BONE5: - case GE_MTX_BONE6: - case GE_MTX_BONE7: - { - int n = type - GE_MTX_BONE0; - __GeCopyMatrix(matrixPtr, gstate.boneMatrix + n * 12, 12 * sizeof(float)); - } - break; - case GE_MTX_TEXGEN: - __GeCopyMatrix(matrixPtr, gstate.tgenMatrix, 12 * sizeof(float)); - break; - case GE_MTX_WORLD: - __GeCopyMatrix(matrixPtr, gstate.worldMatrix, 12 * sizeof(float)); - break; - case GE_MTX_VIEW: - __GeCopyMatrix(matrixPtr, gstate.viewMatrix, 12 * sizeof(float)); - break; - case GE_MTX_PROJECTION: - __GeCopyMatrix(matrixPtr, gstate.projMatrix, 16 * sizeof(float)); - break; - default: - return SCE_KERNEL_ERROR_INVALID_INDEX; - } - return 0; + u32 *dest = (u32 *)Memory::GetPointerWriteUnchecked(matrixPtr); + if (!gpu || !gpu->GetMatrix24(GEMatrixType(type), dest)) + return hleLogError(SCEGE, SCE_KERNEL_ERROR_INVALID_INDEX, "invalid matrix"); + + return hleLogSuccessInfoI(SCEGE, 0); } static u32 sceGeGetCmd(int cmd) { @@ -631,7 +599,7 @@ const HLEFunction sceGe_user[] = { {0X1F6752AD, &WrapU_V, "sceGeEdramGetSize", 'x', "" }, {0XB77905EA, &WrapU_I, "sceGeEdramSetAddrTranslation", 'x', "i" }, {0XDC93CFEF, &WrapU_I, "sceGeGetCmd", 'x', "i" }, - {0X57C8945B, &WrapI_IU, "sceGeGetMtx", 'i', "ix" }, + {0X57C8945B, &WrapI_IU, "sceGeGetMtx", 'i', "ip" }, {0X438A385A, &WrapU_U, "sceGeSaveContext", 'x', "x" }, {0X0BF608FB, &WrapU_U, "sceGeRestoreContext", 'x', "x" }, {0X5FB86AB0, &WrapI_U, "sceGeListDeQueue", 'i', "x" }, diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 56dbbbcf59..13fc85b19c 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -731,6 +731,42 @@ int GPUCommon::GetStack(int index, u32 stackPtr) { return currentList->stackptr; } +static void CopyMatrix24(u32 *result, float *mtx, u32 count) { + for (u32 i = 0; i < count; ++i) { + result[i] = toFloat24(mtx[i]); + } +} + +bool GPUCommon::GetMatrix24(GEMatrixType type, u32 *result) { + switch (type) { + case GE_MTX_BONE0: + case GE_MTX_BONE1: + case GE_MTX_BONE2: + case GE_MTX_BONE3: + case GE_MTX_BONE4: + case GE_MTX_BONE5: + case GE_MTX_BONE6: + case GE_MTX_BONE7: + CopyMatrix24(result, gstate.boneMatrix + (type - GE_MTX_BONE0) * 12, 12); + break; + case GE_MTX_TEXGEN: + CopyMatrix24(result, gstate.tgenMatrix, 12); + break; + case GE_MTX_WORLD: + CopyMatrix24(result, gstate.worldMatrix, 12); + break; + case GE_MTX_VIEW: + CopyMatrix24(result, gstate.viewMatrix, 12); + break; + case GE_MTX_PROJECTION: + CopyMatrix24(result, gstate.projMatrix, 16); + break; + default: + return false; + } + return true; +} + u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer args, bool head) { // TODO Check the stack values in missing arg and ajust the stack depth diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 36c27d72d7..480fe1df09 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -111,6 +111,7 @@ public: int ListSync(int listid, int mode) override; u32 DrawSync(int mode) override; int GetStack(int index, u32 stackPtr) override; + bool GetMatrix24(GEMatrixType type, u32 *result) override; void DoState(PointerWrap &p) override; bool BusyDrawing() override; u32 Continue() override; diff --git a/GPU/GPUInterface.h b/GPU/GPUInterface.h index 2ce7c48620..54d5492ea4 100644 --- a/GPU/GPUInterface.h +++ b/GPU/GPUInterface.h @@ -198,6 +198,7 @@ public: virtual u32 Continue() = 0; virtual u32 Break(int mode) = 0; virtual int GetStack(int index, u32 stackPtr) = 0; + virtual bool GetMatrix24(GEMatrixType type, u32 *result) = 0; virtual void InterruptStart(int listid) = 0; virtual void InterruptEnd(int listid) = 0;