Closed GoogleCodeExporter closed 9 years ago
Prior discussion is on Issue 202.
A small note : It is impossible to write a generic constraint solver. I am sure
of
it, because even a specific constraint format (C64 FLI) has never been solved.
I
wrote a checker, but there are some pictures it can't solve if the user doesn't
give
hints to override its auto-detection. Even brute-force is not viable as it
would
take years for some pictures.
Mode 6 seems to go well with the "Enforcer" way of drawing idea, because every
pixel
is using either the line ink or the raster ink. With an enforcer system, this
is
what would happen wen you paint one pixel with a color different from the 2:
If the target pixel uses the line ink:
If the 96x1 block isn't using any raster ink:
You draw pixels with your selected color, which becomes the raster ink for this
block
Else
Replace the line ink for the whole line (recolor other pixels that use it)
End
Else (the target pixel uses the raster ink)
Replace the raster ink for the whole 96x1 block (recolor other pixels that use it)
End
Mode 5 can't be used with the Enforcer system, because the constraints are too
fuzzy
to be auto-detected from the current image.
For FLI, I made a prototype where the user interface was the following:
User sees his complete/final image in one layer. He draws directly and freely
on it,
with no constraints. He can break the limits.
When he wants to chek, he uses a keyboard shortcuts that solves the image (find
a
way to encode it). Some parts can't be be encoded if the limits are broken OR
if the
algorithm just didn't find a way, so these parts are modified into something
that
can be encoded (ie: some pixels change to a valid ink). The output is written
on a
opaque layer above the normal one, never directly on the user image. To find
the
problem areas, the user toggles this layer on and off. He fixes the areas by
modifying his original, and running rhe checker again. If/when both layers are
identical, it means the image is fully compliant.
Let me know if you think such a system would be viable. I didn't get much
feedback
from the C64 people so far (just a reminder guys... I don't know if I should
proceed
or try another approach)
Original comment by yrizoud
on 28 Apr 2010 at 10:15
Hi yrizoud, i have read your prior discussion about draw for retro systems.
Well, faced with the impossibility of a generic constraint solver, i think that
your
"Checker" is a great solution for the case of mode 5, of course it will need a
system
to define the constraints or permit to select from a list (hires bitmap, fli,
mode 5,
zx, ... ) to make the more flexible possible.
I am thinking now that it would be very helpful (i don't know if it's
possible), if
you could see in the palette which are the colours of the actually "raster
zone", at
the begining all the colours of all "raster zones" are the colour 0, and if you
plot
with a new colour, this colour is selected for this zone,... What do you think?
And of course, your "Enforcer" system is perfect for the mode 6.
Original comment by real.mml
on 28 Apr 2010 at 2:13
I would not use the palette to show raster boundaries, but instead use layers.
For
mode 2+rasters, it's easy : one layer is monochromatic (1 color per line or
transparency), the other below has the splits rasters.
Ideally, I'd like to make this 3 layers : one for the split-ink, one for the
raster
ink, and one for the pixel data. This can't be done with the current layer code
but
I'd like to add it. This would extend much better to a mode 1+raster system.
The
"pixel" layer would act as a selector between the colors in the others layers.
The
raster layers could also be small ones (8x200 pixels or so) and stretched up to
fit
the picture. Or they could simply be RLE-packed, saving a LOT of memory, when
not
used.
This is for the technical part, using this directly for drawing may or may not
be
practical. On one side it enforces the constraint, but on the other it makes it
painful to draw and not efficient. Drawing freely+running a check from time to
time
looks better. As the raster area are quite small (1 line * 96 pixels at most),
it's
easy to see which colors are used in each zone and build up the pixel+raster
data
from this. I'll try to think about a clever algorithm/data structure to do it
efficiently.
Original comment by pulkoma...@gmail.com
on 28 Apr 2010 at 5:10
How i said, your explanation using layers is perfectly logical, Adrien. Is
there
anything that i can make to help?
Original comment by real.mml
on 28 Apr 2010 at 8:48
Adrien, in the "memory repesentation", don't forget that mode 5 also has a
global
screen color. We could fill a complete layer to represent it. It sounds ugly,
but
shouldn't be a big problem after all, since it's a color you normally choose
early,
and then never modify anymore. Or we can store it as entry #27 of the palette :
If
colors 0-26 contain the totality of the CPC palette, Grafx2 can find which one
of
them has the same RGB values.
About the idea of "pixel layer that acts as a layer selector": I'm really
doubtful...
It changes a big fundamental of Grafx2, it's not helpful for the program (If
the C64
data must be maintained in memory, I prefer having two clean arrays line[200]
and
block[40][25]),it doesn't help you draw: Drawing in color 0 exposes layer 0,
drawing
in layer 1 expose layer 1 instead ? Argh!
When using pixels, at least we hide from the user the complexity of choosing if
a
raster line uses Red and Blue or Blue and Red.
Note that in many cases, the pictures don't use all colors. This makes encoding
difficult, because the algorithm should delay a choice until it becomes
necessary:
For example with FLI, in addition to the 16 colors, I use a 17th number to mean
"any". An encoder for "Mode 5" should use same system: After the global "BG"
color is
selected, if a given 96-pixel segment uses only 2 other colors, one should be
picked
as this segment's color, the remaining color should be set as the first line-color.
The second line-color, unused, should not be set to 0, it should stay
"available"
until one of the others 96-pixel segment requires it.
After a bit of thoughts on Mode 5, it doesn't seem difficult to auto-detect
encoding:
Choose BG (Usually, user chooses. In worst case, we can try with all 27 of
them.)
For each line
Enumerate colors used by each 96-pixel segment
For each segment that uses more > 2 colors in addition to BG
Count color usage
If none was found, repeat search with segment that uses > 1 color in addition to BG
Most used color becomes line color 1 (LC1[y])
For each segment that uses more than 1 colors in addition to BG and LC1[y]
Count color usage
Most used color becomes line color 2 (LC2[y])
For each segment
Current segment color (CSG) is initially marked 'unused'
Scan all pixels
If pixel color is BG, then this pixel uses BG
Else if pixel color is LC1[y], then this pixel uses LC1
Else if pixel color is LC2[y], then this pixel uses LC2
Else if CSG is unused, then CSG is this colr, and this pixel uses CSG
Else it's impossible to encode this perfectly, so choose between BG/LC1/LC2/CSG
Original comment by yrizoud
on 28 Apr 2010 at 11:24
>> Else it's impossible to encode this perfectly, so choose between
BG/LC1/LC2/CSG
Actually in my converter i choose from BG/LC1/LC2/CSG the color more similar,
calculating the Euclidean distance between the RGB values and taking the minor.
Original comment by real.mml
on 29 Apr 2010 at 8:13
We're not working with RGB that much. The goal for us is not to convert any
picture,
but drawings done with the computer in mind.
Yves, thrust me, that's how CPC graphists are working when they do raster
things.
The raster system in the CPC really adds an extra layer between the fixed
27-color
palette and the data you use for pixels. So it's all about picking 2, 4, or 16
colors for each screen area and see how you can make it fit all the
constraints. So
it makes sense to have this represented in some way in the program, and using a
layer is the more fitting way, I think.
Original comment by pulkoma...@gmail.com
on 29 Apr 2010 at 10:42
I have a hard time understanding what it would result for end-user, so if you
allow
me some questions :
As I understand it:
Layer 1: Completely filled with "the background color"
Layer 2: Horizontal lines (288x1) that represent Line color 1
Layer 3: Horizontal lines (288x1) that represent Line color 2
Layer 4: 96x1 segments that represent the "horizontal raster" color
Layer 5: Now this layer records the data that determines which of layer 1,2,3
or 4
is visible.
1) What does the user see on this layer? the final image, or a jumble of pixels
with
only values 1,2,3,4 ?
2) When the user picks a color from this layer, what "color" does it report? A
CPC
color, or 1 2 3 4 ?
3) When the user is pointing at a pixel with value 1 (BG color), and the BG
color is
0 (black) and he writes with color "2" what happens?
3A - 2 is the layer of "Line color 1", so this pixel is switched to Line Color 1
3B - 2 is light blue, the BG color becomes light blue
3C - 2 is light blue, grafx2 tries to make this pixel light blue but only if
doesn't
break any constraint and doesn't alter other pixels.
3D - 2 is light blue, grafx2 makes this pixel light blue, even if it causes a
change
on other pixels (at most, this can break the current 96x1 segment)
These questions are for the topmost layer. For the others, I assume that you
can
edit them only when the image is valid, and then:
- The drawing automatically "flood-fills" the relevant area : Layer 1: all
image,
Layer 2 and 3: current line, layer 4: current 96x1 block
- The final "image" is visually modified accordingly : Altering the BG will
recolor
all pixels that were using it.
Original comment by yrizoud
on 29 Apr 2010 at 2:09
The way I see it :
1) User sees the final image.
2) 1,2,3,4 (or actually 0,1,2,3)
3) A
This is how the CPC hardware is done :
a) There is a fixed 27 color choice
b) Depending on the mode, you can select 2, 4, or 16 colors from this. This is
done
by mapping an "ink" (0..26) to a "pen" (0..15)
c) to do rasters, you change this mapping in realtime while the CRTC is drawing
the
screen
So, it's "natural" to work with this in mind. The 5th layer would be the actual
pixel data of the CPC, with the rasters acting as something below it.
Usually a cpc graphist will work on the pixels in a classical drawing program,
and
build the rasters tables by hand. And then switch between the drawing and
running
the code to see the result. We could do the same, let's say, when hiding one of
the
raster layers, it would display as only one color and allow the graphist to see
the
pixel data, if he's lost in what he's doing.
Original comment by pulkoma...@gmail.com
on 29 Apr 2010 at 2:23
Then this can be done easily at the location as "Effects". This is where it's
easy
in Grafx2 to plug some code on each "putpixel" attempt. It's even possible to
use
the best of both worlds:
- When user paints with colors 0-26 : method C or D, WYSIWYG : paint blue, you
get
blue.
- When user paints with color 27-30 : method A. 27 means "Use global BG", 28
means "use Line color 1", etc.
Original comment by yrizoud
on 29 Apr 2010 at 4:12
Alternate idea of representation:
We could handle 2 separate layers for the "bitmap" (which selects pens 0-3) and
the "final result layer", which contains the image as the user will see it.
In the example of CPC mode 5:
Layer 1 : general BG (pen 0)
Layer 2 : horizontal raster (pen 1)
Layer 3 : horizontal raster (pen 2)
Layer 4 : split raster (pen 3)
Layer 5 : bitmap, contains only indices 0-3
Layer 6 : visual result
When you paint on layer 1: it fills the screen, and also alters layer 6,
depending
on the content of Layer 5.
When you paint on layer 2 or 3: it fills the line, and also alters layer 6,
depending on the content of Layer 5.
When you paint on layer 4: it fills the 96x1 segment (or somesuch), and also
alters
layer 6, depending on the content of Layer 5.
When you paint on layer 5: only pens 0-3 are accepted, and the result is
reported on
Layer 6
When you paint on layer 6: Only colors that are available on Layers 1 to 4 are
accepted. The Layers 5 and 6 are modified accordingly.
This system would have the smallest impact on the complexity of grafx2.
It allows free drawing (draw in Layer 6 in WYSIWIG, you can use the colorpicker
etc.)
The layer 5 can be viewed and edited individually - it alters the layer 6
instantly,
even if it's hidden. This layer 5 can be exported easily.
It also has the advantage that aside from the presets for specifics modes, we
can
allow a preset "free raster mode", where Grafx2 automatically adjusts to the
current
number of layers: Top layer is visual, top-1 is the bitmap, 0 to top-2 are the
raster. The user can "draw" all the rasters as he wants, it's his job to ensure
the
limitations are respected - and since he draws them on their own layer, it
should be
quite "visual" and easy.
Original comment by yrizoud
on 4 May 2010 at 1:01
Sounds nice, except the fact that altering 2 layers at once will make the
operation
quite heavy (we have to update 2 layers + the depth buffer + the undo pages).
Remember
an Amstrad CPC picture can be up to 730x256 pixels in mode 2, so a lot of
pixels to
move around.
Original comment by pulkoma...@gmail.com
on 4 May 2010 at 4:14
This extra cost happens once, on first click. Indeed in this case it's +50%. It
will
be as slow as when you click to draw on a 730x384 picture... IMO, not a problem.
I'm more concerned by the case where you draw on one of the raster layers, and
try to
enforce the "blocky" constraint (ex: fill a 8*8 block, fill a width*1 line, fill
everything...) The performance hit is unavoidable due to many pixels affected,
so it
can be excused, however the programming challenge is in the drawing limits:
Normally
grafx2 wouldn't let you draw on areas that are not displayed in the viewport.
This
makes display feedback easier, because every modified pixel can be sent to
screen
without risk of crashing. This mode requires an exception that requires a
rethinking
of that rule. (can we maintain the rule in normal cases without causing a
slowdown)
For simplicity's sake with this drawing in raster layers, I'm very tempted to
implement a new CURSOR that automatically appears as a filled rectangle that
matches
the current layer's restriction (and behaves as such when you click to draw).
Original comment by yrizoud
on 4 May 2010 at 7:02
I just uploaded a working experiment :
http://code.google.com/p/grafx2/downloads/detail?name=grafx2-2.3wip1476-win32.zi
p
It has hard-coded CPC mode 5 restrictions, so it's only for testing the drawing
model.
You can check with the attached image: when used in this version of grafx2, the
top
layer is not just 4-color, it uses the gradients used in layers 1-4.
You can draw in layers 1-4, it both follows the raster restriction (ie: fill the
relevant block/line/segment) and visually updates the pixels that were using
this color.
So layer 5 is internally a 4-color image, as you can see if you use the pipette
or
grab a brush.
Original comment by yrizoud
on 14 May 2010 at 7:30
Attachments:
Original comment by pulkoma...@gmail.com
on 9 Aug 2010 at 9:43
Original comment by pulkoma...@gmail.com
on 22 Aug 2010 at 1:40
Original comment by pulkoma...@gmail.com
on 13 Feb 2011 at 9:12
Updated the experiment :
http://code.google.com/p/grafx2/downloads/detail?name=grafx2-2.3wip1721_cpcmode5
-win32.zip
It is now possible to enable/disable the Mode5 mode in the effects screen.
There is some trouble when switching it on or off, as the picture needs to be
redrawn. If you switch to this mode before drawing anything it's fine, if you
swich with some things already drawn, bad things will happen. We'll need some
kind of converter, even if it is very basic and simple.
Other things I'm planning :
* More configurable settings ('mode 6', maybe Spectrum or MO5-like modes)
* Better display of what will happen when drawing on layer 5 (actual color in statusbar for example)
* Use of a special "palette" for 5th layer (do not show actual colors, but only 4 buttons to select ink 0 1 2 3).
Waiting for comments and sample pictures :)
Original comment by pulkoma...@gmail.com
on 14 Feb 2011 at 5:39
Ok, now merged in trunk !
Original comment by pulkoma...@gmail.com
on 19 Jun 2011 at 8:36
Original issue reported on code.google.com by
real.mml
on 27 Apr 2010 at 9:08Attachments: