diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 8a4ee5ed92..7017cb76d7 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -38,6 +38,9 @@ enum { // Actions static int actionPostAllocCallback; static int actionPostOpenCallback; +static int actionPostOpenAllocCallback; +static int actionPostCharInfoAllocCallback; +static int actionPostCharInfoFreeCallback; // Monster Hunter sequence: // 36:46:998 c:\dev\ppsspp\core\hle\scefont.cpp:469 E[HLE]: sceFontNewLib 89ad4a0, 9fff5cc @@ -82,30 +85,31 @@ struct FontRegistryEntry { const char *fontName; int expireDate; int shadow_option; + u32 fontFileSize; bool ignoreIfMissing; }; static const FontRegistryEntry fontRegistry[] = { // This was added for Chinese translations and is not normally loaded on a PSP. - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_CHINESE, 0, 1, "zh_gb.pgf", "FTT-NewRodin Pro DB", 0, 0, true }, - { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_JAPANESE, 0, 1, "jpn0.pgf", "FTT-NewRodin Pro DB", 0, 0 }, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn0.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn1.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn2.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn3.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn4.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn5.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn6.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn7.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn8.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn9.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn10.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn11.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn12.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn13.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn14.pgf", "FTT-NewRodin Pro Latin", 0, 0}, - {0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn15.pgf", "FTT-Matisse Pro Latin", 0, 0}, - {0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_KOREAN, 0, 3, "kr0.pgf", "AsiaNHH(512Johab)", 0, 0}, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_CHINESE, 0, 1, "zh_gb.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700, true }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_DB, 0, FONT_LANGUAGE_JAPANESE, 0, 1, "jpn0.pgf", "FTT-NewRodin Pro DB", 0, 0, 1581700 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn0.pgf", "FTT-NewRodin Pro Latin", 0, 0, 69108 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn1.pgf", "FTT-Matisse Pro Latin", 0, 0, 65124 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn2.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72948 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn3.pgf", "FTT-Matisse Pro Latin", 0, 0, 67700}, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn4.pgf", "FTT-NewRodin Pro Latin", 0, 0, 72828 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn5.pgf", "FTT-Matisse Pro Latin", 0, 0, 68220 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn6.pgf", "FTT-NewRodin Pro Latin", 0, 0, 77032 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn7.pgf", "FTT-Matisse Pro Latin", 0, 0, 71144 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn8.pgf", "FTT-NewRodin Pro Latin", 0, 0, 41000 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn9.pgf", "FTT-Matisse Pro Latin", 0, 0, 40164 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn10.pgf", "FTT-NewRodin Pro Latin", 0, 0, 42692 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn11.pgf", "FTT-Matisse Pro Latin", 0, 0, 41488 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn12.pgf", "FTT-NewRodin Pro Latin", 0, 0, 43136 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn13.pgf", "FTT-Matisse Pro Latin", 0, 0, 41772 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn14.pgf", "FTT-NewRodin Pro Latin", 0, 0, 45184 }, + { 0x1c0, 0x1c0, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SERIF, FONT_STYLE_BOLD_ITALIC, 0, FONT_LANGUAGE_LATIN, 0, 1, "ltn15.pgf", "FTT-Matisse Pro Latin", 0, 0, 43044 }, + { 0x288, 0x288, 0x2000, 0x2000, 0, 0, FONT_FAMILY_SANS_SERIF, FONT_STYLE_REGULAR, 0, FONT_LANGUAGE_KOREAN, 0, 3, "kr0.pgf", "AsiaNHH(512Johab)", 0, 0, 394192 }, }; static const float pointDPI = 72.f; @@ -204,6 +208,7 @@ public: PGF *GetPGF() { return &pgf_; } const PGF *GetPGF() const { return &pgf_; } + u32 getSize() const { return dataSize_; } bool IsValid() const { return valid_; } void DoState(PointerWrap &p) { @@ -228,6 +233,7 @@ private: style_.fontV = (float)pgf_.header.vSize / 64.0f; style_.fontHRes = (float)pgf_.header.hResolution / 64.0f; style_.fontVRes = (float)pgf_.header.vResolution / 64.0f; + this->dataSize_ = (u32)dataSize; } void Init(const u8 *data, size_t dataSize, const FontRegistryEntry &entry) { @@ -247,11 +253,13 @@ private: strncpy(style_.fontFileName, entry.fileName, sizeof(style_.fontFileName)); style_.fontAttributes = entry.extraAttributes; style_.fontExpire = entry.expireDate; + this->dataSize_ = entry.fontFileSize; } PGF pgf_; PGFFontStyle style_; bool valid_; + u32 dataSize_; DISALLOW_COPY_AND_ASSIGN(Font); }; @@ -378,6 +386,69 @@ private: u32 fontLibID_; }; +class PostOpenAllocCallback : public Action { +public: + PostOpenAllocCallback() {} + static Action *Create() { return new PostOpenAllocCallback(); } + void DoState(PointerWrap &p) override { + auto s = p.Section("PostOpenAllocCallback", 1); + if (!s) + return; + + p.Do(fontLibID_); + p.Do(fontHandle_); + p.Do(fontIndex_); + } + void run(MipsCall &call) override; + void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } + void SetFont(u32 handle, int index) { fontHandle_ = handle; fontIndex_ = index; } + +private: + u32 fontLibID_; + u32 fontHandle_; + int fontIndex_; +}; + +class PostCharInfoAllocCallback : public Action { +public: + PostCharInfoAllocCallback() {} + static Action *Create() { return new PostCharInfoAllocCallback(); } + void DoState(PointerWrap &p) override { + auto s = p.Section("PostCharInfoAllocCallback", 1); + if (!s) + return; + + p.Do(fontLibID_); + } + void run(MipsCall &call) override; + void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } + +private: + u32 fontLibID_; +}; + +class PostCharInfoFreeCallback : public Action { +public: + PostCharInfoFreeCallback() {} + static Action *Create() { return new PostCharInfoFreeCallback(); } + void DoState(PointerWrap &p) override { + auto s = p.Section("PostCharInfoFreeCallback", 1); + if (!s) + return; + + p.Do(fontLibID_); + p.Do(charInfo_); + } + void run(MipsCall &call) override; + void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } + void SetCharInfo(PSPPointer charInfo) { charInfo_ = charInfo; } + +private: + u32 fontLibID_; + PSPPointer charInfo_; +}; + + struct NativeFontLib { FontNewLibParams params; // TODO @@ -406,7 +477,7 @@ public: // For save states only. } - FontLib(u32 paramPtr, u32 errorCodePtr) : fontHRes_(128.0f), fontVRes_(128.0f), altCharCode_(0x5F) { + FontLib(u32 paramPtr, u32 errorCodePtr) : fontHRes_(128.0f), fontVRes_(128.0f), altCharCode_(0x5F), charInfoBitmapAddress_(0) { nfl_ = 0; Memory::ReadStruct(paramPtr, ¶ms_); if (params_.numFonts > 9) { @@ -427,11 +498,13 @@ public: } void Done() { + bool needPending = false; for (size_t i = 0; i < fonts_.size(); i++) { if (isfontopen_[i] == FONT_IS_OPEN) { - fontMap[fonts_[i]]->Close(); + CloseFont(fontMap[fonts_[i]]); delete fontMap[fonts_[i]]; fontMap.erase(fonts_[i]); + needPending = true; // Pending all the next mipcalls. } } u32 args[2] = { params_.userDataAddr, (u32)handle_ }; @@ -442,12 +515,14 @@ public: handle_ = 0; fonts_.clear(); isfontopen_.clear(); + openAllocatedAddresses_.clear(); } void AllocDone(u32 allocatedAddr) { handle_ = allocatedAddr; fonts_.resize(params_.numFonts); isfontopen_.resize(params_.numFonts); + openAllocatedAddresses_.resize(params_.numFonts); for (size_t i = 0; i < fonts_.size(); i++) { u32 addr = allocatedAddr + 0x4C + (u32)i * 0x4C; isfontopen_[i] = 0; @@ -471,6 +546,9 @@ public: u32 handle() const { return handle_; } int numFonts() const { return params_.numFonts; } + u32_le userDataAddr() const{ return params_.userDataAddr; } + u32_le allocFuncAddr() const { return params_.allocFuncAddr; } + u32_le freeFuncAddr() const { return params_.freeFuncAddr; } void SetResolution(float hres, float vres) { fontHRes_ = hres; @@ -524,21 +602,55 @@ public: delete prevFont->second; } fontMap[loadedFont->Handle()] = loadedFont; + + u32 allocSize = 12; + if (mode == FONT_OPEN_INTERNAL_STINGY) { + allocSize = 0x239B4; + } else if (mode == FONT_OPEN_INTERNAL_FULL) { + allocSize += loadedFont->GetFont()->getSize(); + } + + PostOpenAllocCallback *action = (PostOpenAllocCallback *)__KernelCreateAction(actionPostOpenAllocCallback); + action->SetFontLib(GetListID()); + action->SetFont(loadedFont->Handle(), freeFontIndex); + + u32 args[2] = { params_.userDataAddr, allocSize }; + __KernelDirectMipsCall(params_.allocFuncAddr, action, args, 2, true); + return loadedFont; } - void CloseFont(LoadedFont *font) { + void CloseFont(LoadedFont *font, bool needPending = false) { + if (charInfoBitmapAddress_ != 0) + needPending = true; + + flushFont(); + for (size_t i = 0; i < fonts_.size(); i++) { if (fonts_[i] == font->Handle()) { isfontopen_[i] = 0; - + if (openAllocatedAddresses_[i] != 0) { + u32 args[2] = { userDataAddr(), openAllocatedAddresses_[i] }; + __KernelDirectMipsCall(freeFuncAddr(), 0, args, 2, true, needPending); + openAllocatedAddresses_[i] = 0; + } + break; } } + font->Close(); } + void flushFont() { + if (charInfoBitmapAddress_ != 0) { + u32 args[2] = { userDataAddr(), charInfoBitmapAddress_ }; + __KernelDirectMipsCall(freeFuncAddr(), 0, args, 2, true); + charInfoBitmapAddress_ = 0; + } + } + void DoState(PointerWrap &p) { - auto s = p.Section("FontLib", 1, 2); + auto s = p.Section("FontLib", 1, 3); if (!s) return; @@ -555,6 +667,14 @@ public: } else { nfl_ = 0; } + + if (s >= 3) { + p.Do(openAllocatedAddresses_); + p.Do(charInfoBitmapAddress_); + } else { + openAllocatedAddresses_.resize(params_.numFonts); + charInfoBitmapAddress_ = 0; + } } void SetFileFontHandle(u32 handle) { @@ -563,6 +683,19 @@ public: u32 GetAltCharCode() const { return altCharCode_; } + u32 GetOpenAllocatedAddress(int index) const { + if(index < numFonts()) + return openAllocatedAddresses_[index]; + } + + void SetOpenAllocatedAddress(int index, u32 addr) { + if (index < numFonts()) + openAllocatedAddresses_[index] = addr; + } + + u32 GetCharInfoBitmapAddress() const { return charInfoBitmapAddress_; } + void SetCharInfoBitmapAddress(u32 addr) { charInfoBitmapAddress_ = addr; } + private: std::vector fonts_; std::vector isfontopen_; @@ -573,6 +706,8 @@ private: int fileFontHandle_; int handle_; int altCharCode_; + std::vector openAllocatedAddresses_; + u32 charInfoBitmapAddress_; PSPPointer nfl_; DISALLOW_COPY_AND_ASSIGN(FontLib); @@ -601,6 +736,36 @@ void PostOpenCallback::run(MipsCall &call) { fontLib->SetFileFontHandle(v0); } +void PostOpenAllocCallback::run(MipsCall &call) { + FontLib *fontLib = fontLibList[fontLibID_]; + u32 v0 = currentMIPS->r[MIPS_REG_V0]; + fontLib->SetOpenAllocatedAddress(fontIndex_, v0); + call.setReturnValue(fontHandle_); +} + +void PostCharInfoAllocCallback::run(MipsCall &call) { + FontLib *fontLib = fontLibList[fontLibID_]; + u32 v0 = currentMIPS->r[MIPS_REG_V0]; + if (v0 == 0) { + call.setReturnValue(ERROR_FONT_OUT_OF_MEMORY); // From JPCSP, if alloc size is 0, still this error value? + } else { + fontLib->SetCharInfoBitmapAddress(v0); + call.setReturnValue(0); + } +} + +void PostCharInfoFreeCallback::run(MipsCall &call) { + FontLib *fontLib = fontLibList[fontLibID_]; + fontLib->SetCharInfoBitmapAddress(0); + + u32 allocSize = charInfo_->bitmapWidth * charInfo_->bitmapHeight; + PostCharInfoAllocCallback *action = (PostCharInfoAllocCallback *)__KernelCreateAction(actionPostCharInfoAllocCallback); + action->SetFontLib(fontLibID_); + + u32 args[2] = { fontLib->userDataAddr(), allocSize }; + __KernelDirectMipsCall(fontLib->allocFuncAddr(), action, args, 2, true, true); +} + inline bool LoadedFont::GetCharInfo(int charCode, PGFCharInfo *charInfo, int glyphType) const { auto fontLib = GetFontLib(); int altCharCode = fontLib == NULL ? -1 : fontLib->GetAltCharCode(); @@ -711,6 +876,9 @@ int GetInternalFontIndex(Font *font) { void __FontInit() { actionPostAllocCallback = __KernelRegisterActionType(PostAllocCallback::Create); actionPostOpenCallback = __KernelRegisterActionType(PostOpenCallback::Create); + actionPostOpenAllocCallback = __KernelRegisterActionType(PostOpenAllocCallback::Create); + actionPostCharInfoAllocCallback = __KernelRegisterActionType(PostCharInfoAllocCallback::Create); + actionPostCharInfoFreeCallback = __KernelRegisterActionType(PostCharInfoFreeCallback::Create); } void __FontShutdown() { @@ -747,6 +915,12 @@ void __FontDoState(PointerWrap &p) { __KernelRestoreActionType(actionPostAllocCallback, PostAllocCallback::Create); p.Do(actionPostOpenCallback); __KernelRestoreActionType(actionPostOpenCallback, PostOpenCallback::Create); + p.Do(actionPostOpenAllocCallback); + __KernelRestoreActionType(actionPostOpenAllocCallback, PostOpenAllocCallback::Create); + p.Do(actionPostCharInfoAllocCallback); + __KernelRestoreActionType(actionPostCharInfoAllocCallback, PostCharInfoAllocCallback::Create); + p.Do(actionPostCharInfoFreeCallback); + __KernelRestoreActionType(actionPostCharInfoFreeCallback, PostCharInfoFreeCallback::Create); } static u32 sceFontNewLib(u32 paramPtr, u32 errorCodePtr) { @@ -912,14 +1086,12 @@ static u32 sceFontOpenUserFile(u32 libHandle, const char *fileName, u32 mode, u3 static int sceFontClose(u32 fontHandle) { LoadedFont *font = GetLoadedFont(fontHandle, false); - if (font) - { + if (font) { DEBUG_LOG(SCEFONT, "sceFontClose(%x)", fontHandle); FontLib *fontLib = font->GetFontLib(); if (fontLib) fontLib->CloseFont(font); - } - else + } else ERROR_LOG(SCEFONT, "sceFontClose(%x) - font not open?", fontHandle); return 0; } @@ -1100,6 +1272,24 @@ static int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) { auto charInfo = PSPPointer::Create(charInfoPtr); font->GetCharInfo(charCode, charInfo); + u32 allocSize = charInfo->bitmapWidth * charInfo->bitmapHeight; + if (charInfo->sfp26AdvanceH != 0 || charInfo->sfp26AdvanceV != 0) { + if (font->GetFontLib()->GetCharInfoBitmapAddress() != 0) { + PostCharInfoFreeCallback *action = (PostCharInfoFreeCallback *)__KernelCreateAction(actionPostCharInfoFreeCallback); + action->SetFontLib(font->GetFontLib()->GetListID()); + action->SetCharInfo(charInfo); + + u32 args[2] = { font->GetFontLib()->userDataAddr(), font->GetFontLib()->GetCharInfoBitmapAddress() }; + __KernelDirectMipsCall(font->GetFontLib()->freeFuncAddr(), action, args, 2, true); + } else { + PostCharInfoAllocCallback *action = (PostCharInfoAllocCallback *)__KernelCreateAction(actionPostCharInfoAllocCallback); + action->SetFontLib(font->GetFontLib()->GetListID()); + + u32 args[2] = { font->GetFontLib()->userDataAddr(), allocSize }; + __KernelDirectMipsCall(font->GetFontLib()->allocFuncAddr(), action, args, 2, true); + } + } + return 0; } @@ -1215,7 +1405,15 @@ static int sceFontSetAltCharacterCode(u32 fontLibHandle, u32 charCode) { static int sceFontFlush(u32 fontHandle) { INFO_LOG(SCEFONT, "sceFontFlush(%i)", fontHandle); - // Probably don't need to do anything here. + + LoadedFont *font = GetLoadedFont(fontHandle, true); + if (!font) { + ERROR_LOG_REPORT(SCEFONT, "sceFontFlush(%08x): bad font", fontHandle); + return ERROR_FONT_INVALID_PARAMETER; + } + + font->GetFontLib()->flushFont(); + return 0; } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 53b8895304..bf5aefa2e7 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -3128,7 +3128,7 @@ static bool __CanExecuteCallbackNow(Thread *thread) { return g_inCbCount == 0; } -void __KernelCallAddress(Thread *thread, u32 entryPoint, Action *afterAction, const u32 args[], int numargs, bool reschedAfter, SceUID cbId) +void __KernelCallAddress(Thread *thread, u32 entryPoint, Action *afterAction, const u32 args[], int numargs, bool reschedAfter, SceUID cbId, bool forcePending = false) { if (!thread || thread->isStopped()) { WARN_LOG_REPORT(SCEKERNEL, "Running mipscall on dormant thread"); @@ -3179,7 +3179,7 @@ void __KernelCallAddress(Thread *thread, u32 entryPoint, Action *afterAction, co u32 callId = mipsCalls.add(call); bool called = false; - if (!thread || thread == __GetCurrentThread()) { + if ((!thread || thread == __GetCurrentThread()) && !forcePending) { if (__CanExecuteCallbackNow(thread)) { thread = __GetCurrentThread(); __KernelChangeThreadState(thread, THREADSTATUS_RUNNING); @@ -3197,9 +3197,9 @@ void __KernelCallAddress(Thread *thread, u32 entryPoint, Action *afterAction, co } } -void __KernelDirectMipsCall(u32 entryPoint, Action *afterAction, u32 args[], int numargs, bool reschedAfter) +void __KernelDirectMipsCall(u32 entryPoint, Action *afterAction, u32 args[], int numargs, bool reschedAfter, bool forcePending) { - __KernelCallAddress(__GetCurrentThread(), entryPoint, afterAction, args, numargs, reschedAfter, 0); + __KernelCallAddress(__GetCurrentThread(), entryPoint, afterAction, args, numargs, reschedAfter, 0, forcePending); } bool __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter) @@ -3272,7 +3272,7 @@ void __KernelReturnFromMipsCall() // Value returned by the callback function u32 retVal = currentMIPS->r[MIPS_REG_V0]; - DEBUG_LOG(SCEKERNEL,"__KernelReturnFromMipsCall(), returned %08x", retVal); + DEBUG_LOG(SCEKERNEL, "__KernelReturnFromMipsCall(), returned %08x", retVal); // Should also save/restore wait state here. if (call->doAfter) diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 8b95396b97..1e56957f26 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -219,7 +219,7 @@ int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr); class Action; // Not an official Callback object, just calls a mips function on the current thread. -void __KernelDirectMipsCall(u32 entryPoint, Action *afterAction, u32 args[], int numargs, bool reschedAfter); +void __KernelDirectMipsCall(u32 entryPoint, Action *afterAction, u32 args[], int numargs, bool reschedAfter, bool forcePending = false); void __KernelReturnFromMipsCall(); // Called as HLE function bool __KernelInCallback();