Jump to content
  • Advertisement
Sign in to follow this  
CJWR

need help with error

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

hello. i need help with finding the cause of the following error message in vc++ 6. main.obj : error LNK2005: "struct BITMAP_FILE_TAG bitmap" (?bitmap@@3UBITMAP_FILE_TAG@@A) already defined in image.obj the following are my code files: the following is the main program file
//main.cpp

// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN  // just say no to MFC
#define INITGUID
#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> // include directdraw
#include <iostream.h>
#include <fstream.h>

#include "image.h"

// 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      8    // bits per pixel

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

#define TILE_SIZE 21    //size of a tile for the map
#define NUM_TILES_X 40  //number of tiles in X
#define NUM_TILES_Y 28  //number of tiles in Y
#define NUM_TILES NUM_TILES_X*NUM_TILES_Y //number of tiles the screen is made up of (x*y)
#define TILE_TYPES 400  //number of different tiles

//player defines
#define PLAYER_SPEED 3 //the speed that the player walks

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

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

int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color);

int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap, LPDIRECTDRAWSURFACE4 lpdds, int cx,int cy);

LPDIRECTDRAWSURFACE4 DDraw_Create_Surface(int width, int height, int mem_flags, int color_key);

int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE4 source, int x, int y, 
                      int width, int height, LPDIRECTDRAWSURFACE4 dest, 
                      int transparent);    

LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds,
                                         int num_rects,
                                         LPRECT clip_list);

int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE4 lpdds);

void load_map(); //function to load a map from disk

//display functions
int Draw_Background();
int Draw_Middleground();
int Draw_Foreground();
int Draw_Info();

void player_move(); //function to handle player movement

/*
int Draw_Aliens();
int Draw_Missles();
int Draw_PowerUps();
int Draw_BEAM();

void update_frames();
*/
// MACROS /////////////////////////////////////////////////
// tests if a key is up or down
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

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

// 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         lpdd         = 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
PALETTEENTRY          palette[256];          // color palette
PALETTEENTRY          save_palette[256];     // used to save palettes
DDSURFACEDESC2        ddsd;                  // a direct draw surface description struct
DDBLTFX               ddbltfx;               // used to fill
DDSCAPS2              ddscaps;               // a direct draw surface capabilities struct
HRESULT               ddrval;                // result back from dd calls
DWORD                 start_clock_count = 0; // used for timing
/*
BITMAP_FILE           bitmap;                // holds the bitmap
*/
LPDIRECTDRAWSURFACE4 tiles[TILE_TYPES];               //the tiles for the background image

LPDIRECTDRAWSURFACE4 console;			     //holds the interface at the bottom of the screen.
LPDIRECTDRAWSURFACE4 lpddsbackground = NULL; //this will hold the background image
LPDIRECTDRAWSURFACE4 player;                 //holds the player graphics
/*
LPDIRECTDRAWSURFACE4 ship[2];                //bitmap images of ship
*/
int GAME_STATE = 0; //holds the game state 0 = intro, 1 = play, 2 = pause, 3 = done

char buffer[80];                             // general printing buffer

int gwidth  = -1;
int gheight = -1;

int GPT = 0;         //used in pausing the game

int map[40][28][3] = {0}; //the map
int edges[4][24] = {0}; //the edges that the player and other characters are not allowed to pass

int player_x; //x location of the player
int player_y; //y location of the player

IMAGE to_test;

//prototypes2
int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,LPDIRECTDRAWSURFACE4 lpdds=lpddsback);

// FUNCTIONS ////////////////////////////////////////////////
void load_map(){
	//load map from file called map.awm
	ifstream i_file("map.awm");
	for(int i = 0; i < 3; i++){
		for(int j = 0; j < NUM_TILES_Y; j++){
			for(int k = 0; k < NUM_TILES_X; k++){
				i_file >> map[k][j];
			}
		}
	}
}

void player_move(){
	int player_tile_x = player_x/(TILE_SIZE-1);
	int player_tile_y = player_y/(TILE_SIZE-1);
	
	if(KEYDOWN(VK_UP)){
		if(map[player_tile_x][player_tile_y-1][0] == 0){ 
			int edge = (player_tile_y)*(TILE_SIZE-1);
			//find the last pixel we can move this way
			if(player_y > edge+5){
			//make sure that the player is below the edge
				player_y = player_y - PLAYER_SPEED; //move the player up the screen
			}
		}
		else{
			player_y = player_y - PLAYER_SPEED;
		}
	}

	if (KEYDOWN(VK_DOWN)){
		if(map[player_tile_x][player_tile_y+2][0] == 0){ 
			int edge = (player_tile_y-2)*(TILE_SIZE-1);
			//find the last pixel we can move this way
			if(player_y < edge-5){
			//make sure that the player is above the edge
				player_y = player_y + PLAYER_SPEED; //move the player down the screen
			}
		}
		else{
			player_y = player_y + PLAYER_SPEED;
		}
	}
	if (KEYDOWN(VK_LEFT)){
		player_x = player_x - PLAYER_SPEED;
	}
	if (KEYDOWN(VK_RIGHT)){
		player_x = player_x + PLAYER_SPEED;
	}

	//make sure it is impossible for the player to leave the game area
	if(player_x >= 780){
		player_x = 780;
	}
	else if(player_x <= 0){
		player_x = 0;
	}
	else;
	if(player_y >= 520){
		player_y = 520;
	}
	else if(player_y <= 0){
		player_y = 0;
	}
	else;

}
/*
void update_frames(){
	ship_till_next--;

	//check if ship needs to be updated, if so, update
	if(ship_till_next <= 0){
		if(frame_ship == 0){
			frame_ship = 1;
		}
		else if(frame_ship == 1){
			frame_ship = 0;
		}
		else frame_ship = 0;
		ship_till_next = 10;
	}
}
*/

int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,
                   LPDIRECTDRAWSURFACE4 lpdds)
{
// this function uses directdraw to draw a filled rectangle

DDBLTFX ddbltfx; // this contains the DDBLTFX structure
RECT fill_area;  // this contains the destination rectangle

// clear out the structure and set the size field 
DDRAW_INIT_STRUCT(ddbltfx);

// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color; 

// fill in the destination rectangle data (your data)
fill_area.top    = y1;
fill_area.left   = x1;
fill_area.bottom = y2+1;
fill_area.right  = x2+1;

// ready to blt to surface, in this case blt to primary
lpdds->Blt(&fill_area, // ptr to dest rectangle
           NULL,       // ptr to source surface, NA            
           NULL,       // ptr to source rectangle, NA
           DDBLT_COLORFILL | DDBLT_WAIT | DDBLT_ASYNC,   // fill and wait                   
           &ddbltfx);  // ptr to DDBLTFX structure

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

int Draw_Background(){
	//draw background
	Draw_Rectangle(0,0,SCREEN_WIDTH-1, SCREEN_HEIGHT-1,0); //background
	for(int i = 0; i < NUM_TILES_Y; i++){
		for(int j = 0; j < NUM_TILES_X; j++){
			if(map[j][0] != 0){
				DDraw_Draw_Surface(tiles[map[j][0]],j*(TILE_SIZE-1),i*(TILE_SIZE-1),
					               TILE_SIZE,TILE_SIZE,lpddsback,1);
			}
		}
	}
/*
	for(int j = 0; j < 28; j++){
		for(int i = 0; i < 40; i++){
			if(back[map_location] != 0){
				DDraw_Draw_Surface(tiles[back[map_location]],i*(TILE_SIZE-1),j*(TILE_SIZE-1),
					               TILE_SIZE,TILE_SIZE,lpddsback,1);
			}
			map_location++;
		}
	}*/
	return 0;
}

int Draw_Middleground(){
	//draw middleground
	for(int i = 0; i < NUM_TILES_Y; i++){
		for(int j = 0; j < NUM_TILES_X; j++){
			if(map[j][1] != 0){
				DDraw_Draw_Surface(tiles[map[j][1]],j*(TILE_SIZE-1),i*(TILE_SIZE-1),
					               TILE_SIZE,TILE_SIZE,lpddsback,1);
			}
		}
	}
	DDraw_Draw_Surface(player,player_x,player_y,20,42,lpddsback,1);


	return 0;
}

int Draw_Foreground(){
	//draw the foreground
	for(int i = 0; i < NUM_TILES_Y; i++){
		for(int j = 0; j < NUM_TILES_X; j++){
			if(map[j][2] != 0){
				DDraw_Draw_Surface(tiles[map[j][2]],j*(TILE_SIZE-1),i*(TILE_SIZE-1),
					               TILE_SIZE,TILE_SIZE,lpddsback,1);
			}
		}
	}
	return 0;
}

int Draw_Info(){
	//draws the information
	DDraw_Draw_Surface(console,0,560,800,40,lpddsback,1);
	return 0;
}

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,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));

   // now set all the flags in the palette correctly and fix the reversed 
   // BGR RGBQUAD data format
   for (index=0; index < MAX_COLORS_PALETTE; 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 || 
    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(&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

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

LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds,
                                         int num_rects,
                                         LPRECT clip_list)

{
// this function creates a clipper from the sent clip list and attaches
// it to the sent surface

int index;                         // looping var
LPDIRECTDRAWCLIPPER lpddclipper;   // pointer to the newly created dd clipper
LPRGNDATA region_data;             // pointer to the region data that contains
                                   // the header and clip list

// first create the direct draw clipper
if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
   return(NULL);

// now create the clip list from the sent data

// first allocate memory for region data
region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));

// now copy the rects into region data
memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);

// set up fields of header
region_data->rdh.dwSize          = sizeof(RGNDATAHEADER);
region_data->rdh.iType           = RDH_RECTANGLES;
region_data->rdh.nCount          = num_rects;
region_data->rdh.nRgnSize        = num_rects*sizeof(RECT);

region_data->rdh.rcBound.left    =  64000;
region_data->rdh.rcBound.top     =  64000;
region_data->rdh.rcBound.right   = -64000;
region_data->rdh.rcBound.bottom  = -64000;

// find bounds of all clipping regions
for (index=0; index<num_rects; index++)
    {
    // test if the next rectangle unioned with the current bound is larger
    if (clip_list[index].left < region_data->rdh.rcBound.left)
       region_data->rdh.rcBound.left = clip_list[index].left;

    if (clip_list[index].right > region_data->rdh.rcBound.right)
       region_data->rdh.rcBound.right = clip_list[index].right;

    if (clip_list[index].top < region_data->rdh.rcBound.top)
       region_data->rdh.rcBound.top = clip_list[index].top;

    if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
       region_data->rdh.rcBound.bottom = clip_list[index].bottom;

    } // end for index

// now we have computed the bounding rectangle region and set up the data
// now let's set the clipping list

if (FAILED(lpddclipper->SetClipList(region_data, 0)))
   {
   // release memory and return error
   free(region_data);
   return(NULL);
   } // end if

// now attach the clipper to the surface
if (FAILED(lpdds->SetClipper(lpddclipper)))
   {
   // release memory and return error
   free(region_data);
   return(NULL);
   } // end if

// all is well, so release memory and send back the pointer to the new clipper
free(region_data);
return(lpddclipper);

} // end DDraw_Attach_Clipper

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

int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure

// clear out the structure and set the size field 
DDRAW_INIT_STRUCT(ddbltfx);

// set the dwfillcolor field to the desired color
ddbltfx.dwFillColor = color; 

// ready to blt to surface
lpdds->Blt(NULL,       // ptr to dest rectangle
           NULL,       // ptr to source surface, NA            
           NULL,       // ptr to source rectangle, NA
           DDBLT_COLORFILL | DDBLT_WAIT,   // fill and wait                   
           &ddbltfx);  // ptr to DDBLTFX structure

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

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

int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE4 source, // source surface to draw
                      int x, int y,                 // position to draw at
                      int width, int height,        // size of source surface
                      LPDIRECTDRAWSURFACE4 dest,    // surface to draw the surface on
                      int transparent = 1)          // transparency flag
{
// draw a bob at the x,y defined in the BOB
// on the destination surface defined in dest

RECT dest_rect,   // the destination rectangle
     source_rect; // the source rectangle                             

// fill in the destination rect
dest_rect.left   = x;
dest_rect.top    = y;
dest_rect.right  = x+width-1;
dest_rect.bottom = y+height-1;

// fill in the source rect
source_rect.left    = 0;
source_rect.top     = 0;
source_rect.right   = width-1;
source_rect.bottom  = height-1;

// test transparency flag

if (transparent)
   {
   // enable color key blit
   // blt to destination surface
   if (FAILED(dest->Blt(&dest_rect, source,
                     &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
                     NULL)))
           return(0);

   } // end if
else
   {
   // perform blit without color key
   // blt to destination surface
   if (FAILED(dest->Blt(&dest_rect, source,
                     &source_rect,(DDBLT_WAIT),
                     NULL)))
           return(0);

   } // end if

// return success
return(1);

} // end DDraw_Draw_Surface

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

int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap,     // bitmap file to scan image data from
                      LPDIRECTDRAWSURFACE4 lpdds, // surface to hold data
                      int cx, int cy)             // cell to scan image from
{
// this function extracts a bitmap out of a bitmap file

UCHAR *source_ptr,   // working pointers
      *dest_ptr;

DDSURFACEDESC2 ddsd;  //  direct draw surface description 

// get the addr to destination surface memory

// set size of the structure
ddsd.dwSize = sizeof(ddsd);

// lock the display surface
lpdds->Lock(NULL,
            &ddsd,
            DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
            NULL);

// compute position to start scanning bits from
//cx = cx*(ddsd.dwWidth+1) + 1;
//cy = cy*(ddsd.dwHeight+1) + 1;

gwidth  = ddsd.dwWidth;
gheight = ddsd.dwHeight;

int pitch = ((bitmap->bitmapinfoheader.biWidth + 3)&(~3))*(bitmap->bitmapinfoheader.biBitCount/8);

// extract bitmap data
source_ptr = bitmap->buffer + cy*pitch+cx;

// assign a pointer to the memory surface for manipulation
dest_ptr = (UCHAR *)ddsd.lpSurface;

// iterate thru each scanline and copy bitmap
for (int index_y=0; index_y < ddsd.dwHeight; index_y++)
    {
    // copy next line of data to destination
    memcpy(dest_ptr, source_ptr, ddsd.dwWidth*(bitmap->bitmapinfoheader.biBitCount/8));

    // advance pointers
    dest_ptr   += (ddsd.lPitch);
    // source_ptr += bitmap->bitmapinfoheader.biWidth;
	source_ptr += pitch;
    } // end for index_y

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

// return success
return(1);

} // end Scan_Image_Bitmap

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

LPDIRECTDRAWSURFACE4 DDraw_Create_Surface(int width, int height, int mem_flags, int ck = 255)
{
// this function creates an offscreen plain surface

DDSURFACEDESC2 ddsd;         // working description
LPDIRECTDRAWSURFACE4 lpdds;  // temporary surface
    
// set to access caps, width, and height
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize  = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

// set dimensions of the new bitmap surface
ddsd.dwWidth  =  width;
ddsd.dwHeight =  height;

// set surface to offscreen plain
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;

// create the surface
if (FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
   return(NULL);

// test if user wants a color key
if (ck >= 0)
   {
   // set color key to color 0
   DDCOLORKEY color_key; // used to set color key
   color_key.dwColorSpaceLowValue  = ck;
   color_key.dwColorSpaceHighValue = ck;

   // now set the color key for source blitting
   lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);
   } // end if

// return surface
return(lpdds);
} // end DDraw_Create_Surface


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

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 Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE4 lpdds)
{
// this function draws the sent text on the sent surface 
// using color index as the color in the palette

HDC xdc; // the working dc

// get the dc from surface
if (FAILED(lpdds->GetDC(&xdc)))
   return(0);

// set the colors for the text up
SetTextColor(xdc,color);

// set background mode to transparent so black isn't copied
SetBkMode(xdc, TRANSPARENT);

// draw the text a
TextOut(xdc,x,y,text,strlen(text));

// release the dc
lpdds->ReleaseDC(xdc);

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

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

int Game_Main(void *parms = NULL, int num_parms = 0)
{
	int index; // general looping variable

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

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

	GPT = GPT - 1;
//  Missle_TIME = Missle_TIME - 1;
	
	
    //draw all the graphics
    Draw_Background();
	Draw_Middleground();
	Draw_Foreground();
	Draw_Info();

	//pause game
	if (KEYDOWN(VK_TAB)){
		if(GPT < 0){ 
		    GAME_STATE = 2;
			GPT = 33;
		}
	}

	player_move(); //handle player movement

	// draw the info
    sprintf(buffer,"The Ancient West - alpha"); //title
	Draw_Text_GDI(buffer, 1,566, 255, lpddsback);
	sprintf(buffer,"Copyright 2005 Charles Reed"); //title
	Draw_Text_GDI(buffer, 1,582, 255, lpddsback);

	to_test.print(100,100,20,42,lpddsback,1);
	
	// flip pages
	while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

	// clear the drawing surface
	DDraw_Fill_Surface(lpddsback, 0);

	// wait a sec
	Sleep(30);

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

int Game_Intro(){
	if(window_closed)
		return(0);
	Draw_Rectangle(0,0,SCREEN_WIDTH-1, SCREEN_HEIGHT-1,0); //clear screen
	load_map();

	player_x = 400;
	player_y = 300;
	
	GAME_STATE = 1;
	return 0;
}

int Game_Paused(){
	// make sure this isn't executed again
	if(window_closed)
		return(0);
	char buffer[80]; // used to print text
	Draw_Rectangle(0,0,SCREEN_WIDTH-1, SCREEN_HEIGHT-1,0); //clear screen
    sprintf(buffer,"GAME PAUSED: TAB TO UNPAUSE"); //pause
	Draw_Text_GDI(buffer, 200,231, 255, lpddsback);
	GPT = GPT - 1;
	if(KEYDOWN(VK_TAB)){
	   if(GPT < 0){
          GPT = 33;
	      GAME_STATE = 1;
		}
	}
	// flip the surfaces
	while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

    // sync to 33ish fps
    Sleep(30);
	if(KEYDOWN(VK_ESCAPE)){
		PostMessage(main_window_handle,WM_CLOSE,0,0);
		window_closed = 1;
	}   // end if
	return 0;
}

int Game_Done(){
/*	// make sure this isn't executed again
	if(window_closed)
		return(0);
	Draw_Rectangle(0,0,SCREEN_WIDTH-1, SCREEN_HEIGHT-1,0);
   	sprintf(buffer,"GAME OVER"); //pause
	Draw_Text_GDI(buffer, 200,231, 255, lpddsback);
	sprintf(buffer,"TRY AGAIN: TAB");
	Draw_Text_GDI(buffer, 200,247, 255, lpddsback);
	sprintf(buffer,"QUIT: ESCAPE"); //pause
	Draw_Text_GDI(buffer, 200,263, 255, lpddsback);
	sprintf(buffer,"SCORE: %d", score); //pause
	Draw_Text_GDI(buffer, 200,279, 255, lpddsback);
	// flip the surfaces
    while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
    // sync to 33ish fps
    Sleep(30);
	if(KEYDOWN(VK_TAB)){
		GAME_STATE = 0;
	}    
	if(KEYDOWN(VK_ESCAPE)){
		PostMessage(main_window_handle,WM_CLOSE,0,0);
		window_closed = 1;
	}   // end if
	return 0; */
	GAME_STATE = 1;
	return 0;
}

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

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 *)&lpdd)))
	   return(0);

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

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

	// we need a complex surface system with a primary and backbuffer

// 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(lpdd->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;

// get the attached back buffer surface
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
  return(0);

// build up the palette data array
for (int color=1; color < 255; color++)
    {
    // fill with random RGB values
    palette[color].peRed   = rand()%256;
    palette[color].peGreen = rand()%256;
    palette[color].peBlue  = rand()%256;

    // set flags field to PC_NOCOLLAPSE
    palette[color].peFlags = PC_NOCOLLAPSE;
    } // end for color

// now fill in entry 0 and 255 with black and white
palette[0].peRed     = 0;
palette[0].peGreen   = 0;
palette[0].peBlue    = 0;
palette[0].peFlags   = PC_NOCOLLAPSE;

palette[255].peRed   = 255;
palette[255].peGreen = 255;
palette[255].peBlue  = 255;
palette[255].peFlags = PC_NOCOLLAPSE;

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

// finally attach the palette to the primary surface
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
   return(0);

// set clipper up on back buffer since that's where well clip
RECT screen_rect= {0,0,SCREEN_WIDTH,SCREEN_HEIGHT};
lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect);

// load the 8-bit image
if (!Load_Bitmap_File(&bitmap,"graphics.bmp"))
   return(0);

// load it's palette into directdraw
if (FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette)))
   return(0);

// clean the surfaces
DDraw_Fill_Surface(lpddsprimary,0);
DDraw_Fill_Surface(lpddsback,0);

// create the buffer to hold the background
lpddsbackground = DDraw_Create_Surface(800,600,0,-1);

// copy the background bitmap image to the background surface 

// lock the surface
lpddsbackground->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer to primary surfce
UCHAR *image_buffer = (UCHAR *)ddsd.lpSurface;       

	// test if memory is linear
	if (ddsd.lPitch == SCREEN_WIDTH){
	  // copy memory from double buffer to primary buffer
	  memcpy((void *)image_buffer, (void *)bitmap.buffer, SCREEN_WIDTH*SCREEN_HEIGHT);
	} // end if
	else{ // non-linear

	  // make copy of source and destination addresses
	  UCHAR *dest_ptr = image_buffer;
	  UCHAR *src_ptr  = bitmap.buffer;

	  // memory is non-linear, copy line by line
	  for (int y=0; y < SCREEN_HEIGHT; y++){
		// copy line
	    memcpy((void *)dest_ptr, (void *)src_ptr, SCREEN_WIDTH);

       // advance pointers to next line
       dest_ptr+=ddsd.lPitch;
       src_ptr +=SCREEN_WIDTH;
      } // end for

	} // end else

	// now unlock the primary surface
	if (FAILED(lpddsbackground->Unlock(NULL)))
	   return(0);

	// seed random number generator
	srand(GetTickCount());

	for(int i = 0; i < TILE_TYPES; i++){
		tiles = DDraw_Create_Surface(TILE_SIZE,TILE_SIZE,0,255);
		Scan_Image_Bitmap(&bitmap,tiles,((i%32)*TILE_SIZE)+1,((i/32)*TILE_SIZE)+1);
	}

	console = DDraw_Create_Surface(801,41,0,255);
	Scan_Image_Bitmap(&bitmap,console,0,560);

	player = DDraw_Create_Surface(20,42,0,255);
	Scan_Image_Bitmap(&bitmap,player,1,276);

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

	to_test.load(lpddpal, lpddsprimary, lpddsback, lpdd, &bitmap);

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

// kill all the surfaces


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

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

// now blow away the IDirectDraw4 interface
if (lpdd)
   {
   lpdd->Release();
   lpdd = 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
						    "The Ancient West - a",// 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);

// hide mouse
ShowCursor(FALSE);

// 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
	   if(GAME_STATE == 0){
		   Game_Intro();
	   }
	   else if(GAME_STATE == 1){
		   Game_Main();
	   }
	   else if(GAME_STATE == 2){
		   Game_Paused();
	   }
	   else if(GAME_STATE == 3){
		   Game_Done();
	   }
	   else;
       
	} // end while

// closedown game here
Game_Shutdown();

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

} // end WinMain
[\source]

the following is simply a file where i have stored a bunch of grobal varables. i know this is poor coding, but o well.

//basics.h - header file containing basic types and defines

#ifndef __BASIC__
#define __BASIC__

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

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;

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

#define DDRAW_INIT_STRUCT(ddstruct){ memset(&ddstruct,0,sizeof(ddstruct));ddstruct.dwSize=sizeof(ddstruct); }

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

BITMAP_FILE bitmap; // holds the bitmap

#endif


the following the header file for the image class
//image.h - header file for image class

#ifndef __IMAGE__
#define __IMAGE__

#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> //include directdraw
#include <iostream.h> 
#include <fstream.h> //for file i/o

#include "basics.h"

class IMAGE{
public:
	//constructors
	IMAGE(); //default
	IMAGE(int, int); //normal
	IMAGE(const IMAGE& other); //copy
	
	//public functions
	bool load(LPDIRECTDRAWPALETTE lpddpal, 
		      LPDIRECTDRAWSURFACE4 lpddsprimary,
			  LPDIRECTDRAWSURFACE4 lpddsback,
			  LPDIRECTDRAW4 lpdd,
			  BITMAP_FILE_PTR bitmap); //load an image
	int print(int x, int y,              // position to draw at
			  int width, int height,     // size of source surface
			  LPDIRECTDRAWSURFACE4 dest, // surface to draw the surface on
			  int transparent);          // transparency flag
		      //prints the image onto the surface inputted
	bool vaild(); //returns if the image object contains a vaild image or not
	int get_x(); //returns the size for x of the image
	int get_y(); //return the size for y of the image
	//operators

private:
	//private functions
	int load_file(BITMAP_FILE_PTR bitmap, char *filename); //load the actual file
	int flip_bitmap(UCHAR *image, int, int); //flip the bitmap
	int fill_surface(LPDIRECTDRAWSURFACE4, int); //fill the image with the inputted color
	LPDIRECTDRAWSURFACE4 create_surface(int width, int height, int mem_flags,
										LPDIRECTDRAW4 lpdd, int ck);
		//create the surface to hold the data
	int scan_bitmap(BITMAP_FILE_PTR bitmap, int cx, int cy); // cell to scan image from

	//private member varibles
	//BITMAP_FILE bitmap; // holds the bitmap
	LPDIRECTDRAWSURFACE4 image; //holds the actual image
	int size_x; //holds the image's size for x
	int size_y; //holds the image's size for y
	bool is_vaild; //holds if the image is vaild or not. TRUE = yes
};

#endif
[\source]

the following is the code file for the image class

//image.cpp - source file for the image class

#include "image.h"

//default constructor
IMAGE::IMAGE(){
	is_vaild = true;
}

//normal constructor
IMAGE::IMAGE(int a, int b){
	// = DDraw_Create_Surface(ENGINE_SIZE_X,ENGINE_SIZE_Y,0,255);
	is_vaild = true;
}

//copy constructor
IMAGE::IMAGE(const IMAGE& to_copy){
//	image = to_copy.image; 
	size_x = to_copy.size_x;
	size_y = to_copy.size_y;
	is_vaild = to_copy.is_vaild;
}

bool IMAGE::load(LPDIRECTDRAWPALETTE lpddpal, LPDIRECTDRAWSURFACE4 lpddsprimary,
			     LPDIRECTDRAWSURFACE4 lpddsback, LPDIRECTDRAW4 lpdd, BITMAP_FILE_PTR bitmap2){
	load_file(bitmap2,"graphics2.bmp");

	// load it's palette into directdraw
	if (FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette)))

	// clean the surfaces
	fill_surface(lpddsprimary,0);
	fill_surface(lpddsback,0);
	image = create_surface(20,42,0,lpdd,255);
	scan_bitmap(&bitmap,1,276);

	return false;
} 

int IMAGE::print(int x, int y,             // position to draw at
                 int width, int height,     // size of source surface
                 LPDIRECTDRAWSURFACE4 dest, // surface to draw the surface on
                 int transparent = 1){      // transparency flag
	// draw a bob at the x,y defined in the BOB
	// on the destination surface defined in dest

	RECT dest_rect,   // the destination rectangle
	     source_rect; // the source rectangle                             

	// fill in the destination rect
	dest_rect.left   = x;
	dest_rect.top    = y;
	dest_rect.right  = x+width-1;
	dest_rect.bottom = y+height-1;

	// fill in the source rect
	source_rect.left    = 0;
	source_rect.top     = 0;
	source_rect.right   = width-1;
	source_rect.bottom  = height-1;

	// test transparency flag

	if(transparent){
		// enable color key blit
		// blt to destination surface
		if(FAILED(dest->Blt(&dest_rect, image,
           &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
           NULL))){
			return(0);
		}

	} // end if
	else
	{
		// perform blit without color key
		// blt to destination surface
		if(FAILED(dest->Blt(&dest_rect, image, &source_rect,(DDBLT_WAIT), NULL))){
			return(0);
		}

	} // end if

	return 1;
} 

bool IMAGE::vaild(){
	return is_vaild;
	return true;
}

int IMAGE::get_x(){
	return size_x;
}

int IMAGE::get_y(){
	return size_y;
}

//private functions////////////////////////////////////////////////////////////
int IMAGE::load_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,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));

		// now set all the flags in the palette correctly and fix the reversed 
		// BGR RGBQUAD data format
		for (index=0; index < MAX_COLORS_PALETTE; 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 || 
        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;
}

int IMAGE::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(&image[((height-1) - index)*bytes_per_line],
               &buffer[index*bytes_per_line], bytes_per_line);
	}

	// release the memory
	free(buffer);

	// return success
	return 1;
}

int IMAGE::fill_surface(LPDIRECTDRAWSURFACE4 lpdds, int color){
	DDBLTFX ddbltfx; //this contains the DDBLTFX structure

	//clear out the structure and set the size field 
	DDRAW_INIT_STRUCT(ddbltfx);

	//set the dwfillcolor field to the desired color
	ddbltfx.dwFillColor = color; 

	//ready to blt to surface
	lpdds->Blt(NULL,       // ptr to dest rectangle
		       NULL,       // ptr to source surface, NA            
			   NULL,       // ptr to source rectangle, NA
			   DDBLT_COLORFILL | DDBLT_WAIT,   // fill and wait                   
			   &ddbltfx);  // ptr to DDBLTFX structure

	// return success
	return 1;
} 

LPDIRECTDRAWSURFACE4 IMAGE::create_surface(int width, int height, int mem_flags,
										   LPDIRECTDRAW4 lpdd, int ck = 255){
	// this function creates an offscreen plain surface

	DDSURFACEDESC2 ddsd;         // working description
	LPDIRECTDRAWSURFACE4 lpdds;  // temporary surface
    
	// set to access caps, width, and height
	memset(&ddsd,0,sizeof(ddsd));
	ddsd.dwSize  = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;

	// set dimensions of the new bitmap surface
	ddsd.dwWidth  =  width;
	ddsd.dwHeight =  height;

	// set surface to offscreen plain
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;

	// create the surface
	if (FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
	   return(NULL);

	// test if user wants a color key
	if (ck >= 0)
	{
		// set color key to color 0
		DDCOLORKEY color_key; // used to set color key
		color_key.dwColorSpaceLowValue  = ck;
		color_key.dwColorSpaceHighValue = ck;

		// now set the color key for source blitting
		lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);
	} // end if

	// return surface
	return(lpdds);
} 

int IMAGE::scan_bitmap(BITMAP_FILE_PTR bitmap, int cx, int cy){
	// this function extracts a bitmap out of a bitmap file

	UCHAR *source_ptr,   // working pointers
		  *dest_ptr;

	DDSURFACEDESC2 ddsd;  //  direct draw surface description 

	// get the addr to destination surface memory

	// set size of the structure
	ddsd.dwSize = sizeof(ddsd);

	// lock the display surface
	image->Lock(NULL,
		        &ddsd,
			    DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
				NULL);

	// compute position to start scanning bits from
	//cx = cx*(ddsd.dwWidth+1) + 1;
	//cy = cy*(ddsd.dwHeight+1) + 1;

	int gwidth  = ddsd.dwWidth;
	int gheight = ddsd.dwHeight;

	int pitch = ((bitmap->bitmapinfoheader.biWidth + 3)&(~3))*(bitmap->bitmapinfoheader.biBitCount/8);

	// extract bitmap data
	source_ptr = bitmap->buffer + cy*pitch+cx;

	// assign a pointer to the memory surface for manipulation
	dest_ptr = (UCHAR *)ddsd.lpSurface;

	// iterate thru each scanline and copy bitmap
	for(int index_y=0; index_y < ddsd.dwHeight; index_y++){
		// copy next line of data to destination
		memcpy(dest_ptr, source_ptr, ddsd.dwWidth*(bitmap->bitmapinfoheader.biBitCount/8));

		// advance pointers
		dest_ptr   += (ddsd.lPitch);
		// source_ptr += bitmap->bitmapinfoheader.biWidth;
		source_ptr += pitch;
    }
	
	// unlock the surface 
	image->Unlock(NULL);

	return 1;
}


thank you for any help you can give me. i'm not much of a c++ coder.

Share this post


Link to post
Share on other sites
Advertisement
A C++ golden rule:

Include the bear minimum in your header (.h) files, include in the .cpp files instead.


What's going on here is that something is being included more then once, therefore the linker is getting confused.

Share this post


Link to post
Share on other sites
... you can also forward declare things... so say if you had a User class but didn't want to include it straight away, you could do something like this (though this example probably wont compile, you get the gist)


//User.h

class User
{
public:
int userId;
};


// UserGroup.h
class User; //Forward declares so u can have parameters and variables of this type

class UserGroup
{
public:
User theUser;
void Boo(User sayBooToo);


};


// UserGroup.cpp
#include <iostream.h>
#include "UserGroup.h"
#include "User.h" // Actually get the implementation detail of User


void UserGroup::Boo(User sayBooToo)
{
cout << "boo" << sayBooToo.userId;
}



Share this post


Link to post
Share on other sites
Quote:
Original post by paulecoyote
A C++ golden rule:

Include the bear minimum in your header (.h) files, include in the .cpp files instead.


What's going on here is that something is being included more then once, therefore the linker is getting confused.


alright. i did that, same error as before.

Share this post


Link to post
Share on other sites
You have 'BITMAP_FILE bitmap;' in your header. That header is included in both main.cpp and image.cpp. So, it's defining the variable bitmap in both files.

You shouldn't put variable definitions in your header files. Put it in one of the .cpp files and declare it as extern in the header if other .cpp files need to know about it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • 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!