void AGOSEngine::openTextWindow() { if (_textWindow) { if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { if (_textWindow->flags & 0x80) clearWindow(_textWindow); } return; } if (getGameType() == GType_FF || getGameType() == GType_PP) _textWindow = openWindow(64, 96, 384, 172, 1, 0, 15); else _textWindow = openWindow(8, 144, 24, 6, 1, 0, 15); }
void AGOSEngine_Feeble::timerProc() { if (_videoLockOut & 0x80E9 || _videoLockOut & 2) return; _syncCount++; _videoLockOut |= 2; if (!(_videoLockOut & 0x10)) { _syncFlag2 = !_syncFlag2; if (!_syncFlag2) { processVgaEvents(); } else { // Double speed on Oracle if (getGameType() == GType_FF && getBitFlag(99)) { processVgaEvents(); } else if (_scrollCount == 0) { _videoLockOut &= ~2; return; } } if (getGameType() == GType_FF && _interactiveVideo) { // Controls Omni TV videos if (getBitFlag(42)) { stopInteractiveVideo(); } else { _moviePlayer->nextFrame(); } } animateSprites(); } if (_displayFlag) { if (getGameType() == GType_FF && !(getFeatures() & GF_DEMO)) { if (!getBitFlag(78)) { oracleLogo(); } if (getBitFlag(76)) { swapCharacterLogo(); } } handleMouseMoved(); displayScreen(); _displayFlag = 0; } _videoLockOut &= ~2; }
void AGOSEngine::playModule(uint16 music) { char filename[15]; Common::File f; uint32 offs = 0; if (getPlatform() == Common::kPlatformAmiga && getGameType() == GType_WW) { // Multiple tunes are stored in music files for main locations for (uint i = 0; i < 20; i++) { if (amigaWaxworksOffs[i].tune == music) { music = amigaWaxworksOffs[i].fileNum; offs = amigaWaxworksOffs[i].offs; } } } if (getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO) sprintf(filename, "elvira2"); else if (getPlatform() == Common::kPlatformAcorn) sprintf(filename, "%dtune.DAT", music); else sprintf(filename, "%dtune", music); f.open(filename); if (f.isOpen() == false) { error("playModule: Can't load module from '%s'", filename); } Audio::AudioStream *audioStream; if (!(getGameType() == GType_ELVIRA1 && getFeatures() & GF_DEMO) && getFeatures() & GF_CRUNCHED) { uint32 srcSize = f.size(); byte *srcBuf = (byte *)malloc(srcSize); if (f.read(srcBuf, srcSize) != srcSize) error("playModule: Read failed"); uint32 dstSize = READ_BE_UINT32(srcBuf + srcSize - 4); byte *dstBuf = (byte *)malloc(dstSize); decrunchFile(srcBuf, dstBuf, srcSize); free(srcBuf); Common::MemoryReadStream stream(dstBuf, dstSize); audioStream = Audio::makeProtrackerStream(&stream, offs); free(dstBuf); } else { audioStream = Audio::makeProtrackerStream(&f); } _mixer->playStream(Audio::Mixer::kMusicSoundType, &_modHandle, audioStream); }
void AGOSEngine::dumpAllVgaScriptFiles() { uint8 start = (getGameType() == GType_PN) ? 0 : 2; uint16 end = (getGameType() == GType_PN) ? 26 : 450; for (int z = start; z < end; z++) { uint16 zoneNum = (getGameType() == GType_PN) ? 0 : z; loadZone(z, false); VgaPointersEntry *vpe = &_vgaBufferPointers[zoneNum]; if (vpe->vgaFile1 != NULL) { _curVgaFile1 = vpe->vgaFile1; dumpVgaFile(_curVgaFile1); } } }
uint AGOSEngine::readVariable(uint16 variable) { if (variable >= _numVars) error("readVariable: Variable %d out of range", variable); if (getGameType() == GType_PP) { return (uint16)_variableArray[variable]; } else if (getGameType() == GType_FF) { if (getBitFlag(83)) return (uint16)_variableArray2[variable]; else return (uint16)_variableArray[variable]; } else { return _variableArray[variable]; } }
HitArea *AGOSEngine::findBox(uint hitarea_id) { HitArea *ha = _hitAreas; uint count = ARRAYSIZE(_hitAreas); do { if (getGameType() == GType_FF || getGameType() == GType_PP) { if (ha->id == hitarea_id && ha->flags != 0) return ha; } else { if (ha->id == hitarea_id) return ha; } } while (ha++, --count); return NULL; }
void AGOSEngine_Simon1::vc22_setPalette() { byte *offs, *palptr = 0, *src; uint16 a = 0, b, num, palSize = 0; a = vcReadNextWord(); b = vcReadNextWord(); if (getGameType() == GType_FF || getGameType() == GType_PP) { num = 256; palSize = 768; palptr = _displayPalette; } else { num = a == 0 ? 32 : 16; palSize = 96; palptr = &_displayPalette[(a * 64)]; } offs = _curVgaFile1 + 6; src = offs + b * palSize; do { palptr[0] = src[0] * 4; palptr[1] = src[1] * 4; palptr[2] = src[2] * 4; palptr[3] = 0; palptr += 4; src += 3; } while (--num); if (getFeatures() & GF_32COLOR) { // Custom palette used for verb area palptr = &_displayPalette[(13 * 64)]; for (uint8 c = 0; c < 32; c++) { palptr[0] = customPalette[c * 3 + 0]; palptr[1] = customPalette[c * 3 + 1]; palptr[2] = customPalette[c * 3 + 2]; palptr[3] = 0; palptr += 4; }; } _paletteFlag = 2; _vgaSpriteChanged++; }
void AGOSEngine::readItemFromGamePc(Common::SeekableReadStream *in, Item *item) { uint32 type; if (getGameType() == GType_ELVIRA1) { item->itemName = (uint16)in->readUint32BE(); item->adjective = in->readUint16BE(); item->noun = in->readUint16BE(); item->state = in->readUint16BE(); in->readUint16BE(); item->next = (uint16)fileReadItemID(in); item->child = (uint16)fileReadItemID(in); item->parent = (uint16)fileReadItemID(in); in->readUint16BE(); in->readUint16BE(); in->readUint16BE(); item->classFlags = in->readUint16BE(); item->children = NULL; } else if (getGameType() == GType_ELVIRA2) { item->itemName = (uint16)in->readUint32BE(); item->adjective = in->readUint16BE(); item->noun = in->readUint16BE(); item->state = in->readUint16BE(); item->next = (uint16)fileReadItemID(in); item->child = (uint16)fileReadItemID(in); item->parent = (uint16)fileReadItemID(in); in->readUint16BE(); item->classFlags = in->readUint16BE(); item->children = NULL; } else { item->adjective = in->readUint16BE(); item->noun = in->readUint16BE(); item->state = in->readUint16BE(); item->next = (uint16)fileReadItemID(in); item->child = (uint16)fileReadItemID(in); item->parent = (uint16)fileReadItemID(in); in->readUint16BE(); item->classFlags = in->readUint16BE(); item->children = NULL; } type = in->readUint32BE(); while (type) { type = in->readUint16BE(); if (type != 0) readItemChildren(in, item, type); } }
void AGOSEngine::vc60_stopAnimation() { uint16 sprite, zoneNum; if (getGameType() == GType_PP) { zoneNum = vcReadNextWord(); sprite = vcReadVarOrWord(); } else if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) { zoneNum = vcReadNextWord(); sprite = vcReadNextWord(); } else { sprite = vcReadNextWord(); zoneNum = sprite / 100; } vcStopAnimation(zoneNum, sprite); }
void AGOSEngine_Simon2::setupGame() { gss = &simon2_settings; _tableIndexBase = 1580 / 4; _textIndexBase = 1500 / 4; _numVideoOpcodes = 75; #if defined(__DS__) _vgaMemSize = 1300000; #else _vgaMemSize = 2000000; #endif _itemMemSize = 20000; _tableMemSize = 100000; // Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2 if (getGameType() == GType_SIMON2 && _midi.hasNativeMT32()) _musicIndexBase = (1128 + 612) / 4; else _musicIndexBase = 1128 / 4; _soundIndexBase = 1660 / 4; _frameCount = 1; _vgaBaseDelay = 1; _vgaPeriod = 45; _numBitArray1 = 16; _numBitArray2 = 16; _numItemStore = 10; _numTextBoxes = 20; _numVars = 255; _numMusic = 93; _numSFX = 222; _numSpeech = 11997; AGOSEngine::setupGame(); }
Common::Error MadsM4Engine::run() { // Initialize backend _screen = new M4Surface(true); // Special form for creating screen reference _midi = new MidiPlayer(this); _midi->setGM(true); // FIXME: Really? Always? _saveLoad = new SaveLoad(this); _palette = new Palette(this); _mouse = new Mouse(this); _events = new Events(this); _kernel = new Kernel(this); _player = new Player(this); _font = new FontManager(this); if (getGameType() == GType_Burger) { _actor = new Actor(this); _conversationView = new ConversationView(this); } else { _actor = NULL; } _rails = new Rails(); // needs to be initialized before _scene _dialogs = new Dialogs(); _viewManager = new ViewManager(this); _inventory = new Inventory(this); _sound = new Sound(this, _mixer, 255); _script = new ScriptInterpreter(this); _ws = new WoodScript(this); //_callbacks = new Callbacks(this); _random = new Common::RandomSource(); g_eventRec.registerRandomSource(*_random, "m4"); return Common::kNoError; }
void AGOSEngine_Simon2::playSpeech(uint16 speech_id, uint16 vgaSpriteId) { if (speech_id == 0xFFFF) { if (_subtitles) return; if (!getBitFlag(14) && !getBitFlag(28)) { setBitFlag(14, true); _variableArray[100] = 5; animate(4, 1, 30, 0, 0, 0); waitForSync(130); } _skipVgaWait = true; } else { if (getGameType() == GType_SIMON2 && _subtitles && _language != Common::HE_ISR) { loadVoice(speech_id); return; } if (_subtitles && _scriptVar2) { animate(4, 2, 5, 0, 0, 0); waitForSync(205); stopAnimateSimon2(2,5); } stopAnimateSimon2(2, vgaSpriteId + 2); loadVoice(speech_id); animate(4, 2, vgaSpriteId + 2, 0, 0, 0); } }
void AGOSEngine::loadVoice(uint speechId) { if (getGameType() == GType_PP && speechId == 99) { _sound->stopVoice(); return; } if (getFeatures() & GF_ZLIBCOMP) { char filename[15]; uint32 file, offset, srcSize, dstSize; if (getPlatform() == Common::kPlatformAmiga) { loadOffsets((const char*)"spindex.dat", speechId, file, offset, srcSize, dstSize); } else { loadOffsets((const char*)"speech.wav", speechId, file, offset, srcSize, dstSize); } // Voice segment doesn't exist if (offset == 0xFFFFFFFF && srcSize == 0xFFFFFFFF && dstSize == 0xFFFFFFFF) { debug(0, "loadVoice: speechId %d removed", speechId); return; } if (getPlatform() == Common::kPlatformAmiga) sprintf(filename, "sp%d.wav", file); else sprintf(filename, "speech.wav"); byte *dst = (byte *)malloc(dstSize); decompressData(filename, dst, offset, srcSize, dstSize); _sound->playVoiceData(dst, speechId); } else { _sound->playVoice(speechId); } }
void AGOSEngine::o_clearTimers() { // 140: clear timers killAllTimers(); if (getGameType() == GType_SIMON1) addTimeEvent(3, 160); }
void AGOSEngine::o_haltAnimation() { // 88: stop animation _videoLockOut |= 0x10; if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { VgaTimerEntry *vte = _vgaTimerList; while (vte->delay) { if (vte->type == ANIMATE_EVENT) vte->delay += 10; vte++; } _scrollCount = 0; _scrollFlag = 0; } }
void AGOSEngine::showActionString(const byte *string) { WindowBlock *window; uint x; const uint len = (getGameType() == GType_WW) ? 29 : 53; window = _windowArray[1]; if (window == NULL || window->textColor == 0) return; // Arisme : hack for long strings in the French version if ((strlen((const char*)string) - 1) <= len) x = (len - (strlen((const char *)string) - 1)) * 3; else x = 0; window->textColumn = x / 8; window->textColumnOffset = x & 7; if (_language == Common::HE_ISR && window->textColumnOffset != 0) { window->textColumnOffset = 8 - window->textColumnOffset; window->textColumn++; } for (; *string; string++) windowPutChar(window, *string); }
void AGOSEngine_Simon2::os2_mouseOn() { // 180: force mouseOn if (getGameType() == GType_SIMON2 && getBitFlag(79)) { _mouseCursor = 0; } _mouseHideCount = 0; }
void AGOSEngine::scrollEvent() { if (_scrollCount == 0) return; if (getGameType() == GType_FF) { if (_scrollCount < 0) { if (_scrollFlag != -8) { _scrollFlag = -8; _scrollCount += 8; } } else { if (_scrollFlag != 8) { _scrollFlag = 8; _scrollCount -= 8; } } } else { if (_scrollCount < 0) { if (_scrollFlag != -1) { _scrollFlag = -1; if (++_scrollCount == 0) return; } } else { if (_scrollFlag != 1) { _scrollFlag = 1; if (--_scrollCount == 0) return; } } addVgaEvent(6, SCROLL_EVENT, NULL, 0, 0); } }
void AGOSEngine_Feeble::runSubroutine101() { if ((getPlatform() == Common::kPlatformAmiga || getPlatform() == Common::kPlatformMacintosh) && getGameType() == GType_FF) { playVideo("epic.dxa"); } AGOSEngine::runSubroutine101(); }
byte *AGOSEngine::convertImage(VC10_state *state, bool compressed) { int length, i, j; uint8 colorDepth = 4; if (getGameType() == GType_SIMON1) { if (((_videoLockOut & 0x20) && !state->palette) || ((getFeatures() & GF_32COLOR) && state->palette != 0xC0)) { colorDepth = 5; } } const byte *src = state->srcPtr; int width = state->width * 16; int height = state->height; free(_planarBuf); _planarBuf = (byte *)malloc(width * height); byte *dst = _planarBuf; if (compressed) { convertCompressedImage(src, dst, colorDepth, height, width, (getGameType() == GType_PN)); } else { length = (width + 15) / 16 * height; for (i = 0; i < length; i++) { uint16 w[kMaxColorDepth]; if (getGameType() == GType_SIMON1 && colorDepth == 4) { for (j = 0; j < colorDepth; ++j) { w[j] = READ_BE_UINT16(src + j * length * 2); } if (state->palette == 0xC0) { bitplaneToChunkyText(w, colorDepth, dst); } else { bitplaneToChunky(w, colorDepth, dst); } src += 2; } else { for (j = 0; j < colorDepth; ++j) { w[j] = READ_BE_UINT16(src); src += 2; } bitplaneToChunky(w, colorDepth, dst); } } } return _planarBuf; }
CineEngine::~CineEngine() { if (getGameType() == Cine::GType_OS) { freeErrmessDat(); } DebugMan.clearAllDebugChannels(); delete _console; }
bool AGOSEngine::drawImage_clip(VC10_state *state) { const uint16 *vlut; uint maxWidth, maxHeight; int cur; vlut = &_videoWindows[_windowNum * 4]; if (getGameType() != GType_FF && getGameType() != GType_PP) { state->draw_width = state->width * 2; } cur = state->x; if (cur < 0) { do { if (!--state->draw_width) return 0; state->x_skip++; } while (++cur); } state->x = cur; maxWidth = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenWidth : (vlut[2] * 2); cur += state->draw_width - maxWidth; if (cur > 0) { do { if (!--state->draw_width) return 0; } while (--cur); } cur = state->y; if (cur < 0) { do { if (!--state->draw_height) return 0; state->y_skip++; } while (++cur); } state->y = cur; maxHeight = (getGameType() == GType_FF || getGameType() == GType_PP) ? _screenHeight : vlut[3]; cur += state->draw_height - maxHeight; if (cur > 0) { do { if (!--state->draw_height) return 0; } while (--cur); } if (getGameType() != GType_FF && getGameType() != GType_PP) { state->draw_width *= 4; } return (state->draw_width != 0 && state->draw_height != 0); }
void AGOSEngine::writeVariable(uint16 variable, uint16 contents) { if (variable >= _numVars) error("writeVariable: Variable %d out of range", variable); if (getGameType() == GType_FF && getBitFlag(83)) _variableArray2[variable] = contents; else _variableArray[variable] = contents; }
Sprite *ComposerEngine::addSprite(uint16 id, uint16 animId, uint16 zorder, const Common::Point &pos) { Sprite sprite; bool foundSprite = false; // re-use old sprite, if any (the BMAP for this id might well have // changed in the meantime, but the scripts depend on that!) for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) { if (i->_id != id) continue; if (getGameType() == GType_ComposerV1) { if (i->_animId != animId) continue; } else if (i->_animId && animId && (i->_animId != animId)) continue; dirtySprite(*i); // if the zordering is identical, modify it in-place if (i->_zorder == zorder) { i->_animId = animId; i->_pos = pos; dirtySprite(*i); return &(*i); } // otherwise, take a copy and remove it from the list sprite = *i; foundSprite = true; _sprites.erase(i); break; } sprite._animId = animId; sprite._zorder = zorder; sprite._pos = pos; if (!foundSprite) { sprite._id = id; if (!initSprite(sprite)) { debug(1, "ignoring addSprite on invalid sprite %d", id); return NULL; } } dirtySprite(sprite); for (Common::List<Sprite>::iterator i = _sprites.begin(); i != _sprites.end(); i++) { if (sprite._zorder <= i->_zorder) continue; // insert *before* this sprite _sprites.insert(i, sprite); --i; return &(*i); } _sprites.push_back(sprite); return &_sprites.back(); }
const byte *AGOSEngine::getStringPtrByID(uint16 stringId, bool upperCase) { const byte *stringPtr; byte *dst; _freeStringSlot ^= 1; dst = _stringReturnBuffer[_freeStringSlot]; if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAtariST) { byte *ptr = _stringTabPtr[stringId]; _textCount = 0; _awaitTwoByteToken = 0; uncompressText(ptr); _textBuffer[_textCount] = 0; Common::strlcpy((char *)dst, (const char *)_textBuffer, 180); } else { if (stringId < 0x8000) { stringPtr = _stringTabPtr[stringId]; } else { stringPtr = getLocalStringByID(stringId); } Common::strlcpy((char *)dst, (const char *)stringPtr, 180); } // WORKAROUND bug #1538873: The French version of Simon 1 and the // Polish version of Simon 2 used excess spaces, at the end of many // messages, so we strip off those excess spaces. if ((getGameType() == GType_SIMON1 && _language == Common::FR_FRA) || (getGameType() == GType_SIMON2 && _language == Common::PL_POL)) { uint16 len = strlen((const char *)dst) - 1; while (len && dst[len] == 32) { dst[len] = 0; len--; } } if (upperCase && *dst) { if (Common::isLower(*dst)) *dst = toupper(*dst); } return dst; }
void AGOSEngine::displayName(HitArea *ha) { if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_PP) return; bool result; int x = 0, y = 0; if (getGameType() == GType_FF) { if (ha->flags & kBFHyperBox) { _lastNameOn = ha; return; } if (findBox(50)) return; if (getBitFlag(99)) _animatePointer = ((ha->flags & kBFTextBox) == 0); else _animatePointer = true; if (!getBitFlag(73)) return; y = ha->y; if (getBitFlag(99) && y > 288) y = 288; y -= 17; if (y < 0) y = 0; y += 2; x = ha->width / 2 + ha->x; } else { resetNameWindow(); } if (ha->flags & kBFTextBox) { result = printTextOf(ha->flags / 256, x, y); } else { result = printNameOf(ha->itemPtr, x, y); } if (result) _lastNameOn = ha; }
uint AGOSEngine::getVarOrByte() { if (getGameType() == GType_ELVIRA1) { return getVarOrWord(); } else { uint a = *_codePtr++; if (a != 255) return a; return readVariable(*_codePtr++); } }
void AGOSEngine::hitarea_leave(HitArea *ha, bool state) { if (getGameType() == GType_SIMON2) { invertBox(ha, 231, 229, 230, 1); } else { if (getFeatures() & GF_32COLOR) invertBox(ha, 220, 212, 216, 4); else invertBox(ha, 223, 213, 218, 5); } }
void Ship::die() { Ship* temp; //changing owner's ship from this to new ship (pod) temp = getGameType()->RespawnShip(this->loc, this->dir, this->vel, pod, this->owner->number); if(abilityTimer) EndSpecialAbility(this); Kill(); }
void AGOSEngine::o_add() { // 43: add uint var = getVarWrapper(); writeVariable(var, readVariable(var) + getVarOrWord()); // WORKAROUND: The conversation of the male in Vid-Phone Booth at Dave's Space Bar // is based on variable 116, but stops due to a missing option (37). if (getGameType() == GType_FF && _currentTable->id == 10538 && readVariable(116) == 37) writeVariable(116, 38); }