mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Rewrote ASM code of WorldMapFPSPatch in C++
This commit is contained in:
+2
-1
@@ -1,5 +1,5 @@
|
||||
;sfall configuration settings
|
||||
;v3.8.29
|
||||
;v3.8.30
|
||||
|
||||
[Main]
|
||||
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
||||
@@ -233,6 +233,7 @@ WorldMapTimeMod=100
|
||||
WorldMapFPSPatch=1
|
||||
|
||||
;Controls the world map speed if WorldMapFPSPatch is 1. Higher values cause slower movement
|
||||
;Default is 66 milliseconds
|
||||
WorldMapDelay2=66
|
||||
|
||||
;Set to 1 to enable Ray's patch to make world map encounter rate independent of your travel speed
|
||||
|
||||
+2
-2
@@ -318,7 +318,7 @@ static long __fastcall CheckWeaponRangeAndApCost(TGameObj* source, TGameObj* tar
|
||||
long targetDist = fo_obj_dist(source, target);
|
||||
if (targetDist > weaponRange) return 0; // don't use secondary mode
|
||||
|
||||
return (source->critter.movePoints >= sf_item_w_mp_cost(source, ATKTYPE_RWEAPON_SECONDARY, 0)); // 1 - allow secondary mode
|
||||
return (source->critter.movePoints >= sfgame_item_w_mp_cost(source, ATKTYPE_RWEAPON_SECONDARY, 0)); // 1 - allow secondary mode
|
||||
}
|
||||
|
||||
static void __declspec(naked) ai_pick_hit_mode_hook() {
|
||||
@@ -353,7 +353,7 @@ static void __declspec(naked) cai_perform_distance_prefs_hack() {
|
||||
mov ecx, esi;
|
||||
push 0; // no called shot
|
||||
mov edx, ATKTYPE_RWEAPON_PRIMARY;
|
||||
call sf_item_w_mp_cost;
|
||||
call sfgame_item_w_mp_cost;
|
||||
mov edx, [esi + movePoints];
|
||||
sub edx, eax; // ap - cost = free AP's
|
||||
jle moveAway; // <= 0
|
||||
|
||||
+13
-8
@@ -19,11 +19,12 @@
|
||||
#include <cmath>
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "FalloutEngine.h"
|
||||
#include "InputFuncs.h"
|
||||
#include "LoadGameHook.h"
|
||||
|
||||
#include "SpeedPatch.h"
|
||||
|
||||
static const DWORD offsets[] = {
|
||||
// GetTickCount calls
|
||||
0x4C9375, 0x4C93E8, 0x4C93C0, 0x4FE01E,
|
||||
@@ -35,8 +36,12 @@ static const DWORD offsets[] = {
|
||||
0x4F4E53, 0x4F5542, 0x4F56CC, 0x4F59C6, // for mve
|
||||
};
|
||||
|
||||
DWORD sf_GetTickCount = (DWORD)&GetTickCount;
|
||||
DWORD sf_GetLocalTime;
|
||||
static DWORD getLocalTimeOffs;
|
||||
DWORD getTickCountOffs = (DWORD)&GetTickCount;
|
||||
|
||||
DWORD SpeedPatch_getTickCount() {
|
||||
return ((DWORD (__stdcall*)())getTickCountOffs)();
|
||||
}
|
||||
|
||||
static bool enabled = true;
|
||||
static bool toggled = false;
|
||||
@@ -142,7 +147,7 @@ void TimerInit() {
|
||||
char buf[2], spKey[10] = "SpeedKey#";
|
||||
char spMulti[12] = "SpeedMulti#";
|
||||
for (int i = 0; i < 10; i++) {
|
||||
_itoa_s(i, buf, 10);
|
||||
_itoa(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;
|
||||
@@ -160,16 +165,16 @@ void SpeedPatch_Init() {
|
||||
multi = (double)init / 100.0;
|
||||
toggleKey = GetConfigInt("Input", "SpeedToggleKey", 0);
|
||||
|
||||
sf_GetTickCount = (DWORD)&FakeGetTickCount;
|
||||
sf_GetLocalTime = (DWORD)&FakeGetLocalTime;
|
||||
getTickCountOffs = (DWORD)&FakeGetTickCount;
|
||||
getLocalTimeOffs = (DWORD)&FakeGetLocalTime;
|
||||
|
||||
int size = sizeof(offsets) / 4;
|
||||
if (GetConfigInt("Speed", "AffectPlayback", 0) == 0) size -= 4;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
SafeWrite32(offsets[i], (DWORD)&sf_GetTickCount);
|
||||
SafeWrite32(offsets[i], (DWORD)&getTickCountOffs);
|
||||
}
|
||||
SafeWrite32(0x4FDF58, (DWORD)&sf_GetLocalTime);
|
||||
SafeWrite32(0x4FDF58, (DWORD)&getLocalTimeOffs);
|
||||
HookCall(0x4A433E, scripts_check_state_hook);
|
||||
|
||||
TimerInit();
|
||||
|
||||
+6
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* sfall
|
||||
* Copyright (C) 2008, 2009 The sfall team
|
||||
* Copyright (C) 2008-2017 The sfall team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +18,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
extern DWORD sf_GetTickCount;
|
||||
|
||||
void SpeedPatch_Init();
|
||||
void SpeedPatch_Exit();
|
||||
|
||||
extern DWORD getTickCountOffs;
|
||||
|
||||
// sfall implementation of the GetTickCount() function
|
||||
DWORD __stdcall SpeedPatch_getTickCount();
|
||||
|
||||
+44
-46
@@ -32,6 +32,7 @@ static DWORD ViewportY;
|
||||
std::vector<std::pair<long, std::string>> wmTerrainTypeNames; // pair first: x + y * number of horizontal sub-tiles
|
||||
std::tr1::unordered_map<long, std::string> wmAreaHotSpotTitle;
|
||||
|
||||
static bool worldMapLongDelay = false;
|
||||
static DWORD worldMapDelay;
|
||||
static DWORD worldMapTicks;
|
||||
|
||||
@@ -104,52 +105,42 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) WorldMapFpsPatch() {
|
||||
static void WorldMapFPS() {
|
||||
DWORD prevTicks = worldMapTicks; // previous ticks
|
||||
while (true) {
|
||||
RunGlobalScripts3();
|
||||
if (worldMapLongDelay) {
|
||||
__asm call process_bk_;
|
||||
}
|
||||
|
||||
DWORD tick; // current ticks
|
||||
while (true) {
|
||||
tick = SpeedPatch_getTickCount();
|
||||
// get elapsed time
|
||||
if ((tick - prevTicks) >= 10) break; // delay 10 ms (GetTickCount returns a difference of 10-16 ms)
|
||||
}
|
||||
prevTicks = tick;
|
||||
|
||||
// get elapsed time
|
||||
if ((tick - worldMapTicks) >= worldMapDelay) break;
|
||||
}
|
||||
worldMapTicks = prevTicks;
|
||||
}
|
||||
|
||||
static void __declspec(naked) wmWorldMap_hook_patch1() {
|
||||
__asm {
|
||||
push dword ptr ds:[FO_VAR_last_buttons];
|
||||
push dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
||||
mov esi, worldMapTicks;
|
||||
mov ebx, esi; // previous ticks
|
||||
loopDelay:
|
||||
call RunGlobalScripts3;
|
||||
call process_bk_;
|
||||
subLoop:
|
||||
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
|
||||
jb subLoop; // elapsed < invoke delay
|
||||
mov ebx, edx;
|
||||
sub edx, esi; // get elapsed time (cur.ticks - worldMapTicks)
|
||||
cmp edx, worldMapDelay;
|
||||
jb loopDelay; // elapsed < worldMapDelay
|
||||
|
||||
pop dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
||||
push dword ptr ds:[FO_VAR_mouse_buttons];
|
||||
call WorldMapFPS;
|
||||
pop dword ptr ds:[FO_VAR_mouse_buttons];
|
||||
pop dword ptr ds:[FO_VAR_last_buttons];
|
||||
call ds:[sf_GetTickCount];
|
||||
mov worldMapTicks, eax;
|
||||
jmp get_input_;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) WorldMapFpsPatch2() {
|
||||
static void __declspec(naked) wmWorldMap_hook_patch2() {
|
||||
__asm {
|
||||
mov esi, worldMapTicks;
|
||||
mov ebx, esi;
|
||||
loopDelay:
|
||||
call RunGlobalScripts3;
|
||||
subLoop:
|
||||
call ds:[sf_GetTickCount]; // current ticks
|
||||
mov edx, eax;
|
||||
sub eax, ebx; // get elapsed time
|
||||
jz subLoop;
|
||||
mov ebx, edx;
|
||||
sub edx, esi; // get elapsed time
|
||||
cmp edx, worldMapDelay;
|
||||
jb loopDelay; // elapsed < worldMapDelay
|
||||
|
||||
call ds:[sf_GetTickCount];
|
||||
mov worldMapTicks, eax;
|
||||
call WorldMapFPS;
|
||||
jmp get_input_;
|
||||
}
|
||||
}
|
||||
@@ -157,9 +148,14 @@ subLoop:
|
||||
// Only used if the world map speed patch is disabled, so that world map scripts are still run
|
||||
static void __declspec(naked) wmWorldMap_hook() {
|
||||
__asm {
|
||||
//pushadc;
|
||||
call ds:[getTickCountOffs]; // current ticks
|
||||
mov edx, eax;
|
||||
sub eax, worldMapTicks; // get elapsed time (cur.ticks - prev.ticks)
|
||||
cmp eax, 10; // delay 10 ms (GetTickCount returns a difference of 10-16 ms)
|
||||
jb skipHook;
|
||||
mov worldMapTicks, edx;
|
||||
call RunGlobalScripts3;
|
||||
//popadc;
|
||||
skipHook:
|
||||
jmp get_input_;
|
||||
}
|
||||
}
|
||||
@@ -223,6 +219,7 @@ static __declspec(naked) void PathfinderFix() {
|
||||
}
|
||||
|
||||
static const char* automap = "automap"; // no/yes overrides the value in the table to display the automap in pipboy
|
||||
|
||||
static void __declspec(naked) wmMapInit_hack() {
|
||||
__asm {
|
||||
mov esi, [esp + 0xA0 - 0x20 + 4]; // curent map number
|
||||
@@ -345,12 +342,12 @@ static void WorldmapFpsPatch() {
|
||||
bool fpsPatchOK = (*(DWORD*)0x4BFE5E == 0x8D16);
|
||||
if (GetConfigInt("Misc", "WorldMapFPSPatch", 0)) {
|
||||
dlog("Applying world map fps patch.", DL_INIT);
|
||||
if (!fpsPatchOK) {
|
||||
dlogr(" Failed", DL_INIT);
|
||||
} else {
|
||||
if (fpsPatchOK) {
|
||||
int delay = GetConfigInt("Misc", "WorldMapDelay2", 66);
|
||||
worldMapDelay = max(1, delay);
|
||||
dlogr(" Done", DL_INIT);
|
||||
} else {
|
||||
dlogr(" Failed", DL_INIT);
|
||||
}
|
||||
}
|
||||
if (fpsPatchOK) {
|
||||
@@ -358,11 +355,12 @@ static void WorldmapFpsPatch() {
|
||||
if (worldMapDelay == 0) {
|
||||
func = wmWorldMap_hook;
|
||||
} else if (worldMapDelay > 25) {
|
||||
func = WorldMapFpsPatch;
|
||||
worldMapLongDelay = true;
|
||||
func = wmWorldMap_hook_patch1;
|
||||
} else {
|
||||
func = WorldMapFpsPatch2;
|
||||
func = wmWorldMap_hook_patch2;
|
||||
}
|
||||
HookCall(0x4BFE5D, func);
|
||||
HookCall(0x4BFE5D, func); // wmWorldMap_
|
||||
availableGlobalScriptTypes |= 2;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user