From 4b62a11a11a4311aaf073f99b343f309b6d47599 Mon Sep 17 00:00:00 2001 From: "Torkild U. Resheim" Date: Thu, 7 Dec 2023 20:37:57 +0100 Subject: [PATCH] Use PETSCII editor for building levels --- .gitignore | 5 +++ README.md | 1 + screens.asm => font.asm | 58 +------------------------ itema.asm | 68 ++++++++++++++++-------------- libScreen.asm | 82 +++++++++++++++++++++++++++++++++++- libSprite.asm | 46 ++++++++++---------- petscii/README.md | 12 ++++++ petscii/commands.txt | 3 ++ petscii/convert-screens.asm | 61 +++++++++++++++++++++++++++ petscii/convert-screens.sh | 21 +++++++++ petscii/intro.bin | Bin 0 -> 2000 bytes petscii/intro.seq | 1 + petscii/level_1.bin | Bin 0 -> 2000 bytes petscii/level_1.seq | 1 + 14 files changed, 245 insertions(+), 114 deletions(-) rename screens.asm => font.asm (52%) create mode 100644 petscii/README.md create mode 100644 petscii/commands.txt create mode 100644 petscii/convert-screens.asm create mode 100755 petscii/convert-screens.sh create mode 100644 petscii/intro.bin create mode 100644 petscii/intro.seq create mode 100644 petscii/level_1.bin create mode 100644 petscii/level_1.seq diff --git a/.gitignore b/.gitignore index 626dbdf..d822394 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ /itema.vs /bin/ source.txt +.source.txt +itema.asm +petscii/convert-screens.prg +petscii/convert-screens.mod +petscii/convert-screens.sym diff --git a/README.md b/README.md index 6cd6afa..303c251 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,4 @@ This game requires a paddle to play. When using the VICE emulator, add the follo * [Codebase64](https://codebase64.org/doku.php?id=start) * [Dustlayer](https://dustlayer.com) +* [Kick Assembler User Guide](http://www.theweb.dk/KickAssembler/webhelp/content/cpt_Introduction.html) diff --git a/screens.asm b/font.asm similarity index 52% rename from screens.asm rename to font.asm index bcf33f9..56efb04 100644 --- a/screens.asm +++ b/font.asm @@ -1,4 +1,4 @@ -*=$3800 +*=$3800 "Custom character set" .byte $18, $18, $18, $FF, $FF, $18, $18, $18 .byte $3C, $24, $24, $7E, $62, $62, $62, $62 .byte $7C, $44, $44, $7E, $62, $62, $62, $7E @@ -256,59 +256,3 @@ .byte $00, $00, $00, $00, $00, $00, $00, $00 .byte $00, $00, $00, $00, $00, $00, $00, $00 -*=$2800 -background: -.byte $28, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $26, $21, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $09, $14, $05, $0D, $01, $20, $20, $20, $20, $20 -.byte $24, $20, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $20, $25, $29, $20, $08, $01, $03, $0B, $01, $14, $08, $0F, $0E, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $06, $12, $1B, $19, $01, $20, $32, $30, $32, $33, $20, $20 -.byte $24, $20, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $20, $20, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $7F, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $20, $20, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $20, $20, $80, $81, $80, $81, $80, $81, $80, $81, $80, $81, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $7F, $7F, $7F, $E0, $E0, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $E1, $E1, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $7F, $7F, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $7F, $7F, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $7F, $7F, $7F, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $7F, $7F, $2B, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $7F, $7F, $7F, $7F, $7F, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $7F, $7F, $7F, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $7F, $80, $81, $7F, $7F, $20, $20, $20, $20, $20, $20, $20, $20, $20, $7F, $7F, $7F, $80, $81, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $80, $81, $E3, $E3, $80, $81, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $80, $81, $E3, $E3, $80, $81, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $80, $81, $7F, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $80, $81, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $7F, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $40, $41, $42, $43, $44, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $50, $51, $52, $53, $54, $20, $20, $20 -.byte $24, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $25, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $22, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $27, $23, $29, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20, $20 -.byte $ff - -colormap: -.byte $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $00, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05, $05 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $05, $05, $03, $03, $03, $03, $03, $03, $03, $03, $03, $07 -.byte $07, $0F, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $0F, $07, $00, $07, $03, $03, $03, $03, $03, $03, $03, $03, $03, $05, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $07, $07 -.byte $07, $0F, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $0F, $0F, $08, $08, $08, $08, $08, $08, $08, $08, $08, $08, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $0F, $0F, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $0F, $0F, $03, $03, $03, $03, $03, $03, $03, $03, $03, $03, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $03, $03, $03, $07, $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $07, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $03, $03, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $03, $03, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $03, $03, $03, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $03, $03, $08, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $08, $08, $03, $03, $03, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $03, $03, $08, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $03, $03, $03, $03, $03, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $03, $03, $03, $03, $03, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $03, $03, $07, $07, $03, $03, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $03, $03, $07, $07, $03, $03, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $03, $03, $0D, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $03, $03, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0D, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $0F, $0F, $0F, $0F, $0F, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $0F, $0F, $0F, $0F, $0F, $07, $07, $07 -.byte $07, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $0F, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $00, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07, $07 -.byte $ff diff --git a/itema.asm b/itema.asm index 56ef313..ca73422 100644 --- a/itema.asm +++ b/itema.asm @@ -17,10 +17,11 @@ #import "libSprite.asm" #import "libInput.asm" #import "libScreen.asm" -#import "screens.asm" +#import "font.asm" BasicUpstart2(initialize) + .var music = LoadSid("music/Nightshift.sid") //<- Here we load the sid file .var demo_mode_movement_timer = $0 @@ -48,16 +49,17 @@ initialize: lda #$00 // Set sprite/background priority sta $d01b - - + + + lda #$00 // Disable xpand-x sta $d01d - + lda #$0a // Set sprite #1 individual color sta $d027 lda #$0c // Set sprite #2 individual color sta $d028 - + lda #paddleSpriteData/64 sta $07f8 // Sprite #0 lda #ballSpriteData/64 @@ -100,7 +102,7 @@ initialize: /* - Set character set pointer to our custom set, turn off + Set character set pointer to our custom set, turn off multicolor for characters */ @@ -113,16 +115,24 @@ and #%11101111 // by clearing bit #4 of $D016 sta $d016 /* - Print the first level from the second line from the top + Initialize IRQ */ -MEMCOPY(background, $0400) -MEMCOPY(colormap, $d800) +jsr init_irq /* - Initialize IRQ + Load the initial screen + $4500 - intro screen + $4d00 - level 1 */ -jsr init_irq +lda #$4d +sta $ff +lda #$00 +sta $fe +jsr load_screen +/* + Main loop +*/ loop: jmp loop @@ -137,7 +147,7 @@ demo_input: isSmaller: sta temp lda SpriteMem+9 - sbc #$06 // Adjust for ball radius + sbc #$06 // Adjust for ball radius adc temp jsr store_xl // Store the paddle x-position rts @@ -171,27 +181,20 @@ paddle_input: rts init_irq: - - lda #$00 - ldx #0 - ldy #0 - lda #music.startSong-1 - jsr music.init - sei lda #irq_1 sta $0314 - stx $0315 // Set interrupt addr + stx $0315 // Set interrupt addr lda #$7f sta $dc0d // Timer A off on cia1/kb sta $dd0d // Timer A off on cia2 - lda #$81 sta $d01a // Raster interrupts on + /* lda #$1b // Screen ctrl: default sta $d011 - + */ lda #$01 sta $d012 // Interrupt at line 0 @@ -205,7 +208,7 @@ irq_1: lda #$00 sta SpriteIndex jsr paddle_input - + animation_loop: clc @@ -223,7 +226,7 @@ irq_1: move_ball_normally: jsr move_vertically - move_paddle: + move_paddle: jsr move_horizontally jsr draw_sprite jsr check_collision @@ -235,12 +238,7 @@ irq_1: beq done jmp animation_loop done: - asl $d019 -// No music in the main loop -/// inc $d020 -// jsr music.play -// dec $d020 -// dec $d020 + asl $d019 // Clear interrupt flag jmp $ea81 // set flag and end /* @@ -264,8 +262,14 @@ accelerated_movement: jsr store_ya jmp move_ball_normally -*=music.location "Music" -.fill music.size, music.getData(i) // <- Here we put the music in memory +// Intro screen +.var intro_background = LoadBinary("petscii/intro.bin") +*=$4500 "Intro" +.fill intro_background.getSize(), intro_background.get(i) +// Level 1 +.var lvl1_background = LoadBinary("petscii/level_1.bin") +*=$4d00 "Level 1" +.fill lvl1_background.getSize(), lvl1_background.get(i) // -- Sprite Data -------------------------------------------------------------- // Created using https://www.spritemate.com diff --git a/libScreen.asm b/libScreen.asm index 4108146..183cf7b 100644 --- a/libScreen.asm +++ b/libScreen.asm @@ -11,11 +11,12 @@ loop: inx jmp loop out: - rts: + rts: } -.const MEMCP_SRCVECT = $fb +.const MEMCP_SRCVECT = $f9 .const MEMCP_DSTVECT = MEMCP_SRCVECT + 2 +.const MEMCP_CNTVECT = MEMCP_DSTVECT + 2 .macro MEMCOPY(src, dst) { // NB! The vector for index indirect addressing is little-endian @@ -47,3 +48,80 @@ memcp_nextpage: jmp memcp_loop memcp_out: } + +/* + Load a screen from the address prepared in in zeropage + $fe – lowest byte + $ff - highest byte + */ +load_screen: + + // Start with the characters + lda #$00 + sta MEMCP_DSTVECT + lda $fe // zeropage + sta MEMCP_SRCVECT + lda #$04 + sta MEMCP_DSTVECT+1 + lda $ff // zeropage + sta MEMCP_SRCVECT+1 + lda #$00 + sta MEMCP_CNTVECT // Initialize low byte of counter + sta MEMCP_CNTVECT+1 // Initialize high byte of counter + + jsr copy_loop + + // Now do the colours + lda $fe // Load the low byte of the pointer + clc // Clear carry flag before addition + adc #$e5 // Add the LSB for modification + sta MEMCP_SRCVECT + + lda $ff // Load the high byte of the pointer + adc #$03 // Add the MSB for modification + bcc noCarry // Branch if no carry from the first addition + adc #$01 // Add the carry from the first addition + + noCarry: + sta MEMCP_SRCVECT+1 + + // Set the destination to colour memory at $d800 + lda #$00 + sta MEMCP_DSTVECT + lda #$d8 + sta MEMCP_DSTVECT+1 + lda #$00 + sta MEMCP_CNTVECT // Initialize low byte of counter + sta MEMCP_CNTVECT+1 // Initialize high byte of counter + +copy_loop: + ldy MEMCP_CNTVECT // Load low byte of counter into Y + + lda (MEMCP_SRCVECT),Y // Load byte from source address + Y into A + sta (MEMCP_DSTVECT),Y // Store byte from A at target address + Y + + inc MEMCP_CNTVECT // Increment low byte of counter + bne check_counter + inc MEMCP_CNTVECT+1 // If low byte overflowed, increment high byte + +check_counter: + lda MEMCP_CNTVECT + cmp #$e8 // Check if low byte of counter has reached 0xe8 + bne continue_loop + + lda MEMCP_CNTVECT+1 + cmp #$03 // Check if high byte of counter has reached 0x03 + bne continue_loop + + jmp end_loop // If we've copied 1000 bytes, end the loop + +continue_loop: + iny // Increment Y + bne copy_loop + inc MEMCP_SRCVECT+1 // If Y overflowed, increment high byte of source address + inc MEMCP_DSTVECT+1 // If Y overflowed, increment high byte of target address + jmp copy_loop // Jump back to the start of the loop + +end_loop: + +rts \ No newline at end of file diff --git a/libSprite.asm b/libSprite.asm index 06365eb..5946e96 100644 --- a/libSprite.asm +++ b/libSprite.asm @@ -118,7 +118,7 @@ draw_sprite: jsr get_sprite_offset tay jsr get_yl - sta $d001,y + sta $d001,y // set horizontal position jsr get_sprite_offset @@ -130,7 +130,7 @@ draw_sprite: jsr get_xm cmp #$01 beq set_msb - + jsr get_xm cmp #$00 beq clear_msb @@ -175,7 +175,7 @@ move_left: sta temp // Store the new value in a variable jsr get_xl sec - sbc temp // Move left by the amount of velocity + sbc temp // Move left by the amount of velocity jsr store_xl jsr get_xm sbc #$00 // Subtract zero and borrow from lsb subtraction @@ -198,7 +198,7 @@ move_right: adc #$00 // Add zero and carry from lsb addition jsr store_xm jsr right_edge -rts +rts /* Apply the acceleration to the velocity, moving up. Once passing $FF (-1) the @@ -212,7 +212,7 @@ bounce_up: bne bounce_up_end */ jsr get_yv - clc + clc adc #Gravity // Simulate gravity jsr store_yv bounce_up_end: @@ -233,7 +233,7 @@ fall_down: clc adc #Gravity // Simulate gravity cmp #$80 // Never go negative - bpl fall_down_end + bpl fall_down_end jsr store_yv fall_down_end: rts @@ -269,7 +269,7 @@ rts Apply vertical acceleration from input along with gravity */ v_acceleration: - jsr get_ya + jsr get_ya sta temp // Store the new value in a variable jsr get_yv clv // Clear the overflow flag @@ -307,7 +307,7 @@ rts change_to_move_up: jsr get_yv // Change the direction of the velocity clc - sbc #VelocityLoss // Reduce velocity + sbc #VelocityLoss // Reduce velocity eor #$ff // Flip the sign jsr store_yv rts @@ -315,7 +315,7 @@ rts change_to_move_down: jsr get_yv // Change the direction of the velocity clc - adc #VelocityLoss // Reduce velocity + adc #VelocityLoss // Reduce velocity eor #$ff // Flip the sign jsr store_yv rts @@ -346,7 +346,7 @@ move_down: // Only actually move if the ball has not collided with the paddle jsr get_flags - cmp #$01 + cmp #$01 bne store_position lda temp @@ -440,7 +440,7 @@ over_fold: rts /* - Determine whether or not the current sprite is at the left edge of the + Determine whether or not the current sprite is at the left edge of the screen */ left_edge: @@ -473,7 +473,7 @@ shift_right: rts /* - Screen memory lookup tables. Each corresponds to the address of the first + Screen memory lookup tables. Each corresponds to the address of the first colum in each row. */ ScreenMemLowByte: @@ -496,7 +496,7 @@ check_collision: sbc #$00 // Subtract nothing, but make use of carry lsr // MSB -> C, divide by 2 lda temp // Get offset adjusted LSB - ror // Rotate Carry into LSB + ror // Rotate Carry into LSB lsr // Divide by 2 again lsr // Divide by 2 again @@ -504,7 +504,7 @@ check_collision: asl sta column - + jsr get_yl // Get y-position LSB sec // Set carry for borrow purpose sbc #$2b // Subtract for bottom offset @@ -515,12 +515,12 @@ check_collision: ldx row lda ScreenMemLowByte,x - sta $fd + sta $f7 lda ScreenMemHighByte,x - sta $fe + sta $f8 ldy column - lda ($fd),y + lda ($f7),y // Nothing should happen if the character is not a brick cmp #$80 @@ -544,9 +544,9 @@ check_collision: lda #$20 // Clear using space - sta ($fd),y // Store in both left.. + sta ($f7),y // Store in both left.. iny // ..and right half of block - sta ($fd),y + sta ($f7),y bounce_on_brick: jsr get_yv @@ -594,7 +594,7 @@ check_sprite_collision: lda #$0 jsr store_flags - + jsr get_xl // x-position LSB of ball sta balllo jsr get_xm // x-position LSB of ball @@ -657,7 +657,7 @@ bounce_off_paddle: cmp #TopOfPaddle bcc end_check_sprite_collision beq stop_ball - + bounce: jsr get_yv // Change the direction of the velocity clc @@ -675,7 +675,7 @@ bounce_off_paddle: // Set the accellerated movement timer. Hitting the ball with the // paddle will add some extra speed for a few cycles. Otherwise the - // balls velocity will be reduced for each bounce, and it will + // balls velocity will be reduced for each bounce, and it will // eventually stop. lda #$02 sta accelerated_movement_timer @@ -688,7 +688,7 @@ rts stop_ball: jsr get_yv clc - cmp #$2 + cmp #$2 bpl bounce lda #$08 jsr store_yv diff --git a/petscii/README.md b/petscii/README.md new file mode 100644 index 0000000..f6f0c0f --- /dev/null +++ b/petscii/README.md @@ -0,0 +1,12 @@ +# Generating level files + +Use http://petscii.krissz.hu/ to design the levels: + +1. Load `itemaball.pe` found in this folder +2. Edit levels +3. Export levels to `*.seq` files + - intro screen must be named 'intro.seq' + - level screens must be named 'level_.seq' +4. Update 'convert-screens.sh' +5. Run 'convert-screens.sh' + diff --git a/petscii/commands.txt b/petscii/commands.txt new file mode 100644 index 0000000..d1b31e7 --- /dev/null +++ b/petscii/commands.txt @@ -0,0 +1,3 @@ +s "screen.bin" 0 0400 07e7 +s "color.bin" 0 d800 dbe7 +quit diff --git a/petscii/convert-screens.asm b/petscii/convert-screens.asm new file mode 100644 index 0000000..ad9ae79 --- /dev/null +++ b/petscii/convert-screens.asm @@ -0,0 +1,61 @@ +/* + This program will read PETSCII commands crom the SEQ file generated by the + online PETSCII editor at http://petscii.krissz.hu. These files are + basically a sequence of bytes, where each byte is a PETSCII character. + + In order to make use of these screens in a C64 program, we need to load + the SEQ file into memory, and then print the characters to the screen. + This is a fairly simple task, but is pretty slow, and not usable in the + actual game. After a screen has been printed, we use the x64sc emulator + to dump screen and colour memory to a binary file, which we can then + load into the program as a blob. This is much faster, but requires a bit + of extra work to get the screen into the program. + */ +.const LOADSEQ_SRCVECT = $fb +.macro LOADSEQ(start) +{ + lda #start + sta LOADSEQ_SRCVECT + 1 + read_loop: + clc + lda $d6 // load the cursor row + cmp #$18 + bne read_data + lda $d3 // load the cursor column + cmp #$26 + beq end_loop// To avoid scrolling, don't print the last character + read_data: + lda ($fb),y // Load the character from the SEQ address + jsr $ffd2 // Excute the CHROUT routine to print the character + inc $fb // increment the low byte of the address + bne read_loop // if the low byte is not 0 (no overflow), branch to read_loop + inc $fc // if there was overflow, increment the high byte of the address + jmp read_loop // jump back to the start of the loop + end_loop: + + lda #$00 + sta $d012 + wait: + bit $d012 + bpl wait +} + +.var screen = LoadBinary("SEQFILE.seq") +* = $4000 "Screen"; .fill screen.getSize(), screen.uget(i) +* = $c000 "Program" + +BasicUpstart2(initialize) + +initialize: + + lda #$06 // Set the background color for the game area + sta $d021 + lda #$00 // Set the background color for the border + sta $d020 + + LOADSEQ($4000) + + loop: + jmp loop diff --git a/petscii/convert-screens.sh b/petscii/convert-screens.sh new file mode 100755 index 0000000..4f89dc7 --- /dev/null +++ b/petscii/convert-screens.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +KICK_ASSEMBLER_PATH=$HOME/Developer/C64/KickAssembler/KickAss.jar + +function convert() { + sed "s/SEQFILE/$1/g" convert-screens.asm > convert-screens.mod + java -jar $KICK_ASSEMBLER_PATH convert-screens.mod + x64sc -moncommands commands.txt -initbreak 0x0845 -autostart convert-screens.prg -warp + dd bs=2 skip=1 if=screen.bin of=screen_trimmed.bin + dd bs=2 skip=1 if=color.bin of=color_trimmed.bin + cat screen_trimmed.bin color_trimmed.bin > $1.bin + # Clean up + rm -f screen_trimmed.bin + rm -f color_trimmed.bin + rm -f screen.bin + rm -f color.bin + rm -f input.seq +} +rm -rf *.bin +convert "intro" +convert "level_1" diff --git a/petscii/intro.bin b/petscii/intro.bin new file mode 100644 index 0000000000000000000000000000000000000000..b25eca9a05142ffb71739b2ee8dcfa5a6d35ca11 GIT binary patch literal 2000 zcmbu8OLBxD5I~1Q2CU48rEaWj$UmuUlF0?~J3xN-@#<+n1R69mnO-R9>(>nhx7Raq zcBjI)3@73EN^@n$w#0m0=6vE3CkQO^RZ} zR9SU$7zSn5;f;sXttIFl6{!kUH>_=q<^MitW?eQ+byC$E(vLl5eS>en#_blE|>Bb=hBYiTrnqu_c1;y>%J+u=*B~&wFmm1UtZtdAUxt~dJ_Bq$=0?dn+z<55ai}$uk>ijm}V`#LGyd$&gb>C@^2Te?NX2PTx=|HrcxKx+}Ii5WnZcnbC!Yc+2!?B z<(99@H`HrFIGPvcb7W7YeUv#iRV;)r4z<}tV7v9Xx&a{{S1fi^RXPeGs%MfZ!`T5+G67C literal 0 HcmV?d00001 diff --git a/petscii/level_1.seq b/petscii/level_1.seq new file mode 100644 index 0000000..48f7712 --- /dev/null +++ b/petscii/level_1.seq @@ -0,0 +1 @@ +“Žž’(&&&&&&&&&&&&&&&&&&&&&&&&!) ž$› ž%)ž  ŸITEMA ž $› Ÿ@A@A@A@A@A@A@A@A@A@A@A›’ ž%)ž $› Ÿ@A@A@A@A@A@A@A@A@A@A@A›’ ž%)ž ŸHACKATHON ž $› ž%)ž $› ž%)ž ŸFR[YA 2023ž $› ΏΏΏΏΏΏΏΏΏΏ› ΏΏΏΏΏΏΏΏΏΏ› ž%)ž $› Ÿ@A@A@A@A@A›’ Ÿ@A@A@A@A@A›’ ž%)ž $› Ÿ@A@A@A@A@A›’ Ÿ@A@A@A@A@A›’ ž%)ž $› ž%)ž $› ŸΏΏΏž  ›’ ž‘‘›’ ž%)ž $› ŸΏΏ› ž%)ž $› ŸΏΏ› ž%)ž $› ŸΏΏΏ› ŸΏΏ+ž%)ž $› ΏΏŸΏΏΏ› ŸΏΏΏ› ž%)ž $› ŸΏ@A’ΏΏ› ŸΏΏΏ@A›’ ž%)ž $› Ÿ@Až££Ÿ@A›’ Ÿ@Až££Ÿ@A›’ ž%)ž $› Ÿ@A™’Ώ› Ÿ@A›’ ž%)ž $› ™Ώ› ž%)ž $› ž%)ž $› ž%)ž $› ž%)ž ›`abcdž $› ž%)ž ›pqrstž $› ž%)ž ""''''''''''''''''''''''''#)ž ’ \ No newline at end of file