AdamCatalyst Posted January 3 Report Posted January 3 (edited) How to: Fixing the "Handedness" in the Face-Off Insets It's always annoyed me how during a face-off, the inset displays the player on the right (bottom) with the wrong hand. The errors seem to be there from the original, up to and including '94 for SNES. I've played with the code, and can reverse the handedness etc, but can't figure out how to affect the player on the right only. In fact, I can't see any evidence that the flag for the bottom team is even being read in the source code (below). If anyone had any suggestions as to how to handle this (other than a Psychiatrist), I would greatly appreciate it. EDIT: Solution below. cheers, -Adam NHL Hockey (92) Code to Modify Original Logic to Set Handedness for Face-Off Graphics @ 0x63CC 4A2B 0074 6600 0004 5640 Revised In this code I've specified that the patch will be at 0x0007FEDC, but you can change this to wherever you have space. 4EF9 0007 FEDC 4E71 4E71 New Code to Insert Insert this code wherever you specified above. 0x0007FEDC 082B 0007 0062 6700 000E 4A2B 0074 6600 000E 6000 000C 4A2B 0074 6600 0004 5640 4EF9 0000 63D6 NHL 94 Code to Modify Original Logic to Set Handedness for Face-Off Graphics @ 0x63CC 4A2B 0074 6600 0004 5640 Revised In this code I've specified that the patch will be at 0x001FFEA0, but you can change this to wherever you have space. 4EF9 001F FEA0 4E71 4E71 New Code to Insert Insert this code wherever you specified above. 0x001FFEA0 082B 0007 0062 6700 000E 4A2B 0076 6600 000E 6000 000C 4A2B 0076 6600 0004 5640 4EF9 0000 63D6 If you want to understand how this works, check out this post. Edited January 5 by AdamCatalyst Including Solution Quote
McMarkis Posted January 3 Report Posted January 3 (edited) LOL, @AdamCatalyst, diving into source code assembly and the listing file? You're leveling up fast! I wouldn't be surprised if you're rewriting this entire game next. Just to clarify, this is what I am seeing when I test with Montreal (Home), LA (Away) 1st period. 1st image is Muller (Lefty) Home team (Bottom). 2nd image is Bellows (Righty) Home team (Bottom). 3rd image is Gretzky (Lefty) Away Team (Top) 4th image is Carson (Righty) Away Team (Top) Your saying the stance is wrong? When your a lefty like muller in image 1, it should actually be the 2nd image? where your left hand is on the lower portion of the stick. You can't find the code that controls this? Edited January 3 by McMarkis Quote
AdamCatalyst Posted January 3 Author Report Posted January 3 (edited) YES. Exactly. I mean, I can find the code to swap it back and forth, or ignore handedness, etc. but I can't figure out how to *only* flip the bottom player in the face-offset. I keep thinking that I could branch out and check the bottom team flag, but that's a bit beyond me. But perhaps there is a simpler solution I am not thinking of, such as… I dunno, swapping the second bit in the array? LOL. Is that a thing? Is that just nonsense? I am clearly NOT a programmer. Edited January 3 by AdamCatalyst Quote
AdamCatalyst Posted January 4 Author Report Posted January 4 OK, this seems to work in '92. Please let me know if I'm committing any errors, omission, or sins against programming. Code redirect 1. Original Logic to Set Handedness for Face-Off Graphics 0x63CC 4A2B 0074 6600 0004 5640 Revised 4EF9 0007 FEDC 4E71 4E71 Code 2. Test if BOTTOM 082B 0007 0062 3. IF BOTTOM jump ahead to #7 6700 000E 4. Test HAND = RIGHT 4A2B 0074 5. If NOT RIGHT (T), jump ahead to #9 6600 000E 6. ELSE go to #10 6000 000C 7. Test HAND = RIGHT 4A2B 0074 8. If LEFT (B), jump to #10 6600 0004 9. Add 3, d0 5640 10. Go Back to continue where we left off 4EF9 0000 63D6 Quote
McMarkis Posted January 4 Report Posted January 4 (edited) I believe @chaos dreams in m68k assembly now, so I would defer to him about assembly sins 😁. Below are a few of my thoughts. I converted you HEX values to assembly code, and made the smallest of changes for the branching. I personally like JSR.L so i can just do RTS commands to return back to the original code. I haven't tested this, but your pattern seems good. Hack-jack existing code Jump to new code and NOP extra instructions Perform New code and return on exit. ;Hijack Old code and call to new code JSR.L $0007FEDC ; Call new subroutine (long) NOP ; No operation NOP ; No operation ;Start of Your new subroutine @7FEDC BTST.B #7,$0062(A3) ; Test bit 7 (bottom) BEQ.S .bottom ; If bottom, branch (short) TST.B $0074(A3) ; Test if hand = RIGHT BEQ.S .exit ; If RIGHT, exit (short) BRA.S .add3 ; Not RIGHT, do add3 (short) .bottom: TST.B $0074(A3) ; Test if hand = RIGHT BNE.S .exit ; If LEFT, exit (short) .add3: ADDQ.W #3,D0 ; Add 3 to D0 .exit: RTS ; Return from subroutine AI Suggestions: My gut was telling me that you can probably simplify the multiple BTST & TST scenarios with some combo statement. So I asked Claude AI to help, and it suggested the following. Break down the problem into a matrix like (Truth) table to help understand the possible combinations. You want to add 3 when the player is Left handed and top position? You want to add 3 when the player is Right handed and bottom position? Position(bit7) Hand EOR Result BTST #7 Add 3? TOP(0) RIGHT(0) 0 0 No TOP(0) LEFT(1) 1 1 Yes <-- Add 3 BOTTOM(1) RIGHT(0) 1 1 Yes <-- Add 3 BOTTOM(1) LEFT(1) 0 0 No Something like this now possibly, I haven't tested this code. JSR.L $0007FEDC ; Call subroutine (long) NOP ; Padding/placeholder NOP ; Padding/placeholder ;Start of Your new subroutine @7FEDC MOVE.W D1,-(SP) ; Save original D1 value since we are overwriting it MOVE.B $0074(A3),D1 ; Get hand orientation EOR.B $0062(A3),D1 ; XOR with position BTST #7,D1 ; Test result BNE.S .add3 ; If NOT equal, add3 BRA.S .exit ; Otherwise exit .add3: ADDQ.W #3,D0 ; Add 3 to D0 .exit: MOVE.W (SP)+,D1 ; Restore D1 RTS I know this is a bit of a brain dump—I went full over-explainer mode here. If anything’s unclear, just holler, and I’ll happily clarify. Honestly, though, I’m being a bit selfish because it’d be amazing to rope in another brave soul into the wonderful, weird world of assembly. Welcome to the dark side—we have opcodes! Edited January 4 by McMarkis 1 1 Quote
AdamCatalyst Posted January 4 Author Report Posted January 4 Oh wow, yes, will need some time to digest. And I seriously have to remember that AI exists. One side note, I originally tried a JSR command, but it caused visual flickering, for reasons that I wasn't table to discern. My brain is exhausted for the day, will definitely look this over at breakfast tomorrow! Quote
chaos Posted January 4 Report Posted January 4 1 hour ago, McMarkis said: I believe @chaos dreams in m68k assembly now, so I would defer to him about assembly sins 😁. Below are a few of my thoughts. I converted you HEX values to assembly code, and made the smallest of changes for the branching. I personally like JSR.L so i can just do RTS commands to return back to the original code. I haven't tested this, but your pattern seems good. Hack-jack existing code Jump to new code and NOP extra instructions Perform New code and return on exit. ;Hijack Old code and call to new code JSR.L $0007FEDC ; Call new subroutine (long) NOP ; No operation NOP ; No operation ;Start of Your new subroutine @7FEDC BTST.B #7,$0062(A3) ; Test bit 7 (bottom) BEQ.S .bottom ; If bottom, branch (short) TST.B $0074(A3) ; Test if hand = RIGHT BEQ.S .exit ; If RIGHT, exit (short) BRA.S .add3 ; Not RIGHT, do add3 (short) .bottom: TST.B $0074(A3) ; Test if hand = RIGHT BNE.S .exit ; If LEFT, exit (short) .add3: ADDQ.W #3,D0 ; Add 3 to D0 .exit: RTS ; Return from subroutine AI Suggestions: My gut was telling me that you can probably simplify the multiple BTST & TST scenarios with some combo statement. So I asked Claude AI to help, and it suggested the following. Break down the problem into a matrix like (Truth) table to help understand the possible combinations. You want to add 3 when the player is Left handed and top position? You want to add 3 when the player is Right handed and bottom position? Position(bit7) Hand EOR Result BTST #7 Add 3? TOP(0) RIGHT(0) 0 0 No TOP(0) LEFT(1) 1 1 Yes <-- Add 3 BOTTOM(1) RIGHT(0) 1 1 Yes <-- Add 3 BOTTOM(1) LEFT(1) 0 0 No Something like this now possibly, I haven't tested this code. JSR.L $0007FEDC ; Call subroutine (long) NOP ; Padding/placeholder NOP ; Padding/placeholder ;Start of Your new subroutine @7FEDC MOVE.W D1,-(SP) ; Save original D1 value since we are overwriting it MOVE.B $0074(A3),D1 ; Get hand orientation EOR.B $0062(A3),D1 ; XOR with position BTST #7,D1 ; Test result BNE.S .add3 ; If NOT equal, add3 BRA.S .exit ; Otherwise exit .add3: ADDQ.W #3,D0 ; Add 3 to D0 .exit: MOVE.W (SP)+,D1 ; Restore D1 RTS I know this is a bit of a brain dump—I went full over-explainer mode here. If anything’s unclear, just holler, and I’ll happily clarify. Honestly, though, I’m being a bit selfish because it’d be amazing to rope in another brave soul into the wonderful, weird world of assembly. Welcome to the dark side—we have opcodes! The hand byte is $0076 in 94 FYI. ($74 is Fight) Not sure if this would work. The hand orientation is just one bit, and the flag for which net they are shooting on is bit 7 of 62. So when you EOR, it would be comparing bit 0 of 62 offset, which is the deceleration bit. You would have to do an LSL.B #7, D1 before the EOR to line up the bits. I feel like there could be an easier way to do this, but this should work, and who cares, we aren't crammed for space. CB8C is the ROM location in 94 for the code where you want to inject (tst.b($76(a3)) 1 Quote
AdamCatalyst Posted January 5 Author Report Posted January 5 My inefficient method seems to work fine in '92 & '94 (I did note the difference in the hand byte, etc), but going to experiment with all this stuff while I watch the Leafs game tonight. Thanks guys! Quote
AdamCatalyst Posted January 5 Author Report Posted January 5 (edited) @McMarkis I tried your revised code, and for some reason it didn't work. It's ENTIRELY possible that I am misunderstanding or implementing it wrong. To that end, a few questions. Here is my current working patch in '94: 082B 0007 0062 6700 000E 4A2B 0076 6600 000E 6000 000C 4A2B 0076 6600 0004 5640 4EF9 0000 CB96 I adapted your instructions to this: 082B 0007 0062 6712 4A2B 0076 670C 6008 4A2B 0076 6604 5640 4EF9 0000 CB96 For whatever reason, whenever I change to use the JSR.L, I get flickering graphics for the left player in the face-off inset. Odd. Hence the change at the end. As for the rest, I had a few questions… 1. Why 6712 @ 0x06? Wouldn't that make the bottom face-off always use the same graphic, regardless of hand? 2. Why 670C @ 0x0C? My original logic was to use 66, but this reverses the logic of the branch, and jumps two bytes ahead? 3. Why 6604 @ 0x0E? My original logic jumped to the end, but this instead jumps to add #3 to d0 first, or am I misunderstanding something? Or lots of things… I tried a few variants, and couldn't get the desired behaviour. Not sure what I'm missing. As for the AI generated code, I couldn't get it to work, and it might be too far over my head to even ask questions about. I've never used Claude.AI before. I assume it is what you would recommend for this? In any case, my bloated code seems to work fine, but I am definitely curious to learn how to write this optimally! Edited January 5 by AdamCatalyst Quote
chaos Posted January 5 Report Posted January 5 2 hours ago, AdamCatalyst said: @McMarkis I tried your revised code, and for some reason it didn't work. It's ENTIRELY possible that I am misunderstanding or implementing it wrong. To that end, a few questions. Here is my current working patch in '94: 082B 0007 0062 6700 000E 4A2B 0076 6600 000E 6000 000C 4A2B 0076 6600 0004 5640 4EF9 0000 CB96 I adapted your instructions to this: 082B 0007 0062 6712 4A2B 0076 670C 6008 4A2B 0076 6604 5640 4EF9 0000 CB96 For whatever reason, whenever I change to use the JSR.L, I get flickering graphics for the left player in the face-off inset. Odd. Hence the change at the end. As for the rest, I had a few questions… 1. Why 6712 @ 0x06? Wouldn't that make the bottom face-off always use the same graphic, regardless of hand? 2. Why 670C @ 0x0C? My original logic was to use 66, but this reverses the logic of the branch, and jumps two bytes ahead? 3. Why 6604 @ 0x0E? My original logic jumped to the end, but this instead jumps to add #3 to d0 first, or am I misunderstanding something? Or lots of things… I tried a few variants, and couldn't get the desired behaviour. Not sure what I'm missing. As for the AI generated code, I couldn't get it to work, and it might be too far over my head to even ask questions about. I've never used Claude.AI before. I assume it is what you would recommend for this? In any case, my bloated code seems to work fine, but I am definitely curious to learn how to write this optimally! Keep your code if it works fine. Did you add the change I made? The code McMarkis posted won't work because it's not Exclusive ORing the right bits. Needs that LSL.B #7, D1 part 1 Quote
AdamCatalyst Posted January 5 Author Report Posted January 5 Here is what I tried for the AI suggested code. It affects the face-off animation, but not in a desirable way. I suspect that I did this wrong. MOVE.W D1,-(SP) ; 48E7 0200 ; Save D1 MOVE.B $0076(A3),D1 ; 122B 0076 ; Load from offset 0x76 LSL.B #7,D1 ; EF09 ; Shift left 7 bits EOR.B $0062(A3),D1 ; B32B 0062 ; XOR with position BTST #7,D1 ; 0801 0007 ; Test bit 7 BNE.S .add3 ; 6600 0006 ; Branch if not zero BRA.S .exit ; 6000 0004 ; Branch to exit .add3: ADDQ.W #3,D0 ; 5240 ; Add 3 to D0 .exit: MOVE.W (SP)+,D1 ; 4CDF 0400 ; Restore D1 JMP $0000CB96 ; 4EF9 0000 CB96 ; Jump to absolute address Quote
McMarkis Posted January 5 Report Posted January 5 I agree with Chaos, If your code is working keep that. The AI generated code is overkill and was just there as a reference as a possible way to reduce the number of TST instructions. But it can often be wrong and needs to be iterated through to get the correct answer. 1 Quote
AdamCatalyst Posted January 5 Author Report Posted January 5 Thanks guys! Always learning from you both. Quote
chaos Posted January 5 Report Posted January 5 I just checked the AI suggested code with the LSL, it should work as intended. It's possible an opcode is messed up. Just stick with your code Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.