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

📄 fstbitmap.cpp

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

#define FST_PIXEL       0x1
#define FST_TRANS_COLOR 0x2
#define FST_LINE_END    0x3
#define FST_END         0x4

// 建立一个FST位图
FST_BMP *create_fst(BMP *bmp)
{
	FST_BMP *fst_bmp;
	fst_bmp = new FST_BMP;
	put_message(fst_bmp == NULL, "错误,没有足够的内存。");
	fst_bmp->width = bmp->width;
	fst_bmp->height = bmp->height;
	fst_bmp->pixelbitcount = bmp->pixelbitcount;
	fst_bmp->colorkey = bmp->colorkey;
	WORD *p_bmp = bmp->bit;
	WORD *temp = new WORD [bmp->width * bmp->height * 2], *p_temp = temp;
	WORD *buffer = new WORD [65535], *p_buffer;
	if (temp == NULL)
	{
		delete fst_bmp;
		put_message(TRUE, "错误,没有足够的内存。");
		return NULL;
	}
	WORD c = 0;
	for (DWORD i = 0; i < bmp->surface_word;)
	{
		c = 0;
		p_buffer = buffer;
		if (*p_bmp == bmp->colorkey)
		{
			// 压缩透明点
			do
			{
				c++;
				i++;
				p_bmp++;
			}while(c < 65535 && i < bmp->surface_word && 
				*p_bmp == bmp->colorkey && i % bmp->width != 0);
			if (i % bmp->width == 0)
				*p_temp++ = FST_LINE_END;
			else
			{
				*p_temp++ = FST_TRANS_COLOR;
				*p_temp++ = c;
			}
			if (i >= bmp->surface_word)
			{
				*p_temp++ = FST_END;
				break;
			}
		}
		else
		{
			// 不透明的点的处理
			do
			{
				c++;
				i++;
				*p_buffer++ = *p_bmp++;
			}while(c < 65535 && i < bmp->surface_word && 
				*p_bmp != bmp->colorkey && i % bmp->width != 0);
			*p_temp++ = FST_PIXEL;
			*p_temp++ = c;
			memcpy(p_temp, buffer, c << 1);
			p_temp += c;
			if (i % bmp->width == 0)
				*p_temp++ = FST_LINE_END;
			if (i >= bmp->surface_word)
			{
				*p_temp++ = FST_END;
				break;
			}
		}
	}
	DWORD size = (p_temp - temp) << 1;
	fst_bmp->bit = new WORD [size >> 1];
	memcpy(fst_bmp->bit, temp, size);
	fst_bmp->surface_byte = size;
	fst_bmp->surface_word = size >> 1;
	fst_bmp->surface_dword = size >> 2;
	delete temp;
	delete buffer;
	return fst_bmp;
}

// 将一个FST位图保存到文件
void write_fst_to_file(FST_BMP *fst, char *filename)
{
	FILE *fp;
	fp = fopen(filename, "wb+");
	put_message(fp == NULL, "错误,建立新文件失败。");
	fwrite(fst, sizeof(FST_BMP), 1, fp);
	fwrite(fst->bit, fst->surface_byte, 1, fp);
	fclose(fp);
}

// 释放FST位图所占的内存空间
void free_fst(FST_BMP **fst)
{
	FST_BMP *f = *fst;
	if (f == NULL)
		return;
	if (f->bit != NULL)
		free(f->bit);
	free(f);
	*fst = NULL;
}

// 复制FST位图到BMP位图
void bitblt_fst(BMP *dest_bmp, int x, int y, FST_BMP *src_fst, int srcx, int srcy, int w, int h)
{
	put_message(dest_bmp == NULL || src_fst == NULL, 
		"错误,企图对不存在的位图进行操作。");
	_asm
	{
#include "clipblit.inc"
	}
	if (w <= 0 || h <= 0)
		return;
	if (w == src_fst->width && h == src_fst->height)
	{
		// 没有需要剪裁的部分
		DWORD offset_w;
		_asm
		{
			PUSH edi;
			PUSH esi;
			MOV ebx, dest_bmp; // 把dest_bmp.bit的地址保存在edi
			MOV edi, [ebx]BMP.bit;
			MOV edx, src_fst; // 把src_bmp.bit的地址保存在edi
			MOV esi, [edx]FST_BMP.bit;

			ADD edi, x;
			ADD edi, x;

			PUSH edx;
			MOV eax, y;
			IMUL [ebx]BMP.pitch_byte;
			ADD edi, eax;
			POP edx;

			MOV eax, [ebx]BMP.width;
			SUB eax, [edx]FST_BMP.width;
			SHL eax, 1;
			MOV offset_w, eax;

			MOV edx, [edx]FST_BMP.width;
			MOV ebx, 0;

_loop_line:
			LODSW;
			CMP ax, FST_PIXEL;
			JZ _pixel; // 不透明点处理
			CMP ax, FST_TRANS_COLOR;
			JZ _trans_color; // 透明点处理
			CMP ax, FST_LINE_END;
			JZ _line_end; // 行结束
			CMP ax, FST_END;
			JZ _bitblt_end; // FST文件结束
			JMP _bitblt_end;

_pixel:
			LODSW;
			MOV ecx, 0;
			MOV cx, ax;
			ADD ebx, ecx;
			REP MOVSW;
			JMP _loop_line;

_trans_color:
			MOV eax, 0;
			LODSW;
			ADD edi, eax;
			ADD edi, eax;
			ADD ebx, eax;
			JMP _loop_line;

_line_end:
			MOV eax, edx;
			SUB eax, ebx;
			SHL eax, 1;
			ADD edi, eax;
			ADD edi, offset_w;
			MOV ebx, 0;
			JMP _loop_line;

_bitblt_end:
			POP esi;
			POP edi;
		}
	}
	else
	{
		// 有需要剪裁的
		int i;
		WORD *p = src_fst->bit, *pbmp = dest_bmp->bit;
		if (srcy > 0)
		{
			// 剪裁上面的
			for (i  = 0; i < srcy; i++)
			{
				while(TRUE)
				{
					if (*p == FST_PIXEL)
					{
						p++;
						p += *p;
						p++;
					}
					else if (*p == FST_TRANS_COLOR)
					{
						p += 2;
					}
					else if (*p = FST_LINE_END)
					{
						p++;
						break;
					}
					else if (*p == FST_END)
						return;
				}
			}
		}
		// 复制FST位图
		pbmp += y * dest_bmp->width;
		if (x >= 0)
			pbmp += x;
		int size = dest_bmp->width - w, ew;
		if (w == src_fst->width)
		{
			// 左右不须要剪裁
			for (i = 0; i < h; i++)
			{
				ew = 0;
				while(TRUE)
				{
					if (*p == FST_PIXEL)
					{
						p++;
						WORD count;
						count = *p;
						p++;
						memcpy(pbmp, p, count * 2);
						p += count;
						pbmp += count;
						ew += count;
					}
					else if (*p == FST_TRANS_COLOR)
					{
						p++;
						pbmp += *p;
						ew += *p;
						p++;
					}
					else if (*p == FST_LINE_END)
					{
						p++;
						if (ew <= w)
						{
							int temp = w - ew;
							pbmp += temp;
						}
						pbmp += size;
						break;
					}
					else if (*p == FST_END)
					{
						return;
					}
				}
			}
		}
		else
		{
			// 左右须要剪裁
			for (i = 0; i < h; i++)
			{
				int left = 0;
				ew = 0;
				while(TRUE)
				{
					if (*p == FST_PIXEL)
					{
						p++;
						WORD count;
						count = *p;
						p++;
						for (int j = 0; j < count; j++)
						{
							if (ew >= srcx)
							{
								if (ew < w)
								{
									*pbmp++ = *p++;
									left++;
								}
								else
									p++;
							}
							else
								p++;
							ew++;
						}
					}
					else if (*p == FST_TRANS_COLOR)
					{
						p++;
						WORD count;
						count = *p;
						p++;
						for (int j = 0; j < count; j++)
						{
							if (ew >= srcx)
							{
								if (ew < w)
								{
									pbmp++;
									left++;
								}
							}
							ew++;
						}
					}
					else if (*p == FST_LINE_END)
					{
						p++;
						if (left <= w)
						{
							int temp = w - left;
							pbmp += temp;
						}
						pbmp += size;
						break;
					}
					else if (*p == FST_END)
					{
						return;
					}
				}
			}
		}
	}
}

// 复制FST位图到BMP位图(Additive方式555)
void additive_fst_565(BMP *dest_bmp, int x, int y, FST_BMP *src_fst, int srcx, int srcy, int w, int h)
{
	put_message(dest_bmp == NULL || src_fst == NULL, 
		"错误,企图对不存在的位图进行操作。");
	_asm
	{
#include "clipblit.inc"
	}
	if (w <= 0 || h <= 0)
		return;
	if (w == src_fst->width && h == src_fst->height)
	{
		// 没有需要剪裁的部分
		DWORD offset_w;
		_asm
		{
			PUSH edi;
			PUSH esi;
			MOV ebx, dest_bmp; // 把dest_bmp.bit的地址保存在edi
			MOV edi, [ebx]BMP.bit;
			MOV edx, src_fst; // 把src_bmp.bit的地址保存在edi
			MOV esi, [edx]FST_BMP.bit;

			ADD edi, x;
			ADD edi, x;

			PUSH edx;
			MOV eax, y;
			IMUL [ebx]BMP.pitch_byte;
			ADD edi, eax;
			POP edx;

			MOV eax, [ebx]BMP.width;
			SUB eax, [edx]FST_BMP.width;
			SHL eax, 1;
			MOV offset_w, eax;

			MOV edx, [edx]FST_BMP.width;
			MOV ebx, 0;

_loop_line:
			LODSW;
			CMP ax, FST_PIXEL;
			JZ _pixel; // 不透明点处理
			CMP ax, FST_TRANS_COLOR;
			JZ _trans_color; // 透明点处理
			CMP ax, FST_LINE_END;
			JZ _line_end; // 行结束
			CMP ax, FST_END;
			JZ _bitblt_end; // FST文件结束
			JMP _bitblt_end;

_pixel:
			LODSW;
			MOV ecx, 0;
			MOV cx, ax;
			ADD ebx, ecx;
			PUSH ebx;
_pixel_loop:
			LODSW;
			MOV bx, [edi];
			AND ax, 0xf7bf;    // 0111 0111 1101 1111
			AND bx, 0xf7bf;
			ADC ax, bx;
			JNC _rnc;
			OR ax, 0xf000;
_rnc:
			TEST ax, 0x20; // 10 0000
			JZ _bnc;
			OR ax, 0x1f;
_bnc:
			TEST ax, 0x800; // 1000 0000 0000
			JZ _gnc;
			OR ax, 0x7e0;   // 111 1110 0000
_gnc:
			STOSW;
			LOOP _pixel_loop;
			POP ebx;
			JMP _loop_line;

_trans_color:
			MOV eax, 0;
			LODSW;
			ADD edi, eax;
			ADD edi, eax;
			ADD ebx, eax;
			JMP _loop_line;

_line_end:
			MOV eax, edx;
			SUB eax, ebx;
			SHL eax, 1;
			ADD edi, eax;
			ADD edi, offset_w;
			MOV ebx, 0;
			JMP _loop_line;

_bitblt_end:
			POP esi;
			POP edi;
		}
	}
	else
	{
		// 有需要剪裁的
		int i;
		WORD *p = src_fst->bit, *pbmp = dest_bmp->bit;
		if (srcy > 0)
		{
			// 剪裁上面的
			for (i  = 0; i < srcy; i++)
			{
				while(TRUE)
				{
					if (*p == FST_PIXEL)
					{
						p++;
						p += *p;
						p++;
					}
					else if (*p == FST_TRANS_COLOR)
					{
						p += 2;
					}
					else if (*p = FST_LINE_END)
					{
						p++;
						break;
					}
					else if (*p == FST_END)
						return;
				}
			}
		}
		// 复制FST位图
		pbmp += y * dest_bmp->width;
		if (x >= 0)
			pbmp += x;
		int size = dest_bmp->width - w, ew;
		if (w == src_fst->width)
		{
			// 左右不须要剪裁
			for (i = 0; i < h; i++)
			{
				ew = 0;
				while(TRUE)
				{
					if (*p == FST_PIXEL)
					{
						p++;
						WORD count;
						count = *p;
						p++;
						_asm
						{
							PUSH edi;
							PUSH esi;
							MOV edi, pbmp;
							MOV esi, p;
							MOV ecx, 0;
							MOV cx, count;
_line_loopf:
							LODSW;
							MOV bx, [edi];
							AND ax, 0xf7bf;    // 0111 0111 1101 1111
							AND bx, 0xf7bf;
							ADC ax, bx;
							JNC _rncf;
							OR ax, 0xf000;
_rncf:
							TEST ax, 0x20; // 10 0000
							JZ _bncf;
							OR ax, 0x1f;
_bncf:
							TEST ax, 0x800; // 1000 0000 0000
							JZ _gncf;
							OR ax, 0x7e0;   // 111 1110 0000
_gncf:
							STOSW;
							LOOP _line_loopf;
							POP esi;
							POP edi;
						}
						p += count;
						pbmp += count;
						ew += count;
					}
					else if (*p == FST_TRANS_COLOR)
					{
						p++;
						pbmp += *p;
						ew += *p;
						p++;
					}
					else if (*p == FST_LINE_END)
					{
						p++;
						if (ew <= w)
						{
							int temp = w - ew;
							pbmp += temp;
						}
						pbmp += size;
						break;
					}
					else if (*p == FST_END)
					{
						return;
					}
				}
			}
		}
		else
		{
			// 左右须要剪裁
			for (i = 0; i < h; i++)
			{
				int left = 0;
				ew = 0;
				while(TRUE)
				{
					if (*p == FST_PIXEL)
					{
						p++;
						WORD count;
						count = *p;
						p++;
						for (int j = 0; j < count; j++)
						{
							if (ew >= srcx)
							{
								if (ew < w)
								{
									_asm
									{
										PUSH edi;
										PUSH esi;
										MOV edi, pbmp;
										MOV esi, p;
										LODSW;
										MOV bx, [edi];
										AND ax, 0xf7bf;    // 0111 0111 1101 1111
										AND bx, 0xf7bf;
										ADC ax, bx;
										JNC _rncc;
										OR ax, 0xf000;
_rncc:
										TEST ax, 0x20; // 10 0000
										JZ _bncc;
										OR ax, 0x1f;
_bncc:
										TEST ax, 0x800; // 1000 0000 0000
										JZ _gncc;
										OR ax, 0x7e0;   // 111 1110 0000
_gncc:
										STOSW;
										POP esi;
										POP edi;
									}
									pbmp++;
									p++;
									left++;
								}
								else
									p++;
							}
							else
								p++;
							ew++;
						}
					}
					else if (*p == FST_TRANS_COLOR)

⌨️ 快捷键说明

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