📄 cgraph.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, ®s_in, ®s_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 + -