17 const std::vector<std::string>& lines,
size_t first_line) {
18 constexpr std::array<std::string_view, 7> names = {
19 ".start_index",
".nbr_of_tiles",
".x_offsets",
".y_offsets",
20 ".chr",
".properties",
".sizes"};
21 std::array<std::vector<int>, 7> values;
22 std::array<bool, 7> seen{};
24 auto trim = [](std::string_view value) {
25 const auto begin = value.find_first_not_of(
" \t\r");
26 return begin == std::string_view::npos
29 value.find_last_not_of(
" \t\r") - begin + 1);
32 return absl::InvalidArgumentError(
33 "Unsupported draw tables: need seven unique literal db/dw tables in "
36 for (
size_t i = first_line; i < lines.size(); ++i) {
37 auto line = trim(std::string_view(lines[i]).substr(0, lines[i].find(
';')));
38 if (line.empty() || line ==
"{")
42 if (line.back() ==
':' && line.front() !=
'.')
45 for (
size_t j = 0; j < names.size(); ++j) {
46 if (line == names[j] ||
47 (line.back() ==
':' && line.substr(0, line.size() - 1) == names[j]))
59 if (line.size() < 4 ||
60 line.substr(0, 2) != (active == 2 || active == 3 ?
"dw" :
"db") ||
61 (line[2] !=
' ' && line[2] !=
'\t'))
63 line = trim(line.substr(3));
64 while (!line.empty()) {
65 auto comma = line.find(
',');
66 auto token = trim(line.substr(0, comma));
70 if (token.front() ==
'$') {
72 token.remove_prefix(1);
73 }
else if (token.front() ==
'%') {
75 token.remove_prefix(1);
78 auto result = std::from_chars(token.data(), token.data() + token.size(),
80 if (result.ec != std::errc{} || result.ptr != token.data() + token.size())
82 if (active == 2 || active == 3) {
83 if (value < -32768 || value > 65535)
87 }
else if (value < 0 || value > 255)
89 values[active].push_back(value);
90 if (values[active].size() > 256)
92 if (comma == std::string_view::npos)
94 line = trim(line.substr(comma + 1));
99 for (
size_t i = 0; i < names.size(); ++i)
100 if (!seen[i] || values[i].empty())
102 if (values[0].size() != values[1].size())
104 const size_t tiles = values[2].size();
107 for (
size_t i = 3; i < names.size(); ++i)
108 if (values[i].size() != tiles)
110 std::vector<zsprite::Frame> frames;
111 for (
size_t i = 0; i < values[0].size(); ++i) {
112 const size_t start = values[0][i], count = values[1][i] + 1;
113 if (start + count > tiles)
116 for (
size_t j = start; j < start + count; ++j) {
117 if (values[2][j] < -128 || values[2][j] > 127 || values[3][j] < -112 ||
118 values[3][j] > 143 || (values[6][j] != 0 && values[6][j] != 2))
120 const int property = values[5][j];
121 frame.
Tiles.emplace_back(
123 property & 128, values[4][j] | ((property & 1) << 8),
124 (property >> 1) & 7, values[6][j] == 2, (property >> 4) & 3);
126 frames.push_back(std::move(frame));
135 const std::vector<std::string>& lines,
size_t first_line) {
137 size_t table_start = lines.size();
138 for (
size_t i = first_line; i < lines.size(); ++i) {
139 auto text = lines[i].substr(0, lines[i].find(
';'));
140 text.erase(std::remove_if(text.begin(), text.end(),
141 [](
unsigned char c) { return std::isspace(c); }),
143 if (text ==
".start_index" || text ==
".start_index:") {
147 if (text.empty() || text ==
"{")
153 constexpr const char* kReviewedDriverSha256 =
154 "45fc82df667e131b3979473c4c6e9d12c890a7fb1e7589b024405a98b3987e6f";
156 return absl::FailedPreconditionError(
157 "Maple draw driver changed; adapter review required");
158 std::vector<std::string> tables;
159 size_t tile_count = 0;
160 bool reading_chr =
false;
161 for (
size_t i = table_start; i < lines.size(); ++i) {
162 auto text = lines[i].substr(0, lines[i].find(
';'));
163 auto begin = text.find_first_not_of(
" \t\r");
164 if (begin == std::string::npos)
166 text = text.substr(begin, text.find_last_not_of(
" \t\r") - begin + 1);
167 if (text ==
"}" || (text.back() ==
':' && text.front() !=
'.'))
169 if (text.front() ==
'.')
170 reading_chr = (text ==
".chr" || text ==
".chr:");
171 else if (reading_chr && text.rfind(
"db", 0) == 0)
172 tile_count += std::count(text.begin(), text.end(),
',') + 1;
173 tables.push_back(text);
175 if (tile_count == 0 || tile_count > 128)
176 return absl::InvalidArgumentError(
"Invalid Maple tile count");
177 std::string xs =
"dw 0", sizes =
"db 2";
178 for (
size_t i = 1; i < tile_count; ++i) {
182 tables.insert(tables.end(), {
".x_offsets", xs,
".sizes", sizes});