diff options
-rw-r--r-- | sword2/anims.cpp | 4 | ||||
-rw-r--r-- | sword2/build_display.cpp | 2 | ||||
-rw-r--r-- | sword2/console.cpp | 6 | ||||
-rw-r--r-- | sword2/driver/d_draw.cpp | 2 | ||||
-rw-r--r-- | sword2/maketext.cpp | 10 | ||||
-rw-r--r-- | sword2/mem_view.cpp | 67 | ||||
-rw-r--r-- | sword2/mem_view.h | 27 | ||||
-rw-r--r-- | sword2/memory.cpp | 288 | ||||
-rw-r--r-- | sword2/memory.h | 55 | ||||
-rw-r--r-- | sword2/resman.cpp | 58 | ||||
-rw-r--r-- | sword2/resman.h | 5 | ||||
-rw-r--r-- | sword2/router.cpp | 10 | ||||
-rw-r--r-- | sword2/save_rest.cpp | 14 | ||||
-rw-r--r-- | sword2/startup.cpp | 2 | ||||
-rw-r--r-- | sword2/sword2.cpp | 9 | ||||
-rw-r--r-- | sword2/tony_gsdk.cpp | 2 |
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); |