/* 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 3 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, see . * */ #include "audio/audiostream.h" #include "audio/decoders/raw.h" #include "freescape/freescape.h" #include "freescape/games/eclipse/eclipse.h" #include "freescape/language/8bitDetokeniser.h" namespace Freescape { extern byte kEGADefaultPalette[16][3]; extern byte kCGAPaletteRedGreen[4][3]; extern byte kCGAPalettePinkBlue[4][3]; void EclipseEngine::initDOS() { _viewArea = Common::Rect(40, 33, 280, 133); _soundIndexShoot = 18; _soundIndexCollide = 1; _soundIndexStepDown = 3; _soundIndexStepUp = 3; _soundIndexMenu = -1; _soundIndexStart = 9; _soundIndexAreaChange = 5; } void EclipseEngine::loadAssetsDOSFullGame() { Common::File file; if (_renderMode == Common::kRenderEGA) { file.open("SCN1E.DAT"); if (file.isOpen()) { _title = load8bitBinImage(&file, 0x0); _title->setPalette((byte *)&kEGADefaultPalette, 0, 16); } file.close(); file.open("TOTEE.EXE"); if (!file.isOpen()) error("Failed to open TOTEE.EXE"); loadMessagesFixedSize(&file, 0x710f, 16, 20); loadSoundsFx(&file, 0xd670, 5); loadSpeakerFxDOS(&file, 0x7396 + 0x200, 0x72a1 + 0x200, 20); loadFonts(&file, 0xd403); load8bitBinary(&file, 0x3ce0, 16); _border = load8bitBinImage(&file, 0x210); _border->setPalette((byte *)&kEGADefaultPalette, 0, 16); _indicators.push_back(loadBundledImage("eclipse_ankh_indicator")); for (auto &it : _indicators) it->convertToInPlace(_gfx->_texturePixelFormat); } else if (_renderMode == Common::kRenderCGA) { file.open("SCN1C.DAT"); if (file.isOpen()) { _title = load8bitBinImage(&file, 0x0); _title->setPalette((byte *)&kCGAPaletteRedGreen, 0, 4); } file.close(); file.open("TOTEC.EXE"); if (!file.isOpen()) error("Failed to open TOTEC.EXE"); loadMessagesFixedSize(&file, 0x594f, 16, 20); loadSoundsFx(&file, 0xb9f0, 5); loadFonts(&file, 0xb785); load8bitBinary(&file, 0x2530, 4); _border = load8bitBinImage(&file, 0x210); _border->setPalette((byte *)&kCGAPaletteRedGreen, 0, 4); swapPalette(_startArea); } else error("Invalid or unsupported render mode %s for Total Eclipse", Common::getRenderModeDescription(_renderMode)); } void EclipseEngine::drawDOSUI(Graphics::Surface *surface) { int score = _gameStateVars[k8bitVariableScore]; int shield = _gameStateVars[k8bitVariableShield] * 100 / _maxShield; shield = shield < 0 ? 0 : shield; uint32 yellow = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0x55); uint32 black = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x00, 0x00, 0x00); uint32 white = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0xFF, 0xFF); uint32 red = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0x00, 0x00); uint32 blue = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x55, 0x55, 0xFF); uint32 green = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0x55, 0xFF, 0x55); uint32 redish = _gfx->_texturePixelFormat.ARGBToColor(0xFF, 0xFF, 0x55, 0x55); Common::String message; int deadline; getLatestMessages(message, deadline); if (deadline <= _countdown) { drawStringInSurface(message, 102, 135, black, yellow, surface); _temporaryMessages.push_back(message); _temporaryMessageDeadlines.push_back(deadline); } else if (!_currentAreaMessages.empty()) drawStringInSurface(_currentArea->_name, 102, 135, black, yellow, surface); drawScoreString(score, 136, 6, black, white, surface); int x = 171; if (shield < 10) x = 179; else if (shield < 100) x = 175; Common::String shieldStr = Common::String::format("%d", shield); drawStringInSurface(shieldStr, x, 162, black, redish, surface); drawStringInSurface(shiftStr("0", 'Z' - '$' + 1 - _angleRotationIndex), 79, 135, black, yellow, surface); drawStringInSurface(shiftStr("3", 'Z' - '$' + 1 - _playerStepIndex), 63, 135, black, yellow, surface); drawStringInSurface(shiftStr("7", 'Z' - '$' + 1 - _playerHeightNumber), 240, 135, black, yellow, surface); if (_shootingFrames > 0) { drawStringInSurface(shiftStr("4", 'Z' - '$' + 1), 232, 135, black, yellow, surface); drawStringInSurface(shiftStr("<", 'Z' - '$' + 1), 240, 135, black, yellow, surface); } drawAnalogClock(surface, 90, 172, black, red, white); Common::Rect jarBackground(124, 165, 148, 192); surface->fillRect(jarBackground, black); Common::Rect jarWater(124, 192 - _gameStateVars[k8bitVariableEnergy], 148, 192); surface->fillRect(jarWater, blue); drawIndicator(surface, 41, 4, 16); drawEclipseIndicator(surface, 228, 0, yellow, green); surface->fillRect(Common::Rect(225, 168, 235, 187), white); drawCompass(surface, 229, 177, _yaw, 10, black); } soundFx *EclipseEngine::load1bPCM(Common::SeekableReadStream *file, int offset) { soundFx *sound = (soundFx *)malloc(sizeof(soundFx)); file->seek(offset); sound->size = file->readUint16LE(); debugC(1, kFreescapeDebugParser, "size: %d", sound->size); sound->sampleRate = file->readUint16LE(); debugC(1, kFreescapeDebugParser, "sample rate?: %f", sound->sampleRate); uint8 *data = (uint8 *)malloc(sound->size * sizeof(uint8) * 8); for (int i = 0; i < sound->size; i++) { uint8 byte = file->readByte(); for (int j = 0; j < 8; j++) { data[8 * i + j] = byte & 1 ? 255 : 0; byte = byte >> 1; } } sound->size = sound->size * 8; sound->data = (byte *)data; return sound; } void EclipseEngine::loadSoundsFx(Common::SeekableReadStream *file, int offset, int number) { if (isAmiga() || isAtariST()) { FreescapeEngine::loadSoundsFx(file, offset, number); return; } for (int i = 0; i < number; i++) { _soundsFx[i] = load1bPCM(file, offset); offset += (_soundsFx[i]->size / 8) + 4; } } void EclipseEngine::playSoundFx(int index, bool sync) { if (isAmiga() || isAtariST()) { FreescapeEngine::playSoundFx(index, sync); return; } if (_soundsFx.size() == 0) { debugC(1, kFreescapeDebugMedia, "WARNING: Sounds are not loaded"); return; } int size = _soundsFx[index]->size; //int sampleRate = _soundsFx[index]->sampleRate; byte *data = _soundsFx[index]->data; Audio::SeekableAudioStream *stream = Audio::makeRawStream(data, size, 11025, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO); _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundFxHandle, stream, -1, kFreescapeDefaultVolume / 10); } } // End of namespace Freescape