on nyt todella ongelmallinen ognelma ja toivoisin että joku vois auttaa. mulla on tämmönen pitkähkö koodi ja bittikartan lataus ei oikeen onnistu. näkyviin tulee vaan pikselimössöä siihen missä bittikartan pitäis olla. tässä koodi:
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // just say no to MFC
#include // include important windows stuff
#include
#include
#include // include important C/C stuff
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // include directdraw
// DEFINES ////////////////////////////////////////////////
// defines for windows
#define WINDOW_CLASS_NAME "WINCLASS1"
// default screen size
#define SCREEN_WIDTH 640 // size of screen
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8 // bits per pixel
#define MAX_COLORS 256 // maximum colors
#define BITMAP_ID 0x4D42 // universal id for a bitmap
// TYPES //////////////////////////////////////////////////////
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;
// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
// MACROS /////////////////////////////////////////////////
#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 INIT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
// PROTOTYPES//////////////////////////////////////////////////
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds,
int num_rects,
LPRECT clip_list);
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color);
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);
// GLOBALS ////////////////////////////////////////////////
HWND main_hwnd = NULL; // globally track main window
HINSTANCE main_hinstance = NULL; // globally track hinstance
int sx1 = 631;
int sx2 = SCREEN_WIDTH / 2 32 - 1;
int sy1 = SCREEN_WIDTH / 2 - 32;
int sy2 = 568;
// directdraw stuff
LPDIRECTDRAW lpdd = NULL; // dd object
LPDIRECTDRAW4 lpdd4 = NULL; // dd4 object
LPDIRECTDRAWSURFACE4 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE4 lpddsback = NULL; // dd back surface
LPDIRECTDRAWSURFACE4 spaceship = NULL;
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
DDCOLORKEY colorkey;
DWORD start_clock_count = 0; // used for timing
BITMAP_FILE bitmap;
// these defined the general clipping rectangle
int min_clip_x = 0, // clipping rectangle
max_clip_x = SCREEN_WIDTH-1,
min_clip_y = 0,
max_clip_y = SCREEN_HEIGHT-1;
// these are overwritten globally by DD_Init()
int screen_width = SCREEN_WIDTH, // width of screen
screen_height = SCREEN_HEIGHT, // height of screen
screen_bpp = SCREEN_BPP; // bits per pixel
char buffer[80]; // general printing buffer
// 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
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 Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here
RECT destrect;
RECT srcrect;
RECT destrectfill;
//tähän kirjota näppäintunnistuskoodi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (KEYDOWN(VK_LEFT) && sy1 > 0)
{
sy1--;
sx2--;
}
if (KEYDOWN(VK_RIGHT) && sx2 < 640)
{
sx2 ;
sy1 ;
}
if (KEYDOWN(VK_UP) && sy2 > 0)
{
sy2--;
sx1--;
}
if (KEYDOWN(VK_DOWN) && sx1 < 480)
{
sy2 ;
sx1 ;
}
destrectfill.bottom = SCREEN_HEIGHT-1;
destrectfill.left = 0;
destrectfill.right = SCREEN_WIDTH -1;
destrectfill.top = 0;
destrect.bottom = sx1-1;
destrect.left = sy1;
destrect.right = sx2-1;
destrect.top = sy2;
srcrect.bottom = 63;
srcrect.left = 0;
srcrect.right = 63;
srcrect.top = 0;
// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
SendMessage(main_hwnd,WM_CLOSE,0,0);
DDraw_Fill_Surface(lpddsback,255);
if (FAILED(lpddsback->Blt(&destrect, spaceship, &srcrect, (DDBLT_WAIT | DDBLT_KEYSRC ), NULL)))
{
//error
return(0);
}
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
// return success or failure or your own return code here
return(1);
} // end Game_Main
////////////////////////////////////////////////////////////
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
RECT cliprect;
cliprect.bottom = SCREEN_HEIGHT;
cliprect.left = 0;
cliprect.right = SCREEN_WIDTH;
cliprect.top = 0;
// first create base IDirectDraw interface
if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
{
// error
return(0);
} // end if
// now query for IDirectDraw4
if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4,
(LPVOID *)&lpdd4)))
{
// error
return(0);
} // end if
lpdd->Release();
// set cooperation to full screen
if (FAILED(lpdd4->SetCooperativeLevel(main_hwnd,
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
{
// error
return(0);
} // end if
// set display mode to 640x480x8
if (FAILED(lpdd4->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
{
// error
return(0);
} // end if
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL)))
{
//error
return(0);
} //end if
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
{
//error
return(0);
}
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
ddsd.dwWidth = 64;
ddsd.dwHeight = 64;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
if (FAILED(lpdd4->CreateSurface(&ddsd, &spaceship, NULL)))
{
//error
return(0);
}
for (int i = 0; i < MAX_COLORS; i )
{
palette[i].peRed = rand()%256;
palette[i].peGreen = rand()%256;
palette[i].peBlue = rand()%256;
palette[i].peFlags = PC_NOCOLLAPSE;
}
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;
if (FAILED(lpdd4->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette, &lpddpal, NULL)))
{
//error
return(0);
}
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
{
//error
return(0);
}
DDraw_Fill_Surface(spaceship, 5);
Load_Bitmap_File(&bitmap, "spaceship.bmp");
spaceship->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
// get video pointer to primary surfce
UCHAR *spaceship_buffer = (UCHAR *)ddsd.lpSurface;
// test if memory is linear
if (ddsd.lPitch == 64)
{
// copy memory from double buffer to primary buffer
memcpy((void *)spaceship_buffer, (void *)bitmap.buffer, 64*64);
} // end if
else
{ // non-linear
// make copy of source and destination addresses
UCHAR *dest_ptr = spaceship_buffer;
UCHAR *src_ptr = bitmap.buffer;
// memory is non-linear, copy line by line
for (int y=0; y < 64; y )
{
// copy line
memcpy((void *)dest_ptr, (void *)src_ptr, 63);
// advance pointers to next line
dest_ptr =ddsd.lPitch;
src_ptr =64;
} // end for
} // end else
// now unlock the primary surface
if (FAILED(spaceship->Unlock(NULL)))
{
//error
return(0);
}
if (FAILED(lpddpal->SetEntries(0, 0, MAX_COLORS, bitmap.palette)))
{
//error
return(0);
}
lpddclipper = DDraw_Attach_Clipper(lpddsback, 1, &cliprect);
ShowCursor(FALSE);
// return success or failure or your own return code here
return(0);
} // 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
// simply blow away the IDirectDraw4 interface
if (lpdd4)
{
lpdd4->Release();
lpdd4 = NULL;
} // end if
if (lpddpal)
{
lpddpal->Release();
lpddpal = NULL;
}
ShowCursor(TRUE);
// return success or failure or your own return code here
return(0);
} // 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
main_hinstance = hinstance;
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"DirectDraw Full-Screen Demo", // 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);
// save main window handle
main_hwnd = 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
Game_Main();
} // end while
// closedown game here
Game_Shutdown();
// return to Windows like this
return(msg.wParam);
} // end WinMain
///////////////////////////////////////////////////////////
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(lpdd4->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; indexrdh.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 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*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; 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
//////////////////////////////////////////////////////////////////////////////
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
// clear out the structure and set the size field
INIT(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
koodin loppu
ja siis tämän debugatun ohjelman kans samassa kansiossa on spaceship niminen bittikartta.
auttakaa pliis...
sille joka auttaa mä lähetän ton tulevan pelin (:
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // just say no to MFC
#include // include important windows stuff
#include
#include
#include // include important C/C stuff
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // include directdraw
// DEFINES ////////////////////////////////////////////////
// defines for windows
#define WINDOW_CLASS_NAME "WINCLASS1"
// default screen size
#define SCREEN_WIDTH 640 // size of screen
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8 // bits per pixel
#define MAX_COLORS 256 // maximum colors
#define BITMAP_ID 0x4D42 // universal id for a bitmap
// TYPES //////////////////////////////////////////////////////
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;
// basic unsigned types
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
// MACROS /////////////////////////////////////////////////
#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 INIT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
// PROTOTYPES//////////////////////////////////////////////////
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds,
int num_rects,
LPRECT clip_list);
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color);
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);
// GLOBALS ////////////////////////////////////////////////
HWND main_hwnd = NULL; // globally track main window
HINSTANCE main_hinstance = NULL; // globally track hinstance
int sx1 = 631;
int sx2 = SCREEN_WIDTH / 2 32 - 1;
int sy1 = SCREEN_WIDTH / 2 - 32;
int sy2 = 568;
// directdraw stuff
LPDIRECTDRAW lpdd = NULL; // dd object
LPDIRECTDRAW4 lpdd4 = NULL; // dd4 object
LPDIRECTDRAWSURFACE4 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE4 lpddsback = NULL; // dd back surface
LPDIRECTDRAWSURFACE4 spaceship = NULL;
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
DDCOLORKEY colorkey;
DWORD start_clock_count = 0; // used for timing
BITMAP_FILE bitmap;
// these defined the general clipping rectangle
int min_clip_x = 0, // clipping rectangle
max_clip_x = SCREEN_WIDTH-1,
min_clip_y = 0,
max_clip_y = SCREEN_HEIGHT-1;
// these are overwritten globally by DD_Init()
int screen_width = SCREEN_WIDTH, // width of screen
screen_height = SCREEN_HEIGHT, // height of screen
screen_bpp = SCREEN_BPP; // bits per pixel
char buffer[80]; // general printing buffer
// 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
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 Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here
RECT destrect;
RECT srcrect;
RECT destrectfill;
//tähän kirjota näppäintunnistuskoodi!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if (KEYDOWN(VK_LEFT) && sy1 > 0)
{
sy1--;
sx2--;
}
if (KEYDOWN(VK_RIGHT) && sx2 < 640)
{
sx2 ;
sy1 ;
}
if (KEYDOWN(VK_UP) && sy2 > 0)
{
sy2--;
sx1--;
}
if (KEYDOWN(VK_DOWN) && sx1 < 480)
{
sy2 ;
sx1 ;
}
destrectfill.bottom = SCREEN_HEIGHT-1;
destrectfill.left = 0;
destrectfill.right = SCREEN_WIDTH -1;
destrectfill.top = 0;
destrect.bottom = sx1-1;
destrect.left = sy1;
destrect.right = sx2-1;
destrect.top = sy2;
srcrect.bottom = 63;
srcrect.left = 0;
srcrect.right = 63;
srcrect.top = 0;
// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
SendMessage(main_hwnd,WM_CLOSE,0,0);
DDraw_Fill_Surface(lpddsback,255);
if (FAILED(lpddsback->Blt(&destrect, spaceship, &srcrect, (DDBLT_WAIT | DDBLT_KEYSRC ), NULL)))
{
//error
return(0);
}
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
// return success or failure or your own return code here
return(1);
} // end Game_Main
////////////////////////////////////////////////////////////
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
RECT cliprect;
cliprect.bottom = SCREEN_HEIGHT;
cliprect.left = 0;
cliprect.right = SCREEN_WIDTH;
cliprect.top = 0;
// first create base IDirectDraw interface
if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
{
// error
return(0);
} // end if
// now query for IDirectDraw4
if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4,
(LPVOID *)&lpdd4)))
{
// error
return(0);
} // end if
lpdd->Release();
// set cooperation to full screen
if (FAILED(lpdd4->SetCooperativeLevel(main_hwnd,
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
{
// error
return(0);
} // end if
// set display mode to 640x480x8
if (FAILED(lpdd4->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
{
// error
return(0);
} // end if
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL)))
{
//error
return(0);
} //end if
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
{
//error
return(0);
}
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
ddsd.dwWidth = 64;
ddsd.dwHeight = 64;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
if (FAILED(lpdd4->CreateSurface(&ddsd, &spaceship, NULL)))
{
//error
return(0);
}
for (int i = 0; i < MAX_COLORS; i )
{
palette[i].peRed = rand()%256;
palette[i].peGreen = rand()%256;
palette[i].peBlue = rand()%256;
palette[i].peFlags = PC_NOCOLLAPSE;
}
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;
if (FAILED(lpdd4->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette, &lpddpal, NULL)))
{
//error
return(0);
}
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
{
//error
return(0);
}
DDraw_Fill_Surface(spaceship, 5);
Load_Bitmap_File(&bitmap, "spaceship.bmp");
spaceship->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
// get video pointer to primary surfce
UCHAR *spaceship_buffer = (UCHAR *)ddsd.lpSurface;
// test if memory is linear
if (ddsd.lPitch == 64)
{
// copy memory from double buffer to primary buffer
memcpy((void *)spaceship_buffer, (void *)bitmap.buffer, 64*64);
} // end if
else
{ // non-linear
// make copy of source and destination addresses
UCHAR *dest_ptr = spaceship_buffer;
UCHAR *src_ptr = bitmap.buffer;
// memory is non-linear, copy line by line
for (int y=0; y < 64; y )
{
// copy line
memcpy((void *)dest_ptr, (void *)src_ptr, 63);
// advance pointers to next line
dest_ptr =ddsd.lPitch;
src_ptr =64;
} // end for
} // end else
// now unlock the primary surface
if (FAILED(spaceship->Unlock(NULL)))
{
//error
return(0);
}
if (FAILED(lpddpal->SetEntries(0, 0, MAX_COLORS, bitmap.palette)))
{
//error
return(0);
}
lpddclipper = DDraw_Attach_Clipper(lpddsback, 1, &cliprect);
ShowCursor(FALSE);
// return success or failure or your own return code here
return(0);
} // 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
// simply blow away the IDirectDraw4 interface
if (lpdd4)
{
lpdd4->Release();
lpdd4 = NULL;
} // end if
if (lpddpal)
{
lpddpal->Release();
lpddpal = NULL;
}
ShowCursor(TRUE);
// return success or failure or your own return code here
return(0);
} // 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
main_hinstance = hinstance;
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"DirectDraw Full-Screen Demo", // 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);
// save main window handle
main_hwnd = 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
Game_Main();
} // end while
// closedown game here
Game_Shutdown();
// return to Windows like this
return(msg.wParam);
} // end WinMain
///////////////////////////////////////////////////////////
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(lpdd4->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; indexrdh.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 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*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; 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
//////////////////////////////////////////////////////////////////////////////
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
// clear out the structure and set the size field
INIT(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
koodin loppu
ja siis tämän debugatun ohjelman kans samassa kansiossa on spaceship niminen bittikartta.
auttakaa pliis...
sille joka auttaa mä lähetän ton tulevan pelin (:
Vastaukset 16
Vanhimmat
inside peliohjelmointi???
kyllähän se inside peliohjelmointi on.
oot vissiin itekki joskus perehtyny?
kokeilenpa sitte tota LoadImageeee...
siis voisko vielä heittää vähä esimerkkii ja prototyypin siitä LoadImagesta?
ja kun tuota käyttää niin eikö kuva tarvii ladata resurssiks?
HANDLE LoadImage(
HINSTANCE hinst, // handle of the instance containing the image
LPCTSTR lpszName, // name or identifier of image
UINT uType, // type of image
int cxDesired, // desired width
int cyDesired, // desired height
UINT fuLoad // load flags
);
käytetään jotenni näin:
HBITMAP LoadBitmapFile(const TCHAR *filename)
{
return (HBITMAP)LoadImage(NULL, filename,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}
kun on tuo LR_LOADFROMFILE niin ei tarvii olla resurssi...
oisko mahdollista ladata jolain funktiolla bittikatta suoraan tavalliseen ruudun ulkopuoliseen pintaan?
jonka tyyppi on LPDIRECTDRAWSURFACE4
oisko mahd?
//onnistusko tällä ??? =)
LPDIRECTDRAWSURFACE4 bitmap_surface(LPCTSTR file_name)
{
HDC hdc;
HBITMAP bit;
LPDIRECTDRAWSURFACE4 surf;
bit=(HBITMAP) LoadImage(NULL,file_name,IMAGE_BITMAP,0,0,
LR_DEFAULTSIZE|LR_LOADFROMFILE);
if (!bit)
return NULL;
BITMAP bitmap;
GetObject( bit, sizeof(BITMAP), &bitmap );
int surf_width=bitmap.bmWidth;
int surf_height=bitmap.bmHeight;
HRESULT ddrval;
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ;
ddsd.ddsCaps.dwCaps = DSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = surf_width;
ddsd.dwHeight = surf_height;
ddrval=lpDD->CreateSurface(&ddsd,&surf,NULL);
if (ddrval!=DD_OK) {
DeleteObject(bit);
return NULL;
}
else
{
surf->GetDC(&hdc);
HDC bit_dc=CreateCompatibleDC(hdc);
SelectObject(bit_dc,bit);
BitBlt(hdc,0,0,surf_width,surf_height,bit_dc,0,0,SRCCOPY);
surf->ReleaseDC(hdc);
DeleteDC(bit_dc);
}
DeleteObject(bit);
return surf;
}
heti kun pääsen kotiin.
näinkö:
LPDIRECTDRAWSURFACE4 spaceship;
spaceship = bitmap_surface(//tänne tiedostonimi)
//käyteteeän spaceshippii
//vapautetaan...
ja sitte toi prototyyppi vaan johki kohtaa koodia
toimiiko noin?
toimia...
perkule joudun käytännössä kattoen kirjottaan uusiks ton koodin... no joskus ohjelmointi on semmosta... mutta miljoonat kiitokset ku oot auttanu.
...mulle kävi ihan sama homma kun aikani taistelin sen ihme "bitmaploaderin" kans joka ei oikeesti toiminu..
hoksasin tässä että ei tuossa Load_Bitmap_file() - functiossa mitään vikaa oo, koska se toimii täydellisesti ainakin ku lataan koko uudun kokosen bittikartan. että oisko tullu sitte kämmiä siinä bitmap.bufferin kopioinnissa siihen directdraw pintaan???
joka tapauksessa nyt kun mulla on taas melkeenpä hyvä koodi niin ei tuu bittikartan alkuakaan näkyviin. eikä hiiren osotin katoa vaikka onkin tuo ShowCursor(FALSE) sielä... että vian varmaan pitäis olla jossain sitä ennen. en kyllä löytäny...
että jos vaan mitenkään löytyis apuja??
niin ja koodi on siis kokonaisuudessaan tämmönen:
//////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
//INCLUDES
#define WIN32_LEAN_AND_MEAN
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//DEFINES
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 8
#define MAX_COLORS 256
#define BITMAP_ID 0x4D42
#define SHIP_WIDTH 64
#define SHIP_HEIGHT 64
#define ENEMY1_WIDTH 64
#define ENEMY1_HEIGHT 64
#define ENEMY2_WIDTH 128
#define ENEMY2_HEIGHT 128
#define ENEMY3_WIDTH 256
#define ENEMY3_HEIGHT 256
#define FIRE_WIDTH 64
#define FIRE_HEIGHT 64
#define MAX_FIRE 5
#define MAX_ENEMIES 10
#define FIRE_SPEED 5
#define GAME_SPEED 10
#define ENEMY2AT 10000
#define ENEMY3AT 100000
#define WINDOW_CLASS_NAME "WINCLASS1"
//MACROS
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define INIT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
//BASIC UNSIGNED STUFF
typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
///////////////////////////////////////////////////////////////////////////////////////////////////////
//DIRECTDRAW STUFF
LPDIRECTDRAW lpdd = NULL; // dd object
LPDIRECTDRAW4 lpdd4 = NULL; // dd4 object
LPDIRECTDRAWSURFACE4 lpddsprimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE4 lpddsback = NULL; // dd back surface
LPDIRECTDRAWSURFACE4 spaceship = NULL;
LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
PALETTEENTRY palette[256]; // color palette
DDSURFACEDESC2 ddsd; // a direct draw surface description struct
DDBLTFX ddbltfx; // used to fill
DDSCAPS2 ddscaps; // a direct draw surface capabilities struc
DDCOLORKEY colorkey;
DWORD start_clock_count = 0; // used for timing
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//TYPES
typedef struct FIRE_TAG
{
int fire_sx;
int fire_sy;
int fire_bx;
int fire_by;
bool fire_state;
} FIRE, *FIRE_PTR;
typedef struct ENEMY1_TAG
{
int enemy1_sx;
int enemy1_sy;
int enemy1_bx;
int enemy1_by;
int enemy1_speed;
bool enemy1_state;
} ENEMY1, *ENEMY1_PTR;
typedef struct ENEMY2_TAG
{
int enemy2_sx;
int enemy2_sy;
int enemy2_bx;
int enemy2_by;
int enemy2_speed;
bool enemy2_state;
} ENEMY2, *ENEMY2_PTR;
typedef struct ENEMY3_TAG
{
int enemy3_sx;
int enemy3_sy;
int enemy3_bx;
int enemy3_by;
int enemy3_speed;
bool enemy3_state;
} ENEMY3, *ENEMY3_PTR;
typedef struct SHIP_TAG
{
int ship_sx;
int ship_sy;
int ship_bx;
int ship_by;
bool ship_state;
int ship_speed;
} SHIP, *SHIP_PTR;
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;
///////////////////////////////////////////////////////////////////////////////////////////////
//GLOBALS
HWND main_hwnd;
HINSTANCE main_hinstance;
HDC main_hdc;
RECT srcrect;
int fire_amount = 0;
int enemy_amount = 0;
int score = 0;
int enemy_direction = 0;
int fire_index = 0;
int enemy_index = 0;
SHIP ship;
FIRE fire[MAX_FIRE];
ENEMY1 enemy1[MAX_ENEMIES];
ENEMY2 enemy2[MAX_ENEMIES];
ENEMY3 enemy3[MAX_ENEMIES];
BITMAP_FILE bitmap;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//PROTOTYPES
inline void CreateFire();
inline void MoveFire();
inline void CreateEnemy();
inline void MoveEnemy();
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE4 lpdds, int num_rects, LPRECT clip_list);
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color);
LPDIRECTDRAWSURFACE4 bitmap_surface(LPCTSTR);
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 Game_Init();
int Game_Main();
int Game_Shutdown();
///////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNCTIONS
/////////////////////////////////////////////////////////////////////////////////////
//CREATEFIRE
inline void CreateFire()
{
if (KEYDOWN(VK_SPACE) && fire_amount < MAX_FIRE)
{
if (fire_index = 5)
fire_index = 0;
fire[fire_index].fire_state = 1;
fire[fire_index].fire_sx = ship.ship_sx;
fire[fire_index].fire_by = ship.ship_sy;
fire[fire_index].fire_bx = fire[fire_index].fire_sx + FIRE_WIDTH;
fire[fire_index].fire_sy = fire[fire_index].fire_by - FIRE_HEIGHT;
fire_amount++;
fire_index++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
//MOVEFIRE
inline void MoveFire()
{
for (int i = 0; i < MAX_FIRE; i++)
{
if (fire[i].fire_state = 1)
{
fire[i].fire_sy-= FIRE_SPEED;
fire[i].fire_by-= FIRE_SPEED;
if (fire[i].fire_by < 0)
fire[i].fire_state = 0;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////
//CREATEENEMY
inline void CreateEnemy()
{
if (enemy_amount < MAX_ENEMIES)
{
if (score < ENEMY2AT)
{
enemy1[enemy_index].enemy1_state = 1;
enemy1[enemy_index].enemy1_speed = score / 2000 + 1;
enemy1[enemy_index].enemy1_bx = rand()% (SCREEN_WIDTH - ENEMY1_WIDTH);
enemy1[enemy_index].enemy1_by = 0;
enemy1[enemy_index].enemy1_sx = enemy1[enemy_index].enemy1_bx - ENEMY1_WIDTH;
enemy1[enemy_index].enemy1_sy = enemy1[enemy_index].enemy1_by - ENEMY1_HEIGHT;
}
if (score > ENEMY2AT && score < ENEMY3AT)
{
enemy2[enemy_index].enemy2_state = 1;
enemy2[enemy_index].enemy2_speed = score / 20000 + 1;
enemy2[enemy_index].enemy2_bx = rand()% (SCREEN_WIDTH - ENEMY2_WIDTH);
enemy2[enemy_index].enemy2_by = 0;
enemy2[enemy_index].enemy2_sx = enemy2[enemy_index].enemy2_bx - ENEMY2_WIDTH;
enemy2[enemy_index].enemy2_sy = enemy2[enemy_index].enemy2_by - ENEMY2_HEIGHT;
}
if (score > ENEMY3AT)
{
enemy3[enemy_index].enemy3_state = 1;
enemy3[enemy_index].enemy3_speed = score / 200000 + 1;
enemy3[enemy_index].enemy3_bx = rand()% (SCREEN_WIDTH - ENEMY3_WIDTH);
enemy3[enemy_index].enemy3_by = 0;
enemy3[enemy_index].enemy3_sx = enemy3[enemy_index].enemy3_bx - ENEMY3_WIDTH;
enemy3[enemy_index].enemy3_sy = enemy3[enemy_index].enemy3_by - ENEMY3_HEIGHT;
}
enemy_amount++;
enemy_index++;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//MOVEENEMY
inline void MoveEnemy()
{
if (enemy_amount > 0)
{
if (score < ENEMY2AT)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemy1[i].enemy1_state = 1)
{
enemy_direction = rand()% 2;
if (enemy_direction = 0)
enemy1[i].enemy1_sx-= enemy1[i].enemy1_speed;
enemy1[i].enemy1_bx = enemy1[i].enemy1_sx + ENEMY1_WIDTH;
enemy1[i].enemy1_by-= enemy1[i].enemy1_speed;
enemy1[1].enemy1_sy = enemy1[i].enemy1_by - ENEMY1_HEIGHT;
if (enemy1[i].enemy1_sy > SCREEN_HEIGHT || enemy1[i].enemy1_sx > SCREEN_WIDTH || enemy1[i].enemy1_bx < 0)
enemy1[i].enemy1_state = 0;
if (enemy1[i].enemy1_sy > ship.ship_by && enemy1[i].enemy1_by < ship.ship_sy &&
enemy1[i].enemy1_sx > ship.ship_bx && enemy1[i].enemy1_bx < ship.ship_sx) // HIT!!!!!!!!
enemy1[i].enemy1_state = 0;
}
}
}
if (score > ENEMY2AT && score < ENEMY3AT)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemy2[i].enemy2_state = 1)
{
enemy_direction = rand()% 2;
if (enemy_direction = 0)
enemy2[i].enemy2_sx-= enemy2[i].enemy2_speed;
enemy2[i].enemy2_bx = enemy2[i].enemy2_sx + ENEMY2_WIDTH;
enemy2[i].enemy2_by-= enemy2[i].enemy2_speed;
enemy2[1].enemy2_sy = enemy2[i].enemy2_by - ENEMY2_HEIGHT;
if (enemy2[i].enemy2_sy > SCREEN_HEIGHT || enemy2[i].enemy2_sx > SCREEN_WIDTH || enemy2[i].enemy2_bx < 0)
enemy2[i].enemy2_state = 0;
if (enemy2[i].enemy2_sy > ship.ship_by && enemy2[i].enemy2_by < ship.ship_sy &&
enemy2[i].enemy2_sx > ship.ship_bx && enemy2[i].enemy2_bx < ship.ship_sx) // HIT!!!!!!!!
enemy2[i].enemy2_state = 0;
}
}
}
if (score > ENEMY3AT)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemy3[i].enemy3_state = 1)
{
enemy_direction = rand()% 2;
if (enemy_direction = 0)
enemy3[i].enemy3_sx-= enemy3[i].enemy3_speed;
enemy3[i].enemy3_bx = enemy3[i].enemy3_sx + ENEMY3_WIDTH;
enemy3[i].enemy3_by-= enemy3[i].enemy3_speed;
enemy3[1].enemy3_sy = enemy3[i].enemy3_by - ENEMY3_HEIGHT;
if (enemy3[i].enemy3_sy > SCREEN_HEIGHT ||enemy3[i].enemy3_sx > SCREEN_WIDTH || enemy3[i].enemy3_bx < 0)
enemy3[i].enemy3_state = 0;
if (enemy3[i].enemy3_sy > ship.ship_by && enemy3[i].enemy3_by < ship.ship_sy &&
enemy3[i].enemy3_sx > ship.ship_bx && enemy3[i].enemy3_bx < ship.ship_sx) // HIT!!!!!!!!
enemy3[i].enemy3_state = 0;
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//DDRAW_ATTACH_CLIPPER
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(lpdd4->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; indexrdh.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
////////////////////////////////////////////////////////////////////////////////////////////////////////
//LOAD_BITMAP_FILE
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*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; 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
/////////////////////////////////////////////////////////////////////////////////////////////
//UNLOAD_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
///////////////////////////////////////////////////////////////////////////////////////////////////////
//FLIP_BITMAP
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
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//DDRAW_FILL_SURFACE
int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE4 lpdds,int color)
{
DDBLTFX ddbltfx; // this contains the DDBLTFX structure
// clear out the structure and set the size field
INIT(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 Game_Main()
{
RECT destrect;
if (KEYDOWN(VK_LEFT) && ship.ship_sx > 0)
{
ship.ship_sx--;
ship.ship_bx--;
}
if (KEYDOWN(VK_RIGHT) && ship.ship_bx < 640)
{
ship.ship_bx++;
ship.ship_sx++;
}
if (KEYDOWN(VK_UP) && ship.ship_sy > 0)
{
ship.ship_sy--;
ship.ship_by--;
}
if (KEYDOWN(VK_DOWN) && ship.ship_by < 480)
{
ship.ship_by++;
ship.ship_sy++;
}
if (KEYDOWN(VK_ESCAPE))
SendMessage(main_hwnd,WM_CLOSE,0,0);
destrect.bottom = ship.ship_by;
destrect.left = ship.ship_sx;
destrect.right = ship.ship_bx;
destrect.top = ship.ship_sy;
INIT(ddsd);
if (FAILED(lpddsback->Blt(&srcrect, spaceship, &destrect, (DDBLT_WAIT | DDBLT_KEYSRC ), NULL)))
{
//error
return(0);
}
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
return(1);
} // end Game_Main
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Game_Init()
{
RECT cliprect;
cliprect.bottom = SCREEN_HEIGHT;
cliprect.left = 0;
cliprect.right = SCREEN_WIDTH;
cliprect.top = 0;
if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
{
// error
return(1);
}
if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4)))
{
// error
return(1);
}
if (FAILED(lpdd4->SetCooperativeLevel(main_hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
{
// error
return(1);
}
if (FAILED(lpdd4->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 0, 0)))
{
// error
return(1);
}
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL)))
{
//error
return(1);
}
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
{
//error
return(1);
}
INIT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
ddsd.dwWidth = 64;
ddsd.dwHeight = 64;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
if (FAILED(lpdd4->CreateSurface(&ddsd, &spaceship, NULL)))
{
//error
return(1);
}
for (int i = 0; i < MAX_COLORS; i++)
{
palette[i].peRed = rand()%256;
palette[i].peGreen = rand()%256;
palette[i].peBlue = rand()%256;
palette[i].peFlags = PC_NOCOLLAPSE;
}
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;
if (FAILED(lpdd4->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette, &lpddpal, NULL)))
{
//error
return(1);
}
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
{
//error
return(1);
}
if (!Load_Bitmap_File(&bitmap, "spaceship.bmp"))
{
//error
return(1);
}
lpddclipper = DDraw_Attach_Clipper(lpddsback, 1, &cliprect);
// load it's palette into directdraw
if (FAILED(lpddpal->SetEntries(0, 0, MAX_COLORS, bitmap.palette)))
{
//error
return(1);
}
// clean the surface
DDraw_Fill_Surface(spaceship, 0);
// copy the bitmap image to the primary buffer line by line
// note this is a good candidate operation to make into a function - hint!
// lock the primary surface
spaceship->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
// get video pointer to primary surfce
UCHAR *primary_buffer = (UCHAR *)ddsd.lpSurface;
// test if memory is linear
if (ddsd.lPitch == SHIP_WIDTH)
{
// copy memory from double buffer to primary buffer
memcpy((void *)primary_buffer, (void *)bitmap.buffer, SHIP_WIDTH*SHIP_HEIGHT);
} // end if
else
{ // non-linear
// make copy of source and destination addresses
UCHAR *dest_ptr = primary_buffer;
UCHAR *src_ptr = bitmap.buffer;
// memory is non-linear, copy line by line
for (int y=0; y < SHIP_HEIGHT; y++)
{
// copy line
memcpy((void *)dest_ptr, (void *)src_ptr, SHIP_WIDTH);
// advance pointers to next line
dest_ptr+=ddsd.lPitch;
src_ptr +=SHIP_WIDTH;
} // end for
} // end else
// now unlock the primary surface
if (FAILED(lpddsprimary->Unlock(NULL)))
{
//error
return(1);
}
// unload the bitmap file, we no longer need it
Unload_Bitmap_File(&bitmap);
ship.ship_by = SCREEN_HEIGHT;
ship.ship_sx = (SCREEN_WIDTH / 2) - (SHIP_WIDTH / 2);
ship.ship_bx = ship.ship_sx + SHIP_WIDTH;
ship.ship_sy = ship.ship_by - SHIP_HEIGHT;
srcrect.bottom = SHIP_HEIGHT - 1;
srcrect.left = 0;
srcrect.right = SHIP_WIDTH - 1;
srcrect.top = 0;
if (!ShowCursor(FALSE))
{
//error
return(1);
}
return(1);
} // end Game_Init
/////////////////////////////////////////////////////////////////////////////////////////////////////
int Game_Shutdown()
{
if (lpddpal)
{
lpddpal->Release();
lpddpal = NULL;
}
if (lpdd4)
{
lpdd4->Release();
lpdd4 = NULL;
}
ShowCursor(TRUE);
return(0);
} // end Game_Shutdown
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//WINDOW PROCEDURE
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 success
return(0);
} break;
case WM_PAINT:
{
// simply validate the window
main_hdc = 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
////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//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
// 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);
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
"SPACE COMBAT", // 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);
main_hwnd = hwnd;
main_hinstance = hinstance;
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
Game_Main();
} // end while
// closedown game here
Game_Shutdown();
// return to Windows like this
return(msg.wParam);
} // end WinMain
/////////////////////////////////////////////////
//KOODIN LOPPU
HUHHUH kylläpä sitä onki paljolti
huomasin ihan saman aikasemmin... eli kokoruudun kopiointi tuolla onnistuu mutta pienet palaset "hajoaa" jostain kumman syystä...
//// nopealla vilkasulla:
//FLIP_BITMAP
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 )
//MIKÄ TUO TUOSSA ON??
//memcpy( jasitten joku outo??
memcpy(ℑ[((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
tee niistä bitmap funktioista oma luokka niin ei tuu niin pitkä pötkö tuohon mainiin ja se on selkeämpikin sillain...
aivan, siis vika oliskin tuossa FlipBitmapisas ewikä sunkaan LoadBitmapissa... en oo ees vilkassu koko Flippii ku ajttelin sen olevan itsestään selvyys... no tyhmästä päästä.. ja jospa noille bittikarttafunkkareille tekis ihan ikioman headerin. eikös niinki kävis?
ja sitte tosta gameinitissä olevasta directdraw kamastavois vielä tehä yhen funktion niinku siinä kirjassaki oli tehty, auttaisko se mitään vai olis vaan silmälle parempi?
joka tapauksessa miljoonat kiitokset (taas kerran)
:)
eipä oo vikaa tossa funkkarissa. vaikka koko funktiokutsun ottaa pois niin siitä huolimatta mitään ei näy, eikä kohdistinkaan katoa vaikka KYLLÄ pitäis, koska tuo ShowCursor(FALSE) on Game_Init:in lopussa. enpä sitte tiedä mikä on. kaikkien latauasarvojen pitäis olla oikeen(meinaan että bittikartta tosiaan blitataan ylhäältä alas eikä alhaalta ylös) jolloin kuvaa ei näkyis. täytynee kokeilla vilä kerran kirjottaa koko paska uusiks... EIH TUUUUUUUUUUUUUN HULLLLLLLLLLLLLLLLLLLLLLLLLUKS !!!!!!!!!!!!!! no en tuu, kyllä tää vielä tästä lähtee etenemään.
JESSSSSSSSSSSSSSSSSSSSSSSSSSSS
JESSSSSSSSSSSSSSSSSSSSSSSSSSSS
JESSSSSSSSSSSSSSSSSSSSSSSSSSSS
JIIIIIIIIIIIIIIIIIIIIIIHAAAAAAAAAAAAAAAAAAAAAA
VOOOOOOOOOOOOOHOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
VAUVAUVAUVAUVAUVAU
JIPPPPPPPPPPIIIIIIIIIIIIIIIIIIIIIIIIIIII
löysin vian. olin tyhmänä lukinnus spaceshipin ja avannu primarysurfacen... tyhmätyhmätyhmä (hakkaa päätä seinään)