OVR: Move player with controller to the direction it points to
[mercenary-reloaded.git] / src / mercenary / mercenary2.c
index 55449d2..74d9c29 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <stdio.h>
+#include <string.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <math.h>
@@ -30,6 +31,9 @@
 #define        INITIAL_STACK   0x7fffa
 #define RESET_VECTOR   0x59484
 
+/* VR heading to alter direction we walk to */
+static struct vr_move vr_move;
+
 /* interrupt CPU execution at special break points and tell emulation what to do */
 const struct cpu_stop mercenary_stop_at[] = {
        { 0x59a4e,      STOP_AT_WAIT_VBL },                     /* done with rendering, waiting for VBL */
@@ -108,6 +112,7 @@ const struct cpu_stop mercenary_stop_at[] = {
        { 0x528C4,      STOP_AT_PATCH_RENDER },                 /* patch away planet check (behind observer) */
        { 0x45806,      STOP_AT_PATCH_RENDER },                 /* patch away planet rendering (would crash without check above) */
        { 0x53276,      STOP_AT_PATCH_RENDER },                 /* patch away beacon check (not visible on screen) */
+       { 0x58EA8,      STOP_AT_PATCH_VR },                     /* step that moves player */
        { 0x0,          STOP_AT_END },                          /* end */
 };
 
@@ -118,6 +123,8 @@ void mercenary_load(void)
 {
        int i;
 
+       memset(&vr_move, 0, sizeof(vr_move));
+
        /* load game binary from constant to volatile memory */
        for (i = 0; i < mercenary2_hex_size; i += 4) {
                m68k_write_memory_32(i, mercenary2_hex[i / 4]);
@@ -183,6 +190,20 @@ void mercenary_patch_render(void)
        }
 }
 
+/* patch execution for VR improvement */
+void mercenary_patch_vr(void)
+{
+       switch (REG_PC) {
+       case 0x58EA8: /* at this point we process one step of the player walking on the ground */
+               if (vr_move.override && vr_move.index < 4) {
+                       REG_D[2] = vr_move.east[vr_move.index];
+                       REG_D[3] = vr_move.north[vr_move.index];
+                       vr_move.index++;
+               }
+               break;
+       }
+}
+
 uint32_t mercenary_palette_view(void)
 {
        return m68k_read_memory_32(0x007c14);
@@ -303,6 +324,15 @@ uint32_t mercenary_star_table(void)
        return 0x005D8C0;
 }
 
+void mercenary_vr_move(int override, int32_t *east, int32_t *north)
+{
+       vr_move.override = override;
+       if (east)
+               memcpy(vr_move.east, east, sizeof(vr_move.east));
+       if (north)
+               memcpy(vr_move.north, north, sizeof(vr_move.north));
+       vr_move.index = 0;
+}
 const char *mercenary_name = "Mercenary II - Damocles";
 const char *mercenary_gamesavesuffix = ".m2save";