// *************************************************************************************************
//
// Horde3D
// Next-Generation Graphics Engine
//
// Sample Application
// --------------------------------------
// Copyright (C) 2006-2011 Nicolas Schulz
//
//
// This sample source file is not covered by the EPL as the rest of the SDK
// and may be used without any restrictions. However, the EPL's disclaimer of
// warranty and liability shall be in effect for this file.
//
// *************************************************************************************************
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <SFML/Window.hpp>
#include "app.h"
// Configuration
const int appWidth = 1024;
const int appHeight = 576;
static bool fullScreen = false;
static int benchmarkLength = 600;
bool setupWindow( int, int, bool, const char* title );
static bool running;
static int mx0, my0;
static Application *app;
sf::Window* pSfmlWindow;
sf::Clock RenderClock;
double timeAtLastFrame;
double timeSinceLastFrame;
double timeAtCurrentFrame;
std::string extractAppPath( char *fullPath )
{
#ifdef __APPLE__
std::string s( fullPath );
for( int i = 0; i < 4; ++i )
s = s.substr( 0, s.rfind( "/" ) );
return s + "/../";
#else
const std::string s( fullPath );
if( s.find( "/" ) != std::string::npos )
return s.substr( 0, s.rfind( "/" ) ) + "/";
else if( s.find( "\\" ) != std::string::npos )
return s.substr( 0, s.rfind( "\\" ) ) + "\\";
else
return "";
#endif
}
int windowCloseListener()
{
running = false;
return 0;
}
void keyPressListener( int key )
{
if( !running ) return;
int width = appWidth, height = appHeight;
switch (key)
{
case sf::Key::Escape:
running = false;
break;
case sf::Key::F1:
app->release();
// Toggle fullscreen mode
fullScreen = !fullScreen;
setupWindow(appWidth, appHeight, fullScreen, app->getTitle());
app->init();
app->resize( width, height );
break;
//KLUDGE ALERT:
//The samples in trunk use GLFW keycodes to set keystates
//within Application. In order not to modify the sample code
//we play nice and set the GLFW keycoded array it is interested in
case sf::Key::Space:
app->setKeyState(32,true);
break;
case sf::Key::F3:
app->setKeyState(260,true);
break;
case sf::Key::F6:
app->setKeyState(263,true);
break;
case sf::Key::F7:
app->setKeyState(264,true);
break;
case sf::Key::F8:
app->setKeyState(265,true);
break;
case sf::Key::LShift:
app->setKeyState(287,true);
break;
case sf::Key::W:
app->setKeyState(int('W'),true);
break;
case sf::Key::A:
app->setKeyState(int('A'),true);
break;
case sf::Key::S:
app->setKeyState(int('S'),true);
break;
case sf::Key::D:
app->setKeyState(int('D'),true);
break;
}
}
void mouseMoveListener( int x, int y )
{
if( !running )
{
mx0 = x; my0 = y;
return;
}
app->mouseMoveEvent( (float)(x - mx0), (float)(my0 - y) );
mx0 = x; my0 = y;
}
bool setupWindow( int width, int height, bool fullscreen, const char* windowTitle = NULL)
{
//Initialise OpenGL context using SFML
sf::WindowSettings Settings; // Create a settings object to initialise OpenGL context with
Settings.DepthBits = 24; // Request a 24 bits depth buffer
Settings.StencilBits = 8; // Request a 8 bits stencil buffer
Settings.AntialiasingLevel = 2; // Request 2 levels of antialiasing
if(!windowTitle)
windowTitle = "SFML Chicago sample";
if (pSfmlWindow==NULL) //First time creation
{
pSfmlWindow = new sf::Window(sf::VideoMode(width, height, 32), //Create a width * height framebuffer with 32 bits per pixel
windowTitle, //Title for the window to be created
sf::Style::Close, //Create a window with a titlebar and close button
Settings); //Settings object to initialise the OpenGL context with
}
else //Reinitialisation of window
{
//Close the old window
pSfmlWindow->Close();
//Initialise a new window
if(fullscreen)
{
// Creating a fullscreen window with the best video mode supported
pSfmlWindow->Create(sf::VideoMode::GetMode(0),
windowTitle,
sf::Style::Fullscreen,
Settings);
}
else
{
pSfmlWindow->Create(sf::VideoMode(width, height, 32),
windowTitle,
sf::Style::Close,
Settings);
}
}
return true;
}
int main( int argc, char** argv )
{
printf("Starting SFML Chicago!\n");
// Initialize application and engine
app = new Application( extractAppPath(argv[0]) );
// Initialize a GLFW window
pSfmlWindow = NULL;
if( !setupWindow( appWidth, appHeight, fullScreen, app->getTitle() ) ) return -1;
// Check if benchmark mode is requested
bool benchmark = false;
if( argc > 1 && strcmp( argv[1], "-bm" ) == 0 )
{
benchmark = true;
//TODO: Equivalent in SFML
//glfwDisable( GLFW_AUTO_POLL_EVENTS );
}
if ( !app->init() )
{
std::cout << "Unable to initalize engine" << std::endl;
std::cout << "Make sure you have an OpenGL 2.0 compatible graphics card";
return -1;
}
app->resize( appWidth, appHeight );
pSfmlWindow->ShowMouseCursor(false);
int frames = 0;
float fps = 30.0f;
timeSinceLastFrame = RenderClock.GetElapsedTime();
RenderClock.Reset();
timeAtCurrentFrame += timeSinceLastFrame;
running = true;
// Game loop
while( running )
{
timeSinceLastFrame = RenderClock.GetElapsedTime();
RenderClock.Reset();
timeAtCurrentFrame += timeSinceLastFrame;
// Calc FPS
++frames;
if( !benchmark && frames >= 3 )
{
fps = frames / (float)timeSinceLastFrame;
if( fps < 5 ) fps = 30; // Handle breakpoints
frames = 0;
}
//Initialise all app keys' states to false
for( int i = 0; i < 320; ++i )
app->setKeyState(i,false);
// Inject inputs from SFML
sf::Event Event;
while (pSfmlWindow->GetEvent(Event))
{
// Window closed
if (Event.Type == sf::Event::Closed)
running = false;
// Key Press Event
else if (Event.Type == sf::Event::KeyPressed)
{
keyPressListener(Event.Key.Code);
}
else if(Event.Type == sf::Event::MouseMoved)
{
mouseMoveListener(Event.MouseMove.X,Event.MouseMove.Y);
}
}
app->keyStateHandler();
// Render
app->mainLoop( benchmark ? 60 : fps );
pSfmlWindow->Display();
if( benchmark && frames == benchmarkLength ) break;
}
pSfmlWindow->ShowMouseCursor(true);
// Show benchmark results
if( benchmark )
{
timeSinceLastFrame = RenderClock.GetElapsedTime();
RenderClock.Reset();
timeAtCurrentFrame += timeSinceLastFrame;
double avgFPS = benchmarkLength / timeSinceLastFrame;
char title[256];
sprintf( title, "Average FPS: %.2f", avgFPS );
//Simply write the logistics to console
printf("%s",title);
//TODO: Equivalent in SFML
// double startTime = glfwGetTime();
// while( glfwGetTime() - startTime < 5.0 ) {} // Sleep
}
// Quit
app->release();
delete app;
if(pSfmlWindow->IsOpened())
pSfmlWindow->Close();
delete pSfmlWindow;
return 0;
}