2017-01-21 17:27:46 +01:00
|
|
|
|
// movie.cpp
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include "def.h"
|
2017-02-05 17:28:47 +01:00
|
|
|
|
#include "blupi.h"
|
2017-01-21 17:27:46 +01:00
|
|
|
|
#include "movie.h"
|
|
|
|
|
#include "misc.h"
|
2017-02-05 17:28:47 +01:00
|
|
|
|
#include "event.h"
|
|
|
|
|
#include "kitchensink/kitchensink.h"
|
2017-01-21 17:27:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#define AVI_VIDEO "avivideo"
|
|
|
|
|
|
|
|
|
|
#define IDM_PLAY 10
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Initialize avi libraries.
|
|
|
|
|
|
2017-01-22 00:10:12 +01:00
|
|
|
|
bool CMovie::initAVI()
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
2017-02-05 17:28:47 +01:00
|
|
|
|
// Initialize Kitchensink with network support and all formats.
|
|
|
|
|
int err = Kit_Init (KIT_INIT_FORMATS);
|
|
|
|
|
if (err != 0)
|
|
|
|
|
{
|
|
|
|
|
fprintf (stderr, "Unable to initialize Kitchensink: %s", Kit_GetError ());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Closes the opened AVI file and the opened device type. |
|
|
|
|
|
|
|
|
|
|
void CMovie::termAVI()
|
|
|
|
|
{
|
2017-02-05 17:28:47 +01:00
|
|
|
|
Kit_Quit ();
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Close the movie and anything associated with it. |
|
|
|
|
|
// This function clears the <m_fPlaying> and <m_fMovieOpen> flags |
|
|
|
|
|
|
2017-02-05 09:15:08 +01:00
|
|
|
|
void CMovie::fileCloseMovie()
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
2017-01-22 00:10:12 +01:00
|
|
|
|
m_fPlaying = false; // can't be playing any longer
|
|
|
|
|
m_fMovieOpen = false; // no more movies open
|
2017-02-05 17:28:47 +01:00
|
|
|
|
|
|
|
|
|
if (m_videoTex)
|
|
|
|
|
{
|
|
|
|
|
SDL_DestroyTexture (m_videoTex);
|
|
|
|
|
m_videoTex = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_player)
|
|
|
|
|
{
|
|
|
|
|
SDL_CloseAudioDevice (m_audioDev);
|
|
|
|
|
Kit_ClosePlayer (m_player);
|
|
|
|
|
m_player = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_movie)
|
|
|
|
|
{
|
|
|
|
|
Kit_CloseSource (m_movie);
|
|
|
|
|
m_movie = nullptr;
|
|
|
|
|
}
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Open an AVI movie. Use CommDlg open box to
|
|
|
|
|
// open and then handle the initialization to
|
|
|
|
|
// show the movie and position it properly. Keep
|
|
|
|
|
// the movie paused when opened.
|
|
|
|
|
// Sets <m_fMovieOpen> on success.
|
|
|
|
|
|
2017-02-11 18:33:40 +01:00
|
|
|
|
bool CMovie::fileOpenMovie(RECT rect, const char *pFilename)
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
2017-02-11 22:39:25 +01:00
|
|
|
|
const auto path = GetBaseDir () + pFilename;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
|
|
|
|
|
// we got a filename, now close any old movie and open the new one. */
|
2017-02-11 18:10:32 +01:00
|
|
|
|
if ( m_fMovieOpen ) fileCloseMovie();
|
2017-01-21 17:27:46 +01:00
|
|
|
|
|
2017-02-05 17:28:47 +01:00
|
|
|
|
// Open up the sourcefile.
|
|
|
|
|
// This can be a local file, network url, ...
|
2017-02-11 18:10:32 +01:00
|
|
|
|
m_movie = Kit_CreateSourceFromUrl (path.c_str ());
|
2017-02-05 17:28:47 +01:00
|
|
|
|
if (m_movie)
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
2017-02-05 17:28:47 +01:00
|
|
|
|
// Create the player
|
|
|
|
|
m_player = Kit_CreatePlayer (m_movie);
|
2017-02-05 17:54:12 +01:00
|
|
|
|
if (m_player == nullptr)
|
2017-02-05 17:28:47 +01:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
pinfo = new Kit_PlayerInfo;
|
|
|
|
|
Kit_GetPlayerInfo (m_player, pinfo);
|
|
|
|
|
|
|
|
|
|
SDL_AudioSpec wanted_spec, audio_spec;
|
|
|
|
|
|
|
|
|
|
SDL_memset (&wanted_spec, 0, sizeof (wanted_spec));
|
|
|
|
|
wanted_spec.freq = pinfo->audio.samplerate;
|
|
|
|
|
wanted_spec.format = pinfo->audio.format;
|
|
|
|
|
wanted_spec.channels = pinfo->audio.channels;
|
|
|
|
|
m_audioDev = SDL_OpenAudioDevice (nullptr, 0, &wanted_spec, &audio_spec, 0);
|
|
|
|
|
SDL_PauseAudioDevice (m_audioDev, 0);
|
|
|
|
|
|
|
|
|
|
m_videoTex = SDL_CreateTexture (
|
|
|
|
|
g_renderer,
|
|
|
|
|
pinfo->video.format,
|
|
|
|
|
SDL_TEXTUREACCESS_STATIC,
|
|
|
|
|
pinfo->video.width,
|
|
|
|
|
pinfo->video.height
|
|
|
|
|
);
|
2017-02-05 17:54:12 +01:00
|
|
|
|
if (m_videoTex == nullptr)
|
2017-02-05 17:28:47 +01:00
|
|
|
|
return false;
|
|
|
|
|
|
2017-01-22 00:10:12 +01:00
|
|
|
|
return true;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// generic error for open
|
2017-01-22 00:10:12 +01:00
|
|
|
|
m_fMovieOpen = false;
|
|
|
|
|
return false;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Play/pause the movie depending on the state
|
|
|
|
|
|
2017-02-05 18:25:39 +01:00
|
|
|
|
void CMovie::playMovie()
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
|
|
|
|
m_fPlaying = !m_fPlaying; // swap the play flag
|
|
|
|
|
|
|
|
|
|
// play/pause the AVI movie
|
2017-02-05 18:25:39 +01:00
|
|
|
|
if (m_fPlaying)
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
2017-02-05 17:28:47 +01:00
|
|
|
|
SDL_RenderSetLogicalSize (g_renderer, pinfo->video.width, pinfo->video.height);
|
|
|
|
|
Kit_PlayerPlay (m_player);
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
2017-02-05 17:28:47 +01:00
|
|
|
|
Kit_PlayerPause (m_player);
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Constructeur.
|
|
|
|
|
|
|
|
|
|
CMovie::CMovie()
|
|
|
|
|
{
|
2017-01-22 00:10:12 +01:00
|
|
|
|
m_bEnable = false;
|
|
|
|
|
m_fPlaying = false;
|
|
|
|
|
m_fMovieOpen = false;
|
2017-02-05 17:28:47 +01:00
|
|
|
|
|
2017-02-05 17:45:21 +01:00
|
|
|
|
m_movie = nullptr;
|
|
|
|
|
m_player = nullptr;
|
2017-02-05 17:28:47 +01:00
|
|
|
|
m_videoTex = nullptr;
|
2017-02-05 17:45:21 +01:00
|
|
|
|
pinfo = nullptr;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Destructeur.
|
|
|
|
|
|
|
|
|
|
CMovie::~CMovie()
|
|
|
|
|
{
|
|
|
|
|
termAVI();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ouvre la librairie avi.
|
|
|
|
|
|
2017-01-22 00:10:12 +01:00
|
|
|
|
bool CMovie::Create()
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
|
|
|
|
if ( initAVI() )
|
|
|
|
|
{
|
2017-01-22 00:10:12 +01:00
|
|
|
|
m_bEnable = true;
|
|
|
|
|
return true;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2017-01-22 00:10:12 +01:00
|
|
|
|
m_bEnable = false;
|
|
|
|
|
return false;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Retourne l'<27>tat de DirectMovie.
|
|
|
|
|
|
2017-01-22 00:10:12 +01:00
|
|
|
|
bool CMovie::GetEnable()
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
|
|
|
|
return m_bEnable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Indique si un film existe.
|
|
|
|
|
|
2017-02-11 18:33:40 +01:00
|
|
|
|
bool CMovie::IsExist(const char *pFilename)
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
2017-02-11 22:39:25 +01:00
|
|
|
|
const auto path = GetBaseDir () + pFilename;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
FILE* file;
|
|
|
|
|
|
2017-02-11 18:10:32 +01:00
|
|
|
|
file = fopen(path.c_str (), "rb");
|
2017-02-05 17:54:12 +01:00
|
|
|
|
if ( file == nullptr ) return false;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
|
|
|
|
|
fclose(file);
|
2017-01-22 00:10:12 +01:00
|
|
|
|
return true;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Montre un film avi.
|
|
|
|
|
|
2017-02-11 18:33:40 +01:00
|
|
|
|
bool CMovie::Play(RECT rect, const char *pFilename)
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
2017-01-22 00:10:12 +01:00
|
|
|
|
if ( !m_bEnable ) return false;
|
2017-02-05 09:15:08 +01:00
|
|
|
|
if ( !fileOpenMovie(rect, pFilename) ) return false;
|
2017-02-05 18:25:39 +01:00
|
|
|
|
playMovie();
|
2017-02-05 17:28:47 +01:00
|
|
|
|
CEvent::PushUserEvent (WM_MOVIE_PLAY);
|
2017-01-21 17:27:46 +01:00
|
|
|
|
|
2017-01-22 00:10:12 +01:00
|
|
|
|
return true;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stoppe le film avi.
|
|
|
|
|
|
2017-02-05 09:15:08 +01:00
|
|
|
|
void CMovie::Stop()
|
2017-01-21 17:27:46 +01:00
|
|
|
|
{
|
|
|
|
|
if ( !m_bEnable ) return;
|
2017-02-05 09:15:08 +01:00
|
|
|
|
fileCloseMovie();
|
2017-02-05 17:28:47 +01:00
|
|
|
|
SDL_RenderSetLogicalSize (g_renderer, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-05 18:21:32 +01:00
|
|
|
|
void CMovie::Pause ()
|
|
|
|
|
{
|
|
|
|
|
if (!m_bEnable || !m_fPlaying)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (Kit_GetPlayerState (m_player) != KIT_PLAYING)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Kit_PlayerPause (m_player);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CMovie::Resume ()
|
|
|
|
|
{
|
|
|
|
|
if (!m_bEnable || !m_fPlaying)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (Kit_GetPlayerState (m_player) != KIT_PAUSED)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Kit_PlayerPlay (m_player);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-05 17:28:47 +01:00
|
|
|
|
bool CMovie::Render ()
|
|
|
|
|
{
|
|
|
|
|
if (!m_bEnable || !m_fPlaying)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (Kit_GetPlayerState (m_player) == KIT_STOPPED)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Refresh audio
|
|
|
|
|
if (SDL_GetQueuedAudioSize (m_audioDev) < AUDIOBUFFER_SIZE)
|
|
|
|
|
{
|
|
|
|
|
int need = AUDIOBUFFER_SIZE - m_ret;
|
|
|
|
|
|
|
|
|
|
SDL_LockAudio ();
|
|
|
|
|
while (need > 0)
|
|
|
|
|
{
|
|
|
|
|
m_ret = Kit_GetAudioData (m_player, (unsigned char*) m_audiobuf,
|
|
|
|
|
AUDIOBUFFER_SIZE, (size_t) SDL_GetQueuedAudioSize (m_audioDev));
|
|
|
|
|
need -= m_ret;
|
|
|
|
|
if (m_ret > 0)
|
|
|
|
|
{
|
|
|
|
|
SDL_QueueAudio (m_audioDev, m_audiobuf, m_ret);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
SDL_UnlockAudio ();
|
|
|
|
|
SDL_PauseAudioDevice (m_audioDev, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clear screen with black
|
|
|
|
|
SDL_SetRenderDrawColor (g_renderer, 0, 0, 0, 255);
|
|
|
|
|
SDL_RenderClear (g_renderer);
|
|
|
|
|
|
|
|
|
|
// Refresh videotexture and render it
|
|
|
|
|
Kit_GetVideoData (m_player, m_videoTex);
|
|
|
|
|
SDL_RenderCopy (g_renderer, m_videoTex, nullptr, nullptr);
|
|
|
|
|
|
|
|
|
|
SDL_RenderPresent (g_renderer);
|
|
|
|
|
CEvent::PushUserEvent (WM_MOVIE_PLAY);
|
|
|
|
|
return true;
|
2017-01-21 17:27:46 +01:00
|
|
|
|
}
|