vilxdryad

NESDev help with character movement and spawning position V5

May 9th, 2016
124
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. .inesprg 1 ; 1x 16KB PRG code
  2. .ineschr 1 ; 1x 8KB CHR data
  3. .inesmap 0 ; mapper 0 = NROM, no bank swapping
  4. .inesmir 1 ; background mirroring
  5.  
  6.  
  7.  
  8. ;;;;;;;;;;;;;;;
  9.  
  10.  
  11. ;---------------------------------------------------------------------------------------------------------------
  12. .rsset $0000
  13. CharX .rs 1 ;Setting variable for the Mushroom X Position
  14. CharY .rs 1 ;Setting variable for the Mushroom Y Position
  15. buttons1 .rs 1 ; player 1 gamepad buttons, one bit per button
  16. buttons2 .rs 1 ; player 2 gamepad buttons, one bit per button
  17. AddrLow: .rs 1
  18. AddrHigh: .rs 1
  19. vBlankTimer .rs 1 ;** increments once per frame until it wraps back around to zero.
  20. ;** used to sync game logic to once a frame
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27. .bank 0
  28. .org $C000
  29.  
  30. ;** We can put subroutines here for now, where they wouldn't be reached unless called
  31. ;---------------------------------------------------------------------------------------------------------------------
  32. ReadController1:
  33. LDA #$01
  34. STA $4016
  35. LDA #$00
  36. STA $4016
  37. LDX #$08
  38. ReadController1Loop:
  39. LDA $4016
  40. LSR A ; bit0 -> Carry
  41. ROL buttons1 ; bit0 <- Carry
  42. DEX
  43. BNE ReadController1Loop
  44. RTS
  45. ;---------------------------------------------------------------------------------------------------------------------
  46.  
  47. ;---------------------------------------------------------------------------------------------------------------------
  48. MovePlayerAccordingToControllerInput:
  49. ReadDOWN:
  50. LDA buttons1
  51. AND #%00000001 ; only look at bit 0
  52. BEQ ReadDOWNDone ; branch to ReadBDone if button is NOT pressed (0)
  53. ; add instructions here to do something when button IS pressed (1)
  54. LDA CharY ; load sprite X position
  55. SEC ; make sure carry flag is set
  56. SBC #$01 ; A = A - 1
  57. STA CharY ; save sprite X position
  58. ReadDOWNDone: ; handling this button is done
  59.  
  60. ReadUP:
  61. LDA buttons1
  62. AND #%00000010 ; only look at bit 0
  63. BEQ ReadUPDone ; branch to ReadADone if button is NOT pressed (0)
  64. ; add instructions here to do something when button IS pressed (1)
  65. LDA CharY ; load sprite X position
  66. CLC ; make sure the carry flag is clear
  67. ADC #$01 ; A = A + 1
  68. STA CharY ; save sprite X position
  69. ReadUPDone: ; handling this button is done
  70.  
  71. ReadRIGHT:
  72. LDA buttons1
  73. AND #%00000100 ; only look at bit 0
  74. BEQ ReadRIGHTDone ; branch to ReadBDone if button is NOT pressed (0)
  75. ; add instructions here to do something when button IS pressed (1)
  76. LDA CharX ; load sprite X position
  77. SEC ; make sure carry flag is set
  78. SBC #$01 ; A = A - 1
  79. STA CharX ; save sprite X position
  80. ReadRIGHTDone: ; handling this button is done
  81.  
  82. ReadLEFT:
  83. LDA buttons1
  84. AND #%00001000 ; only look at bit 0
  85. BEQ ReadLEFTDone ; branch to ReadADone if button is NOT pressed (0)
  86. ; add instructions here to do something when button IS pressed (1)
  87. LDA CharX ; load sprite X position
  88. CLC ; make sure the carry flag is clear
  89. ADC #$01 ; A = A + 1
  90. STA CharX ; save sprite X position
  91. ReadLEFTDone: ; handling this button is done
  92.  
  93. RTS
  94. ;---------------------------------------------------------------------------------------------------------------------
  95.  
  96. ;---------------------------------------------------------------------------------------------------------------------
  97. BufferSprites:
  98.  
  99. LDX #$00 ; Start routine a 0 to load the first sprite and to store at the first byte of OAM buffer
  100.  
  101. StoreSpritesIntoOamBuffer:
  102. LDA CharY ; Load the object Y position
  103. CLC
  104. ADC sprites, x ; Add Y offset of sprite from object position
  105. STA $0200, x ; Store to OAM buffer
  106. INX
  107.  
  108. LDA sprites, x ; Load the sprite tile
  109. STA $0200, x ; Store to OAM buffer
  110. INX
  111.  
  112. LDA sprites, x ; Load the sprite attribute
  113. STA $0200, x ; Store to OAM buffer
  114. INX
  115.  
  116. LDA CharX ; Load the object X position
  117. CLC
  118. ADC sprites, x ; Add X offset of sprite from object position
  119. STA $0200, x ; Store to OAM buffer
  120. INX
  121.  
  122. CPX #$10 ; See if this was the last sprite that needed to be loaded
  123. BNE StoreSpritesIntoOamBuffer ; Loop back if not.
  124.  
  125. RTS
  126. ;---------------------------------------------------------------------------------------------------------------------
  127.  
  128.  
  129.  
  130.  
  131.  
  132. RESET:
  133. SEI ; disable IRQs
  134. CLD ; disable decimal mode
  135. LDX #$40
  136. STX $4017 ; disable APU frame IRQ
  137. LDX #$FF
  138. TXS ; Set up stack
  139. INX ; now X = 0
  140. STX $2000 ; disable NMI
  141. STX $2001 ; disable rendering
  142. STX $4010 ; disable DMC IRQs
  143.  
  144. vblankwait1: ; First wait for vblank to make sure PPU is ready
  145. BIT $2002
  146. BPL vblankwait1
  147.  
  148. clrmem:
  149. LDA #$00
  150. STA $0000, x
  151. STA $0100, x
  152. STA $0300, x
  153. STA $0400, x
  154. STA $0500, x
  155. STA $0600, x
  156. STA $0700, x
  157. LDA #$FE
  158. STA $0200, x
  159. INX
  160. BNE clrmem
  161.  
  162. vblankwait2: ; Second wait for vblank, PPU is ready after this
  163. BIT $2002
  164. BPL vblankwait2
  165.  
  166. ;---------------------------------------------------------------------------------------------------------------
  167. ;Any code you want to run should be after this point at the earliest
  168.  
  169.  
  170.  
  171. ;** No need to read your controller here because it's only going to happen once
  172. ; JSR ReadController1
  173.  
  174.  
  175. **You can, however, move your position initialization here to occur before your game loop
  176.  
  177. LDA #$3C ;Load the x position for the mushroom player; 64 in deminal
  178. STA CharX
  179. LDX #$AB ;Load the x position for the mushroom player; 268 in deminal
  180. STA CharY
  181.  
  182.  
  183. LoadPalettes:
  184. LDA $2002 ; read PPU status to reset the high/low latch
  185. LDA #$3F
  186. STA $2006 ; write the high byte of $3F00 address
  187. LDA #$00
  188. STA $2006 ; write the low byte of $3F00 address
  189. LDX #$00 ; start out at 0
  190. LoadPalettesLoop:
  191. LDA palette, x ; load data from address (palette + the value in x)
  192. ; 1st time through loop it will load palette+0
  193. ; 2nd time through loop it will load palette+1
  194. ; 3rd time through loop it will load palette+2
  195. ; etc
  196. STA $2007 ; write to PPU
  197. INX ; X = X + 1
  198. CPX #$20
  199. BNE LoadPalettesLoop
  200.  
  201. ;---------------------------------------------------------------------------------------------------------------
  202.  
  203. LDA $2002
  204. LDA #$20
  205. STA $2006 ; write the high byte of $2000 address
  206. LDA #$00
  207. STA $2006 ; write the low byte of $2000 address
  208.  
  209. LDA #low(background)
  210. STA AddrLow
  211. LDA #high(background)
  212. STA AddrHigh
  213.  
  214. LDX #$04 ; Loop X 4 times
  215. LDY #$00 ; Loop Y 256 times
  216.  
  217. LoadBackgroundsLoop:
  218. LDA [AddrLow],y
  219. STA $2007
  220. INY
  221. BNE LoadBackgroundsLoop
  222. ; Outer loop
  223. INC AddrHigh ; increment high byte of address backg to next 256 byte chunk
  224. DEX ; one chunk done so X = X - 1.
  225. BNE LoadBackgroundsLoop ; if X isn't zero, do again
  226.  
  227. LDA $2002 ; Reset Scroll
  228. LDA #$00
  229. STA $2005
  230. STA $2005
  231. STA $2006
  232. STA $2006
  233.  
  234.  
  235. LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  236. STA $2000
  237.  
  238. LDA #%00011110 ; enable sprites, enable background, no clipping on left side
  239. STA $2001
  240.  
  241.  
  242.  
  243.  
  244. ;-------------------------------------------------------------------------------------------------------
  245. ;**This is your main game loop
  246. ;** these are things that happen once every frame but don't need to be in vBlank
  247.  
  248.  
  249. Forever:
  250.  
  251. JSR ReadController1
  252.  
  253. JSR MovePlayerAccordingToControllerInput
  254.  
  255. JSR BufferSprites
  256.  
  257.  
  258. LDA vBlankTimer
  259. MainVblankTimer: ; ** This timer prevents your game logic from running more than once per frame
  260. CMP vBlankTimer
  261. BEQ MainVblankTimer
  262.  
  263.  
  264.  
  265. JMP Forever ;jump back to Forever, infinite loop
  266. ;-------------------------------------------------------------------------------------------------------
  267.  
  268.  
  269.  
  270. ;-------------------------------------------------------------------------------------------------------
  271. ;**This is your NMI. It runs once per frame in vBlank annd must end with an RTI statement
  272. NMI:
  273. PHA
  274. LDA $2002
  275. LDA #$00
  276. STA $2003 ; set the low byte (00) of the RAM address
  277. LDA #$02
  278. STA $4014 ; set the high byte (02) of the RAM address, start the transfer
  279.  
  280. INC vBlankTimer
  281. PLA
  282. RTI ;** <--- you forgot to return from interrupt after your NMI is called
  283. ;-------------------------------------------------------------------------------------------------------
  284.  
  285.  
  286.  
  287.  
  288.  
  289. .bank 1
  290.  
  291. .org $E000
  292. palette:
  293. .db $22,$29,$1A,$0F, $22,$36,$17,$0F, $22,$30,$21,$0F, $22,$27,$17,$0F ;;background palette
  294. .db $22,$16,$30,$26, $22,$02,$38,$3C, $22,$1C,$15,$14, $22,$02,$38,$3C ;;sprite palette
  295.  
  296. sprites:
  297. ;vert tile attr horiz
  298. .db $00, $76, $00, $00
  299. .db $00, $77, $00, $08
  300. .db $08, $78, $00, $00
  301. .db $08, $79, $00, $08
  302.  
  303.  
  304. background:
  305.  
  306. ;X Pos 0 8 16 24 32 40 48 56 64 72 80 88 96 104 112 120
  307. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 1
  308. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 0
  309. ;; 128 136 144 152 160 168 176 184 192 200 208 216 224 232 240 248
  310. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 2
  311. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 8
  312. ;Column 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  313. .db $24,$24,$24,$1F,$12,$15,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 3
  314. .db $24,$24,$20,$18,$1B,$15,$0D,$24,$24,$1D,$12,$16,$0E,$24,$24,$24 ;; Y Position 16
  315. ; 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  316. .db $24,$24,$24,$00,$00,$00,$00,$00,$00,$24,$24,$19,$29,$00,$00,$24 ;; Row 4
  317. .db $24,$24,$24,$09,$28,$01,$24,$24,$24,$24,$00,$00,$00,$24,$24,$24 ;; Y Position 24
  318.  
  319. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 5
  320. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 32
  321.  
  322. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$36,$37,$24,$24,$24,$24 ;; Row 6
  323. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 40
  324.  
  325. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$35,$25,$25,$38,$24,$24,$24 ;; Row 7
  326. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 48
  327.  
  328. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$39,$3A,$3B,$3C,$24,$24,$24 ;; Row 8
  329. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 56
  330.  
  331. .db $24,$24,$24,$24,$24,$24,$36,$37,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 9
  332. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 64
  333.  
  334. .db $24,$24,$24,$24,$24,$35,$25,$25,$38,$24,$24,$24,$24,$24,$24,$24 ;; Row 10
  335. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 72
  336.  
  337. .db $24,$24,$24,$24,$24,$39,$3A,$3B,$3C,$24,$24,$24,$24,$24,$24,$24 ;; Row 11
  338. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 80
  339.  
  340. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 12
  341. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 88
  342.  
  343. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 13
  344. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 96
  345.  
  346. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 14
  347. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 104
  348.  
  349. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$11,$0E,$15,$15,$18,$24 ;; Row 15
  350. .db $20,$18,$1B,$15,$0D,$2B,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 112
  351.  
  352. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 16
  353. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 120
  354.  
  355. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 17
  356. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 128
  357.  
  358. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 18
  359. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 136
  360.  
  361. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 19
  362. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 144
  363.  
  364. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 20
  365. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 152
  366.  
  367. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 21
  368. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 160
  369.  
  370. .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24 ;; Row 22
  371. .db $24,$24,$24,$24,$24,$24,$31,$32,$24,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 168
  372.  
  373. .db $24,$24,$24,$24,$24,$24,$24,$60,$61,$62,$63,$24,$24,$24,$24,$24 ;; Row 23
  374. .db $24,$24,$24,$24,$24,$30,$26,$34,$33,$24,$24,$24,$24,$24,$24,$24 ;; Y Position 176
  375.  
  376. .db $24,$24,$24,$24,$24,$24,$24,$64,$65,$66,$67,$24,$24,$24,$24,$24 ;; Row 24
  377. .db $24,$24,$24,$24,$30,$26,$26,$26,$26,$33,$24,$24,$24,$24,$24,$24 ;; Y Position 184
  378.  
  379. .db $24,$24,$24,$24,$24,$24,$24,$68,$69,$26,$6A,$24,$24,$24,$24,$24 ;; Row 25
  380. .db $24,$24,$24,$30,$26,$34,$26,$26,$34,$26,$33,$24,$24,$24,$24,$24 ;; Y Position 192
  381.  
  382. .db $24,$24,$24,$24,$24,$24,$24,$68,$69,$26,$6A,$24,$24,$24,$24,$24 ;; Row 26
  383. .db $24,$24,$30,$26,$26,$26,$26,$26,$26,$26,$26,$33,$24,$24,$24,$24 ;; Y Position 200
  384.  
  385. .db $B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5 ;; Row 27
  386. .db $B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5 ;; Y Position 208
  387.  
  388. .db $B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7 ;; Row 28
  389. .db $B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7 ;; Y Position 216
  390.  
  391. .db $B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5 ;; Row 29
  392. .db $B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5,$B4,$B5 ;; Y Position 224
  393.  
  394. .db $B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7 ;; Row 30
  395. .db $B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7,$B6,$B7 ;; Y Position 232
  396.  
  397. attribute:
  398. ;; Each 2 bits on each binary byte are a tile's palette information; so each byte
  399. ;; manages to color a square 2x2 tile's portion of the screen; and its arranged like this:
  400. ;;
  401. ;; If we separate tbese binary number like this:
  402. ;;
  403. ;; Position: 0 1 2 3
  404. ;; %00 01 10 11
  405. ;;
  406. ;; We can tell which 2 bits are arranging our tile pallette if we follow this pattern in
  407. ;; a square 2x2 tile
  408. ;;
  409. ;; Square 2x2 Tile: XX XX
  410. ;; XX XX
  411. ;;
  412. ;; Attribute pattern on these tiles: 03 02
  413. ;; 00 01
  414. ;;
  415. ;; So, the binary in the example adobe are arranged like this using the full byte:
  416. ;;
  417. ;; Atribute output: 11 10
  418. ;; 00 01
  419.  
  420. .db %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010
  421. .db %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010
  422. .db %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010
  423. .db %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010
  424.  
  425. .db %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010
  426. .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
  427. .db %01010000, %01010000, %01010000, %01010000, %01010000, %01010000, %01010000, %01010000
  428. .db %01010101, %01010101, %01010101, %01010101, %01010101, %01010101, %01010101, %01010101
  429.  
  430. .org $FFFA ;first of the three vectors starts here
  431. .dw NMI ;when an NMI happens (once per frame if enabled) the
  432. ;processor will jump to the label NMI:
  433. .dw RESET ;when the processor first turns on or is reset, it will jump
  434. ;to the label RESET:
  435. .dw 0 ;external interrupt IRQ is not used in this tutorial
  436.  
  437.  
  438. ;;;;;;;;;;;;;;
  439.  
  440.  
  441. .bank 2
  442. .org $0000
  443. .incbin "mario.chr" ;includes 8KB graphics file from SMB1
RAW Paste Data