diff options
Diffstat (limited to 'engines/mads')
-rw-r--r-- | engines/mads/nebular/dialogs_nebular.cpp | 12 | ||||
-rw-r--r-- | engines/mads/nebular/menu_nebular.cpp | 183 | ||||
-rw-r--r-- | engines/mads/nebular/menu_nebular.h | 17 | ||||
-rw-r--r-- | engines/mads/nebular/nebular_scenes.cpp | 2 | ||||
-rw-r--r-- | engines/mads/nebular/sound_nebular.cpp | 307 | ||||
-rw-r--r-- | engines/mads/nebular/sound_nebular.h | 59 | ||||
-rw-r--r-- | engines/mads/scene.cpp | 1 | ||||
-rw-r--r-- | engines/mads/sound.cpp | 3 |
8 files changed, 558 insertions, 26 deletions
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index f3eddc3fbb..5b0fb7b538 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -313,6 +313,18 @@ void DialogsNebular::showDialog() { delete dlg; break; } + case DIALOG_TEXTVIEW: { + TextView *dlg = new TextView(_vm); + dlg->show(); + delete dlg; + break; + } + case DIALOG_ANIMVIEW: { + AnimationView *dlg = new AnimationView(_vm); + dlg->show(); + delete dlg; + break; + } default: break; } diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index 98eb669616..aa14353092 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -24,6 +24,7 @@ #include "mads/game.h" #include "mads/mads.h" #include "mads/resources.h" +#include "mads/scene.h" #include "mads/screen.h" #include "mads/nebular/menu_nebular.h" @@ -34,6 +35,7 @@ namespace Nebular { #define NEBULAR_MENUSCREEN 990 #define MADS_MENU_Y ((MADS_SCREEN_HEIGHT - MADS_SCENE_HEIGHT) / 2) #define MADS_MENU_ANIM_DELAY 70 +#define DIALOG_TOP 22 MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) { _breakFlag = false; @@ -44,6 +46,9 @@ MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) { void MenuView::show() { Scene &scene = _vm->_game->_scene; EventsManager &events = *_vm->_events; + _vm->_screenFade = SCREEN_FADE_FAST; + + scene._spriteSlots.reset(true); display(); events.setEventTarget(this); @@ -51,9 +56,7 @@ void MenuView::show() { while (!_breakFlag && !_vm->shouldQuit()) { if (_redrawFlag) { - scene.drawElements(_vm->_game->_fx, _vm->_game->_fx); - - _vm->_screen.copyRectToScreen(Common::Rect(0, 0, 320, 200)); + handleFrame(); _redrawFlag = false; } @@ -65,6 +68,11 @@ void MenuView::show() { events.setEventTarget(nullptr); } +void MenuView::handleFrame() { + _vm->_game->_scene.drawElements(_vm->_game->_fx, _vm->_game->_fx); + _vm->_screen.copyRectToScreen(Common::Rect(0, 0, 320, 200)); +} + void MenuView::display() { _vm->_palette->resetGamePalette(4, 8); @@ -375,6 +383,8 @@ void AdvertView::show() { sceneInfo->load(screenId, 0, Common::String(), 0, _vm->_game->_scene._depthSurface, _vm->_screen); _vm->_screen.copyRectToScreen(_vm->_screen.getBounds()); + _vm->_palette->setFullPalette(_vm->_palette->_mainPalette); + delete sceneInfo; EventsManager &events = *_vm->_events; @@ -426,6 +436,9 @@ TextView::TextView(MADSEngine *vm) : MenuView(vm), _scrollTimeout = 0; _panCountdown = 0; _translationX = 0; + + _vm->_palette->resetGamePalette(4, 8); + load(); } TextView::~TextView() { @@ -433,7 +446,10 @@ TextView::~TextView() { } void TextView::load() { - if (!_script.open(_resourceName)) + Common::String scriptName(_resourceName); + scriptName += ".txr"; + + if (!_script.open(scriptName)) error("Could not open resource %s", _resourceName); processLines(); @@ -444,7 +460,11 @@ void TextView::processLines() { error("Attempted to read past end of response file"); while (!_script.eos()) { + // Read in the next line _script.readLine(_currentLine, 79); + char *p = _currentLine + strlen(_currentLine) - 1; + if (*p == '\n') + *p = '\0'; // Commented out line, so go loop for another if (_currentLine[0] == '#') @@ -499,21 +519,6 @@ void TextView::processCommand() { } else if (!strncmp(commandStr, "GO", 2)) { _animating = true; - // Grab what the final palete will be - byte destPalette[PALETTE_SIZE]; - _vm->_palette->grabPalette(destPalette, 0, 256); - - // Copy the loaded background, if any, to the view surface - //int yp = 22; - //scene._backgroundSurface.copyTo(this, 0, 22); - - // Handle fade-in - //byte srcPalette[768]; - //Common::fill(&srcPalette[0], &srcPalette[PALETTE_SIZE], 0); - //_vm->_palette->fadeIn(srcPalette, destPalette, 0, PALETTE_COUNT, 0, 0, - // TV_FADE_DELAY_MILLI, TV_NUM_FADE_STEPS); - _vm->_game->_fx = kTransitionFadeIn; - } else if (!strncmp(commandStr, "PAN", 3)) { // Set panning values paramP = commandStr + 3; @@ -528,10 +533,12 @@ void TextView::processCommand() { } else if (!strncmp(commandStr, "DRIVER", 6)) { // Set the driver to use - paramP = commandStr + 6; - int driverNum = getParameter(¶mP); - _vm->_sound->init(driverNum); + paramP = commandStr + 7; + if (!strncmp(paramP, "#SOUND.00", 9)) { + int driverNum = paramP[9] - '0'; + _vm->_sound->init(driverNum); + } } else if (!strncmp(commandStr, "SOUND", 5)) { // Set sound number paramP = commandStr + 5; @@ -628,6 +635,138 @@ void TextView::processText() { _vm->_font->writeString(&_textSurface, _currentLine, Common::Point(xStart, yp)); } +void TextView::display() { + _vm->_screen.empty(); + _vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2); + _vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2); + + _vm->_palette->setEntry(10, 0, 63, 0); + _vm->_palette->setEntry(11, 0, 45, 0); + _vm->_palette->setEntry(12, 63, 63, 0); + _vm->_palette->setEntry(13, 45, 45, 0); + _vm->_palette->setEntry(14, 63, 63, 63); + _vm->_palette->setEntry(15, 45, 45, 45); + + // Copy the loaded background, if any, to the view surface + _vm->_game->_scene._backgroundSurface.copyTo(&_vm->_screen, DIALOG_TOP); + _vm->_screen.copyRectToScreen(Common::Rect(0, DIALOG_TOP, + MADS_SCREEN_WIDTH, DIALOG_TOP + MADS_SCENE_HEIGHT)); +} + +void TextView::handleFrame() { + // Stop inherited behaviour +} + +void TextView::doFrame() { + Scene &scene = _vm->_game->_scene; + if (!_animating) + return; + + // Only update state if wait period has expired + uint32 currTime = g_system->getMillis(); + + // If a screen transition is in progress and it's time for another column, handle it + if (_spareScreen) { + byte *srcP = _spareScreen->getBasePtr(_translationX, 0); + byte *destP = scene._backgroundSurface.getBasePtr(_translationX, 0); + + for (int y = 0; y < MADS_SCENE_HEIGHT; ++y, srcP += _spareScreen->w, + destP += MADS_SCREEN_WIDTH) { + *destP = *srcP; + } + + if (++_translationX >= MADS_SCREEN_WIDTH) { + // Surface transition is complete + /* + delete _spareScreen; + _spareScreen = nullptr; + +// _vm->_palette->deleteRange(_bgCurrent); + delete _bgCurrent; + _bgCurrent = _bgSpare; + _bgSpare = nullptr; + */ + } + } + + // Make sure it's time for an update + if (currTime < _scrollTimeout) + return; + _scrollTimeout = g_system->getMillis() + TEXT_ANIMATION_DELAY; + + // If any panning values are set, pan the background surface + if ((_pan.x != 0) || (_pan.y != 0)) { + if (_panCountdown > 0) { + --_panCountdown; + return; + } + + // Handle horizontal panning + if (_pan.x != 0) { + byte *lineTemp = new byte[_pan.x]; + for (int y = 0; y < MADS_SCENE_HEIGHT; ++y) { + byte *pixelsP = (byte *)scene._backgroundSurface.getBasePtr(0, y); + + // Copy the first X pixels into temp buffer, move the rest of the line + // to the start of the line, and then move temp buffer pixels to end of line + Common::copy(pixelsP, pixelsP + _pan.x, lineTemp); + Common::copy(pixelsP + _pan.x, pixelsP + MADS_SCREEN_WIDTH, pixelsP); + Common::copy(lineTemp, lineTemp + _pan.x, pixelsP + MADS_SCREEN_WIDTH - _pan.x); + } + + delete[] lineTemp; + } + + // Handle vertical panning + if (_pan.y != 0) { + // Store the bottom Y lines into a temp buffer, move the rest of the lines down, + // and then copy the stored lines back to the top of the screen + byte *linesTemp = new byte[_pan.y * MADS_SCREEN_WIDTH]; + byte *pixelsP = (byte *)scene._backgroundSurface.getBasePtr(0, MADS_SCENE_HEIGHT - _pan.y); + Common::copy(pixelsP, pixelsP + MADS_SCREEN_WIDTH * _pan.y, linesTemp); + + for (int y = MADS_SCENE_HEIGHT - 1; y >= _pan.y; --y) { + byte *destP = (byte *)scene._backgroundSurface.getBasePtr(0, y); + byte *srcP = (byte *)scene._backgroundSurface.getBasePtr(0, y - _pan.y); + Common::copy(srcP, srcP + MADS_SCREEN_WIDTH, destP); + } + + Common::copy(linesTemp, linesTemp + _pan.y * MADS_SCREEN_WIDTH, + (byte *)scene._backgroundSurface.getPixels()); + delete[] linesTemp; + } + } + + // Scroll the text surface up by one row + byte *pixelsP = (byte *)_textSurface.getPixels(); + Common::copy(pixelsP + _textSurface.w, pixelsP + _textSurface.w * _textSurface.h, pixelsP); + pixelsP = _textSurface.getBasePtr(0, _textSurface.h - 1); + Common::fill(pixelsP, pixelsP + _textSurface.w, 0); + + if (_scrollCount > 0) { + // Handling final scrolling of text off of screen + if (--_scrollCount == 0) { + scriptDone(); + return; + } + } else { + // Handling a text row + if (++_lineY == (_vm->_font->getHeight() + TEXTVIEW_LINE_SPACING)) + processLines(); + } + + // Refresh the view + scene._backgroundSurface.copyTo(&_vm->_screen, Common::Point(0, DIALOG_TOP)); + _textSurface.copyTo(&_vm->_screen, Common::Rect(0, 0, _textSurface.w, MADS_SCENE_HEIGHT), + Common::Point(0, DIALOG_TOP), 0); + _vm->_screen.copyRectToScreen(Common::Rect(0, DIALOG_TOP, + MADS_SCREEN_WIDTH, DIALOG_TOP + MADS_SCENE_HEIGHT)); +} + +void TextView::scriptDone() { + _breakFlag = true; +} + /*------------------------------------------------------------------------*/ char AnimationView::_resourceName[100]; diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h index 6e877a8a24..dfb26eb16e 100644 --- a/engines/mads/nebular/menu_nebular.h +++ b/engines/mads/nebular/menu_nebular.h @@ -43,6 +43,8 @@ protected: virtual void doFrame() = 0; + virtual void handleFrame(); + virtual void display(); public: MenuView(MADSEngine *vm); @@ -188,6 +190,17 @@ private: * Get a parameter from line */ int getParameter(const char **paramP); + + /** + * Called when the script is finished + */ + void scriptDone(); +protected: + virtual void display(); + + virtual void handleFrame(); + + virtual void doFrame(); public: /** * Queue the given text resource for display @@ -219,9 +232,9 @@ private: void processCommand(); void scriptDone(); - - void doFrame(); protected: + virtual void doFrame(); + virtual bool onEvent(Common::Event &event); public: /** diff --git a/engines/mads/nebular/nebular_scenes.cpp b/engines/mads/nebular/nebular_scenes.cpp index c71512ed4c..b5e2491624 100644 --- a/engines/mads/nebular/nebular_scenes.cpp +++ b/engines/mads/nebular/nebular_scenes.cpp @@ -331,7 +331,7 @@ void SceneInfoNebular::loadCodes(MSurface &depthSurface, Common::SeekableReadStr byte runValue = stream->readByte(); // Write out the run length - Common::fill(destP, destP + runLength, runValue); + Common::fill(destP, MIN(endP, destP + runLength), runValue); destP += runLength; // Get the next run length diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp index fc2755db2f..4c6070b528 100644 --- a/engines/mads/nebular/sound_nebular.cpp +++ b/engines/mads/nebular/sound_nebular.cpp @@ -3114,6 +3114,313 @@ int ASound8::command37() { return 0; } +/*-----------------------------------------------------------------------*/ + +const ASound9::CommandPtr ASound9::_commandList[52] = { + &ASound9::command0, &ASound9::command1, &ASound9::command2, &ASound9::command3, + &ASound9::command4, &ASound9::command5, &ASound9::command6, &ASound9::command7, + &ASound9::command8, &ASound9::command9, &ASound9::command10, &ASound9::command11, + &ASound9::command12, &ASound9::command13, &ASound9::command14, &ASound9::command15, + &ASound9::command16, &ASound9::command17, &ASound9::command18, &ASound9::command19, + &ASound9::command20, &ASound9::command21, &ASound9::command22, &ASound9::command23, + &ASound9::command24, &ASound9::command25, &ASound9::command26, &ASound9::command27, + &ASound9::command28, &ASound9::command29, &ASound9::command30, &ASound9::command31, + &ASound9::command32, &ASound9::command33, &ASound9::command34, &ASound9::command35, + &ASound9::command36, &ASound9::command37, &ASound9::command38, &ASound9::command39, + &ASound9::command40, &ASound9::command41, &ASound9::command42, &ASound9::command43, + &ASound9::command44_46, &ASound9::command45, &ASound9::command44_46, &ASound9::command47, + &ASound9::command48, &ASound9::command49, &ASound9::command50, &ASound9::command51 +}; + +ASound9::ASound9(Audio::Mixer *mixer) : ASound(mixer, "asound.009", 0x16F0) { + _v1 = _v2 = 0; + _soundPtr = nullptr; + + // Load sound samples + _soundFile.seek(_dataOffset + 0x50); + for (int i = 0; i < 94; ++i) + _samples.push_back(AdlibSample(_soundFile)); +} + +int ASound9::command(int commandId, int param) { + if (commandId > 60) + return 0; + + _commandParam = param; + _frameCounter = 0; + return (this->*_commandList[commandId])(); +} + +int ASound9::command9() { + _v1 = 1848; + _v2 = 84; + _channels[0].load(loadData(0xAA4, 470)); + _channels[1].load(loadData(0xE4C, 450)); + _channels[2].load(loadData(0x1466, 702)); + _channels[3].load(loadData(0x137E, 232)); + _channels[4].load(loadData(0x1014, 65)); + _channels[5].load(loadData(0x11C4, 44)); + _channels[6].load(loadData(0XC7A, 466)); + return 0; +} + +int ASound9::command10() { + _channels[0].load(loadData(0x1724, 24)); + _channels[1].load(loadData(0x173C, 24)); + _channels[2].load(loadData(0x1754, 20)); + _channels[3].load(loadData(0x1768, 20)); + _channels[4].load(loadData(0x177C, 20)); + _channels[5].load(loadData(0x1790, 20)); + return 0; +} + +int ASound9::command11() { + playSound(0x8232, 168); + playSound(0x82DA, 170); + return 0; +} + +int ASound9::command12() { + playSound(0x80DA, 12); + playSound(0x80E6, 12); + return 0; +} + +int ASound9::command13() { + playSound(0x80F2, 38); + playSound(0x8118, 42); + return 0; +} + +int ASound9::command14() { + playSound(0x81F6, 22); + return 0; +} + +int ASound9::command15() { + playSound(0x818A, 32); + playSound(0x81AA, 32); + return 0; +} + +int ASound9::command16() { + playSound(0x8022, 36); + playSound(0x8046, 42); + return 0; +} + +int ASound9::command17() { + command29(); + playSound(0x858C, 11); + return 0; +} + +int ASound9::command18() { + playSound(0x80C2, 24); + return 0; +} + +int ASound9::command19() { + playSound(0x80A0, 34); + return 0; +} + +int ASound9::command20() { + int v = (getRandomNumber() & 0x10) | 0x4D; + byte *pData = loadData(0x8142, 8); + pData[4] = v & 0x7F; + playSoundData(pData); + return 0; +} + +int ASound9::command21() { + playSound(0x815A, 16); + return 0; +} + +int ASound9::command22() { + playSound(0x816A, 16); + return 0; +} + +int ASound9::command23() { + playSound(0x814A, 16); + return 0; +} + +int ASound9::command24() { + playSound(0x7FE2, 34); + return 0; +} + +int ASound9::command25() { + playSound(0x8004, 30); + return 0; +} + +int ASound9::command26() { + _channels[6].load(loadData(0x8384, 156)); + _channels[7].load(loadData(0x8420, 160)); + return 0; +} + +int ASound9::command27() { + playSound(0x84C0, 140); + return 0; +} + +int ASound9::command28() { + playSound(0x81CA, 10); + return 0; +} + +int ASound9::command29() { + playSound(0x81D4, 10); + return 0; +} + +int ASound9::command30() { + playSound(0x817A, 16); + return 0; +} + +int ASound9::command31() { + playSound(0x820C, 14); + playSound(0x821A, 24); + return 0; +} + +int ASound9::command32() { + playSound(0x8070, 8); + return 0; +} + +int ASound9::command33() { + playSound(0x8078, 16); + playSound(0x8088, 16); + return 0; +} + +int ASound9::command34() { + // Skipped stuff in original + _channels[0].load(loadData(0x17A4, 24)); + _channels[1].load(loadData(0x1CDE, 62)); + _channels[2].load(loadData(0x2672, 980)); + _channels[3].load(loadData(0x3336, 1000)); + _channels[4].load(loadData(0x469E, 176)); + _channels[5].load(loadData(0x57F2, 138)); + + return 0; +} + +int ASound9::command35() { + playSound(0x854C, 64); + return 0; +} + +int ASound9::command36() { + playSound(0x81DE, 10); + playSound(0x81E8, 14); + return 0; +} + +int ASound9::command37() { + byte *pData = loadData(0x8098, 8); + int v = getRandomNumber(); + if ((v &= 0x40) != 0) + v |= 8; + else + v += 0x4A; + + pData[6] = v; + playSoundData(pData); + return 0; +} + +int ASound9::command38() { + playSound(0x100E, 6); + return 0; +} + +int ASound9::command39() { + _soundPtr = loadData(0x1055, 128); + return 0; +} + +int ASound9::command40() { + _soundPtr = loadData(0x118C, 50); + return 0; +} + +int ASound9::command41() { + _soundPtr = loadData(0x11BE, 6); + return 0; +} + +int ASound9::command42() { + _soundPtr = loadData(0x11F0, 50); + return 0; +} + +int ASound9::command43() { + _v1 = _v2 = 80; + _channels[0].load(loadData(0x626A, 90)); + _channels[1].load(loadData(0x67F2, 92)); + _channels[2].load(loadData(0x6CFE, 232)); + _channels[3].load(loadData(0x7146, 236)); + + return 0; +} + +int ASound9::command44_46() { + _soundPtr = loadData(0x10D5, 38); + return 0; +} + +int ASound9::command45() { + _soundPtr = loadData(0x10FB, 38); + return 0; +} + +int ASound9::command47() { + _soundPtr = loadData(0x1121, 107); + return 0; +} + +int ASound9::command48() { + playSound(0x7FD0, 8); + playSound(0x7FD8, 10); + return 0; +} + +int ASound9::command49() { + _channels[0].load(loadData(0x7AD6, 92)); + _channels[1].load(loadData(0x7B32, 90)); + _channels[2].load(loadData(0x7B8C, 738)); + _channels[3].load(loadData(0x7E6E, 28)); + _channels[4].load(loadData(0x7E8A, 30)); + _channels[5].load(loadData(0x7EA8, 30)); + _channels[6].load(loadData(0x7EC6, 195)); + return 0; +} + +int ASound9::command50() { + _soundPtr = loadData(0x1222, 348); + return 0; +} + +int ASound9::command51() { + // Skipped stuff in original + _channels[0].load(loadData(0x17BC, 1282)); + _channels[1].load(loadData(0x1CFC, 2422)); + _channels[2].load(loadData(0x2A46, 2288)); + _channels[3].load(loadData(0x371E, 3964)); + _channels[4].load(loadData(0x474E, 1863)); + _channels[5].load(loadData(0x587C, 2538)); + return 0; +} + + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/sound_nebular.h b/engines/mads/nebular/sound_nebular.h index c485bd7955..744467b45e 100644 --- a/engines/mads/nebular/sound_nebular.h +++ b/engines/mads/nebular/sound_nebular.h @@ -713,6 +713,65 @@ public: virtual int command(int commandId, int param); }; +class ASound9 : public ASound { +private: + int _v1, _v2; + byte *_soundPtr; + + typedef int (ASound9::*CommandPtr)(); + static const CommandPtr _commandList[52]; + + int command9(); + int command10(); + int command11(); + int command12(); + int command13(); + int command14(); + int command15(); + int command16(); + int command17(); + int command18(); + int command19(); + int command20(); + int command21(); + int command22(); + int command23(); + int command24(); + int command25(); + int command26(); + int command27(); + int command28(); + int command29(); + int command30(); + int command31(); + int command32(); + int command33(); + int command34(); + int command35(); + int command36(); + int command37(); + int command38(); + int command39(); + int command40(); + int command41(); + int command42(); + int command43(); + int command44_46(); + int command45(); + int command47(); + int command48(); + int command49(); + int command50(); + int command51(); + int command57(); + int command59(); + int command60(); +public: + ASound9(Audio::Mixer *mixer); + + virtual int command(int commandId, int param); +}; + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index 1f95749fd8..cb68d38eec 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -82,6 +82,7 @@ Scene::Scene(MADSEngine *vm) Scene::~Scene() { delete _sceneLogic; delete _sceneInfo; + delete _animationData; } void Scene::clearVocab() { diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp index bd99aed2f4..35d948e0b0 100644 --- a/engines/mads/sound.cpp +++ b/engines/mads/sound.cpp @@ -73,7 +73,8 @@ void SoundManager::init(int sectionNumber) { _driver = new Nebular::ASound8(_mixer); break; case 9: - error("Sound driver 9 not implemented"); + _driver = new Nebular::ASound9(_mixer); + break; default: _driver = nullptr; break; |