Merge branch 'master' into jgrpp
# Conflicts: # src/os/macosx/macos.mm # src/video/cocoa/cocoa_v.mm # src/video/cocoa/fullscreen.mm # src/video/cocoa/wnd_quartz.mm # src/video/cocoa/wnd_quickdraw.mm
This commit is contained in:
71
config.lib
71
config.lib
@@ -59,7 +59,6 @@ set_default() {
|
|||||||
enable_universal="0"
|
enable_universal="0"
|
||||||
enable_osx_g5="0"
|
enable_osx_g5="0"
|
||||||
enable_cocoa_quartz="1"
|
enable_cocoa_quartz="1"
|
||||||
enable_cocoa_quickdraw="1"
|
|
||||||
with_osx_sysroot="1"
|
with_osx_sysroot="1"
|
||||||
with_application_bundle="1"
|
with_application_bundle="1"
|
||||||
with_menu_entry="1"
|
with_menu_entry="1"
|
||||||
@@ -142,7 +141,6 @@ set_default() {
|
|||||||
enable_universal
|
enable_universal
|
||||||
enable_osx_g5
|
enable_osx_g5
|
||||||
enable_cocoa_quartz
|
enable_cocoa_quartz
|
||||||
enable_cocoa_quickdraw
|
|
||||||
with_osx_sysroot
|
with_osx_sysroot
|
||||||
with_application_bundle
|
with_application_bundle
|
||||||
with_allegro
|
with_allegro
|
||||||
@@ -325,9 +323,6 @@ detect_params() {
|
|||||||
--disable-cocoa-quartz) enable_cocoa_quartz="0";;
|
--disable-cocoa-quartz) enable_cocoa_quartz="0";;
|
||||||
--enable-cocoa-quartz) enable_cocoa_quartz="2";;
|
--enable-cocoa-quartz) enable_cocoa_quartz="2";;
|
||||||
--enable-cocoa-quartz=*) enable_cocoa_quartz="$optarg";;
|
--enable-cocoa-quartz=*) enable_cocoa_quartz="$optarg";;
|
||||||
--disable-cocoa-quickdraw) enable_cocoa_quickdraw="0";;
|
|
||||||
--enable-cocoa-quickdraw) enable_cocoa_quickdraw="2";;
|
|
||||||
--enable-cocoa-quickdraw=*) enable_cocoa_quickdraw="$optarg";;
|
|
||||||
|
|
||||||
--with-allegro) with_allegro="2";;
|
--with-allegro) with_allegro="2";;
|
||||||
--without-allegro) with_allegro="0";;
|
--without-allegro) with_allegro="0";;
|
||||||
@@ -1972,12 +1967,6 @@ EOL
|
|||||||
# Add macports include dir which is not always set a default system dir. This avoids zillions of bogus warnings.
|
# Add macports include dir which is not always set a default system dir. This avoids zillions of bogus warnings.
|
||||||
CFLAGS="$CFLAGS -isystem/opt/local/include"
|
CFLAGS="$CFLAGS -isystem/opt/local/include"
|
||||||
|
|
||||||
if [ "$enable_dedicated" = "0" ] && ([ "$cpu_type" = "32" ] || [ "$enable_universal" != "0" ]); then
|
|
||||||
LIBS="$LIBS -framework QuickTime"
|
|
||||||
else
|
|
||||||
CFLAGS="$CFLAGS -DNO_QUICKTIME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$enable_universal" = "0" ]; then
|
if [ "$enable_universal" = "0" ]; then
|
||||||
# Universal builds set this elsewhere
|
# Universal builds set this elsewhere
|
||||||
CFLAGS="$OSX_SYSROOT $CFLAGS"
|
CFLAGS="$OSX_SYSROOT $CFLAGS"
|
||||||
@@ -2074,15 +2063,11 @@ EOL
|
|||||||
|
|
||||||
if [ "$with_cocoa" != "0" ]; then
|
if [ "$with_cocoa" != "0" ]; then
|
||||||
CFLAGS="$CFLAGS -DWITH_COCOA"
|
CFLAGS="$CFLAGS -DWITH_COCOA"
|
||||||
LIBS="$LIBS -F/System/Library/Frameworks -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox"
|
LIBS="$LIBS -F$osx_sdk_path/System/Library/Frameworks -framework Cocoa -framework AudioUnit -framework AudioToolbox"
|
||||||
|
|
||||||
if [ "$enable_cocoa_quartz" != "0" ]; then
|
if [ "$enable_cocoa_quartz" != "0" ]; then
|
||||||
CFLAGS="$CFLAGS -DENABLE_COCOA_QUARTZ"
|
CFLAGS="$CFLAGS -DENABLE_COCOA_QUARTZ"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$enable_cocoa_quickdraw" != "0" ]; then
|
|
||||||
CFLAGS="$CFLAGS -DENABLE_COCOA_QUICKDRAW"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$with_zlib" != "0" ]; then
|
if [ "$with_zlib" != "0" ]; then
|
||||||
@@ -3016,56 +3001,6 @@ detect_cocoa() {
|
|||||||
else
|
else
|
||||||
log 1 "checking whether to enable the Quartz window subdriver... no"
|
log 1 "checking whether to enable the Quartz window subdriver... no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
detect_quickdraw
|
|
||||||
}
|
|
||||||
|
|
||||||
detect_quickdraw() {
|
|
||||||
# 0 means no, 1 is auto-detect, 2 is force
|
|
||||||
if [ "$enable_cocoa_quickdraw" = "0" ]; then
|
|
||||||
log 1 "checking Quickdraw window subdriver... disabled"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Assume QuickDraw is available when doing an universal build
|
|
||||||
if [ "$enable_universal" != "0" ]; then
|
|
||||||
log 1 "checking Quickdraw window subdriver... found"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 64 bits doesn't have quickdraw
|
|
||||||
if [ "$cpu_type" = "64" ]; then
|
|
||||||
enable_cocoa_quickdraw="0"
|
|
||||||
log 1 "checking Quickdraw window subdriver... disabled (64 bits)"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat > tmp.osx.mm << EOF
|
|
||||||
#include <AvailabilityMacros.h>
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
int main(int argc, char *argv[]) { SetEmptyRgn(NULL); return 0; }
|
|
||||||
EOF
|
|
||||||
execute="$cxx_host $OSX_SYSROOT $OSX_LD_SYSROOT $CFLAGS -mmacosx-version-min=10.3 tmp.osx.mm -framework Cocoa -o tmp.osx 2>&1"
|
|
||||||
eval $execute > /dev/null
|
|
||||||
ret=$?
|
|
||||||
log 2 "executing $execute"
|
|
||||||
log 2 " exit code $ret"
|
|
||||||
rm -f tmp.osx.mm tmp.osx
|
|
||||||
if [ "$ret" != "0" ]; then
|
|
||||||
log 1 "checking Quickdraw window subdriver... not found"
|
|
||||||
|
|
||||||
# It was forced, so it should be found.
|
|
||||||
if [ "$enable_cocoa_quickdraw" != "1" ]; then
|
|
||||||
log 1 "configure: error: Quickdraw window driver could not be found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
enable_cocoa_quickdraw=0
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
enable_cocoa_quickdraw=1
|
|
||||||
log 1 "checking Quickdraw window subdriver... found"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
detect_library() {
|
detect_library() {
|
||||||
@@ -3918,8 +3853,7 @@ generate_src_osx() {
|
|||||||
CFLAGS="-isysroot $osx_sdk_path $CFLAGS_orig"
|
CFLAGS="-isysroot $osx_sdk_path $CFLAGS_orig"
|
||||||
LDFLAGS="-Wl,-syslibroot,$osx_sdk_path $LDFLAGS_orig"
|
LDFLAGS="-Wl,-syslibroot,$osx_sdk_path $LDFLAGS_orig"
|
||||||
fi
|
fi
|
||||||
CFLAGS="$CFLAGS -D_SQ64 -DNO_QUICKTIME -UENABLE_COCOA_QUICKDRAW"
|
CFLAGS="$CFLAGS -D_SQ64"
|
||||||
LIBS="`echo $LIBS | sed 's/-framework QuickTime//'`"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
case $type in
|
case $type in
|
||||||
@@ -4034,7 +3968,6 @@ showhelp() {
|
|||||||
echo " Default architectures are: i386 ppc"
|
echo " Default architectures are: i386 ppc"
|
||||||
echo " --enable-osx-g5 enables optimizations for ppc970 (G5) (OSX ONLY)"
|
echo " --enable-osx-g5 enables optimizations for ppc970 (G5) (OSX ONLY)"
|
||||||
echo " --disable-cocoa-quartz disable the quartz window mode driver for Cocoa (OSX ONLY)"
|
echo " --disable-cocoa-quartz disable the quartz window mode driver for Cocoa (OSX ONLY)"
|
||||||
echo " --disable-cocoa-quickdraw disable the quickdraw window mode driver for Cocoa (OSX ONLY)"
|
|
||||||
echo " --disable-unicode disable unicode support to build win9x"
|
echo " --disable-unicode disable unicode support to build win9x"
|
||||||
echo " version (Win32 ONLY)"
|
echo " version (Win32 ONLY)"
|
||||||
echo " --enable-console compile as a console application instead of as a GUI application."
|
echo " --enable-console compile as a console application instead of as a GUI application."
|
||||||
|
@@ -448,7 +448,6 @@ zoning.h
|
|||||||
music/extmidi.h
|
music/extmidi.h
|
||||||
music/fluidsynth.h
|
music/fluidsynth.h
|
||||||
music/os2_m.h
|
music/os2_m.h
|
||||||
music/qtmidi.h
|
|
||||||
os/macosx/macos.h
|
os/macosx/macos.h
|
||||||
os/macosx/osx_stdafx.h
|
os/macosx/osx_stdafx.h
|
||||||
os/macosx/splash.h
|
os/macosx/splash.h
|
||||||
@@ -1220,17 +1219,10 @@ sound/null_s.cpp
|
|||||||
# OSX Files
|
# OSX Files
|
||||||
os/macosx/macos.mm
|
os/macosx/macos.mm
|
||||||
|
|
||||||
#if DEDICATED
|
|
||||||
#else
|
|
||||||
music/qtmidi.cpp
|
|
||||||
#end
|
|
||||||
|
|
||||||
#if COCOA
|
#if COCOA
|
||||||
video/cocoa/cocoa_v.mm
|
video/cocoa/cocoa_v.mm
|
||||||
video/cocoa/event.mm
|
video/cocoa/event.mm
|
||||||
video/cocoa/fullscreen.mm
|
|
||||||
video/cocoa/wnd_quartz.mm
|
video/cocoa/wnd_quartz.mm
|
||||||
video/cocoa/wnd_quickdraw.mm
|
|
||||||
music/cocoa_m.cpp
|
music/cocoa_m.cpp
|
||||||
sound/cocoa_s.cpp
|
sound/cocoa_s.cpp
|
||||||
os/macosx/splash.cpp
|
os/macosx/splash.cpp
|
||||||
|
@@ -16,9 +16,6 @@
|
|||||||
#include "../core/string_compare_type.hpp"
|
#include "../core/string_compare_type.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#if defined(WITH_COCOA)
|
|
||||||
bool QZ_CanDisplay8bpp();
|
|
||||||
#endif /* defined(WITH_COCOA) */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base factory, keeping track of all blitters.
|
* The base factory, keeping track of all blitters.
|
||||||
@@ -113,19 +110,11 @@ public:
|
|||||||
{
|
{
|
||||||
#if defined(DEDICATED)
|
#if defined(DEDICATED)
|
||||||
const char *default_blitter = "null";
|
const char *default_blitter = "null";
|
||||||
|
#elif defined(WITH_COCOA)
|
||||||
|
const char *default_blitter = "32bpp-anim";
|
||||||
#else
|
#else
|
||||||
const char *default_blitter = "8bpp-optimized";
|
const char *default_blitter = "8bpp-optimized";
|
||||||
|
#endif
|
||||||
#if defined(WITH_COCOA)
|
|
||||||
/* Some people reported lack of fullscreen support in 8 bpp mode.
|
|
||||||
* While we prefer 8 bpp since it's faster, we will still have to test for support. */
|
|
||||||
if (!QZ_CanDisplay8bpp()) {
|
|
||||||
/* The main display can't go to 8 bpp fullscreen mode.
|
|
||||||
* We will have to switch to 32 bpp by default. */
|
|
||||||
default_blitter = "32bpp-anim";
|
|
||||||
}
|
|
||||||
#endif /* defined(WITH_COCOA) */
|
|
||||||
#endif /* defined(DEDICATED) */
|
|
||||||
if (GetBlitters().size() == 0) return nullptr;
|
if (GetBlitters().size() == 0) return nullptr;
|
||||||
const char *bname = (StrEmpty(name)) ? default_blitter : name;
|
const char *bname = (StrEmpty(name)) ? default_blitter : name;
|
||||||
|
|
||||||
|
@@ -394,8 +394,6 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||||||
OSStatus os_err = -1;
|
OSStatus os_err = -1;
|
||||||
CFAutoRelease<CFStringRef> name(CFStringCreateWithCString(kCFAllocatorDefault, font_name, kCFStringEncodingUTF8));
|
CFAutoRelease<CFStringRef> name(CFStringCreateWithCString(kCFAllocatorDefault, font_name, kCFStringEncodingUTF8));
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 6, 0)) {
|
|
||||||
/* Simply creating the font using CTFontCreateWithNameAndSize will *always* return
|
/* Simply creating the font using CTFontCreateWithNameAndSize will *always* return
|
||||||
* something, no matter the name. As such, we can't use it to check for existence.
|
* something, no matter the name. As such, we can't use it to check for existence.
|
||||||
* We instead query the list of all font descriptors that match the given name which
|
* We instead query the list of all font descriptors that match the given name which
|
||||||
@@ -410,36 +408,6 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||||||
CFAutoRelease<CFURLRef> fontURL((CFURLRef)CTFontCopyAttribute(font.get(), kCTFontURLAttribute));
|
CFAutoRelease<CFURLRef> fontURL((CFURLRef)CTFontCopyAttribute(font.get(), kCTFontURLAttribute));
|
||||||
if (CFURLGetFileSystemRepresentation(fontURL.get(), true, file_path, lengthof(file_path))) os_err = noErr;
|
if (CFURLGetFileSystemRepresentation(fontURL.get(), true, file_path, lengthof(file_path))) os_err = noErr;
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6)
|
|
||||||
ATSFontRef font = ATSFontFindFromName(name.get(), kATSOptionFlagsDefault);
|
|
||||||
if (font == kInvalidFont) return err;
|
|
||||||
|
|
||||||
/* Get a file system reference for the font. */
|
|
||||||
FSRef ref;
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 5, 0)) {
|
|
||||||
os_err = ATSFontGetFileReference(font, &ref);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) && !defined(__LP64__)
|
|
||||||
/* This type was introduced with the 10.5 SDK. */
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
|
|
||||||
#define ATSFSSpec FSSpec
|
|
||||||
#endif
|
|
||||||
FSSpec spec;
|
|
||||||
os_err = ATSFontGetFileSpecification(font, (ATSFSSpec *)&spec);
|
|
||||||
if (os_err == noErr) os_err = FSpMakeFSRef(&spec, &ref);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get unix path for file. */
|
|
||||||
if (os_err == noErr) os_err = FSRefMakePath(&ref, file_path, sizeof(file_path));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (os_err == noErr) {
|
if (os_err == noErr) {
|
||||||
DEBUG(freetype, 3, "Font path for %s: %s", font_name, file_path);
|
DEBUG(freetype, 3, "Font path for %s: %s", font_name, file_path);
|
||||||
@@ -451,10 +419,6 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||||||
|
|
||||||
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
|
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
|
||||||
{
|
{
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 5, 0)) {
|
|
||||||
/* Determine fallback font using CoreText. This uses the language isocode
|
/* Determine fallback font using CoreText. This uses the language isocode
|
||||||
* to find a suitable font. CoreText is available from 10.5 onwards. */
|
* to find a suitable font. CoreText is available from 10.5 onwards. */
|
||||||
char lang[16];
|
char lang[16];
|
||||||
@@ -486,6 +450,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
|
|||||||
CFAutoRelease<CFSetRef> mandatory_attribs(CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontLanguagesAttribute, 1, &kCFTypeSetCallBacks));
|
CFAutoRelease<CFSetRef> mandatory_attribs(CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontLanguagesAttribute, 1, &kCFTypeSetCallBacks));
|
||||||
CFAutoRelease<CFArrayRef> descs(CTFontDescriptorCreateMatchingFontDescriptors(lang_desc.get(), mandatory_attribs.get()));
|
CFAutoRelease<CFArrayRef> descs(CTFontDescriptorCreateMatchingFontDescriptors(lang_desc.get(), mandatory_attribs.get()));
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
for (CFIndex i = 0; descs.get() != nullptr && i < CFArrayGetCount(descs.get()); i++) {
|
for (CFIndex i = 0; descs.get() != nullptr && i < CFArrayGetCount(descs.get()); i++) {
|
||||||
CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), i);
|
CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), i);
|
||||||
|
|
||||||
@@ -518,45 +483,6 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6)
|
|
||||||
/* Create a font iterator and iterate over all fonts that
|
|
||||||
* are available to the application. */
|
|
||||||
ATSFontIterator itr;
|
|
||||||
ATSFontRef font;
|
|
||||||
ATSFontIteratorCreate(kATSFontContextLocal, nullptr, nullptr, kATSOptionFlagsDefaultScope, &itr);
|
|
||||||
while (!result && ATSFontIteratorNext(itr, &font) == noErr) {
|
|
||||||
/* Get font name. */
|
|
||||||
char name[128];
|
|
||||||
CFStringRef font_name;
|
|
||||||
ATSFontGetName(font, kATSOptionFlagsDefault, &font_name);
|
|
||||||
CFStringGetCString(font_name, name, lengthof(name), kCFStringEncodingUTF8);
|
|
||||||
|
|
||||||
bool monospace = IsMonospaceFont(font_name);
|
|
||||||
CFRelease(font_name);
|
|
||||||
|
|
||||||
/* Select monospaced fonts if asked for. */
|
|
||||||
if (monospace != callback->Monospace()) continue;
|
|
||||||
|
|
||||||
/* We only want the base font and not bold or italic variants. */
|
|
||||||
if (strstr(name, "Italic") != nullptr || strstr(name, "Bold")) continue;
|
|
||||||
|
|
||||||
/* Skip some inappropriate or ugly looking fonts that have better alternatives. */
|
|
||||||
if (name[0] == '.' || strncmp(name, "Apple Symbols", 13) == 0 || strncmp(name, "LastResort", 10) == 0) continue;
|
|
||||||
|
|
||||||
/* Save result. */
|
|
||||||
callback->SetFontNames(settings, name);
|
|
||||||
if (!callback->FindMissingGlyphs(nullptr)) {
|
|
||||||
DEBUG(freetype, 2, "ATS-Font for %s: %s", language_isocode, name);
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ATSFontIteratorRelease(&itr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
/* For some OS versions, the font 'Arial Unicode MS' does not report all languages it
|
/* For some OS versions, the font 'Arial Unicode MS' does not report all languages it
|
||||||
|
@@ -235,6 +235,7 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Select f
|
|||||||
STR_BUTTON_SORT_BY :{BLACK}Sort by
|
STR_BUTTON_SORT_BY :{BLACK}Sort by
|
||||||
STR_BUTTON_LOCATION :{BLACK}Location
|
STR_BUTTON_LOCATION :{BLACK}Location
|
||||||
STR_BUTTON_RENAME :{BLACK}Rename
|
STR_BUTTON_RENAME :{BLACK}Rename
|
||||||
|
STR_TOOLTIP_CATCHMENT :{BLACK}தழுவு பகுதி காட்சியை நிலைமாற்று
|
||||||
|
|
||||||
STR_TOOLTIP_CLOSE_WINDOW :{BLACK}சாளரத்தை மூடு
|
STR_TOOLTIP_CLOSE_WINDOW :{BLACK}சாளரத்தை மூடு
|
||||||
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}சாளர தலைப்பு - சாளரத்தை நகர்த்த இழுக்கவும்
|
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}சாளர தலைப்பு - சாளரத்தை நகர்த்த இழுக்கவும்
|
||||||
@@ -817,6 +818,7 @@ STR_NEWS_VEHICLE_HAS_TOO_FEW_ORDERS :{WHITE}{VEHICLE
|
|||||||
STR_NEWS_VEHICLE_HAS_VOID_ORDER :{WHITE}{VEHICLE} பிழையான கட்டளையைக் கொண்டுள்ளது
|
STR_NEWS_VEHICLE_HAS_VOID_ORDER :{WHITE}{VEHICLE} பிழையான கட்டளையைக் கொண்டுள்ளது
|
||||||
STR_NEWS_VEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}{VEHICLE} இரட்டடிப்பு கட்டளைகளைக் கொண்டுள்ளது
|
STR_NEWS_VEHICLE_HAS_DUPLICATE_ENTRY :{WHITE}{VEHICLE} இரட்டடிப்பு கட்டளைகளைக் கொண்டுள்ளது
|
||||||
STR_NEWS_VEHICLE_HAS_INVALID_ENTRY :{WHITE}{VEHICLE} பிழையான நிலையத்தினை கட்டளைகளில் கொண்டுள்ளது
|
STR_NEWS_VEHICLE_HAS_INVALID_ENTRY :{WHITE}{VEHICLE} பிழையான நிலையத்தினை கட்டளைகளில் கொண்டுள்ளது
|
||||||
|
STR_NEWS_PLANE_USES_TOO_SHORT_RUNWAY :{WHITE}{VEHICLE} அதன் ஆர்டர்களில் ஓடுபாதை மிகக் குறுகியதாக இருக்கும் விமான நிலையத்தைக் கொண்டுள்ளது
|
||||||
|
|
||||||
STR_NEWS_VEHICLE_IS_GETTING_OLD :{WHITE}{VEHICLE} பழையதாகிறது
|
STR_NEWS_VEHICLE_IS_GETTING_OLD :{WHITE}{VEHICLE} பழையதாகிறது
|
||||||
STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD :{WHITE}{VEHICLE} பழையதாகிறது
|
STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD :{WHITE}{VEHICLE} பழையதாகிறது
|
||||||
@@ -1359,6 +1361,7 @@ STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE :சரக்க
|
|||||||
STR_CONFIG_SETTING_NEWS_SUBSIDIES :மானியங்கள்: {STRING}
|
STR_CONFIG_SETTING_NEWS_SUBSIDIES :மானியங்கள்: {STRING}
|
||||||
STR_CONFIG_SETTING_NEWS_SUBSIDIES_HELPTEXT :மானியம் தொடர்பான நிகழ்வுகள் பற்றி செய்தித்தாளினைக் காட்டவும்
|
STR_CONFIG_SETTING_NEWS_SUBSIDIES_HELPTEXT :மானியம் தொடர்பான நிகழ்வுகள் பற்றி செய்தித்தாளினைக் காட்டவும்
|
||||||
STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION :பொதுவான விவரம்: {STRING}
|
STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION :பொதுவான விவரம்: {STRING}
|
||||||
|
STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT :பிரத்தியேக உரிமைகள் வாங்குதல் அல்லது சாலை புனரமைப்புக்கு நிதியளித்தல் போன்ற பொதுவான நிகழ்வுகளைப் பற்றி செய்தித்தாளைக் காண்பி
|
||||||
|
|
||||||
STR_CONFIG_SETTING_NEWS_MESSAGES_OFF :நிறுத்து
|
STR_CONFIG_SETTING_NEWS_MESSAGES_OFF :நிறுத்து
|
||||||
STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY :தொகுப்பு
|
STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY :தொகுப்பு
|
||||||
@@ -1394,6 +1397,7 @@ STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :நகரங்
|
|||||||
STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :நகரங்கள் சாலைச் சந்திப்புகளை கட்ட அனுமதி: {STRING}
|
STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :நகரங்கள் சாலைச் சந்திப்புகளை கட்ட அனுமதி: {STRING}
|
||||||
STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :இந்த அமைப்பு நகராட்சிகள் இருப்புப்பாதை சந்திக் கடவுகளைக் கட்ட அனுமதிக்கும்
|
STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :இந்த அமைப்பு நகராட்சிகள் இருப்புப்பாதை சந்திக் கடவுகளைக் கட்ட அனுமதிக்கும்
|
||||||
STR_CONFIG_SETTING_NOISE_LEVEL :விமான நிலையங்களுக்கு நகராட்சியால் நிர்ணயிக்கப்பட்ட இரைச்சல் அளவினை அனுமதிக்கவும்: {STRING}
|
STR_CONFIG_SETTING_NOISE_LEVEL :விமான நிலையங்களுக்கு நகராட்சியால் நிர்ணயிக்கப்பட்ட இரைச்சல் அளவினை அனுமதிக்கவும்: {STRING}
|
||||||
|
STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :இந்த அமைப்பு முடக்கப்பட்டுள்ளதால், ஒவ்வொரு ஊரிலும் இரண்டு விமான நிலையங்கள் இருக்கலாம். இந்த அமைப்பு இயக்கப்பட்டவுடன், ஒரு நகரத்தின் விமான நிலையங்களின் எண்ணிக்கை நகரத்தின் சத்தத்தை ஏற்றுக்கொள்வதன் மூலம் வரையறுக்கப்படுகிறது, இது மக்கள் தொகை மற்றும் விமான நிலைய அளவு மற்றும் தூரத்தைப் பொறுத்தது
|
||||||
STR_CONFIG_SETTING_TOWN_FOUNDING :ஆட்டத்தில் நகரங்களை நிறுவ அனுமதி: {STRING}
|
STR_CONFIG_SETTING_TOWN_FOUNDING :ஆட்டத்தில் நகரங்களை நிறுவ அனுமதி: {STRING}
|
||||||
STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :இந்த அமைப்பு விளியாடுபவர்கள் ஆட்டத்தில் புதிய நகரங்களை நிறுவ அனுமதிக்கும்
|
STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :இந்த அமைப்பு விளியாடுபவர்கள் ஆட்டத்தில் புதிய நகரங்களை நிறுவ அனுமதிக்கும்
|
||||||
STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :இயலாது
|
STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :இயலாது
|
||||||
@@ -1541,6 +1545,7 @@ STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}பத
|
|||||||
STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}புதிய ஆட்டத்தினைத் தொடங்கு, உயர்படத்தினை நிலப்பரப்பிற்கு பயன்படுத்தி
|
STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}புதிய ஆட்டத்தினைத் தொடங்கு, உயர்படத்தினை நிலப்பரப்பிற்கு பயன்படுத்தி
|
||||||
STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}புதிய பல்வீரர் ஆட்டத்தினைத் தொடங்கவும்
|
STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}புதிய பல்வீரர் ஆட்டத்தினைத் தொடங்கவும்
|
||||||
|
|
||||||
|
STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}'வெப்பமண்டல' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும்
|
||||||
STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}'உபதுருவ' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும்
|
STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}'உபதுருவ' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும்
|
||||||
STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}'மிதவெப்பமண்டல' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும்
|
STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}'மிதவெப்பமண்டல' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும்
|
||||||
STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}'பொம்மைநில' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும்
|
STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}'பொம்மைநில' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும்
|
||||||
@@ -2016,11 +2021,13 @@ STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE :{WHITE}... க
|
|||||||
STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}பதிவிறக்கம் செய்யப்பட்ட கோப்பினை விரிவாக்க முடியவில்லை
|
STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}பதிவிறக்கம் செய்யப்பட்ட கோப்பினை விரிவாக்க முடியவில்லை
|
||||||
|
|
||||||
STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}அசைவூட்டங்கள் இல்லை
|
STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}அசைவூட்டங்கள் இல்லை
|
||||||
|
STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD க்கு கிராபிக்ஸ் செயல்பட வேண்டும், ஆனால் எதுவும் கண்டுபிடிக்கப்படவில்லை. இந்த கிராபிக்ஸ் பதிவிறக்கம் செய்து நிறுவ OpenTTD ஐ அனுமதிக்கிறீர்களா?
|
||||||
STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}ஆம், அசையூட்டங்களை பதிவிறக்கம் செய்
|
STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}ஆம், அசையூட்டங்களை பதிவிறக்கம் செய்
|
||||||
STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}இல்லை, OpenTTD-ஐ விட்டு வெளியேறு
|
STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}இல்லை, OpenTTD-ஐ விட்டு வெளியேறு
|
||||||
|
|
||||||
# Transparency settings window
|
# Transparency settings window
|
||||||
STR_TRANSPARENCY_CAPTION :{WHITE}ஒளி அமைப்புகள்
|
STR_TRANSPARENCY_CAPTION :{WHITE}ஒளி அமைப்புகள்
|
||||||
|
STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}வீடுகளுக்கான வெளிப்படைத்தன்மையை நிலைமாற்று. Ctrl + கிளிக் பூட்ட செய்க
|
||||||
|
|
||||||
# Linkgraph legend window
|
# Linkgraph legend window
|
||||||
STR_LINKGRAPH_LEGEND_ALL :{BLACK}அனைத்தும்
|
STR_LINKGRAPH_LEGEND_ALL :{BLACK}அனைத்தும்
|
||||||
@@ -2129,6 +2136,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}ட்
|
|||||||
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}சாலை கட்டுமானம் செய்யவும்/நீக்கவும்
|
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}சாலை கட்டுமானம் செய்யவும்/நீக்கவும்
|
||||||
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}ட்ராம்வே கட்டுமானம் செய்யவும்/நீக்கவும்
|
STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}ட்ராம்வே கட்டுமானம் செய்யவும்/நீக்கவும்
|
||||||
|
|
||||||
|
STR_ROAD_NAME_ROAD :சாலை
|
||||||
|
|
||||||
# Road depot construction window
|
# Road depot construction window
|
||||||
STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}சாலை வாகன பணிமனை திசையமைப்பு
|
STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}சாலை வாகன பணிமனை திசையமைப்பு
|
||||||
@@ -2616,6 +2624,7 @@ STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} இ
|
|||||||
STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF கோப்பு மொழிபெயர்க்க வடிமைக்கப்பட்டது
|
STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF கோப்பு மொழிபெயர்க்க வடிமைக்கப்பட்டது
|
||||||
STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :அளவிற்கு அதிகமான NewGRF கள் ஏற்றப்பட்டுள்ளன
|
STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :அளவிற்கு அதிகமான NewGRF கள் ஏற்றப்பட்டுள்ளன
|
||||||
STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :எதிர்பார்க்கப்படாத ஸ்பிரைட்டு(ஸ்பிரைட்டு {3:NUM})
|
STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :எதிர்பார்க்கப்படாத ஸ்பிரைட்டு(ஸ்பிரைட்டு {3:NUM})
|
||||||
|
STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :பல அதிரடி 8 உள்ளீடுகளைக் கொண்டுள்ளது (ஸ்பிரிட் {3:NUM})
|
||||||
STR_NEWGRF_ERROR_GRM_FAILED :கேட்கப்பட்ட GRF கள் கிடைக்கவில்லை (ஸ்பிரைட்டு {3:NUM})
|
STR_NEWGRF_ERROR_GRM_FAILED :கேட்கப்பட்ட GRF கள் கிடைக்கவில்லை (ஸ்பிரைட்டு {3:NUM})
|
||||||
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING}, {STRING}ஆல் செயலிழக்க செய்யப்பட்டது
|
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING}, {STRING}ஆல் செயலிழக்க செய்யப்பட்டது
|
||||||
|
|
||||||
@@ -2827,6 +2836,8 @@ STR_STATION_VIEW_TO_HERE :{GREEN}{CARGO_S
|
|||||||
STR_STATION_VIEW_NONSTOP :{YELLOW}{CARGO_SHORT} எங்கும் நிற்காமல்
|
STR_STATION_VIEW_NONSTOP :{YELLOW}{CARGO_SHORT} எங்கும் நிற்காமல்
|
||||||
|
|
||||||
STR_STATION_VIEW_GROUP_S_V_D :மூலம்-வழியாக-சேருமிடம்
|
STR_STATION_VIEW_GROUP_S_V_D :மூலம்-வழியாக-சேருமிடம்
|
||||||
|
STR_STATION_VIEW_GROUP_S_D_V :மூல-சேருமிடம்-வழியாக
|
||||||
|
STR_STATION_VIEW_GROUP_D_V_S :மூல-வழியாக-இலக்கு
|
||||||
|
|
||||||
############ range for rating starts
|
############ range for rating starts
|
||||||
STR_CARGO_RATING_APPALLING :மட்டம்
|
STR_CARGO_RATING_APPALLING :மட்டம்
|
||||||
@@ -2839,6 +2850,7 @@ STR_CARGO_RATING_EXCELLENT :சிறப்
|
|||||||
STR_CARGO_RATING_OUTSTANDING :மிகச்சிறப்பு
|
STR_CARGO_RATING_OUTSTANDING :மிகச்சிறப்பு
|
||||||
############ range for rating ends
|
############ range for rating ends
|
||||||
|
|
||||||
|
STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}நிலைய இருப்பிடத்தின் மையக் காட்சி. Ctrl + Click நிலைய இருப்பிடத்தில் புதிய காட்சிப்பலகையைத் திறக்கிறது
|
||||||
STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}நிலையத்தின் பெயரை மாற்று
|
STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}நிலையத்தின் பெயரை மாற்று
|
||||||
|
|
||||||
STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}இந்த நிலையத்தினை அட்டவணையில் வைத்துள்ள அனைத்து இரயில்களையும் காட்டு
|
STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}இந்த நிலையத்தினை அட்டவணையில் வைத்துள்ள அனைத்து இரயில்களையும் காட்டு
|
||||||
@@ -3092,6 +3104,7 @@ STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}வி
|
|||||||
STR_BUY_VEHICLE_AIRCRAFT_HIDE_TOGGLE_BUTTON :{BLACK}மறை
|
STR_BUY_VEHICLE_AIRCRAFT_HIDE_TOGGLE_BUTTON :{BLACK}மறை
|
||||||
|
|
||||||
STR_BUY_VEHICLE_ROAD_VEHICLE_SHOW_TOGGLE_BUTTON :{BLACK}காட்சி
|
STR_BUY_VEHICLE_ROAD_VEHICLE_SHOW_TOGGLE_BUTTON :{BLACK}காட்சி
|
||||||
|
STR_BUY_VEHICLE_SHIP_SHOW_TOGGLE_BUTTON :{BLACK}காட்சி
|
||||||
|
|
||||||
STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}கப்பல் வகையினை காட்டு/மறை
|
STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}கப்பல் வகையினை காட்டு/மறை
|
||||||
|
|
||||||
@@ -3207,6 +3220,7 @@ STR_REPLACE_VEHICLES_STOP :{BLACK}வா
|
|||||||
STR_REPLACE_ENGINES :பொறிகள்
|
STR_REPLACE_ENGINES :பொறிகள்
|
||||||
STR_REPLACE_WAGONS :வாகனங்கள்
|
STR_REPLACE_WAGONS :வாகனங்கள்
|
||||||
|
|
||||||
|
STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}இடது தேர்ந்தெடுக்கப்பட்ட இயந்திரம் ஏதேனும் இருந்தால் மாற்றப்படும் எந்த இயந்திரத்தைக் காட்டுகிறது
|
||||||
STR_REPLACE_RAIL_VEHICLES :இரயில் வாகனங்கள்
|
STR_REPLACE_RAIL_VEHICLES :இரயில் வாகனங்கள்
|
||||||
STR_REPLACE_ELRAIL_VEHICLES :மின்சார இரயில் வாகனங்கள்
|
STR_REPLACE_ELRAIL_VEHICLES :மின்சார இரயில் வாகனங்கள்
|
||||||
STR_REPLACE_MONORAIL_VEHICLES :மோனோ இரயில் வாகனங்கள்
|
STR_REPLACE_MONORAIL_VEHICLES :மோனோ இரயில் வாகனங்கள்
|
||||||
@@ -3586,6 +3600,7 @@ STR_AI_DEBUG_SETTINGS :{BLACK}அம
|
|||||||
STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}வரிவடிவத்தின் அமைப்புகளை மாற்று
|
STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}வரிவடிவத்தின் அமைப்புகளை மாற்று
|
||||||
STR_AI_DEBUG_RELOAD :{BLACK}AI-ஐ மறுபடியும் ஏற்று
|
STR_AI_DEBUG_RELOAD :{BLACK}AI-ஐ மறுபடியும் ஏற்று
|
||||||
STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}AI இனை நிறுத்தவும், வரிவடிவத்தினை திருப்பி ஏற்றவும், மேலும் AI இனை மீண்டும் தொடங்கவும்
|
STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}AI இனை நிறுத்தவும், வரிவடிவத்தினை திருப்பி ஏற்றவும், மேலும் AI இனை மீண்டும் தொடங்கவும்
|
||||||
|
STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}AI பதிவு செய்தி இடைவெளி சரத்துடன் பொருந்தும்போது உடைப்பதை இயக்கவும் / முடக்கவும்
|
||||||
STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}உடைத்து ஆம்:
|
STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}உடைத்து ஆம்:
|
||||||
STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}உடைத்து ஆம்
|
STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}உடைத்து ஆம்
|
||||||
STR_AI_DEBUG_MATCH_CASE :{BLACK}case இனை சரிபடுத்தவும்
|
STR_AI_DEBUG_MATCH_CASE :{BLACK}case இனை சரிபடுத்தவும்
|
||||||
@@ -3636,6 +3651,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}கு
|
|||||||
STR_AI_LIST_CANCEL :{BLACK}இரத்து செய்
|
STR_AI_LIST_CANCEL :{BLACK}இரத்து செய்
|
||||||
STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}வரிவடிவத்தினை மாற்றாதே
|
STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}வரிவடிவத்தினை மாற்றாதே
|
||||||
|
|
||||||
|
STR_SCREENSHOT_SCREENSHOT :{BLACK}சாதாரண திரைப்பிடிப்பு
|
||||||
|
|
||||||
# AI Parameters
|
# AI Parameters
|
||||||
STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} குணாதிசயங்கள்
|
STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} குணாதிசயங்கள்
|
||||||
|
@@ -1333,6 +1333,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Lliw y tirwedd
|
|||||||
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Gwyrdd
|
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Gwyrdd
|
||||||
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Gwyrdd tywyll
|
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Gwyrdd tywyll
|
||||||
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fioled
|
STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fioled
|
||||||
|
STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Ymddygiad tra'n sgrolio'r map
|
||||||
STR_CONFIG_SETTING_SMOOTH_SCROLLING :Sgrolio prif ffenestr llyfn: {STRING}
|
STR_CONFIG_SETTING_SMOOTH_SCROLLING :Sgrolio prif ffenestr llyfn: {STRING}
|
||||||
STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Rheoli syt y mae'r prif olygfa'n sgrolio at leoliad penodol pan yn clicio ar y map bychan neu yn rhoi gorchymyn i sgrolio at wrthrych penodol
|
STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Rheoli syt y mae'r prif olygfa'n sgrolio at leoliad penodol pan yn clicio ar y map bychan neu yn rhoi gorchymyn i sgrolio at wrthrych penodol
|
||||||
STR_CONFIG_SETTING_MEASURE_TOOLTIP :Dangos cymorth mesur wrth ddefnyddio'r offer adeiladu amrywiol: {STRING}
|
STR_CONFIG_SETTING_MEASURE_TOOLTIP :Dangos cymorth mesur wrth ddefnyddio'r offer adeiladu amrywiol: {STRING}
|
||||||
@@ -2678,14 +2679,17 @@ STR_ABOUT_VERSION :{BLACK}fersiwn
|
|||||||
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2019 Y tîm OpenTTD
|
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2019 Y tîm OpenTTD
|
||||||
|
|
||||||
# Framerate display window
|
# Framerate display window
|
||||||
|
STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Nifer y ticiau gêm a efelychir bob eiliad.
|
||||||
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Nifer o fframiau fideo a lunir bob eiliad.
|
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Nifer o fframiau fideo a lunir bob eiliad.
|
||||||
STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Pa mor gyflym mae'r gêm yn rhedeg, o gymharu a'r cyflymder i'w ddisgwyl ar gyfradd efelychu arferol.
|
STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Pa mor gyflym mae'r gêm yn rhedeg, o gymharu a'r cyflymder i'w ddisgwyl ar gyfradd efelychu arferol.
|
||||||
|
STR_FRAMERATE_AVERAGE :{WHITE}Cymedr
|
||||||
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frâm yr eiliad
|
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frâm yr eiliad
|
||||||
############ Leave those lines in this order!!
|
############ Leave those lines in this order!!
|
||||||
STR_FRAMERATE_GL_ECONOMY :{BLACK} Trin cargo:
|
STR_FRAMERATE_GL_ECONOMY :{BLACK} Trin cargo:
|
||||||
############ End of leave-in-this-order
|
############ End of leave-in-this-order
|
||||||
############ Leave those lines in this order!!
|
############ Leave those lines in this order!!
|
||||||
STR_FRAMETIME_CAPTION_VIDEO :Allbwn fideo
|
STR_FRAMETIME_CAPTION_VIDEO :Allbwn fideo
|
||||||
|
STR_FRAMETIME_CAPTION_SOUND :Cymysgu sain
|
||||||
############ End of leave-in-this-order
|
############ End of leave-in-this-order
|
||||||
|
|
||||||
|
|
||||||
|
@@ -58,34 +58,10 @@ static void DoSetVolume()
|
|||||||
AUGraphGetIndNode(graph, i, &node);
|
AUGraphGetIndNode(graph, i, &node);
|
||||||
|
|
||||||
AudioUnit unit;
|
AudioUnit unit;
|
||||||
OSType comp_type = 0;
|
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 5, 0)) {
|
|
||||||
/* The 10.6 SDK has changed the function prototype of
|
|
||||||
* AUGraphNodeInfo. This is a binary compatible change,
|
|
||||||
* but we need to get the type declaration right or
|
|
||||||
* risk compilation errors. The header AudioComponent.h
|
|
||||||
* was introduced in 10.6 so use it to decide which
|
|
||||||
* type definition to use. */
|
|
||||||
#if defined(__AUDIOCOMPONENT_H__) || defined(HAVE_OSX_107_SDK)
|
|
||||||
AudioComponentDescription desc;
|
AudioComponentDescription desc;
|
||||||
#else
|
|
||||||
ComponentDescription desc;
|
|
||||||
#endif
|
|
||||||
AUGraphNodeInfo(graph, node, &desc, &unit);
|
AUGraphNodeInfo(graph, node, &desc, &unit);
|
||||||
comp_type = desc.componentType;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
|
|
||||||
ComponentDescription desc;
|
|
||||||
AUGraphGetNodeInfo(graph, node, &desc, nullptr, nullptr, &unit);
|
|
||||||
comp_type = desc.componentType;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (comp_type == kAudioUnitType_Output) {
|
if (desc.componentType == kAudioUnitType_Output) {
|
||||||
output_unit = unit;
|
output_unit = unit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -161,27 +137,10 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song)
|
|||||||
const char *os_file = OTTD2FS(filename.c_str());
|
const char *os_file = OTTD2FS(filename.c_str());
|
||||||
CFAutoRelease<CFURLRef> url(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false));
|
CFAutoRelease<CFURLRef> url(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false));
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 5, 0)) {
|
|
||||||
if (MusicSequenceFileLoad(_sequence, url.get(), kMusicSequenceFile_AnyType, 0) != noErr) {
|
if (MusicSequenceFileLoad(_sequence, url.get(), kMusicSequenceFile_AnyType, 0) != noErr) {
|
||||||
DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file");
|
DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
|
|
||||||
FSRef ref_file;
|
|
||||||
if (!CFURLGetFSRef(url.get(), &ref_file)) {
|
|
||||||
DEBUG(driver, 0, "cocoa_m: Failed to make FSRef");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (MusicSequenceLoadSMFWithFlags(_sequence, &ref_file, 0) != noErr) {
|
|
||||||
DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file old style");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Construct audio graph */
|
/* Construct audio graph */
|
||||||
AUGraph graph = nullptr;
|
AUGraph graph = nullptr;
|
||||||
|
@@ -1,344 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file qtmidi.cpp
|
|
||||||
* @brief MIDI music player for MacOS X using QuickTime.
|
|
||||||
*
|
|
||||||
* This music player should work in all MacOS X releases starting from 10.0,
|
|
||||||
* as QuickTime is an integral part of the system since the old days of the
|
|
||||||
* Motorola 68k-based Macintoshes. The only extra dependency apart from
|
|
||||||
* QuickTime itself is Carbon, which is included since 10.0 as well.
|
|
||||||
*
|
|
||||||
* QuickTime gets fooled with the MIDI files from Transport Tycoon Deluxe
|
|
||||||
* because of the @c .gm suffix. To force QuickTime to load the MIDI files
|
|
||||||
* without the need of dealing with the individual QuickTime components
|
|
||||||
* needed to play music (data source, MIDI parser, note allocators,
|
|
||||||
* synthesizers and the like) some Carbon functions are used to set the file
|
|
||||||
* type as seen by QuickTime, using @c FSpSetFInfo() (which modifies the
|
|
||||||
* file's resource fork).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_QUICKTIME
|
|
||||||
|
|
||||||
#include "../stdafx.h"
|
|
||||||
#include "qtmidi.h"
|
|
||||||
#include "midifile.hpp"
|
|
||||||
#include "../debug.h"
|
|
||||||
#include "../base_media_base.h"
|
|
||||||
|
|
||||||
#define Rect OTTD_Rect
|
|
||||||
#define Point OTTD_Point
|
|
||||||
#define WindowClass OTTD_WindowClass
|
|
||||||
#include <QuickTime/QuickTime.h>
|
|
||||||
#undef Rect
|
|
||||||
#undef Point
|
|
||||||
#undef WindowClass
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
|
||||||
|
|
||||||
static FMusicDriver_QtMidi iFMusicDriver_QtMidi;
|
|
||||||
|
|
||||||
|
|
||||||
static const uint MIDI_TYPE = 'Midi'; ///< OSType code for MIDI songs.
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the @c OSType of a given file to @c 'Midi', but only if it's not
|
|
||||||
* already set.
|
|
||||||
*
|
|
||||||
* @param *ref A @c FSSpec structure referencing a file.
|
|
||||||
*/
|
|
||||||
static void SetMIDITypeIfNeeded(const FSRef *ref)
|
|
||||||
{
|
|
||||||
FSCatalogInfo catalogInfo;
|
|
||||||
|
|
||||||
assert(ref);
|
|
||||||
|
|
||||||
if (noErr != FSGetCatalogInfo(ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo, nullptr, nullptr, nullptr)) return;
|
|
||||||
if (!(catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) {
|
|
||||||
FileInfo * const info = (FileInfo *) catalogInfo.finderInfo;
|
|
||||||
if (info->fileType != MIDI_TYPE && !(info->finderFlags & kIsAlias)) {
|
|
||||||
OSErr e;
|
|
||||||
info->fileType = MIDI_TYPE;
|
|
||||||
e = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
|
|
||||||
if (e == noErr) {
|
|
||||||
DEBUG(driver, 3, "qtmidi: changed filetype to 'Midi'");
|
|
||||||
} else {
|
|
||||||
DEBUG(driver, 0, "qtmidi: changing filetype to 'Midi' failed - error %d", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a MIDI file and returns it as a QuickTime Movie structure.
|
|
||||||
*
|
|
||||||
* @param *path String with the path of an existing MIDI file.
|
|
||||||
* @param *moov Pointer to a @c Movie where the result will be stored.
|
|
||||||
* @return Whether the file was loaded and the @c Movie successfully created.
|
|
||||||
*/
|
|
||||||
static bool LoadMovieForMIDIFile(const char *path, Movie *moov)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
int ret;
|
|
||||||
char magic[4];
|
|
||||||
FSRef fsref;
|
|
||||||
FSSpec fsspec;
|
|
||||||
short refnum = 0;
|
|
||||||
short resid = 0;
|
|
||||||
|
|
||||||
assert(path != nullptr);
|
|
||||||
assert(moov != nullptr);
|
|
||||||
|
|
||||||
DEBUG(driver, 2, "qtmidi: start loading '%s'...", path);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX Manual check for MIDI header ('MThd'), as I don't know how to make
|
|
||||||
* QuickTime load MIDI files without a .mid suffix without knowing it's
|
|
||||||
* a MIDI file and setting the OSType of the file to the 'Midi' value.
|
|
||||||
* Perhaps ugly, but it seems that it does the Right Thing(tm).
|
|
||||||
*/
|
|
||||||
fd = open(path, O_RDONLY, 0);
|
|
||||||
if (fd == -1) return false;
|
|
||||||
ret = read(fd, magic, 4);
|
|
||||||
close(fd);
|
|
||||||
if (ret < 4) return false;
|
|
||||||
|
|
||||||
DEBUG(driver, 3, "qtmidi: header is '%.4s'", magic);
|
|
||||||
if (magic[0] != 'M' || magic[1] != 'T' || magic[2] != 'h' || magic[3] != 'd') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (noErr != FSPathMakeRef((const UInt8 *) path, &fsref, nullptr)) return false;
|
|
||||||
SetMIDITypeIfNeeded(&fsref);
|
|
||||||
|
|
||||||
if (noErr != FSGetCatalogInfo(&fsref, kFSCatInfoNone, nullptr, nullptr, &fsspec, nullptr)) return false;
|
|
||||||
if (OpenMovieFile(&fsspec, &refnum, fsRdPerm) != noErr) return false;
|
|
||||||
DEBUG(driver, 3, "qtmidi: '%s' successfully opened", path);
|
|
||||||
|
|
||||||
if (noErr != NewMovieFromFile(moov, refnum, &resid, nullptr,
|
|
||||||
newMovieActive | newMovieDontAskUnresolvedDataRefs, nullptr)) {
|
|
||||||
CloseMovieFile(refnum);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DEBUG(driver, 3, "qtmidi: movie container created");
|
|
||||||
|
|
||||||
CloseMovieFile(refnum);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag which has the @c true value when QuickTime is available and
|
|
||||||
* initialized.
|
|
||||||
*/
|
|
||||||
static bool _quicktime_started = false;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize QuickTime if needed. This function sets the
|
|
||||||
* #_quicktime_started flag to @c true if QuickTime is present in the system
|
|
||||||
* and it was initialized properly.
|
|
||||||
*/
|
|
||||||
static void InitQuickTimeIfNeeded()
|
|
||||||
{
|
|
||||||
OSStatus dummy;
|
|
||||||
|
|
||||||
if (_quicktime_started) return;
|
|
||||||
|
|
||||||
DEBUG(driver, 2, "qtmidi: initializing Quicktime");
|
|
||||||
/* Be polite: check whether QuickTime is available and initialize it. */
|
|
||||||
_quicktime_started =
|
|
||||||
(noErr == Gestalt(gestaltQuickTime, &dummy)) &&
|
|
||||||
(noErr == EnterMovies());
|
|
||||||
if (!_quicktime_started) DEBUG(driver, 0, "qtmidi: Quicktime initialization failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Possible states of the QuickTime music driver. */
|
|
||||||
enum QTStates {
|
|
||||||
QT_STATE_IDLE, ///< No file loaded.
|
|
||||||
QT_STATE_PLAY, ///< File loaded, playing.
|
|
||||||
QT_STATE_STOP, ///< File loaded, stopped.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static Movie _quicktime_movie; ///< Current QuickTime @c Movie.
|
|
||||||
static byte _quicktime_volume = 127; ///< Current volume.
|
|
||||||
static int _quicktime_state = QT_STATE_IDLE; ///< Current player state.
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps OpenTTD volume to QuickTime notion of volume.
|
|
||||||
*/
|
|
||||||
#define VOLUME ((short)((0x00FF & _quicktime_volume) << 1))
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialized the MIDI player, including QuickTime initialization.
|
|
||||||
*
|
|
||||||
* @todo Give better error messages by inspecting error codes returned by
|
|
||||||
* @c Gestalt() and @c EnterMovies(). Needs changes in
|
|
||||||
* #InitQuickTimeIfNeeded.
|
|
||||||
*/
|
|
||||||
const char *MusicDriver_QtMidi::Start(const char * const *parm)
|
|
||||||
{
|
|
||||||
InitQuickTimeIfNeeded();
|
|
||||||
return (_quicktime_started) ? nullptr : "can't initialize QuickTime";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the player is active.
|
|
||||||
*
|
|
||||||
* This function is called at regular intervals from OpenTTD's main loop, so
|
|
||||||
* we call @c MoviesTask() from here to let QuickTime do its work.
|
|
||||||
*/
|
|
||||||
bool MusicDriver_QtMidi::IsSongPlaying()
|
|
||||||
{
|
|
||||||
if (!_quicktime_started) return true;
|
|
||||||
|
|
||||||
switch (_quicktime_state) {
|
|
||||||
case QT_STATE_IDLE:
|
|
||||||
case QT_STATE_STOP:
|
|
||||||
/* Do nothing. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QT_STATE_PLAY:
|
|
||||||
MoviesTask(_quicktime_movie, 0);
|
|
||||||
/* Check whether movie ended. */
|
|
||||||
if (IsMovieDone(_quicktime_movie) ||
|
|
||||||
(GetMovieTime(_quicktime_movie, nullptr) >=
|
|
||||||
GetMovieDuration(_quicktime_movie))) {
|
|
||||||
_quicktime_state = QT_STATE_STOP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _quicktime_state == QT_STATE_PLAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops the MIDI player.
|
|
||||||
*
|
|
||||||
* Stops playing and frees any used resources before returning. As it
|
|
||||||
* deinitilizes QuickTime, the #_quicktime_started flag is set to @c false.
|
|
||||||
*/
|
|
||||||
void MusicDriver_QtMidi::Stop()
|
|
||||||
{
|
|
||||||
if (!_quicktime_started) return;
|
|
||||||
|
|
||||||
DEBUG(driver, 2, "qtmidi: stopping driver...");
|
|
||||||
switch (_quicktime_state) {
|
|
||||||
case QT_STATE_IDLE:
|
|
||||||
DEBUG(driver, 3, "qtmidi: stopping not needed, already idle");
|
|
||||||
/* Do nothing. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QT_STATE_PLAY:
|
|
||||||
StopSong();
|
|
||||||
FALLTHROUGH;
|
|
||||||
|
|
||||||
case QT_STATE_STOP:
|
|
||||||
DisposeMovie(_quicktime_movie);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitMovies();
|
|
||||||
_quicktime_started = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts playing a new song.
|
|
||||||
*
|
|
||||||
* @param filename Path to a MIDI file.
|
|
||||||
*/
|
|
||||||
void MusicDriver_QtMidi::PlaySong(const MusicSongInfo &song)
|
|
||||||
{
|
|
||||||
if (!_quicktime_started) return;
|
|
||||||
|
|
||||||
std::string filename = MidiFile::GetSMFFile(song);
|
|
||||||
if (filename.empty()) return;
|
|
||||||
|
|
||||||
DEBUG(driver, 2, "qtmidi: trying to play '%s'", filename.c_str());
|
|
||||||
switch (_quicktime_state) {
|
|
||||||
case QT_STATE_PLAY:
|
|
||||||
StopSong();
|
|
||||||
DEBUG(driver, 3, "qtmidi: previous tune stopped");
|
|
||||||
FALLTHROUGH;
|
|
||||||
|
|
||||||
case QT_STATE_STOP:
|
|
||||||
DisposeMovie(_quicktime_movie);
|
|
||||||
DEBUG(driver, 3, "qtmidi: previous tune disposed");
|
|
||||||
_quicktime_state = QT_STATE_IDLE;
|
|
||||||
FALLTHROUGH;
|
|
||||||
|
|
||||||
case QT_STATE_IDLE:
|
|
||||||
LoadMovieForMIDIFile(filename.c_str(), &_quicktime_movie);
|
|
||||||
SetMovieVolume(_quicktime_movie, VOLUME);
|
|
||||||
StartMovie(_quicktime_movie);
|
|
||||||
_quicktime_state = QT_STATE_PLAY;
|
|
||||||
}
|
|
||||||
DEBUG(driver, 3, "qtmidi: playing '%s'", filename.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops playing the current song, if the player is active.
|
|
||||||
*/
|
|
||||||
void MusicDriver_QtMidi::StopSong()
|
|
||||||
{
|
|
||||||
if (!_quicktime_started) return;
|
|
||||||
|
|
||||||
switch (_quicktime_state) {
|
|
||||||
case QT_STATE_IDLE:
|
|
||||||
FALLTHROUGH;
|
|
||||||
|
|
||||||
case QT_STATE_STOP:
|
|
||||||
DEBUG(driver, 3, "qtmidi: stop requested, but already idle");
|
|
||||||
/* Do nothing. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QT_STATE_PLAY:
|
|
||||||
StopMovie(_quicktime_movie);
|
|
||||||
_quicktime_state = QT_STATE_STOP;
|
|
||||||
DEBUG(driver, 3, "qtmidi: player stopped");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the playing volume of the MIDI player.
|
|
||||||
*
|
|
||||||
* As QuickTime controls volume in a per-movie basis, the desired volume is
|
|
||||||
* stored in #_quicktime_volume, and the volume is set here using the
|
|
||||||
* #VOLUME macro, @b and when loading new song in #PlaySong.
|
|
||||||
*
|
|
||||||
* @param vol The desired volume, range of the value is @c 0-127
|
|
||||||
*/
|
|
||||||
void MusicDriver_QtMidi::SetVolume(byte vol)
|
|
||||||
{
|
|
||||||
if (!_quicktime_started) return;
|
|
||||||
|
|
||||||
_quicktime_volume = vol;
|
|
||||||
|
|
||||||
DEBUG(driver, 2, "qtmidi: set volume to %u (%hi)", vol, VOLUME);
|
|
||||||
switch (_quicktime_state) {
|
|
||||||
case QT_STATE_IDLE:
|
|
||||||
/* Do nothing. */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QT_STATE_PLAY:
|
|
||||||
case QT_STATE_STOP:
|
|
||||||
SetMovieVolume(_quicktime_movie, VOLUME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* NO_QUICKTIME */
|
|
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file qtmidi.h Base of music playback via the QuickTime driver. */
|
|
||||||
|
|
||||||
#ifndef MUSIC_MACOSX_QUICKTIME_H
|
|
||||||
#define MUSIC_MACOSX_QUICKTIME_H
|
|
||||||
|
|
||||||
#include "music_driver.hpp"
|
|
||||||
|
|
||||||
class MusicDriver_QtMidi : public MusicDriver {
|
|
||||||
public:
|
|
||||||
const char *Start(const char * const *param) override;
|
|
||||||
|
|
||||||
void Stop() override;
|
|
||||||
|
|
||||||
void PlaySong(const MusicSongInfo &song) override;
|
|
||||||
|
|
||||||
void StopSong() override;
|
|
||||||
|
|
||||||
bool IsSongPlaying() override;
|
|
||||||
|
|
||||||
void SetVolume(byte vol) override;
|
|
||||||
const char *GetName() const override { return "qt"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class FMusicDriver_QtMidi : public DriverFactoryBase {
|
|
||||||
public:
|
|
||||||
FMusicDriver_QtMidi() : DriverFactoryBase(Driver::DT_MUSIC, 5, "qt", "QuickTime MIDI Driver") {}
|
|
||||||
Driver *CreateInstance() const override { return new MusicDriver_QtMidi(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* MUSIC_MACOSX_QUICKTIME_H */
|
|
@@ -129,10 +129,12 @@ class CrashLogOSX : public CrashLog {
|
|||||||
" Name: Mac OS X\n"
|
" Name: Mac OS X\n"
|
||||||
" Release: %d.%d.%d\n"
|
" Release: %d.%d.%d\n"
|
||||||
" Machine: %s\n"
|
" Machine: %s\n"
|
||||||
" Min Ver: %d\n",
|
" Min Ver: %d\n"
|
||||||
|
" Max Ver: %d\n",
|
||||||
ver_maj, ver_min, ver_bug,
|
ver_maj, ver_min, ver_bug,
|
||||||
arch != nullptr ? arch->description : "unknown",
|
arch != nullptr ? arch->description : "unknown",
|
||||||
MAC_OS_X_VERSION_MIN_REQUIRED
|
MAC_OS_X_VERSION_MIN_REQUIRED,
|
||||||
|
MAC_OS_X_VERSION_MAX_ALLOWED
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -161,19 +161,8 @@ const char *GetCurrentLocale(const char *)
|
|||||||
NSString *preferredLang = [ languages objectAtIndex:0 ];
|
NSString *preferredLang = [ languages objectAtIndex:0 ];
|
||||||
/* preferredLang is either 2 or 5 characters long ("xx" or "xx_YY"). */
|
/* preferredLang is either 2 or 5 characters long ("xx" or "xx_YY"). */
|
||||||
|
|
||||||
/* Since Apple introduced encoding to CString in OSX 10.4 we have to make a few conditions
|
|
||||||
* to get the right code for the used version of OSX. */
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 4, 0)) {
|
|
||||||
[ preferredLang getCString:retbuf maxLength:32 encoding:NSASCIIStringEncoding ];
|
[ preferredLang getCString:retbuf maxLength:32 encoding:NSASCIIStringEncoding ];
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
|
|
||||||
/* maxLength does not include the \0 char in contrast to the call above. */
|
|
||||||
[ preferredLang getCString:retbuf maxLength:31 ];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return retbuf;
|
return retbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +202,7 @@ bool IsMonospaceFont(CFStringRef name)
|
|||||||
{
|
{
|
||||||
NSFont *font = [ NSFont fontWithName:(__bridge NSString *)name size:0.0f ];
|
NSFont *font = [ NSFont fontWithName:(__bridge NSString *)name size:0.0f ];
|
||||||
|
|
||||||
return font != nullptr ? [ font isFixedPitch ] : false;
|
return font != nil ? [ font isFixedPitch ] : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -222,14 +211,12 @@ bool IsMonospaceFont(CFStringRef name)
|
|||||||
*/
|
*/
|
||||||
void MacOSSetThreadName(const char *name)
|
void MacOSSetThreadName(const char *name)
|
||||||
{
|
{
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 6, 0)) {
|
if (MacOSVersionIsAtLeast(10, 6, 0)) {
|
||||||
pthread_setname_np(name);
|
pthread_setname_np(name);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
NSThread *cur = [ NSThread currentThread ];
|
NSThread *cur = [ NSThread currentThread ];
|
||||||
if (cur != nullptr && [ cur respondsToSelector:@selector(setName:) ]) {
|
if (cur != nil && [ cur respondsToSelector:@selector(setName:) ]) {
|
||||||
[ cur performSelector:@selector(setName:) withObject:[ NSString stringWithUTF8String:name ] ];
|
[ cur performSelector:@selector(setName:) withObject:[ NSString stringWithUTF8String:name ] ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,10 @@
|
|||||||
#define HAVE_OSX_107_SDK
|
#define HAVE_OSX_107_SDK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MAC_OS_X_VERSION_10_9
|
||||||
|
#define HAVE_OSX_109_SDK
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MAC_OS_X_VERSION_10_11
|
#ifdef MAC_OS_X_VERSION_10_11
|
||||||
#define HAVE_OSX_1011_SDK
|
#define HAVE_OSX_1011_SDK
|
||||||
#endif
|
#endif
|
||||||
|
@@ -19,7 +19,34 @@
|
|||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
/* CTRunDelegateCreate is supported since MacOS X 10.5, but was only included in the SDKs starting with the 10.9 SDK. */
|
||||||
|
#ifndef HAVE_OSX_109_SDK
|
||||||
|
extern "C" {
|
||||||
|
typedef const struct __CTRunDelegate * CTRunDelegateRef;
|
||||||
|
|
||||||
|
typedef void (*CTRunDelegateDeallocateCallback) (void* refCon);
|
||||||
|
typedef CGFloat (*CTRunDelegateGetAscentCallback) (void* refCon);
|
||||||
|
typedef CGFloat (*CTRunDelegateGetDescentCallback) (void* refCon);
|
||||||
|
typedef CGFloat (*CTRunDelegateGetWidthCallback) (void* refCon);
|
||||||
|
typedef struct {
|
||||||
|
CFIndex version;
|
||||||
|
CTRunDelegateDeallocateCallback dealloc;
|
||||||
|
CTRunDelegateGetAscentCallback getAscent;
|
||||||
|
CTRunDelegateGetDescentCallback getDescent;
|
||||||
|
CTRunDelegateGetWidthCallback getWidth;
|
||||||
|
} CTRunDelegateCallbacks;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kCTRunDelegateVersion1 = 1,
|
||||||
|
kCTRunDelegateCurrentVersion = kCTRunDelegateVersion1
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const CFStringRef kCTRunDelegateAttributeName AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
|
||||||
|
|
||||||
|
CTRunDelegateRef CTRunDelegateCreate(const CTRunDelegateCallbacks* callbacks, void* refCon) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_OSX_109_SDK */
|
||||||
|
|
||||||
/** Cached current locale. */
|
/** Cached current locale. */
|
||||||
static CFAutoRelease<CFLocaleRef> _osx_locale;
|
static CFAutoRelease<CFLocaleRef> _osx_locale;
|
||||||
/** CoreText cache for font information, cleared when OTTD changes fonts. */
|
/** CoreText cache for font information, cleared when OTTD changes fonts. */
|
||||||
@@ -409,23 +436,3 @@ int MacOSStringCompare(const char *s1, const char *s2)
|
|||||||
|
|
||||||
return new OSXStringIterator();
|
return new OSXStringIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
void MacOSResetScriptCache(FontSize size) {}
|
|
||||||
void MacOSSetCurrentLocaleName(const char *iso_code) {}
|
|
||||||
|
|
||||||
int MacOSStringCompare(const char *s1, const char *s2)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ StringIterator *OSXStringIterator::Create()
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) */
|
|
||||||
|
@@ -557,12 +557,19 @@ void ScriptList::AddList(ScriptList *list)
|
|||||||
{
|
{
|
||||||
if (list == this) return;
|
if (list == this) return;
|
||||||
|
|
||||||
|
if (this->IsEmpty()) {
|
||||||
|
/* If this is empty, we can just take the items of the other list as is. */
|
||||||
|
this->items = list->items;
|
||||||
|
this->buckets = list->buckets;
|
||||||
|
this->modifications++;
|
||||||
|
} else {
|
||||||
ScriptListMap *list_items = &list->items;
|
ScriptListMap *list_items = &list->items;
|
||||||
for (ScriptListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
|
for (ScriptListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) {
|
||||||
this->AddItem((*iter).first);
|
this->AddItem((*iter).first);
|
||||||
this->SetValue((*iter).first, (*iter).second);
|
this->SetValue((*iter).first, (*iter).second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptList::SwapList(ScriptList *list)
|
void ScriptList::SwapList(ScriptList *list)
|
||||||
{
|
{
|
||||||
|
@@ -62,11 +62,11 @@
|
|||||||
DiagDirection to_other_tile = ::DiagdirBetweenTiles(t2, t1);
|
DiagDirection to_other_tile = ::DiagdirBetweenTiles(t2, t1);
|
||||||
|
|
||||||
/* Determine the reachable tracks from the shared edge */
|
/* Determine the reachable tracks from the shared edge */
|
||||||
TrackBits gtts1 = ::TrackStatusToTrackBits(::GetTileTrackStatus(t1, TRANSPORT_WATER, 0, to_other_tile)) & ::DiagdirReachesTracks(to_other_tile);
|
TrackBits gtts1 = ::TrackStatusToTrackBits(::GetTileTrackStatus(t1, TRANSPORT_WATER, 0, ReverseDiagDir(to_other_tile))) & ::DiagdirReachesTracks(to_other_tile);
|
||||||
if (gtts1 == TRACK_BIT_NONE) return false;
|
if (gtts1 == TRACK_BIT_NONE) return false;
|
||||||
|
|
||||||
to_other_tile = ReverseDiagDir(to_other_tile);
|
to_other_tile = ReverseDiagDir(to_other_tile);
|
||||||
TrackBits gtts2 = ::TrackStatusToTrackBits(::GetTileTrackStatus(t2, TRANSPORT_WATER, 0, to_other_tile)) & ::DiagdirReachesTracks(to_other_tile);
|
TrackBits gtts2 = ::TrackStatusToTrackBits(::GetTileTrackStatus(t2, TRANSPORT_WATER, 0, ReverseDiagDir(to_other_tile))) & ::DiagdirReachesTracks(to_other_tile);
|
||||||
|
|
||||||
return gtts2 != TRACK_BIT_NONE;
|
return gtts2 != TRACK_BIT_NONE;
|
||||||
}
|
}
|
||||||
|
@@ -68,8 +68,6 @@ const char *SoundDriver_Cocoa::Start(const char * const *parm)
|
|||||||
|
|
||||||
MxInitialize((uint)requestedDesc.mSampleRate);
|
MxInitialize((uint)requestedDesc.mSampleRate);
|
||||||
|
|
||||||
#if defined(__AUDIOCOMPONENT_H__) || defined(HAVE_OSX_107_SDK)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 6, 0)) {
|
|
||||||
/* Locate the default output audio unit */
|
/* Locate the default output audio unit */
|
||||||
AudioComponentDescription desc;
|
AudioComponentDescription desc;
|
||||||
desc.componentType = kAudioUnitType_Output;
|
desc.componentType = kAudioUnitType_Output;
|
||||||
@@ -87,31 +85,6 @@ const char *SoundDriver_Cocoa::Start(const char * const *parm)
|
|||||||
if (AudioComponentInstanceNew(comp, &_outputAudioUnit) != noErr) {
|
if (AudioComponentInstanceNew(comp, &_outputAudioUnit) != noErr) {
|
||||||
return "cocoa_s: Failed to start CoreAudio: AudioComponentInstanceNew";
|
return "cocoa_s: Failed to start CoreAudio: AudioComponentInstanceNew";
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6)
|
|
||||||
/* Locate the default output audio unit */
|
|
||||||
ComponentDescription desc;
|
|
||||||
desc.componentType = kAudioUnitType_Output;
|
|
||||||
desc.componentSubType = kAudioUnitSubType_HALOutput;
|
|
||||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
|
||||||
desc.componentFlags = 0;
|
|
||||||
desc.componentFlagsMask = 0;
|
|
||||||
|
|
||||||
Component comp = FindNextComponent (nullptr, &desc);
|
|
||||||
if (comp == nullptr) {
|
|
||||||
return "cocoa_s: Failed to start CoreAudio: FindNextComponent returned nullptr";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open & initialize the default output audio unit */
|
|
||||||
if (OpenAComponent(comp, &_outputAudioUnit) != noErr) {
|
|
||||||
return "cocoa_s: Failed to start CoreAudio: OpenAComponent";
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return "cocoa_s: Not supported on this OS X version";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AudioUnitInitialize(_outputAudioUnit) != noErr) {
|
if (AudioUnitInitialize(_outputAudioUnit) != noErr) {
|
||||||
return "cocoa_s: Failed to start CoreAudio: AudioUnitInitialize";
|
return "cocoa_s: Failed to start CoreAudio: AudioUnitInitialize";
|
||||||
@@ -157,22 +130,10 @@ void SoundDriver_Cocoa::Stop()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__AUDIOCOMPONENT_H__) || defined(HAVE_OSX_107_SDK)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 6, 0)) {
|
|
||||||
if (AudioComponentInstanceDispose(_outputAudioUnit) != noErr) {
|
if (AudioComponentInstanceDispose(_outputAudioUnit) != noErr) {
|
||||||
DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: AudioComponentInstanceDispose failed");
|
DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: AudioComponentInstanceDispose failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6)
|
|
||||||
if (CloseComponent(_outputAudioUnit) != noErr) {
|
|
||||||
DEBUG(driver, 0, "cocoa_s: Core_CloseAudio: CloseComponent failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WITH_COCOA */
|
#endif /* WITH_COCOA */
|
||||||
|
@@ -189,17 +189,9 @@ public:
|
|||||||
|
|
||||||
extern CocoaSubdriver *_cocoa_subdriver;
|
extern CocoaSubdriver *_cocoa_subdriver;
|
||||||
|
|
||||||
CocoaSubdriver *QZ_CreateFullscreenSubdriver(int width, int height, int bpp);
|
|
||||||
|
|
||||||
#ifdef ENABLE_COCOA_QUICKDRAW
|
|
||||||
CocoaSubdriver *QZ_CreateWindowQuickdrawSubdriver(int width, int height, int bpp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_COCOA_QUARTZ
|
#ifdef ENABLE_COCOA_QUARTZ
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
CocoaSubdriver *QZ_CreateWindowQuartzSubdriver(int width, int height, int bpp);
|
CocoaSubdriver *QZ_CreateWindowQuartzSubdriver(int width, int height, int bpp);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
void QZ_GameSizeChanged();
|
void QZ_GameSizeChanged();
|
||||||
|
|
||||||
@@ -229,16 +221,7 @@ uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_i
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
/** Subclass of NSView to fix Quartz rendering and mouse awareness */
|
/** Subclass of NSView to fix Quartz rendering and mouse awareness */
|
||||||
@interface OTTD_CocoaView : NSView
|
@interface OTTD_CocoaView : NSView <NSTextInputClient>
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
|
||||||
# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
|
|
||||||
<NSTextInputClient, NSTextInput>
|
|
||||||
# else
|
|
||||||
<NSTextInputClient>
|
|
||||||
# endif /* MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 */
|
|
||||||
#else
|
|
||||||
<NSTextInput>
|
|
||||||
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 */
|
|
||||||
{
|
{
|
||||||
CocoaSubdriver *driver;
|
CocoaSubdriver *driver;
|
||||||
NSTrackingRectTag trackingtag;
|
NSTrackingRectTag trackingtag;
|
||||||
@@ -258,10 +241,7 @@ uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_i
|
|||||||
@end
|
@end
|
||||||
|
|
||||||
/** Delegate for our NSWindow to send ask for quit on close */
|
/** Delegate for our NSWindow to send ask for quit on close */
|
||||||
@interface OTTD_CocoaWindowDelegate : NSObject
|
@interface OTTD_CocoaWindowDelegate : NSObject <NSWindowDelegate>
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
|
||||||
<NSWindowDelegate>
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
CocoaSubdriver *driver;
|
CocoaSubdriver *driver;
|
||||||
}
|
}
|
||||||
|
@@ -45,10 +45,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@interface OTTDMain : NSObject
|
@interface OTTDMain : NSObject <NSApplicationDelegate>
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
|
||||||
<NSApplicationDelegate>
|
|
||||||
#endif
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@@ -159,7 +156,9 @@ static void setApplicationMenu()
|
|||||||
/* Tell the application object that this is now the application menu.
|
/* Tell the application object that this is now the application menu.
|
||||||
* This interesting Objective-C construct is used because not all SDK
|
* This interesting Objective-C construct is used because not all SDK
|
||||||
* versions define this method publicly. */
|
* versions define this method publicly. */
|
||||||
|
if ([ NSApp respondsToSelector:@selector(setAppleMenu:) ]) {
|
||||||
[ NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu ];
|
[ NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu ];
|
||||||
|
}
|
||||||
|
|
||||||
/* Finally give up our references to the objects */
|
/* Finally give up our references to the objects */
|
||||||
[ appleMenu release ];
|
[ appleMenu release ];
|
||||||
@@ -204,13 +203,9 @@ static void setupApplication()
|
|||||||
/* Ensure the application object is initialised */
|
/* Ensure the application object is initialised */
|
||||||
[ NSApplication sharedApplication ];
|
[ NSApplication sharedApplication ];
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
|
|
||||||
/* Tell the dock about us */
|
/* Tell the dock about us */
|
||||||
if (MacOSVersionIsAtLeast(10, 3, 0)) {
|
|
||||||
OSStatus returnCode = TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
OSStatus returnCode = TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||||
if (returnCode != 0) DEBUG(driver, 0, "Could not change to foreground application. Error %d", (int)returnCode);
|
if (returnCode != 0) DEBUG(driver, 0, "Could not change to foreground application. Error %d", (int)returnCode);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable the system-wide tab feature as we only have one window. */
|
/* Disable the system-wide tab feature as we only have one window. */
|
||||||
if ([ NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:) ]) {
|
if ([ NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:) ]) {
|
||||||
@@ -243,12 +238,6 @@ static bool ModeSorter(const OTTD_Point &p1, const OTTD_Point &p2)
|
|||||||
|
|
||||||
static void QZ_GetDisplayModeInfo(CFArrayRef modes, CFIndex i, int &bpp, uint16 &width, uint16 &height)
|
static void QZ_GetDisplayModeInfo(CFArrayRef modes, CFIndex i, int &bpp, uint16 &width, uint16 &height)
|
||||||
{
|
{
|
||||||
bpp = 0;
|
|
||||||
width = 0;
|
|
||||||
height = 0;
|
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 6, 0)) {
|
|
||||||
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
|
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
|
||||||
|
|
||||||
width = (uint16)CGDisplayModeGetWidth(mode);
|
width = (uint16)CGDisplayModeGetWidth(mode);
|
||||||
@@ -264,36 +253,12 @@ static void QZ_GetDisplayModeInfo(CFArrayRef modes, CFIndex i, int &bpp, uint16
|
|||||||
/* CGDisplayModeCopyPixelEncoding is deprecated on OSX 10.11+, but there are no 8 bpp modes anyway... */
|
/* CGDisplayModeCopyPixelEncoding is deprecated on OSX 10.11+, but there are no 8 bpp modes anyway... */
|
||||||
bpp = 32;
|
bpp = 32;
|
||||||
#endif
|
#endif
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
int intvalue;
|
|
||||||
|
|
||||||
CFDictionaryRef onemode = (const __CFDictionary*)CFArrayGetValueAtIndex(modes, i);
|
|
||||||
CFNumberRef number = (const __CFNumber*)CFDictionaryGetValue(onemode, kCGDisplayBitsPerPixel);
|
|
||||||
CFNumberGetValue(number, kCFNumberSInt32Type, &intvalue);
|
|
||||||
bpp = intvalue;
|
|
||||||
|
|
||||||
number = (const __CFNumber*)CFDictionaryGetValue(onemode, kCGDisplayWidth);
|
|
||||||
CFNumberGetValue(number, kCFNumberSInt32Type, &intvalue);
|
|
||||||
width = (uint16)intvalue;
|
|
||||||
|
|
||||||
number = (const __CFNumber*)CFDictionaryGetValue(onemode, kCGDisplayHeight);
|
|
||||||
CFNumberGetValue(number, kCFNumberSInt32Type, &intvalue);
|
|
||||||
height = (uint16)intvalue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_id, int device_depth)
|
uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_id, int device_depth)
|
||||||
{
|
{
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6)
|
CFAutoRelease<CFArrayRef> mode_list(CGDisplayCopyAllDisplayModes(display_id, nullptr));
|
||||||
CFArrayRef mode_list = MacOSVersionIsAtLeast(10, 6, 0) ? CGDisplayCopyAllDisplayModes(display_id, nullptr) : CGDisplayAvailableModes(display_id);
|
CFIndex num_modes = CFArrayGetCount(mode_list.get());
|
||||||
#elif (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
|
||||||
CFArrayRef mode_list = CGDisplayCopyAllDisplayModes(display_id, nullptr);
|
|
||||||
#else
|
|
||||||
CFArrayRef mode_list = CGDisplayAvailableModes(display_id);
|
|
||||||
#endif
|
|
||||||
CFIndex num_modes = CFArrayGetCount(mode_list);
|
|
||||||
|
|
||||||
/* Build list of modes with the requested bpp */
|
/* Build list of modes with the requested bpp */
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
@@ -301,7 +266,7 @@ uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_i
|
|||||||
int bpp;
|
int bpp;
|
||||||
uint16 width, height;
|
uint16 width, height;
|
||||||
|
|
||||||
QZ_GetDisplayModeInfo(mode_list, i, bpp, width, height);
|
QZ_GetDisplayModeInfo(mode_list.get(), i, bpp, width, height);
|
||||||
|
|
||||||
if (bpp != device_depth) continue;
|
if (bpp != device_depth) continue;
|
||||||
|
|
||||||
@@ -325,29 +290,9 @@ uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_i
|
|||||||
/* Sort list smallest to largest */
|
/* Sort list smallest to largest */
|
||||||
std::sort(modes, modes + count, ModeSorter);
|
std::sort(modes, modes + count, ModeSorter);
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 6, 0)) CFRelease(mode_list);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Small function to test if the main display can display 8 bpp in fullscreen */
|
|
||||||
bool QZ_CanDisplay8bpp()
|
|
||||||
{
|
|
||||||
/* 8bpp modes are deprecated starting in 10.5. CoreGraphics will return them
|
|
||||||
* as available in the display list, but many features (e.g. palette animation)
|
|
||||||
* will be broken. */
|
|
||||||
if (MacOSVersionIsAtLeast(10, 5, 0)) return false;
|
|
||||||
|
|
||||||
OTTD_Point p;
|
|
||||||
|
|
||||||
/* We want to know if 8 bpp is possible in fullscreen and not anything about
|
|
||||||
* resolutions. Because of this we want to fill a list of 1 resolution of 8 bpp
|
|
||||||
* on display 0 (main) and return if we found one. */
|
|
||||||
return QZ_ListModes(&p, 1, 0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the video modus.
|
* Update the video modus.
|
||||||
*
|
*
|
||||||
@@ -395,35 +340,11 @@ void QZ_GameSizeChanged()
|
|||||||
*/
|
*/
|
||||||
static CocoaSubdriver *QZ_CreateWindowSubdriver(int width, int height, int bpp)
|
static CocoaSubdriver *QZ_CreateWindowSubdriver(int width, int height, int bpp)
|
||||||
{
|
{
|
||||||
#if defined(ENABLE_COCOA_QUARTZ) || defined(ENABLE_COCOA_QUICKDRAW)
|
#if defined(ENABLE_COCOA_QUARTZ)
|
||||||
CocoaSubdriver *ret;
|
return QZ_CreateWindowQuartzSubdriver(width, height, bpp);
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
#if defined(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 != nullptr) return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_COCOA_QUICKDRAW
|
|
||||||
ret = QZ_CreateWindowQuickdrawSubdriver(width, height, bpp);
|
|
||||||
if (ret != nullptr) return ret;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(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.
|
|
||||||
*/
|
|
||||||
if (MacOSVersionIsAtLeast(10, 4, 0)) {
|
|
||||||
ret = QZ_CreateWindowQuartzSubdriver(width, height, bpp);
|
|
||||||
if (ret != nullptr) return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -438,17 +359,8 @@ static CocoaSubdriver *QZ_CreateWindowSubdriver(int width, int height, int bpp)
|
|||||||
*/
|
*/
|
||||||
static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool fullscreen, bool fallback)
|
static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool fullscreen, bool fallback)
|
||||||
{
|
{
|
||||||
CocoaSubdriver *ret = nullptr;
|
CocoaSubdriver *ret = QZ_CreateWindowSubdriver(width, height, bpp);
|
||||||
/* OSX 10.7 allows to toggle fullscreen mode differently */
|
|
||||||
if (MacOSVersionIsAtLeast(10, 7, 0)) {
|
|
||||||
ret = QZ_CreateWindowSubdriver(width, height, bpp);
|
|
||||||
if (ret != nullptr && fullscreen) ret->ToggleFullscreen();
|
if (ret != nullptr && fullscreen) ret->ToggleFullscreen();
|
||||||
}
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9)
|
|
||||||
else {
|
|
||||||
ret = fullscreen ? QZ_CreateFullscreenSubdriver(width, height, bpp) : QZ_CreateWindowSubdriver(width, height, bpp);
|
|
||||||
}
|
|
||||||
#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9) */
|
|
||||||
|
|
||||||
if (ret != nullptr) return ret;
|
if (ret != nullptr) return ret;
|
||||||
if (!fallback) return nullptr;
|
if (!fallback) return nullptr;
|
||||||
@@ -458,16 +370,6 @@ static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool f
|
|||||||
ret = QZ_CreateWindowSubdriver(640, 480, bpp);
|
ret = QZ_CreateWindowSubdriver(640, 480, bpp);
|
||||||
if (ret != nullptr) return ret;
|
if (ret != nullptr) return ret;
|
||||||
|
|
||||||
#if defined(_DEBUG) && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9)
|
|
||||||
/* 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 != nullptr) return ret;
|
|
||||||
}
|
|
||||||
#endif /* defined(_DEBUG) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9) */
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +398,7 @@ void VideoDriver_Cocoa::Stop()
|
|||||||
*/
|
*/
|
||||||
const char *VideoDriver_Cocoa::Start(const char * const *parm)
|
const char *VideoDriver_Cocoa::Start(const char * const *parm)
|
||||||
{
|
{
|
||||||
if (!MacOSVersionIsAtLeast(10, 3, 0)) return "The Cocoa video driver requires Mac OS X 10.3 or later.";
|
if (!MacOSVersionIsAtLeast(10, 6, 0)) return "The Cocoa video driver requires Mac OS X 10.6 or later.";
|
||||||
|
|
||||||
if (_cocoa_video_started) return "Already started";
|
if (_cocoa_video_started) return "Already started";
|
||||||
_cocoa_video_started = true;
|
_cocoa_video_started = true;
|
||||||
@@ -579,29 +481,7 @@ bool VideoDriver_Cocoa::ToggleFullscreen(bool full_screen)
|
|||||||
{
|
{
|
||||||
assert(_cocoa_subdriver != nullptr);
|
assert(_cocoa_subdriver != nullptr);
|
||||||
|
|
||||||
/* For 10.7 and later, we try to toggle using the quartz subdriver. */
|
return _cocoa_subdriver->ToggleFullscreen();
|
||||||
if (_cocoa_subdriver->ToggleFullscreen()) return true;
|
|
||||||
|
|
||||||
bool oldfs = _cocoa_subdriver->IsFullscreen();
|
|
||||||
if (full_screen != oldfs) {
|
|
||||||
int width = _cocoa_subdriver->GetWidth();
|
|
||||||
int height = _cocoa_subdriver->GetHeight();
|
|
||||||
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
|
|
||||||
|
|
||||||
delete _cocoa_subdriver;
|
|
||||||
_cocoa_subdriver = nullptr;
|
|
||||||
|
|
||||||
_cocoa_subdriver = QZ_CreateSubdriver(width, height, bpp, full_screen, false);
|
|
||||||
if (_cocoa_subdriver == nullptr) {
|
|
||||||
_cocoa_subdriver = QZ_CreateSubdriver(width, height, bpp, oldfs, true);
|
|
||||||
if (_cocoa_subdriver == nullptr) error("Cocoa: Failed to create subdriver");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QZ_GameSizeChanged();
|
|
||||||
QZ_UpdateVideoModes();
|
|
||||||
|
|
||||||
return _cocoa_subdriver->IsFullscreen() == full_screen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -619,16 +499,7 @@ bool VideoDriver_Cocoa::AfterBlitterChange()
|
|||||||
*/
|
*/
|
||||||
void VideoDriver_Cocoa::EditBoxLostFocus()
|
void VideoDriver_Cocoa::EditBoxLostFocus()
|
||||||
{
|
{
|
||||||
if (_cocoa_subdriver != nullptr) {
|
if (_cocoa_subdriver != NULL) [ [ _cocoa_subdriver->cocoaview inputContext ] discardMarkedText ];
|
||||||
if ([ _cocoa_subdriver->cocoaview respondsToSelector:@selector(inputContext) ] && [ [ _cocoa_subdriver->cocoaview performSelector:@selector(inputContext) ] respondsToSelector:@selector(discardMarkedText) ]) {
|
|
||||||
[ [ _cocoa_subdriver->cocoaview performSelector:@selector(inputContext) ] performSelector:@selector(discardMarkedText) ];
|
|
||||||
}
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6)
|
|
||||||
else {
|
|
||||||
[ [ NSInputManager currentInputManager ] markedTextAbandoned:_cocoa_subdriver->cocoaview ];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/* Clear any marked string from the current edit box. */
|
/* Clear any marked string from the current edit box. */
|
||||||
HandleTextInput(nullptr, true);
|
HandleTextInput(nullptr, true);
|
||||||
}
|
}
|
||||||
@@ -654,8 +525,6 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
|
|
||||||
if (MacOSVersionIsAtLeast(10, 3, 0)) {
|
|
||||||
NSAlert *alert = [ [ NSAlert alloc ] init ];
|
NSAlert *alert = [ [ NSAlert alloc ] init ];
|
||||||
[ alert setAlertStyle: NSCriticalAlertStyle ];
|
[ alert setAlertStyle: NSCriticalAlertStyle ];
|
||||||
[ alert setMessageText:[ NSString stringWithUTF8String:title ] ];
|
[ alert setMessageText:[ NSString stringWithUTF8String:title ] ];
|
||||||
@@ -663,13 +532,6 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel
|
|||||||
[ alert addButtonWithTitle: [ NSString stringWithUTF8String:buttonLabel ] ];
|
[ alert addButtonWithTitle: [ NSString stringWithUTF8String:buttonLabel ] ];
|
||||||
[ alert runModal ];
|
[ alert runModal ];
|
||||||
[ alert release ];
|
[ alert release ];
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3)
|
|
||||||
NSRunAlertPanel([ NSString stringWithUTF8String:title ], [ NSString stringWithUTF8String:message ], [ NSString stringWithUTF8String:buttonLabel ], nil, nil);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wasstarted && VideoDriver::GetInstance() != nullptr) VideoDriver::GetInstance()->Stop();
|
if (!wasstarted && VideoDriver::GetInstance() != nullptr) VideoDriver::GetInstance()->Stop();
|
||||||
|
|
||||||
@@ -1095,17 +957,7 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count)
|
|||||||
{
|
{
|
||||||
if (!EditBoxInGlobalFocus()) return NSNotFound;
|
if (!EditBoxInGlobalFocus()) return NSNotFound;
|
||||||
|
|
||||||
NSPoint view_pt = NSZeroPoint;
|
NSPoint view_pt = [ self convertRect:[ [ self window ] convertRectFromScreen:NSMakeRect(thePoint.x, thePoint.y, 0, 0) ] fromView:nil ].origin;
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
|
||||||
if ([ [ self window ] respondsToSelector:@selector(convertRectFromScreen:) ]) {
|
|
||||||
view_pt = [ self convertRect:[ [ self window ] convertRectFromScreen:NSMakeRect(thePoint.x, thePoint.y, 0, 0) ] fromView:nil ].origin;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)
|
|
||||||
view_pt = [ self convertPoint:[ [ self window ] convertScreenToBase:thePoint ] fromView:nil ];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Point pt = { (int)view_pt.x, (int)[ self frame ].size.height - (int)view_pt.y };
|
Point pt = { (int)view_pt.x, (int)[ self frame ].size.height - (int)view_pt.y };
|
||||||
|
|
||||||
@@ -1128,20 +980,8 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count)
|
|||||||
Rect r = _focused_window->GetTextBoundingRect(start, end);
|
Rect r = _focused_window->GetTextBoundingRect(start, end);
|
||||||
NSRect view_rect = NSMakeRect(_focused_window->left + r.left, [ self frame ].size.height - _focused_window->top - r.bottom, r.right - r.left, r.bottom - r.top);
|
NSRect view_rect = NSMakeRect(_focused_window->left + r.left, [ self frame ].size.height - _focused_window->top - r.bottom, r.right - r.left, r.bottom - r.top);
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
|
||||||
if ([ [ self window ] respondsToSelector:@selector(convertRectToScreen:) ]) {
|
|
||||||
return [ [ self window ] convertRectToScreen:[ self convertRect:view_rect toView:nil ] ];
|
return [ [ self window ] convertRectToScreen:[ self convertRect:view_rect toView:nil ] ];
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
|
|
||||||
NSRect window_rect = [ self convertRect:view_rect toView:nil ];
|
|
||||||
NSPoint origin = [ [ self window ] convertBaseToScreen:window_rect.origin ];
|
|
||||||
return NSMakeRect(origin.x, origin.y, window_rect.size.width, window_rect.size.height);
|
|
||||||
#else
|
|
||||||
return NSMakeRect(0, 0, 0, 0);;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get the bounding rect for the given range. */
|
/** Get the bounding rect for the given range. */
|
||||||
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||||
@@ -1155,16 +995,6 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count)
|
|||||||
return [ NSArray array ];
|
return [ NSArray array ];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Identifier for this text input instance. */
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
|
|
||||||
- (long)conversationIdentifier
|
|
||||||
#else
|
|
||||||
- (NSInteger)conversationIdentifier
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Delete single character left of the cursor. */
|
/** Delete single character left of the cursor. */
|
||||||
- (void)deleteBackward:(id)sender
|
- (void)deleteBackward:(id)sender
|
||||||
{
|
{
|
||||||
|
@@ -59,28 +59,12 @@ enum RightMouseButtonEmulationState {
|
|||||||
static unsigned int _current_mods;
|
static unsigned int _current_mods;
|
||||||
static bool _tab_is_down;
|
static bool _tab_is_down;
|
||||||
static bool _emulating_right_button;
|
static bool _emulating_right_button;
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
|
||||||
static float _current_magnification;
|
static float _current_magnification;
|
||||||
#endif
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
static uint32 _tEvent;
|
static uint32 _tEvent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Support for touch gestures is only available starting with the
|
|
||||||
* 10.6 SDK, even if it says that support starts in fact with 10.5.2.
|
|
||||||
* Replicate the needed stuff for older SDKs. */
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6)
|
|
||||||
static const NSUInteger NSEventTypeMagnify = 30;
|
|
||||||
static const NSUInteger NSEventTypeEndGesture = 20;
|
|
||||||
|
|
||||||
@interface NSEvent ()
|
|
||||||
/* This message is valid for events of type NSEventTypeMagnify, on 10.5.2 or later */
|
|
||||||
- (CGFloat)magnification WEAK_IMPORT_ATTRIBUTE;
|
|
||||||
@end
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static uint32 GetTick()
|
static uint32 GetTick()
|
||||||
{
|
{
|
||||||
struct timeval tim;
|
struct timeval tim;
|
||||||
@@ -579,16 +563,13 @@ static bool QZ_PollEvent()
|
|||||||
CGFloat deltaY;
|
CGFloat deltaY;
|
||||||
|
|
||||||
/* Use precise scrolling-specific deltas if they're supported. */
|
/* Use precise scrolling-specific deltas if they're supported. */
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
|
||||||
if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)]) {
|
if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)]) {
|
||||||
/* No precise deltas indicates a scroll wheel is being used, so we don't want 2D scrolling. */
|
/* No precise deltas indicates a scroll wheel is being used, so we don't want 2D scrolling. */
|
||||||
if (![ event hasPreciseScrollingDeltas ]) break;
|
if (![ event hasPreciseScrollingDeltas ]) break;
|
||||||
|
|
||||||
deltaX = [ event scrollingDeltaX ] * 0.5f;
|
deltaX = [ event scrollingDeltaX ] * 0.5f;
|
||||||
deltaY = [ event scrollingDeltaY ] * 0.5f;
|
deltaY = [ event scrollingDeltaY ] * 0.5f;
|
||||||
} else
|
} else {
|
||||||
#endif
|
|
||||||
{
|
|
||||||
deltaX = [ event deltaX ] * 5;
|
deltaX = [ event deltaX ] * 5;
|
||||||
deltaY = [ event deltaY ] * 5;
|
deltaY = [ event deltaY ] * 5;
|
||||||
}
|
}
|
||||||
@@ -598,7 +579,6 @@ static bool QZ_PollEvent()
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
|
|
||||||
case NSEventTypeMagnify:
|
case NSEventTypeMagnify:
|
||||||
/* Pinch open or close gesture. */
|
/* Pinch open or close gesture. */
|
||||||
_current_magnification += [ event magnification ] * 5.0f;
|
_current_magnification += [ event magnification ] * 5.0f;
|
||||||
@@ -619,7 +599,6 @@ static bool QZ_PollEvent()
|
|||||||
/* Gesture ended. */
|
/* Gesture ended. */
|
||||||
_current_magnification = 0.0f;
|
_current_magnification = 0.0f;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case NSCursorUpdate:
|
case NSCursorUpdate:
|
||||||
case NSMouseEntered:
|
case NSMouseEntered:
|
||||||
|
@@ -1,523 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Cocoa video driver *
|
|
||||||
* Known things left to do: *
|
|
||||||
* Scale© the old pixel buffer to the new one when switching resolution. *
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifdef WITH_COCOA
|
|
||||||
|
|
||||||
#include "../../stdafx.h"
|
|
||||||
|
|
||||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9)
|
|
||||||
|
|
||||||
#define Rect OTTDRect
|
|
||||||
#define Point OTTDPoint
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#undef Rect
|
|
||||||
#undef Point
|
|
||||||
|
|
||||||
#include "../../debug.h"
|
|
||||||
#include "../../core/geometry_type.hpp"
|
|
||||||
#include "../../core/sort_func.hpp"
|
|
||||||
#include "cocoa_v.h"
|
|
||||||
#include "../../gfx_func.h"
|
|
||||||
#include "../../thread.h"
|
|
||||||
#include "../../os/macosx/macos.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Important notice regarding all modifications!!!!!!!
|
|
||||||
* There are certain limitations because the file is objective C++.
|
|
||||||
* gdb has limitations.
|
|
||||||
* C++ and objective C code can't be joined in all cases (classes stuff).
|
|
||||||
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* From Menus.h (according to Xcode Developer Documentation) */
|
|
||||||
extern "C" void ShowMenuBar();
|
|
||||||
extern "C" void HideMenuBar();
|
|
||||||
|
|
||||||
|
|
||||||
/* Structure for rez switch gamma fades
|
|
||||||
* We can hide the monitor flicker by setting the gamma tables to 0
|
|
||||||
*/
|
|
||||||
#define QZ_GAMMA_TABLE_SIZE 256
|
|
||||||
|
|
||||||
struct OTTD_QuartzGammaTable {
|
|
||||||
CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Add methods to get at private members of NSScreen.
|
|
||||||
* Since there is a bug in Apple's screen switching code that does not update
|
|
||||||
* this variable when switching to fullscreen, we'll set it manually (but only
|
|
||||||
* for the main screen).
|
|
||||||
*/
|
|
||||||
@interface NSScreen (NSScreenAccess)
|
|
||||||
- (void) setFrame:(NSRect)frame;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation NSScreen (NSScreenAccess)
|
|
||||||
- (void) setFrame:(NSRect)frame
|
|
||||||
{
|
|
||||||
/* The 64 bits libraries don't seem to know about _frame, so this hack won't work. */
|
|
||||||
#ifndef __LP64__
|
|
||||||
_frame = frame;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
class FullscreenSubdriver : public CocoaSubdriver {
|
|
||||||
CGDirectDisplayID display_id; ///< 0 == main display (only support single display)
|
|
||||||
CFDictionaryRef cur_mode; ///< current mode of the display
|
|
||||||
CFDictionaryRef save_mode; ///< original mode of the display
|
|
||||||
CGDirectPaletteRef palette; ///< palette of an 8-bit display
|
|
||||||
|
|
||||||
|
|
||||||
/* Gamma functions to try to hide the flash from a res switch
|
|
||||||
* Fade the display from normal to black
|
|
||||||
* Save gamma tables for fade back to normal
|
|
||||||
*/
|
|
||||||
uint32 FadeGammaOut(OTTD_QuartzGammaTable *table)
|
|
||||||
{
|
|
||||||
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
CGGammaValue greenTable[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
CGGammaValue blueTable[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
|
|
||||||
unsigned int actual;
|
|
||||||
if (CGGetDisplayTransferByTable(this->display_id, QZ_GAMMA_TABLE_SIZE, table->red, table->green, table->blue, &actual) != CGDisplayNoErr
|
|
||||||
|| actual != QZ_GAMMA_TABLE_SIZE) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(redTable, table->red, sizeof(redTable));
|
|
||||||
memcpy(greenTable, table->green, sizeof(greenTable));
|
|
||||||
memcpy(blueTable, table->blue, sizeof(greenTable));
|
|
||||||
|
|
||||||
for (float percent = 1.0; percent >= 0.0; percent -= 0.01) {
|
|
||||||
for (int j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {
|
|
||||||
redTable[j] = redTable[j] * percent;
|
|
||||||
greenTable[j] = greenTable[j] * percent;
|
|
||||||
blueTable[j] = blueTable[j] * percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CGSetDisplayTransferByTable(this->display_id, QZ_GAMMA_TABLE_SIZE, redTable, greenTable, blueTable) != CGDisplayNoErr) {
|
|
||||||
CGDisplayRestoreColorSyncSettings();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fade the display from black to normal
|
|
||||||
* Restore previously saved gamma values
|
|
||||||
*/
|
|
||||||
uint32 FadeGammaIn(const OTTD_QuartzGammaTable *table)
|
|
||||||
{
|
|
||||||
CGGammaValue redTable[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
CGGammaValue greenTable[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
CGGammaValue blueTable[QZ_GAMMA_TABLE_SIZE];
|
|
||||||
|
|
||||||
memset(redTable, 0, sizeof(redTable));
|
|
||||||
memset(greenTable, 0, sizeof(greenTable));
|
|
||||||
memset(blueTable, 0, sizeof(greenTable));
|
|
||||||
|
|
||||||
for (float percent = 0.0; percent <= 1.0; percent += 0.01) {
|
|
||||||
for (int j = 0; j < QZ_GAMMA_TABLE_SIZE; j++) {
|
|
||||||
redTable[j] = table->red[j] * percent;
|
|
||||||
greenTable[j] = table->green[j] * percent;
|
|
||||||
blueTable[j] = table->blue[j] * percent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CGSetDisplayTransferByTable(this->display_id, QZ_GAMMA_TABLE_SIZE, redTable, greenTable, blueTable) != CGDisplayNoErr) {
|
|
||||||
CGDisplayRestoreColorSyncSettings();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */
|
|
||||||
void WaitForVerticalBlank()
|
|
||||||
{
|
|
||||||
/* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */
|
|
||||||
|
|
||||||
CFNumberRef refreshRateCFNumber = (const __CFNumber*)CFDictionaryGetValue(this->cur_mode, kCGDisplayRefreshRate);
|
|
||||||
if (refreshRateCFNumber == nullptr) return;
|
|
||||||
|
|
||||||
double refreshRate;
|
|
||||||
if (CFNumberGetValue(refreshRateCFNumber, kCFNumberDoubleType, &refreshRate) == 0) return;
|
|
||||||
|
|
||||||
if (refreshRate == 0) return;
|
|
||||||
|
|
||||||
double linesPerSecond = refreshRate * this->device_height;
|
|
||||||
double target = this->device_height;
|
|
||||||
|
|
||||||
/* Figure out the first delay so we start off about right */
|
|
||||||
double position = CGDisplayBeamPosition(this->display_id);
|
|
||||||
if (position > target) position = 0;
|
|
||||||
|
|
||||||
double adjustment = (target - position) / linesPerSecond;
|
|
||||||
|
|
||||||
CSleep((uint32)adjustment * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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. */
|
|
||||||
NSRect screen_rect;
|
|
||||||
int gamma_error;
|
|
||||||
NSPoint mouseLocation;
|
|
||||||
|
|
||||||
/* Destroy any previous mode */
|
|
||||||
if (this->pixel_buffer != nullptr) {
|
|
||||||
free(this->pixel_buffer);
|
|
||||||
this->pixel_buffer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See if requested mode exists */
|
|
||||||
boolean_t 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 act_bpp;
|
|
||||||
CFNumberRef number = (const __CFNumber*) CFDictionaryGetValue(this->cur_mode, kCGDisplayBitsPerPixel);
|
|
||||||
CFNumberGetValue(number, kCFNumberSInt32Type, &act_bpp);
|
|
||||||
if (act_bpp != bpp) {
|
|
||||||
DEBUG(driver, 0, "Failed to find display resolution");
|
|
||||||
goto ERR_NO_MATCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
number = (const __CFNumber*)CFDictionaryGetValue(this->cur_mode, kCGDisplayWidth);
|
|
||||||
CFNumberGetValue(number, kCFNumberSInt32Type, &w);
|
|
||||||
|
|
||||||
number = (const __CFNumber*)CFDictionaryGetValue(this->cur_mode, kCGDisplayHeight);
|
|
||||||
CFNumberGetValue(number, kCFNumberSInt32Type, &h);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Capture the main screen */
|
|
||||||
CGDisplayCapture(this->display_id);
|
|
||||||
|
|
||||||
/* Store the mouse coordinates relative to the total screen */
|
|
||||||
mouseLocation = [ NSEvent mouseLocation ];
|
|
||||||
mouseLocation.x /= this->device_width;
|
|
||||||
mouseLocation.y /= this->device_height;
|
|
||||||
|
|
||||||
/* Fade display to zero gamma */
|
|
||||||
OTTD_QuartzGammaTable gamma_table;
|
|
||||||
gamma_error = this->FadeGammaOut(&gamma_table);
|
|
||||||
|
|
||||||
/* Put up the blanking window (a window above all other windows) */
|
|
||||||
if (CGDisplayCapture(this->display_id) != CGDisplayNoErr ) {
|
|
||||||
DEBUG(driver, 0, "Failed capturing display");
|
|
||||||
goto ERR_NO_CAPTURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do the physical switch */
|
|
||||||
if (CGDisplaySwitchToMode(this->display_id, this->cur_mode) != CGDisplayNoErr) {
|
|
||||||
DEBUG(driver, 0, "Failed switching display resolution");
|
|
||||||
goto ERR_NO_SWITCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 = nullptr;
|
|
||||||
this->window_pitch = 0;
|
|
||||||
} 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);
|
|
||||||
this->device_depth = bpp;
|
|
||||||
|
|
||||||
/* Setup double-buffer emulation */
|
|
||||||
this->pixel_buffer = malloc(this->device_width * this->device_height * this->device_depth / 8);
|
|
||||||
if (this->pixel_buffer == nullptr) {
|
|
||||||
DEBUG(driver, 0, "Failed to allocate memory for double buffering");
|
|
||||||
goto ERR_DOUBLEBUF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->device_depth == 8 && !CGDisplayCanSetPalette(this->display_id)) {
|
|
||||||
DEBUG(driver, 0, "Not an indexed display mode.");
|
|
||||||
goto ERR_NOT_INDEXED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't hide menu bar, it will get events and interrupt the program */
|
|
||||||
HideMenuBar();
|
|
||||||
|
|
||||||
/* Hide the OS cursor */
|
|
||||||
CGDisplayHideCursor(this->display_id);
|
|
||||||
|
|
||||||
/* Fade the display to original gamma */
|
|
||||||
if (!gamma_error) FadeGammaIn(&gamma_table);
|
|
||||||
|
|
||||||
/* There is a bug in Cocoa where NSScreen doesn't synchronize
|
|
||||||
* with CGDirectDisplay, so the main screen's frame is wrong.
|
|
||||||
* As a result, coordinate translation produces incorrect results.
|
|
||||||
* We can hack around this bug by setting the screen rect ourselves.
|
|
||||||
* This hack should be removed if/when the bug is fixed.
|
|
||||||
*/
|
|
||||||
screen_rect = NSMakeRect(0, 0, this->device_width, this->device_height);
|
|
||||||
[ [ NSScreen mainScreen ] setFrame:screen_rect ];
|
|
||||||
|
|
||||||
this->UpdatePalette(0, 256);
|
|
||||||
|
|
||||||
/* Move the mouse cursor to approx. the same location */
|
|
||||||
CGPoint display_mouseLocation;
|
|
||||||
display_mouseLocation.x = mouseLocation.x * this->device_width;
|
|
||||||
display_mouseLocation.y = this->device_height - (mouseLocation.y * this->device_height);
|
|
||||||
|
|
||||||
_cursor.in_window = true;
|
|
||||||
|
|
||||||
CGDisplayMoveCursorToPoint(this->display_id, display_mouseLocation);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */
|
|
||||||
ERR_NOT_INDEXED:
|
|
||||||
free(this->pixel_buffer);
|
|
||||||
this->pixel_buffer = nullptr;
|
|
||||||
ERR_DOUBLEBUF:
|
|
||||||
CGDisplaySwitchToMode(this->display_id, this->save_mode);
|
|
||||||
ERR_NO_SWITCH:
|
|
||||||
CGReleaseAllDisplays();
|
|
||||||
ERR_NO_CAPTURE:
|
|
||||||
if (!gamma_error) this->FadeGammaIn(&gamma_table);
|
|
||||||
ERR_NO_MATCH:
|
|
||||||
this->device_width = 0;
|
|
||||||
this->device_height = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RestoreVideoMode()
|
|
||||||
{
|
|
||||||
/* Release fullscreen resources */
|
|
||||||
OTTD_QuartzGammaTable gamma_table;
|
|
||||||
int gamma_error = this->FadeGammaOut(&gamma_table);
|
|
||||||
|
|
||||||
/* Restore original screen resolution/bpp */
|
|
||||||
CGDisplaySwitchToMode(this->display_id, this->save_mode);
|
|
||||||
|
|
||||||
CGReleaseAllDisplays();
|
|
||||||
|
|
||||||
/* Bring back the cursor */
|
|
||||||
CGDisplayShowCursor(this->display_id);
|
|
||||||
|
|
||||||
ShowMenuBar();
|
|
||||||
|
|
||||||
/* Reset the main screen's rectangle
|
|
||||||
* See comment in SetVideoMode for why we do this */
|
|
||||||
NSRect screen_rect = NSMakeRect(0, 0, CGDisplayPixelsWide(this->display_id), CGDisplayPixelsHigh(this->display_id));
|
|
||||||
[ [ NSScreen mainScreen ] setFrame:screen_rect ];
|
|
||||||
|
|
||||||
/* Destroy the pixel buffer */
|
|
||||||
if (this->pixel_buffer != nullptr) {
|
|
||||||
free(this->pixel_buffer);
|
|
||||||
this->pixel_buffer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gamma_error) this->FadeGammaIn(&gamma_table);
|
|
||||||
|
|
||||||
this->device_width = CGDisplayPixelsWide(this->display_id);
|
|
||||||
this->device_height = CGDisplayPixelsHigh(this->display_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
FullscreenSubdriver()
|
|
||||||
{
|
|
||||||
/* Initialize the video settings; this data persists between mode switches */
|
|
||||||
this->display_id = kCGDirectMainDisplay;
|
|
||||||
this->save_mode = CGDisplayCurrentMode(this->display_id);
|
|
||||||
|
|
||||||
this->palette = CGPaletteCreateDefaultColorPalette();
|
|
||||||
|
|
||||||
this->device_width = CGDisplayPixelsWide(this->display_id);
|
|
||||||
this->device_height = CGDisplayPixelsHigh(this->display_id);
|
|
||||||
this->device_depth = 0;
|
|
||||||
this->pixel_buffer = nullptr;
|
|
||||||
|
|
||||||
this->num_dirty_rects = MAX_DIRTY_RECTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~FullscreenSubdriver()
|
|
||||||
{
|
|
||||||
this->RestoreVideoMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Draw(bool force_update)
|
|
||||||
{
|
|
||||||
const uint8 *src = (uint8 *)this->pixel_buffer;
|
|
||||||
uint8 *dst = (uint8 *)this->window_buffer;
|
|
||||||
uint pitch = this->window_pitch;
|
|
||||||
uint width = this->device_width;
|
|
||||||
uint num_dirty = this->num_dirty_rects;
|
|
||||||
uint bytesperpixel = this->device_depth / 8;
|
|
||||||
|
|
||||||
/* Check if we need to do anything */
|
|
||||||
if (num_dirty == 0) return;
|
|
||||||
|
|
||||||
if (num_dirty >= MAX_DIRTY_RECTS) {
|
|
||||||
num_dirty = 1;
|
|
||||||
this->dirty_rects[0].left = 0;
|
|
||||||
this->dirty_rects[0].top = 0;
|
|
||||||
this->dirty_rects[0].right = this->device_width;
|
|
||||||
this->dirty_rects[0].bottom = this->device_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitForVerticalBlank();
|
|
||||||
/* Build the region of dirty rectangles */
|
|
||||||
for (uint i = 0; i < num_dirty; i++) {
|
|
||||||
uint y = this->dirty_rects[i].top;
|
|
||||||
uint left = this->dirty_rects[i].left;
|
|
||||||
uint length = this->dirty_rects[i].right - left;
|
|
||||||
uint bottom = this->dirty_rects[i].bottom;
|
|
||||||
|
|
||||||
for (; y < bottom; y++) {
|
|
||||||
memcpy(dst + y * pitch + left * bytesperpixel, src + y * width * bytesperpixel + left * bytesperpixel, length * bytesperpixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->num_dirty_rects = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void MakeDirty(int left, int top, int width, int height)
|
|
||||||
{
|
|
||||||
if (this->num_dirty_rects < MAX_DIRTY_RECTS) {
|
|
||||||
this->dirty_rects[this->num_dirty_rects].left = left;
|
|
||||||
this->dirty_rects[this->num_dirty_rects].top = top;
|
|
||||||
this->dirty_rects[this->num_dirty_rects].right = left + width;
|
|
||||||
this->dirty_rects[this->num_dirty_rects].bottom = top + height;
|
|
||||||
}
|
|
||||||
this->num_dirty_rects++;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void UpdatePalette(uint first_color, uint num_colors)
|
|
||||||
{
|
|
||||||
if (this->device_depth != 8) return;
|
|
||||||
|
|
||||||
for (uint32_t index = first_color; index < first_color + num_colors; index++) {
|
|
||||||
/* Clamp colors between 0.0 and 1.0 */
|
|
||||||
CGDeviceColor color;
|
|
||||||
color.red = _cur_palette.palette[index].r / 255.0;
|
|
||||||
color.blue = _cur_palette.palette[index].b / 255.0;
|
|
||||||
color.green = _cur_palette.palette[index].g / 255.0;
|
|
||||||
|
|
||||||
CGPaletteSetColorAtIndex(this->palette, color, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
CGDisplaySetPalette(this->display_id, this->palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual uint ListModes(OTTD_Point *modes, uint max_modes)
|
|
||||||
{
|
|
||||||
return QZ_ListModes(modes, max_modes, this->display_id, this->device_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (bpp != 8 && bpp != 32) error("Cocoa: This video driver only supports 8 and 32 bpp blitters.");
|
|
||||||
|
|
||||||
if (SetVideoMode(w, h, bpp)) return true;
|
|
||||||
if (old_width != 0 && old_height != 0) SetVideoMode(old_width, old_height, old_bpp);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool IsFullscreen()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int GetWidth()
|
|
||||||
{
|
|
||||||
return this->device_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int GetHeight()
|
|
||||||
{
|
|
||||||
return this->device_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void *GetPixelBuffer()
|
|
||||||
{
|
|
||||||
return this->pixel_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert local coordinate to window server (CoreGraphics) coordinate.
|
|
||||||
* In fullscreen mode this just means copying the coords.
|
|
||||||
*/
|
|
||||||
virtual CGPoint PrivateLocalToCG(NSPoint *p)
|
|
||||||
{
|
|
||||||
return CGPointMake(p->x, p->y);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual NSPoint GetMouseLocation(NSEvent *event)
|
|
||||||
{
|
|
||||||
NSPoint pt = [ NSEvent mouseLocation ];
|
|
||||||
pt.y = this->device_height - pt.y;
|
|
||||||
|
|
||||||
return pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool MouseIsInsideView(NSPoint *pt)
|
|
||||||
{
|
|
||||||
return pt->x >= 0 && pt->y >= 0 && pt->x < this->device_width && pt->y < this->device_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool IsActive()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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 nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FullscreenSubdriver *ret = new FullscreenSubdriver();
|
|
||||||
|
|
||||||
if (!ret->ChangeResolution(width, height, bpp)) {
|
|
||||||
delete ret;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_9) */
|
|
||||||
#endif /* WITH_COCOA */
|
|
@@ -17,8 +17,6 @@
|
|||||||
#include "../../stdafx.h"
|
#include "../../stdafx.h"
|
||||||
#include "../../os/macosx/macos.h"
|
#include "../../os/macosx/macos.h"
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
|
|
||||||
#define Rect OTTDRect
|
#define Rect OTTDRect
|
||||||
#define Point OTTDPoint
|
#define Point OTTDPoint
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
@@ -194,21 +192,6 @@ 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 */
|
* 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);
|
|
||||||
|
|
||||||
CFNumberGetValue(
|
|
||||||
(const __CFNumber*)CFDictionaryGetValue(cur_mode, kCGDisplayWidth),
|
|
||||||
kCFNumberSInt32Type, &this->device_width
|
|
||||||
);
|
|
||||||
|
|
||||||
CFNumberGetValue(
|
|
||||||
(const __CFNumber*)CFDictionaryGetValue(cur_mode, kCGDisplayHeight),
|
|
||||||
kCFNumberSInt32Type, &this->device_height
|
|
||||||
);
|
|
||||||
# else
|
|
||||||
/* Use the new API when compiling for OSX 10.6 or later */
|
/* Use the new API when compiling for OSX 10.6 or later */
|
||||||
CGDisplayModeRef cur_mode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
|
CGDisplayModeRef cur_mode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
|
||||||
if (cur_mode == nullptr) { return; }
|
if (cur_mode == nullptr) { return; }
|
||||||
@@ -217,7 +200,6 @@ void WindowQuartzSubdriver::GetDeviceInfo()
|
|||||||
this->device_height = CGDisplayModeGetHeight(cur_mode);
|
this->device_height = CGDisplayModeGetHeight(cur_mode);
|
||||||
|
|
||||||
CGDisplayModeRelease(cur_mode);
|
CGDisplayModeRelease(cur_mode);
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Switch to full screen mode on OSX 10.7
|
/** Switch to full screen mode on OSX 10.7
|
||||||
@@ -265,18 +247,11 @@ bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
|
||||||
/* Add built in full-screen support when available (OS X 10.7 and higher)
|
/* 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
|
* 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
|
* with the quartz fullscreen support as found only in 10.7 and later
|
||||||
*/
|
*/
|
||||||
if ([this->window respondsToSelector:@selector(toggleFullScreen:)]) {
|
if ([this->window respondsToSelector:@selector(toggleFullScreen:)]) {
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
|
|
||||||
/* Constants needed to build on pre-10.7 SDKs. Source: NSWindow documentation. */
|
|
||||||
const int NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7;
|
|
||||||
const int NSWindowFullScreenButton = 7;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NSWindowCollectionBehavior behavior = [ this->window collectionBehavior ];
|
NSWindowCollectionBehavior behavior = [ this->window collectionBehavior ];
|
||||||
behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
|
behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
|
||||||
[ this->window setCollectionBehavior:behavior ];
|
[ this->window setCollectionBehavior:behavior ];
|
||||||
@@ -287,7 +262,6 @@ bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp)
|
|||||||
|
|
||||||
[ this->window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary ];
|
[ this->window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary ];
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
[ this->window setDriver:this ];
|
[ this->window setDriver:this ];
|
||||||
|
|
||||||
@@ -303,10 +277,6 @@ bool WindowQuartzSubdriver::SetVideoMode(int width, int height, int bpp)
|
|||||||
[ this->window setAcceptsMouseMovedEvents:YES ];
|
[ this->window setAcceptsMouseMovedEvents:YES ];
|
||||||
[ this->window setViewsNeedDisplay:NO ];
|
[ this->window setViewsNeedDisplay:NO ];
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10
|
|
||||||
if ([ this->window respondsToSelector:@selector(useOptimizedDrawing:) ]) [ this->window useOptimizedDrawing:YES ];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delegate = [ [ OTTD_CocoaWindowDelegate alloc ] init ];
|
delegate = [ [ OTTD_CocoaWindowDelegate alloc ] init ];
|
||||||
[ delegate setDriver:this ];
|
[ delegate setDriver:this ];
|
||||||
[ this->window setDelegate:[ delegate autorelease ] ];
|
[ this->window setDelegate:[ delegate autorelease ] ];
|
||||||
@@ -494,17 +464,8 @@ CGPoint WindowQuartzSubdriver::PrivateLocalToCG(NSPoint *p)
|
|||||||
|
|
||||||
p->y = this->window_height - p->y;
|
p->y = this->window_height - p->y;
|
||||||
*p = [ this->cocoaview convertPoint:*p toView:nil ];
|
*p = [ this->cocoaview convertPoint:*p toView:nil ];
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
|
||||||
if ([ this->window respondsToSelector:@selector(convertRectToScreen:) ]) {
|
|
||||||
*p = [ this->window convertRectToScreen:NSMakeRect(p->x, p->y, 0, 0) ].origin;
|
*p = [ this->window convertRectToScreen:NSMakeRect(p->x, p->y, 0, 0) ].origin;
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
|
|
||||||
*p = [ this->window convertBaseToScreen:*p ];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
p->y = this->device_height - p->y;
|
p->y = this->device_height - p->y;
|
||||||
|
|
||||||
CGPoint cgp;
|
CGPoint cgp;
|
||||||
@@ -519,17 +480,7 @@ NSPoint WindowQuartzSubdriver::GetMouseLocation(NSEvent *event)
|
|||||||
NSPoint pt;
|
NSPoint pt;
|
||||||
|
|
||||||
if ( [ event window ] == nil) {
|
if ( [ event window ] == nil) {
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
|
||||||
if ([ [ this->cocoaview window ] respondsToSelector:@selector(convertRectFromScreen:) ]) {
|
|
||||||
pt = [ this->cocoaview convertPoint:[ [ this->cocoaview window ] convertRectFromScreen:NSMakeRect([ event locationInWindow ].x, [ event locationInWindow ].y, 0, 0) ].origin fromView:nil ];
|
pt = [ this->cocoaview convertPoint:[ [ this->cocoaview window ] convertRectFromScreen:NSMakeRect([ event locationInWindow ].x, [ event locationInWindow ].y, 0, 0) ].origin fromView:nil ];
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
|
|
||||||
pt = [ this->cocoaview convertPoint:[ [ this->cocoaview window ] convertScreenToBase:[ event locationInWindow ] ] fromView:nil ];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
pt = [ event locationInWindow ];
|
pt = [ event locationInWindow ];
|
||||||
}
|
}
|
||||||
@@ -609,9 +560,9 @@ bool WindowQuartzSubdriver::WindowResized()
|
|||||||
|
|
||||||
CocoaSubdriver *QZ_CreateWindowQuartzSubdriver(int width, int height, int bpp)
|
CocoaSubdriver *QZ_CreateWindowQuartzSubdriver(int width, int height, int bpp)
|
||||||
{
|
{
|
||||||
if (!MacOSVersionIsAtLeast(10, 4, 0)) {
|
if (!MacOSVersionIsAtLeast(10, 7, 0)) {
|
||||||
DEBUG(driver, 0, "The cocoa quartz subdriver requires Mac OS X 10.4 or later.");
|
DEBUG(driver, 0, "The cocoa quartz subdriver requires Mac OS X 10.7 or later.");
|
||||||
return nullptr;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpp != 8 && bpp != 32) {
|
if (bpp != 8 && bpp != 32) {
|
||||||
@@ -630,6 +581,5 @@ CocoaSubdriver *QZ_CreateWindowQuartzSubdriver(int width, int height, int bpp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 */
|
|
||||||
#endif /* ENABLE_COCOA_QUARTZ */
|
#endif /* ENABLE_COCOA_QUARTZ */
|
||||||
#endif /* WITH_COCOA */
|
#endif /* WITH_COCOA */
|
||||||
|
@@ -1,561 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Cocoa video driver *
|
|
||||||
* Known things left to do: *
|
|
||||||
* List available resolutions. *
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifdef WITH_COCOA
|
|
||||||
#ifdef ENABLE_COCOA_QUICKDRAW
|
|
||||||
|
|
||||||
#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_3
|
|
||||||
#include "../../stdafx.h"
|
|
||||||
#include "../../os/macosx/macos.h"
|
|
||||||
|
|
||||||
#define Rect OTTDRect
|
|
||||||
#define Point OTTDPoint
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#undef Rect
|
|
||||||
#undef Point
|
|
||||||
|
|
||||||
#include "../../debug.h"
|
|
||||||
#include "../../rev.h"
|
|
||||||
#include "../../core/geometry_type.hpp"
|
|
||||||
#include "cocoa_v.h"
|
|
||||||
#include "../../core/math_func.hpp"
|
|
||||||
#include "../../gfx_func.h"
|
|
||||||
#include "../../framerate_type.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Important notice regarding all modifications!!!!!!!
|
|
||||||
* There are certain limitations because the file is objective C++.
|
|
||||||
* gdb has limitations.
|
|
||||||
* C++ and objective C code can't be joined in all cases (classes stuff).
|
|
||||||
* Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class WindowQuickdrawSubdriver;
|
|
||||||
|
|
||||||
|
|
||||||
class WindowQuickdrawSubdriver : public CocoaSubdriver {
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* This function copies 32bpp pixels from the screen buffer in 16bpp windowed mode.
|
|
||||||
*
|
|
||||||
* @param left The x coord for the left edge of the box to blit.
|
|
||||||
* @param top The y coord for the top edge of the box to blit.
|
|
||||||
* @param right The x coord for the right edge of the box to blit.
|
|
||||||
* @param bottom The y coord for the bottom edge of the box to blit.
|
|
||||||
*/
|
|
||||||
void Blit32ToView32(int left, int top, int right, int bottom);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function copies 8bpp pixels from the screen buffer in 32bpp windowed mode.
|
|
||||||
*
|
|
||||||
* @param left The x coord for the left edge of the box to blit.
|
|
||||||
* @param top The y coord for the top edge of the box to blit.
|
|
||||||
* @param right The x coord for the right edge of the box to blit.
|
|
||||||
* @param bottom The y coord for the bottom edge of the box to blit.
|
|
||||||
*/
|
|
||||||
void BlitIndexedToView32(int left, int top, int right, int bottom);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function copies 8bpp pixels from the screen buffer in 16bpp windowed mode.
|
|
||||||
*
|
|
||||||
* @param left The x coord for the left edge of the box to blit.
|
|
||||||
* @param top The y coord for the top edge of the box to blit.
|
|
||||||
* @param right The x coord for the right edge of the box to blit.
|
|
||||||
* @param bottom The y coord for the bottom edge of the box to blit.
|
|
||||||
*/
|
|
||||||
void BlitIndexedToView16(int left, int top, int right, int bottom);
|
|
||||||
|
|
||||||
inline void BlitToView(int left, int top, int right, int bottom);
|
|
||||||
void DrawResizeIcon();
|
|
||||||
|
|
||||||
virtual void GetDeviceInfo();
|
|
||||||
virtual bool SetVideoMode(int width, int height, int bpp);
|
|
||||||
|
|
||||||
public:
|
|
||||||
WindowQuickdrawSubdriver();
|
|
||||||
virtual ~WindowQuickdrawSubdriver();
|
|
||||||
|
|
||||||
virtual void Draw(bool force_update);
|
|
||||||
virtual void MakeDirty(int left, int top, int width, int height);
|
|
||||||
virtual void UpdatePalette(uint first_color, uint num_colors);
|
|
||||||
|
|
||||||
virtual uint ListModes(OTTD_Point *modes, uint max_modes);
|
|
||||||
|
|
||||||
virtual bool ChangeResolution(int w, int h, int bpp);
|
|
||||||
|
|
||||||
virtual bool IsFullscreen() { return false; }
|
|
||||||
|
|
||||||
virtual int GetWidth() { return window_width; }
|
|
||||||
virtual int GetHeight() { return window_height; }
|
|
||||||
virtual void *GetPixelBuffer() { return pixel_buffer; }
|
|
||||||
|
|
||||||
/* Convert local coordinate to window server (CoreGraphics) coordinate */
|
|
||||||
virtual CGPoint PrivateLocalToCG(NSPoint *p);
|
|
||||||
|
|
||||||
virtual NSPoint GetMouseLocation(NSEvent *event);
|
|
||||||
virtual bool MouseIsInsideView(NSPoint *pt);
|
|
||||||
|
|
||||||
virtual bool IsActive() { return active; }
|
|
||||||
|
|
||||||
void SetPortAlphaOpaque();
|
|
||||||
bool WindowResized();
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int _resize_icon_width = 16;
|
|
||||||
static const int _resize_icon_height = 16;
|
|
||||||
|
|
||||||
static bool _resize_icon[] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
|
|
||||||
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
|
|
||||||
0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
|
|
||||||
0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
|
|
||||||
0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
|
|
||||||
0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
|
|
||||||
0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
|
|
||||||
1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::GetDeviceInfo()
|
|
||||||
{
|
|
||||||
/* Initialize the video settings; this data persists between mode switches */
|
|
||||||
CFDictionaryRef cur_mode = CGDisplayCurrentMode(kCGDirectMainDisplay);
|
|
||||||
|
|
||||||
/* Gather some information that is useful to know about the display */
|
|
||||||
CFNumberGetValue((const __CFNumber*)CFDictionaryGetValue(cur_mode, kCGDisplayBitsPerPixel),
|
|
||||||
kCFNumberSInt32Type, &this->device_depth);
|
|
||||||
|
|
||||||
CFNumberGetValue((const __CFNumber*)CFDictionaryGetValue(cur_mode, kCGDisplayWidth),
|
|
||||||
kCFNumberSInt32Type, &this->device_width);
|
|
||||||
|
|
||||||
CFNumberGetValue((const __CFNumber*)CFDictionaryGetValue(cur_mode, kCGDisplayHeight),
|
|
||||||
kCFNumberSInt32Type, &this->device_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowQuickdrawSubdriver::SetVideoMode(int width, int height, int bpp)
|
|
||||||
{
|
|
||||||
this->setup = true;
|
|
||||||
this->GetDeviceInfo();
|
|
||||||
|
|
||||||
if (bpp > this->device_depth) {
|
|
||||||
DEBUG(driver, 0, "Cannot use a blitter with a higher screen depth than the display when running in windowed mode.");
|
|
||||||
this->setup = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width > this->device_width) width = this->device_width;
|
|
||||||
if (height > this->device_height) height = this->device_height;
|
|
||||||
|
|
||||||
NSRect contentRect = NSMakeRect(0, 0, width, height);
|
|
||||||
|
|
||||||
/* Check if we should recreate the window */
|
|
||||||
if (this->window == nil) {
|
|
||||||
OTTD_CocoaWindowDelegate *delegate;
|
|
||||||
|
|
||||||
/* Set the window style */
|
|
||||||
unsigned int style = NSTitledWindowMask;
|
|
||||||
style |= (NSMiniaturizableWindowMask | NSClosableWindowMask);
|
|
||||||
style |= NSResizableWindowMask;
|
|
||||||
|
|
||||||
/* Manually create a window, avoids having a nib file resource */
|
|
||||||
this->window = [ [ OTTD_CocoaWindow alloc ] initWithContentRect:contentRect
|
|
||||||
styleMask:style backing:NSBackingStoreBuffered defer:NO ];
|
|
||||||
|
|
||||||
if (this->window == nil) {
|
|
||||||
DEBUG(driver, 0, "Could not create the Cocoa window.");
|
|
||||||
this->setup = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ this->window setDriver:this ];
|
|
||||||
|
|
||||||
char caption[50];
|
|
||||||
snprintf(caption, sizeof(caption), "OpenTTD %s", _openttd_revision);
|
|
||||||
NSString *nsscaption = [ [ NSString alloc ] initWithUTF8String:caption ];
|
|
||||||
[ this->window setTitle:nsscaption ];
|
|
||||||
[ this->window setMiniwindowTitle:nsscaption ];
|
|
||||||
[ nsscaption release ];
|
|
||||||
|
|
||||||
[ this->window setContentMinSize:NSMakeSize(64.0f, 64.0f) ];
|
|
||||||
|
|
||||||
[ this->window setAcceptsMouseMovedEvents:YES ];
|
|
||||||
[ this->window setViewsNeedDisplay:NO ];
|
|
||||||
|
|
||||||
delegate = [ [ OTTD_CocoaWindowDelegate alloc ] init ];
|
|
||||||
[ delegate setDriver:this ];
|
|
||||||
[ this->window setDelegate: [ delegate autorelease ] ];
|
|
||||||
} else {
|
|
||||||
/* We already have a window, just change its size */
|
|
||||||
[ this->window setContentSize:contentRect.size ];
|
|
||||||
/* Ensure frame height - title bar height >= view height
|
|
||||||
* The height of title bar of the window is 22 pixels */
|
|
||||||
contentRect.size.height = Clamp(height, 0, [ this->window frame ].size.height - 22);
|
|
||||||
height = contentRect.size.height;
|
|
||||||
[ this->cocoaview setFrameSize:contentRect.size ];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update again */
|
|
||||||
this->window_width = width;
|
|
||||||
this->window_height = height;
|
|
||||||
this->buffer_depth = bpp;
|
|
||||||
|
|
||||||
[ this->window center ];
|
|
||||||
|
|
||||||
/* Only recreate the view if it doesn't already exist */
|
|
||||||
if (this->cocoaview == nil) {
|
|
||||||
this->cocoaview = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
|
|
||||||
if (this->cocoaview == nil) {
|
|
||||||
DEBUG(driver, 0, "Could not create the Quickdraw view.");
|
|
||||||
this->setup = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ this->cocoaview setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
|
|
||||||
[ [ this->window contentView ] addSubview:this->cocoaview ];
|
|
||||||
[ this->cocoaview release ];
|
|
||||||
[ this->window makeKeyAndOrderFront:nil ];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = this->WindowResized();
|
|
||||||
this->UpdatePalette(0, 256);
|
|
||||||
|
|
||||||
this->setup = false;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::Blit32ToView32(int left, int top, int right, int bottom)
|
|
||||||
{
|
|
||||||
const uint32 *src = (uint32*)this->pixel_buffer;
|
|
||||||
uint32 *dst = (uint32*)this->window_buffer;
|
|
||||||
uint width = this->window_width;
|
|
||||||
uint pitch = this->window_pitch / 4;
|
|
||||||
|
|
||||||
dst += top * pitch + left;
|
|
||||||
src += top * width + left;
|
|
||||||
|
|
||||||
for (int y = top; y < bottom; y++, dst+= pitch, src+= width) {
|
|
||||||
memcpy(dst, src, (right - left) * 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::BlitIndexedToView32(int left, int top, int right, int bottom)
|
|
||||||
{
|
|
||||||
const uint32 *pal = this->palette;
|
|
||||||
const uint8 *src = (uint8*)this->pixel_buffer;
|
|
||||||
uint32 *dst = (uint32*)this->window_buffer;
|
|
||||||
uint width = this->window_width;
|
|
||||||
uint pitch = this->window_pitch / 4;
|
|
||||||
|
|
||||||
for (int y = top; y < bottom; y++) {
|
|
||||||
for (int x = left; x < right; x++) {
|
|
||||||
dst[y * pitch + x] = pal[src[y * width + x]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::BlitIndexedToView16(int left, int top, int right, int bottom)
|
|
||||||
{
|
|
||||||
const uint32 *pal = this->palette;
|
|
||||||
const uint8 *src = (uint8*)this->pixel_buffer;
|
|
||||||
uint16 *dst = (uint16*)this->window_buffer;
|
|
||||||
uint width = this->window_width;
|
|
||||||
uint pitch = this->window_pitch / 2;
|
|
||||||
|
|
||||||
for (int y = top; y < bottom; y++) {
|
|
||||||
for (int x = left; x < right; x++) {
|
|
||||||
dst[y * pitch + x] = pal[src[y * width + x]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline void WindowQuickdrawSubdriver::BlitToView(int left, int top, int right, int bottom)
|
|
||||||
{
|
|
||||||
switch (this->device_depth) {
|
|
||||||
case 32:
|
|
||||||
switch (this->buffer_depth) {
|
|
||||||
case 32:
|
|
||||||
this->Blit32ToView32(left, top, right, bottom);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
this->BlitIndexedToView32(left, top, right, bottom);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
this->BlitIndexedToView16(left, top, right, bottom);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::DrawResizeIcon()
|
|
||||||
{
|
|
||||||
int xoff = this->window_width - _resize_icon_width;
|
|
||||||
int yoff = this->window_height - _resize_icon_height;
|
|
||||||
|
|
||||||
switch (this->device_depth) {
|
|
||||||
case 32:
|
|
||||||
for (int y = 0; y < _resize_icon_height; y++) {
|
|
||||||
uint32 *trg = (uint32*)this->window_buffer + (yoff + y) * this->window_pitch / 4 + xoff;
|
|
||||||
|
|
||||||
for (int x = 0; x < _resize_icon_width; x++, trg++) {
|
|
||||||
if (_resize_icon[y * _resize_icon_width + x]) *trg = 0xff000000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
for (int y = 0; y < _resize_icon_height; y++) {
|
|
||||||
uint16 *trg = (uint16*)this->window_buffer + (yoff + y) * this->window_pitch / 2 + xoff;
|
|
||||||
|
|
||||||
for (int x = 0; x < _resize_icon_width; x++, trg++) {
|
|
||||||
if (_resize_icon[y * _resize_icon_width + x]) *trg = 0x0000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WindowQuickdrawSubdriver::WindowQuickdrawSubdriver()
|
|
||||||
{
|
|
||||||
this->window_width = 0;
|
|
||||||
this->window_height = 0;
|
|
||||||
this->buffer_depth = 0;
|
|
||||||
this->pixel_buffer = nullptr;
|
|
||||||
this->active = false;
|
|
||||||
this->setup = false;
|
|
||||||
|
|
||||||
this->window = nil;
|
|
||||||
this->cocoaview = nil;
|
|
||||||
|
|
||||||
this->num_dirty_rects = MAX_DIRTY_RECTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowQuickdrawSubdriver::~WindowQuickdrawSubdriver()
|
|
||||||
{
|
|
||||||
/* Release window mode resources */
|
|
||||||
if (this->window != nil) [ this->window close ];
|
|
||||||
|
|
||||||
free(this->pixel_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::Draw(bool force_update)
|
|
||||||
{
|
|
||||||
PerformanceMeasurer framerate(PFE_VIDEO);
|
|
||||||
|
|
||||||
/* Check if we need to do anything */
|
|
||||||
if (this->num_dirty_rects == 0 || [ this->window isMiniaturized ]) return;
|
|
||||||
|
|
||||||
if (this->num_dirty_rects >= MAX_DIRTY_RECTS) {
|
|
||||||
this->num_dirty_rects = 1;
|
|
||||||
this->dirty_rects[0].left = 0;
|
|
||||||
this->dirty_rects[0].top = 0;
|
|
||||||
this->dirty_rects[0].right = this->window_width;
|
|
||||||
this->dirty_rects[0].bottom = this->window_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
RgnHandle dirty = NewRgn();
|
|
||||||
RgnHandle temp = NewRgn();
|
|
||||||
|
|
||||||
SetEmptyRgn(dirty);
|
|
||||||
|
|
||||||
/* Build the region of dirty rectangles */
|
|
||||||
for (int i = 0; i < this->num_dirty_rects; i++) {
|
|
||||||
this->BlitToView(this->dirty_rects[i].left, this->dirty_rects[i].top,
|
|
||||||
this->dirty_rects[i].right, this->dirty_rects[i].bottom);
|
|
||||||
|
|
||||||
MacSetRectRgn(temp, this->dirty_rects[i].left, this->dirty_rects[i].top,
|
|
||||||
this->dirty_rects[i].right, this->dirty_rects[i].bottom);
|
|
||||||
MacUnionRgn(dirty, temp, dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->DrawResizeIcon();
|
|
||||||
|
|
||||||
/* Flush the dirty region */
|
|
||||||
QDFlushPortBuffer( (OpaqueGrafPtr*) [ this->cocoaview qdPort ], dirty);
|
|
||||||
DisposeRgn(dirty);
|
|
||||||
DisposeRgn(temp);
|
|
||||||
|
|
||||||
this->num_dirty_rects = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::MakeDirty(int left, int top, int width, int height)
|
|
||||||
{
|
|
||||||
if (this->num_dirty_rects < MAX_DIRTY_RECTS) {
|
|
||||||
this->dirty_rects[this->num_dirty_rects].left = left;
|
|
||||||
this->dirty_rects[this->num_dirty_rects].top = top;
|
|
||||||
this->dirty_rects[this->num_dirty_rects].right = left + width;
|
|
||||||
this->dirty_rects[this->num_dirty_rects].bottom = top + height;
|
|
||||||
}
|
|
||||||
this->num_dirty_rects++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowQuickdrawSubdriver::UpdatePalette(uint first_color, uint num_colors)
|
|
||||||
{
|
|
||||||
if (this->buffer_depth != 8) return;
|
|
||||||
|
|
||||||
switch (this->device_depth) {
|
|
||||||
case 32:
|
|
||||||
for (uint i = first_color; i < first_color + num_colors; i++) {
|
|
||||||
uint32 clr32 = 0xff000000;
|
|
||||||
clr32 |= (uint32)_cur_palette.palette[i].r << 16;
|
|
||||||
clr32 |= (uint32)_cur_palette.palette[i].g << 8;
|
|
||||||
clr32 |= (uint32)_cur_palette.palette[i].b;
|
|
||||||
this->palette[i] = clr32;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
for (uint i = first_color; i < first_color + num_colors; i++) {
|
|
||||||
uint16 clr16 = 0x0000;
|
|
||||||
clr16 |= (uint16)((_cur_palette.palette[i].r >> 3) & 0x1f) << 10;
|
|
||||||
clr16 |= (uint16)((_cur_palette.palette[i].g >> 3) & 0x1f) << 5;
|
|
||||||
clr16 |= (uint16)((_cur_palette.palette[i].b >> 3) & 0x1f);
|
|
||||||
this->palette[i] = clr16;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->num_dirty_rects = MAX_DIRTY_RECTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint WindowQuickdrawSubdriver::ListModes(OTTD_Point *modes, uint max_modes)
|
|
||||||
{
|
|
||||||
return QZ_ListModes(modes, max_modes, kCGDirectMainDisplay, this->buffer_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
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, bpp)) return true;
|
|
||||||
|
|
||||||
if (old_width != 0 && old_height != 0) this->SetVideoMode(old_width, old_height, old_bpp);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert local coordinate to window server (CoreGraphics) coordinate */
|
|
||||||
CGPoint WindowQuickdrawSubdriver::PrivateLocalToCG(NSPoint *p)
|
|
||||||
{
|
|
||||||
*p = [ this->cocoaview convertPoint:*p toView: nil ];
|
|
||||||
*p = [ this->window convertBaseToScreen:*p ];
|
|
||||||
p->y = this->device_height - p->y;
|
|
||||||
|
|
||||||
return CGPointMake(p->x, p->y);
|
|
||||||
}
|
|
||||||
|
|
||||||
NSPoint WindowQuickdrawSubdriver::GetMouseLocation(NSEvent *event)
|
|
||||||
{
|
|
||||||
NSPoint pt = [ event locationInWindow ];
|
|
||||||
pt = [ this->cocoaview convertPoint:pt fromView:nil ];
|
|
||||||
|
|
||||||
return pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowQuickdrawSubdriver::MouseIsInsideView(NSPoint *pt)
|
|
||||||
{
|
|
||||||
return [ this->cocoaview mouse:*pt inRect:[ this->cocoaview bounds ] ];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This function makes the *game region* of the window 100% opaque.
|
|
||||||
* The genie effect uses the alpha component. Otherwise,
|
|
||||||
* it doesn't seem to matter what value it has.
|
|
||||||
*/
|
|
||||||
void WindowQuickdrawSubdriver::SetPortAlphaOpaque()
|
|
||||||
{
|
|
||||||
if (this->device_depth != 32) return;
|
|
||||||
|
|
||||||
uint32 *pixels = (uint32*)this->window_buffer;
|
|
||||||
uint32 pitch = this->window_pitch / 4;
|
|
||||||
|
|
||||||
for (int y = 0; y < this->window_height; y++)
|
|
||||||
for (int x = 0; x < this->window_width; x++) {
|
|
||||||
pixels[y * pitch + x] |= 0xFF000000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WindowQuickdrawSubdriver::WindowResized()
|
|
||||||
{
|
|
||||||
if (this->window == nil || this->cocoaview == nil) return true;
|
|
||||||
|
|
||||||
NSRect newframe = [ this->cocoaview frame ];
|
|
||||||
CGrafPtr thePort = (OpaqueGrafPtr*) [ this->cocoaview qdPort ];
|
|
||||||
|
|
||||||
LockPortBits(thePort);
|
|
||||||
this->window_buffer = GetPixBaseAddr(GetPortPixMap(thePort));
|
|
||||||
this->window_pitch = GetPixRowBytes(GetPortPixMap(thePort));
|
|
||||||
UnlockPortBits(thePort);
|
|
||||||
|
|
||||||
/* _cocoa_video_data.realpixels now points to the window's pixels
|
|
||||||
* We want it to point to the *view's* pixels
|
|
||||||
*/
|
|
||||||
int voff = [ this->window frame ].size.height - newframe.size.height - newframe.origin.y;
|
|
||||||
int hoff = [ this->cocoaview frame ].origin.x;
|
|
||||||
this->window_buffer = (uint8*)this->window_buffer + (voff * this->window_pitch) + hoff * (this->device_depth / 8);
|
|
||||||
|
|
||||||
this->window_width = newframe.size.width;
|
|
||||||
this->window_height = newframe.size.height;
|
|
||||||
|
|
||||||
free(this->pixel_buffer);
|
|
||||||
this->pixel_buffer = malloc(this->window_width * this->window_height * this->buffer_depth / 8);
|
|
||||||
if (this->pixel_buffer == nullptr) {
|
|
||||||
DEBUG(driver, 0, "Failed to allocate pixel buffer");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QZ_GameSizeChanged();
|
|
||||||
|
|
||||||
/* Redraw screen */
|
|
||||||
this->num_dirty_rects = MAX_DIRTY_RECTS;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CocoaSubdriver *QZ_CreateWindowQuickdrawSubdriver(int width, int height, int bpp)
|
|
||||||
{
|
|
||||||
WindowQuickdrawSubdriver *ret;
|
|
||||||
|
|
||||||
if (MacOSVersionIsAtLeast(10, 5, 0)) {
|
|
||||||
DEBUG(driver, 0, "The cocoa quickdraw subdriver is not recommended for Mac OS X 10.5 or later.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bpp != 8 && bpp != 32) {
|
|
||||||
DEBUG(driver, 0, "The cocoa quickdraw subdriver only supports 8 and 32 bpp.");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = new WindowQuickdrawSubdriver();
|
|
||||||
|
|
||||||
if (!ret->ChangeResolution(width, height, bpp)) {
|
|
||||||
delete ret;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* ENABLE_COCOA_QUICKDRAW */
|
|
||||||
#endif /* WITH_COCOA */
|
|
Reference in New Issue
Block a user