📄 dxlibrary.h
字号:
//-----------------------------------------------------------------------------
// Name: GetRGB
// Desc: Returns the current mouse speed. This number does not correlate
// with Windows system mouse speed values.
//-----------------------------------------------------------------------------
int GetRGB(byte r, byte g, byte b)
{
return r << 16 | g << 8 | b;
}
//-----------------------------------------------------------------------------
// Name: Graphics
// Desc: Creates an instance of Direct Draw.
//-----------------------------------------------------------------------------
int Graphics (int screenWidth, int screenHeight, int screenDepth,
HWND hWnd, char* pPalleteFile = NULL)
{
//Record screen dimensions as globals.
g_screenWidth = screenWidth;
g_screenHeight = screenHeight;
g_screenDepth = screenDepth;
g_hWndGame = hWnd;
//Create the Direct Draw object. Use DirectDrawCreateEx to enable
//3d stuff.
HRESULT hr = DirectDrawCreateEx(
NULL, //use the GUID of the active display
(VOID**)&g_pDirectDraw,//address of variable representing Direct Draw object
IID_IDirectDraw7,//Specify Direct Draw 7
NULL); //Advanced COM stuff
if (hr != DD_OK) return 2;
//Set the cooperative level
g_hWndGame = hWnd; //save this info globally for the debuglog
hr = g_pDirectDraw->SetCooperativeLevel(
hWnd, //handle of program's window
DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (hr != DD_OK) {ReleaseObjects();return 3;}
// Set the display mode
hr = g_pDirectDraw->SetDisplayMode(
g_screenWidth, g_screenHeight, //set screen width, height
g_screenDepth,//set the screen bit depth (8,16,24,32)
0, //screen refresh rate - set to 0 for hardware default rate
0); //for rarely used standard VGA mode stuff
if (hr != DD_OK)
{
if (g_pDirectDraw != NULL)
{
g_pDirectDraw->Release();
g_pDirectDraw = NULL;
}
return 4;
}
//Create the primary surface (frontbuffer)
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP |
DDSCAPS_COMPLEX |
DDSCAPS_3DDEVICE;
ddsd.dwBackBufferCount = 1;
hr = g_pDirectDraw->CreateSurface(&ddsd, &g_pFrontBuffer, NULL);
if (hr != DD_OK) {ReleaseObjects();return 5;}
//Create the backbuffer
DDSCAPS2 ddscaps;
ZeroMemory(&ddscaps, sizeof(ddscaps));
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hr = g_pFrontBuffer->GetAttachedSurface(&ddscaps,&g_pBackBuffer);
if (hr != DD_OK) {ReleaseObjects();return 6;}
//Make the back buffer the current buffer.
g_pCurrentBuffer = 2;
g_pCurrentSurface = g_pBackBuffer;
//If in 8 bit mode, set a palette
if (g_screenDepth == 8)
{
LoadPalette(&g_pPalette,pPalleteFile);
g_pFrontBuffer->SetPalette(g_pPalette);
g_pBackBuffer->SetPalette(g_pPalette);
}
//If in 16 bit mode, save the screen format (555 or 565)
if (g_screenDepth == 16)
{
DDSURFACEDESC2 ddsd2;
ZeroMemory(&ddsd2, sizeof(ddsd2));
ddsd2.dwSize = sizeof(ddsd2);
hr = g_pFrontBuffer->GetSurfaceDesc(&ddsd2);
if (ddsd2.ddpfPixelFormat.dwGBitMask == 992) g_screenFormat16Bit = 555;//555 16 bit
if (ddsd2.ddpfPixelFormat.dwGBitMask == 2016) g_screenFormat16Bit = 565;//565 16 bit
}
//Create the clipper object
LPDIRECTDRAWCLIPPER pcClipper; //Declare the clipper object
hr = g_pDirectDraw->CreateClipper( //create the clipper object
NULL, //unused flag
&pcClipper, //address of variable pointing to clipper object
NULL); //advanced COM stuff
if (hr != DD_OK) {ReleaseObjects();return 8;}
//Create the clip list, which is a list of RECTS (rectangles) we want to
//clip to. At this point there is only one item on the list, the screen.
LPRGNDATA lpClipList //declare pointer to RGNDATA structure containing list
= (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)//allocate memory (malloc) for
+ sizeof(RECT)); //header; allocate memory for rect holding screen
RECT rcBoundary = {0, 0,g_screenWidth,g_screenHeight};//boundaries of screen
memcpy(lpClipList->Buffer, &rcBoundary, sizeof(RECT));// set clip list
lpClipList->rdh.dwSize = sizeof(RGNDATAHEADER); // size of header
lpClipList->rdh.iType = RDH_RECTANGLES; // type of clip regions
lpClipList->rdh.nCount = 1; // number of rects in clip list
lpClipList->rdh.nRgnSize = sizeof(RECT); // size of Buffer
lpClipList->rdh.rcBound = rcBoundary;// bounding RECT for all items on list
//Set the clip list
pcClipper->SetClipList(
lpClipList, //address of a valid RGNDATA structure, created above
0);//unused flag
if (hr != DD_OK)
{free(lpClipList);ReleaseObjects();return 9;}
//Attach the clipper to the backbuffer
if( FAILED( hr = g_pBackBuffer->SetClipper( pcClipper ) ) )
{
pcClipper->Release();
ReleaseObjects();
return 10;
}
//Free the clipper and clip list.
free(lpClipList);
pcClipper->Release();
//Hide the Windows cursor
ShowCursor(FALSE);
//Set up Direct Input
hr = DirectInputCreateEx(
GetModuleHandle(NULL),//HINSTANCE hinst,
DIRECTINPUT_VERSION,
IID_IDirectInput7,
(VOID**)&g_pDirectInput,
NULL);
if (hr != DD_OK) {ReleaseObjects();return 11;}
//Set up a Direct Input-enabled mouse
hr = g_pDirectInput->CreateDeviceEx(
GUID_SysMouse,//
IID_IDirectInputDevice7,
(void**)&g_pMouse,
NULL);
if (hr != DD_OK) {ReleaseObjects();return 12;}
hr = g_pMouse->SetDataFormat(&c_dfDIMouse);
if (hr != DD_OK) {ReleaseObjects();return 13;}
hr = g_pMouse->SetCooperativeLevel(hWnd,
DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
if (hr != DD_OK) {ReleaseObjects();return 14;}
//Set up buffer for MouseHit()
DIPROPDWORD dipdw; //device property header data structure
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = 10; //# of buffered data items
hr = g_pMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
if (hr != DI_OK)
{
if (hr == DI_PROPNOEFFECT)
{ReleaseObjects();return 15;}
else
{ReleaseObjects();return hr;}
}
//Acquire the mouse
hr = g_pMouse->Acquire();
if (hr != DD_OK) {ReleaseObjects();return 16;}
g_MouseX = g_screenWidth/2;
g_MouseY = g_screenHeight/2;
//If not in 8 bit/24 bit mode, activate 3D mode for special effect
//(fast rotations, alpha blending, etc.).
if (g_screenDepth != 8 && g_screenDepth != 24)
{
//Query DirectDraw for access to Direct3D
hr = g_pDirectDraw->QueryInterface(IID_IDirect3D7,(VOID**)&g_pD3D);
if(FAILED(hr)) {ReleaseObjects();return 17;};
//Create the D3D device using hardware
hr = g_pD3D->CreateDevice(
IID_IDirect3DHALDevice,
g_pBackBuffer,
&g_pD3DDevice);//I'm getting a no palette attached error
//If no hardware support, create the D3D device using sofware
if(FAILED(hr))
{
hr = g_pD3D->CreateDevice(
IID_IDirect3DRGBDevice,
g_pBackBuffer,
&g_pD3DDevice);
if(FAILED(hr)) {ReleaseObjects();return 18;}
}
//Create the viewport
D3DVIEWPORT7 vp = {0,0, g_screenWidth, g_screenHeight, 0.0f, 1.0f };
hr = g_pD3DDevice->SetViewport(&vp);
if(FAILED(hr)) {ReleaseObjects();return 19;}
}//if (g_screenDepth != 8)
//Return function result
return 1;
}
//-----------------------------------------------------------------------------
// Name: HandleImage
// Desc: Sets a handle for an image.
//-----------------------------------------------------------------------------
int HandleImage (cImage* pImage, int x, int y)
{
if(pImage == NULL) return -1;
if(pImage->pSurface == NULL) return -1;
pImage->xHandle = x; //x handle
pImage->yHandle = y; //y handle
return 1;
}
//-----------------------------------------------------------------------------
// Name: HidePointer
// Desc: Hides the Windows cursor (default = hidden)
//-----------------------------------------------------------------------------
void HidePointer (void)
{
ShowCursor(FALSE);
}
//-----------------------------------------------------------------------------
// Name: ImageHeight
// Desc: Gets the width of a given image.
//-----------------------------------------------------------------------------
int ImageHeight (cImage* pImage)
{
if(pImage == NULL) return -1;
return (pImage->imageHeight);
}
//-----------------------------------------------------------------------------
// Name: ImagesCollide
// Desc: Checks to see if two images have collided. This command
// considers pixel transparency, unlike ImagesOverlap, and it is a
// bit slower as a result. It is faster if at least the first of the
// two images is stored in RAM.
//-----------------------------------------------------------------------------
int ImagesCollide (cImage* pImage1, int x1, int y1,
cImage* pImage2, int x2, int y2)
{
if(pImage1 == NULL) return -1;
x1 = x1-pImage1->xHandle;
y1 = y1-pImage1->yHandle;
if(pImage2 == NULL) return -2;
x2 = x2-pImage2->xHandle;
y2 = y2-pImage2->yHandle;
//Figure out whether there is a simple overlap
int overlaps = 0;
if (x2 < x1+pImage1->imageWidth){
if (x2+pImage2->imageWidth > x1){
if (y2 < y1+pImage1->imageHeight){
if (y2+pImage2->imageHeight > y1){
overlaps = 1;
}}}}
//If there is an overlap, figure out the corners,
//width, and height of the collision box.
int a=0; int b = 0; int c = 0; int d= 0;
int width = 0; int height = 0;
if (overlaps == 1)
if (x2 > x1)
{
if (y2 > y1)
{
width = x1 + pImage1->imageWidth - x2;
height = y1 + pImage1->imageHeight - y2;
a = pImage1->imageWidth-width;
b = pImage1->imageHeight-height;
c = 0;
d = 0;
}
else
{
width = x1 + pImage1->imageWidth - x2;
height = y2 + pImage2->imageHeight - y1;
a = pImage1->imageWidth-width;
b = 0;
c = 0;
d = pImage2->imageHeight-height;
}
}
else
{
if (y2 > y1)
{
width = x2 + pImage2->imageWidth - x1;
height = y1 + pImage1->imageHeight - y2;
a = 0;
b = pImage1->imageHeight-height;
c = pImage2->imageWidth-width;
d = 0;
}
else
{
width = x2 + pImage2->imageWidth - x1;
height = y2 + pImage2->imageHeight - y1;
a = 0;
b = 0;
c = pImage2->imageWidth-width;
d = pImage2->imageHeight-height;
}
}
else //if no overlap, return no collision
{
return 0;
}
int collision = 0;
//Lock both surfaces
DDSURFACEDESC2 ddsd1; //surface description data structure
ZeroMemory(&ddsd1, sizeof(ddsd1));// zero-out the memory area
ddsd1.dwSize = sizeof(ddsd1);
HRESULT hr = pImage1->pSurface->Lock(
NULL,//lock entire surface
&ddsd1,
DDLOCK_WAIT | DDLOCK_NOSYSLOCK,
NULL);
if (hr != DD_OK) //couldn't lock surface so exit
return -3;
int pitch1 = (int) ddsd1.lPitch; //get the pitch
int bytesPerPixel1 = ddsd1.ddpfPixelFormat.dwRGBBitCount/8;
DDSURFACEDESC2 ddsd2; //surface description data structure
ZeroMemory(&ddsd2, sizeof(ddsd2));// zero-out the memory area
ddsd2.dwSize = sizeof(ddsd2);
hr = pImage2->pSurface->Lock(
NULL,//lock entire surface
&ddsd2,
DDLOCK_WAIT | DDLOCK_NOSYSLOCK,
NULL);
if (hr != DD_OK) //couldn't lock surface so exit
{
pImage1->pSurface->Unlock(NULL);
return -4;
}
int pitch2 = (int) ddsd2.lPitch; //get the pitch in bytes
int bytesPerPixel2 = ddsd2.ddpfPixelFormat.dwRGBBitCount/8;
//Now do pixel detection in that box
if (g_screenDepth == 8){
byte* pSurface1 = (byte*) ddsd1.lpSurface; //Grab surface pointer
byte* pSurface2 = (byte*) ddsd2.lpSurface; //Grab surface pointer
for (int x = 0; x < width; x++){
for (int y = 0; y < height; y++){
if (*(pSurface1 + a+x + (b+y)*pitch1) !=
pImage1->convertedMaskColor){
if (*(pSurface2 + c+x + (d+y)*pitch2) !=
pImage2->convertedMaskColor){
collision = 1;
break;
}//if (*(pSurface2
if (collision == 1) break;
}//if (*(pSurface1
}//for (int y = 0; y < height; y++){
}//for (int x = 0; x < width; x++){
}//if (g_screenDepth == 8){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -