diff options
Diffstat (limited to 'engines/lab/resource.cpp')
-rw-r--r-- | engines/lab/resource.cpp | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/engines/lab/resource.cpp b/engines/lab/resource.cpp new file mode 100644 index 0000000000..9babc5c080 --- /dev/null +++ b/engines/lab/resource.cpp @@ -0,0 +1,324 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + * This code is based on Labyrinth of Time code with assistance of + * + * Copyright (c) 1993 Terra Nova Development + * Copyright (c) 2004 The Wyrmkeep Entertainment Co. + * + */ + +//#include "lab/labfun.h" +//#include "lab/parsetypes.h" +//#include "lab/parsefun.h" +//#include "lab/stddefines.h" +#include "lab/text.h" +#include "lab/resource.h" + +namespace Lab { + +static uint16 allocroom; + +extern RoomData *Rooms; +extern InventoryData *Inventory; +extern uint16 NumInv, ManyRooms, HighestCondition; + +Resource *g_resource; + +Resource::Resource() { + readStaticText(); +} + +void Resource::readStaticText() { + Common::File labTextFile; + labTextFile.open(translateFileName("Lab:Rooms/LabText")); + + for (int i = 0; i < 48; i++) + _staticText[i] = labTextFile.readLine(); + + labTextFile.close(); +} + +TextFont *Resource::getFont(const char *fileName) { + Common::File *dataFile; + if (!(dataFile = openDataFile(fileName, MKTAG('V', 'G', 'A', 'F')))) + return NULL; + + uint32 headerSize = 4L + 2L + 256 * 3 + 4L; + uint32 fileSize = dataFile->size(); + if (fileSize <= headerSize) + return NULL; + + g_music->updateMusic(); + + TextFont *textfont = (TextFont *)malloc(sizeof(TextFont)); + textfont->DataLength = fileSize - headerSize; + textfont->Height = dataFile->readUint16LE(); + dataFile->read(textfont->Widths, 256); + for (int i = 0; i < 256; i++) + textfont->Offsets[i] = dataFile->readUint16LE(); + dataFile->skip(4); + // TODO: Fix memory leak!! + textfont->data = new byte[textfont->DataLength + 4]; + dataFile->read(textfont->data, textfont->DataLength); + return textfont; +} + +bool Resource::readRoomData(const char *fileName) { + Common::File *dataFile; + if (!(dataFile = openDataFile(fileName, MKTAG('D', 'O', 'R', '1')))) + return false; + + ManyRooms = dataFile->readUint16LE(); + HighestCondition = dataFile->readUint16LE(); + Rooms = (RoomData *)malloc((ManyRooms + 1) * sizeof(RoomData)); + memset(Rooms, 0, (ManyRooms + 1) * sizeof(RoomData)); + + for (uint16 i = 1; i <= ManyRooms; i++) { + Rooms[i].NorthDoor = dataFile->readUint16LE(); + Rooms[i].SouthDoor = dataFile->readUint16LE(); + Rooms[i].EastDoor = dataFile->readUint16LE(); + Rooms[i].WestDoor = dataFile->readUint16LE(); + Rooms[i].WipeType = dataFile->readByte(); + + Rooms[i].NorthView = NULL; + Rooms[i].SouthView = NULL; + Rooms[i].EastView = NULL; + Rooms[i].WestView = NULL; + Rooms[i].RuleList = NULL; + Rooms[i].RoomMsg = NULL; + } + + delete dataFile; + return true; +} + +bool Resource::readInventory(const char *fileName) { + Common::File *dataFile; + if (!(dataFile = openDataFile(fileName, MKTAG('I', 'N', 'V', '1')))) + return false; + + NumInv = dataFile->readUint16LE(); + Inventory = (InventoryData *)malloc((NumInv + 1) * sizeof(InventoryData)); + + for (uint16 i = 1; i <= NumInv; i++) { + Inventory[i].Many = dataFile->readUint16LE(); + Inventory[i].name = readString(dataFile); + Inventory[i].BInvName = readString(dataFile); + } + + delete dataFile; + return true; +} + +bool Resource::readViews(uint16 roomNum) { + Common::String fileName = "LAB:Rooms/" + Common::String::format("%d", roomNum); + Common::File *dataFile; + if (!(dataFile = openDataFile(fileName.c_str(), MKTAG('R', 'O', 'M', '4')))) + return false; + + allocroom = roomNum; + + Rooms[roomNum].RoomMsg = readString(dataFile); + Rooms[roomNum].NorthView = readView(dataFile); + Rooms[roomNum].SouthView = readView(dataFile); + Rooms[roomNum].EastView = readView(dataFile); + Rooms[roomNum].WestView = readView(dataFile); + Rooms[roomNum].RuleList = readRule(dataFile); + /*warning("Room %d, msg %s, north %s, south %s, east %s, west %s", + Rooms[roomNum].RoomMsg, + Rooms[roomNum].NorthView->GraphicName, + Rooms[roomNum].SouthView->GraphicName, + Rooms[roomNum].EastView->GraphicName, + Rooms[roomNum].WestView->GraphicName + );*/ + + g_music->updateMusic(); + + delete dataFile; + return true; +} + +Common::File *Resource::openDataFile(const char * fileName, uint32 fileHeader) { + Common::File *dataFile = new Common::File(); + dataFile->open(translateFileName(fileName)); + if (dataFile->readUint32BE() != fileHeader) { + dataFile->close(); + return NULL; + } + + return dataFile; +} + +char *Resource::readString(Common::File *file) { + byte size = file->readByte(); + if (!size) + return NULL; + char *str = (char *)malloc(size); + char *c = str; + for (int i = 0; i < size; i++) { + *c = file->readByte(); + if (*c != '\0') + *c -= 95; // decrypt char + c++; + } + *c = 0; + + return str; +} + +int16 *Resource::readConditions(Common::File *file) { + int16 i = 0, cond; + //int16 *list = new int16[25]; + int16 *list = (int16 *)malloc(25 * 2); + memset(list, 0, 25 * 2); + + do { + cond = file->readUint16LE(); + if (i < 25) + list[i++] = cond; + } while (cond); + + return list; +} + +Rule *Resource::readRule(Common::File *file) { + char c; + Rule *rule = NULL; + Rule *head = NULL; + + do { + c = file->readByte(); + + if (c == 1) { + rule = (Rule *)malloc(sizeof(Rule)); + rule->RuleType = file->readSint16LE(); + rule->Param1 = file->readSint16LE(); + rule->Param2 = file->readSint16LE(); + rule->Condition = readConditions(file); + if (!rule->Condition) + return NULL; + rule->ActionList = readAction(file); + rule->NextRule = NULL; + if (!head) + head = rule; + rule = rule->NextRule; + } + } while (c == 1); + + return head; +} + +Action *Resource::readAction(Common::File *file) { + char c; + Action *action = NULL; + Action *head = NULL; + char **messages; + + do { + c = file->readByte(); + + if (c == 1) { + action = (Action *)malloc(sizeof(Action)); + action->ActionType = file->readSint16LE(); + action->Param1 = file->readSint16LE(); + action->Param2 = file->readSint16LE(); + action->Param3 = file->readSint16LE(); + + if (action->ActionType == SHOWMESSAGES) { + messages = (char **)malloc(action->Param1 * 4); + + for (int i = 0; i < action->Param1; i++) + messages[i] = readString(file); + + action->Data = (byte *)messages; + } else { + action->Data = (byte *)readString(file); + } + + action->NextAction = NULL; + if (!head) + head = action; + action = action->NextAction; + } + } while (c == 1); + + return head; +} + +CloseData *Resource::readCloseUps(uint16 depth, Common::File *file) { + char c; + CloseData *closeups = NULL; + CloseData *head = NULL; + + do { + c = file->readByte(); + + if (c != '\0') { + closeups = (CloseData *)malloc(sizeof(CloseData)); + closeups->x1 = file->readUint16LE(); + closeups->y1 = file->readUint16LE(); + closeups->x2 = file->readUint16LE(); + closeups->y2 = file->readUint16LE(); + closeups->CloseUpType = file->readSint16LE(); + closeups->depth = depth; + closeups->GraphicName = readString(file); + closeups->Message = readString(file); + if (!(closeups->SubCloseUps = readCloseUps(depth + 1, file))) + return NULL; + closeups->NextCloseUp = NULL; + if (!head) + head = closeups; + closeups = closeups->NextCloseUp; + } + } while (c != '\0'); + + return head; +} + +viewData *Resource::readView(Common::File *file) { + char c; + viewData *view = NULL; + viewData *head = NULL; + + do { + c = file->readByte(); + + if (c == 1) { + view = (viewData *)malloc(sizeof(viewData)); + view->Condition = readConditions(file); + if (!view->Condition) + return NULL; + view->GraphicName = readString(file); + view->closeUps = readCloseUps(0, file); + view->NextCondition = NULL; + if (!head) + head = view; + view = view->NextCondition; + } + } while (c == 1); + + return head; +} + +} // End of namespace Lab |