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