Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2010-09

proposal for palette-related graph unit interface changes

12 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Nikolay Nikolov

Currently, the following palette-related things from the fpc graph unit aren't TP7 compatible:

MaxColors (constant)
PaletteType (record)

procedure SetAllPalette(const Palette: PaletteType);
procedure GetPalette(var Palette: PaletteType);
function GetPaletteSize: smallint;
procedure GetDefaultPalette(var Palette: PaletteType);

the most notable difference is the definition of PaletteType, which is defined as:

in fpc:

const
   MaxColors = 255;
type
   RGBRec = packed record
     Red, Green, Blue: smallint;
   end;
   PaletteType = record
     Size: longint;
     Colors: array [0..MaxColors] of RGBRec;
   end;

in TP7:

const
   MaxColors = 15;
type
   PaletteType = record
     Size: byte;
     Colors: array [0..MaxColors] of shortint;
   end;

so the main difference is that fpc's PaletteType represents a VGA 256 to RGB colour palette, while TP7's represents EGA's 16->64 palette. My proposal is to rename:

MaxColor -> RGBPaletteMaxColor
PaletteType -> RGBPaletteType
SetAllPalette -> SetAllRGBPalette
GetPalette -> GetAllRGBPalette
GetDefaultPalette -> GetDefaultRGBPalette
GetPaletteSize -> GetRGBPaletteSize (this one might be unnecessary - will have to check if GetPaletteSize already returns the same values as TP7; we might still introduce GetRGBPaletteSize for consistency with the other RGBPalette procedures/functions, though)

and then introduce TP7-compatible MaxColors, PaletteType and procedures/functions. They'll be made optionally hookable (so the go32v2 implementation will be able to implement them with the real EGA palette registers for maximum compatibility), with a default implementation that works on top of SetRGBPalette (similar to the way SetPalette is implemented now)

What do you think?

Reply by email

Jonas Maebe
to Nikolay Nikolov
Nikolay Nikolov wrote 8 lines
and then introduce TP7-compatible MaxColors, PaletteType and procedures/functions. They'll be made optionally hookable (so the go32v2 implementation will be able to implement them with the real EGA palette registers for maximum compatibility), with a default implementation that works on top of SetRGBPalette (similar to the way SetPalette is implemented now) What do you think?

How did the palette work in TP7 with the SVGA256 bgi driver?

Jonas

Reply by email

Florian Klaempfl
to Nikolay Nikolov: Currently, the following palette-related things from the fpc graph unit aren't TP7…
Nikolay Nikolov wrote 8 lines
and then introduce TP7-compatible MaxColors, PaletteType and procedures/functions. They'll be made optionally hookable (so the go32v2 implementation will be able to implement them with the real EGA palette registers for maximum compatibility), with a default implementation that works on top of SetRGBPalette (similar to the way SetPalette is implemented now) What do you think?

But this will break existing FPC code, right? I'am also not sure if the palettes as they are done were invented for other OSes e.g. Amiga or Atari

Reply by email

Nikolay Nikolov
to Florian Klaempfl
Florian Klaempfl wrote 11 lines
Am 15.09.2010 16:39, schrieb Nikolay Nikolov: > and then introduce TP7-compatible MaxColors, PaletteType and > procedures/functions. They'll be made optionally hookable (so the go32v2 > implementation will be able to implement them with the real EGA palette > registers for maximum compatibility), with a default implementation that > works on top of SetRGBPalette (similar to the way SetPalette is > implemented now) > > What do you think? But this will break existing FPC code, right? I'am also not sure if the palettes as they are done were invented for other OSes e.g. Amiga or Atari

Yes, it'll break existing FPC code (but will also improve TP7 compatibility), that's why I want to discuss it with you, before making these changes. Regarding Amiga and Atari - I already checked: Atari doesn't seem to have a graph unit implementation; Amiga defines it's own PaletteType and does not include graphh.inc at all, so it should not be affected by the the other platforms use the palettes in graphh.inc and will be affected. Yes, existing fpc code will have to be fixed, but I suspect in most cases it would be doable with a simple find/replace, because we'll keep all the current VGA palette functionality, it'll only have different names.

Reply by email

Nikolay Nikolov
to Jonas Maebe: How did the palette work in TP7 with the SVGA256 bgi driver? Jonas
Jonas Maebe wrote 13 lines
On 15 Sep 2010, at 16:39, Nikolay Nikolov wrote: > and then introduce TP7-compatible MaxColors, PaletteType and > procedures/functions. They'll be made optionally hookable (so the > go32v2 implementation will be able to implement them with the real > EGA palette registers for maximum compatibility), with a default > implementation that works on top of SetRGBPalette (similar to the way > SetPalette is implemented now) > > What do you think? How did the palette work in TP7 with the SVGA256 bgi driver?

I don't know, I haven't checked yet. Which SVGA256.bgi driver do you mean? The Jordan Hargraphix driver? If it has any special behaviour, it can be recreated also, as long as we have a TP7-compatible graph unit interface.

Reply by email

Tomas Hajny
to Nikolay Nikolov: Currently, the following palette-related things from the fpc graph unit aren't TP7…
Nikolay Nikolov wrote 10 lines
Currently, the following palette-related things from the fpc graph unit aren't TP7 compatible: MaxColors (constant) PaletteType (record) procedure SetAllPalette(const Palette: PaletteType); procedure GetPalette(var Palette: PaletteType); function GetPaletteSize: smallint; procedure GetDefaultPalette(var Palette: PaletteType);

.
.

Show quoted text 13 lines
so the main difference is that fpc's PaletteType represents a VGA 256 to RGB colour palette, while TP7's represents EGA's 16->64 palette. My proposal is to rename: MaxColor -> RGBPaletteMaxColor PaletteType -> RGBPaletteType SetAllPalette -> SetAllRGBPalette GetPalette -> GetAllRGBPalette GetDefaultPalette -> GetDefaultRGBPalette GetPaletteSize -> GetRGBPaletteSize (this one might be unnecessary - will have to check if GetPaletteSize already returns the same values as TP7; we might still introduce GetRGBPaletteSize for consistency with the other RGBPalette procedures/functions, though)

.
.

Regardless of outcomes of discussion whether some change would be appropriate at all or not, I believe that it may be better not to rename the existing procedures and functions using the PaletteType but rather provide overloaded versions of those calls.

Tomas

Reply by email

Nikolay Nikolov
to Tomas Hajny
Tomas Hajny wrote 33 lines
On Wed, September 15, 2010 16:39, Nikolay Nikolov wrote: > Currently, the following palette-related things from the fpc graph > unit aren't TP7 compatible: > > MaxColors (constant) > PaletteType (record) > > procedure SetAllPalette(const Palette: PaletteType); > procedure GetPalette(var Palette: PaletteType); > function GetPaletteSize: smallint; > procedure GetDefaultPalette(var Palette: PaletteType); . . > so the main difference is that fpc's PaletteType represents a VGA 256 to > RGB colour palette, while TP7's represents EGA's 16->64 palette. My > proposal is to rename: > > MaxColor -> RGBPaletteMaxColor > PaletteType -> RGBPaletteType > SetAllPalette -> SetAllRGBPalette > GetPalette -> GetAllRGBPalette > GetDefaultPalette -> GetDefaultRGBPalette > GetPaletteSize -> GetRGBPaletteSize (this one might be unnecessary - > will have to check if GetPaletteSize already returns the same values as > TP7; we might still introduce GetRGBPaletteSize for consistency with the > other RGBPalette procedures/functions, though) . . Regardless of outcomes of discussion whether some change would be appropriate at all or not, I believe that it may be better not to rename the existing procedures and functions using the PaletteType but rather provide overloaded versions of those calls.

This could work for some of the functions, but not all of them. The problematic one is SetAllPalette, which is defined in TP7 as:

procedure SetAllPalette(var Palette);

which is, unfortunately, very evil, because it won't catch the error at compile time if you pass the wrong type :(

But it might not be necessary to introduce it exactly like that. Using a typed variable will probably work with 99.9% of the TP7 code?

Reply by email

Tomas Hajny
to Nikolay Nikolov
Nikolay Nikolov wrote 46 lines
On 09/15/2010 06:27 PM, Tomas Hajny wrote: > On Wed, September 15, 2010 16:39, Nikolay Nikolov wrote: >> Currently, the following palette-related things from the fpc graph >> unit aren't TP7 compatible: >> >> MaxColors (constant) >> PaletteType (record) >> >> procedure SetAllPalette(const Palette: PaletteType); >> procedure GetPalette(var Palette: PaletteType); >> function GetPaletteSize: smallint; >> procedure GetDefaultPalette(var Palette: PaletteType); > . > . >> so the main difference is that fpc's PaletteType represents a VGA 256 >> to >> RGB colour palette, while TP7's represents EGA's 16->64 palette. My >> proposal is to rename: >> >> MaxColor -> RGBPaletteMaxColor >> PaletteType -> RGBPaletteType >> SetAllPalette -> SetAllRGBPalette >> GetPalette -> GetAllRGBPalette >> GetDefaultPalette -> GetDefaultRGBPalette >> GetPaletteSize -> GetRGBPaletteSize (this one might be unnecessary - >> will have to check if GetPaletteSize already returns the same values as >> TP7; we might still introduce GetRGBPaletteSize for consistency with >> the >> other RGBPalette procedures/functions, though) > . > . > > Regardless of outcomes of discussion whether some change would be > appropriate at all or not, I believe that it may be better not to rename > the existing procedures and functions using the PaletteType but rather > provide overloaded versions of those calls. This could work for some of the functions, but not all of them. The problematic one is SetAllPalette, which is defined in TP7 as: procedure SetAllPalette(var Palette); which is, unfortunately, very evil, because it won't catch the error at compile time if you pass the wrong type :( But it might not be necessary to introduce it exactly like that. Using a typed variable will probably work with 99.9% of the TP7 code?

I'd assume so; even if not, simple typecast in the TP7 code would be sufficient to make it to work which should be an acceptable limitation (no need to change the logic or so).

Note that even having one version specifying the RGB type and the other defined the same way as in TP7 seems to compile with FPC and should be still compatible to both existing TP7 and FPC code, because FPC always requires to specify the type currently (and having the type specified should always result in selection of the typed version) whereas the TP7 code would be just as dangerous as with real TP7.

Tomas

Reply by email

Nikolay Nikolov
to Jonas Maebe: How did the palette work in TP7 with the SVGA256 bgi driver? Jonas
Jonas Maebe wrote 13 lines
On 15 Sep 2010, at 16:39, Nikolay Nikolov wrote: > and then introduce TP7-compatible MaxColors, PaletteType and > procedures/functions. They'll be made optionally hookable (so the > go32v2 implementation will be able to implement them with the real > EGA palette registers for maximum compatibility), with a default > implementation that works on top of SetRGBPalette (similar to the way > SetPalette is implemented now) > > What do you think? How did the palette work in TP7 with the SVGA256 bgi driver?

Ok, I tested Jordan Hargraphix' SVGA256.BGI (the file header says: "SVGA256 BGI Device Driver (SVGA256) 3.2 - Aug 23, 1994 Copyright (c) 1990-94 by Jordan Hargraphix").

SetRGBPalette works like it should, e.g. SetRGBPalette(0, 63, 0, 0) modifies the background color to red.

GetPaletteSize returns 0.

GetPalette(var Palette: PaletteSize)
returns Palette.Size = 0 and Palette.Colors filled with (seemingly) random values: (0, 0, 0, 0, 0, 64, 1, 64, 1, -57, 0, 0, 0, 0, 0, 8). These values are always the same between different runs of the program, but change when going to a different 256-colour mode (e.g. these were from 320x200x256; in 640x480x256, they are different, but still nonsense)

GetDefaultPalette returns the exact same nonsense palette like GetPalette.

SetPalette does not have any visual effect, but the "palette registers" that you've modified are reflected in the palette, returned by GetPalette; e.g. if you do:

SetPalette(0, 5);

the displayed image doesn't change at all, but after that GetPalette returns:
Palette.Size = 0
Palette.Colors = (5, 0, 0, 0, 0, 64, 1, 64, 1, -57, 0, 0, 0, 0, 0, 8)

while GetDefaultPalette continues to return:
Palette.Size = 0
Palette.Colors = (0, 0, 0, 0, 0, 64, 1, 64, 1, -57, 0, 0, 0, 0, 0, 8)

SetAllPalette also doesn't modify the displayed colors, but still "records" the "modified" palette entries:

for example, if you call SetAllPalette with:

Palette.Size = 8;
Palette.Colors = (1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0)

then GetPalette returns:

Palette.Size = 0;
Palette.Colors = (1, 2, 3, 4, 5, 6, 7, 8, 1, -57, 0, 0, 0, 0, 0, 8)

So obviously SetAllPalette respects the .Size, but still does nothing to the actually displayed colours :)

To summarize, all the EGA palette functions seem to be meaningless in 256-colour modes. Only the RGB palette functions work, which in TP7's case is actually only one function: SetRGBPalette

Reply by email

Nikolay Nikolov
to Nikolay Nikolov: Currently, the following palette-related things from the fpc graph unit aren't TP7…
Nikolay Nikolov wrote 6 lines
Currently, the following palette-related things from the fpc graph unit aren't TP7 compatible: ... What do you think?

There are also 2 other palette-related incompatibilities, that I'd also like to fix. They're relatively independent from the PaletteType/RGBPaletteType issue.

1. SetRGBPalette's range of values for RedValue, GreenValue and BlueValue is 0..63 in TP7 and 0..255 in FPC. So to set the background to bright red, in TP7 you would use:

SetRGBPalette(0, 63, 0, 0)

but this would set it to only dark red in FPC, where you have to use:

SetRGBPalette(0, 255, 0, 0)

this could be supported with a global boolean variable, that enables or disables the extended DAC range. E.g:

ExtendedRGBPaletteRange := true; { use 0..255 range }
ExtendedRGBPaletteRange := false; { use 0..63 range }

This can be implemented without any change to the platform-specific drivers, i.e. TModeInfo.SetRGBPalette and TModeInfo.GetRGBPalette will continue to only support the range 0..255 and not care about the ExtendedRGBPaletteRange flag. However, we'll add new front-end wrapper functions, that'll check the flag and convert the data, if necessary, before calling the internal Set/GetRGBPalette functions:

procedure SetRGBPalette(ColorNum, RedValue, GreenValue, BlueValue:
smallint);
begin
   if not ExtendedRGBPaletteRange then
   begin
     RedValue := (RedValue and 63) shl 2;
     GreenValue := (RedValue and 63) shl 2;
     BlueValue := (RedValue and 63) shl 2;
   end;
   InternalSetRGBPalette(ColorNum, RedValue, GreenValue, BlueValue);
end;

2. The second one's trickier and affects SetRGBPalette in 16-colour modes. In FPC, to set the RGB palette value of a colour number ColorNum (in [0..15]) you simply use:

SetRGBPalette(ColorNum, R, G, B)

in TP7, you have to do something like:

SetRGBPalette(DefaultEGAPalette[ColorNum], R, G, B)

where DefaultEGAPalette is (0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63) for most EGA/VGA and VESA 16-colour modes, with the exception of modes 0Dh - 320x200x16 (not supported by BGI or FPC as of now) and 0Eh - 640x200x16 (supported by both BGI and FPC - driver VGA, mode VGALo), where DefaultEGAPalette is (0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23). These EGA palettes can be obtained in TP7, using GetDefaultPalette or GetPalette. You can also decide to combine SetPalette and SetRGBPalette to produce all sorts of tricks.

This could also be emulated in front-end wrapper functions and we could also add a flag to turn the EGA palettes off, but the code would be trickier.

Reply by email

Florian Klaempfl
to Nikolay Nikolov: Yes, it'll break existing FPC code (but will also improve TP7 compatibility), that's why…
Nikolay Nikolov wrote 15 lines
On 09/15/2010 05:48 PM, Florian Klaempfl wrote: > Am 15.09.2010 16:39, schrieb Nikolay Nikolov: >> and then introduce TP7-compatible MaxColors, PaletteType and >> procedures/functions. They'll be made optionally hookable (so the go32v2 >> implementation will be able to implement them with the real EGA palette >> registers for maximum compatibility), with a default implementation that >> works on top of SetRGBPalette (similar to the way SetPalette is >> implemented now) >> >> What do you think? > But this will break existing FPC code, right? I'am also not sure if the > palettes as they are done were invented for other OSes e.g. Amiga or > Atari Yes, it'll break existing FPC code (but will also improve TP7 compatibility),

I guess most people depend now on FPC compatibility so I'd prefer to leave it as it is.

Reply by email

Nikolay Nikolov
to Florian Klaempfl
Florian Klaempfl wrote 19 lines
Am 15.09.2010 17:05, schrieb Nikolay Nikolov: > On 09/15/2010 05:48 PM, Florian Klaempfl wrote: >> Am 15.09.2010 16:39, schrieb Nikolay Nikolov: >>> and then introduce TP7-compatible MaxColors, PaletteType and >>> procedures/functions. They'll be made optionally hookable (so the go32v2 >>> implementation will be able to implement them with the real EGA palette >>> registers for maximum compatibility), with a default implementation that >>> works on top of SetRGBPalette (similar to the way SetPalette is >>> implemented now) >>> >>> What do you think? >> But this will break existing FPC code, right? I'am also not sure if the >> palettes as they are done were invented for other OSes e.g. Amiga or >> Atari > Yes, it'll break existing FPC code (but will also improve TP7 > compatibility), I guess most people depend now on FPC compatibility so I'd prefer to leave it as it is.

Ok then, what about adding the ExtendedRGBPaletteRange (or some similar name - BGICompatibleRGBPaletteRange?) global variable, that allows using 0..63 range in SetRGBPalette, when set to false (or true, if it's called BGICompatibleRGBPaletteRange)? We can still make FPC compatibility (0..255) the default, so existing FPC applications won't break and TP7 applications would be able to easily enable the TP7-compatible range 0..63. At least in the case of 256-colour modes (SVGA256.bgi) this means pretty much 100% TP7 palette compatibility (when porting code from TP7 to FPC, all the other palette differences only affect 16-colour modes, because TP7's PaletteType, SetPalette, SetAllPalette, etc. have no effect in 256-colour modes).

Reply by email