Refactored ASM code in KillCounter.cpp.

Reformatted and tweaked code in Explosions.cpp.
This commit is contained in:
NovaRain
2019-01-03 11:07:57 +08:00
parent 9ddddcc120
commit 78815425e2
4 changed files with 102 additions and 152 deletions
+64 -69
View File
@@ -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
View File
@@ -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
View File
@@ -18,5 +18,5 @@
#pragma once
void KillCounterInit(bool use);
bool UsingExtraKillTypes();
void KillCounterInit();
bool UsingExtraKillTypes();
+2 -2
View File
@@ -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);