• Hello MLAers! We've re-enabled auto-approval for accounts. If you are still waiting on account approval, please check this thread for more information.

SDL2 for classic MacOS "rough draft"

lauland1

6502

Very very rough port to classic MacOS, but tests work. Despite the current name (which I'll be changing), also runs on M68k 7.6.

I created a video driver (which also handles events, only Command Q for now). Basic drawing works, but ALL other drivers are dummy.

Debug output in stderr.txt.
 

Very very rough port to classic MacOS, but tests work. Despite the current name (which I'll be changing), also runs on M68k 7.6.

I created a video driver (which also handles events, only Command Q for now). Basic drawing works, but ALL other drivers are dummy.

Debug output in stderr.txt.
Very interesting!
 
This is so insanely exciting. I'm working on a game in Godot and wanted to look into backporting it after I was done with it, and was *not* looking forwards to having to make my own renderer. Being able to use SDL2 will make it so much easier!
 
@lauland1 or others: has anyone ever thought of making an app outside of MPW that provides a syslog-type capability for classic Macs? I'm thinking something that provides a toolbox call people could "pipe" to instead of "stdout" or a locally defined filehandle. Such a thing could also log apple events for newer operating systems, and possibly ride on the back of the interfaces that were added for AppleScript which does have a similar system, but limited to the AppleScript environment.
 
Looks like YOU thought of it! That's a very good idea, but hard to visualize the final form and extent.

It could build on DebugStr, and trap those messages to a log instead of the debugger. (So a decent toolbox call already exists). Would be lovely if it could replace not just MPW's standard IO, but also its SIOW and CodeWarrior's SIOUX. (But for that you'd probably need to patch existing apps, as they're link time libraries).

Ideally, something like a standardized classic Mac console for stdin and stdout, with stderr going to a file. Maybe realistically this would take the form of a drop in compatible replacement for what I mentioned above. Such a beast would be lovely to have if anyone actually wrote it.

The way SDL 1.2 for classic mac handles this is to redirect the standard IO file descriptors early in main(), so I'm trying the same thing for SDL2. It seems to mostly work. The trick is that Retro68's console is messy, requires C++, and is optional. I was avoiding it because it might have other implications for whatever main() does.

I'm making SDL_main() optional for now. It is a fake main() that sits in front of the user's and can do system init'ing and other magic, but means you have to include it in the link process. Not all SDL2 platforms need it and it'd be great if MacOS 7/8/9 didn't. (Also it is crashing ppc, but fine on m68k, until I can fix it).

(If you don't use SDL_main(), my SDL2 Mac video driver also does the redirecting, but it is too late if any stdio got done before the driver is opened).
 
Looks like YOU thought of it! That's a very good idea, but hard to visualize the final form and extent.

It could build on DebugStr, and trap those messages to a log instead of the debugger. (So a decent toolbox call already exists). Would be lovely if it could replace not just MPW's standard IO, but also its SIOW and CodeWarrior's SIOUX. (But for that you'd probably need to patch existing apps, as they're link time libraries).

Ideally, something like a standardized classic Mac console for stdin and stdout, with stderr going to a file. Maybe realistically this would take the form of a drop in compatible replacement for what I mentioned above. Such a beast would be lovely to have if anyone actually wrote it.

The way SDL 1.2 for classic mac handles this is to redirect the standard IO file descriptors early in main(), so I'm trying the same thing for SDL2. It seems to mostly work. The trick is that Retro68's console is messy, requires C++, and is optional. I was avoiding it because it might have other implications for whatever main() does.

I'm making SDL_main() optional for now. It is a fake main() that sits in front of the user's and can do system init'ing and other magic, but means you have to include it in the link process. Not all SDL2 platforms need it and it'd be great if MacOS 7/8/9 didn't. (Also it is crashing ppc, but fine on m68k, until I can fix it).

(If you don't use SDL_main(), my SDL2 Mac video driver also does the redirecting, but it is too late if any stdio got done before the driver is opened).
I faintly recall there being some ADC sample code for redirecting SIOW; the first time I attempted to mess with this was around 1998, but I didn't have the time or skill at that point to actually build such a thing. So for that bit, the answer is probably somewhere on a 1997 ADC CD. But I've never attempted to mess with SIOUX at all, so I'm not sure how much patching would be required there, or if the interface changed between CW versions.

Having the fake main makes a lot of sense, as it provides you with a wide open initialization playground to use if needed. Having said that, why are you thinking avoiding it would be preferable? Resource optimization? Seems to me that having it in the default link chain with default contents would allow people to tweak when needed but not be too much more of a pain in a lightweight dev workflow?
 
Re patching consoles, et al: I was alive and coding back then and have similar memories/experiences. I recently looked a little into replacing SIOW with SIOUX for a FreePascal game port for MacOS 9 I never finished, because it needed to do things SIOW didn't have. I didn't get far (because it was pascal, in C probably could have figured it out).

Re SDL_main(): Naw, the only reason to avoid it, at all, is to not have to remember to link it in a Makefile, that's the ONLY reason!

This really only ever comes up when porting code, and since my SDL2 is in its infancy, 90% of the ports I've tried fail because they want to use something not implemented yet. And even then, it's not a great reason! Many other platforms require SDL_main() anyway, so if the port originated on one of them, then SDL_main.o is already taken care of in the Makefile! (Maybe Windows does, but Linux doesn't? I don't know). For obscure linking reasons it can't always be included in the .a/.lib file.

One reason I avoided it was because I had to write it. I just took SDL 1.2's, with lots of tiny tweaks, and it seems to work fine on m68k. It currently crashes on PPC, so it is good that it is optional. It has fancy code to display a dialog box so you can chose alternate video drivers and type in "command line parameters" (and even store what you typed as "preferences" as a resource in the app, nice). Parts of that seem to be broken when built with Retro68 (even in SDL 1.2), but as long as you don't try to use the dialog, everything else works.

You've mostly changed my mind. It is required for classic Mac SDL 1.2, so no harm making it required for SDL2. The fact that it is optional will just be a crutch until I fix it for PPC!
 
Last edited:
Just in case anyone out there actually looked at the files/folders in my SDL2 and got confused by some names:
We are talking about a file called "SDL_main.o", built from src/main/macosclassic/SDL_main.c...but you might notice there's a folder called "SDL-main" also there. The folder contains all of the SDL2 source itself.

That folder has that name because it is a copy of the SDL2 "main" branch from their official github. The names look similar, but the purposes are very different.
 
Updates:
Enough key and mouse events now for really basic games.
Have switched primarily to Retro68 from Codewarrior and loving it.
Split stuff only CodeWarrior needs just for it.
All tests build, but, of course, many still fail due to missing drivers.
Created skeleton audio and joystick drivers, will be trying to move over parts of SDL 1.2 drivers.
timer and loadso drivers from SDL 1.2 converted, but need testing.
Now have SDL_main() based on SDL 1.2's, needs testing.
Uses resources from SDL 1.2 since they were good enough.
Refined SDL_config_macosclassic.h, everything possible now included.
OpenGL support and renderer now building, but nothing in driver but stubs so far.
Fixed lots of memory and cleanup issues/bugs.
Did basic what was needed and created simple video driver for m68k Amiga and it works.
Tons of cleaning and refining.
 
That's great! Are you planning to get it to the point where you can do an upstream PR? Or is this purely a "can we get it far enough to port obvious projects" effort?
 
Sadly, I doubt the official SDL2 folk would have much interest in classic MacOS support, so even if I did a PR, the chances of it being accepted are likely vanishingly small...but that is an interesting question, where from here?

I have to admit, I may have been naive, thinking "if you build it they will come". That someone would've tried a game port or something, by now, and there'd be a synergy of testing, working out bugs, and adding features, as needed. For whatever reason, that hasn't happened, but perhaps, in time...not much hurry when using hardware multiple decades old, is there? (Maybe people HAVE tried, but not shared or piped up?)

So it's been less "we" and more "me", unfortunately. I don't mind slowly chipping away at it, as long as it continues to be entertaining and keeps me off the streets (so to speak)...but, being realistic, will probably get to a point where I get hopelessly stuck, lose interest, and/or just don't feel like working on something very difficult but important (OpenGL might come to be that).

I suppose it doesn't really matter, one way or the other, if there's no one clambering for it, then there isn't as much demand for it as I thought there might be. Regardless, I've done my part, and something interesting now exists where it hadn't before. If it is ever used for anything, that'd be lovely, but, if not, life will go on...
 
First, big thanks @lauland1 for putting in the effort to build this, this SDL2 port is really useful and a real gift to the community. 🙏

One thing I've noticed being in the classic Mac world for the past dozen years is interest is spread out over longer periods of time, and you never know when slow & steady & patient efforts may suddenly drive interest and lead to something. In regular software world interest spikes early and then fades fast, but in here it's more of a slow burn and then at some point a thing gets momentum or becomes relevant.

I'm sure that will happen here in time. It's tough to maintain interest when you're soloing though, I completely get that. Perhaps next step might be to reach out to some communities of people that love a particular SDL2 game and see if anyone wants to port it and you can offer to help on the SDL2 side? Having collaborators on a big project like this is super helpful.

Alternately, maybe people here just don't know what the possibilities are as to what games could be ported, and maybe you need to just let people know what games or apps are great targets for this, basically "hey do you want this game on macOS? its possible now!". I've seen a number of API/backend projects that struggle with this situation of not quite getting recognition, because the hook for most people isn't the tool but what specific experience it enables for them, like a game they're passionate about.

Just asked le chat about what might be games that weren't ever on classic macOS that used SDL2 that might be good candidates, here's some ideas. Not sure if all are applicable, but its a start. I wonder if one of these might be the ticket to getting people fired up!
- Spelunky classic
- Cave Story
- Celeste classic
- OpenTyrian
- Doom (crispy or chocolate) - something better than macdoom which sucks
- Quake 1 - something better than software mac quake which sucks
- Descent (dxx-rebirth)
- Commander Keen
- Jazz Jackrabbit
- Possibly Dwarf Fortress since its steam version is SDL2 (*cpu melts*)
- City games like OpenTTD, FreeCiv, Micropolis
- Engines like FNA, Godot, HaxelFlixel, Ren'Py
 
That's a really good suggestion, especially regarding engines -- being able to target Godot for 68k Macs means you've got an entire environment ready for use, both for new games and for porting stuff already written. Some graphics routines will obviously be a no-go, but anything just using a framebuffer should be fair game?
 
Most of what Godot uses SDL for is just an abstraction layer for input, so they don't need to have tons of platform-specific code for gamepads. Even if you could hypothetically target m68k with it, I wouldn't expect it to fit, because the GDScript interpreter and the matrix multiplication/transform hierarchy alone would probably bring any sort of vintage system to its knees. The average heap size for exported games tends to start around 100 megs, on top of everything else.

For a counterexample of a game I believe could easily work, Super Methane Bros. had an SDL port, before the author rebased it on custom middleware called ClanLib. This got pretty far: People had it working on handhelds, iPhones, PSPs, Wii, Gamecube, etc. It's a pretty faithful (not modern) C++ rewrite of an OCS Amiga title. It plays at around 25 ticks per second and doesn't scroll the screen except as a visual transition between levels.
 
@nickpunt, you are, of course very right about things going in bursts. My work on SDL2 is a great example. I'll forever remember winter '24 spring '25 as my "season of SDL2" where I at least thought about it pretty much daily. There's no way I'll sustain that level, and will naturally taper off, but leave behind something (hopefully) useful that may at some other point be taken up and maybe even used by people other than me! (One can hope, can't one!) Who knows, if I get to a point, and stop working on it, one day it may be taken further by others and I won't even notice, if my interests have moved on to something else.

----

Reaching out and SPECIFICALLY asking if there's a particular game people want is a good idea. Again, I thought someone would pipe up organically about that, but perhaps I am just inpatient. I really don't want to have to do a port all by myself, but part of that is a very small bit of...I wouldn't call it bitterness, but more minor irritation..."I gave you guys SDL2, now I'm expected to give a whole game?!?". I did a lot of classic Mac SDL 1.2 game ports that are up at MG, and it was a lot of, not always fulfilling, hard work.

----

I started several ports of SDL2 demos and games myself for testing things. The demos, for the most part, work exactly as expected, as long as they don't need OpenGL, although mouse and keyboard event handling is still only halfway done in my SDL2 so there's a lot of small crazy weirdnesses.

I haven't gotten far on the games, less because of limitations in my SDL2, and more because of just the "standard" numerous teeny tiny problems of porting a Windows/Linux/MacOSX game to classic MacOS. Dealing with pathname separators or functions missing either in old compilers (looking at YOU codewarrior) or the MacOS itself is really not a whole lot of fun. Doing that on TOP of a questionable SDL2 ends up being a MAJOR pain. If something doesn't work, is it the game itself, or something missing in my SDL2? Who knows! When a game crashes this is even more frustrating on classic MacOS where debugging can be a major challenge. (So I really SHOULD understand why there haven't been any porting attempts...I know EXACTLY what they entail).

----

@Boctor's point about m68k's is a very good one. I did an m68k version of SDL 1.2 (up at MG), and although it works extremely well, pretty much flawlessly, cpu and memory limitations, and lack of accelerated video, are VERY apparent when I did real world game ports (also up at MG). Some of the games ended up being more tech demos or proofs of concept, and too slow to actually be playable on real m68k hardware. But they served their purpose VERY well of testing that SDL 1.2 worked. I would dearly love to have super fast m68k hardware, with something like the '060, or vampire or pistorm, boards our Amiga friends enjoy. Until then, there's always Basilisk!

Luckily, I'm building SDL2 for both m68k and ppc at the same time, even switching back and forth randomly from build to build, so, hypothetically eventually, SDL2 games should run quite well on nice fast G4's.

----

Porting an engine is also a very good idea. Might be a really good test and easier to debug than a standalone game...but at the same time might introduce complications as there's more moving parts. I've also looked into and took a few tentative first steps on porting an SDL2 emulator or two to classic MacOS. Again, didn't even try to go too far, having to deal with compilers, and classic MacOS itself, problems, as mentioned above.

Apologies for getting to the TLDR point on this post, but there was a lot to cover.
 
Last edited:
Now have SDL2_image, SDL2_mixer, SDL2_ttf and SDL2_gfx.
SDL2_image and SDL2_mixer aren't using ANY external libraries yet, as I haven't built them, so file formats limited.
 
Back
Top