SDL Digest, Vol 4, Issue 16

The application’s only peculiarity is the use of Cocotron
http://www.cocotron.org’s Foundation framework and Objective-C
runtime. It does not use OpenGL. All it does is SDL_Init, load a BMP,
then while(!done) blit a BMP onto the screen, flip.

Do the SDL test programs crash as well? I haven’t had any problems on Vista.

They do, but the only DLL that exhibits this behaviour is the
precompiled one in the 1.2 stable download page. Recompiling my own
via mingw from 1.2 HEAD seems to work perfectly, both using windib and
directx. So, fixed.

I also have found a bug relating to the precompiled SDL.framework for
OS X and autorelease pools – the Objective-C windows and delegates
used to implement the Quartz driver are not retained properly, and
creating/releasing an autorelease pool causes the application to
crash. Of course this only happens if the game is Objective-C and uses
its own autorelease pools, rather than pure C. I have a workaround for
it (posted below), but I haven’t had the time to recompile my own OS X
frameworks from HEAD, so I don’t know if it’s fixed already.

– workaround –

=== in main.m:

#import “SDLAutoreleaseBugFix.h”

/* … in main() before creating the first autorelease pool … */

#ifdef APPLE // no need for it on win32 or x11
[SDLAutoreleaseBugFix activateBugFix];
#endif

NSAutoreleasePool* pool = [NSAutoreleasePool new]; //

=== in SDLAutoreleaseBugFix.h:

#import <Cocoa/Cocoa.h>

@interface SDLAutoreleaseBugFix : NSAutoreleasePool {

}

  • (void) activateBugFix;

@end

=== in SDLAutoreleaseBugFix.m:

#import “SDLAutoreleaseBugFix.h”
#import <objc/objc-class.h>
#import <string.h>

// This file is only compiled in the application in the MacOS target;
// Windows and Linux targets do not need it.

@implementation SDLAutoreleaseBugFix

  • (void) activateBugFix {
    [self poseAsClass:[NSAutoreleasePool class]];
    }
  • (void) addObject:(id) object {
    // we use string.h because using NSStringFromClass would autorelease
    // the string and cause -addObject: to be called again, an infinite loop.

    struct objc_class* c = (struct objc_class*) [object class];

    if (c && strnstr(c->name, “SDL_”, 4) != NULL)
    [object retain];

    [super addObject:object];
    }

@end

  • ev