A C64 Game - Step 28


The levels are currently rather ermm. sparse. Remember that a screen is built by several primitve types. To get things rolling a few new building types are added:

Namely a character/color area, an alternating line horizontally and vertically (alternating means toggling the characters +1/-1) and a quad (a 2x2 tile).



We'll start with the new constants:

LD_AREA = 4          ;data contains x,y,width,height,char,color
LD_LINE_H_ALT = 5 ;data contains x,y,width,char,color
LD_LINE_V_ALT = 6 ;data contains x,y,height,char,color
LD_QUAD = 7 ;data contains x,y,quad_id



...the new level building code table entries...

LEVEL_ELEMENT_TABLE_LO
!byte <‍.LevelComplete
!byte <‍LevelLineH
!byte <‍LevelLineV
!byte <‍LevelObject
!byte <‍LevelArea
!byte <‍LevelLineHAlternating
!byte <‍LevelLineVAlternating
!byte <‍LevelQuad

LEVEL_ELEMENT_TABLE_HI
!byte >.LevelComplete
!byte >LevelLineH
!byte >LevelLineV
!byte >LevelObject
!byte >LevelArea
!byte >LevelLineHAlternating
!byte >LevelLineVAlternating
!byte >LevelQuad



Here's the area code. Straight forward, fetch all needed parameters and build the area row by row:

!zone LevelAreaLevelArea
;X pos
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM1

;Y pos
iny
lda (ZEROPAGE_POINTER_1),y
tax
lda SCREEN_LINE_OFFSET_TABLE_LO,x
sta ZEROPAGE_POINTER_2
sta ZEROPAGE_POINTER_3
lda SCREEN_LINE_OFFSET_TABLE_HI,x
sta ZEROPAGE_POINTER_2 + 1
clc
adc #( ( SCREEN_COLOR - SCREEN_CHAR ) & 0xff00 ) >> 8
sta ZEROPAGE_POINTER_3 + 1

;width
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM2
sta PARAM6

;height
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM3

;char
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM4

;color
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM5

;store target pointers to screen and color ram
tya
pha

.NextLineArea
ldy PARAM1

.NextCharArea
lda PARAM4
sta (ZEROPAGE_POINTER_2),y
lda PARAM5
sta (ZEROPAGE_POINTER_3),y
iny
dec PARAM2
bne .NextCharArea

dec PARAM3
beq .AreaDone

;move pointers down a line
tya
sec
sbc #40
tay
lda ZEROPAGE_POINTER_2
clc
adc #40
sta ZEROPAGE_POINTER_2
sta ZEROPAGE_POINTER_3
lda ZEROPAGE_POINTER_2 + 1
adc #0
sta ZEROPAGE_POINTER_2 + 1
clc
adc #( ( SCREEN_COLOR - SCREEN_CHAR ) & 0xff00 ) >> 8
sta ZEROPAGE_POINTER_3 + 1

lda PARAM6
sta PARAM2
jmp .NextLineArea

.AreaDone
jmp NextLevelData




I won't go into details about the alternating lines, they are almost the same as the common lines, with one small addition: After every set character the lowest bit of the character number is toggled.


Way more interesting is the quad where we fall back to a hint from one of the first steps: Tables, tables, tables!

The quad primitive uses indices into quad tables. To easy the workload every quad is split into 8 tables, characters upper left, upper right, lower left, lower right and the same for the colors. This way the quad index can also be used for the content.

For the record: This makes building the quad tables really annoying but the speedup is worth it.

!zone LevelQuad
LevelQuad

;X pos
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM1

;Y pos
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM2

;item
iny
lda (ZEROPAGE_POINTER_1),y
sta PARAM3

;store y for next data
tya
pha

ldy PARAM2
lda SCREEN_LINE_OFFSET_TABLE_LO,y
sta ZEROPAGE_POINTER_2
sta ZEROPAGE_POINTER_3
lda SCREEN_LINE_OFFSET_TABLE_HI,y
sta ZEROPAGE_POINTER_2 + 1
clc
adc #( ( SCREEN_COLOR - SCREEN_CHAR ) & 0xff00 ) >> 8
sta ZEROPAGE_POINTER_3 + 1

ldy PARAM1
ldx PARAM3

;put image
lda BLOCK_TABLE_UL_LOCATION0,x
sta (ZEROPAGE_POINTER_2),y
lda BLOCK_TABLE_UL_COLOR_LOCATION0,x
sta (ZEROPAGE_POINTER_3),y
iny
lda BLOCK_TABLE_UR_LOCATION0,x
sta (ZEROPAGE_POINTER_2),y
lda BLOCK_TABLE_UR_COLOR_LOCATION0,x
sta (ZEROPAGE_POINTER_3),y
tya
clc
adc #39
tay
lda BLOCK_TABLE_LL_LOCATION0,x
sta (ZEROPAGE_POINTER_2),y
lda BLOCK_TABLE_LL_COLOR_LOCATION0,x
sta (ZEROPAGE_POINTER_3),y
iny
lda BLOCK_TABLE_LR_LOCATION0,x
sta (ZEROPAGE_POINTER_2),y
lda BLOCK_TABLE_LR_COLOR_LOCATION0,x
sta (ZEROPAGE_POINTER_3),y
jmp NextLevelData




step28.zip