Cleanup of vidlib: move uqm/-specific code out of vidplayer; other

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3223 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2009-10-12 02:19:46 +00:00
parent 2a76a63292
commit 6473363eb2
11 changed files with 298 additions and 175 deletions
+15 -7
View File
@@ -206,6 +206,14 @@ TFB_DrawCommandQueue_Clear ()
UnlockRecursiveMutex (DCQ_Mutex); UnlockRecursiveMutex (DCQ_Mutex);
} }
static inline int
rects_equal (RECT *r1, RECT *r2)
{
return r1->corner.x == r2->corner.x && r1->corner.y == r2->corner.y
&& r1->extent.width == r2->extent.width
&& r1->extent.height == r2->extent.height;
}
void void
TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand) TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
{ {
@@ -220,17 +228,17 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
static RECT scissor_rect; static RECT scissor_rect;
// Set the clipping region. // Set the clipping region.
if (scissor_rect.corner.x != _pCurContext->ClipRect.corner.x // We allow drawing with no current context set, so the whole screen
|| scissor_rect.corner.y != _pCurContext->ClipRect.corner.y if ((_pCurContext && !rects_equal (&scissor_rect, &_pCurContext->ClipRect))
|| scissor_rect.extent.width != || (!_pCurContext && scissor_rect.extent.width != 0))
_pCurContext->ClipRect.extent.width
|| scissor_rect.extent.height !=
_pCurContext->ClipRect.extent.height)
{ {
// Enqueue command to set the glScissor spec // Enqueue command to set the glScissor spec
TFB_DrawCommand DC; TFB_DrawCommand DC;
scissor_rect = _pCurContext->ClipRect; if (_pCurContext)
scissor_rect = _pCurContext->ClipRect;
else
scissor_rect.extent.width = 0;
if (scissor_rect.extent.width) if (scissor_rect.extent.width)
{ {
+65 -22
View File
@@ -1,39 +1,82 @@
#include "vidintrn.h" /*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
BOOLEAN #include "vidintrn.h"
#include "video.h"
#include "vidplayer.h"
#include "libs/memlib.h"
LEGACY_VIDEO_REF
PlayLegacyVideo (LEGACY_VIDEO vid) PlayLegacyVideo (LEGACY_VIDEO vid)
{ {
const char *name, *audname, *speechname; const char *name, *audname, *speechname;
DWORD loopframe; uint32 loopframe;
VIDEO_REF VidRef; LEGACY_VIDEO_REF ref;
MUSIC_REF AudRef = 0; VIDEO_TYPE type;
MUSIC_REF SpeechRef = 0;
if (!vid) if (!vid)
return FALSE; return NULL;
ref = HCalloc (sizeof (*ref));
if (!ref)
return NULL;
name = vid->video; name = vid->video;
audname = vid->audio; audname = vid->audio;
speechname = vid->speech; speechname = vid->speech;
loopframe = vid->loop; loopframe = vid->loop;
VidRef = LoadVideoFile (name); ref->vidref = LoadVideoFile (name);
if (!VidRef) if (!ref->vidref)
return FALSE; return NULL;
if (audname) if (audname)
AudRef = LoadMusicFile (audname); ref->audref = LoadMusicFile (audname);
if (speechname) if (speechname)
SpeechRef = LoadMusicFile (speechname); ref->speechref = LoadMusicFile (speechname);
VidPlayEx (VidRef, AudRef, SpeechRef, loopframe); type = VidPlayEx (ref->vidref, ref->audref, ref->speechref, loopframe);
VidDoInput (); if (type == NO_FMV)
VidStop (); { // Video failed to start
StopLegacyVideo (ref);
return NULL;
}
DestroyVideo (VidRef); return ref;
if (SpeechRef)
DestroyMusic (SpeechRef);
if (AudRef)
DestroyMusic (AudRef);
return TRUE;
} }
void
StopLegacyVideo (LEGACY_VIDEO_REF ref)
{
if (!ref)
return;
if (TFB_VideoPlaying (ref->vidref))
VidStop ();
DestroyVideo (ref->vidref);
if (ref->speechref)
DestroyMusic (ref->speechref);
if (ref->audref)
DestroyMusic (ref->audref);
HFree (ref);
}
BOOLEAN
PlayingLegacyVideo (LEGACY_VIDEO_REF ref)
{
if (!ref)
return FALSE;
return TFB_VideoPlaying (ref->vidref);
}
+25 -21
View File
@@ -16,12 +16,11 @@
#include "video.h" #include "video.h"
#include "vidintrn.h"
#include "options.h" #include "options.h"
#include "vidplayer.h" #include "vidplayer.h"
#include "libs/inplib.h"
#include "libs/memlib.h" #include "libs/memlib.h"
// XXX: we should not include anything from uqm/ inside libs/ #include "libs/sndlib.h"
#include "uqm/setup.h"
#define NULL_VIDEO_REF (0) #define NULL_VIDEO_REF (0)
@@ -52,21 +51,18 @@ UninitVideoPlayer (void)
} }
void void
VidStop () VidStop (void)
{ {
if (_cur_speech) if (_cur_speech)
snd_StopSpeech (); snd_StopSpeech ();
if (_cur_video) if (_cur_video)
{
TFB_StopVideo (_cur_video); TFB_StopVideo (_cur_video);
TFB_FadeClearScreen ();
}
_cur_speech = 0; _cur_speech = 0;
_cur_video = NULL_VIDEO_REF; _cur_video = NULL_VIDEO_REF;
} }
VIDEO_REF VIDEO_REF
VidPlaying () VidPlaying (void)
// this should just probably return BOOLEAN // this should just probably return BOOLEAN
{ {
if (!_cur_video) if (!_cur_video)
@@ -78,6 +74,24 @@ VidPlaying ()
return NULL_VIDEO_REF; return NULL_VIDEO_REF;
} }
// return current video position in milliseconds
DWORD
VidGetPosition (void)
{
if (!VidPlaying ())
return 0;
return TFB_GetVideoPosition (_cur_video);
}
BOOLEAN
VidSeek (DWORD pos)
// pos in milliseconds
{
if (!VidPlaying ())
return FALSE;
return TFB_SeekVideo (_cur_video, pos);
}
VIDEO_TYPE VIDEO_TYPE
VidPlayEx (VIDEO_REF vid, MUSIC_REF AudRef, MUSIC_REF SpeechRef, VidPlayEx (VIDEO_REF vid, MUSIC_REF AudRef, MUSIC_REF SpeechRef,
DWORD LoopFrame) DWORD LoopFrame)
@@ -105,13 +119,10 @@ VidPlayEx (VIDEO_REF vid, MUSIC_REF AudRef, MUSIC_REF SpeechRef,
_cur_speech = 0; _cur_speech = 0;
_cur_video = NULL_VIDEO_REF; _cur_video = NULL_VIDEO_REF;
TFB_FadeClearScreen ();
FlushInput ();
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetContext (ScreenContext);
// play video in the center of the screen // play video in the center of the screen
if (TFB_PlayVideo (vid, (SCREEN_WIDTH - vid->w) / 2, if (TFB_PlayVideo (vid, (ScreenWidth - vid->w) / 2,
(SCREEN_HEIGHT - vid->h) / 2)) (ScreenHeight - vid->h) / 2))
{ {
_cur_video = vid; _cur_video = vid;
ret = SOFTWARE_FMV; ret = SOFTWARE_FMV;
@@ -136,13 +147,6 @@ VidPlay (VIDEO_REF VidRef)
return VidPlayEx (VidRef, 0, 0, VID_NO_LOOP); return VidPlayEx (VidRef, 0, 0, VID_NO_LOOP);
} }
void
VidDoInput (void)
{
if (_cur_video)
TFB_VideoInput (_cur_video);
}
VIDEO_REF VIDEO_REF
_init_video_file (const char *pStr) _init_video_file (const char *pStr)
{ {
@@ -153,7 +157,7 @@ _init_video_file (const char *pStr)
if (!dec) if (!dec)
return NULL_VIDEO_REF; return NULL_VIDEO_REF;
vid = (TFB_VideoClip*) HCalloc (sizeof (*vid)); vid = HCalloc (sizeof (*vid));
vid->decoder = dec; vid->decoder = dec;
vid->length = dec->length; vid->length = dec->length;
vid->w = vid->decoder->w; vid->w = vid->decoder->w;
+1
View File
@@ -18,6 +18,7 @@
#define _UQM_VIDEO_H #define _UQM_VIDEO_H
#include "libs/vidlib.h" #include "libs/vidlib.h"
#include "libs/sndlib.h"
#include "libs/graphics/tfb_draw.h" #include "libs/graphics/tfb_draw.h"
#include "types.h" #include "types.h"
#include "videodec.h" #include "videodec.h"
+1 -1
View File
@@ -245,7 +245,7 @@ VideoDecoder_Load (uio_DirHandle *dir, const char *filename)
return NULL; return NULL;
} }
decoder = (TFB_VideoDecoder*) HCalloc (info->funcs->GetStructSize ()); decoder = HCalloc (info->funcs->GetStructSize ());
decoder->funcs = info->funcs; decoder->funcs = info->funcs;
if (!decoder->funcs->Init (decoder, &vd_vidfmt)) if (!decoder->funcs->Init (decoder, &vd_vidfmt))
{ {
+21 -3
View File
@@ -19,11 +19,29 @@
#ifndef VIDINTERN_H_ #ifndef VIDINTERN_H_
#define VIDINTERN_H_ #define VIDINTERN_H_
#include "types.h"
#include "libs/vidlib.h" #include "libs/vidlib.h"
#include "libs/threadlib.h"
typedef struct legacy_video_desc { struct legacy_video_desc
{
char *video, *audio, *speech; char *video, *audio, *speech;
DWORD loop; uint32 loop;
} LEGACY_VIDEO_DESC; };
typedef struct legacy_video_desc LEGACY_VIDEO_DESC;
struct legacy_video_ref
{
VIDEO_REF vidref;
MUSIC_REF audref;
MUSIC_REF speechref;
};
// XXX: There has to be a better way to synchronize gfx calls with the rest
// of the game. The only thing we need to sync is the current context, and
// even there only the cliprect. Perhaps a DCQ command that takes an
// explicit cliprect would be better.
extern Mutex GraphicsLock;
#endif #endif
+46 -101
View File
@@ -16,15 +16,12 @@
#include "vidplayer.h" #include "vidplayer.h"
#include "vidintrn.h"
#include "libs/graphics/gfx_common.h" #include "libs/graphics/gfx_common.h"
#include "libs/graphics/tfb_draw.h" #include "libs/graphics/tfb_draw.h"
#include "libs/log.h" #include "libs/log.h"
#include "libs/memlib.h" #include "libs/memlib.h"
// XXX: we should not include anything from uqm/ inside libs/ #include "libs/sndlib.h"
#include "uqm/controls.h"
#include "uqm/settings.h"
#include "uqm/setup.h"
#include "uqm/sounds.h"
// video callbacks // video callbacks
static void vp_BeginFrame (TFB_VideoDecoder*); static void vp_BeginFrame (TFB_VideoDecoder*);
@@ -62,16 +59,6 @@ static TFB_SoundCallbacks vp_AudioCBs =
static Semaphore vp_interthread_lock = 0; static Semaphore vp_interthread_lock = 0;
static void* vp_interthread_clip = NULL; static void* vp_interthread_clip = NULL;
typedef struct
{
// standard state required by DoInput
BOOLEAN (*InputFunc) (void *pInputState);
COUNT MenuRepeatDelay;
VIDEO_REF CurVideo;
} VIDEO_INPUT_STATE;
bool bool
TFB_InitVideoPlayer (void) TFB_InitVideoPlayer (void)
{ {
@@ -87,29 +74,6 @@ TFB_UninitVideoPlayer (void)
DestroySemaphore (vp_interthread_lock); DestroySemaphore (vp_interthread_lock);
} }
void
TFB_FadeClearScreen (void)
{
BYTE xform_buf[1];
RECT r = {{0, 0}, {SCREEN_WIDTH, SCREEN_HEIGHT}};
xform_buf[0] = FadeAllToBlack;
SleepThreadUntil (XFormColorMap (
(COLORMAPPTR) xform_buf, ONE_SECOND / 2));
// paint black rect over screen
LockMutex (GraphicsLock);
SetContext (ScreenContext);
SetContextForeGroundColor (
BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00));
DrawFilledRectangle (&r);
UnlockMutex (GraphicsLock);
// fade in black rect instantly
xform_buf[0] = FadeAllToColor;
XFormColorMap ((COLORMAPPTR) xform_buf, 0);
}
// audio-synced video playback task // audio-synced video playback task
// the frame rate and timing is dictated by the audio // the frame rate and timing is dictated by the audio
static int static int
@@ -131,7 +95,7 @@ as_video_play_task (void *data)
LockMutex (vid->guard); LockMutex (vid->guard);
want_frame = vid->want_frame; want_frame = vid->want_frame;
if (vid->hAudio) if (vid->hAudio)
PlayMusic (vid->hAudio, FALSE, 1); PLRPlaySong (vid->hAudio, FALSE, 1);
UnlockMutex (vid->guard); UnlockMutex (vid->guard);
clagged = 0; clagged = 0;
@@ -201,11 +165,15 @@ as_video_play_task (void *data)
// draw the frame // draw the frame
if (ret > 0) if (ret > 0)
{ {
CONTEXT oldContext;
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetContext (ScreenContext); // We have the cliprect precalculated and don't need the rest
oldContext = SetContext (NULL);
TFB_DrawScreen_Image (vid->frame, TFB_DrawScreen_Image (vid->frame,
vid->dst_rect.corner.x, vid->dst_rect.corner.y, vid->dst_rect.corner.x, vid->dst_rect.corner.y,
GSCALE_IDENTITY, NULL, TFB_SCREEN_MAIN); GSCALE_IDENTITY, NULL, TFB_SCREEN_MAIN);
SetContext (oldContext);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
FlushGraphics (); // needed to prevent half-frame updates FlushGraphics (); // needed to prevent half-frame updates
} }
@@ -217,7 +185,7 @@ as_video_play_task (void *data)
ret = VideoDecoder_Decode (vid->decoder); ret = VideoDecoder_Decode (vid->decoder);
} }
if (vid->hAudio) if (vid->hAudio)
StopMusic (); PLRStop (vid->hAudio);
vid->playing = false; vid->playing = false;
FinishTask (task); FinishTask (task);
@@ -241,7 +209,7 @@ video_play_task (void *data)
LockMutex (vid->guard); LockMutex (vid->guard);
if (vid->hAudio) if (vid->hAudio)
PlayMusic (vid->hAudio, (vid->loop_frame != VID_NO_LOOP), 1); PLRPlaySong (vid->hAudio, (vid->loop_frame != VID_NO_LOOP), 1);
UnlockMutex (vid->guard); UnlockMutex (vid->guard);
@@ -258,15 +226,19 @@ video_play_task (void *data)
while (!Task_ReadState (task, TASK_EXIT) && ret > 0) while (!Task_ReadState (task, TASK_EXIT) && ret > 0)
{ {
CONTEXT oldContext;
// wait till its time to render next frame // wait till its time to render next frame
SleepThreadUntil (vid->frame_time); SleepThreadUntil (vid->frame_time);
vid->cur_frame = vid->decoder->cur_frame; vid->cur_frame = vid->decoder->cur_frame;
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetContext (ScreenContext); // We have the cliprect precalculated and don't need the rest
oldContext = SetContext (NULL);
TFB_DrawScreen_Image (vid->frame, TFB_DrawScreen_Image (vid->frame,
vid->dst_rect.corner.x, vid->dst_rect.corner.y, vid->dst_rect.corner.x, vid->dst_rect.corner.y,
GSCALE_IDENTITY, NULL, TFB_SCREEN_MAIN); GSCALE_IDENTITY, NULL, TFB_SCREEN_MAIN);
SetContext (oldContext);
UnlockMutex (GraphicsLock); UnlockMutex (GraphicsLock);
FlushGraphics (); // needed to prevent half-frame updates FlushGraphics (); // needed to prevent half-frame updates
@@ -277,7 +249,7 @@ video_play_task (void *data)
} }
vid->playing = false; vid->playing = false;
if (vid->hAudio) if (vid->hAudio)
StopMusic (); PLRStop (vid->hAudio);
FinishTask (task); FinishTask (task);
@@ -289,7 +261,7 @@ TFB_PlayVideo (VIDEO_REF vid, uint32 x, uint32 y)
{ {
RECT scrn_r; RECT scrn_r;
RECT clip_r = {{0, 0}, {vid->w, vid->h}}; RECT clip_r = {{0, 0}, {vid->w, vid->h}};
RECT vid_r = {{0, 0}, {SCREEN_WIDTH, SCREEN_HEIGHT}}; RECT vid_r = {{0, 0}, {ScreenWidth, ScreenHeight}};
RECT dr = {{x, y}, {vid->w, vid->h}}; RECT dr = {{x, y}, {vid->w, vid->h}};
RECT sr; RECT sr;
@@ -333,8 +305,6 @@ TFB_PlayVideo (VIDEO_REF vid, uint32 x, uint32 y)
vid->own_audio = true; vid->own_audio = true;
} }
StopMusic ();
if (vid->decoder->audio_synced) if (vid->decoder->audio_synced)
{ {
TFB_SoundSample **pmus; TFB_SoundSample **pmus;
@@ -389,7 +359,7 @@ TFB_StopVideo (VIDEO_REF vid)
if (vid->hAudio) if (vid->hAudio)
{ {
StopMusic (); PLRStop (vid->hAudio);
if (vid->own_audio) if (vid->own_audio)
{ {
DestroyMusic (vid->hAudio); DestroyMusic (vid->hAudio);
@@ -413,67 +383,42 @@ TFB_VideoPlaying (VIDEO_REF vid)
return vid->playing; return vid->playing;
} }
static BOOLEAN uint32
TFB_DoVideoInput (void *pIS) TFB_GetVideoPosition (VIDEO_REF vid)
{ {
VIDEO_INPUT_STATE* pVIS = (VIDEO_INPUT_STATE*) pIS; uint32 pos;
TFB_VideoClip* vid = pVIS->CurVideo;
if (!pVIS->CurVideo || !TFB_VideoPlaying (pVIS->CurVideo)) if (!TFB_VideoPlaying (vid))
return FALSE; return 0;
if (PulsedInputState.menu[KEY_MENU_SELECT] LockMutex (vid->guard);
|| PulsedInputState.menu[KEY_MENU_CANCEL] pos = (uint32) (vid->decoder->pos * 1000);
|| PulsedInputState.menu[KEY_MENU_SPECIAL] UnlockMutex (vid->guard);
|| (GLOBAL (CurrentActivity) & CHECK_ABORT))
{ // abort movie
TFB_StopVideo (pVIS->CurVideo);
return FALSE;
}
else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT])
{
if (vid->decoder->audio_synced)
{
float newpos;
LockMutex (vid->guard);
newpos = vid->decoder->pos;
UnlockMutex (vid->guard);
if (PulsedInputState.menu[KEY_MENU_LEFT]) return pos;
newpos -= 2;
else if (PulsedInputState.menu[KEY_MENU_RIGHT])
newpos += 1;
if (newpos < 0)
newpos = 0;
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
SeekStream (MUSIC_SOURCE, (uint32) (newpos * 1000));
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
TaskSwitch ();
}
// non a/s decoder seeking is not supported yet
}
else
{
SleepThread (ONE_SECOND / 30);
}
return TRUE;
} }
void bool
TFB_VideoInput (VIDEO_REF VidRef) TFB_SeekVideo (VIDEO_REF vid, uint32 pos)
{ {
VIDEO_INPUT_STATE vis; if (!TFB_VideoPlaying (vid))
return false;
vis.MenuRepeatDelay = 0; if (vid->decoder->audio_synced)
vis.InputFunc = TFB_DoVideoInput; {
vis.CurVideo = VidRef; LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
SeekStream (MUSIC_SOURCE, pos);
SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
DoInput (&vis, TRUE); TaskSwitch ();
return true;
}
else
{ // TODO: Non-a/s decoder seeking is not supported yet
// Decide what to do with these. Seeking this kind of
// video is trivial, but we may not want to do it.
// The only non-a/s videos right now are ship spins.
return false;
}
} }
static void static void
+7 -8
View File
@@ -19,13 +19,12 @@
#include "video.h" #include "video.h"
bool TFB_InitVideoPlayer (void); extern bool TFB_InitVideoPlayer (void);
void TFB_UninitVideoPlayer (void); extern void TFB_UninitVideoPlayer (void);
void TFB_FadeClearScreen (void); extern bool TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y);
bool TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y); extern void TFB_StopVideo (VIDEO_REF VidRef);
void TFB_StopVideo (VIDEO_REF VidRef); extern bool TFB_VideoPlaying (VIDEO_REF VidRef);
bool TFB_VideoPlaying (VIDEO_REF VidRef); extern uint32 TFB_GetVideoPosition (VIDEO_REF VidRef);
void TFB_VideoInput (VIDEO_REF VidRef); extern bool TFB_SeekVideo (VIDEO_REF VidRef, uint32 pos);
#endif // _VIDPLAYER_H #endif // _VIDPLAYER_H
+3 -3
View File
@@ -47,7 +47,7 @@ GetLegacyVideoData (const char *path, RESOURCE_DATA *resdata)
{ {
void *result = NULL; void *result = NULL;
char paths[1024], *audio_path, *speech_path, *loop_str; char paths[1024], *audio_path, *speech_path, *loop_str;
DWORD LoopFrame = VID_NO_LOOP; uint32 LoopFrame = VID_NO_LOOP;
/* Parse out the video components. */ /* Parse out the video components. */
strncpy (paths, path, 1023); strncpy (paths, path, 1023);
@@ -93,13 +93,13 @@ GetLegacyVideoData (const char *path, RESOURCE_DATA *resdata)
if (loop_str) if (loop_str)
{ {
char *end; char *end;
LoopFrame = (DWORD) strtol (loop_str, &end, 10); LoopFrame = strtol (loop_str, &end, 10);
// We allow whitespace at the end, but nothing printable. // We allow whitespace at the end, but nothing printable.
if (*end > 32) { if (*end > 32) {
log_add (log_Warning, "Warning: Unparsable loop frame '%s'. Disabling loop.", loop_str); log_add (log_Warning, "Warning: Unparsable loop frame '%s'. Disabling loop.", loop_str);
LoopFrame = VID_NO_LOOP; LoopFrame = VID_NO_LOOP;
} }
log_add (log_Info, "\tLoop frame is %d", LoopFrame); log_add (log_Info, "\tLoop frame is %u", LoopFrame);
} }
else else
log_add (log_Info, "\tNo specified loop frame"); log_add (log_Info, "\tNo specified loop frame");
+9 -5
View File
@@ -32,6 +32,7 @@ typedef enum
typedef struct tfb_videoclip *VIDEO_REF; typedef struct tfb_videoclip *VIDEO_REF;
typedef struct legacy_video_desc *LEGACY_VIDEO; typedef struct legacy_video_desc *LEGACY_VIDEO;
typedef struct legacy_video_ref *LEGACY_VIDEO_REF;
extern BOOLEAN InstallVideoResType (void); extern BOOLEAN InstallVideoResType (void);
@@ -39,17 +40,20 @@ extern BOOLEAN InitVideoPlayer (BOOLEAN UseCDROM);
extern void UninitVideoPlayer (void); extern void UninitVideoPlayer (void);
extern VIDEO_REF LoadVideoFile (const char *pStr); extern VIDEO_REF LoadVideoFile (const char *pStr);
extern BOOLEAN DestroyVideo (VIDEO_REF VideoRef); extern BOOLEAN DestroyVideo (VIDEO_REF VidRef);
extern VIDEO_TYPE VidPlay (VIDEO_REF VidRef); extern VIDEO_TYPE VidPlay (VIDEO_REF VidRef);
extern VIDEO_TYPE VidPlayEx (VIDEO_REF VidRef, MUSIC_REF AudRef, extern VIDEO_TYPE VidPlayEx (VIDEO_REF VidRef, MUSIC_REF AudRef,
MUSIC_REF SpeechRef, DWORD LoopFrame); MUSIC_REF SpeechRef, DWORD LoopFrame);
#define VID_NO_LOOP (0U-1) #define VID_NO_LOOP (0U-1)
extern void VidStop (void); extern void VidStop (void);
extern VIDEO_REF VidPlaying (void); extern VIDEO_REF VidPlaying (void);
extern void VidDoInput (void); extern DWORD VidGetPosition (void); // position in milliseconds
extern BOOLEAN VidSeek (DWORD pos); // position in milliseconds
LEGACY_VIDEO LoadLegacyVideoInstance (RESOURCE res); extern LEGACY_VIDEO LoadLegacyVideoInstance (RESOURCE res);
BOOLEAN PlayLegacyVideo (LEGACY_VIDEO vid); extern BOOLEAN DestroyLegacyVideo (LEGACY_VIDEO vid);
BOOLEAN DestroyLegacyVideo (LEGACY_VIDEO vid); extern LEGACY_VIDEO_REF PlayLegacyVideo (LEGACY_VIDEO vid);
extern void StopLegacyVideo (LEGACY_VIDEO_REF ref);
extern BOOLEAN PlayingLegacyVideo (LEGACY_VIDEO_REF ref);
#endif /* _VIDLIB_H */ #endif /* _VIDLIB_H */
+105 -4
View File
@@ -85,6 +85,16 @@ typedef struct {
int debounce; int debounce;
} SPINANIM_INPUT_STATE; } SPINANIM_INPUT_STATE;
typedef struct
{
// standard state required by DoInput
BOOLEAN (*InputFunc) (void *pInputState);
COUNT MenuRepeatDelay;
LEGACY_VIDEO_REF CurVideo;
} VIDEO_INPUT_STATE;
static BOOLEAN DoPresentation (void *pIS); static BOOLEAN DoPresentation (void *pIS);
static BOOLEAN static BOOLEAN
@@ -795,7 +805,6 @@ ShowSlidePresentation (STRING PresStr)
DestroyDrawable (ReleaseDrawable (pis.Frame)); DestroyDrawable (ReleaseDrawable (pis.Frame));
for (i = 0; i < MAX_FONTS; ++i) for (i = 0; i < MAX_FONTS; ++i)
DestroyFont (pis.Fonts[i]); DestroyFont (pis.Fonts[i]);
DestroyStringTable (ReleaseStringTable (pis.SlideShow));
LockMutex (GraphicsLock); LockMutex (GraphicsLock);
SetContextFont (OldFont); SetContextFont (OldFont);
@@ -806,6 +815,96 @@ ShowSlidePresentation (STRING PresStr)
return TRUE; return TRUE;
} }
static BOOLEAN
DoVideoInput (void *pIS)
{
VIDEO_INPUT_STATE* pVIS = (VIDEO_INPUT_STATE*) pIS;
if (!PlayingLegacyVideo (pVIS->CurVideo))
{ // Video probably finished
// Have to call VidStop anyway to cleanup
VidStop ();
return FALSE;
}
if (PulsedInputState.menu[KEY_MENU_SELECT]
|| PulsedInputState.menu[KEY_MENU_CANCEL]
|| PulsedInputState.menu[KEY_MENU_SPECIAL]
|| (GLOBAL (CurrentActivity) & CHECK_ABORT))
{ // abort movie
VidStop ();
return FALSE;
}
else if (PulsedInputState.menu[KEY_MENU_LEFT]
|| PulsedInputState.menu[KEY_MENU_RIGHT])
{
SDWORD newpos = VidGetPosition ();
if (PulsedInputState.menu[KEY_MENU_LEFT])
newpos -= 2000;
else if (PulsedInputState.menu[KEY_MENU_RIGHT])
newpos += 1000;
if (newpos < 0)
newpos = 0;
VidSeek (newpos);
}
else
{
SleepThread (ONE_SECOND / 30);
}
return TRUE;
}
static void
FadeClearScreen (void)
{
BYTE xform_buf[1];
RECT r = {{0, 0}, {SCREEN_WIDTH, SCREEN_HEIGHT}};
xform_buf[0] = FadeAllToBlack;
SleepThreadUntil (XFormColorMap (
(COLORMAPPTR) xform_buf, ONE_SECOND / 2));
// paint black rect over screen
LockMutex (GraphicsLock);
SetContext (ScreenContext);
SetContextForeGroundColor (
BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x00), 0x00));
DrawFilledRectangle (&r);
UnlockMutex (GraphicsLock);
// fade in black rect instantly
xform_buf[0] = FadeAllToColor;
XFormColorMap ((COLORMAPPTR) xform_buf, 0);
}
static BOOLEAN
ShowLegacyVideo (LEGACY_VIDEO vid)
{
VIDEO_INPUT_STATE vis;
LEGACY_VIDEO_REF ref;
FadeClearScreen ();
ref = PlayLegacyVideo (vid);
if (!ref)
return FALSE;
// XXX: FlushInput() won't be need once DoInput(reset-input) works right
FlushInput ();
vis.MenuRepeatDelay = 0;
vis.InputFunc = DoVideoInput;
vis.CurVideo = ref;
SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE);
DoInput (&vis, TRUE);
StopLegacyVideo (ref);
FadeClearScreen ();
return TRUE;
}
BOOLEAN BOOLEAN
ShowPresentation (RESOURCE res) ShowPresentation (RESOURCE res)
{ {
@@ -816,13 +915,15 @@ ShowPresentation (RESOURCE res)
} }
if (!strcmp (resType, "STRTAB")) if (!strcmp (resType, "STRTAB"))
{ {
return ShowSlidePresentation (CaptureStringTable ( STRING pres = CaptureStringTable (LoadStringTable (res));
LoadStringTable (res))); BOOLEAN result = ShowSlidePresentation (pres);
DestroyStringTable (ReleaseStringTable (pres));
return result;
} }
else if (!strcmp (resType, "3DOVID")) else if (!strcmp (resType, "3DOVID"))
{ {
LEGACY_VIDEO vid = LoadLegacyVideoInstance (res); LEGACY_VIDEO vid = LoadLegacyVideoInstance (res);
BOOLEAN result = PlayLegacyVideo (vid); BOOLEAN result = ShowLegacyVideo (vid);
DestroyLegacyVideo (vid); DestroyLegacyVideo (vid);
return result; return result;
} }