|
@@ -81,7 +81,7 @@ int Script::load(const char *file) {
|
81
|
81
|
|
82
|
82
|
// More strings...
|
83
|
83
|
readStringPackage(f, gameStrings, numGameStrings);
|
84
|
|
- readStringPackage(f, pcStrings, 41);
|
|
84
|
+ readStringPackage(f, pcStrings, numPCStrings);
|
85
|
85
|
readStringPackage(f, puzzles[0], numLevels);
|
86
|
86
|
readStringPackage(f, puzzles[1], numLevels);
|
87
|
87
|
readStringPackage(f, puzzles[2], numLevels);
|
|
@@ -130,29 +130,51 @@ void Script::readScriptPackage(BinaryFile &f, std::vector<std::vector<uint16_t>>
|
130
|
130
|
uint16_t numBytes = f.readU16();
|
131
|
131
|
assertEqual(numBytes % 2, 0); // 16 bit opcodes and operands
|
132
|
132
|
|
133
|
|
- // Only TR2, not TR3, has 6 "filler bytes" hex 13 00 14 00 15 00 here
|
134
|
|
- // We need to skip these
|
135
|
|
- uint16_t hack1 = f.readU16();
|
136
|
|
- uint16_t hack2 = f.readU16();
|
137
|
|
- uint16_t hack3 = f.readU16();
|
138
|
|
- uint16_t hackStart = 0;
|
139
|
133
|
uint16_t *list = new uint16_t[(numBytes + 6) / 2];
|
140
|
|
- if ((hack1 == 19) && (hack2 == 20) && (hack3 == 21)) {
|
141
|
|
- numBytes += 6;
|
|
134
|
+ for (uint16_t i = 0; i < (numBytes / 2); i++) {
|
|
135
|
+ list[i] = f.readU16();
|
|
136
|
+ }
|
|
137
|
+
|
|
138
|
+ // TR2 for PC and PSX has 6 "filler bytes" hex 13 00 14 00 15 00
|
|
139
|
+ // (for TR3 for PSX, the filler is hex 15 00 16 00 17 00 instead)
|
|
140
|
+ // at the end of the script block. We need to skip these...
|
|
141
|
+ uint16_t hack[3];
|
|
142
|
+ hack[0] = f.readU16();
|
|
143
|
+ hack[1] = f.readU16();
|
|
144
|
+ hack[2] = f.readU16();
|
|
145
|
+ if (((hack[0] == 19) && (hack[1] == 20) && (hack[2] == 21))
|
|
146
|
+ || ((hack[0] == 21) && (hack[1] == 22) && (hack[2] == 23))) {
|
|
147
|
+ list[numBytes / 2] = hack[0];
|
|
148
|
+ list[(numBytes / 2) + 1] = hack[1];
|
|
149
|
+ list[(numBytes / 2) + 2] = hack[2];
|
142
|
150
|
} else {
|
143
|
|
- list[0] = hack1;
|
144
|
|
- list[1] = hack2;
|
145
|
|
- list[2] = hack3;
|
146
|
|
- hackStart = 3;
|
|
151
|
+ f.seek(f.tell() - 6);
|
147
|
152
|
}
|
148
|
153
|
|
149
|
|
- for (uint16_t i = hackStart; i < (numBytes / 2); i++) {
|
150
|
|
- list[i] = f.readU16();
|
|
154
|
+ // TR2 for PSX has 64 bytes with unknown content (not zero!) here,
|
|
155
|
+ // TR3 for PSX has 40 bytes. We try to identify and skip them...
|
|
156
|
+ // This is also currently used to set the platform specific string count
|
|
157
|
+ hack[0] = f.readU16();
|
|
158
|
+ hack[1] = f.readU16();
|
|
159
|
+ hack[2] = f.readU16();
|
|
160
|
+ if ((hack[0] == 1) && (hack[1] == 0) && (hack[2] == 864)) {
|
|
161
|
+ f.seek(f.tell() + 58);
|
|
162
|
+ numPCStrings = 80; // TR2 has 80 PSX Strings
|
|
163
|
+ } else if ((hack[0] == 1) && (hack[1] == 0) && (hack[2] == 817)) {
|
|
164
|
+ f.seek(f.tell() + 34);
|
|
165
|
+ numPCStrings = 80; // TR3 also has 80 PSX Strings
|
|
166
|
+ } else {
|
|
167
|
+ f.seek(f.tell() - 6);
|
|
168
|
+ numPCStrings = 41;
|
151
|
169
|
}
|
152
|
170
|
|
153
|
171
|
for (unsigned int i = 0; i < n; i++) {
|
154
|
172
|
unsigned int end = offset[i] / 2;
|
155
|
173
|
|
|
174
|
+ // We need to detect the OP_END opcode marking the end of a
|
|
175
|
+ // script sequence (like the '\0' for the strings).
|
|
176
|
+ // However, the numerical value of OP_END could also be used
|
|
177
|
+ // as an operand for another opcode, so we have to check for this
|
156
|
178
|
bool readingOperand = false;
|
157
|
179
|
while (readingOperand || (list[end] != OP_END)) {
|
158
|
180
|
if (readingOperand) {
|
|
@@ -192,6 +214,15 @@ std::string Script::getLevelFilename(unsigned int i) {
|
192
|
214
|
return levelFilenames.at(i);
|
193
|
215
|
}
|
194
|
216
|
|
|
217
|
+unsigned int Script::pictureCount() {
|
|
218
|
+ return numPictures;
|
|
219
|
+}
|
|
220
|
+
|
|
221
|
+std::string Script::getPictureFilename(unsigned int i) {
|
|
222
|
+ assert(i < numPictures);
|
|
223
|
+ return pictureFilenames.at(i);
|
|
224
|
+}
|
|
225
|
+
|
195
|
226
|
unsigned int Script::cutsceneCount() {
|
196
|
227
|
return numCutscenes;
|
197
|
228
|
}
|
|
@@ -229,11 +260,11 @@ std::string Script::getGameString(unsigned int i) {
|
229
|
260
|
}
|
230
|
261
|
|
231
|
262
|
unsigned int Script::pcStringCount() {
|
232
|
|
- return 41;
|
|
263
|
+ return numPCStrings;
|
233
|
264
|
}
|
234
|
265
|
|
235
|
266
|
std::string Script::getPCString(unsigned int i) {
|
236
|
|
- assert(i < 41);
|
|
267
|
+ assert(i < numPCStrings);
|
237
|
268
|
return pcStrings.at(i);
|
238
|
269
|
}
|
239
|
270
|
|