diff options
Diffstat (limited to 'scumm/smush/chunk.cpp')
-rw-r--r-- | scumm/smush/chunk.cpp | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/scumm/smush/chunk.cpp b/scumm/smush/chunk.cpp index f35e91fffa..0f3bfbf734 100644 --- a/scumm/smush/chunk.cpp +++ b/scumm/smush/chunk.cpp @@ -22,35 +22,34 @@ #include <stdafx.h> #include "chunk.h" -#include "common/engine.h" // for debug, warning, error +#include "common/engine.h" #include "common/file.h" #include "common/str.h" -#include <stdio.h> // for FILE, fopen, fclose, fseek and ftell -#include <string.h> // for memcpy - -/*! @brief very small and fast wrapper for a ifstream. - - implements reference counting, so that ::file_Chunk does not leak memory ! -*/ class FilePtr { ScummVM::String _filename; File _ifs; int32 _refcount; int32 _curPos; public: - FilePtr(const char *fname, const char *directory) : _filename(fname), _refcount(1), _curPos(0) { - debug(9, "FilePtr created for %s", fname); - _ifs.open(fname, directory); - if(_ifs.isOpen() == false) error("FilePtr unable to read file %s", fname); - } + FilePtr(const char *fname, const char *directory) : + _filename(fname), + _refcount(1), + _curPos(0) { + debug(9, "FilePtr created for %s", fname); + _ifs.open(fname, directory); + if(_ifs.isOpen() == false) error("FilePtr unable to read file %s", fname); + } + ~FilePtr() { debug(9, "FilePtr destroyed for %s", _filename.c_str()); _ifs.close(); } + int32 tell() { return _curPos; } + bool seek(int32 pos) { if(pos != _curPos) { _ifs.seek(pos, SEEK_SET); @@ -58,14 +57,17 @@ public: } return true; } + bool read(void *ptr, int32 size) { _ifs.read(ptr, size); _curPos += size; return true; } + void incRef() { _refcount++; } + void decRef() { if(--_refcount == 0) delete this; @@ -82,11 +84,16 @@ const char *Chunk::ChunkString(Chunk::type t) { return data; } -FileChunk::FileChunk() : _data(0), _type(0), _size(0), _curPos(0) { +FileChunk::FileChunk() : + _data(0), + _type(0), + _size(0), + _curPos(0) { } FileChunk::~FileChunk() { - if(_data) _data->decRef(); + if(_data) + _data->decRef(); } FileChunk::FileChunk(const char *fname, const char *directory) { @@ -137,11 +144,15 @@ bool FileChunk::seek(int32 delta, seek_type dir) { _curPos += delta; break; case seek_start: - if(delta < 0) error("invalid seek request"); + if(delta < 0) + error("invalid seek request"); + _curPos = (uint32)delta; break; case seek_end: - if(delta > 0 || (_size + delta) < 0) error("invalid seek request"); + if(delta > 0 || (_size + delta) < 0) + error("invalid seek request"); + _curPos = (uint32)(_size + delta); break; } @@ -154,6 +165,7 @@ bool FileChunk::seek(int32 delta, seek_type dir) { bool FileChunk::read(void *buffer, uint32 size) { if(size <= 0 || (_curPos + size) > _size) error("invalid buffer read request"); + _data->seek(_offset + _curPos); _data->read(buffer, size); _curPos += size; @@ -163,6 +175,7 @@ bool FileChunk::read(void *buffer, uint32 size) { int8 FileChunk::getChar() { if(_curPos >= _size) error("invalid char read request"); + _data->seek(_offset + _curPos); int8 buffer; _data->read(&buffer, sizeof(buffer)); @@ -173,6 +186,7 @@ int8 FileChunk::getChar() { byte FileChunk::getByte() { if(_curPos >= _size) error("invalid byte read request"); + _data->seek(_offset + _curPos); byte buffer; _data->read(&buffer, sizeof(buffer)); @@ -188,6 +202,7 @@ int16 FileChunk::getShort() { uint16 FileChunk::getWord() { if(_curPos >= _size - 1) error("invalid word read request"); + _data->seek(_offset + _curPos); uint16 buffer; _data->read(&buffer, sizeof(buffer)); @@ -198,6 +213,7 @@ uint16 FileChunk::getWord() { uint32 FileChunk::getDword() { if(_curPos >= _size - 3) error("invalid dword read request"); + _data->seek(_offset + _curPos); uint32 buffer; _data->read(&buffer, sizeof(buffer)); @@ -207,7 +223,8 @@ uint32 FileChunk::getDword() { ContChunk::ContChunk(byte *data) { if(data == 0) - error("Chunk() called with NULL point32er"); + error("Chunk() called with NULL pointer"); + _type = (Chunk::type)READ_BE_UINT32(data); _size = READ_BE_UINT32(data + 4); _data = data + sizeof(Chunk::type) + sizeof(uint32); @@ -257,39 +274,51 @@ bool ContChunk::seek(int32 delta, seek_type dir) { } bool ContChunk::read(void *buffer, uint32 size) { - if(size <= 0 || (_curPos + size) > _size) error("invalid buffer read request"); + if(size <= 0 || (_curPos + size) > _size) + error("invalid buffer read request"); + memcpy(buffer, _data + _curPos, size); _curPos += size; return true; } int8 ContChunk::getChar() { - if(_curPos >= _size) error("invalid char read request"); + if(_curPos >= _size) + error("invalid char read request"); + return _data[_curPos++]; } byte ContChunk::getByte() { - if(_curPos >= _size) error("invalid byte read request"); + if(_curPos >= _size) + error("invalid byte read request"); + byte *ptr = (byte *)(_data + _curPos); _curPos += 1; return *ptr; } int16 ContChunk::getShort() { - if(_curPos >= _size - 1) error("invalid int16 read request"); + if(_curPos >= _size - 1) + error("invalid int16 read request"); + int16 buffer = getWord(); return *((int16 *)&buffer); } uint16 ContChunk::getWord() { - if(_curPos >= _size - 1) error("invalid word read request"); + if(_curPos >= _size - 1) + error("invalid word read request"); + uint16 *ptr = (uint16 *)(_data + _curPos); _curPos += 2; return READ_LE_UINT16(ptr); } uint32 ContChunk::getDword() { - if(_curPos >= _size - 3) error("invalid dword read request"); + if(_curPos >= _size - 3) + error("invalid dword read request"); + uint32 *ptr = (uint32 *)(_data + _curPos); _curPos += 4; return READ_LE_UINT32(ptr); |