129 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			129 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | /*
 | ||
|  | MIT License | ||
|  | 
 | ||
|  | Copyright (c) 2025 tobid7 | ||
|  | 
 | ||
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
|  | of this software and associated documentation files (the "Software"), to deal | ||
|  | in the Software without restriction, including without limitation the rights | ||
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
|  | copies of the Software, and to permit persons to whom the Software is | ||
|  | furnished to do so, subject to the following conditions: | ||
|  | 
 | ||
|  | The above copyright notice and this permission notice shall be included in all | ||
|  | copies or substantial portions of the Software. | ||
|  | 
 | ||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
|  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
|  | SOFTWARE. | ||
|  | */ | ||
|  | 
 | ||
|  | #include <d7rc/file.hpp>
 | ||
|  | 
 | ||
|  | namespace D7RC { | ||
|  | File::Header File::Header::New() { | ||
|  |   Header ret; | ||
|  |   ret.Magic = 0; | ||
|  |   ret.Width = 0; | ||
|  |   ret.Height = 0; | ||
|  |   ret.DataSize = 0; | ||
|  |   ret.TabLen = 0; | ||
|  |   ret.Format = 0; | ||
|  |   ret.pUnk = 0; | ||
|  |   ret.NumEntries = 0; | ||
|  |   return ret; | ||
|  | } | ||
|  | 
 | ||
|  | void File::Header::Write(std::ofstream& off) { | ||
|  |   off.write(reinterpret_cast<const char*>(&Magic), sizeof(Magic)); | ||
|  |   off.write(reinterpret_cast<const char*>(&Width), sizeof(Width)); | ||
|  |   off.write(reinterpret_cast<const char*>(&Height), sizeof(Height)); | ||
|  |   off.write(reinterpret_cast<const char*>(&DataSize), sizeof(DataSize)); | ||
|  |   off.write(reinterpret_cast<const char*>(&TabLen), sizeof(TabLen)); | ||
|  |   off.write(reinterpret_cast<const char*>(&Format), sizeof(Format)); | ||
|  |   off.write(reinterpret_cast<const char*>(&pUnk), sizeof(pUnk)); | ||
|  |   off.write(reinterpret_cast<const char*>(&NumEntries), sizeof(NumEntries)); | ||
|  | } | ||
|  | 
 | ||
|  | void File::Header::Read(std::ifstream& iff) { | ||
|  |   iff.read(reinterpret_cast<char*>(&Magic), sizeof(Magic)); | ||
|  |   iff.read(reinterpret_cast<char*>(&Width), sizeof(Width)); | ||
|  |   iff.read(reinterpret_cast<char*>(&Height), sizeof(Height)); | ||
|  |   iff.read(reinterpret_cast<char*>(&DataSize), sizeof(DataSize)); | ||
|  |   iff.read(reinterpret_cast<char*>(&TabLen), sizeof(TabLen)); | ||
|  |   iff.read(reinterpret_cast<char*>(&Format), sizeof(Format)); | ||
|  |   iff.read(reinterpret_cast<char*>(&pUnk), sizeof(pUnk)); | ||
|  |   iff.read(reinterpret_cast<char*>(&NumEntries), sizeof(NumEntries)); | ||
|  | } | ||
|  | 
 | ||
|  | void File::Write(Atlas& atlas, const std::string& path) { | ||
|  |   hdr = Header::New(); | ||
|  |   hdr.Magic = 0x43523744; | ||
|  |   hdr.Width = atlas.Size.x; | ||
|  |   hdr.Height = atlas.Size.y; | ||
|  |   hdr.DataSize = atlas.Img.size(); | ||
|  |   hdr.TabLen = pCalcTabLen(atlas); | ||
|  |   hdr.Format = 0; | ||
|  |   hdr.NumEntries = atlas.Entries.size(); | ||
|  |   std::ofstream off(path, std::ios::out | std::ios::binary); | ||
|  |   hdr.Write(off); | ||
|  |   pWriteTab(off, atlas); | ||
|  |   off.write(reinterpret_cast<const char*>(atlas.Img.data()), atlas.Img.size()); | ||
|  |   off.close(); | ||
|  | } | ||
|  | 
 | ||
|  | size_t File::pCalcTabLen(Atlas& atlas) { | ||
|  |   size_t ret = 0; | ||
|  |   size_t s_uv = sizeof(PD::Li::Rect); | ||
|  |   size_t s_size = sizeof(PD::u16) * 2; | ||
|  |   for (auto& it : atlas.Entries) { | ||
|  |     ret += s_uv + s_size + sizeof(PD::u8) + it.Name.size(); | ||
|  |   } | ||
|  |   return ret; | ||
|  | } | ||
|  | 
 | ||
|  | void File::pWriteTab(std::ofstream& off, Atlas& atlas) { | ||
|  |   for (auto& it : atlas.Entries) { | ||
|  |     if (it.Name.size() > 255) { | ||
|  |       continue; | ||
|  |     } | ||
|  |     off.write(reinterpret_cast<const char*>(&it.UV), sizeof(it.UV)); | ||
|  |     PD::u16 w = it.Size.x; | ||
|  |     PD::u16 h = it.Size.y; | ||
|  |     off.write(reinterpret_cast<const char*>(&w), sizeof(w)); | ||
|  |     off.write(reinterpret_cast<const char*>(&h), sizeof(h)); | ||
|  |     PD::u32 size = (PD::u32)it.Name.size(); | ||
|  |     off.write(reinterpret_cast<const char*>(&size), sizeof(PD::u32)); | ||
|  |     off.write(it.Name.data(), it.Name.size()); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | void File::Read(Atlas& atlas, const std::string& path) { | ||
|  |   std::ifstream iff(path, std::ios::in | std::ios::binary); | ||
|  |   hdr.Read(iff); | ||
|  |   pReadTab(iff, atlas); | ||
|  |   atlas.Img.resize(hdr.DataSize); | ||
|  |   iff.read(reinterpret_cast<char*>(atlas.Img.data()), hdr.DataSize); | ||
|  |   iff.close(); | ||
|  | } | ||
|  | 
 | ||
|  | void File::pReadTab(std::ifstream& iff, Atlas& atlas) { | ||
|  |   for (PD::u32 i = 0; i < hdr.NumEntries; i++) { | ||
|  |     Atlas::Entry e; | ||
|  |     PD::u16 w = 0, h = 0; | ||
|  |     PD::u32 namelen = 0; | ||
|  |     iff.read(reinterpret_cast<char*>(&e.UV), sizeof(e.UV)); | ||
|  |     iff.read(reinterpret_cast<char*>(&w), sizeof(w)); | ||
|  |     iff.read(reinterpret_cast<char*>(&w), sizeof(h)); | ||
|  |     iff.read(reinterpret_cast<char*>(&namelen), sizeof(PD::u32)); | ||
|  |     e.Name.resize(namelen); | ||
|  |     iff.read(e.Name.data(), namelen); | ||
|  |     e.Size = PD::ivec2(w, h); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | }  // namespace D7RC
 |