(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.
This commit is contained in:
29
src/os/macosx/G5_detector.c
Normal file
29
src/os/macosx/G5_detector.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/* $Id$ */
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/host_info.h>
|
||||
#include <mach/machine.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#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");
|
||||
}
|
30
src/os/macosx/macos.h
Normal file
30
src/os/macosx/macos.h
Normal file
@@ -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 */
|
162
src/os/macosx/macos.m
Normal file
162
src/os/macosx/macos.m
Normal file
@@ -0,0 +1,162 @@
|
||||
/* $Id$ */
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/host_info.h>
|
||||
#include <mach/machine.h>
|
||||
#include <stdio.h>
|
||||
#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();
|
||||
}
|
19
src/os/macosx/osx_stdafx.h
Normal file
19
src/os/macosx/osx_stdafx.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef MACOS_STDAFX_H
|
||||
#define MACOS_STDAFX_H
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
// 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 */
|
144
src/os/macosx/splash.c
Normal file
144
src/os/macosx/splash.c
Normal file
@@ -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 <png.h>
|
||||
|
||||
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 */
|
10
src/os/macosx/splash.h
Normal file
10
src/os/macosx/splash.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef SPLASH_H
|
||||
#define SPLASH_H
|
||||
|
||||
#define SPLASH_IMAGE_FILE "splash.png"
|
||||
|
||||
void DisplaySplashImage(void);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user