SCI32: Split GfxPalette and GfxPalette32 + HunkPalette
This commit is contained in:
parent
7f53a26d9e
commit
4cfc387602
10 changed files with 336 additions and 133 deletions
|
@ -497,8 +497,10 @@ bool Console::cmdGetVersion(int argc, const char **argv) {
|
|||
if (getSciVersion() <= SCI_VERSION_1_1) {
|
||||
debugPrintf("kAnimate fastCast enabled: %s\n", g_sci->_gfxAnimate->isFastCastEnabled() ? "yes" : "no");
|
||||
}
|
||||
if (getSciVersion() < SCI_VERSION_2) {
|
||||
debugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette16->isMerging() ? "yes" : "no");
|
||||
debugPrintf("Uses 16 bit color matching: %s\n", g_sci->_gfxPalette16->isUsing16bitColorMatch() ? "yes" : "no");
|
||||
}
|
||||
debugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc());
|
||||
debugPrintf("Resource map version: %s\n", g_sci->getResMan()->getMapVersionDesc());
|
||||
debugPrintf("Contains selector vocabulary (vocab.997): %s\n", hasVocab997 ? "yes" : "no");
|
||||
|
@ -1620,7 +1622,7 @@ bool Console::cmdParserNodes(int argc, const char **argv) {
|
|||
|
||||
bool Console::cmdSetPalette(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
debugPrintf("Sets a palette resource\n");
|
||||
debugPrintf("Sets a palette resource (SCI16)\n");
|
||||
debugPrintf("Usage: %s <resourceId>\n", argv[0]);
|
||||
debugPrintf("where <resourceId> is the number of the palette resource to set\n");
|
||||
return true;
|
||||
|
@ -1628,6 +1630,13 @@ bool Console::cmdSetPalette(int argc, const char **argv) {
|
|||
|
||||
uint16 resourceId = atoi(argv[1]);
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2) {
|
||||
debugPrintf("This SCI version does not support this command\n");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
_engine->_gfxPalette16->kernelSetFromResource(resourceId, true);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -547,7 +547,8 @@ reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv);
|
|||
reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv);
|
||||
reg_t kSetScroll(EngineState *s, int argc, reg_t *argv);
|
||||
|
||||
reg_t kPalCycle(EngineState *s, int argc, reg_t *argv);
|
||||
reg_t kPaletteSetFromResource32(EngineState *s, int argc, reg_t *argv);
|
||||
reg_t kPaletteFindColor32(EngineState *s, int argc, reg_t *argv);
|
||||
reg_t kPaletteSetFade(EngineState *s, int argc, reg_t *argv);
|
||||
|
||||
reg_t kPalCycle(EngineState *s, int argc, reg_t *argv);
|
||||
|
|
|
@ -291,12 +291,13 @@ static const SciKernelMapSubEntry kPalVary_subops[] = {
|
|||
|
||||
// version, subId, function-mapping, signature, workarounds
|
||||
static const SciKernelMapSubEntry kPalette_subops[] = {
|
||||
{ SIG_SCIALL, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL },
|
||||
{ SIG_SCI16, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL },
|
||||
{ SIG_SCI16, 2, MAP_CALL(PaletteSetFlag), "iii", NULL },
|
||||
{ SIG_SCI16, 3, MAP_CALL(PaletteUnsetFlag), "iii", kPaletteUnsetFlag_workarounds },
|
||||
#ifdef ENABLE_SCI32
|
||||
{ SIG_SCI32, 1, MAP_CALL(PaletteSetFromResource32), "i(i)", NULL },
|
||||
{ SIG_SCI32, 2, MAP_CALL(PaletteSetFade), "iii", NULL },
|
||||
{ SIG_SCI32, 3, MAP_CALL(PaletteFindColor), "iii", NULL },
|
||||
{ SIG_SCI32, 3, MAP_CALL(PaletteFindColor32), "iii", NULL },
|
||||
#endif
|
||||
{ SIG_SCI16, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL },
|
||||
{ SIG_SCI16, 5, MAP_CALL(PaletteFindColor), "iii", NULL },
|
||||
|
|
|
@ -790,6 +790,19 @@ reg_t kMorphOn(EngineState *s, int argc, reg_t *argv) {
|
|||
return s->r_acc;
|
||||
}
|
||||
|
||||
reg_t kPaletteSetFromResource32(EngineState *s, int argc, reg_t *argv) {
|
||||
const GuiResourceId paletteId = argv[0].toUint16();
|
||||
g_sci->_gfxPalette32->loadPalette(paletteId);
|
||||
return s->r_acc;
|
||||
}
|
||||
|
||||
reg_t kPaletteFindColor32(EngineState *s, int argc, reg_t *argv) {
|
||||
const uint8 r = argv[0].toUint16();
|
||||
const uint8 g = argv[1].toUint16();
|
||||
const uint8 b = argv[2].toUint16();
|
||||
return make_reg(0, g_sci->_gfxPalette32->matchColor(r, g, b));
|
||||
}
|
||||
|
||||
reg_t kPaletteSetFade(EngineState *s, int argc, reg_t *argv) {
|
||||
uint16 fromColor = argv[0].toUint16();
|
||||
uint16 toColor = argv[1].toUint16();
|
||||
|
|
|
@ -398,7 +398,12 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
|
|||
_segMan->saveLoadWithSerializer(s);
|
||||
|
||||
g_sci->_soundCmd->syncPlayList(s);
|
||||
// NOTE: This will be GfxPalette32 for SCI32 engine games
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2) {
|
||||
g_sci->_gfxPalette32->saveLoadWithSerializer(s);
|
||||
} else
|
||||
#endif
|
||||
g_sci->_gfxPalette16->saveLoadWithSerializer(s);
|
||||
}
|
||||
|
||||
|
@ -767,7 +772,7 @@ void GfxPalette32::saveLoadWithSerializer(Common::Serializer &s) {
|
|||
s.syncAsSint16LE(_varyFromColor);
|
||||
s.syncAsSint16LE(_varyToColor);
|
||||
s.syncAsUint16LE(_varyNumTimesPaused);
|
||||
s.syncAsByte(_versionUpdated);
|
||||
s.syncAsByte(_needsUpdate);
|
||||
s.syncAsSint32LE(_varyTime);
|
||||
s.syncAsUint32LE(_varyLastTick);
|
||||
|
||||
|
|
|
@ -570,12 +570,7 @@ uint8 CelObj::readPixel(uint16 x, const uint16 y, bool mirrorX) const {
|
|||
|
||||
void CelObj::submitPalette() const {
|
||||
if (_hunkPaletteOffset) {
|
||||
Palette palette;
|
||||
|
||||
byte *res = getResPointer();
|
||||
// NOTE: In SCI engine this uses HunkPalette::Init.
|
||||
// TODO: Use a better size value
|
||||
g_sci->_gfxPalette32->createFromData(res + _hunkPaletteOffset, 999999, &palette);
|
||||
HunkPalette palette(getResPointer() + _hunkPaletteOffset);
|
||||
g_sci->_gfxPalette32->submit(palette);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
bool setAmiga();
|
||||
void modifyAmigaPalette(byte *data);
|
||||
void setEGA();
|
||||
virtual void set(Palette *sciPal, bool force, bool forceRealMerge = false);
|
||||
void set(Palette *sciPal, bool force, bool forceRealMerge = false);
|
||||
bool insert(Palette *newPalette, Palette *destPalette);
|
||||
bool merge(Palette *pFrom, bool force, bool forceRealMerge);
|
||||
uint16 matchColor(byte r, byte g, byte b);
|
||||
|
@ -63,11 +63,11 @@ public:
|
|||
|
||||
void drewPicture(GuiResourceId pictureId);
|
||||
|
||||
virtual bool kernelSetFromResource(GuiResourceId resourceId, bool force);
|
||||
bool kernelSetFromResource(GuiResourceId resourceId, bool force);
|
||||
void kernelSetFlag(uint16 fromColor, uint16 toColor, uint16 flag);
|
||||
void kernelUnsetFlag(uint16 fromColor, uint16 toColor, uint16 flag);
|
||||
void kernelSetIntensity(uint16 fromColor, uint16 toColor, uint16 intensity, bool setPalette);
|
||||
virtual int16 kernelFindColor(uint16 r, uint16 g, uint16 b);
|
||||
int16 kernelFindColor(uint16 r, uint16 g, uint16 b);
|
||||
bool kernelAnimate(byte fromColor, byte toColor, int speed);
|
||||
void kernelAnimateSet();
|
||||
reg_t kernelSave();
|
||||
|
@ -81,7 +81,7 @@ public:
|
|||
int16 kernelPalVaryGetCurrentStep();
|
||||
int16 kernelPalVaryChangeTarget(GuiResourceId resourceId);
|
||||
void kernelPalVaryChangeTicks(uint16 ticks);
|
||||
virtual void kernelPalVaryPause(bool pause);
|
||||
void kernelPalVaryPause(bool pause);
|
||||
void kernelPalVaryDeinit();
|
||||
void palVaryUpdate();
|
||||
void palVaryPrepareForTransition();
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
|
||||
Palette _sysPalette;
|
||||
|
||||
virtual void saveLoadWithSerializer(Common::Serializer &s);
|
||||
void saveLoadWithSerializer(Common::Serializer &s);
|
||||
void palVarySaveLoadPalette(Common::Serializer &s, Palette *palette);
|
||||
|
||||
byte findMacIconBarColor(byte r, byte g, byte b);
|
||||
|
|
|
@ -27,19 +27,109 @@
|
|||
#include "sci/sci.h"
|
||||
#include "sci/event.h"
|
||||
#include "sci/resource.h"
|
||||
#include "sci/util.h"
|
||||
#include "sci/graphics/palette32.h"
|
||||
#include "sci/graphics/remap32.h"
|
||||
#include "sci/graphics/screen.h"
|
||||
|
||||
namespace Sci {
|
||||
|
||||
GfxPalette32::GfxPalette32(ResourceManager *resMan, GfxScreen *screen)
|
||||
: GfxPalette(resMan, screen),
|
||||
#pragma mark HunkPalette
|
||||
|
||||
HunkPalette::HunkPalette(byte *rawPalette) :
|
||||
_version(0),
|
||||
// NOTE: The header size in palettes is garbage. In at least KQ7 2.00b and
|
||||
// Phant1, the 999.pal sets this value to 0. In most other palettes it is
|
||||
// set to 14, but the *actual* size of the header structure used in SSCI is
|
||||
// 13, which is reflected by `kHunkPaletteHeaderSize`.
|
||||
// _headerSize(rawPalette[0]),
|
||||
_numPalettes(rawPalette[10]),
|
||||
_data(nullptr) {
|
||||
assert(_numPalettes == 0 || _numPalettes == 1);
|
||||
if (_numPalettes) {
|
||||
_data = rawPalette;
|
||||
_version = getEntryHeader().version;
|
||||
}
|
||||
}
|
||||
|
||||
void HunkPalette::setVersion(const uint32 version) {
|
||||
if (_numPalettes != _data[10]) {
|
||||
error("Invalid HunkPalette");
|
||||
}
|
||||
|
||||
if (_numPalettes) {
|
||||
const EntryHeader header = getEntryHeader();
|
||||
if (header.version != _version) {
|
||||
error("Invalid HunkPalette");
|
||||
}
|
||||
|
||||
WRITE_SCI11ENDIAN_UINT32(getPalPointer() + kEntryVersionOffset, version);
|
||||
_version = version;
|
||||
}
|
||||
}
|
||||
|
||||
const HunkPalette::EntryHeader HunkPalette::getEntryHeader() const {
|
||||
const byte *const data = getPalPointer();
|
||||
|
||||
EntryHeader header;
|
||||
header.startColor = data[10];
|
||||
header.numColors = READ_SCI11ENDIAN_UINT16(data + 14);
|
||||
header.used = data[16];
|
||||
header.sharedUsed = data[17];
|
||||
header.version = READ_SCI11ENDIAN_UINT32(data + kEntryVersionOffset);
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
const Palette HunkPalette::toPalette() const {
|
||||
Palette outPalette;
|
||||
|
||||
for (int16 i = 0; i < ARRAYSIZE(outPalette.colors); ++i) {
|
||||
outPalette.colors[i].used = false;
|
||||
outPalette.colors[i].r = 0;
|
||||
outPalette.colors[i].g = 0;
|
||||
outPalette.colors[i].b = 0;
|
||||
}
|
||||
|
||||
if (_numPalettes) {
|
||||
const EntryHeader header = getEntryHeader();
|
||||
byte *data = getPalPointer() + kEntryHeaderSize;
|
||||
|
||||
int16 end = header.startColor + header.numColors;
|
||||
assert(end <= 256);
|
||||
|
||||
if (header.sharedUsed) {
|
||||
for (int16 i = header.startColor; i < end; ++i) {
|
||||
outPalette.colors[i].used = header.used;
|
||||
outPalette.colors[i].r = *data++;
|
||||
outPalette.colors[i].g = *data++;
|
||||
outPalette.colors[i].b = *data++;
|
||||
}
|
||||
} else {
|
||||
for (int16 i = header.startColor; i < end; ++i) {
|
||||
outPalette.colors[i].used = *data++;
|
||||
outPalette.colors[i].r = *data++;
|
||||
outPalette.colors[i].g = *data++;
|
||||
outPalette.colors[i].b = *data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return outPalette;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark GfxPalette32
|
||||
|
||||
GfxPalette32::GfxPalette32(ResourceManager *resMan)
|
||||
: _resMan(resMan),
|
||||
// Palette versioning
|
||||
_version(1),
|
||||
_versionUpdated(false),
|
||||
_sourcePalette(_sysPalette),
|
||||
_nextPalette(_sysPalette),
|
||||
_needsUpdate(false),
|
||||
_currentPalette(),
|
||||
_sourcePalette(_currentPalette),
|
||||
_nextPalette(_currentPalette),
|
||||
// Clut
|
||||
_clutTable(nullptr),
|
||||
// Palette varying
|
||||
|
@ -59,13 +149,14 @@ GfxPalette32::GfxPalette32(ResourceManager *resMan, GfxScreen *screen)
|
|||
for (int i = 0, len = ARRAYSIZE(_fadeTable); i < len; ++i) {
|
||||
_fadeTable[i] = 100;
|
||||
}
|
||||
// NOTE: In SCI engine, the palette manager constructor loads
|
||||
// the default palette, but in ScummVM this initialisation
|
||||
// is performed by SciEngine::run; see r49523 for details
|
||||
|
||||
loadPalette(999);
|
||||
}
|
||||
|
||||
GfxPalette32::~GfxPalette32() {
|
||||
#ifdef ENABLE_SCI3_GAMES
|
||||
unloadClut();
|
||||
#endif
|
||||
varyOff();
|
||||
cycleAllOff();
|
||||
}
|
||||
|
@ -78,79 +169,64 @@ inline void mergePaletteInternal(Palette *const to, const Palette *const from) {
|
|||
}
|
||||
}
|
||||
|
||||
void GfxPalette32::submit(Palette &palette) {
|
||||
// TODO: The resource manager in SCI32 retains raw data of palettes from
|
||||
// the ResourceManager (ResourceMgr) through SegManager (MemoryMgr), and
|
||||
// the version number for submitted palettes is set in the raw palette
|
||||
// data in memory as an int at an offset
|
||||
// `rawData + *rawData[0x0a] * 2 + 31`. However, ScummVM does not retain
|
||||
// resource data like this, so this versioning code, while accurate to
|
||||
// the original engine, does not do much.
|
||||
// (Hopefully this was an optimisation mechanism in SCI engine and not a
|
||||
// clever thing to keep the same palette submitted many times from
|
||||
// overwriting other palette entries.)
|
||||
if (palette.timestamp == _version) {
|
||||
void GfxPalette32::submit(const Palette &palette) {
|
||||
const Palette oldSourcePalette(_sourcePalette);
|
||||
mergePaletteInternal(&_sourcePalette, &palette);
|
||||
|
||||
if (!_needsUpdate && _sourcePalette != oldSourcePalette) {
|
||||
++_version;
|
||||
_needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GfxPalette32::submit(HunkPalette &hunkPalette) {
|
||||
if (hunkPalette.getVersion() == _version) {
|
||||
return;
|
||||
}
|
||||
|
||||
Palette oldSourcePalette(_sourcePalette);
|
||||
const Palette oldSourcePalette(_sourcePalette);
|
||||
const Palette palette = hunkPalette.toPalette();
|
||||
mergePaletteInternal(&_sourcePalette, &palette);
|
||||
|
||||
if (!_versionUpdated && _sourcePalette != oldSourcePalette) {
|
||||
if (!_needsUpdate && oldSourcePalette != _sourcePalette) {
|
||||
++_version;
|
||||
_versionUpdated = true;
|
||||
_needsUpdate = true;
|
||||
}
|
||||
|
||||
// Technically this information is supposed to be persisted through a
|
||||
// HunkPalette object; right now it would just be lost once the temporary
|
||||
// palette was destroyed.
|
||||
palette.timestamp = _version;
|
||||
hunkPalette.setVersion(_version);
|
||||
}
|
||||
|
||||
bool GfxPalette32::kernelSetFromResource(GuiResourceId resourceId, bool force) {
|
||||
// TODO: In SCI32, palettes that come from resources come in as
|
||||
// HunkPalette objects, not SOLPalette objects. The HunkPalettes
|
||||
// have some extra persistence stuff associated with them, such that
|
||||
// when they are passed to GfxPalette32::submit, they would get the
|
||||
// version number of GfxPalette32 assigned to them.
|
||||
Palette palette;
|
||||
bool GfxPalette32::loadPalette(const GuiResourceId resourceId) {
|
||||
Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), false);
|
||||
|
||||
if (createPaletteFromResourceInternal(resourceId, &palette)) {
|
||||
if (!palResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HunkPalette palette(palResource->data);
|
||||
submit(palette);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// In SCI32 engine this method is SOLPalette::Match(Rgb24 *)
|
||||
// and is called as PaletteMgr.Current().Match(color)
|
||||
int16 GfxPalette32::kernelFindColor(uint16 r, uint16 g, uint16 b) {
|
||||
// SQ6 SCI32 engine takes the 16-bit r, g, b arguments from the
|
||||
// VM and puts them into al, ah, dl. For compatibility, make sure
|
||||
// to discard any high bits here too
|
||||
r = r & 0xFF;
|
||||
g = g & 0xFF;
|
||||
b = b & 0xFF;
|
||||
int16 GfxPalette32::matchColor(const uint8 r, const uint8 g, const uint8 b) {
|
||||
int16 bestIndex = 0;
|
||||
int bestDifference = 0xFFFFF;
|
||||
int difference;
|
||||
|
||||
// SQ6 DOS really does check only the first 236 entries
|
||||
for (int i = 0, channelDifference; i < 236; ++i) {
|
||||
difference = _sysPalette.colors[i].r - r;
|
||||
for (int i = 0, channelDifference; i < g_sci->_gfxRemap32->getStartColor(); ++i) {
|
||||
difference = _currentPalette.colors[i].r - r;
|
||||
difference *= difference;
|
||||
if (bestDifference <= difference) {
|
||||
continue;
|
||||
}
|
||||
|
||||
channelDifference = _sysPalette.colors[i].g - g;
|
||||
channelDifference = _currentPalette.colors[i].g - g;
|
||||
difference += channelDifference * channelDifference;
|
||||
if (bestDifference <= difference) {
|
||||
continue;
|
||||
}
|
||||
|
||||
channelDifference = _sysPalette.colors[i].b - b;
|
||||
channelDifference = _currentPalette.colors[i].b - b;
|
||||
difference += channelDifference * channelDifference;
|
||||
if (bestDifference <= difference) {
|
||||
continue;
|
||||
|
@ -162,51 +238,39 @@ int16 GfxPalette32::kernelFindColor(uint16 r, uint16 g, uint16 b) {
|
|||
return bestIndex;
|
||||
}
|
||||
|
||||
// TODO: set is overridden for the time being to send palettes coming from
|
||||
// various draw methods like GfxPicture::drawSci32Vga and GfxView::draw to
|
||||
// _nextPalette instead of _sysPalette. In the SCI32 engine, CelObj palettes
|
||||
// (which are stored as Hunk palettes) are submitted by GraphicsMgr::FrameOut
|
||||
// to PaletteMgr::Submit by way of calls to CelObj::SubmitPalette.
|
||||
// GfxPalette::set is very similar to GfxPalette32::submit, except that SCI32
|
||||
// does not do any fancy best-fit merging and so does not accept arguments
|
||||
// like `force` and `forceRealMerge`.
|
||||
void GfxPalette32::set(Palette *newPalette, bool force, bool forceRealMerge) {
|
||||
submit(*newPalette);
|
||||
}
|
||||
|
||||
bool GfxPalette32::updateForFrame() {
|
||||
applyAll();
|
||||
_versionUpdated = false;
|
||||
return g_sci->_gfxRemap32->remapAllTables(_nextPalette != _sysPalette);
|
||||
_needsUpdate = false;
|
||||
return g_sci->_gfxRemap32->remapAllTables(_nextPalette != _currentPalette);
|
||||
}
|
||||
|
||||
void GfxPalette32::updateFFrame() {
|
||||
for (int i = 0; i < ARRAYSIZE(_nextPalette.colors); ++i) {
|
||||
_nextPalette.colors[i] = _sourcePalette.colors[i];
|
||||
}
|
||||
_versionUpdated = false;
|
||||
g_sci->_gfxRemap32->remapAllTables(_nextPalette != _sysPalette);
|
||||
_needsUpdate = false;
|
||||
g_sci->_gfxRemap32->remapAllTables(_nextPalette != _currentPalette);
|
||||
}
|
||||
|
||||
void GfxPalette32::updateHardware() {
|
||||
if (_sysPalette == _nextPalette) {
|
||||
if (_currentPalette == _nextPalette) {
|
||||
return;
|
||||
}
|
||||
|
||||
byte bpal[3 * 256];
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(_sysPalette.colors); ++i) {
|
||||
_sysPalette.colors[i] = _nextPalette.colors[i];
|
||||
for (int i = 0; i < ARRAYSIZE(_currentPalette.colors); ++i) {
|
||||
_currentPalette.colors[i] = _nextPalette.colors[i];
|
||||
|
||||
// NOTE: If the brightness option in the user configuration file is set,
|
||||
// SCI engine adjusts palette brightnesses here by mapping RGB values to values
|
||||
// in some hard-coded brightness tables. There is no reason on modern hardware
|
||||
// to implement this, unless it is discovered that some game uses a non-standard
|
||||
// brightness setting by default
|
||||
if (_sysPalette.colors[i].used) {
|
||||
bpal[i * 3 ] = _sysPalette.colors[i].r;
|
||||
bpal[i * 3 + 1] = _sysPalette.colors[i].g;
|
||||
bpal[i * 3 + 2] = _sysPalette.colors[i].b;
|
||||
if (_currentPalette.colors[i].used) {
|
||||
bpal[i * 3 ] = _currentPalette.colors[i].r;
|
||||
bpal[i * 3 + 1] = _currentPalette.colors[i].g;
|
||||
bpal[i * 3 + 2] = _currentPalette.colors[i].b;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,6 +287,7 @@ void GfxPalette32::applyAll() {
|
|||
#pragma mark -
|
||||
#pragma mark Colour look-up
|
||||
|
||||
#ifdef ENABLE_SCI3_GAMES
|
||||
bool GfxPalette32::loadClut(uint16 clutId) {
|
||||
// loadClut() will load a color lookup table from a clu file and set
|
||||
// the palette found in the file. This is to be used with Phantasmagoria 2.
|
||||
|
@ -272,27 +337,20 @@ void GfxPalette32::unloadClut() {
|
|||
delete[] _clutTable;
|
||||
_clutTable = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Varying
|
||||
|
||||
inline bool GfxPalette32::createPaletteFromResourceInternal(const GuiResourceId paletteId, Palette *const out) const {
|
||||
Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, paletteId), false);
|
||||
inline Palette GfxPalette32::getPaletteFromResourceInternal(const GuiResourceId resourceId) const {
|
||||
Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), false);
|
||||
|
||||
if (!palResource) {
|
||||
return false;
|
||||
error("Could not load vary target %d", resourceId);
|
||||
}
|
||||
|
||||
createFromData(palResource->data, palResource->size, out);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline Palette GfxPalette32::getPaletteFromResourceInternal(const GuiResourceId paletteId) const {
|
||||
Palette palette;
|
||||
if (!createPaletteFromResourceInternal(paletteId, &palette)) {
|
||||
error("Could not load vary target %d", paletteId);
|
||||
}
|
||||
return palette;
|
||||
HunkPalette rawPalette(palResource->data);
|
||||
return rawPalette.toPalette();
|
||||
}
|
||||
|
||||
inline void GfxPalette32::setVaryTimeInternal(const int16 percent, const int time) {
|
||||
|
|
|
@ -26,6 +26,118 @@
|
|||
#include "sci/graphics/palette.h"
|
||||
|
||||
namespace Sci {
|
||||
|
||||
/**
|
||||
* HunkPalette represents a raw palette resource
|
||||
* read from disk.
|
||||
*/
|
||||
class HunkPalette {
|
||||
public:
|
||||
HunkPalette(byte *rawPalette);
|
||||
|
||||
/**
|
||||
* Gets the version of the palette.
|
||||
*/
|
||||
uint32 getVersion() const { return _version; }
|
||||
|
||||
/**
|
||||
* Sets the version of the palette.
|
||||
*/
|
||||
void setVersion(const uint32 version);
|
||||
|
||||
/**
|
||||
* Converts the hunk palette to a standard
|
||||
* palette.
|
||||
*/
|
||||
const Palette toPalette() const;
|
||||
|
||||
private:
|
||||
enum {
|
||||
/**
|
||||
* The size of the HunkPalette header.
|
||||
*/
|
||||
kHunkPaletteHeaderSize = 13,
|
||||
|
||||
/**
|
||||
* The size of a palette entry header.
|
||||
*/
|
||||
kEntryHeaderSize = 22,
|
||||
|
||||
/**
|
||||
* The offset of the hunk palette version
|
||||
* within the palette entry header.
|
||||
*/
|
||||
kEntryVersionOffset = 18
|
||||
};
|
||||
|
||||
/**
|
||||
* The header for a palette inside the
|
||||
* HunkPalette.
|
||||
*/
|
||||
struct EntryHeader {
|
||||
/**
|
||||
* The start color.
|
||||
*/
|
||||
uint8 startColor;
|
||||
|
||||
/**
|
||||
* The number of palette colors in this
|
||||
* entry.
|
||||
*/
|
||||
uint16 numColors;
|
||||
|
||||
/**
|
||||
* The default `used` flag.
|
||||
*/
|
||||
bool used;
|
||||
|
||||
/**
|
||||
* Whether or not all palette entries
|
||||
* share the same `used` value in
|
||||
* `defaultFlag`.
|
||||
*/
|
||||
bool sharedUsed;
|
||||
|
||||
/**
|
||||
* The palette version.
|
||||
*/
|
||||
uint32 version;
|
||||
};
|
||||
|
||||
/**
|
||||
* The version number from the last time this
|
||||
* palette was submitted to GfxPalette32.
|
||||
*/
|
||||
uint32 _version;
|
||||
|
||||
/**
|
||||
* The number of palettes stored in the hunk
|
||||
* palette. In SCI32 games this is always 1.
|
||||
*/
|
||||
uint8 _numPalettes;
|
||||
|
||||
/**
|
||||
* The raw palette data for this hunk palette.
|
||||
*/
|
||||
byte *_data;
|
||||
|
||||
/**
|
||||
* Returns a struct that describes the palette
|
||||
* held by this HunkPalette. The entry header
|
||||
* is reconstructed on every call from the raw
|
||||
* palette data.
|
||||
*/
|
||||
const EntryHeader getEntryHeader() const;
|
||||
|
||||
/**
|
||||
* Returns a pointer to the palette data within
|
||||
* the hunk palette.
|
||||
*/
|
||||
byte *getPalPointer() const {
|
||||
return _data + kHunkPaletteHeaderSize + (2 * _numPalettes);
|
||||
}
|
||||
};
|
||||
|
||||
enum PalCyclerDirection {
|
||||
PalCycleBackward = 0,
|
||||
PalCycleForward = 1
|
||||
|
@ -72,28 +184,29 @@ struct PalCycler {
|
|||
uint16 numTimesPaused;
|
||||
};
|
||||
|
||||
class GfxPalette32 : public GfxPalette {
|
||||
class GfxPalette32 {
|
||||
public:
|
||||
GfxPalette32(ResourceManager *resMan, GfxScreen *screen);
|
||||
GfxPalette32(ResourceManager *resMan);
|
||||
~GfxPalette32();
|
||||
|
||||
private:
|
||||
// NOTE: currentPalette in SCI engine is called _sysPalette
|
||||
// here.
|
||||
ResourceManager *_resMan;
|
||||
|
||||
/**
|
||||
* The currently displayed palette.
|
||||
*/
|
||||
Palette _currentPalette;
|
||||
|
||||
/**
|
||||
* The palette revision version. Increments once per game
|
||||
* loop that changes the source palette. TODO: Possibly
|
||||
* other areas also change _version, double-check once it
|
||||
* is all implemented.
|
||||
* loop that changes the source palette.
|
||||
*/
|
||||
uint32 _version;
|
||||
|
||||
/**
|
||||
* Whether or not the palette manager version was updated
|
||||
* during this loop.
|
||||
* Whether or not the hardware palette needs updating.
|
||||
*/
|
||||
bool _versionUpdated;
|
||||
bool _needsUpdate;
|
||||
|
||||
/**
|
||||
* The unmodified source palette loaded by kPalette. Additional
|
||||
|
@ -104,7 +217,7 @@ private:
|
|||
|
||||
/**
|
||||
* The palette to be used when the hardware is next updated.
|
||||
* On update, _nextPalette is transferred to _sysPalette.
|
||||
* On update, _nextPalette is transferred to _currentPalette.
|
||||
*/
|
||||
Palette _nextPalette;
|
||||
|
||||
|
@ -112,20 +225,29 @@ private:
|
|||
Palette getPaletteFromResourceInternal(const GuiResourceId paletteId) const;
|
||||
|
||||
public:
|
||||
virtual void saveLoadWithSerializer(Common::Serializer &s) override;
|
||||
void saveLoadWithSerializer(Common::Serializer &s);
|
||||
inline const Palette &getNextPalette() const { return _nextPalette; };
|
||||
inline const Palette &getCurrentPalette() const { return _sysPalette; };
|
||||
inline const Palette &getCurrentPalette() const { return _currentPalette; };
|
||||
|
||||
bool kernelSetFromResource(GuiResourceId resourceId, bool force) override;
|
||||
int16 kernelFindColor(uint16 r, uint16 g, uint16 b) override;
|
||||
void set(Palette *newPalette, bool force, bool forceRealMerge = false) override;
|
||||
/**
|
||||
* Loads a palette into GfxPalette32 with the given resource
|
||||
* ID.
|
||||
*/
|
||||
bool loadPalette(const GuiResourceId resourceId);
|
||||
|
||||
/**
|
||||
* Finds the nearest color in the current palette matching the
|
||||
* given RGB value.
|
||||
*/
|
||||
int16 matchColor(const uint8 r, const uint8 g, const uint8 b);
|
||||
|
||||
/**
|
||||
* Submits a palette to display. Entries marked as “used” in the
|
||||
* submitted palette are merged into the existing entries of
|
||||
* _sourcePalette.
|
||||
*/
|
||||
void submit(Palette &palette);
|
||||
void submit(const Palette &palette);
|
||||
void submit(HunkPalette &palette);
|
||||
|
||||
bool updateForFrame();
|
||||
void updateFFrame();
|
||||
|
@ -213,7 +335,7 @@ public:
|
|||
void kernelPalVarySetTarget(const GuiResourceId paletteId);
|
||||
void kernelPalVarySetStart(const GuiResourceId paletteId);
|
||||
void kernelPalVaryMergeStart(const GuiResourceId paletteId);
|
||||
virtual void kernelPalVaryPause(bool pause) override;
|
||||
void kernelPalVaryPause(bool pause);
|
||||
|
||||
void setVary(const Palette *const targetPalette, const int16 percent, const int time, const int16 fromColor, const int16 toColor);
|
||||
void setVaryPercent(const int16 percent, const int time, const int16 fromColor, const int16 fromColorAlternate);
|
||||
|
|
|
@ -167,9 +167,7 @@ SciEngine::~SciEngine() {
|
|||
DebugMan.clearAllDebugChannels();
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
// _gfxPalette32 is the same as _gfxPalette16
|
||||
// and will be destroyed when _gfxPalette16 is
|
||||
// destroyed
|
||||
delete _gfxPalette32;
|
||||
delete _gfxControls32;
|
||||
delete _gfxPaint32;
|
||||
delete _gfxText32;
|
||||
|
@ -717,8 +715,7 @@ void SciEngine::initGraphics() {
|
|||
|
||||
#ifdef ENABLE_SCI32
|
||||
if (getSciVersion() >= SCI_VERSION_2) {
|
||||
_gfxPalette32 = new GfxPalette32(_resMan, _gfxScreen);
|
||||
_gfxPalette16 = _gfxPalette32;
|
||||
_gfxPalette32 = new GfxPalette32(_resMan);
|
||||
_gfxRemap32 = new GfxRemap32();
|
||||
} else {
|
||||
#endif
|
||||
|
@ -767,8 +764,10 @@ void SciEngine::initGraphics() {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (getSciVersion() < SCI_VERSION_2) {
|
||||
// Set default (EGA, amiga or resource 999) palette
|
||||
_gfxPalette16->setDefault();
|
||||
}
|
||||
}
|
||||
|
||||
void SciEngine::initStackBaseWithSelector(Selector selector) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue