diff --git a/configure.py b/configure.py index 06f195db..12caee21 100644 --- a/configure.py +++ b/configure.py @@ -665,21 +665,21 @@ config.libs = [ JSystemLib( "JUtility", [ - Object(NonMatching, "JSystem/JUtility/JUTAssert.cpp"), + Object(Matching, "JSystem/JUtility/JUTAssert.cpp"), Object(Matching, "JSystem/JUtility/JUTConsole.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTDbPrint.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTDirectFile.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTDirectPrint.cpp"), + Object(Matching, "JSystem/JUtility/JUTDbPrint.cpp"), + Object(Matching, "JSystem/JUtility/JUTDirectFile.cpp"), + Object(Matching, "JSystem/JUtility/JUTDirectPrint.cpp"), Object(NonMatching, "JSystem/JUtility/JUTException.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTFader.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTFont.cpp"), + Object(Matching, "JSystem/JUtility/JUTFader.cpp"), + Object(Matching, "JSystem/JUtility/JUTFont.cpp"), Object(Matching, "JSystem/JUtility/JUTFontData_Ascfont_fix12.s"), Object(Matching, "JSystem/JUtility/JUTGamePad.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTGraphFifo.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTProcBar.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTResFont.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTVideo.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTXfb.cpp"), + Object(Matching, "JSystem/JUtility/JUTGraphFifo.cpp"), + Object(Matching, "JSystem/JUtility/JUTProcBar.cpp"), + Object(Matching, "JSystem/JUtility/JUTResFont.cpp"), + Object(Matching, "JSystem/JUtility/JUTVideo.cpp"), + Object(Matching, "JSystem/JUtility/JUTXfb.cpp"), ], ), # { diff --git a/include/JSystem/JUtility/JUTDbPrint.h b/include/JSystem/JUtility/JUTDbPrint.h index 25b8c9b7..81640cd1 100644 --- a/include/JSystem/JUtility/JUTDbPrint.h +++ b/include/JSystem/JUtility/JUTDbPrint.h @@ -50,13 +50,14 @@ struct JUTDbPrint JKRHeap *mHeap; // _10 }; +void JUTReport(int x, int y, int show_count, const char* fmt, ...); + extern "C" { #endif void* JC_JUTDbPrint_getManager(void); void JC_JUTDbPrint_setVisible(void*, int); // I know these are C++ but these were used to match a c function so I'll fix these when I need them or fix zurumode update. -void JUTReport(int x, int y, int show_count, const char* fmt, ...); #ifdef __cplusplus } diff --git a/include/JSystem/JUtility/JUTDirectFile.h b/include/JSystem/JUtility/JUTDirectFile.h new file mode 100644 index 00000000..1f028940 --- /dev/null +++ b/include/JSystem/JUtility/JUTDirectFile.h @@ -0,0 +1,34 @@ +#ifndef _JSYSTEM_JUT_JUTDIRECTFILE_H +#define _JSYSTEM_JUT_JUTDIRECTFILE_H + +#include +#include "types.h" + +#define JUTDF_BUFSIZE (0x800) + +struct JUTDirectFile +{ + JUTDirectFile(); + + ~JUTDirectFile(); + + bool fopen(const char *); + void fclose(); + int fgets(void *, int); + + // unused/inlined + int fetch32byte(); + void fread(void *, u32); + void setPos(u32); + void fgetc(); + + u8 mBuffer[0x820]; // _000, 0x20 header, 0x800 sector + u8 *mSectorStart; // _820, ptr to 0x800 buffer + u32 mToRead; // _824, length (max 32 bytes) to read + u32 mLength; // _828, length of file + u32 mPos; // _82C, position in file + bool mIsOpen; // _830, is file open + DVDFileInfo mFileInfo; // _834 +}; + +#endif \ No newline at end of file diff --git a/include/JSystem/JUtility/JUTDirectPrint.h b/include/JSystem/JUtility/JUTDirectPrint.h index cda094d6..8f126d01 100644 --- a/include/JSystem/JUtility/JUTDirectPrint.h +++ b/include/JSystem/JUtility/JUTDirectPrint.h @@ -2,10 +2,10 @@ #define JUTDIRECTPRINT_H #include "types.h" -// #include "va_args.h" -#include "JSystem/JUtility/TColor.h" +#include "libc/stdarg.h" #ifdef __cplusplus + class JUTDirectPrint { private: @@ -14,20 +14,17 @@ private: public: static JUTDirectPrint *start(); void erase(int x, int y, int w, int h); - void setCharColor(JUtility::TColor color); - void setCharColor(u8 r, u8 g, u8 b); void drawChar(int, int, int); void drawString(u16 x, u16 y, char *text); void drawString_f(u16 x, u16 y, const char * text, ...); void changeFrameBuffer(void *framebuffer, u16 w, u16 h ); - - // Inline/Unused - void printSub(u16, u16, const char *, va_list *, bool); + void printSub(u16, u16, const char *, va_list, bool); // TODO: Function signature void print(u16, u16, const char *, ...); bool isActive() const { return mFramebuffer != nullptr; } void *getFrameBuffer() { return mFramebuffer; } - JUtility::TColor getCharColor() const { return mCharColor; } + + void changeFrameBuffer(void* fb) { changeFrameBuffer(fb, mFbWidth, mFbHeight); } static JUTDirectPrint *getManager() { return sDirectPrint; } @@ -44,15 +41,6 @@ private: size_t mFbSize; // _0C u8 _10[0x4]; // _10 - unknown u16 *mFrameMemory; // _14 - JUtility::TColor mCharColor; // _18, Color in RGBA format - u16 mCharColorY; // _1C, 1C-2C = color in YCbCr - u16 mCharColorCb; // _1E - u16 mCharColorCb2; // _20 - u16 mCharColorCb4; // _22 - u16 mCharColorCr; // _24 - u16 mCharColorCr2; // _26 - u16 mCharColorCr4; // _28 - u16 _2A; // _2A }; inline void JUTChangeFrameBuffer(void *buffer, u16 height, u16 width) diff --git a/include/JSystem/JUtility/JUTException.h b/include/JSystem/JUtility/JUTException.h index 0413deca..46bc7932 100644 --- a/include/JSystem/JUtility/JUTException.h +++ b/include/JSystem/JUtility/JUTException.h @@ -11,7 +11,7 @@ struct JUTConsole; struct JUTDirectPrint; -typedef void (*JUTErrorHandler)(s32 error, OSContext *context, u32 dsisr, u32 dar); +typedef void (*JUTErrorHandler)(OSError error, OSContext *context, u32 dsisr, u32 dar); enum ExPrintFlags { diff --git a/include/JSystem/JUtility/JUTFader.h b/include/JSystem/JUtility/JUTFader.h index f6ff4410..8e07a3da 100644 --- a/include/JSystem/JUtility/JUTFader.h +++ b/include/JSystem/JUtility/JUTFader.h @@ -28,7 +28,6 @@ struct JUTFader // unused/inlined: void start(int); void setStatus(EStatus, int); - void setResetState(bool reset) { mResetting = reset; } EStatus getStatus() const { return mStatus; } @@ -38,8 +37,6 @@ struct JUTFader EStatus mStatus; // _04 - current status u16 mTicksTarget; // _08 - ticks (calls to control()) to run a fade in/out for u16 mTicksRun; // _0A - ticks the current fade has run - bool mResetting; // _0C - probably exclusive to mkdd, holds true when starting the fadeout for reset, sets back to false when fading in - u8 _0D[3]; // padding JUtility::TColor mColor; // _10 - color of fade JGeometry::TBox2f mViewBox; // _14 - ortho box to render within int mEStatus; // _24 - ??? diff --git a/include/JSystem/JUtility/JUTVideo.h b/include/JSystem/JUtility/JUTVideo.h index 75b7a7a1..6c62f6cd 100644 --- a/include/JSystem/JUtility/JUTVideo.h +++ b/include/JSystem/JUtility/JUTVideo.h @@ -24,8 +24,8 @@ struct JUTVideo static void drawDoneCallback(); u32 getEfbHeight() const { return mRenderModeObj->efbHeight; } - u32 getXfbHeight() const { return mRenderModeObj->xfbHeight; } - u32 getFbWidth() const { return (u16)mRenderModeObj->fbWidth; } // cast required for callDirectDraw + u32 getXfbHeight() const { return mRenderModeObj->xfbHeight & 0xffff; } + u32 getFbWidth() const { return (u16)mRenderModeObj->fbWidth; } void getBounds(u16& width, u16& height) const { width = getFbWidth(); height = getEfbHeight(); diff --git a/include/dolphin/gx/GXFrameBuffer.h b/include/dolphin/gx/GXFrameBuffer.h index 1d695495..5c72166f 100644 --- a/include/dolphin/gx/GXFrameBuffer.h +++ b/include/dolphin/gx/GXFrameBuffer.h @@ -13,7 +13,7 @@ extern "C" { // extern GXRenderModeObj GXNtsc240Int; // extern GXRenderModeObj GXNtsc240IntAa; extern GXRenderModeObj GXNtsc480IntDf; -// extern GXRenderModeObj GXNtsc480Int; +extern GXRenderModeObj GXNtsc480Int; // extern GXRenderModeObj GXNtsc480IntAa; // extern GXRenderModeObj GXNtsc480Prog; // extern GXRenderModeObj GXNtsc480ProgSoft; diff --git a/include/dolphin/os.h b/include/dolphin/os.h index 6f916968..7a8d58c4 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -3,9 +3,13 @@ #include "types.h" #include "dolphin/os/OSAlloc.h" +#include "dolphin/os/OSArena.h" #include "dolphin/os/OSCache.h" #include "dolphin/os/OSContext.h" +#include "dolphin/os/OSError.h" #include "dolphin/os/OSInterrupt.h" +#include "dolphin/os/OSModule.h" +#include "dolphin/os/OSMemory.h" #include "dolphin/os/OSMessage.h" #include "libforest/osreport.h" /* OSReport funcs */ #include "dolphin/os/OSReset.h" diff --git a/include/dolphin/os/OSError.h b/include/dolphin/os/OSError.h index 61ebbcd9..487c159f 100644 --- a/include/dolphin/os/OSError.h +++ b/include/dolphin/os/OSError.h @@ -26,10 +26,14 @@ typedef void (*OSErrorHandler)(OSError error, OSContext *context, ...); #define OS_ERROR_SYSTEM_INTERRUPT 13 #define OS_ERROR_THERMAL_INTERRUPT 14 #define OS_ERROR_PROTECTION 15 -#define OS_ERROR_MAX (OS_ERROR_THERMAL_INTERRUPT + 1) +#define OS_ERROR_FPE 16 +#define OS_ERROR_MAX (OS_ERROR_FPE + 1) OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler); +extern OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; +extern u32 __OSFpscrEnableBits; + #ifdef __cplusplus } #endif diff --git a/include/dolphin/os/OSMemory.h b/include/dolphin/os/OSMemory.h index 601cf2cc..b9cb9c73 100644 --- a/include/dolphin/os/OSMemory.h +++ b/include/dolphin/os/OSMemory.h @@ -11,6 +11,8 @@ static void Config24MB(); static void Config48MB(); u32 OSGetConsoleSimulatedMemSize(void); +void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control); + #ifdef __cplusplus } #endif diff --git a/include/dolphin/vi.h b/include/dolphin/vi.h index 215a27e0..a33f54ea 100644 --- a/include/dolphin/vi.h +++ b/include/dolphin/vi.h @@ -69,14 +69,22 @@ typedef void (*VIRetraceCallback)(u32 retraceCount); #define VIPadFrameBufferWidth(width) ((u16)(((u16)(width) + 15) & ~15)) +void VIConfigure(const struct _GXRenderModeObj *rm); + void VISetBlack(BOOL); void VIWaitForRetrace(); void VIConfigurePan(u16 x_origin, u16 y_origin, u16 width, u16 height); u32 VIGetRetraceCount(); u32 VIGetDTVStatus(); -void VIFlush(); -void VISetNextFrameBuffer(void *fb); +VIRetraceCallback VISetPreRetraceCallback(VIRetraceCallback callback); +VIRetraceCallback VISetPostRetraceCallback(VIRetraceCallback callback); +void* VIGetNextFrameBuffer(); +void* VIGetCurrentFrameBuffer(); +void VISetNextFrameBuffer(void* fb); + +void VIInit(); +void VIFlush(); #ifdef __cplusplus }; diff --git a/include/libc/string.h b/include/libc/string.h index 2c7fc662..5a87f32e 100644 --- a/include/libc/string.h +++ b/include/libc/string.h @@ -13,6 +13,7 @@ void *memset(void *dest, int ch, size_t count); int memcmp(const void *ptr1, const void *ptr2, size_t num); size_t strlen(const char *s); +long strtol(const char *str, char **end, int base); 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); diff --git a/src/static/JSystem/J2DGraph/J2DOrthoGraph.cpp b/src/static/JSystem/J2DGraph/J2DOrthoGraph.cpp index 7d7ec7b7..c9befb4d 100644 --- a/src/static/JSystem/J2DGraph/J2DOrthoGraph.cpp +++ b/src/static/JSystem/J2DGraph/J2DOrthoGraph.cpp @@ -59,9 +59,9 @@ void J2DDrawLine(f32 x1, f32 y1, f32 x2, f32 y2, JUtility::TColor color, int lin oGrph.lineTo(x2, y2); } -void J2DFillBox(f32 l, f32 b, f32 x, f32 y, JUtility::TColor color) +void J2DFillBox(f32 l, f32 t, f32 x, f32 y, JUtility::TColor color) { - J2DFillBox(JGeometry::TBox2f(l, b, l + x, b + y), color); + J2DFillBox(JGeometry::TBox2f(l, t, l + x, t + y), color); } void J2DFillBox(const JGeometry::TBox2f& box, JUtility::TColor color) @@ -71,9 +71,9 @@ void J2DFillBox(const JGeometry::TBox2f& box, JUtility::TColor color) oGrph.fillBox(box); } -void J2DFillBox(f32 l, f32 b, f32 x, f32 y, JUtility::TColor c1, JUtility::TColor c2, JUtility::TColor c3, JUtility::TColor c4) +void J2DFillBox(f32 l, f32 t, f32 x, f32 y, JUtility::TColor c1, JUtility::TColor c2, JUtility::TColor c3, JUtility::TColor c4) { - J2DFillBox(JGeometry::TBox2f(l, b, l + x, b + y), c1, c2, c3, c4); + J2DFillBox(JGeometry::TBox2f(l, t, l + x, t + y), c1, c2, c3, c4); } void J2DFillBox(const JGeometry::TBox2f &box, JUtility::TColor c1, JUtility::TColor c2, JUtility::TColor c3, JUtility::TColor c4) @@ -83,9 +83,9 @@ void J2DFillBox(const JGeometry::TBox2f &box, JUtility::TColor c1, JUtility::TCo oGrph.fillBox(box); } -void J2DDrawFrame(f32 l, f32 b, f32 x, f32 y, JUtility::TColor color, u8 line_width) +void J2DDrawFrame(f32 l, f32 t, f32 x, f32 y, JUtility::TColor color, u8 line_width) { - J2DDrawFrame(JGeometry::TBox2f(l, b, l + x, b + y), color, line_width); + J2DDrawFrame(JGeometry::TBox2f(l, t, l + x, t + y), color, line_width); } void J2DDrawFrame(const JGeometry::TBox2f& box, JUtility::TColor color, u8 line_width) diff --git a/src/static/JSystem/JUtility/JUTAssert.cpp b/src/static/JSystem/JUtility/JUTAssert.cpp new file mode 100644 index 00000000..bea09b5b --- /dev/null +++ b/src/static/JSystem/JUtility/JUTAssert.cpp @@ -0,0 +1,71 @@ +#include +#include +#include "JSystem/JUtility/JUTAssertion.h" +#include "JSystem/JUtility/JUTConsole.h" +#include "JSystem/JUtility/JUTDbPrint.h" +#include "JSystem/JUtility/JUTDirectPrint.h" + +namespace JUTAssertion +{ + namespace + { + static u32 sMessageLife; + static u32 sMessageOwner; + static bool mSynchro; + static char sMessageFileLine[64]; + static char sMessageString[96]; + + static u32 sDisplayTime = -1; + static u32 sDevice = 3; + static bool sVisible = true; + } + + void create() {} + + u32 flush_subroutine() + { + if (sMessageLife == 0) { + return 0; + } + if (sMessageLife != -1) { + sMessageLife--; + } + if (sMessageLife < 5) { + return 0; + } + return sMessageLife; + } + + void flushMessage() + { + if (flush_subroutine() && sVisible == true) + { + JUTDirectPrint::getManager()->drawString(16, 16, sMessageFileLine); + JUTDirectPrint::getManager()->drawString(16, 24, sMessageString); + } + } + + void flushMessage_dbPrint() + { + if (flush_subroutine() && sVisible == true && JUTDbPrint::getManager()) + { + JUTFont *font = JUTDbPrint::getManager()->getFont(); + if (font) + { + u8 tmp = ((VIGetRetraceCount() & 60) << 2) | 0xF; + font->setGX(); + font->setCharColor(JUtility::TColor(255, tmp, tmp, 255)); + font->drawString(30, 36, sMessageFileLine, true); + font->drawString(30, 54, sMessageString, true); + } + } + } + + void changeDisplayTime(u32 time) { + sDisplayTime = time; + } + + void changeDevice(u32 device) { + sDevice = device; + } +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTDbPrint.cpp b/src/static/JSystem/JUtility/JUTDbPrint.cpp new file mode 100644 index 00000000..cd63fdd9 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTDbPrint.cpp @@ -0,0 +1,130 @@ +#include "MSL_C/printf.h" +#include "JSystem/JUtility/JUTDbPrint.h" +#include "JSystem/J2D/J2DGrafContext.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JUtility/JUTFont.h" +#include "JSystem/JUtility/JUTVideo.h" +#include "types.h" + +JUTDbPrint *JUTDbPrint::sDebugPrint; + +JUTDbPrint::JUTDbPrint(JUTFont *font, JKRHeap *heap) + : mColor() +{ + mFont = font; + mList = nullptr; + mHeap = (heap) ? heap : JKRHeap::getCurrentHeap(); + mColor = TCOLOR_WHITE; + mVisible = true; +} + +JUTDbPrint::~JUTDbPrint() {} + +JUTDbPrint *JUTDbPrint::start(JUTFont *font, JKRHeap *heap) +{ + if (!sDebugPrint) + { + if (!heap) + { + heap = JKRHeap::getCurrentHeap(); + } + sDebugPrint = new JUTDbPrint(font, heap); + } + return sDebugPrint; +} + +JUTFont *JUTDbPrint::changeFont(JUTFont *newFont) +{ + JUTFont *oldFont = mFont; + if (newFont) + { + mFont = newFont; + } + return oldFont; +} + +void JUTDbPrint::enter(int x, int y, int duration, const char *txt, int len) +{ + if(len > 0) { + JUTDbPrintList *pList = (JUTDbPrintList *)JKRAllocFromHeap(mHeap, sizeof(JUTDbPrintList) + len, -4); + if (pList) + { + pList->mX = x; + pList->mY = y; + pList->mDuration = duration; + pList->mLen = len; + strcpy((char *)&pList->mStr, txt); + pList->mNext = mList; + mList = pList; + } + } +} + +void JUTDbPrint::flush() { + // eyebrow raise emoji + JUTDbPrintList *pList = (JUTDbPrintList *)&mList; + JUTDbPrintList *currList = mList; + + if (mFont) + { + if (currList) + { + J2DOrthoGraph orthograph(0.0f, 0.0f, 640.0f, 480.0f, -1.0f, 1.0f); + orthograph.setPort(); + mFont->setGX(); + mFont->setCharColor(mColor); + while (currList) + { + if (mVisible) + { + drawString(currList->mX, currList->mY, currList->mLen, &currList->mStr); + } + if (--currList->mDuration <= 0) + { + JUTDbPrintList *next = currList->mNext; + JKRFreeToHeap(mHeap, currList); + pList->mNext = next; + currList = next; + } + else + { + pList = currList; + currList = currList->mNext; + } + } + } + } } + +void JUTDbPrint::flush(int left, int top, int right, int bottom) +{ + +} + +void JUTDbPrint::drawString(int x, int y, int len, const unsigned char *str) +{ + mFont->drawString_size(x, y, reinterpret_cast(str), len, true); +} + +void JUTReport(int x, int y, const char *fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + char buf[128]; + s32 n = vsnprintf(buf, sizeof(buf), fmt, vl); + if (n >= 0) { + JUTDbPrint::getManager()->enter(x, y, 1, buf, n < 256 ? n : 255); + } + va_end(); +} + +void JUTReport(int x, int y, int duration, const char *fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + char buf[256]; + s32 n = vsnprintf(buf, sizeof(buf), fmt, vl); + if (n >= 0) { + JUTDbPrint::getManager()->enter(x, y, duration, buf, n < 256 ? n : 255); + } + va_end(vl); +} diff --git a/src/static/JSystem/JUtility/JUTDirectFile.cpp b/src/static/JSystem/JUtility/JUTDirectFile.cpp new file mode 100644 index 00000000..f78d5828 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTDirectFile.cpp @@ -0,0 +1,186 @@ +#include +#include "JSystem/JUtility/JUTDirectFile.h" + +int JUTDirectFile::fetch32byte() +{ + mToRead = mLength - ALIGN_PREV(mPos, DVD_MIN_TRANSFER_SIZE); + + if (mToRead > JUTDF_BUFSIZE) + { + mToRead = JUTDF_BUFSIZE; + } + int interrupts = OSEnableInterrupts(); + int readRes = DVDReadAsync(&mFileInfo, mSectorStart, ALIGN_NEXT(mToRead, DVD_MIN_TRANSFER_SIZE), + ALIGN_PREV(mPos, DVD_MIN_TRANSFER_SIZE), nullptr); + OSRestoreInterrupts(interrupts); + if (!readRes) + { + return -1; + } + else + { + interrupts = OSEnableInterrupts(); + while (DVDGetCommandBlockStatus(&mFileInfo.cb)) + { + ; + } + OSRestoreInterrupts(interrupts); + return mToRead; + } +} + +JUTDirectFile::JUTDirectFile() +{ + mLength = 0; + mPos = 0; + mToRead = 0; + mSectorStart = (u8 *)ALIGN_NEXT((u32)mBuffer, DVD_MIN_TRANSFER_SIZE); + mIsOpen = false; +} + +JUTDirectFile::~JUTDirectFile() { mIsOpen = false; } + +bool JUTDirectFile::fopen(const char *filename) +{ + if (!filename) + { + return false; + } + + int interrupts = OSEnableInterrupts(); + int dvdRes = DVDOpen(const_cast(filename), &mFileInfo); + OSRestoreInterrupts(interrupts); + + if (!dvdRes) + { + mIsOpen = false; + return false; + } + + int interrupts2 = OSEnableInterrupts(); + mLength = mFileInfo.length; + OSRestoreInterrupts(interrupts2); + + mPos = 0; + mIsOpen = true; + return true; +} + +void JUTDirectFile::fclose() +{ + if (mIsOpen) + { + int interrupts = OSEnableInterrupts(); + DVDClose(&mFileInfo); + OSRestoreInterrupts(interrupts); + mIsOpen = false; + } +} +/* + * Gets data of length 'len' and stores in 'buf'. + * Returns actual length gotten in bytes, or -1 if error. + */ +int JUTDirectFile::fgets(void *buf, int len) +{ + // if file isn't open, return error (-1). + if (!mIsOpen) + { + return -1; + } + + // if desired length to get is 0, get... 0 bytes. + if (len == 0) + { + return 0; + } + + // if desired length to get is 1, return 1. + // (final byte gotten is always 0, so len 1 is pointless). + if (len == 1) + { + return 1; + } + + // if buffer to read into doesn't exist, return error. + if (!buf) + { + return -1; + } + + // if we're already beyond the file length, return error. + if (mPos >= mLength) + { + return -1; + } + + int readMax; + u8 *byteBuf = (u8 *)buf; + readMax = len - 1; // desired bytes of data to get (last value is then 0). + int readCount = 0; + + while (mPos < mLength) + { + // if there's nothing left to read, return error. + if (mToRead == 0 && fetch32byte() < 0) + { + return -1; + } + + // read in each chunk. + u32 currPos = mPos & (JUTDF_BUFSIZE - 1); + u32 chunkSize = (mToRead - currPos); + if (readCount + chunkSize > readMax) + { + chunkSize = len - readCount - 1; + } + + BOOL isAtEnd = FALSE; + for (int i = 0; i < chunkSize; i++) + { + u8 byte = mSectorStart[currPos++]; + *byteBuf++ = byte; + + // if we hit the end of a line, stop reading. + if (byte == '\n') + { + chunkSize = i + 1; + isAtEnd = TRUE; + break; + } + } + + // if we exceed the buffer size, stop reading. + if (currPos >= JUTDF_BUFSIZE) + { + mToRead = 0; + } + + // if we hit the end of a line, set final byte to 0 and stop reading. + if (isAtEnd == TRUE) + { + readCount += chunkSize; + *byteBuf = 0; + mPos += chunkSize; + break; + } + + // we should have read the full chunkSize, so update count/pos. + readCount += chunkSize; + mPos += chunkSize; + + // if we're at (or beyond) our desired length, set final byte to 0 and stop reading. + if (readCount >= readMax) + { + *byteBuf = 0; + break; + } + } + + // if got to the end of the data, set final byte to 0. + if (mPos >= mLength) + { + *byteBuf = 0; + } + + return readCount; +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTDirectPrint.cpp b/src/static/JSystem/JUtility/JUTDirectPrint.cpp new file mode 100644 index 00000000..32aa8d59 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTDirectPrint.cpp @@ -0,0 +1,203 @@ +#include + +#include "MSL_C/printf.h" +#include "JSystem/JUtility/JUTDirectPrint.h" + +JUTDirectPrint *JUTDirectPrint::sDirectPrint; + +JUTDirectPrint::JUTDirectPrint() +{ + changeFrameBuffer(nullptr, 0, 0); +} + +JUTDirectPrint *JUTDirectPrint::start() +{ + if (!sDirectPrint) { + sDirectPrint = new JUTDirectPrint(); + } + + return sDirectPrint; +} + +void JUTDirectPrint::erase(int x, int y, int width, int height) +{ + if (!mFramebuffer) { + return; + } + + if (400 < mFbWidth) + { + x = x << 1; + width = width << 1; + } + + if (300 < mFbHeight) + { + y = y << 1; + height = height << 1; + } + + u16 *pixel = mFrameMemory + mStride * y + x; + for (int i = 0; i < height; i++) + { + for (int j = 0; j < width; j++) + { + *pixel = 0x1080; + pixel = pixel + 1; + } + + pixel += mStride - width; + } +} + +u8 JUTDirectPrint::sAsciiTable[128] = { + 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0xFD, 0xFE, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x29, 0x64, 0x65, 0x66, 0x2B, 0x67, 0x68, 0x25, 0x26, 0x69, 0x2A, 0x6A, 0x27, 0x2C, 0x6B, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x24, 0x6C, 0x6D, 0x6E, 0x6F, 0x28, + 0x70, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x71, 0x72, 0x73, 0x74, 0x75, + 0xFF, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, + 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x76, 0x77, 0x78, 0x79, 0x7A, +}; + +u32 JUTDirectPrint::sFontData[64] = { + 0x70871C30, 0x8988A250, 0x88808290, 0x88830C90, 0x888402F8, 0x88882210, 0x71CF9C10, 0xF9CF9C70, + 0x8208A288, 0xF200A288, 0x0BC11C78, 0x0A222208, 0x8A222208, 0x71C21C70, 0x23C738F8, 0x5228A480, + 0x8A282280, 0x8BC822F0, 0xFA282280, 0x8A28A480, 0x8BC738F8, 0xF9C89C08, 0x82288808, 0x82088808, + 0xF2EF8808, 0x82288888, 0x82288888, 0x81C89C70, 0x8A08A270, 0x920DA288, 0xA20AB288, 0xC20AAA88, + 0xA208A688, 0x9208A288, 0x8BE8A270, 0xF1CF1CF8, 0x8A28A220, 0x8A28A020, 0xF22F1C20, 0x82AA0220, + 0x82492220, 0x81A89C20, 0x8A28A288, 0x8A28A288, 0x8A289488, 0x8A2A8850, 0x894A9420, 0x894AA220, + 0x70852220, 0xF8011000, 0x08020800, 0x10840400, 0x20040470, 0x40840400, 0x80020800, 0xF8011000, + 0x70800000, 0x88822200, 0x08820400, 0x108F8800, 0x20821000, 0x00022200, 0x20800020, 0x00000000, +}; + +u32 JUTDirectPrint::sFontData2[77] = { + 0x51421820, 0x53E7A420, 0x014A2C40, 0x01471000, 0x0142AA00, 0x03EAA400, 0x01471A78, 0x00000000, + 0x50008010, 0x20010820, 0xF8020040, 0x20420820, 0x50441010, 0x00880000, 0x00070E00, 0x01088840, + 0x78898820, 0x004A8810, 0x788A8810, 0x01098808, 0x00040E04, 0x70800620, 0x11400820, 0x12200820, + 0x10001020, 0x10000820, 0x100F8820, 0x70000620, 0x60070000, 0x110F82A0, 0x12AA8AE0, 0x084F92A0, + 0x100FBE1C, 0x10089008, 0x60070808, 0x00000000, 0x02000200, 0x7A078270, 0x8BC81E88, 0x8A2822F8, + 0x9A282280, 0x6BC79E78, 0x30000000, 0x48080810, 0x41E80000, 0x422F1830, 0xFBE88810, 0x40288890, + 0x43C89C60, 0x81000000, 0x81000000, 0x990F3C70, 0xA10AA288, 0xE10AA288, 0xA10AA288, 0x98CAA270, + 0x00000000, 0x00000020, 0xF1EF1E20, 0x8A28A0F8, 0x8A281C20, 0xF1E80220, 0x80283C38, 0x00000000, + 0x00000000, 0x8A28B688, 0x8A2A8888, 0x8A2A8878, 0x894A8808, 0x788536F0, 0x00000000, 0x00000000, + 0xF8000000, 0x10000000, 0x20000000, 0x40000000, 0xF8000000, +}; + +void JUTDirectPrint::drawChar(int position_x, int position_y, int ch) { + int codepoint = (100 <= ch) ? ch - 100 : ch; + int col_index = (codepoint % 5) * 6; + int row_index = (codepoint / 5) * 7; + + const u32 *font_data = (100 > ch) ? sFontData + row_index : sFontData2 + row_index; + + int scale_x = (mFbWidth < 400) ? 1 : 2; + int scale_y = (mFbHeight < 300) ? 1 : 2; + + u16 *pixel = mFrameMemory + mStride * position_y * scale_y + position_x * scale_x; + for (int y = 0; y < 7; y++) { + u32 data = *font_data << col_index; + font_data += 1; + + for (int x = 0; x < 6; x++) { + u16 value = (data & 0x80000000) ? 0xeb80 : 0x80; + + for (int y2 = 0; y2 < scale_y; y2++) { + int tmp = mStride * y2; + for (int x2 = 0; x2 < scale_x; x2++) { + u16* row = &pixel[tmp]; + row[x2] = value; + } + } + + data <<= 1; + pixel += scale_x; + } + + pixel += mStride * scale_y - 6 * scale_x; + } +} + +void JUTDirectPrint::changeFrameBuffer(void *fb, u16 width, u16 height) +{ + mFramebuffer = fb; + mFrameMemory = (u16 *)fb; + mFbWidth = width; + mFbHeight = height; + mStride = ALIGN_NEXT((u16)width, 16); + mFbSize = (u32)mStride * (u32)mFbHeight * 2; +} + +void JUTDirectPrint::printSub(u16 position_x, u16 position_y, const char *format, va_list args, bool clear) +{ + char buffer[256]; + if (!mFrameMemory) + { + return; + } + + int buffer_length = vsnprintf(buffer, sizeof(buffer), format, args); + u16 x = position_x; + if (buffer_length > 0) + { + if (clear) + { + erase(position_x - 6, position_y - 3, (buffer_length + 2) * 6, 0xd); + } + + char *ptr = buffer; + for (; 0 < buffer_length; buffer_length--, ptr++) + { + int codepoint = sAsciiTable[*ptr & 0x7f]; + if (codepoint == 0xfe) + { + position_x = x; + position_y += 7; + } + else if (codepoint == 0xfd) + { + s32 current_position = (int)position_x; + s32 tab = (current_position - x + 0x2f) % 0x30; + position_x = current_position + 0x30 - tab; + } + else + { + if (codepoint != 0xff) + { + drawChar(position_x, position_y, codepoint); + } + position_x += 6; + } + } + } + + DCFlushRange(mFrameMemory, mFbSize); +} + +void JUTDirectPrint::print(u16 position_x, u16 position_y, char const *format, ...) +{ + if (mFrameMemory) + { + va_list args; + va_start(args, format); + printSub(position_x, position_y, format, args, true); + va_end(args); + } +} + +void JUTDirectPrint::drawString(u16 position_x, u16 position_y, char *text) +{ + drawString_f(position_x, position_y, "%s", text); +} + +void JUTDirectPrint::drawString_f(u16 position_x, u16 position_y, char const *format, ...) +{ + if (mFrameMemory) + { + va_list args; + va_start(args, format); + printSub(position_x, position_y, format, args, false); + va_end(args); + } +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTException.cpp b/src/static/JSystem/JUtility/JUTException.cpp new file mode 100644 index 00000000..48bce331 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTException.cpp @@ -0,0 +1,1047 @@ +#include +#include +#include +#include "MSL_C/w_math.h" +#include "MSL_C/printf.h" +#include "libc/string.h" + +#include "JSystem/JUtility/JUTException.h" +#include "JSystem/JUtility/JUTDirectPrint.h" +#include "JSystem/JUtility/JUTDirectFile.h" + +extern long __fpclassifyf(float x); +long __fpclassifyd(double x); +#define fpclassify(x) (sizeof(x) == sizeof(float) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) + +#define isinf(x) ((fpclassify(x) == 2)) +#define isnan(x) ((fpclassify(x) == 1)) +#define isfinite(x) ((fpclassify(x) > 2)) + +struct CallbackObject +{ + JUTErrorHandler callback; + u16 error; + OSContext *context; + u32 dsisr; + u32 dar; +}; + +void search_name_part(u8 *, u8 *, int); + +OSMessageQueue JUTException::sMessageQueue = {}; +static OSTime c3bcnt[4] = {0, 0, 0, 0}; +const char *JUTException::sCpuExpName[] = { + "SYSTEM RESET", + "MACHINE CHECK", + "DSI", + "ISI", + "EXTERNAL INTERRUPT", + "ALIGNMENT", + "PROGRAM", + "FLOATING POINT", + "DECREMENTER", + "SYSTEM CALL", + "TRACE", + "PERFORMACE MONITOR", + "BREAK POINT", + "SYSTEM INTERRUPT", + "THERMAL INTERRUPT", + "PROTECTION", + "FLOATING POINT" +}; + +JUTException *JUTException::sErrorManager; +JUTErrorHandler JUTException::sPreUserCallback; +JUTErrorHandler JUTException::sPostUserCallback; +static CallbackObject exCallbackObject; +void *JUTException::sConsoleBuffer; +u32 JUTException::sConsoleBufferSize; +JUTConsole *JUTException::sConsole; +u32 JUTException::msr; +u32 JUTException::fpscr; +void *JUTException::sMessageBuffer[1] = { nullptr}; + +JSUList JUTException::sMapFileList(false); + +JUTException::JUTException(JUTDirectPrint *directPrint) :JKRThread(0x4000, 0x10, 0) { + mDirectPrint = directPrint; + + OSSetErrorHandler(OS_ERROR_DSI, (OSErrorHandler)errorHandler); + OSSetErrorHandler(OS_ERROR_ISI, (OSErrorHandler)errorHandler); + OSSetErrorHandler(OS_ERROR_PROGRAM, (OSErrorHandler)errorHandler); + OSSetErrorHandler(OS_ERROR_ALIGNMENT, (OSErrorHandler)errorHandler); + OSSetErrorHandler(OS_ERROR_PROTECTION, (OSErrorHandler)errorHandler); + setFPException(0); + + sPreUserCallback = nullptr; + sPostUserCallback = nullptr; + mGamePad = nullptr; + mPadPort = JUTGamePad::Port_Invalid; + mPrintWaitTime0 = 10; + mPrintWaitTime1 = 10; + mTraceSuppress = 0xffffffff; + _98 = 0; + mPrintFlags = EXPRINTFLAG_All; +} + +JUTException *JUTException::create(JUTDirectPrint *directPrint) { + if(sErrorManager == nullptr) { + sErrorManager = new (JKRGetSystemHeap(), 0) JUTException(directPrint); + sErrorManager->resume(); + } + return sErrorManager; +} + +void *JUTException::run() +{ + PPCMtmsr(PPCMfmsr() & ~0x0900); + OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 1); + OSMessage message; + while (true) + { + OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK); + CallbackObject *cb = (CallbackObject *)message; + JUTErrorHandler callback = cb->callback; + u16 error = cb->error; + OSContext *context = cb->context; + u32 dsisr = cb->dsisr; + u32 dar = cb->dar; + + if (error < OS_ERROR_MAX) + mStackPointer = context->gpr[1]; + + + if (mFrameMemory == nullptr) + sErrorManager->createFB(); + + if (callback) + callback(error, context, dsisr, dar); + + OSDisableInterrupts(); + + sErrorManager->printContext(error, context, dsisr, dar); + } +} + +void JUTException::errorHandler(OSError error, OSContext *context, u32 dsisr, u32 dar) +{ + msr = PPCMfmsr(); + fpscr = context->fpscr; + OSFillFPUContext(context); + OSSetErrorHandler(error, nullptr); + if (error == OS_ERROR_PROTECTION) + { + OSProtectRange(0, nullptr, 0, 3); + OSProtectRange(1, nullptr, 0, 3); + OSProtectRange(2, nullptr, 0, 3); + OSProtectRange(3, nullptr, 0, 3); + } + + exCallbackObject.callback = sPreUserCallback; + exCallbackObject.error = error; + exCallbackObject.context = context; + exCallbackObject.dsisr = dsisr; + exCallbackObject.dar = dar; + + OSSendMessage(&sMessageQueue, &exCallbackObject, OS_MESSAGE_BLOCK); + OSEnableScheduler(); + OSYieldThread(); +} + +void JUTException::setFPException(u32 fpscr_enable_bits) +{ + __OSFpscrEnableBits = fpscr_enable_bits; + if (fpscr_enable_bits) + { + OSSetErrorHandler(OS_ERROR_FPE, (OSErrorHandler)errorHandler); + } + else + { + OSSetErrorHandler(OS_ERROR_FPE, nullptr); + } +} + +void JUTException::showFloatSub(int index, f32 value) +{ + if (isnan(value)) + { + sConsole->print_f("F%02d: Nan ", index); + } + else if (isinf(value)) + { + if ((*(u8*)(&value)) & 0x80) // signed + { + sConsole->print_f("F%02d:+Inf ", index); + } + else + { + sConsole->print_f("F%02d:-Inf ", index); + } + } + else if (value == 0.0f) + { + sConsole->print_f("F%02d: 0.0 ", index); + } + else + { + sConsole->print_f("F%02d:%+.3E", index, value); + } +} + +void JUTException::showFloat(OSContext *context) +{ + if (!sConsole) + { + return; + } + + sConsole->print("-------------------------------- FPR\n"); + for (int i = 0; i < 10; i++) + { + showFloatSub(i, context->fpr[i]); + sConsole->print(" "); + showFloatSub(i + 11, context->fpr[i + 11]); + sConsole->print(" "); + showFloatSub(i + 22, context->fpr[i + 22]); + sConsole->print("\n"); + } + showFloatSub(10, context->fpr[10]); + sConsole->print(" "); + showFloatSub(21, context->fpr[21]); + sConsole->print("\n"); +} + +bool JUTException::searchPartialModule(u32 address, u32 *module_id, u32 *section_id, u32 *section_offset, u32 *name_offset) +{ + if (!address) + { + return false; + } + + OSModuleInfo *module = *(OSModuleInfo **)0x800030C8; + for (; module != nullptr; module = module->link.next) + { + OSSectionInfo *section = OSGetSectionInfo(module); + for (u32 i = 0; i < module->numSections; section++, i++) + { + if (section->size != 0) + { + u32 addr = section->offset & ~0x01; + if ((addr <= address) && (address < addr + section->size)) + { + if (module_id) + *module_id = module->id; + if (section_id) + *section_id = i; + if (section_offset) + *section_offset = address - addr; + if (name_offset) + *name_offset = module->nameOfs; + return true; + } + } + } + } + + return false; +} + +void search_name_part(u8 *src, u8 *dst, int dst_length) +{ + for (u8 *p = src; *p; p++) + { + if (*p == '\\') + { + src = p; + } + } + + if (*src == '\\') + { + src++; + } + + for (int i = 0; (*src != 0) && (i < dst_length);) + { + if (*src == '.') + break; + *dst++ = *src++; + i++; + } + + *dst = '\0'; +} + +void JUTException::showStack(OSContext *context) +{ + if (!sConsole) + { + return; + } + + u32 i; + + sConsole->print("-------------------------------- TRACE\n"); + u32 *stackPointer = (u32 *)mStackPointer; + sConsole->print_f("Address: BackChain LR save\n"); + + for (i = 0; (stackPointer != nullptr) && (stackPointer != (u32 *)0xFFFFFFFF) && (i++ < 0x10);) + { + if (i > mTraceSuppress) + { + sConsole->print("Suppress trace.\n"); + return; + } + + sConsole->print_f("%08X: %08X %08X\n", stackPointer, stackPointer[0], stackPointer[1]); + showMapInfo_subroutine(stackPointer[1], false); + JUTConsoleManager::getManager()->drawDirect(true); + waitTime(mPrintWaitTime1); + stackPointer = (u32 *)stackPointer[0]; + } +} + +void JUTException::showMainInfo(u16 error, OSContext *context, u32 dsisr, u32 dar) +{ + if (!sConsole) + { + return; + } + + sConsole->print_f("CONTEXT:%08XH (%s EXCEPTION)\n", context, sCpuExpName[error]); + sConsole->print_f("SRR0: %08XH SRR1:%08XH\n", context->srr0, context->srr1); + sConsole->print_f("DSISR: %08XH DAR: %08XH\n", dsisr, dar); +} + +void JUTException::showGPR(OSContext *context) +{ + if (!sConsole) + { + return; + } + + sConsole->print("-------------------------------- GPR\n"); + for (int i = 0; i < 10; i++) + { + sConsole->print_f("R%02d:%08XH R%02d:%08XH R%02d:%08XH\n", i, context->gpr[i], i + 11, + context->gpr[i + 11], i + 22, context->gpr[i + 22]); + } + sConsole->print_f("R%02d:%08XH R%02d:%08XH\n", 10, context->gpr[10], 21, context->gpr[21]); +} + +bool JUTException::showMapInfo_subroutine(u32 address, bool begin_with_newline) +{ + if ((address < 0x80000000) || (0x82ffffff < address)) + { + return false; + } + + u32 name_offset; + u32 module_id; + u32 section_id; + u32 section_offset; + u8 name_part[36]; + + const char *new_line = "\n"; + if (begin_with_newline == false) + { + new_line = ""; + } + + bool result = + searchPartialModule(address, &module_id, §ion_id, §ion_offset, &name_offset); + if (result == true) + { + search_name_part((u8 *)name_offset, name_part, 32); + sConsole->print_f("%s %s:%x section:%d\n", new_line, name_part, section_offset, section_id); + begin_with_newline = false; + } + + JSUListIterator last = sMapFileList.getEnd(); + JSUListIterator first = sMapFileList.getFirst(); + if (first != last) + { + u32 out_addr; + u32 out_size; + char out_line[256]; + + if (result == true) + { + result = + queryMapAddress((char *)name_part, section_offset, section_id, &out_addr, &out_size, + out_line, sizeof(out_line), true, begin_with_newline); + } + else + { + result = queryMapAddress(nullptr, address, -1, &out_addr, &out_size, out_line, + sizeof(out_line), true, begin_with_newline); + } + + if (result == true) + { + return true; + } + } + + return false; +} + +void JUTException::showGPRMap(OSContext *context) +{ + if (!sConsole) + { + return; + } + + bool found_address_register = false; + sConsole->print("-------------------------------- GPRMAP\n"); + + for (int i = 0; i < 31; i++) + { + u32 address = context->gpr[i]; + + if (address >= 0x80000000 && 0x83000000 - 1 >= address) + { + found_address_register = true; + + sConsole->print_f("R%02d: %08XH", i, address); + if (!showMapInfo_subroutine(address, true)) + { + sConsole->print(" no information\n"); + } + JUTConsoleManager::sManager->drawDirect(true); + waitTime(mPrintWaitTime1); + } + } + + if (!found_address_register) + { + sConsole->print(" no register which seem to address.\n"); + } +} + +void JUTException::showSRR0Map(OSContext *context) +{ + if (!sConsole) + { + return; + } + + sConsole->print("-------------------------------- SRR0MAP\n"); + u32 address = context->srr0; + if (address >= 0x80000000 && 0x83000000 - 1 >= address) + { + sConsole->print_f("SRR0: %08XH", address); + if (showMapInfo_subroutine(address, true) == false) + { + sConsole->print(" no information\n"); + } + JUTConsoleManager::getManager()->drawDirect(true); + } +} + +void JUTException::printDebugInfo(JUTException::EInfoPage page, OSError error, OSContext *context, u32 param_3, u32 param_4) +{ + switch (page) + { + case INFOPAGE_GPR: + return showGPR(context); + case INFOPAGE_Float: + showFloat(context); + if (sConsole) + { + sConsole->print_f(" MSR:%08XH\t FPSCR:%08XH\n", msr, fpscr); + } + break; + case INFOPAGE_Stack: + return showStack(context); + case INFOPAGE_GPRMap: + return showGPRMap(context); + case INFOPAGE_SRR0Map: + return showSRR0Map(context); + } +} + +bool JUTException::isEnablePad() const +{ + if (mGamePad == (JUTGamePad *)0xFFFFFFFF) + return true; + + if (mPadPort >= JUTGamePad::Port1) + return true; + + if(mGamePad) { + return true; + } + return false; +} + +bool JUTException::readPad(u32 *out_trigger, u32 *out_button) +{ + bool result = false; + OSTime start_time = OSGetTime(); + OSTime ms; + do + { + OSTime end_time = OSGetTime(); + OSTime ticks = end_time - start_time; + ms = ticks / (OS_TIMER_CLOCK / 1000); + } while (ms < 0x32); + + if (mGamePad == (JUTGamePad *)0xffffffff) + { + JUTGamePad gamePad0(JUTGamePad::Port1); + JUTGamePad gamePad1(JUTGamePad::Port2); + JUTGamePad gamePad2(JUTGamePad::Port3); + JUTGamePad gamePad3(JUTGamePad::Port4); + //JUTGamePad::read(); + + c3bcnt[0] = + (gamePad0.isPushing3ButtonReset() ? (c3bcnt[0] != 0 ? c3bcnt[0] : OSGetTime()) : 0); + c3bcnt[1] = + (gamePad1.isPushing3ButtonReset() ? (c3bcnt[1] != 0 ? c3bcnt[1] : OSGetTime()) : 0); + c3bcnt[2] = + (gamePad2.isPushing3ButtonReset() ? (c3bcnt[2] != 0 ? c3bcnt[2] : OSGetTime()) : 0); + c3bcnt[3] = + (gamePad3.isPushing3ButtonReset() ? (c3bcnt[3] != 0 ? c3bcnt[3] : OSGetTime()) : 0); + + OSTime resetTime0 = (c3bcnt[0] != 0) ? (OSGetTime() - c3bcnt[0]) : 0; + OSTime resetTime1 = (c3bcnt[1] != 0) ? (OSGetTime() - c3bcnt[1]) : 0; + OSTime resetTime2 = (c3bcnt[2] != 0) ? (OSGetTime() - c3bcnt[2]) : 0; + OSTime resetTime3 = (c3bcnt[3] != 0) ? (OSGetTime() - c3bcnt[3]) : 0; + + gamePad0.checkResetCallback(resetTime0); + gamePad1.checkResetCallback(resetTime1); + gamePad2.checkResetCallback(resetTime2); + gamePad3.checkResetCallback(resetTime3); + + if (out_trigger) + { + *out_trigger = gamePad0.getTrigger() | gamePad1.getTrigger() | gamePad2.getTrigger() | + gamePad3.getTrigger(); + } + if (out_button) + { + *out_button = gamePad0.getButton() | gamePad1.getButton() | gamePad2.getButton() | + gamePad3.getButton(); + } + + result = true; + } + else if (mPadPort >= JUTGamePad::Port1) + { + JUTGamePad gamePad(mPadPort); + OSTime &gamePadTime = c3bcnt[0]; + gamePadTime = + (gamePad.isPushing3ButtonReset() ? (gamePadTime != 0 ? gamePadTime : OSGetTime()) : 0); + + OSTime resetTime = (gamePadTime != 0) ? (OSGetTime() - gamePadTime) : 0; + gamePad.checkResetCallback(resetTime); + + //JUTGamePad::read(); + if (out_trigger) + { + *out_trigger = gamePad.getTrigger(); + } + if (out_button) + { + *out_button = gamePad.getButton(); + } + + result = true; + } + else if (mGamePad) + { + //JUTGamePad::read(); + if (out_trigger) + { + *out_trigger = mGamePad->getTrigger(); + } + if (out_button) + { + *out_button = mGamePad->getButton(); + } + + result = true; + } + + return result; +} + +void JUTException::printContext(OSError error, OSContext *context, u32 dsisr, u32 dar) +{ + bool is_pad_enabled = isEnablePad() ? false : true; + if (!sErrorManager->mDirectPrint->isActive()) + { + return; + } + VISetPreRetraceCallback(nullptr); + VISetPostRetraceCallback(nullptr); + VISetBlack(FALSE); + VIFlush(); + + if (!sConsole) + { + return; + } + + if(error < OS_ERROR_MAX) + sConsole->print_f("******** EXCEPTION OCCURRED! ********\nFrameMemory:%XH\n", getFrameMemory()); + else + sConsole->print_f("******** USER HALT ********\nFrameMemory:%XH\n", getFrameMemory()); + + int post_callback_executed = false; + while (true) + { + showMainInfo(error, context, dsisr, dar); + + JUTConsoleManager::sManager->drawDirect(true); + waitTime(mPrintWaitTime0); + + if ((mPrintFlags & EXPRINTFLAG_GPR) != 0) + { + printDebugInfo(INFOPAGE_GPR, error, context, dsisr, dar); + JUTConsoleManager::sManager->drawDirect(true); + waitTime(mPrintWaitTime0); + } + if ((mPrintFlags & EXPRINTFLAG_SRR0Map) != 0) + { + printDebugInfo(INFOPAGE_SRR0Map, error, context, dsisr, dar); + JUTConsoleManager::sManager->drawDirect(true); + waitTime(mPrintWaitTime0); + } + if ((mPrintFlags & EXPRINTFLAG_GPRMap) != 0) + { + printDebugInfo(INFOPAGE_GPRMap, error, context, dsisr, dar); + JUTConsoleManager::sManager->drawDirect(true); + waitTime(mPrintWaitTime0); + } + if ((mPrintFlags & EXPRINTFLAG_Float) != 0) + { + printDebugInfo(INFOPAGE_Float, error, context, dsisr, dar); + JUTConsoleManager::sManager->drawDirect(true); + waitTime(mPrintWaitTime0); + } + if ((mPrintFlags & EXPRINTFLAG_Stack) != 0) + { + printDebugInfo(INFOPAGE_Stack, error, context, dsisr, dar); + JUTConsoleManager::sManager->drawDirect(true); + waitTime(mPrintWaitTime1); + } + + sConsole->print("--------------------------------\n"); + JUTConsoleManager::sManager->drawDirect(true); + + if (post_callback_executed == 0 && sPostUserCallback) + { + BOOL enable = OSEnableInterrupts(); + post_callback_executed = true; + (*sPostUserCallback)(error, context, dsisr, dar); + OSRestoreInterrupts(enable); + } + + if (_98 == 0 || !is_pad_enabled) + { + break; + } + + sConsole->setOutput(sConsole->getOutput() & 1); + } + + if (!is_pad_enabled) + { + OSEnableInterrupts(); + + u32 button; + u32 trigger; + + int down = 0; + int up = 0; + do + { + readPad(&trigger, &button); + + bool draw = false; + if (trigger == 0x100) + { + sConsole->scrollToLastLine(); + draw = true; + } + + if (trigger == 0x200) + { + sConsole->scrollToFirstLine(); + draw = true; + } + + if (button == 8) + { + JUTConsole *console = sConsole; + up = (down < 3) ? -1 : ((down < 5) ? -2 : ((down < 7) ? -4 : -8)); + + console->scroll(up); + draw = true; + up = 0; + down++; + } + else if (button == 4) + { + JUTConsole *console = sConsole; + down = (up < 3) ? 1 : ((up < 5) ? 2 : ((up < 7) ? 4 : 8)); + + console->scroll(down); + draw = true; + down = 0; + up++; + } + else + { + down = 0; + up = 0; + } + + if (draw == true) + { + u32 start = VIGetRetraceCount(); + while (start == VIGetRetraceCount()) + ; + JUTConsoleManager::sManager->drawDirect(true); + } + + waitTime(30); + } while (true); + } + + while (true) + { + sConsole->scrollToFirstLine(); + JUTConsoleManager::sManager->drawDirect(true); + waitTime(2000); + + int line_offset; + int used_line; + u32 height; + next: + for (u32 i = sConsole->getHeight(); i > 0; i--) + { + sConsole->scroll(1); + JUTConsoleManager::sManager->drawDirect(true); + + height = sConsole->getHeight(); + JUTConsole *console = sConsole; + line_offset = console->getLineOffset(); + used_line = console->getUsedLine(); + if ((used_line - height) + 1U <= line_offset) + break; + waitTime(20); + } + + waitTime(3000); + height = sConsole->getHeight(); + JUTConsole *console = sConsole; + line_offset = console->getLineOffset(); + used_line = console->getUsedLine(); + if ((used_line - height) + 1U <= line_offset) + { + continue; + } + goto next; + } +} + +void JUTException::waitTime(s32 timeout_ms) +{ + if (timeout_ms) + { + OSTime start_time = OSGetTime(); + OSTime ms; + do + { + OSTime end_time = OSGetTime(); + OSTime ticks = end_time - start_time; + ms = ticks / (OS_TIMER_CLOCK / 1000); + } while (ms < timeout_ms); + } +} + +void JUTException::createFB() +{ + GXRenderModeObj *renderMode = &GXNtsc480Int; + void *end = (void *)OSGetArenaHi(); + u16 width = ALIGN_NEXT(renderMode->fbWidth, 16); + u16 height = renderMode->xfbHeight; + u32 pixel_count = width * height; + u32 size = pixel_count * 2; + + void *begin = (void *)ALIGN_PREV((u32)end - size, 32); + void *object = (void *)ALIGN_PREV((s32)begin - sizeof(JUTExternalFB), 32); + JUTExternalFB *fb = new (object) JUTExternalFB(renderMode, GX_GM_1_7, begin, size); + + mDirectPrint->changeFrameBuffer(object); + VIConfigure(renderMode); + VISetNextFrameBuffer(begin); + VISetBlack(FALSE); + VIFlush(); + + mFrameMemory = (JUTExternalFB *)object; +} + +u32 JUTException::getFpscr() { + // TODO: misses stack frame + register u32 ret; + asm { + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 + isync + mffs f1 + stfd f1, 8(r1) + lwz ret, 12(r1) + } + return ret; +} + +JUTErrorHandler JUTException::setPreUserCallback(JUTErrorHandler callback) +{ + JUTErrorHandler previous = sPreUserCallback; + sPreUserCallback = callback; + return previous; +} + +JUTErrorHandler JUTException::setPostUserCallback(JUTErrorHandler callback) +{ + JUTErrorHandler previous = sPostUserCallback; + sPostUserCallback = callback; + return previous; +} + +void JUTException::appendMapFile(const char *path) +{ + if (!path) + { + return; + } + + JSUListIterator iterator; + for (iterator = sMapFileList.getFirst(); iterator != sMapFileList.getEnd(); ++iterator) + { + if (strcmp(path, iterator->mFileName) == 0) + { + return; + } + } + + JUTExMapFile *mapFile = new JUTExMapFile((char *)path); + sMapFileList.append(&mapFile->mLink); +} + +bool JUTException::queryMapAddress(char *mapPath, u32 address, s32 section_id, u32 *out_addr, u32 *out_size, char *out_line, u32 line_length, bool print, bool begin_with_newline) +{ + if (mapPath) + { + char buffer[80]; + strcpy(buffer, mapPath); + strcat(buffer, ".map"); + if (queryMapAddress_single(buffer, address, section_id, out_addr, out_size, out_line, + line_length, print, begin_with_newline) == true) + { + return true; + } + } + else if (sMapFileList.getFirst() != sMapFileList.getEnd()) + { + if (queryMapAddress_single(sMapFileList.getFirst()->getObject()->mFileName, address, -1, + out_addr, out_size, out_line, line_length, print, + begin_with_newline) == true) + { + return true; + } + } + + return false; +} + +bool JUTException::queryMapAddress_single(char *mapPath, u32 address, s32 section_id, u32 *out_addr, u32 *out_size, char *out_line, u32 line_length, bool print, bool begin_with_newline) +{ + /* fake match on TP debug? */ + if (!mapPath) + { + return false; + } + + char section_name[16]; + char buffer[0x200]; + JUTDirectFile file; + int section_idx = 0; + if (!file.fopen(mapPath)) + { + return false; + } + + bool result = false; + bool found_section; + + while (true) + { + section_idx++; + found_section = false; + while (true) + { + char *src; + char *dst; + + if (file.fgets(buffer, sizeof(buffer)) < 0) + break; + if (buffer[0] != '.') + continue; + + int i = 0; + src = buffer + 1; + while (*src != '\0') + { + section_name[i] = *src; + if (*src == ' ' || i == 0xf) + break; + i++; + src++; + } + + section_name[i] = 0; + if (*src == 0) + break; + + if (src[1] == 's' && src[2] == 'e' && src[3] == 'c' && src[4] == 't') + { + found_section = true; + break; + } + } + + if (!found_section) + break; + + if (section_id >= 0 && section_id != section_idx) + continue; + + int length; + + while (true) + { + if ((length = file.fgets(buffer, sizeof(buffer))) <= 4) + break; + if ((length < 28)) + continue; + if ((buffer[28] == '4')) + { + u32 addr = ((buffer[18] - '0') << 28) | strtol(buffer + 19, nullptr, 16); + int size = strtol(buffer + 11, nullptr, 16); + if ((addr <= address && address < addr + size)) + { + if (out_addr) + *out_addr = addr; + + if (out_size) + *out_size = size; + + if (out_line) + { + const u8 *src = (const u8 *)&buffer[0x1e]; + u8 *dst = (u8 *)out_line; + u32 i = 0; + + for (i = 0; i < line_length - 1; ++src) + { + if ((u32)(*src) < ' ' && (u32)*src != '\t') + break; + if ((*src == ' ' || (u32)*src == '\t') && (i != 0)) + { + if (dst[-1] != ' ') + { + *dst = ' '; + dst++; + ++i; + } + } + else + { + *dst++ = *src; + i++; + } + } + + if (i != 0 && dst[-1] == ' ') + { + dst--; + i--; + } + *dst = 0; + + if (print) + { + if (begin_with_newline) + { + sConsole->print("\n"); + } + sConsole->print_f(" [%08X]: .%s [%08X: %XH]\n %s\n", address, section_name, addr, size, out_line); + begin_with_newline = false; + } + } + result = true; + break; + } + } + (void)0; // memes + } + + //if (!result) + //{ + if ((section_id < 0 || section_id != section_idx)) + { + goto cont; + } + //} + if (print && begin_with_newline) + { + sConsole->print("\n"); + } + break; + cont:; + } + + file.fclose(); + return result ? true : false; +} + +void JUTException::createConsole(void *console_buffer, u32 console_buffer_size) +{ + if (!console_buffer || !console_buffer_size) + { + return; + } + + u32 lines = JUTConsole::getLineFromObjectSize(console_buffer_size, 0x32); + if (lines != 0) + { + sConsoleBuffer = console_buffer; + sConsoleBufferSize = console_buffer_size; + sConsole = JUTConsole::create(0x32, console_buffer, console_buffer_size); + + JUTConsoleManager *manager = JUTConsoleManager::sManager; + manager->setDirectConsole(sConsole); + + sConsole->setFontSize(10.0, 6.0); + sConsole->setPosition(15, 26); + sConsole->setHeight(23); + sConsole->setVisible(true); + sConsole->setOutput(JUTConsole::OUTPUT_OSR_AND_CONSOLE); + } +} + +JUTExternalFB::JUTExternalFB(GXRenderModeObj *renderMode, GXGamma gamma, void *buffer, u32 size) +{ + mRenderModeObj = renderMode; + mSize = size; + _0C = 1; + mGamma = gamma; + _10 = false; +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTFader.cpp b/src/static/JSystem/JUtility/JUTFader.cpp new file mode 100644 index 00000000..465aaa70 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTFader.cpp @@ -0,0 +1,117 @@ +#include "types.h" +#include "JSystem/JUtility/JUTFader.h" +#include "JSystem/JUtility/TColor.h" +#include "JSystem/J2D/J2DGrafContext.h" + +JUTFader::JUTFader(int p1, int p2, int p3, int p4, JUtility::TColor color) + : mColor(color), mViewBox(p1, p2, p1 + p3, p2 + p4) +{ + mStatus = Status_Out; + mTicksTarget = 0; + mTicksRun = 0; + _28 = Status_Out; + mEStatus = -1; +} + +void JUTFader::control() +{ + if (0 <= mEStatus && mEStatus-- == 0) + mStatus = _28; + + if (mStatus == Status_In) + return; + + switch (mStatus) + { + case Status_Out: + mColor.a = 0xFF; + break; + case Status_FadingIn: + mColor.a = 0xFF - ((++mTicksRun * 0xFF) / mTicksTarget); + if (mTicksRun >= mTicksTarget) + { + mStatus = Status_In; + } + break; + case Status_FadingOut: + mColor.a = ((++mTicksRun * 0xFF) / mTicksTarget); + if (mTicksRun >= mTicksTarget) + { + mStatus = Status_Out; + } + break; + } + draw(); +} + +void JUTFader::draw() +{ + if (mColor.a == 0) + return; + + J2DOrthoGraph orthograph; + orthograph.setColor(mColor); + orthograph.fillBox(mViewBox); +} + +void JUTFader::start(int) +{ + // UNUSED FUNCTION +} + +bool JUTFader::startFadeIn(int duration) +{ + bool fadingOut = mStatus == Status_Out; + + if (fadingOut) { + mStatus = Status_FadingIn; + mTicksRun = 0; + mTicksTarget = duration; + } + + return fadingOut; +} + +bool JUTFader::startFadeOut(int duration) +{ + bool fadingIn = mStatus == Status_In; + + if (fadingIn) { + mStatus = Status_FadingOut; + mTicksRun = 0; + mTicksTarget = duration; + } + + return fadingIn; +} + +void JUTFader::setStatus(JUTFader::EStatus i_status, int param_1) +{ + switch (i_status) + { + case Status_Out: + if (param_1 != 0) + { + _28 = Status_Out; + mEStatus = (u16)param_1; + break; + } + + mStatus = Status_Out; + _28 = Status_Out; + mEStatus = 0; + break; + case Status_In: + if (param_1 != 0) + { + _28 = Status_In; + mEStatus = (u16)param_1; + break; + } + + mStatus = Status_In; + _28 = Status_In; + mEStatus = 0; + break; + } +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTFont.cpp b/src/static/JSystem/JUtility/JUTFont.cpp new file mode 100644 index 00000000..a990eb2b --- /dev/null +++ b/src/static/JSystem/JUtility/JUTFont.cpp @@ -0,0 +1,52 @@ +#include "JSystem/JUtility/JUTFont.h" +#include "JSystem/JUtility/JUTAssertion.h" + +JUTFont::JUTFont() : mColor1(), mColor2(), mColor3(), mColor4() +{ + mValid = false; +} + +void JUTFont::initialize_state() +{ + setCharColor(JUtility::TColor()); + setFixedWidth(false, 0); + mValid = false; +} + +void JUTFont::setCharColor(JUtility::TColor color) +{ + mColor1 = color; + mColor2 = color; + mColor3 = color; + mColor4 = color; +} + +void JUTFont::setGradColor(JUtility::TColor color, JUtility::TColor color2) +{ + mColor1 = color; + mColor2 = color; + mColor3 = color2; + mColor4 = color2; +} + +f32 JUTFont::drawString_size_scale(f32 w, f32 x, f32 y, f32 z, const char *str, u32 usz, bool flag) +{ + int str_int; + f32 w_old = w; + + for (; usz != 0; usz--, str++) + { + str_int = (u8)*str; + if (isLeadByte(str_int)) + { + JUT_ASSERT(usz >= 2); + usz--; + str++; + str_int <<= 8; + str_int |= (u8)*str; + } + w += (drawChar_scale(w, x, y, z, str_int, flag)); + flag = true; + } + return w - w_old; +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTGraphFifo.cpp b/src/static/JSystem/JUtility/JUTGraphFifo.cpp new file mode 100644 index 00000000..86a328f5 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTGraphFifo.cpp @@ -0,0 +1,45 @@ +#include +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JUtility/JUTGraphFifo.h" + +bool JUTGraphFifo::sInitiated; +JUTGraphFifo *JUTGraphFifo::sCurrentFifo; +GXBool JUTGraphFifo::mGpStatus[5]; + +JUTGraphFifo::JUTGraphFifo(u32 size) +{ + mSize = ALIGN_NEXT(size, 32); + if (sInitiated) + { + mFifo = (GXFifoObj *)JKRAllocFromSysHeap(mSize + sizeof(GXFifoObj), 32); + mBase = mFifo + 1; + GXInitFifoBase(mFifo, mBase, mSize); + GXInitFifoPtrs(mFifo, mBase, mBase); + } + else + { + /** TODO: Figure out what has sizeof 0xA0. */ + mBase = JKRAllocFromSysHeap(mSize + 0xA0, 32); + mBase = (void *)ALIGN_NEXT((u32)mBase, 32); + mFifo = GXInit(mBase, mSize); + sInitiated = true; + sCurrentFifo = this; + } +} + +JUTGraphFifo::~JUTGraphFifo() +{ + sCurrentFifo->save(); + + while (isGPActive()) + { + ; + } + + if (sCurrentFifo == this) + { + sCurrentFifo = nullptr; + } + + JKRFreeToSysHeap(mBase); +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTProcBar.cpp b/src/static/JSystem/JUtility/JUTProcBar.cpp new file mode 100644 index 00000000..804609a6 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTProcBar.cpp @@ -0,0 +1,298 @@ +#include "JSystem/J2D/J2DGrafContext.h" +#include "JSystem/JUtility/JUTVideo.h" +#include "JSystem/JUtility/JUTProcBar.h" + + +JUTProcBar *JUTProcBar::sManager; + +f32 oneFrameRate = 8.0f; +f32 oneFrameRateUser = 10.0f; + +JUTProcBar::JUTProcBar() { + mVisible = true; + mHeapBarVisible = true; + _108 = 0; + + u16 height = JUTVideo::getManager()->getXfbHeight(); + if (JUTVideo::getManager()->getXfbHeight() > 400) { + + mParams.setBarWidth(2); + mParams.setPosition(39, height - 40); + mParams.setWidth(562); + mParams.setUserPosition(height - 70); + } + else { + mParams.setBarWidth(1); + mParams.setPosition(39, height - 20); + mParams.setWidth(562); + mParams.setUserPosition(height - 35); + } + _110 = 1; + _128 = 0; + mWatchHeap = nullptr; +} + +JUTProcBar::~JUTProcBar() { + sManager = nullptr; +} + +JUTProcBar *JUTProcBar::create() { + if (!sManager) { + sManager = new JUTProcBar(); + } + return sManager; +} + +void JUTProcBar::destroy() { + if (sManager) { + delete sManager; + } + sManager = nullptr; +} + +void JUTProcBar::clear() { + sManager->idleStart(); + sManager->cpuStart(); + sManager->gpStart(); + sManager->wholeLoopStart(); + sManager->mCostFrame = 0; + oneFrameRate = 8.0f; + oneFrameRateUser = 10.0f; +} + +// Matches +void JUTProcBar::bar_subroutine(int param_0, int param_1, int param_2, int param_3, int param_4, + int param_5, int param_6, JUtility::TColor param_7, + JUtility::TColor param_8) { + int var2 = param_5 * param_3 / param_4; + int var1 = param_6 * param_3 / param_4; + + J2DFillBox(param_0, param_1, var2, param_2, param_7); + if (var1 >= 0) + { + if (var1 < 6) + J2DFillBox(param_0, param_1, var1, param_2, param_8); + else + J2DFillBox(param_0 + var1 - 6, param_1, 6.0f, param_2, param_8); + } +} + +// Matched +// perhaps rewrite this function, kinda annoying to read +void JUTProcBar::adjustMeterLength(u32 param_0, f32 *param_1, f32 param_2, f32 param_3, + int *param_4) { + BOOL var2 = false; + float var1 = *param_1; + while (var1 > param_2) + { + if (param_0 * var1 * 20.0f / 16666.0f <= mParams.mWidth - 30.0f) + break; + + var1 -= 0.1f; + var2 = true; + } + + if (var1 >= param_3) + *param_4 = 0; + if (var1 > param_3 - 0.2f) + var1 = param_3; + + while (!var2 && var1 < param_3) + { + (*param_4)++; + if (*param_4 < 0x1e) + break; + if ((param_0 * var1 * 20.0f / 16666.0f) < (mParams.mWidth - 60.0f)) + var1 += 0.2f; + break; + } + *param_1 = var1; +} + +void JUTProcBar::draw() { + drawProcessBar(); + drawHeapBar(); +} + +/* +MKDD: https://decomp.me/scratch/1Q2Ke +TP: https://decomp.me/scratch/YKjcF +*/ +void JUTProcBar::drawProcessBar() { + if (mVisible) + { + int frameDuration = 16666; // duration in miliseconds? for how long a frame takes, + if (JUTVideo::getManager() && ((JUTVideo::getManager()->getRenderMode()->viTVmode >> 2) & 0x0f) == VI_PAL) // possibly a define + frameDuration = 20000; // duration for PAL + + static int cnt = 0; + adjustMeterLength(mWholeLoop.mCost, &oneFrameRate, 1.0f, 10.0f, &cnt); + int r28 = oneFrameRate * 20.0f; + int r27 = mParams.mBarWidth * 8; + int r26 = mParams.mBarWidth * 2; + int r25 = mParams.mBarWidth * 10; + int r24 = (mParams.mWidth - 4 + r28) / r28; + + mIdle.accumePeek(); + mGp.accumePeek(); + mCpu.accumePeek(); + + u32 totalTime = (mGp.mCost - mGpWait.mCost) - mCpu.mCost; // unsure of types + u32 gpuTime = (mGp.mCost - mGpWait.mCost); + J2DFillBox(mParams.mPosX, mParams.mPosY, mParams.mWidth, r27, JUtility::TColor(0, 0, 50, 200)); + J2DDrawFrame(mParams.mPosX, mParams.mPosY, mParams.mWidth, r27, JUtility::TColor(50, 50, 150, 255), 6); + if (mCostFrame > r24) + J2DFillBox(mParams.mPosX, mParams.mPosY + r27 + 1, mParams.mWidth, 1.0f, JUtility::TColor(250, 0, 0, 200)); + else + J2DFillBox(mParams.mPosX, mParams.mPosY + r27 + 1, mCostFrame * r28 + 2, 1.0f, JUtility::TColor(0, 250, 250, 200)); + + int stack92 = mWholeLoop.mCost * r28 / frameDuration; + if (stack92 > mParams.mWidth) + J2DFillBox(mParams.mPosX, mParams.mPosY, mParams.mWidth, 1.0f, JUtility::TColor(255, 100, 0, 255)); + else + J2DFillBox(mParams.mPosX, mParams.mPosY, stack92, 1.0f, JUtility::TColor(50, 255, 0, 255)); + + if (_110 == 0) + { + int r23 = mParams.mPosY + mParams.mBarWidth; + bar_subroutine(mParams.mPosX + 1, r23, r26, r28, frameDuration, mGp.mCost, mGp._08, JUtility::TColor(80, 255, 80, 255), JUtility::TColor(100, 255, 120, 255)); + r23 += mParams.mBarWidth * 2; + bar_subroutine(mParams.mPosX + 1, r23, r26, r28, frameDuration, mCpu.mCost, mCpu._08, JUtility::TColor(255, 80, 80, 255), JUtility::TColor(255, 100, 100, 255)); + r23 += mParams.mBarWidth * 2; + bar_subroutine(mParams.mPosX + 1, r23, r26, r28, frameDuration, mIdle.mCost, mIdle._08, JUtility::TColor(180, 180, 160, 255), JUtility::TColor(200, 200, 200, 255)); + } + else + { + int r22 = mParams.mPosY + mParams.mBarWidth; + int r21 = mParams.mPosX + 1; + bar_subroutine(r21, r22, r26, r28, frameDuration, gpuTime, -1, JUtility::TColor(80, 255, 80, 255), JUtility::TColor(80, 255, 80, 255)); + int thingy1 = gpuTime * r28 / frameDuration + r21; + J2DFillBox(thingy1, r22, mGpWait.calcBarSize(r28, frameDuration), r26, JUtility::TColor(0, 255, 0, 255)); + int r30 = mGp.calcBarSize(r28, frameDuration) + r21; + r21 += totalTime * r28 / frameDuration; + r22 += mParams.mBarWidth * 2; + bar_subroutine(r21, r22, r26, r28, frameDuration, mCpu.mCost, -1, JUtility::TColor(255, 80, 80, 255), JUtility::TColor(255, 80, 80, 255)); + r22 += mParams.mBarWidth * 2; + bar_subroutine(r30, r22, r26, r28, frameDuration, mIdle.mCost, -1, JUtility::TColor(180, 180, 160, 255), JUtility::TColor(180, 180, 160, 255)); + } + for (int i = 1; i < r24; i++) + { + int temp2 = mParams.mPosX + i * r28 + 1; + J2DDrawLine(temp2, mParams.mPosY + mParams.mBarWidth, temp2, mParams.mPosY + r27 - mParams.mBarWidth, (i % 5) != 0 ? JUtility::TColor(100, 100, 255, 255) : JUtility::TColor(180, 255, 255, 255), 12); + } + u32 temp3 = 0; + for (int i = 0; i < 8; i++) + { + CTime *time = &mUsers[i]; + if (++time->_0C >= 0x10 || time->mCost > time->_08) { + time->_08 = time->mCost; + time->_0C = 0; + } + if (time->_08 > temp3) + temp3 = time->_08; + } + if ((temp3 ? true : false) == true) + { + static int cntUser = 0; + adjustMeterLength(temp3, &oneFrameRateUser, 1.0f, 10.0f, &cntUser); + int r21 = oneFrameRateUser * 20.0f; + J2DFillBox(mParams.mPosX, mParams.mUserPosition, mParams.mWidth, r25, JUtility::TColor(0, 0, 50, 200)); + J2DDrawFrame(mParams.mPosX, mParams.mUserPosition, mParams.mWidth, r25, JUtility::TColor(50, 50, 150, 255), 6); + for (int i = 0; i < 8; i++) + { + CTime *time = &mUsers[i]; + if (++time->_0C >= 0x10 || time->mCost > time->_08) { + time->_08 = time->mCost; + time->_0C = 0; + } + if (time->mCost != 0 || time->_08 != 0) + { + int temp4 = time->mCost * r21 / frameDuration; + int temp5 = time->_08 * r21 / frameDuration; + time->mCost = 0; + J2DFillBox(mParams.mPosX + 1, mParams.mUserPosition + mParams.mBarWidth + i * mParams.mBarWidth, temp4, mParams.mBarWidth, JUtility::TColor(time->mR, time->mG, time->mB, 255)); + + if (temp5 < 3u) + J2DFillBox(mParams.mPosX, mParams.mUserPosition + mParams.mBarWidth + i * mParams.mBarWidth, temp5, mParams.mBarWidth, JUtility::TColor(255, 200, 50, 255)); + else + J2DFillBox(mParams.mPosX + temp5 - 3, mParams.mUserPosition + mParams.mBarWidth + i * mParams.mBarWidth, 3.0f, mParams.mBarWidth, JUtility::TColor(255, 200, 50, 255)); + } + } + + int r22 = (mParams.mWidth - 4 + r21) / r21; + + for (int i = 1; i < r22; i++) + { + int temp6 = mParams.mPosX + i * r21 + 1; + J2DDrawLine(temp6, mParams.mUserPosition + mParams.mBarWidth, temp6, mParams.mUserPosition + r25 - mParams.mBarWidth, (i % 5) != 0 ? JUtility::TColor(100, 100, 255, 255) : JUtility::TColor(180, 255, 255, 255), 12); + } + } + _108 = 0; + } +} + +int addrToXPos(void *param_0, int param_1) { + return param_1 * (((u32)param_0 - 0x80000000) / (float)JKRHeap::getMemorySize()); +} + +int byteToXLen(int param_0, int param_1) { + return param_1 * (param_0 / (float)JKRHeap::getMemorySize()); +} + +static void heapBar(JKRHeap *param_0, int param_1, int param_2, int param_3, int param_4, + int param_5) +{ + int stack52 = param_1 + addrToXPos(param_0->getStartAddr(), param_4); + int var1 = param_1 + addrToXPos(param_0->getEndAddr(), param_4); + int stack36 = byteToXLen(param_0->getTotalFreeSize(), param_4); + J2DFillBox(stack52, param_2 - param_5 * 2 + param_5 / 2, var1 - stack52, param_5 / 2, + JUtility::TColor(255, 0, 200, 255)); + J2DFillBox(stack52, param_2 - param_5 * 2 + param_5 / 2, stack36, param_5 / 2, + JUtility::TColor(255, 180, 250, 255)); +} + +/* +Probably close to TP Debug, currently matches TP and MKDD(pik2 probably too) +MKDD(Debug): https://decomp.me/scratch/BUM6J +MKDD(Releae) https://decomp.me/scratch/bxY1q +TP(O3): https://decomp.me/scratch/Mi52V +*/ +void JUTProcBar::drawHeapBar() +{ + if (mHeapBarVisible) + { + int start; // required/workaround for regswaps, end might be a shared variable too, however doesn't seem to be needed? + int posX = mParams.mPosX; + int posY = mParams.mPosY; + int barHeight = mParams.mBarWidth * 2; + int width = mParams.mWidth; + int height = mParams.mBarWidth * 2; + + // draw main box in opaque bordeaux red and main frame in purple? + J2DFillBox(posX, posY - (height * 2), width, height, JUtility::TColor(100, 0, 50, 200)); + J2DDrawFrame(posX, posY - (height * 2), width, height, JUtility::TColor(100, 50, 150, 255), 6); + + // Draws a pink line that shows the size of the memstart to start of arenalow? + start = posX + addrToXPos(JKRHeap::getCodeStart(), width); + int codeEnd = posX + addrToXPos(JKRHeap::getCodeEnd(), width); + J2DFillBox(start, posY - (height * 2), codeEnd - start, height, JUtility::TColor(255, 50, 150, 255)); + + // draws a dark blue line that shows how much memory is free? + start = posX + addrToXPos(JKRHeap::getUserRamStart(), width); + int userEnd = posX + addrToXPos(JKRHeap::getUserRamEnd(), width); + J2DFillBox(start, posY - (height * 2), userEnd - start, height, JUtility::TColor(0, 50, 150, 255)); + + // draws a light blue line that shows how much memory is free in the root heap(blends to light pink, not sure how this works) + int size = byteToXLen(JKRHeap::getRootHeap()->getTotalFreeSize(), width); + J2DFillBox(start, posY - (height * 2), size, height / 2, JUtility::TColor(0, 250, 250, 255)); + if (_128 == 0) + { + // draws a line of either the watch heap(if available), otherwise draw the current heap + JKRHeap *heap = mWatchHeap ? mWatchHeap : JKRGetCurrentHeap(); + if (heap != JKRHeap::getSystemHeap()) { + heapBar(heap, posX, posY, barHeight, width, height); + } + + } + } +} diff --git a/src/static/JSystem/JUtility/JUTResFont.cpp b/src/static/JSystem/JUtility/JUTResFont.cpp new file mode 100644 index 00000000..d82e6d1e --- /dev/null +++ b/src/static/JSystem/JUtility/JUTResFont.cpp @@ -0,0 +1,528 @@ +#include +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JSupport.h" +#include "JSystem/JUtility/JUTConsole.h" +#include "JSystem/JUtility/JUTAssertion.h" +#include "JSystem/JUtility/JUTFont.h" +#include "types.h" + +JUTFont::IsLeadByte const JUTResFont::saoAboutEncoding_[3] = {JUTFont::isLeadByte_1Byte, JUTFont::isLeadByte_2Byte, JUTFont::isLeadByte_ShiftJIS}; +const u32 suAboutEncoding_ = 3; + +JUTResFont::JUTResFont() +{ + initialize_state(); +} + +JUTResFont::JUTResFont(const ResFONT *resource, JKRHeap *heap) +{ + initialize_state(); + JUTResFont::initiate(resource, heap); +} + +JUTResFont::~JUTResFont() +{ + if (mValid) + { + deleteMemBlocks_ResFont(); + initialize_state(); + JUTFont::initialize_state(); + } +} + +void JUTResFont::deleteMemBlocks_ResFont() { delete[] mMemBlocks; } + +void JUTResFont::initialize_state() +{ + mResource = nullptr; + mMemBlocks = nullptr; + mWidthBlocks = nullptr; + mGlyphBlocks = nullptr; + mMapBlocks = nullptr; + mWidth = 0; + mHeight = 0; + _44 = -1; +} + +bool JUTResFont::initiate(const ResFONT *resource, JKRHeap *heap) +{ + if (!protected_initiate(resource, heap)) + { + deleteMemBlocks_ResFont(); + initialize_state(); + JUTFont::initialize_state(); + mValid = false; + return false; + } + return true; +} + +bool JUTResFont::protected_initiate(const ResFONT *resource, JKRHeap *heap) +{ + void **blocks; + + deleteMemBlocks_ResFont(); + initialize_state(); + JUTFont::initialize_state(); + + if (!resource) + { + return false; + } + + mResource = resource; + mValid = true; + + countBlock(); + u32 blockNum = mWidthBlockCount + mGlyphBlockCount + mMapBlockCount; + + mMemBlocks = new (heap, 0) void *[blockNum]; + blocks = mMemBlocks; + if (mMemBlocks == nullptr) + { + return false; + } + else + { + if (mWidthBlockCount != 0) + { + mWidthBlocks = (ResFONT::WidthBlock **)blocks; + blocks += mWidthBlockCount; + } + + if (mGlyphBlockCount != 0) + { + mGlyphBlocks = (ResFONT::GlyphBlock **)blocks; + blocks += mGlyphBlockCount; + } + + if (mMapBlockCount != 0) + { + mMapBlocks = (ResFONT::MapBlock **)blocks; + } + } + + setBlock(); + return true; +} + +void JUTResFont::countBlock() +{ + mWidthBlockCount = 0; + mGlyphBlockCount = 0; + mMapBlockCount = 0; + + BlockHeader *data = (BlockHeader *)mResource->mData; + for (u32 i = 0; i < mResource->mNumBlocks; i++, data = (BlockHeader *)data->getNext()) + { + int magic = data->mMagic; + switch (magic) + { + case 'WID1': + mWidthBlockCount++; + break; + + case 'GLY1': + mGlyphBlockCount++; + break; + + case 'MAP1': + mMapBlockCount++; + break; + + case 'INF1': + // mInfoBlock; + break; + + default: + JUTReportConsole("JUTResFont: Unknown data block\n"); + } + }; +} + +void JUTResFont::setBlock() +{ + int widthNum = 0; + int glyphNum = 0; + int mapNum = 0; + mMaxCode = -1; + + BlockHeader *data = (BlockHeader *)mResource->mData; + for (u32 i = 0; i < mResource->mNumBlocks; i++, data = (BlockHeader *)data->getNext()) + { + int magic = data->mMagic; + switch (magic) + { + case 'INF1': + mInfoBlock = (ResFONT::InfoBlock *)data; + u32 u = mInfoBlock->mFontType; +#line 244 + JUT_ASSERT(u < suAboutEncoding_); + mIsLeadByte = (IsLeadByte *)&saoAboutEncoding_[u]; + break; + + case 'WID1': + mWidthBlocks[widthNum] = (ResFONT::WidthBlock *)data; + widthNum++; + break; + + case 'GLY1': + mGlyphBlocks[glyphNum] = (ResFONT::GlyphBlock *)data; + glyphNum++; + break; + + case 'MAP1': + mMapBlocks[mapNum] = (ResFONT::MapBlock *)data; + if (mMaxCode > mMapBlocks[mapNum]->mStartCode) + { + mMaxCode = mMapBlocks[mapNum]->mStartCode; + } + mapNum++; + break; + + default: + JUTReportConsole("Unknown data block\n"); + break; + } + } +} + +void JUTResFont::setGX() +{ + GXSetNumChans(1); + GXSetNumTevStages(1); + GXSetNumTexGens(1); + + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + + GXSetTevOp(GX_TEVSTAGE0, GX_MODULATE); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_RGBA4, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBX8, 15); + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); +} + +void JUTResFont::setGX(JUtility::TColor color0, JUtility::TColor color1) +{ + if (u32(color0) == 0 && u32(color1) == -1) + { + setGX(); + } + else + { + GXSetNumChans(1); + GXSetNumTevStages(2); + GXSetNumTexGens(1); + + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + + GXSetTevColor(GX_TEVREG0, color0); + GXSetTevColor(GX_TEVREG1, color1); + + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C0, GX_CC_C1, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_A0, GX_CA_A1, GX_CA_TEXA, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_RASC, GX_CC_ZERO); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_APREV, GX_CA_RASA, GX_CA_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBX8, 15); + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + } +} + +f32 JUTResFont::drawChar_scale(f32 pos_x, f32 pos_y, f32 scale_x, f32 scale_y, int chr, bool flag) +{ + JUTFont::TWidth width; + f32 posMinX; + // declaration order matters! + f32 posMinY, scaled_height; + f32 posMaxX; + +#line 378 + JUT_ASSERT(mValid); + + loadFont(chr, GX_TEXMAP0, &width); + + if ((mFixed) || (!flag)) + { + posMinX = pos_x; + } + else + { + posMinX = (pos_x - width.w0 * (scale_x / getCellWidth())); + } + + f32 retval = mFixedWidth * (scale_x / getCellWidth()); + if (!mFixed) + { + if (!flag) + { + retval = (width.w1 + width.w0) * (scale_x / getCellWidth()); + } + else + { + retval = width.w1 * (scale_x / getCellWidth()); + } + } + posMaxX = posMinX + scale_x; + // getAscent needs to be called before getHeight for the sake of weak function order + posMinY = pos_y - getAscent() * (scale_y / getHeight()); + scaled_height = scale_y / getHeight(); + f32 descent = getDescent(); + f32 posMaxY = descent * scaled_height + pos_y; + + // glyph section + ResFONT::GlyphBlock *used_glyphs = mGlyphBlocks[_66]; + u16 tex_width = used_glyphs->mTextureWidth; + u16 tex_height = used_glyphs->mTextureHeight; + int t_width = mWidth; + int t_height = mHeight; + int shift_width = (t_width + used_glyphs->mCellWidth) << 15; + int texMinX = (t_width << 15) / tex_width; + int texMinY = (t_height << 15) / tex_height; + int shift_height = t_height + used_glyphs->mCellHeight << 15; + const u32 texMaxX = shift_width / tex_width; + const u32 texMaxY = shift_height / tex_height; + // end glyph section + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + // Bottom left + GXPosition3f32(posMinX, posMinY, 0.0f); + GXColor1u32(mColor1); + GXPosition2u16(texMinX, texMinY); + + // Bottom right + GXPosition3f32(posMaxX, posMinY, 0.0f); + GXColor1u32(mColor2); + GXPosition2u16(texMaxX, texMinY); + + // Top right + GXPosition3f32(posMaxX, posMaxY, 0.0f); + GXColor1u32(mColor4); + GXPosition2u16(texMaxX, texMaxY); + + // Top left + GXPosition3f32(posMinX, posMaxY, 0.0f); + GXColor1u32(mColor3); + GXPosition2u16(texMinX, texMaxY); + GXEnd(); + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + + return retval; +} + +void JUTResFont::loadFont(int chr, GXTexMapID id, JUTFont::TWidth *width) +{ + if (width) + { + getWidthEntry(chr, width); + } + int fontcode = getFontCode(chr); + loadImage(fontcode, id); +} + +void JUTResFont::getWidthEntry(int chr, JUTFont::TWidth *width) const +{ + int fontcode = getFontCode(chr); + width->w0 = 0; + width->w1 = mInfoBlock->mWidth; + + for (int i = 0; i < mWidthBlockCount; i++) + { + if (mWidthBlocks[i]->mStartCode <= fontcode && fontcode <= mWidthBlocks[i]->mEndCode) + { + *width = mWidthBlocks[i]->mChunkNum[(fontcode - mWidthBlocks[i]->mStartCode)]; + break; + } + } + return; +} + +int JUTResFont::getCellWidth() const +{ + ResFONT::GlyphBlock *glyph; + ResFONT::GlyphBlock **glyphs; + + glyphs = mGlyphBlocks; + if (glyphs) + { + glyph = *glyphs; + if (glyph) + { + return glyph->mCellWidth; + } + } + return getWidth(); +} + +int JUTResFont::getCellHeight() const +{ + ResFONT::GlyphBlock *glyph; + ResFONT::GlyphBlock **glyphs; + + glyphs = mGlyphBlocks; + if (glyphs) + { + glyph = *glyphs; + if (glyph) + { + return glyph->mCellHeight; + } + } + return getHeight(); +} + +bool JUTResFont::isLeadByte(int chr) const { return (*mIsLeadByte)(chr); } + +// regswaps +int JUTResFont::getFontCode(int chr) const +{ + static const u16 halftofull[95] = { + 0x8140, 0x8149, 0x8168, 0x8194, 0x8190, 0x8193, 0x8195, 0x8166, 0x8169, 0x816A, 0x8196, 0x817B, + 0x8143, 0x817C, 0x8144, 0x815E, 0x824F, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, + 0x8257, 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, 0x8184, 0x8148, 0x8197, 0x8260, 0x8261, 0x8262, + 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, 0x8269, 0x826A, 0x826B, 0x826C, 0x826D, 0x826E, + 0x826F, 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x816D, + 0x818F, 0x816E, 0x814F, 0x8151, 0x8165, 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, + 0x8288, 0x8289, 0x828A, 0x828B, 0x828C, 0x828D, 0x828E, 0x828F, 0x8290, 0x8291, 0x8292, 0x8293, + 0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, 0x829A, 0x816F, 0x8162, 0x8170, 0x8160, + }; + + int ret = mInfoBlock->mDefaultCode; + if ((getFontType() == 2) && (mMaxCode >= 0x8000U) && (chr >= 0x20) && (chr < 0x7FU)) + { + chr = halftofull[chr - 32]; + } + + for (int i = 0; i < mMapBlockCount; i++) + { + if ((mMapBlocks[i]->mStartCode <= chr) && (chr <= mMapBlocks[i]->mEndCode)) + { + if (mMapBlocks[i]->mMappingMethod == 0) + { + ret = chr - mMapBlocks[i]->mStartCode; + break; + } + else if (mMapBlocks[i]->mMappingMethod == 2) + { + ret = *(&mMapBlocks[i]->mLeading + ((chr - mMapBlocks[i]->mStartCode))); // type punning sin + break; + } + else if (mMapBlocks[i]->mMappingMethod == 3) + { + + u16 *leading_temp = &mMapBlocks[i]->mLeading; + int phi_r5 = 0; + int phi_r6_2 = mMapBlocks[i]->mNumEntries - 1; + + while (phi_r6_2 >= phi_r5) + { + int temp_r7 = (phi_r6_2 + phi_r5) / 2; + + if (chr < leading_temp[temp_r7 * 2]) + { + phi_r6_2 = temp_r7 - 1; + continue; + } + + if (chr > leading_temp[temp_r7 * 2]) + { + phi_r5 = temp_r7 + 1; + continue; + } + + ret = leading_temp[temp_r7 * 2 + 1]; // jank? possibly type punning fuckery + break; + } // loop closes here + } + else if (mMapBlocks[i]->mMappingMethod == 1) + { + u16 *phi_r5_2 = nullptr; + if (mMapBlocks[i]->mNumEntries == 1) + { + phi_r5_2 = &mMapBlocks[i]->mLeading; + } + ret = JUTResFont::convertSjis(chr, phi_r5_2); + break; + } + break; + } + } + return ret; +} + +void JUTResFont::loadImage(int code, GXTexMapID id) +{ + + int i = 0; + for (; i < mGlyphBlockCount; i++) + { + if (mGlyphBlocks[i]->mStartCode <= code && code <= mGlyphBlocks[i]->mEndCode) + { + code -= mGlyphBlocks[i]->mStartCode; + break; + } + } + + if (i == mGlyphBlockCount) + return; + + s32 pageNumCells = mGlyphBlocks[i]->mNumRows * mGlyphBlocks[i]->mNumColumns; + s32 pageIdx = code / pageNumCells; + s32 cellIdxInPage = code % pageNumCells; + s32 cellCol = (cellIdxInPage % mGlyphBlocks[i]->mNumRows); + s32 cellRow = (cellIdxInPage / mGlyphBlocks[i]->mNumRows); + mWidth = cellCol * mGlyphBlocks[i]->mCellWidth; + mHeight = cellRow * mGlyphBlocks[i]->mCellHeight; + + if (pageIdx != _44 || i != _66) + { + GXInitTexObj(&_24, &mGlyphBlocks[i]->mData[pageIdx * mGlyphBlocks[i]->mTextureSize], mGlyphBlocks[i]->mTextureWidth, + mGlyphBlocks[i]->mTextureHeight, (GXTexFmt)mGlyphBlocks[i]->mTextureFormat, GX_CLAMP, GX_CLAMP, 0); + + GXInitTexObjLOD(&_24, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0U, 0U, GX_ANISO_1); + _44 = pageIdx; + _66 = i; + } + + GXLoadTexObj(&_24, id); +} + +// probably needs some work to match TP(debug) +int JUTResFont::convertSjis(int inChr, u16 *inLead) const +{ + u8 hi = JSUHiByte(inChr); + u16 lead = JSULoByte(inChr); + int out = lead - 0x40; + if (0x40 <= out) + { + out--; + } + lead = 0x31c; + if(inLead) { + lead = *inLead; + } + return out + (hi - 0x88) * 0xbc + -0x5e + lead; +} diff --git a/src/static/JSystem/JUtility/JUTVideo.cpp b/src/static/JSystem/JUtility/JUTVideo.cpp new file mode 100644 index 00000000..b3a85747 --- /dev/null +++ b/src/static/JSystem/JUtility/JUTVideo.cpp @@ -0,0 +1,226 @@ +#include +#include "JSystem/JUtility/JUTDirectPrint.h" +#include "JSystem/JUtility/JUTVideo.h" +#include "JSystem/JUtility/JUTXfb.h" + +JUTVideo *JUTVideo::sManager; +OSTick JUTVideo::sVideoLastTick; +OSTick JUTVideo::sVideoInterval; + +bool sDrawWaiting; + +JUTVideo *JUTVideo::createManager(const GXRenderModeObj *renderModeObj) +{ + if (sManager == nullptr) + { + sManager = new JUTVideo(renderModeObj); + } + return sManager; +} + +void JUTVideo::destroyManager() +{ + if (sManager != nullptr) + { + delete sManager; + sManager = nullptr; + } +} + +JUTVideo::JUTVideo(const GXRenderModeObj *renderModeObj) +{ + mRenderModeObj = nullptr; + VIInit(); + setRenderMode(renderModeObj); + mIsSetBlack = true; + mSetBlackFrameCount = 2; + VISetBlack(TRUE); + VIFlush(); + _08 = 0; + mRetraceCount = VIGetRetraceCount(); + _10 = 1; + _18 = 0; + sVideoLastTick = OSGetTick(); + sVideoInterval = 670000; + mPreviousPreRetraceCallback = VISetPreRetraceCallback(preRetraceProc); + mPreviousPostRetraceCallback = VISetPostRetraceCallback(postRetraceProc); + mPreRetraceCallback = nullptr; + mPostRetraceCallback = nullptr; + OSInitMessageQueue(&mMessageQueue, &mMessage, 1); + GXSetDrawDoneCallback(drawDoneCallback); +} + +JUTVideo::~JUTVideo() +{ + VISetPreRetraceCallback(mPreviousPreRetraceCallback); + VISetPostRetraceCallback(mPreviousPostRetraceCallback); +} + +void JUTVideo::preRetraceProc(u32 retrace_count) +{ + if (sManager->mPreRetraceCallback) + { + (*sManager->mPreRetraceCallback)(retrace_count); + } + + OSTick tick = OSGetTick(); + sVideoInterval = OSDiffTick(tick, sVideoLastTick); + sVideoLastTick = tick; + + JUTXfb *xfb = JUTXfb::getManager(); + if (!xfb) + { + VISetBlack(TRUE); + VIFlush(); + return; + } + + static void *frameBuffer = nullptr; + + if (frameBuffer) + { + JUTVideo *videoManager = JUTGetVideoManager(); + const GXRenderModeObj *renderMode = videoManager->getRenderMode(); + JUTDirectPrint *directPrint = JUTDirectPrint::getManager(); + directPrint->changeFrameBuffer(frameBuffer, renderMode->fbWidth, renderMode->efbHeight); + } + + if (sManager->mIsSetBlack == 1) + { + s32 frame_count = sManager->mSetBlackFrameCount; + if (frame_count > 0) + { + frame_count--; + } + + sManager->mSetBlackFrameCount = frame_count; + sManager->mIsSetBlack = frame_count != 0 ? true : false; + VISetBlack(TRUE); + VIFlush(); + return; + } + + if (!xfb) + { + VISetBlack(TRUE); + VIFlush(); + return; + } + + if (xfb->getBufferNum() == 3 || xfb->getBufferNum() == 2) + { + if (!sDrawWaiting) + { + s16 index = xfb->getDrawnXfbIndex(); + xfb->setDisplayingXfbIndex(index); + if (index < 0) + { + VISetBlack(TRUE); + VIFlush(); + } + else + { + VISetBlack(FALSE); + VISetNextFrameBuffer(xfb->getDisplayingXfb()); + VIFlush(); + frameBuffer = xfb->getDisplayingXfb(); + } + } + } + else if (xfb->getBufferNum() == 1) + { + if (xfb->getSDrawingFlag() == 0) + { + s16 index = xfb->getDrawnXfbIndex(); + if (index >= 0) + { + xfb->setDisplayingXfbIndex(index); + GXCopyDisp(xfb->getDisplayingXfb(), GX_TRUE); + GXFlush(); + xfb->setSDrawingFlag(2); + frameBuffer = xfb->getDisplayingXfb(); + VISetBlack(FALSE); + + } + else + { + VISetBlack(TRUE); + } + } + VIFlush(); + } +} + +void JUTVideo::drawDoneStart() +{ + sDrawWaiting = true; + GXSetDrawDone(); +} + +void JUTVideo::dummyNoDrawWait() { sDrawWaiting = false; } + +void JUTVideo::drawDoneCallback() +{ + JUTXfb *xfb = JUTXfb::getManager(); + if (!xfb) + { + return; + } + + sDrawWaiting = false; + + if (xfb->getBufferNum() == JUTXfb::SingleBuffer && xfb->getSDrawingFlag() == 1) + { + xfb->setSDrawingFlag(0); + if (xfb->getDrawnXfb()) + { + VISetNextFrameBuffer(xfb->getDrawnXfb()); + VIFlush(); + } + } +} + +void JUTVideo::postRetraceProc(u32 p1) +{ + if (sManager->mPostRetraceCallback != nullptr) + { + sManager->mPostRetraceCallback(p1); + } + u32 retraceCount = VIGetRetraceCount(); + OSSendMessage(&sManager->mMessageQueue, (void *)retraceCount, OS_MESSAGE_NOBLOCK); +} + +void JUTVideo::setRenderMode(const GXRenderModeObj *newRenderModeObj) +{ + if (mRenderModeObj && newRenderModeObj->viTVmode != mRenderModeObj->viTVmode) + { + mIsSetBlack = true; + mSetBlackFrameCount = 4; + } + + mRenderModeObj = (GXRenderModeObj *)newRenderModeObj; + VIConfigure(mRenderModeObj); + VIFlush(); + + if (mIsSetBlack) + { + VIWaitForRetrace(); + VIWaitForRetrace(); + } +} + +void JUTVideo::waitRetraceIfNeed() {} + +VIRetraceCallback JUTVideo::setPreRetraceCallback(VIRetraceCallback newCB) +{ + VIRetraceCallback oldCB = mPreRetraceCallback; + mPreRetraceCallback = newCB; + return oldCB; +} + +VIRetraceCallback JUTVideo::setPostRetraceCallback(VIRetraceCallback newCB) +{ + VIRetraceCallback oldCB = mPostRetraceCallback; + mPostRetraceCallback = newCB; + return oldCB; +} \ No newline at end of file diff --git a/src/static/JSystem/JUtility/JUTXfb.cpp b/src/static/JSystem/JUtility/JUTXfb.cpp new file mode 100644 index 00000000..521ed13b --- /dev/null +++ b/src/static/JSystem/JUtility/JUTXfb.cpp @@ -0,0 +1,115 @@ +#include +#include +#include "JSystem/JUtility/JUTAssertion.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JUtility/JUTVideo.h" +#include "JSystem/JUtility/JUTXfb.h" + +JUTXfb *JUTXfb::sManager; + +void JUTXfb::clearIndex() +{ + mDrawingXfbIndex = -1; + mDrawnXfbIndex = -1; + mDisplayingXfbIndex = -1; +} + +void JUTXfb::common_init(int xfbNum) { + mBufferNum = xfbNum; + clearIndex(); + mSDrawingFlag = 99; +} + +JUTXfb::JUTXfb(const GXRenderModeObj *rmode, JKRHeap *heap, JUTXfb::EXfbNumber number) +{ + common_init(number); + + if (rmode) + { + initiate(rmode->fbWidth, rmode->xfbHeight, heap, number); + } + else + { + u16 efbWidth = JUTVideo::getManager()->getRenderMode()->fbWidth; + u16 xfbHeight = JUTVideo::getManager()->getRenderMode()->xfbHeight; + u16 efbHeight = JUTVideo::getManager()->getRenderMode()->efbHeight; + + initiate(efbWidth, xfbHeight, heap, number); + } +} + +JUTXfb::~JUTXfb() +{ + for (int i = 0; i < 3; i++) + { + delXfb(i); + } + sManager = nullptr; +} + +void JUTXfb::delXfb(int xfbIdx) +{ + if (mXfbAllocated[xfbIdx] && mBuffer[xfbIdx]) + { + delete mBuffer[xfbIdx]; + } +} + +JUTXfb *JUTXfb::createManager(const GXRenderModeObj* rmode, JKRHeap *heap, JUTXfb::EXfbNumber number) +{ + JUT_CONFIRM_MESSAGE(sManager == 0); + if (sManager == nullptr) + { + sManager = new JUTXfb(rmode, heap, number); + } + return sManager; +} + +void JUTXfb::destroyManager() +{ + JUT_CONFIRM_MESSAGE(sManager); + delete sManager; + sManager = nullptr; +} + +void JUTXfb::initiate(u16 w, u16 h, JKRHeap *heap, JUTXfb::EXfbNumber number) +{ + if (heap == nullptr) + { + heap = JKRGetSystemHeap(); + } + + u32 size = (u16)ALIGN_NEXT((u16)w, 16) * h; + + mBuffer[0] = new (heap, 32) u16[size]; + mXfbAllocated[0] = true; + if (number >= DoubleBuffer) + { + mBuffer[1] = new (heap, 32) u16[size]; + mXfbAllocated[1] = true; + } + else + { + mBuffer[1] = nullptr; + mXfbAllocated[1] = false; + } + + if (number >= TripleBuffer) + { + mBuffer[2] = new (heap, 32) u16[size]; + mXfbAllocated[2] = true; + } + else + { + mBuffer[2] = nullptr; + mXfbAllocated[2] = false; + } +} + +u32 JUTXfb::accumeXfbSize() +{ + JUTVideo *video = JUTVideo::getManager(); + u16 height = video->getXfbHeight(); + u16 width = video->getFbWidth(); + return (u16)ALIGN_NEXT(width, 16) * height * 2; +} diff --git a/src/static/dolphin/os/OSError.c b/src/static/dolphin/os/OSError.c index 183d4e44..3f07bf04 100644 --- a/src/static/dolphin/os/OSError.c +++ b/src/static/dolphin/os/OSError.c @@ -6,7 +6,7 @@ #include "dolphin/hw_regs.h" // #include "va_args.h" -OSErrorHandler __OSErrorTable[16]; +OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; extern volatile __OSInterrupt __OSLastInterrupt; extern volatile u32 __OSLastInterruptSrr0; diff --git a/src/static/dolphin/os/OSMemory.c b/src/static/dolphin/os/OSMemory.c index 0d961449..fe0af603 100644 --- a/src/static/dolphin/os/OSMemory.c +++ b/src/static/dolphin/os/OSMemory.c @@ -3,8 +3,6 @@ #include "dolphin/os/OSInterrupt.h" #include "dolphin/hw_regs.h" -extern OSErrorHandler __OSErrorTable[16]; - u32 OSGetConsoleSimulatedMemSize(void){ return(SIM_MEM); }