Mercurial > might-and-magic-trilogy
view VideoPlayer.cpp @ 191:d625cbdf34f0
25.12.12(byte_4ED3D8)
author | Ritor1 |
---|---|
date | Tue, 25 Dec 2012 22:24:33 +0600 |
parents | 27bdff4ed3e6 |
children | af624eaf2fc5 |
line wrap: on
line source
#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); }