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

Bugfix/cclcc saveload #62

Merged
merged 2 commits into from
Sep 19, 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
8 changes: 6 additions & 2 deletions src/data/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ void SaveMemory() {
if (Implementation) Implementation->SaveMemory();
}

void LoadMemory(SaveType type, int id) {
if (Implementation) Implementation->LoadMemory(type, id);
void LoadEntry(SaveType type, int id) {
if (Implementation) Implementation->LoadEntry(type, id);
}

void LoadMemoryNew(LoadProcess load) {
if (Implementation) Implementation->LoadMemoryNew(load);
}

void FlushWorkingSaveEntry(SaveType type, int id) {
Expand Down
8 changes: 6 additions & 2 deletions src/data/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ enum SaveError {

enum SaveType { SaveFull = 0, SaveQuick = 1 };

enum LoadProcess { LoadVars = 0, LoadThread = 1 };

int constexpr MaxSaveEntries = 48;

uint8_t const Flbit[] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
Expand Down Expand Up @@ -66,7 +68,8 @@ class SaveSystemBase {
public:
virtual SaveError MountSaveFile() = 0;
virtual void SaveMemory() = 0;
virtual void LoadMemory(SaveType type, int id) = 0;
virtual void LoadEntry(SaveType type, int id) = 0;
virtual void LoadMemoryNew(LoadProcess){};
virtual void FlushWorkingSaveEntry(SaveType type, int id) = 0;
virtual void WriteSaveFile() = 0;
virtual uint32_t GetSavePlayTime(SaveType type, int id) = 0;
Expand Down Expand Up @@ -104,7 +107,8 @@ void Init();

SaveError MountSaveFile();
void SaveMemory();
void LoadMemory(SaveType type, int id);
void LoadEntry(SaveType type, int id);
void LoadMemoryNew(LoadProcess process);
void FlushWorkingSaveEntry(SaveType type, int id);
void WriteSaveFile();
uint32_t GetSavePlayTime(SaveType type, int id);
Expand Down
175 changes: 84 additions & 91 deletions src/games/cclcc/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
using namespace Impacto::Profile::ScriptVars;
using namespace Impacto::Profile::Vm;

SaveFileEntry* WorkingSaveEntry = 0;

SaveError SaveSystem::MountSaveFile() {
Io::Stream* stream;
IoError err = Io::PhysicalFileStream::Create(SaveFilePath, &stream);
Expand All @@ -37,8 +35,7 @@
case IoError_OK:
break;
};

WorkingSaveEntry = new SaveFileEntry();
WorkingSaveEntry = std::optional<SaveFileEntry>(SaveFileEntry());
WorkingSaveThumbnail.Sheet =
SpriteSheet(Window->WindowWidth, Window->WindowHeight);
WorkingSaveThumbnail.Bounds =
Expand Down Expand Up @@ -209,33 +206,30 @@
break;
}

if (WorkingSaveEntry != 0) {
if (entry != 0) {
Renderer->FreeTexture(entry->SaveThumbnail.Sheet.Texture);
*entry = *WorkingSaveEntry;
time_t rawtime;
time(&rawtime);
entry->SaveDate = *localtime(&rawtime);
auto captureBuffer = Renderer->GetImageFromTexture(
WorkingSaveThumbnail.Sheet.Texture, WorkingSaveThumbnail.Bounds);

Texture tex;
tex.Init(TexFmt_RGBA, SaveThumbnailWidth, SaveThumbnailHeight);

entry->SaveThumbnail.Sheet =
SpriteSheet(SaveThumbnailWidth, SaveThumbnailHeight);
entry->SaveThumbnail.Bounds =
RectF(0.0f, 0.0f, SaveThumbnailWidth, SaveThumbnailHeight);

int result = ResizeImage(
WorkingSaveThumbnail.Bounds, entry->SaveThumbnail.Bounds,
captureBuffer,
tcb::span{tex.Buffer, static_cast<size_t>(tex.BufferSize)}, true);
if (result < 0) {
ImpLog(LL_Error, LC_General, "Failed to resize save thumbnail\n");
}
entry->SaveThumbnail.Sheet.Texture = tex.Submit();
if (entry != 0) {
Renderer->FreeTexture(entry->SaveThumbnail.Sheet.Texture);
*entry = *WorkingSaveEntry;
time_t rawtime;
time(&rawtime);
entry->SaveDate = *localtime(&rawtime);
auto captureBuffer = Renderer->GetImageFromTexture(
WorkingSaveThumbnail.Sheet.Texture, WorkingSaveThumbnail.Bounds);

Texture tex;
tex.Init(TexFmt_RGBA, SaveThumbnailWidth, SaveThumbnailHeight);

entry->SaveThumbnail.Sheet =
SpriteSheet(SaveThumbnailWidth, SaveThumbnailHeight);
entry->SaveThumbnail.Bounds =
RectF(0.0f, 0.0f, SaveThumbnailWidth, SaveThumbnailHeight);

int result = ResizeImage(
WorkingSaveThumbnail.Bounds, entry->SaveThumbnail.Bounds, captureBuffer,
tcb::span{tex.Buffer, static_cast<size_t>(tex.BufferSize)}, true);
if (result < 0) {
ImpLog(LL_Error, LC_General, "Failed to resize save thumbnail\n");
}
entry->SaveThumbnail.Sheet.Texture = tex.Submit();
}
}

Expand Down Expand Up @@ -423,7 +417,7 @@
void SaveSystem::SaveMemory() {
// TODO: Sys save data

if (WorkingSaveEntry != 0) {
if (WorkingSaveEntry) {
WorkingSaveEntry->Status = 1;
WorkingSaveEntry->Checksum = 0; // CalculateChecksum(0);
time_t rawtime;
Expand Down Expand Up @@ -460,80 +454,79 @@
}
}

void SaveSystem::LoadMemory(SaveType type, int id) {
SaveFileEntry* entry = 0;
void SaveSystem::LoadEntry(SaveType type, int id) {
if (!WorkingSaveEntry) {
ImpLog(LL_Error, LC_IO, "Failed to load save memory: no working save\n");
return;
}
switch (type) {
case SaveQuick:
entry = (SaveFileEntry*)QuickSaveEntries[id];
WorkingSaveEntry = *static_cast<SaveFileEntry*>(QuickSaveEntries[id]);
break;
case SaveFull:
entry = (SaveFileEntry*)FullSaveEntries[id];
WorkingSaveEntry = *static_cast<SaveFileEntry*>(FullSaveEntries[id]);
break;
default:
ImpLog(LL_Error, LC_IO,
"Failed to load save memory: unknown save type, doing nothing\n");
return;
}
}

if (entry != 0)
if (entry->Status) {
ScrWork[SW_PLAYTIME] = entry->PlayTime;
ScrWork[SW_TITLE] = entry->SwTitle;

memcpy(&FlagWork[50], entry->FlagWorkScript1, 50);
memcpy(&FlagWork[300], entry->FlagWorkScript2, 100);
memcpy(&ScrWork[1000], entry->ScrWorkScript1, 2400);
memcpy(&ScrWork[4300], entry->ScrWorkScript2, 12000);
UI::MapSystem::MapLoad(entry->MapLoadData);
CCLCC::YesNoTrigger::YesNoTriggerPtr->Load(entry->YesNoData);
// TODO: What to do about this mess I wonder...
ScrWork[SW_SVSENO] = ScrWork[SW_SEREQNO];
ScrWork[SW_SVSENO + 1] = ScrWork[SW_SEREQNO + 1];
ScrWork[SW_SVSENO + 2] = ScrWork[SW_SEREQNO + 2];
ScrWork[SW_SVBGMNO] = ScrWork[SW_BGMREQNO];
ScrWork[SW_SVBGM2NO] = ScrWork[SW_BGMREQNO2];
ScrWork[SW_SVSCRNO1] = ScrWork[SW_SCRIPTNO2];
ScrWork[SW_SVSCRNO2] = ScrWork[SW_SCRIPTNO3];
ScrWork[SW_SVSCRNO3] = ScrWork[SW_SCRIPTNO4];
ScrWork[SW_SVSCRNO4] = ScrWork[SW_SCRIPTNO5];
for (int i = 0; i < 8; i++) {
ScrWork[SW_SVBGNO1 + i] = ScrWork[SW_BG1NO + i * ScrWorkBgStructSize];
ScrWork[SW_SVCHANO1 + i] =
ScrWork[SW_CHA1NO + i * ScrWorkChaStructSize];
}
void SaveSystem::LoadMemoryNew(LoadProcess load) {
if (!WorkingSaveEntry || WorkingSaveEntry->Status == 0) {
ImpLog(LL_Error, LC_IO, "Failed to load entry: save is empty\n");
return;
}
if (load == LoadProcess::LoadVars) {
ScrWork[SW_PLAYTIME] = WorkingSaveEntry->PlayTime;
ScrWork[SW_TITLE] = WorkingSaveEntry->SwTitle;

memcpy(&FlagWork[50], WorkingSaveEntry->FlagWorkScript1, 50);
memcpy(&FlagWork[300], WorkingSaveEntry->FlagWorkScript2, 100);
memcpy(&ScrWork[1000], WorkingSaveEntry->ScrWorkScript1, 2400);
memcpy(&ScrWork[4300], WorkingSaveEntry->ScrWorkScript2, 12000);
UI::MapSystem::MapLoad(WorkingSaveEntry->MapLoadData);
CCLCC::YesNoTrigger::YesNoTriggerPtr->Load(WorkingSaveEntry->YesNoData);
// TODO: What to do about this mess I wonder...
ScrWork[SW_SVSENO] = ScrWork[SW_SEREQNO];
ScrWork[SW_SVSENO + 1] = ScrWork[SW_SEREQNO + 1];
ScrWork[SW_SVSENO + 2] = ScrWork[SW_SEREQNO + 2];
ScrWork[SW_SVBGMNO] = ScrWork[SW_BGMREQNO];
ScrWork[SW_SVBGM2NO] = ScrWork[SW_BGMREQNO2];
ScrWork[SW_SVSCRNO1] = ScrWork[SW_SCRIPTNO2];
ScrWork[SW_SVSCRNO2] = ScrWork[SW_SCRIPTNO3];
ScrWork[SW_SVSCRNO3] = ScrWork[SW_SCRIPTNO4];
ScrWork[SW_SVSCRNO4] = ScrWork[SW_SCRIPTNO5];
for (int i = 0; i < 8; i++) {
ScrWork[SW_SVBGNO1 + i] = ScrWork[SW_BG1NO + i * ScrWorkBgStructSize];
ScrWork[SW_SVCHANO1 + i] = ScrWork[SW_CHA1NO + i * ScrWorkChaStructSize];
}
} else if (ScrWork[SW_MAINTHDP] != 0) {
int threadId = ScrWork[SW_MAINTHDP];
Sc3VmThread* thd = &ThreadPool[threadId & 0x7FFFFFFF];

int threadId = ScrWork[SW_MAINTHDP];
Sc3VmThread* thd = &ThreadPool[threadId & 0x7FFFFFFF];

// Load scripts
if (ScrWork[SW_SVSCRNO1] != 65535) LoadScript(2, ScrWork[SW_SVSCRNO1]);
if (ScrWork[SW_SVSCRNO2] != 65535) LoadScript(3, ScrWork[SW_SVSCRNO2]);
if (ScrWork[SW_SVSCRNO4] != 65535) LoadScript(5, ScrWork[SW_SVSCRNO4]);

ScrWork[SW_SVSCRNO1] = 65535;
ScrWork[SW_SVSCRNO2] = 65535;
ScrWork[SW_SVSCRNO4] = 65535;

if (thd->GroupId - 5 < 3) {
thd->ExecPriority = entry->MainThreadExecPriority;
thd->WaitCounter = entry->MainThreadWaitCounter;
thd->ScriptParam = entry->MainThreadScriptParam;
thd->GroupId = entry->MainThreadGroupId;
thd->ScriptBufferId = entry->MainThreadScriptBufferId;
thd->Ip =
ScriptGetRetAddress(ScriptBuffers[entry->MainThreadScriptBufferId],
entry->MainThreadIp);
thd->CallStackDepth = entry->MainThreadCallStackDepth;

for (int i = 0; i < thd->CallStackDepth; i++) {
thd->ReturnScriptBufferIds[i] = entry->MainThreadReturnBufIds[i];
thd->ReturnIds[i] = entry->MainThreadReturnIds[i];
}
if (thd->GroupId - 5 < 3) {
thd->ExecPriority = WorkingSaveEntry->MainThreadExecPriority;
thd->WaitCounter = WorkingSaveEntry->MainThreadWaitCounter;
thd->ScriptParam = WorkingSaveEntry->MainThreadScriptParam;
thd->GroupId = WorkingSaveEntry->MainThreadGroupId;
thd->ScriptBufferId = WorkingSaveEntry->MainThreadScriptBufferId;
thd->Ip = ScriptGetRetAddress(
ScriptBuffers[WorkingSaveEntry->MainThreadScriptBufferId],
WorkingSaveEntry->MainThreadIp);
thd->CallStackDepth = WorkingSaveEntry->MainThreadCallStackDepth;

memcpy(thd->Variables, entry->MainThreadVariables, 64);
thd->DialoguePageId = entry->MainThreadDialoguePageId;
for (int i = 0; i < thd->CallStackDepth; i++) {
thd->ReturnScriptBufferIds[i] =
WorkingSaveEntry->MainThreadReturnBufIds[i];
thd->ReturnIds[i] = WorkingSaveEntry->MainThreadReturnIds[i];
}

memcpy(thd->Variables, WorkingSaveEntry->MainThreadVariables, 64);
thd->DialoguePageId = WorkingSaveEntry->MainThreadDialoguePageId;
}
}
}

uint8_t SaveSystem::GetSaveStatus(SaveType type, int id) {
Expand Down Expand Up @@ -663,7 +656,7 @@
bool SaveSystem::GetBgmFlag(int id) { return BGMFlags[id]; }

void SaveSystem::SetCheckpointId(int id) {
if (WorkingSaveEntry != nullptr) WorkingSaveEntry->MainThreadIp = id;
if (WorkingSaveEntry) WorkingSaveEntry->MainThreadIp = id;
}

Sprite const& SaveSystem::GetSaveThumbnail(SaveType type, int id) {
Expand All @@ -673,5 +666,5 @@
case SaveFull:
return ((SaveFileEntry*)FullSaveEntries[id])->SaveThumbnail;
}
}

Check warning on line 669 in src/games/cclcc/savesystem.cpp

View workflow job for this annotation

GitHub Actions / linux

control reaches end of non-void function [-Wreturn-type]
} // namespace CCLCC
Expand Down
5 changes: 4 additions & 1 deletion src/games/cclcc/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../../data/savesystem.h"
#include "../../texture/texture.h"
#include "../../spritesheet.h"
#include <optional>

namespace Impacto {
namespace CCLCC {
Expand All @@ -26,7 +27,8 @@ class SaveSystem : public SaveSystemBase {
public:
SaveError MountSaveFile() override;
void SaveMemory() override;
void LoadMemory(SaveType type, int id) override;
void LoadEntry(SaveType type, int id) override;
void LoadMemoryNew(LoadProcess load) override;
void FlushWorkingSaveEntry(SaveType type, int id) override;
void WriteSaveFile() override;
uint32_t GetSavePlayTime(SaveType type, int id) override;
Expand Down Expand Up @@ -54,6 +56,7 @@ class SaveSystem : public SaveSystemBase {
uint8_t MessageFlags[10000];
bool EVFlags[1200];
uint8_t BGMFlags[200];
std::optional<SaveFileEntry> WorkingSaveEntry;
};

} // namespace CCLCC
Expand Down
2 changes: 1 addition & 1 deletion src/games/chlcc/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@
}
}

void SaveSystem::LoadMemory(SaveType type, int id) {
void SaveSystem::LoadEntry(SaveType type, int id) {
SaveFileEntry* entry = 0;
switch (type) {
case SaveQuick:
Expand Down Expand Up @@ -591,5 +591,5 @@
case SaveFull:
return FullSaveEntries[id]->SaveThumbnail;
}
}

Check warning on line 594 in src/games/chlcc/savesystem.cpp

View workflow job for this annotation

GitHub Actions / linux

control reaches end of non-void function [-Wreturn-type]
} // namespace CHLCC
Expand Down
2 changes: 1 addition & 1 deletion src/games/chlcc/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SaveSystem : public SaveSystemBase {
public:
SaveError MountSaveFile() override;
void SaveMemory() override;
void LoadMemory(SaveType type, int id) override;
void LoadEntry(SaveType type, int id) override;
void FlushWorkingSaveEntry(SaveType type, int id) override;
void WriteSaveFile() override;
uint32_t GetSavePlayTime(SaveType type, int id) override;
Expand Down
2 changes: 1 addition & 1 deletion src/games/mo6tw/savesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@
}
}

void SaveSystem::LoadMemory(SaveType type, int id) {
void SaveSystem::LoadEntry(SaveType type, int id) {
SaveFileEntry* entry = 0;
switch (type) {
case SaveQuick:
Expand Down Expand Up @@ -734,5 +734,5 @@
case SaveFull:
return ((SaveFileEntry*)FullSaveEntries[id])->SaveThumbnail;
}
}

Check warning on line 737 in src/games/mo6tw/savesystem.cpp

View workflow job for this annotation

GitHub Actions / linux

control reaches end of non-void function [-Wreturn-type]
} // namespace MO6TW
Expand Down
2 changes: 1 addition & 1 deletion src/games/mo6tw/savesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SaveSystem : public SaveSystemBase {
public:
SaveError MountSaveFile() override;
void SaveMemory() override;
void LoadMemory(SaveType type, int id) override;
void LoadEntry(SaveType type, int id) override;
void FlushWorkingSaveEntry(SaveType type, int id) override;
void WriteSaveFile() override;
uint32_t GetSavePlayTime(SaveType type, int id) override;
Expand Down
10 changes: 4 additions & 6 deletions src/vm/inst_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,8 @@ VmInstruction(InstLoadData) {
case 0:
case 10: {
PopExpression(arg1);
if (Profile::Vm::GameInstructionSet == +InstructionSet::CC) {
PopExpression(arg2);
SaveSystem::LoadMemory(static_cast<SaveSystem::SaveType>(arg1), arg2);
}

PopExpression(arg2);
SaveSystem::LoadEntry(static_cast<SaveSystem::SaveType>(arg1), arg2);
ImpLogSlow(LL_Warning, LC_VMStub,
"STUB instruction LoadData(type: %i, arg1: %i)\n", type, arg1);
} break;
Expand All @@ -451,11 +448,12 @@ VmInstruction(InstLoadData) {
type);
break;
}
SaveSystem::LoadMemoryNew(static_cast<SaveSystem::LoadProcess>(type));
}
VmInstruction(InstLoadDataOld) {
StartInstruction;
PopExpression(arg1);
SaveSystem::LoadMemory(SaveSystem::SaveFull, arg1);
SaveSystem::LoadEntry(SaveSystem::SaveFull, arg1);
if (ScrWork[SW_MESWINDOW_COLOR] == 0) ScrWork[SW_MESWINDOW_COLOR] = 0xFFFFFF;
}
VmInstruction(InstTitleMenu) {
Expand Down
Loading