1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GLK_FROTZ_MEM
24 #define GLK_FROTZ_MEM
25 
26 #include "glk/frotz/frotz_types.h"
27 #include "glk/frotz/config.h"
28 
29 namespace Glk {
30 namespace Frotz {
31 
32 #define SET_WORD(addr,v)  zmp[addr] = hi(v); zmp[addr+1] = lo(v)
33 #define LOW_WORD(addr,v)  v = READ_BE_UINT16(&zmp[addr])
34 #define HIGH_WORD(addr,v) v = READ_BE_UINT16(&zmp[addr])
35 #define HIGH_LONG(addr,v) v = READ_BE_UINT32(&zmp[addr])
36 #define SET_BYTE(addr,v)   zmp[addr] = v
37 #define LOW_BYTE(addr,v)   v = zmp[addr]
38 
39 typedef uint offset_t;
40 
41 /**
42  * Stores undo information
43  */
44 struct undo_struct {
45 	undo_struct *next;
46 	undo_struct *prev;
47 	offset_t pc;
48 	long diff_size;
49 	zword frame_count;
50 	zword stack_size;
51 	zword frame_offset;
52 	// undo diff and stack data follow
53 };
54 typedef undo_struct undo_t;
55 
56 /**
57  * Handles the memory, header, and user options
58  */
59 class Mem : public Header, public virtual UserOptions {
60 protected:
61 	Common::SeekableReadStream *story_fp;
62 	uint story_size;
63 	byte *pcp;
64 	byte *zmp;
65 
66 	undo_t *first_undo, *last_undo, *curr_undo;
67 	zbyte *undo_mem, *prev_zmp, *undo_diff;
68 	int undo_count;
69 	int reserve_mem;
70 private:
71 	/**
72 	 * Handles setting the story file, parsing it if it's a Blorb file
73 	 */
74 	void initializeStoryFile();
75 
76 	/**
77 	 * Handles loading the game header
78 	 */
79 	void loadGameHeader();
80 
81 	/**
82 	 * Initializes memory and loads the story data
83 	 */
84 	void loadMemory();
85 
86 	/**
87 	 * Setup undo data
88 	 */
89 	void initializeUndo();
90 protected:
91 	/**
92 	 * Read a value from the header extension (former mouse table).
93 	 */
94 	zword get_header_extension(int entry);
95 
96 	/**
97 	 * Set an entry in the header extension (former mouse table).
98 	 */
99 	void set_header_extension(int entry, zword val);
100 
101 	/**
102 	 * Set all header fields which hold information about the interpreter.
103 	 */
104 	void restart_header();
105 
106 	/**
107 	 * Write a byte value to the dynamic Z-machine memory.
108 	 */
109 	void storeb(zword addr, zbyte value);
110 
111 	/**
112 	 * Write a word value to the dynamic Z-machine memory.
113 	 */
114 	void storew(zword addr, zword value);
115 
116 	/**
117 	 * Free count undo blocks from the beginning of the undo list
118 	 */
119 	void free_undo(int count);
120 
121 	/**
122 	 * Generates a runtime error
123 	 */
124 	virtual void runtimeError(ErrorCode errNum) = 0;
125 
126 	/**
127 	 * Called when the flags are changed
128 	 */
129 	virtual void flagsChanged(zbyte value) = 0;
130 
131 	/**
132 	 * Close the story file and deallocate memory.
133 	 */
134 	void reset_memory();
135 
136 	/**
137 	 * Set diff to a Quetzal-like difference between a and b,
138 	 * copying a to b as we go.  It is assumed that diff points to a
139 	 * buffer which is large enough to hold the diff.
140 	 * mem_size is the number of bytes to compare.
141 	 * Returns the number of bytes copied to diff.
142 	 *
143 	 */
144 	long mem_diff(zbyte *a, zbyte *b, zword mem_size, zbyte *diff);
145 
146 	/**
147 	 * Applies a quetzal-like diff to dest
148 	 */
149 	void mem_undiff(zbyte *diff, long diff_length, zbyte *dest);
150 public:
151 	/**
152 	 * Constructor
153 	 */
154 	Mem();
155 
156 	/**
157 	 * Destructor
158 	 */
~Mem()159 	virtual ~Mem() {}
160 
161 	/**
162 	 * Initialize
163 	 */
164 	void initialize();
165 };
166 
167 } // End of namespace Frotz
168 } // End of namespace Glk
169 
170 #endif
171