User Tools

Site Tools


Static Starfield

by Achim

Locus classicus for this effect is Uridium: Fast scrolling graphics with fixed stars in the background. This kind of parallax shifting is simple but effective. Here's a small tutorial for a sidescrolling game using two screen buffers.

Only two steps necessary to achieve this effect:

  1. Manipulate one char corresponding to the soft scroll registers in $d016
  2. Check wether this char can be printed on its screen position or not

1) Char manipulation

First you've got to reserve one blank char in your charset. Then set up a table with eight values:

star:	.byte	$80, $40, $20, $10, $08, $04, $02, $01

This table is nothing but one bit shifted from left to right. To make the starfield static while the screen is scrolling use the soft scroll registers as an index.

lda softscroll	;bits 0-3 = value 0-7, manipulated by the main program
tay		;make it an index
ora #$30			
sta $d016	;soft scroll
lda star,y	;read bit from table
sta char	;write bit to first byte of resverved char

This has to be done in the interrupt. Now 'char' is always one centered bit, while the rest is scrolling left or right.

Some screen positions have to be defined. Set up two tables (hi-byte and offset) for each screen position.

starhi:		.byte	$00, $00, $01, $01, $02, $02, $03, $03		;relative hi-bytes for eight stars
staroffset:	.byte	$xx, $xx, ...					;some offset values from $00-$ff

The hi-bytes have to be relative values in order to make them usable for double buffering. Double buffering means that the main program switches between two screen buffers after scrolling one char length. The main program should handle two variables for both screen buffers, 'activescreen' and 'inactivescreen' and switch between both.

Stars only appear in 'space' which is usually visualized by a blank char. The screen positions have to be read with relative values in order to check wether there's 'space' or not.

        ldx #$00		;loop for all stars
        stx starposition	;zeropage address, lo-byte always #$00
loop	lda inactivescreen	;hi-byte of inactive screen buffer, e.g. $40 for buffer at $4000
        ora starhi,x		;convert relative to absolute value
        sta starposition+1	;hi-byte zeropage address
        ldy staroffset,x	;read offset
        lda (starposition),y	;read screen position
        bne skip		;while char #$00 is blank for 'space'...
        lda star				
        sta (starposition),y	;...print star on inactive screen buffer
skip	inx
        cpx ...			;max. stars
        bne loop		;check next star

The star will be printed if there's a blank char (in this case char #$00='space') at specific screen position. This has to be done at the right moment. A typical procedure for double buffering would look like this:

  1. initiate scrolling + shift first half from active to inactive screen buffer
  2. shift second half to inactive screen buffer
  3. print new chars to inactive screen buffer
  4. switch screens and shift colour RAM
  5. end of scroll, one char length done

The check can be done after step 2) or 3). Next thing to do is to delete stars from previous scroll procedure as they have moved left or right. After printing the star, increment or decrement (dependent on scroll direction) y-reg and write a blank char.

One thing left to do: Write colour RAM to make the star white. Otherwise the stars would flicker in multicolour mode. This has to be done after step 4).

Multidirectional scrolling

The same can be done for a multidirectional scrolling game. Only the first step has to be changed to make the stars fixed for vertical scrolling as well. Now the centered bit has to be shifted bytewise through the reserved char. The reserved char should be blanked out every frame. Then the centered bit can be written.

lda softscrollx	     ;left-right scrolling
tay		     ;make it an index
ora #$30			
sta $d016	     ;soft scroll x
lda star,y	     ;read bit from table
ldy softscrolly      ;up-down-scrolling as index
sta char,y	     ;write bit to specific byte of reserved char
ora #$10
sta $d011            ;soft scroll y
base/static_starfield.txt · Last modified: 2015-04-17 04:34 (external edit)