?? t3dlib1.cpp
字號(hào):
} // end else
// set globals
screen_height = height;
screen_width = width;
screen_bpp = bpp;
screen_windowed = windowed;
// Create the primary surface
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
// we need to let dd know that we want a complex
// flippable surface structure, set flags for that
if (!screen_windowed)
{
// fullscreen mode
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
// set the backbuffer count to 0 for windowed mode
// 1 for fullscreen mode, 2 for triple buffering
ddsd.dwBackBufferCount = 1;
} // end if
else
{
// windowed mode
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// set the backbuffer count to 0 for windowed mode
// 1 for fullscreen mode, 2 for triple buffering
ddsd.dwBackBufferCount = 0;
} // end else
// create the primary surface
lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
// get the pixel format of the primary surface
DDPIXELFORMAT ddpf; // used to get pixel format
// initialize structure
DDRAW_INIT_STRUCT(ddpf);
// query the format from primary surface
lpddsprimary->GetPixelFormat(&ddpf);
// based on masks determine if system is 5.6.5 or 5.5.5
//RGB Masks for 5.6.5 mode
//DDPF_RGB 16 R: 0x0000F800
// G: 0x000007E0
// B: 0x0000001F
//RGB Masks for 5.5.5 mode
//DDPF_RGB 16 R: 0x00007C00
// G: 0x000003E0
// B: 0x0000001F
// test for 6 bit green mask)
//if (ddpf.dwGBitMask == 0x000007E0)
// dd_pixel_format = DD_PIXEL_FORMAT565;
// use number of bits, better method
dd_pixel_format = ddpf.dwRGBBitCount;
Write_Error("\npixel format = %d",dd_pixel_format);
// set up conversion macros, so you don't have to test which one to use
if (dd_pixel_format == DD_PIXEL_FORMAT555)
{
RGB16Bit = RGB16Bit555;
Write_Error("\npixel format = 5.5.5");
} // end if
else
{
RGB16Bit = RGB16Bit565;
Write_Error("\npixel format = 5.6.5");
} // end else
// only need a backbuffer for fullscreen modes
if (!screen_windowed)
{
// query for the backbuffer i.e the secondary surface
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if (FAILED(lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback)))
return(0);
} // end if
else
{
// must be windowed, so create a double buffer that will be blitted
// rather than flipped as in full screen mode
lpddsback = DDraw_Create_Surface(width, height); // int mem_flags, USHORT color_key_flag);
} // end else
// create a palette only if 8bit mode
if (screen_bpp==DD_PIXEL_FORMAT8)
{
// create and attach palette
// clear all entries, defensive programming
memset(palette,0,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
// load a pre-made "good" palette off disk
Load_Palette_From_File(DEFAULT_PALETTE_FILE, palette);
// load and attach the palette, test for windowed mode
if (screen_windowed)
{
// in windowed mode, so the first 10 and last 10 entries have
// to be slightly modified as does the call to createpalette
// reset the peFlags bit to PC_EXPLICIT for the "windows" colors
for (index=0; index < 10; index++)
palette[index].peFlags = palette[index+246].peFlags = PC_EXPLICIT;
// now create the palette object, but disable access to all 256 entries
if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE,
palette,&lpddpal,NULL)))
return(0);
} // end
else
{
// in fullscreen mode, so simple create the palette with the default palette
// and fill in all 256 entries
if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
palette,&lpddpal,NULL)))
return(0);
} // end if
// now attach the palette to the primary surface
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
return(0);
} // end if attach palette for 8bit mode
// clear out both primary and secondary surfaces
if (screen_windowed)
{
// only clear backbuffer
DDraw_Fill_Surface(lpddsback,0);
} // end if
else
{
// fullscreen, simply clear everything
DDraw_Fill_Surface(lpddsprimary,0);
DDraw_Fill_Surface(lpddsback,0);
} // end else
// set software algorithmic clipping region
min_clip_x = 0;
max_clip_x = screen_width - 1;
min_clip_y = 0;
max_clip_y = screen_height - 1;
// setup backbuffer clipper always
RECT screen_rect = {0,0,screen_width,screen_height};
lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect);
// set up windowed mode clipper
if (screen_windowed)
{
// set windowed clipper
if (FAILED(lpdd->CreateClipper(0,&lpddclipperwin,NULL)))
return(0);
if (FAILED(lpddclipperwin->SetHWnd(0, main_window_handle)))
return(0);
if (FAILED(lpddsprimary->SetClipper(lpddclipperwin)))
return(0);
} // end if screen windowed
// 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 clippers first
if (lpddclipper)
lpddclipper->Release();
if (lpddclipperwin)
lpddclipperwin->Release();
// release the palette if there is one
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(LPDIRECTDRAWSURFACE7 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
///////////////////////////////////////////////////////////
LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width,
int height,
int mem_flags,
USHORT color_key_value)
{
// this function creates an offscreen plain surface
DDSURFACEDESC2 ddsd; // working description
LPDIRECTDRAWSURFACE7 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 default color 000
// note that if this is a 8bit bob then palette index 0 will be
// transparent by default
// note that if this is a 16bit bob then RGB value 000 will be
// transparent
DDCOLORKEY color_key; // used to set color key
color_key.dwColorSpaceLowValue = color_key_value;
color_key.dwColorSpaceHighValue = color_key_value;
// 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
if (!screen_windowed)
while(FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
else
{
RECT dest_rect; // used to compute destination rectangle
// get the window's rectangle in screen coordinates
GetWindowRect(main_window_handle, &dest_rect);
// compute the destination rectangle
dest_rect.left +=window_client_x0;
dest_rect.top +=window_client_y0;
dest_rect.right =dest_rect.left+screen_width;
dest_rect.bottom =dest_rect.top +screen_height;
// clip the screen coords
// blit the entire back surface to the primary
if (FAILED(lpddsprimary->Blt(&dest_rect, lpddsback,NULL,DDBLT_WAIT,NULL)))
return(0);
} // end if
// return success
return(1);
} // end DDraw_Flip
///////////////////////////////////////////////////////////
int DDraw_Wait_For_Vsync(void)
{
// this function waits for a vertical blank to begin
lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
// return success
return(1);
} // end DDraw_Wait_For_Vsync
///////////////////////////////////////////////////////////
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds, USHORT color, RECT *client)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
// clear out the structure and set the size field
DDRAW_INIT_STRUCT(ddbltfx);
// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color;
// ready to blt to surface
lpdds->Blt(client, // 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 DDraw_Fill_Surface
///////////////////////////////////////////////////////////
UCHAR *DDraw_Lock_Surface(LPDIRECTDRAWSURFACE7 lpdds, int *lpitch)
{
// this function locks the sent surface and returns a pointer to it
// is this surface valid
if (!lpdds)
return(NULL);
// lock the surface
DDRAW_INIT_STRUCT(ddsd);
lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
// set the memory pitch
if (lpitch)
*lpitch = ddsd.lPitch;
// return pointer to surface
return((UCHAR *)ddsd.lpSurface);
} // end DDraw_Lock_Surface
///////////////////////////////////////////////////////////
int DDraw_Unlock_Surface(LPDIRECTDRAWSURFACE7 lpdds)
{
// this unlocks a general surface
// is this surface valid
if (!lpdds)
return(0);
// unlock the surface memory
lpdds->Unlock(NULL);
// return success
return(1);
} // end DDraw_Unlock_Surface
///////////////////////////////////////////////////////////
UCHAR *DDraw_Lock_Primary_Surface(void)
{
// this function locks the priamary surface and returns a pointer to it
// and updates the global variables primary_buffer, and primary_lpitch
// is this surface already locked
if (primary_buffer)
{
// return to current lock
return(primary_buffer);
} // end if
// lock the primary surface
DDRAW_INIT_STRUCT(ddsd);
lpddsprimary->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
// set globals
primary_buffer = (UCHAR *)ddsd.lpSurface;
primary_lpitch = ddsd.lPitch;
// return pointer to surface
return(primary_buffer);
} // end DDraw_Lock_Primary_Surface
///////////////////////////////////////////////////////////
int DDraw_Unlock_Primary_Surface(void)
{
// this unlocks the primary
// is this surface valid
if (!primary_buffer)
return(0);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -