From 693fe93eab71abb6e4b68df69c8836b0499cef43 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 4 Oct 2022 18:31:43 -0700 Subject: [PATCH] Fix linking with static libs, CVector3f work, Initial COutputStream --- asm/Kyoto/Streams/COutputStream.s | 13 ++- configure.py | 3 +- include/Kyoto/Math/CVector3f.hpp | 11 ++- include/Kyoto/Streams/COutputStream.hpp | 63 +++++++++++++ include/dolphin/os.h | 36 ++++++++ include/dolphin/os/OSAlarm.h | 7 ++ src/Kyoto/Math/CVector3f.cpp | 113 ++++++++++++++++++++++++ src/Kyoto/Streams/COutputStream.cpp | 50 +++++++++++ 8 files changed, 284 insertions(+), 12 deletions(-) create mode 100644 src/Kyoto/Math/CVector3f.cpp create mode 100644 src/Kyoto/Streams/COutputStream.cpp diff --git a/asm/Kyoto/Streams/COutputStream.s b/asm/Kyoto/Streams/COutputStream.s index d2846d15..bd65f464 100644 --- a/asm/Kyoto/Streams/COutputStream.s +++ b/asm/Kyoto/Streams/COutputStream.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803EE3B8 -lbl_803EE3B8: +.global __vt__13COutputStream +__vt__13COutputStream: # ROM: 0x3EB3B8 .4byte 0 .4byte 0 @@ -232,8 +232,8 @@ __dt__13COutputStreamFv: /* 8033F6A4 0033C604 93 C1 00 08 */ stw r30, 8(r1) /* 8033F6A8 0033C608 7C 7E 1B 79 */ or. r30, r3, r3 /* 8033F6AC 0033C60C 41 82 00 34 */ beq lbl_8033F6E0 -/* 8033F6B0 0033C610 3C 60 80 3F */ lis r3, lbl_803EE3B8@ha -/* 8033F6B4 0033C614 38 03 E3 B8 */ addi r0, r3, lbl_803EE3B8@l +/* 8033F6B0 0033C610 3C 60 80 3F */ lis r3, __vt__13COutputStream@ha +/* 8033F6B4 0033C614 38 03 E3 B8 */ addi r0, r3, __vt__13COutputStream@l /* 8033F6B8 0033C618 90 1E 00 00 */ stw r0, 0(r30) /* 8033F6BC 0033C61C 80 1E 00 08 */ lwz r0, 8(r30) /* 8033F6C0 0033C620 28 00 00 40 */ cmplwi r0, 0x40 @@ -258,13 +258,13 @@ lbl_8033F6E0: __ct__13COutputStreamFi: /* 8033F6FC 0033C65C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8033F700 0033C660 7C 08 02 A6 */ mflr r0 -/* 8033F704 0033C664 3C A0 80 3F */ lis r5, lbl_803EE3B8@ha +/* 8033F704 0033C664 3C A0 80 3F */ lis r5, __vt__13COutputStream@ha /* 8033F708 0033C668 2C 04 00 40 */ cmpwi r4, 0x40 /* 8033F70C 0033C66C 90 01 00 14 */ stw r0, 0x14(r1) /* 8033F710 0033C670 38 00 00 00 */ li r0, 0 /* 8033F714 0033C674 93 E1 00 0C */ stw r31, 0xc(r1) /* 8033F718 0033C678 7C 7F 1B 78 */ mr r31, r3 -/* 8033F71C 0033C67C 38 65 E3 B8 */ addi r3, r5, lbl_803EE3B8@l +/* 8033F71C 0033C67C 38 65 E3 B8 */ addi r3, r5, __vt__13COutputStream@l /* 8033F720 0033C680 90 7F 00 00 */ stw r3, 0(r31) /* 8033F724 0033C684 90 1F 00 04 */ stw r0, 4(r31) /* 8033F728 0033C688 90 9F 00 08 */ stw r4, 8(r31) @@ -310,4 +310,3 @@ lbl_803D7A70: # ROM: 0x3D4A70 .asciz "??(??)" .balign 4 - diff --git a/configure.py b/configure.py index 7d37d35b..2f577449 100755 --- a/configure.py +++ b/configure.py @@ -134,6 +134,7 @@ LIBS = [ "objects": ["MetroTRK/mslsupp"], }, { + "lib": "MetroidPrimeCW", "cflags": "$cflags_retro", "mwcc_version": "1.3.2", "objects": [ @@ -1111,7 +1112,7 @@ LIBS = [ ] # Create & link static libraries -# Currently broken due to deadstripping +# Disabled by default for now until we can get it working on windows/macOS ENABLE_STATIC_LIBS = False # On Windows, we need this to use && in commands diff --git a/include/Kyoto/Math/CVector3f.hpp b/include/Kyoto/Math/CVector3f.hpp index b2fb6491..2cacef95 100644 --- a/include/Kyoto/Math/CVector3f.hpp +++ b/include/Kyoto/Math/CVector3f.hpp @@ -9,6 +9,7 @@ class CInputStream; class COutputStream; +class CRelAngle; enum EDimX { kDX }; enum EDimY { kDY }; @@ -31,13 +32,14 @@ public: void SetZ(f32 z) { mZ = z; } // ByElementMultiply__9CVector3fFRC9CVector3fRC9CVector3f - // Slerp__9CVector3fFRC9CVector3fRC9CVector3fRC9CRelAngle - void Normalize(); + static CVector3f Slerp(const CVector3f& a, const CVector3f& b, const CRelAngle& angle); + CVector3f& Normalize(); f32 Magnitude() const; CVector3f AsNormalized() const; + bool IsNotInf() const; + bool IsMagnitudeSafe() const; bool CanBeNormalized() const; - // GetAngleDiff__9CVector3fFRC9CVector3fRC9CVector3f - // IsEqu__9CVector3fCFRC9CVector3ff + static float GetAngleDiff(const CVector3f& a, const CVector3f& b); bool IsEqu(const CVector3f& other, f32 epsilon = FLT_EPSILON) const; // Lerp__9CVector3fFRC9CVector3fRC9CVector3ff // MagSquared__9CVector3fCFv weak @@ -104,6 +106,7 @@ private: f32 mZ; static CVector3f sZeroVector; + static int sUnkData[18]; static CVector3f sUpVector; static CVector3f sDownVector; static CVector3f sLeftVector; diff --git a/include/Kyoto/Streams/COutputStream.hpp b/include/Kyoto/Streams/COutputStream.hpp index 871cb99d..f6c8f918 100644 --- a/include/Kyoto/Streams/COutputStream.hpp +++ b/include/Kyoto/Streams/COutputStream.hpp @@ -3,9 +3,72 @@ #include "types.h" +class COutputStream; +template +void coutput_stream_helper(const T& t, COutputStream& out) { + t.PutTo(out); +} + class COutputStream { + void DoPut(const void* ptr, size_t len); + void Flush(); + void DoFlush(); public: + COutputStream(int len); + virtual ~COutputStream(); void WriteBits(int val, int bitCount); + + void FlushShiftRegister(); + void Put(const void* ptr, size_t len) { + FlushShiftRegister(); + DoPut(ptr, len); + } + + template + void Put(const T& t) { + coutput_stream_helper(t, *this); + } + + void WriteReal32(float t) { + Put(t); + } + + void WriteUint32(uint t) { + Put(t); + } + void WriteInt32(int t) { + Put(t); + } + + void WriteLong(int t) { + Put(&t, sizeof(int)); + } + +private: + uint mPosition; + uint mBufLen; + void* mBufPtr; + uint mNumWrites; + uint mShiftRegister; + uint mShiftRegisterOffset; + uchar mScratch[96]; }; +template <> +inline void coutput_stream_helper(const float& t, COutputStream& out) { + int tmp = *(int*)&t; + out.Put(&tmp, sizeof(float)); +} + +template<> +inline void coutput_stream_helper(const int& t, COutputStream& out) { + out.WriteLong(t); +} + +template<> +inline void coutput_stream_helper(const uint& t, COutputStream& out) { + out.WriteLong(t); +} + + #endif // _COUTPUTSTREAM_HPP diff --git a/include/dolphin/os.h b/include/dolphin/os.h index a197c4f5..c9807ada 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -61,6 +61,8 @@ void OSSetArenaLo(void* newLo); void* OSAllocFromArenaLo(u32 size, u32 align); void* OSAllocFromArenaHi(u32 size, u32 align); +void OSInit(); + OSTime OSGetTime(); OSTick OSGetTick(); @@ -88,6 +90,40 @@ OSTick OSGetTick(); u32 OSGetConsoleType(); +#define OS_SOUND_MODE_MONO 0u +#define OS_SOUND_MODE_STEREO 1u + +u32 OSGetSoundMode(void); +void OSSetSoundMode(u32 mode); + +#define OS_PROGRESSIVE_MODE_OFF 0u +#define OS_PROGRESSIVE_MODE_ON 1u + +u32 OSGetProgressiveMode(void); +void OSSetProgressiveMode(u32 on); + +#define OS_LANG_ENGLISH 0u +#define OS_LANG_GERMAN 1u +#define OS_LANG_FRENCH 2u +#define OS_LANG_SPANISH 3u +#define OS_LANG_ITALIAN 4u +#define OS_LANG_DUTCH 5u + +u8 OSGetLanguage(void); +void OSSetLanguage(u8 language); + +#define OS_EURGB60_OFF 0u +#define OS_EURGB60_ON 1u + +u32 OSGetEuRgb60Mode(void); +void OSSetEuRgb60Mode(u32 on); + +void OSRegisterVersion(const char* id); + +BOOL OSDisableInterrupts(void); +BOOL OSEnableInterrupts(void); +BOOL OSRestoreInterrupts(BOOL level); + void OSReport(const char* msg, ...); void OSPanic(const char* file, int line, const char* msg, ...); void OSFatal(GXColor fg, GXColor bg, const char* msg); diff --git a/include/dolphin/os/OSAlarm.h b/include/dolphin/os/OSAlarm.h index 3f709ff1..fd04bf18 100644 --- a/include/dolphin/os/OSAlarm.h +++ b/include/dolphin/os/OSAlarm.h @@ -21,9 +21,16 @@ struct OSAlarm { OSTime start; }; +void OSInitAlarm(void); void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler); +void OSSetAlarmTag(OSAlarm* alarm, u32 tag); +void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler); void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler); +void OSCreateAlarm(OSAlarm* alarm); void OSCancelAlarm(OSAlarm* alarm); +void OSCancelAlarms(u32 tag); + +BOOL OSCheckAlarmQueue(void); #ifdef __cplusplus } diff --git a/src/Kyoto/Math/CVector3f.cpp b/src/Kyoto/Math/CVector3f.cpp new file mode 100644 index 00000000..35cb2ca9 --- /dev/null +++ b/src/Kyoto/Math/CVector3f.cpp @@ -0,0 +1,113 @@ +#include "Kyoto/Math/CVector3f.hpp" + +#include "Kyoto/Math/CMath.hpp" +#include "Kyoto/Math/CRelAngle.hpp" +#include "Kyoto/Streams/CInputStream.hpp" +#include "Kyoto/Streams/COutputStream.hpp" +#include "types.h" + +CVector3f CVector3f::sZeroVector(0.f, 0.f, 0.f); +int CVector3f::sUnkData[18]; // This data is unreferenced, only here to ensure sUpVector starts in + // the correct location +CVector3f CVector3f::sUpVector(0.f, 0.f, 1.f); +CVector3f CVector3f::sDownVector(0.f, 0.f, -1.f); +CVector3f CVector3f::sLeftVector(-1.f, 0.f, 0.f); +CVector3f CVector3f::sRightVector(1.f, 0.f, 0.f); +CVector3f CVector3f::sForwardVector(0.f, 1.f, 0.f); +CVector3f CVector3f::sBackVector(0.f, -1.f, 0.f); + +CVector3f::CVector3f(CInputStream& in) { in.Get(this, sizeof(CVector3f)); } + +void CVector3f::PutTo(COutputStream& out) const { + out.WriteReal32(mX); + out.WriteReal32(mY); + out.WriteReal32(mZ); +} + +CVector3f CVector3f::Slerp(const CVector3f& a, const CVector3f& b, const CRelAngle& angle) {} + +CVector3f& CVector3f::Normalize() { + float mag = 1.f / Magnitude(); + + mX *= mag; + mY *= mag; + mZ *= mag; + + return *this; +} + +float CVector3f::Magnitude() const { + float mag = mX * mX; + mag += mY * mY; + mag += mZ * mZ; + return CMath::SqrtF(mag); +} + +CVector3f CVector3f::AsNormalized() const { + float mag = 1.f / Magnitude(); + float x = mX * mag; + float y = mY * mag; + float z = mZ * mag; + return CVector3f(x, y, z); +} + +bool CVector3f::IsNotInf() const { + int x = __HI(mX); + int y = __HI(mY); + int z = __HI(mZ); + + if ((x & 0x7f800000) == 0x7f800000 || (y & 0x7f800000) == 0x7f800000 || + (z & 0x7f800000) == 0x7f800000) { + return false; + } + + return true; +} + +bool CVector3f::IsMagnitudeSafe() const { + bool ret = false; + if (IsNotInf() && mX * mX + mY * mY + mZ * mZ >= 9.999999e-29f) { + ret = true; + } + + return ret; +} + +bool CVector3f::CanBeNormalized() const { + int x = *(int*)&mX; + int y = *(int*)&mY; + int z = *(int*)&mZ; + if ((x & 0x7f800000) == 0x7f800000 || (y & 0x7f800000) == 0x7f800000 || + (z & 0x7f800000) == 0x7f800000) { + return false; + } + + if ((float)fabs(mX) < FLT_EPSILON && (float)fabs(mY) < FLT_EPSILON && + (float)fabs(mZ) < FLT_EPSILON) { + return false; + } + + return true; +} + +float CVector3f::GetAngleDiff(const CVector3f& a, const CVector3f& b) { + float mag1 = a.Magnitude(); + float mag2 = b.Magnitude(); + + float ret = 0.f; + if (mag1 > FLT_EPSILON && mag2 > FLT_EPSILON) { + float dist = CVector3f::Dot(a, b) / (mag1 * mag2); + if (dist < -1.f) { + dist = -1.f; + } else if (dist > 1.f) { + dist = 1.f; + } + ret = CMath::ArcCosineR(dist); + } + return ret; +} + +bool CVector3f::IsEqu(const CVector3f& vec, float epsilon) const { + return (float)fabs(mX - vec.mX) <= epsilon && (float)fabs(mY - vec.mY) <= epsilon && + (float)fabs(mZ - vec.mZ) <= epsilon; +} diff --git a/src/Kyoto/Streams/COutputStream.cpp b/src/Kyoto/Streams/COutputStream.cpp new file mode 100644 index 00000000..90041760 --- /dev/null +++ b/src/Kyoto/Streams/COutputStream.cpp @@ -0,0 +1,50 @@ +#include "Kyoto/Streams/COutputStream.hpp" + +#include "Kyoto/Alloc/CMemory.hpp" + +#include + +COutputStream::COutputStream(int len) +: mPosition(0) +, mBufLen(len) +, mBufPtr(len > 64 ? new u8[len] : &mScratch[32 - (u32)(mScratch) % 31]) +, mNumWrites(0) +, mShiftRegister(0) +, mShiftRegisterOffset(32) {} + +COutputStream::~COutputStream() { + if (mBufLen > 64) { + delete mBufPtr; + } +} + +void COutputStream::DoPut(const void* ptr, size_t len) { + if (len == 0) { + return; + } + + mNumWrites += len; + u32 curLen = len; + if (mBufLen <= len + mPosition) { + memcpy((u8*)mBufPtr + mPosition, ptr, len); + mPosition += len; + } else { + while (curLen != 0) { + u32 count = mBufLen - mPosition; + if (curLen < count) { + count = curLen; + } + if (count == 0) { + DoFlush(); + } else { + memcpy((u8*)mBufPtr + mPosition, (u8*)ptr + (len - curLen), count); + mPosition += count; + curLen -= count; + } + } + } +} + +void COutputStream::Flush() {} + +void COutputStream::DoFlush() {}