Merge tag '1.11.1' into 1.11

This commit is contained in:
Sergii Pylypenko
2021-04-25 22:58:47 +03:00
150 changed files with 1525 additions and 616 deletions
+1 -1
View File
@@ -134,7 +134,7 @@ static bool _allowSoftware;
CGLSetCurrentContext(ctx);
OpenGLBackend::Get()->Paint();
if (_cursor.in_window) OpenGLBackend::Get()->DrawMouseCursor();
OpenGLBackend::Get()->DrawMouseCursor();
[ super drawInCGLContext:ctx pixelFormat:pf forLayerTime:t displayTime:ts ];
}
+1 -1
View File
@@ -224,7 +224,7 @@ bool VideoDriver_Cocoa::AfterBlitterChange()
*/
void VideoDriver_Cocoa::EditBoxLostFocus()
{
[ [ this->cocoaview inputContext ] discardMarkedText ];
[ [ this->cocoaview inputContext ] performSelectorOnMainThread:@selector(discardMarkedText) withObject:nil waitUntilDone:[ NSThread isMainThread ] ];
/* Clear any marked string from the current edit box. */
HandleTextInput(nullptr, true);
}
+32 -13
View File
@@ -510,7 +510,7 @@ OpenGLBackend::~OpenGLBackend()
_glDeleteBuffers(1, &this->anim_pbo);
}
if (_glDeleteTextures != nullptr) {
ClearCursorCache();
this->InternalClearCursorCache();
OpenGLSprite::Destroy();
_glDeleteTextures(1, &this->vid_texture);
@@ -1053,18 +1053,20 @@ void OpenGLBackend::Paint()
*/
void OpenGLBackend::DrawMouseCursor()
{
if (!this->cursor_in_window) return;
/* Draw cursor on screen */
_cur_dpi = &_screen;
for (uint i = 0; i < _cursor.sprite_count; ++i) {
SpriteID sprite = _cursor.sprite_seq[i].sprite;
for (uint i = 0; i < this->cursor_sprite_count; ++i) {
SpriteID sprite = this->cursor_sprite_seq[i].sprite;
/* Sprites are cached by PopulateCursorCache(). */
if (this->cursor_cache.Contains(sprite)) {
const Sprite *spr = GetSprite(sprite, ST_NORMAL);
Sprite *spr = this->cursor_cache.Get(sprite);
this->RenderOglSprite((OpenGLSprite *)this->cursor_cache.Get(sprite)->data, _cursor.sprite_seq[i].pal,
_cursor.pos.x + _cursor.sprite_pos[i].x + UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI),
_cursor.pos.y + _cursor.sprite_pos[i].y + UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI),
this->RenderOglSprite((OpenGLSprite *)spr->data, this->cursor_sprite_seq[i].pal,
this->cursor_pos.x + this->cursor_sprite_pos[i].x + UnScaleByZoom(spr->x_offs, ZOOM_LVL_GUI),
this->cursor_pos.y + this->cursor_sprite_pos[i].y + UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI),
ZOOM_LVL_GUI);
}
}
@@ -1072,20 +1074,24 @@ void OpenGLBackend::DrawMouseCursor()
void OpenGLBackend::PopulateCursorCache()
{
static_assert(lengthof(_cursor.sprite_seq) == lengthof(this->cursor_sprite_seq));
static_assert(lengthof(_cursor.sprite_pos) == lengthof(this->cursor_sprite_pos));
if (this->clear_cursor_cache) {
/* We have a pending cursor cache clear to do first. */
this->clear_cursor_cache = false;
this->last_sprite_pal = (PaletteID)-1;
Sprite *sp;
while ((sp = this->cursor_cache.Pop()) != nullptr) {
OpenGLSprite *sprite = (OpenGLSprite *)sp->data;
sprite->~OpenGLSprite();
free(sp);
}
this->InternalClearCursorCache();
}
this->cursor_pos = _cursor.pos;
this->cursor_sprite_count = _cursor.sprite_count;
this->cursor_in_window = _cursor.in_window;
for (uint i = 0; i < _cursor.sprite_count; ++i) {
this->cursor_sprite_seq[i] = _cursor.sprite_seq[i];
this->cursor_sprite_pos[i] = _cursor.sprite_pos[i];
SpriteID sprite = _cursor.sprite_seq[i].sprite;
if (!this->cursor_cache.Contains(sprite)) {
@@ -1102,6 +1108,19 @@ void OpenGLBackend::PopulateCursorCache()
/**
* Clear all cached cursor sprites.
*/
void OpenGLBackend::InternalClearCursorCache()
{
Sprite *sp;
while ((sp = this->cursor_cache.Pop()) != nullptr) {
OpenGLSprite *sprite = (OpenGLSprite *)sp->data;
sprite->~OpenGLSprite();
free(sp);
}
}
/**
* Queue a request for cursor cache clear.
*/
void OpenGLBackend::ClearCursorCache()
{
/* If the game loop is threaded, this function might be called
+8
View File
@@ -65,12 +65,20 @@ private:
PaletteID last_sprite_pal = (PaletteID)-1; ///< Last uploaded remap palette.
bool clear_cursor_cache = false; ///< A clear of the cursor cache is pending.
Point cursor_pos; ///< Cursor position
bool cursor_in_window; ///< Cursor inside this window
PalSpriteID cursor_sprite_seq[16]; ///< Current image of cursor
Point cursor_sprite_pos[16]; ///< Relative position of individual cursor sprites
uint cursor_sprite_count; ///< Number of cursor sprites to draw
OpenGLBackend();
~OpenGLBackend();
const char *Init();
bool InitShaders();
void InternalClearCursorCache();
void RenderOglSprite(OpenGLSprite *gl_sprite, PaletteID pal, int x, int y, ZoomLevel zoom);
public:
+13 -3
View File
@@ -69,8 +69,11 @@ const char *VideoDriver_SDL_OpenGL::Start(const StringList &param)
int w, h;
SDL_GetWindowSize(this->sdl_window, &w, &h);
this->ClientSizeChanged(w, h, true);
SDL_GL_SetSwapInterval(GetDriverParamBool(param, "vsync") ? 1 : 0);
/* We should have a valid screen buffer now. If not, something went wrong and we should abort. */
if (_screen.dst_ptr == nullptr) {
this->Stop();
return "Can't get pointer to screen buffer";
}
return nullptr;
}
@@ -91,6 +94,11 @@ void VideoDriver_SDL_OpenGL::DestroyContext()
}
}
void VideoDriver_SDL_OpenGL::ToggleVsync(bool vsync)
{
SDL_GL_SetSwapInterval(vsync);
}
const char *VideoDriver_SDL_OpenGL::AllocateContext()
{
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
@@ -107,6 +115,8 @@ const char *VideoDriver_SDL_OpenGL::AllocateContext()
this->gl_context = SDL_GL_CreateContext(this->sdl_window);
if (this->gl_context == nullptr) return "SDL2: Can't active GL context";
ToggleVsync(_video_vsync);
return OpenGLBackend::Create(&GetOGLProcAddressCallback);
}
@@ -174,7 +184,7 @@ void VideoDriver_SDL_OpenGL::Paint()
}
OpenGLBackend::Get()->Paint();
if (_cursor.in_window) OpenGLBackend::Get()->DrawMouseCursor();
OpenGLBackend::Get()->DrawMouseCursor();
SDL_GL_SwapWindow(this->sdl_window);
}
+2
View File
@@ -29,6 +29,8 @@ public:
bool HasAnimBuffer() override { return true; }
uint8 *GetAnimBuffer() override { return this->anim_buffer; }
void ToggleVsync(bool vsync) override;
const char *GetName() const override { return "sdl-opengl"; }
protected:
+1 -1
View File
@@ -17,7 +17,7 @@
/** The SDL video driver. */
class VideoDriver_SDL_Base : public VideoDriver {
public:
VideoDriver_SDL_Base() : sdl_window(nullptr) {}
VideoDriver_SDL_Base() : sdl_window(nullptr), buffer_locked(false) {}
const char *Start(const StringList &param) override;
+1
View File
@@ -21,6 +21,7 @@
#include "video_driver.hpp"
bool _video_hw_accel; ///< Whether to consider hardware accelerated video drivers.
bool _video_vsync; ///< Whether we should use vsync (only if _video_hw_accel is enabled).
void VideoDriver::GameLoop()
{
+8 -1
View File
@@ -28,6 +28,7 @@ extern std::vector<Dimension> _resolutions;
extern Dimension _cur_resolution;
extern bool _rightclick_emulate;
extern bool _video_hw_accel;
extern bool _video_vsync;
/** The base of all video drivers. */
class VideoDriver : public Driver {
@@ -35,7 +36,7 @@ class VideoDriver : public Driver {
const uint DEFAULT_WINDOW_HEIGHT = 480u; ///< Default window height.
public:
VideoDriver() : is_game_threaded(true), change_blitter(nullptr) {}
VideoDriver() : fast_forward_key_pressed(false), fast_forward_via_key(false), is_game_threaded(true), change_blitter(nullptr) {}
/**
* Mark a particular area dirty.
@@ -66,6 +67,12 @@ public:
*/
virtual bool ToggleFullscreen(bool fullscreen) = 0;
/**
* Change the vsync setting.
* @param vsync The new setting.
*/
virtual void ToggleVsync(bool vsync) {}
/**
* Callback invoked after the blitter was changed.
* @return True if no error.
+34 -28
View File
@@ -552,14 +552,6 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
uint scancode = GB(lParam, 16, 8);
keycode = scancode == 41 ? (uint)WKC_BACKQUOTE : MapWindowsKey(wParam);
/* Silently drop all messages handled by WM_CHAR. */
MSG msg;
if (PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE)) {
if ((msg.message == WM_CHAR || msg.message == WM_DEADCHAR) && GB(lParam, 16, 8) == GB(msg.lParam, 16, 8)) {
return 0;
}
}
uint charcode = MapVirtualKey(wParam, MAPVK_VK_TO_CHAR);
/* No character translation? */
@@ -568,21 +560,26 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
return 0;
}
/* Is the console key a dead key? If yes, ignore the first key down event. */
if (HasBit(charcode, 31) && !console) {
if (scancode == 41) {
console = true;
return 0;
/* If an edit box is in focus, wait for the corresponding WM_CHAR message. */
if (!EditBoxInGlobalFocus()) {
/* Is the console key a dead key? If yes, ignore the first key down event. */
if (HasBit(charcode, 31) && !console) {
if (scancode == 41) {
console = true;
return 0;
}
}
console = false;
/* IMEs and other input methods sometimes send a WM_CHAR without a WM_KEYDOWN,
* clear the keycode so a previous WM_KEYDOWN doesn't become 'stuck'. */
uint cur_keycode = keycode;
keycode = 0;
return HandleCharMsg(cur_keycode, LOWORD(charcode));
}
console = false;
/* IMEs and other input methods sometimes send a WM_CHAR without a WM_KEYDOWN,
* clear the keycode so a previous WM_KEYDOWN doesn't become 'stuck'. */
uint cur_keycode = keycode;
keycode = 0;
return HandleCharMsg(cur_keycode, LOWORD(charcode));
return 0;
}
case WM_SYSKEYDOWN: // user presses F10 or Alt, both activating the title-menu
@@ -1293,7 +1290,6 @@ const char *VideoDriver_Win32OpenGL::Start(const StringList &param)
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return "Only real blitters supported";
Dimension old_res = _cur_resolution; // Save current screen resolution in case of errors, as MakeWindow invalidates it.
this->vsync = GetDriverParamBool(param, "vsync");
LoadWGLExtensions();
@@ -1309,6 +1305,12 @@ const char *VideoDriver_Win32OpenGL::Start(const StringList &param)
}
this->ClientSizeChanged(this->width, this->height, true);
/* We should have a valid screen buffer now. If not, something went wrong and we should abort. */
if (_screen.dst_ptr == nullptr) {
this->Stop();
_cur_resolution = old_res;
return "Can't get pointer to screen buffer";
}
MarkWholeScreenDirty();
@@ -1338,6 +1340,15 @@ void VideoDriver_Win32OpenGL::DestroyContext()
}
}
void VideoDriver_Win32OpenGL::ToggleVsync(bool vsync)
{
if (_wglSwapIntervalEXT != nullptr) {
_wglSwapIntervalEXT(vsync);
} else if (vsync) {
DEBUG(driver, 0, "OpenGL: Vsync requested, but not supported by driver");
}
}
const char *VideoDriver_Win32OpenGL::AllocateContext()
{
this->dc = GetDC(this->main_wnd);
@@ -1366,12 +1377,7 @@ const char *VideoDriver_Win32OpenGL::AllocateContext()
}
if (!wglMakeCurrent(this->dc, rc)) return "Can't active GL context";
/* Enable/disable Vsync if supported. */
if (_wglSwapIntervalEXT != nullptr) {
_wglSwapIntervalEXT(this->vsync ? 1 : 0);
} else if (vsync) {
DEBUG(driver, 0, "OpenGL: Vsync requested, but not supported by driver");
}
this->ToggleVsync(_video_vsync);
this->gl_rc = rc;
return OpenGLBackend::Create(&GetOGLProcAddressCallback);
@@ -1457,7 +1463,7 @@ void VideoDriver_Win32OpenGL::Paint()
}
OpenGLBackend::Get()->Paint();
if (_cursor.in_window) OpenGLBackend::Get()->DrawMouseCursor();
OpenGLBackend::Get()->DrawMouseCursor();
SwapBuffers(this->dc);
}
+3 -2
View File
@@ -17,7 +17,7 @@
/** Base class for Windows video drivers. */
class VideoDriver_Win32Base : public VideoDriver {
public:
VideoDriver_Win32Base() : main_wnd(nullptr), fullscreen(false) {}
VideoDriver_Win32Base() : main_wnd(nullptr), fullscreen(false), buffer_locked(false) {}
void Stop() override;
@@ -138,12 +138,13 @@ public:
bool HasAnimBuffer() override { return true; }
uint8 *GetAnimBuffer() override { return this->anim_buffer; }
void ToggleVsync(bool vsync) override;
const char *GetName() const override { return "win32-opengl"; }
protected:
HDC dc; ///< Window device context.
HGLRC gl_rc; ///< OpenGL context.
bool vsync; ///< Enable VSync?
uint8 *anim_buffer; ///< Animation buffer from OpenGL back-end.
uint8 GetFullscreenBpp() override { return 32; } // OpenGL is always 32 bpp.