I really haven't looked at the Restunts code in detail. I imagine that things go more or less like this:
- Stunts original binary was packed and the first thing it did was load itself to memory unpacked. This is no longer relevant to Restunts
- After that, the code would load the graphics "driver" file and proceed to merge it with itself in memory, resulting in the actual program code. This, again, has been hard-wired in Restunts so it should now be irrelevant
- At this point, I assume the code jumps to a loader function or maybe a chain of loader functions. Some fixed memory is reserved at the beginning to contain the main program variables, such as what car is currently loaded, with which colour and whether transmission is automatic or manual, also there's a memory region that's always reserved for a track and the replay events right after it. Which opponent is currently selected, with which car, etc., all this goes to this fixed memory that's reserved at the beginning and is only freed when the program ends. There surely is a lot more being stored there. I don't know if engine-time variables are also stored here or if a dynamic memory region is allocated when the main game engine is started up and freed every time a race ends. After defining the fixed part, the default track and replay are loaded.
- Now the loader begins bringing up the dynamic part. It starts loading resource files. When a resource file is loaded, surely memory is allocated for it and surely, resources in memory can be freed dynamically and indeed, are, very frequently. I assume the intro is loaded, run, and then removed from memory by the time you get to the main menu. The game loads all car files dynamically, even though these ones are not removed until the program ends. At this point, the loader routine likely jumps to a Main Menu routine. I really hope this is done this way.
- The Main Menu routine calls the dynamic resource loader function, the same used for loading cars, to load the menu background image. Not sure if music is loaded dynamically or all tracks at the beginning. A small dynamic region is allocated that corresponds to the local function variables. These hold, for example, the current option being selected. Because Stunts replaces the BIOS keyboard routine with its own, the Main Menu surely invokes other functions to control the keyboard and mouse. Besides, the mouse pointer is drawn by Stunts. It does not use the default arrow cursor. The menu either regularly calls a mouse cursor maintenance function or this is already installed at the timer interrupt. I expect the second and it'd be the best. If not, we will need to identify this maintenance function. When the user presses Enter or clicks on one of the signs, the Main Menu either calls a main branch function for that option or returns a section ID value and exits to the main program loop. We have to know which of these is the case. It's the Main Menu function that we have to replace and we have to give it the same form as the original one.
- Each other part of the program surely loads dynamically. I know for a fact that the internal track editor is really an external executable, yet the mouse cursor remains functional, which makes me think there is some for of API set up in memory, probably in the form of an interrupt. One good way of understanding this API would be to disassemble the track editor, but this is such a big thing to do that we better first try to figure things out by only looking at the Main Menu function.
What I think we should do is to not try to actually modify the original code too much. Only replace this one function. The code will have to be recompiled once so that the new function is blended with the rest of the program, but any other mod we want to make should just be plugged there and run as an external EXE, just like the track editor. Of course, if we want to make a mod that does something "during the execution" of another program section, this won't work. We'll have to make a TSR part for it or something. Good news is that even though Stunts didn't, we can use 32bit registers and we can use XMS.
Do let me know if I'm missing something important or if something is very, very different from my guesses. I'm writing this as a base to start putting the cards on the table.
- Stunts original binary was packed and the first thing it did was load itself to memory unpacked. This is no longer relevant to Restunts
- After that, the code would load the graphics "driver" file and proceed to merge it with itself in memory, resulting in the actual program code. This, again, has been hard-wired in Restunts so it should now be irrelevant
- At this point, I assume the code jumps to a loader function or maybe a chain of loader functions. Some fixed memory is reserved at the beginning to contain the main program variables, such as what car is currently loaded, with which colour and whether transmission is automatic or manual, also there's a memory region that's always reserved for a track and the replay events right after it. Which opponent is currently selected, with which car, etc., all this goes to this fixed memory that's reserved at the beginning and is only freed when the program ends. There surely is a lot more being stored there. I don't know if engine-time variables are also stored here or if a dynamic memory region is allocated when the main game engine is started up and freed every time a race ends. After defining the fixed part, the default track and replay are loaded.
- Now the loader begins bringing up the dynamic part. It starts loading resource files. When a resource file is loaded, surely memory is allocated for it and surely, resources in memory can be freed dynamically and indeed, are, very frequently. I assume the intro is loaded, run, and then removed from memory by the time you get to the main menu. The game loads all car files dynamically, even though these ones are not removed until the program ends. At this point, the loader routine likely jumps to a Main Menu routine. I really hope this is done this way.
- The Main Menu routine calls the dynamic resource loader function, the same used for loading cars, to load the menu background image. Not sure if music is loaded dynamically or all tracks at the beginning. A small dynamic region is allocated that corresponds to the local function variables. These hold, for example, the current option being selected. Because Stunts replaces the BIOS keyboard routine with its own, the Main Menu surely invokes other functions to control the keyboard and mouse. Besides, the mouse pointer is drawn by Stunts. It does not use the default arrow cursor. The menu either regularly calls a mouse cursor maintenance function or this is already installed at the timer interrupt. I expect the second and it'd be the best. If not, we will need to identify this maintenance function. When the user presses Enter or clicks on one of the signs, the Main Menu either calls a main branch function for that option or returns a section ID value and exits to the main program loop. We have to know which of these is the case. It's the Main Menu function that we have to replace and we have to give it the same form as the original one.
- Each other part of the program surely loads dynamically. I know for a fact that the internal track editor is really an external executable, yet the mouse cursor remains functional, which makes me think there is some for of API set up in memory, probably in the form of an interrupt. One good way of understanding this API would be to disassemble the track editor, but this is such a big thing to do that we better first try to figure things out by only looking at the Main Menu function.
What I think we should do is to not try to actually modify the original code too much. Only replace this one function. The code will have to be recompiled once so that the new function is blended with the rest of the program, but any other mod we want to make should just be plugged there and run as an external EXE, just like the track editor. Of course, if we want to make a mod that does something "during the execution" of another program section, this won't work. We'll have to make a TSR part for it or something. Good news is that even though Stunts didn't, we can use 32bit registers and we can use XMS.
Do let me know if I'm missing something important or if something is very, very different from my guesses. I'm writing this as a base to start putting the cards on the table.