mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Refactored ASM code in KillCounter.cpp.
Reformatted and tweaked code in Explosions.cpp.
This commit is contained in:
+64
-69
@@ -30,47 +30,44 @@ static const DWORD ranged_attack_lighting_fix_back = 0x4118F8;
|
||||
// enable lighting for flying projectile, based on projectile PID data (light intensity & radius)
|
||||
static void __declspec(naked) ranged_attack_lighting_fix() {
|
||||
__asm {
|
||||
mov eax, [esp+40]; // projectile ptr - 1st arg
|
||||
mov ecx, [eax+0x70]; // check existing light intensity
|
||||
cmp ecx, 0; // if non-zero, skip obj_set_light call
|
||||
jnz skip;
|
||||
mov ecx, [esp+0x1C]; // protoPtr of projectile
|
||||
mov edx, [ecx+0x0C]; // light radius - 2nd arg
|
||||
mov ebx, [ecx+0x10]; // light intensity - 4th arg
|
||||
xor ecx, ecx; // unknown(0) - 3rd argument
|
||||
mov eax, [esp + 40]; // source projectile ptr - 1st arg
|
||||
mov ecx, [eax + 0x70]; // check existing light intensity
|
||||
test ecx, ecx; // if non-zero, skip obj_set_light call
|
||||
jnz skip;
|
||||
mov ecx, [esp + 0x1C]; // protoPtr of projectile
|
||||
mov edx, [ecx + 0x0C]; // light radius - 2nd arg
|
||||
mov ebx, [ecx + 0x10]; // light intensity - 4th arg
|
||||
xor ecx, ecx; // unknown(0) - 3rd argument
|
||||
call obj_set_light_;
|
||||
skip:
|
||||
jmp ranged_attack_lighting_fix_back; // jump back
|
||||
jmp ranged_attack_lighting_fix_back; // jump back
|
||||
}
|
||||
}
|
||||
|
||||
// misc functions from the engine..
|
||||
static const DWORD register_object_play_sfx = 0x41541C;
|
||||
|
||||
static const DWORD explosion_effect_hook_back = 0x411AB9;
|
||||
static DWORD explosion_effect_starting_dir = 0;
|
||||
static void __declspec(naked) explosion_effect_hook() {
|
||||
__asm {
|
||||
mov bl, lightingEnabled
|
||||
test bl, bl
|
||||
jz usevanilla
|
||||
xor ebx, ebx
|
||||
call register_object_animate_
|
||||
jmp next
|
||||
mov bl, lightingEnabled;
|
||||
test bl, bl;
|
||||
jz usevanilla;
|
||||
xor ebx, ebx;
|
||||
call register_object_animate_;
|
||||
jmp next;
|
||||
usevanilla:
|
||||
xor ebx, ebx
|
||||
call register_object_animate_and_hide_
|
||||
xor ebx, ebx;
|
||||
call register_object_animate_and_hide_;
|
||||
next:
|
||||
mov al, lightingEnabled
|
||||
test al, al
|
||||
jz skiplight
|
||||
mov eax, [esp+40]; // projectile ptr - 1st arg
|
||||
mov edx, 0xFFFF0008; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
mov ebx, 0
|
||||
call register_object_light_;
|
||||
mov al, lightingEnabled;
|
||||
test al, al;
|
||||
jz skiplight;
|
||||
mov eax, [esp + 40]; // projectile ptr - 1st arg
|
||||
mov edx, 0xFFFF0008; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
xor ebx, ebx;
|
||||
call register_object_light_;
|
||||
skiplight:
|
||||
mov edi, explosion_effect_starting_dir; // starting direction
|
||||
jmp explosion_effect_hook_back; // jump back
|
||||
mov edi, explosion_effect_starting_dir; // starting direction
|
||||
jmp explosion_effect_hook_back; // jump back
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,22 +75,21 @@ static const DWORD explosion_lighting_fix2_back = 0x412FC7;
|
||||
// enable lighting for central explosion object (action_explode)
|
||||
static void __declspec(naked) explosion_lighting_fix2() {
|
||||
__asm {
|
||||
mov eax, [esp+24]
|
||||
mov edx, 1 // turn on
|
||||
mov ebx, 0
|
||||
call register_object_funset_
|
||||
mov eax, [esp + 24];
|
||||
mov edx, 1; // turn on
|
||||
xor ebx, ebx;
|
||||
call register_object_funset_;
|
||||
|
||||
mov eax, [esp+24]; // explosion obj ptr
|
||||
mov edx, 0xFFFF0008; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
mov ebx, 0
|
||||
call register_object_light_;
|
||||
mov eax, [esp + 24]; // explosion obj ptr
|
||||
mov edx, 0xFFFF0008; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
xor ebx, ebx;
|
||||
call register_object_light_;
|
||||
|
||||
mov eax, [esp+24]
|
||||
xor edx, edx
|
||||
mov ebx, 0
|
||||
call register_object_animate_
|
||||
|
||||
jmp explosion_lighting_fix2_back; // jump back
|
||||
mov eax, [esp + 24];
|
||||
xor edx, edx;
|
||||
xor ebx, ebx;
|
||||
call register_object_animate_;
|
||||
jmp explosion_lighting_fix2_back; // jump back
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,21 +101,21 @@ DWORD _stdcall LogThis(DWORD value1, DWORD value2, DWORD value3) {
|
||||
static const DWORD anim_set_check__light_back = 0x415A4C;
|
||||
static void __declspec(naked) anim_set_check__light_fix() {
|
||||
__asm {
|
||||
mov eax, [esi+4] // object
|
||||
lea ecx, [esp+16] // unknown.. something related to next "tile_refresh_rect" call?
|
||||
mov edx, [esi+12] // radius set in "reg_anim_light"
|
||||
mov ebx, edx
|
||||
shr ebx, 16 // take highest 2 bytes
|
||||
test ebx, ebx
|
||||
jz nothingspecial
|
||||
mov eax, [esi + 4]; // object
|
||||
lea ecx, [esp + 16]; // unknown.. something related to next "tile_refresh_rect" call?
|
||||
mov edx, [esi + 12]; // radius set in "reg_anim_light"
|
||||
mov ebx, edx;
|
||||
shr ebx, 16; // take highest 2 bytes
|
||||
test ebx, ebx;
|
||||
jz nothingspecial;
|
||||
// special case
|
||||
and edx, 0xFF // use lowest byte as radius, highest 2 bytes as intensity
|
||||
inc ebx
|
||||
jmp end
|
||||
and edx, 0xFF; // use lowest byte as radius, highest 2 bytes as intensity
|
||||
inc ebx;
|
||||
jmp end;
|
||||
nothingspecial:
|
||||
mov ebx, [eax+112] // object current light intensity (original behavior)
|
||||
mov ebx, [eax + 112]; // object current light intensity (original behavior)
|
||||
end:
|
||||
jmp anim_set_check__light_back; // jump back right to the "obj_set_light" call
|
||||
jmp anim_set_check__light_back; // jump back right to the "obj_set_light" call
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,20 +125,19 @@ static void __declspec(naked) fire_dance_lighting_fix1() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ebx;
|
||||
mov eax, esi; // projectile ptr - 1st arg
|
||||
mov edx, 0xFFFF0002; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
mov ebx, 0
|
||||
call register_object_light_;
|
||||
mov eax, esi;
|
||||
pop ebx;
|
||||
pop edx;
|
||||
call register_object_animate_; // overwritten call
|
||||
mov eax, esi; // projectile ptr - 1st arg
|
||||
mov edx, 0x00010000; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
mov ebx, -1
|
||||
call register_object_light_;
|
||||
|
||||
jmp fire_dance_lighting_back; // jump back
|
||||
mov eax, esi; // projectile ptr - 1st arg
|
||||
mov edx, 0xFFFF0002; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
xor ebx, ebx;
|
||||
call register_object_light_;
|
||||
mov eax, esi;
|
||||
pop ebx;
|
||||
pop edx;
|
||||
call register_object_animate_; // overwritten call
|
||||
mov eax, esi; // projectile ptr - 1st arg
|
||||
mov edx, 0x00010000; // maximum radius + intensity (see anim_set_check__light_fix)
|
||||
mov ebx, -1;
|
||||
call register_object_light_;
|
||||
jmp fire_dance_lighting_back; // jump back
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+34
-79
@@ -21,96 +21,51 @@
|
||||
#include "FalloutEngine.h"
|
||||
#include "version.h"
|
||||
|
||||
static int usingExtraKillTypes;
|
||||
bool UsingExtraKillTypes() { return usingExtraKillTypes!=0; }
|
||||
static const DWORD extraKillTypesCountAddr[] = {
|
||||
0x42D8AF, // critter_kill_count_
|
||||
0x42D881, // critter_kill_count_inc_
|
||||
0x42D980, // GetKillTypeName
|
||||
0x42D990,
|
||||
0x42D9C0, // GetKillTypeDesc
|
||||
0x42D9D0,
|
||||
0x4344E4, // Change char sheet to loop through the extra kill types
|
||||
};
|
||||
|
||||
//Fallout's idea of _fastcall seems to be different to VS2005's.
|
||||
//Might as well do this in asm, or the custom prolog code would end up being longer than the function
|
||||
static DWORD __declspec(naked) ReadKillCounter(DWORD killtype) {
|
||||
//if(killtype>38) return 0;
|
||||
//return ((WORD*)_pc_kill_counts)[killtype];
|
||||
static int usingExtraKillTypes = 0;
|
||||
|
||||
bool UsingExtraKillTypes() {
|
||||
return usingExtraKillTypes != 0;
|
||||
}
|
||||
|
||||
static DWORD __declspec(naked) ReadKillCounter() {
|
||||
__asm {
|
||||
cmp eax, 38;
|
||||
jle func;
|
||||
xor eax, eax;
|
||||
ret;
|
||||
func:
|
||||
push ebx;
|
||||
lea ebx, ds:[_pc_kill_counts+eax*2];
|
||||
xor eax,eax;
|
||||
mov ax, word ptr [ebx]
|
||||
pop ebx;
|
||||
ret;
|
||||
movzx eax, word ptr ds:[_pc_kill_counts][eax * 2];
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) IncKillCounter(DWORD killtype) {
|
||||
//if(killtype>38) return;
|
||||
//((WORD*)_pc_kill_counts)[killtype]++;
|
||||
static void __declspec(naked) IncKillCounter() {
|
||||
__asm {
|
||||
cmp eax, 38;
|
||||
jle func;
|
||||
ret;
|
||||
func:
|
||||
push ebx;
|
||||
lea ebx, ds:[_pc_kill_counts+eax*2];
|
||||
xor eax, eax;
|
||||
mov ax, word ptr [ebx];
|
||||
inc ax;
|
||||
mov word ptr [ebx], ax;
|
||||
pop ebx;
|
||||
ret;
|
||||
}
|
||||
inc bx;
|
||||
mov word ptr ds:[_pc_kill_counts][edx], bx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void KillCounterInit(bool use) {
|
||||
if (!use) {
|
||||
usingExtraKillTypes = 0;
|
||||
return;
|
||||
}
|
||||
void KillCounterInit() {
|
||||
usingExtraKillTypes = 1;
|
||||
|
||||
//Overwrite the function that reads the kill counter with my own
|
||||
HookCall(0x4344BF, &ReadKillCounter);
|
||||
HookCall(0x43A162, &ReadKillCounter);
|
||||
HookCall(0x4571D8, &ReadKillCounter);
|
||||
// Overwrite the critter_kill_count_ function that reads the kill counter
|
||||
MakeCall(0x42D8B5, ReadKillCounter, 2);
|
||||
|
||||
//Overwrite the function that increments the kill counter with my own
|
||||
HookCall(0x425144, &IncKillCounter);
|
||||
// Overwrite the critter_kill_count_inc_ function that increments the kill counter
|
||||
MakeCall(0x42D89C, IncKillCounter, 1);
|
||||
SafeWrite8(0x42D88E, 0x45); // lea edx, [eax * 2]
|
||||
SafeWrite8(0x42D899, 0x90); // inc ebx > nop
|
||||
|
||||
//Edit the GetKillTypeName function to accept kill types over 0x13
|
||||
SafeWrite8(0x42D980, 38);
|
||||
SafeWrite8(0x42D990, 38);
|
||||
|
||||
//And the same for GetKillTypeDesc
|
||||
SafeWrite8(0x42D9C0, 38);
|
||||
SafeWrite8(0x42D9D0, 38);
|
||||
// Edit the functions to accept kill types over 19
|
||||
for (int i = 0; i < sizeof(extraKillTypesCountAddr) / 4; i++) {
|
||||
SafeWrite8(extraKillTypesCountAddr[i], 38);
|
||||
}
|
||||
SafeWrite32(0x42D9DD, 1488);
|
||||
|
||||
//Change char sheet to loop through the extra kill types
|
||||
SafeWrite8(0x4344E4, 38);
|
||||
|
||||
//Where fallout clears the counters
|
||||
/*SafeWrite32(0x42CF5E, sizeof(KillCounters));
|
||||
SafeWrite32(0x42CFEC, sizeof(KillCounters));
|
||||
SafeWrite32(0x42D863, sizeof(KillCounters));
|
||||
SafeWrite32(0x42CF63, (DWORD)KillCounters);
|
||||
SafeWrite32(0x42CFF1, (DWORD)KillCounters);
|
||||
SafeWrite32(0x42D868, (DWORD)KillCounters);
|
||||
|
||||
//Where fallout increments the kill counter
|
||||
SafeWrite8(0x42D881, COUNTERS);
|
||||
SafeWrite32(0x42D895, (DWORD)KillCounters);
|
||||
SafeWrite32(0x42D89E, (DWORD)KillCounters);
|
||||
|
||||
//A function that reads the kill counter
|
||||
SafeWrite8(0x42D8AF, COUNTERS);
|
||||
SafeWrite32(0x42D8B8, (DWORD)KillCounters);
|
||||
|
||||
//Not sure what these two do. Possibly related to loading the names/descriptions?
|
||||
SafeWrite32(0x42D8C6, COUNTERS); //This one causes a crash on load?
|
||||
SafeWrite32(0x42D8CB, (DWORD)KillCounters);
|
||||
|
||||
SafeWrite32(0x42D8F6, COUNTERS);
|
||||
SafeWrite32(0x42D8FB, (DWORD)KillCounters);*/
|
||||
}
|
||||
|
||||
+2
-2
@@ -18,5 +18,5 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void KillCounterInit(bool use);
|
||||
bool UsingExtraKillTypes();
|
||||
void KillCounterInit();
|
||||
bool UsingExtraKillTypes();
|
||||
|
||||
+2
-2
@@ -1017,9 +1017,9 @@ static void DllMain2() {
|
||||
|
||||
if (GetPrivateProfileIntA("Misc", "ExtraKillTypes", 0, ini)) {
|
||||
dlog("Applying extra kill types patch.", DL_INIT);
|
||||
KillCounterInit(true);
|
||||
KillCounterInit();
|
||||
dlogr(" Done", DL_INIT);
|
||||
} else KillCounterInit(false);
|
||||
}
|
||||
|
||||
//if (GetPrivateProfileIntA("Misc", "ScriptExtender", 0, ini)) {
|
||||
dlog("Applying script extender patch.", DL_INIT);
|
||||
|
||||
Reference in New Issue
Block a user