Merge tag '1.11.1' into 1.11
This commit is contained in:
@@ -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 ];
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -69,8 +69,11 @@ const char *VideoDriver_SDL_OpenGL::Start(const StringList ¶m)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 ¶m) override;
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
@@ -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 ¶m)
|
||||
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 ¶m)
|
||||
}
|
||||
|
||||
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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user