smitelli / cosmore

A reconstruction of the source code of Cosmo's Cosmic Adventure.
https://www.scottsmitelli.com/projects/cosmore
Other
113 stars 6 forks source link

Better code organization via Unity build? #5

Open lethal-guitar opened 2 years ago

lethal-guitar commented 2 years ago

I was wondering if it wouldn't be possible to further split up the two gameN.c files while retaining the shape of the EXE, by using the preprocessor to include multiple .c files into a single translation unit. This is often called a "Unity build" (no relation to the game engine of the same name). E.g., you could have files actors.c, menu.c etc., and then game1.c would mostly consist of just include statements:

#include "actors.c"
#include "menu.c"
// etc. ...

The compiler would still only be invoked on game1/2.c, never on these additional C files, so the resulting EXE should be the same, but the human reader would be presented with smaller, more focused source files that are a bit easier to navigate.

I have no idea if this would work with Turbo C, but I can't really imagine a reason why it shouldn't. Maybe this is even how the original authors did it? It seems a bit unwieldy to work with these huge files, but OTOH when dealing with all the idiosyncracies of the time it's maybe a small thing. We'll never know..

Anyway, just thought I'd share this idea 🙂

smitelli commented 2 years ago

The short answer is: sure, but it wasn't obvious to me exactly how to split it.

Longer answer: I know that the game was compiled as a pair of GAME1/GAME2-like units, and that all the functions were defined in the order they currently appear. I also know that the initialized global variables -- both the ones at the top of the files and the ones declared static inside functions -- were defined in the current order based on the content of the retail game's data segment.

The vagueness comes in figuring out where to perform the splits. While some of the functions group together into logical sequential groups, others are a mishmash of wildly unrelated concerns that have no obvious common theme. We also wouldn't be able (in many cases) to move the definition of a related initialized global variable into the neighborhood where it might belong because that would change the ordering relative to the function-static variables peppered throughout the code.

I do think that there was probably some kind of #include shenanigans in the original code that didn't survive compilation; I can't imagine it being particularly pleasant working on a 10k LOC source file in an editor from 1992.

Off the top of my head, the actor think functions and the AdLib code are two areas where I distinctly remember everything being together. Could be a small win. Suggestions for other split points are welcome!