Advertisement
Guest User

Untitled

a guest
Jan 17th, 2016
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. LoadTestScreen:
  2.     ;lda #$00
  3.     ;sta camerax+0          ;reset camera (Or set to position determined by the last room)
  4.     ;sta camerax+1
  5. -   jsr CameraCalculateNametable        ;high byte of camerax says which nametable to draw to
  6.     jsr CameraCalculateColumn           ;calculate if drawing on the right or the left
  7.     jsr DrawNewColumn
  8.     lda camerax+0
  9.     clc
  10.     adc #16
  11.     sta camerax+0
  12.     bcc -                               ;repeat until low byte of camerax has rolled over
  13.     inc camerax+1                       ;next screen
  14.     inc drawingmode     ;draw only to buffer now
  15.     jsr CameraCalculateNametable
  16.     jsr CameraCalculateColumn
  17.     jsr DrawNewColumn
  18.     inc needcolumnbufferupdate          ;buffer needs to be drawn next vblank
  19.     jsr CameraCalculatePPUAddr
  20.    
  21.     lda #$00                    ;these should be set to wherever the camera starts
  22.     sta camerax+0
  23.     sta camerax+1
  24.  
  25.  
  26. MainLoop:
  27.     inc sleeping
  28. @waitframe:
  29.     lda sleeping
  30.     bne @waitframe
  31.    
  32.     lda camerax+0
  33.     sta camerax_low_old
  34.    
  35.     jsr ReadControllers
  36.    
  37. ReadLeft:
  38.     lda buttons
  39.     and #%00000010
  40.     beq ReadLeftDone
  41.     lda #$00
  42.     sta dir             ;camera is moving left
  43. @checkedge:             ;sees if at the left edge of the screen, in which case don't move the camera any more
  44.     lda camerax+0
  45.     bne @checkedgedone  ;(Eventually, account for underflow if moving at speeds greater than 1.)
  46. @check2:
  47.     lda camerax+1
  48.     bne @check2done ;if the low byte is at 0, but the high byte isn't camera can still move
  49.     jmp ReadLeftDone    ;skip over moving the camera if both tests failed
  50. @check2done:
  51.     lda camerax+0       ;reload the low byte of camerax which got clobbered
  52. @checkedgedone:
  53.     sec
  54.     sbc #$01                ;(scroll_amount)
  55.     bcs @stillonscreen
  56.     pha                     ;save low byte
  57.     lda camerax+1
  58.     sec
  59.     sbc #$01
  60.     and #%00000011          ;only 4 screens (make variable)
  61.     sta camerax+1
  62.     pla                     ;restore low byte
  63. @stillonscreen:
  64.     sta camerax+0
  65.     jsr CameraCheckBufferUpdate     ;check if 8 pixels have been crossed, in which case the buffer needs to be drawn to the PPU next vblank
  66.     jsr CameraCheckNewColumn        ;check if 16 pixels have been crossed, in which case new data needs to be drawn to the buffer
  67. ReadLeftDone:
  68.  
  69. ReadRight:
  70.     lda buttons
  71.     and #%00000001
  72.     beq ReadRightDone
  73.     lda #$01                ;(scroll_amount)
  74.     sta dir
  75. @checkedge:
  76.     lda camerax+0
  77.     bne @checkedgedone      ;(Eventually, account for overflow if moving at speeds greater than 1.)
  78. @check2:
  79.     lda camerax+1
  80.     cmp #MAXSCREEN          ;change this to a variable to allow for different screen sizes
  81.     bne @check2done
  82.     jmp ReadRightDone       ;don't move camera if at the end of the room
  83. @check2done:
  84.     lda camerax+0           ;reload the low byte of camerax which was clobbered
  85. @checkedgedone:
  86.     clc
  87.     adc #$01
  88.     bcc @stillonscreen      ;don't inc high byte of camera if low byte hasnt overflowed
  89.     pha
  90.     lda camerax+1
  91.     clc
  92.     adc #$01
  93.     and #%00000011          ;only 4 screens (make variable)
  94.     sta camerax+1
  95.     pla
  96. @stillonscreen:
  97.     sta camerax+0
  98.     jsr CameraCheckBufferUpdate
  99.     jsr CameraCheckNewColumn
  100. ReadRightDone:
  101.  
  102.     jsr CameraCalculateNametable
  103.     jmp MainLoop
  104.  
  105. CameraCheckNewColumn:
  106.     ;if a 16 pixel boundary has been crossed, draw the next column
  107.     lda camerax_low_old
  108.     eor camerax+0
  109.     and #%00010000      ;see if bit 4 has changed
  110.     beq +   ;if 0, boundary not crossed
  111.     lda dir
  112.     bne @right
  113. @left:
  114.     jsr CameraCalculateColumnLeft
  115.     jmp DrawNewColumn               ;will RTS to where THIS routine was called
  116. @right:
  117.     jsr CameraCalculateColumnRight
  118.     jmp DrawNewColumn
  119. +   rts
  120.  
  121. CameraCalculateColumnLeft:
  122. CameraCalculateColumn:          ;the same routines, CameraCalculateColumn is just used when inititializing screens to avoid confusion
  123.     ;camerax is 16-bit shifted to find out which column to draw
  124.     ;note that it is only divided by 8 rather than 16 because column is used as an index to a table of words. This avoids having to ASL it
  125.     lda camerax+0
  126.     and #%11110000              ;high nibble says how many columns
  127.     sta column
  128.     lda camerax+1
  129.     lsr
  130.     ror column
  131.     lsr
  132.     ror column
  133.     lsr
  134.     ror column
  135.     rts
  136.    
  137. CameraCalculateColumnRight:
  138.     ;same as the above routine(s), only it looks for the column that's 16 columns away (On the right of the screen)
  139.     lda camerax+0
  140.     and #%11110000
  141.     sta column
  142.     lda camerax+1
  143.     clc
  144.     adc #$01
  145.     lsr
  146.     ror column
  147.     lsr
  148.     ror column
  149.     lsr
  150.     ror column
  151.     rts
  152.    
  153. CameraCalculateNametable:
  154.     lda camerax+1           ;get the high byte of camera (screens)
  155.     and #%00000001          ;look only at bit 0
  156.     sta nametable
  157.     rts
  158.    
  159. CameraCalculatePPUAddr:
  160.     ;uses column to calculate where in the PPU data should be drawn to (at the metatile level)
  161.     lda column      ;should have already been calculated beforehand
  162.     and #%00011110  ;only check column in the screen
  163.     sta ppuaddr_ptr+0
  164.     lda column
  165.     and #%00100000  ;check which screen
  166.     lsr
  167.     lsr
  168.     lsr             ;shift down
  169.     ora #$20        ;combine to get high byte of PPU address
  170.     sta ppuaddr_ptr+1
  171.     rts
  172.    
  173. CameraCheckBufferUpdate:
  174.     ;if an 8 pixel boundary has been crossed, time for the buffer to be drawn next vblank
  175.     lda camerax_low_old
  176.     eor camerax+0
  177.     and #%00001000              ;if changed by 8
  178.     beq +
  179.     lda #$01
  180.     sta needcolumnbufferupdate
  181.     lda dir
  182.     beq @left
  183. @right:
  184.     jsr CameraCalculateColumnRight      ;find the right column. This will be used to find the right PPU address to draw the buffer to
  185.     jmp @done
  186. @left:
  187.     jsr CameraCalculateColumnLeft
  188. @done:
  189.     ;since column gets incremented by two (since its used as an index to a table of addresses), and the buffer is only 1 tile wide,
  190.     ;we divide the low byte of camerax by 8, and if there's a remainder, it gets added to the address so the buffer can be drawn at any individual tile
  191.     lda camerax+0
  192.     and #%00001000
  193.     lsr
  194.     lsr
  195.     lsr                 ;shift bit 3 to bit 0
  196.     sta whichbuffer
  197.     jsr CameraCalculatePPUAddr
  198.     ;to draw to any tile location rather than just to metatile locations, add whichbuffer to low byte of PPU address.
  199.     lda ppuaddr_ptr+0
  200.     clc
  201.     adc whichbuffer
  202.     sta ppuaddr_ptr+0
  203. +   rts
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement