C++ Time!

I feel terrible because of not posting anything for such a long time,
quick overview:

last two weeks was extremely busy at work, Christmas.. was pretty cool.. chilling out with my lovely girlfriend and wasting time on Heroes of Might and Magic 4.. well wasting a time because our Internet connection is approaching on 31.. well.. we need to wait.

yesterday I have decided to do little bit of University stuff.. so I have decided to start with Game Engineering..

yest that means C++!! .. that was my thought at very beginning.. after couple hours on sample code.. I have realized I can do nothing without Internet.. I hate to say that but set up DirectX in Visual studio 2010 is a freaking pain.. and you have to do that for every project..

is there any way of making it automatically? or once for all projects?

anyway,

I have got a mobile.. and Internet connection “G”.. so after 30 minutes I have got my lectures notes for my favorite module already.

after making “step by step” things like.. how to create new project.. I have my first draft of a C++ framework for well we will see.. nothing fancy but hey! this is just a begging!

// Input Handler Class Header
#pragma once

#ifndef INPUTHANDLER_H
#define INPUTHANDLER_H

[...]

#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")

class InputHandler
{
private:
  HWND hWnd;
  IDirectInput8* dInput;
  IDirectInputDevice8* mouse;
  IDirectInputDevice8* keyboard;
  unsigned char keyboardState[256];
  unsigned char previousKeyboardState[256];
  DIMOUSESTATE2 mouseState;
  DIMOUSESTATE2 previousMouseState;
  POINT mousePosition;
  POINT previousMousePosition;
public:
  InputHandler(HINSTANCE hInstance, HWND hWnd);
  virtual ~InputHandler();
  void poll();
  bool isKeyDown(unsigned char key) const;
  bool wasKeyDown(unsigned char key) const;
  DIMOUSESTATE2 getCurrentMouse() const {
    return mouseState;
  }
  DIMOUSESTATE2 getPreviousMouse() const {
    return previousMouseState;
  }
  POINT getCurrentMousePos() const { return mousePosition; }
  POINT getPreviousMousePos() const { return previousMousePosition; }
};
#endif
// Input Handler Source
#include "InputHandler.h"

InputHandler::InputHandler(HINSTANCE hInstance, HWND hWnd){
  this->hWnd = hWnd;
  ZeroMemory(keyboardState, sizeof(keyboardState));
  ZeroMemory(previousKeyboardState, sizeof(previousKeyboardState));
  ZeroMemory(&mouseState, sizeof(mouseState));
  ZeroMemory(&previousMouseState, sizeof(previousMouseState));

  DirectInput8Create(hInstance,
		     DIRECTINPUT_VERSION,
		     IID_IDirectInput8,
		     (void**)&dInput,
		     0);

  dInput->CreateDevice(GUID_SysKeyboard, &keyboard, 0);
  keyboard->SetDataFormat(&c_dfDIKeyboard);
  keyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
  keyboard->Acquire();

  dInput->CreateDevice(GUID_SysMouse, &mouse, 0);
  mouse->SetDataFormat(&c_dfDIMouse2);
  mouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
  mouse->Acquire();
}

InputHandler::~InputHandler(){
  mouse->Unacquire();
  mouse->Release();
  mouse = 0;

  keyboard->Unacquire();
  keyboard->Release();
  keyboard = 0;

  dInput->Release();
  dInput = 0;
}

void InputHandler::poll(){
  memcpy(previousKeyboardState, keyboardState, sizeof(keyboardState));
  keyboard->GetDeviceState(sizeof(keyboardState), (void**)keyboardState);

  previousMouseState = mouseState;
  mouse->GetDeviceState(sizeof(mouseState), (void**)&mouseState);

  previousMousePosition = mousePosition;
  GetCursorPos(&mousePosition);
  ScreenToClient(hWnd, &mousePosition);
}

bool InputHandler::isKeyDown(unsigned char key) const{
  if ((keyboardState[key] & 0x80) != 0)
    return true;
  return false;
}

bool InputHandler::wasKeyDown(unsigned char key) const{
  if ((previousKeyboardState[key] & 0x80) != 0)
    return true;
  return false;
}
// Game Class Header
#pragma once

#ifndef GAME_H
#define GAME_H

[...]
#include "InputHandler.h"

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

class Game
{
private:
  void createWindow(int nShowCmd);
  void initDirectX();
protected:
  HINSTANCE hInstance;
  HWND hWnd;
  IDirect3D9* d3d;
  IDirect3DDevice9* device;
  ID3DXSprite* sprite;
  InputHandler* inputHandler;
public:
  Game(HINSTANCE hInstance, int nShowCmd);
  virtual ~Game();
  virtual void initialise() = 0;
  virtual void loadContent() = 0;
  virtual void update(float frameTime) = 0;
  virtual void render() = 0;
  virtual void unloadContent() = 0;
  LRESULT msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  const InputHandler* getInputHandler() const { return inputHandler; }
};

extern Game* game;
#endif
// Game Source
#include "Game.h"

Game* game = 0;

Game::Game(HINSTANCE hInstance, int nShowCmd){
  this->hInstance = hInstance;
  createWindow(nShowCmd);
  initDirectX();
  inputHandler = new InputHandler(hInstance, hWnd);
}

Game::~Game(){
  delete inputHandler;
  inputHandler = 0;
  sprite->Release();
  sprite = 0;
  device->Release();
  device = 0;
  d3d->Release();
  d3d = 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
  if (game != 0)
    return game->msgProc(hWnd, msg, wParam, lParam);
  else
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

void Game::createWindow(int nShowCmd){
  WNDCLASSEX wc;
  ZeroMemory(&wc, sizeof(WNDCLASSEX));

  wc.cbSize = sizeof(WNDCLASSEX);
  wc.lpfnWndProc = WndProc;
  wc.hInstance = hInstance;
  wc.hIcon = LoadIcon(0, IDI_APPLICATION);
  wc.hCursor = LoadCursor(0, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
  wc.lpszClassName = L"GamesEngineering";

  RegisterClassEx(&wc);

  hWnd = CreateWindowEx(NULL,
                        L"GamesEngineering",
			L"GamesEngineering",
			WS_OVERLAPPEDWINDOW,
		        CW_USEDEFAULT,
			CW_USEDEFAULT,
			800,
			600,
			NULL,
			NULL,
			hInstance,
			NULL);

  ShowWindow(hWnd, nShowCmd);
  UpdateWindow(hWnd);
}

LRESULT Game::msgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
  switch (msg){
    case WM_CLOSE:
      DestroyWindow(hWnd);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hWnd, msg, wParam, lParam);
  }
  return 0;
}

void Game::initDirectX(){
  d3d = Direct3DCreate9(D3D_SDK_VERSION);

  D3DPRESENT_PARAMETERS d3dpp;
  ZeroMemory(&d3dpp, sizeof(d3dpp));
  d3dpp.Windowed = true;
  d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
  d3dpp.hDeviceWindow = hWnd;

  d3d->CreateDevice(D3DADAPTER_DEFAULT,
		    D3DDEVTYPE_HAL,
		    hWnd,
		    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		    &d3dpp,
		    &device);

  D3DXCreateSprite(device, &sprite);
}

and.. the main loop

#define DIRECTINPUT_VERSION 0x0800

#include "Game.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int nShowCmd)
{
  MSG msg;

  // Game creation here
  game->initialise();
  game->loadContent();

  __int64 cntsPerSec = 0;
  QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
  float secsPerCnt = 1.0f / (float)cntsPerSec;

  __int64 prevTimeStamp = 0;
  QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
  __int64 currTimeStamp = 0;

  while (true){
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    if (msg.message == WM_QUIT)
      break;

    QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
    float dt = (currTimeStamp - prevTimeStamp) * secsPerCnt;

    game->update(dt);
    game->render();
    prevTimeStamp = currTimeStamp;
  }

  game->unloadContent();
  return msg.wParam;
}

Published by

Luke Iwanski

Senior Graphics Programmer @ CD Projekt RED

Leave a Reply

Your email address will not be published. Required fields are marked *