Efficient starfields

Subjects related to all or many CPU's... such as issues relating to multi-CPU Linkers and assemblers like VASM, Source editors like Notepad++ etc
If your post is relating to an emulator, post in that platforms post (eg CPC for Winape)
Post Reply
FourSeasons
Posts: 16
Joined: Mon Dec 09, 2019 7:38 pm

Efficient starfields

Post by FourSeasons » Tue Dec 10, 2019 10:46 pm

Hi Folks

I'm something of a fan of old school side scrolling shoot em ups like Gradius/Nemesis and R-Type.

One of the things these have in common are backgrounds full of 'stars' that scroll by in parallax-ed layers as the game progresses. Given that these are '80s machines, I'm guessing that there's not nearly enough horsepower for each dot to be being individually plotted/unplotted frame by frame.

So what's a better, more efficient way of doing this?

Looking at R-Type 2:

[youtube]https://youtu.be/T2ms0lORGiU?t=25[/youtube]

..the majority of the background stars seem to be on tiles that are scrolling along at the same speed as the rest of the scenery. There are some others that move faster, which I'm guessing are individual sprites.

On the other hand, with R-Type 1:

[youtube]https://youtu.be/ERaD8VwZuJc?t=31[/youtube]

.. and Nemesis/Gradius:

[youtube]https://youtu.be/wJVZYvRI0-s?t=6[/youtube]

.. the stars are moving at many more different speeds relative to each other.

So, does anyone have any insight into how this is being done or could be achieved on your platform of choice?

Nick

User avatar
akuyou
Posts: 380
Joined: Mon Apr 22, 2019 3:19 am
Contact:

Re: Efficient starfields

Post by akuyou » Thu Dec 12, 2019 3:58 am

This isn't something I've personally done, so I'm just going to have to give my 'off the cuff' thoughts.

On that R-type II arcade, the background stars move at fixed speed - they'll be a tilemap... the foreground ones that move faster will be sprites.

In the other cases I think they'll all be done with Sprites, the sprite will be a dot, and there will be a table of Xpositions for those dots... the table will be updated with the move speeds of the stars (or it could be a formula that calculates the positions on the fly)

now, you probably know this, but if you want 100 stars onscreen, you don't need 100 sprites to do it - provided there are never two stars on the same line, you could use just one sprite, and repeatedly move it while the screen redraws (timed with the CRT beam) - it will be visible in many places vertically, but you only used one sprite!(or a few)

on a bitmap based screen I think there would be no choice than to just plot pixels... I found some 8 bit examples here:
http://www.cpcmania.com/Docs/Programmin ... rfield.htm
https://github.com/KarolS/millfork/blob ... lencia.mfk

This gameboy one is interesting!... the GB is a Tile/Sprite system demo rom - they're probably using the sprites again, but i may be wrong - I'd have to disassemble the source to figure out what's happening
https://pdroms.de/files/nintendo-gamebo ... field-demo
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter! // 「チビ悪魔」可笑しいゴシックSTG ! // Work in Progress: ChibiAliens

Interested in CPU's :Z80,6502,68000,6809,ARM,8086,RISC-V
Learning: 65816,ARM,8086,6809

FourSeasons
Posts: 16
Joined: Mon Dec 09, 2019 7:38 pm

Re: Efficient starfields

Post by FourSeasons » Thu Dec 12, 2019 8:31 pm

Thanks, that makes sense.

I'm reading through the source at those links.

Lets see if I can get something similar to work on the DMG/GBC..

EvilSandwich
Posts: 20
Joined: Wed Nov 13, 2019 7:36 am

Re: Efficient starfields

Post by EvilSandwich » Sat Dec 14, 2019 3:03 pm

I found some anonymous source code for a horizontal scrolling star-field written in 6502 that was designed to work in Nick Morgan's 6502 machine:

http://skilldrick.github.io/easy6502/

The writer neglected to add any comments though and the labels are beyond unhelpful. But the code is very short and simple. Maybe you can glean something from it. :-O

Code: Select all

; 2d starfield
; Submitted by Anonymous

i:ldx #$7
g:lda $fe
  and #3
  adc #1
  sta $0,x
  lda $fe
  and #$1f
  sta $20,x
  dex
  bpl g
f:lda #$00
  sta $80
  lda #$02
  sta $81
  ldx #$7
l:lda $20,x
  pha
  clc
  sbc $00,x
  and #$1f
  sta $20,x
  lda $20,x
  tay
  lda #1
  sta ($80),y
  pla
  tay
  lda #0
  sta ($80),y
  lda $80
  clc
  adc #$80
  bne n
  inc $81
n:sta $80
  dex
  bpl l
  jmp f
What little I can tell you is that (on the virtual machine) $fe is a random value every clock cycle on that machine. $ff's value is the ascii value of the last key pressed. And the display memory (just pixel color values on a tiny applet screen) is between $0200-$05FF.

FourSeasons
Posts: 16
Joined: Mon Dec 09, 2019 7:38 pm

Re: Efficient starfields

Post by FourSeasons » Mon Dec 16, 2019 4:49 am

I had a couple of hours to spare. so for fun, I tried a another approach as well.

I filled a rectangle on-screen with a single tile. Then every few VBLANKS I changed that tile's bitmap definition with the next one from the following sequence:
stars_tiles_1-8.png
stars_tiles_1-8.png (6.62 KiB) Viewed 1309 times
This gives the effect of an animation where a small, slow moving, blinking background star, and a larger, faster foreground star both move from left to right.

It comes out looking like this in my test program on the VisualBoyAdvance emulator:
stars_tiles_1-8_test_thumb.png
stars_tiles_1-8_test_thumb.png (6.64 KiB) Viewed 1309 times

Click on the 'Download' button on the linked page below to view the animation:

https://github.com/FourSeasons2020/vide ... ated_8.mp4

The upside of this approach is that you only need to write at most 16 bytes (the size of a tile bitmap) to VRAM each frame to update the whole screen, so it's fairly speedy, though as it stands I'd admit the overall effect is pretty ugly.

Things could be improved if the animation was stretched out over two or more adjacent tiles to make things less visually 'dense' and allow a greater variety of star movement speeds. It could also do with each horizontal line using a different sequences from its neighbors to reduce the uniformity.

Anyway, back to the Christmas preparations..

FourSeasons
Posts: 16
Joined: Mon Dec 09, 2019 7:38 pm

Re: Efficient starfields

Post by FourSeasons » Mon Dec 16, 2019 4:55 am

EvilSandwich wrote:
Sat Dec 14, 2019 3:03 pm
I found some anonymous source code for .. Morgan's 6502 machine:
Thanks! I'll take a look later.
EvilSandwich wrote:
Sat Dec 14, 2019 3:03 pm
The writer neglected to add any comments though and the labels are beyond unhelpful.
I'm shocked! SHOCKED I tell you! I've never, EVER done ANYTHING like that myself...

[fx: whistles] [fx: tries to look innocent] :-D

User avatar
akuyou
Posts: 380
Joined: Mon Apr 22, 2019 3:19 am
Contact:

Re: Efficient starfields

Post by akuyou » Wed Dec 18, 2019 11:16 pm

Interesting stuff!

I like your GB example using a simple repeating tile... It makes me wonder how many tiles it would take to stop looking repetitive? I wonder how 4x4 could look... after all it's usually about what can be done quickly with few resources, than what's best.
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter! // 「チビ悪魔」可笑しいゴシックSTG ! // Work in Progress: ChibiAliens

Interested in CPU's :Z80,6502,68000,6809,ARM,8086,RISC-V
Learning: 65816,ARM,8086,6809

FourSeasons
Posts: 16
Joined: Mon Dec 09, 2019 7:38 pm

Re: Efficient starfields

Post by FourSeasons » Sun Dec 22, 2019 6:02 am

FWIW, taking a look at the code @EvilSandwich provided earlier, what it appears to be doing is plotting 8 stars, where each star is on it's own line and then scrolling them left across the screen.
ES_stars_1.png
ES_stars_1.png (2.72 KiB) Viewed 1242 times
In pseudo code it looks something like this:

Code: Select all

Build 2 look up tables for each of 8 stars starting with the 8th star and working backwards as follows
    Store a random horizontal velocity between 1 and 4 for each star at address &0000 + star number
    Store a random starting horizontal position between 0 and &1f (the width of the screen in pixels) for each star at address &0020 + star number

Repeat the following infinitely
    Do the following for each star 
        New star h-position = (Old star h-position - star velocity) AND screen width in pixels (so the star wraps around on the same line)
        Set pixel at new star h-position to white (color #1)
        Set pixel at old star h-position to black (color #0)
On the other hand I'm no 6502 expert, so perhaps there's some subtlety I'm missing here..

FourSeasons
Posts: 16
Joined: Mon Dec 09, 2019 7:38 pm

Re: Efficient starfields

Post by FourSeasons » Sun Dec 22, 2019 7:40 am

akuyou wrote:
Wed Dec 18, 2019 11:16 pm
..using a simple repeating tile... how many tiles it would take to stop looking repetitive?
Thinking about it some more, likely a bunch; probably more than would make it worthwhile on the Gameboy at least. Say around 20% of the screen would be my guess since the human eye is so good at picking up on patterns.

Looking at some Let's Play videos on YouTube I notice that neither of the Gameboy versions of R-Type or Nemesis attempt parallax scrolling and just have a static tilemap. Both Galaga and Galaxians are missing their vertically scrolling parallax star field too.

Looking at the Spectrum and CPC versions of R-Type, it's interesting to see that they both seem to be doing something similar to what @EvilSandwich's example code does.

Strela_999
Posts: 4
Joined: Sun Dec 29, 2019 8:51 am

Re: Efficient starfields

Post by Strela_999 » Tue Dec 31, 2019 12:51 pm

Thanks for the explanations, I'm a newbie but I think I got it, if everything goes right, I'll soon be able to show a basic background for my shoot'em up project.

Post Reply

Return to “General Assembly Programming”