?? t3dlib1.cpp
字號:
// adjust the error term
error+=dy2;
// move to the next pixel
vb_start+=x_inc;
} // end for
} // end if |slope| <= 1
else
{
// initialize error term
error = dx2 - dy;
// draw the line
for (index=0; index <= dy; index++)
{
// set the pixel
*vb_start = color;
// test if error overflowed
if (error >= 0)
{
error-=dy2;
// move to next line
vb_start+=x_inc;
} // end if error overflowed
// adjust the error term
error+=dx2;
// move to the next pixel
vb_start+=y_inc;
} // end for
} // end else |slope| > 1
// return success
return(1);
} // end Draw_Line
///////////////////////////////////////////////////////////
int Draw_Line16(int x0, int y0, // starting position
int x1, int y1, // ending position
int color, // color index
UCHAR *vb_start, int lpitch) // video buffer and memory pitch
{
// this function draws a line from xo,yo to x1,y1 using differential error
// terms (based on Bresenahams work)
int dx, // difference in x's
dy, // difference in y's
dx2, // dx,dy * 2
dy2,
x_inc, // amount in pixel space to move during drawing
y_inc, // amount in pixel space to move during drawing
error, // the discriminant i.e. error i.e. decision variable
index; // used for looping
int lpitch_2 = lpitch >> 1; // USHORT strided lpitch
// pre-compute first pixel address in video buffer based on 16bit data
USHORT *vb_start2 = (USHORT *)vb_start + x0 + y0*lpitch_2;
// compute horizontal and vertical deltas
dx = x1-x0;
dy = y1-y0;
// test which direction the line is going in i.e. slope angle
if (dx>=0)
{
x_inc = 1;
} // end if line is moving right
else
{
x_inc = -1;
dx = -dx; // need absolute value
} // end else moving left
// test y component of slope
if (dy>=0)
{
y_inc = lpitch_2;
} // end if line is moving down
else
{
y_inc = -lpitch_2;
dy = -dy; // need absolute value
} // end else moving up
// compute (dx,dy) * 2
dx2 = dx << 1;
dy2 = dy << 1;
// now based on which delta is greater we can draw the line
if (dx > dy)
{
// initialize error term
error = dy2 - dx;
// draw the line
for (index=0; index <= dx; index++)
{
// set the pixel
*vb_start2 = (USHORT)color;
// test if error has overflowed
if (error >= 0)
{
error-=dx2;
// move to next line
vb_start2+=y_inc;
} // end if error overflowed
// adjust the error term
error+=dy2;
// move to the next pixel
vb_start2+=x_inc;
} // end for
} // end if |slope| <= 1
else
{
// initialize error term
error = dx2 - dy;
// draw the line
for (index=0; index <= dy; index++)
{
// set the pixel
*vb_start2 = (USHORT)color;
// test if error overflowed
if (error >= 0)
{
error-=dy2;
// move to next line
vb_start2+=x_inc;
} // end if error overflowed
// adjust the error term
error+=dx2;
// move to the next pixel
vb_start2+=y_inc;
} // end for
} // end else |slope| > 1
// return success
return(1);
} // end Draw_Line16
///////////////////////////////////////////////////////////
int Draw_Pixel(int x, int y,int color,
UCHAR *video_buffer, int lpitch)
{
// this function plots a single pixel at x,y with color
video_buffer[x + y*lpitch] = color;
// return success
return(1);
} // end Draw_Pixel
///////////////////////////////////////////////////////////
int Draw_Pixel16(int x, int y,int color,
UCHAR *video_buffer, int lpitch)
{
// this function plots a single pixel at x,y with color
((USHORT *)video_buffer)[x + y*(lpitch >> 1)] = color;
// return success
return(1);
} // end Draw_Pixel16
///////////////////////////////////////////////////////////
int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,
LPDIRECTDRAWSURFACE7 lpdds)
{
// this function uses directdraw to draw a filled rectangle
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
RECT fill_area; // this contains the destination rectangle
// clear out the structure and set the size field
DDRAW_INIT_STRUCT(ddbltfx);
// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color;
// fill in the destination rectangle data (your data)
fill_area.top = y1;
fill_area.left = x1;
fill_area.bottom = y2;
fill_area.right = x2;
// ready to blt to surface, in this case blt to primary
lpdds->Blt(&fill_area, // ptr to dest rectangle
NULL, // ptr to source surface, NA
NULL, // ptr to source rectangle, NA
DDBLT_COLORFILL | DDBLT_WAIT, // fill and wait
&ddbltfx); // ptr to DDBLTFX structure
// return success
return(1);
} // end Draw_Rectangle
///////////////////////////////////////////////////////////
int Set_Palette_Entry(int color_index, LPPALETTEENTRY color)
{
// this function sets a palette color in the palette
lpddpal->SetEntries(0,color_index,1,color);
// set data in shadow palette
memcpy(&palette[color_index],color,sizeof(PALETTEENTRY));
// return success
return(1);
} // end Set_Palette_Entry
///////////////////////////////////////////////////////////
int Get_Palette_Entry(int color_index,LPPALETTEENTRY color)
{
// this function retrieves a palette entry from the color
// palette
// copy data out from shadow palette
memcpy(color, &palette[color_index],sizeof(PALETTEENTRY));
// return success
return(1);
} // end Get_Palette_Entry
///////////////////////////////////////////////////////////
int Load_Palette_From_File(char *filename, LPPALETTEENTRY palette)
{
// this function loads a palette from disk into a palette
// structure, but does not set the pallette
FILE *fp_file; // working file
// try and open file
if ((fp_file = fopen(filename,"r"))==NULL)
return(0);
// read in all 256 colors RGBF
for (int index=0; index<MAX_COLORS_PALETTE; index++)
{
// read the next entry in
fscanf(fp_file,"%d %d %d %d",&palette[index].peRed,
&palette[index].peGreen,
&palette[index].peBlue,
&palette[index].peFlags);
} // end for index
// close the file
fclose(fp_file);
// return success
return(1);
} // end Load_Palette_From_Disk
///////////////////////////////////////////////////////////
int Save_Palette_To_File(char *filename, LPPALETTEENTRY palette)
{
// this function saves a palette to disk
FILE *fp_file; // working file
// try and open file
if ((fp_file = fopen(filename,"w"))==NULL)
return(0);
// write in all 256 colors RGBF
for (int index=0; index<MAX_COLORS_PALETTE; index++)
{
// read the next entry in
fprintf(fp_file,"\n%d %d %d %d",palette[index].peRed,
palette[index].peGreen,
palette[index].peBlue,
palette[index].peFlags);
} // end for index
// close the file
fclose(fp_file);
// return success
return(1);
} // end Save_Palette_To_Disk
///////////////////////////////////////////////////////////
int Save_Palette(LPPALETTEENTRY sav_palette)
{
// this function saves the current palette
memcpy(sav_palette, palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
// return success
return(1);
} // end Save_Palette
///////////////////////////////////////////////////////////
int Set_Palette(LPPALETTEENTRY set_palette)
{
// this function writes the sent palette
// first save the new palette in shadow
memcpy(palette, set_palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
// now set the new palette
lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,palette);
// return success
return(1);
} // end Set_Palette
///////////////////////////////////////////////////////////
int Rotate_Colors(int start_index, int end_index)
{
// this function rotates the color between start and end
int colors = end_index - start_index + 1;
PALETTEENTRY work_pal[MAX_COLORS_PALETTE]; // working palette
// get the color palette
lpddpal->GetEntries(0,start_index,colors,work_pal);
// shift the colors
lpddpal->SetEntries(0,start_index+1,colors-1,work_pal);
// fix up the last color
lpddpal->SetEntries(0,start_index,1,&work_pal[colors - 1]);
// update shadow palette
lpddpal->GetEntries(0,0,MAX_COLORS_PALETTE,palette);
// return success
return(1);
} // end Rotate_Colors
///////////////////////////////////////////////////////////
int Blink_Colors(int command, BLINKER_PTR new_light, int id)
{
// this function blinks a set of lights
static BLINKER lights[256]; // supports up to 256 blinking lights
static int initialized = 0; // tracks if function has initialized
// test if this is the first time function has ran
if (!initialized)
{
// set initialized
initialized = 1;
// clear out all structures
memset((void *)lights,0, sizeof(lights));
} // end if
// now test what command user is sending
switch (command)
{
case BLINKER_ADD: // add a light to the database
{
// run thru database and find an open light
for (int index=0; index < 256; index++)
{
// is this light available?
if (lights[index].state == 0)
{
// set light up
lights[index] = *new_light;
// set internal fields up
lights[index].counter = 0;
lights[index].state = -1; // off
// update palette entry
lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
// return id to caller
return(index);
} // end if
} // end for index
} break;
case BLINKER_DELETE: // delete the light indicated by id
{
// delete the light sent in id
if (lights[id].state != 0)
{
// kill the light
memset((void *)&lights[id],0,sizeof(BLINKER));
// return id
return(id);
} // end if
else
return(-1); // problem
} break;
case BLINKER_UPDATE: // update the light indicated by id
{
// make sure light is active
if (lights[id].state != 0)
{
// update on/off parms only
lights[id].on_color = new_light->on_color;
lights[id].off_color = new_light->off_color;
lights[id].on_time = new_light->on_time;
lights[id].off_time = new_light->off_time;
// update palette entry
if (lights[id].state == -1)
lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].off_color);
else
lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].on_color);
// return id
return(id);
} // end if
else
return(-1); // problem
} break;
case BLINKER_RUN: // run the algorithm
{
// run thru database and process each light
for (int index=0; index < 256; index++)
{
// is this active?
if (lights[index].state == -1)
{
// update counter
if (++lights[index].counter >= lights[index].off_time)
{
// reset counter
lights[index].counter = 0;
// change states
lights[index].state = -lights[index].state;
// update color
lpddpa
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -