From 0c93377f5d4e8dd8e8f40fc6505630f439d232f5 Mon Sep 17 00:00:00 2001 From: Joost Peters Date: Mon, 29 Sep 2003 22:27:08 +0000 Subject: [PATCH] added BANK code from Gregory + minor change to loadFile() svn-id: r10491 --- queen/graphics.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++ queen/graphics.h | 66 ++++++++++++++++++++++++++++ queen/logic.cpp | 2 +- queen/module.mk | 1 + queen/resource.cpp | 12 ++++-- queen/resource.h | 4 +- 6 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 queen/graphics.cpp create mode 100644 queen/graphics.h diff --git a/queen/graphics.cpp b/queen/graphics.cpp new file mode 100644 index 00000000000..ec581b42241 --- /dev/null +++ b/queen/graphics.cpp @@ -0,0 +1,104 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "queen/graphics.h" + +QueenGraphics::QueenGraphics(QueenResource *resource) + :_resource(resource) { + + memset(_frames, 0, sizeof(_frames)); + memset(_banks, 0, sizeof(_banks)); +} + + +void QueenGraphics::bankLoad(const char *bankname, uint32 bankslot) { + + int16 i; + + if (!_resource->exists(bankname)) { + error("Unable to open bank '%s'", bankname); + } + bankErase(bankslot); + _banks[bankslot].data = _resource->loadFile(bankname); + int16 entries = (int16)READ_LE_UINT16(_banks[bankslot].data); + if (entries < 0 || entries >= MAX_BANK_SIZE) { + error("Maximum bank size exceeded or negative bank size : %d", entries); + } + + uint32 offset = 2; + uint8 *p = _banks[bankslot].data; + for (i = 1; i <= entries; ++i) { + _banks[bankslot].indexes[i] = offset; + uint16 w = READ_LE_UINT16(p + offset + 0); + uint16 h = READ_LE_UINT16(p + offset + 2); + // jump to next entry, skipping data & header + offset += w * h + 8; + } + + debug(5, "Loaded bank '%s' in slot %d, %d entries", bankname, bankslot, entries); +} + +void QueenGraphics::bankUnpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) { + + uint8* p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe]; + + ObjectFrame* pof = &_frames[dstframe]; + delete[] pof->data; + + pof->width = READ_LE_UINT16(p + 0); + pof->height = READ_LE_UINT16(p + 2); + pof->xhotspot = READ_LE_UINT16(p + 4); + pof->yhotspot = READ_LE_UINT16(p + 6); + + uint size = pof->width * pof->height; + pof->data = new uint8[ size ]; + memcpy(pof->data, p, size); + + debug(5, "Unpacked frame %d from bank slot %d to frame slot %d", srcframe, bankslot, dstframe); +} + + +void QueenGraphics::bankOverpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) { + + uint8 *p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe]; + uint16 src_w = READ_LE_UINT16(p + 0); + uint16 src_h = READ_LE_UINT16(p + 2); + + // unpack if destination frame is smaller than source one + if (_frames[dstframe].width < src_w || _frames[dstframe].height < src_h) { + bankUnpack(srcframe, dstframe, bankslot); + } + else { + // copy data 'over' destination frame (without changing frame header) + memcpy(_frames[dstframe].data, p, src_w * src_h); + } + + debug(5, "Overpacked frame %d from bank slot %d to frame slot %d", srcframe, bankslot, dstframe); +} + +void QueenGraphics::bankErase(uint32 bankslot) { + + delete[] _banks[bankslot].data; + _banks[bankslot].data = 0; + + debug(5, "Erased bank in slot %d", bankslot); +} + diff --git a/queen/graphics.h b/queen/graphics.h new file mode 100644 index 00000000000..586679585c9 --- /dev/null +++ b/queen/graphics.h @@ -0,0 +1,66 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef QUEENGRAPHICS_H +#define QUEENGRAPHICS_H + +#include "queen/queen.h" + + +#define MAX_BANK_SIZE 110 +#define MAX_FRAMES_NUMBER 256 +#define MAX_BANKS_NUMBER 18 + + + +struct ObjectFrame { + uint16 width, height; + uint16 xhotspot, yhotspot; + uint8 *data; +}; + + +class QueenGraphics { +public: + + QueenGraphics(QueenResource *resource); + + void bankLoad(const char *bankname, uint32 bankslot); + void bankUnpack(uint srcframe, uint dstframe, uint32 bankslot); + void bankOverpack(uint srcframe, uint dstframe, uint32 bankslot); + void bankErase(uint32 bankslot); + +private: + + struct PackedBank { + uint32 indexes[MAX_BANK_SIZE]; + uint8 *data; + }; + + ObjectFrame _frames[MAX_FRAMES_NUMBER]; + PackedBank _banks[MAX_BANKS_NUMBER]; + + QueenResource *_resource; + +}; + + +#endif diff --git a/queen/logic.cpp b/queen/logic.cpp index ba435c22a30..3e3efd96526 100644 --- a/queen/logic.cpp +++ b/queen/logic.cpp @@ -23,7 +23,7 @@ QueenLogic::QueenLogic(QueenResource *resource) { _resource = resource; - _jas = _resource->loadFile("QUEEN.JAS"); + _jas = _resource->loadFile("QUEEN.JAS", 20); initialise(); } diff --git a/queen/module.mk b/queen/module.mk index e6987e27a44..aed3cba6c11 100644 --- a/queen/module.mk +++ b/queen/module.mk @@ -1,6 +1,7 @@ MODULE := queen MODULE_OBJS = \ + queen/graphics.o \ queen/logic.o \ queen/resource.o \ queen/restables.o \ diff --git a/queen/resource.cpp b/queen/resource.cpp index aca4fb0f2c4..1a0e7345f97 100644 --- a/queen/resource.cpp +++ b/queen/resource.cpp @@ -115,15 +115,19 @@ uint32 QueenResource::fileOffset(const char *filename) { return _gameVersion->resourceTable[resourceIndex(filename)].offset; } -uint8 *QueenResource::loadFile(const char *filename) { +uint8 *QueenResource::loadFile(const char *filename, uint32 skipBytes) { uint32 size = fileSize(filename); byte *mem = new byte[size]; - //skip 20 byte header - _resourceFile->seek(fileOffset(filename) + 20, SEEK_SET); - _resourceFile->read(mem, size - 20); + // skip 'skipBytes' bytes (useful for headers) + _resourceFile->seek(fileOffset(filename) + skipBytes, SEEK_SET); + _resourceFile->read(mem, size - skipBytes); return mem; } +bool QueenResource::exists(const char *filename) { + return resourceIndex(filename) >= 0; +} + const char *QueenResource::JASVersion() { static char versionStr[6]; if (_gameVersion->isDemo) diff --git a/queen/resource.h b/queen/resource.h index 31c12691630..aea589f49dd 100644 --- a/queen/resource.h +++ b/queen/resource.h @@ -39,12 +39,14 @@ struct GameVersion { const struct ResourceEntry *resourceTable; }; + class QueenResource { public: QueenResource(char *datafilePath); ~QueenResource(void); - uint8 *loadFile(const char *filename); + uint8 *loadFile(const char *filename, uint32 skipbytes = 0); + bool exists(const char *filename); protected: File *_resourceFile;