aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/gargoyle/frotz/frotz.cpp3
-rw-r--r--engines/gargoyle/frotz/glk_interface.cpp2
-rw-r--r--engines/gargoyle/frotz/glk_interface.h2
-rw-r--r--engines/gargoyle/frotz/mem.cpp29
-rw-r--r--engines/gargoyle/frotz/mem.h27
-rw-r--r--engines/gargoyle/frotz/processor.cpp2
-rw-r--r--engines/gargoyle/frotz/processor.h2
7 files changed, 61 insertions, 6 deletions
diff --git a/engines/gargoyle/frotz/frotz.cpp b/engines/gargoyle/frotz/frotz.cpp
index df6d7364ac..5c861890bf 100644
--- a/engines/gargoyle/frotz/frotz.cpp
+++ b/engines/gargoyle/frotz/frotz.cpp
@@ -74,6 +74,9 @@ void Frotz::initialize() {
// Call process initialization
Processor::initialize();
+
+ // Restart the game
+ z_restart();
}
Common::Error Frotz::loadGameState(int slot) {
diff --git a/engines/gargoyle/frotz/glk_interface.cpp b/engines/gargoyle/frotz/glk_interface.cpp
index f60ecc5009..13d0a562b5 100644
--- a/engines/gargoyle/frotz/glk_interface.cpp
+++ b/engines/gargoyle/frotz/glk_interface.cpp
@@ -26,7 +26,7 @@ namespace Gargoyle {
namespace Frotz {
GlkInterface::GlkInterface(OSystem *syst, const GargoyleGameDescription *gameDesc) :
- Glk(syst, gameDesc), UserOptions(),
+ Glk(syst, gameDesc),
oldstyle(0), curstyle(0), cury(1), curx(1), fixforced(0),
curr_fg(-2), curr_bg(-2), curr_font(1), prev_font(1), temp_font(0),
curr_status_ht(0), mach_status_ht(0), gos_status(nullptr), gos_upper(nullptr),
diff --git a/engines/gargoyle/frotz/glk_interface.h b/engines/gargoyle/frotz/glk_interface.h
index 1d30364683..f02fa0dd8c 100644
--- a/engines/gargoyle/frotz/glk_interface.h
+++ b/engines/gargoyle/frotz/glk_interface.h
@@ -40,7 +40,7 @@ enum SoundEffect {
* Implements an intermediate interface on top of the GLK layer, providing screen
* and sound effect handling
*/
-class GlkInterface : public Glk, public UserOptions, public virtual Mem {
+class GlkInterface : public Glk, public virtual UserOptions, public virtual Mem {
public:
zchar statusline[256];
int oldstyle;
diff --git a/engines/gargoyle/frotz/mem.cpp b/engines/gargoyle/frotz/mem.cpp
index cb5a73b8d1..d9ff53d449 100644
--- a/engines/gargoyle/frotz/mem.cpp
+++ b/engines/gargoyle/frotz/mem.cpp
@@ -112,11 +112,15 @@ void Header::loadHeader(Common::SeekableReadStream &f) {
/*--------------------------------------------------------------------------*/
-Mem::Mem() : story_fp(nullptr), blorb_ofs(0), blorb_len(0), story_size(0) {
+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) {
}
void Mem::initialize() {
initializeStoryFile();
+ initializeUndo();
loadGameHeader();
// Allocate memory for story data
@@ -173,6 +177,29 @@ void Mem::initializeStoryFile() {
error("This file is too small to be a Z-code file.");
}
+void Mem::initializeUndo() {
+ void *reserved = nullptr;
+
+ if (reserve_mem != 0) {
+ if ((reserved = malloc(reserve_mem)) == NULL)
+ return;
+ }
+
+ // Allocate h_dynamic_size bytes for previous dynamic zmp state
+ // + 1.5 h_dynamic_size for Quetzal diff + 2.
+ undo_mem = new zbyte[(h_dynamic_size * 5) / 2 + 2];
+ if (undo_mem != nullptr) {
+ prev_zmp = undo_mem;
+ undo_diff = undo_mem + h_dynamic_size;
+ memcpy(prev_zmp, zmp, h_dynamic_size);
+ } else {
+ _undo_slots = 0;
+ }
+
+ if (reserve_mem != 0)
+ delete reserved;
+}
+
void Mem::loadGameHeader() {
// Load header
zmp = new byte[64];
diff --git a/engines/gargoyle/frotz/mem.h b/engines/gargoyle/frotz/mem.h
index 55cc4dc6fe..e12c062ff8 100644
--- a/engines/gargoyle/frotz/mem.h
+++ b/engines/gargoyle/frotz/mem.h
@@ -82,6 +82,21 @@ enum {
};
/**
+ * Stores undo information
+ */
+struct undo_struct {
+ undo_struct *next;
+ undo_struct *prev;
+ long pc;
+ long diff_size;
+ zword frame_count;
+ zword stack_size;
+ zword frame_offset;
+ // undo diff and stack data follow
+};
+typedef undo_struct undo_t;
+
+/**
* Story file header data
*/
struct Header {
@@ -160,13 +175,18 @@ public:
void loadHeader(Common::SeekableReadStream &f);
};
-class Mem : public Header {
+class Mem : public Header, public virtual UserOptions {
protected:
Common::SeekableReadStream *story_fp;
uint blorb_ofs, blorb_len;
uint story_size;
byte *pcp;
byte *zmp;
+
+ undo_t *first_undo, *last_undo, *curr_undo;
+ zbyte *undo_mem, *prev_zmp, *undo_diff;
+ int undo_count;
+ int reserve_mem;
private:
/**
* Handles setting the story file, parsing it if it's a Blorb file
@@ -174,6 +194,11 @@ private:
void initializeStoryFile();
/**
+ * Setup undo data
+ */
+ void initializeUndo();
+
+ /**
* Handles loading the game header
*/
void loadGameHeader();
diff --git a/engines/gargoyle/frotz/processor.cpp b/engines/gargoyle/frotz/processor.cpp
index 20fb387b74..721f64b4bf 100644
--- a/engines/gargoyle/frotz/processor.cpp
+++ b/engines/gargoyle/frotz/processor.cpp
@@ -132,7 +132,7 @@ Opcode Processor::ext_opcodes[64] = {
};
Processor::Processor(OSystem *syst, const GargoyleGameDescription *gameDesc) :
- GlkInterface(syst, gameDesc), Mem(), Errors(),
+ GlkInterface(syst, gameDesc), Errors(),
_finished(0), _sp(nullptr), _fp(nullptr), _frameCount(0),
zargc(0), _decoded(nullptr), _encoded(nullptr), _resolution(0),
_randomInterval(0), _randomCtr(0), first_restart(true) {
diff --git a/engines/gargoyle/frotz/processor.h b/engines/gargoyle/frotz/processor.h
index a11fa1b966..77192b4f6a 100644
--- a/engines/gargoyle/frotz/processor.h
+++ b/engines/gargoyle/frotz/processor.h
@@ -412,7 +412,7 @@ private:
zchar unicode_tolower(zchar c);
/**@}*/
-private:
+protected:
/**
* \defgroup General Opcode methods
* @{