bool Intro::doIntro(bool floppyIntro) { if (!SkyEngine::isCDVersion()) floppyIntro = true; _skyMusic->loadSection(0); _skySound->loadSection(0); if (!escDelay(3000)) return false; if (floppyIntro) _skyMusic->startMusic(1); uint16 *seqData = _mainIntroSeq; while (*seqData != SEQEND) { if (!nextPart(seqData)) return false; } if (floppyIntro) seqData = _floppyIntroSeq; else seqData = _cdIntroSeq; while (*seqData != SEQEND) { if (!nextPart(seqData)) return false; } return true; }
bool Intro::floppyScrollFlirt(void) { uint8 *scrollScreen = (uint8*)malloc(FRAME_SIZE * 2); memset(scrollScreen, 0, FRAME_SIZE); memcpy(scrollScreen + FRAME_SIZE, _skyScreen->giveCurrent(), FRAME_SIZE); uint8 *scrollPos = scrollScreen + FRAME_SIZE; uint8 *vgaData = _skyDisk->loadFile(60100); uint8 *diffData = _skyDisk->loadFile(60101); uint16 frameNum = READ_LE_UINT16(diffData); uint8 *diffPtr = diffData + 2; uint8 *vgaPtr = vgaData; bool doContinue = true; for (uint16 frameCnt = 1; (frameCnt < frameNum) && doContinue; frameCnt++) { uint8 scrollVal = *diffPtr++; if (scrollVal) scrollPos -= scrollVal * GAME_SCREEN_WIDTH; uint16 scrPos = 0; while (scrPos < FRAME_SIZE) { uint8 nrToDo, nrToSkip; do { nrToSkip = *diffPtr++; scrPos += nrToSkip; } while (nrToSkip == 255); do { nrToDo = *diffPtr++; memcpy(scrollPos + scrPos, vgaPtr, nrToDo); scrPos += nrToDo; vgaPtr += nrToDo; } while (nrToDo == 255); } _system->copyRectToScreen(scrollPos, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT); _system->updateScreen(); if (!escDelay(60)) doContinue = false; } memcpy(_skyScreen->giveCurrent(), scrollPos, FRAME_SIZE); free(diffData); free(vgaData); free(scrollScreen); return doContinue; }
bool Intro::commandFlirt(uint16 *&data) { _skyScreen->startSequence(*data++); while ((*data != COMMANDEND) || _skyScreen->sequenceRunning()) { while ((_skyScreen->seqFramesLeft() < *data)) { data++; uint16 command = *data++; switch (command) { case IC_PREPARE_TEXT: _skyText->displayText(*data++, _textBuf, true, INTRO_TEXT_WIDTH, 255); break; case IC_SHOW_TEXT: ((DataFileHeader *)_textBuf)->s_x = *data++; ((DataFileHeader *)_textBuf)->s_y = *data++; showTextBuf(); break; case IC_REMOVE_TEXT: restoreScreen(); break; case IC_MAKE_SOUND: _skySound->playSound(data[0], data[1], 0); data += 2; break; case IC_FX_VOLUME: _skySound->playSound(1, *data++, 0); break; default: error("Unknown FLIRT command %X", command); } } if (!escDelay(50)) { _skyScreen->stopSequence(); return false; } } data++; // move pointer over "COMMANDEND" return true; }
bool Intro::nextPart(uint16 *&data) { uint8 *vData = NULL; // return false means cancel intro uint16 command = *data++; switch (command) { case SHOWSCREEN: _skyScreen->showScreen(*data++); return true; case FADEUP: _skyScreen->paletteFadeUp(*data++); _relDelay += 32 * 20; // hack: the screen uses a seperate delay function for the // blocking fadeups. So add 32*20 msecs to out delay counter. return true; case FADEDOWN: _skyScreen->fnFadeDown(0); _relDelay += 32 * 20; // hack: see above. return true; case DELAY: if (!escDelay(*data++)) return false; return true; case DOFLIRT: _skyScreen->startSequence(*data++); while (_skyScreen->sequenceRunning()) if (!escDelay(50)) return false; return true; case SCROLLFLIRT: return floppyScrollFlirt(); case COMMANDFLIRT: return commandFlirt(data); case STOPFLIRT: _skyScreen->stopSequence(); return true; case STARTMUSIC: _skyMusic->startMusic(*data++); return true; case WAITMUSIC: while (_skyMusic->musicIsPlaying()) if (!escDelay(50)) return false; return true; case BGFLIRT: _skyScreen->startSequence(*data++); return true; case WAITFLIRT: while (_skyScreen->sequenceRunning()) if (!escDelay(50)) return false; return true; case PLAYVOICE: if (!escDelay(200)) return false; vData = _skyDisk->loadFile(*data++); // HACK: Fill the header with silence. We should // probably use _skySound instead of calling playRaw() // directly, but this will have to do for now. memset(vData, 127, sizeof(struct dataFileHeader)); _mixer->playRaw(&_voice, vData, _skyDisk->_lastLoadedFileSize, 11025, Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED, SOUND_VOICE); return true; case WAITVOICE: while (_mixer->isSoundHandleActive(_voice)) if (!escDelay(50)) return false; return true; case LOADBG: _mixer->stopID(SOUND_BG); if (_bgBuf) free(_bgBuf); _bgBuf = _skyDisk->loadFile(*data++); _bgSize = _skyDisk->_lastLoadedFileSize; return true; case LOOPBG: _mixer->stopID(SOUND_BG); _mixer->playRaw(&_bgSfx, _bgBuf + 256, _bgSize - 768, 11025, Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_LOOP, SOUND_BG); return true; case PLAYBG: _mixer->stopID(SOUND_BG); _mixer->playRaw(&_bgSfx, _bgBuf + 256, _bgSize - 768, 11025, Audio::Mixer::FLAG_UNSIGNED, SOUND_BG); return true; case STOPBG: _mixer->stopID(SOUND_BG); return true; default: error("Unknown intro command %X", command); } return true; }