diff --git a/include/parts.h b/include/parts.h index 7dab905..db6ff6b 100644 --- a/include/parts.h +++ b/include/parts.h @@ -248,6 +248,7 @@ void PE_SeekEndMotion(void); void PE_UpdateMotionTime(int time, bool skip); bool PE_IsMotion(void); int PE_GetMotionEndTime(void); +void PE_PauseMotion(bool pause); // text.c bool PE_SetText(int parts_no, struct string *text, int state); diff --git a/src/hll/PartsEngine.c b/src/hll/PartsEngine.c index 4e74357..3d758e4 100644 --- a/src/hll/PartsEngine.c +++ b/src/hll/PartsEngine.c @@ -260,6 +260,10 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, REQUIRE_INTS(1); ints[0].i = PE_get_system_controller(); return 1; + case 3: // void PauseMotion(bool pause) + REQUIRE_INTS(1); + PE_PauseMotion(!!ints[0].i); + return 1; case 4: // void SetWantSave(int parts_no, bool want_save) REQUIRE_INTS(2); PE_parts_set_want_save(ints[0].i, !!ints[1].i); diff --git a/src/parts/motion.c b/src/parts/motion.c index 13a593f..2d29d0d 100644 --- a/src/parts/motion.c +++ b/src/parts/motion.c @@ -38,6 +38,8 @@ static struct parts_motion_list global_motion_list = // true after call to BeginMotion until the motion ends or EndMotion is called static bool is_motion = false; +// true while the motion is paused (time does not advance) +static bool is_motion_paused = false; // the elapsed time of the current motion static int motion_t = 0; // the end time of the current motion @@ -498,6 +500,7 @@ void PE_BeginMotion(void) // FIXME: starting a motion seems to clear non-default states motion_t = 0; is_motion = true; + is_motion_paused = false; parts_init_all_motion(); } @@ -508,6 +511,7 @@ void PE_EndMotion(void) motion_t = 0; motion_end_t = 0; is_motion = false; + is_motion_paused = false; parts_fini_all_motion(); } @@ -531,6 +535,8 @@ void PE_SeekEndMotion(void) void PE_UpdateMotionTime(int time, possibly_unused bool skip) { // TODO: use skip + if (is_motion_paused) + return; PE_SetMotionTime(motion_t + time); } @@ -543,3 +549,20 @@ int PE_GetMotionEndTime(void) { return motion_end_t; } + +void PE_PauseMotion(bool pause) +{ + if (parts_began_click) + return; + if (!is_motion) + return; + if (is_motion_paused == pause) + return; + is_motion_paused = pause; + + // While paused, the per-frame advance stops updating the whole-screen + // vibration offset. Reset it to the origin so the screen doesn't stay + // stuck at the last shake position. + if (pause) + parts_set_global_pos((Point){ 0, 0 }); +}