diff options
Diffstat (limited to 'engines/sword2/protocol.cpp')
-rw-r--r-- | engines/sword2/protocol.cpp | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/engines/sword2/protocol.cpp b/engines/sword2/protocol.cpp new file mode 100644 index 0000000000..23010e27a9 --- /dev/null +++ b/engines/sword2/protocol.cpp @@ -0,0 +1,216 @@ +/* Copyright (C) 1994-1998 Revolution Software Ltd. + * Copyright (C) 2003-2006 The ScummVM project + * + * 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. + * + * $URL$ + * $Id$ + */ + +#include "common/stdafx.h" +#include "sword2/sword2.h" +#include "sword2/resman.h" + +namespace Sword2 { + +/** + * Returns a pointer to the first palette entry, given the pointer to the start + * of the screen file. + */ + +byte *Sword2Engine::fetchPalette(byte *screenFile) { + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + + byte *palette = screenFile + ResHeader::size() + mscreenHeader.palette; + + // Always set colour 0 to black, because while most background screen + // palettes have a bright colour 0 it should come out as black in the + // game. + + palette[0] = 0; + palette[1] = 0; + palette[2] = 0; + palette[3] = 0; + + return palette; +} + +/** + * Returns a pointer to the start of the palette match table, given the pointer + * to the start of the screen file. + */ + +byte *Sword2Engine::fetchPaletteMatchTable(byte *screenFile) { + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + + return screenFile + ResHeader::size() + mscreenHeader.paletteTable; +} + +/** + * Returns a pointer to the screen header, given the pointer to the start of + * the screen file. + */ + +byte *Sword2Engine::fetchScreenHeader(byte *screenFile) { + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + + return screenFile + ResHeader::size() + mscreenHeader.screen; +} + +/** + * Returns a pointer to the requested layer header, given the pointer to the + * start of the screen file. Drops out if the requested layer number exceeds + * the number of layers on this screen. + */ + +byte *Sword2Engine::fetchLayerHeader(byte *screenFile, uint16 layerNo) { +#ifdef SWORD2_DEBUG + ScreenHeader screenHead; + + screenHead.read(fetchScreenHeader(screenFile)); + assert(layerNo < screenHead.noLayers); +#endif + + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + + return screenFile + ResHeader::size() + mscreenHeader.layers + layerNo * LayerHeader::size(); +} + +/** + * Returns a pointer to the start of the shading mask, given the pointer to the + * start of the screen file. + */ + +byte *Sword2Engine::fetchShadingMask(byte *screenFile) { + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + + return screenFile + ResHeader::size() + mscreenHeader.maskOffset; +} + +/** + * Returns a pointer to the anim header, given the pointer to the start of the + * anim file. + */ + +byte *Sword2Engine::fetchAnimHeader(byte *animFile) { + return animFile + ResHeader::size(); +} + +/** + * Returns a pointer to the requested frame number's cdtEntry, given the + * pointer to the start of the anim file. Drops out if the requested frame + * number exceeds the number of frames in this anim. + */ + +byte *Sword2Engine::fetchCdtEntry(byte *animFile, uint16 frameNo) { +#ifdef SWORD2_DEBUG + AnimHeader animHead; + + animHead.read(fetchAnimHeader(animFile)); + + if (frameNo > animHead->noAnimFrames - 1) + error("fetchCdtEntry(animFile,%d) - anim only %d frames", frameNo, animHead.noAnimFrames); +#endif + + return fetchAnimHeader(animFile) + AnimHeader::size() + frameNo * CdtEntry::size(); +} + +/** + * Returns a pointer to the requested frame number's header, given the pointer + * to the start of the anim file. Drops out if the requested frame number + * exceeds the number of frames in this anim + */ + +byte *Sword2Engine::fetchFrameHeader(byte *animFile, uint16 frameNo) { + // required address = (address of the start of the anim header) + frameOffset + CdtEntry cdt; + + cdt.read(fetchCdtEntry(animFile, frameNo)); + + return animFile + ResHeader::size() + cdt.frameOffset; +} + +/** + * Returns a pointer to the requested parallax layer data. + */ + +byte *Sword2Engine::fetchBackgroundParallaxLayer(byte *screenFile, int layer) { + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + assert(mscreenHeader.bg_parallax[layer]); + + return screenFile + ResHeader::size() + mscreenHeader.bg_parallax[layer]; +} + +byte *Sword2Engine::fetchBackgroundLayer(byte *screenFile) { + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + assert(mscreenHeader.screen); + + return screenFile + ResHeader::size() + mscreenHeader.screen + ScreenHeader::size(); +} + +byte *Sword2Engine::fetchForegroundParallaxLayer(byte *screenFile, int layer) { + MultiScreenHeader mscreenHeader; + + mscreenHeader.read(screenFile + ResHeader::size()); + assert(mscreenHeader.fg_parallax[layer]); + + return screenFile + ResHeader::size() + mscreenHeader.fg_parallax[layer]; +} + +byte *Sword2Engine::fetchTextLine(byte *file, uint32 text_line) { + TextHeader text_header; + static byte errorLine[128]; + + text_header.read(file + ResHeader::size()); + + if (text_line >= text_header.noOfLines) { + sprintf((char *)errorLine, "xxMissing line %d of %s (only 0..%d)", text_line, _resman->fetchName(file), text_header.noOfLines - 1); + + // first 2 chars are NULL so that actor-number comes out as '0' + errorLine[0] = 0; + errorLine[1] = 0; + return errorLine; + } + + // The "number of lines" field is followed by a lookup table + + return file + READ_LE_UINT32(file + ResHeader::size() + 4 + 4 * text_line); +} + +// Used for testing text & speech (see fnISpeak in speech.cpp) + +bool Sword2Engine::checkTextLine(byte *file, uint32 text_line) { + TextHeader text_header; + + text_header.read(file + ResHeader::size()); + + return text_line < text_header.noOfLines; +} + +} // End of namespace Sword2 |