// // Generated by dtk // Translation Unit: JUTCacheFont.cpp // #include "JSystem/JUtility/JUTCacheFont.h" #include "JSystem/JKernel/JKRAram.h" #include "JSystem/JUtility/JUTAssert.h" #include "JSystem/JUtility/JUTConsole.h" #include "JSystem/JUtility/JUTDataHeader.h" #include "dolphin/gx/GX.h" /* 802C03D4-802C0454 .text __ct__12JUTCacheFontFPC7ResFONTUlP7JKRHeap */ JUTCacheFont::JUTCacheFont(const ResFONT* p_fontRes, u32 cacheSize, JKRHeap* p_heap) { initialize_state(); JUTResFont::initialize_state(); JUTFont::initialize_state(); initiate(p_fontRes, NULL, cacheSize, p_heap); } /* 802C0454-802C04E8 .text __dt__12JUTCacheFontFv */ JUTCacheFont::~JUTCacheFont() { if (isValid()) { deleteMemBlocks_CacheFont(); initialize_state(); deleteMemBlocks_ResFont(); JUTResFont::initialize_state(); JUTFont::initialize_state(); } } /* 802C04E8-802C056C .text deleteMemBlocks_CacheFont__12JUTCacheFontFv */ void JUTCacheFont::deleteMemBlocks_CacheFont() { if (field_0xb0 != 0) { delete[] mCacheBuffer; } delete field_0xac; delete mInfoBlock; delete mpMemBlocks; delete field_0x7c; delete field_0x80; delete field_0x84; } /* 802C056C-802C05A8 .text initialize_state__12JUTCacheFontFv */ void JUTCacheFont::initialize_state() { field_0xb0 = 0; mCacheBuffer = NULL; field_0xac = NULL; mInfoBlock = NULL; field_0x7c = NULL; field_0x80 = NULL; field_0x84 = NULL; mpMemBlocks = NULL; mPagingType = PAGE_TYPE_0; mMaxSheetSize = 0; mCacheBuffer = NULL; field_0x9c = NULL; field_0xa0 = NULL; } /* 802C05A8-802C0738 .text getMemorySize__12JUTCacheFontFPC7ResFONTPUsPUlPUsPUlPUsPUlPUl */ int JUTCacheFont::getMemorySize(const ResFONT* 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; u32 glyTexSize; u8* fontInf = (u8*)p_font->data; for (int i = 0; i < p_font->numBlocks; i++) { switch (((JUTDataBlockHeader*)fontInf)->mType) { case 'INF1': break; case 'WID1': totalWidSize += ((JUTDataBlockHeader*)fontInf)->mSize; widBlockCount++; break; case 'GLY1': totalGlySize += ((JUTDataBlockHeader*)fontInf)->mSize; glyTexSize = ((ResFONT::GLY1*)fontInf)->textureSize; glyBlockCount++; if (glyTexSize > maxGlyTexSize) { maxGlyTexSize = glyTexSize; } break; case 'MAP1': totalMapSize += ((JUTDataBlockHeader*)fontInf)->mSize; mapBlockCount++; break; default: JUTReportConsole("JUTCacheFont: Unknown data block\n"); break; } fontInf += ((JUTDataBlockHeader*)fontInf)->mSize; } 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; } /* 802C0738-802C0798 .text initiate__12JUTCacheFontFPC7ResFONTPvUlP7JKRHeap */ int JUTCacheFont::initiate(const ResFONT* 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; } /* 802C0798-802C089C .text internal_initiate__12JUTCacheFontFPC7ResFONTPvUlP7JKRHeap */ bool JUTCacheFont::internal_initiate(const ResFONT* p_fontRes, void* param_1, u32 param_2, JKRHeap* param_3) { deleteMemBlocks_CacheFont(); initialize_state(); deleteMemBlocks_ResFont(); JUTResFont::initialize_state(); JUTFont::initialize_state(); if (p_fontRes == NULL) { return false; } mResFont = p_fontRes; mValid = true; getMemorySize(p_fontRes, &mWidthBlockNum, &mTotalWidSize, &mGlyphBlockNum, &mTotalGlySize, &mMapBlockNum, &mTotalMapSize, &mMaxSheetSize); if (!allocArea(param_1, param_2, param_3)) { return false; } else if (!allocArray(param_3)) { return false; } setBlock(); return true; } /* 802C089C-802C0A90 .text allocArea__12JUTCacheFontFPvUlP7JKRHeap */ bool JUTCacheFont::allocArea(void* cacheBuffer, u32 param_1, JKRHeap* heap) { mInfoBlock = (ResFONT::INF1*)new (heap, 0) ResFONT(); if (mInfoBlock == NULL) { return false; } if (mTotalWidSize != 0) { field_0x7c = new (heap, 0) u8[mTotalWidSize]; if (field_0x7c == NULL) { return false; } } if (mGlyphBlockNum != 0) { field_0x80 = new (heap, 0) u8[mGlyphBlockNum * sizeof(ResFONT::GLY1)]; if (field_0x80 == NULL) { return false; } field_0xac = JKRAram::getManager()->mAramHeap->alloc( mTotalGlySize - (mGlyphBlockNum * 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(351, ( (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; } /* 802C0A90-802C0B78 .text allocArray__12JUTCacheFontFP7JKRHeap */ bool JUTCacheFont::allocArray(JKRHeap* heap) { mpMemBlocks = (void**)new (heap, 0) u32[mWidthBlockNum + mGlyphBlockNum + mMapBlockNum]; if (mpMemBlocks == NULL) { return false; } void** blocks = mpMemBlocks; if (mWidthBlockNum) { mpWidthBlocks = (ResFONT::WID1**)blocks; blocks = blocks + mWidthBlockNum; } if (mGlyphBlockNum) { mpGlyphBlocks = (ResFONT::GLY1**)blocks; blocks = blocks + mGlyphBlockNum; for (int i = 0; i < mGlyphBlockNum; i++) { mpGlyphBlocks[i] = (ResFONT::GLY1*)((u8*)mCacheBuffer + (field_0x94 * i)); } } if (mMapBlockNum) { mpMapBlocks = (ResFONT::MAP1**)blocks; } return true; } /* 802C0B78-802C0DD0 .text setBlock__12JUTCacheFontFv */ 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++) { 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->mType = 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 */ 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(TGlyphCacheInfo* param_0, TCachePage* pCachePage, int* param_2, int* param_3) { 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 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); } } } /* 802C109C-802C11E4 .text loadCache_char_subroutine__12JUTCacheFontFPib */ JUTCacheFont::TCachePage* JUTCacheFont::loadCache_char_subroutine(int* param_0, bool param_1) { 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() { 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 */ 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; } } /* 802C12B0-802C12DC .text prepend__12JUTCacheFontFPQ212JUTCacheFont15TGlyphCacheInfo */ 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; } }