Skip to content

Commit d1fc1b4

Browse files
author
fdelapena
authored
Merge pull request #455 from Ghabry/strvec
Support Vector<DBString>
2 parents de7ede0 + 7a1e970 commit d1fc1b4

16 files changed

Lines changed: 313 additions & 49 deletions

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ set(CMAKE_CXX_EXTENSIONS ON)
2828
# lcf library files
2929
set(LCF_SOURCES
3030
src/dbarray.cpp
31+
src/dbstring_struct.cpp
3132
src/encoder.cpp
3233
src/ini.cpp
3334
src/inireader.cpp

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ liblcf_la_LDFLAGS = \
4242
-no-undefined
4343
liblcf_la_SOURCES = \
4444
src/dbarray.cpp \
45+
src/dbstring_struct.cpp \
4546
src/encoder.cpp \
4647
src/ini.cpp \
4748
src/inireader.cpp \

generator/csv/fields.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ Database,animations,f,Array<Animation>,0x13,,1,0,rpg::Animation
589589
Database,chipsets,f,Array<Chipset>,0x14,,1,0,rpg::Chipset
590590
Database,terms,f,Terms,0x15,,1,0,rpg::Terms
591591
Database,system,f,System,0x16,,1,0,rpg::System
592-
Database,switches,f,Array<Switch>,0x17,,1,0,rpg::Switchs
592+
Database,switches,f,Array<Switch>,0x17,,1,0,rpg::Switches
593593
Database,variables,f,Array<Variable>,0x18,,1,0,rpg::Variables
594594
Database,commonevents,f,Array<CommonEvent>,0x19,,1,0,rpg::CommonEvent
595595
Database,version,f,DatabaseVersion,0x1A,0,0,0,Indicates version of database. When 1 the database was converted to RPG Maker 2000 v1.61

generator/csv/fields_easyrpg.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ SaveEasyRpgText,font_size,f,Int32,0x05,12,0,0,Font size
2525
SaveEasyRpgText,letter_spacing,f,Int32,0x06,0,0,0,Additional spacing between letters
2626
SaveEasyRpgText,line_spacing,f,Int32,0x07,4,0,0,Additional spacing between lines
2727
SaveEasyRpgText,flags,f,SaveEasyRpgText_Flags,0x08,3,0,0,Various text settings
28+
SaveSystem,maniac_strings,f,Vector<DBString>,0x24,,0,0,rpg::Strings
2829
SaveSystem,maniac_frameskip,,Int32,0x88,0,0,0,"FatalMix Frameskip (0=None, 1=1/5, 2=1/3, 3=1/2)"
2930
SaveSystem,maniac_picture_limit,,Int32,0x89,0,0,0,FatalMix Picture Limit
3031
SaveSystem,maniac_options,,Vector<UInt8>,0x8A,,0,0,"Various FatalMix options (XX XA XB XC). A: MsgSkip OFF/RShift (0/4) B: TestPlay Keep/ON/OFF (0/2/4), C: Pause focus lost Wait/Run (0/1)"

src/dbstring_struct.cpp

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*
2+
* This file is part of liblcf. Copyright (c) 2021 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 "lcf/dbstring.h"
11+
#include "reader_struct.h"
12+
#include <iostream>
13+
14+
namespace lcf {
15+
16+
/*
17+
DBString has the structure of a Pascal String (Length + Data).
18+
It could be a primitive type but vector<DBString> needs special handling.
19+
20+
Vector<DBString> is Maniac Patch and is sparse:
21+
When size is > 0xFFFFFFFF there is a gap of "0x800000000 - size"
22+
In other cases it is as above: Size Data ... Size Data
23+
*/
24+
25+
template <>
26+
struct RawStruct<DBString> {
27+
static void ReadLcf(DBString& ref, LcfReader& stream, uint32_t length);
28+
static void WriteLcf(const DBString& ref, LcfWriter& stream);
29+
static int LcfSize(const DBString& ref, LcfWriter& stream);
30+
static void WriteXml(const DBString& ref, XmlWriter& stream);
31+
static void BeginXml(DBString& ref, XmlReader& stream);
32+
};
33+
34+
template <>
35+
struct RawStruct<std::vector<DBString> > {
36+
static void ReadLcf(std::vector<DBString>& ref, LcfReader& stream, uint32_t length);
37+
static void WriteLcf(const std::vector<DBString>& ref, LcfWriter& stream);
38+
static int LcfSize(const std::vector<DBString>& ref, LcfWriter& stream);
39+
static void WriteXml(const std::vector<DBString>& ref, XmlWriter& stream);
40+
static void BeginXml(std::vector<DBString>& ref, XmlReader& stream);
41+
};
42+
43+
void RawStruct<DBString>::ReadLcf(DBString& ref, LcfReader& stream, uint32_t length) {
44+
stream.ReadString(ref, length);
45+
#ifdef LCF_DEBUG_TRACE
46+
printf(" %s\n", ref.c_str());
47+
#endif
48+
}
49+
50+
void RawStruct<DBString>::WriteLcf(const DBString& ref, LcfWriter& stream) {
51+
stream.Write(ref);
52+
}
53+
54+
int RawStruct<DBString>::LcfSize(const DBString& ref, LcfWriter& stream) {
55+
return stream.Decode(ref).size();
56+
}
57+
58+
void RawStruct<DBString>::WriteXml(const DBString& ref, XmlWriter& stream) {
59+
stream.Write(ref);
60+
}
61+
62+
class DbStringXmlHandler : public XmlHandler {
63+
private:
64+
DBString& ref;
65+
public:
66+
DbStringXmlHandler(DBString& ref) :
67+
ref(ref) {}
68+
void StartElement(XmlReader& stream, const char* name, const char** /* atts */) {
69+
// no-op
70+
}
71+
void EndElement(XmlReader& /* stream */, const char* /* name */) {
72+
// no-op
73+
}
74+
void CharacterData(XmlReader& /* stream */, const std::string& data) {
75+
ref = DBString(data);
76+
}
77+
};
78+
79+
void RawStruct<DBString>::BeginXml(DBString& /* ref */, XmlReader& /* stream */) {
80+
// no-op
81+
}
82+
83+
void RawStruct<std::vector<DBString>>::ReadLcf(std::vector<DBString>& ref, LcfReader& stream, uint32_t length) {
84+
int index = 0;
85+
DBString string_var;
86+
87+
uint32_t startpos = stream.Tell();
88+
uint32_t endpos = startpos + length;
89+
while (stream.Tell() < endpos) {
90+
// If size is bigger than 4 bytes, size indicates the gap size
91+
// Otherwise it indicates the size of the next string
92+
auto size = stream.ReadUInt64();
93+
if (size > std::numeric_limits<uint32_t>::max()) {
94+
index += static_cast<uint32_t>(0x800000000 - size);
95+
96+
ref.resize(index);
97+
} else {
98+
stream.ReadString(string_var, size);
99+
#ifdef LCF_DEBUG_TRACE
100+
fprintf(stderr, "t[%d]: %s\n", index + 1, string_var.c_str());
101+
#endif
102+
ref.push_back(string_var);
103+
104+
++index;
105+
}
106+
}
107+
108+
if (stream.Tell() != endpos) {
109+
#ifdef LCF_DEBUG_TRACE
110+
fprintf(stderr, "Misaligned!\n");
111+
#endif
112+
stream.Seek(endpos);
113+
}
114+
}
115+
116+
void RawStruct<std::vector<DBString>>::WriteLcf(const std::vector<DBString>& ref, LcfWriter& stream) {
117+
int gap_size = 0;
118+
119+
for (size_t i = 0; i < ref.size(); ++i) {
120+
const auto& e = ref[i];
121+
if (e.empty()) {
122+
++gap_size;
123+
continue;
124+
}
125+
126+
if (gap_size > 0) {
127+
stream.WriteUInt64(0x800000000 - static_cast<uint64_t>(gap_size));
128+
gap_size = 0;
129+
}
130+
131+
auto len = RawStruct<DBString>::LcfSize(e, stream);
132+
stream.WriteInt(len);
133+
RawStruct<DBString>::WriteLcf(e, stream);
134+
}
135+
}
136+
137+
int RawStruct<std::vector<DBString>>::LcfSize(const std::vector<DBString>& ref, LcfWriter& stream) {
138+
int result = 0;
139+
int gap_size = 0;
140+
141+
for (size_t i = 0; i < ref.size(); ++i) {
142+
const auto& e = ref[i];
143+
if (e.empty()) {
144+
++gap_size;
145+
continue;
146+
}
147+
148+
if (gap_size > 0) {
149+
result += LcfReader::UInt64Size(0x800000000 - static_cast<uint64_t>(gap_size));
150+
gap_size = 0;
151+
}
152+
153+
int size = RawStruct<DBString>::LcfSize(e, stream);
154+
result += LcfReader::IntSize(size);
155+
result += size;
156+
}
157+
158+
return result;
159+
}
160+
161+
void RawStruct<std::vector<DBString>>::WriteXml(const std::vector<DBString>& ref, XmlWriter& stream) {
162+
for (size_t i = 0; i < ref.size(); ++i) {
163+
const auto& e = ref[i];
164+
if (e.empty()) {
165+
continue;
166+
}
167+
168+
stream.BeginElement("item", i + 1);
169+
RawStruct<DBString>::WriteXml(e, stream);
170+
stream.EndElement("item");
171+
}
172+
}
173+
174+
class DbStringVectorXmlHandler : public XmlHandler {
175+
public:
176+
DbStringVectorXmlHandler(std::vector<DBString>& ref) : ref(ref) {}
177+
178+
void StartElement(XmlReader& stream, const char* name, const char** atts) {
179+
if (strcmp(name, "item") != 0) {
180+
stream.Error("Expecting %s but got %s", "item", name);
181+
return;
182+
}
183+
184+
int last_id = -1;
185+
int id = -1;
186+
for (int i = 0; atts[i] != NULL && atts[i + 1] != NULL; i += 2) {
187+
if (strcmp(atts[i], "id") == 0) {
188+
id = atoi(atts[i + 1]);
189+
break;
190+
}
191+
}
192+
193+
if (id <= last_id || id < -1) {
194+
stream.Error("Bad Id %d / %d", id, last_id);
195+
return;
196+
}
197+
198+
ref.resize(id);
199+
DBString& obj = ref.back();
200+
201+
stream.SetHandler(new DbStringXmlHandler(obj));
202+
}
203+
private:
204+
std::vector<DBString>& ref;
205+
};
206+
207+
void RawStruct<std::vector<DBString>>::BeginXml(std::vector<DBString>& obj, XmlReader& stream) {
208+
stream.SetHandler(new DbStringVectorXmlHandler(obj));
209+
}
210+
211+
} //namspace lcf

src/generated/lcf/ldb/chunks.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,7 @@ namespace LDB_Reader {
15121512
terms = 0x15,
15131513
/** rpg::System */
15141514
system = 0x16,
1515-
/** rpg::Switchs */
1515+
/** rpg::Switches */
15161516
switches = 0x17,
15171517
/** rpg::Variables */
15181518
variables = 0x18,

src/generated/lcf/lsd/chunks.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ namespace LSD_Reader {
162162
save_slot = 0x84,
163163
/** ATB mode of RPG 2003 battle system. */
164164
atb_mode = 0x8C,
165+
/** rpg::Strings */
166+
maniac_strings = 0x24,
165167
/** FatalMix Frameskip (0=None, 1=1/5, 2=1/3, 3=1/2) */
166168
maniac_frameskip = 0x88,
167169
/** FatalMix Picture Limit */

src/generated/lcf/rpg/savesystem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <stdint.h>
1717
#include <string>
1818
#include <vector>
19+
#include "lcf/dbstring.h"
1920
#include "lcf/enum_tags.h"
2021
#include "lcf/rpg/music.h"
2122
#include "lcf/rpg/sound.h"
@@ -116,6 +117,7 @@ namespace rpg {
116117
int32_t save_count = 0;
117118
int32_t save_slot = 1;
118119
int32_t atb_mode = 0;
120+
std::vector<DBString> maniac_strings;
119121
int32_t maniac_frameskip = 0;
120122
int32_t maniac_picture_limit = 0;
121123
std::vector<uint8_t> maniac_options;
@@ -186,6 +188,7 @@ namespace rpg {
186188
&& l.save_count == r.save_count
187189
&& l.save_slot == r.save_slot
188190
&& l.atb_mode == r.atb_mode
191+
&& l.maniac_strings == r.maniac_strings
189192
&& l.maniac_frameskip == r.maniac_frameskip
190193
&& l.maniac_picture_limit == r.maniac_picture_limit
191194
&& l.maniac_options == r.maniac_options

src/generated/lsd_savesystem.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,13 @@ static TypedField<rpg::SaveSystem, int32_t> static_atb_mode(
417417
0,
418418
1
419419
);
420+
static TypedField<rpg::SaveSystem, std::vector<DBString>> static_maniac_strings(
421+
&rpg::SaveSystem::maniac_strings,
422+
LSD_Reader::ChunkSaveSystem::maniac_strings,
423+
"maniac_strings",
424+
0,
425+
0
426+
);
420427
static TypedField<rpg::SaveSystem, int32_t> static_maniac_frameskip(
421428
&rpg::SaveSystem::maniac_frameskip,
422429
LSD_Reader::ChunkSaveSystem::maniac_frameskip,
@@ -506,6 +513,7 @@ Field<rpg::SaveSystem> const* Struct<rpg::SaveSystem>::fields[] = {
506513
&static_save_count,
507514
&static_save_slot,
508515
&static_atb_mode,
516+
&static_maniac_strings,
509517
&static_maniac_frameskip,
510518
&static_maniac_picture_limit,
511519
&static_maniac_options,

src/generated/rpg_savesystem.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ std::ostream& operator<<(std::ostream& os, const SaveSystem& obj) {
8080
os << ", save_count="<< obj.save_count;
8181
os << ", save_slot="<< obj.save_slot;
8282
os << ", atb_mode="<< obj.atb_mode;
83+
os << ", maniac_strings=";
84+
for (size_t i = 0; i < obj.maniac_strings.size(); ++i) {
85+
os << (i == 0 ? "[" : ", ") << obj.maniac_strings[i];
86+
}
87+
os << "]";
8388
os << ", maniac_frameskip="<< obj.maniac_frameskip;
8489
os << ", maniac_picture_limit="<< obj.maniac_picture_limit;
8590
os << ", maniac_options=";

0 commit comments

Comments
 (0)