// here we are, all the code
// look at mvx.h for more details
// I commented as best as I could
// - Vulcan
#include "mvx.h"
mvxEngine::mvxEngine()
{
mvxD3D = NULL; // used to create a D3D devixe
mvxDevice = NULL; // the rendering device
mvxAudioLoader = NULL; // Audio Loader
mvxPerformance = NULL; // the sound playing device
mvxInput = NULL; // Direct input object
mvxKeyboard = NULL; // direct input keyboard
mvxMouse = NULL; // direct input mouse
// default all values
strcpy(mvxName, "mvxApp");
mvxMWH = 0;
mvxWindowed = false;
mvxWidth = 0;
mvxHeight = 0;
mvxBPP = 16;
mvxAudio = false;
strcpy(mvxAudioPath, "\");
mvxDInput = false;
mvxNetwork = false;
mvxVideo = false;
mvxDebug = false;
}
// close down
mvxEngine::~mvxEngine()
{
mvxDestroy();
}
void mvxEngine::mvxDestroy()
{
if (mvxPerformance)
{
mvxPerformance->CloseDown();
mvxPerformance->Release();
mvxPerformance = NULL;
}
if (mvxAudioLoader)
{
mvxAudioLoader->Release();
mvxAudioLoader = NULL;
}
CoUninitialize();
if (mvxMouse)
{
mvxMouse->Unacquire();
mvxMouse->Release();
mvxMouse = NULL;
}
if (mvxKeyboard)
{
mvxKeyboard->Unacquire();
mvxKeyboard->Release();
mvxKeyboard = NULL;
}
if (mvxInput)
{
mvxInput->Release();
mvxInput = NULL;
}
if (mvxDevice)
{
mvxDevice->Release();
mvxDevice = NULL;
}
if (mvxD3D)
{
mvxD3D->Release();
mvxD3D = NULL;
}
if (mvxDebug)
mvxDebugOut.close();
}
void mvxEngine::mvxDebugOutTime()
{
_SYSTEMTIME time;
GetSystemTime(&time);
if (mvxDebug)
{
mvxDebugOut << time.wMonth << "/" << time.wDay << "/"
<< time.wYear << " at " << time.wHour << ":" << time.wMinute
<< ":" << time.wSecond << endl;
}
}
// init the engine
int mvxEngine::mvxInit(HINSTANCE hInstance)
{
if (mvxDebug)
{
mvxDebugOut.open("debug.txt", ios::out | ios::trunc);
mvxDebugOut << "The MVX game engine debug file" << endl
<< "Using MVX version " << MVX_VERSION << endl
<< "Run on ";
mvxDebugOutTime();
mvxDebugOut << "mvxGameEngine creation paramaters" << endl
<< "1 = true, 0 = false" << endl
<< "Application name: " << mvxName << endl
<< "Initial width: " << mvxWidth << endl
<< "Initial height: " << mvxHeight << endl
<< "Windowed application: " << mvxWindowed << endl
<< "Bits per pixel: " << mvxBPP << endl
<< "Enable DirectSound: " << mvxAudio << endl
<< "Audio File Path: " << mvxAudioPath << endl
<< "Enable DirectInput: " << mvxDInput << endl
<< "Enable DirectPlay: " << mvxNetwork << endl
<< "Enable DirectShow: " << mvxVideo << endl;
}
// create the window, based on desire flags
WNDCLASSEX mvxWinclass; // this will hold the class we create
HWND hwnd; // generic window handle
// first fill in the window class stucture
mvxWinclass.cbSize = sizeof(WNDCLASSEX);
mvxWinclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
mvxWinclass.lpfnWndProc = (WNDPROC)WindowProc;
mvxWinclass.cbClsExtra = 0;
mvxWinclass.cbWndExtra = 0;
mvxWinclass.hInstance = hInstance;
mvxWinclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
mvxWinclass.hCursor = LoadCursor(NULL, NULL);
mvxWinclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
mvxWinclass.lpszMenuName = NULL;
mvxWinclass.lpszClassName = WINDOW_CLASS_NAME;
mvxWinclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// register the window class
if (!RegisterClassEx(&mvxWinclass))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Window class registration failed" << endl;
}
return FAIL;
}
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
WINDOW_CLASS_NAME, // class
mvxName, // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, // initial x,y
mvxWidth, mvxHeight, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hInstance, // instance of this application
NULL))) // extra creation parms
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Window creation failed" << endl;
}
return FAIL;
}
// save main window handle
mvxMWH = hwnd;
// intialize directX, based upon desired flags
if( NULL == ( mvxD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "DirectX graphics init failed" << endl;
}
return FAIL;
}
D3DDISPLAYMODE mvxD3DDisplay;
if( FAILED( mvxD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &mvxD3DDisplay ) ) )
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed getting the adapter display mode" << endl;
}
return FAIL;
}
D3DPRESENT_PARAMETERS mvxD3DPP;
ZeroMemory(&mvxD3DPP, sizeof(mvxD3DPP));
mvxD3DPP.SwapEffect = D3DSWAPEFFECT_FLIP;
mvxD3DPP.Windowed = mvxWindowed;
mvxD3DPP.BackBufferFormat = mvxD3DDisplay.Format;
mvxD3DPP.hDeviceWindow = mvxMWH;
mvxD3DPP.BackBufferWidth = mvxWidth;
mvxD3DPP.BackBufferHeight = mvxHeight;
mvxD3DPP.EnableAutoDepthStencil = TRUE;
mvxD3DPP.AutoDepthStencilFormat = D3DFMT_D16; // 16bpp
if (mvxWindowed)
{
mvxD3DPP.FullScreen_RefreshRateInHz = 0;
mvxD3DPP.FullScreen_PresentationInterval = 0;
}
else
{
mvxD3DPP.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
mvxD3DPP.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}
if( FAILED( mvxD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mvxMWH,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&mvxD3DPP, &mvxDevice ) ) )
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed creating the Direct3D Device" << endl;
}
return FAIL;
}
// lighting enable
mvxDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
mvxDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
// init direct input
if (mvxDInput)
{
// init dinput object
if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&mvxInput, NULL)))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed creating Direct Input" << endl;
}
return FAIL;
}
// create the keyboard device
if (FAILED(mvxInput->CreateDevice(GUID_SysKeyboard, &mvxKeyboard, NULL)))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed creating the keyboard Direct Input device" << endl;
}
return FAIL;
}
// set keyboard data format
if (FAILED(mvxKeyboard->SetDataFormat(&c_dfDIKeyboard)))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed setting data format of keyboard" << endl;
}
return FAIL;
}
// Set the cooperative level
if (FAILED(mvxKeyboard->SetCooperativeLevel(mvxMWH, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed setting cooperative level of keyboard" << endl;
}
return FAIL;
}
// acquire the keyboard
mvxKeyboard->Acquire();
// mouse init time
if (FAILED(mvxInput->CreateDevice(GUID_SysMouse, &mvxMouse, NULL)))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed creating the mouse Direct Input device" << endl;
}
return FAIL;
}
// set the data format
if (FAILED(mvxMouse->SetDataFormat(&c_dfDIMouse)))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed setting the format of the mouse" << endl;
}
return FAIL;
}
// you better cooperate with windows, or else...
if (FAILED(mvxMouse->SetCooperativeLevel(mvxMWH, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
{
if (mvxDebug)
{
mvxDebugOut << "At ";
mvxDebugOutTime();
mvxDebugOut << "Failed setting cooperative level of mouse" << endl;
}
return FAIL;
}
// acquire the mouse
mvxMouse->Acquire();
}
// init directmusic
if (mvxAudio)
{
CoInitialize(NULL);
CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, IID_IDirectMusicLoader8, (void**)&mvxAudioLoader);
CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, IID_IDirectMusicPerformance8, (void**)&mvxPerformance );
mvxPerformance->InitAudio(NULL, NULL, mvxMWH, DMUS_APATH_SHARED_STEREOPLUSREVERB, 64, DMUS_AUDIOF_ALL, NULL);
// Convert the audio path to Unicode.
WCHAR wstrSearchPath[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, mvxAudioPath, -1, wstrSearchPath, MAX_PATH );
// Set the search directory.
mvxAudioLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wstrSearchPath, FALSE);
}
return OK;
}
// read mouse data
void mvxEngine::mvxReadMouse()
{
if (!mvxDInput)
return;
HRESULT hr;
hr = mvxMouse->GetDeviceState(sizeof(mvxMouseState),(LPVOID)&mvxMouseState);
if FAILED(hr)
{
// If it failed, the device has probably been lost.
// attempt to reacquire it
if (hr == DIERR_INPUTLOST)
mvxMouse->Acquire();
return;
}
}
// read key data
void mvxEngine::mvxReadKeys()
{
if (!mvxDInput)
return;
HRESULT hr;
hr = mvxKeyboard->GetDeviceState(sizeof(mvxKeyBuffer),(LPVOID)&mvxKeyBuffer);
if FAILED(hr)
{
// If it failed, the device has probably been lost.
// attempt to reacquire it
if (hr == DIERR_INPUTLOST)
mvxKeyboard->Acquire();
return;
}
}
void mvxEngine::mvxBegin()
{
// Begin the scene
mvxDevice->BeginScene();
}
// clear the back buffer
void mvxEngine::mvxClear(DWORD color)
{
// Clear the backbuffer
mvxDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1, 0);
}
// stop rendering
void mvxEngine::mvxEnd()
{
// End the scene
mvxDevice->EndScene();
}
// page flip
void mvxEngine::mvxShow()
{
// Present the backbuffer contents to the display
mvxDevice->Present( NULL, NULL, NULL, NULL );
}
// audio constructors
mvxMedia::mvxMedia()
{
mvxAudio = NULL;
}
mvxMedia::~mvxMedia()
{
mvxDestroy();
}
// load an audio file into a media class
int mvxMedia::mvxLoad(char* filename, IDirectMusicLoader8* loader, IDirectMusicPerformance8* performance)
{
// convert filename to Unicode
WCHAR wstrFile[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, filename, -1, wstrFile, MAX_PATH );
loader->LoadObjectFromFile(CLSID_DirectMusicSegment, IID_IDirectMusicSegment8, wstrFile, (LPVOID*)&mvxAudio);
mvxAudio->Download( performance );
return OK;
}
int mvxMedia::mvxPlay(IDirectMusicPerformance8* performance)
{
if (mvxAudio)
{
performance->PlaySegmentEx(mvxAudio, NULL, NULL, 0, 0, NULL, NULL, NULL);
return OK;
}
else
return FAIL;
}
int mvxMedia::mvxStop(IDirectMusicPerformance8* performance)
{
if (mvxAudio)
{
performance->Stop(mvxAudio, NULL, 0, 0);
return OK;
}
else
return FAIL;
}
void mvxMedia::mvxDestroy()
{
if (mvxAudio)
{
mvxAudio->Release();
}
}