Initial commit
This commit is contained in:
234
engines/ags/shared/util/memory.h
Normal file
234
engines/ags/shared/util/memory.h
Normal file
@@ -0,0 +1,234 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Memory utils and algorithms
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef AGS_SHARED_UTIL_MEMORY_H
|
||||
#define AGS_SHARED_UTIL_MEMORY_H
|
||||
|
||||
//include <string.h>
|
||||
#include "ags/shared/util/bbop.h"
|
||||
#include "ags/shared/util/math.h"
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
#if defined (AGS_STRICT_ALIGNMENT) || defined (TEST_STRICT_ALIGNMENT)
|
||||
#define MEMORY_STRICT_ALIGNMENT
|
||||
#endif
|
||||
|
||||
namespace AGS {
|
||||
namespace Shared {
|
||||
|
||||
namespace Memory {
|
||||
//-------------------------------------------------------------------------
|
||||
// Converts pointer to 32-bit integer value and vice-versa.
|
||||
// Only for use in special cases for compatibility with 32-bit plugin API.
|
||||
// Dangerous on 64-bit systems.
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline int32_t PtrToInt32(T *ptr) {
|
||||
return static_cast<int32_t>(reinterpret_cast<intptr_t>(ptr));
|
||||
}
|
||||
template <typename T>
|
||||
inline T *Int32ToPtr(int32_t value) {
|
||||
return reinterpret_cast<T *>(static_cast<intptr_t>(value));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions for reading and writing basic types from/to the memory.
|
||||
// Implement safety workaround for CPUs with alignment restrictions
|
||||
// (e.g. MIPS).
|
||||
//-------------------------------------------------------------------------
|
||||
inline int16_t ReadInt16(const void *ptr) {
|
||||
#if defined (MEMORY_STRICT_ALIGNMENT)
|
||||
const uint8_t *b = (const uint8_t *)ptr;
|
||||
#if defined (BITBYTE_BIG_ENDIAN)
|
||||
return (b[0] << 8) | b[1];
|
||||
#else
|
||||
return (b[1] << 8) | b[0];
|
||||
#endif
|
||||
#else
|
||||
return *(const int16_t *)ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int32_t ReadInt32(const void *ptr) {
|
||||
#if defined (MEMORY_STRICT_ALIGNMENT)
|
||||
const uint8_t *b = (const uint8_t *)ptr;
|
||||
#if defined (BITBYTE_BIG_ENDIAN)
|
||||
return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
|
||||
#else
|
||||
return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
|
||||
#endif
|
||||
#else
|
||||
return *(const int32_t *)ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int64_t ReadInt64(const void *ptr) {
|
||||
#if defined (MEMORY_STRICT_ALIGNMENT)
|
||||
const uint8_t *b = (const uint8_t *)ptr;
|
||||
#if defined (BITBYTE_BIG_ENDIAN)
|
||||
return ((uint64_t)b[0] << 56) | ((uint64_t)b[1] << 48) | ((uint64_t)b[2] << 40) | ((uint64_t)b[3] << 32) |
|
||||
(b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
|
||||
#else
|
||||
return ((uint64_t)b[7] << 56) | ((uint64_t)b[6] << 48) | ((uint64_t)b[5] << 40) | ((uint64_t)b[4] << 32) |
|
||||
(b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0];
|
||||
#endif
|
||||
#else
|
||||
return *(const int64_t *)ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void WriteInt16(void *ptr, int16_t value) {
|
||||
#if defined (MEMORY_STRICT_ALIGNMENT)
|
||||
uint8_t *b = (uint8_t *)ptr;
|
||||
#if defined (BITBYTE_BIG_ENDIAN)
|
||||
b[0] = (uint8_t)(value >> 8);
|
||||
b[1] = (uint8_t)(value);
|
||||
#else
|
||||
b[1] = (uint8_t)(value >> 8);
|
||||
b[0] = (uint8_t)(value);
|
||||
#endif
|
||||
#else
|
||||
*(int16_t *)ptr = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void WriteInt32(void *ptr, int32_t value) {
|
||||
#if defined (MEMORY_STRICT_ALIGNMENT)
|
||||
uint8_t *b = (uint8_t *)ptr;
|
||||
#if defined (BITBYTE_BIG_ENDIAN)
|
||||
b[0] = (uint8_t)(value >> 24);
|
||||
b[1] = (uint8_t)(value >> 16);
|
||||
b[2] = (uint8_t)(value >> 8);
|
||||
b[3] = (uint8_t)(value);
|
||||
#else
|
||||
b[3] = (uint8_t)(value >> 24);
|
||||
b[2] = (uint8_t)(value >> 16);
|
||||
b[1] = (uint8_t)(value >> 8);
|
||||
b[0] = (uint8_t)(value);
|
||||
#endif
|
||||
#else
|
||||
*(int32_t *)ptr = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void WriteInt64(void *ptr, int64_t value) {
|
||||
#if defined (MEMORY_STRICT_ALIGNMENT)
|
||||
uint8_t *b = (uint8_t *)ptr;
|
||||
#if defined (BITBYTE_BIG_ENDIAN)
|
||||
b[0] = (uint8_t)(value >> 56);
|
||||
b[1] = (uint8_t)(value >> 48);
|
||||
b[2] = (uint8_t)(value >> 40);
|
||||
b[3] = (uint8_t)(value >> 32);
|
||||
b[4] = (uint8_t)(value >> 24);
|
||||
b[5] = (uint8_t)(value >> 16);
|
||||
b[6] = (uint8_t)(value >> 8);
|
||||
b[7] = (uint8_t)(value);
|
||||
#else
|
||||
b[7] = (uint8_t)(value >> 56);
|
||||
b[6] = (uint8_t)(value >> 48);
|
||||
b[5] = (uint8_t)(value >> 40);
|
||||
b[4] = (uint8_t)(value >> 32);
|
||||
b[3] = (uint8_t)(value >> 24);
|
||||
b[2] = (uint8_t)(value >> 16);
|
||||
b[1] = (uint8_t)(value >> 8);
|
||||
b[0] = (uint8_t)(value);
|
||||
#endif
|
||||
#else
|
||||
*(int64_t *)ptr = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Helpers for reading and writing from memory with respect for endianess.
|
||||
//-------------------------------------------------------------------------
|
||||
inline int16_t ReadInt16LE(const void *ptr) {
|
||||
return BBOp::Int16FromLE(ReadInt16(ptr));
|
||||
}
|
||||
|
||||
inline int32_t ReadInt32LE(const void *ptr) {
|
||||
return BBOp::Int32FromLE(ReadInt32(ptr));
|
||||
}
|
||||
|
||||
inline int64_t ReadInt64LE(const void *ptr) {
|
||||
return BBOp::Int64FromLE(ReadInt64(ptr));
|
||||
}
|
||||
|
||||
inline void WriteInt16LE(void *ptr, int16_t value) {
|
||||
WriteInt16(ptr, BBOp::Int16FromLE(value));
|
||||
}
|
||||
|
||||
inline void WriteInt32LE(void *ptr, int32_t value) {
|
||||
WriteInt32(ptr, BBOp::Int32FromLE(value));
|
||||
}
|
||||
|
||||
inline void WriteInt64LE(void *ptr, int64_t value) {
|
||||
WriteInt64(ptr, BBOp::Int64FromLE(value));
|
||||
}
|
||||
|
||||
inline int16_t ReadInt16BE(const void *ptr) {
|
||||
return BBOp::Int16FromBE(ReadInt16(ptr));
|
||||
}
|
||||
|
||||
inline int32_t ReadInt32BE(const void *ptr) {
|
||||
return BBOp::Int32FromBE(ReadInt32(ptr));
|
||||
}
|
||||
|
||||
inline int64_t ReadInt64BE(const void *ptr) {
|
||||
return BBOp::Int64FromBE(ReadInt64(ptr));
|
||||
}
|
||||
|
||||
inline void WriteInt16BE(void *ptr, int16_t value) {
|
||||
WriteInt16(ptr, BBOp::Int16FromBE(value));
|
||||
}
|
||||
|
||||
inline void WriteInt32BE(void *ptr, int32_t value) {
|
||||
WriteInt32(ptr, BBOp::Int32FromBE(value));
|
||||
}
|
||||
|
||||
inline void WriteInt64BE(void *ptr, int64_t value) {
|
||||
WriteInt64(ptr, BBOp::Int64FromBE(value));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Memory data manipulation
|
||||
//-------------------------------------------------------------------------
|
||||
// Copies block of 2d data from source into destination.
|
||||
inline void BlockCopy(uint8_t *dst, const size_t dst_pitch, const size_t dst_offset,
|
||||
const uint8_t *src, const size_t src_pitch, const size_t src_offset,
|
||||
const size_t height) {
|
||||
for (size_t y = 0; y < height; ++y, src += src_pitch, dst += dst_pitch)
|
||||
memcpy(dst + dst_offset, src + src_offset, MIN(dst_pitch - dst_offset, src_pitch - src_offset));
|
||||
}
|
||||
|
||||
} // namespace Memory
|
||||
|
||||
} // namespace Shared
|
||||
} // namespace AGS
|
||||
} // namespace AGS3
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user