Stunts Forum

Stunts - the Game => Stunts Modification Projects => Topic started by: Daniel3D on May 24, 2021, 11:14:28 PM

Title: Replacing the main menu.
Post by: Daniel3D on May 24, 2021, 11:14:28 PM
Ok, welcome.

Replacing the main menu sounded simple. Its the lobby of the game and it seems just a crossroad between the different parts of the game.
But it is not that simple. The game was programmed by only one programmer and concessions were made for speed and memory usage.
So it could wel be that most of the code of this menu is fragmenteded al over the main engine.

we'll see.
Title: Re: Replacing the main menu.
Post by: Cas on May 25, 2021, 12:39:12 AM
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.
Title: Re: Replacing the main menu.
Post by: Daniel3D on May 25, 2021, 10:05:49 AM
I think you're likely right, or very close to it.

I do not think that all cars are loaded into the memory at startup.
That would be a waste of resources.
I think that they are loaded when the car selection is accessed.
I hope that there is a dynamic memory part that loads the 4 parts when called.
- track selection / editor
- car selection
- opponent selection
- the race engine.

If that is the case it would make things easier.

I agree with you that small changes are wise to start with. So to start I propose to:
Identify the button regions and what their input and output is.
Identify the memory that store's car, track and opponent selection.
Identify what's in the fixed and dynamic memory and when.

Documenting everything else we find along the way..

8)

Duplode, can you give a short recap of what is already known about the memory allocation?
Title: Re: Replacing the main menu.
Post by: Cas on May 27, 2021, 12:44:16 AM
I've been taking a look at a few things and I realise there are a few details I remembered wrong. For example, I was sure that there was a separate executable file for the track editor that of course, would not work if run alone, but could be seen as a separate file. This is not the case. I also had the idea that the default car was also the first one alphabetically and this is not so; that's the Acura. So Stunts does load that car on purpose at start-up. Now I have the same question Daniël had... "What if I remove it?"

And you're right, Daniël. It doesn't make any sense if cars are all loaded at the beginning. They should instead be loaded dynamically. Stunts likely holds a pointed to each of the dashboard items, to the "simd" parameters and to each of the car 3D shapes and explosion debris. When a car is loaded, I expect these memory regions are de-allocated and then reallocated again to hold the contents of the new car. There also is the possibility that fixed-sized regions are permanently allocated during the game program execution and that car objects are loaded there. If this is so, then some objects might produce unexpected results if they happen to be larger than those regions. In particular, bitmaps that are normally smaller in the dashboard could overflow their buffers if they turn out to be too large, say, the instruments. This might explain why these tend to be difficult to configure.

We have to look at the main program function tree. To be honest, it's been long since I gave the only few quick reads to the code in Restunts, so I don't know how much is known about the main tree. The good thing is we don't need to do a lot about interpreting the contents of the program functions. We mainly have to understand the flow and identify which function is which. Then, we will have to write routines from scratch and plug them in. We might need to interpret the lobby/menu function so that we don't end up with "loose cables" when we unplug it and insert our monster in its place, but that's probably the simplest function in the whole program.
Title: Re: Replacing the main menu.
Post by: Duplode on May 27, 2021, 03:56:01 AM
Hello! A few really quick notes:

Quote from: Cas on May 27, 2021, 12:44:16 AM
I also had the idea that the default car was also the first one alphabetically and this is not so; that's the Acura.

Yup, the Countach is hardcoded as the default car. That can be traced starting from this function (http://set_default_car).

Quote from: Cas on May 27, 2021, 12:44:16 AM
And you're right, Daniël. It doesn't make any sense if cars are all loaded at the beginning.

A non-code piece of evidence supporting that is how adding a car RES file without the graphics doesn't crash the game on startup, but rather only when it is attempted to select it on the car menu. 
Title: Re: Replacing the main menu.
Post by: Daniel3D on May 27, 2021, 11:07:30 PM
QuoteOn the main menu: run_menu looks like a good starting point for the investigation. In particular, this appears to be the point where the resulting of calling it is used
That really looks promising,... Thanks.
Title: Re: Replacing the main menu.
Post by: Cas on May 28, 2021, 12:50:52 AM
An experiment I was thinking of making some time ago to better understand how car files are loaded in Stunts is create one of the car files for a car, say, the RES file, but put in it the resources of the four files and see if Stunts is OK with handling that single file instead of the four. That would serve two purposes: one, it would show us whether Stunts cares or not about files, whether it's file-oriented or resource-oriented when loading, and two: if it works, it would mean we can use individual car files, which is a lot easier to handle.
Title: Re: Replacing the main menu.
Post by: Daniel3D on May 28, 2021, 09:18:27 AM
I think the car selection only loads the res and the shape file. When racing all 4 are loaded.
But that can be tested.
I think you get missing file errors even if all is in the res. But maybe you could move resources around between the files and see if it matters if they are in a different file.
But it would be a useful test anyway. and if your hunch is right and the game doesn't care about the files, just about the resources then it could be useful indeed.
There may be a leading file I think, just like the 4 tile track pieces.
Title: Re: Replacing the main menu.
Post by: Cas on May 29, 2021, 01:06:30 AM
My guess would be the same as yours. I am pretty sure that, when a car file is loaded, all resources are made available, even if not the ones that usually belong to that file, but still, probably Stunts looks up the file names and halts if one of them is not found, not realising that the resources are there anyway. But yes, it wouldn't be a surprise if just having the files there with all resources mixed up among them would work. An exception could occur in cases in which Stunts does not attempt to load all four files. For example, in the showroom, only the RES and the 3SH files are necessary, so if you place in the VSH files resources that should be in the RES or 3SH, the game might halt at the showroom because, as it's not trying to load the VSH file, the resource is unavailable.

However, I have a feeling that this is not the case and that Stunts always loads all four files, even in the showroom. The reason?  Well, it's simpler to do.
Title: Re: Replacing the main menu.
Post by: Daniel3D on May 29, 2021, 07:25:01 AM
Well, I hope you have time this weekend to make the test because I'm getting curious. And further speculating serves no purpose.  8)
Title: Re: Replacing the main menu.
Post by: Daniel3D on June 03, 2021, 02:19:00 PM
I think we can change the default track name as well.
https://bitbucket.org/dreadnaut/restunts/src/master/src/restunts/asmorig/seg000.asm#lines-310 (https://bitbucket.org/dreadnaut/restunts/src/master/src/restunts/asmorig/seg000.asm#lines-310)
    mov     ax, offset aDefault_0; "DEFAULT"
    push    ax
    mov     ax, offset gameconfig.game_trackname
    push    ax              ; char *
    call    _strcpy


Title: Re: Replacing the main menu.
Post by: Cas on June 03, 2021, 10:11:58 PM
Yes, I'm pretty sure it would work, but since it's called "DEFAULT", I think it could be fine to stay like that
Title: Re: Replacing the main menu.
Post by: Daniel3D on June 03, 2021, 10:40:42 PM
QuoteYes, I'm pretty sure it would work, but since it's called "DEFAULT", I think it could be fine to stay like that
that is true..
But. One thing that does bug me is the standard "Default" name when you save a replay... Better as something else.
"saved01" for instance (same amount of characters)
Title: Re: Replacing the main menu.
Post by: Cas on June 04, 2021, 07:43:38 PM
So by default it overwrites default.rpl? :o  I didn't know that... or remember that!  Not nice. It should warn you
Title: Re: Replacing the main menu.
Post by: Daniel3D on November 04, 2021, 10:28:02 AM
Back on topic. Something I discussed earlier with CAS.
Stunts is made is several modules, and I believe it's only these 4.
Title: Re: Replacing the main menu.
Post by: Cas on November 05, 2021, 01:19:17 AM
Memory initialisation may occur partly before the intro and partly after it, immediately before entering the menu. It can also be that some initialisation is made just before starting a race. For example, the current car is loaded before the menu (default car) because that way, you can get to the showroom and have it already there but even if you don't visit there, you can still directly race. I believe the default track is also loaded at that point. But the 3D scenery and track objects are probably loaded before the intro, as they will be in memory during the whole game and I think some objects seen during the intro share files with them.

Anyway, it is still possible to replace the menu without writing our own initialisation routine. We just have to find the point in the source where the menu starts and the points where each of the program sections that are called in the menu begin (these we can find in the menu routine). I don't think it'd be hard to find that. What would be some work is then writing the new menu routine and after that, unplugging the old one and plugging the new one in its place. This change is not simple, but it's very useful, as it can give us a section in the program that we have full control on where dynamic plug-ins can be attached.
Title: Re: Replacing the main menu.
Post by: Daniel3D on November 05, 2021, 01:43:42 PM
Quote from: Cas on November 05, 2021, 01:19:17 AM
It can also be that some initialisation is made just before starting a race. For example, the current car is loaded before the menu (default car) because that way, you can get to the showroom and have it already there but even if you don't visit there, you can still directly race.
Well, no.
The default car is set separately for:
Title: Re: Replacing the main menu.
Post by: Cas on November 06, 2021, 02:37:45 AM
There is a memory region to hold the player's car and another for the opponent's car. While in the showroom, I think cars are loaded in the respective slot (player/opponent) as you go through them. If you cancel, the previously selected car is reloaded. This is the way I would've done it if it were 1990. That saves memory. But we'll discover the truth as we continue to dig in the code :)