Backported get/set_proto_data changes and LoadProtoMaxLimit option from the develop branch.

Added more definitions to define_extra.h.
This commit is contained in:
NovaRain
2018-10-08 21:45:16 +08:00
parent d9b748c261
commit a7e492a80f
6 changed files with 125 additions and 90 deletions
+4
View File
@@ -360,6 +360,10 @@ CorpseLineOfFireFix=0
;Set to 1 (or some higher number if needed, the maximum is 127) to prevent 100% CPU use
ProcessorIdle=-1
;Set a number of how many protos of a type can be loaded into memory at once (valid range: 512..4096)
;Set to -1 to let set_proto_data script function automatically increase the limit when needed
LoadProtoMaxLimit=-1
;Set to 1 if using the hero appearance mod
EnableHeroAppearanceMod=0
+19 -9
View File
@@ -21,14 +21,14 @@
#define WEAPON_2HAND 512 // 0x00000200 - 2Hnd (weapon is two-handed)
#define ATKMODE_PRI_NONE 0
#define ATKMODE_PRI_PUNCH 1
#define ATKMODE_PRI_KICK 2
#define ATKMODE_PRI_SWING 3
#define ATKMODE_PRI_THRUST 4
#define ATKMODE_PRI_THROW 5
#define ATKMODE_PRI_SINGLE 6
#define ATKMODE_PRI_BURST 7
#define ATKMODE_PRI_FLAME 8
#define ATKMODE_PRI_PUNCH 1 // 0001
#define ATKMODE_PRI_KICK 2 // 0010
#define ATKMODE_PRI_SWING 3 // 0011
#define ATKMODE_PRI_THRUST 4 // 0100
#define ATKMODE_PRI_THROW 5 // 0101
#define ATKMODE_PRI_SINGLE 6 // 0110
#define ATKMODE_PRI_BURST 7 // 0111
#define ATKMODE_PRI_FLAME 8 // 1000
#define ATKMODE_SEC_NONE 0
#define ATKMODE_SEC_PUNCH 16 // 0x00000010
#define ATKMODE_SEC_KICK 32 // 0x00000020
@@ -75,15 +75,21 @@
// offsets for get_proto_data
#define PROTO_PID (1)
#define PROTO_TEXTID (4)
#define PROTO_FID (8)
// items
#define PROTO_IT_LDIST (12)
#define PROTO_IT_LINT (16)
#define PROTO_IT_FLAG (20)
#define PROTO_IT_FLAGS (24)
#define PROTO_IT_SCRIPTID (28)
#define PROTO_IT_TYPE (32)
#define PROTO_IT_MATERIAL (108)
#define PROTO_IT_SIZE (112)
#define PROTO_IT_WEIGHT (116)
#define PROTO_IT_COST (120)
#define PROTO_IT_INV_FID (124)
#define PROTO_IT_SOUND (128) // byte
// weapons
#define PROTO_WP_ANIM (36)
@@ -161,7 +167,11 @@
#define PROTO_DR_ADDICT_DELAY (100)
// critters
#define PROTO_CR_FLAGS (32)
#define PROTO_CR_LDIST (20)
#define PROTO_CR_LINT (24)
#define PROTO_CR_FLAG (28)
#define PROTO_CR_FLAGS (32) // Critter Flags
#define PROTO_CR_SCRIPTID (36)
#define PROTO_CR_HEAD_FID (40)
#define PROTO_CR_AI_PACKET (44)
#define PROTO_CR_TEAM_NUM (48)
+8 -6
View File
@@ -61,11 +61,11 @@ struct TGameObj
char gap_44[16];
long lastTarget;
char gap_58[12];
long pid;
DWORD pid;
long cid;
long lightDistance;
long lightIntensity;
char outline[4];
DWORD outline;
long scriptID;
TGameObj* owner;
long script_index;
@@ -100,16 +100,18 @@ struct TComputeAttack
struct TScript
{
long script_id;
char gap_4[4];
long next;
// first 3 bits - elevation, rest - tile number
long elevation_and_tile;
long spatial_radius;
char gap_10[4];
long flags;
long script_index;
TProgram *program_ptr;
long self_obj_id;
char gap_20[8];
long local_var_offset;
long num_local_vars;
long scr_return;
char gap_2C[4];
long action;
long fixed_param;
TGameObj *self_obj;
TGameObj *source_obj;
+33
View File
@@ -1211,6 +1211,30 @@ static void __declspec(naked) CombatOverHook() {
}
}
static int maxCountProto = 512;
static void __declspec(naked) proto_ptr_hack() {
__asm {
mov ecx, maxCountProto;
cmp ecx, 4096;
jae skip;
cmp eax, ecx;
jb end;
add ecx, 256;
mov maxCountProto, ecx;
skip:
cmp eax, ecx;
end:
retn;
}
}
void LoadProtoAutoMaxLimit() {
if (maxCountProto != -1) {
MakeCall(0x4A21B2, proto_ptr_hack);
dlogr("Proto patch.", DL_INIT);
}
}
void ScriptExtenderSetup() {
bool AllowUnsafeScripting = IsDebug
&& GetPrivateProfileIntA("Debugging", "AllowUnsafeScripting", 0, ".\\ddraw.ini") != 0;
@@ -1235,6 +1259,15 @@ void ScriptExtenderSetup() {
}
modifiedIni = GetPrivateProfileIntA("Main", "ModifiedIni", 0, ini);
int maxlimit = GetPrivateProfileIntA("Misc", "LoadProtoMaxLimit", -1, ini);
if (maxlimit != -1) {
maxCountProto = -1;
if (maxlimit > 512) {
if (maxlimit > 4096) maxlimit = 4096;
SafeWrite32(0x4A21B3, maxlimit);
}
}
arraysBehavior = GetPrivateProfileIntA("Misc", "arraysBehavior", 1, ini);
if (arraysBehavior > 0) {
arraysBehavior = 1; // only 1 and 0 allowed at this time
+1
View File
@@ -42,6 +42,7 @@ typedef struct {
} sScriptProgram;
void ScriptExtenderSetup();
void LoadProtoAutoMaxLimit();
bool _stdcall isGameScript(const char* filename);
void LoadGlobalScripts();
void ClearGlobalScripts();
+60 -75
View File
@@ -1117,86 +1117,71 @@ static void __declspec(naked) NBCreateChar() {
}
}
static void __declspec(naked) get_proto_data() {
__asm {
pushad;
sub esp, 4;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
mov ecx, eax;
mov eax, ebp;
call interpretPopShort_;
mov esi, eax;
mov eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz fail;
cmp si, VAR_TYPE_INT;
jnz fail;
mov edx, esp;
call proto_ptr_;
mov eax, [esp];
test eax, eax;
jz fail;
mov edx, [eax+ecx/**4*/];
jmp end;
fail:
xor edx, edx;
dec edx;
end:
mov eax, ebp;
call interpretPushLong_;
mov eax, ebp;
mov edx, VAR_TYPE_INT;
call interpretPushShort_;
add esp, 4;
popad;
retn;
static void _stdcall get_proto_data2() {
const ScriptValue &pidArg = opHandler.arg(0),
&offsetArg = opHandler.arg(1);
if (pidArg.isInt() && offsetArg.isInt()) { // argument validation
char* protoPtr;
char* *protoPtrRef = &protoPtr;
int pid = pidArg.asInt();
int result;
__asm {
mov edx, protoPtrRef;
mov eax, pid;
call proto_ptr_;
mov result, eax;
}
if (result != -1) {
result = *(long*)((BYTE*)protoPtr + offsetArg.asInt());
} else {
opHandler.printOpcodeError("get_proto_data() - failed to load a prototype id: %d", pid);
}
opHandler.setReturn(result);
} else {
opHandler.printOpcodeError("get_proto_data() - invalid arguments.");
opHandler.setReturn(-1);
}
}
static void __declspec(naked) set_proto_data() {
__asm {
pushad;
sub esp, 4;
mov ebp, eax;
call interpretPopShort_;
mov edi, eax;
mov eax, ebp;
call interpretPopLong_;
mov ecx, eax;
mov eax, ebp;
call interpretPopShort_;
mov esi, eax;
mov eax, ebp;
call interpretPopLong_;
mov ebx, eax;
mov eax, ebp;
call interpretPopShort_;
xchg eax, ebp;
call interpretPopLong_;
cmp di, VAR_TYPE_INT;
jnz end;
cmp si, VAR_TYPE_INT;
jnz end;
cmp bp, VAR_TYPE_INT;
jnz end;
//mov eax, [eax+0x64];
mov edx, esp;
call proto_ptr_;
mov eax, [esp];
test eax, eax;
jz end;
mov [eax+ebx/**4*/], ecx;
end:
add esp, 4;
popad;
retn;
static void __declspec(naked) get_proto_data() {
_WRAP_OPCODE(get_proto_data2, 2, 1)
}
static bool protoMaxLimitPatch = false;
static void _stdcall set_proto_data2() {
const ScriptValue &pidArg = opHandler.arg(0),
&offsetArg = opHandler.arg(1),
&valueArg = opHandler.arg(2);
if (pidArg.isInt() && offsetArg.isInt() && valueArg.isInt()) { // argument validation
char* protoPtr;
char* *protoPtrRef = &protoPtr;
int pid = pidArg.asInt();
int result;
__asm {
mov edx, protoPtrRef;
mov eax, pid;
call proto_ptr_;
mov result, eax;
}
if (result != -1) {
*(long*)((BYTE*)protoPtr + offsetArg.asInt()) = valueArg.asInt();
if (!protoMaxLimitPatch) {
LoadProtoAutoMaxLimit();
protoMaxLimitPatch = true;
}
} else {
opHandler.printOpcodeError("set_proto_data() - failed to load a prototype id: %d", pid);
}
} else {
opHandler.printOpcodeError("set_proto_data() - invalid arguments.");
opHandler.setReturn(-1);
}
}
static void __declspec(naked) set_proto_data() {
_WRAP_OPCODE(set_proto_data2, 3, 0)
}
static void __declspec(naked) funcHeroSelectWin() {//for opening the appearance selection window
__asm {
push ebx;