static BOOLEAN TalkSegue (COUNT wait_track) { TALKING_STATE talkingState; // Transition animation to talking state, if necessary if (wantTalkingAnim () && haveTalkingAnim ()) { if (haveTransitionAnim ()) setRunIntroAnim (); setRunTalkingAnim (); // wait until the transition finishes while (runningIntroAnim ()) runCommAnimFrame (); } memset (&talkingState, 0, sizeof talkingState); if (wait_track == 0) { // Restarting with a rewind wait_track = WAIT_TRACK_ALL; talkingState.rewind = true; } else if (!PlayingTrack ()) { // initial start of player PlayTrack (); assert (PlayingTrack ()); } // Run the talking controls SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); talkingState.InputFunc = DoTalkSegue; talkingState.waitTrack = wait_track; DoInput (&talkingState, FALSE); ClearSubtitles (); if (talkingState.ended) { // reached the end; set STOP icon SetSliderImage (SetAbsFrameIndex (ActivityFrame, 8)); } // transition back to silent, if necessary if (runningTalkingAnim ()) setStopTalkingAnim (); // Wait until the animation task stops "talking" while (runningTalkingAnim ()) runCommAnimFrame (); return talkingState.ended; }
static BOOLEAN DoTalkSegue (TALKING_STATE *pTS) { bool left = false; bool right = false; COUNT curTrack; if (GLOBAL (CurrentActivity) & CHECK_ABORT) { pTS->ended = true; return FALSE; } if (PulsedInputState.menu[KEY_MENU_CANCEL]) { JumpTrack (); pTS->ended = true; return FALSE; } if (optSmoothScroll == OPT_PC) { left = PulsedInputState.menu[KEY_MENU_LEFT] != 0; right = PulsedInputState.menu[KEY_MENU_RIGHT] != 0; } else if (optSmoothScroll == OPT_3DO) { left = CurrentInputState.menu[KEY_MENU_LEFT] != 0; right = CurrentInputState.menu[KEY_MENU_RIGHT] != 0; } #if DEMO_MODE || CREATE_JOURNAL left = false; right = false; #endif if (right) { SetSliderImage (SetAbsFrameIndex (ActivityFrame, 3)); if (optSmoothScroll == OPT_PC) FastForward_Page (); else if (optSmoothScroll == OPT_3DO) FastForward_Smooth (); pTS->seeking = true; } else if (left || pTS->rewind) { pTS->rewind = false; SetSliderImage (SetAbsFrameIndex (ActivityFrame, 4)); if (optSmoothScroll == OPT_PC) FastReverse_Page (); else if (optSmoothScroll == OPT_3DO) FastReverse_Smooth (); pTS->seeking = true; } else if (pTS->seeking) { // This is only done once the seeking is over (in the smooth // scroll case, once the user releases the seek button) pTS->seeking = false; SetSliderImage (SetAbsFrameIndex (ActivityFrame, 2)); } else { // This used to have a buggy guard condition, which // would cause the animations to remain paused in a couple cases // after seeking back to the beginning. // Broken cases were: Syreen "several hours later" and Starbase // VUX Beast analysis by the scientist. CheckSubtitles (); } // XXX: When seeking, all animations (talking and ambient) stop // progressing. This is an original 3DO behavior, and I see no // reason why the animations cannot continue while seeking. UpdateAnimations (pTS->seeking); UpdateSpeechGraphics (); curTrack = PlayingTrack (); pTS->ended = !pTS->seeking && !curTrack; SleepThreadUntil (pTS->NextTime); // Need a high enough framerate for 3DO smooth seeking pTS->NextTime = GetTimeCounter () + ONE_SECOND / 60; return pTS->seeking || (curTrack && curTrack <= pTS->waitTrack); }
BOOLEAN DoConfirmExit (void) { BOOLEAN result; if (PlayingTrack ()) PauseTrack (); LockMutex (GraphicsLock); { RECT r; STAMP s; RECT ctxRect; CONTEXT oldContext; RECT oldRect; BOOLEAN response = FALSE, done; oldContext = SetContext (ScreenContext); GetContextClipRect (&oldRect); SetContextClipRect (NULL); GetContextClipRect (&ctxRect); r.extent.width = CONFIRM_WIN_WIDTH + 4; r.extent.height = CONFIRM_WIN_HEIGHT + 4; r.corner.x = (ctxRect.extent.width - r.extent.width) >> 1; r.corner.y = (ctxRect.extent.height - r.extent.height) >> 1; s = SaveContextFrame (&r); SetSystemRect (&r); DrawConfirmationWindow (response); FlushGraphics (); FlushInput (); done = FALSE; do { // Forbid recursive calls or pausing here! ExitRequested = FALSE; GamePaused = FALSE; UpdateInputState (); if (GLOBAL (CurrentActivity) & CHECK_ABORT) { // something else triggered an exit done = TRUE; response = TRUE; } else if (PulsedInputState.menu[KEY_MENU_SELECT]) { done = TRUE; PlayMenuSound (MENU_SOUND_SUCCESS); } else if (PulsedInputState.menu[KEY_MENU_CANCEL]) { done = TRUE; response = FALSE; } else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT]) { response = !response; DrawConfirmationWindow (response); PlayMenuSound (MENU_SOUND_MOVE); } SleepThread (ONE_SECOND / 30); } while (!done); // Restore the screen under the confirmation window DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); ClearSystemRect (); if (response || (GLOBAL (CurrentActivity) & CHECK_ABORT)) { result = TRUE; GLOBAL (CurrentActivity) |= CHECK_ABORT; } else { result = FALSE; } ExitRequested = FALSE; GamePaused = FALSE; FlushInput (); SetContextClipRect (&oldRect); SetContext (oldContext); } UnlockMutex (GraphicsLock); if (PlayingTrack ()) ResumeTrack (); return (result); }
/* This code assumes that you aren't in Character Mode. This is * currently safe because VControl doesn't see keystrokes when you * are, and thus cannot conclude that an exit is necessary. */ BOOLEAN DoConfirmExit (void) { BOOLEAN result; static BOOLEAN in_confirm = FALSE; if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE && !(LastActivity & CHECK_RESTART)) SuspendGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) PauseTrack (); LockMutex (GraphicsLock); if (in_confirm) { result = FALSE; ExitRequested = FALSE; } else { RECT r; STAMP s; FRAME F; CONTEXT oldContext; RECT oldRect; BOOLEAN response = FALSE, done; in_confirm = TRUE; oldContext = SetContext (ScreenContext); GetContextClipRect (&oldRect); SetContextClipRect (NULL_PTR); r.extent.width = CONFIRM_WIN_WIDTH + 4; r.extent.height = CONFIRM_WIN_HEIGHT + 4; r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1; r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1; s.origin = r.corner; F = CaptureDrawable (LoadDisplayPixmap (&r, (FRAME)0)); SetSystemRect (&r); DrawConfirmationWindow (response); // Releasing the lock lets the rotate_planet_task // draw a frame. PauseRotate can still allow one more frame // to be drawn, so it is safer to just not release the lock //UnlockMutex (GraphicsLock); FlushGraphics (); //LockMutex (GraphicsLock); GLOBAL (CurrentActivity) |= CHECK_ABORT; FlushInput (); done = FALSE; do { // Forbid recursive calls or pausing here! ExitRequested = FALSE; GamePaused = FALSE; UpdateInputState (); if (PulsedInputState.menu[KEY_MENU_SELECT]) { done = TRUE; PlayMenuSound (MENU_SOUND_SUCCESS); } else if (PulsedInputState.menu[KEY_MENU_CANCEL]) { done = TRUE; response = FALSE; } else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT]) { response = !response; DrawConfirmationWindow (response); PlayMenuSound (MENU_SOUND_MOVE); } TaskSwitch (); } while (!done); s.frame = F; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); ClearSystemRect (); if (response) { result = TRUE; } else { result = FALSE; GLOBAL (CurrentActivity) &= ~CHECK_ABORT; } ExitRequested = FALSE; GamePaused = FALSE; FlushInput (); SetContextClipRect (&oldRect); SetContext (oldContext); } UnlockMutex (GraphicsLock); if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE && !(LastActivity & CHECK_RESTART)) ResumeGameClock (); if (CommData.ConversationPhrases && PlayingTrack ()) { ResumeTrack (); if (CommData.AlienTransitionDesc.AnimFlags & TALK_DONE) do_subtitles ((void *)~0); } in_confirm = FALSE; return (result); }
BOOLEAN PauseGame (void) { RECT r; STAMP s; BOOLEAN ClockActive; CONTEXT OldContext; FRAME F; HOT_SPOT OldHot; if (ActivityFrame == 0 || (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_PAUSE)) || (LastActivity & (CHECK_LOAD | CHECK_RESTART))) return (FALSE); GLOBAL (CurrentActivity) |= CHECK_PAUSE; ClockActive = (BOOLEAN)( LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && GameClockRunning () ); if (ClockActive) SuspendGameClock (); else if (CommData.ConversationPhrases && PlayingTrack ()) PauseTrack (); SetSemaphore (GraphicsSem); OldContext = SetContext (ScreenContext); OldHot = SetFrameHot (Screen, MAKE_HOT_SPOT (0, 0)); GetFrameRect (ActivityFrame, &r); r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1; r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1; s.origin = r.corner; s.frame = ActivityFrame; F = CaptureDrawable (LoadDisplayPixmap (&r, (FRAME)0)); DrawStamp (&s); FlushGraphics (); { BYTE scan; scan = KBDToUNICODE (SK_F1); while (KeyDown (scan)) TaskSwitch (); } FlushInput (); while (KeyHit () != SK_F1) TaskSwitch (); s.frame = F; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); SetFrameHot (Screen, OldHot); SetContext (OldContext); WaitForNoInput (ONE_SECOND / 4); FlushInput (); ClearSemaphore (GraphicsSem); if (ClockActive) ResumeGameClock (); else if (CommData.ConversationPhrases && PlayingTrack ()) ResumeTrack (); TaskSwitch (); GLOBAL (CurrentActivity) &= ~CHECK_PAUSE; return (TRUE); }