diff --git a/.clang-format b/.clang-format index d95929d1..496dd130 100644 --- a/.clang-format +++ b/.clang-format @@ -8,3 +8,6 @@ DerivePointerAlignment: false PointerAlignment: Left AlwaysBreakTemplateDeclarations: Yes SpacesInAngles: Always # for C++98-compatible nested template arguments +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 0 +BreakConstructorInitializers: BeforeComma \ No newline at end of file diff --git a/asm/Kyoto/Streams/CInputStream.s b/asm/Kyoto/Streams/CInputStream.s index b876a4b1..099bed4a 100644 --- a/asm/Kyoto/Streams/CInputStream.s +++ b/asm/Kyoto/Streams/CInputStream.s @@ -2,8 +2,8 @@ .section .data -.global lbl_803EE388 -lbl_803EE388: +.global __vt__12CInputStream +__vt__12CInputStream: # ROM: 0x3EB388 .4byte 0 .4byte 0 @@ -382,8 +382,8 @@ __dt__12CInputStreamFv: /* 8033F0C0 0033C020 93 C1 00 08 */ stw r30, 8(r1) /* 8033F0C4 0033C024 7C 7E 1B 79 */ or. r30, r3, r3 /* 8033F0C8 0033C028 41 82 00 34 */ beq lbl_8033F0FC -/* 8033F0CC 0033C02C 3C 60 80 3F */ lis r3, lbl_803EE388@ha -/* 8033F0D0 0033C030 38 03 E3 88 */ addi r0, r3, lbl_803EE388@l +/* 8033F0CC 0033C02C 3C 60 80 3F */ lis r3, __vt__12CInputStream@ha +/* 8033F0D0 0033C030 38 03 E3 88 */ addi r0, r3, __vt__12CInputStream@l /* 8033F0D4 0033C034 90 1E 00 00 */ stw r0, 0(r30) /* 8033F0D8 0033C038 88 1E 00 14 */ lbz r0, 0x14(r30) /* 8033F0DC 0033C03C 28 00 00 00 */ cmplwi r0, 0 @@ -406,9 +406,9 @@ lbl_8033F0FC: .global __ct__12CInputStreamFPCvib __ct__12CInputStreamFPCvib: -/* 8033F118 0033C078 3C E0 80 3F */ lis r7, lbl_803EE388@ha +/* 8033F118 0033C078 3C E0 80 3F */ lis r7, __vt__12CInputStream@ha /* 8033F11C 0033C07C 38 00 00 00 */ li r0, 0 -/* 8033F120 0033C080 38 E7 E3 88 */ addi r7, r7, lbl_803EE388@l +/* 8033F120 0033C080 38 E7 E3 88 */ addi r7, r7, __vt__12CInputStream@l /* 8033F124 0033C084 90 E3 00 00 */ stw r7, 0(r3) /* 8033F128 0033C088 90 03 00 04 */ stw r0, 4(r3) /* 8033F12C 0033C08C 90 A3 00 08 */ stw r5, 8(r3) @@ -424,10 +424,10 @@ __ct__12CInputStreamFPCvib: __ct__12CInputStreamFi: /* 8033F14C 0033C0AC 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8033F150 0033C0B0 7C 08 02 A6 */ mflr r0 -/* 8033F154 0033C0B4 3C C0 80 3F */ lis r6, lbl_803EE388@ha +/* 8033F154 0033C0B4 3C C0 80 3F */ lis r6, __vt__12CInputStream@ha /* 8033F158 0033C0B8 3C A0 80 3D */ lis r5, lbl_803D7A68@ha /* 8033F15C 0033C0BC 90 01 00 14 */ stw r0, 0x14(r1) -/* 8033F160 0033C0C0 38 06 E3 88 */ addi r0, r6, lbl_803EE388@l +/* 8033F160 0033C0C0 38 06 E3 88 */ addi r0, r6, __vt__12CInputStream@l /* 8033F164 0033C0C4 93 E1 00 0C */ stw r31, 0xc(r1) /* 8033F168 0033C0C8 7C 7F 1B 78 */ mr r31, r3 /* 8033F16C 0033C0CC 7C 83 23 78 */ mr r3, r4 diff --git a/include/Kyoto_CWD/CInputStream.hpp b/include/Kyoto_CWD/CInputStream.hpp index fb7b9c26..2510f4d8 100644 --- a/include/Kyoto_CWD/CInputStream.hpp +++ b/include/Kyoto_CWD/CInputStream.hpp @@ -14,18 +14,27 @@ public: CInputStream(size_t len); CInputStream(const void* ptr, size_t len, bool owned); virtual ~CInputStream(); + virtual u32 Read(void* dest, u32 len); s32 ReadLong(); - char ReadChar(); - void ReadBytes(void* in, unsigned long len); - u32 ReadBits(int len); + u8 ReadChar(); + u32 ReadBytes(void* dest, unsigned long len); + u32 ReadBits(s32 len); + f32 ReadFloat(); + s64 ReadLongLong(); + s16 ReadShort(); + bool ReadBool(); + void Get(void* dest, unsigned long len); template < typename T > inline T Get() { return cinput_stream_helper(TType< T >(), *this); } private: + bool GrabAnotherBlock(); + bool InternalReadNext(); + u32 x4_blockOffset; u32 x8_blockLen; u32 xc_len; diff --git a/include/Kyoto_CWD/CSfxManager.hpp b/include/Kyoto_CWD/CSfxManager.hpp index f1d1efc1..9dbbaad6 100644 --- a/include/Kyoto_CWD/CSfxManager.hpp +++ b/include/Kyoto_CWD/CSfxManager.hpp @@ -5,7 +5,7 @@ class CSfxManager { public: - static void Update(float dt); + static void Update(f32 dt); }; #endif diff --git a/include/Kyoto_CWD/CStopwatch.hpp b/include/Kyoto_CWD/CStopwatch.hpp index 181406c0..9e1ccdac 100644 --- a/include/Kyoto_CWD/CStopwatch.hpp +++ b/include/Kyoto_CWD/CStopwatch.hpp @@ -10,7 +10,7 @@ public: class CSWData { public: bool Initialize(); - void Wait(float) const; + void Wait(f32) const; s64 GetTimerFreq() const { return x0_timerFreq; } s64 GetTimerFreqO1M() const { return x8_timerFreqO1M; } @@ -32,7 +32,7 @@ public: } x0_startTime = mData.GetCPUCycles(); } - inline float GetElapsedTime() const { return (mData.GetCPUCycles() - x0_startTime) * mData.GetTimerPeriod(); } + inline f32 GetElapsedTime() const { return (mData.GetCPUCycles() - x0_startTime) * mData.GetTimerPeriod(); } inline s64 GetElapsedMicros() const { return (mData.GetCPUCycles() - x0_startTime) / mData.GetTimerFreqO1M(); } private: diff --git a/include/string.h b/include/string.h new file mode 100644 index 00000000..31f0e022 --- /dev/null +++ b/include/string.h @@ -0,0 +1,24 @@ +#ifndef _STRING_H_ +#define _STRING_H_ + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void *memcpy(void *dest, const void *src, size_t num); +void *memset(void *dest, int ch, size_t count); + +size_t strlen(const char *s); +char *strcpy(char *dest, const char *src); +char *strncpy(char *dest, const char *src, size_t num); +int strcmp(const char *s1, const char *s2); +int strncmp(const char *s1, const char *s2, size_t n); +char *strncat(char *dest, const char *src, size_t n); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/src/Kyoto/Basics/CSWDataDolphin.cpp b/src/Kyoto/Basics/CSWDataDolphin.cpp index fd370432..a246ec45 100644 --- a/src/Kyoto/Basics/CSWDataDolphin.cpp +++ b/src/Kyoto/Basics/CSWDataDolphin.cpp @@ -5,11 +5,11 @@ bool CStopwatch::CSWData::Initialize() { x0_timerFreq = OS_TIMER_CLOCK; x8_timerFreqO1M = x0_timerFreq / 1000000ull; - x10_timerPeriod = 1.f / static_cast(x0_timerFreq); + x10_timerPeriod = 1.f / static_cast(x0_timerFreq); return true; } -void CStopwatch::CSWData::Wait(float v) const { +void CStopwatch::CSWData::Wait(f32 v) const { OSTime duration = OSSecondsToTicks(v); OSTime end = OSGetTime() + duration; volatile OSTime current; diff --git a/src/Kyoto/Streams/CInputStream.cpp b/src/Kyoto/Streams/CInputStream.cpp new file mode 100644 index 00000000..a2f880ae --- /dev/null +++ b/src/Kyoto/Streams/CInputStream.cpp @@ -0,0 +1,158 @@ +#include "Kyoto_CWD/CInputStream.hpp" + +#include "string.h" + +#include "Kyoto_CWD/CMemory.hpp" + +// TODO move into functions +static u8 lbl_805A94F0; +static s16 lbl_805A94F2; +static s32 lbl_805A94F4; +static s64 lbl_805A94F8; +static f32 lbl_805A9500; + +f32 CInputStream::ReadFloat() { + Get(&lbl_805A9500, sizeof(f32)); + return lbl_805A9500; +} + +s64 CInputStream::ReadLongLong() { + Get(&lbl_805A94F8, sizeof(s64)); + return lbl_805A94F8; +} + +s32 CInputStream::ReadLong() { + Get(&lbl_805A94F4, sizeof(s32)); + return lbl_805A94F4; +} + +s16 CInputStream::ReadShort() { + Get(&lbl_805A94F2, sizeof(s16)); + return lbl_805A94F2; +} + +bool CInputStream::ReadBool() { return static_cast< bool >(ReadChar()); } + +u8 CInputStream::ReadChar() { + Get(&lbl_805A94F0, sizeof(u8)); + return lbl_805A94F0; +} + +// TODO https://decomp.me/scratch/nzMPg +u32 CInputStream::ReadBits(s32 bitCount) { + u32 ret = 0; + u32 bitOffset = x20_bitOffset; + if (bitOffset < bitCount) { + u32 shiftAmt = bitCount - bitOffset; + const u32 mask = bitOffset == 32 ? 0xffffffff : (1 << bitOffset) - 1; + const u32 bitWord = x1c_bitWord; + x20_bitOffset = 0; + const u32 len = (shiftAmt / 8) + static_cast< unsigned int >((shiftAmt % 8) != 0); + Get(&x1c_bitWord, len); + const u32 mask2 = shiftAmt == 32 ? 0xffffffff : (1 << shiftAmt) - 1; + u32 tmp = x20_bitOffset; + x20_bitOffset = len * 8; + ret = ((mask & (bitWord >> (32 - bitOffset))) << shiftAmt) | ((mask2 & (x1c_bitWord >> (32 - shiftAmt))) << tmp); + x20_bitOffset -= shiftAmt; + x1c_bitWord <<= u64(shiftAmt); + } else { + u32 baseVal2 = (bitCount == 0x20 ? 0xffffffff : (1 << bitCount) - 1); + x20_bitOffset -= bitCount; + ret = baseVal2 & (x1c_bitWord >> (32 - bitCount)); + x1c_bitWord <<= u64(bitCount); + } + return ret; +} + +u32 CInputStream::ReadBytes(void* dest, unsigned long len) { + if (len == 0) { + return 0; + } + + if (x4_blockOffset == x8_blockLen) { + GrabAnotherBlock(); + } + + u32 curLen = len; + u32 curReadLen = 0; + + while (curReadLen < len) { + u32 remain = x8_blockLen - x4_blockOffset; + if (remain == 0) { + if (InternalReadNext()) { + continue; + } else { + return curReadLen; + } + } + + u32 sz = curLen < remain ? curLen : remain; + memcpy(reinterpret_cast< u8* >(dest) + curReadLen, x10_ptr + x4_blockOffset, sz); + curReadLen += sz; + curLen -= sz; + x4_blockOffset += sz; + } + + x18_readPosition += curReadLen; + return curReadLen; +} + +void CInputStream::Get(void* dest, unsigned long len) { + u32 remain = len; + u32 readCount = 0; + x20_bitOffset = 0; + + while (remain != 0) { + u32 blockLen = x8_blockLen - x4_blockOffset; + blockLen = remain < blockLen ? remain : blockLen; + + if (blockLen != 0) { + memcpy(reinterpret_cast< u8* >(dest) + readCount, x10_ptr + x4_blockOffset, blockLen); + remain -= blockLen; + readCount += blockLen; + x4_blockOffset += blockLen; + } else if (remain > 256) { + u32 readLen = Read(reinterpret_cast< u8* >(dest) + readCount, remain); + remain -= readLen; + readCount += readLen; + } else { + GrabAnotherBlock(); + } + } + + x18_readPosition += readCount; +} + +bool CInputStream::GrabAnotherBlock() { return InternalReadNext(); } + +bool CInputStream::InternalReadNext() { + x8_blockLen = Read(x10_ptr, xc_len); + x4_blockOffset = 0; + return x8_blockLen != 0; +} + +CInputStream::~CInputStream() { + if (x14_owned) { + delete x10_ptr; + } +} + +CInputStream::CInputStream(const void* ptr, size_t len, bool owned) +: x4_blockOffset(0) +, x8_blockLen(len) +, xc_len(len) +, x10_ptr(const_cast< u8* >(reinterpret_cast< const u8* >(ptr))) +, x14_owned(owned) +, x18_readPosition(0) +, x1c_bitWord(0) +, x20_bitOffset(0) {} + +CInputStream::CInputStream(size_t len) +: x4_blockOffset(0) +, x8_blockLen(0) +, xc_len(len) +, x10_ptr(new u8[len]) +, x14_owned(true) +, x18_readPosition(0) +, x1c_bitWord(0) +, x20_bitOffset(0) {} diff --git a/src/MetroidPrime/Cameras/CCameraFilter.cpp b/src/MetroidPrime/Cameras/CCameraFilter.cpp index 47a0f0d5..5e4faada 100644 --- a/src/MetroidPrime/Cameras/CCameraFilter.cpp +++ b/src/MetroidPrime/Cameras/CCameraFilter.cpp @@ -3,7 +3,7 @@ #include "Kyoto_CWD/CGraphics.hpp" // FIXME non-matching https://decomp.me/scratch/8N81d -void CCameraFilterPass::DrawWideScreen(const CColor& color, const CTexture* tex, float lod) { +void CCameraFilterPass::DrawWideScreen(const CColor& color, const CTexture* tex, f32 lod) { const rstl::pair< CVector2f, CVector2f > vp = gpRender->SetViewportOrtho(true, -4096.f, 4096.f); f32 left = vp.first.mX; f32 dVar5 = -((vp.second.mX - vp.first.mX) * 0.0625f * 9.f - (vp.second.mY - vp.first.mY)) * 0.5f; @@ -20,7 +20,7 @@ void CCameraFilterPass::DrawWideScreen(const CColor& color, const CTexture* tex, { CGraphics::StreamBegin(kP_TriangleStrip); - float v = (float)(rand() % 4000) / 16384.f; + f32 v = (f32)(rand() % 4000) / 16384.f; CGraphics::StreamColor(color); CGraphics::StreamTexcoord(v, 1.f); CGraphics::StreamVertex(CVector3f(left - 10.f, 0.f, bottom + (dVar5 * lod))); @@ -34,7 +34,7 @@ void CCameraFilterPass::DrawWideScreen(const CColor& color, const CTexture* tex, } { CGraphics::StreamBegin(kP_TriangleStrip); - float v = (float)(rand() % 4000) / 16384.f; + f32 v = (f32)(rand() % 4000) / 16384.f; CGraphics::StreamColor(color); CGraphics::StreamTexcoord(v, 0.f); CGraphics::StreamVertex(CVector3f(left - 10.f, 0.f, top));