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:
@@ -206,6 +206,14 @@ TFB_DrawCommandQueue_Clear ()
|
||||
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
|
||||
TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
|
||||
{
|
||||
@@ -220,17 +228,17 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand)
|
||||
static RECT scissor_rect;
|
||||
|
||||
// Set the clipping region.
|
||||
if (scissor_rect.corner.x != _pCurContext->ClipRect.corner.x
|
||||
|| scissor_rect.corner.y != _pCurContext->ClipRect.corner.y
|
||||
|| scissor_rect.extent.width !=
|
||||
_pCurContext->ClipRect.extent.width
|
||||
|| scissor_rect.extent.height !=
|
||||
_pCurContext->ClipRect.extent.height)
|
||||
// We allow drawing with no current context set, so the whole screen
|
||||
if ((_pCurContext && !rects_equal (&scissor_rect, &_pCurContext->ClipRect))
|
||||
|| (!_pCurContext && scissor_rect.extent.width != 0))
|
||||
{
|
||||
// Enqueue command to set the glScissor spec
|
||||
TFB_DrawCommand DC;
|
||||
|
||||
if (_pCurContext)
|
||||
scissor_rect = _pCurContext->ClipRect;
|
||||
else
|
||||
scissor_rect.extent.width = 0;
|
||||
|
||||
if (scissor_rect.extent.width)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
const char *name, *audname, *speechname;
|
||||
DWORD loopframe;
|
||||
VIDEO_REF VidRef;
|
||||
MUSIC_REF AudRef = 0;
|
||||
MUSIC_REF SpeechRef = 0;
|
||||
uint32 loopframe;
|
||||
LEGACY_VIDEO_REF ref;
|
||||
VIDEO_TYPE type;
|
||||
|
||||
if (!vid)
|
||||
return FALSE;
|
||||
return NULL;
|
||||
ref = HCalloc (sizeof (*ref));
|
||||
if (!ref)
|
||||
return NULL;
|
||||
name = vid->video;
|
||||
audname = vid->audio;
|
||||
speechname = vid->speech;
|
||||
loopframe = vid->loop;
|
||||
|
||||
VidRef = LoadVideoFile (name);
|
||||
if (!VidRef)
|
||||
return FALSE;
|
||||
ref->vidref = LoadVideoFile (name);
|
||||
if (!ref->vidref)
|
||||
return NULL;
|
||||
if (audname)
|
||||
AudRef = LoadMusicFile (audname);
|
||||
ref->audref = LoadMusicFile (audname);
|
||||
if (speechname)
|
||||
SpeechRef = LoadMusicFile (speechname);
|
||||
ref->speechref = LoadMusicFile (speechname);
|
||||
|
||||
VidPlayEx (VidRef, AudRef, SpeechRef, loopframe);
|
||||
VidDoInput ();
|
||||
VidStop ();
|
||||
|
||||
DestroyVideo (VidRef);
|
||||
if (SpeechRef)
|
||||
DestroyMusic (SpeechRef);
|
||||
if (AudRef)
|
||||
DestroyMusic (AudRef);
|
||||
|
||||
return TRUE;
|
||||
type = VidPlayEx (ref->vidref, ref->audref, ref->speechref, loopframe);
|
||||
if (type == NO_FMV)
|
||||
{ // Video failed to start
|
||||
StopLegacyVideo (ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
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
@@ -16,12 +16,11 @@
|
||||
|
||||
#include "video.h"
|
||||
|
||||
#include "vidintrn.h"
|
||||
#include "options.h"
|
||||
#include "vidplayer.h"
|
||||
#include "libs/inplib.h"
|
||||
#include "libs/memlib.h"
|
||||
// XXX: we should not include anything from uqm/ inside libs/
|
||||
#include "uqm/setup.h"
|
||||
#include "libs/sndlib.h"
|
||||
|
||||
|
||||
#define NULL_VIDEO_REF (0)
|
||||
@@ -52,21 +51,18 @@ UninitVideoPlayer (void)
|
||||
}
|
||||
|
||||
void
|
||||
VidStop ()
|
||||
VidStop (void)
|
||||
{
|
||||
if (_cur_speech)
|
||||
snd_StopSpeech ();
|
||||
if (_cur_video)
|
||||
{
|
||||
TFB_StopVideo (_cur_video);
|
||||
TFB_FadeClearScreen ();
|
||||
}
|
||||
_cur_speech = 0;
|
||||
_cur_video = NULL_VIDEO_REF;
|
||||
}
|
||||
|
||||
VIDEO_REF
|
||||
VidPlaying ()
|
||||
VidPlaying (void)
|
||||
// this should just probably return BOOLEAN
|
||||
{
|
||||
if (!_cur_video)
|
||||
@@ -78,6 +74,24 @@ VidPlaying ()
|
||||
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
|
||||
VidPlayEx (VIDEO_REF vid, MUSIC_REF AudRef, MUSIC_REF SpeechRef,
|
||||
DWORD LoopFrame)
|
||||
@@ -105,13 +119,10 @@ VidPlayEx (VIDEO_REF vid, MUSIC_REF AudRef, MUSIC_REF SpeechRef,
|
||||
_cur_speech = 0;
|
||||
_cur_video = NULL_VIDEO_REF;
|
||||
|
||||
TFB_FadeClearScreen ();
|
||||
FlushInput ();
|
||||
LockMutex (GraphicsLock);
|
||||
SetContext (ScreenContext);
|
||||
// play video in the center of the screen
|
||||
if (TFB_PlayVideo (vid, (SCREEN_WIDTH - vid->w) / 2,
|
||||
(SCREEN_HEIGHT - vid->h) / 2))
|
||||
if (TFB_PlayVideo (vid, (ScreenWidth - vid->w) / 2,
|
||||
(ScreenHeight - vid->h) / 2))
|
||||
{
|
||||
_cur_video = vid;
|
||||
ret = SOFTWARE_FMV;
|
||||
@@ -136,13 +147,6 @@ VidPlay (VIDEO_REF VidRef)
|
||||
return VidPlayEx (VidRef, 0, 0, VID_NO_LOOP);
|
||||
}
|
||||
|
||||
void
|
||||
VidDoInput (void)
|
||||
{
|
||||
if (_cur_video)
|
||||
TFB_VideoInput (_cur_video);
|
||||
}
|
||||
|
||||
VIDEO_REF
|
||||
_init_video_file (const char *pStr)
|
||||
{
|
||||
@@ -153,7 +157,7 @@ _init_video_file (const char *pStr)
|
||||
if (!dec)
|
||||
return NULL_VIDEO_REF;
|
||||
|
||||
vid = (TFB_VideoClip*) HCalloc (sizeof (*vid));
|
||||
vid = HCalloc (sizeof (*vid));
|
||||
vid->decoder = dec;
|
||||
vid->length = dec->length;
|
||||
vid->w = vid->decoder->w;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define _UQM_VIDEO_H
|
||||
|
||||
#include "libs/vidlib.h"
|
||||
#include "libs/sndlib.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "types.h"
|
||||
#include "videodec.h"
|
||||
|
||||
@@ -245,7 +245,7 @@ VideoDecoder_Load (uio_DirHandle *dir, const char *filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decoder = (TFB_VideoDecoder*) HCalloc (info->funcs->GetStructSize ());
|
||||
decoder = HCalloc (info->funcs->GetStructSize ());
|
||||
decoder->funcs = info->funcs;
|
||||
if (!decoder->funcs->Init (decoder, &vd_vidfmt))
|
||||
{
|
||||
|
||||
@@ -19,11 +19,29 @@
|
||||
#ifndef VIDINTERN_H_
|
||||
#define VIDINTERN_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "libs/vidlib.h"
|
||||
#include "libs/threadlib.h"
|
||||
|
||||
typedef struct legacy_video_desc {
|
||||
struct legacy_video_desc
|
||||
{
|
||||
char *video, *audio, *speech;
|
||||
DWORD loop;
|
||||
} LEGACY_VIDEO_DESC;
|
||||
uint32 loop;
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
@@ -16,15 +16,12 @@
|
||||
|
||||
#include "vidplayer.h"
|
||||
|
||||
#include "vidintrn.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "libs/log.h"
|
||||
#include "libs/memlib.h"
|
||||
// XXX: we should not include anything from uqm/ inside libs/
|
||||
#include "uqm/controls.h"
|
||||
#include "uqm/settings.h"
|
||||
#include "uqm/setup.h"
|
||||
#include "uqm/sounds.h"
|
||||
#include "libs/sndlib.h"
|
||||
|
||||
// video callbacks
|
||||
static void vp_BeginFrame (TFB_VideoDecoder*);
|
||||
@@ -62,16 +59,6 @@ static TFB_SoundCallbacks vp_AudioCBs =
|
||||
static Semaphore vp_interthread_lock = 0;
|
||||
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
|
||||
TFB_InitVideoPlayer (void)
|
||||
{
|
||||
@@ -87,29 +74,6 @@ TFB_UninitVideoPlayer (void)
|
||||
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
|
||||
// the frame rate and timing is dictated by the audio
|
||||
static int
|
||||
@@ -131,7 +95,7 @@ as_video_play_task (void *data)
|
||||
LockMutex (vid->guard);
|
||||
want_frame = vid->want_frame;
|
||||
if (vid->hAudio)
|
||||
PlayMusic (vid->hAudio, FALSE, 1);
|
||||
PLRPlaySong (vid->hAudio, FALSE, 1);
|
||||
UnlockMutex (vid->guard);
|
||||
|
||||
clagged = 0;
|
||||
@@ -201,11 +165,15 @@ as_video_play_task (void *data)
|
||||
// draw the frame
|
||||
if (ret > 0)
|
||||
{
|
||||
CONTEXT oldContext;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
SetContext (ScreenContext);
|
||||
// We have the cliprect precalculated and don't need the rest
|
||||
oldContext = SetContext (NULL);
|
||||
TFB_DrawScreen_Image (vid->frame,
|
||||
vid->dst_rect.corner.x, vid->dst_rect.corner.y,
|
||||
GSCALE_IDENTITY, NULL, TFB_SCREEN_MAIN);
|
||||
SetContext (oldContext);
|
||||
UnlockMutex (GraphicsLock);
|
||||
FlushGraphics (); // needed to prevent half-frame updates
|
||||
}
|
||||
@@ -217,7 +185,7 @@ as_video_play_task (void *data)
|
||||
ret = VideoDecoder_Decode (vid->decoder);
|
||||
}
|
||||
if (vid->hAudio)
|
||||
StopMusic ();
|
||||
PLRStop (vid->hAudio);
|
||||
vid->playing = false;
|
||||
|
||||
FinishTask (task);
|
||||
@@ -241,7 +209,7 @@ video_play_task (void *data)
|
||||
|
||||
LockMutex (vid->guard);
|
||||
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);
|
||||
|
||||
@@ -258,15 +226,19 @@ video_play_task (void *data)
|
||||
|
||||
while (!Task_ReadState (task, TASK_EXIT) && ret > 0)
|
||||
{
|
||||
CONTEXT oldContext;
|
||||
|
||||
// wait till its time to render next frame
|
||||
SleepThreadUntil (vid->frame_time);
|
||||
vid->cur_frame = vid->decoder->cur_frame;
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
SetContext (ScreenContext);
|
||||
// We have the cliprect precalculated and don't need the rest
|
||||
oldContext = SetContext (NULL);
|
||||
TFB_DrawScreen_Image (vid->frame,
|
||||
vid->dst_rect.corner.x, vid->dst_rect.corner.y,
|
||||
GSCALE_IDENTITY, NULL, TFB_SCREEN_MAIN);
|
||||
SetContext (oldContext);
|
||||
UnlockMutex (GraphicsLock);
|
||||
FlushGraphics (); // needed to prevent half-frame updates
|
||||
|
||||
@@ -277,7 +249,7 @@ video_play_task (void *data)
|
||||
}
|
||||
vid->playing = false;
|
||||
if (vid->hAudio)
|
||||
StopMusic ();
|
||||
PLRStop (vid->hAudio);
|
||||
|
||||
FinishTask (task);
|
||||
|
||||
@@ -289,7 +261,7 @@ TFB_PlayVideo (VIDEO_REF vid, uint32 x, uint32 y)
|
||||
{
|
||||
RECT scrn_r;
|
||||
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 sr;
|
||||
|
||||
@@ -333,8 +305,6 @@ TFB_PlayVideo (VIDEO_REF vid, uint32 x, uint32 y)
|
||||
vid->own_audio = true;
|
||||
}
|
||||
|
||||
StopMusic ();
|
||||
|
||||
if (vid->decoder->audio_synced)
|
||||
{
|
||||
TFB_SoundSample **pmus;
|
||||
@@ -389,7 +359,7 @@ TFB_StopVideo (VIDEO_REF vid)
|
||||
|
||||
if (vid->hAudio)
|
||||
{
|
||||
StopMusic ();
|
||||
PLRStop (vid->hAudio);
|
||||
if (vid->own_audio)
|
||||
{
|
||||
DestroyMusic (vid->hAudio);
|
||||
@@ -413,67 +383,42 @@ TFB_VideoPlaying (VIDEO_REF vid)
|
||||
return vid->playing;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
TFB_DoVideoInput (void *pIS)
|
||||
uint32
|
||||
TFB_GetVideoPosition (VIDEO_REF vid)
|
||||
{
|
||||
VIDEO_INPUT_STATE* pVIS = (VIDEO_INPUT_STATE*) pIS;
|
||||
TFB_VideoClip* vid = pVIS->CurVideo;
|
||||
uint32 pos;
|
||||
|
||||
if (!pVIS->CurVideo || !TFB_VideoPlaying (pVIS->CurVideo))
|
||||
return FALSE;
|
||||
|
||||
if (PulsedInputState.menu[KEY_MENU_SELECT]
|
||||
|| PulsedInputState.menu[KEY_MENU_CANCEL]
|
||||
|| PulsedInputState.menu[KEY_MENU_SPECIAL]
|
||||
|| (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;
|
||||
if (!TFB_VideoPlaying (vid))
|
||||
return 0;
|
||||
|
||||
LockMutex (vid->guard);
|
||||
newpos = vid->decoder->pos;
|
||||
pos = (uint32) (vid->decoder->pos * 1000);
|
||||
UnlockMutex (vid->guard);
|
||||
|
||||
if (PulsedInputState.menu[KEY_MENU_LEFT])
|
||||
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 ();
|
||||
return pos;
|
||||
}
|
||||
// non a/s decoder seeking is not supported yet
|
||||
|
||||
bool
|
||||
TFB_SeekVideo (VIDEO_REF vid, uint32 pos)
|
||||
{
|
||||
if (!TFB_VideoPlaying (vid))
|
||||
return false;
|
||||
|
||||
if (vid->decoder->audio_synced)
|
||||
{
|
||||
LockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
SeekStream (MUSIC_SOURCE, pos);
|
||||
UnlockMutex (soundSource[MUSIC_SOURCE].stream_mutex);
|
||||
TaskSwitch ();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SleepThread (ONE_SECOND / 30);
|
||||
{ // 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;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
TFB_VideoInput (VIDEO_REF VidRef)
|
||||
{
|
||||
VIDEO_INPUT_STATE vis;
|
||||
|
||||
vis.MenuRepeatDelay = 0;
|
||||
vis.InputFunc = TFB_DoVideoInput;
|
||||
vis.CurVideo = VidRef;
|
||||
|
||||
SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE);
|
||||
DoInput (&vis, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -19,13 +19,12 @@
|
||||
|
||||
#include "video.h"
|
||||
|
||||
bool TFB_InitVideoPlayer (void);
|
||||
void TFB_UninitVideoPlayer (void);
|
||||
void TFB_FadeClearScreen (void);
|
||||
bool TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y);
|
||||
void TFB_StopVideo (VIDEO_REF VidRef);
|
||||
bool TFB_VideoPlaying (VIDEO_REF VidRef);
|
||||
void TFB_VideoInput (VIDEO_REF VidRef);
|
||||
|
||||
extern bool TFB_InitVideoPlayer (void);
|
||||
extern void TFB_UninitVideoPlayer (void);
|
||||
extern bool TFB_PlayVideo (VIDEO_REF VidRef, uint32 x, uint32 y);
|
||||
extern void TFB_StopVideo (VIDEO_REF VidRef);
|
||||
extern bool TFB_VideoPlaying (VIDEO_REF VidRef);
|
||||
extern uint32 TFB_GetVideoPosition (VIDEO_REF VidRef);
|
||||
extern bool TFB_SeekVideo (VIDEO_REF VidRef, uint32 pos);
|
||||
|
||||
#endif // _VIDPLAYER_H
|
||||
|
||||
@@ -47,7 +47,7 @@ GetLegacyVideoData (const char *path, RESOURCE_DATA *resdata)
|
||||
{
|
||||
void *result = NULL;
|
||||
char paths[1024], *audio_path, *speech_path, *loop_str;
|
||||
DWORD LoopFrame = VID_NO_LOOP;
|
||||
uint32 LoopFrame = VID_NO_LOOP;
|
||||
|
||||
/* Parse out the video components. */
|
||||
strncpy (paths, path, 1023);
|
||||
@@ -93,13 +93,13 @@ GetLegacyVideoData (const char *path, RESOURCE_DATA *resdata)
|
||||
if (loop_str)
|
||||
{
|
||||
char *end;
|
||||
LoopFrame = (DWORD) strtol (loop_str, &end, 10);
|
||||
LoopFrame = strtol (loop_str, &end, 10);
|
||||
// We allow whitespace at the end, but nothing printable.
|
||||
if (*end > 32) {
|
||||
log_add (log_Warning, "Warning: Unparsable loop frame '%s'. Disabling loop.", loop_str);
|
||||
LoopFrame = VID_NO_LOOP;
|
||||
}
|
||||
log_add (log_Info, "\tLoop frame is %d", LoopFrame);
|
||||
log_add (log_Info, "\tLoop frame is %u", LoopFrame);
|
||||
}
|
||||
else
|
||||
log_add (log_Info, "\tNo specified loop frame");
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef enum
|
||||
|
||||
typedef struct tfb_videoclip *VIDEO_REF;
|
||||
typedef struct legacy_video_desc *LEGACY_VIDEO;
|
||||
typedef struct legacy_video_ref *LEGACY_VIDEO_REF;
|
||||
|
||||
extern BOOLEAN InstallVideoResType (void);
|
||||
|
||||
@@ -39,17 +40,20 @@ extern BOOLEAN InitVideoPlayer (BOOLEAN UseCDROM);
|
||||
extern void UninitVideoPlayer (void);
|
||||
|
||||
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 VidPlayEx (VIDEO_REF VidRef, MUSIC_REF AudRef,
|
||||
MUSIC_REF SpeechRef, DWORD LoopFrame);
|
||||
#define VID_NO_LOOP (0U-1)
|
||||
extern void VidStop (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);
|
||||
BOOLEAN PlayLegacyVideo (LEGACY_VIDEO vid);
|
||||
BOOLEAN DestroyLegacyVideo (LEGACY_VIDEO vid);
|
||||
extern LEGACY_VIDEO LoadLegacyVideoInstance (RESOURCE res);
|
||||
extern 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 */
|
||||
|
||||
+105
-4
@@ -85,6 +85,16 @@ typedef struct {
|
||||
int debounce;
|
||||
} 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
|
||||
@@ -795,7 +805,6 @@ ShowSlidePresentation (STRING PresStr)
|
||||
DestroyDrawable (ReleaseDrawable (pis.Frame));
|
||||
for (i = 0; i < MAX_FONTS; ++i)
|
||||
DestroyFont (pis.Fonts[i]);
|
||||
DestroyStringTable (ReleaseStringTable (pis.SlideShow));
|
||||
|
||||
LockMutex (GraphicsLock);
|
||||
SetContextFont (OldFont);
|
||||
@@ -806,6 +815,96 @@ ShowSlidePresentation (STRING PresStr)
|
||||
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
|
||||
ShowPresentation (RESOURCE res)
|
||||
{
|
||||
@@ -816,13 +915,15 @@ ShowPresentation (RESOURCE res)
|
||||
}
|
||||
if (!strcmp (resType, "STRTAB"))
|
||||
{
|
||||
return ShowSlidePresentation (CaptureStringTable (
|
||||
LoadStringTable (res)));
|
||||
STRING pres = CaptureStringTable (LoadStringTable (res));
|
||||
BOOLEAN result = ShowSlidePresentation (pres);
|
||||
DestroyStringTable (ReleaseStringTable (pres));
|
||||
return result;
|
||||
}
|
||||
else if (!strcmp (resType, "3DOVID"))
|
||||
{
|
||||
LEGACY_VIDEO vid = LoadLegacyVideoInstance (res);
|
||||
BOOLEAN result = PlayLegacyVideo (vid);
|
||||
BOOLEAN result = ShowLegacyVideo (vid);
|
||||
DestroyLegacyVideo (vid);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user