Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sceFont and savestate fixes #19347

Merged
merged 7 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading