SwitchGame/source/EngineCore/Asset_ImagePack.cpp

247 lines
8.0 KiB
C++

#include "Asset_ImagePack.h"
Asset_ImagePack::Asset_ImagePack()
{
}
Asset_ImagePack::~Asset_ImagePack()
{
}
void Asset_ImagePack::Init()
{
DIR *dir;
struct dirent *ent;
std::string path = "ImagePacks2/";
dir = opendir(path.c_str());
while ((ent = readdir(dir)))
{
// 跳过.和..目录
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
continue;
std::string RealPath = path + ent->d_name;
Ifstream_NPK Fs;
Fs.open(RealPath.c_str(), std::ios::in | std::ios::binary);
if (Fs.is_open())
{
std::string Header = Fs.ReadString();
// 如果是NPK
if (Header.find("NeoplePack_Bill") != std::string::npos)
{
// 读取img数量
int ImageCount = Fs.ReadInt();
// 读取头
NpkInfo *ImgList = new NpkInfo[ImageCount];
for (int i = 0; i < ImageCount; i++)
{
ImgList[i].Offset = Fs.ReadInt();
ImgList[i].Length = Fs.ReadInt();
ImgList[i].Path = Fs.ReadInfo();
}
for (int i = 0; i < ImageCount; i++)
{
IMG img;
img.imgOffset = ImgList[i].Offset;
img.imgSize = ImgList[i].Length;
img.img_index = i;
img.lpBelongsFile = ent->d_name;
img.lpImgName = ImgList[i].Path;
img.lp_lplist = NULL;
img.png_sum = 0;
map_npk.insert(make_pair(img.lpImgName, img));
}
// 销毁
delete[] ImgList;
}
}
Fs.close();
}
closedir(dir);
}
void Asset_ImagePack::ParseColor(BYTE *Tab, int Type, BYTE *SaveByte, int Offset)
{
BYTE a = 0;
BYTE r = 0;
BYTE g = 0;
BYTE b = 0;
switch (Type)
{
case 0x0e:
a = (BYTE)(Tab[1] >> 7);
r = (BYTE)((Tab[1] >> 2) & 0x1f);
g = (BYTE)((Tab[0] >> 5) | ((Tab[1] & 3) << 3));
b = (BYTE)(Tab[0] & 0x1f);
a = (BYTE)(a * 0xff);
r = (BYTE)((r << 3) | (r >> 2));
g = (BYTE)((g << 3) | (g >> 2));
b = (BYTE)((b << 3) | (b >> 2));
break;
case 0x0f:
a = (BYTE)(Tab[1] & 0xf0);
r = (BYTE)((Tab[1] & 0xf) << 4);
g = (BYTE)(Tab[0] & 0xf0);
b = (BYTE)((Tab[0] & 0xf) << 4);
break;
}
SaveByte[Offset + 0] = b;
SaveByte[Offset + 1] = g;
SaveByte[Offset + 2] = r;
SaveByte[Offset + 3] = a;
}
void Asset_ImagePack::LoadImgToMem(IMG *p)
{
std::string Path = "ImagePacks2/" + p->lpBelongsFile;
// SDL_Log("LoadImgToMem : %s", Path.c_str());
Ifstream_NPK Fs;
Fs.open(Path.c_str(), std::ios::in | std::ios::binary);
if (Fs.is_open())
{
Fs.seekg(p->imgOffset);
std::string Flag = Fs.ReadString(); // 读取Flag
if (Flag.find("Neople Img File") != std::string::npos)
{
// 索引表大小
long TableLength = Fs.ReadLong();
// img 版本 4字节
Fs.ReadInt(); // 读取版本
// img 帧数
int IndexCount = Fs.ReadInt();
// 图片数量赋值
p->png_sum = IndexCount;
// new出 Png数量的 结构体
ImgInfo *PngList = new ImgInfo[IndexCount];
for (int i = 0; i < IndexCount; i++)
{
PngList[i].Type = Fs.ReadInt();
if (PngList[i].Type == 17)
{
// 引用贴图
int frbuf = Fs.ReadInt();
// 压缩类型 用来临时存一下引用编号
PngList[i].CmpType = frbuf;
////大小
PngList[i].Size = 0;
PngList[i].Offset = PngList[i - 1].Offset + PngList[i - 1].Size;
continue;
}
// 压缩类型
PngList[i].CmpType = Fs.ReadInt();
// 宽度
PngList[i].Width = Fs.ReadInt();
// 高度
PngList[i].Height = Fs.ReadInt();
// 大小
PngList[i].Size = Fs.ReadInt();
// Xpos
PngList[i].Xpos = Fs.ReadInt();
// Ypos
PngList[i].Ypos = Fs.ReadInt();
// 帧域X
PngList[i].FrameXpos = Fs.ReadInt();
// 帧域Y
PngList[i].FrameYpos = Fs.ReadInt();
// 计算偏移
if (i == 0)
PngList[i].Offset = 0 + p->imgOffset + TableLength + 32;
else
PngList[i].Offset = PngList[i - 1].Offset + PngList[i - 1].Size;
}
for (int i = 0; i < IndexCount; i++)
{
// 引用
if (PngList[i].Type == 17)
{
// 引用编号
int YYIndex = PngList[i].CmpType;
int sizebuf = PngList[YYIndex].Width * PngList[YYIndex].Height * 4;
BYTE *bByte = new BYTE[sizebuf];
memcpy(bByte, PngList[PngList[i].CmpType].PNGdata, sizebuf);
PngList[i].PNGdata = PngList[YYIndex].PNGdata;
// 压缩类型 用来临时存一下引用编号
PngList[i].CmpType = PngList[YYIndex].CmpType;
// 宽度
PngList[i].Width = PngList[YYIndex].Width;
// 高度
PngList[i].Height = PngList[YYIndex].Height;
// 大小
PngList[i].Size = 0;
// Xpos
PngList[i].Xpos = PngList[YYIndex].Xpos;
// Ypos
PngList[i].Ypos = PngList[YYIndex].Ypos;
// 帧域X
PngList[i].FrameXpos = PngList[YYIndex].FrameXpos;
// 帧域Y
PngList[i].FrameYpos = PngList[YYIndex].FrameYpos;
continue;
}
Fs.seekg(PngList[i].Offset);
BYTE *PngData = Fs.ReadCustomSize(PngList[i].Size);
int DeSize = PngList[i].Width * PngList[i].Height * 4;
BYTE *bByte = new BYTE[DeSize];
unsigned long RealSize = DeSize;
uncompress(bByte, &RealSize, PngData, (unsigned long)PngList[i].Size);
delete[] PngData;
if (PngList[i].Type != 16)
{
int PngByteSize = DeSize * 2;
PngList[i].PNGdata = new BYTE[PngByteSize];
for (int e = 0; e < PngByteSize; e += 4)
{
BYTE NeedData[2];
memset(NeedData, 0, 2);
memcpy(NeedData, bByte + (e / 4) * 2, 2);
ParseColor(NeedData, PngList[i].Type, PngList[i].PNGdata, e);
}
delete[] bByte;
}
else
{
PngList[i].PNGdata = bByte;
}
}
p->lp_lplist = PngList;
}
else if (Flag.find("Neople Image File") != std::string::npos)
{
// LoadImgToMem2(p);
}
Fs.close();
}
}
Asset_ImagePack::IMG *Asset_ImagePack::GetIMG(std::string imgName)
{
IMG *img = NULL;
std::map<std::string, IMG>::iterator itr;
itr = map_npk.find(imgName);
if (itr == map_npk.end())
{
std::string mes = "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!调用了不存在的Img : " + imgName;
SDL_Log(mes.c_str());
img = &map_npk["sprite/interface/base.img"];
}
else
{
img = &itr->second;
}
// 如果图片数组不存在 或者 图片数据不存在都要重读
if (!img->lp_lplist)
{
LoadImgToMem(img);
}
img->UseTime = SDL_GetTicks();
return img;
}