Browse Source

Added text documenting game functions

master
1 year ago
parent
commit
ea61ce429f
3 changed files with 255 additions and 0 deletions
  1. 74
    0
      docs/continue.txt
  2. 106
    0
      docs/dante-change-devil-arm.txt
  3. 75
    0
      docs/update-acquired-redorbs.txt

+ 74
- 0
docs/continue.txt View File

@@ -0,0 +1,74 @@
Devil May Cry 4: Special Edition
Function Documentation
Mediator::Continue

Context: This function is called when the player dies and selects Continue on the menu.

dmc4se.exe+10D2B0 - xorps xmm1,xmm1 ; xmm1 = 0
dmc4se.exe+10D2B3 - push ebx ;
dmc4se.exe+10D2B4 - push esi ;
dmc4se.exe+10D2B5 - mov esi,ecx ;
dmc4se.exe+10D2B7 - mov eax,[esi+3C] ;
dmc4se.exe+10D2BA - mov ecx,[esi+40] ;
dmc4se.exe+10D2BD - mov [esi+34],eax ;
dmc4se.exe+10D2C0 - mov [esi+38],ecx ;
dmc4se.exe+10D2C3 - mov eax,[esi+60] ;
dmc4se.exe+10D2C6 - mov ebx,00000001 ;
dmc4se.exe+10D2CB - test eax,eax ;
dmc4se.exe+10D2CD - je dmc4se.exe+10D2E7 ;
dmc4se.exe+10D2CF - nop ;

dmc4se.exe+10D2D0 - mov dx,[eax+0A] ;
dmc4se.exe+10D2D4 - mov [eax+08],dx ;
dmc4se.exe+10D2D8 - movss [eax+0C],xmm1 ;
dmc4se.exe+10D2DD - mov [eax+10],bl
dmc4se.exe+10D2E0 - mov eax,[eax+14] ;
dmc4se.exe+10D2E3 - test eax,eax ;
dmc4se.exe+10D2E5 - jne dmc4se.exe+10D2D0 ;

dmc4se.exe+10D2E7 - mov edx,[Game Mediator] ; edx = mediator
dmc4se.exe+10D2ED - lea eax,[edx+30] ;
dmc4se.exe+10D2F0 - call dmc4se.exe+19ACE0 ;
dmc4se.exe+10D2F5 - mov [edx+00000250],00000000 ;
dmc4se.exe+10D2FF - movss [edx+0000024C],xmm1 ;
dmc4se.exe+10D307 - mov [edx+00000260],bl ;
dmc4se.exe+10D30D - add [edx+000001B0],ebx ; add ebx to continue count
dmc4se.exe+10D313 - cmp dword ptr [edx+000001B0],63 ;
dmc4se.exe+10D31A - jle dmc4se.exe+10D326 ;
dmc4se.exe+10D31C - mov [edx+000001B0],00000063 ;

dmc4se.exe+10D326 - mov [edx+000001B4],00000003 ; hell mode gold orbs = 3
dmc4se.exe+10D330 - cmp dword ptr [edx+00000240],04 ; check if difficulty is LDK
dmc4se.exe+10D337 - jne dmc4se.exe+10D388 ; jump to end of function
dmc4se.exe+10D339 - mov eax,[edx+00000150] ; eax = mission number
dmc4se.exe+10D33F - cmp eax,61 ; check if mission # is 97
dmc4se.exe+10D342 - je dmc4se.exe+10D34E ;
dmc4se.exe+10D344 - cmp eax,62 ; check if mission # is 98
dmc4se.exe+10D347 - je dmc4se.exe+10D34E ;
dmc4se.exe+10D349 - cmp eax,63 ; check if mission # is 99
dmc4se.exe+10D34C - jne dmc4se.exe+10D361 ;

dmc4se.exe+10D34E - mov eax,00000002 ;
dmc4se.exe+10D353 - lea eax,[eax+eax*4] ;
dmc4se.exe+10D356 - movss xmm0,[eax*4+dmc4se.exe+E7AC44] ;
dmc4se.exe+10D35F - jmp dmc4se.exe+10D380 ;

dmc4se.exe+10D361 - cmp eax,ebx ;
dmc4se.exe+10D363 - jb dmc4se.exe+10D378 ;
dmc4se.exe+10D365 - cmp eax,14 ;
dmc4se.exe+10D368 - ja dmc4se.exe+10D378 ;
dmc4se.exe+10D36A - lea eax,[eax+eax*4] ;
dmc4se.exe+10D36D - movss xmm0,[eax*4+dmc4se.exe+E7AC44] ;
dmc4se.exe+10D376 - jmp dmc4se.exe+10D380 ;

dmc4se.exe+10D378 - movss xmm0,[dmc4se.exe+D492E0] ;

dmc4se.exe+10D380 - movss [edx+000001AC],xmm0 ;

dmc4se.exe+10D388 - mov edx,[esi] ;
dmc4se.exe+10D38A - mov eax,[edx+54] ;
dmc4se.exe+10D38D - mov ecx,esi ;
dmc4se.exe+10D38F - pop esi ;
dmc4se.exe+10D390 - pop ebx ;
dmc4se.exe+10D391 - jmp eax ;
dmc4se.exe+10D393 - int 3 ;

+ 106
- 0
docs/dante-change-devil-arm.txt View File

@@ -0,0 +1,106 @@
Devil May Cry 4: Special Edition
Function Documentation
Dante, Weapon Switching (Devil Arm) Function

Context
This function executes right when the player presses the key for switching Dante's Devil Arms.


Disassembler Output
The only change is that the executable name, DevilMayCry4SpecialEdition, is abbreviated to dmc4se.exe.

;int 3
;int 3

dmc4se.exe+DE030 - mov edx,[edi+2C] ; edx = current devil arm
dmc4se.exe+DE033 - push esi ;
dmc4se.exe+DE034 - mov esi,[edi+24] ; esi = start of weapon id array
dmc4se.exe+DE037 - mov eax,esi ; eax = start of weapon id array
dmc4se.exe+DE039 - mov ecx,[eax] ; ecx = first weapon in array
dmc4se.exe+DE03B - jmp dmc4se.exe+DE040 ;
dmc4se.exe+DE03D - lea ecx,[ecx+00] ;

dmc4se.exe+DE040 - cmp edx,ecx ; compare current weapon w/ 1st weapn
dmc4se.exe+DE042 - je dmc4se.exe+DE04F ; jump if equal
dmc4se.exe+DE044 - mov ecx,[eax+04] ; ecx = next weapon in array
dmc4se.exe+DE047 - add eax,04 ; increment array index
dmc4se.exe+DE04A - cmp ecx,-01 ; check if end of array
dmc4se.exe+DE04D - jne dmc4se.exe+DE040 ; go back to loop

dmc4se.exe+DE04F - add eax,04 ; increment array index
dmc4se.exe+DE052 - cmp dword ptr [eax],-01 ; check if eax is at the end
dmc4se.exe+DE055 - cmove eax,esi ; conditionally move esi to eax
dmc4se.exe+DE058 - mov eax,[eax] ;
dmc4se.exe+DE05A - pop esi ;
dmc4se.exe+DE05B - cmp edx,eax ; compare current wpn with new wpn
dmc4se.exe+DE05D - je dmc4se.exe+DE065 ; jump to end of function
dmc4se.exe+DE05F - mov [edi+2C],eax ; write new wpn to memory
dmc4se.exe+DE062 - mov al,01 ; set al 1 to 1
dmc4se.exe+DE064 - ret ; return true

dmc4se.exe+DE065 - xor al,al ; set al to 0
dmc4se.exe+DE067 - ret ; return false

;int 3
;int 3

Reformated Assembly
The address data is removed or replaced with labels.

switch_devilarm:
mov edx,[edi+2C] ; edx = current devil arm
push esi ;
mov esi,[edi+24] ; esi = start of weapon id array
mov eax,esi ; eax = start of weapon id array
mov ecx,[eax] ; ecx = first weapon in array
jmp loop ;
lea ecx,[ecx+00] ;

loop:
cmp edx,ecx ; compare current weapon w/ 1st weapn
je post_loop ; jump if equal
mov ecx,[eax+04] ; ecx = next weapon in array
add eax,04 ; increment array index
cmp ecx,-01 ; check if end of array
jne loop ; go back to loop

post_loop:
add eax,04 ; increment array index
cmp dword ptr [eax],-01 ; check if eax is at the end
cmove eax,esi ; conditionally move esi to eax
mov eax,[eax] ;
pop esi ; esi = player address
cmp edx,eax ; compare current wpn with new wpn
je false ; jump to end of function
mov [edi+2C],eax ; write new wpn to memory
mov al,01 ; set al 1 to 1
ret ; return true

false:
xor al,al ; set al to 0
ret ; return false

C++
This may not be an actual function under the Dante object because it does not actually use a pointer to the player.

bool switch_devilarm(WeaponCtrl *w) {
int current_wpn = w -> current_devilarm;
int * const weapon_ids = w -> weapon_ids; // "esi"
int *copy = weapon_ids; // "eax"
int i = 0;
int cmp_against = copy[i];
while (current_wpn != cmp_against && cmp_against != -1) {
cmp_against = copy[++i]; //absolutely must be prefix increment!
copy++;
}
copy++;
if (copy[0] == -1) {
copy = weapon_ids;
}
int new_wpn = copy[0];
if (new_wpn == current_wpn) {
return false;
}
w -> current_devilarm = new_wpn;
return true;
}

+ 75
- 0
docs/update-acquired-redorbs.txt View File

@@ -0,0 +1,75 @@
Devil May Cry 4: Special Edition
Function Documentation
Update 'Red Orbs Acquired' Count

Context: This function executes right when the player collides with a Red Orb in the game.
This function is not responsible for adding the total amount of Red Orbs, the player holds in a mission.
x86 calling convention is stdcall.

Disassembled Output
; this function takes one parameter from stack, value of red orb.
dmc4se.exe+19A660 - push esi ;
dmc4se.exe+19A661 - mov esi,eax ; esi = ptr to mediator
dmc4se.exe+19A663 - cmp byte ptr [esi+1C],00 ;
dmc4se.exe+19A667 - jne dmc4se.exe+19A672 ; jump to ntdll fn (enter).
dmc4se.exe+19A669 - cmp byte ptr [dmc4se.exe+F23A58],00 ;
dmc4se.exe+19A670 - je dmc4se.exe+19A67C ; jump to critical section

dmc4se.exe+19A672 - lea eax,[esi+04] ;
dmc4se.exe+19A675 - push eax ;
dmc4se.exe+19A676 - call dword ptr [dmc4se.exe+B73198] ; ntdll.EnterCriticalSection

dmc4se.exe+19A67C - cmp byte ptr [esi+0000019A],00 ; check if ignoring acquired orbs in a mission
dmc4se.exe+19A683 - jne dmc4se.exe+19A68F ; jump if ignoring
dmc4se.exe+19A685 - mov ecx,[esp+08] ; ecx = red orb value (on stack)
dmc4se.exe+19A689 - add [esi+0000018C],ecx ; write to memory

dmc4se.exe+19A68F - cmp byte ptr [esi+1C],00 ;
dmc4se.exe+19A693 - jne dmc4se.exe+19A69E ; jump to ntdll fn (exit).
dmc4se.exe+19A695 - cmp byte ptr [dmc4se.exe+F23A58],00 ;
dmc4se.exe+19A69C - je dmc4se.exe+19A6A8 ; skip win32 api thread synch fn (exit)

dmc4se.exe+19A69E - add esi,04 ; add to mediator ptr
dmc4se.exe+19A6A1 - push esi ; push to stack as parameter
dmc4se.exe+19A6A2 - call dword ptr [dmc4se.exe+B731A0] ; ntdll.ExitCriticalSection

dmc4se.exe+19A6A8 - pop esi ;
dmc4se.exe+19A6A9 - ret 0004 ; stdcall: one parameter

Reformated Assembly
; this function takes one parameter from stack, value of red orb.
update_redorbsacquired_count:
push esi ;
mov esi,eax ; esi = ptr to mediator
cmp byte ptr [esi+1C],00 ;
jne enter ; jump to ntdll fn (enter).
cmp byte ptr [dmc4se.exe+F23A58],00 ;
je critical_section ; jump to critical section

enter:
lea eax,[esi+04] ;
push eax ;
call dword ptr [dmc4se.exe+B73198] ; ntdll.EnterCriticalSection

critical_section:
cmp byte ptr [esi+0000019A],00 ; check if ignoring acquired orbs in a mission
jne dmc4se.exe+19A68F ; jump if ignoring
mov ecx,[esp+08] ; ecx = red orb value (on stack)
add [esi+0000018C],ecx ; write to memory

cmp byte ptr [esi+1C],00 ;
jne exit ; jump to ntdll fn (exit).
cmp byte ptr [dmc4se.exe+F23A58],00 ;
je return ; skip win32 api thread synch fn (exit)

exit:
add esi,04 ; add to mediator ptr
push esi ; push to stack as parameter
call dword ptr [dmc4se.exe+B731A0] ; ntdll.ExitCriticalSection

return:
pop esi ;
ret 0004 ; stdcall: one parameter

C++ (prototype)
void update_redorbs_acquired(orb_value);

Loading…
Cancel
Save