Switch SetFlashRect() to the new flash code, as the next step towards getting rid of threads. Also some small cleanups.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3749 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
Changes towards version 0.8:
|
||||
- Switch SetFlashRect() to the new flash code -- SvdB
|
||||
- Add C++ support to the build system, from Scott A. Colcord
|
||||
- Cleaning up DoModifyShips() - SvdB
|
||||
- Added Valgrind suppression file, from Louis Delacroix
|
||||
- Fix several memory leaks, from Loius Delacroix
|
||||
|
||||
+10
-4
@@ -18,6 +18,12 @@
|
||||
// areas, drawing directly to the screen, using a cache, are
|
||||
// currently in use.
|
||||
|
||||
// NOTE:
|
||||
// - If you change the properties of the original CONTEXT, specifically the
|
||||
// dimensions and origin, you'll need to call Flash_preUpdate() before and
|
||||
// Flash_postUpdate() after that change. Note that this may change which
|
||||
// part of the screen is flashing.
|
||||
|
||||
// TODO:
|
||||
// - During a few frames during the sequence, the frame to be displayed
|
||||
// is equal to a frame which was supplied as a parameter to the flash
|
||||
@@ -472,7 +478,8 @@ Flash_setOverlay (FlashContext *context, const POINT *origin, FRAME overlay)
|
||||
}
|
||||
}
|
||||
|
||||
// Call before you update the graphics in the currently flashing area.
|
||||
// Call before you update the graphics in the currently flashing area,
|
||||
// or before you change the dimensions or origin of the graphics context.
|
||||
void
|
||||
Flash_preUpdate (FlashContext *context)
|
||||
{
|
||||
@@ -483,7 +490,8 @@ Flash_preUpdate (FlashContext *context)
|
||||
}
|
||||
}
|
||||
|
||||
// Call after you update the graphics in the currently flashing area.
|
||||
// Call after you update the graphics in the currently flashing area,
|
||||
// or after you change the dimensions or origin of the graphics context.
|
||||
void
|
||||
Flash_postUpdate (FlashContext *context)
|
||||
{
|
||||
@@ -803,5 +811,3 @@ Flash_drawCurrentFrame (FlashContext *context)
|
||||
Flash_drawCachedFrame (context, numer, denom);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+30
-13
@@ -176,6 +176,26 @@ FeedbackSetting (BYTE which_setting)
|
||||
#define DDSHS_EDIT 1
|
||||
#define DDSHS_BLOCKCUR 2
|
||||
|
||||
static const RECT captainNameRect = {
|
||||
/* .corner = */ {
|
||||
/* .x = */ 3,
|
||||
/* .y = */ 10
|
||||
}, /* .extent = */ {
|
||||
/* .width = */ SHIP_NAME_WIDTH - 2,
|
||||
/* .height = */ SHIP_NAME_HEIGHT
|
||||
}
|
||||
};
|
||||
static const RECT shipNameRect = {
|
||||
/* .corner = */ {
|
||||
/* .x = */ 2,
|
||||
/* .y = */ 20
|
||||
}, /* .extent = */ {
|
||||
/* .width = */ SHIP_NAME_WIDTH,
|
||||
/* .height = */ SHIP_NAME_HEIGHT
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
COUNT state)
|
||||
@@ -185,20 +205,11 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
Color BackGround, ForeGround;
|
||||
FONT Font;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
|
||||
{
|
||||
r.corner.x = 2;
|
||||
r.extent.width = SHIP_NAME_WIDTH;
|
||||
r.extent.height = SHIP_NAME_HEIGHT;
|
||||
|
||||
SetContext (StatusContext);
|
||||
if (nameCaptain)
|
||||
{ // Naming the captain
|
||||
Font = TinyFont;
|
||||
r.corner.y = 10;
|
||||
++r.corner.x;
|
||||
r.extent.width -= 2;
|
||||
r = captainNameRect;
|
||||
lf.baseline.x = r.corner.x + (r.extent.width >> 1) - 1;
|
||||
|
||||
BackGround = BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09);
|
||||
@@ -207,7 +218,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
else
|
||||
{ // Naming the flagship
|
||||
Font = StarConFont;
|
||||
r.corner.y = 20;
|
||||
r = shipNameRect;
|
||||
lf.baseline.x = r.corner.x + (r.extent.width >> 1);
|
||||
|
||||
BackGround = BUILD_COLOR (MAKE_RGB15 (0x0F, 0x00, 0x00), 0x2D);
|
||||
@@ -218,6 +229,8 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
lf.align = ALIGN_CENTER;
|
||||
}
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
SetContext (StatusContext);
|
||||
SetContextFont (Font);
|
||||
lf.pStr = Str;
|
||||
lf.CharCount = (COUNT)~0;
|
||||
@@ -245,6 +258,10 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
UnlockMutex (GraphicsLock);
|
||||
PreUpdateFlashRect ();
|
||||
LockMutex (GraphicsLock);
|
||||
|
||||
SetContextForeGroundColor (BackGround);
|
||||
DrawFilledRectangle (&r);
|
||||
|
||||
@@ -282,7 +299,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
SetContextForeGroundColor (ForeGround);
|
||||
font_DrawText (&lf);
|
||||
|
||||
SetFlashRect (&r);
|
||||
PostUpdateFlashRectLocked ();
|
||||
}
|
||||
|
||||
UnlockMutex (GraphicsLock);
|
||||
@@ -309,7 +326,7 @@ NameCaptainOrShip (bool nameCaptain)
|
||||
UNICODE *Setting;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
SetFlashRect (NULL);
|
||||
SetFlashRect (nameCaptain ? &captainNameRect : &shipNameRect);
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
DrawNameString (nameCaptain, buf, 0, DDSHS_EDIT);
|
||||
|
||||
+2
-9
@@ -28,9 +28,6 @@
|
||||
#include "libs/tasklib.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
extern Task flash_task;
|
||||
extern RECT flash_rect;
|
||||
|
||||
static BYTE GetEndMenuState (BYTE BaseState);
|
||||
static BYTE GetBeginMenuState (BYTE BaseState);
|
||||
static BYTE FixMenuState (BYTE BadState);
|
||||
@@ -500,6 +497,7 @@ DrawMenuStateStrings (BYTE beg_index, SWORD NewState)
|
||||
if (NewState <= end_index - beg_index)
|
||||
s.frame = SetAbsFrameIndex (PlayFrame, beg_index + NewState);
|
||||
|
||||
PreUpdateFlashRect ();
|
||||
LockMutex (GraphicsLock);
|
||||
OldContext = SetContext (StatusContext);
|
||||
GetContextClipRect (&r);
|
||||
@@ -600,13 +598,8 @@ DrawMenuStateStrings (BYTE beg_index, SWORD NewState)
|
||||
}
|
||||
}
|
||||
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);
|
||||
UnlockMutex (GraphicsLock);
|
||||
PostUpdateFlashRect ();
|
||||
}
|
||||
|
||||
|
||||
@@ -448,9 +448,9 @@ DoInstallModule (MENU_STATE *pMS)
|
||||
if (NewItem != pMS->CurState)
|
||||
{
|
||||
pMS->CurState = NewItem;
|
||||
PreUpdateFlashRect ();
|
||||
DrawModuleStrings (pMS, NewItem);
|
||||
// flash with PC menus too
|
||||
SetFlashRect (SFR_MENU_ANY);
|
||||
PostUpdateFlashRect ();
|
||||
}
|
||||
}
|
||||
else if (NewItem != pMS->delta_item || NewState != pMS->CurState)
|
||||
@@ -573,7 +573,9 @@ ChangeFuelQuantity (void)
|
||||
SetContextBackGroundColor (BLACK_COLOR));
|
||||
DrawFilledRectangle (&r);
|
||||
}
|
||||
PreUpdateFlashRect ();
|
||||
DeltaSISGauges (0, FUEL_TANK_SCALE, -GLOBAL (FuelCost));
|
||||
PostUpdateFlashRect ();
|
||||
SetContext (StatusContext);
|
||||
GetGaugeRect (&r, FALSE);
|
||||
SetFlashRect (&r);
|
||||
@@ -590,7 +592,9 @@ ChangeFuelQuantity (void)
|
||||
SetContext (SpaceContext);
|
||||
if (GLOBAL_SIS (FuelOnBoard))
|
||||
{
|
||||
PreUpdateFlashRect ();
|
||||
DeltaSISGauges (0, -FUEL_TANK_SCALE, GLOBAL (FuelCost));
|
||||
PostUpdateFlashRect ();
|
||||
if (GLOBAL_SIS (FuelOnBoard) % FUEL_VOLUME_PER_ROW == 0 &&
|
||||
GLOBAL_SIS (FuelOnBoard) >= FUEL_RESERVE)
|
||||
{
|
||||
|
||||
@@ -198,7 +198,9 @@ DeltaSupportCrew (ROSTER_STATE *rosterState, SIZE crew_delta)
|
||||
StarShipPtr->crew_level,
|
||||
TemplatePtr->crew_level);
|
||||
|
||||
PreUpdateFlashRect ();
|
||||
DrawStatusMessage (buf);
|
||||
PostUpdateFlashRect ();
|
||||
DeltaSISGauges (-crew_delta, 0, 0);
|
||||
if (crew_delta)
|
||||
{
|
||||
|
||||
+53
-24
@@ -219,8 +219,7 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem)
|
||||
r.corner = s.origin;
|
||||
r.extent.width = RADAR_WIDTH;
|
||||
r.extent.height = RADAR_HEIGHT;
|
||||
SetContextForeGroundColor (
|
||||
BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00));
|
||||
SetContextForeGroundColor (BLACK_COLOR);
|
||||
DrawFilledRectangle (&r);
|
||||
if (NewRaceItem != (BYTE)~0)
|
||||
{
|
||||
@@ -232,19 +231,22 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem)
|
||||
hStarShip = GetAvailableRaceFromIndex (NewRaceItem);
|
||||
NewRaceItem = GetIndexFromStarShip (&GLOBAL (avail_race_q),
|
||||
hStarShip);
|
||||
|
||||
// Draw the ship name, above the ship image.
|
||||
s.frame = SetAbsFrameIndex (pMS->ModuleFrame, 3 + NewRaceItem);
|
||||
// Ship name, above the ship image.
|
||||
DrawStamp (&s);
|
||||
|
||||
// Draw the ship image.
|
||||
FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip);
|
||||
s.frame = FleetPtr->melee_icon;
|
||||
// Ship image.
|
||||
UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip);
|
||||
|
||||
t.baseline.x = s.origin.x + RADAR_WIDTH - 2;
|
||||
t.baseline.y = s.origin.y + RADAR_HEIGHT - 2;
|
||||
s.origin.x += (RADAR_WIDTH >> 1);
|
||||
s.origin.y += (RADAR_HEIGHT >> 1);
|
||||
DrawStamp (&s);
|
||||
|
||||
// Print the ship cost.
|
||||
t.align = ALIGN_RIGHT;
|
||||
t.CharCount = (COUNT)~0;
|
||||
t.pStr = buf;
|
||||
@@ -257,8 +259,6 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem)
|
||||
UnbatchGraphics ();
|
||||
SetContext (OldContext);
|
||||
|
||||
// Flash the ship purchase menu even when optMenu == OPT_PC
|
||||
SetFlashRect (SFR_MENU_ANY);
|
||||
UnlockMutex (GraphicsLock);
|
||||
}
|
||||
|
||||
@@ -266,6 +266,10 @@ DrawRaceStrings (MENU_STATE *pMS, BYTE NewRaceItem)
|
||||
#define SHIP_WIN_HEIGHT (SHIP_WIN_WIDTH + 6)
|
||||
#define SHIP_WIN_FRAMES ((SHIP_WIN_WIDTH >> 1) + 1)
|
||||
|
||||
// Print the crew count of an escort ship on top of its (already drawn)
|
||||
// image, either as '30' (full), '28/30' (partially full), or 'SCRAP'
|
||||
// (empty).
|
||||
// pRect is the rectangle of the ship image.
|
||||
static void
|
||||
ShowShipCrew (SHIP_FRAGMENT *StarShipPtr, const RECT *pRect)
|
||||
{
|
||||
@@ -274,20 +278,21 @@ ShowShipCrew (SHIP_FRAGMENT *StarShipPtr, const RECT *pRect)
|
||||
UNICODE buf[80];
|
||||
HFLEETINFO hTemplate;
|
||||
FLEET_INFO *TemplatePtr;
|
||||
COUNT maxCrewLevel;
|
||||
|
||||
hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q),
|
||||
StarShipPtr->race_id);
|
||||
TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate);
|
||||
if (StarShipPtr->crew_level >= TemplatePtr->crew_level)
|
||||
maxCrewLevel = TemplatePtr->crew_level;
|
||||
UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate);
|
||||
|
||||
if (StarShipPtr->crew_level >= maxCrewLevel)
|
||||
sprintf (buf, "%u", StarShipPtr->crew_level);
|
||||
else if (StarShipPtr->crew_level == 0)
|
||||
// XXX: "SCRAP" needs to be moved to starcon.txt
|
||||
utf8StringCopy (buf, sizeof (buf), "SCRAP");
|
||||
else
|
||||
sprintf (buf, "%u/%u",
|
||||
StarShipPtr->crew_level,
|
||||
TemplatePtr->crew_level);
|
||||
UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate);
|
||||
sprintf (buf, "%u/%u", StarShipPtr->crew_level, maxCrewLevel);
|
||||
|
||||
r = *pRect;
|
||||
t.baseline.x = r.corner.x + (r.extent.width >> 1);
|
||||
@@ -313,14 +318,17 @@ static void
|
||||
ShowCombatShip (MENU_STATE *pMS, COUNT which_window,
|
||||
SHIP_FRAGMENT *YankedStarShipPtr)
|
||||
{
|
||||
COUNT i, num_ships;
|
||||
COUNT i;
|
||||
COUNT num_ships;
|
||||
HSHIPFRAG hStarShip, hNextShip;
|
||||
SHIP_FRAGMENT *StarShipPtr;
|
||||
struct
|
||||
{
|
||||
SHIP_FRAGMENT *StarShipPtr;
|
||||
POINT finished_s;
|
||||
STAMP ship_s, lfdoor_s, rtdoor_s;
|
||||
STAMP ship_s;
|
||||
STAMP lfdoor_s;
|
||||
STAMP rtdoor_s;
|
||||
} ship_win_info[MAX_BUILT_SHIPS], *pship_win_info;
|
||||
|
||||
num_ships = 1;
|
||||
@@ -388,6 +396,10 @@ ShowCombatShip (MENU_STATE *pMS, COUNT which_window,
|
||||
hNextShip = _GetSuccLink (StarShipPtr);
|
||||
|
||||
pship_win_info->StarShipPtr = StarShipPtr;
|
||||
// XXX BUG: this looks wrong according to the original
|
||||
// semantics of LockShipFrag(): StarShipPtr is not valid
|
||||
// anymore after UnlockShipFrag() is called, but it is
|
||||
// used thereafter.
|
||||
|
||||
pship_win_info->lfdoor_s.origin.x = -1;
|
||||
pship_win_info->rtdoor_s.origin.x = 1;
|
||||
@@ -496,6 +508,7 @@ ShowCombatShip (MENU_STATE *pMS, COUNT which_window,
|
||||
}
|
||||
}
|
||||
|
||||
// Pre: GraphicsLock is unlocked.
|
||||
static void
|
||||
CrewTransaction (SIZE crew_delta)
|
||||
{
|
||||
@@ -519,10 +532,7 @@ CrewTransaction (SIZE crew_delta)
|
||||
&& crew_bought - crew_delta < CREW_EXPENSE_THRESHOLD)
|
||||
{
|
||||
GLOBAL (CrewCost) += 2;
|
||||
|
||||
UnlockMutex (GraphicsLock);
|
||||
DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW);
|
||||
LockMutex (GraphicsLock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -531,10 +541,7 @@ CrewTransaction (SIZE crew_delta)
|
||||
&& crew_bought - crew_delta >= CREW_EXPENSE_THRESHOLD)
|
||||
{
|
||||
GLOBAL (CrewCost) -= 2;
|
||||
|
||||
UnlockMutex (GraphicsLock);
|
||||
DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW);
|
||||
LockMutex (GraphicsLock);
|
||||
}
|
||||
}
|
||||
if (CheckAlliance (SHOFIXTI_SHIP) != GOOD_GUY)
|
||||
@@ -739,8 +746,14 @@ DMS_HireFlagShipCrew (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Draw a crew member.
|
||||
DrawPoint (&r.corner);
|
||||
|
||||
// Update the crew counter and RU. Note that the crew counter is
|
||||
// flashing.
|
||||
PreUpdateFlashRectLocked ();
|
||||
DeltaSISGauges (1, 0, -GLOBAL (CrewCost));
|
||||
PostUpdateFlashRectLocked ();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -765,9 +778,14 @@ DMS_DismissFlagShipCrew (void)
|
||||
GET_GAME_STATE (CREW_PURCHASED0),
|
||||
GET_GAME_STATE (CREW_PURCHASED1));
|
||||
|
||||
// Update the crew counter and RU. Note that the crew counter is
|
||||
// flashing.
|
||||
PreUpdateFlashRectLocked ();
|
||||
DeltaSISGauges (-1, 0, GLOBAL (CrewCost) -
|
||||
(crew_bought == CREW_EXPENSE_THRESHOLD ? 2 : 0));
|
||||
PostUpdateFlashRectLocked ();
|
||||
|
||||
// Remove the pixel representing the crew member.
|
||||
GetCPodCapacity (&r.corner);
|
||||
SetContextForeGroundColor (BLACK_COLOR);
|
||||
DrawPoint (&r.corner);
|
||||
@@ -824,8 +842,11 @@ DMS_HireEscortShipCrew (SHIP_FRAGMENT *StarShipPtr)
|
||||
}
|
||||
|
||||
++StarShipPtr->crew_level;
|
||||
|
||||
PreUpdateFlashRectLocked ();
|
||||
DMS_GetEscortShipRect (&r, StarShipPtr->index);
|
||||
ShowShipCrew (StarShipPtr, &r);
|
||||
PostUpdateFlashRectLocked ();
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -867,8 +888,10 @@ DMS_DismissEscortShipCrew (SHIP_FRAGMENT *StarShipPtr)
|
||||
PlayMenuSound (MENU_SOUND_FAILURE);
|
||||
}
|
||||
|
||||
PreUpdateFlashRectLocked ();
|
||||
DMS_GetEscortShipRect (&r, StarShipPtr->index);
|
||||
ShowShipCrew (StarShipPtr, &r);
|
||||
PostUpdateFlashRectLocked ();
|
||||
|
||||
return crew_delta;
|
||||
}
|
||||
@@ -880,6 +903,7 @@ DMS_DismissEscortShipCrew (SHIP_FRAGMENT *StarShipPtr)
|
||||
// selected.
|
||||
// 'dy' is -1 if the 'up' button was pressed, or '1' if the down button was
|
||||
// pressed.
|
||||
// Pre: caller holds the GraphicsLock
|
||||
static void
|
||||
DMS_ModifyCrew (MENU_STATE *pMS, HSHIPFRAG hStarShip, SBYTE dy)
|
||||
{
|
||||
@@ -936,12 +960,15 @@ DMS_ModifyCrew (MENU_STATE *pMS, HSHIPFRAG hStarShip, SBYTE dy)
|
||||
pMS->delta_item &= MODIFY_CREW_FLAG;
|
||||
}
|
||||
|
||||
UnlockMutex (GraphicsLock);
|
||||
CrewTransaction (crew_delta);
|
||||
LockMutex (GraphicsLock);
|
||||
}
|
||||
|
||||
// Helper function for DoModifyShips(), called when the player presses the
|
||||
// select button when the cursor is over an empty escort ship slot.
|
||||
// Try to add the currently selected ship as an escort ship.
|
||||
// Pre: caller does not hold the GraphicsLock
|
||||
static void
|
||||
DMS_TryAddEscortShip (MENU_STATE *pMS)
|
||||
{
|
||||
@@ -1000,7 +1027,7 @@ DMS_AddEscortShip (MENU_STATE *pMS, BOOLEAN special, BOOLEAN select,
|
||||
// Cancel selecting an escort ship.
|
||||
pMS->delta_item &= ~MODIFY_CREW_FLAG;
|
||||
LockMutex (GraphicsLock);
|
||||
SetFlashRect (SFR_MENU_3DO);
|
||||
SetFlashRect (NULL);
|
||||
UnlockMutex (GraphicsLock);
|
||||
DrawMenuStateStrings (PM_CREW, SHIPYARD_CREW);
|
||||
LockMutex (GraphicsLock);
|
||||
@@ -1032,7 +1059,9 @@ DMS_AddEscortShip (MENU_STATE *pMS, BOOLEAN special, BOOLEAN select,
|
||||
|
||||
if (currentShip != LOBYTE (pMS->delta_item))
|
||||
{
|
||||
PreUpdateFlashRect ();
|
||||
DrawRaceStrings (pMS, currentShip);
|
||||
PostUpdateFlashRect ();
|
||||
pMS->delta_item = currentShip | MODIFY_CREW_FLAG;
|
||||
}
|
||||
}
|
||||
@@ -1041,6 +1070,7 @@ DMS_AddEscortShip (MENU_STATE *pMS, BOOLEAN special, BOOLEAN select,
|
||||
|
||||
// Helper function for DoModifyShips(), called when the player presses
|
||||
// 'select' or 'cancel' after selling all the crew.
|
||||
// Pre: caller holds the GraphicsLock
|
||||
static void
|
||||
DMS_ScrapEscortShip (MENU_STATE *pMS, HSHIPFRAG hStarShip)
|
||||
{
|
||||
@@ -1108,6 +1138,7 @@ DMS_MoveCursor (BYTE curState, SBYTE dx, SBYTE dy)
|
||||
|
||||
// Helper function for DoModifyShips(), called every time DoModifyShip() is
|
||||
// called when we are in crew editing mode.
|
||||
// Pre: Caller holds the GraphicsLock
|
||||
static void
|
||||
DMS_EditCrewMode (MENU_STATE *pMS, HSHIPFRAG hStarShip,
|
||||
BOOLEAN select, BOOLEAN cancel, SBYTE dy)
|
||||
@@ -1132,9 +1163,7 @@ DMS_EditCrewMode (MENU_STATE *pMS, HSHIPFRAG hStarShip,
|
||||
}
|
||||
|
||||
pMS->delta_item &= ~MODIFY_CREW_FLAG;
|
||||
LockMutex (GraphicsLock);
|
||||
DMS_SetMode (pMS, DMS_Mode_navigate);
|
||||
UnlockMutex (GraphicsLock);
|
||||
}
|
||||
else if (dy)
|
||||
{
|
||||
@@ -1146,7 +1175,7 @@ DMS_EditCrewMode (MENU_STATE *pMS, HSHIPFRAG hStarShip,
|
||||
|
||||
// Helper function for DoModifyShips(), called every time DoModifyShip() is
|
||||
// called when we are in the mode where you can select a ship or empty slot.
|
||||
void
|
||||
static void
|
||||
DMS_NavigateShipSlots (MENU_STATE *pMS, BOOLEAN special, BOOLEAN select,
|
||||
BOOLEAN cancel, SBYTE dx, SBYTE dy)
|
||||
{
|
||||
|
||||
+111
-185
@@ -31,6 +31,7 @@
|
||||
#include "element.h"
|
||||
#include "setup.h"
|
||||
#include "state.h"
|
||||
#include "flash.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/tasklib.h"
|
||||
#include "libs/log.h"
|
||||
@@ -1589,248 +1590,173 @@ DrawAutoPilotMessage (BOOLEAN Reset)
|
||||
}
|
||||
|
||||
|
||||
Task flash_task = 0;
|
||||
RECT flash_rect;
|
||||
static FRAME flash_screen_frame = 0;
|
||||
// The original contents of the flash rectangle.
|
||||
static int flash_changed;
|
||||
Mutex flash_mutex = 0;
|
||||
static Task flash_task = 0;
|
||||
static FlashContext *flashContext = NULL;
|
||||
static RECT flash_rect;
|
||||
static Mutex flash_mutex = 0;
|
||||
|
||||
static int
|
||||
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;
|
||||
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))
|
||||
{
|
||||
CONTEXT OldContext;
|
||||
|
||||
TimeCount nextTime;
|
||||
LockMutex (flash_mutex);
|
||||
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));
|
||||
Flash_process (flashContext);
|
||||
nextTime = Flash_nextTime (flashContext);
|
||||
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;
|
||||
SleepThreadUntil (nextTime);
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pre: the caller holds the GraphicsLock
|
||||
void
|
||||
SetFlashRect (RECT *pRect)
|
||||
SetFlashRect (const RECT *pRect)
|
||||
{
|
||||
RECT clip_r = {{0, 0}, {0, 0}};
|
||||
RECT temp_r, flash_rect1, old_r;
|
||||
CONTEXT OldContext;
|
||||
int create_flash = 0;
|
||||
RECT temp_r;
|
||||
|
||||
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)
|
||||
{
|
||||
// The caller specified their own flash area, or NULL (stop flashing).
|
||||
GetContextClipRect (&clip_r);
|
||||
OldContext = SetContext (ScreenContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Don't flash when using the PC menu
|
||||
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;
|
||||
}
|
||||
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);
|
||||
pRect = &temp_r;
|
||||
temp_r.corner.x = RADAR_X - clip_r.corner.x;
|
||||
temp_r.corner.y = RADAR_Y - clip_r.corner.y;
|
||||
temp_r.extent.width = RADAR_WIDTH;
|
||||
temp_r.extent.height = RADAR_HEIGHT;
|
||||
SetContext (ScreenContext);
|
||||
SetContext (OldContext);
|
||||
}
|
||||
}
|
||||
|
||||
if (pRect == 0 || pRect->extent.width == 0)
|
||||
{
|
||||
// End the flashing.
|
||||
flash_rect1.extent.width = 0;
|
||||
if (flash_task)
|
||||
// Conclude an old flash task.
|
||||
if (flashContext != NULL)
|
||||
{
|
||||
UnlockMutex (GraphicsLock);
|
||||
ConcludeTask (flash_task);
|
||||
LockMutex (GraphicsLock);
|
||||
flash_task = 0;
|
||||
|
||||
Flash_terminate (flashContext);
|
||||
flashContext = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// Start a new flash task.
|
||||
if (pRect != 0 && pRect->extent.width != 0)
|
||||
{
|
||||
flash_rect1 = *pRect;
|
||||
flash_rect1.corner.x += clip_r.corner.x;
|
||||
flash_rect1.corner.y += clip_r.corner.y;
|
||||
create_flash = 1;
|
||||
flash_rect = *pRect;
|
||||
flash_rect.corner.x += clip_r.corner.x;
|
||||
flash_rect.corner.y += clip_r.corner.y;
|
||||
|
||||
flashContext = Flash_createHighlight (ScreenContext, &flash_rect);
|
||||
Flash_setMergeFactors(flashContext, 3, 2, 2);
|
||||
Flash_setSpeed (flashContext, 0, ONE_SECOND / 16, 0, ONE_SECOND / 16);
|
||||
Flash_setFrameTime (flashContext, ONE_SECOND / 16);
|
||||
Flash_start (flashContext);
|
||||
|
||||
flash_task = AssignTask (flash_rect_func, 2048, "flash rectangle");
|
||||
}
|
||||
}
|
||||
|
||||
// Sleep while calling the flash rectangle update when necessary.
|
||||
void
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
COUNT updateFlashRectRecursion = 0;
|
||||
// XXX This is necessary at least because DMS_AddEscortShip() calls
|
||||
// DrawRaceStrings() in an UpdateFlashRect block, which calls
|
||||
// ClearSISRect(), which calls DrawMenuStateStrings(), which starts its own
|
||||
// UpdateFlashRect block. This should probably be cleaned up.
|
||||
|
||||
// GraphicsLock must be unlocked.
|
||||
void
|
||||
PreUpdateFlashRect (void)
|
||||
{
|
||||
if (flash_task)
|
||||
{
|
||||
updateFlashRectRecursion++;
|
||||
if (updateFlashRectRecursion > 1)
|
||||
return;
|
||||
|
||||
LockMutex (flash_mutex);
|
||||
flash_rect = flash_rect1;
|
||||
|
||||
if (old_r.extent.width && !rectsEqual (old_r, flash_rect))
|
||||
{
|
||||
// We had a flash rectangle, and now a different one is set.
|
||||
if (flash_screen_frame)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
// A new flash rectangle is set.
|
||||
// Copy the original contents of the rectangle from the screen.
|
||||
if (flash_screen_frame)
|
||||
DestroyDrawable (ReleaseDrawable (flash_screen_frame));
|
||||
flash_screen_frame =
|
||||
CaptureDrawable (LoadDisplayPixmap (&flash_rect, (FRAME)0));
|
||||
}
|
||||
flash_changed = 1;
|
||||
Flash_pause (flashContext);
|
||||
// We need to actually pause, as the flash update function
|
||||
// is called from another thread.
|
||||
Flash_preUpdate (flashContext);
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// GraphicsLock must be unlocked.
|
||||
void
|
||||
PostUpdateFlashRect (void)
|
||||
{
|
||||
flash_task = AssignTask (flash_rect_func, 2048,
|
||||
"flash rectangle");
|
||||
if (flash_task)
|
||||
{
|
||||
updateFlashRectRecursion--;
|
||||
if (updateFlashRectRecursion > 0)
|
||||
return;
|
||||
|
||||
LockMutex (flash_mutex);
|
||||
Flash_postUpdate (flashContext);
|
||||
Flash_continue (flashContext);
|
||||
UnlockMutex (flash_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
SetContext (OldContext);
|
||||
// Because the situation occurs a lot where the GraphicsLock is already
|
||||
// locked, we add this function.
|
||||
void
|
||||
PreUpdateFlashRectLocked (void)
|
||||
{
|
||||
UnlockMutex (GraphicsLock);
|
||||
PreUpdateFlashRect ();
|
||||
LockMutex (GraphicsLock);
|
||||
}
|
||||
|
||||
// Because the situation occurs a lot where the GraphicsLock is already
|
||||
// locked, we add this function.
|
||||
void
|
||||
PostUpdateFlashRectLocked (void)
|
||||
{
|
||||
UnlockMutex (GraphicsLock);
|
||||
PostUpdateFlashRect ();
|
||||
LockMutex (GraphicsLock);
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -181,7 +181,11 @@ extern void RepairSISBorder (void);
|
||||
extern void InitSISContexts (void);
|
||||
extern void DrawSISFrame (void);
|
||||
extern void ClearSISRect (BYTE ClearFlags);
|
||||
extern void SetFlashRect (RECT *pRect);
|
||||
extern void SetFlashRect (const RECT *pRect);
|
||||
extern void PreUpdateFlashRect (void);
|
||||
extern void PostUpdateFlashRect (void);
|
||||
extern void PreUpdateFlashRectLocked (void);
|
||||
extern void PostUpdateFlashRectLocked (void);
|
||||
#define SFR_MENU_3DO ((RECT*)~0L)
|
||||
#define SFR_MENU_ANY ((RECT*)~1L)
|
||||
extern void DrawHyperCoords (POINT puniverse);
|
||||
|
||||
Reference in New Issue
Block a user