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

OpenTTD Source 15.0-RC2

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