A very wierd question about resolutions

General discussion about nGlide.
paraemuladores
Posts: 14
Joined: Sun Nov 05, 2017 8:47 am

A very wierd question about resolutions

Post by paraemuladores »

Hello. I'm currently using nGlide 1.05 for a few games, for a very specific reason: I have a stereoscopic 3d monitor, and with nGlide 1.05 that emulates directx 9, I can play this games in stereo 3d with Tridef 3d. Everything works great!!
But I found a bit annoying that, having a widescreen monitor, when I set the resolution of Heretic II to 1920x1080 in the nGlide control panel, it stretches the image, but it also stretches the aspect ratio.
I know that nGlide can't change the aspect ratio of a game (i've been googleing it) to maintain it in widescreen resolutions; but, in Heretic II, I've seem to have found a solution: I got the game itself to work in 1920x1080, by a modified quake2.dll . So, in order for the game to work in stereo 3d without stretching the aspect ratio, I'd only need to select the 3dfx voodoo driver in the video settings, so I can use nGlide for the only reason of using DirectX 9 to render the game. I don't need nGlide to make a single change to the image, I only need it to allow me to play in stereo 3d. I've actually tried for a few hours, it works great!, but with the aspect ratio stretched :(
And here comes the problem. I selected this configuration:

Screen resolution: By the app
Aspect ratio: preserve original (and also tried fit to screen)
Refresh rate: By the app
Vertical syncronization: On
Gamma correction: 1.0
3Dfx logo splash screen: On (I need it on so I know that the game is using nGlide)

This appears to be the configuration that modifies the image the least. However, once I enter Heretic II, the game starts in 640x480, and it doesn't matter which resolution I put, when I press enter, it ALWAYS returns to 640x480. I tried modifying the game's inis, but the game still stays in 640x480 all the time. The only way to change the resolution while using nGlide is to change it in the nGlide control panel, and to set up the resolution there. But, if I do that, it stretches the aspect ratio.
So, the question would be: Is there any way to make nGlide not to modify anything in the image, making it only the renderer, and handling the rest of the video settings from inside the game? Or, is there any way to change the resolution of Heretic II while using nGlide?

This program really rocks!!
User avatar
Zeus
Site Admin
Posts: 1712
Joined: Sun Sep 21, 2008 2:51 pm
Contact:

Re: A very wierd question about resolutions

Post by Zeus »

There is a way, but you have to be familiar with programming/assembly in order to make it work.

Officially Glide API didn't allow to use anything other than a limited subset of 5:4 and 4:3 resolutions, but in 2015 VEG, the Need For Speed 3 Modern Patch author convinced me to implement an extension to it.

You can read our historical discussion about it here (a thread for the patch itself is located here). This made NFS3 a first Glide game running natively at 1080p and higher. Later on Drennan made his own patch for Clive Barker's Undying.


There are basically 3 things you have to modify in game engine to make a widescreen patch:

1) Change a resolution (obviously)

For Glide API you'll have to change how grSstWinOpen function is called.
If a game uses 640x480 originally it will call grSstWinOpen(hwnd, 7, ...)
7 is a constant for 640x480, 8 is 800x600, etc.

What you need to change is the second parameter and call function as:

grSstWinOpen(hwnd, 1080<<16 | 1920, ...)

2) Scale graphics content

3D: For a 3D content you'll need to multiply X and Y coordinates of every vertex by a vertical resolution scale factor.
For Glide API look for grDraw...() functions. They are fed with vertices. The most common and often the only one utilized in the whole game is grDrawTriangle().

The factor itself is calculated as: new_resolution.y divided by original_resolution.y, e.g.:

factor = 1080 / 480 = 2.25

Now you'll need to multiply both X and Y coords by 2.25 and add 240 to X coordinate to center it:
(1920 - (1080 * 4/3)) / 2 = 240.

Some game engines may do this automatically for you, but you'll have to make them "think" they use 1920x1080.

UI: In some cases it is also possible you'll have to reposition some HUD/UI elements. If a title won't allow you to change that in assets you'll need to modify it directly in the code.

2D: If a game uses 2D content (rare case) you'll need to scale it up with some algorithm (nearest neighbour for example). In Glide API 2D content is written only with 2 functions: grLfbLock() or grLfbWriteRegion(), so look for them if you need to.

3) Change a field of view

Different aspect ratio means different FOV parameter. Some engines allow the change in config/ini files (Heretic 2 does), but if not you'll have to change FOV calculations in game code (look for a code fragment where projection matrix is calculated). Equations can be found here.


Since you found a widescreen patch for OpenGL version of Heretic 2 it's possible 2) and 3) are already done, but 1) will still need to be implemented in Drivers\3dfxGL_Ht2.dll.
paraemuladores
Posts: 14
Joined: Sun Nov 05, 2017 8:47 am

Re: A very wierd question about resolutions

Post by paraemuladores »

Okey... Uhm, the most complex program I ever wrote was a dice game with no graphic interface with binary trees in C (linear C, not C++) and a little of Delphi, the 3rd version of the compiler; and that was over fifteen years ago, in high school. But I believe I can do it, if I put some effort. However, I'l like to ask you if you could be more specific, or if there are any kind of tutorials on how to do it exactly. You see, for example, when you refer to functions, I'm not sure if you mean the code of the game, or the nGlide. And, also, if I'm gonna need to compile code, I'd like to ask you to point me to some kind of free C++ compiler, if there actually exists such a thing (like I said, I haven't programmed anything since high school, so I'm absolutely out of the loop). I'm pretty sure with those few things I'll be able to make it. By the way, thanks for the reply! If I can do this, I can post the solution so other people can play Heretic II in Stereo 3D.
User avatar
Zeus
Site Admin
Posts: 1712
Joined: Sun Sep 21, 2008 2:51 pm
Contact:

Re: A very wierd question about resolutions

Post by Zeus »

paraemuladores wrote:Okey... Uhm, the most complex program I ever wrote was a dice game with no graphic interface with binary trees in C (linear C, not C++) and a little of Delphi, the 3rd version of the compiler; and that was over fifteen years ago, in high school. But I believe I can do it, if I put some effort.
Your programming experience should be enough, but you'll also need to know how to read and write assembly code. A compiler isn't necessary, but a hex-editor like HxD and a debugger (I recommend OllyDbg2). IDA disassembler isn't required, but it's very useful with its assembly code graph view and xrefs (version 5.0 is free).
paraemuladores wrote:However, I'l like to ask you if you could be more specific, or if there are any kind of tutorials on how to do it exactly. You see, for example, when you refer to functions, I'm not sure if you mean the code of the game, or the nGlide.
You don't need to touch nGlide (glide2x.dll in our case), but game driver (3dfxGL_Ht2.dll in this case) that use those gr_ functions from glide2x.dll. The task is to find where grSstWinOpen from glide2x.dll is called in 3dfxGL_Ht2.dll and change its second parameter.
paraemuladores
Posts: 14
Joined: Sun Nov 05, 2017 8:47 am

Re: A very wierd question about resolutions

Post by paraemuladores »

Okey. This is challenging!! :) I'm using IDA, since it's a lot more detailed than any hex editor I've ever seen. Now, here's the thing. Both of the times I found a call to grSstWinOpen, I find this line:

call _grSstWinOpen@28 ; grSstWinOpen(x,x,x,x,x,x,x)

Since grSstWinOpen() is after point and comma, I assume that's just a comment. So, I believe that _grSstWinOpen@28 is a macro. So, I searched the string "glide2x" to find, uhm, where glide2x.dll meets the function (I'm sorry, I just can't remember the correct programming terms) and found this lines:

.idata:100273C8 ; __declspec(dllimport) __stdcall grSstWinOpen(x, x, x, x, x, x, x)
.idata:100273C8 extrn __imp__grSstWinOpen@28:dword
.idata:100273C8 ; DATA XREF: grSstWinOpen(x,x,x,x,x,x,x)r

And I found grSstWinOpen@28 in another line:

.text:1000EB40 _grSstWinOpen@28 proc near ; CODE XREF: wglCreateContext+5CCp
.text:1000EB40 ; .text:100038BEp
.text:1000EB40 jmp ds:__imp__grSstWinOpen@28 ; grSstWinOpen(x,x,x,x,x,x,x)
.text:1000EB40 _grSstWinOpen@28 endp

I'm pretty sure grSstWinOpen@28 is a macro that's just a way to define grSstWinOpen with given parameters. But I can't find the definition of the macro anywhere in the file. And, being it a macro, I can't change anything, just call it or erase it, but I can't modify it. Is there anything I can do? Or, am I doing something wrong?
Also, please tell me the options in the UI or the commands to replace something in the file, because I couldn't find the way to do it, I can see the file in any way I want, but I couldn't modify anything. If you tell me the commands, please tell me where do I insert them, I only saw them in the lower window the commands inserted by the options in the UI. Also, if the only way to modify the file is modifying the assembly code directly, I'd like to ask you to give an example of how to do it. I learned hexadecimal at high school, and I remember it, but I used it only in electronics, I never used it to modify files in hex (the few times I did, I knew from the start what to look for, and what to replace it with, but I never had to actually comprehend the code I replaced).
User avatar
Zeus
Site Admin
Posts: 1712
Joined: Sun Sep 21, 2008 2:51 pm
Contact:

Re: A very wierd question about resolutions

Post by Zeus »

paraemuladores wrote:.text:1000EB40 _grSstWinOpen@28 proc near ; CODE XREF: wglCreateContext+5CCp
.text:1000EB40 ; .text:100038BEp
.text:1000EB40 jmp ds:__imp__grSstWinOpen@28 ; grSstWinOpen(x,x,x,x,x,x,x)
.text:1000EB40 _grSstWinOpen@28 endp
Now you need to right click on _grSstWinOpen@28 and select Jump to xref to operand. This will give you all locations where grSstWinOpen is called from. We are interested in wglCreateContext+5CC location. As you can see the second argument comes from edx register and on top of it there are several conditions that must be changed. You can switch to Graph View to visualize conditions in a much nicer format.
paraemuladores wrote:I can see the file in any way I want, but I couldn't modify anything.
You don't modify anything in IDA, but in your hexeditor like HxD. You take an offset from disassembler and open it in a hex editor. To confirm you're at correct location you can enable opcodes in IDA (Options->General: Number of opcode bytes, changing it to 8 will be enough).

If this won't take me much time I will try to make necessary changes and upload modified files here. No promises though...
paraemuladores
Posts: 14
Joined: Sun Nov 05, 2017 8:47 am

Re: A very wierd question about resolutions

Post by paraemuladores »

Zeus, I'm sorry, but, this line:

.text:1000EB40 _grSstWinOpen@28 proc near ; CODE XREF: wglCreateContext+5CCp
.text:1000EB40 ; .text:100038BEp
.text:1000EB40 jmp ds:__imp__grSstWinOpen@28 ; grSstWinOpen(x,x,x,x,x,x,x)
.text:1000EB40 _grSstWinOpen@28 endp

I can't find it anymore. I tried a lot of times, but it just isn't there. However, I remeber I tinkered a lot with the way to open the dll. Could you point me to the right options to correctly open it? Or, if that's not the problem, what could be? I erased the .idb files always because I feared I had modified the dll file on purpose (now I know that I can't do that with IDA). This time, when I open it, I won't erase the .idb file.
User avatar
Zeus
Site Admin
Posts: 1712
Joined: Sun Sep 21, 2008 2:51 pm
Contact:

Re: A very wierd question about resolutions

Post by Zeus »

paraemuladores wrote:Zeus, I'm sorry, but, this line:

.text:1000EB40 _grSstWinOpen@28 proc near ; CODE XREF: wglCreateContext+5CCp
.text:1000EB40 ; .text:100038BEp
.text:1000EB40 jmp ds:__imp__grSstWinOpen@28 ; grSstWinOpen(x,x,x,x,x,x,x)
.text:1000EB40 _grSstWinOpen@28 endp
Simply press G and enter 1000EB40 or double click on _grSstWinOpen@28 in Imports tab and right click on __imp__grSstWinOpen@28, select jump to xref to operand.
User avatar
Zeus
Site Admin
Posts: 1712
Joined: Sun Sep 21, 2008 2:51 pm
Contact:

Re: A very wierd question about resolutions

Post by Zeus »

Ok, I have good news regarding modifications. It wasn't hard to force the game working properly in HD/full HD. If you want you can analyze the changes (compare two files in HxD and then two .idbs in IDA).

The patch is really simple, it only replaces 1280x960 and 1600x1200 modes to 1366x768 and 1920x1080 accordingly.

Here's the list of things I changed:
- a fov parameter in user\config.cfg from 75.0 to 91.0
- four integers in quake2.dll (1280=>1366, 960=>768, 1600=>1920, 1200=>1080)
- four integers in Drivers\3dfxGL_Ht2.dll (0xD=>0x03000556, 0xE=>0x04380780, 0x400=>0xFFFF, 0x300=>0xFFFF):
  • - 0xD (13) is a constant for 1280x1024 in Glide API; changed to 0x03000556 that is a result of (768<<16) | 1366
    - 0xE (14) is a constant for 1600x1200 in Glide API; changed to 0x04380780 that is a result of (1080<<16) | 1920
    - 0x400 => 0xFFFF and 0x300 => 0xFFFF, I only had to change them to disable resolution limit condition
- one float in Drivers\3dfxGL_Ht2.dll (1280.0f => 1366.0f) to correct resolution selection condition

Instructions for the patch:
1) install Heretic2 1.06 update (if you didn't yet)
2) extract heretic2_106_glide_ws.zip contents into game directory
3) set "Screen resolution: By app (Default)" and "Aspect ratio: Fit to screen (Default) in nGlide configurator"
4) launch the game and change resolution in Video options
Attachments
heretic2_106_glide_ws.zip
(668.99 KiB) Downloaded 1336 times
paraemuladores
Posts: 14
Joined: Sun Nov 05, 2017 8:47 am

Re: A very wierd question about resolutions

Post by paraemuladores »

Great!! Thanks a lot, Zeus!! :) :) :) :) :) :) I'll reinstall the game and get back to you (I've already made a lot of tweaks to it, I believe it'll be better to just reinstall it clean).
Post Reply