Major revamping of the BS2 memory manager and, some small changes to the

resource manager. All new code! All new bugs!

svn-id: r13603
This commit is contained in:
Torbjörn Andersson 2004-04-23 07:02:11 +00:00
parent fd38da7f13
commit 8f8185f035
43 changed files with 844 additions and 1589 deletions

3
NEWS
View File

@ -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
- ???

View File

@ -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;

View File

@ -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;
}
/**
* Start layer palette fading up
*/
void Sword2Engine::startNewPalette(void) {
// start layer palette fading up
uint8 *screenFile;
// 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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -87,7 +87,7 @@ private:
uint32 textNumber;
uint16 startFrame;
uint16 endFrame;
Memory *text_mem;
byte *text_mem;
uint32 speechBufferSize;
uint16 *speech_mem;
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
_memBlocks = (MemBlock *) malloc(MAX_BLOCKS * sizeof(MemBlock));
_memBlockIndex = (MemBlock **) malloc(MAX_BLOCKS * sizeof(MemBlock *));
_idStack = (int16 *) malloc(MAX_BLOCKS * sizeof(int16));
_suggestedStart = 0;
_totAlloc = 0;
_numBlocks = 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;
// set all but first handle to unused
for (j = 1; j < MAX_mem_blocks; j++)
_memList[j].state = MEM_null;
// 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
_baseMemBlock = 0; // for now
}
MemoryManager::~MemoryManager(void) {
free(_freeMemman);
}
// 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::ptrToInt(const uint8 *p) {
debug(9, "ptrToInt: %p -> %d", p, p - _freeMemman);
if (p < _freeMemman || p >= &_freeMemman[MEMORY_POOL])
warning("ptrToInt: Converting bad pointer: %p", p);
return p - _freeMemman;
}
uint8 *MemoryManager::intToPtr(int32 n) {
debug(9, "intToPtr: %d -> %p", n, &_freeMemman[n]);
if (n < 0 || n >= MEMORY_POOL)
warning("intToPtr: Converting bad integer: %d", n);
return &_freeMemman[n];
}
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;
for (int i = 0; i < MAX_BLOCKS; i++) {
_idStack[i] = MAX_BLOCKS - i - 1;
_memBlocks[i].ptr = NULL;
_memBlockIndex[i] = NULL;
}
// 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
slack = _memList[nu_block].size - size;
_memList[nu_block].state = type; // locked or float
_memList[nu_block].size = size; // set to the required size
_memList[nu_block].uid = unique_id; // an identifier
// child starts after us
_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];
}
// otherwise we spawn a new block after us and before our child - our
// child being a proper block that we cannot change
// we remain a child of our parent
// we spawn a new child and it inherits our current child
// find a NULL slot for a new block
while (_memList[spawn].state != MEM_null && spawn!=MAX_mem_blocks)
spawn++;
if (spawn == MAX_mem_blocks) {
// run out of blocks - stop the program. this is a major blow
// up and we need to alert the developer
// Lets get a printout of this
debugMemory();
error("Out of mem blocks in Talloc()");
}
_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;
// IOW the remaining memory is given to the new free block
// we start 1 byte after the newly allocated block
_memList[spawn].ad = _memList[nu_block].ad + size;
// the spawned child gets it parent - the newly allocated block
_memList[spawn].parent = nu_block;
// the new child inherits the parents old child (we are its new
// child "Waaaa")
_memList[spawn].child = _memList[nu_block].child;
// 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;
}
_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++;
#ifdef MEMDEBUG
debugMemory();
#endif
return &_memList[nu_block];
_idStackPtr = MAX_BLOCKS;
}
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
block->state = MEM_free;
block->uid = (uint32) UID_memman; // belongs to the memory manager again
#ifdef MEMDEBUG
debugMemory();
#endif
MemoryManager::~MemoryManager() {
for (int i = 0; i < MAX_BLOCKS; i++)
free(_memBlocks[i].ptr);
free(_memBlocks);
free(_memBlockIndex);
free(_idStack);
}
void MemoryManager::floatMemory(Memory *block) {
// set a block to float
// wont be trashed but will move around in memory
int32 MemoryManager::encodePtr(byte *ptr) {
int idx = findPointerInIndex(ptr);
block->state = MEM_float;
if (idx == -1)
error("Encoding non-allocated pointer %p", ptr);
#ifdef MEMDEBUG
debugMemory();
#endif
int id = _memBlockIndex[idx]->id;
return (id << 22) | (ptr - _memBlocks[id].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
byte *MemoryManager::decodePtr(int32 n) {
int16 id = (n >> 22) & 0x03ff;
int32 offset = n & 0x003fffff;
// can't move now - this block is now crying out to be floated or
// free'd again
block->state = MEM_locked;
#ifdef MEMDEBUG
debugMemory();
#endif
return _memBlocks[id].ptr + offset;
}
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.
int16 MemoryManager::findExactPointerInIndex(byte *ptr) {
int left = 0;
int right = _numBlocks - 1;
int32 cur_block; // block 0 remains the parent block
int32 original_parent,child, end_child;
uint32 j;
uint32 *a;
uint32 *b;
while (right >= left) {
int n = (left + right) / 2;
// cur_block = _baseMemBlock; //the mother of all parents
cur_block = _suggestedStart;
if (_memBlockIndex[n]->ptr == ptr)
return n;
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::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);
if (_memBlockIndex[n]->ptr > ptr)
right = n - 1;
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);
left = n + 1;
}
// 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);
return -1;
}
Memory *MemoryManager::allocMemory(uint32 size, uint32 type, uint32 unique_id) {
// the high level allocator
int16 MemoryManager::findPointerInIndex(byte *ptr) {
int left = 0;
int right = _numBlocks - 1;
// can ask the resman to remove old resources to make space - will
// either do it or halt the system
while (right >= left) {
int n = (left + right) / 2;
Memory *membloc;
int j;
uint32 free = 0;
if (_memBlockIndex[n]->ptr <= ptr && _memBlockIndex[n]->ptr + _memBlockIndex[n]->size > ptr)
return n;
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);
}
if (_memBlockIndex[n]->ptr > ptr)
right = n - 1;
else
left = n + 1;
}
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);
// return the pointer to the memory
return membloc;
return -1;
}
// Maximum allowed wasted memory.
#define MAX_WASTAGE 51200
int16 MemoryManager::findInsertionPointInIndex(byte *ptr) {
if (_numBlocks == 0)
return 0;
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.
int left = 0;
int right = _numBlocks - 1;
int n = 0;
int32 cur_block;
uint32 currentBubbleSize = 0;
while (right >= left) {
n = (left + right) / 2;
cur_block = _baseMemBlock;
_suggestedStart = _baseMemBlock;
if (_memBlockIndex[n]->ptr == ptr)
return -1;
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 (_memBlockIndex[n]->ptr > ptr)
right = n - 1;
else
left = n + 1;
}
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 (_memBlockIndex[n]->ptr < ptr)
n++;
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;
}
return n;
}
cur_block = _memList[cur_block].child;
} while (cur_block != -1);
byte *MemoryManager::memAlloc(uint32 size, int16 uid) {
byte *ptr = (byte *) malloc(size);
return 1;
assert(ptr);
assert(_idStackPtr > 0);
// Get the new block's id from the stack.
int16 id = _idStack[--_idStackPtr];
_memBlocks[id].id = id;
_memBlocks[id].uid = uid;
_memBlocks[id].ptr = ptr;
_memBlocks[id].size = size;
// 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.
int16 idx = findInsertionPointInIndex(ptr);
assert(idx != -1);
for (int i = _numBlocks; i > idx; i--)
_memBlockIndex[i] = _memBlockIndex[i - 1];
_memBlockIndex[idx] = &_memBlocks[id];
_numBlocks++;
_totAlloc += size;
return _memBlocks[id].ptr;
}
void MemoryManager::memFree(byte *ptr) {
int16 idx = findExactPointerInIndex(ptr);
if (idx == -1) {
warning("Freeing non-allocated pointer %p", ptr);
return;
}
// Put back the id on the stack
_idStack[_idStackPtr++] = _memBlockIndex[idx]->id;
free(_memBlockIndex[idx]->ptr);
_memBlockIndex[idx]->ptr = NULL;
_totAlloc -= _memBlockIndex[idx]->size;
// Remove the pointer from the index
_numBlocks--;
for (int i = idx; i < _numBlocks; i++)
_memBlockIndex[i] = _memBlockIndex[i + 1];
}
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);
}
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

View File

@ -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;
MemBlock *_memBlocks;
MemBlock **_memBlockIndex;
int16 _numBlocks;
uint32 _totalFreeMemory;
uint32 _totalBlocks;
uint32 _totAlloc;
// Start position of the defragger as indicated by its sister,
// VirtualDefrag.
int32 _suggestedStart;
int16 *_idStack;
int16 _idStackPtr;
Memory *lowLevelAlloc(uint32 size, uint32 type, uint32 unique_id);
int32 defragMemory(uint32 req_size);
// Used to determine if the required size can be obtained if the
// defragger is allowed to run.
int32 virtualDefrag(uint32 size);
// Debugging functions
void debugMemory(void);
const char *fetchOwner(uint32 uid);
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

View File

@ -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 \

View File

@ -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

View File

@ -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;
}

View File

@ -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;
// update the accessed time stamp - touch the file in other words
_age[res] = _resTime;
// pass the address of the mem & lock the memory too
// might be locked already (if count > 1)
_vm->_memory->lockMemory(_resList[res]);
return (uint8 *) _resList[res]->ad;
}
uint8 ResourceManager::checkValid(uint32 res) {
// returns '1' if resource is valid, otherwise returns '0'
// used in startup.cpp to ignore invalid screen-manager resources
uint16 parent_res_file;
// resource number out of range
if (res >= _totalResFiles)
return 0;
// points to the number of the ascii filename
parent_res_file = _resConvTable[res * 2];
// null & void resource
if (parent_res_file == 0xffff)
return 0;
// ok
return 1;
}
void ResourceManager::nextCycle(void) {
// increment the cycle and calculate actual per-cycle memory useage
#ifdef _SWORD2_DEBUG
_currentMemoryUsage = 0;
for (int i = 1; i < _totalResFiles; i++) {
// was accessed last cycle
if (_age[i] == _resTime)
_currentMemoryUsage += _resList[i]->size;
}
#endif
_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;
return _resList[res].ptr;
}
void ResourceManager::closeResource(uint32 res) {
// decrements the count
// resource floats when count = 0
assert(res < _totalResFiles);
assert(_count[res]);
assert(_resList[res].refCount > 0);
//one less has it open
_count[res]--;
_resList[res].refCount--;
_resList[res].refTime = _resTime;
//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]);
}
#if !CACHE_CLUSTERS
// Maybe it's useful on some platforms if memory is released as
// quickly as possible?
if (_resList[res].refCount == 0)
remove(res);
#endif
}
/**
* Returns true if resource is valid, otherwise false.
*/
bool ResourceManager::checkValid(uint32 res) {
// Resource number out of range
if (res >= _totalResFiles)
return false;
// Points to the number of the ascii filename
uint16 parent_res_file = _resConvTable[res * 2];
// Null & void resource
if (parent_res_file == 0xffff)
return false;
return true;
}
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.
// 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.
// Therefore, this function is now called when a new room is loaded.
_resTime++;
}
/**
* 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);
file.seek(table_offset + (actual_res * 8) + 4, SEEK_SET);
// read the length
len = fh.readUint32LE();
return len;
return file.readUint32LE();
}
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]];
}
void ResourceManager::expelOldResources() {
int nuked = 0;
uint32 ResourceManager::fetchAge(uint32 res) {
// return the age of res
return _age[res];
}
uint32 ResourceManager::fetchCount(uint32 res) {
// return the open count of res
return _count[res];
}
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");
if (!_resList[res].ptr) {
Debug_Printf("Resource %d is not in memory\n", res);
return;
}
if (_resList[res].refCount) {
Debug_Printf("Resource %d is open - cannot remove\n", res);
return;
}
remove(res);
Debug_Printf("Trashed %d\n", res);
}
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);
}
void ResourceManager::removeAll(void) {
// remove all res files from memory - ready for a total restart
// including player object & global variables resource
int j;
uint32 res;
j = _vm->_memory->_baseMemBlock;
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
}
j = _vm->_memory->_memList[j].child;
} while (j != -1);
}
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;
j = _vm->_memory->_baseMemBlock;
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);
_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);
}
}
}
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);
void ResourceManager::remove(int res) {
if (_resList[res].ptr) {
_vm->_memory->memFree(_resList[res].ptr);
_resList[res].ptr = NULL;
}
}
//----------------------------------------------------------------------------
// 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.
/**
* Remove all res files from memory - ready for a total restart. This includes
* the player object and global variables resource.
*/
void ResourceManager::removeAll(void) {
for (uint i = 0; i < _totalResFiles; i++)
remove(i);
}
/**
* Remove all resources from memory.
*/
void ResourceManager::killAll(bool wantInfo) {
int nuked = 0;
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;
if (_resList[i].ptr) {
StandardHeader *header = (StandardHeader *) _resList[i].ptr;
if (wantInfo)
Debug_Printf("Nuked %5d: %s\n", i, header->name);
remove(i);
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.
*/
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) {
if (wantInfo)
Debug_Printf("Nuked %5d: %s\n", i, header->name);
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);
}
}
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

View File

@ -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.
};

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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++;

View File

@ -287,9 +287,6 @@ void Sword2Engine::gameCycle(void) {
mouseEngine();
processFxQueue();
// update age and calculate previous cycle memory usage
_resman->nextCycle();
}
void Sword2Engine::go() {

View File

@ -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);
byte *fetchPalette(byte *screenFile);
ScreenHeader *fetchScreenHeader(byte *screenFile);
LayerHeader *fetchLayerHeader(byte *screenFile, uint16 layerNo);
byte *fetchShadingMask(byte *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);
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;

View File

@ -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];