Added a new value 2 to AllowDShowMovies

* for forcing avi videos to fit the screen width.

Disabled warning C4995 (e.g. wcscpy in Movies.cpp)
Minor code edits to AI.cpp & Sound.cpp.
This commit is contained in:
NovaRain
2020-07-29 14:20:04 +08:00
parent 648bffedc6
commit 950b9949c0
11 changed files with 128 additions and 105 deletions
+1
View File
@@ -69,6 +69,7 @@ GPUBlt=0
Use32BitHeadGraphics=0
;Set to 1 to automatically search for alternative avi video files when Fallout tries to play the game movies
;Set to 2 to force avi videos to fit the screen width
;Requires DX9 graphics mode
AllowDShowMovies=0
+2 -2
View File
@@ -33,7 +33,7 @@ static std::tr1::unordered_map<TGameObj*, TGameObj*> targets;
static std::tr1::unordered_map<TGameObj*, TGameObj*> sources;
// Returns the friendly critter or any blocking object in the line of fire
TGameObj* __stdcall AI_CheckShootAndFriendlyInLineOfFire(TGameObj* object, long targetTile, long team) {
TGameObj* AI_CheckShootAndFriendlyInLineOfFire(TGameObj* object, long targetTile, long team) {
if (object && object->Type() == OBJ_TYPE_CRITTER && object->critter.teamNum != team) { // is not friendly fire
long objTile = object->tile;
if (objTile == targetTile) return nullptr;
@@ -52,7 +52,7 @@ TGameObj* __stdcall AI_CheckShootAndFriendlyInLineOfFire(TGameObj* object, long
}
// Returns the friendly critter in the line of fire
TGameObj* __stdcall AI_CheckFriendlyFire(TGameObj* target, TGameObj* attacker) {
TGameObj* AI_CheckFriendlyFire(TGameObj* target, TGameObj* attacker) {
TGameObj* object = nullptr;
MakeStraightPathFunc(attacker, attacker->tile, target->tile, 0, (DWORD*)&object, 32, (void*)obj_shoot_blocking_at_);
object = AI_CheckShootAndFriendlyInLineOfFire(object, target->tile, attacker->critter.teamNum);
+2 -2
View File
@@ -22,8 +22,8 @@
void AIInit();
TGameObj* __stdcall AI_CheckShootAndFriendlyInLineOfFire(TGameObj* object, long targetTile, long team);
TGameObj* __stdcall AI_CheckFriendlyFire(TGameObj* target, TGameObj* attacker);
TGameObj* AI_CheckShootAndFriendlyInLineOfFire(TGameObj* object, long targetTile, long team);
TGameObj* AI_CheckFriendlyFire(TGameObj* target, TGameObj* attacker);
void __stdcall AICombatStart();
void __stdcall AICombatEnd();
+1 -1
View File
@@ -2027,7 +2027,7 @@ void ClearWindow(DWORD winID, bool refresh) {
call win_width_;
mov ecx, eax;
mov edx, ebx;
mov eax, winID; //dword ptr ds:[_GNWWin];
mov eax, winID;
call win_fill_;
}
if (refresh) WinDraw(winID);
+102 -86
View File
@@ -52,6 +52,7 @@ DWORD GPUBlt;
DWORD GraphicsMode;
bool PlayAviMovie = false;
bool AviMovieWidthFit = false;
static BYTE* titlesBuffer = nullptr;
@@ -569,8 +570,8 @@ void Gfx_SetMovieTexture(IDirect3DTexture9* tex) {
D3DSURFACE_DESC desc;
movieTex->GetLevelDesc(0, &desc);
float aspect = (float)desc.Width / (float)desc.Height;
float winaspect = (float)gWidth / (float)gHeight;
float aviAspect = (float)desc.Width / (float)desc.Height;
float winAspect = (float)gWidth / (float)gHeight;
VertexFormat ShaderVertices2[4] = {
ShaderVertices[0],
@@ -584,25 +585,35 @@ void Gfx_SetMovieTexture(IDirect3DTexture9* tex) {
ShaderVertices2[3].y = (float)gHeight - 0.5f;
ShaderVertices2[3].x = (float)gWidth - 0.5f;
DWORD gap;
if (aspect > winaspect) {
aspect = (float)desc.Width / (float)gWidth;
desc.Height = (int)(desc.Height / aspect);
gap = (gHeight - desc.Height) / 2;
long offset;
if (aviAspect > winAspect) {
// scales height proportionally and places the movie surface at the center of the window along the Y-axis
aviAspect = (float)desc.Width / (float)gWidth;
desc.Height = (int)(desc.Height / aviAspect);
ShaderVertices2[0].y += gap;
ShaderVertices2[2].y += gap;
ShaderVertices2[1].y -= gap;
ShaderVertices2[3].y -= gap;
} else if (aspect < winaspect) {
aspect = (float)desc.Height / (float)gHeight;
desc.Width = (int)(desc.Width / aspect);
gap = (gWidth - desc.Width) / 2;
offset = (gHeight - desc.Height) / 2;
ShaderVertices2[0].x += gap;
ShaderVertices2[2].x -= gap;
ShaderVertices2[3].x -= gap;
ShaderVertices2[1].x += gap;
ShaderVertices2[0].y += offset;
ShaderVertices2[2].y += offset;
ShaderVertices2[1].y -= offset;
ShaderVertices2[3].y -= offset;
} else if (aviAspect < winAspect) {
if (AviMovieWidthFit || (hrpIsEnabled && *(DWORD*)HRPAddress(0x1006EC10) == 2)) {
// scales the movie surface to screen width
aviAspect = (float)gWidth / (float)desc.Width;
desc.Width = (int)(desc.Width * aviAspect);
} else {
// scales width proportionally and places the movie surface at the center of the window along the X-axis
aviAspect = (float)desc.Height / (float)gHeight;
desc.Width = (int)(desc.Width / aviAspect);
offset = (gWidth - desc.Width) / 2;
ShaderVertices2[0].x += offset;
ShaderVertices2[2].x -= offset;
ShaderVertices2[3].x -= offset;
ShaderVertices2[1].x += offset;
}
}
byte* VertexPointer;
@@ -682,68 +693,6 @@ void Graphics_OnGameLoad() {
LoadGlobalShader();
}
class FakePalette2 : IDirectDrawPalette {
private:
ULONG Refs;
public:
FakePalette2() {
Refs = 1;
}
// IUnknown methods
HRESULT __stdcall QueryInterface(REFIID, LPVOID*) {
return E_NOINTERFACE;
}
ULONG __stdcall AddRef() {
return ++Refs;
}
ULONG __stdcall Release() {
if (!--Refs) {
delete this;
return 0;
} else return Refs;
}
// IDirectDrawPalette methods
HRESULT __stdcall GetCaps(LPDWORD) { UNUSEDFUNCTION; }
HRESULT __stdcall GetEntries(DWORD, DWORD, DWORD, LPPALETTEENTRY) { UNUSEDFUNCTION; }
HRESULT __stdcall Initialize(LPDIRECTDRAW, DWORD, LPPALETTEENTRY) { UNUSEDFUNCTION; }
/* Called from:
0x4CB5C7 GNW95_SetPalette_
0x4CB36B GNW95_SetPaletteEntries_
*/
HRESULT __stdcall SetEntries(DWORD a, DWORD b, DWORD c, LPPALETTEENTRY destPal) { // used to set palette for splash screen, fades, subtitles
if (!windowInit || c == 0 || b + c > 256) return DDERR_INVALIDPARAMS;
CopyMemory(&palette[b], destPal, c * 4);
if (GPUBlt) {
if (gpuPalette) {
D3DLOCKED_RECT rect;
if (!FAILED(gpuPalette->LockRect(0, &rect, 0, D3DLOCK_DISCARD))) {
CopyMemory(rect.pBits, palette, 256 * 4);
gpuPalette->UnlockRect(0);
}
}
} else {
// X8B8G8R8 format
for (DWORD i = b; i < b + c; i++) { // swap color B <> R
BYTE clr = *(BYTE*)((DWORD)&palette[i]); // B
*(BYTE*)((DWORD)&palette[i]) = *(BYTE*)((DWORD)&palette[i] + 2); // R
*(BYTE*)((DWORD)&palette[i] + 2) = clr;
}
primaryDDSurface->SetPalette(0); // update
}
if (!PlayAviMovie) {
//dlog("\nSetEntries: -> RefreshGraphics", DL_INIT);
RefreshGraphics();
}
return DD_OK;
}
};
class FakeSurface2 : IDirectDrawSurface {
private:
ULONG Refs;
@@ -791,10 +740,10 @@ public:
movieDesc.lPitch = (a->right - a->left);
//xoffset = (ResWidth - movieDesc.lPitch) / 2;
//dlog_f("\nMovieDesc: w:%d, h:%d", DL_INIT, movieDesc.lPitch, movieDesc.dwHeight);
//dlog_f("\nBlt: [MovieDesc: w:%d, h:%d]", DL_INIT, movieDesc.lPitch, movieDesc.dwHeight);
IsPlayMovie = true;
if (PlayAviMovie) return DD_OK;
//if (PlayAviMovie) return DD_OK;
BYTE* lockTarget = ((FakeSurface2*)b)->lockTarget;
D3DLOCKED_RECT dRect;
@@ -855,9 +804,9 @@ public:
mainTex->UnlockRect(0);
if (!DeviceLost) {
d3d9Device->BeginScene();
d3d9Device->SetStreamSource(0, vBuffer2, 0, sizeof(VertexFormat));
d3d9Device->SetTexture(0, mainTex);
d3d9Device->BeginScene();
if (GPUBlt) {
UINT unused;
gpuBltEffect->Begin(&unused, 0);
@@ -949,9 +898,9 @@ public:
}
HRESULT __stdcall Unlock(LPVOID) { // common game (is primary)
//dlog("\nUnlock()", DL_INIT);
//dlog("\nUnlock", DL_INIT);
if (Primary && d3d9Device) {
//dlog(" is primary.", DL_INIT);
//dlog(" - is primary.", DL_INIT);
if (DeviceLost) {
if (d3d9Device->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) {
ResetDevice(false);
@@ -1052,6 +1001,73 @@ start2:
bool FakeSurface2::IsPlayMovie;
bool FakeSurface2::subTitlesShow;
class FakePalette2 : IDirectDrawPalette {
private:
ULONG Refs;
public:
FakePalette2() {
Refs = 1;
}
// IUnknown methods
HRESULT __stdcall QueryInterface(REFIID, LPVOID*) {
return E_NOINTERFACE;
}
ULONG __stdcall AddRef() {
return ++Refs;
}
ULONG __stdcall Release() {
if (!--Refs) {
delete this;
return 0;
} else return Refs;
}
// IDirectDrawPalette methods
HRESULT __stdcall GetCaps(LPDWORD) { UNUSEDFUNCTION; }
HRESULT __stdcall GetEntries(DWORD, DWORD, DWORD, LPPALETTEENTRY) { UNUSEDFUNCTION; }
HRESULT __stdcall Initialize(LPDIRECTDRAW, DWORD, LPPALETTEENTRY) { UNUSEDFUNCTION; }
/* Called from:
0x4CB5C7 GNW95_SetPalette_
0x4CB36B GNW95_SetPaletteEntries_
*/
HRESULT __stdcall SetEntries(DWORD a, DWORD b, DWORD c, LPPALETTEENTRY destPal) { // used to set palette for splash screen, fades, subtitles
if (!windowInit || c == 0 || b + c > 256) return DDERR_INVALIDPARAMS;
CopyMemory(&palette[b], destPal, c * 4);
if (GPUBlt) {
if (gpuPalette) {
D3DLOCKED_RECT rect;
if (!FAILED(gpuPalette->LockRect(0, &rect, 0, D3DLOCK_DISCARD))) {
CopyMemory(rect.pBits, palette, 256 * 4);
gpuPalette->UnlockRect(0);
}
}
} else {
// X8B8G8R8 format
for (DWORD i = b; i < b + c; i++) { // swap color B <> R
BYTE clr = *(BYTE*)((DWORD)&palette[i]); // B
*(BYTE*)((DWORD)&palette[i]) = *(BYTE*)((DWORD)&palette[i] + 2); // R
*(BYTE*)((DWORD)&palette[i] + 2) = clr;
}
primaryDDSurface->SetPalette(0); // update
if (FakeSurface2::IsPlayMovie) return DD_OK; // prevents flickering at the beginning of playback (w/o HRP & GPUBlt=2)
}
if (!PlayAviMovie) {
//dlog("\nSetEntries: -> RefreshGraphics", DL_INIT);
RefreshGraphics();
} else {
// only for debugging
//dlog("\nSetEntries: -> ShowMovieFrame", DL_INIT);
//Graphics::ShowMovieFrame();
}
return DD_OK;
}
};
class FakeDirectDraw2 : IDirectDraw
{
private:
+1
View File
@@ -26,6 +26,7 @@ extern DWORD GraphicsMode;
extern DWORD GPUBlt;
extern bool PlayAviMovie;
extern bool AviMovieWidthFit;
extern IDirect3D9* d3d9;
extern IDirect3DDevice9* d3d9Device;
+9 -5
View File
@@ -210,7 +210,7 @@ static DWORD backgroundVolume = 0;
void PlayMovie(sDSTexture* movie) {
movie->pControl->Run();
movie->pAudio->put_Volume(
CalculateVolumeDB(*ptr_master_volume, (backgroundVolume) ? backgroundVolume : *ptr_background_volume)
Sound_CalculateVolumeDB(*ptr_master_volume, (backgroundVolume) ? backgroundVolume : *ptr_background_volume)
);
}
@@ -524,10 +524,14 @@ void MoviesInit() {
WIP: Task
Implement subtitle output from the need to play an mve file in the background.
*/
if (GraphicsMode != 0 && GetConfigInt("Graphics", "AllowDShowMovies", 0)) {
MakeJump(0x44E690, gmovie_play_hack);
HookCall(0x44E993, gmovie_play_hook_stop);
/* NOTE: At this address 0x487781, HRP changes the callback procedure to display mve frames. */
if (GraphicsMode != 0) {
int allowDShowMovies = GetConfigInt("Graphics", "AllowDShowMovies", 0);
if (allowDShowMovies > 0) {
MakeJump(0x44E690, gmovie_play_hack);
HookCall(0x44E993, gmovie_play_hook_stop);
if (allowDShowMovies > 1) AviMovieWidthFit = true;
/* NOTE: At this address 0x487781, HRP changes the callback procedure to display mve frames. */
}
}
dlogr(" Done", DL_INIT);
+5 -5
View File
@@ -163,7 +163,7 @@ static void CreateSndWnd() {
}
// Get sound duration in seconds
static DWORD __stdcall GetSpeechDurationTime() {
static DWORD GetSpeechDurationTime() {
if (!speechSound->pSeek || !speechSound) return 0;
speechSound->pSeek->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
__int64 outVal;
@@ -171,7 +171,7 @@ static DWORD __stdcall GetSpeechDurationTime() {
return static_cast<DWORD>(outVal / 10000000) + 1;
}
static DWORD __stdcall GetSpeechPlayingPosition() {
static DWORD GetSpeechPlayingPosition() {
if (!speechSound) return 0;
__int64 pos;
speechSound->pSeek->GetCurrentPosition(&pos);
@@ -212,7 +212,7 @@ void __stdcall ResumeAllSfallSound() {
}
}
long __stdcall CalculateVolumeDB(long masterVolume, long passVolume) {
long Sound_CalculateVolumeDB(long masterVolume, long passVolume) {
if (masterVolume <= 0 || passVolume <= 0) return -9999; // mute
const int volOffset = -100; // adjust the maximum volume
@@ -233,8 +233,8 @@ long __stdcall CalculateVolumeDB(long masterVolume, long passVolume) {
static void __cdecl SfallSoundVolume(sDSSound* sound, SoundType type, long passVolume) {
long volume, sfxVolume, masterVolume = *ptr_master_volume;
volume = CalculateVolumeDB(masterVolume, passVolume);
if (type == SNDTYPE_game_master) sfxVolume = CalculateVolumeDB(masterVolume, *ptr_sndfx_volume);
volume = Sound_CalculateVolumeDB(masterVolume, passVolume);
if (type == SNDTYPE_game_master) sfxVolume = Sound_CalculateVolumeDB(masterVolume, *ptr_sndfx_volume);
if (sound) {
sound->pAudio->put_Volume(volume);
+1 -1
View File
@@ -25,4 +25,4 @@ void WipeSounds();
DWORD __stdcall PlaySfallSound(const char* path, long mode);
void __stdcall StopSfallSound(DWORD id);
long __stdcall CalculateVolumeDB(long masterVolume, long passVolume);
long Sound_CalculateVolumeDB(long masterVolume, long passVolume);
+1 -1
View File
@@ -162,7 +162,7 @@ static void __fastcall DrawHeadFrame(Frm* frm, int frameno) {
if (frm && !frm->broken) {
if (!frm->loaded && !LoadFrm(frm)) goto loadFail;
FrmFrameData* frame = FramePtr((FrmHeaderData*)frm, frameno, 0);
Gfx_SetHeadTex(frm->textures[frameno], frame->width, frame->height, frame->x + frm->xshift, frame->y + frm->yshift/*, (frm->showHighlights == 2)*/);
Gfx_SetHeadTex(frm->textures[frameno], frame->width, frame->height, frame->x + frm->xshift, frame->y + frm->yshift);
showHighlights = frm->showHighlights;
return;
}
+3 -2
View File
@@ -17,9 +17,10 @@
*/
#pragma once
#pragma warning(disable:4996)
#pragma warning(disable: 4996) // function or variable may be unsafe
#pragma warning(disable: 4995) // 'function': name was marked as #pragma deprecated
#ifdef NDEBUG
#pragma warning(disable:4414)
#pragma warning(disable: 4414) // 'function': short jump to function converted to near
#endif
#include <cassert>