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);
|
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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user