CPCWiki forum

General Category => Programming => Topic started by: abalore on 14:44, 28 May 24

Title: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 14:44, 28 May 24
Quick experiment of 1 pixel horizontal hardware scroll without using R3

With a single screen buffer
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: ervin on 15:17, 28 May 24
That's sorcery.
I'm fascinated to know how you did that.
:)
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 16:06, 28 May 24
It uses the 16 colors to create 4 bitplanes, so the graphics are only 2 colors.

BUT with clever design of the background, only 8 colors are needed to achieve the effect (still 2 color background), but you have 8 remaining colors for the foregroung sprites.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 23:55, 29 May 24
Further experiments testing the concept of 2 color background with 8 color foreground

Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: norecess464 on 02:36, 30 May 24
That's very cool !! BRAVO.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: lightforce6128 on 06:12, 30 May 24
Really exciting! Smooth scrolling, the CPU does not need to do much (and can do other things instead), and - as far as I can see - it is compatible to a wide variety of different screens.

But this 8-color thing, this brought me to thinking for a longer time. Finally I think I have it, but did not find the time to test this with a small program. I will try this later.

By further dividing the color bits, I think it is possible to achieve a 2-color background and an 8-color foreground provided that the scrolling has constant speed and direction. Here are some of my thoughts about this:

Spoiler: ShowHide

  • One bit selects between foreground and background.
  • If foreground is selected, the remaining three bits select one out of eight colors.
  • If background is selected, the second bit selects one out of two background colors.
  • The third bit encodes a set pixel in the background with offset 0.
  • The fourth bit encodes a set pixel in the background with offset 2.

This needs to be combined with a double buffer to create the missing offsets of 1 and 3. Set background pixels with different colors need to have a bit of space in between. This means the two background colors cannot be used freely. Nevertheless, background design can be improved with two colors, and dithering is possible at least from line to line. Applying rasters can help to get even more colors for the background.

Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: andycadley on 08:33, 30 May 24
The problem with overlapping the meaning of the bits like that is you have to do full masked sprites and preserve the background (keeping clean separation let's you cheat with XOR or do simplified AND/OR drawing). 

And the moment you have all that sprite masking you can probably just run with a full 16-colour screen.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 12:57, 30 May 24
Here is the source code, since I'm not going to go further on this by now:

The BASIC loader is on the disc image I previously posted.

Assembled with WinAPE
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: Herman on 14:03, 31 May 24
Quote from: abalore on 16:06, 28 May 24It uses the 16 colors to create 4 bitplanes, so the graphics are only 2 colors.

BUT with clever design of the background, only 8 colors are needed to achieve the effect (still 2 color background), but you have 8 remaining colors for the foregroung sprites.

Quote from: andycadley on 08:33, 30 May 24The problem with overlapping the meaning of the bits like that is you have to do full masked sprites and preserve the background (keeping clean separation let's you cheat with XOR or do simplified AND/OR drawing).

And the moment you have all that sprite masking you can probably just run with a full 16-colour screen.

Didn't Nigel "Chuckie Egg" Alderton do something like this in his CPC version of Ghost'n Goblins (https://www.cpc-power.com/index.php?page=detail&num=974)?

(Including hardware scrolling, although not 1 pixel at a time, but in bigger steps).

I found it fascinating at the time.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 14:24, 31 May 24
Quote from: Herman on 14:03, 31 May 24
Quote from: abalore on 16:06, 28 May 24It uses the 16 colors to create 4 bitplanes, so the graphics are only 2 colors.

BUT with clever design of the background, only 8 colors are needed to achieve the effect (still 2 color background), but you have 8 remaining colors for the foregroung sprites.

Quote from: andycadley on 08:33, 30 May 24The problem with overlapping the meaning of the bits like that is you have to do full masked sprites and preserve the background (keeping clean separation let's you cheat with XOR or do simplified AND/OR drawing).

And the moment you have all that sprite masking you can probably just run with a full 16-colour screen.

Didn't Nigel "Chuckie Egg" Alderton do something like this in his CPC version of Ghost'n Goblins (https://www.cpc-power.com/index.php?page=detail&num=974)?

(Including hardware scrolling, although not 1 pixel at a time, but in bigger steps).

I found it fascinating at the time.

As far as I know, Ghosts and Goblins uses R3 scrolling (2 mode 0 pixels at a time)
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: andycadley on 15:23, 31 May 24
Mission Genocide does something similar with its sprites IIRC, hence the rather limited colours (2 bits for the backgrounds, 2 bits for the foreground). Obviously that's also combined with a hardware vertical scroll.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 16:23, 31 May 24
I think we are wandering off the point, the purpose of the technique is to do accelerated 1 pixel horizontal scrolling.

The other techniques mentioned are for fast XOR sprite drawing.

Two color only background can be useful in a number of scenarios, like a sports game. The point of the technique is that it uses only 1 screen buffer, so 16K more bytes are available for other stuff.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: andycadley on 22:16, 31 May 24
Quote from: abalore on 16:23, 31 May 24I think we are wandering off the point, the purpose of the technique is to do accelerated 1 pixel horizontal scrolling.

The other techniques mentioned are for fast XOR sprite drawing.

Two color only background can be useful in a number of scenarios, like a sports game. The point of the technique is that it uses only 1 screen buffer, so 16K more bytes are available for other stuff.
The point was more that, if you don't follow the way you're segregating the palette because you want more colours, it undermines the entire trick behind it.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: lightforce6128 on 01:44, 11 June 24
Quote from: lightforce6128 on 06:12, 30 May 24... By further dividing the color bits, I think it is possible to achieve a 2-color background and an 8-color foreground provided that the scrolling has constant speed and direction.

I have to correct this: With this configuration the background allows to use 3 colors (not 2), and the foreground allows to use 11 colors (not only 8, the background colors can be used here as well). By putting some constraints on the background design, even 5 colors can be used for the background, and then only 8 for the foreground.

I also did a short comparison between saving the background for sprites and using XOR:

;; save background, and mask and draw one sprite byte
LD A, (HL) : LD (DE), A
AND A, 123 : OR A, 234 : LD (HL), A  ;; either full masking at sprite borders (6 NOPs)
LD (HL), B                           ;; or writing an often used byte in sprite center (2 NOPs)
INC E : INC L
;; restore background
LDI
;; => this takes 13-17 NOPs per byte


;; XOR one sprite byte, both for drawing and restoring
LD A, (HL)
XOR A, 123  ;; either a rarely used byte mask (2 NOPs)
XOR A, B    ;; or an often used byte mask (1 NOPs)
LD (HL), A
INC L
;; => this takes 13-14 NOPs per byte

So there is a difference, but not as big as I did expect. But unrolling sprite code like this will consume much memory. Storing the sprite data in a more compact way will increase the needed time.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 10:47, 11 June 24
Quote from: lightforce6128 on 01:44, 11 June 24
Quote from: lightforce6128 on 06:12, 30 May 24... By further dividing the color bits, I think it is possible to achieve a 2-color background and an 8-color foreground provided that the scrolling has constant speed and direction.

I have to correct this: With this configuration the background allows to use 3 colors (not 2), and the foreground allows to use 11 colors (not only 8, the background colors can be used here as well). By putting some constraints on the background design, even 5 colors can be used for the background, and then only 8 for the foreground.

I also did a short comparison between saving the background for sprites and using XOR:

;; save background, and mask and draw one sprite byte
LD A, (HL) : LD (DE), A
AND A, 123 : OR A, 234 : LD (HL), A  ;; either full masking at sprite borders (6 NOPs)
LD (HL), B                           ;; or writing an often used byte in sprite center (2 NOPs)
INC E : INC L
;; restore background
LDI
;; => this takes 13-17 NOPs per byte


;; XOR one sprite byte, both for drawing and restoring
LD A, (HL)
XOR A, 123  ;; either a rarely used byte mask (2 NOPs)
XOR A, B    ;; or an often used byte mask (1 NOPs)
LD (HL), A
INC L
;; => this takes 13-14 NOPs per byte

So there is a difference, but not as big as I did expect. But unrolling sprite code like this will consume much memory. Storing the sprite data in a more compact way will increase the needed time.

Good investigation! I usually don't aim to compact stuff since my target at this moment is cartridge games where there is plenty of room available.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: andycadley on 11:03, 11 June 24
Yeah, not surprised that with "compiled" sprites most of the cost for proper masking is removed. Like you say, if you store the sprites in a more compact format and do masking on the fly, it probably gets more expensive quickly and then the XOR routine gets better.

You also have to be a little careful with restoring the background when you do it that way as the order of overlapped sprites starts to matter. You can avoid it somewhat by storing the XOR of the background and sprite instead, but it again adds potential cost. If you have a lot of sprites, just storing a "clean" background buffer can end up being the cheaper option.
Title: Re: 1 pixel horizontal hardware scroll without using R3
Post by: abalore on 11:29, 11 June 24
Yes, my way to proceed in cartridge games is compiled sprites and clean background buffer (as in Alcon)
Powered by SMFPacks Menu Editor Mod