Initial commit
This commit is contained in:
209
engines/ags/engine/ac/global_screen.cpp
Normal file
209
engines/ags/engine/ac/global_screen.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ags/shared/ac/common.h"
|
||||
#include "ags/engine/ac/game_setup.h"
|
||||
#include "ags/engine/ac/draw.h"
|
||||
#include "ags/engine/ac/game_setup.h"
|
||||
#include "ags/shared/ac/game_setup_struct.h"
|
||||
#include "ags/engine/ac/game_state.h"
|
||||
#include "ags/engine/ac/global_game.h"
|
||||
#include "ags/engine/ac/global_screen.h"
|
||||
#include "ags/engine/ac/runtime_defines.h"
|
||||
#include "ags/engine/ac/screen.h"
|
||||
#include "ags/engine/debugging/debug_log.h"
|
||||
#include "ags/engine/main/game_run.h"
|
||||
#include "ags/engine/media/audio/audio.h"
|
||||
#include "ags/engine/platform/base/ags_platform_driver.h"
|
||||
#include "ags/engine/gfx/graphics_driver.h"
|
||||
#include "ags/shared/gfx/bitmap.h"
|
||||
|
||||
namespace AGS3 {
|
||||
|
||||
using namespace AGS::Shared;
|
||||
using namespace AGS::Engine;
|
||||
|
||||
|
||||
void FlipScreen(int amount) {
|
||||
if ((amount < 0) || (amount > 3))
|
||||
quit("!FlipScreen: invalid argument (0-3)");
|
||||
_GP(play).screen_flipped = amount;
|
||||
}
|
||||
|
||||
void ShakeScreen(int severe) {
|
||||
EndSkippingUntilCharStops();
|
||||
|
||||
if (_GP(play).fast_forward)
|
||||
return;
|
||||
|
||||
severe = data_to_game_coord(severe);
|
||||
|
||||
// TODO: support shaking room viewport separately
|
||||
// TODO: rely on game speed setting? and/or provide frequency and duration args
|
||||
// TODO: unify blocking and non-blocking shake update
|
||||
|
||||
_GP(play).shakesc_length = 10;
|
||||
_GP(play).shakesc_delay = 2;
|
||||
_GP(play).shakesc_amount = severe;
|
||||
_GP(play).mouse_cursor_hidden++;
|
||||
|
||||
// FIXME: we have to sync audio here explicitly, because ShakeScreen
|
||||
// does not call any game update function while it works
|
||||
sync_audio_playback();
|
||||
if (_G(gfxDriver)->RequiresFullRedrawEachFrame()) {
|
||||
for (int hh = 0; hh < 40; hh++) {
|
||||
_G(loopcounter)++;
|
||||
_G(platform)->Delay(50);
|
||||
|
||||
render_graphics();
|
||||
|
||||
update_polled_stuff();
|
||||
}
|
||||
} else {
|
||||
// Optimized variant for software render: create game scene once and shake it
|
||||
construct_game_scene();
|
||||
_G(gfxDriver)->RenderToBackBuffer();
|
||||
for (int hh = 0; hh < 40; hh++) {
|
||||
_G(platform)->Delay(50);
|
||||
const int yoff = hh % 2 == 0 ? 0 : severe;
|
||||
_GP(play).shake_screen_yoff = yoff;
|
||||
render_to_screen();
|
||||
update_polled_stuff();
|
||||
}
|
||||
clear_letterbox_borders();
|
||||
render_to_screen();
|
||||
}
|
||||
sync_audio_playback();
|
||||
|
||||
_GP(play).mouse_cursor_hidden--;
|
||||
_GP(play).shakesc_length = 0;
|
||||
_GP(play).shakesc_delay = 0;
|
||||
_GP(play).shakesc_amount = 0;
|
||||
}
|
||||
|
||||
void ShakeScreenBackground(int delay, int amount, int length) {
|
||||
if (delay < 2)
|
||||
quit("!ShakeScreenBackground: invalid delay parameter");
|
||||
|
||||
amount = data_to_game_coord(amount);
|
||||
|
||||
if (amount < _GP(play).shakesc_amount) {
|
||||
// from a bigger to smaller shake, clear up the borders
|
||||
clear_letterbox_borders();
|
||||
}
|
||||
|
||||
_GP(play).shakesc_amount = amount;
|
||||
_GP(play).shakesc_delay = delay;
|
||||
_GP(play).shakesc_length = length;
|
||||
}
|
||||
|
||||
void TintScreen(int red, int grn, int blu) {
|
||||
if ((red < 0) || (grn < 0) || (blu < 0) || (red > 100) || (grn > 100) || (blu > 100))
|
||||
quit("!TintScreen: RGB values must be 0-100");
|
||||
|
||||
invalidate_screen();
|
||||
|
||||
if ((red == 0) && (grn == 0) && (blu == 0)) {
|
||||
_GP(play).screen_tint = -1;
|
||||
return;
|
||||
}
|
||||
red = (red * 25) / 10;
|
||||
grn = (grn * 25) / 10;
|
||||
blu = (blu * 25) / 10;
|
||||
_GP(play).screen_tint = red + (grn << 8) + (blu << 16);
|
||||
}
|
||||
|
||||
void FadeOut(int sppd) {
|
||||
EndSkippingUntilCharStops();
|
||||
|
||||
if (_GP(play).fast_forward) {
|
||||
_GP(play).screen_is_faded_out = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: we have to sync audio here explicitly, because FadeOut
|
||||
// does not call any game update function while it works
|
||||
sync_audio_playback();
|
||||
fadeout_impl(sppd);
|
||||
sync_audio_playback();
|
||||
|
||||
// Older engines did not mark the screen as "faded out" specifically for
|
||||
// the 8-bit games, for unknown reasons. There's at least one game where
|
||||
// this was accidentally useful, as it did not run FadeIn after FadeOut.
|
||||
if ((_G(loaded_game_file_version) < kGameVersion_361) && _GP(game).color_depth == 1) {
|
||||
_GP(play).screen_is_faded_out = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void fadeout_impl(int spdd) {
|
||||
if (_GP(play).screen_is_faded_out == 0) {
|
||||
_G(gfxDriver)->FadeOut(spdd, _GP(play).fade_to_red, _GP(play).fade_to_green, _GP(play).fade_to_blue, RENDER_SHOT_SKIP_ON_FADE);
|
||||
_GP(play).screen_is_faded_out = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void SetScreenTransition(int newtrans) {
|
||||
if ((newtrans < 0) || (newtrans > FADE_LAST))
|
||||
quit("!SetScreenTransition: invalid transition type");
|
||||
|
||||
_GP(play).fade_effect = newtrans;
|
||||
|
||||
debug_script_log("Screen transition changed");
|
||||
}
|
||||
|
||||
void SetNextScreenTransition(int newtrans) {
|
||||
if ((newtrans < 0) || (newtrans > FADE_LAST))
|
||||
quit("!SetNextScreenTransition: invalid transition type");
|
||||
|
||||
_GP(play).next_screen_transition = newtrans;
|
||||
|
||||
debug_script_log("SetNextScreenTransition engaged");
|
||||
}
|
||||
|
||||
void SetFadeColor(int red, int green, int blue) {
|
||||
if ((red < 0) || (red > 255) || (green < 0) || (green > 255) ||
|
||||
(blue < 0) || (blue > 255))
|
||||
quit("!SetFadeColor: Red, Green and Blue must be 0-255");
|
||||
|
||||
_GP(play).fade_to_red = red;
|
||||
_GP(play).fade_to_green = green;
|
||||
_GP(play).fade_to_blue = blue;
|
||||
}
|
||||
|
||||
void FadeIn(int sppd) {
|
||||
EndSkippingUntilCharStops();
|
||||
|
||||
if (_GP(play).fast_forward) {
|
||||
_GP(play).screen_is_faded_out = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update drawables, prepare them for the transition-in
|
||||
// in case this is called after the game state change but before any update was run
|
||||
SyncDrawablesState();
|
||||
// FIXME: we have to sync audio here explicitly, because FadeIn
|
||||
// does not call any game update function while it works
|
||||
sync_audio_playback();
|
||||
fadein_impl(_G(palette), sppd);
|
||||
sync_audio_playback();
|
||||
}
|
||||
|
||||
} // namespace AGS3
|
||||
Reference in New Issue
Block a user