aboutsummaryrefslogtreecommitdiff
path: root/sword2/memory.cpp
diff options
context:
space:
mode:
authorMax Horn2006-02-11 22:45:04 +0000
committerMax Horn2006-02-11 22:45:04 +0000
commit26ee630756ebdd7c96bccede0881a8c8b98e8f2b (patch)
tree26e378d5cf990a2b81c2c96e9e683a7f333b62e8 /sword2/memory.cpp
parent2a9a0d4211b1ea5723f1409d91cb95de8984429e (diff)
downloadscummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.gz
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.tar.bz2
scummvm-rg350-26ee630756ebdd7c96bccede0881a8c8b98e8f2b.zip
Moved engines to the new engines/ directory
svn-id: r20582
Diffstat (limited to 'sword2/memory.cpp')
-rw-r--r--sword2/memory.cpp244
1 files changed, 0 insertions, 244 deletions
diff --git a/sword2/memory.cpp b/sword2/memory.cpp
deleted file mode 100644
index 7da4e86b51..0000000000
--- a/sword2/memory.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/* Copyright (C) 1994-1998 Revolution Software Ltd.
- * Copyright (C) 2003-2006 The ScummVM project
- *
- * 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 2
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- */
-
-// The new memory manager, now only used by the resource manager. The original
-// one would allocated a 12 MB memory pool at startup, which may have been
-// appropriate for the original Playstation version but didn't work very well
-// with our PocketPC version.
-//
-// There is one thing that prevents us from replacing the whole memory manager
-// with the standard memory allocation functions: Broken Sword 2 absolutely,
-// positively needs to be able to encode pointers as 32-bit integers. The
-// original engine did this simply by casting between pointers and integers,
-// but as far as I know that's not a very portable thing to do.
-//
-// If it had only used pointers as opcode parameters it would have been
-// possible, albeit messy, to extend the stack data type. However, there is
-// code in walker.cpp that obviously violates that assumption, and there are
-// probably other cases as well.
-//
-// Instead, we take advantage of the fact that the original memory manager
-// could only handle up to 999 blocks of memory. That means we can encode a
-// pointer as a 10-bit id and a 22-bit offset into the block. Judging by early
-// testing, both should be plenty.
-//
-// The number zero is used to represent the NULL pointer.
-
-#include "common/stdafx.h"
-#include "sword2/sword2.h"
-#include "sword2/memory.h"
-
-namespace Sword2 {
-
-MemoryManager::MemoryManager(Sword2Engine *vm) : _vm(vm) {
- // The id stack contains all the possible ids for the memory blocks.
- // We use this to ensure that no two blocks ever have the same id.
-
- // The memory blocks are stored in an array, indexed on the block's
- // id. This means that given a block id we can find the pointer with a
- // simple array lookup.
-
- // The memory block index is an array of pointers to the memory block
- // array, sorted on the memory block's pointer. This means that given
- // a pointer into a memory block we can find its id with binary
- // searching.
- //
- // A balanced tree might have been more efficient - the index has to
- // be re-sorted every time a block is allocated or freed - but such
- // beasts are tricky to implement. Anyway, it wouldn't have made
- // encoding or decoding pointers any faster, and these are by far the
- // most common operations.
-
- _idStack = (int16 *)malloc(MAX_MEMORY_BLOCKS * sizeof(int16));
- _memBlocks = (MemBlock *)malloc(MAX_MEMORY_BLOCKS * sizeof(MemBlock));
- _memBlockIndex = (MemBlock **)malloc(MAX_MEMORY_BLOCKS * sizeof(MemBlock *));
-
- _totAlloc = 0;
- _numBlocks = 0;
-
- for (int i = 0; i < MAX_MEMORY_BLOCKS; i++) {
- _idStack[i] = MAX_MEMORY_BLOCKS - i - 1;
- _memBlocks[i].ptr = NULL;
- _memBlockIndex[i] = NULL;
- }
-
- _idStackPtr = MAX_MEMORY_BLOCKS;
-}
-
-MemoryManager::~MemoryManager() {
- for (int i = 0; i < MAX_MEMORY_BLOCKS; i++)
- free(_memBlocks[i].ptr);
- free(_memBlocks);
- free(_memBlockIndex);
- free(_idStack);
-}
-
-int32 MemoryManager::encodePtr(byte *ptr) {
- if (ptr == NULL)
- return 0;
-
- int idx = findPointerInIndex(ptr);
-
- assert(idx != -1);
-
- uint32 id = _memBlockIndex[idx]->id;
- uint32 offset = ptr - _memBlocks[id].ptr;
-
- assert(id < 0x03ff);
- assert(offset <= 0x003fffff);
- assert(offset < _memBlocks[id].size);
-
- return ((id + 1) << 22) | (ptr - _memBlocks[id].ptr);
-}
-
-byte *MemoryManager::decodePtr(int32 n) {
- if (n == 0)
- return NULL;
-
- uint32 id = ((n & 0xffc00000) >> 22) - 1;
- uint32 offset = n & 0x003fffff;
-
- assert(_memBlocks[id].ptr);
- assert(offset < _memBlocks[id].size);
-
- return _memBlocks[id].ptr + offset;
-}
-
-int16 MemoryManager::findExactPointerInIndex(byte *ptr) {
- int left = 0;
- int right = _numBlocks - 1;
-
- while (right >= left) {
- int n = (left + right) / 2;
-
- if (_memBlockIndex[n]->ptr == ptr)
- return n;
-
- if (_memBlockIndex[n]->ptr > ptr)
- right = n - 1;
- else
- left = n + 1;
- }
-
- return -1;
-}
-
-int16 MemoryManager::findPointerInIndex(byte *ptr) {
- int left = 0;
- int right = _numBlocks - 1;
-
- while (right >= left) {
- int n = (left + right) / 2;
-
- if (_memBlockIndex[n]->ptr <= ptr && _memBlockIndex[n]->ptr + _memBlockIndex[n]->size > ptr)
- return n;
-
- if (_memBlockIndex[n]->ptr > ptr)
- right = n - 1;
- else
- left = n + 1;
- }
-
- return -1;
-}
-
-int16 MemoryManager::findInsertionPointInIndex(byte *ptr) {
- if (_numBlocks == 0)
- return 0;
-
- int left = 0;
- int right = _numBlocks - 1;
- int n = 0;
-
- while (right >= left) {
- n = (left + right) / 2;
-
- if (_memBlockIndex[n]->ptr == ptr)
- return -1;
-
- if (_memBlockIndex[n]->ptr > ptr)
- right = n - 1;
- else
- left = n + 1;
- }
-
- if (_memBlockIndex[n]->ptr < ptr)
- n++;
-
- return n;
-}
-
-byte *MemoryManager::memAlloc(uint32 size, int16 uid) {
- assert(_idStackPtr > 0);
-
- // Get the new block's id from the stack.
- int16 id = _idStack[--_idStackPtr];
-
- // Allocate the new memory block
- byte *ptr = (byte *)malloc(size);
-
- assert(ptr);
-
- _memBlocks[id].id = id;
- _memBlocks[id].uid = uid;
- _memBlocks[id].ptr = ptr;
- _memBlocks[id].size = size;
-
- // Update the memory block index.
- int16 idx = findInsertionPointInIndex(ptr);
-
- assert(idx != -1);
-
- for (int i = _numBlocks; i > idx; i--)
- _memBlockIndex[i] = _memBlockIndex[i - 1];
-
- _memBlockIndex[idx] = &_memBlocks[id];
- _numBlocks++;
- _totAlloc += size;
-
- return _memBlocks[id].ptr;
-}
-
-void MemoryManager::memFree(byte *ptr) {
- int16 idx = findExactPointerInIndex(ptr);
-
- if (idx == -1) {
- warning("Freeing non-allocated pointer %p", ptr);
- return;
- }
-
- // Put back the id on the stack
- _idStack[_idStackPtr++] = _memBlockIndex[idx]->id;
-
- // Release the memory block
- free(_memBlockIndex[idx]->ptr);
- _memBlockIndex[idx]->ptr = NULL;
-
- _totAlloc -= _memBlockIndex[idx]->size;
-
- // Remove the memory block from the index
- _numBlocks--;
-
- for (int i = idx; i < _numBlocks; i++)
- _memBlockIndex[i] = _memBlockIndex[i + 1];
-}
-
-} // End of namespace Sword2