aboutsummaryrefslogtreecommitdiff
path: root/engines/hugo/file.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/hugo/file.cpp')
-rw-r--r--engines/hugo/file.cpp237
1 files changed, 114 insertions, 123 deletions
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index fa8d5b9947..c3e59b19c9 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -39,17 +39,20 @@
#include "hugo/schedule.h"
#include "hugo/display.h"
#include "hugo/util.h"
+#include "hugo/object.h"
namespace Hugo {
-FileManager::FileManager(HugoEngine &vm) : _vm(vm) {
+FileManager::FileManager(HugoEngine *vm) : _vm(vm) {
}
FileManager::~FileManager() {
}
+/**
+* Convert 4 planes (RGBI) data to 8-bit DIB format
+* Return original plane data ptr
+*/
byte *FileManager::convertPCC(byte *p, uint16 y, uint16 bpl, image_pt dataPtr) {
-// Convert 4 planes (RGBI) data to 8-bit DIB format
-// Return original plane data ptr
debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, image_pt data_p)", y, bpl);
dataPtr += y * bpl * 8; // Point to correct DIB line
@@ -64,10 +67,12 @@ byte *FileManager::convertPCC(byte *p, uint16 y, uint16 bpl, image_pt dataPtr) {
return p;
}
+/**
+* Read a pcx file of length len. Use supplied seq_p and image_p or
+* allocate space if NULL. Name used for errors. Returns address of seq_p
+* Set first TRUE to initialize b_index (i.e. not reading a sequential image in file).
+*/
seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool firstFl, const char *name) {
-// Read a pcx file of length len. Use supplied seq_p and image_p or
-// allocate space if NULL. Name used for errors. Returns address of seq_p
-// Set first TRUE to initialize b_index (i.e. not reading a sequential image in file).
debugC(1, kDebugFile, "readPCX(..., %s)", name);
// Read in the PCC header and check consistency
@@ -96,7 +101,7 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool
if ((seqPtr = (seq_t *)malloc(sizeof(seq_t))) == 0)
Utils::Error(HEAP_ERR, "%s", name);
}
-
+
// Find size of image data in 8-bit DIB format
// Note save of x2 - marks end of valid data before garbage
uint16 bytesPerLine4 = PCC_header.bytesPerLine * 4; // 4-bit bpl
@@ -136,14 +141,16 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool
return seqPtr;
}
+/**
+* Read object file of PCC images into object supplied
+*/
void FileManager::readImage(int objNum, object_t *objPtr) {
-// Read object file of PCC images into object supplied
debugC(1, kDebugFile, "readImage(%d, object_t *objPtr)", objNum);
if (!objPtr->seqNumb) // This object has no images
return;
- if (_vm.isPacked()) {
+ if (_vm->isPacked()) {
_objectsArchive.seek((uint32)objNum * sizeof(objBlock_t), SEEK_SET);
objBlock_t objBlock; // Info on file within database
@@ -153,10 +160,10 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
_objectsArchive.seek(objBlock.objOffset, SEEK_SET);
} else {
char *buf = (char *) malloc(2048 + 1); // Buffer for file access
- strcat(strcat(strcpy(buf, _vm._picDir), _vm._arrayNouns[objPtr->nounIndex][0]), OBJEXT);
+ strcat(strcat(strcpy(buf, _vm->_picDir), _vm->_arrayNouns[objPtr->nounIndex][0]), OBJEXT);
if (!_objectsArchive.open(buf)) {
- warning("File %s not found, trying again with %s%s", buf, _vm._arrayNouns[objPtr->nounIndex][0], OBJEXT);
- strcat(strcpy(buf, _vm._arrayNouns[objPtr->nounIndex][0]), OBJEXT);
+ warning("File %s not found, trying again with %s%s", buf, _vm->_arrayNouns[objPtr->nounIndex][0], OBJEXT);
+ strcat(strcpy(buf, _vm->_arrayNouns[objPtr->nounIndex][0]), OBJEXT);
if (!_objectsArchive.open(buf))
Utils::Error(FILE_ERR, "%s", buf);
}
@@ -170,12 +177,12 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image
if (k == 0) { // First image
// Read this image - allocate both seq and image memory
- seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]);
+ seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]);
objPtr->seqList[j].seqPtr = seqPtr;
firstFl = false;
} else { // Subsequent image
// Read this image - allocate both seq and image memory
- seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]);
+ seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]);
seqPtr = seqPtr->nextSeqPtr;
}
@@ -203,6 +210,7 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
}
}
}
+ assert(seqPtr);
seqPtr->nextSeqPtr = objPtr->seqList[j].seqPtr; // loop linked list to head
}
@@ -221,17 +229,19 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
warning("Unexpected cycling: %d", objPtr->cycling);
}
- if (!_vm.isPacked())
+ if (!_vm->isPacked())
_objectsArchive.close();
}
+/**
+* Read sound (or music) file data. Call with SILENCE to free-up
+* any allocated memory. Also returns size of data
+*/
sound_pt FileManager::getSound(int16 sound, uint16 *size) {
-// Read sound (or music) file data. Call with SILENCE to free-up
-// any allocated memory. Also returns size of data
debugC(1, kDebugFile, "getSound(%d, %d)", sound, *size);
// No more to do if SILENCE (called for cleanup purposes)
- if (sound == _vm._soundSilence)
+ if (sound == _vm->_soundSilence)
return 0;
// Open sounds file
@@ -258,7 +268,7 @@ sound_pt FileManager::getSound(int16 sound, uint16 *size) {
// Allocate memory for sound or music, if possible
sound_pt soundPtr = (byte *)malloc(s_hdr[sound].size); // Ptr to sound data
if (soundPtr == 0) {
- Utils::Warn("%s", "Low on memory");
+ warning("Low on memory");
return 0;
}
@@ -272,8 +282,10 @@ sound_pt FileManager::getSound(int16 sound, uint16 *size) {
return soundPtr;
}
+/**
+* Return whether file exists or not
+*/
bool FileManager::fileExists(char *filename) {
-// Return whether file exists or not
Common::File f;
if (f.open(filename)) {
f.close();
@@ -282,48 +294,21 @@ bool FileManager::fileExists(char *filename) {
return false;
}
-void FileManager::saveSeq(object_t *obj) {
-// Save sequence number and image number in given object
- debugC(1, kDebugFile, "saveSeq");
-
- bool found = false;
- for (int j = 0; !found && (j < obj->seqNumb); j++) {
- seq_t *q = obj->seqList[j].seqPtr;
- for (int k = 0; !found && (k < obj->seqList[j].imageNbr); k++) {
- if (obj->currImagePtr == q) {
- found = true;
- obj->curSeqNum = j;
- obj->curImageNum = k;
- } else {
- q = q->nextSeqPtr;
- }
- }
- }
-}
-
-void FileManager::restoreSeq(object_t *obj) {
-// Set up cur_seq_p from stored sequence and image number in object
- debugC(1, kDebugFile, "restoreSeq");
-
- seq_t *q = obj->seqList[obj->curSeqNum].seqPtr;
- for (int j = 0; j < obj->curImageNum; j++)
- q = q->nextSeqPtr;
- obj->currImagePtr = q;
-}
-
+/**
+* Save game to supplied slot (-1 is INITFILE)
+*/
void FileManager::saveGame(int16 slot, const char *descrip) {
-// Save game to supplied slot (-1 is INITFILE)
debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip);
// Get full path of saved game file - note test for INITFILE
Common::String path; // Full path of saved game
if (slot == -1)
- path = _vm._initFilename;
+ path = _vm->_initFilename;
else
- path = Common::String::printf(_vm._saveFilename.c_str(), slot);
+ path = Common::String::format(_vm->_saveFilename.c_str(), slot);
- Common::WriteStream *out = _vm.getSaveFileManager()->openForSaving(path);
+ Common::WriteStream *out = _vm->getSaveFileManager()->openForSaving(path);
if (!out) {
warning("Can't create file '%s', game not saved", path.c_str());
return;
@@ -336,19 +321,19 @@ void FileManager::saveGame(int16 slot, const char *descrip) {
out->write(descrip, DESCRIPLEN);
// Save objects
- for (int i = 0; i < _vm._numObj; i++) {
+ for (int i = 0; i < _vm->_numObj; i++) {
// Save where curr_seq_p is pointing to
- saveSeq(&_vm._objects[i]);
- out->write(&_vm._objects[i], sizeof(object_t));
+ _vm->_object->saveSeq(&_vm->_object->_objects[i]);
+ out->write(&_vm->_object->_objects[i], sizeof(object_t));
}
- const status_t &gameStatus = _vm.getGameStatus();
+ const status_t &gameStatus = _vm->getGameStatus();
// Save whether hero image is swapped
- out->write(&_vm._heroImage, sizeof(_vm._heroImage));
+ out->write(&_vm->_heroImage, sizeof(_vm->_heroImage));
// Save score
- int score = _vm.getScore();
+ int score = _vm->getScore();
out->write(&score, sizeof(score));
// Save story mode
@@ -361,16 +346,16 @@ void FileManager::saveGame(int16 slot, const char *descrip) {
out->write(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl));
// Save screen states
- out->write(_vm._screenStates, sizeof(*_vm._screenStates) * _vm._numScreens);
+ out->write(_vm->_screenStates, sizeof(*_vm->_screenStates) * _vm->_numScreens);
// Save points table
- out->write(_vm._points, sizeof(point_t) * _vm._numBonuses);
+ out->write(_vm->_points, sizeof(point_t) * _vm->_numBonuses);
// Now save current time and all current events in event queue
- _vm.scheduler().saveEvents(out);
+ _vm->_scheduler->saveEvents(out);
// Save palette table
- _vm.screen().savePal(out);
+ _vm->_screen->savePal(out);
// Save maze status
out->write(&_maze, sizeof(maze_t));
@@ -380,22 +365,24 @@ void FileManager::saveGame(int16 slot, const char *descrip) {
delete out;
}
+/**
+* Restore game from supplied slot number (-1 is INITFILE)
+*/
void FileManager::restoreGame(int16 slot) {
-// Restore game from supplied slot number (-1 is INITFILE)
debugC(1, kDebugFile, "restoreGame(%d)", slot);
// Initialize new-game status
- _vm.initStatus();
+ _vm->initStatus();
// Get full path of saved game file - note test for INITFILE
Common::String path; // Full path of saved game
if (slot == -1)
- path = _vm._initFilename;
+ path = _vm->_initFilename;
else
- path = Common::String::printf(_vm._saveFilename.c_str(), slot);
+ path = Common::String::format(_vm->_saveFilename.c_str(), slot);
- Common::SeekableReadStream *in = _vm.getSaveFileManager()->openForLoading(path);
+ Common::SeekableReadStream *in = _vm->getSaveFileManager()->openForLoading(path);
if (!in)
return;
@@ -411,13 +398,13 @@ void FileManager::restoreGame(int16 slot) {
in->seek(DESCRIPLEN, SEEK_CUR);
// If hero image is currently swapped, swap it back before restore
- if (_vm._heroImage != HERO)
- _vm.scheduler().swapImages(HERO, _vm._heroImage);
+ if (_vm->_heroImage != HERO)
+ _vm->_object->swapImages(HERO, _vm->_heroImage);
// Restore objects, retain current seqList which points to dynamic mem
// Also, retain cmnd_t pointers
- for (int i = 0; i < _vm._numObj; i++) {
- object_t *p = &_vm._objects[i];
+ for (int i = 0; i < _vm->_numObj; i++) {
+ object_t *p = &_vm->_object->_objects[i];
seqList_t seqList[MAX_SEQUENCES];
memcpy(seqList, p->seqList, sizeof(seqList_t));
uint16 cmdIndex = p->cmdIndex;
@@ -426,37 +413,37 @@ void FileManager::restoreGame(int16 slot) {
memcpy(p->seqList, seqList, sizeof(seqList_t));
}
- in->read(&_vm._heroImage, sizeof(_vm._heroImage));
+ in->read(&_vm->_heroImage, sizeof(_vm->_heroImage));
// If hero swapped in saved game, swap it
- int heroImg = _vm._heroImage;
+ int heroImg = _vm->_heroImage;
if (heroImg != HERO)
- _vm.scheduler().swapImages(HERO, _vm._heroImage);
- _vm._heroImage = heroImg;
+ _vm->_object->swapImages(HERO, _vm->_heroImage);
+ _vm->_heroImage = heroImg;
- status_t &gameStatus = _vm.getGameStatus();
+ status_t &gameStatus = _vm->getGameStatus();
int score;
in->read(&score, sizeof(score));
- _vm.setScore(score);
+ _vm->setScore(score);
in->read(&gameStatus.storyModeFl, sizeof(gameStatus.storyModeFl));
in->read(&gameStatus.jumpExitFl, sizeof(gameStatus.jumpExitFl));
in->read(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl));
- in->read(_vm._screenStates, sizeof(*_vm._screenStates) * _vm._numScreens);
+ in->read(_vm->_screenStates, sizeof(*_vm->_screenStates) * _vm->_numScreens);
// Restore points table
- in->read(_vm._points, sizeof(point_t) * _vm._numBonuses);
+ in->read(_vm->_points, sizeof(point_t) * _vm->_numBonuses);
// Restore ptrs to currently loaded objects
- for (int i = 0; i < _vm._numObj; i++)
- restoreSeq(&_vm._objects[i]);
+ for (int i = 0; i < _vm->_numObj; i++)
+ _vm->_object->restoreSeq(&_vm->_object->_objects[i]);
// Now restore time of the save and the event queue
- _vm.scheduler().restoreEvents(in);
+ _vm->_scheduler->restoreEvents(in);
// Restore palette and change it if necessary
- _vm.screen().restorePal(in);
+ _vm->_screen->restorePal(in);
// Restore maze status
in->read(&_maze, sizeof(maze_t));
@@ -464,62 +451,50 @@ void FileManager::restoreGame(int16 slot) {
delete in;
}
+/**
+* Initialize the size of a saved game (from the fixed initial game).
+* If status.initsave is TRUE, or the initial saved game is not found,
+* force a save to create one. Normally the game will be shipped with
+* the initial game file but useful to force a write during development
+* when the size is changeable.
+* The net result is a valid INITFILE, with status.savesize initialized.
+*/
void FileManager::initSavedGame() {
-// Initialize the size of a saved game (from the fixed initial game).
-// If status.initsave is TRUE, or the initial saved game is not found,
-// force a save to create one. Normally the game will be shipped with
-// the initial game file but useful to force a write during development
-// when the size is changeable.
-// The net result is a valid INITFILE, with status.savesize initialized.
debugC(1, kDebugFile, "initSavedGame");
// Force save of initial game
- if (_vm.getGameStatus().initSaveFl)
+ if (_vm->getGameStatus().initSaveFl)
saveGame(-1, "");
// If initial game doesn't exist, create it
- Common::SeekableReadStream *in = _vm.getSaveFileManager()->openForLoading(_vm._initFilename);
+ Common::SeekableReadStream *in = _vm->getSaveFileManager()->openForLoading(_vm->_initFilename);
if (!in) {
saveGame(-1, "");
- in = _vm.getSaveFileManager()->openForLoading(_vm._initFilename);
+ in = _vm->getSaveFileManager()->openForLoading(_vm->_initFilename);
if (!in) {
- Utils::Error(WRITE_ERR, "%s", _vm._initFilename.c_str());
+ Utils::Error(WRITE_ERR, "%s", _vm->_initFilename.c_str());
return;
}
}
// Must have an open saved game now
- _vm.getGameStatus().saveSize = in->size();
+ _vm->getGameStatus().saveSize = in->size();
delete in;
// Check sanity - maybe disk full or path set to read-only drive?
- if (_vm.getGameStatus().saveSize == -1)
- Utils::Error(WRITE_ERR, "%s", _vm._initFilename.c_str());
-}
-
-void FileManager::openPlaybackFile(bool playbackFl, bool recordFl) {
- debugC(1, kDebugFile, "openPlaybackFile(%d, %d)", (playbackFl) ? 1 : 0, (recordFl) ? 1 : 0);
-
- if (playbackFl) {
- if (!(fpb = fopen(PBFILE, "r+b")))
- Utils::Error(FILE_ERR, "%s", PBFILE);
- } else if (recordFl) {
- fpb = fopen(PBFILE, "wb");
- }
- pbdata.time = 0; // Say no key available
-}
-
-void FileManager::closePlaybackFile() {
- fclose(fpb);
+ if (_vm->getGameStatus().saveSize == -1)
+ Utils::Error(WRITE_ERR, "%s", _vm->_initFilename.c_str());
}
+/**
+* Read the encrypted text from the boot file and print it
+*/
void FileManager::printBootText() {
-// Read the encrypted text from the boot file and print it
debugC(1, kDebugFile, "printBootText");
Common::File ofp;
if (!ofp.open(BOOTFILE)) {
- if (_vm._gameVariant == 3) {
+ if (_vm->_gameVariant == 3) {
//TODO initialize properly _boot structure
warning("printBootText - Skipping as H1 Dos may be a freeware");
return;
@@ -551,14 +526,16 @@ void FileManager::printBootText() {
ofp.close();
}
+/**
+* Reads boot file for program environment. Fatal error if not there or
+* file checksum is bad. De-crypts structure while checking checksum
+*/
void FileManager::readBootFile() {
-// Reads boot file for program environment. Fatal error if not there or
-// file checksum is bad. De-crypts structure while checking checksum
debugC(1, kDebugFile, "readBootFile");
Common::File ofp;
if (!ofp.open(BOOTFILE)) {
- if (_vm._gameVariant == 3) {
+ if (_vm->_gameVariant == 3) {
//TODO initialize properly _boot structure
warning("readBootFile - Skipping as H1 Dos may be a freeware");
return;
@@ -589,8 +566,10 @@ void FileManager::readBootFile() {
Utils::Error(GEN_ERR, "%s", "Program startup file invalid");
}
+/**
+* Returns address of uif_hdr[id], reading it in if first call
+*/
uif_hdr_t *FileManager::getUIFHeader(uif_t id) {
-// Returns address of uif_hdr[id], reading it in if first call
debugC(1, kDebugFile, "getUIFHeader(%d)", id);
static bool firstFl = true;
@@ -617,8 +596,10 @@ uif_hdr_t *FileManager::getUIFHeader(uif_t id) {
return &UIFHeader[id];
}
+/**
+* Read uif item into supplied buffer.
+*/
void FileManager::readUIFItem(int16 id, byte *buf) {
-// Read uif item into supplied buffer.
debugC(1, kDebugFile, "readUIFItem(%d, ...)", id);
// Open uif file to read data
@@ -645,10 +626,11 @@ void FileManager::readUIFItem(int16 id, byte *buf) {
ip.close();
}
+/**
+* Simple instructions given when F1 pressed twice in a row
+* Only in DOS versions
+*/
void FileManager::instructions() {
-// Simple instructions given when F1 pressed twice in a row
-// Only in DOS versions
-
Common::File f;
if (!f.open(HELPFILE)) {
warning("help.dat not found");
@@ -672,5 +654,14 @@ void FileManager::instructions() {
f.close();
}
+/**
+* Read the uif image file (inventory icons)
+*/
+void FileManager::readUIFImages() {
+ debugC(1, kDebugFile, "readUIFImages");
+
+ readUIFItem(UIF_IMAGES, _vm->_screen->getGUIBuffer()); // Read all uif images
+}
+
} // End of namespace Hugo