diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.cpp @@ -555,4 +555,9 @@ bool VideoDriver_Allegro::ToggleFullscre #endif } +bool VideoDriver_Allegro::AfterBlitterChange() +{ + return CreateMainSurface(_screen.width, _screen.height); +} + #endif /* WITH_ALLEGRO */ diff --git a/src/video/allegro_v.h b/src/video/allegro_v.h --- a/src/video/allegro_v.h +++ b/src/video/allegro_v.h @@ -28,6 +28,9 @@ public: /* virtual */ bool ChangeResolution(int w, int h); /* virtual */ bool ToggleFullscreen(bool fullscreen); + + /* virtual */ bool AfterBlitterChange(); + /* virtual */ const char *GetName() const { return "allegro"; } }; diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h --- a/src/video/cocoa/cocoa_v.h +++ b/src/video/cocoa/cocoa_v.h @@ -47,6 +47,11 @@ public: */ /* virtual */ bool ToggleFullscreen(bool fullscreen); + /** Callback invoked after the blitter was changed. + * @return True if no error. + */ + /* virtual */ bool AfterBlitterChange(); + /** Return driver name * @return driver name */ @@ -123,7 +128,7 @@ public: * @param h New window height * @return Whether change was successful */ - virtual bool ChangeResolution(int w, int h) = 0; + virtual bool ChangeResolution(int w, int h, int bpp) = 0; /** Are we in fullscreen mode * @return whether fullscreen mode is currently used diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -400,7 +400,7 @@ bool VideoDriver_Cocoa::ChangeResolution { assert(_cocoa_subdriver != NULL); - bool ret = _cocoa_subdriver->ChangeResolution(w, h); + bool ret = _cocoa_subdriver->ChangeResolution(w, h, BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth()); QZ_GameSizeChanged(); QZ_UpdateVideoModes(); @@ -444,6 +444,16 @@ bool VideoDriver_Cocoa::ToggleFullscreen } /** + * Callback invoked after the blitter was changed. + * + * @return True if no error. + */ +bool VideoDriver_Cocoa::AfterBlitterChange() +{ + return this->ChangeResolution(_screen.width, _screen.height); +} + +/** * Catch asserts prior to initialization of the videodriver. * * @param title Window title. diff --git a/src/video/cocoa/fullscreen.mm b/src/video/cocoa/fullscreen.mm --- a/src/video/cocoa/fullscreen.mm +++ b/src/video/cocoa/fullscreen.mm @@ -250,7 +250,7 @@ class FullscreenSubdriver: public CocoaS } - bool SetVideoMode(int w, int h) + bool SetVideoMode(int w, int h, int bpp) { /* Define this variables at the top (against coding style) because * otherwise GCC 4.2 barfs at the goto's jumping over variable initialization. */ @@ -266,14 +266,14 @@ class FullscreenSubdriver: public CocoaS /* See if requested mode exists */ boolean_t exact_match; - this->cur_mode = CGDisplayBestModeForParameters(this->display_id, this->device_depth, w, h, &exact_match); + this->cur_mode = CGDisplayBestModeForParameters(this->display_id, bpp, w, h, &exact_match); /* If the mode wasn't an exact match, check if it has the right bpp, and update width and height */ if (!exact_match) { - int bpp; + int act_bpp; CFNumberRef number = (const __CFNumber*) CFDictionaryGetValue(this->cur_mode, kCGDisplayBitsPerPixel); - CFNumberGetValue(number, kCFNumberSInt32Type, &bpp); - if (bpp != this->device_depth) { + CFNumberGetValue(number, kCFNumberSInt32Type, &act_bpp); + if (act_bpp != bpp) { DEBUG(driver, 0, "Failed to find display resolution"); goto ERR_NO_MATCH; } @@ -323,6 +323,7 @@ class FullscreenSubdriver: public CocoaS this->device_width = CGDisplayPixelsWide(this->display_id); this->device_height = CGDisplayPixelsHigh(this->display_id); + this->device_depth = bpp; /* Setup double-buffer emulation */ this->pixel_buffer = malloc(this->device_width * this->device_height * this->device_depth / 8); @@ -418,22 +419,18 @@ ERR_NO_MATCH: } public: - FullscreenSubdriver(int bpp) + FullscreenSubdriver() { - if (bpp != 8 && bpp != 32) { - error("Cocoa: This video driver only supports 8 and 32 bpp blitters."); - } - /* Initialize the video settings; this data persists between mode switches */ this->display_id = kCGDirectMainDisplay; this->save_mode = CGDisplayCurrentMode(this->display_id); - if (bpp == 8) this->palette = CGPaletteCreateDefaultColorPalette(); + this->palette = CGPaletteCreateDefaultColorPalette(); this->device_width = CGDisplayPixelsWide(this->display_id); this->device_height = CGDisplayPixelsHigh(this->display_id); - this->device_depth = bpp; - this->pixel_buffer = NULL; + this->device_depth = 0; + this->pixel_buffer = NULL; this->num_dirty_rects = MAX_DIRTY_RECTS; } @@ -512,14 +509,16 @@ public: return QZ_ListModes(modes, max_modes, this->display_id, this->device_depth); } - virtual bool ChangeResolution(int w, int h) + virtual bool ChangeResolution(int w, int h, int bpp) { int old_width = this->device_width; int old_height = this->device_height; + int old_bpp = this->device_depth; - if (SetVideoMode(w, h)) return true; + if (bpp != 8 && bpp != 32) error("Cocoa: This video driver only supports 8 and 32 bpp blitters."); - if (old_width != 0 && old_height != 0) SetVideoMode(old_width, old_height); + if (SetVideoMode(w, h, bpp)) return true; + if (old_width != 0 && old_height != 0) SetVideoMode(old_width, old_height, old_bpp); return false; } @@ -583,9 +582,9 @@ CocoaSubdriver *QZ_CreateFullscreenSubdr return NULL; } - FullscreenSubdriver *ret = new FullscreenSubdriver(bpp); + FullscreenSubdriver *ret = new FullscreenSubdriver(); - if (!ret->ChangeResolution(width, height)) { + if (!ret->ChangeResolution(width, height, bpp)) { delete ret; return NULL; } diff --git a/src/video/cocoa/wnd_quartz.mm b/src/video/cocoa/wnd_quartz.mm --- a/src/video/cocoa/wnd_quartz.mm +++ b/src/video/cocoa/wnd_quartz.mm @@ -63,10 +63,10 @@ private: void BlitIndexedToView32(int left, int top, int right, int bottom); virtual void GetDeviceInfo(); - virtual bool SetVideoMode(int width, int height); + virtual bool SetVideoMode(int width, int height, int bpp); public: - WindowQuartzSubdriver(int bpp); + WindowQuartzSubdriver(); virtual ~WindowQuartzSubdriver(); virtual void Draw(bool force_update); @@ -75,7 +75,7 @@ public: virtual uint ListModes(OTTD_Point *modes, uint max_modes); - virtual bool ChangeResolution(int w, int h); + virtual bool ChangeResolution(int w, int h, int bpp); virtual bool IsFullscreen() { return false; } virtual bool ToggleFullscreen(); /* Full screen mode on OSX 10.7 */ @@ -248,7 +248,7 @@ bool WindowQuartzSubdriver::ToggleFullsc #endif } -bool WindowQuartzSubdriver::SetVideoMode(int width, int height) +bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp) { this->setup = true; this->GetDeviceInfo(); @@ -337,6 +337,7 @@ bool WindowQuartzSubdriver::SetVideoMode this->window_width = width; this->window_height = height; + this->buffer_depth = bpp; [ this->window center ]; @@ -381,11 +382,11 @@ void WindowQuartzSubdriver::BlitIndexedT } -WindowQuartzSubdriver::WindowQuartzSubdriver(int bpp) +WindowQuartzSubdriver::WindowQuartzSubdriver() { this->window_width = 0; this->window_height = 0; - this->buffer_depth = bpp; + this->buffer_depth = 0; this->window_buffer = NULL; this->pixel_buffer = NULL; this->active = false; @@ -481,13 +482,14 @@ uint WindowQuartzSubdriver::ListModes(OT return QZ_ListModes(modes, max_modes, kCGDirectMainDisplay, this->buffer_depth); } -bool WindowQuartzSubdriver::ChangeResolution(int w, int h) +bool WindowQuartzSubdriver::ChangeResolution(int w, int h, int bpp) { int old_width = this->window_width; int old_height = this->window_height; + int old_bpp = this->buffer_depth; - if (this->SetVideoMode(w, h)) return true; - if (old_width != 0 && old_height != 0) this->SetVideoMode(old_width, old_height); + if (this->SetVideoMode(w, h, bpp)) return true; + if (old_width != 0 && old_height != 0) this->SetVideoMode(old_width, old_height, old_bpp); return false; } @@ -599,9 +601,9 @@ CocoaSubdriver *QZ_CreateWindowQuartzSub return NULL; } - WindowQuartzSubdriver *ret = new WindowQuartzSubdriver(bpp); + WindowQuartzSubdriver *ret = new WindowQuartzSubdriver(); - if (!ret->ChangeResolution(width, height)) { + if (!ret->ChangeResolution(width, height, bpp)) { delete ret; return NULL; } diff --git a/src/video/cocoa/wnd_quickdraw.mm b/src/video/cocoa/wnd_quickdraw.mm --- a/src/video/cocoa/wnd_quickdraw.mm +++ b/src/video/cocoa/wnd_quickdraw.mm @@ -81,10 +81,10 @@ private: void DrawResizeIcon(); virtual void GetDeviceInfo(); - virtual bool SetVideoMode(int width, int height); + virtual bool SetVideoMode(int width, int height, int bpp); public: - WindowQuickdrawSubdriver(int bpp); + WindowQuickdrawSubdriver(); virtual ~WindowQuickdrawSubdriver(); virtual void Draw(bool force_update); @@ -93,7 +93,7 @@ public: virtual uint ListModes(OTTD_Point *modes, uint max_modes); - virtual bool ChangeResolution(int w, int h); + virtual bool ChangeResolution(int w, int h, int bpp); virtual bool IsFullscreen() { return false; } @@ -152,12 +152,12 @@ void WindowQuickdrawSubdriver::GetDevice kCFNumberSInt32Type, &this->device_height); } -bool WindowQuickdrawSubdriver::SetVideoMode(int width, int height) +bool WindowQuickdrawSubdriver::SetVideoMode(int width, int height, int bpp) { this->setup = true; this->GetDeviceInfo(); - if (this->buffer_depth > this->device_depth) { + if (bpp > this->device_depth) { DEBUG(driver, 0, "Cannot use a blitter with a higer screen depth than the display when running in windowed mode."); this->setup = false; return false; @@ -217,6 +217,7 @@ bool WindowQuickdrawSubdriver::SetVideoM /* Update again */ this->window_width = width; this->window_height = height; + this->buffer_depth = bpp; [ this->window center ]; @@ -335,11 +336,11 @@ void WindowQuickdrawSubdriver::DrawResiz } -WindowQuickdrawSubdriver::WindowQuickdrawSubdriver(int bpp) +WindowQuickdrawSubdriver::WindowQuickdrawSubdriver() { this->window_width = 0; this->window_height = 0; - this->buffer_depth = bpp; + this->buffer_depth = 0; this->pixel_buffer = NULL; this->active = false; this->setup = false; @@ -440,14 +441,15 @@ uint WindowQuickdrawSubdriver::ListModes return QZ_ListModes(modes, max_modes, kCGDirectMainDisplay, this->buffer_depth); } -bool WindowQuickdrawSubdriver::ChangeResolution(int w, int h) +bool WindowQuickdrawSubdriver::ChangeResolution(int w, int h, int bpp) { int old_width = this->window_width; int old_height = this->window_height; + int old_bpp = this->buffer_depth; - if (this->SetVideoMode(w, h)) return true; + if (this->SetVideoMode(w, h, bpp)) return true; - if (old_width != 0 && old_height != 0) this->SetVideoMode(old_width, old_height); + if (old_width != 0 && old_height != 0) this->SetVideoMode(old_width, old_height, old_bpp); return false; } @@ -544,9 +546,9 @@ CocoaSubdriver *QZ_CreateWindowQuickdraw return NULL; } - ret = new WindowQuickdrawSubdriver(bpp); + ret = new WindowQuickdrawSubdriver(); - if (!ret->ChangeResolution(width, height)) { + if (!ret->ChangeResolution(width, height, bpp)) { delete ret; return NULL; } diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -635,4 +635,9 @@ bool VideoDriver_SDL::ToggleFullscreen(b return true; } +bool VideoDriver_SDL::AfterBlitterChange() +{ + return this->ChangeResolution(_screen.width, _screen.height) +} + #endif /* WITH_SDL */ diff --git a/src/video/sdl_v.h b/src/video/sdl_v.h --- a/src/video/sdl_v.h +++ b/src/video/sdl_v.h @@ -28,6 +28,9 @@ public: /* virtual */ bool ChangeResolution(int w, int h); /* virtual */ bool ToggleFullscreen(bool fullscreen); + + /* virtual */ bool AfterBlitterChange(); + /* virtual */ const char *GetName() const { return "sdl"; } }; diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -48,6 +48,15 @@ public: virtual bool ToggleFullscreen(bool fullscreen) = 0; /** + * Callback invoked after the blitter was changed. + * @return True if no error. + */ + virtual bool AfterBlitterChange() + { + return true; + } + + /** * Whether the driver has a graphical user interface with the end user. * Or in other words, whether we should spawn a thread for world generation * and NewGRF scanning so the graphical updates can keep coming. Otherwise diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -149,7 +149,7 @@ static uint MapWindowsKey(uint sym) return key; } -static bool AllocateDibSection(int w, int h); +static bool AllocateDibSection(int w, int h, bool force = false); static void ClientSizeChanged(int w, int h) { @@ -690,7 +690,7 @@ static void RegisterWndClass() } } -static bool AllocateDibSection(int w, int h) +static bool AllocateDibSection(int w, int h, bool force) { BITMAPINFO *bi; HDC dc; @@ -701,7 +701,7 @@ static bool AllocateDibSection(int w, in if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals"); - if (w == _screen.width && h == _screen.height) return false; + if (!force && w == _screen.width && h == _screen.height) return false; _screen.width = w; _screen.pitch = (bpp == 8) ? Align(w, 4) : w; @@ -927,3 +927,8 @@ bool VideoDriver_Win32::ToggleFullscreen { return this->MakeWindow(full_screen); } + +bool VideoDriver_Win32::AfterBlitterChange() +{ + return AllocateDibSection(_screen.width, _screen.height, true) && this->MakeWindow(_fullscreen); +} diff --git a/src/video/win32_v.h b/src/video/win32_v.h --- a/src/video/win32_v.h +++ b/src/video/win32_v.h @@ -28,6 +28,9 @@ public: /* virtual */ bool ChangeResolution(int w, int h); /* virtual */ bool ToggleFullscreen(bool fullscreen); + + /* virtual */ bool AfterBlitterChange(); + /* virtual */ const char *GetName() const { return "win32"; } bool MakeWindow(bool full_screen);