aboutsummaryrefslogtreecommitdiff
path: root/engines/tony/utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/tony/utils.cpp')
-rw-r--r--engines/tony/utils.cpp448
1 files changed, 448 insertions, 0 deletions
diff --git a/engines/tony/utils.cpp b/engines/tony/utils.cpp
new file mode 100644
index 0000000000..3cc09a1454
--- /dev/null
+++ b/engines/tony/utils.cpp
@@ -0,0 +1,448 @@
+/* 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.
+ *
+ */
+
+/*
+ * This code is based on original Tony Tough source code
+ *
+ * Copyright (c) 1997-2003 Nayma Software
+ */
+
+#include "tony/utils.h"
+#include "tony/tony.h"
+#include "tony/mpal/lzo.h"
+
+namespace Tony {
+
+/**
+ * Extracts a string from a data stream
+ * @param df data stream
+ */
+Common::String readString(Common::ReadStream &df) {
+ Common::String var;
+ uint8 len = df.readByte();
+
+ for (int i = 0; i < len; i++) {
+ char c;
+ c = df.readByte();
+ var += c;
+ }
+
+ return var;
+}
+
+/****************************************************************************\
+* RMPoint methods
+\****************************************************************************/
+
+/**
+ * Constructor
+ */
+RMPoint::RMPoint() {
+ _x = _y = 0;
+}
+
+/**
+ * Copy constructor
+ */
+RMPoint::RMPoint(const RMPoint &p) {
+ _x = p._x;
+ _y = p._y;
+}
+
+/**
+ * Constructor with integer parameters
+ */
+RMPoint::RMPoint(int x1, int y1) {
+ _x = x1;
+ _y = y1;
+}
+
+/**
+ * Copy operator
+ */
+RMPoint &RMPoint::operator=(RMPoint p) {
+ _x = p._x;
+ _y = p._y;
+
+ return *this;
+}
+
+/**
+ * Set a point
+ */
+void RMPoint::set(int x1, int y1) {
+ _x = x1;
+ _y = y1;
+}
+
+/**
+ * Offsets the point by another point
+ */
+void RMPoint::offset(const RMPoint &p) {
+ _x += p._x;
+ _y += p._y;
+}
+
+/**
+ * Offsets the point by a specified offset
+ */
+void RMPoint::offset(int xOff, int yOff) {
+ _x += xOff;
+ _y += yOff;
+}
+
+/**
+ * Sums together two points
+ */
+RMPoint operator+(RMPoint p1, RMPoint p2) {
+ RMPoint p(p1);
+
+ return (p += p2);
+}
+
+/**
+ * Subtracts two points
+ */
+RMPoint operator-(RMPoint p1, RMPoint p2) {
+ RMPoint p(p1);
+
+ return (p -= p2);
+}
+
+/**
+ * Sum (offset) of a point
+ */
+RMPoint &RMPoint::operator+=(RMPoint p) {
+ offset(p);
+ return *this;
+}
+
+/**
+ * Subtract (offset) of a point
+ */
+RMPoint &RMPoint::operator-=(RMPoint p) {
+ offset(-p);
+ return *this;
+}
+
+/**
+ * Inverts a point
+ */
+RMPoint RMPoint::operator-() {
+ RMPoint p;
+
+ p._x = -_x;
+ p._y = -_y;
+
+ return p;
+}
+
+/**
+ * Equality operator
+ */
+bool RMPoint::operator==(RMPoint p) {
+ return ((_x == p._x) && (_y == p._y));
+}
+
+/**
+ * Not equal operator
+ */
+bool RMPoint::operator!=(RMPoint p) {
+ return ((_x != p._x) || (_y != p._y));
+}
+
+/**
+ * Reads a point from a stream
+ */
+void RMPoint::readFromStream(Common::ReadStream &ds) {
+ _x = ds.readSint32LE();
+ _y = ds.readSint32LE();
+}
+
+/****************************************************************************\
+* RMPointReference methods
+\****************************************************************************/
+
+RMPointReference::RMPointReference(int &x, int &y): _x(x), _y(y) {
+}
+
+RMPointReference &RMPointReference::operator=(const RMPoint &p) {
+ _x = p._x; _y = p._y;
+ return *this;
+}
+
+RMPointReference &RMPointReference::operator-=(const RMPoint &p) {
+ _x -= p._x; _y -= p._y;
+ return *this;
+}
+
+RMPointReference::operator RMPoint() const {
+ return RMPoint(_x, _y);
+}
+
+/****************************************************************************\
+* RMRect methods
+\****************************************************************************/
+
+RMRect::RMRect(): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
+ setEmpty();
+}
+
+void RMRect::setEmpty() {
+ _x1 = _y1 = _x2 = _y2 = 0;
+}
+
+RMRect::RMRect(const RMPoint &p1, const RMPoint &p2): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
+ setRect(p1, p2);
+}
+
+RMRect::RMRect(int X1, int Y1, int X2, int Y2): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
+ setRect(X1, Y1, X2, Y2);
+}
+
+RMRect::RMRect(const RMRect &rc): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
+ copyRect(rc);
+}
+
+void RMRect::setRect(const RMPoint &p1, const RMPoint &p2) {
+ _x1 = p1._x;
+ _y1 = p1._y;
+ _x2 = p2._x;
+ _y2 = p2._y;
+}
+
+void RMRect::setRect(int X1, int Y1, int X2, int Y2) {
+ _x1 = X1;
+ _y1 = Y1;
+ _x2 = X2;
+ _y2 = Y2;
+}
+
+void RMRect::setRect(const RMRect &rc) {
+ copyRect(rc);
+}
+
+void RMRect::copyRect(const RMRect &rc) {
+ _x1 = rc._x1;
+ _y1 = rc._y1;
+ _x2 = rc._x2;
+ _y2 = rc._y2;
+}
+
+RMPointReference &RMRect::topLeft() {
+ return _topLeft;
+}
+
+RMPointReference &RMRect::bottomRight() {
+ return _bottomRight;
+}
+
+RMPoint RMRect::center() {
+ return RMPoint((_x2 - _x1) / 2, (_y2 - _y1) / 2);
+}
+
+int RMRect::width() const {
+ return _x2 - _x1;
+}
+
+int RMRect::height() const {
+ return _y2 - _y1;
+}
+
+int RMRect::size() const {
+ return width() * height();
+}
+
+RMRect::operator Common::Rect() const {
+ return Common::Rect(_x1, _y1, _x2, _y2);
+}
+
+bool RMRect::isEmpty() const {
+ return (_x1 == 0 && _y1 == 0 && _x2 == 0 && _y2 == 0);
+}
+
+const RMRect &RMRect::operator=(const RMRect &rc) {
+ copyRect(rc);
+ return *this;
+}
+
+void RMRect::offset(int xOff, int yOff) {
+ _x1 += xOff;
+ _y1 += yOff;
+ _x2 += xOff;
+ _y2 += yOff;
+}
+
+void RMRect::offset(const RMPoint &p) {
+ _x1 += p._x;
+ _y1 += p._y;
+ _x2 += p._x;
+ _y2 += p._y;
+}
+
+const RMRect &RMRect::operator+=(RMPoint p) {
+ offset(p);
+ return *this;
+}
+
+const RMRect &RMRect::operator-=(RMPoint p) {
+ offset(-p);
+ return *this;
+}
+
+RMRect operator+(const RMRect &rc, RMPoint p) {
+ RMRect r(rc);
+ return (r += p);
+}
+
+RMRect operator-(const RMRect &rc, RMPoint p) {
+ RMRect r(rc);
+
+ return (r -= p);
+}
+
+RMRect operator+(RMPoint p, const RMRect &rc) {
+ RMRect r(rc);
+
+ return (r += p);
+}
+
+RMRect operator-(RMPoint p, const RMRect &rc) {
+ RMRect r(rc);
+
+ return (r += p);
+}
+
+bool RMRect::operator==(const RMRect &rc) {
+ return ((_x1 == rc._x1) && (_y1 == rc._y1) && (_x2 == rc._x2) && (_y2 == rc._y2));
+}
+
+bool RMRect::operator!=(const RMRect &rc) {
+ return ((_x1 != rc._x1) || (_y1 != rc._y1) || (_x2 != rc._x2) || (_y2 != rc._y2));
+}
+
+void RMRect::normalizeRect() {
+ setRect(MIN(_x1, _x2), MIN(_y1, _y2), MAX(_x1, _x2), MAX(_y1, _y2));
+}
+
+void RMRect::readFromStream(Common::ReadStream &ds) {
+ _x1 = ds.readSint32LE();
+ _y1 = ds.readSint32LE();
+ _x2 = ds.readSint32LE();
+ _y2 = ds.readSint32LE();
+}
+
+/**
+ * Check if RMPoint is in RMRect
+ */
+bool RMRect::ptInRect(const RMPoint &pt) {
+ return (pt._x >= _x1 && pt._x <= _x2 && pt._y >= _y1 && pt._y <= _y2);
+}
+
+/****************************************************************************\
+* Resource Update
+\****************************************************************************/
+
+RMResUpdate::RMResUpdate() {
+ _infos = NULL;
+ _numUpd = 0;
+}
+
+RMResUpdate::~RMResUpdate() {
+ if (_infos) {
+ delete[] _infos;
+ _infos = NULL;
+ }
+
+ if (_hFile.isOpen())
+ _hFile.close();
+}
+
+void RMResUpdate::init(const Common::String &fileName) {
+ // Open the resource update file
+ if (!_hFile.open(fileName))
+ // It doesn't exist, so exit immediately
+ return;
+
+ uint8 version = _hFile.readByte();
+
+ _numUpd = _hFile.readUint32LE();
+
+ _infos = new ResUpdInfo[_numUpd];
+
+ // Load the index of the resources in the file
+ for (uint32 i = 0; i < _numUpd; ++i) {
+ ResUpdInfo &info = _infos[i];
+
+ info._dwRes = _hFile.readUint32LE();
+ info._offset = _hFile.readUint32LE();
+ info._size = _hFile.readUint32LE();
+ info._cmpSize = _hFile.readUint32LE();
+ }
+}
+
+MpalHandle RMResUpdate::queryResource(uint32 dwRes) {
+ // If there isn't an update file, return NULL
+ if (!_hFile.isOpen())
+ return NULL;
+
+ uint32 i;
+ for (i = 0; i < _numUpd; ++i)
+ if (_infos[i]._dwRes == dwRes)
+ // Found the index
+ break;
+
+ if (i == _numUpd)
+ // Couldn't find a matching resource, so return NULL
+ return NULL;
+
+ const ResUpdInfo &info = _infos[i];
+ byte *cmpBuf = new byte[info._cmpSize];
+ uint32 dwRead;
+
+ // Move to the correct offset and read in the compressed data
+ _hFile.seek(info._offset);
+ dwRead = _hFile.read(cmpBuf, info._cmpSize);
+
+ if (info._cmpSize > dwRead) {
+ // Error occurred reading data, so return NULL
+ delete[] cmpBuf;
+ return NULL;
+ }
+
+ // Allocate space for the output resource
+ MpalHandle destBuf = globalAllocate(0, info._size);
+ byte *lpDestBuf = (byte *)globalLock(destBuf);
+ uint32 dwSize;
+
+ // Decompress the data
+ lzo1x_decompress(cmpBuf, info._cmpSize, lpDestBuf, &dwSize);
+
+ // Delete buffer for compressed data
+ delete [] cmpBuf;
+
+ // Return the resource
+ globalUnlock(destBuf);
+ return destBuf;
+}
+
+} // End of namespace Tony