From 0ab7bf6cd969979d0b9648cb8b101f5d4dbdf963 Mon Sep 17 00:00:00 2001 From: SwareJonge <41187958+SwareJonge@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:07:08 +0200 Subject: [PATCH] Match JUTConsole --- configure.py | 4 +- include/JSystem/JGadget/linklist.h | 4 +- include/JSystem/JUtility/JUTConsole.h | 21 +- include/MSL_C/printf.h | 2 + src/static/JSystem/JFramework/JFWSystem.cpp | 2 +- src/static/JSystem/JUtility/JUTConsole.cpp | 574 ++++++++++++++++++++ 6 files changed, 595 insertions(+), 12 deletions(-) create mode 100644 src/static/JSystem/JUtility/JUTConsole.cpp diff --git a/configure.py b/configure.py index 4b04f89b..5bd9325e 100644 --- a/configure.py +++ b/configure.py @@ -619,7 +619,7 @@ config.libs = [ "JFramework", [ Object(Matching, "JSystem/JFramework/JFWDisplay.cpp"), - Object(NonMatching, "JSystem/JFramework/JFWSystem.cpp"), + Object(Matching, "JSystem/JFramework/JFWSystem.cpp"), ], ), JSystemLib( @@ -666,7 +666,7 @@ config.libs = [ "JUtility", [ Object(NonMatching, "JSystem/JUtility/JUTAssert.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTConsole.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"), diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index bb4622ff..7458f155 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -148,7 +148,7 @@ public: } } - s32 size() const { return this->size_; } + u32 size() const { return this->size_; } bool empty() const { return this->size() == 0; } void clear() { this->erase(this->begin(), this->end()); } iterator erase(iterator itStart, iterator itEnd); @@ -179,7 +179,7 @@ private: bool Iterator_isEnd_(const_iterator it) const { return it.p_ == &this->oNode_; } - s32 size_; + u32 size_; TLinkListNode oNode_; }; diff --git a/include/JSystem/JUtility/JUTConsole.h b/include/JSystem/JUtility/JUTConsole.h index dd710d4b..eabab006 100644 --- a/include/JSystem/JUtility/JUTConsole.h +++ b/include/JSystem/JUtility/JUTConsole.h @@ -13,7 +13,7 @@ inline s32 colorCheck(s32 diff, s32 t) return ret + 1; } -class JUTConsole : public JKRDisposer +class JUTConsole : JKRDisposer { public: enum EConsoleType @@ -101,12 +101,21 @@ public: return diff += mMaxLines; } + u8 getLineAttr(int i) const { + return mBuf[(_20 + 2) * i]; + } + + int prevIndex(int n) const { + return (--n < 0) ? mMaxLines - 1 : n; + + } + void scrollToLastLine() { scroll(mMaxLines); } void scrollToFirstLine() { scroll(-mMaxLines); } // _00 = VTBL // _00-_18 = JKRDisposer - JGadget::TLinkListNode mNode; // _18 + JGadget::TLinkListNode mNode; // _18 u32 _20; // _20 u32 mMaxLines; // _24, might be int u8 *mBuf; // _28 @@ -124,11 +133,9 @@ public: u32 mOutput; // _58 JUtility::TColor _5C; // _5C JUtility::TColor _60; // _60 - int _64; // _64 - bool mIsVisible; // _68 - bool _69; // _69 - bool _6A; // _6A - bool _6B; // _6B + bool mIsVisible; // _64 + bool _65; // _65 + bool _66; // _66 }; // Size: 0x6C class JUTConsoleManager diff --git a/include/MSL_C/printf.h b/include/MSL_C/printf.h index aa712edd..f8269cc1 100644 --- a/include/MSL_C/printf.h +++ b/include/MSL_C/printf.h @@ -10,6 +10,8 @@ extern "C" { #endif extern int vprintf(const char*, va_list); +extern int vsprintf(char*, const char*, va_list); +extern int vsnprintf(char*, size_t, const char*, va_list); extern int printf(const char*, ...); int snprintf(char* s, size_t n, const char* format, ...); diff --git a/src/static/JSystem/JFramework/JFWSystem.cpp b/src/static/JSystem/JFramework/JFWSystem.cpp index d96c1a3a..34b33d48 100644 --- a/src/static/JSystem/JFramework/JFWSystem.cpp +++ b/src/static/JSystem/JFramework/JFWSystem.cpp @@ -26,7 +26,7 @@ s32 JFWSystem::CSetUpParam::decompPriority = 7; s32 JFWSystem::CSetUpParam::aPiecePriority = 6; const ResFONT *JFWSystem::CSetUpParam::systemFontRes = &JUTResFONT_Ascfont_fix12; const _GXRenderModeObj *JFWSystem::CSetUpParam::renderMode = &GXNtsc480IntDf; -u32 JFWSystem::CSetUpParam::exConsoleBufferSize = 0x24FC; +u32 JFWSystem::CSetUpParam::exConsoleBufferSize = 0x24F8; JKRHeap *JFWSystem::rootHeap; JKRHeap *JFWSystem::systemHeap; diff --git a/src/static/JSystem/JUtility/JUTConsole.cpp b/src/static/JSystem/JUtility/JUTConsole.cpp new file mode 100644 index 00000000..ddcda5eb --- /dev/null +++ b/src/static/JSystem/JUtility/JUTConsole.cpp @@ -0,0 +1,574 @@ +#include + +#include +#include +#include "JSystem/J2D/J2DGrafContext.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JUtility/JUTConsole.h" +#include "JSystem/JUtility/JUTDirectPrint.h" +#include "JSystem/JUtility/JUTVideo.h" + +#define OUTPUT_NONE 0 +#define OUTPUT_CONSOLE 1 +#define OUTPUT_OSREPORT 2 +#define OUTPUT_ALL (OUTPUT_OSREPORT | OUTPUT_CONSOLE) + +JUTConsoleManager *JUTConsoleManager::sManager; + +JUTConsole *JUTConsole::create(uint param_0, uint maxLines, JKRHeap *pHeap) +{ + JUTConsoleManager *const pManager = JUTConsoleManager::getManager(); + JUT_ASSERT(pManager != 0); + + u8 *buffer = (u8*)JKRAllocFromHeap(pHeap, getObjectSizeFromBufferSize(param_0, maxLines), 0); + + JUTConsole *newConsole = new (buffer) JUTConsole(param_0, maxLines, true); + newConsole->mBuf = buffer + sizeof(JUTConsole); + newConsole->clear(); + + pManager->appendConsole(newConsole); + return newConsole; +} + +JUTConsole *JUTConsole::create(uint param_0, void *buffer, u32 bufferSize) +{ + JUTConsoleManager *const pManager = JUTConsoleManager::getManager(); + JUT_ASSERT(pManager != 0); + JUT_ASSERT(( (u32)buffer & 0x3 ) == 0); + u32 maxLines = getLineFromObjectSize(bufferSize, param_0); + + JUTConsole *newConsole = new (buffer) JUTConsole(param_0, maxLines, false); + newConsole->mBuf = (u8 *)buffer + sizeof(JUTConsole); + newConsole->clear(); + + pManager->appendConsole(newConsole); + return newConsole; +} + +// unused +void JUTConsole::destroy(JUTConsole *console) { + JUT_ASSERT(console != 0); + delete console; +} + +JUTConsole::JUTConsole(uint p1, uint maxLines, bool p3) +{ + _2C = p3; + _20 = p1; + mMaxLines = maxLines; + + mPositionX = 30; + mPositionY = 50; + mHeight = 20; + + if (mHeight > mMaxLines) + { + mHeight = mMaxLines; + } + + mFont = nullptr; + mIsVisible = true; + _65 = false; + _66 = false; + mOutput = 1; + + _5C = JUtility::TColor(0, 0, 0, 100); + _60 = JUtility::TColor(0, 0, 0, 230); +} + +JUTConsole::~JUTConsole() { + JUT_ASSERT(JUTConsoleManager::getManager()) + JUTConsoleManager::getManager()->removeConsole(this); +} + +size_t JUTConsole::getObjectSizeFromBufferSize(unsigned int p1, unsigned int maxLines) +{ + int objSize = (p1 + 2) * maxLines + sizeof(JUTConsole); + return objSize; +} + +size_t JUTConsole::getLineFromObjectSize(u32 bufferSize, unsigned int param_1) +{ + bufferSize -= sizeof(JUTConsole); + int line = (bufferSize) / (param_1 + 2); + return line; +} + +void JUTConsole::clear() +{ + _30 = 0; + _34 = 0; + _38 = 0; + _3C = 0; + + for (int i = 0; i < mMaxLines; i++) + { + setLineAttr(i, 0); + } + setLineAttr(0, -1); + *getLinePtr(0) = 0; +} + +void JUTConsole::doDraw(JUTConsole::EConsoleType consoleType) const +{ + f32 font_yOffset; + s32 changeLine_1; + s32 changeLine_2; + + if (mIsVisible && (mFont || consoleType == CONSOLE_TYPE_2)) + { + if (mHeight != 0) + { + bool isConsoleType0 = consoleType == CONSOLE_TYPE_0 ? true : false; + font_yOffset = 2.0f + mFontSizeY; + + if (consoleType != CONSOLE_TYPE_2) + { + if (!JUTVideo::getManager()) + { + J2DOrthoGraph ortho(0.0f, 0.0f, 640.0f, 480.0f, -1.0f, 1.0f); + ortho.setPort(); + } + else + { + f32 w = JUTVideo::getManager()->getFbWidth(); + f32 h = JUTVideo::getManager()->getEfbHeight(); + J2DOrthoGraph ortho(0.0f, 0.0f, w, h, -1.0f, 1.0f); + ortho.setPort(); + } + + const JUtility::TColor *color; + if (isConsoleType0) + { + color = &_60; + } + else + { + color = &_5C; + } + + J2DFillBox(mPositionX - 2, (int)(mPositionY - font_yOffset), + (int)((mFontSizeX * _20) + 4.0f), (int)(font_yOffset * mHeight), + *color); + mFont->setGX(); + + if (isConsoleType0) + { + s32 s = (diffIndex(_30, _38) - mHeight) + 1; + if (s <= 0) + { + mFont->setCharColor(JUtility::TColor(255, 255, 255, 255)); + } + else if (_30 == _34) + { + mFont->setCharColor(JUtility::TColor(255, 230, 230, 255)); + } + else + { + mFont->setCharColor(JUtility::TColor(230, 230, 255, 255)); + } + } + else + { + mFont->setCharColor(JUtility::TColor(230, 230, 230, 255)); + } + } + else + { + JUTDirectPrint::getManager()->erase(mPositionX - 3, mPositionY - 2, + (_20 * 6) + 6, + (int)(font_yOffset * mHeight) + 4); + } + + char *linePtr; + s32 curLine = _30; + s32 yFactor = 0; + + do + { + linePtr = (char *)getLinePtr(curLine); + + if ((u8)linePtr[-1] != 0) + { + if (consoleType != CONSOLE_TYPE_2) + { + mFont->drawString_scale(mPositionX, ((yFactor * font_yOffset) + mPositionY), + mFontSizeX, mFontSizeY, linePtr, true); + } + else + { + JUTDirectPrint::getManager()->drawString( + mPositionX, ((yFactor * font_yOffset) + mPositionY), linePtr); + } + + changeLine_1 = curLine + 1; + changeLine_2 = ((((s32)changeLine_1 )>= (s32)mMaxLines)) ? 0 : changeLine_1; + yFactor += 1; + curLine = changeLine_2; + } + else + { + break; + } + } while (yFactor < mHeight && changeLine_2 != _34); + } + } +} + +void JUTConsole::print_f(char const *text, ...) +{ + va_list args; + va_start(args, text); + JUTConsole_print_f_va_(this, text, args); + va_end(args); +} + +void JUTConsole::print(char const *param_0) +{ + if (mOutput & OUTPUT_OSREPORT) + { + //JUT_REPORT_MSG("%s", param_0); + } + if (mOutput & OUTPUT_CONSOLE) + { + const u8 *r29 = (const u8 *)param_0; + u8 *r28 = getLinePtr(_38) + _3C; + while (*r29 != 0) + { + if (_66 && _34 == nextIndex(_38)) + { + break; + } + if (*r29 == '\n') + { + r29++; + _3C = _20; + } + else if (*r29 == '\t') + { + r29++; + while (_3C < _20) + { + *(r28++) = ' '; + _3C++; + if (_3C % 8 == 0) + { + break; + } + } + } + else if (mFont && mFont->isLeadByte(*r29)) + { + if (_3C + 1 < _20) + { + *(r28++) = *(r29++); + *(r28++) = *(r29++); + _3C++; + _3C++; + } + else + { + *(r28++) = 0; + _3C++; + } + } + else + { + *(r28++) = *(r29++); + _3C++; + } + if (_3C < _20) + { + continue; + } + *r28 = 0; + _38 = nextIndex(_38); + _3C = 0; + setLineAttr(_38, 0xff); + r28 = getLinePtr(_38); + *r28 = 0; + int local_28 = diffIndex(_30, _38); + if (local_28 == mHeight) + { + _30 = nextIndex(_30); + } + if (_38 == _34) + { + _34 = nextIndex(_34); + } + if (_38 == _30) + { + _30 = nextIndex(_30); + } + + } + *r28 = 0; + } +} + +void JUTConsole_print_f_va_(JUTConsole *console, const char *text, va_list args) +{ + char buf[1024]; + JUT_ASSERT(console!=0); + vsnprintf(buf, sizeof(buf), text, args); + console->print(buf); +} + +void JUTConsole::dumpToTerminal(unsigned int n) { + if (n == 0) { + return; + } + + int lineNo = _34; + if (n != 0xffffffff) { + lineNo = _38; + while (n--) { + int prevIdx = prevIndex(lineNo); + if (!getLineAttr(prevIdx)) { + break; + } + lineNo = prevIdx; + if (prevIdx == _34) { + break; + } + } + } + //OSReport("\n:::dump of console[%x]--------------------------------\n", this); + int i = 0; + do { + u8* line = getLinePtr(lineNo); + if ((u8)line[-1] == 0) { + break; + } + if (_65) { + OSReport("[%03d] %s\n",i, line); + } + else { + OSReport("%s\n", line); + } + lineNo = nextIndex(lineNo); + i++; + } while (lineNo != _34); + + //OSReport(":::dump of console[%x] END----------------------------\n", this); +} + +void JUTConsole::scroll(int scrollAmnt) +{ + if (scrollAmnt < 0) + { + int diff = diffIndex(_34, _30); + if (scrollAmnt < -diff) + { + scrollAmnt = -diff; + } + } + else + { + if (scrollAmnt > 0) + { + if (diffIndex(_34, _38) + 1 <= mHeight) + { + scrollAmnt = 0; + } + else + { + int diff = diffIndex(_30, _38) - mHeight + 1; + if (scrollAmnt > diff) + { + scrollAmnt = diff; + } + } + } + } + + _30 += scrollAmnt; + if (_30 < 0) + { + _30 += mMaxLines; + } + + if (_30 >= mMaxLines) + { + _30 -= mMaxLines; + } +} + +int JUTConsole::getUsedLine() const +{ + int usedLine = diffIndex(_34, _38); + return usedLine; +} + +int JUTConsole::getLineOffset() const +{ + int offset = diffIndex(_34, _30); + return offset; +} + +JUTConsoleManager::JUTConsoleManager() +{ + mActiveConsole = nullptr; + mDirectConsole = nullptr; +} + +JUTConsoleManager *JUTConsoleManager::createManager(JKRHeap *pHeap) +{ + JUT_ASSERT(sManager == 0); + if (pHeap == nullptr) + { + pHeap = JKRGetCurrentHeap(); + } + sManager = new (pHeap, 0) JUTConsoleManager(); + return sManager; +} + +void JUTConsoleManager::appendConsole(JUTConsole *const console) +{ + JUT_ASSERT(sManager != 0 && console != 0); + + // not sure why this assert was 3 lines later + JUT_ASSERT(soLink_.Find( console ) == soLink_.end()); + soLink_.Push_back(console); + if (mActiveConsole == nullptr) + { + mActiveConsole = console; + } +} + +void JUTConsoleManager::removeConsole(JUTConsole *const console) +{ + JUT_ASSERT(sManager != 0 && console != 0); + JUT_ASSERT(soLink_.Find( console ) != soLink_.end()); + + if (mActiveConsole == console) + { + if(soLink_.size() <= 1) { + mActiveConsole = nullptr; + } + else { + mActiveConsole = console != &soLink_.back() ? soLink_.Element_toValue(console->mNode.getNext()) : &soLink_.front(); + } + } + if (JUTGetWarningConsole() == console) + JUTSetWarningConsole(nullptr); + if (JUTGetReportConsole() == console) + JUTSetReportConsole(nullptr); + + soLink_.Remove(console); +} + +void JUTConsoleManager::draw() const +{ + // this cast is needed to match release, luckily doesn't affect tp debug either, so maybe there's another temp or cast somewhere? + JGadget::TLinkList::const_iterator it = ((const JUTConsoleManager *)this)->soLink_.begin(); + JGadget::TLinkList::const_iterator itEnd = soLink_.end(); + + for (; it != itEnd; ++it) + { + const JUTConsole &console = *it; + if (&console != mActiveConsole) + { + console.doDraw(JUTConsole::CONSOLE_TYPE_1); + } + } + + if (mActiveConsole) + mActiveConsole->doDraw(JUTConsole::CONSOLE_TYPE_0); +} + + +void JUTConsoleManager::drawDirect(bool waitRetrace) const { + if(mDirectConsole) { + if(waitRetrace) { + BOOL interrupt = OSEnableInterrupts(); + u32 retrace_count = VIGetRetraceCount(); + do + { + } while (retrace_count == VIGetRetraceCount()); + OSRestoreInterrupts(interrupt); + } + mDirectConsole->doDraw(JUTConsole::CONSOLE_TYPE_2); + } +} + +void JUTConsoleManager::setDirectConsole(JUTConsole *console) { + if (mDirectConsole != nullptr) { + appendConsole(mDirectConsole); + } + if(console != nullptr) { + removeConsole(console); + } + mDirectConsole = console; +} + +static JUTConsole *sReportConsole; +static JUTConsole *sWarningConsole; + +// C Functions +void JUTSetReportConsole(JUTConsole *console) { + sReportConsole = console; +} + +JUTConsole *JUTGetReportConsole() { + return sReportConsole; +} + +void JUTSetWarningConsole(JUTConsole *console) { + sWarningConsole = console; +} + +JUTConsole *JUTGetWarningConsole() { + return sWarningConsole; +} + +void JUTReportConsole_f_va(const char *text, va_list args) { + char buf[256]; + if(!JUTGetReportConsole()) { + vsnprintf(buf, sizeof(buf), text, args); + //JUT_REPORT_MSG("%s", buf); + } + else if (JUTGetReportConsole()->getOutput() & OUTPUT_ALL) { + vsnprintf(buf, sizeof(buf), text, args); + JUTGetReportConsole()->print(buf); + } +} + +void JUTReportConsole_f(const char *text, ...) +{ + va_list vl; + va_start(vl, text); + JUTReportConsole_f_va(text, vl); + va_end(vl); +} + +void JUTReportConsole(const char *text) { + JUTReportConsole_f("%s", text); +} + +void JUTWarningConsole_f_va(const char *text, va_list args) +{ + char buf[256]; + if (!JUTGetWarningConsole()) + { + vsnprintf(buf, sizeof(buf), text, args); + OSReport("%s", buf); + } + else if (JUTGetWarningConsole()->getOutput() & OUTPUT_ALL) + { + vsnprintf(buf, sizeof(buf), text, args); + JUTGetWarningConsole()->print(buf); + } +} + +void JUTWarningConsole_f(const char *text, ...) +{ + va_list vl; + va_start(vl, text); + JUTReportConsole_f_va(text, vl); + va_end(vl); +} + +void JUTWarningConsole(const char *text) { + JUTReportConsole_f("%s", text); +} \ No newline at end of file