mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-09 04:16:34 +00:00
DIRECTOR: Allow for palette changes when seeking to arbitrary frames
In Director, palette IDs in the palette channel apply to all subsequent frames. If we seek to an arbitrary frame, the correct palette should be applied. Fixes the introductory cutscene in Majestic: Part 1.
This commit is contained in:
parent
dd43a7d2c4
commit
8eb6cd2ac0
@ -38,7 +38,9 @@ Frame::Frame(Score *score, int numChannels) {
|
||||
_transArea = 0;
|
||||
_transChunkSize = 0;
|
||||
_tempo = 0;
|
||||
|
||||
_scoreCachedTempo = 0;
|
||||
_scoreCachedPaletteId = 0;
|
||||
|
||||
_numChannels = numChannels;
|
||||
|
||||
|
@ -117,7 +117,9 @@ public:
|
||||
TransitionType _transType;
|
||||
PaletteInfo _palette;
|
||||
uint8 _tempo;
|
||||
|
||||
uint8 _scoreCachedTempo;
|
||||
int _scoreCachedPaletteId;
|
||||
|
||||
CastMemberID _sound1;
|
||||
uint8 _soundType1;
|
||||
|
@ -591,13 +591,13 @@ bool Score::renderTransition(uint16 frameId) {
|
||||
|
||||
if (tp) {
|
||||
setLastPalette(frameId);
|
||||
_window->playTransition(frameId, tp->duration, tp->area, tp->chunkSize, tp->type, resolvePaletteId(currentFrame->_palette.paletteId));
|
||||
_window->playTransition(frameId, tp->duration, tp->area, tp->chunkSize, tp->type, resolvePaletteId(currentFrame->_scoreCachedPaletteId));
|
||||
delete _window->_puppetTransition;
|
||||
_window->_puppetTransition = nullptr;
|
||||
return true;
|
||||
} else if (currentFrame->_transType) {
|
||||
setLastPalette(frameId);
|
||||
_window->playTransition(frameId, currentFrame->_transDuration, currentFrame->_transArea, currentFrame->_transChunkSize, currentFrame->_transType, resolvePaletteId(currentFrame->_palette.paletteId));
|
||||
_window->playTransition(frameId, currentFrame->_transDuration, currentFrame->_transArea, currentFrame->_transChunkSize, currentFrame->_transType, resolvePaletteId(currentFrame->_scoreCachedPaletteId));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -666,8 +666,7 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
|
||||
if (_puppetPalette)
|
||||
return false;
|
||||
|
||||
// If the palette is defined in the frame and doesn't match
|
||||
// the current one, set it
|
||||
// Skip this if we don't have a palette instruction
|
||||
int currentPalette = _frames[frameId]->_palette.paletteId;
|
||||
if (!currentPalette || !resolvePaletteId(currentPalette))
|
||||
return false;
|
||||
@ -675,11 +674,6 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
|
||||
if (!_frames[frameId]->_palette.colorCycling &&
|
||||
!_frames[frameId]->_palette.overTime) {
|
||||
|
||||
// Copy the current palette into the snapshot buffer
|
||||
memset(_paletteSnapshotBuffer, 0, 768);
|
||||
memcpy(_paletteSnapshotBuffer, g_director->getPalette(), g_director->getPaletteColorCount() * 3);
|
||||
PaletteV4 *destPal = g_director->getPalette(resolvePaletteId(currentPalette));
|
||||
|
||||
int frameRate = CLIP<int>(_frames[frameId]->_palette.speed, 1, 30);
|
||||
|
||||
if (debugChannelSet(-1, kDebugFast))
|
||||
@ -689,6 +683,11 @@ bool Score::renderPrePaletteCycle(uint16 frameId, RenderMode mode) {
|
||||
int fadeFrames = kFadeColorFrames[frameRate - 1];
|
||||
byte calcPal[768];
|
||||
|
||||
// Copy the current palette into the snapshot buffer
|
||||
memset(_paletteSnapshotBuffer, 0, 768);
|
||||
memcpy(_paletteSnapshotBuffer, g_director->getPalette(), g_director->getPaletteColorCount() * 3);
|
||||
PaletteV4 *destPal = g_director->getPalette(resolvePaletteId(currentPalette));
|
||||
|
||||
if (_frames[frameId]->_palette.normal) {
|
||||
// For fade palette transitions, the whole fade happens with
|
||||
// the previous frame's layout.
|
||||
@ -757,20 +756,38 @@ void Score::setLastPalette(uint16 frameId) {
|
||||
if (_puppetPalette)
|
||||
return;
|
||||
|
||||
bool isCachedPalette = false;
|
||||
int currentPalette = _frames[frameId]->_palette.paletteId;
|
||||
// Palette specified in the frame
|
||||
if (currentPalette) {
|
||||
// If for whatever reason the palette index is invalid, skip
|
||||
if (!resolvePaletteId(currentPalette))
|
||||
return;
|
||||
} else {
|
||||
// Use the score cached palette ID
|
||||
isCachedPalette = true;
|
||||
currentPalette = _frames[frameId]->_scoreCachedPaletteId;
|
||||
// The cached ID is created before the cast gets loaded; if it's zero,
|
||||
// this corresponds to the movie default palette.
|
||||
if (!currentPalette)
|
||||
currentPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette;
|
||||
// If for whatever reason this doesn't resolve, abort.
|
||||
if (!currentPalette || !resolvePaletteId(currentPalette))
|
||||
return;
|
||||
}
|
||||
|
||||
// If the palette is defined in the frame and doesn't match
|
||||
// the current one, set it
|
||||
int currentPalette = _frames[frameId]->_palette.paletteId;
|
||||
if (!currentPalette || !resolvePaletteId(currentPalette))
|
||||
return;
|
||||
|
||||
bool paletteChanged = currentPalette != _lastPalette && currentPalette;
|
||||
if (paletteChanged) {
|
||||
debugC(2, kDebugImages, "Score::setLastPalette(): palette changed to %d", currentPalette);
|
||||
debugC(2, kDebugImages, "Score::setLastPalette(): palette changed to %d, from %s", currentPalette, isCachedPalette ? "cache" :"frame");
|
||||
_lastPalette = currentPalette;
|
||||
_paletteTransitionIndex = 0;
|
||||
|
||||
// For color cycling mode, if there's a new palette, switch to it immediately
|
||||
if (_frames[frameId]->_palette.colorCycling)
|
||||
// Switch to a new palette immediately if:
|
||||
// - this is color cycling mode, or
|
||||
// - the cached palette ID is different (i.e. we jumped in the score)
|
||||
if (_frames[frameId]->_palette.colorCycling || isCachedPalette)
|
||||
g_director->setPalette(resolvePaletteId(_lastPalette));
|
||||
}
|
||||
|
||||
@ -1269,6 +1286,7 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
|
||||
memset(channelData, 0, kChannelDataSize);
|
||||
|
||||
uint8 currentTempo = 0;
|
||||
int currentPaletteId = 0;
|
||||
|
||||
while (size != 0 && !stream.eos()) {
|
||||
uint16 frameSize = stream.readUint16();
|
||||
@ -1305,6 +1323,11 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
|
||||
if (frame->_tempo && frame->_tempo <= 120)
|
||||
currentTempo = frame->_tempo;
|
||||
frame->_scoreCachedTempo = frame->_tempo ? frame->_tempo : currentTempo;
|
||||
// Precache the current palette ID, as this carries forward to frames to the right
|
||||
// of the instruction.
|
||||
if (frame->_palette.paletteId)
|
||||
currentPaletteId = frame->_palette.paletteId;
|
||||
frame->_scoreCachedPaletteId = currentPaletteId;
|
||||
|
||||
debugC(8, kDebugLoading, "Score::loadFrames(): Frame %d actionId: %s", _frames.size(), frame->_actionId.asString().c_str());
|
||||
|
||||
@ -1476,15 +1499,15 @@ Common::String Score::formatChannelInfo() {
|
||||
Frame &frame = *_frames[_currentFrame];
|
||||
Common::String result;
|
||||
int defaultPalette = g_director->getCurrentMovie()->getCast()->_defaultPalette;
|
||||
result += Common::String::format("TMPO: tempo: %d, skipFrameFlag: %d, blend: %d\n",
|
||||
frame._tempo, frame._skipFrameFlag, frame._blend);
|
||||
result += Common::String::format("TMPO: tempo: %d, skipFrameFlag: %d, blend: %d, currentFPS: %d\n",
|
||||
frame._tempo, frame._skipFrameFlag, frame._blend, _currentFrameRate);
|
||||
if (frame._palette.paletteId) {
|
||||
result += Common::String::format("PAL: paletteId: %d, firstColor: %d, lastColor: %d, flags: %d, cycleCount: %d, speed: %d, frameCount: %d, fade: %d, delay: %d, style: %d, defaultId: %d\n",
|
||||
frame._palette.paletteId, frame._palette.firstColor, frame._palette.lastColor, frame._palette.flags,
|
||||
result += Common::String::format("PAL: paletteId: %d, firstColor: %d, lastColor: %d, flags: %d, cycleCount: %d, speed: %d, frameCount: %d, fade: %d, delay: %d, style: %d, currentId: %d, defaultId: %d\n",
|
||||
resolvePaletteId(frame._palette.paletteId), frame._palette.firstColor, frame._palette.lastColor, frame._palette.flags,
|
||||
frame._palette.cycleCount, frame._palette.speed, frame._palette.frameCount,
|
||||
frame._palette.fade, frame._palette.delay, frame._palette.style, defaultPalette);
|
||||
frame._palette.fade, frame._palette.delay, frame._palette.style, resolvePaletteId(_lastPalette), defaultPalette);
|
||||
} else {
|
||||
result += Common::String::format("PAL: paletteId: 000, defaultId: %d\n", defaultPalette);
|
||||
result += Common::String::format("PAL: paletteId: 000, currentId: %d, defaultId: %d\n", resolvePaletteId(_lastPalette), defaultPalette);
|
||||
}
|
||||
result += Common::String::format("TRAN: transType: %d, transDuration: %d, transChunkSize: %d\n",
|
||||
frame._transType, frame._transDuration, frame._transChunkSize);
|
||||
|
Loading…
x
Reference in New Issue
Block a user