Rename project to sacredK
sacred_re.dll/.exe/.ini/.log/_crash files are now sacredK.*; inventory saves with the old "sacred_re.inventory" format id still load. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
462ebf8c0b
commit
70673dc301
34 files changed
+95
-93
No files matched your search
@@ -7,7 +7,7 @@
|
||||
// optional callback (0x017e5ee4) and to either OutputDebugString or the
|
||||
// in-game console object (0x017e5edc).
|
||||
//
|
||||
// Status: hooked, not rewritten. Every message is mirrored into sacred_re.log
|
||||
// Status: hooked, not rewritten. Every message is mirrored into sacredK.log
|
||||
// whether or not the game's own logging is enabled, then forwarded.
|
||||
|
||||
#include "game/engine/log.h"
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// sacred_re.exe: starts sacred.exe with sacred_re.dll injected.
|
||||
// sacredK.exe: starts sacred.exe with sacredK.dll injected.
|
||||
//
|
||||
// sacred_re.exe [--game-dir <dir>] [game arguments...]
|
||||
// sacredK.exe [--game-dir <dir>] [game arguments...]
|
||||
//
|
||||
// The game directory comes from --game-dir (which is then remembered in
|
||||
// sacred_re.ini), else from [paths] GameDir in sacred_re.ini, else the
|
||||
// sacredK.ini), else from [paths] GameDir in sacredK.ini, else the
|
||||
// launcher's own directory. Remaining arguments are passed to the game
|
||||
// unchanged, e.g. `sacred_re.exe log` enables the game's DEBUG.LOG.
|
||||
// unchanged, e.g. `sacredK.exe log` enables the game's DEBUG.LOG.
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -35,7 +35,7 @@ std::wstring WithTrailingSlash(std::wstring dir) {
|
||||
}
|
||||
|
||||
int Fail(const std::wstring& message) {
|
||||
MessageBoxW(nullptr, message.c_str(), L"sacred_re", MB_OK | MB_ICONERROR);
|
||||
MessageBoxW(nullptr, message.c_str(), L"sacredK", MB_OK | MB_ICONERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ int Fail(const std::wstring& message) {
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
|
||||
const std::wstring launcherDir = ExeDir();
|
||||
const std::wstring ini = launcherDir + L"sacred_re.ini";
|
||||
const std::wstring ini = launcherDir + L"sacredK.ini";
|
||||
|
||||
int argc = 0;
|
||||
wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
@@ -71,12 +71,12 @@ int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
|
||||
const std::wstring gameExe = gameDir + L"sacred.exe";
|
||||
if (!FileExists(gameExe)) {
|
||||
return Fail(L"sacred.exe not found in\n" + gameDir +
|
||||
L"\n\nRun once with: sacred_re.exe --game-dir \"<Sacred Gold folder>\"");
|
||||
L"\n\nRun once with: sacredK.exe --game-dir \"<Sacred Gold folder>\"");
|
||||
}
|
||||
|
||||
const std::wstring dllPath = launcherDir + L"sacred_re.dll";
|
||||
const std::wstring dllPath = launcherDir + L"sacredK.dll";
|
||||
if (!FileExists(dllPath)) {
|
||||
return Fail(L"sacred_re.dll not found next to the launcher:\n" + dllPath);
|
||||
return Fail(L"sacredK.dll not found next to the launcher:\n" + dllPath);
|
||||
}
|
||||
// Detours takes the DLL path as ANSI.
|
||||
char dllPathA[MAX_PATH];
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// Mouse positions are mapped back from that rectangle to game pixels, both in
|
||||
// GetMouseClientPos (polled by the game) and in mouse window messages.
|
||||
//
|
||||
// sacred_re.ini:
|
||||
// sacredK.ini:
|
||||
// [borderless]
|
||||
// Enabled=1 ; 0 = original behaviour
|
||||
// IntegerScale=0 ; 1 = scale by whole multiples only (sharper, larger bars)
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace game {
|
||||
// cParticleSystem_burningBone::Render (vf04 0x774e10, vtable 0x895b84):
|
||||
// crashed reading the device it was given, which was null (2026-10-16, Esc
|
||||
// pressed while walking; Windows reported sacred.exe+0x374e39). Who renders
|
||||
// it without a device is not known yet (sacred_re_crash.txt will tell). With
|
||||
// it without a device is not known yet (sacredK_crash.txt will tell). With
|
||||
// no device there is nothing to draw.
|
||||
// (device, a 4x4 matrix by value; ret 0x44).
|
||||
struct Matrix4 {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
// inside both.
|
||||
// The world never sees these offsets: they are only active inside the hooks.
|
||||
//
|
||||
// sacred_re.ini:
|
||||
// sacredK.ini:
|
||||
// [hud]
|
||||
// Enabled=1
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
// off. Alt+key arrives as WM_SYSKEYDOWN and is not handled here anyway.)
|
||||
//
|
||||
// The bindings are set on the options window's key bindings tab
|
||||
// (mods/options.cpp) and kept in sacred_re.ini (key names: kKeyNames below,
|
||||
// (mods/options.cpp) and kept in sacredK.ini (key names: kKeyNames below,
|
||||
// None):
|
||||
// [keys]
|
||||
// SkillSlot0=0 ... SkillSlot6=6 ; cast combat-art slot (0 = right mouse button art)
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ const wchar_t* BindingGroup(int index);
|
||||
int BindingKey(int index); // virtual key, 0 = none
|
||||
int DefaultBindingKey(int index);
|
||||
|
||||
// Sets all bindings (`keys[BindingCount()]`) and writes them to sacred_re.ini.
|
||||
// Sets all bindings (`keys[BindingCount()]`) and writes them to sacredK.ini.
|
||||
void SetBindingKeys(const int* keys);
|
||||
|
||||
// Whether `vk` can be bound, and its name as shown ("Leertaste", "F1", ...).
|
||||
|
||||
@@ -193,7 +193,7 @@ void PutArtSlot(const json& variants, uint8_t* slot) {
|
||||
json ToJson(const std::vector<uint8_t>& block, const uint8_t* shadow) {
|
||||
Reader r(block);
|
||||
json j;
|
||||
j["format"] = "sacred_re.inventory";
|
||||
j["format"] = "sacredK.inventory";
|
||||
j["version"] = kVersion;
|
||||
j["player"] = r.U16();
|
||||
j["flags"] = r.U16();
|
||||
@@ -262,7 +262,9 @@ json ToJson(const std::vector<uint8_t>& block, const uint8_t* shadow) {
|
||||
|
||||
// The original block for slots 1-5; slots 6-7 are applied afterwards.
|
||||
std::vector<uint8_t> ToBlock(const json& j) {
|
||||
if (j.at("format") != "sacred_re.inventory" || j.at("version").get<int>() > kVersion) {
|
||||
// "sacred_re.inventory": saves from before the project was renamed to sacredK.
|
||||
const auto format = j.at("format").get<std::string>();
|
||||
if ((format != "sacredK.inventory" && format != "sacred_re.inventory") || j.at("version").get<int>() > kVersion) {
|
||||
throw std::runtime_error("unknown inventory format / version");
|
||||
}
|
||||
Writer w;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Options window in three tabs: Allgemein, Beute, Tastenbelegung (request of
|
||||
// 2026-10-18). Beute holds the game's auto-pickup settings (first iteration:
|
||||
// moved there from the common page); Tastenbelegung sets the key bindings of
|
||||
// mods/input.cpp, which had only been settable in sacred_re.ini.
|
||||
// mods/input.cpp, which had only been settable in sacredK.ini.
|
||||
//
|
||||
// The window (cUI_Options, vtable 0x89505c, constructor 0x716570 building its
|
||||
// controls in 0x7184e0) is laid out for 1024x768: six frames in two columns
|
||||
|
||||
@@ -334,7 +334,7 @@ void Save() {
|
||||
}
|
||||
}
|
||||
}
|
||||
const json j = {{"format", "sacred_re.shared_chest"}, {"version", kFileVersion}, {"items", items}};
|
||||
const json j = {{"format", "sacredK.shared_chest"}, {"version", kFileVersion}, {"items", items}};
|
||||
const std::string path = FilePath();
|
||||
const std::string temp = path + ".tmp";
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// 1024x768 layout, and set the variables from the render size.
|
||||
// See docs/widescreen.md.
|
||||
//
|
||||
// sacred_re.ini:
|
||||
// sacredK.ini:
|
||||
// [widescreen]
|
||||
// Enabled=1
|
||||
// Height=768 ; world pixels visible vertically (768 = original look);
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
// sacred_re.ini next to sacred_re.dll / sacred_re.exe.
|
||||
// sacredK.ini next to sacredK.dll / sacredK.exe.
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace re {
|
||||
|
||||
void SetConfigPath(const std::wstring& path);
|
||||
const std::wstring& ConfigPath();
|
||||
// Folder of sacred_re.dll (with trailing separator), derived from the config path.
|
||||
// Folder of sacredK.dll (with trailing separator), derived from the config path.
|
||||
std::wstring ModuleDirectory();
|
||||
int ConfigInt(const char* section, const char* key, int fallback);
|
||||
std::string ConfigString(const char* section, const char* key, const char* fallback);
|
||||
|
||||
+7
-7
@@ -1,10 +1,10 @@
|
||||
// Crash report: on an unhandled exception, writes sacred_re_crash.txt (code,
|
||||
// Crash report: on an unhandled exception, writes sacredK_crash.txt (code,
|
||||
// address as module + offset, registers, return addresses found on the stack)
|
||||
// and sacred_re_crash.dmp next to the DLL. The game may install its own
|
||||
// and sacredK_crash.dmp next to the DLL. The game may install its own
|
||||
// filter later; SetUnhandledExceptionFilter is hooked so ours stays first and
|
||||
// passes the crash on to the game's afterwards.
|
||||
//
|
||||
// Hangs: a watchdog thread writes sacred_re_hang.dmp (all threads) when the
|
||||
// Hangs: a watchdog thread writes sacredK_hang.dmp (all threads) when the
|
||||
// engine tick (re::EngineHeartbeat) has stopped for kHangMs while the game
|
||||
// window is in front; once per hang. The game freezing on F2 while walking
|
||||
// (2026-10-18) left no report.
|
||||
@@ -52,7 +52,7 @@ bool IsCode(uintptr_t address) {
|
||||
}
|
||||
|
||||
void WriteReport(EXCEPTION_POINTERS* info) {
|
||||
FILE* file = _wfopen((g_dir + L"sacred_re_crash.txt").c_str(), L"w");
|
||||
FILE* file = _wfopen((g_dir + L"sacredK_crash.txt").c_str(), L"w");
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ void WriteReport(EXCEPTION_POINTERS* info) {
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
HANDLE dump = CreateFileW((g_dir + L"sacred_re_crash.dmp").c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
|
||||
HANDLE dump = CreateFileW((g_dir + L"sacredK_crash.dmp").c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (dump != INVALID_HANDLE_VALUE) {
|
||||
MINIDUMP_EXCEPTION_INFORMATION exception = {GetCurrentThreadId(), info, FALSE};
|
||||
@@ -120,7 +120,7 @@ bool GameInFront() {
|
||||
}
|
||||
|
||||
void WriteHangDump() {
|
||||
HANDLE dump = CreateFileW((g_dir + L"sacred_re_hang.dmp").c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
|
||||
HANDLE dump = CreateFileW((g_dir + L"sacredK_hang.dmp").c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (dump != INVALID_HANDLE_VALUE) {
|
||||
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dump,
|
||||
@@ -142,7 +142,7 @@ DWORD WINAPI Watchdog(void*) {
|
||||
}
|
||||
if (!reported && GameInFront()) {
|
||||
reported = true;
|
||||
Log("hang: no engine tick for %lu ms, writing sacred_re_hang.dmp", GetTickCount() - beat);
|
||||
Log("hang: no engine tick for %lu ms, writing sacredK_hang.dmp", GetTickCount() - beat);
|
||||
WriteHangDump();
|
||||
Log("hang: dump written");
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@
|
||||
|
||||
namespace re {
|
||||
|
||||
// Writes sacred_re_crash.txt / .dmp into `dir` when the game crashes, and
|
||||
// sacred_re_hang.dmp when the engine stops ticking (see EngineHeartbeat).
|
||||
// Writes sacredK_crash.txt / .dmp into `dir` when the game crashes, and
|
||||
// sacredK_hang.dmp when the engine stops ticking (see EngineHeartbeat).
|
||||
void InstallCrashHandler(const std::wstring& dir);
|
||||
|
||||
// The engine ticked (running), or the game ended (not running).
|
||||
|
||||
+6
-6
@@ -1,4 +1,4 @@
|
||||
// sacred_re.dll entry point. Loaded into sacred.exe by the launcher before the
|
||||
// sacredK.dll entry point. Loaded into sacred.exe by the launcher before the
|
||||
// game's own entry point runs, so every hook is in place from the first
|
||||
// instruction of game code.
|
||||
|
||||
@@ -40,17 +40,17 @@ bool IsSupportedGameBuild() {
|
||||
|
||||
void Startup(HMODULE module) {
|
||||
std::wstring dir = ModuleDir(module);
|
||||
re::OpenLog((dir + L"sacred_re.log").c_str());
|
||||
re::SetConfigPath(dir + L"sacred_re.ini");
|
||||
re::Log("sacred_re loaded");
|
||||
re::OpenLog((dir + L"sacredK.log").c_str());
|
||||
re::SetConfigPath(dir + L"sacredK.ini");
|
||||
re::Log("sacredK loaded");
|
||||
re::InstallCrashHandler(dir);
|
||||
|
||||
if (!IsSupportedGameBuild()) {
|
||||
re::Log("unsupported sacred.exe build, no hooks installed");
|
||||
MessageBoxW(nullptr,
|
||||
L"This sacred.exe is not the supported Sacred Gold 2.28 build.\n"
|
||||
L"sacred_re will not patch it; the game runs unmodified.",
|
||||
L"sacred_re", MB_OK | MB_ICONWARNING);
|
||||
L"sacredK will not patch it; the game runs unmodified.",
|
||||
L"sacredK", MB_OK | MB_ICONWARNING);
|
||||
return;
|
||||
}
|
||||
if (re::ConfigInt("debug", "WaitForDebugger", 0)) {
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@
|
||||
//
|
||||
// The signature, including the calling convention, must match the original
|
||||
// exactly (`__cdecl`, `__stdcall`, `__thiscall` / `__fastcall` stand-in, ...).
|
||||
// Hooks can be disabled individually at runtime in sacred_re.ini:
|
||||
// Hooks can be disabled individually at runtime in sacredK.ini:
|
||||
//
|
||||
// [hooks]
|
||||
// Log=0
|
||||
@@ -40,7 +40,7 @@ bool AttachRuntimeHook(const char* name, void** original, void* replacement);
|
||||
|
||||
// Hooks a Windows API function for the whole process (game and DLLs alike).
|
||||
// `replacement` must have the API's exact signature; defines
|
||||
// `replacement##_original`. Disabled in sacred_re.ini under the API's name.
|
||||
// `replacement##_original`. Disabled in sacredK.ini under the API's name.
|
||||
#define RE_HOOK_API(api, replacement) \
|
||||
static decltype(&replacement) replacement##_original = &api; \
|
||||
static ::re::HookRegistration replacement##_registration( \
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
// sacred_re's own log: sacred_re.log next to sacred_re.dll, plus OutputDebugString.
|
||||
// sacredK's own log: sacredK.log next to sacredK.dll, plus OutputDebugString.
|
||||
|
||||
namespace re {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
LIBRARY sacred_re
|
||||
LIBRARY sacredK
|
||||
EXPORTS
|
||||
; Detours requires ordinal 1 on any DLL injected via DetourCreateProcessWithDll.
|
||||
DetourFinishHelperProcess @1 NONAME
|
||||
Reference in new issue
Block a user