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
; You can leave the value empty or omit the parameter to use the engine default value
; Strong Punch
[8]
ReqLevel=1 ; required player level
@@ -18,7 +20,7 @@ MinDamage=1
MaxDamage=2
BonusDamage=3 ; bonus damage added to the minimum and maximum damage
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)
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)
WorldMapTravelMarkers=0
;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
;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)
+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_FUNC0(fo::ScriptInstance*, scr_find_next_at)
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)
// 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
+5 -5
View File
@@ -230,7 +230,7 @@ struct GameObject {
long lightDistance;
long lightIntensity;
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
long scriptIndex;
@@ -295,12 +295,12 @@ struct CombatGcsd {
// Script instance attached to an object or tile (spatial script).
struct ScriptInstance {
long id;
long id; // same as sid
long next;
long elevationAndTile; // first 3 bits - elevation, rest - tile number
long spatialRadius;
long flags;
long scriptIdx;
long scriptIdx; // script index in scripts.lst?
Program *program;
long ownerObjectId;
long localVarOffset; // data
@@ -313,9 +313,9 @@ struct ScriptInstance {
GameObject *targetObject;
long actionNum;
long scriptOverrides;
long field_48;
long field_48; // unknown
long howMuch;
long field_50;
long field_50; // unused
long procedureTable[28];
long gap[7];
};
+2
View File
@@ -193,7 +193,9 @@
#define FO_VAR_movie_list 0x518DA0
#define FO_VAR_Mutate_ 0x5708B4
#define FO_VAR_name_color 0x56D744
#define FO_VAR_name_critter 0x51833C
#define FO_VAR_name_font 0x56D74C
#define FO_VAR_name_item 0x519238
#define FO_VAR_name_sort_list 0x56FCB0
#define FO_VAR_num_caps 0x518060
#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() {
using namespace fo;
__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() {
using namespace fo;
__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 IDirect3DDevice9* d3d9Device;
extern IDirectDrawSurface* primaryDDSurface;
extern IDirectDrawSurface* primarySurface;
extern bool DeviceLost;
/*
@@ -106,12 +106,12 @@ public:
DDSURFACEDESC desc;
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;
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
"result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {"
"result = tex1D(s1, backdrop).bgr;" // get color in palette and swap R <> B
"result = tex1D(s1, backdrop);" // get color in palette
"}"
// blend highlights
"if (showhl) {"
@@ -154,7 +154,7 @@ static const char* gpuEffectA8 =
// main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"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"
"{"
@@ -182,7 +182,7 @@ static const char* gpuEffectL8 =
"if (abs(backdrop - 1.0) < 0.001) {"
"result = tex2D(s2, saturate((Tex - corner) / size));"
"} else {"
"result = tex1D(s1, backdrop).bgr;"
"result = tex1D(s1, backdrop);"
"}"
// blend highlights
"if (showhl) {"
@@ -199,7 +199,7 @@ static const char* gpuEffectL8 =
// main shader
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
"float3 result = tex1D(s1, tex2D(s0, Tex).r);"
"return float4(result.bgr, 1);"
"return float4(result, 1);"
"}"
"technique T0"
"{"
+1 -3
View File
@@ -796,8 +796,6 @@ static void __declspec(naked) wmInterfaceInit_hook() {
}
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)) {
dlog("Applying world map font patch.", DL_INIT);
HookCall(0x4C2343, wmInterfaceInit_text_font_hook);
@@ -846,7 +844,7 @@ static void WorldMapInterfacePatch() {
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
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;
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* 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 item;
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
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) {
fo::ScriptInstance* script;
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)
long __fastcall Objects::SetObjectUniqueID(fo::GameObject* obj) {
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;
obj->id = ++uniqueID;
+2
View File
@@ -17,6 +17,8 @@ public:
static long uniqueID;
static bool IsUniqueID(long id);
static long __fastcall SetObjectUniqueID(fo::GameObject* obj);
static long __fastcall SetSpecialID(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_);
}
InitNewOpcodes();
Opcodes::InitNew();
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 void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) {
if (type == 4) return; // LIST_TILES
vec.reserve(100);
if (type == 6) {
fo::ScriptInstance* scriptPtr;
fo::GameObject* self_obj;
fo::Program* programPtr;
if (type == 6) { // LIST_SPATIAL
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) {
self_obj = scriptPtr->selfObject;
fo::GameObject* self_obj = scriptPtr->selfObject;
if (self_obj == nullptr) {
programPtr = scriptPtr->program;
self_obj = fo::func::scr_find_obj_from_program(programPtr);
self_obj = fo::func::scr_find_obj_from_program(scriptPtr->program);
}
vec.push_back(self_obj);
scriptPtr = fo::func::scr_find_next_at();
}
}
/*} else if (type == 4) {
/*} else if (type == 4) { // LIST_TILES
// TODO: verify code correctness
for(int elv=0;elv<2;elv++) {
DWORD* esquares = &fo::var::squares[elv];
@@ -176,7 +174,7 @@ static void FillListVector(DWORD type, std::vector<fo::GameObject*>& vec) {
esquares[tile]=0x8f000002;
}
}*/
} else if (type != 4) {
} else {
for (int elv = 0; elv < 3; elv++) {
for (int tile = 0; tile < 40000; 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;
}
void InitNewOpcodes() {
void Opcodes::InitNew() {
dlogr("Adding additional opcodes", DL_SCRIPT);
SafeWrite32(0x46E370, opcodeCount); // Maximum number of allowed opcodes
+4 -1
View File
@@ -25,7 +25,10 @@ namespace sfall
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;
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);
if (val >= 0) hit.maxDamage = val;
if (val > 0) hit.maxDamage = val;
val = IniReader::GetInt(sHit, "BonusDamage", -1, file);
if (val >= 0) hit.bonusDamage = val;
@@ -454,7 +454,7 @@ void Unarmed::init() {
if (val >= 0) hit.bonusCrit = val;
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);
if (val >= 0) hit.isPenetrate = (val != 0);