Changed SetFlashRect to use the new flash code.
This is an intermediate step towards getting rid of the flash thread altogether. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3722 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
Changes towards version 0.8:
|
Changes towards version 0.8:
|
||||||
|
- Changed SetFlashRect() to use the new flash code - SvdB
|
||||||
- Added Valgrind suppression file, from Louis Delacroix
|
- Added Valgrind suppression file, from Louis Delacroix
|
||||||
- Fix several memory leaks, from Loius Delacroix
|
- Fix several memory leaks, from Loius Delacroix
|
||||||
- Some cleanups / warnings fixes, from Louis Delacroix
|
- Some cleanups / warnings fixes, from Louis Delacroix
|
||||||
|
|||||||
+2
-9
@@ -28,9 +28,6 @@
|
|||||||
#include "libs/tasklib.h"
|
#include "libs/tasklib.h"
|
||||||
#include "libs/log.h"
|
#include "libs/log.h"
|
||||||
|
|
||||||
extern Task flash_task;
|
|
||||||
extern RECT flash_rect;
|
|
||||||
|
|
||||||
static BYTE GetEndMenuState (BYTE BaseState);
|
static BYTE GetEndMenuState (BYTE BaseState);
|
||||||
static BYTE GetBeginMenuState (BYTE BaseState);
|
static BYTE GetBeginMenuState (BYTE BaseState);
|
||||||
static BYTE FixMenuState (BYTE BadState);
|
static BYTE FixMenuState (BYTE BadState);
|
||||||
@@ -500,6 +497,7 @@ DrawMenuStateStrings (BYTE beg_index, SWORD NewState)
|
|||||||
if (NewState <= end_index - beg_index)
|
if (NewState <= end_index - beg_index)
|
||||||
s.frame = SetAbsFrameIndex (PlayFrame, beg_index + NewState);
|
s.frame = SetAbsFrameIndex (PlayFrame, beg_index + NewState);
|
||||||
|
|
||||||
|
PreUpdateRadarRect ();
|
||||||
LockMutex (GraphicsLock);
|
LockMutex (GraphicsLock);
|
||||||
OldContext = SetContext (StatusContext);
|
OldContext = SetContext (StatusContext);
|
||||||
GetContextClipRect (&r);
|
GetContextClipRect (&r);
|
||||||
@@ -600,13 +598,8 @@ DrawMenuStateStrings (BYTE beg_index, SWORD NewState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnbatchGraphics ();
|
UnbatchGraphics ();
|
||||||
if (flash_task
|
|
||||||
&& flash_rect.corner.x == RADAR_X
|
|
||||||
&& flash_rect.corner.y == RADAR_Y
|
|
||||||
&& flash_rect.extent.width == RADAR_WIDTH
|
|
||||||
&& flash_rect.extent.height == RADAR_HEIGHT)
|
|
||||||
SetFlashRect (SFR_MENU_3DO);
|
|
||||||
SetContext (OldContext);
|
SetContext (OldContext);
|
||||||
UnlockMutex (GraphicsLock);
|
UnlockMutex (GraphicsLock);
|
||||||
|
PostUpdateRadarRect ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+68
-197
@@ -31,6 +31,7 @@
|
|||||||
#include "element.h"
|
#include "element.h"
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "state.h"
|
#include "state.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/log.h"
|
#include "libs/log.h"
|
||||||
@@ -1589,248 +1590,118 @@ DrawAutoPilotMessage (BOOLEAN Reset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Task flash_task = 0;
|
static Task flash_task = 0;
|
||||||
RECT flash_rect;
|
static FlashContext *flashContext = NULL;
|
||||||
static FRAME flash_screen_frame = 0;
|
static RECT flash_rect;
|
||||||
// The original contents of the flash rectangle.
|
|
||||||
static int flash_changed;
|
|
||||||
Mutex flash_mutex = 0;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
flash_rect_func (void *data)
|
flash_rect_func (void *data)
|
||||||
{
|
{
|
||||||
#define NORMAL_STRENGTH 4
|
|
||||||
#define NORMAL_F_STRENGTH 0
|
|
||||||
#define CACHE_SIZE 10
|
|
||||||
DWORD TimeIn;
|
|
||||||
const DWORD WaitTime = ONE_SECOND / 16;
|
|
||||||
SIZE strength;
|
|
||||||
RECT cached_rect = {{0, 0}, {0, 0}};
|
|
||||||
FRAME cached_screen_frame = 0;
|
|
||||||
Task task = (Task)data;
|
Task task = (Task)data;
|
||||||
bool cached[CACHE_SIZE];
|
|
||||||
STAMP cached_stamp[CACHE_SIZE];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Init cache
|
|
||||||
for (i = 0; i < CACHE_SIZE; i++)
|
|
||||||
{
|
|
||||||
cached[i] = false;
|
|
||||||
cached_stamp[i].frame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
strength = NORMAL_STRENGTH;
|
|
||||||
TimeIn = GetTimeCounter ();
|
|
||||||
while (!Task_ReadState(task, TASK_EXIT))
|
while (!Task_ReadState(task, TASK_EXIT))
|
||||||
{
|
{
|
||||||
CONTEXT OldContext;
|
Flash_process (flashContext);
|
||||||
|
TimeCount nextTime = Flash_nextTime (flashContext);
|
||||||
LockMutex (flash_mutex);
|
SleepThreadUntil (nextTime);
|
||||||
if (flash_changed)
|
|
||||||
{
|
|
||||||
cached_rect = flash_rect;
|
|
||||||
if (cached_screen_frame)
|
|
||||||
DestroyDrawable (ReleaseDrawable (cached_screen_frame));
|
|
||||||
flash_changed = 0;
|
|
||||||
// Wait for the flash_screen_frame to get initialized
|
|
||||||
FlushGraphics ();
|
|
||||||
cached_screen_frame = CaptureDrawable (
|
|
||||||
CloneFrame (flash_screen_frame));
|
|
||||||
UnlockMutex (flash_mutex);
|
|
||||||
|
|
||||||
// Clear the cache.
|
|
||||||
for (i = 0; i < CACHE_SIZE; i++)
|
|
||||||
{
|
|
||||||
cached[i] = false;
|
|
||||||
if (cached_stamp[i].frame)
|
|
||||||
DestroyDrawable (ReleaseDrawable (cached_stamp[i].frame));
|
|
||||||
cached_stamp[i].frame = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
UnlockMutex (flash_mutex);
|
|
||||||
|
|
||||||
if (cached_rect.extent.width)
|
|
||||||
{
|
|
||||||
STAMP *pStamp;
|
|
||||||
|
|
||||||
#define MIN_STRENGTH 4
|
|
||||||
#define MAX_STRENGTH 6
|
|
||||||
strength += 2;
|
|
||||||
if (strength > MAX_STRENGTH)
|
|
||||||
strength = MIN_STRENGTH;
|
|
||||||
if (cached[strength - MIN_STRENGTH])
|
|
||||||
pStamp = &cached_stamp[strength - MIN_STRENGTH];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pStamp = &cached_stamp[strength - MIN_STRENGTH];
|
|
||||||
cached[strength - MIN_STRENGTH] = true;
|
|
||||||
pStamp->frame = CaptureDrawable (
|
|
||||||
CloneFrame (cached_screen_frame));
|
|
||||||
pStamp->origin.x = 0;
|
|
||||||
pStamp->origin.y = 0;
|
|
||||||
|
|
||||||
if (strength != 4)
|
|
||||||
{ // brighten the frame with an additive
|
|
||||||
DrawMode oldMode;
|
|
||||||
STAMP s;
|
|
||||||
int factor;
|
|
||||||
|
|
||||||
s.origin.x = 0;
|
|
||||||
s.origin.y = 0;
|
|
||||||
s.frame = cached_screen_frame;
|
|
||||||
|
|
||||||
factor = (strength - MIN_STRENGTH) * DRAW_FACTOR_1 / 4;
|
|
||||||
|
|
||||||
LockMutex (GraphicsLock);
|
|
||||||
OldContext = SetContext (OffScreenContext);
|
|
||||||
SetContextFGFrame (pStamp->frame);
|
|
||||||
SetContextClipRect (NULL);
|
|
||||||
oldMode = SetContextDrawMode (MAKE_DRAW_MODE (
|
|
||||||
DRAW_ADDITIVE, factor));
|
|
||||||
DrawStamp (&s);
|
|
||||||
SetContextDrawMode (oldMode);
|
|
||||||
SetContext (OldContext);
|
|
||||||
UnlockMutex (GraphicsLock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LockMutex (GraphicsLock);
|
|
||||||
OldContext = SetContext (ScreenContext);
|
|
||||||
SetContextClipRect (&cached_rect);
|
|
||||||
// flash changed_can't be modified while GraphicSem is held
|
|
||||||
if (!flash_changed)
|
|
||||||
DrawStamp (pStamp);
|
|
||||||
// XXX: Shouldn't we save and restore the original cliprect?
|
|
||||||
SetContextClipRect (NULL);
|
|
||||||
SetContext (OldContext);
|
|
||||||
UnlockMutex (GraphicsLock);
|
|
||||||
}
|
|
||||||
FlushGraphics ();
|
|
||||||
SleepThreadUntil (TimeIn + WaitTime);
|
|
||||||
TimeIn = GetTimeCounter ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear cache
|
|
||||||
{
|
|
||||||
if (cached_screen_frame)
|
|
||||||
DestroyDrawable (ReleaseDrawable (cached_screen_frame));
|
|
||||||
|
|
||||||
for (i = 0; i < CACHE_SIZE; i++)
|
|
||||||
{
|
|
||||||
if(cached_stamp[i].frame)
|
|
||||||
DestroyDrawable (ReleaseDrawable (cached_stamp[i].frame));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LockMutex (flash_mutex);
|
|
||||||
flash_task = 0;
|
|
||||||
UnlockMutex (flash_mutex);
|
|
||||||
|
|
||||||
FinishTask (task);
|
FinishTask (task);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pre: the caller holds the GraphicsLock
|
||||||
void
|
void
|
||||||
SetFlashRect (RECT *pRect)
|
SetFlashRect (RECT *pRect)
|
||||||
{
|
{
|
||||||
RECT clip_r = {{0, 0}, {0, 0}};
|
RECT clip_r = {{0, 0}, {0, 0}};
|
||||||
RECT temp_r, flash_rect1, old_r;
|
RECT temp_r;
|
||||||
CONTEXT OldContext;
|
|
||||||
int create_flash = 0;
|
|
||||||
|
|
||||||
if (!flash_mutex)
|
|
||||||
flash_mutex = CreateMutex ("FlashRect Lock",
|
|
||||||
SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
|
||||||
|
|
||||||
old_r = flash_rect;
|
|
||||||
flash_rect1 = flash_rect;
|
|
||||||
|
|
||||||
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).
|
||||||
GetContextClipRect (&clip_r);
|
GetContextClipRect (&clip_r);
|
||||||
OldContext = SetContext (ScreenContext);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Don't flash when using the PC menu
|
|
||||||
if (optWhichMenu == OPT_PC && pRect != SFR_MENU_ANY)
|
if (optWhichMenu == OPT_PC && pRect != SFR_MENU_ANY)
|
||||||
{
|
{
|
||||||
OldContext = SetContext (ScreenContext);
|
// The player wants PC menus and this flash is not used
|
||||||
|
// for a PC menu.
|
||||||
|
// Don't flash.
|
||||||
pRect = 0;
|
pRect = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OldContext = SetContext (StatusContext);
|
// The player wants 3DO menus, or the flash is used in both
|
||||||
|
// 3DO and PC mode.
|
||||||
|
CONTEXT OldContext = SetContext (StatusContext);
|
||||||
GetContextClipRect (&clip_r);
|
GetContextClipRect (&clip_r);
|
||||||
pRect = &temp_r;
|
pRect = &temp_r;
|
||||||
temp_r.corner.x = RADAR_X - clip_r.corner.x;
|
temp_r.corner.x = RADAR_X - clip_r.corner.x;
|
||||||
temp_r.corner.y = RADAR_Y - clip_r.corner.y;
|
temp_r.corner.y = RADAR_Y - clip_r.corner.y;
|
||||||
temp_r.extent.width = RADAR_WIDTH;
|
temp_r.extent.width = RADAR_WIDTH;
|
||||||
temp_r.extent.height = RADAR_HEIGHT;
|
temp_r.extent.height = RADAR_HEIGHT;
|
||||||
SetContext (ScreenContext);
|
SetContext (OldContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRect == 0 || pRect->extent.width == 0)
|
// Conclude an old flash task.
|
||||||
|
if (flashContext != NULL)
|
||||||
{
|
{
|
||||||
// End the flashing.
|
UnlockMutex (GraphicsLock);
|
||||||
flash_rect1.extent.width = 0;
|
ConcludeTask (flash_task);
|
||||||
if (flash_task)
|
LockMutex (GraphicsLock);
|
||||||
{
|
flash_task = 0;
|
||||||
UnlockMutex (GraphicsLock);
|
|
||||||
ConcludeTask (flash_task);
|
Flash_terminate (flashContext);
|
||||||
LockMutex (GraphicsLock);
|
flashContext = 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flash_rect1 = *pRect;
|
|
||||||
flash_rect1.corner.x += clip_r.corner.x;
|
|
||||||
flash_rect1.corner.y += clip_r.corner.y;
|
|
||||||
create_flash = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LockMutex (flash_mutex);
|
// Start a new flash task.
|
||||||
flash_rect = flash_rect1;
|
if (pRect != 0 && pRect->extent.width != 0)
|
||||||
|
|
||||||
if (old_r.extent.width && !rectsEqual (old_r, flash_rect))
|
|
||||||
{
|
{
|
||||||
// We had a flash rectangle, and now a different one is set.
|
flash_rect = *pRect;
|
||||||
if (flash_screen_frame)
|
flash_rect.corner.x += clip_r.corner.x;
|
||||||
{
|
flash_rect.corner.y += clip_r.corner.y;
|
||||||
// The screen contents may have changed; we grab a new copy.
|
|
||||||
STAMP old_s;
|
|
||||||
old_s.origin.x = old_r.corner.x;
|
|
||||||
old_s.origin.y = old_r.corner.y;
|
|
||||||
old_s.frame = flash_screen_frame;
|
|
||||||
DrawStamp (&old_s);
|
|
||||||
DestroyDrawable (ReleaseDrawable (flash_screen_frame));
|
|
||||||
flash_screen_frame = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
log_add (log_Debug, "Couldn't locate flash_screen_rect");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flash_rect.extent.width)
|
flashContext = Flash_createHighlight (ScreenContext, &flash_rect);
|
||||||
{
|
Flash_setMergeFactors(flashContext, 3, 2, 2);
|
||||||
// A new flash rectangle is set.
|
Flash_setSpeed (flashContext, 0, ONE_SECOND / 16, 0, ONE_SECOND / 16);
|
||||||
// Copy the original contents of the rectangle from the screen.
|
Flash_setFrameTime (flashContext, ONE_SECOND / 16);
|
||||||
if (flash_screen_frame)
|
Flash_start (flashContext);
|
||||||
DestroyDrawable (ReleaseDrawable (flash_screen_frame));
|
|
||||||
flash_screen_frame =
|
|
||||||
CaptureDrawable (LoadDisplayPixmap (&flash_rect, (FRAME)0));
|
|
||||||
}
|
|
||||||
flash_changed = 1;
|
|
||||||
UnlockMutex (flash_mutex);
|
|
||||||
// we create the thread after the LoadDisplayPixmap()
|
|
||||||
// so there is no race between the FlushGraphics in flash_task
|
|
||||||
// and the Enqueue in LoadDisplayPixmap()
|
|
||||||
if (create_flash && flash_task == 0)
|
|
||||||
{
|
|
||||||
flash_task = AssignTask (flash_rect_func, 2048,
|
|
||||||
"flash rectangle");
|
|
||||||
}
|
|
||||||
|
|
||||||
SetContext (OldContext);
|
flash_task = AssignTask (flash_rect_func, 2048, "flash rectangle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PreUpdateRadarRect (void) {
|
||||||
|
// XXX: this check doesn't take the ContextClipRect into account,
|
||||||
|
// as the code above in SetFlashRect does. One is wrong.
|
||||||
|
// Note that this code came from menu.c originally.
|
||||||
|
if (flash_task
|
||||||
|
&& flash_rect.corner.x == RADAR_X
|
||||||
|
&& flash_rect.corner.y == RADAR_Y
|
||||||
|
&& flash_rect.extent.width == RADAR_WIDTH
|
||||||
|
&& flash_rect.extent.height == RADAR_HEIGHT)
|
||||||
|
{
|
||||||
|
Flash_preUpdate(flashContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PostUpdateRadarRect (void) {
|
||||||
|
// XXX: this check doesn't take the ContextClipRect into account,
|
||||||
|
// as the code above in SetFlashRect does. One is wrong.
|
||||||
|
// Note that this code came from menu.c originally.
|
||||||
|
if (flash_task
|
||||||
|
&& flash_rect.corner.x == RADAR_X
|
||||||
|
&& flash_rect.corner.y == RADAR_Y
|
||||||
|
&& flash_rect.extent.width == RADAR_WIDTH
|
||||||
|
&& flash_rect.extent.height == RADAR_HEIGHT)
|
||||||
|
{
|
||||||
|
Flash_postUpdate(flashContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,8 @@ extern void InitSISContexts (void);
|
|||||||
extern void DrawSISFrame (void);
|
extern void DrawSISFrame (void);
|
||||||
extern void ClearSISRect (BYTE ClearFlags);
|
extern void ClearSISRect (BYTE ClearFlags);
|
||||||
extern void SetFlashRect (RECT *pRect);
|
extern void SetFlashRect (RECT *pRect);
|
||||||
|
extern void PreUpdateRadarRect (void);
|
||||||
|
extern void PostUpdateRadarRect (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);
|
||||||
|
|||||||
Reference in New Issue
Block a user