Example #1
0
void RawDrawImageOffset(int xx, int yy, int slot) {

    if ((current_screen_resolution_multiplier == 1) && game.IsHiRes()) {
        // running a 640x400 game at 320x200, adjust
        xx /= 2;
        yy /= 2;
    }
    else if ((current_screen_resolution_multiplier > 1) && !game.IsHiRes()) {
        // running a 320x200 game at 640x400, adjust
        xx *= 2;
        yy *= 2;
    }

    RawDrawImageCore(xx, yy, slot);
}
Example #2
0
void move_object(int objj,int tox,int toy,int spee,int ignwal) {

    if (!is_valid_object(objj))
        quit("!MoveObject: invalid object number");

    // AGS <= 2.61 uses MoveObject with spp=-1 internally instead of SetObjectPosition
    if ((loaded_game_file_version <= kGameVersion_261) && (spee == -1))
    {
        objs[objj].x = tox;
        objs[objj].y = toy;
        return;
    }

    DEBUG_CONSOLE("Object %d start move to %d,%d", objj, tox, toy);

    int objX = convert_to_low_res(objs[objj].x);
    int objY = convert_to_low_res(objs[objj].y);
    tox = convert_to_low_res(tox);
    toy = convert_to_low_res(toy);

    set_route_move_speed(spee, spee);
    set_color_depth(8);
    int mslot=find_route(objX, objY, tox, toy, prepare_walkable_areas(-1), objj+1, 1, ignwal);
    set_color_depth(ScreenResolution.ColorDepth);
    if (mslot>0) {
        objs[objj].moving = mslot;
        mls[mslot].direct = ignwal;

        if ((game.options[OPT_NATIVECOORDINATES] != 0) &&
            game.IsHiRes())
        {
            convert_move_path_to_high_res(&mls[mslot]);
        }
    }
}
Example #3
0
void adjust_sizes_for_resolution(int filever)
{
    int ee;
    for (ee = 0; ee < game.numcursors; ee++) 
    {
        game.mcurs[ee].hotx = adjust_pixel_size_for_loaded_data(game.mcurs[ee].hotx, filever);
        game.mcurs[ee].hoty = adjust_pixel_size_for_loaded_data(game.mcurs[ee].hoty, filever);
    }

    for (ee = 0; ee < game.numinvitems; ee++) 
    {
        adjust_pixel_sizes_for_loaded_data(&game.invinfo[ee].hotx, &game.invinfo[ee].hoty, filever);
    }

    for (ee = 0; ee < game.numgui; ee++) 
    {
        GUIMain*cgp=&guis[ee];
        adjust_pixel_sizes_for_loaded_data(&cgp->x, &cgp->y, filever);
        if (cgp->wid < 1)
            cgp->wid = 1;
        if (cgp->hit < 1)
            cgp->hit = 1;
        // Temp fix for older games
        if (cgp->wid == BASEWIDTH - 1)
            cgp->wid = BASEWIDTH;

        adjust_pixel_sizes_for_loaded_data(&cgp->wid, &cgp->hit, filever);

        cgp->popupyp = adjust_pixel_size_for_loaded_data(cgp->popupyp, filever);

        for (ff = 0; ff < cgp->numobjs; ff++) 
        {
            adjust_pixel_sizes_for_loaded_data(&cgp->objs[ff]->x, &cgp->objs[ff]->y, filever);
            adjust_pixel_sizes_for_loaded_data(&cgp->objs[ff]->wid, &cgp->objs[ff]->hit, filever);
            cgp->objs[ff]->activated=0;
        }
    }

    if ((filever >= 37) && (game.options[OPT_NATIVECOORDINATES] == 0) &&
        game.IsHiRes())
    {
        // New 3.1 format game file, but with Use Native Coordinates off

        for (ee = 0; ee < game.numcharacters; ee++) 
        {
            game.chars[ee].x /= 2;
            game.chars[ee].y /= 2;
        }

        for (ee = 0; ee < numguiinv; ee++)
        {
            guiinv[ee].itemWidth /= 2;
            guiinv[ee].itemHeight /= 2;
        }
    }

}
Example #4
0
void adjust_sizes_for_resolution(int filever)
{
    int ee;
    for (ee = 0; ee < game.numcursors; ee++) 
    {
        game.mcurs[ee].hotx = adjust_pixel_size_for_loaded_data(game.mcurs[ee].hotx, filever);
        game.mcurs[ee].hoty = adjust_pixel_size_for_loaded_data(game.mcurs[ee].hoty, filever);
    }

    for (ee = 0; ee < game.numinvitems; ee++) 
    {
        adjust_pixel_sizes_for_loaded_data(&game.invinfo[ee].hotx, &game.invinfo[ee].hoty, filever);
    }

    for (ee = 0; ee < game.numgui; ee++) 
    {
        GUIMain*cgp=&guis[ee];
        adjust_pixel_sizes_for_loaded_data(&cgp->X, &cgp->Y, filever);
        if (cgp->Width < 1)
            cgp->Width = 1;
        if (cgp->Height < 1)
            cgp->Height = 1;
        // Temp fix for older games
        if (cgp->Width == BASEWIDTH - 1)
            cgp->Width = BASEWIDTH;

        adjust_pixel_sizes_for_loaded_data(&cgp->Width, &cgp->Height, filever);

        cgp->PopupAtMouseY = adjust_pixel_size_for_loaded_data(cgp->PopupAtMouseY, filever);

        for (ff = 0; ff < cgp->ControlCount; ff++) 
        {
            adjust_pixel_sizes_for_loaded_data(&cgp->Controls[ff]->X, &cgp->Controls[ff]->Y, filever);
            adjust_pixel_sizes_for_loaded_data(&cgp->Controls[ff]->Width, &cgp->Controls[ff]->Height, filever);
            cgp->Controls[ff]->IsActivated = false;
        }
    }

    if ((filever >= 37) && (game.options[OPT_NATIVECOORDINATES] == 0) &&
        game.IsHiRes())
    {
        // New 3.1 format game file, but with Use Native Coordinates off

        for (ee = 0; ee < game.numcharacters; ee++) 
        {
            game.chars[ee].x /= 2;
            game.chars[ee].y /= 2;
        }

        for (ee = 0; ee < numguiinv; ee++)
        {
            guiinv[ee].ItemWidth /= 2;
            guiinv[ee].ItemHeight /= 2;
        }
    }

}
Example #5
0
void engine_init_resolution_settings(const Size game_size)
{
    Debug::Printf("Initializing resolution settings");

    play.SetViewport(game_size);

    if (game.IsHiRes())
    {
        play.native_size.Width = game_size.Width / 2;
        play.native_size.Height = game_size.Height / 2;
        wtext_multiply = 2;
    }
    else
    {
        play.native_size.Width = game_size.Width;
        play.native_size.Height = game_size.Height;
        wtext_multiply = 1;
    }

    usetup.textheight = getfontheight_outlined(0) + 1;
    current_screen_resolution_multiplier = game_size.Width / play.native_size.Width;

    if (game.IsHiRes() &&
        (game.options[OPT_NATIVECOORDINATES]))
    {
        play.native_size.Width *= 2;
        play.native_size.Height *= 2;
    }

    // don't allow them to force a 256-col game to hi-color
    if (game.color_depth < 2)
        usetup.force_hicolor_mode = false;

    Debug::Printf(kDbgMsg_Init, "Game native resolution: %d x %d (%d bit)%s", game_size.Width, game_size.Height, game.color_depth * 8,
        game.options[OPT_LETTERBOX] == 0 ? "": " letterbox-by-design");

    adjust_sizes_for_resolution(loaded_game_file_version);
    engine_setup_system_gamesize();
}
Example #6
0
void engine_init_screen_settings()
{
    Out::FPrint("Initializing screen settings");

    // default shifts for how we store the sprite data

#if defined(PSP_VERSION)
    // PSP: Switch b<>r for 15/16 bit.
    _rgb_r_shift_32 = 16;
    _rgb_g_shift_32 = 8;
    _rgb_b_shift_32 = 0;
    _rgb_b_shift_16 = 11;
    _rgb_g_shift_16 = 5;
    _rgb_r_shift_16 = 0;
    _rgb_b_shift_15 = 10;
    _rgb_g_shift_15 = 5;
    _rgb_r_shift_15 = 0;
#else
    _rgb_r_shift_32 = 16;
    _rgb_g_shift_32 = 8;
    _rgb_b_shift_32 = 0;
    _rgb_r_shift_16 = 11;
    _rgb_g_shift_16 = 5;
    _rgb_b_shift_16 = 0;
    _rgb_r_shift_15 = 10;
    _rgb_g_shift_15 = 5;
    _rgb_b_shift_15 = 0;
#endif

    usetup.base_width = 320;
    usetup.base_height = 200;

    GameSize = ResolutionTypeToSize(game.default_resolution);
    scrnwid = GameSize.Width;
    scrnhit = GameSize.Height;

    if (game.IsHiRes())
    {
        usetup.base_width = scrnwid / 2;
        usetup.base_height = scrnhit / 2;
        wtext_multiply = 2;
    }
    else
    {
        usetup.base_width = scrnwid;
        usetup.base_height = scrnhit;
        wtext_multiply = 1;
    }

    usetup.textheight = wgetfontheight(0) + 1;

    vesa_xres=scrnwid; vesa_yres=scrnhit;
    current_screen_resolution_multiplier = scrnwid / BASEWIDTH;

    if (game.IsHiRes() &&
        (game.options[OPT_NATIVECOORDINATES]))
    {
        usetup.base_width *= 2;
        usetup.base_height *= 2;
    }

    game.options[OPT_LETTERBOX] = force_letterbox > 0 ? 1 : 0;

    // don't allow them to force a 256-col game to hi-color
    if (game.color_depth < 2)
        usetup.force_hicolor_mode = 0;

    firstDepth = 8, secondDepth = 8;
    if ((game.color_depth == 2) || (force_16bit) || (usetup.force_hicolor_mode)) {
        firstDepth = 16;
        secondDepth = 15;
    }
    else if (game.color_depth > 2) {
        firstDepth = 32;
        secondDepth = 24;
    }

    Out::FPrint("Game native resolution: %d x %d (%d bit), letterbox %s, side borders %s", scrnwid, scrnhit, firstDepth,
        game.options[OPT_LETTERBOX] == 0 ? "optional" : "forced", usetup.enable_side_borders != 0 ? "enabled" : "disabled");

    adjust_sizes_for_resolution(loaded_game_file_version);
}
Example #7
0
void engine_init_screen_settings(Size &game_size, Size &screen_size)
{
    Out::FPrint("Initializing screen settings");

    // default shifts for how we store the sprite data

#if defined(PSP_VERSION)
    // PSP: Switch b<>r for 15/16 bit.
    _rgb_r_shift_32 = 16;
    _rgb_g_shift_32 = 8;
    _rgb_b_shift_32 = 0;
    _rgb_b_shift_16 = 11;
    _rgb_g_shift_16 = 5;
    _rgb_r_shift_16 = 0;
    _rgb_b_shift_15 = 10;
    _rgb_g_shift_15 = 5;
    _rgb_r_shift_15 = 0;
#else
    _rgb_r_shift_32 = 16;
    _rgb_g_shift_32 = 8;
    _rgb_b_shift_32 = 0;
    _rgb_r_shift_16 = 11;
    _rgb_g_shift_16 = 5;
    _rgb_b_shift_16 = 0;
    _rgb_r_shift_15 = 10;
    _rgb_g_shift_15 = 5;
    _rgb_b_shift_15 = 0;
#endif

    GameSize = ResolutionTypeToSize(game.default_resolution);
    if (GameSize.IsNull())
        quit("Unable to define native game resolution, could be unsupported game format.");

    scrnwid = GameSize.Width;
    scrnhit = GameSize.Height;

    if (game.IsHiRes())
    {
        usetup.base_width = scrnwid / 2;
        usetup.base_height = scrnhit / 2;
        wtext_multiply = 2;
    }
    else
    {
        usetup.base_width = scrnwid;
        usetup.base_height = scrnhit;
        wtext_multiply = 1;
    }

    usetup.textheight = wgetfontheight(0) + 1;

    vesa_xres=scrnwid; vesa_yres=scrnhit;
    current_screen_resolution_multiplier = scrnwid / BASEWIDTH;

    if (game.IsHiRes() &&
        (game.options[OPT_NATIVECOORDINATES]))
    {
        usetup.base_width *= 2;
        usetup.base_height *= 2;
    }

    // don't allow them to force a 256-col game to hi-color
    if (game.color_depth < 2)
        usetup.force_hicolor_mode = false;

    firstDepth = 8, secondDepth = 8;
    if ((game.color_depth == 2) || (force_16bit) || (usetup.force_hicolor_mode)) {
        firstDepth = 16;
        secondDepth = 15;
    }
    else if (game.color_depth > 2) {
        firstDepth = 32;
        secondDepth = 24;
    }

    // The letterbox-by-design game property requests that game frame must
    // include black horizontal borders of fixed height.
    // If the letterbox option is disabled, then the game frame size will be
    // equal to native game size.
    LetterboxedGameSize = ResolutionTypeToSize(game.default_resolution, game.options[OPT_LETTERBOX] != 0);
    game_size = LetterboxedGameSize;
    screen_size = Size(0, 0);

    // Log out display information
    Size device_size;
    if (get_desktop_resolution(&device_size.Width, &device_size.Height) == 0)
        Out::FPrint("Device display resolution: %d x %d", device_size.Width, device_size.Height);
    else
        Out::FPrint("Unable to obtain device resolution");

    Out::FPrint("Game native resolution: %d x %d (%d bit)%s", scrnwid, scrnhit, firstDepth,
        game.options[OPT_LETTERBOX] == 0 ? "": " letterbox-by-design");
    Out::FPrint("Game settings: %s, letterbox %s, side borders %s",
        usetup.windowed ? "windowed" : "fullscreen",
        usetup.prefer_letterbox ? "acceptable" : "undesirable", usetup.prefer_sideborders ? "acceptable" : "undesirable");

    adjust_sizes_for_resolution(loaded_game_file_version);
}
Example #8
0
// forchar = playerchar on NewRoom, or NULL if restore saved game
void load_new_room(int newnum, CharacterInfo*forchar) {

    Out::FPrint("Loading room %d", newnum);

    String room_filename;
    int cc;
    done_es_error = 0;
    play.room_changes ++;
    set_color_depth(8);
    displayed_room=newnum;

    room_filename.Format("room%d.crm", newnum);
    if (newnum == 0) {
        // support both room0.crm and intro.crm
        // 2.70: Renamed intro.crm to room0.crm, to stop it causing confusion
        if (loaded_game_file_version < kGameVersion_270 && Common::AssetManager::DoesAssetExist("intro.crm") ||
            loaded_game_file_version >= kGameVersion_270 && !Common::AssetManager::DoesAssetExist(room_filename))
        {
            room_filename = "intro.crm";
        }
    }
    // reset these back, because they might have been changed.
    delete thisroom.object;
    thisroom.object=BitmapHelper::CreateBitmap(320,200);

    delete thisroom.ebscene[0];
    thisroom.ebscene[0] = BitmapHelper::CreateBitmap(320,200);

    update_polled_stuff_if_runtime();

    // load the room from disk
    our_eip=200;
    thisroom.gameId = NO_GAME_ID_IN_ROOM_FILE;
    load_room(room_filename, &thisroom, game.IsHiRes());

    if ((thisroom.gameId != NO_GAME_ID_IN_ROOM_FILE) &&
        (thisroom.gameId != game.uniqueid)) {
            quitprintf("!Unable to load '%s'. This room file is assigned to a different game.", room_filename.GetCStr());
    }

    if (game.IsHiRes() && (game.options[OPT_NATIVECOORDINATES] == 0))
    {
        convert_room_coordinates_to_low_res(&thisroom);
    }

    update_polled_stuff_if_runtime();
    our_eip=201;
    /*  // apparently, doing this stops volume spiking between tracks
    if (thisroom.options[ST_TUNE]>0) {
    stopmusic();
    delay(100);
    }*/

    play.room_width = thisroom.width;
    play.room_height = thisroom.height;
    play.anim_background_speed = thisroom.bscene_anim_speed;
    play.bg_anim_delay = play.anim_background_speed;

    int dd;
    // do the palette
    for (cc=0;cc<256;cc++) {
        if (game.paluses[cc]==PAL_BACKGROUND)
            palette[cc]=thisroom.pal[cc];
        else {
            // copy the gamewide colours into the room palette
            for (dd = 0; dd < thisroom.num_bscenes; dd++)
                thisroom.bpalettes[dd][cc] = palette[cc];
        }
    }

    if ((thisroom.ebscene[0]->GetColorDepth() == 8) &&
        (final_col_dep > 8))
        select_palette(palette);

    for (cc=0;cc<thisroom.num_bscenes;cc++) {
        update_polled_stuff_if_runtime();
#ifdef USE_15BIT_FIX
        // convert down scenes from 16 to 15-bit if necessary
        if ((final_col_dep != game.color_depth*8) &&
            (thisroom.ebscene[cc]->GetColorDepth() == game.color_depth * 8)) {
                Bitmap *oldblock = thisroom.ebscene[cc];
                thisroom.ebscene[cc] = convert_16_to_15(oldblock);
                delete oldblock;
        }
        else if ((thisroom.ebscene[cc]->GetColorDepth () == 16) && (convert_16bit_bgr == 1))
            thisroom.ebscene[cc] = convert_16_to_16bgr (thisroom.ebscene[cc]);
#endif

#if defined (AGS_INVERTED_COLOR_ORDER)
        // PSP: Convert 32 bit backgrounds.
        if (thisroom.ebscene[cc]->GetColorDepth() == 32)
            thisroom.ebscene[cc] = convert_32_to_32bgr(thisroom.ebscene[cc]);
#endif

        thisroom.ebscene[cc] = gfxDriver->ConvertBitmapToSupportedColourDepth(thisroom.ebscene[cc]);
    }

    if ((thisroom.ebscene[0]->GetColorDepth() == 8) &&
        (final_col_dep > 8))
        unselect_palette();

    update_polled_stuff_if_runtime();

    our_eip=202;
    const int real_room_height = multiply_up_coordinate(thisroom.height);
    // Frame size is updated when letterbox mode is on, or when room's size is smaller than game's size.
    // NOTE: if "want_letterbox" is false, GameSize.Height = final_scrn_hit always.
    if (usetup.want_letterbox ||
            real_room_height < GameSize.Height || scrnhit < GameSize.Height) {
        int abscreen=0;

        Bitmap *ds = GetVirtualScreen();
        if (ds==BitmapHelper::GetScreenBitmap()) abscreen=1;
        else if (ds==virtual_screen) abscreen=2;
        int newScreenHeight = final_scrn_hit;
        // [IKM] 2015-05-04: in original engine the letterbox feature only allowed viewports of
        // either 200 or 240 (400 and 480) pixels, if the room height was equal or greater than 200 (400).
        const int viewport_height = real_room_height < GameSize.Height ? real_room_height :
            (real_room_height >= GameSize.Height && real_room_height < LetterboxedGameSize.Height) ? GameSize.Height :
            LetterboxedGameSize.Height;
        if (viewport_height < final_scrn_hit) {
            clear_letterbox_borders();
            newScreenHeight = viewport_height;
        }

        // If the game is run not in letterbox mode, but there's a random room smaller than the game size,
        // then the sub_screen does not exist at this point; so we create it here.
        if (!_sub_screen)
            _sub_screen = BitmapHelper::CreateSubBitmap(_old_screen, RectWH(final_scrn_wid / 2 - scrnwid / 2, final_scrn_hit / 2-newScreenHeight/2, scrnwid, newScreenHeight));

        if (newScreenHeight == _sub_screen->GetHeight())
        {
			BitmapHelper::SetScreenBitmap( _sub_screen );
        }
        else if (_sub_screen->GetWidth() != final_scrn_wid)
        {
            int subBitmapWidth = _sub_screen->GetWidth();
            delete _sub_screen;
            _sub_screen = BitmapHelper::CreateSubBitmap(_old_screen, RectWH(_old_screen->GetWidth() / 2 - subBitmapWidth / 2, _old_screen->GetHeight() / 2 - newScreenHeight / 2, subBitmapWidth, newScreenHeight));
            BitmapHelper::SetScreenBitmap( _sub_screen );
        }
        else
        {
            BitmapHelper::SetScreenBitmap( _old_screen );
        }

		scrnhit = BitmapHelper::GetScreenBitmap()->GetHeight();
        vesa_yres = scrnhit;
        game_frame_y_offset = (final_scrn_hit - scrnhit) / 2;

        filter->SetMouseArea(0,0, scrnwid-1, vesa_yres-1);

        if (virtual_screen->GetHeight() != scrnhit) {
            int cdepth=virtual_screen->GetColorDepth();
            delete virtual_screen;
            virtual_screen=BitmapHelper::CreateBitmap(scrnwid,scrnhit,cdepth);
            virtual_screen->Clear();
            gfxDriver->SetMemoryBackBuffer(virtual_screen);
            //      ignore_mouseoff_bitmap = virtual_screen;
        }

        gfxDriver->SetRenderOffset(get_screen_x_adjustment(virtual_screen), get_screen_y_adjustment(virtual_screen));

		if (abscreen==1) //abuf=BitmapHelper::GetScreenBitmap();
            SetVirtualScreen( BitmapHelper::GetScreenBitmap() );
        else if (abscreen==2) //abuf=virtual_screen;
            SetVirtualScreen( virtual_screen );

        update_polled_stuff_if_runtime();
    }
    // update the script viewport height
    scsystem.viewport_height = divide_down_coordinate(scrnhit);

    SetMouseBounds (0,0,0,0);

    our_eip=203;
    in_new_room=1;

    // walkable_areas_temp is used by the pathfinder to generate a
    // copy of the walkable areas - allocate it here to save time later
    delete walkable_areas_temp;
    walkable_areas_temp = BitmapHelper::CreateBitmap(thisroom.walls->GetWidth(), thisroom.walls->GetHeight(), 8);

    // Make a backup copy of the walkable areas prior to
    // any RemoveWalkableArea commands
    delete walkareabackup;
    // copy the walls screen
    walkareabackup=BitmapHelper::CreateBitmapCopy(thisroom.walls);

    our_eip=204;
    update_polled_stuff_if_runtime();
    redo_walkable_areas();
    // fix walk-behinds to current screen resolution
    thisroom.object = fix_bitmap_size(thisroom.object);
    update_polled_stuff_if_runtime();

    set_color_depth(final_col_dep);
    // convert backgrounds to current res
    if (thisroom.resolution != get_fixed_pixel_size(1)) {
        for (cc=0;cc<thisroom.num_bscenes;cc++)
            thisroom.ebscene[cc] = fix_bitmap_size(thisroom.ebscene[cc]);
    }

    if ((thisroom.ebscene[0]->GetWidth() < scrnwid) ||
        (thisroom.ebscene[0]->GetHeight() < scrnhit))
    {
        quitprintf("!The background scene for this room is smaller than the game resolution. If you have recently changed " 
            "the game resolution, you will need to re-import the background for this room. (Room: %d, BG Size: %d x %d)",
            newnum, thisroom.ebscene[0]->GetWidth(), thisroom.ebscene[0]->GetHeight());
    }

    recache_walk_behinds();

    our_eip=205;
    // setup objects
    if (forchar != NULL) {
        // if not restoring a game, always reset this room
        troom.beenhere=0;  
        troom.tsdatasize=0;
        memset(&troom.hotspot_enabled[0],1,MAX_HOTSPOTS);
        memset(&troom.region_enabled[0], 1, MAX_REGIONS);
    }
    if ((newnum>=0) & (newnum<MAX_ROOMS))
        croom = getRoomStatus(newnum);
    else croom=&troom;

    if (croom->beenhere > 0) {
        // if we've been here before, save the Times Run information
        // since we will overwrite the actual NewInteraction structs
        // (cos they have pointers and this might have been loaded from
        // a save game)
        if (thisroom.roomScripts == NULL)
        {
            thisroom.intrRoom->copy_timesrun_from (&croom->intrRoom);
            for (cc=0;cc < MAX_HOTSPOTS;cc++)
                thisroom.intrHotspot[cc]->copy_timesrun_from (&croom->intrHotspot[cc]);
            for (cc=0;cc < MAX_INIT_SPR;cc++)
                thisroom.intrObject[cc]->copy_timesrun_from (&croom->intrObject[cc]);
            for (cc=0;cc < MAX_REGIONS;cc++)
                thisroom.intrRegion[cc]->copy_timesrun_from (&croom->intrRegion[cc]);
        }
    }
    if (croom->beenhere==0) {
        croom->numobj=thisroom.numsprs;
        croom->tsdatasize=0;
        for (cc=0;cc<croom->numobj;cc++) {
            croom->obj[cc].x=thisroom.sprs[cc].x;
            croom->obj[cc].y=thisroom.sprs[cc].y;

            if (thisroom.wasversion <= kRoomVersion_300a)
                croom->obj[cc].y += divide_down_coordinate(spriteheight[thisroom.sprs[cc].sprnum]);

            croom->obj[cc].num=thisroom.sprs[cc].sprnum;
            croom->obj[cc].on=thisroom.sprs[cc].on;
            croom->obj[cc].view=-1;
            croom->obj[cc].loop=0;
            croom->obj[cc].frame=0;
            croom->obj[cc].wait=0;
            croom->obj[cc].transparent=0;
            croom->obj[cc].moving=-1;
            croom->obj[cc].flags = thisroom.objectFlags[cc];
            croom->obj[cc].baseline=-1;
            croom->obj[cc].last_zoom = 100;
            croom->obj[cc].last_width = 0;
            croom->obj[cc].last_height = 0;
            croom->obj[cc].blocking_width = 0;
            croom->obj[cc].blocking_height = 0;
            if (thisroom.objbaseline[cc]>=0)
                //        croom->obj[cc].baseoffs=thisroom.objbaseline[cc]-thisroom.sprs[cc].y;
                croom->obj[cc].baseline=thisroom.objbaseline[cc];
        }
        memcpy(&croom->walkbehind_base[0],&thisroom.objyval[0],sizeof(short)*MAX_OBJ);
        for (cc=0;cc<MAX_FLAGS;cc++) croom->flagstates[cc]=0;

        /*    // we copy these structs for the Score column to work
        croom->misccond=thisroom.misccond;
        for (cc=0;cc<MAX_HOTSPOTS;cc++)
        croom->hscond[cc]=thisroom.hscond[cc];
        for (cc=0;cc<MAX_INIT_SPR;cc++)
        croom->objcond[cc]=thisroom.objcond[cc];*/

        for (cc=0;cc < MAX_HOTSPOTS;cc++) {
            croom->hotspot_enabled[cc] = 1;
        }
        for (cc = 0; cc < MAX_REGIONS; cc++) {
            croom->region_enabled[cc] = 1;
        }
        croom->beenhere=1;
        in_new_room=2;
    }
    else {
        // We have been here before
        for (int ff = 0; ff < thisroom.numLocalVars; ff++)
            thisroom.localvars[ff].value = croom->interactionVariableValues[ff];
    }

    update_polled_stuff_if_runtime();

    if (thisroom.roomScripts == NULL)
    {
        // copy interactions from room file into our temporary struct
        croom->intrRoom = thisroom.intrRoom[0];
        for (cc=0;cc<MAX_HOTSPOTS;cc++)
            croom->intrHotspot[cc] = thisroom.intrHotspot[cc][0];
        for (cc=0;cc<MAX_INIT_SPR;cc++)
            croom->intrObject[cc] = thisroom.intrObject[cc][0];
        for (cc=0;cc<MAX_REGIONS;cc++)
            croom->intrRegion[cc] = thisroom.intrRegion[cc][0];
    }

    objs=&croom->obj[0];

    for (cc = 0; cc < MAX_INIT_SPR; cc++) {
        // 64 bit: Using the id instead
        // scrObj[cc].obj = &croom->obj[cc];
        objectScriptObjNames[cc][0] = 0;
    }

    for (cc = 0; cc < croom->numobj; cc++) {
        // export the object's script object
        if (thisroom.objectscriptnames[cc][0] == 0)
            continue;

        if (thisroom.wasversion >= kRoomVersion_300a) 
        {
            strcpy(objectScriptObjNames[cc], thisroom.objectscriptnames[cc]);
        }
        else
        {
            sprintf(objectScriptObjNames[cc], "o%s", thisroom.objectscriptnames[cc]);
            strlwr(objectScriptObjNames[cc]);
            if (objectScriptObjNames[cc][1] != 0)
                objectScriptObjNames[cc][1] = toupper(objectScriptObjNames[cc][1]);
        }

        ccAddExternalDynamicObject(objectScriptObjNames[cc], &scrObj[cc], &ccDynamicObject);
    }

    for (cc = 0; cc < MAX_HOTSPOTS; cc++) {
        if (thisroom.hotspotScriptNames[cc][0] == 0)
            continue;

        ccAddExternalDynamicObject(thisroom.hotspotScriptNames[cc], &scrHotspot[cc], &ccDynamicHotspot);
    }

    our_eip=206;
    /*  THIS IS DONE IN THE EDITOR NOW
    thisroom.ebpalShared[0] = 1;
    for (dd = 1; dd < thisroom.num_bscenes; dd++) {
    if (memcmp (&thisroom.bpalettes[dd][0], &palette[0], sizeof(color) * 256) == 0)
    thisroom.ebpalShared[dd] = 1;
    else
    thisroom.ebpalShared[dd] = 0;
    }
    // only make the first frame shared if the last is
    if (thisroom.ebpalShared[thisroom.num_bscenes - 1] == 0)
    thisroom.ebpalShared[0] = 0;*/

    update_polled_stuff_if_runtime();

    our_eip = 210;
    if (IS_ANTIALIAS_SPRITES) {
        // sometimes the palette has corrupt entries, which crash
        // the create_rgb_table call
        // so, fix them
        for (int ff = 0; ff < 256; ff++) {
            if (palette[ff].r > 63)
                palette[ff].r = 63;
            if (palette[ff].g > 63)
                palette[ff].g = 63;
            if (palette[ff].b > 63)
                palette[ff].b = 63;
        }
        create_rgb_table (&rgb_table, palette, NULL);
        rgb_map = &rgb_table;
    }
    our_eip = 211;
    if (forchar!=NULL) {
        // if it's not a Restore Game

        // if a following character is still waiting to come into the
        // previous room, force it out so that the timer resets
        for (int ff = 0; ff < game.numcharacters; ff++) {
            if ((game.chars[ff].following >= 0) && (game.chars[ff].room < 0)) {
                if ((game.chars[ff].following == game.playercharacter) &&
                    (forchar->prevroom == newnum))
                    // the player went back to the previous room, so make sure
                    // the following character is still there
                    game.chars[ff].room = newnum;
                else
                    game.chars[ff].room = game.chars[game.chars[ff].following].room;
            }
        }

        offsetx=0;
        offsety=0;
        forchar->prevroom=forchar->room;
        forchar->room=newnum;
        // only stop moving if it's a new room, not a restore game
        for (cc=0;cc<game.numcharacters;cc++)
            StopMoving(cc);

    }

    update_polled_stuff_if_runtime();

    roominst=NULL;
    if (debug_flags & DBG_NOSCRIPT) ;
    else if (thisroom.compiled_script!=NULL) {
        compile_room_script();
        if (croom->tsdatasize>0) {
            if (croom->tsdatasize != roominst->globaldatasize)
                quit("room script data segment size has changed");
            memcpy(&roominst->globaldata[0],croom->tsdata,croom->tsdatasize);
        }
    }
    our_eip=207;
    play.entered_edge = -1;

    if ((new_room_x != SCR_NO_VALUE) && (forchar != NULL))
    {
        forchar->x = new_room_x;
        forchar->y = new_room_y;
    }
    new_room_x = SCR_NO_VALUE;

    if ((new_room_pos>0) & (forchar!=NULL)) {
        if (new_room_pos>=4000) {
            play.entered_edge = 3;
            forchar->y = thisroom.top + get_fixed_pixel_size(1);
            forchar->x=new_room_pos%1000;
            if (forchar->x==0) forchar->x=thisroom.width/2;
            if (forchar->x <= thisroom.left)
                forchar->x = thisroom.left + 3;
            if (forchar->x >= thisroom.right)
                forchar->x = thisroom.right - 3;
            forchar->loop=0;
        }
        else if (new_room_pos>=3000) {
            play.entered_edge = 2;
            forchar->y = thisroom.bottom - get_fixed_pixel_size(1);
            forchar->x=new_room_pos%1000;
            if (forchar->x==0) forchar->x=thisroom.width/2;
            if (forchar->x <= thisroom.left)
                forchar->x = thisroom.left + 3;
            if (forchar->x >= thisroom.right)
                forchar->x = thisroom.right - 3;
            forchar->loop=3;
        }
        else if (new_room_pos>=2000) {
            play.entered_edge = 1;
            forchar->x = thisroom.right - get_fixed_pixel_size(1);
            forchar->y=new_room_pos%1000;
            if (forchar->y==0) forchar->y=thisroom.height/2;
            if (forchar->y <= thisroom.top)
                forchar->y = thisroom.top + 3;
            if (forchar->y >= thisroom.bottom)
                forchar->y = thisroom.bottom - 3;
            forchar->loop=1;
        }
        else if (new_room_pos>=1000) {
            play.entered_edge = 0;
            forchar->x = thisroom.left + get_fixed_pixel_size(1);
            forchar->y=new_room_pos%1000;
            if (forchar->y==0) forchar->y=thisroom.height/2;
            if (forchar->y <= thisroom.top)
                forchar->y = thisroom.top + 3;
            if (forchar->y >= thisroom.bottom)
                forchar->y = thisroom.bottom - 3;
            forchar->loop=2;
        }
        // if starts on un-walkable area
        if (get_walkable_area_pixel(forchar->x, forchar->y) == 0) {
            if (new_room_pos>=3000) { // bottom or top of screen
                int tryleft=forchar->x - 1,tryright=forchar->x + 1;
                while (1) {
                    if (get_walkable_area_pixel(tryleft, forchar->y) > 0) {
                        forchar->x=tryleft; break; }
                    if (get_walkable_area_pixel(tryright, forchar->y) > 0) {
                        forchar->x=tryright; break; }
                    int nowhere=0;
                    if (tryleft>thisroom.left) { tryleft--; nowhere++; }
                    if (tryright<thisroom.right) { tryright++; nowhere++; }
                    if (nowhere==0) break;  // no place to go, so leave him
                }
            }
            else if (new_room_pos>=1000) { // left or right
                int tryleft=forchar->y - 1,tryright=forchar->y + 1;
                while (1) {
                    if (get_walkable_area_pixel(forchar->x, tryleft) > 0) {
                        forchar->y=tryleft; break; }
                    if (get_walkable_area_pixel(forchar->x, tryright) > 0) {
                        forchar->y=tryright; break; }
                    int nowhere=0;
                    if (tryleft>thisroom.top) { tryleft--; nowhere++; }
                    if (tryright<thisroom.bottom) { tryright++; nowhere++; }
                    if (nowhere==0) break;  // no place to go, so leave him
                }
            }
        }
        new_room_pos=0;
    }
    if (forchar!=NULL) {
        play.entered_at_x=forchar->x;
        play.entered_at_y=forchar->y;
        if (forchar->x >= thisroom.right)
            play.entered_edge = 1;
        else if (forchar->x <= thisroom.left)
            play.entered_edge = 0;
        else if (forchar->y >= thisroom.bottom)
            play.entered_edge = 2;
        else if (forchar->y <= thisroom.top)
            play.entered_edge = 3;
    }
    /*  if ((playerchar->x > thisroom.width) | (playerchar->y > thisroom.height))
    quit("!NewRoomEx: x/y co-ordinates are invalid");*/
    if (thisroom.options[ST_TUNE]>0)
        PlayMusicResetQueue(thisroom.options[ST_TUNE]);

    our_eip=208;
    if (forchar!=NULL) {
        if (thisroom.options[ST_MANDISABLED]==0) { forchar->on=1;
        enable_cursor_mode(0); }
        else {
            forchar->on=0;
            disable_cursor_mode(0);
            // remember which character we turned off, in case they
            // use SetPlyaerChracter within this room (so we re-enable
            // the correct character when leaving the room)
            play.temporarily_turned_off_character = game.playercharacter;
        }
        if (forchar->flags & CHF_FIXVIEW) ;
        else if (thisroom.options[ST_MANVIEW]==0) forchar->view=forchar->defview;
        else forchar->view=thisroom.options[ST_MANVIEW]-1;
        forchar->frame=0;   // make him standing
    }
    color_map = NULL;

    our_eip = 209;
    update_polled_stuff_if_runtime();
    generate_light_table();
    update_music_volume();
    update_viewport();
    our_eip = 212;
    invalidate_screen();
    for (cc=0;cc<croom->numobj;cc++) {
        if (objs[cc].on == 2)
            MergeObject(cc);
    }
    new_room_flags=0;
    play.gscript_timer=-1;  // avoid screw-ups with changing screens
    play.player_on_region = 0;
    // trash any input which they might have done while it was loading
    while (kbhit()) { if (getch()==0) getch(); }
    while (mgetbutton()!=NONE) ;
    // no fade in, so set the palette immediately in case of 256-col sprites
    if (game.color_depth > 1)
        setpal();

    our_eip=220;
    update_polled_stuff_if_runtime();
    DEBUG_CONSOLE("Now in room %d", displayed_room);
    guis_need_update = 1;
    platform->RunPluginHooks(AGSE_ENTERROOM, displayed_room);
    //  MoveToWalkableArea(game.playercharacter);
    //  MSS_CHECK_ALL_BLOCKS;
}