Implemented the optimization for receiving/passing script args from 4.x

* combined related engine interpreter functions into a single function
for aligning the compiled ASM code better.

Minor edits to dinput.cpp.
This commit is contained in:
NovaRain
2020-01-31 20:29:29 +08:00
parent 555b3a9504
commit 0d5c88fded
7 changed files with 109 additions and 98 deletions
+38 -14
View File
@@ -1013,24 +1013,48 @@ DWORD __stdcall InterpretPopLong(TProgram* scriptPtr) {
WRAP_WATCOM_CALL1(interpretPopLong_, scriptPtr)
}
// pushes value to Data stack (must be followed by InterpretPushShort)
void __stdcall InterpretPushLong(TProgram* scriptPtr, DWORD val) {
WRAP_WATCOM_CALL2(interpretPushLong_, scriptPtr, val)
}
// pushes value type to Data stack (must be preceded by InterpretPushLong)
void __stdcall InterpretPushShort(TProgram* scriptPtr, DWORD valType) {
WRAP_WATCOM_CALL2(interpretPushShort_, scriptPtr, valType)
}
DWORD __stdcall InterpretAddString(TProgram* scriptPtr, const char* strval) {
WRAP_WATCOM_CALL2(interpretAddString_, scriptPtr, strval)
}
const char* __fastcall InterpretGetString(TProgram* scriptPtr, DWORD dataType, DWORD strId) {
WRAP_WATCOM_FCALL3(interpretGetString_, scriptPtr, dataType, strId)
}
void __stdcall InterpretReturnValue(TProgram* scriptPtr, DWORD val, DWORD valType) {
__asm {
mov esi, scriptPtr;
mov edx, val;
cmp valType, VAR_TYPE_STR;
jne isNotStr;
mov eax, esi;
call interpretAddString_;
mov edx, eax;
isNotStr:
mov eax, esi;
call interpretPushLong_; // pushes value to Data stack (must be followed by InterpretPushShort)
mov edx, valType;
mov eax, esi;
call interpretPushShort_; // pushes value type to Data stack (must be preceded by InterpretPushLong)
}
}
DWORD __fastcall InterpretGetValue(TProgram* scriptPtr, DWORD &outType) {
__asm {
mov eax, ecx;
call interpretPopShort_; // pops value type from Data stack (must be followed by InterpretPopLong)
mov [edx], eax; // out type
mov edx, eax;
mov eax, ecx;
call interpretPopLong_; // pops value from Data stack (must be preceded by InterpretPopShort)
cmp dx, VAR_TYPE_STR2;
je getStr;
cmp dx, VAR_TYPE_STR;
jne isNotStr;
getStr:
mov ebx, eax;
mov eax, ecx;
call interpretGetString_; // retrieve string argument
isNotStr:
}
}
// prints scripting error in debug.log and stops current script execution by performing longjmp
// USE WITH CAUTION
void __declspec(naked) InterpretError(const char* fmt, ...) {
+3 -7
View File
@@ -1162,15 +1162,11 @@ DWORD __stdcall InterpretPopShort(TProgram* scriptPtr);
// pops value from Data stack (must be preceded by InterpretPopShort)
DWORD __stdcall InterpretPopLong(TProgram* scriptPtr);
// pushes value to Data stack (must be followed by InterpretPushShort)
void __stdcall InterpretPushLong(TProgram* scriptPtr, DWORD val);
// pushes value type to Data stack (must be preceded by InterpretPushLong)
void __stdcall InterpretPushShort(TProgram* scriptPtr, DWORD valType);
const char* __fastcall InterpretGetString(TProgram* scriptPtr, DWORD dataType, DWORD strId);
DWORD __stdcall InterpretAddString(TProgram* scriptPtr, const char* str);
void __stdcall InterpretReturnValue(TProgram* scriptPtr, DWORD val, DWORD valType);
DWORD __fastcall InterpretGetValue(TProgram* scriptPtr, DWORD &outType);
// prints scripting error in debug.log and stops current script execution by performing longjmp
// USE WITH CAUTION
+1 -1
View File
@@ -748,7 +748,7 @@ void InventoryInit() {
SafeWrite32(0x475CF2, _stack);
// Enable mouse scroll control in barter and loot screens when the cursor is hovering over other lists
if (UseScrollWheel) {
if (useScrollWheel) {
MakeCall(0x473E66, loot_container_hack_scroll);
MakeCall(0x4759F1, barter_inventory_hack_scroll);
*ptr_max = 100;
+4 -16
View File
@@ -333,16 +333,9 @@ public:
// process arguments on stack (reverse order)
for (int i = argNum - 1; i >= 0; i--) {
// get argument from stack
DWORD rawValueType = InterpretPopShort(program);
DWORD rawValue = InterpretPopLong(program);
SfallDataType type = static_cast<SfallDataType>(getSfallTypeByScriptType(rawValueType));
// retrieve string argument
if (type == DATATYPE_STR) {
_args[i] = InterpretGetString(program, rawValueType, rawValue);
} else {
_args[i] = ScriptValue(type, rawValue);
}
DWORD rawValueType;
DWORD rawValue = InterpretGetValue(program, rawValueType);
_args[i] = ScriptValue(static_cast<SfallDataType>(getSfallTypeByScriptType(rawValueType)), rawValue);
}
// flag that arguments passed are valid
bool argumentsValid = true;
@@ -366,12 +359,7 @@ public:
if (_ret.type() == DATATYPE_NONE) {
_ret = ScriptValue(0); // if no value was set in handler, force return 0 to avoid stack error
}
DWORD rawResult = _ret.rawValue();
if (_ret.type() == DATATYPE_STR) {
rawResult = InterpretAddString(program, _ret.strValue());
}
InterpretPushLong(program, rawResult);
InterpretPushShort(program, getScriptTypeBySfallType(_ret.type()));
InterpretReturnValue(program, _ret.rawValue(), getScriptTypeBySfallType(_ret.type()));
}
}
+1 -1
View File
@@ -108,7 +108,7 @@ static void __declspec(naked) get_mouse_buttons() {
mov edx, ds:[_last_buttons];
test edx, edx;
jnz skip;
cmp byte ptr MiddleMouseDown, 0;
cmp byte ptr middleMouseDown, 0;
jz skip;
mov edx, 4;
skip:
+60 -57
View File
@@ -33,34 +33,34 @@
typedef HRESULT (_stdcall *DInputCreateProc)(HINSTANCE a,DWORD b,IDirectInputA** c,IUnknown* d);
bool UseScrollWheel = true;
static DWORD WheelMod;
bool useScrollWheel = true;
static DWORD wheelMod;
static bool ReverseMouse;
static bool reverseMouse;
bool MiddleMouseDown;
static DWORD MiddleMouseKey;
bool middleMouseDown;
static DWORD middleMouseKey;
static bool BackgroundKeyboard;
static bool BackgroundMouse;
static bool backgroundKeyboard;
static bool backgroundMouse;
static bool AdjustMouseSpeed;
static double MouseSpeedMod;
static double MousePartX;
static double MousePartY;
static bool adjustMouseSpeed;
static double mouseSpeedMod;
static double mousePartX;
static double mousePartY;
#define MAX_KEYS (264)
static DWORD KeysDown[MAX_KEYS] = {0};
static DWORD keysDown[MAX_KEYS] = {0};
static int mouseX;
static int mouseY;
static DWORD ForcingGraphicsRefresh = 0;
static DWORD forcingGraphicsRefresh = 0;
static DWORD DebugEditorKey = 0;
static DWORD debugEditorKey = 0;
void _stdcall ForceGraphicsRefresh(DWORD d) {
ForcingGraphicsRefresh = (d == 0) ? 0 : 1;
forcingGraphicsRefresh = (d == 0) ? 0 : 1;
}
void GetMouse(int* x, int* y) {
@@ -99,11 +99,11 @@ DWORD _stdcall KeyDown(DWORD key) {
return 0;
} else {
DWORD keyVK = 0;
if (KeysDown[key]) { // confirm pressed state
if (keysDown[key]) { // confirm pressed state
keyVK = MapVirtualKeyEx(key, MAPVK_VSC_TO_VK, keyboardLayout);
if (keyVK) KeysDown[key] = (GetAsyncKeyState(keyVK) & 0x8000);
if (keyVK) keysDown[key] = (GetAsyncKeyState(keyVK) & 0x8000);
}
return (KeysDown[key] > 0);
return (keysDown[key] > 0);
}
}
@@ -125,6 +125,7 @@ private:
ULONG Refs;
bool formatLock;
DIDATAFORMAT oldFormat;
public:
/*** Constructor and misc functions ***/
FakeDirectInputDevice(IDirectInputDevice* device,DWORD type) {
@@ -181,7 +182,7 @@ public:
// Only called for the mouse
HRESULT _stdcall GetDeviceState(DWORD a, LPVOID b) {
if (ForcingGraphicsRefresh) RefreshGraphics();
if (forcingGraphicsRefresh) RefreshGraphics();
if (DeviceType != kDeviceType_MOUSE) {
return RealDevice->GetDeviceState(a, b);
}
@@ -192,20 +193,20 @@ public:
if (formatLock) hr = RealDevice->GetDeviceState(sizeof(DIMOUSESTATE2), &MouseState);
else hr = RealDevice->GetDeviceState(sizeof(DIMOUSESTATE), &MouseState);
if (FAILED(hr)) return hr;
if (ReverseMouse) {
if (reverseMouse) {
BYTE tmp = MouseState.rgbButtons[0];
MouseState.rgbButtons[0] = MouseState.rgbButtons[1];
MouseState.rgbButtons[1] = tmp;
}
if (AdjustMouseSpeed) {
double d = ((double)MouseState.lX) * MouseSpeedMod + MousePartX;
MousePartX = modf(d, &d);
if (adjustMouseSpeed) {
double d = ((double)MouseState.lX) * mouseSpeedMod + mousePartX;
mousePartX = modf(d, &d);
MouseState.lX = (LONG)d;
d = ((double)MouseState.lY) * MouseSpeedMod + MousePartY;
MousePartY = modf(d, &d);
d = ((double)MouseState.lY) * mouseSpeedMod + mousePartY;
mousePartY = modf(d, &d);
MouseState.lY = (LONG)d;
}
if (UseScrollWheel) {
if (useScrollWheel) {
int count = 1;
if (MouseState.lZ > 0) {
if (*ptr_gmouse_current_cursor == 2 || *ptr_gmouse_current_cursor == 3) {
@@ -213,7 +214,7 @@ public:
call display_scroll_up_;
}
} else {
if (WheelMod) count = MouseState.lZ / WheelMod;
if (wheelMod) count = MouseState.lZ / wheelMod;
if (count < 1) count = 1;
while (count--) TapKey(DIK_UP);
}
@@ -223,27 +224,27 @@ public:
call display_scroll_down_;
}
} else {
if (WheelMod) count = (-MouseState.lZ) / WheelMod;
if (wheelMod) count = (-MouseState.lZ) / wheelMod;
if (count < 1) count = 1;
while (count--) TapKey(DIK_DOWN);
}
}
}
if (MiddleMouseKey && MouseState.rgbButtons[2]) {
if (!MiddleMouseDown) {
TapKey(MiddleMouseKey);
MiddleMouseDown = true;
if (middleMouseKey && MouseState.rgbButtons[2]) {
if (!middleMouseDown) {
TapKey(middleMouseKey);
middleMouseDown = true;
}
} else MiddleMouseDown = false;
} else middleMouseDown = false;
mouseX = MouseState.lX;
mouseY = MouseState.lY;
numButtons = formatLock ? 8 : 4;
for (int i = 0; i < numButtons; i++) {
if ((MouseState.rgbButtons[i] & 0x80) != (KeysDown[256 + i] & 0x80)) { // state changed
if ((MouseState.rgbButtons[i] & 0x80) != (keysDown[256 + i] & 0x80)) { // state changed
MouseClickHook(i, (MouseState.rgbButtons[i] & 0x80) > 0);
}
KeysDown[256 + i] = MouseState.rgbButtons[i];
keysDown[256 + i] = MouseState.rgbButtons[i];
}
memcpy(b, &MouseState, sizeof(DIMOUSESTATE));
return 0;
@@ -260,18 +261,20 @@ public:
if (!buf || bufferedPresses.empty() || (d & DIGDD_PEEK)) {
HRESULT hr = RealDevice->GetDeviceData(a, buf, count, d);
if (FAILED(hr) || !buf || !(*count)) return hr;
DWORD keyOverride, oldState;
DWORD keyOverride;
for (DWORD i = 0; i < *count; i++) {
oldState = KeysDown[buf[i].dwOfs];
KeysDown[buf[i].dwOfs] = buf[i].dwData & 0x80;
keyOverride = KeyPressHook(buf[i].dwOfs, (buf[i].dwData & 0x80) > 0, MapVirtualKeyEx(buf[i].dwOfs, MAPVK_VSC_TO_VK, keyboardLayout));
DWORD dxKey = buf[i].dwOfs;
DWORD state = buf[i].dwData & 0x80;
DWORD oldState = keysDown[dxKey];
keysDown[dxKey] = state;
keyOverride = KeyPressHook(dxKey, (state > 0), MapVirtualKeyEx(dxKey, MAPVK_VSC_TO_VK, keyboardLayout));
if (keyOverride != 0) {
KeysDown[buf[i].dwOfs] = oldState;
keysDown[buf[i].dwOfs] = oldState;
buf[i].dwOfs = keyOverride;
KeysDown[buf[i].dwOfs] = buf[i].dwData & 0x80;
keysDown[buf[i].dwOfs] = state;
}
}
if (KeysDown[DebugEditorKey]) RunDebugEditor();
if (keysDown[debugEditorKey]) RunDebugEditor();
return hr;
}
//Despite passing an array of 32 data objects, fallout cant seem to cope with a key being pressed and released in the same frame...
@@ -295,8 +298,8 @@ public:
}
HRESULT _stdcall SetCooperativeLevel(HWND a, DWORD b) {
if (DeviceType == kDeviceType_KEYBOARD && BackgroundKeyboard) b = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
if (DeviceType == kDeviceType_MOUSE && BackgroundMouse) 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;
return RealDevice->SetCooperativeLevel(a, b);
}
@@ -404,25 +407,25 @@ HRESULT _stdcall FakeDirectInputCreate(HINSTANCE a, DWORD b, IDirectInputA** c,
HRESULT hr = proc(a, b, c, d);
if (FAILED(hr)) return hr;
ReverseMouse = GetConfigInt("Input", "ReverseMouseButtons", 0) != 0;
reverseMouse = GetConfigInt("Input", "ReverseMouseButtons", 0) != 0;
UseScrollWheel = GetConfigInt("Input", "UseScrollWheel", 1) != 0;
WheelMod = GetConfigInt("Input", "ScrollMod", 0);
useScrollWheel = GetConfigInt("Input", "UseScrollWheel", 1) != 0;
wheelMod = GetConfigInt("Input", "ScrollMod", 0);
LONG MouseSpeed = GetConfigInt("Input", "MouseSensitivity", 100);
if (MouseSpeed != 100) {
AdjustMouseSpeed = true;
MouseSpeedMod = ((double)MouseSpeed) / 100.0;
MousePartX = 0;
MousePartY = 0;
} else AdjustMouseSpeed = false;
adjustMouseSpeed = true;
mouseSpeedMod = ((double)MouseSpeed) / 100.0;
mousePartX = 0;
mousePartY = 0;
} else adjustMouseSpeed = false;
MiddleMouseKey = GetConfigInt("Input", "MiddleMouse", 0x30);
MiddleMouseDown = false;
middleMouseKey = GetConfigInt("Input", "MiddleMouse", 0x30);
middleMouseDown = false;
BackgroundKeyboard = GetConfigInt("Input", "BackgroundKeyboard", 0) != 0;
BackgroundMouse = GetConfigInt("Input", "BackgroundMouse", 0) != 0;
backgroundKeyboard = GetConfigInt("Input", "BackgroundKeyboard", 0) != 0;
backgroundMouse = GetConfigInt("Input", "BackgroundMouse", 0) != 0;
if (isDebug) DebugEditorKey = GetConfigInt("Input", "DebugEditorKey", 0);
if (isDebug) debugEditorKey = GetConfigInt("Input", "DebugEditorKey", 0);
*c = (IDirectInputA*)new FakeDirectInput(*c);
+2 -2
View File
@@ -18,8 +18,8 @@
#pragma once
extern bool UseScrollWheel;
extern bool MiddleMouseDown;
extern bool useScrollWheel;
extern bool middleMouseDown;
void SetMPMode(bool active);
void SetMDown(bool down, bool right);