Hi, I'm trying to load a 24 bit image, and then render it on the primary surface via DirectX. The application compiles fine, but quits with an appcrash error. What is wrong?
Game.cpp
Dexterous.cppCode:/*************************************************************************/ // Called in this order // Code to initialize game - called once #include "main.h" // your header file // Global varables for this source file LPDIRECTDRAW7 lpdd = NULL; // dd object LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface LPDIRECTDRAWSURFACE7 lpddssecondary = NULL; // dd back surface LPDIRECTDRAWSURFACE7 lpoffscreen = NULL; // offscreen working surface LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd 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 int Game_Init(void *parms) { // this function is where you do all the initialization // for your game log_file = fopen("log.txt","w"); debug("Initializing Game...\n\n\n"); // create object and test for error if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL) == DD_OK) debug("-> DirectDraw Object Created Successfully\n\n"); else { debug("***Error creating DDraw object***\n\n\n"); return(0); } // set cooperation level to windowed mode normal if (lpdd->SetCooperativeLevel(g_hwnd, DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT) == DD_OK) debug("-> Cooperation Level Set\n\n"); else { debug("***Couldn't set cooperation level***\n\n\n"); return(0); } // set the display mode if (lpdd->SetDisplayMode(WINDOW_WIDTH,WINDOW_HEIGHT,BITS,0,0) == DD_OK) debug("-> Display Mode Set\n\n"); else { debug("***Failed to set display mode***\n\n\n"); return(0); } // Create the primary surface memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; // For secondary surface ddsd.dwBackBufferCount = 1; if (lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL) == DD_OK) debug("-> Primary Surface Created at lpddsprimary\n\n"); else { debug("***Error Creating Primary Surface***\n\n\n"); return(0); } ddscaps.dwCaps = DDSCAPS_BACKBUFFER; if (lpddsprimary->GetAttachedSurface(&ddscaps,&lpddssecondary) == DD_OK) debug("-> Secondary Surface Created at lpddssecondary off of lpddsprimary\n\n"); else { debug("***Error Creating Secondary Surface***\n\n\n"); return(0); } // For Offscreen surface ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; // set dimensions ddsd.dwWidth = 600; ddsd.dwHeight = 400; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; // create offscreen surface if (lpdd->CreateSurface(&ddsd,&lpoffscreen,NULL) == DD_OK) debug("-> Offscreen Surface Created at lpoffscreen\n\n"); else { debug("***Error Creating Offscreen Surface***\n\n\n"); return(0); } if(!Load_Bitmap_File(&bitmap, "image.bmp")) { debug("***Couldn't Load Bitmap***"); return(0); } else debug("-> Loaded bitmap"); debug("Done\n\n\n"); // return success return(1); } // end Game_Init /**************************************************************************/ // Main Game - loops // 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! int Game_Main(void *parms) { // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE)) PostMessage(g_hwnd, 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 < WINDOW_HEIGHT; y++) { // copy the line memcpy(&primary_buffer[y*ddsd.lPitch], // dest address &bitmap.buffer[y*WINDOW_WIDTH*4], // src address WINDOW_WIDTH*4); // bytes to copy } // end for y // unlock the surface lpddsprimary->Unlock(NULL); // return success return(1); } // end Game_Main /*************************************************************************/ // Called before WM_DESTROY int Game_Shutdown(void *parms) { // this function is where you shutdown your game and // release all resources that you allocated debug("Shutting Game down...\n\n\n"); // release attached surface first if (lpddssecondary!=NULL) lpddssecondary->Release(); debug("-> Released Secondary Surface\n\n"); // first release the primary surface if (lpddsprimary!=NULL) lpddsprimary->Release(); debug("-> Released Primary Surface\n\n"); // release offscreen surface if (lpoffscreen!=NULL) lpoffscreen->Release(); debug("-> Released Offscreen Surface\n\n"); // release the directdraw object if (lpdd!=NULL) lpdd->Release(); debug("-> Released DirectDraw Object\n\n"); if(!Unload_Bitmap_File(&bitmap)) debug("***Failed to unload bitmap***"); else debug("-> Unloaded bitmap\n\n"); debug("Done\n"); fclose(log_file); // return success return(1); } // end Game_Shutdown
main.hCode:#include "main.h" void debug(char *text) { fprintf(log_file,"%s",text); } /***************************************************************************/ 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 char *buffer; 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 16, 24, or 32 bit then simply read it if (bitmap->bitmapinfoheader.biBitCount == 16 || bitmap->bitmapinfoheader.biBitCount == 24 || bitmap->bitmapinfoheader.biBitCount == 32) { // 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 { debug("***8-bit image***"); return(0); } // end if // write the file info out sprintf(buffer,"-> Bitmap Information\n\n\tfilename:%s \n\tsize=%d \n\twidth=%d \n\theight=%d \n\tbitsperpixel=%d \n\tcolors=%d \n\timpcolors=%d\n\n", filename, bitmap->bitmapinfoheader.biSizeImage, bitmap->bitmapinfoheader.biWidth, bitmap->bitmapinfoheader.biHeight, bitmap->bitmapinfoheader.biBitCount, bitmap->bitmapinfoheader.biClrUsed, bitmap->bitmapinfoheader.biClrImportant); debug(buffer); // 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
There is also another file, title Windows.cpp. That file is definately not the problem, since it's only initializing the standard window and calling the game functions.Code:// Compiler Includes #include <windows.h> // include important windows stuff #include <windowsx.h> #include <mmsystem.h> #include <iostream> // include important C/C++ stuff #include <conio.h> #include <stdlib.h> #include <malloc.h> #include <memory.h> #include <string.h> #include <stdarg.h> #include <stdio.h> #include <math.h> #include <io.h> #include <fcntl.h> #include <ddraw.h> // Project Includes // Defines #define WINDOW_TITLE "Dexterous" #define WINDOW_WIDTH 1280 #define WINDOW_HEIGHT 1024 #define BITS 24 #define _RGB24BIT(r,g,b) ((b) + ((g) << 8) + ((r) << 16)) #define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24)) #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) // Typedefs // 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 Game_Init(void *parms=NULL); int Game_Shutdown(void *parms=NULL); int Game_Main(void *parms=NULL); void debug(char *text); 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); // Global Variables extern HWND g_hwnd; // save the window handle extern HINSTANCE g_hInstance; // save the instance extern FILE *log_file; extern BITMAP_FILE bitmap; // a bitmap file
Help is very appreciated, thanks!
P.S. I have this feeling the error or bug is in Game_Main, specifically where it tries to copy memory onto the primary surface...



LinkBack URL
About LinkBacks




I'll try looking