247 lines
8.0 KiB
C++
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;
|
|
}
|