Skip to content

Commit d182256

Browse files
authored
Merge pull request #492 from Ghabry/flags
Flags: Do not hardcode one Flag field per class
2 parents 34db541 + b0e6b13 commit d182256

38 files changed

Lines changed: 648 additions & 86 deletions

CMakeLists.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ set(LCF_SOURCES
4141
src/lmu_movecommand.cpp
4242
src/lmu_reader.cpp
4343
src/log.h
44-
src/lsd_reader.cpp
4544
src/log_handler.cpp
45+
src/lsd_reader.cpp
4646
src/reader_flags.cpp
4747
src/reader_lcf.cpp
4848
src/reader_struct.h
@@ -54,6 +54,8 @@ set(LCF_SOURCES
5454
src/saveopt.cpp
5555
src/writer_lcf.cpp
5656
src/writer_xml.cpp
57+
src/generated/fwd_flags_impl.h
58+
src/generated/fwd_flags_instance.h
5759
src/generated/fwd_struct_impl.h
5860
src/generated/ldb_actor.cpp
5961
src/generated/ldb_animation.cpp
@@ -83,7 +85,7 @@ set(LCF_SOURCES
8385
src/generated/ldb_system.cpp
8486
src/generated/ldb_terms.cpp
8587
src/generated/ldb_terrain.cpp
86-
src/generated/ldb_terrain_flags.h
88+
src/generated/ldb_terrain_special_flags.h
8789
src/generated/ldb_testbattler.cpp
8890
src/generated/ldb_troop.cpp
8991
src/generated/ldb_troopmember.cpp
@@ -109,10 +111,13 @@ set(LCF_SOURCES
109111
src/generated/lsd_saveeasyrpgwindow.cpp
110112
src/generated/lsd_saveeasyrpgwindow_flags.h
111113
src/generated/lsd_saveeventexecframe.cpp
114+
src/generated/lsd_saveeventexecframe_easyrpg_runtime_flags.h
112115
src/generated/lsd_saveeventexecstate.cpp
116+
src/generated/lsd_saveeventexecstate_easyrpg_runtime_flags.h
113117
src/generated/lsd_saveinventory.cpp
114118
src/generated/lsd_savemapevent.cpp
115119
src/generated/lsd_savemapeventbase.cpp
120+
src/generated/lsd_savemapeventbase_easyrpg_runtime_flags.h
116121
src/generated/lsd_savemapinfo.cpp
117122
src/generated/lsd_savepanorama.cpp
118123
src/generated/lsd_savepartylocation.cpp
@@ -205,8 +210,8 @@ set(LCF_HEADERS
205210
src/lcf/ldb/reader.h
206211
src/lcf/lmt/reader.h
207212
src/lcf/lmu/reader.h
208-
src/lcf/lsd/reader.h
209213
src/lcf/log_handler.h
214+
src/lcf/lsd/reader.h
210215
src/lcf/reader_lcf.h
211216
src/lcf/reader_util.h
212217
src/lcf/reader_xml.h

Makefile.am

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ liblcf_la_SOURCES = \
5858
src/lmu_movecommand.cpp \
5959
src/lmu_reader.cpp \
6060
src/log.h \
61-
src/lsd_reader.cpp \
6261
src/log_handler.cpp \
62+
src/lsd_reader.cpp \
6363
src/reader_flags.cpp \
6464
src/reader_lcf.cpp \
6565
src/reader_struct.h \
@@ -71,6 +71,8 @@ liblcf_la_SOURCES = \
7171
src/saveopt.cpp \
7272
src/writer_lcf.cpp \
7373
src/writer_xml.cpp \
74+
src/generated/fwd_flags_impl.h \
75+
src/generated/fwd_flags_instance.h \
7476
src/generated/fwd_struct_impl.h \
7577
src/generated/ldb_actor.cpp \
7678
src/generated/ldb_animation.cpp \
@@ -100,7 +102,7 @@ liblcf_la_SOURCES = \
100102
src/generated/ldb_system.cpp \
101103
src/generated/ldb_terms.cpp \
102104
src/generated/ldb_terrain.cpp \
103-
src/generated/ldb_terrain_flags.h \
105+
src/generated/ldb_terrain_special_flags.h \
104106
src/generated/ldb_testbattler.cpp \
105107
src/generated/ldb_troop.cpp \
106108
src/generated/ldb_troopmember.cpp \
@@ -126,10 +128,13 @@ liblcf_la_SOURCES = \
126128
src/generated/lsd_saveeasyrpgwindow.cpp \
127129
src/generated/lsd_saveeasyrpgwindow_flags.h \
128130
src/generated/lsd_saveeventexecframe.cpp \
131+
src/generated/lsd_saveeventexecframe_easyrpg_runtime_flags.h \
129132
src/generated/lsd_saveeventexecstate.cpp \
133+
src/generated/lsd_saveeventexecstate_easyrpg_runtime_flags.h \
130134
src/generated/lsd_saveinventory.cpp \
131135
src/generated/lsd_savemapevent.cpp \
132136
src/generated/lsd_savemapeventbase.cpp \
137+
src/generated/lsd_savemapeventbase_easyrpg_runtime_flags.h \
133138
src/generated/lsd_savemapinfo.cpp \
134139
src/generated/lsd_savepanorama.cpp \
135140
src/generated/lsd_savepartylocation.cpp \

builds/sources2buildsystem.pl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# sources2buildsystem.pl - maintainer utility script to keep the
44
# source/header file list for our build systems organized and up-to-date.
5-
# by carstene1ns 2018-2021, released under the MIT license
5+
# by carstene1ns 2018-2025, released under the MIT license
66

77
use strict;
88
use warnings;
@@ -22,7 +22,7 @@
2222
@files = (@others, @generated, @third_party);
2323

2424
# split source and headers
25-
my $regex = '(\.cpp|_flags\.h|_impl\.h|src\/[^\/]*\.h)$';
25+
my $regex = '(\.cpp|_flags\.h|fwd_.*\.h|src\/[^\/]*\.h)$';
2626
my @sources = grep( /$regex/, @files);
2727
my @headers = grep(!/$regex/, @files);
2828

@@ -57,6 +57,7 @@
5757
sub wanted {
5858
return unless -f;
5959
return unless /\.(cpp|h)$/;
60+
return if /inireader/;
6061

6162
push @files, $File::Find::name;
6263
}

generator/csv/enums_easyrpg.csv

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
Structure,Entry,Value,Index
22
EventCommand,Code,EasyRpg_TriggerEventAt,2002
3-
EventCommand,Code,EasyRpg_SmartMoveRoute,2003
4-
EventCommand,Code,EasyRpg_SmartStepToward,2004
3+
EventCommand,Code,EasyRpg_Pathfinder,2003
54
EventCommand,Code,EasyRpg_CallMovementAction,2050
65
EventCommand,Code,EasyRpg_WaitForSingleMovement,2051
76
EventCommand,Code,EasyRpg_AnimateVariable,2052

generator/csv/fields_easyrpg.csv

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ SaveEventExecFrame,maniac_event_id,f,Int32,0x0F,0,0,0,Event ID
88
SaveEventExecFrame,maniac_event_page_id,f,Int32,0x10,0,0,0,Page ID when it is a map event
99
SaveEventExecFrame,maniac_loop_info_size,f,Int32,0x11,0,0,0,Amount of loop info groups
1010
SaveEventExecFrame,maniac_loop_info,f,Vector<Int32>,0x12,,0,0,"One group of (Current loop count, end loop value) for each identation"
11+
SaveEventExecFrame,easyrpg_runtime_flags,f,EasyRpgFrameRuntime_Flags,0xCC,0,0,0,Runtime changes to the engine config
1112
SaveEventExecState,easyrpg_active,f,Boolean,0xC9,False,0,0,When true state of an event is preserved in easyrpg_string and easyrpg_parameters
1213
SaveEventExecState,easyrpg_string,f,DBString,0xCA,,0,0,Preserved string data of an event
1314
SaveEventExecState,easyrpg_parameters,f,Vector<Int32>,0xCB,,0,0,Preserved int parameter of an event
15+
SaveEventExecState,easyrpg_runtime_flags,f,EasyRpgStateRuntime_Flags,0xCC,0,0,0,Runtime changes to the engine config
1416
SavePicture,easyrpg_flip,f,Enum<EasyRpgFlip>,0xC8,0,0,1,How to flip the picture
1517
SavePicture,easyrpg_blend_mode,f,Int32,0xC9,0,0,1,Blend mode to use for blit. See Bitmap::BlendMode
1618
SavePicture,easyrpg_type,f,Enum<EasyRpgPictureType>,0xCA,0,0,1,Type of this picture
@@ -31,6 +33,9 @@ SaveEasyRpgText,letter_spacing,f,Int32,0x06,0,0,0,Additional spacing between let
3133
SaveEasyRpgText,line_spacing,f,Int32,0x07,4,0,0,Additional spacing between lines
3234
SaveEasyRpgText,flags,f,SaveEasyRpgText_Flags,0x08,3,0,0,Various text settings
3335
SaveMapEventBase,easyrpg_move_failure_count,f,Int32,0xC9,0,0,0,Tracks how often the current move operation in a move route failed
36+
SaveMapEventBase,easyrpg_clone_map_id,f,UInt32,0xCA,0,0,0,The original map id of a cloned event
37+
SaveMapEventBase,easyrpg_clone_event_id,f,UInt32,0xCB,0,0,0,The original event id of a cloned event
38+
SaveMapEventBase,easyrpg_runtime_flags,f,EasyRpgEventRuntime_Flags,0xCC,0,0,0,Runtime changes to the engine config
3439
SavePartyLocation,maniac_horizontal_pan_speed,f,Double,0x8D,0,0,0,horizontal speed in the scrolls of the screen
3540
SavePartyLocation,maniac_vertical_pan_speed,f,Double,0x8E,0,0,0,vertical speed in the scrolls of the screen
3641
SaveSystem,maniac_strings,f,Vector<DBString>,0x24,,0,0,rpg::Strings

generator/csv/flags_easyrpg.csv

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,25 @@ SaveEasyRpgText,draw_gradient,0
55
SaveEasyRpgText,draw_shadow,0
66
SaveEasyRpgText,bold,0
77
SaveEasyRpgText,italic,0
8+
EasyRpgFrameRuntime,reserved_1,0
9+
EasyRpgEventRuntime,reserved_1,0
10+
EasyRpgStateRuntime,conf_override_active,0
11+
EasyRpgStateRuntime,reserved_1,0
12+
EasyRpgStateRuntime,reserved_2,0
13+
EasyRpgStateRuntime,reserved_3,0
14+
EasyRpgStateRuntime,patch_destiny_on,0
15+
EasyRpgStateRuntime,patch_destiny_off,0
16+
EasyRpgStateRuntime,patch_dynrpg_on,0
17+
EasyRpgStateRuntime,patch_dynrpg_off,0
18+
EasyRpgStateRuntime,patch_maniac_on,0
19+
EasyRpgStateRuntime,patch_maniac_off,0
20+
EasyRpgStateRuntime,patch_common_this_event_on,0
21+
EasyRpgStateRuntime,patch_common_this_event_off,0
22+
EasyRpgStateRuntime,patch_unlock_pics_on,0
23+
EasyRpgStateRuntime,patch_unlock_pics_off,0
24+
EasyRpgStateRuntime,patch_keypatch_on,0
25+
EasyRpgStateRuntime,patch_keypatch_off,0
26+
EasyRpgStateRuntime,patch_rpg2k3_cmds_on,0
27+
EasyRpgStateRuntime,patch_rpg2k3_cmds_off,0
28+
EasyRpgStateRuntime,use_rpg2k_battle_system_on,0
29+
EasyRpgStateRuntime,use_rpg2k_battle_system_off,0

generator/generate.py

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,20 @@ def cpp_type(ty, prefix=True):
9090

9191
m = re.match(r'(.*)_Flags$', ty)
9292
if m:
93-
ty = m.expand(r'\1::Flags')
94-
if prefix:
95-
ty = 'rpg::' + ty
96-
return ty
93+
raise ValueError("use flag_type for flags")
9794

9895
if prefix:
9996
ty = 'rpg::' + ty
10097

10198
return ty
10299

100+
def flag_type(field, struct_name):
101+
field_type = field.type
102+
# Backward compatibility: When Struct Name = Flag Name only emit "Flags"
103+
if struct_name == field.type[:-6]:
104+
field_type = "Flags"
105+
return field_type
106+
103107
def pod_default(field):
104108
dfl = field.default
105109
ftype = field.type
@@ -133,9 +137,6 @@ def pod_default(field):
133137

134138
return " = " + str(dfl)
135139

136-
def num_flags(flag):
137-
return len(flag)
138-
139140
def flag_size(flag):
140141
return (len(flag) + 7) // 8
141142

@@ -149,6 +150,9 @@ def flag_set(field, bit):
149150

150151
return str(res).lower()
151152

153+
def flags_for(field):
154+
return flags[field.type[:-6]]
155+
152156
def filter_structs_without_codes(structs):
153157
for struct in structs:
154158
if all(f.code for f in sfields[struct.name]):
@@ -392,11 +396,14 @@ def type_is_array_of_struct(ty):
392396
def is_monotonic_from_0(enum):
393397
expected = 0
394398
for (val, idx) in enum:
395-
if int(idx) != expected:
399+
if int(idx, 0) != expected:
396400
return False
397401
expected += 1
398402
return True
399403

404+
def is_scoped_enum(enum_name):
405+
return enum_name == "Code"
406+
400407
def openToRender(path):
401408
subdir = os.path.dirname(path)
402409
if not os.path.exists(subdir):
@@ -426,6 +433,8 @@ def generate():
426433
structs=sorted([x.name for x in structs_flat])
427434
))
428435

436+
flag_fields = []
437+
429438
for filetype, structlist in structs.items():
430439
for struct in structlist:
431440
filename = struct.name.lower()
@@ -442,8 +451,8 @@ def generate():
442451
type=filetype
443452
))
444453

445-
446-
filepath = os.path.join(tmp_dir, 'lcf', 'rpg', '%s.h' % filename)
454+
struct_header = os.path.join('lcf', 'rpg', '%s.h' % filename)
455+
filepath = os.path.join(tmp_dir, struct_header)
447456
with openToRender(filepath) as f:
448457
f.write(rpg_header_tmpl.render(
449458
struct_name=struct.name,
@@ -459,14 +468,33 @@ def generate():
459468
filename=filename
460469
))
461470

462-
if struct.name in flags:
463-
filepath = os.path.join(tmp_dir, '%s_%s_flags.h' % (filetype, filename))
471+
struct_flag_fields = [s for s in sfields[struct.name] if s.type.endswith("_Flags")]
472+
for flag_field in struct_flag_fields:
473+
header_file = '%s_%s_%s.h' % (filetype, filename, flag_field.name)
474+
filepath = os.path.join(tmp_dir, header_file)
475+
field_name = flag_type(flag_field, struct.name)
476+
flag_fields.append(dict(struct_name=struct.name, struct_header=struct_header, field_name=field_name, flag_header=header_file))
477+
464478
with openToRender(filepath) as f:
465479
f.write(flags_tmpl.render(
466-
struct_name=struct.name,
467-
type=filetype
480+
struct_name=flag_fields[-1]["struct_name"],
481+
type=filetype,
482+
flag_name=flag_fields[-1]["field_name"],
483+
flag_item=flags[flag_field.type[:-6]]
468484
))
469485

486+
filepath = os.path.join(tmp_dir, 'fwd_flags_impl.h')
487+
with openToRender(filepath) as f:
488+
f.write(flags_fwd_tmpl.render(
489+
flags=flag_fields
490+
))
491+
492+
filepath = os.path.join(tmp_dir, 'fwd_flags_instance.h')
493+
with openToRender(filepath) as f:
494+
f.write(flags_instance_tmpl.render(
495+
flags=flag_fields
496+
))
497+
470498
for dirname, subdirlist, filelist in os.walk(tmp_dir, topdown=False):
471499
subdir = os.path.relpath(dirname, tmp_dir)
472500

@@ -486,7 +514,7 @@ def main(argv):
486514
os.mkdir(dest_dir)
487515

488516
global structs, structs_flat, sfields, enums, flags, functions, constants, headers
489-
global chunk_tmpl, lcf_struct_tmpl, rpg_header_tmpl, rpg_source_tmpl, flags_tmpl, enums_tmpl, fwd_tmpl, fwd_struct_tmpl
517+
global chunk_tmpl, lcf_struct_tmpl, rpg_header_tmpl, rpg_source_tmpl, flags_tmpl, flags_fwd_tmpl, flags_instance_tmpl, enums_tmpl, fwd_tmpl, fwd_struct_tmpl
490518

491519
structs, structs_flat = get_structs('structs.csv', 'structs_easyrpg.csv')
492520
sfields = get_fields('fields.csv', 'fields_easyrpg.csv')
@@ -499,15 +527,17 @@ def main(argv):
499527
# Setup Jinja
500528
env.filters["lcf_type"] = lcf_type
501529
env.filters["cpp_type"] = cpp_type
530+
env.filters["flag_type"] = flag_type
502531
env.filters["pod_default"] = pod_default
503532
env.filters["struct_has_code"] = filter_structs_without_codes
504533
env.filters["field_is_used"] = filter_unused_fields
505534
env.filters["field_is_written"] = filter_unwritten_fields
506535
env.filters["field_is_not_size"] = filter_size_fields
507-
env.filters["num_flags"] = num_flags
508536
env.filters["flag_size"] = flag_size
509537
env.filters["flag_set"] = flag_set
538+
env.filters["flags_for"] = flags_for
510539
env.tests['monotonic_from_0'] = is_monotonic_from_0
540+
env.tests['scoped_enum'] = is_scoped_enum
511541
env.tests['is_db_string'] = type_is_db_string
512542
env.tests['is_array'] = type_is_array
513543
env.tests['is_array_of_struct'] = type_is_array_of_struct
@@ -529,6 +559,8 @@ def main(argv):
529559
rpg_header_tmpl = env.get_template('rpg_header.tmpl', globals=globals)
530560
rpg_source_tmpl = env.get_template('rpg_source.tmpl', globals=globals)
531561
flags_tmpl = env.get_template('flag_reader.tmpl', globals=globals)
562+
flags_fwd_tmpl = env.get_template('flag_fwd.tmpl', globals=globals)
563+
flags_instance_tmpl = env.get_template('flag_instance.tmpl', globals=globals)
532564
fwd_tmpl = env.get_template('fwd.tmpl', globals=globals)
533565
fwd_struct_tmpl = env.get_template('fwd_struct.tmpl', globals=globals)
534566

generator/templates/chunks.tmpl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
{#
2+
This template is used for the chunks.h files
3+
-#}
14
{% include "copyright.tmpl" %}
25
#ifndef LCF_{{ type|upper }}_CHUNKS_H
36
#define LCF_{{ type|upper }}_CHUNKS_H

generator/templates/flag_fwd.tmpl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{#
2+
This template generates "fwd_flags_impl.h" which is included by "reader_struct.h"
3+
and is used to declare the templates used by "Flags"
4+
-#}
5+
{% include "copyright.tmpl" %}
6+
7+
{%- for flag in flags %}
8+
#include "{{ flag.struct_header }}"
9+
{%- endfor %}
10+
11+
{%- for flag in flags %}
12+
template <> struct lcf::TypeCategory<lcf::rpg::{{ flag.struct_name }}::{{ flag.field_name }}> { static const lcf::Category::Index value = lcf::Category::Flags; };
13+
{%- endfor %}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{#
2+
This template generates "fwd_flags_instance.h" which is included by "reader_flags.cpp"
3+
to instantiate the templates used by "Flags"
4+
-#}
5+
{% include "copyright.tmpl" %}
6+
7+
{%- for flag in flags %}
8+
#include "{{ flag.flag_header }}"
9+
{%- endfor %}
10+
11+
namespace lcf {
12+
{%- for flag in flags %}
13+
template class Flags<rpg::{{ flag.struct_name }}::{{ flag.field_name }}>;
14+
{%- endfor %}
15+
}

0 commit comments

Comments
 (0)