mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 08:39:18 +02:00
refactoring: basic application code wrapper
This commit is contained in:
@@ -18,6 +18,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "MdlMngr.h"
|
#include "MdlMngr.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
|
#include "simulationtime.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class TEvent;
|
|||||||
|
|
||||||
class TAnimContainer
|
class TAnimContainer
|
||||||
{ // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista
|
{ // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista
|
||||||
friend class TAnimModel;
|
friend TAnimModel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Math3D::vector3 vRotateAngles; // dla obrotów Eulera
|
Math3D::vector3 vRotateAngles; // dla obrotów Eulera
|
||||||
@@ -124,8 +124,8 @@ class TAnimAdvanced
|
|||||||
// opakowanie modelu, określające stan egzemplarza
|
// opakowanie modelu, określające stan egzemplarza
|
||||||
class TAnimModel : public scene::basic_node {
|
class TAnimModel : public scene::basic_node {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
friend class ui_layer;
|
friend ui_layer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Ra: zestaw klas do robienia wskaźników, aby uporządkować nagłówki
|
// Ra: zestaw klas do robienia wskaźników, aby uporządkować nagłówki
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
class opengl_renderer;
|
||||||
class TTrack; // odcinek trajektorii
|
class TTrack; // odcinek trajektorii
|
||||||
class TEvent;
|
class TEvent;
|
||||||
class TTrain; // pojazd sterowany
|
class TTrain; // pojazd sterowany
|
||||||
@@ -29,8 +30,9 @@ class TTraction; // drut
|
|||||||
class TTractionPowerSource; // zasilanie drutów
|
class TTractionPowerSource; // zasilanie drutów
|
||||||
class TWorld;
|
class TWorld;
|
||||||
class TCamera;
|
class TCamera;
|
||||||
class simulation_time;
|
class scenario_time;
|
||||||
class TMoverParameters;
|
class TMoverParameters;
|
||||||
|
class ui_layer;
|
||||||
|
|
||||||
namespace scene {
|
namespace scene {
|
||||||
struct node_data;
|
struct node_data;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
#include "application.h"
|
||||||
#include "LPT.h"
|
#include "LPT.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "PoKeys55.h"
|
#include "PoKeys55.h"
|
||||||
@@ -247,7 +248,7 @@ void Console::BitsUpdate(int mask)
|
|||||||
|
|
||||||
bool Console::Pressed(int x)
|
bool Console::Pressed(int x)
|
||||||
{ // na razie tak - czyta się tylko klawiatura
|
{ // na razie tak - czyta się tylko klawiatura
|
||||||
if (glfwGetKey(Global.window, x) == GLFW_TRUE)
|
if (glfwGetKey(Application.window(), x) == GLFW_TRUE)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -22,10 +22,11 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "DynObj.h"
|
#include "DynObj.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "MemCell.h"
|
#include "MemCell.h"
|
||||||
#include "World.h"
|
#include "world.h"
|
||||||
#include "utilities.h"
|
#include "simulationtime.h"
|
||||||
#include "McZapkie/MOVER.h"
|
|
||||||
#include "track.h"
|
#include "track.h"
|
||||||
|
#include "station.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
#define LOGVELOCITY 0
|
#define LOGVELOCITY 0
|
||||||
#define LOGORDERS 1
|
#define LOGORDERS 1
|
||||||
|
|||||||
2
DynObj.h
2
DynObj.h
@@ -157,7 +157,7 @@ struct material_data {
|
|||||||
|
|
||||||
class TDynamicObject { // klasa pojazdu
|
class TDynamicObject { // klasa pojazdu
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool bDynamicRemove; // moved from ground
|
static bool bDynamicRemove; // moved from ground
|
||||||
|
|||||||
468
EU07.cpp
468
EU07.cpp
@@ -7,8 +7,8 @@ obtain one at
|
|||||||
http://mozilla.org/MPL/2.0/.
|
http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
MaSzyna EU07 locomotive simulator
|
MaSzyna EU07 locomotive simulator
|
||||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
Authors:
|
Authors:
|
||||||
@@ -16,475 +16,27 @@ MarcinW, McZapkie, Shaxbee, ABu, nbmx, youBy, Ra, winger, mamut, Q424,
|
|||||||
Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
|
Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
|
||||||
*/
|
*/
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#ifdef CAN_I_HAS_LIBPNG
|
|
||||||
#include <png.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "World.h"
|
#include "application.h"
|
||||||
#include "simulation.h"
|
#include "logs.h"
|
||||||
#include "sceneeditor.h"
|
|
||||||
#include "Globals.h"
|
|
||||||
#include "timer.h"
|
|
||||||
#include "Logs.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "uilayer.h"
|
|
||||||
#include "audiorenderer.h"
|
|
||||||
#include "keyboardinput.h"
|
|
||||||
#include "mouseinput.h"
|
|
||||||
#include "gamepadinput.h"
|
|
||||||
#include "Console.h"
|
|
||||||
#include "uart.h"
|
|
||||||
#include "PyInt.h"
|
|
||||||
|
|
||||||
#ifdef EU07_BUILD_STATIC
|
|
||||||
#pragma comment( lib, "glfw3.lib" )
|
|
||||||
#pragma comment( lib, "glew32s.lib" )
|
|
||||||
#else
|
|
||||||
#ifdef _WIN32
|
|
||||||
#pragma comment( lib, "glfw3dll.lib" )
|
|
||||||
#else
|
|
||||||
#pragma comment( lib, "glfw3.lib" )
|
|
||||||
#endif
|
|
||||||
#pragma comment( lib, "glew32.lib" )
|
|
||||||
#endif // build_static
|
|
||||||
#pragma comment( lib, "opengl32.lib" )
|
|
||||||
#pragma comment( lib, "glu32.lib" )
|
|
||||||
#pragma comment( lib, "openal32.lib")
|
|
||||||
#pragma comment( lib, "setupapi.lib" )
|
|
||||||
#pragma comment( lib, "python27.lib" )
|
|
||||||
#pragma comment( lib, "libserialport-0.lib" )
|
|
||||||
#pragma comment (lib, "dbghelp.lib")
|
|
||||||
#pragma comment (lib, "version.lib")
|
|
||||||
#ifdef CAN_I_HAS_LIBPNG
|
|
||||||
#pragma comment (lib, "libpng16.lib")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
|
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TWorld World;
|
int main( int argc, char *argv[] ) {
|
||||||
|
|
||||||
namespace input {
|
|
||||||
|
|
||||||
keyboard_input Keyboard;
|
|
||||||
mouse_input Mouse;
|
|
||||||
gamepad_input Gamepad;
|
|
||||||
glm::dvec2 mouse_pickmodepos; // stores last mouse position in control picking mode
|
|
||||||
std::unique_ptr<uart_input> uart;
|
|
||||||
user_command command; // currently issued control command, if any
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CAN_I_HAS_LIBPNG
|
|
||||||
void screenshot_save_thread( char *img )
|
|
||||||
{
|
|
||||||
png_image png;
|
|
||||||
memset(&png, 0, sizeof(png_image));
|
|
||||||
png.version = PNG_IMAGE_VERSION;
|
|
||||||
png.width = Global.iWindowWidth;
|
|
||||||
png.height = Global.iWindowHeight;
|
|
||||||
png.format = PNG_FORMAT_RGB;
|
|
||||||
|
|
||||||
char datetime[64];
|
|
||||||
time_t timer;
|
|
||||||
struct tm* tm_info;
|
|
||||||
time(&timer);
|
|
||||||
tm_info = localtime(&timer);
|
|
||||||
strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", tm_info);
|
|
||||||
|
|
||||||
uint64_t perf;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&perf);
|
|
||||||
|
|
||||||
std::string filename = "screenshots/" + std::string(datetime) +
|
|
||||||
"_" + std::to_string(perf) + ".png";
|
|
||||||
|
|
||||||
if (png_image_write_to_file(&png, filename.c_str(), 0, img, -Global.iWindowWidth * 3, nullptr) == 1)
|
|
||||||
WriteLog("saved " + filename + ".");
|
|
||||||
else
|
|
||||||
WriteLog("failed to save screenshot.");
|
|
||||||
|
|
||||||
delete[] img;
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_screenshot()
|
|
||||||
{
|
|
||||||
char *img = new char[Global.iWindowWidth * Global.iWindowHeight * 3];
|
|
||||||
glReadPixels(0, 0, Global.iWindowWidth, Global.iWindowHeight, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
|
|
||||||
|
|
||||||
std::thread t(screenshot_save_thread, img);
|
|
||||||
t.detach();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void window_resize_callback(GLFWwindow *window, int w, int h)
|
|
||||||
{
|
|
||||||
// NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
|
|
||||||
// TBD, TODO: merge them?
|
|
||||||
Global.iWindowWidth = w;
|
|
||||||
Global.iWindowHeight = h;
|
|
||||||
Global.fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
|
|
||||||
glViewport(0, 0, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cursor_pos_callback(GLFWwindow *window, double x, double y)
|
|
||||||
{
|
|
||||||
if( false == Global.ControlPicking ) {
|
|
||||||
glfwSetCursorPos( window, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// give the potential event recipient a shot at it, in the virtual z order
|
|
||||||
if( true == scene::Editor.on_mouse_move( x, y ) ) { return; }
|
|
||||||
input::Mouse.move( x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ) {
|
|
||||||
|
|
||||||
if( ( button != GLFW_MOUSE_BUTTON_LEFT )
|
|
||||||
&& ( button != GLFW_MOUSE_BUTTON_RIGHT ) ) {
|
|
||||||
// we don't care about other mouse buttons at the moment
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// give the potential event recipient a shot at it, in the virtual z order
|
|
||||||
if( true == scene::Editor.on_mouse_button( button, action ) ) { return; }
|
|
||||||
input::Mouse.button( button, action );
|
|
||||||
}
|
|
||||||
|
|
||||||
void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods ) {
|
|
||||||
|
|
||||||
Global.shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false;
|
|
||||||
Global.ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false;
|
|
||||||
Global.altState = ( mods & GLFW_MOD_ALT ) ? true : false;
|
|
||||||
|
|
||||||
// give the ui first shot at the input processing...
|
|
||||||
if( true == UILayer.on_key( key, action ) ) { return; }
|
|
||||||
if( true == scene::Editor.on_key( key, action ) ) { return; }
|
|
||||||
// ...if the input is left untouched, pass it on
|
|
||||||
input::Keyboard.key( key, action );
|
|
||||||
|
|
||||||
if( ( true == Global.InputMouse )
|
|
||||||
&& ( ( key == GLFW_KEY_LEFT_ALT )
|
|
||||||
|| ( key == GLFW_KEY_RIGHT_ALT ) ) ) {
|
|
||||||
// if the alt key was pressed toggle control picking mode and set matching cursor behaviour
|
|
||||||
if( action == GLFW_RELEASE ) {
|
|
||||||
|
|
||||||
if( Global.ControlPicking ) {
|
|
||||||
// switch off
|
|
||||||
glfwGetCursorPos( window, &input::mouse_pickmodepos.x, &input::mouse_pickmodepos.y );
|
|
||||||
UILayer.set_cursor( GLFW_CURSOR_DISABLED );
|
|
||||||
glfwSetCursorPos( window, 0, 0 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// enter picking mode
|
|
||||||
glfwSetCursorPos( window, input::mouse_pickmodepos.x, input::mouse_pickmodepos.y );
|
|
||||||
UILayer.set_cursor( GLFW_CURSOR_NORMAL );
|
|
||||||
}
|
|
||||||
// actually toggle the mode
|
|
||||||
Global.ControlPicking = !Global.ControlPicking;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( key == GLFW_KEY_LEFT_SHIFT )
|
|
||||||
|| ( key == GLFW_KEY_LEFT_CONTROL )
|
|
||||||
|| ( key == GLFW_KEY_LEFT_ALT )
|
|
||||||
|| ( key == GLFW_KEY_RIGHT_SHIFT )
|
|
||||||
|| ( key == GLFW_KEY_RIGHT_CONTROL )
|
|
||||||
|| ( key == GLFW_KEY_RIGHT_ALT ) ) {
|
|
||||||
// don't bother passing these
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( action == GLFW_PRESS || action == GLFW_REPEAT ) {
|
|
||||||
|
|
||||||
World.OnKeyDown( key );
|
|
||||||
|
|
||||||
#ifdef CAN_I_HAS_LIBPNG
|
|
||||||
switch( key )
|
|
||||||
{
|
|
||||||
case GLFW_KEY_PRINT_SCREEN: {
|
|
||||||
make_screenshot();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: { break; }
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void focus_callback( GLFWwindow *window, int focus )
|
|
||||||
{
|
|
||||||
if( Global.bInactivePause ) // jeśli ma być pauzowanie okna w tle
|
|
||||||
if( focus )
|
|
||||||
Global.iPause &= ~4; // odpauzowanie, gdy jest na pierwszym planie
|
|
||||||
else
|
|
||||||
Global.iPause |= 4; // włączenie pauzy, gdy nieaktywy
|
|
||||||
}
|
|
||||||
|
|
||||||
void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) {
|
|
||||||
|
|
||||||
if( Global.ctrlState ) {
|
|
||||||
// ctrl + scroll wheel adjusts fov in debug mode
|
|
||||||
Global.FieldOfView = clamp( static_cast<float>(Global.FieldOfView - yoffset * 20.0 / Global.fFpsAverage), 15.0f, 75.0f );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
|
||||||
}
|
|
||||||
|
|
||||||
LONG CALLBACK unhandled_handler(::EXCEPTION_POINTERS* e);
|
|
||||||
LRESULT APIENTRY WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
extern HWND Hwnd;
|
|
||||||
extern WNDPROC BaseWindowProc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
#if defined(_MSC_VER) && defined (_DEBUG)
|
|
||||||
// memory leaks
|
|
||||||
_CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_LEAK_CHECK_DF );
|
|
||||||
// floating point operation errors
|
|
||||||
auto state = _clearfp();
|
|
||||||
state = _control87( 0, 0 );
|
|
||||||
// this will turn on FPE for #IND and zerodiv
|
|
||||||
state = _control87( state & ~( _EM_ZERODIVIDE | _EM_INVALID ), _MCW_EM );
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
::SetUnhandledExceptionFilter( unhandled_handler );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!glfwInit())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
DeleteFile( "log.txt" );
|
|
||||||
DeleteFile( "errors.txt" );
|
|
||||||
_mkdir("logs");
|
|
||||||
#endif
|
|
||||||
Global.LoadIniFile("eu07.ini");
|
|
||||||
|
|
||||||
// hunter-271211: ukrywanie konsoli
|
|
||||||
if( Global.iWriteLogEnabled & 2 )
|
|
||||||
{
|
|
||||||
AllocConsole();
|
|
||||||
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN );
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
std::string executable( argv[ 0 ] ); auto const pathend = executable.rfind( '\\' );
|
|
||||||
Global.ExecutableName =
|
|
||||||
( pathend != std::string::npos ?
|
|
||||||
executable.substr( executable.rfind( '\\' ) + 1 ) :
|
|
||||||
executable );
|
|
||||||
*/
|
|
||||||
// retrieve product version from the file's version data table
|
|
||||||
{
|
|
||||||
auto const fileversionsize = ::GetFileVersionInfoSize( argv[ 0 ], NULL );
|
|
||||||
std::vector<BYTE>fileversiondata; fileversiondata.resize( fileversionsize );
|
|
||||||
if( ::GetFileVersionInfo( argv[ 0 ], 0, fileversionsize, fileversiondata.data() ) ) {
|
|
||||||
|
|
||||||
struct lang_codepage {
|
|
||||||
WORD language;
|
|
||||||
WORD codepage;
|
|
||||||
} *langcodepage;
|
|
||||||
UINT datasize;
|
|
||||||
|
|
||||||
::VerQueryValue(
|
|
||||||
fileversiondata.data(),
|
|
||||||
TEXT( "\\VarFileInfo\\Translation" ),
|
|
||||||
(LPVOID*)&langcodepage,
|
|
||||||
&datasize );
|
|
||||||
|
|
||||||
std::string subblock; subblock.resize( 50 );
|
|
||||||
::StringCchPrintf(
|
|
||||||
&subblock[0], subblock.size(),
|
|
||||||
TEXT( "\\StringFileInfo\\%04x%04x\\ProductVersion" ),
|
|
||||||
langcodepage->language,
|
|
||||||
langcodepage->codepage );
|
|
||||||
|
|
||||||
VOID *stringdata;
|
|
||||||
if( ::VerQueryValue(
|
|
||||||
fileversiondata.data(),
|
|
||||||
subblock.data(),
|
|
||||||
&stringdata,
|
|
||||||
&datasize ) ) {
|
|
||||||
|
|
||||||
Global.asVersion = std::string( reinterpret_cast<char*>(stringdata) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i)
|
|
||||||
{
|
|
||||||
std::string token(argv[i]);
|
|
||||||
|
|
||||||
if (token == "-e3d") {
|
|
||||||
if (Global.iConvertModels > 0)
|
|
||||||
Global.iConvertModels = -Global.iConvertModels;
|
|
||||||
else
|
|
||||||
Global.iConvertModels = -7; // z optymalizacją, bananami i prawidłowym Opacity
|
|
||||||
}
|
|
||||||
else if (i + 1 < argc && token == "-s")
|
|
||||||
Global.SceneryFile = std::string(argv[++i]);
|
|
||||||
else if (i + 1 < argc && token == "-v")
|
|
||||||
{
|
|
||||||
std::string v(argv[++i]);
|
|
||||||
std::transform(v.begin(), v.end(), v.begin(), ::tolower);
|
|
||||||
Global.asHumanCtrlVehicle = v;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout
|
|
||||||
<< "usage: " << std::string(argv[0])
|
|
||||||
<< " [-s sceneryfilepath]"
|
|
||||||
<< " [-v vehiclename]"
|
|
||||||
<< " [-e3d]"
|
|
||||||
<< std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// match requested video mode to current to allow for
|
|
||||||
// fullwindow creation when resolution is the same
|
|
||||||
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
|
|
||||||
const GLFWvidmode *vmode = glfwGetVideoMode(monitor);
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_RED_BITS, vmode->redBits);
|
|
||||||
glfwWindowHint(GLFW_GREEN_BITS, vmode->greenBits);
|
|
||||||
glfwWindowHint(GLFW_BLUE_BITS, vmode->blueBits);
|
|
||||||
glfwWindowHint(GLFW_REFRESH_RATE, vmode->refreshRate);
|
|
||||||
|
|
||||||
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
|
||||||
if( Global.iMultisampling > 0 ) {
|
|
||||||
glfwWindowHint( GLFW_SAMPLES, 1 << Global.iMultisampling );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Global.bFullScreen)
|
|
||||||
{
|
|
||||||
// match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode
|
|
||||||
Global.iWindowWidth = vmode->width;
|
|
||||||
Global.iWindowHeight = vmode->height;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWwindow *window =
|
|
||||||
glfwCreateWindow(
|
|
||||||
Global.iWindowWidth,
|
|
||||||
Global.iWindowHeight,
|
|
||||||
Global.AppName.c_str(),
|
|
||||||
( Global.bFullScreen ?
|
|
||||||
monitor :
|
|
||||||
nullptr),
|
|
||||||
nullptr );
|
|
||||||
|
|
||||||
if (!window)
|
|
||||||
{
|
|
||||||
std::cout << "failed to create window" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
glfwSwapInterval(Global.VSync ? 1 : 0); //vsync
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //capture cursor
|
|
||||||
glfwSetCursorPos(window, 0.0, 0.0);
|
|
||||||
glfwSetFramebufferSizeCallback(window, window_resize_callback);
|
|
||||||
glfwSetCursorPosCallback(window, cursor_pos_callback);
|
|
||||||
glfwSetMouseButtonCallback( window, mouse_button_callback );
|
|
||||||
glfwSetKeyCallback(window, key_callback);
|
|
||||||
glfwSetScrollCallback( window, scroll_callback );
|
|
||||||
glfwSetWindowFocusCallback(window, focus_callback);
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
|
||||||
window_resize_callback(window, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glewInit() != GLEW_OK)
|
|
||||||
{
|
|
||||||
std::cout << "failed to init GLEW" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// setup wrapper for base glfw window proc, to handle copydata messages
|
|
||||||
Hwnd = glfwGetWin32Window( window );
|
|
||||||
BaseWindowProc = (WNDPROC)::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc );
|
|
||||||
// switch off the topmost flag
|
|
||||||
::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( ( false == GfxRenderer.Init( window ) )
|
|
||||||
|| ( false == UILayer.init( window ) ) ) {
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Global.bSoundEnabled ) {
|
|
||||||
Global.bSoundEnabled &= audio::renderer.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
input::Keyboard.init();
|
|
||||||
input::Mouse.init();
|
|
||||||
input::Gamepad.init();
|
|
||||||
if( true == Global.uart_conf.enable ) {
|
|
||||||
input::uart = std::make_unique<uart_input>();
|
|
||||||
input::uart->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
Global.pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
|
|
||||||
try {
|
try {
|
||||||
if( false == World.Init( window ) ) {
|
auto result { Application.init( argc, argv ) };
|
||||||
ErrorLog( "Simulation setup failed" );
|
if( result == 0 ) {
|
||||||
return -1;
|
result = Application.run();
|
||||||
}
|
}
|
||||||
|
Application.exit();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch( std::bad_alloc const &Error ) {
|
catch( std::bad_alloc const &Error ) {
|
||||||
|
|
||||||
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
|
||||||
Console *pConsole = new Console(); // Ra: nie wiem, czy ma to sens, ale jakoś zainicjowac trzeba
|
|
||||||
#endif
|
|
||||||
if( Global.iConvertModels < 0 ) {
|
|
||||||
Global.iConvertModels = -Global.iConvertModels;
|
|
||||||
World.CreateE3D( szModelPath ); // rekurencyjne przeglądanie katalogów
|
|
||||||
World.CreateE3D( szDynamicPath, true );
|
|
||||||
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
|
|
||||||
#ifdef _WIN32
|
|
||||||
Console::On(); // włączenie konsoli
|
|
||||||
#endif
|
|
||||||
try {
|
|
||||||
while( ( false == glfwWindowShouldClose( window ) )
|
|
||||||
&& ( true == World.Update() )
|
|
||||||
&& ( true == GfxRenderer.Render() ) ) {
|
|
||||||
glfwPollEvents();
|
|
||||||
input::Keyboard.poll();
|
|
||||||
if( true == Global.InputMouse ) { input::Mouse.poll(); }
|
|
||||||
if( true == Global.InputGamepad ) { input::Gamepad.poll(); }
|
|
||||||
if( input::uart != nullptr ) { input::uart->poll(); }
|
|
||||||
// TODO: wrap current command in object, include other input sources
|
|
||||||
input::command = (
|
|
||||||
input::Mouse.command() != user_command::none ?
|
|
||||||
input::Mouse.command() :
|
|
||||||
input::Keyboard.command() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch( std::bad_alloc const &Error ) {
|
|
||||||
|
|
||||||
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
|
|
||||||
SafeDelete( pConsole );
|
|
||||||
#endif
|
|
||||||
SafeDelete( simulation::Region );
|
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
glfwTerminate();
|
|
||||||
|
|
||||||
TPythonInterpreter::killInstance();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "world.h"
|
#include "simulationtime.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ struct global_settings {
|
|||||||
// members
|
// members
|
||||||
// data items
|
// data items
|
||||||
// TODO: take these out of the settings
|
// TODO: take these out of the settings
|
||||||
GLFWwindow *window{ nullptr };
|
|
||||||
bool shiftState{ false }; //m7todo: brzydko
|
bool shiftState{ false }; //m7todo: brzydko
|
||||||
bool ctrlState{ false };
|
bool ctrlState{ false };
|
||||||
bool altState{ false };
|
bool altState{ false };
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
|||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "simulationtime.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "sn_utils.h"
|
#include "sn_utils.h"
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
10
Model3d.h
10
Model3d.h
@@ -55,10 +55,10 @@ class TSubModel
|
|||||||
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||||
//m7todo: zrobić normalną serializację
|
//m7todo: zrobić normalną serializację
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
friend TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
||||||
friend class TDynamicObject; // temporary etc
|
friend TDynamicObject; // temporary etc
|
||||||
friend class scene::shape_node; // temporary etc
|
friend scene::shape_node; // temporary etc
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum normalization {
|
enum normalization {
|
||||||
@@ -218,7 +218,7 @@ public:
|
|||||||
|
|
||||||
class TModel3d
|
class TModel3d
|
||||||
{
|
{
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSubModel *Root; // drzewo submodeli
|
TSubModel *Root; // drzewo submodeli
|
||||||
|
|||||||
4
Track.h
4
Track.h
@@ -126,9 +126,9 @@ private:
|
|||||||
// trajektoria ruchu - opakowanie
|
// trajektoria ruchu - opakowanie
|
||||||
class TTrack : public scene::basic_node {
|
class TTrack : public scene::basic_node {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
// NOTE: temporary arrangement
|
// NOTE: temporary arrangement
|
||||||
friend class ui_layer;
|
friend ui_layer;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class TTractionPowerSource;
|
|||||||
|
|
||||||
class TTraction : public scene::basic_node {
|
class TTraction : public scene::basic_node {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public: // na razie
|
public: // na razie
|
||||||
TTractionPowerSource *psPower[ 2 ] { nullptr, nullptr }; // najbliższe zasilacze z obu kierunków
|
TTractionPowerSource *psPower[ 2 ] { nullptr, nullptr }; // najbliższe zasilacze z obu kierunków
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
#include "world.h"
|
#include "simulationtime.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "MdlMngr.h"
|
#include "MdlMngr.h"
|
||||||
|
|||||||
206
World.cpp
206
World.cpp
@@ -16,7 +16,9 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
#include "application.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
|
#include "simulationtime.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "MdlMngr.h"
|
#include "MdlMngr.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
@@ -33,188 +35,13 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace simulation {
|
TWorld World;
|
||||||
|
|
||||||
simulation_time Time;
|
|
||||||
|
|
||||||
basic_station Station;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window ); //m7todo: potrzebne do directsound
|
GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window ); //m7todo: potrzebne do directsound
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
simulation_time::init() {
|
|
||||||
|
|
||||||
char monthdaycounts[ 2 ][ 13 ] = {
|
|
||||||
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
|
||||||
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
|
|
||||||
::memcpy( m_monthdaycounts, monthdaycounts, sizeof( monthdaycounts ) );
|
|
||||||
|
|
||||||
// potentially adjust scenario clock
|
|
||||||
auto const requestedtime { clamp_circular<int>( m_time.wHour * 60 + m_time.wMinute + Global.ScenarioTimeOffset * 60, 24 * 60 ) };
|
|
||||||
auto const requestedhour { ( requestedtime / 60 ) % 24 };
|
|
||||||
auto const requestedminute { requestedtime % 60 };
|
|
||||||
// cache requested elements, if any
|
|
||||||
::GetLocalTime( &m_time );
|
|
||||||
|
|
||||||
if( Global.fMoveLight > 0.0 ) {
|
|
||||||
// day and month of the year can be overriden by scenario setup
|
|
||||||
daymonth( m_time.wDay, m_time.wMonth, m_time.wYear, static_cast<WORD>( Global.fMoveLight ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( requestedhour != -1 ) { m_time.wHour = static_cast<WORD>( clamp( requestedhour, 0, 23 ) ); }
|
|
||||||
if( requestedminute != -1 ) { m_time.wMinute = static_cast<WORD>( clamp( requestedminute, 0, 59 ) ); }
|
|
||||||
// if the time is taken from the local clock leave the seconds intact, otherwise set them to zero
|
|
||||||
if( ( requestedhour != -1 )
|
|
||||||
|| ( requestedminute != 1 ) ) {
|
|
||||||
m_time.wSecond = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_yearday = year_day( m_time.wDay, m_time.wMonth, m_time.wYear );
|
|
||||||
|
|
||||||
// calculate time zone bias
|
|
||||||
// retrieve relevant time zone info from system registry (or fall back on supplied default)
|
|
||||||
// TODO: select timezone matching defined geographic location and/or country
|
|
||||||
struct registry_time_zone_info {
|
|
||||||
long Bias;
|
|
||||||
long StandardBias;
|
|
||||||
long DaylightBias;
|
|
||||||
SYSTEMTIME StandardDate;
|
|
||||||
SYSTEMTIME DaylightDate;
|
|
||||||
} registrytimezoneinfo = { -60, 0, -60, { 0, 10, 0, 5, 3, 0, 0, 0 }, { 0, 3, 0, 5, 2, 0, 0, 0 } };
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
TCHAR timezonekeyname[] { TEXT( "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\Central European Standard Time" ) };
|
|
||||||
HKEY timezonekey { NULL };
|
|
||||||
DWORD size { sizeof( registrytimezoneinfo ) };
|
|
||||||
if( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, timezonekeyname, 0, KEY_QUERY_VALUE, &timezonekey ) == ERROR_SUCCESS ) {
|
|
||||||
::RegQueryValueEx( timezonekey, "TZI", NULL, NULL, (BYTE *)®istrytimezoneinfo, &size );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
TIME_ZONE_INFORMATION timezoneinfo { 0 };
|
|
||||||
timezoneinfo.Bias = registrytimezoneinfo.Bias;
|
|
||||||
timezoneinfo.DaylightBias = registrytimezoneinfo.DaylightBias;
|
|
||||||
timezoneinfo.DaylightDate = registrytimezoneinfo.DaylightDate;
|
|
||||||
timezoneinfo.StandardBias = registrytimezoneinfo.StandardBias;
|
|
||||||
timezoneinfo.StandardDate = registrytimezoneinfo.StandardDate;
|
|
||||||
|
|
||||||
auto zonebias { timezoneinfo.Bias };
|
|
||||||
if( m_yearday < year_day( timezoneinfo.DaylightDate.wDay, timezoneinfo.DaylightDate.wMonth, m_time.wYear ) ) {
|
|
||||||
zonebias += timezoneinfo.StandardBias;
|
|
||||||
}
|
|
||||||
else if( m_yearday < year_day( timezoneinfo.StandardDate.wDay, timezoneinfo.StandardDate.wMonth, m_time.wYear ) ) {
|
|
||||||
zonebias += timezoneinfo.DaylightBias;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
zonebias += timezoneinfo.StandardBias;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_timezonebias = ( zonebias / 60.0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
simulation_time::update( double const Deltatime ) {
|
|
||||||
|
|
||||||
m_milliseconds += ( 1000.0 * Deltatime );
|
|
||||||
while( m_milliseconds >= 1000.0 ) {
|
|
||||||
|
|
||||||
++m_time.wSecond;
|
|
||||||
m_milliseconds -= 1000.0;
|
|
||||||
}
|
|
||||||
m_time.wMilliseconds = std::floor( m_milliseconds );
|
|
||||||
while( m_time.wSecond >= 60 ) {
|
|
||||||
|
|
||||||
++m_time.wMinute;
|
|
||||||
m_time.wSecond -= 60;
|
|
||||||
}
|
|
||||||
while( m_time.wMinute >= 60 ) {
|
|
||||||
|
|
||||||
++m_time.wHour;
|
|
||||||
m_time.wMinute -= 60;
|
|
||||||
}
|
|
||||||
while( m_time.wHour >= 24 ) {
|
|
||||||
|
|
||||||
++m_time.wDay;
|
|
||||||
++m_time.wDayOfWeek;
|
|
||||||
if( m_time.wDayOfWeek >= 7 ) {
|
|
||||||
m_time.wDayOfWeek -= 7;
|
|
||||||
}
|
|
||||||
m_time.wHour -= 24;
|
|
||||||
}
|
|
||||||
int leap = ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 );
|
|
||||||
while( m_time.wDay > m_monthdaycounts[ leap ][ m_time.wMonth ] ) {
|
|
||||||
|
|
||||||
m_time.wDay -= m_monthdaycounts[ leap ][ m_time.wMonth ];
|
|
||||||
++m_time.wMonth;
|
|
||||||
// unlikely but we might've entered a new year
|
|
||||||
if( m_time.wMonth > 12 ) {
|
|
||||||
|
|
||||||
++m_time.wYear;
|
|
||||||
leap = ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 );
|
|
||||||
m_time.wMonth -= 12;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
simulation_time::year_day( int Day, const int Month, const int Year ) const {
|
|
||||||
|
|
||||||
char const daytab[ 2 ][ 13 ] = {
|
|
||||||
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
|
||||||
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) };
|
|
||||||
for( int i = 1; i < Month; ++i )
|
|
||||||
Day += daytab[ leap ][ i ];
|
|
||||||
|
|
||||||
return Day;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
simulation_time::daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yearday ) {
|
|
||||||
|
|
||||||
WORD daytab[ 2 ][ 13 ] = {
|
|
||||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
|
|
||||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
|
||||||
};
|
|
||||||
|
|
||||||
int leap = ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 );
|
|
||||||
WORD idx = 1;
|
|
||||||
while( ( idx < 13 ) && ( Yearday >= daytab[ leap ][ idx ] ) ) {
|
|
||||||
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
Month = idx;
|
|
||||||
Day = Yearday - daytab[ leap ][ idx - 1 ];
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
simulation_time::julian_day() const {
|
|
||||||
|
|
||||||
int yy = ( m_time.wYear < 0 ? m_time.wYear + 1 : m_time.wYear ) - std::floor( ( 12 - m_time.wMonth ) / 10.f );
|
|
||||||
int mm = m_time.wMonth + 9;
|
|
||||||
if( mm >= 12 ) { mm -= 12; }
|
|
||||||
|
|
||||||
int K1 = std::floor( 365.25 * ( yy + 4712 ) );
|
|
||||||
int K2 = std::floor( 30.6 * mm + 0.5 );
|
|
||||||
|
|
||||||
// for dates in Julian calendar
|
|
||||||
int JD = K1 + K2 + m_time.wDay + 59;
|
|
||||||
// for dates in Gregorian calendar; 2299160 is October 15th, 1582
|
|
||||||
const int gregorianswitchday = 2299160;
|
|
||||||
if( JD > gregorianswitchday ) {
|
|
||||||
|
|
||||||
int K3 = std::floor( std::floor( ( yy * 0.01 ) + 49 ) * 0.75 ) - 38;
|
|
||||||
JD -= K3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JD;
|
|
||||||
}
|
|
||||||
|
|
||||||
TWorld::TWorld()
|
TWorld::TWorld()
|
||||||
{
|
{
|
||||||
Train = NULL;
|
Train = NULL;
|
||||||
@@ -254,7 +81,6 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
|||||||
auto timestart = std::chrono::system_clock::now();
|
auto timestart = std::chrono::system_clock::now();
|
||||||
|
|
||||||
window = Window;
|
window = Window;
|
||||||
Global.window = Window; // do WM_COPYDATA
|
|
||||||
Global.pCamera = &Camera; // Ra: wskaźnik potrzebny do likwidacji drgań
|
Global.pCamera = &Camera; // Ra: wskaźnik potrzebny do likwidacji drgań
|
||||||
|
|
||||||
WriteLog( "\nStarting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" );
|
WriteLog( "\nStarting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" );
|
||||||
@@ -935,7 +761,6 @@ bool TWorld::Update() {
|
|||||||
audio::renderer.update( dt );
|
audio::renderer.update( dt );
|
||||||
|
|
||||||
GfxRenderer.Update( dt );
|
GfxRenderer.Update( dt );
|
||||||
ResourceSweep();
|
|
||||||
|
|
||||||
m_init = true;
|
m_init = true;
|
||||||
|
|
||||||
@@ -1007,12 +832,12 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
// double modelrotate = atan2( -tempangle.x, tempangle.z );
|
// double modelrotate = atan2( -tempangle.x, tempangle.z );
|
||||||
|
|
||||||
if( ( true == Global.ctrlState )
|
if( ( true == Global.ctrlState )
|
||||||
&& ( ( glfwGetKey( Global.window, GLFW_KEY_LEFT ) == GLFW_TRUE )
|
&& ( ( glfwGetKey( Application.window(), GLFW_KEY_LEFT ) == GLFW_TRUE )
|
||||||
|| ( glfwGetKey( Global.window, GLFW_KEY_RIGHT ) == GLFW_TRUE ) ) ) {
|
|| ( glfwGetKey( Application.window(), GLFW_KEY_RIGHT ) == GLFW_TRUE ) ) ) {
|
||||||
// jeśli lusterko lewe albo prawe (bez rzucania na razie)
|
// jeśli lusterko lewe albo prawe (bez rzucania na razie)
|
||||||
Global.CabWindowOpen = true;
|
Global.CabWindowOpen = true;
|
||||||
|
|
||||||
auto const lr { glfwGetKey( Global.window, GLFW_KEY_LEFT ) == GLFW_TRUE };
|
auto const lr { glfwGetKey( Application.window(), GLFW_KEY_LEFT ) == GLFW_TRUE };
|
||||||
// Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu
|
// Camera.Yaw powinno być wyzerowane, aby po powrocie patrzeć do przodu
|
||||||
Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka
|
Camera.Pos = Controlled->GetPosition() + Train->MirrorPosition( lr ); // pozycja lusterka
|
||||||
Camera.Yaw = 0; // odchylenie na bok od Camera.LookAt
|
Camera.Yaw = 0; // odchylenie na bok od Camera.LookAt
|
||||||
@@ -1079,13 +904,6 @@ void TWorld::Update_Environment() {
|
|||||||
Environment.update();
|
Environment.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TWorld::ResourceSweep()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
ResourceManager::Sweep( Timer::GetSimulationTime() );
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void TWorld::OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
void TWorld::OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||||
{ // odebranie komunikatu z serwera
|
{ // odebranie komunikatu z serwera
|
||||||
@@ -1445,11 +1263,11 @@ TWorld::compute_season( int const Yearday ) const {
|
|||||||
using dayseasonpair = std::pair<int, std::string>;
|
using dayseasonpair = std::pair<int, std::string>;
|
||||||
|
|
||||||
std::vector<dayseasonpair> seasonsequence {
|
std::vector<dayseasonpair> seasonsequence {
|
||||||
{ 65, "winter" },
|
{ 65, "winter:" },
|
||||||
{ 158, "spring" },
|
{ 158, "spring:" },
|
||||||
{ 252, "summer" },
|
{ 252, "summer:" },
|
||||||
{ 341, "autumn" },
|
{ 341, "autumn:" },
|
||||||
{ 366, "winter" } };
|
{ 366, "winter:" } };
|
||||||
auto const lookup =
|
auto const lookup =
|
||||||
std::lower_bound(
|
std::lower_bound(
|
||||||
std::begin( seasonsequence ), std::end( seasonsequence ),
|
std::begin( seasonsequence ), std::end( seasonsequence ),
|
||||||
@@ -1457,7 +1275,7 @@ TWorld::compute_season( int const Yearday ) const {
|
|||||||
[]( dayseasonpair const &Left, const int Right ) {
|
[]( dayseasonpair const &Left, const int Right ) {
|
||||||
return Left.first < Right; } );
|
return Left.first < Right; } );
|
||||||
|
|
||||||
Global.Season = lookup->second + ":";
|
Global.Season = lookup->second;
|
||||||
// season can affect the weather so if it changes, re-calculate weather as well
|
// season can affect the weather so if it changes, re-calculate weather as well
|
||||||
compute_weather();
|
compute_weather();
|
||||||
}
|
}
|
||||||
|
|||||||
49
World.h
49
World.h
@@ -20,52 +20,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "stars.h"
|
#include "stars.h"
|
||||||
#include "skydome.h"
|
#include "skydome.h"
|
||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
#include "station.h"
|
|
||||||
|
|
||||||
// wrapper for simulation time
|
|
||||||
class simulation_time {
|
|
||||||
|
|
||||||
public:
|
|
||||||
simulation_time() { m_time.wHour = 10; m_time.wMinute = 30; }
|
|
||||||
void
|
|
||||||
init();
|
|
||||||
void
|
|
||||||
update( double const Deltatime );
|
|
||||||
SYSTEMTIME &
|
|
||||||
data() { return m_time; }
|
|
||||||
SYSTEMTIME const &
|
|
||||||
data() const { return m_time; }
|
|
||||||
double
|
|
||||||
second() const { return ( m_time.wMilliseconds * 0.001 + m_time.wSecond ); }
|
|
||||||
int
|
|
||||||
year_day() const { return m_yearday; }
|
|
||||||
// helper, calculates day of year from given date
|
|
||||||
int
|
|
||||||
year_day( int Day, int const Month, int const Year ) const;
|
|
||||||
int
|
|
||||||
julian_day() const;
|
|
||||||
double
|
|
||||||
zone_bias() const { return m_timezonebias; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// calculates day and month from given day of year
|
|
||||||
void
|
|
||||||
daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yearday );
|
|
||||||
|
|
||||||
SYSTEMTIME m_time;
|
|
||||||
double m_milliseconds{ 0.0 };
|
|
||||||
int m_yearday;
|
|
||||||
char m_monthdaycounts[ 2 ][ 13 ];
|
|
||||||
double m_timezonebias{ 0.0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace simulation {
|
|
||||||
|
|
||||||
extern simulation_time Time;
|
|
||||||
|
|
||||||
extern basic_station Station; // temporary object, for station functionality tests
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrapper for environment elements -- sky, sun, stars, clouds etc
|
// wrapper for environment elements -- sky, sun, stars, clouds etc
|
||||||
class world_environment {
|
class world_environment {
|
||||||
@@ -126,7 +80,6 @@ TWorld();
|
|||||||
private:
|
private:
|
||||||
void Update_Environment();
|
void Update_Environment();
|
||||||
void Update_Camera( const double Deltatime );
|
void Update_Camera( const double Deltatime );
|
||||||
void ResourceSweep();
|
|
||||||
// handles vehicle change flag
|
// handles vehicle change flag
|
||||||
void ChangeDynamic();
|
void ChangeDynamic();
|
||||||
void InOutKey( bool const Near = true );
|
void InOutKey( bool const Near = true );
|
||||||
@@ -154,5 +107,7 @@ private:
|
|||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern TWorld World;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
514
application.cpp
Normal file
514
application.cpp
Normal file
@@ -0,0 +1,514 @@
|
|||||||
|
/*
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "application.h"
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include "keyboardinput.h"
|
||||||
|
#include "mouseinput.h"
|
||||||
|
#include "gamepadinput.h"
|
||||||
|
#include "console.h"
|
||||||
|
#include "simulation.h"
|
||||||
|
#include "world.h"
|
||||||
|
#include "pyint.h"
|
||||||
|
#include "sceneeditor.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "uilayer.h"
|
||||||
|
#include "logs.h"
|
||||||
|
|
||||||
|
#ifdef EU07_BUILD_STATIC
|
||||||
|
#pragma comment( lib, "glfw3.lib" )
|
||||||
|
#pragma comment( lib, "glew32s.lib" )
|
||||||
|
#else
|
||||||
|
#ifdef _WIN32
|
||||||
|
#pragma comment( lib, "glfw3dll.lib" )
|
||||||
|
#else
|
||||||
|
#pragma comment( lib, "glfw3.lib" )
|
||||||
|
#endif
|
||||||
|
#pragma comment( lib, "glew32.lib" )
|
||||||
|
#endif // build_static
|
||||||
|
#pragma comment( lib, "opengl32.lib" )
|
||||||
|
#pragma comment( lib, "glu32.lib" )
|
||||||
|
#pragma comment( lib, "openal32.lib")
|
||||||
|
#pragma comment( lib, "setupapi.lib" )
|
||||||
|
#pragma comment( lib, "python27.lib" )
|
||||||
|
#pragma comment( lib, "libserialport-0.lib" )
|
||||||
|
#pragma comment (lib, "dbghelp.lib")
|
||||||
|
#pragma comment (lib, "version.lib")
|
||||||
|
|
||||||
|
eu07_application Application;
|
||||||
|
|
||||||
|
namespace input {
|
||||||
|
|
||||||
|
gamepad_input Gamepad;
|
||||||
|
mouse_input Mouse;
|
||||||
|
glm::dvec2 mouse_pickmodepos; // stores last mouse position in control picking mode
|
||||||
|
keyboard_input Keyboard;
|
||||||
|
Console console;
|
||||||
|
std::unique_ptr<uart_input> uart;
|
||||||
|
user_command command; // currently issued control command, if any
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
GLFWAPI HWND glfwGetWin32Window( GLFWwindow* window );
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG CALLBACK unhandled_handler( ::EXCEPTION_POINTERS* e );
|
||||||
|
LRESULT APIENTRY WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
|
||||||
|
extern HWND Hwnd;
|
||||||
|
extern WNDPROC BaseWindowProc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// user input callbacks
|
||||||
|
|
||||||
|
void window_resize_callback( GLFWwindow *window, int w, int h ) {
|
||||||
|
// NOTE: we have two variables which basically do the same thing as we don't have dynamic fullscreen toggle
|
||||||
|
// TBD, TODO: merge them?
|
||||||
|
Global.iWindowWidth = w;
|
||||||
|
Global.iWindowHeight = h;
|
||||||
|
Global.fDistanceFactor = std::max( 0.5f, h / 768.0f ); // not sure if this is really something we want to use
|
||||||
|
glViewport( 0, 0, w, h );
|
||||||
|
}
|
||||||
|
|
||||||
|
void cursor_pos_callback( GLFWwindow *window, double x, double y ) {
|
||||||
|
if( false == Global.ControlPicking ) {
|
||||||
|
glfwSetCursorPos( window, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// give the potential event recipient a shot at it, in the virtual z order
|
||||||
|
if( true == scene::Editor.on_mouse_move( x, y ) ) { return; }
|
||||||
|
input::Mouse.move( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_button_callback( GLFWwindow* window, int button, int action, int mods ) {
|
||||||
|
|
||||||
|
if( ( button != GLFW_MOUSE_BUTTON_LEFT )
|
||||||
|
&& ( button != GLFW_MOUSE_BUTTON_RIGHT ) ) {
|
||||||
|
// we don't care about other mouse buttons at the moment
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// give the potential event recipient a shot at it, in the virtual z order
|
||||||
|
if( true == scene::Editor.on_mouse_button( button, action ) ) { return; }
|
||||||
|
input::Mouse.button( button, action );
|
||||||
|
}
|
||||||
|
|
||||||
|
void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods ) {
|
||||||
|
|
||||||
|
Global.shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false;
|
||||||
|
Global.ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false;
|
||||||
|
Global.altState = ( mods & GLFW_MOD_ALT ) ? true : false;
|
||||||
|
|
||||||
|
// give the ui first shot at the input processing...
|
||||||
|
if( true == UILayer.on_key( key, action ) ) { return; }
|
||||||
|
if( true == scene::Editor.on_key( key, action ) ) { return; }
|
||||||
|
// ...if the input is left untouched, pass it on
|
||||||
|
input::Keyboard.key( key, action );
|
||||||
|
|
||||||
|
if( ( true == Global.InputMouse )
|
||||||
|
&& ( ( key == GLFW_KEY_LEFT_ALT )
|
||||||
|
|| ( key == GLFW_KEY_RIGHT_ALT ) ) ) {
|
||||||
|
// if the alt key was pressed toggle control picking mode and set matching cursor behaviour
|
||||||
|
if( action == GLFW_RELEASE ) {
|
||||||
|
|
||||||
|
if( Global.ControlPicking ) {
|
||||||
|
// switch off
|
||||||
|
Application.get_cursor_pos( input::mouse_pickmodepos.x, input::mouse_pickmodepos.y );
|
||||||
|
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||||
|
Application.set_cursor_pos( 0, 0 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// enter picking mode
|
||||||
|
Application.set_cursor_pos( input::mouse_pickmodepos.x, input::mouse_pickmodepos.y );
|
||||||
|
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||||
|
}
|
||||||
|
// actually toggle the mode
|
||||||
|
Global.ControlPicking = !Global.ControlPicking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( key == GLFW_KEY_LEFT_SHIFT )
|
||||||
|
|| ( key == GLFW_KEY_LEFT_CONTROL )
|
||||||
|
|| ( key == GLFW_KEY_LEFT_ALT )
|
||||||
|
|| ( key == GLFW_KEY_RIGHT_SHIFT )
|
||||||
|
|| ( key == GLFW_KEY_RIGHT_CONTROL )
|
||||||
|
|| ( key == GLFW_KEY_RIGHT_ALT ) ) {
|
||||||
|
// don't bother passing these
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( action == GLFW_PRESS || action == GLFW_REPEAT ) {
|
||||||
|
|
||||||
|
World.OnKeyDown( key );
|
||||||
|
|
||||||
|
#ifdef CAN_I_HAS_LIBPNG
|
||||||
|
switch( key ) {
|
||||||
|
case GLFW_KEY_PRINT_SCREEN: {
|
||||||
|
make_screenshot();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { break; }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void focus_callback( GLFWwindow *window, int focus ) {
|
||||||
|
if( Global.bInactivePause ) // jeśli ma być pauzowanie okna w tle
|
||||||
|
if( focus )
|
||||||
|
Global.iPause &= ~4; // odpauzowanie, gdy jest na pierwszym planie
|
||||||
|
else
|
||||||
|
Global.iPause |= 4; // włączenie pauzy, gdy nieaktywy
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll_callback( GLFWwindow* window, double xoffset, double yoffset ) {
|
||||||
|
|
||||||
|
if( Global.ctrlState ) {
|
||||||
|
// ctrl + scroll wheel adjusts fov in debug mode
|
||||||
|
Global.FieldOfView = clamp( static_cast<float>( Global.FieldOfView - yoffset * 20.0 / Global.fFpsAverage ), 15.0f, 75.0f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public:
|
||||||
|
|
||||||
|
int
|
||||||
|
eu07_application::init( int Argc, char *Argv[] ) {
|
||||||
|
|
||||||
|
int result { 0 };
|
||||||
|
|
||||||
|
init_debug();
|
||||||
|
init_files();
|
||||||
|
if( ( result = init_settings( Argc, Argv ) ) != 0 ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if( ( result = init_glfw() ) != 0 ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
init_callbacks();
|
||||||
|
if( ( result = init_gfx() ) != 0 ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if( ( result = init_audio() ) != 0 ) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
eu07_application::run() {
|
||||||
|
|
||||||
|
// TODO: move input sources and their initializations to the application mode member
|
||||||
|
input::Keyboard.init();
|
||||||
|
input::Mouse.init();
|
||||||
|
input::Gamepad.init();
|
||||||
|
if( true == Global.uart_conf.enable ) {
|
||||||
|
input::uart = std::make_unique<uart_input>();
|
||||||
|
input::uart->init();
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
Console::On(); // włączenie konsoli
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Global.pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
|
||||||
|
|
||||||
|
if( false == World.Init( m_window ) ) {
|
||||||
|
ErrorLog( "Bad init: simulation setup failed" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Global.iConvertModels < 0 ) {
|
||||||
|
// generate binary files for all 3d models
|
||||||
|
Global.iConvertModels = -Global.iConvertModels;
|
||||||
|
World.CreateE3D( szModelPath ); // rekurencyjne przeglądanie katalogów
|
||||||
|
World.CreateE3D( szDynamicPath, true );
|
||||||
|
// auto-close when you're done
|
||||||
|
WriteLog( "Binary 3d model generation completed" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_cursor( GLFW_CURSOR_DISABLED );
|
||||||
|
set_cursor_pos( 0, 0 );
|
||||||
|
|
||||||
|
// main application loop
|
||||||
|
// TODO: split into parts and delegate these to application mode member
|
||||||
|
while( ( false == glfwWindowShouldClose( m_window ) )
|
||||||
|
&& ( true == World.Update() )
|
||||||
|
&& ( true == GfxRenderer.Render() ) ) {
|
||||||
|
glfwPollEvents();
|
||||||
|
input::Keyboard.poll();
|
||||||
|
if( true == Global.InputMouse ) { input::Mouse.poll(); }
|
||||||
|
if( true == Global.InputGamepad ) { input::Gamepad.poll(); }
|
||||||
|
if( input::uart != nullptr ) { input::uart->poll(); }
|
||||||
|
// TODO: wrap current command in object, include other input sources
|
||||||
|
input::command = (
|
||||||
|
input::Mouse.command() != user_command::none ?
|
||||||
|
input::Mouse.command() :
|
||||||
|
input::Keyboard.command() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::exit() {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
|
||||||
|
#endif
|
||||||
|
SafeDelete( simulation::Region );
|
||||||
|
|
||||||
|
glfwDestroyWindow( m_window );
|
||||||
|
glfwTerminate();
|
||||||
|
|
||||||
|
TPythonInterpreter::killInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::set_cursor( int const Mode ) {
|
||||||
|
|
||||||
|
UILayer.set_cursor( Mode );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::set_cursor_pos( double const X, double const Y ) {
|
||||||
|
|
||||||
|
if( m_window != nullptr ) {
|
||||||
|
glfwSetCursorPos( m_window, X, Y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::get_cursor_pos( double &X, double &Y ) const {
|
||||||
|
|
||||||
|
if( m_window != nullptr ) {
|
||||||
|
glfwGetCursorPos( m_window, &X, &Y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// private:
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::init_debug() {
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined (_DEBUG)
|
||||||
|
// memory leaks
|
||||||
|
_CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_LEAK_CHECK_DF );
|
||||||
|
// floating point operation errors
|
||||||
|
auto state { _clearfp() };
|
||||||
|
state = _control87( 0, 0 );
|
||||||
|
// this will turn on FPE for #IND and zerodiv
|
||||||
|
state = _control87( state & ~( _EM_ZERODIVIDE | _EM_INVALID ), _MCW_EM );
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
::SetUnhandledExceptionFilter( unhandled_handler );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::init_files() {
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
DeleteFile( "log.txt" );
|
||||||
|
DeleteFile( "errors.txt" );
|
||||||
|
_mkdir( "logs" );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
eu07_application::init_settings( int Argc, char *Argv[] ) {
|
||||||
|
|
||||||
|
Global.LoadIniFile( "eu07.ini" );
|
||||||
|
if( ( Global.iWriteLogEnabled & 2 ) != 0 ) {
|
||||||
|
// show output console if requested
|
||||||
|
AllocConsole();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
std::string executable( argv[ 0 ] ); auto const pathend = executable.rfind( '\\' );
|
||||||
|
Global.ExecutableName =
|
||||||
|
( pathend != std::string::npos ?
|
||||||
|
executable.substr( executable.rfind( '\\' ) + 1 ) :
|
||||||
|
executable );
|
||||||
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
// retrieve product version from the file's version data table
|
||||||
|
{
|
||||||
|
auto const fileversionsize { ::GetFileVersionInfoSize( Argv[ 0 ], NULL ) };
|
||||||
|
std::vector<BYTE>fileversiondata; fileversiondata.resize( fileversionsize );
|
||||||
|
if( ::GetFileVersionInfo( Argv[ 0 ], 0, fileversionsize, fileversiondata.data() ) ) {
|
||||||
|
|
||||||
|
struct lang_codepage {
|
||||||
|
WORD language;
|
||||||
|
WORD codepage;
|
||||||
|
} *langcodepage;
|
||||||
|
UINT datasize;
|
||||||
|
|
||||||
|
::VerQueryValue(
|
||||||
|
fileversiondata.data(),
|
||||||
|
TEXT( "\\VarFileInfo\\Translation" ),
|
||||||
|
(LPVOID*)&langcodepage,
|
||||||
|
&datasize );
|
||||||
|
|
||||||
|
std::string subblock; subblock.resize( 50 );
|
||||||
|
::StringCchPrintf(
|
||||||
|
&subblock[0], subblock.size(),
|
||||||
|
TEXT( "\\StringFileInfo\\%04x%04x\\ProductVersion" ),
|
||||||
|
langcodepage->language,
|
||||||
|
langcodepage->codepage );
|
||||||
|
|
||||||
|
VOID *stringdata;
|
||||||
|
if( ::VerQueryValue(
|
||||||
|
fileversiondata.data(),
|
||||||
|
subblock.data(),
|
||||||
|
&stringdata,
|
||||||
|
&datasize ) ) {
|
||||||
|
|
||||||
|
Global.asVersion = std::string( reinterpret_cast<char*>(stringdata) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// process command line arguments
|
||||||
|
for( int i = 1; i < Argc; ++i ) {
|
||||||
|
|
||||||
|
std::string token { Argv[ i ] };
|
||||||
|
|
||||||
|
if( token == "-e3d" ) {
|
||||||
|
Global.iConvertModels = (
|
||||||
|
Global.iConvertModels > 0 ?
|
||||||
|
-Global.iConvertModels :
|
||||||
|
-7 ); // z optymalizacją, bananami i prawidłowym Opacity
|
||||||
|
}
|
||||||
|
else if( token == "-s" ) {
|
||||||
|
if( i + 1 < Argc ) {
|
||||||
|
Global.SceneryFile = Argv[ ++i ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( token == "-v" ) {
|
||||||
|
if( i + 1 < Argc ) {
|
||||||
|
Global.asHumanCtrlVehicle = Argv[ ++i ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout
|
||||||
|
<< "usage: " << std::string( Argv[ 0 ] )
|
||||||
|
<< " [-s sceneryfilepath]"
|
||||||
|
<< " [-v vehiclename]"
|
||||||
|
<< " [-e3d]"
|
||||||
|
<< std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
eu07_application::init_glfw() {
|
||||||
|
|
||||||
|
if( glfwInit() == GLFW_FALSE ) {
|
||||||
|
ErrorLog( "Bad init: failed to initialize glfw" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// match requested video mode to current to allow for
|
||||||
|
// fullwindow creation when resolution is the same
|
||||||
|
auto *monitor { glfwGetPrimaryMonitor() };
|
||||||
|
auto const *vmode { glfwGetVideoMode( monitor ) };
|
||||||
|
|
||||||
|
glfwWindowHint( GLFW_RED_BITS, vmode->redBits );
|
||||||
|
glfwWindowHint( GLFW_GREEN_BITS, vmode->greenBits );
|
||||||
|
glfwWindowHint( GLFW_BLUE_BITS, vmode->blueBits );
|
||||||
|
glfwWindowHint( GLFW_REFRESH_RATE, vmode->refreshRate );
|
||||||
|
|
||||||
|
glfwWindowHint( GLFW_AUTO_ICONIFY, GLFW_FALSE );
|
||||||
|
if( Global.iMultisampling > 0 ) {
|
||||||
|
glfwWindowHint( GLFW_SAMPLES, 1 << Global.iMultisampling );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Global.bFullScreen ) {
|
||||||
|
// match screen dimensions with selected monitor, for 'borderless window' in fullscreen mode
|
||||||
|
Global.iWindowWidth = vmode->width;
|
||||||
|
Global.iWindowHeight = vmode->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *window {
|
||||||
|
glfwCreateWindow(
|
||||||
|
Global.iWindowWidth,
|
||||||
|
Global.iWindowHeight,
|
||||||
|
Global.AppName.c_str(),
|
||||||
|
( Global.bFullScreen ?
|
||||||
|
monitor :
|
||||||
|
nullptr ),
|
||||||
|
nullptr ) };
|
||||||
|
|
||||||
|
if( window == nullptr ) {
|
||||||
|
ErrorLog( "Bad init: failed to create glfw window" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent( window );
|
||||||
|
glfwSwapInterval( Global.VSync ? 1 : 0 ); //vsync
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// setup wrapper for base glfw window proc, to handle copydata messages
|
||||||
|
Hwnd = glfwGetWin32Window( window );
|
||||||
|
BaseWindowProc = ( WNDPROC )::SetWindowLongPtr( Hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc );
|
||||||
|
// switch off the topmost flag
|
||||||
|
::SetWindowPos( Hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
|
||||||
|
#endif
|
||||||
|
// TBD, TODO: move the global pointer to a more appropriate place
|
||||||
|
m_window = window;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eu07_application::init_callbacks() {
|
||||||
|
|
||||||
|
glfwSetFramebufferSizeCallback( m_window, window_resize_callback );
|
||||||
|
glfwSetCursorPosCallback( m_window, cursor_pos_callback );
|
||||||
|
glfwSetMouseButtonCallback( m_window, mouse_button_callback );
|
||||||
|
glfwSetKeyCallback( m_window, key_callback );
|
||||||
|
glfwSetScrollCallback( m_window, scroll_callback );
|
||||||
|
glfwSetWindowFocusCallback( m_window, focus_callback );
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
glfwGetFramebufferSize( m_window, &width, &height );
|
||||||
|
window_resize_callback( m_window, width, height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
eu07_application::init_gfx() {
|
||||||
|
|
||||||
|
if( glewInit() != GLEW_OK ) {
|
||||||
|
ErrorLog( "Bad init: failed to initialize glew" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( false == GfxRenderer.Init( m_window ) )
|
||||||
|
|| ( false == UILayer.init( m_window ) ) ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
eu07_application::init_audio() {
|
||||||
|
|
||||||
|
if( Global.bSoundEnabled ) {
|
||||||
|
Global.bSoundEnabled &= audio::renderer.init();
|
||||||
|
}
|
||||||
|
// NOTE: lack of audio isn't deemed a failure serious enough to throw in the towel
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
46
application.h
Normal file
46
application.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class eu07_application {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// constructors
|
||||||
|
eu07_application() = default;
|
||||||
|
// methods
|
||||||
|
int
|
||||||
|
init( int Argc, char *Argv[] );
|
||||||
|
int
|
||||||
|
run();
|
||||||
|
void
|
||||||
|
exit();
|
||||||
|
void
|
||||||
|
set_cursor( int const Mode );
|
||||||
|
void
|
||||||
|
set_cursor_pos( double const X, double const Y );
|
||||||
|
void
|
||||||
|
get_cursor_pos( double &X, double &Y ) const;
|
||||||
|
inline
|
||||||
|
GLFWwindow *
|
||||||
|
window() {
|
||||||
|
return m_window; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
void init_debug();
|
||||||
|
void init_files();
|
||||||
|
int init_settings( int Argc, char *Argv[] );
|
||||||
|
int init_glfw();
|
||||||
|
void init_callbacks();
|
||||||
|
int init_gfx();
|
||||||
|
int init_audio();
|
||||||
|
// members
|
||||||
|
GLFWwindow * m_window { nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
extern eu07_application Application;
|
||||||
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "resourcemanager.h"
|
#include "resourcemanager.h"
|
||||||
#include "uitranscripts.h"
|
#include "uitranscripts.h"
|
||||||
|
|
||||||
|
class opengl_renderer;
|
||||||
class sound_source;
|
class sound_source;
|
||||||
|
|
||||||
using uint32_sequence = std::vector<std::uint32_t>;
|
using uint32_sequence = std::vector<std::uint32_t>;
|
||||||
@@ -100,7 +101,7 @@ private:
|
|||||||
|
|
||||||
class openal_renderer {
|
class openal_renderer {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "world.h"
|
|
||||||
|
|
||||||
extern TWorld World;
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
keyboard_input::recall_bindings() {
|
keyboard_input::recall_bindings() {
|
||||||
|
|||||||
@@ -51,9 +51,6 @@
|
|||||||
<ClCompile Include="DynObj.cpp">
|
<ClCompile Include="DynObj.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="EU07.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Event.cpp">
|
<ClCompile Include="Event.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -246,6 +243,15 @@
|
|||||||
<ClCompile Include="sceneeditor.cpp">
|
<ClCompile Include="sceneeditor.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="simulationtime.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="application.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="eu07.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Globals.h">
|
<ClInclude Include="Globals.h">
|
||||||
@@ -476,6 +482,12 @@
|
|||||||
<ClInclude Include="sceneeditor.h">
|
<ClInclude Include="sceneeditor.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="simulationtime.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="application.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="maszyna.rc">
|
<ResourceCompile Include="maszyna.rc">
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "messaging.h"
|
#include "messaging.h"
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "application.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
@@ -51,7 +52,7 @@ WyslijEvent(const std::string &e, const std::string &d)
|
|||||||
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
||||||
cData.cbData = (DWORD)(12 + i + j); // 8+dwa liczniki i dwa zera kończące
|
cData.cbData = (DWORD)(12 + i + j); // 8+dwa liczniki i dwa zera kończące
|
||||||
cData.lpData = &r;
|
cData.lpData = &r;
|
||||||
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global.window ), (LPARAM)&cData );
|
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Application.window() ), (LPARAM)&cData );
|
||||||
CommLog( Now() + " " + std::to_string(r.iComm) + " " + e + " sent" );
|
CommLog( Now() + " " + std::to_string(r.iComm) + " " + e + " sent" );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -71,7 +72,7 @@ WyslijUszkodzenia(const std::string &t, char fl)
|
|||||||
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
||||||
cData.cbData = (DWORD)(11 + i); // 8+licznik i zero kończące
|
cData.cbData = (DWORD)(11 + i); // 8+licznik i zero kończące
|
||||||
cData.lpData = &r;
|
cData.lpData = &r;
|
||||||
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global.window ), (LPARAM)&cData );
|
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Application.window() ), (LPARAM)&cData );
|
||||||
CommLog( Now() + " " + std::to_string(r.iComm) + " " + t + " sent");
|
CommLog( Now() + " " + std::to_string(r.iComm) + " " + t + " sent");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -90,7 +91,7 @@ WyslijString(const std::string &t, int n)
|
|||||||
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
||||||
cData.cbData = (DWORD)(10 + i); // 8+licznik i zero kończące
|
cData.cbData = (DWORD)(10 + i); // 8+licznik i zero kończące
|
||||||
cData.lpData = &r;
|
cData.lpData = &r;
|
||||||
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global.window ), (LPARAM)&cData );
|
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Application.window() ), (LPARAM)&cData );
|
||||||
CommLog( Now() + " " + std::to_string(r.iComm) + " " + t + " sent");
|
CommLog( Now() + " " + std::to_string(r.iComm) + " " + t + " sent");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -174,7 +175,7 @@ WyslijNamiary(TDynamicObject const *Vehicle)
|
|||||||
cData.cbData = (DWORD)(10 + i + j); // 8+licznik i zero kończące
|
cData.cbData = (DWORD)(10 + i + j); // 8+licznik i zero kończące
|
||||||
cData.lpData = &r;
|
cData.lpData = &r;
|
||||||
// WriteLog("Ramka gotowa");
|
// WriteLog("Ramka gotowa");
|
||||||
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global.window ), (LPARAM)&cData );
|
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Application.window() ), (LPARAM)&cData );
|
||||||
// WriteLog("Ramka poszla!");
|
// WriteLog("Ramka poszla!");
|
||||||
CommLog( Now() + " " + std::to_string(r.iComm) + " " + Vehicle->asName + " sent");
|
CommLog( Now() + " " + std::to_string(r.iComm) + " " + Vehicle->asName + " sent");
|
||||||
#endif
|
#endif
|
||||||
@@ -223,7 +224,7 @@ WyslijObsadzone()
|
|||||||
cData.cbData = 8 + 1984; // 8+licznik i zero kończące
|
cData.cbData = 8 + 1984; // 8+licznik i zero kończące
|
||||||
cData.lpData = &r;
|
cData.lpData = &r;
|
||||||
// WriteLog("Ramka gotowa");
|
// WriteLog("Ramka gotowa");
|
||||||
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global.window ), (LPARAM)&cData );
|
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Application.window() ), (LPARAM)&cData );
|
||||||
CommLog( Now() + " " + std::to_string(r.iComm) + " obsadzone" + " sent");
|
CommLog( Now() + " " + std::to_string(r.iComm) + " obsadzone" + " sent");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -249,7 +250,7 @@ WyslijParam(int nr, int fl)
|
|||||||
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
||||||
cData.cbData = 12 + i; // 12+rozmiar danych
|
cData.cbData = 12 + i; // 12+rozmiar danych
|
||||||
cData.lpData = &r;
|
cData.lpData = &r;
|
||||||
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global.window ), (LPARAM)&cData );
|
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Application.window() ), (LPARAM)&cData );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
moon.cpp
2
moon.cpp
@@ -4,7 +4,7 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "world.h"
|
#include "simulationtime.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun,
|
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun,
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "mouseinput.h"
|
#include "mouseinput.h"
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
@@ -18,8 +20,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "uilayer.h"
|
#include "uilayer.h"
|
||||||
|
|
||||||
extern TWorld World;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mouse_slider::bind( user_command const &Command ) {
|
mouse_slider::bind( user_command const &Command ) {
|
||||||
|
|
||||||
@@ -82,15 +82,14 @@ mouse_slider::bind( user_command const &Command ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// hide the cursor and place it in accordance with current slider value
|
// hide the cursor and place it in accordance with current slider value
|
||||||
glfwGetCursorPos( Global.window, &m_cursorposition.x, &m_cursorposition.y );
|
Application.get_cursor_pos( m_cursorposition.x, m_cursorposition.y );
|
||||||
UILayer.set_cursor( GLFW_CURSOR_DISABLED );
|
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||||
|
|
||||||
auto const controlsize { Global.iWindowHeight * 0.75 };
|
auto const controlsize { Global.iWindowHeight * 0.75 };
|
||||||
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
|
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
|
||||||
auto const stepsize { controlsize / m_valuerange };
|
auto const stepsize { controlsize / m_valuerange };
|
||||||
|
|
||||||
glfwSetCursorPos(
|
Application.set_cursor_pos(
|
||||||
Global.window,
|
|
||||||
Global.iWindowWidth * 0.5,
|
Global.iWindowWidth * 0.5,
|
||||||
( m_analogue ?
|
( m_analogue ?
|
||||||
controledge - ( 1.0 - m_value ) * controlsize :
|
controledge - ( 1.0 - m_value ) * controlsize :
|
||||||
@@ -101,8 +100,8 @@ void
|
|||||||
mouse_slider::release() {
|
mouse_slider::release() {
|
||||||
|
|
||||||
m_command = user_command::none;
|
m_command = user_command::none;
|
||||||
glfwSetCursorPos( Global.window, m_cursorposition.x, m_cursorposition.y );
|
Application.set_cursor_pos( m_cursorposition.x, m_cursorposition.y );
|
||||||
UILayer.set_cursor( GLFW_CURSOR_NORMAL );
|
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -525,10 +524,10 @@ mouse_input::default_bindings() {
|
|||||||
user_command::pantographtogglerear,
|
user_command::pantographtogglerear,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
{ "pantfrontoff_sw:", {
|
{ "pantfrontoff_sw:", {
|
||||||
user_command::pantographtogglefront,
|
user_command::pantographlowerfront,
|
||||||
user_command::none } }, // TODO: dedicated lower pantograph commands
|
user_command::none } }, // TODO: dedicated lower pantograph commands
|
||||||
{ "pantrearoff_sw:", {
|
{ "pantrearoff_sw:", {
|
||||||
user_command::pantographtogglerear,
|
user_command::pantographlowerrear,
|
||||||
user_command::none } }, // TODO: dedicated lower pantograph commands
|
user_command::none } }, // TODO: dedicated lower pantograph commands
|
||||||
{ "pantalloff_sw:", {
|
{ "pantalloff_sw:", {
|
||||||
user_command::pantographlowerall,
|
user_command::pantographlowerall,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "world.h"
|
#include "simulationtime.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
double TTrainParameters::CheckTrainLatency()
|
double TTrainParameters::CheckTrainLatency()
|
||||||
@@ -49,7 +49,7 @@ bool TTrainParameters::IsStop()
|
|||||||
return true; // na ostatnim się zatrzymać zawsze
|
return true; // na ostatnim się zatrzymać zawsze
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TTrainParameters::UpdateMTable( simulation_time const &Time, std::string const &NewName ) {
|
bool TTrainParameters::UpdateMTable( scenario_time const &Time, std::string const &NewName ) {
|
||||||
|
|
||||||
return UpdateMTable( Time.data().wHour, Time.data().wMinute, NewName );
|
return UpdateMTable( Time.data().wHour, Time.data().wMinute, NewName );
|
||||||
}
|
}
|
||||||
|
|||||||
2
mtable.h
2
mtable.h
@@ -75,7 +75,7 @@ class TTrainParameters
|
|||||||
bool IsStop();
|
bool IsStop();
|
||||||
bool IsTimeToGo(double hh, double mm);
|
bool IsTimeToGo(double hh, double mm);
|
||||||
bool UpdateMTable(double hh, double mm, std::string const &NewName);
|
bool UpdateMTable(double hh, double mm, std::string const &NewName);
|
||||||
bool UpdateMTable( simulation_time const &Time, std::string const &NewName );
|
bool UpdateMTable( scenario_time const &Time, std::string const &NewName );
|
||||||
bool RewindTimeTable( std::string actualStationName );
|
bool RewindTimeTable( std::string actualStationName );
|
||||||
TTrainParameters( std::string const &NewTrainName );
|
TTrainParameters( std::string const &NewTrainName );
|
||||||
void NewName(std::string const &NewTrainName);
|
void NewName(std::string const &NewTrainName);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
|
#include "simulationtime.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "dynobj.h"
|
#include "dynobj.h"
|
||||||
@@ -24,7 +25,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
opengl_renderer GfxRenderer;
|
opengl_renderer GfxRenderer;
|
||||||
extern TWorld World;
|
|
||||||
|
|
||||||
int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer
|
int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer
|
||||||
int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture
|
int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture
|
||||||
|
|||||||
6
scene.h
6
scene.h
@@ -60,7 +60,7 @@ struct scratch_data {
|
|||||||
// TBD, TODO: replace with quadtree scheme?
|
// TBD, TODO: replace with quadtree scheme?
|
||||||
class basic_cell {
|
class basic_cell {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
@@ -198,7 +198,7 @@ private:
|
|||||||
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
||||||
class basic_section {
|
class basic_section {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
@@ -302,7 +302,7 @@ private:
|
|||||||
// top-level of scene spatial structure, holds collection of sections
|
// top-level of scene spatial structure, holds collection of sections
|
||||||
class basic_region {
|
class basic_region {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "sceneeditor.h"
|
#include "sceneeditor.h"
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "application.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
#include "uilayer.h"
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
namespace scene {
|
namespace scene {
|
||||||
@@ -47,7 +47,7 @@ basic_editor::on_mouse_button( int const Button, int const Action ) {
|
|||||||
m_node = GfxRenderer.Update_Pick_Node();
|
m_node = GfxRenderer.Update_Pick_Node();
|
||||||
m_nodesnapshot = { m_node };
|
m_nodesnapshot = { m_node };
|
||||||
if( m_node ) {
|
if( m_node ) {
|
||||||
UILayer.set_cursor( GLFW_CURSOR_DISABLED );
|
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -55,7 +55,7 @@ basic_editor::on_mouse_button( int const Button, int const Action ) {
|
|||||||
// TODO: record the current undo step on the undo stack
|
// TODO: record the current undo step on the undo stack
|
||||||
m_nodesnapshot = { m_node };
|
m_nodesnapshot = { m_node };
|
||||||
if( m_node ) {
|
if( m_node ) {
|
||||||
UILayer.set_cursor( GLFW_CURSOR_NORMAL );
|
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
144
simulation.cpp
144
simulation.cpp
@@ -10,11 +10,11 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
|
|
||||||
#include "world.h"
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "logs.h"
|
#include "simulationtime.h"
|
||||||
#include "uilayer.h"
|
#include "uilayer.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "logs.h"
|
||||||
|
|
||||||
|
|
||||||
namespace simulation {
|
namespace simulation {
|
||||||
@@ -32,9 +32,42 @@ light_array Lights;
|
|||||||
|
|
||||||
scene::basic_region *Region { nullptr };
|
scene::basic_region *Region { nullptr };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
state_manager::deserialize( std::string const &Scenariofile ) {
|
state_manager::deserialize( std::string const &Scenariofile ) {
|
||||||
|
|
||||||
|
return m_serializer.deserialize( Scenariofile );
|
||||||
|
}
|
||||||
|
|
||||||
|
// stores class data in specified file, in legacy (text) format
|
||||||
|
void
|
||||||
|
state_manager::export_as_text( std::string const &Scenariofile ) const {
|
||||||
|
|
||||||
|
return m_serializer.export_as_text( Scenariofile );
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
state_manager::update( double const Deltatime, int Iterationcount ) {
|
||||||
|
// aktualizacja animacji krokiem FPS: dt=krok czasu [s], dt*iter=czas od ostatnich przeliczeń
|
||||||
|
if (Deltatime == 0.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const totaltime { Deltatime * Iterationcount };
|
||||||
|
// NOTE: we perform animations first, as they can determine factors like contact with powergrid
|
||||||
|
TAnimModel::AnimUpdate( totaltime ); // wykonanie zakolejkowanych animacji
|
||||||
|
|
||||||
|
simulation::Powergrid.update( totaltime );
|
||||||
|
simulation::Vehicles.update( Deltatime, Iterationcount );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
state_serializer::deserialize( std::string const &Scenariofile ) {
|
||||||
|
|
||||||
// TODO: move initialization to separate routine so we can reuse it
|
// TODO: move initialization to separate routine so we can reuse it
|
||||||
SafeDelete( Region );
|
SafeDelete( Region );
|
||||||
Region = new scene::basic_region();
|
Region = new scene::basic_region();
|
||||||
@@ -61,50 +94,33 @@ state_manager::deserialize( std::string const &Scenariofile ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy method, calculates changes in simulation state over specified time
|
|
||||||
void
|
|
||||||
state_manager::update( double const Deltatime, int Iterationcount ) {
|
|
||||||
// aktualizacja animacji krokiem FPS: dt=krok czasu [s], dt*iter=czas od ostatnich przeliczeń
|
|
||||||
if (Deltatime == 0.0) {
|
|
||||||
// jeśli załączona jest pauza, to tylko obsłużyć ruch w kabinie trzeba
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const totaltime { Deltatime * Iterationcount };
|
|
||||||
// NOTE: we perform animations first, as they can determine factors like contact with powergrid
|
|
||||||
TAnimModel::AnimUpdate( totaltime ); // wykonanie zakolejkowanych animacji
|
|
||||||
|
|
||||||
simulation::Powergrid.update( totaltime );
|
|
||||||
simulation::Vehicles.update( Deltatime, Iterationcount );
|
|
||||||
}
|
|
||||||
|
|
||||||
// restores class data from provided stream
|
// restores class data from provided stream
|
||||||
void
|
void
|
||||||
state_manager::deserialize( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// prepare deserialization function table
|
// prepare deserialization function table
|
||||||
// since all methods use the same objects, we can have simple, hard-coded binds or lambdas for the task
|
// since all methods use the same objects, we can have simple, hard-coded binds or lambdas for the task
|
||||||
using deserializefunction = void(state_manager::*)(cParser &, scene::scratch_data &);
|
using deserializefunction = void( state_serializer::*)(cParser &, scene::scratch_data &);
|
||||||
std::vector<
|
std::vector<
|
||||||
std::pair<
|
std::pair<
|
||||||
std::string,
|
std::string,
|
||||||
deserializefunction> > functionlist = {
|
deserializefunction> > functionlist = {
|
||||||
{ "atmo", &state_manager::deserialize_atmo },
|
{ "atmo", &state_serializer::deserialize_atmo },
|
||||||
{ "camera", &state_manager::deserialize_camera },
|
{ "camera", &state_serializer::deserialize_camera },
|
||||||
{ "config", &state_manager::deserialize_config },
|
{ "config", &state_serializer::deserialize_config },
|
||||||
{ "description", &state_manager::deserialize_description },
|
{ "description", &state_serializer::deserialize_description },
|
||||||
{ "event", &state_manager::deserialize_event },
|
{ "event", &state_serializer::deserialize_event },
|
||||||
{ "firstinit", &state_manager::deserialize_firstinit },
|
{ "firstinit", &state_serializer::deserialize_firstinit },
|
||||||
{ "light", &state_manager::deserialize_light },
|
{ "light", &state_serializer::deserialize_light },
|
||||||
{ "node", &state_manager::deserialize_node },
|
{ "node", &state_serializer::deserialize_node },
|
||||||
{ "origin", &state_manager::deserialize_origin },
|
{ "origin", &state_serializer::deserialize_origin },
|
||||||
{ "endorigin", &state_manager::deserialize_endorigin },
|
{ "endorigin", &state_serializer::deserialize_endorigin },
|
||||||
{ "rotate", &state_manager::deserialize_rotate },
|
{ "rotate", &state_serializer::deserialize_rotate },
|
||||||
{ "sky", &state_manager::deserialize_sky },
|
{ "sky", &state_serializer::deserialize_sky },
|
||||||
{ "test", &state_manager::deserialize_test },
|
{ "test", &state_serializer::deserialize_test },
|
||||||
{ "time", &state_manager::deserialize_time },
|
{ "time", &state_serializer::deserialize_time },
|
||||||
{ "trainset", &state_manager::deserialize_trainset },
|
{ "trainset", &state_serializer::deserialize_trainset },
|
||||||
{ "endtrainset", &state_manager::deserialize_endtrainset } };
|
{ "endtrainset", &state_serializer::deserialize_endtrainset } };
|
||||||
using deserializefunctionbind = std::function<void()>;
|
using deserializefunctionbind = std::function<void()>;
|
||||||
std::unordered_map<
|
std::unordered_map<
|
||||||
std::string,
|
std::string,
|
||||||
@@ -146,7 +162,7 @@ state_manager::deserialize( cParser &Input, scene::scratch_data &Scratchpad ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// NOTE: parameter system needs some decent replacement, but not worth the effort if we're moving to built-in editor
|
// NOTE: parameter system needs some decent replacement, but not worth the effort if we're moving to built-in editor
|
||||||
// atmosphere color; legacy parameter, no longer used
|
// atmosphere color; legacy parameter, no longer used
|
||||||
@@ -178,7 +194,7 @@ state_manager::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
glm::dvec3 xyz, abc;
|
glm::dvec3 xyz, abc;
|
||||||
int i = -1, into = -1; // do której definicji kamery wstawić
|
int i = -1, into = -1; // do której definicji kamery wstawić
|
||||||
@@ -232,21 +248,21 @@ state_manager::deserialize_camera( cParser &Input, scene::scratch_data &Scratchp
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_config( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_config( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// config parameters (re)definition
|
// config parameters (re)definition
|
||||||
Global.ConfigParse( Input );
|
Global.ConfigParse( Input );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_description( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_description( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// legacy section, never really used;
|
// legacy section, never really used;
|
||||||
skip_until( Input, "enddescription" );
|
skip_until( Input, "enddescription" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_event( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_event( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// TODO: refactor event class and its de/serialization. do offset and rotation after deserialization is done
|
// TODO: refactor event class and its de/serialization. do offset and rotation after deserialization is done
|
||||||
auto *event = new TEvent();
|
auto *event = new TEvent();
|
||||||
@@ -265,7 +281,7 @@ state_manager::deserialize_event( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_firstinit( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_firstinit( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
if( true == Scratchpad.initialized ) { return; }
|
if( true == Scratchpad.initialized ) { return; }
|
||||||
|
|
||||||
@@ -279,14 +295,14 @@ state_manager::deserialize_firstinit( cParser &Input, scene::scratch_data &Scrat
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_light( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_light( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// legacy section, no longer used nor supported;
|
// legacy section, no longer used nor supported;
|
||||||
skip_until( Input, "endlight" );
|
skip_until( Input, "endlight" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
auto const inputline = Input.Line(); // cache in case we need to report error
|
auto const inputline = Input.Line(); // cache in case we need to report error
|
||||||
|
|
||||||
@@ -469,7 +485,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_origin( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_origin( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
glm::dvec3 offset;
|
glm::dvec3 offset;
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
@@ -486,7 +502,7 @@ state_manager::deserialize_origin( cParser &Input, scene::scratch_data &Scratchp
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
if( false == Scratchpad.location.offset.empty() ) {
|
if( false == Scratchpad.location.offset.empty() ) {
|
||||||
Scratchpad.location.offset.pop();
|
Scratchpad.location.offset.pop();
|
||||||
@@ -497,7 +513,7 @@ state_manager::deserialize_endorigin( cParser &Input, scene::scratch_data &Scrat
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_rotate( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_rotate( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
Input
|
Input
|
||||||
@@ -507,7 +523,7 @@ state_manager::deserialize_rotate( cParser &Input, scene::scratch_data &Scratchp
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_sky( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_sky( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// sky model
|
// sky model
|
||||||
Input.getTokens( 1 );
|
Input.getTokens( 1 );
|
||||||
@@ -518,14 +534,14 @@ state_manager::deserialize_sky( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_test( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_test( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// legacy section, no longer supported;
|
// legacy section, no longer supported;
|
||||||
skip_until( Input, "endtest" );
|
skip_until( Input, "endtest" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_time( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_time( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// current scenario time
|
// current scenario time
|
||||||
cParser timeparser( Input.getToken<std::string>() );
|
cParser timeparser( Input.getToken<std::string>() );
|
||||||
@@ -548,7 +564,7 @@ state_manager::deserialize_time( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_trainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_trainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
if( true == Scratchpad.trainset.is_open ) {
|
if( true == Scratchpad.trainset.is_open ) {
|
||||||
// shouldn't happen but if it does wrap up currently open trainset and report an error
|
// shouldn't happen but if it does wrap up currently open trainset and report an error
|
||||||
@@ -568,7 +584,7 @@ state_manager::deserialize_trainset( cParser &Input, scene::scratch_data &Scratc
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_endtrainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_endtrainset( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
if( ( false == Scratchpad.trainset.is_open )
|
if( ( false == Scratchpad.trainset.is_open )
|
||||||
|| ( true == Scratchpad.trainset.vehicles.empty() ) ) {
|
|| ( true == Scratchpad.trainset.vehicles.empty() ) ) {
|
||||||
@@ -616,7 +632,7 @@ state_manager::deserialize_endtrainset( cParser &Input, scene::scratch_data &Scr
|
|||||||
|
|
||||||
// creates path and its wrapper, restoring class data from provided stream
|
// creates path and its wrapper, restoring class data from provided stream
|
||||||
TTrack *
|
TTrack *
|
||||||
state_manager::deserialize_path( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_path( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
||||||
auto *track = new TTrack( Nodedata );
|
auto *track = new TTrack( Nodedata );
|
||||||
@@ -633,7 +649,7 @@ state_manager::deserialize_path( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
}
|
}
|
||||||
|
|
||||||
TTraction *
|
TTraction *
|
||||||
state_manager::deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
if( false == Global.bLoadTraction ) {
|
if( false == Global.bLoadTraction ) {
|
||||||
skip_until( Input, "endtraction" );
|
skip_until( Input, "endtraction" );
|
||||||
@@ -651,7 +667,7 @@ state_manager::deserialize_traction( cParser &Input, scene::scratch_data &Scratc
|
|||||||
}
|
}
|
||||||
|
|
||||||
TTractionPowerSource *
|
TTractionPowerSource *
|
||||||
state_manager::deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
if( false == Global.bLoadTraction ) {
|
if( false == Global.bLoadTraction ) {
|
||||||
skip_until( Input, "end" );
|
skip_until( Input, "end" );
|
||||||
@@ -667,7 +683,7 @@ state_manager::deserialize_tractionpowersource( cParser &Input, scene::scratch_d
|
|||||||
}
|
}
|
||||||
|
|
||||||
TMemCell *
|
TMemCell *
|
||||||
state_manager::deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
auto *memorycell = new TMemCell( Nodedata );
|
auto *memorycell = new TMemCell( Nodedata );
|
||||||
memorycell->Load( &Input );
|
memorycell->Load( &Input );
|
||||||
@@ -678,7 +694,7 @@ state_manager::deserialize_memorycell( cParser &Input, scene::scratch_data &Scra
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEventLauncher *
|
TEventLauncher *
|
||||||
state_manager::deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
glm::dvec3 location;
|
glm::dvec3 location;
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
@@ -695,7 +711,7 @@ state_manager::deserialize_eventlauncher( cParser &Input, scene::scratch_data &S
|
|||||||
}
|
}
|
||||||
|
|
||||||
TAnimModel *
|
TAnimModel *
|
||||||
state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
glm::dvec3 location;
|
glm::dvec3 location;
|
||||||
glm::vec3 rotation;
|
glm::vec3 rotation;
|
||||||
@@ -721,7 +737,7 @@ state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
}
|
}
|
||||||
|
|
||||||
TDynamicObject *
|
TDynamicObject *
|
||||||
state_manager::deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
if( false == Scratchpad.trainset.is_open ) {
|
if( false == Scratchpad.trainset.is_open ) {
|
||||||
// part of trainset data is used when loading standalone vehicles, so clear it just in case
|
// part of trainset data is used when loading standalone vehicles, so clear it just in case
|
||||||
@@ -846,7 +862,7 @@ state_manager::deserialize_dynamic( cParser &Input, scene::scratch_data &Scratch
|
|||||||
}
|
}
|
||||||
|
|
||||||
sound_source *
|
sound_source *
|
||||||
state_manager::deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_serializer::deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
glm::dvec3 location;
|
glm::dvec3 location;
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
@@ -869,7 +885,7 @@ state_manager::deserialize_sound( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
|
|
||||||
// skips content of stream until specified token
|
// skips content of stream until specified token
|
||||||
void
|
void
|
||||||
state_manager::skip_until( cParser &Input, std::string const &Token ) {
|
state_serializer::skip_until( cParser &Input, std::string const &Token ) {
|
||||||
|
|
||||||
std::string token { Input.getToken<std::string>() };
|
std::string token { Input.getToken<std::string>() };
|
||||||
while( ( false == token.empty() )
|
while( ( false == token.empty() )
|
||||||
@@ -881,7 +897,7 @@ state_manager::skip_until( cParser &Input, std::string const &Token ) {
|
|||||||
|
|
||||||
// transforms provided location by specifed rotation and offset
|
// transforms provided location by specifed rotation and offset
|
||||||
glm::dvec3
|
glm::dvec3
|
||||||
state_manager::transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad ) {
|
state_serializer::transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad ) {
|
||||||
|
|
||||||
if( Scratchpad.location.rotation != glm::vec3( 0, 0, 0 ) ) {
|
if( Scratchpad.location.rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||||
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
||||||
@@ -896,7 +912,7 @@ state_manager::transform( glm::dvec3 Location, scene::scratch_data const &Scratc
|
|||||||
|
|
||||||
// stores class data in specified file, in legacy (text) format
|
// stores class data in specified file, in legacy (text) format
|
||||||
void
|
void
|
||||||
state_manager::export_as_text( std::string const &Scenariofile ) const {
|
state_serializer::export_as_text( std::string const &Scenariofile ) const {
|
||||||
|
|
||||||
if( Scenariofile == "$.scn" ) {
|
if( Scenariofile == "$.scn" ) {
|
||||||
ErrorLog( "Bad file: scenery export not supported for file \"$.scn\"" );
|
ErrorLog( "Bad file: scenery export not supported for file \"$.scn\"" );
|
||||||
|
|||||||
26
simulation.h
26
simulation.h
@@ -25,15 +25,11 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
namespace simulation {
|
namespace simulation {
|
||||||
|
|
||||||
class state_manager {
|
class state_serializer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// types
|
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
// legacy method, calculates changes in simulation state over specified time
|
// restores simulation data from specified file. returns: true on success, false otherwise
|
||||||
void
|
|
||||||
update( double Deltatime, int Iterationcount );
|
|
||||||
bool
|
bool
|
||||||
deserialize( std::string const &Scenariofile );
|
deserialize( std::string const &Scenariofile );
|
||||||
// stores class data in specified file, in legacy (text) format
|
// stores class data in specified file, in legacy (text) format
|
||||||
@@ -72,7 +68,25 @@ private:
|
|||||||
void skip_until( cParser &Input, std::string const &Token );
|
void skip_until( cParser &Input, std::string const &Token );
|
||||||
// transforms provided location by specifed rotation and offset
|
// transforms provided location by specifed rotation and offset
|
||||||
glm::dvec3 transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad );
|
glm::dvec3 transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad );
|
||||||
|
};
|
||||||
|
|
||||||
|
class state_manager {
|
||||||
|
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
|
void
|
||||||
|
update( double Deltatime, int Iterationcount );
|
||||||
|
// restores simulation data from specified file. returns: true on success, false otherwise
|
||||||
|
bool
|
||||||
|
deserialize( std::string const &Scenariofile );
|
||||||
|
// stores class data in specified file, in legacy (text) format
|
||||||
|
void
|
||||||
|
export_as_text( std::string const &Scenariofile ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// members
|
||||||
|
state_serializer m_serializer;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern state_manager State;
|
extern state_manager State;
|
||||||
|
|||||||
192
simulationtime.cpp
Normal file
192
simulationtime.cpp
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "simulationtime.h"
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
namespace simulation {
|
||||||
|
|
||||||
|
scenario_time Time;
|
||||||
|
|
||||||
|
} // simulation
|
||||||
|
|
||||||
|
void
|
||||||
|
scenario_time::init() {
|
||||||
|
|
||||||
|
char monthdaycounts[ 2 ][ 13 ] = {
|
||||||
|
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||||
|
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
|
||||||
|
::memcpy( m_monthdaycounts, monthdaycounts, sizeof( monthdaycounts ) );
|
||||||
|
|
||||||
|
// potentially adjust scenario clock
|
||||||
|
auto const requestedtime { clamp_circular<int>( m_time.wHour * 60 + m_time.wMinute + Global.ScenarioTimeOffset * 60, 24 * 60 ) };
|
||||||
|
auto const requestedhour { ( requestedtime / 60 ) % 24 };
|
||||||
|
auto const requestedminute { requestedtime % 60 };
|
||||||
|
// cache requested elements, if any
|
||||||
|
::GetLocalTime( &m_time );
|
||||||
|
|
||||||
|
if( Global.fMoveLight > 0.0 ) {
|
||||||
|
// day and month of the year can be overriden by scenario setup
|
||||||
|
daymonth( m_time.wDay, m_time.wMonth, m_time.wYear, static_cast<WORD>( Global.fMoveLight ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( requestedhour != -1 ) { m_time.wHour = static_cast<WORD>( clamp( requestedhour, 0, 23 ) ); }
|
||||||
|
if( requestedminute != -1 ) { m_time.wMinute = static_cast<WORD>( clamp( requestedminute, 0, 59 ) ); }
|
||||||
|
// if the time is taken from the local clock leave the seconds intact, otherwise set them to zero
|
||||||
|
if( ( requestedhour != -1 )
|
||||||
|
|| ( requestedminute != 1 ) ) {
|
||||||
|
m_time.wSecond = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_yearday = year_day( m_time.wDay, m_time.wMonth, m_time.wYear );
|
||||||
|
|
||||||
|
// calculate time zone bias
|
||||||
|
// retrieve relevant time zone info from system registry (or fall back on supplied default)
|
||||||
|
// TODO: select timezone matching defined geographic location and/or country
|
||||||
|
struct registry_time_zone_info {
|
||||||
|
long Bias;
|
||||||
|
long StandardBias;
|
||||||
|
long DaylightBias;
|
||||||
|
SYSTEMTIME StandardDate;
|
||||||
|
SYSTEMTIME DaylightDate;
|
||||||
|
} registrytimezoneinfo = { -60, 0, -60, { 0, 10, 0, 5, 3, 0, 0, 0 }, { 0, 3, 0, 5, 2, 0, 0, 0 } };
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
TCHAR timezonekeyname[] { TEXT( "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\Central European Standard Time" ) };
|
||||||
|
HKEY timezonekey { NULL };
|
||||||
|
DWORD size { sizeof( registrytimezoneinfo ) };
|
||||||
|
if( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, timezonekeyname, 0, KEY_QUERY_VALUE, &timezonekey ) == ERROR_SUCCESS ) {
|
||||||
|
::RegQueryValueEx( timezonekey, "TZI", NULL, NULL, (BYTE *)®istrytimezoneinfo, &size );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
TIME_ZONE_INFORMATION timezoneinfo { 0 };
|
||||||
|
timezoneinfo.Bias = registrytimezoneinfo.Bias;
|
||||||
|
timezoneinfo.DaylightBias = registrytimezoneinfo.DaylightBias;
|
||||||
|
timezoneinfo.DaylightDate = registrytimezoneinfo.DaylightDate;
|
||||||
|
timezoneinfo.StandardBias = registrytimezoneinfo.StandardBias;
|
||||||
|
timezoneinfo.StandardDate = registrytimezoneinfo.StandardDate;
|
||||||
|
|
||||||
|
auto zonebias { timezoneinfo.Bias };
|
||||||
|
if( m_yearday < year_day( timezoneinfo.DaylightDate.wDay, timezoneinfo.DaylightDate.wMonth, m_time.wYear ) ) {
|
||||||
|
zonebias += timezoneinfo.StandardBias;
|
||||||
|
}
|
||||||
|
else if( m_yearday < year_day( timezoneinfo.StandardDate.wDay, timezoneinfo.StandardDate.wMonth, m_time.wYear ) ) {
|
||||||
|
zonebias += timezoneinfo.DaylightBias;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
zonebias += timezoneinfo.StandardBias;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_timezonebias = ( zonebias / 60.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
scenario_time::update( double const Deltatime ) {
|
||||||
|
|
||||||
|
m_milliseconds += ( 1000.0 * Deltatime );
|
||||||
|
while( m_milliseconds >= 1000.0 ) {
|
||||||
|
|
||||||
|
++m_time.wSecond;
|
||||||
|
m_milliseconds -= 1000.0;
|
||||||
|
}
|
||||||
|
m_time.wMilliseconds = std::floor( m_milliseconds );
|
||||||
|
while( m_time.wSecond >= 60 ) {
|
||||||
|
|
||||||
|
++m_time.wMinute;
|
||||||
|
m_time.wSecond -= 60;
|
||||||
|
}
|
||||||
|
while( m_time.wMinute >= 60 ) {
|
||||||
|
|
||||||
|
++m_time.wHour;
|
||||||
|
m_time.wMinute -= 60;
|
||||||
|
}
|
||||||
|
while( m_time.wHour >= 24 ) {
|
||||||
|
|
||||||
|
++m_time.wDay;
|
||||||
|
++m_time.wDayOfWeek;
|
||||||
|
if( m_time.wDayOfWeek >= 7 ) {
|
||||||
|
m_time.wDayOfWeek -= 7;
|
||||||
|
}
|
||||||
|
m_time.wHour -= 24;
|
||||||
|
}
|
||||||
|
int leap = ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 );
|
||||||
|
while( m_time.wDay > m_monthdaycounts[ leap ][ m_time.wMonth ] ) {
|
||||||
|
|
||||||
|
m_time.wDay -= m_monthdaycounts[ leap ][ m_time.wMonth ];
|
||||||
|
++m_time.wMonth;
|
||||||
|
// unlikely but we might've entered a new year
|
||||||
|
if( m_time.wMonth > 12 ) {
|
||||||
|
|
||||||
|
++m_time.wYear;
|
||||||
|
leap = ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 );
|
||||||
|
m_time.wMonth -= 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
scenario_time::year_day( int Day, const int Month, const int Year ) const {
|
||||||
|
|
||||||
|
char const daytab[ 2 ][ 13 ] = {
|
||||||
|
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||||
|
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) };
|
||||||
|
for( int i = 1; i < Month; ++i )
|
||||||
|
Day += daytab[ leap ][ i ];
|
||||||
|
|
||||||
|
return Day;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
scenario_time::daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yearday ) {
|
||||||
|
|
||||||
|
WORD daytab[ 2 ][ 13 ] = {
|
||||||
|
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
|
||||||
|
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int leap = ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 );
|
||||||
|
WORD idx = 1;
|
||||||
|
while( ( idx < 13 ) && ( Yearday >= daytab[ leap ][ idx ] ) ) {
|
||||||
|
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
Month = idx;
|
||||||
|
Day = Yearday - daytab[ leap ][ idx - 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
scenario_time::julian_day() const {
|
||||||
|
|
||||||
|
int yy = ( m_time.wYear < 0 ? m_time.wYear + 1 : m_time.wYear ) - std::floor( ( 12 - m_time.wMonth ) / 10.f );
|
||||||
|
int mm = m_time.wMonth + 9;
|
||||||
|
if( mm >= 12 ) { mm -= 12; }
|
||||||
|
|
||||||
|
int K1 = std::floor( 365.25 * ( yy + 4712 ) );
|
||||||
|
int K2 = std::floor( 30.6 * mm + 0.5 );
|
||||||
|
|
||||||
|
// for dates in Julian calendar
|
||||||
|
int JD = K1 + K2 + m_time.wDay + 59;
|
||||||
|
// for dates in Gregorian calendar; 2299160 is October 15th, 1582
|
||||||
|
const int gregorianswitchday = 2299160;
|
||||||
|
if( JD > gregorianswitchday ) {
|
||||||
|
|
||||||
|
int K3 = std::floor( std::floor( ( yy * 0.01 ) + 49 ) * 0.75 ) - 38;
|
||||||
|
JD -= K3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JD;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
66
simulationtime.h
Normal file
66
simulationtime.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// wrapper for scenario time
|
||||||
|
class scenario_time {
|
||||||
|
|
||||||
|
public:
|
||||||
|
scenario_time() {
|
||||||
|
m_time.wHour = 10; m_time.wMinute = 30; }
|
||||||
|
void
|
||||||
|
init();
|
||||||
|
void
|
||||||
|
update( double const Deltatime );
|
||||||
|
inline
|
||||||
|
SYSTEMTIME &
|
||||||
|
data() {
|
||||||
|
return m_time; }
|
||||||
|
inline
|
||||||
|
SYSTEMTIME const &
|
||||||
|
data() const {
|
||||||
|
return m_time; }
|
||||||
|
inline
|
||||||
|
double
|
||||||
|
second() const {
|
||||||
|
return ( m_time.wMilliseconds * 0.001 + m_time.wSecond ); }
|
||||||
|
inline
|
||||||
|
int
|
||||||
|
year_day() const {
|
||||||
|
return m_yearday; }
|
||||||
|
// helper, calculates day of year from given date
|
||||||
|
int
|
||||||
|
year_day( int Day, int const Month, int const Year ) const;
|
||||||
|
int
|
||||||
|
julian_day() const;
|
||||||
|
inline
|
||||||
|
double
|
||||||
|
zone_bias() const {
|
||||||
|
return m_timezonebias; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// calculates day and month from given day of year
|
||||||
|
void
|
||||||
|
daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yearday );
|
||||||
|
|
||||||
|
SYSTEMTIME m_time;
|
||||||
|
double m_milliseconds{ 0.0 };
|
||||||
|
int m_yearday;
|
||||||
|
char m_monthdaycounts[ 2 ][ 13 ];
|
||||||
|
double m_timezonebias{ 0.0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace simulation {
|
||||||
|
|
||||||
|
extern scenario_time Time;
|
||||||
|
|
||||||
|
} // simulation
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
2
sky.h
2
sky.h
@@ -14,7 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
class TSky {
|
class TSky {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TSky() = default;
|
TSky() = default;
|
||||||
|
|||||||
2
stars.h
2
stars.h
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
class cStars {
|
class cStars {
|
||||||
|
|
||||||
friend class opengl_renderer;
|
friend opengl_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// types:
|
// types:
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "dynobj.h"
|
#include "dynobj.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
|
|
||||||
|
namespace simulation {
|
||||||
|
|
||||||
|
basic_station Station;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// exchanges load with consist attached to specified vehicle, operating on specified schedule
|
// exchanges load with consist attached to specified vehicle, operating on specified schedule
|
||||||
double
|
double
|
||||||
basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) {
|
basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform ) {
|
||||||
|
|||||||
@@ -20,3 +20,9 @@ public:
|
|||||||
double
|
double
|
||||||
update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform );
|
update_load( TDynamicObject *First, Mtable::TTrainParameters &Schedule, int const Platform );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace simulation {
|
||||||
|
|
||||||
|
extern basic_station Station; // temporary object, for station functionality tests
|
||||||
|
|
||||||
|
} // simulation
|
||||||
|
|||||||
2
sun.cpp
2
sun.cpp
@@ -4,7 +4,7 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include "world.h"
|
#include "simulationtime.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun,
|
// cSun -- class responsible for dynamic calculation of position and intensity of the Sun,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
|
#include "simulationtime.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "sceneeditor.h"
|
#include "sceneeditor.h"
|
||||||
|
|||||||
@@ -257,17 +257,23 @@ int stol_def(const std::string &str, const int &DefaultValue) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToLower(std::string const &text)
|
std::string ToLower(std::string const &text) {
|
||||||
{
|
|
||||||
std::string lowercase( text );
|
auto lowercase { text };
|
||||||
std::transform(text.begin(), text.end(), lowercase.begin(), ::tolower);
|
std::transform(
|
||||||
|
std::begin( text ), std::end( text ),
|
||||||
|
std::begin( lowercase ),
|
||||||
|
[]( unsigned char c ) { return std::tolower( c ); } );
|
||||||
return lowercase;
|
return lowercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToUpper(std::string const &text)
|
std::string ToUpper(std::string const &text) {
|
||||||
{
|
|
||||||
std::string uppercase( text );
|
auto uppercase { text };
|
||||||
std::transform(text.begin(), text.end(), uppercase.begin(), ::toupper);
|
std::transform(
|
||||||
|
std::begin( text ), std::end( text ),
|
||||||
|
std::begin( uppercase ),
|
||||||
|
[]( unsigned char c ) { return std::toupper( c ); } );
|
||||||
return uppercase;
|
return uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ LONG CALLBACK unhandled_handler(::EXCEPTION_POINTERS* e)
|
|||||||
HWND Hwnd;
|
HWND Hwnd;
|
||||||
WNDPROC BaseWindowProc;
|
WNDPROC BaseWindowProc;
|
||||||
PCOPYDATASTRUCT pDane;
|
PCOPYDATASTRUCT pDane;
|
||||||
extern TWorld World;
|
|
||||||
|
|
||||||
LRESULT APIENTRY WndProc( HWND hWnd, // handle for this window
|
LRESULT APIENTRY WndProc( HWND hWnd, // handle for this window
|
||||||
UINT uMsg, // message for this window
|
UINT uMsg, // message for this window
|
||||||
|
|||||||
Reference in New Issue
Block a user