2012-04-29 11:01:40 +10:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
2012-05-14 07:43:50 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This code is based on original Tony Tough source code
|
|
|
|
*
|
|
|
|
* Copyright (c) 1997-2003 Nayma Software
|
|
|
|
*/
|
2012-04-29 11:01:40 +10:00
|
|
|
|
|
|
|
#include "tony/utils.h"
|
2012-04-29 23:19:30 +10:00
|
|
|
#include "tony/tony.h"
|
|
|
|
#include "tony/mpal/lzo.h"
|
2012-04-29 11:01:40 +10:00
|
|
|
|
|
|
|
namespace Tony {
|
|
|
|
|
2012-04-29 23:19:30 +10:00
|
|
|
/**
|
|
|
|
* Extracts a string from a data stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param df data stream
|
|
|
|
* @param var String
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-08-25 00:31:00 +02:00
|
|
|
RMDataStream &operator>>(RMDataStream &df, Common::String &var) {
|
2012-04-29 23:19:30 +10:00
|
|
|
uint8 len;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
df >> len;
|
|
|
|
|
2012-08-25 00:31:00 +02:00
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
char c;
|
|
|
|
df >> c;
|
|
|
|
var += c;
|
|
|
|
}
|
2012-05-21 23:53:13 +02:00
|
|
|
|
2012-04-29 23:19:30 +10:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
2012-05-03 22:49:30 +10:00
|
|
|
/****************************************************************************\
|
2012-05-20 13:54:59 +10:00
|
|
|
* RMFileStreamSlow Methods
|
2012-05-03 22:49:30 +10:00
|
|
|
\****************************************************************************/
|
|
|
|
|
|
|
|
RMFileStreamSlow::RMFileStreamSlow() : RMDataStream() {
|
|
|
|
_stream = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
RMFileStreamSlow::~RMFileStreamSlow() {
|
2012-06-07 08:42:35 +02:00
|
|
|
close();
|
2012-05-03 22:49:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMFileStreamSlow::close() {
|
2012-05-03 22:49:30 +10:00
|
|
|
delete _stream;
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMFileStreamSlow::openFile(Common::File &file) {
|
2012-05-03 22:49:30 +10:00
|
|
|
_stream = file.readStream(file.size());
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
_length = _stream->pos();
|
2012-05-03 22:49:30 +10:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMFileStreamSlow::openFile(const char *lpFN) {
|
2012-05-20 13:54:59 +10:00
|
|
|
// Open file for reading
|
2012-05-03 22:49:30 +10:00
|
|
|
Common::File f;
|
|
|
|
if (!f.open(lpFN))
|
|
|
|
return false;
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
_length = f.size();
|
2012-05-03 22:49:30 +10:00
|
|
|
_stream = f.readStream(f.size());
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
RMDataStream &RMFileStreamSlow::operator+=(int nBytes) {
|
2012-06-07 08:42:35 +02:00
|
|
|
seek(nBytes);
|
2012-05-03 22:49:30 +10:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMFileStreamSlow::pos() {
|
2012-05-03 22:49:30 +10:00
|
|
|
return _stream->pos();
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMFileStreamSlow::isEOF() {
|
|
|
|
return (pos() >= _length);
|
2012-05-03 22:49:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMFileStreamSlow::seek(int nBytes, RMDSPos where) {
|
2012-05-03 22:49:30 +10:00
|
|
|
switch (where) {
|
|
|
|
case START:
|
|
|
|
return _stream->seek(nBytes);
|
2012-05-21 23:53:13 +02:00
|
|
|
|
2012-05-03 22:49:30 +10:00
|
|
|
case END:
|
|
|
|
return _stream->seek(nBytes, SEEK_END);
|
|
|
|
|
|
|
|
case CUR:
|
|
|
|
return _stream->seek(nBytes, SEEK_CUR);
|
|
|
|
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMFileStreamSlow::read(void *buf, int size) {
|
2012-05-03 22:49:30 +10:00
|
|
|
uint32 dwRead;
|
|
|
|
|
|
|
|
dwRead = _stream->read(buf, size);
|
|
|
|
return ((int)dwRead == size);
|
|
|
|
}
|
|
|
|
|
|
|
|
RMFileStreamSlow &operator>>(RMFileStreamSlow &df, char &var) {
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&var, 1);
|
2012-05-03 22:49:30 +10:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
RMFileStreamSlow &operator>>(RMFileStreamSlow &df, byte &var) {
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&var, 1);
|
2012-05-03 22:49:30 +10:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
RMFileStreamSlow &operator>>(RMFileStreamSlow &df, uint16 &var) {
|
|
|
|
uint16 v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 2);
|
2012-05-03 22:49:30 +10:00
|
|
|
v = FROM_LE_16(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
RMFileStreamSlow &operator>>(RMFileStreamSlow &df, int16 &var) {
|
|
|
|
uint16 v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 2);
|
2012-05-03 22:49:30 +10:00
|
|
|
var = (int16)FROM_LE_16(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
RMFileStreamSlow &operator>>(RMFileStreamSlow &df, int &var) {
|
|
|
|
int v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 4);
|
2012-05-03 22:49:30 +10:00
|
|
|
var = FROM_LE_32(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
RMFileStreamSlow &operator>>(RMFileStreamSlow &df, uint32 &var) {
|
|
|
|
uint32 v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 4);
|
2012-05-03 22:49:30 +10:00
|
|
|
var = FROM_LE_32(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
2012-04-29 23:19:30 +10:00
|
|
|
/****************************************************************************\
|
|
|
|
* RMDataStream methods
|
|
|
|
\****************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
|
|
|
RMDataStream::RMDataStream() {
|
2012-06-07 08:42:35 +02:00
|
|
|
_length = 0;
|
|
|
|
_pos = 0;
|
|
|
|
_bError = false;
|
2012-06-15 08:42:24 +02:00
|
|
|
|
|
|
|
_buf = NULL;
|
|
|
|
_ecode = 0;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*/
|
|
|
|
RMDataStream::~RMDataStream() {
|
2012-06-07 08:42:35 +02:00
|
|
|
close();
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Close a stream
|
|
|
|
*/
|
2012-06-18 08:24:33 +02:00
|
|
|
void RMDataStream::close() {
|
2012-06-07 08:42:35 +02:00
|
|
|
_length = 0;
|
|
|
|
_pos = 0;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Takes the address of the buffer from which will be read the data.
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param lpBuf Data buffer
|
|
|
|
* @param size Size of the buffer
|
|
|
|
* @remarks If the length of the buffer is not known, and cannot be
|
|
|
|
* specified, then EOF() and Seek() to end won't work.
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMDataStream::openBuffer(const byte *lpBuf, int size) {
|
|
|
|
_length = size;
|
|
|
|
_buf = lpBuf;
|
|
|
|
_bError = false;
|
|
|
|
_pos = 0;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the length of the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @returns Stream length
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMDataStream::length() {
|
|
|
|
return _length;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines if the end of the stream has been reached
|
2012-05-21 23:53:13 +02:00
|
|
|
* @returns true if end of stream reached, false if not
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMDataStream::isEOF() {
|
|
|
|
return (_pos >= _length);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extracts data from the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param df Stream
|
|
|
|
* @param var Variable of a supported type
|
|
|
|
* @returns Value read from the stream
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
|
|
|
RMDataStream &operator>>(RMDataStream &df, char &var) {
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&var, 1);
|
2012-04-29 23:19:30 +10:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extracts data from the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param df Stream
|
|
|
|
* @param var Variable of a supported type
|
|
|
|
* @returns Value read from the stream
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
|
|
|
RMDataStream &operator>>(RMDataStream &df, uint8 &var) {
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&var, 1);
|
2012-04-29 23:19:30 +10:00
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extracts data from the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param df Stream
|
|
|
|
* @param var Variable of a supported type
|
|
|
|
* @returns Value read from the stream
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
|
|
|
RMDataStream &operator>>(RMDataStream &df, uint16 &var) {
|
|
|
|
uint16 v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 2);
|
2012-04-29 23:19:30 +10:00
|
|
|
|
|
|
|
var = FROM_LE_16(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extracts data from the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param df Stream
|
|
|
|
* @param var Variable of a supported type
|
|
|
|
* @returns Value read from the stream
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
|
|
|
RMDataStream &operator>>(RMDataStream &df, int16 &var) {
|
|
|
|
uint16 v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 2);
|
2012-04-29 23:19:30 +10:00
|
|
|
|
|
|
|
var = (int16)FROM_LE_16(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extracts data from the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param df Stream
|
|
|
|
* @param var Variable of a supported type
|
|
|
|
* @returns Value read from the stream
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
|
|
|
RMDataStream &operator>>(RMDataStream &df, int &var) {
|
|
|
|
uint32 v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 4);
|
2012-04-29 23:19:30 +10:00
|
|
|
|
|
|
|
var = (int)FROM_LE_32(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extracts data from the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param df Stream
|
|
|
|
* @param var Variable of a supported type
|
|
|
|
* @returns Value read from the stream
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
|
|
|
RMDataStream &operator>>(RMDataStream &df, uint32 &var) {
|
|
|
|
uint32 v;
|
2012-06-07 08:42:35 +02:00
|
|
|
df.read(&v, 4);
|
2012-04-29 23:19:30 +10:00
|
|
|
|
|
|
|
var = FROM_LE_32(v);
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads a series of data from the stream in a buffer
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param lpBuf Data buffer
|
|
|
|
* @param size Size of the buffer
|
|
|
|
* @returns true if we have reached the end, false if not
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMDataStream::read(void *lpBuf, int size) {
|
2012-04-29 23:19:30 +10:00
|
|
|
byte *dest = (byte *)lpBuf;
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
if ((_pos + size) > _length) {
|
|
|
|
Common::copy(_buf + _pos, _buf + _pos + (_length - _pos), dest);
|
2012-04-29 23:19:30 +10:00
|
|
|
|
|
|
|
return true;
|
|
|
|
} else {
|
2012-06-07 08:42:35 +02:00
|
|
|
Common::copy(_buf + _pos, _buf + _pos + size, dest);
|
2012-04-29 23:19:30 +10:00
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
_pos += size;
|
2012-04-29 23:19:30 +10:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Skips a number of bytes in the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param nBytres Number of bytes to skip
|
|
|
|
* @returns The stream
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
|
|
|
RMDataStream &RMDataStream::operator+=(int nBytes) {
|
2012-06-07 08:42:35 +02:00
|
|
|
_pos += nBytes;
|
2012-04-29 23:19:30 +10:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Seeks to a position within the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param nBytes Number of bytes from specified origin
|
|
|
|
* @param origin Origin to do offset from
|
|
|
|
* @returns The absolute current position in bytes
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMDataStream::seek(int nBytes, RMDSPos origin) {
|
2012-04-29 23:19:30 +10:00
|
|
|
switch (origin) {
|
|
|
|
case CUR:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case START:
|
2012-06-07 08:42:35 +02:00
|
|
|
_pos = 0;
|
2012-04-29 23:19:30 +10:00
|
|
|
break;
|
|
|
|
|
|
|
|
case END:
|
2012-06-07 08:42:35 +02:00
|
|
|
if (_length == SIZENOTKNOWN)
|
|
|
|
return _pos;
|
|
|
|
_pos = _length;
|
2012-04-29 23:19:30 +10:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
_pos += nBytes;
|
|
|
|
return _pos;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the current position of the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @returns The current position
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMDataStream::pos() {
|
|
|
|
return _pos;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if an error occurred during reading the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @returns true if there was an error, false otherwise
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMDataStream::isError() {
|
|
|
|
return _bError;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets an error code for the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @param code Error code
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMDataStream::setError(int code) {
|
|
|
|
_bError = true;
|
|
|
|
_ecode = code;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the error code for the stream
|
2012-05-21 23:53:13 +02:00
|
|
|
* @returns Error code
|
2012-04-29 23:19:30 +10:00
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMDataStream::getError() {
|
|
|
|
return _ecode;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************\
|
|
|
|
* RMPoint methods
|
|
|
|
\****************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
|
|
|
RMPoint::RMPoint() {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x = _y = 0;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy constructor
|
|
|
|
*/
|
|
|
|
RMPoint::RMPoint(const RMPoint &p) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x = p._x;
|
|
|
|
_y = p._y;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor with integer parameters
|
|
|
|
*/
|
|
|
|
RMPoint::RMPoint(int x1, int y1) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x = x1;
|
|
|
|
_y = y1;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy operator
|
|
|
|
*/
|
|
|
|
RMPoint &RMPoint::operator=(RMPoint p) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x = p._x;
|
|
|
|
_y = p._y;
|
2012-04-29 23:19:30 +10:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Offsets the point by another point
|
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMPoint::offset(const RMPoint &p) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x += p._x;
|
|
|
|
_y += p._y;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Offsets the point by a specified offset
|
|
|
|
*/
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMPoint::offset(int xOff, int yOff) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x += xOff;
|
|
|
|
_y += yOff;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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) {
|
2012-06-07 08:42:35 +02:00
|
|
|
offset(p);
|
2012-04-29 23:19:30 +10:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Subtract (offset) of a point
|
|
|
|
*/
|
2012-05-03 22:49:30 +10:00
|
|
|
RMPoint &RMPoint::operator-=(RMPoint p) {
|
2012-06-07 08:42:35 +02:00
|
|
|
offset(-p);
|
2012-04-29 23:19:30 +10:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Inverts a point
|
|
|
|
*/
|
|
|
|
RMPoint RMPoint::operator-() {
|
|
|
|
RMPoint p;
|
|
|
|
|
2012-06-11 20:24:25 +02:00
|
|
|
p._x = -_x;
|
|
|
|
p._y = -_y;
|
2012-04-29 23:19:30 +10:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Equality operator
|
|
|
|
*/
|
|
|
|
bool RMPoint::operator==(RMPoint p) {
|
2012-06-11 20:24:25 +02:00
|
|
|
return ((_x == p._x) && (_y == p._y));
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Not equal operator
|
|
|
|
*/
|
|
|
|
bool RMPoint::operator!=(RMPoint p) {
|
2012-06-11 20:24:25 +02:00
|
|
|
return ((_x != p._x) || (_y != p._y));
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads a point from a stream
|
|
|
|
*/
|
|
|
|
RMDataStream &operator>>(RMDataStream &ds, RMPoint &p) {
|
2012-06-11 20:24:25 +02:00
|
|
|
ds >> p._x >> p._y;
|
2012-04-29 23:19:30 +10:00
|
|
|
return ds;
|
|
|
|
}
|
|
|
|
|
2012-06-18 19:50:29 +10:00
|
|
|
/****************************************************************************\
|
|
|
|
* RMPointReference methods
|
|
|
|
\****************************************************************************/
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2012-04-29 23:19:30 +10:00
|
|
|
/****************************************************************************\
|
|
|
|
* RMRect methods
|
|
|
|
\****************************************************************************/
|
|
|
|
|
2012-06-18 19:50:29 +10:00
|
|
|
RMRect::RMRect(): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
|
2012-06-07 08:42:35 +02:00
|
|
|
setEmpty();
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-18 08:24:33 +02:00
|
|
|
void RMRect::setEmpty() {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x1 = _y1 = _x2 = _y2 = 0;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-18 19:50:29 +10:00
|
|
|
RMRect::RMRect(const RMPoint &p1, const RMPoint &p2): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
|
2012-06-07 08:42:35 +02:00
|
|
|
setRect(p1, p2);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-18 19:50:29 +10:00
|
|
|
RMRect::RMRect(int X1, int Y1, int X2, int Y2): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
|
2012-06-07 08:42:35 +02:00
|
|
|
setRect(X1, Y1, X2, Y2);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-18 19:50:29 +10:00
|
|
|
RMRect::RMRect(const RMRect &rc): _topLeft(_x1, _y1), _bottomRight(_x2, _y2) {
|
2012-06-07 08:42:35 +02:00
|
|
|
copyRect(rc);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMRect::setRect(const RMPoint &p1, const RMPoint &p2) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x1 = p1._x;
|
|
|
|
_y1 = p1._y;
|
|
|
|
_x2 = p2._x;
|
|
|
|
_y2 = p2._y;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMRect::setRect(int X1, int Y1, int X2, int Y2) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x1 = X1;
|
|
|
|
_y1 = Y1;
|
|
|
|
_x2 = X2;
|
|
|
|
_y2 = Y2;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMRect::setRect(const RMRect &rc) {
|
|
|
|
copyRect(rc);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMRect::copyRect(const RMRect &rc) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x1 = rc._x1;
|
|
|
|
_y1 = rc._y1;
|
|
|
|
_x2 = rc._x2;
|
|
|
|
_y2 = rc._y2;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
RMPoint RMRect::center() {
|
2012-06-11 20:24:25 +02:00
|
|
|
return RMPoint((_x2 - _x1) / 2, (_y2 - _y1) / 2);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMRect::width() const {
|
2012-06-11 20:24:25 +02:00
|
|
|
return _x2 - _x1;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMRect::height() const {
|
2012-06-11 20:24:25 +02:00
|
|
|
return _y2 - _y1;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
int RMRect::size() const {
|
|
|
|
return width() * height();
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-16 10:57:35 +10:00
|
|
|
RMRect::operator Common::Rect() const {
|
|
|
|
return Common::Rect(_x1, _y1, _x2, _y2);
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
bool RMRect::isEmpty() const {
|
2012-06-11 20:24:25 +02:00
|
|
|
return (_x1 == 0 && _y1 == 0 && _x2 == 0 && _y2 == 0);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
const RMRect &RMRect::operator=(const RMRect &rc) {
|
2012-06-07 08:42:35 +02:00
|
|
|
copyRect(rc);
|
2012-04-29 23:19:30 +10:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMRect::offset(int xOff, int yOff) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x1 += xOff;
|
|
|
|
_y1 += yOff;
|
|
|
|
_x2 += xOff;
|
|
|
|
_y2 += yOff;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMRect::offset(const RMPoint &p) {
|
2012-06-11 20:24:25 +02:00
|
|
|
_x1 += p._x;
|
|
|
|
_y1 += p._y;
|
|
|
|
_x2 += p._x;
|
|
|
|
_y2 += p._y;
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
const RMRect &RMRect::operator+=(RMPoint p) {
|
2012-06-07 08:42:35 +02:00
|
|
|
offset(p);
|
2012-04-29 23:19:30 +10:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RMRect &RMRect::operator-=(RMPoint p) {
|
2012-06-07 08:42:35 +02:00
|
|
|
offset(-p);
|
2012-04-29 23:19:30 +10:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
RMRect operator+(const RMRect &rc, RMPoint p) {
|
|
|
|
RMRect r(rc);
|
|
|
|
return (r += p);
|
|
|
|
}
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
RMRect operator-(const RMRect &rc, RMPoint p) {
|
2012-04-29 23:19:30 +10:00
|
|
|
RMRect r(rc);
|
|
|
|
|
|
|
|
return (r -= p);
|
|
|
|
}
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
RMRect operator+(RMPoint p, const RMRect &rc) {
|
2012-04-29 23:19:30 +10:00
|
|
|
RMRect r(rc);
|
|
|
|
|
2012-05-20 13:54:59 +10:00
|
|
|
return (r += p);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
RMRect operator-(RMPoint p, const RMRect &rc) {
|
2012-04-29 23:19:30 +10:00
|
|
|
RMRect r(rc);
|
|
|
|
|
2012-05-20 13:54:59 +10:00
|
|
|
return (r += p);
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
bool RMRect::operator==(const RMRect &rc) {
|
2012-06-11 20:24:25 +02:00
|
|
|
return ((_x1 == rc._x1) && (_y1 == rc._y1) && (_x2 == rc._x2) && (_y2 == rc._y2));
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
bool RMRect::operator!=(const RMRect &rc) {
|
2012-06-11 20:24:25 +02:00
|
|
|
return ((_x1 != rc._x1) || (_y1 != rc._y1) || (_x2 != rc._x2) || (_y2 != rc._y2));
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
2012-06-18 08:24:33 +02:00
|
|
|
void RMRect::normalizeRect() {
|
2012-06-11 20:24:25 +02:00
|
|
|
setRect(MIN(_x1, _x2), MIN(_y1, _y2), MAX(_x1, _x2), MAX(_y1, _y2));
|
2012-04-29 23:19:30 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
RMDataStream &operator>>(RMDataStream &ds, RMRect &rc) {
|
2012-06-11 20:24:25 +02:00
|
|
|
ds >> rc._x1 >> rc._y1 >> rc._x2 >> rc._y2;
|
2012-04-29 23:19:30 +10:00
|
|
|
return ds;
|
|
|
|
}
|
|
|
|
|
2012-04-29 11:01:40 +10:00
|
|
|
/****************************************************************************\
|
|
|
|
* Resource Update
|
|
|
|
\****************************************************************************/
|
|
|
|
|
|
|
|
RMResUpdate::RMResUpdate() {
|
|
|
|
_infos = NULL;
|
2012-06-15 08:42:24 +02:00
|
|
|
_numUpd = 0;
|
2012-04-29 11:01:40 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
RMResUpdate::~RMResUpdate() {
|
|
|
|
if (_infos) {
|
|
|
|
delete[] _infos;
|
|
|
|
_infos = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_hFile.isOpen())
|
|
|
|
_hFile.close();
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
void RMResUpdate::init(const Common::String &fileName) {
|
2012-04-29 11:01:40 +10:00
|
|
|
// Open the resource update file
|
|
|
|
if (!_hFile.open(fileName))
|
|
|
|
// It doesn't exist, so exit immediately
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint8 version;
|
|
|
|
uint32 i;
|
|
|
|
|
|
|
|
version = _hFile.readByte();
|
|
|
|
_numUpd = _hFile.readUint32LE();
|
|
|
|
|
|
|
|
_infos = new ResUpdInfo[_numUpd];
|
|
|
|
|
|
|
|
// Load the index of the resources in the file
|
2012-05-20 13:54:59 +10:00
|
|
|
for (i = 0; i < _numUpd; ++i) {
|
2012-04-29 11:01:40 +10:00
|
|
|
ResUpdInfo &info = _infos[i];
|
|
|
|
|
2012-06-11 20:24:25 +02:00
|
|
|
info._dwRes = _hFile.readUint32LE();
|
|
|
|
info._offset = _hFile.readUint32LE();
|
|
|
|
info._size = _hFile.readUint32LE();
|
|
|
|
info._cmpSize = _hFile.readUint32LE();
|
2012-04-29 11:01:40 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-07 08:42:35 +02:00
|
|
|
HGLOBAL RMResUpdate::queryResource(uint32 dwRes) {
|
2012-04-29 11:01:40 +10:00
|
|
|
// If there isn't an update file, return NULL
|
|
|
|
if (!_hFile.isOpen())
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
uint32 i;
|
2012-05-20 13:54:59 +10:00
|
|
|
for (i = 0; i < _numUpd; ++i)
|
2012-06-11 20:24:25 +02:00
|
|
|
if (_infos[i]._dwRes == dwRes)
|
2012-04-29 11:01:40 +10:00
|
|
|
// Found the index
|
|
|
|
break;
|
|
|
|
|
2012-05-21 23:53:13 +02:00
|
|
|
if (i == _numUpd)
|
2012-04-29 11:01:40 +10:00
|
|
|
// Couldn't find a matching resource, so return NULL
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
const ResUpdInfo &info = _infos[i];
|
2012-06-11 20:24:25 +02:00
|
|
|
byte *cmpBuf = new byte[info._cmpSize];
|
2012-04-29 11:01:40 +10:00
|
|
|
uint32 dwRead;
|
|
|
|
|
|
|
|
// Move to the correct offset and read in the compressed data
|
2012-06-11 20:24:25 +02:00
|
|
|
_hFile.seek(info._offset);
|
|
|
|
dwRead = _hFile.read(cmpBuf, info._cmpSize);
|
2012-04-29 11:01:40 +10:00
|
|
|
|
2012-06-11 20:24:25 +02:00
|
|
|
if (info._cmpSize > dwRead) {
|
2012-04-29 11:01:40 +10:00
|
|
|
// Error occurred reading data, so return NULL
|
|
|
|
delete[] cmpBuf;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Allocate space for the output resource
|
2012-06-11 20:24:25 +02:00
|
|
|
HGLOBAL destBuf = globalAllocate(0, info._size);
|
2012-06-07 21:14:59 +02:00
|
|
|
byte *lpDestBuf = (byte *)globalLock(destBuf);
|
2012-04-29 11:01:40 +10:00
|
|
|
uint32 dwSize;
|
|
|
|
|
|
|
|
// Decompress the data
|
2012-06-11 20:24:25 +02:00
|
|
|
lzo1x_decompress(cmpBuf, info._cmpSize, lpDestBuf, &dwSize);
|
2012-04-29 11:01:40 +10:00
|
|
|
|
|
|
|
// Delete buffer for compressed data
|
|
|
|
delete [] cmpBuf;
|
|
|
|
|
|
|
|
// Return the resource
|
2012-06-07 21:14:59 +02:00
|
|
|
globalUnlock(destBuf);
|
2012-06-08 23:00:48 +10:00
|
|
|
return destBuf;
|
2012-04-29 11:01:40 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
} // End of namespace Tony
|