From: <av...@us...> - 2009-11-26 17:10:23
|
Revision: 3355 http://sc2.svn.sourceforge.net/sc2/?rev=3355&view=rev Author: avolkov Date: 2009-11-26 17:10:02 +0000 (Thu, 26 Nov 2009) Log Message: ----------- Comm animations task retired; Talking Pet mind control strobe reworked into an ambient animation; potential buffer overflow and potential wrong summary context fixed (counts towards bug #576) Modified Paths: -------------- trunk/sc2/src/uqm/comm/talkpet/talkpet.c trunk/sc2/src/uqm/comm.c trunk/sc2/src/uqm/comm.h trunk/sc2/src/uqm/commanim.c trunk/sc2/src/uqm/commanim.h trunk/sc2/src/uqm/oscill.c trunk/sc2/src/uqm/oscill.h Modified: trunk/sc2/src/uqm/comm/talkpet/talkpet.c =================================================================== --- trunk/sc2/src/uqm/comm/talkpet/talkpet.c 2009-11-25 21:43:48 UTC (rev 3354) +++ trunk/sc2/src/uqm/comm/talkpet/talkpet.c 2009-11-26 17:10:02 UTC (rev 3355) @@ -22,6 +22,10 @@ #include "uqm/build.h" +#define STROBE_RATE 10 +#define STROBE_LENGTH (ONE_SECOND * 3 / 2) +#define NUM_STROBES (STROBE_LENGTH * STROBE_RATE / ONE_SECOND) + static LOCDATA talkpet_desc = { NULL, /* init_encounter_func */ @@ -40,7 +44,7 @@ NULL_RESOURCE, /* AlienAltSong */ 0, /* AlienSongFlags */ TALKING_PET_CONVERSATION_PHRASES, /* PlayerPhrases */ - 16, /* NumAnimations */ + 17, /* NumAnimations */ { /* AlienAmbientArray (ambient animations) */ { 7, /* StartIndex */ @@ -173,6 +177,15 @@ ONE_SECOND, ONE_SECOND * 3, /* RestartRate */ 0, /* BlockMask */ }, + { /* Mind control strobe (on-demand) */ + 1, /* StartIndex */ + NUM_STROBES * 2, /* NumFrames */ + CIRCULAR_ANIM | COLORXFORM_ANIM | ONE_SHOT_ANIM + | ANIM_DISABLED, /* AnimFlags */ + ONE_SECOND / (STROBE_RATE * 2), 0, /* FrameRate */ + 0, 0, /* RestartRate */ + 0, /* BlockMask */ + }, }, { /* AlienTransitionDesc */ 0, /* StartIndex */ @@ -197,10 +210,6 @@ NULL, }; -#define STROBE_RATE 15 -#define STROBE_LENGTH (ONE_SECOND * 3 / 2) -#define NUM_STROBES (STROBE_LENGTH * STROBE_RATE / ONE_SECOND) - static void ExitConversation (RESPONSE_REF R) { @@ -266,19 +275,8 @@ static void MindControlStrobe (void) { - BYTE i; - - for (i = 0; i < NUM_STROBES; ++i) - { - XFormColorMap (GetColorMapAddress ( - SetAbsColorMapIndex (CommData.AlienColorMap, 1) - ), 0); - SleepThread (ONE_SECOND / (STROBE_RATE * 2)); - XFormColorMap (GetColorMapAddress ( - SetAbsColorMapIndex (CommData.AlienColorMap, 0) - ), 0); - SleepThread (ONE_SECOND / (STROBE_RATE * 2)); - } + // Enable the one-shot strobe animation + CommData.AlienAmbientArray[16].AnimFlags &= ~ANIM_DISABLED; } static void Modified: trunk/sc2/src/uqm/comm.c =================================================================== --- trunk/sc2/src/uqm/comm.c 2009-11-25 21:43:48 UTC (rev 3354) +++ trunk/sc2/src/uqm/comm.c 2009-11-26 17:10:02 UTC (rev 3355) @@ -50,7 +50,21 @@ (speechVolumeScale == 0.0f ? NORMAL_VOLUME : (NORMAL_VOLUME >> 1)) #define FOREGROUND_VOL NORMAL_VOLUME +// Oscilloscope frame rate +// Should be <= COMM_ANIM_RATE +// XXX: was 32 picked experimentally? +#define OSCILLOSCOPE_RATE (ONE_SECOND / 32) +// Maximum comm animation frame rate (actual execution rate) +// A gfx frame is not always produced during an execution frame, +// and several animations are combined into one gfx frame. +// The rate was originally 120fps which allowed for more animation +// precision which is ultimately wasted on the human eye anyway. +// The highest known stable animation rate is 40fps, so that's what we use. +#define COMM_ANIM_RATE (ONE_SECOND / 40) + +static CONTEXT AnimContext; + LOCDATA CommData; UNICODE shared_phrase_buf[2048]; @@ -77,20 +91,14 @@ BYTE top_response; RESPONSE_ENTRY response_list[MAX_RESPONSES]; - Task AnimTask; - - COUNT phrase_buf_index; - UNICODE phrase_buf[512]; + UNICODE phrase_buf[1024]; } ENCOUNTER_STATE; static ENCOUNTER_STATE *pCurInputState; -// Mutex guards accesses to SubtitleText, last_subtitle and clear_subtitles. -static Mutex subtitle_mutex; -// These vars are indirectly accessed by the ambient_anim_task -static volatile BOOLEAN clear_subtitles; +static BOOLEAN clear_subtitles; static TEXT SubtitleText; -static const UNICODE * volatile last_subtitle; +static const UNICODE *last_subtitle; static CONTEXT TextCacheContext; static FRAME TextCacheFrame; @@ -104,6 +112,7 @@ static void ClearSubtitles (void); static void CheckSubtitles (void); +static void RedrawSubtitles (void); /* _count_lines - sees how many lines a given input string would take to @@ -392,14 +401,13 @@ void init_communication (void) { - subtitle_mutex = CreateMutex ("Subtitle Lock", - SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO); + // now a no-op } void uninit_communication (void) { - DestroyMutex (subtitle_mutex); + // now a no-op } static void @@ -481,34 +489,73 @@ UnbatchGraphics (); } -void -UpdateSpeechGraphics (BOOLEAN Initialize) +static void +InitSpeechGraphics (void) { + RECT r; + RECT sr; + FRAME f; + + InitOscilloscope (0, 0, RADAR_WIDTH, RADAR_HEIGHT, + SetAbsFrameIndex (ActivityFrame, 9)); + + f = SetAbsFrameIndex (ActivityFrame, 2); + GetFrameRect (f, &r); + SetSliderImage (f); + f = SetAbsFrameIndex (ActivityFrame, 5); + GetFrameRect (f, &sr); + InitSlider (0, SLIDER_Y, SIS_SCREEN_WIDTH, sr.extent.height, + r.extent.width, r.extent.height, f); +} + +static void +UpdateSpeechGraphics (void) +{ + static TimeCount NextTime; CONTEXT OldContext; - if (Initialize) - { - RECT r, sr; - FRAME f; + if (GetTimeCounter () < NextTime) + return; // too early - InitOscilloscope (0, 0, RADAR_WIDTH, RADAR_HEIGHT, - SetAbsFrameIndex (ActivityFrame, 9)); - f = SetAbsFrameIndex (ActivityFrame, 2); - GetFrameRect (f, &r); - SetSliderImage (f); - f = SetAbsFrameIndex (ActivityFrame, 5); - GetFrameRect (f, &sr); - InitSlider (0, SLIDER_Y, SIS_SCREEN_WIDTH, sr.extent.height, - r.extent.width, r.extent.height, f); - } + NextTime = GetTimeCounter () + OSCILLOSCOPE_RATE; OldContext = SetContext (RadarContext); - Oscilloscope (!Initialize); + DrawOscilloscope (); SetContext (SpaceContext); - Slider (); + DrawSlider (); SetContext (OldContext); } +static void +UpdateAnimations (bool paused) +{ + static TimeCount NextTime; + CONTEXT OldContext; + BOOLEAN change; + + if (GetTimeCounter () < NextTime) + return; // too early + + NextTime = GetTimeCounter () + COMM_ANIM_RATE; + + OldContext = SetContext (AnimContext); + BatchGraphics (); + // Advance and draw ambient, transit and talk animations + change = ProcessCommAnimations (clear_subtitles, paused); + if (change) + RedrawSubtitles (); + UnbatchGraphics (); + clear_subtitles = FALSE; + SetContext (OldContext); +} + +static void +UpdateCommGraphics (void) +{ + UpdateAnimations (false); + UpdateSpeechGraphics (); +} + // Derived from INPUT_STATE_DESC typedef struct talking_state { @@ -560,8 +607,6 @@ right = false; #endif - LockMutex (GraphicsLock); - if (right) { SetSliderImage (SetAbsFrameIndex (ActivityFrame, 3)); @@ -570,10 +615,6 @@ else if (optSmoothScroll == OPT_3DO) FastForward_Smooth (); pTS->seeking = true; - // XXX: This causes all animations (talking and ambient) - // in ambient_anim_task to stop progressing. I see no reason why - // the animations cannot continue while seeking. - PauseAnimTask = TRUE; } else if (left || pTS->rewind) { @@ -584,8 +625,6 @@ else if (optSmoothScroll == OPT_3DO) FastReverse_Smooth (); pTS->seeking = true; - // XXX: See pause discussion above - PauseAnimTask = TRUE; } else if (pTS->seeking) { @@ -595,16 +634,21 @@ SetSliderImage (SetAbsFrameIndex (ActivityFrame, 2)); } else - { // XXX: See pause discussion above - // Additionally, this used to have a buggy guard condition, which + { + // 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. - PauseAnimTask = FALSE; CheckSubtitles (); } - + + LockMutex (GraphicsLock); + // 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 (); UnlockMutex (GraphicsLock); curTrack = PlayingTrack (); @@ -617,6 +661,15 @@ return pTS->seeking || (curTrack && curTrack <= pTS->waitTrack); } +static void +runCommAnimFrame (void) +{ + LockMutex (GraphicsLock); + UpdateCommGraphics (); + UnlockMutex (GraphicsLock); + SleepThread (COMM_ANIM_RATE); +} + static BOOLEAN TalkSegue (COUNT wait_track) { @@ -630,12 +683,9 @@ setRunTalkingAnim (); + // wait until the transition finishes while (runningIntroAnim ()) - { // wait until the transition finishes - UnlockMutex (GraphicsLock); - SleepThread (ONE_SECOND / 30); - LockMutex (GraphicsLock); - } + runCommAnimFrame (); } memset (&talkingState, 0, sizeof talkingState); @@ -651,16 +701,12 @@ assert (PlayingTrack ()); } - UnlockMutex (GraphicsLock); - // Run the talking controls + SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); talkingState.InputFunc = DoTalkSegue; talkingState.waitTrack = wait_track; DoInput (&talkingState, FALSE); - LockMutex (GraphicsLock); - - PauseAnimTask = FALSE; ClearSubtitles (); if (talkingState.ended) @@ -672,20 +718,11 @@ if (runningTalkingAnim ()) setStopTalkingAnim (); - return talkingState.ended; -} - -static void -FlushTalkSegue (void) -{ - WaitForNoInput (ONE_SECOND / 2, TRUE); - // Wait until the animation task stops "talking" - do - SleepThread (ONE_SECOND / 30); - while (runningTalkingAnim ()); + while (runningTalkingAnim ()) + runCommAnimFrame (); - TalkingFinished = TRUE; + return talkingState.ended; } static void @@ -732,53 +769,34 @@ void AlienTalkSegue (COUNT wait_track) { - BOOLEAN done; - // this skips any talk segues that follow an aborted one if ((GLOBAL (CurrentActivity) & CHECK_ABORT) || TalkingFinished) return; - LockMutex (GraphicsLock); - if (!pCurInputState->Initialized) { + InitSpeechGraphics (); + LockMutex (GraphicsLock); SetColorMap (GetColorMapAddress (CommData.AlienColorMap)); + SetContext (AnimContext); DrawAlienFrame (NULL, 0, TRUE); - UpdateSpeechGraphics (TRUE); - + UpdateSpeechGraphics (); CommIntroTransition (); + UnlockMutex (GraphicsLock); + pCurInputState->Initialized = TRUE; PlayMusic (CommData.AlienSong, TRUE, 1); SetMusicVolume (BACKGROUND_VOL); - { - DWORD TimeOut; + InitCommAnimations (); - TimeOut = GetTimeCounter () + (ONE_SECOND >> 1); - // Anim task processes not only ambient animations, but also - // talking animations and subtitles - pCurInputState->AnimTask = StartCommAnimTask (); - - UnlockMutex (GraphicsLock); - SleepThreadUntil (TimeOut); - LockMutex (GraphicsLock); - } - LastActivity &= ~CHECK_LOAD; } - done = TalkSegue (wait_track); - if (done) + TalkingFinished = TalkSegue (wait_track); + if (TalkingFinished) FadeMusic (FOREGROUND_VOL, ONE_SECOND); - - UnlockMutex (GraphicsLock); - FlushTalkSegue (); - - if (!done) - { // there is more to come - TalkingFinished = FALSE; - } } @@ -835,7 +853,6 @@ RECT r; TEXT t; int row; - FONT oldFont; r.corner.x = 0; r.corner.y = 0; @@ -843,6 +860,7 @@ r.extent.height = SIS_SCREEN_HEIGHT - SLIDER_Y - SLIDER_HEIGHT + 2; LockMutex (GraphicsLock); + SetContext (AnimContext); SetContextForeGroundColor (COMM_HISTORY_BACKGROUND_COLOR); DrawFilledRectangle (&r); @@ -852,7 +870,7 @@ t.baseline.x = 2; t.align = ALIGN_LEFT; t.baseline.y = DELTA_Y_SUMMARY; - oldFont = SetContextFont (TinyFont); + SetContextFont (TinyFont); for (row = 0; row < MAX_SUMM_ROWS && pSS->NextSub; ++row, pSS->NextSub = GetNextTrackSubtitle (pSS->NextSub)) @@ -910,7 +928,6 @@ font_DrawText (&mt); } - SetContextFont (oldFont); UnlockMutex (GraphicsLock); pSS->PrintNext = FALSE; @@ -927,20 +944,16 @@ static void SelectResponse (ENCOUNTER_STATE *pES) { - const unsigned char *end; TEXT *response_text = &pES->response_list[pES->cur_response].response_text; - end = skipUTF8Chars(response_text->pStr, response_text->CharCount); - pES->phrase_buf_index = end - response_text->pStr; - memcpy(pES->phrase_buf, response_text->pStr, pES->phrase_buf_index); - pES->phrase_buf[pES->phrase_buf_index++] = '\0'; - + utf8StringCopy (pES->phrase_buf, sizeof pES->phrase_buf, + response_text->pStr); LockMutex (GraphicsLock); FeedbackPlayerPhrase (pES->phrase_buf); + UnlockMutex (GraphicsLock); StopTrack (); ClearSubtitles (); SetSliderImage (SetAbsFrameIndex (ActivityFrame, 2)); - UnlockMutex (GraphicsLock); FadeMusic (BACKGROUND_VOL, ONE_SECOND); @@ -959,10 +972,7 @@ LockMutex (GraphicsLock); if (pES) FeedbackPlayerPhrase (pES->phrase_buf); - PauseAnimTask = TRUE; UnlockMutex (GraphicsLock); - // wait for ambient anim task to pause - SleepThread (ONE_SECOND / 30); SummaryState.Initialized = FALSE; DoConvSummary (&SummaryState); @@ -971,7 +981,6 @@ if (pES) RefreshResponses (pES); clear_subtitles = TRUE; - PauseAnimTask = FALSE; UnlockMutex (GraphicsLock); } @@ -982,10 +991,9 @@ LockMutex (GraphicsLock); if (pES) FeedbackPlayerPhrase (pES->phrase_buf); - TalkingFinished = FALSE; - TalkSegue (0); UnlockMutex (GraphicsLock); - FlushTalkSegue (); + + TalkSegue (0); } static void @@ -1058,8 +1066,12 @@ UnlockMutex (GraphicsLock); } + LockMutex (GraphicsLock); + UpdateCommGraphics (); + UnlockMutex (GraphicsLock); + SleepThreadUntil (pES->NextTime); - pES->NextTime = GetTimeCounter () + ONE_SECOND / 20; + pES->NextTime = GetTimeCounter () + COMM_ANIM_RATE; } } @@ -1097,8 +1109,12 @@ pLRS->TimeOut = FadeMusic (0, ONE_SECOND * 2) + ONE_SECOND / 60; } + LockMutex (GraphicsLock); + UpdateCommGraphics (); + UnlockMutex (GraphicsLock); + SleepThreadUntil (pLRS->NextTime); - pLRS->NextTime = GetTimeCounter () + ONE_SECOND / 60; + pLRS->NextTime = GetTimeCounter () + COMM_ANIM_RATE; return TRUE; } @@ -1110,7 +1126,10 @@ // First, finish playing all queued tracks if not done yet if (!TalkingFinished) + { AlienTalkSegue (WAIT_TRACK_ALL); + return TRUE; + } if (GLOBAL (CurrentActivity) & CHECK_ABORT) ; @@ -1128,23 +1147,13 @@ else { PlayerResponseInput (pES); - return (TRUE); + return TRUE; } LockMutex (GraphicsLock); - - if (pES->AnimTask) - { - UnlockMutex (GraphicsLock); - ConcludeTask (pES->AnimTask); - LockMutex (GraphicsLock); - pES->AnimTask = 0; - } - SetContext (SpaceContext); - DestroyContext (TaskContext); - TaskContext = 0; - + DestroyContext (AnimContext); + AnimContext = NULL; UnlockMutex (GraphicsLock); FlushColorXForms (); @@ -1155,7 +1164,7 @@ StopTrack (); SleepThreadUntil (FadeMusic (NORMAL_VOLUME, 0) + ONE_SECOND / 60); - return (FALSE); + return FALSE; } void @@ -1234,6 +1243,8 @@ SubtitleText.baseline = CommData.AlienTextBaseline; SubtitleText.align = CommData.AlienTextAlign; + LockMutex (GraphicsLock); + // init subtitle cache context TextCacheContext = CreateContext ("TextCacheContext"); TextCacheFrame = CaptureDrawable ( @@ -1247,7 +1258,6 @@ ClearDrawable (); SetFrameTransparentColor (TextCacheFrame, TextBack); - ES.phrase_buf_index = 1; ES.phrase_buf[0] = '\0'; SetContext (SpaceContext); @@ -1256,8 +1266,8 @@ { RECT r; - TaskContext = CreateContext ("TaskContext"); - SetContext (TaskContext); + AnimContext = CreateContext ("AnimContext"); + SetContext (AnimContext); SetContextFGFrame (Screen); GetFrameRect (CommData.AlienFrame, &r); r.extent.width = SIS_SCREEN_WIDTH; @@ -1308,6 +1318,9 @@ (*CommData.uninit_encounter_func) (); LockMutex (GraphicsLock); + SetContext (SpaceContext); + SetContextFont (OldFont); + UnlockMutex (GraphicsLock); DestroyStringTable (ReleaseStringTable (CommData.ConversationPhrases)); DestroyMusic (CommData.AlienSong); @@ -1318,8 +1331,6 @@ DestroyContext (TextCacheContext); DestroyDrawable (ReleaseDrawable (TextCacheFrame)); - SetContext (SpaceContext); - SetContextFont (OldFont); DestroyFont (PlayerFont); // Some support code tests either of these to see if the @@ -1373,6 +1384,8 @@ } } + UnlockMutex (GraphicsLock); + if (which_comm == URQUAN_DRONE_CONVERSATION) { status = URQUAN_DRONE_SHIP; @@ -1416,8 +1429,6 @@ CommData = *LocDataPtr; } - UnlockMutex (GraphicsLock); - if (GET_GAME_STATE (BATTLE_SEGUE) == 0) { // Not offered the chance to attack. @@ -1435,8 +1446,6 @@ SET_GAME_STATE (BATTLE_SEGUE, 1); } - LockMutex (GraphicsLock); - if (status == HAIL) { HailAlien (); @@ -1449,8 +1458,6 @@ (*CommData.uninit_encounter_func) (); // cleanup } - UnlockMutex (GraphicsLock); - status = 0; if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) { @@ -1625,7 +1632,7 @@ } } -void +static void RedrawSubtitles (void) { TEXT t; @@ -1633,38 +1640,20 @@ if (!optSubtitles) return; - LockMutex (subtitle_mutex); if (SubtitleText.pStr) { t = SubtitleText; add_text (1, &t); } - UnlockMutex (subtitle_mutex); } -// Returns clear_subtitles and resets it -BOOLEAN -HaveSubtitlesChanged (void) -{ - BOOLEAN ret; - - LockMutex (subtitle_mutex); - ret = clear_subtitles; - clear_subtitles = FALSE; - UnlockMutex (subtitle_mutex); - - return ret; -} - static void ClearSubtitles (void) { - LockMutex (subtitle_mutex); clear_subtitles = TRUE; last_subtitle = NULL; SubtitleText.pStr = NULL; SubtitleText.CharCount = 0; - UnlockMutex (subtitle_mutex); } static void @@ -1674,7 +1663,6 @@ pStr = GetTrackSubtitle (); - LockMutex (subtitle_mutex); if (pStr != SubtitleText.pStr) { // Subtitles changed clear_subtitles = TRUE; @@ -1688,7 +1676,6 @@ else SubtitleText.CharCount = 0; } - UnlockMutex (subtitle_mutex); } void Modified: trunk/sc2/src/uqm/comm.h =================================================================== --- trunk/sc2/src/uqm/comm.h 2009-11-25 21:43:48 UTC (rev 3354) +++ trunk/sc2/src/uqm/comm.h 2009-11-26 17:10:02 UTC (rev 3355) @@ -115,8 +115,6 @@ extern void AlienTalkSegue (COUNT wait_track); BOOLEAN getLineWithinWidth(TEXT *pText, const unsigned char **startNext, SIZE maxWidth, COUNT maxChars); -extern void RedrawSubtitles (void); -extern BOOLEAN HaveSubtitlesChanged (void); extern RECT CommWndRect; /* comm window rect */ Modified: trunk/sc2/src/uqm/commanim.c =================================================================== --- trunk/sc2/src/uqm/commanim.c 2009-11-25 21:43:48 UTC (rev 3354) +++ trunk/sc2/src/uqm/commanim.c 2009-11-26 17:10:02 UTC (rev 3355) @@ -27,23 +27,20 @@ #include "libs/mathlib.h" -// Maximum ambient animation frame rate (actual execution rate) -// A gfx frame is not always produced during an execution frame, -// and several animations are combined into one gfx frame. -// The rate was originally 120fps which allowed for more animation -// precision which is ultimately wasted on the human eye anyway. -// The highest known stable animation rate is 40fps, so that's what we use. -#define AMBIENT_ANIM_RATE 40 +static TimeCount LastTime; +static SEQUENCE Sequences[MAX_ANIMATIONS + 2]; + // 2 extra for Talk and Transition animations +static DWORD ActiveMask; + // Bit mask of all animations that are currently active. + // Bit 'i' is set if the animation with index 'i' is active. +static ANIMATION_DESC TalkDesc; +static ANIMATION_DESC TransitDesc; +static SEQUENCE* Talk; +static SEQUENCE* Transit; +static COUNT FirstAmbient; +static COUNT TotalSequences; -// Oscilloscope frame rate -// Should be <= AMBIENT_ANIM_RATE -// XXX: was 32 picked experimentally? -#define OSCILLOSCOPE_RATE 32 -static int ambient_anim_task (void *data); - -volatile BOOLEAN PauseAnimTask = FALSE; - static inline DWORD randomFrameRate (SEQUENCE *pSeq) { @@ -354,37 +351,11 @@ return done; } -static int -ambient_anim_task (void *data) +void +InitCommAnimations (void) { - COUNT i; - TimeCount LastTime; - SEQUENCE Sequences[MAX_ANIMATIONS + 2]; - // 2 extra for Talk and Transition animations - SEQUENCE *pSeq; - DWORD ActiveMask; - // Bit mask of all animations that are currently active. - // Bit 'i' is set if the animation with index 'i' is active. - DWORD LastOscillTime; - Task task = (Task) data; - BOOLEAN ColorChange = FALSE; - - ANIMATION_DESC TalkDesc; - ANIMATION_DESC TransitDesc; - SEQUENCE* Talk; - SEQUENCE* Transit; - COUNT FirstAmbient; - COUNT TotalSequences; - - while (!CommData.AlienFrame && !Task_ReadState (task, TASK_EXIT)) - TaskSwitch (); - ActiveMask = 0; - // Certain data must be accessed under GraphicsLock - LockMutex (GraphicsLock); - - memset (&DisplayArray[0], 0, sizeof (DisplayArray)); TalkDesc = CommData.AlienTalkDesc; TransitDesc = CommData.AlienTransitionDesc; @@ -403,41 +374,35 @@ SetupAmbientSequences (Sequences + FirstAmbient, CommData.NumAnimations); TotalSequences += CommData.NumAnimations; - UnlockMutex (GraphicsLock); - LastTime = GetTimeCounter (); - LastOscillTime = LastTime; +} - while (!Task_ReadState (task, TASK_EXIT)) +BOOLEAN +ProcessCommAnimations (BOOLEAN FullRedraw, BOOLEAN paused) +{ + if (paused) + { // Drive colormap xforms and nothing else + XFormColorMap_step (); + return FALSE; + } + else { - BOOLEAN CanTalk; + COUNT i; + SEQUENCE *pSeq; + BOOLEAN Change; + BOOLEAN CanTalk = TRUE; TimeCount CurTime; DWORD ElapsedTicks; DWORD NextActiveMask; - SleepThreadUntil (LastTime + ONE_SECOND / AMBIENT_ANIM_RATE); - - LockMutex (GraphicsLock); - BatchGraphics (); CurTime = GetTimeCounter (); ElapsedTicks = CurTime - LastTime; LastTime = CurTime; - if (PauseAnimTask) - { // anims not processed - i = CommData.NumAnimations; - CanTalk = FALSE; - } - else - { - i = 0; - CanTalk = TRUE; - } - // Process ambient animations NextActiveMask = ActiveMask; pSeq = Sequences + FirstAmbient; - for ( ; i < CommData.NumAnimations; ++i, ++pSeq) + for (i = 0; i < CommData.NumAnimations; ++i, ++pSeq) { ANIMATION_DESC *ADPtr = pSeq->ADPtr; DWORD ActiveBit = 1L << i; @@ -542,61 +507,55 @@ } } else - { // Not talking (task may be paused) - // Disable talking anim if it is done + { // Not talking -- disable talking anim if it is done if (Talk->Direction == NO_DIR) TalkDesc.AnimFlags |= ANIM_DISABLED; } + BatchGraphics (); + // Draw all animations - if (!PauseAnimTask) { - CONTEXT OldContext; - BOOLEAN SubtitleChange; - BOOLEAN FullRedraw; - BOOLEAN Change; + BOOLEAN ColorChange = XFormColorMap_step (); - // Clearing any active subtitles counts as 'change' - SubtitleChange = HaveSubtitlesChanged (); - FullRedraw = ColorChange || SubtitleChange; + if (ColorChange) + FullRedraw = TRUE; - OldContext = SetContext (TaskContext); - // Colormap animations are processed separately // from picture anims (see XFormColorMap_step) ProcessColormapAnims (Sequences + FirstAmbient, CommData.NumAnimations); Change = DrawAlienFrame (Sequences, TotalSequences, FullRedraw); - if (FullRedraw || Change) - RedrawSubtitles (); - - SetContext (OldContext); - - ColorChange = FALSE; + if (FullRedraw) + Change = TRUE; } - if (LastOscillTime + (ONE_SECOND / OSCILLOSCOPE_RATE) < CurTime) + UnbatchGraphics (); + + // Post-process ambient animations + pSeq = Sequences + FirstAmbient; + for (i = 0; i < CommData.NumAnimations; ++i, ++pSeq) { - LastOscillTime = CurTime; - UpdateSpeechGraphics (FALSE); + ANIMATION_DESC *ADPtr = pSeq->ADPtr; + DWORD ActiveBit = 1L << i; + + if (ADPtr->AnimFlags & ANIM_DISABLED) + continue; + + // We can only disable a one-shot anim here, otherwise the + // last frame will not be drawn + if ((ADPtr->AnimFlags & ONE_SHOT_ANIM) + && !(NextActiveMask & ActiveBit)) + { // One-shot animation, inactive next frame + ADPtr->AnimFlags |= ANIM_DISABLED; + } } - - UnbatchGraphics (); - UnlockMutex (GraphicsLock); - - ColorChange = XFormColorMap_step (); + + return Change; } - FinishTask (task); - return 0; } -Task -StartCommAnimTask (void) -{ - return AssignTask (ambient_anim_task, 3072, "ambient animations"); -} - BOOLEAN DrawAlienFrame (SEQUENCE *Sequences, COUNT Num, BOOLEAN fullRedraw) { Modified: trunk/sc2/src/uqm/commanim.h =================================================================== --- trunk/sc2/src/uqm/commanim.h 2009-11-25 21:43:48 UTC (rev 3354) +++ trunk/sc2/src/uqm/commanim.h 2009-11-26 17:10:02 UTC (rev 3355) @@ -19,7 +19,6 @@ #include "libs/compiler.h" #include "libs/gfxlib.h" -#include "libs/tasklib.h" // Some background: every animation has a neutral frame which returns // the image to the state it was in before the animation began. Which @@ -57,6 +56,10 @@ #define COLORXFORM_ANIM PAUSE_TALKING +#define ONE_SHOT_ANIM TALK_INTRO + // Set in AlienAmbientArray for animations that should be + // disabled after they run once. + typedef struct { COUNT StartIndex; @@ -124,12 +127,9 @@ // Returns TRUE if there was an animation change extern BOOLEAN DrawAlienFrame (SEQUENCE *pSeq, COUNT Num, BOOLEAN fullRedraw); +extern void InitCommAnimations (void); +extern BOOLEAN ProcessCommAnimations (BOOLEAN fullRedraw, BOOLEAN paused); -void UpdateSpeechGraphics (BOOLEAN Initialize); -Task StartCommAnimTask(void); - -extern volatile BOOLEAN PauseAnimTask; - #endif /* _COMMANIM_H */ Modified: trunk/sc2/src/uqm/oscill.c =================================================================== --- trunk/sc2/src/uqm/oscill.c 2009-11-25 21:43:48 UTC (rev 3354) +++ trunk/sc2/src/uqm/oscill.c 2009-11-26 17:10:02 UTC (rev 3355) @@ -84,16 +84,13 @@ // draws the oscilloscope void -Oscilloscope (DWORD grab_data) +DrawOscilloscope (void) { STAMP s; if (oscillDisabled) return; - if (!grab_data) - return; - TFB_DrawImage_Image (scope_bg, 0, 0, 0, NULL, scope_surf); if (GraphForegroundStream (scope_data, RADAR_WIDTH - 2, RADAR_HEIGHT - 2)) { @@ -150,7 +147,7 @@ } void -Slider (void) +DrawSlider (void) { int offs; static int last_offs = -1; Modified: trunk/sc2/src/uqm/oscill.h =================================================================== --- trunk/sc2/src/uqm/oscill.h 2009-11-25 21:43:48 UTC (rev 3354) +++ trunk/sc2/src/uqm/oscill.h 2009-11-26 17:10:02 UTC (rev 3355) @@ -25,13 +25,13 @@ extern void InitOscilloscope (DWORD x, DWORD y, DWORD width, DWORD height, FRAME f); -extern void Oscilloscope (DWORD grab_data); +extern void DrawOscilloscope (void); extern void UninitOscilloscope (void); extern void InitSlider (int x, int y, int width, int height, int bwidth, int bheight, FRAME f); extern void SetSliderImage (FRAME f); -void Slider (void); +void DrawSlider (void); #endif /* _OSCILL_H */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |