Пример #1
0
void PreReadSaveFileInfo(Stream *in, GameDataVersion data_ver)
{
    AlignedStream align_s(in, Common::kAligned_Read);
    game.ReadFromFile(&align_s);
    // Discard game messages we do not need here
    delete [] game.load_messages;
    game.load_messages = NULL;
    game.read_savegame_info(in, data_ver);
}
Пример #2
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);
}
Пример #3
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]);
        }
    }
}
Пример #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;
        }
    }

}
Пример #5
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;
        }
    }

}
Пример #6
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();
}
Пример #7
0
void move_object(int objj,int tox,int toy,int spee,int ignwal) {

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

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

    int objX = objs[objj].x;
    int objY = objs[objj].y;

    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(game.GetColorDepth());
    if (mslot>0) {
        objs[objj].moving = mslot;
        mls[mslot].direct = ignwal;
    }
}
Пример #8
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);
}
Пример #9
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);
}
Пример #10
0
int load_game_file() {

	int res;    

    game_paused = 0;  // reset the game paused flag
    ifacepopped = -1;

	//-----------------------------------------------------------
	// Start reading from file
	//-----------------------------------------------------------

    Stream *in = game_file_open();
	if (in==NULL)
		return -1;

    our_eip=-18;

    setup_script_exports();

    our_eip=-16;

	res = game_file_read_version(in);
	if (res != RETURN_CONTINUE) {
		return res;
	}

    game.charScripts = NULL;
    game.invScripts = NULL;
    memset(&game.spriteflags[0], 0, MAX_SPRITES);

    ReadGameSetupStructBase_Aligned(in);

    // The earlier versions of AGS provided support for "upscaling" low-res
    // games (320x200 and 320x240) to hi-res (640x400 and 640x480
    // respectively). The script API has means for detecting if the game is
    // running upscaled, and game developer could use this opportunity to setup
    // game accordingly (e.g. assign hi-res fonts, etc).
    // This feature is officially deprecated since 3.1.0, however the engine
    // itself still supports it, technically.
    // This overriding option re-enables "upscaling". It works ONLY for low-res
    // resolutions, such as 320x200 and 320x240.
    if (usetup.override_upscale)
    {
        if (game.default_resolution == 1)
            game.default_resolution = 3;
        else if (game.default_resolution == 2)
            game.default_resolution = 4;
    }

    if (filever < kGameVersion_312)
    {
        // Fix animation speed for old formats
		game.options[OPT_GLOBALTALKANIMSPD] = 5;
    }
    else if (filever < kGameVersion_330)
    {
        // Convert game option for 3.1.2 - 3.2 games
        game.options[OPT_GLOBALTALKANIMSPD] = game.options[OPT_GLOBALTALKANIMSPD] != 0 ? 5 : (-5 - 1);
    }

    if (game.numfonts > MAX_FONTS)
        quit("!This game requires a newer version of AGS. Too many fonts for this version to handle.");

    GameSetupStruct::GAME_STRUCT_READ_DATA read_data;
    read_data.filever        = filever;
    read_data.saveGameSuffix = saveGameSuffix;
    read_data.max_audio_types= MAX_AUDIO_TYPES;
    read_data.game_file_name = game_file_name;

    //-----------------------------------------------------
    game.ReadFromFile_Part1(in, read_data);
    //-----------------------------------------------------

    if (!game.load_compiled_script)
        quit("No global script in game; data load error");

    gamescript = ccScript::CreateFromStream(in);
    if (gamescript == NULL)
        quit("Global script load failed; need newer version?");

    game_file_read_dialog_script(in);

	game_file_read_script_modules(in);

    our_eip=-15;

    charextra = (CharacterExtras*)calloc(game.numcharacters, sizeof(CharacterExtras));
    mls = (MoveList*)calloc(game.numcharacters + MAX_INIT_SPR + 1, sizeof(MoveList));
    actSpsCount = game.numcharacters + MAX_INIT_SPR + 2;
    actsps = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *));
    actspsbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*));
    actspswb = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *));
    actspswbbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*));
    actspswbcache = (CachedActSpsData*)calloc(actSpsCount, sizeof(CachedActSpsData));
    game.charProps = (CustomProperties*)calloc(game.numcharacters, sizeof(CustomProperties));

    allocate_memory_for_views(game.numviews);
    int iteratorCount = 0;

	game_file_read_views(in);

    our_eip=-14;

    if (filever <= kGameVersion_251) // <= 2.1 skip unknown data
    {
        int count = in->ReadInt32();
        in->Seek(Common::kSeekCurrent, count * 0x204);
    }

    charcache = (CharacterCache*)calloc(1,sizeof(CharacterCache)*game.numcharacters+5);
    //-----------------------------------------------------
    game.ReadFromFile_Part2(in, read_data);
    //-----------------------------------------------------

    game_file_set_default_glmsg();
    
    our_eip=-13;

	game_file_read_dialogs(in);

	game_file_read_gui(in);

    if (filever >= kGameVersion_260) // >= 2.60
    {
        platform->ReadPluginsFromDisk(in);
    }

    //-----------------------------------------------------
    game.ReadFromFile_Part3(in, read_data);
    //-----------------------------------------------------

    game_file_set_score_sound(read_data);

	delete in;

	//-----------------------------------------------------------
	// Reading from file is finished here
	//-----------------------------------------------------------

    update_gui_zorder();

    if (game.numfonts == 0)
        return -2;  // old v2.00 version

    our_eip=-11;

	init_and_register_game_objects();    

    our_eip = -23;

    platform->StartPlugins();

    our_eip = -24;

    ccSetScriptAliveTimer(150000);
    ccSetStringClassImpl(&myScriptStringImpl);

    if (create_global_script())
        return -3;

    return 0;
}
Пример #11
0
int load_game_file() {

	int res;    

    game_paused = 0;  // reset the game paused flag
    ifacepopped = -1;

	//-----------------------------------------------------------
	// Start reading from file
	//-----------------------------------------------------------

    Stream *in = game_file_open();
	if (in==NULL)
		return -1;

    our_eip=-18;

    setup_script_exports();

    our_eip=-16;

	res = game_file_read_version(in);
	if (res != RETURN_CONTINUE) {
		return res;
	}

    game.charScripts = NULL;
    game.invScripts = NULL;
    memset(&game.spriteflags[0], 0, MAX_SPRITES);

    ReadGameSetupStructBase_Aligned(in);

    if (filever <= kGameVersion_300)
    {
        // Fix animation speed for old formats
        game.options[OPT_OLDTALKANIMSPD] = 1;
    }
    // 3.20: Fixed GUI AdditiveOpacity mode not working properly if you tried to have a non-alpha sprite on an alpha GUI
    if (loaded_game_file_version < kGameVersion_320)
    {
        // Force new style rendering for gui sprites with alpha channel
        game.options[OPT_NEWGUIALPHA] = 1;
    }
    init_blenders((GameGuiAlphaRenderingStyle)game.options[OPT_NEWGUIALPHA]);

    if (game.numfonts > MAX_FONTS)
        quit("!This game requires a newer version of AGS. Too many fonts for this version to handle.");

    GameSetupStruct::GAME_STRUCT_READ_DATA read_data;
    read_data.filever        = filever;
    read_data.saveGameSuffix = saveGameSuffix;
    read_data.max_audio_types= MAX_AUDIO_TYPES;
    read_data.game_file_name = game_file_name;

    //-----------------------------------------------------
    game.ReadFromFile_Part1(in, read_data);
    //-----------------------------------------------------

    if (game.compiled_script == NULL)
        quit("No global script in game; data load error");

    gamescript = ccScript::CreateFromStream(in);
    if (gamescript == NULL)
        quit("Global script load failed; need newer version?");

    game_file_read_dialog_script(in);

	game_file_read_script_modules(in);

    our_eip=-15;

    charextra = (CharacterExtras*)calloc(game.numcharacters, sizeof(CharacterExtras));
    mls = (MoveList*)calloc(game.numcharacters + MAX_INIT_SPR + 1, sizeof(MoveList));
    actSpsCount = game.numcharacters + MAX_INIT_SPR + 2;
    actsps = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *));
    actspsbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*));
    actspswb = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *));
    actspswbbmp = (IDriverDependantBitmap**)calloc(actSpsCount, sizeof(IDriverDependantBitmap*));
    actspswbcache = (CachedActSpsData*)calloc(actSpsCount, sizeof(CachedActSpsData));
    game.charProps = (CustomProperties*)calloc(game.numcharacters, sizeof(CustomProperties));

    allocate_memory_for_views(game.numviews);
    int iteratorCount = 0;

	game_file_read_views(in);

    our_eip=-14;

    if (filever <= kGameVersion_251) // <= 2.1 skip unknown data
    {
        int count = in->ReadInt32();
        in->Seek(Common::kSeekCurrent, count * 0x204);
    }

    charcache = (CharacterCache*)calloc(1,sizeof(CharacterCache)*game.numcharacters+5);
    //-----------------------------------------------------
    game.ReadFromFile_Part2(in, read_data);
    //-----------------------------------------------------

    game_file_set_default_glmsg();
    
    our_eip=-13;

	game_file_read_dialogs(in);

	game_file_read_gui(in);

    if (filever >= kGameVersion_260) // >= 2.60
    {
        platform->ReadPluginsFromDisk(in);
    }

    //-----------------------------------------------------
    game.ReadFromFile_Part3(in, read_data);
    //-----------------------------------------------------

    game_file_set_score_sound(read_data);

	delete in;

	//-----------------------------------------------------------
	// Reading from file is finished here
	//-----------------------------------------------------------

    update_gui_zorder();

    if (game.numfonts == 0)
        return -2;  // old v2.00 version

    our_eip=-11;

	init_and_register_game_objects();    

    our_eip = -23;

    platform->StartPlugins();

    our_eip = -24;

    ccSetScriptAliveTimer(150000);
    ccSetStringClassImpl(&myScriptStringImpl);

    if (create_global_script())
        return -3;

    return 0;
}
Пример #12
0
// Pass yy = -1 to find Y co-ord automatically
// allowShrink = 0 for none, 1 for leftwards, 2 for rightwards
// pass blocking=2 to create permanent overlay
int _display_main(int xx,int yy,int wii,const char*text,int blocking,int usingfont,int asspch, int isThought, int allowShrink, bool overlayPositionFixed) 
{
    const bool use_speech_textwindow = (asspch < 0) && (game.options[OPT_SPEECHTYPE] >= 2);
    const bool use_thought_gui = (isThought) && (game.options[OPT_THOUGHTGUI] > 0);

    bool alphaChannel = false;
    char todis[STD_BUFFER_SIZE];
    snprintf(todis, STD_BUFFER_SIZE - 1, "%s", text);
    int usingGui = -1;
    if (use_speech_textwindow)
	    usingGui = play.speech_textwindow_gui;
    else if (use_thought_gui)
	    usingGui = game.options[OPT_THOUGHTGUI];

    int padding = get_textwindow_padding(usingGui);
    int paddingScaled = padding;
    int paddingDoubledScaled = padding * 2; // Just in case screen size does is not neatly divisible by 320x200

    ensure_text_valid_for_font(todis, usingfont);
    break_up_text_into_lines(wii-2*padding,usingfont,todis);
    disp.lineheight = getfontheight_outlined(usingfont);
    disp.linespacing= getfontspacing_outlined(usingfont);
    disp.fulltxtheight = getheightoflines(usingfont, numlines);

    // if it's a normal message box and the game was being skipped,
    // ensure that the screen is up to date before the message box
    // is drawn on top of it
    if ((play.skip_until_char_stops >= 0) && (blocking == 1))
        render_graphics();

    EndSkippingUntilCharStops();

    if (topBar.wantIt) {
        // ensure that the window is wide enough to display
        // any top bar text
        int topBarWid = wgettextwidth_compensate(topBar.text, topBar.font);
        topBarWid += (play.top_bar_borderwidth + 2) * 2;
        if (longestline < topBarWid)
            longestline = topBarWid;
        // the top bar should behave like DisplaySpeech wrt blocking
        blocking = 0;
    }

    if (asspch > 0) {
        // update the all_buttons_disabled variable in advance
        // of the adjust_x/y_for_guis calls
        play.disabled_user_interface++;
        update_gui_disabled_status();
        play.disabled_user_interface--;
    }

    const Rect &ui_view = play.GetUIViewport();
    if (xx == OVR_AUTOPLACE) ;
    // centre text in middle of screen
    else if (yy<0) yy= ui_view.GetHeight()/2-disp.fulltxtheight/2-padding;
    // speech, so it wants to be above the character's head
    else if (asspch > 0) {
        yy-=disp.fulltxtheight;
        if (yy < 5) yy=5;
        yy = adjust_y_for_guis (yy);
    }

    if (longestline < wii - paddingDoubledScaled) {
        // shrink the width of the dialog box to fit the text
        int oldWid = wii;
        //if ((asspch >= 0) || (allowShrink > 0))
        // If it's not speech, or a shrink is allowed, then shrink it
        if ((asspch == 0) || (allowShrink > 0))
            wii = longestline + paddingDoubledScaled;

        // shift the dialog box right to align it, if necessary
        if ((allowShrink == 2) && (xx >= 0))
            xx += (oldWid - wii);
    }

    if (xx<-1) { 
        xx=(-xx)-wii/2;
        if (xx < 0)
            xx = 0;

        xx = adjust_x_for_guis (xx, yy);

        if (xx + wii >= ui_view.GetWidth())
            xx = (ui_view.GetWidth() - wii) - 5;
    }
    else if (xx<0) xx= ui_view.GetWidth()/2-wii/2;

    int ee, extraHeight = paddingDoubledScaled;
    color_t text_color = MakeColor(15);
    if (blocking < 2)
        remove_screen_overlay(OVER_TEXTMSG);

    Bitmap *text_window_ds = BitmapHelper::CreateTransparentBitmap((wii > 0) ? wii : 2, disp.fulltxtheight + extraHeight, game.GetColorDepth());

    // inform draw_text_window to free the old bitmap
    const bool wantFreeScreenop = true;

    if ((strlen (todis) < 1) || (strcmp (todis, "  ") == 0) || (wii == 0)) ;
    // if it's an empty speech line, don't draw anything
    else if (asspch) { //text_color = ds->GetCompatibleColor(12);
        int ttxleft = 0, ttxtop = paddingScaled, oriwid = wii - padding * 2;
        int drawBackground = 0;

        if (use_speech_textwindow) {
            drawBackground = 1;
        }
        else if (use_thought_gui) {
            // make it treat it as drawing inside a window now
            if (asspch > 0)
                asspch = -asspch;
            drawBackground = 1;
        }

        if (drawBackground)
        {
            draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &ttxleft, &ttxtop, &xx, &yy, &wii, &text_color, 0, usingGui);
            if (usingGui > 0)
            {
                alphaChannel = guis[usingGui].HasAlphaChannel();
            }
        }
        else if ((ShouldAntiAliasText()) && (game.GetColorDepth() >= 24))
            alphaChannel = true;

        for (ee=0;ee<numlines;ee++) {
            //int ttxp=wii/2 - wgettextwidth_compensate(lines[ee], usingfont)/2;
            int ttyp=ttxtop+ee*disp.linespacing;
            // asspch < 0 means that it's inside a text box so don't
            // centre the text
            if (asspch < 0) {
                if ((usingGui >= 0) && 
                    ((game.options[OPT_SPEECHTYPE] >= 2) || (isThought)))
                    text_color = text_window_ds->GetCompatibleColor(guis[usingGui].FgColor);
                else
                    text_color = text_window_ds->GetCompatibleColor(-asspch);

                wouttext_aligned(text_window_ds, ttxleft, ttyp, oriwid, usingfont, text_color, lines[ee], play.text_align);
            }
            else {
                text_color = text_window_ds->GetCompatibleColor(asspch);
                //wouttext_outline(ttxp,ttyp,usingfont,lines[ee]);
                wouttext_aligned(text_window_ds, ttxleft, ttyp, wii, usingfont, text_color, lines[ee], play.speech_text_align);
            }
        }
    }
    else {
		
        int xoffs,yoffs, oriwid = wii - padding * 2;
        draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &xoffs,&yoffs,&xx,&yy,&wii,&text_color);

        if (game.options[OPT_TWCUSTOM] > 0)
        {
            alphaChannel = guis[game.options[OPT_TWCUSTOM]].HasAlphaChannel();
        }

        adjust_y_coordinate_for_text(&yoffs, usingfont);

        for (ee=0;ee<numlines;ee++)
            wouttext_aligned (text_window_ds, xoffs, yoffs + ee * disp.linespacing, oriwid, usingfont, text_color, lines[ee], play.text_align);
    }

    int ovrtype = OVER_TEXTMSG;
    if (blocking == 2) ovrtype=OVER_CUSTOM;
    else if (blocking >= OVER_CUSTOM) ovrtype=blocking;

    int nse = add_screen_overlay(xx, yy, ovrtype, text_window_ds, alphaChannel);
    // we should not delete text_window_ds here, because it is now owned by Overlay

    if (blocking>=2) {
        return screenover[nse].type;
    }

    if (blocking) {
        if (play.fast_forward) {
            remove_screen_overlay(OVER_TEXTMSG);
            play.messagetime=-1;
            return 0;
        }

        /*    wputblock(xx,yy,screenop,1);
        remove_screen_overlay(OVER_TEXTMSG);*/

        if (!play.mouse_cursor_hidden)
            ags_domouse(DOMOUSE_ENABLE);
        // play.skip_display has same values as SetSkipSpeech:
        // 0 = click mouse or key to skip
        // 1 = key only
        // 2 = can't skip at all
        // 3 = only on keypress, no auto timer
        // 4 = mouse only
        int countdown = GetTextDisplayTime (todis);
        int skip_setting = user_to_internal_skip_speech((SkipSpeechStyle)play.skip_display);
        while (1) {
            /*      if (!play.mouse_cursor_hidden)
            ags_domouse(DOMOUSE_UPDATE);
            write_screen();*/

            update_audio_system_on_game_loop();
            render_graphics();

            if (ags_mgetbutton()>NONE) {
                // If we're allowed, skip with mouse
                if (skip_setting & SKIP_MOUSECLICK)
                    break;
            }
            int kp;
            if (run_service_key_controls(kp)) {
                // let them press ESC to skip the cutscene
                check_skip_cutscene_keypress (kp);
                if (play.fast_forward)
                    break;

                if (skip_setting & SKIP_KEYPRESS)
                    break;
            }
            PollUntilNextFrame();
            countdown--;

            if (play.speech_has_voice) {
                // extend life of text if the voice hasn't finished yet
                if (channel_is_playing(SCHAN_SPEECH) && (play.fast_forward == 0)) {
                    if (countdown <= 1)
                        countdown = 1;
                }
                else  // if the voice has finished, remove the speech
                    countdown = 0;
            }

            if ((countdown < 1) && (skip_setting & SKIP_AUTOTIMER))
            {
                play.ignore_user_input_until_time = AGS_Clock::now() + std::chrono::milliseconds(play.ignore_user_input_after_text_timeout_ms);
                break;
            }
            // if skipping cutscene, don't get stuck on No Auto Remove
            // text boxes
            if ((countdown < 1) && (play.fast_forward))
                break;
        }
        if (!play.mouse_cursor_hidden)
            ags_domouse(DOMOUSE_DISABLE);
        remove_screen_overlay(OVER_TEXTMSG);

        construct_virtual_screen(true);
    }
    else {
        // if the speech does not time out, but we are skipping a cutscene,
        // allow it to time out
        if ((play.messagetime < 0) && (play.fast_forward))
            play.messagetime = 2;

        if (!overlayPositionFixed)
        {
            screenover[nse].positionRelativeToScreen = false;
            VpPoint vpt = play.ScreenToRoom(screenover[nse].x, screenover[nse].y, false);
            screenover[nse].x = vpt.first.X;
            screenover[nse].y = vpt.first.Y;
        }

        GameLoopUntilEvent(UNTIL_NOOVERLAY,0);
    }

    play.messagetime=-1;
    return 0;
}
Пример #13
0
void draw_text_window_and_bar(Bitmap **text_window_ds, bool should_free_ds,
                              int*xins,int*yins,int*xx,int*yy,int*wii,color_t *set_text_color,int ovrheight, int ifnum) {

    draw_text_window(text_window_ds, should_free_ds, xins, yins, xx, yy, wii, set_text_color, ovrheight, ifnum);

    if ((topBar.wantIt) && (text_window_ds && *text_window_ds)) {
        // top bar on the dialog window with character's name
        // create an enlarged window, then free the old one
        Bitmap *ds = *text_window_ds;
        Bitmap *newScreenop = BitmapHelper::CreateBitmap(ds->GetWidth(), ds->GetHeight() + topBar.height, game.GetColorDepth());
        newScreenop->Blit(ds, 0, 0, 0, topBar.height, ds->GetWidth(), ds->GetHeight());
        delete *text_window_ds;
        *text_window_ds = newScreenop;
        ds = *text_window_ds;

        // draw the top bar
        color_t draw_color = ds->GetCompatibleColor(play.top_bar_backcolor);
        ds->FillRect(Rect(0, 0, ds->GetWidth() - 1, topBar.height - 1), draw_color);
        if (play.top_bar_backcolor != play.top_bar_bordercolor) {
            // draw the border
            draw_color = ds->GetCompatibleColor(play.top_bar_bordercolor);
            for (int j = 0; j < play.top_bar_borderwidth; j++)
                ds->DrawRect(Rect(j, j, ds->GetWidth() - (j + 1), topBar.height - (j + 1)), draw_color);
        }

        // draw the text
        int textx = (ds->GetWidth() / 2) - wgettextwidth_compensate(topBar.text, topBar.font) / 2;
        color_t text_color = ds->GetCompatibleColor(play.top_bar_textcolor);
        wouttext_outline(ds, textx, play.top_bar_borderwidth + 1, topBar.font, text_color, topBar.text);

        // don't draw it next time
        topBar.wantIt = 0;
        // adjust the text Y position
        yins[0] += topBar.height;
    }
    else if (topBar.wantIt)
        topBar.wantIt = 0;
}
Пример #14
0
int System_GetScreenHeight() {
    return game.GetGameRes().Height;
}
Пример #15
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;
}
Пример #16
0
void draw_text_window(Bitmap **text_window_ds, bool should_free_ds,
                      int*xins,int*yins,int*xx,int*yy,int*wii, color_t *set_text_color, int ovrheight, int ifnum) {

    Bitmap *ds = *text_window_ds;
    if (ifnum < 0)
        ifnum = game.options[OPT_TWCUSTOM];

    if (ifnum <= 0) {
        if (ovrheight)
            quit("!Cannot use QFG4 style options without custom text window");
        draw_button_background(ds, 0,0,ds->GetWidth() - 1,ds->GetHeight() - 1,nullptr);
        if (set_text_color)
            *set_text_color = ds->GetCompatibleColor(16);
        xins[0]=3;
        yins[0]=3;
    }
    else {
        if (ifnum >= game.numgui)
            quitprintf("!Invalid GUI %d specified as text window (total GUIs: %d)", ifnum, game.numgui);
        if (!guis[ifnum].IsTextWindow())
            quit("!GUI set as text window but is not actually a text window GUI");

        int tbnum = get_but_pic(&guis[ifnum], 0);

        wii[0] += get_textwindow_border_width (ifnum);
        xx[0]-=game.SpriteInfos[tbnum].Width;
        yy[0]-=game.SpriteInfos[tbnum].Height;
        if (ovrheight == 0)
            ovrheight = disp.fulltxtheight;

        if (should_free_ds)
            delete *text_window_ds;
        int padding = get_textwindow_padding(ifnum);
        *text_window_ds = BitmapHelper::CreateTransparentBitmap(wii[0],ovrheight+(padding*2)+ game.SpriteInfos[tbnum].Height*2,game.GetColorDepth());
        ds = *text_window_ds;
        int xoffs=game.SpriteInfos[tbnum].Width,yoffs= game.SpriteInfos[tbnum].Height;
        draw_button_background(ds, xoffs,yoffs,(ds->GetWidth() - xoffs) - 1,(ds->GetHeight() - yoffs) - 1,&guis[ifnum]);
        if (set_text_color)
            *set_text_color = ds->GetCompatibleColor(guis[ifnum].FgColor);
        xins[0]=xoffs+padding;
        yins[0]=yoffs+padding;
    }
}
Пример #17
0
// [IKM] 2014-09-21
// IMPORTANT NOTE on System.ScreenWidth and System.ScreenHeight:
// It appears that in AGS these properties were not defining actual window size
// in pixels, but rather game frame size, which could include black borders,
// in 'native' (unscaled) pixels. This was due the specifics of how graphics
// modes were implemented in previous versions.
// 
// Quote from the old manual:
// "Returns the actual screen width that the game is running at. If a graphic
//  filter is in use, the resolution returned will be that before any
//  stretching by the filter has been applied. If widescreen side borders are
//  enabled, the screen width reported will include the size of these borders."
//
// The key words are "the resolution returned will be that BEFORE any
// stretching by the filter has been applied".
//
// Since now the letterbox and pillarbox borders are handled by graphics
// renderer and are not part of the game anymore, these properties should
// return strictly native game size. This is required for backwards
// compatibility.
//
int System_GetScreenWidth() {
    return game.GetGameRes().Width;
}