Quick experiment of 1 pixel horizontal hardware scroll without using R3
With a single screen buffer
That's sorcery.
I'm fascinated to know how you did that.
:)
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.
Further experiments testing the concept of 2 color background with 8 color foreground
That's very cool !! BRAVO.
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:
- 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.
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.
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
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.
Quote from: Herman on 14:03, 31 May 24Quote 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)
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.
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.
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.
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.
Quote from: lightforce6128 on 01:44, 11 June 24Quote 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.
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.
Yes, my way to proceed in cartridge games is compiled sprites and clean background buffer (as in Alcon)