mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Refactored and fixed speed patch related code (from Mr.Stalin)
Rewrote ASM code of WorldMapFpsPatch functions.
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)
|
;The speeds corresponding to each slot in percent. (i.e. 100 is normal speed)
|
||||||
SpeedMulti0=50
|
SpeedMulti0=50
|
||||||
SpeedMulti1=100
|
SpeedMulti1=100
|
||||||
SpeedMulti2=150
|
SpeedMulti2=200
|
||||||
SpeedMulti3=200
|
SpeedMulti3=300
|
||||||
SpeedMulti4=300
|
SpeedMulti4=400
|
||||||
SpeedMulti5=500
|
SpeedMulti5=500
|
||||||
SpeedMulti6=1000
|
SpeedMulti6=600
|
||||||
SpeedMulti7=100
|
SpeedMulti7=700
|
||||||
SpeedMulti8=100
|
SpeedMulti8=800
|
||||||
SpeedMulti9=100
|
SpeedMulti9=900
|
||||||
|
|
||||||
;The initial speed at game startup
|
;The initial speed at game startup
|
||||||
SpeedMultiInitial=100
|
SpeedMultiInitial=100
|
||||||
|
|
||||||
|
;Set to 1 to also affect video playback and slideshow speed
|
||||||
|
AffectPlayback=0
|
||||||
|
|
||||||
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||||
[Graphics]
|
[Graphics]
|
||||||
;Set to 0 for 8 bit fullscreen
|
;Set to 0 for 8 bit fullscreen
|
||||||
|
|||||||
+17
-17
@@ -386,25 +386,25 @@ static OpcodeHandler opHandler;
|
|||||||
If you don't include opcode in this array, you should take care of all argument validation inside handler itself.
|
If you don't include opcode in this array, you should take care of all argument validation inside handler itself.
|
||||||
*/
|
*/
|
||||||
static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
||||||
{sf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
{sf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||||
{sf_critter_inven_obj2, "critter_inven_obj2", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
{sf_critter_inven_obj2, "critter_inven_obj2", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||||
{sf_get_current_inven_size, "get_current_inven_size", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_get_current_inven_size, "get_current_inven_size", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_get_flags, "get_flags", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_get_flags, "get_flags", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_get_object_data, "get_object_data", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
{sf_get_object_data, "get_object_data", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||||
{sf_get_outline, "get_outline", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_get_outline, "get_outline", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_inventory_redraw, "inventory_redraw", {DATATYPE_MASK_INT}},
|
{sf_inventory_redraw, "inventory_redraw", {DATATYPE_MASK_INT}},
|
||||||
{sf_item_weight, "item_weight", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_item_weight, "item_weight", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_lock_is_jammed, "lock_is_jammed", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_lock_is_jammed, "lock_is_jammed", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_get_obj_under_cursor, "obj_under_cursor", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
{sf_get_obj_under_cursor, "obj_under_cursor", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||||
{sf_set_cursor_mode, "set_cursor_mode", {DATATYPE_MASK_INT}},
|
{sf_set_cursor_mode, "set_cursor_mode", {DATATYPE_MASK_INT}},
|
||||||
{sf_set_flags, "set_flags", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
{sf_set_flags, "set_flags", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||||
{sf_set_ini_setting, "set_ini_setting", {DATATYPE_MASK_STR, DATATYPE_MASK_INT | DATATYPE_MASK_STR}},
|
{sf_set_ini_setting, "set_ini_setting", {DATATYPE_MASK_STR, DATATYPE_MASK_INT | DATATYPE_MASK_STR}},
|
||||||
{sf_set_map_enter_position, "set_map_enter_position", {DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
{sf_set_map_enter_position, "set_map_enter_position", {DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||||
{sf_set_object_data, "set_object_data", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
{sf_set_object_data, "set_object_data", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||||
{sf_set_outline, "set_outline", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
{sf_set_outline, "set_outline", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||||
{sf_spatial_radius, "spatial_radius", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_spatial_radius, "spatial_radius", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_unjam_lock, "unjam_lock", {DATATYPE_MASK_VALID_OBJ}},
|
{sf_unjam_lock, "unjam_lock", {DATATYPE_MASK_VALID_OBJ}},
|
||||||
{sf_test, "validate_test", {DATATYPE_MASK_INT, DATATYPE_MASK_INT | DATATYPE_MASK_FLOAT, DATATYPE_MASK_STR, DATATYPE_NONE}},
|
{sf_test, "validate_test", {DATATYPE_MASK_INT, DATATYPE_MASK_INT | DATATYPE_MASK_FLOAT, DATATYPE_MASK_STR, DATATYPE_NONE}},
|
||||||
//{op_message_str_game, {}}
|
//{op_message_str_game, {}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -103,39 +103,39 @@ static void sf_get_metarule_table() {
|
|||||||
- minArgs/maxArgs - minimum and maximum number of arguments allowed for this function
|
- minArgs/maxArgs - minimum and maximum number of arguments allowed for this function
|
||||||
*/
|
*/
|
||||||
static const SfallMetarule metaruleArray[] = {
|
static const SfallMetarule metaruleArray[] = {
|
||||||
{"art_cache_clear", sf_art_cache_flush, 0, 0},
|
{"art_cache_clear", sf_art_cache_flush, 0, 0},
|
||||||
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
|
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
|
||||||
{"critter_inven_obj2", sf_critter_inven_obj2, 2, 2},
|
{"critter_inven_obj2", sf_critter_inven_obj2, 2, 2},
|
||||||
{"create_win", sf_create_win, 5, 6},
|
{"create_win", sf_create_win, 5, 6},
|
||||||
{"display_stats", sf_display_stats, 0, 0},
|
{"display_stats", sf_display_stats, 0, 0},
|
||||||
{"exec_map_update_scripts", sf_exec_map_update_scripts, 0, 0},
|
{"exec_map_update_scripts", sf_exec_map_update_scripts, 0, 0},
|
||||||
{"floor2", sf_floor2, 1, 1},
|
{"floor2", sf_floor2, 1, 1},
|
||||||
{"get_current_inven_size", sf_get_current_inven_size, 1, 1},
|
{"get_current_inven_size", sf_get_current_inven_size, 1, 1},
|
||||||
{"get_cursor_mode", sf_get_cursor_mode, 0, 0},
|
{"get_cursor_mode", sf_get_cursor_mode, 0, 0},
|
||||||
{"get_flags", sf_get_flags, 1, 1},
|
{"get_flags", sf_get_flags, 1, 1},
|
||||||
{"get_map_enter_position", sf_get_map_enter_position, 0, 0},
|
{"get_map_enter_position", sf_get_map_enter_position, 0, 0},
|
||||||
{"get_metarule_table", sf_get_metarule_table, 0, 0},
|
{"get_metarule_table", sf_get_metarule_table, 0, 0},
|
||||||
{"get_object_data", sf_get_object_data, 2, 2},
|
{"get_object_data", sf_get_object_data, 2, 2},
|
||||||
{"get_outline", sf_get_outline, 1, 1},
|
{"get_outline", sf_get_outline, 1, 1},
|
||||||
{"intface_hide", sf_intface_hide, 0, 0},
|
{"intface_hide", sf_intface_hide, 0, 0},
|
||||||
{"intface_is_hidden", sf_intface_is_hidden, 0, 0},
|
{"intface_is_hidden", sf_intface_is_hidden, 0, 0},
|
||||||
{"intface_redraw", sf_intface_redraw, 0, 0},
|
{"intface_redraw", sf_intface_redraw, 0, 0},
|
||||||
{"intface_show", sf_intface_show, 0, 0},
|
{"intface_show", sf_intface_show, 0, 0},
|
||||||
{"inventory_redraw", sf_inventory_redraw, 1, 1},
|
{"inventory_redraw", sf_inventory_redraw, 1, 1},
|
||||||
{"item_weight", sf_item_weight, 1, 1},
|
{"item_weight", sf_item_weight, 1, 1},
|
||||||
{"lock_is_jammed", sf_lock_is_jammed, 1, 1},
|
{"lock_is_jammed", sf_lock_is_jammed, 1, 1},
|
||||||
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2},
|
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2},
|
||||||
{"outlined_object", sf_outlined_object, 0, 0},
|
{"outlined_object", sf_outlined_object, 0, 0},
|
||||||
{"set_cursor_mode", sf_set_cursor_mode, 1, 1},
|
{"set_cursor_mode", sf_set_cursor_mode, 1, 1},
|
||||||
{"set_flags", sf_set_flags, 2, 2},
|
{"set_flags", sf_set_flags, 2, 2},
|
||||||
{"set_ini_setting", sf_set_ini_setting, 2, 2},
|
{"set_ini_setting", sf_set_ini_setting, 2, 2},
|
||||||
{"set_map_enter_position", sf_set_map_enter_position, 3, 3},
|
{"set_map_enter_position", sf_set_map_enter_position, 3, 3},
|
||||||
{"set_object_data", sf_set_object_data, 3, 3},
|
{"set_object_data", sf_set_object_data, 3, 3},
|
||||||
{"set_outline", sf_set_outline, 2, 2},
|
{"set_outline", sf_set_outline, 2, 2},
|
||||||
{"spatial_radius", sf_spatial_radius, 1, 1},
|
{"spatial_radius", sf_spatial_radius, 1, 1},
|
||||||
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
|
{"tile_refresh_display", sf_tile_refresh_display, 0, 0},
|
||||||
{"unjam_lock", sf_unjam_lock, 1, 1},
|
{"unjam_lock", sf_unjam_lock, 1, 1},
|
||||||
{"validate_test", sf_test, 2, 5},
|
{"validate_test", sf_test, 2, 5},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void InitMetaruleTable() {
|
static void InitMetaruleTable() {
|
||||||
|
|||||||
+12
-14
@@ -50,7 +50,7 @@ static double MousePartX;
|
|||||||
static double MousePartY;
|
static double MousePartY;
|
||||||
|
|
||||||
#define MAX_KEYS (264)
|
#define MAX_KEYS (264)
|
||||||
static DWORD KeysDown[MAX_KEYS];
|
static DWORD KeysDown[MAX_KEYS] = {0};
|
||||||
|
|
||||||
static int mouseX;
|
static int mouseX;
|
||||||
static int mouseY;
|
static int mouseY;
|
||||||
@@ -112,9 +112,9 @@ void _stdcall TapKey(DWORD key) {
|
|||||||
data.dwTimeStamp = 0;
|
data.dwTimeStamp = 0;
|
||||||
data.dwSequence = 0;
|
data.dwSequence = 0;
|
||||||
data.dwOfs = key;
|
data.dwOfs = key;
|
||||||
data.dwData = 0x80;
|
data.dwData = 0x80; // flag pressed
|
||||||
bufferedPresses.push(data);
|
bufferedPresses.push(data);
|
||||||
data.dwData = 0x00;
|
data.dwData = 0x00; // flag released
|
||||||
bufferedPresses.push(data);
|
bufferedPresses.push(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ public:
|
|||||||
return RealDevice->Unacquire();
|
return RealDevice->Unacquire();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Only called for the mouse
|
// Only called for the mouse
|
||||||
HRESULT _stdcall GetDeviceState(DWORD a, LPVOID b) {
|
HRESULT _stdcall GetDeviceState(DWORD a, LPVOID b) {
|
||||||
if (ForcingGraphicsRefresh) RefreshGraphics();
|
if (ForcingGraphicsRefresh) RefreshGraphics();
|
||||||
if (DeviceType != kDeviceType_MOUSE) {
|
if (DeviceType != kDeviceType_MOUSE) {
|
||||||
@@ -198,10 +198,10 @@ public:
|
|||||||
MouseState.rgbButtons[1] = tmp;
|
MouseState.rgbButtons[1] = tmp;
|
||||||
}
|
}
|
||||||
if (AdjustMouseSpeed) {
|
if (AdjustMouseSpeed) {
|
||||||
double d = ((double)MouseState.lX)*MouseSpeedMod + MousePartX;
|
double d = ((double)MouseState.lX) * MouseSpeedMod + MousePartX;
|
||||||
MousePartX = modf(d, &d);
|
MousePartX = modf(d, &d);
|
||||||
MouseState.lX = (LONG)d;
|
MouseState.lX = (LONG)d;
|
||||||
d = ((double)MouseState.lY)*MouseSpeedMod + MousePartY;
|
d = ((double)MouseState.lY) * MouseSpeedMod + MousePartY;
|
||||||
MousePartY = modf(d, &d);
|
MousePartY = modf(d, &d);
|
||||||
MouseState.lY = (LONG)d;
|
MouseState.lY = (LONG)d;
|
||||||
}
|
}
|
||||||
@@ -249,7 +249,7 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Only called for the keyboard
|
// Only called for the keyboard
|
||||||
HRESULT _stdcall GetDeviceData(DWORD a, DIDEVICEOBJECTDATA* b, DWORD* c, DWORD d) {
|
HRESULT _stdcall GetDeviceData(DWORD a, DIDEVICEOBJECTDATA* b, DWORD* c, DWORD d) {
|
||||||
if (DeviceType != kDeviceType_KEYBOARD) {
|
if (DeviceType != kDeviceType_KEYBOARD) {
|
||||||
return RealDevice->GetDeviceData(a, b, c, d);
|
return RealDevice->GetDeviceData(a, b, c, d);
|
||||||
@@ -285,7 +285,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
HRESULT _stdcall SetDataFormat(const DIDATAFORMAT* a) {
|
HRESULT _stdcall SetDataFormat(const DIDATAFORMAT* a) {
|
||||||
if (formatLock&&oldFormat.dwSize) return RealDevice->SetDataFormat(&oldFormat);
|
if (formatLock && oldFormat.dwSize) return RealDevice->SetDataFormat(&oldFormat);
|
||||||
memcpy(&oldFormat, a, sizeof(DIDATAFORMAT));
|
memcpy(&oldFormat, a, sizeof(DIDATAFORMAT));
|
||||||
return RealDevice->SetDataFormat(a);
|
return RealDevice->SetDataFormat(a);
|
||||||
}
|
}
|
||||||
@@ -295,8 +295,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
HRESULT _stdcall SetCooperativeLevel(HWND a, DWORD b) {
|
HRESULT _stdcall SetCooperativeLevel(HWND a, DWORD b) {
|
||||||
if (DeviceType == kDeviceType_KEYBOARD&&BackgroundKeyboard) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
|
if (DeviceType == kDeviceType_KEYBOARD && BackgroundKeyboard) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
|
||||||
if (DeviceType == kDeviceType_MOUSE&&BackgroundMouse) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
|
if (DeviceType == kDeviceType_MOUSE && BackgroundMouse) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
|
||||||
return RealDevice->SetCooperativeLevel(a, b);
|
return RealDevice->SetCooperativeLevel(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,8 +352,8 @@ public:
|
|||||||
|
|
||||||
/*** IDirectInput8A methods ***/
|
/*** IDirectInput8A methods ***/
|
||||||
HRESULT _stdcall CreateDevice(REFGUID r, IDirectInputDeviceA** device, IUnknown* unused) {
|
HRESULT _stdcall CreateDevice(REFGUID r, IDirectInputDeviceA** device, IUnknown* unused) {
|
||||||
GUID GUID_SysMouse = { 0x6F1D2B60, 0xD5A0, 0x11CF, { 0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00} };
|
GUID GUID_SysMouse = { 0x6F1D2B60, 0xD5A0, 0x11CF, { 0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
|
||||||
GUID GUID_SysKeyboard = { 0x6F1D2B61, 0xD5A0, 0x11CF, { 0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00} };
|
GUID GUID_SysKeyboard = { 0x6F1D2B61, 0xD5A0, 0x11CF, { 0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
|
||||||
|
|
||||||
if (r != GUID_SysKeyboard && r != GUID_SysMouse) {
|
if (r != GUID_SysKeyboard && r != GUID_SysMouse) {
|
||||||
return RealInput->CreateDevice(r, device, unused);
|
return RealInput->CreateDevice(r, device, unused);
|
||||||
@@ -396,8 +396,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
HRESULT _stdcall FakeDirectInputCreate(HINSTANCE a, DWORD b, IDirectInputA** c, IUnknown* d) {
|
HRESULT _stdcall FakeDirectInputCreate(HINSTANCE a, DWORD b, IDirectInputA** c, IUnknown* d) {
|
||||||
ZeroMemory(KeysDown, sizeof(KeysDown));
|
|
||||||
|
|
||||||
HMODULE dinput = LoadLibraryA("dinput.dll");
|
HMODULE dinput = LoadLibraryA("dinput.dll");
|
||||||
if (!dinput || dinput == INVALID_HANDLE_VALUE) return -1;
|
if (!dinput || dinput == INVALID_HANDLE_VALUE) return -1;
|
||||||
DInputCreateProc proc = (DInputCreateProc)GetProcAddress(dinput, "DirectInputCreateA");
|
DInputCreateProc proc = (DInputCreateProc)GetProcAddress(dinput, "DirectInputCreateA");
|
||||||
|
|||||||
+39
-83
@@ -87,29 +87,6 @@ bool npcautolevel;
|
|||||||
|
|
||||||
static int* scriptDialog = nullptr;
|
static int* scriptDialog = nullptr;
|
||||||
|
|
||||||
//GetTickCount calls
|
|
||||||
static const DWORD offsetsA[] = {
|
|
||||||
0x4C8D34, 0x4C9375, 0x4C9384, 0x4C93C0, 0x4C93E8, 0x4C9D2E, 0x4FE01E,
|
|
||||||
};
|
|
||||||
|
|
||||||
//Delayed GetTickCount calls
|
|
||||||
static const DWORD offsetsB[] = {
|
|
||||||
0x4FDF64,
|
|
||||||
};
|
|
||||||
|
|
||||||
//timeGetTime calls
|
|
||||||
static const DWORD offsetsC[] = {
|
|
||||||
0x4A3179, 0x4A325D, 0x4F482B, 0x4F4E53, 0x4F5542, 0x4F56CC, 0x4F59C6,
|
|
||||||
0x4FE036,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const DWORD getLocalTimePos = 0x4FDF58;
|
|
||||||
|
|
||||||
static const DWORD dinputPos = 0x50FB70;
|
|
||||||
|
|
||||||
static DWORD AddrGetTickCount;
|
|
||||||
static DWORD AddrGetLocalTime;
|
|
||||||
|
|
||||||
static DWORD ViewportX;
|
static DWORD ViewportX;
|
||||||
static DWORD ViewportY;
|
static DWORD ViewportY;
|
||||||
|
|
||||||
@@ -290,51 +267,61 @@ run:
|
|||||||
|
|
||||||
static DWORD worldMapDelay;
|
static DWORD worldMapDelay;
|
||||||
static DWORD worldMapTicks;
|
static DWORD worldMapTicks;
|
||||||
static DWORD worldMapAdjustDelay = 4;
|
|
||||||
static void __declspec(naked) WorldMapFpsPatch() {
|
static void __declspec(naked) WorldMapFpsPatch() {
|
||||||
__asm {
|
__asm {
|
||||||
pushadc;
|
|
||||||
push dword ptr ds:[_last_buttons];
|
push dword ptr ds:[_last_buttons];
|
||||||
push dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
push dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
||||||
xor ecx, ecx;
|
mov esi, worldMapTicks;
|
||||||
|
mov ebx, esi; // previous ticks
|
||||||
loopDelay:
|
loopDelay:
|
||||||
call process_bk_;
|
|
||||||
dec ecx;
|
|
||||||
jg subLoop; // jmp ecx > -1
|
|
||||||
call RunGlobalScripts3;
|
call RunGlobalScripts3;
|
||||||
mov ecx, worldMapAdjustDelay; // adjust invoke frequency
|
call process_bk_;
|
||||||
subLoop:
|
subLoop:
|
||||||
mov eax, worldMapTicks;
|
call ds:[sf_GetTickCount]; // current ticks
|
||||||
call elapsed_time_;
|
mov edx, eax;
|
||||||
cmp eax, 10; // delay
|
sub eax, ebx; // get elapsed time (cur.ticks - prev.ticks)
|
||||||
jle subLoop;
|
cmp eax, 10; // delay - GetTickCount returns minimum difference of 15 units
|
||||||
cmp eax, worldMapDelay;
|
jb subLoop; // elapsed < invoke delay
|
||||||
jl loopDelay; // elapsed < worldMapDelay
|
mov ebx, edx;
|
||||||
|
sub edx, esi; // get elapsed time (cur.ticks - worldMapTicks)
|
||||||
|
cmp edx, worldMapDelay;
|
||||||
|
jb loopDelay; // elapsed < worldMapDelay
|
||||||
|
|
||||||
call get_time_;
|
|
||||||
mov worldMapTicks, eax;
|
|
||||||
pop dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
pop dword ptr ds:[0x6AC7B0]; // _mouse_buttons
|
||||||
pop dword ptr ds:[_last_buttons];
|
pop dword ptr ds:[_last_buttons];
|
||||||
popadc;
|
call ds:[sf_GetTickCount];
|
||||||
|
mov worldMapTicks, eax;
|
||||||
jmp get_input_;
|
jmp get_input_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __declspec(naked) WorldMapFpsPatch2() {
|
static void __declspec(naked) WorldMapFpsPatch2() {
|
||||||
__asm {
|
__asm {
|
||||||
pushadc;
|
mov esi, worldMapTicks;
|
||||||
|
mov ebx, esi;
|
||||||
loopDelay:
|
loopDelay:
|
||||||
call RunGlobalScripts3;
|
call RunGlobalScripts3;
|
||||||
subLoop:
|
subLoop:
|
||||||
mov eax, worldMapTicks;
|
call ds:[sf_GetTickCount]; // current ticks
|
||||||
call elapsed_time_;
|
mov edx, eax;
|
||||||
test eax, eax; // 1 min delay
|
sub eax, ebx; // get elapsed time
|
||||||
jz subLoop;
|
jz subLoop;
|
||||||
cmp eax, worldMapDelay;
|
mov ebx, edx;
|
||||||
jl loopDelay; // elapsed < worldMapDelay
|
sub edx, esi; // get elapsed time
|
||||||
|
cmp edx, worldMapDelay;
|
||||||
|
jb loopDelay; // elapsed < worldMapDelay
|
||||||
|
|
||||||
call get_time_;
|
call ds:[sf_GetTickCount];
|
||||||
mov worldMapTicks, eax;
|
mov worldMapTicks, eax;
|
||||||
|
jmp get_input_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 RunGlobalScripts3;
|
||||||
popadc;
|
popadc;
|
||||||
jmp get_input_;
|
jmp get_input_;
|
||||||
}
|
}
|
||||||
@@ -404,16 +391,6 @@ end_cppf:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 RunGlobalScripts3;
|
|
||||||
popadc;
|
|
||||||
jmp get_input_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __declspec(naked) ViewportHook() {
|
static void __declspec(naked) ViewportHook() {
|
||||||
__asm {
|
__asm {
|
||||||
call wmWorldMapLoadTempData_;
|
call wmWorldMapLoadTempData_;
|
||||||
@@ -861,32 +838,11 @@ static void DllMain2() {
|
|||||||
dlogr("Running BugsInit().", DL_INIT);
|
dlogr("Running BugsInit().", DL_INIT);
|
||||||
BugsInit();
|
BugsInit();
|
||||||
|
|
||||||
if (GetPrivateProfileIntA("Speed", "Enable", 0, ini)) {
|
SpeedPatchInit();
|
||||||
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);
|
|
||||||
}
|
|
||||||
dlog(".", DL_INIT);
|
|
||||||
for (int i = 0; i < sizeof(offsetsB) / 4; i++) {
|
|
||||||
SafeWrite32(offsetsB[i], (DWORD)&AddrGetTickCount);
|
|
||||||
}
|
|
||||||
dlog(".", DL_INIT);
|
|
||||||
for (int i = 0; i < sizeof(offsetsC) / 4; i++) {
|
|
||||||
SafeWrite32(offsetsC[i], (DWORD)&AddrGetTickCount);
|
|
||||||
}
|
|
||||||
dlog(".", DL_INIT);
|
|
||||||
|
|
||||||
SafeWrite32(getLocalTimePos, (DWORD)&AddrGetLocalTime);
|
|
||||||
TimerInit();
|
|
||||||
dlogr(" Done", DL_INIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (GetPrivateProfileIntA("Input", "Enable", 0, ini)) {
|
//if (GetPrivateProfileIntA("Input", "Enable", 0, ini)) {
|
||||||
dlog("Applying input patch.", DL_INIT);
|
dlog("Applying input patch.", DL_INIT);
|
||||||
SafeWriteStr(dinputPos, "ddraw.dll");
|
SafeWriteStr(0x50FB70, "ddraw.dll");
|
||||||
AvailableGlobalScriptTypes |= 1;
|
AvailableGlobalScriptTypes |= 1;
|
||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
//}
|
//}
|
||||||
@@ -1052,12 +1008,12 @@ static void DllMain2() {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
bool fpsPatchOK = (*(DWORD*)0x4BFE5E == 0x8D16);
|
bool fpsPatchOK = (*(DWORD*)0x4BFE5E == 0x8D16);
|
||||||
if (GetPrivateProfileInt("Misc", "WorldMapFPSPatch", 0, ini)) {
|
if (GetPrivateProfileIntA("Misc", "WorldMapFPSPatch", 0, ini)) {
|
||||||
dlog("Applying world map fps patch.", DL_INIT);
|
dlog("Applying world map fps patch.", DL_INIT);
|
||||||
if (!fpsPatchOK) {
|
if (!fpsPatchOK) {
|
||||||
dlogr(" Failed", DL_INIT);
|
dlogr(" Failed", DL_INIT);
|
||||||
} else {
|
} else {
|
||||||
int delay = GetPrivateProfileInt("Misc", "WorldMapDelay2", 66, ini);
|
int delay = GetPrivateProfileIntA("Misc", "WorldMapDelay2", 66, ini);
|
||||||
worldMapDelay = max(1, delay);
|
worldMapDelay = max(1, delay);
|
||||||
dlogr(" Done", DL_INIT);
|
dlogr(" Done", DL_INIT);
|
||||||
}
|
}
|
||||||
@@ -1066,8 +1022,7 @@ static void DllMain2() {
|
|||||||
void* func;
|
void* func;
|
||||||
if (worldMapDelay == 0) {
|
if (worldMapDelay == 0) {
|
||||||
func = wmWorldMap_hook;
|
func = wmWorldMap_hook;
|
||||||
} else if (worldMapDelay > 15) {
|
} else if (worldMapDelay > 25) {
|
||||||
worldMapAdjustDelay += worldMapDelay / 10;
|
|
||||||
func = WorldMapFpsPatch;
|
func = WorldMapFpsPatch;
|
||||||
} else {
|
} else {
|
||||||
func = WorldMapFpsPatch2;
|
func = WorldMapFpsPatch2;
|
||||||
@@ -1592,6 +1547,7 @@ static void _stdcall OnExit() {
|
|||||||
if (scriptDialog != nullptr) {
|
if (scriptDialog != nullptr) {
|
||||||
delete[] scriptDialog;
|
delete[] scriptDialog;
|
||||||
}
|
}
|
||||||
|
SpeedPatchExit();
|
||||||
ClearReadExtraGameMsgFiles();
|
ClearReadExtraGameMsgFiles();
|
||||||
ConsoleExit();
|
ConsoleExit();
|
||||||
BooksExit();
|
BooksExit();
|
||||||
|
|||||||
+132
-65
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* sfall
|
* sfall
|
||||||
* Copyright (C) 2008, 2009, 2010 The sfall team
|
* Copyright (C) 2008-2017 The sfall team
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -16,67 +16,100 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include "FalloutEngine.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "LoadGameHook.h"
|
||||||
|
|
||||||
static bool Enabled;
|
static const DWORD offsets[] = {
|
||||||
static bool Toggled;
|
// GetTickCount calls
|
||||||
|
0x4C9375, 0x4C93E8, 0x4C93C0, 0x4FE01E,
|
||||||
|
0x4C9384, 0x4C9D2E, 0x4C8D34,
|
||||||
|
// Delayed GetTickCount calls
|
||||||
|
0x4FDF64,
|
||||||
|
// timeGetTime calls
|
||||||
|
0x4A3179, 0x4A325D, 0x4F482B, 0x4FE036,
|
||||||
|
0x4F4E53, 0x4F5542, 0x4F56CC, 0x4F59C6, // for mve
|
||||||
|
};
|
||||||
|
|
||||||
static double Multi;
|
DWORD sf_GetTickCount = (DWORD)&GetTickCount;
|
||||||
static DWORD StoredTickCount;
|
//DWORD sf_GetLocalTime;
|
||||||
static DWORD LastTickCount;
|
|
||||||
static double TickCountFraction;
|
|
||||||
|
|
||||||
static __int64 StartTime;
|
static bool enabled = true;
|
||||||
|
static bool toggled = false;
|
||||||
|
static bool slideShow = false;
|
||||||
|
|
||||||
static double Multipliers[10];
|
static double multi;
|
||||||
static int Keys[10];
|
static DWORD storedTickCount = 0;
|
||||||
static int ModKey;
|
static DWORD lastTickCount;
|
||||||
static int ToggleKey;
|
static double tickCountFraction = 0.0;
|
||||||
|
|
||||||
DWORD _stdcall FakeGetTickCount() {
|
static __int64 startTime;
|
||||||
//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]))
|
static struct SpeedCfg {
|
||||||
Multi=Multipliers[i];
|
int key;
|
||||||
|
double multiplier;
|
||||||
|
} *speed = nullptr;
|
||||||
|
|
||||||
if(ToggleKey&&KeyDown(ToggleKey)) {
|
static int modKey;
|
||||||
if(!Toggled) {
|
static int toggleKey;
|
||||||
Toggled=true;
|
|
||||||
Enabled=!Enabled;
|
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)))))
|
||||||
|
{
|
||||||
|
if (toggleKey && KeyDown(toggleKey)) {
|
||||||
|
if (!toggled) {
|
||||||
|
toggled = true;
|
||||||
|
enabled = !enabled;
|
||||||
}
|
}
|
||||||
} else Toggled=false;
|
} else {
|
||||||
|
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
|
// Just in case someone's been running their computer for 49 days straight
|
||||||
if(NewTickCount<LastTickCount) {
|
if (newTickCount < lastTickCount) {
|
||||||
NewTickCount=LastTickCount;
|
newTickCount = lastTickCount;
|
||||||
return StoredTickCount;
|
return storedTickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Multiply the tick count difference by the multiplier
|
double elapsed = (double)(newTickCount - lastTickCount);
|
||||||
double add=(double)(NewTickCount-LastTickCount)*(Enabled?Multi:1.0);
|
lastTickCount = newTickCount;
|
||||||
LastTickCount=NewTickCount;
|
|
||||||
TickCountFraction+=modf(add,&add);
|
// Multiply the tick count difference by the multiplier
|
||||||
StoredTickCount+=(DWORD)add;
|
if (enabled && !slideShow
|
||||||
if(TickCountFraction>1) {
|
&& !(GetCurrentLoops() & (INVENTORY | INTFACEUSE | INTFACELOOT | DIALOG)))
|
||||||
TickCountFraction-=1;
|
{
|
||||||
StoredTickCount++;
|
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) {
|
void _stdcall FakeGetLocalTime(LPSYSTEMTIME time) {
|
||||||
__int64 CurrentTime=StartTime + StoredTickCount*10000;
|
__int64 currentTime = startTime + storedTickCount * 10000;
|
||||||
FileTimeToSystemTime((FILETIME*)&CurrentTime, time);
|
FileTimeToSystemTime((FILETIME*)¤tTime, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Could divide 'uDelay' by 'Multi', but doesn't seem to have any effect.
|
//Could divide 'uDelay' by 'Multi', but doesn't seem to have any effect.
|
||||||
@@ -88,29 +121,63 @@ MMRESULT _stdcall fTimeKillEvent(UINT id) {
|
|||||||
return timeKillEvent(id);
|
return timeKillEvent(id);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
static void __declspec(naked) scripts_check_state_hook() {
|
||||||
|
__asm {
|
||||||
|
inc slideShow;
|
||||||
|
call endgame_slideshow_;
|
||||||
|
dec slideShow;
|
||||||
|
retn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TimerInit() {
|
void TimerInit() {
|
||||||
StoredTickCount=0;
|
lastTickCount = GetTickCount();
|
||||||
LastTickCount=GetTickCount();
|
|
||||||
TickCountFraction=0;
|
|
||||||
Multi=(double)GetPrivateProfileInt("Speed", "SpeedMultiInitial", 100, ini)/100.0;
|
|
||||||
Enabled=true;
|
|
||||||
Toggled=false;
|
|
||||||
|
|
||||||
SYSTEMTIME time;
|
SYSTEMTIME time;
|
||||||
GetLocalTime(&time);
|
GetLocalTime(&time);
|
||||||
SystemTimeToFileTime(&time, (FILETIME*)&StartTime);
|
SystemTimeToFileTime(&time, (FILETIME*)&startTime);
|
||||||
|
|
||||||
ModKey=GetPrivateProfileInt("Input", "SpeedModKey", -1, ini);
|
speed = new SpeedCfg[10];
|
||||||
ToggleKey=GetPrivateProfileInt("Input", "SpeedToggleKey", 0, ini);
|
|
||||||
char c[2];
|
char buf[2], spKey[10] = "SpeedKey#";
|
||||||
char key[12];
|
char spMulti[12] = "SpeedMulti#";
|
||||||
for(int i=0;i<10;i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
_itoa_s(i, c, 10);
|
_itoa_s(i, buf, 10);
|
||||||
strcpy_s(key, "SpeedKey");
|
spKey[8] = spMulti[10] = buf[0];
|
||||||
strcat_s(key, c);
|
speed[i].key = GetPrivateProfileIntA("Input", spKey, 0, ini);
|
||||||
Keys[i]=GetPrivateProfileInt("Input", key, 0, ini);
|
speed[i].multiplier = GetPrivateProfileIntA("Speed", spMulti, 0, ini) / 100.0;
|
||||||
strcpy_s(key, "SpeedMulti");
|
|
||||||
strcat_s(key, c);
|
|
||||||
Multipliers[i]=GetPrivateProfileInt("Speed", key, 0x00, ini)/100.0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpeedPatchInit() {
|
||||||
|
if (GetPrivateProfileIntA("Speed", "Enable", 0, ini)) {
|
||||||
|
modKey = GetPrivateProfileIntA("Input", "SpeedModKey", 0, ini);
|
||||||
|
int init = GetPrivateProfileIntA("Speed", "SpeedMultiInitial", 100, ini);
|
||||||
|
if (init == 100 && !modKey) return;
|
||||||
|
|
||||||
|
dlog("Applying speed patch.", DL_INIT);
|
||||||
|
|
||||||
|
multi = (double)init / 100.0;
|
||||||
|
toggleKey = GetPrivateProfileIntA("Input", "SpeedToggleKey", 0, ini);
|
||||||
|
|
||||||
|
sf_GetTickCount = (DWORD)&FakeGetTickCount;
|
||||||
|
//sf_GetLocalTime = (DWORD)&FakeGetLocalTime;
|
||||||
|
|
||||||
|
int size = sizeof(offsets) / 4;
|
||||||
|
if (GetPrivateProfileIntA("Speed", "AffectPlayback", 0, ini) == 0) {
|
||||||
|
size -= 4;
|
||||||
|
HookCall(0x4A433E, scripts_check_state_hook);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
SafeWrite32(offsets[i], (DWORD)&sf_GetTickCount);
|
||||||
|
}
|
||||||
|
SafeWrite32(0x4FDF58, (DWORD)&FakeGetLocalTime);
|
||||||
|
|
||||||
|
TimerInit();
|
||||||
|
dlogr(" Done", DL_INIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeedPatchExit() {
|
||||||
|
if (speed) delete[] speed;
|
||||||
|
}
|
||||||
|
|||||||
+4
-2
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
DWORD _stdcall FakeGetTickCount();
|
extern DWORD sf_GetTickCount;
|
||||||
|
|
||||||
void _stdcall FakeGetLocalTime(LPSYSTEMTIME);
|
void _stdcall FakeGetLocalTime(LPSYSTEMTIME);
|
||||||
void TimerInit();
|
void SpeedPatchInit();
|
||||||
|
void SpeedPatchExit();
|
||||||
|
|||||||
Reference in New Issue
Block a user