diff --git a/engines/access/access.h b/engines/access/access.h index e6a3f332c69e..c93a1b32e567 100644 --- a/engines/access/access.h +++ b/engines/access/access.h @@ -58,7 +58,8 @@ namespace Access { enum { GType_Amazon = 1, - GType_MeanStreets = 2 + GType_MeanStreets = 2, + GType_Noctropolis = 3 }; enum AccessDebugChannels { diff --git a/engines/access/amazon/amazon_game.cpp b/engines/access/amazon/amazon_game.cpp index d1ba0e0258f0..5c2cda61aafc 100644 --- a/engines/access/amazon/amazon_game.cpp +++ b/engines/access/amazon/amazon_game.cpp @@ -126,6 +126,8 @@ void AmazonEngine::doTitle() { _sound->playSound(1); _objectsTable[0] = _files->loadFile(0, 2); + SpriteResource *spr = new SpriteResource(this, _objectsTable[0], _files->_filesize); + _sound->playSound(1); _screen->_loadPalFlag = false; @@ -141,9 +143,11 @@ void AmazonEngine::doTitle() { _buffer2.copyFrom(_buffer1); int id = READ_LE_UINT16(COUNTDOWN + _pCount * 4); int xp = READ_LE_UINT16(COUNTDOWN + _pCount * 4 + 2); - _screen->plotImage(_objectsTable[0], id, Common::Point(xp, 71)); + _screen->plotImage(spr, id, Common::Point(xp, 71)); } // TODO: More to do + + delete spr; } void AmazonEngine::doOpening() { diff --git a/engines/access/amazon/amazon_room.cpp b/engines/access/amazon/amazon_room.cpp index 5627325f6ee6..056fa8f1ebb5 100644 --- a/engines/access/amazon/amazon_room.cpp +++ b/engines/access/amazon/amazon_room.cpp @@ -122,16 +122,18 @@ void AmazonRoom::roomSet() { } void AmazonRoom::roomMenu() { - _icon = _vm->_files->loadFile("ICONS.LZ"); + byte *iconData = _vm->_files->loadFile("ICONS.LZ"); + SpriteResource *spr = new SpriteResource(_vm, _icon, _vm->_files->_filesize); + delete[] iconData; + _vm->_screen->saveScreen(); _vm->_screen->setDisplayScan(); - _vm->_destIn = _vm->_screen; - _vm->_screen->plotImage(_icon, 0, Common::Point(0, 177)); - _vm->_screen->plotImage(_icon, 1, Common::Point(143, 177)); + _vm->_destIn = _vm->_screen; // TODO: Redundant + _vm->_screen->plotImage(spr, 0, Common::Point(0, 177)); + _vm->_screen->plotImage(spr, 1, Common::Point(143, 177)); - _vm->_screen->restoreScan(); - delete[] _icon; - _icon = nullptr; + _vm->_screen->restoreScreen(); + delete spr; } } // End of namespace Amazon diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp index a0a790dbdcbe..0fb8f7d43a6e 100644 --- a/engines/access/asurface.cpp +++ b/engines/access/asurface.cpp @@ -25,9 +25,85 @@ namespace Access { + +/*------------------------------------------------------------------------*/ + +int ASurface::_leftSkip; +int ASurface::_rightSkip; +int ASurface::_topSkip; +int ASurface::_bottomSkip; +int ASurface::_clipWidth; +int ASurface::_clipHeight; +int ASurface::_lastBoundsX; +int ASurface::_lastBoundsY; +int ASurface::_lastBoundsW; +int ASurface::_lastBoundsH; + void ASurface::clearBuffer() { byte *pSrc = (byte *)getPixels(); Common::fill(pSrc, pSrc + w * h, 0); } +bool ASurface::clip(Common::Rect &r) { + int skip; + _leftSkip = _rightSkip = 0; + _topSkip = _bottomSkip = 0; + + if (r.left > _clipWidth) { + skip = -r.left; + r.setWidth(r.width() - skip); + _leftSkip = skip; + r.moveTo(0, r.top); + } + else if (r.left >= 0) + return true; + + int right = r.right - 1; + if (right < 0) + return true; + else if (right > _clipWidth) { + skip = right - _clipWidth; + r.setWidth(r.width() - skip); + _rightSkip = skip; + } + + if (r.top > _clipHeight) { + skip = -r.top; + r.setHeight(r.height() - skip); + _topSkip = skip; + r.moveTo(r.left, 0); + } + else if (r.top >= 0) + return true; + + int bottom = r.bottom - 1; + if (bottom < 0) + return true; + else if (bottom > _clipHeight) { + skip = bottom - _clipHeight; + _bottomSkip = skip; + r.setHeight(r.height() - skip); + } + + return false; +} + +void ASurface::plotImage(SpriteResource *sprite, int frameNum, const Common::Point &pt) { + SpriteFrame *frame = sprite->getFrame(frameNum); + Common::Rect r(pt.x, pt.y, pt.x + frame->w, pt.y + frame->h); + + if (!clip(r)) { + _lastBoundsX = r.left; + _lastBoundsY = r.top; + _lastBoundsW = r.width(); + _lastBoundsH = r.height(); + +// plotImage(frame, , ) + } +} + +void ASurface::plotF(SpriteFrame *frame, const Common::Point &pt) { + +} + } // End of namespace Access diff --git a/engines/access/asurface.h b/engines/access/asurface.h index ace1b2382cf4..7d1ee6c57aaa 100644 --- a/engines/access/asurface.h +++ b/engines/access/asurface.h @@ -24,16 +24,30 @@ #define ACCESS_ASURFACE_H #include "common/scummsys.h" +#include "common/array.h" #include "common/rect.h" #include "graphics/surface.h" +#include "access/data.h" namespace Access { class ASurface : public Graphics::Surface { +public: + static int _leftSkip, _rightSkip; + static int _topSkip, _bottomSkip; + static int _clipWidth, _clipHeight; + static int _lastBoundsX, _lastBoundsY; + static int _lastBoundsW, _lastBoundsH; +protected: + virtual void ASurface::plotF(SpriteFrame *frame, const Common::Point &pt); public: void clearBuffer(); void copyBuffer(Graphics::Surface *src) { copyFrom(*src); } + + bool clip(Common::Rect &r); + + void plotImage(SpriteResource *sprite, int frameNum, const Common::Point &pt); }; } // End of namespace Access diff --git a/engines/access/data.cpp b/engines/access/data.cpp index 0ef1845892d9..ed913c9be9c9 100644 --- a/engines/access/data.cpp +++ b/engines/access/data.cpp @@ -20,10 +20,47 @@ * */ -#include "access/data.h" #include "common/algorithm.h" +#include "common/endian.h" +#include "common/memstream.h" +#include "access/access.h" +#include "access/data.h" namespace Access { +SpriteResource::SpriteResource(AccessEngine *vm, const byte *data, uint32 size) { + Common::MemoryReadStream stream(data, size); + Common::Array offsets; + int count = stream.readUint16LE(); + + for (int i = 0; i < count; i++) + offsets.push_back(stream.readUint32LE()); + offsets.push_back(size); // For easier calculations of Noctropolis sizes + + // Build up the frames + for (int i = 0; i < count; ++i) { + stream.seek(offsets[i]); + + SpriteFrame *frame = new SpriteFrame(); + frame->_width = stream.readUint16LE(); + frame->_height = stream.readUint16LE(); + frame->_size = (vm->getGameID() == GType_MeanStreets) ? stream.readUint16LE() : + offsets[i + 1] - offsets[i]; + + frame->_data = new byte[frame->_size]; + stream.read(frame->_data, frame->_size); + + _frames.push_back(frame); + } +} + +SpriteResource::~SpriteResource() { + for (uint i = 0; i < _frames.size(); ++i) + delete _frames[i]; +} + +SpriteFrame::~SpriteFrame() { + delete[] _data; +} } // End of namespace Access diff --git a/engines/access/data.h b/engines/access/data.h index cf8394baf9f7..bd1e1563fcfa 100644 --- a/engines/access/data.h +++ b/engines/access/data.h @@ -24,7 +24,9 @@ #define ACCESS_DATA_H #include "common/scummsys.h" +#include "common/array.h" #include "common/rect.h" +#include "graphics/surface.h" namespace Access { @@ -56,6 +58,27 @@ class ExtraCell { int _vidSTable1; }; +class SpriteFrame : public Graphics::Surface { +public: + uint16 _width, _height; + byte *_data; + uint32 _size; + + ~SpriteFrame(); +}; + +class SpriteResource { +public: + Common::Array _frames; +public: + SpriteResource(AccessEngine *vm, const byte *data, uint32 size); + ~SpriteResource(); + + int getCount() { return _frames.size(); } + + SpriteFrame *getFrame(int idx) { return _frames[idx]; } +}; + } // End of namespace Access #endif /* ACCESS_DATA_H */ diff --git a/engines/access/player.cpp b/engines/access/player.cpp index f0cceb718008..b28e6c92bc18 100644 --- a/engines/access/player.cpp +++ b/engines/access/player.cpp @@ -129,7 +129,11 @@ void Player::load() { } _vm->_man = _vm->_man1; - Common::copy(_vm->_manPal1 + 0x270, _vm->_manPal1 + 0x270 + 0x60, _vm->_screen->_manPal); + if (_vm->_manPal1) { + Common::copy(_vm->_manPal1 + 0x270, _vm->_manPal1 + 0x270 + 0x60, _vm->_screen->_manPal); + } else { + Common::fill(_vm->_screen->_manPal + 0x270, _vm->_screen->_manPal + 0x270 + 0x60, 0); + } } void Player::calcManScale() { diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp index 6a241d0c2b05..c1a4d9143c86 100644 --- a/engines/access/screen.cpp +++ b/engines/access/screen.cpp @@ -43,15 +43,13 @@ Screen::Screen(AccessEngine *vm) : _vm(vm) { _currentPanel = 0; _hideFlag = true; _loadPalFlag = false; - _leftSkip = _rightSkip = 0; - _topSkip = _bottomSkip = 0; - _clipWidth = _clipHeight = 0; _scrollFlag = false; _scrollThreshold = 0; _startColor = _numColors = 0; _scrollX = _scrollY = 0; _scrollCol = _scrollRow = 0; - + _windowXAdd = _windowYAdd = 0; + _screenYOff = 0; } void Screen::setDisplayScan() { @@ -145,60 +143,6 @@ void Screen::copyBuffer(const byte *data) { g_system->copyRectToScreen(destP, w, 0, 0, w, h); } -void Screen::plotImage(const byte *pData, int idx, const Common::Point &pt) { - const byte *sizeP = pData + READ_LE_UINT16(pData + idx * 4); - int w = READ_LE_UINT16(sizeP); - int h = READ_LE_UINT16(sizeP + 2); - Common::Rect r(pt.x, pt.y, pt.x + w, pt.y + h); - - if (!clip(r)) { - _lastBounds = r; - //plotf(); - } -} - -bool Screen::clip(Common::Rect &r) { - int skip; - _leftSkip = _rightSkip = 0; - _topSkip = _bottomSkip = 0; - - if (r.left > _clipWidth) { - skip = -r.left; - r.setWidth(r.width() - skip); - _leftSkip = skip; - r.moveTo(0, r.top); - } else if (r.left >= 0) - return true; - - int right = r.right - 1; - if (right < 0) - return true; - else if (right > _clipWidth) { - skip = right - _clipWidth; - r.setWidth(r.width() - skip); - _rightSkip = skip; - } - - if (r.top > _clipHeight) { - skip = -r.top; - r.setHeight(r.height() - skip); - _topSkip = skip; - r.moveTo(r.left, 0); - } else if (r.top >= 0) - return true; - - int bottom = r.bottom - 1; - if (bottom < 0) - return true; - else if (bottom > _clipHeight) { - skip = bottom - _clipHeight; - _bottomSkip = skip; - r.setHeight(r.height() - skip); - } - - return false; -} - void Screen::checkScroll() { warning("TODO"); } @@ -227,10 +171,6 @@ void Screen::setBufferScan() { warning("TODO: setBufferScan"); } -void Screen::restoreScan() { - warning("TODO: restoreScan"); -} - void Screen::setScaleTable(int scale) { int total = 0; for (int idx = 0; idx < 256; ++idx) { @@ -241,7 +181,31 @@ void Screen::setScaleTable(int scale) { } void Screen::saveScreen() { - warning("TODO: saveScreen"); + _screenSave._clipWidth = _clipWidth; + _screenSave._clipHeight = _clipHeight; + _screenSave._windowXAdd = _windowXAdd; + _screenSave._windowYAdd = _windowYAdd; + _screenSave._scroll.x = _scrollX; + _screenSave._scroll.y = _scrollY; + _screenSave._scrollCol = _scrollCol; + _screenSave._scrollRow = _scrollRow; + _screenSave._bufferStart.x = _bufferStart.x; + _screenSave._bufferStart.y = _bufferStart.y; + _screenSave._screenYOff = _screenYOff; +} + +void Screen::restoreScreen() { + _clipWidth = _screenSave._clipWidth; + _clipHeight = _screenSave._clipHeight; + _windowXAdd = _screenSave._windowXAdd; + _windowYAdd = _screenSave._windowYAdd; + _scrollX = _screenSave._scroll.x; + _scrollY = _screenSave._scroll.y; + _scrollCol = _screenSave._scrollCol; + _scrollRow = _screenSave._scrollRow; + _bufferStart.x = _screenSave._bufferStart.x; + _bufferStart.y = _screenSave._bufferStart.y; + _screenYOff = _screenSave._screenYOff; } } // End of namespace Access diff --git a/engines/access/screen.h b/engines/access/screen.h index a2eac29312f5..8dc56d273cc5 100644 --- a/engines/access/screen.h +++ b/engines/access/screen.h @@ -35,6 +35,18 @@ class AccessEngine; #define PALETTE_COUNT 256 #define PALETTE_SIZE (256 * 3) +struct ScreenSave { + int _clipWidth; + int _clipHeight; + int _windowXAdd; + int _windowYAdd; + Common::Point _scroll; + int _scrollCol; + int _scrollRow; + Common::Point _bufferStart; + int _screenYOff; +}; + class Screen: public ASurface { private: AccessEngine *_vm; @@ -45,14 +57,9 @@ class Screen: public ASurface { Common::Point _msVirtualOffset; Common::Point _virtualOffsetsTable[4]; bool _hideFlag; - Common::Rect _lastBounds; - int _leftSkip, _rightSkip; - int _topSkip, _bottomSkip; - int _clipWidth, _clipHeight; + ScreenSave _screenSave; void updatePalette(); - - bool clip(Common::Rect &r); public: int _vesaMode; bool _loadPalFlag; @@ -60,8 +67,11 @@ class Screen: public ASurface { int _scrollThreshold; int _startColor, _numColors; Common::Point _vWindowSize; + Common::Point _bufferStart; int _scrollX, _scrollY; int _scrollCol, _scrollRow; + int _windowXAdd, _windowYAdd; + int _screenYOff; byte _manPal[0x60]; byte _scaleTable1[256]; byte _scaleTable2[256]; @@ -70,8 +80,6 @@ class Screen: public ASurface { void setDisplayScan(); - void restoreScan(); - void setPanel(int num); /** @@ -109,8 +117,6 @@ class Screen: public ASurface { */ void copyBuffer(const byte *data); - void plotImage(const byte *pData, int idx, const Common::Point &pt); - void checkScroll(); void copyBF1BF2(); @@ -127,7 +133,15 @@ class Screen: public ASurface { void setScaleTable(int scale); + /** + * Save all the screen display state variables + */ void saveScreen(); + + /** + * Restores previously saved screen display state variables + */ + void restoreScreen(); }; } // End of namespace Access