;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; sprite data ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; init JSL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dcb "INIT" LDA #Health ; Store health. STA $1528,x RTL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; main sprite JSL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dcb "MAIN" PHB ; \ PHK ; | main sprite function, just calls local subroutine PLB ; | JSR START_HB_CODE ; | JSR MostrarTiles JSR CheckIfSpriteDie PLB ; | RTL ; / ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Tables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; A = $0A : B = $0B : C = $0C : D = $0D : E = $0E : F = $0F : G = $10 : H = $11 : I = $12 : J = $13 : K = $14 L = $15 : M = $16 : N = $17 : O = $18 : P = $19 : Q = $1A : R = $1B : S = $1C : T = $1D : U = $1E : V = $1F W = $20 : X = $21 : Y = $22 : Z = $23 NameTable: db S,P,I,N,Y NameSize = $04 ;O tamanho do nome do seu chefe menos - Ex: nome LOL, tem 3 letras, entao 3-2=2, entao coloco 2 aqui Position = $0EF9 ;Posição que vai desenhar os tiles, melhor nao mecher ShowTiles = $01 ;Mostrar o nome do boss na status bar? Health = $01 ;Vai de 1-100 (1-63) CustomSprite = $01 ;O numero do custom sprite inserido para ser gerado (goal Sphere) SoundEffect = $08 ;Coloque aqui o valor que corresponde ao efeito sonoro desejado quando o sprite morrer. FaceMario = $01 XSPEED: dcb $F5,$0C ;;;;;;;;;;;;Dir;Esq;;;;;;;;;;;; ;Dir = Direita ; ;Esq = Esquerda ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;JSRs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MostrarTiles: LDA #ShowTiles ; .. If it's set to show tiles. BEQ NoDont PHX JSR DrawTilemaps ; Draw the tilemaps. PLX LDA $1528,x PHX JSR HexDec STX Position+NameSize+2 STA Position+NameSize+3 NoDont PLX RTS HexDec: LDX #$00 HexLoop: CMP #$0A ; While (A == $0A) { BCC NoConvo ; } SBC #$0A ; Else { DrawLine.(A - 10); Fail C++ ftw. INX ; (X + 1) } BRA HexLoop ; Cout << ("C++ Fail ftw"); NoConvo: ; Oh wait where's the cin command? RTS DrawTilemaps: LDX #NameSize DrawLoop: LDA NameTable,x ; Load the tile data indexed by the size. STA Position,x ; .. and store to appriopriate tile. STA Position,x ; .. and store to appriopriate tile. DEX BPL DrawLoop ; So far, it draws "AAAA" LDA #$26 STA Position+NameSize+1 ; Now, "AAAAx" RTS CheckIfSpriteDie LDA $1528,x BNE RETURN STZ Position+NameSize+3 LDA #$FC STA Position+NameSize+2 JMP DIE Die: PHX LDA #SoundEffect STA $1DF9 LDA #$04 STA $14C8,x ; Disappear in a puff of smoke. JSL $03A6C8 PLX JMP DoExit DoExit PHX TYX LDA #$01 STA $14C8,x LDA #CustomSprite STA $7FAB9E,x JSL $07F7D2 JSL $0187A7 LDA #$08 STA $7FAB10,x TXY PLX LDA $E4,x STA $00E4,y LDA $14E0,x STA $14E0,y LDA $D8,x STA $00D8,y LDA $14D4,x STA $14D4,y RETURN: RTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; main sprite routine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RETURN RTS START_HB_CODE JSR SUB_GFX LDA $14C8,x CMP #$08 BNE RETURN LDA $9D BNE RETURN JSR SUB_OFF_SCREEN_X0 ; only process sprite while on screen JSL $018032 JSR XMOVING JSL $01A7DC BCC NoContact NoContact: RTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; graphics routine ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TILEMAP dcb $82,$80 dcb $A2,$A0 dcb $86,$84 dcb $A6,$A4 X_OFFSET dcb $08,$F8,$08,$F8 dcb $F8,$08,$F8,$08 Y_OFFSET dcb $F0,$F0,$00,$00 dcb $F0,$F0,$00,$00 SUB_GFX JSR GET_DRAW_INFO ; sets y = OAM offset LDA $157C,x STA $02 LDA $157C,x ; \ $02 = direction ASL A ASL A STA $02 ; / LDA $14 LSR A LSR A LSR A AND #$01 ASL A ASL A STA $03 PHX LDX #$03 LOOP_START PHX TXA CLC ADC $02 TAX LDA X_OFFSET,x CLC ADC $00 ; \ tile x position = sprite y location ($01) STA $0300,y ; / PLX LDA Y_OFFSET,x CLC ADC $01 ; \ tile y position = sprite x location ($00) STA $0301,y ; / PHX TXA CLC ADC $03 TAX LDA TILEMAP,x STA $0302,y PLX PHX LDX $02 LDA PROPERTIES,x PLX ORA $64 STA $0303,y INY ; \ increase index to sprite tile map ($300)... INY ; | ...we wrote 1 16x16 tile... INY ; | ...sprite OAM is 8x8... INY ; / ...so increment 4 times DEX BPL LOOP_START PLX LDY #$02 ; \ 460 = 2 (all 16x16 tiles) LDA #$03 ; | A = (number of tiles drawn - 1) JSL $01B7B3 ; / don't draw if offscreen RTS ; return PROPERTIES: dcb $09,$69 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $B760 - graphics routine helper - shared ; sets off screen flags and sets index to OAM ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;org $03B75C TABLE1 dcb $0C,$1C TABLE2 dcb $01,$02 GET_DRAW_INFO STZ $186C,x ; reset sprite offscreen flag, vertical STZ $15A0,x ; reset sprite offscreen flag, horizontal LDA $E4,x ; \ CMP $1A ; | set horizontal offscreen if necessary LDA $14E0,x ; | SBC $1B ; | BEQ ON_SCREEN_X ; | INC $15A0,x ; / ON_SCREEN_X LDA $14E0,x ; \ XBA ; | LDA $E4,x ; | REP #$20 ; | SEC ; | SBC $1A ; | mark sprite invalid if far enough off screen CLC ; | ADC.W #$0040 ; | CMP.W #$0180 ; | SEP #$20 ; | ROL A ; | AND #$01 ; | STA $15C4,x ; / BNE INVALID ; LDY #$00 ; \ set up loop: LDA $1662,x ; | AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice BEQ ON_SCREEN_LOOP ; | else, go through loop once INY ; / ON_SCREEN_LOOP LDA $D8,x ; \ CLC ; | set vertical offscreen if necessary ADC TABLE1,y ; | PHP ; | CMP $1C ; | (vert screen boundry) ROL $00 ; | PLP ; | LDA $14D4,x ; | ADC #$00 ; | LSR $00 ; | SBC $1D ; | BEQ ON_SCREEN_Y ; | LDA $186C,x ; | (vert offscreen) ORA TABLE2,y ; | STA $186C,x ; | ON_SCREEN_Y DEY ; | BPL ON_SCREEN_LOOP ; / LDY $15EA,x ; get offset to sprite OAM LDA $E4,x ; \ SEC ; | SBC $1A ; | $00 = sprite x position relative to screen boarder STA $00 ; / LDA $D8,x ; \ SEC ; | SBC $1C ; | $01 = sprite y position relative to screen boarder STA $01 ; / RTS ; return INVALID PLA ; \ return from *main gfx routine* subroutine... PLA ; | ...(not just this subroutine) RTS ; / ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; off screen processing code - shared ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;org $03B83B TABLE3 dcb $40,$B0 TABLE6 dcb $01,$FF TABLE4 dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0 TABLE5 dcb $01,$FF,$01,$FF,$01,$00,$01,$FF SUB_OFF_SCREEN_X0 LDA #$06 ; \ entry point of routine determines value of $03 BRA STORE_03 ; | SUB_OFF_SCREEN_X1 LDA #$04 ; | BRA STORE_03 ; | SUB_OFF_SCREEN_X2 LDA #$02 ; | STORE_03 STA $03 ; | BRA START_SUB ; | SUB_OFF_SCREEN_X3 STZ $03 ; / START_SUB JSR SUB_IS_OFF_SCREEN ; \ if sprite is not off screen, return BEQ RETURN_2 ; / LDA $5B ; \ goto VERTICAL_LEVEL if vertical level AND #$01 ; | BNE VERTICAL_LEVEL ; / LDA $D8,x ; \ CLC ; | ADC #$50 ; | if the sprite has gone off the bottom of the level... LDA $14D4,x ; | (if adding 0x50 to the sprite y position would make the high byte >= 2) ADC #$00 ; | CMP #$02 ; | BPL ERASE_SPRITE ; / ...erase the sprite LDA $167A,x ; \ if "process offscreen" flag is set, return AND #$04 ; | BNE RETURN_2 ; / LDA $13 ; \ AND #$01 ; | ORA $03 ; | STA $01 ; | TAY ; / LDA $1A CLC ADC TABLE4,y ROL $00 CMP $E4,x PHP LDA $1B LSR $00 ADC TABLE5,y PLP SBC $14E0,x STA $00 LSR $01 BCC LABEL20 EOR #$80 STA $00 LABEL20 LDA $00 BPL RETURN_2 ERASE_SPRITE LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite CMP #$08 ; | BCC KILL_SPRITE ; / LDY $161A,x CPY #$FF BEQ KILL_SPRITE LDA #$00 STA $1938,y KILL_SPRITE STZ $14C8,x ; erase sprite RETURN_2 RTS ; return VERTICAL_LEVEL LDA $167A,x ; \ if "process offscreen" flag is set, return AND #$04 ; | BNE RETURN_2 ; / LDA $13 ; \ only handle every other frame?? LSR A ; | BCS RETURN_2 ; / AND #$01 STA $01 TAY LDA $1C CLC ADC TABLE3,y ROL $00 CMP $D8,x PHP LDA.W $001D LSR $00 ADC TABLE6,y PLP SBC $14D4,x STA $00 LDY $01 BEQ LABEL22 EOR #$80 STA $00 LABEL22 LDA $00 BPL RETURN_2 BMI ERASE_SPRITE SUB_IS_OFF_SCREEN LDA $15A0,x ; \ if sprite is on screen, accumulator = 0 ORA $186C,x ; | RTS ; / return XMOVING LDA $1588,x AND #$04 BEQ NotOnGround LDY $157C,x ; Load the direction in Y. LDA XSPEED,y ; Speed based on direction. STA $B6,x ; Store to sprite's X speed. LDA #$10 STA $AA,x NotOnGround: JSL $01802A LDA $1588,x AND #$03 BEQ NotTouchingWall LDA $157C,x EOR #$01 STA $157C,x NotTouchingWall RTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $B817 - horizontal mario/sprite check - shared ; Y = 1 if mario left of sprite?? ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;org $03B817 SUB_HORZ_POS: LDY #$00 ;A:25D0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1020 VC:097 00 FL:31642 LDA $94 ;A:25D0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZCHC:1036 VC:097 00 FL:31642 SEC ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1060 VC:097 00 FL:31642 SBC $E4,x ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1074 VC:097 00 FL:31642 STA $0F ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1104 VC:097 00 FL:31642 LDA $95 ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1128 VC:097 00 FL:31642 SBC $14E0,x ;A:2500 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZcHC:1152 VC:097 00 FL:31642 BPL LABEL16 ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1184 VC:097 00 FL:31642 INY ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1200 VC:097 00 FL:31642 LABEL16: RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642