1use getset::*;
58use serde_derive::{Serialize, Deserialize};
59
60use std::collections::BTreeMap;
61
62use crate::error::Result;
63use crate::binary::{ReadBytes, WriteBytes};
64use crate::files::{DecodeableExtraData, Decodeable, EncodeableExtraData, Encodeable, table::{DecodedData, local::TableInMemory, Table}};
65use crate::schema::{Definition, Field, FieldType};
66use crate::utils::check_size_mismatch;
67
68pub const EXTENSION: &str = ".atlas";
70
71const IMAGE_SIZE: u32 = 4096;
76
77const VERSION: i32 = 1;
79
80#[cfg(test)] mod atlas_test;
81
82#[derive(PartialEq, Clone, Debug, Default, Getters, MutGetters, Setters, Serialize, Deserialize)]
91#[getset(get = "pub", get_mut = "pub", set = "pub")]
92pub struct Atlas {
93 version: u32,
95
96 unknown: u32,
98
99 entries: Vec<AtlasEntry>,
101}
102
103#[derive(PartialEq, Clone, Debug, Default, Getters, MutGetters, Setters, Serialize, Deserialize)]
108#[getset(get = "pub", get_mut = "pub", set = "pub")]
109pub struct AtlasEntry {
110 string1: String,
112
113 string2: String,
115
116 x_1: f32,
118
119 y_1: f32,
121
122 x_2: f32,
124
125 y_2: f32,
127
128 width: f32,
130
131 height: f32,
133}
134
135impl From<TableInMemory> for Atlas {
140 fn from(value: TableInMemory) -> Self {
141 let entries = value.data()
142 .iter()
143 .map(|row| AtlasEntry {
144 string1: if let DecodedData::StringU8(data) = &row[0] { data.to_string() } else { panic!("WTF?!")},
145 string2: if let DecodedData::StringU8(data) = &row[1] { data.to_string() } else { panic!("WTF?!")},
146 x_1: if let DecodedData::F32(data) = row[2] { data } else { panic!("WTF?!")},
147 y_1: if let DecodedData::F32(data) = row[3] { data } else { panic!("WTF?!")},
148 x_2: if let DecodedData::F32(data) = row[4] { data } else { panic!("WTF?!")},
149 y_2: if let DecodedData::F32(data) = row[5] { data } else { panic!("WTF?!")},
150 width: if let DecodedData::F32(data) = row[6] { data } else { panic!("WTF?!")},
151 height: if let DecodedData::F32(data) = row[7] { data } else { panic!("WTF?!")},
152 })
153 .collect();
154
155 Self {
156 version: VERSION as u32,
157 unknown: 0,
158 entries,
159 }
160 }
161}
162
163impl From<Atlas> for TableInMemory {
164 fn from(value: Atlas) -> Self {
165 let mut table = Self::new(&Atlas::definition(), None, "");
166 let data = value.entries.iter()
167 .map(|entry| {
168 vec![
169 DecodedData::StringU8(entry.string1.to_owned()),
170 DecodedData::StringU8(entry.string2.to_owned()),
171 DecodedData::F32(entry.x_1),
172 DecodedData::F32(entry.y_1),
173 DecodedData::F32(entry.x_2),
174 DecodedData::F32(entry.y_2),
175 DecodedData::F32(entry.width),
176 DecodedData::F32(entry.height),
177 ]
178 })
179 .collect::<Vec<_>>();
180 let _ = table.set_data(&data);
181 table
182 }
183}
184
185impl Atlas {
186
187 pub fn definition() -> Definition {
201 let mut definition = Definition::new(VERSION, None);
202 let fields = vec![
203 Field::new("string1".to_owned(), FieldType::StringU8, true, Some("PLACEHOLDER".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
204 Field::new("string2".to_owned(), FieldType::StringU8, true, Some("PLACEHOLDER".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
205 Field::new("x_1".to_owned(), FieldType::F32, false, Some("0".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
206 Field::new("y_1".to_owned(), FieldType::F32, false, Some("0".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
207 Field::new("x_2".to_owned(), FieldType::F32, false, Some("0".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
208 Field::new("y_2".to_owned(), FieldType::F32, false, Some("0".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
209 Field::new("width".to_owned(), FieldType::F32, false, Some("0".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
210 Field::new("height".to_owned(), FieldType::F32, false, Some("0".to_owned()), false, None, None, None, String::new(), 0, 0, BTreeMap::new(), None),
211 ];
212 definition.set_fields(fields);
213 definition
214 }
215}
216
217impl Decodeable for Atlas {
218
219 fn decode<R: ReadBytes>(data: &mut R, _extra_data: &Option<DecodeableExtraData>) -> Result<Self> {
220 let version = data.read_u32()?;
221 let unknown = data.read_u32()?;
222
223 let mut entries = vec![];
224
225 for _ in 0..data.read_u32()? {
226
227 entries.push(AtlasEntry {
229 string1: data.read_string_u16_0padded(512)?,
230 string2: data.read_string_u16_0padded(512)?,
231 x_1: data.read_f32()? * IMAGE_SIZE as f32,
232 y_1: data.read_f32()? * IMAGE_SIZE as f32,
233 x_2: data.read_f32()? * IMAGE_SIZE as f32,
234 y_2: data.read_f32()? * IMAGE_SIZE as f32,
235 width: data.read_f32()?,
236 height: data.read_f32()?,
237 })
238 }
239
240 check_size_mismatch(data.stream_position()? as usize, data.len()? as usize)?;
242
243 Ok(Self {
244 version,
245 unknown,
246 entries
247 })
248 }
249}
250
251impl Encodeable for Atlas {
252
253 fn encode<W: WriteBytes>(&mut self, buffer: &mut W, _extra_data: &Option<EncodeableExtraData>) -> Result<()> {
254 buffer.write_u32(self.version)?;
255 buffer.write_u32(self.unknown)?;
256 buffer.write_u32(self.entries.len() as u32)?;
257
258 for entry in &self.entries {
259 buffer.write_string_u16_0padded(&entry.string1, 512, true)?;
260 buffer.write_string_u16_0padded(&entry.string2, 512, true)?;
261 buffer.write_f32(entry.x_1 / IMAGE_SIZE as f32)?;
262 buffer.write_f32(entry.y_1 / IMAGE_SIZE as f32)?;
263 buffer.write_f32(entry.x_2 / IMAGE_SIZE as f32)?;
264 buffer.write_f32(entry.y_2 / IMAGE_SIZE as f32)?;
265 buffer.write_f32(entry.width)?;
266 buffer.write_f32(entry.height)?;
267 }
268
269 Ok(())
270 }
271}