Skip to content

Commit

Permalink
Merge pull request #19347 from hrydgard/scefont-fixes
Browse files Browse the repository at this point in the history
sceFont and savestate fixes
  • Loading branch information
hrydgard authored Jul 20, 2024
2 parents 11a5dc2 + cf49ff0 commit 5edd02e
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 57 deletions.
2 changes: 1 addition & 1 deletion Common/Render/ManagedTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class TextureLoadTask : public Task {
size_t fileSize;
uint8_t *buffer = g_VFS.ReadFile(filename_.c_str(), &fileSize);
if (!buffer) {
ERROR_LOG(Log::IO, "Failed to read file '%s'", filename_.c_str());
WARN_LOG(Log::IO, "Failed to read file '%s'", filename_.c_str());
filename_.clear();
*state_ = ManagedTexture::LoadState::FAILED;
waitable_->Notify();
Expand Down
4 changes: 4 additions & 0 deletions Common/Serialize/Serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ PointerWrapSection PointerWrap::Section(const char *title, int minVer, int ver)
char marker[16] = {0};
int foundVersion = ver;

curTitle_ = title;

// This is strncpy because we rely on its weird non-null-terminating zero-filling truncation behaviour.
// Can't replace it with the more sensible truncate_cpy because that would break savestates.
strncpy(marker, title, sizeof(marker));
Expand Down Expand Up @@ -122,6 +124,8 @@ void PointerWrap::SetError(Error error_) {
// For the rest of this run, do nothing, to avoid running off the end of memory or something,
// and also not logspam like MEASURE will do in an error case.
mode = PointerWrap::MODE_NOOP;
// Also, remember the bad section.
firstBadSectionTitle_ = curTitle_;
}
}

Expand Down
5 changes: 5 additions & 0 deletions Common/Serialize/Serializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ class PointerWrap
}
}

bool Failed() const {
return error == ERROR_FAILURE;
}

void RewindForWrite(u8 *writePtr);
bool CheckAfterWrite();

Expand Down Expand Up @@ -156,6 +160,7 @@ class PointerWrap

private:
const char *firstBadSectionTitle_ = nullptr;
const char *curTitle_;
u8 *ptrStart_;
std::vector<SerializeCheckpoint> checkpoints_;
size_t curCheckpoint_ = 0;
Expand Down
107 changes: 68 additions & 39 deletions Core/HLE/sceFont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static std::vector<Font *> internalFonts;
// However, these we must save - but we could take a shortcut
// for LoadedFonts that point to internal fonts.
static std::map<u32, LoadedFont *> fontMap;
static std::map<u32, u32> fontLibMap;
static std::map<u32, int> fontLibMap;
// We keep this list to avoid ptr references, even before alloc is called.
static std::vector<FontLib *> fontLibList;

Expand All @@ -152,7 +152,7 @@ enum FontOpenMode {
class Font {
public:
// For savestates only.
Font() {
Font() : valid_(false) {
}

Font(const u8 *data, size_t dataSize) {
Expand Down Expand Up @@ -273,8 +273,7 @@ class Font {
class LoadedFont {
public:
// For savestates only.
LoadedFont() : font_(NULL) {
}
LoadedFont() {}

LoadedFont(Font *font, FontOpenMode mode, u32 fontLibID, u32 handle)
: fontLibID_(fontLibID), font_(font), handle_(handle), mode_(mode), open_(true) {}
Expand All @@ -296,9 +295,18 @@ class LoadedFont {

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_]; }
const FontLib *GetFontLib() const {
_dbg_assert_(IsValid());
return fontLibList[fontLibID_];
}
FontLib *GetFontLib() {
_dbg_assert_(IsValid());
return fontLibList[fontLibID_];
}
u32 Handle() const { return handle_; }
bool IsValid() const {
return fontLibID_ >= 0 && fontLibID_ < (int)fontLibList.size();
}

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;
Expand All @@ -319,7 +327,7 @@ class LoadedFont {
Do(p, numInternalFonts);
// It's okay if numInternalFonts was zero and we've now loaded them.
if (numInternalFonts != (int)internalFonts.size() && numInternalFonts != 0) {
ERROR_LOG(Log::sceFont, "Unable to load state: different internal font count.");
ERROR_LOG(Log::sceFont, "Unable to load state: different internal font count (%d in save, %d in memory)", numInternalFonts, (int)internalFonts.size());
p.SetError(p.ERROR_FAILURE);
return;
}
Expand Down Expand Up @@ -351,11 +359,12 @@ class LoadedFont {
}

private:
u32 fontLibID_;
Font *font_;
u32 handle_;
FontOpenMode mode_;
bool open_;
int fontLibID_ = -1;
Font *font_ = nullptr;
u32 handle_ = 0;
FontOpenMode mode_ = FONT_OPEN_INTERNAL_STINGY;
bool open_ = false;

DISALLOW_COPY_AND_ASSIGN(LoadedFont);
};

Expand All @@ -379,8 +388,10 @@ class PostAllocCallback : public PSPAction {
void SetFontLib(u32 fontLibID, u32 errorCodePtr) { fontLibID_ = fontLibID; errorCodePtr_ = errorCodePtr; }

private:
u32 fontLibID_;
u32 errorCodePtr_;
int fontLibID_ = -1;
u32 errorCodePtr_ = 0;

DISALLOW_COPY_AND_ASSIGN(PostAllocCallback);
};

class PostOpenCallback : public PSPAction {
Expand All @@ -395,10 +406,12 @@ class PostOpenCallback : public PSPAction {
Do(p, fontLibID_);
}
void run(MipsCall &call) override;
void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; }
void SetFontLib(int fontLibID) { fontLibID_ = fontLibID; }

private:
u32 fontLibID_;
int fontLibID_ = -1;

DISALLOW_COPY_AND_ASSIGN(PostOpenCallback);
};

class PostOpenAllocCallback : public PSPAction {
Expand All @@ -415,13 +428,15 @@ class PostOpenAllocCallback : public PSPAction {
Do(p, fontIndex_);
}
void run(MipsCall &call) override;
void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; }
void SetFontLib(int fontLibID) { fontLibID_ = fontLibID; }
void SetFont(u32 handle, int index) { fontHandle_ = handle; fontIndex_ = index; }

private:
u32 fontLibID_;
u32 fontHandle_;
int fontIndex_;
int fontLibID_ = -1;
u32 fontHandle_ = 0;
int fontIndex_ = -1;

DISALLOW_COPY_AND_ASSIGN(PostOpenAllocCallback);
};

class PostCharInfoAllocCallback : public PSPAction {
Expand All @@ -436,10 +451,12 @@ class PostCharInfoAllocCallback : public PSPAction {
Do(p, fontLibID_);
}
void run(MipsCall &call) override;
void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; }
void SetFontLib(int fontLibID) { fontLibID_ = fontLibID; }

private:
u32 fontLibID_;
int fontLibID_ = -1;

DISALLOW_COPY_AND_ASSIGN(PostCharInfoAllocCallback);
};

class PostCharInfoFreeCallback : public PSPAction {
Expand All @@ -455,18 +472,19 @@ class PostCharInfoFreeCallback : public PSPAction {
Do(p, charInfo_);
}
void run(MipsCall &call) override;
void SetFontLib(u32 fontLibID) { fontLibID_ = fontLibID; }
void SetFontLib(int fontLibID) { fontLibID_ = fontLibID; }
void SetCharInfo(PSPPointer<PGFCharInfo> charInfo) { charInfo_ = charInfo; }

private:
u32 fontLibID_;
int fontLibID_ = -1;
PSPPointer<PGFCharInfo> charInfo_;
};

DISALLOW_COPY_AND_ASSIGN(PostCharInfoFreeCallback);
};

struct NativeFontLib {
FontNewLibParams params;
// TODO
// TODO (what?)
u32_le fontInfo1;
u32_le fontInfo2;
u16_le unk1;
Expand All @@ -485,7 +503,7 @@ struct FontImageRect {
};

// A "fontLib" is a container of loaded fonts.
// One can open either "internal" fonts or custom fonts into a fontlib.
// One can open either "internal" fonts or load custom fonts into a fontlib.
class FontLib {
public:
FontLib() {
Expand All @@ -507,8 +525,8 @@ class FontLib {
hleEnqueueCall(allocFuncAddr(), 2, args, action);
}

u32 GetListID() {
return (u32)(std::find(fontLibList.begin(), fontLibList.end(), this) - fontLibList.begin());
int GetListID() {
return (int)(std::find(fontLibList.begin(), fontLibList.end(), this) - fontLibList.begin());
}

void Done() {
Expand Down Expand Up @@ -623,7 +641,7 @@ class FontLib {
// Before replacing it and forgetting about it, let's free it.
delete prevFont->second;
}
fontMap[loadedFont->Handle()] = loadedFont;
fontMap.insert_or_assign(loadedFont->Handle(), loadedFont);
} else {
loadedFont = fontMap[fonts_[foundFontIndex]];
}
Expand Down Expand Up @@ -770,7 +788,6 @@ class FontLib {
DISALLOW_COPY_AND_ASSIGN(FontLib);
};


void PostAllocCallback::run(MipsCall &call) {
INFO_LOG(Log::sceFont, "Entering PostAllocCallback::run");
u32 v0 = currentMIPS->r[MIPS_REG_V0];
Expand All @@ -780,6 +797,7 @@ void PostAllocCallback::run(MipsCall &call) {
Memory::Write_U32(ERROR_FONT_OUT_OF_MEMORY, errorCodePtr_);
call.setReturnValue(0);
} else {
_dbg_assert_(fontLibID_ >= 0);
FontLib *fontLib = fontLibList[fontLibID_];
fontLib->AllocDone(v0);
fontLibMap[fontLib->handle()] = fontLibID_;
Expand All @@ -790,18 +808,21 @@ void PostAllocCallback::run(MipsCall &call) {
}

void PostOpenCallback::run(MipsCall &call) {
_dbg_assert_(fontLibID_ >= 0);
FontLib *fontLib = fontLibList[fontLibID_];
u32 v0 = currentMIPS->r[MIPS_REG_V0];
fontLib->SetFileFontHandle(v0);
}

void PostOpenAllocCallback::run(MipsCall &call) {
_dbg_assert_(fontLibID_ >= 0);
FontLib *fontLib = fontLibList[fontLibID_];
u32 v0 = currentMIPS->r[MIPS_REG_V0];
fontLib->SetOpenAllocatedAddress(fontIndex_, v0);
}

void PostCharInfoAllocCallback::run(MipsCall &call) {
_dbg_assert_(fontLibID_ >= 0);
FontLib *fontLib = fontLibList[fontLibID_];
u32 v0 = currentMIPS->r[MIPS_REG_V0];
if (v0 == 0) {
Expand All @@ -824,20 +845,23 @@ void PostCharInfoFreeCallback::run(MipsCall &call) {
}

inline bool LoadedFont::GetCharInfo(int charCode, PGFCharInfo *charInfo, int glyphType) const {
_dbg_assert_(IsValid());
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 {
_dbg_assert_(IsValid());
auto fontLib = GetFontLib();
int altCharCode = fontLib == NULL ? -1 : fontLib->GetAltCharCode();
GetPGF()->DrawCharacter(image, clipX, clipY, clipWidth, clipHeight, charCode, altCharCode, glyphType);
}

static FontLib *GetFontLib(u32 handle) {
if (fontLibMap.find(handle) != fontLibMap.end()) {
return fontLibList[fontLibMap[handle]];
auto iter = fontLibMap.find(handle);
if (iter != fontLibMap.end()) {
return fontLibList[iter->second];
}
return nullptr;
}
Expand Down Expand Up @@ -935,9 +959,14 @@ void __FontInit() {

void __FontShutdown() {
for (auto iter = fontMap.begin(); iter != fontMap.end(); iter++) {
FontLib *fontLib = iter->second->GetFontLib();
if (fontLib)
fontLib->CloseFont(iter->second, true);
if (iter->second->IsValid()) {
FontLib *fontLib = iter->second->GetFontLib();
if (fontLib) {
fontLib->CloseFont(iter->second, true);
}
} else {
ERROR_LOG(Log::HLE, "__FontShutdown: Bad entry in fontMap");
}
delete iter->second;
}
fontMap.clear();
Expand All @@ -963,7 +992,7 @@ void __FontDoState(PointerWrap &p) {
needInternalFonts = !internalFonts.empty();
Do(p, needInternalFonts);
}
if (needInternalFonts)
if (needInternalFonts && p.mode == PointerWrap::MODE_READ)
__LoadInternalFonts();

Do(p, fontLibList);
Expand Down Expand Up @@ -1477,9 +1506,9 @@ static int sceFontFlush(u32 fontHandle) {
return ERROR_FONT_INVALID_PARAMETER;
}

if (font->GetFontLib())
if (font->GetFontLib()) {
font->GetFontLib()->flushFont();

}
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion Core/HW/SimpleAudioDec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ void AuCtx::DoState(PointerWrap &p) {
Do(p, Channels);
Do(p, MaxOutputSample);
Do(p, readPos);
int audioType = (int)decoder->GetAudioType();
int audioType = decoder ? (int)decoder->GetAudioType() : 0;
Do(p, audioType);
Do(p, BitRate);
Do(p, SamplingRate);
Expand Down
Loading

0 comments on commit 5edd02e

Please sign in to comment.