Mercurial > mm7
diff VideoPlayer.cpp @ 0:9c0607679772
init
author | Ritor1 |
---|---|
date | Sat, 12 Jan 2013 09:45:18 +0600 |
parents | |
children | bf31c505f4d3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VideoPlayer.cpp Sat Jan 12 09:45:18 2013 +0600 @@ -0,0 +1,1173 @@ +#include "OSAPI.h" + +#include "Bink_Smacker.h" + +#include "OSInfo.h" +#include "VideoPlayer.h" +#include "AudioPlayer.h" +#include "Game.h" +#include "Render.h" +#include "Party.h" +#include "GUIWindow.h" +#include "Allocator.h" +#include "Time.h" +#include "Log.h" + +#include "mm7_data.h" + + +VideoPlayer *pVideoPlayer = nullptr; + + + + + + + +#pragma comment(lib, "Version.lib") +bool GetDllVersion(const wchar_t *pDllName, uint *pMajor, uint *pMinor) +{ + uint uVersionSize = GetFileVersionInfoSizeW(pDllName, nullptr); + void *pVersionData = HeapAlloc(GetProcessHeap(), 0, uVersionSize); + { + GetFileVersionInfoW(pDllName, 0, uVersionSize, pVersionData); + + VS_FIXEDFILEINFO *pInfo = nullptr; + UINT uInfoSize = 0; + VerQueryValueW(pVersionData, L"\\", (void **)&pInfo, &uInfoSize); + + if (!pMajor || !pMinor) + { + HeapFree(GetProcessHeap(), 0, pVersionData); + return false; + } + *pMajor = pInfo->dwFileVersionMS; + *pMinor = pInfo->dwFileVersionLS; + } + HeapFree(GetProcessHeap(), 0, pVersionData); + return true; +} + + +// 3.15.1.0: +// 3 15 1 0 +// 0x0003000F00010000 +unsigned __int64 uBinkVersion; + + + + + + +//----- (004BFE2D) -------------------------------------------------------- +_BINKBUF *VideoPlayer::CreateBinkBuffer(HWND hWindow, unsigned int uWidth, unsigned int uHeight, char a4) +{ + __int32 v4; // edi@3 + _BINKBUF *v5; // esi@3 + HRESULT v6; // eax@5 + IDirectDrawSurface *v7; // eax@6 + HRESULT v8; // eax@9 + char v9; // al@11 + DDSURFACEDESC2 v11; // [sp+Ch] [bp-108h]@7 + DDSURFACEDESC Dst; // [sp+88h] [bp-8Ch]@3 + unsigned int v13; // [sp+F4h] [bp-20h]@1 + struct tagRECT Rect; // [sp+F8h] [bp-1Ch]@11 + IDirectDrawSurface4 *v15; // [sp+108h] [bp-Ch]@7 + IDirectDrawSurface2 *a2; // [sp+10Ch] [bp-8h]@3 + HWND hWnd; // [sp+110h] [bp-4h]@1 + + v13 = uWidth; + hWnd = hWindow; + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5u ) + { + v4 = 0; + v15 = 0; + + if (uBinkVersion == 0x0001000500150000) + { + v5 = new _BINKBUF_1_5_21_0; + memset(v5, 0, sizeof(_BINKBUF_1_5_21_0)); + } + else if (uBinkVersion == 0x0003000000000000) + { + v5 = new _BINKBUF_3_0_0_0; + memset(v5, 0, sizeof(_BINKBUF_3_0_0_0)); + } + + memset(&v11, 0, 0x7Cu); + v11.dwSize = 124; + v11.dwWidth = v13; + v11.dwFlags = 0x1007u; // DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT + v11.ddsCaps.dwCaps = 0x4040u; // DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY + v11.dwHeight = uHeight; + *(_QWORD *)&v11.ddpfPixelFormat.dwSize = 0x400000020ui64;// DDPF_FOURCC + v11.ddpfPixelFormat.dwFourCC = 0x32595559u; + if ( dword_6BE384_2dacceloff || pRenderer->pDirectDraw4->CreateSurface(&v11, &v15, 0) ) + { + memset(&v11.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT)); + + v11.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + v11.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + + auto hr = pRenderer->pDirectDraw4->CreateSurface(&v11, &v15, 0); + ErrD3D(hr, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Video.cpp:1476"); + } + v5->uWidth = v11.dwWidth; + v5->uHeight = v11.dwHeight; + v5->uBinkDDSurfaceType = BinkDDSurfaceType((IDirectDrawSurface *)v15); + v5->field_38 = 0; + v7 = (IDirectDrawSurface *)v15; + } + else + { + v4 = 0; + a2 = 0; + + + if (uBinkVersion == 0x0001000500150000) + { + v5 = new _BINKBUF_1_5_21_0; + memset(v5, 0, sizeof(_BINKBUF_1_5_21_0)); + } + else if (uBinkVersion == 0x0003000000000000) + { + v5 = new _BINKBUF_3_0_0_0; + memset(v5, 0, sizeof(_BINKBUF_3_0_0_0)); + } + + memset(&Dst, 0, 0x6Cu); + Dst.dwSize = 108; + Dst.dwWidth = v13; + Dst.dwFlags = 4103; + Dst.ddsCaps.dwCaps = 16448; + Dst.dwHeight = uHeight; + Dst.ddpfPixelFormat.dwSize = 32; + Dst.ddpfPixelFormat.dwFlags = 4; + Dst.ddpfPixelFormat.dwFourCC = 844715353; + if ( dword_6BE384_2dacceloff + || pRenderer->pDirectDraw2->CreateSurface(&Dst, (LPDIRECTDRAWSURFACE *)&a2, 0) ) + { + memset(&Dst.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT)); + + Dst.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + Dst.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + + auto hr = pRenderer->pDirectDraw2->CreateSurface(&Dst, (LPDIRECTDRAWSURFACE *)&a2, 0); + ErrD3D(hr, "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Video.cpp:1426"); + } + v5->uWidth = Dst.dwWidth; + v5->uHeight = Dst.dwHeight; + v5->uBinkDDSurfaceType = BinkDDSurfaceType((IDirectDrawSurface *)a2); + v5->field_38 = 0; + v7 = (IDirectDrawSurface *)a2; + } + v5->pTargetDDrawSurface = v7; + v5->hWnd = hWnd; + v9 = a4; + v5->field_4C = v4; + v5->field_68 = v4; + v5->field_5C = v4; + v5->field_74 = v9 & 0x1F; + v5->field_78 = 1; + v5->field_24 = GetSystemMetrics(v4); + v5->field_28 = GetSystemMetrics(SM_CYSCREEN); + v5->field_2C = 16; + GetWindowRect(hWnd, &Rect); + v5->field_8 = Rect.right - Rect.left; + v5->field_C = Rect.bottom - Rect.top; + v5->field_1C = Rect.left; + v5->field_20 = Rect.top; + Rect.left = v4; + Rect.top = v4; + ClientToScreen(hWnd, (LPPOINT)&Rect); + v5->field_1C = Rect.left - v5->field_1C; + v5->field_20 = Rect.top - v5->field_20; + GetClientRect(hWnd, &Rect); + v5->field_30 = v5->field_8 - Rect.right; + v5->field_34 = v5->field_C - Rect.bottom; + v5->field_8 = v5->uWidth + v5->field_30; + v5->field_C = v5->uHeight + v5->field_34; + BinkBufferSetOffset(v5, v4, v4); + BinkBufferSetScale(v5, v5->uWidth, v5->uHeight); + return v5; +} + + +//----- (004C0133) -------------------------------------------------------- +bool BinkLockBuffer(_BINKBUF *_this) +{ + _BINKBUF *v1; // esi@1 + IDirectDrawSurface *v2; // edi@5 + DWORD v4; // eax@8 + DWORD v5; // eax@8 + IDirectDrawSurface4 *v6; // edi@11 + LPVOID v7; // eax@14 + + v1 = _this; + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5u ) + { + DDSURFACEDESC2 v8; // [sp+Ch] [bp-7Ch]@4 + if ( _this->pTargetDDrawSurface ) + { + memset(&v8, 0, 0x7Cu); + v8.dwSize = 124; + while ( 1 ) + { + v6 = (IDirectDrawSurface4 *)v1->pTargetDDrawSurface; + if ( !v6->Lock(0, &v8, 1u, 0) ) + break; + + if (uBinkVersion < 0x0003000000000000) + BYTE3(v1->uBinkDDSurfaceType) |= 0x80u; + else + BYTE3(v1->uBinkDDSurfaceType) |= 0x04; + + if ( v6->Restore() ) + return 0; + } + v7 = v8.lpSurface; + v1->pDDrawSurfaceData_ = v8.lpSurface; + v1->pDDrawSurfaceData = v7; + v5 = v8.lPitch; + goto LABEL_15; + } + } + else + { + DDSURFACEDESC v8; // [sp+Ch] [bp-7Ch]@4 + if ( _this->pTargetDDrawSurface ) + { + memset(&v8.lPitch, 0, 0x6Cu); + v8.lPitch = 108; + while ( 1 ) + { + v2 = v1->pTargetDDrawSurface; + if ( !v2->Lock(0, (LPDDSURFACEDESC)&v8.lPitch, 1u, 0) ) + break; + + if (uBinkVersion < 0x0003000000000000) + __asm int 3; + else + BYTE3(v1->uBinkDDSurfaceType) |= 4u; + + if ( v2->Restore() ) + return 0; + } + v4 = (DWORD)v8.lpSurface; + v1->pDDrawSurfaceData_ = (void *)v8.lpSurface; + v1->pDDrawSurfaceData = (void *)v4; + v5 = v8.dwReserved; +LABEL_15: + v1->uDDrawSurfacePitch = v5; + return 1; + } + } + return 1; +} + +//----- (004C01FB) -------------------------------------------------------- +void BinkUnlockBuffer(_BINKBUF *_this) +{ + _BINKBUF *v1; // esi@1 + IDirectDrawSurface *v2; // eax@1 + + v1 = _this; + v2 = _this->pTargetDDrawSurface; + if ( v2 ) + { + v2->Unlock(0); + v1->uDDrawSurfacePitch = 0; + v1->pDDrawSurfaceData = 0; + + if (uBinkVersion < 0x0003000000000000) + BYTE3(_this->uBinkDDSurfaceType) &= 0x7F; + else + BYTE3(_this->uBinkDDSurfaceType) &= 0xFB; + } +} +//----- (004BF794) -------------------------------------------------------- +void __cdecl ShowIntroVideo_and_LoadingScreen() +{ + RGBTexture tex; // [sp+Ch] [bp-30h]@1 + unsigned int uTrackStartMS; // [sp+34h] [bp-8h]@8 + unsigned int uTrackEndMS; // [sp+38h] [bp-4h]@8 + + pVideoPlayer->bStopBeforeSchedule = false; + pVideoPlayer->field_40 = 0; + bGameoverLoop = 1; + if ( !bNoVideo ) + { + bNoVideo = 0; + pRenderer->PresentBlackScreen(); + pGame->pCShow->PlayMovie(MOVIE_3DOLogo, 1); + if ( !pVideoPlayer->bStopBeforeSchedule ) + { + pGame->pCShow->PlayMovie(MOVIE_NWCLogo, 1); + if ( !pVideoPlayer->bStopBeforeSchedule ) + { + pGame->pCShow->PlayMovie(MOVIE_JVC, 1); + if ( !pVideoPlayer->bStopBeforeSchedule ) + pGame->pCShow->PlayMovie(MOVIE_Intro, 1); + } + } + } + tex.Load("mm6title.pcx", 2); + pRenderer->BeginScene(); + pRenderer->DrawTextureRGB(0, 0, &tex); + free(tex.pPixels); + tex.pPixels = 0; + MainMenuUI_LoadFontsAndSomeStuff(); + DrawCopyrightWindow(); + pRenderer->EndScene(); + pRenderer->Present(); + if (!bNoSound && pAudioPlayer->hAILRedbook ) + { + pAudioPlayer->SetMusicVolume((signed __int64)(pSoundVolumeLevels[uMusicVolimeMultiplier] * 64.0)); + AIL_redbook_stop(pAudioPlayer->hAILRedbook); + AIL_redbook_track_info(pAudioPlayer->hAILRedbook, 0xE, &uTrackStartMS, &uTrackEndMS); + AIL_redbook_play(pAudioPlayer->hAILRedbook, uTrackStartMS + 1, uTrackEndMS); + } + bGameoverLoop = 0; +} + + + + +//----- (004BE70E) -------------------------------------------------------- +void __fastcall VideoPlayer::MovieLoop(const char *pMovieName, int a2, int ScreenSizeFlag, int a4) +{ + int v4; // ebp@1 + const char *pName; // edi@1 + MSG Msg; // [sp+Ch] [bp-1Ch]@12 + + v4 = a2; + pName = pMovieName; + if ( !(dword_6BE364_game_settings_1 & 0x44) ) + { + if ( a2 == 2 ) + v4 = 0; + ShowCursor(0); + pVideoPlayer->OpenMovie(pName, 0, ScreenSizeFlag); + pVideoPlayer->bPlayingMovie = 1; + pVideoPlayer->field_44 = v4; + if ( pRenderer->pRenderD3D ) + { + pRenderer->ClearTarget(0); + } + else + { + pRenderer->BeginScene(); + pRenderer->ClearTarget(0); + pRenderer->EndScene(); + } + pCurrentScreen = 16; //окно видео ролика + if ( pVideoPlayer->uMovieFormat == 2 ) + { + if ( pVideoPlayer->pBinkMovie ) + { + pVideoPlayer->BinkDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag); + while ( pVideoPlayer->pBinkMovie ) + { + if ( pVideoPlayer->bStopBeforeSchedule ) + break; + while ( PeekMessageA(&Msg, 0, 0, 0, 1) ) + { + if ( Msg.message == 18 ) + Game_DeinitializeAndTerminate(0); + if ( Msg.message == 15 ) + break; + TranslateMessage(&Msg); + DispatchMessageA(&Msg); + } + GUI_MainMenuMessageProc(); + if ( !pVideoPlayer->pBinkMovie ) + break; + if ( !BinkWait(pVideoPlayer->pBinkMovie) && !pVideoPlayer->bStopBeforeSchedule ) + pVideoPlayer->BinkDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag); + } + } + if ( pVideoPlayer->bStopBeforeSchedule == 1 ) + Sleep(0x3E8u); + } + else + { + if ( pVideoPlayer->uMovieFormat == 1 ) + { + if ( pVideoPlayer->pSmackerMovie ) + { + pVideoPlayer->SmackDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag); + while ( pVideoPlayer->pSmackerMovie ) + { + if ( pVideoPlayer->bStopBeforeSchedule ) + break; + while ( PeekMessageW(&Msg, 0, 0, 0, 1) ) + { + if (Msg.message == WM_QUIT) + Game_DeinitializeAndTerminate(0); + if (Msg.message == WM_PAINT) + break; + TranslateMessage(&Msg); + DispatchMessageW(&Msg); + } + GUI_MainMenuMessageProc(); + if ( !pVideoPlayer->pSmackerMovie ) + break; + if ( !SmackWait(pVideoPlayer->pSmackerMovie) && !pVideoPlayer->bStopBeforeSchedule ) + pVideoPlayer->SmackDrawFrame(pVideoPlayer->hWindow, v4, ScreenSizeFlag); + } + } + } + } + if ( a4 == 1 ) + pCurrentScreen = 0; + pVideoPlayer->bPlayingMovie = 0; + ShowCursor(1); + if ( pCurrentScreen == 16 )//окно видео ролика + pCurrentScreen = 0; + } +} + + + + +//----- (004BE95A) -------------------------------------------------------- +unsigned int VideoPlayer::SmackCheckSurfaceFromat() +{ + DDPIXELFORMAT a2; // [sp+0h] [bp-20h]@1 + + a2.dwSize = 32; + a2.dwFlags = 64; + pRenderer->GetTargetPixelFormat(&a2); + if ( a2.dwRGBBitCount != 8 ) + { + if ( a2.dwRBitMask == 0xF800 ) + { + if ( a2.dwGBitMask == 0x7E0 && a2.dwBBitMask == 0x1F ) + return 0xC0000000u; + } + else + { + if ( a2.dwRBitMask == 0x7C00 + && a2.dwGBitMask == 0x3E0 + && a2.dwBBitMask == 0x1F ) + return 0x80000000u; + } + MessageBoxA(0, "Unsupported pixel format.", "Smacker Error", 0); + } + return 0; +} + +//----- (004BE9D8) -------------------------------------------------------- +void VideoPlayer::Initialize() +{ + DWORD NumberOfBytesRead; // [sp+10h] [bp-4h]@9 + + uint uBinkVersionMajor = -1, + uBinkVersionMinor = -1; + GetDllVersion(L"BINKW32.DLL", &uBinkVersionMajor, &uBinkVersionMinor); + uBinkVersion = (unsigned __int64)uBinkVersionMajor << 32 | uBinkVersionMinor; + + strcpy(pTmpBuf, "anims\\might7.vid"); + hMightVid = CreateFileW(L"anims\\might7.vid", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080u, 0); + if ( hMightVid == INVALID_HANDLE_VALUE ) + { + sprintf(pTmpBuf2, "Can't open file - anims\\%s.smk", pTmpBuf); + MessageBoxA(0, pTmpBuf2, "Video File Error", 0); + return; + } + strcpy(pTmpBuf, "anims\\magic7.vid"); + hMagicVid = CreateFileW(L"anims\\magic7.vid", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080u, 0); + if ( hMagicVid == INVALID_HANDLE_VALUE ) + { + if ( !bCanLoadFromCD ) + { + sprintf(pTmpBuf2, "Can't open file - anims\\%s.smk", pTmpBuf); + MessageBoxA(0, pTmpBuf2, "Video File Error", 0); + return; + } + sprintf(pTmpBuf2, "%c:\\%s", (unsigned __int8)cMM7GameCDDriveLetter, pTmpBuf); + hMagicVid = CreateFileA(pTmpBuf2, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0x8000080u, 0); + if ( hMagicVid == (HANDLE)INVALID_HANDLE_VALUE ) + { + sprintf(pTmpBuf2, "Can't open file - %s", pTmpBuf); + MessageBoxA(0, pTmpBuf2, "Video File Error", 0); + return; + } + } + ReadFile(hMightVid, &uNumMightVideoHeaders, 4, &NumberOfBytesRead, 0); + ReadFile(hMagicVid, &uNumMagicVideoHeaders, 4, &NumberOfBytesRead, 0); + pMagicVideoHeaders = 0; + pMightVideoHeaders = 0; + pMightVideoHeaders = (MovieHeader *)pAllocator->AllocNamedChunk(0, 44 * uNumMightVideoHeaders + 2, 0); + pMagicVideoHeaders = (MovieHeader *)pAllocator->AllocNamedChunk(pMagicVideoHeaders, 44 * uNumMagicVideoHeaders + 2, 0); + ReadFile(hMightVid, pMightVideoHeaders, 44 * uNumMightVideoHeaders, &NumberOfBytesRead, 0); + ReadFile(hMagicVid, pMagicVideoHeaders, 44 * uNumMagicVideoHeaders, &NumberOfBytesRead, 0); +} + +//----- (004BEB41) -------------------------------------------------------- +void VideoPlayer::Prepare() +{ + VideoPlayer *pVideoPlayer; // esi@1 + IDirectDrawSurface *v2; // [sp-4h] [bp-Ch]@5 + + pVideoPlayer = this; + pEventTimer->Pause(); + pVideoPlayer->bStopBeforeSchedule = 0; + if ( pAudioPlayer->hAILRedbook ) + AIL_redbook_pause(pAudioPlayer->hAILRedbook); + pVideoPlayer->field_54 = 1; + pVideoPlayer->hWindow = hWnd; + pVideoPlayer->pSmackerMovie = 0; + pVideoPlayer->pSmackerBuffer = 0; + pVideoPlayer->pBinkMovie = 0; + pVideoPlayer->pBinkBuffer = 0; + pVideoPlayer->bPlayingMovie = 0; + pVideoPlayer->bFirstFrame = 0; + pVideoPlayer->bUsingSmackerMMX = SmackUseMMX(1); + BinkSetSoundSystem(BinkOpenMiles, pAudioPlayer->hDigDriver); + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion >= 5 ) + v2 = (IDirectDrawSurface*)pRenderer->pBackBuffer4; + else + v2 = (IDirectDrawSurface*)pRenderer->pBackBuffer2; + pVideoPlayer->uBinkDirectDrawSurfaceType = BinkDDSurfaceType(v2); + _flushall(); +} + + +//----- (004BEBD7) -------------------------------------------------------- +void VideoPlayer::Unload() +{ + VideoPlayer *pVideoPlayer; // esi@1 + _BINK *pBinkMovie; // eax@1 + _BINKBUF *pBinkBuffer; // eax@3 + _SMACK *pSmackerMovie; // eax@5 + + pVideoPlayer = this; + pBinkMovie = this->pBinkMovie; + if ( pBinkMovie ) + { + BinkPause(pBinkMovie, 1); + Sleep(300); + BinkClose(pVideoPlayer->pBinkMovie); + pVideoPlayer->pBinkMovie = 0; + } + pBinkBuffer = pVideoPlayer->pBinkBuffer; + if ( pBinkBuffer ) + { + pBinkBuffer->pTargetDDrawSurface->Release(); + pVideoPlayer->pBinkBuffer->pTargetDDrawSurface = 0; + free(pVideoPlayer->pBinkBuffer); + pVideoPlayer->pBinkBuffer = 0; + } + pSmackerMovie = pVideoPlayer->pSmackerMovie; + if ( pSmackerMovie ) + { + SmackSoundOnOff(pSmackerMovie, 0); + SmackClose(pVideoPlayer->pSmackerMovie); + pVideoPlayer->pSmackerMovie = 0; + } + if ( pVideoPlayer->pSmackerBuffer ) + { + SmackBufferClose(pVideoPlayer->pSmackerBuffer); + pVideoPlayer->pSmackerBuffer = 0; + } + if ( pVideoPlayer->pSmackMovieBlit ) + { + SmackBlitClose(pVideoPlayer->pSmackMovieBlit); + pVideoPlayer->pSmackMovieBlit = 0; + } + pVideoPlayer->field_54 = 0; + pVideoPlayer->uMovieFormat = 0; + pVideoPlayer->dword_0000A0 = 0; + memset(pVideoPlayer->pCurrentMovieName, 0, 0x40); + if ( pAudioPlayer->hAILRedbook && !bGameoverLoop ) + AIL_redbook_resume(pAudioPlayer->hAILRedbook); + pEventTimer->Resume(); +} + +//----- (004BECD5) -------------------------------------------------------- +void VideoPlayer::FastForwardToFrame(unsigned int uDstFrameNum) +{ + VideoPlayer *v2; // esi@1 + unsigned int v3; // eax@1 + + v2 = this; + v3 = this->uMovieFormat; + if ( v3 == 2 ) + { + if (uDstFrameNum) + { + int *pCurrentFrame = uBinkVersion == 0x0001000500150000 ? &((_BINK_1_5_21_0 *)pBinkMovie)->uCurrentFrame : + uBinkVersion == 0x0003000000000000 ? &((_BINK_3_0_0_0 *)pBinkMovie)->uCurrentFrame : + nullptr; + while (*pCurrentFrame < uDstFrameNum) + { + BinkDoFrame(pBinkMovie); + BinkNextFrame(pBinkMovie); + } + } + } + else + { + if ( v3 != 1 ) + return; + SmackSoundOnOff(this->pSmackerMovie, 0); + if (uDstFrameNum) + { + while ( v2->pSmackerMovie->FrameNum < uDstFrameNum) + { + SmackDoFrame(v2->pSmackerMovie); + SmackNextFrame(v2->pSmackerMovie); + } + } + } + Unload(); +} + + +//----- (004BED4F) -------------------------------------------------------- +void VideoPlayer::BinkDrawFrame(HWND hWnd, int a3, int a4) +{ + //VideoPlayer *v4; // esi@1 + _BINKBUF *v5; // eax@5 + LONG v6; // edx@6 + int v7; // ecx@6 + LONG v8; // edx@6 + struct tagRECT a3a; // [sp+8h] [bp-20h]@10 + struct tagRECT a1; // [sp+18h] [bp-10h]@6 + + //v4 = this; + if ( this->pBinkMovie && this->pBinkBuffer ) + { + BinkDoFrame(pBinkMovie); + BinkGetRects(pBinkMovie, pBinkBuffer->uBinkDDSurfaceType); + if ( BinkLockBuffer(pBinkBuffer) ) + { + BinkCopyToBuffer(pBinkMovie, pBinkBuffer->pDDrawSurfaceData, pBinkBuffer->uDDrawSurfacePitch, pBinkBuffer->uHeight, + 0, 0, pBinkBuffer->uBinkDDSurfaceType); + BinkUnlockBuffer(pBinkBuffer); + } + v5 = pBinkBuffer; + if ( pRenderer->bWindowMode ) + { + v6 = v5->uRectX; + a1.left = v6; + a1.top = v5->uRectY; + v7 = v6 + v5->uWidth; + a1.right = v6 + v5->uWidth; + v8 = a1.top + v5->uHeight; + } + else + { + a1.left = 0; + a1.top = 0; + v7 = v5->uWidth; + a1.right = v5->uWidth; + v8 = v5->uHeight; + } + a1.bottom = v8; + if ( a4 ) + { + a1.right = v5->uWidth + v7; + a1.bottom = v5->uHeight + v8; + } + a3a.left = 0; + a3a.top = 0; + a3a.right = v5->uWidth; + a3a.bottom = v5->uHeight; + pRenderer->BltToFront(&a1, v5->pTargetDDrawSurface, &a3a, 0x1000000u); + + + int *pCurrentFrame = uBinkVersion == 0x0001000500150000 ? &((_BINK_1_5_21_0 *)pBinkMovie)->uCurrentFrame : + uBinkVersion == 0x0003000000000000 ? &((_BINK_3_0_0_0 *)pBinkMovie)->uCurrentFrame: + nullptr; + int *pNumFrames = uBinkVersion == 0x0001000500150000 ? &((_BINK_1_5_21_0 *)pBinkMovie)->uNumFrames : + uBinkVersion == 0x0003000000000000 ? &((_BINK_3_0_0_0 *)pBinkMovie)->uNumFrames : + nullptr; + + if (*pCurrentFrame != *pNumFrames - 1 || bLoopPlaying) + BinkNextFrame(pBinkMovie); + else + Unload(); + } +} + + + +//----- (004BEE6B) -------------------------------------------------------- +void VideoPlayer::SmackDrawFrame(HWND hWnd, int a3, int a4) +{ + VideoPlayer *v4; // esi@1 + _SMACK *v5; // eax@3 + unsigned int v6; // eax@5 + char v7; // zf@5 + int v8; // eax@11 + _SMACK *v9; // eax@13 + _SMACK *v10; // eax@16 + _SMACK *v11; // eax@20 + unsigned int v12; // [sp-1Ch] [bp-34h]@7 + LONG v13; // [sp-18h] [bp-30h]@7 + LONG v14; // [sp-14h] [bp-2Ch]@7 + signed int v15; // [sp-10h] [bp-28h]@7 + signed int v16; // [sp-Ch] [bp-24h]@7 + signed int v17; // [sp-8h] [bp-20h]@7 + struct tagPOINT Point; // [sp+8h] [bp-10h]@7 + unsigned short *pOutSurface; // [sp+10h] [bp-8h]@5 + unsigned int uPixelsPerRow; // [sp+14h] [bp-4h]@5 + + v4 = this; + if ( !pRenderer->bWindowMode || GetFocus() == hWnd ) + { + v5 = v4->pSmackerMovie; + if ( v5->NewPalette ) + SmackBlitSetPalette(v4->pSmackMovieBlit, v5->Palette, v5->PalType); + SmackDoFrame(v4->pSmackerMovie); + pRenderer->LockFrontBuffer((void **)&pOutSurface, &uPixelsPerRow); + v6 = 2 * uPixelsPerRow; + v7 = v4->bFirstFrame == 0; + uPixelsPerRow *= 2; + if ( !v7 ) + { + if ( pRenderer->bWindowMode ) + { + Point.y = 0; + Point.x = 0; + ClientToScreen(hWnd, &Point); + v17 = -1; + v16 = 480; + v15 = 640; + v14 = Point.y; + v13 = Point.x; + v12 = uPixelsPerRow; + } + else + { + v17 = -1; + v16 = 480; + v15 = 640; + v14 = 0; + v13 = 0; + v12 = v6; + } + SmackBlitClear(v4->pSmackMovieBlit, pOutSurface, v12, v13, v14, v15, v16, v17); + v4->bFirstFrame = 0; + } + pRenderer->RestoreFrontBuffer(); + if ( pRenderer->bWindowMode ) + { + Point.y = 0; + Point.x = 0; + ClientToScreen(hWnd, &Point); + v8 = SmackToBufferRect(v4->pSmackerMovie, 0); + if ( a4 ) + { + while ( v8 ) + { + v9 = v4->pSmackerMovie; + SmackBlit( + v4->pSmackMovieBlit, + pOutSurface, + uPixelsPerRow, + v9->LastRectx + Point.x / 2, + a3 + v9->LastRecty + Point.y / 2, + v4->pSomeSmackerBuffer, + v9->Width, + v9->LastRectx, + v9->LastRecty, + v9->LastRectw, + v9->LastRecth); + v8 = SmackToBufferRect(v4->pSmackerMovie, 0); + } + } + else + { + while ( v8 ) + { + v10 = v4->pSmackerMovie; + SmackBlit(v4->pSmackMovieBlit, pOutSurface, uPixelsPerRow, Point.x + v10->LastRectx, a3 + Point.y + v10->LastRecty, + v4->pSomeSmackerBuffer, v10->Width, v10->LastRectx, v10->LastRecty, v10->LastRectw, v10->LastRecth); + v8 = SmackToBufferRect(v4->pSmackerMovie, 0); + } + } + } + else + { + while ( SmackToBufferRect(v4->pSmackerMovie, 0) ) + { + v11 = v4->pSmackerMovie; + SmackBlit(v4->pSmackMovieBlit, pOutSurface, uPixelsPerRow, v11->LastRectx, a3 + v11->LastRecty, v4->pSomeSmackerBuffer, + v11->Width, v11->LastRectx, v11->LastRecty, v11->LastRectw, v11->LastRecth); + } + } + pRenderer->UnlockFrontBuffer(); + if ( v4->pSmackerMovie->FrameNum != v4->pSmackerMovie->Frames - 1 || v4->bLoopPlaying ) + SmackNextFrame(v4->pSmackerMovie); + else + Unload(); + } +} +// 4D83D8: using guessed type int __stdcall SmackBlitSetPalette(int, int, int); +// 4D83DC: using guessed type int __stdcall SmackBlitClear(int, int, int, int, int, int, int, int); +// 4D83E0: using guessed type int __stdcall SmackToBufferRect(int, int); +// 4D83E4: using guessed type int __stdcall SmackDoFrame(int); +// 4D83E8: using guessed type int __stdcall SmackNextFrame(int); +// 4D8404: using guessed type int __stdcall SmackBlit(int, int, int, int, int, int, int, int, int, int, int); + +//----- (004BF08B) -------------------------------------------------------- +void VideoPlayer::SmackUpdatePalette(HWND hWnd) +{ + VideoPlayer *v2; // esi@1 + unsigned __int16 *v3; // ebx@1 + unsigned int v4; // edi@1 + unsigned int v5; // eax@1 + _SMACK *v6; // eax@1 + + v2 = this; + pRenderer->BeginScene(); + v3 = pRenderer->pTargetSurface; + v4 = pRenderer->uTargetSurfacePitch; + v5 = SmackCheckSurfaceFromat(); + SmackToBuffer(v2->pSmackerMovie, 8, 8, 2 * v4, pRenderer->field_14, v3, v5); + v6 = v2->pSmackerMovie; + if ( v6->NewPalette ) + { + SmackBufferNewPalette((long)pSmackerBuffer, (long)v6->Palette, LOWORD(v6->PalType)); + SmackColorRemapWithTrans( + (long)pSmackerMovie, + (long)pSmackerBuffer->Palette, + (long)pSmackerBuffer->MaxPalColors, + (long)pSmackerBuffer->PalType, + 1000); + } + SmackDoFrame(v2->pSmackerMovie); + if ( v2->pSmackerMovie->FrameNum != v2->pSmackerMovie->Frames - 1 || v2->bLoopPlaying ) + SmackNextFrame(v2->pSmackerMovie); + else + Unload(); + pRenderer->EndScene(); +} + + + + + +//----- (004BF141) -------------------------------------------------------- +_BINK *VideoPlayer::OpenBink(const char *pName) +{ + //VideoPlayer *v2; // esi@1 + signed int v3; // edi@1 + int v4; // ebx@2 + signed int v5; // edi@5 + int v6; // ebx@6 + HANDLE v8; // [sp-8h] [bp-18h]@10 + unsigned int v9; // [sp-4h] [bp-14h]@10 + + for (uint i = 0; i < uNumMightVideoHeaders; ++i) + if (!strcmpi(pName, pMightVideoHeaders[i].pVideoName)) + { + SetFilePointer(hMightVid, pMightVideoHeaders[i].uFileOffset, 0, FILE_BEGIN); + + if (uBinkVersion < 0x0003000000000000) + return BinkOpen(hMightVid, 0x8800000); + else + return BinkOpen(hMightVid, 0x82000000); + } + + for (uint i = 0; i < uNumMagicVideoHeaders; ++i) + if (!strcmpi(pName, pMagicVideoHeaders[i].pVideoName)) + { + SetFilePointer(hMagicVid, pMagicVideoHeaders[i].uFileOffset, 0, FILE_BEGIN); + + if (uBinkVersion < 0x0003000000000000) + return BinkOpen(hMagicVid, 0x8800000); + else + return BinkOpen(hMagicVid, 0x82000000); + } + + return nullptr; +} +//----- (004BF1E6) -------------------------------------------------------- +_SMACK *VideoPlayer::OpenSmack(const char *pFilename) +{ + VideoPlayer *pVideoPlayer; // esi@1 + signed int v3; // edi@1 + int v4; // ebx@2 + signed int v5; // edi@5 + //int v6; // ebx@6 + //HANDLE v8; // [sp-Ch] [bp-1Ch]@10 + //unsigned int v9; // [sp-8h] [bp-18h]@10 + //signed int v10; // [sp-4h] [bp-14h]@10 + + pVideoPlayer = this; + if ( (signed int)this->uNumMightVideoHeaders > 0 ) + { + for ( v3 = 0; v3 < (signed int)pVideoPlayer->uNumMightVideoHeaders; ++v3) + { + v4 = _strcmpi(pVideoPlayer->pMightVideoHeaders[v3].pVideoName, pFilename); + if ( !v4 ) + { + SetFilePointer(pVideoPlayer->hMightVid, pVideoPlayer->pMightVideoHeaders[v3].uFileOffset, 0, 0); + return SmackOpen(pVideoPlayer->hMightVid, 0x7140, -1); + } + } + } + v5 = 0; + if ( (signed int)pVideoPlayer->uNumMagicVideoHeaders > 0 ) + { + while ( _strcmpi(pVideoPlayer->pMagicVideoHeaders[v5].pVideoName, pFilename) ) + { + ++v5; + if ( v5 >= (signed int)pVideoPlayer->uNumMagicVideoHeaders ) + return 0; + } + SetFilePointer(pVideoPlayer->hMagicVid, pVideoPlayer->pMagicVideoHeaders[v5].uFileOffset, 0, 0); + return SmackOpen(pVideoPlayer->hMagicVid, 0x7140, -1); + } + return 0; +} + +//----- (004BF28F) -------------------------------------------------------- +void VideoPlayer::_4BF28F(const char *pMovieName, unsigned int a3_1) +{ + VideoPlayer *v3; // esi@1 + std::string *v4; // ecx@3 + _SMACK *v5; // eax@4 + _SMACK *v6; // eax@7 + int v7; // eax@7 + int v8; // ecx@7 + unsigned int v9; // ebx@8 + unsigned int v10; // eax@8 + signed __int64 v11; // qax@9 + char *v12; // [sp-20h] [bp-54h]@3 + int v13; // [sp-1Ch] [bp-50h]@3 + std::string v14; // [sp-18h] [bp-4Ch]@3 + const char *v15; // [sp-8h] [bp-3Ch]@3 + int v16; // [sp-4h] [bp-38h]@3 + char Str2[0x30]; // [sp+Ch] [bp-28h]@4 + std::string *v18; // [sp+3Ch] [bp+8h]@3 + std::string *v19; // [sp+3Ch] [bp+8h]@5 + unsigned __int16 *v20; // [sp+3Ch] [bp+8h]@8 + + v3 = this; + if ( !this->field_54 ) + { + Prepare(); + v3->bLoopPlaying = a3_1; + __debugbreak(); // VideoPlayer is larger than this + if ( v3[1].pVideoFrame.pName[0] == 1 ) + { + v15 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Video.cpp:925"; + v12 = "Unsupported Bink playback!"; +LABEL_6: + MessageBoxA(nullptr, v12, v15, 0); + return; + } + sprintf(Str2, "%s.smk", pMovieName); + v5 = OpenSmack(Str2); + v3->pSmackerMovie = v5; + if ( !v5 ) + { + v3->Unload(); + sprintf(pTmpBuf, "Can't load %s", &Str2); + v15 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Video.cpp:937"; + v12 = pTmpBuf; + goto LABEL_6; + } + v16 = (int)pMovieName; + v3->uMovieFormat = 1; + strcpy(v3->pCurrentMovieName, (const char *)v16); + v6 = v3->pSmackerMovie; + v3->dword_0000A0 = 1; + v7 = SmackBufferOpen(v3->hWindow, 4, LOWORD(v6->Width), LOWORD(v6->Height), LOWORD(v6->Width), LOWORD(v6->Height)); + v3->pSmackerBuffer = (_SMACKBUF *)v7; + if ( v7 ) + { + pRenderer->BeginScene(); + v9 = pRenderer->uTargetSurfacePitch; + v20 = pRenderer->pTargetSurface; + v10 = SmackCheckSurfaceFromat(); + SmackToBuffer(v3->pSmackerMovie, 8, 8, 2 * v9, pRenderer->field_14, v20, v10); + pRenderer->EndScene(); + } + v16 = 32767; + v11 = (signed __int64)(pSoundVolumeLevels[(char)uSoundVolumeMultiplier] * 32767.0); + SmackVolumePan(v8, HIDWORD(v11), v3->pSmackerMovie, 1040384, v11, 32767); + } +} + +//----- (004BF3F9) -------------------------------------------------------- +bool VideoPlayer::AnyMovieLoaded() +{ + return pSmackerMovie || pBinkMovie; +} + +//----- (004BF411) -------------------------------------------------------- +void VideoPlayer::OpenMovie(const char *pFilename, unsigned int bLoop, int a4) +{ + VideoPlayer *pVideoPlayer; // esi@1 + _BINK *pVideoOpen; // eax@2 + _SMACK *v6; // eax@3 + _BINK *pBinkMovie; // eax@5 + _SMACK *v8; // eax@7 + char *v9; // eax@7 + unsigned int v10; // eax@11 + _SMACKBLIT *v11; // eax@14 + const char *v12; // [sp-4h] [bp-38h]@8 + char pVideoName[120]; // [sp+Ch] [bp-28h]@2 + + pVideoPlayer = this; + if ( !this->field_54 ) + { + Prepare(); + pVideoPlayer->bLoopPlaying = bLoop; + sprintf(pVideoName, "%s.bik", pFilename); + pVideoOpen = OpenBink(pVideoName); + pVideoPlayer->pBinkMovie = pVideoOpen; + if ( pVideoOpen ) + { + pVideoPlayer->uMovieFormat = 2; + strcpy(pVideoPlayer->pCurrentMovieName, pFilename); + pBinkMovie = pVideoPlayer->pBinkMovie; + pVideoPlayer->dword_0000A0 = 1; + if ( pBinkMovie ) + pVideoPlayer->pBinkBuffer = CreateBinkBuffer(pVideoPlayer->hWindow, pBinkMovie->uWidth, pBinkMovie->uHeight, 0); + } + else + { + Unload(); + sprintf(pVideoName, "%s.smk", pFilename); + v6 = OpenSmack(pVideoName); + pVideoPlayer->pSmackerMovie = v6; + if ( !v6 ) + { + Unload(); + sprintf(pVideoName, "Can't load file - anims\\%s.smk", pFilename); + MessageBoxA(0, pVideoName, "Smacker Error", 0); + return; + } + pVideoPlayer->uMovieFormat = 1; + strcpy(pVideoPlayer->pCurrentMovieName, pFilename); + v8 = pVideoPlayer->pSmackerMovie; + pVideoPlayer->dword_0000A0 = 2; + v9 = (char *)malloc(v8->Width * v8->Height); + pVideoPlayer->pSomeSmackerBuffer = v9; + if ( !v9 ) + { + Unload(); + v12 = "Can't allocate memory for buffer"; + sprintf(pVideoName, v12); + MessageBoxA(0, pVideoName, "Smacker Error", 0); + return; + } + SmackToBuffer(pVideoPlayer->pSmackerMovie, 0, 0, pVideoPlayer->pSmackerMovie->Width, pVideoPlayer->pSmackerMovie->Height, v9, 0); + if ( a4 ) + { + if ( (unsigned int)uCPUSpeed < 165 ) + { + v10 = SmackCheckSurfaceFromat() | 2; + } + else + { + v10 = SmackCheckSurfaceFromat(); + LOBYTE(v10) = v10 | 6; + } + } + else + { + v10 = SmackCheckSurfaceFromat(); + } + v11 = SmackBlitOpen(v10); + pVideoPlayer->pSmackMovieBlit = v11; + if ( !v11 ) + { + Unload(); + v12 = "Failed to open Blit API"; + sprintf(pVideoName, v12); + MessageBoxA(0, pVideoName, "Smacker Error", 0); + return; + } + } + } +} + + +//----- (004BF5B2) -------------------------------------------------------- +void VideoPlayer::_4BF5B2() +{ + VideoPlayer *v1; // esi@1 + unsigned int v2; // eax@1 + _BINK **v3; // edi@2 + + v1 = this; + v2 = this->uMovieFormat; + if ( v2 == 2 ) + { + v3 = &this->pBinkMovie; + BinkGoto(pBinkMovie, 1, 0); + BinkDoFrame(pBinkMovie); + BinkNextFrame(pBinkMovie); + } + else + { + if ( v2 != 1 ) + return; + SmackGoto(pSmackerMovie, 1); + if ( pVersion->pVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT || pVersion->pVersionInfo.dwMajorVersion != 4 ) + { + SmackDoFrame(pSmackerMovie); + SmackNextFrame(pSmackerMovie); + } + } + pMouse->_469E24(); + if ( ptr_507BC0 && ptr_507BC0->ptr_1C == (void *)165 && !v1->pSmackerMovie ) + { + bGameoverLoop = 1; + sub_4BD8B5(); + ptr_507BC0->Release(); + pParty->uFlags &= 0xFFFFFFFDu; + if ( EnterHouse((enum HOUSE_TYPE)165) ) + { + pAudioPlayer->PlaySound(SOUND_0, 0, 0, -1, 0, 0, 0, 0); + ptr_507BC0 = GUIWindow::Create(0, 0, 640, 480, WINDOW_HouseInterior, 165, 0); + ptr_507BC0->CreateButton(0x3Du, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 1u, 0x31u, "", 0); + ptr_507BC0->CreateButton(0xB1u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 2u, 0x32u, "", 0); + ptr_507BC0->CreateButton(0x124u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 3u, 0x33u, "", 0); + ptr_507BC0->CreateButton(0x197u, 0x1A8u, 0x1Fu, 0, 2, 94, 0x6Eu, 4u, 0x34u, "", 0); + } + bGameoverLoop = 0; + } +} + +//----- (004BF73A) -------------------------------------------------------- +void VideoPlayer::_4BF73A() +{ + VideoPlayer *v1; // esi@1 + int v2; // edi@1 + unsigned __int8 v3; // bl@1 + int v4; // edi@1 + char Source[32]; // [sp+Ch] [bp-40h]@1 + + v1 = this; + v2 = this->dword_0000A0; + v3 = LOBYTE(this->bLoopPlaying); + strcpy(Source, this->pCurrentMovieName); + Unload(); + v4 = v2 - 1; + if ( v4 ) + { + if ( v4 == 1 ) + OpenMovie(Source, v3, 1); + } + else + { + _4BF28F(Source, v3); + } +} + +//----- (004BF8F6) -------------------------------------------------------- +void VideoPlayer::PlayDeathMovie() +{ + bStopBeforeSchedule = 0; + field_40 = 0; + pGame->pCShow->PlayMovie(MOVIE_Death, 1); +} \ No newline at end of file