aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--sword2/anims.cpp55
-rw-r--r--sword2/build_display.cpp54
-rw-r--r--sword2/console.cpp2
-rw-r--r--sword2/console.h2
-rw-r--r--sword2/controls.cpp60
-rw-r--r--sword2/debug.cpp4
-rw-r--r--sword2/driver/_mouse.cpp18
-rw-r--r--sword2/driver/animation.cpp24
-rw-r--r--sword2/driver/animation.h8
-rw-r--r--sword2/driver/d_draw.h36
-rw-r--r--sword2/driver/d_sound.cpp10
-rw-r--r--sword2/driver/driver96.h4
-rw-r--r--sword2/driver/menu.cpp4
-rw-r--r--sword2/driver/palette.cpp6
-rw-r--r--sword2/driver/render.cpp16
-rw-r--r--sword2/driver/sprite.cpp44
-rw-r--r--sword2/events.cpp2
-rw-r--r--sword2/function.cpp28
-rw-r--r--sword2/header.h2
-rw-r--r--sword2/icons.cpp6
-rw-r--r--sword2/interpreter.cpp10
-rw-r--r--sword2/layers.cpp6
-rw-r--r--sword2/logic.h2
-rw-r--r--sword2/maketext.cpp64
-rw-r--r--sword2/maketext.h16
-rw-r--r--sword2/mem_view.cpp164
-rw-r--r--sword2/memory.cpp625
-rw-r--r--sword2/memory.h90
-rw-r--r--sword2/module.mk1
-rw-r--r--sword2/mouse.cpp29
-rw-r--r--sword2/protocol.cpp57
-rw-r--r--sword2/resman.cpp594
-rw-r--r--sword2/resman.h47
-rw-r--r--sword2/router.cpp41
-rw-r--r--sword2/router.h5
-rw-r--r--sword2/save_rest.cpp78
-rw-r--r--sword2/sound.cpp4
-rw-r--r--sword2/speech.cpp30
-rw-r--r--sword2/startup.cpp4
-rw-r--r--sword2/sword2.cpp3
-rw-r--r--sword2/sword2.h50
-rw-r--r--sword2/walker.cpp49
43 files changed, 806 insertions, 1551 deletions
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, "<sob> %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];