Merge tag '1.11.0-beta1' into jgrpp
# Conflicts: # src/console_cmds.cpp # src/gfx_func.h # src/industry.h # src/lang/czech.txt # src/lang/estonian.txt # src/lang/german.txt # src/lang/indonesian.txt # src/lang/japanese.txt # src/lang/norwegian_bokmal.txt # src/lang/russian.txt # src/lang/slovak.txt # src/saveload/saveload.h # src/station_gui.cpp # src/town_gui.cpp # src/vehicle_gui.cpp # src/video/sdl2_v.cpp # src/waypoint_gui.cpp
This commit is contained in:
@@ -417,6 +417,8 @@ const char *VideoDriver_Allegro::Start(const StringList &parm)
|
||||
}
|
||||
_allegro_instance_count++;
|
||||
|
||||
this->UpdateAutoResolution();
|
||||
|
||||
install_timer();
|
||||
install_mouse();
|
||||
install_keyboard();
|
||||
|
||||
@@ -70,6 +70,9 @@ public:
|
||||
/** Main game loop. */
|
||||
void GameLoop(); // In event.mm.
|
||||
|
||||
protected:
|
||||
Dimension GetScreenSize() const override;
|
||||
|
||||
private:
|
||||
friend class WindowQuartzSubdriver;
|
||||
|
||||
|
||||
@@ -200,6 +200,8 @@ const char *VideoDriver_Cocoa::Start(const StringList &parm)
|
||||
/* Don't create a window or enter fullscreen if we're just going to show a dialog. */
|
||||
if (!CocoaSetupApplication()) return NULL;
|
||||
|
||||
this->UpdateAutoResolution();
|
||||
|
||||
this->orig_res = _cur_resolution;
|
||||
int width = _cur_resolution.width;
|
||||
int height = _cur_resolution.height;
|
||||
@@ -302,6 +304,15 @@ void VideoDriver_Cocoa::EditBoxLostFocus()
|
||||
HandleTextInput(NULL, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resolution of the main screen.
|
||||
*/
|
||||
Dimension VideoDriver_Cocoa::GetScreenSize() const
|
||||
{
|
||||
NSRect frame = [ [ NSScreen mainScreen ] frame ];
|
||||
return { static_cast<uint>(NSWidth(frame)), static_cast<uint>(NSHeight(frame)) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a change of the display area.
|
||||
*/
|
||||
|
||||
@@ -135,6 +135,8 @@ static FVideoDriver_Dedicated iFVideoDriver_Dedicated;
|
||||
|
||||
const char *VideoDriver_Dedicated::Start(const StringList &parm)
|
||||
{
|
||||
this->UpdateAutoResolution();
|
||||
|
||||
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
|
||||
_dedicated_video_mem = (bpp == 0) ? nullptr : MallocT<byte>(_cur_resolution.width * _cur_resolution.height * (bpp / 8));
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ const char *VideoDriver_Null::Start(const StringList &parm)
|
||||
_set_error_mode(_OUT_TO_STDERR);
|
||||
#endif
|
||||
|
||||
this->UpdateAutoResolution();
|
||||
|
||||
this->ticks = GetDriverParamInt(parm, "ticks", 1000);
|
||||
this->until_exit = GetDriverParamBool(parm, "until_exit");
|
||||
_screen.width = _screen.pitch = _cur_resolution.width;
|
||||
|
||||
@@ -491,8 +491,6 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize)
|
||||
|
||||
DEBUG(driver, 1, "SDL2: using mode %ux%ux%d", w, h, bpp);
|
||||
|
||||
if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals");
|
||||
|
||||
/* Free any previously allocated shadow surface */
|
||||
if (_sdl_surface != nullptr && _sdl_surface != _sdl_realscreen) SDL_FreeSurface(_sdl_surface);
|
||||
|
||||
@@ -505,10 +503,15 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize)
|
||||
flags |= SDL_WINDOW_FULLSCREEN;
|
||||
}
|
||||
|
||||
int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;
|
||||
SDL_Rect r;
|
||||
if (SDL_GetDisplayBounds(this->startup_display, &r) == 0) {
|
||||
x = r.x + std::max(0, r.w - static_cast<int>(w)) / 2;
|
||||
y = r.y + std::max(0, r.h - static_cast<int>(h)) / 4; // decent desktops have taskbars at the bottom
|
||||
}
|
||||
_sdl_window = SDL_CreateWindow(
|
||||
caption,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
x, y,
|
||||
w, h,
|
||||
flags);
|
||||
|
||||
@@ -997,6 +1000,8 @@ int VideoDriver_SDL::PollEvent()
|
||||
|
||||
const char *VideoDriver_SDL::Start(const StringList &parm)
|
||||
{
|
||||
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
|
||||
|
||||
#if defined(WITH_FCITX)
|
||||
FcitxInit();
|
||||
#endif
|
||||
@@ -1016,6 +1021,25 @@ const char *VideoDriver_SDL::Start(const StringList &parm)
|
||||
}
|
||||
if (ret_code < 0) return SDL_GetError();
|
||||
|
||||
this->startup_display = GetDriverParamInt(parm, "display", -1);
|
||||
int num_displays = SDL_GetNumVideoDisplays();
|
||||
if (!IsInsideBS(this->startup_display, 0, num_displays)) {
|
||||
/* Mouse position decides which display to use */
|
||||
int mx, my;
|
||||
SDL_GetGlobalMouseState(&mx, &my);
|
||||
this->startup_display = 0; // used when mouse is on no screen...
|
||||
for (int display = 0; display < num_displays; ++display) {
|
||||
SDL_Rect r;
|
||||
if (SDL_GetDisplayBounds(display, &r) == 0 && IsInsideBS(mx, r.x, r.w) && IsInsideBS(my, r.y, r.h)) {
|
||||
DEBUG(driver, 1, "SDL2: Mouse is at (%d, %d), use display %d (%d, %d, %d, %d)", mx, my, display, r.x, r.y, r.w, r.h);
|
||||
this->startup_display = display;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->UpdateAutoResolution();
|
||||
|
||||
GetVideoModes();
|
||||
if (!CreateMainSurface(_cur_resolution.width, _cur_resolution.height, false)) {
|
||||
return SDL_GetError();
|
||||
@@ -1268,6 +1292,7 @@ bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen)
|
||||
|
||||
bool VideoDriver_SDL::AfterBlitterChange()
|
||||
{
|
||||
assert(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0);
|
||||
int w, h;
|
||||
SDL_GetWindowSize(_sdl_window, &w, &h);
|
||||
return CreateMainSurface(w, h, false);
|
||||
@@ -1283,4 +1308,12 @@ void VideoDriver_SDL::ReleaseBlitterLock()
|
||||
if (_draw_mutex != nullptr) _draw_mutex->unlock();
|
||||
}
|
||||
|
||||
Dimension VideoDriver_SDL::GetScreenSize() const
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
if (SDL_GetCurrentDisplayMode(this->startup_display, &mode) != 0) return VideoDriver::GetScreenSize();
|
||||
|
||||
return { static_cast<uint>(mode.w), static_cast<uint>(mode.h) };
|
||||
}
|
||||
|
||||
#endif /* WITH_SDL2 */
|
||||
|
||||
@@ -40,6 +40,10 @@ public:
|
||||
void EditBoxLostFocus() override;
|
||||
|
||||
const char *GetName() const override { return "sdl"; }
|
||||
|
||||
protected:
|
||||
Dimension GetScreenSize() const override;
|
||||
|
||||
private:
|
||||
int PollEvent();
|
||||
void LoopOnce();
|
||||
@@ -60,6 +64,7 @@ private:
|
||||
uint32 last_cur_ticks;
|
||||
uint32 next_tick;
|
||||
|
||||
int startup_display;
|
||||
std::thread draw_thread;
|
||||
std::unique_lock<std::recursive_mutex> draw_lock;
|
||||
};
|
||||
|
||||
@@ -620,6 +620,8 @@ const char *VideoDriver_SDL::Start(const StringList &parm)
|
||||
}
|
||||
if (ret_code < 0) return SDL_GetError();
|
||||
|
||||
this->UpdateAutoResolution();
|
||||
|
||||
GetVideoModes();
|
||||
if (!CreateMainSurface(_cur_resolution.width, _cur_resolution.height)) {
|
||||
return SDL_GetError();
|
||||
|
||||
@@ -12,10 +12,19 @@
|
||||
|
||||
#include "../driver.h"
|
||||
#include "../core/geometry_type.hpp"
|
||||
#include "../core/math_func.hpp"
|
||||
#include <vector>
|
||||
|
||||
extern std::string _ini_videodriver;
|
||||
extern std::vector<Dimension> _resolutions;
|
||||
extern Dimension _cur_resolution;
|
||||
extern bool _rightclick_emulate;
|
||||
|
||||
/** The base of all video drivers. */
|
||||
class VideoDriver : public Driver {
|
||||
const uint DEFAULT_WINDOW_WIDTH = 640u; ///< Default window width.
|
||||
const uint DEFAULT_WINDOW_HEIGHT = 480u; ///< Default window height.
|
||||
|
||||
public:
|
||||
/**
|
||||
* Mark a particular area dirty.
|
||||
@@ -102,11 +111,27 @@ public:
|
||||
static VideoDriver *GetInstance() {
|
||||
return static_cast<VideoDriver*>(*DriverFactoryBase::GetActiveDriver(Driver::DT_VIDEO));
|
||||
}
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Get the resolution of the main screen.
|
||||
*/
|
||||
virtual Dimension GetScreenSize() const { return { DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT }; }
|
||||
|
||||
/**
|
||||
* Apply resolution auto-detection and clamp to sensible defaults.
|
||||
*/
|
||||
void UpdateAutoResolution()
|
||||
{
|
||||
if (_cur_resolution.width == 0 || _cur_resolution.height == 0) {
|
||||
/* Auto-detect a good resolution. We aim for 75% of the screen size.
|
||||
* Limit width times height times bytes per pixel to fit a 32 bit
|
||||
* integer, This way all internal drawing routines work correctly. */
|
||||
Dimension res = this->GetScreenSize();
|
||||
_cur_resolution.width = ClampU(res.width * 3 / 4, DEFAULT_WINDOW_WIDTH, UINT16_MAX / 2);
|
||||
_cur_resolution.height = ClampU(res.height * 3 / 4, DEFAULT_WINDOW_HEIGHT, UINT16_MAX / 2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern std::string _ini_videodriver;
|
||||
extern std::vector<Dimension> _resolutions;
|
||||
extern Dimension _cur_resolution;
|
||||
extern bool _rightclick_emulate;
|
||||
|
||||
#endif /* VIDEO_VIDEO_DRIVER_HPP */
|
||||
|
||||
@@ -44,9 +44,6 @@
|
||||
#define PM_QS_INPUT 0x20000
|
||||
#endif
|
||||
|
||||
typedef BOOL (WINAPI *PFNTRACKMOUSEEVENT)(LPTRACKMOUSEEVENT lpEventTrack);
|
||||
static PFNTRACKMOUSEEVENT _pTrackMouseEvent = nullptr;
|
||||
|
||||
static struct {
|
||||
HWND main_wnd; ///< Handle to system window.
|
||||
HBITMAP dib_sect; ///< System bitmap object referencing our rendering buffer.
|
||||
@@ -81,24 +78,24 @@ static Palette _local_palette;
|
||||
|
||||
static void MakePalette()
|
||||
{
|
||||
_cur_palette.first_dirty = 0;
|
||||
_cur_palette.count_dirty = 256;
|
||||
_local_palette = _cur_palette;
|
||||
|
||||
LOGPALETTE *pal = (LOGPALETTE*)alloca(sizeof(LOGPALETTE) + (256 - 1) * sizeof(PALETTEENTRY));
|
||||
|
||||
pal->palVersion = 0x300;
|
||||
pal->palNumEntries = 256;
|
||||
|
||||
for (uint i = 0; i != 256; i++) {
|
||||
pal->palPalEntry[i].peRed = _cur_palette.palette[i].r;
|
||||
pal->palPalEntry[i].peGreen = _cur_palette.palette[i].g;
|
||||
pal->palPalEntry[i].peBlue = _cur_palette.palette[i].b;
|
||||
pal->palPalEntry[i].peRed = _local_palette.palette[i].r;
|
||||
pal->palPalEntry[i].peGreen = _local_palette.palette[i].g;
|
||||
pal->palPalEntry[i].peBlue = _local_palette.palette[i].b;
|
||||
pal->palPalEntry[i].peFlags = 0;
|
||||
|
||||
}
|
||||
_wnd.gdi_palette = CreatePalette(pal);
|
||||
if (_wnd.gdi_palette == nullptr) usererror("CreatePalette failed!\n");
|
||||
|
||||
_cur_palette.first_dirty = 0;
|
||||
_cur_palette.count_dirty = 256;
|
||||
_local_palette = _cur_palette;
|
||||
}
|
||||
|
||||
static void UpdatePalette(HDC dc, uint start, uint count)
|
||||
@@ -234,31 +231,6 @@ int RedrawScreenDebug()
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Windows 95 will not have a WM_MOUSELEAVE message, so define it if needed */
|
||||
#if !defined(WM_MOUSELEAVE)
|
||||
#define WM_MOUSELEAVE 0x02A3
|
||||
#endif
|
||||
#define TID_POLLMOUSE 1
|
||||
#define MOUSE_POLL_DELAY 75
|
||||
|
||||
static void CALLBACK TrackMouseTimerProc(HWND hwnd, UINT msg, UINT_PTR event, DWORD time)
|
||||
{
|
||||
RECT rc;
|
||||
POINT pt;
|
||||
|
||||
/* Get the rectangle of our window and translate it to screen coordinates.
|
||||
* Compare this with the current screen coordinates of the mouse and if it
|
||||
* falls outside of the area or our window we have left the window. */
|
||||
GetClientRect(hwnd, &rc);
|
||||
MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT)(LPRECT)&rc, 2);
|
||||
GetCursorPos(&pt);
|
||||
|
||||
if (!PtInRect(&rc, pt) || (WindowFromPoint(pt) != hwnd)) {
|
||||
KillTimer(hwnd, event);
|
||||
PostMessage(hwnd, WM_MOUSELEAVE, 0, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new window.
|
||||
* @param full_screen Whether to make a full screen window or not.
|
||||
@@ -638,7 +610,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||
|
||||
switch (msg) {
|
||||
case WM_CREATE:
|
||||
SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, TrackMouseTimerProc);
|
||||
_cursor.in_window = false; // Win32 has mouse tracking.
|
||||
SetCompositionPos(hwnd);
|
||||
_imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);
|
||||
break;
|
||||
@@ -735,16 +707,12 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||
* tracking the mouse for exiting the window */
|
||||
if (!_cursor.in_window) {
|
||||
_cursor.in_window = true;
|
||||
if (_pTrackMouseEvent != nullptr) {
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(tme);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hwnd;
|
||||
TRACKMOUSEEVENT tme;
|
||||
tme.cbSize = sizeof(tme);
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hwnd;
|
||||
|
||||
_pTrackMouseEvent(&tme);
|
||||
} else {
|
||||
SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, TrackMouseTimerProc);
|
||||
}
|
||||
TrackMouseEvent(&tme);
|
||||
}
|
||||
|
||||
if (_cursor.fix_at) {
|
||||
@@ -1012,27 +980,24 @@ static void RegisterWndClass()
|
||||
{
|
||||
static bool registered = false;
|
||||
|
||||
if (!registered) {
|
||||
HINSTANCE hinst = GetModuleHandle(nullptr);
|
||||
WNDCLASS wnd = {
|
||||
CS_OWNDC,
|
||||
WndProcGdi,
|
||||
0,
|
||||
0,
|
||||
hinst,
|
||||
LoadIcon(hinst, MAKEINTRESOURCE(100)),
|
||||
LoadCursor(nullptr, IDC_ARROW),
|
||||
0,
|
||||
0,
|
||||
_T("OTTD")
|
||||
};
|
||||
if (registered) return;
|
||||
|
||||
registered = true;
|
||||
if (!RegisterClass(&wnd)) usererror("RegisterClass failed");
|
||||
HINSTANCE hinst = GetModuleHandle(nullptr);
|
||||
WNDCLASS wnd = {
|
||||
CS_OWNDC,
|
||||
WndProcGdi,
|
||||
0,
|
||||
0,
|
||||
hinst,
|
||||
LoadIcon(hinst, MAKEINTRESOURCE(100)),
|
||||
LoadCursor(nullptr, IDC_ARROW),
|
||||
0,
|
||||
0,
|
||||
_T("OTTD")
|
||||
};
|
||||
|
||||
/* Dynamically load mouse tracking, as it doesn't exist on Windows 95. */
|
||||
_pTrackMouseEvent = (PFNTRACKMOUSEEVENT)GetProcAddress(GetModuleHandle(_T("User32")), "TrackMouseEvent");
|
||||
}
|
||||
registered = true;
|
||||
if (!RegisterClass(&wnd)) usererror("RegisterClass failed");
|
||||
}
|
||||
|
||||
static bool AllocateDibSection(int w, int h, bool force)
|
||||
@@ -1044,8 +1009,6 @@ static bool AllocateDibSection(int w, int h, bool force)
|
||||
w = std::max(w, 64);
|
||||
h = std::max(h, 64);
|
||||
|
||||
if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals");
|
||||
|
||||
if (!force && w == _screen.width && h == _screen.height) return false;
|
||||
|
||||
bi = (BITMAPINFO*)alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
|
||||
@@ -1056,7 +1019,7 @@ static bool AllocateDibSection(int w, int h, bool force)
|
||||
bi->bmiHeader.biHeight = -(_wnd.height = h);
|
||||
|
||||
bi->bmiHeader.biPlanes = 1;
|
||||
bi->bmiHeader.biBitCount = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
|
||||
bi->bmiHeader.biBitCount = bpp;
|
||||
bi->bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
if (_wnd.dib_sect) DeleteObject(_wnd.dib_sect);
|
||||
@@ -1119,6 +1082,10 @@ static FVideoDriver_Win32 iFVideoDriver_Win32;
|
||||
|
||||
const char *VideoDriver_Win32::Start(const StringList &parm)
|
||||
{
|
||||
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
|
||||
|
||||
this->UpdateAutoResolution();
|
||||
|
||||
memset(&_wnd, 0, sizeof(_wnd));
|
||||
|
||||
RegisterWndClass();
|
||||
@@ -1282,7 +1249,7 @@ void VideoDriver_Win32::MainLoop()
|
||||
|
||||
/* Release the thread while sleeping */
|
||||
if (_draw_threaded) draw_lock.unlock();
|
||||
Sleep(1);
|
||||
CSleep(1);
|
||||
if (_draw_threaded) draw_lock.lock();
|
||||
|
||||
NetworkDrawChatMessage();
|
||||
@@ -1329,6 +1296,7 @@ bool VideoDriver_Win32::ToggleFullscreen(bool full_screen)
|
||||
|
||||
bool VideoDriver_Win32::AfterBlitterChange()
|
||||
{
|
||||
assert(BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0);
|
||||
return AllocateDibSection(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen);
|
||||
}
|
||||
|
||||
@@ -1351,3 +1319,8 @@ void VideoDriver_Win32::EditBoxLostFocus()
|
||||
SetCompositionPos(_wnd.main_wnd);
|
||||
SetCandidatePos(_wnd.main_wnd);
|
||||
}
|
||||
|
||||
Dimension VideoDriver_Win32::GetScreenSize() const
|
||||
{
|
||||
return { static_cast<uint>(GetSystemMetrics(SM_CXSCREEN)), static_cast<uint>(GetSystemMetrics(SM_CYSCREEN)) };
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ public:
|
||||
const char *GetName() const override { return "win32"; }
|
||||
|
||||
bool MakeWindow(bool full_screen);
|
||||
|
||||
protected:
|
||||
Dimension GetScreenSize() const override;
|
||||
};
|
||||
|
||||
/** The factory for Windows' video driver. */
|
||||
|
||||
Reference in New Issue
Block a user