Jump to content
  • Advertisement

Archived

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

Kasooi

I cannot figure this out...

This topic is 5387 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

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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!