Refactored colormaps storage, management and xforms; colormaps are now stored as versioned refcounted objects and passed to rendering code by reference; SDL palettes are reset on images only when versions change; folded fades and xforms into single func; supporting several concurrent colormap xforms
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2063 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
+8
-170
@@ -55,11 +55,6 @@
|
|||||||
// XXX: was 32 picked experimentally?
|
// XXX: was 32 picked experimentally?
|
||||||
#define OSCILLOSCOPE_RATE 32
|
#define OSCILLOSCOPE_RATE 32
|
||||||
|
|
||||||
static void init_xform_control (void);
|
|
||||||
static void uninit_xform_control (void);
|
|
||||||
static void xform_complete (void);
|
|
||||||
static void xform_PLUT_step (SIZE TDelta);
|
|
||||||
static void FlushPLUTXForms (void);
|
|
||||||
static int ambient_anim_task (void *data);
|
static int ambient_anim_task (void *data);
|
||||||
|
|
||||||
static BOOLEAN getLineWithinWidth(TEXT *pText,
|
static BOOLEAN getLineWithinWidth(TEXT *pText,
|
||||||
@@ -509,177 +504,21 @@ DrawAlienFrame (FRAME aframe, PSEQUENCE pSeq)
|
|||||||
UnbatchGraphics ();
|
UnbatchGraphics ();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct xform_control
|
|
||||||
{
|
|
||||||
COLORMAPPTR CMapPtr;
|
|
||||||
SIZE Ticks, TTotal, TOrig;
|
|
||||||
UBYTE OldCMap[PLUT_BYTE_SIZE];
|
|
||||||
} XFORM_CONTROL;
|
|
||||||
|
|
||||||
#define MAX_XFORMS 32
|
|
||||||
static struct {
|
|
||||||
XFORM_CONTROL TaskControl[MAX_XFORMS];
|
|
||||||
volatile int XFormCurrent, XFormInsertPoint;
|
|
||||||
volatile BOOLEAN XFormsPending;
|
|
||||||
Mutex XFormLock;
|
|
||||||
} XFormControl;
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_xform_control (void)
|
|
||||||
{
|
|
||||||
XFormControl.XFormCurrent = XFormControl.XFormInsertPoint = 0;
|
|
||||||
XFormControl.XFormsPending = FALSE;
|
|
||||||
XFormControl.XFormLock = CreateMutex ("Transform Lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
uninit_xform_control (void)
|
|
||||||
{
|
|
||||||
DestroyMutex (XFormControl.XFormLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
xform_complete (void)
|
|
||||||
{
|
|
||||||
LockMutex (XFormControl.XFormLock);
|
|
||||||
if (XFormControl.XFormsPending)
|
|
||||||
{
|
|
||||||
SetColorMap (XFormControl.TaskControl[XFormControl.XFormCurrent].CMapPtr);
|
|
||||||
if (++XFormControl.XFormCurrent >= MAX_XFORMS)
|
|
||||||
{
|
|
||||||
XFormControl.XFormCurrent = 0;
|
|
||||||
}
|
|
||||||
if (XFormControl.XFormCurrent == XFormControl.XFormInsertPoint)
|
|
||||||
{
|
|
||||||
XFormControl.XFormsPending = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UnlockMutex (XFormControl.XFormLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
init_communication (void)
|
init_communication (void)
|
||||||
{
|
{
|
||||||
subtitle_mutex = CreateMutex ("Subtitle Lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
subtitle_mutex = CreateMutex ("Subtitle Lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||||
init_xform_control ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
uninit_communication (void)
|
uninit_communication (void)
|
||||||
{
|
{
|
||||||
DestroyMutex (subtitle_mutex);
|
DestroyMutex (subtitle_mutex);
|
||||||
uninit_xform_control ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile BOOLEAN ColorChange;
|
|
||||||
static volatile BOOLEAN SummaryChange;
|
static volatile BOOLEAN SummaryChange;
|
||||||
static volatile BOOLEAN ClearSubtitle;
|
static volatile BOOLEAN ClearSubtitle;
|
||||||
|
|
||||||
/* Only one thread should ever be allowed to be calling this at any time */
|
|
||||||
static void
|
|
||||||
xform_PLUT_step (SIZE TDelta)
|
|
||||||
{
|
|
||||||
XFORM_CONTROL *control;
|
|
||||||
COLORMAPPTR ColorMapPtr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!XFormControl.XFormsPending)
|
|
||||||
return;
|
|
||||||
|
|
||||||
control = &XFormControl.TaskControl[XFormControl.XFormCurrent];
|
|
||||||
|
|
||||||
ColorMapPtr = control->CMapPtr;
|
|
||||||
|
|
||||||
if (TDelta > control->TTotal)
|
|
||||||
TDelta = control->TTotal;
|
|
||||||
|
|
||||||
if (_varPLUTs && control->TOrig != 0)
|
|
||||||
{
|
|
||||||
#define XFORM_SCALE 0x10000
|
|
||||||
UBYTE *pCurCMap, *pOldCMap, *pNewCMap;
|
|
||||||
int frac;
|
|
||||||
|
|
||||||
pCurCMap = GET_VAR_PLUT (*ColorMapPtr);
|
|
||||||
pOldCMap = control->OldCMap;
|
|
||||||
pNewCMap = (UBYTE*)ColorMapPtr + 2;
|
|
||||||
|
|
||||||
frac = (int)(control->TOrig - control->TTotal) * XFORM_SCALE
|
|
||||||
/ control->TOrig;
|
|
||||||
|
|
||||||
for (i = 0; i < PLUT_BYTE_SIZE; i++)
|
|
||||||
{
|
|
||||||
*pCurCMap = (UBYTE)(*pOldCMap + ((int)*pNewCMap - *pOldCMap)
|
|
||||||
* frac / XFORM_SCALE);
|
|
||||||
pOldCMap++;
|
|
||||||
pCurCMap++;
|
|
||||||
pNewCMap++;
|
|
||||||
}
|
|
||||||
ColorChange = TRUE;
|
|
||||||
}
|
|
||||||
else if (control->TOrig == 0)
|
|
||||||
{ // asked for immediate xform
|
|
||||||
ColorChange = TRUE;
|
|
||||||
}
|
|
||||||
control->TTotal -= TDelta;
|
|
||||||
if (!control->TTotal)
|
|
||||||
{
|
|
||||||
xform_complete ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This should be thread-safe without locking the XFormControl because
|
|
||||||
* only one thread should be Flushing at any given time, constant
|
|
||||||
* writes are atomic anyway, and Flush is the only routine that writes
|
|
||||||
* XFormFlush. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
FlushPLUTXForms (void)
|
|
||||||
{
|
|
||||||
while (XFormControl.XFormsPending)
|
|
||||||
{
|
|
||||||
xform_complete ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
XFormPLUT (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
|
|
||||||
{
|
|
||||||
if (ColorMapPtr)
|
|
||||||
{
|
|
||||||
XFORM_CONTROL *control;
|
|
||||||
|
|
||||||
// FlushPLUTXForms ();
|
|
||||||
|
|
||||||
LockMutex (XFormControl.XFormLock);
|
|
||||||
while (XFormControl.XFormsPending
|
|
||||||
&& (XFormControl.XFormInsertPoint == XFormControl.XFormCurrent))
|
|
||||||
{
|
|
||||||
UnlockMutex (XFormControl.XFormLock);
|
|
||||||
FlushPLUTXForms ();
|
|
||||||
LockMutex (XFormControl.XFormLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
control = &XFormControl.TaskControl[XFormControl.XFormInsertPoint];
|
|
||||||
|
|
||||||
memcpy (control->OldCMap, GET_VAR_PLUT (*ColorMapPtr), PLUT_BYTE_SIZE);
|
|
||||||
|
|
||||||
control->CMapPtr = ColorMapPtr;
|
|
||||||
if ((control->Ticks = TimeInterval) <= 0)
|
|
||||||
control->Ticks = 1; /* prevent divide by zero and negative fade */
|
|
||||||
control->TTotal = control->TOrig = TimeInterval;
|
|
||||||
|
|
||||||
if (++XFormControl.XFormInsertPoint >= MAX_XFORMS)
|
|
||||||
XFormControl.XFormInsertPoint = 0;
|
|
||||||
|
|
||||||
XFormControl.XFormsPending = TRUE;
|
|
||||||
|
|
||||||
UnlockMutex (XFormControl.XFormLock);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
RefreshResponses (PENCOUNTER_STATE pES)
|
RefreshResponses (PENCOUNTER_STATE pES)
|
||||||
{
|
{
|
||||||
@@ -867,6 +706,7 @@ ambient_anim_task (void *data)
|
|||||||
BOOLEAN TransitionDone = FALSE;
|
BOOLEAN TransitionDone = FALSE;
|
||||||
BOOLEAN TalkFrameChanged = FALSE;
|
BOOLEAN TalkFrameChanged = FALSE;
|
||||||
BOOLEAN FrameChanged[MAX_ANIMATIONS];
|
BOOLEAN FrameChanged[MAX_ANIMATIONS];
|
||||||
|
BOOLEAN ColorChange = FALSE;
|
||||||
|
|
||||||
while ((CommFrame = CommData.AlienFrame) == 0 && !Task_ReadState (task, TASK_EXIT))
|
while ((CommFrame = CommData.AlienFrame) == 0 && !Task_ReadState (task, TASK_EXIT))
|
||||||
TaskSwitch ();
|
TaskSwitch ();
|
||||||
@@ -963,7 +803,7 @@ ambient_anim_task (void *data)
|
|||||||
|
|
||||||
if (pSeq->AnimType == COLOR_ANIM)
|
if (pSeq->AnimType == COLOR_ANIM)
|
||||||
{
|
{
|
||||||
XFormPLUT (
|
XFormColorMap (
|
||||||
GetColorMapAddress (pSeq->AnimObj.CurCMap),
|
GetColorMapAddress (pSeq->AnimObj.CurCMap),
|
||||||
(COUNT) (pSeq->Alarm - 1)
|
(COUNT) (pSeq->Alarm - 1)
|
||||||
);
|
);
|
||||||
@@ -1208,7 +1048,7 @@ ambient_anim_task (void *data)
|
|||||||
if (!summary)
|
if (!summary)
|
||||||
{
|
{
|
||||||
CONTEXT OldContext;
|
CONTEXT OldContext;
|
||||||
BOOLEAN CheckSub = 0;
|
BOOLEAN CheckSub = FALSE;
|
||||||
BOOLEAN ClearSub;
|
BOOLEAN ClearSub;
|
||||||
int sub_state;
|
int sub_state;
|
||||||
|
|
||||||
@@ -1228,8 +1068,8 @@ ambient_anim_task (void *data)
|
|||||||
CommData.AlienFrame = CommFrame;
|
CommData.AlienFrame = CommFrame;
|
||||||
DrawAlienFrame (TalkFrame, &Sequencer[CommData.NumAnimations - 1]);
|
DrawAlienFrame (TalkFrame, &Sequencer[CommData.NumAnimations - 1]);
|
||||||
CommData.AlienFrame = F;
|
CommData.AlienFrame = F;
|
||||||
CheckSub = 1;
|
CheckSub = TRUE;
|
||||||
ClearSub = SummaryChange ? TRUE : FALSE;
|
ClearSub = SummaryChange;
|
||||||
ColorChange = SummaryChange = FALSE;
|
ColorChange = SummaryChange = FALSE;
|
||||||
}
|
}
|
||||||
if (Change || ClearSub)
|
if (Change || ClearSub)
|
||||||
@@ -1270,7 +1110,7 @@ ambient_anim_task (void *data)
|
|||||||
TalkFrameChanged = FALSE;
|
TalkFrameChanged = FALSE;
|
||||||
}
|
}
|
||||||
Change = FALSE;
|
Change = FALSE;
|
||||||
CheckSub = 1;
|
CheckSub = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optSubtitles && CheckSub && sub_state >= SPACE_SUBTITLE)
|
if (optSubtitles && CheckSub && sub_state >= SPACE_SUBTITLE)
|
||||||
@@ -1290,7 +1130,7 @@ ambient_anim_task (void *data)
|
|||||||
}
|
}
|
||||||
UnbatchGraphics ();
|
UnbatchGraphics ();
|
||||||
UnlockMutex (GraphicsLock);
|
UnlockMutex (GraphicsLock);
|
||||||
xform_PLUT_step(ElapsedTicks);
|
ColorChange = XFormColorMap_step ();
|
||||||
}
|
}
|
||||||
FinishTask (task);
|
FinishTask (task);
|
||||||
return(0);
|
return(0);
|
||||||
@@ -1914,11 +1754,9 @@ DoCommunication (PENCOUNTER_STATE pES)
|
|||||||
|
|
||||||
UnlockMutex (GraphicsLock);
|
UnlockMutex (GraphicsLock);
|
||||||
|
|
||||||
FlushPLUTXForms ();
|
FlushColorXForms ();
|
||||||
ColorChange = FALSE;
|
|
||||||
ClearSubtitle = FALSE;
|
ClearSubtitle = FALSE;
|
||||||
|
|
||||||
FlushColorXForms ();
|
|
||||||
StopMusic ();
|
StopMusic ();
|
||||||
StopSound ();
|
StopSound ();
|
||||||
StopTrack ();
|
StopTrack ();
|
||||||
|
|||||||
@@ -588,7 +588,7 @@ GiveRadios (RESPONSE_REF R)
|
|||||||
CommData.AlienAmbientArray[2].AnimFlags |= ANIM_DISABLED;
|
CommData.AlienAmbientArray[2].AnimFlags |= ANIM_DISABLED;
|
||||||
UnlockMutex (GraphicsLock);
|
UnlockMutex (GraphicsLock);
|
||||||
|
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
|
|
||||||
|
|||||||
@@ -1342,7 +1342,7 @@ NatureOfConversation (RESPONSE_REF R)
|
|||||||
/* Melnorme reports any news and turns purple */
|
/* Melnorme reports any news and turns purple */
|
||||||
NPCPhrase (BUY_OR_SELL);
|
NPCPhrase (BUY_OR_SELL);
|
||||||
AlienTalkSegue(1);
|
AlienTalkSegue(1);
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
AlienTalkSegue((COUNT)~0);
|
AlienTalkSegue((COUNT)~0);
|
||||||
@@ -1432,7 +1432,7 @@ DoBluster (RESPONSE_REF R)
|
|||||||
|
|
||||||
if (PLAYER_SAID (R, trade_is_for_the_weak))
|
if (PLAYER_SAID (R, trade_is_for_the_weak))
|
||||||
{
|
{
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
|
|
||||||
@@ -1629,7 +1629,7 @@ DoFirstMeeting (RESPONSE_REF R)
|
|||||||
}
|
}
|
||||||
else if (PLAYER_SAID (R, yes_really_testing))
|
else if (PLAYER_SAID (R, yes_really_testing))
|
||||||
{
|
{
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
|
|
||||||
@@ -1638,7 +1638,7 @@ DoFirstMeeting (RESPONSE_REF R)
|
|||||||
else if (PLAYER_SAID (R, we_apologize))
|
else if (PLAYER_SAID (R, we_apologize))
|
||||||
{
|
{
|
||||||
SET_GAME_STATE (MELNORME_ANGER, 0);
|
SET_GAME_STATE (MELNORME_ANGER, 0);
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
|
|
||||||
@@ -1677,7 +1677,7 @@ DoMelnormeMiffed (RESPONSE_REF R)
|
|||||||
}
|
}
|
||||||
SET_GAME_STATE (MELNORME_MIFFED_COUNT, miffed_count);
|
SET_GAME_STATE (MELNORME_MIFFED_COUNT, miffed_count);
|
||||||
|
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
}
|
}
|
||||||
@@ -1749,7 +1749,7 @@ DoMelnormePissed (RESPONSE_REF R)
|
|||||||
}
|
}
|
||||||
SET_GAME_STATE (MELNORME_PISSED_COUNT, pissed_count);
|
SET_GAME_STATE (MELNORME_PISSED_COUNT, pissed_count);
|
||||||
|
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
}
|
}
|
||||||
@@ -1804,7 +1804,7 @@ DoMelnormeHate (RESPONSE_REF R)
|
|||||||
}
|
}
|
||||||
SET_GAME_STATE (MELNORME_HATE_COUNT, hate_count);
|
SET_GAME_STATE (MELNORME_HATE_COUNT, hate_count);
|
||||||
|
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 2)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
|
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ ExitConversation (RESPONSE_REF R)
|
|||||||
if (PLAYER_SAID (R, about_andro_3))
|
if (PLAYER_SAID (R, about_andro_3))
|
||||||
ActivateStarShip (ORZ_SHIP, -1);
|
ActivateStarShip (ORZ_SHIP, -1);
|
||||||
|
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -575,7 +575,7 @@ AllianceOffer (RESPONSE_REF R)
|
|||||||
if (PLAYER_SAID (R, misunderstanding))
|
if (PLAYER_SAID (R, misunderstanding))
|
||||||
{
|
{
|
||||||
NPCPhrase (JUST_MISUNDERSTANDING);
|
NPCPhrase (JUST_MISUNDERSTANDING);
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
||||||
), ONE_SECOND / 4);
|
), ONE_SECOND / 4);
|
||||||
|
|
||||||
@@ -753,7 +753,7 @@ SpathiCouncil (RESPONSE_REF R)
|
|||||||
else if (PLAYER_SAID (R, good_password))
|
else if (PLAYER_SAID (R, good_password))
|
||||||
{
|
{
|
||||||
NPCPhrase (YES_GOOD_PASSWORD);
|
NPCPhrase (YES_GOOD_PASSWORD);
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
||||||
), ONE_SECOND / 4);
|
), ONE_SECOND / 4);
|
||||||
|
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ FriendlyExit (RESPONSE_REF R)
|
|||||||
|
|
||||||
AlienTalkSegue (1);
|
AlienTalkSegue (1);
|
||||||
AlienTalkSegue (2);
|
AlienTalkSegue (2);
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
||||||
), ONE_SECOND / 2);
|
), ONE_SECOND / 2);
|
||||||
AlienTalkSegue ((COUNT)~0);
|
AlienTalkSegue ((COUNT)~0);
|
||||||
@@ -279,7 +279,7 @@ Foreplay (RESPONSE_REF R)
|
|||||||
NPCPhrase (ABOUT_US);
|
NPCPhrase (ABOUT_US);
|
||||||
NPCPhrase (MORE_COMFORTABLE);
|
NPCPhrase (MORE_COMFORTABLE);
|
||||||
AlienTalkSegue (1);
|
AlienTalkSegue (1);
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
||||||
), ONE_SECOND);
|
), ONE_SECOND);
|
||||||
AlienTalkSegue ((COUNT)~0);
|
AlienTalkSegue ((COUNT)~0);
|
||||||
|
|||||||
@@ -264,11 +264,11 @@ MindControlStrobe (void)
|
|||||||
|
|
||||||
for (i = 0; i < NUM_STROBES; ++i)
|
for (i = 0; i < NUM_STROBES; ++i)
|
||||||
{
|
{
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
||||||
), 0);
|
), 0);
|
||||||
SleepThread (ONE_SECOND / (STROBE_RATE * 2));
|
SleepThread (ONE_SECOND / (STROBE_RATE * 2));
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 0)
|
||||||
), 0);
|
), 0);
|
||||||
SleepThread (ONE_SECOND / (STROBE_RATE * 2));
|
SleepThread (ONE_SECOND / (STROBE_RATE * 2));
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ CombatIsInevitable (RESPONSE_REF R)
|
|||||||
NPCPhrase (FOOL_AIEE1);
|
NPCPhrase (FOOL_AIEE1);
|
||||||
|
|
||||||
AlienTalkSegue (1);
|
AlienTalkSegue (1);
|
||||||
XFormPLUT (GetColorMapAddress (
|
XFormColorMap (GetColorMapAddress (
|
||||||
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
SetAbsColorMapIndex (CommData.AlienColorMap, 1)
|
||||||
), ONE_SECOND / 4);
|
), ONE_SECOND / 4);
|
||||||
AlienTalkSegue ((COUNT)~0);
|
AlienTalkSegue ((COUNT)~0);
|
||||||
|
|||||||
@@ -126,7 +126,5 @@ extern LOCDATAPTR init_zoqfot_comm (void);
|
|||||||
|
|
||||||
extern LOCDATAPTR init_umgah_comm (void);
|
extern LOCDATAPTR init_umgah_comm (void);
|
||||||
|
|
||||||
extern DWORD XFormPLUT (COLORMAPPTR ColorMapPtr, SIZE TimeInterval);
|
|
||||||
|
|
||||||
#endif /* _COMMGLUE_H */
|
#endif /* _COMMGLUE_H */
|
||||||
|
|
||||||
|
|||||||
@@ -30,37 +30,222 @@ static struct
|
|||||||
COUNT NumCycles;
|
COUNT NumCycles;
|
||||||
Task XFormTask;
|
Task XFormTask;
|
||||||
} tc;
|
} tc;
|
||||||
} TaskControl;
|
} FadeControl;
|
||||||
|
|
||||||
|
typedef struct xform_control
|
||||||
|
{
|
||||||
|
int CMapIndex; // -1 means unused
|
||||||
|
COLORMAPPTR CMapPtr;
|
||||||
|
SIZE Ticks;
|
||||||
|
DWORD StartTime;
|
||||||
|
DWORD EndTime;
|
||||||
|
TFB_Palette OldCMap[NUMBER_OF_PLUTVALS];
|
||||||
|
} XFORM_CONTROL;
|
||||||
|
|
||||||
|
#define MAX_XFORMS 16
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
XFORM_CONTROL TaskControl[MAX_XFORMS];
|
||||||
|
volatile int Highest;
|
||||||
|
// 'pending' is Highest >= 0
|
||||||
|
Mutex Lock;
|
||||||
|
} XFormControl;
|
||||||
|
|
||||||
volatile int FadeAmount = FADE_NORMAL_INTENSITY;
|
volatile int FadeAmount = FADE_NORMAL_INTENSITY;
|
||||||
static volatile int end, XForming;
|
static volatile int FadeEnd, XForming;
|
||||||
|
|
||||||
UBYTE* _varPLUTs;
|
#define SPARE_COLORMAPS 20
|
||||||
static unsigned int varPLUTsize = 0;
|
#define MAP_POOL_SIZE (MAX_COLORMAPS + SPARE_COLORMAPS)
|
||||||
|
|
||||||
|
static TFB_ColorMap mappool[MAP_POOL_SIZE];
|
||||||
|
static TFB_ColorMap *poolhead;
|
||||||
|
|
||||||
|
static TFB_ColorMap * colormaps[MAX_COLORMAPS];
|
||||||
|
static int mapcount;
|
||||||
|
Mutex maplock;
|
||||||
|
|
||||||
|
|
||||||
void TFB_ColorMapToRGB (TFB_Palette *pal, int colormap_index)
|
void
|
||||||
|
InitColorMaps (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
UBYTE *colors;
|
|
||||||
|
|
||||||
colors = GET_VAR_PLUT (colormap_index);
|
// init colormaps
|
||||||
|
maplock = CreateMutex ("Colormaps Lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||||
|
// init static pool
|
||||||
|
for (i = 0; i < MAP_POOL_SIZE - 1; ++i)
|
||||||
|
mappool[i].next = mappool + i + 1;
|
||||||
|
mappool[i].next = NULL;
|
||||||
|
poolhead = mappool;
|
||||||
|
|
||||||
for (i = 0; i < NUMBER_OF_PLUTVALS; i++)
|
// init xform control
|
||||||
|
XFormControl.Highest = -1;
|
||||||
|
XFormControl.Lock = CreateMutex ("Transform Lock", SYNC_CLASS_TOPLEVEL | SYNC_CLASS_VIDEO);
|
||||||
|
for (i = 0; i < MAX_XFORMS; ++i)
|
||||||
|
XFormControl.TaskControl[i].CMapIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UninitColorMaps (void)
|
||||||
|
{
|
||||||
|
// uninit xform control
|
||||||
|
DestroyMutex (XFormControl.Lock);
|
||||||
|
|
||||||
|
// uninit colormaps
|
||||||
|
DestroyMutex (maplock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TFB_ColorMap *
|
||||||
|
alloc_colormap (void)
|
||||||
|
// returns an addrefed object
|
||||||
|
{
|
||||||
|
TFB_ColorMap *map;
|
||||||
|
|
||||||
|
if (!poolhead)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
map = poolhead;
|
||||||
|
poolhead = map->next;
|
||||||
|
|
||||||
|
map->next = NULL;
|
||||||
|
map->index = -1;
|
||||||
|
map->refcount = 1;
|
||||||
|
map->version = 0;
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static TFB_ColorMap *
|
||||||
|
clone_colormap (TFB_ColorMap *from, int index)
|
||||||
|
// returns an addrefed object
|
||||||
|
{
|
||||||
|
TFB_ColorMap *map;
|
||||||
|
|
||||||
|
map = alloc_colormap ();
|
||||||
|
if (!map)
|
||||||
{
|
{
|
||||||
pal[i].r = *colors++;
|
static DWORD NextTime = 0;
|
||||||
pal[i].g = *colors++;
|
DWORD Now;
|
||||||
pal[i].b = *colors++;
|
|
||||||
|
if (!from)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "FATAL: clone_colormap(): no maps available\n");
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
Now = GetTimeCounter ();
|
||||||
|
if (Now >= NextTime)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "clone_colormap(): static pool exhausted\n");
|
||||||
|
NextTime = Now + ONE_SECOND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just overwrite the current one -- better than aborting
|
||||||
|
map = from;
|
||||||
|
from->refcount++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{ // fresh new map
|
||||||
|
map->index = index;
|
||||||
|
if (from)
|
||||||
|
map->version = from->version;
|
||||||
|
}
|
||||||
|
map->version++;
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
free_colormap (TFB_ColorMap *map)
|
||||||
|
{
|
||||||
|
if (!map)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "free_colormap(): tried to free a NULL map\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map->next = poolhead;
|
||||||
|
poolhead = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TFB_ColorMap *
|
||||||
|
get_colormap (int index)
|
||||||
|
{
|
||||||
|
TFB_ColorMap *map;
|
||||||
|
|
||||||
|
map = colormaps[index];
|
||||||
|
if (!map)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "BUG: get_colormap(): map not present\n");
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
map->refcount++;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
release_colormap (TFB_ColorMap *map)
|
||||||
|
{
|
||||||
|
if (!map)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (map->refcount <= 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "BUG: release_colormap(): refcount not >0\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
map->refcount--;
|
||||||
|
if (map->refcount == 0)
|
||||||
|
free_colormap (map);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TFB_ReturnColorMap (TFB_ColorMap *map)
|
||||||
|
{
|
||||||
|
LockMutex (maplock);
|
||||||
|
release_colormap (map);
|
||||||
|
UnlockMutex (maplock);
|
||||||
|
}
|
||||||
|
|
||||||
|
TFB_ColorMap *
|
||||||
|
TFB_GetColorMap (int index)
|
||||||
|
{
|
||||||
|
TFB_ColorMap *map;
|
||||||
|
|
||||||
|
LockMutex (maplock);
|
||||||
|
map = get_colormap (index);
|
||||||
|
UnlockMutex (maplock);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TFB_ColorMapToRGB (TFB_Palette *pal, int index)
|
||||||
|
{
|
||||||
|
TFB_ColorMap *map = NULL;
|
||||||
|
|
||||||
|
if (index < mapcount)
|
||||||
|
map = colormaps[index];
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "TFB_ColorMapToRGB(): "
|
||||||
|
"requested non-present colormap %d\n", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (pal, map->colors, sizeof (map->colors));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
SetColorMap (COLORMAPPTR map)
|
SetColorMap (COLORMAPPTR map)
|
||||||
{
|
{
|
||||||
int start, end;
|
int start, end;
|
||||||
DWORD size, total_size;
|
int total_size;
|
||||||
UBYTE *colors = (UBYTE*)map;
|
UBYTE *colors = (UBYTE*)map;
|
||||||
UBYTE *vp;
|
TFB_ColorMap **mpp;
|
||||||
|
|
||||||
if (!map)
|
if (!map)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -68,46 +253,77 @@ SetColorMap (COLORMAPPTR map)
|
|||||||
start = *colors++;
|
start = *colors++;
|
||||||
end = *colors++;
|
end = *colors++;
|
||||||
if (start > end)
|
if (start > end)
|
||||||
return TRUE;
|
{
|
||||||
|
fprintf (stderr, "ERROR: SetColorMap(): "
|
||||||
size = (end - start + 1) * PLUT_BYTE_SIZE;
|
"starting map (%d) not less or eq ending (%d)\n",
|
||||||
total_size = (end + 1) * PLUT_BYTE_SIZE;
|
start, end);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (start >= MAX_COLORMAPS)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "ERROR: SetColorMap(): "
|
||||||
|
"starting map (%d) beyond range (0-%d)\n",
|
||||||
|
start, (int)MAX_COLORMAPS - 1);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (end >= MAX_COLORMAPS)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "SetColorMap(): "
|
||||||
|
"ending map (%d) beyond range (0-%d)\n",
|
||||||
|
end, (int)MAX_COLORMAPS - 1);
|
||||||
|
end = MAX_COLORMAPS - 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_varPLUTs)
|
total_size = end + 1;
|
||||||
{
|
|
||||||
_varPLUTs = (UBYTE *) HMalloc (total_size);
|
LockMutex (maplock);
|
||||||
varPLUTsize = total_size;
|
|
||||||
}
|
if (total_size > mapcount)
|
||||||
else if (total_size > varPLUTsize)
|
mapcount = total_size;
|
||||||
{
|
|
||||||
_varPLUTs = (UBYTE *) HRealloc (_varPLUTs, total_size);
|
|
||||||
varPLUTsize = total_size;
|
|
||||||
}
|
|
||||||
if (!_varPLUTs)
|
|
||||||
{
|
|
||||||
varPLUTsize = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
vp = GET_VAR_PLUT (start);
|
// parse the supplied PLUTs into our colormaps
|
||||||
memcpy (vp, colors, size);
|
for (mpp = colormaps + start; start <= end; ++start, ++mpp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
TFB_Palette *pal;
|
||||||
|
TFB_ColorMap *newmap;
|
||||||
|
TFB_ColorMap *oldmap;
|
||||||
|
|
||||||
|
oldmap = *mpp;
|
||||||
|
newmap = clone_colormap (oldmap, start);
|
||||||
|
|
||||||
|
for (i = 0, pal = newmap->colors; i < NUMBER_OF_PLUTVALS; ++i, ++pal)
|
||||||
|
{
|
||||||
|
pal->r = *colors++;
|
||||||
|
pal->g = *colors++;
|
||||||
|
pal->b = *colors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*mpp = newmap;
|
||||||
|
release_colormap (oldmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnlockMutex (maplock);
|
||||||
|
|
||||||
//fprintf (stderr, "SetColorMap(): vp %x map %x bytes %d, start %d end %d\n", vp, map, bytes, start, end);
|
//fprintf (stderr, "SetColorMap(): vp %x map %x bytes %d, start %d end %d\n", vp, map, bytes, start, end);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fade Transforms */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xform_clut_task (void *data)
|
fade_xform_task (void *data)
|
||||||
{
|
{
|
||||||
SIZE TDelta, TTotal;
|
SIZE TDelta, TTotal;
|
||||||
DWORD CurTime;
|
DWORD CurTime;
|
||||||
Task task = (Task)data;
|
Task task = (Task)data;
|
||||||
|
|
||||||
XForming = TRUE;
|
XForming = TRUE;
|
||||||
while (TaskControl.tc.XFormTask == 0 && (!Task_ReadState (task, TASK_EXIT)))
|
while (FadeControl.tc.XFormTask == 0
|
||||||
|
&& (!Task_ReadState (task, TASK_EXIT)))
|
||||||
TaskSwitch ();
|
TaskSwitch ();
|
||||||
TTotal = TaskControl.Ticks;
|
TTotal = FadeControl.Ticks;
|
||||||
TaskControl.tc.XFormTask = 0;
|
FadeControl.tc.XFormTask = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
CurTime = GetTimeCounter ();
|
CurTime = GetTimeCounter ();
|
||||||
@@ -121,8 +337,8 @@ xform_clut_task (void *data)
|
|||||||
if (!XForming || (TDelta = (SIZE)(CurTime - StartTime)) > TTotal)
|
if (!XForming || (TDelta = (SIZE)(CurTime - StartTime)) > TTotal)
|
||||||
TDelta = TTotal;
|
TDelta = TTotal;
|
||||||
|
|
||||||
FadeAmount += (end - FadeAmount) * TDelta / TTotal;
|
FadeAmount += (FadeEnd - FadeAmount) * TDelta / TTotal;
|
||||||
//fprintf (stderr, "xform_clut_task FadeAmount %d\n", FadeAmount);
|
//fprintf (stderr, "fade_xform_task FadeAmount %d\n", FadeAmount);
|
||||||
} while ((TTotal -= TDelta) && (!Task_ReadState (task, TASK_EXIT)));
|
} while ((TTotal -= TDelta) && (!Task_ReadState (task, TASK_EXIT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,58 +348,8 @@ xform_clut_task (void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
static void
|
||||||
XFormColorMap (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
|
FlushFadeXForms (void)
|
||||||
{
|
|
||||||
BYTE what;
|
|
||||||
DWORD TimeOut;
|
|
||||||
|
|
||||||
FlushColorXForms ();
|
|
||||||
|
|
||||||
if (ColorMapPtr == (COLORMAPPTR)0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
what = *ColorMapPtr;
|
|
||||||
switch (what)
|
|
||||||
{
|
|
||||||
case FadeAllToBlack:
|
|
||||||
case FadeSomeToBlack:
|
|
||||||
end = FADE_NO_INTENSITY;
|
|
||||||
break;
|
|
||||||
case FadeAllToColor:
|
|
||||||
case FadeSomeToColor:
|
|
||||||
end = FADE_NORMAL_INTENSITY;
|
|
||||||
break;
|
|
||||||
case FadeAllToWhite:
|
|
||||||
case FadeSomeToWhite:
|
|
||||||
end = FADE_FULL_INTENSITY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return (GetTimeCounter ());
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskControl.Ticks = TimeInterval;
|
|
||||||
if (TaskControl.Ticks <= 0 ||
|
|
||||||
(TaskControl.tc.XFormTask = AssignTask (xform_clut_task,
|
|
||||||
1024, "transform colormap")) == 0)
|
|
||||||
{
|
|
||||||
FadeAmount = end;
|
|
||||||
TimeOut = GetTimeCounter ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do
|
|
||||||
TaskSwitch ();
|
|
||||||
while (TaskControl.tc.XFormTask);
|
|
||||||
|
|
||||||
TimeOut = GetTimeCounter () + TimeInterval + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (TimeOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FlushColorXForms()
|
|
||||||
{
|
{
|
||||||
if (XForming)
|
if (XForming)
|
||||||
{
|
{
|
||||||
@@ -191,3 +357,266 @@ FlushColorXForms()
|
|||||||
TaskSwitch ();
|
TaskSwitch ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD
|
||||||
|
XFormFade (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
|
||||||
|
{
|
||||||
|
BYTE what;
|
||||||
|
DWORD TimeOut;
|
||||||
|
|
||||||
|
FlushFadeXForms ();
|
||||||
|
|
||||||
|
what = *ColorMapPtr;
|
||||||
|
switch (what)
|
||||||
|
{
|
||||||
|
case FadeAllToBlack:
|
||||||
|
case FadeSomeToBlack:
|
||||||
|
FadeEnd = FADE_NO_INTENSITY;
|
||||||
|
break;
|
||||||
|
case FadeAllToColor:
|
||||||
|
case FadeSomeToColor:
|
||||||
|
FadeEnd = FADE_NORMAL_INTENSITY;
|
||||||
|
break;
|
||||||
|
case FadeAllToWhite:
|
||||||
|
case FadeSomeToWhite:
|
||||||
|
FadeEnd = FADE_FULL_INTENSITY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (GetTimeCounter ());
|
||||||
|
}
|
||||||
|
|
||||||
|
FadeControl.Ticks = TimeInterval;
|
||||||
|
if (FadeControl.Ticks <= 0 ||
|
||||||
|
(FadeControl.tc.XFormTask = AssignTask (fade_xform_task,
|
||||||
|
1024, "fade transform")) == 0)
|
||||||
|
{
|
||||||
|
FadeAmount = FadeEnd;
|
||||||
|
TimeOut = GetTimeCounter ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
TaskSwitch ();
|
||||||
|
while (FadeControl.tc.XFormTask);
|
||||||
|
|
||||||
|
TimeOut = GetTimeCounter () + TimeInterval + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TimeOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Colormap Transforms */
|
||||||
|
|
||||||
|
static void
|
||||||
|
finish_colormap_xform (int which)
|
||||||
|
{
|
||||||
|
SetColorMap (XFormControl.TaskControl[which].CMapPtr);
|
||||||
|
XFormControl.TaskControl[which].CMapIndex = -1;
|
||||||
|
// check Highest ptr
|
||||||
|
if (which == XFormControl.Highest)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
--which;
|
||||||
|
while (which >= 0 && XFormControl.TaskControl[which].CMapIndex == -1);
|
||||||
|
|
||||||
|
XFormControl.Highest = which;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This gives the XFormColorMap task a timeslice to do its thing
|
||||||
|
* Only one thread should ever be allowed to be calling this at any time
|
||||||
|
*/
|
||||||
|
BOOLEAN
|
||||||
|
XFormColorMap_step ()
|
||||||
|
{
|
||||||
|
BOOLEAN Changed = FALSE;
|
||||||
|
int x;
|
||||||
|
DWORD Now = GetTimeCounter ();
|
||||||
|
|
||||||
|
LockMutex (XFormControl.Lock);
|
||||||
|
|
||||||
|
for (x = 0; x <= XFormControl.Highest; ++x)
|
||||||
|
{
|
||||||
|
XFORM_CONTROL *control = &XFormControl.TaskControl[x];
|
||||||
|
int index = control->CMapIndex;
|
||||||
|
int TicksLeft = control->EndTime - Now;
|
||||||
|
TFB_ColorMap *curmap;
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
continue; // unused slot
|
||||||
|
|
||||||
|
LockMutex (maplock);
|
||||||
|
|
||||||
|
curmap = colormaps[index];
|
||||||
|
if (!curmap)
|
||||||
|
{
|
||||||
|
UnlockMutex (maplock);
|
||||||
|
fprintf (stderr, "BUG: XFormColorMap_step(): no current map\n");
|
||||||
|
finish_colormap_xform (x);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TicksLeft > 0)
|
||||||
|
{
|
||||||
|
#define XFORM_SCALE 0x10000
|
||||||
|
TFB_ColorMap *newmap = NULL;
|
||||||
|
UBYTE *pNewCMap;
|
||||||
|
TFB_Palette *pCurCMap, *pOldCMap;
|
||||||
|
int frac;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
newmap = clone_colormap (curmap, index);
|
||||||
|
|
||||||
|
pCurCMap = newmap->colors;
|
||||||
|
pOldCMap = control->OldCMap;
|
||||||
|
pNewCMap = (UBYTE*)control->CMapPtr + 2;
|
||||||
|
|
||||||
|
frac = (int)(control->Ticks - TicksLeft) * XFORM_SCALE
|
||||||
|
/ control->Ticks;
|
||||||
|
|
||||||
|
for (i = 0; i < NUMBER_OF_PLUTVALS; i++, ++pCurCMap, ++pOldCMap)
|
||||||
|
{
|
||||||
|
|
||||||
|
pCurCMap->r = (UBYTE)(pOldCMap->r + ((int)*pNewCMap - pOldCMap->r)
|
||||||
|
* frac / XFORM_SCALE);
|
||||||
|
pNewCMap++;
|
||||||
|
|
||||||
|
pCurCMap->g = (UBYTE)(pOldCMap->g + ((int)*pNewCMap - pOldCMap->g)
|
||||||
|
* frac / XFORM_SCALE);
|
||||||
|
pNewCMap++;
|
||||||
|
|
||||||
|
pCurCMap->b = (UBYTE)(pOldCMap->b + ((int)*pNewCMap - pOldCMap->b)
|
||||||
|
* frac / XFORM_SCALE);
|
||||||
|
pNewCMap++;
|
||||||
|
}
|
||||||
|
|
||||||
|
colormaps[index] = newmap;
|
||||||
|
release_colormap (curmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnlockMutex (maplock);
|
||||||
|
|
||||||
|
if (TicksLeft <= 0)
|
||||||
|
{ // asked for immediate xform or already done
|
||||||
|
finish_colormap_xform (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
Changed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnlockMutex (XFormControl.Lock);
|
||||||
|
|
||||||
|
return Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FlushPLUTXForms (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
LockMutex (XFormControl.Lock);
|
||||||
|
|
||||||
|
for (i = 0; i <= XFormControl.Highest; ++i)
|
||||||
|
{
|
||||||
|
if (XFormControl.TaskControl[i].CMapIndex >= 0)
|
||||||
|
finish_colormap_xform (i);
|
||||||
|
}
|
||||||
|
XFormControl.Highest = -1; // all gone
|
||||||
|
|
||||||
|
UnlockMutex (XFormControl.Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD
|
||||||
|
XFormPLUT (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
|
||||||
|
{
|
||||||
|
TFB_ColorMap *map;
|
||||||
|
XFORM_CONTROL *control;
|
||||||
|
int index;
|
||||||
|
int x;
|
||||||
|
int first_avail = -1;
|
||||||
|
DWORD EndTime;
|
||||||
|
DWORD Now;
|
||||||
|
|
||||||
|
Now = GetTimeCounter ();
|
||||||
|
index = *ColorMapPtr;
|
||||||
|
|
||||||
|
LockMutex (XFormControl.Lock);
|
||||||
|
// Find an available slot, or reuse if required
|
||||||
|
for (x = 0; x <= XFormControl.Highest
|
||||||
|
&& index != XFormControl.TaskControl[x].CMapIndex;
|
||||||
|
++x)
|
||||||
|
{
|
||||||
|
if (first_avail == -1 && XFormControl.TaskControl[x].CMapIndex == -1)
|
||||||
|
first_avail = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == XFormControl.TaskControl[x].CMapIndex)
|
||||||
|
{ // already xforming this colormap -- cancel and reuse slot
|
||||||
|
finish_colormap_xform (x);
|
||||||
|
}
|
||||||
|
else if (first_avail >= 0)
|
||||||
|
{ // picked up a slot along the way
|
||||||
|
x = first_avail;
|
||||||
|
}
|
||||||
|
else if (x >= MAX_XFORMS)
|
||||||
|
{ // flush some xforms if the queue is full
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf (stderr, "WARNING: XFormPLUT(): no slots available\n");
|
||||||
|
#endif
|
||||||
|
x = XFormControl.Highest;
|
||||||
|
finish_colormap_xform (x);
|
||||||
|
}
|
||||||
|
// take next unused one
|
||||||
|
control = &XFormControl.TaskControl[x];
|
||||||
|
if (x > XFormControl.Highest)
|
||||||
|
XFormControl.Highest = x;
|
||||||
|
|
||||||
|
// make a copy of the current map
|
||||||
|
LockMutex (maplock);
|
||||||
|
map = colormaps[index];
|
||||||
|
if (!map)
|
||||||
|
{
|
||||||
|
UnlockMutex (maplock);
|
||||||
|
UnlockMutex (XFormControl.Lock);
|
||||||
|
fprintf (stderr, "BUG: XFormPLUT(): no current map\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
memcpy (control->OldCMap, map->colors, sizeof (map->colors));
|
||||||
|
UnlockMutex (maplock);
|
||||||
|
|
||||||
|
control->CMapIndex = index;
|
||||||
|
control->CMapPtr = ColorMapPtr;
|
||||||
|
control->Ticks = TimeInterval;
|
||||||
|
if (control->Ticks < 0)
|
||||||
|
control->Ticks = 0; /* prevent negative fade */
|
||||||
|
control->StartTime = Now;
|
||||||
|
control->EndTime = EndTime = Now + control->Ticks;
|
||||||
|
|
||||||
|
UnlockMutex (XFormControl.Lock);
|
||||||
|
|
||||||
|
return (EndTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
XFormColorMap (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
|
||||||
|
{
|
||||||
|
int what;
|
||||||
|
|
||||||
|
if (!ColorMapPtr)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
what = *ColorMapPtr;
|
||||||
|
if (what >= (int)FadeAllToWhite && what <= (int)FadeSomeToColor)
|
||||||
|
return XFormFade (ColorMapPtr, TimeInterval);
|
||||||
|
else
|
||||||
|
return XFormPLUT (ColorMapPtr, TimeInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FlushColorXForms (void)
|
||||||
|
{
|
||||||
|
FlushFadeXForms ();
|
||||||
|
FlushPLUTXForms ();
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,12 +21,10 @@
|
|||||||
#ifndef CMAP_H
|
#ifndef CMAP_H
|
||||||
#define CMAP_H
|
#define CMAP_H
|
||||||
|
|
||||||
#define NUMBER_OF_VARPLUTS 256
|
#define MAX_COLORMAPS 250
|
||||||
#define PLUTVAL_BYTE_SIZE 3
|
#define PLUTVAL_BYTE_SIZE 3
|
||||||
#define NUMBER_OF_PLUTVALS 256
|
#define NUMBER_OF_PLUTVALS 256
|
||||||
#define PLUT_BYTE_SIZE (PLUTVAL_BYTE_SIZE * NUMBER_OF_PLUTVALS)
|
#define PLUT_BYTE_SIZE (PLUTVAL_BYTE_SIZE * NUMBER_OF_PLUTVALS)
|
||||||
#define VARPLUTS_SIZE (NUMBER_OF_VARPLUTS * PLUT_BYTE_SIZE)
|
|
||||||
#define GET_VAR_PLUT(i) (_varPLUTs + (i) * PLUT_BYTE_SIZE)
|
|
||||||
|
|
||||||
#define BUILD_FRAME (1 << 0)
|
#define BUILD_FRAME (1 << 0)
|
||||||
#define FIND_PAGE (1 << 1)
|
#define FIND_PAGE (1 << 1)
|
||||||
@@ -40,9 +38,25 @@
|
|||||||
#define FADE_NORMAL_INTENSITY 255
|
#define FADE_NORMAL_INTENSITY 255
|
||||||
#define FADE_FULL_INTENSITY 510
|
#define FADE_FULL_INTENSITY 510
|
||||||
|
|
||||||
extern UBYTE* _varPLUTs;
|
typedef struct tfb_colormap
|
||||||
|
{
|
||||||
|
TFB_Palette colors[NUMBER_OF_PLUTVALS];
|
||||||
|
int index;
|
||||||
|
int version;
|
||||||
|
int refcount;
|
||||||
|
struct tfb_colormap *next;
|
||||||
|
} TFB_ColorMap;
|
||||||
|
|
||||||
extern volatile int FadeAmount;
|
extern volatile int FadeAmount;
|
||||||
|
|
||||||
void TFB_ColorMapToRGB (TFB_Palette *pal, int colormap_index);
|
extern void InitColorMaps (void);
|
||||||
|
extern void UninitColorMaps (void);
|
||||||
|
|
||||||
|
extern void TFB_ColorMapToRGB (TFB_Palette *pal, int colormap_index);
|
||||||
|
extern TFB_ColorMap * TFB_GetColorMap (int index);
|
||||||
|
extern void TFB_ReturnColorMap (TFB_ColorMap *map);
|
||||||
|
|
||||||
|
extern BOOLEAN XFormColorMap_step ();
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ typedef struct tfb_dc_img
|
|||||||
TFB_Image *image;
|
TFB_Image *image;
|
||||||
int x, y;
|
int x, y;
|
||||||
SCREEN destBuffer;
|
SCREEN destBuffer;
|
||||||
BOOLEAN UsePalette;
|
TFB_ColorMap *colormap;
|
||||||
int scale;
|
int scale;
|
||||||
} TFB_DrawCommand_Image;
|
} TFB_DrawCommand_Image;
|
||||||
|
|
||||||
|
|||||||
@@ -61,10 +61,12 @@ TFB_DrawCanvas_Rect (PRECT rect, int r, int g, int b, TFB_Canvas target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *palette, TFB_Canvas target)
|
TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale,
|
||||||
|
TFB_ColorMap *cmap, TFB_Canvas target)
|
||||||
{
|
{
|
||||||
SDL_Rect srcRect, targetRect, *pSrcRect;
|
SDL_Rect srcRect, targetRect, *pSrcRect;
|
||||||
SDL_Surface *surf;
|
SDL_Surface *surf;
|
||||||
|
TFB_Palette* palette;
|
||||||
|
|
||||||
if (img == 0)
|
if (img == 0)
|
||||||
{
|
{
|
||||||
@@ -74,18 +76,25 @@ TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *pale
|
|||||||
|
|
||||||
LockMutex (img->mutex);
|
LockMutex (img->mutex);
|
||||||
|
|
||||||
if (palette == 0)
|
if (cmap)
|
||||||
|
palette = cmap->colors;
|
||||||
|
else
|
||||||
palette = img->Palette;
|
palette = img->Palette;
|
||||||
|
|
||||||
|
// only set the new palette if it changed
|
||||||
|
if (((SDL_Surface *)img->NormalImg)->format->palette
|
||||||
|
&& cmap && img->colormap_version != cmap->version)
|
||||||
|
SDL_SetColors (img->NormalImg, (SDL_Color*)palette, 0, 256);
|
||||||
|
|
||||||
if (scale != 0 && scale != GSCALE_IDENTITY)
|
if (scale != 0 && scale != GSCALE_IDENTITY)
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
if (optMeleeScale == TFB_SCALE_TRILINEAR && img->MipmapImg)
|
if (optMeleeScale == TFB_SCALE_TRILINEAR && img->MipmapImg)
|
||||||
{
|
{
|
||||||
type = TFB_SCALE_TRILINEAR;
|
type = TFB_SCALE_TRILINEAR;
|
||||||
if (((SDL_Surface *)img->NormalImg)->format->palette)
|
// only set the new palette if it changed
|
||||||
SDL_SetColors (img->NormalImg, (SDL_Color*)palette, 0, 256);
|
if (((SDL_Surface *)img->MipmapImg)->format->palette
|
||||||
if (((SDL_Surface *)img->MipmapImg)->format->palette)
|
&& cmap && img->colormap_version != cmap->version)
|
||||||
SDL_SetColors (img->MipmapImg, (SDL_Color*)palette, 0, 256);
|
SDL_SetColors (img->MipmapImg, (SDL_Color*)palette, 0, 256);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -95,6 +104,9 @@ TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *pale
|
|||||||
|
|
||||||
TFB_DrawImage_FixScaling (img, scale, type);
|
TFB_DrawImage_FixScaling (img, scale, type);
|
||||||
surf = img->ScaledImg;
|
surf = img->ScaledImg;
|
||||||
|
if (surf->format->palette)
|
||||||
|
SDL_SetColors (surf, (SDL_Color*)palette, 0, 256);
|
||||||
|
|
||||||
srcRect.x = 0;
|
srcRect.x = 0;
|
||||||
srcRect.y = 0;
|
srcRect.y = 0;
|
||||||
srcRect.w = img->extent.width;
|
srcRect.w = img->extent.width;
|
||||||
@@ -113,8 +125,11 @@ TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *pale
|
|||||||
targetRect.y = y - img->NormalHs.y;
|
targetRect.y = y - img->NormalHs.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surf->format->palette)
|
if (cmap)
|
||||||
SDL_SetColors (surf, (SDL_Color*)palette, 0, 256);
|
{
|
||||||
|
img->colormap_version = cmap->version;
|
||||||
|
TFB_ReturnColorMap (cmap);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_BlitSurface (surf, pSrcRect, (NativeCanvas) target, &targetRect);
|
SDL_BlitSurface (surf, pSrcRect, (NativeCanvas) target, &targetRect);
|
||||||
UnlockMutex (img->mutex);
|
UnlockMutex (img->mutex);
|
||||||
@@ -254,6 +269,8 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int
|
|||||||
pal[i].b = b;
|
pal[i].b = b;
|
||||||
}
|
}
|
||||||
SDL_SetColors (surf, pal, 0, 256);
|
SDL_SetColors (surf, pal, 0, 256);
|
||||||
|
// reflect the change in *actual* image palette
|
||||||
|
img->colormap_version--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // fill the non-transparent parts of the image with fillcolor
|
{ // fill the non-transparent parts of the image with fillcolor
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ TFB_InitGraphics (int driver, int flags, int width, int height, int bpp)
|
|||||||
|
|
||||||
Init_DrawCommandQueue ();
|
Init_DrawCommandQueue ();
|
||||||
|
|
||||||
TFB_FlushPaletteCache ();
|
|
||||||
TFB_DrawCanvas_Initialize ();
|
TFB_DrawCanvas_Initialize ();
|
||||||
|
|
||||||
RenderingCond = CreateCondVar ("DCQ empty",
|
RenderingCond = CreateCondVar ("DCQ empty",
|
||||||
@@ -614,17 +613,12 @@ TFB_FlushGraphics () // Only call from main thread!!
|
|||||||
case TFB_DRAWCOMMANDTYPE_IMAGE:
|
case TFB_DRAWCOMMANDTYPE_IMAGE:
|
||||||
{
|
{
|
||||||
TFB_Image *DC_image = DC.data.image.image;
|
TFB_Image *DC_image = DC.data.image.image;
|
||||||
TFB_Palette *pal;
|
TFB_ColorMap *cmap = DC.data.image.colormap;
|
||||||
int x = DC.data.image.x;
|
int x = DC.data.image.x;
|
||||||
int y = DC.data.image.y;
|
int y = DC.data.image.y;
|
||||||
|
|
||||||
if (DC.data.image.UsePalette)
|
|
||||||
pal = palette;
|
|
||||||
else
|
|
||||||
pal = 0;
|
|
||||||
|
|
||||||
TFB_DrawCanvas_Image (DC_image, x, y,
|
TFB_DrawCanvas_Image (DC_image, x, y,
|
||||||
DC.data.image.scale, pal,
|
DC.data.image.scale, cmap,
|
||||||
SDL_Screens[DC.data.image.destBuffer]);
|
SDL_Screens[DC.data.image.destBuffer]);
|
||||||
|
|
||||||
if (DC.data.image.destBuffer == 0)
|
if (DC.data.image.destBuffer == 0)
|
||||||
|
|||||||
@@ -78,67 +78,21 @@ TFB_DrawScreen_SetPalette (int paletteIndex, int r, int g, int b)
|
|||||||
TFB_EnqueueDrawCommand (&DC);
|
TFB_EnqueueDrawCommand (&DC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This value is protected by the DCQ's lock. */
|
|
||||||
static int _localpal[256][3];
|
|
||||||
|
|
||||||
void
|
|
||||||
TFB_FlushPaletteCache ()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Lock_DCQ (-1);
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
_localpal[i][0] = -1;
|
|
||||||
_localpal[i][1] = -1;
|
|
||||||
_localpal[i][2] = -1;
|
|
||||||
}
|
|
||||||
Unlock_DCQ ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale,
|
TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale,
|
||||||
TFB_Palette *palette, SCREEN dest)
|
TFB_ColorMap *cmap, SCREEN dest)
|
||||||
{
|
{
|
||||||
TFB_DrawCommand DC;
|
TFB_DrawCommand DC;
|
||||||
|
|
||||||
DC.Type = TFB_DRAWCOMMANDTYPE_IMAGE;
|
DC.Type = TFB_DRAWCOMMANDTYPE_IMAGE;
|
||||||
DC.data.image.image = img;
|
DC.data.image.image = img;
|
||||||
|
DC.data.image.colormap = cmap;
|
||||||
DC.data.image.x = x;
|
DC.data.image.x = x;
|
||||||
DC.data.image.y = y;
|
DC.data.image.y = y;
|
||||||
DC.data.image.scale = (scale == GSCALE_IDENTITY) ? 0 : scale;
|
DC.data.image.scale = (scale == GSCALE_IDENTITY) ? 0 : scale;
|
||||||
|
|
||||||
if (palette != NULL)
|
|
||||||
{
|
|
||||||
int i, changed;
|
|
||||||
Lock_DCQ(257);
|
|
||||||
changed = 0;
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
if ((_localpal[i][0] != palette[i].r) ||
|
|
||||||
(_localpal[i][1] != palette[i].g) ||
|
|
||||||
(_localpal[i][2] != palette[i].b))
|
|
||||||
{
|
|
||||||
changed++;
|
|
||||||
_localpal[i][0] = palette[i].r;
|
|
||||||
_localpal[i][1] = palette[i].g;
|
|
||||||
_localpal[i][2] = palette[i].b;
|
|
||||||
TFB_DrawScreen_SetPalette (i, palette[i].r, palette[i].g,
|
|
||||||
palette[i].b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if (changed) { fprintf (stderr, "Actually changing palette! "); }
|
|
||||||
DC.data.image.UsePalette = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Lock_DCQ (1);
|
|
||||||
DC.data.image.UsePalette = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DC.data.image.destBuffer = dest;
|
DC.data.image.destBuffer = dest;
|
||||||
|
|
||||||
TFB_EnqueueDrawCommand (&DC);
|
TFB_EnqueueDrawCommand (&DC);
|
||||||
Unlock_DCQ ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -296,10 +250,10 @@ TFB_DrawImage_Rect (PRECT rect, int r, int g, int b, TFB_Image *image)
|
|||||||
|
|
||||||
void
|
void
|
||||||
TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale,
|
TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale,
|
||||||
TFB_Palette *palette, TFB_Image *target)
|
TFB_ColorMap *cmap, TFB_Image *target)
|
||||||
{
|
{
|
||||||
LockMutex (target->mutex);
|
LockMutex (target->mutex);
|
||||||
TFB_DrawCanvas_Image (img, x, y, scale, palette, target->NormalImg);
|
TFB_DrawCanvas_Image (img, x, y, scale, cmap, target->NormalImg);
|
||||||
target->dirty = TRUE;
|
target->dirty = TRUE;
|
||||||
UnlockMutex (target->mutex);
|
UnlockMutex (target->mutex);
|
||||||
}
|
}
|
||||||
@@ -334,6 +288,7 @@ TFB_DrawImage_New (TFB_Canvas canvas)
|
|||||||
img->MipmapImg = NULL;
|
img->MipmapImg = NULL;
|
||||||
img->FilledImg = NULL;
|
img->FilledImg = NULL;
|
||||||
img->colormap_index = -1;
|
img->colormap_index = -1;
|
||||||
|
img->colormap_version = 0;
|
||||||
img->NormalHs = NullHs;
|
img->NormalHs = NullHs;
|
||||||
img->MipmapHs = NullHs;
|
img->MipmapHs = NullHs;
|
||||||
img->last_scale_hs = NullHs;
|
img->last_scale_hs = NullHs;
|
||||||
@@ -363,6 +318,7 @@ TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha)
|
|||||||
img->MipmapImg = NULL;
|
img->MipmapImg = NULL;
|
||||||
img->FilledImg = NULL;
|
img->FilledImg = NULL;
|
||||||
img->colormap_index = -1;
|
img->colormap_index = -1;
|
||||||
|
img->colormap_version = 0;
|
||||||
img->NormalHs = NullHs;
|
img->NormalHs = NullHs;
|
||||||
img->MipmapHs = NullHs;
|
img->MipmapHs = NullHs;
|
||||||
img->last_scale_hs = NullHs;
|
img->last_scale_hs = NullHs;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ typedef struct tfb_palette
|
|||||||
} TFB_Palette;
|
} TFB_Palette;
|
||||||
|
|
||||||
#include "graphics/gfx_common.h"
|
#include "graphics/gfx_common.h"
|
||||||
|
#include "cmap.h"
|
||||||
|
|
||||||
typedef struct tfb_image
|
typedef struct tfb_image
|
||||||
{
|
{
|
||||||
@@ -56,6 +57,7 @@ typedef struct tfb_image
|
|||||||
TFB_Canvas FilledImg;
|
TFB_Canvas FilledImg;
|
||||||
TFB_Palette *Palette;
|
TFB_Palette *Palette;
|
||||||
int colormap_index;
|
int colormap_index;
|
||||||
|
int colormap_version;
|
||||||
HOT_SPOT NormalHs;
|
HOT_SPOT NormalHs;
|
||||||
HOT_SPOT MipmapHs;
|
HOT_SPOT MipmapHs;
|
||||||
HOT_SPOT last_scale_hs;
|
HOT_SPOT last_scale_hs;
|
||||||
@@ -92,7 +94,7 @@ typedef struct tfb_pixelformat
|
|||||||
|
|
||||||
void TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, int r, int g, int b, SCREEN dest);
|
void TFB_DrawScreen_Line (int x1, int y1, int x2, int y2, int r, int g, int b, SCREEN dest);
|
||||||
void TFB_DrawScreen_Rect (PRECT rect, int r, int g, int b, SCREEN dest);
|
void TFB_DrawScreen_Rect (PRECT rect, int r, int g, int b, SCREEN dest);
|
||||||
void TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *palette, SCREEN dest);
|
void TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale, TFB_ColorMap *cmap, SCREEN dest);
|
||||||
void TFB_DrawScreen_Copy (PRECT r, SCREEN src, SCREEN dest);
|
void TFB_DrawScreen_Copy (PRECT r, SCREEN src, SCREEN dest);
|
||||||
void TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, SCREEN dest);
|
void TFB_DrawScreen_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, SCREEN dest);
|
||||||
void TFB_DrawScreen_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, SCREEN dest);
|
void TFB_DrawScreen_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, SCREEN dest);
|
||||||
@@ -103,7 +105,6 @@ void TFB_DrawScreen_DeleteData (void *);
|
|||||||
void TFB_DrawScreen_WaitForSignal (void);
|
void TFB_DrawScreen_WaitForSignal (void);
|
||||||
void TFB_DrawScreen_ReinitVideo (int driver, int flags, int width, int height, int bpp);
|
void TFB_DrawScreen_ReinitVideo (int driver, int flags, int width, int height, int bpp);
|
||||||
void TFB_DrawScreen_SetPalette (int paletteIndex, int r, int g, int b);
|
void TFB_DrawScreen_SetPalette (int paletteIndex, int r, int g, int b);
|
||||||
void TFB_FlushPaletteCache (void);
|
|
||||||
|
|
||||||
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
|
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
|
||||||
TFB_Image *TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha);
|
TFB_Image *TFB_DrawImage_CreateForScreen (int w, int h, BOOLEAN withalpha);
|
||||||
@@ -113,7 +114,7 @@ void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type);
|
|||||||
|
|
||||||
void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, int r, int g, int b, TFB_Image *dest);
|
void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, int r, int g, int b, TFB_Image *dest);
|
||||||
void TFB_DrawImage_Rect (PRECT rect, int r, int g, int b, TFB_Image *image);
|
void TFB_DrawImage_Rect (PRECT rect, int r, int g, int b, TFB_Image *image);
|
||||||
void TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *palette, TFB_Image *target);
|
void TFB_DrawImage_Image (TFB_Image *img, int x, int y, int scale, TFB_ColorMap *cmap, TFB_Image *target);
|
||||||
void TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, TFB_Image *target);
|
void TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, TFB_Image *target);
|
||||||
void TFB_DrawImage_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, TFB_Image *target);
|
void TFB_DrawImage_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, TFB_Image *target);
|
||||||
|
|
||||||
@@ -137,7 +138,7 @@ void TFB_DrawCanvas_Delete (TFB_Canvas canvas);
|
|||||||
|
|
||||||
void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, int r, int g, int b, TFB_Canvas dest);
|
void TFB_DrawCanvas_Line (int x1, int y1, int x2, int y2, int r, int g, int b, TFB_Canvas dest);
|
||||||
void TFB_DrawCanvas_Rect (PRECT rect, int r, int g, int b, TFB_Canvas image);
|
void TFB_DrawCanvas_Rect (PRECT rect, int r, int g, int b, TFB_Canvas image);
|
||||||
void TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *palette, TFB_Canvas target);
|
void TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_ColorMap *cmap, TFB_Canvas target);
|
||||||
void TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, TFB_Canvas target);
|
void TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int g, int b, TFB_Canvas target);
|
||||||
void TFB_DrawCanvas_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, TFB_Canvas target);
|
void TFB_DrawCanvas_FontChar (TFB_Char *, TFB_Image *backing, int x, int y, TFB_Canvas target);
|
||||||
|
|
||||||
|
|||||||
@@ -119,8 +119,7 @@ TFB_Prim_Stamp (PSTAMP stmp)
|
|||||||
int x, y;
|
int x, y;
|
||||||
PFRAME_DESC SrcFramePtr;
|
PFRAME_DESC SrcFramePtr;
|
||||||
TFB_Image *img;
|
TFB_Image *img;
|
||||||
BOOLEAN paletted;
|
TFB_ColorMap *cmap = NULL;
|
||||||
TFB_Palette palette[256];
|
|
||||||
int gscale;
|
int gscale;
|
||||||
|
|
||||||
SrcFramePtr = (PFRAME_DESC)stmp->frame;
|
SrcFramePtr = (PFRAME_DESC)stmp->frame;
|
||||||
@@ -143,25 +142,22 @@ TFB_Prim_Stamp (PSTAMP stmp)
|
|||||||
img->NormalHs = SrcFramePtr->HotSpot;
|
img->NormalHs = SrcFramePtr->HotSpot;
|
||||||
x = stmp->origin.x - _CurFramePtr->HotSpot.x;
|
x = stmp->origin.x - _CurFramePtr->HotSpot.x;
|
||||||
y = stmp->origin.y - _CurFramePtr->HotSpot.y;
|
y = stmp->origin.y - _CurFramePtr->HotSpot.y;
|
||||||
paletted = FALSE;
|
|
||||||
|
|
||||||
if (TFB_DrawCanvas_IsPaletted(img->NormalImg) && img->colormap_index != -1)
|
if (TFB_DrawCanvas_IsPaletted(img->NormalImg) && img->colormap_index != -1)
|
||||||
{
|
{
|
||||||
TFB_ColorMapToRGB (palette, img->colormap_index);
|
// returned cmap is addrefed, must release later
|
||||||
paletted = TRUE;
|
cmap = TFB_GetColorMap (img->colormap_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnlockMutex (img->mutex);
|
UnlockMutex (img->mutex);
|
||||||
|
|
||||||
if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE)
|
if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE)
|
||||||
{
|
{
|
||||||
TFB_DrawScreen_Image (img, x, y, gscale, (paletted ? palette : NULL),
|
TFB_DrawScreen_Image (img, x, y, gscale, cmap, TFB_SCREEN_MAIN);
|
||||||
TFB_SCREEN_MAIN);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TFB_DrawImage_Image (img, x, y, gscale, (paletted ? palette : NULL),
|
TFB_DrawImage_Image (img, x, y, gscale, cmap, _CurFramePtr->image);
|
||||||
_CurFramePtr->image);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user