Hacker News new | past | comments | ask | show | jobs | submit login
SpaceCadetPinball – Decompilation of 3D Pinball for Windows (github.com/k4zmu2a)
288 points by Lammy on Oct 14, 2021 | hide | past | favorite | 147 comments

I am one of the original authors of Space Cadet pinball (along with Mike Sandige, lead programmer, and Kevin Gliner, producer and designer.) It is surprising and gratifying to see interest is still alive for our old game. And I can't help but be impressed by the ingenuity shown by both the decompiling effort and the playable web-based game.

I'm impressed as well! It's exciting to see folks so enthusiastic about the game.

I took a deeper look at the github project. It's been a long time since I worked on the Space Cadet code, but the decompiled github code is pretty familiar. It's formatted differently of course, but I think it's actually better than the original. And, nice! Check it out David and Kevin: k4zmu2a got the quotes in! https://github.com/k4zmu2a/SpaceCadetPinball/blob/master/Spa...

Now I'll never live down how long I spent working on the flippers.

Bonus points for anyone who knows why the classes in the source are prefixed with a 'T'!

-Mike Sandige (Lead programmer on Space Cadet)

From wikipedia: "...[Danny Thorpe] in 1994 while at Borland, he contracted with Santa Cruz startup Cinematronics (David Stafford and Mike Sandige) to build a component model and collision physics engine for a software pinball game. Cinematronics licensed an early version of the pinball engine to Microsoft" Maybe Borland and Delphi has something to do with the 'T' prefixes. Source: https://en.wikipedia.org/wiki/Danny_Thorpe

Yep, this is the reason. Danny's initial code used Delphi with this convention. I'm not actually sure why that convention is used there, though. I remember asking Danny why, and I think his answer was just that was the Delphi convention. But it's been a while, so perhaps I have forgotten the details of his answer. I later had to migrate to C++ to integrate with the Windows build. And I retained the naming convention, mostly because it was quicker than changing it and I didn't have a lot of time. But I was always uncomfortable with the T prefix on the ramp class.

I remember using lots of T classes back in the early 90s when I was building software using Turbo Vision, a text user-interface framework bundled with Borland C++ (https://en.wikipedia.org/wiki/Turbo_Vision)

Absolutely not. "T" prefix stands for "type" and has its roots in case-insensitive Pascal

  /* eg common C style notation involving type identifier and var identifier is illegal in Pascal */
  Rect rect;
  (* so Pascal requires some distinct identifiers eg *)
  rect: TRect;
the other common prefix is "P" which stands for pointer type

Borland's C++ frameworks use the same convention, to this day.

Thanks to both of you. It took me a while to realize the depth built in. I tried making a pinball game many moons ago but couldn't get the ball to "feel" right (flippers as well).

How was that process? Did you go play physical tables, go for a realistic approach, or tweak magic numbers until it "felt right"?

We played every table we could get our hands on. Also rented tables weekly to be brought into the office once we moved to Austin. I tried to dig as deeply into the history of pinball too, to understand why tables had evolved the way they had.

Mike (Sandige) built a scripting system that allowed me to tweak the physics, materials, etc. of each component. But our constant exposure to real tables helped us form a "feels right" baseline to target. I also applied whatever I'd learned at that point about game design fundamentals (it was early in my career).

After we finished 3D Pinball and started on Full Tilt, I got put in touch with a seasoned designer of real pinball tables who had worked on some hits from the 70s. He took me to task for a bunch of mistakes I made in 3D Pinball, and some of those corrections found their way into the Full Tilt version of Space Cadet (and more so in the other tables in Full Tilt).

   Kevin Gliner (designer and producer for 3D Pinball, etc)

Wow, great info. Thanks!

Always interesting to see the things hidden in games. When I was in the biz I was aware of many easter eggs, a lot of which are still unknown to the public.

For instance, this sign in GTA:SA has the word "TFT" on the back which is a reference to a secret video game "Illuminati": https://gta-myths.fandom.com/wiki/Signs_(GTA_SA)?file=Egg_8....

> Bonus points for anyone who knows why the classes in the source are prefixed with a 'T'!

Was it written in, or ported from, Delphi?

Has to be ported, since Delphi doesn't generate PDB7's.

Or at least written by someone familiar/used to Delphi, since Age of Empires utility classes are also prefixed with T, but the game was obviously written in Visual Studio - but some dev tools were written in Delphi, so somebody seems to have taken the naming scheme from there in that case.

Borland C++ frameworks used the same coding conventions as Turbo Pascal/Delphi.

They still use them.

yep, this is it. The project started out in Delphi, but I had to port it to C to integrate with the Windows Build. For some reason they didn't want to include Delphi tooling in the Windows build.

Great to see you commenting here! :D

Were those quotes some kind of cheat system?

These were just a fun little Easter egg that made us smile. Typing the right code displayed memorable quotes collected from various folks at Cinematronics in the hectic time we were developing Space Cadet. Maybe I can find some time to check with the folks that they are ok with it, I can put together a commit that comments who said them. I don't recall who said all of them, but I'm sure David and Kevin can fill in my gaps. There was a more deeply hidden Easter egg that shows the credits as well. Code to trigger that is not in this repo, though.

Borland C++ OWL and Turbo Vision. :)

"She may already be a glue bottle"


This quote is mine, and is related to a game we were working on for Microsoft before we pivoted to pinball. There was a bug - probably mine - where the game displayed the previous state for an object, but the object had changed state, so the resulting behavior was confusing. 'she' and 'glue bottle' were referring to imagery used for the placeholder prototype artwork. I was trying to explain what was going on, and it made sense, but only in that incredibly constrained context. Outside of that context it's nonsense, but that's what makes it memorable and humorous to us.

Definitely thought that was about a childhood horse

I can't help but wonder for old closed-source utilities and games like this: whatever happened to the original source code?

Is it still around, stashed in a vault a MSFT, or is it lost for ever?

Do you know?

And what would it take to convince a large corp. like MSFT to actually release the original under some open source license ... not like the thing has much value by now other than historical.

The rights belong to Electronic Arts today. They acquired Maxis who had acquired us (Cinematronics.) Microsoft may still have rights to continue publishing a version with the Windows operating system.

Microsoft, if you're reading this, we would be glad to provide assistance in getting 3D Pinball running again on the latest Windows OS.

Given that the reason it was removed was IA-64 which isn't a thing anymore... this should be plausible. But also given where MS has gone with games as late I'd be surprised if they do. EA should just release all of Full Tilt! Pinball on steam or GoG if they haven't already.

It was removed for Vista, because it couldn't transition to AMD64. This was after Microsoft had essentially completely ditched Itanium.

(I'd love to see a GOG or Steam or even Origin release of Full Tilt Pinball, though. The Full Tilt version of Space Cadet is better-- higher-resolution graphics plus some gameplay tweaks.)

[edit] Digging a little deeper, that might not be entirely true. The first consumer version of Windows it didn't appear in was Vista, but it sounds like the decision to drop Pinball was made during the XP era (even though it shipped with x86 Windows XP). So issues with the IA64 port (or with another architecture) might've been the reason it was dropped, then that decision was not revisited for Vista even if Pinball might've worked under AMD64 Windows.

Actually 3d Pinball is available in the AMD64 Window XP 64 bit versions. It was not available (sort of... it's there but not actually installed from media) on IA-64 versions. There was a youtuber that dug into it (probably at the cost of far too much of their own sanity). So there is no "might have" it works (albeit with some rendering issues).

Was it compiled as a 64-bit executable on AMD64 Windows XP?

Yes... https://www.youtube.com/watch?v=3EPTfOTC4Jw

Warning contains a youtuber bashing their head firmly against the pain of Itanium to test this.

Wow, this game was a staple in my childhood! Just wanted to let you know that your work brought me lots of happiness as a kid, so thank you :)

Out of curiosity, have you ever written about the experience? Technical challenges, the development culture, etc?


There were a couple of interviews with gaming magazines years ago. They would be hard to find today and didn't cover the topics you mentioned. Mike, Kevin, and I, really need to get together to tell the story some day.

Please do! There are loads of us who would love to hear it all direct from you guys.

Yes, that would be amazing! I absolutely adored playing this game on our first family PC back in the day.

I've been meaning to write up a history, but it's one of those things that's been on my to do list for years...Maybe someday, soon.


Well, in this day and age of bazooka DMCA take down, it's refreshing to see a game author happy about his game being gutted, and put online to play.

> it's refreshing to see a game author happy about his game being gutted, and put online to play.

The game author is typically not the copyright holder.

I played it before it was bundled with Windows, at the time I didn't think that much of it (I was more into Epic Pinball, spent so much time on the shareware version with the android themed board <_<), but it was a game we'd fire up Windows for. We probably got it off one of those shareware CD's, but I don't recall. Might have been off a diskette?

Thank you sir, you brought many many hours of enjoyment to my childhood. I remember being excited to go to my Aunt's house because she had a computer with Windows XP (my family only had Windows 2000) and I could play your game.

And only on hacker news will I be replying to one of the authors.

if the game would be available as open source and/or run on linux, that would be super... this was my first pc game when i was a little child

You can easily compile it on Linux following the instructions in the repo and grab the game assets from here: https://www.reddit.com/r/vitahacks/comments/pro8x1/comment/h... Tested on Arch Linux, works flawlessy!

Check the SDL port or the emscripten

It runs perfectly on Void as my example.

We played the hell out of it on our Windows 2000 machines during particularly boring IT labs in college, in early 2000s.

The physics just seemed so spot on. I installed Win2K on a VM recently, just for this.

Start Menu, type in "pinball". Ah....

Was it available on Windows 2000? I know it was a default on Windows XP. I was way too young back then to remember

Definitely. It was available (apparently) even with a Win95 upgrade pack, so it's very old.

I was not aware of it, however. I am not sure it was as easy to launch before, by just typing in "pinball" in the Start menu.

I played this game for hours a day, for an entire summer.

And it was the best summer of my life.

I remember getting up early, making cereal, and then playing this.

You created one of my favorite childhood memories, thank you so much.

it was the most joyful game that shipped with windows and it was also fun! I would like to play it again :)

This game blew my mind! How did you get the physics to be so realistic? At the time I tried a number of different pinball implementations and unrealistic physics was a big problem.

Thanks! We modeled collision boundaries with high resolution, and tried to use physically appropriate material settings. But this had to run on relatively slow machines, so the physics model itself was pretty basic. Except for the flippers. I really wanted them to feel like physical flippers - predictable, controllable, and without computational problems that let the ball pass through them sometimes. :( I put lots of time into the flippers, and had some trouble balancing those requirements with the available CPU - it wouldn't do to have the game slow down to figure out how the ball should move when you hit the flippers.

I noted this in another reply, but Mike had written a scripting model that let me adjust the physics and materials for each component separately. That allowed me to iterate rapidly when tuning the feel of the game. A solid physics engine is a pre-requisite, but what you do with it from there is also critical (and the goal was to replicate how real world tables felt, not how they actually behaved).

Well, it is simply one of the best pinball games I've ever played on a computer. Interesting scoring system. Fair. Not gimmicky. Pure beauty.

Great to see you here David. Thanks for all the work over the years.

'twas a great little game. good job!

Not just decompiled.

What was done:

* All structures were populated, globals and locals named.

* All subs were decompiled, C pseudo code was converted to compilable C++. Loose (namespace?) subs were assigned to classes.

Edit: Wow, and a lot more: https://github.com/k4zmu2a/SpaceCadetPinball/commits/master

Also see “On the attempts to resurrect Space Cadet Pinball” by Raymond Chen: https://devblogs.microsoft.com/oldnewthing/20181221-00/?p=10...

Wikipedia suggests the copyright owner is Electronic Arts:


So we can all look forward to a reboot of space cadet on Windows 11 with lootboxes and microtransactions?

>* All structures were populated, globals and locals named.

Microsoft provides that openly via debug symbols, so it's not even anything new.

Assuming it’s a debug build or a release build with absolutely no optimization. Otherwise at least some amount of manual work is suggested by the bullet point.

But are PDBs even available for it? I assumed Microsoft only releases PDBs for binaries used in development scenarios.

Looks like a .pdb is available for it (no idea where it was sourced from but the readme says it's public).

You can download it from the microsoft symbol servers (i.e. via IDA). Then it's %TMP%\ida somewhere.

No idea how else you'd acquire it, Visual Studio would probably also download it if you get pinball.exe to crash and debug it.

the protocol isn't that complicated, but if you'd rather use something existing, you could just do

    rabin2 -PP pinball.exe
(part of https://radare.org) to download the pdb from microsoft's symbol server.

If you read the README in the link, you will find the answer to your question.

I did read it, and in fact posted an excerpt and a couple relevant links. Apologies for missing “and its public PDB”.

What level of optimization was used in the released executable?

I just ran the pdb through dia2dump, and it seems that their public pdb doesn't keep this information, so one could only estimate.

Edit: It does however tell you still from which exact .obj an offset is, info the author didn't seem to have used since they created their own filenames. (Edit 2:, at least partially, some original filenames are there, but also custom ones)

And it was forked and ported to emscripten! Amazing!


that is really cool!! but the flippers are a teeny bit sluggish, screws up my timing on some stuff I know how to do (gotta love gravity well)

In the graphics settings up the FPS and it seems to work a lot better for sluggishness.

Did it really have music like that? I only remember the sounds, for some reason.

I don't remember the music either, possibly because i turned it off the first time i played, and never turned it back on. The menu option to turn music off doesn't work in the web version, sadly.

Because the default was to keep the music off.

Be cautious that publishing source code generated in part or entirely from decompilation of copyrighted content may take you to court.



I suspect the much more recent news article https://news.ycombinator.com/item?id=28809559 may have encouraged the author to publish this... and he was looking for a bug to fix, after all.

That lets you decompile and likely publish a patch, not publish the complete derived source.

Patch for what though? Is the ability to use a patch taken into account because a patch to clang on Linux and a patch to appleclang on Mac have very different interpretations

Binary patches exist; there are fairly reasonable arguments that distributing binary patches (in a format that does not significantly contain the original work, e.g. bsdiff) is at least fair use, or possibly not a copyright problem at all.

Could you make the argument (not here) that binary patches are not a reasonable way of distributing a patch for a program that is frequently updated?

Doesn't the Chrome updater use binary patches?


The patch, of course, is covered by a separate copyright.

But there's hundreds of decompiled copies of Super Mario 64 on github and have been for years. Where's their court cases?

if the purpose of the decompilation is for reverse engineering and api compatibility, there's a fair use argument.

So the OP would need to show that the purpose is indeed for reverse engineering. IANAL, so don't actually do it...

Decompiling may be legal, but publishing the decompiled source is almost always a copyright violation.

Interoperability is an argument for the legality of decompilation itself (i.e. you can ignore EULA clauses that say otherwise); it doesn't make the resulting code copyright-free or automatically eligible for fair use.

The path to fixing the law is doing it anyway, letting the takedowns come, and then harnessing the collective frustration of people who want to see the things they grew up with be preserved.

There are reasonable fair use arguments to be made around preservation indeed (just look at what archive.org does). They just have nothing to do with the decompilation for interoperability story.


Because copyright. The decompiled code is a derivative work of the binary, and thus subject to its original copyright.

You can make fair use arguments in some cases, but "I decompiled it for interoperability" isn't one of those. That just lets you decompile it privately (for analysis/research), not publish the resulting code.

That's still a handwavy answer.

I worked with game RE for a long time and the only way that publishers were able to go after people was if they used game assets. The decompiled code was, as far as I was ever aware, free game. There was almost always manual intervention to get it to build.

That's really not a safe assumption to make. The publishers may not have wanted to go after people but I wouldn't be betting on winning a court case against them over this.

If decompiled code were fair use, you could take any application, decompile it, and re-publish it for free. It doesn't make any sense. Decompilation is a mechanical transformation, and the manual edits that come after to make it work do not significantly alter the nature of the work. It is clearly a derivative work of the original, so you're left with fair use arguments, and there certainly isn't any universal "well it's a game and it's just the code, not the assets" fair use argument.

The game asset thing applies to reimplemented games like OpenTTD, which are independently implemented and then ask to be combined with legally sourced assets. That's very different than a decompiled game.

It wasn't "free game". It just isn't worth the effort to prove code was copied.

Here are some interesting takes by the guy who ported it for XP at Microsoft. He says it would later prove very difficult to move to 64bit due to some low-level hacks/dependencies on word length in the collision detection code.


This is the line implementing the famous “hidden test” cheat https://github.com/k4zmu2a/SpaceCadetPinball/blob/8c4f38c0af...

Looks like there are other undiscovered cheat codes too.

What is the hidden test cheat? Your link brings me to the top of page

    // Original allowed to enter cheats only before the first launch.
    std::memmove(&cheatBuffer[0], &cheatBuffer[1], 10);
    cheatBuffer[10] = key;

    if (strcmp(bufferEnd - 11, "hidden test") == 0)
        pb::cheat_mode ^= true;

Typing "hidden test" and hitting enter would cause the ball to be stuck to the mouse pointer rather than playing normally. I assume this was used to test the game features but it was left in the final build.

That's correct. Mike needed it to test the physics, and I needed it to tune and balance the gameplay.

Hah, thanks so much for replying! I just wanted to say that leaving this in the final build was awesome. Knowing this cheat in school made you basically a wizard.

> On 64-bit bug that killed the game

I had heard about this bug, I think I saw it on Dave Plummer's YouTube channel[1]. I remember thinking at the time that I am surprised nobody has tried to decompile it and figure it out, looks like k4zmu2a did and couldn't find it. Now I have more questions about the original bug reports.

[1] https://www.youtube.com/channel/UCNzszbnvQeFzObW0ghk0Ckw

The bug lore came from Raymond Chen's blog post [1]

[1] Why was Pinball removed from Windows Vista? https://devblogs.microsoft.com/oldnewthing/20121218-00/?p=58...

This comment made me chuckle and also a bit sad:

> [...] we simply couldn’t figure out why the collision detector was not working. Heck, we couldn’t even find the collision detector!

And the continuation is:

"We had several million lines of code still to port, so we couldn’t afford to spend days studying the code trying to figure out what obscure floating point rounding error was causing collision detection to fail."

I'd say Ray is right, not lacking the skill, but lacking the time

To be clear I was sad about the lack of comments in the original code. It shouldn't be that hard to find where the collision detection occurs.

Raymond's comment about not being able to find the collision code is a bit absurd. I can't recall if Danny or I named the top-level collision detection function, but it was just named 'pb_collide'.

It's nice to be able to point to this line: https://github.com/k4zmu2a/SpaceCadetPinball/blob/5947727f80...

And, while it is true that the code is sparsely commented, the geometry code that computes ray intersections is commented.

To be fair it's a huge undertaking to port any code of that size to 64 bits, be it fully commented or not. He probably remembers it vaguely and it might be a different function they had problems finding the exact location in the source code.

I'm curious, didn't they just call you or Danny (I believe that's Danny Thorpe, who is currently working for Microsoft) for assistance?

Ray wasn't about only to find the collision, but porting or not the game, meaning going through entire uncommented code of the game. And he said they made the executive decision not to port it.

There's a documentary about it: https://www.youtube.com/watch?v=3EPTfOTC4Jw

I unpacked pinball from 64-bit windows xp cd, played it and the only bug I see is that the launcher isn't well visible.

It is incredible that even in 2021 people still parrot Chen's original _WRONG_ post about Pinball not being available in x64 Windows. We already even mentioned that in the original entry of his blog before the comments were removed.

Tens of "YouTube videos" appear in this thread and all of them simply parrot the same statement from Chen and not a single one of them even bothers to actually try Windows XP x64 edition and check whether Pinball is there not. Again only in some comments people seem to realize 'hey, you guys may be wrong .. there is a x64 pinball here after all, at least'.

I guess it's a sad reflection of our society.

I just looked in wikipedia, where it says xp had a working amd64 version.

Someone edited that in a couple weeks ago. (And cites a "Youtube video" as source. Sigh. )

I pirated (sorry) the Windows version of Space Cadet Pinball from some big torrent tracker (TBP, Demonoid?)some time after that blog post was put up and it worked on Windows 7. Last time I saw this story making the rounds, around 2017, I checked to see if it still worked on Windows 10 and to my surprise, it did. I don't know what sort of unofficial patch was applied if any, but it has been working on 64 bit windows for nearly a decade from what I can tell.

So there are various Youtubes about this... but it was 'Windows XP 64bit-Edition' (yes 'Edition' is part of the name. This specifically refers to IA-64 and not AMD64. There are rendering issues on the AMD64 versions but the IA-64 version doesn't work. Windows XP 64bit (non-edition) that was on AMD64 actually did ship with 3d pinball, albeit with some rendering issues. Best guess is that it was later removed in vista because it didn't fit the shiny new games theme that existed then. Raymond was giving his view of his part of the port to IA-64.

So, Microsoft had an agreement with Intel that Itanium version will be no worse than amd64 version, so they couldn't release pinball only for amd64 version?

They did release it for the windows XP 64bit editions for AMD64. So no it was definitely released, it has rendering issues but it is there and works AFAIK. As best I can tell it was removed because it didn't fit vista's aesthetic not that they couldn't get it to work.

Because if MS had that agreement... almost nothing would have been released on AMD64 as very little actually made it to IA-64 or was supported there realistically.

Windows for AMD64 is called x64 Edition, it also includes "Edition" on the name. Windows for IA64 is called 64-bit Edition.

Because Microsoft couldn't make it more confusing... lol

They could not really help it. It was not that clear these days what would exactly succeed x86 as the mainstream 64-bit architecture.

Makes me wonder why they removed Hearts from Windows 8

Probably the same collision detector issue⸮

Could anyone speak more about how this decompilation is done from a technical perspective?

This looks nothing like the pseudocode C that IDA/Ghidra spit out, so how would you go about doing this even?

It says in the README:

  Tools used: Ghidra, Ida, Visual Studio

  What was done:

    All structures were populated, globals and locals named.
    All subs were decompiled, C pseudo code was converted to compilable C++. Loose (namespace?) subs were assigned to classes.
Which is a bit "Draw-the-rest-of-the-fucking-owl" for me. Or am I just clueless.

I'm not aware of any good general-case automation for this.

When I've done this in the past, it basically consists of:

1) Decompile project using Ghidra/IDA, first pass.

2) Load symbols if present (sounds like there was a PDB for this one, which makes things a lot easier).

3) Read decompilation/asm for unnamed subs and try to name them based on what they do.

4) Export all decompiled source into an editor and start copy/paste/editing into readable source. Highly manual process, for some files it's just pattern matching / renaming and goes really quickly, for others it's full reimplementation and a bit harder.

And, if you look at most "decompiled game" projects, I think this is the industry standard way to do this. For example, OpenRCT2 started as a repository full of manually created source with Hex-Rays names and slowly evolved module-by-module into readable source code. (disclosure: per the child post, my original assumption that OpenRCT2 was copied out of Hex-Rays was inaccurate, since it was originally written in assembler it didn't follow a standard C ABI and the decompiler wouldn't work properly anyway).

For OpenRCT2 thats not quite how we did it. We didn't use IDA decomp output as its useless with Chris Sawyer calling conventions you had to just read the assembly. We did name things as per IDA when things were completely unknown hence why there was lots of sub_XXXX functions and byte_XXXX. I personally just used OllyDbg and read the assembly and wrote equivalent C code. I've a few videos of implementing functions for OpenRCT2 and OpenLoco if you are interested.

I stand corrected - I'll check them out! It makes sense that the Sawyer calling conventions wouldn't decompile correctly, since he was just making the ABI up as he programmed.

  > sounds like there was a PDB for this one, which makes things a lot easier
Ah yeah that certainly reduces the difficulty by an order of magnitude.

Do you know of anyone who has done this with high-skill as a recorded video tutorial? Seems like one of those things much easier to follow in video than text due to how complicated IDA/Ghidra are as tools.

Check out `wrongbaud` tutorials: https://hackaday.io/course/172292-introduction-to-reverse-en... .

wrongbaud's are the best trainings I've seen for Ghidra so far. I actually haven't watched this particular course (I confused it with some other ones) - but given what I've seen, I'm sure it's good.

Thanks a ton for the point in the right direction!

It is definitely skipping over a lot of the details. Essentially the code put out by those tools is going to be almost the right code. The thing you do then is go through each function it produces and fix up the names and maybe re-organize it to be more readable. Then you try to compile it and find and fix the errors. It's going to be entirely project and file specific as to what you'll need to do but usually you'll need to rewrite the conditionals in if statements to be more understandable since the optimization passes that the original compiler did will have likely scrambled the logical version of things before (to reduce the number of things that need to be done, or reordered them to take better advantage of the way the processor pipelines things).

  > " The thing you do then is go through each function it produces and fix up the names and maybe re-organize it to be more readable."
How do you do this, when most of the code is like (real fn decompilation from random binary opened with Ghidra v10.0.4 for example's sake just now):

  undefined8 FUN_14004dd60(longlong *param_1)
    if ((((*param_1 != 0) && (param_1[1] != 0)) && (param_1[2] != 0)) &&
      ((param_1[0x2b] != 0 && (*(longlong *)(param_1[0x2b] + 0x28) != 0)))) {
      if (*(char *)((longlong)param_1 + 0x21) != '\0') {
        return 0;
      (**(code **)(param_1[1] + 0x18))();
      *(undefined *)((longlong)param_1 + 0x21) = 1;
      return 1;
    return 0;
This program is 14MB, and Ghidra says:

  # of Functions:  12661
  # of Symbols:   118504
  # of Data Types:  6513
It just seems unapproachably daunting.

(Serious question, not being passive-aggressive. I find this stuff interesting and wish I understood it more.)

What's missing here is type information. This is the reason why the decompiled code is quite unreadable. How to solve this: try to figure out what these missing types (like structs, arrays, ...) are, by looking at how the code uses the variables. Then you define these types in IDA/Ghidra/..., and this will already give you decompiled code that's much easier to read.

The sibling comment covers it a bit more in detail, but it's largely just some guessing and as much an art to figuring out what the types are or could be. This particular one looks like it's taking a function pointer in and checking if it's a valid function (not null) and then checking the first two bytes of the function. From my memory, the windows ABI uses the first two bytes of functions for installing hooks/debugging by patching the first two bytes into some kind of jump (while originally being nops). The 0x2b part I'm not sure about myself but it looks like some other kind of similar checks.

And actually then thinking about the way it's calling it, i'm wondering if this is actually from some C++ standard library code for doing stuff with a vtable, looking up the vtable entry and checking it's validity before calling it (in this case, location 0x18, and checking some kind of RTTI at 0x28 and 0x2b) and storing that it's been initialized in 0x21. So I think this might be part of an initialization function for some property on top of a object that exists at *param_1. and the decompiler has misinterpreted it as a longlong because of the access patterns (64bit pointers).

In the case of Pinball, Microsoft released the debug symbols for the game because it was a part of Windows (meaning that there wasn't a need to figure out the function/variable/type information).

I learned a lot about 3D Pinball recently on this video [0]. It's specifically about the 64bit versions of 3D Pinball (or the lack thereof) and the reasons why. Part of that is debugging which relates to this.

[0] https://youtu.be/3EPTfOTC4Jw

Dave Plummer, the programmer who ported Space Cadet pinball to ship with Windows, also recently did a video on this.


Plummer is flat out wrong that his port enabled our game to ship with Windows -- we built it for Windows (and for Microsoft) from the start. He didn't enter the picture until we were already shipping with the popular Microsoft Plus Pack (which put us on about 25% of all Windows machines). Honestly, I'd never heard of Plummer until a few years ago when a journalist asked about him.

Plummer's only role, near as I can tell, was to get it working on later Windows operating systems that were 32 bit (or certain 32 bit variants), which likely extended the shipping life of the game (so, not Windows 95 or Windows 98, but the others that followed). Microsoft actually had the option in our original deal to ship with the OS when Win 95 launched and chose the Plus Pack instead.


Interesting insight but I think you're both "right". If I'm reading you correctly and understanding Dave correctly, the game was made for running in 16-bit mode on Windows. According to Dave, Microsoft did not want to ship any applications with their "flagship" 32-bit OS that were not able to run natively in 32-bit.

This, according to Dave, is also the reason you don't see Pinball shipped on the newer "64-bit" versions of Windows, despite the 32-bit version running just fine on 64-bit Windows.

If you want to play a modern, hi-resolution 3D version of Space Cadet, there was a Visual Pinball port recently by JPSalas: https://www.vpforums.org/index.php?showtopic=47560

Not technically a port but recreation. Nice work!

Finally! This has been lost for ages! I want to see someone do a breakdown on the ball physics!

Gonna archive this before it's wiped from the intenet.

this game was a huge part of my 12 year old childhood. really good times.

Note that they used Ghidra (the NSA-developed decompiler), which, in spite of its shady origin, is a wonderful tool.

How does ghidra compare nowadays to IDA? Is it good enough already to be used as a replacement to IDA and Hex-Rays decompilation, at least for x86 code?

Yes, I think Ghidra is "good enough" for most use cases. For some (architectures other than x86/ARM), it is vastly superior. For others (Windows and especially C++) it's not quite as good, but still useable.

For C++ projects targeting Windows, IDA is still a lot better in terms of decompilation quality. The demangler and function signature system is particularly tailored to MSVC++.

For other architectures, Ghidra kills IDA by virtue of abstraction - all disassembly turns into the same IR (P-code) and is decompiled from there. So, the decompiler works across all architectures with a processor spec, rather than being specialized to x86/ARM.

And, the exposure of this P-code system is very powerful as well - with some clever plugin scripting for Ghidra, you can actually single-step through the P-code as though you had a full emulator/debugger, without needing to set up an entire virtual environment. https://wrongbaud.github.io/posts/kong-vs-ghidra/

That would depend on your needs. For me, at least, it's largely an adequate replacement-I'd rank it as "consistently at least 50% as good, sometimes up to 200% as good as IDA". For the price it's simply unbeatable.

> How does ghidra compare nowadays to IDA?

Not in the same category, IDA is really good.

However, Ghidra is:

    a) free

    b) good enough for many thing
One downside: the UI is convoluted.

This is interesting to me - I feel as though both GUIs are an acquired taste and now that I've spent enough time in Ghidra, I find IDA annoying sometimes.

I agree that IDA is head-and-shoulders better for Windows, especially Microsoft-compiler built software, but I'm not sure Ghidra isn't in the same category, especially for embedded. I find myself much more productive in Ghidra than IDA for embedded tasks.

> I find myself much more productive in Ghidra than IDA for embedded tasks.

Ah, fair enough. I've only used these tools in an windows x86-64 context.

The 1992 Pinball Dreams from DICE is still being published for new platforms latest release on the Amstrad.(but as unlicensed as this release seem to be)

You can get the original game data freely from Internet Archive- https://archive.org/details/SpaceCadet_Plus95

In you need music install timitidy and freepats.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact