diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 935968d735..d89752e085 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1435,15 +1435,15 @@ static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteRead } for (int i = 0; i < numinfo; i++) { - WaterFeature *wf = &_water_feature[id + i]; + CanalProperties *cp = &_cur_grffile->canal_local_properties[id + i]; switch (prop) { case 0x08: - wf->callback_mask = buf->ReadByte(); + cp->callback_mask = buf->ReadByte(); break; case 0x09: - wf->flags = buf->ReadByte(); + cp->flags = buf->ReadByte(); break; default: @@ -7519,6 +7519,17 @@ static void CalculateRefitMasks() } } +/** Set to use the correct action0 properties for each canal feature */ +static void FinaliseCanals() +{ + for (uint i = 0; i < CF_END; i++) { + if (_water_feature[i].grffile != NULL) { + _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask; + _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags; + } + } +} + /** Check for invalid engines */ static void FinaliseEngineArray() { @@ -8204,6 +8215,9 @@ static void AfterLoadGRFs() /* Polish engines */ FinaliseEngineArray(); + /* Set the actually used Canal properties */ + FinaliseCanals(); + /* Set the block size in the depot windows based on vehicle sprite sizes */ InitDepotWindowBlockSizes(); diff --git a/src/newgrf.h b/src/newgrf.h index 014280fc36..82430f6884 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -15,6 +15,27 @@ #include "cargotype.h" #include "rail_type.h" +/** + * List of different canal 'features'. + * Each feature gets an entry in the canal spritegroup table + */ +enum CanalFeature { + CF_WATERSLOPE, + CF_LOCKS, + CF_DIKES, + CF_ICON, + CF_DOCKS, + CF_RIVER_SLOPE, + CF_RIVER_EDGE, + CF_END, +}; + +/** Canal properties local to the NewGRF */ +struct CanalProperties { + uint8 callback_mask; ///< Bitmask of canal callbacks that have to be called. + uint8 flags; ///< Flags controlling display. +}; + enum GrfLoadingStage { GLS_FILESCAN, GLS_SAFETYSCAN, @@ -123,6 +144,8 @@ struct GRFFile { RailTypeLabel *railtype_list; RailType railtype_map[RAILTYPE_END]; + CanalProperties canal_local_properties[CF_END]; ///< Canal properties as set by this NewGRF + struct LanguageMap *language_map; ///< Mappings related to the languages. int traininfo_vehicle_pitch; ///< Vertical offset for draing train images in depot GUI and vehicle details diff --git a/src/newgrf_canal.h b/src/newgrf_canal.h index 1a0dc2cf07..0a2b062d43 100644 --- a/src/newgrf_canal.h +++ b/src/newgrf_canal.h @@ -14,23 +14,9 @@ #include "gfx_type.h" #include "tile_type.h" +#include "newgrf.h" #include "newgrf_generic.h" -/** - * List of different canal 'features'. - * Each feature gets an entry in the canal spritegroup table - */ -enum CanalFeature { - CF_WATERSLOPE, - CF_LOCKS, - CF_DIKES, - CF_ICON, - CF_DOCKS, - CF_RIVER_SLOPE, - CF_RIVER_EDGE, - CF_END, -}; - /** Flags controlling the display of canals. */ enum CanalFeatureFlag { CFF_HAS_FLAT_SPRITE = 0, ///< Additional flat ground sprite in the beginning. diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index f2f28883a1..711f5edec2 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -587,7 +587,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by return v->grf_cache.company_information; case 0x44: // Aircraft information - if (v->type != VEH_AIRCRAFT) return UINT_MAX; + if (v->type != VEH_AIRCRAFT || !Aircraft::From(v)->IsNormalAircraft()) return UINT_MAX; { const Vehicle *w = v->Next(); diff --git a/src/os/macosx/macos.h b/src/os/macosx/macos.h index b30cc8fce9..d147dfb0b0 100644 --- a/src/os/macosx/macos.h +++ b/src/os/macosx/macos.h @@ -29,6 +29,14 @@ #define MAC_OS_X_VERSION_10_6 1060 #endif +#ifndef MAC_OS_X_VERSION_10_7 +#define MAC_OS_X_VERSION_10_7 1070 +#endif + +#ifndef MAC_OS_X_VERSION_10_8 +#define MAC_OS_X_VERSION_10_8 1080 +#endif + /** Helper function displaying a message the best possible way. */ void ShowMacDialog(const char *title, const char *message, const char *button_label); diff --git a/src/string_func.h b/src/string_func.h index 1fb58b46a3..0493c155b6 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -195,7 +195,7 @@ static inline bool IsWhitespace(WChar c) #endif /* strndup is a GNU extension */ -#if defined(_GNU_SOURCE) || (defined(__NetBSD_Version__) && 400000000 <= __NetBSD_Version__) || (defined(__FreeBSD_version) && 701101 <= __FreeBSD_version) +#if defined(_GNU_SOURCE) || (defined(__NetBSD_Version__) && 400000000 <= __NetBSD_Version__) || (defined(__FreeBSD_version) && 701101 <= __FreeBSD_version) || (defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L) # undef DEFINE_STRNDUP #else # define DEFINE_STRNDUP diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 774bdca96d..f777dd67a2 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2166,7 +2166,7 @@ static const NWidgetPart _nested_vehicle_view_widgets[] = { EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHBTN, COLOUR_GREY, VVW_WIDGET_START_STOP_VEH), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 0), SetFill(1, 0), + NWidget(WWT_PUSHBTN, COLOUR_GREY, VVW_WIDGET_START_STOP_VEH), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetResize(1, 0), SetFill(1, 0), NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(), }; diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h index 087b2072c1..498f40cbb8 100644 --- a/src/video/cocoa/cocoa_v.h +++ b/src/video/cocoa/cocoa_v.h @@ -88,6 +88,7 @@ public: virtual bool ChangeResolution(int w, int h) = 0; virtual bool IsFullscreen() = 0; + virtual bool ToggleFullscreen() { return false; }; virtual int GetWidth() = 0; virtual int GetHeight() = 0; virtual void *GetPixelBuffer() = 0; diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index b55e6ee026..4d90ec36c1 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -130,6 +130,11 @@ static void setupWindowMenu() [ menuItem setSubmenu:windowMenu ]; [ [ NSApp mainMenu ] addItem:menuItem ]; + if (MacOSVersionIsAtLeast(10, 7, 0)) { + /* The OS will change the name of this menu item automatically */ + [ windowMenu addItemWithTitle:@"Fullscreen" action:@selector(toggleFullScreen:) keyEquivalent:@"^f" ]; + } + /* Tell the application object that this is now the window menu */ [ NSApp setWindowsMenu:windowMenu ]; @@ -207,23 +212,20 @@ static CocoaSubdriver *QZ_CreateWindowSubdriver(int width, int height, int bpp) CocoaSubdriver *ret; #endif -#ifdef ENABLE_COCOA_QUARTZ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 +#ifdef ENABLE_COCOA_QUARTZ && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) /* The reason for the version mismatch is due to the fact that the 10.4 binary needs to work on 10.5 as well. */ if (MacOSVersionIsAtLeast(10, 5, 0)) { ret = QZ_CreateWindowQuartzSubdriver(width, height, bpp); if (ret != NULL) return ret; } #endif -#endif #ifdef ENABLE_COCOA_QUICKDRAW ret = QZ_CreateWindowQuickdrawSubdriver(width, height, bpp); if (ret != NULL) return ret; #endif -#ifdef ENABLE_COCOA_QUARTZ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 +#ifdef ENABLE_COCOA_QUARTZ && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) /* * If we get here we are running 10.4 or earlier and either openttd was compiled without the QuickDraw driver * or it failed to load for some reason. Fall back to Quartz if possible even though that driver is slower. @@ -232,17 +234,39 @@ static CocoaSubdriver *QZ_CreateWindowSubdriver(int width, int height, int bpp) ret = QZ_CreateWindowQuartzSubdriver(width, height, bpp); if (ret != NULL) return ret; } -#endif #endif return NULL; } +/** + * Find a suitable cocoa subdriver. + * + * @param width Width of display area. + * @param height Height of display area. + * @param bpp Colour depth of display area. + * @param fullscreen Whether a fullscreen mode is requested. + * @param fallback Whether we look for a fallback driver. + * @return Pointer to window subdriver. + */ static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool fullscreen, bool fallback) { - CocoaSubdriver *ret = fullscreen ? QZ_CreateFullscreenSubdriver(width, height, bpp) : QZ_CreateWindowSubdriver(width, height, bpp); - if (ret != NULL) return ret; + CocoaSubdriver *ret = NULL; + /* OSX 10.7 allows to toggle fullscreen mode differently */ + if (MacOSVersionIsAtLeast(10, 7, 0)) { + ret = QZ_CreateWindowSubdriver(width, height, bpp); + } else { + ret = fullscreen ? QZ_CreateFullscreenSubdriver(width, height, bpp) : QZ_CreateWindowSubdriver(width, height, bpp); + } + + if (ret != NULL) { + /* We cannot set any fullscreen mode on OSX 10.7 when not compiled against SDK 10.7 */ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if (fullscreen) { ret->ToggleFullscreen(); } +#endif + return ret; + } if (!fallback) return NULL; @@ -252,10 +276,13 @@ static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool f if (ret != NULL) return ret; #ifdef _DEBUG - /* Try fullscreen too when in debug mode */ - DEBUG(driver, 0, "Setting video mode failed, falling back to 640x480 fullscreen mode."); - ret = QZ_CreateFullscreenSubdriver(640, 480, bpp); - if (ret != NULL) return ret; + /* This Fullscreen mode crashes on OSX 10.7 */ + if !(MacOSVersionIsAtLeast(10, 7, 0) { + /* Try fullscreen too when in debug mode */ + DEBUG(driver, 0, "Setting video mode failed, falling back to 640x480 fullscreen mode."); + ret = QZ_CreateFullscreenSubdriver(640, 480, bpp); + if (ret != NULL) return ret; + } #endif return NULL; @@ -333,6 +360,9 @@ bool VideoDriver_Cocoa::ToggleFullscreen(bool full_screen) { assert(_cocoa_subdriver != NULL); + /* For 10.7 and later, we try to toggle using the quartz subdriver. */ + if (_cocoa_subdriver->ToggleFullscreen()) return true; + bool oldfs = _cocoa_subdriver->IsFullscreen(); if (full_screen != oldfs) { int width = _cocoa_subdriver->GetWidth(); @@ -575,8 +605,8 @@ void cocoaReleaseAutoreleasePool() { NSPoint loc = [ self convertPoint:[ [ self window ] mouseLocationOutsideOfEventStream ] fromView:nil ]; BOOL inside = ([ self hitTest:loc ]==self); - if(inside) [ [ self window] makeFirstResponder:self ]; - trackingtag = [ self addTrackingRect:[self visibleRect] owner:self userData:nil assumeInside:inside ]; + if (inside) [ [ self window ] makeFirstResponder:self ]; + trackingtag = [ self addTrackingRect:[ self visibleRect ] owner:self userData:nil assumeInside:inside ]; } /** * Return responsibility for the application window to system @@ -607,7 +637,7 @@ void cocoaReleaseAutoreleasePool() */ - (void)viewDidMoveToWindow { - if([ self window ]) [ self setTrackingRect ]; + if ([ self window ]) [ self setTrackingRect ]; } /** * Make OpenTTD aware that it has control over the mouse diff --git a/src/video/cocoa/fullscreen.mm b/src/video/cocoa/fullscreen.mm index aa28422d3b..6eea3d64b5 100644 --- a/src/video/cocoa/fullscreen.mm +++ b/src/video/cocoa/fullscreen.mm @@ -309,8 +309,17 @@ class FullscreenSubdriver: public CocoaSubdriver { goto ERR_NO_SWITCH; } - this->window_buffer = CGDisplayBaseAddress(this->display_id); - this->window_pitch = CGDisplayBytesPerRow(this->display_id); + /* Since CGDisplayBaseAddress and CGDisplayBytesPerRow are no longer available on 10.7, + * disable until a replacement can be found. */ + if (MacOSVersionIsAtLeast(10, 7, 0)) { + this->window_buffer = NULL; + this->window_pitch = NULL; + } else { +#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) + this->window_buffer = CGDisplayBaseAddress(this->display_id); + this->window_pitch = CGDisplayBytesPerRow(this->display_id); +#endif + } this->device_width = CGDisplayPixelsWide(this->display_id); this->device_height = CGDisplayPixelsHigh(this->display_id); @@ -565,6 +574,15 @@ public: CocoaSubdriver *QZ_CreateFullscreenSubdriver(int width, int height, int bpp) { + /* OSX 10.7 doesn't support this way of the fullscreen driver. If we end up here + * OpenTTD was compiled without SDK 10.7 available and - and thus we don't support + * fullscreen mode in OSX 10.7 or higher, as necessary elements for this way have + * been removed from the API. + */ + if (MacOSVersionIsAtLeast(10, 7, 0)) { + return NULL; + } + FullscreenSubdriver *ret = new FullscreenSubdriver(bpp); if (!ret->ChangeResolution(width, height)) { diff --git a/src/video/cocoa/wnd_quartz.mm b/src/video/cocoa/wnd_quartz.mm index 0f2b4b0adb..0559b5c409 100644 --- a/src/video/cocoa/wnd_quartz.mm +++ b/src/video/cocoa/wnd_quartz.mm @@ -78,6 +78,7 @@ public: virtual bool ChangeResolution(int w, int h); virtual bool IsFullscreen() { return false; } + virtual bool ToggleFullscreen(); /* Full screen mode on OSX 10.7 */ virtual int GetWidth() { return window_width; } virtual int GetHeight() { return window_height; } @@ -205,10 +206,14 @@ static CGColorSpaceRef QZ_GetCorrectColorSpace() void WindowQuartzSubdriver::GetDeviceInfo() { - /* Initialize the video settings; this data persists between mode switches */ + /* Initialize the video settings; this data persists between mode switches + * and gather some information that is useful to know about the display */ + +# if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 + /* This way is deprecated as of OSX 10.6 but continues to work.Thus use it + * always, unless allowed to skip compatibility with 10.5 and earlier */ CFDictionaryRef cur_mode = CGDisplayCurrentMode(kCGDirectMainDisplay); - /* Gather some information that is useful to know about the display */ CFNumberGetValue( (const __CFNumber*)CFDictionaryGetValue(cur_mode, kCGDisplayWidth), kCFNumberSInt32Type, &this->device_width @@ -218,6 +223,29 @@ void WindowQuartzSubdriver::GetDeviceInfo() (const __CFNumber*)CFDictionaryGetValue(cur_mode, kCGDisplayHeight), kCFNumberSInt32Type, &this->device_height ); +# else + /* Use the new API when compiling for OSX 10.6 or later */ + CGDisplayModeRef cur_mode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); + if (cur_mode == NULL) { return; } + + this->device_width = CGDisplayModeGetWidth(cur_mode); + this->device_height = CGDisplayModeGetHeight(cur_mode); + + CGDisplayModeRelease(cur_mode); +# endif +} + +/** Switch to full screen mode on OSX 10.7 + * @return Whether we switched to full screen + */ +bool WindowQuartzSubdriver::ToggleFullscreen() +{ +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) + [this->window toggleFullScreen:this->window]; + return true; +#else + return false; +#endif } bool WindowQuartzSubdriver::SetVideoMode(int width, int height) @@ -252,6 +280,29 @@ bool WindowQuartzSubdriver::SetVideoMode(int width, int height) return false; } + /* Add built in full-screen support when available (OS X 10.7 and higher) + * This code actually compiles for 10.5 and later, but only makes sense in conjunction + * with the quartz fullscreen support as found only in 10.7 and later + */ +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) + if ([this->window respondsToSelector:@selector(toggleFullScreen:)]) { + /* Constants needed to build on pre-10.7 systems. Source: NSWindow documentation. */ + const int NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7; + const int NSWindowFullScreenButton = 7; + + NSWindowCollectionBehavior behavior = [this->window collectionBehavior]; + behavior |= NSWindowCollectionBehaviorFullScreenPrimary; + [window setCollectionBehavior:behavior]; + + NSButton* fullscreenButton = + [this->window standardWindowButton:NSWindowFullScreenButton]; + [fullscreenButton setAction:@selector(toggleFullScreen:)]; + [fullscreenButton setTarget:this->window]; + + [this->window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary]; + } +#endif + [ this->window setDriver:this ]; char caption[50];