| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
Unrestricted hires colour mode! (albeit just a *tiny* bit letterboxed..)
I've been spending a few weeks on and off experimenting with how sequences of hires pixels behave, and as something of a side effect I've reached a startling conclusion.
If you layer seven hires sprites over a multicolour sprite over a multicolour bitmap, with the just that final sprite set to a lower priority than the bitmap foreground colours, I'm pretty sure you can have a 24x1 pixel area of any pixel any colour.
It's easily done for a palette of 11 colours as so:
BBbbbbbbbbbbbbbbbbbbBBbb # background layer: two pixels from $d800 & $d802, rest from $d021
00112233445566778899 # MCM sprite layer. Note odd x-position -> half pixels peek out from under fg
ff ff ff ff ff ff # bitmap fg layer
s s s s s s # hires sprite layer. 's' where layer's always opaque, space where it is optional
So, any of the pixels whose x%4 is 0 or 1 can be any of the 7 hires colours or any of the three MCM sprite colours, or $d021
any pixels where x%4==2 can be any one of the 7 hires sprite colours (so ensure those 7 include the up to six represented here)
any pixels where x%4==3 are unrestricted
For 16 colours it's more complex. I have a algorithm that will deal with any sequence for which all sixteen colours are present in the first 16 pixels (ie the first 16 are just a permutation), which chooses from about 50 different layouts depending on the last 8 colours and where they can be found in the first 16.
I've yet to generalise to all 16^24 possibilities, but have also yet to find a sequence that cannot be represented. lp_solve and gprolog have both failed me, as they grind to a halt if I try to describe the general problem.
Would anyone care to prove me right or wrong about the general case being solvable (preferably with either an algorithm or a counter example)? I'm having trouble concentrating on anything else while this is still an open question.
Not sure whether this belongs in Coding or Pixeling; posting here because it's pretty impractical for artwork. Still, it's trivially stretchable to full screen height, so perhaps it would be good for a narrow area of vertical 'raster bars' :D |
|
... 25 posts hidden. Click here to view all posts.... |
| | chatGPZ
Registered: Dec 2001 Posts: 11386 |
you forgot "practically useless" =) |
| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
@Groepaz - I got as far as "pretty impractical" in the OP, but concur that that was something of an understatement :D |
| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
@Jammer I've had related thoughts myself.. The reversal in the official port's still a brilliant idea, mind. |
| | Digger
Registered: Mar 2005 Posts: 437 |
I can imagine having restrictionless twister upscroller using this mode if combined with FLI. Should be enough rastertime to push all the pixels, providing you'll somehow solve your LUTs ChristopherJam :) |
| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
@DGGR, pushing the pixels should be fine, however the palette is a different issue.
I've just implemented a solution finder, and I've discovered that while it's almost certainly safe to have a constant background colour and four constant hires sprite colours, I would still need to be able to change three hires sprite colours and all three sprite multicolours every line for complete freedom, and probably some $d800 colours as well - a minimum of 36 cycles, probably more like 42 or 48. Seeing as the sprite DMA alone would be taking 19 cycles per line, I can't see that working.
Enough 'difficult' colours in common between all the candidate lines for the upscroller and perhaps something could be done - it's getting a little far away from the original unrestricted concept, but would certainly make for a more interesting effect :)
ps - python 3's "yield from" is magical! |
| | Copyfault
Registered: Dec 2001 Posts: 478 |
What a nice thread ;)) @Ninja: thanks for pointing me to this one!
I think it's possible to "proof" that 24x1 unrestricted hires mode is possible - i.e. that any of the 16^24 pixel combination can be displayed. Maybe even more width is possible, but I don't have a complete reasoning for that atm. But first of all let's see if the basic idea works.
The 24x1 pixels can be divided into twelve 2x1-cells (with the same width as a usual multicolour pixel). Four of these cells sum up to a 8x1 pixel row each of which belonging to a char. If we denote the three chars by C1, C2, C3, the cells by 01,...,04 for each char and the colours in each cell by f1,f2 we have the following picture:
| C1 | C2 | C3 |
| 01 | 02 | 03 | 04 | 01 | 02 | 03 | 04 | 01 | 02 | 03 | 04 |
|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|
Assume we have (a priori) virtual layers: l0 as "background layer" and l1 as "foreground layer". In a first step, the occuring colours will be assigned to a certain layer; in a second step, both layer types will be constructed by means of what the vic is capable of.
Now let's assign the colours by the following rules:
1. for each cell check if f1=f2
-->> if this is true, assign f1 and f2 to l0
-->> the appropriate cell will not be considered in further checks
2. a) Sort the remaining cells by amount of occuring colours
2. b) Most often colour will be assigned to l1
2. c) all cells carrying this colours will not be considered in further checks
2. d) As long as there are remaining cells with same colours, repeat from 2.a)
3. For the remaining cells: arbitrarily assign colours to l0, l1
Worst case scenario is: all cells have different colours and there are exactly eight colours each of which occuring exactly 2 times.
In this case, check 1 doesn't do anything. Check 2 will find a maximum 2 -> two cells done
Now repeapt check 2 for the remaining 20 pixels:
least max >= no.of pixels/no.of colours = 20/15 = 1 + 5/20
-->> least max = 2 -> two cells done
etc.
Counting like this, the worst case would be that both cells that are "done" in each step have both colours f1 and f2 equal. In this case check 2 will end after looping 4 times and the remaining 4 cells will carry 8 different colours, i.e. every remaining pixel is individually coloured. By Rule 3 we arbitrarily assign them to l0 and l1.
Counting the total no. of colours in each layer, we find that for both the sum is 8. Adding the layers to the picture we now get
| C1 | C2 | C3 |
| 01 | 02 | 03 | 04 | 01 | 02 | 03 | 04 | 01 | 02 | 03 | 04 |
|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|f1f2|
|f1 f2 f1 f1 f2 f2 f1 f1 f1 f2 f2 f2| layer 0
| f2 f1 f2 f2 f1 f1 f2 f2 f2 f1 f1 f1 | layer 1
Now we have to construct the layers with the vic.
Layer 0 can be done using the Multicolour GFX-Mode:
| c1 | c2 | c3 |
| v1 | v0 | d8 |spr0| v1 | v0 | d8 |spr1| v1 | v0 | d8 | 00 |
00 is bgr colour, v1,v0 are the vram cols, d8 comes from colour ram and spr0, spr1 are the corresponding sprite colours of sprite0(=lowest priority) which will be set to multicolour mode. This way, each cell can have a unique "layer0"-colour.
For layer 1 we use all remaining sprites as hires sprites. As shown in the first step of the proof, we need eight different colours at most but there are only 7 sprites left. Now the shift trick of the OP comes into play: if we shift the multicolour sprite and utilize the sprite/bgr/gfx-priority handling of the vic, the third mc-colour can be misused to form a hires pixel "above" the v0-colour.
For example, a hires pixel done with this trick at pixel position c2,02,f1 would look like this:
| c1 | c2 | c3 |
| v1 | v0 | d8 |spr0| v1 | v0 | d8 |spr1| v1 | v0 | d8 | 00 | pure gfx data
| ssssssss ssss ssssssss | sprite0 data
|ss ss ss ss ss ss ss ss ss ss ss | data sprite1-7
This completes the proof; an algorithm should be easy to do based on this.
Am I forgetting something? Maybe the assumed "worst case" is not "worse enough"?
By some clever shifting of the "foreground layer" l1 and maybe by using x-expanded sprites throughout it should be possible to get some wider range. Do I smell a "Hardcore Coding Compo for senseless gfx modes" here ;)? |
| | ChristopherJam
Registered: Aug 2004 Posts: 1409 |
@Copyfault - I like your approach, and the reasoning seems pretty sound, from what I can follow. Only issue I can see is that the worst case scenario for your two layer abstraction actually needs nine colours for foreground layer. Cf
01 12 20 34 45 56 67 73 89 ab cd ef
The colours 0 to 2 form a ring of three, that need two foreground colours between them
The colours 3 to 7 form a ring of five, that need three foreground colours between them
The remaining eight colours need four foreground colours between them
I suspect this means your proof now falls down, as we now need all seven hires sprites and two of the MCM sprite colours just for the foreground colours, which doesn't leave enough MCM sprite colours to cover the two cells in the background layer that might not be coverable by d800, d021, and VM
The good news is, further randomised testing seems to indicate that only six hires sprites are needed for the frontmost layer, even in the scenario above. For example:
| , , , | , , , | , , ,f f| palette : f
| , , , | , ,7 7,7 7| ,b b, , | palettes: -,7,b
| , , , | , 6,6 , | a,a , e,e | palette : 6ae
| ,2 2,2 2,4 4|4 4,6 6, , |9 9, ,d d, | palettes: 24,46,9d
|0 1,1 , 0,3 | 5,5 , , 3|8 , ,c , | palette : 01358c
Alternately, if I hold $d021 constant at zero, I can colour thousands of randomised pixmaps (with either completely random pixels, or a permutation of arange(24)%16) without fail, as long as I allocate 7 hires sprites
As for wider ranges, I'm wondering how wide an area could be covered if the hires sprites were staggered. After all, even as is we could position each at the first x-position their colour is used. On top of that, it's starting to look like the seventh is currently unused.
Start the 'image' halfway through a character cell, and the first two and last two 2x1 cells have free range for their background, too. Could 32x1 be within our grasp? Who knows, or dares to dream..
Compo sounds hilarious :D |
| | Oswald
Registered: Apr 2002 Posts: 5094 |
the twister scroller idea is pretty good for this one, altho complicated, static lines can be precalculated into simple lda/sta code.
altho even if colorful I dont think it would look spectacular at 24x200, 3 chars wide at best. |
| | algorithm
Registered: May 2002 Posts: 705 |
Regardless of small width, it is still nice proof of concept. However, I feel that even with some restrictions in place, the difference in output at a wider width would be negligible dependant on how the converter creates the image and sprite definitions.
Have a look at the mucsu-fli mode for example, having full width FLI with sprites over 240 pixel range (albeit blocky) but underlaid with hires masking. Copyfault I believe updated the routine to work at full 200 vertical lines. |
| | Copyfault
Registered: Dec 2001 Posts: 478 |
Quoting ChristopherJam@Copyfault - I like your approach, and the reasoning seems pretty sound, from what I can follow. Only issue I can see is that the worst case scenario for your two layer abstraction actually needs nine colours for foreground layer. Cf
01 12 20 34 45 56 67 73 89 ab cd ef
The colours 0 to 2 form a ring of three, that need two foreground colours between them
The colours 3 to 7 form a ring of five, that need three foreground colours between them
The remaining eight colours need four foreground colours between them
I suspect this means your proof now falls down, as we now need all seven hires sprites and two of the MCM sprite colours just for the foreground colours, which doesn't leave enough MCM sprite colours to cover the two cells in the background layer that might not be coverable by d800, d021, and VM
Damn, processing your new worst case pixel sequence by the rules I suggested gives 9 necessary foreground colours just like you said.
But, the proof can be "repaired" (in a way;)). Instead of aligning the foreground layer with exactly three chars we move the layer 4 hires pixels to the right. As picture says more than 1000 words I'll put it into a table:
| C1 | C2 | C3 | C4 | chars
|--,--,v0,v1|v0,v1,bg,d8|v0,v1,bg,d8|v0,v1,--,--| l0: gfx
| , , , , , , ,s0,s0, , , | l0: spr0
|v0,v1,v0,v1,bg,d8,v0,v1,sp,d8,v0,v1| l0
| ,s1, , , , , , , , ,s2, | l1: spr0
| s, s, ,s , s, s, s,s , s,s , , s| l1: sp1-7
| s, s,1 ,s , s, s, s,s , s,s , 2, s| l1
The colours of spr0 are numbered s0,s1,s2 in order to show where the corresponding l1-colours reoccur. In the outer chars C1 and C4 the '--'-pixels can be coloured by $d800 (e.g. to create a frame or whatever design is wanted).
This way, we have 7 hires sprites (=7 l1-colours) + 2 mc-colours (=2 further l1-colours) = the needed 9 colours.
Hope there's no other worst case pixel sequence.
From a mathmatical point of view, it would be interesting to find out the minimum of needed l1-colours. When starting the proof, I first had the feeling that 6 colours would suffice, but up to now I still don't have the faintest idea for a formal argument. |
Previous - 1 | 2 | 3 | 4 - Next | |