/* 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/file.h" #include "agos/intern.h" #include "agos/agos.h" #include "agos/vga.h" namespace AGOS { void AGOSEngine::freezeBottom() { _vgaMemBase = _vgaMemPtr; _vgaFrozenBase = _vgaMemPtr; } void AGOSEngine::unfreezeBottom() { _vgaMemPtr = _vgaRealBase; _vgaMemBase = _vgaRealBase; _vgaFrozenBase = _vgaRealBase; } static const uint8 zoneTable[160] = { 0, 0, 2, 2, 2, 2, 0, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 1, 3, 0, 0, 0, 1, 0, 2, 0, 3, 0, 3, 3, 0, 1, 1, 0, 1, 2, 2, 2, 0, 2, 2, 2, 0, 2, 1, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 3, 2, 2, 2, 3, 2, 3, 3, 3, 1, 3, 3, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, }; void AGOSEngine::loadZone(uint16 zoneNum, bool useError) { VgaPointersEntry *vpe; CHECK_BOUNDS(zoneNum, _vgaBufferPointers); if (getGameType() == GType_PN) { // Only a single zone is used in Personal Nightmare vpe = _vgaBufferPointers; vc27_resetSprite(); _vgaMemPtr = _vgaMemBase; } else { vpe = _vgaBufferPointers + zoneNum; if (vpe->vgaFile1 != NULL) return; } // Loading order is important due to resource management if (getPlatform() == Common::kPlatformAmiga && getGameType() == GType_WW && zoneTable[zoneNum] == 3) { uint8 num = (zoneNum >= 85) ? 94 : 18; loadVGAVideoFile(num, 2, useError); } else { loadVGAVideoFile(zoneNum, 2, useError); } vpe->vgaFile2 = _block; vpe->vgaFile2End = _blockEnd; loadVGAVideoFile(zoneNum, 1, useError); vpe->vgaFile1 = _block; vpe->vgaFile1End = _blockEnd; vpe->sfxFile = NULL; if (getGameType() == GType_ELVIRA2) { // A singe sound file is used for Amiga and AtariST versions if (loadVGASoundFile(1, 3)) { vpe->sfxFile = _block; vpe->sfxFileEnd = _blockEnd; } } else if (!(getFeatures() & GF_ZLIBCOMP)) { if (loadVGASoundFile(zoneNum, 3)) { vpe->sfxFile = _block; vpe->sfxFileEnd = _blockEnd; } } } void AGOSEngine::setZoneBuffers() { _zoneBuffers = (byte *)malloc(_vgaMemSize); _vgaMemPtr = _zoneBuffers; _vgaMemBase = _zoneBuffers; _vgaFrozenBase = _zoneBuffers; _vgaRealBase = _zoneBuffers; _vgaMemEnd = _zoneBuffers + _vgaMemSize; } byte *AGOSEngine::allocBlock(uint32 size) { for (;;) { _block = _vgaMemPtr; _blockEnd = _block + size; if (_blockEnd >= _vgaMemEnd) { _vgaMemPtr = _vgaMemBase; } else { _rejectBlock = false; checkNoOverWrite(); if (_rejectBlock) continue; checkRunningAnims(); if (_rejectBlock) continue; checkZonePtrs(); _vgaMemPtr = _blockEnd; return _block; } } } void AGOSEngine::checkRunningAnims() { if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) && (_videoLockOut & 0x20)) { return; } VgaSprite *vsp; for (vsp = _vgaSprites; vsp->id; vsp++) { checkAnims(vsp->zoneNum); if (_rejectBlock == true) return; } } void AGOSEngine::checkNoOverWrite() { VgaPointersEntry *vpe; if (_noOverWrite == 0xFFFF) return; vpe = &_vgaBufferPointers[_noOverWrite]; if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) { _rejectBlock = true; _vgaMemPtr = vpe->vgaFile1End; } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) { _rejectBlock = true; _vgaMemPtr = vpe->vgaFile2End; } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { _rejectBlock = true; _vgaMemPtr = vpe->sfxFileEnd; } else { _rejectBlock = false; } } void AGOSEngine::checkAnims(uint a) { VgaPointersEntry *vpe; vpe = &_vgaBufferPointers[a]; if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) { _rejectBlock = true; _vgaMemPtr = vpe->vgaFile1End; } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) { _rejectBlock = true; _vgaMemPtr = vpe->vgaFile2End; } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { _rejectBlock = true; _vgaMemPtr = vpe->sfxFileEnd; } else { _rejectBlock = false; } } void AGOSEngine::checkZonePtrs() { uint count = ARRAYSIZE(_vgaBufferPointers); VgaPointersEntry *vpe = _vgaBufferPointers; do { if (((vpe->vgaFile1 < _blockEnd) && (vpe->vgaFile1End > _block)) || ((vpe->vgaFile2 < _blockEnd) && (vpe->vgaFile2End > _block)) || ((vpe->sfxFile < _blockEnd) && (vpe->sfxFileEnd > _block))) { vpe->vgaFile1 = NULL; vpe->vgaFile1End = NULL; vpe->vgaFile2 = NULL; vpe->vgaFile2End = NULL; vpe->sfxFile = NULL; vpe->sfxFileEnd = NULL; } } while (++vpe, --count); } } // End of namespace AGOS