mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Refactored and fixed SpeedPatch module (from Mr.Stalin)
This commit is contained in:
+10
-7
@@ -34,18 +34,21 @@ Enable=1
|
||||
;The speeds corresponding to each slot in percent. (i.e. 100 is normal speed)
|
||||
SpeedMulti0=50
|
||||
SpeedMulti1=100
|
||||
SpeedMulti2=150
|
||||
SpeedMulti3=200
|
||||
SpeedMulti4=300
|
||||
SpeedMulti2=200
|
||||
SpeedMulti3=300
|
||||
SpeedMulti4=400
|
||||
SpeedMulti5=500
|
||||
SpeedMulti6=1000
|
||||
SpeedMulti7=100
|
||||
SpeedMulti8=100
|
||||
SpeedMulti9=100
|
||||
SpeedMulti6=600
|
||||
SpeedMulti7=700
|
||||
SpeedMulti8=800
|
||||
SpeedMulti9=900
|
||||
|
||||
;The initial speed at game startup
|
||||
SpeedMultiInitial=100
|
||||
|
||||
;Set to 1 to also affect video playback and slideshow speed
|
||||
AffectPlayback=0
|
||||
|
||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
[Graphics]
|
||||
;Set to 0 for 8 bit fullscreen
|
||||
|
||||
@@ -49,7 +49,7 @@ static double mousePartX;
|
||||
static double mousePartY;
|
||||
|
||||
#define MAX_KEYS (264)
|
||||
static DWORD keysDown[MAX_KEYS];
|
||||
static DWORD keysDown[MAX_KEYS] = {0};
|
||||
|
||||
static int mouseX;
|
||||
static int mouseY;
|
||||
@@ -125,9 +125,9 @@ void _stdcall TapKey(DWORD key) {
|
||||
data.dwTimeStamp = 0;
|
||||
data.dwSequence = 0;
|
||||
data.dwOfs = key;
|
||||
data.dwData = 0x80;
|
||||
data.dwData = 0x80; // flag pressed
|
||||
bufferedPresses.push(data);
|
||||
data.dwData = 0x00;
|
||||
data.dwData = 0x00; // flag released
|
||||
bufferedPresses.push(data);
|
||||
}
|
||||
|
||||
@@ -406,8 +406,6 @@ public:
|
||||
};
|
||||
|
||||
inline void InitInputFeatures() {
|
||||
ZeroMemory(keysDown, sizeof(keysDown));
|
||||
|
||||
reverseMouse = GetConfigInt("Input", "ReverseMouseButtons", 0) != 0;
|
||||
|
||||
useScrollWheel = GetConfigInt("Input", "UseScrollWheel", 1) != 0;
|
||||
|
||||
@@ -10,18 +10,16 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static const DWORD dinputPos = 0x50FB70;
|
||||
|
||||
void Input::init() {
|
||||
//if(GetConfigInt("Input", "Enable", 0)) {
|
||||
dlog("Applying input patch.", DL_INIT);
|
||||
SafeWriteStr(dinputPos, "ddraw.dll");
|
||||
SafeWriteStr(0x50FB70, "ddraw.dll");
|
||||
::sfall::availableGlobalScriptTypes |= 1;
|
||||
dlogr(" Done", DL_INIT);
|
||||
//}
|
||||
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
ForceGraphicsRefresh(0);
|
||||
ForceGraphicsRefresh(0); // disable refresh
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
|
||||
#include "..\..\FalloutEngine\Fallout2.h"
|
||||
#include "..\..\InputFuncs.h"
|
||||
#include "..\KillCounter.h"
|
||||
|
||||
#include "Handlers\Anims.h"
|
||||
@@ -258,7 +257,7 @@ void InitNewOpcodes() {
|
||||
opcodes[0x169] = op_deactivate_shader;
|
||||
opcodes[0x16a] = op_set_global_script_repeat;
|
||||
opcodes[0x16b] = op_input_funcs_available;
|
||||
opcodes[0x16c] = defaultOpcodeHandler;
|
||||
|
||||
opcodes[0x16d] = op_set_shader_int;
|
||||
opcodes[0x16e] = op_set_shader_float;
|
||||
opcodes[0x16f] = op_set_shader_vector;
|
||||
|
||||
+102
-85
@@ -21,91 +21,99 @@
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "..\InputFuncs.h"
|
||||
#include "LoadGameHook.h"
|
||||
|
||||
#include "SpeedPatch.h"
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static const DWORD offsets[] = {
|
||||
// GetTickCount calls
|
||||
static const DWORD offsetsA[] = {
|
||||
0x4C8D34, 0x4C9375, 0x4C9384, 0x4C93C0, 0x4C93E8, 0x4C9D2E, 0x4FE01E,
|
||||
};
|
||||
|
||||
0x4C9375, 0x4C93E8, 0x4C93C0, 0x4FE01E,
|
||||
0x4C9384, 0x4C9D2E, 0x4C8D34,
|
||||
// Delayed GetTickCount calls
|
||||
static const DWORD offsetsB[] = {
|
||||
0x4FDF64,
|
||||
};
|
||||
|
||||
// timeGetTime calls
|
||||
static const DWORD offsetsC[] = {
|
||||
0x4A3179, 0x4A325D, 0x4F482B, 0x4F4E53, 0x4F5542, 0x4F56CC, 0x4F59C6,
|
||||
0x4FE036,
|
||||
0x4A3179, 0x4A325D, 0x4F482B, 0x4FE036,
|
||||
0x4F4E53, 0x4F5542, 0x4F56CC, 0x4F59C6, // for mve
|
||||
};
|
||||
|
||||
static const DWORD getLocalTimePos = 0x4FDF58;
|
||||
static DWORD addrGetTickCount;
|
||||
static DWORD addrGetLocalTime;
|
||||
DWORD sf_GetTickCount = (DWORD)&GetTickCount;
|
||||
//DWORD sf_GetLocalTime;
|
||||
|
||||
static bool Enabled;
|
||||
static bool Toggled;
|
||||
static bool enabled = true;
|
||||
static bool toggled = false;
|
||||
static bool slideShow = false;
|
||||
|
||||
static double Multi;
|
||||
static DWORD StoredTickCount;
|
||||
static DWORD LastTickCount;
|
||||
static double TickCountFraction;
|
||||
static double multi;
|
||||
static DWORD storedTickCount = 0;
|
||||
static DWORD lastTickCount;
|
||||
static double tickCountFraction = 0.0;
|
||||
|
||||
static __int64 StartTime;
|
||||
static __int64 startTime;
|
||||
|
||||
static double Multipliers[10];
|
||||
static int Keys[10];
|
||||
static int ModKey;
|
||||
static int ToggleKey;
|
||||
static struct SpeedCfg {
|
||||
int key;
|
||||
double multiplier;
|
||||
} *speed = nullptr;
|
||||
|
||||
DWORD _stdcall FakeGetTickCount() {
|
||||
static int modKey;
|
||||
static int toggleKey;
|
||||
|
||||
static DWORD _stdcall FakeGetTickCount() {
|
||||
// Keyboard control
|
||||
if (!ModKey || (ModKey > 0 && KeyDown(ModKey))
|
||||
|| (ModKey == -1 && (KeyDown(DIK_LCONTROL) || KeyDown(DIK_RCONTROL)))
|
||||
|| (ModKey == -2 && (KeyDown(DIK_LMENU) || KeyDown(DIK_RMENU)))
|
||||
|| (ModKey == -3 && (KeyDown(DIK_LSHIFT) || KeyDown(DIK_RSHIFT)))
|
||||
) {
|
||||
|
||||
for (int i = 0; i < 10; i++) if (Keys[i] && KeyDown(Keys[i])) {
|
||||
Multi = Multipliers[i];
|
||||
}
|
||||
|
||||
if (ToggleKey&&KeyDown(ToggleKey)) {
|
||||
if (!Toggled) {
|
||||
Toggled = true;
|
||||
Enabled = !Enabled;
|
||||
if (modKey && ((modKey > 0 && KeyDown(modKey))
|
||||
|| (modKey == -1 && (KeyDown(DIK_LCONTROL) || KeyDown(DIK_RCONTROL)))
|
||||
|| (modKey == -2 && (KeyDown(DIK_LMENU) || KeyDown(DIK_RMENU)))
|
||||
|| (modKey == -3 && (KeyDown(DIK_LSHIFT) || KeyDown(DIK_RSHIFT)))))
|
||||
{
|
||||
if (toggleKey && KeyDown(toggleKey)) {
|
||||
if (!toggled) {
|
||||
toggled = true;
|
||||
enabled = !enabled;
|
||||
}
|
||||
} else {
|
||||
Toggled = false;
|
||||
toggled = false;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int key = speed[i].key;
|
||||
if (key && KeyDown(key)) {
|
||||
multi = speed[i].multiplier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD NewTickCount = GetTickCount();
|
||||
DWORD newTickCount = GetTickCount();
|
||||
// Just in case someone's been running their computer for 49 days straight
|
||||
if (NewTickCount < LastTickCount) {
|
||||
NewTickCount = LastTickCount;
|
||||
return StoredTickCount;
|
||||
if (newTickCount < lastTickCount) {
|
||||
newTickCount = lastTickCount;
|
||||
return storedTickCount;
|
||||
}
|
||||
|
||||
double elapsed = (double)(newTickCount - lastTickCount);
|
||||
lastTickCount = newTickCount;
|
||||
|
||||
// Multiply the tick count difference by the multiplier
|
||||
double add = (double)(NewTickCount - LastTickCount)*(Enabled ? Multi : 1.0);
|
||||
LastTickCount = NewTickCount;
|
||||
TickCountFraction += modf(add, &add);
|
||||
StoredTickCount += (DWORD)add;
|
||||
if (TickCountFraction > 1) {
|
||||
TickCountFraction -= 1;
|
||||
StoredTickCount++;
|
||||
if (enabled && !slideShow
|
||||
&& !(GetLoopFlags() & (LoopFlag::INVENTORY | LoopFlag::INTFACEUSE | LoopFlag::INTFACELOOT | LoopFlag::DIALOG)))
|
||||
{
|
||||
elapsed *= multi;
|
||||
tickCountFraction += modf(elapsed, &elapsed);
|
||||
}
|
||||
return StoredTickCount;
|
||||
storedTickCount += (DWORD)elapsed;
|
||||
|
||||
if (tickCountFraction > 1.0) {
|
||||
tickCountFraction -= 1.0;
|
||||
storedTickCount++;
|
||||
}
|
||||
return storedTickCount;
|
||||
}
|
||||
|
||||
void _stdcall FakeGetLocalTime(LPSYSTEMTIME time) {
|
||||
__int64 CurrentTime = StartTime + StoredTickCount * 10000;
|
||||
FileTimeToSystemTime((FILETIME*)&CurrentTime, time);
|
||||
__int64 currentTime = startTime + storedTickCount * 10000;
|
||||
FileTimeToSystemTime((FILETIME*)¤tTime, time);
|
||||
}
|
||||
|
||||
//Could divide 'uDelay' by 'Multi', but doesn't seem to have any effect.
|
||||
@@ -117,56 +125,65 @@ MMRESULT _stdcall fTimeKillEvent(UINT id) {
|
||||
return timeKillEvent(id);
|
||||
}*/
|
||||
|
||||
static void __declspec(naked) scripts_check_state_hook() {
|
||||
__asm {
|
||||
inc slideShow;
|
||||
call fo::funcoffs::endgame_slideshow_;
|
||||
dec slideShow;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerInit() {
|
||||
StoredTickCount = 0;
|
||||
LastTickCount = GetTickCount();
|
||||
TickCountFraction = 0;
|
||||
Multi = (double)GetConfigInt("Speed", "SpeedMultiInitial", 100) / 100.0;
|
||||
Enabled = true;
|
||||
Toggled = false;
|
||||
lastTickCount = GetTickCount();
|
||||
|
||||
SYSTEMTIME time;
|
||||
GetLocalTime(&time);
|
||||
SystemTimeToFileTime(&time, (FILETIME*)&StartTime);
|
||||
SystemTimeToFileTime(&time, (FILETIME*)&startTime);
|
||||
|
||||
ModKey = GetConfigInt("Input", "SpeedModKey", -1);
|
||||
ToggleKey = GetConfigInt("Input", "SpeedToggleKey", 0);
|
||||
char c[2];
|
||||
char key[12];
|
||||
speed = new SpeedCfg[10];
|
||||
|
||||
char buf[2], spKey[10] = "SpeedKey#";
|
||||
char spMulti[12] = "SpeedMulti#";
|
||||
for (int i = 0; i < 10; i++) {
|
||||
_itoa_s(i, c, 10);
|
||||
strcpy_s(key, "SpeedKey");
|
||||
strcat_s(key, c);
|
||||
Keys[i] = GetConfigInt("Input", key, 0);
|
||||
strcpy_s(key, "SpeedMulti");
|
||||
strcat_s(key, c);
|
||||
Multipliers[i] = GetConfigInt("Speed", key, 0x00) / 100.0;
|
||||
_itoa_s(i, buf, 10);
|
||||
spKey[8] = spMulti[10] = buf[0];
|
||||
speed[i].key = GetConfigInt("Input", spKey, 0);
|
||||
speed[i].multiplier = GetConfigInt("Speed", spMulti, 0) / 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
void SpeedPatch::init() {
|
||||
if (GetConfigInt("Speed", "Enable", 0)) {
|
||||
modKey = GetConfigInt("Input", "SpeedModKey", 0);
|
||||
int init = GetConfigInt("Speed", "SpeedMultiInitial", 100);
|
||||
if (init == 100 && !modKey) return;
|
||||
|
||||
dlog("Applying speed patch.", DL_INIT);
|
||||
addrGetTickCount = (DWORD)&FakeGetTickCount;
|
||||
addrGetLocalTime = (DWORD)&FakeGetLocalTime;
|
||||
|
||||
for (int i = 0; i < sizeof(offsetsA) / 4; i++) {
|
||||
SafeWrite32(offsetsA[i], (DWORD)&addrGetTickCount);
|
||||
multi = (double)init / 100.0;
|
||||
toggleKey = GetConfigInt("Input", "SpeedToggleKey", 0);
|
||||
|
||||
sf_GetTickCount = (DWORD)&FakeGetTickCount;
|
||||
//sf_GetLocalTime = (DWORD)&FakeGetLocalTime;
|
||||
|
||||
int size = sizeof(offsets) / 4;
|
||||
if (GetConfigInt("Speed", "AffectPlayback", 0) == 0) {
|
||||
size -= 4;
|
||||
HookCall(0x4A433E, scripts_check_state_hook);
|
||||
}
|
||||
dlog(".", DL_INIT);
|
||||
for (int i = 0; i < sizeof(offsetsB) / 4; i++) {
|
||||
SafeWrite32(offsetsB[i], (DWORD)&addrGetTickCount);
|
||||
for (int i = 0; i < size; i++) {
|
||||
SafeWrite32(offsets[i], (DWORD)&sf_GetTickCount);
|
||||
}
|
||||
dlog(".", DL_INIT);
|
||||
for (int i = 0; i < sizeof(offsetsC) / 4; i++) {
|
||||
SafeWrite32(offsetsC[i], (DWORD)&addrGetTickCount);
|
||||
}
|
||||
dlog(".", DL_INIT);
|
||||
SafeWrite32(0x4FDF58, (DWORD)&FakeGetLocalTime);
|
||||
|
||||
SafeWrite32(getLocalTimePos, (DWORD)&addrGetLocalTime);
|
||||
TimerInit();
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
void SpeedPatch::exit() {
|
||||
if (speed) delete[] speed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ class SpeedPatch : public Module {
|
||||
public:
|
||||
const char* name() { return "SpeedPatch"; }
|
||||
void init();
|
||||
void exit() override;
|
||||
};
|
||||
|
||||
extern DWORD sf_GetTickCount;
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "LoadGameHook.h"
|
||||
#include "ScriptExtender.h"
|
||||
#include "SpeedPatch.h"
|
||||
|
||||
#include "Worldmap.h"
|
||||
|
||||
@@ -153,7 +154,7 @@ loopDelay:
|
||||
call WorldmapLoopHook;
|
||||
call fo::funcoffs::process_bk_;
|
||||
subLoop:
|
||||
call GetTickCount; // current ticks
|
||||
call ds:[sf_GetTickCount]; // current ticks
|
||||
mov edx, eax;
|
||||
sub eax, ebx; // get elapsed time (cur.ticks - prev.ticks)
|
||||
cmp eax, 10; // delay - GetTickCount returns minimum difference of 15 units
|
||||
@@ -165,7 +166,7 @@ subLoop:
|
||||
|
||||
pop dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
||||
pop dword ptr ds:[FO_VAR_last_buttons];
|
||||
call GetTickCount;
|
||||
call ds:[sf_GetTickCount];
|
||||
mov worldMapTicks, eax;
|
||||
jmp fo::funcoffs::get_input_;
|
||||
}
|
||||
@@ -178,7 +179,7 @@ static void __declspec(naked) WorldMapFpsPatch2() {
|
||||
loopDelay:
|
||||
call WorldmapLoopHook;
|
||||
subLoop:
|
||||
call GetTickCount; // current ticks
|
||||
call ds:[sf_GetTickCount]; // current ticks
|
||||
mov edx, eax;
|
||||
sub eax, ebx; // get elapsed time
|
||||
jz subLoop;
|
||||
@@ -187,7 +188,7 @@ subLoop:
|
||||
cmp edx, worldMapDelay;
|
||||
jb loopDelay; // elapsed < worldMapDelay
|
||||
|
||||
call GetTickCount;
|
||||
call ds:[sf_GetTickCount];
|
||||
mov worldMapTicks, eax;
|
||||
jmp fo::funcoffs::get_input_;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user