VS. Duck Hunt zapper not responding properly [SOLVED]

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
VS. Duck Hunt zapper not responding properly [SOLVED]
by on (#173712)
I am attempting to add VS. Zapper support to my emulator by following the description on the wiki (the VS. Zapper is strobed and serialized like a standard controller). But, it is only partially working. In VS. Duck Hunt, when the trigger is pulled on the single player select screen, it generates a fully black frame, then a fully white frame and finally another fully black screen. Debugging reveals that during the black frames, it reads from the controller port once per scanline, presumably examining the light sensor bit. However, during the white frame, it does not read from the controller port at all. Debugging also shows that during the white frame, the light sensor is active for 26 scanlines. But, since the game is simply not reading from the controller port during the white frame, it fails to get detected.

I tried various combinations of trigger pull times and light sensor active times without success.

Could this somehow be related to the VS. palettes? VS. Duck Hunt uses a palette that is almost identical to the standard NES palette. However, is something strange done to generate the fully colored frames? Could the black and white frames be reversed in color or something?
Re: VS. Duck Hunt zapper not responding properly
by on (#173797)
The Vs Zapper's light sense bit is inverted compared to the standard Zapper (or "normal" from a neutral standpoint) - 1 when sensing light, 0 otherwise. If you were using the same behavior as the normal Zapper, the game probably decided that you weren't pointing at the screen and thus didn't bother checking it during the white frame (though it would've also stopped reading during the "dark" frame after the very first scanline).
Re: VS. Duck Hunt zapper not responding properly
by on (#173824)
Quietust wrote:
The Vs Zapper's light sense bit is inverted compared to the standard Zapper (or "normal" from a neutral standpoint) - 1 when sensing light, 0 otherwise. If you were using the same behavior as the normal Zapper, the game probably decided that you weren't pointing at the screen and thus didn't bother checking it during the white frame (though it would've also stopped reading during the "dark" frame after the very first scanline).


Thanks for the suggestion, but my implementation is already doing that per the information on the wiki. The cause of the issue is something else.
Re: VS. Duck Hunt zapper not responding properly
by on (#173827)
I don't know how it's detected exactly, but the gun manual for the VS says that games are supposed to trigger an alarm if it thinks the gun has been removed/stolen/vandalized. Maybe the game thinks something is wrong and is getting into a state where it doesn't check for hits anymore? Just a guess. I would think you'd hear an audible alarm if that was the case, but I don't know, it must depend on how each game handles it.
Re: VS. Duck Hunt zapper not responding properly
by on (#173838)
Memblers wrote:
I don't know how it's detected exactly, but the gun manual for the VS says that games are supposed to trigger an alarm if it thinks the gun has been removed/stolen/vandalized. Maybe the game thinks something is wrong and is getting into a state where it doesn't check for hits anymore? Just a guess. I would think you'd hear an audible alarm if that was the case, but I don't know, it must depend on how each game handles it.

You definitely do hear an alarm in Duck Hunt when that happens - if the gun isn't connected on startup, it plays about 2 notes of the title screen tune before emitting a loud beep, and disconnecting it at any point during gameplay has a similar effect. Hogan's Alley is the same way.
Re: VS. Duck Hunt zapper not responding properly
by on (#173966)
@Quietust Is there any way to test the VS. Zapper in Nintendulator? It reports Mapper 099 as unsupported, but source suggests otherwise.
Re: VS. Duck Hunt zapper not responding properly
by on (#174013)
I really can't figure out what is going wrong with my VS. Zapper implementation. I'm willing to run whatever test anyone can suggestion. I'm out of ideas. Thanks.
Re: VS. Duck Hunt zapper not responding properly
by on (#174081)
zeroone wrote:
@Quietust Is there any way to test the VS. Zapper in Nintendulator? It reports Mapper 099 as unsupported, but source suggests otherwise.

Either you're running a very old version (0.975, despite being "unstable", is what you actually want to be running), or you somehow extracted the archive without subfolders and it can't find the mapper DLLs.
Re: VS. Duck Hunt zapper not responding properly
by on (#174084)
Or maybe the mapper DLLs got overwritten with DLLs from another emulator. I know that NESten uses the same filenames for mappers.
Re: VS. Duck Hunt zapper not responding properly
by on (#174086)
Quietust wrote:
zeroone wrote:
@Quietust Is there any way to test the VS. Zapper in Nintendulator? It reports Mapper 099 as unsupported, but source suggests otherwise.

Either you're running a very old version (0.975, despite being "unstable", is what you actually want to be running), or you somehow extracted the archive without subfolders and it can't find the mapper DLLs.


Version 0.975 does not appear to support Mapper 099. I re-downloaded it to be sure. I see the VS.dll in the the mappers subdirectory. It is dated 02/28/2015.

By the way, what controller does VS Duck Hunt expect in the other port?
Re: VS. Duck Hunt zapper not responding properly
by on (#174106)
What is your zapper implementation?

Do you have it assigned to the correct port?
Re: VS. Duck Hunt zapper not responding properly
by on (#174107)
2600 wrote:
What is your zapper implementation?

Do you have it assigned to the correct port?


I followed the description on the wiki. It provides the data serially like the gamepad. My VS Zapper implementation is an extension of my standard NES Zapper implementation that works correctly with normal Duck Hunt. In VS Duck Hunt, the player select screen flashes when the trigger is pulled, but the game fails to register the hit. Per the description earlier in the thread, the flash is actually 3 frames: full black, full white, full black. Debugging shows that it reads from the zapper port once-per-scanline only during the full black frame, ignoring when the light sensor detects the white frame. The sensor is also inactive in the black frame.

Since the trigger and the light sensor data is delivered serially from the same bit and the game does respond to the trigger, it suggests that my implementation is rigged up to deliver the data on the proper port.

I'm willing to run any experiment and collect any kind of logging that someone can suggest. This is a really strange issue.
Re: VS. Duck Hunt zapper not responding properly
by on (#174120)
zeroone wrote:
Version 0.975 does not appear to support Mapper 099. I re-downloaded it to be sure. I see the VS.dll in the the mappers subdirectory. It is dated 02/28/2015.


Open the ROM in Nintendulator's Header Editor and make sure the "VS Unisystem" flag is set. If it's not set, that's why it doesn't work - VS.dll will only accept .NES files that have that flag set.
Re: VS. Duck Hunt zapper not responding properly
by on (#174124)
Quietust wrote:
Open the ROM in Nintendulator's Header Editor and make sure the "VS Unisystem" flag is set. If it's not set, that's why it doesn't work - VS.dll will only accept .NES files that have that flag set.


Thanks. Setting the flag in the header enabled it to load. Nintendulator's VS UniSystem Zapper works perfectly.
Re: VS. Duck Hunt zapper not responding properly
by on (#174139)
@Quietust In the controller port write function below, does PPU::DrawArray contain prior frame pixel values within the region that has yet to be updated? Or, is PPU::DrawArray cleared between frames?

Code:
void   StdPort_VSZapper::Write (unsigned char Val)
{
   int x = State->PosX, y = State->PosY;

   State->Strobe = Val & 1;
   if (!State->Strobe)
      return;
      
   State->Bits = 0x10;
   State->BitPtr = 0;
   if (State->Button)
      State->Bits |= 0x80;

   if ((x < 0) || (x >= 256) || (y < 0) || (y >= 240))
      return;

   if (PPU::IsRendering && PPU::OnScreen)
   {
      int X, Y;
      int WhiteCount = 0;
      for (Y = y - 8; Y < y + 8; Y++)
      {
         if (Y < 0)
            Y = 0;
         if (Y < PPU::SLnum - 32)
            continue;
         if (Y > PPU::SLnum)
            break;
         for (X = x - 8; X < x + 8; X++)
         {
            if (X < 0)
               X = 0;
            if (X > 255)
               break;
            if ((Y == PPU::SLnum) && (X >= PPU::Clockticks))
               break;
            if (GFX::ZapperHit(PPU::DrawArray[Y * 256 + X]))
               WhiteCount++;
         }
      }
      if (WhiteCount >= 64)
         State->Bits |= 0x40;
   }
}
Re: VS. Duck Hunt zapper not responding properly
by on (#174147)
zeroone wrote:
@Quietust In the controller port write function below, does PPU::DrawArray contain prior frame pixel values within the region that has yet to be updated? Or, is PPU::DrawArray cleared between frames?

I don't remember whether it's cleared or not, but it is updated in real time, and the checks against PPU::SLnum and PPU::Clockticks ensure that it will never attempt to read data that has not yet been rendered.
Re: VS. Duck Hunt zapper not responding properly
by on (#174164)
Quietust wrote:
I don't remember whether it's cleared or not, but it is updated in real time, and the checks against PPU::SLnum and PPU::Clockticks ensure that it will never attempt to read data that has not yet been rendered.


I see that check in the code. Thanks.

Do the VS Zapper games have some sort of copy protection that prevents them from advancing beyond the player select screens?

Edit: The VS Zapper works correctly in VS Freedom Force and VS Gumshoe in my emulator. It fails to work properly in VS Duck Hunt and VS Hogan's Alley.
Re: VS. Duck Hunt zapper not responding properly
by on (#174320)
To get past the player-selection screen issue in my emulator, I started up the game in FCEUX and I copied CPU RAM $0000--$2000 from FCEUX to my emulator. Unfortunately, the VS Zapper still does not work during gameplay either. However, this suggests it is not a missing copy protection feature.

Since my VS Zapper implementation works in VS Freedom Force and VS Gumshoe, it could be some sort of timing issue in VS Duck Hunt. But, it's really strange that normal Duck Hunt works just fine.

I'm open to suggestions on things I can try. Thanks.
Re: VS. Duck Hunt zapper not responding properly
by on (#174344)
I'm not familiar with the nes side of stuff, I am familiar with the VS side of things.
If this stuff has already been covered then you can skip it.

Vs Hogans alley and vs duck hunt do the gun check, which is just a ground loop.
Freedom force and gumshoe dont look for it... They will work with or without the ground loop.

Vs gun is also connected to the player 1 controls on the real cab. Taking place of the joystick and ect.
So its programed differently.

Just like i can split up the nes rom of wildgunman and put it on an actual vs pcb, the game will physically run, but the gun does nothing. The code isnt the same for location of gun.
Re: VS. Duck Hunt zapper not responding properly
by on (#174355)
pc-10.com wrote:
I'm not familiar with the nes side of stuff, I am familiar with the VS side of things.
If this stuff has already been covered then you can skip it.

Vs Hogans alley and vs duck hunt do the gun check, which is just a ground loop.
Freedom force and gumshoe dont look for it... They will work with or without the ground loop.

Vs gun is also connected to the player 1 controls on the real cab. Taking place of the joystick and ect.
So its programed differently.

Just like i can split up the nes rom of wildgunman and put it on an actual vs pcb, the game will physically run, but the gun does nothing. The code isnt the same for location of gun.


This is new to me. Can you describe the gun check in more detail? What does the ground loop mean in terms of data made available to the controller port?
Re: VS. Duck Hunt zapper not responding properly
by on (#174359)
Is it possible that the game is making sure that no light is being sensed on a black frame, and you're still turning the light sensed output on despite pointing at black pixels?
Re: VS. Duck Hunt zapper not responding properly
by on (#174360)
lidnariq wrote:
Is it possible that the game is making sure that no light is being sensed on a black frame, and you're still turning the light sensed output on despite pointing at black pixels?


I added logging to my emulator to see when the game was probing the controller ports. On the black frame, it probes once per scanline (8 reads to transfer the byte serially). Each of those probes indicates no light sensed. On the successive white frame, it doesn't do any probing. If it wasn't satisfied with the black frame, why does it even display the white frame? The white frame is followed by a second black frame. No scanline probing takes place in that frame either.

Since the VS Zapper works perfectly in 2 of the 4 VS Zapper games, these 2 are doing some check that my emulator is failing to completely satisfy.
Re: VS. Duck Hunt zapper not responding properly
by on (#174361)
Its a literal ground. The "alarm" ties to ground. That wire would translate to player one up on joystick, in the wiring schematic of a vs cab. Right is trigger, left is hit.
Re: VS. Duck Hunt zapper not responding properly
by on (#174362)
I just checked on my cab, if no gun is installed, pressing up on the player 1 joystick closes the circuit and the gun alarm doesnt sound. As soon as i let it go the alarm sounds. So player 1 up needs to be tied to ground to shut down alarm.....
Re: VS. Duck Hunt zapper not responding properly
by on (#174364)
pc-10.com wrote:
I just checked on my cab, if no gun is installed, pressing up on the player 1 joystick closes the circuit and the gun alarm doesnt sound. As soon as i let it go the alarm sounds. So player 1 up needs to be tied to ground to shut down alarm.....


This is mentioned on the wiki. I'll check if there is an audible alarm in my emulator if that bit is left unset...

Edit: VS Duck Hunt and VS Hogan's Alley make an annoying audible ringing tone on the title screen if the UP bit is not set. Apparently, the implementation is missing something else.
Re: VS. Duck Hunt zapper not responding properly
by on (#174409)
I made a tiny configuration file for clever-disasm to have a go at Vs. Duck Hunt:
Code:
JumpTableRoutineWithAppendix $05B3
CertainlyCode $00A0
CertainlyCode $012B
CertainlyData $60F0
CertainlyCode $04D5 PollJoys
CertainlyCode $293C CheckLight
CertainlyCode $2938 CheckTrigger


I find the following, three of the four times that CheckLight is called:
Code:
-       $A80E  AD 02 20:    lda $2002
        $A811  29 40:       and #$40
        $A813  D0 09:       bne +               ; $A81E
        $A815  20 3C A9:    jsr CheckLight
How's your sprite 0 hits?
Re: VS. Duck Hunt zapper not responding properly
by on (#174416)
Debugging in my emulator reveals that it does reach $A81E when you pull the trigger on the player-selection screen; the sprite0 hit was detected. In fact, it breaks there twice when you pull the trigger, once on the black screen and once on the white screen.

Also, from debugging in FCEUX, the $A81E code does not appear to be used while the game is running. It's only used in the player-selection screen.

And, I put in some test code to force a sprite0 hit on the first scanline just in case my debugger was lying or something. That did not enable it to pass the player-selection screen.

Something else is going on. Thanks for your help lidnariq. I'm also trying to decipher the source.
Re: VS. Duck Hunt zapper not responding properly
by on (#174420)
zeroone wrote:
And, I put in some test code to force a sprite0 hit on the first scanline just in case my debugger was lying or something. That did not enable it to pass the player-selection screen.
That's backwards ... at least I think it's backwards? It looks like it's only checking for light until the sprite 0 hit.

The other identical fragments are at $A82C and $A867. The last one is similar, now that I look at it more closely, just structured differently. And at $A886.
Re: VS. Duck Hunt zapper not responding properly
by on (#174421)
lidnariq wrote:
That's backwards ... at least I think it's backwards? It looks like it's only checking for light until the sprite 0 hit.

The other identical fragments are at $A82C and $A867. The last one is similar, now that I look at it more closely, just structured differently. And at $A886.


It looks like it positions sprite0 in the middle of the first scanline. I assume that enables it to subsequently check each successive scanline for a light/dark hit.

I'm willing to run any test that you can propose. This one is a real mystery.
Re: VS. Duck Hunt zapper not responding properly
by on (#174422)
How well does your emulator handle Zap Ruder (which uses a normal D4/D3 Zapper, not the Vs. Zapper)? It also uses sprite 0 at the top and counts scanlines to determine. If I had a Zapper modified to also speak Vs. protocol, I might be able to help you by making a test ROM.
Re: VS. Duck Hunt zapper not responding properly
by on (#174423)
zeroone wrote:
It looks like it positions sprite0 in the middle of the first scanline.
That's not what I'm seeing in Nintendulator (There sprite 0 is at Y=$EE on both black and white frames)
Re: VS. Duck Hunt zapper not responding properly
by on (#174424)
tepples wrote:
How well does your emulator handle Zap Ruder (which uses a normal D4/D3 Zapper, not the Vs. Zapper)? It also uses sprite 0 at the top and counts scanlines to determine. If I had a Zapper modified to also speak Vs. protocol, I might be able to help you by making a test ROM.


Zap Ruder appears to work perfectly. It's unfortunate there is no VS Zapper version of it.
Re: VS. Duck Hunt zapper not responding properly
by on (#174425)
lidnariq wrote:
zeroone wrote:
It looks like it positions sprite0 in the middle of the first scanline.
That's not what I'm seeing in Nintendulator (There sprite 0 is at Y=$EE on both black and white frames)


I think you just revealed the issue. Apparently there is a flaw in my PPU implementation. It is reporting a sprite0 hit on the pre-render scanline (scanline -1). I put in a check to prevent that and now it detects it on scanline 239 ($EF). More importantly, the game works now!

It's really amazing that this flaw was not revealed in any other games. That's nuts. I'll study my code further to understand how this happened. Thanks so much everyone.

Edit: That solves the issue with VS Hogan's Alley also. And, it didn't break Battletoads or the Simpsons HUD, etc. Interesting.

Edit 2: The unlicensed game Lethal Weapon (Ch) [U][!].unf still does not work. But, it doesn't work correctly in Nestopia either. So, I can live with that.

Edit 3: Thanks again everyone. This change did not affect the test ROM results either. I'm still amazed that this issue wasn't detected until now.