Skip to content

Commit a8f59ad

Browse files
committed
Bump version and docs
1 parent 9932c0d commit a8f59ad

9 files changed

+264
-17
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ SRCDIR:=src
2828
OBJDIR:=obj
2929
INCS:=-I$(SRCDIR)
3030

31-
VERSION := "0.8"
31+
VERSION := "0.9"
3232
GIT_COMMIT := "$(shell git describe --all --abbrev=8 --dirty --always)"
3333

3434
#override CXX:=clang++

doc/doc.adoc

+150-1
Original file line numberDiff line numberDiff line change
@@ -3522,7 +3522,7 @@ Syntax:
35223522
----
35233523
macro("macro_name", "args"...)
35243524
----
3525-
- `"macro_name"` is the string literal name of the macro file being invoked, without the `.macrofile` extension.
3525+
- `"macro_name"` is the string literal name of the macro file being invoked, without the `.macrofile` extension. If the string is empty, no macro is invoked.
35263526
- `"args"` are a comma-separated list of string literals to be substituted into the `.macrofab` file.
35273527

35283528
*Macro Files:*
@@ -3564,6 +3564,154 @@ vars
35643564
U something = 100
35653565
----
35663566

3567+
*Modifiers:*
3568+
3569+
- <<mod_flags, `+fork_scope`>>
3570+
3571+
=== `mapfab` [[kw_mapfab]]
3572+
3573+
The `mapfab` keyword parses a `.mapfab` file and invokes a series of <<kw_macro, macros>> based on the data.
3574+
It is only usable at top-level scope.
3575+
3576+
[NOTE]
3577+
http://pubby.games/mapfab.html[MapFab] is a level editor designed to be used with NESFab.
3578+
3579+
Syntax:
3580+
----
3581+
mapfab(target, "mapfab_file", "chr_macro", "palette_macro", "metatiles_macro", "level_macro")
3582+
----
3583+
- `target` specifies the output target to use for the level tiles.
3584+
- `"mapfab_file"` is the string literal path to the `.mapfab` file.
3585+
- `"chr_macro"` is the name of the macro to invoke for each CHR definition.
3586+
- `"palette_macro"` is the name of the macro to invoke for each palette definition.
3587+
- `"metatiles_macro"` is the name of the macro to invoke for each metatile set definition.
3588+
- `"level_macro"` is the name of the macro to invoke for each level definition.
3589+
3590+
If any of the macro names are the empty string (`""`), those macros are not invoked.
3591+
3592+
*CHR Macro:*
3593+
3594+
The following macro arguments are supplied for each CHR definition:
3595+
----
3596+
#:name:# // The name of the CHR definition
3597+
#:path:# // The path to the CHR definition
3598+
----
3599+
3600+
Additionally, the following private definitions are defined:
3601+
3602+
----
3603+
ct Int _index // The unique index of the CHR definition.
3604+
----
3605+
3606+
[NOTE]
3607+
It can make sense to ignore `path`, and instead use `name` to derive the desired path.
3608+
3609+
*Palette Macro:*
3610+
3611+
The following macro arguments are supplied for each palette definition:
3612+
----
3613+
#:name:# // The name of the palette definition, which is an integer from 0 to 255.
3614+
----
3615+
3616+
Additionally, the following private definitions are defined:
3617+
3618+
----
3619+
ct Int _index // The unique index of the palette definition.
3620+
ct U[25] _palette // The palette's data.
3621+
----
3622+
3623+
*Metatiles Macro:*
3624+
3625+
The following macro arguments are supplied for each metatile set definition:
3626+
----
3627+
#:name:# // The name of the metatile definition.
3628+
#:chr_name:# // The name of the CHR definition the metatile set uses for display.
3629+
#:palette_name:# // The name of the palette definition the metatile set uses for display.
3630+
----
3631+
3632+
Additionally, the following private definitions are defined:
3633+
3634+
----
3635+
ct Int _index // The unique index of the metatile set definition.
3636+
ct Int _num // The number of metatiles in the set.
3637+
ct U[_num] _nw // The north-west tiles of each metatile.
3638+
ct U[_num] _ne // The north-east tiles of each metatile.
3639+
ct U[_num] _sw // The south-west tiles of each metatile.
3640+
ct U[_num] _se // The south-east tiles of each metatile.
3641+
ct U[_num] _attributes // The 2-bit attribute data of each metatile.
3642+
ct U[_num] _collisions // The 6-bit collision data of each metatile.
3643+
ct U[_num] _combined // The two arrays above combined: attribute | (collision << 2)
3644+
----
3645+
3646+
[NOTE]
3647+
Typically, `chr_name` and `palette_name` should be ignored for metatile sets,
3648+
as level macros have this information too.
3649+
3650+
*Levels Macro:*
3651+
3652+
The following macro arguments are supplied for each level set definition:
3653+
----
3654+
#:name:# // The name of the level definition.
3655+
#:chr_name:# // The name of the CHR definition the metatile set uses for display.
3656+
#:palette_name:# // The name of the palette definition the metatile set uses for display.
3657+
#:metatiles_name:# // The name of the metatile set definition the metatile set uses for display.
3658+
#:macro_name:# // Contents of MapFab's macro field.
3659+
----
3660+
3661+
Additionally, the following private definitions are defined:
3662+
3663+
----
3664+
ct Int _index // The unique index of the level definition.
3665+
ct Int _width // The width of the level, in tiles.
3666+
ct Int _height // The height of the level, in tiles.
3667+
ct U[_width * _height] _row_major // The level's contents in a row-major order.
3668+
ct U[_width * _height] _column_major // The level's contents in a column-major order.
3669+
----
3670+
3671+
For each object class (`CLASS`), the following <<type_vec, VECs>> are defined:
3672+
3673+
----
3674+
ct Int{} _CLASS_x
3675+
ct Int{} _CLASS_y
3676+
----
3677+
3678+
For each field (`FIELD`) in `CLASS`, additional VECs are defined, with the string of each field wrapped inside a cast.
3679+
----
3680+
ct TYPE{} _CLASS_FIELD
3681+
----
3682+
3683+
For example, if the class `foo` had three objects in this level,
3684+
and each object had a field `U bar`, the following definitions would exist:
3685+
3686+
----
3687+
ct Int{} _foo_x = Int{}(203, -3, 3099)
3688+
ct Int{} _foo_y = Int{}(13, 991, -30)
3689+
ct U{} _foo_bar = U{}(U(0), U(5), U(2))
3690+
----
3691+
3692+
*Output Target Conversions*
3693+
3694+
The data of each level (`_row_major` and `_column_major`) are converted based on specified target:
3695+
3696+
[cols="1,3"]
3697+
|===
3698+
|Conversion Target |Description
3699+
3700+
| <<file_raw, `raw`>>
3701+
| No conversion
3702+
3703+
| <<file_pbz, `pbz`>>
3704+
| Compress using PBZ compression
3705+
3706+
| <<file_rlz, `rlz`>>
3707+
| Compress using RLZ compression (no terminator)
3708+
3709+
|===
3710+
3711+
*Modifiers:*
3712+
3713+
- <<mod_flags, `+fork_scope`>>
3714+
35673715
=== `audio` [[kw_audio]]
35683716

35693717
The `audio` keyword imports and converts audio data from an external file,
@@ -3735,6 +3883,7 @@ The following flags exist:
37353883
- `palette_3`: Converts 4-byte palettes into 3-byte palettes.
37363884
- `palette_25`: Converts 32-byte palettes into 25-byte palettes.
37373885
- `+sloppy`, `-sloppy`: Enables / disables faster compilation speed, at the cost of performance.
3886+
- `+fork_scope`: The invoked macro(s) will have access to private definitions inside the invoking file.
37383887

37393888
Example:
37403889
----

src/compiler_error.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "format.hpp"
44
#include "options.hpp"
55
#include "assert.hpp"
6+
#include "text.hpp"
67

78
namespace
89
{
@@ -90,7 +91,17 @@ std::string fmt_error(
9091

9192
assert(file->index() == pstring.file_i);
9293

93-
std::string str(fmt("%: %%:" CONSOLE_RESET " %\n", fmt_source_pos(*file, pstring), color, prefix, what));
94+
std::string str;
95+
96+
if(auto const* invoke = file->invoke())
97+
{
98+
str += fmt(CONSOLE_BOLD "In the invocation of macro \"%\":\n" CONSOLE_RESET, escape(invoke->name));
99+
unsigned i = 0;
100+
for(std::string const& arg : invoke->args)
101+
str += fmt(" With argument % = \"%\"\n", i++, escape(arg));
102+
}
103+
104+
str += fmt("%: %%:" CONSOLE_RESET " %\n", fmt_source_pos(*file, pstring), color, prefix, what);
94105

95106
char const* line_begin = get_line_begin(file->source(), pstring);
96107
char const* line_end = get_line_end(file->source(), pstring);

src/file.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
struct macro_result_t
2929
{
3030
fs::path path;
31+
macro_invocation_t invoke;
3132
std::string contents;
3233
ident_map_t<global_ht> private_globals;
3334
ident_map_t<group_ht> private_groups;
@@ -66,7 +67,10 @@ void invoke_macro(
6667
{
6768
std::lock_guard<std::mutex> lock(invoke_mutex);
6869
if(invoke_set.insert(invoke).second)
69-
new_macro_results.push_back({ pair->second.file, std::move(str), std::move(private_globals), std::move(private_groups) });
70+
{
71+
new_macro_results.push_back({ pair->second.dir / pair->second.file, std::move(invoke), std::move(str),
72+
std::move(private_globals), std::move(private_groups) });
73+
}
7074
}
7175
}
7276

@@ -229,5 +233,6 @@ void file_contents_t::reset(unsigned file_i)
229233
m_source = macro.contents.data();
230234
m_private_globals = &macro.private_globals;
231235
m_private_groups = &macro.private_groups;
236+
m_invoke = &macro.invoke;
232237
}
233238
}

src/file.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct file_contents_t
8181
std::size_t size() const { return m_size; }
8282
ident_map_t<global_ht> const* private_globals() const { return m_private_globals; }
8383
ident_map_t<group_ht> const* private_groups() const { return m_private_groups; }
84+
macro_invocation_t const* invoke() const { return m_invoke; }
8485

8586
void clear() { m_alloc.reset(); m_size = 0; m_source = nullptr; }
8687
void reset(unsigned file_i);
@@ -92,6 +93,7 @@ struct file_contents_t
9293
std::unique_ptr<char[]> m_alloc;
9394
ident_map_t<global_ht> const* m_private_globals = nullptr;
9495
ident_map_t<group_ht> const* m_private_groups = nullptr;
96+
macro_invocation_t const* m_invoke = nullptr;
9597
};
9698

9799
#endif

src/mapfab.cpp

+33-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
#include "convert_compress.hpp"
88

99
void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, std::size_t size,
10-
pstring_t at, fs::path mapfab_path, mapfab_macros_t const& macros)
10+
pstring_t at, fs::path mapfab_path, mapfab_macros_t const& macros,
11+
ident_map_t<global_ht>* base_private_globals,
12+
ident_map_t<group_ht>* base_private_groups)
1113
{
1214
using namespace std::literals;
1315

@@ -68,6 +70,12 @@ void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, s
6870
for(unsigned i = 0; i < num_chr; ++i)
6971
{
7072
ident_map_t<global_ht> private_globals;
73+
if(base_private_globals)
74+
private_globals = *base_private_globals;
75+
ident_map_t<group_ht> private_groups;
76+
if(base_private_groups)
77+
private_groups = *base_private_groups;
78+
7179
define_ct_int(private_globals.lookup(at, "_index"sv), at, TYPE_INT, i);
7280

7381
macro_invocation_t m = { macros.chr };
@@ -78,7 +86,7 @@ void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, s
7886
if(path.is_relative())
7987
path = base_path / path;
8088
m.args.push_back(path.string());
81-
invoke_macro(std::move(m), std::move(private_globals), {});
89+
invoke_macro(std::move(m), std::move(private_globals), std::move(private_groups));
8290
dprint(log, "MAPFAB_CHR_MACRO", i);
8391
}
8492

@@ -90,15 +98,20 @@ void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, s
9098
for(unsigned i = 0; i < num_palettes; ++i)
9199
{
92100
// Defines:
93-
94101
ident_map_t<global_ht> private_globals;
102+
if(base_private_globals)
103+
private_globals = *base_private_globals;
104+
ident_map_t<group_ht> private_groups;
105+
if(base_private_groups)
106+
private_groups = *base_private_groups;
107+
95108
global_t& g = private_globals.lookup(at, "_palette"sv);
96109
define_ct(g, at, palette_data.data() + 25*i, 25);
97110
define_ct_int(private_globals.lookup(at, "_index"sv), at, TYPE_INT, i);
98111

99112
macro_invocation_t m = { macros.palette };
100113
m.args.push_back(std::to_string(i));
101-
invoke_macro(std::move(m), std::move(private_globals), {});
114+
invoke_macro(std::move(m), std::move(private_globals), std::move(private_groups));
102115
dprint(log, "MAPFAB_PALETTE_MACRO", i);
103116
}
104117

@@ -140,6 +153,12 @@ void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, s
140153
mt_combined[i] = (mt_attributes[i] & 0b11) | (mt_collisions[i] << 2);
141154

142155
ident_map_t<global_ht> private_globals;
156+
if(base_private_globals)
157+
private_globals = *base_private_globals;
158+
ident_map_t<group_ht> private_groups;
159+
if(base_private_groups)
160+
private_groups = *base_private_groups;
161+
143162
define_ct_int(private_globals.lookup(at, "_index"sv), at, TYPE_INT, i);
144163
define_ct_int(private_globals.lookup(at, "_num"sv), at, TYPE_INT, num);
145164
define_ct(private_globals.lookup(at, "_nw"sv), at, mt_nw.data(), num);
@@ -154,7 +173,7 @@ void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, s
154173
m.args.push_back(name);
155174
m.args.push_back(chr_name);
156175
m.args.push_back(std::to_string(palette));
157-
invoke_macro(std::move(m), std::move(private_globals), {});
176+
invoke_macro(std::move(m), std::move(private_globals), std::move(private_groups));
158177
}
159178

160179
struct field_t
@@ -227,6 +246,12 @@ void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, s
227246
}
228247

229248
ident_map_t<global_ht> private_globals;
249+
if(base_private_globals)
250+
private_globals = *base_private_globals;
251+
ident_map_t<group_ht> private_groups;
252+
if(base_private_groups)
253+
private_groups = *base_private_groups;
254+
230255
define_ct_int(private_globals.lookup(at, "_index"sv), at, TYPE_INT, i);
231256
define_ct_int(private_globals.lookup(at, "_width"sv), at, TYPE_INT, w);
232257
define_ct_int(private_globals.lookup(at, "_height"sv), at, TYPE_INT, h);
@@ -288,19 +313,19 @@ void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, s
288313
{
289314
if(k != j)
290315
append += ", ";
291-
append += objects[i][k];
316+
append += fmt("%(%)", field.type, objects[i][k]);
292317
}
293318
append += ")\n";
294319
}
295320
}
296321

297-
macro_invocation_t m = { macros.level.empty() ? macro_name : macros.level };
322+
macro_invocation_t m = { macros.level };
298323
m.args.push_back(name);
299324
m.args.push_back(chr_name);
300325
m.args.push_back(std::to_string(palette));
301326
m.args.push_back(metatiles_name);
302327
m.args.push_back(macro_name);
303-
invoke_macro(std::move(m), std::move(private_globals), {}, append);
328+
invoke_macro(std::move(m), std::move(private_globals), std::move(private_groups), std::move(append));
304329
}
305330
}
306331

src/mapfab.hpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ enum mapfab_convert_type_t
2323
MAPFAB_PBZ,
2424
};
2525

26+
template<typename Handle>
27+
class ident_map_t;
28+
class global_ht;
29+
class group_ht;
30+
2631
void convert_mapfab(mapfab_convert_type_t ct, std::uint8_t const* const begin, std::size_t size,
27-
pstring_t at, fs::path mapfab_path, mapfab_macros_t const& macros);
32+
pstring_t at, fs::path mapfab_path, mapfab_macros_t const& macros,
33+
ident_map_t<global_ht>* private_globals,
34+
ident_map_t<group_ht>* private_groups);
2835

2936
#endif

src/parser.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ auto parser_t<P>::parse_file(token_type_t tt, Fn const& fn)
518518
fs::path preferred_dir = file.path();
519519
preferred_dir.remove_filename();
520520

521-
fn(file_pstring, script, preferred_dir, std::move(mods), std::move(args));
521+
fn(file_pstring, script, std::filesystem::absolute(preferred_dir), std::move(mods), std::move(args));
522522
}
523523

524524
template<typename P>

0 commit comments

Comments
 (0)