mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-18 07:53:12 +00:00
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:
parent
fd38da7f13
commit
8f8185f035
3
NEWS
3
NEWS
@ -22,7 +22,8 @@ For a more comprehensive changelog for the latest experimental CVS code, see:
|
||||
- ??? [TODO: Somebody of the Sword1 team please fill this in]
|
||||
|
||||
Sword2:
|
||||
- Various fixes [TODO: Somebody of the Sword2 team please fill this in]
|
||||
- Simplified the memory/resource management.
|
||||
- Various minor bugfixes.
|
||||
|
||||
BASS
|
||||
- ???
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -87,7 +87,7 @@ private:
|
||||
uint32 textNumber;
|
||||
uint16 startFrame;
|
||||
uint16 endFrame;
|
||||
Memory *text_mem;
|
||||
byte *text_mem;
|
||||
uint32 speechBufferSize;
|
||||
uint16 *speech_mem;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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++;
|
||||
|
@ -287,9 +287,6 @@ void Sword2Engine::gameCycle(void) {
|
||||
|
||||
mouseEngine();
|
||||
processFxQueue();
|
||||
|
||||
// update age and calculate previous cycle memory usage
|
||||
_resman->nextCycle();
|
||||
}
|
||||
|
||||
void Sword2Engine::go() {
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user