Initial commit
This commit is contained in:
676
engines/sci/graphics/palette32.h
Normal file
676
engines/sci/graphics/palette32.h
Normal file
@@ -0,0 +1,676 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCI_GRAPHICS_PALETTE32_H
|
||||
#define SCI_GRAPHICS_PALETTE32_H
|
||||
|
||||
#include "common/ptr.h"
|
||||
|
||||
namespace Sci {
|
||||
|
||||
#pragma mark HunkPalette
|
||||
|
||||
/**
|
||||
* HunkPalette represents a raw palette resource read from disk. The data
|
||||
* structure of a HunkPalette allows palettes to be smaller than 256 colors. It
|
||||
* also allows multiple palettes to be stored in one HunkPalette, though in
|
||||
* SCI32 games there seems to only ever be one palette per HunkPalette.
|
||||
*/
|
||||
class HunkPalette {
|
||||
public:
|
||||
HunkPalette(const SciSpan<const byte> &rawPalette);
|
||||
|
||||
static void write(SciSpan<byte> &out, const Palette &palette);
|
||||
|
||||
static uint32 calculateHunkPaletteSize(const uint16 numIndexes = 256, const bool sharedUsed = true) {
|
||||
const int numPalettes = 1;
|
||||
return kHunkPaletteHeaderSize +
|
||||
/* slack bytes between hunk header & palette offset table */ 2 +
|
||||
/* palette offset table */ 2 * numPalettes +
|
||||
/* palette data */ (kEntryHeaderSize + numIndexes * (/* RGB */ 3 + !sharedUsed)) * numPalettes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version of the palette. Used to avoid resubmitting a HunkPalette
|
||||
* which has already been submitted for the next frame.
|
||||
*/
|
||||
uint32 getVersion() const { return _version; }
|
||||
|
||||
/**
|
||||
* Sets the version of the palette.
|
||||
*/
|
||||
void setVersion(const uint32 version) const;
|
||||
|
||||
/**
|
||||
* Converts the hunk palette to a standard Palette.
|
||||
*/
|
||||
const Palette toPalette() const;
|
||||
|
||||
private:
|
||||
enum {
|
||||
/**
|
||||
* The offset into the HunkPalette header of the number of palettes in
|
||||
* the HunkPalette.
|
||||
*/
|
||||
kNumPaletteEntriesOffset = 10,
|
||||
|
||||
/**
|
||||
* The size of the HunkPalette header.
|
||||
*/
|
||||
kHunkPaletteHeaderSize = 13,
|
||||
|
||||
/**
|
||||
* The size of a palette entry header.
|
||||
*/
|
||||
kEntryHeaderSize = 22
|
||||
};
|
||||
|
||||
enum {
|
||||
/**
|
||||
* The offset of the start color within the palette entry header.
|
||||
*/
|
||||
kEntryStartColorOffset = 10,
|
||||
|
||||
/**
|
||||
* The offset of the color count within the palette entry header.
|
||||
*/
|
||||
kEntryNumColorsOffset = 14,
|
||||
|
||||
/**
|
||||
* The offset of the shared used palette index flag within the palette
|
||||
* entry header.
|
||||
*/
|
||||
kEntryUsedOffset = 16,
|
||||
|
||||
/**
|
||||
* The offset of the flag within the palette entry header that says
|
||||
* whether or not the corresponding palette data includes used flags for
|
||||
* each palette index individually.
|
||||
*/
|
||||
kEntrySharedUsedOffset = 17,
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
mutable 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.
|
||||
*/
|
||||
SciSpan<const 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.
|
||||
*/
|
||||
SciSpan<const byte> getPalPointer() const {
|
||||
return _data.subspan(kHunkPaletteHeaderSize + (2 * _numPalettes));
|
||||
}
|
||||
};
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark PalCycler
|
||||
|
||||
enum PalCyclerDirection {
|
||||
kPalCycleBackward = 0,
|
||||
kPalCycleForward = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* PalCycler represents a range of palette entries that are rotated on a timer.
|
||||
*/
|
||||
struct PalCycler {
|
||||
/**
|
||||
* The color index of this palette cycler. This value is used as the unique
|
||||
* key for this PalCycler object.
|
||||
*/
|
||||
uint8 fromColor;
|
||||
|
||||
/**
|
||||
* The number of palette slots which are to be cycled by this cycler.
|
||||
*/
|
||||
uint16 numColorsToCycle;
|
||||
|
||||
/**
|
||||
* The current position of the first palette entry.
|
||||
*/
|
||||
uint8 currentCycle;
|
||||
|
||||
/**
|
||||
* The direction of the cycler.
|
||||
*/
|
||||
PalCyclerDirection direction;
|
||||
|
||||
/**
|
||||
* The last tick the cycler cycled.
|
||||
*/
|
||||
uint32 lastUpdateTick;
|
||||
|
||||
/**
|
||||
* The amount of time in ticks each cycle should take to complete. In other
|
||||
* words, the higher the delay, the slower the cycle animation. If delay is
|
||||
* 0, the cycler does not automatically cycle and needs to be cycled
|
||||
* manually by calling `doCycle`.
|
||||
*/
|
||||
int16 delay;
|
||||
|
||||
/**
|
||||
* The number of times this cycler has been paused.
|
||||
*/
|
||||
uint16 numTimesPaused;
|
||||
};
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark GfxPalette32
|
||||
|
||||
class GfxPalette32 {
|
||||
public:
|
||||
GfxPalette32(ResourceManager *resMan);
|
||||
|
||||
void saveLoadWithSerializer(Common::Serializer &s);
|
||||
|
||||
/**
|
||||
* Gets the palette that will be use for the next frame.
|
||||
*/
|
||||
inline const Palette &getNextPalette() const { return _nextPalette; };
|
||||
|
||||
/**
|
||||
* Gets the palette that is used for the current frame.
|
||||
*/
|
||||
inline const Palette &getCurrentPalette() const { return _currentPalette; };
|
||||
|
||||
#ifdef USE_RGB_COLOR
|
||||
/**
|
||||
* Gets the raw hardware palette in RGB format. This should be used instead
|
||||
* of `::PaletteManager::grabPalette` when the OSystem screen is >8bpp.
|
||||
*/
|
||||
inline const uint8 *getHardwarePalette() const { return _hardwarePalette; };
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Gets the palette index for black based on the platform
|
||||
*/
|
||||
uint8 getPlatformBlack() const;
|
||||
|
||||
/**
|
||||
* Gets the palette index for white based on the platform
|
||||
*/
|
||||
uint8 getPlatformWhite() const;
|
||||
|
||||
/**
|
||||
* Submits a palette to display. Entries marked as "used" in the submitted
|
||||
* palette are merged into `_sourcePalette`.
|
||||
*/
|
||||
void submit(const Palette &palette);
|
||||
void submit(const HunkPalette &palette);
|
||||
|
||||
/**
|
||||
* Applies all fades, cycles, remaps, and varies for the current frame to
|
||||
* `nextPalette`.
|
||||
*/
|
||||
bool updateForFrame();
|
||||
|
||||
/**
|
||||
* Copies all palette entries from `sourcePalette` to `nextPalette` and
|
||||
* applies remaps. Unlike `updateForFrame`, this call does not apply fades,
|
||||
* cycles, or varies.
|
||||
*/
|
||||
void updateFFrame();
|
||||
|
||||
/**
|
||||
* Copies all entries from `nextPalette` to `currentPalette` and updates the
|
||||
* backend's raw palette.
|
||||
*/
|
||||
void updateHardware();
|
||||
|
||||
private:
|
||||
ResourceManager *_resMan;
|
||||
|
||||
/**
|
||||
* The palette revision version. Increments once per game loop that changes
|
||||
* the source palette.
|
||||
*/
|
||||
uint32 _version;
|
||||
|
||||
/**
|
||||
* Whether or not the hardware palette needs updating.
|
||||
*/
|
||||
bool _needsUpdate;
|
||||
|
||||
#ifdef USE_RGB_COLOR
|
||||
/**
|
||||
* A local copy of the hardware palette. Used when the backend is in a true
|
||||
* color mode and a change to the game's internal framebuffer occurs that
|
||||
* needs to be reconverted from 8bpp to the backend's bit depth.
|
||||
*/
|
||||
uint8 _hardwarePalette[256 * 3];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The currently displayed palette.
|
||||
*/
|
||||
Palette _currentPalette;
|
||||
|
||||
/**
|
||||
* The unmodified source palette loaded by kPalette. Additional palette
|
||||
* entries may be mixed into the source palette by CelObj objects, which
|
||||
* contain their own palettes.
|
||||
*/
|
||||
Palette _sourcePalette;
|
||||
|
||||
/**
|
||||
* The palette to be used when the hardware is next updated.
|
||||
* On update, `_nextPalette` is transferred to `_currentPalette`.
|
||||
*/
|
||||
Palette _nextPalette;
|
||||
|
||||
/**
|
||||
* Creates and returns a new Palette object with data from the given
|
||||
* resource ID.
|
||||
*/
|
||||
Palette getPaletteFromResource(const GuiResourceId paletteId) const;
|
||||
|
||||
/**
|
||||
* Merges used colors in the `from` palette into the `to` palette.
|
||||
*/
|
||||
void mergePalette(Palette &to, const Palette &from);
|
||||
|
||||
/**
|
||||
* Applies all varies, cycles, and fades to `_nextPalette`.
|
||||
*/
|
||||
void applyAll();
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Varying
|
||||
public:
|
||||
/**
|
||||
* Blends the `target` palette into the current palette over `time` ticks.
|
||||
*
|
||||
* @param target The target palette.
|
||||
* @param percent The amount that the target palette should be blended into
|
||||
* the source palette by the end of the vary.
|
||||
* @param ticks The number of ticks that it should take for the blend to be
|
||||
* completed.
|
||||
* @param fromColor The first palette entry that should be blended.
|
||||
* @param toColor The last palette entry that should be blended.
|
||||
*/
|
||||
void setVary(const Palette &target, const int16 percent, const int32 ticks, const int16 fromColor, const int16 toColor);
|
||||
|
||||
/**
|
||||
* Gets the current vary blend amount.
|
||||
*/
|
||||
inline int16 getVaryPercent() const { return ABS(_varyPercent); }
|
||||
|
||||
/**
|
||||
* Changes the percentage of the current vary to `percent`, to be completed
|
||||
* over `time` ticks, if there is a currently active vary target palette.
|
||||
*/
|
||||
void setVaryPercent(const int16 percent, const int32 time);
|
||||
|
||||
/**
|
||||
* Changes the amount of time, in ticks, an in-progress palette vary should
|
||||
* take to finish.
|
||||
*/
|
||||
void setVaryTime(const int32 ticks);
|
||||
|
||||
/**
|
||||
* Changes the vary percent and time to perform the vary.
|
||||
*/
|
||||
void setVaryTime(const int16 percent, const int32 ticks);
|
||||
|
||||
/**
|
||||
* Removes the active palette vary.
|
||||
*/
|
||||
void varyOff();
|
||||
|
||||
/**
|
||||
* Pauses any active palette vary.
|
||||
*/
|
||||
void varyPause();
|
||||
|
||||
/**
|
||||
* Unpauses any paused palette vary.
|
||||
*/
|
||||
void varyOn();
|
||||
|
||||
/**
|
||||
* Sets the target palette for the blend.
|
||||
*/
|
||||
void setTarget(const Palette &palette);
|
||||
|
||||
/**
|
||||
* Sets the start palette for the blend.
|
||||
*/
|
||||
void setStart(const Palette &palette);
|
||||
|
||||
/**
|
||||
* Merges a new start palette into the existing start palette.
|
||||
*/
|
||||
void mergeStart(const Palette &palette);
|
||||
|
||||
/**
|
||||
* Merges a new target palette into the existing target palette.
|
||||
*/
|
||||
void mergeTarget(const Palette &palette);
|
||||
|
||||
/**
|
||||
* Applies any active palette vary to `_nextPalette`.
|
||||
*/
|
||||
void applyVary();
|
||||
|
||||
void kernelPalVarySet(const GuiResourceId paletteId, const int16 percent, const int32 ticks, const int16 fromColor, const int16 toColor);
|
||||
void kernelPalVaryMergeTarget(const GuiResourceId paletteId);
|
||||
void kernelPalVarySetTarget(const GuiResourceId paletteId);
|
||||
void kernelPalVarySetStart(const GuiResourceId paletteId);
|
||||
void kernelPalVaryMergeStart(const GuiResourceId paletteId);
|
||||
void kernelPalVaryPause(const bool pause);
|
||||
|
||||
private:
|
||||
/**
|
||||
* An optional palette used to provide source colors for a palette vary
|
||||
* operation. If this palette is not specified, `_sourcePalette` is used
|
||||
* instead.
|
||||
*/
|
||||
Common::ScopedPtr<Palette> _varyStartPalette;
|
||||
|
||||
/**
|
||||
* An optional palette used to provide target colors for a palette vary
|
||||
* operation.
|
||||
*/
|
||||
Common::ScopedPtr<Palette> _varyTargetPalette;
|
||||
|
||||
/**
|
||||
* The minimum palette index that has been varied from the source palette.
|
||||
*/
|
||||
uint8 _varyFromColor;
|
||||
|
||||
/**
|
||||
* The maximum palette index that has been varied from the source palette.
|
||||
*/
|
||||
uint8 _varyToColor;
|
||||
|
||||
/**
|
||||
* The tick at the last time the palette vary was updated.
|
||||
*/
|
||||
uint32 _varyLastTick;
|
||||
|
||||
/**
|
||||
* The amount of time that should elapse, in ticks, between each cycle of a
|
||||
* palette vary animation.
|
||||
*/
|
||||
int32 _varyTime;
|
||||
|
||||
/**
|
||||
* The direction of change: -1, 0, or 1.
|
||||
*/
|
||||
int16 _varyDirection;
|
||||
|
||||
/**
|
||||
* The amount, in percent, that the vary color is currently blended into the
|
||||
* source color.
|
||||
*/
|
||||
int16 _varyPercent;
|
||||
|
||||
/**
|
||||
* The target amount that a vary color will be blended into the source
|
||||
* color.
|
||||
*/
|
||||
int16 _varyTargetPercent;
|
||||
|
||||
/**
|
||||
* The number of times palette varying has been paused.
|
||||
*/
|
||||
uint16 _varyNumTimesPaused;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Cycling
|
||||
public:
|
||||
inline const bool *getCycleMap() const { return _cycleMap; }
|
||||
|
||||
/**
|
||||
* Cycle palette entries between `fromColor` and `toColor`, inclusive.
|
||||
* Palette cyclers may not overlap. `fromColor` is used in other methods as
|
||||
* the key for looking up a cycler.
|
||||
*
|
||||
* @param fromColor The first color in the cycle.
|
||||
* @param toColor The last color in the cycle.
|
||||
* @param delay The number of ticks that should elapse between cycles.
|
||||
* @param direction A negative `direction` will cycle backwards instead of
|
||||
* forwards. The numeric value of this argument is ignored;
|
||||
* only its sign is used to determine direction.
|
||||
*/
|
||||
void setCycle(const uint8 fromColor, const uint8 toColor, const int16 direction, const int16 delay);
|
||||
|
||||
/**
|
||||
* Performs a round of palette cycling.
|
||||
*
|
||||
* @param fromColor The color key for the cycler.
|
||||
* @param speed The number of entries that should be cycled this round.
|
||||
*/
|
||||
void doCycle(const uint8 fromColor, const int16 speed);
|
||||
|
||||
/**
|
||||
* Unpauses the cycler starting at `fromColor`.
|
||||
*/
|
||||
void cycleOn(const uint8 fromColor);
|
||||
|
||||
/**
|
||||
* Pauses the cycler starting at `fromColor`.
|
||||
*/
|
||||
void cyclePause(const uint8 fromColor);
|
||||
|
||||
/**
|
||||
* Unpauses all cyclers.
|
||||
*/
|
||||
void cycleAllOn();
|
||||
|
||||
/**
|
||||
* Pauses all cyclers.
|
||||
*/
|
||||
void cycleAllPause();
|
||||
|
||||
/**
|
||||
* Removes the cycler starting at `fromColor`.
|
||||
*/
|
||||
void cycleOff(const uint8 fromColor);
|
||||
|
||||
/**
|
||||
* Removes all cyclers.
|
||||
*/
|
||||
void cycleAllOff();
|
||||
|
||||
private:
|
||||
enum {
|
||||
kNumCyclers = 10
|
||||
};
|
||||
|
||||
typedef Common::ScopedPtr<PalCycler> PalCyclerOwner;
|
||||
PalCyclerOwner _cyclers[kNumCyclers];
|
||||
|
||||
/**
|
||||
* Updates the `currentCycle` of the given `cycler` by `speed` entries.
|
||||
*/
|
||||
void updateCycler(PalCycler &cycler, const int16 speed);
|
||||
|
||||
/**
|
||||
* The cycle map is used to detect overlapping cyclers, and to avoid
|
||||
* remapping to palette entries that are being cycled.
|
||||
*
|
||||
* According to SSCI, when two cyclers overlap, a fatal error has occurred
|
||||
* and the engine will display an error and then exit.
|
||||
*
|
||||
* The color remapping system avoids attempts to remap to palette entries
|
||||
* that are cycling because they won't be the expected color once the cycler
|
||||
* updates the palette entries.
|
||||
*/
|
||||
bool _cycleMap[256];
|
||||
|
||||
/**
|
||||
* Marks `numColorsToClear` colors starting at `fromColor` in the cycle
|
||||
* map as inactive.
|
||||
*/
|
||||
void clearCycleMap(const uint16 fromColor, const uint16 numColorsToClear);
|
||||
|
||||
/**
|
||||
* Marks `numColorsToClear` colors starting at `fromColor` in the cycle
|
||||
* map as active.
|
||||
*/
|
||||
void setCycleMap(const uint16 fromColor, const uint16 numColorsToClear);
|
||||
|
||||
/**
|
||||
* Gets the cycler object that starts at the given `fromColor`, or NULL if
|
||||
* there is no cycler for that color.
|
||||
*/
|
||||
PalCycler *getCycler(const uint16 fromColor);
|
||||
|
||||
/**
|
||||
* Advances all cyclers by one step, regardless of whether or not it is time
|
||||
* to perform another cycle.
|
||||
*/
|
||||
void applyAllCycles();
|
||||
|
||||
/**
|
||||
* Advances, by one step, only the cyclers whose time has come to cycle.
|
||||
*/
|
||||
void applyCycles();
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Fading
|
||||
public:
|
||||
/**
|
||||
* Sets the intensity level for a range of palette entries. An intensity of
|
||||
* zero indicates total darkness. Intensity may also be set above 100
|
||||
* percent to increase the intensity of a palette entry.
|
||||
*/
|
||||
void setFade(const uint16 percent, const uint8 fromColor, const uint16 toColor);
|
||||
|
||||
/**
|
||||
* Resets the intensity of all palette entries to 100%.
|
||||
*/
|
||||
void fadeOff();
|
||||
|
||||
/**
|
||||
* Applies intensity values to the palette entries in `_nextPalette`.
|
||||
*/
|
||||
void applyFade();
|
||||
|
||||
private:
|
||||
/**
|
||||
* The intensity levels of each palette entry, in percent. Defaults to 100.
|
||||
*/
|
||||
uint16 _fadeTable[256];
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Gamma correction
|
||||
public:
|
||||
enum {
|
||||
/**
|
||||
* The number of available gamma corrections.
|
||||
*/
|
||||
numGammaTables = 6
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the gamma correction level, from 0 (off) to `numGammaTables`,
|
||||
* inclusive.
|
||||
*/
|
||||
void setGamma(const int16 level) {
|
||||
_gammaLevel = CLIP<int16>(level, 0, numGammaTables) - 1;
|
||||
_gammaChanged = true;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* The current gamma correction level. -1 means no correction.
|
||||
*/
|
||||
int8 _gammaLevel;
|
||||
|
||||
/**
|
||||
* Whether the gamma correction has changed since the last call to update
|
||||
* the hardware palette.
|
||||
*/
|
||||
bool _gammaChanged;
|
||||
};
|
||||
|
||||
} // End of namespace Sci
|
||||
|
||||
#endif // SCI_GRAPHICS_PALETTE32_H
|
||||
Reference in New Issue
Block a user