Presentation (slides) player; 2nd edition

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1452 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2005-01-17 20:35:06 +00:00
parent e079d19b06
commit 4ab169325e
8 changed files with 515 additions and 7 deletions
+1
View File
@@ -37,6 +37,7 @@ int optWhichMusic;
int optWhichCoarseScan;
int optWhichMenu;
int optWhichFonts;
int optWhichIntro;
int optSmoothScroll;
int optMeleeScale;
+1
View File
@@ -33,6 +33,7 @@ extern int optWhichMusic;
extern int optWhichCoarseScan;
extern int optWhichMenu;
extern int optWhichFonts;
extern int optWhichIntro;
extern int optSmoothScroll;
extern int optMeleeScale;
+11 -3
View File
@@ -19,6 +19,7 @@
#include "starcon.h"
#include "vidlib.h"
#include "libs/graphics/gfx_common.h"
#include "options.h"
//Added by Chris
@@ -132,8 +133,11 @@ Introduction (void)
SleepThreadUntil (XFormColorMap ((COLORMAPPTR)xform_buf, ONE_SECOND / 2));
if (InputState == 0)
{
DoFMV ("slides/intro/intro.duk", NULL, TRUE);
{ /* by default we do 3DO cinematics; or PC slides when 3DO files are
* not present */
if (optWhichIntro == OPT_PC ||
!DoFMV ("slides/intro/intro.duk", NULL, TRUE))
ShowPresentation ("slides/intro/intro.txt");
}
}
@@ -145,7 +149,11 @@ Victory (void)
xform_buf[0] = FadeAllToBlack;
SleepThreadUntil (XFormColorMap ((COLORMAPPTR)xform_buf, ONE_SECOND / 2));
DoFMV ("slides/ending/victory.duk", NULL, TRUE);
/* by default we do 3DO cinematics; or PC slides when 3DO files are
* not present */
if (optWhichIntro == OPT_PC ||
!DoFMV ("slides/ending/victory.duk", NULL, TRUE))
ShowPresentation ("slides/ending/ending.txt");
xform_buf[0] = FadeAllToBlack;
XFormColorMap ((COLORMAPPTR)xform_buf, 0);
+459 -1
View File
@@ -16,8 +16,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <ctype.h>
#include "starcon.h"
#include "libs/vidlib.h"
#include "options.h"
#include "libs/graphics/gfx_common.h"
#include "libs/sound/sound.h"
//Added by Chris
@@ -27,16 +31,470 @@ void LoadMasterShipList (void);
//End Added by Chris
void
typedef struct
{
/* standard state required by DoInput */
BOOLEAN (*InputFunc) (PVOID pInputState);
COUNT MenuRepeatDelay;
/* Presentation state */
TimeCount StartTime;
TimeCount LastSyncTime;
TimeCount TimeOut;
int TimeOutOnSkip;
STRING SlideShow;
FONT Font;
FRAME Frame;
MUSIC_REF MusicRef;
COUNT OperIndex;
COLOR TextFadeColor;
COLOR TextColor;
COLOR TextBackColor;
int TextVPos;
RECT clip_r;
RECT tfade_r;
#define MAX_TEXT_LINES 15
TEXT TextLines[MAX_TEXT_LINES];
COUNT LinesCount;
char Buffer[512];
} PRESENTATION_INPUT_STATE, *PPRESENTATION_INPUT_STATE;
BOOLEAN
DoFMV (char *name, char *loopname, BOOLEAN uninit)
{
VIDEO_REF VidRef;
VidRef = LoadVideoFile (name);
if (!VidRef)
return FALSE;
VidPlay (VidRef, loopname, uninit);
VidDoInput ();
VidStop ();
DestroyVideo (VidRef);
return TRUE;
}
static void
CopyTextString (char *Buffer, COUNT BufSize, const char *Src)
{
strncpy (Buffer, Src, BufSize);
Buffer[BufSize - 1] = '\0';
}
static BOOLEAN
ParseColorString (const char *Src, COLOR* pColor)
{
unsigned clr;
if (1 != sscanf (Src, "%x", &clr))
return FALSE;
*pColor = BUILD_COLOR (MAKE_RGB15 (
(clr >> 19) & 0x1f, (clr >> 11) & 0x1f, (clr >> 3) & 0x1f),
0);
return TRUE;
}
static BOOLEAN
DoFadeScreen (PRESENTATION_INPUT_STATE* pPIS, const char *Src, BYTE FadeType)
{
BYTE xform_buf[1] = {FadeType};
int msecs;
if (1 == sscanf (Src, "%d", &msecs))
{
pPIS->TimeOut = XFormColorMap (
(COLORMAPPTR) xform_buf,
(SIZE)(msecs * ONE_SECOND / 1000)) + ONE_SECOND / 10;
pPIS->TimeOutOnSkip = FALSE;
}
return TRUE;
}
static void
DrawTracedText (TEXT *pText, COLOR Fore, COLOR Back)
{
SetContextForeGroundColor (Back);
pText->baseline.x--;
font_DrawText (pText);
pText->baseline.x += 2;
font_DrawText (pText);
pText->baseline.x--;
pText->baseline.y--;
font_DrawText (pText);
pText->baseline.y += 2;
font_DrawText (pText);
pText->baseline.y--;
SetContextForeGroundColor (Fore);
font_DrawText (pText);
}
static COUNT
ParseTextLines (TEXT *Lines, COUNT MaxLines, char* Buffer)
{
COUNT i;
const char* pEnd = Buffer + strlen(Buffer);
for (i = 0; i < MaxLines && Buffer < pEnd; ++i, ++Lines)
{
char* pTerm = strchr(Buffer, '\n');
if (!pTerm)
pTerm = Buffer + strlen(Buffer);
*pTerm = '\0'; /* terminate string */
Lines->pStr = Buffer;
Lines->CharCount = ~0;
Buffer = pTerm + 1;
}
return i;
}
BOOLEAN
DoPresentation (PVOID pIS)
{
PRESENTATION_INPUT_STATE* pPIS = (PRESENTATION_INPUT_STATE*) pIS;
if (PulsedInputState.key[KEY_MENU_CANCEL]
|| (GLOBAL (CurrentActivity) & CHECK_ABORT))
return FALSE; /* abort requested - we are done */
if (pPIS->TimeOut)
{
if (GetTimeCounter () > pPIS->TimeOut)
{ /* time elapsed - continue normal ops */
pPIS->TimeOut = 0;
return TRUE;
}
if (pPIS->TimeOutOnSkip &&
(PulsedInputState.key[KEY_MENU_SELECT]
|| PulsedInputState.key[KEY_MENU_SPECIAL]
|| PulsedInputState.key[KEY_MENU_RIGHT]) )
{ /* skip requested - continue normal ops */
pPIS->TimeOut = 0;
return TRUE;
}
SleepThread (ONE_SECOND / 20);
return TRUE;
}
while (pPIS->OperIndex < GetStringTableCount (pPIS->SlideShow))
{
char Opcode[16];
STRINGPTR pStr = GetStringAddress (pPIS->SlideShow);
pPIS->OperIndex++;
pPIS->SlideShow = SetRelStringTableIndex (pPIS->SlideShow, 1);
if (!pStr)
continue;
if (1 != sscanf (pStr, "%15s", Opcode))
continue;
pStr += strlen(Opcode);
if (*pStr != '\0')
++pStr;
strupr(Opcode);
if (strcmp (Opcode, "DIMS") == 0)
{ /* set dimensions */
int w, h;
if (2 == sscanf (pStr, "%d %d", &w, &h))
{
pPIS->clip_r.extent.width = w;
pPIS->clip_r.extent.height = h;
/* center on screen */
pPIS->clip_r.corner.x = (SCREEN_WIDTH - w) / 2;
pPIS->clip_r.corner.y = (SCREEN_HEIGHT - h) / 2;
LockMutex (GraphicsLock);
SetContextClipRect (&pPIS->clip_r);
UnlockMutex (GraphicsLock);
}
}
if (strcmp (Opcode, "FONT") == 0)
{ /* set font */
CopyTextString (pPIS->Buffer, sizeof(pPIS->Buffer), pStr);
if (pPIS->Font)
DestroyFont (ReleaseFont (pPIS->Font));
pPIS->Font = CaptureFont ((FONT_REF) LoadFontFile (pPIS->Buffer));
LockMutex (GraphicsLock);
SetContextFont (pPIS->Font);
UnlockMutex (GraphicsLock);
}
else if (strcmp (Opcode, "ANI") == 0)
{ /* set ani */
CopyTextString (pPIS->Buffer, sizeof(pPIS->Buffer), pStr);
if (pPIS->Frame)
DestroyDrawable (ReleaseDrawable (pPIS->Frame));
pPIS->Frame = CaptureDrawable (LoadCelFile (pPIS->Buffer));
}
else if (strcmp (Opcode, "MUSIC") == 0)
{ /* set music */
CopyTextString (pPIS->Buffer, sizeof(pPIS->Buffer), pStr);
if (pPIS->MusicRef)
{
StopMusic ();
DestroyMusic (pPIS->MusicRef);
}
pPIS->MusicRef = LoadMusicFile (pPIS->Buffer);
PlayMusic (pPIS->MusicRef, FALSE, 1);
}
else if (strcmp (Opcode, "WAIT") == 0)
{ /* wait */
int msecs;
if (1 == sscanf (pStr, "%d", &msecs))
{
pPIS->TimeOut = GetTimeCounter ()
+ msecs * ONE_SECOND / 1000;
pPIS->TimeOutOnSkip = TRUE;
return TRUE;
}
}
else if (strcmp (Opcode, "SYNC") == 0)
{ /* absolute time-sync */
int msecs;
if (1 == sscanf (pStr, "%d", &msecs))
{
pPIS->LastSyncTime = pPIS->StartTime
+ msecs * ONE_SECOND / 1000;
pPIS->TimeOut = pPIS->LastSyncTime;
pPIS->TimeOutOnSkip = FALSE;
return TRUE;
}
}
else if (strcmp (Opcode, "RESYNC") == 0)
{ /* flush and update absolute sync point */
pPIS->LastSyncTime = pPIS->StartTime = GetTimeCounter ();
}
else if (strcmp (Opcode, "DSYNC") == 0)
{ /* delta time-sync; from the last absolute sync */
int msecs;
if (1 == sscanf (pStr, "%d", &msecs))
{
pPIS->TimeOut = pPIS->LastSyncTime
+ msecs * ONE_SECOND / 1000;
pPIS->TimeOutOnSkip = FALSE;
return TRUE;
}
}
else if (strcmp (Opcode, "TC") == 0)
{ /* text fore color */
ParseColorString (pStr, &pPIS->TextColor);
}
else if (strcmp (Opcode, "TBC") == 0)
{ /* text back color */
ParseColorString (pStr, &pPIS->TextBackColor);
}
else if (strcmp (Opcode, "TFC") == 0)
{ /* text fade color */
ParseColorString (pStr, &pPIS->TextFadeColor);
}
else if (strcmp (Opcode, "TVA") == 0)
{ /* text vertical align */
pPIS->TextVPos = toupper (*pStr);
}
else if (strcmp (Opcode, "TEXT") == 0)
{ /* simple text draw */
SIZE leading;
COUNT i;
COORD y;
CopyTextString (pPIS->Buffer, sizeof(pPIS->Buffer), pStr);
pPIS->LinesCount = ParseTextLines (pPIS->TextLines,
MAX_TEXT_LINES, pPIS->Buffer);
LockMutex (GraphicsLock);
GetContextFontLeading (&leading);
UnlockMutex (GraphicsLock);
switch (pPIS->TextVPos)
{
case 'T': /* top */
y = leading;
break;
case 'M': /* middle */
y = (pPIS->clip_r.extent.height
- pPIS->LinesCount * leading) / 2;
break;
default: /* bottom */
y = pPIS->clip_r.extent.height - pPIS->LinesCount * leading;
}
for (i = 0; i < pPIS->LinesCount; ++i, y += leading)
{
pPIS->TextLines[i].align = ALIGN_CENTER;
pPIS->TextLines[i].valign = VALIGN_MIDDLE;
pPIS->TextLines[i].baseline.x = SCREEN_WIDTH / 2;
pPIS->TextLines[i].baseline.y = y;
}
LockMutex (GraphicsLock);
SetContextClipping (TRUE);
for (i = 0; i < pPIS->LinesCount; ++i)
DrawTracedText (pPIS->TextLines + i,
pPIS->TextColor, pPIS->TextBackColor);
UnlockMutex (GraphicsLock);
}
else if (strcmp (Opcode, "TFI") == 0)
{ /* text fade-in */
SIZE leading;
COUNT i;
COORD y;
CopyTextString (pPIS->Buffer, sizeof(pPIS->Buffer), pStr);
pPIS->LinesCount = ParseTextLines (pPIS->TextLines,
MAX_TEXT_LINES, pPIS->Buffer);
LockMutex (GraphicsLock);
GetContextFontLeading (&leading);
UnlockMutex (GraphicsLock);
switch (pPIS->TextVPos)
{
case 'T': /* top */
y = leading;
break;
case 'M': /* middle */
y = (pPIS->clip_r.extent.height
- pPIS->LinesCount * leading) / 2;
break;
default: /* bottom */
y = pPIS->clip_r.extent.height - pPIS->LinesCount * leading;
}
pPIS->tfade_r = pPIS->clip_r;
pPIS->tfade_r.corner.y += y - leading;
pPIS->tfade_r.extent.height = (pPIS->LinesCount + 1) * leading;
for (i = 0; i < pPIS->LinesCount; ++i, y += leading)
{
pPIS->TextLines[i].align = ALIGN_CENTER;
pPIS->TextLines[i].valign = VALIGN_MIDDLE;
pPIS->TextLines[i].baseline.x = SCREEN_WIDTH / 2;
pPIS->TextLines[i].baseline.y = y;
}
LockMutex (GraphicsLock);
SetContextClipping (TRUE);
for (i = 0; i < pPIS->LinesCount; ++i)
DrawTracedText (pPIS->TextLines + i,
pPIS->TextFadeColor, pPIS->TextFadeColor);
/* do transition */
SetTransitionSource (&pPIS->tfade_r);
BatchGraphics ();
for (i = 0; i < pPIS->LinesCount; ++i)
DrawTracedText (pPIS->TextLines + i,
pPIS->TextColor, pPIS->TextBackColor);
ScreenTransition (3, &pPIS->tfade_r);
UnbatchGraphics ();
UnlockMutex (GraphicsLock);
}
else if (strcmp (Opcode, "TFO") == 0)
{ /* text fade-out */
COUNT i;
LockMutex (GraphicsLock);
SetContextClipping (TRUE);
/* do transition */
SetTransitionSource (&pPIS->tfade_r);
BatchGraphics ();
for (i = 0; i < pPIS->LinesCount; ++i)
DrawTracedText (pPIS->TextLines + i,
pPIS->TextFadeColor, pPIS->TextFadeColor);
ScreenTransition (3, &pPIS->tfade_r);
UnbatchGraphics ();
UnlockMutex (GraphicsLock);
}
else if (strcmp (Opcode, "DRAW") == 0)
{ /* draw a graphic */
int index;
if (1 == sscanf (pStr, "%d", &index))
{
STAMP s;
s.frame = SetAbsFrameIndex (pPIS->Frame, (COUNT)index);
s.origin.x = 0;
s.origin.y = 0;
LockMutex (GraphicsLock);
SetContextClipping (TRUE);
DrawStamp (&s);
UnlockMutex (GraphicsLock);
}
}
else if (strcmp (Opcode, "FTC") == 0)
{ /* fade to color */
return DoFadeScreen (pPIS, pStr, FadeAllToColor);
}
else if (strcmp (Opcode, "FTB") == 0)
{ /* fade to black */
return DoFadeScreen (pPIS, pStr, FadeAllToBlack);
}
else if (strcmp (Opcode, "FTW") == 0)
{ /* fade to white */
return DoFadeScreen (pPIS, pStr, FadeAllToWhite);
}
else if (strcmp (Opcode, "NOOP") == 0)
{ /* no operation - must be a comment in script */
/* do nothing */
}
}
/* we are all done */
return FALSE;
}
BOOLEAN
ShowPresentation (char *name)
{
CONTEXT OldContext;
FONT OldFont;
RECT OldRect;
PRESENTATION_INPUT_STATE pis;
RECT r = {{0, 0}, {SCREEN_WIDTH, SCREEN_HEIGHT}};
pis.SlideShow = CaptureStringTable (
LoadStringTableFile (contentDir, name)
);
if (!pis.SlideShow)
return FALSE;
pis.SlideShow = SetAbsStringTableIndex (pis.SlideShow, 0);
pis.OperIndex = 0;
LockMutex (GraphicsLock);
OldContext = SetContext (ScreenContext);
GetContextClipRect (&OldRect);
OldFont = SetContextFont (NULL);
/* paint black rect over screen */
SetContextForeGroundColor (BUILD_COLOR (
MAKE_RGB15 (0x0, 0x0, 0x0), 0x00));
DrawFilledRectangle (&r);
UnlockMutex (GraphicsLock);
FlushInput ();
SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE);
pis.MenuRepeatDelay = 0;
pis.InputFunc = DoPresentation;
pis.Font = 0;
pis.Frame = 0;
pis.MusicRef = 0;
pis.TextVPos = 'B';
pis.LastSyncTime = pis.StartTime = GetTimeCounter ();
pis.TimeOut = 0;
DoInput (&pis, TRUE);
SleepThreadUntil (FadeMusic (0, ONE_SECOND));
StopMusic ();
FadeMusic (MAX_VOLUME, 0);
DestroyMusic (pis.MusicRef);
DestroyDrawable (ReleaseDrawable (pis.Frame));
DestroyFont (ReleaseFont (pis.Font));
DestroyStringTable (ReleaseStringTable (pis.SlideShow));
LockMutex (GraphicsLock);
SetContextFont (OldFont);
SetContextClipRect (&OldRect);
SetContext (OldContext);
UnlockMutex (GraphicsLock);
return TRUE;
}
/* //Already defined in fmv.c
+1
View File
@@ -271,6 +271,7 @@ extern HOT_SPOT SetFrameHot (FRAME Frame, HOT_SPOT HotSpot);
extern HOT_SPOT GetFrameHot (FRAME Frame);
extern BOOLEAN InstallGraphicResTypes (COUNT cel_type, COUNT font_type);
extern DWORD LoadCelFile (PVOID pStr);
extern DWORD LoadFontFile (PVOID pStr);
extern DWORD LoadGraphicInstance (DWORD res);
extern DWORD LoadGraphic (DWORD res);
extern DRAWABLE LoadDisplayPixmap (PRECT area, FRAME frame);
+27 -1
View File
@@ -31,7 +31,8 @@ LoadCelFile (PVOID pStr)
// something else is loading resources atm
return 0;
if ((fp = res_OpenResFile (contentDir, pStr, "rb")) != NULL)
fp = res_OpenResFile (contentDir, pStr, "rb");
if (fp != NULL)
{
MEM_HANDLE hData;
@@ -44,3 +45,28 @@ LoadCelFile (PVOID pStr)
return (0);
}
DWORD
LoadFontFile (PVOID pStr)
{
uio_Stream *fp;
// FIXME: this theoretically needs a mechanism to prevent races
if (_cur_resfile_name)
// something else is loading resources atm
return 0;
fp = res_OpenResFile (contentDir, pStr, "rb");
if (fp == ~0)
{
MEM_HANDLE hData;
_cur_resfile_name = pStr;
hData = _GetFontData (fp, LengthResFile (fp));
_cur_resfile_name = 0;
res_CloseResFile (fp);
return ((DWORD)hData);
}
return (0);
}
+2 -1
View File
@@ -46,7 +46,8 @@ extern void VidStop (void);
extern VIDEO_REF VidPlaying (void);
extern void VidDoInput (void);
void DoFMV (char *name, char *loopname, BOOLEAN uninit);
extern BOOLEAN DoFMV (char *name, char *loopname, BOOLEAN uninit);
extern BOOLEAN ShowPresentation(char *name);
+13 -1
View File
@@ -67,6 +67,7 @@ struct options_struct {
int whichCoarseScan;
int whichMenu;
int whichFonts;
int whichIntro;
int smoothScroll;
int meleeScale;
BOOLEAN subTitles;
@@ -116,6 +117,7 @@ main (int argc, char *argv[])
/* .whichCoarseScan = */ OPT_PC,
/* .whichMenu = */ OPT_PC,
/* .whichFont = */ OPT_PC,
/* .whichIntro = */ OPT_3DO,
/* .smoothScroll = */ OPT_PC,
/* .meleeScale = */ TFB_SCALE_TRILINEAR,
/* .subtitles = */ TRUE,
@@ -182,6 +184,7 @@ main (int argc, char *argv[])
optWhichCoarseScan = options.whichCoarseScan;
optWhichMenu = options.whichMenu;
optWhichFonts = options.whichFonts;
optWhichIntro = options.whichIntro;
optSmoothScroll = options.smoothScroll;
optMeleeScale = options.meleeScale;
optSubtitles = options.subTitles;
@@ -244,7 +247,7 @@ enum
ADDON_OPT
};
static const char *optString = "+r:d:foc:b:spC:n:?hM:S:T:m:q:ug:l:";
static const char *optString = "+r:d:foc:b:spC:n:?hM:S:T:m:q:ug:l:i:";
static struct option longOptions[] =
{
{"res", 1, NULL, 'r'},
@@ -266,6 +269,7 @@ static struct option longOptions[] =
{"music", 1, NULL, 'm'},
{"gamma", 1, NULL, 'g'},
{"logfile", 1, NULL, 'l'},
{"intro", 1, NULL, 'i'},
// options with no short equivalent:
{"cscan", 1, NULL, CSCAN_OPT},
@@ -484,6 +488,14 @@ parseOptions(int argc, char *argv[], struct options_struct *options)
case 'l':
// -l is a no-op on the second pass..
break;
case 'i':
{
if (Check_PC_3DO_opt (optarg, OPT_PC | OPT_3DO,
longOptions[optionIndex].name,
&options->whichIntro) == -1)
badArg = TRUE;
break;
}
case CSCAN_OPT:
if (Check_PC_3DO_opt (optarg, OPT_PC | OPT_3DO,
longOptions[optionIndex].name,