Advertisement
NovaYoshi

ChangeBlock

Jun 25th, 2017
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Changes a block in the level immediately and queues a PPU update.
  2. ; input: A (new block), LevelBlockPtr,y (block to change)
  3. ; output: carry (success)
  4. ; locals: 0, 1, 2, 3, LevelDecodePointer, LevelSpritePointer
  5. .proc ChangeBlock
  6. SaveX = 0
  7. SaveY = 1
  8. Temp = 2
  9. TempSlot = 3
  10. LeftPointer = LevelDecodePointer  ; reuse pointers
  11. RightPointer = LevelSpritePointer
  12.  
  13.   sty SaveY       ; save X and Y so the routine calling this doesn't have to
  14.   stx SaveX
  15.   sta (LevelBlockPtr),y
  16.  
  17.   tax             ; X = block type, to index into metatile info tables
  18.  
  19.   ; find a slot for the block update
  20.   ldy #MaxNumBlockUpdates-1
  21. : lda BlockUpdateA1,y
  22.   beq :+          ; empty slot found
  23.   dey
  24.   bpl :-
  25. ;  no free slots, return with carry clear
  26.   ldy SaveY
  27.   ldx SaveX
  28.   clc
  29.   rts
  30. :
  31.   ; queue the block update
  32.   ; needs the bank set to MAINLOOP_BANK
  33.  
  34.   lda MetatileUL,x
  35.   sta BlockUpdateT1,y
  36.   lda MetatileUR,x
  37.   sta BlockUpdateT2,y
  38.   lda MetatileLL,x
  39.   sta BlockUpdateT3,y
  40.   lda MetatileLR,x
  41.   sta BlockUpdateT4,y
  42.  
  43.   ; use a lookup table to find the PPU addresses for the block updates
  44.   ldx SaveY ; Y index into the level
  45.   lda LevelBlockPtr+0
  46.   lsr
  47.   lsr
  48.   lsr
  49.   and #%11110
  50.   ora PPURowAddrLo,x
  51.   sta BlockUpdateA2,y
  52.   lda PPURowAddrHi,x
  53.   sta Temp
  54.  
  55.   ; use $2000 or $2400 as a base depending on the screen number
  56.   ldx #$20
  57.   lda LevelBlockPtr+1
  58.   and #1
  59.   beq :+
  60.      ldx #$24
  61. : txa
  62.   ora Temp
  63.   sta BlockUpdateA1,y
  64.   ora #$03 ; get attribute table base
  65.   sta Temp ; save for the attribute table update
  66.  
  67.   ; calculate the bottom row from the top row
  68.   lda BlockUpdateA2,y
  69.   add #32
  70.   sta BlockUpdateB2,y
  71.   lda BlockUpdateA1,y
  72.   adc #0
  73.   sta BlockUpdateB1,y
  74.  
  75.   ; update the attribute square too
  76.   ; but first find a slot for that (maybe find and update identical slots later?)
  77.   ldy #0
  78. : lda TileUpdateA1,y
  79.   beq :+   ; found a free slot
  80.   iny
  81.   cpy #MaxNumTileUpdates
  82.   bne :-   ; keep going
  83.   jmp Exit ; no slots? don't bother updating the attribute table
  84. :
  85.  
  86.   ; calculate attribute address and value
  87.   lda Temp
  88.   sta TileUpdateA1,y
  89.  
  90.   ; set up the two pointers
  91.   lda LevelBlockPtr+0
  92.   and #%11101111
  93.   sta LeftPointer+0
  94.   ora #%00010000
  95.   sta RightPointer+0
  96.   lda LevelBlockPtr+1
  97.   sta LeftPointer+1
  98.   sta RightPointer+1
  99.  
  100.   ; xxxx0000 <--- low byte of block pointer
  101.   ; 0000yyyy <--- Y coordinate, in SaveY
  102.   ; 11yyyxxx <--- attribute table format
  103.   lda SaveY
  104.   asl            ; 000yyyy0
  105.   asl            ; 00yyyy00
  106.   and #%00111000 ; 00yyy000
  107.   ora #%11000000 ; 11yyy000
  108.   sta Temp
  109.   lda LevelBlockPtr
  110.   lsr            ; 0xxxx000
  111.   lsr            ; 00xxxx00
  112.   lsr            ; 000xxxx0
  113.   lsr            ; 0000xxxx
  114.   lsr            ; 00000xxx
  115.   ora Temp       ; 11yyyxxx
  116.   sta TileUpdateA2,y
  117.  
  118.   sty TempSlot
  119.   lda SaveY
  120.   and #<~1 ; round to 32 pixel square
  121.   tay
  122.   lda (LeftPointer),y
  123.   tax
  124.   lda MetatilePalettes,x
  125.   and #%00000011
  126.   sta Temp
  127.   ; top right corner of attribute byte
  128.   lda (RightPointer),y
  129.   tax
  130.   lda MetatilePalettes,x
  131.   and #%00001100
  132.   ora Temp
  133.   sta Temp
  134.   iny
  135.   ; bottom left corner of attribute byte
  136.   lda (LeftPointer),y
  137.   tax
  138.   lda MetatilePalettes,x
  139.   and #%00110000
  140.   ora Temp
  141.   sta Temp
  142.   ; top right corner of attribute byte
  143.   lda (RightPointer),y
  144.   tax
  145.   lda MetatilePalettes,x
  146.   and #%11000000
  147.   ora Temp
  148.   ldy TempSlot
  149.   sta TileUpdateT,y
  150.  
  151. Exit:
  152.   sec             ; success
  153.   ldx SaveX
  154.   ldy SaveY
  155.   rts
  156. .endproc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement