#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::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; }