diff --git a/configure.py b/configure.py index a58b62871..14698874f 100644 --- a/configure.py +++ b/configure.py @@ -810,14 +810,14 @@ config.libs = [ JSystemLib( "JUtility", [ - Object(NonMatching, "JSystem/JUtility/JUTCacheFont.cpp"), + Object(Matching, "JSystem/JUtility/JUTCacheFont.cpp"), Object(Matching, "JSystem/JUtility/JUTResource.cpp"), Object(Matching, "JSystem/JUtility/JUTTexture.cpp"), Object(Matching, "JSystem/JUtility/JUTPalette.cpp"), Object(Matching, "JSystem/JUtility/JUTNameTab.cpp"), Object(Matching, "JSystem/JUtility/JUTGraphFifo.cpp"), Object(Matching, "JSystem/JUtility/JUTFont.cpp"), - Object(NonMatching, "JSystem/JUtility/JUTResFont.cpp"), + Object(Matching, "JSystem/JUtility/JUTResFont.cpp"), Object(Matching, "JSystem/JUtility/JUTDbPrint.cpp"), Object(NonMatching, "JSystem/JUtility/JUTGamePad.cpp"), Object(NonMatching, "JSystem/JUtility/JUTException.cpp"), diff --git a/include/JSystem/JKernel/JKRAram.h b/include/JSystem/JKernel/JKRAram.h index a9f2564e4..f211a8a5a 100644 --- a/include/JSystem/JKernel/JKRAram.h +++ b/include/JSystem/JKernel/JKRAram.h @@ -69,7 +69,7 @@ private: static JSUList sAramCommandList; }; -inline void* JKRAllocFromAram(u32 size, JKRAramHeap::EAllocMode allocMode) { +inline JKRAramBlock* JKRAllocFromAram(u32 size, JKRAramHeap::EAllocMode allocMode) { return JKRAram::getAramHeap()->alloc(size, allocMode); } @@ -77,9 +77,9 @@ inline void JKRFreeToAram(JKRAramBlock* block) { JKRAram::getAramHeap()->free(block); } -inline void JKRAramToMainRam(u32 p1, u8* p2, u32 p3, JKRExpandSwitch p4, u32 p5, JKRHeap* p6, +inline u8* JKRAramToMainRam(u32 p1, u8* p2, u32 p3, JKRExpandSwitch p4, u32 p5, JKRHeap* p6, int p7, u32* p8) { - JKRAram::aramToMainRam(p1, p2, p3, p4, p5, p6, p7, p8); + return JKRAram::aramToMainRam(p1, p2, p3, p4, p5, p6, p7, p8); } inline JKRAramBlock *JKRMainRamToAram(u8 *buf, u32 bufSize, u32 alignedSize, JKRExpandSwitch expandSwitch, u32 fileSize, JKRHeap *heap, int id) { diff --git a/include/JSystem/JUtility/JUTCacheFont.h b/include/JSystem/JUtility/JUTCacheFont.h index 4d39bae82..862250de5 100644 --- a/include/JSystem/JUtility/JUTCacheFont.h +++ b/include/JSystem/JUtility/JUTCacheFont.h @@ -11,21 +11,22 @@ public: struct TGlyphCacheInfo { /* 0x0 */ TGlyphCacheInfo* mPrev; /* 0x4 */ TGlyphCacheInfo* mNext; - }; - - struct TCachePage { - /* 0x00 */ u8 field_0x0[8]; - /* 0x08 */ s16 field_0x8; + /* 0x08 */ u16 field_0x8; /* 0x0A */ u16 field_0xa; - /* 0x0C */ u8 field_0xc[4]; - /* 0x10 */ u8* field_0x10; - /* 0x14 */ u16 field_0x14; + /* 0x0C */ u16 field_0xc; + /* 0x0E */ u16 field_0xe; + /* 0x10 */ u32 field_0x10; + /* 0x14 */ u16 mTexFormat; /* 0x16 */ u16 field_0x16; /* 0x18 */ u16 field_0x18; - /* 0x1A */ u16 field_0x1a; - /* 0x1C */ u16 field_0x1c; + /* 0x1A */ u16 mWidth; + /* 0x1C */ u16 mHeight; /* 0x1E */ u16 field_0x1e; - }; // Size: 0x20 + }; + + struct TCachePage : TGlyphCacheInfo { + /* 0x20 */ GXTexObj mTexObj; + }; // Size: 0x40 enum EPagingType { PAGE_TYPE_0, @@ -40,19 +41,19 @@ public: /* 802DD54C */ bool internal_initiate(ResFONT const*, void*, u32, JKRHeap*); /* 802DD650 */ bool allocArea(void*, u32, JKRHeap*); /* 802DD804 */ bool allocArray(JKRHeap*); - /* 802DDB0C */ void determineBlankPage(); - /* 802DDBBC */ void getGlyphFromAram(JUTCacheFont::TGlyphCacheInfo*, JUTCacheFont::TCachePage*, - int*, int*); - /* 802DDD98 */ void loadCache_char_subroutine(int*, bool); + /* 802DDB0C */ TGlyphCacheInfo* determineBlankPage(); + /* 802DDBBC */ void getGlyphFromAram(TGlyphCacheInfo*, TCachePage*, int*, int*); + /* 802DDD98 */ TCachePage* loadCache_char_subroutine(int*, bool); /* 802DDEE0 */ void invalidiateAllCache(); - /* 802DDF68 */ void unlink(JUTCacheFont::TGlyphCacheInfo*); - /* 802DDFAC */ void prepend(JUTCacheFont::TGlyphCacheInfo*); + /* 802DDF68 */ void unlink(TGlyphCacheInfo*); + /* 802DDFAC */ void prepend(TGlyphCacheInfo*); /* 802DD208 */ virtual ~JUTCacheFont(); /* 802DDCE4 */ virtual void loadImage(int, _GXTexMapID); /* 802DD8EC */ virtual void setBlock(); void setPagingType(EPagingType type) { mPagingType = type; } + GXTexObj* getTexObj(void* buffer) { return &((TCachePage*)buffer)->mTexObj; } static u32 calcCacheSize(u32 param_0, int param_1) { return (ALIGN_NEXT(param_0, 0x20) + 0x40) * param_1; } @@ -70,7 +71,7 @@ private: /* 0x98 */ u32 mCachePage; /* 0x9C */ TGlyphCacheInfo* field_0x9c; /* 0xA0 */ TGlyphCacheInfo* field_0xa0; - /* 0xA4 */ void* field_0xa4; + /* 0xA4 */ TGlyphCacheInfo* field_0xa4; /* 0xA8 */ u32 field_0xa8; /* 0xAC */ JKRAramBlock* field_0xac; /* 0xB0 */ u8 field_0xb0; diff --git a/include/JSystem/JUtility/JUTFont.h b/include/JSystem/JUtility/JUTFont.h index e91b9ed3a..17ab59ee8 100644 --- a/include/JSystem/JUtility/JUTFont.h +++ b/include/JSystem/JUtility/JUTFont.h @@ -80,7 +80,7 @@ public: /* 0x30 */ virtual int getCellWidth() const; /* 0x34 */ virtual s32 getCellHeight() const; /* 0x38 */ virtual int getFontType() const = 0; - /* 0x3C */ virtual const ResFONT* getResFont() = 0; + /* 0x3C */ virtual const ResFONT* getResFont() const = 0; /* 0x40 */ virtual bool isLeadByte(int a1) const = 0; static bool isLeadByte_1Byte(int b); diff --git a/include/JSystem/JUtility/JUTResFont.h b/include/JSystem/JUtility/JUTResFont.h index 34f23ff0b..f6b3d7d69 100644 --- a/include/JSystem/JUtility/JUTResFont.h +++ b/include/JSystem/JUtility/JUTResFont.h @@ -23,7 +23,7 @@ public: virtual int getCellWidth() const; virtual s32 getCellHeight() const; virtual int getFontType() const { return mInfoBlock->fontType; } - virtual const ResFONT* getResFont() { return mResFont; } + virtual const ResFONT* getResFont() const { return mResFont; } virtual bool isLeadByte(int) const; virtual void loadImage(int, _GXTexMapID); virtual void setBlock(); @@ -44,7 +44,8 @@ public: initialize_state(); } - static IsLeadByte_func const saoAboutEncoding_[3]; + static const int suAboutEncoding_ = 3; + static IsLeadByte_func const saoAboutEncoding_[suAboutEncoding_]; /* 0x1C */ int mWidth; /* 0x20 */ int mHeight; @@ -61,7 +62,7 @@ public: /* 0x64 */ u16 mMapBlockNum; /* 0x66 */ u16 field_0x66; /* 0x68 */ u16 mMaxCode; - /* 0x6C */ IsLeadByte_func* mIsLeadByte; + /* 0x6C */ const IsLeadByte_func* mIsLeadByte; }; #endif /* JUTRESFONT_H */ diff --git a/src/JSystem/JUtility/JUTCacheFont.cpp b/src/JSystem/JUtility/JUTCacheFont.cpp index 09c53c115..f859787b4 100644 --- a/src/JSystem/JUtility/JUTCacheFont.cpp +++ b/src/JSystem/JUtility/JUTCacheFont.cpp @@ -263,32 +263,197 @@ bool JUTCacheFont::allocArray(JKRHeap* heap) { /* 802C0B78-802C0DD0 .text setBlock__12JUTCacheFontFv */ void JUTCacheFont::setBlock() { - /* Nonmatching */ + 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++) { + switch (*pData) { + case 'INF1': + memcpy(mInfoBlock, pData, 0x20); + u32 u = mInfoBlock->fontType; + JUT_ASSERT(447, u < suAboutEncoding_); + mIsLeadByte = &JUTResFont::saoAboutEncoding_[u]; + break; + case 'WID1': + memcpy(pWidth, pData, pData[1]); + mpWidthBlocks[widthNum] = (ResFONT::WID1*)pWidth; + pWidth += pData[1]; + widthNum++; + break; + case 'GLY1': + memcpy(piVar5, pData, 0x20); + JKRAramBlock* iVar1 = + JKRMainRamToAram((u8*)pData + 0x20, aramAddress, pData[1] - 0x20, + EXPAND_SWITCH_UNKNOWN0, 0, NULL, 0xffffffff); + if (iVar1 == NULL) { + OSPanic(__FILE__, 476, "Cannot alloc ARAM area."); + } + piVar5->magic = aramAddress; + if (piVar5->textureSize > mMaxSheetSize) { + mMaxSheetSize = piVar5->textureSize; + } + mpGlyphBlocks[gylphNum] = piVar5; + gylphNum++; + piVar5++; + aramAddress = pData[1] + aramAddress - 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]); + } } /* 802C0DD0-802C0E80 .text determineBlankPage__12JUTCacheFontFv */ -void JUTCacheFont::determineBlankPage() { - /* Nonmatching */ +JUTCacheFont::TGlyphCacheInfo* JUTCacheFont::determineBlankPage() { + TGlyphCacheInfo* pVar1 = field_0xa4; + if (pVar1 != NULL) { + field_0xa4 = pVar1->mNext; + TGlyphCacheInfo* pVar2 = pVar1->mNext; + if (pVar2 == NULL) { + field_0xa8 = 0; + } else { + pVar2->mPrev = NULL; + } + return pVar1; + } + + TGlyphCacheInfo* puVar1 = field_0xa0; + while (puVar1 != NULL) { + TGlyphCacheInfo* prev = puVar1->mPrev; + if (puVar1->field_0x1e == 0) { + unlink(puVar1); + field_0xb4++; + return puVar1; + } + puVar1 = prev; + } + + return NULL; } /* 802C0E80-802C0FE8 .text getGlyphFromAram__12JUTCacheFontFPQ212JUTCacheFont15TGlyphCacheInfoPQ212JUTCacheFont10TCachePagePiPi */ -void JUTCacheFont::getGlyphFromAram(JUTCacheFont::TGlyphCacheInfo*, JUTCacheFont::TCachePage*, int*, int*) { +void JUTCacheFont::getGlyphFromAram(TGlyphCacheInfo* param_0, TCachePage* pCachePage, int* param_2, int* param_3) { /* Nonmatching */ + TGlyphCacheInfo* pGylphCacheInfo = pCachePage; + memcpy(pGylphCacheInfo, param_0, sizeof(TGlyphCacheInfo)); + prepend(pGylphCacheInfo); + int iVar3 = pGylphCacheInfo->field_0x16 * pGylphCacheInfo->field_0x18; + int iVar2 = *param_2 / iVar3; + 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; + *param_2 -= iVar2 * iVar3; + u8* result = + JKRAramToMainRam((u32)param_0->mPrev + pGylphCacheInfo->field_0x10 * iVar2, (u8*)(pCachePage + 1), + pGylphCacheInfo->field_0x10, EXPAND_SWITCH_UNKNOWN0, 0, NULL, 0xffffffff, NULL); + JUT_ASSERT(623, result); + GXInitTexObj(&pCachePage->mTexObj, pCachePage + 1, 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); } /* 802C0FE8-802C109C .text loadImage__12JUTCacheFontFi11_GXTexMapID */ -void JUTCacheFont::loadImage(int, _GXTexMapID) { +void JUTCacheFont::loadImage(int param_0, GXTexMapID texMapId) { /* Nonmatching */ + 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); + } + } } /* 802C109C-802C11E4 .text loadCache_char_subroutine__12JUTCacheFontFPib */ -void JUTCacheFont::loadCache_char_subroutine(int*, bool) { +JUTCacheFont::TCachePage* JUTCacheFont::loadCache_char_subroutine(int* param_0, bool param_1) { /* Nonmatching */ + TCachePage* rv = NULL; + for (TCachePage* pCachePage = (TCachePage*)field_0x9c; pCachePage != NULL; + pCachePage = (TCachePage*)pCachePage->mNext) + { + if (pCachePage->field_0x8 <= *param_0 && *param_0 <= pCachePage->field_0xa) { + rv = pCachePage; + *param_0 -= pCachePage->field_0x8; + break; + } + } + + if (rv == NULL) { + int i = 0; + for (; i < mGlyphBlockNum; i++) { + if (mpGlyphBlocks[i]->startCode <= *param_0 && *param_0 <= mpGlyphBlocks[i]->endCode) { + *param_0 -= mpGlyphBlocks[i]->startCode; + break; + } + } + if (i < mGlyphBlockNum) { + TCachePage* pBlankPage = (TCachePage*)determineBlankPage(); + if (pBlankPage == NULL) { + return NULL; + } + int texPageIdx; + getGlyphFromAram((JUTCacheFont::TGlyphCacheInfo*)mpGlyphBlocks[i], pBlankPage, param_0, + &texPageIdx); + mTexPageIdx = texPageIdx; + field_0x66 = i; + rv = pBlankPage; + } else { + return NULL; + } + } + if (param_1) { + rv->field_0x1e = 1; + } + return rv; } /* 802C11E4-802C126C .text invalidiateAllCache__12JUTCacheFontFv */ void JUTCacheFont::invalidiateAllCache() { - /* Nonmatching */ + int* piVar3 = (int*)mCacheBuffer; + for (int uVar2 = 0; uVar2 < mCachePage; uVar2++) { + int iVar1; + if (uVar2 == 0) { + iVar1 = 0; + } else { + iVar1 = (int)piVar3 - field_0x94; + } + *piVar3 = iVar1; + if (uVar2 == mCachePage - 1) { + iVar1 = 0; + } else { + iVar1 = (int)piVar3 + field_0x94; + } + piVar3[1] = iVar1; + piVar3 = (int*)((int)piVar3 + field_0x94); + } + field_0xa8 = (int)piVar3 - field_0x94; + field_0xa4 = (TGlyphCacheInfo*)mCacheBuffer; + field_0x9c = NULL; + field_0xa0 = NULL; } /* 802C126C-802C12B0 .text unlink__12JUTCacheFontFPQ212JUTCacheFont15TGlyphCacheInfo */ diff --git a/src/JSystem/JUtility/JUTResFont.cpp b/src/JSystem/JUtility/JUTResFont.cpp index 05f47a1a8..c1f0db9e6 100644 --- a/src/JSystem/JUtility/JUTResFont.cpp +++ b/src/JSystem/JUtility/JUTResFont.cpp @@ -11,9 +11,6 @@ #include "dolphin/gx/GX.h" #include "dolphin/types.h" -// Only used for an assert -#define suAboutEncoding_ 3 - IsLeadByte_func const JUTResFont::saoAboutEncoding_[3] = { isLeadByte_1Byte, isLeadByte_2Byte, @@ -220,7 +217,6 @@ void JUTResFont::setGX(JUtility::TColor col1, JUtility::TColor col2) { /* 802C28F8-802C2D6C .text drawChar_scale__10JUTResFontFffffib */ f32 JUTResFont::drawChar_scale(f32 posX, f32 posY, f32 scaleX, f32 scaleY, int chr, bool flag) { - /* Nonmatching */ JUTFont::TWidth width; f32 x1; f32 y1; @@ -294,7 +290,6 @@ void JUTResFont::loadFont(int code, _GXTexMapID texMapID, JUTFont::TWidth* pDstW /* 802C2DE8-802C2E90 .text getWidthEntry__10JUTResFontCFiPQ27JUTFont6TWidth */ void JUTResFont::getWidthEntry(int code, JUTFont::TWidth* width) const { - /* Nonmatching */ int fontCode = getFontCode(code); width->field_0x0 = 0; width->field_0x1 = mInfoBlock->width; @@ -339,7 +334,6 @@ bool JUTResFont::isLeadByte(int chr) const { /* 802C2F5C-802C30E4 .text getFontCode__10JUTResFontCFi */ int JUTResFont::getFontCode(int chr) const { - /* Nonmatching */ 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, @@ -356,15 +350,14 @@ int JUTResFont::getFontCode(int chr) const { if ((getFontType() == 2) && (mMaxCode >= 0x8000u) && (chr >= 0x20) && (chr < 0x7Fu)) { chr = halftofull[chr - 32]; } - int j = 0; - for (int i = mMapBlockNum; i > 0; j++, i--) { - if ((mpMapBlocks[j]->startCode <= chr) && (chr <= mpMapBlocks[j]->endCode)) { - ResFONT::MAP1* map = mpMapBlocks[j]; + for (int i = 0; i < mMapBlockNum; i++) { + if ((mpMapBlocks[i]->startCode <= chr) && (chr <= mpMapBlocks[i]->endCode)) { + ResFONT::MAP1* map = mpMapBlocks[i]; if (map->mappingMethod == 0) { ret = chr - map->startCode; break; } else if (map->mappingMethod == 2) { - ret = *(&mpMapBlocks[j]->mLeading + ((chr - mpMapBlocks[j]->startCode))); + ret = *(&mpMapBlocks[i]->mLeading + ((chr - mpMapBlocks[i]->startCode))); break; } else if (map->mappingMethod == 3) { u16* leading_temp = &map->mLeading; @@ -372,8 +365,7 @@ int JUTResFont::getFontCode(int chr) const { int phi_r6_2 = map->numEntries - 1; while (phi_r6_2 >= phi_r5) { - u32 temp_r3 = phi_r6_2 + phi_r5; - int temp_r7 = (int)((temp_r3 >> 0x1FU) + phi_r6_2 + phi_r5) >> 1; + int temp_r7 = (phi_r6_2 + phi_r5) / 2; if (chr < leading_temp[temp_r7 * 2]) { phi_r6_2 = temp_r7 - 1; @@ -393,7 +385,7 @@ int JUTResFont::getFontCode(int chr) const { if (map->numEntries == 1) { phi_r5_2 = &map->mLeading; } - ret = JUTResFont::convertSjis(chr, phi_r5_2); + ret = convertSjis(chr, phi_r5_2); break; } break;