diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index a87e0094e..7f396abd9 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -3,6 +3,9 @@ #include "base/timeutil.h" #include +#include +#include +#include #include "HLE.h" #include "../MIPS/MIPS.h" @@ -185,43 +188,49 @@ static std::vector internalFonts; // However, these we must save - but we could take a shortcut // for LoadedFonts that point to internal fonts. static std::map fontMap; -static std::map fontLibMap; +static std::map fontLibMap; +// We keep this list to avoid ptr references, even before alloc is called. +static std::vector fontLibList; class PostAllocCallback : public Action { public: PostAllocCallback() {} static Action *Create() { return new PostAllocCallback(); } - void DoState(PointerWrap &p) { /*TODO*/ p.DoMarker("PostAllocCallback"); } + void DoState(PointerWrap &p) { p.Do(fontLibID_); p.DoMarker("PostAllocCallback"); } void run(MipsCall &call); - void SetFontLib(FontLib *fontLib) { fontLib_ = fontLib; } + void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } private: - FontLib *fontLib_; + u32 fontLibID_; }; class PostOpenCallback : public Action { public: PostOpenCallback() {} static Action *Create() { return new PostOpenCallback(); } - void DoState(PointerWrap &p) { /*TODO*/ p.DoMarker("PostOpenCallback"); } + void DoState(PointerWrap &p) { p.Do(fontLibID_); p.DoMarker("PostOpenCallback"); } void run(MipsCall &call); - void SetFontLib(FontLib *fontLib) { fontLib_ = fontLib; } + void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; } private: - FontLib *fontLib_; + u32 fontLibID_; }; // A "fontLib" is a container of loaded fonts. // One can open either "internal" fonts or custom fonts into a fontlib. class FontLib { public: + FontLib() { + // For save states only. + } + FontLib(u32 paramPtr) : fontHRes_(128.0f), fontVRes_(128.0f) { Memory::ReadStruct(paramPtr, ¶ms_); fakeAlloc_ = 0x13370; // We use the same strange scheme that JPCSP uses. u32 allocSize = 4 + 4 * params_.numFonts; PostAllocCallback *action = (PostAllocCallback*) __KernelCreateAction(actionPostAllocCallback); - action->SetFontLib(this); + action->SetFontLib(GetListID()); if (false) { // This fails in dissidia. The function at 088ff320 (params_.allocFuncAddr) calls some malloc function, the second one returns 0 which causes @@ -231,11 +240,15 @@ public: } else { AllocDone(fakeAlloc_); fakeAlloc_ += allocSize; - fontLibMap[handle()] = this; + fontLibMap[handle()] = GetListID(); INFO_LOG(HLE, "Leaving PostAllocCallback::run"); } } + u32 GetListID() { + return (u32)(std::find(fontLibList.begin(), fontLibList.end(), this) - fontLibList.begin()); + } + void Close() { __KernelDirectMipsCall(params_.closeFuncAddr, 0, 0, 0, false); } @@ -312,12 +325,15 @@ public: void DoState(PointerWrap &p) { p.Do(fonts_); + p.Do(isfontopen_); p.Do(params_); p.Do(fontHRes_); p.Do(fontVRes_); p.Do(fileFontHandle_); p.Do(handle_); p.Do(altCharCode_); + p.Do(fakeAlloc_); + p.DoMarker("FontLib"); } void SetFileFontHandle(u32 handle) { @@ -345,19 +361,21 @@ private: void PostAllocCallback::run(MipsCall &call) { INFO_LOG(HLE, "Entering PostAllocCallback::run"); u32 v0 = currentMIPS->r[0]; - fontLib_->AllocDone(call.savedV0); - fontLibMap[fontLib_->handle()] = fontLib_; - call.setReturnValue(fontLib_->handle()); + FontLib *fontLib = fontLibList[fontLibID_]; + fontLib->AllocDone(call.savedV0); + fontLibMap[fontLib->handle()] = fontLibID_; + call.setReturnValue(fontLib->handle()); INFO_LOG(HLE, "Leaving PostAllocCallback::run"); } void PostOpenCallback::run(MipsCall &call) { - fontLib_->SetFileFontHandle(call.savedV0); + FontLib *fontLib = fontLibList[fontLibID_]; + fontLib->SetFileFontHandle(call.savedV0); } FontLib *GetFontLib(u32 handle) { if (fontLibMap.find(handle) != fontLibMap.end()) { - return fontLibMap[handle]; + return fontLibList[fontLibMap[handle]]; } else { ERROR_LOG(HLE, "No fontlib with handle %08x", handle); return 0; @@ -463,9 +481,10 @@ void __FontShutdown() { fontLib->CloseFont(iter->second); } fontMap.clear(); - for (auto iter = fontLibMap.begin(); iter != fontLibMap.end(); iter++) { - delete iter->second; + for (auto iter = fontLibList.begin(); iter != fontLibList.end(); iter++) { + delete *iter; } + fontLibList.clear(); fontLibMap.clear(); for (auto iter = internalFonts.begin(); iter != internalFonts.end(); ++iter) { delete *iter; @@ -474,7 +493,9 @@ void __FontShutdown() { } void __FontDoState(PointerWrap &p) { - // TODO: Needs much work. + p.Do(fontLibList); + p.Do(fontLibMap); + // TODO: p.Do(fontMap); p.Do(actionPostAllocCallback); __KernelRestoreActionType(actionPostAllocCallback, PostAllocCallback::Create); @@ -490,6 +511,7 @@ u32 sceFontNewLib(u32 paramPtr, u32 errorCodePtr) { Memory::Write_U32(0, errorCodePtr); FontLib *newLib = new FontLib(paramPtr); + fontLibList.push_back(newLib); // The game should never see this value, the return value is replaced // by the action. Except if we disable the alloc, in this case we return // the handle correctly here.