1use std::io::Cursor;
2use binrw::{BinRead, BinWrite};
3use rpkg_rs::{GlacierResource, GlacierResourceError};
4use crate::mipblock::MipblockData;
5use crate::pack::TexturePackerError;
6use crate::texture_map::TextureMap;
7use crate::WoaVersion;
8
9
10impl From<rpkg_rs::WoaVersion> for WoaVersion {
11 fn from(value: rpkg_rs::WoaVersion) -> Self {
12 match value {
13 rpkg_rs::WoaVersion::HM2016 => { WoaVersion::HM2016 }
14 rpkg_rs::WoaVersion::HM2 => { WoaVersion::HM2 }
15 rpkg_rs::WoaVersion::HM3 => { WoaVersion::HM3 }
16 }
17 }
18}
19
20impl From<WoaVersion> for rpkg_rs::WoaVersion{
21 fn from(value: WoaVersion) -> Self {
22 match value {
23 WoaVersion::HM2016 => { rpkg_rs::WoaVersion::HM2016 }
24 WoaVersion::HM2 => { rpkg_rs::WoaVersion::HM2 }
25 WoaVersion::HM3 => { rpkg_rs::WoaVersion::HM3 }
26 }
27 }
28}
29
30impl GlacierResource for TextureMap {
31 type Output = TextureMap;
32
33 fn process_data<R: AsRef<[u8]>>(woa_version: rpkg_rs::WoaVersion, data: R) -> Result<Self::Output, GlacierResourceError> {
34 let mut stream = Cursor::new(data);
35 TextureMap::read_le_args(&mut stream, (WoaVersion::from(woa_version), )).map_err(|e| GlacierResourceError::ReadError(e.to_string()))
36 }
37
38 fn serialize(&self, _: rpkg_rs::WoaVersion) -> Result<Vec<u8>, GlacierResourceError> {
39 let mut writer = Cursor::new(Vec::new());
41 self.write_le_args(&mut writer, ())
42 .map_err(TexturePackerError::SerializationError).map_err(|e| GlacierResourceError::ReadError(e.to_string()))?; Ok(writer.into_inner())
44 }
45
46 fn resource_type() -> [u8; 4] {
47 *b"TEXT"
48 }
49
50 fn video_memory_requirement(&self) -> u64 {
51 self.video_memory_requirement() as u64
52 }
53
54 fn system_memory_requirement(&self) -> u64 {
55 0xFFFFFFFF
56 }
57
58 fn should_scramble(&self) -> bool {
59 true
60 }
61
62 fn should_compress(&self) -> bool {
63 match self.version(){
64 WoaVersion::HM2016 => {true}
65 WoaVersion::HM2 |
66 WoaVersion::HM3 => {false}
67 }
68 }
69}
70
71impl GlacierResource for MipblockData{
72 type Output = MipblockData;
73
74 fn process_data<R: AsRef<[u8]>>(woa_version: rpkg_rs::WoaVersion, data: R) -> Result<Self::Output, GlacierResourceError> {
75 let mipblock = MipblockData::from_memory(data.as_ref(), woa_version.into()).map_err(|e| GlacierResourceError::ReadError(e.to_string()))?;
76 Ok(mipblock)
77 }
78
79 fn serialize(&self, woa_version: rpkg_rs::WoaVersion) -> Result<Vec<u8>, GlacierResourceError> {
80 if self.header.is_empty() && (woa_version == rpkg_rs::WoaVersion::HM2016 || woa_version == rpkg_rs::WoaVersion::HM2) {
81 return Err(GlacierResourceError::ReadError(format!("Cannot serialize to {woa_version:?} without header data :(")));
82 }
83 self.pack_to_vec(woa_version.into()).map_err( |e| GlacierResourceError::WriteError(format!("Texd packing error: {e}")))
84 }
85
86 fn resource_type() -> [u8; 4] {
87 *b"TEXD"
88 }
89
90 fn video_memory_requirement(&self) -> u64 {
91 self.video_memory_requirement() as u64
92 }
93
94 fn system_memory_requirement(&self) -> u64 {
95 0xFFFFFFFF
96 }
97
98 fn should_scramble(&self) -> bool {
99 false
100 }
101
102 fn should_compress(&self) -> bool {
103 false
104 }
105}
106
107pub fn full_texture(manager: &rpkg_rs::resource::partition_manager::PartitionManager, woa_version: rpkg_rs::WoaVersion, rrid: rpkg_rs::resource::runtime_resource_id::RuntimeResourceID) -> Result<TextureMap, GlacierResourceError> {
108 let res_info = manager.resource_info_from(&"chunk0".parse().unwrap(), &rrid).map_err(|e| GlacierResourceError::ReadError(e.to_string()))?;
109 let data = manager.read_resource_from("chunk0".parse().unwrap(), rrid).map_err(|e| GlacierResourceError::ReadError(e.to_string()))?;
110
111 let mut stream = Cursor::new(data);
112 let mut texture_map = TextureMap::read_le_args(&mut stream, (WoaVersion::from(woa_version), )).map_err(|e| GlacierResourceError::ReadError(e.to_string()))?;
113
114 if let Some((rrid, _)) = res_info.references().first(){
115 let texd_data = manager.read_resource_from("chunk0".parse().unwrap(), *rrid).map_err(|e| GlacierResourceError::ReadError(format!("Tried to load broken depend: {e}")))?;
116 let mipblock = MipblockData::from_memory(texd_data.as_slice(), woa_version.into()).map_err(|e| GlacierResourceError::ReadError(format!("Failed to read texd: {e}")))?;
117 texture_map.set_mipblock1(mipblock);
118 }
119 Ok(texture_map)
120}