Updated global.fx and withinperception example script

Fixed some code.
This commit is contained in:
NovaRain
2020-08-19 15:19:11 +08:00
parent e6d30d7def
commit 19df2f9eec
8 changed files with 250 additions and 111 deletions
+211 -77
View File
@@ -1,4 +1,23 @@
// Status: WIP ///////////////////////////////////////////////////////////////////////////////
// Blur filter setting
//
// min: blurFalloff 8, sharpness 10/8
// mid: blurFalloff 6, sharpness 8
// max: blurFalloff 4, sharpness 6
///////////////////////////////////////////////////////////////////////////////
#define blurFalloff 4.0
#define sharpness 6.0
///////////////////////////////////////////////////////////////////////////////
// Sharpen filter setting
//
// min: Sharpen 0.5, EdgeSharpen 1.0
// mid: Sharpen 1.0, EdgeSharpen -0.25
// max: Sharpen 1.75, EdgeSharpen -0.5 (1.5, -0.25)
///////////////////////////////////////////////////////////////////////////////
#define Sharpen 0.5
#define EdgeSharpen 1.0
texture bloomMap; texture bloomMap;
sampler s0; sampler s0;
@@ -12,6 +31,88 @@ sampler BloomSampler : samplerstate
AddressV = Clamp; AddressV = Clamp;
}; };
// Variables that set the width and height of the current game resolution from sfall
float w;
float h;
static const float2 resolution = float2(w, h);
static const float2 wPass = float2(1, 0);
static const float2 hPass = float2(0, 1);
float Brightness(float3 color)
{
return 0.299 * color.r + 0.587 * color.g + 0.114 * color.b;
}
float3 BlurFunction(float2 uv, float brightness, inout float totalWeight)
{
float3 pointColor = (tex2Dlod(s0, float4(uv, 0, 0)).rgb);
float diff = abs(brightness - Brightness(pointColor));
float weight = exp2((-0.25 * blurFalloff) - (diff * sharpness));
totalWeight += weight;
return pointColor * weight;
}
float4 BlurDeltaPassPS(float2 uv : TEXCOORD0, uniform float2 delta) : COLOR0
{
float3 sumColor = (tex2D(s0, uv).rgb);
float brightness = Brightness(sumColor);
delta *= (1 / resolution);
float totalWeight = 1;
float2 pointUV = uv + delta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - delta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
return float4((sumColor / totalWeight), 1);
}
static const float2 wDelta = float2(1, 0) * (1 / resolution);
static const float2 hDelta = float2(0, 1) * (1 / resolution);
float4 BlurPS(float4 color : COLOR0, float2 uv : TEXCOORD0) : COLOR0
{
float totalWeight = 1;
float3 sumColor = (tex2D(s0, uv).rgb);
float brightness = Brightness(sumColor);
float2 pointUV = uv + wDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - wDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv + hDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - hDelta;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
return float4((sumColor / totalWeight), 1);
}
///////////////////////////////////////////////////////////////////////////////
// Bloom effect setting
//
// min: BloomIntensity .8
// mid: BloomIntensity .85
// max: BloomIntensity .9
///////////////////////////////////////////////////////////////////////////////
#define BaseIntensity 1.2
#define BaseSaturation 1.0
#define BloomIntensity 0.8
#define BloomSaturation 0.35
#define BloomThreshold 0.35
#define BlurPower 0.002
// pseudo gauss blur // pseudo gauss blur
static const float2 offsets[12] = { static const float2 offsets[12] = {
-0.326212, -0.405805, -0.326212, -0.405805,
@@ -28,89 +129,122 @@ static const float2 offsets[12] = {
-0.791559, -0.597705, -0.791559, -0.597705,
}; };
float w; float4 AdjustSaturation(float4 color, float saturation)
float h; {
static const float2 resolution = float2(w, h);
// blur setting
static const float blurFalloff = 8;
static const float sharpness = 4;
float4 AdjustSaturation(float4 color, float saturation) {
float grey = dot(color, float3(0.3, 0.59, 0.11)); float grey = dot(color, float3(0.3, 0.59, 0.11));
return lerp(grey, color, saturation); return lerp(grey, color, saturation);
} }
float Brightness(float3 color) float4 BloomPS(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{ {
return color.r * color.g - 0.75 * color.b;
}
float3 BlurFunction(float2 uv, float brightness, inout float totalWeight)
{
float3 pointColor =(tex2Dlod(s0, float4(uv, 0, 0)).rgb);
float diff = abs(brightness - Brightness(pointColor));
float weight = exp2(-0.25 * blurFalloff - diff * sharpness);
totalWeight += weight;
return pointColor * weight;
}
float4 BlurPS(float2 uv : TEXCOORD0, uniform float2 delta) : COLOR0
{
float3 sumColor = (tex2D(s0, uv).rgb);
float totalWeight = 1;
float brightness = Brightness(sumColor);
delta *= (1 / resolution);
float radius = 1;
float2 pointUV = uv + delta * radius;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
pointUV = uv - delta * radius;
sumColor += BlurFunction(pointUV, brightness, totalWeight);
return float4((sumColor / totalWeight),1);
// return AdjustSaturation(Color, 0.5);
}
float4 BloomT(float2 texCoord : TEXCOORD0) : COLOR0 {
float4 c = tex2D(s0, texCoord);
float BloomThreshold = 0.2;
return saturate((c - BloomThreshold) / (1 - BloomThreshold));
}
float4 Bloom(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 {
float BaseIntensity = 1.0;
float BaseSaturation = 1;
float BloomIntensity = 1; // 0.4
float BloomSaturation = 0.5;
float BlurPower = 0.01;
float BloomThreshold = 0.5;
float4 original = tex2D(s0, texCoord); float4 original = tex2D(s0, texCoord);
// blur
float4 sum = tex2D(s0, texCoord);
for(int i = 0; i < 12; i++){
sum += tex2D(s0, texCoord + BlurPower * offsets[i]);
}
sum /= 13;
original = AdjustSaturation(original, BaseSaturation) * BaseIntensity; original = AdjustSaturation(original, BaseSaturation) * BaseIntensity;
sum = AdjustSaturation(sum, BloomSaturation) * BloomIntensity; float sum = (original.r + original.g + original.b) * 0.333;
if (sum >= 0.95) return original;
sum = saturate((sum - BloomThreshold) / (1 - BloomThreshold)); // bloom blur
float4 bloomBlur = tex2D(s0, texCoord);
return sum + original; for(int i = 0; i < 12; i++)
// return sum;
}
technique Blur
{ {
// pass P2 { PixelShader = compile ps_2_0 BloomT(); } bloomBlur += tex2D(s0, texCoord + BlurPower * offsets[i]);
// pass P3 { PixelShader = compile ps_2_0 Bloom(); } }
Pass P0 { PixelShader = compile ps_3_0 BlurPS(float2(1, 0)); } bloomBlur *= 0.085;
Pass P1 { PixelShader = compile ps_3_0 BlurPS(float2(0, 1)); }
float intensity = BloomIntensity - lerp(0.0, 0.2, sum);
bloomBlur = AdjustSaturation(bloomBlur, BloomSaturation) * intensity;
bloomBlur = saturate((bloomBlur - BloomThreshold) / (1 - BloomThreshold));
return bloomBlur + original;
}
static const float CoefBlur = (Sharpen * 0.5);
static const float CoefOrig = (1 + CoefBlur);
// for the sharpen edge
#define SharpenEdge 0.4
static const float sharpenVal0 = (Sharpen * (1.5 + EdgeSharpen));
static const float sharpenVal1 = ((sharpenVal0 - 1) / 8.0);
// pixel "width"
static const float px = (1.0 / w);
static const float py = (1.0 / h);
// for the blur filter
#define mean 1.0
static const float dx = (mean * px);
static const float dy = (mean * py);
float4 SharpenComplexPS(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
float4 c0 = tex2D(s0, texCoord); // get original pixel
// edge detection
// Get neighbor points
// [ c1, c2, c3 ]
// [ c4, c0, c5 ]
// [ c6, c7, c8 ]
float4 c1 = tex2D(s0, texCoord + float2(-px, -py));
float4 c2 = tex2D(s0, texCoord + float2( 0, -py));
float4 c3 = tex2D(s0, texCoord + float2( px, -py));
float4 c4 = tex2D(s0, texCoord + float2(-px, 0));
float4 c5 = tex2D(s0, texCoord + float2( px, 0));
float4 c6 = tex2D(s0, texCoord + float2(-px, py));
float4 c7 = tex2D(s0, texCoord + float2( 0, py));
float4 c8 = tex2D(s0, texCoord + float2( px, py));
// using Sobel filter
// horizontal gradient
// [ -1, 0, 1 ]
// [ -2, 0, 2 ]
// [ -1, 0, 1 ]
float delta1 = (c3 + 2 * c5 + c8) - (c1 + 2 * c4 + c6);
// vertical gradient
// [ -1, - 2, -1 ]
// [ 0, 0, 0 ]
// [ 1, 2, 1 ]
float4 c13 = c1 + c3;
float4 c68 = c6 + c8;
float delta2 = (c68 + 2 * c7) - (c13 + 2 * c2);
// computation
if (sqrt(mul(delta1, delta1) + mul(delta2, delta2)) > SharpenEdge) {
// if we have an edge, use sharpen
return c0 * sharpenVal0 - (c13 + c2 + c4 + c5 + c68 + c7) * sharpenVal1;
// Display edges in red...
//return float4( 1.0, 0.0, 0.0, 0.0 );
} else {
// else return corrected image
// compute blurred image (gaussian filter)
c1 = tex2D(s0, texCoord + float2(-dx, -dy));
c2 = tex2D(s0, texCoord + float2( 0, -dy));
c3 = tex2D(s0, texCoord + float2( dx, -dy));
c4 = tex2D(s0, texCoord + float2(-dx, 0));
c5 = tex2D(s0, texCoord + float2( dx, 0));
c6 = tex2D(s0, texCoord + float2(-dx, dy));
c7 = tex2D(s0, texCoord + float2( 0, dy));
c8 = tex2D(s0, texCoord + float2( dx, dy));
// gaussian filter
// [ 1, 2, 1 ]
// [ 2, 4, 2 ]
// [ 1, 2, 1 ]
// to normalize the values, we need to divide by the coeff sum
float4 flou = (c1 + c3 + c6 + c8 + 2 * (c2 + c4 + c5 + c7) + 4 * c0) * 0.0625; // 1 / (1+2+1+2+4+2+1+2+1) = 1 / 16 = 0.0625
// substract blurred image from original image
return (CoefOrig * c0 - CoefBlur * flou);
}
}
technique BlurBloom
{
//pass P0 { PixelShader = compile ps_3_0 BlurDeltaPassPS(wPass); }
//pass P1 { PixelShader = compile ps_3_0 BlurDeltaPassPS(hPass); }
pass P0 { PixelShader = compile ps_3_0 BlurPS(); }
pass P3 { PixelShader = compile ps_2_0 BloomPS(); }
pass P2 { PixelShader = compile ps_2_0 SharpenComplexPS(); }
} }
@@ -1,7 +1,5 @@
/* /*
Example implementation of the algorithm of how the game engine checks if one critter sees another critter. Example implementation of the algorithm of how the game engine checks if one critter sees another critter.
NOTE: the AllowUnsafeScripting option must be enabled.
*/ */
#include "..\headers\define.h" #include "..\headers\define.h"
@@ -9,10 +7,8 @@
#include "..\headers\sfall\sfall.h" #include "..\headers\sfall\sfall.h"
#include "..\headers\sfall\define_extra.h" #include "..\headers\sfall\define_extra.h"
#define can_see_(source, target) call_offset_r2(0x412BEC, source, target)
#define obj_dist_(target, source) call_offset_r2(0x48BBD4, target, source)
procedure start; procedure start;
procedure can_see(variable obj1, variable obj2);
procedure start begin procedure start begin
if game_loaded then begin if game_loaded then begin
@@ -21,40 +17,50 @@ procedure start begin
variable variable
source := get_sfall_arg, source := get_sfall_arg,
target := get_sfall_arg, target := get_sfall_arg,
original := get_sfall_arg, engine := get_sfall_arg,
hookType := get_sfall_arg, /* new arg */ type := get_sfall_arg, /* new arg */
result := 0, result := 0,
distance; distance, seeDistance, seeText;
if target then begin if target then begin
distance := get_critter_stat(source, STAT_pe); seeDistance := get_critter_stat(source, STAT_pe);
if can_see_(source, target) then begin if can_see(source, target) then begin
distance *= 5; seeDistance *= 5;
if (get_flags(target) bwand FLAG_TRANSGLASS) then distance /= 2; if (get_flags(target) bwand FLAG_TRANSGLASS) then seeDistance /= 2;
end else if combat_is_initialized then begin end else if combat_is_initialized then begin
distance *= 2; seeDistance *= 2;
end end
if (target == dude_obj) then begin if (target == dude_obj) then begin
if sneak_success then begin if sneak_success then begin
distance /= 4; seeDistance /= 4;
if has_skill(target, SKILL_SNEAK) > 120 then distance -= 1; if has_skill(target, SKILL_SNEAK) > 120 then seeDistance -= 1;
end else if dude_is_sneaking then begin end else if dude_is_sneaking then begin
distance := distance * 2 / 3; seeDistance := (seeDistance * 2) / 3; // distance div 1.5
end end
end end
if obj_dist_(target, source) <= distance then result := 1; distance := tile_distance_objs(source, target);
if (get_flags(source) bwand FLAG_MULTIHEX) then distance--;
if (get_flags(target) bwand FLAG_MULTIHEX) then distance--;
// example if (distance <= seeDistance) then result := 1;
if (result) then begin
display_msg("hs_withinperception: " + obj_name(source) + " sees " + obj_name(target) + " [original: " + original + " script: " + result + "]");
end else begin
display_msg("hs_withinperception: " + obj_name(source) + " does not see " + obj_name(target) + " [original: " + original + " script: " + result + "]");
end
end
seeText = " does not see > ";
if (result) then seeText = " sees > ";
// Example
display_msg("hs_withinperception: " + obj_name(source) + seeText + obj_name(target) + " [engine: " + engine + ", script: " + result + "]");
/* override engine result */
//set_sfall_return(result); //set_sfall_return(result);
end end
end end
end
procedure can_see(variable obj1, variable obj2) begin
variable dir = obj_get_rot(obj1) - rotation_to_tile(tile_num(obj1), tile_num(obj2));
if (dir < 0) then dir = -dir;
return (dir <= 1) or (dir == 5);
end
+3 -5
View File
@@ -114,16 +114,14 @@ DWORD __stdcall KeyDown(DWORD key) {
} }
key = key & 0xFFFF; key = key & 0xFFFF;
// combined use of DINPUT states + confirmation from GetAsyncKeyState() // combined use of DINPUT states + confirmation from GetAsyncKeyState()
if (key > MAX_KEYS) { if (key < MAX_KEYS) {
return 0;
} else {
DWORD keyVK = 0;
if (keysDown[key]) { // confirm pressed state if (keysDown[key]) { // confirm pressed state
keyVK = MapVirtualKeyEx(key, MAPVK_VSC_TO_VK, keyboardLayout); DWORD keyVK = MapVirtualKeyEx(key, MAPVK_VSC_TO_VK, keyboardLayout);
if (keyVK) keysDown[key] = (GetAsyncKeyState(keyVK) & 0x8000); if (keyVK) keysDown[key] = (GetAsyncKeyState(keyVK) & 0x8000);
} }
return (keysDown[key] > 0); return (keysDown[key] > 0);
} }
return 0;
} }
void __stdcall TapKey(DWORD key) { void __stdcall TapKey(DWORD key) {
+1 -1
View File
@@ -3548,7 +3548,7 @@ void BugFixes::init()
MakeCall(0x41094B, show_damage_to_object_hack, 1); MakeCall(0x41094B, show_damage_to_object_hack, 1);
MakeCall(0x48A6CB, obj_move_to_tile_hack_ondeath, 1); MakeCall(0x48A6CB, obj_move_to_tile_hack_ondeath, 1);
// Fix to limit the maximum distance for knockback animation // Fix to limit the maximum distance for the knockback animation
MakeCall(0x4104D5, action_knockback_hack); MakeCall(0x4104D5, action_knockback_hack);
} }
+2 -2
View File
@@ -69,7 +69,7 @@ DWORD InCombat();
DWORD InDialog(); DWORD InDialog();
enum LoopFlag : long { enum LoopFlag : unsigned long {
WORLDMAP = 1 << 0, // 0x1 WORLDMAP = 1 << 0, // 0x1
// RESERVED = 1 << 1, // 0x2 (unused) // RESERVED = 1 << 1, // 0x2 (unused)
DIALOG = 1 << 2, // 0x4 DIALOG = 1 << 2, // 0x4
@@ -92,7 +92,7 @@ enum LoopFlag : long {
DIALOGVIEW = 1 << 19, // 0x80000 DIALOGVIEW = 1 << 19, // 0x80000
COUNTERWIN = 1 << 20, // 0x100000 Counter window for moving multiple items or setting a timer COUNTERWIN = 1 << 20, // 0x100000 Counter window for moving multiple items or setting a timer
SPECIAL = 1 << 31 // 0x80000000 Additional special flag for all modes SPECIAL = 1UL << 31 // 0x80000000 Additional special flag for all modes
}; };
DWORD GetLoopFlags(); DWORD GetLoopFlags();
+3 -2
View File
@@ -805,10 +805,11 @@ void MiscPatches::init() {
HookCall(0x483726, map_check_state_hook); HookCall(0x483726, map_check_state_hook);
// Corrects the height of the black background for the subtitles on death screens // Corrects the height of the black background for the subtitles on death screens
if (hrpVersionValid) { if (hrpIsEnabled == false || hrpVersionValid) {
SafeWrite8(HRPAddress(0x10011738), 10); SafeWrite32(0x48134D, -602 - (640 * 2)); // main_death_scene_ (shift y-offset 2px up, w/o HRP)
SafeWrite8(0x481345, 4); // main_death_scene_ SafeWrite8(0x481345, 4); // main_death_scene_
} }
if (hrpVersionValid) SafeWrite8(HRPAddress(0x10011738), 10);
F1EngineBehaviorPatch(); F1EngineBehaviorPatch();
DialogueFix(); DialogueFix();
@@ -548,7 +548,7 @@ void mf_unwield_slot(OpcodeContext& ctx) {
} }
bool isDude = (critter == fo::var::obj_dude); bool isDude = (critter == fo::var::obj_dude);
bool update = false; bool update = false;
if (slot && (GetLoopFlags() && (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER)) == false) { if (slot && (GetLoopFlags() & (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER)) == false) {
if (fo::func::inven_unwield(critter, (slot == fo::INVEN_TYPE_LEFT_HAND) ? fo::Left : fo::Right) == 0) { if (fo::func::inven_unwield(critter, (slot == fo::INVEN_TYPE_LEFT_HAND) ? fo::Left : fo::Right) == 0) {
update = isDude; update = isDude;
} }
+1 -1
View File
@@ -199,7 +199,7 @@ void mf_string_compare(OpcodeContext& ctx) {
} }
// A safer version of sprintf for using in user scripts. // A safer version of sprintf for using in user scripts.
static char* sprintf_lite(const char* format, ScriptValue value) { static char* sprintf_lite(const char* format, const ScriptValue& value) {
int fmtlen = strlen(format); int fmtlen = strlen(format);
int buflen = fmtlen + 1; int buflen = fmtlen + 1;