Compile without HUD

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Compile without HUD

Postby Curbfeeler » Tue Jan 15, 2013 5:36 pm

Hi. Just joined today and first post. Glad I did. This emulator is super-fun! Thanks so much for all your hard work here.

I'm interested in using the emulator to make a cut scene for a fan-based Star Wars movie. I've got the code to compile in VS2008 and can play wide-screen. Very awesome! Was wondering what is the easiest way to remove all the HUD and text prompts during gameplay. Would be ideal to only see the gameplay itself. the crosshairs and targeting around the tie fighters make you lose some of that immersiveness for my purposes. thanks in advance!

Dan
Curbfeeler
 
Posts: 3
Joined: Tue Jan 15, 2013 1:21 pm

Re: Compile without HUD

Postby Bart » Tue Jan 15, 2013 7:55 pm

Unfortunately, this is not a simple modification and will require you to understand both Supermodel's rendering engine and the underlying Model 3 scene graph data that it processes. It is the game which renders the HUD and games are free to organize things as they see fit. Supermodel has no knowledge of what's going on, it merely consumes the scene graph data that is passed to the Real3D GPU and blindly outputs it.

Model 3 has two independent graphics devices: the Real3D board for 3D graphics and a 2D tile generator that can display 2 layers behind and in front of the 3D graphics. In Star Wars, I believe that the dialog text and instructions are displayed as 2D tile layers and therefore will be the easiest for you to disable. The 2D renderer is in Src/Graphics/Render2D.cpp. Simply comment out the contents of CRender2D::EndFrame().

The rest of the HUD, including the targeting reticles, are 3D models displayed by the Real3D. Supermodel's 3D renderer is mostly contained in Src/Graphics/Render3D.cpp and Src/Graphics/Models.cpp. CRender3D::RenderFrame() is called each frame to draw the 3D graphics. You will unfortunately have to start from there and work out how Supermodel's rendering works and deduce from that what the underlying Model 3 data looks like. I don't have the time to provide a detailed overview of it all, unfortunately.

I can give you some helpful hints. The PowerPC writes data structures to the Real3D graphics memory, which are then parsed by the renderer and displayed. There are three basic data structures: viewports, culling nodes, and models. A complete 3D scene is called a 'viewport' and an arbitrary number of them can be drawn onto the screen each frame. Viewports can be used to create separate 3D scenes drawn as smaller insets or overlays, as you would expect. But in fact, any complex 3D scene in a Model 3 game is usually comprised of several viewports of the exact same size overlayed on top of each other. Why? Because lighting parameters, fog, and some other things can only be specified once per viewport. To change lighting color or direction on different objects, they have to be rendered in different viewports. The Z-buffer is cleared for each viewport.

Games will place their HUDs and status bars in separate viewports from the rest of the scene. What you need to do is discover which viewports are being used to do this in Star Wars and skip over them. Viewports are stored in Real3D memory as a linked list of structs. CRender3D::RenderViewport() will traverse this list and render all viewports with the given priority (viewports have priority and must be rendered accordingly, so Supermodel traverses the list multiple times).

The 'addr' parameter passed to RenderViewport() uniquely identifies the viewport. All you have to do is check for the viewport addresses you wish to skip and then skip over them. You must remember to draw the remaining viewports so I would place my code here:

Code: Select all
   // Recursively process next viewport
   if (vpnode[0x01] == 0)      // memory probably hasn't been set up yet, abort
      return;
    if (vpnode[0x01] != 0x01000000)
      RenderViewport(vpnode[0x01],pri);
      
   // Skip viewports we don't want
   if (addr == STARWARS_HUD_ADDR1)
      return;   // do nothing


How do you find the viewport addresses of interest? Well, that's up to you to figure out. My suggestion would be to print out all the viewports rendered each frame to stdout or to a log file. Examine the last frame printed out when you see the HUD on screen and then try them one-by-one. I actually have some tools that have not been publicly released which allow me to examine each viewport in a save state but these are finicky and you'd be better off just figuring it out the way I described.

Many Bothans died to bring you this information. May the Force be with you!
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Compile without HUD

Postby Curbfeeler » Wed Jan 16, 2013 2:23 pm

Bart - Thanks so much for this great info. I will dig in tonight and let you know the result soon. Again, can't thank you enough for what you did to bring these games to us.

Dan
Curbfeeler
 
Posts: 3
Joined: Tue Jan 15, 2013 1:21 pm

Re: Compile without HUD

Postby Bart » Wed Jan 16, 2013 3:40 pm

I thought of a potentially easier way to get rid of the HUD. Try skipping the highest priority viewports. I think there are 4 priority levels so it should take you no more than 4 attempts to determine whether this strategy is feasible. It will only work if the HUD viewport is assigned a different priority than the game world, which is likely but not guaranteed to be true.

The modification would be to RenderFrame() and I'm sure you can easily figure it out: simply avoid calling RenderViewport() for the priority level you wish to disable. Modify the for-loop bounds:

Code: Select all
for (int pri = 0; pri <= 3; pri++)
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Compile without HUD

Postby Curbfeeler » Thu Jan 17, 2013 6:33 am

Wow, can't tell you how impressed, pleased, and thankful I am. Your suggested fix to remove the 2D worked right off the bat and removed everything 2D from the game.

The other hint about removing the layers one-by-one was also right on, at least for the Battle of Yavin. I started by removing the first layer and it removed all the stars. I took this to mean I was on the wrong end of things, so I removed the 4th layer instead. Bingo!!! Now gameplay looks just like a movie and will do exactly what I want to do.

I'll shoot some screenies or a youtube this weekend in case anybody is interested. The same didn't quite work out for Hoth, so I will have to keep trying but will probably wait until I've captured the footage I need off Yavin first.

Thanks again!

Dan
Curbfeeler
 
Posts: 3
Joined: Tue Jan 15, 2013 1:21 pm

Re: Compile without HUD

Postby Bart » Thu Jan 17, 2013 1:08 pm

Glad to hear it's working. If the priority method doesn't work for Hoth, you'll have to use the more complex approach: search the viewports. There may be multiple viewports that need to be disabled.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada


Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest

cron