REPRO:
1. Launch Nestopia with default settings.
2. Configure gamepad input device.
3. Load Super Mario Brothers 1 (NTSC NES ROM).
4. Start playing: note that the game is very responsive to controller button presses, but there are bad horizontal shearing lines everywhere due to lack of VSync.
5. Go into Nestopia settings, and enable VSync.
6. Resume playing: note that while the horizontal shearing problem is now gone (as expected), the game is no longer responsive to controller button presses, making the game unplayable. If you press the "jump" (A) button, for example, to make Mario jump, there is a very long lag/delay (500ms or longer) before he finally jumps.
VERSION:
I am using Nestopia version 1.37 for Windows.
HARDWARE:
This problem repros identically for me on both Windows XP Professional SP2 32-bit and Windows Vista Ultimate 32-bit. Both machines are Intel Core 2 Duo systems with ATI Radeon graphics cards (Radeon Series X1900 and Mobility Radeon X2300). Both machines are using SoundMAX integrated audio chipsets. Both machines have the latest motherboard chipset drivers, ATI graphics drivers, and sound drivers installed. On both machines, I am using a Mayflash Super DualBox USB adaptor (for plugging two PlayStation 2 Dual-Shock controllers into my PC) as my input device.
COMPARISON TO OTHER NES EMULATORS:
I have also tried this same repro (on the same hardware) on numerous other NES emulators (FCEUltra, VirtualNES, UberNes, Nintendulator) to compare the results:
* FCEUltra - same problem (leg) with VSync enabled
* VirtualNES - same problem (lag) with VSync enabled
* Nintendulator - game is perfectly responsive with
VSync enabled
* UberNes - game is perfectly responsive with VSync enabled
EXPECTATION:
If Nintendulator and UberNes can both be responsive even with VSync enabled, then Nestopia should be able to be responsive too.
Logged In: NO
It looks like the main cause of this is the "only poll every other time" logic in Input::Poll() and Input::CheckPoll(). When I comment out all that logic and just have it ForcePoll on every call, Nestopia is noticeably more responsive to the player.
Logged In: YES
user_id=779735
Originator: YES
That last comment (about polling) was mine. I did a more thorough side-by-side comparison of the official 1.37 binary release and my private build with the polling changes, and there's actually no improvement whatsoever. I think in my previous testing I forgot to turn VSync on in my private build's settings.
Logged In: YES
user_id=779735
Originator: YES
I found this lag issue reported in the forums against an old version of Nestopia. The claim in that thread was that the lag was caused by Nestopia using DirectDraw rather than Direct3D. But the current (v1.37) Nestopia sources use Direct3D, not DirectDraw, and I am still experiencing this problem.
Interestingly, Nintendulator 0.965 beta uses DirectDraw (NOT Direct3D) and it does not exhibit the lag problem...
Logged In: YES
user_id=779735
Originator: YES
I downloaded a bunch of past Nestopia versions (1.31, 1.32, 1.34, 1.35, 1.36, and the latest, 1.37) to see if this issue might have been recently introduced, and if so, by which version.
Versions 1.31 and 1.32 do not exhibit this issue. They both have perfectly responsive game controls.
Versions 1.34 and later all exhibit this lag issue. So this issue was introduced sometime between the 1.32 and 1.34 releases.
So I also downloaded the source code for 1.32 and 1.34, and I am going to do a complete diff on the source trees and look for any changes that look like possible causes.
Logged In: YES
user_id=779735
Originator: YES
I finally found the code that is causing this.
It's the "timeStamp" stuff that was added to NstInpPad.cpp between v1.32 and v1.34.
It looks like that code was added from a desire to more accurately emulate NES timings. But all it really does is prevent DirectInput polling from occuring as frequently as it ought to, making the game either miss button presses entirely or lag slightly behind them.
I modified the 1.37 sources to remove "timeStamp" and "nextStamp" completely, and to really poll on every call to Pad::Poll(), and that fixes the issue. I won't go to the trouble of providing a diff because this should be an easy change to make based on my description here.
Please include this fix in Nestopia 1.38!
Logged In: YES
user_id=779735
Originator: YES
Ignore all my previous claims at identifying the problem. To date, I have been unable to clearly and truly identify the problem, although I have tried many different things. I have also been unable to clearly track down a specific version of Nestopia that introduced the problem. The only thing I have been able to figure out with certainty is that Nintendulator does NOT have this problem, while Nestopia clearly does. Compare the latest release of Nestopia against the latest release of Nintendulator and you can definitely tell that Nintendulator is way more responsive.
I can describe the symptoms more accurately now, however:
* All of the symptoms are exclusive to full-screen video mode with VSync enabled, and occur in all games (not specific to one particular game or mapper).
* All of the symptoms are hardware-independent: I have reproduced them on five different PCs, all with different cpus and video cards and RAM and sound cards and motherboards, using a variety of PS/2 keyboards and various forms of USB gamepads for input.
* All games lags noticeably behind the user's controller button presses, annoying enough to make any action-type game essentially unplayable.
* Audio is choppy and does not stay in sync with the video. A speed run through level 1-1 of "Super Mario Brothers" easily reveals this issue: the jumping sound starts lagging badly behind the actual jumps, and the background music starts skipping, as you run through the level. This is NOT due to an underpowered PC, since CPU utilization and used physical RAM both remain very low during the repro.
* Changing the "speed" slider in the Timing options appears to screw up the VSyncing (it shouldn't). Example: change speed from default of 60 to a slightly different value, such as 59 or 61, and then notice that even with VSync on, you get bad shearing in full-screen mode.
* All of these symptoms persist regardless of how you set the following options:
- use high resolution timer
- sync to refresh rate versus auto-frame-skip
- bit depth and resolution of full-screen video
- use video filters versus using none
I spent months debugging the Nestopia code to understand it better, and I finally found the cause of the sluggish controls.
In NstInpPad.cpp, in function Pad::Poll(), there's a divisor 0x10000 that causes gamepad polling to only occur every 65536 NES CPU cycles. (I'm not sure why this is present -- possibly in some attempt to match real behavior of a NES?) Anyway, removing the divisor, and/or removing the subsequent check on "if (timeStamp <= nextStamp)" eliminates the sluggish controls.
Wikipedia says the NTSC NES CPU ran at 1.79 MHz. (65536/1790000)*1.0s = 36.6ms, so this bug causes up to a 36ms delay between the user pressing a control and the running NES ROM receiving the control change. It's a small but perceptible delay, enough to make fast action games feel unresponsive.
This is very interesting. I hope you can work with the author and get this resolved. As it stands now, Nestopia is an inferior emulator just because of this bug, despite having great features.
Hello c0d3h4x0r. Thank you for the work in identifying the input lag issue. Would it be possible to put a link of the updated Nestopia program you edited? I am not a coder, so the concept of removing divisors and the like are quite foreign to me. I appreciated your work into the matter.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Additional point of note. If you have an nVidia card, check for the setting "Maximum pre-rendered frames" in the nVidia control panel. All newer drivers default this to 3, and this will create a huge lag for emulation when VSync is turned on.
You'll need to turn it off entirely to prevent this, but it will need to be reset every time you install or update your drivers.
Last edit: Anonymous 2017-06-02
I have fixed this issue! I'm posting an unofficial release of Nestopia (v1.41, both binaries and source code) right here in this bug, since Martin Freij appears to have abandoned the SourceForge project entirely and has not responded to my e-mails, leaving me no official way to get him to issue an official release containing the fix.
Nestopia 1.41 unofficial release:
Binaries: http://c0d3h4x0r.0catch.com/Nestopia-1.41-unofficial-x86.zip
Source: http://c0d3h4x0r.0catch.com/Nestopia-1.41-unofficial-x86-src.zip