⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pack.cpp

📁 vc写的源程序,是关于游戏类的程序。调用了系统的很多API
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "graphics.h"

DATA_FILE *data_file = NULL;

// 建立一个数据文件
void create_data_file(char *filename)
{
	close_data_file();
	data_file = new DATA_FILE;
	data_file->fp = fopen(filename, "wb+");
	put_message(data_file->fp == NULL, "错误,建立新数据文件失败。");
	data_file->file_count = 0;
	fwrite(&data_file->file_count, sizeof(DWORD), 1, data_file->fp);
	data_file->pack_file_list = create_list();
}

// 打开一个数据文件
void open_data_file(char *filename)
{
	close_data_file();
	data_file = new DATA_FILE;
	data_file->fp = fopen(filename, "rb");
	put_message(data_file->fp == NULL, "错误,打开数据文件失败。");
	fread(&data_file->file_count, sizeof(DWORD), 1, data_file->fp);
	data_file->pack_file_list = create_list();
	PACK_FILE *temp;
	// 装入数据文件列表
	for (DWORD i = 0; i < data_file->file_count; i++)
	{
		temp = new PACK_FILE;
		fread(&temp->ID, sizeof(DWORD), 1, data_file->fp);
		fread(&temp->pos, sizeof(DWORD), 1, data_file->fp);
		fread(temp->filename, 64, 1, data_file->fp);
		fread(&temp->oldsize, sizeof(DWORD), 1, data_file->fp);
		fread(&temp->filesize, sizeof(DWORD), 1, data_file->fp);
		fread(&temp->compress, sizeof(BOOL), 1, data_file->fp);
		add_point(data_file->pack_file_list, temp);
		fseek(data_file->fp, temp->filesize, SEEK_CUR);
	}
}

/* * * * * * * * * * * *
 * 添加文件到数据文件  *
 * 音乐文件不要压缩    *
 * * * * * * * * * * * */
void add_file(char *filename, DWORD ID, BOOL comp)
{
	put_message(data_file == NULL, "错误,当前没有打开数据文件。");
	FILE *fp;
	PACK_FILE *pf = new PACK_FILE;
	put_message(pf == NULL, "错误,没有足够的内存。");
	fp = fopen(filename, "rb");
	put_message(fp == NULL, "错误,打开文件%s失败", filename);
	fseek(data_file->fp, 0, SEEK_END);
	fseek(fp, 0, SEEK_END);
	DWORD pos = ftell(data_file->fp);
	DWORD size = ftell(fp);
	fseek(data_file->fp, 0, SEEK_SET);
	fseek(fp, 0, SEEK_SET);
	data_file->file_count++;
	fwrite(&data_file->file_count, sizeof(DWORD), 1, data_file->fp);
	fseek(data_file->fp, 0, SEEK_END);
	pos += sizeof(PACK_FILE);
	pf->ID = ID;
	pf->pos = pos;
	strcpy(pf->filename, filename);
	char *buffer = new char [size];
	put_message(buffer == NULL, "错误,没有足够的内存。");
	fread(buffer, size, 1, fp);
	pf->oldsize = size;
	pf->filesize = size;
	if (!comp)
	{
		pf->compress = FALSE;
		fwrite(&pf->ID, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->pos, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->filename, 64, 1, data_file->fp);
		fwrite(&pf->oldsize, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->filesize, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->compress, sizeof(BOOL), 1, data_file->fp);
		fwrite(buffer, pf->filesize, 1, data_file->fp);
		delete buffer;
	}
	else
	{
		char *cbuffer = new char [pf->filesize];
		pf->filesize = compress(buffer, pf->filesize, cbuffer);
		pf->compress = TRUE;
		fwrite(&pf->ID, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->pos, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->filename, 64, 1, data_file->fp);
		fwrite(&pf->oldsize, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->filesize, sizeof(DWORD), 1, data_file->fp);
		fwrite(&pf->compress, sizeof(BOOL), 1, data_file->fp);
		fwrite(cbuffer, pf->filesize, 1, data_file->fp);
		delete buffer;
		delete cbuffer;
	}
	add_point(data_file->pack_file_list, pf);
	fclose(fp);
}

// 关闭数据文件
void close_data_file()
{
	if (data_file != NULL)
	{
		free_list(&data_file->pack_file_list);
		fclose(data_file->fp);
	}
}

// 只有数据包内的子文件才可以在压缩状态打开
// 读入一个标准WindowsBMP(8位色 或 24位色)
BMP *load_pack_win_bitmap(char *filename)
{
	BOOL find_ok = FALSE;
	seek_to_first(data_file->pack_file_list);
	PACK_FILE *pf;
	for (DWORD c = 0; c < data_file->file_count; c++)
	{
		pf = (PACK_FILE *)get_data(data_file->pack_file_list);
		if (strcmp(pf->filename, filename) == 0)
		{
			find_ok = TRUE;
			break;
		}
		seek_to_next(data_file->pack_file_list);
	}
	if (!find_ok)
		return NULL;

	fseek(data_file->fp, pf->pos, SEEK_SET);
	BMP *bmp;

	if (!pf->compress)
	{
		// 处理没有压缩的
		BITMAPFILEHEADER bmpheader; // 取BMP文件头信息
		if (fread(&bmpheader, sizeof(bmpheader), 1, data_file->fp) == NULL)
		{
			fclose(data_file->fp);
			put_message(TRUE, 
				"错误,读取文件头失败。");
		}
		if (bmpheader.bfType != 19778)
		{
			fclose(data_file->fp);
			put_message(TRUE, 
				"错误,不是标准Windows BMP文件。");
		}
		BITMAPINFOHEADER bmpinfo;// 取BMP文件信息
		if (fread(&bmpinfo, sizeof(bmpinfo), 1, data_file->fp) == NULL)
		{
			fclose(data_file->fp);
			put_message(TRUE, 
				"错误,读取图象信息失败。");
		}
		if ((bmpinfo.biCompression != BI_RGB) || ((bmpinfo.biBitCount!=8)&&(bmpinfo.biBitCount != 24)))
		{
			fclose(data_file->fp);      // 是否未压缩且为8 or 24位色
			put_message(TRUE, 
				"错误,这个Windows BMP是已压缩的。");
		}
		bmp = new BMP;
		put_message(bmp == NULL, "错误,没有足够的内存。");
		bmp->height        = bmpinfo.biHeight ;
		bmp->width         = bmpinfo.biWidth  ;
		bmp->cliptop       = bmp->clipleft = 0;
		bmp->clipright     = bmp->width - 1;
		bmp->clipbottom    = bmp->height - 1;
		bmp->pitch_byte    = WORD(bmp->width << 1);
		bmp->pitch_word    = bmp->width;
		bmp->pitch_dword   = bmp->width / 2;
		bmp->surface_byte  = bmp->pitch_byte  * bmp->height;
		bmp->surface_word  = bmp->pitch_word  * bmp->height;
		bmp->surface_dword = bmp->pitch_dword * bmp->height;
		bmp->colorkey      = 0x0;
		bmp->bit = new WORD [bmp->surface_word];
		if (Is555)
			bmp->pixelbitcount = 15;
		else
			bmp->pixelbitcount = 16;
		put_message(bmp->bit == NULL, "错误,没有足够的内存。");
		if (bmpinfo.biBitCount == 8) // 8位色的处理
		{
			RGBQUAD *quad;
			quad = new RGBQUAD[256];
			if (quad == NULL)
			{
				fclose(data_file->fp);
				put_message(TRUE, 
					"错误,没有足够的内存。");
				return NULL;
			}
			WORD *pal;
			pal = new WORD[256];
			if (pal == NULL)
			{
				delete quad;
				fclose(data_file->fp);
				put_message(TRUE, 
					"错误,没有足够的内存。");
				return NULL;
			}
			fread(quad, sizeof(RGBQUAD) * 256, 1, data_file->fp);
			DWORD c;
			for (int i = 0; i < 256; i++) // 调色板
			{
				c = ((((DWORD)quad[i].rgbRed) << 16) | (((DWORD)quad[i].rgbGreen) << 8) | ((DWORD)quad[i].rgbBlue));
				pal[i] = true_to_hi(c);
			}
			for (int ii = 0; ii < 256; ii++)
				pal[ii] = true_to_hi(*((DWORD *)(quad + ii)));
			WORD* Offset = bmp->bit;
			DWORD linesize;
			BYTE* buffer;
			linesize = (bmpinfo.biWidth + 3) & 0xfffffffc;
			buffer = (BYTE *)malloc(linesize);
			
			for (i = bmpinfo.biHeight - 1; i >= 0; i--)
			{
				Offset = bmp->bit + i * bmpinfo.biWidth ;
				fread(buffer, linesize, 1, data_file->fp);
				for (int j = 0; j < bmpinfo.biWidth; j++)
					Offset[j] = pal[buffer[j]];
			}
			delete buffer;
			Offset = NULL;
			delete pal;
			delete quad;
			return bmp;
		}
		// 24位色处理
		int linesize = (bmpinfo.biWidth * 3 + 3) & 0xfffffffc;
		BYTE *Buffer;
		Buffer = new BYTE[linesize];
		if (Buffer == NULL)
		{
			fclose(data_file->fp);
			put_message(TRUE, 
				"错误,没有足够的内存。");
			return NULL;
		}
		WORD *Offset;
		for (int i = bmpinfo.biHeight - 1; i >= 0; i--)
		{
			fread(Buffer, linesize, 1, data_file->fp);
			Offset = bmp->bit + i * bmpinfo.biWidth; 
			for (int j = 0; j < bmpinfo.biWidth; j++)
				Offset[j] = true_to_hi((*(DWORD *)(Buffer + j * 3)));
		}
		delete Buffer;
		Offset = NULL;
		return bmp;
	}
	else
	{
		// 处理压缩过的
		BITMAPFILEHEADER bmpheader; // 取BMP文件头信息
		char *filebuffer, *cbuffer, *pbuffer;
		cbuffer = new char [pf->filesize];
		put_message(cbuffer == NULL, "错误,没有足够的内存空间。");
		fread(cbuffer, pf->filesize, 1, data_file->fp);
		filebuffer = new char [pf->oldsize];
		put_message(filebuffer == NULL, "错误,没有足够的内存空间。");
		decompress(cbuffer, pf->filesize, filebuffer);
		delete cbuffer;
		pbuffer = filebuffer;

		memcpy(&bmpheader, pbuffer, sizeof(bmpheader));
		pbuffer += sizeof(bmpheader);
		if (bmpheader.bfType != 19778)
		{
			delete filebuffer;
			fclose(data_file->fp);
			put_message(TRUE, 
				"错误,不是标准Windows BMP文件。");
		}
		BITMAPINFOHEADER bmpinfo;// 取BMP文件信息
		memcpy(&bmpinfo, pbuffer, sizeof(bmpinfo));
		pbuffer += sizeof(bmpinfo);
		if ((bmpinfo.biCompression != BI_RGB) || ((bmpinfo.biBitCount!=8)&&(bmpinfo.biBitCount != 24)))
		{
			delete filebuffer;
			fclose(data_file->fp);      // 是否未压缩且为8 or 24位色
			put_message(TRUE, 
				"错误,这个Windows BMP是已压缩的。");
		}
		bmp = new BMP;
		put_message(bmp == NULL, "错误,没有足够的内存。");
		bmp->height        = bmpinfo.biHeight ;
		bmp->width         = bmpinfo.biWidth  ;
		bmp->cliptop       = bmp->clipleft = 0;
		bmp->clipright     = bmp->width - 1;
		bmp->clipbottom    = bmp->height - 1;
		bmp->pitch_byte    = WORD(bmp->width << 1);
		bmp->pitch_word    = bmp->width;
		bmp->pitch_dword   = bmp->width / 2;
		bmp->surface_byte  = bmp->pitch_byte  * bmp->height;
		bmp->surface_word  = bmp->pitch_word  * bmp->height;
		bmp->surface_dword = bmp->pitch_dword * bmp->height;
		bmp->colorkey      = 0x0;
		bmp->bit = new WORD [bmp->surface_word];
		if (Is555)
			bmp->pixelbitcount = 15;
		else
			bmp->pixelbitcount = 16;
		put_message(bmp->bit == NULL, "错误,没有足够的内存。");
		if (bmpinfo.biBitCount == 8) // 8位色的处理
		{
			RGBQUAD *quad;
			quad = new RGBQUAD[256];
			if (quad == NULL)
			{
				delete bmp;
				delete filebuffer;
				fclose(data_file->fp);
				put_message(TRUE, 
					"错误,没有足够的内存。");
				return NULL;
			}
			WORD *pal;
			pal = new WORD[256];
			if (pal == NULL)
			{
				delete bmp;
				delete filebuffer;
				delete quad;
				fclose(data_file->fp);
				put_message(TRUE, 
					"错误,没有足够的内存。");
				return NULL;
			}
			memcpy(quad, pbuffer, sizeof(RGBQUAD) * 256);
			pbuffer += sizeof(RGBQUAD) * 256;
			DWORD c;
			for (int i = 0; i < 256; i++) // 调色板
			{
				c = ((((DWORD)quad[i].rgbRed) << 16) | (((DWORD)quad[i].rgbGreen) << 8) | ((DWORD)quad[i].rgbBlue));
				pal[i] = true_to_hi(c);
			}
			for (int ii = 0; ii < 256; ii++)
				pal[ii] = true_to_hi(*((DWORD *)(quad + ii)));
			WORD* Offset = bmp->bit;
			DWORD linesize;
			BYTE* buffer;
			linesize = (bmpinfo.biWidth + 3) & 0xfffffffc;
			buffer = (BYTE *)malloc(linesize);
			
			for (i = bmpinfo.biHeight - 1; i >= 0; i--)
			{
				Offset = bmp->bit + i * bmpinfo.biWidth ;
				memcpy(buffer, pbuffer, linesize);
				pbuffer += linesize;
				for (int j = 0; j < bmpinfo.biWidth; j++)
					Offset[j] = pal[buffer[j]];
			}
			delete filebuffer;
			delete buffer;
			Offset = NULL;
			delete pal;
			delete quad;
			return bmp;
		}
		// 24位色处理
		int linesize = (bmpinfo.biWidth * 3 + 3) & 0xfffffffc;
		BYTE *Buffer;
		Buffer = new BYTE[linesize];
		if (Buffer == NULL)
		{
			delete filebuffer;
			delete bmp;
			fclose(data_file->fp);
			put_message(TRUE, 
				"错误,没有足够的内存。");
			return NULL;
		}
		WORD *Offset;
		for (int i = bmpinfo.biHeight - 1; i >= 0; i--)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -