yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
scad_format.cc
Go to the documentation of this file.
1#include "scad_format.h"
2
3#include <cstdint>
4#include <cstdlib>
5#include <cstring>
6#include <fstream>
7#include <iostream>
8#include <vector>
9
10#include "absl/status/status.h"
11#include "app/gfx/snes_tile.h"
12#include "util/macro.h"
13
14namespace yaze {
15namespace gfx {
16namespace scad_format {
17
19 int matching_position = -1;
20 bool matched = false;
21 std::vector<uint8_t> cgx_rom;
22 std::vector<uint8_t> raw_data_;
23 for (int i = 0;
24 i < cgx_rom.size() - sizeof(kMatchedBytes) - kOffsetFromMatchedBytesEnd;
25 i++) {
26 raw_data_.push_back(cgx_rom[i]);
27 bool is_match = std::equal(std::begin(kMatchedBytes),
28 std::end(kMatchedBytes), &cgx_rom[i]);
29 if (is_match) {
30 matching_position = i;
31 matched = true;
32 break;
33 }
34 }
35 if (matched) {
36 int bpp_marker_position =
37 matching_position + sizeof(kMatchedBytes) + kOffsetFromMatchedBytesEnd;
38 int bpp_marker = cgx_rom[bpp_marker_position];
39 std::string bpp_type = (bpp_marker == 0x31) ? "8bpp" : "4bpp";
40 }
41}
42
43absl::Status LoadCgx(uint8_t bpp, std::string_view filename,
44 std::vector<uint8_t>& cgx_data,
45 std::vector<uint8_t>& cgx_loaded,
46 std::vector<uint8_t>& cgx_header) {
47 std::ifstream file(filename.data(), std::ios::binary);
48 if (!file.is_open()) {
49 return absl::NotFoundError("CGX file not found.");
50 }
51 std::vector<uint8_t> file_content((std::istreambuf_iterator<char>(file)),
52 std::istreambuf_iterator<char>());
53 cgx_data =
54 std::vector<uint8_t>(file_content.begin(), file_content.end() - 0x500);
55 file.seekg(cgx_data.size() + 0x100);
56 cgx_header = std::vector<uint8_t>((std::istreambuf_iterator<char>(file)),
57 std::istreambuf_iterator<char>());
58 file.close();
59
60 if (bpp > 8) {
61 cgx_loaded = gfx::Bpp8SnesToIndexed(cgx_data, 40);
62 return absl::OkStatus();
63 }
64 cgx_loaded = gfx::Bpp8SnesToIndexed(cgx_data, bpp);
65 return absl::OkStatus();
66}
67
68absl::Status LoadScr(std::string_view filename, uint8_t input_value,
69 std::vector<uint8_t>& map_data) {
70 std::ifstream file(filename.data(), std::ios::binary);
71 if (!file.is_open()) {
72 return absl::NotFoundError("SCR/PNL/MAP file not found.");
73 }
74
75 // Check if file extension is PNL
76 bool pnl = false;
77 if (filename.find("PNL") != std::string::npos) {
78 std::vector<uint8_t> scr_data;
79 map_data.resize(0x8000);
80 scr_data.resize(0x8000);
81
82 // Read from file for 0x8000 bytes
83 std::vector<uint8_t> file_content((std::istreambuf_iterator<char>(file)),
84 std::istreambuf_iterator<char>());
85 scr_data = std::vector<uint8_t>(file_content.begin(), file_content.end());
86
87 int md = 0x100;
88
89 for (int i = input_value * 0x400; i < 0x1000 + input_value * 0x400;
90 i += 2) {
91 auto b1_pos = (i - (input_value * 0x400));
92 map_data[b1_pos] = gfx::TileInfoToShort(
93 gfx::GetTilesInfo((uint16_t)scr_data[md + (i * 2)]));
94
95 auto b2_pos = (i - (input_value * 0x400) + 1);
96 map_data[b2_pos] = gfx::TileInfoToShort(
97 gfx::GetTilesInfo((uint16_t)scr_data[md + (i * 2) + 2]));
98 }
99 // 0x900
100
101 } else {
102 int offset = 0;
103 std::vector<uint8_t> scr_data;
104 map_data.resize(0x2000);
105 scr_data.resize(0x2000);
106
107 // read from file for 0x2000 bytes
108 std::vector<uint8_t> file_content((std::istreambuf_iterator<char>(file)),
109 std::istreambuf_iterator<char>());
110 scr_data = std::vector<uint8_t>(file_content.begin(), file_content.end());
111
112 for (int i = 0; i < 0x1000 - offset; i++) {
113 map_data[i] = gfx::TileInfoToShort(
114 gfx::GetTilesInfo((uint16_t)scr_data[((i + offset) * 2)]));
115 }
116 }
117 return absl::OkStatus();
118}
119
120absl::Status DrawScrWithCgx(uint8_t bpp, std::vector<uint8_t>& map_data,
121 std::vector<uint8_t>& map_bitmap_data,
122 std::vector<uint8_t>& cgx_loaded) {
123 const std::vector<uint16_t> dimensions = {0x000, 0x400, 0x800, 0xC00};
124 uint8_t p = 0;
125 for (const auto each_dimension : dimensions) {
126 p = each_dimension;
127 // for each tile on the tile buffer
128 for (int i = 0; i < 0x400; i++) {
129 if (map_data[i + p] != 0xFF) {
130 auto t = gfx::GetTilesInfo(map_data[i + p]);
131
132 for (auto yl = 0; yl < 8; yl++) {
133 for (auto xl = 0; xl < 8; xl++) {
134 int mx = xl * (1 - t.horizontal_mirror_) +
135 (7 - xl) * (t.horizontal_mirror_);
136 int my =
137 yl * (1 - t.vertical_mirror_) + (7 - yl) * (t.vertical_mirror_);
138
139 int ty = (t.id_ / 16) * 1024;
140 int tx = (t.id_ % 16) * 8;
141 auto pixel = cgx_loaded[(tx + ty) + (yl * 128) + xl];
142
143 int index = (((i % 32) * 8) + ((i / 32) * 2048) + mx + (my * 256));
144
145 if (bpp != 8) {
146 map_bitmap_data[index] =
147 (uint8_t)((pixel & 0xFF) + t.palette_ * 16);
148 } else {
149 map_bitmap_data[index] = (uint8_t)(pixel & 0xFF);
150 }
151 }
152 }
153 }
154 }
155 }
156 return absl::OkStatus();
157}
158
159std::vector<SDL_Color> DecodeColFile(const std::string_view filename) {
160 std::vector<SDL_Color> decoded_col;
161 std::ifstream file(filename.data(), std::ios::binary | std::ios::ate);
162
163 if (!file.is_open()) {
164 return decoded_col; // Return an empty vector if the file couldn't be
165 // opened.
166 }
167
168 std::streamsize size = file.tellg();
169 file.seekg(0, std::ios::beg);
170
171 std::vector<char> buffer(size);
172 if (file.read(buffer.data(), size)) {
173 buffer.resize(size - 0x200);
174
175 int k = 0;
176 for (size_t i = 0; i < buffer.size() / 2; i++) {
177 uint16_t current_color = static_cast<unsigned char>(buffer[k]) |
178 (static_cast<unsigned char>(buffer[k + 1]) << 8);
179
180 SDL_Color color;
181 color.r = (current_color & 31) << 3;
182 color.g = ((current_color >> 5) & 31) << 3;
183 color.b = ((current_color >> 10) & 31) << 3;
184 color.a = (i & 0xF) == 0 ? 0 : 255;
185
186 decoded_col.push_back(color);
187 k += 2;
188 }
189 }
190
191 return decoded_col;
192}
193
194absl::Status DecodeObjFile(
195 std::string_view filename, std::vector<uint8_t>& obj_data,
196 std::vector<uint8_t> actual_obj_data,
197 std::unordered_map<std::string, std::vector<uint8_t>> decoded_obj,
198 std::vector<uint8_t>& decoded_extra_obj, int& obj_loaded) {
199 std::vector<uint8_t> header_obj;
200 int obj_range;
201 int expected_cut;
202 if (obj_loaded == 0) {
203 obj_range = 0x180;
204 expected_cut = 0x500;
205 } else {
206 obj_range = 0x300;
207 expected_cut = 0x900;
208 }
209
210 std::ifstream file(filename.data(), std::ios::binary);
211 if (!file.is_open()) {
212 return absl::NotFoundError("OBJ file not found.");
213 }
214
215 std::vector<uint8_t> file_content((std::istreambuf_iterator<char>(file)),
216 std::istreambuf_iterator<char>());
217 obj_data = file_content;
218 file.close();
219
220 int cut = obj_data.size() & 0x0FFF;
221 actual_obj_data =
222 std::vector<uint8_t>(obj_data.begin(), obj_data.end() - cut);
223 decoded_extra_obj =
224 std::vector<uint8_t>(obj_data.begin() + actual_obj_data.size(),
225 obj_data.begin() + actual_obj_data.size() + 0x100);
226 header_obj = std::vector<uint8_t>(
227 actual_obj_data.begin() + actual_obj_data.size(), actual_obj_data.end());
228
229 if (cut > expected_cut) {
230 std::vector<uint8_t> scad_data;
231 int j = 0;
232 int k = (obj_loaded == 0) ? 63 : 127;
233
234 for (size_t i = 0; i < (actual_obj_data.size() / 6); i++) {
235 std::vector<uint8_t> data = {
236 actual_obj_data[k * 6 + 0 + j], // display
237 actual_obj_data[k * 6 + 1 + j], // unknown
238 actual_obj_data[k * 6 + 2 + j], // y-disp
239 actual_obj_data[k * 6 + 3 + j], // x-disp
240 actual_obj_data[k * 6 + 5 + j], // props
241 actual_obj_data[k * 6 + 4 + j] // tile
242 };
243 scad_data.insert(scad_data.end(), data.begin(), data.end());
244
245 k = k - 1;
246 if (k == -1) {
247 k = (obj_loaded == 0) ? 63 : 127;
248 j = j + ((k + 1) * 6);
249 }
250 }
251
252 int extra_data_range = 0x400 * (obj_loaded + 1) + 0x100;
253 for (int i = 0; i < extra_data_range; i++) {
254 scad_data.push_back(header_obj[i]);
255 }
256
257 obj_data = scad_data;
258 actual_obj_data =
259 std::vector<uint8_t>(obj_data.begin(), obj_data.end() - cut);
260 }
261
262 decoded_obj.clear();
263 for (int k = 0; k < 128; k++) {
264 decoded_obj["frame " + std::to_string(k)] = std::vector<uint8_t>(obj_range);
265 for (int i = 0; i < obj_range; i++) {
266 try {
267 decoded_obj["frame " + std::to_string(k)][i] =
268 obj_data[i + (obj_range * k)];
269 } catch (...) {
270 decoded_obj["frame " + std::to_string(k)][i] = 0;
271 }
272 }
273 }
274
275 return absl::OkStatus();
276}
277
278} // namespace scad_format
279} // namespace gfx
280} // namespace yaze
Loading from prototype SCAD format.
absl::Status LoadScr(std::string_view filename, uint8_t input_value, std::vector< uint8_t > &map_data)
Load Scr file (screen data)
absl::Status DecodeObjFile(std::string_view filename, std::vector< uint8_t > &obj_data, std::vector< uint8_t > actual_obj_data, std::unordered_map< std::string, std::vector< uint8_t > > decoded_obj, std::vector< uint8_t > &decoded_extra_obj, int &obj_loaded)
Decode obj file.
absl::Status LoadCgx(uint8_t bpp, std::string_view filename, std::vector< uint8_t > &cgx_data, std::vector< uint8_t > &cgx_loaded, std::vector< uint8_t > &cgx_header)
Load Cgx file (graphical content)
constexpr uint16_t kOffsetFromMatchedBytesEnd
Definition scad_format.h:52
absl::Status DrawScrWithCgx(uint8_t bpp, std::vector< uint8_t > &map_data, std::vector< uint8_t > &map_bitmap_data, std::vector< uint8_t > &cgx_loaded)
Draw screen tilemap with graphical data.
std::vector< SDL_Color > DecodeColFile(const std::string_view filename)
Decode color file.
void FindMetastamp()
Find metastamp in CGX file.
constexpr uint16_t kMatchedBytes[]
Definition scad_format.h:51
Contains classes for handling graphical data.
Definition bitmap.cc:16
uint16_t TileInfoToShort(TileInfo tile_info)
Definition snes_tile.cc:345
std::vector< uint8_t > Bpp8SnesToIndexed(std::vector< uint8_t > data, uint64_t bpp)
Definition snes_tile.cc:211
TileInfo GetTilesInfo(uint16_t tile)
Definition snes_tile.cc:376
Main namespace for the application.
Definition controller.cc:18