aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sword2/anims.cpp4
-rw-r--r--sword2/build_display.cpp2
-rw-r--r--sword2/console.cpp6
-rw-r--r--sword2/driver/d_draw.cpp2
-rw-r--r--sword2/maketext.cpp10
-rw-r--r--sword2/mem_view.cpp67
-rw-r--r--sword2/mem_view.h27
-rw-r--r--sword2/memory.cpp288
-rw-r--r--sword2/memory.h55
-rw-r--r--sword2/resman.cpp58
-rw-r--r--sword2/resman.h5
-rw-r--r--sword2/router.cpp10
-rw-r--r--sword2/save_rest.cpp14
-rw-r--r--sword2/startup.cpp2
-rw-r--r--sword2/sword2.cpp9
-rw-r--r--sword2/tony_gsdk.cpp2
16 files changed, 263 insertions, 298 deletions
diff --git a/sword2/anims.cpp b/sword2/anims.cpp
index 7eae4971d8..a06d3b7c20 100644
--- a/sword2/anims.cpp
+++ b/sword2/anims.cpp
@@ -603,7 +603,7 @@ void CreateSequenceSpeech(_movieTextObject *sequenceText[]) {
// if we've made a text sprite for this line...
if (sequence_text_list[line].text_mem) {
- Lock_mem(sequence_text_list[line].text_mem);
+ memory.lockMemory(sequence_text_list[line].text_mem);
// now fill out the _spriteInfo structure in the
// _movieTextObjectStructure
@@ -642,7 +642,7 @@ void ClearSequenceSpeech(_movieTextObject *textSprites[]) {
// free up the mem block containing this text sprite
if (sequence_text_list[line].text_mem)
- Free_mem(sequence_text_list[line].text_mem);
+ memory.freeMemory(sequence_text_list[line].text_mem);
// free up the mem block containing this speech sample
if (sequence_text_list[line].speech_mem)
diff --git a/sword2/build_display.cpp b/sword2/build_display.cpp
index 653b513c1b..1531c6cd90 100644
--- a/sword2/build_display.cpp
+++ b/sword2/build_display.cpp
@@ -379,7 +379,7 @@ void DisplayMsg(uint8 *text, int time) {
FadeUp((float) 0.75);
- Free_mem(text_spr);
+ memory.freeMemory(text_spr);
WaitForFade();
diff --git a/sword2/console.cpp b/sword2/console.cpp
index b90f99ab7c..f4a0f535f7 100644
--- a/sword2/console.cpp
+++ b/sword2/console.cpp
@@ -168,10 +168,10 @@ void Init_console(void) {
// Force a palatte for the console.
BS2_SetPalette(CON_PEN, 1, white, RDPAL_INSTANT);
- console_sprite = Twalloc(con_width * (CON_lines * con_chr_height), MEM_float, UID_con_sprite);
+ console_sprite = memory.alloc(con_width * (CON_lines * con_chr_height), MEM_float, UID_con_sprite);
if (!console_sprite) {
- ExitWithReport("Init_console Talloc fail");
+ ExitWithReport("Init_console alloc fail");
}
con_depth = CON_lines * con_chr_height;
@@ -444,7 +444,7 @@ uint32 Parse_user_input(void) {
Con_help();
return 0;
case 1: // MEM
- Console_mem_display();
+ memory.displayMemory();
return 0;
case 2: // Q
// quit the console
diff --git a/sword2/driver/d_draw.cpp b/sword2/driver/d_draw.cpp
index 18dbaccf62..eaec82e37e 100644
--- a/sword2/driver/d_draw.cpp
+++ b/sword2/driver/d_draw.cpp
@@ -235,7 +235,7 @@ int32 PlaySmacker(char *filename, _movieTextObject *text[], uint8 *musicOut) {
CreateSurface(&msgSprite, &msgSurface);
DrawSurface(&msgSprite, msgSurface);
DeleteSurface(msgSurface);
- Free_mem(data);
+ memory.freeMemory(data);
// In case the cutscene has a long lead-in, start just before
// the first line of text.
diff --git a/sword2/maketext.cpp b/sword2/maketext.cpp
index ad97f4c38a..84e198a8a7 100644
--- a/sword2/maketext.cpp
+++ b/sword2/maketext.cpp
@@ -133,7 +133,7 @@ mem* MakeTextSprite(uint8 *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes)
// allocate memory for array of lineInfo structures
- line = Twalloc(MAX_LINES * sizeof(_lineInfo), MEM_locked, UID_temp);
+ line = memory.allocMemory(MAX_LINES * sizeof(_lineInfo), MEM_locked, UID_temp);
// get details of sentence breakdown into array of _lineInfo structures
// and get the no of lines involved
@@ -146,7 +146,7 @@ mem* MakeTextSprite(uint8 *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes)
textSprite = BuildTextSprite(sentence, fontRes, pen, (_lineInfo *) line->ad, noOfLines);
// free up the lineInfo array now
- Free_mem(line);
+ memory.freeMemory(line);
return textSprite;
}
@@ -259,7 +259,7 @@ mem* BuildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen, _lineInfo *line
// allocate memory for sprite, and lock it ready for use
// NB. 'textSprite' is the given pointer to the handle to be used
- textSprite = Twalloc(sizeof(_frameHeader) + sizeOfSprite, MEM_locked, UID_text_sprite);
+ textSprite = memory.allocMemory(sizeof(_frameHeader) + sizeOfSprite, MEM_locked, UID_text_sprite);
// the handle (*textSprite) now points to UNMOVABLE memory block
// set up the frame header
@@ -320,7 +320,7 @@ mem* BuildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen, _lineInfo *line
res_man.close(fontRes);
// unlock the sprite memory block, so it's movable
- Float_mem(textSprite);
+ memory.floatMemory(textSprite);
return textSprite;
}
@@ -601,7 +601,7 @@ void Kill_text_bloc(uint32 bloc_number) {
if (text_sprite_list[bloc_number].text_mem) {
// release the floating memory and mark it as free
- Free_mem(text_sprite_list[bloc_number].text_mem);
+ memory.freeMemory(text_sprite_list[bloc_number].text_mem);
text_sprite_list[bloc_number].text_mem = 0;
} else {
// illegal kill - stop the system
diff --git a/sword2/mem_view.cpp b/sword2/mem_view.cpp
index 0e3ceb83b4..26164e8798 100644
--- a/sword2/mem_view.cpp
+++ b/sword2/mem_view.cpp
@@ -21,14 +21,13 @@
#include "build_display.h"
#include "console.h"
#include "header.h"
-#include "mem_view.h"
#include "memory.h"
#include "resman.h"
// has to be global because a local in Fetch_mem_owner is destroyed on exit
char buf[50];
-void Console_mem_display(void) {
+void MemoryManager::displayMemory(void) {
int pass, found_end, k, j, free = 0;
_standardHeader *file_header;
int scrolls = 0;
@@ -41,14 +40,14 @@ void Console_mem_display(void) {
{ "M_float " }
};
- j = base_mem_block;
+ j = _baseMemBlock;
do {
- if (mem_list[j].uid < 65536) {
- file_header = (_standardHeader*) res_man.open(mem_list[j].uid);
+ if (_memList[j].uid < 65536) {
+ file_header = (_standardHeader*) res_man.open(_memList[j].uid);
// close immediately so give a true count
- res_man.close(mem_list[j].uid);
+ res_man.close(_memList[j].uid);
- debug(5, "view %d", mem_list[j].uid);
+ debug(5, "view %d", _memList[j].uid);
pass = 0;
found_end = 0;
@@ -68,29 +67,29 @@ void Console_mem_display(void) {
if (!pass && found_end) { // && file_header->fileType < 10)
Print_to_console("%d %s, size 0x%.5x (%dk %d%%), res %d %s %s, A%d, C%d",
- j, inf[mem_list[j].state],
- mem_list[j].size,
- mem_list[j].size / 1024,
- (mem_list[j].size * 100) / total_free_memory,
- mem_list[j].uid,
- res_man.fetchCluster(mem_list[j].uid),
+ j, inf[_memList[j].state],
+ _memList[j].size,
+ _memList[j].size / 1024,
+ (_memList[j].size * 100) / _totalFreeMemory,
+ _memList[j].uid,
+ res_man.fetchCluster(_memList[j].uid),
file_header->name,
- res_man.fetchAge(mem_list[j].uid),
- res_man.fetchCount(mem_list[j].uid));
+ res_man.fetchAge(_memList[j].uid),
+ res_man.fetchCount(_memList[j].uid));
} else
- Print_to_console(" %d is an illegal resource", mem_list[j].uid);
+ Print_to_console(" %d is an illegal resource", _memList[j].uid);
} else {
Print_to_console("%d %s, size 0x%.5x (%dk %d%%), %s",
- j, inf[mem_list[j].state], mem_list[j].size,
- mem_list[j].size / 1024,
- (mem_list[j].size * 100) / total_free_memory,
- Fetch_mem_owner(mem_list[j].uid));
+ j, inf[_memList[j].state], _memList[j].size,
+ _memList[j].size / 1024,
+ (_memList[j].size * 100) / _totalFreeMemory,
+ fetchOwner(_memList[j].uid));
}
- if (mem_list[j].state == MEM_free)
- free += mem_list[j].size;
+ if (_memList[j].state == MEM_free)
+ free += _memList[j].size;
- j = mem_list[j].child;
+ j = _memList[j].child;
scrolls++;
@@ -116,12 +115,12 @@ void Console_mem_display(void) {
Scroll_console();
Print_to_console("(total memory block 0x%.8x %dk %dMB) %d / %d%% free",
- total_free_memory, total_free_memory / 1024,
- total_free_memory / (1000 * 1024), free,
- (free * 100) / total_free_memory);
+ _totalFreeMemory, _totalFreeMemory / 1024,
+ _totalFreeMemory / (1000 * 1024), free,
+ (free * 100) / _totalFreeMemory);
}
-const char *Fetch_mem_owner(uint32 uid) {
+const char *MemoryManager::fetchOwner(uint32 uid) {
switch (uid) {
case UID_memman:
return "MEMMAN";
@@ -147,8 +146,8 @@ const char *Fetch_mem_owner(uint32 uid) {
}
}
-void Create_mem_string(char *string) {
- int blockNo = base_mem_block;
+void MemoryManager::memoryString(char *string) {
+ int blockNo = _baseMemBlock;
int blocksUsed = 0;
int mem_free = 0;
int mem_locked = 0;
@@ -157,27 +156,27 @@ void Create_mem_string(char *string) {
int percent;
while (blockNo != -1) {
- switch (mem_list[blockNo].state) {
+ switch (_memList[blockNo].state) {
case MEM_free:
mem_free++;
break;
case MEM_locked:
mem_locked++;
- memUsed += mem_list[blockNo].size;
+ memUsed += _memList[blockNo].size;
break;
case MEM_float:
mem_floating++;
- memUsed += mem_list[blockNo].size;
+ memUsed += _memList[blockNo].size;
break;
}
blocksUsed++;
- blockNo = mem_list[blockNo].child;
+ blockNo = _memList[blockNo].child;
}
- percent = (memUsed * 100) / total_free_memory;
+ percent = (memUsed * 100) / _totalFreeMemory;
sprintf(string,
"locked(%u)+float(%u)+free(%u) = %u/%u blocks (%u%% used)(cur %uk)",
diff --git a/sword2/mem_view.h b/sword2/mem_view.h
deleted file mode 100644
index 73e4efefc7..0000000000
--- a/sword2/mem_view.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright (C) 1994-2003 Revolution Software Ltd
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Header$
- */
-
-#ifndef MEMVIEW_H
-#define MEMVIEW_H
-
-const char *Fetch_mem_owner(uint32 uid);
-void Console_mem_display(void);
-void Create_mem_string(char *string);
-
-#endif
diff --git a/sword2/memory.cpp b/sword2/memory.cpp
index 9499579862..0b6c9baef0 100644
--- a/sword2/memory.cpp
+++ b/sword2/memory.cpp
@@ -43,82 +43,53 @@
#include "memory.h"
#include "resman.h"
-uint32 total_blocks;
-uint32 total_free_memory;
+MemoryManager memory;
#define MEMORY_POOL (1024 * 12000)
-// address of init malloc to be freed later
-uint8 *free_memman;
-
-// list of defined memory handles - each representing a block of memory.
-mem mem_list[MAX_mem_blocks];
-
-uint32 base_mem_block;
-
// #define MEMDEBUG 1
-// Used to determine if the required size can be obtained if the defragger is
-// allowed to run.
-
-int32 VirtualDefrag(uint32 size);
-
-// Start position of the Defragger as indicated by its sister VirtualDefrag.
-int32 suggestedStart = 0;
-
-void Close_memory_manager(void) { // Tony2Oct96
- free(free_memman);
+void MemoryManager::exit(void) {
+ free(_freeMemman);
}
-void Init_memory_manager(void) {
+void MemoryManager::init(void) {
uint32 j;
uint8 *memory_base;
- total_free_memory = MEMORY_POOL;
+ _suggestedStart = 0;
+
+ _totalFreeMemory = MEMORY_POOL;
// malloc memory and adjust for long boundaries
- memory_base = (uint8 *) malloc(total_free_memory);
+ memory_base = (uint8 *) malloc(_totalFreeMemory);
if (!memory_base) { //could not grab the memory
- error("Init_memory_manager() couldn't malloc %d bytes", total_free_memory);
+ error("Init_memory_manager() couldn't malloc %d bytes", _totalFreeMemory);
}
// the original malloc address
- free_memman = memory_base;
-
-#if 0
- // FIXME: I don't think it's necessary to force alignment here,
- // because memory_base is the address returned by malloc(), and
- // according to my C book "every allocated region from malloc must
- // be aligned for any type".
-
- // force to long word boundary
- memory_base += 3;
- memory_base = (uint8 *) ((uint32) memory_base & 0xfffffffc); // ** was (int)memory_base
- // total_free_memory -= 3; //play safe
-#endif
+ _freeMemman = memory_base;
// set all but first handle to unused
for (j = 1; j < MAX_mem_blocks; j++)
- mem_list[j].state = MEM_null;
+ _memList[j].state = MEM_null;
// total used (free, locked or floating)
- total_blocks = 1;
+ _totalBlocks = 1;
- mem_list[0].ad = memory_base;
- mem_list[0].state = MEM_free;
- mem_list[0].age = 0;
- mem_list[0].size = total_free_memory;
- mem_list[0].parent = -1; // we are base - for now
- mem_list[0].child = -1; // we are the end as well
- mem_list[0].uid = UID_memman; // init id
+ _memList[0].ad = memory_base;
+ _memList[0].state = MEM_free;
+ _memList[0].age = 0;
+ _memList[0].size = _totalFreeMemory;
+ _memList[0].parent = -1; // we are base - for now
+ _memList[0].child = -1; // we are the end as well
+ _memList[0].uid = UID_memman; // init id
- base_mem_block = 0; // for now
+ _baseMemBlock = 0; // for now
}
-// This is the low-level memory allocator
-
-mem *Talloc(uint32 size, uint32 type, uint32 unique_id) {
+mem *MemoryManager::lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id) {
// allocate a block of memory - locked or float
// returns 0 if fails to allocate the memory
@@ -140,23 +111,23 @@ mem *Talloc(uint32 size, uint32 type, uint32 unique_id) {
// a good time to defrag as we're probably not doing anything super
// time-critical at the moment
- if ((nu_block = Defrag_mem(size)) == -1) {
+ if ((nu_block = defragMemory(size)) == -1) {
// error - couldn't find a big enough space
return 0;
}
// an exact fit?
- if (mem_list[nu_block].size == size) {
+ if (_memList[nu_block].size == size) {
// no new block is required as the fit is perfect
- mem_list[nu_block].state = type; // locked or float
- mem_list[nu_block].size = size; // set to the required size
- mem_list[nu_block].uid = unique_id; // an identifier
+ _memList[nu_block].state = type; // locked or float
+ _memList[nu_block].size = size; // set to the required size
+ _memList[nu_block].uid = unique_id; // an identifier
#ifdef MEMDEBUG
- Mem_debug();
+ debugMemory();
#endif
- return &mem_list[nu_block];
+ return &_memList[nu_block];
}
// nu_block is the free block to split, forming our locked/float block
@@ -171,23 +142,23 @@ mem *Talloc(uint32 size, uint32 type, uint32 unique_id) {
// mini blocks. This way avoids that as the free child keeps growing
// downwards.
- if (mem_list[nu_block].child != -1 && mem_list[mem_list[nu_block].child].state == MEM_free) {
+ if (_memList[nu_block].child != -1 && _memList[_memList[nu_block].child].state == MEM_free) {
// our child is free
// the spare memory is the blocks current size minus the
// amount we're taking
- slack = mem_list[nu_block].size - size;
+ slack = _memList[nu_block].size - size;
- mem_list[nu_block].state = type; // locked or float
- mem_list[nu_block].size = size; // set to the required size
- mem_list[nu_block].uid = unique_id; // an identifier
+ _memList[nu_block].state = type; // locked or float
+ _memList[nu_block].size = size; // set to the required size
+ _memList[nu_block].uid = unique_id; // an identifier
// child starts after us
- mem_list[mem_list[nu_block].child].ad = mem_list[nu_block].ad + size;
+ _memList[_memList[nu_block].child].ad = _memList[nu_block].ad + size;
// child's size increases
- mem_list[mem_list[nu_block].child].size += slack;
+ _memList[_memList[nu_block].child].size += slack;
- return &mem_list[nu_block];
+ return &_memList[nu_block];
}
// otherwise we spawn a new block after us and before our child - our
@@ -198,61 +169,61 @@ mem *Talloc(uint32 size, uint32 type, uint32 unique_id) {
// find a NULL slot for a new block
- while (mem_list[spawn].state != MEM_null && spawn!=MAX_mem_blocks)
+ while (_memList[spawn].state != MEM_null && spawn!=MAX_mem_blocks)
spawn++;
if (spawn == MAX_mem_blocks) {
// run out of blocks - stop the program. this is a major blow
// up and we need to alert the developer
// Lets get a printout of this
- Mem_debug();
+ debugMemory();
error("Out of mem blocks in Talloc()");
}
- mem_list[spawn].state = MEM_free; // new block is free
- mem_list[spawn].uid = UID_memman; // a memman created bloc
+ _memList[spawn].state = MEM_free; // new block is free
+ _memList[spawn].uid = UID_memman; // a memman created bloc
// size of the existing parent free block minus the size of the new
// space Talloc'ed.
- mem_list[spawn].size = mem_list[nu_block].size - size;
+ _memList[spawn].size = _memList[nu_block].size - size;
// IOW the remaining memory is given to the new free block
// we start 1 byte after the newly allocated block
- mem_list[spawn].ad = mem_list[nu_block].ad + size;
+ _memList[spawn].ad = _memList[nu_block].ad + size;
// the spawned child gets it parent - the newly allocated block
- mem_list[spawn].parent = nu_block;
+ _memList[spawn].parent = nu_block;
// the new child inherits the parents old child (we are its new
// child "Waaaa")
- mem_list[spawn].child = mem_list[nu_block].child;
+ _memList[spawn].child = _memList[nu_block].child;
// is the spawn the end block?
- if (mem_list[spawn].child != -1) {
+ if (_memList[spawn].child != -1) {
// the child of the new free-spawn needs to know its new parent
- mem_list[mem_list[spawn].child].parent = spawn;
+ _memList[_memList[spawn].child].parent = spawn;
}
- mem_list[nu_block].state = type; // locked or float
- mem_list[nu_block].size = size; // set to the required size
- mem_list[nu_block].uid = unique_id; // an identifier
+ _memList[nu_block].state = type; // locked or float
+ _memList[nu_block].size = size; // set to the required size
+ _memList[nu_block].uid = unique_id; // an identifier
// the new blocks new child is the newly formed free block
- mem_list[nu_block].child = spawn;
+ _memList[nu_block].child = spawn;
//we've brought a new block into the world. Ahhh!
- total_blocks++;
+ _totalBlocks++;
#ifdef MEMDEBUG
- Mem_debug();
+ debugMemory();
#endif
- return &mem_list[nu_block];
+ return &_memList[nu_block];
}
-void Free_mem(mem *block) {
+void MemoryManager::freeMemory(mem *block) {
// kill a block of memory - which was presumably floating or locked
// once you've done this the memory may be recycled
@@ -260,22 +231,22 @@ void Free_mem(mem *block) {
block->uid = UID_memman; // belongs to the memory manager again
#ifdef MEMDEBUG
- Mem_debug();
+ debugMemory();
#endif
}
-void Float_mem(mem *block) {
+void MemoryManager::floatMemory(mem *block) {
// set a block to float
// wont be trashed but will move around in memory
block->state = MEM_float;
#ifdef MEMDEBUG
- Mem_debug();
+ debugMemory();
#endif
}
-void Lock_mem(mem *block) {
+void MemoryManager::lockMemory(mem *block) {
// set a block to lock
// wont be moved - don't lock memory for any longer than necessary
// unless you know the locked memory is at the bottom of the heap
@@ -286,11 +257,11 @@ void Lock_mem(mem *block) {
block->state = MEM_locked;
#ifdef MEMDEBUG
- Mem_debug();
+ debugMemory();
#endif
}
-int32 Defrag_mem(uint32 req_size) {
+int32 MemoryManager::defragMemory(uint32 req_size) {
// moves floating blocks down and/or merges free blocks until a large
// enough space is found or there is nothing left to do and a big
// enough block cannot be found we stop when we find/create a large
@@ -302,20 +273,20 @@ int32 Defrag_mem(uint32 req_size) {
uint32 *a;
uint32 *b;
- // cur_block = base_mem_block; //the mother of all parents
- cur_block = suggestedStart;
+ // cur_block = _baseMemBlock; //the mother of all parents
+ cur_block = _suggestedStart;
do {
// is current block a free block?
- if (mem_list[cur_block].state == MEM_free) {
- if (mem_list[cur_block].size >= req_size) {
+ if (_memList[cur_block].state == MEM_free) {
+ if (_memList[cur_block].size >= req_size) {
// this block is big enough - return its id
return cur_block;
}
// the child is the end block - stop if the next block
// along is the end block
- if (mem_list[cur_block].child == -1) {
+ if (_memList[cur_block].child == -1) {
// no luck, couldn't find a big enough block
return -1;
}
@@ -323,31 +294,31 @@ int32 Defrag_mem(uint32 req_size) {
// current free block is too small, but if its child
// is *also* free then merge the two together
- if (mem_list[mem_list[cur_block].child].state == MEM_free) {
+ if (_memList[_memList[cur_block].child].state == MEM_free) {
// ok, we nuke the child and inherit its child
- child = mem_list[cur_block].child;
+ child = _memList[cur_block].child;
// our size grows by the size of our child
- mem_list[cur_block].size += mem_list[child].size;
+ _memList[cur_block].size += _memList[child].size;
// our new child is our old childs, child
- mem_list[cur_block].child = mem_list[child].child;
+ _memList[cur_block].child = _memList[child].child;
// not if the chld we're nuking is the end
// child (it has no child)
- if (mem_list[child].child != -1) {
+ if (_memList[child].child != -1) {
// the (nuked) old childs childs
// parent is now us
- mem_list[mem_list[child].child].parent = cur_block;
+ _memList[_memList[child].child].parent = cur_block;
}
// clean up the nuked child, so it can be used
// again
- mem_list[child].state = MEM_null;
+ _memList[child].state = MEM_null;
- total_blocks--;
- } else if (mem_list[mem_list[cur_block].child].state == MEM_float) {
+ _totalBlocks--;
+ } else if (_memList[_memList[cur_block].child].state == MEM_float) {
// current free block is too small, but if its
// child is a float then we move the floating
// memory block down and the free up but,
@@ -358,7 +329,7 @@ int32 Defrag_mem(uint32 req_size) {
// positions in the memory list may become
// truly random, but, any particular block of
// locked or floating memory must retain its
- // position within the mem_list - the float
+ // position within the _memList - the float
// stays a float because the handle/pointer
// has been passed back
//
@@ -371,16 +342,16 @@ int32 Defrag_mem(uint32 req_size) {
// takes place - phew.
// our child is currently floating
- child = mem_list[cur_block].child;
+ child = _memList[cur_block].child;
// move the higher float down over the free
// block
- // memcpy(mem_list[cur_block].ad, mem_list[child].ad, mem_list[child].size);
+ // memcpy(_memList[cur_block].ad, _memList[child].ad, _memList[child].size);
- a = (uint32*) mem_list[cur_block].ad;
- b = (uint32*) mem_list[child].ad;
+ a = (uint32*) _memList[cur_block].ad;
+ b = (uint32*) _memList[child].ad;
- for (j = 0; j < mem_list[child].size / 4; j++)
+ for (j = 0; j < _memList[child].size / 4; j++)
*(a++) = *(b++);
// both *ad's change
@@ -388,34 +359,34 @@ int32 Defrag_mem(uint32 req_size) {
// free goes up by the size of the float
// (which has come down)
- mem_list[child].ad = mem_list[cur_block].ad;
- mem_list[cur_block].ad += mem_list[child].size;
+ _memList[child].ad = _memList[cur_block].ad;
+ _memList[cur_block].ad += _memList[child].size;
- // the status of the mem_list blocks must
+ // the status of the _memList blocks must
// remain the same, so...
// our child gets this when we become its
// child and it our parent
- original_parent = mem_list[cur_block].parent;
+ original_parent = _memList[cur_block].parent;
// the free's child becomes its parent
- mem_list[cur_block].parent = child;
+ _memList[cur_block].parent = child;
// the new child inherits its previous childs
// child
- mem_list[cur_block].child = mem_list[child].child;
+ _memList[cur_block].child = _memList[child].child;
// save this - see next line
- end_child = mem_list[child].child;
+ end_child = _memList[child].child;
// the floats parent becomes its child
- mem_list[child].child = cur_block;
- mem_list[child].parent = original_parent;
+ _memList[child].child = cur_block;
+ _memList[child].parent = original_parent;
// if the child had a child
if (end_child != -1) {
// then its parent is now the new child
- mem_list[end_child].parent = cur_block;
+ _memList[end_child].parent = cur_block;
}
// if the base block was the true base parent
@@ -424,33 +395,33 @@ int32 Defrag_mem(uint32 req_size) {
// becomes the base block as it sits
// at the lowest possible memory
// location
- base_mem_block = child;
+ _baseMemBlock = child;
} else {
// otherwise the parent of the current
// free block - that is now the child
// - gets a new child, that child
// being previously the child of the
// child of the original parent
- mem_list[original_parent].child = child;
+ _memList[original_parent].child = child;
}
- } else { // if (mem_list[mem_list[cur_block].child].state == MEM_lock)
+ } else { // if (_memList[_memList[cur_block].child].state == MEM_lock)
// the child of current is locked - move to it
// move to next one along - either locked or
// END
- cur_block=mem_list[cur_block].child;
+ cur_block=_memList[cur_block].child;
}
} else {
// move to next one along, the current must be
// floating, locked, or a NULL slot
- cur_block = mem_list[cur_block].child;
+ cur_block = _memList[cur_block].child;
}
} while (cur_block != -1); // while the block we've just done is not the final block
return -1; //no luck, couldn't find a big enough block
}
-void Mem_debug(void) {
- // gets called with Talloc, Mem_free, Mem_lock & Mem_float if
+void MemoryManager::debugMemory(void) {
+ // gets called with lowLevelAlloc, Mem_free, Mem_lock & Mem_float if
// MEMDEBUG has been #defined otherwise can be called at any time
// anywhere else
@@ -462,33 +433,34 @@ void Mem_debug(void) {
{ "MEM_float" }
};
- debug(5, "base %d total %d", base_mem_block, total_blocks);
+ debug(5, "base %d total %d", _baseMemBlock, _totalBlocks);
// first in mem list order
for (j = 0; j < MAX_mem_blocks; j++) {
- if (mem_list[j].state == MEM_null)
+ if (_memList[j].state == MEM_null)
debug(5, "%d- NULL", j);
else
debug(5, "%d- state %s, ad %d, size %d, p %d, c %d, id %d",
- j, inf[mem_list[j].state], mem_list[j].ad,
- mem_list[j].size, mem_list[j].parent,
- mem_list[j].child, mem_list[j].uid);
+ j, inf[_memList[j].state], _memList[j].ad,
+ _memList[j].size, _memList[j].parent,
+ _memList[j].child, _memList[j].uid);
}
// now in child/parent order
- j = base_mem_block;
+ j = _baseMemBlock;
do {
debug(5, " %d- state %s, ad %d, size %d, p %d, c %d", j,
- inf[mem_list[j].state], mem_list[j].ad,
- mem_list[j].size, mem_list[j].parent,
- mem_list[j].child, mem_list[j].uid);
+ inf[_memList[j].state], _memList[j].ad,
+ _memList[j].size, _memList[j].parent,
+ _memList[j].child, _memList[j].uid);
- j = mem_list[j].child;
+ j = _memList[j].child;
} while (j != -1);
}
-mem *Twalloc(uint32 size, uint32 type, uint32 unique_id) {
- // the high level Talloc
+mem *MemoryManager::allocMemory(uint32 size, uint32 type, uint32 unique_id) {
+ // the high level allocator
+
// can ask the resman to remove old resources to make space - will
// either do it or halt the system
@@ -496,26 +468,26 @@ mem *Twalloc(uint32 size, uint32 type, uint32 unique_id) {
int j;
uint32 free = 0;
- while (VirtualDefrag(size)) {
+ while (virtualDefrag(size)) {
// trash the oldest closed resource
if (!res_man.helpTheAgedOut()) {
- error("Twalloc ran out of memory: size=%d type=%d unique_id=%d", size, type, unique_id);
+ error("alloc ran out of memory: size=%d type=%d unique_id=%d", size, type, unique_id);
}
}
- membloc = Talloc(size, type, unique_id);
+ membloc = lowLevelAlloc(size, type, unique_id);
if (membloc == 0) {
- error("Talloc failed to get memory VirtualDefrag said was there");
+ error("lowLevelAlloc failed to get memory virtualDefrag said was there");
}
- j = base_mem_block;
+ j = _baseMemBlock;
do {
- if (mem_list[j].state == MEM_free)
- free += mem_list[j].size;
+ if (_memList[j].state == MEM_free)
+ free += _memList[j].size;
- j = mem_list[j].child;
+ j = _memList[j].child;
} while (j != -1);
// return the pointer to the memory
@@ -525,13 +497,13 @@ mem *Twalloc(uint32 size, uint32 type, uint32 unique_id) {
// Maximum allowed wasted memory.
#define MAX_WASTAGE 51200
-int32 VirtualDefrag(uint32 size) {
+int32 MemoryManager::virtualDefrag(uint32 size) {
// Virutually defrags memory...
//
// Used to determine if there is potentially are large enough free
// block available is the real defragger was allowed to run.
//
- // The idea being that Twalloc will call this and help_the_aged_out
+ // The idea being that alloc will call this and help_the_aged_out
// until we indicate that it is possible to obtain a large enough
// free block. This way the defragger need only run once to yield the
// required block size.
@@ -543,11 +515,11 @@ int32 VirtualDefrag(uint32 size) {
int32 cur_block;
uint32 currentBubbleSize = 0;
- cur_block = base_mem_block;
- suggestedStart = base_mem_block;
+ cur_block = _baseMemBlock;
+ _suggestedStart = _baseMemBlock;
do {
- if (mem_list[cur_block].state == MEM_free) {
+ if (_memList[cur_block].state == MEM_free) {
// Add a little intelligence. At the start the oldest
// resources are at the bottom of the tube. However
// there will be some air at the top. Thus bubbles
@@ -556,21 +528,21 @@ int32 VirtualDefrag(uint32 size) {
// bubble will form lower down the tube. Thus less
// memory will need to be shifted.
- if (mem_list[cur_block].child != -1)
- currentBubbleSize += mem_list[cur_block].size;
- else if (mem_list[cur_block].size > MAX_WASTAGE)
- currentBubbleSize += mem_list[cur_block].size;
+ if (_memList[cur_block].child != -1)
+ currentBubbleSize += _memList[cur_block].size;
+ else if (_memList[cur_block].size > MAX_WASTAGE)
+ currentBubbleSize += _memList[cur_block].size;
if (currentBubbleSize >= size)
return 0;
- } else if (mem_list[cur_block].state == MEM_locked) {
+ } else if (_memList[cur_block].state == MEM_locked) {
currentBubbleSize = 0;
// Any free block of the correct size will be above
// this locked block.
- suggestedStart = mem_list[cur_block].child;
+ _suggestedStart = _memList[cur_block].child;
}
- cur_block = mem_list[cur_block].child;
+ cur_block = _memList[cur_block].child;
} while (cur_block != -1);
return 1;
diff --git a/sword2/memory.h b/sword2/memory.h
index 6a1fa6c7bb..5c83ee12dd 100644
--- a/sword2/memory.h
+++ b/sword2/memory.h
@@ -60,19 +60,46 @@ typedef struct {
#define UID_savegame_buffer 0xfffffff6
#define UID_restoregame_buffer 0xfffffff5
-void Init_memory_manager(void);
-void Close_memory_manager(void); // Tony2Oct96
-mem *Twalloc(uint32 size, uint32 type, uint32 unique_id); // high level
-void Free_mem(mem *block);
-void Float_mem(mem *block);
-void Lock_mem(mem *block);
-void Mem_debug(void);
-void Visual_mem_display(void);
-int32 Defrag_mem(uint32 req_size); // Tony10Apr96
-
-extern uint32 total_blocks;
-extern uint32 base_mem_block;
-extern mem mem_list[MAX_mem_blocks];
-extern uint32 total_free_memory;
+class MemoryManager {
+private:
+ // Address of init malloc to be freed later
+ uint8 *_freeMemman;
+
+ uint32 _totalFreeMemory;
+ uint32 _totalBlocks;
+
+ // Start position of the defragger as indicated by its sister,
+ // VirtualDefrag.
+ int32 _suggestedStart;
+
+ mem *lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id);
+ int32 defragMemory(uint32 req_size);
+
+ // Used to determine if the required size can be obtained if the
+ // defragger is allowed to run.
+ int32 virtualDefrag(uint32 size);
+
+ // Debugging functions
+ void debugMemory(void);
+ const char *fetchOwner(uint32 uid);
+ void memoryString(char *string);
+
+public:
+ // List of defined memory handles - each representing a block of memory
+ mem _memList[MAX_mem_blocks];
+ uint32 _baseMemBlock;
+
+ void init(void);
+ void exit(void);
+ mem *allocMemory(uint32 size, uint32 type, uint32 unique_id);
+ void freeMemory(mem *block);
+ void floatMemory(mem *block);
+ void lockMemory(mem *block);
+
+ // Debugging function
+ void displayMemory(void);
+};
+
+extern MemoryManager memory;
#endif
diff --git a/sword2/resman.cpp b/sword2/resman.cpp
index 5c844f809a..f059e62094 100644
--- a/sword2/resman.cpp
+++ b/sword2/resman.cpp
@@ -111,7 +111,7 @@ void ResourceManager::init(void) {
end = file.size();
//get some space for the incoming resource file - soon to be trashed
- temp = Twalloc(end, MEM_locked, UID_temp);
+ temp = memory.allocMemory(end, MEM_locked, UID_temp);
if (file.read(temp->ad, end) != end) {
file.close();
@@ -213,7 +213,7 @@ void ResourceManager::init(void) {
}
_resTime = 1; //cannot start at 0
- Free_mem(temp); //get that memory back
+ memory.freeMemory(temp); //get that memory back
// FIXME: Is this really needed?
@@ -533,12 +533,7 @@ uint8 *ResourceManager::open(uint32 res) {
// ok, we know the length so try and allocate the memory
// if it can't then old files will be ditched until it works
- _resList[res] = Twalloc(len, MEM_locked, res);
-
-/* This probably isn't needed
- // Do a quick ServiceWindows to stop the music screwing up.
- ServiceWindows();
-*/
+ _resList[res] = memory.allocMemory(len, MEM_locked, res);
// now load the file
// hurray, load it in.
@@ -563,7 +558,7 @@ uint8 *ResourceManager::open(uint32 res) {
// pass the address of the mem & lock the memory too
// might be locked already (if count > 1)
- Lock_mem(_resList[res]);
+ memory.lockMemory(_resList[res]);
return (uint8 *) _resList[res]->ad;
}
@@ -642,7 +637,8 @@ void ResourceManager::close(uint32 res) {
//if noone has the file open then unlock and allow to float
if (!_count[res]) {
- Float_mem(_resList[res]); // pass the address of the mem
+ // pass the address of the mem
+ memory.floatMemory(_resList[res]);
}
}
@@ -732,7 +728,7 @@ uint32 ResourceManager::helpTheAgedOut(void) {
// trash this old resource
_age[oldest_res] = 0; // effectively gone from _resList
- Free_mem(_resList[oldest_res]); // release the memory too
+ memory.freeMemory(_resList[oldest_res]); // release the memory too
return _resList[oldest_res]->size; // return bytes freed
}
@@ -890,7 +886,7 @@ void ResourceManager::kill(uint8 *input) {
if (!_count[res]) {
if (_age[res]) {
_age[res] = 0; // effectively gone from _resList
- Free_mem(_resList[res]); // release the memory too
+ memory.freeMemory(_resList[res]); // release the memory too
Print_to_console(" trashed %d", res);
} else
Print_to_console("%d not in memory", res);
@@ -904,7 +900,7 @@ void ResourceManager::kill(uint8 *input) {
void ResourceManager::remove(uint32 res) {
if (_age[res]) {
_age[res] = 0; // effectively gone from _resList
- Free_mem(_resList[res]); // release the memory too
+ memory.freeMemory(_resList[res]); // release the memory too
debug(5, " - Trashing %d", res);
} else
debug(5, "remove(%d) not even in memory!", res);
@@ -917,16 +913,16 @@ void ResourceManager::removeAll(void) {
int j;
uint32 res;
- j = base_mem_block;
+ j = memory._baseMemBlock;
do {
- if (mem_list[j].uid < 65536) { // a resource
- res = mem_list[j].uid;
+ if (memory._memList[j].uid < 65536) { // a resource
+ res = memory._memList[j].uid;
_age[res] = 0; // effectively gone from _resList
- Free_mem(_resList[res]); // release the memory too
+ memory.freeMemory(_resList[res]); // release the memory too
}
- j = mem_list[j].child;
+ j = memory._memList[j].child;
} while (j != -1);
}
@@ -942,11 +938,11 @@ void ResourceManager::killAll(uint8 wantInfo) {
int scrolls = 0;
_keyboardEvent ke;
- j = base_mem_block;
+ j = memory._baseMemBlock;
do {
- if (mem_list[j].uid < 65536) { // a resource
- res = mem_list[j].uid;
+ if (memory._memList[j].uid < 65536) { // a resource
+ res = memory._memList[j].uid;
// not the global vars which are assumed to be open in
// memory & not the player object!
@@ -955,7 +951,7 @@ void ResourceManager::killAll(uint8 wantInfo) {
res_man.close(res);
_age[res] = 0; // effectively gone from _resList
- Free_mem(_resList[res]); // release the memory too
+ memory.freeMemory(_resList[res]); // release the memory too
nuked++;
// if this was called from the console + we
@@ -985,7 +981,7 @@ void ResourceManager::killAll(uint8 wantInfo) {
}
}
}
- j = mem_list[j].child;
+ j = memory._memList[j].child;
} while (j != -1);
// if this was called from the console + we want info!
@@ -1015,20 +1011,20 @@ void ResourceManager::killAllObjects(uint8 wantInfo) {
int scrolls = 0;
_keyboardEvent ke;
- j = base_mem_block;
+ j = memory._baseMemBlock;
do {
- if (mem_list[j].uid < 65536) { //a resource
- res=mem_list[j].uid;
+ if (memory._memList[j].uid < 65536) { // a resource
+ res = memory._memList[j].uid;
//not the global vars which are assumed to be open in
- // memory & not the player object! (James17jan97)
+ // memory & not the player object!
if (res != 1 && res != CUR_PLAYER_ID) {
header = (_standardHeader*) res_man.open(res);
res_man.close(res);
if (header->fileType == GAME_OBJECT) {
_age[res] = 0; // effectively gone from _resList
- Free_mem(_resList[res]); // release the memory too
+ memory.freeMemory(_resList[res]); // release the memory too
nuked++;
// if this was called from the console + we want info
@@ -1059,7 +1055,7 @@ void ResourceManager::killAllObjects(uint8 wantInfo) {
}
}
}
- j = mem_list[j].child;
+ j = memory._memList[j].child;
} while (j != -1);
// if this was called from the console + we want info
@@ -1266,7 +1262,7 @@ void ResourceManager::cacheNewCluster(uint32 newCluster) {
inFile.close();
outFile.close();
- Free_mem(text_spr);
+ memory.freeMemory(text_spr);
EraseBackBuffer();
@@ -1436,6 +1432,6 @@ void ResourceManager::getCd(int cd) {
spriteInfo.x = oldX;
} while (!done);
- Free_mem(text_spr);
+ memory.freeMemory(text_spr);
RemoveMsg();
}
diff --git a/sword2/resman.h b/sword2/resman.h
index 089f214077..d388fefdb6 100644
--- a/sword2/resman.h
+++ b/sword2/resman.h
@@ -24,11 +24,6 @@
#define MAX_res_files 20
-#if 0
-#define RES_locked 1
-#define RES_perm 2
-#endif
-
class ResourceManager {
public:
void init(void); // read in the config file
diff --git a/sword2/router.cpp b/sword2/router.cpp
index b64c5c2b42..c581463f90 100644
--- a/sword2/router.cpp
+++ b/sword2/router.cpp
@@ -272,7 +272,7 @@ void AllocateRouteMem(void) {
if (route_slots[slotNo])
FreeRouteMem();
- route_slots[slotNo] = Twalloc(sizeof(_walkData) * O_WALKANIM_SIZE, MEM_locked, UID_walk_anim);
+ route_slots[slotNo] = memory.allocMemory(sizeof(_walkData) * O_WALKANIM_SIZE, MEM_locked, UID_walk_anim);
// 12000 bytes were used for this in Sword1 mega compacts, based on
// 20 bytes per '_walkData' frame
@@ -290,14 +290,14 @@ void AllocateRouteMem(void) {
_walkData* LockRouteMem(void) {
uint8 slotNo = ReturnSlotNo(ID);
- Lock_mem(route_slots[slotNo]);
+ memory.lockMemory(route_slots[slotNo]);
return (_walkData *) route_slots[slotNo]->ad;
}
void FloatRouteMem(void) {
uint8 slotNo = ReturnSlotNo(ID);
- Float_mem(route_slots[slotNo]);
+ memory.floatMemory(route_slots[slotNo]);
}
void FreeRouteMem(void) {
@@ -305,7 +305,7 @@ void FreeRouteMem(void) {
// free the mem block pointed to from this entry of route_slots[]
- Free_mem(route_slots[slotNo]);
+ memory.freeMemory(route_slots[slotNo]);
route_slots[slotNo] = NULL;
}
@@ -314,7 +314,7 @@ void FreeAllRouteMem(void) {
if (route_slots[slotNo]) {
// free the mem block pointed to from this entry of
// route_slots[]
- Free_mem(route_slots[slotNo]);
+ memory.freeMemory(route_slots[slotNo]);
route_slots[slotNo] = NULL;
}
}
diff --git a/sword2/save_rest.cpp b/sword2/save_rest.cpp
index 1040232c2f..8d9ff09b39 100644
--- a/sword2/save_rest.cpp
+++ b/sword2/save_rest.cpp
@@ -143,7 +143,7 @@ uint32 SaveGame(uint16 slotNo, uint8 *desc) {
// allocate the savegame buffer
bufferSize = FindBufferSize();
- saveBufferMem = Twalloc(bufferSize, MEM_locked, UID_savegame_buffer);
+ saveBufferMem = memory.allocMemory(bufferSize, MEM_locked, UID_savegame_buffer);
FillSaveBuffer(saveBufferMem, bufferSize, desc);
@@ -154,7 +154,7 @@ uint32 SaveGame(uint16 slotNo, uint8 *desc) {
// free the buffer
- Free_mem(saveBufferMem);
+ memory.freeMemory(saveBufferMem);
return errorCode;
}
@@ -273,7 +273,7 @@ uint32 RestoreGame(uint16 slotNo) {
// allocate the savegame buffer
bufferSize = FindBufferSize();
- saveBufferMem = Twalloc(bufferSize, MEM_locked, UID_savegame_buffer);
+ saveBufferMem = memory.allocMemory(bufferSize, MEM_locked, UID_savegame_buffer);
// read the savegame file into our buffer
@@ -291,7 +291,7 @@ uint32 RestoreGame(uint16 slotNo) {
// loading in the new screen & runlist
} else {
// because RestoreFromBuffer would have freed it
- Free_mem(saveBufferMem);
+ memory.freeMemory(saveBufferMem);
}
return errorCode;
@@ -354,7 +354,7 @@ uint32 RestoreFromBuffer(mem *buffer, uint32 size) {
// (James05aug97)
if (g_header.checksum != CalcChecksum(buffer->ad + sizeof(g_header.checksum), size - sizeof(g_header.checksum))) {
- Free_mem(buffer);
+ memory.freeMemory(buffer);
// error: incompatible save-data - can't use!
return SR_ERR_INCOMPATIBLE;
@@ -369,7 +369,7 @@ uint32 RestoreFromBuffer(mem *buffer, uint32 size) {
// if header contradicts actual current size of global variables
if (g_header.varLength != res_man.fetchLen(1)) {
- Free_mem(buffer);
+ memory.freeMemory(buffer);
// error: incompatible save-data - can't use!
return SR_ERR_INCOMPATIBLE;
@@ -415,7 +415,7 @@ uint32 RestoreFromBuffer(mem *buffer, uint32 size) {
// free it now, rather than in RestoreGame, to unblock memory before
// new screen & runlist loaded
- Free_mem(buffer);
+ memory.freeMemory(buffer);
pars[0] = g_header.screenId;
pars[1] = 1;
diff --git a/sword2/startup.cpp b/sword2/startup.cpp
index 5aad72b40b..4009f3451b 100644
--- a/sword2/startup.cpp
+++ b/sword2/startup.cpp
@@ -134,7 +134,7 @@ uint32 Init_start_menu(void) {
debug(5, "- resource %d invalid", res);
}
- Free_mem(temp); // release the Talloc
+ memory.freeMemory(temp);
return 1;
}
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
index 4e97f904b6..474b36a78c 100644
--- a/sword2/sword2.cpp
+++ b/sword2/sword2.cpp
@@ -49,6 +49,8 @@
#include "bs2/driver/driver96.h"
#include "bs2/driver/palette.h"
+extern uint16 _debugLevel;
+
uint8 quitGame = 0;
// version & owner details
@@ -106,6 +108,7 @@ Sword2State::Sword2State(GameDetector *detector, OSystem *syst)
_game_name = strdup(detector->_gameFileName.c_str());
_bootParam = detector->_bootParam;
_saveSlot = detector->_save_slot;
+ _debugLevel = detector->_debugLevel;
// Setup mixer
if (!_mixer->bindToSystem(syst))
@@ -134,8 +137,8 @@ int32 Sword2State::InitialiseGame(void) {
// get some falling RAM and put it in your pocket, never let it slip
// away
- debug(5, "CALLING: Init_memory_manager");
- Init_memory_manager();
+ debug(5, "CALLING: memory.init");
+ memory.init();
// initialise the resource manager
debug(5, "CALLING: res_man.init");
@@ -205,7 +208,7 @@ void Close_game() {
Kill_music();
// free the memory again
- Close_memory_manager();
+ memory.exit();
res_man.exit();
}
diff --git a/sword2/tony_gsdk.cpp b/sword2/tony_gsdk.cpp
index 537a7c8776..4138993071 100644
--- a/sword2/tony_gsdk.cpp
+++ b/sword2/tony_gsdk.cpp
@@ -44,7 +44,7 @@ uint32 Read_file(const char *name, mem **membloc, uint32 uid) {
size = fh.size();
// reserve enough floating memory for the file
- *membloc = Twalloc(size, MEM_float, uid);
+ *membloc = memory.allocMemory(size, MEM_float, uid);
if (fh.read((*membloc)->ad, size) != size) {
debug(5, "Read_file read fail %d", name);