mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
292 lines
8.5 KiB
C++
292 lines
8.5 KiB
C++
/*
|
|
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/.
|
|
*/
|
|
/*
|
|
MaSzyna EU07 locomotive simulator
|
|
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
|
|
|
*/
|
|
/*
|
|
Authors:
|
|
MarcinW, McZapkie, Shaxbee, ABu, nbmx, youBy, Ra, winger, mamut, Q424,
|
|
Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Globals.h"
|
|
#include "Logs.h"
|
|
#include "Console.h"
|
|
#include "PyInt.h"
|
|
#include "World.h"
|
|
#include "Mover.h"
|
|
|
|
#pragma comment (lib, "glew32.lib")
|
|
#pragma comment (lib, "glu32.lib")
|
|
#pragma comment (lib, "opengl32.lib")
|
|
#pragma comment (lib, "dsound.lib")
|
|
#pragma comment (lib, "winmm.lib")
|
|
#pragma comment (lib, "setupapi.lib")
|
|
#pragma comment (lib, "python27.lib")
|
|
#pragma comment (lib, "dbghelp.lib")
|
|
#pragma comment (lib, "glfw3.lib") //static
|
|
|
|
TWorld World;
|
|
|
|
#ifdef _WINDOWS
|
|
void make_minidump( ::EXCEPTION_POINTERS* e ) {
|
|
|
|
auto hDbgHelp = ::LoadLibraryA( "dbghelp" );
|
|
if( hDbgHelp == nullptr )
|
|
return;
|
|
auto pMiniDumpWriteDump = (decltype( &MiniDumpWriteDump ))::GetProcAddress( hDbgHelp, "MiniDumpWriteDump" );
|
|
if( pMiniDumpWriteDump == nullptr )
|
|
return;
|
|
|
|
char name[ MAX_PATH ];
|
|
{
|
|
auto nameEnd = name + ::GetModuleFileNameA( ::GetModuleHandleA( 0 ), name, MAX_PATH );
|
|
::SYSTEMTIME t;
|
|
::GetSystemTime( &t );
|
|
wsprintfA( nameEnd - strlen( ".exe" ),
|
|
"_crashdump_%4d%02d%02d_%02d%02d%02d.dmp",
|
|
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond );
|
|
}
|
|
|
|
auto hFile = ::CreateFileA( name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
return;
|
|
|
|
::MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
|
|
exceptionInfo.ThreadId = ::GetCurrentThreadId();
|
|
exceptionInfo.ExceptionPointers = e;
|
|
exceptionInfo.ClientPointers = FALSE;
|
|
|
|
auto dumped = pMiniDumpWriteDump(
|
|
::GetCurrentProcess(),
|
|
::GetCurrentProcessId(),
|
|
hFile,
|
|
::MINIDUMP_TYPE( ::MiniDumpWithIndirectlyReferencedMemory | ::MiniDumpScanMemory ),
|
|
e ? &exceptionInfo : nullptr,
|
|
nullptr,
|
|
nullptr );
|
|
|
|
::CloseHandle( hFile );
|
|
|
|
return;
|
|
}
|
|
|
|
LONG CALLBACK unhandled_handler( ::EXCEPTION_POINTERS* e ) {
|
|
make_minidump( e );
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
}
|
|
#endif
|
|
|
|
void window_resize_callback(GLFWwindow *window, int w, int h)
|
|
{
|
|
glViewport(0, 0, w, h); // Reset The Current Viewport
|
|
glMatrixMode(GL_PROJECTION); // select the Projection Matrix
|
|
glLoadIdentity(); // reset the Projection Matrix
|
|
// calculate the aspect ratio of the window
|
|
gluPerspective(45.0f, (GLdouble)w / (GLdouble)h, 0.2f, 2500.0f);
|
|
glMatrixMode(GL_MODELVIEW); // select the Modelview Matrix
|
|
glLoadIdentity(); // reset the Modelview Matrix
|
|
}
|
|
|
|
void cursor_pos_callback(GLFWwindow *window, double x, double y)
|
|
{
|
|
if (Global::bActive)
|
|
World.OnMouseMove(x * 0.005, y * 0.01);
|
|
glfwSetCursorPos(window, 0.0, 0.0);
|
|
}
|
|
|
|
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
|
{
|
|
//m7todo: bActive teraz pewnie nie potrzebne
|
|
if (!Global::bActive)
|
|
return;
|
|
|
|
Global::shiftState = (mods & GLFW_MOD_SHIFT) ? true : false;
|
|
Global::ctrlState = (mods & GLFW_MOD_CONTROL) ? true : false;
|
|
|
|
if (action == GLFW_PRESS || action == GLFW_REPEAT)
|
|
{
|
|
World.OnKeyDown(key);
|
|
|
|
switch (key)
|
|
{
|
|
case GLFW_KEY_PAUSE:
|
|
if (Global::iPause & 1)
|
|
Global::iPause &= ~1;
|
|
else if (!(Global::iMultiplayer & 2) &&
|
|
(mods & GLFW_MOD_CONTROL))
|
|
Global::iPause ^= 2;
|
|
if (Global::iPause)
|
|
Global::iTextMode = GLFW_KEY_F1;
|
|
break;
|
|
|
|
case GLFW_KEY_F7:
|
|
Global::bWireFrame = !Global::bWireFrame;
|
|
++Global::iReCompile;
|
|
break;
|
|
}
|
|
}
|
|
else if (action == GLFW_RELEASE)
|
|
{
|
|
World.OnKeyUp(key);
|
|
}
|
|
}
|
|
|
|
void focus_callback(GLFWwindow *window, int focus)
|
|
{
|
|
Global::bActive = (focus == GLFW_TRUE ? 1 : 0);
|
|
if (Global::bInactivePause) // jeśli ma być pauzowanie okna w tle
|
|
if (Global::bActive)
|
|
Global::iPause &= ~4; // odpauzowanie, gdy jest na pierwszym planie
|
|
else
|
|
Global::iPause |= 4; // włączenie pauzy, gdy nieaktywy
|
|
}
|
|
|
|
int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR lpCmdLine, int)
|
|
{
|
|
#ifdef _WINDOWS
|
|
::SetUnhandledExceptionFilter(unhandled_handler);
|
|
#endif
|
|
|
|
if (!glfwInit())
|
|
return -1;
|
|
|
|
DeleteFile("errors.txt"); // usunięcie starego
|
|
Global::LoadIniFile("eu07.ini"); // teraz dopiero można przejrzeć plik z ustawieniami
|
|
Global::InitKeys("keys.ini"); // wczytanie mapowania klawiszy - jest na stałe
|
|
|
|
// hunter-271211: ukrywanie konsoli
|
|
if (Global::iWriteLogEnabled & 2)
|
|
{
|
|
AllocConsole();
|
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
|
|
}
|
|
|
|
std::string commandline(lpCmdLine);
|
|
if (!commandline.empty())
|
|
{
|
|
cParser parser(commandline);
|
|
std::string token;
|
|
do
|
|
{
|
|
parser.getTokens();
|
|
token.clear();
|
|
parser >> token;
|
|
|
|
if (token == "-s")
|
|
{ // nazwa scenerii
|
|
parser.getTokens();
|
|
parser >> Global::SceneryFile;
|
|
}
|
|
else if (token == "-v")
|
|
{ // nazwa wybranego pojazdu
|
|
parser.getTokens();
|
|
parser >> Global::asHumanCtrlVehicle;
|
|
}
|
|
else if (token == "-modifytga")
|
|
{ // wykonanie modyfikacji wszystkich plików TGA
|
|
Global::iModifyTGA = -1; // specjalny tryb wykonania totalnej modyfikacji
|
|
}
|
|
else if (token == "-e3d")
|
|
{ // wygenerowanie wszystkich plików E3D
|
|
if (Global::iConvertModels > 0)
|
|
Global::iConvertModels = -Global::iConvertModels; // specjalny tryb
|
|
else
|
|
Global::iConvertModels = -7; // z optymalizacją, bananami i prawidłowym Opacity
|
|
}
|
|
else
|
|
Error(
|
|
"Program usage: EU07 [-s sceneryfilepath] [-v vehiclename] [-modifytga] [-e3d]",
|
|
!Global::iWriteLogEnabled);
|
|
}
|
|
while (!token.empty());
|
|
}
|
|
|
|
glfwWindowHint(GLFW_SAMPLES, Global::iMultisampling);
|
|
|
|
// 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);
|
|
|
|
GLFWwindow *window =
|
|
glfwCreateWindow(Global::iWindowWidth, Global::iWindowHeight,
|
|
"EU07++", Global::bFullScreen ? monitor : nullptr, nullptr);
|
|
|
|
if (!window)
|
|
return -1;
|
|
glfwMakeContextCurrent(window);
|
|
glfwSwapInterval(1); //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);
|
|
glfwSetKeyCallback(window, key_callback);
|
|
glfwSetWindowFocusCallback(window, focus_callback);
|
|
{
|
|
int width, height;
|
|
glfwGetFramebufferSize(window, &width, &height);
|
|
window_resize_callback(window, width, height);
|
|
}
|
|
|
|
if (glewInit() != GLEW_OK)
|
|
return -1;
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
|
|
if (!World.Init(window))
|
|
return -1;
|
|
|
|
Console *pConsole = new Console(); // Ra: nie wiem, czy ma to sens, ale jakoś zainicjowac trzeba
|
|
|
|
if (!joyGetNumDevs())
|
|
WriteLog("No joystick");
|
|
if (Global::iModifyTGA < 0)
|
|
{ // tylko modyfikacja TGA, bez uruchamiania symulacji
|
|
Global::iMaxTextureSize = 64; //żeby nie zamulać pamięci
|
|
World.ModifyTGA(); // rekurencyjne przeglądanie katalogów
|
|
}
|
|
else
|
|
{
|
|
if (Global::iConvertModels < 0)
|
|
{
|
|
Global::iConvertModels = -Global::iConvertModels;
|
|
World.CreateE3D("models\\"); // rekurencyjne przeglądanie katalogów
|
|
World.CreateE3D("dynamic\\", true);
|
|
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
|
|
|
|
Console::On(); // włączenie konsoli
|
|
while (!glfwWindowShouldClose(window) && World.Update())
|
|
{
|
|
glfwSwapBuffers(window);
|
|
glfwPollEvents();
|
|
}
|
|
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
|
|
}
|
|
|
|
delete pConsole;
|
|
TPythonInterpreter::killInstance();
|
|
|
|
glfwDestroyWindow(window);
|
|
glfwTerminate();
|
|
return 0;
|
|
}
|