;Enhanced Low Gravity/Floaty Luigi Physics, by Blind Devil (revision 2018-10-16) ;This file applies a change to the player jumping physics, and alters its pose ;accordingly if set to do so. The configuration can be applied to all player ;characters, to a specific character or can be RAM flag dependent. You also ;have the option to use flutter animation or not. ;You should place this in the library folder, and call it from your level or game ;mode 14 (main) code like this: ;LDA #%xxxxxxxx ;these are the option bits ;JSL Floaty_runcode ;format: filename_labelname ;Option bit usage: ;----RFLM ;M = enable floaty physics for player 1. ;L = enable floaty physics for player 2. ;F = use flutter animation. ;R = make floaty physics flag-dependent (overrides bits 0 and 1 options). ;---- = unused. ;Values for each bit can be either 0 or 1. If M, L, or R are zero, this code ;is useless. ;Example: If you want to enable floaty physics for player 2 only, and use ;fluttering animation, you use this before the JSL: ;LDA #%00000110 ;Configurable define: ;FREE RAM FLAG ;What address to use as a flag to enable/disable floaty physics. ;If the bit option is not used, this RAM is untouched. !FloatyFlag = $0DDD|!addr ;Code starts below. runcode: STA $00 ;store value in A to scratch RAM. AND #$08 ;preserve bit 3 BEQ .UseNoFlag ;if bit is not set, don't use flag. LDA !FloatyFlag ;load RAM flag BNE .ProcessFloaty ;if not equal zero, process physics. .NoProc RTL ;just return and process nothing. .UseNoFlag LDA $00 ;load user-defined bits from scratch RAM AND #$03 ;preserve bits 0 and 1 CMP #$03 ;compare to value BEQ .ProcessFloaty ;if equal, process physics for both players. CMP #$02 ;compare again BNE + ;if not equal, skip ahead. LDA $0DB3|!addr ;load character in play BNE .ProcessFloaty ;if not player 1, process physics. RTL ;else, just return and process nothing. + CMP #$01 ;compare again BNE .NoProc ;if not equal, return. LDA $0DB3|!addr ;load character in play BNE .NoProc ;if not player 1, don't process physics. .ProcessFloaty LDA $75 ;load player is in water flag ORA $1407|!addr ;OR with cape flying phase ORA $1B89|!addr ;OR with message box timer/size ORA $1471|!addr ;OR with what kind of platform/sprite player is standing on ORA $18BD|!addr ;OR with stun player timer BNE .NoProc ;if result is not zero, don't use low gravity. LDA $72 ;load player is in the air flag BEQ .NoFlutter ;if not in the air, don't change pose. LDA $00 ;load user-defined bits from scratch RAM AND #$04 ;preserve bit 2 BEQ .NoFlutter ;if bit is not set, don't change pose. LDA $73 ;load player ducking flag ORA $74 ;OR with player climbing flag ORA $71 ;OR with current player animation settings ORA $140D|!addr ;OR with spin jump flag ORA $149C|!addr ;OR with shooting fireball timer ORA $14A6|!addr ;OR with cape spin timer ORA $187A|!addr ;OR with riding Yoshi flag BNE .NoFlutter ;if result is not zero, don't change pose. LDA $148F|!addr ;load player is carrying an item flag BNE .carrying ;if yes, branch to use carrying flutter pose. LDA $14 ;load effective frame counter LSR ;divide by 2 AND #$01 ;check if bit is set BNE .flutter2 ;if set, branch. LDA #$00 ;load pose value BRA .storepose ;branch to store pose. .flutter2 LDA #$02 ;load pose value BRA .storepose ;branch to store pose. .carrying LDA $14 ;load effective frame counter LSR ;divide by 2 AND #$01 ;check if bit is set BNE .flutter4 ;if set, branch. LDA #$07 ;load pose value BRA .storepose ;branch to store pose. .flutter4 LDA #$09 ;load pose value .storepose STA $13E0|!addr ;store A value to display pose. .NoFlutter LDA $13D4|!addr ;load game paused flag ORA $9D ;OR with sprites/animation flag locked BNE ++ ;if both aren't zero, return. LDA $77 ;load player blocked status AND #$1C ;preserve bits 2, 3 and 4 (within a block, touching ceiling and touching ground) BNE ++ ;if any bits are set, return. LDA $7D ;load player's Y speed CMP #$80 ;compare to value (highest upwards) BEQ ++ ;if equal, don't decrement - prevent overflow DEC $7D ;decrement player's Y speed by one every frame ++ RTL ;return.