Language…
14 users online:  AmperSam, BabaYegha, codfish1002, deported, h.carrell, Heitor Porfirio,  idol, MegaSonic1999, NewPointless, playagmes169, saucebrune, Sweetdude, TheKazooBloccGosh, TheXander - Guests: 293 - Bots: 394
Users: 64,795 (2,374 active)
Latest user: mathew

[SOLVED] Don't drop item if gliding - Help with a patch

This patch disables Item Box dropping if the player is gliding with a cape. Here is the fixed code incase someone else is interested:

Now it is optimized.

Code
header
lorom

org $00C56C
	autoclean JML MyCode
	NOP #2
	
freecode	

MyCode:
	LDA $16
	AND #$20				;Check if Player is pressing Select
	BEQ NotPressingSelect
	LDA $1407				;Is a cape, then check if player is gliding
	BEQ NotGliding
	CMP #$04				
	BCS NotGliding
NotPressingSelect:
	JML $00C58F		
NotGliding:	
	JML $00C572


Originally posted by Old post
I am trying to make a patch that disables Item Box dropping if the player is gliding with a cape.

So I checked SMWDISC and found some stuff related:

Code
;CODE_00C56C:        A5 16         LDA $16                   
;CODE_00C56E:        29 20         AND.B #$20        		;Check if Player is pressing SELECT        
;CODE_00C570:        F0 1D         BEQ CODE_00C58F           
;CODE_00C572:        A5 15         LDA RAM_ControllerA     		(7E0015)  
;CODE_00C574:        29 08         AND.B #$08                
;CODE_00C576:        80 0D         BRA CODE_00C585           ; Change to BEQ to reach debug routine below 

;CODE_00C578: 	(Debug: Cycle through powerups Routine, skip)...

;CODE_00C585:        8B            PHB                       
;CODE_00C586:        A9 02         LDA.B #$02                
;CODE_00C588:        48            PHA                       
;CODE_00C589:        AB            PLB                       
;CODE_00C58A:        22 08 80 02   JSL.L CODE_028008      	 ; ItemBoxRoutine
;CODE_00C58E:        AB            PLB                       
;CODE_00C58F:        9C 02 14      STZ.W $1402               
;Return00C592:       60            RTS                       ; Return 


Alright, then I tried making a patch that checks if Select is being pressed, then if the player is using cape powerup, then if the player is gliding:

Code
header
lorom

org $00C56C
	autoclean JML MyCode
	
freecode	

MyCode:
	LDA $16
	AND #$20					;Check if Player is pressing Select
	BEQ NotPressingSelect
	LDA #$19					;Is pressing select, then proceed to check powerup.
	CMP #$02					;Check if Player is using Cape powerup
	BNE	NotACape				;If not a cape, then proceed to run default item box code
	LDA $13E0					;Is a cape, then check if glidding animation is running
	CMP #$2A	;Glidding frame #01				
	BEQ	Return
	CMP #$2B	;Glidding frame #02
	BEQ	Return
	CMP #$2C	;Glidding frame #03
	BEQ	Return
	CMP #$2D	;Glidding frame #04
	BEQ	Return
	CMP #$2E	;Glidding frame #05
	BEQ	Return
	CMP #$2F	;Glidding frame #06
	BEQ	Return
NotACape:	
	JML $00C572
NotPressingSelect:
	JML $00C58F	
Return:
	RTL


Well, absolutely nothing happens. It is still possible to drop items from ItemBox even if player is Gliding.

Am I missing some check? Or are my hijacks completely wrong? Any help is appreciated.

Thank you.
You are doing LDA #$19, not LDA $19, so the powerup check will always be false. Also, you can't RTL from that routine since you didn't jump into it with a JSL, you'll have to replace that RTL with a JML.
Oh, I should have double checked my code, it was so simple #smw{-_-2} So, I replaced RTL with a JML that jumps to the "not pressing select" code and now it works flawlesssly.

Here is the fixed code:

Code
header
lorom

org $00C56C
	autoclean JML MyCode
	NOP #2
	
freecode	

MyCode:
	LDA $16
	AND #$20					;Check if Player is pressing Select
	BEQ NotPressingSelect
	LDA $19						;Is pressing select, then proceed to check powerup.
	CMP #$02					;Check if Player is using Cape powerup
	BNE NotACape					;If not a cape, then proceed to run default item box code
	LDA $13E0					;Is a cape, then check if glidding animation is running
	CMP #$2A					;Glidding frame #01			
	BEQ Return
	CMP #$2B					;Glidding frame #02
	BEQ Return
	CMP #$2C					;Glidding frame #03
	BEQ Return
	CMP #$2D					;Glidding frame #04
	BEQ Return
	CMP #$2E					;Glidding frame #05
	BEQ Return
	CMP #$2F					;Glidding frame #06
	BEQ Return
NotACape:	
	JML $00C572
Return:
NotPressingSelect:
	JML $00C58F	


Thank you very much randomdude999 #smw{:TUP:}
By the way, you might want to optimise the gliding frame code a bit. Since you're checking a range, you might want to use a ranged check. That is, you subtract A from the smallest value you want to compare with (here 0x2A) and compare it with the largest value plus minus the smallest value (i.e. 0x2F + 0x01 = 0x30 and 0x30 - 0x2A = 0x06). If the carry flag is clear than the value is in range.

Furthermore, if I was you I wouldn't check through the poses but rather per the cape flying state $1407. Checking through the poses is rather complicated and has got its own limits so try to avoid that.
Okay, I was able to optimize the code even more:

Code
header
lorom

org $00C56C
	autoclean JML MyCode
	NOP #2
	
freecode	

MyCode:
	LDA $16
	AND #$20				;Check if Player is pressing Select
	BEQ NotPressingSelect
	LDA $1407				;Is a cape, then check if player is gliding
	CMP #$04				
	BCS NotGliding
	CMP #$00
	BEQ NotGliding
NotPressingSelect:
	JML $00C58F		
NotGliding:	
	JML $00C572


With cape flying state, I don't even have to check if player is using cape powerup :P

Not sure if it is coded correctly, but it is working well it seems.
Thanks for the tip MFG!


There's another optimization:

Code
header
lorom

org $00C56C
	autoclean JML MyCode
	NOP #2
	
freecode	

MyCode:
	LDA $16
	AND #$20				;Check if Player is pressing Select
	BEQ NotPressingSelect
	LDA $1407				;Is a cape, then check if player is gliding
	BEQ NotGliding
	CMP #$04				
	BCS NotGliding
NotPressingSelect:
	JML $00C58F		
NotGliding:	
	JML $00C572






Dream team (feed them, please):






Oh cool, so if I call BEQ without a CMP, then it already compares with zero.

Nice way to save 2 more bytes :P


Originally posted by Yan
Oh cool, so if I call BEQ without a CMP, then it already compares with zero.

Nice way to save 2 more bytes :P

Yes.

For your future reference: all branch commands, sans BRA and BRL, just check the status of the processor flags. As you'll probably know, SNES has these processor flags in native mode: negative, overflow, accumulator and memory width, x and y width, decimal, interrupt, carry and zero (the famous nvmxdizc flags). Now, some of them are tested by branches:

Negative (n): BPL and BMI;
Overflow (v): BVC and BVS;
Carry (c): BCC and BCS;
Zero (z): BEQ and BNE.

See? BEQ and BNE just check the zero flag. CMP happens to set negative, overflow, carry and zero flags depending on its result. But why you can omit CMP ifyou compare with #$00 in this case? LDA too alters the processor flags: the n and z ones. So:

Code
	LDX #$00
	LDY #$00
	LDA #$00
	BEQ .Zero
	LDX #$01
.Zero
	LDA #$7D
	BMI .Negative
	LDY #$01
.Negative
	RTS


If you analyze closely the code above, you'll see that, at the end of its execution, X will contain #$00 and Y will contain #$01.





Dream team (feed them, please):