Skip to content

Commit

Permalink
Animate Window_Message during transitions
Browse files Browse the repository at this point in the history
Emulates the RPG_RT behavior for EasyRPG#1706 Tests 17 & 18
  • Loading branch information
mateofio committed Dec 31, 2019
1 parent ddcdb56 commit 11cb051
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 10 deletions.
6 changes: 6 additions & 0 deletions src/game_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ int Game_Message::WordWrap(const std::string& line, const int limit, const std::
return line_count;
}

void Game_Message::AdvanceAnimationFrames(int frames) {
if (window) {
window->AdvanceAnimationFrames(frames);
}
}

void Game_Message::Update() {
if (window) {
window->Update();
Expand Down
3 changes: 3 additions & 0 deletions src/game_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ namespace Game_Message {

void Update();

/** Calls AdvanceAnimationFrames() on the Window_Message */
void AdvanceAnimationFrames(int frames);

/** Reset the face graphic. */
void ClearFace();

Expand Down
25 changes: 19 additions & 6 deletions src/scene_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,16 @@ void Scene_Map::TransitionOut(SceneType next_scene) {
}

if (next_scene == Scene::Battle) {
Graphics::GetTransition().Init((Transition::TransitionType)Game_System::GetTransition(Game_System::Transition_BeginBattleErase), this, 32, true);
InitTransitionOut((Transition::TransitionType)Game_System::GetTransition(Game_System::Transition_BeginBattleErase), 32);
Graphics::GetTransition().AppendBefore(Color(255, 255, 255, 255), 12, 2);
return;
}
if (next_scene == Scene::Gameover) {
Graphics::GetTransition().Init(Transition::TransitionFadeOut, this, 32, true);
InitTransitionOut(Transition::TransitionFadeOut, 32);
return;
}
Scene::TransitionOut(next_scene);

InitTransitionOut(Transition::TransitionFadeOut, 6);
}

void Scene_Map::DrawBackground() {
Expand Down Expand Up @@ -324,7 +325,7 @@ void Scene_Map::StartPendingTeleport(TeleportParams tp) {
request->Start();

if (!Graphics::IsTransitionErased() && tt.GetType() != TeleportTarget::eVehicleHackTeleport && tp.erase_screen) {
Graphics::GetTransition().Init((Transition::TransitionType)Game_System::GetTransition(Game_System::Transition_TeleportErase), this, 32, true);
InitTransitionOut((Transition::TransitionType)Game_System::GetTransition(Game_System::Transition_TeleportErase), 32);
}

AsyncNext([=]() { FinishPendingTeleport(tp); });
Expand Down Expand Up @@ -450,7 +451,7 @@ void Scene_Map::OnAsyncSuspend(F&& f, AsyncOp aop, bool is_preupdate) {

if (aop.GetType() == AsyncOp::eEraseScreen) {
auto tt = static_cast<Transition::TransitionType>(aop.GetTransitionType());
Graphics::GetTransition().Init(tt, this, 32, true);
InitTransitionOut(tt, 32);
if (!is_preupdate) {
// RPG_RT behavior: EraseScreen commands performed during pre-update don't stick.
screen_erased_by_event = true;
Expand All @@ -471,7 +472,7 @@ void Scene_Map::OnAsyncSuspend(F&& f, AsyncOp aop, bool is_preupdate) {
Game_System::BgmFade(800);

// FIXME: Is 36 correct here?
Graphics::GetTransition().Init(Transition::TransitionFadeOut, Scene::instance.get(), 36, true);
InitTransitionOut(Transition::TransitionFadeOut, 36);

AsyncNext([=]() { StartInn(); });
return;
Expand Down Expand Up @@ -515,3 +516,15 @@ void Scene_Map::UpdateInn() {
FinishInn();
}
}

void Scene_Map::InitTransitionOut(Transition::TransitionType tt, int frames) {
// In rare cases where a message and a transition are triggered on the same frame, RPG_RT
// will still animate the message box open/close and the transition effect will show
// the resulting message box state. This can affect interpreter timing so we try to emulate it.
// See #1706 Tests 17 and 18
auto cb = [this](int frames) {
message_window->AdvanceAnimationFrames(frames);
};
Graphics::GetTransition().Init(tt, this, frames, true, cb);
}

3 changes: 3 additions & 0 deletions src/scene_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "window_message.h"
#include "window_varlist.h"
#include "game_map.h"
#include "transition.h"

/**
* Scene Map class.
Expand Down Expand Up @@ -91,6 +92,8 @@ class Scene_Map: public Scene {
void UpdateInn();
void FinishInn();

void InitTransitionOut(Transition::TransitionType tt, int frames);

template <typename F> void AsyncNext(F&& f);
template <typename F> void OnAsyncSuspend(F&& f, AsyncOp aop, bool is_preupdate);

Expand Down
14 changes: 12 additions & 2 deletions src/transition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "baseui.h"
#include "drawable.h"
#include "drawable_mgr.h"
#include "game_message.h"

Transition::Transition() : Drawable(TypeTransition, Priority_Transition, true)
{
Expand All @@ -45,7 +46,7 @@ void Transition::AppendBefore(Color color, int duration, int iterations) {
total_frames += flash_duration * flash_iterations;
}

void Transition::Init(TransitionType type, Scene *linked_scene, int duration, bool erase) {
void Transition::Init(TransitionType type, Scene *linked_scene, int duration, bool erase, const TransitionCallback& cb) {
// FIXME: Break this dependency on DisplayUI
if (!black_screen && DisplayUi) {
black_screen = Bitmap::Create(DisplayUi->GetWidth(), DisplayUi->GetHeight(), Color(0, 0, 0, 255));
Expand All @@ -61,6 +62,15 @@ void Transition::Init(TransitionType type, Scene *linked_scene, int duration, bo
return;
}

if (transition_type == TransitionErase) {
duration = 1;
}

// Note: This must be called before we grab the screen!
if (cb) {
cb(duration);
}

frozen_screen = Graphics::SnapToBitmap(GetZ());
screen1 = erase ? frozen_screen : old_frozen_screen? old_frozen_screen : black_screen;
screen2 = erase ? black_screen : frozen_screen;
Expand All @@ -73,7 +83,7 @@ void Transition::Init(TransitionType type, Scene *linked_scene, int duration, bo
current_frame = 0;
flash_iterations = 0;
flash_duration = 0;
total_frames = transition_type == TransitionErase ? 1 : duration;
total_frames = duration;

SetAttributesTransitions();
}
Expand Down
4 changes: 3 additions & 1 deletion src/transition.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class Transition : public Drawable {
TransitionNone
};

using TransitionCallback = std::function<void(int)>;

Transition();

/**
Expand All @@ -83,7 +85,7 @@ class Transition : public Drawable {
* @param duration transition duration.
* @param erase erase screen flag.
*/
void Init(TransitionType type, Scene *linked_scene, int duration, bool erase = false);
void Init(TransitionType type, Scene *linked_scene, int duration, bool erase = false, const TransitionCallback& cb = {});

void AppendBefore(Color color, int duration, int iterations);

Expand Down
15 changes: 15 additions & 0 deletions src/window_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,21 @@ void Window_Message::ResetWindow() {

}

void Window_Message::AdvanceAnimationFrames(int frames) {
if (frames == 0) {
return;
}

close_started_this_frame = false;

while (frames > 0) {
bool was_closing = IsClosing();
Window::Update();
close_finished_this_frame = was_closing && !IsClosing();
--frames;
}
}

void Window_Message::Update() {
if (IsOpening()) { DebugLog("%d: MSG OPENING"); }
if (IsClosing()) { DebugLog("%d: MSG CLOSING"); }
Expand Down
10 changes: 9 additions & 1 deletion src/window_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,19 @@ class Window_Message: public Window_Selectable {

void Update() override;

/**
* Force the window animations to advance by a number of frames.
* This is exercised by some edge cases with transitions
*
* @params frames number of frames of the transition.
*/
void AdvanceAnimationFrames(int frames);

/**
* Continues outputting more text. Also handles the
* CommandCode parsing.
*/
virtual void UpdateMessage();
void UpdateMessage();

/**
* Stub. For choice.
Expand Down

0 comments on commit 11cb051

Please sign in to comment.