scummvm/sword2/protocol.cpp

222 lines
7.1 KiB
C++
Raw Normal View History

2003-07-28 01:44:38 +00:00
/* Copyright (C) 1994-2003 Revolution Software Ltd
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*/
2003-07-28 03:12:49 +00:00
#include "stdafx.h"
#include "bs2/sword2.h"
#include "bs2/console.h"
#include "bs2/defs.h"
#include "bs2/header.h"
#include "bs2/memory.h"
#include "bs2/protocol.h"
#include "bs2/resman.h"
2003-07-28 01:44:38 +00:00
2003-10-04 00:52:27 +00:00
namespace Sword2 {
2003-09-19 13:55:19 +00:00
// Returns a pointer to the first palette entry, given the pointer to the
// start of the screen file.
uint8 *FetchPalette(uint8 *screenFile) {
2003-07-28 01:44:38 +00:00
uint8 *palette;
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
2003-09-19 13:55:19 +00:00
palette = (uint8 *) mscreenHeader + 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.
2003-07-28 01:44:38 +00:00
2003-09-19 13:55:19 +00:00
palette[0] = 0;
palette[1] = 0;
palette[2] = 0;
2003-07-28 01:44:38 +00:00
palette[3] = 0;
return palette;
}
2003-09-19 13:55:19 +00:00
// Returns a pointer to the start of the palette match table, given the
// pointer to the start of the screen file.
uint8 *FetchPaletteMatchTable(uint8 *screenFile) {
2003-07-28 01:44:38 +00:00
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
2003-09-12 18:52:53 +00:00
return (uint8 *) mscreenHeader + mscreenHeader->paletteTable;
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
// Returns a pointer to the screen header, given the pointer to the start of
// the screen file.
_screenHeader *FetchScreenHeader(uint8 *screenFile) {
2003-07-28 01:44:38 +00:00
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
2003-09-12 18:52:53 +00:00
_screenHeader *screenHeader = (_screenHeader*) ((uint8 *) mscreenHeader + mscreenHeader->screen);
2003-07-28 01:44:38 +00:00
2003-09-07 03:18:27 +00:00
return screenHeader;
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
// 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.
_layerHeader *FetchLayerHeader(uint8 *screenFile, uint16 layerNo) { // Chris 04Oct96
#ifdef _SWORD2_DEBUG
2003-09-07 03:18:27 +00:00
_screenHeader *screenHead = FetchScreenHeader(screenFile);
2003-09-19 13:55:19 +00:00
if (layerNo > screenHead->noLayers - 1)
error("FetchLayerHeader(%d) invalid layer number!", layerNo);
2003-07-28 01:44:38 +00:00
#endif
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
2003-09-12 18:52:53 +00:00
_layerHeader *layerHeader = (_layerHeader *) ((uint8 *) mscreenHeader + mscreenHeader->layers + (layerNo * sizeof(_layerHeader)));
2003-09-07 03:18:27 +00:00
return layerHeader;
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
// Returns a pointer to the start of the shading mask, given the pointer to
// the start of the screen file.
2003-07-28 01:44:38 +00:00
uint8 *FetchShadingMask(uint8 *screenFile) {
2003-07-28 01:44:38 +00:00
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
2003-09-12 18:52:53 +00:00
return (uint8 *) mscreenHeader + mscreenHeader->maskOffset;
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
// Returns a pointer to the anim header, given the pointer to the start of
// the anim file.
2003-07-28 01:44:38 +00:00
_animHeader *FetchAnimHeader(uint8 *animFile) {
2003-09-19 13:55:19 +00:00
return (_animHeader *) (animFile + sizeof(_standardHeader));
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
// 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.
2003-07-28 01:44:38 +00:00
_cdtEntry *FetchCdtEntry(uint8 *animFile, uint16 frameNo) {
2003-09-19 13:55:19 +00:00
_animHeader *animHead = FetchAnimHeader(animFile);
2003-07-28 01:44:38 +00:00
#ifdef _SWORD2_DEBUG
2003-09-19 13:55:19 +00:00
if (frameNo > animHead->noAnimFrames - 1)
error("FetchCdtEntry(animFile,%d) - anim only %d frames", frameNo, animHead->noAnimFrames);
2003-07-28 01:44:38 +00:00
#endif
2003-09-19 13:55:19 +00:00
return (_cdtEntry *) ((uint8 *) animHead + sizeof(_animHeader) + frameNo * sizeof(_cdtEntry));
2003-07-28 01:44:38 +00:00
}
2003-09-07 03:18:27 +00:00
2003-09-19 13:55:19 +00:00
// 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
2003-07-28 01:44:38 +00:00
_frameHeader *FetchFrameHeader(uint8 *animFile, uint16 frameNo) {
2003-07-28 01:44:38 +00:00
// required address = (address of the start of the anim header) + frameOffset
2003-09-19 13:55:19 +00:00
return (_frameHeader *) (animFile + sizeof(_standardHeader) + FetchCdtEntry(animFile, frameNo)->frameOffset);
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
2003-07-28 01:44:38 +00:00
// Returns a pointer to the requested parallax layer data.
2003-09-19 13:55:19 +00:00
_parallax *FetchBackgroundParallaxLayer(uint8 *screenFile, int layer) {
2003-07-28 01:44:38 +00:00
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
#ifdef _SWORD2_DEBUG
2003-09-12 18:52:53 +00:00
if (mscreenHeader->bg_parallax[layer] == 0)
error("FetchBackgroundParallaxLayer(%d) - No parallax layer exists", layer);
2003-07-28 01:44:38 +00:00
#endif
2003-09-19 13:55:19 +00:00
return (_parallax *) ((uint8 *) mscreenHeader + mscreenHeader->bg_parallax[layer]);
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
_parallax *FetchBackgroundLayer(uint8 *screenFile) {
2003-07-28 01:44:38 +00:00
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
#ifdef _SWORD2_DEBUG
2003-09-12 18:52:53 +00:00
if (mscreenHeader->screen == 0)
error("FetchBackgroundLayer (%d) - No background layer exists");
2003-07-28 01:44:38 +00:00
#endif
2003-09-19 13:55:19 +00:00
return (_parallax *) ((uint8 *) mscreenHeader + mscreenHeader->screen + sizeof(_screenHeader));
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
_parallax *FetchForegroundParallaxLayer(uint8 *screenFile, int layer) {
2003-07-28 01:44:38 +00:00
_multiScreenHeader *mscreenHeader = (_multiScreenHeader *) (screenFile + sizeof(_standardHeader));
#ifdef _SWORD2_DEBUG
2003-09-12 18:52:53 +00:00
if (mscreenHeader->fg_parallax[layer] == 0)
error("FetchForegroundParallaxLayer(%d) - No parallax layer exists", layer);
2003-07-28 01:44:38 +00:00
#endif
2003-09-19 13:55:19 +00:00
return (_parallax *) ((uint8 *) mscreenHeader + mscreenHeader->fg_parallax[layer]);
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
2003-07-28 01:44:38 +00:00
uint8 errorLine[128];
uint8 *FetchTextLine(uint8 *file, uint32 text_line) {
2003-09-19 13:55:19 +00:00
_standardHeader *fileHeader;
uint32 *point;
2003-07-28 01:44:38 +00:00
_textHeader *text_header = (_textHeader *) (file + sizeof(_standardHeader));
if (text_line >= text_header->noOfLines) {
2003-07-28 01:44:38 +00:00
fileHeader = (_standardHeader*)file;
sprintf((char *) errorLine, "xxMissing line %d of %s (only 0..%d)", text_line, fileHeader->name, text_header->noOfLines - 1);
2003-07-28 01:44:38 +00:00
2003-09-19 13:55:19 +00:00
// first 2 chars are NULL so that actor-number comes out as '0'
errorLine[0] = 0;
errorLine[1] = 0;
return errorLine;
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
//point to the lookup table
point = (uint32 *) text_header + 1;
2003-07-28 01:44:38 +00:00
return (uint8 *) (file + READ_LE_UINT32(point + text_line));
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
// Used for testing text & speech (see fnISpeak in speech.cpp)
2003-09-19 13:55:19 +00:00
uint8 CheckTextLine(uint8 *file, uint32 text_line) {
2003-07-28 01:44:38 +00:00
_textHeader *text_header = (_textHeader *) (file + sizeof(_standardHeader));
2003-09-19 13:55:19 +00:00
// out of range => invalid
if (text_line >= text_header->noOfLines)
return 0;
// valid
return 1;
2003-07-28 01:44:38 +00:00
}
2003-09-19 13:55:19 +00:00
uint8 *FetchObjectName(int32 resourceId) {
2003-07-28 01:44:38 +00:00
_standardHeader *header;
header = (_standardHeader *) res_man.open(resourceId);
res_man.close(resourceId);
2003-07-28 01:44:38 +00:00
2003-09-19 13:55:19 +00:00
// note this pointer is no longer valid, but it should be ok until
// another resource is opened!
// FIXME: I don't like the sound of this at all. Though thanks to the
// BS2 memory manager, at least it will still point to malloced
// memory.
return header->name;
2003-07-28 01:44:38 +00:00
}
2003-10-04 00:52:27 +00:00
} // End of namespace Sword2