2018-01-05 19:21:07 +02:00
/*
* CPrologEpilogVideo . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
# include "StdInc.h"
# include "CPrologEpilogVideo.h"
# include "../CGameInfo.h"
2024-05-02 14:55:20 +02:00
# include "../media/IMusicPlayer.h"
# include "../media/ISoundPlayer.h"
2024-05-30 20:02:19 +02:00
//#include "../gui/WindowHandler.h"
2018-01-05 19:21:07 +02:00
# include "../gui/CGuiHandler.h"
2024-05-30 20:02:19 +02:00
//#include "../gui/FramerateManager.h"
2018-01-05 19:21:07 +02:00
# include "../widgets/TextControls.h"
2024-05-02 21:14:50 +02:00
# include "../widgets/VideoWidget.h"
2024-05-18 19:58:51 +02:00
# include "../widgets/Images.h"
2023-06-02 15:42:18 +02:00
# include "../render/Canvas.h"
2018-01-05 19:21:07 +02:00
2023-06-25 20:16:03 +02:00
CPrologEpilogVideo : : CPrologEpilogVideo ( CampaignScenarioPrologEpilog _spe , std : : function < void ( ) > callback )
2024-01-25 22:11:42 +02:00
: CWindowObject ( BORDERED ) , spe ( _spe ) , positionCounter ( 0 ) , voiceSoundHandle ( - 1 ) , videoSoundHandle ( - 1 ) , exitCb ( callback ) , elapsedTimeMilliseconds ( 0 )
2018-01-05 19:21:07 +02:00
{
2024-08-09 17:30:04 +02:00
OBJECT_CONSTRUCTION ;
2024-01-26 12:17:38 +02:00
addUsedEvents ( LCLICK | TIME ) ;
2018-01-05 19:21:07 +02:00
pos = center ( Rect ( 0 , 0 , 800 , 600 ) ) ;
2024-05-18 19:58:51 +02:00
backgroundAroundMenu = std : : make_shared < CFilledTexture > ( ImagePath : : builtin ( " DIBOXBCK " ) , Rect ( - pos . x , - pos . y , GH . screenDimensions ( ) . x , GH . screenDimensions ( ) . y ) ) ;
2018-01-05 19:21:07 +02:00
2024-05-30 20:02:19 +02:00
//TODO: remove hardcoded paths. Some of campaigns video actually consist from 2 parts
// however, currently our campaigns format expects only a single video file
static const std : : map < VideoPath , VideoPath > pairedVideoFiles = {
{ VideoPath : : builtin ( " EVIL2AP1 " ) , VideoPath : : builtin ( " EVIL2AP2 " ) } ,
{ VideoPath : : builtin ( " H3ABdb4 " ) , VideoPath : : builtin ( " H3ABdb4b " ) } ,
{ VideoPath : : builtin ( " H3x2_RNe1 " ) , VideoPath : : builtin ( " H3x2_RNe2 " ) } ,
} ;
if ( pairedVideoFiles . count ( spe . prologVideo ) )
videoPlayer = std : : make_shared < VideoWidget > ( Point ( 0 , 0 ) , spe . prologVideo , pairedVideoFiles . at ( spe . prologVideo ) , true ) ;
else
videoPlayer = std : : make_shared < VideoWidget > ( Point ( 0 , 0 ) , spe . prologVideo , true ) ;
2024-05-02 21:14:50 +02:00
//some videos are 800x600 in size while some are 800x400
if ( videoPlayer - > pos . h = = 400 )
videoPlayer - > moveBy ( Point ( 0 , 100 ) ) ;
2024-10-14 20:47:06 +02:00
CCS - > musich - > setVolume ( CCS - > musich - > getVolume ( ) / 2 ) ; // background volume is too loud by default
2023-09-04 12:03:15 +02:00
CCS - > musich - > playMusic ( spe . prologMusic , true , true ) ;
2024-01-26 22:58:39 +02:00
voiceDurationMilliseconds = CCS - > soundh - > getSoundDurationMilliseconds ( spe . prologVoice ) ;
2023-09-11 14:11:16 +02:00
voiceSoundHandle = CCS - > soundh - > playSound ( spe . prologVoice ) ;
2023-09-11 14:44:07 +02:00
auto onVoiceStop = [ this ] ( )
{
voiceStopped = true ;
2024-01-25 21:49:59 +02:00
elapsedTimeMilliseconds = 0 ;
2023-09-11 14:44:07 +02:00
} ;
CCS - > soundh - > setCallback ( voiceSoundHandle , onVoiceStop ) ;
2018-01-05 19:21:07 +02:00
2023-09-28 00:10:28 +02:00
text = std : : make_shared < CMultiLineLabel > ( Rect ( 100 , 500 , 600 , 100 ) , EFonts : : FONT_BIG , ETextAlignment : : CENTER , Colors : : METALLIC_GOLD , spe . prologText . toString ( ) ) ;
2024-10-14 23:26:24 +02:00
if ( text - > getLines ( ) . size ( ) = = 3 )
text - > scrollTextTo ( - 25 ) ; // beginning of text in the vertical middle of black area
else if ( text - > getLines ( ) . size ( ) > 3 )
text - > scrollTextTo ( - 50 ) ; // beginning of text in the vertical middle of black area
2018-01-05 19:21:07 +02:00
}
2024-01-25 21:49:59 +02:00
void CPrologEpilogVideo : : tick ( uint32_t msPassed )
2018-01-05 19:21:07 +02:00
{
2024-01-25 21:49:59 +02:00
elapsedTimeMilliseconds + = msPassed ;
2018-01-05 19:21:07 +02:00
2024-01-26 22:58:39 +02:00
const uint32_t speed = ( voiceDurationMilliseconds = = 0 ) ? 150 : ( voiceDurationMilliseconds / ( text - > textSize . y ) ) ;
2024-01-24 02:17:23 +02:00
2024-01-25 21:49:59 +02:00
if ( elapsedTimeMilliseconds > speed & & text - > textSize . y - 50 > positionCounter )
2024-01-24 02:17:23 +02:00
{
2018-01-05 19:21:07 +02:00
text - > scrollTextBy ( 1 ) ;
2024-01-25 21:49:59 +02:00
elapsedTimeMilliseconds - = speed ;
2024-01-24 02:17:23 +02:00
+ + positionCounter ;
}
2024-01-26 22:58:39 +02:00
else if ( elapsedTimeMilliseconds > ( voiceDurationMilliseconds = = 0 ? 8000 : 3000 ) & & voiceStopped ) // pause after completed scrolling (longer for intros missing voice)
2024-01-26 21:13:02 +02:00
clickPressed ( GH . getCursorPosition ( ) ) ;
2018-01-05 19:21:07 +02:00
}
2023-06-02 15:42:18 +02:00
void CPrologEpilogVideo : : show ( Canvas & to )
2018-01-05 19:21:07 +02:00
{
2023-06-02 15:42:18 +02:00
to . drawColor ( pos , Colors : : BLACK ) ;
2018-01-05 19:21:07 +02:00
2024-05-02 21:14:50 +02:00
videoPlayer - > show ( to ) ;
2024-01-26 21:13:02 +02:00
text - > showAll ( to ) ; // blit text over video, if needed
2018-01-05 19:21:07 +02:00
}
2023-07-08 13:33:04 +02:00
void CPrologEpilogVideo : : clickPressed ( const Point & cursorPosition )
2018-01-05 19:21:07 +02:00
{
2024-10-14 20:47:06 +02:00
CCS - > musich - > setVolume ( CCS - > musich - > getVolume ( ) * 2 ) ; // restore background volume
2018-07-25 00:36:48 +02:00
close ( ) ;
2024-04-11 12:22:06 +02:00
CCS - > soundh - > resetCallback ( voiceSoundHandle ) ; // reset callback to avoid memory corruption since 'this' will be destroyed
2018-01-05 19:21:07 +02:00
CCS - > soundh - > stopSound ( voiceSoundHandle ) ;
2023-10-08 20:27:56 +02:00
CCS - > soundh - > stopSound ( videoSoundHandle ) ;
2024-01-24 00:45:31 +02:00
if ( exitCb )
exitCb ( ) ;
2018-01-05 19:21:07 +02:00
}