Aspect ratio of the 2D layers

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!

Aspect ratio of the 2D layers

Postby Daro » Tue Nov 17, 2020 4:01 pm

Hello everyone, long time lurker, first time poster.

I've been looking into correcting the aspect ratio of the tile layer generator output for widescreen modes, as I've noticed vf3 and lemans24 would benefit from it:

Image

I understand this wouldn't be "accurate" behavior, but once you're running games in 16:9 (which a lot of users do) I guess the user is not very concerned about accuracy anymore. So full disclaimer, I'm not a coder by any extent of the imagination, but I looked through Render2D.cpp and aside from being amazed at how well documented everything is, I found out that commenting out line 549 in the Frame Display Functions section

Code: Select all
glViewport(m_xOffset - m_correction, m_yOffset + m_correction, m_xPixels, m_yPixels);


produces some of the desired effect, affecting all 2D layers (I'm sure this is a very hacky way to go about things, but I don't know any better):

Image

Image

Image

Unsurprisingly, Le Mans 24's attract mode and ending now looks a little bit weird:

Image

Image

So obviously this is far, far from a perfect solution, but all in all, I think this is still a desirable tradeoff.

Now, the reason I'm posting is to ask the devs for some pointers, because I'd like to correct only the bottom layer, leaving things in the top layer like HUDs and menus displaying in 4:3. If I understood anything at all, it seems like right now both layers are drawn to one surface, and in order to get this working the way I want, I'd need to get the layers to draw to different surfaces so I can correct them independent of each other. Am I going in the right direction?

Anyway, I hope I'm not being too much of a hassle. I really appreciate the enormous amount of work you all put into making this beautiful piece of software.
User avatar
Daro
 
Posts: 5
Joined: Tue Nov 17, 2020 2:48 pm

Re: Aspect ratio of the 2D layers

Postby Bart » Thu Nov 19, 2020 10:59 pm

There are a number of strategies that can be used for expanding background layers in wide-screen mode but none of them will work in all cases. It depends on what the artistic intent is for a given scene. You can do any of the following:

- Repeat the background. If the background scrolls and is intended to simulate a sky, it probably wraps, and could potentially be expanded by an integer multiple of the screen width.
- Fill the extra space of each scan line with a solid color. This will look best when the layer is being used to display text or a specific graphical pattern that should not repeat.
- Simply stretch (as you have done).

I think ElSemi's Model 2 emulator allows scripts to be written that monitor a game's state and implement the appropriate strategy. I'd love to support this in Supermodel but it's a lot of non-trivial work and probably won't happen for a long time if ever. In the mean time, stretching is a possibility. I'm not sure whether we would want to include this as a feature in Supermodel but if you find that it generally works well maybe it could be a run-time configurable option.

I can explain how the code you found works. On each frame, Supermodel calls CRender2D::PreRenderFrame(), RenderFrameBottom(), and then RenderFrameTop(). "Top" and "bottom" refer to layers positioned on top of or below the 3D graphics layer, respectively. Depending on how layer priorities are configured by a game, zero or more layers can be drawn in either of these calls. PreRenderFrame() renders all the layers into a top and bottom texture map. These are of size 496x384 (although the actual texture itself may be 512x512, if I remember correctly, with the extra parts unused). RenderFrameBottom() will actually draw the bottom texture to the screen. It is the first thing drawn each frame and if there are no layers on the bottom, it simply clears the frame buffer. Next, 3D graphics are drawn (elsewhere in the 3D renderer), and the last step is RenderFrameTop().

RenderFrameTop() and RenderFrameBottom() are almost identical. They do the following:

1. Call Setup2D() to set up OpenGL drawing state. Most importantly, this function sets the shader that is used to draw the tile layers (it's a super simple shader that just reads from the layer texture map directly), sets up the viewport (the rectangular area on the screen to which we will draw the layer), and creates an orthographic projection (i.e., no perspective).
2. Call DisplaySurface(). This function selects the appropriate layer texture (top or bottom) and draws a giant quad that is the same size as the viewport defined in [1]. That's how the layer gets blitted to the screen. The glVertex2f() calls are what define the quad and the coordinates are normalized to the viewport (e.g., x=0 is the far left of the viewport, x=1.0 is the far right).

The line you commented out is in Setup2D(). It constrains the drawing area to a viewport that is of the correct aspect ratio and at the correct location on screen. If wide-screen mode is disabled and the display resolution is the same aspect ratio as Model 3 (496:384), the viewport is basically the same as the screen (there's a small one or two pixel correction Ian applies for alignment to 3D). If the aspect ratio differs, for example by being wider, then the viewport is smaller. The x and y offset are non-zero in this case and the width and height are smaller than the screen dimensions. This places the viewport in the center of the screen.

By commenting out that line, you end up using whatever last viewport was set, which happens to be the entire screen. And so the texture gets stretched.

There is also a scissor operation applied and unfortunately, I can't remember what this does. Scissor defines a rectangular clipping region and I forget offhand what we define as the scissor region in this case. I believe it ensures that nothing is rendered outside the constrained viewports.

If you read Setup2D() carefully, you will notice that it takes a parameter that tells it whether we are rendering the bottom or top layer. The parameter is aptly named "isBottom". When isBottom == false, the top layers are being drawn. I think what you want to do is avoid calling glViewport() for bottom layers but otherwise call it. There might need to be some additional logic for the scissor, when it is applied. But this is a starting point.

Lastly, all this code is a bit brittle because it depends on how viewport was set outside of the RenderFrameBottom() call. To make this more robust, we should probably pass in the underlying screen dimensions to CRender2D() so it can set that explicitly when you want to stretch.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Aspect ratio of the 2D layers

Postby Daro » Fri Nov 20, 2020 1:42 am

So I went through your post and got it working immediately:

Image

Image

Regarding graphics outside of the original 4:3 ratio, Le Mans 24 behaves particularly well, with this screenshot being the worst case scenario:

Image

VF3 doesn't play as nice, as it uses the top layer to hide the loading of models and textures. Stretching the bottom layer makes the character select screen look worse, but gameplay looks much, much better.

Image

As to whether this should be a run-time option, I really believe so, especially if adding it doesn't translate into a lot of work for you. But then again, I'm not extremely familiar with the entirety of the Model 3 catalog, so I don't know if any other games use 2D backgrounds. I'll go through it and let you know if something turns into a graphical mess.

By the way, thanks so much for such an elaborate reply. It was probably easier and faster to make the changes yourself, but you took the time to try and teach me something instead. I appreciate it.
User avatar
Daro
 
Posts: 5
Joined: Tue Nov 17, 2020 2:48 pm

Re: Aspect ratio of the 2D layers

Postby Bart » Sat Nov 21, 2020 5:17 pm

Glad you got it working! I'm still torn about whether this should be an option but I think users would like it. Do you think there should be independent options for stretching the foreground and background layers? Enabling both would be equivalent to simply using the -stretch option. Maybe you could add "-stretch-2d-bg" and "-stretch-2d-fg" options to Main.cpp. The functions you want to modify are Help(), ParseCommandLine(), and DefaultConfig().
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Aspect ratio of the 2D layers

Postby SegaLover2020 » Sun Nov 22, 2020 2:21 am

I only speak for myself here but I'd love to have that option, especially in virtua striker where the background 2d image is too small for the whole stadium.
User avatar
SegaLover2020
 
Posts: 63
Joined: Wed Aug 19, 2020 10:49 pm

Re: Aspect ratio of the 2D layers

Postby Ian » Sun Nov 22, 2020 6:23 am

I'm a bit mixed about this feature request. Personally I wouldn't implement it, but I don't see the harm if it is added, as long as it is simply disabled by default. Then users can toggle it when they want it.
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Aspect ratio of the 2D layers

Postby Daro » Sun Nov 22, 2020 7:20 am

Bart wrote:Maybe you could add "-stretch-2d-bg" and "-stretch-2d-fg" options to Main.cpp. The functions you want to modify are Help(), ParseCommandLine(), and DefaultConfig().


Okay so I've successfully added -stretch-2d-bg and -fg options. I've gotta say, I can't think of many uses for stretching the foreground layer alone, but you know, there it is. Keep in mind that I'm a designer and not a programmer, and any examples of my "code" will make this immediately evident :)

Oh yeah, and as it turns out there are five games (and their respective variations) that use 2D backgrounds: Virtua Fighter 3/tb, Le Mans 24, Get Bass(or Sega Bass Fishing), the Virtua Striker 2 series (base, '98, '99 and '99.1), and The Lost World: Jurassic Park. I think The Lost World in widescreen is a bit pointless because you obviously can't shoot the edges of the screen, but it still looks nice for the most part.

Ian wrote:Personally I wouldn't implement it, but I don't see the harm if it is added, as long as it is simply disabled by default. Then users can toggle it when they want it.


I agree with you on all counts. I think emulators should present the games as close as possible to the original hardware, but users like myself would enjoy having the option, especially since widescreen has been an option for the longest time.

SegaLover2020 wrote:especially in virtua striker where the background 2d image is too small for the whole stadium.


Virtua Striker looks good when you stretch the bg layer. However, this game really loves its 4:3 ratio, and all geometry output is closely limited to the original screen area, causing a lot of pop-in around the edges of a 16:9 frame. So that's the other issue with the game in widescreen. You'll have to ask Bart and Ian, but I suspect this is not something you can fix from the emulator side of things.

Image

You can see how it mainly affects parts of the stadium, but it also affects players. Still very playable, nonetheless.
User avatar
Daro
 
Posts: 5
Joined: Tue Nov 17, 2020 2:48 pm

Re: Aspect ratio of the 2D layers

Postby SegaLover2020 » Mon Nov 23, 2020 6:36 am

Daro wrote:You can see how it mainly affects parts of the stadium, but it also affects players. Still very playable, nonetheless.


Well done, so what do I have to do to get the same result?
User avatar
SegaLover2020
 
Posts: 63
Joined: Wed Aug 19, 2020 10:49 pm

Re: Aspect ratio of the 2D layers

Postby Bart » Mon Nov 23, 2020 12:56 pm

Is there an alternative formulation of the parameters that would make sense and provide the utility you seek? For example, should we only allow the bg version of the option? I agree with Ian. If this is really desired by some power users, I would like to see this option off by default.
User avatar
Bart
Site Admin
 
Posts: 3086
Joined: Thu Sep 01, 2011 2:13 pm
Location: Reno, Nevada

Re: Aspect ratio of the 2D layers

Postby Daro » Mon Nov 23, 2020 5:56 pm

Well, in my opinion, there isn't a valuable use case for stretching the foreground alone. I'd say -stretch-2d-bg is far more valuable and the only option worth adding, specifically for those five games I mentioned before. Bart, Ian: If you want, I can send you the files I modified, which would be Main.cpp, Render2D.cpp and Render2D.h, so you can go ahead and have a chuckle at the mess I've made. I've found no issues while testing the emulator with those changes. The files correspond to the r832 version of Supermodel. Let me know.

SegaLover2020 wrote:Well done, so what do I have to do to get the same result?


I'm sorry to say this, but you should probably wait until the devs add these options themselves, since this sounds like the most responsible thing to do. To my eyes, everything works properly, but I'm highly inexperienced with these matters, and I might have messed something up while poking around in the code. If they say otherwise however, I'll be glad to help you out.
User avatar
Daro
 
Posts: 5
Joined: Tue Nov 17, 2020 2:48 pm

Next

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest