Skip to content

Commit e31db4e

Browse files
committed
Making recolor_art accept all art formats
1 parent f690bd5 commit e31db4e

2 files changed

Lines changed: 115 additions & 44 deletions

File tree

CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,8 @@ set(VOICEDUMPER_SOURCES
412412
"src/tools/fmvoice.cc"
413413
"src/tools/voice_dumper.cc"
414414
)
415+
416+
set(ALL_FORMATS "mdcomp::comper;mdcomp::comperx;mdcomp::kosinski;mdcomp::kosplus;mdcomp::lzkn1;mdcomp::nemesis;mdcomp::rocket;mdcomp::saxman;mdcomp::snkrle")
415417
define_exe(voice_dumper "${VOICEDUMPER_SOURCES}" "" voice_dumper)
416418
define_exe(chunk_census "src/tools/chunk_census.cc" "mdcomp::kosinski" chunk_census)
417419
define_exe(split_art "src/tools/split_art.cc" "mappings;mdcomp::comper;mdcomp::kosinski" split_art)
@@ -423,7 +425,7 @@ set(SMPS2ASM_SOURCES
423425
"src/tools/songtrack.cc"
424426
)
425427
define_exe(smps2asm "${SMPS2ASM_SOURCES}" "mdcomp::saxman" smps2asm)
426-
define_exe(recolor_art "src/tools/recolor_art.cc" "mdcomp::nemesis;mdcomp::kosinski" recolor_art)
428+
define_exe(recolor_art "src/tools/recolor_art.cc" "${ALL_FORMATS}" recolor_art)
427429
define_exe(mapping_tool "src/tools/mapping_tool.cc" "mappings" mapping_tool)
428430
define_exe(plane_map "src/tools/plane_map.cc" "mdcomp::enigma" plane_map)
429431
define_exe(enitool "src/tools/enitool.cc" "mdcomp::enigma" enitool)

src/tools/recolor_art.cc

Lines changed: 112 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,29 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18+
#include "mdtools/ignore_unused_variable_warning.hh"
19+
1820
#include <getopt.h>
21+
#include <mdcomp/comper.hh>
22+
#include <mdcomp/comperx.hh>
1923
#include <mdcomp/kosinski.hh>
24+
#include <mdcomp/kosplus.hh>
25+
#include <mdcomp/lzkn1.hh>
2026
#include <mdcomp/nemesis.hh>
27+
#include <mdcomp/rocket.hh>
28+
#include <mdcomp/saxman.hh>
29+
#include <mdcomp/snkrle.hh>
2130

2231
#include <algorithm>
2332
#include <cstdlib>
2433
#include <cstring>
2534
#include <fstream>
35+
#include <functional>
2636
#include <iostream>
37+
#include <memory>
2738
#include <sstream>
39+
#include <string>
40+
#include <unordered_map>
2841

2942
using std::cerr;
3043
using std::endl;
@@ -35,10 +48,15 @@ using std::ofstream;
3548
using std::ostream;
3649
using std::streamsize;
3750
using std::string;
51+
using std::string_view;
3852
using std::stringstream;
3953

54+
using namespace std::literals::string_view_literals;
55+
4056
static void usage() {
41-
cerr << "Usage: recolor-art [-o|--format {unc|nem|kos}] [-m|--moduled] "
57+
cerr << "Usage: recolor-art [-o|--format "
58+
"{unc|comp|compx|kos|kos+|lzkn1|nem|rocket|snk}] "
59+
"[-m|--moduled] "
4260
"{-clr1 clr2}+ {input_art} {output_art}"
4361
<< endl;
4462
cerr << "\tRecolors the art file, changing palette index clr1 to clr2. "
@@ -50,8 +68,6 @@ static void usage() {
5068
<< endl;
5169
}
5270

53-
enum Formats { eInvalid = -1, eUncompressed = 0, eNemesis = 1, eKosinski = 2 };
54-
5571
using ColorMap = std::array<int, 16>;
5672

5773
struct Tile {
@@ -88,6 +104,30 @@ struct Tile {
88104
}
89105
};
90106

107+
class uncompressed;
108+
using basic_uncompressed = BasicDecoder<uncompressed, PadMode::PadEven>;
109+
using moduled_uncompressed = ModuledAdaptor<uncompressed, 4096U, 1U>;
110+
111+
class uncompressed : public basic_uncompressed, public moduled_uncompressed {
112+
friend basic_uncompressed;
113+
friend moduled_uncompressed;
114+
static bool encode(std::ostream& Dst, uint8_t const* data, size_t Size);
115+
116+
public:
117+
using basic_uncompressed::encode;
118+
static bool decode(std::istream& Src, std::iostream& Dst);
119+
};
120+
121+
bool uncompressed::encode(std::ostream& Dst, uint8_t const* data, size_t Size) {
122+
Dst.write(reinterpret_cast<const char*>(data), Size);
123+
return true;
124+
}
125+
126+
bool uncompressed::decode(std::istream& Src, std::iostream& Dst) {
127+
Dst << Src.rdbuf();
128+
return true;
129+
}
130+
91131
void recolor(istream& in, ostream& out, ColorMap& colormap) {
92132
Tile tile{};
93133
while (true) {
@@ -99,6 +139,21 @@ void recolor(istream& in, ostream& out, ColorMap& colormap) {
99139
}
100140
}
101141

142+
template <>
143+
size_t moduled_uncompressed::PadMaskBits = 1U;
144+
145+
using encoder = decltype(&basic_uncompressed::encode);
146+
using decoder = decltype(&uncompressed::decode);
147+
using moduled_encoder = decltype(&uncompressed::moduled_encode);
148+
using moduled_decoder = decltype(&uncompressed::moduled_decode);
149+
150+
struct art_format {
151+
encoder encode;
152+
decoder decode;
153+
moduled_encoder moduled_encode;
154+
moduled_decoder moduled_decode;
155+
};
156+
102157
int main(int argc, char* argv[]) {
103158
constexpr static const std::array long_options{
104159
option{"format", required_argument, nullptr, 'o'},
@@ -111,7 +166,44 @@ int main(int argc, char* argv[]) {
111166
ColorMap colormap{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
112167
0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
113168
unsigned numcolors = 0;
114-
Formats fmt = eUncompressed;
169+
170+
static const std::unordered_map<string_view, art_format>
171+
format_lut{
172+
{{"unc"sv,
173+
{uncompressed::encode, uncompressed::decode,
174+
uncompressed::moduled_encode,
175+
uncompressed::moduled_decode}},
176+
{"comp"sv,
177+
{comper::encode, comper::decode, comper::moduled_encode,
178+
comper::moduled_decode}},
179+
{"compx"sv,
180+
{comperx::encode, comperx::decode,
181+
comperx::moduled_encode, comperx::moduled_decode}},
182+
{"kos"sv,
183+
{kosinski::encode, kosinski::decode,
184+
kosinski::moduled_encode, kosinski::moduled_decode}},
185+
{"kos+"sv,
186+
{kosplus::encode, kosplus::decode,
187+
kosplus::moduled_encode, kosplus::moduled_decode}},
188+
{"lzkn1"sv,
189+
{lzkn1::encode, lzkn1::decode, lzkn1::moduled_encode,
190+
lzkn1::moduled_decode}},
191+
{"nem"sv,
192+
{nemesis::encode,
193+
+[](std::istream& Src, std::iostream& Dst) {
194+
return nemesis::decode(Src, Dst);
195+
},
196+
nemesis::moduled_encode, nemesis::moduled_decode}},
197+
{"rocket"sv,
198+
{rocket::encode, rocket::decode, rocket::moduled_encode,
199+
rocket::moduled_decode}},
200+
{"snk"sv,
201+
{snkrle::encode,
202+
+[](std::istream& Src, std::iostream& Dst) {
203+
return snkrle::decode(Src, Dst);
204+
},
205+
snkrle::moduled_encode, snkrle::moduled_decode}}}};
206+
auto fmt = format_lut.cend();
115207

116208
while (true) {
117209
int option_index = 0;
@@ -126,26 +218,14 @@ int main(int argc, char* argv[]) {
126218
option_char += ('a' - 'A');
127219
}
128220

129-
auto getFormat = [](auto optarg) {
130-
if (optarg == nullptr) {
131-
return eInvalid;
132-
}
133-
if (strcmp(optarg, "unc") == 0) {
134-
return eUncompressed;
135-
}
136-
if (strcmp(optarg, "nem") == 0) {
137-
return eNemesis;
138-
}
139-
if (strcmp(optarg, "kos") == 0) {
140-
return eKosinski;
141-
}
142-
return eInvalid;
143-
};
144-
145221
switch (option_char) {
146222
case 'o':
147-
fmt = getFormat(optarg);
148-
if (fmt == eInvalid) {
223+
if (optarg == nullptr) {
224+
usage();
225+
return 1;
226+
}
227+
fmt = format_lut.find(optarg);
228+
if (fmt == format_lut.cend()) {
149229
usage();
150230
return 1;
151231
}
@@ -220,17 +300,13 @@ int main(int argc, char* argv[]) {
220300
stringstream sin(ios::in | ios::out | ios::binary);
221301
stringstream sout(ios::in | ios::out | ios::binary);
222302

303+
auto const& [key, fmt_handler] = *fmt;
304+
223305
fin.seekg(0);
224-
if (fmt == eUncompressed) {
225-
sin << fin.rdbuf();
226-
} else if (fmt == eNemesis) {
227-
nemesis::decode(fin, sin);
228-
} else { // if (fmt == eKosinski)
229-
if (moduled) {
230-
kosinski::moduled_decode(fin, sin);
231-
} else {
232-
kosinski::decode(fin, sin);
233-
}
306+
if (moduled) {
307+
fmt_handler.moduled_decode(fin, sin, modulesize);
308+
} else {
309+
fmt_handler.decode(fin, sin);
234310
}
235311

236312
fin.close();
@@ -246,17 +322,10 @@ int main(int argc, char* argv[]) {
246322
}
247323

248324
sout.seekg(0);
249-
250-
if (fmt == eUncompressed) {
251-
fout << sout.rdbuf();
252-
} else if (fmt == eNemesis) {
253-
nemesis::encode(sout, fout);
254-
} else { // if (fmt == eKosinski)
255-
if (moduled) {
256-
kosinski::moduled_encode(sout, fout, modulesize);
257-
} else {
258-
kosinski::encode(sout, fout);
259-
}
325+
if (moduled) {
326+
fmt_handler.moduled_encode(sout, fout, modulesize);
327+
} else {
328+
fmt_handler.encode(sout, fout);
260329
}
261330

262331
fout.close();

0 commit comments

Comments
 (0)