#include <windows.h>
#include <FreeImage.h>
#include <ddraw.h>
#include "bouncy_resource.h"
#include "bouncy_functions.h"
#include "bouncy_classes.h"
BitMapObject bmoBall;
BitMapObject bmoBackground;
HBITMAP hBall;
HWND hWnd;
CBouncyBall BallClass;
LPDIRECTDRAW7 lpDD;
LPDIRECTDRAWSURFACE7 lpDDSPrimary;
LPDIRECTDRAWSURFACE7 lpDDSBack;
LPDIRECTDRAWCLIPPER lpDDClipper;
int Bouncy_Points;
bool done;
bool bRunGame;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
switch(message){
case WM_SIZE:
{
SetWindowPos(hWnd,0,0,0,400,500,SWP_NOMOVE | SWP_NOZORDER);
return(0);
}break;
case WM_COMMAND:
{
switch(LOWORD(wParam)){
case MENUID_CLOSE:
{
PostMessage(hWnd,WM_DESTROY,0,0);
return(0);
}break;
}
}break;
case WM_KEYDOWN:
{
switch(wParam){
case VK_ESCAPE:
{
PostMessage(hWnd,WM_DESTROY,0,0);
return(0);
}break;
}
}break;
case WM_DESTROY:
{
done=true;
return(0);
}break;
case WM_ACTIVATE:
{
if( LOWORD( wParam ) == WA_INACTIVE )
{
bRunGame = false;
}
else
{
bRunGame = true;
}
}break;
default:break;
}
return(DefWindowProc(hWnd,message,wParam,lParam));
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow){
MSG message;
WNDCLASSEX bouncyMain;
bouncyMain.cbSize=sizeof(WNDCLASSEX);
bouncyMain.style=CS_HREDRAW|CS_VREDRAW;
bouncyMain.lpfnWndProc=WindowProc;
bouncyMain.cbClsExtra=0;
bouncyMain.cbWndExtra=0;
bouncyMain.hInstance=hinst;
bouncyMain.hIcon=LoadIcon(NULL,IDI_WINLOGO);
bouncyMain.hCursor=LoadCursor(NULL,IDC_ARROW);
bouncyMain.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
bouncyMain.lpszMenuName=MAKEINTRESOURCE(MAIN_MENU);
bouncyMain.lpszClassName="BouncyMainClass";
bouncyMain.hIconSm=LoadIcon(NULL,IDI_WINLOGO);
if(!RegisterClassEx(&bouncyMain))return(0);
if(!(hWnd=CreateWindowEx(NULL,
"BouncyMainClass",
"Bouncy Ball",
WS_BORDER | WS_SYSMENU | WS_VISIBLE,
200, 200,
400, 500,
NULL,
NULL,
hinst,
NULL)))return(0);
ShowWindow(hWnd,SW_SHOWNORMAL);
UpdateWindow(hWnd);
if(!Bouncy_Init())return(0);
FreeImage_Initialise(false);
done=false;
while(!done){
while(PeekMessage(&message,hWnd,0,0,PM_REMOVE)){
TranslateMessage(&message);
DispatchMessage(&message);
}
GameLoop();
}
Bouncy_EndDDraw();
PostQuitMessage(0);
return(0);
}
bool Bouncy_Init(void){
if(!Bouncy_InitDDraw())return(false);
return(true);
}
bool Bouncy_InitDDraw(void){
HRESULT ddrval;
ddrval=DirectDrawCreateEx(NULL,(LPVOID *)&lpDD,IID_IDirectDraw7,NULL);
if(ddrval!=DD_OK){
return(false);
}
ddrval=lpDD->SetCooperativeLevel(hWnd,DDSCL_NORMAL);
if(ddrval!=DD_OK){
lpDD->Release();
return(false);
}
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
ddrval=lpDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL);
if(ddrval!=DD_OK){
lpDD->Release();
return(false);
}
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = 400;
ddsd.dwHeight = 500;
ddrval=lpDD->CreateSurface(&ddsd,&lpDDSBack,NULL);
if(ddrval!=DD_OK){
lpDD->Release();
lpDDSPrimary->Release();
return(false);
}
ddrval=lpDD->CreateClipper(0,&lpDDClipper,NULL);
if(ddrval!=DD_OK){
lpDD->Release();
lpDDSPrimary->Release();
lpDDSBack->Release();
return(false);
}
ddrval=lpDDClipper->SetHWnd(0,hWnd);
if(ddrval!=DD_OK){
lpDDClipper->Release();
lpDDSPrimary->Release();
lpDDSBack->Release();
lpDD->Release();
return(false);
}
ddrval=lpDDSPrimary->SetClipper(lpDDClipper);
if(ddrval!=DD_OK){
lpDDClipper->Release();
lpDDSPrimary->Release();
lpDDSBack->Release();
lpDD->Release();
return(false);
}
return(true);
}
bool Bouncy_EndDDraw(void){
if(lpDDSBack){
lpDDSBack->Release();
lpDDSBack=NULL;
}
if(lpDDSPrimary){
lpDDSPrimary->SetClipper(NULL);
lpDDClipper=NULL;
lpDDSPrimary->Release();
lpDDSPrimary=NULL;
}
if(lpDD){
lpDD->Release();
lpDD=NULL;
}
return(true);
}
bool GameLoop(){
if(bRunGame){
DrawAll();
}
return(true);
}
bool DrawAll(){
DDSURFACEDESC2 ddsd;
UCHAR *VRam;
int Linewidth;
int x,y;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
lpDDSBack->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);
Linewidth=ddsd.lPitch;
VRam=(UCHAR *)ddsd.lpSurface;
for(y=0;y<200;y++){
for(x=0;x<200;x++){
VRam[x+y*Linewidth]=245;
}
}
lpDDSBack->Unlock(NULL);
Bouncy_Flip();
return(true);
}
bool Bouncy_Flip(void){
RECT rect;
ZeroMemory(&rect,sizeof(rect));
GetClientRect(hWnd,&rect);
POINT p1;
POINT p2;
p1.x=rect.left;
p1.y=rect.top;
p2.x=rect.right;
p2.y=rect.bottom;
ClientToScreen(hWnd,&p1);
ClientToScreen(hWnd,&p2);
rect.left=p1.x;
rect.top=p1.y;
rect.right=p2.x;
rect.bottom=p2.y;
lpDDSPrimary->Blt(&rect,lpDDSBack,NULL,DDBLT_WAIT,NULL);
return(true);
}