mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-19 16:33:50 +00:00
SCI21: Allow the game scripts to sync robot videos, like in SSCI. Also, references of the SciEngine class to itself via g_sci have been removed
svn-id: r55422
This commit is contained in:
parent
7c14cf2b1b
commit
89087b18c7
@ -1398,6 +1398,7 @@ reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) {
|
||||
reg_t kRobot(EngineState *s, int argc, reg_t *argv) {
|
||||
|
||||
int16 subop = argv[0].toUint16();
|
||||
GfxRobot *robot = g_sci->_gfxRobot;
|
||||
|
||||
switch (subop) {
|
||||
case 0: { // init
|
||||
@ -1407,10 +1408,7 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) {
|
||||
int16 x = argv[4].toUint16();
|
||||
int16 y = argv[5].toUint16();
|
||||
warning("kRobot(init), id %d, obj %04x:%04x, flag %d, x=%d, y=%d", id, PRINT_REG(obj), flag, x, y);
|
||||
GfxRobot *test = new GfxRobot(g_sci->getResMan(), g_sci->_gfxScreen, g_sci->_gfxPalette, id);
|
||||
test->draw(x,y);
|
||||
delete test;
|
||||
|
||||
robot->init(id, x, y);
|
||||
}
|
||||
break;
|
||||
case 1: // LSL6 hires (startup)
|
||||
@ -1422,11 +1420,10 @@ reg_t kRobot(EngineState *s, int argc, reg_t *argv) {
|
||||
}
|
||||
break;
|
||||
case 8: // sync
|
||||
//warning("kRobot(sync), obj %04x:%04x", PRINT_REG(argv[1]));
|
||||
// HACK: Make robots return immediately for now,
|
||||
// otherwise they just hang for a while.
|
||||
// TODO: Replace with proper robot functionality.
|
||||
writeSelector(s->_segMan, argv[1], SELECTOR(signal), SIGNAL_REG);
|
||||
robot->drawNextFrame();
|
||||
// Sync
|
||||
if (robot->getCurFrame() == robot->getFrameCount())
|
||||
writeSelector(s->_segMan, argv[1], SELECTOR(signal), SIGNAL_REG);
|
||||
break;
|
||||
default:
|
||||
warning("kRobot(%d)", subop);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "sci/graphics/paint32.h"
|
||||
#include "sci/graphics/palette.h"
|
||||
#include "sci/graphics/picture.h"
|
||||
#include "sci/graphics/robot.h"
|
||||
#include "sci/graphics/frameout.h"
|
||||
|
||||
namespace Sci {
|
||||
@ -338,6 +339,9 @@ static int16 GetLongest(const char *text, int16 maxWidth, GfxFont *font) {
|
||||
}
|
||||
|
||||
void GfxFrameout::kernelFrameout() {
|
||||
if (g_sci->_gfxRobot->isPlaying())
|
||||
return;
|
||||
|
||||
_palette->palVaryUpdate();
|
||||
|
||||
for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "common/util.h"
|
||||
#include "common/stack.h"
|
||||
|
||||
#include "graphics/primitives.h"
|
||||
|
||||
#include "sci/sci.h"
|
||||
@ -81,8 +82,11 @@ void GfxPaint32::kernelGraphDrawLine(Common::Point startPoint, Common::Point end
|
||||
}
|
||||
|
||||
void GfxPaint32::debugDrawRobot(GuiResourceId robotId) {
|
||||
GfxRobot *test = new GfxRobot(g_sci->getResMan(), _screen, _palette, robotId);
|
||||
test->draw(0,0);
|
||||
GfxRobot *test = new GfxRobot(g_sci->getResMan(), _screen, _palette);
|
||||
test->init(robotId, 0, 0);
|
||||
while (test->getCurFrame() + 1 < test->getFrameCount()) {
|
||||
test->drawNextFrame();
|
||||
}
|
||||
delete test;
|
||||
}
|
||||
|
||||
|
@ -57,10 +57,10 @@ namespace Sci {
|
||||
// around the screen and go behind other objects. (...)
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
GfxRobot::GfxRobot(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette, GuiResourceId resourceId)
|
||||
: _resMan(resMan), _screen(screen), _palette(palette), _resourceId(resourceId) {
|
||||
assert(resourceId != -1);
|
||||
initData(resourceId);
|
||||
GfxRobot::GfxRobot(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette)
|
||||
: _resMan(resMan), _screen(screen), _palette(palette) {
|
||||
_resourceId = -1;
|
||||
_x = _y = 0;
|
||||
}
|
||||
|
||||
GfxRobot::~GfxRobot() {
|
||||
@ -70,11 +70,17 @@ GfxRobot::~GfxRobot() {
|
||||
delete[] _audioLen;
|
||||
}
|
||||
|
||||
void GfxRobot::initData(GuiResourceId resourceId) {
|
||||
void GfxRobot::init(GuiResourceId resourceId, uint16 x, uint16 y) {
|
||||
char fileName[10];
|
||||
uint32 fileSize;
|
||||
|
||||
sprintf(fileName, "%d.rbt", resourceId);
|
||||
// resourceId = 1305; // debug
|
||||
|
||||
_resourceId = resourceId;
|
||||
_x = x;
|
||||
_y = y;
|
||||
_curFrame = 0;
|
||||
sprintf(fileName, "%d.rbt", _resourceId);
|
||||
|
||||
Common::File robotFile;
|
||||
if (robotFile.open(fileName)) {
|
||||
@ -98,28 +104,22 @@ void GfxRobot::initData(GuiResourceId resourceId) {
|
||||
_hasSound = (_resourceData[25] != 0);
|
||||
|
||||
_palOffset = 60;
|
||||
if (_hasSound)
|
||||
|
||||
// Some robot files have sound, which doesn't start from frame 0
|
||||
// (e.g. Phantasmagoria, robot 1305)
|
||||
if (_hasSound && _audioSize > 14)
|
||||
_palOffset += READ_LE_UINT32(_resourceData + 60) + 14;
|
||||
|
||||
getFrameOffsets();
|
||||
assert(_imageStart[_frameCount] == fileSize);
|
||||
|
||||
setPalette();
|
||||
|
||||
debug("Robot %d, %d frames, sound: %s\n", resourceId, _frameCount, _hasSound ? "yes" : "no");
|
||||
}
|
||||
|
||||
void GfxRobot::draw(int x, int y) {
|
||||
|
||||
return; // TODO: Remove once done
|
||||
// Play the audio of the robot file (for debugging)
|
||||
#if 0
|
||||
if (_hasSound) {
|
||||
Audio::SoundHandle _audioHandle;
|
||||
Audio::AudioStream *audioStream = g_sci->_audio->getRobotAudioStream(_resourceData);
|
||||
g_system->getMixer()->playStream(Audio::Mixer::kSpeechSoundType, &_audioHandle, audioStream);
|
||||
}
|
||||
#endif
|
||||
|
||||
byte *paletteData = _hasSound ?
|
||||
void GfxRobot::setPalette() {
|
||||
byte *paletteData = (_hasSound && _audioSize > 14) ?
|
||||
_resourceData + 60 + 14 + _audioSize :
|
||||
_resourceData + 60;
|
||||
uint16 paletteSize = READ_LE_UINT16(_resourceData + 16);
|
||||
@ -127,7 +127,6 @@ void GfxRobot::draw(int x, int y) {
|
||||
Palette resourcePal;
|
||||
|
||||
byte robotPal[256 * 4];
|
||||
byte savePal[256 * 4];
|
||||
int startIndex = READ_LE_UINT16(paletteData + 25);
|
||||
int colorCount = READ_LE_UINT16(paletteData + 29);
|
||||
|
||||
@ -136,13 +135,13 @@ void GfxRobot::draw(int x, int y) {
|
||||
_palette->createFromData(paletteData, paletteSize, &resourcePal);
|
||||
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
savePal[i * 4 + 0] = _palette->_sysPalette.colors[i].r;
|
||||
savePal[i * 4 + 1] = _palette->_sysPalette.colors[i].g;
|
||||
savePal[i * 4 + 2] = _palette->_sysPalette.colors[i].b;
|
||||
savePal[i * 4 + 3] = 0;
|
||||
_savedPal[i * 4 + 0] = _palette->_sysPalette.colors[i].r;
|
||||
_savedPal[i * 4 + 1] = _palette->_sysPalette.colors[i].g;
|
||||
_savedPal[i * 4 + 2] = _palette->_sysPalette.colors[i].b;
|
||||
_savedPal[i * 4 + 3] = 0;
|
||||
}
|
||||
|
||||
memcpy(robotPal, savePal, sizeof(savePal));
|
||||
memcpy(robotPal, _savedPal, sizeof(_savedPal));
|
||||
|
||||
for (int i = 0; i < colorCount; ++i) {
|
||||
int index = i + startIndex;
|
||||
@ -153,19 +152,34 @@ void GfxRobot::draw(int x, int y) {
|
||||
}
|
||||
|
||||
g_system->setPalette(robotPal, 0, 256);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _frameCount; ++i) {
|
||||
int width, height;
|
||||
|
||||
byte *pixels = assembleVideoFrame(i);
|
||||
getFrameDimensions(i, width, height);
|
||||
g_system->copyRectToScreen(pixels, width, x, y, width, height * getFrameScale(i) / 100);
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(100);
|
||||
delete[] pixels;
|
||||
void GfxRobot::drawNextFrame() {
|
||||
// Play the audio of the robot file (for debugging)
|
||||
#if 0
|
||||
if (_hasSound) {
|
||||
Audio::SoundHandle _audioHandle;
|
||||
Audio::AudioStream *audioStream = g_sci->_audio->getRobotAudioStream(_resourceData);
|
||||
g_system->getMixer()->playStream(Audio::Mixer::kSpeechSoundType, &_audioHandle, audioStream);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_system->setPalette(savePal, 0, 256);
|
||||
int width, height;
|
||||
|
||||
byte *pixels = assembleVideoFrame(_curFrame);
|
||||
getFrameDimensions(_curFrame, width, height);
|
||||
g_system->copyRectToScreen(pixels, width, _x, _y, width, height * getFrameScale(_curFrame) / 100);
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(100);
|
||||
delete[] pixels;
|
||||
|
||||
_curFrame++;
|
||||
|
||||
if (_curFrame == _frameCount) {
|
||||
// End of robot video, restore palette
|
||||
g_system->setPalette(_savedPal, 0, 256);
|
||||
_resourceId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void GfxRobot::getFrameOffsets() {
|
||||
@ -183,7 +197,7 @@ void GfxRobot::getFrameOffsets() {
|
||||
if (frameDataOffset & 0x7ff)
|
||||
frameDataOffset = (frameDataOffset & ~0x7ff)+0x800;
|
||||
|
||||
_imageStart = new uint32[_frameCount+1];
|
||||
_imageStart = new uint32[_frameCount + 1];
|
||||
_audioStart = new uint32[_frameCount];
|
||||
_audioLen = new uint32[_frameCount];
|
||||
|
||||
@ -276,9 +290,7 @@ void GfxRobot::getFrameRect(int frame, Common::Rect &rect) {
|
||||
|
||||
int GfxRobot::getFrameScale(int frame) {
|
||||
byte *videoData = _resourceData + _imageStart[frame];
|
||||
byte percentage = videoData[3];
|
||||
|
||||
return percentage;
|
||||
return videoData[3];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -33,10 +33,14 @@ namespace Sci {
|
||||
#ifdef ENABLE_SCI32
|
||||
class GfxRobot {
|
||||
public:
|
||||
GfxRobot(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette, GuiResourceId resourceId);
|
||||
GfxRobot(ResourceManager *resMan, GfxScreen *screen, GfxPalette *palette);
|
||||
~GfxRobot();
|
||||
|
||||
void draw(int x, int y);
|
||||
void init(GuiResourceId resourceId, uint16 x, uint16 y);
|
||||
void drawNextFrame();
|
||||
uint16 getCurFrame() { return _curFrame; }
|
||||
uint16 getFrameCount() { return _frameCount; }
|
||||
bool isPlaying() { return _resourceId != -1; }
|
||||
|
||||
private:
|
||||
void initData(GuiResourceId resourceId);
|
||||
@ -45,6 +49,7 @@ private:
|
||||
void getFrameDimensions(int frame, int &width, int &height);
|
||||
void getFrameRect(int frame, Common::Rect &rect); // Not sure what to use this for yet
|
||||
int getFrameScale(int frame); // Scale factor (multiplied by 100). More like custom height, but why use a percentage for it?
|
||||
void setPalette();
|
||||
|
||||
ResourceManager *_resMan;
|
||||
GfxScreen *_screen;
|
||||
@ -52,7 +57,10 @@ private:
|
||||
|
||||
GuiResourceId _resourceId;
|
||||
byte *_resourceData;
|
||||
byte _savedPal[256 * 4];
|
||||
|
||||
uint16 _x;
|
||||
uint16 _y;
|
||||
//uint16 _width;
|
||||
//uint16 _height;
|
||||
uint16 _frameCount;
|
||||
@ -63,6 +71,7 @@ private:
|
||||
uint32 *_imageStart;
|
||||
uint32 *_audioStart;
|
||||
uint32 *_audioLen;
|
||||
uint16 _curFrame;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "sci/graphics/transitions.h"
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
#include "sci/graphics/robot.h"
|
||||
#include "sci/graphics/frameout.h"
|
||||
#endif
|
||||
|
||||
@ -145,6 +146,7 @@ SciEngine::~SciEngine() {
|
||||
DebugMan.clearAllDebugChannels();
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
delete _gfxRobot;
|
||||
delete _gfxFrameout;
|
||||
#endif
|
||||
delete _gfxMenu;
|
||||
@ -585,6 +587,7 @@ void SciEngine::initGraphics() {
|
||||
_gfxText16 = 0;
|
||||
_gfxTransitions = 0;
|
||||
#ifdef ENABLE_SCI32
|
||||
_gfxRobot = 0;
|
||||
_gfxFrameout = 0;
|
||||
_gfxPaint32 = 0;
|
||||
#endif
|
||||
@ -610,24 +613,25 @@ void SciEngine::initGraphics() {
|
||||
// SCI32 graphic objects creation
|
||||
_gfxCoordAdjuster = new GfxCoordAdjuster32(_gamestate->_segMan);
|
||||
_gfxCursor->init(_gfxCoordAdjuster, _eventMan);
|
||||
_gfxCompare = new GfxCompare(_gamestate->_segMan, g_sci->getKernel(), _gfxCache, _gfxScreen, _gfxCoordAdjuster);
|
||||
_gfxPaint32 = new GfxPaint32(g_sci->getResMan(), _gamestate->_segMan, g_sci->getKernel(), _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette);
|
||||
_gfxCompare = new GfxCompare(_gamestate->_segMan, _kernel, _gfxCache, _gfxScreen, _gfxCoordAdjuster);
|
||||
_gfxPaint32 = new GfxPaint32(_resMan, _gamestate->_segMan, _kernel, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette);
|
||||
_gfxPaint = _gfxPaint32;
|
||||
_gfxFrameout = new GfxFrameout(_gamestate->_segMan, g_sci->getResMan(), _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32);
|
||||
_gfxRobot = new GfxRobot(_resMan, _gfxScreen, _gfxPalette);
|
||||
_gfxFrameout = new GfxFrameout(_gamestate->_segMan, _resMan, _gfxCoordAdjuster, _gfxCache, _gfxScreen, _gfxPalette, _gfxPaint32);
|
||||
} else {
|
||||
#endif
|
||||
// SCI0-SCI1.1 graphic objects creation
|
||||
_gfxPorts = new GfxPorts(_gamestate->_segMan, _gfxScreen);
|
||||
_gfxCoordAdjuster = new GfxCoordAdjuster16(_gfxPorts);
|
||||
_gfxCursor->init(_gfxCoordAdjuster, g_sci->getEventManager());
|
||||
_gfxCompare = new GfxCompare(_gamestate->_segMan, g_sci->getKernel(), _gfxCache, _gfxScreen, _gfxCoordAdjuster);
|
||||
_gfxTransitions = new GfxTransitions(_gfxScreen, _gfxPalette, g_sci->getResMan()->isVGA());
|
||||
_gfxPaint16 = new GfxPaint16(g_sci->getResMan(), _gamestate->_segMan, g_sci->getKernel(), _gfxCache, _gfxPorts, _gfxCoordAdjuster, _gfxScreen, _gfxPalette, _gfxTransitions, _audio);
|
||||
_gfxCursor->init(_gfxCoordAdjuster, _eventMan);
|
||||
_gfxCompare = new GfxCompare(_gamestate->_segMan, _kernel, _gfxCache, _gfxScreen, _gfxCoordAdjuster);
|
||||
_gfxTransitions = new GfxTransitions(_gfxScreen, _gfxPalette, _resMan->isVGA());
|
||||
_gfxPaint16 = new GfxPaint16(_resMan, _gamestate->_segMan, _kernel, _gfxCache, _gfxPorts, _gfxCoordAdjuster, _gfxScreen, _gfxPalette, _gfxTransitions, _audio);
|
||||
_gfxPaint = _gfxPaint16;
|
||||
_gfxAnimate = new GfxAnimate(_gamestate, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen, _gfxPalette, _gfxCursor, _gfxTransitions);
|
||||
_gfxText16 = new GfxText16(g_sci->getResMan(), _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen);
|
||||
_gfxText16 = new GfxText16(_resMan, _gfxCache, _gfxPorts, _gfxPaint16, _gfxScreen);
|
||||
_gfxControls = new GfxControls(_gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen);
|
||||
_gfxMenu = new GfxMenu(g_sci->getEventManager(), _gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen, _gfxCursor);
|
||||
_gfxMenu = new GfxMenu(_eventMan, _gamestate->_segMan, _gfxPorts, _gfxPaint16, _gfxText16, _gfxScreen, _gfxCursor);
|
||||
|
||||
_gfxMenu->reset();
|
||||
#ifdef ENABLE_SCI32
|
||||
@ -663,14 +667,14 @@ void SciEngine::runGame() {
|
||||
if (DebugMan.isDebugChannelEnabled(kDebugLevelOnStartup))
|
||||
_console->attach();
|
||||
|
||||
g_sci->getEngineState()->_syncedAudioOptions = false;
|
||||
_gamestate->_syncedAudioOptions = false;
|
||||
|
||||
do {
|
||||
_gamestate->_executionStackPosChanged = false;
|
||||
run_vm(_gamestate);
|
||||
exitGame();
|
||||
|
||||
g_sci->getEngineState()->_syncedAudioOptions = true;
|
||||
_gamestate->_syncedAudioOptions = true;
|
||||
|
||||
if (_gamestate->abortScriptProcessing == kAbortRestartGame) {
|
||||
_gamestate->_segMan->resetSegMan();
|
||||
@ -701,7 +705,7 @@ void SciEngine::exitGame() {
|
||||
if (_gamestate->abortScriptProcessing != kAbortLoadGame) {
|
||||
_gamestate->_executionStack.clear();
|
||||
_audio->stopAllAudio();
|
||||
g_sci->_soundCmd->clearPlayList();
|
||||
_soundCmd->clearPlayList();
|
||||
}
|
||||
|
||||
// TODO Free parser segment here
|
||||
@ -809,9 +813,9 @@ void SciEngine::syncSoundSettings() {
|
||||
|
||||
int soundVolumeMusic = (mute ? 0 : ConfMan.getInt("music_volume"));
|
||||
|
||||
if (_gamestate && g_sci->_soundCmd) {
|
||||
if (_gamestate && _soundCmd) {
|
||||
int vol = (soundVolumeMusic + 1) * MUSIC_MASTERVOLUME_MAX / Audio::Mixer::kMaxMixerVolume;
|
||||
g_sci->_soundCmd->setMasterVolume(vol);
|
||||
_soundCmd->setMasterVolume(vol);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,7 @@ class GfxTransitions;
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
class SciGui32;
|
||||
class GfxRobot;
|
||||
class GfxFrameout;
|
||||
#endif
|
||||
|
||||
@ -312,6 +313,7 @@ public:
|
||||
GfxMacIconBar *_gfxMacIconBar; // Mac Icon Bar manager
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
GfxRobot *_gfxRobot;
|
||||
GfxFrameout *_gfxFrameout; // kFrameout and the like for 32-bit gfx
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user