Jump to content

jstout

Members
  • Posts

    545
  • Joined

  • Last visited

  • Days Won

    5

Everything posted by jstout

  1. Passing loft is just part of creating the arc you see in the game. The Arc needs to know other things like velocity to create a pass that will hit the mark. But if test or watch the video then you'll see the xFF loft is a straight line and the x01 has some upward movement but nothing that would be comical so all the x30 values will look fairly similar. >http://www.youtube.com/watch?v=KsFvQ8MwaNc
  2. I've learned more about the code since then. The original code is below: x2869E: LDY #$08 ; PLAYER ID INDEX LDA ($AE),Y ; PLAYER ID TAX LDA $70 AND #$1C CMP #$10 BCS @TACKLED CMP #$08 BCS @KR_PR ; KR/PR TXA EOR $70 BMI @QB_OL_PR TXA AND #$0F ; PLAYER # BEQ @QB_OL_PR ; QB CMP #$06 BCS @QB_OL_PR ; OL TXA JSR L_DD8D JMP @SKILL ; SKILL PLAYER@KR_PR: CMP #$0A BCS @QB_OL_PR ; PR EXIT ORA #$10 ; GET KR ID STA $45 TXA AND #$80 ORA $45 JSR L_DD98@SKILL: LDY #$86 ; GET PLAYER BALL CONTROL JSR L_DDAA TAY LDA $3D ; RANDOM CMP BALL_CONTROL_VALUES,Y ; BALL CONTROL SKILL BCS @TACKLED ; TACKLED? JMP @FUMBLED ; FUMBLED@QB_OL_PR: LDA $3D ; RANDOM CMP #$0C ; 44 SKILL BCS @TACKLED ; TACKLED?@FUMBLED: ; FUMBLE ROUTINE LDY #$01 LDA ($AE),Y AND #$DF STA ($AE),Y JSR L_21_BA47 JMP L_21_85A6@TACKLED: ; TACKLED ROUTINE LDA $71 ORA #$80 STA $71 JMP L_21_85A6BALL_CONTROL_VALUES:.BYTE $12,$11,$10,$0F,$0E,$0D,$0C,$0B,$0A,$09,$08,$07,$06,$05,$04,$03The hack posted here uses the first lines LDY #$08 as the PRs skill index (which was 56 skill) for the CMP BALL_CONTROL_VALUES,Y line. The QB kept the branch listed about for the skill value. Its quite possible to hack this using tables for a team's QB and PR ball control value. Or even to have the PR use their own ball control skill.
  3. The percentages can be changed with each player on defense but overall 12% seems to be the normal amount set. If IND calls Pass #2 and the defense calls Pass #1: ROLB = 12% Man WR1 RILB = Rush LILB = Rush LOLB = 12% MAN WR2 RCB = Move Turn LCB = MAN TE However if the defense calls Run #2 (nobody gets man to man): ROLB = Turn Rush (if COA/COM and week 5 or more then 12% rush else vertical mirror ballcarrier) RILB = Rush LILB = Rush LOLB = Turn Rush RCB = Move Turn LCB = Move Turn
  4. Change x29FEC from x87 to x88 and change the x88 to x87 in the PC/PA hack to reverse the values. Or you can flip the ratings for all the QBs.
  5. The defensive play design has randoms and jumps based upon the week that produce the various tasks like what you described. An simplified example of IND calling Pass #1 and the defense calling Pass #2 has the defense: RE = ZigZag or Rush NT = Rush LE = Rush ROLB = 12% Chance to Man to Man RB (else turn and later rush) RILB = Rush LILB = Rush LOLB = 12% Chance to Man to Man TE (else turn and later rush) RCB = Man to Man WR1 LCB = 12% Chance to Man to Man WR2 (else move and stop)
  6. I was intrigued as most wanted a hacking front to back example. The grappling hack was involved with only light complications. I spent much much much longer writing this all out then actually going through the steps this morning. This definitely needs some cleanup and only you guys can tell me if I need to dumb it down more or if I was babying you too much at times but this will give an idea of the steps I followed that you can replicate. Feedback will improve this too as I tried to get this done as fast as possible without detailing every last exact button name to press (just told to do it). The FCEUX Save State and the Code/Data logs I remembered to save are attached so you can see what I saw with them. I'm using FCEUX 2.2.1, http://www.fceux.com/web/home.html, and the original TSB rom. So here it goes hoping all this text fits and I already know my clean looking notepad format will be ripped to shreds in the post =) I'll probably created a new topic when all the other stuff is created or more ready to go than this so its easily found in one place. ManVsGrappleFiles.zip GOAL: Improve Man vs Com Grappling KNOW: Pressing buttons on controller helps determines grapple winner. High HP popcorns opponent. Com can't use a controller to press buttons. START: Find the Man Presses. HOW: A. Find the controller RAM storage then using the storage to count presses B. Find when it counts presses We'll attempt with Option B as it would be the quickest method if found. -------------------- GOAL: Find the press counter Step 1. Get a save state just before a grapple occurs so we can reload and test over and over again. Step 2. Open the Code/Data Logger and hit Start. Step 3. Run winning a grapple then pause the emulator and then run losing a grapple (no presses) then pause the emulator then pause the Code/Data Logger. Step 4. Pause the emulator during a grapple and open the Cheats... 1. In the Cheat Search hit Reset 2. Presses could be counted up (highest value) or down (first to a certain number). Logically we expect up. 3. Hit 00 Known Value = 639 Possibilities 4. Unpause grapple then repause during grapple. (If Grapple is done then reload save state to get back into grapple) 5. Hit 00 Known Value = 636 Possibilities 6. Unpause grapple, press A Button, then repause during grapple. (If Grapple is done then reload save state to get back into grapple then hit A Button) 7. Hit Greater Than = 51 Possibilites 8. Unpause grapple, press A Button, then repause during grapple. (If Grapple is done then reload save state to get back into grapple then hit A Button twice) 9. Hit Greater Than = 3 Possibilites (only $03BC == 02 so we expect this to be the location) Step 5. We are looking for press confirmaton. In the Debugger, Add Breakpoint with Address: 03BC and Write 1. Reload the Save State 2. Determine the breakpoints by writing down each location and hitting run to find the next until grapple finishes then pause 3. Repeat 1 and 2 hitting the A button during the grapple At Contact: x2826A 0A:825A:91 AE STA ($AE),Y @ $03BC [A = 00] This should be the press reset At Press: x28285 0A:8275:91 AE STA ($AE),Y @ $03BC [A = 01] This should be the press storage Step 6. Gather some information off these breakpoints. 1. Double-click on the 3BC breakpoint to disable 2. Add Breakpoint with Address: 825A and Execute 3. Add Breakpoint with Address: 8275 and Execute 4. Open the Trace Logger and have it start logging in the window 5. Reload the Save State and enter the grapple Trace Logger: $DAC1:A0 07 LDY #$07 A:00 X:00 Y:05 S:39 P:nvUBdiZC $DAC3:B1 AE LDA ($AE),Y @ $0606 = #$82 A:00 X:00 Y:07 S:39 P:nvUBdizC $DAC5:48 PHA A:82 X:00 Y:07 S:39 P:NvUBdizC $DAC6:88 DEY A:82 X:00 Y:07 S:38 P:NvUBdizC $DAC7:B1 AE LDA ($AE),Y @ $0605 = #$55 A:82 X:00 Y:06 S:38 P:nvUBdizC $DAC9:48 PHA A:55 X:00 Y:06 S:38 P:nvUBdizC $DACA:60 RTS (from $DACB) ----------------- A:55 X:00 Y:06 S:37 P:nvUBdizC $8256:A9 00 LDA #$00 A:55 X:00 Y:06 S:39 P:nvUBdizC ; RESET PRESS COUNTER $8258:A0 1D LDY #$1D A:00 X:00 Y:06 S:39 P:nvUBdiZC Breakpoint 1 Hit at $825A: $825A:EC--X- 6. Change 825A Breakpoint Addresss to 8256 7. Stop the Trace Logger 8. Copy Code from the Debugger using 8256 and 8275 and label the obvious 0A:8256:A9 00 LDA #$00 ; RESET PRESS VALUE 0A:8258:A0 1D LDY #$1D ; #$1D INDEX to PRESS COUNTER 0A:825A:91 AE STA ($AE),Y @ $03BC ; $AE = POINTER, $03BC = PRESS COUNTER 0A:825C:A0 01 LDY #$01 0A:825E:B1 AE LDA ($AE),Y @ $03A0 0A:8260:29 40 AND #$40 0A:8262:F0 16 BEQ $827A 0A:8264:A9 01 LDA #$01 0A:8266:20 CB DA JSR $DACB 0A:8269:20 08 A1 JSR $A108 ; COUNT? 0A:826C:10 F6 BPL $8264 0A:826E:A0 1D LDY #$1D ; INDEX TO PRESS COUNTER 0A:8270:B1 AE LDA ($AE),Y @ $03BC ; LOAD PRESS COUNTER 0A:8272:18 CLC 0A:8273:69 01 ADC #$01 ; ADD 1 TO PRESS COUNTER 0A:8275:91 AE STA ($AE),Y @ $03BC ; STORE PRESSES 0A:8277:4C 64 82 JMP $8264 ; REPEAT AT $8264 Step 7. Determine when the press counter is used (exluding the read to store the counter we found above) 1. Add Breakpoint with Address: 03BC and Read with Condition: P != #8270 2. Reload the Save State and enter the grapple At End: x284F6 0A:84E6:B1 AE LDA ($AE),Y @ $03BC This should be read for the press winner 3. Reset Code/Data Logger then hit Start. Win a grapple and Lose a Grapple as above. 4. Copy Code from Debugger (with help from Code/Data Logger spotting the entry point) and label the obvious *In the Hex Editor, using the View Menu set to ROM File (Code/Data Logger makes Data Blue, Code Gold, Code and Data Green, Unused Black) 0A:84DC:20 4C B1 JSR $B14C 0A:84DF:A9 40 LDA #$40 0A:84E1:20 CB DA JSR $DACB 0A:84E4:A0 1D LDY #$1D ; PRESS COUNTER INDEX 0A:84E6:B1 AE LDA ($AE),Y @ $03BC ; LOAD PRESS COUNTER 0A:84E8:C9 02 CMP #$02 0A:84EA:90 0D BCC $84F9 ; LESS THAN 2 PRESSES? ; GREATER THAN OR EQUAL TO 2 PRESSES 0A:84EC:20 90 B1 JSR $B190 0A:84EF:A0 81 LDY #$81 0A:84F1:A2 85 LDX #$85 0A:84F3:20 C9 B1 JSR $B1C9 0A:84F6:4C 23 87 JMP $8723 ; EXIT ; LESS THAN 2 PRESSES 0A:84F9:20 90 B1 JSR $B190 0A:84FC:A0 22 LDY #$22 0A:84FE:A2 87 LDX #$87 0A:8500:20 C9 B1 JSR $B1C9 0A:8503:A9 01 LDA #$01 0A:8505:20 CB DA JSR $DACB 0A:8508:4C 51 85 JMP $8551 ; EXIT 5. When we force to $84F9 by either NOP or JMP (refer to the 6502 opcodes for these values), quick testing shows Player 1 always loses the grapple 6. When we force to $84EC by NOP, quick testing shows Player 1 always wins the grapple We found our grapple section we need to edit but we are lacking all the info we what to use. -------------------- GOAL 2: We want to include HP so we need to find if its already loaded for our use KNOW: High HP popcorns opponent. Each Player has a section containing important game info. Its well documented and easy to find regardless so my Save State player QB Bills HP: x3011 2nd Nibble START: HP of our player Step 1. Add a Breakpoint for HP 1. Address: 9001 and Read with Condition: $9001 == #11 2. Address: B001 and Read with Condition: $B001 == #11 *We don't know if x3011 is in the $8000 or $A000 Bank so we set both. 3. Disable prior breakpoints 4. Determine the breakpoints by writing down each location and hitting run between the play call screen and game screen First Hit: x3DDEB >0F:DDDB:B1 3E LDA ($3E),Y @ $B001 = #$11 Second Hit: x3DDEB >0F:DDDB:B1 3E LDA ($3E),Y @ $B001 = #$11 5. Do it again but in the Debugger hit Step Into after hit to determine how its used First Step Into: >0F:DDDB:B1 3E LDA ($3E),Y @ $B001 0F:DDDD:B0 04 BCS $DDE3 0F:DDDF:4A LSR 0F:DDE0:4A LSR 0F:DDE1:4A LSR 0F:DDE2:4A LSR 0F:DDE3:29 0F AND #$0F 0F:DDE5:85 3E STA $003E ; FIRST NIBBLE Second Step Into: >0F:DDDB:B1 3E LDA ($3E),Y @ $B001 0F:DDDD:B0 04 BCS $DDE3 0F:DDE3:29 0F AND #$0F 0F:DDE5:85 3E STA $003E ; SECOND NIBBLE 6. Add Breakpoint with Address: 3E and Read and Write but disable it 7. Wait until second breakpoint and enable the 3E breakpoint then hit run x3DE0E 0F:DDFE:65 3E ADC $003E Adding our value to something x3DDC8 0F:DDB8:85 3E STA $003E Removes our number and quick inspection of debugger shows its creating a pointer 8. In the Debugger seek to DDFE and copy the code until the exit. 0F:DDE7:A5 45 LDA $0045 0F:DDE9:4A LSR 0F:DDEA:4A LSR 0F:DDEB:A8 TAY 0F:DDEC:28 PLP 0F:DDED:B0 06 BCS $DDF5 0F:DDEF:B9 03 65 LDA $6503,Y 0F:DDF2:4C F8 DD JMP $DDF8 0F:DDF5:B9 08 66 LDA $6608,Y 0F:DDF8:A6 45 LDX $0045 0F:DDFA:20 40 DE JSR $DE40 0F:DDFD:18 CLC 0F:DDFE:65 3E ADC $003E 0F:DE00:38 SEC 0F:DE01:E9 01 SBC #$01 0F:DE03:B0 02 BCS $DE07 0F:DE05:A9 00 LDA #$00 0F:DE07:C9 10 CMP #$10 0F:DE09:90 02 BCC $DE0D 0F:DE0B:A9 0F LDA #$0F 0F:DE0D:A8 TAY 0F:DE0E:A6 44 LDX $0044 0F:DE10:20 E3 D8 JSR $D8E3 0F:DE13:98 TYA 0F:DE14:60 RTS ------------------------------- ; EXIT 9. Add a Breakpoint at Address: DE14 and Execute but disable 10. Do 6 and 7 again but also enable the DE14 breakpoint. 11. At the DE14 breakpoint, use the debugger Step Into storing the code until values are gone then label the obvious 0F:DDE7:A5 45 LDA $0045 0F:DDE9:4A LSR 0F:DDEA:4A LSR 0F:DDEB:A8 TAY 0F:DDEC:28 PLP 0F:DDED:B0 06 BCS $DDF5 0F:DDEF:B9 03 65 LDA $6503,Y @ $6503 0F:DDF2:4C F8 DD JMP $DDF8 0F:DDF5:B9 08 66 LDA $6608,Y @ $6608 0F:DDF8:A6 45 LDX $0045 0F:DDFA:20 40 DE JSR $DE40 ; GET CONDITIONAL BOOSTS 0F:DDFD:18 CLC 0F:DDFE:65 3E ADC $003E ; ADD HP 0F:DE00:38 SEC 0F:DE01:E9 01 SBC #$01 ; SUBTRACT 1 0F:DE03:B0 02 BCS $DE07 ; NEGATIVE VALUE? 0F:DE05:A9 00 LDA #$00 ; SET TO 0 IF NEGATIVE 0F:DE07:C9 10 CMP #$10 0F:DE09:90 02 BCC $DE0D ; ABOVE MAX? 0F:DE0B:A9 0F LDA #$0F ; SET TO MAX IF TOO LARGE 0F:DE0D:A8 TAY ; FINAL HP TO Y 0F:DE0E:A6 44 LDX $0044 0F:DE10:20 E3 D8 JSR $D8E3 0F:DE13:98 TYA ; FINAL HP TO A 0F:DE14:60 RTS ------------------------------- 0D:86B4:AA TAX ; FINAL HP TO X (NOTE FINAL HP IS IN A, X, Y) 0D:86B5:60 RTS ------------------------------- 0D:8675:AA TAX ; SET HP AS INDEX FOR TABLE 0D:8676:BD EF DF LDA $DFEF,X @ $DFF0 ; GET HP VALUE FROM TABLE 0D:8679:A0 1C LDY #$1C ; HP VALUE INDEX 0D:867B:91 40 STA ($40),Y @ $03BB ; STORE HP VALUE ... CONTINUE ELIMINATES FINAL HP IN REGISTERS A,X,Y Step 2. Add a breakpoint for the new HP location we found 1. Delete the 9001, B001, 3E, DE14 breakpoints 2. Add a breakpoint for Address: 03BB and Read and Write 4. Enable the breakpoints at 8256 and 8275 (We know the HP has to be checked first) 5. Pause the emulator and reset the Code/Data Logger hit Run 6. Reload our save state just before the grapple and record the breakpoints for $03BB At Contact: x284D9 0A:84C9:B1 AE LDA ($AE),Y @ $03BB Read HP for Popcorn Check 7. Pause the Code/Data Logger 8. Reload before the grapple until breakpoint and copy Code from Debugger (with help from Code/Data Logger spotting the entry point) and label the obvious 0A:84C7:A0 1C LDY #$1C ; HP VALUE INDEX 0A:84C9:B1 AE LDA ($AE),Y @ $03BB ; MAN HP VALUE ($AE is MAN POINTER) 0A:84CB:38 SEC 0A:84CC:F1 3E SBC ($3E),Y @ $061B ; SUBTRACT COM HP VALUE ($3E is COM POINTER; $61B ADDRESS - #$1C INDEX = $05FF POINTER) 0A:84CE:90 04 BCC $84D4 ; MAN LESS THAN COM HP VALUE? ; MAN MORE THAN COM HP VALUE 0A:84D0:C9 20 CMP #$20 0A:84D2:B0 18 BCS $84EC ; MAN MORE THAN COM HP VALUE BY x20+ (THIS HEADS STRAIGHT TO WIN GRAPPLE) ; MAN LESS THAN COM HP VALUE 0A:84D4:20 36 B1 JSR $B136 0A:84D7:A9 01 LDA #$01 0A:84D9:20 CB DA JSR $DACB ; We know the following code here is the Man vs Com press check from above 0A:84DC:20 4C B1 JSR $B14C 0A:84DF:A9 40 LDA #$40 0A:84E1:20 CB DA JSR $DACB 0A:84E4:A0 1D LDY #$1D ; PRESS COUNTER INDEX 0A:84E6:B1 AE LDA ($AE),Y @ $03BC ; LOAD PRESS COUNTER 0A:84E8:C9 02 CMP #$02 0A:84EA:90 0D BCC $84F9 ; LESS THAN 2 PRESSES? ; GREATER THAN OR EQUAL TO 2 PRESSES 0A:84EC:20 90 B1 JSR $B190 0A:84EF:A0 81 LDY #$81 0A:84F1:A2 85 LDX #$85 0A:84F3:20 C9 B1 JSR $B1C9 0A:84F6:4C 23 87 JMP $8723 ; EXIT ; LESS THAN 2 PRESSES 0A:84F9:20 90 B1 JSR $B190 0A:84FC:A0 22 LDY #$22 0A:84FE:A2 87 LDX #$87 0A:8500:20 C9 B1 JSR $B1C9 0A:8503:A9 01 LDA #$01 0A:8505:20 CB DA JSR $DACB 0A:8508:4C 51 85 JMP $8551 ; EXIT Step 3. Find the Com Pointer creation 1. Add a breakpoint of Address: 3E to 3F and Write with Condition: A == #FF (From the Pointer calculation of $05FF above). We'll change A to X then Y if the most common A isn't correct. 2. Reset the Trace Logger and hit Start in the window 3. Reload before the grapple until we reach our beginning breakpoint of 84C7 then label the obvious $832E:20 90 B1 JSR $B190 A:2D X:07 Y:03 S:39 P:nvUBdizC ; GET COM POINTER $B190:A0 1E LDY #$1E A:2D X:07 Y:03 S:37 P:nvUBdizC ; INDEX $B192:B1 AE LDA ($AE),Y @ $03BD = #$FF A:2D X:07 Y:1E S:37 P:nvUBdizC ; FROM MAN PLAYER Breakpoint 5 Hit at $B194: $003E-003F:EC-W-- Condition:A == #FF $B194:85 3E STA $003E = #$4A A:FF X:07 Y:1E S:37 P:NvUBdizC ; COM POINTER LO $B196:C8 INY A:FF X:07 Y:1E S:37 P:NvUBdizC ; NEXT INDEX $B197:B1 AE LDA ($AE),Y @ $03BE = #$05 A:FF X:07 Y:1F S:37 P:nvUBdizC ; FROM MAN PLAYER $B199:85 3F STA $003F = #$B2 A:05 X:07 Y:1F S:37 P:nvUBdizC ; COM POINTER HI $B19B:60 RTS (from $B190) ----------------- A:05 X:07 Y:1F S:37 P:nvUBdizC ; EXIT $8331:A0 01 LDY #$01 A:05 X:07 Y:1F S:39 P:nvUBdizC $8333:B1 AE LDA ($AE),Y @ $03A0 = #$60 A:05 X:07 Y:01 S:39 P:nvUBdizC $8335:29 40 AND #$40 A:60 X:07 Y:01 S:39 P:nvUBdizC $8337:F0 0C BEQ $8345 A:40 X:07 Y:01 S:39 P:nvUBdizC $8339:B1 3E LDA ($3E),Y @ $0600 = #$80 A:40 X:07 Y:01 S:39 P:nvUBdizC $833B:29 40 AND #$40 A:80 X:07 Y:01 S:39 P:NvUBdizC $833D:F0 03 BEQ $8342 A:00 X:07 Y:01 S:39 P:nvUBdiZC $8342:4C C7 84 JMP $84C7 A:00 X:07 Y:01 S:39 P:nvUBdiZC ; JUMP TO GRAPPLE ROUTINE Breakpoint 4 Hit at $84C7: $84C7:EC--X- Now he have the Pointer for the Man and Com players with their HP values -------------------- GOAL: Write the Improvement Code with the knowledge we acquired KNOW: $3B-$3D are Random Values START: Write it in notepad Step 1. Write the code out 0A:84C7:A0 1C LDY #$1C ; HP VALUE INDEX 0A:84C9:B1 AE LDA ($AE),Y @ $03BB ; MAN HP VALUE ($AE is MAN POINTER) 0A:84CB:38 SEC 0A:84CC:F1 3E SBC ($3E),Y @ $061B ; SUBTRACT COM HP VALUE ($3E is COM POINTER; $61B ADDRESS - #$1C INDEX = $05FF POINTER) 0A:84CE:90 04 BCC $84D4 ; MAN LESS THAN COM HP VALUE? ; MAN MORE THAN COM HP VALUE 0A:84D0:C9 20 CMP #$20 0A:84D2:B0 18 BCS $84EC ; MAN MORE THAN COM HP VALUE BY x20+ (THIS HEADS STRAIGHT TO WIN GRAPPLE) ; MAN LESS THAN COM HP VALUE 0A:84D4:20 36 B1 JSR $B136 0A:84D7:A9 01 LDA #$01 0A:84D9:20 CB DA JSR $DACB 0A:84DC:20 4C B1 JSR $B14C 0A:84DF:A9 40 LDA #$40 0A:84E1:20 CB DA JSR $DACB A0 1C LDY #$1C ; HP INDEX B1 AE LDA ($AE),Y ; LOAD MAN HP 4A LSR 4A LSR 4A LSR C8 INY ; PRESS INDEX 18 CLC 71 AE ADC ($AE),Y ; HP/8 + PRESS 91 AE STA ($AE),Y ; STORE IN MAN PRESS COUNTER 20 90 B1 JSR $B190 ; LOAD COM POINTER A0 1C LDY #$1C ; HP INDEX B1 3E LDA ($3E),Y ; LOAD COM HP 4A LSR 4A LSR 4A LSR C8 INY 91 3E STA ($3E),Y ; STORE HP/8 IN COM PRESS COUNTER A5 3D LDA $003D ; RANDOM NUMBER 29 0F AND #$0F ; MAKE RANDOM x0-F 18 CLC 71 3E ADC ($3E),Y ; HP/8 + RANDOM 91 3E STA ($3E),Y ; STORE IN COM PRESS COUNTER B1 AE LDA ($AE),Y ; LOAD MAN PRESS COUNTER D1 3E CMP ($3E),Y ; COMPARE WITH COM PRESS COUNTER 0A:84EA:90 0D BCC $84F9 ; LESS THAN COM? ; GREATER THAN OR EQUAL TO COM PRESSES 0A:84EC:20 90 B1 JSR $B190 0A:84EF:A0 81 LDY #$81 0A:84F1:A2 85 LDX #$85 0A:84F3:20 C9 B1 JSR $B1C9 0A:84F6:4C 23 87 JMP $8723 ; EXIT ; LESS THAN COM PRESSES 0A:84F9:20 90 B1 JSR $B190 0A:84FC:A0 22 LDY #$22 0A:84FE:A2 87 LDX #$87 0A:8500:20 C9 B1 JSR $B1C9 0A:8503:A9 01 LDA #$01 0A:8505:20 CB DA JSR $DACB 0A:8508:4C 51 85 JMP $8551 ; EXIT Step 2. Insert the Code 1. Open the Hex Editor 2. Using the debugger, Add a breakpoint with Address: 84E4 and Execute and Disable the other breakpoints 3. Reload and run until breakpoint 4. In the debugger, Seek To 9FFF and scroll up searching for empty space (not enough there) 5. In the debugger, Seek To BFFF and scroll up searching for empty space (we have room where these FFs are) *Its usually a good idea to leave the first FF unless you know its not used but in this case I'm starting at the start of a fresh line 6. Type in our code so it fits. At x284F4: 20 40 BF JSR $BF40 ; NEW MAN VS CPU GRAPPLING CODE At x2BF50: MAN VS CPU GRAPPLING: A0 1C LDY #$1C ; HP INDEX B1 AE LDA ($AE),Y ; LOAD MAN HP 4A LSR 4A LSR 4A LSR C8 INY ; PRESS INDEX 18 CLC 71 AE ADC ($AE),Y ; HP/8 + PRESS 91 AE STA ($AE),Y ; STORE IN MAN PRESS COUNTER 20 90 B1 JSR $B190 ; LOAD COM POINTER A0 1C LDY #$1C ; HP INDEX B1 3E LDA ($3E),Y ; LOAD COM HP 4A LSR 4A LSR 4A LSR C8 INY 91 3E STA ($3E),Y ; STORE HP/8 IN COM PRESS COUNTER A5 3D LDA $003D ; RANDOM NUMBER 29 0F AND #$0F ; MAKE RANDOM x0-F 18 CLC 71 3E ADC ($3E),Y ; HP/8 + RANDOM 91 3E STA ($3E),Y ; STORE IN COM PRESS COUNTER ; RETURN TO NORMAL B1 AE LDA ($AE),Y ; LOAD MAN PRESS COUNTER AS BEFORE 60 RTS At x284E5 ; RETURN HERE EA NOP D1 3E CMP ($3E),Y ; REPLACE CMP #$02 with COM PRESS COUNTER Step 3. Test the game to make sure everything works and the inserted code never gets swapped out when its needed -------------------- Repeat with a Man vs Man grapple to determine if the same code or new code but I'll leave that to you to work on your skills =)
  7. I thought about all the common topics/issues with the NES and created the list below with the | being related and/or advanced topics. The 6502 section is general assembly knowledge allowing people to read and write code. The NES Programming section is a how and why things are done (could create a game, low-level hacking is limited but might explain how things are stored, high-level hacking will understand reasoning and allow practical applications outside of code snippets) and likely contain code examples. The FCEUX Hacking section would describe how to use the various features in the emulator and likely contain simple examples (the problem here is sometimes things just aren't simple to find or change). Did I miss anything people want to know about? Is this overkill of what people want to know about? And more importantly are there more than 2-3 people even interested in this? 6502: NUMBER FORMATS REGISTERS ADDRESSING MODES PROCESSOR STATUS FLAGS OPCODES BASIC MATH | 16-BIT OPERATIONS, FIXED POINT NES PROGRAMMING: MEMORY MAPS PPU REGISTERS SKELETON ROM GAME LOOP | GAME STATES, MULTITASK PALETTE | FADE SPRITES | METASPRITES, ANIMATION, COLLISION DETECTION CONTROLLER BACKGROUND | METATILES, COMPRESSION SCROLL | CAMERA SPRITE 0 HIT MMC3 MEMORY MAPPER SOUND | DMC, SOUND ENGINE FCEUX HACKING: HEX EDITOR | CORRUPTION, FONT TABLES, CODE INSERTION PPU VIEWER NAME TABLE VIEWER CODE/DATA LOGGER | FILE COMPARE CHEAT SEARCH DEBUGGER | CONDITIONS TRACE LOGGER SAVE STATES
  8. Generally the sorting was being created before 20F995 but sometimes calculations get thrown off like the QB Rating. There likely is some type of workaround to such issues but I only really looked for what was needed earlier.
  9. xXX = %76543210 (Listing Bit Numbers) x55 = %01010101 (%00 = Palette 0, %01 = Palette 1, %10 = Palette 2, %11 = Palette 3) An attribute byte = 4x4 Tiles (32 pixels x 32 pixels) with each Palette Block = 2x2 Tiles (16 pixels x 16 pixels) [ ][ ][ ][ ] [ ][ ][ ][ ] [ ][ ][ ][ ] [ ][ ][ ][ ] The Top Left 2x2 uses bits 10 The Top Right 2x2 uses bits 32 The Bottom Left 2x2 uses bits 54 The Bottom Right 2x2 uses bits 76 So x55 has all 4 Palette Blocks %01 = Palette 1
  10. If there is enough people wanting to learn 6502 / NES programming then I could do this.
  11. It probably depends on the graphic but generally large graphics have byte(s) that are ready to be stored in the attribute table. A 16x16 block gets colored in bits %76543210 like: +---+---+---+---+ | | | | | + 1-0 + 3-2 + | | | | | +---+---+---+---+ | | | | | + 5-4 + 7-6 + | | | | | +---+---+---+---+ where %00 = Palette 0, %01 = Palette 1, %10 = Palette 2, %11 = Palette 3.
  12. That is pretty cool. I attached a text file with the NES Register info and an example of a full source code of a simple NES game I wrote to learn the basics. Maybe these will help someone learn something. 6502_Registers.txt pong.zip
  13. The offset is x35A10 and its known and actually can be executed when certain code breaks occur but obviously the game isn't meant to break so it doesn't happen normally.
  14. I wouldn't say that is entirely right. The high 2 bits control mirroring and the low 6 bits control the row as %VHRRRRRR (V = Vertical Mirror, H = Horizontal Mirror, R = Row). So: x00-x3F = Set Tile Normally (Row 00 to 3F) x40-x7F = Set Tile with Horizontal Mirror (Row 00-3F) x80-xBF = Set Tile with Vertical Mirror (Row 00-3F) xC0-xFF = Set Tile with Horizontal and Vertical Mirror (Row 00-3F)
  15. Here is an example of how the faces are done: Frank Reich: x1C054 $A064 (POINTER) = B9A3 x1C3C9 $A3B9 (DESIGN) = CC10 CF60 CDCC CEBD CF97 B074 x1CC20 $AC10 (HAIR) = 700088 704090 710888 710890 7A0080 7A4098 FE x1CDDC $ADCC (EARS) = 7A0080 7A4098 380800 384818 3A1000 3A5018 FE x1CECD $AEBD (MOUTH) = 221408 225410 FE x1CF70 $AF60 (EYES) = 1B0988 1B4990 FE x1CFA7 $AF97 (LOWER HEAD) = 021008 025010 071808 075810 FE x1D084 $B074 (UPPER HEAD) = 210008 214010 000808 004810 FF Format: TILE ROW COLUMN *ROW = +00 = NORMAL, +40 = HORIZONTAL MIRROR, +80 = VERTICAL MIRROR, +C0 = HORIZONTAL AND VERTICAL MIRROR *COLUMN = +00 = PALETTE 0, +40 = PALETTE 01, +80 = PALETTE 02, +C0 = PALETTE 03 FE = NEXT FF = END
  16. Expanded roms have a lot of room too. Generally, the issue is what else is there to create a hack for? I rarely have solid ideas of things to even attempt on my own.
  17. I did a quick and easy dark uniform and white uniform for the teams. If you have better colors for usage that won't cause uniform clashes then it can easily be changed to those.
  18. x328CB - x328D2 are the pro bowl starters and the last two values are the returners. Both Pro Bowl teams use the same values so you have to write code in order to separate them.
  19. Try changing x2331B to x0A instead of x0B. It looks like the drop in teams is requiring you to change the amount of teams to sort for the wildcard position.
  20. I don't think anyone has edited the CPU call logic much. In the zip file on my post here: http://tecmobowl.org/topic/10793-cpu-logic-for-play-selection/, it goes through the entire play call logic code. It should be easy enough to change or add things knowing what you are trying to make it do.
  21. This is the same code as above but changing the rectangular check to a circle (requires more space for better accuracy). .define DISTANCE $DD .define TEMP_HI $DE .define RECEIVER_LO $40 .define RECEIVER_HI $41 .define DEFENDER_LO $42 .define DEFENDER_HI $43 .define X_LO_APART $44 .define X_HI_APART $45 .define X_APART $44 .define Y_APART $45 .define APART_LO $44 .define APART_HI $45 START: LDY #$00 ; SET TO FIRST COMMAND BYTE TYA PHA @NEXT_RECEIVER: PLA TAY ; CHECK FOR NO MORE RECEIVERS CPY $DC BCC @CONTINUE BEQ @CONTINUE ; NO OPEN RECEIVERS SO RANDOM THROW LDA $3B AND $DC TAY RTS @CONTINUE: INY ; SET TO NEXT RECEIVER ; FIND DISTANCE LDA ($3E),Y AND #$F0 LSR LSR LSR LSR STA DISTANCE BNE @LOCATIONS JMP @EXIT @LOCATIONS: ; GET RECEIVER LOCATION LDA ($3E),Y AND #$0F ; RECEIVER ASL TAX ; PLAYER INDEX TYA PHA ; STORE Y ; WHICH PLAYER? LDY #$08 LDA ($AE),Y BMI @2P LDA $DEEB,X STA RECEIVER_LO LDA $DEEC,X STA RECEIVER_HI JMP @DEFENDER @2P: LDA $DF01,X STA RECEIVER_LO LDA $DF02,X STA RECEIVER_HI @DEFENDER: ; GET DEFENDER LOCATION LDX #$14 ; SET TO LAST DEFENDER INDEX @NEXT_DEFENDER: ; WHICH PLAYER? LDY #$08 LDA ($AE),Y BMI @1P LDA $DF01,X STA DEFENDER_LO LDA $DF02,X STA DEFENDER_HI JMP @CALC @1P: LDA $DEEB,X STA DEFENDER_LO LDA $DEEC,X STA DEFENDER_HI @CALC: ; FIND X SIDE LDY #$15 LDA (RECEIVER_LO),Y CMP (DEFENDER_LO),Y BCC @RIGHT ; RECEIVER < DEFENDER BNE @LEFT ; RECEIVER > DEFENDER DEY LDA (RECEIVER_LO),Y CMP (DEFENDER_LO),Y BCC @RIGHT ; RECEIVER < DEFENDER ; RECEIVER > DEFENDER ; X DISTANCE CHECK @LEFT: LDY #$14 LDA (RECEIVER_LO),Y SEC SBC (DEFENDER_LO),Y STA X_LO_APART INY LDA (RECEIVER_LO),Y SBC (DEFENDER_LO),Y STA X_HI_APART JMP @XAPART @RIGHT: LDY #$14 LDA (DEFENDER_LO),Y SEC SBC (RECEIVER_LO),Y STA X_LO_APART INY LDA (DEFENDER_LO),Y SBC (RECEIVER_LO),Y STA X_HI_APART @XAPART: LDA X_HI_APART BEQ @X_LO JMP @GOOD ; VERY LARGE DISTANCE @X_LO: LDA X_LO_APART LSR LSR LSR CMP DISTANCE BCS @GOOD ; OUT OF X DISTANCE STA X_APART ; IN X DISTANCE = CHECK Y DISTANCE ; FIND Y SIDE LDY #$17 LDA (RECEIVER_LO),Y CMP (DEFENDER_LO),Y BCC @BOTTOM ; RECEIVER < DEFENDER ; RECEIVER > DEFENDER ; Y DISTANCE CHECK @TOP: LDA (RECEIVER_LO),Y SEC SBC (DEFENDER_LO),Y JMP @YAPART @BOTTOM: LDA (DEFENDER_LO),Y SEC SBC (RECEIVER_LO),Y @YAPART: LSR LSR LSR CMP DISTANCE BCS @GOOD ; OUT OF Y DISTANCE STA Y_APART ; IN Y DISTANCE = CHECK RADIUS ; CHECK RADIUS DISTANCE ; A^2 LDY X_APART BEQ @NO_X LDA #$00 @LOOP_X: CLC ADC X_APART DEY BNE @LOOP_X STA X_APART ; B^2 @NO_X: LDY Y_APART BEQ @NO_Y LDA #$00 @LOOP_Y: CLC ADC Y_APART DEY BNE @LOOP_Y STA Y_APART @NO_Y: ; A^2 + B^2 LDA X_APART CLC ADC Y_APART STA APART_LO LDA #$00 ADC #$00 STA APART_HI ; SQRT(A^2 + B^2) TXA PHA LDY #$00 LDX #$07 @loop: TYA ORA @stab-1,X STA TEMP_HI LDA APART_HI CMP TEMP_HI BCC @skip1 SBC TEMP_HI STA APART_HI TYA ORA @stab,x TAY @skip1: ASL APART_LO ROL APART_HI DEX BNE @loop ; last iteration STY TEMP_HI LDA APART_LO CMP #$80 LDA APART_HI SBC TEMP_HI BCC @skip2 INY @skip2: PLA TAX CPY DISTANCE BCC @NEXT ; IN RADIUS DISTANCE = BAD THROW ; MORE DEFENDERS? @GOOD: DEX DEX BMI @THROW ; OPEN JMP @NEXT_DEFENDER @NEXT: JMP @NEXT_RECEIVER @THROW: PLA TAY @EXIT: RTS @stab: .BYTE $01,$02,$04,$08,$10,$20,$40,$80
  22. The higher the first nibble the more open they need to be. Example 13 and A3, 13 would need the WR1 to be open with about 1 yard surrounding him on all sides to be open while A3 would need about 10 yards to his left and right and 6 yards to his top and bottom to be open The original play code looked like: 91 73 F4 42 B8 91 = 2 Receivers 73 = 46% chance of throwing to 3 (WR1) F4 = 100% chance of throwing to 4 (WR2) (if not thrown to 3) 42 B8 = pointer to change control to receiver while the new code replaces the receivers chance of being thrown to with the value of how much space needs to open around him.
  23. This can be applied to any rom including the 32-team roms. If there is playbook changes then the made code will work but all the x90 commands for the offense need to be altered to adhere to the new format. The code above is x1DA20-x1DAF9 and the code to jump to it is x288BE-x288D6 (only other changes are the 90 commands values for the plays)
  24. View attachment: Original_CPU_Passing.nes View attachment: Original_CPU_Passing_Juiced.nes .define X_DISTANCE $DD.define Y_DISTANCE $DE .define RECEIVER_LO $40.define RECEIVER_HI $41 .define DEFENDER_LO $42.define DEFENDER_HI $43 .define X_LO_APART $44.define X_HI_APART $45 START:LDY #$00 ; SET TO FIRST COMMAND BYTETYAPHA@NEXT_RECEIVER:PLATAY; CHECK FOR NO MORE RECEIVERSCPY $DCBCC @CONTINUEBEQ @CONTINUE; NO OPEN RECEIVERS SO RANDOM THROWLDA $3BAND $DCTAYRTS@CONTINUE:INY ; SET TO NEXT RECEIVER ; FIND X DISTANCELDA ($3E),YAND #$F0LSRSTA X_DISTANCE ; DISTANCE * 8 PIXELSBNE @Y_GETJMP @EXIT @Y_GET:; FIND Y DISTANCELDA ($3E),YAND #$F0LSRLSRLSRLSRSTA Y_DISTANCEASLASLCLCADC Y_DISTANCESTA Y_DISTANCE ; DISTANCE * 5 PIXELS ; GET RECEIVER LOCATIONLDA ($3E),YAND #$0FASLTAXTYAPHA;LDY #$08LDA ($AE),YBMI @2PLDA $DEEB,XSTA RECEIVER_LOLDA $DEEC,XSTA RECEIVER_HIJMP @DEFENDER@2P:LDA $DF01,XSTA RECEIVER_LOLDA $DF02,XSTA RECEIVER_HI @DEFENDER:; GET DEFENDER LOCATIONLDX #$14@NEXT_DEFENDER:LDY #$08LDA ($AE),YBMI @1PLDA $DF01,XSTA DEFENDER_LOLDA $DF02,XSTA DEFENDER_HIJMP @CALC@1P:LDA $DEEB,XSTA DEFENDER_LOLDA $DEEC,XSTA DEFENDER_HI @CALC:; FIND X SIDELDY #$15LDA (RECEIVER_LO),YCMP (DEFENDER_LO),YBCC @RIGHT ; RECEIVER < DEFENDERBNE @LEFT ; RECEIVER > DEFENDERDEYLDA (RECEIVER_LO),YCMP (DEFENDER_LO),YBCC @RIGHT ; RECEIVER < DEFENDER ; RECEIVER > DEFENDER ; X DISTANCE CHECK@LEFT:LDY #$14LDA (RECEIVER_LO),YSECSBC (DEFENDER_LO),YSTA X_LO_APARTINYLDA (RECEIVER_LO),YSBC (DEFENDER_LO),YSTA X_HI_APARTJMP @XAPART @RIGHT:LDY #$14LDA (DEFENDER_LO),YSECSBC (RECEIVER_LO),YSTA X_LO_APARTINYLDA (DEFENDER_LO),YSBC (RECEIVER_LO),YSTA X_HI_APART @XAPART:LDA X_HI_APARTBNE @GOOD ; VERY LARGE DISTANCELDA X_LO_APARTCMP X_DISTANCEBCS @GOOD ; OUT OF X DISTANCE ; IN X DISTANCE = CHECK Y DISTANCE ; Y DISTANCE CHECK@TOP_BOTTOM:LDY #$17LDA (RECEIVER_LO),YCMP (DEFENDER_LO),YBCC @BOTTOM ; RECEIVER < DEFENDER ; RECEIVER > DEFENDER @TOP:LDA (RECEIVER_LO),YSECSBC (DEFENDER_LO),YCMP Y_DISTANCEJMP @YAPART @BOTTOM:LDA (DEFENDER_LO),YSECSBC (RECEIVER_LO),YCMP Y_DISTANCE @YAPART:BCC @NEXT ; IN Y DISTANCE = BAD THROW@GOOD:DEXDEXBMI @THROW ; OPENJMP @NEXT_DEFENDER@NEXT:JMP @NEXT_RECEIVER @THROW:PLATAY@EXIT:RTS Set Default Values: PRO T WAGGLE L = 93 54 22 R AND S FLARE C = 94 83 75 52 21 PRO T WAGGLE R = 63 54 21 ROLL OUT R = 94 63 45 31 ROLL OUT L = 93 74 45 22 T PLAY ACTION D = 93 73 42 21 PRO T SCREEN L = 93 54 45 21 PLAY ACTION = 93 54 42 PWR FAKE Z POST = 94 53 31 WTE F-FLICKER = 93 84 SHOTGUN X CURL = 63 64 45 42 21 R AND S Z FLY = 94 92 53 55 PRO T FLARE D = 94 73 45 22 21 OFFSET FLARE E = 94 63 41 32 ONEBACK Z CROSS = 93 92 44 31 ONEBACK FLARE A = 94 53 42 T FLEA FLICKER = 93 54 22 PWR FAKE X FLY = 93 94 55 31 SHOTGUN X DRIVE = 93 54 AND 93 95 54 61 22 R AND S 3-WING = 93 94 72 55 PLAYACTION Z IN = 93 51 54 42 FLEA FLICKER = 94 53 32 PRO T FLARE C = 93 75 64 42 SHOTGUN 3-WING = 93 74 52 45 31 SHOTGUN XY BOMB = 93 94 81 75 62 R AND S Y UP = 93 95 84 42 21 X OUT AND FLY = 94 83 55 32 31 REV-FAKE Z POST = 94 51 SLOT L Z DRIVE = 83 54 AND 83 71 54 45 22 NO BACK X DEEP = 94 72 53 21 SHOTGUN Z S-IN = 73 44 AND 95 73 62 44 21 REDGUN Z SLANT = 94 95 52 43 31 ;--------------- x90 COMMAND: FIRST NIBBLE (BOX DISTANCE) SECOND NIBBLE (RECEIVER): (8 Pixels = 1 Yard) 0 = 0 PIXELS LEFT AND RIGHT + 0 PIXELS UP AND DOWN (Forces Throw) 1 = 8 PIXELS LEFT AND RIGHT + 5 PIXELS UP AND DOWN 2 = 16 PIXELS LEFT AND RIGHT + 10 PIXELS UP AND DOWN 3 = 24 PIXELS LEFT AND RIGHT + 15 PIXELS UP AND DOWN 4 = 32 PIXELS LEFT AND RIGHT + 20 PIXELS UP AND DOWN 5 = 40 PIXELS LEFT AND RIGHT + 25 PIXELS UP AND DOWN 6 = 48 PIXELS LEFT AND RIGHT + 30 PIXELS UP AND DOWN 7 = 56 PIXELS LEFT AND RIGHT + 35 PIXELS UP AND DOWN 8 = 64 PIXELS LEFT AND RIGHT + 40 PIXELS UP AND DOWN 9 = 72 PIXELS LEFT AND RIGHT + 45 PIXELS UP AND DOWN A = 80 PIXELS LEFT AND RIGHT + 50 PIXELS UP AND DOWN B = 88 PIXELS LEFT AND RIGHT + 55 PIXELS UP AND DOWN C = 96 PIXELS LEFT AND RIGHT + 60 PIXELS UP AND DOWN D = 104 PIXELS LEFT AND RIGHT + 65 PIXELS UP AND DOWN E = 112 PIXELS LEFT AND RIGHT + 70 PIXELS UP AND DOWN F = 120 PIXELS LEFT AND RIGHT + 75 PIXELS UP AND DOWN View full article
×
×
  • Create New...