🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Wait Ill just post the code here... help please...

Started by
4 comments, last by GameDev.net 24 years, 7 months ago
The first problem I see is that you are using an unsigned char for 16 bit data. Unsigned char is used for 8 bit, unsigned short is used for 16 bit and unsigned int is used for 32 (and 24 I think). I hope this helps.
Advertisement
Be careful there. The size of an int varies depending on the platform you're compiling under. unsigned long would be more precise.
What is the nature of the problem?
Compile error?
Run time?
Code not behaving properly?
I think more info on nature of problem, will encourage people to look at you're code.
The problem is that the program compiles and runs without an error but all it does is show me a black screen for about a second. I the code to display the bitmap by drawing it direclty to the primary surface but when I try to implement a secondary one and draw the bitmap to the secodnary surface and flip it I get nothing but a black screen for a second. Thanks for trying to help!
OK Why dosnt this work the first person that tells me how to fix it becomes my new God!

// 16-bit page flipping demo

// INCLUDES ///////////////////////////////////////////////

#define WIN32_LEAN_AND_MEAN // just say no to MFC

#define INITGUID

#include // include important windows stuff
#include
#include
#include // include important C/C++ stuff
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include // include directdraw

// DEFINES ////////////////////////////////////////////////

// defines for windows
#define WINDOW_CLASS_NAME "WINCLASS1"

// default screen size
#define SCREEN_WIDTH 800 // size of screen
#define SCREEN_HEIGHT 600
#define SCREEN_BPP 16 // bits per pixel

// TYPES //////////////////////////////////////////////////////

// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;


// container structure for bitmaps .BMP file
typedef struct BITMAP_FILE_TAG
{
BITMAPFILEHEADER bitmapfileheader; // this contains the bitmapfile header
BITMAPINFOHEADER bitmapinfoheader; // this is all the info including the palette
UCHAR *buffer; // this is a pointer to the data

} BITMAP_FILE, *BITMAP_FILE_PTR;

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

int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);

int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename);

int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);

// MACROS /////////////////////////////////////////////////

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define BITMAP_ID 0x4D42 // universal id for a bitmap

// initializes a direct draw struct
#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }


// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b%32) + ((g%64) << 6) + ((r%32) << 11))

// GLOBALS ////////////////////////////////////////////////
HWND main_window_handle = NULL; // globally track main window
int window_closed = 0; // tracks if window is closed
HINSTANCE hinstance_app = NULL; // globally track hinstance

// directdraw stuff
LPDIRECTDRAW4 lpdd4 = NULL; // dd4 object
LPDIRECTDRAWSURFACE4 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE4 lpddsback = NULL; // dd back surface
LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
HRESULT ddrval; // result back from dd calls
DWORD start_clock_count = 0; // used for timing
BITMAP_FILE bitmap; // holds the bitmap

char buffer[80]; // general printing buffer

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


int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
// this function opens a bitmap file and loads the data into bitmap

int file_handle; // the file handle

UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
OFSTRUCT file_data; // the file data information

// open the file if it exists
if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
return(0);

// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));

// test if this is a bitmap file
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
// close the file
_lclose(file_handle);

// return error
return(0);
} // end if

// now we know this is a bitmap, so read in all the sections

// first the bitmap infoheader

// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));

// finally the image data itself
_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);

// now read in the image, if the image is 8 or 16 bit then simply read it
// but if its 24 bit then read it into a temporary area and then convert
// it to a 16 bit image

if (bitmap->bitmapinfoheader.biBitCount==8 | | bitmap->bitmapinfoheader.biBitCount==16 | |
bitmap->bitmapinfoheader.biBitCount==24)
{
// delete the last image if there was one
if (bitmap->buffer)
free(bitmap->buffer);

// allocate the memory for the image
if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
// close the file
_lclose(file_handle);

// return error
return(0);
} // end if

// now read it in
_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);

} // end if
else
{
// serious problem
return(0);

} // end else

#if 0
// write the file info out
printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
filename,
bitmap->bitmapinfoheader.biSizeImage,
bitmap->bitmapinfoheader.biWidth,
bitmap->bitmapinfoheader.biHeight,
bitmap->bitmapinfoheader.biBitCount,
bitmap->bitmapinfoheader.biClrUsed,
bitmap->bitmapinfoheader.biClrImportant);
#endif

// close the file
_lclose(file_handle);

// flip the bitmap
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);

// return success
return(1);

} // end Load_Bitmap_File

///////////////////////////////////////////////////////////

int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
// this function releases all memory associated with "bitmap"
if (bitmap->buffer)
{
// release memory
free(bitmap->buffer);

// reset pointer
bitmap->buffer = NULL;

} // end if

// return success
return(1);

} // end Unload_Bitmap_File

///////////////////////////////////////////////////////////

int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
{
// this function is used to flip bottom-up .BMP images

UCHAR *buffer; // used to perform the image processing
int index; // looping index

// allocate the temporary buffer
if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
return(0);

// copy image to work area
memcpy(buffer,image,bytes_per_line*height);

// flip vertically
for (index=0; index < height; index++)
memcpy(ℑ[((height-1) - index)*bytes_per_line],
&buffer[index*bytes_per_line], bytes_per_line);

// release the memory
free(buffer);

// return success
return(1);

} // end Flip_Bitmap

///////////////////////////////////////////////////////////////


LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
char buffer[80]; // used to print strings

// what is the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
// return success
return(0);
} break;

case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hwnd,&ps);

// end painting
EndPaint(hwnd,&ps);

// return success
return(0);
} break;

case WM_DESTROY:
{

// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);

// return success
return(0);
} break;

default:break;

} // end switch

// process any messages that we didn't take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc

///////////////////////////////////////////////////////////

int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

// make sure this isn't executed again
if (window_closed)
return(0);

// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
{
PostMessage(main_window_handle,WM_CLOSE,0,0);
window_closed = 1;
} // end if


Load_Bitmap_File(&bitmap,"bitmap24.bmp");

// lock the back buffer
DDRAW_INIT_STRUCT(ddsd);
lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// alias pointer to back buffer surface
USHORT *back_buffer = (USHORT *)ddsd.lpSurface;

// now clear the back buffer out
memset(back_buffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);

// process each line and copy it into the primary buffer
for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
{
for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
{
// get BGR values, note the scaling down of the channels, so that they
// fit into the 5.6.5 format
UCHAR blue = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]) >> 3,
green = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]) >> 3,
red = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]) >> 3;

// this builds a 16 bit color value in 5.6.5 format (green dominant mode)
USHORT pixel = _RGB16BIT565(red,green,blue);

// write the pixel
back_buffer[index_x + (index_y*ddsd.lPitch >> 1)] = pixel;

} // end for index_x

} // end for index_y

// unlock the back buffer
if (FAILED(lpddsback->Unlock(NULL)))
return(0);

// perform the flip
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

// wait a sec
Sleep(500);

// return success or failure or your own return code here
return(1);

// unload the bitmap file, we no longer need it
Unload_Bitmap_File(&bitmap);

} // end Game_Main

////////////////////////////////////////////////////////////

int Game_Init(void *parms = NULL, int num_parms = 0)
{
// this is called once after the initial window is created and
// before the main event loop is entered, do all your initialization
// here

LPDIRECTDRAW lpdd_temp;

// first create base IDirectDraw interface
if (FAILED(DirectDrawCreate(NULL, &lpdd_temp, NULL)))
return(0);

// now query for IDirectDraw4
if (FAILED(lpdd_temp->QueryInterface(IID_IDirectDraw4,
(LPVOID *)&lpdd4)))
return(0);

// set cooperation to full screen
if (FAILED(lpdd4->SetCooperativeLevel(main_window_handle,
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
return(0);

// set display mode to 800x600x16
if (FAILED(lpdd4->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
return(0);


// clear ddsd and set size
DDRAW_INIT_STRUCT(ddsd);

// enable valid fields
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

// set the backbuffer count field to 1, use 2 for triple buffering
ddsd.dwBackBufferCount = 1;

// request a complex, flippable
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

// create the primary surface
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL)))
return(0);

// now query for attached surface from the primary surface

// this line is needed by the call
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;


// return success or failure or your own return code here
return(1);

} // end Game_Init

/////////////////////////////////////////////////////////////

int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
// this is called after the game is exited and the main event
// loop while is exited, do all you cleanup and shutdown here


// first the palette
if (lpddpal)
{
lpddpal->Release();
lpddpal = NULL;
} // end if


// now the back buffer surface
if (lpddsback)
{
lpddsback->Release();
lpddsback = NULL;
} // end if

// now the primary surface
if (lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
} // end if

// now blow away the IDirectDraw4 interface
if (lpdd4)
{
lpdd4->Release();
lpdd4 = NULL;
} // end if

// return success or failure or your own return code here
return(1);

} // end Game_Shutdown

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

int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{

WNDCLASSEX winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
HDC hdc; // graphics device context

// first fill in the window class stucture
winclass.cbSize = sizeof(WNDCLASSEX);
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;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

// save hinstance in global
hinstance_app = hinstance;

// register the window class
if (!RegisterClassEx(&winclass))
return(0);

// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"DirectDraw Page Flipping Demo", // title
WS_POPUP | WS_VISIBLE,
0,0, // initial x,y
SCREEN_WIDTH,SCREEN_HEIGHT, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance of this application
NULL))) // extra creation parms
return(0);

// save main window handle
main_window_handle = hwnd;

// initialize game here
Game_Init();

// enter main event loop
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;

// translate any accelerator keys
TranslateMessage(&msg);

// send the message to the window proc
DispatchMessage(&msg);
} // end if

// main game processing goes here
Game_Main();

} // end while

// closedown game here
Game_Shutdown();

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

} // end WinMain

///////////////////////////////////////////////////////////

i found your problem.

your program crashes in the game_main() function when the following line is executed:

lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

why you ask?
you delcared lpddsback as a direct draw surface pointer, but never actually attached it to a valid surface. when you make the above call you are trying to lock using a NULL pointer. hence, the program crashes.

your primary problem is that you need to make a call to GetAttachedSurface() which will attach lpddsback to the primary surface. only after you attach the backbuffer to the primary surface can you make calls using lpddsback.

also, you need a ddscaps structure to send along with lpddsback when you call GetAttachedSurface().

good luck

www.ChippedDagger.com"They that can give up essential liberty to obtain temporary safety deserve neither." -- Benjamin Franklin"If opportunity doesn't knock, build a door." -- Milton Berle

This topic is closed to new replies.

Advertisement