mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Moved some code from Graphics.cpp to the new submodule GameRender.cpp
Minor edits to MetaruleExtender.cpp and notes.txt.
This commit is contained in:
@@ -36,7 +36,7 @@ int w;
|
|||||||
int h;
|
int h;
|
||||||
|
|
||||||
// the pixel size is computed as: 1.0f / resolution
|
// the pixel size is computed as: 1.0f / resolution
|
||||||
float2 rcpRes;
|
float2 rcpres;
|
||||||
|
|
||||||
// system ticks (received from sfall)
|
// system ticks (received from sfall)
|
||||||
//int tickcount;
|
//int tickcount;
|
||||||
@@ -65,7 +65,7 @@ float4 BlurDeltaPassPS(float2 uv : TEXCOORD0, uniform float2 delta) : COLOR0
|
|||||||
float3 sumColor = (tex2D(s0, uv).rgb);
|
float3 sumColor = (tex2D(s0, uv).rgb);
|
||||||
float brightness = Brightness(sumColor);
|
float brightness = Brightness(sumColor);
|
||||||
|
|
||||||
delta *= rcpRes;
|
delta *= rcpres;
|
||||||
float totalWeight = 1;
|
float totalWeight = 1;
|
||||||
|
|
||||||
float2 pointUV = uv + delta;
|
float2 pointUV = uv + delta;
|
||||||
@@ -77,8 +77,8 @@ float4 BlurDeltaPassPS(float2 uv : TEXCOORD0, uniform float2 delta) : COLOR0
|
|||||||
return float4((sumColor / totalWeight), 1);
|
return float4((sumColor / totalWeight), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float2 wDelta = float2(1, 0) * rcpRes;
|
static const float2 wDelta = float2(1, 0) * rcpres;
|
||||||
static const float2 hDelta = float2(0, 1) * rcpRes;
|
static const float2 hDelta = float2(0, 1) * rcpres;
|
||||||
|
|
||||||
float4 BlurPS(float4 color : COLOR0, float2 uv : TEXCOORD0) : COLOR0
|
float4 BlurPS(float4 color : COLOR0, float2 uv : TEXCOORD0) : COLOR0
|
||||||
{
|
{
|
||||||
@@ -171,8 +171,8 @@ static const float sharpenVal0 = (Sharpen * (1.5 + EdgeSharpen));
|
|||||||
static const float sharpenVal1 = ((sharpenVal0 - 1) / 8.0);
|
static const float sharpenVal1 = ((sharpenVal0 - 1) / 8.0);
|
||||||
|
|
||||||
// pixel "width"
|
// pixel "width"
|
||||||
static const float px = rcpRes.x;
|
static const float px = rcpres.x;
|
||||||
static const float py = rcpRes.y;
|
static const float py = rcpres.y;
|
||||||
|
|
||||||
// for the blur filter
|
// for the blur filter
|
||||||
#define mean 1.0
|
#define mean 1.0
|
||||||
|
|||||||
@@ -770,7 +770,7 @@ optional arguments:
|
|||||||
- width (optional): the maximum width of the text. The text will be wrapped to fit within the specified width
|
- width (optional): the maximum width of the text. The text will be wrapped to fit within the specified width
|
||||||
|
|
||||||
> mixed sfall_func0("combat_data")
|
> mixed sfall_func0("combat_data")
|
||||||
- returns a pointer to the C_ATTACK_* data for the current combat attack turn (see defined constants in define_extra.h)
|
- returns a pointer to the C_ATTACK_* data for the current combat attack process (see defined constants in define_extra.h)
|
||||||
- can be used in conjunction with the get_object_data and set_object_data functions
|
- can be used in conjunction with the get_object_data and set_object_data functions
|
||||||
example: sfall_func3("set_object_data", sfall_func0("combat_data"), C_ATTACK_UNUSED, 255);
|
example: sfall_func3("set_object_data", sfall_func0("combat_data"), C_ATTACK_UNUSED, 255);
|
||||||
|
|
||||||
|
|||||||
+7
-202
@@ -19,10 +19,10 @@
|
|||||||
#include "..\main.h"
|
#include "..\main.h"
|
||||||
#include "..\FalloutEngine\Fallout2.h"
|
#include "..\FalloutEngine\Fallout2.h"
|
||||||
#include "..\InputFuncs.h"
|
#include "..\InputFuncs.h"
|
||||||
#include "..\Version.h"
|
|
||||||
#include "LoadGameHook.h"
|
|
||||||
#include "ScriptShaders.h"
|
#include "ScriptShaders.h"
|
||||||
|
|
||||||
|
#include "SubModules\GameRender.h"
|
||||||
|
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
|
|
||||||
namespace sfall
|
namespace sfall
|
||||||
@@ -34,7 +34,7 @@ namespace sfall
|
|||||||
typedef HRESULT (__stdcall *DDrawCreateProc)(void*, IDirectDraw**, void*);
|
typedef HRESULT (__stdcall *DDrawCreateProc)(void*, IDirectDraw**, void*);
|
||||||
//typedef IDirect3D9* (__stdcall *D3DCreateProc)(UINT version);
|
//typedef IDirect3D9* (__stdcall *D3DCreateProc)(UINT version);
|
||||||
|
|
||||||
static IDirectDrawSurface* primaryDDSurface = nullptr; // aka _GNW95_DDPrimarySurface
|
IDirectDrawSurface* primaryDDSurface = nullptr; // aka _GNW95_DDPrimarySurface
|
||||||
|
|
||||||
static DWORD ResWidth;
|
static DWORD ResWidth;
|
||||||
static DWORD ResHeight;
|
static DWORD ResHeight;
|
||||||
@@ -48,7 +48,7 @@ bool Graphics::AviMovieWidthFit = false;
|
|||||||
static DWORD yoffset;
|
static DWORD yoffset;
|
||||||
//static DWORD xoffset;
|
//static DWORD xoffset;
|
||||||
|
|
||||||
static bool DeviceLost = false;
|
bool DeviceLost = false;
|
||||||
static bool mainTexLock = false;
|
static bool mainTexLock = false;
|
||||||
static char textureFilter; // 1 - auto, 2 - force
|
static char textureFilter; // 1 - auto, 2 - force
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ static VertexFormat ShaderVertices[] = {
|
|||||||
{639.5, 479.5, 0, 1, 1, 1} // 3 - bottom right
|
{639.5, 479.5, 0, 1, 1, 1} // 3 - bottom right
|
||||||
};
|
};
|
||||||
|
|
||||||
HWND GetFalloutWindowInfo(RECT* rect) {
|
HWND Graphics::GetFalloutWindowInfo(RECT* rect) {
|
||||||
if (rect) {
|
if (rect) {
|
||||||
rect->left = windowLeft;
|
rect->left = windowLeft;
|
||||||
rect->top = windowTop;
|
rect->top = windowTop;
|
||||||
@@ -185,7 +185,7 @@ long Graphics::GetGameHeightRes() {
|
|||||||
return (fo::var::scr_size.offy - fo::var::scr_size.y) + 1;
|
return (fo::var::scr_size.offy - fo::var::scr_size.y) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall GetShaderVersion() {
|
int __stdcall Graphics::GetShaderVersion() {
|
||||||
return ShaderVersion;
|
return ShaderVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1125,178 +1125,6 @@ static __declspec(naked) void game_init_hook() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static double fadeMulti;
|
|
||||||
|
|
||||||
static __declspec(naked) void palette_fade_to_hook() {
|
|
||||||
__asm {
|
|
||||||
push ebx; // _fade_steps
|
|
||||||
fild [esp];
|
|
||||||
fmul fadeMulti;
|
|
||||||
fistp [esp];
|
|
||||||
pop ebx;
|
|
||||||
jmp fo::funcoffs::fadeSystemPalette_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void __forceinline UpdateDDSurface(BYTE* surface, int width, int height, int widthFrom, RECT* rect) {
|
|
||||||
DDSURFACEDESC desc;
|
|
||||||
RECT lockRect = { rect->left, rect->top, rect->right + 1, rect->bottom + 1 };
|
|
||||||
|
|
||||||
primaryDDSurface->Lock(&lockRect, &desc, 0, 0);
|
|
||||||
|
|
||||||
fo::func::buf_to_buf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch); //+ (desc.lPitch * rect->top) + rect->left
|
|
||||||
|
|
||||||
primaryDDSurface->Unlock(desc.lpSurface);
|
|
||||||
}
|
|
||||||
|
|
||||||
static BYTE* GetBuffer() {
|
|
||||||
return (BYTE*)*(DWORD*)FO_VAR_screen_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYTE* toBuffer) {
|
|
||||||
if (win->flags & fo::WinFlags::Hidden) return;
|
|
||||||
fo::RectList* rects;
|
|
||||||
|
|
||||||
if (win->flags & fo::WinFlags::Transparent && !*(DWORD*)FO_VAR_doing_refresh_all) {
|
|
||||||
__asm {
|
|
||||||
mov eax, updateRect;
|
|
||||||
mov edx, ds:[FO_VAR_screen_buffer];
|
|
||||||
call fo::funcoffs::refresh_all_;
|
|
||||||
}
|
|
||||||
int w = updateRect->right - updateRect->left + 1;
|
|
||||||
|
|
||||||
if (fo::var::mouse_is_hidden || !fo::func::mouse_in(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) {
|
|
||||||
/*__asm {
|
|
||||||
mov eax, win;
|
|
||||||
mov edx, updateRect;
|
|
||||||
call fo::funcoffs::GNW_button_refresh_;
|
|
||||||
}*/
|
|
||||||
if (!DeviceLost) {
|
|
||||||
int h = (updateRect->bottom - updateRect->top) + 1;
|
|
||||||
UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fo::func::mouse_show(); // for updating background cursor area
|
|
||||||
RECT mouseRect;
|
|
||||||
__asm {
|
|
||||||
lea eax, mouseRect;
|
|
||||||
mov edx, eax;
|
|
||||||
call fo::funcoffs::mouse_get_rect_;
|
|
||||||
mov eax, updateRect;
|
|
||||||
call fo::funcoffs::rect_clip_;
|
|
||||||
mov rects, eax;
|
|
||||||
}
|
|
||||||
while (rects) { // updates everything except the cursor area
|
|
||||||
/*__asm {
|
|
||||||
mov eax, win;
|
|
||||||
mov edx, rects;
|
|
||||||
call fo::funcoffs::GNW_button_refresh_;
|
|
||||||
}*/
|
|
||||||
if (!DeviceLost) {
|
|
||||||
int wRect = (rects->wRect.right - rects->wRect.left) + 1;
|
|
||||||
int hRect = (rects->wRect.bottom - rects->wRect.top) + 1;
|
|
||||||
UpdateDDSurface(&GetBuffer()[rects->wRect.left - updateRect->left] + (rects->wRect.top - updateRect->top) * w, wRect, hRect, w, &rects->wRect);
|
|
||||||
}
|
|
||||||
fo::RectList* next = rects->nextRect;
|
|
||||||
fo::sf_rect_free(rects);
|
|
||||||
rects = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocates memory for 10 RectList (if no memory was allocated), returns the first Rect and removes it from the list */
|
|
||||||
__asm {
|
|
||||||
call fo::funcoffs::rect_malloc_;
|
|
||||||
mov rects, eax;
|
|
||||||
}
|
|
||||||
if (!rects) return;
|
|
||||||
|
|
||||||
rects->rect = { updateRect->left, updateRect->top, updateRect->right, updateRect->bottom };
|
|
||||||
rects->nextRect = nullptr;
|
|
||||||
RECT &rect = rects->wRect;
|
|
||||||
|
|
||||||
/*
|
|
||||||
If the border of the updateRect rectangle is located outside the window, then assign to rects->rect the border of the window rectangle
|
|
||||||
Otherwise, rects->rect contains the borders from the update rectangle (updateRect)
|
|
||||||
*/
|
|
||||||
if (win->wRect.left >= rect.left) rect.left = win->wRect.left;
|
|
||||||
if (win->wRect.top >= rect.top) rect.top = win->wRect.top;
|
|
||||||
if (win->wRect.right <= rect.right) rect.right = win->wRect.right;
|
|
||||||
if (win->wRect.bottom <= rect.bottom) rect.bottom = win->wRect.bottom;
|
|
||||||
|
|
||||||
if (rect.right < rect.left || rect.bottom < rect.top) {
|
|
||||||
fo::sf_rect_free(rects);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int widthFrom = win->width;
|
|
||||||
int toWidth = (toBuffer) ? updateRect->right - updateRect->left + 1 : Graphics::GetGameWidthRes();
|
|
||||||
|
|
||||||
fo::func::win_clip(win, &rects, toBuffer);
|
|
||||||
|
|
||||||
fo::RectList* currRect = rects;
|
|
||||||
while (currRect) {
|
|
||||||
RECT &crect = currRect->wRect;
|
|
||||||
int width = (crect.right - crect.left) + 1; // for current rectangle
|
|
||||||
int height = (crect.bottom - crect.top) + 1;; // for current rectangle
|
|
||||||
|
|
||||||
BYTE* surface;
|
|
||||||
if (win->wID) {
|
|
||||||
__asm {
|
|
||||||
mov eax, win;
|
|
||||||
mov edx, currRect;
|
|
||||||
call fo::funcoffs::GNW_button_refresh_;
|
|
||||||
}
|
|
||||||
surface = &win->surface[crect.left - win->rect.x] + ((crect.top - win->rect.y) * win->width);
|
|
||||||
} else {
|
|
||||||
surface = new BYTE[height * width](); // black background
|
|
||||||
widthFrom = width; // replace with rectangle
|
|
||||||
}
|
|
||||||
|
|
||||||
auto drawFunc = (win->flags & fo::WinFlags::Transparent && win->wID) ? fo::func::trans_buf_to_buf : fo::func::buf_to_buf;
|
|
||||||
if (toBuffer) {
|
|
||||||
drawFunc(surface, width, height, widthFrom, &toBuffer[crect.left - updateRect->left] + ((crect.top - updateRect->top) * toWidth), toWidth);
|
|
||||||
} else {
|
|
||||||
// copy to buffer instead of DD surface (buffering)
|
|
||||||
drawFunc(surface, width, height, widthFrom, &GetBuffer()[crect.left] + (crect.top * toWidth), toWidth);
|
|
||||||
//if (!DeviceLost) UpdateDDSurface(surface, width, height, widthFrom, crect);
|
|
||||||
}
|
|
||||||
if (win->wID == 0) delete[] surface;
|
|
||||||
|
|
||||||
currRect = currRect->nextRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (rects) {
|
|
||||||
// copy all rectangles from the buffer to the DD surface (buffering)
|
|
||||||
if (!toBuffer && !DeviceLost) {
|
|
||||||
int width = (rects->rect.offx - rects->rect.x) + 1;
|
|
||||||
int height = (rects->rect.offy - rects->rect.y) + 1;
|
|
||||||
int widthFrom = toWidth;
|
|
||||||
UpdateDDSurface(&GetBuffer()[rects->rect.x] + (rects->rect.y * widthFrom), width, height, widthFrom, &rects->wRect);
|
|
||||||
}
|
|
||||||
fo::RectList* next = rects->nextRect;
|
|
||||||
fo::sf_rect_free(rects);
|
|
||||||
rects = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!toBuffer && !*(DWORD*)FO_VAR_doing_refresh_all && !fo::var::mouse_is_hidden && fo::func::mouse_in(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) {
|
|
||||||
fo::func::mouse_show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static __declspec(naked) void GNW_win_refresh_hack() {
|
|
||||||
__asm {
|
|
||||||
push ebx; // toBuffer
|
|
||||||
mov ecx, eax;
|
|
||||||
call sf_GNW_win_refresh;
|
|
||||||
pop ecx;
|
|
||||||
retn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::init() {
|
void Graphics::init() {
|
||||||
Graphics::mode = GetConfigInt("Graphics", "Mode", 0);
|
Graphics::mode = GetConfigInt("Graphics", "Mode", 0);
|
||||||
if (Graphics::mode == 6) {
|
if (Graphics::mode == 6) {
|
||||||
@@ -1324,30 +1152,7 @@ void Graphics::init() {
|
|||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
fadeMulti = GetConfigInt("Graphics", "FadeMultiplier", 100);
|
GameRender::init();
|
||||||
if (fadeMulti != 100) {
|
|
||||||
dlog("Applying fade patch.", DL_INIT);
|
|
||||||
HookCall(0x493B16, palette_fade_to_hook);
|
|
||||||
fadeMulti = ((double)fadeMulti) / 100.0;
|
|
||||||
dlogr(" Done", DL_INIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the srcCopy_ function with a pure MMX implementation
|
|
||||||
MakeJump(0x4D36D4, fo::func::buf_to_buf); // buf_to_buf_
|
|
||||||
// Replace the transSrcCopy_ function
|
|
||||||
MakeJump(0x4D3704, fo::func::trans_buf_to_buf); // trans_buf_to_buf_
|
|
||||||
|
|
||||||
// Enable support for transparent interface windows
|
|
||||||
SafeWrite16(0x4D5D46, 0x9090); // win_init_ (create screen_buffer)
|
|
||||||
SafeWrite8(0x42F869, fo::WinFlags::MoveOnTop | fo::WinFlags::OwnerFlag); // addWindow_ (remove Transparent flag)
|
|
||||||
if (Graphics::mode) {
|
|
||||||
// custom implementation of the GNW_win_refresh function
|
|
||||||
MakeJump(0x4D6FD9, GNW_win_refresh_hack, 1);
|
|
||||||
SafeWrite16(0x4D75E6, 0x9090); // win_clip_ (remove _buffering checking)
|
|
||||||
} else { // for default or HRP graphics mode
|
|
||||||
SafeWrite8(0x4D5DAB, 0x1D); // ecx > ebx (enable _buffering)
|
|
||||||
BlockCall(0x431076); // dialogMessage_
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::exit() {
|
void Graphics::exit() {
|
||||||
|
|||||||
@@ -27,6 +27,11 @@
|
|||||||
namespace sfall
|
namespace sfall
|
||||||
{
|
{
|
||||||
|
|
||||||
|
extern IDirect3D9* d3d9;
|
||||||
|
extern IDirect3DDevice9* d3d9Device;
|
||||||
|
extern IDirectDrawSurface* primaryDDSurface;
|
||||||
|
extern bool DeviceLost;
|
||||||
|
|
||||||
class Graphics : public Module {
|
class Graphics : public Module {
|
||||||
public:
|
public:
|
||||||
const char* name() { return "Graphics"; }
|
const char* name() { return "Graphics"; }
|
||||||
@@ -36,9 +41,12 @@ public:
|
|||||||
static DWORD mode;
|
static DWORD mode;
|
||||||
static DWORD GPUBlt;
|
static DWORD GPUBlt;
|
||||||
|
|
||||||
|
static HWND GetFalloutWindowInfo(RECT* rect);
|
||||||
static long GetGameWidthRes();
|
static long GetGameWidthRes();
|
||||||
static long GetGameHeightRes();
|
static long GetGameHeightRes();
|
||||||
|
|
||||||
|
static int __stdcall GetShaderVersion();
|
||||||
|
|
||||||
static const float* rcpresGet();
|
static const float* rcpresGet();
|
||||||
|
|
||||||
static void SetHighlightTexture(IDirect3DTexture9* htex, int xPos, int yPos);
|
static void SetHighlightTexture(IDirect3DTexture9* htex, int xPos, int yPos);
|
||||||
@@ -56,13 +64,19 @@ public:
|
|||||||
static bool AviMovieWidthFit;
|
static bool AviMovieWidthFit;
|
||||||
|
|
||||||
static void RefreshGraphics();
|
static void RefreshGraphics();
|
||||||
|
|
||||||
|
static __forceinline void UpdateDDSurface(BYTE* surface, int width, int height, int widthFrom, RECT* rect) {
|
||||||
|
if (!DeviceLost) {
|
||||||
|
DDSURFACEDESC desc;
|
||||||
|
RECT lockRect = { rect->left, rect->top, rect->right + 1, rect->bottom + 1 };
|
||||||
|
|
||||||
|
primaryDDSurface->Lock(&lockRect, &desc, 0, 0);
|
||||||
|
|
||||||
|
fo::func::buf_to_buf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch); //+ (desc.lPitch * rect->top) + rect->left
|
||||||
|
|
||||||
|
primaryDDSurface->Unlock(desc.lpSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern IDirect3D9* d3d9;
|
|
||||||
extern IDirect3DDevice9* d3d9Device;
|
|
||||||
|
|
||||||
int __stdcall GetShaderVersion();
|
|
||||||
|
|
||||||
HWND GetFalloutWindowInfo(RECT* rect);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ static long __fastcall op_metarule3_ext(long metafunc, long* args) {
|
|||||||
} else {
|
} else {
|
||||||
if (argValue > 127) argValue = 127;
|
if (argValue > 127) argValue = 127;
|
||||||
SafeWrite8(HorriganEncounterDays, static_cast<BYTE>(argValue));
|
SafeWrite8(HorriganEncounterDays, static_cast<BYTE>(argValue));
|
||||||
HorriganEncounterSetDays = static_cast<BYTE>(argValue);
|
HorriganEncounterSetDays = static_cast<signed char>(argValue);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ int __stdcall LoadShader(const char* file) {
|
|||||||
if (FAILED(shader.Effect->GetString(buf, &name))) break;
|
if (FAILED(shader.Effect->GetString(buf, &name))) break;
|
||||||
sprintf_s(buf, "%s\\art\\stex\\%s", fo::var::master_db_handle->path, name); // fo::var::patches
|
sprintf_s(buf, "%s\\art\\stex\\%s", fo::var::master_db_handle->path, name); // fo::var::patches
|
||||||
if (FAILED(D3DXCreateTextureFromFileA(d3d9Device, buf, &tex))) continue;
|
if (FAILED(D3DXCreateTextureFromFileA(d3d9Device, buf, &tex))) continue;
|
||||||
|
|
||||||
sprintf(buf, "tex%d", i);
|
sprintf(buf, "tex%d", i);
|
||||||
shader.Effect->SetTexture(buf, tex);
|
shader.Effect->SetTexture(buf, tex);
|
||||||
shaderTextures.push_back(tex);
|
shaderTextures.push_back(tex);
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ end:
|
|||||||
void __declspec(naked) op_get_shader_version() {
|
void __declspec(naked) op_get_shader_version() {
|
||||||
__asm {
|
__asm {
|
||||||
mov esi, ecx;
|
mov esi, ecx;
|
||||||
call GetShaderVersion;
|
call Graphics::GetShaderVersion;
|
||||||
mov edx, eax;
|
mov edx, eax;
|
||||||
mov eax, ebx;
|
mov eax, ebx;
|
||||||
_RET_VAL_INT;
|
_RET_VAL_INT;
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* sfall
|
||||||
|
* Copyright (C) 2008-2020 The sfall team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "..\..\main.h"
|
||||||
|
#include "..\..\FalloutEngine\Fallout2.h"
|
||||||
|
#include "..\Graphics.h"
|
||||||
|
|
||||||
|
#include "GameRender.h"
|
||||||
|
|
||||||
|
namespace sfall
|
||||||
|
{
|
||||||
|
|
||||||
|
static BYTE* GetBuffer() {
|
||||||
|
return (BYTE*)*(DWORD*)FO_VAR_screen_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __fastcall sf_GNW_win_refresh(fo::Window* win, RECT* updateRect, BYTE* toBuffer) {
|
||||||
|
if (win->flags & fo::WinFlags::Hidden) return;
|
||||||
|
fo::RectList* rects;
|
||||||
|
|
||||||
|
if (win->flags & fo::WinFlags::Transparent && !*(DWORD*)FO_VAR_doing_refresh_all) {
|
||||||
|
__asm {
|
||||||
|
mov eax, updateRect;
|
||||||
|
mov edx, ds:[FO_VAR_screen_buffer];
|
||||||
|
call fo::funcoffs::refresh_all_;
|
||||||
|
}
|
||||||
|
int w = updateRect->right - updateRect->left + 1;
|
||||||
|
|
||||||
|
if (fo::var::mouse_is_hidden || !fo::func::mouse_in(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) {
|
||||||
|
/*__asm {
|
||||||
|
mov eax, win;
|
||||||
|
mov edx, updateRect;
|
||||||
|
call fo::funcoffs::GNW_button_refresh_;
|
||||||
|
}*/
|
||||||
|
int h = (updateRect->bottom - updateRect->top) + 1;
|
||||||
|
Graphics::UpdateDDSurface(GetBuffer(), w, h, w, updateRect); // update the entire rectangle area
|
||||||
|
} else {
|
||||||
|
fo::func::mouse_show(); // for updating background cursor area
|
||||||
|
RECT mouseRect;
|
||||||
|
__asm {
|
||||||
|
lea eax, mouseRect;
|
||||||
|
mov edx, eax;
|
||||||
|
call fo::funcoffs::mouse_get_rect_;
|
||||||
|
mov eax, updateRect;
|
||||||
|
call fo::funcoffs::rect_clip_;
|
||||||
|
mov rects, eax;
|
||||||
|
}
|
||||||
|
while (rects) { // updates everything except the cursor area
|
||||||
|
/*__asm {
|
||||||
|
mov eax, win;
|
||||||
|
mov edx, rects;
|
||||||
|
call fo::funcoffs::GNW_button_refresh_;
|
||||||
|
}*/
|
||||||
|
int wRect = (rects->wRect.right - rects->wRect.left) + 1;
|
||||||
|
int hRect = (rects->wRect.bottom - rects->wRect.top) + 1;
|
||||||
|
Graphics::UpdateDDSurface(&GetBuffer()[rects->wRect.left - updateRect->left] + (rects->wRect.top - updateRect->top) * w, wRect, hRect, w, &rects->wRect);
|
||||||
|
|
||||||
|
fo::RectList* next = rects->nextRect;
|
||||||
|
fo::sf_rect_free(rects);
|
||||||
|
rects = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocates memory for 10 RectList (if no memory was allocated), returns the first Rect and removes it from the list */
|
||||||
|
__asm call fo::funcoffs::rect_malloc_;
|
||||||
|
__asm mov rects, eax;
|
||||||
|
if (!rects) return;
|
||||||
|
|
||||||
|
rects->rect = { updateRect->left, updateRect->top, updateRect->right, updateRect->bottom };
|
||||||
|
rects->nextRect = nullptr;
|
||||||
|
RECT &rect = rects->wRect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
If the border of the updateRect rectangle is located outside the window, then assign to rects->rect the border of the window rectangle
|
||||||
|
Otherwise, rects->rect contains the borders from the update rectangle (updateRect)
|
||||||
|
*/
|
||||||
|
if (win->wRect.left >= rect.left) rect.left = win->wRect.left;
|
||||||
|
if (win->wRect.top >= rect.top) rect.top = win->wRect.top;
|
||||||
|
if (win->wRect.right <= rect.right) rect.right = win->wRect.right;
|
||||||
|
if (win->wRect.bottom <= rect.bottom) rect.bottom = win->wRect.bottom;
|
||||||
|
|
||||||
|
if (rect.right < rect.left || rect.bottom < rect.top) {
|
||||||
|
fo::sf_rect_free(rects);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int widthFrom = win->width;
|
||||||
|
int toWidth = (toBuffer) ? updateRect->right - updateRect->left + 1 : Graphics::GetGameWidthRes();
|
||||||
|
|
||||||
|
fo::func::win_clip(win, &rects, toBuffer);
|
||||||
|
|
||||||
|
fo::RectList* currRect = rects;
|
||||||
|
while (currRect) {
|
||||||
|
RECT &crect = currRect->wRect;
|
||||||
|
int width = (crect.right - crect.left) + 1; // for current rectangle
|
||||||
|
int height = (crect.bottom - crect.top) + 1;; // for current rectangle
|
||||||
|
|
||||||
|
BYTE* surface;
|
||||||
|
if (win->wID) {
|
||||||
|
__asm {
|
||||||
|
mov eax, win;
|
||||||
|
mov edx, currRect;
|
||||||
|
call fo::funcoffs::GNW_button_refresh_;
|
||||||
|
}
|
||||||
|
surface = &win->surface[crect.left - win->rect.x] + ((crect.top - win->rect.y) * win->width);
|
||||||
|
} else {
|
||||||
|
surface = new BYTE[height * width](); // black background
|
||||||
|
widthFrom = width; // replace with rectangle
|
||||||
|
}
|
||||||
|
|
||||||
|
auto drawFunc = (win->flags & fo::WinFlags::Transparent && win->wID) ? fo::func::trans_buf_to_buf : fo::func::buf_to_buf;
|
||||||
|
if (toBuffer) {
|
||||||
|
drawFunc(surface, width, height, widthFrom, &toBuffer[crect.left - updateRect->left] + ((crect.top - updateRect->top) * toWidth), toWidth);
|
||||||
|
} else {
|
||||||
|
// copy to buffer instead of DD surface (buffering)
|
||||||
|
drawFunc(surface, width, height, widthFrom, &GetBuffer()[crect.left] + (crect.top * toWidth), toWidth);
|
||||||
|
//Graphics::UpdateDDSurface(surface, width, height, widthFrom, crect);
|
||||||
|
}
|
||||||
|
if (win->wID == 0) delete[] surface;
|
||||||
|
|
||||||
|
currRect = currRect->nextRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (rects) {
|
||||||
|
// copy all rectangles from the buffer to the DD surface (buffering)
|
||||||
|
if (!toBuffer) {
|
||||||
|
int width = (rects->rect.offx - rects->rect.x) + 1;
|
||||||
|
int height = (rects->rect.offy - rects->rect.y) + 1;
|
||||||
|
int widthFrom = toWidth;
|
||||||
|
Graphics::UpdateDDSurface(&GetBuffer()[rects->rect.x] + (rects->rect.y * widthFrom), width, height, widthFrom, &rects->wRect);
|
||||||
|
}
|
||||||
|
fo::RectList* next = rects->nextRect;
|
||||||
|
fo::sf_rect_free(rects);
|
||||||
|
rects = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!toBuffer && !*(DWORD*)FO_VAR_doing_refresh_all && !fo::var::mouse_is_hidden && fo::func::mouse_in(updateRect->left, updateRect->top, updateRect->right, updateRect->bottom)) {
|
||||||
|
fo::func::mouse_show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static __declspec(naked) void GNW_win_refresh_hack() {
|
||||||
|
__asm {
|
||||||
|
push ebx; // toBuffer
|
||||||
|
mov ecx, eax;
|
||||||
|
call sf_GNW_win_refresh;
|
||||||
|
pop ecx;
|
||||||
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static double fadeMulti;
|
||||||
|
|
||||||
|
static __declspec(naked) void palette_fade_to_hook() {
|
||||||
|
__asm {
|
||||||
|
push ebx; // _fade_steps
|
||||||
|
fild [esp];
|
||||||
|
fmul fadeMulti;
|
||||||
|
fistp [esp];
|
||||||
|
pop ebx;
|
||||||
|
jmp fo::funcoffs::fadeSystemPalette_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameRender::init() {
|
||||||
|
fadeMulti = GetConfigInt("Graphics", "FadeMultiplier", 100);
|
||||||
|
if (fadeMulti != 100) {
|
||||||
|
dlog("Applying fade patch.", DL_INIT);
|
||||||
|
HookCall(0x493B16, palette_fade_to_hook);
|
||||||
|
fadeMulti = ((double)fadeMulti) / 100.0;
|
||||||
|
dlogr(" Done", DL_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the srcCopy_ function with a pure MMX implementation
|
||||||
|
MakeJump(0x4D36D4, fo::func::buf_to_buf); // buf_to_buf_
|
||||||
|
// Replace the transSrcCopy_ function
|
||||||
|
MakeJump(0x4D3704, fo::func::trans_buf_to_buf); // trans_buf_to_buf_
|
||||||
|
|
||||||
|
// Enable support for transparent interface windows
|
||||||
|
SafeWrite16(0x4D5D46, 0x9090); // win_init_ (create screen_buffer)
|
||||||
|
SafeWrite8(0x42F869, fo::WinFlags::MoveOnTop | fo::WinFlags::OwnerFlag); // addWindow_ (remove Transparent flag)
|
||||||
|
if (Graphics::mode) {
|
||||||
|
// custom implementation of the GNW_win_refresh function
|
||||||
|
MakeJump(0x4D6FD9, GNW_win_refresh_hack, 1);
|
||||||
|
SafeWrite16(0x4D75E6, 0x9090); // win_clip_ (remove _buffering checking)
|
||||||
|
} else { // for default or HRP graphics mode
|
||||||
|
SafeWrite8(0x4D5DAB, 0x1D); // ecx > ebx (enable _buffering)
|
||||||
|
BlockCall(0x431076); // dialogMessage_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* sfall
|
||||||
|
* Copyright (C) 2008-2020 The sfall team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace sfall
|
||||||
|
{
|
||||||
|
|
||||||
|
class GameRender {
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -317,6 +317,7 @@
|
|||||||
<ClInclude Include="Modules\Scripting\Handlers\Math.h" />
|
<ClInclude Include="Modules\Scripting\Handlers\Math.h" />
|
||||||
<ClInclude Include="Modules\SpeedPatch.h" />
|
<ClInclude Include="Modules\SpeedPatch.h" />
|
||||||
<ClInclude Include="Modules\SubModules\CombatBlock.h" />
|
<ClInclude Include="Modules\SubModules\CombatBlock.h" />
|
||||||
|
<ClInclude Include="Modules\SubModules\GameRender.h" />
|
||||||
<ClInclude Include="Modules\Worldmap.h" />
|
<ClInclude Include="Modules\Worldmap.h" />
|
||||||
<ClInclude Include="Modules\ScriptExtender.h" />
|
<ClInclude Include="Modules\ScriptExtender.h" />
|
||||||
<ClInclude Include="Modules\BarBoxes.h" />
|
<ClInclude Include="Modules\BarBoxes.h" />
|
||||||
@@ -412,6 +413,7 @@
|
|||||||
<ClCompile Include="Modules\Scripting\Handlers\Math.cpp" />
|
<ClCompile Include="Modules\Scripting\Handlers\Math.cpp" />
|
||||||
<ClCompile Include="Modules\SpeedPatch.cpp" />
|
<ClCompile Include="Modules\SpeedPatch.cpp" />
|
||||||
<ClCompile Include="Modules\SubModules\CombatBlock.cpp" />
|
<ClCompile Include="Modules\SubModules\CombatBlock.cpp" />
|
||||||
|
<ClCompile Include="Modules\SubModules\GameRender.cpp" />
|
||||||
<ClCompile Include="Modules\Worldmap.cpp" />
|
<ClCompile Include="Modules\Worldmap.cpp" />
|
||||||
<ClCompile Include="Modules\ScriptExtender.cpp" />
|
<ClCompile Include="Modules\ScriptExtender.cpp" />
|
||||||
<ClCompile Include="Modules\BarBoxes.cpp" />
|
<ClCompile Include="Modules\BarBoxes.cpp" />
|
||||||
|
|||||||
@@ -301,6 +301,9 @@
|
|||||||
<ClInclude Include="Modules\MetaruleExtender.h">
|
<ClInclude Include="Modules\MetaruleExtender.h">
|
||||||
<Filter>Modules</Filter>
|
<Filter>Modules</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Modules\SubModules\GameRender.h">
|
||||||
|
<Filter>Modules\SubModules</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
@@ -556,6 +559,9 @@
|
|||||||
<ClCompile Include="Modules\MetaruleExtender.cpp">
|
<ClCompile Include="Modules\MetaruleExtender.cpp">
|
||||||
<Filter>Modules</Filter>
|
<Filter>Modules</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Modules\SubModules\GameRender.cpp">
|
||||||
|
<Filter>Modules\SubModules</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="version.rc" />
|
<ResourceCompile Include="version.rc" />
|
||||||
|
|||||||
Reference in New Issue
Block a user