From 8f8185f035d747c720371d88de90c54e43a543d0 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Fri, 23 Apr 2004 07:02:11 +0000 Subject: Major revamping of the BS2 memory manager and, some small changes to the resource manager. All new code! All new bugs! svn-id: r13603 --- NEWS | 3 +- sword2/anims.cpp | 55 ++-- sword2/build_display.cpp | 54 ++-- sword2/console.cpp | 2 +- sword2/console.h | 2 +- sword2/controls.cpp | 60 ++--- sword2/debug.cpp | 4 +- sword2/driver/_mouse.cpp | 18 +- sword2/driver/animation.cpp | 24 +- sword2/driver/animation.h | 8 +- sword2/driver/d_draw.h | 36 +-- sword2/driver/d_sound.cpp | 10 +- sword2/driver/driver96.h | 4 +- sword2/driver/menu.cpp | 4 +- sword2/driver/palette.cpp | 6 +- sword2/driver/render.cpp | 16 +- sword2/driver/sprite.cpp | 44 ++-- sword2/events.cpp | 2 +- sword2/function.cpp | 28 +- sword2/header.h | 2 +- sword2/icons.cpp | 6 +- sword2/interpreter.cpp | 10 +- sword2/layers.cpp | 6 +- sword2/logic.h | 2 +- sword2/maketext.cpp | 64 +++-- sword2/maketext.h | 16 +- sword2/mem_view.cpp | 164 ------------ sword2/memory.cpp | 625 ++++++++++---------------------------------- sword2/memory.h | 90 ++----- sword2/module.mk | 1 - sword2/mouse.cpp | 29 +- sword2/protocol.cpp | 57 ++-- sword2/resman.cpp | 594 +++++++++++++++++------------------------ sword2/resman.h | 47 ++-- sword2/router.cpp | 41 +-- sword2/router.h | 5 +- sword2/save_rest.cpp | 78 +++--- sword2/sound.cpp | 4 +- sword2/speech.cpp | 30 +-- sword2/startup.cpp | 4 +- sword2/sword2.cpp | 3 - sword2/sword2.h | 50 ++-- sword2/walker.cpp | 49 ++-- 43 files changed, 806 insertions(+), 1551 deletions(-) delete mode 100644 sword2/mem_view.cpp diff --git a/NEWS b/NEWS index 043a0b4d73..6064044c6c 100644 --- a/NEWS +++ b/NEWS @@ -22,7 +22,8 @@ For a more comprehensive changelog for the latest experimental CVS code, see: - ??? [TODO: Somebody of the Sword1 team please fill this in] Sword2: - - Various fixes [TODO: Somebody of the Sword2 team please fill this in] + - Simplified the memory/resource management. + - Various minor bugfixes. BASS - ??? diff --git a/sword2/anims.cpp b/sword2/anims.cpp index d78b9aefec..98a2913527 100644 --- a/sword2/anims.cpp +++ b/sword2/anims.cpp @@ -81,9 +81,9 @@ int32 Logic::animate(int32 *params, bool reverse) { // 1 pointer to object's graphic structure // 2 resource id of animation file - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); - ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[1]); - uint8 *anim_file; + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); + ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[1]); + byte *anim_file; AnimHeader *anim_head; int32 res = params[2]; @@ -202,11 +202,11 @@ int32 Logic::megaTableAnimate(int32 *params, bool reverse) { // If this is the start of the anim, read the anim table to get the // appropriate anim resource - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); if (ob_logic->looping == 0) { - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]); - uint32 *anim_table = (uint32 *) _vm->_memory->intToPtr(params[3]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]); + uint32 *anim_table = (uint32 *) _vm->_memory->decodePtr(params[3]); // appropriate anim resource is in 'table[direction]' pars[2] = anim_table[ob_mega->current_dir]; @@ -224,7 +224,7 @@ int32 Logic::fnSetFrame(int32 *params) { assert(res); // open the resource (& check it's valid) - uint8 *anim_file = _vm->_resman->openResource(res); + byte *anim_file = _vm->_resman->openResource(res); StandardHeader *head = (StandardHeader *) anim_file; assert(head->fileType == ANIMATION_FILE); @@ -233,7 +233,7 @@ int32 Logic::fnSetFrame(int32 *params) { AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file); // set up anim resource in graphic object - ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[0]); + ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[0]); ob_graphic->anim_resource = res; ob_graphic->anim_pc = params[2] ? anim_head->noAnimFrames - 1 : 0; @@ -244,14 +244,14 @@ int32 Logic::fnSetFrame(int32 *params) { } void Logic::setSpriteStatus(uint32 sprite, uint32 type) { - ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(sprite); + ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(sprite); // Remove the previous status, but don't affect the shading upper-word ob_graphic->type = (ob_graphic->type & 0xffff0000) | type; } void Logic::setSpriteShading(uint32 sprite, uint32 type) { - ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(sprite); + ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(sprite); // Remove the previous shading, but don't affect the status lower-word. // Note that drivers may still shade mega frames automatically, even @@ -338,7 +338,7 @@ void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) { FrameHeader *frame; uint32 local_text; uint32 text_res; - uint8 *text; + byte *text; uint32 wavId; // ie. offical text number (actor text number) bool speechRunning; char speechFile[256]; @@ -426,19 +426,14 @@ void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) { // MovieTextObject's sequenceText[_sequenceTextLines] = NULL; - // now lock all the memory blocks containing text sprites & speech - // samples and set up the pointers to them, etc, for the drivers - for (line = 0; line < _sequenceTextLines; line++) { // if we've made a text sprite for this line... if (_sequenceTextList[line].text_mem) { - _vm->_memory->lockMemory(_sequenceTextList[line].text_mem); - // now fill out the SpriteInfo structure in the // MovieTextObjectStructure - frame = (FrameHeader *) _sequenceTextList[line].text_mem->ad; + frame = (FrameHeader *) _sequenceTextList[line].text_mem; sequenceText[line]->textSprite = new SpriteInfo; @@ -448,7 +443,7 @@ void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) { sequenceText[line]->textSprite->w = frame->width; sequenceText[line]->textSprite->h = frame->height; sequenceText[line]->textSprite->type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION; - sequenceText[line]->textSprite->data = _sequenceTextList[line].text_mem->ad + sizeof(FrameHeader); + sequenceText[line]->textSprite->data = _sequenceTextList[line].text_mem + sizeof(FrameHeader); } // if we've loaded a speech sample for this line... @@ -464,19 +459,17 @@ void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) { } void Logic::clearSequenceSpeech(MovieTextObject *sequenceText[]) { - uint32 line; - - for (line = 0; line < _sequenceTextLines; line++) { + for (uint i = 0; i < _sequenceTextLines; i++) { // free up the memory used by this MovieTextObject - delete sequenceText[line]; + delete sequenceText[i]; // free up the mem block containing this text sprite - if (_sequenceTextList[line].text_mem) - _vm->_memory->freeMemory(_sequenceTextList[line].text_mem); + if (_sequenceTextList[i].text_mem) + free(_sequenceTextList[i].text_mem); // free up the mem block containing this speech sample - if (_sequenceTextList[line].speech_mem) - free(_sequenceTextList[line].speech_mem); + if (_sequenceTextList[i].speech_mem) + free(_sequenceTextList[i].speech_mem); } // IMPORTANT! Reset the line count ready for the next sequence! @@ -484,7 +477,7 @@ void Logic::clearSequenceSpeech(MovieTextObject *sequenceText[]) { } int32 Logic::fnSmackerLeadIn(int32 *params) { - uint8 *leadIn; + byte *leadIn; uint32 rv; // params: 0 id of lead-in music @@ -521,18 +514,18 @@ int32 Logic::fnPlaySequence(int32 *params) { char filename[30]; MovieTextObject *sequenceSpeechArray[MAX_SEQUENCE_TEXT_LINES + 1]; - uint8 *leadOut = NULL; + byte *leadOut = NULL; // The original code had some #ifdef blocks for skipping or muting the // cutscenes - fondly described as "the biggest fudge in the history // of computer games" - but at the very least we want to show the // cutscene subtitles, so I removed them. - debug(5, "fnPlaySequence(\"%s\");", (const char *) _vm->_memory->intToPtr(params[0])); + debug(5, "fnPlaySequence(\"%s\");", (const char *) _vm->_memory->decodePtr(params[0])); // add the appropriate file extension & play it - strcpy(filename, (const char *) _vm->_memory->intToPtr(params[0])); + strcpy(filename, (const char *) _vm->_memory->decodePtr(params[0])); // Write to walkthrough file (zebug0.txt) debug(5, "PLAYING SEQUENCE \"%s\"", filename); @@ -598,7 +591,7 @@ int32 Logic::fnPlaySequence(int32 *params) { PalEntry pal[256]; memset(pal, 0, 256 * sizeof(PalEntry)); - _vm->_graphics->setPalette(0, 256, (uint8 *) pal, RDPAL_INSTANT); + _vm->_graphics->setPalette(0, 256, (byte *) pal, RDPAL_INSTANT); debug(5, "fnPlaySequence FINISHED"); return IR_CONT; diff --git a/sword2/build_display.cpp b/sword2/build_display.cpp index 794645b9c1..1072960708 100644 --- a/sword2/build_display.cpp +++ b/sword2/build_display.cpp @@ -53,7 +53,7 @@ void Sword2Engine::buildDisplay(void) { _graphics->animateMouse(); _graphics->startRenderCycle(); - uint8 *file = _resman->openResource(_thisScreen.background_layer_id); + byte *file = _resman->openResource(_thisScreen.background_layer_id); MultiScreenHeader *screenLayerTable = (MultiScreenHeader *) (file + sizeof(StandardHeader)); // Render at least one frame, but if the screen is scrolling, and if @@ -118,7 +118,7 @@ void Sword2Engine::buildDisplay(void) { * @param time The number of seconds to display the message */ -void Sword2Engine::displayMsg(uint8 *text, int time) { +void Sword2Engine::displayMsg(byte *text, int time) { PalEntry pal[256]; PalEntry oldPal[256]; @@ -135,8 +135,8 @@ void Sword2Engine::displayMsg(uint8 *text, int time) { _graphics->closeMenuImmediately(); _graphics->clearScene(); - Memory *text_spr = _fontRenderer->makeTextSprite(text, 640, 187, _speechFontId); - FrameHeader *frame = (FrameHeader *) text_spr->ad; + byte *text_spr = _fontRenderer->makeTextSprite(text, 640, 187, _speechFontId); + FrameHeader *frame = (FrameHeader *) text_spr; SpriteInfo spriteInfo; @@ -152,7 +152,7 @@ void Sword2Engine::displayMsg(uint8 *text, int time) { spriteInfo.scaledHeight = 0; spriteInfo.type = RDSPR_DISPLAYALIGN | RDSPR_NOCOMPRESSION | RDSPR_TRANS; spriteInfo.blend = 0; - spriteInfo.data = text_spr->ad + sizeof(FrameHeader); + spriteInfo.data = text_spr + sizeof(FrameHeader); spriteInfo.colourTable = 0; uint32 rv = _graphics->drawSprite(&spriteInfo); @@ -166,15 +166,15 @@ void Sword2Engine::displayMsg(uint8 *text, int time) { pal[187].green = 255; pal[187].blue = 255; - _graphics->setPalette(0, 256, (uint8 *) pal, RDPAL_FADE); + _graphics->setPalette(0, 256, (byte *) pal, RDPAL_FADE); _graphics->fadeUp(); - _memory->freeMemory(text_spr); + free(text_spr); _graphics->waitForFade(); uint32 targetTime = _system->get_msecs() + (time * 1000); sleepUntil(targetTime); - _graphics->setPalette(0, 256, (uint8 *) oldPal, RDPAL_FADE); + _graphics->setPalette(0, 256, (byte *) oldPal, RDPAL_FADE); } /** @@ -211,7 +211,7 @@ void Sword2Engine::drawBackFrames(void) { processImage(&_backList[i]); } -void Sword2Engine::drawSortFrames(uint8 *file) { +void Sword2Engine::drawSortFrames(byte *file) { uint i, j; // Sort the sort list. Used to be a separate function, but it was only @@ -260,7 +260,7 @@ void Sword2Engine::drawForePar1Frames(void) { processImage(&_fgp1List[i]); } -void Sword2Engine::processLayer(uint8 *file, uint32 layer_number) { +void Sword2Engine::processLayer(byte *file, uint32 layer_number) { LayerHeader *layer_head = fetchLayerHeader(file, layer_number); SpriteInfo spriteInfo; @@ -295,8 +295,8 @@ void Sword2Engine::processLayer(uint8 *file, uint32 layer_number) { } void Sword2Engine::processImage(BuildUnit *build_unit) { - uint8 *file = _resman->openResource(build_unit->anim_resource); - uint8 *colTablePtr = NULL; + byte *file = _resman->openResource(build_unit->anim_resource); + byte *colTablePtr = NULL; AnimHeader *anim_head = fetchAnimHeader(file); CdtEntry *cdt_entry = fetchCdtEntry(file, build_unit->anim_pc); @@ -337,7 +337,7 @@ void Sword2Engine::processImage(BuildUnit *build_unit) { spriteType |= RDSPR_RLE16; // points to just after last cdt_entry, ie. // start of colour table - colTablePtr = (uint8 *) (anim_head + 1) + anim_head->noAnimFrames * sizeof(CdtEntry); + colTablePtr = (byte *) (anim_head + 1) + anim_head->noAnimFrames * sizeof(CdtEntry); break; } } @@ -359,7 +359,7 @@ void Sword2Engine::processImage(BuildUnit *build_unit) { spriteInfo.type = spriteType; spriteInfo.blend = anim_head->blend; // points to just after frame header, ie. start of sprite data - spriteInfo.data = (uint8 *) (frame_head + 1); + spriteInfo.data = (byte *) (frame_head + 1); spriteInfo.colourTable = colTablePtr; // check for largest layer for debug info @@ -434,10 +434,10 @@ void Sword2Engine::registerFrame(int32 *params, BuildUnit *build_unit) { // 1 pointer to graphic structure // 2 pointer to mega structure - ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->intToPtr(params[1]); + ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->decodePtr(params[1]); assert(ob_graph->anim_resource); - uint8 *file = _resman->openResource(ob_graph->anim_resource); + byte *file = _resman->openResource(ob_graph->anim_resource); AnimHeader *anim_head = fetchAnimHeader(file); CdtEntry *cdt_entry = fetchCdtEntry(file, ob_graph->anim_pc); @@ -469,7 +469,7 @@ void Sword2Engine::registerFrame(int32 *params, BuildUnit *build_unit) { int scale = 0; if (cdt_entry->frameType & FRAME_OFFSET) { - ObjectMega *ob_mega = (ObjectMega *) _memory->intToPtr(params[2]); + ObjectMega *ob_mega = (ObjectMega *) _memory->decodePtr(params[2]); // calc scale at which to print the sprite, based on feet // y-coord & scaling constants (NB. 'scale' is actually @@ -508,7 +508,7 @@ void Sword2Engine::registerFrame(int32 *params, BuildUnit *build_unit) { if (params[0]) { // passed a mouse structure, so add to the _mouseList - ObjectMouse *ob_mouse = (ObjectMouse *) _memory->intToPtr(params[0]); + ObjectMouse *ob_mouse = (ObjectMouse *) _memory->decodePtr(params[0]); if (ob_mouse->pointer) { assert(_curMouse < TOTAL_mouse_list); @@ -557,7 +557,7 @@ int32 Logic::fnRegisterFrame(int32 *params) { } int32 Sword2Engine::registerFrame(int32 *params) { - ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->intToPtr(params[1]); + ObjectGraphic *ob_graph = (ObjectGraphic *) _memory->decodePtr(params[1]); // check low word for sprite type switch (ob_graph->type & 0x0000ffff) { @@ -605,18 +605,18 @@ int32 Sword2Engine::registerFrame(int32 *params) { return IR_CONT; } -void Sword2Engine::startNewPalette(void) { - // start layer palette fading up - - uint8 *screenFile; +/** + * Start layer palette fading up + */ +void Sword2Engine::startNewPalette(void) { // if the screen is still fading down then wait for black - could // happen when everythings cached into a large memory model _graphics->waitForFade(); - screenFile = _resman->openResource(_thisScreen.background_layer_id); + byte *screenFile = _resman->openResource(_thisScreen.background_layer_id); - _graphics->updatePaletteMatchTable((uint8 *) fetchPaletteMatchTable(screenFile)); + _graphics->updatePaletteMatchTable((byte *) fetchPaletteMatchTable(screenFile)); _graphics->setPalette(0, 256, fetchPalette(screenFile), RDPAL_FADE); // indicating that it's a screen palette @@ -632,7 +632,7 @@ int32 Logic::fnUpdatePlayerStats(int32 *params) { // params: 0 pointer to mega structure - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[0]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[0]); _vm->_thisScreen.player_feet_x = ob_mega->feet_x; _vm->_thisScreen.player_feet_y = ob_mega->feet_y; @@ -715,7 +715,7 @@ void Sword2Engine::setFullPalette(int32 palRes) { // If non-zero, set palette to this separate palette file. Otherwise, // set palette to current screen palette. - uint8 *file; + byte *file; if (palRes) { file = _resman->openResource(palRes); diff --git a/sword2/console.cpp b/sword2/console.cpp index d6ece7c1ac..b96394a0dd 100644 --- a/sword2/console.cpp +++ b/sword2/console.cpp @@ -172,7 +172,7 @@ bool Debugger::Cmd_Help(int argc, const char **argv) { } bool Debugger::Cmd_Mem(int argc, const char **argv) { - _vm->_memory->displayMemory(); + _vm->_memory->memDisplay(); return true; } diff --git a/sword2/console.h b/sword2/console.h index d445b977f5..ca8879806c 100644 --- a/sword2/console.h +++ b/sword2/console.h @@ -44,7 +44,7 @@ private: int32 _showVar[MAX_SHOWVARS]; - uint8 _debugTextBlocks[MAX_DEBUG_TEXTS]; + byte _debugTextBlocks[MAX_DEBUG_TEXTS]; void clearDebugTextBlocks(void); void makeDebugTextBlock(char *text, int16 x, int16 y); diff --git a/sword2/controls.cpp b/sword2/controls.cpp index 755ad1ebad..69cc36103a 100644 --- a/sword2/controls.cpp +++ b/sword2/controls.cpp @@ -78,7 +78,7 @@ protected: SpriteInfo *_sprites; struct WidgetSurface { - uint8 *_surface; + byte *_surface; bool _original; }; @@ -129,7 +129,7 @@ private: Gui *_gui; struct Glyph { - uint8 *_data; + byte *_data; int _width; int _height; }; @@ -148,21 +148,21 @@ public: FontRendererGui(Gui *gui, int fontId); ~FontRendererGui(); - void fetchText(uint32 textId, uint8 *buf); + void fetchText(uint32 textId, byte *buf); - int getCharWidth(uint8 c); - int getCharHeight(uint8 c); + int getCharWidth(byte c); + int getCharHeight(byte c); - int getTextWidth(uint8 *text); + int getTextWidth(byte *text); int getTextWidth(uint32 textId); - void drawText(uint8 *text, int x, int y, int alignment = kAlignLeft); + void drawText(byte *text, int x, int y, int alignment = kAlignLeft); void drawText(uint32 textId, int x, int y, int alignment = kAlignLeft); }; FontRendererGui::FontRendererGui(Gui *gui, int fontId) : _gui(gui), _fontId(fontId) { - uint8 *font = _gui->_vm->_resman->openResource(fontId); + byte *font = _gui->_vm->_resman->openResource(fontId); FrameHeader *head; SpriteInfo sprite; @@ -170,7 +170,7 @@ FontRendererGui::FontRendererGui(Gui *gui, int fontId) for (int i = 0; i < SIZE_OF_CHAR_SET; i++) { head = (FrameHeader *) _gui->_vm->fetchFrameHeader(font, i); - sprite.data = (uint8 *) (head + 1); + sprite.data = (byte *) (head + 1); sprite.w = head->width; sprite.h = head->height; _gui->_vm->_graphics->createSurface(&sprite, &_glyph[i]._data); @@ -186,8 +186,8 @@ FontRendererGui::~FontRendererGui() { _gui->_vm->_graphics->deleteSurface(_glyph[i]._data); } -void FontRendererGui::fetchText(uint32 textId, uint8 *buf) { - uint8 *data = _gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff); +void FontRendererGui::fetchText(uint32 textId, byte *buf) { + byte *data = _gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff); int i; for (i = 0; data[i + 2]; i++) { @@ -199,19 +199,19 @@ void FontRendererGui::fetchText(uint32 textId, uint8 *buf) { _gui->_vm->_resman->closeResource(textId / SIZE); } -int FontRendererGui::getCharWidth(uint8 c) { +int FontRendererGui::getCharWidth(byte c) { if (c < 32) return 0; return _glyph[c - 32]._width; } -int FontRendererGui::getCharHeight(uint8 c) { +int FontRendererGui::getCharHeight(byte c) { if (c < 32) return 0; return _glyph[c - 32]._height; } -int FontRendererGui::getTextWidth(uint8 *text) { +int FontRendererGui::getTextWidth(byte *text) { int textWidth = 0; for (int i = 0; text[i]; i++) @@ -221,13 +221,13 @@ int FontRendererGui::getTextWidth(uint8 *text) { } int FontRendererGui::getTextWidth(uint32 textId) { - uint8 text[MAX_STRING_LEN]; + byte text[MAX_STRING_LEN]; fetchText(textId, text); return getTextWidth(text); } -void FontRendererGui::drawText(uint8 *text, int x, int y, int alignment) { +void FontRendererGui::drawText(byte *text, int x, int y, int alignment) { SpriteInfo sprite; int i; @@ -260,7 +260,7 @@ void FontRendererGui::drawText(uint8 *text, int x, int y, int alignment) { } void FontRendererGui::drawText(uint32 textId, int x, int y, int alignment) { - uint8 text[MAX_STRING_LEN]; + byte text[MAX_STRING_LEN]; fetchText(textId, text); drawText(text, x, y, alignment); @@ -431,7 +431,7 @@ Widget::~Widget() { } void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc) { - uint8 *file, *colTablePtr = NULL; + byte *file, *colTablePtr = NULL; AnimHeader *anim_head; FrameHeader *frame_head; CdtEntry *cdt_entry; @@ -463,7 +463,7 @@ void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc) spriteType |= RDSPR_RLE256; // Points to just after last cdt_entry, i.e. start of colour // table - colTablePtr = (uint8 *) (anim_head + 1) + + colTablePtr = (byte *) (anim_head + 1) + anim_head->noAnimFrames * sizeof(CdtEntry); break; } @@ -477,7 +477,7 @@ void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc) _sprites[state].blend = anim_head->blend; // Points to just after frame header, ie. start of sprite data - _sprites[state].data = (uint8 *) (frame_head + 1); + _sprites[state].data = (byte *) (frame_head + 1); _parent->_gui->_vm->_graphics->createSurface(&_sprites[state], &_surfaces[state]._surface); _surfaces[state]._original = true; @@ -1044,7 +1044,7 @@ class Slot : public Widget { private: int _mode; FontRendererGui *_fr; - uint8 _text[SAVE_DESCRIPTION_LEN]; + byte _text[SAVE_DESCRIPTION_LEN]; bool _clickable; bool _editable; @@ -1071,7 +1071,7 @@ public: return _editable; } - void setText(FontRendererGui *fr, int slot, uint8 *text) { + void setText(FontRendererGui *fr, int slot, byte *text) { _fr = fr; if (text) sprintf((char *) _text, "%d. %s", slot, text); @@ -1079,7 +1079,7 @@ public: sprintf((char *) _text, "%d. ", slot); } - uint8 *getText() { + byte *getText() { return &_text[0]; } @@ -1147,7 +1147,7 @@ public: class SaveLoadDialog : public Dialog { private: int _mode, _selectedSlot; - uint8 _editBuffer[SAVE_DESCRIPTION_LEN]; + byte _editBuffer[SAVE_DESCRIPTION_LEN]; int _editPos, _firstPos; int _cursorTick; @@ -1162,7 +1162,7 @@ private: Button *_okButton; Button *_cancelButton; - void saveLoadError(uint8 *text); + void saveLoadError(byte *text); public: SaveLoadDialog(Gui *gui, int mode) @@ -1232,7 +1232,7 @@ public: for (int i = 0; i < 8; i++) { Slot *slot = _slotButton[(_gui->_baseSlot + i) % 8]; FontRendererGui *fr; - uint8 description[SAVE_DESCRIPTION_LEN]; + byte description[SAVE_DESCRIPTION_LEN]; slot->setY(72 + i * 36); @@ -1295,7 +1295,7 @@ public: } else { Slot *slot = (Slot *) widget; int textWidth; - uint8 tmp; + byte tmp; int i; int j; @@ -1417,7 +1417,7 @@ public: _editBuffer[_editPos] = 0; - uint32 rv = _gui->_vm->saveGame(_selectedSlot, (uint8 *) &_editBuffer[_firstPos]); + uint32 rv = _gui->_vm->saveGame(_selectedSlot, (byte *) &_editBuffer[_firstPos]); if (rv != SR_OK) { uint32 textId; @@ -1474,9 +1474,9 @@ public: } }; -void SaveLoadDialog::saveLoadError(uint8* text) { +void SaveLoadDialog::saveLoadError(byte* text) { // Print a message on screen. Second parameter is duration. - _gui->_vm->displayMsg((uint8 *) text, 0); + _gui->_vm->displayMsg((byte *) text, 0); // Wait for ESC or mouse click while (1) { diff --git a/sword2/debug.cpp b/sword2/debug.cpp index 8d9bb1d8b2..3c41f34655 100644 --- a/sword2/debug.cpp +++ b/sword2/debug.cpp @@ -50,7 +50,7 @@ void Debugger::makeDebugTextBlock(char *text, int16 x, int16 y) { assert(blockNo < MAX_DEBUG_TEXTS); - _debugTextBlocks[blockNo] = _vm->_fontRenderer->buildNewBloc((uint8 *) text, x, y, 640 - x, 0, RDSPR_DISPLAYALIGN, CONSOLE_FONT_ID, NO_JUSTIFICATION); + _debugTextBlocks[blockNo] = _vm->_fontRenderer->buildNewBloc((byte *) text, x, y, 640 - x, 0, RDSPR_DISPLAYALIGN, CONSOLE_FONT_ID, NO_JUSTIFICATION); } void Debugger::buildDebugText(void) { @@ -290,7 +290,7 @@ void Debugger::buildDebugText(void) { // memory indicator - this should come last, to show all the // sprite blocks above! - _vm->_memory->memoryString(buf); + _vm->_memory->memStatusStr(buf); makeDebugTextBlock(buf, 0, 0); } } diff --git a/sword2/driver/_mouse.cpp b/sword2/driver/_mouse.cpp index f0dc663daf..d57b01a306 100644 --- a/sword2/driver/_mouse.cpp +++ b/sword2/driver/_mouse.cpp @@ -68,7 +68,7 @@ MouseEvent *Input::mouseEvent(void) { // 0xFF. That means that parts of the mouse cursor that weren't meant to be // transparent may be now. -void Graphics::decompressMouse(uint8 *decomp, uint8 *comp, int width, int height, int pitch, int xOff, int yOff) { +void Graphics::decompressMouse(byte *decomp, byte *comp, int width, int height, int pitch, int xOff, int yOff) { int32 size = width * height; int32 i = 0; int x = 0; @@ -155,7 +155,7 @@ void Graphics::drawMouse(void) { memset(_mouseData, 0xFF, mouse_width * mouse_height); if (_luggageAnim) - decompressMouse(_mouseData, (uint8 *) _luggageAnim + READ_LE_UINT32(_luggageOffset), _luggageAnim->mousew, + decompressMouse(_mouseData, (byte *) _luggageAnim + READ_LE_UINT32(_luggageOffset), _luggageAnim->mousew, _luggageAnim->mouseh, mouse_width, deltaX, deltaY); if (_mouseAnim) @@ -177,7 +177,7 @@ int32 Graphics::animateMouse(void) { if (++_mouseFrame == _mouseAnim->noAnimFrames) _mouseFrame = MOUSEFLASHFRAME; - _mouseSprite = (uint8 *) _mouseAnim + READ_LE_UINT32(_mouseOffsets + _mouseFrame); + _mouseSprite = (byte *) _mouseAnim + READ_LE_UINT32(_mouseOffsets + _mouseFrame); if (_mouseFrame != prevMouseFrame) drawMouse(); @@ -193,7 +193,7 @@ int32 Graphics::animateMouse(void) { * or not there is a lead-in animation */ -int32 Graphics::setMouseAnim(uint8 *ma, int32 size, int32 mouseFlash) { +int32 Graphics::setMouseAnim(byte *ma, int32 size, int32 mouseFlash) { if (_mouseAnim) { free(_mouseAnim); _mouseAnim = NULL; @@ -209,8 +209,8 @@ int32 Graphics::setMouseAnim(uint8 *ma, int32 size, int32 mouseFlash) { if (!_mouseAnim) return RDERR_OUTOFMEMORY; - memcpy((uint8 *) _mouseAnim, ma, size); - _mouseOffsets = (int32 *) ((uint8 *) _mouseAnim + sizeof(MouseAnim)); + memcpy((byte *) _mouseAnim, ma, size); + _mouseOffsets = (int32 *) ((byte *) _mouseAnim + sizeof(MouseAnim)); animateMouse(); drawMouse(); @@ -233,7 +233,7 @@ int32 Graphics::setMouseAnim(uint8 *ma, int32 size, int32 mouseFlash) { * @param size the size of the animation data */ -int32 Graphics::setLuggageAnim(uint8 *ma, int32 size) { +int32 Graphics::setLuggageAnim(byte *ma, int32 size) { if (_luggageAnim) { free(_luggageAnim); _luggageAnim = NULL; @@ -244,8 +244,8 @@ int32 Graphics::setLuggageAnim(uint8 *ma, int32 size) { if (!_luggageAnim) return RDERR_OUTOFMEMORY; - memcpy((uint8 *) _luggageAnim, ma, size); - _luggageOffset = (int32 *) ((uint8 *) _luggageAnim + sizeof(MouseAnim)); + memcpy((byte *) _luggageAnim, ma, size); + _luggageOffset = (int32 *) ((byte *) _luggageAnim + sizeof(MouseAnim)); animateMouse(); drawMouse(); diff --git a/sword2/driver/animation.cpp b/sword2/driver/animation.cpp index 9785ed2110..53dad119f5 100644 --- a/sword2/driver/animation.cpp +++ b/sword2/driver/animation.cpp @@ -50,7 +50,7 @@ void AnimationState::setPalette(byte *pal) { #else -void AnimationState::drawTextObject(SpriteInfo *s, uint8 *src) { +void AnimationState::drawTextObject(SpriteInfo *s, byte *src) { OverlayColor *dst = overlay + RENDERWIDE * (s->y) + s->x; // FIXME: These aren't the "right" colours, but look good to me. @@ -166,7 +166,7 @@ void MoviePlayer::drawTextObject(AnimationState *anim, MovieTextObject *obj) { * @param musicOut lead-out music */ -int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *musicOut) { +int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], byte *musicOut) { // This happens if the user quits during the "eye" smacker if (_vm->_quit) return RD_OK; @@ -178,7 +178,7 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu uint32 flags = SoundMixer::FLAG_16BITS; bool startNextText = false; - uint8 oldPal[1024]; + byte oldPal[1024]; memcpy(oldPal, _vm->_graphics->_palCopy, 1024); AnimationState *anim = new AnimationState(_vm); @@ -342,11 +342,11 @@ int32 MoviePlayer::play(const char *filename, MovieTextObject *text[], uint8 *mu * are missing. */ -int32 MoviePlayer::playDummy(const char *filename, MovieTextObject *text[], uint8 *musicOut) { +int32 MoviePlayer::playDummy(const char *filename, MovieTextObject *text[], byte *musicOut) { int frameCounter = 0, textCounter = 0; if (text) { - uint8 oldPal[1024]; - uint8 tmpPal[1024]; + byte oldPal[1024]; + byte tmpPal[1024]; _vm->_graphics->clearScene(); @@ -357,23 +357,23 @@ int32 MoviePlayer::playDummy(const char *filename, MovieTextObject *text[], uint memset(_vm->_graphics->_buffer, 0, _vm->_graphics->_screenWide * MENUDEEP); - uint8 msg[] = "Cutscene - Narration Only: Press ESC to exit, or visit www.scummvm.org to download cutscene videos"; - Memory *data = _vm->_fontRenderer->makeTextSprite(msg, RENDERWIDE, 255, _vm->_speechFontId); - FrameHeader *frame = (FrameHeader *) data->ad; + byte msg[] = "Cutscene - Narration Only: Press ESC to exit, or visit www.scummvm.org to download cutscene videos"; + byte *data = _vm->_fontRenderer->makeTextSprite(msg, RENDERWIDE, 255, _vm->_speechFontId); + FrameHeader *frame = (FrameHeader *) data; SpriteInfo msgSprite; - uint8 *msgSurface; + byte *msgSurface; msgSprite.x = _vm->_graphics->_screenWide / 2 - frame->width / 2; msgSprite.y = RDMENU_MENUDEEP / 2 - frame->height / 2; msgSprite.w = frame->width; msgSprite.h = frame->height; msgSprite.type = RDSPR_NOCOMPRESSION; - msgSprite.data = data->ad + sizeof(FrameHeader); + msgSprite.data = data + sizeof(FrameHeader); _vm->_graphics->createSurface(&msgSprite, &msgSurface); _vm->_graphics->drawSurface(&msgSprite, msgSurface); _vm->_graphics->deleteSurface(msgSurface); - _vm->_memory->freeMemory(data); + _vm->_memory->memFree(data); // In case the cutscene has a long lead-in, start just before // the first line of text. diff --git a/sword2/driver/animation.h b/sword2/driver/animation.h index 818167537e..cf991733de 100644 --- a/sword2/driver/animation.h +++ b/sword2/driver/animation.h @@ -38,7 +38,7 @@ public: ~AnimationState(); #ifndef BACKEND_8BIT - void drawTextObject(SpriteInfo *s, uint8 *src); + void drawTextObject(SpriteInfo *s, byte *src); #endif void clearScreen(); @@ -63,7 +63,7 @@ private: SoundMixer *_snd; OSystem *_sys; - uint8 *_textSurface; + byte *_textSurface; static struct MovieInfo _movies[]; @@ -71,11 +71,11 @@ private: void closeTextObject(MovieTextObject *obj); void drawTextObject(AnimationState *anim, MovieTextObject *obj); - int32 playDummy(const char *filename, MovieTextObject *text[], uint8 *musicOut); + int32 playDummy(const char *filename, MovieTextObject *text[], byte *musicOut); public: MoviePlayer(Sword2Engine *vm); - int32 play(const char *filename, MovieTextObject *text[], uint8 *musicOut); + int32 play(const char *filename, MovieTextObject *text[], byte *musicOut); }; } // End of namespace Sword2 diff --git a/sword2/driver/d_draw.h b/sword2/driver/d_draw.h index 257be0d117..5c56246995 100644 --- a/sword2/driver/d_draw.h +++ b/sword2/driver/d_draw.h @@ -91,9 +91,9 @@ private: bool _needFullRedraw; - uint8 _paletteMatch[PALTABLESIZE]; + byte _paletteMatch[PALTABLESIZE]; - uint8 _fadePalette[256][4]; + byte _fadePalette[256][4]; uint8 _fadeStatus; int32 _fadeStartTime; @@ -102,7 +102,7 @@ private: byte _mouseData[MAX_MOUSE_W * MAX_MOUSE_H]; uint8 _mouseFrame; - uint8 *_mouseSprite; + byte *_mouseSprite; struct MouseAnim *_mouseAnim; struct MouseAnim *_luggageAnim; int32 *_mouseOffsets; @@ -146,11 +146,11 @@ private: uint16 _xScale[SCALE_MAXWIDTH]; uint16 _yScale[SCALE_MAXHEIGHT]; - uint8 *_lightMask; + byte *_lightMask; void clearIconArea(int menu, int pocket, Common::Rect *r); - void decompressMouse(uint8 *decomp, uint8 *comp, int width, int height, int pitch, int xOff = 0, int yOff = 0); + void decompressMouse(byte *decomp, byte *comp, int width, int height, int pitch, int xOff = 0, int yOff = 0); uint8 getMatch(uint8 r, uint8 g, uint8 b); void fadeServer(void); @@ -166,10 +166,10 @@ private: void blitBlockSurface(BlockSurface *s, Common::Rect *r, Common::Rect *clipRect); - void mirrorSprite(uint8 *dst, uint8 *src, int16 w, int16 h); - int32 decompressRLE256(uint8 *dest, uint8 *source, int32 decompSize); - void unwindRaw16(uint8 *dest, uint8 *source, uint8 blockSize, uint8 *colTable); - int32 decompressRLE16(uint8 *dest, uint8 *source, int32 decompSize, uint8 *colTable); + void mirrorSprite(byte *dst, byte *src, int16 w, int16 h); + int32 decompressRLE256(byte *dest, byte *source, int32 decompSize); + void unwindRaw16(byte *dest, byte *source, uint8 blockSize, byte *colTable); + int32 decompressRLE16(byte *dest, byte *source, int32 decompSize, byte *colTable); public: @@ -180,7 +180,7 @@ public: int16 _screenWide; int16 _screenDeep; - uint8 _palCopy[256][4]; + byte _palCopy[256][4]; byte *getScreen(void) { return _buffer; } @@ -192,15 +192,15 @@ public: void processMenu(void); int32 showMenu(uint8 menu); int32 hideMenu(uint8 menu); - int32 setMenuIcon(uint8 menu, uint8 pocket, uint8 *icon); + int32 setMenuIcon(uint8 menu, uint8 pocket, byte *icon); void closeMenuImmediately(void); void updateDisplay(bool redrawScene = true); void setWindowName(const char *windowName); void setNeedFullRedraw(void); - void setPalette(int16 startEntry, int16 noEntries, uint8 *palette, uint8 setNow); - void updatePaletteMatchTable(uint8 *data); + void setPalette(int16 startEntry, int16 noEntries, byte *palette, uint8 setNow); + void updatePaletteMatchTable(byte *data); uint8 quickMatch(uint8 r, uint8 g, uint8 b); int32 fadeUp(float time = 0.75); int32 fadeDown(float time = 0.75); @@ -208,8 +208,8 @@ public: void dimPalette(void); void waitForFade(void); - int32 setMouseAnim(uint8 *ma, int32 size, int32 mouseFlash); - int32 setLuggageAnim(uint8 *la, int32 size); + int32 setMouseAnim(byte *ma, int32 size, int32 mouseFlash); + int32 setLuggageAnim(byte *la, int32 size); int32 animateMouse(void); void drawMouse(void); @@ -232,9 +232,9 @@ public: #endif - int32 createSurface(SpriteInfo *s, uint8 **surface); - void drawSurface(SpriteInfo *s, uint8 *surface, Common::Rect *clipRect = NULL); - void deleteSurface(uint8 *surface); + int32 createSurface(SpriteInfo *s, byte **surface); + void drawSurface(SpriteInfo *s, byte *surface, Common::Rect *clipRect = NULL); + void deleteSurface(byte *surface); int32 drawSprite(SpriteInfo *s); int32 openLightMask(SpriteInfo *s); int32 closeLightMask(void); diff --git a/sword2/driver/d_sound.cpp b/sword2/driver/d_sound.cpp index ccadfe4ec8..e6b547fdae 100644 --- a/sword2/driver/d_sound.cpp +++ b/sword2/driver/d_sound.cpp @@ -251,7 +251,7 @@ bool MusicHandle::endOfData(void) const { * @return True if the data appears to be a WAV file, otherwise false. */ -bool Sound::getWavInfo(uint8 *data, WavInfo *wavInfo) { +bool Sound::getWavInfo(byte *data, WavInfo *wavInfo) { uint32 wavLength; uint32 offset; @@ -750,7 +750,7 @@ int32 Sound::amISpeaking(void) { uint32 Sound::preFetchCompSpeech(const char *filename, uint32 speechid, uint16 **buf) { uint32 i; - uint8 *data8; + byte *data8; uint32 speechPos, speechLength; File fp; uint32 bufferSize; @@ -772,7 +772,7 @@ uint32 Sound::preFetchCompSpeech(const char *filename, uint32 speechid, uint16 * } // Create a temporary buffer for compressed speech - data8 = (uint8 *) malloc(speechLength); + data8 = (byte *) malloc(speechLength); if (!data8) { fp.close(); return 0; @@ -1036,7 +1036,7 @@ bool Sound::isFxPlaying(int32 id) { * @warning Zero is not a valid id */ -int32 Sound::openFx(int32 id, uint8 *data) { +int32 Sound::openFx(int32 id, byte *data) { if (!_soundOn) return RD_OK; @@ -1128,7 +1128,7 @@ int32 Sound::closeFx(int32 id) { * @warning Zero is not a valid id */ -int32 Sound::playFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type) { +int32 Sound::playFx(int32 id, byte *data, uint8 vol, int8 pan, uint8 type) { if (!_soundOn) return RD_OK; diff --git a/sword2/driver/driver96.h b/sword2/driver/driver96.h index e4e909453a..6356b9a287 100644 --- a/sword2/driver/driver96.h +++ b/sword2/driver/driver96.h @@ -214,8 +214,8 @@ struct SpriteInfo { uint16 scaledHeight; // uint16 type; // mask containing 'RDSPR_' bits specifying compression type, flip, transparency, etc uint16 blend; // holds the blending values. - uint8 *data; // pointer to the sprite data - uint8 *colourTable; // pointer to 16-byte colour table, only applicable to 16-col compression type + byte *data; // pointer to the sprite data + byte *colourTable; // pointer to 16-byte colour table, only applicable to 16-col compression type }; // This is the structure which is passed to the sequence player. It includes diff --git a/sword2/driver/menu.cpp b/sword2/driver/menu.cpp index b1534e686b..79245fe0db 100644 --- a/sword2/driver/menu.cpp +++ b/sword2/driver/menu.cpp @@ -264,7 +264,7 @@ void Graphics::closeMenuImmediately(void) { * @return RD_OK, or an error code */ -int32 Graphics::setMenuIcon(uint8 menu, uint8 pocket, uint8 *icon) { +int32 Graphics::setMenuIcon(uint8 menu, uint8 pocket, byte *icon) { Common::Rect r; // Check for invalid menu parameter. @@ -287,7 +287,7 @@ int32 Graphics::setMenuIcon(uint8 menu, uint8 pocket, uint8 *icon) { // Only put the icon in the pocket if it is not NULL if (icon != NULL) { _iconCount++; - _icons[menu][pocket] = (uint8 *) malloc(RDMENU_ICONWIDE * RDMENU_ICONDEEP); + _icons[menu][pocket] = (byte *) malloc(RDMENU_ICONWIDE * RDMENU_ICONDEEP); if (_icons[menu][pocket] == NULL) return RDERR_OUTOFMEMORY; memcpy(_icons[menu][pocket], icon, RDMENU_ICONWIDE * RDMENU_ICONDEEP); diff --git a/sword2/driver/palette.cpp b/sword2/driver/palette.cpp index c9433c3ef1..1c5096c11b 100644 --- a/sword2/driver/palette.cpp +++ b/sword2/driver/palette.cpp @@ -64,10 +64,10 @@ uint8 Graphics::getMatch(uint8 r, uint8 g, uint8 b) { * from the current palCopy */ -void Graphics::updatePaletteMatchTable(uint8 *data) { +void Graphics::updatePaletteMatchTable(byte *data) { if (!data) { int16 red, green, blue; - uint8 *p; + byte *p; // Create palette match table @@ -109,7 +109,7 @@ uint8 Graphics::quickMatch(uint8 r, uint8 g, uint8 b) { * @param colourTable the new colour entries */ -void Graphics::setPalette(int16 startEntry, int16 noEntries, uint8 *colourTable, uint8 fadeNow) { +void Graphics::setPalette(int16 startEntry, int16 noEntries, byte *colourTable, uint8 fadeNow) { if (noEntries) { memcpy(&_palCopy[startEntry][0], colourTable, noEntries * 4); if (fadeNow == RDPAL_INSTANT) { diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp index ff06fb5fef..a6d83e615c 100644 --- a/sword2/driver/render.cpp +++ b/sword2/driver/render.cpp @@ -332,7 +332,7 @@ void Graphics::stretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 */ void Graphics::plotPoint(uint16 x, uint16 y, uint8 colour) { - uint8 *buf = _buffer + 40 * RENDERWIDE; + byte *buf = _buffer + 40 * RENDERWIDE; int16 newx, newy; newx = x - _scrollX; @@ -353,7 +353,7 @@ void Graphics::plotPoint(uint16 x, uint16 y, uint8 colour) { // Uses Bressnham's incremental algorithm! void Graphics::drawLine(int16 x0, int16 y0, int16 x1, int16 y1, uint8 colour) { - uint8 *buf = _buffer + 40 * RENDERWIDE; + byte *buf = _buffer + 40 * RENDERWIDE; int dx, dy; int dxmod, dymod; int ince, incne; @@ -700,15 +700,15 @@ void Graphics::setScrollTarget(int16 sx, int16 sy) { */ int32 Graphics::initialiseBackgroundLayer(Parallax *p) { - uint8 *memchunk; + byte *memchunk; uint8 zeros; uint16 count; uint16 i, j, k; uint16 x; - uint8 *data; - uint8 *dst; + byte *data; + byte *dst; ParallaxLine line; - uint8 *pLine; + byte *pLine; debug(2, "initialiseBackgroundLayer"); @@ -732,7 +732,7 @@ int32 Graphics::initialiseBackgroundLayer(Parallax *p) { // Decode the parallax layer into a large chunk of memory - memchunk = (uint8 *) calloc(_xBlocks[_layer] * _yBlocks[_layer], BLOCKWIDTH * BLOCKHEIGHT); + memchunk = (byte *) calloc(_xBlocks[_layer] * _yBlocks[_layer], BLOCKWIDTH * BLOCKHEIGHT); if (!memchunk) return RDERR_OUTOFMEMORY; @@ -740,7 +740,7 @@ int32 Graphics::initialiseBackgroundLayer(Parallax *p) { if (p->offset[i] == 0) continue; - pLine = (uint8 *) p + FROM_LE_32(p->offset[i]); + pLine = (byte *) p + FROM_LE_32(p->offset[i]); line.packets = READ_LE_UINT16(pLine); line.offset = READ_LE_UINT16(pLine + 2); data = pLine + sizeof(ParallaxLine); diff --git a/sword2/driver/sprite.cpp b/sword2/driver/sprite.cpp index f13eb877fd..597d63f712 100644 --- a/sword2/driver/sprite.cpp +++ b/sword2/driver/sprite.cpp @@ -31,7 +31,7 @@ namespace Sword2 { * @param h height of the sprite */ -void Graphics::mirrorSprite(uint8 *dst, uint8 *src, int16 w, int16 h) { +void Graphics::mirrorSprite(byte *dst, byte *src, int16 w, int16 h) { for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { *dst++ = *(src + w - x - 1); @@ -48,15 +48,15 @@ void Graphics::mirrorSprite(uint8 *dst, uint8 *src, int16 w, int16 h) { * @param decompSize the expected size of the decompressed sprite */ -int32 Graphics::decompressRLE256(uint8 *dest, uint8 *source, int32 decompSize) { +int32 Graphics::decompressRLE256(byte *dest, byte *source, int32 decompSize) { // PARAMETERS: // source points to the start of the sprite data for input // decompSize gives size of decompressed data in bytes // dest points to start of destination buffer for decompressed // data - uint8 headerByte; // block header byte - uint8 *endDest = dest + decompSize; // pointer to byte after end of decomp buffer + byte headerByte; // block header byte + byte *endDest = dest + decompSize; // pointer to byte after end of decomp buffer int32 rv; while(1) { @@ -128,7 +128,7 @@ int32 Graphics::decompressRLE256(uint8 *dest, uint8 *source, int32 decompSize) { * Unwinds a run of 16-colour data into 256-colour palette data. */ -void Graphics::unwindRaw16(uint8 *dest, uint8 *source, uint8 blockSize, uint8 *colTable) { +void Graphics::unwindRaw16(byte *dest, byte *source, uint8 blockSize, byte *colTable) { // for each pair of pixels while (blockSize > 1) { // 1st colour = number in table at position given by upper @@ -163,9 +163,9 @@ void Graphics::unwindRaw16(uint8 *dest, uint8 *source, uint8 blockSize, uint8 *c * @param colTable mapping from the 16 encoded colours to the current palette */ -int32 Graphics::decompressRLE16(uint8 *dest, uint8 *source, int32 decompSize, uint8 *colTable) { - uint8 headerByte; // block header byte - uint8 *endDest = dest + decompSize; // pointer to byte after end of decomp buffer +int32 Graphics::decompressRLE16(byte *dest, byte *source, int32 decompSize, byte *colTable) { + byte headerByte; // block header byte + byte *endDest = dest + decompSize; // pointer to byte after end of decomp buffer int32 rv; while(1) { @@ -243,8 +243,8 @@ int32 Graphics::decompressRLE16(uint8 *dest, uint8 *source, int32 decompSize, ui * @return RD_OK, or an error code */ -int32 Graphics::createSurface(SpriteInfo *s, uint8 **sprite) { - *sprite = (uint8 *) malloc(s->w * s->h); +int32 Graphics::createSurface(SpriteInfo *s, byte **sprite) { + *sprite = (byte *) malloc(s->w * s->h); if (!*sprite) return RDERR_OUTOFMEMORY; @@ -268,10 +268,10 @@ int32 Graphics::createSurface(SpriteInfo *s, uint8 **sprite) { * @param clipRect the clipping rectangle */ -void Graphics::drawSurface(SpriteInfo *s, uint8 *surface, Common::Rect *clipRect) { +void Graphics::drawSurface(SpriteInfo *s, byte *surface, Common::Rect *clipRect) { Common::Rect rd, rs; uint16 x, y; - uint8 *src, *dst; + byte *src, *dst; rs.left = 0; rs.right = s->w; @@ -327,7 +327,7 @@ void Graphics::drawSurface(SpriteInfo *s, uint8 *surface, Common::Rect *clipRect * Destroys a surface. */ -void Graphics::deleteSurface(uint8 *surface) { +void Graphics::deleteSurface(byte *surface) { free(surface); } @@ -353,9 +353,9 @@ void Graphics::deleteSurface(uint8 *surface) { // mallocing here. int32 Graphics::drawSprite(SpriteInfo *s) { - uint8 *src, *dst; - uint8 *sprite, *newSprite; - uint8 *backbuf = NULL; + byte *src, *dst; + byte *sprite, *newSprite; + byte *backbuf = NULL; uint16 scale; int16 i, j; uint16 srcPitch; @@ -370,7 +370,7 @@ int32 Graphics::drawSprite(SpriteInfo *s) { if (s->type & RDSPR_NOCOMPRESSION) sprite = s->data; else { - sprite = (uint8 *) malloc(s->w * s->h); + sprite = (byte *) malloc(s->w * s->h); freeSprite = true; if (!sprite) return RDERR_OUTOFMEMORY; @@ -388,7 +388,7 @@ int32 Graphics::drawSprite(SpriteInfo *s) { } if (s->type & RDSPR_FLIP) { - newSprite = (uint8 *) malloc(s->w * s->h); + newSprite = (byte *) malloc(s->w * s->h); if (newSprite == NULL) { if (freeSprite) free(sprite); @@ -486,7 +486,7 @@ int32 Graphics::drawSprite(SpriteInfo *s) { return RDERR_NOTIMPLEMENTED; } - newSprite = (uint8 *) malloc(s->scaledWidth * s->scaledHeight); + newSprite = (byte *) malloc(s->scaledWidth * s->scaledHeight); if (newSprite == NULL) { if (freeSprite) free(sprite); @@ -519,10 +519,10 @@ int32 Graphics::drawSprite(SpriteInfo *s) { // (actors, presumably) are always affected. if ((_renderCaps & RDBLTFX_SHADOWBLEND) && _lightMask && (scale != 256 || (s->type & RDSPR_SHADOW))) { - uint8 *lightMap; + byte *lightMap; if (!freeSprite) { - newSprite = (uint8 *) malloc(s->w * s->h); + newSprite = (byte *) malloc(s->w * s->h); memcpy(newSprite, sprite, s->w * s->h); sprite = newSprite; freeSprite = true; @@ -640,7 +640,7 @@ int32 Graphics::openLightMask(SpriteInfo *s) { if (_lightMask) return RDERR_NOTCLOSED; - _lightMask = (uint8 *) malloc(s->w * s->h); + _lightMask = (byte *) malloc(s->w * s->h); if (!_lightMask) return RDERR_OUTOFMEMORY; diff --git a/sword2/events.cpp b/sword2/events.cpp index 403d32b9b2..f567118c5c 100644 --- a/sword2/events.cpp +++ b/sword2/events.cpp @@ -151,7 +151,7 @@ int32 Logic::fnPauseForEvent(int32 *params) { // params: 0 pointer to object's logic structure // 1 number of game-cycles to pause - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); if (checkEventWaiting()) { ob_logic->looping = 0; diff --git a/sword2/function.cpp b/sword2/function.cpp index 116b3ce579..eab786fcb2 100644 --- a/sword2/function.cpp +++ b/sword2/function.cpp @@ -131,7 +131,7 @@ int32 Logic::fnPause(int32 *params) { // NB. Pause-value of 0 causes script to continue, 1 causes a 1-cycle // quit, 2 gives 2 cycles, etc. - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); if (ob_logic->looping == 0) { ob_logic->looping = 1; @@ -152,7 +152,7 @@ int32 Logic::fnRandomPause(int32 *params) { // 1 minimum number of game-cycles to pause // 2 maximum number of game-cycles to pause - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); int32 pars[2]; if (ob_logic->looping == 0) { @@ -189,7 +189,7 @@ int32 Logic::fnPassMega(int32 *params) { // params: 0 pointer to a mega structure - memcpy(&_engineMega, _vm->_memory->intToPtr(params[0]), sizeof(ObjectMega)); + memcpy(&_engineMega, _vm->_memory->decodePtr(params[0]), sizeof(ObjectMega)); return IR_CONT; } @@ -202,7 +202,7 @@ int32 Logic::fnSetValue(int32 *params) { // params: 0 pointer to object's mega structure // 1 value to set it to - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[0]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[0]); ob_mega->megaset_res = params[1]; return IR_CONT; @@ -323,7 +323,7 @@ int32 Logic::fnResetGlobals(int32 *params) { debug(5, "globals size: %d", size); - globals = (uint32 *) ((uint8 *) _vm->_resman->openResource(1) + sizeof(StandardHeader)); + globals = (uint32 *) ((byte *) _vm->_resman->openResource(1) + sizeof(StandardHeader)); // blank each global variable memset(globals, 0, size); @@ -363,7 +363,7 @@ struct CreditsLine { byte type; int top; int height; - Memory *sprite; + byte *sprite; }; #define CREDITS_FONT_HEIGHT 25 @@ -432,8 +432,8 @@ int32 Logic::fnPlayCredits(int32 *params) { uint16 logoWidth = 0; uint16 logoHeight = 0; - uint8 *logoData = NULL; - uint8 palette[1024]; + byte *logoData = NULL; + byte palette[1024]; if (f.open("credits.bmp")) { logoWidth = f.readUint16LE(); @@ -446,7 +446,7 @@ int32 Logic::fnPlayCredits(int32 *params) { palette[i * 4 + 3] = 0; } - logoData = (uint8 *) malloc(logoWidth * logoHeight); + logoData = (byte *) malloc(logoWidth * logoHeight); f.read(logoData, logoWidth * logoHeight); f.close(); @@ -610,7 +610,7 @@ int32 Logic::fnPlayCredits(int32 *params) { if (creditsLines[i].top + creditsLines[i].height < scrollPos) { if (creditsLines[i].sprite) { - _vm->_memory->freeMemory(creditsLines[i].sprite); + free(creditsLines[i].sprite); creditsLines[i].sprite = NULL; debug(2, "Freeing sprite '%s'", creditsLines[i].str); } @@ -626,15 +626,15 @@ int32 Logic::fnPlayCredits(int32 *params) { if (!creditsLines[i].sprite) { debug(2, "Creating sprite '%s'", creditsLines[i].str); - creditsLines[i].sprite = _vm->_fontRenderer->makeTextSprite((uint8 *) creditsLines[i].str, 600, 14, _vm->_speechFontId, 0); + creditsLines[i].sprite = _vm->_fontRenderer->makeTextSprite((byte *) creditsLines[i].str, 600, 14, _vm->_speechFontId, 0); } - FrameHeader *frame = (FrameHeader *) creditsLines[i].sprite->ad; + FrameHeader *frame = (FrameHeader *) creditsLines[i].sprite; spriteInfo.y = creditsLines[i].top - scrollPos; spriteInfo.w = frame->width; spriteInfo.h = frame->height; - spriteInfo.data = creditsLines[i].sprite->ad + sizeof(FrameHeader); + spriteInfo.data = creditsLines[i].sprite + sizeof(FrameHeader); switch (creditsLines[i].type) { case LINE_LEFT: @@ -685,7 +685,7 @@ int32 Logic::fnPlayCredits(int32 *params) { if (creditsLines[i].str) free(creditsLines[i].str); if (creditsLines[i].sprite) - _vm->_memory->freeMemory(creditsLines[i].sprite); + free(creditsLines[i].sprite); } if (logoData) diff --git a/sword2/header.h b/sword2/header.h index b30af21145..b88e7c71c7 100644 --- a/sword2/header.h +++ b/sword2/header.h @@ -47,7 +47,7 @@ struct StandardHeader { uint32 decompSize; // Length of decompressed file held in // memory (NB. frames still held // compressed) - uint8 name[NAME_LEN]; // Name of object + byte name[NAME_LEN]; // Name of object } GCC_PACK; // fileType diff --git a/sword2/icons.cpp b/sword2/icons.cpp index f38eea572d..c782826a85 100644 --- a/sword2/icons.cpp +++ b/sword2/icons.cpp @@ -30,7 +30,7 @@ namespace Sword2 { int32 Logic::fnAddMenuObject(int32 *params) { // params: 0 pointer to a MenuObject structure to copy down - _vm->addMenuObject((MenuObject *) _vm->_memory->intToPtr(params[0])); + _vm->addMenuObject((MenuObject *) _vm->_memory->decodePtr(params[0])); return IR_CONT; } @@ -140,7 +140,7 @@ void Sword2Engine::buildMenu(void) { for (i = 0; i < 15; i++) { uint32 res = _masterMenuList[i].icon_resource; - uint8 *icon = NULL; + byte *icon = NULL; if (res) { bool icon_coloured; @@ -196,7 +196,7 @@ void Sword2Engine::buildSystemMenu(void) { // rest will grey out. for (int i = 0; i < ARRAYSIZE(icon_list); i++) { - uint8 *icon = _resman->openResource(icon_list[i]) + sizeof(StandardHeader); + byte *icon = _resman->openResource(icon_list[i]) + sizeof(StandardHeader); // The only case when an icon is grayed is when the player // is dead. Then SAVE is not available. diff --git a/sword2/interpreter.cpp b/sword2/interpreter.cpp index 4b67fcdb29..8807f24e4a 100644 --- a/sword2/interpreter.cpp +++ b/sword2/interpreter.cpp @@ -194,7 +194,7 @@ do { \ stack[stackPtr++] = (value); \ } while (false) -#define push_ptr(ptr) push(_vm->_memory->ptrToInt(ptr)) +#define push_ptr(ptr) push(_vm->_memory->encodePtr(ptr)) #define pop() (assert(stackPtr < ARRAYSIZE(stack)), stack[--stackPtr]) @@ -301,7 +301,7 @@ int Logic::runScript(char *scriptData, char *objectData, uint32 *offset) { int retVal; int caseCount; bool foundCase; - uint8 *ptr; + byte *ptr; curCommand = code[ip++]; @@ -372,7 +372,7 @@ int Logic::runScript(char *scriptData, char *objectData, uint32 *offset) { Read16ip(parameter); parameter /= 4; - ptr = (uint8 *) &localVars[parameter]; + ptr = (byte *) &localVars[parameter]; push_ptr(ptr); debug(9, "CP_PUSH_LOCAL_ADDR: &localVars[%d] => %p", parameter, ptr); break; @@ -382,7 +382,7 @@ int Logic::runScript(char *scriptData, char *objectData, uint32 *offset) { Read8ip(parameter); // ip now points to the string - ptr = (uint8 *) (code + ip); + ptr = (byte *) (code + ip); push_ptr(ptr); debug(9, "CP_PUSH_STRING: \"%s\"", ptr); ip += (parameter + 1); @@ -390,7 +390,7 @@ int Logic::runScript(char *scriptData, char *objectData, uint32 *offset) { case CP_PUSH_DEREFERENCED_STRUCTURE: // Push the address of a dereferenced structure Read32ip(parameter); - ptr = (uint8 *) (objectData + sizeof(int32) + sizeof(StandardHeader) + sizeof(ObjectHub) + parameter); + ptr = (byte *) (objectData + sizeof(int32) + sizeof(StandardHeader) + sizeof(ObjectHub) + parameter); push_ptr(ptr); debug(9, "CP_PUSH_DEREFERENCED_STRUCTURE: %d => %p", parameter, ptr); break; diff --git a/sword2/layers.cpp b/sword2/layers.cpp index 174c1b3f4f..ad2cc47d4a 100644 --- a/sword2/layers.cpp +++ b/sword2/layers.cpp @@ -55,6 +55,10 @@ int32 Sword2Engine::initBackground(int32 res, int32 new_palette) { assert(res); debug(1, "CHANGED TO LOCATION \"%s\"", fetchObjectName(res)); + // The resources age every time a new room is entered. + _resman->passTime(); + _resman->expelOldResources(); + clearFxQueue(); _graphics->waitForFade(); @@ -75,7 +79,7 @@ int32 Sword2Engine::initBackground(int32 res, int32 new_palette) { // info/and set them up at the beginning of the sort list - why do it // each cycle - uint8 *file = _resman->openResource(_thisScreen.background_layer_id); + byte *file = _resman->openResource(_thisScreen.background_layer_id); ScreenHeader *screen_head = fetchScreenHeader(file); // set number of special sort layers diff --git a/sword2/logic.h b/sword2/logic.h index dc9852d09f..3d7586b5c3 100644 --- a/sword2/logic.h +++ b/sword2/logic.h @@ -87,7 +87,7 @@ private: uint32 textNumber; uint16 startFrame; uint16 endFrame; - Memory *text_mem; + byte *text_mem; uint32 speechBufferSize; uint16 *speech_mem; }; diff --git a/sword2/maketext.cpp b/sword2/maketext.cpp index 7d90f9ba3e..83dbb253e3 100644 --- a/sword2/maketext.cpp +++ b/sword2/maketext.cpp @@ -57,9 +57,8 @@ namespace Sword2 { // our character set is in the '@' position /** - * This function creates a new text sprite in a movable memory block. It must - * be locked before use, i.e. lock, draw sprite, unlock/free. The sprite data - * contains a FrameHeader, but not a standard file header. + * This function creates a new text sprite. The sprite data contains a + * FrameHeader, but not a standard file header. * * @param sentence pointer to a null-terminated string * @param maxWidth the maximum allowed text sprite width in pixels @@ -72,7 +71,7 @@ namespace Sword2 { * error-signal character (chequered flag) */ -Memory *FontRenderer::makeTextSprite(uint8 *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border) { +byte *FontRenderer::makeTextSprite(byte *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border) { debug(3, "makeTextSprite(\"%s\", maxWidth=%u)", sentence, maxWidth); _borderPen = border; @@ -93,23 +92,23 @@ Memory *FontRenderer::makeTextSprite(uint8 *sentence, uint16 maxWidth, uint8 pen // Allocate memory for array of lineInfo structures - Memory *line = _vm->_memory->allocMemory(MAX_LINES * sizeof(LineInfo), MEM_locked, UID_temp); + byte *line = (byte *) malloc(MAX_LINES * sizeof(LineInfo)); // Get details of sentence breakdown into array of LineInfo structures // and get the number of lines involved - uint16 noOfLines = analyseSentence(sentence, maxWidth, fontRes, (LineInfo *) line->ad); + uint16 noOfLines = analyseSentence(sentence, maxWidth, fontRes, (LineInfo *) line); // Construct the sprite based on the info gathered - returns floating // mem block - Memory *textSprite = buildTextSprite(sentence, fontRes, pen, (LineInfo *) line->ad, noOfLines); + byte *textSprite = buildTextSprite(sentence, fontRes, pen, (LineInfo *) line, noOfLines); - _vm->_memory->freeMemory(line); + free(line); return textSprite; } -uint16 FontRenderer::analyseSentence(uint8 *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line) { +uint16 FontRenderer::analyseSentence(byte *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line) { // joinWidth = how much extra space is needed to append a word to a // line. NB. SPACE requires TWICE the '_charSpacing' to join a word // to line @@ -120,7 +119,7 @@ uint16 FontRenderer::analyseSentence(uint8 *sentence, uint16 maxWidth, uint32 fo uint16 pos = 0; bool firstWord = true; - uint8 ch; + byte ch; do { uint16 wordWidth = 0; @@ -193,7 +192,7 @@ uint16 FontRenderer::analyseSentence(uint8 *sentence, uint16 maxWidth, uint32 fo * error-signal character (chequered flag) */ -Memory *FontRenderer::buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines) { +byte *FontRenderer::buildTextSprite(byte *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines) { uint16 i; // Find the width of the widest line in the output text @@ -213,12 +212,12 @@ Memory *FontRenderer::buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen // Allocate memory for the text sprite uint32 sizeOfSprite = spriteWidth * spriteHeight; - Memory *textSprite = _vm->_memory->allocMemory(sizeof(FrameHeader) + sizeOfSprite, MEM_locked, UID_text_sprite); + byte *textSprite = (byte *) malloc(sizeof(FrameHeader) + sizeOfSprite); // At this stage, textSprite points to an unmovable memory block. Set // up the frame header. - FrameHeader *frameHeadPtr = (FrameHeader *) textSprite->ad; + FrameHeader *frameHeadPtr = (FrameHeader *) textSprite; frameHeadPtr->compSize = 0; frameHeadPtr->width = spriteWidth; @@ -228,10 +227,10 @@ Memory *FontRenderer::buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen // Clear the entire sprite to make it transparent. - uint8 *linePtr = textSprite->ad + sizeof(FrameHeader); + byte *linePtr = textSprite + sizeof(FrameHeader); memset(linePtr, 0, sizeOfSprite); - uint8 *charSet = _vm->_resman->openResource(fontRes); + byte *charSet = _vm->_resman->openResource(fontRes); // Build the sprite, one line at a time @@ -239,7 +238,7 @@ Memory *FontRenderer::buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen for (i = 0; i < noOfLines; i++) { // Center each line - uint8 *spritePtr = linePtr + (spriteWidth - line[i].width) / 2; + byte *spritePtr = linePtr + (spriteWidth - line[i].width) / 2; // copy the sprite for each character in this line to the // text sprite and inc the sprite ptr by the character's @@ -261,8 +260,6 @@ Memory *FontRenderer::buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen _vm->_resman->closeResource(fontRes); - // Unlock the sprite memory block, so it's movable - _vm->_memory->floatMemory(textSprite); return textSprite; } @@ -272,8 +269,8 @@ Memory *FontRenderer::buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen * @return the width of the character */ -uint16 FontRenderer::charWidth(uint8 ch, uint32 fontRes) { - uint8 *charSet = _vm->_resman->openResource(fontRes); +uint16 FontRenderer::charWidth(byte ch, uint32 fontRes) { + byte *charSet = _vm->_resman->openResource(fontRes); FrameHeader *charFrame = findChar(ch, charSet); uint16 width = charFrame->width; @@ -293,7 +290,7 @@ uint16 FontRenderer::charWidth(uint8 ch, uint32 fontRes) { // and a pointer to the start of the character set. uint16 FontRenderer::charHeight(uint32 fontRes) { - uint8 *charSet = _vm->_resman->openResource(fontRes); + byte *charSet = _vm->_resman->openResource(fontRes); FrameHeader *charFrame = findChar(FIRST_CHAR, charSet); uint16 height = charFrame->height; @@ -309,7 +306,7 @@ uint16 FontRenderer::charHeight(uint32 fontRes) { * 'dud' character (chequered flag) */ -FrameHeader* FontRenderer::findChar(uint8 ch, uint8 *charSet) { +FrameHeader* FontRenderer::findChar(byte ch, byte *charSet) { if (ch < FIRST_CHAR) ch = DUD; return _vm->fetchFrameHeader(charSet, ch - FIRST_CHAR); @@ -325,12 +322,12 @@ FrameHeader* FontRenderer::findChar(uint8 ch, uint8 *charSet) { * LETTER_COL to pen. */ -void FontRenderer::copyChar(FrameHeader *charPtr, uint8 *spritePtr, uint16 spriteWidth, uint8 pen) { - uint8 *source = (uint8 *) charPtr + sizeof(FrameHeader); - uint8 *rowPtr = spritePtr; +void FontRenderer::copyChar(FrameHeader *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen) { + byte *source = (byte *) charPtr + sizeof(FrameHeader); + byte *rowPtr = spritePtr; for (uint i = 0; i < charPtr->height; i++) { - uint8 *dest = rowPtr; + byte *dest = rowPtr; if (pen) { // Use the specified colours @@ -373,7 +370,7 @@ void FontRenderer::copyChar(FrameHeader *charPtr, uint8 *spritePtr, uint16 sprit * RDSPR_DISPLAYALIGN or 0 */ -uint32 FontRenderer::buildNewBloc(uint8 *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification) { +uint32 FontRenderer::buildNewBloc(byte *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification) { uint32 i = 0; while (i < MAX_text_blocs && _blocList[i].text_mem) @@ -389,7 +386,7 @@ uint32 FontRenderer::buildNewBloc(uint8 *ascii, int16 x, int16 y, uint16 width, // without margin checking - used for debug text if (justification != NO_JUSTIFICATION) { - FrameHeader *frame_head = (FrameHeader *) _blocList[i].text_mem->ad; + FrameHeader *frame_head = (FrameHeader *) _blocList[i].text_mem; switch (justification) { case POSITION_AT_CENTRE_OF_BASE: @@ -462,7 +459,7 @@ uint32 FontRenderer::buildNewBloc(uint8 *ascii, int16 x, int16 y, uint16 width, void FontRenderer::printTextBlocs(void) { for (uint i = 0; i < MAX_text_blocs; i++) { if (_blocList[i].text_mem) { - FrameHeader *frame = (FrameHeader *) _blocList[i].text_mem->ad; + FrameHeader *frame = (FrameHeader *) _blocList[i].text_mem; SpriteInfo spriteInfo; spriteInfo.x = _blocList[i].x; @@ -474,7 +471,7 @@ void FontRenderer::printTextBlocs(void) { spriteInfo.scaledHeight = 0; spriteInfo.type = _blocList[i].type; spriteInfo.blend = 0; - spriteInfo.data = _blocList[i].text_mem->ad + sizeof(FrameHeader); + spriteInfo.data = _blocList[i].text_mem + sizeof(FrameHeader); spriteInfo.colourTable = 0; uint32 rv = _vm->_graphics->drawSprite(&spriteInfo); @@ -486,9 +483,8 @@ void FontRenderer::printTextBlocs(void) { void FontRenderer::killTextBloc(uint32 bloc_number) { bloc_number--; - assert(_blocList[bloc_number].text_mem); - _vm->_memory->freeMemory(_blocList[bloc_number].text_mem); - _blocList[bloc_number].text_mem = 0; + free(_blocList[bloc_number].text_mem); + _blocList[bloc_number].text_mem = NULL; } // Resource 3258 contains text from location script for 152 (install, save & @@ -501,7 +497,7 @@ void FontRenderer::killTextBloc(uint32 bloc_number) { #define SAVE_LINE_NO 1 void Sword2Engine::initialiseFontResourceFlags(void) { - uint8 *textFile = _resman->openResource(TEXT_RES); + byte *textFile = _resman->openResource(TEXT_RES); // If language is Polish or Finnish it requires alternate fonts. // Otherwise, use regular fonts diff --git a/sword2/maketext.h b/sword2/maketext.h index c249ad3a1a..adde69d9cd 100644 --- a/sword2/maketext.h +++ b/sword2/maketext.h @@ -61,7 +61,7 @@ enum { int16 x; int16 y; uint16 type; - Memory *text_mem; + byte *text_mem; }; // Info for each line of words in the output text sprite @@ -86,12 +86,12 @@ private: // each line - negative for overlap uint8 _borderPen; // output pen colour of character borders - uint16 analyseSentence(uint8 *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line); - Memory *buildTextSprite(uint8 *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines); - uint16 charWidth(uint8 ch, uint32 fontRes); + uint16 analyseSentence(byte *sentence, uint16 maxWidth, uint32 fontRes, LineInfo *line); + byte *buildTextSprite(byte *sentence, uint32 fontRes, uint8 pen, LineInfo *line, uint16 noOfLines); + uint16 charWidth(byte ch, uint32 fontRes); uint16 charHeight(uint32 fontRes); - FrameHeader* findChar(uint8 ch, uint8 *charSet); - void copyChar(FrameHeader *charPtr, uint8 *spritePtr, uint16 spriteWidth, uint8 pen); + FrameHeader* findChar(byte ch, byte *charSet); + void copyChar(FrameHeader *charPtr, byte *spritePtr, uint16 spriteWidth, uint8 pen); public: FontRenderer(Sword2Engine *vm) : _vm(vm) { @@ -99,12 +99,12 @@ public: _blocList[i].text_mem = NULL; } - Memory *makeTextSprite(uint8 *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border = BORDER_PEN); + byte *makeTextSprite(byte *sentence, uint16 maxWidth, uint8 pen, uint32 fontRes, uint8 border = BORDER_PEN); void killTextBloc(uint32 bloc_number); void printTextBlocs(void); - uint32 buildNewBloc(uint8 *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification); + uint32 buildNewBloc(byte *ascii, int16 x, int16 y, uint16 width, uint8 pen, uint32 type, uint32 fontRes, uint8 justification); }; } // End of namespace Sword2 diff --git a/sword2/mem_view.cpp b/sword2/mem_view.cpp deleted file mode 100644 index 7cc70b308f..0000000000 --- a/sword2/mem_view.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright (C) 1994-2004 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$ - */ - -#include "common/stdafx.h" -#include "sword2/sword2.h" -#include "sword2/console.h" -#include "sword2/resman.h" - -#define Debug_Printf _vm->_debugger->DebugPrintf - -namespace Sword2 { - -void MemoryManager::displayMemory(void) { - int pass, found_end, k, j, free = 0; - StandardHeader *file_header; - - char inf[][20] = { - { "M_null " }, - { "M_free " }, - { "M_locked" }, - { "M_float " } - }; - - j = _baseMemBlock; - do { - if (_memList[j].uid < 65536) { - file_header = (StandardHeader *) _vm->_resman->openResource(_memList[j].uid); - // close immediately so give a true count - _vm->_resman->closeResource(_memList[j].uid); - - debug(5, "view %d", _memList[j].uid); - - pass = 0; - found_end = 0; - - for (k = 0; k < 30; k++) { - if (file_header->name[k] == 0) { - found_end = 1; - break; - } - - if (file_header->name[k] < ' ' || file_header->name[k] > 'z') - pass = 1; - } - - if (file_header->name[0] == 0) - pass = 1; // also illegal - - if (!pass && found_end) { // && file_header->fileType < 10) - Debug_Printf("%d %s, size 0x%.5x (%dk %d%%), res %d %s %s, A%d, C%d\n", - j, inf[_memList[j].state], - _memList[j].size, - _memList[j].size / 1024, - (_memList[j].size * 100) / _totalFreeMemory, - _memList[j].uid, - _vm->_resman->fetchCluster(_memList[j].uid), - file_header->name, - _vm->_resman->fetchAge(_memList[j].uid), - _vm->_resman->fetchCount(_memList[j].uid)); - } else - Debug_Printf(" %d is an illegal resource\n", _memList[j].uid); - } else { - Debug_Printf("%d %s, size 0x%.5x (%dk %d%%), %s\n", - j, inf[_memList[j].state], _memList[j].size, - _memList[j].size / 1024, - (_memList[j].size * 100) / _totalFreeMemory, - fetchOwner(_memList[j].uid)); - } - - if (_memList[j].state == MEM_free) - free += _memList[j].size; - - j = _memList[j].child; - } while (j != -1); - - Debug_Printf("(total memory block 0x%.8x %dk %dMB) %d / %d%% free\n", - _totalFreeMemory, _totalFreeMemory / 1024, - _totalFreeMemory / (1000 * 1024), free, - (free * 100) / _totalFreeMemory); -} - -const char *MemoryManager::fetchOwner(uint32 uid) { - static char buf[50]; - - switch (uid) { - case UID_memman: - return "MEMMAN"; - case UID_font: - return "font"; - case UID_temp: - return "temp ram allocation"; - case UID_decompression_buffer: - return "decompression buffer"; - case UID_shrink_buffer: - return "shrink buffer"; - case UID_con_sprite: - return "console sprite buffer"; - case UID_text_sprite: - return "text sprite"; - case UID_walk_anim: - return "walk anim"; - case UID_savegame_buffer: - return "savegame buffer"; - default: - sprintf(buf, " %d?", uid); - return buf; - } -} - -void MemoryManager::memoryString(char *string) { - int blockNo = _baseMemBlock; - int blocksUsed = 0; - int mem_free = 0; - int mem_locked = 0; - int mem_floating = 0; - int memUsed = 0; - int percent; - - while (blockNo != -1) { - switch (_memList[blockNo].state) { - case MEM_free: - mem_free++; - break; - - case MEM_locked: - mem_locked++; - memUsed += _memList[blockNo].size; - break; - - case MEM_float: - mem_floating++; - memUsed += _memList[blockNo].size; - break; - } - - blocksUsed++; - blockNo = _memList[blockNo].child; - } - - percent = (memUsed * 100) / _totalFreeMemory; - - sprintf(string, - "locked(%u)+float(%u)+free(%u) = %u/%u blocks (%u%% used)(cur %uk)", - mem_locked, mem_floating, mem_free, blocksUsed, MAX_mem_blocks, - percent, (_vm->_resman->fetchUsage() / 1024)); -} - -} // End of namespace Sword2 diff --git a/sword2/memory.cpp b/sword2/memory.cpp index 5b01e03364..4155156d17 100644 --- a/sword2/memory.cpp +++ b/sword2/memory.cpp @@ -17,560 +17,211 @@ * $Header$ */ -// memory manager -// - "remember, it's not good to leave memory locked for a moment longer -// than necessary" Tony -// - "actually, in a sequential system theoretically you never need to lock -// any memory!" Chris ;) +// The new memory manager, now only used by the resource manager. Unlike the +// original, this one does not allocate a 12 MB memory pool at startup. // -// This is a very simple implementation but I see little advantage to being -// any cleverer with the coding - i could have put the mem blocks before the -// defined blocks instead of in an array and then used pointers to -// child/parent blocks. But why bother? I've Kept it simple. When it needs -// updating or customising it will be accessable to anyone who looks at it. +// There is one thing that prevents us from replacing the whole memory manager +// with the standard memory allocation functions: Broken Sword II absolutely, +// positively needs to be able to encode pointers as 32-bit integers. The +// original engine did this simply by casting between pointers and integers, +// but as far as I know that's not a very portable thing to do. // -// Doesn't have a purgeable/age consituant yet - if anyone wants this then -// I'll add it in. - -// MemMan v1.1 +// For a while I was hopeing that the engine only needed pointers as function +// parameters, in which case I could have extended the stack to use a struct or +// a union instead, but no such luck. There is code in walker.cpp that +// obviously violates that assumption, and there are probably other, more +// well-hidden places, as well. +// +// This attacks the problem from the direction of another limitation in the +// original memory manager: it could only handle up to 999 blocks of memory. +// This memory manager has the same limitation, although it's probably way too +// large now, which means that a pointer can be encoded as 10 bits to store the +// block id, and another 22 bits to store an index into that block. #include "common/stdafx.h" #include "sword2/sword2.h" -#include "sword2/resman.h" +#include "sword2/console.h" namespace Sword2 { -#define MEMORY_POOL (1024 * 12000) +#define MAX_BLOCKS 999 -// #define MEMDEBUG 1 +#define Debug_Printf _vm->_debugger->DebugPrintf MemoryManager::MemoryManager(Sword2Engine *vm) : _vm(vm) { - uint32 j; - uint8 *memory_base; - - _suggestedStart = 0; - - _totalFreeMemory = MEMORY_POOL; - - memory_base = (uint8 *) malloc(_totalFreeMemory); - - if (!memory_base) - error("MemoryManager: couldn't malloc %d bytes", _totalFreeMemory); - - // the original malloc address - _freeMemman = memory_base; + _memBlocks = (MemBlock *) malloc(MAX_BLOCKS * sizeof(MemBlock)); + _memBlockIndex = (MemBlock **) malloc(MAX_BLOCKS * sizeof(MemBlock *)); + _idStack = (int16 *) malloc(MAX_BLOCKS * sizeof(int16)); - // set all but first handle to unused - for (j = 1; j < MAX_mem_blocks; j++) - _memList[j].state = MEM_null; + _totAlloc = 0; + _numBlocks = 0; - // total used (free, locked or floating) - _totalBlocks = 1; - - _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 = (uint32) UID_memman; // init id + for (int i = 0; i < MAX_BLOCKS; i++) { + _idStack[i] = MAX_BLOCKS - i - 1; + _memBlocks[i].ptr = NULL; + _memBlockIndex[i] = NULL; + } - _baseMemBlock = 0; // for now + _idStackPtr = MAX_BLOCKS; } -MemoryManager::~MemoryManager(void) { - free(_freeMemman); +MemoryManager::~MemoryManager() { + for (int i = 0; i < MAX_BLOCKS; i++) + free(_memBlocks[i].ptr); + free(_memBlocks); + free(_memBlockIndex); + free(_idStack); } -// I don't know about C++, but here's what "C: A Reference Manual" (Harbison & -// Steele) has to say: -// -// "There is no requirement in C that any of the integral types be large enough -// to represent a pointer, although C programmers often assume that type long -// is large enough, which it is on most computers. In C99, header inttypes.h -// may define integer types intptr_t and uintptr_t, which are guaranteed large -// enough to hold a pointer as an integer." -// -// The script engine frequently needs to pass around pointers to various -// structures etc. and, and used to do so by casting them to int32 and back -// again. Since those pointers always point to memory that belongs to the -// memory manager, we can easily represent them as offsets instead. +int32 MemoryManager::encodePtr(byte *ptr) { + int idx = findPointerInIndex(ptr); -int32 MemoryManager::ptrToInt(const uint8 *p) { - debug(9, "ptrToInt: %p -> %d", p, p - _freeMemman); + if (idx == -1) + error("Encoding non-allocated pointer %p", ptr); - if (p < _freeMemman || p >= &_freeMemman[MEMORY_POOL]) - warning("ptrToInt: Converting bad pointer: %p", p); + int id = _memBlockIndex[idx]->id; - return p - _freeMemman; + return (id << 22) | (ptr - _memBlocks[id].ptr); } -uint8 *MemoryManager::intToPtr(int32 n) { - debug(9, "intToPtr: %d -> %p", n, &_freeMemman[n]); +byte *MemoryManager::decodePtr(int32 n) { + int16 id = (n >> 22) & 0x03ff; + int32 offset = n & 0x003fffff; - if (n < 0 || n >= MEMORY_POOL) - warning("intToPtr: Converting bad integer: %d", n); - - return &_freeMemman[n]; + return _memBlocks[id].ptr + offset; } -Memory *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 - // or a pointer to a mem structure - - int32 nu_block; - uint32 spawn = 0; - uint32 slack; - - // we must first round the size UP to a dword, so subsequent blocks - // will start dword alligned - - size += 3; // move up - size &= 0xfffffffc; // and back down to boundary - - // find a free block large enough - - // the defragger returns when its made a big enough block. This is - // a good time to defrag as we're probably not doing anything super - // time-critical at the moment - - if ((nu_block = defragMemory(size)) == -1) { - // error - couldn't find a big enough space - return 0; - } - - // an exact fit? - if (_memList[nu_block].size == size) { - // no new block is required as the fit is perfect - _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 - debugMemory(); -#endif - - return &_memList[nu_block]; - } - - // nu_block is the free block to split, forming our locked/float block - // with a new free block in any remaining space - - // If our child is free then is can expand downwards to eat up our - // chopped space this is good because it doesn't create an extra block - // so keeping the block count down. - // - // Why? Imagine you Talloc 1000k, then free it. Now keep allocating 10 - // bytes less and freeing again you end up with thousands of new free - // mini blocks. This way avoids that as the free child keeps growing - // downwards. - - 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 +int16 MemoryManager::findExactPointerInIndex(byte *ptr) { + int left = 0; + int right = _numBlocks - 1; - slack = _memList[nu_block].size - size; + while (right >= left) { + int n = (left + right) / 2; - _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 + if (_memBlockIndex[n]->ptr == ptr) + return n; - // child starts after us - _memList[_memList[nu_block].child].ad = _memList[nu_block].ad + size; - // child's size increases - _memList[_memList[nu_block].child].size += slack; - - return &_memList[nu_block]; + if (_memBlockIndex[n]->ptr > ptr) + right = n - 1; + else + left = n + 1; } - // otherwise we spawn a new block after us and before our child - our - // child being a proper block that we cannot change + return -1; +} - // we remain a child of our parent - // we spawn a new child and it inherits our current child +int16 MemoryManager::findPointerInIndex(byte *ptr) { + int left = 0; + int right = _numBlocks - 1; - // find a NULL slot for a new block + while (right >= left) { + int n = (left + right) / 2; - while (_memList[spawn].state != MEM_null && spawn!=MAX_mem_blocks) - spawn++; + if (_memBlockIndex[n]->ptr <= ptr && _memBlockIndex[n]->ptr + _memBlockIndex[n]->size > ptr) + return n; - 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 - debugMemory(); - error("Out of mem blocks in Talloc()"); + if (_memBlockIndex[n]->ptr > ptr) + right = n - 1; + else + left = n + 1; } - _memList[spawn].state = MEM_free; // new block is free - _memList[spawn].uid = (uint32) UID_memman; // a memman created bloc - - // size of the existing parent free block minus the size of the new - // space Talloc'ed. - - _memList[spawn].size = _memList[nu_block].size - size; + return -1; +} - // IOW the remaining memory is given to the new free block +int16 MemoryManager::findInsertionPointInIndex(byte *ptr) { + if (_numBlocks == 0) + return 0; - // we start 1 byte after the newly allocated block - _memList[spawn].ad = _memList[nu_block].ad + size; + int left = 0; + int right = _numBlocks - 1; + int n = 0; - // the spawned child gets it parent - the newly allocated block - _memList[spawn].parent = nu_block; + while (right >= left) { + n = (left + right) / 2; - // the new child inherits the parents old child (we are its new - // child "Waaaa") - _memList[spawn].child = _memList[nu_block].child; + if (_memBlockIndex[n]->ptr == ptr) + return -1; - // is the spawn the end block? - if (_memList[spawn].child != -1) { - // the child of the new free-spawn needs to know its new parent - _memList[_memList[spawn].child].parent = spawn; + if (_memBlockIndex[n]->ptr > ptr) + right = n - 1; + else + left = n + 1; } - _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 - _memList[nu_block].child = spawn; - - //we've brought a new block into the world. Ahhh! - _totalBlocks++; + if (_memBlockIndex[n]->ptr < ptr) + n++; -#ifdef MEMDEBUG - debugMemory(); -#endif - - return &_memList[nu_block]; + return n; } -void MemoryManager::freeMemory(Memory *block) { - // kill a block of memory - which was presumably floating or locked - // once you've done this the memory may be recycled +byte *MemoryManager::memAlloc(uint32 size, int16 uid) { + byte *ptr = (byte *) malloc(size); - block->state = MEM_free; - block->uid = (uint32) UID_memman; // belongs to the memory manager again + assert(ptr); + assert(_idStackPtr > 0); -#ifdef MEMDEBUG - debugMemory(); -#endif -} + // Get the new block's id from the stack. + int16 id = _idStack[--_idStackPtr]; -void MemoryManager::floatMemory(Memory *block) { - // set a block to float - // wont be trashed but will move around in memory + _memBlocks[id].id = id; + _memBlocks[id].uid = uid; + _memBlocks[id].ptr = ptr; + _memBlocks[id].size = size; - block->state = MEM_float; + // The memory index provides a method for figuring out which memory + // block an arbitrary pointer points to. A balanced tree might be more + // efficient, but such beasts are tricky to implement. -#ifdef MEMDEBUG - debugMemory(); -#endif -} + int16 idx = findInsertionPointInIndex(ptr); -void MemoryManager::lockMemory(Memory *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 + assert(idx != -1); - // can't move now - this block is now crying out to be floated or - // free'd again + for (int i = _numBlocks; i > idx; i--) + _memBlockIndex[i] = _memBlockIndex[i - 1]; - block->state = MEM_locked; + _memBlockIndex[idx] = &_memBlocks[id]; + _numBlocks++; + _totAlloc += size; -#ifdef MEMDEBUG - debugMemory(); -#endif + return _memBlocks[id].ptr; } -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 - // enough block - this is enough defragging. - - int32 cur_block; // block 0 remains the parent block - int32 original_parent,child, end_child; - uint32 j; - uint32 *a; - uint32 *b; - - // cur_block = _baseMemBlock; //the mother of all parents - cur_block = _suggestedStart; - - do { - // is current block a free block? - 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 (_memList[cur_block].child == -1) { - // no luck, couldn't find a big enough block - return -1; - } - - // current free block is too small, but if its child - // is *also* free then merge the two together - - if (_memList[_memList[cur_block].child].state == MEM_free) { - // ok, we nuke the child and inherit its child - child = _memList[cur_block].child; - - // our size grows by the size of our child - _memList[cur_block].size += _memList[child].size; - - // our new child is our old childs, child - _memList[cur_block].child = _memList[child].child; - - // not if the chld we're nuking is the end - // child (it has no child) - - if (_memList[child].child != -1) { - // the (nuked) old childs childs - // parent is now us - _memList[_memList[child].child].parent = cur_block; - } - - // clean up the nuked child, so it can be used - // again - _memList[child].state = MEM_null; - - _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, - // parent/child relationships must be such - // that the memory is all continuous between - // blocks. ie. a childs memory always begins 1 - // byte after its parent finishes. However, the - // positions in the memory list may become - // truly random, but, any particular block of - // locked or floating memory must retain its - // position within the _memList - the float - // stays a float because the handle/pointer - // has been passed back - // - // what this means is that when the physical - // memory of the foat moves down (and the free - // up) the child becomes the parent and the - // parent the child but, remember, the parent - // had a parent and the child another child - - // these swap over too as the parent/child swap - // takes place - phew. - - // our child is currently floating - child = _memList[cur_block].child; - - // move the higher float down over the free - // block - // memcpy(_memList[cur_block].ad, _memList[child].ad, _memList[child].size); - - a = (uint32 *) _memList[cur_block].ad; - b = (uint32 *) _memList[child].ad; - - for (j = 0; j < _memList[child].size / 4; j++) - *(a++) = *(b++); - - // both *ad's change - // the float is now where the free was and the - // free goes up by the size of the float - // (which has come down) - - _memList[child].ad = _memList[cur_block].ad; - _memList[cur_block].ad += _memList[child].size; - - // 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 = _memList[cur_block].parent; - - // the free's child becomes its parent - _memList[cur_block].parent = child; - - // the new child inherits its previous childs - // child - _memList[cur_block].child = _memList[child].child; - - // save this - see next line - end_child = _memList[child].child; - - // the floats parent becomes its child - _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 - _memList[end_child].parent = cur_block; - } - - // if the base block was the true base parent - if (original_parent == -1) { - // then the child that has moved down - // becomes the base block as it sits - // at the lowest possible memory - // location - _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 - _memList[original_parent].child = child; - } - } 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=_memList[cur_block].child; - } - } else { - // move to next one along, the current must be - // floating, locked, or a NULL slot - 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 MemoryManager::memFree(byte *ptr) { + int16 idx = findExactPointerInIndex(ptr); -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 - - int j; - char inf[][20] = { - { "MEM_null" }, - { "MEM_free" }, - { "MEM_locked" }, - { "MEM_float" } - }; - - debug(5, "base %d total %d", _baseMemBlock, _totalBlocks); - - // first in mem list order - for (j = 0; j < MAX_mem_blocks; j++) { - if (_memList[j].state == MEM_null) - debug(5, "%d- NULL", j); - else - debug(5, "%d- state %s, ad %p, size %d, p %d, c %d, id %d", - j, inf[_memList[j].state], _memList[j].ad, - _memList[j].size, _memList[j].parent, - _memList[j].child, _memList[j].uid); + if (idx == -1) { + warning("Freeing non-allocated pointer %p", ptr); + return; } - // now in child/parent order - j = _baseMemBlock; - do { - debug(5, " %d- state %s, ad %p, size %d, p %d, c %d, id %d", - j, inf[_memList[j].state], _memList[j].ad, - _memList[j].size, _memList[j].parent, - _memList[j].child, _memList[j].uid); - - j = _memList[j].child; - } while (j != -1); -} + // Put back the id on the stack + _idStack[_idStackPtr++] = _memBlockIndex[idx]->id; -Memory *MemoryManager::allocMemory(uint32 size, uint32 type, uint32 unique_id) { - // the high level allocator + free(_memBlockIndex[idx]->ptr); + _memBlockIndex[idx]->ptr = NULL; - // can ask the resman to remove old resources to make space - will - // either do it or halt the system - - Memory *membloc; - int j; - uint32 free = 0; - - while (virtualDefrag(size)) { - // trash the oldest closed resource - if (!_vm->_resman->helpTheAgedOut()) { - error("alloc ran out of memory: size=%d type=%d unique_id=%d", size, type, unique_id); - } - } + _totAlloc -= _memBlockIndex[idx]->size; + + // Remove the pointer from the index + _numBlocks--; - membloc = lowLevelAlloc(size, type, unique_id); - - if (membloc == 0) { - error("lowLevelAlloc failed to get memory virtualDefrag said was there"); - } - - j = _baseMemBlock; - do { - - if (_memList[j].state == MEM_free) - free += _memList[j].size; - - j = _memList[j].child; - } while (j != -1); + for (int i = idx; i < _numBlocks; i++) + _memBlockIndex[i] = _memBlockIndex[i + 1]; +} - // return the pointer to the memory - return membloc; +void MemoryManager::memDisplay() { + for (int i = 0; i < _numBlocks; i++) + Debug_Printf("%d: %ld bytes allocated by resource %d\n", i, _memBlocks[i].size, _memBlocks[i].uid); } -// Maximum allowed wasted memory. -#define MAX_WASTAGE 51200 - -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 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. - // - // The reason for its current slowness is that the defragger is - // potentially called several times, each time shifting upto 20Megs - // around, to obtain the required free block. - - int32 cur_block; - uint32 currentBubbleSize = 0; - - cur_block = _baseMemBlock; - _suggestedStart = _baseMemBlock; - - do { - 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 - // will be created at the bottom and float to the - // top. If we ignore the top gap then a large enough - // bubble will form lower down the tube. Thus less - // memory will need to be shifted. - - 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 (_memList[cur_block].state == MEM_locked) { - currentBubbleSize = 0; - // Any free block of the correct size will be above - // this locked block. - _suggestedStart = _memList[cur_block].child; - } - - cur_block = _memList[cur_block].child; - } while (cur_block != -1); - - return 1; +void MemoryManager::memStatusStr(char *buf) { + if (_totAlloc < 1024) + sprintf(buf, "%u bytes in %d memory blocks", _totAlloc, _numBlocks); + else if (_totAlloc < 1048576) + sprintf(buf, "%uK in %d memory blocks", _totAlloc / 1024, _numBlocks); + else + sprintf(buf, "%.02fM in %d memory blocks", _totAlloc / 1048576., _numBlocks); } } // End of namespace Sword2 diff --git a/sword2/memory.h b/sword2/memory.h index 0c3095e048..f483a03498 100644 --- a/sword2/memory.h +++ b/sword2/memory.h @@ -22,92 +22,42 @@ namespace Sword2 { -struct Memory { - uint32 state; - uint32 age; // *not used* +struct MemBlock { + int16 id; + int16 uid; + byte *ptr; uint32 size; - int32 parent; // who is before us - int32 child; // who is after us - // id of a position in the _resList or some other unique id - for the - // visual display only - uint32 uid; - uint8 *ad; -}; - -enum { - MEM_null = 0, // null - MEM_free = 1, - MEM_locked = 2, - MEM_float = 3 -}; - -//--------------------------------------- -// MEMORY BLOCKS - -#define MAX_mem_blocks 999 - -// maintain at a good 50% higher than the -// highest recorded value from the on-screen info -//--------------------------------------- - -enum { - UID_memman = 0xffffffff, - UID_NULL = 0xfffffffe, // FREE - UID_font = 0xfffffffd, - UID_temp = 0xfffffffc, - UID_decompression_buffer = 0xfffffffb, - UID_shrink_buffer = 0xfffffffa, - UID_con_sprite = 0xfffffff9, - UID_text_sprite = 0xfffffff8, - UID_walk_anim = 0xfffffff7, - UID_savegame_buffer = 0xfffffff6, - UID_restoregame_buffer = 0xfffffff5 }; class MemoryManager { private: Sword2Engine *_vm; - // Address of init malloc to be freed later - uint8 *_freeMemman; - - uint32 _totalFreeMemory; - uint32 _totalBlocks; + MemBlock *_memBlocks; + MemBlock **_memBlockIndex; + int16 _numBlocks; - // Start position of the defragger as indicated by its sister, - // VirtualDefrag. - int32 _suggestedStart; + uint32 _totAlloc; - Memory *lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id); - int32 defragMemory(uint32 req_size); + int16 *_idStack; + int16 _idStackPtr; - // 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); + int16 findExactPointerInIndex(byte *ptr); + int16 findPointerInIndex(byte *ptr); + int16 findInsertionPointInIndex(byte *ptr); public: - // List of defined memory handles - each representing a block of memory - Memory _memList[MAX_mem_blocks]; - uint32 _baseMemBlock; - MemoryManager(Sword2Engine *vm); - ~MemoryManager(void); + ~MemoryManager(); - int32 ptrToInt(const uint8 *p); - uint8 *intToPtr(int32 n); + int32 encodePtr(byte *ptr); + byte *decodePtr(int32 n); - Memory *allocMemory(uint32 size, uint32 type, uint32 unique_id); - void freeMemory(Memory *block); - void floatMemory(Memory *block); - void lockMemory(Memory *block); + byte *memAlloc(uint32 size, int16 uid); + void memFree(byte *ptr); - // Debugging function - void displayMemory(void); - void memoryString(char *string); + void memDisplay(); + void memStatusStr(char *buf); }; } // End of namespace Sword2 diff --git a/sword2/module.mk b/sword2/module.mk index 784f541fcc..1b83bb5dd1 100644 --- a/sword2/module.mk +++ b/sword2/module.mk @@ -14,7 +14,6 @@ MODULE_OBJS := \ sword2/logic.o \ sword2/maketext.o \ sword2/memory.o \ - sword2/mem_view.o \ sword2/mouse.o \ sword2/protocol.o \ sword2/resman.o \ diff --git a/sword2/mouse.cpp b/sword2/mouse.cpp index 883d24d3a1..6814a570e5 100644 --- a/sword2/mouse.cpp +++ b/sword2/mouse.cpp @@ -131,7 +131,7 @@ void Sword2Engine::systemMenuMouse(void) { uint32 safe_looping_music_id; MouseEvent *me; int hit; - uint8 *icon; + byte *icon; int32 pars[2]; uint32 icon_list[5] = { OPTIONS_ICON, @@ -772,15 +772,12 @@ void Sword2Engine::mouseOnOff(void) { } void Sword2Engine::setMouse(uint32 res) { - uint8 *icon; - uint32 len; - // high level - whats the mouse - for the engine _mousePointerRes = res; if (res) { - icon = _resman->openResource(res) + sizeof(StandardHeader); - len = _resman->_resList[res]->size - sizeof(StandardHeader); + byte *icon = _resman->openResource(res) + sizeof(StandardHeader); + uint32 len = _resman->fetchLen(res) - sizeof(StandardHeader); // don't pulse the normal pointer - just do the regular anim // loop @@ -798,17 +795,13 @@ void Sword2Engine::setMouse(uint32 res) { } void Sword2Engine::setLuggage(uint32 res) { - uint8 *icon; - uint32 len; - _realLuggageItem = res; if (res) { - icon = _resman->openResource(res) + sizeof(StandardHeader); - len = _resman->_resList[res]->size - sizeof(StandardHeader); - - _graphics->setLuggageAnim(icon, len); + byte *icon = _resman->openResource(res) + sizeof(StandardHeader); + uint32 len = _resman->fetchLen(res) - sizeof(StandardHeader); + _graphics->setLuggageAnim(icon + sizeof(StandardHeader), len); _resman->closeResource(res); } else _graphics->setLuggageAnim(NULL, 0); @@ -853,7 +846,7 @@ uint32 Sword2Engine::checkMouseList(void) { void Sword2Engine::createPointerText(uint32 text_id, uint32 pointer_res) { uint32 local_text; uint32 text_res; - uint8 *text; + byte *text; // offsets for pointer text sprite from pointer position int16 xOffset, yOffset; uint8 justification; @@ -1179,7 +1172,7 @@ int32 Logic::fnRegisterMouse(int32 *params) { // params: 0 pointer to ObjectMouse or 0 for no write to mouse // list - _vm->registerMouse((ObjectMouse *) _vm->_memory->intToPtr(params[0])); + _vm->registerMouse((ObjectMouse *) _vm->_memory->decodePtr(params[0])); return IR_CONT; } @@ -1203,7 +1196,7 @@ int32 Logic::fnRegisterPointerText(int32 *params) { int32 Logic::fnInitFloorMouse(int32 *params) { // params: 0 pointer to object's mouse structure - ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->intToPtr(params[0]); + ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->decodePtr(params[0]); // floor is always lowest priority @@ -1221,7 +1214,7 @@ int32 Logic::fnInitFloorMouse(int32 *params) { int32 Logic::fnSetScrollLeftMouse(int32 *params) { // params: 0 pointer to object's mouse structure - ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->intToPtr(params[0]); + ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->decodePtr(params[0]); // Highest priority @@ -1245,7 +1238,7 @@ int32 Logic::fnSetScrollLeftMouse(int32 *params) { int32 Logic::fnSetScrollRightMouse(int32 *params) { // params: 0 pointer to object's mouse structure - ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->intToPtr(params[0]); + ObjectMouse *ob_mouse = (ObjectMouse *) _vm->_memory->decodePtr(params[0]); // Highest priority diff --git a/sword2/protocol.cpp b/sword2/protocol.cpp index 85a2bc35e2..4f7f2350fc 100644 --- a/sword2/protocol.cpp +++ b/sword2/protocol.cpp @@ -28,12 +28,10 @@ namespace Sword2 { * of the screen file. */ -uint8 *Sword2Engine::fetchPalette(uint8 *screenFile) { - uint8 *palette; - +byte *Sword2Engine::fetchPalette(byte *screenFile) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); - palette = (uint8 *) mscreenHeader + mscreenHeader->palette; + byte *palette = (byte *) mscreenHeader + mscreenHeader->palette; // Always set colour 0 to black, because while most background screen // palettes have a bright colour 0 it should come out as black in the @@ -52,10 +50,10 @@ uint8 *Sword2Engine::fetchPalette(uint8 *screenFile) { * to the start of the screen file. */ -uint8 *Sword2Engine::fetchPaletteMatchTable(uint8 *screenFile) { +byte *Sword2Engine::fetchPaletteMatchTable(byte *screenFile) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); - return (uint8 *) mscreenHeader + mscreenHeader->paletteTable; + return (byte *) mscreenHeader + mscreenHeader->paletteTable; } /** @@ -63,9 +61,9 @@ uint8 *Sword2Engine::fetchPaletteMatchTable(uint8 *screenFile) { * the screen file. */ -ScreenHeader *Sword2Engine::fetchScreenHeader(uint8 *screenFile) { +ScreenHeader *Sword2Engine::fetchScreenHeader(byte *screenFile) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); - ScreenHeader *screenHeader = (ScreenHeader *) ((uint8 *) mscreenHeader + mscreenHeader->screen); + ScreenHeader *screenHeader = (ScreenHeader *) ((byte *) mscreenHeader + mscreenHeader->screen); return screenHeader; } @@ -76,7 +74,7 @@ ScreenHeader *Sword2Engine::fetchScreenHeader(uint8 *screenFile) { * the number of layers on this screen. */ -LayerHeader *Sword2Engine::fetchLayerHeader(uint8 *screenFile, uint16 layerNo) { +LayerHeader *Sword2Engine::fetchLayerHeader(byte *screenFile, uint16 layerNo) { #ifdef _SWORD2_DEBUG ScreenHeader *screenHead = fetchScreenHeader(screenFile); @@ -86,7 +84,7 @@ LayerHeader *Sword2Engine::fetchLayerHeader(uint8 *screenFile, uint16 layerNo) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); - LayerHeader *layerHeader = (LayerHeader *) ((uint8 *) mscreenHeader + mscreenHeader->layers + (layerNo * sizeof(LayerHeader))); + LayerHeader *layerHeader = (LayerHeader *) ((byte *) mscreenHeader + mscreenHeader->layers + (layerNo * sizeof(LayerHeader))); return layerHeader; } @@ -96,10 +94,10 @@ LayerHeader *Sword2Engine::fetchLayerHeader(uint8 *screenFile, uint16 layerNo) { * start of the screen file. */ -uint8 *Sword2Engine::fetchShadingMask(uint8 *screenFile) { +byte *Sword2Engine::fetchShadingMask(byte *screenFile) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); - return (uint8 *) mscreenHeader + mscreenHeader->maskOffset; + return (byte *) mscreenHeader + mscreenHeader->maskOffset; } /** @@ -107,7 +105,7 @@ uint8 *Sword2Engine::fetchShadingMask(uint8 *screenFile) { * anim file. */ -AnimHeader *Sword2Engine::fetchAnimHeader(uint8 *animFile) { +AnimHeader *Sword2Engine::fetchAnimHeader(byte *animFile) { return (AnimHeader *) (animFile + sizeof(StandardHeader)); } @@ -117,7 +115,7 @@ AnimHeader *Sword2Engine::fetchAnimHeader(uint8 *animFile) { * number exceeds the number of frames in this anim. */ -CdtEntry *Sword2Engine::fetchCdtEntry(uint8 *animFile, uint16 frameNo) { +CdtEntry *Sword2Engine::fetchCdtEntry(byte *animFile, uint16 frameNo) { AnimHeader *animHead = fetchAnimHeader(animFile); #ifdef _SWORD2_DEBUG @@ -125,7 +123,7 @@ CdtEntry *Sword2Engine::fetchCdtEntry(uint8 *animFile, uint16 frameNo) { error("fetchCdtEntry(animFile,%d) - anim only %d frames", frameNo, animHead->noAnimFrames); #endif - return (CdtEntry *) ((uint8 *) animHead + sizeof(AnimHeader) + frameNo * sizeof(CdtEntry)); + return (CdtEntry *) ((byte *) animHead + sizeof(AnimHeader) + frameNo * sizeof(CdtEntry)); } /** @@ -134,7 +132,7 @@ CdtEntry *Sword2Engine::fetchCdtEntry(uint8 *animFile, uint16 frameNo) { * exceeds the number of frames in this anim */ -FrameHeader *Sword2Engine::fetchFrameHeader(uint8 *animFile, uint16 frameNo) { +FrameHeader *Sword2Engine::fetchFrameHeader(byte *animFile, uint16 frameNo) { // required address = (address of the start of the anim header) + frameOffset return (FrameHeader *) (animFile + sizeof(StandardHeader) + fetchCdtEntry(animFile, frameNo)->frameOffset); } @@ -143,7 +141,7 @@ FrameHeader *Sword2Engine::fetchFrameHeader(uint8 *animFile, uint16 frameNo) { * Returns a pointer to the requested parallax layer data. */ -Parallax *Sword2Engine::fetchBackgroundParallaxLayer(uint8 *screenFile, int layer) { +Parallax *Sword2Engine::fetchBackgroundParallaxLayer(byte *screenFile, int layer) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); #ifdef _SWORD2_DEBUG @@ -151,10 +149,10 @@ Parallax *Sword2Engine::fetchBackgroundParallaxLayer(uint8 *screenFile, int laye error("fetchBackgroundParallaxLayer(%d) - No parallax layer exists", layer); #endif - return (Parallax *) ((uint8 *) mscreenHeader + mscreenHeader->bg_parallax[layer]); + return (Parallax *) ((byte *) mscreenHeader + mscreenHeader->bg_parallax[layer]); } -Parallax *Sword2Engine::fetchBackgroundLayer(uint8 *screenFile) { +Parallax *Sword2Engine::fetchBackgroundLayer(byte *screenFile) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); #ifdef _SWORD2_DEBUG @@ -162,10 +160,10 @@ Parallax *Sword2Engine::fetchBackgroundLayer(uint8 *screenFile) { error("fetchBackgroundLayer (%d) - No background layer exists"); #endif - return (Parallax *) ((uint8 *) mscreenHeader + mscreenHeader->screen + sizeof(ScreenHeader)); + return (Parallax *) ((byte *) mscreenHeader + mscreenHeader->screen + sizeof(ScreenHeader)); } -Parallax *Sword2Engine::fetchForegroundParallaxLayer(uint8 *screenFile, int layer) { +Parallax *Sword2Engine::fetchForegroundParallaxLayer(byte *screenFile, int layer) { MultiScreenHeader *mscreenHeader = (MultiScreenHeader *) (screenFile + sizeof(StandardHeader)); #ifdef _SWORD2_DEBUG @@ -173,12 +171,12 @@ Parallax *Sword2Engine::fetchForegroundParallaxLayer(uint8 *screenFile, int laye error("fetchForegroundParallaxLayer(%d) - No parallax layer exists", layer); #endif - return (Parallax *) ((uint8 *) mscreenHeader + mscreenHeader->fg_parallax[layer]); + return (Parallax *) ((byte *) mscreenHeader + mscreenHeader->fg_parallax[layer]); } -uint8 errorLine[128]; +static byte errorLine[128]; -uint8 *Sword2Engine::fetchTextLine(uint8 *file, uint32 text_line) { +byte *Sword2Engine::fetchTextLine(byte *file, uint32 text_line) { StandardHeader *fileHeader; uint32 *point; @@ -198,30 +196,29 @@ uint8 *Sword2Engine::fetchTextLine(uint8 *file, uint32 text_line) { // point to the lookup table point = (uint32 *) text_header + 1; - return (uint8 *) (file + READ_LE_UINT32(point + text_line)); + return (byte *) (file + READ_LE_UINT32(point + text_line)); } // Used for testing text & speech (see fnISpeak in speech.cpp) -bool Sword2Engine::checkTextLine(uint8 *file, uint32 text_line) { +bool Sword2Engine::checkTextLine(byte *file, uint32 text_line) { TextHeader *text_header = (TextHeader *) (file + sizeof(StandardHeader)); return text_line < text_header->noOfLines; } -uint8 *Sword2Engine::fetchObjectName(int32 resourceId) { +byte *Sword2Engine::fetchObjectName(int32 resourceId) { StandardHeader *header; header = (StandardHeader *) _resman->openResource(resourceId); _resman->closeResource(resourceId); - // note this pointer is no longer valid, but it should be ok until + // Note this pointer is no longer valid, but it should be ok until // another resource is opened! // FIXME: I don't like the sound of this at all. Though thanks to the - // BS2 memory manager, at least it will still point to malloced - // memory. + // resource caching, at least it will still point to malloced memory. return header->name; } diff --git a/sword2/resman.cpp b/sword2/resman.cpp index 4fbf6cfdc5..c807a6025a 100644 --- a/sword2/resman.cpp +++ b/sword2/resman.cpp @@ -30,7 +30,6 @@ namespace Sword2 { -// --------------------------------------------------------------------------- // Welcome to the easy resource manager - written in simple code for easy // maintenance // @@ -39,7 +38,19 @@ namespace Sword2 { // resource.inf which is a list of ascii cluster file names // resource.tab which is a table which tells us which cluster a resource // is located in and the number within the cluster -// --------------------------------------------------------------------------- + +// If 0, resouces are expelled immediately when they are closed. At the moment +// this causes the game to crash, which seems like a bug to me. In fact, it +// could be a clue to the mysterious and infrequent crashes... + +#define CACHE_CLUSTERS 1 + +// Resources age every time a new room is entered. This constant indicates how +// long a cached resource (i.e. one that has been closed) is allowed to live +// before it dies of old age. This may need some tuning, but I picked three +// because so many areas in the game seem to consist of about three rooms. + +#define MAX_CACHE_AGE 3 enum { BOTH = 0x0, // Cluster is on both CDs @@ -75,132 +86,128 @@ ResourceManager::ResourceManager(Sword2Engine *vm) { // wish to know what resource files there are and what is in each File file; - uint32 end; - Memory *temp; - uint32 pos = 0; - uint32 j = 0; + uint32 size; + byte *temp; _totalClusters = 0; _resConvTable = NULL; - if (!file.open("resource.inf")) { - error("init cannot *OPEN* resource.inf"); - } + if (!file.open("resource.inf")) + error("Cannot open resource.inf"); - end = file.size(); + size = file.size(); - //get some space for the incoming resource file - soon to be trashed - temp = _vm->_memory->allocMemory(end, MEM_locked, (uint32) UID_temp); + // Get some space for the incoming resource file - soon to be trashed + temp = (byte *) malloc(size); - if (file.read(temp->ad, end) != end) { + if (file.read(temp, size) != size) { file.close(); error("init cannot *READ* resource.inf"); } file.close(); - // ok, we've loaded in the resource.inf file which contains a list of - // all the files now extract the filenames + // Ok, we've loaded in the resource.inf file which contains a list of + // all the files now extract the filenames. + + // Using this method the Gode generated resource.inf must have #0d0a on + // the last entry + + uint32 i = 0; + uint32 j = 0; + do { // item must have an #0d0a - while (temp->ad[j] != 13) { - _resourceFiles[_totalClusters][pos] = temp->ad[j]; + while (temp[i] != 13) { + _resourceFiles[_totalClusters][j] = temp[i]; + i++; j++; - pos++; } // NULL terminate our extracted string - _resourceFiles[_totalClusters][pos]=0; + _resourceFiles[_totalClusters][j] = 0; // Reset position in current slot between entries, skip the // 0x0a in the source and increase the number of clusters. - pos = 0; - j += 2; + j = 0; + i += 2; _totalClusters++; // TODO: put overload check here - } while (j != end); // using this method the Gode generated resource.inf must have #0d0a on the last entry + } while (i != size); - // now load in the binary id to res conversion table - if (!file.open("resource.tab")) { - error("init cannot *OPEN* resource.tab"); - } + free(temp); - // find how many resources - end = file.size(); + // Now load in the binary id to res conversion table + if (!file.open("resource.tab")) + error("Cannot open resource.tab"); - _totalResFiles = end / 4; + // Find how many resources + size = file.size(); - // table seems ok so malloc some space - _resConvTable = (uint16 *) malloc(end); + _totalResFiles = size / 4; - for (j = 0; j < end / 2; j++) - _resConvTable[j] = file.readUint16LE(); + // Table seems ok so malloc some space + _resConvTable = (uint16 *) malloc(size); + + for (i = 0; i < size / 2; i++) + _resConvTable[i] = file.readUint16LE(); if (file.ioFailed()) { file.close(); - error("init cannot *READ* resource.tab"); + error("Cannot read resource.tab"); } file.close(); - if (!file.open("cd.inf")) { - error("init cannot *OPEN* cd.inf"); - } + if (!file.open("cd.inf")) + error("Cannot open cd.inf"); CdInf *cdInf = new CdInf[_totalClusters]; - for (j = 0; j < _totalClusters; j++) { - file.read(cdInf[j].clusterName, sizeof(cdInf[j].clusterName)); - cdInf[j].cd = file.readByte(); + for (i = 0; i < _totalClusters; i++) { + file.read(cdInf[i].clusterName, sizeof(cdInf[i].clusterName)); + cdInf[i].cd = file.readByte(); - if (file.ioFailed()) { - error("init failed to read cd.inf. Insufficient entries?"); - } + if (file.ioFailed()) + error("Cannot read cd.inf"); } file.close(); - for (j = 0; j < _totalClusters; j++) { - uint32 i = 0; + for (i = 0; i < _totalClusters; i++) { + for (j = 0; j < _totalClusters; j++) { + if (scumm_stricmp((char *) cdInf[j].clusterName, _resourceFiles[i]) == 0) + break; + } - while (scumm_stricmp((char *) cdInf[i].clusterName, _resourceFiles[j]) != 0 && i < _totalClusters) - i++; + if (j == _totalClusters) + error("%s is not in cd.inf", _resourceFiles[i]); - if (i == _totalClusters) { - error("init, %s is not in cd.inf", _resourceFiles[j]); - } else - _cdTab[j] = cdInf[i].cd; + _cdTab[i] = cdInf[j].cd; } delete [] cdInf; - debug(5, "%d resources in %d cluster files", _totalResFiles, _totalClusters); - for (j = 0; j < _totalClusters; j++) - debug(5, "filename of cluster %d: -%s", j, _resourceFiles[j]); + debug(1, "%d resources in %d cluster files", _totalResFiles, _totalClusters); + for (i = 0; i < _totalClusters; i++) + debug(2, "filename of cluster %d: -%s", i, _resourceFiles[i]); - // create space for a list of pointers to mem's - _resList = (Memory **) malloc(_totalResFiles * sizeof(Memory *)); + _resList = (Resource *) malloc(_totalResFiles * sizeof(Resource)); - _age = (uint32 *) malloc(_totalResFiles * sizeof(uint32)); - _count = (uint16 *) malloc(_totalResFiles * sizeof(uint16)); - - for (j = 0; j < _totalResFiles; j++) { - // age must be 0 if the file is not in memory at all - _age[j] = 0; - _count[j] = 0; + for (i = 0; i < _totalResFiles; i++) { + _resList[i].ptr = NULL; + _resList[i].size = 0; + _resList[i].refCount = 0; + _resList[i].refTime = 0; } - _resTime = 1; //cannot start at 0 - _vm->_memory->freeMemory(temp); //get that memory back + _resTime = 0; } ResourceManager::~ResourceManager(void) { - // free up our mallocs free(_resList); - free(_age); - free(_count); free(_resConvTable); } @@ -209,7 +216,7 @@ ResourceManager::~ResourceManager(void) { #define SWAP16(x) x = SWAP_BYTES_16(x) #define SWAP32(x) x = SWAP_BYTES_32(x) -void convertEndian(uint8 *file, uint32 len) { +void convertEndian(byte *file, uint32 len) { int i; StandardHeader *hdr = (StandardHeader *) file; @@ -390,40 +397,29 @@ void convertEndian(uint8 *file, uint32 len) { } } -uint8 *ResourceManager::openResource(uint32 res, bool dump) { - // returns ad of resource. Loads if not in memory - // retains a count - // resource can be aged out of memory if count = 0 - // the resource is locked while count != 0 i.e. until a closeResource - // is called - - File file; - uint16 parent_res_file; - uint16 actual_res; - uint32 pos, len; - - uint32 table_offset; +/** + * Returns the address of a resource. Loads if not in memory. Retains a count. + */ +byte *ResourceManager::openResource(uint32 res, bool dump) { assert(res < _totalResFiles); - // is the resource in memory already? - // if the file is not in memory then age should and MUST be 0 - if (!_age[res]) { - // fetch the correct file and read in the correct portion - // if the file cannot fit then we must trash the oldest large - // enough floating file + // Is the resource in memory already? If not, load it. + + if (!_resList[res].ptr) { + // Fetch the correct file and read in the correct portion. // points to the number of the ascii filename - parent_res_file = _resConvTable[res * 2]; + uint16 parent_res_file = _resConvTable[res * 2]; assert(parent_res_file != 0xffff); - // relative resource within the file - actual_res = _resConvTable[(res * 2) + 1]; + // Relative resource within the file + uint16 actual_res = _resConvTable[(res * 2) + 1]; - // first we have to find the file via the _resConvTable + // First we have to find the file via the _resConvTable - debug(5, "resOpen %s res %d", _resourceFiles[parent_res_file], res); + debug(5, "openResource %s res %d", _resourceFiles[parent_res_file], res); // If we're loading a cluster that's only available from one // of the CDs, remember which one so that we can play the @@ -436,6 +432,8 @@ uint8 *ResourceManager::openResource(uint32 res, bool dump) { // care which CD it's on. But if we can't find it, keep asking // for the CD until we do. + File file; + while (!file.open(_resourceFiles[parent_res_file])) { // If the file is supposed to be on hard disk, or we're // playing a demo, then we're in trouble if the file @@ -448,32 +446,28 @@ uint8 *ResourceManager::openResource(uint32 res, bool dump) { } // 1st DWORD of a cluster is an offset to the look-up table - table_offset = file.readUint32LE(); + uint32 table_offset = file.readUint32LE(); - debug(5, "table offset = %d", table_offset); + debug(6, "table offset = %d", table_offset); - // 2 dwords per resource file.seek(table_offset + actual_res * 8, SEEK_SET); - // get position of our resource within the cluster file - pos = file.readUint32LE(); - // read the length - len = file.readUint32LE(); - // get to position in file of our particular resource + uint32 pos = file.readUint32LE(); + uint32 len = file.readUint32LE(); + file.seek(pos, SEEK_SET); - debug(5, "res len %d", len); + debug(6, "res len %d", len); - // 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] = _vm->_memory->allocMemory(len, MEM_locked, 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].ptr = _vm->_memory->memAlloc(len, res); + _resList[res].size = len; - // now load the file - // hurray, load it in. - file.read(_resList[res]->ad, len); + file.read(_resList[res].ptr, len); if (dump) { - StandardHeader *header = (StandardHeader *) _resList[res]->ad; + StandardHeader *header = (StandardHeader *) _resList[res].ptr; char buf[256]; char tag[10]; File out; @@ -531,7 +525,7 @@ uint8 *ResourceManager::openResource(uint32 res, bool dump) { if (!out.open(buf, "")) { if (out.open(buf, "", File::kFileWriteMode)) - out.write(_resList[res]->ad, len); + out.write(_resList[res].ptr, len); } if (out.isOpen()) @@ -542,184 +536,112 @@ uint8 *ResourceManager::openResource(uint32 res, bool dump) { file.close(); #ifdef SCUMM_BIG_ENDIAN - convertEndian((uint8 *) _resList[res]->ad, len); + convertEndian(_resList[res].ptr, len); #endif - } else { - debug(9, "RO %d, already open count=%d", res, _count[res]); } - // number of times opened - the file won't move in memory while count - // is non zero - _count[res]++; + _resList[res].refCount++; + _resList[res].refTime = _resTime; + + return _resList[res].ptr; +} - // update the accessed time stamp - touch the file in other words - _age[res] = _resTime; +void ResourceManager::closeResource(uint32 res) { + assert(res < _totalResFiles); + assert(_resList[res].refCount > 0); - // pass the address of the mem & lock the memory too - // might be locked already (if count > 1) - _vm->_memory->lockMemory(_resList[res]); + _resList[res].refCount--; + _resList[res].refTime = _resTime; - return (uint8 *) _resList[res]->ad; -} +#if !CACHE_CLUSTERS + // Maybe it's useful on some platforms if memory is released as + // quickly as possible? -uint8 ResourceManager::checkValid(uint32 res) { - // returns '1' if resource is valid, otherwise returns '0' - // used in startup.cpp to ignore invalid screen-manager resources + if (_resList[res].refCount == 0) + remove(res); +#endif +} - uint16 parent_res_file; +/** + * Returns true if resource is valid, otherwise false. + */ - // resource number out of range +bool ResourceManager::checkValid(uint32 res) { + // Resource number out of range if (res >= _totalResFiles) - return 0; + return false; - // points to the number of the ascii filename - parent_res_file = _resConvTable[res * 2]; + // Points to the number of the ascii filename + uint16 parent_res_file = _resConvTable[res * 2]; - // null & void resource + // Null & void resource if (parent_res_file == 0xffff) - return 0; + return false; - // ok - return 1; + return true; } -void ResourceManager::nextCycle(void) { - // increment the cycle and calculate actual per-cycle memory useage +void ResourceManager::passTime() { + // In the original game this was called every game cycle. This allowed + // for a more exact measure of when a loaded resouce was most recently + // used. When the memory pool got too fragmented, the oldest and + // largest of the closed resources would be expelled from the cache. -#ifdef _SWORD2_DEBUG - _currentMemoryUsage = 0; + // With the new memory manager, there is no single memory block that + // can become fragmented. Therefore, it makes more sense to me to + // measure an object's age in how many rooms ago it was last used. - for (int i = 1; i < _totalResFiles; i++) { - // was accessed last cycle - if (_age[i] == _resTime) - _currentMemoryUsage += _resList[i]->size; - } -#endif + // Therefore, this function is now called when a new room is loaded. _resTime++; - - // if you left the game running for a hundred years when this went to 0 - // there'd be a resource left stuck in memory - after another hundred - // years there'd be another... - // - // Mind you, by then the our get_msecs() function will have wrapped - // around too, probably causing a mess of other problems. - - if (!_resTime) - _resTime++; -} - -uint32 ResourceManager::fetchUsage(void) { - // returns memory usage previous cycle - return _currentMemoryUsage; } -void ResourceManager::closeResource(uint32 res) { - // decrements the count - // resource floats when count = 0 - - assert(res < _totalResFiles); - assert(_count[res]); - - //one less has it open - _count[res]--; - - //if noone has the file open then unlock and allow to float - if (!_count[res]) { - // pass the address of the mem - _vm->_memory->floatMemory(_resList[res]); - } -} +/** + * Returns the total file length of a resource - i.e. all headers are included + * too. + */ uint32 ResourceManager::fetchLen(uint32 res) { - // returns the total file length of a resource - i.e. all headers are - // included too + if (_resList[res].ptr) + return _resList[res].size; - File fh; - uint16 parent_res_file; - uint16 actual_res; - uint32 len; - uint32 table_offset; + // Does this ever happen? + warning("fetchLen: Resource %u is not loaded; reading length from file", res); - // points to the number of the ascii filename - parent_res_file = _resConvTable[res * 2]; + // Points to the number of the ascii filename + uint16 parent_res_file = _resConvTable[res * 2]; // relative resource within the file - actual_res = _resConvTable[(res * 2) + 1]; + uint16 actual_res = _resConvTable[(res * 2) + 1]; // first we have to find the file via the _resConvTable // open the cluster file - if (!fh.open(_resourceFiles[parent_res_file])) - error("fetchLen cannot *OPEN* %s", _resourceFiles[parent_res_file]); + File file; + + if (!file.open(_resourceFiles[parent_res_file])) + error("Cannot open %s", _resourceFiles[parent_res_file]); // 1st DWORD of a cluster is an offset to the look-up table - table_offset = fh.readUint32LE(); + uint32 table_offset = file.readUint32LE(); // 2 dwords per resource + skip the position dword - fh.seek(table_offset + (actual_res * 8) + 4, SEEK_SET); - - // read the length - len = fh.readUint32LE(); - return len; -} - -char *ResourceManager::fetchCluster(uint32 res) { - // returns a pointer to the ascii name of the cluster file which - // contains resource res - return _resourceFiles[_resConvTable[res * 2]]; -} + file.seek(table_offset + (actual_res * 8) + 4, SEEK_SET); -uint32 ResourceManager::fetchAge(uint32 res) { - // return the age of res - return _age[res]; + return file.readUint32LE(); } -uint32 ResourceManager::fetchCount(uint32 res) { - // return the open count of res - return _count[res]; -} +void ResourceManager::expelOldResources() { + int nuked = 0; -uint32 ResourceManager::helpTheAgedOut(void) { - // remove from memory the oldest closed resource - - uint32 oldest_res; // holds id of oldest found so far when we have to chuck stuff out of memory - uint32 oldest_age; // age of above during search - uint32 j; - uint32 largestResource = 0; - - oldest_age = _resTime; - oldest_res = 0; - - for (j = 2; j < _totalResFiles; j++) { - // not held open and older than this one - if (!_count[j] && _age[j] && _age[j] <= oldest_age) { - if (_age[j] == oldest_age && _resList[j]->size > largestResource) { - // Kick old resource of oldest age and largest - // size (Helps the poor defragger). - oldest_res = j; - largestResource = _resList[j]->size; - } else if (_age[j] < oldest_age) { - oldest_res = j; - oldest_age = _age[j]; - largestResource = _resList[j]->size; - } + for (uint i = 0; i < _totalResFiles; i++) { + if (_resList[i].ptr && _resList[i].refCount == 0 && _resTime - _resList[i].refTime >= MAX_CACHE_AGE) { + remove(i); + nuked++; } } - // there was not a file we could release - // no bytes released - oh dear, lets hope this never happens - if (!oldest_res) - return 0; - - debug(5, "removing %d, age %d, size %d", oldest_res, _age[oldest_res], _resList[oldest_res]->size); - - // trash this old resource - - _age[oldest_res] = 0; // effectively gone from _resList - _vm->_memory->freeMemory(_resList[oldest_res]); // release the memory too - - return _resList[oldest_res]->size; // return bytes freed + debug(1, "%d resources died of old age", nuked); } void ResourceManager::printConsoleClusters(void) { @@ -750,20 +672,13 @@ void ResourceManager::printConsoleClusters(void) { } void ResourceManager::examine(int res) { - StandardHeader *file_header; - if (res < 0 || res >= (int) _totalResFiles) Debug_Printf("Illegal resource %d (there are %d resources 0-%d)\n", res, _totalResFiles, _totalResFiles - 1); else if (_resConvTable[res * 2] == 0xffff) Debug_Printf("%d is a null & void resource number\n", res); else { // open up the resource and take a look inside! - file_header = (StandardHeader *) openResource(res); - - // Debug_Printf("%d\n", file_header->fileType); - // Debug_Printf("%s\n", file_header->name); - - // Resource types. See header.h + StandardHeader *file_header = (StandardHeader *) openResource(res); switch (file_header->fileType) { case ANIMATION_FILE: @@ -813,141 +728,100 @@ void ResourceManager::kill(int res) { return; } - // if noone has the file open then unlock and allow to float - if (!_count[res]) { - if (_age[res]) { - _age[res] = 0; // effectively gone from _resList - _vm->_memory->freeMemory(_resList[res]); // release the memory too - Debug_Printf("Trashed %d\n", res); - } else - Debug_Printf("%d not in memory\n", res); - } else - Debug_Printf("File is open - cannot remove\n"); -} - -void ResourceManager::remove(uint32 res) { - if (_age[res]) { - _age[res] = 0; // effectively gone from _resList - _vm->_memory->freeMemory(_resList[res]); // release the memory too - debug(5, " - Trashing %d", res); - } else - debug(5, "remove(%d) not even in memory!", res); -} + if (!_resList[res].ptr) { + Debug_Printf("Resource %d is not in memory\n", res); + return; + } -void ResourceManager::removeAll(void) { - // remove all res files from memory - ready for a total restart - // including player object & global variables resource + if (_resList[res].refCount) { + Debug_Printf("Resource %d is open - cannot remove\n", res); + return; + } - int j; - uint32 res; + remove(res); + Debug_Printf("Trashed %d\n", res); +} - j = _vm->_memory->_baseMemBlock; +void ResourceManager::remove(int res) { + if (_resList[res].ptr) { + _vm->_memory->memFree(_resList[res].ptr); + _resList[res].ptr = NULL; + } +} - do { - if (_vm->_memory->_memList[j].uid < 65536) { // a resource - res = _vm->_memory->_memList[j].uid; - _age[res] = 0; // effectively gone from _resList - _vm->_memory->freeMemory(_resList[res]); // release the memory too - } +/** + * Remove all res files from memory - ready for a total restart. This includes + * the player object and global variables resource. + */ - j = _vm->_memory->_memList[j].child; - } while (j != -1); +void ResourceManager::removeAll(void) { + for (uint i = 0; i < _totalResFiles; i++) + remove(i); } -void ResourceManager::killAll(bool wantInfo) { - // remove all res files from memory - // its quicker to search the mem blocs for res files than search - // resource lists for those in memory - - int j; - uint32 res; - uint32 nuked = 0; - StandardHeader *header; +/** + * Remove all resources from memory. + */ - j = _vm->_memory->_baseMemBlock; +void ResourceManager::killAll(bool wantInfo) { + int nuked = 0; - do { - if (_vm->_memory->_memList[j].uid < 65536) { // a resource - res = _vm->_memory->_memList[j].uid; + for (uint i = 0; i < _totalResFiles; i++) { + // Don't nuke the global variables or the player object! + if (i == 1 || i == CUR_PLAYER_ID) + continue; - // not the global vars which are assumed to be open in - // memory & not the player object! - if (res != 1 && res != CUR_PLAYER_ID) { - header = (StandardHeader *) openResource(res); - closeResource(res); + if (_resList[i].ptr) { + StandardHeader *header = (StandardHeader *) _resList[i].ptr; - _age[res] = 0; // effectively gone from _resList - _vm->_memory->freeMemory(_resList[res]); // release the memory too - nuked++; + if (wantInfo) + Debug_Printf("Nuked %5d: %s\n", i, header->name); - // if this was called from the console, - if (wantInfo) { - Debug_Printf("Nuked %5d: %s\n", res, header->name); - debug(5, " nuked %d: %s", res, header->name); - } - } + remove(i); + nuked++; } - j = _vm->_memory->_memList[j].child; - } while (j != -1); - - // if this was called from the console - if (wantInfo) { - Debug_Printf("Expelled %d resource(s)\n", nuked); } + + if (wantInfo) + Debug_Printf("Expelled %d resources\n", nuked); } -//---------------------------------------------------------------------------- -// Like killAll but only kills objects (except George & the variable table of -// course) - ie. forcing them to reload & restart their scripts, which -// simulates the effect of a save & restore, thus checking that each object's -// re-entrant logic works correctly, and doesn't cause a statuette to -// disappear forever, or some plaster-filled holes in sand to crash the game & -// get James in trouble again. +/** + * Like killAll but only kills objects (except George & the variable table of + * course) - ie. forcing them to reload & restart their scripts, which + * simulates the effect of a save & restore, thus checking that each object's + * re-entrant logic works correctly, and doesn't cause a statuette to + * disappear forever, or some plaster-filled holes in sand to crash the game & + * get James in trouble again. + */ void ResourceManager::killAllObjects(bool wantInfo) { - // remove all object res files from memory, excluding George - // its quicker to search the mem blocs for res files than search - // resource lists for those in memory + int nuked = 0; - int j; - uint32 res; - uint32 nuked = 0; - StandardHeader *header; + for (uint i = 0; i < _totalResFiles; i++) { + // Don't nuke the global variables or the player object! + if (i == 1 || i == CUR_PLAYER_ID) + continue; - j = _vm->_memory->_baseMemBlock; + if (_resList[i].ptr) { + StandardHeader *header = (StandardHeader *) _resList[i].ptr; - do { - if (_vm->_memory->_memList[j].uid < 65536) { // a resource - res = _vm->_memory->_memList[j].uid; - //not the global vars which are assumed to be open in - // memory & not the player object! - if (res != 1 && res != CUR_PLAYER_ID) { - header = (StandardHeader *) openResource(res); - closeResource(res); - - if (header->fileType == GAME_OBJECT) { - _age[res] = 0; // effectively gone from _resList - _vm->_memory->freeMemory(_resList[res]); // release the memory too - nuked++; - - // if this was called from the console - if (wantInfo) { - Debug_Printf("Nuked %5d: %s\n", res, header->name); - debug(5, " nuked %d: %s", res, header->name); - } - } + if (header->fileType == GAME_OBJECT) { + if (wantInfo) + Debug_Printf("Nuked %5d: %s\n", i, header->name); + + remove(i); + nuked++; } } - j = _vm->_memory->_memList[j].child; - } while (j != -1); + } - // if this was called from the console if (wantInfo) - Debug_Printf("Expelled %d object resource(s)\n", nuked); + Debug_Printf("Expelled %d resources\n", nuked); } void ResourceManager::getCd(int cd) { - uint8 *textRes; + byte *textRes; // stop any music from playing - so the system no longer needs the // current CD - otherwise when we take out the CD, Windows will diff --git a/sword2/resman.h b/sword2/resman.h index b6c0838362..35cca72ef2 100644 --- a/sword2/resman.h +++ b/sword2/resman.h @@ -26,35 +26,27 @@ namespace Sword2 { class Sword2Engine; +struct Resource { + byte *ptr; + uint32 size; + uint32 refCount; + uint32 refTime; +}; + class ResourceManager { public: ResourceManager(Sword2Engine *vm); // read in the config file ~ResourceManager(void); - // Returns ad of resource. Loads if not in memory. Retains a count. - // Resource can be aged out of memory if count = 0 - // The resource is locked while count != 0 - // Resource floats when count = 0 - - uint8 *openResource(uint32 res, bool dump = false); - void closeResource(uint32 res); // decrements the count - - // returns '0' if resource out of range or null, otherwise '1' for ok - - uint8 checkValid(uint32 res); - - //for mem_view to query the owners of mem blocs - - char *fetchCluster(uint32 res); - uint32 fetchAge(uint32 res); - uint32 fetchCount(uint32 count); - - uint32 helpTheAgedOut(void); + byte *openResource(uint32 res, bool dump = false); + void closeResource(uint32 res); + bool checkValid(uint32 res); uint32 fetchLen(uint32 res); - void nextCycle(void); - uint32 fetchUsage(void); + void expelOldResources(void); + + void passTime(void); // Prompts the user for the specified CD. void getCd(int cd); @@ -63,6 +55,8 @@ public: return _curCd; } + void remove(int res); + // ----console commands void printConsoleClusters(void); @@ -70,11 +64,9 @@ public: void kill(int res); void killAll(bool wantInfo); void killAllObjects(bool wantInfo); - void remove(uint32 res); void removeAll(void); - // pointer to a pointer (or list of pointers in-fact) - Memory **_resList; + Resource *_resList; private: Sword2Engine *_vm; @@ -82,20 +74,13 @@ private: int _curCd; uint32 _totalResFiles; uint32 _totalClusters; - uint32 _currentMemoryUsage; - - // Inc's each time open is called and is given to resource as its age. - // Cannot be allowed to start at 0! (A pint if you can tell me why) uint32 _resTime; - uint32 *_age; - // Gode generated res-id to res number/rel number conversion table uint16 *_resConvTable; - uint16 *_count; char _resourceFiles[MAX_res_files][20]; uint8 _cdTab[MAX_res_files]; // Location of each cluster. }; diff --git a/sword2/router.cpp b/sword2/router.cpp index 59eddd059e..3bc04f4636 100644 --- a/sword2/router.cpp +++ b/sword2/router.cpp @@ -110,7 +110,7 @@ void Router::allocateRouteMem(void) { if (_routeSlots[slotNo]) freeRouteMem(); - _routeSlots[slotNo] = _vm->_memory->allocMemory(sizeof(WalkData) * O_WALKANIM_SIZE, MEM_locked, (uint32) UID_walk_anim); + _routeSlots[slotNo] = (WalkData *) malloc(sizeof(WalkData) * O_WALKANIM_SIZE); // 12000 bytes were used for this in Sword1 mega compacts, based on // 20 bytes per 'WalkData' frame @@ -125,36 +125,23 @@ void Router::allocateRouteMem(void) { // megaObject->route_slot_id = slotNo + 1; } -WalkData *Router::lockRouteMem(void) { +WalkData *Router::getRouteMem(void) { uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]); - _vm->_memory->lockMemory(_routeSlots[slotNo]); - return (WalkData *) _routeSlots[slotNo]->ad; -} - -void Router::floatRouteMem(void) { - uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]); - - _vm->_memory->floatMemory(_routeSlots[slotNo]); + return (WalkData *) _routeSlots[slotNo]; } void Router::freeRouteMem(void) { uint8 slotNo = returnSlotNo(Logic::_scriptVars[ID]); - // free the mem block pointed to from this entry of _routeSlots[] - - _vm->_memory->freeMemory(_routeSlots[slotNo]); + free(_routeSlots[slotNo]); _routeSlots[slotNo] = NULL; } void Router::freeAllRouteMem(void) { for (int i = 0; i < TOTAL_ROUTE_SLOTS; i++) { - if (_routeSlots[i]) { - // free the mem block pointed to from this entry of - // _routeSlots[] - _vm->_memory->freeMemory(_routeSlots[i]); - _routeSlots[i] = NULL; - } + free(_routeSlots[i]); + _routeSlots[i] = NULL; } } @@ -191,8 +178,7 @@ int32 Router::routeFinder(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int3 setUpWalkGrid(ob_mega, x, y, dir); loadWalkData(ob_walkdata); - // lock the WalkData array (NB. AFTER loading walkgrid & walkdata!) - walkAnim = lockRouteMem(); + walkAnim = getRouteMem(); // All route data now loaded start finding a route @@ -268,8 +254,6 @@ int32 Router::routeFinder(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata, int3 break; } - floatRouteMem(); // float the WalkData array again - return routeFlag; // send back null route } @@ -728,8 +712,7 @@ void Router::earlySlowOut(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata) { walk_pc = ob_mega->walk_pc; - // lock the WalkData array (NB. AFTER loading walkgrid & walkdata!) - walkAnim = lockRouteMem(); + walkAnim = getRouteMem(); // if this mega does actually have slow-out frames if (_usingSlowOutFrames) { @@ -2400,7 +2383,7 @@ void Router::plotCross(int16 x, int16 y, uint8 colour) { void Router::loadWalkGrid(void) { WalkGridHeader floorHeader; - uint8 *fPolygrid; + byte *fPolygrid; uint32 theseBars; uint32 theseNodes; @@ -2415,7 +2398,7 @@ void Router::loadWalkGrid(void) { // open walk grid file fPolygrid = _vm->_resman->openResource(_walkGridList[i]); fPolygrid += sizeof(StandardHeader); - memcpy((uint8 *) &floorHeader, fPolygrid, sizeof(WalkGridHeader)); + memcpy((byte *) &floorHeader, fPolygrid, sizeof(WalkGridHeader)); fPolygrid += sizeof(WalkGridHeader); // how many bars & nodes are we getting from this @@ -2432,7 +2415,7 @@ void Router::loadWalkGrid(void) { // lines - memcpy((uint8 *) &_bars[_nBars], fPolygrid, theseBars * sizeof(BarData)); + memcpy((byte *) &_bars[_nBars], fPolygrid, theseBars * sizeof(BarData)); // move pointer to start of node data fPolygrid += theseBars * sizeof(BarData); @@ -2441,7 +2424,7 @@ void Router::loadWalkGrid(void) { // leave node 0 for start node for (uint j = 0; j < theseNodes; j++) { - memcpy((uint8 *) &_node[_nNodes + j].x, fPolygrid, 2 * sizeof(int16)); + memcpy((byte *) &_node[_nNodes + j].x, fPolygrid, 2 * sizeof(int16)); fPolygrid += 2 * sizeof(int16); } diff --git a/sword2/router.h b/sword2/router.h index f717aed40e..a044bc2b18 100644 --- a/sword2/router.h +++ b/sword2/router.h @@ -105,7 +105,7 @@ private: // stores pointers to mem blocks containing routes created & used by // megas (NULL if slot not in use) - Memory *_routeSlots[TOTAL_ROUTE_SLOTS]; + WalkData *_routeSlots[TOTAL_ROUTE_SLOTS]; BarData _bars[O_GRID_SIZE]; NodeData _node[O_GRID_SIZE]; @@ -228,8 +228,7 @@ public: void earlySlowOut(ObjectMega *ob_mega, ObjectWalkdata *ob_walkdata); void allocateRouteMem(void); - WalkData *lockRouteMem(void); - void floatRouteMem(void); + WalkData *getRouteMem(void); void freeRouteMem(void); void freeAllRouteMem(void); void addWalkGrid(int32 gridResource); diff --git a/sword2/save_rest.cpp b/sword2/save_rest.cpp index bb98ed8117..c65825db2c 100644 --- a/sword2/save_rest.cpp +++ b/sword2/save_rest.cpp @@ -88,26 +88,26 @@ static void convertHeaderEndian(Sword2Engine::SaveGameHeader &header) { // SAVE GAME -uint32 Sword2Engine::saveGame(uint16 slotNo, uint8 *desc) { - Memory *saveBufferMem; +uint32 Sword2Engine::saveGame(uint16 slotNo, byte *desc) { + byte *saveBufferMem; uint32 bufferSize; uint32 errorCode; // allocate the savegame buffer bufferSize = findBufferSize(); - saveBufferMem = _memory->allocMemory(bufferSize, MEM_locked, (uint32) UID_savegame_buffer); + saveBufferMem = (byte *) malloc(bufferSize); fillSaveBuffer(saveBufferMem, bufferSize, desc); // save it (hopefully no longer platform-specific) // save the buffer - errorCode = saveData(slotNo, saveBufferMem->ad, bufferSize); + errorCode = saveData(slotNo, saveBufferMem, bufferSize); // free the buffer - _memory->freeMemory(saveBufferMem); + free(saveBufferMem); return errorCode; } @@ -119,8 +119,8 @@ uint32 Sword2Engine::findBufferSize(void) { return sizeof(_saveGameHeader) + _resman->fetchLen(1); } -void Sword2Engine::fillSaveBuffer(Memory *buffer, uint32 size, uint8 *desc) { - uint8 *varsRes; +void Sword2Engine::fillSaveBuffer(byte *buffer, uint32 size, byte *desc) { + byte *varsRes; // set up the _saveGameHeader @@ -160,7 +160,7 @@ void Sword2Engine::fillSaveBuffer(Memory *buffer, uint32 size, uint8 *desc) { #endif // copy the header to the savegame buffer - memcpy(buffer->ad, &_saveGameHeader, sizeof(_saveGameHeader)); + memcpy(buffer, &_saveGameHeader, sizeof(_saveGameHeader)); // copy the global variables to the buffer @@ -168,10 +168,10 @@ void Sword2Engine::fillSaveBuffer(Memory *buffer, uint32 size, uint8 *desc) { varsRes = _resman->openResource(1); // copy that to the buffer, following the header - memcpy(buffer->ad + sizeof(_saveGameHeader), varsRes, FROM_LE_32(_saveGameHeader.varLength)); + memcpy(buffer + sizeof(_saveGameHeader), varsRes, FROM_LE_32(_saveGameHeader.varLength)); #ifdef SCUMM_BIG_ENDIAN - uint32 *globalVars = (uint32 *) (buffer->ad + sizeof(_saveGameHeader) + sizeof(StandardHeader)); + uint32 *globalVars = (uint32 *) (buffer + sizeof(_saveGameHeader) + sizeof(StandardHeader)); const uint numVars = (FROM_LE_32(_saveGameHeader.varLength) - sizeof(StandardHeader)) / 4; for (uint i = 0; i < numVars; i++) @@ -183,11 +183,11 @@ void Sword2Engine::fillSaveBuffer(Memory *buffer, uint32 size, uint8 *desc) { // set the checksum & copy that to the buffer - _saveGameHeader.checksum = TO_LE_32(calcChecksum((buffer->ad) + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum))); - memcpy(buffer->ad, &_saveGameHeader.checksum, sizeof(_saveGameHeader.checksum)); + _saveGameHeader.checksum = TO_LE_32(calcChecksum(buffer + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum))); + memcpy(buffer, &_saveGameHeader.checksum, sizeof(_saveGameHeader.checksum)); } -uint32 Sword2Engine::saveData(uint16 slotNo, uint8 *buffer, uint32 bufferSize) { +uint32 Sword2Engine::saveData(uint16 slotNo, byte *buffer, uint32 bufferSize) { char saveFileName[MAX_FILENAME_LEN]; uint32 itemsWritten; SaveFile *out; @@ -219,19 +219,19 @@ uint32 Sword2Engine::saveData(uint16 slotNo, uint8 *buffer, uint32 bufferSize) { // RESTORE GAME uint32 Sword2Engine::restoreGame(uint16 slotNo) { - Memory *saveBufferMem; + byte *saveBufferMem; uint32 bufferSize; uint32 errorCode; // allocate the savegame buffer bufferSize = findBufferSize(); - saveBufferMem = _memory->allocMemory(bufferSize, MEM_locked, (uint32) UID_savegame_buffer); + saveBufferMem = (byte *) malloc(bufferSize); // read the savegame file into our buffer // load savegame into buffer - errorCode = restoreData(slotNo, saveBufferMem->ad, bufferSize); + errorCode = restoreData(slotNo, saveBufferMem, bufferSize); // if it was read in successfully, then restore the game from the // buffer & free the buffer @@ -244,7 +244,7 @@ uint32 Sword2Engine::restoreGame(uint16 slotNo) { // loading in the new screen & runlist } else { // because restoreFromBuffer would have freed it - _memory->freeMemory(saveBufferMem); + free(saveBufferMem); } // Force the game engine to pick a cursor. This appears to be needed @@ -253,7 +253,7 @@ uint32 Sword2Engine::restoreGame(uint16 slotNo) { return errorCode; } -uint32 Sword2Engine::restoreData(uint16 slotNo, uint8 *buffer, uint32 bufferSize) { +uint32 Sword2Engine::restoreData(uint16 slotNo, byte *buffer, uint32 bufferSize) { char saveFileName[MAX_FILENAME_LEN]; SaveFile *in; SaveFileManager *mgr = _system->get_savefile_manager(); @@ -295,12 +295,12 @@ uint32 Sword2Engine::restoreData(uint16 slotNo, uint8 *buffer, uint32 bufferSize } } -uint32 Sword2Engine::restoreFromBuffer(Memory *buffer, uint32 size) { - uint8 *varsRes; +uint32 Sword2Engine::restoreFromBuffer(byte *buffer, uint32 size) { + byte *varsRes; int32 pars[2]; // get a copy of the header from the savegame buffer - memcpy(&_saveGameHeader, buffer->ad, sizeof(_saveGameHeader)); + memcpy(&_saveGameHeader, buffer, sizeof(_saveGameHeader)); #ifdef SCUMM_BIG_ENDIAN convertHeaderEndian(_saveGameHeader); @@ -308,8 +308,8 @@ uint32 Sword2Engine::restoreFromBuffer(Memory *buffer, uint32 size) { // Calc checksum & check that aginst the value stored in the header - if (_saveGameHeader.checksum != calcChecksum(buffer->ad + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum))) { - _memory->freeMemory(buffer); + if (_saveGameHeader.checksum != calcChecksum(buffer + sizeof(_saveGameHeader.checksum), size - sizeof(_saveGameHeader.checksum))) { + free(buffer); // error: incompatible save-data - can't use! return SR_ERR_INCOMPATIBLE; @@ -324,7 +324,7 @@ uint32 Sword2Engine::restoreFromBuffer(Memory *buffer, uint32 size) { // if header contradicts actual current size of global variables if (_saveGameHeader.varLength != _resman->fetchLen(1)) { - _memory->freeMemory(buffer); + free(buffer); // error: incompatible save-data - can't use! return SR_ERR_INCOMPATIBLE; @@ -355,7 +355,7 @@ uint32 Sword2Engine::restoreFromBuffer(Memory *buffer, uint32 size) { varsRes = _resman->openResource(1); // copy that to the buffer, following the header - memcpy(varsRes, buffer->ad + sizeof(_saveGameHeader), _saveGameHeader.varLength); + memcpy(varsRes, buffer + sizeof(_saveGameHeader), _saveGameHeader.varLength); #ifdef SCUMM_BIG_ENDIAN uint32 *globalVars = (uint32 *) (varsRes + sizeof(StandardHeader)); @@ -370,7 +370,7 @@ uint32 Sword2Engine::restoreFromBuffer(Memory *buffer, uint32 size) { // free it now, rather than in RestoreGame, to unblock memory before // new screen & runlist loaded - _memory->freeMemory(buffer); + free(buffer); pars[0] = _saveGameHeader.screenId; pars[1] = 1; @@ -428,7 +428,7 @@ uint32 Sword2Engine::restoreFromBuffer(Memory *buffer, uint32 size) { // GetSaveDescription - PC version... -uint32 Sword2Engine::getSaveDescription(uint16 slotNo, uint8 *description) { +uint32 Sword2Engine::getSaveDescription(uint16 slotNo, byte *description) { char saveFileName[MAX_FILENAME_LEN]; SaveGameHeader dummy; SaveFile *in; @@ -547,7 +547,7 @@ void Sword2Engine::putPlayerStructures(void) { _resman->closeResource(CUR_PLAYER_ID); } -uint32 Sword2Engine::calcChecksum(uint8 *buffer, uint32 size) { +uint32 Sword2Engine::calcChecksum(byte *buffer, uint32 size) { uint32 total = 0; for (uint32 pos = 0; pos < size; pos++) @@ -569,9 +569,9 @@ int32 Logic::fnPassPlayerSaveData(int32 *params) { // copy from player object to savegame header - memcpy(&_vm->_saveGameHeader.logic, _vm->_memory->intToPtr(params[0]), sizeof(ObjectLogic)); - memcpy(&_vm->_saveGameHeader.graphic, _vm->_memory->intToPtr(params[1]), sizeof(ObjectGraphic)); - memcpy(&_vm->_saveGameHeader.mega, _vm->_memory->intToPtr(params[2]), sizeof(ObjectMega)); + memcpy(&_vm->_saveGameHeader.logic, _vm->_memory->decodePtr(params[0]), sizeof(ObjectLogic)); + memcpy(&_vm->_saveGameHeader.graphic, _vm->_memory->decodePtr(params[1]), sizeof(ObjectGraphic)); + memcpy(&_vm->_saveGameHeader.mega, _vm->_memory->decodePtr(params[2]), sizeof(ObjectMega)); // makes no odds return IR_CONT; @@ -585,17 +585,17 @@ int32 Logic::fnGetPlayerSaveData(int32 *params) { // 1 pointer to object's graphic structure // 2 pointer to object's mega structure - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); - ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[1]); - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); + ObjectGraphic *ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[1]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]); int32 pars[3]; // copy from savegame header to player object - memcpy((uint8 *) ob_logic, &_vm->_saveGameHeader.logic, sizeof(ObjectLogic)); - memcpy((uint8 *) ob_graphic, &_vm->_saveGameHeader.graphic, sizeof(ObjectGraphic)); - memcpy((uint8 *) ob_mega, &_vm->_saveGameHeader.mega, sizeof(ObjectMega)); + memcpy((byte *) ob_logic, &_vm->_saveGameHeader.logic, sizeof(ObjectLogic)); + memcpy((byte *) ob_graphic, &_vm->_saveGameHeader.graphic, sizeof(ObjectGraphic)); + memcpy((byte *) ob_mega, &_vm->_saveGameHeader.mega, sizeof(ObjectMega)); // any walk-data must be cleared - the player will be set to stand if // he was walking when saved @@ -606,10 +606,10 @@ int32 Logic::fnGetPlayerSaveData(int32 *params) { ob_mega->currently_walking = 0; // pointer to object's graphic structure - pars[0] = _vm->_memory->ptrToInt((const uint8 *) ob_graphic); + pars[0] = _vm->_memory->encodePtr((byte *) ob_graphic); // pointer to object's mega structure - pars[1] = _vm->_memory->ptrToInt((const uint8 *) ob_mega); + pars[1] = _vm->_memory->encodePtr((byte *) ob_mega); // target direction pars[2] = ob_mega->current_dir; diff --git a/sword2/sound.cpp b/sword2/sound.cpp index cc8b199cfe..b197625c90 100644 --- a/sword2/sound.cpp +++ b/sword2/sound.cpp @@ -82,7 +82,7 @@ void Sword2Engine::processFxQueue(void) { // called from processFxQueue only void Sword2Engine::triggerFx(uint8 j) { - uint8 *data; + byte *data; int32 id; uint32 rv; @@ -160,7 +160,7 @@ int32 Logic::fnPlayFx(int32 *params) { // fnStopFx (fx_water); uint8 j = 0; - uint8 *data; + byte *data; uint32 id; uint32 rv; diff --git a/sword2/speech.cpp b/sword2/speech.cpp index d052881781..174ef3b976 100644 --- a/sword2/speech.cpp +++ b/sword2/speech.cpp @@ -96,7 +96,7 @@ int32 Logic::fnChoose(int32 *params) { MouseEvent *me; uint32 i; int hit; - uint8 *icon; + byte *icon; _scriptVars[AUTO_SELECTED] = 0; // see below @@ -367,7 +367,7 @@ int32 Logic::fnTheyDoWeWait(int32 *params) { _vm->_resman->closeResource(target); - ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); if (!_scriptVars[INS_COMMAND] && _scriptVars[RESULT] == 1 && ob_logic->looping == 0) { // first time so set up targets command if target is waiting @@ -476,7 +476,7 @@ int32 Logic::fnTimedWait(int32 *params) { StandardHeader *head; int32 target = params[1]; - ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); if (!ob_logic->looping) ob_logic->looping = params[2]; // first time in @@ -557,7 +557,7 @@ int32 Logic::fnSpeechProcess(int32 *params) { ObjectSpeech *ob_speech; int32 pars[9]; - ob_speech = (ObjectSpeech *) _vm->_memory->intToPtr(params[1]); + ob_speech = (ObjectSpeech *) _vm->_memory->decodePtr(params[1]); debug(5, " SP"); @@ -843,10 +843,10 @@ int32 Logic::fnISpeak(int32 *params) { ObjectLogic *ob_logic; ObjectGraphic *ob_graphic; ObjectMega *ob_mega; - uint8 *anim_file; + byte *anim_file; uint32 local_text; uint32 text_res; - uint8 *text; + byte *text; static bool speechRunning; int32 *anim_table; bool speechFinished = false; @@ -860,8 +860,8 @@ int32 Logic::fnISpeak(int32 *params) { // set up the pointers which we know we'll always need - ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[S_OB_LOGIC]); - ob_graphic = (ObjectGraphic *) _vm->_memory->intToPtr(params[S_OB_GRAPHIC]); + ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[S_OB_LOGIC]); + ob_graphic = (ObjectGraphic *) _vm->_memory->decodePtr(params[S_OB_GRAPHIC]); // FIRST TIME ONLY: create the text, load the wav, set up the anim, // etc. @@ -918,7 +918,7 @@ int32 Logic::fnISpeak(int32 *params) { if (head->fileType == TEXT_FILE) { // if it's not an animation file // if line number is out of range - if (!_vm->checkTextLine((uint8 *) head, local_text)) { + if (!_vm->checkTextLine((byte *) head, local_text)) { // line number out of range _scriptVars[RESULT] = 2; } @@ -1003,10 +1003,10 @@ int32 Logic::fnISpeak(int32 *params) { // use this direction table to derive the anim // NB. ASSUMES WE HAVE A MEGA OBJECT!! - ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[S_OB_MEGA]); + ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[S_OB_MEGA]); // pointer to anim table - anim_table = (int32 *) _vm->_memory->intToPtr(params[S_DIR_TABLE]); + anim_table = (int32 *) _vm->_memory->decodePtr(params[S_DIR_TABLE]); // appropriate anim resource is in 'table[direction]' _animId = anim_table[ob_mega->current_dir]; @@ -1282,7 +1282,7 @@ void Logic::locateTalker(int32 *params) { ObjectMega *ob_mega; - uint8 *file; + byte *file; FrameHeader *frame_head; AnimHeader *anim_head; CdtEntry *cdt_entry; @@ -1313,7 +1313,7 @@ void Logic::locateTalker(int32 *params) { if (cdt_entry->frameType & FRAME_OFFSET) { // this may be NULL - ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[S_OB_MEGA]); + ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[S_OB_MEGA]); // calc scale at which to print the sprite, based on // feet y-coord & scaling constants (NB. 'scale' is @@ -1378,7 +1378,7 @@ void Logic::formText(int32 *params) { uint32 local_text; uint32 text_res; - uint8 *text; + byte *text; uint32 textWidth; ObjectSpeech *ob_speech; @@ -1386,7 +1386,7 @@ void Logic::formText(int32 *params) { // text if (params[S_TEXT]) { - ob_speech = (ObjectSpeech *) _vm->_memory->intToPtr(params[S_OB_SPEECH]); + ob_speech = (ObjectSpeech *) _vm->_memory->decodePtr(params[S_OB_SPEECH]); // establish the max width allowed for this text sprite diff --git a/sword2/startup.cpp b/sword2/startup.cpp index 9c0756cee1..661d702b1b 100644 --- a/sword2/startup.cpp +++ b/sword2/startup.cpp @@ -147,7 +147,7 @@ int32 Logic::fnRegisterStartPoint(int32 *params) { error("ERROR: _startList full"); // +1 to allow for NULL terminator - if (strlen((const char *) _vm->_memory->intToPtr(params[1])) + 1 > MAX_description) + if (strlen((const char *) _vm->_memory->decodePtr(params[1])) + 1 > MAX_description) error("ERROR: startup description too long"); #endif @@ -158,7 +158,7 @@ int32 Logic::fnRegisterStartPoint(int32 *params) { // the correct start _startList[_totalStartups].key = params[0]; - strcpy(_startList[_totalStartups].description, (const char *) _vm->_memory->intToPtr(params[1])); + strcpy(_startList[_totalStartups].description, (const char *) _vm->_memory->decodePtr(params[1])); // point to next _totalStartups++; diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp index a0407af4fb..22ea9dd6c6 100644 --- a/sword2/sword2.cpp +++ b/sword2/sword2.cpp @@ -287,9 +287,6 @@ void Sword2Engine::gameCycle(void) { mouseEngine(); processFxQueue(); - - // update age and calculate previous cycle memory usage - _resman->nextCycle(); } void Sword2Engine::go() { diff --git a/sword2/sword2.h b/sword2/sword2.h index ecc2e5a0f1..64d90ea2ce 100644 --- a/sword2/sword2.h +++ b/sword2/sword2.h @@ -107,22 +107,22 @@ private: void drawBackPar0Frames(void); void drawBackPar1Frames(void); void drawBackFrames(void); - void drawSortFrames(uint8 *file); + void drawSortFrames(byte *file); void drawForeFrames(void); void drawForePar0Frames(void); void drawForePar1Frames(void); void startNewPalette(void); - void processLayer(uint8 *file, uint32 layer_number); + void processLayer(byte *file, uint32 layer_number); void processImage(BuildUnit *build_unit); void getPlayerStructures(void); void putPlayerStructures(void); - uint32 saveData(uint16 slotNo, uint8 *buffer, uint32 bufferSize); - uint32 restoreData(uint16 slotNo, uint8 *buffer, uint32 bufferSize); + uint32 saveData(uint16 slotNo, byte *buffer, uint32 bufferSize); + uint32 restoreData(uint16 slotNo, byte *buffer, uint32 bufferSize); - uint32 calcChecksum(uint8 *buffer, uint32 size); + uint32 calcChecksum(byte *buffer, uint32 size); void pauseGame(void); void unpauseGame(void); @@ -163,7 +163,7 @@ public: void resetRenderLists(void); void buildDisplay(void); - void displayMsg(uint8 *text, int time); + void displayMsg(byte *text, int time); void removeMsg(void); void setFullPalette(int32 palRes); @@ -261,21 +261,21 @@ public: void registerMouse(ObjectMouse *ob_mouse); - uint8 *fetchPalette(uint8 *screenFile); - ScreenHeader *fetchScreenHeader(uint8 *screenFile); - LayerHeader *fetchLayerHeader(uint8 *screenFile, uint16 layerNo); - uint8 *fetchShadingMask(uint8 *screenFile); - - AnimHeader *fetchAnimHeader(uint8 *animFile); - CdtEntry *fetchCdtEntry(uint8 *animFile, uint16 frameNo); - FrameHeader *fetchFrameHeader(uint8 *animFile, uint16 frameNo); - Parallax *fetchBackgroundParallaxLayer(uint8 *screenFile, int layer); - Parallax *fetchBackgroundLayer(uint8 *screenFile); - Parallax *fetchForegroundParallaxLayer(uint8 *screenFile, int layer); - uint8 *fetchTextLine(uint8 *file, uint32 text_line); - bool checkTextLine(uint8 *file, uint32 text_line); - uint8 *fetchPaletteMatchTable(uint8 *screenFile); - uint8 *fetchObjectName(int32 resourceId); + byte *fetchPalette(byte *screenFile); + ScreenHeader *fetchScreenHeader(byte *screenFile); + LayerHeader *fetchLayerHeader(byte *screenFile, uint16 layerNo); + byte *fetchShadingMask(byte *screenFile); + + AnimHeader *fetchAnimHeader(byte *animFile); + CdtEntry *fetchCdtEntry(byte *animFile, uint16 frameNo); + FrameHeader *fetchFrameHeader(byte *animFile, uint16 frameNo); + Parallax *fetchBackgroundParallaxLayer(byte *screenFile, int layer); + Parallax *fetchBackgroundLayer(byte *screenFile); + Parallax *fetchForegroundParallaxLayer(byte *screenFile, int layer); + byte *fetchTextLine(byte *file, uint32 text_line); + bool checkTextLine(byte *file, uint32 text_line); + byte *fetchPaletteMatchTable(byte *screenFile); + byte *fetchObjectName(int32 resourceId); // savegame file header @@ -304,13 +304,13 @@ public: SaveGameHeader _saveGameHeader; - uint32 saveGame(uint16 slotNo, uint8 *description); + uint32 saveGame(uint16 slotNo, byte *description); uint32 restoreGame(uint16 slotNo); - uint32 getSaveDescription(uint16 slotNo, uint8 *description); + uint32 getSaveDescription(uint16 slotNo, byte *description); bool saveExists(void); bool saveExists(uint16 slotNo); - void fillSaveBuffer(Memory *buffer, uint32 size, uint8 *desc); - uint32 restoreFromBuffer(Memory *buffer, uint32 size); + void fillSaveBuffer(byte *buffer, uint32 size, byte *desc); + uint32 restoreFromBuffer(byte *buffer, uint32 size); uint32 findBufferSize(void); uint8 _scrollFraction; diff --git a/sword2/walker.cpp b/sword2/walker.cpp index 9a83ca2c77..49312844ae 100644 --- a/sword2/walker.cpp +++ b/sword2/walker.cpp @@ -46,9 +46,9 @@ int32 Logic::fnWalk(int32 *params) { // 5 target y-coord // 6 target direction (8 means end walk on ANY direction) - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); - ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->intToPtr(params[1]); - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); + ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->decodePtr(params[1]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]); int16 target_x = (int16) params[4]; int16 target_y = (int16) params[5]; @@ -74,7 +74,7 @@ int32 Logic::fnWalk(int32 *params) { assert(params[6] >= 0 && params[6] <= 8); - ob_walkdata = (ObjectWalkdata *) _vm->_memory->intToPtr(params[3]); + ob_walkdata = (ObjectWalkdata *) _vm->_memory->decodePtr(params[3]); ob_mega->walk_pc = 0; @@ -134,7 +134,7 @@ int32 Logic::fnWalk(int32 *params) { // get pointer to walkanim & current frame position - WalkData *walkAnim = _router->lockRouteMem(); + WalkData *walkAnim = _router->getRouteMem(); int32 walk_pc = ob_mega->walk_pc; // If stopping the walk early, overwrite the next step with a @@ -143,7 +143,7 @@ int32 Logic::fnWalk(int32 *params) { if (checkEventWaiting()) { if (walkAnim[walk_pc].step == 0 && walkAnim[walk_pc + 1].step == 1) { // At the beginning of a step - ob_walkdata = (ObjectWalkdata *) _vm->_memory->intToPtr(params[3]); + ob_walkdata = (ObjectWalkdata *) _vm->_memory->decodePtr(params[3]); _router->earlySlowOut(ob_mega, ob_walkdata); } } @@ -198,12 +198,9 @@ int32 Logic::fnWalk(int32 *params) { } } - // Increment the walkanim frame number, float the walkanim & come - // back next cycle + // Increment the walkanim frame number and come back next cycle ob_mega->walk_pc++; - - _router->floatRouteMem(); return IR_REPEAT; } @@ -228,12 +225,12 @@ int32 Logic::fnWalkToAnim(int32 *params) { pars[2] = params[2]; pars[3] = params[3]; - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); // If this is the start of the walk, read anim file to get start coords if (!ob_logic->looping) { - uint8 *anim_file = _vm->_resman->openResource(params[4]); + byte *anim_file = _vm->_resman->openResource(params[4]); AnimHeader *anim_head = _vm->fetchAnimHeader( anim_file ); pars[4] = anim_head->feetStartX; @@ -278,7 +275,7 @@ int32 Logic::fnTurn(int32 *params) { pars[2] = params[2]; pars[3] = params[3]; - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); // If this is the start of the turn, get the mega's current feet // coords + the required direction @@ -286,7 +283,7 @@ int32 Logic::fnTurn(int32 *params) { if (!ob_logic->looping) { assert(params[4] >= 0 && params[4] <= 7); - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]); pars[4] = ob_mega->feet_x; pars[5] = ob_mega->feet_y; @@ -311,8 +308,8 @@ int32 Logic::fnStandAt(int32 *params) { assert(params[4] >= 0 && params[4] <= 7); - ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->intToPtr(params[0]); - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[1]); + ObjectGraphic *ob_graph = (ObjectGraphic *) _vm->_memory->decodePtr(params[0]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[1]); // set up the stand frame & set the mega's new direction @@ -339,7 +336,7 @@ int32 Logic::fnStand(int32 *params) { // 1 pointer to object's mega structure // 2 target direction - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[1]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[1]); int32 pars[5]; @@ -361,7 +358,7 @@ int32 Logic::fnStandAfterAnim(int32 *params) { // 1 pointer to object's mega structure // 2 anim resource id - uint8 *anim_file = _vm->_resman->openResource(params[2]); + byte *anim_file = _vm->_resman->openResource(params[2]); AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file); int32 pars[5]; @@ -399,7 +396,7 @@ int32 Logic::fnStandAtAnim(int32 *params) { // 1 pointer to object's mega structure // 2 anim resource id - uint8 *anim_file = _vm->_resman->openResource(params[2]); + byte *anim_file = _vm->_resman->openResource(params[2]); AnimHeader *anim_head = _vm->fetchAnimHeader(anim_file); int32 pars[5]; @@ -483,13 +480,13 @@ int32 Logic::fnFaceXY(int32 *params) { pars[2] = params[2]; pars[3] = params[3]; - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); // If this is the start of the turn, get the mega's current feet // coords + the required direction if (!ob_logic->looping) { - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]); pars[4] = ob_mega->feet_x; pars[5] = ob_mega->feet_y; @@ -513,7 +510,7 @@ int32 Logic::fnFaceMega(int32 *params) { pars[2] = params[2]; pars[3] = params[3]; - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); // If this is the start of the walk, decide where to walk to. @@ -533,7 +530,7 @@ int32 Logic::fnFaceMega(int32 *params) { _vm->_resman->closeResource(params[4]); - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]); pars[3] = params[3]; pars[4] = ob_mega->feet_x; @@ -563,7 +560,7 @@ int32 Logic::fnWalkToTalkToMega(int32 *params) { pars[2] = params[2]; pars[3] = params[3]; - ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->intToPtr(params[0]); + ObjectLogic *ob_logic = (ObjectLogic *) _vm->_memory->decodePtr(params[0]); // If this is the start of the walk, calculate the route. @@ -586,7 +583,7 @@ int32 Logic::fnWalkToTalkToMega(int32 *params) { // Stand exactly beside the mega, ie. at same y-coord pars[5] = _engineMega.feet_y; - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[2]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[2]); // Apply scale factor to walk distance. Ay+B gives 256 * scale // ie. 256 * 256 * true_scale for even better accuracy, ie. @@ -674,7 +671,7 @@ int32 Logic::fnSetScaling(int32 *params) { // Where s is system scale, which itself is (256 * actual_scale) ie. // s == 128 is half size - ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->intToPtr(params[0]); + ObjectMega *ob_mega = (ObjectMega *) _vm->_memory->decodePtr(params[0]); ob_mega->scale_a = params[1]; ob_mega->scale_b = params[2]; -- cgit v1.2.3