(Lua, ASMx86) Replication of Devil May Cry 4's debug functions for it's re-released version.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dante-change-devil-arm.txt 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. Devil May Cry 4: Special Edition
  2. Function Documentation
  3. Dante, Weapon Switching (Devil Arm) Function
  4. Context
  5. This function executes right when the player presses the key for switching Dante's Devil Arms.
  6. Disassembler Output
  7. The only change is that the executable name, DevilMayCry4SpecialEdition, is abbreviated to dmc4se.exe.
  8. ;int 3
  9. ;int 3
  10. dmc4se.exe+DE030 - mov edx,[edi+2C] ; edx = current devil arm
  11. dmc4se.exe+DE033 - push esi ;
  12. dmc4se.exe+DE034 - mov esi,[edi+24] ; esi = start of weapon id array
  13. dmc4se.exe+DE037 - mov eax,esi ; eax = start of weapon id array
  14. dmc4se.exe+DE039 - mov ecx,[eax] ; ecx = first weapon in array
  15. dmc4se.exe+DE03B - jmp dmc4se.exe+DE040 ;
  16. dmc4se.exe+DE03D - lea ecx,[ecx+00] ;
  17. dmc4se.exe+DE040 - cmp edx,ecx ; compare current weapon w/ 1st weapn
  18. dmc4se.exe+DE042 - je dmc4se.exe+DE04F ; jump if equal
  19. dmc4se.exe+DE044 - mov ecx,[eax+04] ; ecx = next weapon in array
  20. dmc4se.exe+DE047 - add eax,04 ; increment array index
  21. dmc4se.exe+DE04A - cmp ecx,-01 ; check if end of array
  22. dmc4se.exe+DE04D - jne dmc4se.exe+DE040 ; go back to loop
  23. dmc4se.exe+DE04F - add eax,04 ; increment array index
  24. dmc4se.exe+DE052 - cmp dword ptr [eax],-01 ; check if eax is at the end
  25. dmc4se.exe+DE055 - cmove eax,esi ; conditionally move esi to eax
  26. dmc4se.exe+DE058 - mov eax,[eax] ;
  27. dmc4se.exe+DE05A - pop esi ;
  28. dmc4se.exe+DE05B - cmp edx,eax ; compare current wpn with new wpn
  29. dmc4se.exe+DE05D - je dmc4se.exe+DE065 ; jump to end of function
  30. dmc4se.exe+DE05F - mov [edi+2C],eax ; write new wpn to memory
  31. dmc4se.exe+DE062 - mov al,01 ; set al 1 to 1
  32. dmc4se.exe+DE064 - ret ; return true
  33. dmc4se.exe+DE065 - xor al,al ; set al to 0
  34. dmc4se.exe+DE067 - ret ; return false
  35. ;int 3
  36. ;int 3
  37. Reformated Assembly
  38. The address data is removed or replaced with labels.
  39. switch_devilarm:
  40. mov edx,[edi+2C] ; edx = current devil arm
  41. push esi ;
  42. mov esi,[edi+24] ; esi = start of weapon id array
  43. mov eax,esi ; eax = start of weapon id array
  44. mov ecx,[eax] ; ecx = first weapon in array
  45. jmp loop ;
  46. lea ecx,[ecx+00] ;
  47. loop:
  48. cmp edx,ecx ; compare current weapon w/ 1st weapn
  49. je post_loop ; jump if equal
  50. mov ecx,[eax+04] ; ecx = next weapon in array
  51. add eax,04 ; increment array index
  52. cmp ecx,-01 ; check if end of array
  53. jne loop ; go back to loop
  54. post_loop:
  55. add eax,04 ; increment array index
  56. cmp dword ptr [eax],-01 ; check if eax is at the end
  57. cmove eax,esi ; conditionally move esi to eax
  58. mov eax,[eax] ;
  59. pop esi ; esi = player address
  60. cmp edx,eax ; compare current wpn with new wpn
  61. je false ; jump to end of function
  62. mov [edi+2C],eax ; write new wpn to memory
  63. mov al,01 ; set al 1 to 1
  64. ret ; return true
  65. false:
  66. xor al,al ; set al to 0
  67. ret ; return false
  68. C++
  69. This may not be an actual function under the Dante object because it does not actually use a pointer to the player.
  70. bool switch_devilarm(WeaponCtrl *w) {
  71. int current_wpn = w -> current_devilarm;
  72. int * const weapon_ids = w -> weapon_ids; // "esi"
  73. int *copy = weapon_ids; // "eax"
  74. int i = 0;
  75. int cmp_against = copy[i];
  76. while (current_wpn != cmp_against && cmp_against != -1) {
  77. cmp_against = copy[++i]; //absolutely must be prefix increment!
  78. copy++;
  79. }
  80. copy++;
  81. if (copy[0] == -1) {
  82. copy = weapon_ids;
  83. }
  84. int new_wpn = copy[0];
  85. if (new_wpn == current_wpn) {
  86. return false;
  87. }
  88. w -> current_devilarm = new_wpn;
  89. return true;
  90. }