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