Archived

This topic is now archived and is closed to further replies.

DirectDraw7: Lock Surface never succeeds...

This topic is 5576 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there, I am currently working on a simple wrapper class for my DirectX related stuff. I am using DirectDraw7 for the graphics and built a colordepth independent and windowed/fullscreen capable simple engine. For now I am really stuck: I''ve done a lot of debugging in windowed mode so far, but have really no idea what might be the reason for my problem... all the DX functions for the initializations return success... Whenever I try to Lock for instance the backbuffer (to draw some pixels etc) I get the HRESULT DDERR_SURFACEBUSY (-2005532242). The meaning of this is "Access to this surface is being refused because the surface is already locked by another thread". In fullscreen mode the program just crashed back to Windows... In fullscreen I build a primary surface and an attached backbuffer. In windowed mode I build just a primary surface with a clipper (attached to the window, of window''s size) and the "backbuffer" as an offscreen surface that can be blitted to the primary surface. In the following posts I''ll send the source. Thanks for any help!

Share this post


Link to post
Share on other sites
This is the "Main Program":
***************************


#include <ddraw.h>
#include "DXEngine.h" // selbstgebastelte DirectX Engine
#include "TetrisEngine.h" // Game Engine

// CONSTANTS //////////////////////////////////////////////
const char WINDOW_CLASS_NAME[] = "WINXCLASS";

const int WINDOW_WIDTH = 640,
WINDOW_HEIGHT = 480;
const int NUMBER_OF_PIECES = 7;

const bool EXCLUSIVESTART = false;
const bool DEBUG = true;

// GLOBALS ////////////////////////////////////////////////
HWND main_window_handle = NULL; // save window handle
HINSTANCE main_instance = NULL; // save the instance

CDDrawSystem *DDSys = NULL; // ptr to "DirectDraw engine object"

DWORD *ColorTable = NULL; // ptr to color-values (array)

CPiece *pieceset = NULL; // ptr to set (array) of pieces
CPlayer *player = NULL; // ptr to player(s)

bool g_bRunGame = true;

// MAKROS /////////////////////////////////////////////////

// PROTOTYPES /////////////////////////////////////////////

int Game_Init(void *parms=NULL);
int Game_Shutdown(void *parms=NULL);
int Game_Start(void *parms=NULL);
int Game_Run(void *parms=NULL);


// FUNCTIONS //////////////////////////////////////////////

// MAIN MESSAGE HANDLER ///////////////////////////////////
LRESULT CALLBACK WindowProc(HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam) {
PAINTSTRUCT ps; // für WM_PAINT-Message
HDC hdc; // handle zu device context

// process messages
switch(msg)
{
case WM_CREATE:
{ // Init
return(0);
} break;

case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps); // start painting

EndPaint(hWnd,&ps); // end painting
return(0);
} break;

case WM_DESTROY:
{
// kill application
PostQuitMessage(0);
return(0);
} break;

case WM_ACTIVATE: // window activated or deactivated
{
if(LOWORD(wParam) == WA_INACTIVE)
{
g_bRunGame = false; // window deactivated
} // end if
else
{
g_bRunGame = true; // window activated
} // end else
} break;

default: break;

} // end switch

// process undefined messages

return (DefWindowProc(hWnd, msg, wParam, lParam));
} // end WindowProc


// WINMAIN ////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hprecinstance,
LPSTR lpcmdline,
int ncmdshow) {
WNDCLASS winclass; //window class
HWND hWnd; //window handle
MSG msg; //message

// Window-class erstellen
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hInstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;

if (!RegisterClass(&winclass))
return(0);

// Window selbst erstellen
if (!(hWnd = CreateWindow(WINDOW_CLASS_NAME,
"Tetrisclone", //title
WS_POPUP | WS_VISIBLE, // style: popup=no controls
0,0,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL, //handle to parent window
NULL, //hanlde to menu
hInstance, //instance
NULL))) //parameter für WM_CREATE
return(0);

// window handle und instance global wegsichern
main_window_handle = hWnd;
main_instance = hInstance;

// set gamestate for startup initializations
game_state = GAME_STATE_INIT;

// main game loop /////////////////////
while(game_state!=GAME_STATE_EXIT)
{
//Messages asynchron abfragen
if (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
{
//Programmende
if (msg.message == WM_QUIT)
break;

//translate accelerator keys
TranslateMessage(&msg);

//send message to message handler (=WindowProc)
DispatchMessage(&msg);
} // end if

// is game in exclusive mode ? (or Debug mode)
if (g_bRunGame || DEBUG)
{
// game main event loop
switch(game_state)
{
case GAME_STATE_INIT:
{
Game_Init(); // game intializing

game_state = GAME_STATE_MENU; // go to main menu
} break;

case GAME_STATE_MENU:
{
// menu processing ???
game_state = GAME_STATE_START; // game_state = Main_Menu();
} break;

case GAME_STATE_START:
{
Game_Start(); // any last preparations ???
game_state = GAME_STATE_RUN; // Game_Start
} break;

case GAME_STATE_RUN:
{
Game_Run(); // main game processing
} break;

case GAME_STATE_SHUTDOWN:
{
Game_Shutdown(); // do all the cleanup & exit program
game_state = GAME_STATE_EXIT;
} break;

default: break;
} //end switch
} // end if


// check for user trying to exit
if (KEY_DOWN(VK_ESCAPE)) // ???
PostMessage(main_window_handle, WM_DESTROY,0,0);

} // end while


// return to Windows
return(msg.wParam);

} // end WinMain


// Game functions /////////////////////////////////////////

///////////////////////////////////////////////////////////
// initializing all subsystems...
///////////////////////////////////////
int Game_Init(void *parms)
{
// create "DirectDraw engine object"
DDSys = new CDDrawSystem;
// initialize DirectDraw
DDSys->Init(EXCLUSIVESTART,SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP);
return(1);
}

///////////////////////////////////////////////////////////
// destroy all objects & release memory
///////////////////////////////////////
int Game_Shutdown(void *parms)
{
// destroy DirectDraw objects
DDSys->Shutdown();

delete DDSys;

return(1);
}

///////////////////////////////////////////////////////////
// last preparations, resets, inits
///////////////////////////////////////
int Game_Start(void *parms) {
//????player->Reset();

return(1);
}

///////////////////////////////////////////////////////////
// main game processing loop
///////////////////////////////////////
int Game_Run(void *parms)
{

int tmp_lpitch = 0;
UCHAR *tmp_back = DDSys->Lock_Back_Buffer(&tmp_lpitch);
if (tmp_back != NULL)
Gfx_DrawPixel(tmp_back,0,0,
DDSys->CompilePixelColor(0,0,255),
tmp_lpitch);

DDSys->Unlock_Back_Buffer();

DDSys->Wait_for_Vsync(); // wait for vsync
DDSys->Flip(); // flip the surfaces

return(1);
}

Share this post


Link to post
Share on other sites
// DXEngine.CPP

// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <io.h>
#include <ddraw.h> // DirectX includes
#include <ddrawex.h>
#include <dxerr8.h> // DirectX error handling
#include "DXEngine.h" // selbstgebastelte DirectX Engine

// EXTERNALS /////////////////////////////////////////////
extern HWND main_window_handle; // save the window handle
extern HINSTANCE main_instance; // save the instance

// GLOBALS ////////////////////////////////////////////////
BITMAP_FILE bitmap16bit; // 16bit bitmap file

// video settings
int g_screen_width,
g_screen_height,
g_screen_bpp;
bool g_bExclusive; // switch: exclusive or windowed mode

// FUNCTIONS //////////////////////////////////////////////

///////////////////////////////////////////////////////////
// CLASS CDDrawSystem
///////////////////////////////////////
CDDrawSystem::CDDrawSystem()
{
front_buffer = back_buffer = NULL;
front_lpitch = back_lpitch = 0;

r_shift = g_shift = b_shift = 0;
r_size = g_size = b_size = 0;

lpddsFront = lpddsBack = NULL;

// create main dd object
DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL);
} // end constructor

///////////////////////////////////////
// destructor
///////////////////////////////////////
CDDrawSystem::~CDDrawSystem()
{
// release main dd object
if(lpdd)
lpdd->Release();

} // end destructor

///////////////////////////////////////////////////////////
// init DDraw: set coop level, set display mode
// create primary surface and backbuffer
///////////////////////////////////////
int CDDrawSystem::Init(bool bExclusive, int width, int height, int bpp)
{
g_bExclusive = bExclusive; // save window state

g_screen_height = height;
g_screen_width = width;
g_screen_bpp = bpp;


if (bExclusive) // FULLSCREEN //
{
// set cooperative mode
if(FAILED(lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
return(0);

// set display mode
if(FAILED(lpdd->SetDisplayMode(width,height,bpp,0,0)))
return(0);

// create the primary surface (frontbuffer)
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // used flags

// flags: complex, flippable surface
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
// one backbuffer
ddsd.dwBackBufferCount = 1;

// create the surface
if(FAILED(lpdd->CreateSurface(&ddsd, &lpddsFront, NULL)))
return(0);

// query for a backbuffer
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if(FAILED(lpddsFront->GetAttachedSurface(&ddscaps, &lpddsBack)))
return(0);


// get the pixelformat of the frontbuffer
GetPixelformat(lpddsFront);

// clear front- and backbuffer surfaces
Fill_Surface(lpddsFront,0);
Fill_Surface(lpddsBack,0);

// return success
return(1);
} // end if
else // WINDOWED MODE //
{
// set cooperative mode
if(FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL)))
return(0);

// set display mode isn''t possible in windowded mode !

// create the primary surface
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS; // used flags

// flags: primary surface only
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

// create the surface
if(FAILED(lpdd->CreateSurface(&ddsd, &lpddsFront, NULL)))
return(0);


// create backbuffer
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; // used flags

// "normal" offscreen surface
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = width;
ddsd.dwHeight = height;

// create the surface
if(FAILED(lpdd->CreateSurface(&ddsd, &lpddsBack, NULL)))
return(0);

// create clipper object
if(FAILED(lpdd->CreateClipper(0,&lpddClipper,NULL)))
return(0);

// attach clipper to window
if(FAILED(lpddClipper->SetHWnd(0,main_window_handle)))
return(0);

// attach clipper to primary surface
if(FAILED(lpddsFront->SetClipper(lpddClipper)))
return(0);

// get the pixelformat of the frontbuffer
// set color resolution to windows
g_screen_bpp = GetPixelformat(lpddsFront);

// clear front- and backbuffer surfaces
Fill_Surface(lpddsFront,0);
Fill_Surface(lpddsBack,0);

// return success
return(1);
} // end else

} // end CDDrawSystem::Init

///////////////////////////////////////////////////////////
// releases all DDraw Ressources:
// clipper, surfaces...
///////////////////////////////////////
int CDDrawSystem::Shutdown(void)
{
if (g_bExclusive) // FULLSCREEN //
{
// ??? release clipper

// release backbuffer
if(lpddsBack)
lpddsBack->Release();
lpddsBack = NULL;

// release frontbuffer
if(lpddsFront)
lpddsFront->Release();
lpddsFront = NULL;

// reset pixelformat values
r_shift = g_shift = b_shift = 0;
r_size = g_size = b_size = 0;

// return success
return(1);
} // end if
else // WINDOWED MODE //
{
// release backbuffer
if(lpddsBack)
lpddsBack->Release();
lpddsBack = NULL;

// detach clipper (indirectly)
lpddsFront->SetClipper(NULL);
lpddClipper = NULL;

// release primary surface
if(lpddsFront)
lpddsFront->Release();
lpddsFront = NULL;

// reset pixelformat values
r_shift = g_shift = b_shift = 0;
r_size = g_size = b_size = 0;

// return success
return(1);
} // end else

} // end CDDrawSystem::Shutdown

///////////////////////////////////////////////////////////
// changes display mode
///////////////////////////////////////
int CDDrawSystem::ChangeDisplayMode(bool bExclusive, int width, int height, int bpp)
{
if(!Shutdown())
return(0); // delete surfaces

// create surfaces, set display mode
if(!Init(bExclusive,width,height,bpp))
return(0);

// return success
return(1);
} // end CDDrawSystem::ChangeDisplayMode

///////////////////////////////////////////////////////////
// creates offscreen plain surface
///////////////////////////////////////
LPDIRECTDRAWSURFACE7 CDDrawSystem::Create_Surface(int width, int height, int mem_flags)
{
DDSURFACEDESC2 ddsd; // working description
LPDIRECTDRAWSURFACE7 lpdds; // temp surface

// set to access caps, width, height
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

// set dimensions for new 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 (black) ???
DDCOLORKEY color_key;
color_key.dwColorSpaceLowValue = 0;
color_key.dwColorSpaceHighValue = 0;

lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);

// return surface pointer
return(lpdds);

} // end CDDrawSystem::Create_Surface

///////////////////////////////////////////////////////////
// flips the frontbuffer with the backbuffer (exclusive)
// or blits the backbuffer to the client rect (windowed)
///////////////////////////////////////
int CDDrawSystem::Flip(void)
{
if (g_bExclusive) // FULLSCREEN //
{
// test whether one of the buffers is locked
if(front_buffer || back_buffer)
return(0);

// flip pages
while(FAILED(lpddsFront->Flip(lpddsBack, DDFLIP_WAIT)));

// return success
return(1);
} // end if
else // WINDOWED MODE //
{
// calculate the client rect in screen coordinates
RECT rect;
memset(&rect,0,sizeof(rect));

// get the client area
GetClientRect(main_window_handle, &rect);

// copy the rect''s data into two points
POINT p1, p2;
p1.x = rect.left;
p1.y = rect.top;
p2.x = rect.right;
p2.y = rect.bottom;

// convert points to screen coordinates
ClientToScreen(main_window_handle,&p1);
ClientToScreen(main_window_handle,&p2);

// copy the points to the rect
rect.left = p1.x;
rect.top = p1.y;
rect.right = p2.x;
rect.bottom = p2.y;

// blit back buffer to windows position
lpddsFront->Blt(&rect,lpddsBack, NULL, DDBLT_WAIT, NULL);

// return success
return(1);
} // end else

} // end CDDrawSystem::Flip

///////////////////////////////////////////////////////////
// waits for a vertical blank to begin
///////////////////////////////////////
int CDDrawSystem::Wait_for_Vsync(void)
{
lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);

// return success
return(1);

} // end CDDrawSystem::Wait_for_Vsync

///////////////////////////////////////////////////////////
// Fill the whole surface with a color
///////////////////////////////////////
int CDDrawSystem::Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds, DWORD color)
{
DDBLTFX ddbltfx; // temp ddbltfx struct

// clear struct and set size member
DD_INIT_STRUCT(ddbltfx);

// set fillcolor to desired color
ddbltfx.dwFillColor = color;

if (FAILED(lpdds->Blt(NULL, // ptr to destination rect
NULL, // ptr to source surface
NULL, // ptr to source rect
DDBLT_COLORFILL | DDBLT_WAIT, // fill & wait
&ddbltfx))) // ptr to ddbltfx struct
return(0);

// return success
return(1);

} // end CDDrawSystem::Fill_Surface

///////////////////////////////////////////////////////////
// locks the sent surface and returns a pointer to it
///////////////////////////////////////
UCHAR *CDDrawSystem::Lock_Surface(LPDIRECTDRAWSURFACE7 lpdds, int *lpitch)
{
if (!lpdds) // is the surface valid ?
return(NULL);

// lock the whole surface
DD_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 CDDrawSystem::Lock_Surface

///////////////////////////////////////////////////////////
// unlock a general surface
///////////////////////////////////////
int CDDrawSystem::Unlock_Surface(LPDIRECTDRAWSURFACE7 lpdds, UCHAR *surface_buffer)
{
if(!lpdds) // is the surface valid ?
return(0);

// unlock the whole surface memory
lpdds->Unlock(NULL);

// return success
return(1);

} // end CDDrawSystem::Unlock_Surface

///////////////////////////////////////////////////////////
// locks the frontbuffer (primary buffer) and returns a pointer to it
// and updates the global variables front_buffer and front_lpitch
///////////////////////////////////////
UCHAR *CDDrawSystem::Lock_Front_Buffer(int *lpitch)
{
HRESULT hr=0;
if (front_buffer) // already locked ?
{
// return current lock
return(front_buffer);
} // end if

// lock the whole frontbuffer surface
DD_INIT_STRUCT(ddsd);
if FAILED(hr = lpddsFront->Lock(NULL,&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL))
{
MessageBox(main_window_handle,
DXGetErrorDescription8(hr),
"Error",
MB_OK | MB_ICONERROR);
return NULL;
}

// set globals
front_buffer = (UCHAR *)ddsd.lpSurface;
*lpitch = front_lpitch = ddsd.lPitch;

// return pointer to surface
return(front_buffer);

} // end CDDrawSystem::Lock_Front_Buffer

///////////////////////////////////////////////////////////
// unlocks the frontbuffer and global variables
///////////////////////////////////////
int CDDrawSystem::Unlock_Front_Buffer(void)
{
if (!front_buffer) // is frontbuffer valid ?
return(0);

// unlock the whole primary surface
lpddsFront->Unlock(NULL);

// reset globals
front_buffer = NULL;
front_lpitch = 0;

// return success
return(1);
} // end CDDrawSystem::Unlock_Front_Buffer

///////////////////////////////////////////////////////////
// locks the backbuffer and returns a pointer to it
// and updates the globals variables back_buffer and back_lpitch
///////////////////////////////////////
UCHAR *CDDrawSystem::Lock_Back_Buffer(int *lpitch)
{
HRESULT hr=0;
if (back_buffer) // already locked ?
{
// return current lock
return(back_buffer);
} // end if

// lock the whole backbuffer surface
DD_INIT_STRUCT(ddsd);
MessageBox(main_window_handle,
"before lock",
"debug",
MB_OK | MB_ICONERROR);

if (FAILED(hr = lpddsBack->Lock(NULL,&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL)))
{
MessageBox(main_window_handle,
DXGetErrorDescription8(hr),
"Error",
MB_OK | MB_ICONERROR);
return NULL;
}

MessageBox(main_window_handle,
"after lock",
"debug",
MB_OK | MB_ICONERROR);

// set globals
back_buffer = (UCHAR *)ddsd.lpSurface;
*lpitch = back_lpitch = ddsd.lPitch;

// return pointer to surface
return(back_buffer);

} // end CDDrawSystem::Lock_Back_Buffer

///////////////////////////////////////////////////////////
// unlocks the backbuffer and global variables
///////////////////////////////////////
int CDDrawSystem::Unlock_Back_Buffer(void)
{
if (!back_buffer) // is backbuffer valid ?
return(0);

// unlock the whole backbuffer surface
lpddsBack->Unlock(NULL);

// reset globals
back_buffer = NULL;
back_lpitch = 0;

// return success
return(1);

} // end CDDrawSystem::Unlock_Back_Buffer

///////////////////////////////////////////////////////////
/* Graphics functions */
///////////////////////////////////////////////////////////
// gets the pixelformat of the graphics settings
// based on the given DirectDrawSurface
// stores the gathered data
// z.Zt. nur für Frontbuffer verwendbar !!!!!!!!!!!
///////////////////////////////////////
DWORD CDDrawSystem::GetPixelformat(LPDIRECTDRAWSURFACE7 lpDDSurface)
{
DDPIXELFORMAT ddpf;

// get the pixelformat of the given surface
DD_INIT_STRUCT(ddpf);
lpDDSurface->GetPixelFormat(&ddpf);

// get size and bitshift
GetMaskInfo(ddpf.dwRBitMask, &r_shift, &r_size); // red
GetMaskInfo(ddpf.dwGBitMask, &g_shift, &g_size); // green
GetMaskInfo(ddpf.dwBBitMask, &b_shift, &b_size); // blue

// return color bitdepth
return(ddpf.dwRGBBitCount);
} // end CDDrawSystem::GetSettings

///////////////////////////////////////////////////////////
// calculates the bitshift and size of a color component
///////////////////////////////////////
int CDDrawSystem::GetMaskInfo(DWORD Bitmask, int* lpBitShift, int* lpBitSize)
{
int Size, Shift; // size = number of bits used for color component
Shift = Size = 0; // bitshift = number of bits the component is shifted to the right

// calculate shift value
while(!(Bitmask & 0x01L))
{
Bitmask >>= 1;
Shift++;
} // end while

// calculate size of the color component
while(Bitmask & 0x01L)
{
Bitmask >>= 1;
Size++;
} // end while

// "return" shift & size
*lpBitShift = Shift;
*lpBitSize = Size;

// return success
return(1);
} // end CDDrawSystem::GetMaskInfo

///////////////////////////////////////////////////////////
// calculates the pixelvalue of a given color (in RGB)
// returns a DWORD (16-32 bit color modes supported)
///////////////////////////////////////
DWORD CDDrawSystem::CompilePixelColor(int r, int g, int b) // RGB Values 16 bit each
{
// 16bpp modes: calculate down to 2 bytes (5 or 6 bit per colorcomponent)
if(g_screen_bpp == 16)
{
r >>= (8 - r_size);
g >>= (8 - g_size);
b >>= (8 - b_size);
} // end if

// return the compiled pixel
return( (DWORD) ((r << r_shift) | (g << g_shift) | (b << b_shift)) );

} // end CDDrawSystem::CompilePixelColor

Share this post


Link to post
Share on other sites
// DXEngine.H - Header file
#ifndef DXENGINE_H
#define DXENGINE_H

// DEFINES ////////////////////////////////////////////////
const unsigned short BITMAP_ID = 0x4D42u;

// CONSTANTS //////////////////////////////////////////////
const int SCREEN_WIDTH = 640, // default screen size
SCREEN_HEIGHT = 480,
SCREEN_BPP = 16; // bits per pixel

// MACROS /////////////////////////////////////////////////
// initialize DirectDraw Structures and set size member
#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

// CLASSES ////////////////////////////////////////////////

class CDDrawSystem
{
public:
CDDrawSystem();
~CDDrawSystem();

int Init(bool bExclusive = true,
int width = SCREEN_WIDTH,
int height = SCREEN_HEIGHT,
int bpp = SCREEN_BPP);
int Shutdown(void);
int ChangeDisplayMode(bool bExclusive, int width, int height, int bpp);

int Flip(void);
int Wait_for_Vsync(void);

int GetMaskInfo(DWORD Bitmask, int* lpBitShift, int* lpBitSize);
DWORD GetPixelformat(LPDIRECTDRAWSURFACE7 lpDDSurface);
DWORD CompilePixelColor(int r, int g, int b);

// surface functions
LPDIRECTDRAWSURFACE7 Create_Surface(int width, int height, int mem_flags);
int Fill_Surface(LPDIRECTDRAWSURFACE7 lddds, DWORD color);
// front- and back-buffer
UCHAR *Lock_Front_Buffer(int *lpitch);
int Unlock_Front_Buffer(void);
UCHAR *Lock_Back_Buffer(int *lpitch);
int Unlock_Back_Buffer(void);
// off-screen surfaces
UCHAR *Lock_Surface(LPDIRECTDRAWSURFACE7 lpdds, int *lpitch);
int Unlock_Surface(LPDIRECTDRAWSURFACE7 lpdds, UCHAR *surface_buffer);

private:
LPDIRECTDRAW7 lpdd; // main dd object

LPDIRECTDRAWSURFACE7 lpddsFront; // front buffer (primary surface)
LPDIRECTDRAWSURFACE7 lpddsBack; // back buffer

LPDIRECTDRAWCLIPPER lpddClipper; // clipper object

DDSURFACEDESC2 ddsd; // dd surface description struct
DDBLTFX ddbltfx; // dd bltfx struct (for blitting)
DDSCAPS2 ddscaps; // dd surface capabilities struc



int r_size, r_shift, // pixelformat: bitshift & bitsize
g_size, g_shift,
b_size, b_shift;

BYTE *front_buffer; // front video buffer (primary)
BYTE *back_buffer; // back buffer (secondary)
int front_lpitch; // memory line pitch frontbuffer
int back_lpitch; // memory line pitch backbuffer
};

// GLOBALS ////////////////////////////////////////////////
extern int g_screen_width, // default screen setting; overwritten by Init()
g_screen_height,
g_screen_bpp;

#endif /* DXENGINE_H */

Share this post


Link to post
Share on other sites