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