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); }
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); }
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]); } } }
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; } } }
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; } } }
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(); }
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; } }
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); }
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); }
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; }
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; }
// 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; }
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; }
int System_GetScreenHeight() { return game.GetGameRes().Height; }
// 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; }
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; } }
// [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; }