Updated global.fx and withinperception example script

Fixed some code.
This commit is contained in:
NovaRain
2020-08-19 15:21:53 +08:00
parent 13976a5278
commit 502a5764a5
7 changed files with 249 additions and 110 deletions
+208 -74
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;
sampler s0;
@@ -12,6 +31,88 @@ sampler BloomSampler : samplerstate
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
static const float2 offsets[12] = {
-0.326212, -0.405805,
@@ -28,89 +129,122 @@ static const float2 offsets[12] = {
-0.791559, -0.597705,
};
float w;
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) {
float4 AdjustSaturation(float4 color, float saturation)
{
float grey = dot(color, float3(0.3, 0.59, 0.11));
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);
// 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;
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);
for(int i = 0; i < 12; i++)
{
bloomBlur += tex2D(s0, texCoord + BlurPower * offsets[i]);
}
bloomBlur *= 0.085;
return sum + original;
// return sum;
float intensity = BloomIntensity - lerp(0.0, 0.2, sum);
bloomBlur = AdjustSaturation(bloomBlur, BloomSaturation) * intensity;
bloomBlur = saturate((bloomBlur - BloomThreshold) / (1 - BloomThreshold));
return bloomBlur + original;
}
technique Blur
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
{
// pass P2 { PixelShader = compile ps_2_0 BloomT(); }
// pass P3 { PixelShader = compile ps_2_0 Bloom(); }
Pass P0 { PixelShader = compile ps_3_0 BlurPS(float2(1, 0)); }
Pass P1 { PixelShader = compile ps_3_0 BlurPS(float2(0, 1)); }
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.
NOTE: the AllowUnsafeScripting option must be enabled.
*/
#include "..\headers\define.h"
@@ -9,10 +7,8 @@
#include "..\headers\sfall\sfall.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 can_see(variable obj1, variable obj2);
procedure start begin
if game_loaded then begin
@@ -21,40 +17,50 @@ procedure start begin
variable
source := get_sfall_arg,
target := get_sfall_arg,
original := get_sfall_arg,
hookType := get_sfall_arg, /* new arg */
engine := get_sfall_arg,
type := get_sfall_arg, /* new arg */
result := 0,
distance;
distance, seeDistance, seeText;
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
distance *= 5;
if (get_flags(target) bwand FLAG_TRANSGLASS) then distance /= 2;
if can_see(source, target) then begin
seeDistance *= 5;
if (get_flags(target) bwand FLAG_TRANSGLASS) then seeDistance /= 2;
end else if combat_is_initialized then begin
distance *= 2;
seeDistance *= 2;
end
if (target == dude_obj) then begin
if sneak_success then begin
distance /= 4;
if has_skill(target, SKILL_SNEAK) > 120 then distance -= 1;
seeDistance /= 4;
if has_skill(target, SKILL_SNEAK) > 120 then seeDistance -= 1;
end else if dude_is_sneaking then begin
distance := distance * 2 / 3;
seeDistance := (seeDistance * 2) / 3; // distance div 1.5
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 (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
if (distance <= seeDistance) then result := 1;
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);
end
//set_sfall_return(result);
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
+1 -1
View File
@@ -3542,6 +3542,6 @@ void BugFixesInit()
MakeCall(0x41094B, show_damage_to_object_hack, 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);
}
+3 -5
View File
@@ -100,16 +100,14 @@ DWORD __stdcall KeyDown(DWORD key) {
}
key = key & 0xFFFF;
// combined use of DINPUT states + confirmation from GetAsyncKeyState()
if (key > MAX_KEYS) {
return 0;
} else {
DWORD keyVK = 0;
if (key < MAX_KEYS) {
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);
}
return (keysDown[key] > 0);
}
return 0;
}
void __stdcall TapKey(DWORD key) {
+2 -2
View File
@@ -27,7 +27,7 @@ DWORD InWorldMap();
DWORD InCombat();
DWORD InDialog();
enum LoopFlag : long {
enum LoopFlag : unsigned long {
WORLDMAP = 1 << 0, // 0x1
// RESERVED = 1 << 1, // 0x2 (unused)
DIALOG = 1 << 2, // 0x4
@@ -50,7 +50,7 @@ enum LoopFlag : long {
DIALOGVIEW = 1 << 19, // 0x80000
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();
+3 -2
View File
@@ -694,10 +694,11 @@ void MiscPatchesInit() {
HookCall(0x483726, map_check_state_hook);
// Corrects the height of the black background for the subtitles on death screens
if (hrpVersionValid) {
SafeWrite8(HRPAddress(0x10011738), 10);
if (hrpIsEnabled == false || hrpVersionValid) {
SafeWrite32(0x48134D, -602 - (640 * 2)); // main_death_scene_ (shift y-offset 2px up, w/o HRP)
SafeWrite8(0x481345, 4); // main_death_scene_
}
if (hrpVersionValid) SafeWrite8(HRPAddress(0x10011738), 10);
F1EngineBehaviorPatch();
DialogueFix();
+1 -1
View File
@@ -693,7 +693,7 @@ static void mf_unwield_slot() {
}
bool isDude = (critter == *ptr_obj_dude);
bool update = false;
if (slot && (GetLoopFlags() && (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER)) == false) {
if (slot && (GetLoopFlags() & (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER)) == false) {
if (InvenUnwield(critter, (slot == INVEN_TYPE_LEFT_HAND) ? 0 : 1) == 0) {
update = isDude;
}