OpenTTD Source: src/video/dedicated_v.cpp Source File

OpenTTD Source 15.0-beta1

dedicated_v.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "../stdafx.h"
11
12#include "../gfx_func.h"
13#include "../error_func.h"
14#include "../network/network.h"
15#include "../network/network_internal.h"
16#include "../console_func.h"
17#include "../genworld.h"
18#include "../fileio_type.h"
19#include "../fios.h"
20#include "../blitter/factory.hpp"
21#include "../company_func.h"
22#include "../core/random_func.hpp"
23#include "../saveload/saveload.h"
24#include "../thread.h"
25#include "../window_func.h"
26#include <iostream>
27#include "dedicated_v.h"
28
29#if defined(UNIX)
30# include <sys/time.h> /* gettimeofday */
31# include <sys/types.h>
32# include <unistd.h>
33# include <signal.h>
34# define STDIN 0 /* file descriptor for standard input */
35
36/* Signal handlers */
37static void DedicatedSignalHandler(int sig)
38{
39 if (_game_mode == GM_NORMAL && _settings_client.gui.autosave_on_exit) DoExitSave();
40 _exit_game = true;
41 signal(sig, DedicatedSignalHandler);
42}
43#endif
44
45#if defined(_WIN32)
46# include <windows.h> /* GetTickCount */
47# include <conio.h>
48# include <time.h>
49# include <tchar.h>
50# include "../os/windows/win32.h"
51
52static HANDLE _hInputReady, _hWaitForInputHandling;
53static HANDLE _hThread; // Thread to close
54static std::string _win_console_thread_buffer;
55
56/* Windows Console thread. Just loop and signal when input has been received */
57static void WINAPI CheckForConsoleInput()
58{
59 SetCurrentThreadName("ottd:win-console");
60
61 for (;;) {
62 std::getline(std::cin, _win_console_thread_buffer);
63
64 /* Signal input waiting that input is read and wait for it being handled. */
65 SignalObjectAndWait(_hInputReady, _hWaitForInputHandling, INFINITE, FALSE);
66 }
67}
68
69static void CreateWindowsConsoleThread()
70{
71 DWORD dwThreadId;
72 /* Create event to signal when console input is ready */
73 _hInputReady = CreateEvent(nullptr, false, false, nullptr);
74 _hWaitForInputHandling = CreateEvent(nullptr, false, false, nullptr);
75 if (_hInputReady == nullptr || _hWaitForInputHandling == nullptr) UserError("Cannot create console event!");
76
77 _hThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)CheckForConsoleInput, nullptr, 0, &dwThreadId);
78 if (_hThread == nullptr) UserError("Cannot create console thread!");
79
80 Debug(driver, 2, "Windows console thread started");
81}
82
83static void CloseWindowsConsoleThread()
84{
85 CloseHandle(_hThread);
86 CloseHandle(_hInputReady);
87 CloseHandle(_hWaitForInputHandling);
88 Debug(driver, 2, "Windows console thread shut down");
89}
90
91#endif
92
93#include "../safeguards.h"
94
95
96static void *_dedicated_video_mem;
97
98/* Whether a fork has been done. */
99bool _dedicated_forks;
100
101extern bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr);
102
103static FVideoDriver_Dedicated iFVideoDriver_Dedicated;
104
105
106std::optional<std::string_view> VideoDriver_Dedicated::Start(const StringList &)
107{
108 this->UpdateAutoResolution();
109
110 int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
111 _dedicated_video_mem = (bpp == 0) ? nullptr : MallocT<uint8_t>(static_cast<size_t>(_cur_resolution.width) * _cur_resolution.height * (bpp / 8));
112
113 _screen.width = _screen.pitch = _cur_resolution.width;
114 _screen.height = _cur_resolution.height;
115 _screen.dst_ptr = _dedicated_video_mem;
116 ScreenSizeChanged();
117 BlitterFactory::GetCurrentBlitter()->PostResize();
118
119#if defined(_WIN32)
120 /* For win32 we need to allocate a console (debug mode does the same) */
121 CreateConsole();
122 CreateWindowsConsoleThread();
123 SetConsoleTitle(L"OpenTTD Dedicated Server");
124#endif
125
126#ifdef _MSC_VER
127 /* Disable the MSVC assertion message box. */
128 _set_error_mode(_OUT_TO_STDERR);
129 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
130 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
131#endif
132
133 Debug(driver, 1, "Loading dedicated server");
134 return std::nullopt;
135}
136
137 void VideoDriver_Dedicated::Stop()
138{
139#ifdef _WIN32
140 CloseWindowsConsoleThread();
141#endif
142 free(_dedicated_video_mem);
143}
144
145 void VideoDriver_Dedicated::MakeDirty(int, int, int, int) {}
146 bool VideoDriver_Dedicated::ChangeResolution(int, int) { return false; }
147 bool VideoDriver_Dedicated::ToggleFullscreen(bool) { return false; }
148
149#if defined(UNIX)
150static bool InputWaiting()
151{
152 struct timeval tv;
153 fd_set readfds;
154
155 tv.tv_sec = 0;
156 tv.tv_usec = 1;
157
158 FD_ZERO(&readfds);
159 FD_SET(STDIN, &readfds);
160
161 /* don't care about writefds and exceptfds: */
162 return select(STDIN + 1, &readfds, nullptr, nullptr, &tv) > 0;
163}
164
165#else
166
167static bool InputWaiting()
168{
169 return WaitForSingleObject(_hInputReady, 1) == WAIT_OBJECT_0;
170}
171
172#endif
173
174static void DedicatedHandleKeyInput()
175{
176 if (!InputWaiting()) return;
177
178 if (_exit_game) return;
179
180 std::string input_line;
181#if defined(UNIX)
182 if (!std::getline(std::cin, input_line)) return;
183#else
184 /* Handle console input, and signal console thread, it can accept input again */
185 std::swap(input_line, _win_console_thread_buffer);
186 SetEvent(_hWaitForInputHandling);
187#endif
188
189 /* Remove any trailing \r or \n, and ensure the string is valid. */
190 auto p = input_line.find_last_not_of("\r\n");
191 if (p != std::string::npos) p++;
192 IConsoleCmdExec(StrMakeValid(input_line.substr(0, p)));
193}
194
195 void VideoDriver_Dedicated::MainLoop()
196{
197 /* Signal handlers */
198#if defined(UNIX)
199 signal(SIGTERM, DedicatedSignalHandler);
200 signal(SIGINT, DedicatedSignalHandler);
201 signal(SIGQUIT, DedicatedSignalHandler);
202#endif
203
204 /* Load the dedicated server stuff */
205 _is_network_server = true;
206 _network_dedicated = true;
207 _current_company = _local_company = COMPANY_SPECTATOR;
208
209 /* If SwitchMode is SM_LOAD_GAME / SM_START_HEIGHTMAP, it means that the user used the '-g' options */
210 if (_switch_mode != SM_LOAD_GAME && _switch_mode != SM_START_HEIGHTMAP) {
211 StartNewGameWithoutGUI(GENERATE_NEW_SEED);
212 }
213
214 this->is_game_threaded = false;
215
216 /* Done loading, start game! */
217
218 while (!_exit_game) {
219 if (!_dedicated_forks) DedicatedHandleKeyInput();
220 this->DrainCommandQueue();
221
222 this->Tick();
223 this->SleepTillNextTick();
224 }
225}
BlitterFactory::GetCurrentBlitter
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition factory.hpp:138
Blitter::GetScreenDepth
virtual uint8_t GetScreenDepth()=0
Get the screen depth this blitter works for.
Blitter::PostResize
virtual void PostResize()
Post resize event.
Definition base.hpp:205
FVideoDriver_Dedicated
Factory for the dedicated server video driver.
Definition dedicated_v.h:34
VideoDriver_Dedicated::Start
std::optional< std::string_view > Start(const StringList &param) override
Start this driver.
Definition dedicated_v.cpp:106
VideoDriver_Dedicated::MainLoop
void MainLoop() override
Perform the actual drawing.
Definition dedicated_v.cpp:195
VideoDriver_Dedicated::Stop
void Stop() override
Stop this driver.
Definition dedicated_v.cpp:137
VideoDriver_Dedicated::ToggleFullscreen
bool ToggleFullscreen(bool fullscreen) override
Change the full screen setting.
Definition dedicated_v.cpp:147
VideoDriver_Dedicated::MakeDirty
void MakeDirty(int left, int top, int width, int height) override
Mark a particular area dirty.
Definition dedicated_v.cpp:145
VideoDriver_Dedicated::ChangeResolution
bool ChangeResolution(int w, int h) override
Change the resolution of the window.
Definition dedicated_v.cpp:146
VideoDriver::Tick
void Tick()
Give the video-driver a tick.
Definition video_driver.cpp:102
VideoDriver::SleepTillNextTick
void SleepTillNextTick()
Sleep till the next tick is about to happen.
Definition video_driver.cpp:171
VideoDriver::DrainCommandQueue
void DrainCommandQueue()
Execute all queued commands.
Definition video_driver.hpp:337
VideoDriver::UpdateAutoResolution
void UpdateAutoResolution()
Apply resolution auto-detection and clamp to sensible defaults.
Definition video_driver.hpp:244
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:52
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:53
COMPANY_SPECTATOR
@ COMPANY_SPECTATOR
The client is spectating.
Definition company_type.h:35
IConsoleCmdExec
void IConsoleCmdExec(const std::string &command_string, const uint recurse_count)
Execute a given command passed to us.
Definition console.cpp:291
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition debug.h:37
dedicated_v.h
Base for the dedicated video driver.
_cur_resolution
Dimension _cur_resolution
The current resolution.
Definition driver.cpp:26
SaveLoadOperation
SaveLoadOperation
Operation performed on the file.
Definition fileio_type.h:53
DetailedFileType
DetailedFileType
Kinds of files in each AbstractFileType.
Definition fileio_type.h:29
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition fileio_type.h:115
GENERATE_NEW_SEED
static const uint32_t GENERATE_NEW_SEED
Create a new random seed.
Definition genworld.h:24
StartNewGameWithoutGUI
void StartNewGameWithoutGUI(uint32_t seed)
Start a normal game without the GUI.
Definition genworld_gui.cpp:1066
_switch_mode
SwitchMode _switch_mode
The next mainloop command.
Definition gfx.cpp:49
_is_network_server
bool _is_network_server
Does this client wants to be a network-server?
Definition network.cpp:69
_network_dedicated
bool _network_dedicated
are we a dedicated server?
Definition network.cpp:68
SM_START_HEIGHTMAP
@ SM_START_HEIGHTMAP
Load a heightmap and start a new game from it.
Definition openttd.h:38
SM_LOAD_GAME
@ SM_LOAD_GAME
Load game, Play Scenario.
Definition openttd.h:32
GameMode
GameMode
Mode which defines the state of the game.
Definition openttd.h:18
DoExitSave
void DoExitSave()
Do a save when exiting the game (_settings_client.gui.autosave_on_exit)
Definition saveload.cpp:3237
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
free
void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition stdafx.h:334
StrMakeValid
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition string.cpp:107
StringList
std::vector< std::string > StringList
Type for a list of strings.
Definition string_type.h:60
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:610
GUISettings::autosave_on_exit
bool autosave_on_exit
save an autosave when you quit the game, but do not ask "Do you really want to quit?...
Definition settings_type.h:171
LoadFilter
Interface for filtering a savegame till it is loaded.
Definition saveload_filter.h:14
SetCurrentThreadName
void SetCurrentThreadName(const char *threadName)
Name the thread this function is called on for the debugger.
Definition unix.cpp:245