C++ / directX ONGELMA

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 (:
16684
Äänestä

Muut lukivat myös

Vastaukset 16

Vanhimmat

inside peliohjelmointi???

Äänestä
  • kyllähän se inside peliohjelmointi on.

    oot vissiin itekki joskus perehtyny?

    kokeilenpa sitte tota LoadImageeee...

    Äänestä

  • siis voisko vielä heittää vähä esimerkkii ja prototyypin siitä LoadImagesta?


    ja kun tuota käyttää niin eikö kuva tarvii ladata resurssiks?

    Äänestä

  • greature kirjoitti:

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

    Äänestä

  • TSwiGH kirjoitti:

    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?

    Äänestä

  • greature kirjoitti:

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

    Äänestä

  • TSwiGH kirjoitti:

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

    Äänestä

  • Nimetön kirjoitti:

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

    Äänestä

  • TSwiGH kirjoitti:

    toimia...

    perkule joudun käytännössä kattoen kirjottaan uusiks ton koodin... no joskus ohjelmointi on semmosta... mutta miljoonat kiitokset ku oot auttanu.

    Äänestä

  • greature kirjoitti:

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

    Äänestä

  • TSwiGH kirjoitti:

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

    Äänestä

  • greature kirjoitti:

    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

    Äänestä

  • greature kirjoitti:

    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

    tee niistä bitmap funktioista oma luokka niin ei tuu niin pitkä pötkö tuohon mainiin ja se on selkeämpikin sillain...

    Äänestä

  • TSwiGH kirjoitti:

    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

    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)
    :)

    Äänestä

  • TSwiGH kirjoitti:

    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

    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.

    Äänestä

  • greature kirjoitti:

    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)

    Äänestä

Kommentoi aloitusta


greture kirjoitti:

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 (:

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu