1 //=============================================================================
2 //
3 // Adventure Game Studio (AGS)
4 //
5 // Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
6 // The full list of copyright holders can be found in the Copyright.txt
7 // file, which is part of this source code distribution.
8 //
9 // The AGS source code is provided under the Artistic License 2.0.
10 // A copy of this license can be found in the file License.txt and at
11 // http://www.opensource.org/licenses/artistic-license-2.0.php
12 //
13 //=============================================================================
14
15 #include <stdio.h>
16 #include "ac/roomstruct.h"
17 #include "ac/common.h"
18 #include "ac/wordsdictionary.h"
19 #include "util/string_utils.h" // fputstring, etc
20 #include "util/compress.h"
21 #include "util/stream.h"
22 #include "core/assetmanager.h"
23 #include "gfx/bitmap.h"
24
25 using namespace AGS::Common;
26
27 Bitmap *backups[5];
28 int _acroom_bpp = 1; // bytes per pixel of currently loading room
29
ReadFromFile(Common::Stream * in)30 void sprstruc::ReadFromFile(Common::Stream *in)
31 {
32 sprnum = in->ReadInt16();
33 x = in->ReadInt16();
34 y = in->ReadInt16();
35 room = in->ReadInt16();
36 on = in->ReadInt16();
37 }
38
roomstruct()39 roomstruct::roomstruct() {
40 ebscene[0] = NULL; walls = NULL; object = NULL; lookat = NULL; nummes = 0;
41 left = 0; right = 317; top = 40; bottom = 199; numobj = MAX_OBJ; numsprs = 0; password[0] = 0;
42 wasversion = kRoomVersion_Current; numanims = 0; regions = NULL; numwalkareas = 0;
43 numhotspots = 0;
44 memset(&objbaseline[0], 0xff, sizeof(int) * MAX_INIT_SPR);
45 memset(&objectFlags[0], 0, sizeof(short) * MAX_INIT_SPR);
46 width = 320; height = 200; scripts = NULL;
47 cscriptsize = 0;
48 memset(&walk_area_zoom[0], 0, sizeof(short) * (MAX_WALK_AREAS + 1));
49 memset(&walk_area_light[0], 0, sizeof(short) * (MAX_WALK_AREAS + 1));
50 resolution = 1; num_bscenes = 1; ebscene[0] = NULL;
51 bscene_anim_speed = 5; bytes_per_pixel = 1;
52 numLocalVars = 0;
53 localvars = NULL;
54 int i;
55 for (i = 0; i <= MAX_WALK_AREAS; i++) {
56 walk_area_zoom2[i] = NOT_VECTOR_SCALED;
57 walk_area_top[i] = -1;
58 walk_area_bottom[i] = -1;
59 }
60 for (i = 0; i < MAX_HOTSPOTS; i++) {
61 intrHotspot[i] = new Interaction();
62 }
63 for (i = 0; i < MAX_INIT_SPR; i++)
64 intrObject[i] = new Interaction();
65 for (i = 0; i < MAX_REGIONS; i++)
66 intrRegion[i] = new Interaction();
67 intrRoom = new Interaction();
68 gameId = 0;
69 numRegions = 0;
70 hotspotScripts = NULL;
71 regionScripts = NULL;
72 objectScripts = NULL;
73 roomScripts = NULL;
74 }
75
freemessage()76 void roomstruct::freemessage() {
77 for (int f = 0; f < nummes; f++) {
78 if (message[f] != NULL)
79 free(message[f]);
80 }
81 }
82
freescripts()83 void roomstruct::freescripts()
84 {
85 if (scripts != NULL)
86 {
87 free(scripts);
88 scripts = NULL;
89 }
90
91 compiled_script.reset();
92
93 if (roomScripts != NULL)
94 {
95 delete roomScripts;
96 roomScripts = NULL;
97 }
98 if (hotspotScripts != NULL)
99 {
100 for (int i = 0; i < numhotspots; i++)
101 {
102 delete hotspotScripts[i];
103 }
104 delete[] hotspotScripts;
105 hotspotScripts = NULL;
106 }
107 if (objectScripts != NULL)
108 {
109 for (int i = 0; i < numsprs; i++)
110 {
111 delete objectScripts[i];
112 }
113 delete[] objectScripts;
114 objectScripts = NULL;
115 }
116 if (regionScripts != NULL)
117 {
118 for (int i = 0; i < numRegions; i++)
119 {
120 delete regionScripts[i];
121 }
122 delete[] regionScripts;
123 regionScripts = NULL;
124 }
125 }
126
has_region_lightlevel(int id) const127 bool roomstruct::has_region_lightlevel(int id) const
128 {
129 if (id >= 0 && id < MAX_REGIONS)
130 return regionTintLevel[id] == 0;
131 return false;
132 }
133
has_region_tint(int id) const134 bool roomstruct::has_region_tint(int id) const
135 {
136 if (id >= 0 && id < MAX_REGIONS)
137 return regionTintLevel[id] != 0;
138 return false;
139 }
140
get_region_lightlevel(int id) const141 int roomstruct::get_region_lightlevel(int id) const
142 {
143 if (id >= 0 && id < MAX_REGIONS)
144 return has_region_lightlevel(id) ? regionLightLevel[id] : 0;
145 return 0;
146 }
147
get_region_tintluminance(int id) const148 int roomstruct::get_region_tintluminance(int id) const
149 {
150 if (id >= 0 && id < MAX_REGIONS)
151 return has_region_tint(id) ? (regionLightLevel[id] * 10) / 25 : 0;
152 return 0;
153 }
154
ReadFromFile(Stream * in)155 void room_file_header::ReadFromFile(Stream *in)
156 {
157 version = (RoomFileVersion)in->ReadInt16();
158 }
159
WriteFromFile(Common::Stream * out)160 void room_file_header::WriteFromFile(Common::Stream *out)
161 {
162 out->WriteInt16(version);
163 }
164
165 int usesmisccond = 0;
166
load_main_block(roomstruct * rstruc,const char * files,Stream * in,room_file_header rfh)167 void load_main_block(roomstruct *rstruc, const char *files, Stream *in, room_file_header rfh) {
168 int f, gsmod, NUMREAD;
169 char buffre[3000];
170 long tesl;
171
172 usesmisccond = 0;
173 rstruc->width = 320;
174 rstruc->height = 200;
175 rstruc->resolution = 1;
176 rstruc->numwalkareas = 0;
177 rstruc->numhotspots = 0;
178
179 memset(&rstruc->shadinginfo[0], 0, sizeof(short) * 16);
180 memset(&rstruc->sprs[0], 0, sizeof(sprstruc) * MAX_INIT_SPR);
181 memset(&rstruc->objbaseline[0], 0xff, sizeof(int) * MAX_INIT_SPR);
182 memset(&rstruc->objectFlags[0], 0, sizeof(short) * MAX_INIT_SPR);
183 memset(&rstruc->hswalkto[0], 0, sizeof(_Point) * MAX_HOTSPOTS);
184 memset(&rstruc->walk_area_zoom[0], 0, sizeof(short) * (MAX_WALK_AREAS + 1));
185 memset(&rstruc->walk_area_light[0], 0, sizeof(short) * (MAX_WALK_AREAS + 1));
186
187 for (f = 0; f < MAX_HOTSPOTS; f++) {
188 rstruc->hotspotScriptNames[f].Free();
189 if (f == 0)
190 rstruc->hotspotnames[f] = "No hotspot";
191 else
192 rstruc->hotspotnames[f].Format("Hotspot %d", f);
193 }
194
195 /* memset(&rstruc->hscond[0], 0, sizeof(EventBlock) * MAX_HOTSPOTS);
196 memset(&rstruc->objcond[0], 0, sizeof(EventBlock) * MAX_INIT_SPR);
197 memset(&rstruc->misccond, 0, sizeof(EventBlock));*/
198
199 if (rfh.version >= kRoomVersion_208)
200 _acroom_bpp = in->ReadInt32();
201 else
202 _acroom_bpp = 1;
203
204 if (_acroom_bpp < 1)
205 _acroom_bpp = 1;
206
207 rstruc->bytes_per_pixel = _acroom_bpp;
208 rstruc->numobj = in->ReadInt16();
209 if (rstruc->numobj > MAX_OBJ)
210 quit("!room newer than this version - too many walk-behinds");
211
212 NUMREAD = NUM_CONDIT;
213 in->ReadArrayOfInt16(&rstruc->objyval[0], rstruc->numobj);
214
215 gsmod = 0;
216
217 rstruc->numhotspots = in->ReadInt32();
218 if (rstruc->numhotspots == 0)
219 rstruc->numhotspots = 20;
220 if (rstruc->numhotspots > MAX_HOTSPOTS)
221 quit("room has too many hotspots: need newer version of AGS?");
222
223 // Points are a pair of shorts
224 // [IKM] TODO: read/write member for _Point?
225 in->ReadArrayOfInt16((int16_t*)&rstruc->hswalkto[0], 2*rstruc->numhotspots);
226
227 for (f = 0; f < rstruc->numhotspots; f++)
228 {
229 if (rfh.version >= kRoomVersion_3415)
230 rstruc->hotspotnames[f] = StrUtil::ReadString(in);
231 else if (rfh.version >= kRoomVersion_303a)
232 rstruc->hotspotnames[f] = String::FromStream(in);
233 else
234 rstruc->hotspotnames[f] = String::FromStreamCount(in, 30);
235 }
236
237 if (rfh.version >= kRoomVersion_270)
238 {
239 for (int i = 0; i < rstruc->numhotspots; ++i)
240 {
241 if (rfh.version >= kRoomVersion_3415)
242 rstruc->hotspotScriptNames[i] = StrUtil::ReadString(in);
243 else
244 rstruc->hotspotScriptNames[i] = String::FromStreamCount(in, MAX_SCRIPT_NAME_LEN);
245 }
246 }
247
248 rstruc->numwalkareas = in->ReadInt32();
249 for (int iteratorCount = 0; iteratorCount < rstruc->numwalkareas; ++iteratorCount)
250 {
251 rstruc->wallpoints[iteratorCount].ReadFromFile(in);
252 }
253
254 update_polled_stuff_if_runtime();
255
256 rstruc->top = in->ReadInt16();
257 rstruc->bottom = in->ReadInt16();
258 rstruc->left = in->ReadInt16();
259 rstruc->right = in->ReadInt16();
260
261 rstruc->numsprs = in->ReadInt16();
262 for (int iteratorCount = 0; iteratorCount < rstruc->numsprs; ++iteratorCount)
263 {
264 rstruc->sprs[iteratorCount].ReadFromFile(in);
265 }
266
267 if (rfh.version >= kRoomVersion_253) {
268 rstruc->numLocalVars = in->ReadInt32();
269 if (rstruc->numLocalVars > 0) {
270 rstruc->localvars = new InteractionVariable[rstruc->numLocalVars];
271
272 for (int iteratorCount = 0; iteratorCount < rstruc->numLocalVars; ++iteratorCount)
273 {
274 rstruc->localvars[iteratorCount].Read(in);
275 }
276 }
277 }
278
279 rstruc->numRegions = 0;
280
281 if (rfh.version >= kRoomVersion_241) {
282 if ((rstruc->numhotspots > MAX_HOTSPOTS) || (rstruc->numsprs > MAX_INIT_SPR))
283 quit("load_room: room file created with newer version (too many hotspots/objects)");
284
285 // free all of the old interactions
286 for (f = 0; f < MAX_HOTSPOTS; f++) {
287 if (rstruc->intrHotspot[f] != NULL) {
288 delete rstruc->intrHotspot[f];
289 rstruc->intrHotspot[f] = NULL;
290 }
291
292 if (rfh.version < kRoomVersion_300a)
293 {
294 if (f < rstruc->numhotspots)
295 rstruc->intrHotspot[f] = Interaction::CreateFromStream(in);
296 else
297 rstruc->intrHotspot[f] = new Interaction();
298 }
299 }
300
301 for (f = 0; f < MAX_INIT_SPR; f++) {
302 if (rstruc->intrObject[f] != NULL) {
303 delete rstruc->intrObject[f];
304 rstruc->intrObject[f] = NULL;
305 }
306
307 if (rfh.version < kRoomVersion_300a)
308 {
309 if (f < rstruc->numsprs)
310 rstruc->intrObject[f] = Interaction::CreateFromStream(in);
311 else
312 rstruc->intrObject[f] = new Interaction();
313 }
314 }
315
316 if (rfh.version < kRoomVersion_300a)
317 {
318 delete rstruc->intrRoom;
319 rstruc->intrRoom = Interaction::CreateFromStream(in);
320 }
321
322 for (f = 0; f < MAX_REGIONS; f++) {
323 if (rstruc->intrRegion[f] != NULL)
324 delete rstruc->intrRegion[f];
325 rstruc->intrRegion[f] = new Interaction();
326 }
327
328 if (rfh.version >= kRoomVersion_255b) {
329 rstruc->numRegions = in->ReadInt32();
330 if (rstruc->numRegions > MAX_REGIONS)
331 quit("load_room: needs newer version of AGS - too many regions");
332
333 if (rfh.version < kRoomVersion_300a)
334 {
335 for (f = 0; f < rstruc->numRegions; f++) {
336 delete rstruc->intrRegion[f];
337 rstruc->intrRegion[f] = Interaction::CreateFromStream(in);
338 }
339 }
340 }
341
342 if (rfh.version >= kRoomVersion_300a)
343 {
344 rstruc->hotspotScripts = new InteractionScripts*[rstruc->numhotspots];
345 rstruc->objectScripts = new InteractionScripts*[rstruc->numsprs];
346 rstruc->regionScripts = new InteractionScripts*[rstruc->numRegions];
347 rstruc->roomScripts = InteractionScripts::CreateFromStream(in);
348 int bb;
349 for (bb = 0; bb < rstruc->numhotspots; bb++) {
350 rstruc->hotspotScripts[bb] = InteractionScripts::CreateFromStream(in);
351 }
352 for (bb = 0; bb < rstruc->numsprs; bb++) {
353 rstruc->objectScripts[bb] = InteractionScripts::CreateFromStream(in);
354 }
355 for (bb = 0; bb < rstruc->numRegions; bb++) {
356 rstruc->regionScripts[bb] = InteractionScripts::CreateFromStream(in);
357 }
358
359 }
360 }
361
362 if (rfh.version >= kRoomVersion_200_alpha) {
363 in->ReadArrayOfInt32(&rstruc->objbaseline[0], rstruc->numsprs);
364 rstruc->width = in->ReadInt16();
365 rstruc->height = in->ReadInt16();
366 }
367
368 if (rfh.version >= kRoomVersion_262)
369 in->ReadArrayOfInt16(&rstruc->objectFlags[0], rstruc->numsprs);
370
371 if (rfh.version >= kRoomVersion_200_final)
372 rstruc->resolution = in->ReadInt16();
373
374 int num_walk_areas = MAX_WALK_AREAS;
375 if (rfh.version >= kRoomVersion_240)
376 num_walk_areas = in->ReadInt32();
377
378 if (num_walk_areas > MAX_WALK_AREAS + 1)
379 quit("load_room: Too many walkable areas, need newer version");
380
381 if (rfh.version >= kRoomVersion_200_alpha7)
382 in->ReadArrayOfInt16(&rstruc->walk_area_zoom[0], num_walk_areas);
383
384 if (rfh.version >= kRoomVersion_214)
385 in->ReadArrayOfInt16(&rstruc->walk_area_light[0], num_walk_areas);
386
387 if (rfh.version >= kRoomVersion_251) {
388 in->ReadArrayOfInt16(&rstruc->walk_area_zoom2[0], num_walk_areas);
389 in->ReadArrayOfInt16(&rstruc->walk_area_top[0], num_walk_areas);
390 in->ReadArrayOfInt16(&rstruc->walk_area_bottom[0], num_walk_areas);
391
392 for (f = 0; f < num_walk_areas; f++) {
393 // if they set a contiuously scaled area where the top
394 // and bottom zoom levels are identical, set it as a normal
395 // scaled area
396 if (rstruc->walk_area_zoom[f] == rstruc->walk_area_zoom2[f])
397 rstruc->walk_area_zoom2[f] = NOT_VECTOR_SCALED;
398 }
399 }
400
401 in->Read(&rstruc->password[0], 11);
402 in->Read(&rstruc->options[0], 10);
403 rstruc->nummes = in->ReadInt16();
404
405 if (rfh.version >= kRoomVersion_272)
406 rstruc->gameId = in->ReadInt32();
407
408 if (rfh.version >= kRoomVersion_pre114_3)
409 {
410 for (int iteratorCount = 0; iteratorCount < rstruc->nummes; ++iteratorCount)
411 {
412 rstruc->msgi[iteratorCount].ReadFromFile(in);
413 }
414 }
415 else
416 memset(&rstruc->msgi[0], 0, sizeof(MessageInfo) * MAXMESS);
417
418 for (f = 0;f < rstruc->nummes; f++) {
419 if (rfh.version >= kRoomVersion_261)
420 read_string_decrypt(in, buffre);
421 else
422 fgetstring_limit(buffre, in, 2999);
423
424 int buffre_length = strlen(buffre);
425
426 rstruc->message[f] = (char *)malloc(buffre_length + 2);
427 strcpy(rstruc->message[f], buffre);
428
429 if ((buffre_length > 0) && (buffre[buffre_length-1] == (char)200)) {
430 rstruc->message[f][strlen(buffre)-1] = 0;
431 rstruc->msgi[f].flags |= MSG_DISPLAYNEXT;
432 }
433 }
434
435 rstruc->numanims = 0;
436 if (rfh.version >= kRoomVersion_pre114_6) {
437 rstruc->numanims = in->ReadInt16();
438
439 if (rstruc->numanims > 0)
440 // [IKM] CHECKME later: this will cause trouble if structure changes
441 in->Seek (sizeof(FullAnimation) * rstruc->numanims);
442 // in->ReadArray(&rstruc->anims[0], sizeof(FullAnimation), rstruc->numanims);
443 }
444 else {
445 rstruc->numanims = 0;
446 memset(&rstruc->anims[0], 0, sizeof(FullAnimation) * MAXANIMS);
447 }
448
449 if ((rfh.version >= kRoomVersion_pre114_4) && (rfh.version < kRoomVersion_250a)) {
450 load_script_configuration(in);
451 load_graphical_scripts(in, rstruc);
452 }
453
454 if (rfh.version >= kRoomVersion_114)
455 in->ReadArrayOfInt16(&rstruc->shadinginfo[0], 16);
456
457 if (rfh.version >= kRoomVersion_255b) {
458 in->ReadArrayOfInt16 (&rstruc->regionLightLevel[0], rstruc->numRegions);
459 in->ReadArrayOfInt32 (&rstruc->regionTintLevel[0], rstruc->numRegions);
460 }
461
462 if (rfh.version < kRoomVersion_3404)
463 {
464 // Convert the old format tint saturation
465 for (int i = 0; i < MAX_REGIONS; ++i)
466 {
467 if ((rstruc->regionTintLevel[i] & LEGACY_TINT_IS_ENABLED) != 0)
468 {
469 rstruc->regionTintLevel[i] &= ~LEGACY_TINT_IS_ENABLED;
470 // older versions of the editor had a bug - work around it
471 int tint_amount = (rstruc->regionLightLevel[i] > 0 ? rstruc->regionLightLevel[i] : 50);
472 rstruc->regionTintLevel[i] |= (tint_amount & 0xFF) << 24;
473 rstruc->regionLightLevel[i] = 255;
474 }
475 }
476 }
477
478 update_polled_stuff_if_runtime();
479
480 if (rfh.version >= kRoomVersion_pre114_5) {
481 tesl = load_lzw(in, rstruc->ebscene[0], rstruc->pal);
482 rstruc->ebscene[0] = recalced;
483 }
484 else
485 tesl = loadcompressed_allegro(in, &rstruc->ebscene[0], rstruc->pal, in->GetPosition());
486
487 if ((rstruc->ebscene[0]->GetWidth() > 320) & (rfh.version < kRoomVersion_200_final))
488 rstruc->resolution = 2;
489
490 update_polled_stuff_if_runtime();
491 if (rfh.version >= kRoomVersion_255b)
492 tesl = loadcompressed_allegro(in, &rstruc->regions, rstruc->pal, tesl);
493 else if (rfh.version >= kRoomVersion_114) {
494 tesl = loadcompressed_allegro(in, &rstruc->regions, rstruc->pal, tesl);
495 // an old version - ->Clear the 'shadow' area into a blank regions bmp
496 delete rstruc->regions;
497 rstruc->regions = NULL;
498 }
499
500 update_polled_stuff_if_runtime();
501 tesl = loadcompressed_allegro(in, &rstruc->walls, rstruc->pal, tesl);
502
503 update_polled_stuff_if_runtime();
504 tesl = loadcompressed_allegro(in, &rstruc->object, rstruc->pal, tesl);
505
506 update_polled_stuff_if_runtime();
507 tesl = loadcompressed_allegro(in, &rstruc->lookat, rstruc->pal, tesl);
508
509 if (rfh.version < kRoomVersion_255b) {
510 // Old version - copy walkable areas to Regions
511 if (rstruc->regions == NULL)
512 rstruc->regions = BitmapHelper::CreateBitmap(rstruc->walls->GetWidth(), rstruc->walls->GetHeight(), 8);
513 rstruc->regions->Fill(0);
514 rstruc->regions->Blit (rstruc->walls, 0, 0, 0, 0, rstruc->regions->GetWidth(), rstruc->regions->GetHeight());
515 for (f = 0; f <= 15; f++) {
516 rstruc->regionLightLevel[f] = rstruc->walk_area_light[f];
517 rstruc->regionTintLevel[f] = 255;
518 }
519 }
520
521 if (rfh.version < kRoomVersion_200_alpha) {
522 for (f = 0; f < 11; f++)
523 rstruc->password[f] += 60;
524 }
525 else {
526 for (f = 0; f < 11; f++)
527 rstruc->password[f] += passwencstring[f];
528 }
529 }
530
531 extern bool load_room_is_version_bad(roomstruct *rstruc);
532
load_room(const char * files,roomstruct * rstruc,bool gameIsHighRes)533 void load_room(const char *files, roomstruct *rstruc, bool gameIsHighRes) {
534 Common::Stream *opty; // CHECKME why "opty"??
535 room_file_header rfh;
536 int i;
537
538 rstruc->freemessage();
539 rstruc->freescripts();
540
541 if (rstruc->num_bscenes > 1) {
542 int ff;
543
544 for (ff = 1; ff < rstruc->num_bscenes; ff++) {
545 delete rstruc->ebscene[ff];
546 rstruc->ebscene[ff] = NULL;
547 }
548 update_polled_stuff_if_runtime();
549 }
550
551 rstruc->num_bscenes = 1;
552 rstruc->bscene_anim_speed = 5;
553 for (size_t i = 0; i < MAX_INIT_SPR; ++i)
554 {
555 rstruc->objectnames[i].Free();
556 rstruc->objectscriptnames[i].Free();
557 }
558 memset (&rstruc->regionLightLevel[0], 0, sizeof(short) * MAX_REGIONS);
559 memset (&rstruc->regionTintLevel[0], 0, sizeof(int) * MAX_REGIONS);
560
561 for (i = 0; i <= MAX_WALK_AREAS; i++) {
562 rstruc->walk_area_zoom2[i] = NOT_VECTOR_SCALED;
563 rstruc->walk_area_top[i] = -1;
564 rstruc->walk_area_bottom[i] = -1;
565 }
566
567 for (i = 0; i < rstruc->numhotspots; i++)
568 rstruc->hsProps[i].clear();
569 for (i = 0; i < rstruc->numsprs; i++)
570 rstruc->objProps[i].clear();
571 rstruc->roomProps.clear();
572
573 if (rstruc->localvars != NULL)
574 delete [] rstruc->localvars;
575 rstruc->localvars = NULL;
576 rstruc->numLocalVars = 0;
577
578 memset(&rstruc->ebpalShared[0], 0, MAX_BSCENE);
579
580 update_polled_stuff_if_runtime();
581
582 opty = Common::AssetManager::OpenAsset(files);
583 if (opty == NULL) {
584 char errbuffr[500];
585 sprintf(errbuffr,"Load_room: Unable to load the room file '%s'\n"
586 "Make sure that you saved the room to the correct folder (it should be\n"
587 "in your game's sub-folder of the AGS directory).\n"
588 "Also check that the player character's starting room is set correctly.\n",files);
589 quit(errbuffr);
590 }
591 update_polled_stuff_if_runtime(); // it can take a while to load the file sometimes
592
593 rfh.ReadFromFile(opty);
594 //fclose(opty);
595 rstruc->wasversion = rfh.version;
596
597 if (load_room_is_version_bad(rstruc))
598 {
599 delete opty;
600 quit("Load_Room: Bad packed file. Either the file requires a newer or older version of\n"
601 "this program or the file is corrupt.\n");
602 }
603
604 int thisblock = 0;
605 int bloklen;
606
607 while (thisblock != BLOCKTYPE_EOF) {
608 update_polled_stuff_if_runtime();
609 thisblock = opty->ReadByte();
610
611 if (thisblock == BLOCKTYPE_EOF)
612 break;
613
614 bloklen = opty->ReadInt32();
615 bloklen += opty->GetPosition(); // make it the new position for after block read
616
617 if (thisblock == BLOCKTYPE_MAIN)
618 load_main_block(rstruc, files, opty, rfh);
619 else if (thisblock == BLOCKTYPE_SCRIPT) {
620 int lee;
621 int hh;
622
623 lee = opty->ReadInt32();
624 rstruc->scripts = (char *)malloc(lee + 5);
625 // MACPORT FIX: swap
626 opty->Read(rstruc->scripts, lee);
627 rstruc->scripts[lee] = 0;
628
629 for (hh = 0; hh < lee; hh++)
630 rstruc->scripts[hh] += passwencstring[hh % 11];
631 }
632 else if (thisblock == BLOCKTYPE_COMPSCRIPT3) {
633 rstruc->compiled_script.reset(ccScript::CreateFromStream(opty));
634 if (rstruc->compiled_script == NULL)
635 quit("Load_room: Script load failed; need newer version?");
636 }
637 else if ((thisblock == BLOCKTYPE_COMPSCRIPT) || (thisblock == BLOCKTYPE_COMPSCRIPT2))
638 #ifdef LOADROOM_ALLOWOLD
639 rstruc->compiled_script = NULL;
640 #else
641 quit("Load_room: old room format. Please upgrade the room.");
642 #endif
643 else if (thisblock == BLOCKTYPE_OBJECTNAMES) {
644 if (opty->ReadByte() != rstruc->numsprs)
645 quit("Load_room: inconsistent blocks for object names");
646
647 for (int i = 0; i < rstruc->numsprs; ++i)
648 {
649 if (rfh.version >= kRoomVersion_3415)
650 rstruc->objectnames[i] = StrUtil::ReadString(opty);
651 else
652 rstruc->objectnames[i].ReadCount(opty, LEGACY_MAXOBJNAMELEN);
653 }
654 }
655 else if (thisblock == BLOCKTYPE_OBJECTSCRIPTNAMES) {
656 if (opty->ReadByte() != rstruc->numsprs)
657 quit("Load_room: inconsistent blocks for object script names");
658
659 for (int i = 0; i < rstruc->numsprs; ++i)
660 {
661 if (rfh.version >= kRoomVersion_3415)
662 rstruc->objectscriptnames[i] = StrUtil::ReadString(opty);
663 else
664 rstruc->objectscriptnames[i].ReadCount(opty, MAX_SCRIPT_NAME_LEN);
665 }
666 }
667 else if (thisblock == BLOCKTYPE_ANIMBKGRND) {
668 int ct;
669 long fpos;
670
671 rstruc->num_bscenes = opty->ReadByte();
672 rstruc->bscene_anim_speed = opty->ReadByte();
673
674 if (rfh.version >= kRoomVersion_255a)
675 opty->Read(&rstruc->ebpalShared[0], rstruc->num_bscenes);
676 else
677 memset (&rstruc->ebpalShared[0], 0, rstruc->num_bscenes);
678
679 fpos = opty->GetPosition();
680 // fclose(opty);
681
682 for (ct = 1; ct < rstruc->num_bscenes; ct++) {
683 update_polled_stuff_if_runtime();
684 // fpos = load_lzw(files,rstruc->ebscene[ct],rstruc->pal,fpos);
685 fpos = load_lzw(opty, rstruc->ebscene[ct], rstruc->bpalettes[ct]);
686 rstruc->ebscene[ct] = recalced;
687 }
688 // opty = Common::AssetManager::OpenAsset(files, "rb");
689 // Seek(opty, fpos, SEEK_SET);
690 }
691 else if (thisblock == BLOCKTYPE_PROPERTIES) {
692 // Read custom properties
693 if (opty->ReadInt32() != 1)
694 quit("LoadRoom: unknown Custom Properties block encountered");
695
696 int errors = 0, gg;
697
698 if (Properties::ReadValues(rstruc->roomProps, opty))
699 quit("LoadRoom: error reading custom properties block");
700
701 for (gg = 0; gg < rstruc->numhotspots; gg++)
702 errors += Properties::ReadValues(rstruc->hsProps[gg], opty);
703 for (gg = 0; gg < rstruc->numsprs; gg++)
704 errors += Properties::ReadValues(rstruc->objProps[gg], opty);
705
706 if (errors > 0)
707 quit("LoadRoom: errors encountered reading custom props");
708 }
709 else if (thisblock == -1)
710 {
711 delete opty;
712 quit("LoadRoom: unexpected end of file while loading room");
713 return;
714 }
715 else {
716 quitprintf("LoadRoom: unknown block type %d encountered in '%s'", thisblock, files);
717 }
718
719 if (opty->GetPosition() != bloklen)
720 quitprintf("LoadRoom: unexpected end of block %d in in '%s'", thisblock, files);
721 }
722
723 // sync bpalettes[0] with room.pal
724 memcpy (&rstruc->bpalettes[0][0], &rstruc->pal[0], sizeof(color) * 256);
725
726 delete opty;
727
728 if ((rfh.version < kRoomVersion_303b) && (gameIsHighRes))
729 {
730 // Pre-3.0.3, multiply up co-ordinates
731 // If you change this, also change convert_room_coordinates_to_low_res
732 // function in the engine
733 int f;
734 for (f = 0; f < rstruc->numsprs; f++)
735 {
736 rstruc->sprs[f].x *= 2;
737 rstruc->sprs[f].y *= 2;
738 if (rstruc->objbaseline[f] > 0)
739 {
740 rstruc->objbaseline[f] *= 2;
741 }
742 }
743
744 for (f = 0; f < rstruc->numhotspots; f++)
745 {
746 rstruc->hswalkto[f].x *= 2;
747 rstruc->hswalkto[f].y *= 2;
748 }
749
750 for (f = 0; f < rstruc->numobj; f++)
751 {
752 rstruc->objyval[f] *= 2;
753 }
754
755 rstruc->left *= 2;
756 rstruc->top *= 2;
757 rstruc->bottom *= 2;
758 rstruc->right *= 2;
759 rstruc->width *= 2;
760 rstruc->height *= 2;
761 }
762
763 }
764