mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
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:
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -26,6 +26,7 @@ extern DWORD GraphicsMode;
|
||||
extern DWORD GPUBlt;
|
||||
|
||||
extern bool PlayAviMovie;
|
||||
extern bool AviMovieWidthFit;
|
||||
|
||||
extern IDirect3D9* d3d9;
|
||||
extern IDirect3DDevice9* d3d9Device;
|
||||
|
||||
+9
-5
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user