Only the shipping artifacts (coop_host.exe, coop_hook.dll, coop_hook_x86.dll, coop_inject_x86.exe, steam_api64.dll, steam_input_actions.vdf) now land in the bin/<config>/ root, so it can be copied wholesale into a donor game folder. Test exes (plus the coop_tone fixture) build into bin/<config>/tests/ and the dev probes into bin/<config>/tools/, via a new coop_output_subdir() CMake helper. The probes resolve coop_hook.dll / the x86 injector from the deployable root one level up (new common/coop/tool_paths.hpp: deployed_artifact_path checks next-to-exe then parent). coop_tone is co-located with the tests so audio_loopback_test's "spawn coop_tone.exe next to me" lookup is unchanged. Verified from a clean bin/: root holds only deployables; ctest x64 7/7 and x86 3/3 green (incl. audio_loopback_test driving coop_tone from tests/). Also convert the roadmap Planned list to bullets and drop this (now-done) item. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
1.6 KiB
C++
53 lines
1.6 KiB
C++
// Resolve artifacts that ship in the deployable bin/<config>/ root even when the
|
|
// running executable lives in a sibling subfolder (e.g. dev tools staged under
|
|
// bin/<config>/tools/). The probes use this to find coop_hook.dll and the x86
|
|
// injector helper, which stay at the root while the probes themselves do not.
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <string>
|
|
|
|
#include <windows.h>
|
|
|
|
namespace coop
|
|
{
|
|
|
|
// Directory of the current executable, with a trailing separator.
|
|
inline std::wstring exe_directory()
|
|
{
|
|
wchar_t buf[MAX_PATH] = {};
|
|
GetModuleFileNameW(nullptr, buf, MAX_PATH);
|
|
std::wstring path(buf);
|
|
const std::size_t slash = path.find_last_of(L"\\/");
|
|
return slash == std::wstring::npos ? std::wstring() : path.substr(0, slash + 1);
|
|
}
|
|
|
|
// Full path to a deployed artifact `name`: prefer one next to the running exe, else
|
|
// one directory up (the deployable root, when the exe runs from a tools/ subfolder).
|
|
// Falls back to the next-to-exe path so callers can report a sensible "not found".
|
|
inline std::wstring deployed_artifact_path(const wchar_t* name)
|
|
{
|
|
const std::wstring here = exe_directory() + name;
|
|
if (GetFileAttributesW(here.c_str()) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
return here;
|
|
}
|
|
std::wstring dir = exe_directory();
|
|
if (!dir.empty())
|
|
{
|
|
dir.pop_back(); // drop the trailing separator before going up a level
|
|
}
|
|
const std::size_t slash = dir.find_last_of(L"\\/");
|
|
if (slash != std::wstring::npos)
|
|
{
|
|
const std::wstring up = dir.substr(0, slash + 1) + name;
|
|
if (GetFileAttributesW(up.c_str()) != INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
return up;
|
|
}
|
|
}
|
|
return here;
|
|
}
|
|
|
|
} // namespace coop
|