As a learning exercise I'm trying to make a Tetris clone. I had been going through some tutorials that got me as far as drawing background, sprites, and taking controller input. I applied this info in making a background to show the play area. Due to the limitations of number of onscreen sprites, my assumption of how Tetris works is there are 4 sprites representing the piece that is currently in play. Once the piece lands into its final position, I am assuming that piece then becomes part of the background, and the next piece in play gets some new sprites to represent it. Subsequent pieces in play need to stay within the boundaries of the play area, and they cannot encroach on any of the previous blocks in the play area.
Right now I've hooked up left and right controller input. I set it up so that the piece can move left or right, but must stay within the boundaries of the play area. I have a file to represent the background - I've manually placed a couple of blocks in the play area so that I can experiment with new logic to prevent the piece in play from encroaching into those blocks.
Here is a snippet of what is in my background data. Bytes beginning with a 1 like $1C and $19 are using tiles that represent outside the play area. Values of $00 are blank and are empty spaces within the play area. Bytes that begin with 0 like $0C and $0A represent spaces in the playing area that are occupied with blocks.
I define these variables in the zero page since I think I'll need indirect indexed addressing to read what's in my background data.
I believe what I need to do is to always know the current location of the 4 squares that represent the playing piece relative to the background tiles that they cover. If the background is a 960 byte array, I believe the initial position that I'm placing my pieces are at these positions. I'm hard coding the starting position here. Additionally I'll need to know the destination position when the player tries to move a piece in order to determine whether the desired move is legal or not.
I have this code to check to see if my move is legal or not. The first piece section is checking to see if the adjacent left square is still within the boundaries of the play area. I could remove this code if I'm instead able to see if the adjacent square's using empty background tile $00.
This is the part that has problems. I'm trying to figure out what background tile exists in the left adjacent square. I believe I should be able to read and write to the background data that I used to draw the background. Right now I'm not getting the expected results. I'm not sure if I'm using the wrong initial position for my pieces, if I'm doing the indirect indexed addressing wrong, or if there's just something fundamentally wrong with my approach.
This code first attempts to subtract 1 from the current position of the leftmost sprite and saves it in playerNextGridPos1. I next attempt to use indirect indexed addressing to figure out what tile occupies the same square of playerNextGridPos1 in the background by using playerNextGridPos1 as the offset. I know that playerNextGridPos1 may be more than 255 bytes away from the first byte of my background data which is why I increment gridLocationHighByte if carry flag is true.
I believe the background data occupies 960 bytes starting at $E000. Initial value of playerGridPos1 is $D1, which I hardcoded because I believe the sprite I'm interested in begins on top of the tile specified in the position D1 of my background array, $E0D1. When I move left, I expect the block to move to $D0, which is stored in playerNextGridPos1. I believe gridLocationLowByte holds the value 00 and gridLocationHighByte holds the position of E0. When I add gridLocationLowByte and playerNextGridPos1, I believe carry flag would not be set so gridLocationHighByte should not be incremented since I'm still in the first 255 bytes of the background data. I'm expecting LDA [gridLocationLowByte], y to give return me a value of #$00, representing an empty space in the play area. However I don't believe this is returning #$00.
my project can be found here:
https://github.com/buschi8282/falling-blocks
Right now I've hooked up left and right controller input. I set it up so that the piece can move left or right, but must stay within the boundaries of the play area. I have a file to represent the background - I've manually placed a couple of blocks in the play area so that I can experiment with new logic to prevent the piece in play from encroaching into those blocks.
Here is a snippet of what is in my background data. Bytes beginning with a 1 like $1C and $19 are using tiles that represent outside the play area. Values of $00 are blank and are empty spaces within the play area. Bytes that begin with 0 like $0C and $0A represent spaces in the playing area that are occupied with blocks.
Code:
.db $1B,$1E,$16,$17,$19,$13,$1C,$19,$1D,$17,$16,$17,$19,$17,$16,$1D
.db $1B,$1A,$19,$1D,$17,$16,$18,$1E,$1A,$1C,$16,$18,$15,$18,$1E,$19
.db $1B,$16,$1B,$19,$18,$1A,$1E,$19,$12,$1B,$1C,$1C,$0C,$00,$00,$00
.db $00,$00,$00,$00,$0A,$0A,$1A,$1A,$15,$17,$1C,$1A,$16,$17,$1A,$1C
.db $19,$12,$1B,$1C,$16,$1B,$16,$1B,$1A,$15,$17,$1E,$0C,$00,$00,$00
.db $00,$00,$0C,$0C,$00,$0A,$19,$18,$1A,$19,$14,$1B,$15,$1B,$15,$17
.db $1B,$1A,$19,$1D,$17,$16,$18,$1E,$1A,$1C,$16,$18,$15,$18,$1E,$19
.db $1B,$16,$1B,$19,$18,$1A,$1E,$19,$12,$1B,$1C,$1C,$0C,$00,$00,$00
.db $00,$00,$00,$00,$0A,$0A,$1A,$1A,$15,$17,$1C,$1A,$16,$17,$1A,$1C
.db $19,$12,$1B,$1C,$16,$1B,$16,$1B,$1A,$15,$17,$1E,$0C,$00,$00,$00
.db $00,$00,$0C,$0C,$00,$0A,$19,$18,$1A,$19,$14,$1B,$15,$1B,$15,$17
I define these variables in the zero page since I think I'll need indirect indexed addressing to read what's in my background data.
Code:
;i attempt to use these bytes for indirect indexed addressing of background data
gridLocationLowByte .rs 1
gridLocationHighByte .rs 1
gridLocationLowByte .rs 1
gridLocationHighByte .rs 1
I believe what I need to do is to always know the current location of the 4 squares that represent the playing piece relative to the background tiles that they cover. If the background is a 960 byte array, I believe the initial position that I'm placing my pieces are at these positions. I'm hard coding the starting position here. Additionally I'll need to know the destination position when the player tries to move a piece in order to determine whether the desired move is legal or not.
Code:
playerGridPos1 = $D1
playerGridPos2 = $D2
playerGridPos3 = $D3
playerGridPos4 = $F1
playerNextGridPos1 .rs 1
playerNextGridPos2 .rs 1
playerNextGridPos3 .rs 1
playerNextGridPos4 .rs 1
playerGridPos2 = $D2
playerGridPos3 = $D3
playerGridPos4 = $F1
playerNextGridPos1 .rs 1
playerNextGridPos2 .rs 1
playerNextGridPos3 .rs 1
playerNextGridPos4 .rs 1
I have this code to check to see if my move is legal or not. The first piece section is checking to see if the adjacent left square is still within the boundaries of the play area. I could remove this code if I'm instead able to see if the adjacent square's using empty background tile $00.
Code:
MoveLeftIfLegal:
; check if square 1 new position is within play area
LDA playerSquare1x
SEC
SBC #$08
CMP #playAreaLeftBoundary
BCC DontMoveLeft
STA playerNextPos1x
; check if square 1 new position is within play area
LDA playerSquare1x
SEC
SBC #$08
CMP #playAreaLeftBoundary
BCC DontMoveLeft
STA playerNextPos1x
This is the part that has problems. I'm trying to figure out what background tile exists in the left adjacent square. I believe I should be able to read and write to the background data that I used to draw the background. Right now I'm not getting the expected results. I'm not sure if I'm using the wrong initial position for my pieces, if I'm doing the indirect indexed addressing wrong, or if there's just something fundamentally wrong with my approach.
This code first attempts to subtract 1 from the current position of the leftmost sprite and saves it in playerNextGridPos1. I next attempt to use indirect indexed addressing to figure out what tile occupies the same square of playerNextGridPos1 in the background by using playerNextGridPos1 as the offset. I know that playerNextGridPos1 may be more than 255 bytes away from the first byte of my background data which is why I increment gridLocationHighByte if carry flag is true.
Code:
LDA playerGridPos1
SBC #$01
STA playerNextGridPos1
; check if square 1 new position is not occupied
LDA #LOW(background)
STA gridLocationLowByte
LDA #HIGH(background)
STA gridLocationHighByte
LDA gridLocationLowByte
ADC #playerNextGridPos1
BCC BlockOneNotCrossedPage
INC gridLocationHighByte
BlockOneNotCrossedPage:
LDY #playerNextGridPos1
LDA [gridLocationLowByte], y
CMP $00
BNE DontMoveLeft
SBC #$01
STA playerNextGridPos1
; check if square 1 new position is not occupied
LDA #LOW(background)
STA gridLocationLowByte
LDA #HIGH(background)
STA gridLocationHighByte
LDA gridLocationLowByte
ADC #playerNextGridPos1
BCC BlockOneNotCrossedPage
INC gridLocationHighByte
BlockOneNotCrossedPage:
LDY #playerNextGridPos1
LDA [gridLocationLowByte], y
CMP $00
BNE DontMoveLeft
I believe the background data occupies 960 bytes starting at $E000. Initial value of playerGridPos1 is $D1, which I hardcoded because I believe the sprite I'm interested in begins on top of the tile specified in the position D1 of my background array, $E0D1. When I move left, I expect the block to move to $D0, which is stored in playerNextGridPos1. I believe gridLocationLowByte holds the value 00 and gridLocationHighByte holds the position of E0. When I add gridLocationLowByte and playerNextGridPos1, I believe carry flag would not be set so gridLocationHighByte should not be incremented since I'm still in the first 255 bytes of the background data. I'm expecting LDA [gridLocationLowByte], y to give return me a value of #$00, representing an empty space in the play area. However I don't believe this is returning #$00.
my project can be found here:
https://github.com/buschi8282/falling-blocks