Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- LoadTestScreen:
- ;lda #$00
- ;sta camerax+0 ;reset camera (Or set to position determined by the last room)
- ;sta camerax+1
- - jsr CameraCalculateNametable ;high byte of camerax says which nametable to draw to
- jsr CameraCalculateColumn ;calculate if drawing on the right or the left
- jsr DrawNewColumn
- lda camerax+0
- clc
- adc #16
- sta camerax+0
- bcc - ;repeat until low byte of camerax has rolled over
- inc camerax+1 ;next screen
- inc drawingmode ;draw only to buffer now
- jsr CameraCalculateNametable
- jsr CameraCalculateColumn
- jsr DrawNewColumn
- inc needcolumnbufferupdate ;buffer needs to be drawn next vblank
- jsr CameraCalculatePPUAddr
- lda #$00 ;these should be set to wherever the camera starts
- sta camerax+0
- sta camerax+1
- MainLoop:
- inc sleeping
- @waitframe:
- lda sleeping
- bne @waitframe
- lda camerax+0
- sta camerax_low_old
- jsr ReadControllers
- ReadLeft:
- lda buttons
- and #%00000010
- beq ReadLeftDone
- lda #$00
- sta dir ;camera is moving left
- @checkedge: ;sees if at the left edge of the screen, in which case don't move the camera any more
- lda camerax+0
- bne @checkedgedone ;(Eventually, account for underflow if moving at speeds greater than 1.)
- @check2:
- lda camerax+1
- bne @check2done ;if the low byte is at 0, but the high byte isn't camera can still move
- jmp ReadLeftDone ;skip over moving the camera if both tests failed
- @check2done:
- lda camerax+0 ;reload the low byte of camerax which got clobbered
- @checkedgedone:
- sec
- sbc #$01 ;(scroll_amount)
- bcs @stillonscreen
- pha ;save low byte
- lda camerax+1
- sec
- sbc #$01
- and #%00000011 ;only 4 screens (make variable)
- sta camerax+1
- pla ;restore low byte
- @stillonscreen:
- sta camerax+0
- jsr CameraCheckBufferUpdate ;check if 8 pixels have been crossed, in which case the buffer needs to be drawn to the PPU next vblank
- jsr CameraCheckNewColumn ;check if 16 pixels have been crossed, in which case new data needs to be drawn to the buffer
- ReadLeftDone:
- ReadRight:
- lda buttons
- and #%00000001
- beq ReadRightDone
- lda #$01 ;(scroll_amount)
- sta dir
- @checkedge:
- lda camerax+0
- bne @checkedgedone ;(Eventually, account for overflow if moving at speeds greater than 1.)
- @check2:
- lda camerax+1
- cmp #MAXSCREEN ;change this to a variable to allow for different screen sizes
- bne @check2done
- jmp ReadRightDone ;don't move camera if at the end of the room
- @check2done:
- lda camerax+0 ;reload the low byte of camerax which was clobbered
- @checkedgedone:
- clc
- adc #$01
- bcc @stillonscreen ;don't inc high byte of camera if low byte hasnt overflowed
- pha
- lda camerax+1
- clc
- adc #$01
- and #%00000011 ;only 4 screens (make variable)
- sta camerax+1
- pla
- @stillonscreen:
- sta camerax+0
- jsr CameraCheckBufferUpdate
- jsr CameraCheckNewColumn
- ReadRightDone:
- jsr CameraCalculateNametable
- jmp MainLoop
- CameraCheckNewColumn:
- ;if a 16 pixel boundary has been crossed, draw the next column
- lda camerax_low_old
- eor camerax+0
- and #%00010000 ;see if bit 4 has changed
- beq + ;if 0, boundary not crossed
- lda dir
- bne @right
- @left:
- jsr CameraCalculateColumnLeft
- jmp DrawNewColumn ;will RTS to where THIS routine was called
- @right:
- jsr CameraCalculateColumnRight
- jmp DrawNewColumn
- + rts
- CameraCalculateColumnLeft:
- CameraCalculateColumn: ;the same routines, CameraCalculateColumn is just used when inititializing screens to avoid confusion
- ;camerax is 16-bit shifted to find out which column to draw
- ;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
- lda camerax+0
- and #%11110000 ;high nibble says how many columns
- sta column
- lda camerax+1
- lsr
- ror column
- lsr
- ror column
- lsr
- ror column
- rts
- CameraCalculateColumnRight:
- ;same as the above routine(s), only it looks for the column that's 16 columns away (On the right of the screen)
- lda camerax+0
- and #%11110000
- sta column
- lda camerax+1
- clc
- adc #$01
- lsr
- ror column
- lsr
- ror column
- lsr
- ror column
- rts
- CameraCalculateNametable:
- lda camerax+1 ;get the high byte of camera (screens)
- and #%00000001 ;look only at bit 0
- sta nametable
- rts
- CameraCalculatePPUAddr:
- ;uses column to calculate where in the PPU data should be drawn to (at the metatile level)
- lda column ;should have already been calculated beforehand
- and #%00011110 ;only check column in the screen
- sta ppuaddr_ptr+0
- lda column
- and #%00100000 ;check which screen
- lsr
- lsr
- lsr ;shift down
- ora #$20 ;combine to get high byte of PPU address
- sta ppuaddr_ptr+1
- rts
- CameraCheckBufferUpdate:
- ;if an 8 pixel boundary has been crossed, time for the buffer to be drawn next vblank
- lda camerax_low_old
- eor camerax+0
- and #%00001000 ;if changed by 8
- beq +
- lda #$01
- sta needcolumnbufferupdate
- lda dir
- beq @left
- @right:
- jsr CameraCalculateColumnRight ;find the right column. This will be used to find the right PPU address to draw the buffer to
- jmp @done
- @left:
- jsr CameraCalculateColumnLeft
- @done:
- ;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,
- ;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
- lda camerax+0
- and #%00001000
- lsr
- lsr
- lsr ;shift bit 3 to bit 0
- sta whichbuffer
- jsr CameraCalculatePPUAddr
- ;to draw to any tile location rather than just to metatile locations, add whichbuffer to low byte of PPU address.
- lda ppuaddr_ptr+0
- clc
- adc whichbuffer
- sta ppuaddr_ptr+0
- + rts
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement