From 46370e2860ea199d49d584426f41ca800da3a097 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Feb 2014 20:57:18 -0800 Subject: [PATCH 01/13] Implement sceFontGetShadowGlyphImage(). Not sure if any games actually use it, though... --- Core/Font/PGF.cpp | 10 +++++----- Core/HLE/sceFont.cpp | 40 +++++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Core/Font/PGF.cpp b/Core/Font/PGF.cpp index 23db5391ea..4095d70479 100644 --- a/Core/Font/PGF.cpp +++ b/Core/Font/PGF.cpp @@ -276,7 +276,7 @@ bool PGF::ReadPtr(const u8 *ptr, size_t dataSize) { int charmap_compr_len = header.revision == 3 ? 7 : 1; charmap_compr.resize(charmap_compr_len * 4); glyphs.resize(header.charPointerLength); - shadowGlyphs.resize(header.shadowMapLength); + shadowGlyphs.resize(header.charPointerLength); firstGlyph = header.firstGlyph; // Parse out the char map (array where each entry is an irregular number of bits) @@ -289,7 +289,7 @@ bool PGF::ReadPtr(const u8 *ptr, size_t dataSize) { } std::vector charPointers = getTable(charPointerTable, header.charPointerBpe, glyphs.size()); - std::vector shadowMap = getTable(shadowCharMap, header.shadowMapBpe, shadowGlyphs.size()); + std::vector shadowMap = getTable(shadowCharMap, header.shadowMapBpe, (s32)header.shadowMapLength); // Pregenerate glyphs. for (size_t i = 0; i < glyphs.size(); i++) { @@ -299,11 +299,11 @@ bool PGF::ReadPtr(const u8 *ptr, size_t dataSize) { // And shadow glyphs. for (size_t i = 0; i < glyphs.size(); i++) { size_t shadowId = glyphs[i].shadowID; - if ((shadowId < shadowMap.size()) && (shadowId < shadowGlyphs.size())) { + if (shadowId < shadowMap.size()) { size_t charId = shadowMap[shadowId]; - if (charId < glyphs.size()) { + if (charId < shadowGlyphs.size()) { // TODO: check for pre existing shadow glyph - GetGlyph(fontData, charPointers[charId] * 4 * 8 /* ??? */, FONT_PGF_SHADOWGLYPH, shadowGlyphs[shadowId]); + GetGlyph(fontData, charPointers[charId] * 4 * 8 /* ??? */, FONT_PGF_SHADOWGLYPH, shadowGlyphs[charId]); } } } diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 96a263af2f..ac2974cd80 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1059,7 +1059,7 @@ int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) { DEBUG_LOG(SCEFONT, "sceFontGetCharGlyphImage(%x, %x, %x)", fontHandle, charCode, glyphImagePtr); auto glyph = PSPPointer::Create(glyphImagePtr); int altCharCode = font->GetFontLib()->GetAltCharCode(); - font->GetPGF()->DrawCharacter(glyph, 0, 0, 8192, 8192, charCode, altCharCode, FONT_PGF_CHARGLYPH); + font->GetPGF()->DrawCharacter(glyph, -1, -1, -1, -1, charCode, altCharCode, FONT_PGF_CHARGLYPH); return 0; } @@ -1175,13 +1175,39 @@ int sceFontCalcMemorySize() { return 0; } -int sceFontGetShadowGlyphImage() { - ERROR_LOG_REPORT(SCEFONT, "UNIMPL sceFontGetShadowGlyphImage()"); +int sceFontGetShadowGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) { + if (!Memory::IsValidAddress(glyphImagePtr)) { + ERROR_LOG(SCEFONT, "sceFontGetShadowGlyphImage(%x, %x, %x): bad glyphImage pointer", fontHandle, charCode, glyphImagePtr); + return ERROR_FONT_INVALID_PARAMETER; + } + LoadedFont *font = GetLoadedFont(fontHandle, true); + if (!font) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetShadowGlyphImage(%x, %x, %x): bad font", fontHandle, charCode, glyphImagePtr); + return ERROR_FONT_INVALID_PARAMETER; + } + + DEBUG_LOG(SCEFONT, "sceFontGetShadowGlyphImage(%x, %x, %x)", fontHandle, charCode, glyphImagePtr); + auto glyph = PSPPointer::Create(glyphImagePtr); + int altCharCode = font->GetFontLib()->GetAltCharCode(); + font->GetPGF()->DrawCharacter(glyph, -1, -1, -1, -1, charCode, altCharCode, FONT_PGF_SHADOWGLYPH); return 0; } -int sceFontGetShadowGlyphImage_Clip() { - ERROR_LOG_REPORT(SCEFONT, "UNIMPL sceFontGetShadowGlyphImage_Clip()"); +int sceFontGetShadowGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 glyphImagePtr, int clipXPos, int clipYPos, int clipWidth, int clipHeight) { + if (!Memory::IsValidAddress(glyphImagePtr)) { + ERROR_LOG(SCEFONT, "sceFontGetShadowGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i): bad glyphImage pointer", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight); + return ERROR_FONT_INVALID_PARAMETER; + } + LoadedFont *font = GetLoadedFont(fontHandle, true); + if (!font) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetShadowGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i): bad font", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight); + return ERROR_FONT_INVALID_PARAMETER; + } + + DEBUG_LOG(SCEFONT, "sceFontGetShadowGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i)", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight); + auto glyph = PSPPointer::Create(glyphImagePtr); + int altCharCode = font->GetFontLib()->GetAltCharCode(); + font->GetPGF()->DrawCharacter(glyph, clipXPos, clipYPos, clipWidth, clipHeight, charCode, altCharCode, FONT_PGF_SHADOWGLYPH); return 0; } @@ -1211,8 +1237,8 @@ const HLEFunction sceLibFont[] = { {0x472694cd, WrapF_IFU, "sceFontPointToPixelH"}, {0x3c4b7e82, WrapF_IFU, "sceFontPointToPixelV"}, {0xee232411, WrapI_UU, "sceFontSetAltCharacterCode"}, - {0x568be516, WrapI_V, "sceFontGetShadowGlyphImage"}, - {0x5dcf6858, WrapI_V, "sceFontGetShadowGlyphImage_Clip"}, + {0x568be516, WrapI_UUU, "sceFontGetShadowGlyphImage"}, + {0x5dcf6858, WrapI_UUUIIII, "sceFontGetShadowGlyphImage_Clip"}, {0x02d7f94b, WrapI_U, "sceFontFlush"}, }; From 692cffffd1b6902eba9317951a4ef61f97533ba1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Feb 2014 21:20:06 -0800 Subject: [PATCH 02/13] Use the correct default for font altCharCode. --- Core/HLE/sceFont.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index ac2974cd80..9a9f79e561 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -357,7 +357,7 @@ struct NativeFontLib { float_le vRes; u32_le internalFontCount; u32_le internalFontInfo; - u16_le unk4; + u16_le altCharCode; u16_le unk5; }; @@ -369,7 +369,7 @@ public: // For save states only. } - FontLib(u32 paramPtr, u32 errorCodePtr) : fontHRes_(128.0f), fontVRes_(128.0f) { + FontLib(u32 paramPtr, u32 errorCodePtr) : fontHRes_(128.0f), fontVRes_(128.0f), altCharCode_(0x5F) { Memory::ReadStruct(paramPtr, ¶ms_); if (params_.numFonts > 9) { params_.numFonts = 9; @@ -426,7 +426,7 @@ public: nfl->vRes = fontVRes_; nfl->internalFontCount = (u32)internalFonts.size(); nfl->internalFontInfo = allocatedAddr + 0x4C + params_.numFonts * 0x4C + params_.numFonts * 0x230; - nfl->unk4 = 0x5F; + nfl->altCharCode = altCharCode_; } u32 handle() const { return handle_; } @@ -1082,11 +1082,14 @@ int sceFontGetCharGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 glyphImagePt } int sceFontSetAltCharacterCode(u32 fontLibHandle, u32 charCode) { - INFO_LOG(SCEFONT, "sceFontSetAltCharacterCode(%08x) (%08x)", fontLibHandle, charCode); FontLib *fl = GetFontLib(fontLibHandle); - if (fl) { - fl->SetAltCharCode(charCode); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontSetAltCharacterCode(%08x, %08x): invalid font lib", fontLibHandle, charCode); + return ERROR_FONT_INVALID_LIBID; } + + INFO_LOG(SCEFONT, "sceFontSetAltCharacterCode(%08x, %08x)", fontLibHandle, charCode); + fl->SetAltCharCode(charCode & 0xFFFF); return 0; } From bc3e123b610e6a74d1dcc4f910e0f6606f795cdd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Feb 2014 21:25:45 -0800 Subject: [PATCH 03/13] Oops, fix negative clip regions. Since they're summed, need to clamp the left/top side. And the bottom/right side is offset by x/y. --- Core/Font/PGF.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Core/Font/PGF.cpp b/Core/Font/PGF.cpp index 4095d70479..f9e03ce0e7 100644 --- a/Core/Font/PGF.cpp +++ b/Core/Font/PGF.cpp @@ -557,10 +557,14 @@ void PGF::DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipW int y = image->yPos64 >> 6; // Negative means don't clip on that side. + if (clipX < 0) + clipX = 0; + if (clipY < 0) + clipY = 0; if (clipWidth < 0) - clipWidth = glyph.w; + clipWidth = 8192; if (clipHeight < 0) - clipHeight = glyph.h; + clipHeight = 8192; while (pixelIndex < numberPixels && bitPtr + 8 < fontDataSize * 8) { // This is some kind of nibble based RLE compression. From 67fcdc0f4a53fee0339bdd076e571e0f68dcea59 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Feb 2014 21:29:41 -0800 Subject: [PATCH 04/13] Reflect font altCharCode in psp mem for tests. Makes it easier to be sure it's working right. Not completely impossible a game will check it... but hopefully not. --- Core/HLE/sceFont.cpp | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 9a9f79e561..5d74d38df2 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -370,6 +370,7 @@ public: } FontLib(u32 paramPtr, u32 errorCodePtr) : fontHRes_(128.0f), fontVRes_(128.0f), altCharCode_(0x5F) { + nfl_ = 0; Memory::ReadStruct(paramPtr, ¶ms_); if (params_.numFonts > 9) { params_.numFonts = 9; @@ -416,17 +417,17 @@ public: // Let's write out the native struct to make tests easier. // It's possible games may depend on this staying in ram, e.g. copying it, we may move to that. - auto nfl = PSPPointer::Create(allocatedAddr); - nfl->params = params_; - nfl->fontInfo1 = allocatedAddr + 0x4C; - nfl->fontInfo2 = allocatedAddr + 0x4C + params_.numFonts * 0x4C; - nfl->unk1 = 0; - nfl->unk2 = 0; - nfl->hRes = fontHRes_; - nfl->vRes = fontVRes_; - nfl->internalFontCount = (u32)internalFonts.size(); - nfl->internalFontInfo = allocatedAddr + 0x4C + params_.numFonts * 0x4C + params_.numFonts * 0x230; - nfl->altCharCode = altCharCode_; + nfl_ = allocatedAddr; + nfl_->params = params_; + nfl_->fontInfo1 = allocatedAddr + 0x4C; + nfl_->fontInfo2 = allocatedAddr + 0x4C + params_.numFonts * 0x4C; + nfl_->unk1 = 0; + nfl_->unk2 = 0; + nfl_->hRes = fontHRes_; + nfl_->vRes = fontVRes_; + nfl_->internalFontCount = (u32)internalFonts.size(); + nfl_->internalFontInfo = allocatedAddr + 0x4C + params_.numFonts * 0x4C + params_.numFonts * 0x230; + nfl_->altCharCode = altCharCode_; } u32 handle() const { return handle_; } @@ -435,12 +436,20 @@ public: void SetResolution(float hres, float vres) { fontHRes_ = hres; fontVRes_ = vres; + if (nfl_.IsValid()) { + nfl_->hRes = hres; + nfl_->vRes = vres; + } } float FontHRes() const { return fontHRes_; } float FontVRes() const { return fontVRes_; } - void SetAltCharCode(int charCode) { altCharCode_ = charCode; } + void SetAltCharCode(int charCode) { + altCharCode_ = charCode; + if (nfl_.IsValid()) + nfl_->altCharCode = charCode; + } int GetFontHandle(int index) { return fonts_[index]; @@ -482,7 +491,7 @@ public: } void DoState(PointerWrap &p) { - auto s = p.Section("FontLib", 1); + auto s = p.Section("FontLib", 1, 2); if (!s) return; @@ -494,6 +503,11 @@ public: p.Do(fileFontHandle_); p.Do(handle_); p.Do(altCharCode_); + if (s >= 2) { + p.Do(nfl_); + } else { + nfl_ = 0; + } } void SetFileFontHandle(u32 handle) { @@ -512,6 +526,7 @@ private: int fileFontHandle_; int handle_; int altCharCode_; + PSPPointer nfl_; DISALLOW_COPY_AND_ASSIGN(FontLib); }; From 57e64547b39c3e10de4166858e848dd5bb9204a2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Feb 2014 21:52:34 -0800 Subject: [PATCH 05/13] Fix sceFontSetResolution() error codes. --- Core/HLE/sceFont.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 5d74d38df2..bc2b2918b3 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1136,11 +1136,17 @@ int sceFontGetNumFontList(u32 fontLibHandle, u32 errorCodePtr) { } int sceFontSetResolution(u32 fontLibHandle, float hRes, float vRes) { - INFO_LOG(SCEFONT, "sceFontSetResolution(%08x, %f, %f)", fontLibHandle, hRes, vRes); FontLib *fl = GetFontLib(fontLibHandle); - if (fl) { - fl->SetResolution(hRes, vRes); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontSetResolution(%08x, %f, %f): invalid font lib", fontLibHandle, hRes, vRes); + return ERROR_FONT_INVALID_LIBID; } + if (hRes <= 0.0f || vRes <= 0.0f) { + ERROR_LOG_REPORT(SCEFONT, "sceFontSetResolution(%08x, %f, %f): negative value", fontLibHandle, hRes, vRes); + return ERROR_FONT_INVALID_PARAMETER; + } + INFO_LOG(SCEFONT, "sceFontSetResolution(%08x, %f, %f)", fontLibHandle, hRes, vRes); + fl->SetResolution(hRes, vRes); return 0; } From 96a93d9baed5861221f914984b852111e43ade22 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Feb 2014 22:05:37 -0800 Subject: [PATCH 06/13] Fix error handling in sceFontPointToPixelH()/etc. --- Core/HLE/sceFont.cpp | 80 ++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index bc2b2918b3..b736fbf1f6 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1151,47 +1151,71 @@ int sceFontSetResolution(u32 fontLibHandle, float hRes, float vRes) { } float sceFontPixelToPointH(int fontLibHandle, float fontPixelsH, u32 errorCodePtr) { - DEBUG_LOG(SCEFONT, "sceFontPixelToPointH(%08x, %f, %08x)", fontLibHandle, fontPixelsH, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - Memory::Write_U32(0, errorCodePtr); - FontLib *fl = GetFontLib(fontLibHandle); - if (fl) { - return fontPixelsH * pointDPI / fl->FontHRes(); + auto errorCode = PSPPointer::Create(errorCodePtr); + if (!errorCode.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPixelToPointH(%08x, %f, %08x): invalid error address", fontLibHandle, fontPixelsH, errorCodePtr); + return 0.0f; } - return 0; + FontLib *fl = GetFontLib(fontLibHandle); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPixelToPointH(%08x, %f, %08x): invalid font lib", fontLibHandle, fontPixelsH, errorCodePtr); + *errorCode = ERROR_FONT_INVALID_LIBID; + return 0.0f; + } + DEBUG_LOG(SCEFONT, "sceFontPixelToPointH(%08x, %f, %08x)", fontLibHandle, fontPixelsH, errorCodePtr); + *errorCode = 0; + return fontPixelsH * pointDPI / fl->FontHRes(); } float sceFontPixelToPointV(int fontLibHandle, float fontPixelsV, u32 errorCodePtr) { - DEBUG_LOG(SCEFONT, "sceFontPixelToPointV(%08x, %f, %08x)", fontLibHandle, fontPixelsV, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - Memory::Write_U32(0, errorCodePtr); - FontLib *fl = GetFontLib(fontLibHandle); - if (fl) { - return fontPixelsV * pointDPI / fl->FontVRes(); + auto errorCode = PSPPointer::Create(errorCodePtr); + if (!errorCode.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPixelToPointV(%08x, %f, %08x): invalid error address", fontLibHandle, fontPixelsV, errorCodePtr); + return 0.0f; } - return 0; + FontLib *fl = GetFontLib(fontLibHandle); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPixelToPointV(%08x, %f, %08x): invalid font lib", fontLibHandle, fontPixelsV, errorCodePtr); + *errorCode = ERROR_FONT_INVALID_LIBID; + return 0.0f; + } + DEBUG_LOG(SCEFONT, "sceFontPixelToPointV(%08x, %f, %08x)", fontLibHandle, fontPixelsV, errorCodePtr); + *errorCode = 0; + return fontPixelsV * pointDPI / fl->FontVRes(); } float sceFontPointToPixelH(int fontLibHandle, float fontPointsH, u32 errorCodePtr) { - DEBUG_LOG(SCEFONT, "sceFontPointToPixelH(%08x, %f, %08x)", fontLibHandle, fontPointsH, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - Memory::Write_U32(0, errorCodePtr); - FontLib *fl = GetFontLib(fontLibHandle); - if (fl) { - return fontPointsH * fl->FontHRes() / pointDPI; + auto errorCode = PSPPointer::Create(errorCodePtr); + if (!errorCode.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPointToPixelH(%08x, %f, %08x): invalid error address", fontLibHandle, fontPointsH, errorCodePtr); + return 0.0f; } - return 0; + FontLib *fl = GetFontLib(fontLibHandle); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPointToPixelH(%08x, %f, %08x): invalid font lib", fontLibHandle, fontPointsH, errorCodePtr); + *errorCode = ERROR_FONT_INVALID_LIBID; + return 0.0f; + } + DEBUG_LOG(SCEFONT, "sceFontPointToPixelH(%08x, %f, %08x)", fontLibHandle, fontPointsH, errorCodePtr); + *errorCode = 0; + return fontPointsH * fl->FontHRes() / pointDPI; } float sceFontPointToPixelV(int fontLibHandle, float fontPointsV, u32 errorCodePtr) { - DEBUG_LOG(SCEFONT, "sceFontPointToPixelV(%08x, %f, %08x)", fontLibHandle, fontPointsV, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - Memory::Write_U32(0, errorCodePtr); - FontLib *fl = GetFontLib(fontLibHandle); - if (fl) { - return fontPointsV * fl->FontVRes() / pointDPI; + auto errorCode = PSPPointer::Create(errorCodePtr); + if (!errorCode.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPointToPixelV(%08x, %f, %08x): invalid error address", fontLibHandle, fontPointsV, errorCodePtr); + return 0.0f; } - return 0; + FontLib *fl = GetFontLib(fontLibHandle); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontPointToPixelV(%08x, %f, %08x): invalid font lib", fontLibHandle, fontPointsV, errorCodePtr); + *errorCode = ERROR_FONT_INVALID_LIBID; + return 0.0f; + } + DEBUG_LOG(SCEFONT, "sceFontPointToPixelV(%08x, %f, %08x)", fontLibHandle, fontPointsV, errorCodePtr); + *errorCode = 0; + return fontPointsV * fl->FontVRes() / pointDPI; } int sceFontCalcMemorySize() { From 29d2e8167658e16e29df115388f9b0594bd6f767 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 28 Feb 2014 23:04:34 -0800 Subject: [PATCH 07/13] Cleanup errors in sceFontGet*ImageRect(). --- Core/Font/PGF.cpp | 6 +-- Core/Font/PGF.h | 2 +- Core/HLE/sceFont.cpp | 87 ++++++++++++++++++++++++++++++-------------- 3 files changed, 63 insertions(+), 32 deletions(-) diff --git a/Core/Font/PGF.cpp b/Core/Font/PGF.cpp index f9e03ce0e7..4f98b59538 100644 --- a/Core/Font/PGF.cpp +++ b/Core/Font/PGF.cpp @@ -323,16 +323,16 @@ int PGF::GetCharIndex(int charCode, const std::vector &charmapCompressed) { return -1; } -bool PGF::GetCharInfo(int charCode, PGFCharInfo *charInfo, int altCharCode) const { +bool PGF::GetCharInfo(int charCode, PGFCharInfo *charInfo, int altCharCode, int glyphType) const { Glyph glyph; memset(charInfo, 0, sizeof(*charInfo)); - if (!GetCharGlyph(charCode, FONT_PGF_CHARGLYPH, glyph)) { + if (!GetCharGlyph(charCode, glyphType, glyph)) { if (charCode < firstGlyph) { // Character not in font, return zeroed charInfo as on real PSP. return false; } - if (!GetCharGlyph(altCharCode, FONT_PGF_CHARGLYPH, glyph)) { + if (!GetCharGlyph(altCharCode, glyphType, glyph)) { return false; } } diff --git a/Core/Font/PGF.h b/Core/Font/PGF.h index 4fd224c810..eafc7224e0 100644 --- a/Core/Font/PGF.h +++ b/Core/Font/PGF.h @@ -264,7 +264,7 @@ public: bool ReadPtr(const u8 *ptr, size_t dataSize); - bool GetCharInfo(int charCode, PGFCharInfo *ci, int altCharCode) const; + bool GetCharInfo(int charCode, PGFCharInfo *ci, int altCharCode, int glyphType = FONT_PGF_CHARGLYPH) const; void GetFontInfo(PGFFontInfo *fi) const; void DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipWidth, int clipHeight, int charCode, int altCharCode, int glyphType) const; diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index b736fbf1f6..ee9c3ae982 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -258,11 +258,15 @@ public: LoadedFont(Font *font, u32 fontLibID, u32 handle) : fontLibID_(fontLibID), font_(font), handle_(handle), open_(true) {} - Font *GetFont() { return font_; } - PGF *GetPGF() { return font_->GetPGF(); } + const Font *GetFont() const { return font_; } + const PGF *GetPGF() const { return font_->GetPGF(); } + const FontLib *GetFontLib() const { return fontLibList[fontLibID_]; } FontLib *GetFontLib() { return fontLibList[fontLibID_]; } u32 Handle() const { return handle_; } + bool GetCharInfo(int charCode, PGFCharInfo *charInfo, int glyphType = FONT_PGF_CHARGLYPH) const; + void DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipWidth, int clipHeight, int charCode, int glyphType) const; + bool IsOpen() const { return open_; } void Close() { open_ = false; @@ -361,6 +365,11 @@ struct NativeFontLib { u16_le unk5; }; +struct FontImageRect { + s16_le width; + s16_le height; +}; + // A "fontLib" is a container of loaded fonts. // One can open either "internal" fonts or custom fonts into a fontlib. class FontLib { @@ -554,6 +563,18 @@ void PostOpenCallback::run(MipsCall &call) { fontLib->SetFileFontHandle(v0); } +inline bool LoadedFont::GetCharInfo(int charCode, PGFCharInfo *charInfo, int glyphType) const { + auto fontLib = GetFontLib(); + int altCharCode = fontLib == NULL ? -1 : fontLib->GetAltCharCode(); + return GetPGF()->GetCharInfo(charCode, charInfo, altCharCode, glyphType); +} + +inline void LoadedFont::DrawCharacter(const GlyphImage *image, int clipX, int clipY, int clipWidth, int clipHeight, int charCode, int glyphType) const { + auto fontLib = GetFontLib(); + int altCharCode = fontLib == NULL ? -1 : fontLib->GetAltCharCode(); + GetPGF()->DrawCharacter(image, clipX, clipY, clipWidth, clipHeight, charCode, altCharCode, glyphType); +} + FontLib *GetFontLib(u32 handle) { if (fontLibMap.find(handle) != fontLibMap.end()) { return fontLibList[fontLibMap[handle]]; @@ -1021,10 +1042,8 @@ int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) { } DEBUG_LOG(SCEFONT, "sceFontGetCharInfo(%08x, %i, %08x)", fontHandle, charCode, charInfoPtr); - auto fontLib = font->GetFontLib(); - int altCharCode = fontLib == NULL ? -1 : fontLib->GetAltCharCode(); auto charInfo = PSPPointer::Create(charInfoPtr); - font->GetPGF()->GetCharInfo(charCode, charInfo, altCharCode); + font->GetCharInfo(charCode, charInfo); return 0; } @@ -1037,26 +1056,42 @@ int sceFontGetShadowInfo(u32 fontHandle, u32 charCode, u32 shadowCharInfoPtr) { } int sceFontGetCharImageRect(u32 fontHandle, u32 charCode, u32 charRectPtr) { - DEBUG_LOG(SCEFONT, "sceFontGetCharImageRect(%08x, %i, %08x)", fontHandle, charCode, charRectPtr); - if (!Memory::IsValidAddress(charRectPtr)) - return -1; - - PGFCharInfo charInfo; - LoadedFont *font = GetLoadedFont(fontHandle, false); - if (font) { - auto fontLib = font->GetFontLib(); - int altCharCode = fontLib == NULL ? -1 : fontLib->GetAltCharCode(); - font->GetPGF()->GetCharInfo(charCode, &charInfo, altCharCode); - Memory::Write_U16(charInfo.bitmapWidth, charRectPtr); // character bitmap width in pixels - Memory::Write_U16(charInfo.bitmapHeight, charRectPtr + 2); // character bitmap height in pixels - } else { - ERROR_LOG(SCEFONT, "sceFontGetCharImageRect - invalid font"); + auto charRect = PSPPointer::Create(charRectPtr); + LoadedFont *font = GetLoadedFont(fontHandle, true); + if (!font) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetCharImageRect(%08x, %i, %08x): bad font", fontHandle, charCode, charRectPtr); + return ERROR_FONT_INVALID_PARAMETER; } + if (!charRect.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetCharImageRect(%08x, %i, %08x): invalid rect pointer", fontHandle, charCode, charRectPtr); + return ERROR_FONT_INVALID_PARAMETER; + } + + DEBUG_LOG(SCEFONT, "sceFontGetCharImageRect(%08x, %i, %08x)", fontHandle, charCode, charRectPtr); + PGFCharInfo charInfo; + font->GetCharInfo(charCode, &charInfo); + charRect->width = charInfo.bitmapWidth; + charRect->height = charInfo.bitmapHeight; return 0; } int sceFontGetShadowImageRect(u32 fontHandle, u32 charCode, u32 charRectPtr) { - ERROR_LOG_REPORT(SCEFONT, "UNIMPL sceFontGetShadowImageRect()"); + auto charRect = PSPPointer::Create(charRectPtr); + LoadedFont *font = GetLoadedFont(fontHandle, true); + if (!font) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetShadowImageRect(%08x, %i, %08x): bad font", fontHandle, charCode, charRectPtr); + return ERROR_FONT_INVALID_PARAMETER; + } + if (!charRect.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetShadowImageRect(%08x, %i, %08x): invalid rect pointer", fontHandle, charCode, charRectPtr); + return ERROR_FONT_INVALID_PARAMETER; + } + + DEBUG_LOG(SCEFONT, "sceFontGetShadowImageRect(%08x, %i, %08x)", fontHandle, charCode, charRectPtr); + PGFCharInfo charInfo; + font->GetCharInfo(charCode, &charInfo, FONT_PGF_SHADOWGLYPH); + charRect->width = charInfo.bitmapWidth; + charRect->height = charInfo.bitmapHeight; return 0; } @@ -1073,8 +1108,7 @@ int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) { DEBUG_LOG(SCEFONT, "sceFontGetCharGlyphImage(%x, %x, %x)", fontHandle, charCode, glyphImagePtr); auto glyph = PSPPointer::Create(glyphImagePtr); - int altCharCode = font->GetFontLib()->GetAltCharCode(); - font->GetPGF()->DrawCharacter(glyph, -1, -1, -1, -1, charCode, altCharCode, FONT_PGF_CHARGLYPH); + font->DrawCharacter(glyph, -1, -1, -1, -1, charCode, FONT_PGF_CHARGLYPH); return 0; } @@ -1091,8 +1125,7 @@ int sceFontGetCharGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 glyphImagePt DEBUG_LOG(SCEFONT, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i)", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight); auto glyph = PSPPointer::Create(glyphImagePtr); - int altCharCode = font->GetFontLib()->GetAltCharCode(); - font->GetPGF()->DrawCharacter(glyph, clipXPos, clipYPos, clipWidth, clipHeight, charCode, altCharCode, FONT_PGF_CHARGLYPH); + font->DrawCharacter(glyph, clipXPos, clipYPos, clipWidth, clipHeight, charCode, FONT_PGF_CHARGLYPH); return 0; } @@ -1236,8 +1269,7 @@ int sceFontGetShadowGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) DEBUG_LOG(SCEFONT, "sceFontGetShadowGlyphImage(%x, %x, %x)", fontHandle, charCode, glyphImagePtr); auto glyph = PSPPointer::Create(glyphImagePtr); - int altCharCode = font->GetFontLib()->GetAltCharCode(); - font->GetPGF()->DrawCharacter(glyph, -1, -1, -1, -1, charCode, altCharCode, FONT_PGF_SHADOWGLYPH); + font->DrawCharacter(glyph, -1, -1, -1, -1, charCode, FONT_PGF_SHADOWGLYPH); return 0; } @@ -1254,8 +1286,7 @@ int sceFontGetShadowGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 glyphImage DEBUG_LOG(SCEFONT, "sceFontGetShadowGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i)", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight); auto glyph = PSPPointer::Create(glyphImagePtr); - int altCharCode = font->GetFontLib()->GetAltCharCode(); - font->GetPGF()->DrawCharacter(glyph, clipXPos, clipYPos, clipWidth, clipHeight, charCode, altCharCode, FONT_PGF_SHADOWGLYPH); + font->DrawCharacter(glyph, clipXPos, clipYPos, clipWidth, clipHeight, charCode, FONT_PGF_SHADOWGLYPH); return 0; } From 131cbc073c3f43ed821eaef3aacd7dbe3a787446 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Mar 2014 00:18:19 -0800 Subject: [PATCH 08/13] Implement sceFontGetShadowInfo(). --- Core/Font/PGF.cpp | 192 ++++++++++++++++++++++++------------------- Core/Font/PGF.h | 3 +- Core/HLE/sceFont.cpp | 19 ++++- 3 files changed, 123 insertions(+), 91 deletions(-) diff --git a/Core/Font/PGF.cpp b/Core/Font/PGF.cpp index 4f98b59538..8294525246 100644 --- a/Core/Font/PGF.cpp +++ b/Core/Font/PGF.cpp @@ -293,7 +293,7 @@ bool PGF::ReadPtr(const u8 *ptr, size_t dataSize) { // Pregenerate glyphs. for (size_t i = 0; i < glyphs.size(); i++) { - GetGlyph(fontData, charPointers[i] * 4 * 8 /* ??? */, FONT_PGF_CHARGLYPH, glyphs[i]); + ReadCharGlyph(fontData, charPointers[i] * 4 * 8 /* ??? */, glyphs[i]); } // And shadow glyphs. @@ -303,7 +303,7 @@ bool PGF::ReadPtr(const u8 *ptr, size_t dataSize) { size_t charId = shadowMap[shadowId]; if (charId < shadowGlyphs.size()) { // TODO: check for pre existing shadow glyph - GetGlyph(fontData, charPointers[charId] * 4 * 8 /* ??? */, FONT_PGF_SHADOWGLYPH, shadowGlyphs[charId]); + ReadShadowGlyph(fontData, charPointers[charId] * 4 * 8 /* ??? */, shadowGlyphs[charId]); } } } @@ -387,14 +387,39 @@ void PGF::GetFontInfo(PGFFontInfo *fi) const { fi->BPP = header.bpp; } -bool PGF::GetGlyph(const u8 *fontdata, size_t charPtr, int glyphType, Glyph &glyph) { - if (glyphType == FONT_PGF_SHADOWGLYPH) { - if (charPtr + 96 > fontDataSize * 8) - return false; - charPtr += getBits(14, fontdata, charPtr) * 8; - if (charPtr + 96 > fontDataSize * 8) - return false; +bool PGF::ReadShadowGlyph(const u8 *fontdata, size_t charPtr, Glyph &glyph) { + // Most of the glyph info is from the char data. + if (!ReadCharGlyph(fontdata, charPtr, glyph)) + return false; + + // Skip over the char data. + if (charPtr + 96 > fontDataSize * 8) + return false; + charPtr += getBits(14, fontdata, charPtr) * 8; + if (charPtr + 96 > fontDataSize * 8) + return false; + + // Skip size. + charPtr += 14; + + glyph.w = consumeBits(7, fontdata, charPtr); + glyph.h = consumeBits(7, fontdata, charPtr); + + glyph.left = consumeBits(7, fontdata, charPtr); + if (glyph.left >= 64) { + glyph.left -= 128; } + + glyph.top = consumeBits(7, fontdata, charPtr); + if (glyph.top >= 64) { + glyph.top -= 128; + } + + glyph.ptr = (u32)(charPtr / 8); + return true; +} + +bool PGF::ReadCharGlyph(const u8 *fontdata, size_t charPtr, Glyph &glyph) { // Skip size. charPtr += 14; @@ -413,98 +438,93 @@ bool PGF::GetGlyph(const u8 *fontdata, size_t charPtr, int glyphType, Glyph &gly glyph.flags = consumeBits(6, fontdata, charPtr); - if (glyphType == FONT_PGF_CHARGLYPH) { - glyph.shadowFlags = consumeBits(2, fontdata, charPtr) << (2 + 3); - glyph.shadowFlags |= consumeBits(2, fontdata, charPtr) << 3; - glyph.shadowFlags |= consumeBits(3, fontdata, charPtr); + glyph.shadowFlags = consumeBits(2, fontdata, charPtr) << (2 + 3); + glyph.shadowFlags |= consumeBits(2, fontdata, charPtr) << 3; + glyph.shadowFlags |= consumeBits(3, fontdata, charPtr); - glyph.shadowID = consumeBits(9, fontdata, charPtr); + glyph.shadowID = consumeBits(9, fontdata, charPtr); - if ((glyph.flags & FONT_PGF_METRIC_DIMENSION_INDEX) == FONT_PGF_METRIC_DIMENSION_INDEX) - { - int dimensionIndex = consumeBits(8, fontdata, charPtr); + if ((glyph.flags & FONT_PGF_METRIC_DIMENSION_INDEX) == FONT_PGF_METRIC_DIMENSION_INDEX) + { + int dimensionIndex = consumeBits(8, fontdata, charPtr); - if (dimensionIndex < header.dimTableLength) { - glyph.dimensionWidth = dimensionTable[0][dimensionIndex]; - glyph.dimensionHeight = dimensionTable[1][dimensionIndex]; - } - - if (dimensionIndex == 0 && isJPCSPFont(fileName.c_str())) { - // Fonts created by ttf2pgf do not contain complete Glyph information. - // Provide default values. - glyph.dimensionWidth = glyph.w << 6; - glyph.dimensionHeight = glyph.h << 6; - } - } - else - { - glyph.dimensionWidth = consumeBits(32, fontdata, charPtr); - glyph.dimensionHeight = consumeBits(32, fontdata, charPtr); + if (dimensionIndex < header.dimTableLength) { + glyph.dimensionWidth = dimensionTable[0][dimensionIndex]; + glyph.dimensionHeight = dimensionTable[1][dimensionIndex]; } - if ((glyph.flags & FONT_PGF_METRIC_BEARING_X_INDEX) == FONT_PGF_METRIC_BEARING_X_INDEX) - { - int xAdjustIndex = consumeBits(8, fontdata, charPtr); - - if (xAdjustIndex < header.xAdjustTableLength) { - glyph.xAdjustH = xAdjustTable[0][xAdjustIndex]; - glyph.xAdjustV = xAdjustTable[1][xAdjustIndex]; - } - - if (xAdjustIndex == 0 && isJPCSPFont(fileName.c_str())) - { - // Fonts created by ttf2pgf do not contain complete Glyph information. - // Provide default values. - glyph.xAdjustH = glyph.left << 6; - glyph.xAdjustV = glyph.left << 6; - } + if (dimensionIndex == 0 && isJPCSPFont(fileName.c_str())) { + // Fonts created by ttf2pgf do not contain complete Glyph information. + // Provide default values. + glyph.dimensionWidth = glyph.w << 6; + glyph.dimensionHeight = glyph.h << 6; } - else - { - glyph.xAdjustH = consumeBits(32, fontdata, charPtr); - glyph.xAdjustV = consumeBits(32, fontdata, charPtr); + } + else + { + glyph.dimensionWidth = consumeBits(32, fontdata, charPtr); + glyph.dimensionHeight = consumeBits(32, fontdata, charPtr); + } + + if ((glyph.flags & FONT_PGF_METRIC_BEARING_X_INDEX) == FONT_PGF_METRIC_BEARING_X_INDEX) + { + int xAdjustIndex = consumeBits(8, fontdata, charPtr); + + if (xAdjustIndex < header.xAdjustTableLength) { + glyph.xAdjustH = xAdjustTable[0][xAdjustIndex]; + glyph.xAdjustV = xAdjustTable[1][xAdjustIndex]; } - if ((glyph.flags & FONT_PGF_METRIC_BEARING_Y_INDEX) == FONT_PGF_METRIC_BEARING_Y_INDEX) + if (xAdjustIndex == 0 && isJPCSPFont(fileName.c_str())) { - int yAdjustIndex = consumeBits(8, fontdata, charPtr); - - if (yAdjustIndex < header.xAdjustTableLength) { - glyph.yAdjustH = yAdjustTable[0][yAdjustIndex]; - glyph.yAdjustV = yAdjustTable[1][yAdjustIndex]; - } - - if (yAdjustIndex == 0 && isJPCSPFont(fileName.c_str())) - { - // Fonts created by ttf2pgf do not contain complete Glyph information. - // Provide default values. - glyph.yAdjustH = glyph.top << 6; - glyph.yAdjustV = glyph.top << 6; - } + // Fonts created by ttf2pgf do not contain complete Glyph information. + // Provide default values. + glyph.xAdjustH = glyph.left << 6; + glyph.xAdjustV = glyph.left << 6; } - else - { - glyph.yAdjustH = consumeBits(32, fontdata, charPtr); - glyph.yAdjustV = consumeBits(32, fontdata, charPtr); + } + else + { + glyph.xAdjustH = consumeBits(32, fontdata, charPtr); + glyph.xAdjustV = consumeBits(32, fontdata, charPtr); + } + + if ((glyph.flags & FONT_PGF_METRIC_BEARING_Y_INDEX) == FONT_PGF_METRIC_BEARING_Y_INDEX) + { + int yAdjustIndex = consumeBits(8, fontdata, charPtr); + + if (yAdjustIndex < header.xAdjustTableLength) { + glyph.yAdjustH = yAdjustTable[0][yAdjustIndex]; + glyph.yAdjustV = yAdjustTable[1][yAdjustIndex]; } - if ((glyph.flags & FONT_PGF_METRIC_ADVANCE_INDEX) == FONT_PGF_METRIC_ADVANCE_INDEX) + if (yAdjustIndex == 0 && isJPCSPFont(fileName.c_str())) { - int advanceIndex = consumeBits(8, fontdata, charPtr); + // Fonts created by ttf2pgf do not contain complete Glyph information. + // Provide default values. + glyph.yAdjustH = glyph.top << 6; + glyph.yAdjustV = glyph.top << 6; + } + } + else + { + glyph.yAdjustH = consumeBits(32, fontdata, charPtr); + glyph.yAdjustV = consumeBits(32, fontdata, charPtr); + } - if (advanceIndex < header.advanceTableLength) { - glyph.advanceH = advanceTable[0][advanceIndex]; - glyph.advanceV = advanceTable[1][advanceIndex]; - } + if ((glyph.flags & FONT_PGF_METRIC_ADVANCE_INDEX) == FONT_PGF_METRIC_ADVANCE_INDEX) + { + int advanceIndex = consumeBits(8, fontdata, charPtr); + + if (advanceIndex < header.advanceTableLength) { + glyph.advanceH = advanceTable[0][advanceIndex]; + glyph.advanceV = advanceTable[1][advanceIndex]; } - else - { - glyph.advanceH = consumeBits(32, fontdata, charPtr); - glyph.advanceV = consumeBits(32, fontdata, charPtr); - } - } else { - glyph.shadowID = 65535; - glyph.advanceH = 0; + } + else + { + glyph.advanceH = consumeBits(32, fontdata, charPtr); + glyph.advanceV = consumeBits(32, fontdata, charPtr); } glyph.ptr = (u32)(charPtr / 8); diff --git a/Core/Font/PGF.h b/Core/Font/PGF.h index eafc7224e0..88daa8d291 100644 --- a/Core/Font/PGF.h +++ b/Core/Font/PGF.h @@ -273,7 +273,8 @@ public: PGFHeader header; private: - bool GetGlyph(const u8 *fontdata, size_t charPtr, int glyphType, Glyph &glyph); + bool ReadCharGlyph(const u8 *fontdata, size_t charPtr, Glyph &glyph); + bool ReadShadowGlyph(const u8 *fontdata, size_t charPtr, Glyph &glyph); bool GetCharGlyph(int charCode, int glyphType, Glyph &glyph) const; // Unused diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index ee9c3ae982..ef824e28d6 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1048,10 +1048,21 @@ int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) { return 0; } -// Not sure about the arguments. -int sceFontGetShadowInfo(u32 fontHandle, u32 charCode, u32 shadowCharInfoPtr) { - ERROR_LOG_REPORT(SCEFONT, "UNIMPL sceFontGetShadowInfo(%08x, %i, %08x)", fontHandle, charCode, shadowCharInfoPtr); - // TODO +int sceFontGetShadowInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) { + if (!Memory::IsValidAddress(charInfoPtr)) { + ERROR_LOG(SCEFONT, "sceFontGetShadowInfo(%08x, %i, %08x): bad charInfo pointer", fontHandle, charCode, charInfoPtr); + return ERROR_FONT_INVALID_PARAMETER; + } + LoadedFont *font = GetLoadedFont(fontHandle, true); + if (!font) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetShadowInfo(%08x, %i, %08x): bad font", fontHandle, charCode, charInfoPtr); + return ERROR_FONT_INVALID_PARAMETER; + } + + DEBUG_LOG(SCEFONT, "sceFontGetShadowInfo(%08x, %i, %08x)", fontHandle, charCode, charInfoPtr); + auto charInfo = PSPPointer::Create(charInfoPtr); + font->GetCharInfo(charCode, charInfo, FONT_PGF_SHADOWGLYPH); + return 0; } From 0e39b6fe36da4074f17679da737da7c3d06ced1b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Mar 2014 01:30:25 -0800 Subject: [PATCH 09/13] Fix results of sceFontGetFontInfo() for user fonts. --- Core/HLE/sceFont.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index ef824e28d6..8c70f2971c 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -218,6 +218,7 @@ public: private: void Init(const u8 *data, size_t dataSize) { valid_ = pgf_.ReadPtr(data, dataSize); + memset(&style_, 0, sizeof(style_)); style_.fontH = (float)pgf_.header.hSize / 64.0f; style_.fontV = (float)pgf_.header.vSize / 64.0f; style_.fontHRes = (float)pgf_.header.hResolution / 64.0f; From 140982223a93e240c050da53b91547dc9999c56a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Mar 2014 01:30:43 -0800 Subject: [PATCH 10/13] Correct sceFontGetFontInfoByIndexNumber(). It just gets font style info, pretty simple. --- Core/HLE/sceFont.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 8c70f2971c..10e65fac6d 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1023,11 +1023,28 @@ int sceFontGetFontInfo(u32 fontHandle, u32 fontInfoPtr) { return 0; } -int sceFontGetFontInfoByIndexNumber(u32 libHandle, u32 fontInfoPtr, u32 unknown, u32 fontIndex) { - DEBUG_LOG(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i, %i)", libHandle, fontInfoPtr, unknown, fontIndex); +// It says FontInfo but it means Style - this is like sceFontGetFontList(). +int sceFontGetFontInfoByIndexNumber(u32 libHandle, u32 fontInfoPtr, u32 index) { + auto fontStyle = PSPPointer::Create(fontInfoPtr); FontLib *fl = GetFontLib(libHandle); - u32 fontHandle = fl->GetFontHandle(fontIndex); - return sceFontGetFontInfo(fontHandle, fontInfoPtr); + if (!fl || fl->handle() == 0) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i): invalid font lib", libHandle, fontInfoPtr, index); + return !fl ? ERROR_FONT_INVALID_LIBID : ERROR_FONT_INVALID_PARAMETER; + } + if (index >= internalFonts.size()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i): invalid font index", libHandle, fontInfoPtr, index); + return ERROR_FONT_INVALID_PARAMETER; + } + if (!fontStyle.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i): invalid info pointer", libHandle, fontInfoPtr, index); + return ERROR_FONT_INVALID_PARAMETER; + } + + DEBUG_LOG(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i, %i)", libHandle, fontInfoPtr, index); + auto font = internalFonts[index]; + *fontStyle = font->GetFontStyle(); + + return 0; } int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) { @@ -1311,7 +1328,7 @@ const HLEFunction sceLibFont[] = { {0x099ef33c, WrapI_UUU, "sceFontFindOptimumFont"}, {0x681e61a7, WrapI_UUU, "sceFontFindFont"}, {0x2f67356a, WrapI_V, "sceFontCalcMemorySize"}, - {0x5333322d, WrapI_UUUU, "sceFontGetFontInfoByIndexNumber"}, + {0x5333322d, WrapI_UUU, "sceFontGetFontInfoByIndexNumber"}, {0xa834319d, WrapU_UUUU, "sceFontOpen"}, {0x57fcb733, WrapU_UCUU, "sceFontOpenUserFile"}, {0xbb8e7fe6, WrapU_UUUU, "sceFontOpenUserMemory"}, From 160d5e327989bdb3504a0dde8f5e0e5fbe54ff6a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Mar 2014 01:47:35 -0800 Subject: [PATCH 11/13] Fix sceFontGetFontList() error codes. --- Core/HLE/sceFont.cpp | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 10e65fac6d..26b5b33921 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1028,19 +1028,19 @@ int sceFontGetFontInfoByIndexNumber(u32 libHandle, u32 fontInfoPtr, u32 index) { auto fontStyle = PSPPointer::Create(fontInfoPtr); FontLib *fl = GetFontLib(libHandle); if (!fl || fl->handle() == 0) { - ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i): invalid font lib", libHandle, fontInfoPtr, index); + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%08x, %08x, %i): invalid font lib", libHandle, fontInfoPtr, index); return !fl ? ERROR_FONT_INVALID_LIBID : ERROR_FONT_INVALID_PARAMETER; } if (index >= internalFonts.size()) { - ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i): invalid font index", libHandle, fontInfoPtr, index); + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%08x, %08x, %i): invalid font index", libHandle, fontInfoPtr, index); return ERROR_FONT_INVALID_PARAMETER; } if (!fontStyle.IsValid()) { - ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i): invalid info pointer", libHandle, fontInfoPtr, index); + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontInfoByIndexNumber(%08x, %08x, %i): invalid info pointer", libHandle, fontInfoPtr, index); return ERROR_FONT_INVALID_PARAMETER; } - DEBUG_LOG(SCEFONT, "sceFontGetFontInfoByIndexNumber(%x, %x, %i, %i)", libHandle, fontInfoPtr, index); + DEBUG_LOG(SCEFONT, "sceFontGetFontInfoByIndexNumber(%08x, %08x, %i)", libHandle, fontInfoPtr, index); auto font = internalFonts[index]; *fontStyle = font->GetFontStyle(); @@ -1178,16 +1178,26 @@ int sceFontFlush(u32 fontHandle) { // One would think that this should loop through the fonts loaded in the fontLibHandle, // but it seems not. -int sceFontGetFontList(u32 fontLibHandle, u32 fontStylePtr, u32 numFonts) { - INFO_LOG(SCEFONT, "sceFontGetFontList(%08x, %08x, %i)", fontLibHandle, fontStylePtr, numFonts); - numFonts = std::min(numFonts, (u32)internalFonts.size()); - for (u32 i = 0; i < numFonts; i++) - { - PGFFontStyle style = internalFonts[i]->GetFontStyle(); - Memory::WriteStruct(fontStylePtr, &style); - fontStylePtr += sizeof(style); +int sceFontGetFontList(u32 fontLibHandle, u32 fontStylePtr, int numFonts) { + auto fontStyles = PSPPointer::Create(fontStylePtr); + FontLib *fl = GetFontLib(fontLibHandle); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontList(%08x, %08x, %i): invalid font lib", fontLibHandle, fontStylePtr, numFonts); + return ERROR_FONT_INVALID_LIBID; } - return 0; + if (!fontStyles.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetFontList(%08x, %08x, %i): invalid style pointer", fontLibHandle, fontStylePtr, numFonts); + return ERROR_FONT_INVALID_PARAMETER; + } + + DEBUG_LOG(SCEFONT, "sceFontGetFontList(%08x, %08x, %i)", fontLibHandle, fontStylePtr, numFonts); + if (fl->handle() != 0) { + numFonts = std::min(numFonts, (int)internalFonts.size()); + for (int i = 0; i < numFonts; i++) + fontStyles[i] = internalFonts[i]->GetFontStyle(); + } + + return hleDelayResult(0, "font list read", 100); } int sceFontGetNumFontList(u32 fontLibHandle, u32 errorCodePtr) { @@ -1324,7 +1334,7 @@ const HLEFunction sceLibFont[] = { {0x574b6fbc, WrapI_U, "sceFontDoneLib"}, {0x48293280, WrapI_UFF, "sceFontSetResolution"}, {0x27f6e642, WrapI_UU, "sceFontGetNumFontList"}, - {0xbc75d85b, WrapI_UUU, "sceFontGetFontList"}, + {0xbc75d85b, WrapI_UUI, "sceFontGetFontList"}, {0x099ef33c, WrapI_UUU, "sceFontFindOptimumFont"}, {0x681e61a7, WrapI_UUU, "sceFontFindFont"}, {0x2f67356a, WrapI_V, "sceFontCalcMemorySize"}, From 58e29062a5be45d3eb6bcd35c72134bc6de395dc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Mar 2014 01:54:15 -0800 Subject: [PATCH 12/13] Improve error checking in sceFontGetNumFontList(). --- Core/HLE/sceFont.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 26b5b33921..2773bd860e 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -1201,10 +1201,20 @@ int sceFontGetFontList(u32 fontLibHandle, u32 fontStylePtr, int numFonts) { } int sceFontGetNumFontList(u32 fontLibHandle, u32 errorCodePtr) { - INFO_LOG(SCEFONT, "sceFontGetNumFontList(%08x, %08x)", fontLibHandle, errorCodePtr); - if (Memory::IsValidAddress(errorCodePtr)) - Memory::Write_U32(0, errorCodePtr); - return (int)internalFonts.size(); + auto errorCode = PSPPointer::Create(errorCodePtr); + if (!errorCode.IsValid()) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetNumFontList(%08x, %08x): invalid error address", fontLibHandle, errorCodePtr); + return ERROR_FONT_INVALID_PARAMETER; + } + FontLib *fl = GetFontLib(fontLibHandle); + if (!fl) { + ERROR_LOG_REPORT(SCEFONT, "sceFontGetNumFontList(%08x, %08x): invalid font lib", fontLibHandle, errorCodePtr); + *errorCode = ERROR_FONT_INVALID_LIBID; + return 0; + } + DEBUG_LOG(SCEFONT, "sceFontGetNumFontList(%08x, %08x)", fontLibHandle, errorCodePtr); + *errorCode = 0; + return fl->handle() == 0 ? 0 : (int)internalFonts.size(); } int sceFontSetResolution(u32 fontLibHandle, float hRes, float vRes) { From 1b5e54abb4bfdc07fd9eadc8f75a60121e896680 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 1 Mar 2014 02:17:11 -0800 Subject: [PATCH 13/13] Fix nearest size check in optimum, cleanup. --- Core/HLE/sceFont.cpp | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 2773bd860e..1d212985ab 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -161,7 +161,7 @@ public: const PGFFontStyle &GetFontStyle() const { return style_; } - MatchQuality MatchesStyle(const PGFFontStyle &style, bool optimum) const { + MatchQuality MatchesStyle(const PGFFontStyle &style) const { // If no field matches, it doesn't match. MatchQuality match = MATCH_UNKNOWN; @@ -658,26 +658,6 @@ Style FontStyleFromString(const std::string &str) { return FONT_STYLE_REGULAR; } -Font *GetOptimumFont(const PGFFontStyle &requestedStyle, Font *optimumFont, Font *candidateFont) { - if (!optimumFont) - return candidateFont; - PGFFontStyle optimumStyle = optimumFont->GetFontStyle(); - PGFFontStyle candidateStyle = candidateFont->GetFontStyle(); - - bool testH = requestedStyle.fontH != 0.0f || requestedStyle.fontV == 0.0f; - if (testH && fabsf(requestedStyle.fontH - optimumStyle.fontH) > fabsf(requestedStyle.fontH - candidateStyle.fontH)) { - return candidateFont; - } - - // Check the fontV if it is specified or both fontH and fontV are unspecified - bool testV = requestedStyle.fontV != 0.f || requestedStyle.fontH == 0.f; - if (testV && fabsf(requestedStyle.fontV - optimumStyle.fontV) > fabsf(requestedStyle.fontV - candidateStyle.fontV)) { - return candidateFont; - } - - return optimumFont; -} - int GetInternalFontIndex(Font *font) { for (size_t i = 0; i < internalFonts.size(); i++) { if (internalFonts[i] == font) @@ -921,16 +901,17 @@ int sceFontFindOptimumFont(u32 libHandle, u32 fontStylePtr, u32 errorCodePtr) { float hRes = requestedStyle->fontHRes > 0.0f ? requestedStyle->fontHRes : fontLib->FontHRes(); float vRes = requestedStyle->fontVRes > 0.0f ? requestedStyle->fontVRes : fontLib->FontVRes(); Font *optimumFont = 0; + Font *nearestFont = 0; float nearestDist = std::numeric_limits::infinity(); for (size_t i = 0; i < internalFonts.size(); i++) { - MatchQuality q = internalFonts[i]->MatchesStyle(*requestedStyle, true); + MatchQuality q = internalFonts[i]->MatchesStyle(*requestedStyle); if (q != MATCH_NONE) { auto matchStyle = internalFonts[i]->GetFontStyle(); if (requestedStyle->fontH > 0.0f) { float hDist = abs(matchStyle.fontHRes * matchStyle.fontH - hRes * requestedStyle->fontH); if (hDist < nearestDist) { nearestDist = hDist; - q = MATCH_GOOD; + nearestFont = internalFonts[i]; } } if (requestedStyle->fontV > 0.0f) { @@ -938,7 +919,7 @@ int sceFontFindOptimumFont(u32 libHandle, u32 fontStylePtr, u32 errorCodePtr) { float vDist = abs(matchStyle.fontVRes * matchStyle.fontV - vRes * requestedStyle->fontH); if (vDist < nearestDist) { nearestDist = vDist; - q = MATCH_GOOD; + nearestFont = internalFonts[i]; } } } @@ -946,6 +927,9 @@ int sceFontFindOptimumFont(u32 libHandle, u32 fontStylePtr, u32 errorCodePtr) { optimumFont = internalFonts[i]; } } + if (nearestFont) { + optimumFont = nearestFont; + } if (optimumFont) { *errorCode = 0; return GetInternalFontIndex(optimumFont); @@ -984,7 +968,7 @@ int sceFontFindFont(u32 libHandle, u32 fontStylePtr, u32 errorCodePtr) { float hRes = requestedStyle->fontHRes > 0.0f ? requestedStyle->fontHRes : fontLib->FontHRes(); float vRes = requestedStyle->fontVRes > 0.0f ? requestedStyle->fontVRes : fontLib->FontVRes(); for (size_t i = 0; i < internalFonts.size(); i++) { - if (internalFonts[i]->MatchesStyle(*requestedStyle, false) != MATCH_NONE) { + if (internalFonts[i]->MatchesStyle(*requestedStyle) != MATCH_NONE) { auto matchStyle = internalFonts[i]->GetFontStyle(); if (requestedStyle->fontH > 0.0f) { float hDist = abs(matchStyle.fontHRes * matchStyle.fontH - hRes * requestedStyle->fontH);