diff --git a/include/global.h b/include/global.h index d634332797..eda2a610ec 100644 --- a/include/global.h +++ b/include/global.h @@ -220,10 +220,12 @@ using std::isnan; // Some basic macros that are more convenient than putting down #if blocks for one-line changes. #if TARGET_PC #define IF_DUSK(statement) statement +#define IF_DUSK_ARG(expr) , expr #define IF_NOT_DUSK(statement) #define DUSK_IF_ELSE(dusk, orig) dusk #else #define IF_DUSK(statement) +#define IF_DUSK_ARG(expr) #define IF_NOT_DUSK(statement) statement #define DUSK_IF_ELSE(dusk, orig) orig #endif diff --git a/libs/JSystem/include/JSystem/JUtility/JUTFont.h b/libs/JSystem/include/JSystem/JUtility/JUTFont.h index 2718132048..d07e09a590 100644 --- a/libs/JSystem/include/JSystem/JUtility/JUTFont.h +++ b/libs/JSystem/include/JSystem/JUtility/JUTFont.h @@ -5,6 +5,18 @@ #include #include "dusk/endian.h" +#if TARGET_PC +struct FontDrawContext { + int loadedBlock = -1; + int loadedPage = -1; +}; +#define FONT_DRAW_CTX , FontDrawContext* context +#define FONT_DRAW_CTX_ARG , context +#else +#define FONT_DRAW_CTX +#define FONT_DRAW_CTX_ARG +#endif + /** * @ingroup jsystem-jutility * @@ -84,7 +96,12 @@ public: /* 0x0C */ virtual void setGX() = 0; /* 0x10 */ virtual void setGX(JUtility::TColor col1, JUtility::TColor col2) { setGX(); } - /* 0x14 */ virtual f32 drawChar_scale(f32 a1, f32 a2, f32 a3, f32 a4, int a5, bool a6) = 0; + /* 0x14 */ virtual f32 drawChar_scale(f32 a1, f32 a2, f32 a3, f32 a4, int a5, bool a6 FONT_DRAW_CTX) = 0; +#if TARGET_PC + f32 drawChar_scale(f32 a1, f32 a2, f32 a3, f32 a4, int a5, bool a6) { + return drawChar_scale(a1, a2, a3, a4, a5, a6, nullptr); + } +#endif /* 0x18 */ virtual int getLeading() const = 0; /* 0x1C */ virtual s32 getAscent() const = 0; /* 0x20 */ virtual s32 getDescent() const = 0; @@ -97,6 +114,11 @@ public: /* 0x3C */ virtual ResFONT* getResFont() const = 0; /* 0x40 */ virtual bool isLeadByte(int a1) const = 0; +#if TARGET_PC + virtual void pushDrawState() = 0; + virtual void popDrawState() = 0; +#endif + static bool isLeadByte_1Byte(int b) { return false; } diff --git a/libs/JSystem/include/JSystem/JUtility/JUTResFont.h b/libs/JSystem/include/JSystem/JUtility/JUTResFont.h index 8709822d7b..68fd798ba5 100644 --- a/libs/JSystem/include/JSystem/JUtility/JUTResFont.h +++ b/libs/JSystem/include/JSystem/JUtility/JUTResFont.h @@ -31,7 +31,7 @@ public: virtual ~JUTResFont(); virtual void setGX(); virtual void setGX(JUtility::TColor, JUtility::TColor); - virtual f32 drawChar_scale(f32, f32, f32, f32, int, bool); + virtual f32 drawChar_scale(f32, f32, f32, f32, int, bool FONT_DRAW_CTX); virtual int getLeading() const; virtual s32 getAscent() const; virtual s32 getDescent() const; @@ -43,7 +43,7 @@ public: virtual int getFontType() const; virtual ResFONT* getResFont() const; virtual bool isLeadByte(int) const; - virtual void loadImage(int, GXTexMapID); + virtual void loadImage(int, GXTexMapID FONT_DRAW_CTX); virtual void setBlock(); JUTResFont(ResFONT const*, JKRHeap*); @@ -53,10 +53,15 @@ public: bool initiate(ResFONT const*, JKRHeap*); bool protected_initiate(ResFONT const*, JKRHeap*); void countBlock(); - void loadFont(int, GXTexMapID, JUTFont::TWidth*); + void loadFont(int, GXTexMapID, JUTFont::TWidth* FONT_DRAW_CTX); int getFontCode(int) const; int convertSjis(int, BE(u16)*) const; +#if TARGET_PC + void pushDrawState() override; + void popDrawState() override; +#endif + inline void delete_and_initialize() { deleteMemBlocks_ResFont(); initialize_state(); diff --git a/libs/JSystem/src/J2DGraph/J2DPrint.cpp b/libs/JSystem/src/J2DGraph/J2DPrint.cpp index bd7156f706..69d71aa6c5 100644 --- a/libs/JSystem/src/J2DGraph/J2DPrint.cpp +++ b/libs/JSystem/src/J2DGraph/J2DPrint.cpp @@ -211,6 +211,11 @@ f32 J2DPrint::parse(const u8* pString, int length, int param_2, u16* param_3, local_bc.a = local_bc.a * alpha / 0xFF; mFont->setGradColor(local_b8, field_0x22 ? local_bc : local_b8); +#if TARGET_PC + FontDrawContext context; + mFont->pushDrawState(); +#endif + do { bool b2ByteCharacter = false; bool r25; @@ -312,9 +317,9 @@ f32 J2DPrint::parse(const u8* pString, int length, int param_2, u16* param_3, } else { if (param_6) { if (param_3 != NULL) { - mFont->drawChar_scale(mCursorH + (s16)param_3[someIndex], mCursorV, (s32)mScaleX, (s32)mScaleY, iCharacter, true); + mFont->drawChar_scale(mCursorH + (s16)param_3[someIndex], mCursorV, (s32)mScaleX, (s32)mScaleY, iCharacter, true IF_DUSK_ARG(&context)); } else { - mFont->drawChar_scale(mCursorH, mCursorV, (s32)mScaleX, (s32)mScaleY, iCharacter, true); + mFont->drawChar_scale(mCursorH, mCursorV, (s32)mScaleX, (s32)mScaleY, iCharacter, true IF_DUSK_ARG(&context)); } } mCursorH += field_0x34; @@ -353,6 +358,8 @@ f32 J2DPrint::parse(const u8* pString, int length, int param_2, u16* param_3, iCharacter = *(pString++); } while (true); + IF_DUSK(mFont->popDrawState()); + if (param_3 != NULL) { param_3[someIndex] = 0xFFFF; } diff --git a/libs/JSystem/src/JUtility/JUTResFont.cpp b/libs/JSystem/src/JUtility/JUTResFont.cpp index 206968f053..8583d42c58 100644 --- a/libs/JSystem/src/JUtility/JUTResFont.cpp +++ b/libs/JSystem/src/JUtility/JUTResFont.cpp @@ -231,14 +231,14 @@ void JUTResFont::setGX(JUtility::TColor col1, JUtility::TColor col2) { } f32 JUTResFont::drawChar_scale(f32 pos_x, f32 pos_y, f32 scale_x, f32 scale_y, int str_int, - bool flag) { + bool flag FONT_DRAW_CTX) { f32 x1; f32 x2; f32 y1; JUT_ASSERT(378, mValid); JUTFont::TWidth width; - loadFont(str_int, GX_TEXMAP0, &width); + loadFont(str_int, GX_TEXMAP0, &width FONT_DRAW_CTX_ARG); if ((mFixed) || (!flag)) { x1 = pos_x; @@ -266,7 +266,13 @@ f32 JUTResFont::drawChar_scale(f32 pos_x, f32 pos_y, f32 scale_x, f32 scale_y, i s32 u2 = ((mWidth + cellW) * 0x8000) / texW; s32 v2 = ((mHeight + cellH) * 0x8000) / texH; +#if TARGET_PC + if (!context) { + pushDrawState(); + } +#else GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); +#endif GXBegin(GX_QUADS, GX_VTXFMT0, 4); // Bottom Left @@ -290,18 +296,33 @@ f32 JUTResFont::drawChar_scale(f32 pos_x, f32 pos_y, f32 scale_x, f32 scale_y, i GXTexCoord2u16(u1, v2); GXEnd(); +#if TARGET_PC + if (!context) { + popDrawState(); + } +#else GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); - +#endif return retval; } -void JUTResFont::loadFont(int code, GXTexMapID texMapID, JUTFont::TWidth* pDstWidth) { +#if TARGET_PC +void JUTResFont::pushDrawState() { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); +} + +void JUTResFont::popDrawState() { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); +} +#endif + +void JUTResFont::loadFont(int code, GXTexMapID texMapID, JUTFont::TWidth* pDstWidth FONT_DRAW_CTX) { if (pDstWidth != 0) { getWidthEntry(code, pDstWidth); } int fontCode = getFontCode(code); - loadImage(fontCode, texMapID); + loadImage(fontCode, texMapID FONT_DRAW_CTX_ARG); } void JUTResFont::getWidthEntry(int code, JUTFont::TWidth* i_width) const { @@ -403,7 +424,7 @@ int JUTResFont::getFontCode(int chr) const { return ret; } -void JUTResFont::loadImage(int code, GXTexMapID id){ +void JUTResFont::loadImage(int code, GXTexMapID id FONT_DRAW_CTX){ int i = 0; for (; i < mGly1BlockNum; i++) { @@ -435,22 +456,29 @@ void JUTResFont::loadImage(int code, GXTexMapID id){ mHeight = cellRow * cellH; #if TARGET_PC - const auto found = mGlyphTextures->textures.find(pageIdx); - GXTexObj* texObj; - if (found == mGlyphTextures->textures.end()) { - texObj = &mGlyphTextures->textures[pageIdx]; - void* pImg = &mpGlyphBlocks[i]->data[pageIdx * mpGlyphBlocks[i]->textureSize]; - GXInitTexObj(texObj, pImg, mpGlyphBlocks[i]->textureWidth, - mpGlyphBlocks[i]->textureHeight, (GXTexFmt)(u16)mpGlyphBlocks[i]->textureFormat, - GX_CLAMP, GX_CLAMP, 0); + if (!context || context->loadedPage != pageIdx || context->loadedBlock != i) { + const auto found = mGlyphTextures->textures.find(pageIdx); + GXTexObj* texObj; + if (found == mGlyphTextures->textures.end()) { + texObj = &mGlyphTextures->textures[pageIdx]; + void* pImg = &mpGlyphBlocks[i]->data[pageIdx * mpGlyphBlocks[i]->textureSize]; + GXInitTexObj(texObj, pImg, mpGlyphBlocks[i]->textureWidth, + mpGlyphBlocks[i]->textureHeight, (GXTexFmt)(u16)mpGlyphBlocks[i]->textureFormat, + GX_CLAMP, GX_CLAMP, 0); - GXInitTexObjLOD(texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0U, 0U, GX_ANISO_1); - } else { - texObj = &found->second; + GXInitTexObjLOD(texObj, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, 0U, 0U, GX_ANISO_1); + } else { + texObj = &found->second; + } + + GXLoadTexObj(texObj, id); + + if (context) { + context->loadedBlock = i; + context->loadedPage = pageIdx; + } } - GXLoadTexObj(texObj, id); - // Gets used by some other code. mTexPageIdx = pageIdx; field_0x66 = i;