ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
memory.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 //=============================================================================
23 //
24 // Memory utils and algorithms
25 //
26 //=============================================================================
27 
28 #ifndef AGS_SHARED_UTIL_MEMORY_H
29 #define AGS_SHARED_UTIL_MEMORY_H
30 
31 //include <string.h>
32 #include "ags/shared/util/bbop.h"
33 #include "ags/shared/util/math.h"
34 
35 namespace AGS3 {
36 
37 #if defined (AGS_STRICT_ALIGNMENT) || defined (TEST_STRICT_ALIGNMENT)
38 #define MEMORY_STRICT_ALIGNMENT
39 #endif
40 
41 namespace AGS {
42 namespace Shared {
43 
44 namespace Memory {
45 //-------------------------------------------------------------------------
46 // Converts pointer to 32-bit integer value and vice-versa.
47 // Only for use in special cases for compatibility with 32-bit plugin API.
48 // Dangerous on 64-bit systems.
49 //-------------------------------------------------------------------------
50 template <typename T>
51 inline int32_t PtrToInt32(T *ptr) {
52  return static_cast<int32_t>(reinterpret_cast<intptr_t>(ptr));
53 }
54 template <typename T>
55 inline T *Int32ToPtr(int32_t value) {
56  return reinterpret_cast<T *>(static_cast<intptr_t>(value));
57 }
58 
59 //-------------------------------------------------------------------------
60 // Functions for reading and writing basic types from/to the memory.
61 // Implement safety workaround for CPUs with alignment restrictions
62 // (e.g. MIPS).
63 //-------------------------------------------------------------------------
64 inline int16_t ReadInt16(const void *ptr) {
65  #if defined (MEMORY_STRICT_ALIGNMENT)
66  const uint8_t *b = (const uint8_t *)ptr;
67  #if defined (BITBYTE_BIG_ENDIAN)
68  return (b[0] << 8) | b[1];
69  #else
70  return (b[1] << 8) | b[0];
71  #endif
72  #else
73  return *(const int16_t *)ptr;
74  #endif
75 }
76 
77 inline int32_t ReadInt32(const void *ptr) {
78  #if defined (MEMORY_STRICT_ALIGNMENT)
79  const uint8_t *b = (const uint8_t *)ptr;
80  #if defined (BITBYTE_BIG_ENDIAN)
81  return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
82  #else
83  return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
84  #endif
85  #else
86  return *(const int32_t *)ptr;
87  #endif
88 }
89 
90 inline int64_t ReadInt64(const void *ptr) {
91  #if defined (MEMORY_STRICT_ALIGNMENT)
92  const uint8_t *b = (const uint8_t *)ptr;
93  #if defined (BITBYTE_BIG_ENDIAN)
94  return ((uint64_t)b[0] << 56) | ((uint64_t)b[1] << 48) | ((uint64_t)b[2] << 40) | ((uint64_t)b[3] << 32) |
95  (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
96  #else
97  return ((uint64_t)b[7] << 56) | ((uint64_t)b[6] << 48) | ((uint64_t)b[5] << 40) | ((uint64_t)b[4] << 32) |
98  (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
99  #endif
100  #else
101  return *(const int64_t *)ptr;
102  #endif
103 }
104 
105 inline void WriteInt16(void *ptr, int16_t value) {
106  #if defined (MEMORY_STRICT_ALIGNMENT)
107  uint8_t *b = (uint8_t *)ptr;
108  #if defined (BITBYTE_BIG_ENDIAN)
109  b[0] = (uint8_t)(value >> 8);
110  b[1] = (uint8_t)(value);
111  #else
112  b[1] = (uint8_t)(value >> 8);
113  b[0] = (uint8_t)(value);
114  #endif
115  #else
116  *(int16_t *)ptr = value;
117  #endif
118 }
119 
120 inline void WriteInt32(void *ptr, int32_t value) {
121  #if defined (MEMORY_STRICT_ALIGNMENT)
122  uint8_t *b = (uint8_t *)ptr;
123  #if defined (BITBYTE_BIG_ENDIAN)
124  b[0] = (uint8_t)(value >> 24);
125  b[1] = (uint8_t)(value >> 16);
126  b[2] = (uint8_t)(value >> 8);
127  b[3] = (uint8_t)(value);
128  #else
129  b[3] = (uint8_t)(value >> 24);
130  b[2] = (uint8_t)(value >> 16);
131  b[1] = (uint8_t)(value >> 8);
132  b[0] = (uint8_t)(value);
133  #endif
134  #else
135  *(int32_t *)ptr = value;
136  #endif
137 }
138 
139 inline void WriteInt64(void *ptr, int64_t value) {
140  #if defined (MEMORY_STRICT_ALIGNMENT)
141  uint8_t *b = (uint8_t *)ptr;
142  #if defined (BITBYTE_BIG_ENDIAN)
143  b[0] = (uint8_t)(value >> 56);
144  b[1] = (uint8_t)(value >> 48);
145  b[2] = (uint8_t)(value >> 40);
146  b[3] = (uint8_t)(value >> 32);
147  b[4] = (uint8_t)(value >> 24);
148  b[5] = (uint8_t)(value >> 16);
149  b[6] = (uint8_t)(value >> 8);
150  b[7] = (uint8_t)(value);
151  #else
152  b[7] = (uint8_t)(value >> 56);
153  b[6] = (uint8_t)(value >> 48);
154  b[5] = (uint8_t)(value >> 40);
155  b[4] = (uint8_t)(value >> 32);
156  b[3] = (uint8_t)(value >> 24);
157  b[2] = (uint8_t)(value >> 16);
158  b[1] = (uint8_t)(value >> 8);
159  b[0] = (uint8_t)(value);
160  #endif
161  #else
162  *(int64_t *)ptr = value;
163  #endif
164 }
165 
166 //-------------------------------------------------------------------------
167 // Helpers for reading and writing from memory with respect for endianess.
168 //-------------------------------------------------------------------------
169 inline int16_t ReadInt16LE(const void *ptr) {
170  return BBOp::Int16FromLE(ReadInt16(ptr));
171 }
172 
173 inline int32_t ReadInt32LE(const void *ptr) {
174  return BBOp::Int32FromLE(ReadInt32(ptr));
175 }
176 
177 inline int64_t ReadInt64LE(const void *ptr) {
178  return BBOp::Int64FromLE(ReadInt64(ptr));
179 }
180 
181 inline void WriteInt16LE(void *ptr, int16_t value) {
182  WriteInt16(ptr, BBOp::Int16FromLE(value));
183 }
184 
185 inline void WriteInt32LE(void *ptr, int32_t value) {
186  WriteInt32(ptr, BBOp::Int32FromLE(value));
187 }
188 
189 inline void WriteInt64LE(void *ptr, int64_t value) {
190  WriteInt64(ptr, BBOp::Int64FromLE(value));
191 }
192 
193 inline int16_t ReadInt16BE(const void *ptr) {
194  return BBOp::Int16FromBE(ReadInt16(ptr));
195 }
196 
197 inline int32_t ReadInt32BE(const void *ptr) {
198  return BBOp::Int32FromBE(ReadInt32(ptr));
199 }
200 
201 inline int64_t ReadInt64BE(const void *ptr) {
202  return BBOp::Int64FromBE(ReadInt64(ptr));
203 }
204 
205 inline void WriteInt16BE(void *ptr, int16_t value) {
206  WriteInt16(ptr, BBOp::Int16FromBE(value));
207 }
208 
209 inline void WriteInt32BE(void *ptr, int32_t value) {
210  WriteInt32(ptr, BBOp::Int32FromBE(value));
211 }
212 
213 inline void WriteInt64BE(void *ptr, int64_t value) {
214  WriteInt64(ptr, BBOp::Int64FromBE(value));
215 }
216 
217 //-------------------------------------------------------------------------
218 // Memory data manipulation
219 //-------------------------------------------------------------------------
220 // Copies block of 2d data from source into destination.
221 inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_offset,
222  const uint8_t *src, const size_t src_pitch, const size_t src_offset,
223  const size_t height) {
224  for (size_t y = 0; y < height; ++y, src += src_pitch, dst += dst_pitch)
225  memcpy(dst + dst_offset, src + src_offset, MIN(dst_pitch - dst_offset, src_pitch - src_offset));
226 }
227 
228 } // namespace Memory
229 
230 } // namespace Shared
231 } // namespace AGS
232 } // namespace AGS3
233 
234 #endif
Definition: achievements_tables.h:27
T MIN(T a, T b)
Definition: util.h:61
Definition: ags.h:40