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 Common {
28 class ReadStream;
29 class WriteStream;
30 }
31 
32 namespace Ultima {
33 namespace Ultima8 {
34 
35 // A little-endian stack for use with usecode
36 class BaseUCStack {
37 protected:
38  uint8 *_buf;
39  uint8 *_bufPtr;
40  uint32 _size;
41 public:
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 
167 class DynamicUCStack : public BaseUCStack {
168 public:
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
182 class UCStack : public BaseUCStack {
183  uint8 _bufArray[0x1000];
184 public:
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:77
Definition: uc_stack.h:182
Definition: uc_stack.h:36
Definition: detection.h:27
Definition: algorithm.h:29
Definition: stream.h:385
Definition: uc_stack.h:167