Added graphics context debugging function.
Plus small cleanups. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3302 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
Changes towards version 0.7:
|
||||
- Added graphics context debugging function - SvdB
|
||||
- Thread down-throttling and game sleep when inactive (currently disabled),
|
||||
(bug #1070), from Flandry
|
||||
- Internal changes: GOOD_GUY/BAD_GUY ship flags retired - Alex
|
||||
|
||||
+16
-5
@@ -6,11 +6,15 @@ require the game to be in a specific state.
|
||||
The function debugKeyPressed() in uqmdebug.c is called when the debug key
|
||||
is pressed. This function is a suitable place to put various debugging
|
||||
calls.
|
||||
There is also a global variable 'debugHook', which can be set to a function
|
||||
to be called the next iteration of the main game loop (which will occur
|
||||
when the current activity (IP, HyperSpace, Communication, Battle) changes.
|
||||
By setting this, a function can be called from the main loop, thereby
|
||||
eliminating threading issues that may otherwise arrise.
|
||||
There are also global variables 'debugHook' and 'doInputDebugHook',
|
||||
which can be set to a function to be called from the Starcon2Main thread.
|
||||
If if is set, 'debugHook' is called the next iteration of the main game loop
|
||||
(which will occur when the current activity (IP, HyperSpace, Communication,
|
||||
Battle) changes. The game will be in a well defined state here.
|
||||
If 'doInputDebugHook' is set, the function it is set to is called from
|
||||
doInput(), which is called all throughout the game.
|
||||
By setting one of these hooks, a function can be called from the Starcon2Main
|
||||
thread, thereby eliminating threading issues that may otherwise arrise.
|
||||
The debug key can be specified in user's override.cfg by adding a line
|
||||
with a text similar to "debug.1 = STRING:key F12".
|
||||
An interactive way to access various debugging code, similar to
|
||||
@@ -56,6 +60,13 @@ listed below:
|
||||
This function is not defined in sc2code/uqmdebug.h, but in libs/uio.h.
|
||||
This function can interactively (tty-based) display information on
|
||||
the state of the uio file system, and modifications can be made.
|
||||
- the function dumpStrings()
|
||||
This function prints all the game strings, and is useful to check whether
|
||||
the various string bases, as defined in gamestr.h, are correct.
|
||||
- the function debugContexts()
|
||||
Prints and visually displays the various graphics contexts.
|
||||
This function should only be called from doInputDebugHook(), as threading
|
||||
issues would otherwise arrise.
|
||||
|
||||
|
||||
The first version of this document was created by Serge van den Boom,
|
||||
|
||||
+16
-1
@@ -169,8 +169,11 @@ extern void UninitGraphics (void);
|
||||
|
||||
extern CONTEXT SetContext (CONTEXT Context);
|
||||
extern COLOR SetContextForeGroundColor (COLOR Color);
|
||||
extern COLOR GetContextForeGroundColor (void);
|
||||
extern COLOR SetContextBackGroundColor (COLOR Color);
|
||||
extern COLOR GetContextBackGroundColor (void);
|
||||
extern FRAME SetContextFGFrame (FRAME Frame);
|
||||
extern FRAME GetContextFGFrame (void);
|
||||
extern BOOLEAN SetContextClipping (BOOLEAN ClipStatus);
|
||||
extern BOOLEAN SetContextClipRect (RECT *pRect);
|
||||
extern BOOLEAN GetContextClipRect (RECT *pRect);
|
||||
@@ -191,7 +194,13 @@ extern void UnbatchGraphics (void);
|
||||
extern void FlushGraphics (void);
|
||||
extern void ClearBackGround (RECT *pClipRect);
|
||||
extern void ClearDrawable (void);
|
||||
extern CONTEXT CreateContext (void);
|
||||
#ifdef DEBUG
|
||||
extern CONTEXT CreateContextAux (const char *name);
|
||||
#define CreateContext(name) CreateContextAux((name))
|
||||
#else /* if !defined(DEBUG) */
|
||||
extern CONTEXT CreateContextAux (void);
|
||||
#define CreateContext(name) CreateContextAux()
|
||||
#endif /* !defined(DEBUG) */
|
||||
extern BOOLEAN DestroyContext (CONTEXT ContextRef);
|
||||
extern DRAWABLE CreateDisplay (CREATE_FLAGS CreateFlags, SIZE *pwidth,
|
||||
SIZE *pheight);
|
||||
@@ -199,6 +208,12 @@ extern DRAWABLE CreateDrawable (CREATE_FLAGS CreateFlags, SIZE width,
|
||||
SIZE height, COUNT num_frames);
|
||||
extern BOOLEAN DestroyDrawable (DRAWABLE Drawable);
|
||||
extern BOOLEAN GetFrameRect (FRAME Frame, RECT *pRect);
|
||||
#ifdef DEBUG
|
||||
extern const char *GetContextName (CONTEXT context);
|
||||
extern CONTEXT GetFirstContext (void);
|
||||
extern CONTEXT GetNextContext (CONTEXT context);
|
||||
extern size_t GetContextCount (void);
|
||||
#endif /* DEBUG */
|
||||
|
||||
extern HOT_SPOT SetFrameHot (FRAME Frame, HOT_SPOT HotSpot);
|
||||
extern HOT_SPOT GetFrameHot (FRAME Frame);
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
GRAPHICS_STATUS _GraphicsStatusFlags;
|
||||
CONTEXT _pCurContext;
|
||||
|
||||
#ifdef DEBUG
|
||||
// We keep track of all contexts
|
||||
CONTEXT firstContext;
|
||||
// The first one in the list.
|
||||
CONTEXT *contextEnd = &firstContext;
|
||||
// Where to put the next context.
|
||||
#endif
|
||||
|
||||
PRIMITIVE _locPrim;
|
||||
|
||||
FONT _CurFontPtr;
|
||||
@@ -37,12 +45,10 @@ SetContext (CONTEXT Context)
|
||||
if (LastContext)
|
||||
{
|
||||
UnsetContextFlags (
|
||||
MAKE_WORD (0, GRAPHICS_ACTIVE | DRAWABLE_ACTIVE)
|
||||
);
|
||||
MAKE_WORD (0, GRAPHICS_ACTIVE | DRAWABLE_ACTIVE));
|
||||
SetContextFlags (
|
||||
MAKE_WORD (0, _GraphicsStatusFlags
|
||||
& (GRAPHICS_ACTIVE | DRAWABLE_ACTIVE))
|
||||
);
|
||||
& (GRAPHICS_ACTIVE | DRAWABLE_ACTIVE)));
|
||||
|
||||
DeactivateContext ();
|
||||
}
|
||||
@@ -65,17 +71,29 @@ SetContext (CONTEXT Context)
|
||||
return (LastContext);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
CONTEXT
|
||||
CreateContext (void)
|
||||
CreateContextAux (const char *name)
|
||||
#else /* if !defined(DEBUG) */
|
||||
CONTEXT
|
||||
CreateContextAux (void)
|
||||
#endif /* !defined(DEBUG) */
|
||||
{
|
||||
CONTEXT NewContext;
|
||||
|
||||
NewContext = AllocContext ();
|
||||
if (NewContext)
|
||||
{
|
||||
/* initialize context */
|
||||
CONTEXT OldContext;
|
||||
|
||||
/* initialize context */
|
||||
#ifdef DEBUG
|
||||
NewContext->name = name;
|
||||
NewContext->next = NULL;
|
||||
*contextEnd = NewContext;
|
||||
contextEnd = &NewContext->next;
|
||||
#endif /* DEBUG */
|
||||
|
||||
OldContext = SetContext (NewContext);
|
||||
SetContextForeGroundColor (
|
||||
BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
|
||||
@@ -85,9 +103,25 @@ CreateContext (void)
|
||||
SetContext (OldContext);
|
||||
}
|
||||
|
||||
return (NewContext);
|
||||
return NewContext;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Loop through the list of context to the pointer which points to the
|
||||
// specified context. This is either 'firstContext' or the address of
|
||||
// the 'next' field of some other context.
|
||||
static CONTEXT *
|
||||
FindContextPtr (CONTEXT context) {
|
||||
CONTEXT *ptr;
|
||||
|
||||
for (ptr = &firstContext; *ptr != NULL; ptr = &(*ptr)->next) {
|
||||
if (*ptr == context)
|
||||
break;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
BOOLEAN
|
||||
DestroyContext (CONTEXT ContextRef)
|
||||
{
|
||||
@@ -97,6 +131,16 @@ DestroyContext (CONTEXT ContextRef)
|
||||
if (_pCurContext && _pCurContext == ContextRef)
|
||||
SetContext ((CONTEXT)0);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Unlink the context.
|
||||
{
|
||||
CONTEXT *contextPtr = FindContextPtr (ContextRef);
|
||||
if (contextEnd == &ContextRef->next)
|
||||
contextEnd = contextPtr;
|
||||
*contextPtr = ContextRef->next;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
FreeContext (ContextRef);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -109,7 +153,8 @@ SetContextForeGroundColor (COLOR Color)
|
||||
if (!ContextActive ())
|
||||
return (BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
|
||||
|
||||
if ((oldColor = _get_context_fg_color ()) != Color)
|
||||
oldColor = _get_context_fg_color ();
|
||||
if (oldColor != Color)
|
||||
{
|
||||
SwitchContextForeGroundColor (Color);
|
||||
|
||||
@@ -123,6 +168,15 @@ SetContextForeGroundColor (COLOR Color)
|
||||
return (oldColor);
|
||||
}
|
||||
|
||||
COLOR
|
||||
GetContextForeGroundColor (void)
|
||||
{
|
||||
if (!ContextActive ())
|
||||
return (BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
|
||||
|
||||
return _get_context_fg_color ();
|
||||
}
|
||||
|
||||
COLOR
|
||||
SetContextBackGroundColor (COLOR Color)
|
||||
{
|
||||
@@ -131,14 +185,22 @@ SetContextBackGroundColor (COLOR Color)
|
||||
if (!ContextActive ())
|
||||
return (BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00));
|
||||
|
||||
if ((oldColor = _get_context_bg_color ()) != Color)
|
||||
{
|
||||
oldColor = _get_context_bg_color ();
|
||||
if (oldColor != Color)
|
||||
SwitchContextBackGroundColor (Color);
|
||||
}
|
||||
|
||||
return (oldColor);
|
||||
}
|
||||
|
||||
COLOR
|
||||
GetContextBackGroundColor (void)
|
||||
{
|
||||
if (!ContextActive ())
|
||||
return (BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00));
|
||||
|
||||
return _get_context_bg_color ();
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SetContextClipping (BOOLEAN ClipStatus)
|
||||
{
|
||||
@@ -249,3 +311,24 @@ FixContextFontEffect (void)
|
||||
_pCurContext->FontBacking = img;
|
||||
UnsetContextFBkFlags (FBK_DIRTY);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
const char *
|
||||
GetContextName (CONTEXT context)
|
||||
{
|
||||
return context->name;
|
||||
}
|
||||
|
||||
CONTEXT
|
||||
GetFirstContext (void)
|
||||
{
|
||||
return firstContext;
|
||||
}
|
||||
|
||||
CONTEXT
|
||||
GetNextContext (CONTEXT context)
|
||||
{
|
||||
return context->next;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ struct context_desc
|
||||
TFB_Image *FontBacking;
|
||||
FBK_FLAGS BackingFlags;
|
||||
|
||||
#ifdef DEBUG
|
||||
const char *name;
|
||||
CONTEXT next;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define AllocContext() HCalloc (sizeof (CONTEXT_DESC))
|
||||
|
||||
@@ -51,6 +51,12 @@ SetContextFGFrame (FRAME Frame)
|
||||
return (LastFrame);
|
||||
}
|
||||
|
||||
FRAME
|
||||
GetContextFGFrame (void)
|
||||
{
|
||||
return _CurFramePtr;
|
||||
}
|
||||
|
||||
DRAWABLE
|
||||
CreateDisplay (CREATE_FLAGS CreateFlags, SIZE *pwidth, SIZE *pheight)
|
||||
{
|
||||
|
||||
+2
-2
@@ -1266,7 +1266,7 @@ HailAlien (void)
|
||||
SubtitleText.align = CommData.AlienTextAlign;
|
||||
|
||||
// init subtitle cache context
|
||||
TextCacheContext = CreateContext ();
|
||||
TextCacheContext = CreateContext ("TextCacheContext");
|
||||
TextCacheFrame = CaptureDrawable (
|
||||
CreateDrawable (WANT_PIXMAP, SIS_SCREEN_WIDTH,
|
||||
SIS_SCREEN_HEIGHT - SLIDER_Y - SLIDER_HEIGHT + 2, 1));
|
||||
@@ -1287,7 +1287,7 @@ HailAlien (void)
|
||||
{
|
||||
RECT r;
|
||||
|
||||
TaskContext = CreateContext ();
|
||||
TaskContext = CreateContext ("TaskContext");
|
||||
SetContext (TaskContext);
|
||||
SetContextFGFrame (Screen);
|
||||
GetFrameRect (CommData.AlienFrame, &r);
|
||||
|
||||
@@ -315,8 +315,8 @@ credit_roll_task (void *data)
|
||||
TextBack = BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00);
|
||||
TextFore = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F);
|
||||
|
||||
LocalContext = CreateContext ();
|
||||
DrawContext = CreateContext ();
|
||||
LocalContext = CreateContext ("Credits.LocalContext");
|
||||
DrawContext = CreateContext ("Credits.DrawContext");
|
||||
|
||||
total_h = disp_h = SCREEN_HEIGHT;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "settings.h"
|
||||
#include "sounds.h"
|
||||
#include "tactrans.h"
|
||||
#include "uqmdebug.h"
|
||||
#include "libs/inplib.h"
|
||||
#include "libs/timelib.h"
|
||||
#include "libs/threadlib.h"
|
||||
@@ -352,6 +353,19 @@ DoInput (void *pInputState, BOOLEAN resetInput)
|
||||
|
||||
UpdateInputState ();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (doInputDebugHook != NULL)
|
||||
{
|
||||
void (*saveDebugHook) (void);
|
||||
saveDebugHook = doInputDebugHook;
|
||||
doInputDebugHook = NULL;
|
||||
// No further debugHook calls unless the called
|
||||
// function resets doInputDebugHook.
|
||||
(*saveDebugHook) ();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEMO_MODE || CREATE_JOURNAL
|
||||
if (ArrowInput != DemoInput)
|
||||
#endif
|
||||
|
||||
@@ -125,7 +125,7 @@ CreateRadar (void)
|
||||
RECT r;
|
||||
CONTEXT OldContext;
|
||||
|
||||
RadarContext = CreateContext ();
|
||||
RadarContext = CreateContext ("RadarContext");
|
||||
OldContext = SetContext (RadarContext);
|
||||
SetContextFGFrame (Screen);
|
||||
r.corner.x = RADAR_X;
|
||||
|
||||
@@ -110,7 +110,7 @@ GenerateChmmr (BYTE control)
|
||||
CaptureStringTable (
|
||||
LoadStringTable (CHMMR_BASE_STRTAB));
|
||||
|
||||
ScanContext = CreateContext ();
|
||||
ScanContext = CreateContext ("genchmmr.ScanContext");
|
||||
SetContext (ScanContext);
|
||||
SetContextFGFrame (Screen);
|
||||
r.corner.x = (SIS_ORG_X + SIS_SCREEN_WIDTH) - MAP_WIDTH;
|
||||
|
||||
@@ -152,7 +152,7 @@ LoadPlanet (FRAME SurfDefFrame)
|
||||
|
||||
StopMusic ();
|
||||
|
||||
TaskContext = CreateContext ();
|
||||
TaskContext = CreateContext ("TaskContext");
|
||||
|
||||
pPlanetDesc = pSolarSysState->pOrbitalDesc;
|
||||
|
||||
|
||||
@@ -1164,7 +1164,7 @@ ScanSystem (void)
|
||||
(MAP_HEIGHT >> 1) << MAG_SHIFT;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
ScanContext = CreateContext ();
|
||||
ScanContext = CreateContext ("ScanContext");
|
||||
SetContext (ScanContext);
|
||||
|
||||
initPlanetLocationImage (&MenuState);
|
||||
|
||||
+4
-4
@@ -96,7 +96,7 @@ LoadKernel (int argc, char *argv[])
|
||||
InitSound (argc, argv);
|
||||
InitVideoPlayer (TRUE);
|
||||
|
||||
ScreenContext = CreateContext ();
|
||||
ScreenContext = CreateContext ("ScreenContext");
|
||||
if (ScreenContext == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -158,7 +158,7 @@ InitContexts (void)
|
||||
{
|
||||
RECT r;
|
||||
|
||||
StatusContext = CreateContext ();
|
||||
StatusContext = CreateContext ("StatusContext");
|
||||
if (StatusContext == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -170,11 +170,11 @@ InitContexts (void)
|
||||
r.extent.height = STATUS_HEIGHT;
|
||||
SetContextClipRect (&r);
|
||||
|
||||
SpaceContext = CreateContext ();
|
||||
SpaceContext = CreateContext ("SpaceContext");
|
||||
if (SpaceContext == NULL)
|
||||
return FALSE;
|
||||
|
||||
OffScreenContext = CreateContext ();
|
||||
OffScreenContext = CreateContext ("OffScreenContext");
|
||||
if (OffScreenContext == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
+52
-48
@@ -761,7 +761,8 @@ DrawStorageBays (BOOLEAN Refresh)
|
||||
--i;
|
||||
}
|
||||
|
||||
r.extent.height = (4 * j + (STORAGE_BAY_CAPACITY - 1)) / STORAGE_BAY_CAPACITY;
|
||||
r.extent.height = (4 * j + (STORAGE_BAY_CAPACITY - 1)) /
|
||||
STORAGE_BAY_CAPACITY;
|
||||
if (r.extent.height)
|
||||
{
|
||||
r.corner.y += 4 - r.extent.height;
|
||||
@@ -876,14 +877,11 @@ DeltaSISGauges (SIZE crew_delta, SIZE fuel_delta, int resunit_delta)
|
||||
s.origin.y = 0;
|
||||
for (i = 0; i < NUM_DRIVE_SLOTS; ++i)
|
||||
{
|
||||
BYTE which_piece;
|
||||
|
||||
if ((which_piece =
|
||||
GLOBAL_SIS (DriveSlots[i])) < EMPTY_SLOT)
|
||||
BYTE which_piece = GLOBAL_SIS (DriveSlots[i]);
|
||||
if (which_piece < EMPTY_SLOT)
|
||||
{
|
||||
s.frame = SetAbsFrameIndex (
|
||||
FlagStatFrame, which_piece + 1 + 0
|
||||
);
|
||||
FlagStatFrame, which_piece + 1 + 0);
|
||||
DrawStamp (&s);
|
||||
s.frame = IncFrameIndex (s.frame);
|
||||
DrawStamp (&s);
|
||||
@@ -894,14 +892,11 @@ DeltaSISGauges (SIZE crew_delta, SIZE fuel_delta, int resunit_delta)
|
||||
s.origin.y = 0;
|
||||
for (i = 0; i < NUM_JET_SLOTS; ++i)
|
||||
{
|
||||
BYTE which_piece;
|
||||
|
||||
if ((which_piece =
|
||||
GLOBAL_SIS (JetSlots[i])) < EMPTY_SLOT)
|
||||
BYTE which_piece = GLOBAL_SIS (JetSlots[i]);
|
||||
if (which_piece < EMPTY_SLOT)
|
||||
{
|
||||
s.frame = SetAbsFrameIndex (
|
||||
FlagStatFrame, which_piece + 1 + 1
|
||||
);
|
||||
FlagStatFrame, which_piece + 1 + 1);
|
||||
DrawStamp (&s);
|
||||
s.frame = IncFrameIndex (s.frame);
|
||||
DrawStamp (&s);
|
||||
@@ -913,14 +908,11 @@ DeltaSISGauges (SIZE crew_delta, SIZE fuel_delta, int resunit_delta)
|
||||
s.origin.x = 1; // This properly centers the modules.
|
||||
for (i = 0; i < NUM_MODULE_SLOTS; ++i)
|
||||
{
|
||||
BYTE which_piece;
|
||||
|
||||
if ((which_piece =
|
||||
GLOBAL_SIS (ModuleSlots[i])) < EMPTY_SLOT)
|
||||
BYTE which_piece = GLOBAL_SIS (ModuleSlots[i]);
|
||||
if (which_piece < EMPTY_SLOT)
|
||||
{
|
||||
s.frame = SetAbsFrameIndex (
|
||||
FlagStatFrame, which_piece + 1 + 2
|
||||
);
|
||||
FlagStatFrame, which_piece + 1 + 2);
|
||||
DrawStamp (&s);
|
||||
}
|
||||
|
||||
@@ -996,22 +988,25 @@ DeltaSISGauges (SIZE crew_delta, SIZE fuel_delta, int resunit_delta)
|
||||
old_coarse_fuel = (COUNT)~0;
|
||||
else
|
||||
{
|
||||
DWORD FuelCapacity;
|
||||
|
||||
old_coarse_fuel = (COUNT)(
|
||||
GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE
|
||||
);
|
||||
GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE);
|
||||
if (fuel_delta < 0
|
||||
&& GLOBAL_SIS (FuelOnBoard) <= (DWORD)-fuel_delta)
|
||||
{
|
||||
GLOBAL_SIS (FuelOnBoard) = 0;
|
||||
else if ((GLOBAL_SIS (FuelOnBoard) += fuel_delta) >
|
||||
(FuelCapacity = GetFTankCapacity (NULL)))
|
||||
GLOBAL_SIS (FuelOnBoard) = FuelCapacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD FuelCapacity = GetFTankCapacity (NULL);
|
||||
GLOBAL_SIS (FuelOnBoard) += fuel_delta;
|
||||
if (GLOBAL_SIS (FuelOnBoard) > FuelCapacity)
|
||||
GLOBAL_SIS (FuelOnBoard) = FuelCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
new_coarse_fuel = (COUNT)(
|
||||
GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE
|
||||
);
|
||||
GLOBAL_SIS (FuelOnBoard) / FUEL_TANK_SCALE);
|
||||
if (new_coarse_fuel != old_coarse_fuel)
|
||||
{
|
||||
sprintf (buf, "%u", new_coarse_fuel);
|
||||
@@ -1122,8 +1117,7 @@ GetCPodCapacity (POINT *ppt)
|
||||
SetContextForeGroundColor (crew_rows[which_row]);
|
||||
else
|
||||
SetContextForeGroundColor (
|
||||
BUILD_COLOR (MAKE_RGB15 (0x05, 0x10, 0x05), 0x65)
|
||||
);
|
||||
BUILD_COLOR (MAKE_RGB15 (0x05, 0x10, 0x05), 0x65));
|
||||
}
|
||||
|
||||
capacity += CREW_POD_CAPACITY;
|
||||
@@ -1169,7 +1163,8 @@ GetSBayCapacity (POINT *ppt)
|
||||
};
|
||||
|
||||
bay_remainder = GLOBAL_SIS (TotalElementMass) - capacity;
|
||||
if ((which_row = bay_remainder / SBAY_MASS_PER_ROW) == 0)
|
||||
which_row = bay_remainder / SBAY_MASS_PER_ROW;
|
||||
if (which_row == 0)
|
||||
SetContextForeGroundColor (BLACK_COLOR);
|
||||
else
|
||||
SetContextForeGroundColor (color_bars[--which_row]);
|
||||
@@ -1184,7 +1179,7 @@ GetSBayCapacity (POINT *ppt)
|
||||
x -= SHIP_PIECE_OFFSET;
|
||||
} while (slot--);
|
||||
|
||||
return (capacity);
|
||||
return capacity;
|
||||
}
|
||||
|
||||
DWORD
|
||||
@@ -1229,8 +1224,7 @@ GetFTankCapacity (POINT *ppt)
|
||||
|
||||
which_row = (COUNT)(
|
||||
(GLOBAL_SIS (FuelOnBoard) - capacity)
|
||||
* MAX_FUEL_BARS / HEFUEL_TANK_CAPACITY
|
||||
);
|
||||
* MAX_FUEL_BARS / HEFUEL_TANK_CAPACITY);
|
||||
ppt->x = x + 1;
|
||||
if (volume == FUEL_TANK_CAPACITY)
|
||||
ppt->y = 27 - which_row;
|
||||
@@ -1247,7 +1241,7 @@ GetFTankCapacity (POINT *ppt)
|
||||
x -= SHIP_PIECE_OFFSET;
|
||||
} while (slot--);
|
||||
|
||||
return (capacity);
|
||||
return capacity;
|
||||
}
|
||||
|
||||
COUNT
|
||||
@@ -1281,7 +1275,7 @@ CountSISPieces (BYTE piece_type)
|
||||
}
|
||||
}
|
||||
|
||||
return (num_pieces);
|
||||
return num_pieces;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1356,6 +1350,7 @@ 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;
|
||||
// XXX: these are currently defined in libs/graphics/sdl/3do_getbody.c
|
||||
@@ -1369,25 +1364,25 @@ flash_rect_func (void *data)
|
||||
#define NORMAL_STRENGTH 4
|
||||
#define NORMAL_F_STRENGTH 0
|
||||
#define CACHE_SIZE 10
|
||||
DWORD TimeIn, WaitTime;
|
||||
SIZE strength, fstrength, incr;
|
||||
DWORD TimeIn;
|
||||
const DWORD WaitTime = ONE_SECOND / 16;
|
||||
SIZE strength;
|
||||
RECT cached_rect;
|
||||
FRAME cached_screen_frame = 0;
|
||||
Task task = (Task)data;
|
||||
int cached[CACHE_SIZE];
|
||||
bool cached[CACHE_SIZE];
|
||||
STAMP cached_stamp[CACHE_SIZE];
|
||||
int i;
|
||||
|
||||
// Init cache
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
cached[i] = 0;
|
||||
cached[i] = false;
|
||||
cached_stamp[i].frame = 0;
|
||||
}
|
||||
fstrength = NORMAL_F_STRENGTH;
|
||||
incr = 1;
|
||||
|
||||
strength = NORMAL_STRENGTH;
|
||||
TimeIn = GetTimeCounter ();
|
||||
WaitTime = ONE_SECOND / 16;
|
||||
while (!Task_ReadState(task, TASK_EXIT))
|
||||
{
|
||||
CONTEXT OldContext;
|
||||
@@ -1411,10 +1406,12 @@ flash_rect_func (void *data)
|
||||
arith_frame_blit (flash_screen_frame, &screen_rect,
|
||||
cached_screen_frame, NULL, 0, 0);
|
||||
UnlockMutex (flash_mutex);
|
||||
|
||||
// Clear the cache.
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
cached[i] = 0;
|
||||
if(cached_stamp[i].frame)
|
||||
cached[i] = false;
|
||||
if (cached_stamp[i].frame)
|
||||
DestroyDrawable (ReleaseDrawable (cached_stamp[i].frame));
|
||||
cached_stamp[i].frame = 0;
|
||||
}
|
||||
@@ -1436,7 +1433,7 @@ flash_rect_func (void *data)
|
||||
{
|
||||
RECT tmp_rect = cached_rect;
|
||||
pStamp = &cached_stamp[strength - MIN_STRENGTH];
|
||||
cached[strength - MIN_STRENGTH] = 1;
|
||||
cached[strength - MIN_STRENGTH] = true;
|
||||
pStamp->frame = CaptureDrawable (CreateDrawable (WANT_PIXMAP,
|
||||
cached_rect.extent.width, cached_rect.extent.height,
|
||||
1));
|
||||
@@ -1451,11 +1448,12 @@ flash_rect_func (void *data)
|
||||
arith_frame_blit (cached_screen_frame, &tmp_rect,
|
||||
pStamp->frame, &tmp_rect, strength, 4);
|
||||
}
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
OldContext = SetContext (ScreenContext);
|
||||
SetContextClipRect (&cached_rect);
|
||||
// flash changed_can't be modified while GraphicSem is held
|
||||
if (! flash_changed)
|
||||
if (!flash_changed)
|
||||
DrawStamp (pStamp);
|
||||
SetContextClipRect (NULL); // this will flush whatever
|
||||
SetContext (OldContext);
|
||||
@@ -1465,6 +1463,8 @@ flash_rect_func (void *data)
|
||||
SleepThreadUntil (TimeIn + WaitTime);
|
||||
TimeIn = GetTimeCounter ();
|
||||
}
|
||||
|
||||
// Clear cache
|
||||
{
|
||||
if (cached_screen_frame)
|
||||
DestroyDrawable (ReleaseDrawable (cached_screen_frame));
|
||||
@@ -1480,7 +1480,7 @@ flash_rect_func (void *data)
|
||||
UnlockMutex (flash_mutex);
|
||||
|
||||
FinishTask (task);
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1490,7 +1490,7 @@ SetFlashRect (RECT *pRect)
|
||||
CONTEXT OldContext;
|
||||
int create_flash = 0;
|
||||
|
||||
if (! flash_mutex)
|
||||
if (!flash_mutex)
|
||||
flash_mutex = CreateMutex ("FlashRect Lock",
|
||||
SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||
|
||||
@@ -1525,6 +1525,7 @@ SetFlashRect (RECT *pRect)
|
||||
|
||||
if (pRect == 0 || pRect->extent.width == 0)
|
||||
{
|
||||
// End the flashing.
|
||||
flash_rect1.extent.width = 0;
|
||||
if (flash_task)
|
||||
{
|
||||
@@ -1550,8 +1551,10 @@ SetFlashRect (RECT *pRect)
|
||||
|| old_r.corner.x != flash_rect.corner.x
|
||||
|| old_r.corner.y != flash_rect.corner.y))
|
||||
{
|
||||
// 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;
|
||||
@@ -1566,6 +1569,7 @@ SetFlashRect (RECT *pRect)
|
||||
|
||||
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));
|
||||
|
||||
+422
-5
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "build.h"
|
||||
#include "colors.h"
|
||||
#include "controls.h"
|
||||
#include "clock.h"
|
||||
#include "encount.h"
|
||||
#include "element.h"
|
||||
@@ -68,6 +69,7 @@ static void dumpPlanetTypeCallback (int index, const PlanetFrame *planet,
|
||||
BOOLEAN instantMove = FALSE;
|
||||
BOOLEAN disableInteractivity = FALSE;
|
||||
void (* volatile debugHook) (void) = NULL;
|
||||
void (* volatile doInputDebugHook) (void) = NULL;
|
||||
|
||||
|
||||
void
|
||||
@@ -118,6 +120,12 @@ debugKeyPressed (void)
|
||||
// main loop. Calling it from here would give threading
|
||||
// problems.
|
||||
|
||||
// Graphical and textual:
|
||||
//doInputDebugHook = debugContexts;
|
||||
// This will cause debugContexts to be called from the
|
||||
// Starcon2Main thread, from DoInput(). Calling it from here
|
||||
// would give threading problems.
|
||||
|
||||
// Interactive:
|
||||
// uio_debugInteractive(stdin, stdout, stderr);
|
||||
}
|
||||
@@ -755,6 +763,7 @@ dumpUniverse (FILE *out)
|
||||
UniverseRecurse (&universeRecurseArg);
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
void
|
||||
dumpUniverseToFile (void)
|
||||
{
|
||||
@@ -1162,6 +1171,7 @@ tallyResources (FILE *out)
|
||||
UniverseRecurse (&universeRecurseArg);
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
void
|
||||
tallyResourcesToFile (void)
|
||||
{
|
||||
@@ -1459,7 +1469,8 @@ depositQualityString (BYTE quality)
|
||||
|
||||
// playerNr should be 0 or 1
|
||||
STARSHIP*
|
||||
findPlayerShip (SIZE playerNr) {
|
||||
findPlayerShip (SIZE playerNr)
|
||||
{
|
||||
HELEMENT hElement, hNextElement;
|
||||
|
||||
for (hElement = GetHeadElement (); hElement; hElement = hNextElement)
|
||||
@@ -1486,7 +1497,8 @@ findPlayerShip (SIZE playerNr) {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
resetCrewBattle(void) {
|
||||
resetCrewBattle (void)
|
||||
{
|
||||
STARSHIP *StarShipPtr;
|
||||
COUNT delta;
|
||||
CONTEXT OldContext;
|
||||
@@ -1508,7 +1520,8 @@ resetCrewBattle(void) {
|
||||
}
|
||||
|
||||
void
|
||||
resetEnergyBattle(void) {
|
||||
resetEnergyBattle (void)
|
||||
{
|
||||
STARSHIP *StarShipPtr;
|
||||
COUNT delta;
|
||||
CONTEXT OldContext;
|
||||
@@ -1534,7 +1547,8 @@ resetEnergyBattle(void) {
|
||||
// This function should help in making sure that gamestr.h matches
|
||||
// gamestrings.txt.
|
||||
void
|
||||
dumpStrings(FILE *out) {
|
||||
dumpStrings (FILE *out)
|
||||
{
|
||||
#define STRINGIZE(a) #a
|
||||
#define MAKE_STRING_CATEGORY(prefix) \
|
||||
{ \
|
||||
@@ -1603,6 +1617,409 @@ dumpStrings(FILE *out) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static COLOR
|
||||
hsvaToRgba (double hue, double sat, double val, BYTE alpha) {
|
||||
assert (hue >= 0.0 && hue < 360.0);
|
||||
assert (sat >= 0 && sat <= 1.0);
|
||||
assert (val >= 0 && val <= 1.0);
|
||||
/*fprintf(stderr, "hsva = (%.1f, %.2f, %.2f, %.2d)\n",
|
||||
hue, sat, val, alpha);*/
|
||||
|
||||
unsigned int hi = (int) (hue / 60.0);
|
||||
double f = (hue / 60.0) - ((int) (hue / 60.0));
|
||||
double p = val * (1.0 - sat);
|
||||
double q = val * (1.0 - f * sat);
|
||||
double t = val * (1.0 - (1.0 - f * sat));
|
||||
|
||||
// Convert p, q, t, and v from [0..1] to [0..255]
|
||||
BYTE pb = (BYTE) (p * 255.0 + 0.5);
|
||||
BYTE qb = (BYTE) (q * 255.0 + 0.5);
|
||||
BYTE tb = (BYTE) (t * 255.0 + 0.5);
|
||||
BYTE vb = (BYTE) (val * 255.0 + 0.5);
|
||||
|
||||
assert (hi < 6);
|
||||
switch (hi) {
|
||||
case 0: return BUILD_COLOR_RGBA (vb, tb, pb, alpha);
|
||||
case 1: return BUILD_COLOR_RGBA (qb, vb, pb, alpha);
|
||||
case 2: return BUILD_COLOR_RGBA (pb, vb, tb, alpha);
|
||||
case 3: return BUILD_COLOR_RGBA (pb, qb, vb, alpha);
|
||||
case 4: return BUILD_COLOR_RGBA (tb, pb, vb, alpha);
|
||||
case 5: return BUILD_COLOR_RGBA (vb, pb, qb, alpha);
|
||||
}
|
||||
|
||||
// Should not happen.
|
||||
return BUILD_COLOR_RGBA (0, 0, 0, alpha);
|
||||
}
|
||||
|
||||
// Work-around: colors returned by BUILD_COLOR_RGBA are not usable to draw
|
||||
// with.
|
||||
static DWORD
|
||||
fixColorRgba (FRAME frame, COLOR col)
|
||||
{
|
||||
#if 0
|
||||
extern DWORD frame_mapRGBA (FRAME FramePtr, BYTE r, BYTE g, BYTE b,
|
||||
BYTE a);
|
||||
|
||||
BYTE r = (col & 0xff000000) >> 24;
|
||||
BYTE g = (col & 0x00ff0000) >> 16;
|
||||
BYTE b = (col & 0x0000ff00) >> 8;
|
||||
BYTE a = (col & 0x000000ff) >> 0;
|
||||
|
||||
return (DWORD) frame_mapRGBA (frame, r, g, b, a);
|
||||
#endif
|
||||
|
||||
BYTE r = (col & 0xff000000) >> 24;
|
||||
BYTE g = (col & 0x00ff0000) >> 16;
|
||||
BYTE b = (col & 0x0000ff00) >> 8;
|
||||
|
||||
(void) frame;
|
||||
return BUILD_COLOR (MAKE_RGB15 (r >> 3, g >> 3, b >> 3) ,0);
|
||||
}
|
||||
|
||||
// Workaround. DrawFilledRectangle() doesn't handle transparency.
|
||||
// We use a temporary frame to achieve the same thing.
|
||||
static void
|
||||
DrawFilledRectangleTransparent (RECT *rect, BYTE alpha)
|
||||
{
|
||||
extern void arith_frame_blit (FRAME srcFrame, const RECT *rsrc,
|
||||
FRAME dstFrame, const RECT *rdst, int num, int denom);
|
||||
|
||||
RECT absRect;
|
||||
FRAME orgRectFrame;
|
||||
COLOR fillColor;
|
||||
|
||||
// Create a rectangle from 'rect', but with (0, 0) as origin.
|
||||
absRect.corner.x = 0;
|
||||
absRect.corner.y = 0;
|
||||
absRect.extent = rect->extent;
|
||||
|
||||
// Create a new temporary FRAME to store the contents of the original
|
||||
// rectangle in.
|
||||
orgRectFrame = CaptureDrawable (CreateDrawable (
|
||||
WANT_PIXMAP, rect->extent.width, rect->extent.height, 1));
|
||||
|
||||
// Copy the original rectangle, faded.
|
||||
arith_frame_blit (GetContextFGFrame (), rect, orgRectFrame, &absRect,
|
||||
255 - alpha, 255);
|
||||
|
||||
// Apply the transparency to the colour.
|
||||
fillColor = GetContextForeGroundColor ();
|
||||
#if 0 /* 32 bits RGBA */
|
||||
fillColor =
|
||||
(((((fillColor & 0xff000000) >> 24) * alpha + 127) / 255) << 24) |
|
||||
(((((fillColor & 0x00ff0000) >> 16) * alpha + 127) / 255) << 16) |
|
||||
(((((fillColor & 0x0000ff00) >> 8) * alpha + 127) / 255) << 8);
|
||||
*/
|
||||
#endif
|
||||
/* 15 bits RGB + index: */
|
||||
fillColor =
|
||||
(((((fillColor & 0x007c0000) >> 18) * alpha + 15) / 31) << 18) |
|
||||
(((((fillColor & 0x0003e000) >> 13) * alpha + 15) / 31) << 13) |
|
||||
(((((fillColor & 0x00001f00) >> 8) * alpha + 15) / 31) << 8) |
|
||||
(fillColor & 0x000000ff);
|
||||
|
||||
// Fill the frame with fillColor
|
||||
{
|
||||
COLOR oldFgColor = SetContextForeGroundColor (fillColor);
|
||||
DrawFilledRectangle (rect);
|
||||
SetContextForeGroundColor (oldFgColor);
|
||||
FlushGraphics ();
|
||||
// Not really necessary for the Context for which this
|
||||
// function is called, but if this function is ever used
|
||||
// to draw directly to the screen, this will be needed
|
||||
// to make sure the rectangle is drawn before the
|
||||
// arith_frame_blit() call, which is immediate.
|
||||
}
|
||||
|
||||
// Blend in the original rectangle.
|
||||
arith_frame_blit (orgRectFrame, &absRect, GetContextFGFrame (), rect,
|
||||
1, -1);
|
||||
|
||||
// Destroy the temporary frame
|
||||
DestroyDrawable (ReleaseDrawable (orgRectFrame));
|
||||
}
|
||||
|
||||
// Returns true iff this context has a visible FRAME.
|
||||
static bool
|
||||
isContextVisible (CONTEXT context)
|
||||
{
|
||||
FRAME contextFrame;
|
||||
|
||||
// Save the original context.
|
||||
CONTEXT oldContext = SetContext (context);
|
||||
|
||||
// Get the frame of the specified context.
|
||||
contextFrame = GetContextFGFrame ();
|
||||
|
||||
// Restore the original context.
|
||||
SetContext (oldContext);
|
||||
|
||||
return contextFrame == Screen;
|
||||
}
|
||||
|
||||
static size_t
|
||||
countVisibleContexts (void)
|
||||
{
|
||||
size_t contextCount;
|
||||
CONTEXT context;
|
||||
|
||||
contextCount = 0;
|
||||
for (context = GetFirstContext (); context != NULL;
|
||||
context = GetNextContext (context))
|
||||
{
|
||||
if (!isContextVisible (context))
|
||||
continue;
|
||||
|
||||
contextCount++;
|
||||
}
|
||||
|
||||
return contextCount;
|
||||
}
|
||||
|
||||
static void
|
||||
drawContext (CONTEXT context, double hue /* no pun intended */)
|
||||
{
|
||||
FRAME drawFrame;
|
||||
CONTEXT oldContext;
|
||||
FONT oldFont;
|
||||
COLOR oldFgCol;
|
||||
COLOR rectCol;
|
||||
COLOR lineCol;
|
||||
COLOR textCol;
|
||||
bool haveClippingRect;
|
||||
RECT rect;
|
||||
LINE line;
|
||||
TEXT text;
|
||||
POINT p1, p2, p3, p4;
|
||||
|
||||
drawFrame = GetContextFGFrame ();
|
||||
rectCol = (COLOR) fixColorRgba (drawFrame,
|
||||
hsvaToRgba (hue, 1.0, 0.5, 127));
|
||||
lineCol = (COLOR) fixColorRgba (drawFrame,
|
||||
hsvaToRgba (hue, 1.0, 1.0, 0));
|
||||
textCol = lineCol;
|
||||
|
||||
// Save the original context.
|
||||
oldContext = SetContext (context);
|
||||
|
||||
// Get the clipping rectangle of the specified context.
|
||||
haveClippingRect = GetContextClipRect (&rect);
|
||||
|
||||
// Switch back the old context; we're going to draw in it.
|
||||
(void) SetContext (oldContext);
|
||||
|
||||
if (!haveClippingRect)
|
||||
{
|
||||
rect.corner.x = 0;
|
||||
rect.corner.y = 0;
|
||||
rect.extent.width = ScreenWidth;
|
||||
rect.extent.height = ScreenHeight;
|
||||
}
|
||||
|
||||
p1 = rect.corner;
|
||||
p2.x = rect.corner.x + rect.extent.width - 1;
|
||||
p2.y = rect.corner.y;
|
||||
p3.x = rect.corner.x;
|
||||
p3.y = rect.corner.y + rect.extent.height - 1;
|
||||
p4.x = rect.corner.x + rect.extent.width - 1;
|
||||
p4.y = rect.corner.y + rect.extent.height - 1;
|
||||
|
||||
oldFgCol = SetContextForeGroundColor (rectCol);
|
||||
DrawFilledRectangleTransparent (&rect, 63);
|
||||
|
||||
SetContextForeGroundColor (lineCol);
|
||||
line.first = p1; line.second = p2; DrawLine (&line);
|
||||
line.first = p2; line.second = p4; DrawLine (&line);
|
||||
line.first = p1; line.second = p3; DrawLine (&line);
|
||||
line.first = p3; line.second = p4; DrawLine (&line);
|
||||
line.first = p1; line.second = p4; DrawLine (&line);
|
||||
line.first = p2; line.second = p3; DrawLine (&line);
|
||||
// Gimme C'99! So I can do:
|
||||
// DrawLine ((LINE) { .first = p1, .second = p2 })
|
||||
|
||||
oldFont = SetContextFont (TinyFont);
|
||||
SetContextForeGroundColor (textCol);
|
||||
text.baseline.x = (p1.x + (p2.x + 1)) / 2;
|
||||
text.baseline.y = p1.y + 8;
|
||||
text.pStr = GetContextName (context);
|
||||
text.align = ALIGN_CENTER;
|
||||
text.CharCount = (COUNT) ~0;
|
||||
font_DrawText (&text);
|
||||
|
||||
(void) SetContextForeGroundColor (oldFgCol);
|
||||
(void) SetContextFont (oldFont);
|
||||
}
|
||||
|
||||
static void
|
||||
describeContext (FILE *out, const CONTEXT context) {
|
||||
RECT rect;
|
||||
CONTEXT oldContext = SetContext (context);
|
||||
|
||||
GetContextClipRect (&rect);
|
||||
fprintf(out, "Context '%s':\n"
|
||||
"\tClipRect = (%d, %d)-(%d, %d) (%d x %d)\n",
|
||||
GetContextName (context),
|
||||
rect.corner.x, rect.corner.y,
|
||||
rect.corner.x + rect.extent.width,
|
||||
rect.corner.y + rect.extent.height,
|
||||
rect.extent.width, rect.extent.height);
|
||||
|
||||
SetContext (oldContext);
|
||||
}
|
||||
|
||||
|
||||
typedef struct wait_state
|
||||
{
|
||||
// standard state required by DoInput
|
||||
BOOLEAN (*InputFunc) (struct wait_state *self);
|
||||
COUNT MenuRepeatDelay;
|
||||
} WAIT_STATE;
|
||||
|
||||
|
||||
// Maybe move to elsewhere, where it can be reused?
|
||||
static BOOLEAN
|
||||
waitForKey (struct wait_state *self) {
|
||||
if (PulsedInputState.menu[KEY_MENU_SELECT] ||
|
||||
PulsedInputState.menu[KEY_MENU_CANCEL])
|
||||
return FALSE;
|
||||
|
||||
SleepThread (ONE_SECOND / 20);
|
||||
|
||||
(void) self;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Maybe move to elsewhere, where it can be reused?
|
||||
static FRAME
|
||||
getScreen (void)
|
||||
{
|
||||
CONTEXT oldContext = SetContext (ScreenContext);
|
||||
FRAME savedFrame;
|
||||
RECT screenRect;
|
||||
|
||||
screenRect.corner.x = 0;
|
||||
screenRect.corner.y = 0;
|
||||
screenRect.extent.width = ScreenWidth;
|
||||
screenRect.extent.height = ScreenHeight;
|
||||
savedFrame = CaptureDrawable (LoadDisplayPixmap (&screenRect, (FRAME) 0));
|
||||
|
||||
(void) SetContext (oldContext);
|
||||
return savedFrame;
|
||||
}
|
||||
|
||||
static void
|
||||
putScreen (FRAME savedFrame) {
|
||||
STAMP stamp;
|
||||
|
||||
CONTEXT oldContext = SetContext (ScreenContext);
|
||||
|
||||
stamp.origin.x = 0;
|
||||
stamp.origin.y = 0;
|
||||
stamp.frame = savedFrame;
|
||||
DrawStamp (&stamp);
|
||||
|
||||
(void) SetContext (oldContext);
|
||||
}
|
||||
|
||||
// Show the contexts on the screen.
|
||||
// Must be called from the main thread.
|
||||
void
|
||||
debugContexts (void)
|
||||
{
|
||||
extern void arith_frame_blit (FRAME srcFrame, const RECT *rsrc,
|
||||
FRAME dstFrame, const RECT *rdst, int num, int denom);
|
||||
static volatile bool inDebugContexts = false;
|
||||
// Prevent this function from being called from within itself.
|
||||
|
||||
CONTEXT orgContext;
|
||||
CONTEXT debugDrawContext;
|
||||
// We're going to use this context to draw in.
|
||||
FRAME debugDrawFrame;
|
||||
double hueIncrement;
|
||||
size_t visibleContextI;
|
||||
CONTEXT context;
|
||||
size_t contextCount;
|
||||
FRAME savedScreen;
|
||||
|
||||
// Prevent this function from being called from within itself.
|
||||
if (inDebugContexts)
|
||||
return;
|
||||
inDebugContexts = true;
|
||||
|
||||
contextCount = countVisibleContexts ();
|
||||
if (contextCount == 0)
|
||||
goto out;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
savedScreen = getScreen ();
|
||||
//UnlockMutex (GraphicsLock);
|
||||
FlushGraphics ();
|
||||
// Make sure that the screen has actually been captured,
|
||||
// before we use the frame.
|
||||
|
||||
// Create a new frame to draw on.
|
||||
debugDrawContext = CreateContext ("debugDrawContext");
|
||||
debugDrawFrame = CaptureDrawable (CreateDrawable (
|
||||
WANT_PIXMAP /*| WANT_ALPHA*/, ScreenWidth, ScreenHeight, 1));
|
||||
orgContext = SetContext (debugDrawContext);
|
||||
SetContextFGFrame (debugDrawFrame);
|
||||
|
||||
// Fill the new frame with a copy of the original.
|
||||
arith_frame_blit (savedScreen, NULL, debugDrawFrame, NULL, 1, 1);
|
||||
|
||||
hueIncrement = 360.0 / contextCount;
|
||||
|
||||
//LockMutex (GraphicsLock);
|
||||
visibleContextI = 0;
|
||||
for (context = GetFirstContext (); context != NULL;
|
||||
context = GetNextContext (context))
|
||||
{
|
||||
if (context == debugDrawContext) {
|
||||
// Skip our own context.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isContextVisible (context))
|
||||
{
|
||||
// Only draw the visible contexts.
|
||||
drawContext (context, visibleContextI * hueIncrement);
|
||||
visibleContextI++;
|
||||
}
|
||||
|
||||
describeContext (stderr, context);
|
||||
}
|
||||
|
||||
// Blit the final debugging frame to the screen.
|
||||
putScreen (debugDrawFrame);
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
// Wait for a key:
|
||||
{
|
||||
WAIT_STATE state;
|
||||
state.InputFunc = waitForKey;
|
||||
DoInput(&state, TRUE);
|
||||
}
|
||||
|
||||
SetContext (orgContext);
|
||||
|
||||
// Destroy the debugging frame and context.
|
||||
DestroyContext (debugDrawContext);
|
||||
// This does nothing with the drawable set with
|
||||
// SetContextFGFrame().
|
||||
DestroyDrawable (ReleaseDrawable (debugDrawFrame));
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
putScreen (savedScreen);
|
||||
UnlockMutex (GraphicsLock);
|
||||
|
||||
DestroyDrawable (ReleaseDrawable (savedScreen));
|
||||
|
||||
out:
|
||||
inDebugContexts = false;
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
|
||||
+11
-1
@@ -29,9 +29,14 @@
|
||||
// functions are a no-op.
|
||||
extern BOOLEAN disableInteractivity;
|
||||
|
||||
// If a function is assigned to this, it will be called from the main loop.
|
||||
// If a function is assigned to this, it will be called from the
|
||||
// Starcon2Main thread, in the main game loop.
|
||||
extern void (* volatile debugHook) (void);
|
||||
|
||||
// If a function is assigned to this, it will be called from the
|
||||
// Starcon2Main thread, in doInput().
|
||||
extern void (* volatile doInputDebugHook) (void);
|
||||
|
||||
|
||||
// Called when the debug key (symbol 'Debug' in the keys.cfg) is pressed.
|
||||
void debugKeyPressed (void);
|
||||
@@ -180,6 +185,11 @@ extern BOOLEAN instantMove;
|
||||
void dumpStrings(FILE *out);
|
||||
|
||||
|
||||
// Graphically and textually show all the contexts.
|
||||
// Should be called from debugHook.
|
||||
void debugContexts (void);
|
||||
|
||||
|
||||
// To add some day:
|
||||
// - a function to fast forward the game clock to a specifiable time.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user