diff --git a/artifacts/ddraw.ini b/artifacts/ddraw.ini index 338781b0..2ce5a6d0 100644 --- a/artifacts/ddraw.ini +++ b/artifacts/ddraw.ini @@ -71,6 +71,9 @@ WindowData=0 ;The shader file .fx must be placed in \\shaders\ and must contain one technique with one or more passes ;GlobalShaderFile=global.fx +;Set to 1 to enable linear texture filtering +TextureFilter=0 + ;Set to 1 to do the palette conversion on the GPU ;Set to 2 to do the palette conversion on the CPU ;Set to 0 to pick automatically diff --git a/sfall/FalloutEngine/Functions.cpp b/sfall/FalloutEngine/Functions.cpp index 5d72f972..02876338 100644 --- a/sfall/FalloutEngine/Functions.cpp +++ b/sfall/FalloutEngine/Functions.cpp @@ -143,7 +143,7 @@ isNotStr: // prints scripting error in debug.log and stops current script execution by performing longjmp // USE WITH CAUTION void __declspec(naked) interpretError(const char* fmt, ...) { - __asm jmp fo::funcoffs::interpretError_ + __asm jmp fo::funcoffs::interpretError_; } long __fastcall tile_num(long x, long y) { @@ -324,7 +324,7 @@ void __cdecl buf_to_buf(void* src, long width, long height, long src_width, void dec eax; // height jnz startLoop; jmp end; -copySmall: // copies the small size data + copySmall: // copies the small size data mov ecx, remainderD; rep movsd; mov ecx, remainderB; diff --git a/sfall/FalloutEngine/Functions_def.h b/sfall/FalloutEngine/Functions_def.h index 01fc25a8..f700e082 100644 --- a/sfall/FalloutEngine/Functions_def.h +++ b/sfall/FalloutEngine/Functions_def.h @@ -123,7 +123,7 @@ WRAP_WATCOM_FUNC1(long, interpretPopLong, Program*, scriptPtr) // Pops value fr WRAP_WATCOM_FUNC2(long, intface_get_attack, DWORD*, hitMode, DWORD*, isSecondary) WRAP_WATCOM_FUNC0(long, intface_is_item_right_hand) WRAP_WATCOM_FUNC0(long, intface_is_hidden) -WRAP_WATCOM_FUNC0(void, intface_redraw) // redraws the main game interface windows (useful after changing some data like active hand, etc.) +WRAP_WATCOM_FUNC0(void, intface_redraw) // Redraws the main game interface windows (useful after changing some data like active hand, etc.) WRAP_WATCOM_FUNC0(void, intface_toggle_item_state) WRAP_WATCOM_FUNC1(void, intface_update_ac, long, animate) WRAP_WATCOM_FUNC2(void, intface_update_move_points, long, ap, long, freeAP) diff --git a/sfall/Modules/Graphics.cpp b/sfall/Modules/Graphics.cpp index 2ad78c46..6c6b1b74 100644 --- a/sfall/Modules/Graphics.cpp +++ b/sfall/Modules/Graphics.cpp @@ -50,6 +50,7 @@ static DWORD yoffset; static bool DeviceLost = false; static bool mainTexLock = false; +static bool textureFilter = false; static DDSURFACEDESC surfaceDesc; static DDSURFACEDESC mveDesc; @@ -271,16 +272,18 @@ static void ResetDevice(bool createNew) { MessageBoxA(window, "GPU does not support the D3DFMT_A8 texture format.\nNow CPU is used to convert the palette.", "Texture format error", MB_TASKMODAL | MB_ICONWARNING); } + d3d9Device->CreateTexture(ResWidth, ResHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &sTex1, 0); d3d9Device->CreateTexture(ResWidth, ResHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &sTex2, 0); + sTex1->GetSurfaceLevel(0, &sSurf1); + sTex2->GetSurfaceLevel(0, &sSurf2); + if (Graphics::GPUBlt) { d3d9Device->CreateTexture(256, 1, 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &gpuPalette, 0); gpuBltEffect->SetTexture(gpuBltMainTex, mainTex); gpuBltEffect->SetTexture(gpuBltPalette, gpuPalette); } - sTex1->GetSurfaceLevel(0, &sSurf1); - sTex2->GetSurfaceLevel(0, &sSurf2); d3d9Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer); ShaderVertices[1].y = ResHeight - 0.5f; @@ -323,9 +326,10 @@ static void ResetDevice(bool createNew) { d3d9Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); d3d9Device->SetRenderState(D3DRS_LIGHTING, false); - //d3d9Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE); //D3DTEXF_LINEAR - //d3d9Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE); //D3DTEXF_LINEAR - + if (textureFilter) { + d3d9Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3d9Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + } //d3d9Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 0, 255), 1.0f, 0); // for debbuging dlogr(" Done", DL_MAIN); } @@ -403,9 +407,9 @@ static void Refresh() { d3d9Device->SetStreamSource(0, vBuffer, 0, sizeof(VertexFormat)); d3d9Device->SetRenderTarget(0, sSurf1); - UINT unused; - if (ScriptShaders::Count() && Graphics::GPUBlt) { - gpuBltEffect->Begin(&unused, 0); + UINT passes; + if ((textureFilter || ScriptShaders::Count()) && Graphics::GPUBlt) { + gpuBltEffect->Begin(&passes, 0); gpuBltEffect->BeginPass(0); d3d9Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); gpuBltEffect->EndPass(); @@ -421,12 +425,12 @@ static void Refresh() { d3d9Device->SetStreamSource(0, vBuffer2, 0, sizeof(VertexFormat)); d3d9Device->SetRenderTarget(0, backBuffer); - if (!ScriptShaders::Count() && Graphics::GPUBlt) { - gpuBltEffect->Begin(&unused, 0); + if (!textureFilter && !ScriptShaders::Count() && Graphics::GPUBlt) { + gpuBltEffect->Begin(&passes, 0); gpuBltEffect->BeginPass(0); } d3d9Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); - if (!ScriptShaders::Count() && Graphics::GPUBlt) { + if (!textureFilter && !ScriptShaders::Count() && Graphics::GPUBlt) { gpuBltEffect->EndPass(); gpuBltEffect->End(); } @@ -528,7 +532,7 @@ void Graphics::ShowMovieFrame(IDirect3DTexture9* tex) { d3d9Device->BeginScene(); if (!mainTexLock) { - if (Graphics::GPUBlt && ScriptShaders::Count()) { + if (ScriptShaders::Count() && Graphics::GPUBlt) { d3d9Device->SetTexture(0, sTex2); } else { d3d9Device->SetTexture(0, mainTex); @@ -668,20 +672,34 @@ public: } mainTex->UnlockRect(0); //mainTexLock = false; - - //if (!Graphics::PlayAviMovie) return DD_OK; // Blt method is not executed during avi playback because the sfShowFrame_ function is blocked + //if (Graphics::PlayAviMovie) return DD_OK; // Blt method is not executed during avi playback because the sfShowFrame_ function is blocked if (!DeviceLost) { - d3d9Device->BeginScene(); - d3d9Device->SetStreamSource(0, vBuffer2, 0, sizeof(VertexFormat)); d3d9Device->SetTexture(0, mainTex); - if (Graphics::GPUBlt) { - UINT unused; - gpuBltEffect->Begin(&unused, 0); + + d3d9Device->BeginScene(); + UINT passes; + if (textureFilter && Graphics::GPUBlt) { // fixes color palette distortion of movie images when texture filtering and GPUBlt are enabled + d3d9Device->SetStreamSource(0, vBuffer, 0, sizeof(VertexFormat)); + d3d9Device->SetRenderTarget(0, sSurf1); + + gpuBltEffect->Begin(&passes, 0); + gpuBltEffect->BeginPass(0); + d3d9Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + gpuBltEffect->EndPass(); + gpuBltEffect->End(); + + d3d9Device->SetTexture(0, sTex1); + d3d9Device->SetRenderTarget(0, backBuffer); + } + d3d9Device->SetStreamSource(0, vBuffer2, 0, sizeof(VertexFormat)); + + if (!textureFilter && Graphics::GPUBlt) { + gpuBltEffect->Begin(&passes, 0); gpuBltEffect->BeginPass(0); } d3d9Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); - if (Graphics::GPUBlt) { + if (!textureFilter && Graphics::GPUBlt) { gpuBltEffect->EndPass(); gpuBltEffect->End(); } @@ -1082,6 +1100,9 @@ HRESULT __stdcall InitFakeDirectDrawCreate(void*, IDirectDraw** b, void*) { rcpres[0] = 1.0f / (float)gWidth; rcpres[1] = 1.0f / (float)gHeight; + // Disable texture filtering if the set resolutions are equal + textureFilter = (textureFilter && (ResWidth != gWidth || ResHeight != gHeight)); + *b = (IDirectDraw*)new FakeDirectDraw(); dlogr(" Done", DL_MAIN); @@ -1132,6 +1153,8 @@ void Graphics::init() { } SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2 HookCall(0x44260C, game_init_hook); + + textureFilter = (GetConfigInt("Graphics", "TextureFilter", 0) != 0); dlogr(" Done", DL_INIT); } diff --git a/sfall/Modules/Movies.cpp b/sfall/Modules/Movies.cpp index 79dba7fb..946cf785 100644 --- a/sfall/Modules/Movies.cpp +++ b/sfall/Modules/Movies.cpp @@ -317,7 +317,7 @@ static DWORD __fastcall PlayMovieLoop() { StopMovie(); return 0; // break play } - //Sleep(10); // idle delay + Sleep(10); // idle delay, reduces dropping frames when playing AVI __int64 pos; movieInterface.pSeek->GetCurrentPosition(&pos);