Reorganize library code into libs/ (#3119)

* Reorganize files into libs/{dolphin,JSystem,PowerPC_EABI_Support,revolution,TRK_MINNOW_DOLPHIN}

* Update configure.py and project.py for new libs structure

* Refactor `#include <dolphin/x.h>` -> `<x.h>`

* Remove `__REVOLUTION_SDK__` forwards from dolphin

* Fix dolphin/ references in revolution

* Wrap `#include <dolphin.h>` in `!__REVOLUTION_SDK__`

* Always build TRK against dolphin headers

* Resolve revolution SDK header resolution issues
This commit is contained in:
Luke Street
2026-03-01 15:35:36 -07:00
committed by GitHub
parent c9a46bd65b
commit 4df8ccc871
1740 changed files with 583 additions and 825 deletions
+212
View File
@@ -0,0 +1,212 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTDbPrint.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
#include <cstdio>
#include <vi.h>
namespace JUTAssertion {
void create() {}
namespace {
static u32 sMessageLife;
static char sMessageFileLine[64];
static char sMessageString[256];
static s32 sDisplayTime = -1;
static s32 sDevice = 3;
static bool mVisible = true;
static s32 sMessageOwner;
static u8 mSynchro;
}; // namespace
u32 flush_subroutine() {
if (sMessageLife == 0) {
return 0;
}
if (sMessageLife != -1) {
sMessageLife--;
}
if (sMessageLife < 5) {
return 0;
}
return sMessageLife;
}
void flushMessage() {
if (flush_subroutine() && mVisible == true) {
JUTDirectPrint* manager = JUTDirectPrint::getManager();
JUtility::TColor color = manager->getCharColor();
manager->setCharColor(JUtility::TColor(255, 200, 200, 255));
manager->drawString(16, 16, sMessageFileLine);
manager->drawString(16, 24, sMessageString);
manager->setCharColor(color);
}
}
void flushMessage_dbPrint() {
if (flush_subroutine() && mVisible == true && JUTDbPrint::getManager() != NULL) {
JUTFont* font = JUTDbPrint::getManager()->getFont();
if (font != NULL) {
u8 tmp = ((VIGetRetraceCount() & 0x3C) << 2) | 0xF;
font->setGX();
font->setCharColor(JUtility::TColor(255, tmp, tmp, 255));
font->drawString(30, 36, sMessageFileLine, true);
font->drawString(30, 54, sMessageString, true);
}
}
}
u32 getSDevice() {
return sDevice;
}
void setConfirmMessage(u32 param_1, char* file, int line, bool param_4, const char* msg) {
if (param_4 == 1) {
return;
}
int r30 = 0;
u32 r28 = sMessageLife;
if (r28 == 0 && (param_1 & 1) != 0) {
sMessageLife = sDisplayTime;
sMessageOwner = 2;
snprintf(sMessageFileLine, sizeof(sMessageFileLine) - 1, "FAILED [%s:%d]", file, line);
snprintf(sMessageString, sizeof(sMessageString) - 1, "%s", msg);
}
if ((r28 == 0 || mSynchro == 0) && (param_1 & 2) != 0) {
JUTWarningConsole_f("FAILED [%s:%d] %s\n", file, line, msg);
}
}
void showAssert_f_va(u32 device, const char* file, int line, const char* msg, va_list args) {
sMessageLife = -1;
vsnprintf(sMessageString, 255, msg, args);
if (device & 2) {
OSReport("Failed assertion: %s:%d\n", file, line);
OSReport("%s\n", sMessageString);
}
if ((device & 1)) {
JUTDirectPrint* directPrint = JUTDirectPrint::getManager();
if (directPrint) {
JUtility::TColor old_color(directPrint->getCharColor());
directPrint->setCharColor(JUtility::TColor(255, 255, 255, 255));
directPrint->erase(10, 16, 306, 24);
snprintf(sMessageFileLine, 63, "Failed assertion: %s:%d", file, line);
directPrint->drawString(16, 16, sMessageFileLine);
directPrint->drawString(16, 24, sMessageString);
directPrint->setCharColor(old_color);
VISetNextFrameBuffer(directPrint->getFrameBuffer());
VIFlush();
OSEnableInterrupts();
u32 retrace_count = VIGetRetraceCount();
while (retrace_count == VIGetRetraceCount()){
// nop
}
// busy loop for 2 seconds
OSTime var1 = OSGetTime();
while (OSTicksToMilliseconds(OSGetTime() - var1) < 2000) {
}
}
}
}
void showAssert_f(u32 device, const char* file, int line, const char* msg, ...) {
UNUSED(msg);
va_list args;
va_start(args, msg);
showAssert_f_va(device, file, line, msg, args);
va_end(args);
}
void setWarningMessage_f_va(u32 device, const char* file, int line, const char* msg, va_list args) {
u32 messageLife = sMessageLife;
bool r26 = false;
if (messageLife == 0) {
if (device & 1) {
sMessageLife = sDisplayTime;
sMessageOwner = 3;
snprintf(sMessageFileLine, sizeof(sMessageFileLine) - 1, "WARNING [%s:%d]", file, line);
}
vsnprintf(sMessageString, sizeof(sMessageString) - 1, msg, args);
r26 = true;
}
if ((messageLife == 0 || mSynchro == 0) && (device & 2)) {
JUTWarningConsole_f("WARNING [%s:%d] ", file, line);
if (!r26) {
JUTWarningConsole_f_va(msg, args);
} else {
JUTWarningConsole(sMessageString);
}
JUTWarningConsole("\n");
}
}
void setWarningMessage_f(u32 device, char* file, int line, const char* msg, ...) {
UNUSED(msg);
va_list args;
va_start(args, msg);
setWarningMessage_f_va(device, file, line, msg, args);
va_end(args);
}
void setLogMessage_f_va(u32 device, const char* file, int line, const char* msg, va_list args) {
u32 messageLife = sMessageLife;
bool r26 = false;
if (messageLife == 0) {
if (device & 1) {
sMessageLife = sDisplayTime;
sMessageOwner = 4;
snprintf(sMessageFileLine, sizeof(sMessageFileLine) - 1, "[%s:%d]", file, line);
}
vsnprintf(sMessageString, sizeof(sMessageString) - 1, msg, args);
r26 = true;
}
if ((messageLife == 0 || mSynchro == 0) && (device & 2)) {
JUTReportConsole_f("[%s:%d] ", file, line);
if (!r26) {
JUTReportConsole_f_va(msg, args);
} else {
JUTReportConsole(sMessageString);
}
JUTReportConsole("\n");
}
}
void setLogMessage_f(u32 device, char* file, int line, const char* msg, ...) {
UNUSED(msg);
va_list args;
va_start(args, msg);
setLogMessage_f_va(device, file, line, msg, args);
va_end(args);
}
void setVisible(bool visible) {
mVisible = visible;
}
void setMessageCount(int msg_count) {
if (msg_count <= 0) {
sMessageLife = 0;
} else {
sMessageLife = msg_count;
}
}
}; // namespace JUTAssertion
+485
View File
@@ -0,0 +1,485 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTCacheFont.h"
#include "JSystem/JUtility/JUTException.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JKernel/JKRAram.h"
#include <gx.h>
#include <stdint.h>
#include <cstring>
#include "angle_utils.h"
JUTCacheFont::JUTCacheFont(ResFONT const* p_fontRes, u32 cacheSize, JKRHeap* p_heap) {
initialize_state();
JUTResFont::initialize_state();
JUTFont::initialize_state();
initiate(p_fontRes, NULL, cacheSize, p_heap);
}
JUTCacheFont::~JUTCacheFont() {
if (mValid) {
delete_and_initialize();
JUTResFont::delete_and_initialize();
JUTFont::initialize_state();
}
}
void JUTCacheFont::deleteMemBlocks_CacheFont() {
if (field_0xb0 != 0) {
delete[] mCacheBuffer;
}
JKRFreeToAram(field_0xac);
delete mInf1Ptr;
delete mMemBlocks;
delete field_0x7c;
delete field_0x80;
delete field_0x84;
}
void JUTCacheFont::initialize_state() {
field_0xb0 = 0;
mCacheBuffer = NULL;
field_0xac = NULL;
mInf1Ptr = NULL;
field_0x7c = NULL;
field_0x80 = NULL;
field_0x84 = NULL;
mMemBlocks = NULL;
mPagingType = PAGE_TYPE_0;
mMaxSheetSize = 0;
mCacheBuffer = NULL;
field_0x9c = NULL;
field_0xa0 = NULL;
}
int JUTCacheFont::getMemorySize(ResFONT const* p_font, u16* o_widCount, u32* o_widSize,
u16* o_glyCount, u32* o_glySize, u16* o_mapCount, u32* o_mapSize,
u32* o_glyTexSize) {
if (p_font == NULL) {
return 0;
}
u16 widBlockCount = 0;
u16 glyBlockCount = 0;
u16 mapBlockCount = 0;
u32 totalWidSize = 0;
u32 totalGlySize = 0;
u32 totalMapSize = 0;
u32 maxGlyTexSize = 0;
u8* fontInf = (u8*)p_font->data;
for (int i = 0; i < p_font->numBlocks; i++) {
switch (((BlockHeader*)fontInf)->magic) {
case 'INF1':
break;
case 'WID1':
totalWidSize += ((BlockHeader*)fontInf)->size;
widBlockCount++;
break;
case 'GLY1':
totalGlySize += ((BlockHeader*)fontInf)->size;
glyBlockCount++;
if (((ResFONT::GLY1*)fontInf)->textureSize > maxGlyTexSize) {
maxGlyTexSize = ((ResFONT::GLY1*)fontInf)->textureSize;
}
break;
case 'MAP1':
totalMapSize += ((BlockHeader*)fontInf)->size;
mapBlockCount++;
break;
default:
JUTReportConsole("JUTCacheFont: Unknown data block\n");
break;
}
fontInf += ((BlockHeader*)fontInf)->size;
}
if (o_widCount != NULL) {
*o_widCount = widBlockCount;
}
if (o_glyCount != NULL) {
*o_glyCount = glyBlockCount;
}
if (o_mapCount != NULL) {
*o_mapCount = mapBlockCount;
}
if (o_widSize != NULL) {
*o_widSize = totalWidSize;
}
if (o_glySize != NULL) {
*o_glySize = totalGlySize;
}
if (o_mapSize != NULL) {
*o_mapSize = totalMapSize;
}
if (o_glyTexSize != NULL) {
*o_glyTexSize = maxGlyTexSize;
}
return 1;
}
int JUTCacheFont::initiate(ResFONT const* p_fontRes, void* param_1, u32 param_2, JKRHeap* p_heap) {
if (!internal_initiate(p_fontRes, param_1, param_2, p_heap)) {
deleteMemBlocks_CacheFont();
deleteMemBlocks_ResFont();
JUTFont::initialize_state();
mValid = false;
return 0;
}
return 1;
}
bool JUTCacheFont::internal_initiate(ResFONT const* p_fontRes, void* param_1, u32 param_2,
JKRHeap* param_3) {
delete_and_initialize();
JUTResFont::delete_and_initialize();
JUTFont::initialize_state();
if (p_fontRes == NULL) {
return false;
}
mResFont = p_fontRes;
mValid = true;
getMemorySize(p_fontRes, &mWid1BlockNum, &mTotalWidSize, &mGly1BlockNum, &mTotalGlySize,
&mMap1BlockNum, &mTotalMapSize, &mMaxSheetSize);
if (!allocArea(param_1, param_2, param_3)) {
return false;
} else if (!allocArray(param_3)) {
return false;
}
setBlock();
return true;
}
bool JUTCacheFont::allocArea(void* cacheBuffer, u32 param_1, JKRHeap* heap) {
mInf1Ptr = (ResFONT::INF1*)new (heap, 0) ResFONT();
if (mInf1Ptr == NULL) {
return false;
}
if (mTotalWidSize != 0) {
field_0x7c = new (heap, 0) u8[mTotalWidSize];
if (field_0x7c == NULL) {
return false;
}
}
if (mGly1BlockNum != 0) {
field_0x80 = new (heap, 0) u8[mGly1BlockNum * sizeof(ResFONT::GLY1)];
if (field_0x80 == NULL) {
return false;
}
field_0xac = JKRAllocFromAram(mTotalGlySize - (mGly1BlockNum * sizeof(ResFONT::GLY1)), JKRAramHeap::HEAD);
if (field_0xac == NULL) {
return false;
}
}
if (mTotalMapSize != 0) {
field_0x84 = new (heap, 0) u8[mTotalMapSize];
if (field_0x84 == NULL) {
return false;
}
}
field_0x94 = mMaxSheetSize + 0x40;
mCachePage = param_1 / field_0x94;
u32 v1 = field_0x94 * mCachePage;
if (mCachePage == 0) {
return false;
}
if (cacheBuffer != NULL) {
JUT_ASSERT(352, ( (u32)cacheBuffer & 0x1f ) == 0);
mCacheBuffer = cacheBuffer;
field_0xb0 = 0;
} else {
mCacheBuffer = new (heap, 0x20) u8[v1];
if (mCacheBuffer == NULL) {
return false;
}
field_0xb0 = 1;
}
invalidiateAllCache();
return true;
}
bool JUTCacheFont::allocArray(JKRHeap* param_0) {
mMemBlocks = (void**)new (param_0, 0) u32[mWid1BlockNum + mGly1BlockNum + mMap1BlockNum];
if (mMemBlocks == NULL) {
return false;
}
void** blocks = mMemBlocks;
if (mWid1BlockNum) {
mpWidthBlocks = new (blocks) ResFONT::WID1*[mWid1BlockNum];
blocks = blocks + mWid1BlockNum;
}
if (mGly1BlockNum) {
mpGlyphBlocks = new (blocks) ResFONT::GLY1*[mGly1BlockNum];
blocks = blocks + mGly1BlockNum;
for (int i = 0; i < mGly1BlockNum; i++) {
mpGlyphBlocks[i] = (ResFONT::GLY1*)((u8*)mCacheBuffer + (field_0x94 * i));
}
}
if (mMap1BlockNum) {
mpMapBlocks = new (blocks) ResFONT::MAP1*[mMap1BlockNum];
}
return true;
}
void JUTCacheFont::setBlock() {
int widthNum = 0;
int gylphNum = 0;
int mapNum = 0;
u8* pWidth = (u8*)field_0x7c;
ResFONT::GLY1* piVar5 = (ResFONT::GLY1*)field_0x80;
ResFONT::MAP1* pMap = (ResFONT::MAP1*)field_0x84;
u32 aramAddress = field_0xac->getAddress();
mMaxCode = 0xffff;
const int* pData = (int*)mResFont->data;
for (int i = 0; i < mResFont->numBlocks; i++) {
u32 u;
switch (*pData) {
case 'INF1':
memcpy(mInf1Ptr, pData, 0x20);
u = mInf1Ptr->fontType;
JUT_ASSERT(448, u < suAboutEncoding_);
mIsLeadByte = &JUTResFont::saoAboutEncoding_[u];
break;
case 'WID1':
memcpy(pWidth, pData, pData[1]);
mpWidthBlocks[widthNum] = (ResFONT::WID1*)pWidth;
widthNum++;
pWidth += pData[1];
break;
case 'GLY1':
memcpy(piVar5, pData, 0x20);
JKRAramBlock* iVar1;
iVar1 = JKRMainRamToAram((u8*)pData + 0x20, aramAddress, pData[1] - 0x20,
EXPAND_SWITCH_UNKNOWN0, 0, NULL, 0xffffffff, NULL);
if (iVar1 == NULL) {
JUTException::panic("JUTCacheFont.cpp", 0x1dd,
"trouble occurred in JKRMainRamToAram.");
}
piVar5->magic = aramAddress;
if (piVar5->textureSize > mMaxSheetSize) {
mMaxSheetSize = piVar5->textureSize;
}
mpGlyphBlocks[gylphNum] = piVar5;
gylphNum++;
piVar5++;
aramAddress += pData[1] - 0x20;
break;
case 'MAP1':
memcpy(pMap, pData, pData[1]);
mpMapBlocks[mapNum] = pMap;
if (mMaxCode > mpMapBlocks[mapNum]->startCode) {
mMaxCode = mpMapBlocks[mapNum]->startCode;
}
mapNum++;
pMap = (ResFONT::MAP1*)((u8*)pMap + pData[1]);
break;
default:
JUTReportConsole("Unknown data block\n");
break;
}
pData = (int*)((u8*)pData + pData[1]);
}
}
JUTCacheFont::TGlyphCacheInfo* JUTCacheFont::determineBlankPage() {
TGlyphCacheInfo* pVar1;
if (field_0xa4 != NULL) {
pVar1 = field_0xa4;
field_0xa4 = pVar1->mNext;
if (pVar1->mNext == NULL) {
field_0xa8 = 0;
} else {
pVar1->mNext->mPrev = NULL;
}
return pVar1;
}
pVar1 = field_0xa0;
while (pVar1 != NULL) {
TGlyphCacheInfo* prev = pVar1->mPrev;
if (pVar1->field_0x1e == 0) {
unlink(pVar1);
field_0xb4++;
return pVar1;
}
pVar1 = prev;
}
return NULL;
}
void JUTCacheFont::getGlyphFromAram(JUTCacheFont::TGlyphCacheInfo* param_0,
JUTCacheFont::TCachePage* pCachePage, int* param_2, int* param_3) {
TGlyphCacheInfo* pGylphCacheInfo = pCachePage;
int* r30 = param_2;
memcpy(pGylphCacheInfo, param_0, sizeof(TGlyphCacheInfo));
prepend(pGylphCacheInfo);
int iVar3 = pGylphCacheInfo->field_0x16 * pGylphCacheInfo->field_0x18;
int iVar2 = *r30 / iVar3;
U16_ADD_2(pGylphCacheInfo->field_0x8, iVar2 * iVar3);
u16 local_30 = pGylphCacheInfo->field_0x8 + iVar3 - 1;
pGylphCacheInfo->field_0xa = pGylphCacheInfo->field_0xa < local_30 ? pGylphCacheInfo->field_0xa : local_30;
*param_3 = iVar2;
*r30 -= iVar2 * iVar3;
u8* result =
JKRAramToMainRam((u32)param_0->mPrev + pGylphCacheInfo->field_0x10 * iVar2, pCachePage->mImage,
pGylphCacheInfo->field_0x10, EXPAND_SWITCH_UNKNOWN0, 0, NULL, 0xffffffff, NULL);
JUT_ASSERT(624, result);
GXInitTexObj(&pCachePage->mTexObj, pCachePage->mImage, pGylphCacheInfo->mWidth, pGylphCacheInfo->mHeight,
(GXTexFmt)pGylphCacheInfo->mTexFormat, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXInitTexObjLOD(&pCachePage->mTexObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE,
GX_ANISO_1);
}
void JUTCacheFont::loadImage(int param_0, _GXTexMapID texMapId) {
TCachePage* cachePage = loadCache_char_subroutine(&param_0, false);
if (cachePage != NULL) {
mWidth = cachePage->field_0xc * (param_0 % (int)cachePage->field_0x16);
mHeight = cachePage->field_0xe * (param_0 / cachePage->field_0x16);
GXLoadTexObj(getTexObj(cachePage), texMapId);
if (mPagingType == PAGE_TYPE_1) {
unlink(cachePage);
prepend(cachePage);
}
}
}
JUTCacheFont::TCachePage* JUTCacheFont::loadCache_char_subroutine(int* param_0, bool param_1) {
TCachePage* rv = NULL;
int* r29 = param_0;
for (TCachePage* pCachePage = (TCachePage*)field_0x9c; pCachePage != NULL;
pCachePage = (TCachePage*)pCachePage->mNext)
{
if (pCachePage->field_0x8 <= *r29 && *r29 <= pCachePage->field_0xa) {
rv = pCachePage;
*r29 -= pCachePage->field_0x8;
break;
}
}
if (rv == NULL) {
rv = NULL;
int i = 0;
for (; i < mGly1BlockNum; i++) {
if (mpGlyphBlocks[i]->startCode <= *r29 && *r29 <= mpGlyphBlocks[i]->endCode) {
*r29 -= mpGlyphBlocks[i]->startCode;
break;
}
}
if (i < mGly1BlockNum) {
TCachePage* pBlankPage = (TCachePage*)determineBlankPage();
if (pBlankPage == NULL) {
return NULL;
}
int texPageIdx;
getGlyphFromAram((JUTCacheFont::TGlyphCacheInfo*)mpGlyphBlocks[i], pBlankPage, r29,
&texPageIdx);
mTexPageIdx = texPageIdx;
field_0x66 = i;
rv = pBlankPage;
} else {
return NULL;
}
}
if (param_1) {
rv->field_0x1e = 1;
}
return rv;
}
void JUTCacheFont::invalidiateAllCache() {
int* cacheBuffer = (int*)mCacheBuffer;
for (int i = 0; i < mCachePage; i++) {
*cacheBuffer = i == 0 ? 0 : (intptr_t)cacheBuffer - field_0x94;
cacheBuffer[1] = i == mCachePage - 1 ? 0 : (intptr_t)cacheBuffer + field_0x94;
cacheBuffer = (int*)((intptr_t)cacheBuffer + field_0x94);
}
field_0xa8 = (intptr_t)cacheBuffer - field_0x94;
field_0xa4 = (TGlyphCacheInfo*)mCacheBuffer;
field_0x9c = NULL;
field_0xa0 = NULL;
}
void JUTCacheFont::unlink(JUTCacheFont::TGlyphCacheInfo* cacheInfo) {
if (cacheInfo->mPrev == NULL) {
field_0x9c = cacheInfo->mNext;
} else {
cacheInfo->mPrev->mNext = cacheInfo->mNext;
}
if (cacheInfo->mNext == NULL) {
field_0xa0 = cacheInfo->mPrev;
} else {
cacheInfo->mNext->mPrev = cacheInfo->mPrev;
}
}
void JUTCacheFont::prepend(JUTCacheFont::TGlyphCacheInfo* cacheInfo) {
TGlyphCacheInfo* oldHead = field_0x9c;
field_0x9c = cacheInfo;
cacheInfo->mPrev = NULL;
cacheInfo->mNext = oldHead;
if (oldHead == NULL) {
field_0xa0 = cacheInfo;
} else {
oldHead->mPrev = cacheInfo;
}
}
ResFONT* JUTResFont::getResFont() const {
return (ResFONT*)mResFont;
}
int JUTResFont::getFontType() const {
return mInf1Ptr->fontType;
}
int JUTResFont::getLeading() const {
return mInf1Ptr->leading;
}
s32 JUTResFont::getWidth() const {
return mInf1Ptr->width;
}
s32 JUTResFont::getAscent() const {
return mInf1Ptr->ascent;
}
s32 JUTResFont::getDescent() const {
return mInf1Ptr->descent;
}
s32 JUTResFont::getHeight() const {
return getAscent() + getDescent();
}
+557
View File
@@ -0,0 +1,557 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/J2DGraph/J2DOrthoGraph.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
#include "JSystem/JUtility/JUTVideo.h"
#include <vi.h>
#include <cstdio>
#include "global.h"
JUTConsoleManager* JUTConsoleManager::sManager;
JUTConsole* JUTConsole::create(unsigned int param_0, unsigned int maxLines, JKRHeap* pHeap) {
JUTConsoleManager* pManager = JUTConsoleManager::getManager();
JUT_ASSERT(33, pManager != NULL);
u8* buffer = (u8*)JKRAllocFromHeap(pHeap, getObjectSizeFromBufferSize(param_0, maxLines), 0);
JUTConsole* console = new (buffer) JUTConsole(param_0, maxLines, true);
console->mBuf = buffer + sizeof(JUTConsole);
console->clear();
pManager->appendConsole(console);
return console;
}
JUTConsole* JUTConsole::create(unsigned int param_0, void* buffer, u32 bufferSize) {
JUTConsoleManager* pManager = JUTConsoleManager::getManager();
JUT_ASSERT(59, pManager != NULL);
JUT_ASSERT(62, ( (u32)buffer & 0x3 ) == 0);
u32 maxLines = getLineFromObjectSize(bufferSize, param_0);
JUTConsole* console = new (buffer) JUTConsole(param_0, maxLines, false);
console->mBuf = (u8*)buffer + sizeof(JUTConsole);
console->clear();
pManager->appendConsole(console);
return console;
}
JUTConsole::JUTConsole(unsigned int param_0, unsigned int maxLines, bool param_2) {
field_0x2c = param_2;
field_0x20 = param_0;
mMaxLines = maxLines;
mPositionX = 30;
mPositionY = 50;
mHeight = 20;
if (mHeight > mMaxLines) {
mHeight = mMaxLines;
}
mFont = NULL;
mVisible = true;
field_0x69 = false;
field_0x6a = false;
field_0x6b = false;
mOutput = 1;
field_0x5c = JUtility::TColor(0, 0, 0, 100);
field_0x60 = JUtility::TColor(0, 0, 0, 230);
field_0x64 = 8;
}
static void dummystring1() {
UNUSED("console != 0");
}
JUTConsole::~JUTConsole() {
JUT_ASSERT(154, JUTConsoleManager::getManager());
JUTConsoleManager::getManager()->removeConsole(this);
}
size_t JUTConsole::getObjectSizeFromBufferSize(unsigned int param_0, unsigned int maxLines) {
size_t result = (param_0 + 2) * maxLines + sizeof(JUTConsole);
return result;
}
size_t JUTConsole::getLineFromObjectSize(u32 bufferSize, unsigned int param_1) {
bufferSize -= sizeof(JUTConsole);
size_t result = (bufferSize) / (param_1 + 2);
return result;
}
void JUTConsole::clear() {
field_0x30 = 0;
field_0x34 = 0;
field_0x38 = 0;
field_0x3c = 0;
for (u32 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 (mVisible && (mFont != NULL || consoleType == CONSOLE_TYPE_2)) {
if (mHeight != 0) {
bool spA = consoleType == CONSOLE_TYPE_0 ? true : false;
int spA4 = spA ? 1 : 0;
spA4 = 0;
font_yOffset = 2.0f + mFontSizeY;
if (consoleType != CONSOLE_TYPE_2) {
if (JUTGetVideoManager() == NULL) {
J2DOrthoGraph ortho(0.0f, 0.0f, 640.0f, 480.0f, -1.0f, 1.0f);
ortho.setPort();
} else {
J2DOrthoGraph ortho(0.0f, 0.0f, JUTGetVideoManager()->getFbWidth(),
JUTGetVideoManager()->getEfbHeight(), -1.0f, 1.0f);
ortho.setPort();
}
J2DFillBox(mPositionX - 2, (int)(mPositionY - font_yOffset),
(int)((mFontSizeX * field_0x20) + 4.0f),
(int)(font_yOffset * (mHeight + spA4)), spA ? field_0x60 : field_0x5c);
mFont->setGX();
if (spA) {
if (((diffIndex(field_0x30, field_0x38) - (int)mHeight) + 1) <= 0) {
mFont->setCharColor(JUtility::TColor(255, 255, 255, 255));
} else if (field_0x30 == field_0x34) {
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,
(field_0x20 * 6) + 6,
(int)(font_yOffset * mHeight) + 4);
JUTDirectPrint::getManager()->setCharColor(JUtility::TColor(255, 255, 255, 255));
}
s32 curLine = field_0x30;
s32 yFactor = 0;
u8* linePtr;
while (true) {
linePtr = getLinePtr(curLine);
u8 sp9 = linePtr[-1];
if (sp9 == 0) {
break;
}
if (consoleType != CONSOLE_TYPE_2) {
mFont->drawString_scale(mPositionX, ((yFactor * font_yOffset) + mPositionY),
mFontSizeX, mFontSizeY, (char*)linePtr, true);
} else {
JUTDirectPrint::getManager()->drawString(
mPositionX, ((yFactor * font_yOffset) + mPositionY), (char*)linePtr);
}
curLine = nextIndex(curLine);
yFactor++;
if (yFactor >= mHeight || curLine == field_0x34) {
break;
}
}
if (spA4 != 0) {
f32 f31 = mPositionX;
int sp94 = mHeight * font_yOffset + mPositionY;
mFont->setCharColor(JUtility::TColor(0xff, mVisible ? 0xff : 200, 0xc8, 0xff));
mFont->drawString_scale((int)f31, sp94, mFontSizeX, mFontSizeY, "X", TRUE);
f31 += mFontSizeX;
mFont->drawString_scale((int)f31, sp94, mFontSizeX, mFontSizeY,
mVisible ? "[ON]" : "[OFF]", TRUE);
f31 += (int)(mFontSizeX * 6.0f);
if (this == NULL) // ????
{
mFont->setCharColor(JUtility::TColor(0xff, 0xff, 0x64, 0xff));
mFont->drawString_scale((int)(f31 - mFontSizeX), mFontSizeX, mFontSizeY, sp94,
"*", TRUE);
}
mFont->setCharColor(JUtility::TColor(0xc8, 0xc8, 0xc8, 0xff));
char spA8[] = "S----------E";
char spB8[0x20];
int sp90 = diffIndex(field_0x34, field_0x38) + 1;
int sp8C = diffIndex(field_0x34, field_0x30);
int sp88 = 0;
int sp84;
if (sp90 <= mHeight) {
sp84 = 9;
sp88 = 1;
} else {
sp84 = (sp8C * 9) / (int)(sp90 - mHeight);
}
spA8[sp84 + 1] = 'O';
mFont->drawString_scale((int)f31, sp94, mFontSizeX, mFontSizeY, spA8, TRUE);
f31 += mFontSizeX * 13.0f;
if (sp88) {
sprintf(spB8, "ALL");
} else {
f32 f29 = sp8C / (f32)(sp90 - mHeight);
sprintf(spB8, "%3d%%(%dL)", (int)(100.0 * f29), sp90);
}
mFont->drawString_scale(f31, sp94, mFontSizeX, mFontSizeY, spB8, TRUE);
}
}
}
}
void JUTConsole::print_f(char const* fmt, ...) {
UNUSED(fmt);
va_list args;
va_start(args, fmt);
JUTConsole::print_f_va(fmt, args);
va_end(args);
}
void JUTConsole::print(char const* str) {
if (mOutput & 2) {
OS_REPORT("%s", str);
}
if (mOutput & 1) {
u8* src = (u8*)const_cast<char*>(str); // needs to be non-const to match debug
u8* dst = (u8*)getLinePtr(field_0x38) + field_0x3c;
while (*src != 0) {
if (field_0x6a && field_0x34 == nextIndex(field_0x38)) {
break;
}
if (*src == '\n') {
src++;
field_0x3c = field_0x20;
} else if (*src == '\t') {
src++;
while (field_0x3c < field_0x20) {
*dst++ = ' ';
field_0x3c++;
if (field_0x3c % field_0x64 == 0) {
break;
}
}
} else if (mFont && mFont->isLeadByte(*src)) {
if (field_0x3c + 1 < field_0x20) {
*dst++ = *src++;
*dst++ = *src++;
field_0x3c++;
field_0x3c++;
} else {
*dst++ = '\0';
field_0x3c++;
}
} else {
*dst++ = *src++;
field_0x3c++;
}
if (field_0x3c < field_0x20) {
continue;
}
*dst = '\0';
field_0x38 = nextIndex(field_0x38);
field_0x3c = 0;
setLineAttr(field_0x38, 0xff);
dst = getLinePtr(field_0x38);
*dst = '\0';
int local_28 = diffIndex(field_0x30, field_0x38);
if (local_28 == mHeight) {
field_0x30 = nextIndex(field_0x30);
}
if (field_0x38 == field_0x34) {
field_0x34 = nextIndex(field_0x34);
}
if (field_0x38 == field_0x30) {
field_0x30 = nextIndex(field_0x30);
}
if (field_0x6b) {
break;
}
}
*dst = '\0';
}
}
extern "C" void JUTConsole_print_f_va_(JUTConsole* console, const char* fmt, va_list args) {
JUT_ASSERT(563, console!=NULL);
char buf[1024];
int len = vsnprintf(buf, sizeof(buf), fmt, args);
console->print(buf);
}
void JUTConsole::dumpToTerminal(unsigned int param_0) {
if (param_0 == 0) {
return;
}
int r29 = field_0x34;
if (param_0 != -1) {
r29 = field_0x38;
for (; param_0; param_0--) {
int r25 = prevIndex(r29);
if (getLineAttr(r25) == 0) {
break;
}
r29 = r25;
if (r29 == field_0x34) {
break;
}
}
}
int r27 = 0;
OS_REPORT("\n:::dump of console[%x]--------------------------------\n", this);
while (true) {
u8* r28 = getLinePtr(r29);
u8 r24 = r28[-1];
if (r24 == 0) {
break;
}
if (field_0x69) {
OSReport("[%03d] %s\n", r27, r28);
} else {
OSReport("%s\n", r28);
}
r29 = nextIndex(r29);
r27++;
if (r29 == field_0x34) {
break;
}
};
OS_REPORT(":::dump of console[%x] END----------------------------\n", this);
}
static void dummyStrings2()
{
UNUSED("console != this && console != 0");
UNUSED("\n:::dump of console[%x]----------------\n");
UNUSED(":::dump of console[%x] END------------\n");
UNUSED("sManager == 0");
UNUSED("consoleManager != 0 && sManager == consoleManager");
}
void JUTConsole::scroll(int scrollAmnt) {
if (scrollAmnt < 0) {
int diff = diffIndex(field_0x34, field_0x30);
if (scrollAmnt < -diff) {
scrollAmnt = -diff;
}
} else if (scrollAmnt > 0) {
if (diffIndex(field_0x34, field_0x38) + 1 <= mHeight) {
scrollAmnt = 0;
} else {
int r27 = diffIndex(field_0x30, field_0x38) - mHeight + 1;
if (scrollAmnt > r27) {
scrollAmnt = r27;
}
}
}
field_0x30 += scrollAmnt;
if (field_0x30 < 0) {
field_0x30 += mMaxLines;
}
if (field_0x30 >= (u32)mMaxLines) {
field_0x30 -= mMaxLines;
}
}
int JUTConsole::getUsedLine() const {
int result = diffIndex(field_0x34, field_0x38);
return result;
}
int JUTConsole::getLineOffset() const {
int result = diffIndex(field_0x34, field_0x30);
return result;
}
JUTConsoleManager::JUTConsoleManager() {
mActiveConsole = NULL;
mDirectConsole = NULL;
}
JUTConsoleManager* JUTConsoleManager::createManager(JKRHeap* pHeap) {
JUT_ASSERT(0x39c, sManager == NULL);
if (pHeap == NULL) {
pHeap = JKRGetCurrentHeap();
}
sManager = new (pHeap, 0) JUTConsoleManager();
return sManager;
}
void JUTConsoleManager::appendConsole(JUTConsole* console) {
JUT_ASSERT(961, sManager != NULL && console != NULL);
JUT_ASSERT(964, soLink_.Find( console ) == soLink_.end());
soLink_.Push_back(console);
if (mActiveConsole == NULL) {
mActiveConsole = console;
}
}
void JUTConsoleManager::removeConsole(JUTConsole* console) {
JUT_ASSERT(984, sManager != NULL && console != NULL);
JUT_ASSERT(987, soLink_.Find( console ) != soLink_.end());
if (mActiveConsole == console) {
if (soLink_.size() <= 1) {
mActiveConsole = NULL;
} else {
mActiveConsole = console != &soLink_.back() ? soLink_.Element_toValue(console->mListNode.getNext()) : &soLink_.front();
}
}
if (JUTGetWarningConsole() == console)
JUTSetWarningConsole(NULL);
if (JUTGetReportConsole() == console)
JUTSetReportConsole(NULL);
soLink_.Remove(console);
}
void JUTConsoleManager::draw() const {
ConsoleList::const_iterator iter = soLink_.begin();
ConsoleList::const_iterator end = soLink_.end();
for (; iter != end; ++iter) {
const JUTConsole* const console = &(*iter);
if (console != mActiveConsole)
console->doDraw(JUTConsole::CONSOLE_TYPE_1);
}
if (mActiveConsole != NULL)
mActiveConsole->doDraw(JUTConsole::CONSOLE_TYPE_0);
}
void JUTConsoleManager::drawDirect(bool waitRetrace) const {
if (mDirectConsole != NULL) {
if (waitRetrace) {
s32 interrupt_status = OSEnableInterrupts();
u32 retrace_count = VIGetRetraceCount();
u32 new_count;
while (retrace_count == VIGetRetraceCount()){
// nop
}
OSRestoreInterrupts(interrupt_status);
}
mDirectConsole->doDraw(JUTConsole::CONSOLE_TYPE_2);
}
}
void JUTConsoleManager::setDirectConsole(JUTConsole* console) {
if (mDirectConsole != NULL) {
appendConsole(mDirectConsole);
}
if (console != NULL) {
removeConsole(console);
}
mDirectConsole = console;
}
static JUTConsole* sReportConsole;
extern "C" void JUTSetReportConsole(JUTConsole* console) {
sReportConsole = console;
}
extern "C" JUTConsole* JUTGetReportConsole() {
return sReportConsole;
}
static JUTConsole* sWarningConsole;
extern "C" void JUTSetWarningConsole(JUTConsole* console) {
sWarningConsole = console;
}
extern "C" JUTConsole* JUTGetWarningConsole() {
return sWarningConsole;
}
extern "C" void JUTReportConsole_f_va(const char* fmt, va_list args) {
char buf[256];
int len;
if (JUTGetReportConsole() == NULL) {
len = vsnprintf(buf, sizeof(buf), fmt, args);
OS_REPORT("%s", buf);
} else if (JUTGetReportConsole()->getOutput() &
(JUTConsole::OUTPUT_CONSOLE | JUTConsole::OUTPUT_OSREPORT))
{
len = vsnprintf(buf, sizeof(buf), fmt, args);
JUTGetReportConsole()->print(buf);
}
}
extern "C" void JUTReportConsole_f(const char* fmt, ...) {
UNUSED(fmt);
va_list args;
va_start(args, fmt);
JUTReportConsole_f_va(fmt, args);
va_end(args);
}
static void dummyString() {
DEAD_STRING("\n:::dump of console[%x]----------------\n");
DEAD_STRING(":::dump of console[%x] END------------\n");
}
void JUTReportConsole(const char* message) {
JUTReportConsole_f("%s", message);
}
void JUTWarningConsole_f_va(const char* fmt, va_list args) {
char buf[256];
int len;
if (JUTGetWarningConsole() == NULL) {
len = vsnprintf(buf, sizeof(buf), fmt, args);
OSReport("%s", buf);
} else if (JUTGetWarningConsole()->getOutput() &
(JUTConsole::OUTPUT_CONSOLE | JUTConsole::OUTPUT_OSREPORT))
{
len = vsnprintf(buf, sizeof(buf), fmt, args);
JUTGetWarningConsole()->print(buf);
}
}
void JUTWarningConsole_f(const char* fmt, ...) {
UNUSED(fmt);
va_list args;
va_start(args, fmt);
JUTReportConsole_f_va(fmt, args);
va_end(args);
}
void JUTWarningConsole(const char* message) {
JUTReportConsole_f("%s", message);
}
+115
View File
@@ -0,0 +1,115 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTDbPrint.h"
#include "JSystem/J2DGraph/J2DOrthoGraph.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTVideo.h"
#include <cstdio>
#include <cstring>
JUTDbPrint::JUTDbPrint(JUTFont* pFont, JKRHeap* pHeap) {
mFont = pFont;
mFirst = NULL;
mHeap = pHeap != NULL ? pHeap : JKRGetCurrentHeap();
mColor = JUtility::TColor(255, 255, 255, 255);
mVisible = true;
}
JUTDbPrint* JUTDbPrint::sDebugPrint;
JUTDbPrint* JUTDbPrint::start(JUTFont* pFont, JKRHeap* pHeap) {
if (sDebugPrint == NULL) {
if (pHeap == NULL) {
pHeap = JKRGetCurrentHeap();
}
sDebugPrint = new JUTDbPrint(pFont, pHeap);
}
return sDebugPrint;
}
JUTFont* JUTDbPrint::changeFont(JUTFont* pFont) {
JUTFont* old = mFont;
if (pFont != NULL) {
mFont = pFont;
}
return old;
}
void JUTDbPrint::enter(int param_0, int param_1, int param_2, const char* param_3, int param_4) {
if (param_4 > 0) {
unk_print* ptr = static_cast<unk_print*>(JKRAllocFromHeap(mHeap, param_4 + 0x10, -4));
if (ptr != NULL) {
ptr->unk_0x04 = param_0;
ptr->unk_0x06 = param_1;
ptr->unk_0x08 = param_2;
ptr->unk_0x0A = param_4;
strcpy(ptr->unk_0x0C, param_3);
ptr->mNext = mFirst;
mFirst = ptr;
}
}
}
static inline void enter_(int param_0, int param_1, int param_2, const char* fmt, va_list args) {
char buf[0x100];
int ret = vsnprintf(buf, 0x100, fmt, args);
if (ret >= 0) {
JUTDbPrint::getManager()->enter(param_0, param_1, param_2, buf, ret < 0x100 ? ret : 0xFF);
}
}
void JUTDbPrint::flush() {
this->flush(0, 0, JUTVideo::getManager()->getFbWidth(), JUTVideo::getManager()->getEfbHeight());
}
void JUTDbPrint::flush(int param_0, int param_1, int param_2, int param_3) {
// weird cast
unk_print* curPtr = (unk_print*)&mFirst;
unk_print* cur = mFirst;
if (mFont != NULL && cur != NULL) {
J2DOrthoGraph g(param_0, param_1, param_2, param_3, -1, 1);
g.setPort();
mFont->setGX();
mFont->setCharColor(mColor);
while (cur != NULL) {
if (mVisible) {
this->drawString(cur->unk_0x04, cur->unk_0x06, cur->unk_0x0A, (u8*)cur->unk_0x0C);
}
if (--cur->unk_0x08 <= 0) {
unk_print* next = cur->mNext;
JKRFreeToHeap(mHeap, cur);
cur = next;
curPtr->mNext = next;
} else {
curPtr = cur;
cur = cur->mNext;
}
}
}
}
void JUTDbPrint::drawString(int posX, int posY, int len, const u8* str) {
mFont->drawString_size(posX, posY, (const char*)str, len, true);
}
void JUTReport(int param_0, int param_1, char const* fmt, ...) {
UNUSED(fmt); // although not really unused
va_list args;
va_start(args, fmt);
enter_(param_0, param_1, TRUE, fmt, args);
va_end(args);
}
void JUTReport(int param_0, int param_1, int param_2, char const* fmt, ...) {
UNUSED(fmt); // although not really unused
va_list args;
va_start(args, fmt);
enter_(param_0, param_1, param_2, fmt, args);
va_end(args);
}
+168
View File
@@ -0,0 +1,168 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTDirectFile.h"
#include <os.h>
#include "global.h"
#include <stdint.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 = DVDReadAsyncPrio(&mFileInfo, mSectorStart, ALIGN_NEXT(mToRead, DVD_MIN_TRANSFER_SIZE),
ALIGN_PREV(mPos, DVD_MIN_TRANSFER_SIZE), NULL, 2);
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((uintptr_t)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<char*>(filename), &mFileInfo);
OSRestoreInterrupts(interrupts);
if (!dvdRes) {
mIsOpen = false;
return false;
}
interrupts = OSEnableInterrupts();
mLength = mFileInfo.length;
OSRestoreInterrupts(interrupts);
mPos = 0;
mIsOpen = true;
return true;
}
static void dummy(JUTDirectFile* directFile) {
directFile->isOpened();
}
void JUTDirectFile::fclose() {
if (!isOpened()) {
return;
}
int interrupts = OSEnableInterrupts();
DVDClose(&mFileInfo);
OSRestoreInterrupts(interrupts);
mIsOpen = false;
}
int JUTDirectFile::fgets(void* buf, int len) {
// if file isn't open, return error (-1).
if (!isOpened()) {
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) {
buf = NULL;
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;
}
u8* byteBuf = (u8*)buf;
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 > len - 1) {
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') {
isAtEnd = TRUE;
chunkSize = i + 1;
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) {
*byteBuf = 0;
mPos += chunkSize;
readCount += chunkSize;
break;
}
// we should have read the full chunkSize, so update count/pos.
mPos += chunkSize;
readCount += chunkSize;
// if we're at (or beyond) our desired length, set final byte to 0 and stop reading.
if (readCount >= len - 1) {
*byteBuf = 0;
break;
}
}
// if got to the end of the data, set final byte to 0.
if (mPos >= mLength) {
*byteBuf = 0;
}
return readCount;
}
@@ -0,0 +1,223 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTDirectPrint.h"
#include <cstdio>
#include <os.h>
#include "global.h"
#include "angle_utils.h"
JUTDirectPrint* JUTDirectPrint::sDirectPrint;
JUTDirectPrint::JUTDirectPrint() {
changeFrameBuffer(NULL, 0, 0);
setCharColor(0xff, 0xff, 0xff);
}
JUTDirectPrint* JUTDirectPrint::start() {
if (!sDirectPrint) {
sDirectPrint = new JUTDirectPrint();
}
return sDirectPrint;
}
void JUTDirectPrint::erase(int x, int y, int width, int height) {
if (!this->field_0x00) {
return;
}
if (400 < mFrameBufferWidth) {
x = x << 1;
width = width << 1;
}
if (300 < mFrameBufferHeight) {
y = y << 1;
height = height << 1;
}
u16* pixel = mFrameBuffer + 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) {
static u32 twiceBit[4] = { 0, 3, 12, 15 };
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 = (mFrameBufferWidth < 400) ? 1 : 2;
int scale_y = (mFrameBufferHeight < 300) ? 1 : 2;
u16 *pixel = mFrameBuffer + mStride * position_y * scale_y + position_x * scale_x;
for (int y = 0; y < 7; y++) {
u32 data = *font_data++ << col_index;
if (scale_x == 1) {
data = (data & 0xfc000000) >> 1;
} else {
data = (twiceBit[(data >> 26) & 3] | twiceBit[(data >> 28) & 3] << 4 | twiceBit[(data >> 30) & 3] << 8) << 19;
}
for (int x = 0; x < scale_x * 6; x += 2) {
u16 value;
value = (((data & 0x40000000) ? mCharColor_Y : 0) |
((data & 0x80000000) ? mCharColor_Cb4 : 32) +
((data & 0x40000000) ? mCharColor_Cb2 : 64) +
((data & 0x20000000) ? mCharColor_Cb4 : 32));
*pixel = value;
if (scale_y > 1) {
pixel[mStride] = value;
}
pixel++;
value = (((data & 0x20000000) ? mCharColor_Y : 0) |
((data & 0x40000000) ? mCharColor_Cr4 : 32) +
((data & 0x20000000) ? mCharColor_Cr2 : 64) +
((data & 0x10000000) ? mCharColor_Cr4 : 32));
*pixel = value;
if (scale_y > 1) {
pixel[mStride] = value;
}
pixel++;
data <<= 2;
}
pixel += mStride * scale_y - 6 * scale_x;
}
}
void JUTDirectPrint::changeFrameBuffer(void* frameBuffer, u16 width, u16 height) {
this->field_0x00 = frameBuffer;
mFrameBuffer = (u16*)frameBuffer;
mFrameBufferWidth = width;
mFrameBufferHeight = height;
mStride = ALIGN_NEXT(width & 0xFFFF, 16);
mFrameBufferSize = (u32)mStride * (u32)mFrameBufferHeight * 2;
}
void JUTDirectPrint::printSub(u16 position_x, u16 position_y, char const* format, va_list args,
bool clear) {
char buffer[256];
if (!mFrameBuffer) {
return;
}
int buffer_length = vsnprintf(buffer, ARRAY_SIZEU(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) {
U16_ADD_2(position_y, 7);
position_x = x;
} else if (codepoint == 0xfd) {
position_x = position_x + 0x30 - ((position_x - x + 0x2f) % 0x30);
} else {
if (codepoint != 0xff) {
drawChar(position_x, position_y, codepoint);
}
U16_ADD_2(position_x, 6);
}
}
}
DCStoreRange(mFrameBuffer, mFrameBufferSize);
}
void JUTDirectPrint::print(u16 position_x, u16 position_y, char const* format, ...) {
UNUSED(format);
if (mFrameBuffer) {
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, ...) {
UNUSED(format);
if (mFrameBuffer) {
va_list args;
va_start(args, format);
printSub(position_x, position_y, format, args, false);
va_end(args);
}
}
void JUTDirectPrint::setCharColor(JUtility::TColor color) {
setCharColor(color.r, color.g, color.b);
}
void JUTDirectPrint::setCharColor(u8 r, u8 g, u8 b) {
mCharColor = JUtility::TColor(r, g, b, 0xFF);
int Y = 0.257 * (int)r + 0.504 * (int)g + 0.098 * (int)b + 16.0f;
int Cb = -0.148 * (int)r - 0.291 * (int)g + 0.439 * (int)b + 128.0f;
int Cr = 0.439 * (int)r - 0.368 * (int)g - 0.071 * (int)b + 128.0f;
mCharColor_Y = (u16)Y * 256;
mCharColor_Cb = Cb;
mCharColor_Cb2 = (u16)Cb / 2;
mCharColor_Cb4 = (u16)Cb / 4;
mCharColor_Cr = Cr;
mCharColor_Cr2 = (u16)Cr / 2;
mCharColor_Cr4 = (u16)Cr / 4;
}
File diff suppressed because it is too large Load Diff
+112
View File
@@ -0,0 +1,112 @@
/**
* JUTFader.cpp
* JUtility - Color Fader
*/
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTFader.h"
#include "JSystem/J2DGraph/J2DOrthoGraph.h"
JUTFader::JUTFader(int x, int y, int width, int height, JUtility::TColor pColor)
: mColor(pColor), mBox(x, y, x + width, y + height) {
mStatus = 0;
field_0x8 = 0;
field_0xa = 0;
field_0x24 = 0;
mEStatus = UNKSTATUS_M1;
}
void JUTFader::control() {
if (0 <= mEStatus && mEStatus-- == 0) {
mStatus = field_0x24;
}
if (mStatus == 1) {
return;
}
switch (mStatus) {
case 0:
mColor.a = 0xFF;
break;
case 2:
mColor.a = 0xFF - ((++field_0xa * 0xFF) / field_0x8);
if (field_0xa >= field_0x8) {
mStatus = 1;
}
break;
case 3:
mColor.a = ((++field_0xa * 0xFF) / field_0x8);
if (field_0xa >= field_0x8) {
mStatus = 0;
}
break;
}
draw();
}
void JUTFader::draw() {
if (mColor.a != 0) {
J2DOrthoGraph orthograph;
orthograph.setColor(mColor);
orthograph.fillBox(mBox);
}
}
bool JUTFader::startFadeIn(int param_0) {
bool statusCheck = mStatus == 0;
if (statusCheck) {
mStatus = 2;
field_0xa = 0;
field_0x8 = param_0;
}
return statusCheck;
}
bool JUTFader::startFadeOut(int param_0) {
bool statusCheck = mStatus == 1;
if (statusCheck) {
mStatus = 3;
field_0xa = 0;
field_0x8 = param_0;
}
return statusCheck;
}
void JUTFader::setStatus(JUTFader::EStatus i_status, int param_1) {
switch (i_status) {
case 0:
if (param_1 != 0) {
field_0x24 = 0;
mEStatus = param_1;
break;
}
mStatus = 0;
field_0x24 = 0;
mEStatus = 0;
break;
case 1:
if (param_1 != 0) {
field_0x24 = 1;
mEStatus = param_1;
break;
}
mStatus = 1;
field_0x24 = 1;
mEStatus = 0;
break;
}
}
JUTFader::~JUTFader() {}
+53
View File
@@ -0,0 +1,53 @@
/**
* JUTFont.cpp
* JUtility - Font Management
*/
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTFont.h"
JUTFont::JUTFont() : mColor1(), mColor2(), mColor3(), mColor4() {
mValid = false;
}
void JUTFont::initialize_state() {
setCharColor(-1);
setFixedWidth(false, 0);
mValid = false;
}
void JUTFont::setCharColor(JUtility::TColor col1) {
mColor1 = col1;
mColor2 = col1;
mColor3 = col1;
mColor4 = col1;
}
void JUTFont::setGradColor(JUtility::TColor col1, JUtility::TColor col2) {
mColor1 = col1;
mColor2 = col1;
mColor3 = col2;
mColor4 = col2;
}
f32 JUTFont::drawString_size_scale(f32 a1, f32 a2, f32 a3, f32 a4, const char* str, u32 usz,
bool a7) {
f32 temp = a1;
for (; usz != 0; --usz, ++str) {
s32 b = (u8)*str;
if (isLeadByte(b)) {
JUT_ASSERT(114, usz >= 2);
usz--;
str++;
b <<= 8;
b |= (u8)*str;
}
a1 += drawChar_scale(a1, a2, a3, a4, b, a7);
a7 = 1;
}
return a1 - temp;
}
File diff suppressed because it is too large Load Diff
+612
View File
@@ -0,0 +1,612 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTGamePad.h"
#include <cmath>
u32 JUTGamePad::CRumble::sChannelMask[4] = {
PAD_CHAN0_BIT,
PAD_CHAN1_BIT,
PAD_CHAN2_BIT,
PAD_CHAN3_BIT,
};
static u32 channel_mask[4] = {PAD_CHAN0_BIT, PAD_CHAN1_BIT, PAD_CHAN2_BIT, PAD_CHAN3_BIT};
JSUList<JUTGamePad> JUTGamePad::mPadList(false);
bool JUTGamePad::mListInitialized;
u8 JUTGamePad::mPadAssign[4];
JUTGamePad::JUTGamePad(EPadPort port) : mRumble(this), mLink(this) {
mPortNum = port;
if (mPortNum >= 0) {
mPadAssign[port]++;
}
initList();
mPadList.append(&mLink);
update();
mPadRecord = 0;
mPadReplay = 0;
clear();
}
JUTGamePad::~JUTGamePad() {
if (mPortNum >= 0) {
mPadAssign[mPortNum]--;
mPortNum = EPortInvalid;
}
mPadList.remove(&mLink);
}
void JUTGamePad::initList() {
if (!mListInitialized) {
mPadList.initiate();
mListInitialized = true;
}
}
u32 JUTGamePad::sSuppressPadReset;
u8 data_8074CFA4_debug;
s32 JUTGamePad::sAnalogMode;
BOOL JUTGamePad::init() {
PADSetSpec(PAD_SPEC_5);
setAnalogMode(3);
return PADInit();
}
void JUTGamePad::clear() {
mButtonReset.mReset = false;
field_0xa8 = 1;
}
PADStatus JUTGamePad::mPadStatus[4];
JUTGamePad::CButton JUTGamePad::mPadButton[4];
JUTGamePad::CStick JUTGamePad::mPadMStick[4];
JUTGamePad::CStick JUTGamePad::mPadSStick[4];
JUTGamePad::EStickMode JUTGamePad::sStickMode = EStickMode1;
int JUTGamePad::sClampMode = EClampStick;
u32 JUTGamePad::sRumbleSupported;
u32 JUTGamePad::read() {
sRumbleSupported = PADRead(mPadStatus);
switch (sClampMode) {
case EClampStick:
PADClamp(mPadStatus);
break;
case EClampCircle:
PADClampCircle(mPadStatus);
break;
}
u32 bittest;
u32 reset_mask = 0;
for (int i = 0; i < 4; i++) {
bittest = PAD_CHAN0_BIT >> i;
if (mPadStatus[i].err == 0) {
PADStatus* pad_status = &mPadStatus[i];
u32 stick_status;
stick_status = mPadMStick[i].update(pad_status->stickX, pad_status->stickY, sStickMode, EMainStick, mPadButton[i].mButton) << 0x18;
stick_status |= (mPadSStick[i].update(pad_status->substickX, pad_status->substickY, sStickMode, ESubStick, mPadButton[i].mButton) << 0x10);
mPadButton[i].update(pad_status, stick_status);
} else if (mPadStatus[i].err == -1) {
mPadMStick[i].update(0, 0, sStickMode, EMainStick, 0);
mPadSStick[i].update(0, 0, sStickMode, ESubStick, 0);
mPadButton[i].update(NULL, 0);
if (!(sSuppressPadReset & bittest)) {
reset_mask |= bittest;
}
} else {
if (data_8074CFA4_debug) {
OS_REPORT("game pad read error (%d)\n", mPadStatus[i].err);
}
mPadButton[i].mTrigger = 0;
mPadButton[i].mRelease = 0;
mPadButton[i].mRepeat = 0;
}
}
for (JSUListIterator<JUTGamePad> pad(mPadList.getFirst()); pad != mPadList.getEnd(); ++pad) {
if (pad->getPadReplay() != NULL && pad->getPadReplay()->isActive()) {
PADStatus status;
pad->getPadReplay()->getStatus(&status);
u32 stick_status;
stick_status = pad->mMainStick.update(status.stickX, status.stickY, sStickMode,
EMainStick, pad->mButton.mButton) << 0x18;
stick_status |= pad->mSubStick.update(status.substickX, status.substickY, sStickMode,
ESubStick, pad->mButton.mButton) << 0x10;
pad->mButton.update(&status, stick_status);
} else {
if (pad->mPortNum == EPortInvalid) {
pad->assign();
}
pad->update();
}
if (pad->getPadRecord() != NULL && pad->getPadRecord()->isActive()) {
if (pad->mPortNum >= 0) {
int port = pad->mPortNum;
if (mPadStatus[port].err == 0) {
pad->getPadRecord()->write(&mPadStatus[port]);
}
}
}
}
if (reset_mask != 0) {
PADReset(reset_mask);
}
checkResetSwitch();
return sRumbleSupported;
}
void JUTGamePad::assign() {
for (int i = 0; i < 4; i++) {
if (mPadStatus[i].err == 0 && mPadAssign[i] == 0) {
mPortNum = i;
mPadAssign[i] = 1;
mPadButton[i].setRepeat(mButton.mRepeatMask, mButton.mRepeatDelay, mButton.mRepeatRate);
mRumble.clear(this);
break;
}
}
}
u8 JUTGamePad::CRumble::mStatus[4];
u32 JUTGamePad::CRumble::mEnabled;
callbackFn JUTGamePad::C3ButtonReset::sCallback;
void* JUTGamePad::C3ButtonReset::sCallbackArg;
OSTime JUTGamePad::C3ButtonReset::sThreshold = (OSTime)(OS_TIMER_CLOCK / 60) * 30;
bool JUTGamePad::C3ButtonReset::sResetSwitchPushing;
bool JUTGamePad::C3ButtonReset::sResetOccurred;
s32 JUTGamePad::C3ButtonReset::sResetOccurredPort;
void JUTGamePad::checkResetCallback(OSTime holdTime) {
if (holdTime >= JUTGamePad::C3ButtonReset::sThreshold) {
JUTGamePad::C3ButtonReset::sResetOccurred = true;
JUTGamePad::C3ButtonReset::sResetOccurredPort = mPortNum;
if (JUTGamePad::C3ButtonReset::sCallback != NULL) {
JUTGamePad::C3ButtonReset::sCallback(mPortNum, JUTGamePad::C3ButtonReset::sCallbackArg);
}
}
}
f32 JUTGamePad::CStick::sPressPoint = 0.5f;
f32 JUTGamePad::CStick::sReleasePoint = 0.25f;
u32 JUTGamePad::C3ButtonReset::sResetPattern = PAD_BUTTON_START | PAD_BUTTON_X | PAD_BUTTON_B;
u32 JUTGamePad::C3ButtonReset::sResetMaskPattern = 0x0000FFFF;
void JUTGamePad::update() {
if (mPortNum != EPortInvalid) {
if (mPortNum >= 0 && mPortNum < 4) {
mButton = mPadButton[mPortNum];
mMainStick = mPadMStick[mPortNum];
mSubStick = mPadSStick[mPortNum];
mErrorStatus = mPadStatus[mPortNum].err;
}
if (field_0xa8 == 0 || C3ButtonReset::sResetPattern != (mButton.mButton & C3ButtonReset::sResetMaskPattern)) {
mButtonReset.mReset = false;
} else if (!JUTGamePad::C3ButtonReset::sResetOccurred) {
if (mButtonReset.mReset == true) {
OSTime hold_time = OSGetTime() - mResetHoldStartTime;
checkResetCallback(hold_time);
} else {
mButtonReset.mReset = true;
mResetHoldStartTime = OSGetTime();
}
}
for (JSUListIterator<JUTGamePadLongPress> pad(JUTGamePadLongPress::sPatternList.getFirst()); pad != JUTGamePadLongPress::sPatternList.getEnd(); ++pad) {
if (pad->isValid()) {
if (mPortNum >= 0 && mPortNum < 4) {
if ((mButton.mButton & pad->getMaskPattern()) == pad->getPattern()) {
if (pad->mLongPressStatus[mPortNum] == true) {
OSTime hold_time = OSGetTime() - pad->mStartHoldTime[mPortNum];
pad->checkCallback(mPortNum, hold_time);
} else {
pad->mLongPressStatus[mPortNum] = true;
pad->mStartHoldTime[mPortNum] = OSGetTime();
}
} else {
pad->mLongPressStatus[mPortNum] = false;
}
}
}
}
if (mPortNum >= 0 && mPortNum < 4) {
mRumble.update(mPortNum);
}
}
}
JSUList<JUTGamePadLongPress> JUTGamePadLongPress::sPatternList(false);
void JUTGamePad::checkResetSwitch() {
if (!JUTGamePad::C3ButtonReset::sResetOccurred) {
int unused;
if (OSGetResetSwitchState()) {
C3ButtonReset::sResetSwitchPushing = true;
} else {
if (C3ButtonReset::sResetSwitchPushing == true) {
C3ButtonReset::sResetOccurred = true;
C3ButtonReset::sResetOccurredPort = EPortInvalid;
if (C3ButtonReset::sCallback != NULL) {
C3ButtonReset::sCallback(EPortInvalid, C3ButtonReset::sCallbackArg);
}
}
C3ButtonReset::sResetSwitchPushing = false;
}
}
}
void JUTGamePad::clearForReset() {
CRumble::setEnabled(0);
recalibrate(PAD_CHAN3_BIT | PAD_CHAN2_BIT | PAD_CHAN1_BIT | PAD_CHAN0_BIT);
}
void JUTGamePad::CButton::clear() {
mButton = 0;
mTrigger = 0;
mRelease = 0;
mRepeat = 0;
mAnalogA = 0;
mAnalogB = 0;
mAnalogL = 0;
mAnalogR = 0;
mRepeatCount = 0;
mRepeatStart = 0;
mRepeatMask = 0;
mRepeatDelay = 0;
mRepeatRate = 0;
}
void JUTGamePad::CButton::update(const PADStatus* padStatus, u32 stickStatus) {
u32 buttons = stickStatus | (padStatus != NULL ? padStatus->button : 0);
mRepeat = 0;
if (mRepeatDelay != 0 && mRepeatMask != 0) {
u32 repeatButton = buttons & mRepeatMask;
mRepeat = 0;
if (repeatButton == 0) {
mRepeatStart = 0;
mRepeatCount = 0;
} else if (mRepeatStart == repeatButton) {
mRepeatCount++;
if (mRepeatCount == mRepeatDelay ||
(mRepeatCount > mRepeatDelay && (mRepeatCount - mRepeatDelay) % mRepeatRate == 0))
{
mRepeat = repeatButton;
}
} else {
mRepeat = repeatButton & (mRepeatStart ^ 0xFFFFFFFF);
mRepeatStart = repeatButton;
mRepeatCount = 0;
}
}
mTrigger = buttons & (buttons ^ mButton);
mRelease = mButton & (buttons ^ mButton);
mButton = buttons;
mRepeat |= (mRepeatMask ^ 0xFFFFFFFF) & mTrigger;
if (padStatus != NULL) {
mAnalogA = padStatus->analogA;
mAnalogB = padStatus->analogB;
mAnalogL = padStatus->triggerLeft;
mAnalogR = padStatus->triggerRight;
} else {
mAnalogA = 0;
mAnalogB = 0;
mAnalogL = 0;
mAnalogR = 0;
}
mAnalogLf = (s32)mAnalogL / 150.0f;
mAnalogRf = (s32)mAnalogR / 150.0f;
}
void JUTGamePad::CStick::clear() {
mPosX = 0.0f;
mPosY = 0.0f;
mValue = 0.0f;
mAngle = 0;
}
u32 JUTGamePad::CStick::update(s8 x, s8 y, JUTGamePad::EStickMode mode,
JUTGamePad::EWhichStick stick, u32 buttons) {
s32 clamp;
switch (getClampMode()) {
case EClampStick:
clamp = stick == EMainStick ? 54 : 42;
break;
case EClampCircle:
clamp = stick == EMainStick ? 38 : 29;
break;
default:
clamp = stick == EMainStick ? 69 : 57;
break;
}
mRawX = x;
mRawY = y;
mPosX = (f32)x / (f32)clamp;
mPosY = (f32)y / (f32)clamp;
mValue = sqrtf((mPosX * mPosX) + (mPosY * mPosY));
if (mValue > 1.0f) {
if (mode == EStickMode1) {
mPosX /= mValue;
mPosY /= mValue;
}
mValue = 1.0f;
}
if (mValue > 0.0f) {
if (mPosY == 0.0f) {
if (mPosX > 0.0f) {
mAngle = 0x4000;
} else {
mAngle = -0x4000;
}
} else {
mAngle = (0x8000 / 3.1415926f) * atan2f(mPosX, -mPosY);
}
}
return getButton(buttons >> (stick == EMainStick ? 0x18 : 0x10));
}
u32 JUTGamePad::CStick::getButton(u32 buttons) {
u32 button = buttons & (PAD_BUTTON_UP | PAD_BUTTON_DOWN | PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT);
if (-sReleasePoint < mPosX && mPosX < sReleasePoint) {
button &= ~(PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT);
} else if (mPosX <= -sPressPoint) {
button &= ~PAD_BUTTON_RIGHT;
button |= PAD_BUTTON_LEFT;
} else if (mPosX >= sPressPoint) {
button &= ~PAD_BUTTON_LEFT;
button |= PAD_BUTTON_RIGHT;
}
if (-sReleasePoint < mPosY && mPosY < sReleasePoint) {
button &= ~(PAD_BUTTON_UP | PAD_BUTTON_DOWN);
} else if (mPosY <= -sPressPoint) {
button &= ~PAD_BUTTON_UP;
button |= PAD_BUTTON_DOWN;
} else if (mPosY >= sPressPoint) {
button &= ~PAD_BUTTON_DOWN;
button |= PAD_BUTTON_UP;
}
return button;
}
void JUTGamePad::CRumble::clear() {
mFrame = 0;
mLength = 0;
mPattern = NULL;
mFrameCount = 0;
field_0x10 = 0;
mEnabled = (PAD_CHAN3_BIT | PAD_CHAN2_BIT | PAD_CHAN1_BIT | PAD_CHAN0_BIT);
}
void JUTGamePad::CRumble::clear(JUTGamePad* pad) {
if (pad->getPortNum() >= 0 && pad->getPortNum() < 4) {
mStatus[pad->getPortNum()] = false;
pad->stopMotorHard();
}
clear();
}
void JUTGamePad::CRumble::startMotor(int port) {
if (isEnabledPort(port)) {
PADControlMotor(port, PAD_MOTOR_RUMBLE);
mStatus[port] = true;
}
}
void JUTGamePad::CRumble::stopMotor(int port, bool hard_stop) {
u8 command;
if (isEnabledPort(port)) {
if (hard_stop) {
command = PAD_MOTOR_STOP_HARD;
} else {
command = PAD_MOTOR_STOP;
}
PADControlMotor(port, command);
mStatus[port] = false;
}
}
static bool getNumBit(u8* pattern, int index) {
u8 bit = pattern[index >> 3] & (0x80 >> (index & 7));
return bit != 0;
}
void JUTGamePad::CRumble::update(s16 port) {
if (isEnabledPort(port) == false) {
mFrame = 0;
mLength = 0;
mPattern = NULL;
mFrameCount = 0;
field_0x10 = NULL;
}
if (mLength == 0) {
return;
}
if (mFrame >= mLength) {
stopMotorHard(port);
mLength = 0;
} else if (mFrameCount == 0) {
if (mStatus[port] == false) {
startMotor(port);
}
return;
} else {
bool enabled = getNumBit(mPattern, mFrame % mFrameCount);
u32 status = mStatus[port] != false;
if (enabled && !status) {
startMotor(port);
} else if (!enabled) {
bool hard_stop = false;
if (field_0x10) {
hard_stop = getNumBit(field_0x10, mFrame % mFrameCount);
}
if (status) {
stopMotor(port, hard_stop);
} else if (hard_stop) {
stopMotor(port, true);
}
}
}
mFrame++;
}
void JUTGamePad::CRumble::triggerPatternedRumble(u32 length) {
if (mPattern != NULL && mFrameCount != 0) {
mLength = length;
mFrame = 0;
}
}
void JUTGamePad::CRumble::startPatternedRumble(void* data, JUTGamePad::CRumble::ERumble rumble,
u32 length) {
mFrameCount = ((*(u8*)data) << 8) + *((u8*)data + 1);
mPattern = (u8*)data + 2;
switch (rumble) {
case JUTGamePad::CRumble::VAL_0:
triggerPatternedRumble(mFrameCount);
break;
case JUTGamePad::CRumble::VAL_1:
triggerPatternedRumble(-1);
break;
case JUTGamePad::CRumble::VAL_2:
triggerPatternedRumble(length);
break;
}
}
void JUTGamePad::CRumble::stopPatternedRumble(s16 port) {
JUT_ASSERT(1341, 0 <= port && port < 4);
mLength = 0;
stopMotorHard(port);
}
void JUTGamePad::CRumble::stopPatternedRumbleAtThePeriod() {
u32 r31 = mFrame % mFrameCount;
mLength = (mFrame + mFrameCount - 1) % mFrameCount;
}
JUTGamePad* JUTGamePad::getGamePad(int port) {
for (JSUListIterator<JUTGamePad> pad(mPadList.getFirst()); pad != mPadList.getEnd(); ++pad) {
if (port == pad->mPortNum) {
return pad.getObject();
}
}
return NULL;
}
void JUTGamePad::CRumble::setEnabled(u32 mask) {
mask = (mask & (PAD_CHAN3_BIT | PAD_CHAN2_BIT | PAD_CHAN1_BIT | PAD_CHAN0_BIT));
for (int i = 0; i < 4; i++) {
if ((mEnabled & channel_mask[i]) == 0) {
if (mStatus[i]) {
stopMotor(i);
}
JUTGamePad* pad = getGamePad(i);
if (pad != NULL) {
pad->stopMotorWaveHard();
}
}
}
mEnabled = mask;
}
void JUTGamePad::CButton::setRepeat(u32 mask, u32 delay, u32 rate) {
mRepeatStart = 0;
mRepeatCount = 0;
mRepeatMask = mask;
mRepeatDelay = delay;
mRepeatRate = rate;
}
void JUTGamePad::setButtonRepeat(u32 mask, u32 delay, u32 rate) {
mButton.setRepeat(mask, delay, rate);
if (mPortNum >= 0) {
mPadButton[mPortNum].setRepeat(mask, delay, rate);
}
}
bool JUTGamePad::recalibrate(u32 mask) {
for (int i = 0; i < 4; i++) {
if (sSuppressPadReset & channel_mask[i]) {
mask &= channel_mask[i] ^ 0xFFFFFFFF;
}
}
BOOL result = PADRecalibrate(mask);
return result;
}
void JUTGamePadLongPress::checkCallback(int port, u32 hold_time) {
if (port < 0) {
return;
}
JUT_ASSERT(1673, 0 <= port && port < 4);
if (hold_time < mThreshold) {
return;
}
field_0x11 = true;
field_0x48[port] = true;
if (mCallback != NULL) {
mCallback(port, this, field_0x50);
}
}
@@ -0,0 +1,41 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTGraphFifo.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <stdint.h>
static bool data_804514B8;
JUTGraphFifo* JUTGraphFifo::sCurrentFifo;
JUTGraphFifo::JUTGraphFifo(u32 size) {
mSize = ROUND(size, 0x20);
if (data_804514B8) {
u32 fifoSize = sizeof(GXFifoObj);
mFifo = (GXFifoObj*)JKRAllocFromSysHeap(fifoSize + mSize, 32);
mBase = (u8*)mFifo + fifoSize;
GXInitFifoBase(mFifo, mBase, mSize);
GXInitFifoPtrs(mFifo, mBase, mBase);
} else {
mBase = JKRAllocFromSysHeap(mSize + 0xA0, 32);
mBase = (void*)ALIGN_NEXT((uintptr_t)mBase, 0x20);
mFifo = GXInit(mBase, mSize);
data_804514B8 = true;
sCurrentFifo = this;
}
}
bool JUTGraphFifo::mGpStatus[5];
JUTGraphFifo::~JUTGraphFifo() {
sCurrentFifo->save();
while (isGPActive()) {
// nop
}
if (sCurrentFifo == this) {
sCurrentFifo = NULL;
}
JKRFreeToSysHeap(mBase);
}
+57
View File
@@ -0,0 +1,57 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTNameTab.h"
#include <cstring>
JUTNameTab::JUTNameTab() {
setResource(NULL);
}
JUTNameTab::JUTNameTab(const ResNTAB* pNameTable) {
setResource(pNameTable);
}
void JUTNameTab::setResource(const ResNTAB* pNameTable) {
mNameTable = pNameTable;
if (pNameTable != NULL) {
mNameNum = pNameTable->mEntryNum;
mpStrData = (const char*)(pNameTable->mEntries + mNameNum);
} else {
mNameNum = 0;
mpStrData = 0;
}
}
s32 JUTNameTab::getIndex(const char* pName) const {
JUT_ASSERT(101, mNameTable != NULL);
const ResNTAB::Entry* pEntry = mNameTable->mEntries;
u16 keyCode = calcKeyCode(pName);
for (u16 i = 0; i < mNameNum; i++) {
if (
pEntry->mKeyCode == keyCode &&
strcmp((mNameTable->mEntries[i].mOffs + ((const char*)mNameTable)), pName) == 0
) {
return i;
}
pEntry++;
}
return -1;
}
const char* JUTNameTab::getName(u16 index) const {
JUT_ASSERT(138, mNameTable != NULL);
if (index < mNameNum)
return ((const char*)mNameTable) + mNameTable->mEntries[index].mOffs;
return NULL;
}
u16 JUTNameTab::calcKeyCode(const char* pName) const {
u32 keyCode = 0;
while (*pName)
keyCode = (keyCode * 3) + *pName++;
return keyCode;
}
+36
View File
@@ -0,0 +1,36 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTPalette.h"
#include <gx.h>
#include <os.h>
void JUTPalette::storeTLUT(GXTlut param_0, ResTLUT* tlut) {
if (tlut == NULL) {
OSPanic("JUTPalette.cpp", 35, "JUTTexture: TLUT is NULL\n");
}
mTlutName = param_0;
mFormat = (const u8)tlut->format;
mTransparency = (const u8)tlut->transparency;
mNumColors = tlut->numColors;
mColorTable = tlut + 8;
GXInitTlutObj(&mTlutObj, (void*)mColorTable, (GXTlutFmt)mFormat, mNumColors);
}
void JUTPalette::storeTLUT(GXTlut param_0, GXTlutFmt param_1, JUTTransparency param_2,
u16 param_3, void* param_4) {
mTlutName = param_0;
mFormat = param_1;
mTransparency = param_2;
mNumColors = param_3;
mColorTable = (ResTLUT*)param_4;
GXInitTlutObj(&mTlutObj, (void*)mColorTable, (GXTlutFmt)mFormat, mNumColors);
}
bool JUTPalette::load() {
bool check = mNumColors != 0;
if (check) {
GXLoadTlut(&mTlutObj, mTlutName);
}
return check;
}
+322
View File
@@ -0,0 +1,322 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTProcBar.h"
#include "JSystem/J2DGraph/J2DOrthoGraph.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTVideo.h"
#include <stdint.h>
JUTProcBar::JUTProcBar() {
mVisible = true;
mHeapBarVisible = true;
field_0x108 = 0;
s32 height = JUTVideo::getManager()->getEfbHeight();
if (height > 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);
}
field_0x110 = 1;
field_0x128 = 0;
mWatchHeap = NULL;
}
JUTProcBar* JUTProcBar::sManager;
JUTProcBar::~JUTProcBar() {
sManager = NULL;
}
JUTProcBar* JUTProcBar::create() {
if (!sManager) {
sManager = new JUTProcBar();
}
return sManager;
}
void JUTProcBar::destroy() {
if (sManager) {
delete sManager;
}
sManager = NULL;
}
static f32 oneFrameRate = 8.0f;
static f32 oneFrameRateUser = 10.0f;
void JUTProcBar::clear() {
sManager->idleStart();
sManager->cpuStart();
sManager->gpStart();
sManager->wholeLoopStart();
sManager->setCostFrame(0);
oneFrameRate = 8.0f;
oneFrameRateUser = 10.0f;
}
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 r29 = param_5 * param_3 / param_4;
int r31 = param_6 * param_3 / param_4;
J2DFillBox(param_0, param_1, r29, param_2, param_7);
if (r31 < 0) {
return;
}
if (r31 < 6) {
J2DFillBox(param_0, param_1, r31, param_2, param_8);
} else {
J2DFillBox(param_0 + r31 - 6, param_1, 6.0f, param_2, param_8);
}
}
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;
u32 frameDuration = 16666;
while (var1 > param_2) {
if (param_0 * var1 * 20.0f / frameDuration <= mParams.mWidth - 30.0f)
break;
var1 -= (1.0f / 10.0f);
var2 = true;
}
if (var1 >= param_3)
*param_4 = 0;
if (var1 > param_3 - (1.0f / 5.0f))
var1 = param_3;
while (!var2 && var1 < param_3) {
(*param_4)++;
if (*param_4 < 0x1e)
break;
if ((param_0 * var1 * 20.0f / frameDuration) < (mParams.mWidth - 60.0f))
var1 += (1.0f / 5.0f);
break;
}
*param_1 = var1;
}
void JUTProcBar::draw() {
drawProcessBar();
drawHeapBar();
}
void JUTProcBar::drawProcessBar() {
if (mVisible) {
int frameDuration = 16666; // duration in miliseconds? for how long a frame takes,
if (JUTVideo::getManager()) {
int viMode = JUTVideo::getManager()->getRenderMode()->viTVmode;
int viMode2 = ((viMode >> 2) & 0x0f);
if (viMode2 == 1) { // 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 (field_0x110 == 0) {
int r23 = mParams.mPosY + mParams.mBarWidth;
bar_subroutine(mParams.mPosX + 1, r23, r26, r28, frameDuration, mGp.mCost,
mGp.field_0x8, 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.field_0x8, 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.field_0x8, 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));
J2DFillBox((int)(gpuTime * r28 / frameDuration + r21), r22,
(int)(mGpWait.mCost * r28 / frameDuration), r26,
JUtility::TColor(0, 255, 0, 255));
int r30 = mGp.mCost * 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));
r21 += mCpu.mCost * r28 / frameDuration;
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];
u32 sp17c = time->mCost;
if (++time->field_0xc >= 0x10 || time->mCost > time->field_0x8) {
time->field_0x8 = time->mCost;
time->field_0xc = 0;
}
if (time->field_0x8 > temp3)
temp3 = time->field_0x8;
}
bool sp11 = temp3 ? true : false;
if (sp11 == 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];
int unsued = time->mCost;
if (++time->field_0xc >= 0x10 || time->mCost > time->field_0x8) {
time->field_0x8 = time->mCost;
time->field_0xc = 0;
}
if (time->mCost != 0 || time->field_0x8 != 0) {
int temp4 = time->mCost * r21 / frameDuration;
int temp5 = time->field_0x8 * 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);
}
}
field_0x108 = 0;
}
}
static int addrToXPos(void* param_0, int param_1) {
int result = param_1 * (((uintptr_t)param_0 - 0x80000000) / (float)JKRHeap::getMemorySize());
return result;
}
static int byteToXLen(int param_0, int param_1) {
int result = param_1 * (param_0 / (float)JKRHeap::getMemorySize());
return result;
}
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);
s32 freeSize = param_0->getTotalFreeSize();
int stack36 = byteToXLen(freeSize, 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));
}
void JUTProcBar::drawHeapBar() {
if (mHeapBarVisible) {
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?
int start = posX + addrToXPos(JKRHeap::getCodeStart(), width);
int end = posX + addrToXPos(JKRHeap::getCodeEnd(), width);
J2DFillBox(start, posY - (height * 2), end - 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);
end = posX + addrToXPos(JKRHeap::getUserRamEnd(), width);
J2DFillBox(start, posY - (height * 2), end - 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)
s32 freeSize = JKRHeap::getRootHeap()->getTotalFreeSize();
int size = byteToXLen(freeSize, width);
J2DFillBox(start, posY - (height * 2), size, height / 2,
JUtility::TColor(0, 250, 250, 255));
if (field_0x128 == 0) {
// draws a line of either the watch heap(if available), otherwise draw the current heap
JKRHeap* heap = mWatchHeap ? mWatchHeap : JKRHeap::getCurrentHeap();
if (heap != JKRHeap::getSystemHeap()) {
heapBar(heap, posX, posY, barHeight, width, height);
}
}
}
}
+431
View File
@@ -0,0 +1,431 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTResFont.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JSupport/JSupport.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTConsole.h"
#include <gx.h>
JUTResFont::JUTResFont() {
initialize_state();
JUTFont::initialize_state();
}
JUTResFont::JUTResFont(const ResFONT* pFont, JKRHeap* pHeap) {
initialize_state();
JUTFont::initialize_state();
initiate(pFont, pHeap);
}
JUTResFont::~JUTResFont() {
if (mValid) {
delete_and_initialize();
JUTFont::initialize_state();
}
}
void JUTResFont::deleteMemBlocks_ResFont() {
delete[] mMemBlocks;
}
void JUTResFont::initialize_state() {
mResFont = NULL;
mMemBlocks = NULL;
mpWidthBlocks = NULL;
mpGlyphBlocks = NULL;
mpMapBlocks = NULL;
mWidth = 0;
mHeight = 0;
mTexPageIdx = -1;
}
bool JUTResFont::initiate(const ResFONT* pFont, JKRHeap* pHeap) {
if (!protected_initiate(pFont, pHeap)) {
delete_and_initialize();
JUTFont::initialize_state();
mValid = false;
return false;
}
return true;
}
bool JUTResFont::protected_initiate(const ResFONT* pFont, JKRHeap* pHeap) {
void** p;
delete_and_initialize();
JUTFont::initialize_state();
if (!pFont) {
return false;
}
mResFont = pFont;
mValid = true;
countBlock();
mMemBlocks = new (pHeap, 0) void*[mWid1BlockNum + mGly1BlockNum + mMap1BlockNum];
if (!mMemBlocks) {
return false;
}
p = mMemBlocks;
if (mWid1BlockNum != 0) {
mpWidthBlocks = new (p) ResFONT::WID1*[mWid1BlockNum];
p += mWid1BlockNum;
}
if (mGly1BlockNum != 0) {
mpGlyphBlocks = new (p) ResFONT::GLY1*[mGly1BlockNum];
p += mGly1BlockNum;
}
if (mMap1BlockNum != 0) {
mpMapBlocks = new (p) ResFONT::MAP1*[mMap1BlockNum];
}
setBlock();
return true;
}
void JUTResFont::countBlock() {
mWid1BlockNum = 0;
mGly1BlockNum = 0;
mMap1BlockNum = 0;
u8* pData = (u8*)&mResFont->data;
for (u32 i = 0; i < mResFont->numBlocks; i++) {
switch (((BlockHeader*)pData)->magic) {
case 'WID1':
mWid1BlockNum++;
break;
case 'GLY1':
mGly1BlockNum++;
break;
case 'MAP1':
mMap1BlockNum++;
break;
case 'INF1':
break;
default:
JUTReportConsole("JUTResFont: Unknown data block\n");
}
pData += ((BlockHeader*)pData)->size;
}
}
IsLeadByte_func const JUTResFont::saoAboutEncoding_[3] = {
JUTFont::isLeadByte_1Byte,
JUTFont::isLeadByte_2Byte,
JUTFont::isLeadByte_ShiftJIS,
};
void JUTResFont::setBlock() {
s32 widthNum = 0;
s32 glyphNum = 0;
s32 mapNum = 0;
u32 u;
mMaxCode = -1;
BlockHeader* data = (BlockHeader*)mResFont->data;
for (u32 i = 0; i < mResFont->numBlocks; i++) {
switch (data->magic) {
case 'INF1': {
mInf1Ptr = (ResFONT::INF1*)data;
u = mInf1Ptr->fontType;
JUT_ASSERT(244, u < suAboutEncoding_);
mIsLeadByte = &saoAboutEncoding_[u];
break;
}
case 'WID1':
mpWidthBlocks[widthNum] = (ResFONT::WID1*)data;
widthNum++;
break;
case 'GLY1':
mpGlyphBlocks[glyphNum] = (ResFONT::GLY1*)data;
glyphNum++;
break;
case 'MAP1':
mpMapBlocks[mapNum] = (ResFONT::MAP1*)data;
if (mMaxCode > mpMapBlocks[mapNum]->startCode) {
mMaxCode = mpMapBlocks[mapNum]->startCode;
}
mapNum++;
break;
default:
JUTReportConsole("Unknown data block\n");
break;
}
data = (BlockHeader*)(((Ptr)data) + data->size);
}
}
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 col1, JUtility::TColor col2) {
if (col1 == 0 && col2 == -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, col1);
GXSetTevColor(GX_TEVREG1, col2);
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_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);
}
}
f32 JUTResFont::drawChar_scale(f32 pos_x, f32 pos_y, f32 scale_x, f32 scale_y, int str_int,
bool flag) {
f32 x1;
f32 x2;
f32 y1;
JUT_ASSERT(378, mValid);
JUTFont::TWidth width;
loadFont(str_int, GX_TEXMAP0, &width);
if ((mFixed) || (!flag)) {
x1 = pos_x;
} else {
x1 = (pos_x - width.field_0x0 * (scale_x / getCellWidth()));
}
f32 retval = mFixedWidth * (scale_x / getCellWidth());
if (mFixed == false) {
if (!flag) {
retval = (width.field_0x1 + width.field_0x0) * (scale_x / getCellWidth());
} else {
retval = width.field_0x1 * (scale_x / getCellWidth());
}
}
x2 = x1 + scale_x;
y1 = pos_y - getAscent() * (scale_y / getHeight());
f32 y2 = getDescent() * (scale_y / getHeight()) + pos_y;
s32 u1 = (mWidth * 0x8000) / mpGlyphBlocks[field_0x66]->textureWidth;
s32 v1 = (mHeight * 0x8000) / mpGlyphBlocks[field_0x66]->textureHeight;
s32 u2 = ((mWidth + mpGlyphBlocks[field_0x66]->cellWidth) * 0x8000) / mpGlyphBlocks[field_0x66]->textureWidth;
s32 v2 = ((mHeight + mpGlyphBlocks[field_0x66]->cellHeight) * 0x8000) / mpGlyphBlocks[field_0x66]->textureHeight;
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
// Bottom Left
GXPosition3f32(x1, y1, 0.0f);
GXColor1u32(mColor1);
GXTexCoord2u16(u1, v1);
// Bottom Right
GXPosition3f32(x2, y1, 0.0f);
GXColor1u32(mColor2);
GXTexCoord2u16(u2, v1);
// Top Right
GXPosition3f32(x2, y2, 0.0f);
GXColor1u32(mColor4);
GXTexCoord2u16(u2, v2);
// Top Left
GXPosition3f32(x1, y2, 0.0f);
GXColor1u32(mColor3);
GXTexCoord2u16(u1, v2);
GXEnd();
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
return retval;
}
void JUTResFont::loadFont(int code, GXTexMapID texMapID, JUTFont::TWidth* pDstWidth) {
if (pDstWidth != 0) {
getWidthEntry(code, pDstWidth);
}
int fontCode = getFontCode(code);
loadImage(fontCode, texMapID);
}
void JUTResFont::getWidthEntry(int code, JUTFont::TWidth* i_width) const {
int fontCode = getFontCode(code);
i_width->field_0x0 = 0;
i_width->field_0x1 = mInf1Ptr->width;
for (int i = 0; i < mWid1BlockNum; i++) {
if (mpWidthBlocks[i]->startCode <= fontCode && fontCode <= mpWidthBlocks[i]->endCode) {
*i_width = *(JUTFont::TWidth*)&mpWidthBlocks[i]->mChunkNum[(fontCode - mpWidthBlocks[i]->startCode) * 2];
break;
}
}
}
s32 JUTResFont::getCellWidth() const {
if (mpGlyphBlocks) {
if (mpGlyphBlocks[0]) {
return mpGlyphBlocks[0]->cellWidth;
}
}
return getWidth();
}
s32 JUTResFont::getCellHeight() const {
if (mpGlyphBlocks) {
if (mpGlyphBlocks[0]) {
return mpGlyphBlocks[0]->cellHeight;
}
}
return getHeight();
}
bool JUTResFont::isLeadByte(int chr) const {
return (*mIsLeadByte)(chr);
}
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 = mInf1Ptr->defaultCode;
if ((getFontType() == 2) && (mMaxCode >= 0x8000U) && (chr >= 0x20) && (chr < 0x7FU)) {
chr = (halftofull - 0x20)[chr];
}
for (int i = 0; i < mMap1BlockNum; i++) {
if ((mpMapBlocks[i]->startCode <= chr) && (chr <= mpMapBlocks[i]->endCode)) {
if (mpMapBlocks[i]->mappingMethod == 0) {
ret = chr - mpMapBlocks[i]->startCode;
} else if (mpMapBlocks[i]->mappingMethod == 2) {
u16* leading_temp = &mpMapBlocks[i]->mLeading;
ret = leading_temp[chr - mpMapBlocks[i]->startCode];
} else if (mpMapBlocks[i]->mappingMethod == 3) {
// invented struct to help match debug, unsure of real struct
struct paired_u16 {
u16 fullChar;
u16 fontCode;
};
paired_u16* leading_temp = (paired_u16*)&mpMapBlocks[i]->mLeading;
int binarySearchMin = 0;
int binarySearchMax = mpMapBlocks[i]->numEntries - 1;
while (binarySearchMax >= binarySearchMin) {
int midIndex = (binarySearchMax + binarySearchMin) / 2;
if (chr < leading_temp[midIndex].fullChar) {
binarySearchMax = midIndex - 1;
} else if (chr > leading_temp[midIndex].fullChar) {
binarySearchMin = midIndex + 1;
} else {
ret = leading_temp[midIndex].fontCode;
break;
}
}
} else if (mpMapBlocks[i]->mappingMethod == 1) {
u16* phi_r5_2 = NULL;
if (mpMapBlocks[i]->numEntries == 1) {
phi_r5_2 = &mpMapBlocks[i]->mLeading;
}
ret = convertSjis(chr, phi_r5_2);
}
break;
}
}
return ret;
}
void JUTResFont::loadImage(int code, GXTexMapID id){
int i = 0;
for (; i < mGly1BlockNum; i++)
{
if (mpGlyphBlocks[i]->startCode <= code && code <= mpGlyphBlocks[i]->endCode)
{
code -= mpGlyphBlocks[i]->startCode;
break;
}
}
if (i != mGly1BlockNum) {
s32 pageNumCells = mpGlyphBlocks[i]->numRows * mpGlyphBlocks[i]->numColumns;
s32 pageIdx = code / pageNumCells;
s32 cellIdxInPage = code - pageIdx * pageNumCells;
s32 cellRow = (cellIdxInPage / mpGlyphBlocks[i]->numRows);
s32 cellCol = (cellIdxInPage - cellRow * mpGlyphBlocks[i]->numRows);
mWidth = cellCol * mpGlyphBlocks[i]->cellWidth;
mHeight = cellRow * mpGlyphBlocks[i]->cellHeight;
if (pageIdx != mTexPageIdx || i != field_0x66)
{
void* pImg = &mpGlyphBlocks[i]->data[pageIdx * mpGlyphBlocks[i]->textureSize];
GXInitTexObj(&mTexObj, pImg, mpGlyphBlocks[i]->textureWidth,
mpGlyphBlocks[i]->textureHeight, (GXTexFmt)mpGlyphBlocks[i]->textureFormat,
GX_CLAMP, GX_CLAMP, 0);
GXInitTexObjLOD(&mTexObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0U, 0U, GX_ANISO_1);
mTexPageIdx = pageIdx;
field_0x66 = i;
}
GXLoadTexObj(&mTexObj, id);
}
}
int JUTResFont::convertSjis(int inChr, u16* inLead) const {
int r29;
int tmp = JSUHiByte(inChr);
int tmp2 = JSULoByte(inChr) - 0x40;
if (0x40 <= tmp2) {
tmp2--;
}
u16 lead = 0x31c;
if (inLead) {
lead = *inLead;
}
r29 = tmp2 + (tmp - 0x88) * 0xbc + -0x5e + lead;
return r29;
}
+54
View File
@@ -0,0 +1,54 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTResource.h"
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JSupport/JSUInputStream.h"
#include <cstring>
void* JUTResReference::getResource(JSUInputStream* stream, u32 resType, JKRArchive* archive) {
stream->read(mType);
stream->read(mNameLength);
stream->read(&mName, mNameLength);
if (mType == RESTYPE_Unk2 || mType == RESTYPE_Unk3 || mType == RESTYPE_Unk4) {
mName[mNameLength] = 0;
}
return getResource(resType, archive);
}
void* JUTResReference::getResource(const void* data, u32 resType, JKRArchive* archive) {
const u8* pData = (const u8*)data;
mType = pData[0];
mNameLength = pData[1];
if (mNameLength != 0) {
memcpy(&mName, &pData[2], mNameLength);
}
if (mType == RESTYPE_Unk2 || mType == RESTYPE_Unk3 || mType == RESTYPE_Unk4) {
mName[mNameLength] = 0;
}
return getResource(resType, archive);
}
void* JUTResReference::getResource(u32 resType, JKRArchive* archive) {
void* res = NULL;
switch (mType) {
case RESTYPE_Unk1:
break;
case RESTYPE_Unk2:
res = JKRGetTypeResource(resType, mName, archive);
break;
case RESTYPE_Unk3:
res = JKRGetNameResource(mName, archive);
break;
case RESTYPE_Unk4:
res = JKRGetResource(mName);
break;
}
return res;
}
+164
View File
@@ -0,0 +1,164 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTTexture.h"
#include "JSystem/JUtility/JUTPalette.h"
#include <gx.h>
JUTTexture::~JUTTexture() {
if (getCaptureFlag()) {
delete[] field_0x3c;
}
if (getEmbPaletteDelFlag()) {
delete mEmbPalette;
}
}
void JUTTexture::storeTIMG(ResTIMG const* param_0, u8 param_1) {
if (param_0 && param_1 < 0x10) {
mTexInfo = param_0;
mTexData = (void*)((intptr_t)mTexInfo + mTexInfo->imageOffset);
if (mTexInfo->imageOffset == 0) {
mTexData = (void*)((intptr_t)mTexInfo + 0x20);
}
field_0x2c = NULL;
mTlutName = 0;
mWrapS = mTexInfo->wrapS;
mWrapT = mTexInfo->wrapT;
mMinFilter = mTexInfo->minFilter;
mMagFilter = mTexInfo->magFilter;
mMinLOD = (s8)mTexInfo->minLOD;
mMaxLOD = (s8)mTexInfo->maxLOD;
mLODBias = mTexInfo->LODBias;
if (mTexInfo->numColors == 0) {
initTexObj();
} else {
GXTlut tlut;
if (mTexInfo->numColors > 0x100) {
tlut = (GXTlut)((param_1 % 4) + GX_BIGTLUT0);
} else {
tlut = (GXTlut)param_1;
}
if (mEmbPalette == NULL || !getEmbPaletteDelFlag()) {
mEmbPalette = new JUTPalette(tlut, (GXTlutFmt)mTexInfo->colorFormat,
(JUTTransparency)mTexInfo->alphaEnabled, mTexInfo->numColors,
(void*)(&mTexInfo->format + mTexInfo->paletteOffset));
setEmbPaletteDelFlag(true);
} else {
mEmbPalette->storeTLUT(tlut, (GXTlutFmt)mTexInfo->colorFormat,
(JUTTransparency)mTexInfo->alphaEnabled, mTexInfo->numColors,
(void*)(&mTexInfo->format + mTexInfo->paletteOffset));
}
attachPalette(mEmbPalette);
}
}
}
void JUTTexture::storeTIMG(ResTIMG const* param_0, JUTPalette* param_1) {
GXTlut type;
if (param_1 != NULL) {
type = param_1->getTlutName();
} else {
type = GX_TLUT0;
}
storeTIMG(param_0, param_1, type);
}
void JUTTexture::storeTIMG(ResTIMG const* param_0, JUTPalette* param_1, GXTlut param_2) {
GXTlut type;
if (param_0 == NULL) {
return;
}
mTexInfo = param_0;
mTexData = ((u8*)mTexInfo) + mTexInfo->imageOffset;
if (mTexInfo->imageOffset == 0) {
mTexData = ((u8*)mTexInfo) + sizeof(ResTIMG);
}
if (getEmbPaletteDelFlag()) {
delete mEmbPalette;
}
mEmbPalette = param_1;
setEmbPaletteDelFlag(false);
field_0x2c = NULL;
if (param_1 != NULL) {
mTlutName = param_2;
if (param_2 != param_1->getTlutName()) {
GXTlutFmt format = param_1->getFormat();
JUTTransparency transperancy = param_1->getTransparency();
u16 numColors = param_1->getNumColors();
ResTLUT* colorTable = param_1->getColorTable();
param_1->storeTLUT(param_2, format, transperancy, numColors, colorTable);
}
}
mWrapS = mTexInfo->wrapS;
mWrapT = mTexInfo->wrapT;
mMinFilter = mTexInfo->minFilter;
mMagFilter = mTexInfo->magFilter;
mMinLOD = mTexInfo->minLOD;
mMaxLOD = mTexInfo->maxLOD;
mLODBias = mTexInfo->LODBias;
init();
}
void JUTTexture::attachPalette(JUTPalette* param_0) {
if (mTexInfo->indexTexture) {
if (param_0 == NULL && mEmbPalette != NULL) {
field_0x2c = mEmbPalette;
} else {
field_0x2c = param_0;
}
initTexObj(field_0x2c->getTlutName());
}
}
void JUTTexture::init() {
if (mTexInfo->numColors == 0) {
initTexObj();
} else {
if (mEmbPalette != NULL) {
field_0x2c = mEmbPalette;
initTexObj(field_0x2c->getTlutName());
} else {
OS_REPORT("This texture is CI-Format, but EmbPalette is NULL.\n");
}
}
}
void JUTTexture::initTexObj() {
GXBool mipmapEnabled = mTexInfo->mipmapEnabled != 0 ? GX_TRUE : GX_FALSE;
u8* image = ((u8*)mTexInfo);
image += (mTexInfo->imageOffset ? mTexInfo->imageOffset : 0x20);
GXInitTexObj(&mTexObj, image, mTexInfo->width, mTexInfo->height,
(GXTexFmt)mTexInfo->format, (GXTexWrapMode)mWrapS,
(GXTexWrapMode)mWrapT, mipmapEnabled);
GXInitTexObjLOD(&mTexObj, (GXTexFilter)mMinFilter, (GXTexFilter)mMagFilter,
mMinLOD / 8.0f, mMaxLOD / 8.0f, mLODBias / 100.0f, mTexInfo->biasClamp,
mTexInfo->doEdgeLOD, (GXAnisotropy)mTexInfo->maxAnisotropy);
}
void JUTTexture::initTexObj(GXTlut param_0) {
GXBool mipmapEnabled = mTexInfo->mipmapEnabled != 0 ? GX_TRUE : GX_FALSE;
mTlutName = param_0;
u8* image = ((u8*)mTexInfo);
image += (mTexInfo->imageOffset ? mTexInfo->imageOffset : 0x20);
GXInitTexObjCI(&mTexObj, image, mTexInfo->width, mTexInfo->height,
(GXCITexFmt)mTexInfo->format, (GXTexWrapMode)mWrapS,
(GXTexWrapMode)mWrapT, mipmapEnabled, param_0);
GXInitTexObjLOD(&mTexObj, (GXTexFilter)mMinFilter, (GXTexFilter)mMagFilter,
mMinLOD / 8.0f, mMaxLOD / 8.0f, mLODBias / 100.0f, mTexInfo->biasClamp,
mTexInfo->doEdgeLOD, (GXAnisotropy)mTexInfo->maxAnisotropy);
}
void JUTTexture::load(GXTexMapID param_0) {
if (field_0x2c) {
field_0x2c->load();
}
GXLoadTexObj(&mTexObj, param_0);
}
+199
View File
@@ -0,0 +1,199 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTVideo.h"
#include "JSystem/JUtility/JUTDirectPrint.h"
#include "JSystem/JUtility/JUTXfb.h"
#include <gx.h>
#include <vi.h>
JUTVideo* JUTVideo::sManager;
OSTick JUTVideo::sVideoLastTick;
OSTick JUTVideo::sVideoInterval;
static bool data_80451544;
JUTVideo* JUTVideo::createManager(_GXRenderModeObj const* param_0) {
if (sManager == NULL) {
sManager = new JUTVideo(param_0);
}
return sManager;
}
void JUTVideo::destroyManager() {
if (sManager != NULL) {
delete sManager;
sManager = NULL;
}
}
JUTVideo::JUTVideo(GXRenderModeObj const* param_0) {
mRenderObj = NULL;
VIInit();
mSetBlack = true;
mSetBlackFrameCount = 2;
setRenderMode(param_0);
VISetBlack(1);
VIFlush();
field_0x8 = 0;
mRetraceCount = VIGetRetraceCount();
field_0x10 = 1;
field_0x18 = 0;
sVideoLastTick = OSGetTick();
sVideoInterval = 670000;
mPreRetraceCallback = VISetPreRetraceCallback(preRetraceProc);
mPostRetraceCallback = VISetPostRetraceCallback(postRetraceProc);
mPreCallback = NULL;
mPostCallback = NULL;
OSInitMessageQueue(&mMessageQueue, &mMessage, 1);
GXSetDrawDoneCallback(drawDoneCallback);
}
JUTVideo::~JUTVideo() {
VISetPreRetraceCallback(mPreRetraceCallback);
VISetPostRetraceCallback(mPostRetraceCallback);
}
void JUTVideo::preRetraceProc(u32 retrace_count) {
#if PLATFORM_GCN
if (!sManager) {
return;
}
#endif
if (sManager->mPreCallback) {
(*sManager->mPreCallback)(retrace_count);
}
OSTick tick = OSGetTick();
sVideoInterval = tick - sVideoLastTick;
sVideoLastTick = tick;
JUTXfb* xfb = JUTXfb::getManager();
if (!xfb) {
VISetBlack(TRUE);
VIFlush();
return;
}
static void* frameBuffer = NULL;
if (frameBuffer) {
const GXRenderModeObj* renderMode = JUTGetVideoManager()->getRenderMode();
u16 width = renderMode->fbWidth;
u16 height = renderMode->efbHeight;
JUTDirectPrint::getManager()->changeFrameBuffer(frameBuffer, width, height);
}
if (getManager()->mSetBlack == 1) {
s32 frame_count = getManager()->mSetBlackFrameCount;
if (frame_count > 0) {
frame_count--;
}
getManager()->mSetBlackFrameCount = frame_count;
getManager()->mSetBlack = frame_count ? true : false;
VISetBlack(TRUE);
VIFlush();
return;
}
if (!xfb) {
VISetBlack(TRUE);
VIFlush();
return;
}
if (xfb->getBufferNum() == 3 || xfb->getBufferNum() == 2) {
if (!data_80451544) {
s16 index = xfb->getDrawnXfbIndex();
xfb->setDisplayingXfbIndex(index);
if (index < 0) {
VISetBlack(1);
VIFlush();
} else {
VISetNextFrameBuffer(xfb->getDisplayingXfb());
VIFlush();
VISetBlack(FALSE);
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();
if (VIGetNextFrameBuffer()) {
VISetBlack(FALSE);
}
} else {
VISetBlack(TRUE);
}
}
VIFlush();
}
}
void JUTVideo::drawDoneStart() {
data_80451544 = true;
GXSetDrawDone();
}
void JUTVideo::dummyNoDrawWait() {
data_80451544 = false;
}
void JUTVideo::drawDoneCallback() {
JUTXfb* xfb = JUTXfb::getManager();
if (!xfb) {
return;
}
data_80451544 = false;
if (xfb->getBufferNum() == 1) {
if (xfb->getSDrawingFlag() == 1) {
xfb->setSDrawingFlag(0);
if (xfb->getDrawnXfb()) {
VISetNextFrameBuffer(xfb->getDrawnXfb());
VIFlush();
}
}
}
}
void JUTVideo::postRetraceProc(u32 retrace_count) {
#if PLATFORM_GCN
if (!sManager) {
return;
}
#endif
if (sManager->mPostCallback != NULL) {
sManager->mPostCallback(retrace_count);
}
OSSendMessage(&sManager->mMessageQueue, (OSMessage)(uintptr_t)VIGetRetraceCount(), OS_MESSAGE_NOBLOCK);
}
void JUTVideo::setRenderMode(GXRenderModeObj const* pObj) {
if (mRenderObj != NULL && pObj->viTVmode != mRenderObj->viTVmode) {
mSetBlack = true;
mSetBlackFrameCount = 4;
}
mRenderObj = (GXRenderModeObj*)pObj;
VIConfigure(mRenderObj);
VIFlush();
if (mSetBlack) {
VIWaitForRetrace();
VIWaitForRetrace();
}
}
void JUTVideo::waitRetraceIfNeed() {}
+90
View File
@@ -0,0 +1,90 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/JUtility/JUTXfb.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include <gx.h>
void JUTXfb::clearIndex() {
mDrawingXfbIndex = -1;
mDrawnXfbIndex = -1;
mDisplayingXfbIndex = -1;
}
void JUTXfb::common_init(int bufNum) {
mBufferNum = bufNum;
clearIndex();
mSDrawingFlag = 99;
}
JUTXfb::JUTXfb(GXRenderModeObj const* pObj, JKRHeap* pHeap, JUTXfb::EXfbNumber xfbNum) {
common_init(xfbNum);
if (pObj) {
initiate(pObj->fbWidth, pObj->xfbHeight, pHeap, xfbNum);
} else {
u16 fbWidth = (u32)JUTVideo::getManager()->getRenderMode()->fbWidth;
u16 xfbHeight = (u32)JUTVideo::getManager()->getRenderMode()->xfbHeight;
u16 efbHeight = (u32)JUTVideo::getManager()->getRenderMode()->efbHeight;
f32 scale_factor = GXGetYScaleFactor(efbHeight, xfbHeight);
u16 xfb_lines = GXGetNumXfbLines(efbHeight, scale_factor);
initiate(fbWidth, xfb_lines, pHeap, xfbNum);
}
}
JUTXfb* JUTXfb::sManager;
JUTXfb::~JUTXfb() {
for (int i = 0; i < 3; i++) {
delXfb(i);
}
sManager = NULL;
}
void JUTXfb::delXfb(int xfbIdx) {
if (mXfbAllocated[xfbIdx] && mBuffer[xfbIdx]) {
delete mBuffer[xfbIdx];
}
}
JUTXfb* JUTXfb::createManager(JKRHeap* pHeap, JUTXfb::EXfbNumber xfbNum) {
JUT_CONFIRM(273, sManager == NULL);
if (sManager == NULL) {
sManager = new JUTXfb(NULL, pHeap, xfbNum);
}
return sManager;
}
void JUTXfb::destroyManager() {
JUT_CONFIRM(344, sManager);
delete sManager;
sManager = NULL;
}
void JUTXfb::initiate(u16 width, u16 height, JKRHeap* pHeap, JUTXfb::EXfbNumber xfbNum) {
if (pHeap == NULL) {
pHeap = JKRGetSystemHeap();
}
int size = (u16)((u16)width + 0xf & ~0xf) * height * 2;
mBuffer[0] = new (pHeap, 0x20) u8[size];
mXfbAllocated[0] = true;
if (xfbNum >= 2) {
mBuffer[1] = new (pHeap, 0x20) u8[size];
mXfbAllocated[1] = true;
} else {
mBuffer[1] = NULL;
mXfbAllocated[1] = false;
}
if (xfbNum >= 3) {
mBuffer[2] = new (pHeap, 0x20) u8[size];
mXfbAllocated[2] = true;
} else {
mBuffer[2] = NULL;
mXfbAllocated[2] = false;
}
}