News:

Herr Otto Partz says you're all nothing but pipsqueaks!

Main Menu

Replacing the main menu.

Started by Daniel3D, May 24, 2021, 11:14:28 PM

Previous topic - Next topic

Daniel3D

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.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

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.
Earth is my country. Science is my religion.

Daniel3D

#2
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?
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

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.
Earth is my country. Science is my religion.

Duplode

Hello! A few really quick notes:

  • I don't know/remember much about memory management. My excursions through the code were mostly done, so to say, on the edges rather than the core, focusing on making sense of the game engine logic.
  • On strategies to modify the code: if we can get it to work, the restunts toolchain would probably be a convenient way to do it, as its main goal was making it possible to recompile Stunts while replacing functions in the source code (for instance, with the ports to C of those functions).
  • On 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 to choose which of the secondary menus gets opened (the analysis you can see in those parts assembly code was done by the restunts team, rather than by me). While I don't think run_menu itself has been ported, the call I just mentioned can also be found in the ported code in restunts.c.

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.

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. 

Daniel3D

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.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

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.
Earth is my country. Science is my religion.

Daniel3D

#7
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.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

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.
Earth is my country. Science is my religion.

Daniel3D

Well, I hope you have time this weekend to make the test because I'm getting curious. And further speculating serves no purpose.  8)
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Daniel3D

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
    mov     ax, offset aDefault_0; "DEFAULT"
    push    ax
    mov     ax, offset gameconfig.game_trackname
    push    ax              ; char *
    call    _strcpy


Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

Yes, I'm pretty sure it would work, but since it's called "DEFAULT", I think it could be fine to stay like that
Earth is my country. Science is my religion.

Daniel3D

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)
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)

Cas

So by default it overwrites default.rpl? :o  I didn't know that... or remember that!  Not nice. It should warn you
Earth is my country. Science is my religion.

Daniel3D

Back on topic. Something I discussed earlier with CAS.
Stunts is made is several modules, and I believe it's only these 4.
  • The intro sequence.
  • The menu structure. (including Evaluation)
  • The race 3D engine for Race and Replay.
  • The track editor.

    In the menu, several parameters are loaded or stored.
  • display settings - scenery, FPS
  • track
  • car, colour, shift
  • opponent + car and colour.

    Those parameters are used to load the race engine.
    ...
    If we can make a little program that can load these parameters in memory, (+maybe some other things needed)
    then we could maybe start racing without going through intro and menus.
    If we can do that, then replacing the menu becomes a real possibility.
Edison once said,
"I have not failed 10,000 times,
I've successfully found 10,000 ways that will not work."
---------
Currently running over 20 separate instances of Stunts
---------
Check out the STUNTS resources on my Mega (globe icon)