#ifndef JUTFONT_H #define JUTFONT_H #include "types.h" #include "string.h" #include "dolphin/gx.h" #include "dolphin/os.h" #include "JSystem/JUtility/TColor.h" #ifdef __cplusplus struct JKRAramBlock; struct JKRHeap; struct ResFONT; struct JUTFont { typedef bool (*IsLeadByte)(int); struct TWidth { u8 w0; u8 w1; const TWidth& operator=(const TWidth& other) { w0 = other.w0; w1 = other.w1; return *this; } }; JUTFont(); virtual ~JUTFont() { } // _08 virtual void setGX() = 0; // _0C virtual void setGX(JUtility::TColor, JUtility::TColor) { setGX(); }; // _10 virtual f32 drawChar_scale(f32, f32, f32, f32, int, bool) = 0; // _14 virtual int getLeading() const = 0; // _18 virtual int getAscent() const = 0; // _1C virtual int getDescent() const = 0; // _20 virtual int getHeight() const = 0; // _24 virtual int getWidth() const = 0; // _28 virtual void getWidthEntry(int, JUTFont::TWidth*) const = 0; // _2C virtual int getCellWidth() const { return getWidth(); }; // _30 virtual int getCellHeight() const { return getHeight(); }; // _34 virtual int getFontType() const = 0; // _38 virtual const ResFONT* getResFont() const = 0; // _3C virtual bool isLeadByte(int) const = 0; // _40 void initialize_state(); void setCharColor(JUtility::TColor); void setGradColor(JUtility::TColor, JUtility::TColor); f32 drawString_size_scale(f32, f32, f32, f32, const char*, u32, bool); void drawString(int posX, int posY, const char* str, bool visible) { drawString_size(posX, posY, str, strlen(str), visible); } void drawString_size(int posX, int posY, const char* str, u32 len, bool visible) { drawString_size_scale(posX, posY, getWidth(), getHeight(), str, len, visible); } void drawString_scale(f32 posX, f32 posY, f32 width, f32 height, const char* str, bool visible) { drawString_size_scale(posX, posY, width, height, str, strlen(str), visible); } int getWidth(int i_no) const { TWidth width; getWidthEntry(i_no, &width); return width.w0; } void setFixedWidth(bool fixed, int width) { mFixed = fixed; mFixedWidth = width; } bool isValid() const { return mValid; } static bool isLeadByte_1Byte(int c) { return false; } static bool isLeadByte_2Byte(int c) { return true; } static bool isLeadByte_ShiftJIS(int c) { return ((c >= 0x81) && (c <= 0x9F)) || ((c >= 0xE0) && (c <= 0xFC)); } // _00 = VTBL bool mValid; // _04 bool mFixed; // _05 int mFixedWidth; // _08 JUtility::TColor mColor1; // _0C, bottom left JUtility::TColor mColor2; // _10, bottom right JUtility::TColor mColor3; // _14, top left JUtility::TColor mColor4; // _18, top right }; struct JUTRomFont : public JUTFont { // @fabricatedName struct AboutEncoding { u32 mFontType; // _00 u32 mDataSize; // _04 IsLeadByte mIsLeadByteFunction; // _08 }; JUTRomFont(); JUTRomFont(JKRHeap*); virtual ~JUTRomFont(); // _08 virtual void setGX(); // _0C virtual f32 drawChar_scale(f32, f32, f32, f32, int, bool); // _14 virtual int getWidth() const { return spFontHeader_->width; }; // _28 virtual int getLeading() const { return spFontHeader_->leading; }; // _18 virtual int getAscent() const { return spFontHeader_->ascent; }; // _1C virtual int getDescent() const { return spFontHeader_->descent; }; // _20 virtual int getHeight() const { return getAscent() + getDescent(); }; // _24 virtual void getWidthEntry(int, JUTFont::TWidth*) const; // _2C virtual int getCellWidth() const { return spFontHeader_->cellWidth; }; // _30 virtual int getCellHeight() const { return spFontHeader_->cellHeight; }; // _34 virtual ResFONT* getResFont() const { return nullptr; }; // _3C virtual int getFontType() const { return spAboutEncoding_->mFontType; }; // _38 virtual bool isLeadByte(int) const; // _40 void initiate(JKRHeap*); void loadImage(JKRHeap*); static AboutEncoding* spAboutEncoding_; static OSFontHeader* spFontHeader_; static u32 suFontHeaderRefered_; // they misspelled referred static AboutEncoding saoAboutEncoding_[2]; // _00 = VTBL // _00-_1C = JUTFont }; struct BlockHeader { const BlockHeader* getNext() const { return reinterpret_cast(reinterpret_cast(this) + this->mSize); } inline static void advance(const BlockHeader** iterator) { *iterator = reinterpret_cast(reinterpret_cast(*iterator) + (*iterator)->mSize); } u32 mMagic; // _00 u32 mSize; // _04 }; struct ResFONT { // INF1, size: 0x14 struct InfoBlock : public BlockHeader { // _00 = BlockHeader u16 mFontType; // _08 u16 mAscent; // _0A u16 mDescent; // _0C u16 mWidth; // _0E u16 mLeading; // _10 u16 mDefaultCode; // _12 }; // WID1, size: 0x10 struct WidthBlock : public BlockHeader { // _00 = BlockHeader u16 mStartCode; // _08 u16 mEndCode; // _0A JUTFont::TWidth mChunkNum[2]; // _0C }; // MAP1, size: 0x14 struct MapBlock : public BlockHeader { // _00 = BlockHeader u16 mMappingMethod; // _08 u16 mStartCode; // _0A u16 mEndCode; // _0C u16 mNumEntries; // _0E u16 mLeading; // _10 }; // GLY1, size: 0x20 struct GlyphBlock : public BlockHeader { // _00 = BlockHeader u16 mStartCode; // _08 u16 mEndCode; // _0A u16 mCellWidth; // _0C u16 mCellHeight; // _0E u32 mTextureSize; // _10 u16 mTextureFormat; // _14 u16 mNumRows; // _16 u16 mNumColumns; // _18 u16 mTextureWidth; // _1A u16 mTextureHeight; // _1C u16 mPadding; // _1E u8 mData[]; // _20 }; u64 mMagic; // _00 u32 mFileSize; // _08 u32 mNumBlocks; // _0C u8 mPadding[0x10]; // _10 u8 mData[]; // _20 }; /** * @size{0x70} */ struct JUTResFont : public JUTFont { JUTResFont(); JUTResFont(const ResFONT*, JKRHeap*); virtual ~JUTResFont(); // _08 virtual void setGX(); // _0C virtual void setGX(JUtility::TColor, JUtility::TColor); // _10 virtual f32 drawChar_scale(f32, f32, f32, f32, int, bool); // _14 virtual int getDescent() const { return mInfoBlock->mDescent; }; // _20 virtual int getHeight() const { return getAscent() + getDescent(); }; // _24 virtual int getAscent() const { return mInfoBlock->mAscent; }; // _1C virtual int getWidth() const { return mInfoBlock->mWidth; }; // _28 virtual void getWidthEntry(int, JUTFont::TWidth*) const; // _2C virtual int getCellWidth() const; // _30 virtual int getCellHeight() const; // _34 virtual int getFontType() const { return mInfoBlock->mFontType; }; // _38 virtual const ResFONT* getResFont() const { return mResource; }; // _3C virtual int getLeading() const { return mInfoBlock->mLeading; }; // _18 virtual bool isLeadByte(int) const; // _40 virtual void loadImage(int, GXTexMapID); // _44 virtual void setBlock(); // _48 int convertSjis(int, u16*) const; void countBlock(); void deleteMemBlocks_ResFont(); int getFontCode(int) const; void initialize_state(); bool initiate(const ResFONT*, JKRHeap*); void loadFont(int, GXTexMapID, TWidth*); bool protected_initiate(const ResFONT*, JKRHeap*); inline void delete_and_initialize() { deleteMemBlocks_ResFont(); initialize_state(); } static IsLeadByte const saoAboutEncoding_[3]; // _00 = VTBL // _00-_1C = JUTFont int mWidth; // _1C int mHeight; // _20 GXTexObj _24; // _24 int _44; // _44 const ResFONT* mResource; // _48 ResFONT::InfoBlock* mInfoBlock; // _4C, INF1 void** mMemBlocks; // _50 ResFONT::WidthBlock** mWidthBlocks; // _54, WID1 ResFONT::GlyphBlock** mGlyphBlocks; // _58, GLY1 ResFONT::MapBlock** mMapBlocks; // _5C, MAP1 u16 mWidthBlockCount; // _60 u16 mGlyphBlockCount; // _62 u16 mMapBlockCount; // _64 u16 _66; // _66 u16 mMaxCode; // _68 IsLeadByte* mIsLeadByte; // _6C }; struct JUTCacheFont : public JUTResFont { enum EPagingType { CFPAGETYPE_Unk0 = 0, CFPAGETYPE_Unk1 = 1, }; struct TGlyphCacheInfo { // TODO: the rest of the data members TGlyphCacheInfo* mPrev; // _00 TGlyphCacheInfo* mNext; // _04 u8 _08[4]; // _08 u16 _0C; // _0C u16 _0E; // _0E u8 _10[4]; // _10 u16 _14; // _14 u16 _16; // _16 u8 _18[8]; // _18 GXTexObj mGxTexObj; // _20 }; struct TCachePage { u8 _00[0x8]; // _00, unknown s16 _08; // _08 u16 _0A; // _0A u8 _0C[0x4]; // _0C, unknown u8* _10; // _10 u16 _14; // _14 u16 _18; // _18 u16 _1C; // _1C u16 _20; // _20 u16 _24; // _24 u16 _28; // _28 }; JUTCacheFont(); JUTCacheFont(const ResFONT*, void*, u32, JKRHeap*); JUTCacheFont(const ResFONT*, u32, JKRHeap*); virtual ~JUTCacheFont(); // _08 virtual void loadImage(int, _GXTexMapID); // _44 virtual void setBlock(); // _48 bool allocArea(void*, u32, JKRHeap*); bool allocArray(JKRHeap*); void deleteMemBlocks_CacheFont(); bool getMemorySize(const ResFONT*, u16*, u32*, u16*, u32*, u16*, u32*, u32*); void initialize_state(); bool initiate(const ResFONT*, void*, u32, JKRHeap*); bool internal_initiate(const ResFONT*, void*, u32, JKRHeap*); void invalidiateAllCache(); TGlyphCacheInfo* loadCache_char_subroutine(int*, bool); void loadCache_string(const char*, bool); void prepend(TGlyphCacheInfo*); void unlink(TGlyphCacheInfo*); // Unused/inlined: void determineBlankPage(); void getGlyphFromAram(TGlyphCacheInfo*, TCachePage*, int*, int*); void loadCache_char(int, bool); void loadCache_string_size(const char*, u32, bool); void unlockCache_all(); void unlockCache_char(int); void unlockCache_string(const char*); void unlockCache_string_size(const char*, u32); void setPagingType(EPagingType type) { mPagingType = type; } static u32 calcCacheSize(u32 param_0, int param_1) { return (ALIGN_NEXT(param_0, 0x20) + 0x40) * param_1; } // _00 = VTBL // _00-_70 = JUTResFont u32 mWidthBlocksSize; // _70 u32 mGlyphBlocksSize; // _74 u32 mMapBlocksSize; // _78 void* _7C; // _7C void* _80; // _80 void* _84; // _84 u32 mMaxSheetSize; // _88 EPagingType mPagingType; // _8C void* mCacheBuffer; // _90 u32 _94; // _94 u32 mCachePage; // _98 TGlyphCacheInfo* _9C; // _9C TGlyphCacheInfo* _A0; // _A0 void* _A4; // _A4 u32 _A8; // _A8 JKRAramBlock* mAramBlock; // _AC u8 _B0; // _B0 int _B4; // _B4 }; extern const ResFONT JUTResFONT_Ascfont_fix12; #endif #endif