Improved the rendering performance of DX9 modes

Excluded the animated colors from TravelMarkerColor (same as in 3.8.x)
Code edits and preparation.
This commit is contained in:
NovaRain
2021-10-01 12:25:18 +08:00
parent dbe24d3ebd
commit edbfc055d0
17 changed files with 259 additions and 109 deletions
+3 -1
View File
@@ -1,5 +1,7 @@
; This file lets you configure the requirements and effects of unarmed attacks ; This file lets you configure the requirements and effects of unarmed attacks
; You can leave the value empty or omit the parameter to use the engine default value
; Strong Punch ; Strong Punch
[8] [8]
ReqLevel=1 ; required player level ReqLevel=1 ; required player level
@@ -18,7 +20,7 @@ MinDamage=1
MaxDamage=2 MaxDamage=2
BonusDamage=3 ; bonus damage added to the minimum and maximum damage BonusDamage=3 ; bonus damage added to the minimum and maximum damage
BonusCrit=0 ; value of the critical hit chance BonusCrit=0 ; value of the critical hit chance
APCost= ; you can leave the value empty or omit the parameter to use the engine default value APCost=
Penetrate=0 ; set to 1 to make the attack reduce target's armor DT (the formula is determined by the engine or a hook script) Penetrate=0 ; set to 1 to make the attack reduce target's armor DT (the formula is determined by the engine or a hook script)
Secondary=0 ; set to 1 to assign the attack to the secondary mode (be careful when setting this parameter) Secondary=0 ; set to 1 to assign the attack to the secondary mode (be careful when setting this parameter)
+1 -1
View File
@@ -113,7 +113,7 @@ ExpandWorldMap=0
;Set to 1 to draw a dotted line while traveling on the world map (similar to Fallout 1) ;Set to 1 to draw a dotted line while traveling on the world map (similar to Fallout 1)
WorldMapTravelMarkers=0 WorldMapTravelMarkers=0
;Uncomment these lines to change the appearance of the markers ;Uncomment these lines to change the appearance of the markers
;The color index in Fallout default palette (valid range: 1..255; default is 134) ;The color index in Fallout default palette (valid range: 1..228; default is 134)
;TravelMarkerColor=134 ;TravelMarkerColor=134
;The length and spacing of the dots in pixels for each type of terrain in worldmap.txt ;The length and spacing of the dots in pixels for each type of terrain in worldmap.txt
;Syntax is 'length:spacing', with each pair separated by a comma (valid range: 1..10; default is 2) ;Syntax is 'length:spacing', with each pair separated by a comma (valid range: 1..10; default is 2)
+1
View File
@@ -235,6 +235,7 @@ WRAP_WATCOM_FUNC1(void, scr_build_lookup_table, fo::ScriptInstance*, script)
WRAP_WATCOM_FUNC1(fo::ScriptInstance*, scr_find_first_at, long, elevation) WRAP_WATCOM_FUNC1(fo::ScriptInstance*, scr_find_first_at, long, elevation)
WRAP_WATCOM_FUNC0(fo::ScriptInstance*, scr_find_next_at) WRAP_WATCOM_FUNC0(fo::ScriptInstance*, scr_find_next_at)
WRAP_WATCOM_FUNC1(fo::GameObject*, scr_find_obj_from_program, fo::Program*, program) WRAP_WATCOM_FUNC1(fo::GameObject*, scr_find_obj_from_program, fo::Program*, program)
WRAP_WATCOM_FUNC1(long, scr_find_sid_from_program, fo::Program*, program)
WRAP_WATCOM_FUNC2(long, scr_new, long*, scriptID, long, sType) WRAP_WATCOM_FUNC2(long, scr_new, long*, scriptID, long, sType)
// Saves pointer to script object into scriptPtr using scriptID // Saves pointer to script object into scriptPtr using scriptID
WRAP_WATCOM_FUNC2(long, scr_ptr, long, scriptId, fo::ScriptInstance**, scriptPtr) // Returns 0 on success, -1 on failure WRAP_WATCOM_FUNC2(long, scr_ptr, long, scriptId, fo::ScriptInstance**, scriptPtr) // Returns 0 on success, -1 on failure
+5 -5
View File
@@ -230,7 +230,7 @@ struct GameObject {
long lightDistance; long lightDistance;
long lightIntensity; long lightIntensity;
DWORD outline; DWORD outline;
long scriptId; // SID 0x0Y00XXXX: Y - type: 0=s_system, 1=s_spatial, 2=s_time, 3=s_item, 4=s_critter; XXXX - index in scripts.lst; 0xFFFFFFFF no attached script long scriptId; // SID 0x0Y00XXXX: Y - type: 0=s_system, 1=s_spatial, 2=s_time, 3=s_item, 4=s_critter; XXXX - ID number (1-32000); 0xFFFFFFFF no attached script
GameObject* owner; // not saved GameObject* owner; // not saved
long scriptIndex; long scriptIndex;
@@ -295,12 +295,12 @@ struct CombatGcsd {
// Script instance attached to an object or tile (spatial script). // Script instance attached to an object or tile (spatial script).
struct ScriptInstance { struct ScriptInstance {
long id; long id; // same as sid
long next; long next;
long elevationAndTile; // first 3 bits - elevation, rest - tile number long elevationAndTile; // first 3 bits - elevation, rest - tile number
long spatialRadius; long spatialRadius;
long flags; long flags;
long scriptIdx; long scriptIdx; // script index in scripts.lst?
Program *program; Program *program;
long ownerObjectId; long ownerObjectId;
long localVarOffset; // data long localVarOffset; // data
@@ -313,9 +313,9 @@ struct ScriptInstance {
GameObject *targetObject; GameObject *targetObject;
long actionNum; long actionNum;
long scriptOverrides; long scriptOverrides;
long field_48; long field_48; // unknown
long howMuch; long howMuch;
long field_50; long field_50; // unused
long procedureTable[28]; long procedureTable[28];
long gap[7]; long gap[7];
}; };
+2
View File
@@ -193,7 +193,9 @@
#define FO_VAR_movie_list 0x518DA0 #define FO_VAR_movie_list 0x518DA0
#define FO_VAR_Mutate_ 0x5708B4 #define FO_VAR_Mutate_ 0x5708B4
#define FO_VAR_name_color 0x56D744 #define FO_VAR_name_color 0x56D744
#define FO_VAR_name_critter 0x51833C
#define FO_VAR_name_font 0x56D74C #define FO_VAR_name_font 0x56D74C
#define FO_VAR_name_item 0x519238
#define FO_VAR_name_sort_list 0x56FCB0 #define FO_VAR_name_sort_list 0x56FCB0
#define FO_VAR_num_caps 0x518060 #define FO_VAR_num_caps 0x518060
#define FO_VAR_num_game_global_vars 0x5186C4 #define FO_VAR_num_game_global_vars 0x5186C4
+2 -2
View File
@@ -284,7 +284,7 @@ void DamageMod::DamageYAAM(fo::ComputeAttackResult &ctd, DWORD &accumulatedDamag
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Display melee damage w/o perk bonus // Display melee damage w/o PERK_bonus_hth_damage bonus
static __declspec(naked) void MeleeDmgDisplayPrintFix_hook() { static __declspec(naked) void MeleeDmgDisplayPrintFix_hook() {
using namespace fo; using namespace fo;
__asm { __asm {
@@ -304,7 +304,7 @@ static __declspec(naked) void MeleeDmgDisplayPrintFix_hook() {
} }
} }
// Display max melee damage w/o perk bonus // Display max melee damage w/o PERK_bonus_hth_damage bonus
static __declspec(naked) void CommonDmgRngDispFix_hook() { static __declspec(naked) void CommonDmgRngDispFix_hook() {
using namespace fo; using namespace fo;
__asm { __asm {
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -29,7 +29,7 @@ namespace sfall
extern IDirect3D9* d3d9; extern IDirect3D9* d3d9;
extern IDirect3DDevice9* d3d9Device; extern IDirect3DDevice9* d3d9Device;
extern IDirectDrawSurface* primaryDDSurface; extern IDirectDrawSurface* primarySurface;
extern bool DeviceLost; extern bool DeviceLost;
/* /*
@@ -106,12 +106,12 @@ public:
DDSURFACEDESC desc; DDSURFACEDESC desc;
RECT lockRect = { x, y, rect->right + 1, rect->bottom + 1 }; RECT lockRect = { x, y, rect->right + 1, rect->bottom + 1 };
if (primaryDDSurface->Lock(&lockRect, &desc, 0, 0)) return; // lock error if (primarySurface->Lock(&lockRect, &desc, 0, 0)) return; // lock error
if (Graphics::GPUBlt == 0) desc.lpSurface = (BYTE*)desc.lpSurface + (desc.lPitch * y) + x; if (Graphics::GPUBlt == 0) desc.lpSurface = (BYTE*)desc.lpSurface + (desc.lPitch * y) + x;
fo::func::buf_to_buf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch); fo::func::buf_to_buf(surface, width, height, widthFrom, (BYTE*)desc.lpSurface, desc.lPitch);
primaryDDSurface->Unlock(desc.lpSurface); primarySurface->Unlock(desc.lpSurface);
} }
} }
}; };
@@ -137,7 +137,7 @@ static const char* gpuEffectA8 =
"if (abs(backdrop - 1.0) < 0.001) {" // (48.0 / 255.0) // 48 - key index color "if (abs(backdrop - 1.0) < 0.001) {" // (48.0 / 255.0) // 48 - key index color
"result = tex2D(s2, saturate((Tex - corner) / size));" "result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {" "} else {"
"result = tex1D(s1, backdrop).bgr;" // get color in palette and swap R <> B "result = tex1D(s1, backdrop);" // get color in palette
"}" "}"
// blend highlights // blend highlights
"if (showhl) {" "if (showhl) {"
@@ -154,7 +154,7 @@ static const char* gpuEffectA8 =
// main shader // main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {" "float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float3 result = tex1D(s1, tex2D(s0, Tex).a);" // get color in palette "float3 result = tex1D(s1, tex2D(s0, Tex).a);" // get color in palette
"return float4(result.bgr, 1);" // swap R <> B "return float4(result, 1);"
"}" "}"
"technique T0" "technique T0"
"{" "{"
@@ -182,7 +182,7 @@ static const char* gpuEffectL8 =
"if (abs(backdrop - 1.0) < 0.001) {" "if (abs(backdrop - 1.0) < 0.001) {"
"result = tex2D(s2, saturate((Tex - corner) / size));" "result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {" "} else {"
"result = tex1D(s1, backdrop).bgr;" "result = tex1D(s1, backdrop);"
"}" "}"
// blend highlights // blend highlights
"if (showhl) {" "if (showhl) {"
@@ -199,7 +199,7 @@ static const char* gpuEffectL8 =
// main shader // main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {" "float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float3 result = tex1D(s1, tex2D(s0, Tex).r);" "float3 result = tex1D(s1, tex2D(s0, Tex).r);"
"return float4(result.bgr, 1);" "return float4(result, 1);"
"}" "}"
"technique T0" "technique T0"
"{" "{"
+1 -3
View File
@@ -796,8 +796,6 @@ static void __declspec(naked) wmInterfaceInit_hook() {
} }
static void WorldMapInterfacePatch() { static void WorldMapInterfacePatch() {
BlockCall(0x4C2380); // Remove disabling palette animations (can be used as a place to call a hack function in wmInterfaceInit_)
if (IniReader::GetConfigInt("Misc", "WorldMapFontPatch", 0)) { if (IniReader::GetConfigInt("Misc", "WorldMapFontPatch", 0)) {
dlog("Applying world map font patch.", DL_INIT); dlog("Applying world map font patch.", DL_INIT);
HookCall(0x4C2343, wmInterfaceInit_text_font_hook); HookCall(0x4C2343, wmInterfaceInit_text_font_hook);
@@ -846,7 +844,7 @@ static void WorldMapInterfacePatch() {
dlog("Applying world map travel markers patch.", DL_INIT); dlog("Applying world map travel markers patch.", DL_INIT);
int color = IniReader::GetConfigInt("Interface", "TravelMarkerColor", 134); // color index in palette: R = 224, G = 0, B = 0 int color = IniReader::GetConfigInt("Interface", "TravelMarkerColor", 134); // color index in palette: R = 224, G = 0, B = 0
if (color > 255) color = 255; else if (color < 1) color = 1; if (color > 228) color = 228; else if (color < 1) color = 1; // no palette animation colors
colorDot = color; colorDot = color;
auto dotList = IniReader::GetConfigList("Interface", "TravelMarkerStyles", "", 512); auto dotList = IniReader::GetConfigList("Interface", "TravelMarkerStyles", "", 512);
+1 -1
View File
@@ -228,7 +228,7 @@ static void __fastcall SwapHandSlots(fo::GameObject* item, fo::GameObject* &toSl
fo::ItemButtonItem* leftSlot = &fo::var::itemButtonItems[fo::HandSlot::Left]; fo::ItemButtonItem* leftSlot = &fo::var::itemButtonItems[fo::HandSlot::Left];
fo::ItemButtonItem* rightSlot = &fo::var::itemButtonItems[fo::HandSlot::Right]; fo::ItemButtonItem* rightSlot = &fo::var::itemButtonItems[fo::HandSlot::Right];
if (toSlot == nullptr) { // copy to slot if (toSlot == nullptr) { // copy to empty slot
fo::ItemButtonItem* dstSlot; fo::ItemButtonItem* dstSlot;
fo::ItemButtonItem item; fo::ItemButtonItem item;
if ((int)&toSlot == FO_VAR_i_lhand) { if ((int)&toSlot == FO_VAR_i_lhand) {
+5 -1
View File
@@ -31,6 +31,10 @@ static int maxCountLoadProto = 512;
long Objects::uniqueID = UniqueID::Start; // current counter id, saving to sfallgv.sav long Objects::uniqueID = UniqueID::Start; // current counter id, saving to sfallgv.sav
bool Objects::IsUniqueID(long id) {
return (id > UniqueID::Start || (id >= fo::PLAYER_ID && id < 83536)); // 65535 maximum possible number of prototypes
}
static void SetScriptObjectID(fo::GameObject* obj) { static void SetScriptObjectID(fo::GameObject* obj) {
fo::ScriptInstance* script; fo::ScriptInstance* script;
if (fo::func::scr_ptr(obj->scriptId, &script) != -1) { if (fo::func::scr_ptr(obj->scriptId, &script) != -1) {
@@ -43,7 +47,7 @@ static void SetScriptObjectID(fo::GameObject* obj) {
// player ID = 18000, all party members have ID = 18000 + its pid (file number of prototype) // player ID = 18000, all party members have ID = 18000 + its pid (file number of prototype)
long __fastcall Objects::SetObjectUniqueID(fo::GameObject* obj) { long __fastcall Objects::SetObjectUniqueID(fo::GameObject* obj) {
long id = obj->id; long id = obj->id;
if (id > UniqueID::Start || (id >= fo::PLAYER_ID && id < 83536)) return id; // 65535 maximum possible number of prototypes if (IsUniqueID(id)) return id;
if ((DWORD)uniqueID >= (DWORD)UniqueID::End) uniqueID = UniqueID::Start; if ((DWORD)uniqueID >= (DWORD)UniqueID::End) uniqueID = UniqueID::Start;
obj->id = ++uniqueID; obj->id = ++uniqueID;
+2
View File
@@ -17,6 +17,8 @@ public:
static long uniqueID; static long uniqueID;
static bool IsUniqueID(long id);
static long __fastcall SetObjectUniqueID(fo::GameObject* obj); static long __fastcall SetObjectUniqueID(fo::GameObject* obj);
static long __fastcall SetSpecialID(fo::GameObject* obj); static long __fastcall SetSpecialID(fo::GameObject* obj);
static void SetNewEngineID(fo::GameObject* obj); static void SetNewEngineID(fo::GameObject* obj);
+1 -1
View File
@@ -1007,7 +1007,7 @@ void ScriptExtender::init() {
MakeCall(0x423DEB, (void*)fo::funcoffs::compute_damage_); MakeCall(0x423DEB, (void*)fo::funcoffs::compute_damage_);
} }
InitNewOpcodes(); Opcodes::InitNew();
ScriptExtender::OnMapExit() += ClearEventsOnMapExit; // for reordering the execution of functions before exiting the map ScriptExtender::OnMapExit() += ClearEventsOnMapExit; // for reordering the execution of functions before exiting the map
} }
+8 -10
View File
@@ -151,24 +151,22 @@ struct ListId {
static std::vector<ListId> mList; static std::vector<ListId> mList;
static void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) { static void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) {
if (type == 4) return; // LIST_TILES
vec.reserve(100); vec.reserve(100);
if (type == 6) { if (type == 6) { // LIST_SPATIAL
fo::ScriptInstance* scriptPtr;
fo::GameObject* self_obj;
fo::Program* programPtr;
for (int elev = 0; elev <= 2; elev++) { for (int elev = 0; elev <= 2; elev++) {
scriptPtr = fo::func::scr_find_first_at(elev); fo::ScriptInstance* scriptPtr = fo::func::scr_find_first_at(elev);
while (scriptPtr != nullptr) { while (scriptPtr != nullptr) {
self_obj = scriptPtr->selfObject; fo::GameObject* self_obj = scriptPtr->selfObject;
if (self_obj == nullptr) { if (self_obj == nullptr) {
programPtr = scriptPtr->program; self_obj = fo::func::scr_find_obj_from_program(scriptPtr->program);
self_obj = fo::func::scr_find_obj_from_program(programPtr);
} }
vec.push_back(self_obj); vec.push_back(self_obj);
scriptPtr = fo::func::scr_find_next_at(); scriptPtr = fo::func::scr_find_next_at();
} }
} }
/*} else if (type == 4) { /*} else if (type == 4) { // LIST_TILES
// TODO: verify code correctness // TODO: verify code correctness
for(int elv=0;elv<2;elv++) { for(int elv=0;elv<2;elv++) {
DWORD* esquares = &fo::var::squares[elv]; DWORD* esquares = &fo::var::squares[elv];
@@ -176,7 +174,7 @@ static void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) {
esquares[tile]=0x8f000002; esquares[tile]=0x8f000002;
} }
}*/ }*/
} else if (type != 4) { } else {
for (int elv = 0; elv < 3; elv++) { for (int elv = 0; elv < 3; elv++) {
for (int tile = 0; tile < 40000; tile++) { for (int tile = 0; tile < 40000; tile++) {
fo::GameObject* obj = fo::func::obj_find_first_at_tile(elv, tile); fo::GameObject* obj = fo::func::obj_find_first_at_tile(elv, tile);
+1 -1
View File
@@ -270,7 +270,7 @@ static void __fastcall defaultOpcodeHandler(fo::Program* program, DWORD opcodeOf
__asm pop ecx; __asm pop ecx;
} }
void InitNewOpcodes() { void Opcodes::InitNew() {
dlogr("Adding additional opcodes", DL_SCRIPT); dlogr("Adding additional opcodes", DL_SCRIPT);
SafeWrite32(0x46E370, opcodeCount); // Maximum number of allowed opcodes SafeWrite32(0x46E370, opcodeCount); // Maximum number of allowed opcodes
+4 -1
View File
@@ -25,7 +25,10 @@ namespace sfall
namespace script namespace script
{ {
void InitNewOpcodes(); class Opcodes {
public:
static void InitNew();
};
} }
} }
+3 -3
View File
@@ -442,10 +442,10 @@ void Unarmed::init() {
if (val >= 0) hit.reqSkill = val; if (val >= 0) hit.reqSkill = val;
val = IniReader::GetInt(sHit, "MinDamage", -1, file); val = IniReader::GetInt(sHit, "MinDamage", -1, file);
if (val >= 0) hit.minDamage = val; if (val > 0) hit.minDamage = val;
val = IniReader::GetInt(sHit, "MaxDamage", -1, file); val = IniReader::GetInt(sHit, "MaxDamage", -1, file);
if (val >= 0) hit.maxDamage = val; if (val > 0) hit.maxDamage = val;
val = IniReader::GetInt(sHit, "BonusDamage", -1, file); val = IniReader::GetInt(sHit, "BonusDamage", -1, file);
if (val >= 0) hit.bonusDamage = val; if (val >= 0) hit.bonusDamage = val;
@@ -454,7 +454,7 @@ void Unarmed::init() {
if (val >= 0) hit.bonusCrit = val; if (val >= 0) hit.bonusCrit = val;
val = IniReader::GetInt(sHit, "APCost", -1, file); val = IniReader::GetInt(sHit, "APCost", -1, file);
if (val >= 0) hit.apCost = val; if (val > 0) hit.apCost = val;
val = IniReader::GetInt(sHit, "Penetrate", -1, file); val = IniReader::GetInt(sHit, "Penetrate", -1, file);
if (val >= 0) hit.isPenetrate = (val != 0); if (val >= 0) hit.isPenetrate = (val != 0);