aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2018-11-18 20:29:14 -0800
committerPaul Gilbert2018-12-08 19:05:59 -0800
commitbd86fd7bbf19324e06834ee8f2e08e7e0df02e14 (patch)
tree825c11b8f6f7c1f51c4e3cfd8954cda1502f57be /engines
parent0f0b8ae3b72d066259332a728eab1edc760de5df (diff)
downloadscummvm-rg350-bd86fd7bbf19324e06834ee8f2e08e7e0df02e14.tar.gz
scummvm-rg350-bd86fd7bbf19324e06834ee8f2e08e7e0df02e14.tar.bz2
scummvm-rg350-bd86fd7bbf19324e06834ee8f2e08e7e0df02e14.zip
GLK: Implementing picture loading
Diffstat (limited to 'engines')
-rw-r--r--engines/glk/glk.cpp6
-rw-r--r--engines/glk/glk.h4
-rw-r--r--engines/glk/glk_api.cpp2
-rw-r--r--engines/glk/picture.cpp109
-rw-r--r--engines/glk/picture.h92
-rw-r--r--engines/glk/window_graphics.cpp4
-rw-r--r--engines/glk/window_text_buffer.cpp4
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;
}