Archived

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

Kasooi

I cannot figure this out...

Recommended Posts

Kasooi    122
I have tried every possible thing to get this to work:
// PROG10_6.CPP - a 640x480x8 bitmap loader


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

#define WIN32_LEAN_AND_MEAN  

#include <windows.h>   // include important windows stuff

#include <windowsx.h> 
#include <mmsystem.h>
#include <iostream.h> // 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>  // 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

#define _RGB16BIT(r,g,b) ((b%32) + ((g%32) << 5) + ((r%32) << 10))

// 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


LPDIRECTDRAW         lpdd         = NULL;  // dd object

LPDIRECTDRAWSURFACE  lpddsprimary = NULL;  // dd primary surface

LPDIRECTDRAWSURFACE  lpddsback    = NULL;  // dd back surface

LPDIRECTDRAWPALETTE  lpddpal      = NULL;  // a pointer to the created dd palette

PALETTEENTRY         palette[256];         // color palette

DDSURFACEDESC        ddsd;                 // a direct draw surface description struct

DDSCAPS              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 (DirectDrawCreate(NULL,&lpdd,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)!=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(primary_buffer);

// 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("\nconverting 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; index<bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight; index++)
       {
       // extract RGB components (in BGR order), note the scaling

       UCHAR blue  = (temp_buffer[index*3 + 0] >> 3),
             green = (temp_buffer[index*3 + 1] >> 3),
             red   = (temp_buffer[index*3 + 2] >> 3);

       // build up 16 bit color word

       USHORT color = _RGB16BIT(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("\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 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
Its something with bitmaps... You guys said it was because I was reffering to a NULL somewhere. But I got rid of the NULL's and it didn't help anything. If someone could just try compiling this and telling me whats wrong with it, I will be forever grateful to you. And I have debugged it as good as I can too... [edited by - kasooi on October 11, 2003 9:48:58 PM]

Share this post


Link to post
Share on other sites
XDarkScar    122
For some odd reason I can paste it down. Also if GameDevs staff hasn''t fix it I think when you copy out of a source box it is all on one line. Might link of linking the file. Also I have no clue how to fix this. Just throwing this in the air.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
quote:
Original post by XDarkScar
For some odd reason I can paste it down. Also if GameDevs staff hasn''t fix it I think when you copy out of a source box it is all on one line.

Press the "Edit" link and copy from the "Message:" box.

Share this post


Link to post
Share on other sites
Kasooi    122
Here is all the stuff in a zip file, even the image I'm trying to load.
.Zip file

Can anyone solve this please? I cannot figure it out...

[edited by - kasooi on October 18, 2003 5:49:40 PM]

Share this post


Link to post
Share on other sites