lx5 Moderador Global
Posts : 2169
| Tema: [Tutorial] Como hacer Custom Blocks Mar Abr 02, 2013 2:27 pm | |
| Hola gente de FR, este dia les enseñare a crear sus propios custom blocks para el Super Mario World. Ojala comprendan el tutorial y puedan hacer custom blocks geniales. Antes de comenzar el tutorial, necesitan las siguientes cosas: - Un archivo de texto - El Block Tool Super Deluxe - Un ROM de Super Mario World - Conocimientos basicos de ASM - Paciencia, mucha paciencia Leccion 1 - Primeros pasos para hacer el custom blockPara comenzar tu custom block debes renombrar tu archivo de texto a BloqueCustom.asm, despues abre el archivo .asm con el bloc de notas y pega lo siguiente lo siguiente: db $42
JMP MarioBelow : JMP MarioAbove : JMP MarioSide JMP SpriteV : JMP SpriteH JMP MarioCape : JMP MarioFireBall JMP MarioCorner : JMP MarioBodyInside : JMP MarioHeadInside
MarioBelow: MarioAbove: MarioSide:
SpriteV: SpriteH:
MarioCape: MarioFireBall:
MarioCorner: MarioBodyInside: MarioHeadInside: RTLEsto es la base que ocuparas para hacer tus custom blocks, de seguro no tienes idea de que significa cada cosa, asi que te lo explicare: db $42Este codigo es para señalar los nuevos offsets del BTSD, estos son: MarioCorner, MarioBodyInside y MarioHeadInside, no es necesario del todo en un bloque, pero hay que tenerlo si quieres compartirlo. Ademas, a veces puede haber algunos pequeños problemas si no tiene el db $42 al principio. JMPsLos JMPs que estan al principio es para dar un brinco al label señalado, el orden de los labels es como esta ahi arriba: MarioBelow, MarioAbove, MarioSide, SpriteV, SpriteH, MarioCape, MarioFireBall, MarioCorner, MarioBodyInside, MarioHeadInside. Nota:A los labels anteriormente mencionados puedes renombrarlos como quieras, aqui un ejemplo: JMP Mario : JMP Mario : JMP Mario : JMP Sprite : JMP Sprite : JMP Cape : JMP Fire JMP Mario : JMP Mario : JMP Mario
Mario: Sprite: Cape: Fire: RTLPuedes ponerle cualquier nombre que quieras a las labels, con tal que sepas y recuerdes para que es cada una. LabelsLas labels es el texto que esta enseguida de algun JMP, por ejemplo, MarioBelow, ese es un label, son vitales para hacer un custom block, no las olvides!. Nota: Despues de los JMPs, las labels pueden estar acomodadas de cualquier manera, por ejemplo db $42
JMP MarioBelow : JMP MarioAbove : JMP MarioSide JMP SpriteV : JMP SpriteH JMP MarioCape : JMP MarioFireBall JMP MarioCorner : JMP MarioBodyInside : JMP MarioHeadInside
MarioBelow: MarioAbove: MarioSide: MarioCorner: MarioBodyInside: MarioHeadInside:
MarioCape: MarioFireBall: SpriteV: SpriteH: RTLRTLEsto indica el fin del codigo, cuando el codigo llega a este punto deja de interactuar con Mario o Sprites. Leccion 2 - Añadiendo mas codigoAhora vamos a codear el custom block, para empezar, necesitamos ir a la [Tienes que estar registrado y conectado para ver este vínculo] y buscar alguna direccion RAM para nuestro bloque, para este tutorial tomare la direccion $7E:0DBF que es la que controla las monedas del jugador. El bloque te dara 5 monedas si tienes 10 monedas, si no, solo te dara una, tambien hara diferente sonido. db $42
JMP MarioBelow : JMP MarioAbove : JMP MarioSide JMP SpriteV : JMP SpriteH JMP MarioCape : JMP MarioFireBall JMP MarioCorner : JMP MarioBodyInside : JMP MarioHeadInside
MarioBelow: MarioAbove: MarioSide: MarioCorner: MarioBodyInside: MarioHeadInside: LDA $0DBF ;Con esto cargamos la direccion RAM de las monedas, las direcciones del bank 7E pueden ser cargadas sin tener que poner $7E0DBF. CMP #$0A ;Checamos si Mario tiene 10 monedas... BEQ Monedas ;Si tiene exactamente 10 monedas nos vamos al label "Monedas", si no es asi, el codigo continua normalmente. ;LDA $0DBF ;Esta parte del codigo es innecesaria si ya habias cargado la RAM de las monedas anteriormente sin haber cargado alguna otra cosa en A. CLC ;Opcode utilizado para la operacion matematica de sumar. ADC #$01 ;Aqui va el numero de monedas que vas añadir, en este caso seria 1. STA $0DBF ;Al final cargas el valor anterior en la RAM de monedas. RTL ;Fin del codigo.
Monedas: ;LDA $0DBF ;Igual que lo anterior, esto es innecesario, pero si quieren, incluyanlo. CLC ;Opcode utilizado para la operacion matematica de sumar. ADC #$05 ;Aqui va el numero de monedas que vas añadir, en este caso seria 5. STA $0DBF ;Al final cargas el valor anterior en la RAM de monedas. ;RTL ; Aqui seria el fin del codigo, pero como no hay mas codigo abajo y hay un RTL, no es necesario incluirlo. MarioCape: MarioFireBall: SpriteV: SpriteH: RTL ;Como no queremos que el bloque interactue con la capa, fireballs de mario y los sprites las labels se dirigiran a un RTLAsi seria el codigo del bloque, ahora procede a insertarlo y pruebalo. Leccion 3 - Utilizando subrutinasExisten varias subrutinas para bloques, algunas muy simples, pero otras demasiado complejas. En esta leccion te enseñare como usarlas. Lista de subrutinas: - Hacer desaparecer el bloque al tomarlo:
Desaparece: PHY LDA #$02 ; Replace block with block # 25 STA $9C JSL $00BEB0 ; Make the block disappear. PLY
- Hacer que el bloque tenga un efecto como si rompieras un Turn Block con un spinjump:
Break: LDA #$02 ;\ Replace block STA $9C ; | with block # 1E6 JSL $00BEB0 ;/ Erase self PHB ; LDA #$02 ;\ Push PHA ;/ A PLB ; LDA #$00 ; Set to 0 for normal explosion, 1 for rainbow (throw blocks) (Pongan #$00 para una explosión normal, y #$01 para la explosión de "arcoiris" como los Throw Blocks) JSR $028663 ; Breaking effect PLB
- Hacer que el bloque deje un rastro de estrellitas:
DisplayGlitter: LDA $7F ORA $81 BNE ReturnLoop LDY #$03 ; \ Find free sprite effect slot LoopStart: LDA $17C0,y ; | BEQ CreateGlitter ; | Branch if one found DEY ; | BPL LoopStart ; / ReturnLoop: RTL
CreateGlitter: LDA #$05 STA $17C0,Y LDA $9A AND #$F0 STA $17C8,Y LDA $98 AND #$F0 STA $17C4,Y LDA $1933 BEQ ADDR_00FD97 LDA $9A SEC SBC $26 AND #$F0 STA $17C8,Y LDA $98 SEC SBC $28 AND #$F0 STA $17C4,Y ADDR_00FD97: LDA #$10 STA $17CC,Y RTL
- Hacer que el bloque deje un rastro de humo:
Smoke: LDA $7F ORA $81 BNE .End
LDY #$03 .FindFree LDA $17C0,y BEQ .FoundOne DEY BPL .FindFree .End RTL
.FoundOne LDA #$01 STA $17C0,y LDA $98 AND #$F0 STA $17C4,y LDA $9A AND #$F0 STA $17C8,y LDA $1933 BEQ .End2 LDA $9A SEC SBC $26 AND #$F0 STA $17C8,y LDA $98 SEC SBC $28 AND #$F0 STA $17C4,y .End2 LDA #$1B STA $17CC,y RTL
- Hacer que el bloque cambie al siguiente Map16:
ChangeMap16: PHP REP #$30 ; Index (16 bit) Accum (16 bit) LDA $0003 CLC ADC #$0001 JSL ADDR_00814A PLP RTL
ADDR_008000: PLX PLB PLP RTL ADDR_008004: PHP SEP #$20 ; Accum (8 bit) PHB LDA $7EBD05 BNE ADDR_008012 LDA #$00 BRA ADDR_008014
ADDR_008012: LDA #$30 ADDR_008014: PHA PLB REP #$30 ; Index (16 bit) Accum (16 bit) PHX LDA $9A STA $0C LDA $98 STA $0E LDA #$0000 SEP #$20 ; Accum (8 bit) LDA $5B STA $09 LDA $1933 BEQ ADDR_008031 LSR $09 ADDR_008031: LDY $0E LDA $09 AND #$01 BEQ ADDR_008047 LDA $9B STA $00 LDA $99 STA $9B LDA $00 STA $99 LDY $0C ADDR_008047: CPY #$0200 BCS ADDR_008000 LDA $1933 ASL TAX LDA $BEA8,X STA $65 LDA $BEA9,X STA $66 STZ $67 LDA $1925 ASL TAY LDA ($65),Y STA $04 INY LDA ($65),Y STA $05 STZ $06 LDA $9B STA $07 ASL CLC ADC $07 TAY LDA ($04),Y STA $6B STA $6E INY LDA ($04),Y STA $6C STA $6F LDA #$7E STA $6D INC A STA $70 LDA $09 AND #$01 BEQ ADDR_008099 LDA $99 LSR LDA $9B AND #$01 BRA ADDR_00809E
ADDR_008099: LDA $9B LSR LDA $99 ADDR_00809E: ROL ASL ASL ORA #$20 STA $04 CPX #$0000 BEQ ADDR_0080AF CLC ADC #$10 STA $04 ADDR_0080AF: LDA $98 AND #$F0 CLC ASL ROL STA $05 ROL AND #$03 ORA $04 STA $06 LDA $9A AND #$F0 LSR LSR LSR STA $04 LDA $05 AND #$C0 ORA $04 STA $07 REP #$20 ; Accum (16 bit) LDA $09 AND #$0001 BNE ADDR_0080F2 LDA $1A SEC SBC #$0080 TAX LDY $1C LDA $1933 BEQ ADDR_008109 LDX $1E LDA $20 SEC SBC #$0080 TAY BRA ADDR_008109
ADDR_0080F2: LDX $1A LDA $1C SEC SBC #$0080 TAY LDA $1933 BEQ ADDR_008109 LDA $1E SEC SBC #$0080 TAX LDY $20 ADDR_008109: STX $08 STY $0A LDA $98 AND #$01F0 STA $04 LDA $9A LSR LSR LSR LSR AND #$000F ORA $04 TAY PLA SEP #$20 ; Accum (8 bit) STA [$6B],Y XBA STA [$6E],Y XBA REP #$20 ; Accum (16 bit) ASL TAY PHK PER $0015 LDA $7EBD05 BNE ADDR_008140 PEA $804C JMP $00C0FB
BRA ADDR_008147
ADDR_008140: PEA $805F JMP $30C0FF
ADDR_008147: PLB PLP RTL ADDR_00814A: PHP REP #$30 ; Index (16 bit) Accum (16 bit) PHY PHX TAX LDA $03 PHA JSL ADDR_008004 PLA STA $03 PLX PLY PLP RTL
- Hacer que el bloque haga aparecer un sprite normal:
JSR SetSpriteCoord1 LDA #$74 ;Sprite number JSR SpawnSprite
SpawnSprite: PHX PHP SEP #$30 PHA LDX #$0B SpwnSprtTryAgain: LDA $14C8,x ;Sprite Status Table BEQ SpwnSprtSet DEX CPX #$FF BEQ SpwnSprtClear BRA SpwnSprtTryAgain SpwnSprtClear: DEC $1861 BPL SpwnSprtExist LDA #$01 STA $1861 SpwnSprtExist: LDA $1861 CLC ADC #$0A TAX SpwnSprtSet: STX $185E LDA #$08 STA $14C8,x ;Sprite Status Table PLA STA $9E,x ;Sprite Type JSL $07F7D2 ; reset sprite properties INC $15A0,x ;"Sprite off screen" flag, horizontal LDA $9A ;Sprite creation: X position (low) STA $E4,x ;Sprite Xpos Low Byte LDA $9B STA $14E0,x ;Sprite Xpos High Byte LDA $98 ;Sprite creation: Y position (low) STA $D8,x ;Sprite Ypos Low Byte LDA $99 ;Sprite creation: Y position (high) STA $14D4,x ;Sprite Ypos High Byte LDA #$3E STA $1540,x ;Sprite Spin Jump Death Frame Counter LDA #$D0 STA $AA,x ;Sprite Y Speed LDA #$2C STA $144C,x LDA $190F,x ;Sprite Properties BPL SpwnSprtProp LDA #$10 STA $15AC,x SpwnSprtProp: PLP PLX RTS
SetSpriteCoord1: PHP REP #$20 LDA $98 AND #$FFF0 STA $98 LDA $9A AND #$FFF0 STA $9A PLP RTS
- Hacer que el bloque haga aparecer un custom sprite:
JSR SetSpriteCoord1 LDA #$01 ;Custom Sprite Number JSR SpawnSprite
SpawnSprite: PHX PHP SEP #$30 PHA LDX #$0B SpwnSprtTryAgain: LDA $14C8,x ;Sprite Status Table BEQ SpwnSprtSet DEX CPX #$FF BEQ SpwnSprtClear BRA SpwnSprtTryAgain SpwnSprtClear: DEC $1861 BPL SpwnSprtExist LDA #$01 STA $1861 SpwnSprtExist: LDA $1861 CLC ADC #$0A TAX SpwnSprtSet: STX $185E LDA #$08 STA $14C8,x ;Sprite Status Table PLA STA $7FAB9E,x JSL $07F7D2 ; reset sprite properties JSL $0187A7 ; get table values for custom sprite LDA #$88 ; mark as initialized STA $7FAB10,x INC $15A0,x ;"Sprite off screen" flag, horizontal LDA $9A ;Sprite creation: X position (low) STA $E4,x ;Sprite Xpos Low Byte LDA $9B STA $14E0,x ;Sprite Xpos High Byte LDA $98 ;Sprite creation: Y position (low) STA $D8,x ;Sprite Ypos Low Byte LDA $99 ;Sprite creation: Y position (high) STA $14D4,x ;Sprite Ypos High Byte LDA #$3E STA $1540,x ;Sprite Spin Jump Death Frame Counter LDA #$D0 STA $AA,x ;Sprite Y Speed LDA #$2C STA $144C,x LDA $190F,x ;Sprite Properties BPL SpwnSprtProp LDA #$10 STA $15AC,x SpwnSprtProp: PLP PLX RTS
SetSpriteCoord1: PHP REP #$20 LDA $98 AND #$FFF0 STA $98 LDA $9A AND #$FFF0 STA $9A PLP RTS
- Hacer que el bloque cheque a un sprite en especifico:
CheckSprite:
;In this label, you can check the sprite touching it:
LDX $15E9 LDA $9E,x CMP #$xx ; Sprite number to compare with. BNE Mario ;~Sprite touches the block code here. RTL
- Hacer que el bloque cheque a un custom sprite en especifico:
CheckCustom:
;In this label, you can check the sprite touching it:
LDX $15E9 LDA $7FAB9E,x CMP #$xx ; Sprite number to compare with. BNE Mario ;~Sprite touches the block code here. RTL
- Hacer que el bloque haga aparecer un score sprite:
Puntos: LDA $D8 ;\ PHA ;/ LDA $98 ;\ STA $D8 ;/ LDA $E4 ;\ PHA ;/ LDA $9A ;\ STA $E4 ;/ LDA $14D4 ;\ PHA ;/ LDA $99 ;\ STA $14D4 ;/ LDA $14E0 ;\ PHA ; \ LDA $9B ; | Hace aparecer el Sprite de puntos/1-up y le otorga el valor colocado enseguida STA $14E0 ; / LDA #$08 ;/ ;Posibles valores de $02ACE5: PHX ;\ ;00 = 100 LDX #$00 ;/ ;01 = 200 JSL $02ACE5 ;\ ;02 = 400 PLX ;/ ;03 = 800 PLA ;\ ;04 = 1000 STA $14E0 ;/ ;05 = 2000 PLA ;\ ;06 = 4000 STA $14D4 ;/ ;07 = 8000 PLA ;\ ;08 = 1up STA $E4 ;/ ;09 = 2up PLA ;\ ;0A = 3up STA $D8 ;/ ;0B+ = Glitch RTL ;Fin.
- Hacer que el bloque genere un bounce sprite:
Bounce: PHX PHY LDA #$0F TRB $9A TRB $98 LDX #$02; Cambiar esto para obtener diferente sprite, ver valores abajo LOOP100: ;00 = Turn Block LDA $1699,y ;01 = Note Block BEQ LBL100 ;02 = Question Block DEY ;03 = Question Block BPL LOOP100 ;04 = Translucent Block LDA $1699,y ;05 = On/Off Switch CMP #$07 ;+06 = Glitch BNE LBL100 PHA LDA $9B PHA LDA $98 PHA LDA $99 PHA LDA $16A5,y LDA $16AD,y STA $9B LDA $16A1,y CLC ADC #$0C AND #$F0 STA $98 LDA $16A9,y ADC #$00 STA $99 LDA $16c1,y JSL $00BEB0 STA $99 STA $98 PLA STA $9B PLA STA $9A
LBL100: LDA $028789,x STA $1901,y TXA INC A STA $1699,y LDA #$01 STA $169D,y LDA $9A STA $16A5,y LDA $9B STA $16AD,y LDA $98 STA $16A1,y LDA $99 STA $16A9,y
LDA #$08 LDA #$0D LDA $1933 LSR A ROR STA $08 LDX #$00 STA $16B1,y LDA $02873E,x STA $16B5,y TXA ORA $08 STA $16C9,y PLY PLX RTL
Wow, demasiadas subrutinas, no es necesario que las uses todas, solo usas si son totalmente necesarias. Para llamar a una subrutina solo basta con llamarla con JSL NombreDeLaRutina, por ejemplo, queremos que el bloque que hicimos anteriormente deje un rastro de estrellitas y que desaparezca. db $42
JMP MarioBelow : JMP MarioAbove : JMP MarioSide JMP SpriteV : JMP SpriteH JMP MarioCape : JMP MarioFireBall JMP MarioCorner : JMP MarioBodyInside : JMP MarioHeadInside
MarioBelow: MarioAbove: MarioSide: MarioCorner: MarioBodyInside: MarioHeadInside: LDA $0DBF ;Con esto cargamos la direccion RAM de las monedas, las direcciones del bank 7E pueden ser cargadas sin tener que poner $7E0DBF. CMP #$0A ;Checamos si Mario tiene 10 monedas... BEQ Monedas ;Si tiene exactamente 10 monedas nos vamos al label "Monedas", si no es asi, el codigo continua normalmente. ;LDA $0DBF ;Esta parte del codigo es innecesaria si ya habias cargado la RAM de las monedas anteriormente sin haber cargado alguna otra cosa en A. CLC ;Opcode utilizado para la operacion matematica de sumar. ADC #$01 ;Aqui va el numero de monedas que vas añadir, en este caso seria 1. STA $0DBF ;Al final cargas el valor anterior en la RAM de monedas.JSL Desaparece ;Se va a la subrutina que hace desaparecer el bloque.
JSL DisplayGlitter ;Se va a la subrutina que deja un rastro de estrellitas.RTL ;Fin del codigo.
Monedas: ;LDA $0DBF ;Igual que lo anterior, esto es innecesario, pero si quieren, incluyanlo. CLC ;Opcode utilizado para la operacion matematica de sumar. ADC #$05 ;Aqui va el numero de monedas que vas añadir, en este caso seria 5. STA $0DBF ;Al final cargas el valor anterior en la RAM de monedas.JSL Desaparece ;Se va a la subrutina que hace desaparecer el bloque.
JSL DisplayGlitter ;Se va a la subrutina que deja un rastro de estrellitas.;RTL ; Aqui seria el fin del codigo, pero como no hay mas codigo abajo y hay un RTL, no es necesario incluirlo. MarioCape: MarioFireBall: SpriteV: SpriteH: RTL ;Como no queremos que el bloque interactue con la capa, fireballs de mario y los sprites las labels se dirigiran a un RTL.
;Aqui abajo es un buen lugar para colocar las subrutinas.
DisplayGlitter: LDA $7F ORA $81 BNE ReturnLoop LDY #$03 ; \ Find free sprite effect slot LoopStart: LDA $17C0,y ; | BEQ CreateGlitter ; | Branch if one found DEY ; | BPL LoopStart ; / ReturnLoop: RTL
CreateGlitter: LDA #$05 STA $17C0,Y LDA $9A AND #$F0 STA $17C8,Y LDA $98 AND #$F0 STA $17C4,Y LDA $1933 BEQ ADDR_00FD97 LDA $9A SEC SBC $26 AND #$F0 STA $17C8,Y LDA $98 SEC SBC $28 AND #$F0 STA $17C4,Y ADDR_00FD97: LDA #$10 STA $17CC,Y RTL
Desaparece: PHY LDA #$02 ; Replace block with block # 25 STA $9C JSL $00BEB0 ; Make the block disappear. PLY RTLAhora el bloque desaparece y deja un rastro de estrellitas al ser tomado. AgradecimientosBueno gente de FR este fue el tutorial de como hacer custom blocks, en verdad quiero agradecer a Wiiq de SMWC por hacer su tutorial de bloques ya que gracias a su tutorial pude aprender ASM, ojala a ustedes les sirva este tutorial y si hacen algun bloque pueden postear sus resultados aqui, tambien si tienen alguna duda pueden postear aqui. Diviertanse haciendo sus bloques custom. ~TheLX5 |
|