mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
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:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -42,6 +42,7 @@ typedef struct {
|
||||
} sScriptProgram;
|
||||
|
||||
void ScriptExtenderSetup();
|
||||
void LoadProtoAutoMaxLimit();
|
||||
bool _stdcall isGameScript(const char* filename);
|
||||
void LoadGlobalScripts();
|
||||
void ClearGlobalScripts();
|
||||
|
||||
+60
-75
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user