📄 t3dlib1.cpp
字号:
///////////////////////////////////////////////////////////
int Move_BOB(BOB_PTR bob)
{
// this function moves the bob based on its current velocity
// also, the function test for various motion attributes of the'
// bob and takes the appropriate actions
// is this a valid bob
if (!bob)
return(0);
// translate the bob
bob->x+=bob->xv;
bob->y+=bob->yv;
// test for wrap around
if (bob->attr & BOB_ATTR_WRAPAROUND)
{
// test x extents first
if (bob->x > max_clip_x)
bob->x = min_clip_x - bob->width;
else
if (bob->x < min_clip_x-bob->width)
bob->x = max_clip_x;
// now y extents
if (bob->x > max_clip_x)
bob->x = min_clip_x - bob->width;
else
if (bob->x < min_clip_x-bob->width)
bob->x = max_clip_x;
} // end if
else
// test for bounce
if (bob->attr & BOB_ATTR_BOUNCE)
{
// test x extents first
if ((bob->x > max_clip_x - bob->width) || (bob->x < min_clip_x) )
bob->xv = -bob->xv;
// now y extents
if ((bob->y > max_clip_y - bob->height) || (bob->y < min_clip_y) )
bob->yv = -bob->yv;
} // end if
// return success
return(1);
} // end Move_BOB
///////////////////////////////////////////////////////////
int Load_Animation_BOB(BOB_PTR bob,
int anim_index,
int num_frames,
int *sequence)
{
// this function load an animation sequence for a bob
// the sequence consists of frame indices, the function
// will append a -1 to the end of the list so the display
// software knows when to restart the animation sequence
// is this bob valid
if (!bob)
return(0);
// allocate memory for bob animation
if (!(bob->animations[anim_index] = (int *)malloc((num_frames+1)*sizeof(int))))
return(0);
// load data into
for (int index=0; index<num_frames; index++)
bob->animations[anim_index][index] = sequence[index];
// set the end of the list to a -1
bob->animations[anim_index][index] = -1;
// return success
return(1);
} // end Load_Animation_BOB
///////////////////////////////////////////////////////////
int Set_Pos_BOB(BOB_PTR bob, int x, int y)
{
// this functions sets the postion of a bob
// is this a valid bob
if (!bob)
return(0);
// set positin
bob->x = x;
bob->y = y;
// return success
return(1);
} // end Set_Pos_BOB
///////////////////////////////////////////////////////////
int Set_Anim_Speed_BOB(BOB_PTR bob,int speed)
{
// this function simply sets the animation speed of a bob
// is this a valid bob
if (!bob)
return(0);
// set speed
bob->anim_count_max = speed;
// return success
return(1);
} // end Set_Anim_Speed
///////////////////////////////////////////////////////////
int Set_Animation_BOB(BOB_PTR bob, int anim_index)
{
// this function sets the animation to play
// is this a valid bob
if (!bob)
return(0);
// set the animation index
bob->curr_animation = anim_index;
// reset animation
bob->anim_index = 0;
// return success
return(1);
} // end Set_Animation_BOB
///////////////////////////////////////////////////////////
int Set_Vel_BOB(BOB_PTR bob,int xv, int yv)
{
// this function sets the velocity of a bob
// is this a valid bob
if (!bob)
return(0);
// set velocity
bob->xv = xv;
bob->yv = yv;
// return success
return(1);
} // end Set_Vel_BOB
///////////////////////////////////////////////////////////
int Hide_BOB(BOB_PTR bob)
{
// this functions hides bob
// is this a valid bob
if (!bob)
return(0);
// reset the visibility bit
RESET_BIT(bob->attr, BOB_ATTR_VISIBLE);
// return success
return(1);
} // end Hide_BOB
///////////////////////////////////////////////////////////
int Show_BOB(BOB_PTR bob)
{
// this function shows a bob
// is this a valid bob
if (!bob)
return(0);
// set the visibility bit
SET_BIT(bob->attr, BOB_ATTR_VISIBLE);
// return success
return(1);
} // end Show_BOB
///////////////////////////////////////////////////////////
int Collision_BOBS(BOB_PTR bob1, BOB_PTR bob2)
{
// are these a valid bobs
if (!bob1 || !bob2)
return(0);
// get the radi of each rect
int width1 = (bob1->width>>1) - (bob1->width>>3);
int height1 = (bob1->height>>1) - (bob1->height>>3);
int width2 = (bob2->width>>1) - (bob2->width>>3);
int height2 = (bob2->height>>1) - (bob2->height>>3);
// compute center of each rect
int cx1 = bob1->x + width1;
int cy1 = bob1->y + height1;
int cx2 = bob2->x + width2;
int cy2 = bob2->y + height2;
// compute deltas
int dx = abs(cx2 - cx1);
int dy = abs(cy2 - cy1);
// test if rects overlap
if (dx < (width1+width2) && dy < (height1+height2))
return(1);
else
// else no collision
return(0);
} // end Collision_BOBS
///////////////////////////////////////////////////////////
int DDraw_Init(int width, int height, int bpp)
{
// this function initializes directdraw
int index; // looping variable
LPDIRECTDRAW lpdd_temp = NULL; // used to get directdraw1
// create IDirectDrawdirectdraw interface 1.0 object and test for error
if (FAILED(DirectDrawCreate(NULL,&lpdd_temp,NULL)))
return(0);
// now query for IDirectDraw4
if (FAILED(lpdd_temp->QueryInterface(IID_IDirectDraw4,
(LPVOID *)&lpdd)))
return(0);
// set cooperation level to requested mode
if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
return(0);
// set the display mode
if (FAILED(lpdd->SetDisplayMode(width,height,bpp,0,0)))
return(0);
// set globals
screen_height = height;
screen_width = width;
screen_bpp = bpp;
// Create the primary surface
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
// we need to let dd know that we want a complex
// flippable surface structure, set flags for that
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
// set the backbuffer count to 1, 2 for triple buffering
ddsd.dwBackBufferCount = 1;
// create the primary surface
lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
// query for the backbuffer i.e the secondary surface
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if (FAILED(lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback)))
return(0);
// create and attach palette
// create palette data
// clear all entries defensive programming
memset(palette,0,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
// create a R,G,B,GR gradient palette
for (index=0; index < MAX_COLORS_PALETTE; index++)
{
// set each entry
if (index < 64)
palette[index].peRed = index*4;
else // shades of green
if (index >= 64 && index < 128)
palette[index].peGreen = (index-64)*4;
else // shades of blue
if (index >= 128 && index < 192)
palette[index].peBlue = (index-128)*4;
else // shades of grey
if (index >= 192 && index < 256)
palette[index].peRed = palette[index].peGreen =
palette[index].peBlue = (index-192)*4;
// set flag to force directdraw to leave alone
palette[index].peFlags = PC_NOCOLLAPSE;
} // end for index
// now create the palette object
if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
palette,&lpddpal,NULL)))
return(0);
// attach the palette to the primary
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
return(0);
// clear out both primary and secondary surfaces
DDraw_Fill_Surface(lpddsprimary,0);
DDraw_Fill_Surface(lpddsback,0);
// return success
return(1);
} // end DDraw_Init
///////////////////////////////////////////////////////////
int DDraw_Shutdown(void)
{
// this function release all the resources directdraw
// allocated, mainly to com objects
// release the clipper first
if (lpddclipper)
lpddclipper->Release();
// release the palette
if (lpddpal)
lpddpal->Release();
// release the secondary surface
if (lpddsback)
lpddsback->Release();
// release the primary surface
if (lpddsprimary)
lpddsprimary->Release();
// finally, the main dd object
if (lpdd)
lpdd->Release();
// return success
return(1);
} // end DDraw_Shutdown
///////////////////////////////////////////////////////////
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds,
int num_rects,
LPRECT clip_list)
{
// this function creates a clipper from the sent clip list and attaches
// it to the sent surface
int index; // looping var
LPDIRECTDRAWCLIPPER lpddclipper; // pointer to the newly created dd clipper
LPRGNDATA region_data; // pointer to the region data that contains
// the header and clip list
// first create the direct draw clipper
if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
return(NULL);
// now create the clip list from the sent data
// first allocate memory for region data
region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));
// now copy the rects into region data
memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);
// set up fields of header
region_data->rdh.dwSize = sizeof(RGNDATAHEADER);
region_data->rdh.iType = RDH_RECTANGLES;
region_data->rdh.nCount = num_rects;
region_data->rdh.nRgnSize = num_rects*sizeof(RECT);
region_data->rdh.rcBound.left = 64000;
region_data->rdh.rcBound.top = 64000;
region_data->rdh.rcBound.right = -64000;
region_data->rdh.rcBound.bottom = -64000;
// find bounds of all clipping regions
for (index=0; index<num_rects; index++)
{
// test if the next rectangle unioned with the current bound is larger
if (clip_list[index].left < region_data->rdh.rcBound.left)
region_data->rdh.rcBound.left = clip_list[index].left;
if (clip_list[index].right > region_data->rdh.rcBound.right)
region_data->rdh.rcBound.right = clip_list[index].right;
if (clip_list[index].top < region_data->rdh.rcBound.top)
region_data->rdh.rcBound.top = clip_list[index].top;
if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
region_data->rdh.rcBound.bottom = clip_list[index].bottom;
} // end for index
// now we have computed the bounding rectangle region and set up the data
// now let's set the clipping list
if (FAILED(lpddclipper->SetClipList(region_data, 0)))
{
// release memory and return error
free(region_data);
return(NULL);
} // end if
// now attach the clipper to the surface
if (FAILED(lpdds->SetClipper(lpddclipper)))
{
// release memory and return error
free(region_data);
return(NULL);
} // end if
// all is well, so release memory and send back the pointer to the new clipper
free(region_data);
return(lpddclipper);
} // end DDraw_Attach_Clipper
///////////////////////////////////////////////////////////
LPDIRECTDRAWSURFACE4 DDraw_Create_Surface(int width, int height, int mem_flags)
{
// this function creates an offscreen plain surface
DDSURFACEDESC2 ddsd; // working description
LPDIRECTDRAWSURFACE4 lpdds; // temporary surface
// set to access caps, width, and height
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
// set dimensions of the new bitmap surface
ddsd.dwWidth = width;
ddsd.dwHeight = height;
// set surface to offscreen plain
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;
// create the surface
if (FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
return(NULL);
// set color key to color 0
DDCOLORKEY color_key; // used to set color key
color_key.dwColorSpaceLowValue = 0;
color_key.dwColorSpaceHighValue = 0;
// now set the color key for source blitting
lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);
// return surface
return(lpdds);
} // end DDraw_Create_Surface
///////////////////////////////////////////////////////////
int DDraw_Flip(void)
{
// this function flip the primary surface with the secondary surface
// test if either of the buffers are locked
if (primary_buffer || back_buffer)
return(0);
// flip pages
while(FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
// flip the surface
// return success
return(1);
} // end DDraw_Flip
///////////////////////////////////////////////////////////
int DDraw_Wait_For_Vsync(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -