Modifications to external libraries' source code for running Oolite
-------------------------------------------------------------------

The various ports of Oolite are using a number of external libraries for graphics, sound, input and event handling. Throughout development, certain changes to the source code of these libraries have been deemed necessary, either to enable Oolite to run in a more efficient and independent manner, or simply to fix issues that occurred as a result of these external libraries themselves. Of these libraries, the ones that have to be rebuilt specifically for Oolite, together with the main reasons/areas changed for this reason are:

1. gnustep-base v1.20.1 (Windows) - bug in NSInteger definition, change to dictionary format of NSUserDefaults, fix for integer truncation of integers to 32-bit when parsing XML plists (bug #32495 on the gnustep.org bugtracker) and changes to facilitate native Obj-C exceptions support. Also, fix bug in the stack grabbing code at NSDebug.m so that correct stack traces can be obtained also on Windows XP and later.
2. SDL v1.2.13 - (Windows) window resizing issues, backported fix for setting gamma crash.
3. SpiderMonkey v1.85 (all platforms) - certain JS macro definitions required by Oolite not guaranteed or non-existent in standard library.
4. eSpeak v1.43.03 (Windows) - Special build of the Windows speech synthesis libespeak.dll to enable asynchronous playback. Also, defaults the eSpeak data directory to Resources/espeak-data.

The changes made in the source code of each of these libraries are as follows:

1. gnustep-base v1.20.1 (Windows)

- GSConfig.h (build generated file): In the section reading
/*
 * Integer type with same size as a pointer
 */
typedef	unsigned int gsuaddr;
typedef	int gssaddr;
typedef	gsuaddr gsaddr;

Change
typedef	gsuaddr gsaddr;
to
typedef	gssaddr gsaddr;
to fix incorrect definition of NSInteger. 

- The NSUserDefaults system dictionary (.GNUstepDefaults) is written in XML format in GNUstep 1.20.1. This is inconvenient for Oolite, where the more human-friendly OpenStep format for plists is used. The static BOOL writeDictionary(NSDictionary *dict, NSString *file) function, at around line 157 of the NSUserDefaults.m file is therefore changed to read as below:
data = [NSPropertyListSerialization dataFromPropertyList: dict
	       //format: NSPropertyListXMLFormat_v1_0  // no XML format, use OpenStep istead
	       format: NSPropertyListOpenStepFormat
	       errorDescription: &err];
	       
- When parsing XML plists, integers are truncated to 32-bit, effectively prohibiting the correct parsing of long long or unsigned long long values. The fix applied in the gnustep-base-1_20.dll distributed with Oolite in order to address this is:
a) Changing line 309 of NSPropertyList.m of the GNUstep base source code distribution from
ASSIGN(plist, [NSNumber numberWithInt: [value intValue]]);
to
ASSIGN(plist, [NSNumber numberWithLongLong: [value longLongValue]]);
and b) Changing line 1103 of the same file from
result = [[NSNumber alloc] initWithLong: atol(buf)];
to
result = [[NSNumber alloc] initWithLongLong: atoll(buf)];

- The stack backtrace grabbing code in NSDebug.m works for Linux but fails on Windows. The GSPrivateStackAddresses function has been modified to use the WinAPI CaptureStackBacktrace method, so that it returns a correct stack backtrace also on Windows (64-bit only, 32-bit version not modified because we want to keep backwards compatibility as much as possible). The modified function is as follows:
NSMutableArray * GSPrivateStackAddresses(void)
{
  NSMutableArray        *stack;
  NSAutoreleasePool     *pool;

#if HAVE_BACKTRACE
  void                  *addresses[1024];
  int                   n = backtrace(addresses, 1024);
  int                   i;

  stack = [NSMutableArray arrayWithCapacity: n];
  pool = [NSAutoreleasePool new];
  for (i = 0; i < n; i++)
    {
      [stack addObject: [NSValue valueWithPointer: addresses[i]]];
    }
#else	// Windows code here
  unsigned              i;
  const int				kMaxCallers = 62;
  void*					callers[kMaxCallers];
  unsigned              n = CaptureStackBackTrace(0, kMaxCallers, callers, NULL);

  stack = [NSMutableArray arrayWithCapacity: n];
  pool = [NSAutoreleasePool new];
  for (i = 0; i < n; i++)
  {
	[stack addObject: [NSValue valueWithPointer: callers[i]]];
  }
#endif	// HAVE_BACKTRACE
  RELEASE(pool);
  return stack;
}

- The GNUstep objc-1.dll runtime has been rebuilt with native Obj-C exception support. To do this on Windows, the patch which provides the void (*_objc_unexpected_exception) (id exception) callback hook to the runtime is required for versions of gcc older than 4.4.0. The patch can be downloaded from http://gcc.gnu.org/bugzilla/attachment.cgi?id=17365. Also, the gcc source header unwind-pe.h must be visible to exception.c in order for the build of libobjc to succeed.

The full source code of GNUstep 1.20.1 is available from
ftp://ftp.gnustep.org/pub/gnustep/core/gnustep-base-1.20.1.tar.gz



2. SDL v1.2.13 (Windows)

- SDL_resize.c:57: Added the lines
#ifdef __WIN32__
	SDL_VideoSurface->w = w;
	SDL_VideoSurface->h = h;
#endif
to enable window resizing without side effects like texture corruption in the Windows port of Oolite. The entire source of the modified SDL library is included in the source distribution of the game under <source code installation folder>/deps/Cross-platform-deps/SDL/SDL-1.2.13.zip

- SDL_dibvideo.c:768: Changed from
/* BitBlt() maps colors for us */
video->flags |= SDL_HWPALETTE;
to
if ( screen_pal )
{
	/* BitBlt() maps colors for us */
	video->flags |= SDL_HWPALETTE;
}
to fix crash occuring when attempting to set the screen gamma value. This fix occured in a later version of SDL and was backported to the version used with the Windows port of Oolite.




3. SpiderMonkey v1.85 (all platforms)

- Specific build settings for Oolite are required. Library rebuilt with the following macros defined as shown below:
	JS_THREADSAFE defined on Mac and Linux debug builds.
	MOZ_TRACE_JSCALLS defined in order to enable full JavaScript profiling.
The entire source code of the library can be downloaded from ftp://anonymous@ftp.mozilla.org/pub/firefox/releases/4.0/source/firefox-4.0.source.tar.bz2



4. eSpeak v1.43.03 (Windows)

- The libespeak.dll has been custom-built for the Windows port of Oolite to enable asynchronous playback and to also default the eSpeak data files folder to Resources/espeak-data. The source files that need to be changed for this to happen can be found inside deps/Windows-x86-deps/OOeSpeakWin32DLLBuild. The instructions for building this library, for those interested, are as follows:
  - You will need to have OoliteDevelopmentEnvironment - Light Edition installed, downloadable from http://terrastorage.dyndns.info/Marmagka/c0a11a8fe8b5124823a91ff1d90065ff/OoliteDevelopmentEnvironment_LE_20110212.zip. Instructions for setting it up can be found at http://www.aegidian.org/bb/viewtopic.php?t=5943.
  - Download espeak-1.43.03-source.zip from http://espeak.sourceforge.net/download.html
  - Unzip the file to a folder of choice, maintaining the directory structure. We'll refer to this folder as <espeakSourceFolder>.
  - Copy the files
	Makefile
	gettimeofday.c
	speak_lib.cpp
	speech.h
    from deps/Windows-x86-deps/OOeSpeakWin32DLLBuild to <espeakSourceFolder>/src.
  - Rename the file <eSpeakSourceFolder>/src/portaudio19.h to portaudio.h.
  - Copy the file speak_lib.h from <espeakSourceFolder>/platforms/windows/windows_dll/src to <espeakSourceFolder>/src.
  - Start up MinGW/MSYS and change working directory to the <espeakSourceFolder>/src folder.
  - Execute 'make libespeak.dll' from the command prompt.
  - The library should compile and at the end of the build you should have a file named libespeak.dll (the actual binary) and the import library file libespeak.dll.a, for use when you want to link libespeak.dll to your project.




Certain other Oolite dependencies are built with specific project settings on the Mac platform, without further changes to their source code. These libraries are libpng (uses also a custom pngusr.h header for the Mac version) and libogg/libvorbis. Also, the Mac debug support uses a modified version of RBSplitView, mostly to enable it to build on 64-bit Mac OS X.
