Hello,
I know the basics of C++, PHP, JavaScript and VB
I've read for C++ from rly old books so some things may have changed. Now I've started reading Advamced-2D-Game-Development by Jonathan S. Harbour.
He has given a source code of an 2d game engine using DirectX.
This is what he've wrote, can you help me to fix it?
Headers:
Advanced2d.h
timer.h
winmain.h
Source: same names except format .cpp
adv2d.h
#ifndef _ADVANCED2D_H
#define _ADVANCED2D_H 1
#include <iostream>
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include "Timer.h"
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION 0
//external variables and functions
extern bool gameover;
extern bool game_preload();
extern bool game_init(HWND);
extern void game_update();
extern void game_end();
namespace Advanced2D
{
class Engine {
private:
int p_versionMajor, p_versionMinor, p_revision;
HWND p_windowHandle;
LPDIRECT3D9 p_d3d;
LPDIRECT3DDEVICE9 p_device;
LPDIRECT3DSURFACE9 p_backbuffer;
LPD3DXSPRITE p_sprite_handler;
std::string p_apptitle;
bool p_fullscreen;
int p_screenwidth;
int p_screenheight;
int p_colordepth;
bool p_pauseMode;
D3DCOLOR p_ambientColor;
bool p_maximizeProcessor;
Timer p_coreTimer;
long p_frameCount_core;
long p_frameRate_core;
Timer p_realTimer;
long p_frameCount_real;
long p_frameRate_real;
public:
Engine();
virtual ~Engine();
int Init(int width, int height, int colordepth, bool fullscreen);
void Close();
void Update();
void message(std::string message, std::string title = "ADVANCED 2D");
void fatalerror(std::string message, std::string title = "FATAL ERROR");
void Shutdown();
void ClearScene(D3DCOLOR color);
void SetDefaultMaterial();
void SetAmbient(D3DCOLOR colorvalue);
int RenderStart();
int RenderStop();
int Release();
//accessor/mutator functions expose the private variables
bool isPaused() { return this->p_pauseMode; }
void setPaused(bool value) { this->p_pauseMode = value; }
LPDIRECT3DDEVICE9 getDevice() { return this->p_device; }
LPDIRECT3DSURFACE9 getBackBuffer() { return this->p_backbuffer; }
LPD3DXSPRITE getSpriteHandler() { return this->p_sprite_handler; }
void setWindowHandle(HWND hwnd) { this->p_windowHandle = hwnd; }
HWND getWindowHandle() { return this->p_windowHandle; }
std::string getAppTitle() { return this->p_apptitle; }
void setAppTitle(std::string value) { this->p_apptitle = value; }
int getVersionMajor() { return this->p_versionMajor; }
int getVersionMinor() { return this->p_versionMinor; }
int getRevision() { return this->p_revision; }
std::string getVersionText();
long getFrameRate_core() { return this->p_frameRate_core; };
long getFrameRate_real() { return this->p_frameRate_real; };
int getScreenWidth() { return this->p_screenwidth; }
void setScreenWidth(int value) { this->p_screenwidth = value; }
int getScreenHeight() { return this->p_screenheight; }
void setScreenHeight(int value) { this->p_screenheight = value; }
int getColorDepth() { return this->p_colordepth; }
void setColorDepth(int value) { this->p_colordepth = value; }
bool getFullscreen() { return this->p_fullscreen; }
void setFullscreen(bool value) { this->p_fullscreen = value; }
bool getMaximizeProcessor() { return this->p_maximizeProcessor; }
void setMaximizeProcessor(bool value) { this->p_maximizeProcessor = value;}
}; //class
}; //namespace
//define the global engine object (visible everywhere!)
extern Advanced2D::Engine *g_engine;
#endif
timer.h
#pragma once
#include <time.h>
#include <windows.h>
namespace Advanced2D {
class Timer
{
private:
DWORD timer_start;
DWORD stopwatch_start;
public:
Timer(void);
~Timer(void);
DWORD getTimer();
DWORD getStartTimeMillis();
void sleep(int ms);
void reset();
bool stopwatch(int ms);
};
};
winmain.h
#ifndef _WINMAIN_H
#define _WINMAIN_H 1
#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN
#include <iostream>
#include <windows.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "Advanced2D.h"
#endif
adv2d.cpp
// Advanced2D Engine
// Main source code file
//includes
#include "Advanced2D.h"
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <list>
#include "winmain.h"
namespace Advanced2D
{
Engine::Engine()
{
srand((unsigned int)time(NULL));
p_maximizeProcessor = false;
p_frameCount_core = 0;
p_frameRate_core = 0;
p_frameCount_real = 0;
p_frameRate_real = 0;
p_ambientColor = D3DCOLOR_RGBA(255,255,255, 0);
p_windowHandle = 0;
p_pauseMode = false;
p_versionMajor = VERSION_MAJOR;
p_versionMinor = VERSION_MINOR;
p_revision = REVISION;
//set default values
this->setAppTitle("Advanced2D");
this->setScreenWidth(640);
this->setScreenHeight(480);
this->setColorDepth(32);
this->setFullscreen(false);
//window handle must be set later on for DirectX!
this->setWindowHandle(0);
}
Engine::~Engine()
{
if (this->p_device) this->p_device->Release();
if (this->p_d3d) this->p_d3d->Release();
}
std::string Engine::getVersionText()
{
std::ostringstream s;
s << "Advanced2D Engine v" << p_versionMajor << "." << p_versionMinor
<< "." << p_revision;
return s.str();
}
void Engine::message(std::string message, std::string title)
{
MessageBox(0,message.c_str(), title.c_str(), 0);
}
void Engine::fatalerror(std::string message, std::string title)
{
this->message(message,title);
Shutdown();
}
int Engine::Init(int width, int height, int colordepth, bool fullscreen)
{
//initialize Direct3D
this->p_d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (this->p_d3d == NULL) {
return 0;
}
//get system desktop color depth
D3DDISPLAYMODE dm;
this->p_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm);
//set configuration options for Direct3D
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = (!fullscreen);
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.BackBufferFormat = dm.Format;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.hDeviceWindow = p_windowHandle;
//create Direct3D device
this->p_d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
this->p_windowHandle,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&this->p_device);
if (this->p_device = = NULL) return 0;
//clear the backbuffer to black
this->ClearScene(D3DCOLOR_XRGB(0,0,0));
//create pointer to the back buffer
this->p_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &this-
>p_ backbuffer);
//use ambient lighting and z-buffering
this->p_device->SetRenderState(D3DRS_ZENABLE, TRUE);
this->p_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
this->SetAmbient(this->p_ambientColor);
//initialize 2D renderer
HRESULT result = D3DXCreateSprite(this->p_device, &this->p_sprite_handler);
if (result != D3D_OK) return 0;
//call game initialization extern function
if (!game_init(this->getWindowHandle())) return 0;
//set a default material
SetDefaultMaterial();
return 1;
}
void Engine::SetDefaultMaterial()
{
D3DMATERIAL9 mat;
memset(&mat, 0, sizeof(mat));
mat.Diffuse.r = 1.0f;
mat.Diffuse.g = 1.0f;
mat.Diffuse.b = 1.0f;
mat.Diffuse.a = 1.0f;
p_device->SetMaterial(&mat);
}
void Engine::ClearScene(D3DCOLOR color)
{
this->p_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
color, 1.0f, 0);
}
void Engine::SetAmbient(D3DCOLOR colorvalue)
{
this->p_ambientColor = colorvalue;
this->p_device->SetRenderState(D3DRS_AMBIENT, this->p_ambientColor);
}
int Engine::RenderStart()
{
if (!this->p_device) return 0;
if (this->p_device->BeginScene() != D3D_OK) return 0;
return 1;
}
int Engine::RenderStop()
{
if (!this->p_device) return 0;
if (this->p_device->EndScene() != D3D_OK) return 0;
if (p_device->Present(NULL, NULL, NULL, NULL) != D3D_OK) return 0;
return 1;
}
void Engine::Shutdown()
{
gameover = true;
}
void Engine::Update()
{
static Timer timedUpdate;
//calculate core framerate
p_frameCount_core+ +;
if (p_coreTimer.stopwatch(999)) {
p_frameRate_core = p_frameCount_core;
p_frameCount_core = 0;
}
//fast update with no timing
game_update();
//update with 60fps timing
if (!timedUpdate.stopwatch(14)) {
if (!this->getMaximizeProcessor())
{
Sleep(1);
}
}
else {
//calculate real framerate
p_frameCount_real+ +;
if (p_realTimer.stopwatch(999)) {
p_frameRate_real = p_frameCount_real;
p_frameCount_real = 0;
}
//begin rendering
this->RenderStart();
//done rendering
this->RenderStop();
}
}
void Engine::Close()
{
game_end();
}
}
timer.cpp
#include "Timer.h"
namespace Advanced2D {
Timer::Timer(void)
{
timer_start = timeGetTime();
reset();
}
Timer::~Timer(void)
{
}
DWORD Timer::getTimer()
{
return (DWORD) (timeGetTime());
}
DWORD Timer::getStartTimeMillis()
{
return (DWORD) (timeGetTime() - timer_start);
}
void Timer::sleep(int ms)
{
DWORD start = getTimer();
while (start + ms > getTimer());
}
void Timer::reset()
{
stopwatch_start = getTimer();
}
bool Timer::stopwatch(int ms)
{
if ( timeGetTime() > stopwatch_start + ms ) {
stopwatch_start = getTimer();
return true;
}
else return false;
}
};
winmain.cpp
#include <sstream>
#include "winmain.h"
#include "Advanced2D.h"
//macro to read the key states
#define KEY_DOWN(vk) ((GetAsyncKeyState(vk) & 0x8000)?1:0)
HINSTANCE g_hInstance;
HWND g_hWnd;
int g_nCmdShow;
//declare global engine object
Advanced2D::Engine *g_engine;
bool gameover;
//window event callback function
LRESULT WINAPI WinProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_QUIT:
case WM_CLOSE:
case WM_DESTROY:
gameover = true;
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int
nCmdShow)
{
MSG msg;
srand((unsigned int)time(NULL));
g_hInstance = hInstance;
g_nCmdShow = nCmdShow;
DWORD dwStyle, dwExStyle;
RECT windowRect;
/**
* Create engine object first!
**/
g_engine = new Advanced2D::Engine();
//let main program have a crack at things before window is created
if (!game_preload()) {
MessageBox(g_hWnd, L"Error in game preload!", L"Error", MB_OK);
return 0;
}
//get window caption string from engine
char title[255];
sprintf_s(title, "%s", g_engine->getAppTitle().c_str());
//set window dimensions
windowRect.left = (long)0;
windowRect.right = (long)g_engine->getScreenWidth();
windowRect.top = (long)0;
windowRect.bottom = (long)g_engine->getScreenHeight();
//create the window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
//fill the struct with info
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = title;
wc.hIconSm = NULL;
//set up the window with the class info
RegisterClassEx(&wc);
//set up the screen in windowed or fullscreen mode?
if (g_engine->getFullscreen())
{
DEVMODE dm;
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmPelsWidth = g_engine->getScreenWidth();
dm.dmPelsHeight = g_engine->getScreenHeight();
dm.dmBitsPerPel = g_engine->getColorDepth();
dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) {
MessageBox(NULL, L"Display mode failed", NULL, MB_OK);
g_engine->setFullscreen(false);
}
dwStyle = WS_POPUP;
dwExStyle = WS_EX_APPWINDOW;
ShowCursor(FALSE);
}
else {
dwStyle = WS_OVERLAPPEDWINDOW;
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
}
//adjust window to true requested size
AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);
//create the program window
g_hWnd = CreateWindowEx( 0,
title, //window class
title, //title bar
dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, //x,y coordinate
windowRect.right - windowRect.left, //width of the window
windowRect.bottom - windowRect.top, //height of the window
0, //parent window
0, //menu
g_hInstance, //application instance
0); //window parameters
//was there an error creating the window?
if (!g_hWnd) {
MessageBox(g_hWnd, L"Error creating program window!", L"Error", MB_OK);
return 0;
}
//display the window
ShowWindow(g_hWnd, g_nCmdShow);
UpdateWindow(g_hWnd);
//initialize the engine
g_engine->setWindowHandle(g_hWnd);
if (!g_engine->Init(g_engine->getScreenWidth(), g_engine->getScreenHeight(),
g_engine->getColorDepth(), g_engine->getFullscreen())) {
MessageBox(g_hWnd, "Error initializing the engine", "Error", MB_OK);
return 0;
}
// main message loop
gameover = false;
while (!gameover)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
g_engine->Update();
}
if (g_engine->getFullscreen()) {
ShowCursor(TRUE);
}
g_engine->Close();
delete g_engine;
return 1;
}
I'm using Visual Studio 2008
I hope someone can help me :(