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

📄 cgraph.h

📁 A 2D game engine for C++ and an example : Aero Blasters
💻 H
字号:
#include <conio.h>
#include <stdio.h>

#define Getmaxx 319
#define Getmaxy 199

#define MAX_X 319
#define MAX_Y 199

#define PALETTE_INDEX       0x03c8
//---defines---
#define     vga256        0x13      // 320  x 200 x 256
#define     text          0x03      // Text mode

#define     ROM_CHAR_SET_SEG 0xF000
#define     ROM_CHAR_SET_OFF 0xFA6E

#define     SCREEN_WIDTH   (unsigned int)320
#define     SCREEN_HEIGHT  (unsigned int)200
#define     CHAR_WIDTH   (unsigned int)8
#define     CHAR_HEIGHT  (unsigned int)8


	#define PALETTE_MASK			0x3c6
	#define PALETTE_REGISTER_RD		0x3c7
	#define PALETTE_REGISTER_WR		0x3c8
	#define PALETTE_DATA			0x3c9


		   ///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
// G L O B A L S //////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

unsigned char far *double_buffer = NULL;
unsigned int 	   buffer_height = SCREEN_HEIGHT;
unsigned int       buffer_size = SCREEN_WIDTH*SCREEN_HEIGHT;

/////////////////////////////////////////////////////////////////////////////
// F U N C T I O N  P R O T O T Y P E S /////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////


	  ////////// structures
   typedef struct RGB_color_typ
	      {

	      unsigned char red;
	      unsigned char green;
	      unsigned char blue;

	      }RGB_color, *RGB_color_ptr;



// These are the pointers to hold the addresses

	 unsigned char far *video_buffer = (char far *)0xA0000000L;
	 unsigned char far *rom_char_set = (char far *)0xF000FA6EL;



    class cgraphics
     {
       private:
       // no assignments

       public:
       void plot_pixel_db ( int x, int y, unsigned char color );

	//////////////////////// game programming
void cgraphics::plot_circle_db (int xc, int yc, int r, char color);
void cgraphics::wait(int clicks);
int  cgraphics::create_double_buffer(void);
void cgraphics::show_double_buffer (void);
void cgraphics::delete_double_buffer(void);
void cgraphics::HLine(int x,int y,int color,int length,int thickness);
void cgraphics::VLine(int x,int y,int color,int length,int thickness);
     };

      /////////////FUNCTION DECLARATIONS
void cgraphics::plot_pixel_db ( int x, int y, unsigned char color )
	{
	double_buffer [((y<<8) + (y<<6)) + x] = color;
	}
void cgraphics::plot_circle_db (int xc, int yc, int r, char color)
{
      int x = 0, y = r, d = 2 * (1 - r);

      while(y > 0)
      {
	    plot_pixel_db(xc + x, yc + y, color);
	    plot_pixel_db(xc + x, yc - y, color);
	    plot_pixel_db(xc - x, yc + y, color);
	    plot_pixel_db(xc - x, yc - y, color);
	    if(d + y > 0)
	    {
		  y -= 1;
		  d -= (2 * y * SCREEN_WIDTH / SCREEN_HEIGHT) - 1;
	    }
	    if(x > d)
	    {
		  x += 1;
		  d += (2 * x) + 1;
	    }
      }
}

/* draws random plotlines and plotcircles until a key is pressed in mode 13h */
/* (draws in colors 0 - 63 only) */

void cgraphics::wait(int clicks)
{
// this function uses the internal timekeeper (the one that runs
// at 18.2 clicks/sec to time a delay).

unsigned char far *clock = (char far *)0x0000046CL;

unsigned int now;

// get the current time

now = *clock;

// wait until the time has gone past the cuurent time plus the
// amount we wanted to wait. Note that each tick is
// approximately 55 millisecond.

while (abs(*clock - now) < clicks) {}



} // end delay   */
///////////////////////////////////////////////////////////////////////////

int cgraphics::create_double_buffer(void)
{

	if ((double_buffer = (unsigned char far *)
	farmalloc (SCREEN_WIDTH * (SCREEN_HEIGHT+1)))==NULL)
	return(0);
	_fmemset(double_buffer, 0, SCREEN_WIDTH * SCREEN_HEIGHT);

	return(1);
}


///////////////////////////////////////////////////////////////////////////

 void cgraphics::show_double_buffer (void)
 {

 _fmemcpy(&video_buffer[0],
 &double_buffer[0],
 SCREEN_WIDTH*SCREEN_HEIGHT);

 }

///////////////////////////////////////////////////////////////////////////

void cgraphics::delete_double_buffer(void)
{

	if (double_buffer)
	  farfree(double_buffer);

}

	 // end class
// system


////////////////// 	inline assembly functions
///////////////////////////////////////////////////////////////////////////

void cgraphics::HLine(int x,int y,int color,int length,int thickness)
    {
    int offset = (y<<6)+(y<<8)+x;
    int i;

    for  (i=0; i<=thickness ; i++)
    {
    memset(double_buffer+offset,color,length);
    offset+=SCREEN_WIDTH;
    }
    }

void cgraphics::VLine(int x,int y,int color,int length,int thickness)
    {
    int offset = (y<<6)+(y<<8)+x;
    int i;

    for  (i=0; i<=length ; i++)
    {
    memset(double_buffer+offset,color,thickness);
    offset+=SCREEN_WIDTH;
    }
    }

///////////////////////////////////////////////////////////////////////////

void waitretrace(void)
{

  _DX = 0x03DA;

  l1: asm{
	in  al,dx;
	and al,0x08;
	jnz l1;
      }

  l2: asm{
	in  al,dx;
	and al,0x08;
	jz  l2;
      }
}



void show_double_buffer(void)
{
// this function copies the double buffer into the video buffer

	_asm{
	     push ds			;
	     mov cx,buffer_size	        ;
	     les di,video_buffer        ;
	     lds si,double_buffer       ;

	     cld                        ;
	     rep movsb                  ;
	     pop ds                     ;
	     }
}// end


void set_palette_register( int index, RGB_color_ptr color )
{
	///	      	sets the palette
	///		tell the vga card to update the palette
	outp (PALETTE_MASK, 0xff);
	//		tell the vga card the number
	outp (PALETTE_REGISTER_WR ,index);
	// 		update the rbg
	outp(PALETTE_DATA , color-> red   );
	outp(PALETTE_DATA , color-> green );
	outp(PALETTE_DATA , color-> blue  );
	//  		palette set
}


void get_palette_register( int index, RGB_color_ptr color )
{
	///	      	sets the palette
	///		tell the vga card to update the palette
	outp (PALETTE_MASK, 0xff);
	//		tell the vga card the number
	outp (PALETTE_REGISTER_RD ,index);
	// 		update the rbg
	color-> red   = inp(PALETTE_DATA);
	color-> green = inp(PALETTE_DATA);
	color-> blue  = inp(PALETTE_DATA);
	//  		palette set
}

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
RGB_color SystemPalette[256];

    void GetSystemPalette (void)
     {
       for (int index=0;index<256;index++)
		{
		//get the color to fade
	get_palette_register(index,(RGB_color_ptr)&SystemPalette[index]);
		}

     }

     void SetSystemPalette (void)
     {
       for (int index=0;index<256;index++)
		{
		//get the color to fade
	set_palette_register(index,(RGB_color_ptr)&SystemPalette[index]);
		}

     }
/////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
void set_double_buffer(int color)
       {
   memset(double_buffer,color,SCREEN_WIDTH * (SCREEN_HEIGHT));
       }




void set_video_mode ( int mode )
	{
	 union REGS regs_in , regs_out;
	 regs_in.h.ah = 0;
	 regs_in.h.al = (unsigned char)mode;
	 int86 ( 0x10, &regs_in, &regs_out );
	}

void blit_char_db (int xc,int yc,char c,int color,int trans_flag)
{

//this uses the rom char set to blit a character.
//Bits r extracted out of each character byte 2 represent char

	int offset, x, y;
	char far *work_char;
	unsigned char bit_mask=0x80; //starting offset in ROM table

	work_char = rom_char_set + c * CHAR_HEIGHT;
	//COMPUTE THe offset of the video buffer
	offset=(yc<<8)+(yc<<6)+xc;
	for (y=0;y<CHAR_HEIGHT;y++)
	{
	//reset bit mask
		bit_mask=0x80;
		for(x=0;x<CHAR_WIDTH;x++)
		{
			//test for transparent pixel 0 else draw
			if ((*work_char & bit_mask))
			double_buffer[offset+x]=color;
			else if (!trans_flag)
			double_buffer[offset+x]=0;
			//takes care of transparency
			//shift bit mask
			bit_mask= (bit_mask >> 1);
		}//end for
	//move to next line
	offset+=SCREEN_WIDTH;
	work_char++;
	}//end for y
}//end blit char

void  write(int x,int y,int color,char *string,int trans_flag)
{
//the function blits a string using blit char
	int index;
	for (index=0;string[index]!=0;index++)
	{
	blit_char_db(x+(index<<3),y,string[index],color,trans_flag);
	}//end for
}//end blit strring

void plot_pixel_db ( int x, int y, unsigned char color )
	{
	double_buffer [((y<<8) + (y<<6)) + x] = color;
	}


void putpixel( int x, int y, unsigned char color )
	{
	if ((x>0) && (y>0) && (x<SCREEN_WIDTH) && (y<SCREEN_HEIGHT))
	double_buffer [((y<<8) + (y<<6)) + x] = color;
	}

    int getpixel (int x,int y)
     {
     return( double_buffer[(y<<6)+(y<<8)+x] );
     }

void plot_line_db (int x, int y, int x2, int y2, char color)
{
      int i, steep = 0, sx, sy, dx, dy, e;

      dx = abs(x2 - x);
      sx = ((x2 - x) > 0) ? 1 : -1;
      dy = abs(y2 - y);
      sy = ((y2 - y) > 0) ? 1 : -1;

      if(dy > dx)
      {
	    steep = 1;
	    x ^= y;  /* swap x and y */
	    y ^= x;
	    x ^= y;
	    dx ^= dy; /* swap dx and dy */
	    dy ^= dx;
	    dx ^= dy;
	    sx ^= sy; /* swap sx and sy */
	    sy ^= sx;
	    sx ^= sy;
      }

      e = 2 * dy - dx;
      for(i = 0;i < dx;i++)
      {
	    if(steep)
		  plot_pixel_db(y, x, color);
	    else  plot_pixel_db(x, y, color);
	    while(e >= 0)
	    {
		  y += sy;
		  e -= 2 * dx;
	    }
	    x += sx;
	    e += 2 * dy;
      }
      plot_pixel_db(x2, y2, color);
}

   int CheckPoint(int xx,int yy)
   {
      if   ((xx > 0) && (xx < Getmaxx))
      { if ((yy > 0) && (yy < Getmaxy))
	{ return (1); } }

     return(0);

   }


   void square_db (int x,int y,int width,int color)
   {
      int xm, ym;
      int xp, yp;

      xm=x-(width>>1);
      xp=x+(width>>1);
      ym=y-(width>>1);
      yp=y+(width>>1);

    if (CheckPoint(xm,ym))
    if (CheckPoint(xp,yp))
    plot_line_db(xm,ym,xp,ym,color);

    if (CheckPoint(xm,ym))
    if (CheckPoint(xp,yp))
    plot_line_db(xm,ym,xm,yp,color);

    if (CheckPoint(xm,ym))
    if (CheckPoint(xp,yp))
    plot_line_db(xp,ym,xp,yp,color);

    if (CheckPoint(xm,ym))
    if (CheckPoint(xp,yp))
    plot_line_db(xm,yp,xp,yp,color);
   }

////////////////////////////////////////////////////////////////////////
void FadeAway (void)
{
//this function fades the light by slowly decresing the
//color values in all color registers.

int pal_reg,index;
RGB_color color;

	for (index=0;index<64;index++)
	{
		for (pal_reg=0;pal_reg<256;pal_reg++)
		{
		//get the color to fade
		get_palette_register(pal_reg,(RGB_color_ptr)&color);

		if (color.red > 5) color.red -=1;
		else
			color.red = 0;

		if (color.green > 5) color.green -=1;
		else
			color.green= 0;

		if (color.blue > 5) color.blue -=1;
		else
			color.blue = 0;

		//set the color to a diminished intensity.

		set_palette_register(pal_reg,(RGB_color_ptr)&color);

		} // end for pal_reg
	// wait a bit
	waitretrace();
	}

	 set_double_buffer(0);
	 show_double_buffer();


}

////////////////////////////////////////////////////////////////////////////

void FadeIn (void)
{
  //this function fades the light by slowly incresing the
  //color values in all color registers.

  int i,j,index;
  RGB_color orignal[256],initial[256];

   // secondary easy way

	//find decrement
	for(i=0; i<256;i++)
		{
 get_palette_register(i,(RGB_color_ptr)&orignal[i]);

		}

	//0 out palette
	for(i=0; i<256;i++)
	{
	initial[i].red=0;
	initial[i].green=0;
	initial[i].blue=0;
	}
	//fade in

	for(i=0;i<256;i++)
	{
	set_palette_register(i,(RGB_color_ptr)&initial[i]);
	}

	for (index=0;index<64;index++)
	{
	    for(j=0;j<256;j++)
	    {

		if (initial[j].red < orignal[j].red)
		{
		initial[j].red+=1;
		}

		if (initial[j].green < orignal[j].green)
		{
		initial[j].green+=1;
		}

		if (initial[j].blue < orignal[j].blue)
		{
		initial[j].blue+=1;
		}

		set_palette_register(j,(RGB_color_ptr)&initial[j]);
	     }

	waitretrace();
     }
   }

////////////////////////////////////////////////////////////////////////////

////////////// closing the screen with lines ////////////////////////////

void smooth (void)
{ int y;

  for (y=1 ; y<99 ; y+=2)
  {
  plot_line_db(0,y,320,y,0);
  plot_line_db(0,199-y,320,199-y,0);
  delay(20);
  waitretrace();
  show_double_buffer();
  }
}

    void ChangePalette (char col)
{
//this function fades the light by slowly decresing the
//color values in all color registers.

int index;
RGB_color color[256];


		for (index=0;index<256;index++)
		{
		//get the color to fade
	get_palette_register(index,(RGB_color_ptr)&color[index]);
		}
		int count;

	  for (count=0;count<40;count++)
	      {
		for (index=0;index<256;index++)
		{

		if (col == 'b')
		if (color[index].blue  > 0) color[index].blue  -=1;
		if (col == 'g')
		if (color[index].blue  > 0) color[index].green  -=1;
		if (col == 'r')
		if (color[index].blue  > 0) color[index].red  -=1;
		//set the color to a diminished intensity.
		set_palette_register(index,(RGB_color_ptr)&color[index]);
		} // end for pal_reg
	waitretrace();

	     }
	}


⌨️ 快捷键说明

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