joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.6k stars 376 forks source link

Can't game on Windows 98 SE unless sbtype = none #2689

Open brunocastello opened 3 years ago

brunocastello commented 3 years ago

Describe the bug I cannot run any game at all on Windows 98 SE, unless I set sbtype to "none". FIFA 98 RTWC, FIFA 99, Need For Speed II SE, all them cannot run with sound on, even when I try to play them in software mode instead of glide pass-through.

NFS2SE with both software and 3dfx crashes when the race is about to start, during the intro flying into the player's car. FIFA 98 RTWC and FIFA 99 both crash when the match kick-off is about to start, no matter if 3dfx is enabled or not.

When I set sbtype = none, without any sound at all, I can play all three games without issues (but without sound as well).

To Reproduce Play any of the three games above (a demo is enough) under Windows 98 SE, using sbtype = sb16 or sb16vibra.

Expected behavior Games to run flawlessly with sound enabled.

Environment (please complete the following information):

Additional context I am running a build without avcodec and fluidsynth. I do not want all the 93893 dependencies both require to run. In a Mac where hard disk space is a premium, this is needed. I just need networking and the gaming features; I do not want extra sound features (fluidsynth) or to do any screen recording (avcodec) stuff. However, even using the standard build with them, the problem persists.

The computer has this configuration and has been upgraded to 16GB RAM at the time of purchase.

Attached is my dosbox configuration file, pretty similar to the one from the wiki guide for Windows 98 installation. dosbox.txt

joncampbell123 commented 2 years ago

Here on Linux I can confirm non-accelerated NFS2SE will eventually just dump back to the desktop without any error message.

I've thought about one possible cause, and it has to do with the audible artifacts when Windows 95 starts up. DOSBox-X inherits DOSBox SVN's millisecond-by-millisecond Sound Blaster Processing and the "minimum DMA" processing that I can only assume was meant to keep games from stuttering.

If NFS2SE is using DirectX and DirectSound to render audio, perhaps it's sensitive to any "jitter" that might happen from the 1ms-based processing. Having written code to deal with DirectX, DirectSound primary buffers are either emulated as or actually handled as a circular DMA buffer, just like you would do in MS-DOS with Sound Blaster, and in fact when DirectX drivers are working, the buffer and playback position are exactly just that. In fact a programming mistake I made back in the Windows 98 days showed me that with ISA hardware the playback position reported comes straight from the DMA controller. The theory is that maybe NFS2SE has naive code that assumes the DMA will always advance monotonically, and if it judders back a bit because of some naive handling by the sound driver, the game computes some extra large integer and throws an assertion check or error function, or maybe tries to render that many samples and throws an exception.

I suppose one way to verify that would be to whip up a Win32 program that starts a DirectSound primary buffer and then continually watches and reports it's movement to a file.

joncampbell123 commented 2 years ago

To explain the programming mistake, my code back then used DirectSound to record from the microphone at 44.1KHz 16-bit stereo. I was writing something to record radio shows and I had arranged a sound board to use two microphones side by side to pick up the voice in stereo.

It would have been a good test recording except that I found out too late the L and R channels constantly switched back and forth.

My code assumed the playback byte position reported would be aligned to a complete stereo sample in the buffer, but because the Windows 98 drivers reported directly from the DMA controller, the reported byte position was sometimes in the middle of the complete sample, meaning, since it was obviously using 16-bit DMA, sometimes the reported position would be right between the 16-bit L and R samples meaning the DMA had written L, but not yet R. I've been writing my code to round down the reported position by nBlockAlign since.

This would around 2001 or so with an old Pentium laptop running Windows 98 that had one of those "OPL3SAx" Sound Blaster Pro compatible WSS chipsets that they had obviously connected to the ISA bus internally.

joncampbell123 commented 2 years ago

A quick check: Whatever it doesn't like about SB16 emulation it dislikes the ESS 688 AudioDrive emulation even more.

casasfernando commented 1 year ago

Just found this github issue after troubleshooting the problem for a few hours. I’m using Dosbox-X flatpak latest version (2022.09.0 64bit sdl2) on Ubuntu 20.04 and indeed changing sbtype to none stops NFS2SE from crashing anymore (3dfx enabled). I can also confirm that the same issue affect other NFS games like High Stakes.

Are there any debug logs or something that can be collected to help narrow down this issue? Dosbox-x log didn’t show any information or error when the game crashes so it was very difficult to troubleshoot so far.

grapeli commented 1 year ago

Under dosbox-pure it is very similar. I suspect that if someone would test NFS2SE under dosbox-svn or dosbox-staging, of course, with the necessary patches extending the capabilities of these programs, the effect would be the same.

The error is hidden deep in the dosbox code.

I don't think it has anything to do with soundblaster. I tested NFS2SE under dosbox-x with GUS and it behaves the same as with soundblaster. There is a quick exit when the game starts.

With sbtype=sb16 and 3dfx I sometimes managed to complete the whole race (over 4 minutes), but most of the time the error occurred 15-30 seconds after the start of the race.

casasfernando commented 1 year ago

@grapeli Thanks for sharing this as testing GUS was my next step so I can skip it now. I’m wondering how can this be debugged because certainly not from the game itself. Maybe from DirectX if this is what for instance NFS2SE uses for sound?

grapeli commented 1 year ago

@casasfernando As I thought this bug is not exclusive to DOSBox-X. It's the same with dosbox-staging. I tested on the latest version git with five patches from the ww/fat32-test-1 and ww/voodoo-3dfx-2 branches included.

In the recording, the exit to the desktop occurs very quickly. Other times it took about a minute and a half.

NFS2SE.dosbox-staging.webm

casasfernando commented 1 year ago

@grapeli in my case with none of the games I get that far, meaning race shows for a few seconds. For me, both NFS2SE and NFSHS exit one second or less after the race loading finishes and the "race environment" is displayed. Sometimes I get to see a a few frames of the car or the track, but it crashes almost right away..

Anyways, the problem is how to debug this issue. So far we only know the may be in the sound emulation code path because as soon as sound emulation is disabled the problem goes away. I'm willing to help testing, collecting logs, etc. just need guidance on what information would be needed because I'm new to DOSBox in general and DOSBox-X in particular.

Thanks

grapeli commented 1 year ago

If this bug is so hard to diagnose with NFS2SE it might be worth a try with the Need for Speed High Stakes Demo, which behaves very similarly, except that exiting the game to the desktop ends with a detailed error message.

guest os_000

grapeli commented 1 year ago

The error EXCEPTION_ACCESS_VIOLATION: read attempted in High Stakes appeared on real hardware configurations. The most common cause suggested is a problem with the graphics driver or the directx version. You can find this information in the readme.txt file for this demo.

AUDIO PROBLEMS In some cases, sound problems are caused by video drivers. Make sure you have the latest video drivers for your video card.

Of course, this demo with sbtype=none works perfectly fine. Except for one drawback - there is no sound.

casasfernando commented 1 year ago

@grapeli which DirectX version and graphics drivers are you using? In my case I installed (maybe I shouldn’t) DirectX 9.0c and the Voodoo drivers are the one mentioned in the wiki for Win98. I can check the exact version later on and report back.

grapeli commented 1 year ago

@casasfernando I posted a link to the win98se disk image a few posts above. I'm testing it on exactly the same.

guest os_000 guest os_001 guest os_002

casasfernando commented 1 year ago

@grapeli my setup is mostly the same except that I'm using the S3 emulated card with the OS driver. I'm wondering if it makes sense trying with an older version of DirectX. I was planning to create a new image anyway because wanted to switch Win98 to english (currently I'm using the spanish version) so when I do that I will try to test NFS2SE and NFSHS with whatever version comes with the game and check if it makes any difference but I'm not holding my breath.

grapeli commented 1 year ago

@casasfernando I haven't noticed a difference in stability between the two drivers. Also in those games listed here.

The main and essential reason why I use the VBE driver is its much better performance.

Run Crystal Mark on both - CM09GDI and CM09D2D. You can read the results in ini files. While in GDI the difference is tiny, in 2D it is 50% in favor of VBE. Huge. This difference is also visible in other cases I tested.

kcgen commented 1 year ago

@grapeli ,

I understand Staging's Voodoo and FAT32 branches are ports of the DOSBox-X sources. Maybe Meson's Address and Undefined Behavior Sanitizer (UB+ASAN) build will reveal issues in the Voodoo or FAT32 code?

Setup:

meson setup \
  -Dbuildtype=debug \
  -Doptimization=0 \
  -Db_lundef=false \
  -Db_sanitize=address,undefined \
  -Dc_args=-fsanitize-recover=all \
  -Dcpp_args=-fsanitize-recover=all \
  -Dunit_tests=disabled \
  --native-file=.github/meson/native-clang.ini \
  build/clang-ubasan

Build:

meson compile -C build/clang-ubasan

Executable: build/clang-ubasan/dosbox

It will run slow, but it might help reveal issues at the moment the game cuts out back to Windows, which would be common to both projects. Atleast, if the code has problems at the host level (as opposed to emulation level).

grapeli commented 1 year ago

@kcgen No chance to run Win98SE in dosbox-staging built with clang sanitizer (llvmorg-16-init-10467-g1239d37b-1). Unless I'm doing something wrong.

Dosbox-staging terminates shortly after the win 98 desktop appears. There is still a long way to go before the system is fully loaded. Log with core=dynamic. dosbox-staging.clang-ubsan.core-dynamic.log Log with core=normal. dosbox-staging.clang-ubsan.core-normal.log

In the latter case, once the loading of the system stopped at this point. boot_000

grapeli commented 1 year ago

In dosbox-x compiled with clang (-fsanitize=undefined) NFS2SE it starts. At the time of the error and when exiting the game in the logs I received this information.

voodoo_emu.cpp:2635:29: runtime error: index 768 out of bounds for type 'UINT32[9]' (aka 'unsigned int[9]')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_emu.cpp:2635:29 in
mixer.cpp:359:62: runtime error: left shift of negative value -20066
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior mixer.cpp:359:62 in
voodoo_data.h:918:46: runtime error: left shift of negative value -3
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_data.h:918:46 in
voodoo_opengl.cpp:226:31: runtime error: signed integer overflow: 163 * -9223372036854775807 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:226:31 in
voodoo_opengl.cpp:226:57: runtime error: signed integer overflow: -931 * -9223372036854775807 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:226:57 in
voodoo_opengl.cpp:245:35: runtime error: signed integer overflow: 163 * -9223372036854775807 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:245:35 in
voodoo_opengl.cpp:245:64: runtime error: signed integer overflow: -931 * -9223372036854775807 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:245:64 in
voodoo_data.h:918:46: runtime error: left shift of negative value -15
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_data.h:918:46 in
voodoo_opengl.cpp:226:50: runtime error: signed integer overflow: -9223372036854775547 + -576460752303423280 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:226:50 in
voodoo_opengl.cpp:245:57: runtime error: signed integer overflow: -9223372036854775547 + -576460752303423280 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:245:57 in
voodoo_opengl.cpp:226:24: runtime error: signed integer overflow: -9223372036854775807 + -576460752303423234 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:226:24 in
voodoo_opengl.cpp:245:28: runtime error: signed integer overflow: -9223372036854775807 + -576460752303423234 cannot be represented in type 'INT64' (aka 'long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior voodoo_opengl.cpp:245:28 in
LOG: VOODOO: OpenGL: quit
LOG: 2295202800 DEBUG MISC:GFX_SetSize 640x480 flags=0x14e scale=1.000x1.000
LOG: menuScale=1

I will mention that I previously tested NFS2SE in dosbox-x with both openglide and voodoo_card=opengl and voodoo_card=software. Same error everywhere. The worst is with openglide, because it freezes dosbox-x.

casasfernando commented 1 year ago

@grapeli the above looks like a very good lead on where in the code the problem may be. What is a bit misleading is that only Voodoo emulation related code is mentioned while the issue seems to be triggered by sound emulation. I’m not familiar with the code so looking forward @joncampbell123 or other devs thoughts on this.

grapeli commented 1 year ago

@casasfernando It's not so obvious. Please note that this instability also occurs in the non-3Dfx version (nfs2sen). This is not exclusive to the 3Dfx version. I'm not a developer, I don't know what this clang tinkers with when running the code and whether these reports are false.

grapeli commented 1 year ago

@casasfernando Regarding the non-accelerated version of NFS2SE, it is generally much more stable. Many times I finished the whole race lasting about 6-7 minutes. I also tested its behavior in dosbox-staging now. I completed two full races totaling nearly 13 minutes. During the third, after about a minute, there was an unexpected end to the game. Compared to the 3Dfx version, it is much more stable.

kcgen commented 1 year ago

Thanks for those build and test results, @grapeli. This will be useful when @Wengier's voodoo branch is PR'ed and reviewed -- if we can make any improvements, no doubt we can try them in X and see if helps.

maron2000 commented 1 year ago

According to @grapeli 's log, there is a left bit shift of a negative value in mixer.cpp, which its behavior is undefined if I understand correctly. Maybe we should change the code not to use bit shift.

grapeli commented 1 year ago

@maron2000 With this setting (disable filtering=true), you don't get this mixer warning, and the game still doesn't work properly.

nfs2se demo gcc 12.2.0 -O0 -fsanitize=address -fsanitize=undefined...

LOG: opengl: I am able to use OpenGL to emulate Voodoo graphics
voodoo_emu.cpp:1106:33: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_emu.cpp:1106:83: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_emu.cpp:1107:33: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_emu.cpp:1107:83: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_emu.cpp:1106:33: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_emu.cpp:1106:83: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_emu.cpp:1107:33: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_emu.cpp:1107:83: runtime error: signed integer overflow: -562949953421312 * -562949953421312 cannot be represented in type 'long int'
voodoo_opengl.cpp:253:13: runtime error: signed integer overflow: 13129440 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:254:13: runtime error: signed integer overflow: 13129440 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:246:35: runtime error: signed integer overflow: 49 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:246:28: runtime error: signed integer overflow: -9223372036854775807 + -576460752303423485 cannot be represented in type 'long int'
voodoo_opengl.cpp:246:64: runtime error: signed integer overflow: 451 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:247:35: runtime error: signed integer overflow: 49 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:247:28: runtime error: signed integer overflow: -9223372036854775807 + -576460752303423485 cannot be represented in type 'long int'
voodoo_opengl.cpp:247:64: runtime error: signed integer overflow: 451 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:246:9: runtime error: signed integer overflow: -9223372036854775803 + -576460752303423462 cannot be represented in type 'long int'
voodoo_opengl.cpp:247:9: runtime error: signed integer overflow: -9223372036854775803 + -576460752303423462 cannot be represented in type 'long int'
voodoo_emu.cpp:2679:51: runtime error: index 256 out of bounds for type 'unsigned int [9]'
voodoo_opengl.cpp:221:57: runtime error: signed integer overflow: 372 * -5890867 cannot be represented in type 'int'
voodoo_opengl.cpp:222:57: runtime error: signed integer overflow: 372 * -5890867 cannot be represented in type 'int'
voodoo_opengl.cpp:223:57: runtime error: signed integer overflow: 372 * -5890867 cannot be represented in type 'int'
voodoo_emu.cpp:2635:51: runtime error: index 768 out of bounds for type 'unsigned int [9]'
voodoo_opengl.cpp:226:31: runtime error: signed integer overflow: 4022 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:226:57: runtime error: signed integer overflow: 4130 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:245:35: runtime error: signed integer overflow: 4022 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_opengl.cpp:245:64: runtime error: signed integer overflow: 4130 * -9223372036854775807 cannot be represented in type 'long int'
voodoo_data.h:918:46: runtime error: left shift of negative value -15
voodoo_data.h:918:46: runtime error: left shift of negative value -3
LOG: VOODOO: OpenGL: quit
maron2000 commented 1 year ago

@grapeli Thanks for testing. There are still bit shifting of negative values and out of bound indexs in the voodoo code, so they have to be fixed. How about trying the build with fsanitize=... without voodoo since there has to be flaws without it as well?

grapeli commented 1 year ago

@maron2000 The Nfs2se demo is only in the 3dfx version.

I tried several times to run the non-accelerated full version of the game under dosbox-x compiled with clang and gcc (-fsanitize=....). Without success. The game starts, after loading the race route, it stops at some point. Most often there is an error in the dosbox-x logs - triple fault.

grapeli commented 1 year ago

@maron2000 With sbtype=none the demo runs under dosbox-x compiled with gcc (-fsanitize=...). Some of these runtime errors related to voodoo appear (mostly when the 3dfx logo shows up). nfs2se-demo-gcc-fsanitize.log My conclusion, this is not the essence of the problem.

maron2000 commented 1 year ago

@grapeli Thank you for sharg iyour research. Although it may not be the cause of this issue, it is a big implication to fix voodoo code.

skipster1337 commented 5 months ago

On the issue above it's mentioned that disabling sound hardware acceleration supposedly fixes it, but I tried it in DOSBox-X and the game crashed in the middle of the race instead of in the beginning, and also the sound disappears when approaching tunnels. I hope it's possible to fix this issue since DOSBox-X runs games much faster than PCEm and 86Box.