From 96a93d69434e6a4e8b873ea539b4227358cadcb0 Mon Sep 17 00:00:00 2001
From: CCHyper <73803386+CCHyper@users.noreply.github.com>
Date: Sat, 23 Jul 2022 14:33:12 +0100
Subject: [PATCH] Adds patch to fix VQA_MixFileHandler to allow VQA movies to
be loaded from local paths.
---
src/extensions/ext_hooks.cpp | 2 +
src/extensions/vqa/vqaext_hooks.cpp | 98 +++++++++++++++++++++++++++++
src/extensions/vqa/vqaext_hooks.h | 31 +++++++++
3 files changed, 131 insertions(+)
create mode 100644 src/extensions/vqa/vqaext_hooks.cpp
create mode 100644 src/extensions/vqa/vqaext_hooks.h
diff --git a/src/extensions/ext_hooks.cpp b/src/extensions/ext_hooks.cpp
index 1f2d405d6..975b0cc92 100644
--- a/src/extensions/ext_hooks.cpp
+++ b/src/extensions/ext_hooks.cpp
@@ -49,6 +49,7 @@
#include "cdext_hooks.h"
#include "playmovie_hooks.h"
+#include "vqaext_hooks.h"
#include "themeext_hooks.h"
#include "objecttypeext_hooks.h"
@@ -229,6 +230,7 @@ void Extension_Hooks()
CombatExtension_Hooks();
PlayMovieExtension_Hooks();
+ VQAExtension_Hooks();
ThemeClassExtension_Hooks();
TextLabelClassExtension_Hooks();
diff --git a/src/extensions/vqa/vqaext_hooks.cpp b/src/extensions/vqa/vqaext_hooks.cpp
new file mode 100644
index 000000000..8cf67d25e
--- /dev/null
+++ b/src/extensions/vqa/vqaext_hooks.cpp
@@ -0,0 +1,98 @@
+/*******************************************************************************
+/* O P E N S O U R C E -- V I N I F E R A **
+/*******************************************************************************
+ *
+ * @project Vinifera
+ *
+ * @file VQAEXT_HOOKS.CPP
+ *
+ * @author CCHyper
+ *
+ * @brief Contains the hooks for the extended VQAClass.
+ *
+ * @license Vinifera is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version
+ * 3 of the License, or (at your option) any later version.
+ *
+ * Vinifera is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ * If not, see .
+ *
+ ******************************************************************************/
+#include "vqaext_hooks.h"
+#include "vqa.h"
+#include "debughandler.h"
+#include "asserthandler.h"
+
+#include "hooker.h"
+#include "hooker_macros.h"
+
+
+/**
+ * #issue-87
+ *
+ * Patch to use CCFileClass instead of MixFileClass when loading VQA files. This
+ * allows VQA files to be loaded from the games root directory.
+ *
+ * @author: CCHyper
+ */
+DECLARE_PATCH(_VQA_Mix_File_Handler_Use_CCFileClass_Patch)
+{
+ GET_REGISTER_STATIC(VQAClass *, this_ptr, esi);
+ GET_STACK_STATIC(char *, filename, esp, 0xC);
+
+ static int error;
+
+ /**
+ * Original code used MixFileClass::Offset to find the file, this limited
+ * the VQA file streamer to only be able to load files from mix files.
+ */
+#if 0
+ static MFCC *mixfile;
+ static long offset;
+ if (!MFCC::Offset(this_ptr->Filename, nullptr, &mixfile, &offset)) {
+ error = 1;
+ } else {
+ this_ptr->field_64 = this_ptr->File.Open(mixfile->Filename, FILE_ACCESS_READ);
+ error = (this_ptr->File.Seek(offset, FILE_SEEK_CURRENT) == 0);
+ }
+#endif
+
+ /**
+ * ...Now we use CCFileClass, which does use MixFileClass to search for
+ * the file, but also scans for the file locally first.
+ */
+ this_ptr->File.Set_Name(filename);
+
+ // #REMOVED: This fails as CDFileClass does not implement Is_Available to search the paths.
+ //if (this_ptr->File.Is_Available()) {
+ // error = 1;
+ // goto exit_label;
+ //}
+
+ this_ptr->field_64 = this_ptr->File.Open(FILE_ACCESS_READ);
+
+ error = !this_ptr->field_64;
+
+exit_label:
+ _asm { xor eax, eax }
+ _asm { cmp error, 0 }
+ _asm { setnz al }
+ _asm { pop esi }
+ _asm { ret 0x0C }
+}
+
+
+/**
+ * Main function for patching the hooks.
+ */
+void VQAExtension_Hooks()
+{
+ Patch_Jump(0x0066C0FD, _VQA_Mix_File_Handler_Use_CCFileClass_Patch);
+}
diff --git a/src/extensions/vqa/vqaext_hooks.h b/src/extensions/vqa/vqaext_hooks.h
new file mode 100644
index 000000000..8379af58b
--- /dev/null
+++ b/src/extensions/vqa/vqaext_hooks.h
@@ -0,0 +1,31 @@
+/*******************************************************************************
+/* O P E N S O U R C E -- V I N I F E R A **
+/*******************************************************************************
+ *
+ * @project Vinifera
+ *
+ * @file VQAEXT_HOOKS.H
+ *
+ * @author CCHyper
+ *
+ * @brief Contains the hooks for the extended VQAClass.
+ *
+ * @license Vinifera is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version
+ * 3 of the License, or (at your option) any later version.
+ *
+ * Vinifera is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program.
+ * If not, see .
+ *
+ ******************************************************************************/
+#pragma once
+
+
+void VQAExtension_Hooks();