From 17aa20109fc2c2d635b32fc0ea94ce2698e573d1 Mon Sep 17 00:00:00 2001
From: Akash Mozumdar <akashmozumdar@gmail.com>
Date: Mon, 30 Sep 2019 08:34:07 -0400
Subject: [PATCH] ponscripter hook

---
 texthook/engine/engine.cc  | 27 +++++++++++++++++++++++++++
 texthook/engine/engine.h   |  1 +
 texthook/engine/match32.cc |  5 +++++
 3 files changed, 33 insertions(+)

diff --git a/texthook/engine/engine.cc b/texthook/engine/engine.cc
index 2d85081..cb37c55 100644
--- a/texthook/engine/engine.cc
+++ b/texthook/engine/engine.cc
@@ -12596,6 +12596,33 @@ bool InsertPalHook() // use Old Pal first, which does not have ruby
 	return InsertOldPalHook() || InsertNewPal1Hook() || InsertNewPal2Hook(); 
 }
 
+bool InsertPONScripterHook()
+{
+	if (DWORD str = MemDbg::findBytes("CBString::Failure in (CBString", 30, processStartAddress, processStopAddress))
+	{
+		if (DWORD calledAt = MemDbg::findBytes(&str, sizeof(str), processStartAddress, processStopAddress))
+		{
+			DWORD funcs[] = { 0xec8b55, 0xe58955 };
+			DWORD addr = MemDbg::findBytes(funcs, 3, calledAt - 0x100, calledAt);
+			if (!addr) addr = MemDbg::findBytes(funcs + 1, 3, calledAt - 0x100, calledAt);
+			if (addr)
+			{
+				HookParam hp = {};
+				hp.address = addr;
+				hp.type = USING_STRING | USING_UTF8 | DATA_INDIRECT;
+				hp.offset = 4;
+				hp.index = 0xc;
+				NewHook(hp, "PONScripter");
+				return true;
+			}
+			else ConsoleOutput("Textractor: failed to find function start");
+		}
+		else ConsoleOutput("Textractor: failed to find string reference");
+	}
+	else ConsoleOutput("Textractor: failed to find string");
+	return false;
+}
+
 /** jichi 7/6/2014 NeXAS
  *  Sample game: BALDRSKYZERO EXTREME
  *
diff --git a/texthook/engine/engine.h b/texthook/engine/engine.h
index 4b292bc..4fb3acf 100644
--- a/texthook/engine/engine.h
+++ b/texthook/engine/engine.h
@@ -136,6 +136,7 @@ bool InsertNexton1Hook();
 bool InsertNitroplusHook();     // Nitroplus: *.npa
 bool InsertPalHook();           // AMUSE CRAFT: *.pac
 bool InsertPensilHook();        // Pensil: PSetup.exe
+bool InsertPONScripterHook();
 bool InsertQLIEHook();          // QLiE: GameData/*.pack
 //bool InsertRai7Hook();          // Rai7puk: rai7.exe
 bool InsertRejetHook();         // Rejet: Module/{gd.dat,pf.dat,sd.dat}
diff --git a/texthook/engine/match32.cc b/texthook/engine/match32.cc
index f21b6e4..e6eacfa 100644
--- a/texthook/engine/match32.cc
+++ b/texthook/engine/match32.cc
@@ -80,6 +80,11 @@ bool DeterminePCEngine()
 
 bool DetermineEngineByFile1()
 {
+	if (Util::SearchResourceString(L"Proportional ONScripter"))
+	{
+		InsertPONScripterHook();
+		return true;
+	}
   // Artikash 7/14/2018: AIRNovel - sample game https://vndb.org/v18814
   if (Util::CheckFile(L"*.swf"))
   {