Implemented voice-over subtitle synchronization
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@565 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
+46
-10
@@ -1945,9 +1945,10 @@ RaceCommunication (void)
|
||||
}
|
||||
|
||||
int
|
||||
do_subtitles (UNICODE *pStr)
|
||||
do_subtitles (UNICODE *pStr, UNICODE *pTimeStamp)
|
||||
{
|
||||
static DWORD TimeOut;
|
||||
static unsigned long *cur_sub_ts;
|
||||
|
||||
// TODO: proper disabling of subtitles, this one prolly isn't 'safe'
|
||||
if (optSubtitles == FALSE)
|
||||
@@ -1981,6 +1982,8 @@ do_subtitles (UNICODE *pStr)
|
||||
UNICODE ch;
|
||||
COUNT numchars;
|
||||
static UNICODE alien_phrase_buf[4096];
|
||||
UNICODE *s;
|
||||
static unsigned long subtitle_frames_ts[50];
|
||||
|
||||
CommData.AlienTextTemplate.pStr = alien_phrase_buf;
|
||||
numchars = 0;
|
||||
@@ -2001,6 +2004,27 @@ do_subtitles (UNICODE *pStr)
|
||||
numchars += 6;
|
||||
}
|
||||
} while ((*CommData.AlienTextTemplate.pStr++ = ch));
|
||||
if (s = pTimeStamp)
|
||||
{
|
||||
int pos;
|
||||
cur_sub_ts = subtitle_frames_ts;
|
||||
while (*s && (pos = wstrcspn (s, ",")))
|
||||
{
|
||||
UNICODE valStr[10];
|
||||
wstrncpy (valStr, s, pos);
|
||||
valStr[pos] = '\0';
|
||||
*cur_sub_ts++ = wstrtoul(valStr,NULL,10);
|
||||
s += pos;
|
||||
if (*s)
|
||||
s++;
|
||||
}
|
||||
*cur_sub_ts = 0;
|
||||
TimeOut = GetTimeCounter ();
|
||||
}
|
||||
else
|
||||
subtitle_frames_ts[0] = 0;
|
||||
cur_sub_ts = subtitle_frames_ts;
|
||||
|
||||
CommData.AlienTextTemplate.pStr = alien_phrase_buf;
|
||||
CommData.AlienTextTemplate.CharCount = 0;
|
||||
#if 0
|
||||
@@ -2029,17 +2053,29 @@ do_subtitles (UNICODE *pStr)
|
||||
|
||||
CommData.AlienTextTemplate.CharCount = t.pStr - CommData.AlienTextTemplate.pStr;
|
||||
|
||||
read_speed = speed_array[GLOBAL (glob_flags) & READ_SPEED_MASK];
|
||||
talk_length = ONE_SECOND * CommData.AlienTextTemplate.CharCount / MODERATE_SPEED;
|
||||
if (read_speed)
|
||||
if (*cur_sub_ts)
|
||||
{
|
||||
silence_length = ONE_SECOND
|
||||
* (CommData.AlienTextTemplate.CharCount + MODERATE_SPEED) / read_speed;
|
||||
if (silence_length < talk_length)
|
||||
talk_length = silence_length;
|
||||
silence_length -= talk_length;
|
||||
// We found subtitle timestamps, let's use them
|
||||
// timestamps are stored as time per frame in milliseconds
|
||||
talk_length = *cur_sub_ts++ * ONE_SECOND /1000;
|
||||
silence_length = 0;
|
||||
TimeOut += talk_length;
|
||||
//sprintf (stderr, "Sound length is %d\n", talk_length);
|
||||
}
|
||||
else
|
||||
{
|
||||
read_speed = speed_array[GLOBAL (glob_flags) & READ_SPEED_MASK];
|
||||
talk_length = ONE_SECOND * CommData.AlienTextTemplate.CharCount / MODERATE_SPEED;
|
||||
if (read_speed)
|
||||
{
|
||||
silence_length = ONE_SECOND
|
||||
* (CommData.AlienTextTemplate.CharCount + MODERATE_SPEED) / read_speed;
|
||||
if (silence_length < talk_length)
|
||||
talk_length = silence_length;
|
||||
silence_length -= talk_length;
|
||||
}
|
||||
TimeOut = GetTimeCounter () + talk_length;
|
||||
}
|
||||
TimeOut = GetTimeCounter () + talk_length;
|
||||
subtitle_state = SPACE_SUBTITLE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ void
|
||||
NPCPhrase (int index)
|
||||
{
|
||||
UNICODE *pStr, numbuf[100];
|
||||
void *pClip;
|
||||
void *pClip, *pTimeStamp;
|
||||
|
||||
switch (index)
|
||||
{
|
||||
@@ -74,6 +74,7 @@ NPCPhrase (int index)
|
||||
}
|
||||
pStr = numbuf;
|
||||
pClip = 0;
|
||||
pTimeStamp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -83,11 +84,14 @@ NPCPhrase (int index)
|
||||
pClip = GetStringSoundClip (
|
||||
SetAbsStringTableIndex (CommData.ConversationPhrases, index - 1)
|
||||
);
|
||||
pTimeStamp = GetStringTimeStamp (
|
||||
SetAbsStringTableIndex (CommData.ConversationPhrases, index - 1)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SpliceTrack (pClip, pStr);
|
||||
SpliceTrack (pClip, pStr, pTimeStamp);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -802,6 +802,8 @@ extern void RetrieveStarMap (void);
|
||||
#define wstrupr strupr
|
||||
#define wstrncpy strncpy
|
||||
#define wstricmp stricmp
|
||||
#define wstrtoul strtoul
|
||||
#define wstrcspn strcspn
|
||||
|
||||
#endif /* _GLOBDATA_H */
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "sound.h"
|
||||
#include "libs/sound/trackplayer.h"
|
||||
|
||||
extern int do_subtitles (UNICODE *pStr);
|
||||
extern int do_subtitles (UNICODE *pStr, UNICODE *TimeStamp);
|
||||
|
||||
static int tct, tcur, no_voice;
|
||||
|
||||
@@ -32,6 +32,7 @@ static struct
|
||||
{
|
||||
int text_spliced;
|
||||
UNICODE *text;
|
||||
UNICODE *timestamp;
|
||||
TFB_SoundSample *sample;
|
||||
} track_clip[MAX_CLIPS];
|
||||
|
||||
@@ -49,7 +50,7 @@ JumpTrack (int abort)
|
||||
}
|
||||
|
||||
no_voice = 1;
|
||||
do_subtitles ((void *)~0);
|
||||
do_subtitles ((void *)~0, 0);
|
||||
|
||||
if (abort)
|
||||
tcur = tct;
|
||||
@@ -68,7 +69,7 @@ advance_track (int channel_finished)
|
||||
PlayStream (track_clip[tcur].sample, SPEECH_SOURCE, AL_FALSE,
|
||||
speechVolumeScale == 0.0f ? AL_FALSE : AL_TRUE);
|
||||
UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex);
|
||||
do_subtitles (0);
|
||||
do_subtitles (0, 0);
|
||||
}
|
||||
else if (channel_finished == 0)
|
||||
{
|
||||
@@ -115,8 +116,8 @@ PlayingTrack ()
|
||||
{
|
||||
if (tcur < tct)
|
||||
{
|
||||
if (do_subtitles (track_clip[tcur].text) ||
|
||||
(no_voice && ++tcur < tct && do_subtitles (0)))
|
||||
if (do_subtitles (track_clip[tcur].text, track_clip[tcur].timestamp) ||
|
||||
(no_voice && ++tcur < tct && do_subtitles (0, 0)))
|
||||
{
|
||||
return (tcur + 1);
|
||||
}
|
||||
@@ -170,11 +171,11 @@ StopTrack ()
|
||||
}
|
||||
tct = tcur = 0;
|
||||
no_voice = 0;
|
||||
do_subtitles (0);
|
||||
do_subtitles (0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SpliceTrack (UNICODE *TrackName, UNICODE *TrackText)
|
||||
SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp)
|
||||
{
|
||||
if (TrackText)
|
||||
{
|
||||
@@ -204,6 +205,7 @@ SpliceTrack (UNICODE *TrackName, UNICODE *TrackText)
|
||||
track_clip[tct].text = TrackText;
|
||||
track_clip[tct].text_spliced = 0;
|
||||
|
||||
track_clip[tct].timestamp = TimeStamp;
|
||||
fprintf (stderr, "SpliceTrack(): loading %s\n", TrackName);
|
||||
|
||||
track_clip[tct].sample = (TFB_SoundSample *) HMalloc (sizeof (TFB_SoundSample));
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#define VOICE_CHANNEL 0
|
||||
|
||||
extern int do_subtitles (UNICODE *pStr);
|
||||
extern int do_subtitles (UNICODE *pStr, UNICODE *pTimeStamp);
|
||||
|
||||
static int tct, tcur, no_voice;
|
||||
#define MAX_CLIPS 50
|
||||
@@ -35,6 +35,7 @@ static struct
|
||||
{
|
||||
int text_spliced;
|
||||
UNICODE *text;
|
||||
UNICODE *timestamp;
|
||||
Mix_Chunk *chunk;
|
||||
} track_clip[MAX_CLIPS];
|
||||
|
||||
@@ -47,7 +48,7 @@ JumpTrack (int abort)
|
||||
Mix_HaltChannel (VOICE_CHANNEL);
|
||||
|
||||
no_voice = 1;
|
||||
do_subtitles ((void *)~0);
|
||||
do_subtitles ((void *)~0, 0);
|
||||
|
||||
if (abort)
|
||||
tcur = tct;
|
||||
@@ -63,7 +64,7 @@ advance_track (int channel_finished)
|
||||
if (tcur < tct)
|
||||
{
|
||||
Mix_PlayChannel (VOICE_CHANNEL, track_clip[tcur].chunk, 0);
|
||||
do_subtitles (0);
|
||||
do_subtitles (0, 0);
|
||||
}
|
||||
else if (channel_finished == VOICE_CHANNEL)
|
||||
{
|
||||
@@ -94,8 +95,8 @@ PlayingTrack ()
|
||||
{
|
||||
if (tcur < tct)
|
||||
{
|
||||
if (do_subtitles (track_clip[tcur].text)
|
||||
|| (no_voice && ++tcur < tct && do_subtitles (0)))
|
||||
if (do_subtitles (track_clip[tcur].text, track_clip[tcur].timestamp)
|
||||
|| (no_voice && ++tcur < tct && do_subtitles (0, 0)))
|
||||
return (tcur + 1);
|
||||
else if (track_clip[tcur].chunk)
|
||||
return (Mix_Playing (VOICE_CHANNEL) ? (COUNT)(tcur + 1) : 0);
|
||||
@@ -126,11 +127,11 @@ StopTrack ()
|
||||
}
|
||||
tct = tcur = 0;
|
||||
no_voice = 0;
|
||||
do_subtitles (0);
|
||||
do_subtitles (0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SpliceTrack (UNICODE *TrackName, UNICODE *TrackText)
|
||||
SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp)
|
||||
{
|
||||
if (TrackText)
|
||||
{
|
||||
@@ -153,6 +154,7 @@ SpliceTrack (UNICODE *TrackName, UNICODE *TrackText)
|
||||
track_clip[tct - 1].text_spliced = 1;
|
||||
}
|
||||
wstrcpy (&track_clip[tct - 1].text[slen1], TrackText);
|
||||
track_clip[tct - 1].timestamp = 0;
|
||||
}
|
||||
}
|
||||
else if (tct < MAX_CLIPS)
|
||||
@@ -168,6 +170,7 @@ SpliceTrack (UNICODE *TrackName, UNICODE *TrackText)
|
||||
|
||||
track_clip[tct].text = TrackText;
|
||||
track_clip[tct].text_spliced = 0;
|
||||
track_clip[tct].timestamp = TimeStamp;
|
||||
++tct;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ void JumpTrack(int abort);
|
||||
void FastForward();
|
||||
void FastReverse();
|
||||
void StopTrack();
|
||||
void SpliceTrack(UNICODE *filespec, UNICODE *textspec);
|
||||
void SpliceTrack(UNICODE *filespec, UNICODE *textspec, UNICODE *TimeStamp);
|
||||
int GetSoundData (void *data);
|
||||
int GetSoundInfo (int *len, int *offs);
|
||||
|
||||
|
||||
@@ -54,11 +54,13 @@ _GetStringData (FILE *fp, DWORD length)
|
||||
#ifdef WIN32
|
||||
int omode;
|
||||
#endif
|
||||
int n, path_len;
|
||||
int n, path_len, num_data_sets;
|
||||
DWORD opos,
|
||||
slen[MAX_STRINGS], StringOffs, tot_string_size,
|
||||
clen[MAX_STRINGS], ClipOffs, tot_clip_size;
|
||||
char CurrentLine[1024], clip_path[1024], *strdata, *clipdata;
|
||||
clen[MAX_STRINGS], ClipOffs, tot_clip_size,
|
||||
tslen[MAX_STRINGS], TSOffs, tot_ts_size;
|
||||
char CurrentLine[1024], clip_path[1024], *strdata, *clipdata, *ts_data;
|
||||
FILE *timestamp_fp = NULL;
|
||||
|
||||
if ((strdata = HMalloc (tot_string_size = POOL_SIZE)) == 0)
|
||||
return (0);
|
||||
@@ -86,12 +88,28 @@ _GetStringData (FILE *fp, DWORD length)
|
||||
path_len = strlen (clip_path);
|
||||
}
|
||||
|
||||
{
|
||||
// try to open the timestamp file
|
||||
char ts_file_name[1024];
|
||||
strcpy (ts_file_name, _cur_resfile_name);
|
||||
s = strrchr (ts_file_name, '.');
|
||||
s += 2;
|
||||
*s++ = 's';
|
||||
*s = '\0';
|
||||
if ((timestamp_fp = fopen (ts_file_name, "rb")))
|
||||
{
|
||||
fprintf (stderr, "Found timestamp file: %s\n", ts_file_name);
|
||||
if ((ts_data = HMalloc (tot_ts_size = POOL_SIZE)) == 0)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
opos = ftell (fp);
|
||||
#ifdef WIN32
|
||||
omode = _setmode (fileno (fp), O_TEXT);
|
||||
#endif
|
||||
n = -1;
|
||||
StringOffs = ClipOffs = 0;
|
||||
StringOffs = ClipOffs = TSOffs = 0;
|
||||
while (fgets (CurrentLine, sizeof (CurrentLine), fp) && n < MAX_STRINGS - 1)
|
||||
{
|
||||
int l;
|
||||
@@ -115,6 +133,48 @@ _GetStringData (FILE *fp, DWORD length)
|
||||
}
|
||||
|
||||
slen[++n] = 0;
|
||||
// now lets check for timestamp data
|
||||
if (timestamp_fp)
|
||||
{
|
||||
char TimeStampLine[1024], *tsptr;
|
||||
BOOLEAN ts_ok = FALSE;
|
||||
fgets (TimeStampLine, sizeof (TimeStampLine), timestamp_fp);
|
||||
if (TimeStampLine[0] == '#')
|
||||
{
|
||||
tslen[n] = 0;
|
||||
if ((tsptr = strstr (TimeStampLine,s))
|
||||
&& (tsptr += strlen(s))
|
||||
&& (++tsptr))
|
||||
{
|
||||
ts_ok = TRUE;
|
||||
while (! strcspn(tsptr," \t\n") && *tsptr)
|
||||
tsptr++;
|
||||
if (*tsptr)
|
||||
{
|
||||
l = strlen (tsptr) + 1;
|
||||
if (TSOffs + l > tot_ts_size
|
||||
&& (ts_data = HRealloc (ts_data,
|
||||
tot_ts_size += POOL_SIZE)) == 0)
|
||||
{
|
||||
HFree (strdata);
|
||||
return (0);
|
||||
}
|
||||
strcpy (&ts_data[TSOffs], tsptr);
|
||||
TSOffs += l;
|
||||
tslen[n] = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! ts_ok)
|
||||
{
|
||||
// timestamp data is invalid, remove all of it
|
||||
fprintf (stderr, "Invalid timestamp data for '%s'. Disabling timestamps\n", s);
|
||||
HFree (ts_data);
|
||||
fclose (timestamp_fp);
|
||||
timestamp_fp = NULL;
|
||||
TSOffs = 0;
|
||||
}
|
||||
}
|
||||
clen[n] = 0;
|
||||
s = strtok (NULL, " \t\n)");
|
||||
if (s)
|
||||
@@ -142,82 +202,108 @@ _GetStringData (FILE *fp, DWORD length)
|
||||
&& (strdata = HRealloc (strdata,
|
||||
tot_string_size += POOL_SIZE)) == 0)
|
||||
{
|
||||
HFree (clipdata);
|
||||
return (0);
|
||||
HFree (clipdata);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (slen[n])
|
||||
{
|
||||
--slen[n];
|
||||
--StringOffs;
|
||||
}
|
||||
s = &strdata[StringOffs];
|
||||
slen[n] += l;
|
||||
StringOffs += l;
|
||||
|
||||
strcpy (s, CurrentLine);
|
||||
}
|
||||
|
||||
if (slen[n])
|
||||
if ((int)ftell (fp) - (int)opos >= (int)length)
|
||||
break;
|
||||
}
|
||||
#ifdef WIN32
|
||||
_setmode (fileno (fp), omode);
|
||||
#endif
|
||||
if (n >= 0)
|
||||
{
|
||||
while (slen[n] > 1 && strdata[StringOffs - 2] == '\n')
|
||||
{
|
||||
--slen[n];
|
||||
--StringOffs;
|
||||
strdata[StringOffs - 1] = '\0';
|
||||
}
|
||||
s = &strdata[StringOffs];
|
||||
slen[n] += l;
|
||||
StringOffs += l;
|
||||
|
||||
strcpy (s, CurrentLine);
|
||||
}
|
||||
|
||||
if ((int)ftell (fp) - (int)opos >= (int)length)
|
||||
break;
|
||||
}
|
||||
#ifdef WIN32
|
||||
_setmode (fileno (fp), omode);
|
||||
#endif
|
||||
if (n >= 0)
|
||||
{
|
||||
while (slen[n] > 1 && strdata[StringOffs - 2] == '\n')
|
||||
if (timestamp_fp)
|
||||
fclose (timestamp_fp);
|
||||
|
||||
hData = 0;
|
||||
num_data_sets = (ClipOffs ? 1 : 0) + (TSOffs ? 1 : 0) + 1;
|
||||
if (++n && (hData = AllocStringTable (
|
||||
(sizeof (STRING_TABLE_DESC) - sizeof (DWORD))
|
||||
+ (sizeof (DWORD) * ((n + 1) * num_data_sets))
|
||||
+ StringOffs
|
||||
+ ClipOffs
|
||||
+ TSOffs
|
||||
)))
|
||||
{
|
||||
--slen[n];
|
||||
--StringOffs;
|
||||
strdata[StringOffs - 1] = '\0';
|
||||
}
|
||||
}
|
||||
PDWORD lpStringOffs, lpClipOffs, lpTSOffs;
|
||||
STRING_TABLEPTR lpST;
|
||||
|
||||
hData = 0;
|
||||
if (++n && (hData = AllocStringTable (
|
||||
(sizeof (STRING_TABLE_DESC) - sizeof (DWORD))
|
||||
+ (sizeof (DWORD) * ((n + 1) << (ClipOffs ? 1 : 0)))
|
||||
+ StringOffs
|
||||
+ ClipOffs
|
||||
)))
|
||||
{
|
||||
PDWORD lpStringOffs, lpClipOffs;
|
||||
STRING_TABLEPTR lpST;
|
||||
LockStringTable (hData, &lpST);
|
||||
lpST->StringCount = n;
|
||||
lpST->flags = 0;
|
||||
if (ClipOffs)
|
||||
lpST->flags |= HAS_SOUND_CLIPS;
|
||||
if (TSOffs)
|
||||
lpST->flags |= HAS_TIMESTAMP;
|
||||
|
||||
LockStringTable (hData, &lpST);
|
||||
lpST->StringCount = n;
|
||||
lpST->flags = 0;
|
||||
if (ClipOffs)
|
||||
lpST->flags |= HAS_SOUND_CLIPS;
|
||||
memcpy (&lpST->StringOffsets[(n + 1) * num_data_sets], strdata, StringOffs);
|
||||
memcpy ((BYTE *)&lpST->StringOffsets[(n + 1) * num_data_sets] + StringOffs,
|
||||
clipdata, ClipOffs);
|
||||
memcpy ((BYTE *)&lpST->StringOffsets[(n + 1) * num_data_sets]
|
||||
+ StringOffs + ClipOffs, ts_data, TSOffs);
|
||||
TSOffs = ((BYTE *)&lpST->StringOffsets[(n + 1) * num_data_sets]
|
||||
- (BYTE *)lpST) + StringOffs + ClipOffs;
|
||||
ClipOffs = TSOffs - ClipOffs;
|
||||
StringOffs = ClipOffs - StringOffs;
|
||||
|
||||
memcpy (&lpST->StringOffsets[(n + 1) << (ClipOffs ? 1 : 0)], strdata, StringOffs);
|
||||
memcpy ((BYTE *)&lpST->StringOffsets[(n + 1) << (ClipOffs ? 1 : 0)] + StringOffs,
|
||||
clipdata, ClipOffs);
|
||||
ClipOffs = ((BYTE *)&lpST->StringOffsets[(n + 1) << (ClipOffs ? 1 : 0)]
|
||||
- (BYTE *)lpST) + StringOffs;
|
||||
StringOffs = ClipOffs - StringOffs;
|
||||
|
||||
for (n = 0, lpStringOffs = lpST->StringOffsets,
|
||||
lpClipOffs = &lpST->StringOffsets[lpST->StringCount + 1];
|
||||
n < (int)lpST->StringCount; ++n, ++lpStringOffs, ++lpClipOffs)
|
||||
{
|
||||
*lpStringOffs = StringOffs;
|
||||
StringOffs += slen[n];
|
||||
if (lpST->flags & HAS_SOUND_CLIPS)
|
||||
lpStringOffs = lpST->StringOffsets;
|
||||
lpClipOffs = &lpST->StringOffsets[lpST->StringCount + 1];
|
||||
{
|
||||
*lpClipOffs = ClipOffs;
|
||||
ClipOffs += clen[n];
|
||||
long foo = (lpST->StringCount + 1) << ((lpST->flags & HAS_SOUND_CLIPS) ? 1 : 0);
|
||||
}
|
||||
lpTSOffs = &lpST->StringOffsets[(lpST->StringCount + 1)
|
||||
<< ((lpST->flags & HAS_SOUND_CLIPS) ? 1 : 0)];
|
||||
for (n = 0; n < (int)lpST->StringCount;
|
||||
++n, ++lpStringOffs, ++lpClipOffs, ++lpTSOffs)
|
||||
{
|
||||
*lpStringOffs = StringOffs;
|
||||
StringOffs += slen[n];
|
||||
if (lpST->flags & HAS_SOUND_CLIPS)
|
||||
{
|
||||
*lpClipOffs = ClipOffs;
|
||||
ClipOffs += clen[n];
|
||||
}
|
||||
if (lpST->flags & HAS_TIMESTAMP)
|
||||
{
|
||||
*lpTSOffs = TSOffs;
|
||||
TSOffs += tslen[n];
|
||||
}
|
||||
|
||||
}
|
||||
*lpStringOffs = StringOffs;
|
||||
if (lpST->flags & HAS_SOUND_CLIPS)
|
||||
*lpClipOffs = ClipOffs;
|
||||
if (lpST->flags & HAS_TIMESTAMP)
|
||||
*lpTSOffs = TSOffs;
|
||||
|
||||
UnlockStringTable (hData);
|
||||
}
|
||||
*lpStringOffs = StringOffs;
|
||||
if (lpST->flags & HAS_SOUND_CLIPS)
|
||||
*lpClipOffs = ClipOffs;
|
||||
|
||||
UnlockStringTable (hData);
|
||||
}
|
||||
|
||||
HFree (strdata);
|
||||
HFree (strdata);
|
||||
HFree (clipdata);
|
||||
HFree (ts_data);
|
||||
|
||||
return (hData);
|
||||
}
|
||||
|
||||
@@ -185,6 +185,39 @@ GetStringSoundClip (STRING String)
|
||||
return (StringAddr);
|
||||
}
|
||||
|
||||
STRINGPTR
|
||||
GetStringTimeStamp (STRING String)
|
||||
{
|
||||
STRINGPTR StringAddr;
|
||||
STRING_TABLE StringTable;
|
||||
|
||||
if ((StringTable = GetStringTable (String)) == 0)
|
||||
StringAddr = 0;
|
||||
else
|
||||
{
|
||||
COUNT StringIndex;
|
||||
STRING_TABLEPTR StringTablePtr;
|
||||
int offset;
|
||||
|
||||
StringIndex = STRING_INDEX (String);
|
||||
LockStringTable (StringTable, &StringTablePtr);
|
||||
offset = (StringTablePtr->flags & HAS_SOUND_CLIPS) ? 1 : 0;
|
||||
if (!(StringTablePtr->flags & HAS_TIMESTAMP)
|
||||
|| ((StringIndex += (StringTablePtr->StringCount + 1) << offset),
|
||||
StringTablePtr->StringOffsets[StringIndex + 1]
|
||||
== StringTablePtr->StringOffsets[StringIndex]))
|
||||
StringAddr = 0;
|
||||
else
|
||||
{
|
||||
StringAddr = (STRINGPTR)StringTablePtr;
|
||||
((BYTE *) StringAddr) += StringTablePtr->StringOffsets[StringIndex];
|
||||
}
|
||||
UnlockStringTable (StringTable);
|
||||
}
|
||||
|
||||
return (StringAddr);
|
||||
}
|
||||
|
||||
STRINGPTR
|
||||
GetStringAddress (STRING String)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@ typedef struct string_table
|
||||
typedef STRING_TABLE_DESC *PSTRING_TABLE_DESC;
|
||||
|
||||
#define HAS_SOUND_CLIPS (1 << 0)
|
||||
#define HAS_TIMESTAMP (1 << 1)
|
||||
#define STRING_TABLEPTR PSTRING_TABLE_DESC
|
||||
|
||||
#define AllocStringTable(s) AllocResourceData((s),MEM_SOUND)
|
||||
|
||||
@@ -41,6 +41,7 @@ extern STRING SetRelStringTableIndex (STRING String, SIZE
|
||||
extern COUNT GetStringLength (STRING String);
|
||||
extern STRINGPTR GetStringAddress (STRING String);
|
||||
extern STRINGPTR GetStringSoundClip (STRING String);
|
||||
extern STRINGPTR GetStringTimeStamp (STRING String);
|
||||
extern BOOLEAN GetStringContents (STRING String, STRINGPTR StringBuf,
|
||||
BOOLEAN AppendSpace);
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ CDToContentDir (char *contentdir)
|
||||
static int
|
||||
Check_PC_3DO_opt (char *value, DWORD mask, char *opt)
|
||||
{
|
||||
if (value == NULL)
|
||||
{
|
||||
fprintf (stderr, "option '%s' requires a value!\n",opt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((mask & OPT_3DO) && strcmp (value, "3do") == 0)
|
||||
return OPT_3DO;
|
||||
if ((mask & OPT_PC) && strcmp (value, "pc") == 0)
|
||||
|
||||
Reference in New Issue
Block a user