diff options
-rw-r--r-- | engines/glk/blorb.cpp | 251 | ||||
-rw-r--r-- | engines/glk/blorb.h | 86 | ||||
-rw-r--r-- | engines/glk/frotz/mem.cpp | 40 | ||||
-rw-r--r-- | engines/glk/frotz/mem.h | 1 | ||||
-rw-r--r-- | engines/glk/frotz/processor_streams.cpp | 4 | ||||
-rw-r--r-- | engines/glk/glk.cpp | 32 | ||||
-rw-r--r-- | engines/glk/glk.h | 2 | ||||
-rw-r--r-- | engines/glk/glk_api.h | 2 |
8 files changed, 211 insertions, 207 deletions
diff --git a/engines/glk/blorb.cpp b/engines/glk/blorb.cpp index ed730bfa8a..2a8ef45a85 100644 --- a/engines/glk/blorb.cpp +++ b/engines/glk/blorb.cpp @@ -54,7 +54,6 @@ struct giblorb_resdesc_struct { */ struct giblorb_map_struct { glui32 inited; ///< holds giblorb_Inited_Magic if the map structure is valid - Common::SeekableReadStream *file; uint numchunks; giblorb_chunkdesc_t *chunks; ///< list of chunk descriptors @@ -66,13 +65,68 @@ struct giblorb_map_struct { /*--------------------------------------------------------------------------*/ -giblorb_err_t Blorb::giblorb_initialize() { - _file = nullptr; - _map = nullptr; - return giblorb_err_None; +Blorb::Blorb(const Common::String &filename, InterpreterType interpType) : + Common::Archive(), _interpType(interpType), _map(nullptr) { + if (!_file.open(filename)) + error("Could not open blorb file"); + + if (create_map() != giblorb_err_None) + error("Could not parse blorb file"); +} + +Blorb::~Blorb() { + for (uint ix = 0; ix < _map->numchunks; ix++) { + giblorb_chunkdesc_t *chu = &(_map->chunks[ix]); + if (chu->ptr) { + delete chu->ptr; + chu->ptr = nullptr; + } + } + + if (_map->chunks) { + delete[] _map->chunks; + _map->chunks = nullptr; + } + + _map->numchunks = 0; + + if (_map->resources) { + delete[] _map->resources; + _map->resources = nullptr; + } + + if (_map->ressorted) { + delete[] _map->ressorted; + _map->ressorted = nullptr; + } + + _map->numresources = 0; + _map->inited = 0; + + delete _map; +} + +bool Blorb::hasFile(const Common::String &name) const { + return false; +} + +int Blorb::listMatchingMembers(Common::ArchiveMemberList &list, const Common::String &pattern) const { + return 0; +} + +int Blorb::listMembers(Common::ArchiveMemberList &list) const { + return 0; } -giblorb_err_t Blorb::giblorb_create_map(Common::SeekableReadStream *file, giblorb_map_t **newmap) { +const Common::ArchiveMemberPtr Blorb::getMember(const Common::String &name) const { + return Common::ArchiveMemberPtr(); +} + +Common::SeekableReadStream *Blorb::createReadStreamForMember(const Common::String &name) const { + return nullptr; +} + +giblorb_err_t Blorb::create_map() { giblorb_err_t err; giblorb_map_t *map; glui32 readlen; @@ -81,21 +135,12 @@ giblorb_err_t Blorb::giblorb_create_map(Common::SeekableReadStream *file, giblor int chunks_size, numchunks; char buffer[16]; - *newmap = nullptr; - - if (!_libInited) { - err = giblorb_initialize(); - if (err) - return err; - _libInited = true; - } - - /* First, chew through the file and index the chunks. */ - file->seek(0); + // First, chew through the file and index the chunks + _file.seek(0); - readlen = file->read(buffer, 12); + readlen = _file.read(buffer, 12); if (readlen != 12) - return giblorb_err_Read; + return giblorb_err_Format; if (READ_BE_INT32(buffer + 0) != giblorb_ID_FORM) return giblorb_err_Format; @@ -114,9 +159,9 @@ giblorb_err_t Blorb::giblorb_create_map(Common::SeekableReadStream *file, giblor int chunum; giblorb_chunkdesc_t *chu; - file->seek(nextpos); + _file.seek(nextpos); - readlen = file->read(buffer, 8); + readlen = _file.read(buffer, 8); if (readlen != 8) { delete[] chunks; return giblorb_err_Read; @@ -158,34 +203,29 @@ giblorb_err_t Blorb::giblorb_create_map(Common::SeekableReadStream *file, giblor // The basic IFF structure seems to be ok, and we have a list of chunks. // Now we allocate the map structure itself. - map = new giblorb_map_t(); - if (!map) { + _map = new giblorb_map_t(); + if (!_map) { delete[] chunks; return giblorb_err_Alloc; } - map->inited = giblorb_Inited_Magic; - map->file = file; - map->chunks = chunks; - map->numchunks = numchunks; - map->resources = nullptr; - map->ressorted = nullptr; - map->numresources = 0; + _map->inited = giblorb_Inited_Magic; + _map->chunks = chunks; + _map->numchunks = numchunks; + _map->resources = nullptr; + _map->ressorted = nullptr; + _map->numresources = 0; // Now we do everything else involved in loading the Blorb file, // such as building resource lists. - err = giblorb_initialize_map(map); - if (err) { - giblorb_destroy_map(map); + err = initialize_map(); + if (err) return err; - } - *newmap = map; return giblorb_err_None; } - -giblorb_err_t Blorb::giblorb_initialize_map(giblorb_map_t *map) { +giblorb_err_t Blorb::initialize_map() { // It is important that the map structure be kept valid during this function. // If this returns an error, giblorb_destroy_map() will be called. uint ix, jx; @@ -196,8 +236,8 @@ giblorb_err_t Blorb::giblorb_initialize_map(giblorb_map_t *map) { glui32 numres; int gotindex = false; - for (ix = 0; ix<map->numchunks; ix++) { - giblorb_chunkdesc_t *chu = &map->chunks[ix]; + for (ix = 0; ix < _map->numchunks; ix++) { + giblorb_chunkdesc_t *chu = &_map->chunks[ix]; switch (chu->type) { case giblorb_ID_RIdx: @@ -205,7 +245,7 @@ giblorb_err_t Blorb::giblorb_initialize_map(giblorb_map_t *map) { if (gotindex) return giblorb_err_Format; // duplicate index chunk - err = giblorb_load_chunk_by_number(map, giblorb_method_Memory, &chunkres, ix); + err = load_chunk_by_number(giblorb_method_Memory, &chunkres, ix); if (err) return err; @@ -238,12 +278,12 @@ giblorb_err_t Blorb::giblorb_initialize_map(giblorb_map_t *map) { res->resnum = READ_BE_INT32(ptr + jx * 12 + 8); respos = READ_BE_INT32(ptr + jx * 12 + 12); - while (ix2 < map->numchunks - && map->chunks[ix2].startpos < respos) + while (ix2 < _map->numchunks + && _map->chunks[ix2].startpos < respos) ix2++; - if (ix2 >= map->numchunks - || map->chunks[ix2].startpos != respos) { + if (ix2 >= _map->numchunks + || _map->chunks[ix2].startpos != respos) { delete[] resources; delete[] ressorted; return giblorb_err_Format; // start pos does not match a real chunk @@ -254,16 +294,16 @@ giblorb_err_t Blorb::giblorb_initialize_map(giblorb_map_t *map) { ressorted[jx] = res; } - // Sort a resource list (actually a list of pointers to structures in map->resources.) + // Sort a resource list (actually a list of pointers to structures in _map->resources.) // This makes it easy to find resources by usage and resource number. - giblorb_qsort(ressorted, numres); + qsort(ressorted, numres); - map->numresources = numres; - map->resources = resources; - map->ressorted = ressorted; + _map->numresources = numres; + _map->resources = resources; + _map->ressorted = ressorted; } - giblorb_unload_chunk(map, ix); + unload_chunk(ix); gotindex = true; break; } @@ -272,7 +312,7 @@ giblorb_err_t Blorb::giblorb_initialize_map(giblorb_map_t *map) { return giblorb_err_None; } -void Blorb::giblorb_qsort(giblorb_resdesc_t **list, size_t len) { +void Blorb::qsort(giblorb_resdesc_t **list, size_t len) { int ix, jx, res; giblorb_resdesc_t *tmpptr, *pivot; @@ -306,12 +346,12 @@ void Blorb::giblorb_qsort(giblorb_resdesc_t **list, size_t len) { } ix++; // Sort the halves. - giblorb_qsort(list + 0, ix); - giblorb_qsort(list + ix, len - ix); + qsort(list + 0, ix); + qsort(list + ix, len - ix); } } -giblorb_resdesc_t *Blorb::giblorb_bsearch(giblorb_resdesc_t *sample, +giblorb_resdesc_t *Blorb::bsearch(giblorb_resdesc_t *sample, giblorb_resdesc_t **list, int len) { int top, bot, val, res; @@ -345,71 +385,31 @@ int Blorb::sortsplot(giblorb_resdesc_t *v1, giblorb_resdesc_t *v2) { return 0; } -giblorb_err_t Blorb::giblorb_destroy_map(giblorb_map_t *map) { - if (!map || !map->chunks || map->inited != giblorb_Inited_Magic) - return giblorb_err_NotAMap; - - for (uint ix = 0; ix<map->numchunks; ix++) { - giblorb_chunkdesc_t *chu = &(map->chunks[ix]); - if (chu->ptr) { - delete chu->ptr; - chu->ptr = nullptr; - } - } - - if (map->chunks) { - delete[] map->chunks; - map->chunks = nullptr; - } - - map->numchunks = 0; - - if (map->resources) { - delete[] map->resources; - map->resources = nullptr; - } - - if (map->ressorted) { - delete[] map->ressorted; - map->ressorted = nullptr; - } - - map->numresources = 0; - map->file = nullptr; - map->inited = 0; - - delete map; - - return giblorb_err_None; -} - -giblorb_err_t Blorb::giblorb_load_chunk_by_type(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 chunktype, glui32 count) { +giblorb_err_t Blorb::load_chunk_by_type(glui32 method, giblorb_result_t *res, glui32 chunktype, glui32 count) { uint ix; - for (ix = 0; ix < map->numchunks; ix++) { - if (map->chunks[ix].type == chunktype) { + for (ix = 0; ix < _map->numchunks; ix++) { + if (_map->chunks[ix].type == chunktype) { if (count == 0) break; count--; } } - if (ix >= map->numchunks) { + if (ix >= _map->numchunks) { return giblorb_err_NotFound; } - return giblorb_load_chunk_by_number(map, method, res, ix); + return load_chunk_by_number(method, res, ix); } -giblorb_err_t Blorb::giblorb_load_chunk_by_number(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 chunknum) { +giblorb_err_t Blorb::load_chunk_by_number(glui32 method, giblorb_result_t *res, glui32 chunknum) { giblorb_chunkdesc_t *chu; - if (chunknum >= map->numchunks) + if (chunknum >= _map->numchunks) return giblorb_err_NotFound; - chu = &(map->chunks[chunknum]); + chu = &(_map->chunks[chunknum]); switch (method) { case giblorb_method_DontLoad: @@ -428,9 +428,9 @@ giblorb_err_t Blorb::giblorb_load_chunk_by_number(giblorb_map_t *map, if (!dat) return giblorb_err_Alloc; - map->file->seek(chu->datpos); + _file.seek(chu->datpos); - readlen = map->file->read(dat, chu->len); + readlen = _file.read(dat, chu->len); if (readlen != chu->len) return giblorb_err_Read; @@ -448,13 +448,13 @@ giblorb_err_t Blorb::giblorb_load_chunk_by_number(giblorb_map_t *map, return giblorb_err_None; } -giblorb_err_t Blorb::giblorb_unload_chunk(giblorb_map_t *map, glui32 chunknum) { +giblorb_err_t Blorb::unload_chunk(glui32 chunknum) { giblorb_chunkdesc_t *chu; - if (chunknum >= map->numchunks) + if (chunknum >= _map->numchunks) return giblorb_err_NotFound; - chu = &(map->chunks[chunknum]); + chu = &(_map->chunks[chunknum]); if (chu->ptr) { delete chu->ptr; @@ -464,24 +464,22 @@ giblorb_err_t Blorb::giblorb_unload_chunk(giblorb_map_t *map, glui32 chunknum) { return giblorb_err_None; } -giblorb_err_t Blorb::giblorb_load_resource(giblorb_map_t *map, glui32 method, - giblorb_result_t *res, glui32 usage, glui32 resnum) { +giblorb_err_t Blorb::load_resource(glui32 method, giblorb_result_t *res, glui32 usage, glui32 resnum) { giblorb_resdesc_t sample; giblorb_resdesc_t *found; sample.usage = usage; sample.resnum = resnum; - found = giblorb_bsearch(&sample, map->ressorted, map->numresources); + found = bsearch(&sample, _map->ressorted, _map->numresources); if (!found) return giblorb_err_NotFound; - return giblorb_load_chunk_by_number(map, method, res, found->chunknum); + return load_chunk_by_number(method, res, found->chunknum); } -giblorb_err_t Blorb::giblorb_count_resources(giblorb_map_t *map, - glui32 usage, glui32 *num, glui32 *min, glui32 *max) { +giblorb_err_t Blorb::count_resources(glui32 usage, glui32 *num, glui32 *min, glui32 *max) { int ix; int count; glui32 val; @@ -491,9 +489,9 @@ giblorb_err_t Blorb::giblorb_count_resources(giblorb_map_t *map, minval = 0; maxval = 0; - for (ix = 0; ix<map->numresources; ix++) { - if (map->resources[ix].usage == usage) { - val = map->resources[ix].resnum; + for (ix = 0; ix<_map->numresources; ix++) { + if (_map->resources[ix].usage == usage) { + val = _map->resources[ix].resnum; if (count == 0) { count++; minval = val; @@ -519,25 +517,4 @@ giblorb_err_t Blorb::giblorb_count_resources(giblorb_map_t *map, return giblorb_err_None; } -giblorb_err_t Blorb::giblorb_set_resource_map(Common::SeekableReadStream *file) { - giblorb_err_t err; - - err = giblorb_create_map(file, &_map); - if (err) { - _map = nullptr; - return err; - } - - _file = file; - return giblorb_err_None; -} - -giblorb_map_t *Blorb::giblorb_get_resource_map(void) { - return _map; -} - -bool Blorb::giblorb_is_resource_map(void) const { - return _map != nullptr; -} - } // End of namespace Glk diff --git a/engines/glk/blorb.h b/engines/glk/blorb.h index ae9c5032fc..97fd520fcc 100644 --- a/engines/glk/blorb.h +++ b/engines/glk/blorb.h @@ -25,10 +25,11 @@ #include "glk/glk_types.h" #include "glk/streams.h" +#include "common/archive.h" +#include "common/array.h" namespace Glk { - /** * Error type */ @@ -101,46 +102,81 @@ typedef struct giblorb_result_struct { typedef struct giblorb_resdesc_struct giblorb_resdesc_t; -class Blorb { +/** + * Blorb file manager + */ +class Blorb : public Common::Archive { private: - bool _libInited; - Common::SeekableReadStream *_file; + Common::File _file; + InterpreterType _interpType; giblorb_map_t *_map; private: /** - * Initializes Blorb + * Parses the Blorb file index to load in a list of the chunks */ - giblorb_err_t giblorb_initialize(); + giblorb_err_t create_map(); - giblorb_err_t giblorb_initialize_map(giblorb_map_t *map); - void giblorb_qsort(giblorb_resdesc_t **list, size_t len); - giblorb_resdesc_t *giblorb_bsearch(giblorb_resdesc_t *sample, - giblorb_resdesc_t **list, int len); + giblorb_err_t initialize_map(); + void qsort(giblorb_resdesc_t **list, size_t len); + giblorb_resdesc_t *bsearch(giblorb_resdesc_t *sample, giblorb_resdesc_t **list, int len); int sortsplot(giblorb_resdesc_t *v1, giblorb_resdesc_t *v2); public: /** * Constructor */ - Blorb() : _libInited(false), _file(nullptr), _map(nullptr) {} + Blorb(const Common::String &filename, InterpreterType interpType); - giblorb_err_t giblorb_set_resource_map(Common::SeekableReadStream *file); - giblorb_map_t *giblorb_get_resource_map(void); - bool giblorb_is_resource_map(void) const; + /** + * Destructor + */ + ~Blorb(); + /** + * Check if a member with the given name is present in the Archive. + * Patterns are not allowed, as this is meant to be a quick File::exists() + * replacement. + */ + virtual bool hasFile(const Common::String &name) const override; - giblorb_err_t giblorb_create_map(Common::SeekableReadStream *file, giblorb_map_t **newmap); - giblorb_err_t giblorb_destroy_map(giblorb_map_t *map); + /** + * Add all members of the Archive matching the specified pattern to list. + * Must only append to list, and not remove elements from it. + * + * @return the number of members added to list + */ + virtual int listMatchingMembers(Common::ArchiveMemberList &list, const Common::String &pattern) const override; + + /** + * Add all members of the Archive to list. + * Must only append to list, and not remove elements from it. + * + * @return the number of names added to list + */ + virtual int listMembers(Common::ArchiveMemberList &list) const override; + + /** + * Returns a ArchiveMember representation of the given file. + */ + virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const override; + + /** + * Create a stream bound to a member with the specified name in the + * archive. If no member with this name exists, 0 is returned. + * @return the newly created input stream + */ + virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override; +public: + /** + * Get a pointer to the Blorb's resource map + */ + giblorb_map_t *get_resource_map() const { return _map; } - giblorb_err_t giblorb_load_chunk_by_type(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 chunktype, glui32 count); - giblorb_err_t giblorb_load_chunk_by_number(giblorb_map_t *map, - glui32 method, giblorb_result_t *res, glui32 chunknum); - giblorb_err_t giblorb_unload_chunk(giblorb_map_t *map, glui32 chunknum); + giblorb_err_t load_chunk_by_type(glui32 method, giblorb_result_t *res, glui32 chunktype, glui32 count); + giblorb_err_t load_chunk_by_number(glui32 method, giblorb_result_t *res, glui32 chunknum); + giblorb_err_t unload_chunk(glui32 chunknum); - giblorb_err_t giblorb_load_resource(giblorb_map_t *map, glui32 method, - giblorb_result_t *res, glui32 usage, glui32 resnum); - giblorb_err_t giblorb_count_resources(giblorb_map_t *map, - glui32 usage, glui32 *num, glui32 *min, glui32 *max); + giblorb_err_t load_resource(glui32 method, giblorb_result_t *res, glui32 usage, glui32 resnum); + giblorb_err_t count_resources(glui32 usage, glui32 *num, glui32 *min, glui32 *max); }; } // End of namespace Glk diff --git a/engines/glk/frotz/mem.cpp b/engines/glk/frotz/mem.cpp index 12e860add2..bec30b00f7 100644 --- a/engines/glk/frotz/mem.cpp +++ b/engines/glk/frotz/mem.cpp @@ -28,10 +28,9 @@ namespace Glk { namespace Frotz { -Mem::Mem() : story_fp(nullptr), blorb_ofs(0), blorb_len(0), story_size(0), - first_undo(nullptr), last_undo(nullptr), curr_undo(nullptr), - undo_mem(nullptr), prev_zmp(nullptr), undo_diff(nullptr), - undo_count(0), reserve_mem(0) { +Mem::Mem() : story_fp(nullptr), story_size(0), first_undo(nullptr), last_undo(nullptr), + curr_undo(nullptr), undo_mem(nullptr), zmp(nullptr), prev_zmp(nullptr), + undo_diff(nullptr), undo_count(0), reserve_mem(0) { } void Mem::initialize() { @@ -60,32 +59,7 @@ void Mem::initialize() { } void Mem::initializeStoryFile() { - Common::SeekableReadStream *f = story_fp; - giblorb_map_t *map; - giblorb_result_t res; - uint32 magic; - - magic = f->readUint32BE(); - - if (magic == MKTAG('F', 'O', 'R', 'M')) { - if (g_vm->giblorb_set_resource_map(f)) - error("This Blorb file seems to be invalid."); - - map = g_vm->giblorb_get_resource_map(); - - if (g_vm->giblorb_load_resource(map, giblorb_method_FilePos, &res, giblorb_ID_Exec, 0)) - error("This Blorb file does not contain an executable chunk."); - if (res.chunktype != MKTAG('Z', 'C', 'O', 'D')) - error("This Blorb file contains an executable chunk, but it is not a Z-code file."); - - blorb_ofs = res.data.startpos; - blorb_len = res.length; - } else { - blorb_ofs = 0; - blorb_len = f->size(); - } - - if (blorb_len < 64) + if (story_fp->size() < 64) error("This file is too small to be a Z-code file."); } @@ -115,7 +89,7 @@ void Mem::initializeUndo() { void Mem::loadGameHeader() { // Load header zmp = new byte[64]; - story_fp->seek(blorb_ofs); + story_fp->seek(0); story_fp->read(zmp, 64); Common::MemoryReadStream h(zmp, 64); @@ -131,7 +105,7 @@ void Mem::loadGameHeader() { story_size *= 2; } else { // Some old games lack the file size entry - story_size = blorb_len; + story_size = story_fp->size(); } } @@ -254,8 +228,6 @@ void Mem::free_undo(int count) { void Mem::reset_memory() { story_fp = nullptr; - blorb_ofs = 0; - blorb_len = 0; if (undo_mem) { free_undo(undo_count); diff --git a/engines/glk/frotz/mem.h b/engines/glk/frotz/mem.h index d973890605..a632bc6e63 100644 --- a/engines/glk/frotz/mem.h +++ b/engines/glk/frotz/mem.h @@ -57,7 +57,6 @@ typedef undo_struct undo_t; class Mem : public Header, public virtual UserOptions { protected: Common::SeekableReadStream *story_fp; - uint blorb_ofs, blorb_len; uint story_size; byte *pcp; byte *zmp; diff --git a/engines/glk/frotz/processor_streams.cpp b/engines/glk/frotz/processor_streams.cpp index cbef38aaa6..095ef247fd 100644 --- a/engines/glk/frotz/processor_streams.cpp +++ b/engines/glk/frotz/processor_streams.cpp @@ -519,7 +519,7 @@ void Processor::z_restart() { seed_random(0); if (!first_restart) { - story_fp->seek(blorb_ofs); + story_fp->seek(0); if (story_fp->read(zmp, h_dynamic_size) != h_dynamic_size) error("Story file read error"); @@ -599,7 +599,7 @@ void Processor::z_verify() { zword checksum = 0; // Sum all bytes in story file except header bytes - story_fp->seek(blorb_ofs + 64); + story_fp->seek(64); for (uint i = 64; i < story_size; i++) checksum += story_fp->readByte(); diff --git a/engines/glk/glk.cpp b/engines/glk/glk.cpp index 0e44f04e51..c2a8264750 100644 --- a/engines/glk/glk.cpp +++ b/engines/glk/glk.cpp @@ -29,6 +29,7 @@ #include "graphics/scaler.h" #include "graphics/thumbnail.h" #include "glk/glk.h" +#include "glk/blorb.h" #include "glk/conf.h" #include "glk/events.h" #include "glk/picture.h" @@ -42,14 +43,16 @@ namespace Glk { GlkEngine *g_vm; GlkEngine::GlkEngine(OSystem *syst, const GlkGameDescription &gameDesc) : - _gameDescription(gameDesc), Engine(syst), _random("Glk"), _clipboard(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) { + _gameDescription(gameDesc), Engine(syst), _random("Glk"), _blorb(nullptr), + _clipboard(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; } GlkEngine::~GlkEngine() { + delete _blorb; delete _clipboard; delete _conf; delete _events; @@ -96,11 +99,26 @@ void GlkEngine::initGraphicsMode() { } Common::Error GlkEngine::run() { + Common::File f; + Common::String filename = getFilename(); + if (!Common::File::exists(filename)) + return Common::kNoGameDataFoundError; + initialize(); - Common::File f; - if (f.open(getFilename())) - runGame(&f); + if (filename.hasSuffixIgnoreCase(".blorb") || filename.hasSuffixIgnoreCase(".zblorb")) { + // Blorb archive + _blorb = new Blorb(filename, getInterpreterType()); + SearchMan.add("blorb", _blorb, 99, false); + + if (!f.open("EXEC", *_blorb)) + return Common::kNoGameDataFoundError; + } else { + if (!f.open(filename)) + return Common::kNoGameDataFoundError; + } + + runGame(&f); return Common::kNoError; } diff --git a/engines/glk/glk.h b/engines/glk/glk.h index 50722ae8dc..af9a42ba43 100644 --- a/engines/glk/glk.h +++ b/engines/glk/glk.h @@ -35,6 +35,7 @@ namespace Glk { class Clipboard; +class Blorb; class Conf; class Events; class Pictures; @@ -93,6 +94,7 @@ protected: */ virtual void runGame(Common::SeekableReadStream *gameFile) = 0; public: + Blorb *_blorb; Clipboard *_clipboard; Conf *_conf; Events *_events; diff --git a/engines/glk/glk_api.h b/engines/glk/glk_api.h index 400f3c08cd..b625f69bf7 100644 --- a/engines/glk/glk_api.h +++ b/engines/glk/glk_api.h @@ -34,7 +34,7 @@ namespace Glk { /** * Implements the GLK interface */ -class GlkAPI : public GlkEngine, public Blorb { +class GlkAPI : public GlkEngine { private: bool _gliFirstEvent; unsigned char _charTolowerTable[256]; |