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

📄 images.cpp

📁 DOS游戏编程中处理Int 13的工具包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// constructor opens the file as binary, readonly. It reads the dac palette
// into the member p_rec structure palette, corrects it for shift, sets sev-
// eral status variables, and closes the file. On error it sets pcx.status to
// Failed, and reports the error in the images module error record imag_err.
// **************************************************************************

pcx::pcx(char *fspec)
	{
	char check_pal;
	int i,j;
	FILE *filptr;

	status = NoErr;

	if ((filptr = fopen(fspec,"rb"))==NULL)
		{
		status = FileOpenErr;
		return;
		}
	if (fseek(filptr,-769L,SEEK_END) != 0)
		{
		status= FileReadErr;
		fclose(filptr);
		return;
		}
	fread(&check_pal,1,1,filptr);

	// check for 256 color PCX palette tag 0x0C at filelength-769

	if (check_pal!=0x0C)
		{
		status = FileFormatErr;
		fclose(filptr);
		return;
		}

	// read in the palette and store in class member data palette

	if (fread(palette,1,768,filptr) != 768)
		{
		status = FileReadErr;
		fclose(filptr);
		return;
		}

	// shift the palette values right by two bits (pcx specific detail)

	for (i=0;i<256;i++)
		{
		for (j=0;j<3;j++)
			{
			palette[i][j]=palette[i][j]>>2;
			}
		}

	// leave the file pointer on the first byte of image data

	if (fseek(filptr,128,SEEK_SET) != 0)
		{
		status = FileReadErr;
		fclose(filptr);
		return;
		}
	fclose(filptr);
	buffer=NULL;                       // pcx:image.buffer
	for (j=0;fspec[j]!=0;j++);         // these two lines copy the path to
	memcpy(fpath,fspec,j+1);           // to storage in the object data
	in_ram = 0;                        // pcx.in_ram
	packed = 0;                        // pcx.packed
	return;
	}

// **************************************************************************
// unpacktoram unpacks the rle encoded into the buffer pointed to by dest.
// No size checking is performed on the buffer. The unpacking process cont-
// inues until num_bytes have been moved to dest. The function checks the
// state of the in_ram member variable. If the image is not in memory it is
// unpacked from the disk file. If the image is in memory in compressed mode
// it is unpacked from memory. If the image is in memory, but is already
// uncompressed the function returns UnknownErr.
// **************************************************************************

char pcx::unpacktoram(char far *dest, unsigned int num_bytes)
	{
	unsigned int bytes=0;           // counts unpacked bytes
	char    c;                      // byte being processed
	int     runlen;                 // length of packet
	unsigned int src_cntr = 0;      // counts through ram buffer if any
	char far *streambuf;
	FILE *filptr;

	if (!in_ram)
		{
		if ((filptr=fopen(fpath,"rb"))==NULL)
			return(FileOpenErr);
		if ((streambuf=new char[5000]) != NULL)
			{
			setbuf(filptr,streambuf);
			}
		if (fseek(filptr,128L,SEEK_SET) != 0)
			{
			fclose(filptr);
			if (streambuf != NULL)
				delete(streambuf);
			return(FileReadErr);
			}
		do
			{
			c=fgetc(filptr);
			if ((c & 0xc0) == 0xc0)
				{
				runlen = (c & 0x3f);
				c=fgetc(filptr);
				while(runlen--) (dest[bytes++]=c);
				}
			else
				dest[bytes++]=c;
			} while (bytes<num_bytes);
		fclose(filptr);
		if (streambuf!=NULL)
			delete(streambuf);
		}
	else
		{
		if (!packed)
			return(UnknownErr);
		else
			{
			do
				{
				c=buffer[src_cntr++];
				if ((c & 0xc0) == 0xc0)
					{
					runlen = (c & 0x3f);
					c=buffer[src_cntr++];
					while(runlen--) (dest[bytes++]=c);
					}
				else
					dest[bytes++]=c;
				} while (bytes<num_bytes);
			}
		}
	return(NoErr);
	}


// **************************************************************************
// the load() member function reads the pcx file into a memory buffer. The
// pointer to the buffer and the buffer size are internal to the class, and
// do not need to be taken into account by the programmer. The data is loaded
// based on the value of method. A set of three constants is defined for this
// value; Packed, Unpacked, and Bestfit. If method = packed the data will be
// read into the memory buffer in compressed PCX format, but the palette and
// header data will be stripped. If method = unpacked the data is uncompress-
// to memory using the unpacktoram() function. In either case, if there is
// not sufficient memory, the function returns MemErr. If method = Bestfit
// the function will unpack the data is possible, or load it packed if not,
// and finally returns MemErr if neither method can be used. If successfull
// the function sets internal switches so that other pcx member functions
// will know that the image data is already loaded, and in what form it has
// been loaded.
// **************************************************************************

char pcx::load(char method)
	{
	unsigned readsize;
	FILE *filptr;

	// make sure the image isn't already loaded

	if (!in_ram)
		{
		if (method == Bestfit)
			{

			// if enough ram for the image load unpacked

			if (coreleft() >= 64000U)
				{
				method = Unpacked;
				}
			else

			// if not enough ram open the file, compare it's size to the
			// available memory, and load it packed if there's enough room
			// or return a MemErr if there isn't.

				{
				if ((filptr=fopen(fpath,"rb"))==NULL)
					{
					return(FileOpenErr);
					}
				readsize = filelength(fileno(filptr))-(128+769);
				fclose(filptr);
				if (coreleft() >= readsize)
					method = Packed;
				else
					return(MemErr);
				}
			}

		// if method = packed then allocate a buffer the size of the image
		// file with the header and palette data stripped out. Zero the
		// buffer, then read the packed data into it. Finally, set in_ram
		// and packed = 1 (pcx class member data used by display() member
		// function)

		if (method == Packed)
			{
			if ((filptr=fopen(fpath,"rb"))==NULL)
				return(FileOpenErr);
			readsize = filelength(fileno(filptr))-(128+769);
			if ((buffer = new char[readsize]) == NULL)
				{
				fclose(filptr);
				return(MemErr);
				}
			_fmemset(buffer,0,readsize);
			if (fseek(filptr, 128L, SEEK_SET) != 0)
				{
				fclose(filptr);
				delete(buffer);
				return(FileReadErr);
				}
			if (fread(buffer, 1, readsize, filptr) != readsize)
				{
				fclose(filptr);
				delete(buffer);
				return(FileReadErr);
				}
			fclose(filptr);
			in_ram = 1;
			packed = 1;
			}
		else

		// if method = Unpacked then allocate a 64000 byte buffer, and
		// unpack the data into it.

			{
			if ((buffer = new char[64000U]) == NULL)
				return(MemErr);
			_fmemset(buffer,0,64000U);
			if(unpacktoram(buffer,64000U) != NoErr)
				{
				delete(buffer);
				in_ram = 0;
				return(SecondaryErr);
				}
			else
				{
				in_ram = 1;
				packed = 0;
				}
			}
		}
	return(NoErr);
	}

// **************************************************************************
// the unload() member function frees the memory allocated to the pcx data,
// and updates the internal switches so that other member functions will
// know that the image is no longer in memory.
// **************************************************************************

void pcx::unload()
	{
	if (in_ram)
		{
		delete(buffer);
		in_ram = 0;
		packed = 0;
		}
	}

// **************************************************************************
// pcx::display can be used to display a PCX class object to screen using
// various fade types, wipes, and dissolves. All fade types other than Soft-
// Fade and SnapWipe require a screen buffer of 64000 bytes. If that memory
// is not available the function returns MemErr. The PCX will be displayed
// whether it is: on disk, in ram packed, or in ram unpacked (in order of
// decreasing execution time).
//
// The following fade types are available:
//
//		SnapWipe           - snaps the pcx to screen, basic block mem move.
//		SplitVerticalWipe  - fades from the top and bottom toward center.
//		SplitHorizWipe     - fades from the right and left toward center.
//      SlideVerticalWipe  - slides pic in from left and right
//      SlideHorizWipe     - slides pic in from top and bottom
//		VerticalDissolve   - overlays multiple vertical slices
//		HorizDissolve      - overlays multiple horizontal slices
//		SparkleDissolve    - fades with random block placement
//		SoftFade           - dac palette intensity fade, 64 passes
// **************************************************************************

char pcx::display(char fadetype)
	{
	char far *do_buffer;
	char loaded_here = 0;

	// SoftFade (palette fade) requires the palette to be cleared.

	if (fadetype == SoftFade)
		{
		wait_vbi();
		clrpalette(0,256);
		}
	else

	// all other types require the new palette to be loaded

		{
		wait_vbi();
		loadpalette(0,256,palette);
		}

	// if the image is not in ram, or is in ram compressed, then it
	// needs to be unpacked, from either disk or memory, to either the
	// video buffer or a memory buffer depending on the fade type.

	if ((!in_ram) || ((in_ram) && (packed)))
		{

		// these two fade types simply require the data unpacked to vseg.

		if ((fadetype == SoftFade) || (fadetype == SnapWipe))
			{
			if (unpacktoram((char far *)MK_FP(0xa000,0), 64000U) != NoErr)
				return(SecondaryErr);
			}
		else

		// all the others require the data in a 64K memory buffer
		// so one is allocated, and the data is unpacked to it

			{
			if ((do_buffer = new char[64100U]) == NULL)
				return(MemErr);
			if (unpacktoram(do_buffer, 64000U) != NoErr)
				{
				delete(do_buffer);
				return(SecondaryErr);
				}
			loaded_here = 1;
			}
		}
	else

	// if the data is in ram uncompressed it's ready to go. The only
	// action necessary is to copy it to the video buffer for the two
	// simple fade types. The buffer identifier is member data of the
	// image class, and stores a pointer to the image buffer. In both
	// cases do_buffer is assigned the value of buffer, and then the
	// operations are performed on it. This simplifies the calls to
	// the fade functions below.

		{
		do_buffer = buffer;

		// for these two fade types copy the data over to vseg

		if ((fadetype == SoftFade) || (fadetype == SnapWipe))
			{
			wait_vbi();
			asm {
				push es
				push ds
				push cx
				push si
				push di
				mov es, GRAPH_SEG
				xor di, di
				lds si, do_buffer
				mov cx, 32000
				rep movsw
				pop di
				pop si
				pop cx
				pop ds
				pop es
				}
			}
		}
	switch (fadetype)
		{
		case SoftFade:           fadepalettein(0,256,palette); break;
		case SplitVerticalWipe:  doSplitVerticalWipe(do_buffer); break;
		case SplitHorizWipe:     doSplitHorizWipe(do_buffer); break;
		case SlideVerticalWipe:  doSlideVerticalWipe(do_buffer); break;
		case SlideHorizWipe:     doSlideHorizWipe(do_buffer); break;
		case VerticalDissolve:   doVerticalDissolve(do_buffer); break;
		case HorizDissolve:      doHorizDissolve(do_buffer); break;
		case SparkleDissolve:    doSparkleDissolve(do_buffer); break;
		}
	if (loaded_here)
		delete(do_buffer);
	return(NoErr);
	}

// **************************************************************************
// remove() clears the current image from the screen using the passed fade
// type. It will clear the screen regardless of what image is on it. No
// checking is performed 

⌨️ 快捷键说明

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