#define WIN32_LEAN_AND_MEAN
//include important stuff
#include
#include
#include
#include
#include
//#include "Blitex.h"
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
int GameInit();
int GameMain();
int GameEnd();
//declarations
struct Mover
{
int bitheight;
int bitwidth;
int locationx;
int locationy;
int velocityx;
int velocityy;
RECT mover;
}MOVER;
Mover Mover1;
int mainloop = 0;
int locx;
int locy;
int velx;
int vely;
int bh;
int hw;
bool LoadBMP(LPDIRECTDRAWSURFACE4 surface,
LPSTR filename);
HWND window_handle = NULL;
HINSTANCE instance = NULL;
LPDIRECTDRAW lpdd = NULL;
LPDIRECTDRAW4 lpdd4 = NULL;
LPDIRECTDRAWSURFACE4 pbuff = NULL;
LPDIRECTDRAWSURFACE4 bbuff = NULL;
LPDIRECTDRAWSURFACE4 Bitmap = NULL;
DDSURFACEDESC2 ddsd;
DDSCAPS2 ddscaps;
HRESULT hr;
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
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
//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 = "class";
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// save hinstance in global
instance = hinstance;
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
"class", // class
"BlitMove", // title
WS_POPUP / WS_VISIBLE,
0,0, // initial x,y
640,480, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance of this application
NULL))) // extra creation parms
return(0);
ShowCursor(FALSE);
// save main window handle
window_handle = hwnd;
// initialize game here
GameInit();
// 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
GameMain();
} // end while
// closedown game here
GameEnd();
// return to Windows like this
return(msg.wParam);
} // end WinM
bool LoadBMP(LPDIRECTDRAWSURFACE4 surface, LPSTR filename)
{
HBITMAP hbm;
HDC imagedc;
HDC surfacedc;
DDSURFACEDESC2 ddsd2;
DDSCAPS2 ddscaps2;
memset(&ddsd2, 0, sizeof(ddsd2));
ddsd2.dwSize = sizeof(ddsd2);
if(FAILED(surface->GetSurfaceDesc(&ddsd2)))
return FALSE;
memset(&ddscaps2, 0, sizeof(ddscaps2));
if(FAILED(surface->GetCaps(&ddscaps)))
return FALSE;
hbm = (HBITMAP)LoadImage(NULL, filename,
IMAGE_BITMAP, ddsd2.dwWidth,
ddsd2.dwHeight, LR_LOADFROMFILE/
LR_CREATEDIBSECTION);
imagedc = CreateCompatibleDC(NULL);
SelectObject(imagedc, hbm);
if(FAILED(surface->GetDC(&surfacedc)))
return FALSE;
if(!(BitBlt(surfacedc, 0, 0, ddsd2.dwWidth, ddsd2.dwHeight,
imagedc, 0, 0, SRCCOPY)))
return FALSE;
if(surfacedc)
surface->ReleaseDC(surfacedc);
if(imagedc)
DeleteDC(imagedc);
if(hbm)
DeleteObject(hbm);
return TRUE;
}//end LoadBMP
int GameInit()
{
if(FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
return(0);
if(FAILED(lpdd->QueryInterface(IID_IDirectDraw4,
(LPVOID *)&lpdd4)))
return(0);
if(FAILED(lpdd4->SetCooperativeLevel(window_handle, DDSCL_FULLSCREEN/
DDSCL_EXCLUSIVE/DDSCL_ALLOWREBOOT)))
return(0);
if(FAILED(lpdd4->SetDisplayMode(640, 480, 16, 0, 0)))
return(0);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS/DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE/
DDSCAPS_COMPLEX/
DDSCAPS_FLIP;
if(FAILED(lpdd4->CreateSurface(&ddsd, &pbuff, NULL)))
return(0);
//*********************************
// You were using the ddsd instead of ddscaps
// ie. ddsd.ddsCaps.dwCaps = ...
// should be:
// ddscaps.dwCaps = ...
// The back buffer uses the ddscaps while the primary uses the ddsd
memset(&ddscaps, 0, sizeof(ddscaps));
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if(FAILED(pbuff->GetAttachedSurface(&ddscaps, &bbuff)))
return(0);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS/DDSD_HEIGHT/DDSD_WIDTH;
ddsd.dwWidth = 640;
ddsd.dwHeight = 480;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
if(FAILED(lpdd4->CreateSurface(&ddsd, &Bitmap, NULL)))
return (0);
LoadBMP(Bitmap, "image.bmp");
//*****************************
// Make sure to return a value
return 1;
}//end GameInit()
inline int CreateMover(Mover create)
{
create.mover.top = 200;
create.mover.left = 320;
create.mover.bottom = 232;
create.mover.right = 352;
create.velocityx = rand()%5;
create.velocityy = rand()%5;
return(1);
}
int UpdateMover(LPDIRECTDRAWSURFACE4 surface,Mover update)
{
velx = update.velocityx;//the x velocity of the "mover"
vely = update.velocityy;//the y velocity of the "mover"
//Update the location of the "mover"
update.mover.top += vely;
update.mover.left += velx;
update.mover.bottom += vely;
update.mover.right += velx;
if(update.mover.right >= 640)
velx = -velx;
if(update.mover.left <= 0)
velx = -velx;
if(update.mover.top <= 0)
vely = -vely;
if(update.mover.bottom >= 480)
vely = -vely;
//Blit the mover''s new location
if(FAILED(surface->Blt(NULL, Bitmap, &update.mover,
DDBLT_WAIT,
NULL)))
return(0);
return (1);
}
int GameMain()
{
if(KEYDOWN(VK_ESCAPE))
PostMessage(window_handle, WM_CLOSE, 0, 0);
if(mainloop == 0)
{
CreateMover(Mover1);
UpdateMover(bbuff, Mover1);
}
else
{
UpdateMover(bbuff, Mover1);
}
if(FAILED(pbuff->Flip(NULL, DDFLIP_WAIT)))
return(0);
mainloop++;
return(1);
Sleep(500);
}
int GameEnd()
{
if (Bitmap)
{
Bitmap->Release();
Bitmap = NULL;
}
if(bbuff)
{
bbuff->Release();
bbuff = NULL;
}
if(pbuff)
{
pbuff->Release();
pbuff = NULL;
}
if(lpdd4)
{
lpdd4->Release();
lpdd4 = NULL;
}
return(1);
}
"Remember, I'm the monkey, and you're the cheese grater. So no fooling around."
-Grand Theft Auto, London
I ran the following code and got this streak across the top of my screen as if something is flying past me. I am just trying to get a little bitmap to bounce around the screen. Help! Here''s the code:
There are several problems in your UpdateMover function.
First, you copy your Mover''s velocity values into local
variables and then when you change those values you
don''t change them in the Mover struct.
Second, if your rectangle moves off the edge of the screen,
your flip the velocity but you don''t adjust the rectangle
so it fits on the screen again.
Third, you don''t pass appropriate rectangles to the
BLT call.
Try changing it like this:
int UpdateMover(LPDIRECTDRAWSURFACE4 surface,Mover update)
{
velx = update.velocityx;
vely = update.velocityy;
update.mover.top += vely;
update.mover.left += velx;
update.mover.bottom += vely;
update.mover.right += velx;
if( update.mover.right >= 640 )
{
update.mover.left -= (update.mover.right - 640);
update.mover.right = 640;
update.velocityx = -velx;
}
else if( update.mover.left <= 0 )
{
update.mover.right -= update.mover.left;
update.mover.left = 0;
update.velocityx = -velx;
}
if( update.mover.bottom >= 480 )
{
update.mover.top -= (update.mover.bottom - 480);
update.mover.bottom = 480;
update.velocityy = -vely;
}
else if( update.mover.top <= 0 )
{
update.mover.bottom -= update.mover.top;
update.mover.top = 0;
update.velocityy = -vely;
}
RECT image_rect = { 0, 0, 32, 32 };
//Blit the mover''s new location
if(FAILED(surface->Blt(&update.mover,Bitmap,
ℑ_rect,DDBLT_WAIT,NULL)))
return 0;
return 1;
}
Thanks. I should have seen that, however, I still get the same problem. If You e-mail me, I could send you the .exe so you can see the results of the code.
"Remember, I'm the monkey, and you're the cheese grater. So no fooling around."
-Grand Theft Auto, London
Edited by - psychoprog on 2/29/00 1:32:43 PM
"Remember, I'm the monkey, and you're the cheese grater. So no fooling around."
-Grand Theft Auto, London
Edited by - psychoprog on 2/29/00 1:32:43 PM
Any help would be great.
"Remember, I'm the monkey, and you're the cheese grater. So no fooling around."
-Grand Theft Auto, London
"Remember, I'm the monkey, and you're the cheese grater. So no fooling around."
-Grand Theft Auto, London
PsYcHoPrOg: Will you PLEASE stop posting these huge source code listings here? If you can''t narrow it down to a small section of code, then you aren''t spending enough time trying to figure things out on your own.
Sorry, I''ll make an attempt to narrow down my code.
"Remember, I'm the monkey, and you're the cheese grater. So no fooling around."
-Grand Theft Auto, London
"Remember, I'm the monkey, and you're the cheese grater. So no fooling around."
-Grand Theft Auto, London
Ok. After a brief (ok, I spent some time here ) look at that code I can see some problems.
1) CreateMover(Mover & create)
Otherwise create is just a copy and is destroyed when the function returns.
2) Same deal in UpdateMover(... , Mover & update)
3) In UpdateMover(...) you don't set the new velocity on the edge hit. Need
update.velocityx = velx;
update.velocityy = vely;
before you leave the function to keep track of any changes.
4) In UpdateMove(...) when you BLT the image I think that you are getting the source and destination rects mixed up.
update.mover is where to draw the bitmap.
testRect is where to look on the surface for the bitmap.
5) You don't clean out the back buffer so all the crap from the last frame and stuff in memory is shown. Try
as soon as you enter the GameMain().
Ok. I think I spent more time on this then I should have but what the hey it's good training.
If you want I can mail you the code and .exe that I have got working on my machine. You could also look at CDX since it is all open source and very well organized.
Andrew
acraig@engr.mun.ca
Edited by - acraig on 3/1/00 6:31:35 PM
1) CreateMover(Mover & create)
Otherwise create is just a copy and is destroyed when the function returns.
2) Same deal in UpdateMover(... , Mover & update)
3) In UpdateMover(...) you don't set the new velocity on the edge hit. Need
update.velocityx = velx;
update.velocityy = vely;
before you leave the function to keep track of any changes.
4) In UpdateMove(...) when you BLT the image I think that you are getting the source and destination rects mixed up.
update.mover is where to draw the bitmap.
testRect is where to look on the surface for the bitmap.
RECT testRect;
testRect.top = 0;
testRect.left = 0;
testRect.bottom = 64; //My test image 64,64
testRect.right = 64;
if(FAILED(surface->Blt(&update.mover, Bitmap,&testRect, DDBLT_WAIT, NULL)))
5) You don't clean out the back buffer so all the crap from the last frame and stuff in memory is shown. Try
DDBLTFX ddBltFx;
ddBltFx.dwSize = sizeof(DDBLTFX); ddBltFx.dwFillColor = 0; // 0 = black;
bbuff->Blt(NULL, NULL, NULL,DDBLT_WAIT / DDBLT_COLORFILL, &ddBltFx);
as soon as you enter the GameMain().
Ok. I think I spent more time on this then I should have but what the hey it's good training.
If you want I can mail you the code and .exe that I have got working on my machine. You could also look at CDX since it is all open source and very well organized.
Andrew
acraig@engr.mun.ca
Edited by - acraig on 3/1/00 6:31:35 PM
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement