Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AGS 4: color properties have alpha component #2648

Merged
7 changes: 6 additions & 1 deletion Common/ac/game_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ Palette component range changed from 64 to 256
Font file names
4.0.0.11:
Incremented version, marking sync with 3.6.2.3
4.0.0.13:
Room names are always serialized, not just in Debug config (had to adjust format)
4.0.0.14:
Obligatory alpha component in 32-bit color. SCR_COLOR_TRANSPARENT is redefined as 0.
*/

enum GameDataVersion
Expand All @@ -155,8 +159,9 @@ enum GameDataVersion
kGameVersion_400_10 = 4000010,
kGameVersion_400_11 = 4000011,
kGameVersion_400_13 = 4000013,
kGameVersion_400_14 = 4000014,
kGameVersion_LowSupported = kGameVersion_360_21,
kGameVersion_Current = kGameVersion_400_13
kGameVersion_Current = kGameVersion_400_14
};

// Data format version of the loaded game
Expand Down
1 change: 1 addition & 0 deletions Common/ac/gamesetupstructbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ const char *GetScriptAPIName(ScriptAPIVersion v)
case kScriptAPI_v399: return "3.99.x";
case kScriptAPI_v400: return "4.0.0-alpha8";
case kScriptAPI_v400_07: return "4.0.0-alpha12";
case kScriptAPI_v400_14: return "4.0.0-alpha18";
default: return "unknown";
}
}
3 changes: 2 additions & 1 deletion Common/ac/gamestructdefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ enum ScriptAPIVersion
kScriptAPI_v399 = 3990000,
kScriptAPI_v400 = 4000003,
kScriptAPI_v400_07 = 4000007,
kScriptAPI_Current = kScriptAPI_v400_07
kScriptAPI_v400_14 = 4000014,
kScriptAPI_Current = kScriptAPI_v400_14
};

const char *GetScriptAPIName(ScriptAPIVersion v);
Expand Down
28 changes: 19 additions & 9 deletions Common/game/main_game_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,24 +319,33 @@ static const uint8_t RGBScale6[64]
// Remaps color number from legacy to new format:
// * palette index in 8-bit game,
// * encoded 32-bit A8R8G8B8 in 32-bit game.
static int RemapFromLegacyColourNumber(const GameSetupStruct &game, int color)
static int RemapFromLegacyColourNumber(const GameSetupStruct &game, int color, bool is_bg = false)
{
if (game.color_depth == 1)
return color; // keep palette index

// Special 0-31 color numbers were always interpreted as palette indexes;
// for them we compose a 32-bit xRGB from the palette entry
// Special color number 0 is treated depending on its purpose:
// * background color becomes fully transparent;
// * foreground color becomes opaque black
if (color == 0)
{
return is_bg ? 0 : (0 | (0xFF << 24));
}

// Special color numbers 1-31 were always interpreted as palette indexes;
// for them we compose a 32-bit ARGB from the palette entry
if (color >= 0 && color < 32)
{
const RGB &rgb = game.defpal[color];
return rgb.b | (rgb.g << 8) | (rgb.r << 16);
return rgb.b | (rgb.g << 8) | (rgb.r << 16) | (0xFF << 24);
}

// The rest is a R5G6B5 color; we convert it to a proper 32-bit xRGB
// The rest is a R5G6B5 color; we convert it to a proper 32-bit ARGB;
// color is always opaque when ported from legacy projects
uint8_t red = RGBScale5[(color >> 11) & 0x1f];
uint8_t green = RGBScale6[(color >> 5) & 0x3f];
uint8_t blue = RGBScale5[(color) & 0x1f];
return blue | (green << 8) | (red << 16);
return blue | (green << 8) | (red << 16) | (0xFF << 24);
}

void UpgradeGame(GameSetupStruct &game, GameDataVersion data_ver)
Expand Down Expand Up @@ -415,8 +424,9 @@ void UpgradeGUI(GameSetupStruct &game, LoadedGameEntities &ents, GameDataVersion
{
for (auto &gui : ents.Guis)
{
gui.BgColor = RemapFromLegacyColourNumber(game, gui.BgColor);
gui.FgColor = RemapFromLegacyColourNumber(game, gui.FgColor);
gui.BgColor = RemapFromLegacyColourNumber(game, gui.BgColor, true);
gui.FgColor = RemapFromLegacyColourNumber(game, gui.FgColor, !gui.IsTextWindow()
/* right, treat border as background for normal gui */);
}

for (auto &btn : ents.GuiControls.Buttons)
Expand All @@ -432,7 +442,7 @@ void UpgradeGUI(GameSetupStruct &game, LoadedGameEntities &ents, GameDataVersion
for (auto &list : ents.GuiControls.ListBoxes)
{
list.TextColor = RemapFromLegacyColourNumber(game, list.TextColor);
list.SelectedBgColor = RemapFromLegacyColourNumber(game, list.SelectedBgColor);
list.SelectedBgColor = RemapFromLegacyColourNumber(game, list.SelectedBgColor, true);
list.SelectedTextColor = RemapFromLegacyColourNumber(game, list.SelectedTextColor);
}

Expand Down
11 changes: 2 additions & 9 deletions Common/gfx/allegrobitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,18 +540,11 @@ void Bitmap::SetScanLine(int index, unsigned char *data, int data_size)
namespace BitmapHelper
{

int AGSColorToBitmapColor(int color, int color_depth)
int AGSColorToBitmapColor(int color, int /*color_depth*/)
{
// no conversion necessary, we assume that "ags color" is matching
// palette index in 8-bit mode and 32-bit A8R8G8B8 in 32-bit mode
if (color_depth == 8)
{
return color;
}
else
{
return color | 0xFF000000; // temporary fix for missing alpha in color values
}
return color;
}

void AGSColorToRGB(int color, int color_depth, RGB &rgb)
Expand Down
2 changes: 1 addition & 1 deletion Common/gui/guibutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ void GUIButton::ReadFromFile(Stream *in, GuiVersion gui_version)
TextAlignment = (FrameAlignment)in->ReadInt32();

if (TextColor == 0)
TextColor = 16;
TextColor = 16; // FIXME: adjust this using GetStandardColor where is safe to access GuiContext
_currentImage = _image;
}

Expand Down
2 changes: 1 addition & 1 deletion Common/gui/guilabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void GUILabel::ReadFromFile(Stream *in, GuiVersion gui_version)
TextAlignment = (FrameAlignment)in->ReadInt32();

if (TextColor == 0)
TextColor = 16;
TextColor = 16; // FIXME: adjust this using GetStandardColor where is safe to access GuiContext

_textMacro = GUI::FindLabelMacros(Text);
}
Expand Down
6 changes: 3 additions & 3 deletions Common/gui/guilistbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ GUIListBox::GUIListBox()
TextColor = 0;
SelectedTextColor = 7;
ListBoxFlags = kListBox_DefFlags;
SelectedBgColor = 16;
SelectedBgColor = 16; // FIXME: adjust this using GetStandardColor where is safe to access GuiContext
TextAlignment = kHAlignLeft;

_scEventCount = 1;
Expand Down Expand Up @@ -187,7 +187,7 @@ void GUIListBox::Draw(Bitmap *ds, int x, int y)
if (item + TopItem == SelectedItem)
{
text_color = ds->GetCompatibleColor(SelectedTextColor);
if (SelectedBgColor > 0)
if (SelectedBgColor != 0)
{
int stretch_to = (x + width) - pixel_size;
// draw the SelectedItem item bar (if colour not transparent)
Expand Down Expand Up @@ -376,7 +376,7 @@ void GUIListBox::ReadFromFile(Stream *in, GuiVersion gui_version)
}

if (TextColor == 0)
TextColor = 16;
TextColor = 16; // FIXME: adjust this using GetStandardColor where is safe to access GuiContext

// Reset dynamic values
RowHeight = 0;
Expand Down
5 changes: 3 additions & 2 deletions Common/gui/guimain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,9 @@ void GUIMain::DrawSelf(Bitmap *ds)

set_our_eip(376);
// stop border being transparent, if the whole GUI isn't
// FIXME: don't do this in DrawSelf, fix properties when they are set!
if ((FgColor == 0) && (BgColor != 0))
FgColor = 16;
FgColor = GUI::GetStandardColor(16);

if (BgColor != 0)
ds->Fill(ds->GetCompatibleColor(BgColor));
Expand Down Expand Up @@ -825,7 +826,7 @@ int GetStandardColor(int index)
index = 0;
if (Context.GameColorDepth == 8)
return index;
return GuiContext::StandardColors[index];
return GuiContext::StandardColors[index] | (0xFF << 24);
}

int GetStandardColorForBitmap(int index)
Expand Down
2 changes: 2 additions & 0 deletions Common/gui/guimain.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ struct GuiContext
// Last selected inventory item's pic
int InventoryPic = -1;

// Standard colors are used as defaults if no user setting exists;
// all of them are fully opaque RGBs.
const static int MaxStandardColors = 32;
const static int StandardColors[MaxStandardColors];
};
Expand Down
2 changes: 1 addition & 1 deletion Common/gui/guitextbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void GUITextBox::ReadFromFile(Stream *in, GuiVersion gui_version)
TextBoxFlags = in->ReadInt32();

if (TextColor == 0)
TextColor = 16;
TextColor = 16; // FIXME: adjust this using GetStandardColor where is safe to access GuiContext
}

void GUITextBox::ReadFromSavegame(Stream *in, GuiSvgVersion svg_ver)
Expand Down
3 changes: 2 additions & 1 deletion Editor/AGS.Editor/AGSEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ public class AGSEditor : IAGSEditorDirectories
* Settings.ScriptCompiler as a selection of script compiler IDs,
* ExtendedCompiler is deprecated.
* 4.00.00.12 - ViewFrame.Flip has full flip selection.
* 4.00.00.14 - Obligatory alpha component in 32-bit color.
*
*/
public const int LATEST_XML_VERSION_INDEX = 4000012;
public const int LATEST_XML_VERSION_INDEX = 4000014;
/// <summary>
/// XML version index on the release of AGS 4.0.0, this constant be used to determine
/// if upgrade of Rooms/Sprites/etc. to new format have been performed.
Expand Down
10 changes: 5 additions & 5 deletions Editor/AGS.Editor/Resources/agsdefns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@
#define OPT_SAVECOMPONENTSIGNORE 55
#define OPT_LIPSYNCTEXT 99

#define COLOR_TRANSPARENT -1
#define DIALOG_PARSER_SELECTED -3053
#define COLOR_TRANSPARENT 0
#define SCR_NO_VALUE 31998 // $AUTOCOMPLETEIGNORE$

#define DIALOG_PARSER_SELECTED -3053
#define RUN_DIALOG_RETURN -1
#define RUN_DIALOG_STOP_DIALOG -2
#define RUN_DIALOG_GOTO_PREVIOUS -4

#define SCR_NO_VALUE 31998 // $AUTOCOMPLETEIGNORE$

#ifdef SCRIPT_API_v399
#define AXIS_DEFAULT_DEADZONE 0.125
#endif // SCRIPT_API_v399
Expand Down Expand Up @@ -743,7 +743,7 @@ builtin managed struct ViewFrame {

builtin managed struct DrawingSurface {
/// Clears the surface to the specified colour, or transparent if you do not specify a colour.
import void Clear(int colour=-SCR_NO_VALUE);
import void Clear(int colour=COLOR_TRANSPARENT);
/// Creates a copy of the surface.
import DrawingSurface* CreateCopy();
/// Draws a circle onto the surface with its centre at (x,y).
Expand Down
49 changes: 36 additions & 13 deletions Editor/AGS.Editor/Tasks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,10 @@ private void SetDefaultValuesForNewFeatures(Game game)
{
RemapLegacyColourProperties(game);
}
else if (xmlVersionIndex < 4000014)
{
RemapOpaqueColourProperties(game);
}

// Update ScriptCompiler selection
if (xmlVersionIndex < 3999900)
Expand Down Expand Up @@ -617,14 +621,16 @@ private string RemoveAllLeadingSpacesFromLines(string script)
return returnValue;
}

private delegate int RemapColourProperty(int color, bool isBackgroundColor = false);

/// <summary>
/// Remaps all color properties in game from old color depth to a new color depth;
/// for example: from palette mode to 32-bit mode, or other way.
/// </summary>
public static void RemapColourPropertiesOnDepthChange(Game game, GameColorDepth oldColorDepth)
{
Func<int, int> remapColor = (color) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperties(game, remapColor);
RemapColourProperty remapColor = (color, isBg) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperties(game, remapColor );
}

/// <summary>
Expand All @@ -633,7 +639,7 @@ public static void RemapColourPropertiesOnDepthChange(Game game, GameColorDepth
/// </summary>
public static void RemapCharacterColours(Character character, Game game, GameColorDepth oldColorDepth)
{
Func<int, int> remapColor = (color) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperty remapColor = (color, isBg) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperties(character, remapColor);
}

Expand All @@ -643,7 +649,7 @@ public static void RemapCharacterColours(Character character, Game game, GameCol
/// </summary>
public static void RemapGUIColours(GUI gui, Game game, GameColorDepth oldColorDepth)
{
Func<int, int> remapColor = (color) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperty remapColor = (color, isBg) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperties(gui, remapColor);
}

Expand All @@ -653,7 +659,7 @@ public static void RemapGUIColours(GUI gui, Game game, GameColorDepth oldColorDe
/// </summary>
public static void RemapGUIColours(GUIControl guiControl, Game game, GameColorDepth oldColorDepth)
{
Func<int, int> remapColor = (color) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperty remapColor = (color, isBg) => { return ColorMapper.RemapColourNumberToDepth(color, game.Palette, game.Settings.ColorDepth, oldColorDepth); };
RemapColourProperties(guiControl, remapColor);
}

Expand All @@ -662,14 +668,31 @@ public static void RemapGUIColours(GUIControl guiControl, Game game, GameColorDe
/// </summary>
private static void RemapLegacyColourProperties(Game game)
{
Func<int, int> remapColor = (color) => { return ColorMapper.RemapFromLegacyColourNumber(color, game.Palette, game.Settings.ColorDepth); };
RemapColourProperty remapColor = (color, isBg) => {
return ColorMapper.RemapFromLegacyColourNumber(color, game.Palette, game.Settings.ColorDepth, isBg);
};
RemapColourProperties(game, remapColor);
}

/// <summary>
/// Remaps 32-bit RGB color number to proper 32-bit ARGB.
/// This method has a nuance: the background colors of value 0 are treated as "transparent",
/// while foreground colors of value 0 are treated as "black".
/// </summary>
private static void RemapOpaqueColourProperties(Game game)
{
RemapColourProperty remapColor = (color, isBg) => {
if (isBg && (color == 0))
return 0;
return ColorMapper.MakeOpaque(color, game.Settings.ColorDepth);
};
RemapColourProperties(game, remapColor);
}

/// <summary>
/// Remaps all color properties in game using provided delegate.
/// </summary>
private static void RemapColourProperties(Game game, Func<int, int> remapColor)
private static void RemapColourProperties(Game game, RemapColourProperty remapColor)
{
var settings = game.Settings;
settings.InventoryHotspotMarkerCrosshairColor = remapColor(settings.InventoryHotspotMarkerCrosshairColor);
Expand All @@ -686,18 +709,18 @@ private static void RemapColourProperties(Game game, Func<int, int> remapColor)
}
}

private static void RemapColourProperties(Character character, Func<int, int> remapColor)
private static void RemapColourProperties(Character character, RemapColourProperty remapColor)
{
character.SpeechColor = remapColor(character.SpeechColor);
}

private static void RemapColourProperties(GUI gui, Func<int, int> remapColor)
private static void RemapColourProperties(GUI gui, RemapColourProperty remapColor)
{
gui.BackgroundColor = remapColor(gui.BackgroundColor);
gui.BackgroundColor = remapColor(gui.BackgroundColor, isBackgroundColor: true);
if (gui is NormalGUI)
{
var ngui = gui as NormalGUI;
ngui.BorderColor = remapColor(ngui.BorderColor);
ngui.BorderColor = remapColor(ngui.BorderColor, isBackgroundColor: true);
}
else if (gui is TextWindowGUI)
{
Expand All @@ -712,7 +735,7 @@ private static void RemapColourProperties(GUI gui, Func<int, int> remapColor)
}
}

private static void RemapColourProperties(GUIControl guiControl, Func<int, int> remapColor)
private static void RemapColourProperties(GUIControl guiControl, RemapColourProperty remapColor)
{
if (guiControl is GUIButton)
{
Expand All @@ -729,7 +752,7 @@ private static void RemapColourProperties(GUIControl guiControl, Func<int, int>
GUIListBox list = guiControl as GUIListBox;
list.TextColor = remapColor(list.TextColor);
list.SelectedTextColor = remapColor(list.SelectedTextColor);
list.SelectedBackgroundColor = remapColor(list.SelectedBackgroundColor);
list.SelectedBackgroundColor = remapColor(list.SelectedBackgroundColor, isBackgroundColor: true);
}
else if (guiControl is GUITextBox)
{
Expand Down
Loading
Loading