mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed stuttering when playing avi movies
Fixed a crash when playing mve movies without the hi-res patch. Minor edits to ddraw.ini and function notes.txt.
This commit is contained in:
+18
-18
@@ -738,10 +738,27 @@ CreditsAtBottom=0
|
|||||||
;Set to 1 to enable sfall debugging mode
|
;Set to 1 to enable sfall debugging mode
|
||||||
Enable=0
|
Enable=0
|
||||||
|
|
||||||
|
;Set to 1 to give scripts direct access to Fallout's address space, and to make arbitrary calls into Fallout's code
|
||||||
|
;Set to 2 to also disable the memory address check in unsafe script functions
|
||||||
|
;Does not require sfall debugging mode
|
||||||
|
AllowUnsafeScripting=0
|
||||||
|
|
||||||
|
;If you're testing changes to the Fallout exe, you can override the CRC that sfall looks for here
|
||||||
|
;You can use several hex values, separated by commas
|
||||||
|
;Does not require sfall debugging mode
|
||||||
|
;ExtraCRC=0x00000000,0x00000000
|
||||||
|
|
||||||
|
;Set to 1 to skip the executable file size check
|
||||||
|
;Does not require sfall debugging mode
|
||||||
|
SkipSizeCheck=0
|
||||||
|
|
||||||
|
;Change to 1 to skip the compatibility mode check
|
||||||
|
SkipCompatModeCheck=0
|
||||||
|
|
||||||
;Fallout 2 Debug Patch
|
;Fallout 2 Debug Patch
|
||||||
;Set to 1 to send debug output to the screen, 2 to a debug.log file, or 3 to both the screen and debug.log
|
;Set to 1 to send debug output to the screen, 2 to a debug.log file, or 3 to both the screen and debug.log
|
||||||
;Does not require sfall debugging mode
|
;Does not require sfall debugging mode
|
||||||
;While you don't need to create an environment variable, you do still need to set the appropriate lines in fallout2.cfg:
|
;While you don't need to create an environment variable, you do still need to set the appropriate lines in fallout2.cfg
|
||||||
;-------
|
;-------
|
||||||
;[debug]
|
;[debug]
|
||||||
;mode=environment
|
;mode=environment
|
||||||
@@ -758,27 +775,10 @@ DebugMode=0
|
|||||||
;Set to 1 to hide error messages in debug output when a null value is passed to the function as an object
|
;Set to 1 to hide error messages in debug output when a null value is passed to the function as an object
|
||||||
HideObjIsNullMsg=0
|
HideObjIsNullMsg=0
|
||||||
|
|
||||||
;Change to 1 to skip the compatibility mode check
|
|
||||||
SkipCompatModeCheck=0
|
|
||||||
|
|
||||||
;Set to 1 to skip the executable file size check
|
|
||||||
;Does not require sfall debugging mode
|
|
||||||
SkipSizeCheck=0
|
|
||||||
|
|
||||||
;If you're testing changes to the Fallout exe, you can override the CRC that sfall looks for here
|
|
||||||
;You can use several hex values, separated by commas
|
|
||||||
;Does not require sfall debugging mode
|
|
||||||
;ExtraCRC=0x00000000,0x00000000
|
|
||||||
|
|
||||||
;Set to 1 to stop Fallout from deleting non read-only protos at startup
|
;Set to 1 to stop Fallout from deleting non read-only protos at startup
|
||||||
;Has pretty nasty side effects when saving/reloading, so don't use for regular gameplay
|
;Has pretty nasty side effects when saving/reloading, so don't use for regular gameplay
|
||||||
DontDeleteProtos=0
|
DontDeleteProtos=0
|
||||||
|
|
||||||
;Set to 1 to give scripts direct access to Fallout's address space, and to make arbitrary calls into Fallout's code
|
|
||||||
;Set to 2 to also disable the memory address check in unsafe script functions
|
|
||||||
;Does not require sfall debugging mode
|
|
||||||
AllowUnsafeScripting=0
|
|
||||||
|
|
||||||
;Set to 1 to force critters to display combat float messages
|
;Set to 1 to force critters to display combat float messages
|
||||||
;Requires AllowSoundForFloats to be enabled
|
;Requires AllowSoundForFloats to be enabled
|
||||||
Test_ForceFloats=0
|
Test_ForceFloats=0
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ The mapper manual lists the functions 'world_map_x_pos' and 'world_map_y_pos', w
|
|||||||
|
|
||||||
set_pipboy_available will only accept 0 or 1 as an argument. Using any other value will cause the function to have no effect. Use 0 to disable the pipboy, and 1 to enable it.
|
set_pipboy_available will only accept 0 or 1 as an argument. Using any other value will cause the function to have no effect. Use 0 to disable the pipboy, and 1 to enable it.
|
||||||
|
|
||||||
get/set_critter_current_ap functions should only be used during the target critters turn while in combat. Calling them outside of combat typically returns the critters max ap, but don't rely on that behaviour. (Specifically, if the critter has never before entered combat, it will probably return the critters base ap ignoring any extra bonuses from perks etc.) Using set_critter_current_ap on the player will not automatically redraw the screen, so the ap bar will be incorrect until the player next clicks.
|
get/set_critter_current_ap functions should only be used during the target critters turn while in combat. Calling them outside of combat typically returns the critters max ap, but don't rely on that behaviour. (Specifically, if the critter has never before entered combat, it will probably return the critters base ap ignoring any extra bonuses from perks etc.)
|
||||||
|
|
||||||
The 'type' value in the weapon knockback functions can be 0 or 1. If 0, the value becomes an absolute distance that targets will be knocked back. If 1, the value is multiplied by the distance they would normally have been knocked back. Weapon knockback modifiers are applied in the order weapon -> attacker -> target, so a x2 weapon wielded by an abs 6 attacker hitting a /2 target will knock the target back 3 squares. The knockback functions will not override the stonewall perk or knockdowns resulting from criticals. knockback values set on weapons or critters are not saved, and must be reset each time the player reloads.
|
The 'type' value in the weapon knockback functions can be 0 or 1. If 0, the value becomes an absolute distance that targets will be knocked back. If 1, the value is multiplied by the distance they would normally have been knocked back. Weapon knockback modifiers are applied in the order weapon -> attacker -> target, so a x2 weapon wielded by an abs 6 attacker hitting a /2 target will knock the target back 3 squares. The knockback functions will not override the stonewall perk or knockdowns resulting from criticals. knockback values set on weapons or critters are not saved, and must be reset each time the player reloads.
|
||||||
|
|
||||||
|
|||||||
+13
-16
@@ -55,8 +55,8 @@ bool PlayAviMovie = false;
|
|||||||
|
|
||||||
static BYTE* titlesBuffer = nullptr;
|
static BYTE* titlesBuffer = nullptr;
|
||||||
|
|
||||||
static DWORD yoffset, movieHeight = 0;
|
static DWORD yoffset;
|
||||||
//static DWORD xoffset, movieWidth = 0;
|
//static DWORD xoffset;
|
||||||
|
|
||||||
static bool DeviceLost = false;
|
static bool DeviceLost = false;
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ static void ResetDevice(bool createNew) {
|
|||||||
GetDisplayMode(dispMode);
|
GetDisplayMode(dispMode);
|
||||||
|
|
||||||
params.BackBufferCount = 1;
|
params.BackBufferCount = 1;
|
||||||
params.BackBufferFormat = dispMode.Format; // (GraphicsMode == 4) ? D3DFMT_UNKNOWN : D3DFMT_X8R8G8B8;
|
params.BackBufferFormat = dispMode.Format; // (GraphicsMode != 4) ? D3DFMT_UNKNOWN : D3DFMT_X8R8G8B8;
|
||||||
params.BackBufferWidth = gWidth;
|
params.BackBufferWidth = gWidth;
|
||||||
params.BackBufferHeight = gHeight;
|
params.BackBufferHeight = gHeight;
|
||||||
params.EnableAutoDepthStencil = false;
|
params.EnableAutoDepthStencil = false;
|
||||||
@@ -442,9 +442,9 @@ static void Present() {
|
|||||||
|
|
||||||
RECT r, r2;
|
RECT r, r2;
|
||||||
r.left = windowLeft;
|
r.left = windowLeft;
|
||||||
r.right = r.left + gWidth;
|
r.right = windowLeft + gWidth;
|
||||||
r.top = windowTop;
|
r.top = windowTop;
|
||||||
r.bottom = r.top + gHeight;
|
r.bottom = windowTop + gHeight;
|
||||||
AdjustWindowRect(&r, WS_CAPTION | WS_BORDER, false);
|
AdjustWindowRect(&r, WS_CAPTION | WS_BORDER, false);
|
||||||
|
|
||||||
r.right -= (r.left - windowLeft);
|
r.right -= (r.left - windowLeft);
|
||||||
@@ -781,24 +781,21 @@ public:
|
|||||||
/*
|
/*
|
||||||
0x4868DA movie_MVE_ShowFrame_
|
0x4868DA movie_MVE_ShowFrame_
|
||||||
*/
|
*/
|
||||||
HRESULT _stdcall Blt(LPRECT a, LPDIRECTDRAWSURFACE b, LPRECT c, DWORD d, LPDDBLTFX e) { // used for game movies (w/o HRP)
|
HRESULT _stdcall Blt(LPRECT a, LPDIRECTDRAWSURFACE b, LPRECT c, DWORD d, LPDDBLTFX e) { // used for game movies (only for w/o HRP)
|
||||||
//long addrs;
|
movieDesc.dwHeight = (a->bottom - a->top);
|
||||||
//__asm mov eax, dword ptr [ebp + 4];
|
yoffset = (ResHeight - movieDesc.dwHeight) / 2;
|
||||||
//__asm mov addrs, eax;
|
movieDesc.lPitch = (a->right - a->left);
|
||||||
//dlog_f("\nBlt(0x%x)", DL_INIT, addrs);
|
//xoffset = (ResWidth - movieDesc.lPitch) / 2;
|
||||||
|
|
||||||
|
//dlog_f("\nMovieDesc: w:%d, h:%d", DL_INIT, movieDesc.lPitch, movieDesc.dwHeight);
|
||||||
|
|
||||||
IsPlayMovie = true;
|
IsPlayMovie = true;
|
||||||
if (PlayAviMovie) return DD_OK;
|
if (PlayAviMovie) return DD_OK;
|
||||||
|
|
||||||
//movieWidth = (a->right - a->left);
|
|
||||||
//xoffset = (ResWidth - movieWidth) / 2;
|
|
||||||
//movieHeight = (a->bottom - a->top);
|
|
||||||
yoffset = (ResHeight - movieDesc.dwHeight) / 2;
|
|
||||||
|
|
||||||
BYTE* lockTarget = ((FakeSurface2*)b)->lockTarget;
|
BYTE* lockTarget = ((FakeSurface2*)b)->lockTarget;
|
||||||
D3DLOCKED_RECT dRect;
|
D3DLOCKED_RECT dRect;
|
||||||
Tex->LockRect(0, &dRect, a, 0);
|
Tex->LockRect(0, &dRect, a, 0);
|
||||||
DWORD width = movieDesc.lPitch; // the current size of the width of the mve movie //ResWidth;
|
DWORD width = movieDesc.lPitch; // the current size of the width of the mve movie
|
||||||
int pitch = dRect.Pitch;
|
int pitch = dRect.Pitch;
|
||||||
if (GPUBlt) {
|
if (GPUBlt) {
|
||||||
char* pBits = (char*)dRect.pBits;
|
char* pBits = (char*)dRect.pBits;
|
||||||
|
|||||||
+68
-67
@@ -26,11 +26,6 @@
|
|||||||
|
|
||||||
#include "Movies.h"
|
#include "Movies.h"
|
||||||
|
|
||||||
static DWORD MoviePtrs[MaxMovies];
|
|
||||||
char MoviePaths[MaxMovies * 65];
|
|
||||||
|
|
||||||
static bool aviIsReadyToPlay = false;
|
|
||||||
|
|
||||||
class CAllocator : public IVMRSurfaceAllocator9, IVMRImagePresenter9 {
|
class CAllocator : public IVMRSurfaceAllocator9, IVMRImagePresenter9 {
|
||||||
|
|
||||||
#define SAFERELEASE(a) { if (a) { a->Release(); a = nullptr; } }
|
#define SAFERELEASE(a) { if (a) { a->Release(); a = nullptr; } }
|
||||||
@@ -40,13 +35,15 @@ private:
|
|||||||
IVMRSurfaceAllocatorNotify9 *pAllocNotify;
|
IVMRSurfaceAllocatorNotify9 *pAllocNotify;
|
||||||
|
|
||||||
std::vector<IDirect3DSurface9*> surfaces;
|
std::vector<IDirect3DSurface9*> surfaces;
|
||||||
IDirect3DTexture9* pTex;
|
//IDirect3DTexture9* pTex;
|
||||||
IDirect3DTexture9* mTex;
|
IDirect3DTexture9* mTex;
|
||||||
|
|
||||||
|
bool isStartPresenting;
|
||||||
|
|
||||||
HRESULT __stdcall TerminateDevice(DWORD_PTR dwID) {
|
HRESULT __stdcall TerminateDevice(DWORD_PTR dwID) {
|
||||||
dlog_f("\nTerminate Device id: %d\n", DL_INIT, dwID);
|
dlog_f("\nTerminate Device id: %d\n", DL_INIT, dwID);
|
||||||
|
|
||||||
SAFERELEASE(pTex);
|
//SAFERELEASE(pTex);
|
||||||
SAFERELEASE(mTex);
|
SAFERELEASE(mTex);
|
||||||
|
|
||||||
for (std::vector<IDirect3DSurface9*>::iterator it = surfaces.begin(); it != surfaces.end(); ++it) {
|
for (std::vector<IDirect3DSurface9*>::iterator it = surfaces.begin(); it != surfaces.end(); ++it) {
|
||||||
@@ -80,7 +77,7 @@ private:
|
|||||||
HRESULT __stdcall InitializeDevice(DWORD_PTR dwUserID, VMR9AllocationInfo *lpAllocInfo, DWORD *lpNumBuffers) {
|
HRESULT __stdcall InitializeDevice(DWORD_PTR dwUserID, VMR9AllocationInfo *lpAllocInfo, DWORD *lpNumBuffers) {
|
||||||
dlog("\nInitialize Device:", DL_INIT);
|
dlog("\nInitialize Device:", DL_INIT);
|
||||||
|
|
||||||
lpAllocInfo->dwFlags |= VMR9AllocFlag_TextureSurface;
|
lpAllocInfo->dwFlags |= VMR9AllocFlag_TextureSurface; // | VMR9AllocFlag_DXVATarget;
|
||||||
lpAllocInfo->Pool = D3DPOOL_SYSTEMMEM;
|
lpAllocInfo->Pool = D3DPOOL_SYSTEMMEM;
|
||||||
|
|
||||||
// Ask the VMR-9 to allocate the surfaces for us.
|
// Ask the VMR-9 to allocate the surfaces for us.
|
||||||
@@ -92,15 +89,17 @@ private:
|
|||||||
HRESULT hr = pAllocNotify->AllocateSurfaceHelper(lpAllocInfo, lpNumBuffers, &surfaces[0]);
|
HRESULT hr = pAllocNotify->AllocateSurfaceHelper(lpAllocInfo, lpNumBuffers, &surfaces[0]);
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
dlog_f(" Width: %d,", DL_INIT, lpAllocInfo->dwWidth);
|
dlog_f(" Width: %d,", DL_INIT, lpAllocInfo->dwWidth);
|
||||||
dlog_f(" Height: %d,", DL_INIT, lpAllocInfo->dwHeight);
|
dlog_f(" Height: %d,", DL_INIT, lpAllocInfo->dwHeight);
|
||||||
dlog_f(" Format: %d", DL_INIT, lpAllocInfo->Format);
|
dlog_f(" Format: %d", DL_INIT, lpAllocInfo->Format);
|
||||||
|
#endif
|
||||||
|
|
||||||
hr = surfaces[0]->GetContainer(IID_IDirect3DTexture9, (void**)&pTex);
|
//hr = surfaces[0]->GetContainer(IID_IDirect3DTexture9, (void**)&pTex);
|
||||||
if (FAILED(hr)) {
|
//if (FAILED(hr)) {
|
||||||
TerminateDevice(-1);
|
// TerminateDevice(-1);
|
||||||
return hr;
|
// return hr;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (d3d9Device->CreateTexture(lpAllocInfo->dwWidth, lpAllocInfo->dwHeight, 1, 0, lpAllocInfo->Format, D3DPOOL_DEFAULT, &mTex, nullptr) != D3D_OK) {
|
if (d3d9Device->CreateTexture(lpAllocInfo->dwWidth, lpAllocInfo->dwHeight, 1, 0, lpAllocInfo->Format, D3DPOOL_DEFAULT, &mTex, nullptr) != D3D_OK) {
|
||||||
dlog(" Failed to create movie texture!", DL_INIT);
|
dlog(" Failed to create movie texture!", DL_INIT);
|
||||||
@@ -122,19 +121,24 @@ private:
|
|||||||
HRESULT __stdcall StartPresenting(DWORD_PTR dwUserID) {
|
HRESULT __stdcall StartPresenting(DWORD_PTR dwUserID) {
|
||||||
dlog("\nStart Presenting.", DL_INIT);
|
dlog("\nStart Presenting.", DL_INIT);
|
||||||
Gfx_SetMovieTexture(mTex);
|
Gfx_SetMovieTexture(mTex);
|
||||||
|
isStartPresenting = true;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall StopPresenting(DWORD_PTR dwUserID) {
|
HRESULT __stdcall StopPresenting(DWORD_PTR dwUserID) {
|
||||||
dlog("\nStop Presenting.", DL_INIT);
|
dlog("\nStop Presenting.", DL_INIT);
|
||||||
|
isStartPresenting = false;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall PresentImage(DWORD_PTR dwUserID, VMR9PresentationInfo *lpPresInfo) {
|
HRESULT __stdcall PresentImage(DWORD_PTR dwUserID, VMR9PresentationInfo *lpPresInfo) {
|
||||||
#ifndef NDEBUG
|
//dlog_f("\nPresent Image %d", DL_INIT, isStartPresenting);
|
||||||
dlog("\nPresent Image.", DL_INIT);
|
if (isStartPresenting) {
|
||||||
#endif
|
IDirect3DTexture9* tex;
|
||||||
d3d9Device->UpdateTexture(pTex, mTex);
|
lpPresInfo->lpSurf->GetContainer(IID_IDirect3DTexture9, (LPVOID*)&tex);
|
||||||
|
d3d9Device->UpdateTexture(tex, mTex);
|
||||||
|
Gfx_ShowMovieFrame();
|
||||||
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,14 +147,15 @@ public:
|
|||||||
RefCount = 1;
|
RefCount = 1;
|
||||||
pAllocNotify = nullptr;
|
pAllocNotify = nullptr;
|
||||||
mTex = nullptr;
|
mTex = nullptr;
|
||||||
pTex = nullptr;
|
//pTex = nullptr;
|
||||||
|
isStartPresenting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG __stdcall AddRef() {
|
ULONG __stdcall AddRef() {
|
||||||
return ++RefCount;
|
return ++RefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG _stdcall Release() {
|
ULONG __stdcall Release() {
|
||||||
if (--RefCount == 0) {
|
if (--RefCount == 0) {
|
||||||
TerminateDevice(-2);
|
TerminateDevice(-2);
|
||||||
if (pAllocNotify) {
|
if (pAllocNotify) {
|
||||||
@@ -180,9 +185,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct sDSTexture {
|
struct sDSTexture {
|
||||||
CAllocator *pMyAlloc;
|
CAllocator *pSFAlloc;
|
||||||
IGraphBuilder *pGraph;
|
IGraphBuilder *pGraph;
|
||||||
//ICaptureGraphBuilder2 *pBuild;
|
|
||||||
IBaseFilter *pVmr;
|
IBaseFilter *pVmr;
|
||||||
IVMRFilterConfig9 *pConfig;
|
IVMRFilterConfig9 *pConfig;
|
||||||
IVMRSurfaceAllocatorNotify9 *pAlloc;
|
IVMRSurfaceAllocatorNotify9 *pAlloc;
|
||||||
@@ -219,11 +223,10 @@ DWORD FreeMovie(sDSTexture* movie) {
|
|||||||
if (movie->pControl) movie->pControl->Release();
|
if (movie->pControl) movie->pControl->Release();
|
||||||
if (movie->pSeek) movie->pSeek->Release();
|
if (movie->pSeek) movie->pSeek->Release();
|
||||||
if (movie->pAlloc) movie->pAlloc->Release();
|
if (movie->pAlloc) movie->pAlloc->Release();
|
||||||
if (movie->pMyAlloc) movie->pMyAlloc->Release();
|
if (movie->pSFAlloc) movie->pSFAlloc->Release();
|
||||||
if (movie->pConfig) movie->pConfig->Release();
|
if (movie->pConfig) movie->pConfig->Release();
|
||||||
if (movie->pVmr) movie->pVmr->Release();
|
if (movie->pVmr) movie->pVmr->Release();
|
||||||
if (movie->pGraph) movie->pGraph->Release();
|
if (movie->pGraph) movie->pGraph->Release();
|
||||||
//if (movie->pBuild) movie->pBuild->Release();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,18 +235,10 @@ DWORD CreateDSGraph(wchar_t* path, sDSTexture* movie) {
|
|||||||
|
|
||||||
ZeroMemory(movie, sizeof(sDSTexture));
|
ZeroMemory(movie, sizeof(sDSTexture));
|
||||||
|
|
||||||
// Create the Capture Graph Builder.
|
|
||||||
//HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, 0, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&movie->pBuild);
|
|
||||||
//if (hr != S_OK) return FreeMovie(movie);
|
|
||||||
|
|
||||||
// Create the Filter Graph Manager.
|
// Create the Filter Graph Manager.
|
||||||
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&movie->pGraph);
|
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&movie->pGraph);
|
||||||
if (hr != S_OK) return FreeMovie(movie);
|
if (hr != S_OK) return FreeMovie(movie);
|
||||||
|
|
||||||
// Initialize the Capture Graph Builder.
|
|
||||||
//hr = movie->pBuild->SetFiltergraph(movie->pGraph);
|
|
||||||
//if (hr != S_OK) return FreeMovie(movie);
|
|
||||||
|
|
||||||
hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&movie->pVmr);
|
hr = CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&movie->pVmr);
|
||||||
if (hr != S_OK) return FreeMovie(movie);
|
if (hr != S_OK) return FreeMovie(movie);
|
||||||
|
|
||||||
@@ -261,45 +256,47 @@ DWORD CreateDSGraph(wchar_t* path, sDSTexture* movie) {
|
|||||||
Custom Allocator-Presenter for VMR-9:
|
Custom Allocator-Presenter for VMR-9:
|
||||||
https://docs.microsoft.com/en-us/windows/win32/directshow/supplying-a-custom-allocator-presenter-for-vmr-9
|
https://docs.microsoft.com/en-us/windows/win32/directshow/supplying-a-custom-allocator-presenter-for-vmr-9
|
||||||
*/
|
*/
|
||||||
movie->pMyAlloc = new CAllocator();
|
movie->pSFAlloc = new CAllocator();
|
||||||
|
|
||||||
hr = movie->pVmr->QueryInterface(IID_IVMRSurfaceAllocatorNotify9, (void**)&movie->pAlloc);
|
hr = movie->pVmr->QueryInterface(IID_IVMRSurfaceAllocatorNotify9, (void**)&movie->pAlloc);
|
||||||
if (hr != S_OK) return FreeMovie(movie);
|
if (hr != S_OK) return FreeMovie(movie);
|
||||||
|
|
||||||
hr = movie->pAlloc->AdviseSurfaceAllocator(0, (IVMRSurfaceAllocator9*)movie->pMyAlloc);
|
hr = movie->pAlloc->AdviseSurfaceAllocator(0, (IVMRSurfaceAllocator9*)movie->pSFAlloc);
|
||||||
if (hr != S_OK) return FreeMovie(movie);
|
if (hr != S_OK) return FreeMovie(movie);
|
||||||
|
|
||||||
hr = movie->pMyAlloc->AdviseNotify(movie->pAlloc);
|
hr = movie->pSFAlloc->AdviseNotify(movie->pAlloc);
|
||||||
if (hr != S_OK) return FreeMovie(movie);
|
if (hr != S_OK) return FreeMovie(movie);
|
||||||
/****************************************************/
|
/****************************************************/
|
||||||
|
|
||||||
hr = movie->pGraph->AddFilter(movie->pVmr, L"VMR9");
|
hr = movie->pGraph->AddFilter(movie->pVmr, L"VMR9");
|
||||||
if (hr != S_OK) return FreeMovie(movie);
|
if (hr != S_OK) return FreeMovie(movie);
|
||||||
|
|
||||||
dlog_f("\nStart rendering file.", DL_INIT);
|
dlog("\nStart rendering file.", DL_INIT);
|
||||||
hr = movie->pGraph->RenderFile(path, nullptr);
|
hr = movie->pGraph->RenderFile(path, nullptr);
|
||||||
if (hr != S_OK) dlog_f(" ERROR: %d", DL_INIT, hr);
|
if (hr != S_OK) dlog_f(" ERROR: %d", DL_INIT, hr);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
return (hr == S_OK && movie->pSFAlloc->GetMovieTexture()) ? 1 : 0;
|
||||||
if (movie->pMyAlloc->GetMovieTexture()) dlog_f("\nMovieTex: %d", DL_INIT, *(DWORD*)movie->pMyAlloc->GetMovieTexture());
|
|
||||||
#endif
|
|
||||||
return (movie->pMyAlloc->GetMovieTexture()) ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __int64 endMoviePosition;
|
||||||
|
|
||||||
// Movie play looping
|
// Movie play looping
|
||||||
static DWORD PlayMovieLoop() {
|
static DWORD PlayMovieLoop() {
|
||||||
Gfx_ShowMovieFrame();
|
//dlog("\nPlay Movie Loop.", DL_INIT);
|
||||||
|
|
||||||
|
if (*(DWORD*)_subtitles) __asm call movieUpdate_; // for reading subtitles when playing mve
|
||||||
|
|
||||||
if (GetAsyncKeyState(VK_ESCAPE)) {
|
if (GetAsyncKeyState(VK_ESCAPE)) {
|
||||||
StopMovie(&movieInterface);
|
StopMovie(&movieInterface);
|
||||||
return 0; // break play
|
return 0; // break play
|
||||||
}
|
}
|
||||||
|
|
||||||
_int64 pos, end;
|
Sleep(10); // idle delay
|
||||||
movieInterface.pSeek->GetCurrentPosition(&pos);
|
|
||||||
movieInterface.pSeek->GetStopPosition(&end);
|
|
||||||
|
|
||||||
bool isPlayEnd = (end == pos);
|
__int64 pos;
|
||||||
|
movieInterface.pSeek->GetCurrentPosition(&pos);
|
||||||
|
|
||||||
|
bool isPlayEnd = (endMoviePosition == pos);
|
||||||
if (isPlayEnd) StopMovie(&movieInterface);
|
if (isPlayEnd) StopMovie(&movieInterface);
|
||||||
|
|
||||||
return !isPlayEnd; // 0 - for breaking play
|
return !isPlayEnd; // 0 - for breaking play
|
||||||
@@ -308,7 +305,6 @@ static DWORD PlayMovieLoop() {
|
|||||||
static void __declspec(naked) gmovie_play_hook() {
|
static void __declspec(naked) gmovie_play_hook() {
|
||||||
__asm {
|
__asm {
|
||||||
push ecx;
|
push ecx;
|
||||||
xor eax, eax;
|
|
||||||
call GNW95_process_message_; // windows message pump
|
call GNW95_process_message_; // windows message pump
|
||||||
call PlayMovieLoop;
|
call PlayMovieLoop;
|
||||||
pop ecx;
|
pop ecx;
|
||||||
@@ -316,18 +312,6 @@ static void __declspec(naked) gmovie_play_hook() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) gmovie_play_hook_wsub() {
|
|
||||||
__asm {
|
|
||||||
push ecx;
|
|
||||||
xor eax, eax;
|
|
||||||
call GNW95_process_message_; // windows message pump
|
|
||||||
call movieUpdate_; // for playing mve
|
|
||||||
call PlayMovieLoop;
|
|
||||||
pop ecx;
|
|
||||||
retn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __declspec(naked) gmovie_play_hook_input() {
|
static void __declspec(naked) gmovie_play_hook_input() {
|
||||||
__asm {
|
__asm {
|
||||||
xor eax,eax;
|
xor eax,eax;
|
||||||
@@ -339,6 +323,20 @@ static void __declspec(naked) gmovie_play_hook_input() {
|
|||||||
static DWORD backgroundVolume = 0;
|
static DWORD backgroundVolume = 0;
|
||||||
|
|
||||||
static DWORD __fastcall PreparePlayMovie(const DWORD id) {
|
static DWORD __fastcall PreparePlayMovie(const DWORD id) {
|
||||||
|
static long isNotWMR = -1;
|
||||||
|
// Verify that the VMR exists on this system
|
||||||
|
if (isNotWMR == -1) {
|
||||||
|
IBaseFilter* pBF = nullptr;
|
||||||
|
if (SUCCEEDED(CoCreateInstance(CLSID_VideoMixingRenderer9, 0, CLSCTX_INPROC, IID_IBaseFilter, (LPVOID*)&pBF))) {
|
||||||
|
pBF->Release();
|
||||||
|
isNotWMR = 0;
|
||||||
|
} else {
|
||||||
|
dlogr("Error: Video Mixing Renderer (VMR9) capabilities are required.", DL_MAIN);
|
||||||
|
isNotWMR = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isNotWMR) return 0;
|
||||||
|
|
||||||
// Get file path in unicode
|
// Get file path in unicode
|
||||||
wchar_t path[MAX_PATH];
|
wchar_t path[MAX_PATH];
|
||||||
char* master_patches = *ptr_patches;
|
char* master_patches = *ptr_patches;
|
||||||
@@ -361,13 +359,13 @@ static DWORD __fastcall PreparePlayMovie(const DWORD id) {
|
|||||||
// Create texture and graph filter
|
// Create texture and graph filter
|
||||||
if (!CreateDSGraph(path, &movieInterface)) return FreeMovie(&movieInterface);
|
if (!CreateDSGraph(path, &movieInterface)) return FreeMovie(&movieInterface);
|
||||||
|
|
||||||
HookCall(0x44E949,gmovie_play_hook_input); // block get_input_ (if subtitles are disabled then mve videos will not be played)
|
HookCall(0x44E949, gmovie_play_hook_input); // block get_input_ (if subtitles are disabled then mve videos will not be played)
|
||||||
|
HookCall(0x44E937, gmovie_play_hook); // looping call moviePlaying_
|
||||||
|
|
||||||
// patching gmovie_play_ for disabled game subtitles
|
// patching gmovie_play_ for disabled game subtitles
|
||||||
if (*(DWORD*)_subtitles == 0) {
|
if (*(DWORD*)_subtitles == 0) {
|
||||||
HookCall(0x44E937, gmovie_play_hook); // looping call moviePlaying_
|
|
||||||
SafeWrite8(0x4CB850, 0xC3); // GNW95_ShowRect_ blocking image rendering from the 'descSurface' surface when subtitles are disabled (optional)
|
SafeWrite8(0x4CB850, 0xC3); // GNW95_ShowRect_ blocking image rendering from the 'descSurface' surface when subtitles are disabled (optional)
|
||||||
} else {
|
} else {
|
||||||
HookCall(0x44E937, gmovie_play_hook_wsub); // looping call moviePlaying_
|
|
||||||
//SafeWrite8(0x486654, 0xC3); // blocking movie_MVE_ShowFrame_
|
//SafeWrite8(0x486654, 0xC3); // blocking movie_MVE_ShowFrame_
|
||||||
//SafeWrite8(0x486900, 0xC3); // blocking movieShowFrame_
|
//SafeWrite8(0x486900, 0xC3); // blocking movieShowFrame_
|
||||||
SafeWrite8(0x4F5F40, 0xC3); // blocking sfShowFrame_ for disabling the display of mve video frames
|
SafeWrite8(0x4F5F40, 0xC3); // blocking sfShowFrame_ for disabling the display of mve video frames
|
||||||
@@ -381,14 +379,14 @@ static DWORD __fastcall PreparePlayMovie(const DWORD id) {
|
|||||||
//SafeWrite32(0x4C73B2, 0x2E);
|
//SafeWrite32(0x4C73B2, 0x2E);
|
||||||
//BlockCall(0x48827E);
|
//BlockCall(0x48827E);
|
||||||
//BlockCall(0x44E92B);
|
//BlockCall(0x44E92B);
|
||||||
//aviIsReadyToPlay = true;
|
|
||||||
|
|
||||||
|
movieInterface.pSeek->GetStopPosition(&endMoviePosition);
|
||||||
PlayMovie(&movieInterface);
|
PlayMovie(&movieInterface);
|
||||||
|
|
||||||
return 1; // play AVI
|
return 1; // play AVI
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _stdcall PlayMovieRestore() {
|
static void __stdcall PlayMovieRestore() {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
dlog("\nPlay Movie Restore.", DL_INIT);
|
dlog("\nPlay Movie Restore.", DL_INIT);
|
||||||
#endif
|
#endif
|
||||||
@@ -405,11 +403,10 @@ static void _stdcall PlayMovieRestore() {
|
|||||||
|
|
||||||
Gfx_SetMovieTexture(0);
|
Gfx_SetMovieTexture(0);
|
||||||
FreeMovie(&movieInterface);
|
FreeMovie(&movieInterface);
|
||||||
//aviIsReadyToPlay = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const DWORD gmovie_play_addr = 0x44E695;
|
|
||||||
static void __declspec(naked) gmovie_play_hack() {
|
static void __declspec(naked) gmovie_play_hack() {
|
||||||
|
static const DWORD gmovie_play_addr = 0x44E695;
|
||||||
__asm {
|
__asm {
|
||||||
cmp eax, MaxMovies;
|
cmp eax, MaxMovies;
|
||||||
jge failPlayAvi;
|
jge failPlayAvi;
|
||||||
@@ -423,7 +420,7 @@ static void __declspec(naked) gmovie_play_hack() {
|
|||||||
pop edx;
|
pop edx;
|
||||||
pop ecx;
|
pop ecx;
|
||||||
jz failPlayAvi;
|
jz failPlayAvi;
|
||||||
push offset return; // return here
|
push offset return; // return to here label
|
||||||
failPlayAvi:
|
failPlayAvi:
|
||||||
push ebx;
|
push ebx;
|
||||||
push ecx;
|
push ecx;
|
||||||
@@ -442,10 +439,14 @@ return:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const DWORD Artimer1DaysCheckJmp = 0x4A3790;
|
char MoviePaths[MaxMovies * 65];
|
||||||
static const DWORD Artimer1DaysCheckJmpLess = 0x4A37A9;
|
|
||||||
|
static DWORD MoviePtrs[MaxMovies];
|
||||||
static DWORD Artimer1DaysCheckTimer;
|
static DWORD Artimer1DaysCheckTimer;
|
||||||
|
|
||||||
static void __declspec(naked) Artimer1DaysCheckHack() {
|
static void __declspec(naked) Artimer1DaysCheckHack() {
|
||||||
|
static const DWORD Artimer1DaysCheckJmp = 0x4A3790;
|
||||||
|
static const DWORD Artimer1DaysCheckJmpLess = 0x4A37A9;
|
||||||
__asm {
|
__asm {
|
||||||
cmp edx, Artimer1DaysCheckTimer;
|
cmp edx, Artimer1DaysCheckTimer;
|
||||||
jl less;
|
jl less;
|
||||||
|
|||||||
Reference in New Issue
Block a user