mirror of
https://github.com/zeldaret/tww.git
synced 2026-06-14 06:04:22 -04:00
487 lines
15 KiB
C++
487 lines
15 KiB
C++
//
|
|
// 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 "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 (((BlockHeader*)fontInf)->magic) {
|
|
case 'INF1':
|
|
break;
|
|
case 'WID1':
|
|
totalWidSize += ((BlockHeader*)fontInf)->size;
|
|
widBlockCount++;
|
|
break;
|
|
case 'GLY1':
|
|
totalGlySize += ((BlockHeader*)fontInf)->size;
|
|
glyTexSize = ((ResFONT::GLY1*)fontInf)->textureSize;
|
|
glyBlockCount++;
|
|
if (glyTexSize > maxGlyTexSize) {
|
|
maxGlyTexSize = glyTexSize;
|
|
}
|
|
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;
|
|
}
|
|
|
|
/* 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->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 */
|
|
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) {
|
|
/* 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 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 */
|
|
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() {
|
|
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;
|
|
}
|
|
}
|