ScummVM API documentation
uc_stack.h
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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (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, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef ULTIMA8_USECODE_UCSTACK_H
23#define ULTIMA8_USECODE_UCSTACK_H
24
25#include "common/scummsys.h"
26
27namespace Common {
28class ReadStream;
29class WriteStream;
30}
31
32namespace Ultima {
33namespace Ultima8 {
34
35// A little-endian stack for use with usecode
37protected:
38 uint8 *_buf;
39 uint8 *_bufPtr;
40 uint32 _size;
41public:
42
43 BaseUCStack(uint32 len, uint8 *b) : _buf(b), _size(len) {
44 // stack grows downward, so start at the end of the buffer
45 _bufPtr = _buf + _size;
46 }
47 virtual ~BaseUCStack() { }
48
49 inline uint32 getSize() const {
50 return _size;
51 }
52
53 inline uint32 stacksize() const {
54 return _size - (_bufPtr - _buf);
55 }
56
57 inline void addSP(const int32 offset) {
58 _bufPtr += offset;
59 }
60
61 inline unsigned int getSP() const {
62 return static_cast<unsigned int>(_bufPtr - _buf);
63 }
64
65 inline void setSP(unsigned int pos) {
66 _bufPtr = _buf + pos;
67 }
68
69 //
70 // Push values to the stack
71 //
72
73 inline void push1(uint8 val) {
74 _bufPtr--;
75 _bufPtr[0] = val;
76 }
77
78 inline void push2(uint16 val) {
79 _bufPtr -= 2;
80 _bufPtr[0] = static_cast<uint8>(val & 0xFF);
81 _bufPtr[1] = static_cast<uint8>((val >> 8) & 0xFF);
82 }
83 inline void push4(uint32 val) {
84 _bufPtr -= 4;
85 _bufPtr[0] = static_cast<uint8>(val & 0xFF);
86 _bufPtr[1] = static_cast<uint8>((val >> 8) & 0xFF);
87 _bufPtr[2] = static_cast<uint8>((val >> 16) & 0xFF);
88 _bufPtr[3] = static_cast<uint8>((val >> 24) & 0xFF);
89 }
90 // Push an arbitrary number of bytes of 0
91 inline void push0(const uint32 count) {
92 _bufPtr -= count;
93 memset(_bufPtr, 0, count);
94 }
95 // Push an arbitrary number of bytes
96 inline void push(const uint8 *in, const uint32 count) {
97 _bufPtr -= count;
98 memcpy(_bufPtr, in, count);
99 }
100
101 //
102 // Pop values from the stack
103 //
104
105 inline uint16 pop2() {
106 uint8 b0, b1;
107 b0 = *_bufPtr++;
108 b1 = *_bufPtr++;
109 return (b0 | (b1 << 8));
110 }
111 inline uint32 pop4() {
112 uint8 b0, b1, b2, b3;
113 b0 = *_bufPtr++;
114 b1 = *_bufPtr++;
115 b2 = *_bufPtr++;
116 b3 = *_bufPtr++;
117 return (b0 | (b1 << 8) | (b2 << 16) | (b3 << 24));
118 }
119 inline void pop(uint8 *out, const uint32 count) {
120 memcpy(out, _bufPtr, count);
121 _bufPtr += count;
122 }
123
124 //
125 // Access a value from a location in the stack
126 //
127
128 inline uint8 access1(const uint32 offset) const {
129 return _buf[offset];
130 }
131 inline uint16 access2(const uint32 offset) const {
132 return (_buf[offset] | (_buf[offset + 1] << 8));
133 }
134 inline uint32 access4(const uint32 offset) const {
135 return _buf[offset] | (_buf[offset + 1] << 8) |
136 (_buf[offset + 2] << 16) | (_buf[offset + 3] << 24);
137 }
138 inline uint8 *access(const uint32 offset) {
139 return _buf + offset;
140 }
141 inline uint8 *access() {
142 return _bufPtr;
143 }
144
145 //
146 // Assign a value to a location in the stack
147 //
148
149 inline void assign1(const uint32 offset, const uint8 val) {
150 const_cast<uint8 *>(_buf)[offset] = static_cast<uint8>(val & 0xFF);
151 }
152 inline void assign2(const uint32 offset, const uint16 val) {
153 const_cast<uint8 *>(_buf)[offset] = static_cast<uint8>(val & 0xFF);
154 const_cast<uint8 *>(_buf)[offset + 1] = static_cast<uint8>((val >> 8) & 0xFF);
155 }
156 inline void assign4(const uint32 offset, const uint32 val) {
157 const_cast<uint8 *>(_buf)[offset] = static_cast<uint8>(val & 0xFF);
158 const_cast<uint8 *>(_buf)[offset + 1] = static_cast<uint8>((val >> 8) & 0xFF);
159 const_cast<uint8 *>(_buf)[offset + 2] = static_cast<uint8>((val >> 16) & 0xFF);
160 const_cast<uint8 *>(_buf)[offset + 3] = static_cast<uint8>((val >> 24) & 0xFF);
161 }
162 inline void assign(const uint32 offset, const uint8 *in, const uint32 len) {
163 memcpy(const_cast<uint8 *>(_buf) + offset, in, len);
164 }
165};
166
168public:
169 DynamicUCStack(uint32 len = 0x1000) : BaseUCStack(len, new uint8[len]) { }
170 ~DynamicUCStack() override {
171 delete [] _buf;
172 }
173
174#ifdef USE_DYNAMIC_UCSTACK
175#define UCStack DynamicUCStack
176 void save(Common::WriteStream *ws);
177 bool load(Common::ReadStream *rs, uint32 version);
178#endif
179};
180
181#ifndef USE_DYNAMIC_UCSTACK
182class UCStack : public BaseUCStack {
183 uint8 _bufArray[0x1000];
184public:
185 UCStack() : BaseUCStack(0x1000, _bufArray) { }
186 ~UCStack() override { }
187
188 void save(Common::WriteStream *ws);
189 bool load(Common::ReadStream *rs, uint32 version);
190};
191#endif
192
193} // End of namespace Ultima8
194} // End of namespace Ultima
195
196#endif
Definition: stream.h:385
Definition: stream.h:77
Definition: uc_stack.h:36
Definition: uc_stack.h:167
Definition: uc_stack.h:182
Definition: algorithm.h:29