User Tools

Site Tools


base:dysp_d017

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
base:dysp_d017 [2016-04-22 13:55] – [Stretching the first and last sprite line] compyxbase:dysp_d017 [2016-04-26 13:52] (current) – added link to github repo compyx
Line 7: Line 7:
 Anyway, a DYSP can be done in many ways, the way I'm describing below is probably the easiest way, since it keeps the timing for each raster line constant by 'cheating' with $d017 manipulation. Anyway, a DYSP can be done in many ways, the way I'm describing below is probably the easiest way, since it keeps the timing for each raster line constant by 'cheating' with $d017 manipulation.
  
 +{{:base:d017-dysp.png|Screen of the DYSP in action}}
 ==== Assembling the code ==== ==== Assembling the code ====
  
Line 12: Line 13:
 <code>64tass -C -a -o dysp.prg dysp.asm</code>... assuming one would copy and paste the code into a file called 'dysp.asm'. <code>64tass -C -a -o dysp.prg dysp.asm</code>... assuming one would copy and paste the code into a file called 'dysp.asm'.
  
 +Update: The code is now hosted on [[https://github.com/Compyx/dysp-d017|GitHub]], just clone the repo and run <code>make</code> to assemble, or <code>make x64</code> to assemble and run.
 ==== Sprite stretching theory ==== ==== Sprite stretching theory ====
  
Line 27: Line 29:
 Using the $d017 sprite stretching technique, we can make our sprites arbitrarily high, repeating each line of a sprite for as long as we like. This keeps our border opening routine simple. Using the $d017 sprite stretching technique, we can make our sprites arbitrarily high, repeating each line of a sprite for as long as we like. This keeps our border opening routine simple.
  
-==== Stretching the first and last sprite line ==== +Here's the routine, basically an adjusted FLD with side border opening and sprite stretching
- +The interesting part is the d017_table access, this allows use to stretch (or not) each line of each sprite
-The trick to variable Y-positioning is to stretch the first line of a sprite until we reach the Y-position where we want the sprite to display, then displaying 19 lines of the sprite, and then stretching the last line of the sprite until the loop ends. +
-This of course means we can only use 19 pixels high sprites, lines 0 and 20 are cleared so we don't see the stretched sprite data. +
- +
- +
-here's the routine, basically an adjusted FLD with side border open and sprite stretching: +
 <code 6502tasm> <code 6502tasm>
 ; The $d017 stretcher ; The $d017 stretcher
Line 69: Line 65:
 </code> </code>
  
-The interesting part is the d017_table access, this allows use to stretch (or not) each line of each sprite. This means we can +==== Stretching the first and last sprite line ==== 
 + 
 +The trick to variable Y-positioning is to stretch the first line of a sprite until we reach the Y-position where we want the sprite to display, then displaying 19 lines of the sprite (not stretching the sprite(s)), and then stretching the last line of the sprite until the loop ends. 
 + 
 +Suppose we would want to display three sprites, each one one pixel lower than the next. 'A' means sprite 0, 'B' sprite 1 and so on. A[xx] means which line of the sprite we display, 00 is the empty sprite line which we use to stretch until we display the actual sprite data (01-19), line 20 is the empty line we use to complete the loop. 
 + 
 +<code> 
 +Sprites            $d017             Display 
 +---------------    --------------    --------------------- 
 +A00   B00   C00    %11111111  $ff    (nothing, we stretch the first, empty, line 
 +A01   B00   C00    %11111110  $fe    AAA            
 +A02   B01   C00    %11111100  $fc    AAA  BBB 
 +A03   B02   C01    %11111000  $f8    AAA  BBB  CCC 
 +A04   B03   C02    %11111000  $f8    AAA  BBB  CCC 
 +...   ...   ...    %11111000  $f8    AAA  BBB  CCC 
 +A20   B19   C18    %11111001  $f9         BBB  CCC  
 +A20   B20   C19    %11111011  $fb              CCC 
 +A20   B20   C20    %11111111  $ff    (nothing, we stretch the last, empty, line 
 +</code> 
 + 
 +==== Generating the $d017 values ==== 
 + 
 +Generating the correct $d017 value is quite simple, but takes some cycles. 
 + 
 +  * fill $d017 table with $ff (all sprites are stretched) 
 +  * for each SPRITE: 
 +    - get Y-position of SPRITE 
 +    - mask out bits in $d017 table, starting at Y-position, for 19 lines 
 +  * next SPRITE 
 + 
 +In pseudo-code, this would look like this: 
 +<code> 
 +        ; fill $d017 table with $ff 
 +        ldx #0 
 +        lda #$ff 
 +-       sta $1000,x 
 +        inx 
 +        cpx #64 
 +        bne - 
 + 
 +        ; render sprite 
 +        ldy sprite0_y 
 +        ldx #0 
 +-       lda $1000,x 
 +        and #%11111110    ; don't stretch sprite 0 
 +        sta $1000,x 
 +        iny 
 +        inx 
 +        cpx #19           ; repeat 19 times 
 +        bne - 
 + 
 +        ; more code ... 
 + 
 +        ; render sprite 7 
 +        ldy sprite7_y 
 +        ldx #0 
 +-       lda $1000,x 
 +        and #%01111111    ; don't stretch sprite 7 
 +        sta $1000,x 
 +        iny 
 +        inx 
 +        cpx #19 
 +        bne - 
 +</code> 
 + 
 +==== Limitations ==== 
 + 
 +This of course means we can only use 19 pixels high sprites, lines 0 and 20 are cleared so we don't see the stretched sprite data. 
  
  
 ===== The Code ===== ===== The Code =====
 +
 +Putting it all together, we end up with the code below. I use two sinus tables for the X-movement, giving us 344 pixels total movement (actually a little less to avoid the DMA sprite access bug in the right border) and a single sinus for the Y movement.
 +
 +Again, this code is not up to (my) demo standards: change the border color to non-black and you'll see the border-opening bugs at the start of the routine.
  
 <code 6502tasm> <code 6502tasm>
base/dysp_d017.1461326125.txt.gz · Last modified: 2016-04-22 13:55 by compyx