1 #ifndef H_GAMEFLOW 2 #define H_GAMEFLOW 3 4 #include "utils.h" 5 #include "lang.h" 6 7 #define CHECK_FILE(name) if (Stream::existsContent(name)) return name 8 9 namespace TR { 10 11 bool useEasyStart; 12 bool isGameEnded; 13 14 enum { 15 NO_TRACK = 0xFF, 16 }; 17 18 enum Version { 19 VER_UNKNOWN = 0, 20 21 VER_PC = 0x1000, 22 VER_PSX = 0x2000, 23 VER_SAT = 0x4000, 24 VER_SDC = 0x8000, 25 26 VER_TR1 = 0x01, 27 VER_TR2 = 0x02, 28 VER_TR3 = 0x04, 29 VER_TR4 = 0x08, 30 VER_TR5 = 0x10, 31 32 VER_VERSION = VER_TR1 | VER_TR2 | VER_TR3 | VER_TR4 | VER_TR5, 33 VER_PLATFORM = VER_PC | VER_PSX | VER_SAT | VER_SDC, 34 35 VER_TR1_PC = VER_TR1 | VER_PC, 36 VER_TR1_PSX = VER_TR1 | VER_PSX, 37 VER_TR1_SAT = VER_TR1 | VER_SAT, 38 39 VER_TR2_PC = VER_TR2 | VER_PC, 40 VER_TR2_PSX = VER_TR2 | VER_PSX, 41 42 VER_TR3_PC = VER_TR3 | VER_PC, 43 VER_TR3_PSX = VER_TR3 | VER_PSX, 44 45 VER_TR4_PC = VER_TR4 | VER_PC, 46 VER_TR4_PSX = VER_TR4 | VER_PSX, 47 VER_TR4_SDC = VER_TR4 | VER_SDC, 48 49 VER_TR5_PC = VER_TR5 | VER_PC, 50 VER_TR5_PSX = VER_TR5 | VER_PSX, 51 VER_TR5_SDC = VER_TR5 | VER_SDC, 52 53 VER_MAX = 0xFFFFFFFF, 54 }; 55 56 enum LevelID { 57 LVL_CUSTOM, 58 // TR1 59 LVL_TR1_TITLE, 60 LVL_TR1_GYM, 61 LVL_TR1_1, 62 LVL_TR1_2, 63 LVL_TR1_3A, 64 LVL_TR1_3B, 65 LVL_TR1_CUT_1, 66 LVL_TR1_4, 67 LVL_TR1_5, 68 LVL_TR1_6, 69 LVL_TR1_7A, 70 LVL_TR1_7B, 71 LVL_TR1_CUT_2, 72 LVL_TR1_8A, 73 LVL_TR1_8B, 74 LVL_TR1_8C, 75 LVL_TR1_10A, 76 LVL_TR1_CUT_3, 77 LVL_TR1_10B, 78 LVL_TR1_CUT_4, 79 LVL_TR1_10C, 80 LVL_TR1_EGYPT, 81 LVL_TR1_CAT, 82 LVL_TR1_END, 83 LVL_TR1_END2, 84 // TR2 85 LVL_TR2_TITLE, 86 LVL_TR2_ASSAULT, 87 LVL_TR2_WALL, 88 LVL_TR2_CUT_1, 89 LVL_TR2_BOAT, 90 LVL_TR2_VENICE, 91 LVL_TR2_OPERA, 92 LVL_TR2_CUT_2, 93 LVL_TR2_RIG, 94 LVL_TR2_PLATFORM, 95 LVL_TR2_CUT_3, 96 LVL_TR2_UNWATER, 97 LVL_TR2_KEEL, 98 LVL_TR2_LIVING, 99 LVL_TR2_DECK, 100 LVL_TR2_SKIDOO, 101 LVL_TR2_MONASTRY, 102 LVL_TR2_CATACOMB, 103 LVL_TR2_ICECAVE, 104 LVL_TR2_EMPRTOMB, 105 LVL_TR2_CUT_4, 106 LVL_TR2_FLOATING, 107 LVL_TR2_XIAN, 108 LVL_TR2_HOUSE, 109 // TR3 110 LVL_TR3_TITLE, 111 LVL_TR3_HOUSE, 112 LVL_TR3_JUNGLE, 113 LVL_TR3_CUT_6, 114 LVL_TR3_TEMPLE, 115 LVL_TR3_CUT_9, 116 LVL_TR3_QUADCHAS, 117 LVL_TR3_TONYBOSS, 118 LVL_TR3_SHORE, 119 LVL_TR3_CUT_1, 120 LVL_TR3_CRASH, 121 LVL_TR3_CUT_4, 122 LVL_TR3_RAPIDS, 123 LVL_TR3_TRIBOSS, 124 LVL_TR3_ROOFS, 125 LVL_TR3_CUT_2, 126 LVL_TR3_SEWER, 127 LVL_TR3_CUT_5, 128 LVL_TR3_TOWER, 129 LVL_TR3_CUT_11, 130 LVL_TR3_OFFICE, 131 LVL_TR3_NEVADA, 132 LVL_TR3_CUT_7, 133 LVL_TR3_COMPOUND, 134 LVL_TR3_CUT_8, 135 LVL_TR3_AREA51, 136 LVL_TR3_ANTARC, 137 LVL_TR3_CUT_3, 138 LVL_TR3_MINES, 139 LVL_TR3_CITY, 140 LVL_TR3_CUT_12, 141 LVL_TR3_CHAMBER, 142 LVL_TR3_STPAUL, 143 // TR4 144 LVL_TR4_TITLE, 145 LVL_TR4_ANGKOR1, 146 LVL_TR4_ANG_RACE, 147 LVL_TR4_SETTOMB1, 148 LVL_TR4_SETTOMB2, 149 LVL_TR4_JEEPCHAS, 150 LVL_TR4_JEEPCHS2, 151 LVL_TR4_KARNAK1, 152 LVL_TR4_HALL, 153 LVL_TR4_LAKE, 154 LVL_TR4_SEMER, 155 LVL_TR4_SEMER2, 156 LVL_TR4_TRAIN, 157 LVL_TR4_ALEXHUB, 158 LVL_TR4_ALEXHUB2, 159 LVL_TR4_PALACES, 160 LVL_TR4_PALACES2, 161 LVL_TR4_CSPLIT1, 162 LVL_TR4_CSPLIT2, 163 LVL_TR4_LIBRARY, 164 LVL_TR4_LIBEND, 165 LVL_TR4_BIKEBIT, 166 LVL_TR4_NUTRENCH, 167 LVL_TR4_CORTYARD, 168 LVL_TR4_LOWSTRT, 169 LVL_TR4_HIGHSTRT, 170 LVL_TR4_CITNEW, 171 LVL_TR4_JOBY1A, 172 LVL_TR4_JOBY1B, 173 LVL_TR4_JOBY2, 174 LVL_TR4_JOBY3A, 175 LVL_TR4_JOBY3B, 176 LVL_TR4_JOBY4A, 177 LVL_TR4_JOBY4B, 178 LVL_TR4_JOBY4C, 179 LVL_TR4_JOBY5A, 180 LVL_TR4_JOBY5B, 181 LVL_TR4_JOBY5C, 182 183 LVL_MAX, 184 }; 185 186 enum { 187 // TR1 188 TRACK_TR1_TITLE = 2, 189 TRACK_TR1_CAVES = 5, 190 TRACK_TR1_SECRET = 13, 191 TRACK_TR1_CISTERN = 57, 192 TRACK_TR1_WIND = 58, 193 TRACK_TR1_PYRAMID = 59, 194 TRACK_TR1_CUT_1 = 23, 195 TRACK_TR1_CUT_2 = 25, 196 TRACK_TR1_CUT_3 = 24, 197 TRACK_TR1_CUT_4 = 22, 198 // TR2 199 TRACK_TR2_TITLE = 64, 200 TRACK_TR2_CHINA_1 = 33, 201 TRACK_TR2_CHINA_2 = 59, 202 TRACK_TR2_ITALY = 31, 203 TRACK_TR2_RIG = 58, 204 TRACK_TR2_UNWATER_1 = 34, 205 TRACK_TR2_UNWATER_2 = 31, 206 TRACK_TR2_TIBET_1 = 33, 207 TRACK_TR2_TIBET_2 = 31, 208 TRACK_TR2_CUT_1 = 3, 209 TRACK_TR2_CUT_2 = 4, 210 TRACK_TR2_CUT_3 = 5, 211 TRACK_TR2_CUT_4 = 30, 212 // TR3 213 TRACK_TR3_TITLE = 5, 214 TRACK_TR3_HOUSE = 2, 215 TRACK_TR3_CAVES = 30, 216 TRACK_TR3_INDIA_1 = 34, 217 TRACK_TR3_INDIA_2 = 30, 218 TRACK_TR3_SOUTH_1 = 32, 219 TRACK_TR3_SOUTH_2 = 33, 220 TRACK_TR3_SOUTH_3 = 36, 221 TRACK_TR3_LONDON_1 = 73, 222 TRACK_TR3_LONDON_2 = 74, 223 TRACK_TR3_LONDON_3 = 31, 224 TRACK_TR3_LONDON_4 = 78, 225 TRACK_TR3_NEVADA_1 = 33, 226 TRACK_TR3_NEVADA_2 = 27, 227 TRACK_TR3_ANTARC_1 = 28, 228 TRACK_TR3_ANTARC_2 = 30, 229 TRACK_TR3_ANTARC_3 = 26, 230 TRACK_TR3_CUT_1 = 68, 231 TRACK_TR3_CUT_2 = 67, 232 TRACK_TR3_CUT_3 = 62, 233 TRACK_TR3_CUT_4 = 65, 234 TRACK_TR3_CUT_5 = 63, 235 TRACK_TR3_CUT_6 = 64, 236 TRACK_TR3_CUT_7 = 72, 237 TRACK_TR3_CUT_8 = 70, 238 TRACK_TR3_CUT_9 = 69, 239 TRACK_TR3_CUT_11 = 71, 240 TRACK_TR3_CUT_12 = 66, 241 // TR4 242 TRACK_TR4_BOSS = 97, 243 TRACK_TR4_JEEP = 98, 244 TRACK_TR4_BATTLE = 102, 245 TRACK_TR4_TITLE = 104, 246 TRACK_TR4_COASTAL = 105, 247 TRACK_TR4_TRAIN = 106, 248 TRACK_TR4_IN_DARK = 107, 249 TRACK_TR4_IN_DRIPS = 108, 250 TRACK_TR4_WEIRD1 = 109, 251 TRACK_TR4_OUT_DAY = 110, 252 TRACK_TR4_OUT_NIGHT = 111, 253 }; 254 255 struct LevelInfo { 256 const char *name; 257 StringID title; 258 uint8 track; 259 uint8 secrets; 260 } LEVEL_INFO[LVL_MAX] = { 261 { "" , STR_EMPTY , TRACK_TR1_CAVES , 0 }, 262 // TR1 263 { "TITLE" , STR_EMPTY , TRACK_TR1_TITLE , 0 }, 264 { "GYM" , STR_TR1_GYM , NO_TRACK , 0 }, 265 { "LEVEL1" , STR_TR1_LEVEL1 , TRACK_TR1_CAVES , 3 }, 266 { "LEVEL2" , STR_TR1_LEVEL2 , TRACK_TR1_CAVES , 3 }, 267 { "LEVEL3A" , STR_TR1_LEVEL3A , TRACK_TR1_CAVES , 5 }, 268 { "LEVEL3B" , STR_TR1_LEVEL3B , TRACK_TR1_CAVES , 3 }, 269 { "CUT1" , STR_EMPTY , TRACK_TR1_CUT_1 , 0 }, 270 { "LEVEL4" , STR_TR1_LEVEL4 , TRACK_TR1_WIND , 4 }, 271 { "LEVEL5" , STR_TR1_LEVEL5 , TRACK_TR1_WIND , 3 }, 272 { "LEVEL6" , STR_TR1_LEVEL6 , TRACK_TR1_WIND , 3 }, 273 { "LEVEL7A" , STR_TR1_LEVEL7A , TRACK_TR1_CISTERN , 3 }, 274 { "LEVEL7B" , STR_TR1_LEVEL7B , TRACK_TR1_CISTERN , 2 }, 275 { "CUT2" , STR_EMPTY , TRACK_TR1_CUT_2 , 0 }, 276 { "LEVEL8A" , STR_TR1_LEVEL8A , TRACK_TR1_WIND , 3 }, 277 { "LEVEL8B" , STR_TR1_LEVEL8B , TRACK_TR1_WIND , 3 }, 278 { "LEVEL8C" , STR_TR1_LEVEL8C , TRACK_TR1_WIND , 1 }, 279 { "LEVEL10A" , STR_TR1_LEVEL10A , TRACK_TR1_CISTERN , 3 }, 280 { "CUT3" , STR_EMPTY , TRACK_TR1_CUT_3 , 0 }, 281 { "LEVEL10B" , STR_TR1_LEVEL10B , TRACK_TR1_PYRAMID , 3 }, 282 { "CUT4" , STR_EMPTY , TRACK_TR1_CUT_4 , 0 }, 283 { "LEVEL10C" , STR_TR1_LEVEL10C , TRACK_TR1_PYRAMID , 3 }, 284 { "EGYPT" , STR_TR1_EGYPT , TRACK_TR1_WIND , 3 }, 285 { "CAT" , STR_TR1_CAT , TRACK_TR1_WIND , 4 }, 286 { "END" , STR_TR1_END , TRACK_TR1_WIND , 2 }, 287 { "END2" , STR_TR1_END2 , TRACK_TR1_WIND , 1 }, 288 // TR2 289 { "TITLE" , STR_EMPTY , TRACK_TR2_TITLE , 0 }, 290 { "ASSAULT" , STR_TR2_ASSAULT , NO_TRACK , 0 }, 291 { "WALL" , STR_TR2_WALL , TRACK_TR2_CHINA_1 , 3 }, 292 { "CUT1" , STR_EMPTY , TRACK_TR2_CUT_1 , 0 }, 293 { "BOAT" , STR_TR2_BOAT , NO_TRACK , 3 }, 294 { "VENICE" , STR_TR2_VENICE , NO_TRACK , 3 }, 295 { "OPERA" , STR_TR2_OPERA , TRACK_TR2_ITALY , 3 }, 296 { "CUT2" , STR_EMPTY , TRACK_TR2_CUT_2 , 0 }, 297 { "RIG" , STR_TR2_RIG , TRACK_TR2_RIG , 3 }, 298 { "PLATFORM" , STR_TR2_PLATFORM , TRACK_TR2_RIG , 3 }, 299 { "CUT3" , STR_EMPTY , TRACK_TR2_CUT_3 , 0 }, 300 { "UNWATER" , STR_TR2_UNWATER , TRACK_TR2_UNWATER_1 , 3 }, 301 { "KEEL" , STR_TR2_KEEL , TRACK_TR2_UNWATER_2 , 3 }, 302 { "LIVING" , STR_TR2_LIVING , TRACK_TR2_UNWATER_1 , 3 }, 303 { "DECK" , STR_TR2_DECK , TRACK_TR2_UNWATER_2 , 3 }, 304 { "SKIDOO" , STR_TR2_SKIDOO , TRACK_TR2_TIBET_1 , 3 }, 305 { "MONASTRY" , STR_TR2_MONASTRY , NO_TRACK , 3 }, 306 { "CATACOMB" , STR_TR2_CATACOMB , TRACK_TR2_TIBET_2 , 3 }, 307 { "ICECAVE" , STR_TR2_ICECAVE , TRACK_TR2_TIBET_2 , 3 }, 308 { "EMPRTOMB" , STR_TR2_EMPRTOMB , TRACK_TR2_CHINA_2 , 3 }, 309 { "CUT4" , STR_EMPTY , TRACK_TR2_CUT_4 , 0 }, 310 { "FLOATING" , STR_TR2_FLOATING , TRACK_TR2_CHINA_2 , 3 }, 311 { "XIAN" , STR_TR2_XIAN , TRACK_TR2_CHINA_2 , 3 }, 312 { "HOUSE" , STR_TR2_HOUSE , NO_TRACK , 3 }, 313 // TR3 314 { "TITLE" , STR_EMPTY , TRACK_TR3_TITLE , 0 }, 315 { "HOUSE" , STR_TR3_HOUSE , NO_TRACK , 3 }, 316 { "JUNGLE" , STR_TR3_JUNGLE , TRACK_TR3_INDIA_1 , 3 }, 317 { "CUT6" , STR_EMPTY , TRACK_TR3_CUT_6 , 0 }, 318 { "TEMPLE" , STR_TR3_TEMPLE , TRACK_TR3_INDIA_1 , 3 }, 319 { "CUT9" , STR_EMPTY , TRACK_TR3_CUT_9 , 0 }, 320 { "QUADCHAS" , STR_TR3_QUADCHAS , TRACK_TR3_INDIA_1 , 3 }, 321 { "TONYBOSS" , STR_TR3_TONYBOSS , TRACK_TR3_INDIA_2 , 3 }, 322 { "SHORE" , STR_TR3_SHORE , TRACK_TR3_SOUTH_1 , 3 }, 323 { "CUT1" , STR_EMPTY , TRACK_TR3_CUT_1 , 0 }, 324 { "CRASH" , STR_TR3_CRASH , TRACK_TR3_SOUTH_2 , 3 }, 325 { "CUT4" , STR_EMPTY , TRACK_TR3_CUT_4 , 0 }, 326 { "RAPIDS" , STR_TR3_RAPIDS , TRACK_TR3_SOUTH_3 , 3 }, 327 { "TRIBOSS" , STR_TR3_TRIBOSS , TRACK_TR3_CAVES , 3 }, 328 { "ROOFS" , STR_TR3_ROOFS , TRACK_TR3_LONDON_1 , 3 }, 329 { "CUT2" , STR_EMPTY , TRACK_TR3_CUT_2 , 0 }, 330 { "SEWER" , STR_TR3_SEWER , TRACK_TR3_LONDON_2 , 3 }, 331 { "CUT5" , STR_EMPTY , TRACK_TR3_CUT_5 , 0 }, 332 { "TOWER" , STR_TR3_TOWER , TRACK_TR3_LONDON_3 , 3 }, 333 { "CUT11" , STR_EMPTY , TRACK_TR3_CUT_11 , 0 }, 334 { "OFFICE" , STR_TR3_OFFICE , TRACK_TR3_LONDON_4 , 3 }, 335 { "NEVADA" , STR_TR3_NEVADA , TRACK_TR3_NEVADA_1 , 3 }, 336 { "CUT7" , STR_EMPTY , TRACK_TR3_CUT_7 , 0 }, 337 { "COMPOUND" , STR_TR3_COMPOUND , TRACK_TR3_NEVADA_2 , 3 }, 338 { "CUT8" , STR_EMPTY , TRACK_TR3_CUT_8 , 0 }, 339 { "AREA51" , STR_TR3_AREA51 , TRACK_TR3_NEVADA_2 , 3 }, 340 { "ANTARC" , STR_TR3_ANTARC , TRACK_TR3_ANTARC_1 , 3 }, 341 { "CUT3" , STR_EMPTY , TRACK_TR3_CUT_3 , 0 }, 342 { "MINES" , STR_TR3_MINES , TRACK_TR3_ANTARC_2 , 3 }, 343 { "CITY" , STR_TR3_CITY , TRACK_TR3_ANTARC_3 , 3 }, 344 { "CUT12" , STR_EMPTY , TRACK_TR3_CUT_12 , 0 }, 345 { "CHAMBER" , STR_TR3_CHAMBER , TRACK_TR3_ANTARC_3 , 3 }, 346 { "STPAUL" , STR_TR3_STPAUL , TRACK_TR3_CAVES , 3 }, 347 // TR4 348 { "title" , STR_UNKNOWN , TRACK_TR4_TITLE , 0 }, 349 { "angkor1" , STR_UNKNOWN , TRACK_TR4_OUT_DAY , 0 }, 350 { "ang_race" , STR_UNKNOWN , TRACK_TR4_OUT_DAY , 0 }, 351 { "settomb1" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 352 { "settomb2" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 353 { "jeepchas" , STR_UNKNOWN , TRACK_TR4_OUT_DAY , 0 }, 354 { "jeepchs2" , STR_UNKNOWN , TRACK_TR4_JEEP , 0 }, 355 { "karnak1" , STR_UNKNOWN , TRACK_TR4_OUT_DAY , 0 }, 356 { "hall" , STR_UNKNOWN , TRACK_TR4_OUT_DAY , 0 }, 357 { "lake" , STR_UNKNOWN , TRACK_TR4_OUT_DAY , 0 }, 358 { "semer" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 359 { "semer2" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 360 { "train" , STR_UNKNOWN , TRACK_TR4_TRAIN , 0 }, 361 { "alexhub" , STR_UNKNOWN , TRACK_TR4_OUT_DAY , 0 }, 362 { "alexhub2" , STR_UNKNOWN , TRACK_TR4_COASTAL , 0 }, 363 { "palaces" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 364 { "palaces2" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 365 { "csplit1" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS , 0 }, 366 { "csplit2" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS , 0 }, 367 { "library" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS , 0 }, 368 { "libend" , STR_UNKNOWN , TRACK_TR4_WEIRD1 , 0 }, 369 { "bikebit" , STR_UNKNOWN , TRACK_TR4_BATTLE , 0 }, 370 { "nutrench" , STR_UNKNOWN , TRACK_TR4_BATTLE , 0 }, 371 { "cortyard" , STR_UNKNOWN , TRACK_TR4_BATTLE , 0 }, 372 { "lowstrt" , STR_UNKNOWN , TRACK_TR4_BATTLE , 0 }, 373 { "highstrt" , STR_UNKNOWN , TRACK_TR4_BATTLE , 0 }, 374 { "citnew" , STR_UNKNOWN , TRACK_TR4_BATTLE , 0 }, 375 { "joby1a" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT , 0 }, 376 { "joby1b" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 377 { "joby2" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 378 { "joby3a" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT , 0 }, 379 { "joby3b" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 380 { "joby4a" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT , 0 }, 381 { "joby4b" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 382 { "joby4c" , STR_UNKNOWN , TRACK_TR4_OUT_NIGHT , 0 }, 383 { "joby5a" , STR_UNKNOWN , TRACK_TR4_IN_DARK , 0 }, 384 { "joby5b" , STR_UNKNOWN , TRACK_TR4_BOSS , 0 }, 385 { "joby5c" , STR_UNKNOWN , TRACK_TR4_IN_DRIPS , 0 }, 386 }; 387 388 static const char* TRACK_LIST_TR4[] = { 389 "044_Attack_part_i" 390 , "008_VonCroy9a" 391 , "100_Attack_part_ii" 392 , "010_VonCroy10" 393 , "015_VonCroy14" 394 , "073_Secret" 395 , "109_Lyre_01" 396 , "042_Action_Part_iv" 397 , "043_Action_Part_v" 398 , "030_VonCroy30" 399 , "012_VonCroy11b" 400 , "011_VonCroy11a" 401 , "063_Misc_Inc_01" 402 , "014_VonCroy13b" 403 , "111_charmer" 404 , "025_VonCroy24b" 405 , "023_VonCroy23" 406 , "006_VonCroy7" 407 , "024_VonCroy24a" 408 , "110_Lyre_02" 409 , "020_VonCroy19" 410 , "034_VonCroy34" 411 , "054_General_Part_ii" 412 , "036_VonCroy36" 413 , "004_VonCroy5" 414 , "035_VonCroy35" 415 , "027_VonCroy27" 416 , "053_General_Part_i" 417 , "022_VonCroy22b" 418 , "028_VonCroy28_L11" 419 , "003_VonCroy4" 420 , "001_VonCroy2" 421 , "041_Action_Part_iii" 422 , "057_General_Part_v" 423 , "018_VonCroy17" 424 , "064_Misc_Inc_02" 425 , "033_VonCroy33" 426 , "031_VonCroy31_L12" 427 , "032_VonCroy32_L13" 428 , "016_VonCroy15" 429 , "065_Misc_Inc_03" 430 , "040_Action_Part_ii" 431 , "112_Gods_part_iv" 432 , "029_VonCroy29" 433 , "007_VonCroy8" 434 , "013_VonCroy12_13a_Lara4" 435 , "009_VonCroy9b_Lara3" 436 , "081_dig" 437 , "085_intro" 438 , "071_Ominous_Part_i" 439 , "095_phildoor" 440 , "061_In_The_Pyramid_Part_i" 441 , "050_Underwater_Find_part_i" 442 , "058_Gods_Part_i" 443 , "005_VonCroy6_Lara2" 444 , "045_Authentic_TR" 445 , "060_Gods_Part_iii" 446 , "055_General_Part_iii" 447 , "059_Gods_Part_ii" 448 , "068_Mystery_Part_ii" 449 , "076_captain2" 450 , "019_Lara6_VonCroy18" 451 , "002_VonCroy3" 452 , "066_Misc_Inc_04" 453 , "067_Mystery_Part_i" 454 , "038_A_Short_01" 455 , "088_key" 456 , "017_VonCroy16_lara5" 457 , "026_VC25_L9_VC26_L10" 458 , "056_General_Part_iv" 459 , "021_VC20_L7_VC21_L8_VC22a" 460 , "096_sarcoph" 461 , "087_jeepB" 462 , "091_minilib1" 463 , "086_jeepA" 464 , "051_Egyptian_Mood_Part_i" 465 , "078_croywon" 466 , "092_minilib2" 467 , "083_horus" 468 , "049_Close_to_the_End_part_ii" 469 , "037_VC37_L15_VC38" 470 , "097_scorpion" 471 , "089_larawon" 472 , "094_minilib4" 473 , "098_throne" 474 , "048_Close_to_the_End" 475 , "070_Mystery_Part_iv" 476 , "093_minilib3" 477 , "072_Puzzle_part_i" 478 , "074_backpack" 479 , "069_Mystery_Part_iii" 480 , "052_Egyptian_Mood_Part_ii" 481 , "084_inscrip" 482 , "099_whouse" 483 , "047_Boss_02" 484 , "080_crypt2" 485 , "090_libend" 486 , "046_Boss_01" 487 , "062_Jeep_Thrills_max" 488 , "079_crypt1" 489 , "082_finale" 490 , "075_captain1" 491 , "105_A5_Battle" 492 , "077_crocgod" 493 , "039_TR4_Title_Q10" 494 , "108_A8_Coastal" 495 , "107_A7_Train+" 496 , "101_A1_In_Dark" 497 , "102_A2_In_Drips" 498 , "104_A4_Weird1" 499 , "106_A6_Out_Day" 500 , "103_A3_Out_Night" 501 }; 502 getGameVersionByLevel(LevelID id)503 Version getGameVersionByLevel(LevelID id) { 504 if (id >= LVL_TR1_TITLE && id <= LVL_TR1_END2) 505 return VER_TR1; 506 if (id >= LVL_TR2_TITLE && id <= LVL_TR2_HOUSE) 507 return VER_TR2; 508 if (id >= LVL_TR3_TITLE && id <= LVL_TR3_STPAUL) 509 return VER_TR3; 510 if (id >= LVL_TR4_TITLE && id <= LVL_TR4_JOBY5C) 511 return VER_TR4; 512 return VER_UNKNOWN; 513 } 514 getLevelID(int size,const char * name,Version & version,bool & isDemoLevel)515 LevelID getLevelID(int size, const char *name, Version &version, bool &isDemoLevel) { 516 isDemoLevel = false; 517 switch (size) { 518 // TR1 519 // TITLE 520 case 585648 : // PSX JAP 521 case 508614 : version = VER_TR1_PSX; 522 case 5148 : // SAT 523 case 320412 : // PC JAP 524 case 334874 : 525 case 316138 : 526 case 316518 : // PC G 527 case 316460 : return LVL_TR1_TITLE; 528 // GYM 529 case 1234800 : // PSX JAP 530 case 1074234 : version = VER_TR1_PSX; 531 case 343854 : // SAT 532 case 3377974 : // PC JAP 533 case 3236806 : 534 case 3282970 : // PC G 535 case 3237128 : return LVL_TR1_GYM; 536 // LEVEL1 537 case 1667568 : // PSX JAP 538 case 1448896 : version = VER_TR1_PSX; 539 case 497656 : // SAT 540 case 2540906 : // PC JAP 541 case 2533312 : 542 case 2533634 : return LVL_TR1_1; 543 // LEVEL2 544 case 2873406 : isDemoLevel = true; return LVL_TR1_2; 545 case 1766352 : // PSX JAP 546 case 1535734 : version = VER_TR1_PSX; 547 case 532250 : // SAT 548 case 2880722 : // PC JAP 549 case 2873128 : 550 case 2873450 : return LVL_TR1_2; 551 // LEVEL3A 552 case 1876896 : // PSX JAP 553 case 1630560 : version = VER_TR1_PSX; 554 case 547782 : // SAT 555 case 2942002 : // PC JAP 556 case 2934408 : 557 case 2934730 : return LVL_TR1_3A; 558 // LEVEL3B 559 case 1510414 : // PSX JAP 560 case 1506614 : version = VER_TR1_PSX; 561 case 310960 : // SAT 562 case 2745530 : // PC JAP 563 case 2737936 : 564 case 2738258 : return LVL_TR1_3B; 565 // CUT1 566 case 722402 : version = VER_TR1_PSX; 567 case 142116 : // SAT 568 case 599840 : return LVL_TR1_CUT_1; 569 // LEVEL4 570 case 1624130 : // PSX JAP 571 case 1621970 : version = VER_TR1_PSX; 572 case 440612 : // SAT 573 case 3038144 : // PC JAP 574 case 3030550 : 575 case 3030872 : return LVL_TR1_4; 576 // LEVEL5 577 case 1588102 : // PSX JAP 578 case 1585942 : version = VER_TR1_PSX; 579 case 389996 : // SAT 580 case 2725812 : // PC JAP 581 case 2718218 : 582 case 2718540 : return LVL_TR1_5; 583 // LEVEL6 584 case 1710624 : // PSX JAP 585 case 1708464 : version = VER_TR1_PSX; 586 case 573506 : // SAT 587 case 3147184 : // PC JAP 588 case 3139590 : 589 case 3074376 : return LVL_TR1_6; 590 // LEVEL7A 591 case 1698824 : // PSX JAP 592 case 1696664 : version = VER_TR1_PSX; 593 case 581416 : // SAT 594 case 2824884 : // PC JAP 595 case 2817290 : 596 case 2817612 : return LVL_TR1_7A; 597 // LEVEL7B 598 case 1735434 : // PSX JAP 599 case 1733274 : version = VER_TR1_PSX; 600 case 596416 : // SAT 601 case 3603912 : // PC JAP 602 case 3388774 : 603 case 3395618 : // PC G 604 case 3389096 : return LVL_TR1_7B; 605 // CUT2 606 case 542960 : version = VER_TR1_PSX; 607 case 70860 : // SAT 608 case 354320 : return LVL_TR1_CUT_2; 609 // LEVEL8A 610 case 1565494 : // PSX JAP 611 case 1563356 : version = VER_TR1_PSX; 612 case 592188 : // SAT 613 case 2887836 : // PC JAP 614 case 2880242 : 615 case 2880564 : return LVL_TR1_8A; 616 // LEVEL8B 617 case 1567790 : // PSX JAP 618 case 1565630 : version = VER_TR1_PSX; 619 case 599928 : // SAT 620 case 2894028 : // PC JAP 621 case 2886434 : 622 case 2886756 : return LVL_TR1_8B; 623 // LEVEL8C 624 case 1621520 : // PSX JAP 625 case 1619360 : version = VER_TR1_PSX; 626 case 536950 : // SAT 627 case 3072066 : // PC JAP 628 case 3105128 : 629 case 3025380 : // PC G 630 case 3105450 : return LVL_TR1_8C; 631 // LEVEL10A 632 case 1680146 : // PSX JAP 633 case 1678018 : version = VER_TR1_PSX; 634 case 569856 : // SAT 635 case 3270372 : // PC JAP 636 case 3223816 : 637 case 3154346 : // PC G 638 case 3224138 : return LVL_TR1_10A; 639 // CUT3 640 case 636660 : version = VER_TR1_PSX; 641 case 210134 : // SAT 642 case 512104 : return LVL_TR1_CUT_3; 643 // LEVEL10B 644 case 1688908 : // PSX JAP 645 case 1686748 : version = VER_TR1_PSX; 646 case 525646 : // SAT 647 case 3101614 : // PC JAP 648 case 3094342 : 649 case 3094020 : return LVL_TR1_10B; 650 // CUT4 651 case 940398 : version = VER_TR1_PSX; 652 case 167188 : // SAT 653 case 879582 : return LVL_TR1_CUT_4; 654 // LEVEL10C 655 case 1816438 : // PSX JAP 656 case 1814278 : version = VER_TR1_PSX; 657 case 418170 : // SAT 658 case 3533814 : // PC JAP 659 case 3531702 : 660 case 3496692 : // PC G 661 case 3532024 : return LVL_TR1_10C; 662 // EGYPT 663 case 3278614 : version = VER_TR1_PSX; 664 case 3279242 : return LVL_TR1_EGYPT; 665 // CAT 666 case 3270370 : version = VER_TR1_PSX; 667 case 3270998 : return LVL_TR1_CAT; 668 // END 669 case 3208018 : return LVL_TR1_END; 670 // END2 671 case 3153300 : return LVL_TR1_END2; 672 // TR2 673 // TITLE 674 case 148698 : // PSX JAP 675 case 148744 : version = VER_TR2_PSX; 676 case 611892 : return LVL_TR2_TITLE; 677 // ASSAULT 678 case 1568632 : // PSX JAP 679 case 1565974 : version = VER_TR2_PSX; 680 case 3471450 : return LVL_TR2_ASSAULT; 681 // WALL 682 case 1664198 : // PSX JAP 683 case 1661622 : version = VER_TR2_PSX; 684 case 2986356 : return LVL_TR2_WALL; 685 // BOAT 686 case 2017538 : // PSX JAP 687 case 2014880 : 688 case 2010678 : version = VER_TR2_PSX; // PLAYABLE.PSX 689 case 3945738 : return LVL_TR2_BOAT; 690 // VENICE 691 case 2084060 : // PSX JAP 692 case 2081402 : version = VER_TR2_PSX; 693 case 4213070 : return LVL_TR2_VENICE; 694 // OPERA 695 case 2063540 : // PSX JAP 696 case 2060882 : version = VER_TR2_PSX; 697 case 3996500 : return LVL_TR2_OPERA; 698 // RIG 699 case 1952874 : // PSX JAP 700 case 1950216 : version = VER_TR2_PSX; 701 case 3944472 : return LVL_TR2_RIG; 702 // PLATFORM 703 case 1995728 : // PSX JAP 704 case 1993070 : version = VER_TR2_PSX; 705 case 4101590 : return LVL_TR2_PLATFORM; 706 // UNWATER 707 case 1786858 : // PSX JAP 708 case 1784200 : version = VER_TR2_PSX; 709 case 3131814 : return LVL_TR2_UNWATER; 710 // KEEL 711 case 2016768 : // PSX JAP 712 case 2014110 : version = VER_TR2_PSX; 713 case 3995356 : return LVL_TR2_KEEL; 714 // LIVING 715 case 1811102 : // PSX JAP 716 case 1808444 : version = VER_TR2_PSX; 717 case 3501472 : return LVL_TR2_LIVING; 718 // DECK 719 case 1970742 : // PSX JAP 720 case 1968084 : version = VER_TR2_PSX; 721 case 3890042 : return LVL_TR2_DECK; 722 // SKIDOO 723 case 1984560 : // PSX JAP 724 case 1981902 : version = VER_TR2_PSX; 725 case 3521106 : return LVL_TR2_SKIDOO; 726 // MONASTRY 727 case 2123446 : // PSX JAP 728 case 2120772 : version = VER_TR2_PSX; 729 case 4325562 : return LVL_TR2_MONASTRY; 730 // CATACOMB 731 case 1880628 : // PSX JAP 732 case 1877970 : version = VER_TR2_PSX; 733 case 3605052 : return LVL_TR2_CATACOMB; 734 // ICECAVE 735 case 1990512 : // PSX JAP 736 case 1987854 : version = VER_TR2_PSX; 737 case 3803398 : return LVL_TR2_ICECAVE; 738 // EMPRTOMB 739 case 2104252 : // PSX JAP 740 case 2101594 : version = VER_TR2_PSX; 741 case 4291468 : return LVL_TR2_EMPRTOMB; 742 // FLOATING 743 case 2081348 : // PSX JAP 744 case 2078690 : version = VER_TR2_PSX; 745 case 4007486 : return LVL_TR2_FLOATING; 746 // XIAN 747 case 1751496 : // PSX JAP 748 case 1748838 : version = VER_TR2_PSX; 749 case 3173840 : return LVL_TR2_XIAN; 750 // HOUSE 751 case 1889386 : // PSX JAP 752 case 1886728 : version = VER_TR2_PSX; 753 case 3693108 : return LVL_TR2_HOUSE; 754 // CUT1 755 case 952800 : // PSX JAP 756 case 952798 : version = VER_TR2_PSX; 757 case 1767052 : return LVL_TR2_CUT_1; 758 // CUT2 759 case 1098878 : // PSX JAP 760 case 1098876 : version = VER_TR2_PSX; 761 case 2037544 : return LVL_TR2_CUT_2; 762 // CUT3 763 case 1288924 : // PSX JAP 764 case 1288922 : version = VER_TR2_PSX; 765 case 2558286 : return LVL_TR2_CUT_3; 766 // CUT4 767 case 1116968 : // PSX JAP 768 case 1116966 : version = VER_TR2_PSX; 769 case 1900230 : return LVL_TR2_CUT_4; 770 // TR3 771 // TITLE 772 case 653485 : // PSX JAP 773 case 653403 : 774 case 1275266 : return LVL_TR3_TITLE; 775 // HOUSE 776 case 1891244 : // PSX JAP 777 case 1889506 : 778 case 3437855 : return LVL_TR3_HOUSE; 779 // JUNGLE 780 case 1933419 : // PSX JAP 781 case 1930923 : 782 case 3360001 : return LVL_TR3_JUNGLE; 783 // TEMPLE 784 case 1945795 : // PSX JAP 785 case 1943847 : 786 case 3180412 : return LVL_TR3_TEMPLE; 787 // QUADCHAS 788 case 1881562 : // PSX JAP 789 case 1880004 : 790 case 3131453 : return LVL_TR3_QUADCHAS; 791 // TONYBOSS 792 case 1495530 : // PSX JAP 793 case 1493796 : 794 case 2618437 : return LVL_TR3_TONYBOSS; 795 // SHORE 796 case 1981723 : // PSX JAP 797 case 1979611 : 798 case 3365562 : return LVL_TR3_SHORE; 799 // CRASH 800 case 2018552 : // PSX JAP 801 case 2016876 : 802 case 3331132 : return LVL_TR3_CRASH; 803 // RAPIDS 804 case 1942136 : // PSX JAP 805 case 1940346 : 806 case 3148248 : return LVL_TR3_RAPIDS; 807 // TRIBOSS 808 case 1523788 : // PSX JAP 809 case 1521998 : 810 case 2276838 : return LVL_TR3_TRIBOSS; 811 // ROOFS 812 case 2098953 : // PSX JAP 813 case 2097077 : 814 case 3579476 : return LVL_TR3_ROOFS; 815 // SEWER 816 case 2035235 : // PSX JAP 817 case 2033505 : 818 case 3670149 : return LVL_TR3_SEWER; 819 // TOWER 820 case 2080921 : // PSX JAP 821 case 2079183 : 822 case 3523586 : return LVL_TR3_TOWER; 823 // OFFICE 824 case 1550728 : // PSX JAP 825 case 1549006 : 826 case 2504910 : return LVL_TR3_OFFICE; 827 // NEVADA 828 case 1940862 : // PSX JAP 829 case 1938738 : 830 case 3140417 : return LVL_TR3_NEVADA; 831 // COMPOUND 832 case 2050018 : // PSX JAP 833 case 2048288 : 834 case 3554880 : return LVL_TR3_COMPOUND; 835 // AREA51 836 case 2056073 : // PSX JAP 837 case 2054325 : 838 case 3530130 : return LVL_TR3_AREA51; 839 // ANTARC 840 case 2000298 : // PSX JAP 841 case 1998398 : 842 case 3515272 : return LVL_TR3_ANTARC; 843 // MINES 844 case 2025641 : // PSX JAP 845 case 2023895 : 846 case 3331087 : return LVL_TR3_MINES; 847 // CITY 848 case 2058380 : // PSX JAP 849 case 2056388 : 850 case 3575873 : return LVL_TR3_CITY; 851 // CHAMBER 852 case 1782615 : // PSX JAP 853 case 1780885 : 854 case 3190736 : return LVL_TR3_CHAMBER; 855 // STPAUL 856 case 1711157 : // PSX JAP 857 case 1709427 : 858 case 3140028 : return LVL_TR3_STPAUL; 859 // CUT1 860 case 757909 : // PSX JAP 861 case 757827 : 862 case 1547866 : return LVL_TR3_CUT_1; 863 // CUT2 864 case 982847 : // PSX JAP 865 case 982765 : 866 case 1957327 : return LVL_TR3_CUT_2; 867 // CUT3 868 case 1243054 : // PSX JAP 869 case 1242972 : 870 case 2020225 : return LVL_TR3_CUT_3; 871 // CUT4 872 case 430212 : // PSX JAP 873 case 430130 : 874 case 1048466 : return LVL_TR3_CUT_4; 875 // CUT5 876 case 971367 : // PSX JAP 877 case 971285 : 878 case 1580868 : return LVL_TR3_CUT_5; 879 // CUT6 880 case 1325570 : // PSX JAP 881 case 1325488 : 882 case 2430940 : return LVL_TR3_CUT_6; 883 // CUT7 884 case 467203 : // PSX JAP 885 case 467121 : 886 case 1253227 : return LVL_TR3_CUT_7; 887 // CUT8 888 case 494396 : // PSX JAP 889 case 494314 : 890 case 944962 : return LVL_TR3_CUT_8; 891 // CUT9 892 case 1002318 : // PSX JAP 893 case 1002236 : 894 case 1788075 : return LVL_TR3_CUT_9; 895 // CUT11 896 case 590267 : // PSX JAP 897 case 590185 : 898 case 1402003 : return LVL_TR3_CUT_11; 899 // CUT12 900 case 1080128 : // PSX JAP 901 case 1080046 : 902 case 2321393 : return LVL_TR3_CUT_12; 903 // TR4 904 case 3007155 : return LVL_TR4_TITLE; 905 case 4034313 : return LVL_TR4_ANGKOR1; 906 case 4343019 : return LVL_TR4_ANG_RACE; 907 case 3715110 : return LVL_TR4_SETTOMB1; 908 case 3868566 : return LVL_TR4_SETTOMB2; 909 case 3600478 : return LVL_TR4_JEEPCHAS; 910 case 4826055 : return LVL_TR4_JEEPCHS2; 911 case 4773596 : return LVL_TR4_KARNAK1; 912 case 4882065 : return LVL_TR4_HALL; 913 case 5021843 : return LVL_TR4_LAKE; 914 case 4409367 : return LVL_TR4_SEMER; 915 case 4294398 : return LVL_TR4_SEMER2; 916 case 3246177 : return LVL_TR4_TRAIN; 917 case 4007946 : return LVL_TR4_ALEXHUB; 918 case 4735043 : return LVL_TR4_ALEXHUB2; 919 case 4549992 : return LVL_TR4_PALACES; 920 case 4779709 : return LVL_TR4_PALACES2; 921 case 4570232 : return LVL_TR4_CSPLIT1; 922 case 4838007 : return LVL_TR4_CSPLIT2; 923 case 4606099 : return LVL_TR4_LIBRARY; 924 case 3240517 : return LVL_TR4_LIBEND; 925 case 5013974 : return LVL_TR4_BIKEBIT; 926 case 4260336 : return LVL_TR4_NUTRENCH; 927 case 4989001 : return LVL_TR4_CORTYARD; 928 case 3970465 : return LVL_TR4_LOWSTRT; 929 case 4725022 : return LVL_TR4_HIGHSTRT; 930 case 4776907 : return LVL_TR4_CITNEW; 931 case 5011064 : return LVL_TR4_JOBY1A; 932 case 4544163 : return LVL_TR4_JOBY1B; 933 case 4839409 : return LVL_TR4_JOBY2; 934 case 4433722 : return LVL_TR4_JOBY3A; 935 case 5141026 : return LVL_TR4_JOBY3B; 936 case 4786641 : return LVL_TR4_JOBY4A; 937 case 4401690 : return LVL_TR4_JOBY4B; 938 case 4999677 : return LVL_TR4_JOBY4C; 939 case 3741579 : return LVL_TR4_JOBY5A; 940 case 4623726 : return LVL_TR4_JOBY5B; 941 case 4398142 : return LVL_TR4_JOBY5C; 942 } 943 944 if (name) { 945 // skip directory path 946 int start = 0; 947 for (int i = int(strlen(name)) - 1; i >= 0; i--) 948 if (name[i] == '/' || name[i] == '\\') { 949 start = i + 1; 950 break; 951 } 952 // skip file extension 953 char buf[255]; 954 strcpy(buf, name + start); 955 char *ext = NULL; 956 for (int i = 0; i < int(strlen(buf)); i++) 957 if (buf[i] == '.') { 958 buf[i] = 0; 959 ext = buf + i + 1; 960 break; 961 } 962 // compare with standard levels 963 // TODO: fix TITLE (2-3), HOUSE (3), CUTx (2-3) 964 for (int i = 0; i < LVL_MAX; i++) 965 if (!strcmp(buf, LEVEL_INFO[i].name)) { 966 LevelID id = LevelID(i); 967 if (ext) { 968 version = getGameVersionByLevel(id); 969 if (!strcmp("PSX", ext)) { 970 version = Version(version | VER_PSX); 971 } else if (!strcmp("SAT", ext)) { 972 version = Version(version | VER_SAT); 973 } else { 974 version = Version(version | VER_PC); 975 } 976 } 977 return id; 978 } 979 } 980 981 return LVL_CUSTOM; 982 } 983 getTitleId(Version version)984 LevelID getTitleId(Version version) { 985 switch (version & VER_VERSION) { 986 case VER_TR1 : return LVL_TR1_TITLE; 987 case VER_TR2 : return LVL_TR2_TITLE; 988 case VER_TR3 : return LVL_TR3_TITLE; 989 case VER_TR4 : return LVL_TR4_TITLE; 990 } 991 return LVL_TR1_TITLE; 992 ASSERT(false); 993 } 994 getHomeId(Version version)995 LevelID getHomeId(Version version) { 996 switch (version & VER_VERSION) { 997 case VER_TR1 : return LVL_TR1_GYM; 998 case VER_TR2 : return LVL_TR2_ASSAULT; 999 case VER_TR3 : return LVL_TR3_HOUSE; 1000 case VER_TR4 : return LVL_MAX; 1001 } 1002 ASSERT(false); 1003 return LVL_MAX; 1004 } 1005 getStartId(Version version)1006 LevelID getStartId(Version version) { 1007 switch (version & VER_VERSION) { 1008 case VER_TR1 : return LVL_TR1_1; 1009 case VER_TR2 : return LVL_TR2_WALL; 1010 case VER_TR3 : return LVL_TR3_JUNGLE; 1011 case VER_TR4 : return LVL_TR4_ANGKOR1; 1012 } 1013 ASSERT(false); 1014 return LVL_MAX; 1015 } 1016 getEndId(Version version)1017 LevelID getEndId(Version version) { 1018 switch (version & VER_VERSION) { 1019 case VER_TR1 : return LVL_TR1_10C; 1020 case VER_TR2 : return LVL_TR2_HOUSE; 1021 case VER_TR3 : return LVL_TR3_CHAMBER; 1022 case VER_TR4 : return LVL_TR4_JOBY5C; 1023 } 1024 ASSERT(false); 1025 return LVL_MAX; 1026 } 1027 isCutsceneLevel(LevelID id)1028 bool isCutsceneLevel(LevelID id) { 1029 return id == LVL_TR1_CUT_1 || id == LVL_TR1_CUT_2 || id == LVL_TR1_CUT_3 || id == LVL_TR1_CUT_4 || 1030 id == LVL_TR2_CUT_1 || id == LVL_TR2_CUT_2 || id == LVL_TR2_CUT_3 || id == LVL_TR2_CUT_4 || 1031 id == LVL_TR3_CUT_1 || id == LVL_TR3_CUT_2 || id == LVL_TR3_CUT_3 || id == LVL_TR3_CUT_4 || 1032 id == LVL_TR3_CUT_5 || id == LVL_TR3_CUT_6 || id == LVL_TR3_CUT_7 || id == LVL_TR3_CUT_8 || 1033 id == LVL_TR3_CUT_9 || id == LVL_TR3_CUT_11 || id == LVL_TR3_CUT_12; 1034 } 1035 isTitleLevel(LevelID id)1036 bool isTitleLevel(LevelID id) { 1037 return id == LVL_TR1_TITLE || 1038 id == LVL_TR2_TITLE || 1039 id == LVL_TR3_TITLE || 1040 id == LVL_TR4_TITLE; 1041 } 1042 isEmptyLevel(LevelID id)1043 bool isEmptyLevel(LevelID id) { 1044 return id == TR::LVL_TR1_10A || id == TR::LVL_TR2_RIG || id == TR::LVL_TR3_COMPOUND; 1045 } 1046 getGameVersion()1047 Version getGameVersion() { 1048 useEasyStart = true; 1049 if (Stream::existsContent("DATA/GYM.PHD") || Stream::existsContent("GYM.PHD")) 1050 return VER_TR1_PC; 1051 if (Stream::existsContent("PSXDATA/GYM.PSX")) 1052 return VER_TR1_PSX; 1053 if (Stream::existsContent("DATA/GYM.SAT")) 1054 return VER_TR1_SAT; 1055 1056 if (Stream::existsContent("data/ASSAULT.TR2") || Stream::existsContent("assault.TR2")) 1057 return VER_TR2_PC; 1058 if (Stream::existsContent("DATA/ASSAULT.PSX")) 1059 return VER_TR2_PSX; 1060 1061 if (Stream::existsContent("data/JUNGLE.TR2")) 1062 return VER_TR3_PC; 1063 1064 if (Stream::existsContent("DATA/JUNGLE.PSX")) 1065 return VER_TR3_PSX; 1066 1067 if (Stream::existsContent("data/angkor1.tr4")) 1068 return VER_TR4_PC; 1069 1070 useEasyStart = false; 1071 return VER_UNKNOWN; 1072 } 1073 getGameLevelFile(char * dst,Version version,LevelID id)1074 void getGameLevelFile(char *dst, Version version, LevelID id) { 1075 if (useEasyStart) { 1076 switch (version) { 1077 case VER_TR1_PC : 1078 sprintf(dst, "DATA/%s.PHD", LEVEL_INFO[id].name); 1079 if (Stream::existsContent(dst)) break; 1080 sprintf(dst, "%s.PHD", LEVEL_INFO[id].name); 1081 break; 1082 case VER_TR1_PSX : sprintf(dst, "PSXDATA/%s.PSX", LEVEL_INFO[id].name); break; 1083 case VER_TR1_SAT : sprintf(dst, "DATA/%s.SAT", LEVEL_INFO[id].name); break; 1084 case VER_TR2_PC : { // oh FFFFUUUUUUCKing CaTaComB.Tr2! 1085 if (id == LVL_TR2_VENICE || id == LVL_TR2_CUT_2 || id == LVL_TR2_PLATFORM || id == LVL_TR2_CUT_3 || id == LVL_TR2_UNWATER || 1086 id == LVL_TR2_KEEL || id == LVL_TR2_LIVING || id == LVL_TR2_DECK || id == LVL_TR2_CATACOMB || id == LVL_TR2_ICECAVE || 1087 id == LVL_TR2_CUT_4 || id == LVL_TR2_XIAN || id == LVL_TR2_HOUSE) { 1088 char buf[64]; 1089 strcpy(buf, LEVEL_INFO[id].name); 1090 StrUtils::toLower(buf); 1091 sprintf(dst, "DATA/%s.TR2", buf); 1092 } else if (id == LVL_TR2_TITLE) { 1093 sprintf(dst, "DATA/%s.tr2", LEVEL_INFO[id].name); 1094 } else if (id == LVL_TR2_EMPRTOMB) { 1095 strcpy(dst, "DATA/Emprtomb.tr2"); 1096 } else { 1097 sprintf(dst, "DATA/%s.TR2", LEVEL_INFO[id].name); 1098 } 1099 if (Stream::existsContent(dst)) break; 1100 strcpy(dst, LEVEL_INFO[id].name); 1101 StrUtils::toLower(dst); 1102 strcat(dst, ".TR2"); 1103 break; 1104 } 1105 case VER_TR2_PSX : sprintf(dst, "DATA/%s.PSX", LEVEL_INFO[id].name); break; 1106 case VER_TR3_PC : sprintf(dst, isCutsceneLevel(id) ? "cuts/%s.TR2" : "data/%s.TR2", LEVEL_INFO[id].name); break; 1107 case VER_TR3_PSX : sprintf(dst, isCutsceneLevel(id) ? "CUTS/%s.PSX" : "DATA/%s.PSX", LEVEL_INFO[id].name); break; 1108 case VER_TR4_PC : sprintf(dst, "DATA/%s.tr4", LEVEL_INFO[id].name); break; 1109 default : ASSERT(false); 1110 } 1111 } else { 1112 strcpy(dst, "level/"); 1113 if ((version & VER_TR1) || version == VER_UNKNOWN) strcat(dst, "1/"); 1114 if (version & VER_TR2) strcat(dst, "2/"); 1115 if (version & VER_TR3) strcat(dst, "3/"); 1116 strcat(dst, LEVEL_INFO[id].name); 1117 1118 #ifdef _OS_WEB 1119 strcat(dst, ".PSX"); 1120 #else 1121 switch (version) { 1122 case VER_TR1_PC : strcat(dst, ".PHD"); break; 1123 case VER_TR2_PC : 1124 case VER_TR3_PC : strcat(dst, ".TR2"); break; 1125 case VER_TR1_PSX : 1126 case VER_TR2_PSX : 1127 case VER_TR3_PSX : strcat(dst, ".PSX"); break; 1128 case VER_TR1_SAT : strcat(dst, ".SAT"); break; 1129 case VER_UNKNOWN : 1130 if (Stream::existsContent("level/1/TITLE.PSX")) { 1131 strcpy(dst, "level/1/TITLE.PSX"); 1132 return; 1133 } 1134 if (Stream::existsContent("level/1/TITLE.PHD")) { 1135 strcpy(dst, "level/1/TITLE.PHD"); 1136 return; 1137 } 1138 if (Stream::existsContent("level/1/TITLE.SAT")) { 1139 strcpy(dst, "level/1/TITLE.SAT"); 1140 return; 1141 } 1142 if (Stream::existsContent("level/2/TITLE.TR2")) { 1143 strcpy(dst, "level/2/TITLE.TR2"); 1144 return; 1145 } 1146 if (Stream::existsContent("level/2/TITLE.PSX")) { 1147 strcpy(dst, "level/2/TITLE.PSX"); 1148 return; 1149 } 1150 if (Stream::existsContent("level/3/TITLE.TR2")) { 1151 strcpy(dst, "level/3/TITLE.TR2"); 1152 return; 1153 } 1154 if (Stream::existsContent("level/3/TITLE.PSX")) { 1155 strcpy(dst, "level/3/TITLE.PSX"); 1156 return; 1157 } 1158 ASSERT(false); // 1159 break; 1160 default : ASSERT(false); 1161 } 1162 #endif 1163 } 1164 } 1165 getGameSoundsFile(Version version)1166 const char* getGameSoundsFile(Version version) { 1167 if (version == VER_TR2_PC) { 1168 CHECK_FILE("data/MAIN.SFX"); // PC 1169 CHECK_FILE("MAIN.SFX"); // Android 1170 return "audio/2/MAIN.SFX"; // Web 1171 } 1172 1173 if (version == VER_TR3_PC) { 1174 CHECK_FILE("data/MAIN.SFX"); // PC 1175 return "audio/3/MAIN.SFX"; // Web 1176 } 1177 1178 ASSERT(false); 1179 return NULL; 1180 } 1181 remapTrack(Version version,uint8 track)1182 uint8 remapTrack(Version version, uint8 track) { 1183 static const uint8 TR1_TRACK_MAPPING[] = { 1184 2, 2, 2, 11, 12, 3, 13, 14, 15, 16, 17, 18, 19, 60, 20, 21, 22, 23, 24, 25, 26, 27, 1185 7, 8, 9, 10, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 1186 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 28, 4, 5, 6 1187 }; 1188 1189 static const uint8 TR2_TRACK_MAPPING[] = { 1190 2, 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 19, 20, 1191 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 1192 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61 1193 }; 1194 1195 if (version & VER_TR1) { 1196 ASSERT(track < COUNT(TR1_TRACK_MAPPING)); 1197 return TR1_TRACK_MAPPING[track]; 1198 } 1199 1200 if (version & VER_TR2) { 1201 ASSERT(track < COUNT(TR2_TRACK_MAPPING)); 1202 return TR2_TRACK_MAPPING[track]; 1203 } 1204 1205 return track; 1206 } 1207 checkTrack(const char * pre,char * name)1208 bool checkTrack(const char *pre, char *name) { 1209 static const char *fmt[] = { ".ogg", ".mp3", ".wav" }; 1210 const char *lng[] = { "", "", LANG_PREFIXES }; 1211 1212 int start = 1; 1213 if (Core::settings.audio.language != 0) { 1214 start = 0; 1215 lng[start] = lng[Core::settings.audio.language + 2]; 1216 } 1217 1218 char buf[64]; 1219 for (int f = 0; f < COUNT(fmt); f++) 1220 for (int l = start; l < COUNT(lng); l++) { 1221 strcpy(buf, pre); 1222 strcat(buf, name); 1223 strcat(buf, lng[l]); 1224 strcat(buf, fmt[f]); 1225 if (Stream::existsContent(buf)) { 1226 strcpy(name, buf); 1227 return true; 1228 } 1229 } 1230 1231 return false; 1232 } 1233 getVideoSubs(LevelID id)1234 StringID getVideoSubs(LevelID id) { 1235 switch (id) { 1236 // TR1 1237 case LVL_TR1_TITLE : return isGameEnded ? STR_EMPTY : STR_TR1_SUB_CAFE; 1238 case LVL_TR1_4 : return STR_TR1_SUB_LIFT; 1239 case LVL_TR1_10A : return STR_TR1_SUB_CANYON; 1240 case LVL_TR1_CUT_4 : return STR_TR1_SUB_PRISON; 1241 default : return STR_EMPTY; 1242 } 1243 } 1244 getVideoTrack(LevelID id,Stream::Callback callback,void * userData)1245 bool getVideoTrack(LevelID id, Stream::Callback callback, void *userData) { 1246 char title[32]; 1247 1248 const char *str = NULL; 1249 switch (id) { 1250 // TR1 1251 case LVL_TR1_TITLE : str = isGameEnded ? NULL : "CAFE"; break; 1252 case LVL_TR1_4 : str = "LIFT"; break; 1253 case LVL_TR1_10A : str = "CANYON"; break; 1254 case LVL_TR1_CUT_4 : str = "PRISON"; break; 1255 // TR2 TODO 1256 // TR3 TODO 1257 default : return false; 1258 } 1259 1260 sprintf(title, "track_%s", str); 1261 if (!checkTrack("", title) && !checkTrack("audio/1/", title) && !checkTrack("audio/", title)) { 1262 return false; 1263 } 1264 1265 new Stream(title, callback, userData); 1266 return true; 1267 } 1268 getSubs(Version version,int track)1269 StringID getSubs(Version version, int track) { 1270 if ((version & VER_TR1) && (track >= 22 && track <= 56 && track != 24)) { 1271 return StringID(STR_TR1_SUB_22 + (track - 22)); 1272 } 1273 // TR2, TR3 TODO 1274 return STR_EMPTY; 1275 } 1276 checkWebDub(Version version,int track)1277 bool checkWebDub(Version version, int track) { 1278 if (getSubs(version, track) != STR_EMPTY) { 1279 int lang = Core::settings.audio.language + STR_LANG_EN; 1280 return lang == STR_LANG_EN || lang == STR_LANG_DE || lang == STR_LANG_FR || lang == STR_LANG_RU || lang == STR_LANG_JA; 1281 } 1282 return false; 1283 } 1284 getGameTrack(Version version,int track,Stream::Callback callback,void * userData)1285 void getGameTrack(Version version, int track, Stream::Callback callback, void *userData) { 1286 char title[64]; 1287 if (useEasyStart) { 1288 switch (version) { 1289 case VER_TR1_SAT : 1290 case VER_TR1_PC : 1291 case VER_TR1_PSX : 1292 sprintf(title, "track_%02d", track); 1293 if (!checkTrack("", title) && !checkTrack("audio/1/", title) && !checkTrack("audio/", title)) { 1294 track = remapTrack(version, track); 1295 sprintf(title, "%03d", track); 1296 if (!checkTrack("", title) && !checkTrack("audio/1/", title) && !checkTrack("audio/", title)) { 1297 callback(NULL, userData); 1298 return; 1299 } 1300 } 1301 break; 1302 case VER_TR2_PC : 1303 case VER_TR2_PSX : 1304 //if (Stream::existsContent("audio/cdaudio.mp3")) { 1305 // callback(Sound::openCDAudioMP3("audio/cdaudio.dat", "audio/cdaudio.mp3", track), userData); 1306 // return; 1307 //} 1308 track = remapTrack(version, track); 1309 sprintf(title, "track_%02d", track); 1310 if (!checkTrack("", title) && !checkTrack("audio/2/", title) && !checkTrack("audio/", title)) { 1311 callback(NULL, userData); 1312 return; 1313 } 1314 break; 1315 case VER_TR3_PC : 1316 case VER_TR3_PSX : 1317 callback(Sound::openCDAudioWAD("audio/cdaudio.wad", track), userData); 1318 return; 1319 case VER_TR4_PC : 1320 strcpy(title, TRACK_LIST_TR4[track]); 1321 if (!checkTrack("audio/", title)) { 1322 callback(NULL, userData); 1323 } 1324 break; 1325 default : return; 1326 } 1327 } else { 1328 switch (version) { 1329 case VER_TR1_SAT : 1330 case VER_TR1_PC : 1331 case VER_TR1_PSX : { 1332 if (TR::checkWebDub(version, track)) { 1333 const char *lng[] = { LANG_PREFIXES }; 1334 sprintf(title, "audio/1/track_%02d%s.ogg", track, lng[Core::settings.audio.language]); 1335 } else { 1336 if (TR::getSubs(version, track) != STR_EMPTY) { 1337 sprintf(title, "audio/1/track_%02d_EN.ogg", track); 1338 } else { 1339 sprintf(title, "audio/1/track_%02d.ogg", track); 1340 } 1341 } 1342 #ifndef _OS_WEB 1343 if (Stream::existsContent(title)) 1344 break; 1345 track = remapTrack(version, track); 1346 sprintf(title, "audio/1/%03d.ogg", track); 1347 #endif 1348 break; 1349 } 1350 case VER_TR2_PC : 1351 case VER_TR2_PSX : 1352 track = remapTrack(version, track); 1353 sprintf(title, "audio/2/track_%02d.ogg", track); 1354 break; 1355 case VER_TR3_PC : 1356 case VER_TR3_PSX : 1357 #ifndef _OS_WEB 1358 callback(Sound::openCDAudioWAD("audio/3/cdaudio.wad", track), userData); 1359 return; 1360 #else 1361 sprintf(title, "audio/3/track_%02d.wav", track); 1362 #endif 1363 break; 1364 default : return; 1365 } 1366 } 1367 1368 new Stream(title, callback, userData); 1369 } 1370 getGameScreen(LevelID id)1371 const char* getGameScreen(LevelID id) { 1372 switch (id) { 1373 // TR1 1374 case LVL_TR1_TITLE : 1375 CHECK_FILE("TITLEH.png"); // Android 1376 CHECK_FILE("DATA/TITLEH.PCX"); // PC 1377 CHECK_FILE("DELDATA/AMERTIT.RAW"); // PSX 1378 CHECK_FILE("DELDATA/JAPTIT.RAW"); // PSX JAP 1379 CHECK_FILE("BINDATA/USATIT.BIN"); // SEGA 1380 CHECK_FILE("BINDATA/TITLE1.BIN"); // SEGA 1381 return "level/1/AMERTIT.PNG"; // WEB 1382 case LVL_TR1_GYM : 1383 CHECK_FILE("DELDATA/GYMLOAD.RAW"); 1384 CHECK_FILE("BINDATA/GYM224.BIN"); 1385 CHECK_FILE("BINDATA/GYM.BIN"); 1386 return "level/1/GYMLOAD.PNG"; 1387 case LVL_TR1_1 : 1388 case LVL_TR1_2 : 1389 case LVL_TR1_3A : 1390 case LVL_TR1_3B : 1391 CHECK_FILE("DELDATA/AZTECLOA.RAW"); 1392 CHECK_FILE("BINDATA/AZTEC224.BIN"); 1393 CHECK_FILE("BINDATA/AZTEC.BIN"); 1394 return "level/1/AZTECLOA.PNG"; 1395 case LVL_TR1_4 : 1396 case LVL_TR1_5 : 1397 case LVL_TR1_6 : 1398 case LVL_TR1_7A : 1399 case LVL_TR1_7B : 1400 CHECK_FILE("DELDATA/GREEKLOA.RAW"); 1401 CHECK_FILE("BINDATA/GREEK224.BIN"); 1402 CHECK_FILE("BINDATA/GREEK.BIN"); 1403 return "level/1/GREEKLOA.PNG"; 1404 case LVL_TR1_8A : 1405 case LVL_TR1_8B : 1406 case LVL_TR1_8C : 1407 CHECK_FILE("DELDATA/EGYPTLOA.RAW"); 1408 CHECK_FILE("BINDATA/EGYPT224.BIN"); 1409 CHECK_FILE("BINDATA/EGYPT.BIN"); 1410 return "level/1/EGYPTLOA.PNG"; 1411 case LVL_TR1_10A : 1412 case LVL_TR1_10B : 1413 case LVL_TR1_10C : 1414 CHECK_FILE("DELDATA/ATLANLOA.RAW"); 1415 CHECK_FILE("BINDATA/ATLAN224.BIN"); 1416 CHECK_FILE("BINDATA/ATLAN.BIN"); 1417 return "level/1/ATLANLOA.PNG"; 1418 // TR2 1419 case LVL_TR2_TITLE : 1420 CHECK_FILE("TITLE.png"); // Android 1421 CHECK_FILE("data/TITLE.PCX"); // PC 1422 CHECK_FILE("pix/title.pcx"); // PC 1423 CHECK_FILE("PIXUS/TITLEUS.RAW"); // PSX US 1424 CHECK_FILE("PIXJAP/TITLEJAP.RAW"); // PSX US 1425 return "level/2/TITLEUS.PNG"; // WEB 1426 case LVL_TR2_ASSAULT : 1427 case LVL_TR2_HOUSE : 1428 CHECK_FILE("PIX/MANSION.RAW"); 1429 return "level/2/MANSION.PNG"; 1430 case LVL_TR2_WALL : 1431 case LVL_TR2_EMPRTOMB : 1432 case LVL_TR2_FLOATING : 1433 case LVL_TR2_XIAN : 1434 CHECK_FILE("PIX/CHINA.RAW"); 1435 return "level/2/CHINA.PNG"; 1436 case LVL_TR2_BOAT : 1437 case LVL_TR2_VENICE : 1438 case LVL_TR2_OPERA : 1439 CHECK_FILE("PIX/VENICE.RAW"); 1440 return "level/2/VENICE.PNG"; 1441 case LVL_TR2_RIG : 1442 case LVL_TR2_PLATFORM : 1443 CHECK_FILE("PIX/RIG.RAW"); 1444 return "level/2/RIG.PNG"; 1445 case LVL_TR2_UNWATER : 1446 case LVL_TR2_KEEL : 1447 case LVL_TR2_LIVING : 1448 case LVL_TR2_DECK : 1449 CHECK_FILE("PIX/TITAN.RAW"); 1450 return "level/2/TITAN.PNG"; 1451 case LVL_TR2_SKIDOO : 1452 case LVL_TR2_MONASTRY : 1453 case LVL_TR2_CATACOMB : 1454 case LVL_TR2_ICECAVE : 1455 CHECK_FILE("PIX/TIBET.RAW"); 1456 return "level/2/TIBET.PNG"; 1457 // TR3 1458 case LVL_TR3_TITLE : 1459 CHECK_FILE("pix/TITLEUK.BMP"); // PC 1460 CHECK_FILE("PIXUS/TITLEUS.RAW"); // PSX 1461 CHECK_FILE("PIXJAP/TITLEJAP.RAW"); // PSX 1462 return "level/3/TITLEUK.PNG"; // WEB 1463 case LVL_TR3_HOUSE : 1464 CHECK_FILE("pix/HOUSE.BMP"); 1465 CHECK_FILE("PIX/HOUSE.RAW"); 1466 return "level/3/HOUSE.PNG"; 1467 case LVL_TR3_JUNGLE : 1468 case LVL_TR3_TEMPLE : 1469 case LVL_TR3_QUADCHAS : 1470 case LVL_TR3_TONYBOSS : 1471 CHECK_FILE("pix/INDIA.BMP"); 1472 CHECK_FILE("PIX/INDIA.RAW"); 1473 return "level/3/INDIA.PNG"; 1474 case LVL_TR3_SHORE : 1475 case LVL_TR3_CRASH : 1476 case LVL_TR3_RAPIDS : 1477 case LVL_TR3_TRIBOSS : 1478 CHECK_FILE("pix/SOUTHPAC.BMP"); 1479 CHECK_FILE("PIX/SOUTHPAC.RAW"); 1480 return "level/3/SOUTHPAC.PNG"; 1481 case LVL_TR3_ROOFS : 1482 case LVL_TR3_SEWER : 1483 case LVL_TR3_TOWER : 1484 case LVL_TR3_OFFICE : 1485 case LVL_TR3_STPAUL : 1486 CHECK_FILE("pix/LONDON.BMP"); 1487 CHECK_FILE("PIX/LONDON.RAW"); 1488 return "level/3/LONDON.PNG"; 1489 case LVL_TR3_NEVADA : 1490 case LVL_TR3_COMPOUND : 1491 case LVL_TR3_AREA51 : 1492 CHECK_FILE("pix/NEVADA.BMP"); 1493 CHECK_FILE("PIX/NEVADA.RAW"); 1494 return "level/3/NEVADA.PNG"; 1495 case LVL_TR3_ANTARC : 1496 case LVL_TR3_MINES : 1497 case LVL_TR3_CITY : 1498 case LVL_TR3_CHAMBER : 1499 CHECK_FILE("pix/ANTARC.BMP"); 1500 CHECK_FILE("PIX/ANTARC.RAW"); 1501 return "level/3/ANTARC.PNG"; 1502 1503 default : return NULL; 1504 } 1505 } 1506 getGameLogo(Version version)1507 const char* getGameLogo(Version version) { 1508 if (version & VER_TR1) { 1509 CHECK_FILE("FMV/CORELOGO.FMV"); 1510 CHECK_FILE("FMV/CORE.RPL"); 1511 CHECK_FILE("FMV/CORELOGO.CPK"); 1512 CHECK_FILE("video/1/CORELOGO.FMV"); 1513 CHECK_FILE("video/1/CORE.RPL"); 1514 } 1515 1516 if (version & VER_TR2) { 1517 CHECK_FILE("FMV/LOGO.FMV"); 1518 CHECK_FILE("FMV/LOGO.RPL"); 1519 CHECK_FILE("video/2/LOGO.FMV"); 1520 CHECK_FILE("video/2/LOGO.RPL"); 1521 } 1522 1523 if (version & VER_TR3) { 1524 CHECK_FILE("FMV/LOGO.FMV"); 1525 CHECK_FILE("fmv/logo.rpl"); 1526 CHECK_FILE("video/3/LOGO.FMV"); 1527 CHECK_FILE("video/3/logo.rpl"); 1528 } 1529 1530 return NULL; 1531 } 1532 getGameVideo(LevelID id)1533 const char* getGameVideo(LevelID id) { 1534 switch (id) { 1535 // TR1 1536 case LVL_TR1_TITLE : 1537 if (isGameEnded) { 1538 CHECK_FILE("FMV/END.FMV"); 1539 CHECK_FILE("FMV/END.RPL"); 1540 CHECK_FILE("FMV/END.CPK"); 1541 CHECK_FILE("video/1/END.FMV"); 1542 CHECK_FILE("video/1/END.RPL"); 1543 CHECK_FILE("video/1/END.CPK"); 1544 } else { 1545 CHECK_FILE("FMV/CAFE.FMV"); 1546 CHECK_FILE("FMV/CAFE.RPL"); 1547 CHECK_FILE("FMV/CAFE.CPK"); 1548 CHECK_FILE("video/1/CAFE.FMV"); 1549 CHECK_FILE("video/1/CAFE.RPL"); 1550 CHECK_FILE("video/1/CAFE.CPK"); 1551 } 1552 break; 1553 case LVL_TR1_GYM : 1554 CHECK_FILE("FMV/MANSION.FMV"); 1555 CHECK_FILE("FMV/MANSION.RPL"); 1556 CHECK_FILE("FMV/MANSION.CPK"); 1557 CHECK_FILE("video/1/MANSION.FMV"); 1558 CHECK_FILE("video/1/MANSION.RPL"); 1559 CHECK_FILE("video/1/MANSION.CPK"); 1560 break; 1561 case LVL_TR1_1 : 1562 CHECK_FILE("FMV/SNOW.FMV"); 1563 CHECK_FILE("FMV/SNOW.RPL"); 1564 CHECK_FILE("FMV/SNOW.CPK"); 1565 CHECK_FILE("video/1/SNOW.FMV"); 1566 CHECK_FILE("video/1/SNOW.RPL"); 1567 CHECK_FILE("video/1/SNOW.CPK"); 1568 break; 1569 case LVL_TR1_4 : 1570 CHECK_FILE("FMV/LIFT.FMV"); 1571 CHECK_FILE("FMV/LIFT.RPL"); 1572 CHECK_FILE("FMV/LIFT.CPK"); 1573 CHECK_FILE("video/1/LIFT.FMV"); 1574 CHECK_FILE("video/1/LIFT.RPL"); 1575 CHECK_FILE("video/1/LIFT.CPK"); 1576 break; 1577 case LVL_TR1_8A : 1578 CHECK_FILE("FMV/VISION.FMV"); 1579 CHECK_FILE("FMV/VISION.RPL"); 1580 CHECK_FILE("FMV/VISION.CPK"); 1581 CHECK_FILE("video/1/VISION.FMV"); 1582 CHECK_FILE("video/1/VISION.RPL"); 1583 CHECK_FILE("video/1/VISION.CPK"); 1584 break; 1585 case LVL_TR1_10A : 1586 CHECK_FILE("FMV/CANYON.FMV"); 1587 CHECK_FILE("FMV/CANYON.RPL"); 1588 CHECK_FILE("FMV/CANYON.CPK"); 1589 CHECK_FILE("video/1/CANYON.FMV"); 1590 CHECK_FILE("video/1/CANYON.RPL"); 1591 CHECK_FILE("video/1/CANYON.CPK"); 1592 break; 1593 case LVL_TR1_10B : 1594 CHECK_FILE("FMV/PYRAMID.FMV"); 1595 CHECK_FILE("FMV/PYRAMID.RPL"); 1596 CHECK_FILE("FMV/PYRAMID.CPK"); 1597 CHECK_FILE("video/1/PYRAMID.FMV"); 1598 CHECK_FILE("video/1/PYRAMID.RPL"); 1599 CHECK_FILE("video/1/PYRAMID.CPK"); 1600 break; 1601 case LVL_TR1_CUT_4 : 1602 CHECK_FILE("FMV/PRISON.FMV"); 1603 CHECK_FILE("FMV/PRISON.RPL"); 1604 CHECK_FILE("FMV/PRISON.CPK"); 1605 CHECK_FILE("video/1/PRISON.FMV"); 1606 CHECK_FILE("video/1/PRISON.RPL"); 1607 CHECK_FILE("video/1/PRISON.CPK"); 1608 break; 1609 case LVL_TR1_EGYPT : 1610 CHECK_FILE("FMV/END.FMV"); 1611 CHECK_FILE("FMV/END.RPL"); 1612 CHECK_FILE("FMV/END.CPK"); 1613 CHECK_FILE("video/1/END.FMV"); 1614 CHECK_FILE("video/1/END.RPL"); 1615 CHECK_FILE("video/1/END.CPK"); 1616 break; 1617 // TR2 1618 case LVL_TR2_TITLE : 1619 CHECK_FILE("FMV/ANCIENT.FMV"); 1620 CHECK_FILE("fmv/ANCIENT.RPL"); 1621 CHECK_FILE("video/2/ANCIENT.FMV"); 1622 CHECK_FILE("video/2/ANCIENT.RPL"); 1623 break; 1624 case LVL_TR2_WALL : 1625 CHECK_FILE("FMV/MODERN.FMV"); 1626 CHECK_FILE("fmv/MODERN.RPL"); 1627 CHECK_FILE("video/2/MODERN.FMV"); 1628 CHECK_FILE("video/2/MODERN.RPL"); 1629 break; 1630 case LVL_TR2_RIG : 1631 CHECK_FILE("FMV/LANDING.FMV"); 1632 CHECK_FILE("fmv/LANDING.RPL"); 1633 CHECK_FILE("video/2/LANDING.FMV"); 1634 CHECK_FILE("video/2/LANDING.RPL"); 1635 break; 1636 case LVL_TR2_UNWATER : 1637 CHECK_FILE("FMV/MS.FMV"); 1638 CHECK_FILE("fmv/MS.RPL"); 1639 CHECK_FILE("video/2/MS.FMV"); 1640 CHECK_FILE("video/2/MS.RPL"); 1641 break; 1642 case LVL_TR2_SKIDOO : 1643 CHECK_FILE("FMV/CRASH.FMV"); 1644 CHECK_FILE("fmv/CRASH.RPL"); 1645 CHECK_FILE("video/2/CRASH.FMV"); 1646 CHECK_FILE("video/2/CRASH.RPL"); 1647 break; 1648 case LVL_TR2_EMPRTOMB : 1649 CHECK_FILE("FMV/JEEP.FMV"); 1650 CHECK_FILE("fmv/JEEP.RPL"); 1651 CHECK_FILE("video/2/JEEP.FMV"); 1652 CHECK_FILE("video/2/JEEP.RPL"); 1653 break; 1654 case LVL_TR2_HOUSE : 1655 CHECK_FILE("FMV/END.FMV"); 1656 CHECK_FILE("fmv/END.RPL"); 1657 CHECK_FILE("video/2/END.FMV"); 1658 CHECK_FILE("video/2/END.RPL"); 1659 break; 1660 // TR3 1661 case LVL_TR3_TITLE : 1662 if (isGameEnded) { 1663 CHECK_FILE("FMV/END.FMV"); 1664 CHECK_FILE("fmv/Endgame.rpl"); 1665 CHECK_FILE("video/3/END.FMV"); 1666 CHECK_FILE("video/3/Endgame.rpl"); 1667 } else { 1668 CHECK_FILE("FMV/INTRO.FMV"); 1669 CHECK_FILE("fmv/Intr_Eng.rpl"); 1670 CHECK_FILE("video/3/INTRO.FMV"); 1671 CHECK_FILE("video/3/Intr_Eng.rpl"); 1672 } 1673 break; 1674 case LVL_TR3_SHORE : 1675 CHECK_FILE("FMV/LAGOON.FMV"); 1676 CHECK_FILE("fmv/Sail_Eng.rpl"); 1677 CHECK_FILE("video/3/LAGOON.FMV"); 1678 CHECK_FILE("video/3/Sail_Eng.rpl"); 1679 break; 1680 case LVL_TR3_ANTARC : 1681 CHECK_FILE("FMV/HUEY.FMV"); 1682 CHECK_FILE("fmv/Crsh_Eng.rpl"); 1683 CHECK_FILE("video/3/HUEY.FMV"); 1684 CHECK_FILE("video/3/Crsh_Eng.rpl"); 1685 break; 1686 case LVL_TR3_STPAUL : 1687 CHECK_FILE("FMV/END.FMV"); 1688 CHECK_FILE("fmv/Endgame.rpl"); 1689 CHECK_FILE("video/3/END.FMV"); 1690 CHECK_FILE("video/3/Endgame.rpl"); 1691 break; 1692 default : ; 1693 } 1694 return NULL; 1695 } 1696 1697 #define FOG_DIST (1.0f / (18 * 1024)) 1698 #define FOG_NONE vec4(0.0f, 0.0f, 0.0f, 0.0f) 1699 #define FOG_BLACK vec4(0.0f, 0.0f, 0.0f, FOG_DIST) 1700 #define FOG_SANDY vec4(0.2f, 0.1f, 0.0f, FOG_DIST) 1701 #define FOG_GREEN vec4(0.0f, 0.1f, 0.0f, FOG_DIST) 1702 #define FOG_RED vec4(0.2f, 0.0f, 0.0f, FOG_DIST) 1703 #define FOG_MIST vec4(0.25f, 0.2f, 0.15f, FOG_DIST) 1704 getFogParams(LevelID id)1705 vec4 getFogParams(LevelID id) { 1706 switch (id) { 1707 case LVL_TR1_1 : 1708 case LVL_TR1_2 : return FOG_BLACK; 1709 case LVL_TR1_3A : return FOG_MIST; 1710 case LVL_TR1_3B : 1711 case LVL_TR1_CUT_1 : return FOG_BLACK; 1712 case LVL_TR1_4 : 1713 case LVL_TR1_5 : 1714 case LVL_TR1_6 : return FOG_SANDY; 1715 case LVL_TR1_7A : 1716 case LVL_TR1_7B : 1717 case LVL_TR1_CUT_2 : return FOG_GREEN; 1718 case LVL_TR1_8A : 1719 case LVL_TR1_8B : 1720 case LVL_TR1_8C : return FOG_SANDY; 1721 case LVL_TR1_10A : return FOG_BLACK; 1722 case LVL_TR1_CUT_3 : 1723 case LVL_TR1_10B : 1724 case LVL_TR1_CUT_4 : 1725 case LVL_TR1_10C : return FOG_RED; 1726 case LVL_TR1_EGYPT : 1727 case LVL_TR1_CAT : 1728 case LVL_TR1_END : 1729 case LVL_TR1_END2 : return FOG_SANDY; 1730 default : return FOG_BLACK; 1731 } 1732 } 1733 1734 struct SkyParams { 1735 vec4 skyDownColor; 1736 vec4 skyUpColor; 1737 vec4 sunDirSize; 1738 vec4 sunColorGlare; 1739 vec4 cloudDownColor; 1740 vec4 cloudUpColor; 1741 vec3 wind; 1742 }; 1743 1744 #define CLOUD_UP vec3() 1745 #define CLOUD_DOWN vec3() 1746 getSkyParams(LevelID id,SkyParams & params)1747 bool getSkyParams(LevelID id, SkyParams ¶ms) { 1748 switch (id) { 1749 case LVL_TR1_3A : 1750 params.skyDownColor = vec4(0.8f, 0.8f, 0.7f, 1.0f); 1751 params.skyUpColor = vec4(0.3f, 0.4f, 0.5f, 1.0f); 1752 params.sunDirSize = vec4(vec3(1.0f, 0.75f, -1.0f).normal(), 0.0025f); 1753 params.sunColorGlare = vec4(0.8f, 0.4f, 0.1f, 4.0f); 1754 params.cloudDownColor = vec4(0.35f, 0.4f, 0.45f, 1.0f); 1755 params.cloudUpColor = vec4(1.1f, 1.045f, 0.88f, 1.0f); 1756 params.wind = vec3(0.01f, -0.005f, 0.005f); 1757 break; 1758 case LVL_TR1_5 : 1759 params.skyDownColor = vec4(0.15f, 0.05f, 0.0f, 1.0f); 1760 params.skyUpColor = vec4(0.3f, 0.2f, 0.1f, 1.0f); 1761 params.sunDirSize = vec4(vec3(-1.0f, 0.8f, -1.0f).normal(), 0.0015f); 1762 params.sunColorGlare = vec4(0.7f, 0.7f, 0.6f, 256.0f); 1763 params.cloudDownColor = vec4(0.2f, 0.1f, 0.0f, 1.0f); 1764 params.cloudUpColor = vec4(0.5f, 0.5f, 0.4f, 1.0f); 1765 params.wind = vec3(0.01f, -0.005f, 0.005f); 1766 break; 1767 case LVL_TR3_HOUSE : // test 1768 params.skyDownColor = vec4(0.8f, 0.8f, 0.7f, 1.0f); 1769 params.skyUpColor = vec4(0.3f, 0.4f, 0.5f, 1.0f); 1770 params.sunDirSize = vec4(vec3(1.0f, 0.75f, -1.0f).normal(), 0.0025f); 1771 params.sunColorGlare = vec4(0.8f, 0.4f, 0.1f, 4.0f); 1772 params.cloudDownColor = vec4(0.35f, 0.4f, 0.45f, 1.0f); 1773 params.cloudUpColor = vec4(1.1f, 1.045f, 0.88f, 1.0f); 1774 params.wind = vec3(0.01f, -0.005f, 0.005f); 1775 break; 1776 default : return false; 1777 } 1778 return true; 1779 } 1780 } 1781 1782 #undef CHECK_FILE 1783 1784 #endif 1785