128x192 with 4 levels compatible
128x192 with 4 levels compatible
Ok, another one of my crazy ideas, just for the fun of it!
Thinking about a way to have a new screen-mode, 128x192 with 4 levels + attributes, and be compatible with standard Spectrums.
4 levels image:
ZX Compatible image:
If we take two consecutive pixels:
0 0 = 0
0 1 = 1
1 0 = 2
1 1 = 3
We can store two intermediate "gray scale" values that way.
On normal screens, the user would see a vertical dither pattern. Not that pretty, but not that different from many CGA or Apple II games.
But on an emulator that decodes the pixels patterns, the extra tones would be visible.
Of course, attributes and bright would still behave as before, with a two levels of mixing between paper and ink.
Thinking about a way to have a new screen-mode, 128x192 with 4 levels + attributes, and be compatible with standard Spectrums.
4 levels image:
ZX Compatible image:
If we take two consecutive pixels:
0 0 = 0
0 1 = 1
1 0 = 2
1 1 = 3
We can store two intermediate "gray scale" values that way.
On normal screens, the user would see a vertical dither pattern. Not that pretty, but not that different from many CGA or Apple II games.
But on an emulator that decodes the pixels patterns, the extra tones would be visible.
Of course, attributes and bright would still behave as before, with a two levels of mixing between paper and ink.
Re: 128x192 with 4 levels compatible
Would be similar to the Amstrad CPC Mode 1 and suffer a similar issue with the sheer amount of memory you have to start pushing around to draw screens (if anything it would be worse since you'd need separate planar layouts to remain compatible rather than storing all the bits for a pixel within a given byte). With any display mode that pushes much past about the 7K memory limit you really start to need hardware assistance to shift things around, which is where the CPC and SAM Coupe really suffered. If you really wanted more colours on screen without losing resolution a character-based mode like the C64 would make a lot more sense (and potentially use less memory) but that's difficult to work with unless you have hardware scrolling and sprites.
Re: 128x192 with 4 levels compatible
I think the idea behind 4throck's screenmode is that it takes exactly the same amount of memory as a usual 6912 screen just at the cost of horizontal resolution. Much the same way the multicolour modes work on the C64 (not including colour RAM etc).
ZX Soft - ALIEN(BUGFIX) - GB Soft - Demoscene
Re: 128x192 with 4 levels compatible
This is Radastan mode on the ZX-Uno, except that you can have 16 colours per pixel rather than 4 greyscale, taken from a user-specified quarter of the GGGRRRBB ULA+ palette.
Jimistan mode on the Spectrum Next works similarly, except it uses the Timex shadow screen as well, interleaving a byte from each screen, allowing 256 colours per pixel taken freely from a ULA Enhanced palette of 512 colours (because the Next palettes are 9-bit RRRGGGBBB).
ZEsarUX emulates both Radastan and Jimistan modes.
Jimistan mode on the Spectrum Next works similarly, except it uses the Timex shadow screen as well, interleaving a byte from each screen, allowing 256 colours per pixel taken freely from a ULA Enhanced palette of 512 colours (because the Next palettes are 9-bit RRRGGGBBB).
ZEsarUX emulates both Radastan and Jimistan modes.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: 128x192 with 4 levels compatible
The idea is to only use the standard ZX spectrum screen memory, and to display images that are 100% compatible with a standard Spectrum.
So no extra memory, and all extra gray levels must translate to dithering.
Simple pixel averaging from 256x192 to 128x192 will get you a gray tone, but my proposal stores 2 gray levels
00 = black
01 = grey 1
10 = grey 2
11 = white
So no extra memory, and all extra gray levels must translate to dithering.
Simple pixel averaging from 256x192 to 128x192 will get you a gray tone, but my proposal stores 2 gray levels
00 = black
01 = grey 1
10 = grey 2
11 = white
Re: 128x192 with 4 levels compatible
OK, I see now! Nice
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: 128x192 with 4 levels compatible
I'm just curious, how an emulator would know that it should do this conversion ?
Something for the user to select by hand ?
Something for the user to select by hand ?
Re: 128x192 with 4 levels compatible
Or maybe a ZXI port to turn it on and off, why not?
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: 128x192 with 4 levels compatible
I don't know much about hardware, but how about OUT 255 like the extra Timex modes ?
But since the idea is to be retro compatible, then yes, something that the user could select would be ideal.
Just select whatever mode works best for a given game / software.
I have a second idea: limit the effect to only certain attribute combinations (only bright for example).
This would allow full resolution text or detailed graphics as needed.
But since the idea is to be retro compatible, then yes, something that the user could select would be ideal.
Just select whatever mode works best for a given game / software.
I have a second idea: limit the effect to only certain attribute combinations (only bright for example).
This would allow full resolution text or detailed graphics as needed.
Re: 128x192 with 4 levels compatible
I don't really think it's worth it trying to make it visible on ordinary displays. The dithered image looks terrible; no-one would play a game like that.
There's some merit, I suppose, in mimicking the modes of other 8-bit computers - in this case the C64. I don't like the blocky look myself, but if you're going to do it, why not go the whole way and use the attribute byte to set two colours of the four available in each character cell?
You could even use the byte in a 2+3+3 bit fashion to select three of the colours, with the remaining background colour being common across the whole screen. Might as well then use something like ULA+ on top to define separate 4/8/8 colour palettes for each part of that colour byte. Or if the attribute just sets two colours, use a 16-colour palette that can be similarly redefined.
Personally I'd rather see the pixels paired up vertically to gain the extra bits for colour indexing. It's a little harder to make text readable, but I think it works far better for designing sprites, particularly upright humanoid figures, trees, buildings etc.
What I'd like to see is a character-mapped mode like the MSX has, where you can redraw character cells by writing one byte, but there's enough character data that you can put a different character in each cell, then treat the character definition RAM as a completely bitmapped screen.
There's some merit, I suppose, in mimicking the modes of other 8-bit computers - in this case the C64. I don't like the blocky look myself, but if you're going to do it, why not go the whole way and use the attribute byte to set two colours of the four available in each character cell?
You could even use the byte in a 2+3+3 bit fashion to select three of the colours, with the remaining background colour being common across the whole screen. Might as well then use something like ULA+ on top to define separate 4/8/8 colour palettes for each part of that colour byte. Or if the attribute just sets two colours, use a 16-colour palette that can be similarly redefined.
Personally I'd rather see the pixels paired up vertically to gain the extra bits for colour indexing. It's a little harder to make text readable, but I think it works far better for designing sprites, particularly upright humanoid figures, trees, buildings etc.
What I'd like to see is a character-mapped mode like the MSX has, where you can redraw character cells by writing one byte, but there's enough character data that you can put a different character in each cell, then treat the character definition RAM as a completely bitmapped screen.
Re: 128x192 with 4 levels compatible
I cannot understad this. Is it about automatic dithering? If so it would be interesting to achieve any blending of colours which is a trick used to simulate oranges for example interleaving ditherings in red and yellow. Automatic dithering in colours, not only for greys, might Not be "ugly". I don't think dithering is ugly in general. Just plain flat colours don't help to tell bright and dimmed colours, besides a bit of noise is interesting to suggest volumes and shades.
Re: 128x192 with 4 levels compatible
No, the original idea was for an extra screen mode that still looks OK if you don't have the modified hardware to display it properly.
I don't think it's really worth trying, because the fallback image doesn't look good enough. There were a few games converted from the C64 and amstrad to the Spectrum that just used dithers in place of colours for lazy ports of the graphics, and they all looked terrible.
Mind you, Gobots looked crap on the Amstrad in the first place...
Maybe if you could get the dithers to swap places on alternate rows so you got proper chessboard stipples, like Mr Heli there, but then it'd be an immense pain to program the 4-colour versions as the bit order would be reversed on alternate rows. Fine I suppose if you stick to 2-pixel movements of sprites as then the bits are always in the same positions...
I don't think it's really worth trying, because the fallback image doesn't look good enough. There were a few games converted from the C64 and amstrad to the Spectrum that just used dithers in place of colours for lazy ports of the graphics, and they all looked terrible.
Mind you, Gobots looked crap on the Amstrad in the first place...
Maybe if you could get the dithers to swap places on alternate rows so you got proper chessboard stipples, like Mr Heli there, but then it'd be an immense pain to program the 4-colour versions as the bit order would be reversed on alternate rows. Fine I suppose if you stick to 2-pixel movements of sprites as then the bits are always in the same positions...
Re: 128x192 with 4 levels compatible
what about something really subtle? just enough to make you believe there are more colours
something subtler than this
something subtler than this
Re: 128x192 with 4 levels compatible
That works but you only get one intermediate tone (3 levels).
The advantage of using the pixel order is to have 2 intermediate tones (4 levels).
I agree that the fallback image is not nice.
So lets consider changing the pixel order on alternate lines
That way, we could still use the normal chessboard dithering....
I really need to write a converter (or try to mod an emulator), but if I'm not mistaken, we would get this:
Original
Converted
So it would be:
Even lines
00 = black
01 = grey 1
10 = grey 2
11 = white
Odd lines
00 = black
10 = grey 1
01 = grey 2
11 = white
The advantage of using the pixel order is to have 2 intermediate tones (4 levels).
I agree that the fallback image is not nice.
So lets consider changing the pixel order on alternate lines
That way, we could still use the normal chessboard dithering....
I really need to write a converter (or try to mod an emulator), but if I'm not mistaken, we would get this:
Original
Converted
So it would be:
Even lines
00 = black
01 = grey 1
10 = grey 2
11 = white
Odd lines
00 = black
10 = grey 1
01 = grey 2
11 = white
Re: 128x192 with 4 levels compatible
Off-topic
This : https://commons.m.wikimedia.org/wiki/Fi ... hering.png
See? you'd make your graphics as usual and the engine would change small chameleon-esque ditherings for you on the fly!
This : https://commons.m.wikimedia.org/wiki/Fi ... hering.png
See? you'd make your graphics as usual and the engine would change small chameleon-esque ditherings for you on the fly!
Re: 128x192 with 4 levels compatible
You need large shaded or blended areas for all those different dithers to look any good. Even then, the pixels are pretty big and distinct, so it only really works for blending similar colours.
Within the usual size of Speccy game graphics, anything more than 01/10 dithering is too complicated. And you sometimes have to invert the stipple pattern (or move it by 1 pixel) when putting it next to the solid or clear parts of your design.
Within the usual size of Speccy game graphics, anything more than 01/10 dithering is too complicated. And you sometimes have to invert the stipple pattern (or move it by 1 pixel) when putting it next to the solid or clear parts of your design.
Re: 128x192 with 4 levels compatible
This is the idea! It was already invented around 2009 by Gasman ?
It's called Chunkypaint 53c :
http://chunkypaint.zxdemo.org
http://events.retroscene.org/53c
http://53c.verve.space
There are some works from parties on zx-art, pouet, demozoo, etc
https://demozoo.org/parties/1779/
http://www.pouet.net/prod.php?which=61392
Dunno if this would be possible to make games or it's just useful for lower resolution loading screens.
It's called Chunkypaint 53c :
http://chunkypaint.zxdemo.org
http://events.retroscene.org/53c
http://53c.verve.space
There are some works from parties on zx-art, pouet, demozoo, etc
https://demozoo.org/parties/1779/
http://www.pouet.net/prod.php?which=61392
Dunno if this would be possible to make games or it's just useful for lower resolution loading screens.
Last edited by hikoki on Fri Apr 06, 2018 6:43 pm, edited 1 time in total.
Re: 128x192 with 4 levels compatible
hikoki, those examples are different. They use dithering to simulate a 50% mix between paper and ink.
The point here it to try to use dithering in a way that:
- still looks decent on a normal spectrum
- encodes two values, so you can have 33% and 66% mixing (on compatible "hardware")
The point here it to try to use dithering in a way that:
- still looks decent on a normal spectrum
- encodes two values, so you can have 33% and 66% mixing (on compatible "hardware")
Re: 128x192 with 4 levels compatible
Good luck 4thRock. Hope someone will help you mod some emulator.
Anyways I like the idea of painting with a virtual extended palette like and the paint editor makes all the dithering for you. This might be a nice feature suggestion for ZXPaintBrush. According to Joefish this is not feasible to make games? Please let me know if there is some game using this technique intensively.
Anyways I like the idea of painting with a virtual extended palette like and the paint editor makes all the dithering for you. This might be a nice feature suggestion for ZXPaintBrush. According to Joefish this is not feasible to make games? Please let me know if there is some game using this technique intensively.
Re: 128x192 with 4 levels compatible
OK, wrote a simple Javascript image converter and got some results
Standard image
Decoded
Not horrible on a standard display.
I'll share the code latter.
Standard image
Decoded
Not horrible on a standard display.
I'll share the code latter.
Re: 128x192 with 4 levels compatible
Using a different encoding on different scanlines would be pretty much unworkable for moving images, so you'd really be limiting the use to static screens.
Re: 128x192 with 4 levels compatible
Not really. Because of the drop in resolution, things would only move horizontally in 2-pixel steps, so it would be reasonable for things to move vertically in 2-pixel steps too, thus preserving the stipple alignment.
Re: 128x192 with 4 levels compatible
Copy this into a HTML file and you have an encoder / decoder.
The JS code is quite basic and not optimized, so it's very simple to understand.
You can see it working here:
http://4throckworld.com/dev/128x192/
Of course, for better results it's better to start with images already converted to 4 levels.
The converter will only do straight brightness level mapping.
Attributes are completely ignored.
The JS code is quite basic and not optimized, so it's very simple to understand.
You can see it working here:
http://4throckworld.com/dev/128x192/
Of course, for better results it's better to start with images already converted to 4 levels.
The converter will only do straight brightness level mapping.
Attributes are completely ignored.
Code: Select all
<!DOCTYPE html>
<html>
<head>
<script>
function draw(img) {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
var Encode = function() {
for (var i = 0; i < data.length; i += 8) {
//get average value
var avg = (data[i] + data[i + 1] + data[i + 2] + data[i + 4] + data[i + 5] + data[i + 6]) / 6;
var lineNumber = Math.round( (i/4)/256 );
var oddLine = lineNumber % 2
// 00
if ( avg < 64) {var avg_a = 0 ; var avg_b = 0};
// 01
if ( (avg > 64) && (avg < 127) ) { if ( oddLine == 0 ) { var avg_a = 0 ; var avg_b = 255} else { avg_a = 255 ; avg_b = 0} };
// 10
if ( (avg > 127) && (avg < 191) ) { if ( oddLine == 0 ) { var avg_a = 255 ; var avg_b = 0} else { avg_a = 0 ; avg_b = 255} };
// 11
if ( avg > 191 ) { var avg_a = 255 ; var avg_b = 255};
data[i] = avg_a; // red
data[i + 1] = avg_a; // green
data[i + 2] = avg_a; // blue
//data[i + 3 ] = 255; // red
data[i + 4] = avg_b; // green
data[i + 5] = avg_b; // blue
data[i + 6] = avg_b; // green
//data[i + 7] = 255; // blue
}
ctx.putImageData(imageData, 0, 0);
};
var Decode = function() {
for (var i = 0; i < data.length; i += 8) {
//get average values of two consecutive pixels
var avg_a = (data[i] + data[i + 1] + data[i + 2] ) / 3;
var avg_b = (data[i + 4] + data[i + 5] + data[i + 6] ) /3;
var lineNumber = Math.round( (i/4)/256 );
var oddLine = lineNumber % 2
// 00
if ( (avg_a < 85) && (avg_b < 85) ) {avg = 0};
// 01
if ( (avg_a < 85) && (avg_b > 170) ) { if ( oddLine == 0 ) { avg = 85} else { avg = 170} };
// 10
if ( (avg_a > 170) && (avg_b < 85) ) { if ( oddLine == 0 ) { avg = 170} else { avg = 85} };
// 11
if ( (avg_a > 170) && (avg_b > 170) ) {avg = 255};
data[i] = avg; // red
data[i + 1] = avg; // green
data[i + 2] = avg; // blue
//data[i + 3 ] = 255; // red
data[i + 4] = avg; // green
data[i + 5] = avg; // blue
data[i + 6] = avg; // green
//data[i + 7] = 255; // blue
}
ctx.putImageData(imageData, 0, 0);
};
var Encodebtn = document.getElementById('Encodebtn');
Encodebtn.addEventListener('click', Encode);
var Decodebtn = document.getElementById('Decodebtn');
Decodebtn.addEventListener('click', Decode);
}
function handleImage(e){
var reader = new FileReader();
var img = new Image();
//img.src = 'heli.png';
reader.onload = function(event){
img.src = event.target.result;
img.onload = function() {
draw(this);
};
}
reader.readAsDataURL(e.target.files[0]);
}
function readImage() {
if ( this.files && this.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
//var img = new Image();
img.addEventListener("load", function() {
ctx.drawImage(img, 0, 0);
});
img.src = e.target.result;
};
FR.readAsDataURL( this.files[0] );
}
}
function pageLoaded() {
var imageLoader = document.getElementById('fileUpload');
imageLoader.addEventListener('change', handleImage);
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
}
</script>
</head>
<body onload = "pageLoaded();">
<label>Loads a 256x192 image.<br> Encodes / decodes a 192x192 4 bit level image using 1 bit dithering. <br>Bit order is reversed on each line for better visual quality on the undecoded image.</label><br/>
<hr>
<input type='file' id="fileUpload" />
<canvas id="canvas" width="256" height="192"></canvas>
<div>
<input id="Decodebtn" value="Decode" type="button">
<input id="Encodebtn" value="Encode" type="button">
</div>
</body>
</html>
-
- Microbot
- Posts: 170
- Joined: Tue Nov 28, 2017 7:39 am
Re: 128x192 with 4 levels compatible
Seems some of the video modes of machine ZX Prism from Jeff Braine
https://youtu.be/Jrge4HtnqPI
Minute 5.37
You can test it on ZEsarUX
https://youtu.be/Jrge4HtnqPI
Minute 5.37
You can test it on ZEsarUX