From 35070dfd5838b8fffdd3c2efa2c01511348a81fa Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Wed, 5 Jun 2019 17:33:57 -0400 Subject: [PATCH] Add Items --- Makefile | 2 +- src/display.asm | 106 +++++++++++++++++++++++++++- src/display.inc | 5 +- src/main.asm | 179 +++++++++++++++++++++++++++++++++++++++++++----- src/tiles.asm | 141 ++++++++++++++++++++++++++++++++++++-- src/tiles.inc | 30 +++++--- src/world.asm | 30 +++++++- src/world.inc | 2 + 8 files changed, 462 insertions(+), 33 deletions(-) diff --git a/Makefile b/Makefile index 94dc979..324d19a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ APPLE2_CL := C:\Users\bslat\Downloads\cc65-snapshot-win32\bin\cl65 -APPLE2_SRC := src\main.asm src\display.asm src\tiles.asm src\world.asm +APPLE2_SRC := src\main.asm src\display.asm src\tiles.asm src\world.asm APPLE2_MAP := factory.map APPLE2_LIST := factory.list APPLE2_CFLAGS := -Oirs -v -t apple2 -vm --cpu 6502 diff --git a/src/display.asm b/src/display.asm index 904a29e..4979c3c 100644 --- a/src/display.asm +++ b/src/display.asm @@ -12,8 +12,11 @@ .include "world.inc" .export draw +.export itemdraw .import World +.import ItemLoc +.import ItemRot .CODE @@ -25,7 +28,7 @@ .define ADDR_1 $19 ; First block line address .define ADDR_2 $1B ; Second block line address -.define TILE2D $abc ; non-zeropage placeholder for tile adderss. +.define TILE2D $abc ; This gets LDA into Absolute mode draw: ldx TILENUM ; This section gets the type of tile to draw. lda TILES, X ; It then loads the address of the tile to draw @@ -115,6 +118,107 @@ patch_8: bne lin916 ; Do that till the end, then you're done. rts + + + + +itemdraw: + ldx TILENUM + lda ITEMS,X + sta Ipatch_1+1 ; and changes all references to the placeholder + sta Ipatch_2+1 ; address to the address of the tile to draw. + sta Ipatch_3+1 + sta Ipatch_4+1 ; this first part gets the low byte + sta Ipatch_5+1 + sta Ipatch_6+1 + sta Ipatch_7+1 + sta Ipatch_8+1 + + lda ITEMS+1, X ; and this second part gets the high byte. + sta Ipatch_1+2 + sta Ipatch_2+2 + sta Ipatch_3+2 + sta Ipatch_4+2 + sta Ipatch_5+2 + sta Ipatch_6+2 + sta Ipatch_7+2 + sta Ipatch_8+2 + + ldx #00 ; Start x, the counter, to 0. + ldy TILECD ; Set y to the coordinate to draw to. + lda HGR_GRID,Y ; Load the screen address for that coordinate + sta ADDR_1 ; Store that to address 1 + clc + adc #$80 ; Add $80 to get the block below that + sta ADDR_2 ; Store that to address 2 + lda HGR_GRID+1,Y ; Get the high bytes for those two, which will be the + sta ADDR_1+1 ; same since the tiles never cross the interleaving pattern. + sta ADDR_2+1 + .define ITER3 #$20 ; $20 means the first block is done. +Ilin1t8: ldy #00 +Ipatch_1: ; Loop through the first 8 lines, drawing the value from the tile + lda TILE2D,X ; data to the screen memory + beq Iskip1 + sta (ADDR_1),Y +Iskip1: inx + iny +Ipatch_2: + lda TILE2D,X + beq Iskip2 + sta (ADDR_1),Y +Iskip2: inx + iny +Ipatch_3: + lda TILE2D,X + beq Iskip3 + sta (ADDR_1),Y +Iskip3: inx + iny +Ipatch_4: + lda TILE2D,X + beq Iskip4 + sta (ADDR_1),Y +Iskip4: inx + iny + lda ADDR_1+1 + adc #$04 + sta ADDR_1+1 + cpx ITER3 + bne Ilin1t8 ; Once that is over, go down to the next 8 lines. + clc + .define ITER4 #$40 ; The x counter keeps going to access the rest of the tile data +Ilin916: ldy #00 ; Y resets to go back to the beginning of screen memory offset +Ipatch_5: + lda TILE2D,X + beq Iskip5 + sta (ADDR_2),Y +Iskip5: inx + iny +Ipatch_6: + lda TILE2D,X + beq Iskip6 + sta (ADDR_2),Y +Iskip6: inx + iny +Ipatch_7: + lda TILE2D,X + beq Iskip7 + sta (ADDR_2),Y +Iskip7: inx + iny +Ipatch_8: + lda TILE2D,X + beq Iskip8 + sta (ADDR_2),Y +Iskip8: inx + iny + lda ADDR_2+1 + adc #$04 + sta ADDR_2+1 + cpx ITER4 + bne Ilin916 ; Do that till the end, then you're done. + rts + .DATA ; The HGR grid is every location that a tile can be drawn. HGR_GRID: ; It is a 10x10 grid. diff --git a/src/display.inc b/src/display.inc index 5c1d314..9902de6 100644 --- a/src/display.inc +++ b/src/display.inc @@ -1,4 +1,7 @@ ; stuff .define TILECD $1D -.define TILENUM $1E \ No newline at end of file +.define TILENUM $1E + +.define ITEMCD $ED +.define ITEMNUM $EE \ No newline at end of file diff --git a/src/main.asm b/src/main.asm index b4f17d8..afc131b 100644 --- a/src/main.asm +++ b/src/main.asm @@ -4,6 +4,11 @@ .import draw .import World +.import ItemLoc +.import itemRot + +.define UPDATEPT $6 +.define UPDATERT $8 .CODE @@ -14,21 +19,45 @@ loop: jsr update ; update runs the "game logic" (more to come) jmp loop ; to every tile, which animates belts and assemblers update: ldx #00 ; This loop just updates any animated tiles, like conveyors. -update1:lda World,x ; Load every world coordinate -ckconv: cmp #00 +update1:lda World,x +cktile: cmp #00 beq view cmp #02 ; Check if it is one of the three conveyor positions - beq upconv ; Jump if it is + beq rtconvJ ; Jump if it is cmp #04 - beq upconv + beq rtconvJ cmp #06 - beq upconv2 ; Jump if it needs to be reset -ckasmb: cmp #14 - beq upassm + beq rtconv2J ; Jump if it needs to be reset + cmp #08 + beq lfconvJ + cmp #10 + beq lfconvJ + cmp #12 + beq lfconv2J + cmp #14 + beq upassmJ cmp #16 - beq upassm + beq upassmJ cmp #18 - beq upassm2 + beq upassm2J + jmp ckitem +rtconvJ: jmp rtconv +rtconv2J:jmp rtconv2 +lfconvJ: jmp lfconv +lfconv2J:jmp lfconv2 +upassmJ: jmp upassm +upassm2J:jmp upassm2 +ckitem: lda World,x + cmp #14 + bcs upitem + jmp view +upitem: lda ItemLoc,x + cmp #02 + beq orecalc1 + cmp #04 + beq orecalc2 + cmp #06 + beq orecalc3 view: lda World,x sta TILENUM txa @@ -38,28 +67,111 @@ view: lda World,x lda TILECD lsr tax + lda ItemLoc,x + sta TILENUM + txa + asl + sta TILECD + jsr itemdraw + lda TILECD + lsr + tax footer: inx cpx #100 bne update1 rts -upconv: clc ; Add 2 to the tile type, moving it forward 1. +orecalc1: + lda ItemRot,x + cmp #00 + beq orecalc10 + cmp #02 + beq orecalc12 + jmp view + +orecalc10: + lda #04 + sta ItemLoc,x + jmp view + +orecalc12: + lda #00 + sta ItemLoc,x + lda #06 + dex + sta ItemLoc,x + jmp view + +orecalc2: + lda ItemRot,x + cmp #00 + beq orecalc20 + cmp #02 + beq orecalc22 + jmp view + +orecalc20: + lda #06 + sta ItemLoc,x + jmp view + +orecalc22: + lda #02 + sta ItemLoc,x + jmp view + +orecalc3: + lda ItemRot,x + cmp #00 + beq orecalc30 + cmp #02 + beq orecalc32 + jmp view + +orecalc30: + lda #00 + sta ItemLoc,x + lda #02 + inx + sta ItemLoc,x + jmp view + +orecalc32: + lda #04 + sta ItemLoc,x + jmp view + + +rtconv: clc ; Add 2 to the tile type, moving it forward 1. adc #02 sta World,x - jmp view + jmp ckitem -upconv2:lda #02 ; Set the tile type back to 2, reseting it. +rtconv2:lda #02 ; Set the tile type back to 2, reseting it. sta World,x - jmp view + jmp ckitem +lfconv: clc ; Add 2 to the tile type, moving it forward 1. + adc #02 + sta World,x + jmp ckitem + +lfconv2:lda #08 ; Set the tile type back to 2, reseting it. + sta World,x + jmp ckitem + +insert: jmp ckitem + +insert2:jmp ckitem + upassm: clc adc #02 sta World,x - jmp view + jmp ckitem upassm2:lda #14 sta World,x - jmp view + jmp ckitem _delay: ; Delay loop just adds a bunch of numbers lda #00 ; together to waste time. @@ -70,4 +182,39 @@ _delay1:adc #01 inx cpx #$ff bne _delay1 - rts \ No newline at end of file + rts + + +; This routine is a routine which calculates the corrent place to jump based +; off of the data loaded from the world. This has the advantage of taking the +; same time no matter which of the 128 possible tiles are loaded, but takes much +; longer. More common tiles like grass, conveyors, or assemblers would be earlier +; in the list so it wouldn't matter as much. There might be a way to speed this up +; more, but I think the chain of cmp/beq will actually be faster and easier to use. +; If there are a ton of subroutines, it might be too much for the break instructions, +; whereass the jump instructions would not have this problem. +; +; This loop is 39 cycles always, the chan loop is 4 cycles for each false, and 5 for true. + +slow: ldx #00 ; This loop just updates any animated tiles, like conveyors. +slow1: lda #>updates + sta UPDATEPT+1 + lda World,x ; Load every world coordinate + tay + adc #