2016-05-15 18:43:33 -04:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Disable symbol overrides so that we can use system headers.
|
|
|
|
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
|
|
|
|
|
|
|
// HACK to allow building with the SDL backend on MinGW
|
|
|
|
// see bug #1800764 "TOOLS: MinGW tools building broken"
|
|
|
|
#ifdef main
|
|
|
|
#undef main
|
|
|
|
#endif // main
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "common/language.h"
|
|
|
|
#include "common/rect.h"
|
|
|
|
#include "winexe_pe.h"
|
|
|
|
#include "file.h"
|
2016-07-29 21:57:19 -04:00
|
|
|
#include "script_preresponses.h"
|
2016-07-27 06:42:40 -04:00
|
|
|
#include "script_quotes.h"
|
2016-05-31 20:52:16 -04:00
|
|
|
#include "script_responses.h"
|
2016-06-06 08:51:37 -04:00
|
|
|
#include "script_ranges.h"
|
2016-07-28 21:03:02 -04:00
|
|
|
#include "script_states.h"
|
2016-06-09 22:14:29 -04:00
|
|
|
#include "tag_maps.h"
|
2016-05-15 18:43:33 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Format of the access.dat file that will be created:
|
|
|
|
* 4 Bytes - Magic string 'SVTN' to identify valid data file
|
|
|
|
* 2 bytes - Version number
|
|
|
|
*
|
|
|
|
* Following is a series of index entries with the following fields:
|
|
|
|
* 4 bytes - offset in file of entry
|
|
|
|
* 4 bytes - size of entry in the file
|
|
|
|
* ASCIIZ - name of the resource
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define VERSION_NUMBER 1
|
2016-07-31 17:16:23 -04:00
|
|
|
#define HEADER_SIZE 0xD00
|
2016-05-15 18:43:33 -04:00
|
|
|
|
|
|
|
Common::File inputFile, outputFile;
|
|
|
|
Common::PEResources res;
|
|
|
|
uint headerOffset = 6;
|
2016-05-15 23:15:24 -04:00
|
|
|
uint dataOffset = HEADER_SIZE;
|
2016-05-15 18:43:33 -04:00
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
#define ENGLISH_GOG_FILESIZE 4099072
|
|
|
|
#define ENGLISH_ORIG_FILESIZE 4095488
|
|
|
|
enum {
|
|
|
|
ENGLISH_ORIG_DIFF = 0x401400,
|
|
|
|
ENGLISH_GOG_DIFF = 0x401C00
|
|
|
|
};
|
|
|
|
enum Version {
|
|
|
|
ENGLISH_GOG = 0,
|
|
|
|
ENGLISH_ORIG = 1
|
|
|
|
};
|
|
|
|
Version _version;
|
|
|
|
|
|
|
|
const int FILE_DIFF[2] = { ENGLISH_GOG_DIFF, ENGLISH_ORIG_DIFF };
|
2016-06-08 19:15:15 -04:00
|
|
|
|
2016-05-15 23:15:24 -04:00
|
|
|
static const char *const ITEM_NAMES[46] = {
|
|
|
|
"LeftArmWith", "LeftArmWithout", "RightArmWith", "RightArmWithout", "BridgeRed",
|
|
|
|
"BridgeYellow", "BridgeBlue", "BridgeGreen", "Parrot", "CentralCore", "BrainGreen",
|
|
|
|
"BrainYellow", "BrainRed", "BrainBlue", "ChickenGreasy", "ChickenPlain", "ChickenPurple",
|
|
|
|
"ChickenRed", "ChickenYellow", "CrushedTV", "Ear", "Ear1", "Eyeball", "Eyeball1",
|
|
|
|
"Feather", "Lemon", "GlassEmpty", "GlassPurple", "GlassRed", "GlassYellow", "Hammer",
|
|
|
|
"Hose", "HoseEnd", "LiftHead", "LongStick", "Magazine", "Mouth", "MusicKey", "Napkin",
|
|
|
|
"Nose", "Perch", "PhonoCylinder", "PhonoCylinder1", "PhonoCylinder2", "PhonoCylinder3",
|
|
|
|
"Photo"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *const ITEM_DESCRIPTIONS[46] = {
|
|
|
|
"The Maitre d'Bot's left arm holding a key", "The Maitre d'Bot's left arm",
|
|
|
|
"The Maitre d'Bot's right arm holding Titania's auditory center",
|
|
|
|
"The Maitre d'Bot's right arm", "Red Fuse", "Yellow Fuse", "Blue Fuse",
|
|
|
|
"Green Fuse", "The Parrot", "Titania's central intelligence core",
|
|
|
|
"Titania's auditory center", "Titania's olfactory center",
|
|
|
|
"Titania's speech center", "Titania's vision center", "rather greasy chicken",
|
|
|
|
"very plain chicken", "chicken smeared with starling pur$e",
|
|
|
|
"chicken covered with tomato sauce", "chicken coated in mustard sauce",
|
|
|
|
"A crushed television set", "Titania's ear", "Titania's ear", "Titania's eye",
|
|
|
|
"Titania's eye", "A parrot feather", "A nice fat juicy lemon",
|
|
|
|
"An empty beer glass", "A beer glass containing pur$ed flock of starlings",
|
|
|
|
"A beer glass containing tomato sauce", "A beer glass containing mustard sauce",
|
|
|
|
"A hammer", "A hose", "The other end of a hose", "The LiftBot's head",
|
|
|
|
"A rather long stick", "A magazine", "Titania's mouth", "A key",
|
|
|
|
"A super-absorbent napkin", "Titania's nose", "A perch", "A phonograph cylinder",
|
|
|
|
"A phonograph cylinder", "A phonograph cylinder", "A phonograph cylinder",
|
|
|
|
"A photograph"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *const ITEM_IDS[40] = {
|
|
|
|
"MaitreD Left Arm", "MaitreD Right Arm", "OlfactoryCentre", "AuditoryCentre",
|
|
|
|
"SpeechCentre", "VisionCentre", "CentralCore", "Perch", "SeasonBridge",
|
|
|
|
"FanBridge", "BeamBridge", "ChickenBridge", "CarryParrot", "Chicken",
|
|
|
|
"CrushedTV", "Feathers", "Lemon", "BeerGlass", "BigHammer", "Ear1", "Ear 2",
|
|
|
|
"Eye1", "Eye2", "Mouth", "Nose", "NoseSpare", "Hose", "DeadHoseSpare",
|
|
|
|
"HoseEnd", "DeadHoseEndSpare", "BrokenLiftbotHead", "LongStick", "Magazine",
|
|
|
|
"Napkin", "Phonograph Cylinder", "Phonograph Cylinder 1", "Phonograph Cylinder 2",
|
|
|
|
"Phonograph Cylinder 3", "Photograph", "Music System Key"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *const ROOM_NAMES[34] = {
|
|
|
|
"1stClassLobby", "1stClassRestaurant", "1stClassState",
|
|
|
|
"2ndClassLobby", "secClassState", "Arboretum", "FrozenArboretum",
|
|
|
|
"Bar", "BilgeRoom", "BilgeRoomWith", "BottomOfWell", "Bridge",
|
|
|
|
"CreatorsChamber", "CreatorsChamberOn", "Dome", "Home", "Lift",
|
|
|
|
"EmbLobby", "MoonEmbLobby", "MusicRoomLobby", "MusicRoom",
|
|
|
|
"ParrotLobby", "Pellerator", "PromenadeDeck", "SculptureChamber",
|
|
|
|
"SecClassLittleLift", "ServiceElevator", "SGTLeisure", "SGTLittleLift",
|
|
|
|
"SgtLobby", "SGTState", "Titania", "TopOfWell", "PlayersRoom"
|
|
|
|
};
|
|
|
|
|
2016-05-16 19:59:09 -04:00
|
|
|
struct NumberEntry {
|
|
|
|
const char *_text;
|
|
|
|
int _value;
|
|
|
|
uint _flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
const NumberEntry NUMBERS[76] = {
|
|
|
|
{ "a", 1, 3 },
|
|
|
|
{ "and", 0, 1 },
|
|
|
|
{ "negative", 0, 10 },
|
|
|
|
{ "minus", 0, 10 },
|
|
|
|
{ "below zeor", 0, 8 },
|
|
|
|
{ "degrees below zero", 0, 8 },
|
|
|
|
{ "nil", 0, 2 },
|
|
|
|
{ "zero", 0, 2 },
|
|
|
|
{ "one", 1, 0x12 },
|
|
|
|
{ "two", 2, 0x12 },
|
|
|
|
{ "three", 3, 0x12 },
|
|
|
|
{ "four", 4, 0x12 },
|
|
|
|
{ "five", 5, 0x12 },
|
|
|
|
{ "six", 6, 0x12 },
|
|
|
|
{ "seven", 7, 0x12 },
|
|
|
|
{ "eight", 8, 0x12 },
|
|
|
|
{ "nine", 9, 0x12 },
|
|
|
|
{ "0", 0, 2 },
|
|
|
|
{ "1", 1, 2 },
|
|
|
|
{ "2", 2, 2 },
|
|
|
|
{ "3", 3, 2 },
|
|
|
|
{ "4", 4, 2 },
|
|
|
|
{ "5", 5, 2 },
|
|
|
|
{ "6", 6, 2 },
|
|
|
|
{ "7", 7, 2 },
|
|
|
|
{ "8", 8, 2 },
|
|
|
|
{ "9", 9, 2 },
|
|
|
|
{ "first", 1, 2 },
|
|
|
|
{ "second", 2, 2 },
|
|
|
|
{ "third", 3, 2 },
|
|
|
|
{ "fourth", 4, 2 },
|
|
|
|
{ "fifth", 5, 2 },
|
|
|
|
{ "sixth", 6, 2 },
|
|
|
|
{ "seventh", 7, 2 },
|
|
|
|
{ "eighth", 8, 2 },
|
|
|
|
{ "ninth", 9, 2 },
|
|
|
|
{ "ten", 10, 2 },
|
|
|
|
{ "eleven", 11, 2 },
|
|
|
|
{ "twelve", 12, 2 },
|
|
|
|
{ "thirteen", 13, 2 },
|
|
|
|
{ "fourteen", 14, 2 },
|
|
|
|
{ "fifteen", 15, 2 },
|
|
|
|
{ "sixteen", 16, 2 },
|
|
|
|
{ "seventeen", 17, 2 },
|
|
|
|
{ "eighteen", 18, 2 },
|
|
|
|
{ "nineteen", 19, 2 },
|
|
|
|
{ "tenth", 10, 2 },
|
|
|
|
{ "eleventh", 11, 2 },
|
|
|
|
{ "twelfth", 12, 2 },
|
|
|
|
{ "thirteenth", 13, 2 },
|
|
|
|
{ "fourteenth", 14, 2 },
|
|
|
|
{ "fifteenth", 15, 2 },
|
|
|
|
{ "sixteenth", 16, 2 },
|
|
|
|
{ "seventeenth", 17, 2 },
|
|
|
|
{ "eighteenth", 18, 2 },
|
|
|
|
{ "nineteenth", 19, 2 },
|
|
|
|
{ "twenty", 20, 0x12 },
|
|
|
|
{ "thirty", 30, 0x12 },
|
|
|
|
{ "forty", 40, 0x12 },
|
|
|
|
{ "fourty", 40, 0x12 },
|
|
|
|
{ "fifty", 50, 0x12 },
|
|
|
|
{ "sixty", 60, 0x12 },
|
|
|
|
{ "seventy", 70, 0x12 },
|
|
|
|
{ "eighty", 80, 0x12 },
|
|
|
|
{ "ninety", 90, 0x12 },
|
|
|
|
{ "twentieth", 20, 2 },
|
|
|
|
{ "thirtieth", 30, 2 },
|
|
|
|
{ "fortieth", 40, 2 },
|
|
|
|
{ "fiftieth", 50, 2 },
|
|
|
|
{ "sixtieth", 60, 2 },
|
|
|
|
{ "seventieth", 70, 2 },
|
|
|
|
{ "eightieth", 80, 2 },
|
|
|
|
{ "ninetieth", 90, 2 },
|
|
|
|
{ "hundred", 100, 4 },
|
|
|
|
{ "hundredth", 100, 6 }
|
|
|
|
};
|
|
|
|
|
2016-07-30 23:28:03 -04:00
|
|
|
struct CommonPhrase {
|
|
|
|
const char *_str;
|
|
|
|
uint _dialogueId;
|
|
|
|
uint _roomNum;
|
|
|
|
uint _val1;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const CommonPhrase BELLBOT_COMMON_PHRASES[] = {
|
|
|
|
{ "what is wrong with her", 0x30FF9, 0x7B, 0 },
|
|
|
|
{ "what is wrong with titania", 0x30FF9, 0x7B, 0 },
|
|
|
|
{ "something for the weekend", 0x30D8B, 0x00, 0 },
|
|
|
|
{ "other food", 0x30E1D, 0x00, 3 },
|
|
|
|
{ "different food", 0x30E1D, 0x00, 3 },
|
|
|
|
{ "alternative food", 0x30E1D, 0x00, 3 },
|
|
|
|
{ "decent food", 0x30E1D, 0x00, 3 },
|
|
|
|
{ "nice food", 0x30E1D, 0x00, 3 },
|
|
|
|
{ "nicer food", 0x30E1D, 0x00, 3 },
|
|
|
|
{ "make me happy", 0x31011, 0x00, 0 },
|
|
|
|
{ "cheer me up", 0x31011, 0x00, 0 },
|
|
|
|
{ "help me if im unhappy", 0x31011, 0x00, 0 },
|
|
|
|
{ "i obtain a better room", 0x30E8A, 0x00, 3 },
|
|
|
|
{ "i obtain a better room", 0x30E8A, 0x00, 2 },
|
|
|
|
{ "i get a better room", 0x30E8A, 0x00, 3 },
|
|
|
|
{ "i get a better room", 0x30E8A, 0x00, 2 },
|
|
|
|
{ "i want a better room", 0x30E8A, 0x00, 3 },
|
|
|
|
{ "i want a better room", 0x30E8A, 0x00, 2 },
|
|
|
|
{ "i understood", 0x30D75, 0x6D, 0 },
|
|
|
|
{ "i knew", 0x30D75, 0x6D, 0 },
|
|
|
|
{ "i know", 0x30D75, 0x6D, 0 },
|
|
|
|
{ "not stupid", 0x30D75, 0x6D, 0 },
|
|
|
|
{ "cheeky", 0x30D75, 0x6D, 0 },
|
|
|
|
{ "not help", 0x30D6F, 0x6D, 0 },
|
|
|
|
{ "not helpful", 0x30D6F, 0x6D, 0 },
|
|
|
|
{ "dont help", 0x30D6F, 0x6D, 0 },
|
|
|
|
{ "no help", 0x30D6F, 0x6D, 0 },
|
|
|
|
{ "sorry", 0x30D76, 0x6D, 0 },
|
|
|
|
{ "not mean that", 0x30D76, 0x6D, 0 },
|
|
|
|
{ "didnt mean that", 0x30D76, 0x6D, 0 },
|
|
|
|
{ "apologise", 0x30D76, 0x6D, 0 },
|
|
|
|
{ "play golf", 0x313B6, 0x00, 0 },
|
|
|
|
{ "is not the captain meant to go down with the ship", 0x31482, 0x00, 0 },
|
|
|
|
{ "is not the captain supposed to go down with the ship", 0x31482, 0x00, 0 },
|
|
|
|
{ "sauce sticks to the chicken", 0x3156B, 0x00, 0 },
|
|
|
|
{ "sauce gets stuck to the chicken", 0x3156B, 0x00, 0 },
|
|
|
|
{ nullptr, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
2016-08-13 15:09:49 -04:00
|
|
|
struct FrameRange {
|
|
|
|
int _startFrame;
|
|
|
|
int _endFrame;
|
|
|
|
};
|
|
|
|
|
|
|
|
static const FrameRange BARBOT_FRAME_RANGES[60] = {
|
|
|
|
{ 558, 585 }, { 659, 692 }, { 802, 816 }, { 1941, 1977 }, { 1901, 1941 },
|
|
|
|
{ 810, 816 }, { 857, 865}, { 842, 857 }, { 821, 842 }, { 682, 692 },
|
|
|
|
{ 1977, 2018 }, { 2140, 2170 }, { 2101, 2139 }, { 2018, 2099}, { 1902, 2015 },
|
|
|
|
{ 1811, 1901 }, { 1751, 1810 }, { 1703, 1750 }, { 1681, 1702 }, { 1642, 1702 },
|
|
|
|
{ 1571, 1641 }, { 1499, 1570 }, { 1403, 1463 }, { 1464, 1499 }, { 1288, 1295 },
|
|
|
|
{ 1266, 1287 }, { 1245, 1265 }, { 1208, 1244 }, { 1171, 1207 }, { 1120, 1170 },
|
|
|
|
{ 1092, 1120 }, { 1092, 1092 }, { 1044, 1091 }, { 1011, 1043 }, { 1001, 1010 },
|
|
|
|
{ 985, 1001 }, { 927, 984 }, { 912, 926 }, { 898, 906 }, { 802, 896 },
|
|
|
|
{ 865, 896 }, { 842, 865 }, { 816, 842 }, { 802, 842 }, { 740, 801 },
|
|
|
|
{ 692, 740 }, { 610, 692 }, { 558, 610 }, { 500, 558 }, { 467, 500 },
|
|
|
|
{ 421, 466 }, { 349, 420 }, { 306, 348 }, { 305, 306 }, { 281, 305 },
|
|
|
|
{ 202, 281 }, { 182, 202 }, { 165, 182 }, { 96, 165 }, { 0, 95 }
|
|
|
|
};
|
2016-07-30 23:28:03 -04:00
|
|
|
|
2016-05-15 18:43:33 -04:00
|
|
|
void NORETURN_PRE error(const char *s, ...) {
|
|
|
|
printf("%s\n", s);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeEntryHeader(const char *name, uint offset, uint size) {
|
2016-05-15 23:15:24 -04:00
|
|
|
assert(headerOffset < HEADER_SIZE);
|
2016-05-15 18:43:33 -04:00
|
|
|
outputFile.seek(headerOffset);
|
|
|
|
outputFile.writeLong(offset);
|
|
|
|
outputFile.writeLong(size);
|
|
|
|
outputFile.writeString(name);
|
|
|
|
|
|
|
|
headerOffset += 8 + strlen(name) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeFinalEntryHeader() {
|
2016-05-15 23:15:24 -04:00
|
|
|
assert(headerOffset <= (HEADER_SIZE - 8));
|
2016-05-15 18:43:33 -04:00
|
|
|
outputFile.seek(headerOffset);
|
|
|
|
outputFile.writeLong(0);
|
|
|
|
outputFile.writeLong(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeStringArray(const char *name, uint offset, int count) {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
|
|
|
inputFile.seek(offset);
|
|
|
|
uint *offsets = new uint[count];
|
|
|
|
for (int idx = 0; idx < count; ++idx)
|
|
|
|
offsets[idx] = inputFile.readLong();
|
|
|
|
|
|
|
|
// Iterate through reading each string
|
|
|
|
for (int idx = 0; idx < count; ++idx) {
|
|
|
|
if (offsets[idx]) {
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(offsets[idx] - FILE_DIFF[_version]);
|
2016-05-15 18:43:33 -04:00
|
|
|
outputFile.writeString(inputFile);
|
|
|
|
} else {
|
|
|
|
outputFile.writeString("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader(name, dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
|
|
|
|
delete[] offsets;
|
|
|
|
}
|
|
|
|
|
2016-05-15 23:15:24 -04:00
|
|
|
void writeStringArray(const char *name, const char *const *strings, int count) {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
|
|
|
// Iterate through writing each string
|
|
|
|
for (int idx = 0; idx < count; ++idx) {
|
|
|
|
outputFile.writeString(strings[idx]);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader(name, dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-05-15 18:43:33 -04:00
|
|
|
Common::WinResourceID getResId(uint id) {
|
|
|
|
return Common::WinResourceID(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::WinResourceID getResId(const char *id) {
|
|
|
|
if (!strcmp(id, "Bitmap"))
|
|
|
|
return Common::WinResourceID(2);
|
|
|
|
|
|
|
|
return Common::WinResourceID(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeResource(const char *name, Common::File *file) {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
outputFile.write(*file, file->size());
|
|
|
|
|
|
|
|
writeEntryHeader(name, dataOffset, file->size());
|
|
|
|
dataOffset += file->size();
|
|
|
|
delete file;
|
|
|
|
}
|
|
|
|
|
2016-07-22 21:44:50 -04:00
|
|
|
void writeResource(const char *sectionStr, uint32 resId) {
|
2016-05-15 18:43:33 -04:00
|
|
|
char nameBuffer[256];
|
2016-07-22 21:44:50 -04:00
|
|
|
sprintf(nameBuffer, "%s/%u", sectionStr, resId);
|
2016-05-15 18:43:33 -04:00
|
|
|
|
|
|
|
Common::File *file = res.getResource(getResId(sectionStr), resId);
|
|
|
|
assert(file);
|
|
|
|
writeResource(nameBuffer, file);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeResource(const char *sectionStr, const char *resId) {
|
|
|
|
char nameBuffer[256];
|
|
|
|
sprintf(nameBuffer, "%s/%s", sectionStr, resId);
|
|
|
|
|
|
|
|
Common::File *file = res.getResource(getResId(sectionStr),
|
|
|
|
Common::WinResourceID(resId));
|
|
|
|
assert(file);
|
|
|
|
writeResource(nameBuffer, file);
|
|
|
|
}
|
|
|
|
|
2016-07-22 21:44:50 -04:00
|
|
|
void writeBitmap(const char *name, Common::File *file) {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
|
|
|
// Write out the necessary bitmap header so that the ScummVM
|
|
|
|
// BMP decoder can properly handle decoding the bitmaps
|
|
|
|
outputFile.write("BM", 2);
|
|
|
|
outputFile.writeLong(file->size() + 14); // Filesize
|
|
|
|
outputFile.writeLong(0); // res1 & res2
|
|
|
|
outputFile.writeLong(0x436); // image offset
|
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
outputFile.write(*file, file->size());
|
2016-07-22 21:44:50 -04:00
|
|
|
|
|
|
|
writeEntryHeader(name, dataOffset, file->size() + 14);
|
|
|
|
dataOffset += file->size() + 14;
|
|
|
|
delete file;
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeBitmap(const char *sectionStr, const char *resId) {
|
|
|
|
char nameBuffer[256];
|
|
|
|
sprintf(nameBuffer, "%s/%s", sectionStr, resId);
|
|
|
|
|
|
|
|
Common::File *file = res.getResource(getResId(sectionStr),
|
|
|
|
Common::WinResourceID(resId));
|
|
|
|
assert(file);
|
|
|
|
writeBitmap(nameBuffer, file);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeBitmap(const char *sectionStr, uint32 resId) {
|
|
|
|
char nameBuffer[256];
|
|
|
|
sprintf(nameBuffer, "%s/%u", sectionStr, resId);
|
|
|
|
|
|
|
|
Common::File *file = res.getResource(getResId(sectionStr),
|
|
|
|
Common::WinResourceID(resId));
|
|
|
|
assert(file);
|
|
|
|
writeBitmap(nameBuffer, file);
|
|
|
|
}
|
|
|
|
|
2016-05-16 19:59:09 -04:00
|
|
|
void writeNumbers() {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
|
|
|
// Iterate through writing each string
|
|
|
|
for (int idx = 0; idx < 76; ++idx) {
|
|
|
|
outputFile.writeString(NUMBERS[idx]._text);
|
|
|
|
outputFile.writeLong(NUMBERS[idx]._value);
|
|
|
|
outputFile.writeLong(NUMBERS[idx]._flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader("TEXT/NUMBERS", dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-06-07 22:33:51 -04:00
|
|
|
void writeString(uint offset) {
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(offset - FILE_DIFF[_version]);
|
2016-06-07 22:33:51 -04:00
|
|
|
char c;
|
|
|
|
do {
|
|
|
|
c = inputFile.readByte();
|
|
|
|
outputFile.writeByte(c);
|
|
|
|
} while (c);
|
|
|
|
}
|
|
|
|
|
2016-06-04 17:24:38 -04:00
|
|
|
void writeResponseTree() {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
const int OFFSETS[2] = { 0x619520, 0x618340 };
|
2016-06-04 17:24:38 -04:00
|
|
|
for (int idx = 0; idx < 1022; ++idx) {
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(OFFSETS[_version] - FILE_DIFF[_version] + idx * 8);
|
2016-06-04 17:24:38 -04:00
|
|
|
uint id = inputFile.readLong();
|
|
|
|
uint offset = inputFile.readLong();
|
|
|
|
|
|
|
|
outputFile.writeLong(id);
|
|
|
|
if (!id) {
|
|
|
|
// An end of list id
|
2016-08-20 21:52:19 -04:00
|
|
|
} else if (offset >= OFFSETS[_version] && offset <= (OFFSETS[_version] + 0x1FF0)) {
|
2016-06-04 17:24:38 -04:00
|
|
|
// Offset to another table
|
|
|
|
outputFile.writeByte(0);
|
2016-08-20 21:52:19 -04:00
|
|
|
outputFile.writeLong((offset - OFFSETS[_version]) / 8);
|
2016-06-04 17:24:38 -04:00
|
|
|
} else {
|
|
|
|
// Offset to ASCIIZ string
|
|
|
|
outputFile.writeByte(1);
|
2016-06-07 22:33:51 -04:00
|
|
|
writeString(offset);
|
2016-06-04 17:24:38 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader("TEXT/TREE", dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-06-07 22:33:51 -04:00
|
|
|
void writeSentenceEntries(const char *name, uint tableOffset) {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
|
|
|
uint v1, v2, v4, v9, v11, v12, v13;
|
|
|
|
uint offset3, offset5, offset6, offset7, offset8, offset10;
|
|
|
|
|
|
|
|
for (uint idx = 0; ; ++idx) {
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(tableOffset - FILE_DIFF[_version] + idx * 0x34);
|
2016-06-07 22:33:51 -04:00
|
|
|
v1 = inputFile.readLong();
|
|
|
|
if (!v1)
|
|
|
|
// Reached end of list
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Read data fields
|
|
|
|
v2 = inputFile.readLong();
|
|
|
|
offset3 = inputFile.readLong();
|
|
|
|
v4 = inputFile.readLong();
|
|
|
|
offset5 = inputFile.readLong();
|
|
|
|
offset6 = inputFile.readLong();
|
|
|
|
offset7 = inputFile.readLong();
|
|
|
|
offset8 = inputFile.readLong();
|
|
|
|
v9 = inputFile.readLong();
|
|
|
|
offset10 = inputFile.readLong();
|
|
|
|
v11 = inputFile.readLong();
|
|
|
|
v12 = inputFile.readLong();
|
|
|
|
v13 = inputFile.readLong();
|
|
|
|
|
|
|
|
outputFile.writeLong(v1);
|
|
|
|
outputFile.writeLong(v2);
|
|
|
|
writeString(offset3);
|
|
|
|
outputFile.writeLong(v1);
|
|
|
|
writeString(offset5);
|
|
|
|
writeString(offset6);
|
|
|
|
writeString(offset7);
|
|
|
|
writeString(offset8);
|
|
|
|
outputFile.writeLong(v9);
|
|
|
|
writeString(offset10);
|
|
|
|
outputFile.writeLong(v11);
|
|
|
|
outputFile.writeLong(v12);
|
|
|
|
outputFile.writeLong(v13);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
2016-06-08 22:00:36 -04:00
|
|
|
writeEntryHeader(name, dataOffset, size);
|
2016-06-07 22:33:51 -04:00
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-07-24 23:08:19 -04:00
|
|
|
void writeWords(const char *name, uint tableOffset, int recordCount = 2) {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
int recordSize = recordCount * 4;
|
|
|
|
|
|
|
|
uint val, strOffset;
|
|
|
|
for (uint idx = 0; ; ++idx) {
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(tableOffset - FILE_DIFF[_version] + idx * recordSize);
|
2016-07-24 23:08:19 -04:00
|
|
|
val = inputFile.readLong();
|
|
|
|
strOffset = inputFile.readLong();
|
|
|
|
|
|
|
|
if (!val)
|
|
|
|
// Reached end of list
|
|
|
|
break;
|
|
|
|
|
|
|
|
outputFile.writeLong(val);
|
|
|
|
writeString(strOffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader(name, dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-06-08 19:15:15 -04:00
|
|
|
void writeSentenceMappings(const char *name, uint offset, int numValues) {
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(offset - FILE_DIFF[_version]);
|
2016-06-08 19:15:15 -04:00
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
|
|
|
uint id;
|
|
|
|
while ((id = inputFile.readLong()) != 0) {
|
|
|
|
outputFile.writeLong(id);
|
|
|
|
|
|
|
|
for (int ctr = 0; ctr < numValues; ++ctr)
|
|
|
|
outputFile.writeLong(inputFile.readLong());
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader(name, dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-07-02 19:48:40 -04:00
|
|
|
void writeStarfieldPoints() {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
const int OFFSETS[2] = { 0x59DE4C, 0x59DBEC };
|
|
|
|
inputFile.seek(OFFSETS[_version] - FILE_DIFF[_version]);
|
2016-07-02 19:48:40 -04:00
|
|
|
uint size = 876 * 12;
|
|
|
|
|
|
|
|
outputFile.write(inputFile, size);
|
|
|
|
writeEntryHeader("STARFIELD/POINTS", dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-07-03 11:28:26 -04:00
|
|
|
void writeStarfieldPoints2() {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
const int OFFSETS[2] = { 0x5A2F28, 0x5A2CC8 };
|
2016-07-03 11:28:26 -04:00
|
|
|
for (int rootCtr = 0; rootCtr < 80; ++rootCtr) {
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(OFFSETS[_version] - FILE_DIFF[_version] + rootCtr * 8);
|
2016-07-03 11:28:26 -04:00
|
|
|
uint offset = inputFile.readUint32LE();
|
|
|
|
uint count = inputFile.readUint32LE();
|
|
|
|
|
|
|
|
outputFile.writeLong(count);
|
2016-08-20 21:52:19 -04:00
|
|
|
inputFile.seek(offset - FILE_DIFF[_version]);
|
2016-07-03 11:28:26 -04:00
|
|
|
outputFile.write(inputFile, count * 4 * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
outputFile.write(inputFile, size);
|
|
|
|
writeEntryHeader("STARFIELD/POINTS2", dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-07-30 23:28:03 -04:00
|
|
|
void writePhrases(const char *name, const CommonPhrase *phrases) {
|
|
|
|
for (uint idx = 0; phrases->_str; ++idx, ++phrases) {
|
|
|
|
outputFile.seek(dataOffset + idx * 4);
|
|
|
|
outputFile.writeString(phrases->_str);
|
|
|
|
outputFile.writeLong(phrases->_dialogueId);
|
|
|
|
outputFile.writeLong(phrases->_roomNum);
|
|
|
|
outputFile.writeLong(phrases->_val1);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader("Phrases/Bellbot", dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-08-13 15:09:49 -04:00
|
|
|
void writeBarbotFrameRanges() {
|
|
|
|
outputFile.seek(dataOffset);
|
|
|
|
|
|
|
|
for (int idx = 0; idx < 60; ++idx) {
|
|
|
|
outputFile.writeLong(BARBOT_FRAME_RANGES[idx]._startFrame);
|
|
|
|
outputFile.writeLong(BARBOT_FRAME_RANGES[idx]._endFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint size = outputFile.size() - dataOffset;
|
|
|
|
writeEntryHeader("FRAMES/BARBOT", dataOffset, size);
|
|
|
|
dataOffset += size;
|
|
|
|
}
|
|
|
|
|
2016-05-15 18:43:33 -04:00
|
|
|
void writeHeader() {
|
|
|
|
// Write out magic string
|
|
|
|
const char *MAGIC_STR = "SVTN";
|
|
|
|
outputFile.write(MAGIC_STR, 4);
|
|
|
|
|
|
|
|
// Write out version number
|
|
|
|
outputFile.writeWord(VERSION_NUMBER);
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeData() {
|
2016-07-22 21:44:50 -04:00
|
|
|
writeBitmap("Bitmap", "BACKDROP");
|
|
|
|
writeBitmap("Bitmap", "EVILTWIN");
|
|
|
|
writeBitmap("Bitmap", "RESTORED");
|
|
|
|
writeBitmap("Bitmap", "RESTOREF");
|
|
|
|
writeBitmap("Bitmap", "RESTOREU");
|
|
|
|
writeBitmap("Bitmap", "STARTD");
|
|
|
|
writeBitmap("Bitmap", "STARTF");
|
|
|
|
writeBitmap("Bitmap", "STARTU");
|
|
|
|
writeBitmap("Bitmap", "TITANIC");
|
|
|
|
writeBitmap("Bitmap", 133);
|
|
|
|
writeBitmap("Bitmap", 164);
|
|
|
|
writeBitmap("Bitmap", 165);
|
2016-05-15 18:43:33 -04:00
|
|
|
|
|
|
|
writeResource("STFONT", 149);
|
|
|
|
writeResource("STFONT", 151);
|
|
|
|
writeResource("STFONT", 152);
|
|
|
|
writeResource("STFONT", 153);
|
|
|
|
|
2016-06-04 17:24:38 -04:00
|
|
|
writeResource("STARFIELD", 132);
|
2016-07-02 19:48:40 -04:00
|
|
|
writeStarfieldPoints();
|
2016-07-03 11:28:26 -04:00
|
|
|
writeStarfieldPoints2();
|
2016-06-04 17:24:38 -04:00
|
|
|
|
2016-05-15 18:43:33 -04:00
|
|
|
writeResource("TEXT", "STVOCAB.TXT");
|
|
|
|
writeResource("TEXT", "JRQUOTES.TXT");
|
|
|
|
writeResource("TEXT", 155);
|
2016-05-16 19:59:09 -04:00
|
|
|
|
|
|
|
writeStringArray("TEXT/ITEM_DESCRIPTIONS", ITEM_DESCRIPTIONS, 46);
|
|
|
|
writeStringArray("TEXT/ITEM_NAMES", ITEM_NAMES, 46);
|
|
|
|
writeStringArray("TEXT/ITEM_IDS", ITEM_IDS, 40);
|
|
|
|
writeStringArray("TEXT/ROOM_NAMES", ROOM_NAMES, 34);
|
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
const int TEXT_PHRASES[2] = { 0x21B7C8, 0x21ADA0 };
|
|
|
|
const int TEXT_REPLACEMENTS1[2] = { 0x21BDB0, 0x21B388 };
|
|
|
|
const int TEXT_REPLACEMENTS2[2] = { 0x21C120, 0x21B6F8 };
|
|
|
|
const int TEXT_REPLACEMENTS3[2] = { 0x21D9C8, 0x21CFA0 };
|
|
|
|
const int TEXT_PRONOUNS[2] = { 0x22F718, 0x22ECF8 };
|
|
|
|
writeStringArray("TEXT/PHRASES", TEXT_PHRASES[_version], 376);
|
|
|
|
writeStringArray("TEXT/REPLACEMENTS1", TEXT_REPLACEMENTS1[_version], 218);
|
|
|
|
writeStringArray("TEXT/REPLACEMENTS2", TEXT_REPLACEMENTS2[_version], 1576);
|
|
|
|
writeStringArray("TEXT/REPLACEMENTS3", TEXT_REPLACEMENTS3[_version], 82);
|
|
|
|
writeStringArray("TEXT/PRONOUNS", TEXT_PRONOUNS[_version], 15);
|
|
|
|
|
|
|
|
const int SENTENCES_DEFAULT[2] = { 0x5C0130, 0x5BEFC8 };
|
|
|
|
const int SENTENCES_BARBOT[2][2] = { { 0x5ABE60, 0x5AACF8 }, { 0x5BD4E8, 0x5BC380 } };
|
|
|
|
const int SENTENCES_BELLBOT[21][2] = {
|
|
|
|
{ 0x5C2230, 0x5C10C8 }, { 0x5D1670, 0x5D0508 }, { 0x5D1A80, 0x5D0918 },
|
|
|
|
{ 0x5D1AE8, 0x5D0980 }, { 0x5D1B88, 0x5D0A20 }, { 0x5D2A60, 0x5D18F8 },
|
|
|
|
{ 0x5D2CD0, 0x5D1B68 }, { 0x5D3488, 0x5D2320 }, { 0x5D3900, 0x5D2798 },
|
|
|
|
{ 0x5D3968, 0x5D2800 }, { 0x5D4668, 0x5D3500 }, { 0x5D47A0, 0x5D3638 },
|
|
|
|
{ 0x5D4EC0, 0x5D3D58 }, { 0x5D5100, 0x5D3F98 }, { 0x5D5370, 0x5D4208 },
|
|
|
|
{ 0x5D5548, 0x5D43E0 }, { 0x5D56B8, 0x5D4550 }, { 0x5D57C0, 0x5D4658 },
|
|
|
|
{ 0x5D5B38, 0x5D49D0 }, { 0x5D61B8, 0x5D5050 }
|
|
|
|
};
|
|
|
|
writeSentenceEntries("Sentences/Default", SENTENCES_DEFAULT[_version]);
|
|
|
|
writeSentenceEntries("Sentences/Barbot", SENTENCES_BARBOT[0][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Barbot2", SENTENCES_BARBOT[1][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot", SENTENCES_BELLBOT[0][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/1", SENTENCES_BELLBOT[1][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/2", SENTENCES_BELLBOT[2][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/3", SENTENCES_BELLBOT[3][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/4", SENTENCES_BELLBOT[4][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/5", SENTENCES_BELLBOT[5][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/6", SENTENCES_BELLBOT[6][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/7", SENTENCES_BELLBOT[7][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/8", SENTENCES_BELLBOT[8][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/9", SENTENCES_BELLBOT[9][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/10", SENTENCES_BELLBOT[10][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/11", SENTENCES_BELLBOT[11][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/12", SENTENCES_BELLBOT[12][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/13", SENTENCES_BELLBOT[13][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/14", SENTENCES_BELLBOT[14][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/15", SENTENCES_BELLBOT[15][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/16", SENTENCES_BELLBOT[16][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/17", SENTENCES_BELLBOT[17][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/18", SENTENCES_BELLBOT[18][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Bellbot/19", SENTENCES_BELLBOT[19][_version]);
|
|
|
|
|
|
|
|
const int SENTENCES_DESKBOT[3][2] = {
|
|
|
|
{ 0x5DCD10, 0x5DBBA8 }, { 0x5E8E18, 0x5E7CB0 }, { 0x5E8BA8, 0x5E7A40 }
|
|
|
|
};
|
|
|
|
writeSentenceEntries("Sentences/Deskbot", SENTENCES_DESKBOT[0][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Deskbot/2", SENTENCES_DESKBOT[1][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Deskbot/3", SENTENCES_DESKBOT[2][_version]);
|
2016-07-31 17:16:23 -04:00
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
const int SENTENCES_DOORBOT[12][2] = {
|
|
|
|
{ 0x5EC110, 0x5EAFA8 }, { 0x5FD930, 0x5FC7C8 }, { 0x5FDD0C, 0x5FCBA4 },
|
|
|
|
{ 0x5FE668, 0x5FD500 }, { 0x5FDD40, 0x5FCBD8 }, { 0x5FFF08, 0x5FEDA0 },
|
|
|
|
{ 0x5FE3C0, 0x5FD258 }, { 0x5FF0C8, 0x5FDF60 }, { 0x5FF780, 0x5FE618 },
|
|
|
|
{ 0x5FFAC0, 0x5FE958 }, { 0x5FFC30, 0x5FEAC8 }, { 0x6000E0, 0x5FEF78 }
|
|
|
|
};
|
|
|
|
writeSentenceEntries("Sentences/Doorbot", SENTENCES_DOORBOT[0][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/2", SENTENCES_DOORBOT[1][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/100", SENTENCES_DOORBOT[2][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/101", SENTENCES_DOORBOT[3][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/102", SENTENCES_DOORBOT[4][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/107", SENTENCES_DOORBOT[5][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/110", SENTENCES_DOORBOT[6][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/111", SENTENCES_DOORBOT[7][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/124", SENTENCES_DOORBOT[8][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/129", SENTENCES_DOORBOT[9][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/131", SENTENCES_DOORBOT[10][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Doorbot/132", SENTENCES_DOORBOT[11][_version]);
|
|
|
|
|
|
|
|
const int SENTENCES_LIFTBOT[2] = { 0x6026B0, 0x601548 };
|
|
|
|
const int SENTENCES_MAITRED[2][2] = { { 0x60CFD8, 0x60BE70 }, { 0x614288, 0x613120 } };
|
|
|
|
const int SENTENCES_PARROT[2] = { 0x615858, 0x6146F0 };
|
|
|
|
const int SENTENCES_SUCCUBUS[2] = { 0x616698, 0x615530 };
|
|
|
|
const int MAPPINGS_BARBOT[2] = { 0x5B28A0, 0x5B173E };
|
|
|
|
const int MAPPINGS_BELLBOT[2] = { 0x5CD830, 0x5CC6C8 };
|
|
|
|
const int MAPPINGS_DESKBOT[2] = { 0x5E2BB8, 0x5E1A50 };
|
|
|
|
const int MAPPINGS_DOORBOT[2] = { 0x5F7950, 0x5F67E8 };
|
|
|
|
const int MAPPINGS_LIFTBOT[2] = { 0x608660, 0x6074F8 };
|
|
|
|
const int MAPPINGS_MAITRED[2] = { 0x6125C8, 0x611460 };
|
|
|
|
const int MAPPINGS_PARROT[2] = { 0x615B68, 0x614A00 };
|
|
|
|
const int MAPPINGS_SUCCUBUS[2] = { 0x6189F0, 0x617888 };
|
|
|
|
const int WORDS_BARBOT[2] = { 0x5BE2E0, 0x5BD178 };
|
|
|
|
const int WORDS_BELLBOT[2] = { 0x5D8230, 0x5D70C8 };
|
|
|
|
const int WORDS_DESKBOT[2] = { 0x5EAAA8, 0x5E9940 };
|
|
|
|
const int WORDS_DOORBOT[2] = { 0x601098, 0x5FFF30 };
|
|
|
|
const int WORDS_LIFTBOT[2] = { 0x60C788, 0x60B620 };
|
|
|
|
writeSentenceEntries("Sentences/Liftbot", SENTENCES_LIFTBOT[_version]);
|
|
|
|
writeSentenceEntries("Sentences/MaitreD", SENTENCES_MAITRED[0][_version]);
|
|
|
|
writeSentenceEntries("Sentences/MaitreD/1", SENTENCES_MAITRED[1][_version]);
|
|
|
|
writeSentenceEntries("Sentences/Parrot", SENTENCES_PARROT[_version]);
|
|
|
|
writeSentenceEntries("Sentences/SuccUBus", SENTENCES_SUCCUBUS[_version]);
|
|
|
|
writeSentenceMappings("Mappings/Barbot", MAPPINGS_BARBOT[_version], 8);
|
|
|
|
writeSentenceMappings("Mappings/Bellbot", MAPPINGS_BELLBOT[_version], 1);
|
|
|
|
writeSentenceMappings("Mappings/Deskbot", MAPPINGS_DESKBOT[_version], 4);
|
|
|
|
writeSentenceMappings("Mappings/Doorbot", MAPPINGS_DOORBOT[_version], 4);
|
|
|
|
writeSentenceMappings("Mappings/Liftbot", MAPPINGS_LIFTBOT[_version], 4);
|
|
|
|
writeSentenceMappings("Mappings/MaitreD", MAPPINGS_MAITRED[_version], 1);
|
|
|
|
writeSentenceMappings("Mappings/Parrot", MAPPINGS_PARROT[_version], 1);
|
|
|
|
writeSentenceMappings("Mappings/SuccUBus", MAPPINGS_SUCCUBUS[_version], 1);
|
|
|
|
writeWords("Words/Barbot", WORDS_BARBOT[_version]);
|
|
|
|
writeWords("Words/Bellbot", WORDS_BELLBOT[_version]);
|
|
|
|
writeWords("Words/Deskbot", WORDS_DESKBOT[_version]);
|
|
|
|
writeWords("Words/Doorbot", WORDS_DOORBOT[_version], 3);
|
|
|
|
writeWords("Words/Liftbot", WORDS_LIFTBOT[_version]);
|
2016-07-30 23:28:03 -04:00
|
|
|
writePhrases("Phrases/Bellbot", BELLBOT_COMMON_PHRASES);
|
2016-06-07 22:33:51 -04:00
|
|
|
|
|
|
|
writeResponseTree();
|
2016-05-16 19:59:09 -04:00
|
|
|
writeNumbers();
|
2016-07-27 06:42:40 -04:00
|
|
|
writeAllScriptQuotes();
|
2016-05-31 21:01:13 -04:00
|
|
|
writeAllScriptResponses();
|
2016-06-06 08:51:37 -04:00
|
|
|
writeAllScriptRanges();
|
2016-08-20 21:52:19 -04:00
|
|
|
|
2016-06-09 22:14:29 -04:00
|
|
|
writeAllTagMappings();
|
2016-07-28 21:03:02 -04:00
|
|
|
writeAllUpdateStates();
|
2016-07-29 21:57:19 -04:00
|
|
|
writeAllScriptPreResponses();
|
2016-08-13 15:09:49 -04:00
|
|
|
writeBarbotFrameRanges();
|
2016-05-15 18:43:33 -04:00
|
|
|
}
|
|
|
|
|
2016-06-09 22:14:29 -04:00
|
|
|
void createScriptMap() {
|
2016-05-31 20:52:16 -04:00
|
|
|
Common::File inFile;
|
|
|
|
char line[80];
|
|
|
|
char c[2];
|
|
|
|
c[0] = c[1] = '\0';
|
2016-06-09 22:14:29 -04:00
|
|
|
int counter = 0;
|
2016-05-31 20:52:16 -04:00
|
|
|
|
2016-06-09 22:14:29 -04:00
|
|
|
inFile.open("d:\\temp\\map.txt");
|
|
|
|
printf("static const TagMapping xxxx_ID_MAP[] = {\n");
|
2016-05-31 20:52:16 -04:00
|
|
|
|
|
|
|
do {
|
|
|
|
strcpy(line, "");
|
|
|
|
|
|
|
|
while (!inFile.eof()) {
|
|
|
|
c[0] = inFile.readByte();
|
|
|
|
if (c[0] == '\n')
|
|
|
|
c[0] = ' ';
|
|
|
|
else if (c[0] == '\r')
|
|
|
|
continue;
|
|
|
|
strcat(line, c);
|
2016-06-09 22:14:29 -04:00
|
|
|
if (inFile.eof() || strlen(line) == (2 * 9))
|
2016-05-31 20:52:16 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-06-09 22:14:29 -04:00
|
|
|
int v1, v2;
|
|
|
|
sscanf(line, "%x %x", &v1, &v2);
|
2016-05-31 20:52:16 -04:00
|
|
|
|
2016-06-09 22:14:29 -04:00
|
|
|
if (counter != 0 && (counter % 3) == 0)
|
|
|
|
printf("\r\n");
|
|
|
|
if ((counter % 3) == 0)
|
|
|
|
printf("\t");
|
2016-05-31 20:52:16 -04:00
|
|
|
|
2016-06-09 22:14:29 -04:00
|
|
|
printf("{ 0x%.5x, 0x%.5x }, ", v1, v2);
|
|
|
|
++counter;
|
2016-05-31 20:52:16 -04:00
|
|
|
} while (!inFile.eof());
|
|
|
|
|
|
|
|
printf("};\r\n");
|
|
|
|
inFile.close();
|
|
|
|
}
|
|
|
|
|
2016-05-15 18:43:33 -04:00
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
if (argc != 3) {
|
|
|
|
printf("Format: %s ST.exe titanic.dat\n", argv[0]);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!inputFile.open(argv[1])) {
|
|
|
|
error("Could not open input file");
|
|
|
|
}
|
|
|
|
res.loadFromEXE(argv[1]);
|
|
|
|
|
2016-08-20 21:52:19 -04:00
|
|
|
if (inputFile.size() == ENGLISH_GOG_FILESIZE)
|
|
|
|
_version = ENGLISH_GOG;
|
|
|
|
else if (inputFile.size() == ENGLISH_ORIG_FILESIZE)
|
|
|
|
_version = ENGLISH_ORIG;
|
|
|
|
else {
|
|
|
|
printf("Unknown version of ST.exe specified");
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2016-05-15 18:43:33 -04:00
|
|
|
if (!outputFile.open(argv[2], Common::kFileWriteMode)) {
|
|
|
|
error("Could not open output file");
|
|
|
|
}
|
|
|
|
|
|
|
|
writeHeader();
|
|
|
|
writeData();
|
|
|
|
writeFinalEntryHeader();
|
|
|
|
|
|
|
|
inputFile.close();
|
|
|
|
outputFile.close();
|
|
|
|
return 0;
|
|
|
|
}
|