SCI: Add custom palette mods for SQ3 and LSL2

This adds a devtools script to convert scifx config files from FreeSCI
into C++ code to apply the palette mods.

The actual palette mods are by Matt Hargett, and from FreeSCI.
This commit is contained in:
Willem Jan Palenstijn 2017-12-08 18:56:37 +01:00 committed by Filippos Karapetis
parent d625da4dcb
commit 2cc67cd29b
10 changed files with 905 additions and 20 deletions

View File

@ -0,0 +1,45 @@
# LSL2 per-resource palette configuration
# Copyright (C) 2006 Matt Hargett
gameid = LSL2;
#ego
view(507,155,161,163,170,197,198,431,432,145..159,131..141,191,104,244,215,217,219,100,101,110,111,112,113,192,193,604,704..706,717,718,818,819,822,823,824,831,832,833,834,835) *= 1.25;
pic(28,99) *= 1.25;
view(218)(3) *= 1.25;
view(218)(0..2) *= 0.9;
view(820)(0,1) *= 0.9;
view(227,224,206,208,209,220) *= 0.9;
view(221,254,252) *= 0.7;
view(820)(2..4) *= 1.2;
view(816)(5)(0) *= 1.2;
view(516,509,501..504,401..403,408,409,411,413,414,417,418,419,430,310,302,303,120..124,232,223,208,710,716,714) *=1.1;
view(434..438,311,313,316,319,321,323,324,306..309,248,245,246,233..235,237,226,229,222,203,204,205,600,525,524,523,522,520,602,605,608,707..708) *=1.2;
view(305)(4) *= 1.1;
view(305)(0..3) *= 0.6;
view(661)(0,1,3..5) *= 1.2;
view(661)(2) *= 0.7;
view(711,712,713,60) *= (0.9, 1.0, 1.0);
view(816)(0..4) *= 0.9;
view(506,508,500,252,803,804,433) *= 0.6;
view(513)(0..5) *= 0.5;
view(240..243,701,722) *= 0.8;
view(700)(1) *= (0.6, 0.9, 1.0);
view(610,611) *= (0.9, 1.0, 1.1);
view(607)(1) *= 0.8;
view(253,228,247,300,326) *= 0.8;
view(412) *= 1.3;
pic(96) *= 1.1;
pic(92,93,18,20..26,134,40,50,76..82,181) *= 0.9;
pic(114..118,125,11..17,19,43,70..74,44,86,101..104,32,33,35,36,95) *= 0.85;
#titles
view(800,801) *= 1.5;
pic(10,90,91) *= 0.4;
#misc effects
view(702) *= (1.1, 1.0, 1.0);
view(519) *= 0.8;
view(200)(0) *= 0.7;
view(201,202) *= 0.8;

View File

@ -0,0 +1,203 @@
from __future__ import print_function
import sys
if len(sys.argv) < 2:
print("Usage: python scifx_to_header.py [scifx files] > scifx.cpp")
sys.exit(-1)
print("""
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
// NB: This file is AUTO-GENERATED by devtools/sci/scifx/scifx_to_cpp.py
// from devtools/sci/scifx/*.scifx
#include "sci/graphics/helpers.h"
#include "sci/graphics/screen.h"
namespace Sci {
""")
def ModToIndex(m):
try:
return M.index(m)
except ValueError:
M.append(m)
return len(M)-1
def PrintMods():
L = [ "\t{ " + ", ".join( [ "%4d" % (round(128 * (val - 1)),) for val in m ] ) + " }" for m in M ]
print("static const PaletteMod paletteMods" + GID + "[] = {")
print( ",\n".join(L) )
print("};")
def PrintPic(pic):
print("static void doCustomPic" + GID + "(GfxScreen *screen, int x) {")
print("\tbyte val = 0;")
print(pic)
print("\tif (val)")
print("\t\tscreen->setCurPaletteMapValue(val);")
print("}")
def PrintView(view):
print("static void doCustomView" + GID + "(GfxScreen *screen, int x, int y, int z) {")
print("\tbyte val = 0;")
print(view)
print("\tif (val)")
print("\t\tscreen->setCurPaletteMapValue(val);")
print("}")
def ParseList(l, v):
assert(l[0] == '(')
e = l.find(")")
L = l[1:e].split(",")
tests = ""
for t in L:
t = t.strip()
ell = t.find('..')
if ell >= 0:
# interval
test = "(" + v + " >= " + t[0:ell] + " && " + v + " <= " + t[ell+2:] + ")"
else:
test = v + " == " + t
if tests:
tests = tests + " || " + test
else:
tests = test
tests = "(" + tests + ")"
return l[e+1:], tests
def ParseTriple(l):
assert(l[0] == '(')
e = l.find(")")
L = l[1:e].split(",")
assert(len(L) == 3)
return L
GIDs = []
for F in sys.argv[1:]:
pic = ""
view = ""
M = [(1.,1.,1.)]
GID=""
for l in open(F, "r").readlines():
l = l.strip()
if len(l) == 0:
continue
if l[0] == '#':
comment = l[1:].strip()
pic += " // " + comment + "\n"
view += " // " + comment + "\n"
continue
if l[0:6] == "gameid":
assert(GID == "")
l = l[6:].strip()
l = l.strip()
assert(l[0] == "=")
assert(l[-1] == ";")
l = l[1:-1].strip()
GID = l
continue
if l[0:4] == "view":
ruletype = "view"
l = l[4:]
elif l[0:3] == "pic":
ruletype = "pic"
l = l[3:]
else:
assert(False)
S = ""
l,t = ParseList(l, "x")
S = S + "\tif " + t + "\n "
if l[0] == "(":
l,t = ParseList(l, "y")
S = S + "\tif " + t + "\n "
if l[0] == "(":
l,t = ParseList(l, "z")
S = S + "\tif " + t + "\n "
l = l.strip()
assert(l[0:2] == "*=")
assert(l[-1] == ";")
l = l[2:-1].strip()
if l[0] == "(":
val = ParseTriple(l)
val = (float(v) for v in val)
else:
val = (float(l), float(l), float(l))
S = S + "\tval = " + str(ModToIndex(val)) + "; // color * " + l + "\n"
if ruletype == "pic":
pic = pic + S
elif ruletype == "view":
view = view + S
if GID == "":
raise ValueError("No gameid specified")
GIDs.append(GID)
PrintMods()
print()
PrintPic(pic)
print()
PrintView(view)
print()
print("void setupCustomPaletteMods(GfxScreen *screen) {")
print("\tswitch (g_sci->getGameId()) {")
for GID in GIDs:
print("\tcase GID_" + GID + ":")
print("\t\tscreen->setPaletteMods(paletteMods" + GID + ", ARRAYSIZE(paletteMods" + GID + "));")
print("\t\tbreak;")
print("\tdefault:")
print("\t\tbreak;")
print("\t}")
print("}")
print()
print("void doCustomViewPalette(GfxScreen *screen, int x, int y, int z) {")
print("\tswitch (g_sci->getGameId()) {")
for GID in GIDs:
print("\tcase GID_" + GID + ":")
print("\t\tdoCustomView" + GID + "(screen, x, y, z);")
print("\t\tbreak;")
print("\tdefault:")
print("\t\tbreak;")
print("\t}")
print("}")
print()
print("void doCustomPicPalette(GfxScreen *screen, int x) {")
print("\tswitch (g_sci->getGameId()) {")
for GID in GIDs:
print("\tcase GID_" + GID + ":")
print("\t\tdoCustomPic" + GID + "(screen, x);")
print("\t\tbreak;")
print("\tdefault:")
print("\t\tbreak;")
print("\t}")
print("}")
print()
print("}")

View File

@ -0,0 +1,83 @@
# SQ3 per-resource palette configuration
# Copyright (C) 2006 Matt Hargett
gameid = SQ3;
# ego
view(0,8,11,12,14,68,17,22..26,32,35, 751, 289, 288, 261, 260, 257, 213, 199, 193, 192, 138, 137, 134, 109, 110, 113, 114, 117, 122, 123,100, 99, 97, 95, 89, 88, 87, 85, 84, 82, 76, 68, 63, 104 ) *= 1.25 ;
view(136) *= 1.15;
view(106)(4,5,9) *= 1.25;
view(105)(0,1) *= 1.25;
# ego on garbage lifter -- lighten but not so as to make the lifter be obviously weird
view(13)(0)(2) *= 1.15 ;
view(31) *= 1.15;
view(15)(3)(0) *= 1.25 ;
view(16,19)(0) *= 1.25;
view(57)(5..6) *= 1.25 ;
view(21)(1) *= 1.25 ;
# ego's shadow
view(7,18) *= 0.5;
view(6..8,18) *= 0.9;
view(901) *= 1.25;
view(751) *= 1.25;
view(750)(1) *= 1.25;
view(92)(4) *= 1.25;
view(83)(0) *= 1.25;
view(83)(1)(2) *=1.15;
view(83)(2)(2) *=1.15;
view(78)(3) *= 1.25;
view(64)(2,3) *= 1.25;
# ego's hands controlling robot
pic(96) *= 1.15;
# peeking at scumsoft
pic(81,82) *= 1.15;
#lifted by robot
pic(430) *= 1.15;
# computer controls
view(40,41,42,149,146,141,151,152) *= 0.8;
view(70,2) *= 0.9;
pic(17,18,162..164,170,180,191,300) *= 0.75;
# title screen
view(900) *= 0.9;
pic(1) *= 0.9 ;
pic(926) *= 0.9;
# humans(?)
view(593,93,103,131..133,210,130,115) *= 1.2;
pic(117) *=1.15;
view(116)(1..2) *= 1.2;
#ships, planets, and robots
view(39) *= 0.9;
view(1) *= 0.75;
pic(205..209,112..115) *= 0.9;
pic(60..72) *= 0.9;
pic(153) *= 0.8;
view(96) *= 0.9;
pic(690) *= 0.9;
view(77)(0..2) *= 0.7;
view(259) *= 1.15;
# in the garbage scow
pic(1..20) *= 0.75 ;
pic(157) *= 0.6;
view(20)(0) *= 0.5;
# rats
view(15)(0,1) *= 0.6;
view(34) *= 0.6;
# guys from andromeda
view(128) *= 0.9;
view(601, 602) *= 0.9;
# misc text bubbles, effects, etc
view(94) *= 1.1;
view(91, 73) *= 1.5;
view(57)(3,4) *= 1.5;
view(15)(4) *= 1.5;
view(64)(0) *= 1.5;
view(71)(8) *= 1.5;
view(10)(6) *= 1.5;

View File

@ -265,6 +265,10 @@ struct Palette {
#endif
};
struct PaletteMod {
int8 r, g, b;
};
struct PalSchedule {
byte from;
uint32 schedule;

View File

@ -39,6 +39,8 @@
#include "sci/graphics/text16.h"
#include "sci/graphics/transitions.h"
#include "sci/graphics/scifx.h"
namespace Sci {
GfxPaint16::GfxPaint16(ResourceManager *resMan, SegManager *segMan, GfxCache *cache, GfxPorts *ports, GfxCoordAdjuster16 *coordAdjuster, GfxScreen *screen, GfxPalette *palette, GfxTransitions *transitions, AudioPlayer *audio)
@ -66,6 +68,9 @@ void GfxPaint16::debugSetEGAdrawingVisualize(bool state) {
void GfxPaint16::drawPicture(GuiResourceId pictureId, bool mirroredFlag, bool addToFlag, GuiResourceId paletteId) {
GfxPicture *picture = new GfxPicture(_resMan, _coordAdjuster, _ports, _screen, _palette, pictureId, _EGAdrawingVisualize);
// Set up custom per-picture palette mod
doCustomPicPalette(_screen, pictureId);
// do we add to a picture? if not -> clear screen with white
if (!addToFlag)
clearScreen(_screen->getColorWhite());
@ -77,6 +82,9 @@ void GfxPaint16::drawPicture(GuiResourceId pictureId, bool mirroredFlag, bool ad
// (SCI1.1 only)
if (getSciVersion() == SCI_VERSION_1_1)
_palette->drewPicture(pictureId);
// Reset custom per-picture palette mod
_screen->setCurPaletteMapValue(0);
}
// This one is the only one that updates screen!

View File

@ -0,0 +1,398 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
// NB: This file is AUTO-GENERATED by devtools/sci/scifx/scifx_to_cpp.py
// from devtools/sci/scifx/*.scifx
#include "sci/graphics/helpers.h"
#include "sci/graphics/screen.h"
namespace Sci {
static const PaletteMod paletteModsLSL2[] = {
{ 0, 0, 0 },
{ 32, 32, 32 },
{ -13, -13, -13 },
{ -38, -38, -38 },
{ 26, 26, 26 },
{ 13, 13, 13 },
{ -51, -51, -51 },
{ -13, 0, 0 },
{ -64, -64, -64 },
{ -26, -26, -26 },
{ -51, -13, 0 },
{ -13, 0, 13 },
{ 38, 38, 38 },
{ -19, -19, -19 },
{ 64, 64, 64 },
{ -77, -77, -77 },
{ 13, 0, 0 }
};
static void doCustomPicLSL2(GfxScreen *screen, int x) {
byte val = 0;
// LSL2 per-resource palette configuration
// Copyright (C) 2006 Matt Hargett
// ego
if (x == 28 || x == 99)
val = 1; // color * 1.25
if (x == 96)
val = 5; // color * 1.1
if (x == 92 || x == 93 || x == 18 || (x >= 20 && x <= 26) || x == 134 || x == 40 || x == 50 || (x >= 76 && x <= 82) || x == 181)
val = 2; // color * 0.9
if ((x >= 114 && x <= 118) || x == 125 || (x >= 11 && x <= 17) || x == 19 || x == 43 || (x >= 70 && x <= 74) || x == 44 || x == 86 || (x >= 101 && x <= 104) || x == 32 || x == 33 || x == 35 || x == 36 || x == 95)
val = 13; // color * 0.85
// titles
if (x == 10 || x == 90 || x == 91)
val = 15; // color * 0.4
// misc effects
if (val)
screen->setCurPaletteMapValue(val);
}
static void doCustomViewLSL2(GfxScreen *screen, int x, int y, int z) {
byte val = 0;
// LSL2 per-resource palette configuration
// Copyright (C) 2006 Matt Hargett
// ego
if (x == 507 || x == 155 || x == 161 || x == 163 || x == 170 || x == 197 || x == 198 || x == 431 || x == 432 || (x >= 145 && x <= 159) || (x >= 131 && x <= 141) || x == 191 || x == 104 || x == 244 || x == 215 || x == 217 || x == 219 || x == 100 || x == 101 || x == 110 || x == 111 || x == 112 || x == 113 || x == 192 || x == 193 || x == 604 || (x >= 704 && x <= 706) || x == 717 || x == 718 || x == 818 || x == 819 || x == 822 || x == 823 || x == 824 || x == 831 || x == 832 || x == 833 || x == 834 || x == 835)
val = 1; // color * 1.25
if (x == 218)
if (y == 3)
val = 1; // color * 1.25
if (x == 218)
if ((y >= 0 && y <= 2))
val = 2; // color * 0.9
if (x == 820)
if (y == 0 || y == 1)
val = 2; // color * 0.9
if (x == 227 || x == 224 || x == 206 || x == 208 || x == 209 || x == 220)
val = 2; // color * 0.9
if (x == 221 || x == 254 || x == 252)
val = 3; // color * 0.7
if (x == 820)
if ((y >= 2 && y <= 4))
val = 4; // color * 1.2
if (x == 816)
if (y == 5)
if (z == 0)
val = 4; // color * 1.2
if (x == 516 || x == 509 || (x >= 501 && x <= 504) || (x >= 401 && x <= 403) || x == 408 || x == 409 || x == 411 || x == 413 || x == 414 || x == 417 || x == 418 || x == 419 || x == 430 || x == 310 || x == 302 || x == 303 || (x >= 120 && x <= 124) || x == 232 || x == 223 || x == 208 || x == 710 || x == 716 || x == 714)
val = 5; // color * 1.1
if ((x >= 434 && x <= 438) || x == 311 || x == 313 || x == 316 || x == 319 || x == 321 || x == 323 || x == 324 || (x >= 306 && x <= 309) || x == 248 || x == 245 || x == 246 || (x >= 233 && x <= 235) || x == 237 || x == 226 || x == 229 || x == 222 || x == 203 || x == 204 || x == 205 || x == 600 || x == 525 || x == 524 || x == 523 || x == 522 || x == 520 || x == 602 || x == 605 || x == 608 || (x >= 707 && x <= 708))
val = 4; // color * 1.2
if (x == 305)
if (y == 4)
val = 5; // color * 1.1
if (x == 305)
if ((y >= 0 && y <= 3))
val = 6; // color * 0.6
if (x == 661)
if (y == 0 || y == 1 || (y >= 3 && y <= 5))
val = 4; // color * 1.2
if (x == 661)
if (y == 2)
val = 3; // color * 0.7
if (x == 711 || x == 712 || x == 713 || x == 60)
val = 7; // color * (0.9, 1.0, 1.0)
if (x == 816)
if ((y >= 0 && y <= 4))
val = 2; // color * 0.9
if (x == 506 || x == 508 || x == 500 || x == 252 || x == 803 || x == 804 || x == 433)
val = 6; // color * 0.6
if (x == 513)
if ((y >= 0 && y <= 5))
val = 8; // color * 0.5
if ((x >= 240 && x <= 243) || x == 701 || x == 722)
val = 9; // color * 0.8
if (x == 700)
if (y == 1)
val = 10; // color * (0.6, 0.9, 1.0)
if (x == 610 || x == 611)
val = 11; // color * (0.9, 1.0, 1.1)
if (x == 607)
if (y == 1)
val = 9; // color * 0.8
if (x == 253 || x == 228 || x == 247 || x == 300 || x == 326)
val = 9; // color * 0.8
if (x == 412)
val = 12; // color * 1.3
// titles
if (x == 800 || x == 801)
val = 14; // color * 1.5
// misc effects
if (x == 702)
val = 16; // color * (1.1, 1.0, 1.0)
if (x == 519)
val = 9; // color * 0.8
if (x == 200)
if (y == 0)
val = 3; // color * 0.7
if (x == 201 || x == 202)
val = 9; // color * 0.8
if (val)
screen->setCurPaletteMapValue(val);
}
static const PaletteMod paletteModsSQ3[] = {
{ 0, 0, 0 },
{ 32, 32, 32 },
{ 19, 19, 19 },
{ -64, -64, -64 },
{ -13, -13, -13 },
{ -26, -26, -26 },
{ -32, -32, -32 },
{ 26, 26, 26 },
{ -38, -38, -38 },
{ -51, -51, -51 },
{ 13, 13, 13 },
{ 64, 64, 64 }
};
static void doCustomPicSQ3(GfxScreen *screen, int x) {
byte val = 0;
// SQ3 per-resource palette configuration
// Copyright (C) 2006 Matt Hargett
// ego
// ego on garbage lifter -- lighten but not so as to make the lifter be obviously weird
// ego's shadow
// ego's hands controlling robot
if (x == 96)
val = 2; // color * 1.15
// peeking at scumsoft
if (x == 81 || x == 82)
val = 2; // color * 1.15
// lifted by robot
if (x == 430)
val = 2; // color * 1.15
// computer controls
if (x == 17 || x == 18 || (x >= 162 && x <= 164) || x == 170 || x == 180 || x == 191 || x == 300)
val = 6; // color * 0.75
// title screen
if (x == 1)
val = 4; // color * 0.9
if (x == 926)
val = 4; // color * 0.9
// humans(?)
if (x == 117)
val = 2; // color * 1.15
// ships, planets, and robots
if ((x >= 205 && x <= 209) || (x >= 112 && x <= 115))
val = 4; // color * 0.9
if ((x >= 60 && x <= 72))
val = 4; // color * 0.9
if (x == 153)
val = 5; // color * 0.8
if (x == 690)
val = 4; // color * 0.9
// in the garbage scow
if ((x >= 1 && x <= 20))
val = 6; // color * 0.75
if (x == 157)
val = 9; // color * 0.6
// rats
// guys from andromeda
// misc text bubbles, effects, etc
if (val)
screen->setCurPaletteMapValue(val);
}
static void doCustomViewSQ3(GfxScreen *screen, int x, int y, int z) {
byte val = 0;
// SQ3 per-resource palette configuration
// Copyright (C) 2006 Matt Hargett
// ego
if (x == 0 || x == 8 || x == 11 || x == 12 || x == 14 || x == 68 || x == 17 || (x >= 22 && x <= 26) || x == 32 || x == 35 || x == 751 || x == 289 || x == 288 || x == 261 || x == 260 || x == 257 || x == 213 || x == 199 || x == 193 || x == 192 || x == 138 || x == 137 || x == 134 || x == 109 || x == 110 || x == 113 || x == 114 || x == 117 || x == 122 || x == 123 || x == 100 || x == 99 || x == 97 || x == 95 || x == 89 || x == 88 || x == 87 || x == 85 || x == 84 || x == 82 || x == 76 || x == 68 || x == 63 || x == 104)
val = 1; // color * 1.25
if (x == 136)
val = 2; // color * 1.15
if (x == 106)
if (y == 4 || y == 5 || y == 9)
val = 1; // color * 1.25
if (x == 105)
if (y == 0 || y == 1)
val = 1; // color * 1.25
// ego on garbage lifter -- lighten but not so as to make the lifter be obviously weird
if (x == 13)
if (y == 0)
if (z == 2)
val = 2; // color * 1.15
if (x == 31)
val = 2; // color * 1.15
if (x == 15)
if (y == 3)
if (z == 0)
val = 1; // color * 1.25
if (x == 16 || x == 19)
if (y == 0)
val = 1; // color * 1.25
if (x == 57)
if ((y >= 5 && y <= 6))
val = 1; // color * 1.25
if (x == 21)
if (y == 1)
val = 1; // color * 1.25
// ego's shadow
if (x == 7 || x == 18)
val = 3; // color * 0.5
if ((x >= 6 && x <= 8) || x == 18)
val = 4; // color * 0.9
if (x == 901)
val = 1; // color * 1.25
if (x == 751)
val = 1; // color * 1.25
if (x == 750)
if (y == 1)
val = 1; // color * 1.25
if (x == 92)
if (y == 4)
val = 1; // color * 1.25
if (x == 83)
if (y == 0)
val = 1; // color * 1.25
if (x == 83)
if (y == 1)
if (z == 2)
val = 2; // color * 1.15
if (x == 83)
if (y == 2)
if (z == 2)
val = 2; // color * 1.15
if (x == 78)
if (y == 3)
val = 1; // color * 1.25
if (x == 64)
if (y == 2 || y == 3)
val = 1; // color * 1.25
// ego's hands controlling robot
// peeking at scumsoft
// lifted by robot
// computer controls
if (x == 40 || x == 41 || x == 42 || x == 149 || x == 146 || x == 141 || x == 151 || x == 152)
val = 5; // color * 0.8
if (x == 70 || x == 2)
val = 4; // color * 0.9
// title screen
if (x == 900)
val = 4; // color * 0.9
// humans(?)
if (x == 593 || x == 93 || x == 103 || (x >= 131 && x <= 133) || x == 210 || x == 130 || x == 115)
val = 7; // color * 1.2
if (x == 116)
if ((y >= 1 && y <= 2))
val = 7; // color * 1.2
// ships, planets, and robots
if (x == 39)
val = 4; // color * 0.9
if (x == 1)
val = 6; // color * 0.75
if (x == 96)
val = 4; // color * 0.9
if (x == 77)
if ((y >= 0 && y <= 2))
val = 8; // color * 0.7
if (x == 259)
val = 2; // color * 1.15
// in the garbage scow
if (x == 20)
if (y == 0)
val = 3; // color * 0.5
// rats
if (x == 15)
if (y == 0 || y == 1)
val = 9; // color * 0.6
if (x == 34)
val = 9; // color * 0.6
// guys from andromeda
if (x == 128)
val = 4; // color * 0.9
if (x == 601 || x == 602)
val = 4; // color * 0.9
// misc text bubbles, effects, etc
if (x == 94)
val = 10; // color * 1.1
if (x == 91 || x == 73)
val = 11; // color * 1.5
if (x == 57)
if (y == 3 || y == 4)
val = 11; // color * 1.5
if (x == 15)
if (y == 4)
val = 11; // color * 1.5
if (x == 64)
if (y == 0)
val = 11; // color * 1.5
if (x == 71)
if (y == 8)
val = 11; // color * 1.5
if (x == 10)
if (y == 6)
val = 11; // color * 1.5
if (val)
screen->setCurPaletteMapValue(val);
}
void setupCustomPaletteMods(GfxScreen *screen) {
switch (g_sci->getGameId()) {
case GID_LSL2:
screen->setPaletteMods(paletteModsLSL2, ARRAYSIZE(paletteModsLSL2));
break;
case GID_SQ3:
screen->setPaletteMods(paletteModsSQ3, ARRAYSIZE(paletteModsSQ3));
break;
default:
break;
}
}
void doCustomViewPalette(GfxScreen *screen, int x, int y, int z) {
switch (g_sci->getGameId()) {
case GID_LSL2:
doCustomViewLSL2(screen, x, y, z);
break;
case GID_SQ3:
doCustomViewSQ3(screen, x, y, z);
break;
default:
break;
}
}
void doCustomPicPalette(GfxScreen *screen, int x) {
switch (g_sci->getGameId()) {
case GID_LSL2:
doCustomPicLSL2(screen, x);
break;
case GID_SQ3:
doCustomPicSQ3(screen, x);
break;
default:
break;
}
}
}

View File

@ -0,0 +1,29 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
namespace Sci {
void setupCustomPaletteMods(GfxScreen *screen);
void doCustomViewPalette(GfxScreen *screen, int x, int y, int z);
void doCustomPicPalette(GfxScreen *screen, int x);
}

View File

@ -34,6 +34,7 @@
#include "sci/graphics/screen.h"
#include "sci/graphics/view.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/scifx.h"
namespace Sci {
@ -50,6 +51,9 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
_displayWidth = 0;
_displayHeight = 0;
_curPaletteMapValue = 0;
_paletteModsEnabled = false;
// King's Quest 6 and Gabriel Knight 1 have hires content, gk1/cd was able
// to provide that under DOS as well, but as gk1/floppy does support
// upscaled hires scriptswise, but doesn't actually have the hires content
@ -175,6 +179,12 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
_colorDefaultVectorData = 0;
}
// Set up palette mods if requested
if (ConfMan.getBool("palette_mods")) {
setupCustomPaletteMods(this);
ConfMan.setBool("rgb_rendering", true);
}
// Initialize the actual screen
Graphics::PixelFormat format8 = Graphics::PixelFormat::createFormatCLUT8();
const Graphics::PixelFormat *format = &format8;
@ -203,10 +213,16 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) {
_displayedScreen = (byte *)calloc(_displayPixels, 1);
_rgbScreen = (byte *)calloc(_format.bytesPerPixel*_displayPixels, 1);
_palette = new byte[3*256];
if (_paletteModsEnabled)
_paletteMapScreen = (byte *)calloc(_displayPixels, 1);
else
_paletteMapScreen = 0;
} else {
_displayedScreen = 0;
_palette = 0;
_rgbScreen = 0;
_paletteMapScreen = 0;
}
_backupScreen = 0;
}
@ -217,6 +233,7 @@ GfxScreen::~GfxScreen() {
free(_controlScreen);
free(_displayScreen);
free(_paletteMapScreen);
free(_displayedScreen);
free(_rgbScreen);
delete[] _palette;
@ -235,29 +252,73 @@ void GfxScreen::convertToRGB(const Common::Rect &rect) {
if (_format.bytesPerPixel == 2) {
for (int x = 0; x < rect.width(); ++x) {
byte i = *in;
byte r = _palette[3*i + 0];
byte g = _palette[3*i + 1];
byte b = _palette[3*i + 2];
uint16 c = (uint16)_format.RGBToColor(r, g, b);
WRITE_UINT16(out, c);
in += 1;
out += 2;
if (_paletteMapScreen) {
const byte *mod = _paletteMapScreen + y * _displayWidth + rect.left;
for (int x = 0; x < rect.width(); ++x) {
byte i = *in;
byte r = _palette[3*i + 0];
byte g = _palette[3*i + 1];
byte b = _palette[3*i + 2];
if (*mod) {
r = MIN(r * (128 + _paletteMods[*mod].r) / 128, 255);
g = MIN(g * (128 + _paletteMods[*mod].g) / 128, 255);
b = MIN(b * (128 + _paletteMods[*mod].b) / 128, 255);
}
uint16 c = (uint16)_format.RGBToColor(r, g, b);
WRITE_UINT16(out, c);
in += 1;
out += 2;
mod += 1;
}
} else {
for (int x = 0; x < rect.width(); ++x) {
byte i = *in;
byte r = _palette[3*i + 0];
byte g = _palette[3*i + 1];
byte b = _palette[3*i + 2];
uint16 c = (uint16)_format.RGBToColor(r, g, b);
WRITE_UINT16(out, c);
in += 1;
out += 2;
}
}
} else {
assert(_format.bytesPerPixel == 4);
for (int x = 0; x < rect.width(); ++x) {
byte i = *in;
byte r = _palette[3*i + 0];
byte g = _palette[3*i + 1];
byte b = _palette[3*i + 2];
uint32 c = _format.RGBToColor(r, g, b);
WRITE_UINT32(out, c);
in += 1;
out += 4;
if (_paletteMapScreen) {
const byte *mod = _paletteMapScreen + y * _displayWidth + rect.left;
for (int x = 0; x < rect.width(); ++x) {
byte i = *in;
byte r = _palette[3*i + 0];
byte g = _palette[3*i + 1];
byte b = _palette[3*i + 2];
if (*mod) {
r = MIN(r * (128 + _paletteMods[*mod].r) / 128, 255);
g = MIN(g * (128 + _paletteMods[*mod].g) / 128, 255);
b = MIN(b * (128 + _paletteMods[*mod].b) / 128, 255);
}
uint32 c = _format.RGBToColor(r, g, b);
WRITE_UINT32(out, c);
in += 1;
out += 4;
mod += 1;
}
} else {
for (int x = 0; x < rect.width(); ++x) {
byte i = *in;
byte r = _palette[3*i + 0];
byte g = _palette[3*i + 1];
byte b = _palette[3*i + 2];
uint32 c = _format.RGBToColor(r, g, b);
WRITE_UINT32(out, c);
in += 1;
out += 4;
}
}
}
}
@ -309,6 +370,8 @@ void GfxScreen::clearForRestoreGame() {
if (_displayedScreen) {
memset(_displayedScreen, 0, _displayPixels);
memset(_rgbScreen, 0, _format.bytesPerPixel*_displayPixels);
if (_paletteMapScreen)
memset(_paletteMapScreen, 0, _displayPixels);
}
memset(&_ditheredPicColors, 0, sizeof(_ditheredPicColors));
_fontIsUpscaled = false;
@ -579,10 +642,14 @@ int GfxScreen::bitsGetDataSize(Common::Rect rect, byte mask) {
byteCount += pixels; // _visualScreen
if (!_upscaledHires) {
byteCount += pixels; // _displayScreen
if (_paletteMapScreen)
byteCount += pixels; // _paletteMapScreen
} else {
int rectHeight = _upscaledHeightMapping[rect.bottom] - _upscaledHeightMapping[rect.top];
int rectWidth = _upscaledWidthMapping[rect.right] - _upscaledWidthMapping[rect.left];
byteCount += rectHeight * rectWidth; // _displayScreen (upscaled hires)
if (_paletteMapScreen)
byteCount += rectHeight * rectWidth; // _paletteMapScreen (upscaled hires)
}
}
if (mask & GFX_SCREEN_MASK_PRIORITY) {
@ -595,6 +662,8 @@ int GfxScreen::bitsGetDataSize(Common::Rect rect, byte mask) {
if (!_upscaledHires)
error("bitsGetDataSize() called w/o being in upscaled hires mode");
byteCount += pixels; // _displayScreen (coordinates actually are given to us for hires displayScreen)
if (_paletteMapScreen)
byteCount += pixels; // _paletteMapScreen
}
return byteCount;
}
@ -606,6 +675,8 @@ void GfxScreen::bitsSave(Common::Rect rect, byte mask, byte *memoryPtr) {
if (mask & GFX_SCREEN_MASK_VISUAL) {
bitsSaveScreen(rect, _visualScreen, _width, memoryPtr);
bitsSaveDisplayScreen(rect, _displayScreen, memoryPtr);
if (_paletteMapScreen)
bitsSaveDisplayScreen(rect, _paletteMapScreen, memoryPtr);
}
if (mask & GFX_SCREEN_MASK_PRIORITY) {
bitsSaveScreen(rect, _priorityScreen, _width, memoryPtr);
@ -617,6 +688,8 @@ void GfxScreen::bitsSave(Common::Rect rect, byte mask, byte *memoryPtr) {
if (!_upscaledHires)
error("bitsSave() called w/o being in upscaled hires mode");
bitsSaveScreen(rect, _displayScreen, _displayWidth, memoryPtr);
if (_paletteMapScreen)
bitsSaveScreen(rect, _paletteMapScreen, _displayWidth, memoryPtr);
}
}
@ -666,6 +739,8 @@ void GfxScreen::bitsRestore(const byte *memoryPtr) {
if (mask & GFX_SCREEN_MASK_VISUAL) {
bitsRestoreScreen(rect, memoryPtr, _visualScreen, _width);
bitsRestoreDisplayScreen(rect, memoryPtr, _displayScreen);
if (_paletteMapScreen)
bitsRestoreDisplayScreen(rect, memoryPtr, _paletteMapScreen);
}
if (mask & GFX_SCREEN_MASK_PRIORITY) {
bitsRestoreScreen(rect, memoryPtr, _priorityScreen, _width);
@ -677,6 +752,9 @@ void GfxScreen::bitsRestore(const byte *memoryPtr) {
if (!_upscaledHires)
error("bitsRestore() called w/o being in upscaled hires mode");
bitsRestoreScreen(rect, memoryPtr, _displayScreen, _displayWidth);
if (_paletteMapScreen)
bitsRestoreScreen(rect, memoryPtr, _paletteMapScreen, _displayWidth);
// WORKAROUND - we are not sure what sierra is doing. If we don't do this here, portraits won't get fully removed
// from screen. Some lowres showBits() call is used for that and it's not covering the whole area
// We would need to find out inside the kq6 windows interpreter, but this here works already and seems not to have
@ -754,6 +832,7 @@ void GfxScreen::dither(bool addToFlag) {
byte color, ditheredColor;
byte *visualPtr = _visualScreen;
byte *displayPtr = _displayScreen;
byte *paletteMapPtr = _paletteMapScreen;
if (!_unditheringEnabled) {
// Do dithering on visual and display-screen
@ -767,6 +846,8 @@ void GfxScreen::dither(bool addToFlag) {
case GFX_SCREEN_UPSCALED_DISABLED:
case GFX_SCREEN_UPSCALED_480x300:
*displayPtr = color;
if (_paletteMapScreen)
*paletteMapPtr = _curPaletteMapValue;
break;
default:
putScaledPixelOnDisplay(x, y, color);
@ -774,7 +855,7 @@ void GfxScreen::dither(bool addToFlag) {
}
*visualPtr = color;
}
visualPtr++; displayPtr++;
visualPtr++; displayPtr++; paletteMapPtr++;
}
}
} else {
@ -799,6 +880,8 @@ void GfxScreen::dither(bool addToFlag) {
case GFX_SCREEN_UPSCALED_DISABLED:
case GFX_SCREEN_UPSCALED_480x300:
*displayPtr = ditheredColor;
if (_paletteMapScreen)
*paletteMapPtr = _curPaletteMapValue;
break;
default:
putScaledPixelOnDisplay(x, y, ditheredColor);
@ -807,7 +890,7 @@ void GfxScreen::dither(bool addToFlag) {
color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
*visualPtr = color;
}
visualPtr++; displayPtr++;
visualPtr++; displayPtr++; paletteMapPtr++;
}
}
}
@ -996,7 +1079,13 @@ void GfxScreen::bakCopyRectToScreen(const Common::Rect &rect, int16 x, int16 y)
g_system->copyRectToScreen(ptr, _format.bytesPerPixel * _displayWidth, x, y, rect.width(), rect.height());
}
void GfxScreen::setPaletteMods(const PaletteMod *mods, unsigned int count) {
assert(count < 256);
for (unsigned int i = 0; i < count; ++i)
_paletteMods[i] = mods[i];
_paletteModsEnabled = true;
}

View File

@ -150,6 +150,11 @@ public:
void grabPalette(byte *buffer, uint start, uint num) const;
void setPalette(const byte *buffer, uint start, uint num, bool update = true);
byte getCurPaletteMapValue() const { return _curPaletteMapValue; }
void setCurPaletteMapValue(byte val) { _curPaletteMapValue = val; }
void setPaletteMods(const PaletteMod *mods, unsigned int count);
bool paletteModsEnabled() const { return _paletteModsEnabled; }
private:
uint16 _width;
uint16 _height;
@ -196,6 +201,12 @@ private:
byte *_displayedScreen;
byte *_rgbScreen;
// For RGB per-view/pic palette mods
byte *_paletteMapScreen;
byte _curPaletteMapValue;
PaletteMod _paletteMods[256];
bool _paletteModsEnabled;
byte *_backupScreen; // for bak* functions
void convertToRGB(const Common::Rect &rect);
@ -244,6 +255,8 @@ public:
if (drawMask & GFX_SCREEN_MASK_VISUAL) {
_visualScreen[offset] = color;
if (_paletteMapScreen)
_paletteMapScreen[offset] = _curPaletteMapValue;
switch (_upscaledHires) {
case GFX_SCREEN_UPSCALED_DISABLED:
@ -314,6 +327,9 @@ public:
if (drawMask & GFX_SCREEN_MASK_VISUAL) {
_visualScreen[offset] = color;
_displayScreen[offset] = color;
if (_paletteMapScreen)
_paletteMapScreen[offset] = _curPaletteMapValue;
}
if (drawMask & GFX_SCREEN_MASK_PRIORITY) {
_priorityScreen[offset] = priority;

View File

@ -28,6 +28,9 @@
#include "sci/graphics/coordadjuster.h"
#include "sci/graphics/view.h"
#include "sci/graphics/scifx.h"
namespace Sci {
GfxView::GfxView(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette, GuiResourceId resourceId)
@ -820,6 +823,10 @@ void GfxView::draw(const Common::Rect &rect, const Common::Rect &clipRect, const
const byte *bitmapData = bitmap.getUnsafeDataAt((clipRect.top - rect.top) * celWidth + (clipRect.left - rect.left), celWidth * (height - 1) + width);
// Set up custom per-view palette mod
byte oldpalvalue = _screen->getCurPaletteMapValue();
doCustomViewPalette(_screen, _resourceId, loopNo, celNo);
if (_EGAmapping) {
const SciSpan<const byte> EGAmapping = _EGAmapping.subspan(EGAmappingNr * SCI_VIEW_EGAMAPPING_SIZE, SCI_VIEW_EGAMAPPING_SIZE);
for (int y = 0; y < height; y++, bitmapData += celWidth) {
@ -856,6 +863,9 @@ void GfxView::draw(const Common::Rect &rect, const Common::Rect &clipRect, const
}
}
}
// Reset custom per-view palette mod
_screen->setCurPaletteMapValue(oldpalvalue);
}
/**