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 #define USE_CLIB
16 #include "util/string_utils.h" //strlwr()
17 #include "ac/common.h"
18 #include "media/audio/audiodefines.h"
19 #include "ac/charactercache.h"
20 #include "ac/characterextras.h"
21 #include "ac/draw.h"
22 #include "ac/event.h"
23 #include "ac/game.h"
24 #include "ac/gamesetup.h"
25 #include "ac/gamesetupstruct.h"
26 #include "ac/gamestate.h"
27 #include "ac/global_audio.h"
28 #include "ac/global_character.h"
29 #include "ac/global_game.h"
30 #include "ac/global_object.h"
31 #include "ac/global_translation.h"
32 #include "ac/mouse.h"
33 #include "ac/objectcache.h"
34 #include "ac/overlay.h"
35 #include "ac/properties.h"
36 #include "ac/region.h"
37 #include "ac/record.h"
38 #include "ac/room.h"
39 #include "ac/roomobject.h"
40 #include "ac/roomstatus.h"
41 #include "ac/screen.h"
42 #include "ac/string.h"
43 #include "ac/system.h"
44 #include "ac/viewport.h"
45 #include "ac/walkablearea.h"
46 #include "ac/walkbehind.h"
47 #include "ac/dynobj/scriptobject.h"
48 #include "ac/dynobj/scripthotspot.h"
49 #include "gui/guidefines.h"
50 #include "script/cc_instance.h"
51 #include "debug/debug_log.h"
52 #include "debug/debugger.h"
53 #include "debug/out.h"
54 #include "device/mousew32.h"
55 #include "media/audio/audio.h"
56 #include "platform/base/agsplatformdriver.h"
57 #include "plugin/agsplugin.h"
58 #include "plugin/plugin_engine.h"
59 #include "script/script.h"
60 #include "script/script_runtime.h"
61 #include "ac/spritecache.h"
62 #include "util/stream.h"
63 #include "gfx/graphicsdriver.h"
64 #include "core/assetmanager.h"
65 #include "ac/dynobj/all_dynamicclasses.h"
66 #include "gfx/bitmap.h"
67 #include "gfx/gfxfilter.h"
68 #include "util/math.h"
69 #include "device/mousew32.h"
70
71 using namespace AGS::Common;
72 using namespace AGS::Engine;
73
74 #if !defined (WINDOWS_VERSION)
75 // for toupper
76 #include <ctype.h>
77 #endif
78
79 extern GameSetup usetup;
80 extern GameSetupStruct game;
81 extern GameState play;
82 extern RoomStatus*croom;
83 extern RoomStatus troom; // used for non-saveable rooms, eg. intro
84 extern int displayed_room;
85 extern RoomObject*objs;
86 extern ccInstance *roominst;
87 extern AGSPlatformDriver *platform;
88 extern int numevents;
89 extern CharacterCache *charcache;
90 extern ObjectCache objcache[MAX_INIT_SPR];
91 extern CharacterExtras *charextra;
92 extern int done_es_error;
93 extern int our_eip;
94 extern Bitmap *walkareabackup, *walkable_areas_temp;
95 extern ScriptObject scrObj[MAX_INIT_SPR];
96 extern SpriteCache spriteset;
97 extern int spritewidth[MAX_SPRITES],spriteheight[MAX_SPRITES];
98 extern int in_new_room, new_room_was; // 1 in new room, 2 first time in new room, 3 loading saved game
99 extern ScriptHotspot scrHotspot[MAX_HOTSPOTS];
100 extern int in_leaves_screen;
101 extern CharacterInfo*playerchar;
102 extern int starting_room;
103 extern unsigned int loopcounter,lastcounter;
104 extern int ccError;
105 extern char ccErrorString[400];
106 extern IDriverDependantBitmap* roomBackgroundBmp;
107 extern IGraphicsDriver *gfxDriver;
108 extern Bitmap *raw_saved_screen;
109 extern int actSpsCount;
110 extern Bitmap **actsps;
111 extern IDriverDependantBitmap* *actspsbmp;
112 extern Bitmap **actspswb;
113 extern IDriverDependantBitmap* *actspswbbmp;
114 extern CachedActSpsData* actspswbcache;
115 extern color palette[256];
116 extern Bitmap *virtual_screen;
117 extern Bitmap *_old_screen;
118 extern Bitmap *_sub_screen;
119 extern int offsetx, offsety;
120 extern int mouse_z_was;
121
122 extern Bitmap **guibg;
123 extern IDriverDependantBitmap **guibgbmp;
124
125 extern CCHotspot ccDynamicHotspot;
126 extern CCObject ccDynamicObject;
127
128 RGB_MAP rgb_table; // for 256-col antialiasing
129 int new_room_flags=0;
130 int gs_to_newroom=-1;
131
Room_GetDrawingSurfaceForBackground(int backgroundNumber)132 ScriptDrawingSurface* Room_GetDrawingSurfaceForBackground(int backgroundNumber)
133 {
134 if (displayed_room < 0)
135 quit("!Room.GetDrawingSurfaceForBackground: no room is currently loaded");
136
137 if (backgroundNumber == SCR_NO_VALUE)
138 {
139 backgroundNumber = play.bg_frame;
140 }
141
142 if ((backgroundNumber < 0) || (backgroundNumber >= thisroom.num_bscenes))
143 quit("!Room.GetDrawingSurfaceForBackground: invalid background number specified");
144
145
146 ScriptDrawingSurface *surface = new ScriptDrawingSurface();
147 surface->roomBackgroundNumber = backgroundNumber;
148 ccRegisterManagedObject(surface, surface);
149 return surface;
150 }
151
152
Room_GetObjectCount()153 int Room_GetObjectCount() {
154 return croom->numobj;
155 }
156
Room_GetWidth()157 int Room_GetWidth() {
158 return thisroom.width;
159 }
160
Room_GetHeight()161 int Room_GetHeight() {
162 return thisroom.height;
163 }
164
Room_GetColorDepth()165 int Room_GetColorDepth() {
166 return thisroom.ebscene[0]->GetColorDepth();
167 }
168
Room_GetLeftEdge()169 int Room_GetLeftEdge() {
170 return thisroom.left;
171 }
172
Room_GetRightEdge()173 int Room_GetRightEdge() {
174 return thisroom.right;
175 }
176
Room_GetTopEdge()177 int Room_GetTopEdge() {
178 return thisroom.top;
179 }
180
Room_GetBottomEdge()181 int Room_GetBottomEdge() {
182 return thisroom.bottom;
183 }
184
Room_GetMusicOnLoad()185 int Room_GetMusicOnLoad() {
186 return thisroom.options[ST_TUNE];
187 }
188
Room_GetProperty(const char * property)189 int Room_GetProperty(const char *property)
190 {
191 return get_int_property(thisroom.roomProps, croom->roomProps, property);
192 }
193
Room_GetTextProperty(const char * property)194 const char* Room_GetTextProperty(const char *property)
195 {
196 return get_text_property_dynamic_string(thisroom.roomProps, croom->roomProps, property);
197 }
198
Room_SetProperty(const char * property,int value)199 bool Room_SetProperty(const char *property, int value)
200 {
201 return set_int_property(croom->roomProps, property, value);
202 }
203
Room_SetTextProperty(const char * property,const char * value)204 bool Room_SetTextProperty(const char *property, const char *value)
205 {
206 return set_text_property(croom->roomProps, property, value);
207 }
208
Room_GetMessages(int index)209 const char* Room_GetMessages(int index) {
210 if ((index < 0) || (index >= thisroom.nummes)) {
211 return NULL;
212 }
213 char buffer[STD_BUFFER_SIZE];
214 buffer[0]=0;
215 replace_tokens(get_translation(thisroom.message[index]), buffer, STD_BUFFER_SIZE);
216 return CreateNewScriptString(buffer);
217 }
218
219
220 //=============================================================================
221
fix_bitmap_size(Bitmap * todubl)222 Bitmap *fix_bitmap_size(Bitmap *todubl) {
223 int oldw=todubl->GetWidth(), oldh=todubl->GetHeight();
224 int newWidth = multiply_up_coordinate(thisroom.width);
225 int newHeight = multiply_up_coordinate(thisroom.height);
226
227 if ((oldw == newWidth) && (oldh == newHeight))
228 return todubl;
229
230 // Bitmap *tempb=BitmapHelper::CreateBitmap(play.viewport.GetWidth(),play.viewport.GetHeight());
231 //todubl->SetClip(Rect(0,0,oldw-1,oldh-1)); // CHECKME! [IKM] Not sure this is needed here
232 Bitmap *tempb=BitmapHelper::CreateBitmap(newWidth, newHeight, todubl->GetColorDepth());
233 tempb->SetClip(Rect(0,0,tempb->GetWidth()-1,tempb->GetHeight()-1));
234 tempb->Fill(0);
235 tempb->StretchBlt(todubl, RectWH(0,0,oldw,oldh), RectWH(0,0,tempb->GetWidth(),tempb->GetHeight()));
236 delete todubl;
237 return tempb;
238 }
239
240
241
242
save_room_data_segment()243 void save_room_data_segment () {
244 croom->FreeScriptData();
245
246 croom->tsdatasize = roominst->globaldatasize;
247 if (croom->tsdatasize > 0) {
248 croom->tsdata=(char*)malloc(croom->tsdatasize+10);
249 memcpy(croom->tsdata,&roominst->globaldata[0],croom->tsdatasize);
250 }
251
252 }
253
unload_old_room()254 void unload_old_room() {
255 int ff;
256
257 // if switching games on restore, don't do this
258 if (displayed_room < 0)
259 return;
260
261 debug_script_log("Unloading room %d", displayed_room);
262
263 current_fade_out_effect();
264
265 Bitmap *ds = GetVirtualScreen();
266 ds->Fill(0);
267 for (ff=0;ff<croom->numobj;ff++)
268 objs[ff].moving = 0;
269
270 if (!play.ambient_sounds_persist) {
271 for (ff = 1; ff < MAX_SOUND_CHANNELS; ff++)
272 StopAmbientSound(ff);
273 }
274
275 cancel_all_scripts();
276 numevents = 0; // cancel any pending room events
277
278 if (roomBackgroundBmp != NULL)
279 {
280 gfxDriver->DestroyDDB(roomBackgroundBmp);
281 roomBackgroundBmp = NULL;
282 }
283
284 if (croom==NULL) ;
285 else if (roominst!=NULL) {
286 save_room_data_segment();
287 delete roominstFork;
288 delete roominst;
289 roominstFork = NULL;
290 roominst=NULL;
291 }
292 else croom->tsdatasize=0;
293 memset(&play.walkable_areas_on[0],1,MAX_WALK_AREAS+1);
294 play.bg_frame=0;
295 play.bg_frame_locked=0;
296 play.offsets_locked=0;
297 remove_screen_overlay(-1);
298 delete raw_saved_screen;
299 raw_saved_screen = NULL;
300 for (ff = 0; ff < MAX_BSCENE; ff++)
301 play.raw_modified[ff] = 0;
302 for (ff = 0; ff < thisroom.numLocalVars; ff++)
303 croom->interactionVariableValues[ff] = thisroom.localvars[ff].Value;
304
305 // wipe the character cache when we change rooms
306 for (ff = 0; ff < game.numcharacters; ff++) {
307 if (charcache[ff].inUse) {
308 delete charcache[ff].image;
309 charcache[ff].image = NULL;
310 charcache[ff].inUse = 0;
311 }
312 // ensure that any half-moves (eg. with scaled movement) are stopped
313 charextra[ff].xwas = INVALID_X;
314 }
315
316 play.swap_portrait_lastchar = -1;
317 play.swap_portrait_lastlastchar = -1;
318
319 for (ff = 0; ff < croom->numobj; ff++) {
320 // un-export the object's script object
321 if (objectScriptObjNames[ff].IsEmpty())
322 continue;
323
324 ccRemoveExternalSymbol(objectScriptObjNames[ff]);
325 }
326
327 for (ff = 0; ff < MAX_HOTSPOTS; ff++) {
328 if (thisroom.hotspotScriptNames[ff].IsEmpty())
329 continue;
330
331 ccRemoveExternalSymbol(thisroom.hotspotScriptNames[ff]);
332 }
333
334 croom_ptr_clear();
335
336 // clear the object cache
337 for (ff = 0; ff < MAX_INIT_SPR; ff++) {
338 delete objcache[ff].image;
339 objcache[ff].image = NULL;
340 }
341 // clear the actsps buffers to save memory, since the
342 // objects/characters involved probably aren't on the
343 // new screen. this also ensures all cached data is flushed
344 for (ff = 0; ff < MAX_INIT_SPR + game.numcharacters; ff++) {
345 delete actsps[ff];
346 actsps[ff] = NULL;
347
348 if (actspsbmp[ff] != NULL)
349 gfxDriver->DestroyDDB(actspsbmp[ff]);
350 actspsbmp[ff] = NULL;
351
352 delete actspswb[ff];
353 actspswb[ff] = NULL;
354
355 if (actspswbbmp[ff] != NULL)
356 gfxDriver->DestroyDDB(actspswbbmp[ff]);
357 actspswbbmp[ff] = NULL;
358
359 actspswbcache[ff].valid = 0;
360 }
361
362 // if Hide Player Character was ticked, restore it to visible
363 if (play.temporarily_turned_off_character >= 0) {
364 game.chars[play.temporarily_turned_off_character].on = 1;
365 play.temporarily_turned_off_character = -1;
366 }
367
368 }
369
370
371
convert_room_coordinates_to_low_res(roomstruct * rstruc)372 void convert_room_coordinates_to_low_res(roomstruct *rstruc)
373 {
374 int f;
375 for (f = 0; f < rstruc->numsprs; f++)
376 {
377 rstruc->sprs[f].x /= 2;
378 rstruc->sprs[f].y /= 2;
379 if (rstruc->objbaseline[f] > 0)
380 {
381 rstruc->objbaseline[f] /= 2;
382 }
383 }
384
385 for (f = 0; f < rstruc->numhotspots; f++)
386 {
387 rstruc->hswalkto[f].x /= 2;
388 rstruc->hswalkto[f].y /= 2;
389 }
390
391 for (f = 0; f < rstruc->numobj; f++)
392 {
393 rstruc->objyval[f] /= 2;
394 }
395
396 rstruc->left /= 2;
397 rstruc->top /= 2;
398 rstruc->bottom /= 2;
399 rstruc->right /= 2;
400 rstruc->width /= 2;
401 rstruc->height /= 2;
402 }
403
404 extern int convert_16bit_bgr;
405
406 #define NO_GAME_ID_IN_ROOM_FILE 16325
407 // forchar = playerchar on NewRoom, or NULL if restore saved game
load_new_room(int newnum,CharacterInfo * forchar)408 void load_new_room(int newnum, CharacterInfo*forchar) {
409
410 debug_script_log("Loading room %d", newnum);
411
412 String room_filename;
413 int cc;
414 done_es_error = 0;
415 play.room_changes ++;
416 set_color_depth(8);
417 displayed_room=newnum;
418
419 room_filename.Format("room%d.crm", newnum);
420 if (newnum == 0) {
421 // support both room0.crm and intro.crm
422 // 2.70: Renamed intro.crm to room0.crm, to stop it causing confusion
423 if (loaded_game_file_version < kGameVersion_270 && Common::AssetManager::DoesAssetExist("intro.crm") ||
424 loaded_game_file_version >= kGameVersion_270 && !Common::AssetManager::DoesAssetExist(room_filename))
425 {
426 room_filename = "intro.crm";
427 }
428 }
429 // reset these back, because they might have been changed.
430 delete thisroom.object;
431 thisroom.object=BitmapHelper::CreateBitmap(320,200);
432
433 delete thisroom.ebscene[0];
434 thisroom.ebscene[0] = BitmapHelper::CreateBitmap(320,200);
435
436 update_polled_stuff_if_runtime();
437
438 // load the room from disk
439 our_eip=200;
440 thisroom.gameId = NO_GAME_ID_IN_ROOM_FILE;
441 load_room(room_filename, &thisroom, game.IsHiRes());
442
443 if ((thisroom.gameId != NO_GAME_ID_IN_ROOM_FILE) &&
444 (thisroom.gameId != game.uniqueid)) {
445 quitprintf("!Unable to load '%s'. This room file is assigned to a different game.", room_filename.GetCStr());
446 }
447
448 if (game.IsHiRes() && (game.options[OPT_NATIVECOORDINATES] == 0))
449 {
450 convert_room_coordinates_to_low_res(&thisroom);
451 }
452
453 update_polled_stuff_if_runtime();
454 our_eip=201;
455 /* // apparently, doing this stops volume spiking between tracks
456 if (thisroom.options[ST_TUNE]>0) {
457 stopmusic();
458 delay(100);
459 }*/
460
461 play.room_width = thisroom.width;
462 play.room_height = thisroom.height;
463 play.anim_background_speed = thisroom.bscene_anim_speed;
464 play.bg_anim_delay = play.anim_background_speed;
465
466 int dd;
467 // do the palette
468 for (cc=0;cc<256;cc++) {
469 if (game.paluses[cc]==PAL_BACKGROUND)
470 palette[cc]=thisroom.pal[cc];
471 else {
472 // copy the gamewide colours into the room palette
473 for (dd = 0; dd < thisroom.num_bscenes; dd++)
474 thisroom.bpalettes[dd][cc] = palette[cc];
475 }
476 }
477
478 for (cc=0;cc<thisroom.num_bscenes;cc++) {
479 update_polled_stuff_if_runtime();
480 thisroom.ebscene[cc] = PrepareSpriteForUse(thisroom.ebscene[cc], false);
481 }
482
483 update_polled_stuff_if_runtime();
484
485 our_eip=202;
486 const int real_room_height = multiply_up_coordinate(thisroom.height);
487 // Game viewport is updated when when room's size is smaller than game's size.
488 // NOTE: if "OPT_LETTERBOX" is false, altsize.Height = size.Height always.
489 if (real_room_height < game.size.Height || play.viewport.GetHeight() < game.size.Height) {
490 int abscreen=0;
491
492 // [IKM] Here we remember what was set as virtual screen: either real screen bitmap, or virtual_screen bitmap
493 Bitmap *ds = GetVirtualScreen();
494 if (ds==BitmapHelper::GetScreenBitmap()) abscreen=1;
495 else if (ds==virtual_screen) abscreen=2;
496
497 // Define what should be a new game viewport size
498 int newScreenHeight = game.size.Height;
499 // [IKM] 2015-05-04: in original engine the letterbox feature only allowed viewports of
500 // either 200 or 240 (400 and 480) pixels, if the room height was equal or greater than 200 (400).
501 const int viewport_height = real_room_height < game.altsize.Height ? real_room_height :
502 (real_room_height >= game.altsize.Height && real_room_height < game.size.Height) ? game.altsize.Height :
503 game.size.Height;
504 if (viewport_height < game.size.Height) {
505 clear_letterbox_borders();
506 newScreenHeight = viewport_height;
507 }
508
509 // If this is the first time we got here, then the sub_screen does not exist at this point; so we create it here.
510 if (!_sub_screen)
511 _sub_screen = BitmapHelper::CreateSubBitmap(_old_screen, RectWH(game.size.Width / 2 - play.viewport.GetWidth() / 2, game.size.Height / 2-newScreenHeight/2, play.viewport.GetWidth(), newScreenHeight));
512
513 // Reset screen bitmap
514 if (newScreenHeight == _sub_screen->GetHeight())
515 {
516 // requested viewport height is the same as existing subscreen
517 BitmapHelper::SetScreenBitmap( _sub_screen );
518 }
519 // CHECKME: WTF is this for?
520 else if (_sub_screen->GetWidth() != game.size.Width)
521 {
522 // the height has changed and the width is not equal with game width
523 int subBitmapWidth = _sub_screen->GetWidth();
524 delete _sub_screen;
525 _sub_screen = BitmapHelper::CreateSubBitmap(_old_screen, RectWH(_old_screen->GetWidth() / 2 - subBitmapWidth / 2, _old_screen->GetHeight() / 2 - newScreenHeight / 2, subBitmapWidth, newScreenHeight));
526 BitmapHelper::SetScreenBitmap( _sub_screen );
527 }
528 else
529 {
530 // the height and width are equal to game native size: restore original screen
531 BitmapHelper::SetScreenBitmap( _old_screen );
532 }
533
534 // Update viewport and mouse area
535 play.SetViewport(BitmapHelper::GetScreenBitmap()->GetSize());
536 Mouse::SetGraphicArea();
537
538 // Reset virtual_screen bitmap
539 if (virtual_screen->GetHeight() != play.viewport.GetHeight()) {
540 int cdepth=virtual_screen->GetColorDepth();
541 delete virtual_screen;
542 virtual_screen=BitmapHelper::CreateBitmap(play.viewport.GetWidth(),play.viewport.GetHeight(),cdepth);
543 virtual_screen->Clear();
544 gfxDriver->SetMemoryBackBuffer(virtual_screen);
545 }
546
547 // Adjust offsets for rendering sprites on virtual screen
548 gfxDriver->SetRenderOffset(play.viewport.Left, play.viewport.Top);
549
550 // [IKM] Since both screen and virtual_screen bitmaps might have changed, we reset a virtual screen,
551 // with either first or second, depending on what was set as virtual screen before
552 if (abscreen==1) // it was a screen bitmap
553 SetVirtualScreen( BitmapHelper::GetScreenBitmap() );
554 else if (abscreen==2) // it was a virtual_screen bitmap
555 SetVirtualScreen( virtual_screen );
556
557 update_polled_stuff_if_runtime();
558 }
559 // update the script viewport height
560 scsystem.viewport_height = divide_down_coordinate(play.viewport.GetHeight());
561
562 SetMouseBounds (0,0,0,0);
563
564 our_eip=203;
565 in_new_room=1;
566
567 // walkable_areas_temp is used by the pathfinder to generate a
568 // copy of the walkable areas - allocate it here to save time later
569 delete walkable_areas_temp;
570 walkable_areas_temp = BitmapHelper::CreateBitmap(thisroom.walls->GetWidth(), thisroom.walls->GetHeight(), 8);
571
572 // Make a backup copy of the walkable areas prior to
573 // any RemoveWalkableArea commands
574 delete walkareabackup;
575 // copy the walls screen
576 walkareabackup=BitmapHelper::CreateBitmapCopy(thisroom.walls);
577
578 our_eip=204;
579 update_polled_stuff_if_runtime();
580 redo_walkable_areas();
581 // fix walk-behinds to current screen resolution
582 thisroom.object = fix_bitmap_size(thisroom.object);
583 update_polled_stuff_if_runtime();
584
585 set_color_depth(game.GetColorDepth());
586 // convert backgrounds to current res
587 if (thisroom.resolution != get_fixed_pixel_size(1)) {
588 for (cc=0;cc<thisroom.num_bscenes;cc++)
589 thisroom.ebscene[cc] = fix_bitmap_size(thisroom.ebscene[cc]);
590 }
591
592 if ((thisroom.ebscene[0]->GetWidth() < play.viewport.GetWidth()) ||
593 (thisroom.ebscene[0]->GetHeight() < play.viewport.GetHeight()))
594 {
595 quitprintf("!The background scene for this room is smaller than the game resolution. If you have recently changed "
596 "the game resolution, you will need to re-import the background for this room. (Room: %d, BG Size: %d x %d)",
597 newnum, thisroom.ebscene[0]->GetWidth(), thisroom.ebscene[0]->GetHeight());
598 }
599
600 recache_walk_behinds();
601
602 our_eip=205;
603 // setup objects
604 if (forchar != NULL) {
605 // if not restoring a game, always reset this room
606 troom.beenhere=0;
607 troom.FreeScriptData();
608 troom.FreeProperties();
609 memset(&troom.hotspot_enabled[0],1,MAX_HOTSPOTS);
610 memset(&troom.region_enabled[0], 1, MAX_REGIONS);
611 }
612 if ((newnum>=0) & (newnum<MAX_ROOMS))
613 croom = getRoomStatus(newnum);
614 else croom=&troom;
615
616 if (croom->beenhere > 0) {
617 // if we've been here before, save the Times Run information
618 // since we will overwrite the actual NewInteraction structs
619 // (cos they have pointers and this might have been loaded from
620 // a save game)
621 if (thisroom.roomScripts == NULL)
622 {
623 thisroom.intrRoom->CopyTimesRun(croom->intrRoom);
624 for (cc=0;cc < MAX_HOTSPOTS;cc++)
625 thisroom.intrHotspot[cc]->CopyTimesRun(croom->intrHotspot[cc]);
626 for (cc=0;cc < MAX_INIT_SPR;cc++)
627 thisroom.intrObject[cc]->CopyTimesRun(croom->intrObject[cc]);
628 for (cc=0;cc < MAX_REGIONS;cc++)
629 thisroom.intrRegion[cc]->CopyTimesRun(croom->intrRegion[cc]);
630 }
631 }
632 if (croom->beenhere==0) {
633 croom->numobj=thisroom.numsprs;
634 croom->tsdatasize=0;
635 for (cc=0;cc<croom->numobj;cc++) {
636 croom->obj[cc].x=thisroom.sprs[cc].x;
637 croom->obj[cc].y=thisroom.sprs[cc].y;
638
639 if (thisroom.wasversion <= kRoomVersion_300a)
640 croom->obj[cc].y += divide_down_coordinate(spriteheight[thisroom.sprs[cc].sprnum]);
641
642 croom->obj[cc].num=thisroom.sprs[cc].sprnum;
643 croom->obj[cc].on=thisroom.sprs[cc].on;
644 croom->obj[cc].view=-1;
645 croom->obj[cc].loop=0;
646 croom->obj[cc].frame=0;
647 croom->obj[cc].wait=0;
648 croom->obj[cc].transparent=0;
649 croom->obj[cc].moving=-1;
650 croom->obj[cc].flags = thisroom.objectFlags[cc];
651 croom->obj[cc].baseline=-1;
652 croom->obj[cc].last_zoom = 100;
653 croom->obj[cc].last_width = 0;
654 croom->obj[cc].last_height = 0;
655 croom->obj[cc].blocking_width = 0;
656 croom->obj[cc].blocking_height = 0;
657 if (thisroom.objbaseline[cc]>=0)
658 // croom->obj[cc].baseoffs=thisroom.objbaseline[cc]-thisroom.sprs[cc].y;
659 croom->obj[cc].baseline=thisroom.objbaseline[cc];
660 }
661 memcpy(&croom->walkbehind_base[0],&thisroom.objyval[0],sizeof(short)*MAX_OBJ);
662 for (cc=0;cc<MAX_FLAGS;cc++) croom->flagstates[cc]=0;
663
664 /* // we copy these structs for the Score column to work
665 croom->misccond=thisroom.misccond;
666 for (cc=0;cc<MAX_HOTSPOTS;cc++)
667 croom->hscond[cc]=thisroom.hscond[cc];
668 for (cc=0;cc<MAX_INIT_SPR;cc++)
669 croom->objcond[cc]=thisroom.objcond[cc];*/
670
671 for (cc=0;cc < MAX_HOTSPOTS;cc++) {
672 croom->hotspot_enabled[cc] = 1;
673 }
674 for (cc = 0; cc < MAX_REGIONS; cc++) {
675 croom->region_enabled[cc] = 1;
676 }
677
678 croom->beenhere=1;
679 in_new_room=2;
680 }
681 else {
682 // We have been here before
683 for (int ff = 0; ff < thisroom.numLocalVars; ff++)
684 thisroom.localvars[ff].Value = croom->interactionVariableValues[ff];
685 }
686
687 update_polled_stuff_if_runtime();
688
689 if (thisroom.roomScripts == NULL)
690 {
691 // copy interactions from room file into our temporary struct
692 croom->intrRoom = thisroom.intrRoom[0];
693 for (cc=0;cc<MAX_HOTSPOTS;cc++)
694 croom->intrHotspot[cc] = thisroom.intrHotspot[cc][0];
695 for (cc=0;cc<MAX_INIT_SPR;cc++)
696 croom->intrObject[cc] = thisroom.intrObject[cc][0];
697 for (cc=0;cc<MAX_REGIONS;cc++)
698 croom->intrRegion[cc] = thisroom.intrRegion[cc][0];
699 }
700
701 objs=&croom->obj[0];
702
703 for (cc = 0; cc < MAX_INIT_SPR; cc++) {
704 // 64 bit: Using the id instead
705 // scrObj[cc].obj = &croom->obj[cc];
706 objectScriptObjNames[cc].Free();
707 }
708
709 for (cc = 0; cc < croom->numobj; cc++) {
710 // export the object's script object
711 if (thisroom.objectscriptnames[cc].IsEmpty())
712 continue;
713
714 if (thisroom.wasversion >= kRoomVersion_300a)
715 {
716 objectScriptObjNames[cc] = thisroom.objectscriptnames[cc];
717 }
718 else
719 {
720 objectScriptObjNames[cc].Format("o%s", thisroom.objectscriptnames[cc].GetCStr());
721 objectScriptObjNames[cc].MakeLower();
722 if (objectScriptObjNames[cc].GetLength() >= 2)
723 objectScriptObjNames[cc].SetAt(1, toupper(objectScriptObjNames[cc].GetAt(1)));
724 }
725
726 ccAddExternalDynamicObject(objectScriptObjNames[cc], &scrObj[cc], &ccDynamicObject);
727 }
728
729 for (cc = 0; cc < MAX_HOTSPOTS; cc++) {
730 if (thisroom.hotspotScriptNames[cc].IsEmpty())
731 continue;
732
733 ccAddExternalDynamicObject(thisroom.hotspotScriptNames[cc], &scrHotspot[cc], &ccDynamicHotspot);
734 }
735
736 our_eip=206;
737 /* THIS IS DONE IN THE EDITOR NOW
738 thisroom.ebpalShared[0] = 1;
739 for (dd = 1; dd < thisroom.num_bscenes; dd++) {
740 if (memcmp (&thisroom.bpalettes[dd][0], &palette[0], sizeof(color) * 256) == 0)
741 thisroom.ebpalShared[dd] = 1;
742 else
743 thisroom.ebpalShared[dd] = 0;
744 }
745 // only make the first frame shared if the last is
746 if (thisroom.ebpalShared[thisroom.num_bscenes - 1] == 0)
747 thisroom.ebpalShared[0] = 0;*/
748
749 update_polled_stuff_if_runtime();
750
751 our_eip = 210;
752 if (IS_ANTIALIAS_SPRITES) {
753 // sometimes the palette has corrupt entries, which crash
754 // the create_rgb_table call
755 // so, fix them
756 for (int ff = 0; ff < 256; ff++) {
757 if (palette[ff].r > 63)
758 palette[ff].r = 63;
759 if (palette[ff].g > 63)
760 palette[ff].g = 63;
761 if (palette[ff].b > 63)
762 palette[ff].b = 63;
763 }
764 create_rgb_table (&rgb_table, palette, NULL);
765 rgb_map = &rgb_table;
766 }
767 our_eip = 211;
768 if (forchar!=NULL) {
769 // if it's not a Restore Game
770
771 // if a following character is still waiting to come into the
772 // previous room, force it out so that the timer resets
773 for (int ff = 0; ff < game.numcharacters; ff++) {
774 if ((game.chars[ff].following >= 0) && (game.chars[ff].room < 0)) {
775 if ((game.chars[ff].following == game.playercharacter) &&
776 (forchar->prevroom == newnum))
777 // the player went back to the previous room, so make sure
778 // the following character is still there
779 game.chars[ff].room = newnum;
780 else
781 game.chars[ff].room = game.chars[game.chars[ff].following].room;
782 }
783 }
784
785 offsetx=0;
786 offsety=0;
787 forchar->prevroom=forchar->room;
788 forchar->room=newnum;
789 // only stop moving if it's a new room, not a restore game
790 for (cc=0;cc<game.numcharacters;cc++)
791 StopMoving(cc);
792
793 }
794
795 update_polled_stuff_if_runtime();
796
797 roominst=NULL;
798 if (debug_flags & DBG_NOSCRIPT) ;
799 else if (thisroom.compiled_script!=NULL) {
800 compile_room_script();
801 if (croom->tsdatasize>0) {
802 if (croom->tsdatasize != roominst->globaldatasize)
803 quit("room script data segment size has changed");
804 memcpy(&roominst->globaldata[0],croom->tsdata,croom->tsdatasize);
805 }
806 }
807 our_eip=207;
808 play.entered_edge = -1;
809
810 if ((new_room_x != SCR_NO_VALUE) && (forchar != NULL))
811 {
812 forchar->x = new_room_x;
813 forchar->y = new_room_y;
814
815 if (new_room_loop != SCR_NO_VALUE)
816 forchar->loop = new_room_loop;
817 }
818 new_room_x = SCR_NO_VALUE;
819 new_room_loop = SCR_NO_VALUE;
820
821 if ((new_room_pos>0) & (forchar!=NULL)) {
822 if (new_room_pos>=4000) {
823 play.entered_edge = 3;
824 forchar->y = thisroom.top + get_fixed_pixel_size(1);
825 forchar->x=new_room_pos%1000;
826 if (forchar->x==0) forchar->x=thisroom.width/2;
827 if (forchar->x <= thisroom.left)
828 forchar->x = thisroom.left + 3;
829 if (forchar->x >= thisroom.right)
830 forchar->x = thisroom.right - 3;
831 forchar->loop=0;
832 }
833 else if (new_room_pos>=3000) {
834 play.entered_edge = 2;
835 forchar->y = thisroom.bottom - get_fixed_pixel_size(1);
836 forchar->x=new_room_pos%1000;
837 if (forchar->x==0) forchar->x=thisroom.width/2;
838 if (forchar->x <= thisroom.left)
839 forchar->x = thisroom.left + 3;
840 if (forchar->x >= thisroom.right)
841 forchar->x = thisroom.right - 3;
842 forchar->loop=3;
843 }
844 else if (new_room_pos>=2000) {
845 play.entered_edge = 1;
846 forchar->x = thisroom.right - get_fixed_pixel_size(1);
847 forchar->y=new_room_pos%1000;
848 if (forchar->y==0) forchar->y=thisroom.height/2;
849 if (forchar->y <= thisroom.top)
850 forchar->y = thisroom.top + 3;
851 if (forchar->y >= thisroom.bottom)
852 forchar->y = thisroom.bottom - 3;
853 forchar->loop=1;
854 }
855 else if (new_room_pos>=1000) {
856 play.entered_edge = 0;
857 forchar->x = thisroom.left + get_fixed_pixel_size(1);
858 forchar->y=new_room_pos%1000;
859 if (forchar->y==0) forchar->y=thisroom.height/2;
860 if (forchar->y <= thisroom.top)
861 forchar->y = thisroom.top + 3;
862 if (forchar->y >= thisroom.bottom)
863 forchar->y = thisroom.bottom - 3;
864 forchar->loop=2;
865 }
866 // if starts on un-walkable area
867 if (get_walkable_area_pixel(forchar->x, forchar->y) == 0) {
868 if (new_room_pos>=3000) { // bottom or top of screen
869 int tryleft=forchar->x - 1,tryright=forchar->x + 1;
870 while (1) {
871 if (get_walkable_area_pixel(tryleft, forchar->y) > 0) {
872 forchar->x=tryleft; break; }
873 if (get_walkable_area_pixel(tryright, forchar->y) > 0) {
874 forchar->x=tryright; break; }
875 int nowhere=0;
876 if (tryleft>thisroom.left) { tryleft--; nowhere++; }
877 if (tryright<thisroom.right) { tryright++; nowhere++; }
878 if (nowhere==0) break; // no place to go, so leave him
879 }
880 }
881 else if (new_room_pos>=1000) { // left or right
882 int tryleft=forchar->y - 1,tryright=forchar->y + 1;
883 while (1) {
884 if (get_walkable_area_pixel(forchar->x, tryleft) > 0) {
885 forchar->y=tryleft; break; }
886 if (get_walkable_area_pixel(forchar->x, tryright) > 0) {
887 forchar->y=tryright; break; }
888 int nowhere=0;
889 if (tryleft>thisroom.top) { tryleft--; nowhere++; }
890 if (tryright<thisroom.bottom) { tryright++; nowhere++; }
891 if (nowhere==0) break; // no place to go, so leave him
892 }
893 }
894 }
895 new_room_pos=0;
896 }
897 if (forchar!=NULL) {
898 play.entered_at_x=forchar->x;
899 play.entered_at_y=forchar->y;
900 if (forchar->x >= thisroom.right)
901 play.entered_edge = 1;
902 else if (forchar->x <= thisroom.left)
903 play.entered_edge = 0;
904 else if (forchar->y >= thisroom.bottom)
905 play.entered_edge = 2;
906 else if (forchar->y <= thisroom.top)
907 play.entered_edge = 3;
908 }
909 /* if ((playerchar->x > thisroom.width) | (playerchar->y > thisroom.height))
910 quit("!NewRoomEx: x/y co-ordinates are invalid");*/
911 if (thisroom.options[ST_TUNE]>0)
912 PlayMusicResetQueue(thisroom.options[ST_TUNE]);
913
914 our_eip=208;
915 if (forchar!=NULL) {
916 if (thisroom.options[ST_MANDISABLED]==0) { forchar->on=1;
917 enable_cursor_mode(0); }
918 else {
919 forchar->on=0;
920 disable_cursor_mode(0);
921 // remember which character we turned off, in case they
922 // use SetPlyaerChracter within this room (so we re-enable
923 // the correct character when leaving the room)
924 play.temporarily_turned_off_character = game.playercharacter;
925 }
926 if (forchar->flags & CHF_FIXVIEW) ;
927 else if (thisroom.options[ST_MANVIEW]==0) forchar->view=forchar->defview;
928 else forchar->view=thisroom.options[ST_MANVIEW]-1;
929 forchar->frame=0; // make him standing
930 }
931 color_map = NULL;
932
933 our_eip = 209;
934 update_polled_stuff_if_runtime();
935 generate_light_table();
936 update_music_volume();
937 update_viewport();
938 our_eip = 212;
939 invalidate_screen();
940 for (cc=0;cc<croom->numobj;cc++) {
941 if (objs[cc].on == 2)
942 MergeObject(cc);
943 }
944 new_room_flags=0;
945 play.gscript_timer=-1; // avoid screw-ups with changing screens
946 play.player_on_region = 0;
947 // trash any input which they might have done while it was loading
948 clear_input_buffer();
949 // no fade in, so set the palette immediately in case of 256-col sprites
950 if (game.color_depth > 1)
951 setpal();
952
953 our_eip=220;
954 update_polled_stuff_if_runtime();
955 debug_script_log("Now in room %d", displayed_room);
956 guis_need_update = 1;
957 pl_run_plugin_hooks(AGSE_ENTERROOM, displayed_room);
958 // MoveToWalkableArea(game.playercharacter);
959 // MSS_CHECK_ALL_BLOCKS;
960 }
961
962 extern int psp_clear_cache_on_room_change;
963
964 // new_room: changes the current room number, and loads the new room from disk
new_room(int newnum,CharacterInfo * forchar)965 void new_room(int newnum,CharacterInfo*forchar) {
966 EndSkippingUntilCharStops();
967
968 debug_script_log("Room change requested to room %d", newnum);
969
970 update_polled_stuff_if_runtime();
971
972 // we are currently running Leaves Screen scripts
973 in_leaves_screen = newnum;
974
975 // player leaves screen event
976 run_room_event(8);
977 // Run the global OnRoomLeave event
978 run_on_event (GE_LEAVE_ROOM, RuntimeScriptValue().SetInt32(displayed_room));
979
980 pl_run_plugin_hooks(AGSE_LEAVEROOM, displayed_room);
981
982 // update the new room number if it has been altered by OnLeave scripts
983 newnum = in_leaves_screen;
984 in_leaves_screen = -1;
985
986 if ((playerchar->following >= 0) &&
987 (game.chars[playerchar->following].room != newnum)) {
988 // the player character is following another character,
989 // who is not in the new room. therefore, abort the follow
990 playerchar->following = -1;
991 }
992 update_polled_stuff_if_runtime();
993
994 // change rooms
995 unload_old_room();
996
997 if (psp_clear_cache_on_room_change)
998 {
999 // Delete all cached sprites
1000 spriteset.removeAll();
1001
1002 // Delete all gui background images
1003 for (int i = 0; i < game.numgui; i++)
1004 {
1005 delete guibg[i];
1006 guibg[i] = NULL;
1007
1008 if (guibgbmp[i])
1009 gfxDriver->DestroyDDB(guibgbmp[i]);
1010 guibgbmp[i] = NULL;
1011 }
1012 guis_need_update = 1;
1013 }
1014
1015 update_polled_stuff_if_runtime();
1016
1017 load_new_room(newnum,forchar);
1018 }
1019
find_highest_room_entered()1020 int find_highest_room_entered() {
1021 int qq,fndas=-1;
1022 for (qq=0;qq<MAX_ROOMS;qq++) {
1023 if (isRoomStatusValid(qq) && (getRoomStatus(qq)->beenhere != 0))
1024 fndas = qq;
1025 }
1026 // This is actually legal - they might start in room 400 and save
1027 //if (fndas<0) quit("find_highest_room: been in no rooms?");
1028 return fndas;
1029 }
1030
1031 extern long t1; // defined in ac_main
1032
first_room_initialization()1033 void first_room_initialization() {
1034 starting_room = displayed_room;
1035 t1 = time(NULL);
1036 lastcounter=0;
1037 loopcounter=0;
1038 mouse_z_was = mouse_z;
1039 }
1040
check_new_room()1041 void check_new_room() {
1042 // if they're in a new room, run Player Enters Screen and on_event(ENTER_ROOM)
1043 if ((in_new_room>0) & (in_new_room!=3)) {
1044 EventHappened evh;
1045 evh.type = EV_RUNEVBLOCK;
1046 evh.data1 = EVB_ROOM;
1047 evh.data2 = 0;
1048 evh.data3 = 5;
1049 evh.player=game.playercharacter;
1050 // make sure that any script calls don't re-call enters screen
1051 int newroom_was = in_new_room;
1052 in_new_room = 0;
1053 play.disabled_user_interface ++;
1054 process_event(&evh);
1055 play.disabled_user_interface --;
1056 in_new_room = newroom_was;
1057 // setevent(EV_RUNEVBLOCK,EVB_ROOM,0,5);
1058 }
1059 }
1060
compile_room_script()1061 void compile_room_script() {
1062 ccError = 0;
1063
1064 roominst = ccInstance::CreateFromScript(thisroom.compiled_script);
1065
1066 if ((ccError!=0) || (roominst==NULL)) {
1067 char thiserror[400];
1068 sprintf(thiserror, "Unable to create local script: %s", ccErrorString);
1069 quit(thiserror);
1070 }
1071
1072 roominstFork = roominst->Fork();
1073 if (roominstFork == NULL)
1074 quitprintf("Unable to create forked room instance: %s", ccErrorString);
1075
1076 repExecAlways.roomHasFunction = true;
1077 lateRepExecAlways.roomHasFunction = true;
1078 getDialogOptionsDimensionsFunc.roomHasFunction = true;
1079 }
1080
1081 int bg_just_changed = 0;
1082
on_background_frame_change()1083 void on_background_frame_change () {
1084
1085 invalidate_screen();
1086 mark_current_background_dirty();
1087 invalidate_cached_walkbehinds();
1088
1089 // get the new frame's palette
1090 memcpy (palette, thisroom.bpalettes[play.bg_frame], sizeof(color) * 256);
1091
1092 // hi-colour, update the palette. It won't have an immediate effect
1093 // but will be drawn properly when the screen fades in
1094 if (game.color_depth > 1)
1095 setpal();
1096
1097 if (in_enters_screen)
1098 return;
1099
1100 // Don't update the palette if it hasn't changed
1101 if (thisroom.ebpalShared[play.bg_frame])
1102 return;
1103
1104 // 256-colours, tell it to update the palette (will actually be done as
1105 // close as possible to the screen update to prevent flicker problem)
1106 if (game.color_depth == 1)
1107 bg_just_changed = 1;
1108 }
1109
croom_ptr_clear()1110 void croom_ptr_clear()
1111 {
1112 croom = NULL;
1113 objs = NULL;
1114 }
1115
1116 //=============================================================================
1117 //
1118 // Script API Functions
1119 //
1120 //=============================================================================
1121
1122 #include "debug/out.h"
1123 #include "script/script_api.h"
1124 #include "script/script_runtime.h"
1125 #include "ac/dynobj/scriptstring.h"
1126
1127 extern ScriptString myScriptStringImpl;
1128
1129 // ScriptDrawingSurface* (int backgroundNumber)
Sc_Room_GetDrawingSurfaceForBackground(const RuntimeScriptValue * params,int32_t param_count)1130 RuntimeScriptValue Sc_Room_GetDrawingSurfaceForBackground(const RuntimeScriptValue *params, int32_t param_count)
1131 {
1132 API_SCALL_OBJAUTO_PINT(ScriptDrawingSurface, Room_GetDrawingSurfaceForBackground);
1133 }
1134
1135 // int (const char *property)
Sc_Room_GetProperty(const RuntimeScriptValue * params,int32_t param_count)1136 RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t param_count)
1137 {
1138 API_SCALL_INT_POBJ(Room_GetProperty, const char);
1139 }
1140
1141 // const char* (const char *property)
Sc_Room_GetTextProperty(const RuntimeScriptValue * params,int32_t param_count)1142 RuntimeScriptValue Sc_Room_GetTextProperty(const RuntimeScriptValue *params, int32_t param_count)
1143 {
1144 API_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Room_GetTextProperty, const char);
1145 }
1146
Sc_Room_SetProperty(const RuntimeScriptValue * params,int32_t param_count)1147 RuntimeScriptValue Sc_Room_SetProperty(const RuntimeScriptValue *params, int32_t param_count)
1148 {
1149 API_SCALL_BOOL_POBJ_PINT(Room_SetProperty, const char);
1150 }
1151
1152 // const char* (const char *property)
Sc_Room_SetTextProperty(const RuntimeScriptValue * params,int32_t param_count)1153 RuntimeScriptValue Sc_Room_SetTextProperty(const RuntimeScriptValue *params, int32_t param_count)
1154 {
1155 API_SCALL_BOOL_POBJ2(Room_SetTextProperty, const char, const char);
1156 }
1157
1158 // int ()
Sc_Room_GetBottomEdge(const RuntimeScriptValue * params,int32_t param_count)1159 RuntimeScriptValue Sc_Room_GetBottomEdge(const RuntimeScriptValue *params, int32_t param_count)
1160 {
1161 API_SCALL_INT(Room_GetBottomEdge);
1162 }
1163
1164 // int ()
Sc_Room_GetColorDepth(const RuntimeScriptValue * params,int32_t param_count)1165 RuntimeScriptValue Sc_Room_GetColorDepth(const RuntimeScriptValue *params, int32_t param_count)
1166 {
1167 API_SCALL_INT(Room_GetColorDepth);
1168 }
1169
1170 // int ()
Sc_Room_GetHeight(const RuntimeScriptValue * params,int32_t param_count)1171 RuntimeScriptValue Sc_Room_GetHeight(const RuntimeScriptValue *params, int32_t param_count)
1172 {
1173 API_SCALL_INT(Room_GetHeight);
1174 }
1175
1176 // int ()
Sc_Room_GetLeftEdge(const RuntimeScriptValue * params,int32_t param_count)1177 RuntimeScriptValue Sc_Room_GetLeftEdge(const RuntimeScriptValue *params, int32_t param_count)
1178 {
1179 API_SCALL_INT(Room_GetLeftEdge);
1180 }
1181
1182 // const char* (int index)
Sc_Room_GetMessages(const RuntimeScriptValue * params,int32_t param_count)1183 RuntimeScriptValue Sc_Room_GetMessages(const RuntimeScriptValue *params, int32_t param_count)
1184 {
1185 API_SCALL_OBJ_PINT(const char, myScriptStringImpl, Room_GetMessages);
1186 }
1187
1188 // int ()
Sc_Room_GetMusicOnLoad(const RuntimeScriptValue * params,int32_t param_count)1189 RuntimeScriptValue Sc_Room_GetMusicOnLoad(const RuntimeScriptValue *params, int32_t param_count)
1190 {
1191 API_SCALL_INT(Room_GetMusicOnLoad);
1192 }
1193
1194 // int ()
Sc_Room_GetObjectCount(const RuntimeScriptValue * params,int32_t param_count)1195 RuntimeScriptValue Sc_Room_GetObjectCount(const RuntimeScriptValue *params, int32_t param_count)
1196 {
1197 API_SCALL_INT(Room_GetObjectCount);
1198 }
1199
1200 // int ()
Sc_Room_GetRightEdge(const RuntimeScriptValue * params,int32_t param_count)1201 RuntimeScriptValue Sc_Room_GetRightEdge(const RuntimeScriptValue *params, int32_t param_count)
1202 {
1203 API_SCALL_INT(Room_GetRightEdge);
1204 }
1205
1206 // int ()
Sc_Room_GetTopEdge(const RuntimeScriptValue * params,int32_t param_count)1207 RuntimeScriptValue Sc_Room_GetTopEdge(const RuntimeScriptValue *params, int32_t param_count)
1208 {
1209 API_SCALL_INT(Room_GetTopEdge);
1210 }
1211
1212 // int ()
Sc_Room_GetWidth(const RuntimeScriptValue * params,int32_t param_count)1213 RuntimeScriptValue Sc_Room_GetWidth(const RuntimeScriptValue *params, int32_t param_count)
1214 {
1215 API_SCALL_INT(Room_GetWidth);
1216 }
1217
1218 // void (int xx,int yy,int mood)
Sc_ProcessClick(const RuntimeScriptValue * params,int32_t param_count)1219 RuntimeScriptValue Sc_ProcessClick(const RuntimeScriptValue *params, int32_t param_count)
1220 {
1221 API_SCALL_VOID_PINT3(ProcessClick);
1222 }
1223
1224
RegisterRoomAPI()1225 void RegisterRoomAPI()
1226 {
1227 ccAddExternalStaticFunction("Room::GetDrawingSurfaceForBackground^1", Sc_Room_GetDrawingSurfaceForBackground);
1228 ccAddExternalStaticFunction("Room::GetProperty^1", Sc_Room_GetProperty);
1229 ccAddExternalStaticFunction("Room::GetTextProperty^1", Sc_Room_GetTextProperty);
1230 ccAddExternalStaticFunction("Room::SetProperty^2", Sc_Room_SetProperty);
1231 ccAddExternalStaticFunction("Room::SetTextProperty^2", Sc_Room_SetTextProperty);
1232 ccAddExternalStaticFunction("Room::ProcessClick^3", Sc_ProcessClick);
1233 ccAddExternalStaticFunction("ProcessClick", Sc_ProcessClick);
1234 ccAddExternalStaticFunction("Room::get_BottomEdge", Sc_Room_GetBottomEdge);
1235 ccAddExternalStaticFunction("Room::get_ColorDepth", Sc_Room_GetColorDepth);
1236 ccAddExternalStaticFunction("Room::get_Height", Sc_Room_GetHeight);
1237 ccAddExternalStaticFunction("Room::get_LeftEdge", Sc_Room_GetLeftEdge);
1238 ccAddExternalStaticFunction("Room::geti_Messages", Sc_Room_GetMessages);
1239 ccAddExternalStaticFunction("Room::get_MusicOnLoad", Sc_Room_GetMusicOnLoad);
1240 ccAddExternalStaticFunction("Room::get_ObjectCount", Sc_Room_GetObjectCount);
1241 ccAddExternalStaticFunction("Room::get_RightEdge", Sc_Room_GetRightEdge);
1242 ccAddExternalStaticFunction("Room::get_TopEdge", Sc_Room_GetTopEdge);
1243 ccAddExternalStaticFunction("Room::get_Width", Sc_Room_GetWidth);
1244
1245 /* ----------------------- Registering unsafe exports for plugins -----------------------*/
1246
1247 ccAddExternalFunctionForPlugin("Room::GetDrawingSurfaceForBackground^1", (void*)Room_GetDrawingSurfaceForBackground);
1248 ccAddExternalFunctionForPlugin("Room::GetProperty^1", (void*)Room_GetProperty);
1249 ccAddExternalFunctionForPlugin("Room::GetTextProperty^1", (void*)Room_GetTextProperty);
1250 ccAddExternalFunctionForPlugin("Room::get_BottomEdge", (void*)Room_GetBottomEdge);
1251 ccAddExternalFunctionForPlugin("Room::get_ColorDepth", (void*)Room_GetColorDepth);
1252 ccAddExternalFunctionForPlugin("Room::get_Height", (void*)Room_GetHeight);
1253 ccAddExternalFunctionForPlugin("Room::get_LeftEdge", (void*)Room_GetLeftEdge);
1254 ccAddExternalFunctionForPlugin("Room::geti_Messages", (void*)Room_GetMessages);
1255 ccAddExternalFunctionForPlugin("Room::get_MusicOnLoad", (void*)Room_GetMusicOnLoad);
1256 ccAddExternalFunctionForPlugin("Room::get_ObjectCount", (void*)Room_GetObjectCount);
1257 ccAddExternalFunctionForPlugin("Room::get_RightEdge", (void*)Room_GetRightEdge);
1258 ccAddExternalFunctionForPlugin("Room::get_TopEdge", (void*)Room_GetTopEdge);
1259 ccAddExternalFunctionForPlugin("Room::get_Width", (void*)Room_GetWidth);
1260 }
1261