mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-02 16:16:20 -04:00
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:
@@ -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
|
||||
@@ -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(¶m_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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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() {}
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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() {}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user