VOGONS


Reply 20 of 53, by Dege

User metadata
Rank l33t
Rank
l33t
kjliew wrote:

I noticed that dgVoodoo may have miscalculate the rendering window size by 1 pixel. When dgVoodoo takes over the window, the window is missing the right and bottom border. OpenGlide and psVoodoo are OK. This applies to both 32-bit and 64-bit dgVoodoo.

Say, when the game is running at 640x480 then it's window client size is 639x479? I'll check it out.

kjliew wrote:

Another 64-bit only issue, but this time it applies to both dgVoodoo & psVoodoo. And, this is about a game demo, NFS 2 SE, the executable is nfs2sea.exe. Both dgVoodoo & psVoodoo are rendering with complete white screen.

Isn't it because of the fogtable problem you mentioned? I mean, the screen is white because everything is in full fog or sg like that.
Unfortunately I could only debug the x64 version through QEMU.

Reply 21 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

HI Dege,

Attached the patch for QEMU 3Dfx Glide pass-through. It should work with any recent version of QEMU. I am testing with the following version:
QEMU 2.12.0 (sdl2)
QEMU 2.9.1 (sdl1/sdl2)
QEMU 1.6.2 (sdl1)(patch failed for 1 hunk, but manual merge is easy)

You will need MSYS2/mingw-w64 GCC toolchain build environment & bash shell. Here's a brief instruction on how to apply the patch assuming you are familiar with bash shell.

$ mkdir ~/myqemu4fun
$ cp qemu64-3dfx-20180627.tar.gz ~/myqemu4fun
$ cd ~/myqemu4fun
$ wget https://download.qemu.org/qemu-2.12.0.tar.xz
$ tar xf qemu-2.12.0.tar.xz
$ mv -v qemu-2.12.0 devel
$ tar xf qemu64-3dfx-20180627.tar.gz
$ patch -p0 < ./hw/3dfx/3dfx.patch
$ mkdir build
$ cd build
$ ../devel/configure
$ make

I added window resizing helper code in QEMU for OpenGlide & PsVoodoo to render into the same QEMU window. (See glide_prepare_window() in sdl.c/sdl2.c) Somehow, dgVoodoo2 is capable of rendering into QEMU window without the helper code, but with the 1-pixel off in width and height. Unfortunately, dgVoodoo1 just hung, similar to OpenGlide & PsVoodoo before I took out their window resizing code. Not sure if you would still be interesting to fix this issue for dgVoodoo1 or we will just retire it.

I am having hard time to figure out why window resizing cannot be done by Glide wrappers, as they can be done in DOSBox. Any call to MoveWindow() or SDL_SetVideoMode() simply crashed QEMU, or required QEMU to create a separate window for Glide rendering. I also have the code for Glide wrapper to render into its own window, but I removed it in favor of rendering into the same QEMU window. Unfortunately, while the helper code works for OpenGlide & PsVoodoo, it broke dgVoodoo2 for QEMU on SDL2. QEMU on SDL1.2 is fine. I think this has to do with the off by 1-pixel from dgVoodoo2. Glide session worked once and upon exited, QEMU window shrunk into just the title bar. I am still debugging this from QEMU side.

Dege wrote:

Say, when the game is running at 640x480 then it's window client size is 639x479? I'll check it out.

I think it is more likely 641x481, since it overlapped the right & bottom border, which have the thickness of 1 pixel. Or perhaps, something more serious, as once dgVoodoo2 is done, it seems to corrupt the rendering context of QEMU and switching out dgVoodoo2 with OpenGlide or PsVoodoo does not change anything. QEMU has to be restarted to fix this.

Looking forward to more good news from you, especially on fixing the 64-bit fogging issue. 😀

Update: It turned out that the window resizing helper code was the problem, not dgVoodoo2. So considered this resolved, as now I have dgVoodoo2 rendered correctly with all the borders. I updated the new patch in the OP.

Reply 22 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

Hi Dege,

I think 64-bit dgVoodoo2 really have some serious rendering issues. I managed to get more games to try. All of them work with 32-bit dgVoodoo255_2. Adding the list of games with rendering issues:
- NFS 3 Hot Pursuit
- Nuclear Strike
- MDK 3Dfx
- NFS 2 SE

I believe all these games share the same issue. If you manage to fix one of them, then you are probably fixing all of them. They show strange colors on the screen. Let me know if a screenshot will be helpful.

NFS 3 Hot Pursuit has other rendering issues with fogging even on 32-bit dgVoodoo255_2, but I considered it working because OpenGlide produces the same rendering. I recompiled OpenGlide to disable Fog and the game looked better then, but still there are issues on the car body reflection of light. I think NFS3 may have special handling of fogging by looking at the symbols from voodooa.dll/voodoo2a.dll.

Have you ever checked out NFS 3 Hot Pursuit with dgVoodoo255_2 natively in GLIDE mode? Your website compatibility report has NFS 2 Hot Pursuit, but the screenshot looked like NFS 3, and NFS 2 did not go with "Hot Pursuit". There was also no indication if this was with D3D or GLIDE renderer.

Hopefully, you are starting to build and try out QEMU with dgVoodoo2. Looking forward to getting a solid 64-bit dgVoodoo2 to go with QEMU from you. 😎

Reply 23 of 53, by Dege

User metadata
Rank l33t
Rank
l33t

Thanks! I didn't look into QEMU yet at all because I have near zero time nowadays again, but, couldn't I just try to use a precompiled binary with your patch? The point is debugging dgVoodoo (at least, I think) in the same way as for games.

Reply 24 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

Sure. However, running QEMU x64 built from mingw-w64 has a number of dependencies DLLs. Let me take a look if static build is possible or I will just package all the dependencies with it.

Anyway, you will need to prepare your own disk image for win9x, unless you already have one lying around that can be supported by QEMU. QEMU can work with different formats of disk image. I think this is going to take more time than building QEMU if you don't already have a win9x disk image.

I will get back to you on the prebuilt QEMU.

Update: Attached the version of QEMU with 3Dfx Glide pass-through patch. I picked the QEMU version with reduced dependencies. Hopefully, all the DLLs are included. Let me know if you have any issue getting it to work. You will need to provide your own OS disk image.

Update2: If you are setting up Win98 image, I found that forcing ACPI option during win98 setup is the best way to get the OS running under QEMU. Use "SETUP /pj /nm". This should give you the Cirrus 5446 PCI SVGA card currently emulated by QEMU.

Attachment moved to top.

Last edited by kjliew on 2018-07-06, 09:39. Edited 1 time in total.

Reply 25 of 53, by Dege

User metadata
Rank l33t
Rank
l33t

I managed to set up a working Win98 virtual machine run by qemu-system-i386.exe (the binaries from your pack).
However 64bit Glide dlls don't get loaded by the virtual machine so guest glide dlls don't work.
Should it work out of the box or some command line switch is needed?

Reply 26 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

No command line switch is required. It uses WINAPI LoadLibrary to load the host glide2x.dll. So for Windows, the standard DLL search path for LoadLibrary applies. You should also be getting the debug info from stdout. Below is the stdout from running the Glide SDK TEST04.

glidept: DLL loaded - glide2x.dll
glidept: grGlideGetVersion Glide 2.45 - OpenGLide 0.09rc9
glidept: grSstWinOpen called
glidept: grGlideShutdown called
glidept: DLL unloaded

I downloaded and double checked the same pack at attached on Windows command prompt. No issue loading the host glide2x.dll. Here's my dir listing. I use OpenGlide, so I need an additional libstdc++-6.dll for OpenGlide.

C:\MyData\_qemu\local\bin>dir
Volume in drive C has no label.
Volume Serial Number is 12A8-35B9

Directory of C:\MyData\_qemu\local\bin

07/05/2018 12:21 PM <DIR> .
07/05/2018 12:21 PM <DIR> ..
07/05/2018 12:15 PM 783,638 glide2x.dll
06/30/2018 06:07 PM 83,088 libgcc_s_seh-1.dll
06/30/2018 06:07 PM 1,143,569 libglib-2.0-0.dll
06/30/2018 06:07 PM 1,055,010 libiconv-2.dll
06/30/2018 06:07 PM 132,146 libintl-8.dll
06/30/2018 06:07 PM 286,369 libpcre-1.dll
06/30/2018 06:07 PM 682,872 libpixman-1-0.dll
07/05/2018 12:21 PM 1,435,729 libstdc++-6.dll
06/30/2018 06:07 PM 57,317 libwinpthread-1.dll
06/30/2018 06:07 PM 5,882,580 qemu-system-i386.exe
06/30/2018 06:07 PM 1,141,020 SDL2.dll
06/30/2018 06:07 PM 93,830 zlib1.dll
12 File(s) 12,777,168 bytes
2 Dir(s) 58,348,089,344 bytes free

C:\MyData\_qemu\local\bin>qemu-system-i386 -L ..\..\share\qemu -vga cirrus -drive format=raw,file=c:\mydata\vmimgs\w98q.ima -rtc base=localtime -no-hpet -soundhw pcspk,ac97
glidept: DLL loaded - glide2x.dll
glidept: grSstWinOpen called
glidept: grGlideShutdown called
glidept: DLL unloaded

Reply 27 of 53, by Dege

User metadata
Rank l33t
Rank
l33t

Thanks, now it works. Glide dll's were corrupted for some reason...

I debugged TEST08 and what I can see is float parameter is passed incorrectly to Glide_x64:

(The test passes 0.01 as density to the function but I can see -1.37973736e-21 instead on the x64 side:

Glide64_Bug.png

Since density is the second parameter and float type, it should be passed through xmm1.

Reply 28 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

OK, I think I know where the problems arise. To make the glide pass-through simple and without the need to include 3Dfx SDK header files, I generalized the function arguments into uint32_t/uintptr_t type. I think I had had a good lesson learned on WIN64 C ABI, that float/double are passed using XMM registers. I will fix the code for GLIDE APIs with float arguments.

Update: I have fixed the pass-through for Glide APIs with float arguments. I updated the QEMU package in the 1st post for you to try out. All previous non-working games on 64-bit dgVoodoo2 are now rendered correctly as in 32-bit counterpart. It is strange that this issue wasn't evident in WIN32 C ABI. I thought the WIN32 C ABI for __stdcall would have expected the float arguments to be passed in FPU ST[0...3], or they are not.

Anyway, things are working out beautifully for WIN64 QEMU 😀 , and QEMU really needs that extra 10~15% speed improvement from TCG to run the games.

Did you get a chance to try out NFS 3 Hot Pursuit? I think this game uses fogging for car body reflection, and both 32-bit/64-bit OpenGlide/dgVoodoo2 do not render correctly compared to running the game natively in Direct3D mode.

Reply 29 of 53, by Dege

User metadata
Rank l33t
Rank
l33t

Great!

kjliew wrote:

I thought the WIN32 C ABI for __stdcall would have expected the float arguments to be passed in FPU ST[0...3], or they are not.

No, Win32 _stdcall always passes parameters on the stack. Win64 expects the first 4 parameters in the corresponding expected registers (if possible) but also reserves their room on the stack.

kjliew wrote:

Did you get a chance to try out NFS 3 Hot Pursuit? I think this game uses fogging for car body reflection, and both 32-bit/64-bit OpenGlide/dgVoodoo2 do not render correctly compared to running the game natively in Direct3D mode.

I didn't try it but isn't it an expected difference between 3Dfx and D3D? I also don't know which NFS3 version you're trying. VEG made a wonderful patch for that game, if not that one is what you're using then let's give it a go. 😉

Reply 30 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie
Dege wrote:

I didn't try it but isn't it an expected difference between 3Dfx and D3D? I also don't know which NFS3 version you're trying. VEG made a wonderful patch for that game, if not that one is what you're using then let's give it a go. 😉

Yes, that's the version I have, NFS 3 Hot Pursuit. I remembered I played it on a real Voodoo2, and later with Direct3D and renaming the D3DA.DLL to VOODOO2A.DLL to get 1024x768 resolution. IIRC, the Voodoo2 rendering had better smog effects and projected headlight. The games used to work pretty good from WinXP->Win7, but those are 32-bit era. I didn't remember I tried it on Win7 x64. Now, to get it run on Win 10 Pro x64 is pretty challenging. All the NFS series with accelerated 3D rendering also don't work under DOSBox/Win9x.
Well, the goal with QEMU 3Dfx Glide pass-through is to get the games going seamlessly as long as they support 3Dfx Glide, only if the Glide wrappers are able to render them correctly.

Update: I tried VEG modern patch for NFS3. It works on Win10 Pro x64 natively with dgVoodoo2. The rendering is correct as far as I remember. I found that a number of NFS3 fixes are providing replacement of VOODOO2A.DLL which uses glide3x instead of glide2x. The original VOODOO2A.DLL comes with my NFS3 CD is using glide2x. Perhaps, the Glide wrappers can only render the game correctly with Glide3x??

Reply 31 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

Hi Dege,

Would you please provide 64-bit build of glide3x.dll, too? I am adding the support for wrapping glide3x APIs in QEMU. Hopefully, this would get NFS3 to play within QEMU, too, and other 3Dfx OGL based games, such as Homeworld. The 3Dfx OGL driver requires glide3x.

Reply 32 of 53, by Dege

User metadata
Rank l33t
Rank
l33t
kjliew wrote:

Update: I tried VEG modern patch for NFS3. It works on Win10 Pro x64 natively with dgVoodoo2. The rendering is correct as far as I remember. I found that a number of NFS3 fixes are providing replacement of VOODOO2A.DLL which uses glide3x instead of glide2x. The original VOODOO2A.DLL comes with my NFS3 CD is using glide2x. Perhaps, the Glide wrappers can only render the game correctly with Glide3x??

NFS3 renders through the various versions of Thrash drivers having a common internal interface for all impls like Glide2,3, D3D and such. I guess the difference comes from the implementations of the Glide2x and 3x and that's why Veg changed the original Voodoo2a.dll, because the version backed by Glide3x is more advanced.

kjliew wrote:

Would you please provide 64-bit build of glide3x.dll, too? I am adding the support for wrapping glide3x APIs in QEMU. Hopefully, this would get NFS3 to play within QEMU, too, and other 3Dfx OGL based games, such as Homeworld. The 3Dfx OGL driver requires glide3x.

Ok, I'll compile an 64bit Glide3x too. I wanted to ask you if you need that too anyway. Unfortunately I cannot be engaged in dgVoodoo now because of various reasons but I'll be back soon. 😀

Reply 33 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie
Dege wrote:

Ok, I'll compile an 64bit Glide3x too. I wanted to ask you if you need that too anyway. Unfortunately I cannot be engaged in dgVoodoo now because of various reasons but I'll be back soon. 😀

Great, thanks a lot!

BTW, I found that dgVoodoo2 is doing some weird hijacking on the WNDCLASS and likely whacking with dwStyle/dwExtStyle or chaining a custom windowProc
into the HWND from QEMU to dgVoodoo2 in _grSstWinOpen call. That explains why it did not crash and being so robust in handling the size of rendering window. However, something fishy seemed to be taking place on that matter and TEST30 from Glide 2/3 diag kit is not very happy about it. It would make subsequent call to _grSstWinOpen failed, even though the DLL was unloaded and reloaded between runs. It also caused QEMU SDL display to shrink in width gradually. It is more troublesome when Windows 10 display scaling is in effect on high DPI display.

Would you be able to provide a configuration option to bypass all these window management? I believe they are there mostly have to do with the sizing of window to match Glide resolution. I am guessing that dgVoodoo2 may have issues when _grSstWinOpen and_grSstWinClose are called repeatedly without calling _grGlideShutdown. From GDB traces, I think dgVoodoo2 faulted with DXGI exceptions. That's all I can tell from my observation from GDB without source level debugging.

Reply 34 of 53, by Dege

User metadata
Rank l33t
Rank
l33t
kjliew wrote:

Would you be able to provide a configuration option to bypass all these window management? I believe they are there mostly have to do with the sizing of window to match Glide resolution.

Yes, but the hook takes over some other events too. This was a problem for DosBox too, so I chosed a simple (I-don't-like-these-type-of-though) solution: if dgVoodoo detects dosbox in the name of the running application then it only hooks Alt-Enter and sizes the window to the expected Glide resolution.
I wonder if the same solution for QEMU were enough.

Reply 35 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

I found that QEMU works best for Glide wrappers that do not interfere with events loop and window sizing. I made this change to locally compiled OpenGlide and psVoodoo.

Instead of detecting the name of the running application, I would suggest that this be done through dgvoodoo.conf, for eg. "HostedEnvironment = true". In Hosted Environment (DOSBox, QEMU or any future virtualizers), dgvoodoo only needs to focus on scene rendering while the host takes care of the rest, mouse/keyboard inputs, window sizing etc.

There is a nice feature from psVoodoo I found that being a D3D9 renderer, it is able to stretch Glide resolution into screen resolution while keeping LFB accesses at Glide resolution. The latest OpenGlide also has similar Glide resolution scaling, but it did not maintain LFB accesses at Glide resolution. Unfortunately, scaling of LFB accesses does not work universally. I believe dgVoodoo would also have similar scaling capabilities without the need to scale LFB accesses. This should remain available in Hosted Environment. In Hosted Environment, you will always receive a valid HWND on _grSstWinOpen, so that screen resolution can be obtained by GetClientRect(HWND). Most of the time, screen resolution will be the same as Glide resolution. Otherwise, scale Glide resolution accordingly.

I haven't done a lot of testing on full-screen rendering. So far, OpenGlide full-screen rendering works with QEMU windowed mode through its own INI file settings. I don't think Glide wrappers should be hooking into keyboard events to switch between windowed and full-screen rendering. I think I am OK with OpenGlide approach of independent configuration for windowed and full-screen mode. And, I think dynamically toggling between windowed and full-screen mode is a pretty bad scenario for Glide wrappers to handle correctly.

Reply 36 of 53, by Dege

User metadata
Rank l33t
Rank
l33t

So if I get it right, you'd like the current window size to be the forced resolution when calling grSstWinOpen, overriding the one specified in dgVoodoo config file?

For the config option, I think 'Environment = [|Native|DosBox|QEmu]' would be better.
Gulikoza's patch works in an other way, it doesn't know about forced resolution (so the wrapper itself has to size the window) and I don't want to remove the possibility of manual screen mode switching from DosBox.

Reply 37 of 53, by DosFreak

User metadata
Rank l33t++
Rank
l33t++

I emailed gulikoza a couple of weeks ago and he was planning on working on his patch some more. Dunno if he knows about any of this though. May be worth it to hit him up.

How To Ask Questions The Smart Way
Make your games work offline

Reply 38 of 53, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie
Dege wrote:

So if I get it right, you'd like the current window size to be the forced resolution when calling grSstWinOpen, overriding the one specified in dgVoodoo config file?

Ideally, I would like dgvoodoo to be "Resolution = unforced". Just render at Glide resolution from _grSstWinOpen. Scaling is optionally controlled by host environment using the HWND based on the size of the client area. It doesn't have to scale perfectly, just try the best to keep the aspect ratio and performance. It is OK to leave black borders. QEMU does the same to its 2D SDL display for scaling. OpenGlide would render from lower-left corner and leave black borders on top and right. Resizing window is done prior to activating Glide and the size cannot change once Glide is running. I would like to experiment with this design concept for Glide games that only support 640x480. LFB accesses must be maintained at Glide resolution to make things work.

Dege wrote:

For the config option, I think 'Environment = [|Native|DosBox|QEmu]' would be better.
Gulikoza's patch works in an other way, it doesn't know about forced resolution (so the wrapper itself has to size the window) and I don't want to remove the possibility of manual screen mode switching from DosBox.

Gulikoza's patch actually resizes the window for dgVoodoo1 based on Glide resolution. It is detecting dgvoodoo1 by the exported symbol "DispatchDosNT". Obviously, this had failed for dgVoodoo2. If you add back the symbol as dummy, then DOSBox will resize the window for you, too.

To be frank, I don't mind if Glide wrappers are capable of managing the size of rendering window. In fact, I expected this based on Gulikoza's Glide patch for DOSBox. However, after working on QEMU, I found that QEMU SDL display rendering is markedly different from DOSBox. DgVoodoo1, OpenGlide and psVoodoo all failed at window sizing as well as others such as nGlde and zecks' which I tested much later. Even my own Glide pass-through module within QEMU failed, I had to resort to event posting and let the event handling does the sizing or spawn a new window for Glide rendering. Only dgVoodoo2 survived window sizing, but there are side-effects. TEST27 and TEST30 which repeated call into _grSstWinOpen/_grSstWinClose will failed and QEMU 2D SDL display is also affected after gaining screen rendering back from dgVoodoo2. So I think it is better for dgVoodoo2 not to mess around with window sizing and let QEMU handle it nicely.

Feel free to share with me if you have other opinions and ideas.

Reply 39 of 53, by Stiletto

User metadata
Rank l33t++
Rank
l33t++
DosFreak wrote:

I emailed gulikoza a couple of weeks ago and he was planning on working on his patch some more. Dunno if he knows about any of this though. May be worth it to hit him up.

Another thing gulikoza should hear about is a few guys working on applying community patches to OpenGlide over on Github: https://github.com/voyageur/openglide/

"I see a little silhouette-o of a man, Scaramouche, Scaramouche, will you
do the Fandango!" - Queen

Stiletto