changeset 2430:cb66a1082fcf

* ITrack, IMovie now properly propogate destructors * VideoPlayer correctly deallocates memory after playing a movie
author a.parshin
date Wed, 23 Jul 2014 20:28:28 +0300
parents 6d5877899730
children a2d95b16e28b
files Build/Visual Studio 2012/World of Might and Magic.vcxproj.user CShow.h Events.cpp MediaPlayer.cpp MediaPlayer.h VideoPlayer.cpp VideoPlayer.h
diffstat 7 files changed, 50 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/Build/Visual Studio 2012/World of Might and Magic.vcxproj.user	Wed Jul 23 19:42:39 2014 +0300
+++ b/Build/Visual Studio 2012/World of Might and Magic.vcxproj.user	Wed Jul 23 20:28:28 2014 +0300
@@ -4,6 +4,6 @@
     <LocalDebuggerCommand>$(OutDir)$(TargetName)$(TargetExt)</LocalDebuggerCommand>
     <LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerCommandArguments>-nomarg -window -nointro -nologo -novideo</LocalDebuggerCommandArguments>
+    <LocalDebuggerCommandArguments>-nomarg -window -nointro -nologo</LocalDebuggerCommandArguments>
   </PropertyGroup>
 </Project>
\ No newline at end of file
--- a/CShow.h	Wed Jul 23 19:42:39 2014 +0300
+++ b/CShow.h	Wed Jul 23 20:28:28 2014 +0300
@@ -23,13 +23,13 @@
 
   switch (movie)
   {
-    case MOVIE_3DOLogo: pVideoPlayer->MovieLoop("3dologo", 0, 0, 1);        break;
-	case MOVIE_NWCLogo: pVideoPlayer->MovieLoop("new world logo", 0, 1, 1); break;
-	case MOVIE_JVC:     pVideoPlayer->MovieLoop("jvc", 0, 1, 1);            break;
-	case MOVIE_Intro:   pVideoPlayer->MovieLoop("Intro", 0, 1, 1);          break;
-	case MOVIE_Emerald: pVideoPlayer->MovieLoop("Intro Post", 0, 1, 1);     break;
-	case MOVIE_Death:   pVideoPlayer->MovieLoop("losegame", 2, 1, 1);       break;
-	case MOVIE_Outro:   pVideoPlayer->MovieLoop("end_seq1", 20, 1, 1);      break;
+    case MOVIE_3DOLogo: pVideoPlayer->MovieLoop("3dologo", 0, 0);        break;
+	case MOVIE_NWCLogo: pVideoPlayer->MovieLoop("new world logo", 0, 1); break;
+	case MOVIE_JVC:     pVideoPlayer->MovieLoop("jvc", 0, 1);            break;
+	case MOVIE_Intro:   pVideoPlayer->MovieLoop("Intro", 0, 1);          break;
+	case MOVIE_Emerald: pVideoPlayer->MovieLoop("Intro Post", 0, 1);     break;
+	case MOVIE_Death:   pVideoPlayer->MovieLoop("losegame", 2, 1);       break;
+	case MOVIE_Outro:   pVideoPlayer->MovieLoop("end_seq1", 20, 1);      break;
 
     default:
       Error("Invalid movie requested: %u", movie);
--- a/Events.cpp	Wed Jul 23 19:42:39 2014 +0300
+++ b/Events.cpp	Wed Jul 23 20:28:28 2014 +0300
@@ -465,7 +465,7 @@
         v128 = pCurrentScreen;
         strcpy(Str, Source);
         v16 = RemoveQuotes(Str);
-		pVideoPlayer->MovieLoop(v16, 0, _evt->v5, 1);
+		pVideoPlayer->MovieLoop(v16, 0, _evt->v5);
         if ( !_stricmp(v16, "arbiter good") )
                 {
                   pParty->alignment = PartyAlignment_Good;
--- a/MediaPlayer.cpp	Wed Jul 23 19:42:39 2014 +0300
+++ b/MediaPlayer.cpp	Wed Jul 23 20:28:28 2014 +0300
@@ -791,8 +791,10 @@
 	  format_ctx = nullptr;
 	  avioContext = nullptr;
     }
+
+    virtual ~Movie() {}
  
-    inline void Release()
+    virtual void Release()
     {
       ReleaseAVCodec();
     }
@@ -880,7 +882,7 @@
 		  {
 			current_movie_width = width;
 			current_movie_height = height;
-	      } 
+	      }
 		  //
           decoding_packet = new AVPacket;
           av_init_packet(decoding_packet);
@@ -1033,8 +1035,8 @@
     AVAudioStream   audio;
     int             num_audio_frames;
     int             num_audio_samples;
-	unsigned char * ioBuffer;
-	AVIOContext *avioContext;
+	unsigned char  *ioBuffer;
+	AVIOContext    *avioContext;
     OpenALSoundProvider::StreamingTrackBuffer *audio_data_in_device;
 
     AVVideoStream   video;
--- a/MediaPlayer.h	Wed Jul 23 19:42:39 2014 +0300
+++ b/MediaPlayer.h	Wed Jul 23 20:28:28 2014 +0300
@@ -5,14 +5,20 @@
   class ITrack
   {
     public:
-		virtual void Play(bool loop = false) = 0;
+      virtual ~ITrack() {}
+
+	  virtual void Play(bool loop = false) = 0;
+      virtual void Release() = 0;
   };
 
   class IMovie
   {
     public: 
-		virtual void Play() = 0;
-        virtual void GetNextFrame(double dt, void *target_surface) = 0;
+      virtual ~IMovie() {}
+
+	  virtual void Play() = 0;
+      virtual void GetNextFrame(double dt, void *target_surface) = 0;
+      virtual void Release() = 0;
   };
 
   class MPlayer
--- a/VideoPlayer.cpp	Wed Jul 23 19:42:39 2014 +0300
+++ b/VideoPlayer.cpp	Wed Jul 23 20:28:28 2014 +0300
@@ -94,14 +94,16 @@
 }
 
 //----- (004BE70E) --------------------------------------------------------
-void VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag, int a4)
+void VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag/*, int a4*/)
 {
   int v4; // ebp@1
   MSG Msg; // [sp+Ch] [bp-1Ch]@12
 
   v4 = a2;
-  if ( !(dword_6BE364_game_settings_1 & (GAME_SETTINGS_NO_HOUSE_ANIM | GAME_SETTINGS_NO_INTRO)) )
-  {
+  if ( dword_6BE364_game_settings_1 & (GAME_SETTINGS_NO_HOUSE_ANIM | GAME_SETTINGS_NO_INTRO) ||
+	   bNoVideo)
+    return;
+
     if ( a2 == 2 )
       v4 = 0;
     ShowCursor(0);//Убрать курсор
@@ -112,6 +114,7 @@
     pCurrentScreen = SCREEN_VIDEO;
 
     auto hwnd = pVideoPlayer->window->GetApiHandle();
+
     RECT rc_client;
     GetClientRect(hwnd, &rc_client);
     int client_width = rc_client.right - rc_client.left,
@@ -120,6 +123,7 @@
     HDC     dc = GetDC(hwnd);
     HDC     back_dc = CreateCompatibleDC(dc);
 	HBITMAP back_bmp = CreateCompatibleBitmap(dc, client_width, client_height);
+	auto    frame_buffer = new char[client_width * client_height * 4];
     SelectObject(back_dc, back_bmp);
 
 	DWORD t = GetTickCount();//текущее время от запуска ОС
@@ -128,32 +132,27 @@
 
     while (true) //Цикл воспроизведения видеоролика
     {
-      if ( pVideoPlayer->bStopBeforeSchedule )
+      if (pVideoPlayer->bStopBeforeSchedule)
         break;
       while (PeekMessageA(&Msg, hwnd, 0, 0, PM_REMOVE))
       {
-        if (Msg.message == 18)
+        if (Msg.message == WM_QUIT)
           Game_DeinitializeAndTerminate(0);
-        if (Msg.message == 15)
+        if (Msg.message == WM_PAINT)
           break;
         TranslateMessage(&Msg);
         DispatchMessageA(&Msg);
       }
 
       double dt = (GetTickCount() - t) / 1000.0; //изменение времени
-      //dt = 1.0/15.0;
       t = GetTickCount();
 
-      //log("dt=%.5f\n", dt);
-
-      auto image = new char[client_width * client_height * 4];
-
-      pMovie_Track->GetNextFrame(dt, image);	//получить следующий кадр
+      pMovie_Track->GetNextFrame(dt, frame_buffer);	//получить следующий кадр
 
       if (end_current_file)//достигнут ли конец видео?
         break;
 
-      if (image)
+      if (frame_buffer)
       {
         // draw to hwnd
         BITMAPINFO bmi;
@@ -169,32 +168,31 @@
         bmi.bmiHeader.biClrUsed = 0;
         bmi.bmiHeader.biClrImportant = 0;
         GetDIBits(back_dc, back_bmp, 0, client_height, 0, &bmi, DIB_RGB_COLORS);
-        SetDIBits(back_dc, back_bmp, 0, client_height, image, &bmi, DIB_RGB_COLORS);
+        SetDIBits(back_dc, back_bmp, 0, client_height, frame_buffer, &bmi, DIB_RGB_COLORS);
         BitBlt(dc, 0, 0, client_width, client_height, back_dc, 0, 0, SRCCOPY);
-
       }
 
-	  delete[] image;//удалить кадр
-
       GUI_MainMenuMessageProc();  //после отрисовки, т.к. иначе вылетает dt = 0.03, image - ???
 
       if (pVideoPlayer->bStopBeforeSchedule == 1)//остановка видео
         Sleep(1000); //пауза после видеоролика
     }
+	delete [] frame_buffer;
 	DeleteObject(back_bmp);
 	DeleteObject(back_dc);
+	ReleaseDC(hwnd, dc);
+
     pVideoPlayer->Unload();
 
-    if (a4 == 1)
+    //if (a4 == 1)
       pCurrentScreen = SCREEN_GAME;
 
     pVideoPlayer->bPlayingMovie = 0;
 
     ShowCursor(1);//вернуть курсор
 
-    if ( pCurrentScreen == SCREEN_VIDEO )
-      pCurrentScreen = SCREEN_GAME;
-  }
+    /*if ( pCurrentScreen == SCREEN_VIDEO )
+      pCurrentScreen = SCREEN_GAME;*/
 }
 
 //----- (004BE9D8) --------------------------------------------------------
@@ -260,8 +258,8 @@
     AIL_redbook_resume(pAudioPlayer->hAILRedbook);
   pEventTimer->Resume();
 
+  pMovie_Track->Release();
   delete pMovie_Track;
-  Log::Warning(L"delete dynamic memory for pMovie_Track\n");
   pMovie_Track = nullptr;
 }
 
@@ -487,7 +485,7 @@
   return li.QuadPart;
 }
 
-void VideoPlayer::LoadMovie(const char * pFilename)
+void VideoPlayer::LoadMovie(const char *pFilename)
 {
   char pVideoNameBik[120]; // [sp+Ch] [bp-28h]@2
   char pVideoNameSmk[120]; // [sp+Ch] [bp-28h]@2
@@ -540,7 +538,5 @@
   int client_width = rc_client.right - rc_client.left,
       client_height = rc_client.bottom - rc_client.top;
 
-
   pMovie_Track = pMediaPlayer->LoadMovieFromLOD(hVidFile, &readFunction, &seekFunction, client_width, client_height);
-
 }
--- a/VideoPlayer.h	Wed Jul 23 19:42:39 2014 +0300
+++ b/VideoPlayer.h	Wed Jul 23 20:28:28 2014 +0300
@@ -55,10 +55,8 @@
   void SelectMovieType();//0x4BF73A
   void _inlined_in_463149();
 
-  void MovieLoop(const char *pMovieName, int a2, int a3, int a4);
+  void MovieLoop(const char *pMovieName, int a2, int a3);
   void UpdatePalette();
-  static int readFunction(void *, uint8_t *, int);
-  static int64_t seekFunction(void *, int64_t, int);
   void LoadMovie(const char *);
 
   RGBTexture pVideoFrame;
@@ -88,6 +86,10 @@
   HANDLE hVidFile;
   int uSize;
   int uOffset;
+
+  protected:
+    static int readFunction(void *, uint8_t *, int);
+    static int64_t seekFunction(void *, int64_t, int);
 };
 #pragma pack(pop)