76 lines
2.8 KiB
C++
76 lines
2.8 KiB
C++
#include "TexDecoder.h"
|
||
#include "ImageReader.h"
|
||
|
||
namespace PKG {
|
||
|
||
// TEX 文件结构:
|
||
// [magic1:NString(16)] "TEXV0005"
|
||
// [magic2:NString(16)] "TEXI0001"
|
||
// [format:int32] TexFormat
|
||
// [flags:int32] TexType 标志位
|
||
// [texW:int32][texH:int32] 纹理尺寸
|
||
// [imgW:int32][imgH:int32] 图像尺寸
|
||
// [unk:uint32]
|
||
// <TexImageContainer> 图像数据(TEXB 块)
|
||
Result<Tex> TexDecoder::Decode(StreamReader& reader) {
|
||
Tex tex{};
|
||
|
||
// 校验魔数
|
||
auto magic1Res = reader.ReadNString(16);
|
||
if (!magic1Res)
|
||
return Fail<Tex>(magic1Res.error.code, magic1Res.error.message);
|
||
tex.Magic1 = *magic1Res;
|
||
if (tex.Magic1 != "TEXV0005")
|
||
return Fail<Tex>(ErrorCode::BadMagic, "Invalid TEX magic1: " + tex.Magic1);
|
||
|
||
auto magic2Res = reader.ReadNString(16);
|
||
if (!magic2Res)
|
||
return Fail<Tex>(magic2Res.error.code, magic2Res.error.message);
|
||
tex.Magic2 = *magic2Res;
|
||
if (tex.Magic2 != "TEXI0001")
|
||
return Fail<Tex>(ErrorCode::BadMagic, "Invalid TEX magic2: " + tex.Magic2);
|
||
|
||
// 读取头部字段
|
||
auto formatRes = reader.ReadInt32();
|
||
if (!formatRes) return Fail<Tex>(formatRes.error.code, formatRes.error.message);
|
||
tex.Header.Format = static_cast<TexFormat>(*formatRes);
|
||
|
||
auto flagsRes = reader.ReadInt32();
|
||
if (!flagsRes) return Fail<Tex>(flagsRes.error.code, flagsRes.error.message);
|
||
tex.Header.Flags = static_cast<TexType>(*flagsRes);
|
||
|
||
auto texWidthRes = reader.ReadInt32();
|
||
if (!texWidthRes) return Fail<Tex>(texWidthRes.error.code, texWidthRes.error.message);
|
||
tex.Header.TextureWidth = *texWidthRes;
|
||
|
||
auto texHeightRes = reader.ReadInt32();
|
||
if (!texHeightRes) return Fail<Tex>(texHeightRes.error.code, texHeightRes.error.message);
|
||
tex.Header.TextureHeight = *texHeightRes;
|
||
|
||
auto imgWidthRes = reader.ReadInt32();
|
||
if (!imgWidthRes) return Fail<Tex>(imgWidthRes.error.code, imgWidthRes.error.message);
|
||
tex.Header.ImageWidth = *imgWidthRes;
|
||
|
||
auto imgHeightRes = reader.ReadInt32();
|
||
if (!imgHeightRes) return Fail<Tex>(imgHeightRes.error.code, imgHeightRes.error.message);
|
||
tex.Header.ImageHeight = *imgHeightRes;
|
||
|
||
auto unkRes = reader.ReadUInt32();
|
||
if (!unkRes) return Fail<Tex>(unkRes.error.code, unkRes.error.message);
|
||
tex.Header.UnkInt0 = *unkRes;
|
||
|
||
// 解析标志位
|
||
tex.IsGif = (static_cast<int>(tex.Header.Flags) & static_cast<int>(TexType::IsGif)) != 0;
|
||
tex.IsVideoTexture = (static_cast<int>(tex.Header.Flags) & static_cast<int>(TexType::IsVideoTexture)) != 0;
|
||
|
||
// 读取图像容器
|
||
auto containerRes = ImageReader::ReadContainer(reader, tex.Header.Format);
|
||
if (!containerRes)
|
||
return Fail<Tex>(containerRes.error.code, containerRes.error.message);
|
||
tex.ImageContainer = *containerRes;
|
||
|
||
return Ok(std::move(tex));
|
||
}
|
||
|
||
} // namespace PKG
|