Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Project not responding help.

I'm trying to learn about game programming and I'm using windows game programming for dummies. The thing is in chapter 10 when I use the code for loading a bitmap it compiles fine (two warnings about ps and hdc though) but when I try to run the program it stops working giving that project.exe has stopped working message. I'm using vista now days and directx 8.0 sdk.

Here's the code from the book plus a couple alterations so it works with visual studio 9. Can anyone help?

// PROG10_6.CPP - a 640x480x8 bitmap loader

// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#define INITGUID
#undef UNICODE

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

#include // directX includes

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

// defines for windows
#define WINDOW_CLASS_NAME "WINXCLASS" // class name

#define WINDOW_WIDTH 640 // size of window
#define WINDOW_HEIGHT 480
#define SCREEN_WIDTH 640 // size of screen
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8 // bits per pixel

#define BITMAP_ID 0x4D42 // universal id for a bitmap

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

// these read the keyboard asynchronously
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))

// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))


// 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
PALETTEENTRY palette[256]; // we will store the palette here
UCHAR *buffer; // this is a pointer to the data

} BITMAP_FILE, *BITMAP_FILE_PTR;

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

int Game_Init(void *parms=NULL);
int Game_Shutdown(void *parms=NULL);
int Game_Main(void *parms=NULL);

int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename);
int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);

// GLOBALS ////////////////////////////////////////////////

HWND main_window_handle = NULL; // save the window handle
HINSTANCE main_instance = NULL; // save the instance
char buffer[80]; // used to print text

LPDIRECTDRAW7 lpdd = NULL; // dd object
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE7 lpddsback = NULL; // dd back surface
LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
PALETTEENTRY palette[256]; // color palette
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
DDSCAPS2 ddscaps; // a direct draw surface capabilities struct
HRESULT ddrval; // result back from dd calls
UCHAR *primary_buffer = NULL; // primary video buffer
BITMAP_FILE bitmap16bit, // a 16 bit bitmap file
bitmap8bit; // a 8 bit bitmap file

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

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

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

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

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

case WM_DESTROY:
{
// kill the application
PostQuitMessage(0);
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

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

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

WNDCLASS winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
HDC hdc; // generic dc
PAINTSTRUCT ps; // generic paintstruct

// first fill in the window class stucture
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;

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

// create the window, note the use of WS_POPUP
if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
"WinX Game Console", // title
WS_POPUP | WS_VISIBLE,
0,0, // x,y
WINDOW_WIDTH, // width
WINDOW_HEIGHT, // height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance
NULL))) // creation parms
return(0);

// hide the mouse
ShowCursor(FALSE);

// save the window handle and instance in a global
main_window_handle = hwnd;
main_instance = hinstance;

// perform all game console specific initialization
Game_Init();

// enter main event loop
while(1)
{
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

// shutdown game and release all resources
Game_Shutdown();

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

} // end WinMain

// WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////

int Game_Init(void *parms)
{
// this function is where you do all the initialization
// for your game

// create object and test for error
if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)
return(0);


// set cooperation level to windowed mode normal
if (lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)
return(0);

// set the display mode
if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)!=DD_OK)
return(0);

// Create the primary surface
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

if (lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)
return(0);

// create and attach palette

// create palette data
// first clear out all the entries, defensive programming
memset(palette,0,256*sizeof(PALETTEENTRY));

// create a R,G,B,GR gradient palette
for (int index=0; index < 256; index++)
{
// set flags
palette[index].peFlags = PC_NOCOLLAPSE;
} // end for index

// now create the palette object
if (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
palette,&lpddpal,NULL)!=DD_OK)
return(0);

// attach the palette to the primary
if (lpddsprimary->SetPalette(lpddpal)!=DD_OK)
return(0);

// now load the 8 bit color bitmap
Load_Bitmap_File(&bitmap8bit, "ANDRE8.BMP");

// now load the palette into the directdraw
lpddpal->SetEntries(0,0,256,bitmap8bit.palette);

// return success
return(1);

} // end Game_Init

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

int Game_Shutdown(void *parms)
{
// this function is where you shutdown your game and
// release all resources that you allocated

// first release the primary surface
if (lpddsprimary!=NULL)
lpddsprimary->Release();

// release the directdraw object
if (lpdd!=NULL)
lpdd->Release();

// delete the bitmap
Unload_Bitmap_File(&bitmap8bit);

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

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

int Game_Main(void *parms)
{
// this is the workhorse of your game it will be called
// continuously in real-time this is like main() in C
// all the calls for you game go here!

// check of user is trying to exit
if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))
PostMessage(main_window_handle, WM_DESTROY,0,0);

// set up the surface description to lock the surface
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

// lock the primary surface, note in a real game you would
lpddsprimary->Lock(NULL,&ddsd,
DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer
primary_buffer = (UCHAR *)ddsd.lpSurface;

// copy each bitmap line into primary buffer
// taking into consideration non-linear video
// cards and the memory pitch lPitch
for (int y=0; y < SCREEN_HEIGHT; y++)
{
// copy the line
memcpy(&primary_buffer[y*ddsd.lPitch], // dest address
&bitmap8bit.buffer[y*SCREEN_WIDTH], // src address
SCREEN_WIDTH); // bytes to copy
} // end for y

// unlock the surface
lpddsprimary->Unlock(NULL);

// return success
return(1);

} // end Game_Main

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

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
index; // looping index

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));

// now load the color palette if there is one
if (bitmap->bitmapinfoheader.biBitCount == 8)
{
_lread(file_handle, &bitmap->palette,256*sizeof(PALETTEENTRY));

// now set all the flags in the palette correctly and fix the reversed
// BGR RGBQUAD data format
for (index=0; index < 256; index++)
{
// reverse the red and green fields
int temp_color = bitmap->palette[index].peRed;
bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
bitmap->palette[index].peBlue = temp_color;

// always set the flags word to this
bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
} // end for index

} // end if

// 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)
{
// 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
{
// this must be a 24 bit image, load it in and convert it to 16 bit
// printf("
converting 24 bit image...");

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

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

// allocate final 16 bit storage buffer
if (!(bitmap->buffer=(UCHAR *)malloc(2*bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight)))
{
// close the file
_lclose(file_handle);

// release working buffer
free(temp_buffer);

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

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

// now convert each 24 bit RGB value into a 16 bit value
for (index=0; indexbitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight; index++)
{
// extract RGB components (note they are in memory BGR)
// also, assume 5.6.5 format, so scale appropriately
UCHAR red = (temp_buffer[index*3 + 2] >> 3), // 5 bits
green = (temp_buffer[index*3 + 1] >> 2), // 6 bits, change to 3 for 5 bits
blue = (temp_buffer[index*3 + 0] >> 3); // 5 bits

// build up 16 bit color word assume 5.6.5 format
USHORT color = _RGB16BIT565(red,green,blue);

// write color to buffer
((USHORT *)bitmap->buffer)[index] = color;

} // end for index

// finally write out the correct number of bits
bitmap->bitmapinfoheader.biBitCount=16;

} // end if

#if 0
// write the file info out
printf("
filename:%s
size=%d
width=%d
height=%d
bitsperpixel=%d
colors=%d
impcolors=%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 upside down .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(&image[((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

Comments

  • MT2002MT2002 Member Posts: 1,444
    Windows only displays "Not Responding" if, and only if, the window is not responding to the messages being sent to that window procedure. This is handled by you in your message loop.

    So, if your message loop is never getting reached, you have an infinity loop somewhere (Or similar). The best advice I can give you is to step through your code with a debugger to see what is happening.

    Better advice would be NOT to use that code. As a reader of his Tricks books (Yes, I know who the author of your book is); his code is *very* bad. They are great books, however most of the programming practices he teaches are not used anymore. Not to mention, there are alot of design and general programming issues with his code.

    His books are great, and I recommend keeping them--but please write your own code. You will learn more that way, anyways.

    (For reference, just in case you did not know, DirectDraw should be considered deprecated)

    [hr][size=1][leftbr].:EvolutionEngine[rightbr][leftbr].:MicroOS Operating System[rightbr][leftbr][link=http://www.brokenthorn.com]Website :: OS Development Series[rightbr][/link][/size]
  • penguinthpenguinth Member Posts: 2
    : Windows only displays "Not Responding" if, and only if, the window
    : is not responding to the messages being sent to that window
    : procedure. This is handled by you in your message loop.
    :
    : So, if your message loop is never getting reached, you have an
    : infinity loop somewhere (Or similar). The best advice I can give you
    : is to step through your code with a debugger to see what is
    : happening.
    :
    : Better advice would be NOT to use that code. As a reader of his
    : Tricks books (Yes, I know who the author of your book is); his code
    : is *very* bad. They are great books, however most of the programming
    : practices he teaches are not used anymore. Not to mention, there are
    : alot of design and general programming issues with his code.
    :
    : His books are great, and I recommend keeping them--but please write
    : your own code. You will learn more that way, anyways.
    :
    : (For reference, just in case you did not know, DirectDraw should be
    : considered deprecated)
    :
    : [hr][size=1][leftbr].:EvolutionEngine[rightbr][leftbr].:MicroOS
    : Operating
    : System[rightbr][leftbr][link=http://www.brokenthorn.com]Website ::
    : OS Development Series[rightbr][/link][/size]
    :

    Yeah, I plan on writing my own code once I know more. Jut using his to help figure it all out. Thanks though knowing that I probably have an infinite loop somewhere is very helpful. Now I know what to look for anyway.
Sign In or Register to comment.