2025-10-24 09:15:00 +02:00
|
|
|
/*
|
|
|
|
|
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);
|
2025-10-25 17:37:04 +02:00
|
|
|
atlas.Size = PD::ivec2(hdr.Width, hdr.Height);
|
2025-10-24 09:15:00 +02:00
|
|
|
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));
|
2025-10-25 17:37:04 +02:00
|
|
|
iff.read(reinterpret_cast<char*>(&h), sizeof(h));
|
2025-10-24 09:15:00 +02:00
|
|
|
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);
|
2025-10-25 17:37:04 +02:00
|
|
|
atlas.Entries.push_back(e);
|
2025-10-24 09:15:00 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace D7RC
|