base:waving_sprite_scroll
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | base:waving_sprite_scroll [2020-11-14 00:00] (current) – created mace | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Waving sprite scroll ====== | ||
+ | |||
+ | The sprites 1 through 8 are positioned on the screen next to each other with a fixed spacing. The scrolling takes place by moving them all a bit to the left, 4 pixels at a time, until sprite 1 reaches X≤0. At that moment sprite 2 is 4 pixels to the right of where sprite 1 started. | ||
+ | The sprites are then all positioned back to their starting position and the content is shifted, so that the value of sprites 8 is in 7, 7 in 6, etc. A new letter is fetched from the scroll text and the corresponding pointer value is plotted in the pointer of sprite 8. So basically sprites 1 moves from X=43 to X=255, 4 pixels at a time, after which it resets to value 43 again. | ||
+ | |||
+ | In addition to that all, the Y-coords of the sprites are changed based on sine data. | ||
+ | |||
+ | This codes assumes a letter-per-sprite font, in the same order as the screencodes, | ||
+ | |||
+ | The code is a stripped down and somewhat simplified version of what is used in "This Is Halloweed" | ||
+ | |||
+ | < | ||
+ | // Made in Kick Assembler | ||
+ | |||
+ | .const SPRITESPACING = 43 // minimal possible spacing | ||
+ | .const SINLEAP = 20 // choose anything here to change sine wave | ||
+ | .const SCROLLSPEED = 4 // lower value is slower | ||
+ | .const SPRITEPOINTER = $07f8 | ||
+ | .label spriteMemory = $2000 // assumes sprite font from $2000 to $3000 | ||
+ | |||
+ | *=$0801 | ||
+ | BasicUpstart($0810) | ||
+ | *=$0810 | ||
+ | sei | ||
+ | jsr $e544 // KERNAL: clear screen | ||
+ | lda #$00 // reset sine wave pointers | ||
+ | sta sinreset+1 | ||
+ | sta sinwave+1 | ||
+ | |||
+ | ldx #< | ||
+ | ldy #> | ||
+ | stx textpointer+1 | ||
+ | sty textpointer+2 | ||
+ | |||
+ | lda #$ff | ||
+ | sta $d015 // turn on all sprites | ||
+ | |||
+ | ldx #$00 | ||
+ | !: lda #$a0 // init with spaces in all sprite pointers | ||
+ | sta SPRITEPOINTER, | ||
+ | lda #$0e // light blue | ||
+ | sta $d027, | ||
+ | inx | ||
+ | cpx #$08 | ||
+ | bne !- | ||
+ | |||
+ | lda #$01 // init IRQ | ||
+ | sta $d01a | ||
+ | lda #$7f | ||
+ | sta $dc0d | ||
+ | sta $dd0d | ||
+ | lda $dc0d | ||
+ | lda $dd0d | ||
+ | |||
+ | lda #$32 // arbitrary value | ||
+ | sta $d012 | ||
+ | lda #$1b | ||
+ | sta $d011 | ||
+ | |||
+ | ldx #< | ||
+ | ldy #>irq | ||
+ | stx $0314 | ||
+ | sty $0315 | ||
+ | |||
+ | cli | ||
+ | |||
+ | jmp * | ||
+ | |||
+ | irq: | ||
+ | inc $d019 | ||
+ | |||
+ | lda scrollpos+1 // | ||
+ | sec | ||
+ | sbc # | ||
+ | bpl notext // skip text fetch if sprite 1 can still move left | ||
+ | |||
+ | ldx #$00 // shift content of sprites pointers | ||
+ | scrollpointers: | ||
+ | lda SPRITEPOINTER+1, | ||
+ | sta SPRITEPOINTER, | ||
+ | inx | ||
+ | cpx #$07 | ||
+ | bne scrollpointers | ||
+ | lda sinreset+1 // | ||
+ | clc | ||
+ | adc SINLEAP // this fixes sine offset | ||
+ | adc # | ||
+ | sta sinreset+1 | ||
+ | textpointer: | ||
+ | lda scrolltext // | ||
+ | bne noreset // if not #$00 (end indicator) | ||
+ | |||
+ | lda #< | ||
+ | sta textpointer+1 | ||
+ | lda #> | ||
+ | sta textpointer+2 | ||
+ | jmp textpointer // | ||
+ | |||
+ | noreset: | ||
+ | clc | ||
+ | adc # | ||
+ | sta SPRITEPOINTER+7 // | ||
+ | |||
+ | inc textpointer+1 // | ||
+ | bne !+ | ||
+ | inc textpointer+2 | ||
+ | !: | ||
+ | lda # | ||
+ | notext: | ||
+ | sta scrollpos+1 | ||
+ | |||
+ | ldx #$00 // position other sprites relative to sprite 1 | ||
+ | scrollpos: | ||
+ | lda #$18 // set new X-coord for all sprites | ||
+ | sta $d000 | ||
+ | clc | ||
+ | adc # | ||
+ | sta $d002 | ||
+ | clc | ||
+ | adc # | ||
+ | sta $d004 | ||
+ | clc | ||
+ | adc # | ||
+ | sta $d006 | ||
+ | clc | ||
+ | adc # | ||
+ | sta $d008 | ||
+ | clc | ||
+ | adc # | ||
+ | sta $d00a | ||
+ | bcc !+ | ||
+ | ldx # | ||
+ | clc | ||
+ | !: adc # | ||
+ | sta $d00c | ||
+ | bcc !+ | ||
+ | ldx #%11000000 | ||
+ | clc | ||
+ | !: adc # | ||
+ | sta $d00e | ||
+ | bcc !+ | ||
+ | ldx #%10000000 | ||
+ | !: stx $d010 // set proper sprite MSB | ||
+ | |||
+ | sinreset: | ||
+ | ldx #$00 // sine wave counter | ||
+ | stx sinwave+1 // | ||
+ | inc sinreset+1 | ||
+ | ldy #$00 | ||
+ | sinwave: | ||
+ | lda sindata // | ||
+ | sta $d001, | ||
+ | lda sinwave+1 | ||
+ | clc | ||
+ | adc # | ||
+ | sta sinwave+1 // | ||
+ | iny | ||
+ | iny | ||
+ | cpy #$10 // next sprites | ||
+ | bne sinwave | ||
+ | jmp $ea31 // end of IRQ1 | ||
+ | |||
+ | .align $100 | ||
+ | sindata: | ||
+ | .fill 256, 120 + 15.5*sin(toRadians(i*(3*360)/ | ||
+ | |||
+ | scrolltext: | ||
+ | .text "this is a sprite scroller for codebase64.org | ||
+ | .byte $00 | ||
+ | </ | ||
base/waving_sprite_scroll.txt · Last modified: 2020-11-14 00:00 by mace