diff options
Diffstat (limited to 'engines/sci/engine/heap.cpp')
-rw-r--r-- | engines/sci/engine/heap.cpp | 286 |
1 files changed, 0 insertions, 286 deletions
diff --git a/engines/sci/engine/heap.cpp b/engines/sci/engine/heap.cpp deleted file mode 100644 index 5907582e37..0000000000 --- a/engines/sci/engine/heap.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* 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 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$ - * - */ - -#include "sci/engine/state.h" -#include "sci/scicore/sciconsole.h" -#include "sci/engine/heap.h" - -namespace Sci { - -#define assert_in_range(pos) assert(pos >= 1000 && pos <= 0xffff) - -static void set_size(heap_t *h, int block_pos, int size) { - assert_in_range(block_pos); - assert(size <= 0xffff - 1000); - putInt16(h->start + block_pos, size); -} - -static void set_next(heap_t *h, int block_pos, int next) { - assert_in_range(block_pos); - assert_in_range(next); - putInt16(h->start + block_pos + 2, next); -} - - -static unsigned int get_size(heap_t *h, int block_pos) { - assert_in_range(block_pos); - return (uint16)getInt16(h->start + block_pos); -} - -static unsigned int get_next(heap_t *h, int block_pos) { - assert_in_range(block_pos); - return (uint16)getInt16(h->start + block_pos + 2); -} - -// Allocates a new heap -heap_t *heap_new() { - heap_t *h; - - if ((h = (heap_t*)sci_malloc(sizeof(heap_t))) == 0) - return 0; - - if ((h->start = (byte *)sci_calloc(SCI_HEAP_SIZE, 1)) == 0) { - free(h); - return 0; - } - - h->base = h->start + 1000; - h->first_free = 1000; - h->old_ff = -1; - set_size(h, 1000, 0xffff - 1000); - set_next(h, 1000, 0xffff); - - return h; -} - -// Deletes a heap -void heap_del(heap_t *h) { - free(h->start); - free(h); -} - -int heap_meminfo(heap_t *h) { - heap_ptr current = h->first_free; - int total = 0; - - while (current != 0xffff) { - total += get_size(h, current); - current = get_next(h, current); - } - - return total; -} - - -int heap_largest(heap_t *h) { - int current = h->first_free; - int best_pos = -1, best_size = 0; - - while (current != 0xffff) { - int size = get_size(h, current); - int next = get_next(h, current); - - if (size > best_size) { - best_pos = current; - best_size = size; - } - - current = next; - } - - return best_size; -} - -heap_ptr heap_allocate(heap_t *h, int size) { - unsigned int previous = h->first_free; - unsigned int current = previous; - - if (!size) { - fprintf(stderr, "Warning: heap_alloc'd zero bytes!\n"); - size += 2; - } - - size += 2 + (size & 1); - - while (current < 0xffff) { - int block_size = get_size(h, current); - int next = get_next(h, current); - - // Is this block large enough? - if (block_size >= size) { - // Swallow the block whole - if (block_size <= size + 4) { - size = block_size; - set_next(h, previous, next); - } else { - // Split the block - int rest = current + size; - - set_next(h, previous, rest); - set_size(h, rest, block_size - size); - set_next(h, rest, next); - next = rest; - } - set_size(h, current, size); - if (current == h->first_free) h->first_free = next; - return current; - } - previous = current; - current = next; - } - - // No large enough block was found. - return 0; -} - -void heap_free(heap_t *h, unsigned int m) { - unsigned int previous, next; - assert_in_range(m); - previous = next = h->first_free; - - // Find the previous and next blocks - while (next < m) { - previous = next; - assert(previous < 0xffff); - next = get_next(h, previous); - if (next <= previous) { - sciprintf("Heap corrupt. Aborting heap_free()...\n"); - return; - } - } - - if (h->first_free > m) - h->first_free = m; // Guarantee that first_free is correct - - if (previous == next) { - if (m < previous) { - h->first_free = m; - if (m + get_size(h, m) == previous) { - set_size(h, m, get_size(h, m) + get_size(h, previous)); - set_next(h, m, get_next(h, previous)); - } else - set_next(h, m, previous); - } else { - if (previous + get_size(h, previous) == m) { - set_size(h, previous, get_size(h, previous) + get_size(h, m)); - set_next(h, previous, 0xffff); - } else { - set_next(h, previous, m); - set_next(h, m, next); - } - } - } else { - set_next(h, previous, m); - set_next(h, m, next); - - // Try to merge with previous - if (previous + get_size(h, previous) == m) { - set_size(h, previous, get_size(h, previous) + get_size(h, m)); - set_next(h, previous, next); - m = previous; - } - - // Try to merge with next - if (m + get_size(h, m) == next) { - set_size(h, m, get_size(h, m) + get_size(h, next)); - set_next(h, m, get_next(h, next)); - } - } -} - -void save_ff(heap_t *h) { - h->old_ff = h->first_free; -} - -void restore_ff(heap_t *h) { - h->first_free = h->old_ff; - set_size(h, h->first_free, 0xffff - h->first_free); - set_next(h, h->first_free, 0xffff); -} - -void heap_dump_free(heap_t *h) { - int freedomseeker; - - printf("\tfirst_free= %#x (oldff= %#x)\n\tFree Blocks:\n", h->first_free, h->old_ff); - - freedomseeker = h->first_free; - while (freedomseeker != 0xffff) { - printf("\t %#04x: size: %#04x\n", freedomseeker, get_size(h, freedomseeker)); - freedomseeker = get_next(h, freedomseeker); - } -} - -void heap_dump_all(heap_t *h) { - int seeker = 1000; - int free_seeker = h->first_free; - - while (seeker < 0xffff) { - int is_free = (seeker == free_seeker); - int size = get_size(h, seeker); - - if (is_free) - free_seeker = get_next(h, free_seeker); - - printf("%04x\t%d\t%s\n", seeker, size, is_free ? "FREE" : ""); - seeker += size; - } -} - -#if 0 -int main(int argc, char **argv) { - heap_t *h = heap_new(); - int a, b, c, d, e; - - printf("Running heap tests:\nHeap initialization:\n"); - heap_dump_free(h); - - printf("[a] Allocating 0x1: position is %#x\n", a = heap_allocate(h, 1)); - heap_dump_free(h); - - printf("[b] Allocating 0x10: position is %#x\n", b = heap_allocate(h, 0x10)); - printf("[c] Allocating 0x10: position is %#x\n", c = heap_allocate(h, 0x10)); - printf("[d] Allocating 0x10: position is %#x\n", d = heap_allocate(h, 0x10)); - printf("[e] Allocating 0x1000: position is %#x\n", e = heap_allocate(h, 0x1000)); - heap_dump_free(h); - - printf("Freeing [b]:\n"); - heap_free(h, b); - heap_dump_free(h); - - printf("Freeing [d]:\n"); - heap_free(h, d); - heap_dump_free(h); - - printf("Freeing [c]:\n"); - heap_free(h, c); - heap_dump_free(h); - - heap_del(h); - - return 0; -} -#endif - -} // End of namespace Sci |