From 013df98f79866a75f367853c9e436f3c5c79f645 Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 2 Jan 2007 19:19:48 +0000 Subject: (svn r7759) -Merge: makefile rewrite. This merge features: - A proper ./configure, so everything needs to be configured only once, not for every make. - Usage of makedepend when available. This greatly reduces the time needed for generating the dependencies. - A generator for all project files. There is a single file with sources, which is used to generate Makefiles and the project files for MSVC. - Proper support for OSX universal binaries. - Object files for non-MSVC compiles are also placed in separate directories, making is faster to switch between debug and release compiles and it does not touch the directory with the source files. - Functionality to make a bundle of all needed files for for example a nightly or distribution of a binary with all needed GRFs and language files. Note: as this merge moves almost all files, it is recommended to make a backup of your working copy before updating your working copy. --- src/os/macosx/G5_detector.c | 29 ++++++++ src/os/macosx/macos.h | 30 ++++++++ src/os/macosx/macos.m | 162 ++++++++++++++++++++++++++++++++++++++++++++ src/os/macosx/osx_stdafx.h | 19 ++++++ src/os/macosx/splash.c | 144 +++++++++++++++++++++++++++++++++++++++ src/os/macosx/splash.h | 10 +++ 6 files changed, 394 insertions(+) create mode 100644 src/os/macosx/G5_detector.c create mode 100644 src/os/macosx/macos.h create mode 100644 src/os/macosx/macos.m create mode 100644 src/os/macosx/osx_stdafx.h create mode 100644 src/os/macosx/splash.c create mode 100644 src/os/macosx/splash.h (limited to 'src/os/macosx') diff --git a/src/os/macosx/G5_detector.c b/src/os/macosx/G5_detector.c new file mode 100644 index 000000000..b4831c772 --- /dev/null +++ b/src/os/macosx/G5_detector.c @@ -0,0 +1,29 @@ +/* $Id$ */ + +#include +#include +#include +#include +#include + + +#ifndef CPU_SUBTYPE_POWERPC_970 +#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) +#endif + +// this function is a lightly modified version of some code from Apple's developer homepage to detect G5 CPUs at runtime +main() +{ + host_basic_info_data_t hostInfo; + mach_msg_type_number_t infoCount; + boolean_t is_G5; + + infoCount = HOST_BASIC_INFO_COUNT; + host_info(mach_host_self(), HOST_BASIC_INFO, + (host_info_t)&hostInfo, &infoCount); + + is_G5 = ((hostInfo.cpu_type == CPU_TYPE_POWERPC) && + (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970)); + if (is_G5) + printf("1"); +} diff --git a/src/os/macosx/macos.h b/src/os/macosx/macos.h new file mode 100644 index 000000000..b8a6cd511 --- /dev/null +++ b/src/os/macosx/macos.h @@ -0,0 +1,30 @@ +/* $Id$ */ + +#ifndef MACOS_H +#define MACOS_H + +/* + * Functions to show the popup window + * use ShowMacDialog when you want to control title, message and text on the button + * ShowMacAssertDialog is used by assert + * ShowMacErrorDialog should be used when an unrecoverable error shows up. It only contains the title, which will should tell what went wrong + * the function then adds text that tells the user to update and then report the bug if it's present in the newest version + * It also quits in a nice way since we call it when we know something happened that will crash OpenTTD (like a needed pointer turns out to be NULL or similar) + */ +void ShowMacDialog ( const char *title, const char *message, const char *buttonLabel ); +void ShowMacAssertDialog ( const char *function, const char *file, const int line, const char *expression ); +void ShowMacErrorDialog(const char *error); + +// Since MacOS X users will never see an assert unless they started the game from a terminal +// we're using a custom assert(e) macro. +#undef assert + +#ifdef NDEBUG +#define assert(e) ((void)0) +#else + +#define assert(e) \ + (__builtin_expect(!(e), 0) ? ShowMacAssertDialog ( __func__, __FILE__, __LINE__, #e ): (void)0 ) +#endif + +#endif /* MACOS_H */ diff --git a/src/os/macosx/macos.m b/src/os/macosx/macos.m new file mode 100644 index 000000000..59801fce0 --- /dev/null +++ b/src/os/macosx/macos.m @@ -0,0 +1,162 @@ +/* $Id$ */ + +#include + +#include +#include +#include +#include +#include +#include "../../stdafx.h" +#include "../../openttd.h" +#include "../../newgrf.h" +#include "../../gfx.h" +#include "../../macros.h" +#include "../../string.h" + +#ifndef CPU_SUBTYPE_POWERPC_970 +#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) +#endif + +/* + * This file contains objective C + * Apple uses objective C instead of plain C to interact with OS specific/native functions + * + * Note: TrueLight's crosscompiler can handle this, but it likely needs a manual modification for each change in this file. + * To insure that the crosscompiler still works, let him try any changes before they are committed + */ + +static char *GetOSString(void) +{ + static char buffer[175]; + const char* CPU; + char OS[20]; + char newgrf[125]; + long sysVersion; + extern const char _openttd_revision[]; + + // get the hardware info + host_basic_info_data_t hostInfo; + mach_msg_type_number_t infoCount; + + infoCount = HOST_BASIC_INFO_COUNT; + host_info( + mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount + ); + + // replace the hardware info with strings, that tells a bit more than just an int + switch (hostInfo.cpu_subtype) { +#ifdef __POWERPC__ + case CPU_SUBTYPE_POWERPC_750: CPU = "G3"; break; + case CPU_SUBTYPE_POWERPC_7400: + case CPU_SUBTYPE_POWERPC_7450: CPU = "G4"; break; + case CPU_SUBTYPE_POWERPC_970: CPU = "G5"; break; + default: CPU = "Unknown PPC"; break; +#else + /* it looks odd to have a switch for two cases, but it leaves room for easy + * expansion. Odds are that Apple will some day use newer CPUs than i686 + */ + case CPU_SUBTYPE_PENTPRO: CPU = "i686"; break; + default: CPU = "Unknown Intel"; break; +#endif + } + + // get the version of OSX + if (Gestalt(gestaltSystemVersion, &sysVersion) != noErr) { + sprintf(OS, "Undetected"); + } else { + int majorHiNib = GB(sysVersion, 12, 4); + int majorLoNib = GB(sysVersion, 8, 4); + int minorNib = GB(sysVersion, 4, 4); + int bugNib = GB(sysVersion, 0, 4); + + sprintf(OS, "%d%d.%d.%d", majorHiNib, majorLoNib, minorNib, bugNib); + } + + // make a list of used newgrf files + if (_first_grffile != NULL) { + char* n = newgrf; + const GRFFile* file; + + for (file = _first_grffile; file != NULL; file = file->next) { + n = strecpy(n, " ", lastof(newgrf)); + n = strecpy(n, file->filename, lastof(newgrf)); + } + } else { + sprintf(newgrf, "none"); + } + + snprintf( + buffer, lengthof(buffer), + "Please add this info: (tip: copy-paste works)\n" + "CPU: %s, OSX: %s, OpenTTD version: %s\n" + "NewGRF files:%s", + CPU, OS, _openttd_revision, newgrf + ); + return buffer; +} + + +#ifdef WITH_SDL + +void ShowMacDialog(const char* title, const char* message, const char* buttonLabel) +{ + NSRunAlertPanel([NSString stringWithCString: title], [NSString stringWithCString: message], [NSString stringWithCString: buttonLabel], nil, nil); +} + +#elif defined WITH_COCOA + +void CocoaDialog(const char* title, const char* message, const char* buttonLabel); + +void ShowMacDialog(const char* title, const char* message, const char* buttonLabel) +{ + CocoaDialog(title, message, buttonLabel); +} + + +#else + +void ShowMacDialog(const char* title, const char* message, const char* buttonLabel) +{ + fprintf(stderr, "%s: %s\n", title, message); +} + +#endif + +void ShowMacAssertDialog(const char* function, const char* file, const int line, const char* expression) +{ + const char* buffer = + [[NSString stringWithFormat:@ + "An assertion has failed and OpenTTD must quit.\n" + "%s in %s (line %d)\n" + "\"%s\"\n" + "\n" + "You should report this error the OpenTTD developers if you think you found a bug.\n" + "\n" + "%s", + function, file, line, expression, GetOSString()] cString + ]; + NSLog(@"%s", buffer); + ToggleFullScreen(0); + ShowMacDialog("Assertion Failed", buffer, "Quit"); + + // abort so that a debugger has a chance to notice + abort(); +} + + +void ShowMacErrorDialog(const char *error) +{ + const char* buffer = + [[NSString stringWithFormat:@ + "Please update to the newest version of OpenTTD\n" + "If the problem presists, please report this to\n" + "http://bugs.openttd.org\n" + "\n" + "%s", + GetOSString()] cString + ]; + ToggleFullScreen(0); + ShowMacDialog(error, buffer, "Quit"); + abort(); +} diff --git a/src/os/macosx/osx_stdafx.h b/src/os/macosx/osx_stdafx.h new file mode 100644 index 000000000..9567d70ba --- /dev/null +++ b/src/os/macosx/osx_stdafx.h @@ -0,0 +1,19 @@ +/* $Id$ */ + +#ifndef MACOS_STDAFX_H +#define MACOS_STDAFX_H + +#include +// remove the variables that CoreServices defines, but we define ourselves too +#undef bool +#undef false +#undef true + +/* Name conflict */ +#define Rect OTTDRect +#define Point OTTDPoint +#define GetTime OTTDGetTime + +#define SL_ERROR OSX_SL_ERROR + +#endif /* MACOS_STDAFX_H */ diff --git a/src/os/macosx/splash.c b/src/os/macosx/splash.c new file mode 100644 index 000000000..46a19b1a6 --- /dev/null +++ b/src/os/macosx/splash.c @@ -0,0 +1,144 @@ +/* $Id$ */ + +#include "../../stdafx.h" +#include "../../openttd.h" +#include "../../variables.h" +#include "../../macros.h" +#include "../../debug.h" +#include "../../functions.h" +#include "../../gfx.h" +#include "../../fileio.h" + +#include "splash.h" + +#ifdef WITH_PNG + +#include + +static void PNGAPI png_my_error(png_structp png_ptr, png_const_charp message) +{ + DEBUG(misc, 0, "[libpng] error: %s - %s", message, (char *)png_get_error_ptr(png_ptr)); + longjmp(png_ptr->jmpbuf, 1); +} + +static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message) +{ + DEBUG(misc, 1, "[libpng] warning: %s - %s", message, (char *)png_get_error_ptr(png_ptr)); +} + +void DisplaySplashImage(void) +{ + png_byte header[8]; + FILE *f; + png_structp png_ptr; + png_infop info_ptr, end_info; + uint width, height, bit_depth, color_type; + png_colorp palette; + int num_palette; + png_bytep *row_pointers; + uint8 *src, *dst; + uint y; + uint xoff, yoff; + int i; + + f = FioFOpenFile(SPLASH_IMAGE_FILE); + if (f == NULL) return; + + fread(header, 1, 8, f); + if (png_sig_cmp(header, 0, 8) != 0) { + fclose(f); + return; + } + + png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning); + + if (png_ptr == NULL) { + fclose(f); + return; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + fclose(f); + return; + } + + end_info = png_create_info_struct(png_ptr); + if (end_info == NULL) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + fclose(f); + return; + } + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(f); + return; + } + + png_init_io(png_ptr, f); + png_set_sig_bytes(png_ptr, 8); + + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + width = png_get_image_width(png_ptr, info_ptr); + height = png_get_image_height(png_ptr, info_ptr); + bit_depth = png_get_bit_depth(png_ptr, info_ptr); + color_type = png_get_color_type(png_ptr, info_ptr); + + if (color_type != PNG_COLOR_TYPE_PALETTE || bit_depth != 8) { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(f); + return; + } + + if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(f); + return; + } + + png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); + + row_pointers = png_get_rows(png_ptr, info_ptr); + + memset(_screen.dst_ptr, 0xff, _screen.pitch * _screen.height); + + if (width > (uint) _screen.width) width = _screen.width; + if (height > (uint) _screen.height) height = _screen.height; + + xoff = (_screen.width - width) / 2; + yoff = (_screen.height - height) / 2; + for (y = 0; y < height; y++) { + src = row_pointers[y]; + dst = ((uint8 *) _screen.dst_ptr) + (yoff + y) * _screen.pitch + xoff; + + memcpy(dst, src, width); + } + + for (i = 0; i < num_palette; i++) { + _cur_palette[i].r = palette[i].red; + _cur_palette[i].g = palette[i].green; + _cur_palette[i].b = palette[i].blue; + } + + _cur_palette[0xff].r = 0; + _cur_palette[0xff].g = 0; + _cur_palette[0xff].b = 0; + + _pal_first_dirty = 0; + _pal_last_dirty = 0xff; + + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(f); + return; +} + + + +#else /* WITH_PNG */ + +void DisplaySplashImage(void) {} + +#endif /* WITH_PNG */ diff --git a/src/os/macosx/splash.h b/src/os/macosx/splash.h new file mode 100644 index 000000000..39880562d --- /dev/null +++ b/src/os/macosx/splash.h @@ -0,0 +1,10 @@ +/* $Id$ */ + +#ifndef SPLASH_H +#define SPLASH_H + +#define SPLASH_IMAGE_FILE "splash.png" + +void DisplaySplashImage(void); + +#endif -- cgit v1.2.3-54-g00ecf