Duck Hunt Reverse Engineering

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
3gengames
Formerly 65024U
Posts: 2276
Joined: Sat Mar 27, 2010 12:57 pm

Duck Hunt Reverse Engineering

Post by 3gengames » Sat Mar 21, 2020 12:08 am

Hey guys,

I recently had the idea of trying to get into streaming. I plan on doing reverse engineering of NES games on stream, going over the internals, finding and fixing bugs, unused data, etc. I made a tool to help me do this. I have been using it on duck hunt to basically prove it has enough features to do it. This tool is what I'm using to export the source file located here. Game core is basically 100% commented and 95% figured out. Data is known but not labeled exactly yet. Sound engine needs done, too. The source will need a bit of TLC AFTER I get all variables and routines named and such to actually allow it to compile, since my tool works on references and not names, many things share global names instead of being identified uniquely, which is obviously an end goal to this. Hopefully won't be too much longer and all these will be done, as I plan on fixing these independent of the tool to eventually start working on the actual source file and not through the tool.

If anyone has questions about something in duck hunt, let me know and I'll tell you the exact lines you should be looking at. Although for most variables, using a text editor and find will drop you to most relevant places and the comments should explain most of it, I'd hope.

If you figure anything out, make sure to let me know so I can add the info into the tool! :lol:

Source on Git
My Twitch, where I stream using the tool live some days.

Oziphantom
Posts: 859
Joined: Tue Feb 07, 2017 2:03 am

Re: Duck Hunt Reverse Engineering

Post by Oziphantom » Sat Mar 21, 2020 5:05 am

I've also reversed Duck Hunt for reasons

You might want to try https://csdb.dk/release/?id=149429 it is already fully featured and handles all the cases, such as split lo/hi rts tables etc.

3gengames
Formerly 65024U
Posts: 2276
Joined: Sat Mar 27, 2010 12:57 pm

Re: Duck Hunt Reverse Engineering

Post by 3gengames » Sat Mar 21, 2020 10:13 am

Oziphantom wrote:
Sat Mar 21, 2020 5:05 am
I've also reversed Duck Hunt for reasons

You might want to try https://csdb.dk/release/?id=149429 it is already fully featured and handles all the cases, such as split lo/hi rts tables etc.
Did you get the whole thing done too?

Your tool does look like a slightly more flexible version of mine: Screenshot with F12 menu open. but mine does handle all 4 combinations of tables (LHLH,HLHL,LLHH,HHLL, although i guess I should add split tables too.) It actually doesn't have much a concept of banks, although it sorta does. So you can actually relatively label any data in any bank to a table. It uses a "cursor" so you can also move to references from a specific line, see what else references either the variable or the line its self, etc. And return if you view those references, or other lines that reference the one you're on. There's a bunch of menus not shown, too. It's not 100% feature complete but it is 95% there. I actually plan on extending it to 6809 next and doing Williams games, or at least Defender, while adding the final 2-3 things I need from it. I have some features implemented that aren't editable from the menu, like access redirection for different parts of the ROM for >32KB games. Not too hard to add, though.

Oziphantom
Posts: 859
Joined: Tue Feb 07, 2017 2:03 am

Re: Duck Hunt Reverse Engineering

Post by Oziphantom » Sat Mar 21, 2020 11:30 pm

mostly, I didn't care about the sound driver, I just worked out which function played which sfx.
Since I wasn't using a PPU, I didn't care for the minute details of the PPU code either, such as sprite offsets or the particle code.

I see the UNK_ROUTINE is not there?

Code: Select all

$D6D5: A5 58       updatePigeon            LDA PigionFlyFXCounter
$D6D7: F0 07                               BEQ _dontPlaySFX
$D6D9: C6 58                               DEC PigionFlyFXCounter
$D6DB: D0 03                               BNE _dontPlaySFX
$D6DD: 20 F6 D4                            JSR playPigionFly
$D6E0: A5 4C       _dontPlaySFX            LDA BirdFlyAwayTimer
$D6E2: 30 08                               BMI bD6EC
$D6E4: A5 49                               LDA CurrSpriteDeltaIndex
$D6E6: 4A                                  LSR 
$D6E7: 4A                                  LSR 
$D6E8: C9 07                               CMP #$07
$D6EA: 90 02                               BCC bD6EE
$D6EC: A9 07       bD6EC                   LDA #$07
$D6EE: C5 5F       bD6EE                   CMP a5F
$D6F0: F0 0B                               BEQ bD6FD
$D6F2: 85 5F                               STA a5F
$D6F4: 18                                  CLC 
$D6F5: 65 A8                               ADC aA8
$D6F7: AA                                  TAX 
$D6F8: BD C8 E9                            LDA fE9C8,X
$D6FB: 85 5E                               STA CurrBirdSpeedIndex
$D6FD: 20 1B D8    bD6FD                   JSR getBirdSpeed
$D700: 48          bD700                   PHA 
$D701: 20 AE D8                            JSR updateCurves
$D704: 68                                  PLA 
$D705: 38                                  SEC 
$D706: E9 01                               SBC #$01
$D708: D0 F6                               BNE bD700
$D70A: A5 4E                               LDA CE_doingFlyAway
$D70C: 30 3F                               BMI bD74D
$D70E: A5 49                               LDA CurrSpriteDeltaIndex
$D710: C9 30                               CMP #$30
$D712: B0 39                               BCS bD74D
$D714: 20 2F D8                            JSR getPigieonXY
$D717: A5 32                               LDA BirdY
$D719: 38                                  SEC 
$D71A: E9 40                               SBC #$40
$D71C: 85 32                               STA BirdY
$D71E: A5 49                               LDA CurrSpriteDeltaIndex
$D720: 4A                                  LSR 
$D721: AA                                  TAX 
$D722: BD 2A E9                            LDA ClayDeltaToAnimIndex,X
$D725: 85 35                               STA SpriteScriptIndex
$D727: 86 0C                               STX a0C
$D729: 38                                  SEC 
$D72A: E9 18                               SBC #$18
$D72C: 85 56                               STA pigionDistance
$D72E: A6 C1                               LDX CurrRound
$D730: A9 00                               LDA #$00
$D732: E0 12                               CPX #$12
$D734: 90 08                               BCC bD73E
$D736: A9 03                               LDA #$03
$D738: E0 23                               CPX #$23
$D73A: 90 02                               BCC bD73E
$D73C: A9 06                               LDA #$06
$D73E: 18          bD73E                   CLC 
$D73F: 65 0C                               ADC a0C
$D741: AA                                  TAX 
$D742: BD 44 E9                            LDA fE944,X
$D745: 85 3A                               STA a3A
$D747: 20 05 D8                            JSR sD805
$D74A: 4C 1B D0                            JMP unpackSprite

$D74D: A9 08       bD74D                   LDA #$08
$D74F: 85 31                               STA BirdEntFSMIndex
$D751: 60                                  RTS 
I've done it "full" so you can match it up. Update Curves I think is the function you don't have

not sure if it is my UpdateCurves which just adds an acceleration to the 3 parabola curves.
or if its is my

Code: Select all

$D82F: A5 4D       getPigieonXY            LDA a4D
$D831: 38                                  SEC 
$D832: E9 00                               SBC #$00
$D834: A8                                  TAY 
$D835: A5 4E                               LDA CE_doingFlyAway
$D837: E9 10                               SBC #$10
$D839: AA                                  TAX 
$D83A: A9 3B                               LDA #$3B
$D83C: 20 DB D8                            JSR mul_s16_s8_r16
$D83F: 84 14                               STY a14
$D841: 86 15                               STX a15
$D843: A5 4D                               LDA a4D
$D845: 38                                  SEC 
$D846: E9 00                               SBC #$00                     ;=4D_4E - $1000 * $3b
$D848: A8                                  TAY 
$D849: A5 4E                               LDA CE_doingFlyAway
$D84B: E9 10                               SBC #$10
$D84D: AA                                  TAX 
$D84E: A9 E7                               LDA #$E7
$D850: 20 DB D8                            JSR mul_s16_s8_r16
$D853: 84 12                               STY a12
$D855: 86 13                               STX a13
$D857: A5 48                               LDA DirToSetBird
$D859: 38                                  SEC 
$D85A: E9 00                               SBC #$00                     ;=4D_4E - $1000 * $E7
$D85C: A8                                  TAY 
$D85D: A5 49                               LDA CurrSpriteDeltaIndex
$D85F: E9 18                               SBC #$18
$D861: AA                                  TAX 
$D862: A9 7F                               LDA #$7F
$D864: 20 DB D8                            JSR mul_s16_s8_r16           ;48_49 - $1800 * $7f
$D867: 18                                  CLC 
$D868: 98                                  TYA 
$D869: 69 4F                               ADC #$4F
$D86B: A8                                  TAY 
$D86C: 8A                                  TXA 
$D86D: 69 23                               ADC #$23
$D86F: AA                                  TAX 
$D870: 98                                  TYA                          ; + $234F
$D871: 38                                  SEC 
$D872: E5 14                               SBC a14
$D874: 85 93                               STA a93
$D876: 8A                                  TXA 
$D877: E5 15                               SBC a15
$D879: C9 50                               CMP #$50
$D87B: 6A                                  ROR 
$D87C: 85 94                               STA a94                      ;93_94 = (48_49 - $1800 * $7f + $234F) - (4D_4E - $1000 * $3b)
$D87E: 66 93                               ROR a93
$D880: A4 91                               LDY a91
$D882: A6 92                               LDX a92
$D884: A9 6C                               LDA #$6C
$D886: 20 DB D8                            JSR mul_s16_s8_r16           ;91_92 * $6c
$D889: 18                                  CLC 
$D88A: 98                                  TYA 
$D88B: 65 12                               ADC a12
$D88D: A8                                  TAY 
$D88E: 8A                                  TXA 
$D88F: 65 13                               ADC a13
$D891: AA                                  TAX 
$D892: 20 07 D9                            JSR div_s16_s16_r8           ;91_92 * 6c + (4D_4E - $1000 * $E7)
$D895: E9 00                               SBC #$00
$D897: 49 7F                               EOR #$7F
$D899: 85 32                               STA BirdY
$D89B: A5 43                               LDA AnimScriptIndex
$D89D: 38                                  SEC 
$D89E: E9 00                               SBC #$00                     ;signed negate
$D8A0: A8                                  TAY 
$D8A1: A5 44                               LDA a44
$D8A3: E9 09                               SBC #$09
$D8A5: AA                                  TAX 
$D8A6: 20 07 D9                            JSR div_s16_s16_r8           ; (43_44 - $0900) / (48_49 - $1800 * $7f + $234F) - (4D_4E - $1000 * $3b)
$D8A9: 49 80                               EOR #$80
$D8AB: 85 33                               STA BirdX
$D8AD: 60                                  RTS 

3gengames
Formerly 65024U
Posts: 2276
Joined: Sat Mar 27, 2010 12:57 pm

Re: Duck Hunt Reverse Engineering

Post by 3gengames » Sun Mar 22, 2020 2:49 pm

Oziphantom wrote:
Sat Mar 21, 2020 11:30 pm
mostly, I didn't care about the sound driver, I just worked out which function played which sfx.
Since I wasn't using a PPU, I didn't care for the minute details of the PPU code either, such as sprite offsets or the particle code.
Where is your source code? I actually did that game also because there wasn't a disassembly that I had found. I really want to match them up and improve my labels/comments for sure.

And yeah, I just got to that routine. Didn't make too much sense going through it, didn't get to trace it out yet. It is 100% the pigeon curve, though. Your routine is exactly the same code.

I also did try to do most of the disassembly without using emulator help. In the middle/end I did use an emulator with hex editor during gameplay more, but not too much. I do plan on going through the sound engine and stuff soon. I want to get all the code in the game labeled eventually. Although right now, I might take time to rework my tool for 6809 like said. I do plan on doing more NES games, though. I am thinking Contra or Kirby next. Or maybe even something else, as going from a 16KB game to a 128KB+ game is a large stretch. I want to do Defender since it's a really cool game without a source currently. :)

Oziphantom
Posts: 859
Joined: Tue Feb 07, 2017 2:03 am

Re: Duck Hunt Reverse Engineering

Post by Oziphantom » Sun Mar 22, 2020 11:59 pm

behind closed doors so the vultures don't get access to it ;) or get hints of what I'm up to.

Use the cheat finder and work out as many variables as you can before you start. Pump them in and it will make it a LOT faster.

dec $4a
rts

well this decs something, but what???

dec PlayerLives
rts

oh this decs lives, then you look at where it is called and then you know where the collision routine ends.. then it calls sum function that does something with audio.. they will be the "play death sound routine" then etc.

3gengames
Formerly 65024U
Posts: 2276
Joined: Sat Mar 27, 2010 12:57 pm

Re: Duck Hunt Reverse Engineering

Post by 3gengames » Wed Mar 25, 2020 6:49 am

Oziphantom wrote:
Sun Mar 22, 2020 11:59 pm
behind closed doors so the vultures don't get access to it ;) or get hints of what I'm up to.
You do know that I have the full source mostly done, right? But that's fine, thanks for the hint of what that routine does/comments that I didn't have.

I'll probably slightly poach your function comments them to complete my source file. If you don't mind. :)

Oziphantom
Posts: 859
Joined: Tue Feb 07, 2017 2:03 am

Re: Duck Hunt Reverse Engineering

Post by Oziphantom » Wed Mar 25, 2020 7:01 am

well this is the NESDev world, most of the vultures don't circle here, in the rich fertile crowded Commodore lands, they circle..

Post Reply