#include "Windows.h"
#include "stdio.h"
#include "sys\stat.h"
#include "de_client.h"
#include "MusicSystem.h"
#include "sample_clientshell.h"
// --------------------------------------------------------------- //
// Command IDs (mapped to keys in autoexec.cfg).
// --------------------------------------------------------------- //
#define COMMAND_LEFT 10
#define COMMAND_RIGHT 11
#define COMMAND_LOOKUP 15
#define COMMAND_LOOKDOWN 16
#define COMMAND_QUIT 17
// Some Helper Functions
DBOOL FileExists (char* strPath)
{
OFSTRUCT ofs;
HFILE hFile = OpenFile (strPath, &ofs, OF_EXIST);
if (hFile == HFILE_ERROR) return FALSE;
return TRUE;
}
// --------------------------------------------------------------- //
// These functions create the client shell for DirectEngine.
// --------------------------------------------------------------- //
ClientShellDE* CreateClientShell(ClientDE *pClient)
{
g_pClientDE = pClient;
return ((ClientShellDE*)new CSampleClientShell);
}
void DeleteClientShell(ClientShellDE *pShell)
{
delete ((CSampleClientShell*)pShell);
}
SETUP_CLIENTSHELL();
// --------------------------------------------------------------- //
// CSampleClientShell functions.
// --------------------------------------------------------------- //
CSampleClientShell::CSampleClientShell()
{
m_hCamera = DNULL;
}
DRESULT CSampleClientShell::OnEngineInitialized(struct RMode_t *pMode, DGUID *pGuid)
{
StartGameRequest request;
InitSoundInfo pSoundInfo;
// New addition
if (GetClientDE()->SetRenderMode (pMode) != LT_OK)
{
GetClientDE()->Shutdown();
return LT_ERROR;
}
// Initialize the sound
INITSOUNDINFO_INIT(pSoundInfo);
if (GetClientDE()->InitSound(&pSoundInfo) != LT_OK)
{
GetClientDE()->Shutdown();
return LT_ERROR;
}
// Display Dimensions setup
GetClientDE()->GetSurfaceDims(
GetClientDE()->GetScreenSurface(),
&(TheDisplayStats.ScreenWidth),
&(TheDisplayStats.ScreenHeight)
);
// And get the Midpoints
TheDisplayStats.MidScreenWidth = TheDisplayStats.ScreenWidth/2;
TheDisplayStats.MidScreenHeight = TheDisplayStats.ScreenHeight/2;
HUD = new cHUD();
HUD->init(this,"interface//hud//hud.pcx",
GetClientDE()->GetScreenSurface(),
&TheDisplayStats);
// Start playing the video
PlayMovie(GetClientDE(),"movies\\logo.smk");
return LT_OK;
}
void CSampleClientShell::OnEnterWorld()
{
ObjectCreateStruct createStruct;
INIT_OBJECTCREATESTRUCT(createStruct);
createStruct.m_ObjectType = OT_CAMERA;
m_hCamera = GetClientDE()->CreateObject(&createStruct);
m_Yaw = m_Pitch = m_Roll = 0.0f;
// Init CD Audio.
m_MusicTracker.init(GetClientDE(), DNULL, "GameWorld", 0);
m_MusicTracker.AddSong("2");
m_MusicTracker.Begin();
}
void CSampleClientShell::OnExitWorld()
{
if(m_hCamera)
{
GetClientDE()->DeleteObject(m_hCamera);
m_hCamera = DNULL;
}
m_MusicTracker.End();
}
void CSampleClientShell::Update()
{
HCONSOLEVAR hVar;
StartGameRequest request;
// What the state of the current Game?
// it could be :
// GAME_PAUSED The Game, she is paused
// GAME_MOVIE The Game, she is playing a movie
// GAME_PLAYING The Game, she is, how you say, rocking and rolling?
// GAME_OVER That's it man, Game Over man, Game over.
// GAME_MENU When we want to display a menu to the user
switch (m_nGameState)
{
case GAME_PLAYING:
UpdatePlayer();
break;
case GAME_MOVIE:
UpdateMoviesState();
break;
case GAME_MENU :
break;
case GAME_PAUSED:
break;
case GAME_OVER:
break;
case GAME_LOADLEVEL:
// Zero-out our request for safety.
memset(&request,0,sizeof(request));
// Look for the +runworld command-line parameter and start a world based on that.
hVar = GetClientDE()->GetConsoleVar("runworld");
sprintf(request.m_WorldName,"%s",GetClientDE()->GetVarValueString(hVar));
request.m_Type = STARTGAME_NORMAL;
GetClientDE()->StartGame(&request);
m_nGameState = GAME_PLAYING;
break;
default : break;
}
}
void CSampleClientShell::OnCommandOn(int command)
{
if (m_nGameState == GAME_PLAYING)
if(command == COMMAND_QUIT)
{
GetClientDE()->Shutdown();
};
}
void CSampleClientShell::OnKeyDown(int key, int rep)
{
CClientDE* pClientDE = GetClientDE();
if (!pClientDE) return;
if (m_nGameState == GAME_MOVIE)
{
if (key == VK_ESCAPE && pClientDE->IsVideoPlaying() == VIDEO_PLAYING)
{
if (pClientDE->StopVideo() == DE_OK)
{
m_nGameState = GAME_LOADLEVEL;
}
}
return;
}
}
void CSampleClientShell::PlayMovie(CClientDE* pClientDE, char * szMovieName)
{
DRESULT nResult;
// attempt to play the movie
if (FileExists(szMovieName))
nResult = GetClientDE()->StartVideo (szMovieName, PLAYBACK_FULLSCREEN);
else
nResult = LT_ERROR;
if (nResult != DE_OK)
m_nGameState = GAME_LOADLEVEL;
else
m_nGameState = GAME_MOVIE;
return;
}
void CSampleClientShell::UpdateMoviesState()
{
CClientDE* pClientDE = GetClientDE();
if (!pClientDE) return;
GetClientDE()->ClearScreen(DNULL,CLEARSCREEN_SCREEN | CLEARSCREEN_RENDER);
// If we're playing movies, see if the current one is finished...
pClientDE->UpdateVideo();
if (pClientDE->IsVideoPlaying() != VIDEO_PLAYING)
{
m_nGameState = GAME_LOADLEVEL;
}
GetClientDE()->FlipScreen(FLIPSCREEN_CANDRAWCONSOLE);
}
void CSampleClientShell::UpdatePlayer()
{
HLOCALOBJ hClientObj;
DVector pos;
DRotation rotation;
float radiansPerSec = 2.5f;
DFLOAT offsets[3];
HMESSAGEWRITE hMessage;
hClientObj = GetClientDE()->GetClientObject();
if(hClientObj)
{
GetClientDE()->GetObjectPos(hClientObj, &pos);
GetClientDE()->SetObjectPos(m_hCamera, &pos);
// Update our orientation. We do this on the client and send the
// angles to the server so mouse orientation is zero latency.
if(GetClientDE()->IsCommandOn(COMMAND_LEFT))
{
m_Pitch -= radiansPerSec * GetClientDE()->GetFrameTime();
}
if(GetClientDE()->IsCommandOn(COMMAND_RIGHT))
{
m_Pitch += radiansPerSec * GetClientDE()->GetFrameTime();
}
if(GetClientDE()->IsCommandOn(COMMAND_LOOKUP))
{
m_Yaw -= radiansPerSec * GetClientDE()->GetFrameTime();
}
if(GetClientDE()->IsCommandOn(COMMAND_LOOKDOWN))
{
m_Yaw += radiansPerSec * GetClientDE()->GetFrameTime();
}
GetClientDE()->GetAxisOffsets(offsets);
m_Pitch += offsets[0] / 100.0f;
m_Yaw += offsets[1] / 100.0f;
// Update our camera.
GetClientDE()->SetupEuler(&rotation, m_Yaw, m_Pitch, m_Roll);
GetClientDE()->SetObjectRotation(m_hCamera, &rotation);
// Send the orientation to the server. The server will update the
// player object rotation.
hMessage = GetClientDE()->StartMessage(1);
GetClientDE()->WriteToMessageRotation(hMessage, &rotation);
GetClientDE()->EndMessage(hMessage);
}
// Now Draw the world - Very important!
GetClientDE()->ClearScreen(DNULL,CLEARSCREEN_SCREEN | CLEARSCREEN_RENDER);
GetClientDE()->Start3D();
GetClientDE()->RenderCamera(m_hCamera);
GetClientDE()->StartOptimized2D();
HUD->Rende