Annihigate flash thread.

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3750 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
Meep-Eep
2012-01-27 23:29:03 +00:00
parent 20e2ea337f
commit d8d201ee54
23 changed files with 359 additions and 96 deletions
+2 -1
View File
@@ -1,5 +1,6 @@
Changes towards version 0.8: Changes towards version 0.8:
- Switch SetFlashRect() to the new flash code -- SvdB - Annihigate flash thread - SvdB
- Switch SetFlashRect() to the new flash code - SvdB
- Add C++ support to the build system, from Scott A. Colcord - Add C++ support to the build system, from Scott A. Colcord
- Cleaning up DoModifyShips() - SvdB - Cleaning up DoModifyShips() - SvdB
- Added Valgrind suppression file, from Louis Delacroix - Added Valgrind suppression file, from Louis Delacroix
+12
View File
@@ -215,6 +215,14 @@ SOURCE=..\..\src\libs\callback\alarm.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\src\libs\callback\async.c
# End Source File
# Begin Source File
SOURCE=..\..\src\libs\callback\async.h
# End Source File
# Begin Source File
SOURCE=..\..\src\libs\callback\callback.c SOURCE=..\..\src\libs\callback\callback.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@@ -1470,6 +1478,10 @@ SOURCE=..\..\src\libs\alarm.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\src\libs\async.h
# End Source File
# Begin Source File
SOURCE=..\..\src\libs\callback.h SOURCE=..\..\src\libs\callback.h
# End Source File # End Source File
# Begin Source File # Begin Source File
+4 -4
View File
@@ -12,8 +12,8 @@ fi
# uqm_SUBDIRS="$UQM_SUBDIRS debug" # uqm_SUBDIRS="$UQM_SUBDIRS debug"
#fi #fi
uqm_HFILES="alarm.h callback.h cdplib.h compiler.h declib.h file.h gfxlib.h uqm_HFILES="alarm.h async.h callback.h cdplib.h compiler.h declib.h file.h
heap.h inplib.h list.h log.h mathlib.h md5.h memlib.h misc.h net.h gfxlib.h heap.h inplib.h list.h log.h mathlib.h md5.h memlib.h
platform.h reslib.h sndlib.h strlib.h tasklib.h threadlib.h misc.h net.h platform.h reslib.h sndlib.h strlib.h tasklib.h
timelib.h uio.h uioutils.h unicode.h vidlib.h" threadlib.h timelib.h uio.h uioutils.h unicode.h vidlib.h"
+10
View File
@@ -0,0 +1,10 @@
#if defined(__cplusplus)
extern "C" {
#endif
#include "callback/async.h"
#if defined(__cplusplus)
}
#endif
+2 -2
View File
@@ -1,2 +1,2 @@
uqm_CFILES="alarm.c callback.c" uqm_CFILES="alarm.c async.c callback.c"
uqm_HFILES="alarm.h callback.h" uqm_HFILES="alarm.h async.h callback.h"
+50 -7
View File
@@ -18,6 +18,7 @@
#include "alarm.h" #include "alarm.h"
#include SDL_INCLUDE(SDL.h)
#include "libs/heap.h" #include "libs/heap.h"
#include <assert.h> #include <assert.h>
@@ -71,19 +72,36 @@ Alarm_uninit(void) {
} }
static inline AlarmTime static inline AlarmTime
AlarmTime_nowMS(void) { AlarmTime_nowMs(void) {
return SDL_GetTicks(); return SDL_GetTicks();
} }
Alarm * Alarm *
Alarm_addRelativeMs(Uint32 ms, AlarmCallback callback, Alarm_addAbsoluteMs(uint32 ms, AlarmCallback callback,
AlarmCallbackArg arg) { AlarmCallbackArg arg) {
Alarm *alarm; Alarm *alarm;
assert(alarmHeap != NULL); assert(alarmHeap != NULL);
alarm = Alarm_alloc(); alarm = Alarm_alloc();
alarm->time = AlarmTime_nowMS() + ms; alarm->time = ms;
alarm->callback = callback;
alarm->arg = arg;
Heap_add(alarmHeap, (HeapValue *) alarm);
return alarm;
}
Alarm *
Alarm_addRelativeMs(uint32 ms, AlarmCallback callback,
AlarmCallbackArg arg) {
Alarm *alarm;
assert(alarmHeap != NULL);
alarm = Alarm_alloc();
alarm->time = AlarmTime_nowMs() + ms;
alarm->callback = callback; alarm->callback = callback;
alarm->arg = arg; alarm->arg = arg;
@@ -99,15 +117,40 @@ Alarm_remove(Alarm *alarm) {
Alarm_free(alarm); Alarm_free(alarm);
} }
// Process at most one alarm, if its time has come.
// It is safe to call this function again from inside a callback function
// that it called. It should not be called from multiple threads at once.
bool
Alarm_processOne(void)
{
AlarmTime now;
Alarm *alarm;
assert(alarmHeap != NULL);
if (!Heap_hasMore(alarmHeap))
return false;
now = AlarmTime_nowMs();
alarm = (Alarm *) Heap_first(alarmHeap);
if (now < alarm->time)
return false;
Heap_pop(alarmHeap);
alarm->callback(alarm->arg);
Alarm_free(alarm);
return true;
}
#if 0
// It is safe to call this function again from inside a callback function // It is safe to call this function again from inside a callback function
// that it called. It should not be called from multiple threads at once. // that it called. It should not be called from multiple threads at once.
void void
Alarm_process(void) { Alarm_processAll(void) {
AlarmTime now; AlarmTime now;
assert(alarmHeap != NULL); assert(alarmHeap != NULL);
now = AlarmTime_nowMS(); now = AlarmTime_nowMs();
while (Heap_hasMore(alarmHeap)) { while (Heap_hasMore(alarmHeap)) {
Alarm *alarm = (Alarm *) Heap_first(alarmHeap); Alarm *alarm = (Alarm *) Heap_first(alarmHeap);
@@ -119,8 +162,9 @@ Alarm_process(void) {
Alarm_free(alarm); Alarm_free(alarm);
} }
} }
#endif
Uint32 uint32
Alarm_timeBeforeNextMs(void) { Alarm_timeBeforeNextMs(void) {
Alarm *alarm; Alarm *alarm;
@@ -131,4 +175,3 @@ Alarm_timeBeforeNextMs(void) {
return alarmTimeToMsUint32(alarm->time); return alarmTimeToMsUint32(alarm->time);
} }
+9 -7
View File
@@ -22,11 +22,10 @@
#include "port.h" #include "port.h"
#include "types.h" #include "types.h"
#include SDL_INCLUDE(SDL.h) typedef uint32 AlarmTime;
typedef Uint32 AlarmTime; static inline uint32
static inline Uint32
alarmTimeToMsUint32(AlarmTime time) { alarmTimeToMsUint32(AlarmTime time) {
return (Uint32) time; return (uint32) time;
} }
typedef struct Alarm Alarm; typedef struct Alarm Alarm;
@@ -44,11 +43,14 @@ struct Alarm {
void Alarm_init(void); void Alarm_init(void);
void Alarm_uninit(void); void Alarm_uninit(void);
Alarm *Alarm_addRelativeMs(Uint32 ms, AlarmCallback callback, Alarm *Alarm_addAbsoluteMs(uint32 ms, AlarmCallback callback,
AlarmCallbackArg arg);
Alarm *Alarm_addRelativeMs(uint32 ms, AlarmCallback callback,
AlarmCallbackArg arg); AlarmCallbackArg arg);
void Alarm_remove(Alarm *alarm); void Alarm_remove(Alarm *alarm);
void Alarm_process(void); bool Alarm_processOne(void);
Uint32 Alarm_timeBeforeNextMs(void); void Alarm_processAll(void);
uint32 Alarm_timeBeforeNextMs(void);
#endif /* _ALARM_H */ #endif /* _ALARM_H */
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright 2012 Serge van den Boom <svdb@stack.nl>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "async.h"
#include "libs/alarm.h"
#include "libs/callback.h"
// Process all alarms and callbacks.
// First, all scheduled callbacks are called.
// Then each alarm due is called, and after each of these alarms, the
// callbacks scheduled by this alarm are called.
void
Async_process(void)
{
// Call pending callbacks.
Callback_process();
for (;;) {
if (!Alarm_processOne())
return;
// Call callbacks scheduled from the last alarm.
Callback_process();
}
}
// Returns the next time that some asynchronous callback is
// to be called. Note that all values lower than the current time
// should be considered as 'somewhere in the past'.
uint32
Async_timeBeforeNextMs(void) {
if (Callback_haveMore()) {
// Any time before the current time is ok, though we reserve 0 so
// that the caller may use it as a special value in its own code.
return 1;
}
return Alarm_timeBeforeNextMs();
}
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright 2012 Serge van den Boom <svdb@stack.nl>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _ASYNC_H
#define _ASYNC_H
#include "types.h"
void Async_process(void);
uint32 Async_timeBeforeNextMs(void);
#endif /* _ASYNC_H */
+10
View File
@@ -170,4 +170,14 @@ Callback_process(void) {
} }
} }
bool
Callback_haveMore(void) {
bool result;
CallbackList_lock();
result = (callbacks != NULL);
CallbackList_unlock();
return result;
}
+1
View File
@@ -36,6 +36,7 @@ void Callback_init(void);
CallbackID Callback_add(CallbackFunction callback, CallbackArg arg); CallbackID Callback_add(CallbackFunction callback, CallbackArg arg);
bool Callback_remove(CallbackID id); bool Callback_remove(CallbackID id);
void Callback_process(void); void Callback_process(void);
bool Callback_haveMore(void);
#endif /* _CALLBACK_H */ #endif /* _CALLBACK_H */
@@ -211,7 +211,7 @@ PlaybackTaskFunc (void *data)
mixer_MixFake (NULL, stream, len); mixer_MixFake (NULL, stream, len);
delay = period - (GetTimeCounter () - entryTime); delay = period - (GetTimeCounter () - entryTime);
if (delay > 0) if (delay > 0)
SleepThread (delay); HibernateThread (delay);
} }
HFree (stream); HFree (stream);
+1 -1
View File
@@ -568,7 +568,7 @@ StreamDecoderTaskFunc (void *data)
if (active_streams == 0) if (active_streams == 0)
{ // Throttle down the thread when there are no active streams { // Throttle down the thread when there are no active streams
SleepThread (ONE_SECOND / 10); HibernateThread (ONE_SECOND / 10);
} }
else else
TaskSwitch (); TaskSwitch ();
+2
View File
@@ -145,6 +145,8 @@ ThreadLocal *CreateThreadLocal (void);
void DestroyThreadLocal (ThreadLocal *tl); void DestroyThreadLocal (ThreadLocal *tl);
ThreadLocal *GetMyThreadLocal (void); ThreadLocal *GetMyThreadLocal (void);
void HibernateThread (TimePeriod timePeriod);
void HibernateThreadUntil (TimeCount wakeTime);
void SleepThread (TimePeriod timePeriod); void SleepThread (TimePeriod timePeriod);
void SleepThreadUntil (TimeCount wakeTime); void SleepThreadUntil (TimeCount wakeTime);
void DestroyThread (Thread); void DestroyThread (Thread);
+66 -2
View File
@@ -19,6 +19,7 @@
#include "libs/threadlib.h" #include "libs/threadlib.h"
#include "libs/timelib.h" #include "libs/timelib.h"
#include "libs/log.h" #include "libs/log.h"
#include "libs/async.h"
#include "libs/memlib.h" #include "libs/memlib.h"
#include "thrcommon.h" #include "thrcommon.h"
@@ -284,16 +285,79 @@ WaitThread (Thread thread, int *status)
NativeWaitThread (thread, status); NativeWaitThread (thread, status);
} }
#ifdef DEBUG_SLEEP
extern uint32 mainThreadId;
extern uint32 SDL_ThreadID(void);
#endif /* DEBUG_SLEEP */
void void
SleepThread (TimePeriod timePeriod) HibernateThread (TimePeriod timePeriod)
{ {
#ifdef DEBUG_SLEEP
if (SDL_ThreadID() == mainThreadId)
log_add (log_Debug, "HibernateThread called from main thread.\n");
#endif /* DEBUG_SLEEP */
NativeSleepThread (timePeriod); NativeSleepThread (timePeriod);
} }
void
HibernateThreadUntil (TimeCount wakeTime)
{
#ifdef DEBUG_SLEEP
if (SDL_ThreadID() == mainThreadId)
log_add (log_Debug, "HibernateThreadUntil called from main "
"thread.\n");
#endif /* DEBUG_SLEEP */
NativeSleepThreadUntil (wakeTime);
}
void
SleepThread (TimePeriod timePeriod)
{
TimeCount now;
#ifdef DEBUG_SLEEP
if (SDL_ThreadID() != mainThreadId)
log_add (log_Debug, "SleepThread called from non-main "
"thread.\n");
#endif /* DEBUG_SLEEP */
now = GetTimeCounter ();
SleepThreadUntil (now + timePeriod);
}
// Sleep until wakeTime, but call asynchrounous operations until then.
void void
SleepThreadUntil (TimeCount wakeTime) SleepThreadUntil (TimeCount wakeTime)
{ {
NativeSleepThreadUntil (wakeTime); #ifdef DEBUG_SLEEP
if (SDL_ThreadID() != mainThreadId)
log_add (log_Debug, "SleepThreadUntil called from non-main "
"thread.\n");
#endif /* DEBUG_SLEEP */
for (;;) {
uint32 nextTimeMs;
TimeCount nextTime;
TimeCount now;
Async_process ();
now = GetTimeCounter ();
if (wakeTime <= now)
return;
nextTimeMs = Async_timeBeforeNextMs ();
nextTime = (nextTimeMs / 1000) * ONE_SECOND +
((nextTimeMs % 1000) * ONE_SECOND / 1000);
// Overflow-safe conversion.
if (wakeTime < nextTime)
nextTime = wakeTime;
NativeSleepThreadUntil (nextTime);
}
} }
void void
+2
View File
@@ -40,6 +40,7 @@
#include "setup.h" #include "setup.h"
#include "settings.h" #include "settings.h"
#include "sounds.h" #include "sounds.h"
#include "libs/async.h"
#include "libs/graphics/gfx_common.h" #include "libs/graphics/gfx_common.h"
#include "libs/log.h" #include "libs/log.h"
#include "libs/mathlib.h" #include "libs/mathlib.h"
@@ -334,6 +335,7 @@ DoBattle (BATTLE_STATE *bs)
battle_speed = HIBYTE (nth_frame); battle_speed = HIBYTE (nth_frame);
if (battle_speed == (BYTE)~0) if (battle_speed == (BYTE)~0)
{ // maximum speed, nothing rendered at all { // maximum speed, nothing rendered at all
Async_process ();
TaskSwitch (); TaskSwitch ();
} }
else else
+7
View File
@@ -83,6 +83,8 @@ DoConfirmExit (void)
if (PlayingTrack ()) if (PlayingTrack ())
PauseTrack (); PauseTrack ();
PauseFlash ();
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
{ {
RECT r; RECT r;
@@ -160,6 +162,8 @@ DoConfirmExit (void)
} }
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
ContinueFlash ();
if (PlayingTrack ()) if (PlayingTrack ())
ResumeTrack (); ResumeTrack ();
@@ -212,6 +216,7 @@ DoPopupWindow (const char *msg)
label.line_count = SplitString (msg, '\n', 30, lines, bank); label.line_count = SplitString (msg, '\n', 30, lines, bank);
label.lines = lines; label.lines = lines;
PauseFlash ();
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
oldContext = SetContext (ScreenContext); oldContext = SetContext (ScreenContext);
@@ -242,6 +247,8 @@ DoPopupWindow (const char *msg)
SetContextClipRect (&oldRect); SetContextClipRect (&oldRect);
SetContext (oldContext); SetContext (oldContext);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
ContinueFlash ();
SetMenuSounds (s0, s1); SetMenuSounds (s0, s1);
StringBank_Free (bank); StringBank_Free (bank);
} }
+2
View File
@@ -28,6 +28,7 @@
#include "sounds.h" #include "sounds.h"
#include "tactrans.h" #include "tactrans.h"
#include "uqmdebug.h" #include "uqmdebug.h"
#include "libs/async.h"
#include "libs/inplib.h" #include "libs/inplib.h"
#include "libs/timelib.h" #include "libs/timelib.h"
#include "libs/threadlib.h" #include "libs/threadlib.h"
@@ -359,6 +360,7 @@ DoInput (void *pInputState, BOOLEAN resetInput)
do do
{ {
MENU_SOUND_FLAGS soundFlags; MENU_SOUND_FLAGS soundFlags;
Async_process ();
TaskSwitch (); TaskSwitch ();
UpdateInputState (); UpdateInputState ();
+69 -58
View File
@@ -34,6 +34,7 @@
#include "flash.h" #include "flash.h"
#include "libs/graphics/gfx_common.h" #include "libs/graphics/gfx_common.h"
#include "libs/tasklib.h" #include "libs/tasklib.h"
#include "libs/alarm.h"
#include "libs/log.h" #include "libs/log.h"
#include <stdio.h> #include <stdio.h>
@@ -1590,28 +1591,32 @@ DrawAutoPilotMessage (BOOLEAN Reset)
} }
static Task flash_task = 0;
static FlashContext *flashContext = NULL; static FlashContext *flashContext = NULL;
static RECT flash_rect; static RECT flash_rect;
static Mutex flash_mutex = 0; static Alarm *flashAlarm = NULL;
static BOOLEAN flashPaused = FALSE;
static int static void scheduleFlashAlarm (void);
flash_rect_func (void *data)
static void
updateFlashRect (void *arg)
{ {
Task task = (Task)data; if (flashContext == NULL)
return;
while (!Task_ReadState(task, TASK_EXIT))
{
TimeCount nextTime;
LockMutex (flash_mutex);
Flash_process (flashContext); Flash_process (flashContext);
nextTime = Flash_nextTime (flashContext); scheduleFlashAlarm ();
UnlockMutex (flash_mutex); (void) arg;
SleepThreadUntil (nextTime); }
}
FinishTask (task); static void
return 0; scheduleFlashAlarm (void)
{
TimeCount nextTime = Flash_nextTime (flashContext);
DWORD nextTimeMs = (nextTime / ONE_SECOND) * 1000 +
((nextTime % ONE_SECOND) * 1000 / ONE_SECOND);
// Overflow-safe conversion.
flashAlarm = Alarm_addAbsoluteMs (nextTimeMs, updateFlashRect, NULL);
} }
// Pre: the caller holds the GraphicsLock // Pre: the caller holds the GraphicsLock
@@ -1621,10 +1626,6 @@ SetFlashRect (const RECT *pRect)
RECT clip_r = {{0, 0}, {0, 0}}; RECT clip_r = {{0, 0}, {0, 0}};
RECT temp_r; RECT temp_r;
if (!flash_mutex)
flash_mutex = CreateMutex ("FlashRect Lock",
SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
if (pRect != SFR_MENU_3DO && pRect != SFR_MENU_ANY) if (pRect != SFR_MENU_3DO && pRect != SFR_MENU_ANY)
{ {
// The caller specified their own flash area, or NULL (stop flashing). // The caller specified their own flash area, or NULL (stop flashing).
@@ -1654,47 +1655,42 @@ SetFlashRect (const RECT *pRect)
} }
} }
// Conclude an old flash task.
if (flashContext != NULL)
{
UnlockMutex (GraphicsLock);
ConcludeTask (flash_task);
LockMutex (GraphicsLock);
flash_task = 0;
Flash_terminate (flashContext);
flashContext = 0;
}
// Start a new flash task.
if (pRect != 0 && pRect->extent.width != 0) if (pRect != 0 && pRect->extent.width != 0)
{ {
// Flash rectangle is not empty, start or continue flashing.
flash_rect = *pRect; flash_rect = *pRect;
flash_rect.corner.x += clip_r.corner.x; flash_rect.corner.x += clip_r.corner.x;
flash_rect.corner.y += clip_r.corner.y; flash_rect.corner.y += clip_r.corner.y;
if (flashContext == NULL)
{
// Create a new flash context.
flashContext = Flash_createHighlight (ScreenContext, &flash_rect); flashContext = Flash_createHighlight (ScreenContext, &flash_rect);
Flash_setMergeFactors(flashContext, 3, 2, 2); Flash_setMergeFactors(flashContext, 3, 2, 2);
Flash_setSpeed (flashContext, 0, ONE_SECOND / 16, 0, ONE_SECOND / 16); Flash_setSpeed (flashContext, 0, ONE_SECOND / 16, 0, ONE_SECOND / 16);
Flash_setFrameTime (flashContext, ONE_SECOND / 16); Flash_setFrameTime (flashContext, ONE_SECOND / 16);
Flash_start (flashContext); Flash_start (flashContext);
scheduleFlashAlarm ();
flash_task = AssignTask (flash_rect_func, 2048, "flash rectangle");
} }
} else
// Sleep while calling the flash rectangle update when necessary.
void
FlashRectSleepUntil (TimeCount wakeTime)
{
while (GetTimeCounter() < wakeTime)
{ {
TimeCount flashNextTime = Flash_nextTime (flashContext); // Reuse an existing flash context
TimeCount nextTime = (flashNextTime < wakeTime) ? Flash_setRect (flashContext, &flash_rect);
flashNextTime : wakeTime; }
SleepThreadUntil (nextTime); }
if (nextTime == flashNextTime) else
Flash_process (flashContext); {
// Flash rectangle is empty. Stop flashing.
if (flashContext != NULL)
{
UnlockMutex (GraphicsLock);
Alarm_remove(flashAlarm);
LockMutex (GraphicsLock);
flashAlarm = 0;
Flash_terminate (flashContext);
flashContext = NULL;
}
} }
} }
@@ -1708,18 +1704,12 @@ COUNT updateFlashRectRecursion = 0;
void void
PreUpdateFlashRect (void) PreUpdateFlashRect (void)
{ {
if (flash_task) if (flashAlarm)
{ {
updateFlashRectRecursion++; updateFlashRectRecursion++;
if (updateFlashRectRecursion > 1) if (updateFlashRectRecursion > 1)
return; return;
LockMutex (flash_mutex);
Flash_pause (flashContext);
// We need to actually pause, as the flash update function
// is called from another thread.
Flash_preUpdate (flashContext); Flash_preUpdate (flashContext);
UnlockMutex (flash_mutex);
} }
} }
@@ -1727,16 +1717,13 @@ PreUpdateFlashRect (void)
void void
PostUpdateFlashRect (void) PostUpdateFlashRect (void)
{ {
if (flash_task) if (flashAlarm)
{ {
updateFlashRectRecursion--; updateFlashRectRecursion--;
if (updateFlashRectRecursion > 0) if (updateFlashRectRecursion > 0)
return; return;
LockMutex (flash_mutex);
Flash_postUpdate (flashContext); Flash_postUpdate (flashContext);
Flash_continue (flashContext);
UnlockMutex (flash_mutex);
} }
} }
@@ -1760,3 +1747,27 @@ PostUpdateFlashRectLocked (void)
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
} }
// Stop flashing if flashing is active.
void
PauseFlash (void)
{
if (flashContext != NULL)
{
Alarm_remove(flashAlarm);
flashAlarm = 0;
flashPaused = TRUE;
}
}
// Continue flashing after PauseFlash (), if flashing was active.
void
ContinueFlash (void)
{
if (flashPaused)
{
scheduleFlashAlarm ();
flashPaused = FALSE;
}
}
+3
View File
@@ -186,6 +186,9 @@ extern void PreUpdateFlashRect (void);
extern void PostUpdateFlashRect (void); extern void PostUpdateFlashRect (void);
extern void PreUpdateFlashRectLocked (void); extern void PreUpdateFlashRectLocked (void);
extern void PostUpdateFlashRectLocked (void); extern void PostUpdateFlashRectLocked (void);
extern void PauseFlash (void);
extern void ContinueFlash (void);
#define SFR_MENU_3DO ((RECT*)~0L) #define SFR_MENU_3DO ((RECT*)~0L)
#define SFR_MENU_ANY ((RECT*)~1L) #define SFR_MENU_ANY ((RECT*)~1L)
extern void DrawHyperCoords (POINT puniverse); extern void DrawHyperCoords (POINT puniverse);
+8
View File
@@ -50,6 +50,10 @@
#include "options.h" #include "options.h"
volatile int MainExited = FALSE; volatile int MainExited = FALSE;
#ifdef DEBUG_SLEEP
uint32 mainThreadId;
extern uint32 SDL_ThreadID(void);
#endif
// Open or close the periodically occuring QuasiSpace portal. // Open or close the periodically occuring QuasiSpace portal.
// It changes the appearant portal size when necessary. // It changes the appearant portal size when necessary.
@@ -143,6 +147,10 @@ extern int snddriver, soundflags;
int int
Starcon2Main (void *threadArg) Starcon2Main (void *threadArg)
{ {
#ifdef DEBUG_SLEEP
mainThreadId = SDL_ThreadID();
#endif
#if CREATE_JOURNAL #if CREATE_JOURNAL
{ {
int ac = argc; int ac = argc;
+6 -7
View File
@@ -17,7 +17,7 @@
*/ */
#include "netmelee.h" #include "netmelee.h"
#include "libs/alarm.h" #include "libs/async.h"
#include "libs/callback.h" #include "libs/callback.h"
#include "libs/log.h" #include "libs/log.h"
#include "libs/net.h" #include "libs/net.h"
@@ -146,8 +146,7 @@ netInputAux(uint32 timeoutMs) {
NetManager_process(&timeoutMs); NetManager_process(&timeoutMs);
// This may cause more packets to be queued, hence the // This may cause more packets to be queued, hence the
// flushPacketQueues(). // flushPacketQueues().
Alarm_process(); Async_process();
Callback_process();
flushPacketQueues(); flushPacketQueues();
// During the flush, a disconnect may be noticed, which triggers // During the flush, a disconnect may be noticed, which triggers
// another callback. It must be handled immediately, before // another callback. It must be handled immediately, before
@@ -166,11 +165,11 @@ netInput(void) {
void void
netInputBlocking(uint32 timeoutMs) { netInputBlocking(uint32 timeoutMs) {
uint32 nextAlarmMs; uint32 nextAsyncMs;
nextAlarmMs = Alarm_timeBeforeNextMs(); nextAsyncMs = Async_timeBeforeNextMs();
if (nextAlarmMs < timeoutMs) if (nextAsyncMs < timeoutMs)
timeoutMs = nextAlarmMs; timeoutMs = nextAsyncMs;
netInputAux(timeoutMs); netInputAux(timeoutMs);
} }
+2
View File
@@ -37,6 +37,7 @@
#include "../races.h" #include "../races.h"
#include "../setup.h" #include "../setup.h"
#include "../sounds.h" #include "../sounds.h"
#include "libs/async.h"
#include "libs/log.h" #include "libs/log.h"
#include "libs/mathlib.h" #include "libs/mathlib.h"
@@ -676,6 +677,7 @@ MeleeGameOver (void)
ButtonState = FALSE; ButtonState = FALSE;
} }
Async_process ();
TaskSwitch (); TaskSwitch ();
} while (!(GLOBAL (CurrentActivity) & CHECK_ABORT) && (!ButtonState } while (!(GLOBAL (CurrentActivity) & CHECK_ABORT) && (!ButtonState
&& (!(PlayerControl[0] & PlayerControl[1] & PSYTRON_CONTROL) && (!(PlayerControl[0] & PlayerControl[1] & PSYTRON_CONTROL)