liblcf
Loading...
Searching...
No Matches
lsd_reader.cpp
Go to the documentation of this file.
1/*
2 * This file is part of liblcf. Copyright (c) 2020 liblcf authors.
3 * https://github.com/EasyRPG/liblcf - https://easyrpg.org
4 *
5 * liblcf is Free/Libre Open Source Software, released under the MIT License.
6 * For the full copyright and license information, please view the COPYING
7 * file that was distributed with this source code.
8 */
9
10#include <cmath>
11#include <fstream>
12#include <cerrno>
13#include <cstring>
14
15#include "lsd_reader.h"
16#include "lsd_chunks.h"
17#include "ldb_reader.h"
18#include "rpg_save.h"
19#include "reader_util.h"
20#include "reader_struct.h"
21
22double LSD_Reader::ToTDateTime(std::time_t const t) {
23 // 25569 is UnixDateDelta: number of days between 1970-01-01 and 1900-01-01
24 return(t / 86400.0 + 25569.0);
25}
26
27std::time_t LSD_Reader::ToUnixTimestamp(double const ms) {
28 return(std::time_t(ms * 86400.0 - 25569.0 * 86400.0 + 0.5));
29}
30
31double LSD_Reader::GenerateTimestamp(std::time_t const t) {
32 return ToTDateTime(t);
33}
34
35void LSD_Reader::PrepareSave(RPG::Save& save, int32_t version) {
36 ++save.system.save_count;
38 save.easyrpg_data.version = version;
39}
40
41std::unique_ptr<RPG::Save> LSD_Reader::Load(const std::string& filename, const std::string& encoding) {
42 std::ifstream stream(filename.c_str(), std::ios::binary);
43 if (!stream.is_open()) {
44 fprintf(stderr, "Failed to open LSD file `%s' for reading : %s\n", filename.c_str(), strerror(errno));
45 return nullptr;
46 }
47 return LSD_Reader::Load(stream, encoding);
48}
49
50bool LSD_Reader::Save(const std::string& filename, const RPG::Save& save, const std::string& encoding) {
51 std::ofstream stream(filename.c_str(), std::ios::binary);
52 if (!stream.is_open()) {
53 fprintf(stderr, "Failed to open LSD file `%s' for writing : %s\n", filename.c_str(), strerror(errno));
54 return false;
55 }
56 return LSD_Reader::Save(stream, save, encoding);
57}
58
59bool LSD_Reader::SaveXml(const std::string& filename, const RPG::Save& save) {
60 std::ofstream stream(filename.c_str(), std::ios::binary);
61 if (!stream.is_open()) {
62 fprintf(stderr, "Failed to open LSD XML file `%s' for writing : %s\n", filename.c_str(), strerror(errno));
63 return false;
64 }
65 return LSD_Reader::SaveXml(stream, save);
66}
67
68std::unique_ptr<RPG::Save> LSD_Reader::LoadXml(const std::string& filename) {
69 std::ifstream stream(filename.c_str(), std::ios::binary);
70 if (!stream.is_open()) {
71 fprintf(stderr, "Failed to open LSD XML file `%s' for reading : %s\n", filename.c_str(), strerror(errno));
72 return nullptr;
73 }
74 return LSD_Reader::LoadXml(stream);
75}
76
77std::unique_ptr<RPG::Save> LSD_Reader::Load(std::istream& filestream, const std::string &encoding) {
78 LcfReader reader(filestream, encoding);
79 if (!reader.IsOk()) {
80 LcfReader::SetError("Couldn't parse save file.\n");
81 return std::unique_ptr<RPG::Save>();
82 }
83 std::string header;
84 reader.ReadString(header, reader.ReadInt());
85 if (header.length() != 11) {
86 LcfReader::SetError("This is not a valid RPG2000 save.\n");
87 return std::unique_ptr<RPG::Save>();
88 }
89 if (header != "LcfSaveData") {
90 fprintf(stderr, "Warning: This header is not LcfSaveData and might not be a valid RPG2000 save.\n");
91 }
92 RPG::Save* save = new RPG::Save();
93 Struct<RPG::Save>::ReadLcf(*save, reader);
94 return std::unique_ptr<RPG::Save>(save);
95}
96
97bool LSD_Reader::Save(std::ostream& filestream, const RPG::Save& save, const std::string &encoding) {
98 LcfWriter writer(filestream, encoding);
99 if (!writer.IsOk()) {
100 LcfReader::SetError("Couldn't parse save file.\n");
101 return false;
102 }
103 const std::string header("LcfSaveData");
104 writer.WriteInt(header.size());
105 writer.Write(header);
106
107 Struct<RPG::Save>::WriteLcf(save, writer);
108 return true;
109}
110
111bool LSD_Reader::SaveXml(std::ostream& filestream, const RPG::Save& save) {
112 XmlWriter writer(filestream);
113 if (!writer.IsOk()) {
114 LcfReader::SetError("Couldn't parse save file.\n");
115 return false;
116 }
117
118 writer.BeginElement("LSD");
119 Struct<RPG::Save>::WriteXml(save, writer);
120 writer.EndElement("LSD");
121 return true;
122}
123
124std::unique_ptr<RPG::Save> LSD_Reader::LoadXml(std::istream& filestream) {
125 XmlReader reader(filestream);
126 if (!reader.IsOk()) {
127 LcfReader::SetError("Couldn't parse save file.\n");
128 return std::unique_ptr<RPG::Save>();
129 }
130
131 RPG::Save* save = new RPG::Save();
132 reader.SetHandler(new RootXmlHandler<RPG::Save>(*save, "LSD"));
133 reader.Parse();
134 return std::unique_ptr<RPG::Save>(save);
135}
136
137RPG::Save LSD_Reader::ClearDefaults(const RPG::Save& save_in, const RPG::MapInfo& map_info, const RPG::Map& map) {
138 auto save = save_in;
139
140 save.system.UnFixup();
141 for (auto& actor: save.actors) {
142 actor.UnFixup();
143 }
144 save.map_info.UnFixup(map);
145 save.map_info.UnFixup(map_info);
146
147 return save;
148}
int ReadInt()
Definition: reader_lcf.cpp:84
bool IsOk() const
Definition: reader_lcf.cpp:192
void ReadString(std::string &ref, size_t size)
Definition: reader_lcf.cpp:186
static void SetError(const char *fmt,...)
Definition: reader_lcf.cpp:278
void WriteInt(int val)
Definition: writer_lcf.cpp:51
bool IsOk() const
Definition: writer_lcf.cpp:125
void Write(const void *ptr, size_t size, size_t nmemb)
Definition: writer_lcf.cpp:24
SaveSystem system
Definition: rpg_save.h:40
SaveTitle title
Definition: rpg_save.h:39
SaveEasyRpgData easyrpg_data
Definition: rpg_save.h:54
static void WriteLcf(const S &obj, LcfWriter &stream)
static void WriteXml(const S &obj, XmlWriter &stream)
static void ReadLcf(S &obj, LcfReader &stream)
void SetHandler(XmlHandler *handler)
Definition: reader_xml.cpp:80
bool IsOk() const
Definition: reader_xml.cpp:55
void Parse()
Definition: reader_xml.cpp:67
void BeginElement(const std::string &name)
Definition: writer_xml.cpp:161
bool IsOk() const
Definition: writer_xml.cpp:199
void EndElement(const std::string &name)
Definition: writer_xml.cpp:177
double ToTDateTime(std::time_t const t)
Definition: lsd_reader.cpp:22
std::time_t ToUnixTimestamp(double const ms)
Definition: lsd_reader.cpp:27
bool Save(const std::string &filename, const RPG::Save &save, const std::string &encoding)
Definition: lsd_reader.cpp:50
void PrepareSave(RPG::Save &save, int32_t version=0)
Definition: lsd_reader.cpp:35
RPG::Save ClearDefaults(const RPG::Save &save, const RPG::MapInfo &map_info, const RPG::Map &map)
Definition: lsd_reader.cpp:137
bool SaveXml(const std::string &filename, const RPG::Save &save)
Definition: lsd_reader.cpp:59
double GenerateTimestamp(std::time_t const t=std::time(NULL))
Definition: lsd_reader.cpp:31
std::unique_ptr< RPG::Save > LoadXml(const std::string &filename)
Definition: lsd_reader.cpp:68
std::unique_ptr< RPG::Save > Load(const std::string &filename, const std::string &encoding)
Definition: lsd_reader.cpp:41