diff options
-rw-r--r-- | engines/glk/glk.cpp | 6 | ||||
-rw-r--r-- | engines/glk/glk.h | 4 | ||||
-rw-r--r-- | engines/glk/glk_api.cpp | 2 | ||||
-rw-r--r-- | engines/glk/picture.cpp | 109 | ||||
-rw-r--r-- | engines/glk/picture.h | 92 | ||||
-rw-r--r-- | engines/glk/window_graphics.cpp | 4 | ||||
-rw-r--r-- | engines/glk/window_text_buffer.cpp | 4 |
7 files changed, 189 insertions, 32 deletions
diff --git a/engines/glk/glk.cpp b/engines/glk/glk.cpp index 0c90fc79e4..0e44f04e51 100644 --- a/engines/glk/glk.cpp +++ b/engines/glk/glk.cpp @@ -43,7 +43,7 @@ GlkEngine *g_vm; GlkEngine::GlkEngine(OSystem *syst, const GlkGameDescription &gameDesc) : _gameDescription(gameDesc), Engine(syst), _random("Glk"), _clipboard(nullptr), - _conf(nullptr), _events(nullptr), _picList(nullptr), _screen(nullptr), + _conf(nullptr), _events(nullptr), _pictures(nullptr), _screen(nullptr), _selection(nullptr), _windows(nullptr), _copySelect(false), _terminated(false), gli_unregister_obj(nullptr), gli_register_arr(nullptr), gli_unregister_arr(nullptr) { g_vm = this; @@ -53,7 +53,7 @@ GlkEngine::~GlkEngine() { delete _clipboard; delete _conf; delete _events; - delete _picList; + delete _pictures; delete _screen; delete _selection; delete _streams; @@ -73,7 +73,7 @@ void GlkEngine::initialize() { _clipboard = new Clipboard(); _events = new Events(); - _picList = new PicList(); + _pictures = new Pictures(); _selection = new Selection(); _streams = new Streams(); _windows = new Windows(_screen); diff --git a/engines/glk/glk.h b/engines/glk/glk.h index 8f973f03cd..50722ae8dc 100644 --- a/engines/glk/glk.h +++ b/engines/glk/glk.h @@ -37,7 +37,7 @@ namespace Glk { class Clipboard; class Conf; class Events; -class PicList; +class Pictures; class Screen; class Selection; class Streams; @@ -96,7 +96,7 @@ public: Clipboard *_clipboard; Conf *_conf; Events *_events; - PicList *_picList; + Pictures *_pictures; Screen *_screen; Selection *_selection; Streams *_streams; diff --git a/engines/glk/glk_api.cpp b/engines/glk/glk_api.cpp index e04040f67f..ec98ab6374 100644 --- a/engines/glk/glk_api.cpp +++ b/engines/glk/glk_api.cpp @@ -924,7 +924,7 @@ glui32 GlkAPI::glk_image_get_info(glui32 image, glui32 *width, glui32 *height) { if (!g_conf->_graphics) return false; - Picture *pic = Picture::load(image); + Picture *pic = g_vm->_pictures->load(image); if (!pic) return false; diff --git a/engines/glk/picture.cpp b/engines/glk/picture.cpp index b87b1297eb..8461983c45 100644 --- a/engines/glk/picture.cpp +++ b/engines/glk/picture.cpp @@ -21,15 +21,109 @@ */ #include "glk/picture.h" +#include "common/file.h" +#include "image/jpeg.h" +#include "image/png.h" namespace Glk { -void PicList::increment() { - // TODO +void Pictures::clear() { + for (uint idx = 0; idx < _store.size(); ++idx) { + delete _store[idx]._picture; + delete _store[idx]._scaled; + } + + _store.clear(); +} + +void Pictures::increment() { + ++_refCount; +} + +void Pictures::decrement() { + if (_refCount > 0 && --_refCount == 0) + clear(); +} + +PictureEntry *Pictures::search(uint id) { + Picture *pic; + + for (uint idx = 0; idx < _store.size(); ++idx) { + pic = _store[idx]._picture; + + if (pic && pic->_id == id) + return &_store[idx]; + } + + return nullptr; +} + +void Pictures::storeOriginal(Picture *pic) { + PictureEntry newPic; + newPic._picture = pic; + + _store.push_back(newPic); +} + +void Pictures::storeScaled(Picture *pic) { + PictureEntry *entry = search(pic->_id); + if (!entry) + return; + + delete entry->_scaled; + entry->_scaled = pic; } -void PicList::decrement() { - // TODO +void Pictures::store(Picture *pic) { + if (!pic) + return; + + if (!pic->_scaled) + storeOriginal(pic); + else + storeScaled(pic); +} + +Picture *Pictures::retrieve(uint id, bool scaled) { + Picture *pic; + + for (uint idx = 0; idx < _store.size(); ++idx) { + pic = scaled ? _store[idx]._scaled : _store[idx]._picture; + + if (pic && pic->_id == id) + return pic; + } + + return nullptr; +} + +Picture *Pictures::load(uint32 id) { + ::Image::PNGDecoder png; + ::Image::JPEGDecoder jpg; + const Graphics::Surface *img; + Picture *pic; + + // Check if the picture is already in the store + pic = retrieve(id, false); + if (pic) + return pic; + + Common::File f; + if (f.open(Common::String::format("PIC%lu.png", id))) { + png.loadStream(f); + img = png.getSurface(); + } else if (f.open(Common::String::format("PIC%lu.jpg", id))) { + jpg.loadStream(f); + img = jpg.getSurface(); + } + + pic = new Picture(); + pic->_refCount = 1; + pic->_id = id; + pic->_scaled = false; + + store(pic); + return pic; } /*--------------------------------------------------------------------------*/ @@ -40,16 +134,11 @@ void Picture::increment() { void Picture::decrement() { if (_refCount > 0 && --_refCount == 0) { - free(); + // No longer any references to this picture, so remove it delete this; } } -Picture *Picture::load(uint32 id) { - // TODO: gli_picture_load - return nullptr; -} - Picture *Picture::scale(int sx, int sy) { // TODO: gli_picture_scale return nullptr; diff --git a/engines/glk/picture.h b/engines/glk/picture.h index 3ca615b84f..ca4f9995c8 100644 --- a/engines/glk/picture.h +++ b/engines/glk/picture.h @@ -23,20 +23,15 @@ #ifndef GLK_PICTURE_H #define GLK_PICTURE_H -#include "graphics/surface.h" +#include "common/array.h" +#include "graphics/managed_surface.h" namespace Glk { -class PicList { -public: - void increment(); - - void decrement(); -}; - -struct Picture : Graphics::Surface { -public: - static Picture *load(uint32 id); +/** + * Picture/image class + */ +struct Picture : Graphics::ManagedSurface { public: int _refCount; uint32 _id; @@ -45,7 +40,7 @@ public: /** * Constructor */ - Picture() : Graphics::Surface(), _refCount(0), _id(0), _scaled(0) {} + Picture() : Graphics::ManagedSurface(), _refCount(0), _id(0), _scaled(0) {} /** * Increment reference counter @@ -68,6 +63,79 @@ public: void drawPicture(int x0, int y0, int dx0, int dy0, int dx1, int dy1); }; +/** + * Picture entry in the in-memory store + */ +struct PictureEntry { + Picture *_picture; + Picture *_scaled; + PictureEntry() : _picture(nullptr), _scaled(nullptr) {} +}; + +/** + * Pictures manager + */ +class Pictures { +private: + int _refCount; + Common::Array<PictureEntry> _store; +private: + /** + * Stores an original picture in the store + */ + void storeOriginal(Picture *pic); + + /** + * Stores a scaled picture in the store + */ + void storeScaled(Picture *pic); +public: + /** + * Constructor + */ + Pictures() : _refCount(0) {} + + /** + * Destructor + */ + ~Pictures() { clear(); } + + /** + * Clear the picture list + */ + void clear(); + + /** + * Increments the count of the number of pictures in use + */ + void increment(); + + /** + * Decrements the count of the number of pictures in use + */ + void decrement(); + + /** + * Searches for an existing picture entry + */ + PictureEntry *search(uint id); + + /** + * Stores a picture in the store + */ + void store(Picture *pic); + + /** + * Retrieves a picture from the store + */ + Picture *retrieve(uint id, bool scaled); + + /** + * Load a given picture + */ + Picture *load(uint32 id); +}; + } // End of namespace Glk #endif diff --git a/engines/glk/window_graphics.cpp b/engines/glk/window_graphics.cpp index b18e2b27e6..13e66451f7 100644 --- a/engines/glk/window_graphics.cpp +++ b/engines/glk/window_graphics.cpp @@ -96,14 +96,14 @@ void GraphicsWindow::redraw() { glui32 GraphicsWindow::drawPicture(glui32 image, glsi32 xpos, glsi32 ypos, int scale, glui32 imagewidth, glui32 imageheight) { - Picture *pic = Picture::load(image); + Picture *pic = g_vm->_pictures->load(image); glui32 hyperlink = _attr.hyper; if (!pic) return false; if (!_imageLoaded) { - g_vm->_picList->increment(); + g_vm->_pictures->increment(); _imageLoaded = true; } diff --git a/engines/glk/window_text_buffer.cpp b/engines/glk/window_text_buffer.cpp index 2a98581365..6f861fb7b3 100644 --- a/engines/glk/window_text_buffer.cpp +++ b/engines/glk/window_text_buffer.cpp @@ -274,13 +274,13 @@ glui32 TextBufferWindow::drawPicture(glui32 image, glui32 align, glui32 scaled, glui32 hyperlink; int error; - pic = Picture::load(image); + pic = g_vm->_pictures->load(image); if (!pic) return false; if (!_imageLoaded) { - g_vm->_picList->increment(); + g_vm->_pictures->increment(); _imageLoaded = true; } |