Implemented new way of handling sfall opcodes - now almost without any ASM code

Added bunch of engine function wrappers
This commit is contained in:
phobos2077
2016-11-03 19:30:42 +07:00
parent 502897cb6f
commit d29b51d5ea
7 changed files with 155 additions and 14 deletions
+65 -2
View File
@@ -351,6 +351,7 @@ const DWORD interpretPopLong_ = 0x467500;
const DWORD interpretPopShort_ = 0x4674F0;
const DWORD interpretPushLong_ = 0x4674DC;
const DWORD interpretPushShort_ = 0x46748C;
const DWORD interpretError_ = 0x4671F0;
const DWORD intface_redraw_ = 0x45EB98;
const DWORD intface_toggle_item_state_ = 0x45F4E0;
const DWORD intface_toggle_items_ = 0x45F404;
@@ -672,8 +673,7 @@ void DisplayConsoleMessage(const char* msg) {
}
static DWORD mesg_buf[4] = {0, 0, 0, 0};
const char* _stdcall GetMessageStr(DWORD fileAddr, DWORD messageId)
{
const char* _stdcall GetMessageStr(DWORD fileAddr, DWORD messageId) {
DWORD buf = (DWORD)mesg_buf;
const char* result;
__asm {
@@ -730,3 +730,66 @@ void InterfaceRedraw() {
call intface_redraw_
}
}
// pops value type from Data stack (must be followed by InterpretPopLong)
DWORD __stdcall InterpretPopShort(TProgram* scriptPtr) {
__asm {
mov eax, scriptPtr
call interpretPopShort_
}
}
// pops value from Data stack (must be preceded by InterpretPopShort)
DWORD __stdcall InterpretPopLong(TProgram* scriptPtr) {
__asm {
mov eax, scriptPtr
call interpretPopLong_
}
}
// pushes value to Data stack (must be followed by InterpretPushShort)
void __stdcall InterpretPushLong(TProgram* scriptPtr, DWORD val) {
__asm {
mov edx, val
mov eax, scriptPtr
call interpretPushLong_
}
}
// pushes value type to Data stack (must be preceded by InterpretPushLong)
void __stdcall InterpretPushShort(TProgram* scriptPtr, DWORD valType) {
__asm {
mov edx, valType
mov eax, scriptPtr
call interpretPushShort_
}
}
DWORD __stdcall InterpretAddString(TProgram* scriptPtr, const char* str) {
__asm {
mov edx, str
mov eax, scriptPtr
call interpretAddString_
}
}
const char* __stdcall InterpretGetString(TProgram* scriptPtr, DWORD strId, DWORD dataType) {
__asm {
mov edx, dataType
mov ebx, strId
mov eax, scriptPtr
call interpretGetString_
}
}
void __declspec(naked) InterpretError(const char* fmt, ...) {
__asm {
jmp interpretError_
}
}
void __declspec(naked) DebugPrintf(const char* fmt, ...) {
__asm {
jmp debug_printf_
}
}
+31 -1
View File
@@ -26,6 +26,9 @@
#include "FalloutStructs.h"
// Global variable offsets
// TODO: probably need to hide these by moving inside implementation file
#define _aiInfoList 0x510948
#define _ambient_light 0x51923C
#define _art 0x510738
@@ -206,6 +209,8 @@
#define _YellowColor 0x6AB8BB
// variables
// TODO: move to separate namespace
extern long* ptr_pc_traits; // 2 of them
extern DWORD* ptr_aiInfoList;
@@ -385,7 +390,8 @@ extern DWORD* ptr_world_ypos;
extern DWORD* ptr_WorldMapCurrArea;
extern DWORD* ptr_YellowColor;
// misc. offsets from engine
// engine function offsets
// TODO: move to separate namespace
extern const DWORD action_get_an_object_;
extern const DWORD action_loot_container_;
extern const DWORD action_use_an_item_on_object_;
@@ -514,6 +520,7 @@ extern const DWORD interpretPopLong_;
extern const DWORD interpretPopShort_;
extern const DWORD interpretPushLong_;
extern const DWORD interpretPushShort_;
extern const DWORD interpretError_;
extern const DWORD intface_redraw_; // no args
extern const DWORD intface_toggle_item_state_;
extern const DWORD intface_toggle_items_;
@@ -829,6 +836,7 @@ extern const DWORD getmsg_; // eax - msg file addr, ebx - message ID, edx - int[
#define MSG_FILE_WORLDMAP (0x672FB0)
// WRAPPERS:
// TODO: move these to different namespace
int _stdcall IsPartyMember(TGameObj* obj);
int _stdcall PartyMemberGetCurrentLevel(TGameObj* obj);
TGameObj* __stdcall GetInvenWeaponLeft(TGameObj* obj);
@@ -851,3 +859,25 @@ void SkillSetTags(int* tags, DWORD num);
// redraws the main game interface windows (useful after changing some data like active hand, etc.)
void InterfaceRedraw();
// pops value type from Data stack (must be followed by InterpretPopLong)
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* __stdcall InterpretGetString(TProgram* scriptPtr, DWORD strId, DWORD dataType);
DWORD __stdcall InterpretAddString(TProgram* scriptPtr, const char* str);
// prints scripting error in debug.log and stops current script execution by performing longjmp
void __declspec() InterpretError(const char* fmt, ...);
// prints message to debug.log file
void __declspec() DebugPrintf(const char* fmt, ...);
+1 -1
View File
@@ -139,7 +139,7 @@ enum ObjectTypes
#pragma pack(push, 1)
struct TProgram
{
char gap_0[4];
const char* fileName;
int *codeStackPtr;
char gap_8[8];
int *codePtr;
+45 -2
View File
@@ -18,9 +18,11 @@
#include "main.h"
#include <cassert>
#include <hash_map>
#include <set>
#include <string>
#include "Arrays.h"
#include "BarBoxes.h"
#include "Console.h"
@@ -37,9 +39,12 @@
void _stdcall HandleMapUpdateForScripts(DWORD procId);
// variables for new opcodes
#define OP_MAX_ARGUMENTS (10)
static TProgram* opProgram;
static DWORD opArgCount = 0;
static DWORD opArgs[5];
static DWORD opArgTypes[5];
static DWORD opArgs[OP_MAX_ARGUMENTS];
static DWORD opArgTypes[OP_MAX_ARGUMENTS];
static DWORD opRet;
static DWORD opRetType;
@@ -72,6 +77,10 @@ static bool _stdcall IsOpArgStr(int num) {
return (opArgTypes[num] == DATATYPE_STR);
}
static int _stdcall GetOpArgCount() {
return opArgCount;
}
static int _stdcall GetOpArgInt(int num) {
switch (opArgTypes[num]) {
case DATATYPE_FLOAT:
@@ -100,6 +109,40 @@ static const char* _stdcall GetOpArgStr(int num) {
: "";
}
// Handle opcodes
static void __stdcall HandleOpcode(TProgram* scriptPtr, int argNum, void(*func)()) {
assert(argNum < OP_MAX_ARGUMENTS);
opProgram = scriptPtr;
// process arguments on stack (reverse order)
opArgCount = argNum;
for (int i = argNum - 1; i >= 0; i--) {
DWORD rawValueType = InterpretPopShort(scriptPtr);
DWORD rawValue = InterpretPopLong(scriptPtr);
opArgTypes[i] = getSfallTypeByScriptType(rawValueType);
// retrieve string argument
if (opArgTypes[i] == DATATYPE_STR) {
opArgs[i] = reinterpret_cast<DWORD>(InterpretGetString(scriptPtr, rawValue, rawValueType));
} else {
opArgs[i] = rawValue;
}
}
// call opcode handler
func();
// process return value
if (opRetType != DATATYPE_NONE) {
DWORD rawResult = opRet;
if (opRetType == DATATYPE_STR) {
rawResult = InterpretAddString(scriptPtr, reinterpret_cast<const char*>(opRet));
}
InterpretPushLong(scriptPtr, rawResult);
InterpretPushShort(scriptPtr, getScriptTypeBySfallType(opRetType));
}
}
#include "ScriptOps\AsmMacros.h"
#include "ScriptOps\ScriptArrays.hpp"
#include "ScriptOps\ScriptUtils.hpp"
+11
View File
@@ -139,6 +139,17 @@ __asm resultnotstr##num: \
func - C-function to call (should not have arguments)
*/
#define _WRAP_OPCODE(argnum, func) __asm { \
__asm pushad \
__asm push func \
__asm push argnum \
__asm push eax \
__asm call HandleOpcode \
__asm popad \
__asm retn \
}
// Old wrapping macros.. does not support string arguments
#define _WRAP_OPCODE_OLD(argnum, func) __asm { \
__asm pushad \
__asm mov ebp, eax \
__asm mov esi, argnum \
-6
View File
@@ -334,19 +334,15 @@ end:
}
static DWORD _stdcall obj_blocking_at_wrapper(DWORD obj, DWORD tile, DWORD elevation, DWORD func) {
DWORD retval;
__asm {
mov eax, obj;
mov edx, tile;
mov ebx, elevation;
call func;
mov retval, eax;
}
return retval;
}
static DWORD _stdcall make_straight_path_func_wrapper(DWORD obj, DWORD tileFrom, DWORD a3, DWORD tileTo, DWORD* result, DWORD a6, DWORD func) {
DWORD retval;
__asm {
mov eax, obj;
mov edx, tileFrom;
@@ -356,9 +352,7 @@ static DWORD _stdcall make_straight_path_func_wrapper(DWORD obj, DWORD tileFrom,
push a6;
push result;
call make_straight_path_func_;
mov retval, eax;
}
return retval;
}
#define BLOCKING_TYPE_BLOCK (0)