diff options
Diffstat (limited to 'engines/m4/mads_anim.cpp')
-rw-r--r-- | engines/m4/mads_anim.cpp | 745 |
1 files changed, 0 insertions, 745 deletions
diff --git a/engines/m4/mads_anim.cpp b/engines/m4/mads_anim.cpp deleted file mode 100644 index aac21ae65d..0000000000 --- a/engines/m4/mads_anim.cpp +++ /dev/null @@ -1,745 +0,0 @@ -/* 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "common/textconsole.h" - -#include "m4/mads_anim.h" -#include "m4/m4.h" -#include "m4/compression.h" - -namespace M4 { - -#define TEXTVIEW_LINE_SPACING 2 -#define TEXT_ANIMATION_DELAY 100 -#define TV_NUM_FADE_STEPS 40 -#define TV_FADE_DELAY_MILLI 50 - -TextviewView::TextviewView(MadsM4Engine *vm): - View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())), - _bgSurface(vm->_screen->width(), MADS_SURFACE_HEIGHT), - _textSurface(vm->_screen->width(), MADS_SURFACE_HEIGHT + vm->_font->current()->getHeight() + - TEXTVIEW_LINE_SPACING) { - - _screenType = VIEWID_TEXTVIEW; - _screenFlags.layer = LAYER_BACKGROUND; - _screenFlags.visible = true; - _screenFlags.get = SCREVENT_ALL; - _callback = NULL; - _script = NULL; - _spareScreen = NULL; - _bgCurrent = NULL; - _bgSpare = NULL; - reset(); - - // Set up system palette colors and the two colors for text display - _vm->_palette->setMadsSystemPalette(); - RGB8 palData[3]; - palData[0].r = palData[0].g = palData[0].b = 0; - palData[1].r = 0; palData[1].g = palData[1].b = 252; - palData[2].r = 0; palData[2].g = palData[2].b = 180; - _vm->_palette->setPalette(&palData[0], 4, 3); - _vm->_palette->blockRange(4, 3); - - _vm->_font->current()->setColors(5, 6, 4); - - clear(); - _bgSurface.clear(); - _textSurface.clear(); - - int y = (height() - MADS_SURFACE_HEIGHT) / 2; - setColor(2); - hLine(0, width() - 1, y - 2); - hLine(0, width() - 1, height() - y + 1); -} - -TextviewView::~TextviewView() { - if (_script) - _vm->res()->toss(_resourceName); - delete _spareScreen; - delete _bgCurrent; - delete _bgSpare; -} - -void TextviewView::reset() { - _bgSurface.clear(); - _textSurface.clear(); - _animating = false; - _panX = 0; - _panY = 0; - _panSpeed = 0; - _soundDriverLoaded = false; - Common::fill(&_spareScreens[0], &_spareScreens[10], 0); - _scrollCount = 0; - _lineY = -1; - _scrollTimeout = 0; - _panCountdown = 0; - _processEvents = true; -} - -void TextviewView::setScript(const char *resourceName, TextviewCallback callback) { - _callback = callback; - if (_script) - _vm->res()->toss(_resourceName); - if (_spareScreen) { - delete _spareScreen; - _spareScreen = NULL; - } - - reset(); - - strncpy(_resourceName, resourceName, 15); - _resourceName[15] = '\0'; - if (!strchr(_resourceName, '.')) - strcat(_resourceName, ".txr"); - - _script = _vm->res()->get(_resourceName); - - processLines(); -} - -bool TextviewView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) { - if (!_processEvents) - return false; - - // Wait for the Escape key or a mouse press - if (((eventType == KEVENT_KEY) && (param == Common::KEYCODE_ESCAPE)) || - (eventType == MEVENT_LEFT_RELEASE) || (eventType == MEVENT_RIGHT_RELEASE)) { - scriptDone(); - captureEvents = false; - return true; - } - - return false; -} - -void TextviewView::updateState() { - 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 = _bgSurface.getBasePtr(_translationX, 0); - - for (int y = 0; y < _bgSurface.height(); ++y, srcP += _spareScreen->width(), - destP += _bgSurface.width()) { - *destP = *srcP; - } - - if (++_translationX >= _bgSurface.width()) { - // Surface transition is complete - delete _spareScreen; - _spareScreen = NULL; - - _vm->_palette->deleteRange(_bgCurrent); - delete _bgCurrent; - _bgCurrent = _bgSpare; - _bgSpare = NULL; - } - } - - // 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 ((_panX != 0) || (_panY != 0)) { - if (_panCountdown > 0) { - --_panCountdown; - return; - } - - // Handle horizontal panning - if (_panX != 0) { - byte *lineTemp = new byte[_panX]; - for (int y = 0; y < _bgSurface.height(); ++y) { - byte *pixelsP = _bgSurface.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 + _panX, lineTemp); - Common::copy(pixelsP + _panX, pixelsP + _bgSurface.width(), pixelsP); - Common::copy(lineTemp, lineTemp + _panX, pixelsP + _bgSurface.width() - _panX); - } - - delete[] lineTemp; - } - - // Handle vertical panning - if (_panY != 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[_panY * _bgSurface.width()]; - byte *pixelsP = _bgSurface.getBasePtr(0, _bgSurface.height() - _panY); - Common::copy(pixelsP, pixelsP + _bgSurface.width() * _panY, linesTemp); - - for (int y = _bgSurface.height() - 1; y >= _panY; --y) { - byte *destP = _bgSurface.getBasePtr(0, y); - byte *srcP = _bgSurface.getBasePtr(0, y - _panY); - Common::copy(srcP, srcP + _bgSurface.width(), destP); - } - - Common::copy(linesTemp, linesTemp + _panY * _bgSurface.width(), _bgSurface.getBasePtr(0, 0)); - delete[] linesTemp; - } - } - - // Scroll the text surface up by one row - byte *pixelsP = _textSurface.getBasePtr(0, 0); - Common::copy(pixelsP + width(), pixelsP + _textSurface.width() * _textSurface.height(), pixelsP); - pixelsP = _textSurface.getBasePtr(0, _textSurface.height() - 1); - Common::fill(pixelsP, pixelsP + _textSurface.width(), _vm->_palette->BLACK); - - 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->current()->getHeight() + TEXTVIEW_LINE_SPACING)) - processLines(); - } - - // Refresh the view - int yp = (height() - _bgSurface.height()) / 2; - _bgSurface.copyTo(this, 0, yp); - _textSurface.copyTo(this, Common::Rect(0, 0, _textSurface.width(), _bgSurface.height()), - 0, yp, _vm->_palette->BLACK); -} - -void TextviewView::scriptDone() { - TextviewCallback fn = _callback; - MadsM4Engine *vm = _vm; - - // Remove this view from manager and destroy it - _vm->_viewManager->deleteView(this); - - if (fn) - fn(vm); -} - -void TextviewView::processLines() { - strncpy(_currentLine, _script->readLine().c_str(), 79); - if (_script->eos() || _script->err()) - error("Attempted to read past end of response file"); - - while (!_script->eos() && !_script->err()) { - // Commented out line, so go loop for another - if (_currentLine[0] == '#') { - strncpy(_currentLine, _script->readLine().c_str(), 79); - continue; - } - - // Process the line - char *cStart = strchr(_currentLine, '['); - if (cStart) { - while (cStart) { - // Loop for possible multiple commands on one line - char *cEnd = strchr(_currentLine, ']'); - if (!cEnd) - error("Unterminated command '%s' in response file", _currentLine); - - *cEnd = '\0'; - processCommand(); - - // Copy rest of line (if any) to start of buffer - strcpy(_currentLine, cEnd + 1); - - cStart = strchr(_currentLine, '['); - } - - if (_currentLine[0]) { - processText(); - break; - } - - } else { - processText(); - break; - } - - strncpy(_currentLine, _script->readLine().c_str(), 79); - } -} - -void TextviewView::processCommand() { - char commandStr[80]; - char *paramP; - strcpy(commandStr, _currentLine + 1); - str_upper(commandStr); - - if (!strncmp(commandStr, "BACKGROUND", 10)) { - // Set the background - paramP = commandStr + 10; - int screenId = getParameter(¶mP); - _bgSurface.loadBackground(screenId, &_bgCurrent); - _vm->_palette->addRange(_bgCurrent); - _bgSurface.translate(_bgCurrent); - - } else if (!strncmp(commandStr, "GO", 2)) { - _animating = true; - - // Grab what the final palete will be - RGB8 destPalette[256]; - _vm->_palette->grabPalette(destPalette, 0, 256); - - // Copy the loaded background, if any, to the view surface - int yp = (height() - _bgSurface.height()) / 2; - _bgSurface.copyTo(this, 0, yp); - - // Handle fade-in - _processEvents = false; // stop processing events during fade-in - _vm->_palette->fadeIn(TV_NUM_FADE_STEPS, TV_FADE_DELAY_MILLI, destPalette, 256); - _processEvents = true; - - } else if (!strncmp(commandStr, "PAN", 3)) { - // Set panning values - paramP = commandStr + 3; - int panX = getParameter(¶mP); - int panY = getParameter(¶mP); - int panSpeed = getParameter(¶mP); - - if ((panX != 0) || (panY != 0)) { - _panX = panX; - _panY = panY; - _panSpeed = panSpeed; - } - - } else if (!strncmp(commandStr, "DRIVER", 6)) { - // Set the driver to use - // TODO: Handling of the sound drivers - - } else if (!strncmp(commandStr, "SOUND", 5)) { - // Set sound number - paramP = commandStr + 5; - //int soundId = getParameter(¶mP); - - //TODO: Proper handling of the sound drivers/sounds - //if (!_soundDriverLoaded) - // error("Attempted to set sound without loading any driver"); - - } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') || (commandStr[5] == '1'))) { - // Set the text colors - int index = commandStr[5] - '0'; - paramP = commandStr + 6; - - RGB8 palEntry; - palEntry.r = getParameter(¶mP) << 2; - palEntry.g = getParameter(¶mP) << 2; - palEntry.b = getParameter(¶mP) << 2; - _vm->_palette->setPalette(&palEntry, 5 + index, 1); - - } else if (!strncmp(commandStr, "SPARE", 5)) { - // Sets a secondary background number that can be later switched in with a PAGE command - paramP = commandStr + 6; - int spareIndex = commandStr[5] - '0'; - if ((spareIndex >= 0) && (spareIndex <= 9)) { - int screenId = getParameter(¶mP); - - _spareScreens[spareIndex] = screenId; - } - - } else if (!strncmp(commandStr, "PAGE", 4)) { - // Signals to change to a previous specified secondary background - paramP = commandStr + 4; - int spareIndex = getParameter(¶mP); - - // Only allow background switches if one isn't currently in progress - if (!_spareScreen && (_spareScreens[spareIndex] != 0)) { - _spareScreen = new M4Surface(width(), MADS_SURFACE_HEIGHT); - _spareScreen->loadBackground(_spareScreens[spareIndex], &_bgSpare); - _vm->_palette->addRange(_bgSpare); - _spareScreen->translate(_bgSpare); - - _translationX = 0; - } - - } else { - error("Unknown response command: '%s'", commandStr); - } -} - -int TextviewView::getParameter(char **paramP) { - if ((**paramP != '=') && (**paramP != ',')) - return 0; - - int result = 0; - ++*paramP; - while ((**paramP >= '0') && (**paramP <= '9')) { - result = result * 10 + (**paramP - '0'); - ++*paramP; - } - - return result; -} - -void TextviewView::processText() { - int lineWidth, xStart; - - if (!strcmp(_currentLine, "***")) { - // Special signifier for end of script - _scrollCount = _vm->_font->current()->getHeight() * 13; - _lineY = -1; - return; - } - - _lineY = 0; - - // Lines are always centered, except if line contains a '@', in which case the - // '@' marks the position that must be horizontally centered - char *centerP = strchr(_currentLine, '@'); - if (centerP) { - *centerP = '\0'; - xStart = (width() / 2) - _vm->_font->current()->getWidth(_currentLine); - - // Delete the @ character and shift back the remainder of the string - char *p = centerP + 1; - if (*p == ' ') ++p; - strcpy(centerP, p); - - } else { - lineWidth = _vm->_font->current()->getWidth(_currentLine); - xStart = (width() - lineWidth) / 2; - } - - // Copy the text line onto the bottom of the textSurface surface, which will allow it - // to gradually scroll onto the screen - int yp = _textSurface.height() - _vm->_font->current()->getHeight() - TEXTVIEW_LINE_SPACING; - _textSurface.fillRect(Common::Rect(0, yp, _textSurface.width(), _textSurface.height()), - _vm->_palette->BLACK); - _vm->_font->current()->writeString(&_textSurface, _currentLine, xStart, yp); -} - - -//-------------------------------------------------------------------------- - -AnimviewView::AnimviewView(MadsM4Engine *vm): - View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())), - MadsView(this), _backgroundSurface(MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT), - _codeSurface(MADS_SURFACE_WIDTH, MADS_SURFACE_HEIGHT) { - - MadsView::_bgSurface = &_backgroundSurface; - MadsView::_depthSurface = &_codeSurface; - MadsView::setViewport(Common::Rect(0, MADS_Y_OFFSET, MADS_SURFACE_WIDTH, MADS_Y_OFFSET + MADS_SURFACE_HEIGHT)); - - _screenType = VIEWID_ANIMVIEW; - _screenFlags.layer = LAYER_BACKGROUND; - _screenFlags.visible = true; - _screenFlags.get = SCREVENT_ALL; - _callback = NULL; - _script = NULL; - _palData = NULL; - _previousUpdate = 0; - _transition = kTransitionNone; - _activeAnimation = NULL; - _bgLoadFlag = true; - _startFrame = -1; - _scriptDone = false; - - reset(); - - // Set up system palette colors - _vm->_palette->setMadsSystemPalette(); - - // Block reserved palette ranges - _vm->_palette->blockRange(16, 2); - _vm->_palette->blockRange(250, 4); - - clear(); - _backgroundSurface.clear(); - - setColor(2); - hLine(0, width() - 1, MADS_Y_OFFSET - 2); - hLine(0, width() - 1, MADS_Y_OFFSET + MADS_SURFACE_HEIGHT + 2); -} - -AnimviewView::~AnimviewView() { - if (_script) - _vm->res()->toss(_resourceName); - delete _activeAnimation; -} - -void AnimviewView::reset() { - _backgroundSurface.clear(); - _soundDriverLoaded = false; -} - -void AnimviewView::setScript(const char *resourceName, AnimviewCallback callback) { - _callback = callback; - if (_script) - _vm->res()->toss(_resourceName); - - reset(); - - strncpy(_resourceName, resourceName, 15); - _resourceName[15] = '\0'; - if (!strchr(_resourceName, '.')) - strcat(_resourceName, ".res"); - - _script = _vm->res()->get(_resourceName); -} - -bool AnimviewView::onEvent(M4EventType eventType, int32 param, int x, int y, bool &captureEvents) { - // Wait for the Escape key or a mouse press - if (((eventType == KEVENT_KEY) && (param == Common::KEYCODE_ESCAPE)) || - (eventType == MEVENT_LEFT_RELEASE) || (eventType == MEVENT_RIGHT_RELEASE)) { - scriptDone(); - captureEvents = false; - return true; - } - - return false; -} - -void AnimviewView::updateState() { - MadsView::update(); - - if (!_script || _scriptDone) - return; - - if (!_activeAnimation) { - readNextCommand(); - assert(_activeAnimation); - } - - // Update the current animation - _activeAnimation->update(); - if (_activeAnimation->freeFlag()) { - delete _activeAnimation; - _activeAnimation = NULL; - - // Clear up current background and sprites - _backgroundSurface.reset(); - clearLists(); - - // Reset flags - _startFrame = -1; - - readNextCommand(); - - // Check if script is finished - if (_scriptDone) { - scriptDone(); - return; - } - } - - refresh(); -} - -void AnimviewView::readNextCommand() { -static bool tempFlag = true;//****DEBUG - Temporarily allow me to skip several intro scenes **** - - while (!_script->eos() && !_script->err()) { - if (!tempFlag) { - tempFlag = true; - strncpy(_currentLine, _script->readLine().c_str(), 79); - strncpy(_currentLine, _script->readLine().c_str(), 79); - } - - strncpy(_currentLine, _script->readLine().c_str(), 79); - - // Process any switches on the line - char *cStart = strchr(_currentLine, '-'); - while (cStart) { - // Loop for possible multiple commands on one line - char *cEnd = strchr(_currentLine, ' '); - if (!cEnd) - error("Unterminated command '%s' in response file", _currentLine); - - *cEnd = '\0'; - processCommand(); - - // Copy rest of line (if any) to start of buffer - // Don't use strcpy() here, because if the - // rest of the line is the longer of the two - // strings, the memory areas will overlap. - memmove(_currentLine, cEnd + 1, strlen(cEnd + 1) + 1); - - cStart = strchr(_currentLine, '-'); - } - - // If there's something left, presume it's a resource name to process - if (_currentLine[0]) - break; - } - - if (!_currentLine[0]) { - // A blank line at this point means that the end of the animation has been reached - _scriptDone = true; - return; - } - - if (strchr(_currentLine, '.') == NULL) - strcat(_currentLine, ".aa"); - - uint16 flags = 0; - if (_bgLoadFlag) - flags |= 0x100; - - _activeAnimation = new MadsAnimation(_vm, this); - _activeAnimation->initialize(_currentLine, flags, &_backgroundSurface, &_codeSurface); - - if (_startFrame != -1) - _activeAnimation->setCurrentFrame(_startFrame); - - _spriteSlots.fullRefresh(); -/* - // Handle scene transition - switch (_transition) { - case kTransitionNone: - // nothing to do - break; - case kTransitionFadeIn: - case kTransitionFadeIn2: - _vm->_palette->fadeIn(TV_NUM_FADE_STEPS, TV_FADE_DELAY_MILLI, destPalette, 256); - break; - case kTransitionBoxInBottomLeft: - case kTransitionBoxInBottomRight: - case kTransitionBoxInTopLeft: - case kTransitionBoxInTopRight: - // unused - warning("Unsupported box in scene effect"); - break; - case kTransitionPanLeftToRight: - // TODO - break; - case kTransitionPanRightToLeft: - // TODO - break; - case kTransitionCircleIn: - // TODO - break; - default: - // nothing to do - break; - } -*/ - - _vm->_resourceManager->toss(_currentLine); -} - - -void AnimviewView::scriptDone() { -return; - AnimviewCallback fn = _callback; - MadsM4Engine *vm = _vm; - - // Remove this view from manager and destroy it - _vm->_viewManager->deleteView(this); - - if (fn) - fn(vm); -} - -/* -Switches are: (taken from the help of the original executable) - -b Toggle background load status off/on. - -c:char Specify sound card id letter. - -f:num Specify a specific starting frame number - -g Stay in graphics mode on exit. - -h[:ex] Disable EMS/XMS high memory support. - -i Switch sound interrupts mode off/on. - -j Wait for music to finish at end. - -k Keystroke jumps to end instead of abort. - -m Operate in non-MADS mode. - -o:xxx Specify opening special effect. - -p Switch MADS path mode to CONCAT. - -r[:abn] Resynch timer (always, beginning, never). - -s:file Specify sound file. - -u[:...] Use DMA speech [optional: addr,type,irq,drq]. - -w Toggle white bars off/on. - -x Exit immediately after last frame. - -y Do not clear screen initially - -z Display statistics after run. - - Opening special effects are: - 0: no effect - 1: fade in - 2: fade in (looks to be the same as 1) - 3: box in from bottom left (unused) - 4: box in from bottom right (unused) - 5: box in from top left (unused) - 6: box in from top right (unused) - 7: pan in from left to right - 8: pan in from right to left - 9: circle in (new scene appears in a circle that expands) - - Animview is ran like this from the original games: - animview.exe @resfilename -c:P,220,20 -u:220,20,07,01 -p -a:mainmenu -p - - Note that the first -p is necessary to watch the animation, otherwise - the program just exits - - To watch an animation within the *.res file, just run animview like this: - animview.exe -x -r:b -o:2 animfilename -p -*/ -void AnimviewView::processCommand() { - char commandStr[80]; - strcpy(commandStr, _currentLine + 1); - str_upper(commandStr); - char *param = commandStr; - - switch (commandStr[0]) { - case 'B': - // Toggle background load flag - _bgLoadFlag = !_bgLoadFlag; - break; - - case 'F': - // Start animation at a specific frame - ++param; - assert(*param == ':'); - _startFrame = atoi(++param); - break; - - case 'O': - param = param + 2; - //warning(kDebugGraphics, "O:%i ", atoi(param)); - _transition = atoi(param); - break; - - case 'R': - param = param + 2; - //warning(kDebugGraphics, "R:%s ", param); - break; - - case 'W': - //warning(kDebugGraphics, "W "); - break; - - case 'X': - //warning(kDebugGraphics, "X "); - break; - - default: - error("Unknown response command: '%s'", commandStr); - } -} - -} |