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:
+2
-1
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "callback/async.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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 */
|
||||||
|
|
||||||
@@ -170,4 +170,14 @@ Callback_process(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Callback_haveMore(void) {
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
CallbackList_lock();
|
||||||
|
result = (callbacks != NULL);
|
||||||
|
CallbackList_unlock();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 ();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 ();
|
||||||
|
|||||||
+67
-56
@@ -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)
|
|
||||||
{
|
|
||||||
Task task = (Task)data;
|
|
||||||
|
|
||||||
while (!Task_ReadState(task, TASK_EXIT))
|
static void
|
||||||
|
updateFlashRect (void *arg)
|
||||||
{
|
{
|
||||||
TimeCount nextTime;
|
if (flashContext == NULL)
|
||||||
LockMutex (flash_mutex);
|
return;
|
||||||
|
|
||||||
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
|
||||||
|
{
|
||||||
|
// Reuse an existing flash context
|
||||||
|
Flash_setRect (flashContext, &flash_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Flash rectangle is empty. Stop flashing.
|
||||||
|
if (flashContext != NULL)
|
||||||
|
{
|
||||||
|
UnlockMutex (GraphicsLock);
|
||||||
|
Alarm_remove(flashAlarm);
|
||||||
|
LockMutex (GraphicsLock);
|
||||||
|
flashAlarm = 0;
|
||||||
|
|
||||||
// Sleep while calling the flash rectangle update when necessary.
|
Flash_terminate (flashContext);
|
||||||
void
|
flashContext = NULL;
|
||||||
FlashRectSleepUntil (TimeCount wakeTime)
|
}
|
||||||
{
|
|
||||||
while (GetTimeCounter() < wakeTime)
|
|
||||||
{
|
|
||||||
TimeCount flashNextTime = Flash_nextTime (flashContext);
|
|
||||||
TimeCount nextTime = (flashNextTime < wakeTime) ?
|
|
||||||
flashNextTime : wakeTime;
|
|
||||||
SleepThreadUntil (nextTime);
|
|
||||||
if (nextTime == flashNextTime)
|
|
||||||
Flash_process (flashContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user