15#include "lcf/lsd/reader.h"
16#include "lcf/lsd/chunks.h"
17#include "lcf/rpg/save.h"
18#include "lcf/reader_util.h"
24double LSD_Reader::ToTDateTime(std::time_t t) {
26 return(t / 86400.0 + 25569.0);
29std::time_t LSD_Reader::ToUnixTimestamp(
double ms) {
30 return(std::time_t(ms * 86400.0 - 25569.0 * 86400.0 + 0.5));
33double LSD_Reader::GenerateTimestamp(std::time_t t) {
34 return ToTDateTime(t);
37void LSD_Reader::PrepareSave(rpg::Save& save, int32_t version, int32_t codepage) {
38 ++save.system.save_count;
39 save.title.timestamp = LSD_Reader::GenerateTimestamp();
40 save.easyrpg_data.version = version;
41 save.easyrpg_data.codepage = codepage;
44std::unique_ptr<rpg::Save> LSD_Reader::Load(std::string_view filename, std::string_view encoding) {
45 std::ifstream stream(ToString(filename), std::ios::binary);
46 if (!stream.is_open()) {
47 Log::Error(
"Failed to open LSD file '%s' for reading: %s", ToString(filename).c_str(), strerror(errno));
50 return LSD_Reader::Load(stream, encoding);
53bool LSD_Reader::Save(std::string_view filename,
const rpg::Save& save, EngineVersion engine, std::string_view encoding) {
54 std::ofstream stream(ToString(filename), std::ios::binary);
55 if (!stream.is_open()) {
56 Log::Error(
"Failed to open LSD file '%s' for reading: %s", ToString(filename).c_str(), strerror(errno));
59 return LSD_Reader::Save(stream, save, engine, encoding);
62bool LSD_Reader::SaveXml(std::string_view filename,
const rpg::Save& save, EngineVersion engine) {
63 std::ofstream stream(ToString(filename), std::ios::binary);
64 if (!stream.is_open()) {
65 Log::Error(
"Failed to open LSD XML file '%s' for writing: %s", ToString(filename).c_str(), strerror(errno));
68 return LSD_Reader::SaveXml(stream, save, engine);
71std::unique_ptr<rpg::Save> LSD_Reader::LoadXml(std::string_view filename) {
72 std::ifstream stream(ToString(filename), std::ios::binary);
73 if (!stream.is_open()) {
74 Log::Error(
"Failed to open LSD XML file `%s' for reading : %s", ToString(filename).c_str(), strerror(errno));
77 return LSD_Reader::LoadXml(stream);
80std::unique_ptr<rpg::Save> LSD_Reader::Load(std::istream& filestream, std::string_view encoding) {
81 LcfReader reader(filestream, ToString(encoding));
84 LcfReader::SetError(
"Couldn't parse save file.");
88 reader.ReadString(header, reader.ReadInt());
89 if (header.length() != 11) {
90 LcfReader::SetError(
"This is not a valid RPG2000 save.");
93 if (header !=
"LcfSaveData") {
94 Log::Warning(
"Header %s != LcfSaveData and might not be a valid RPG2000 save.", header.c_str());
97 auto pos = reader.Tell();
99 std::unique_ptr<rpg::Save> save(
new rpg::Save());
102 if (save->easyrpg_data.codepage > 0) {
104 filestream.seekg(pos, std::ios_base::beg);
105 LcfReader reader2(filestream, std::to_string(save->easyrpg_data.codepage));
106 if (!reader2.IsOk()) {
107 LcfReader::SetError(
"Couldn't parse save file.");
110 save.reset(
new rpg::Save());
117bool LSD_Reader::Save(std::ostream& filestream,
const rpg::Save& save, EngineVersion engine, std::string_view encoding) {
120 if (save.easyrpg_data.codepage > 0) {
121 enc = std::to_string(save.easyrpg_data.codepage);
123 enc = ToString(encoding);
126 LcfWriter writer(filestream, engine, enc);
127 if (!writer.IsOk()) {
128 LcfReader::SetError(
"Couldn't parse save file.\n");
131 const std::string header(
"LcfSaveData");
132 writer.WriteInt(header.size());
133 writer.Write(header);
139bool LSD_Reader::SaveXml(std::ostream& filestream,
const rpg::Save& save, EngineVersion engine) {
140 XmlWriter writer(filestream, engine);
141 if (!writer.IsOk()) {
142 LcfReader::SetError(
"Couldn't parse save file.");
146 writer.BeginElement(
"LSD");
148 writer.EndElement(
"LSD");
152std::unique_ptr<rpg::Save> LSD_Reader::LoadXml(std::istream& filestream) {
153 XmlReader reader(filestream);
154 if (!reader.IsOk()) {
155 LcfReader::SetError(
"Couldn't parse save file.");
159 rpg::Save* save =
new rpg::Save();
160 reader.SetHandler(
new RootXmlHandler<rpg::Save>(*save,
"LSD"));
162 return std::unique_ptr<rpg::Save>(save);
static void WriteXml(const S &obj, XmlWriter &stream)
static void WriteLcf(const S &obj, LcfWriter &stream)
static void ReadLcf(S &obj, LcfReader &stream)
void Warning(const char *fmt,...) LIKE_PRINTF
void Error(const char *fmt,...) LIKE_PRINTF