IO: Resolve IO DLL paths from environment variables (#119)

## Summary

Adds a unified mechanism for locating third-party IO DLLs through environment
variables, on top of the existing per-game `[xxxio] path=` INI setting.

## Changes

For each IO DLL, the path is resolved in this order:

1. The section-specific INI value, e.g. `[mai2io] path=`.
2. The section-specific environment variable, e.g. `SEGATOOLS_MAI2IO_PATH`.
3. `SEGATOOLS_IO_ROOT` joined with the default IO DLL filename, e.g.
   `%SEGATOOLS_IO_ROOT%\mai2io.dll`.
4. Empty path, which keeps the built-in IO implementation (unchanged default).

INI and environment-variable paths are run through Windows environment-variable
expansion, so values such as `%SEGATOOLS_IO_ROOT%\mai2io.dll` are valid in the
INI directly.

Reviewed-on: https://gitea.tendokyu.moe/TeamTofuShop/segatools/pulls/119
Co-authored-by: グローランプ <130208311+Gl0w1amp@users.noreply.github.com>
Co-committed-by: グローランプ <130208311+Gl0w1amp@users.noreply.github.com>
This commit is contained in:
グローランプ
2026-07-08 20:23:08 +00:00
committed by Dniel97
parent 8da836ccfb
commit 89bd77e306
44 changed files with 501 additions and 103 deletions
+14 -11
View File
@@ -11,6 +11,7 @@
#include "board/vfd.h"
#include "util/dprintf.h"
#include "util/io-path.h"
// Check windows
#if _WIN32 || _WIN64
@@ -44,24 +45,26 @@ static void aime_dll_config_load(struct aime_dll_config *cfg, const wchar_t *fil
// Always empty, due to amdaemon being 64 bit in 32 bit mode
memset(cfg->path, 0, sizeof(cfg->path));
#elif defined(ENV64BIT)
GetPrivateProfileStringW(
L"aimeio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"aimeio",
L"path",
L"SEGATOOLS_AIMEIO_PATH",
L"aimeio.dll",
filename);
#else
#error "Unknown environment"
#endif
} else {
GetPrivateProfileStringW(
L"aimeio",
L"path",
L"",
cfg->path,
_countof(cfg->path),
filename);
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"aimeio",
L"path",
L"SEGATOOLS_AIMEIO_PATH",
L"aimeio.dll",
filename);
}
}
+7 -5
View File
@@ -9,6 +9,7 @@
#include "hooklib/dvd.h"
#include "hooklib/y3.h"
#include "hooklib/y3-dll.h"
#include "util/io-path.h"
void dvd_config_load(struct dvd_config *cfg, const wchar_t *filename)
{
@@ -158,12 +159,13 @@ void y3_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"y3io",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"y3io",
L"path",
L"SEGATOOLS_Y3IO_PATH",
L"y3io.dll",
filename);
}
@@ -243,4 +245,4 @@ void y3_config_load(
filename);
wcstombs(cfg->target_code_printer, tmpstr, sizeof(cfg->target_code_printer) - 1);
}
}
+203
View File
@@ -0,0 +1,203 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "util/dprintf.h"
#include "util/io-path.h"
static bool io_path_expand(
wchar_t *out,
size_t out_count,
const wchar_t *path,
const wchar_t *source);
static bool io_path_from_root(
wchar_t *out,
size_t out_count,
const wchar_t *root_filename);
static bool io_path_is_separator(wchar_t ch);
bool io_path_config_load(
wchar_t *out,
size_t out_count,
const wchar_t *section,
const wchar_t *key,
const wchar_t *env_name,
const wchar_t *root_filename,
const wchar_t *filename)
{
wchar_t path[MAX_PATH];
DWORD count;
assert(out != NULL);
assert(out_count > 0);
assert(section != NULL);
assert(key != NULL);
assert(filename != NULL);
out[0] = L'\0';
count = GetPrivateProfileStringW(
section,
key,
L"",
path,
_countof(path),
filename);
if (count >= _countof(path) - 1 && path[0] != L'\0') {
dprintf("IO path: INI value [%S] %S may be truncated "
"(exceeds %d characters)\n",
section,
key,
(int) _countof(path) - 1);
}
if (path[0] != L'\0') {
return io_path_expand(out, out_count, path, key);
}
if (env_name != NULL) {
count = GetEnvironmentVariableW(env_name, path, _countof(path));
if (count >= _countof(path)) {
dprintf("IO path: Environment variable too long: %S\n", env_name);
return false;
}
if (count != 0 && path[0] != L'\0') {
return io_path_expand(out, out_count, path, env_name);
}
}
return io_path_from_root(out, out_count, root_filename);
}
static bool io_path_expand(
wchar_t *out,
size_t out_count,
const wchar_t *path,
const wchar_t *source)
{
DWORD expanded;
assert(out != NULL);
assert(out_count > 0);
assert(path != NULL);
assert(source != NULL);
expanded = ExpandEnvironmentStringsW(path, out, (DWORD) out_count);
if (expanded == 0) {
dprintf("IO path: Failed to expand path from %S: %lx\n",
source,
GetLastError());
out[0] = L'\0';
return false;
}
if (expanded > out_count) {
dprintf("IO path: Expanded path from %S is too long: %S\n",
source,
path);
out[0] = L'\0';
return false;
}
return true;
}
static bool io_path_from_root(
wchar_t *out,
size_t out_count,
const wchar_t *root_filename)
{
wchar_t root[MAX_PATH];
wchar_t expanded_root[MAX_PATH];
size_t root_len;
size_t file_len;
DWORD count;
assert(out != NULL);
assert(out_count > 0);
if (root_filename == NULL || root_filename[0] == L'\0') {
return false;
}
count = GetEnvironmentVariableW(
L"SEGATOOLS_IO_ROOT",
root,
_countof(root));
if (count >= _countof(root)) {
dprintf("IO path: SEGATOOLS_IO_ROOT is too long\n");
return false;
}
if (count == 0 || root[0] == L'\0') {
return false;
}
if (!io_path_expand(
expanded_root,
_countof(expanded_root),
root,
L"SEGATOOLS_IO_ROOT")) {
return false;
}
root_len = wcslen(expanded_root);
file_len = wcslen(root_filename);
if (root_len == 0) {
return false;
}
if (root_len + file_len + 2 > out_count) {
dprintf("IO path: SEGATOOLS_IO_ROOT path is too long: %S\\%S\n",
expanded_root,
root_filename);
return false;
}
wcscpy_s(out, out_count, expanded_root);
if (!io_path_is_separator(out[root_len - 1])) {
out[root_len++] = L'\\';
out[root_len] = L'\0';
}
wcscat_s(out, out_count, root_filename);
/* The SEGATOOLS_IO_ROOT fallback is broadcast to every hook at once, so a
single global setting is shared by games that may not each ship an IO
DLL in that directory. Unlike an explicit INI/env path (direct user
intent, allowed to fail loudly at load time), a synthesized root path
that does not exist should quietly fall back to the built-in IO
implementation instead of aborting hook startup. */
if (GetFileAttributesW(out) == INVALID_FILE_ATTRIBUTES) {
dprintf("IO path: SEGATOOLS_IO_ROOT DLL not found, "
"using built-in IO: %S\n",
out);
out[0] = L'\0';
return false;
}
return true;
}
static bool io_path_is_separator(wchar_t ch)
{
return ch == L'\\' || ch == L'/';
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
#include <stddef.h>
bool io_path_config_load(
wchar_t *out,
size_t out_count,
const wchar_t *section,
const wchar_t *key,
const wchar_t *env_name,
const wchar_t *root_filename,
const wchar_t *filename);
+2
View File
@@ -21,6 +21,8 @@ util_lib = static_library(
'fg-detect.h',
'get_function_ordinal.c',
'get_function_ordinal.h',
'io-path.c',
'io-path.h',
'lib.c',
'lib.h',
'slurp.c',
+4
View File
@@ -133,11 +133,15 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[apm3io]
; To use a custom APM3 IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in gamepad input.
; If empty, SEGATOOLS_APM3IO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\apm3io.dll.
path=
; -----------------------------------------------------------------------------
+2
View File
@@ -97,6 +97,8 @@ dpiAware=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -136,11 +136,15 @@ controllerLedOutputOpeNITHM=0
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[chuniio]
; To use a custom Chunithm IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_CHUNIIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\chuniio.dll.
path=
; -----------------------------------------------------------------------------
+5
View File
@@ -162,15 +162,20 @@ controllerLedOutputOpeNITHM=0
[aimeio]
; To use a custom card reader IO DLL (x64) enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[chuniio]
; Uncomment this if you have custom chuniio implementation comprised of a single 32bit DLL.
; (will use chu2to3 engine internally)
; If empty, SEGATOOLS_CHUNIIO_PATH can provide this path.
;path=
; Uncomment both of these if you have custom chuniio implementation comprised of two DLLs.
; x86 chuniio to path32, x64 to path64. Both are necessary.
; If empty, SEGATOOLS_CHUNIIO_PATH32 and SEGATOOLS_CHUNIIO_PATH64 are used if set.
; Otherwise SEGATOOLS_IO_ROOT\chuniio_x86.dll and SEGATOOLS_IO_ROOT\chuniio_x64.dll are used.
;path32=
;path64=
+2
View File
@@ -103,6 +103,8 @@ printerOutPath="DEVICE\print"
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -108,11 +108,15 @@ dpiAware=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[cxbio]
; To use a custom crossbeats REV. DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_CXBIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\cxbio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -98,11 +98,15 @@ dpiAware=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[divaio]
; To use a custom Project DIVA Arcade IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in gamepad/wheel input.
; If empty, SEGATOOLS_DIVAIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\divaio.dll.
path=
; -----------------------------------------------------------------------------
+6
View File
@@ -114,16 +114,22 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[ektio]
; To use a custom Eiketsu Taisen IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
; If empty, SEGATOOLS_EKTIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\ektio.dll.
path=
[y3io]
; To use a custom Y3 IO DLL enter its path here.
; Leave empty if you want to use ... TBA ...
; If empty, SEGATOOLS_Y3IO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\y3io.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -101,11 +101,15 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[ektio]
; To use a custom Eiketsu Taisen IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
; If empty, SEGATOOLS_EKTIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\ektio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -134,11 +134,15 @@ rotate180=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[fgoio]
; To use a custom Fate/Grand Order Arcade IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in gamepad input.
; If empty, SEGATOOLS_FGOIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\fgoio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -125,11 +125,15 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[idacio]
; To use a custom Initial D THE ARCADE IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in gamepad/wheel input.
; If empty, SEGATOOLS_IDACIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\idacio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -125,11 +125,15 @@ dpiAware=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[idzio]
; To use a custom Initial D Zero IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in gamepad/wheel input.
; If empty, SEGATOOLS_IDZIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\idzio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -123,11 +123,15 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[kemonoio]
; To use a custom Kemono IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_KEMONOIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\kemonoio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -112,11 +112,15 @@ targetAssembly=
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[mai2io]
; To use a custom maimai DX IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_MAI2IO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\mai2io.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -109,11 +109,15 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[mercuryio]
; To use a custom WACCA IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_MERCURYIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\mercuryio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -153,11 +153,15 @@ controllerLedOutputSerial=0
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[mu3io]
; To use a custom O.N.G.E.K.I. IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
; If empty, SEGATOOLS_MU3IO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\mu3io.dll.
path=
; -----------------------------------------------------------------------------
+6
View File
@@ -138,16 +138,22 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[sekitoio]
; To use a custom Eiketsu Taisen IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
; If empty, SEGATOOLS_SEKITOIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\sekitoio.dll.
path=
[y3io]
; To use a custom Y3 IO DLL enter its path here.
; Leave empty if you want to use ... TBA ...
; If empty, SEGATOOLS_Y3IO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\y3io.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -123,11 +123,15 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[sekitoio]
; To use a custom Eiketsu Taisen IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard/gamepad input.
; If empty, SEGATOOLS_SEKITOIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\sekitoio.dll.
path=
; -----------------------------------------------------------------------------
+4
View File
@@ -92,11 +92,15 @@ enable=1
[aimeio]
; To use a custom card reader IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
; If empty, SEGATOOLS_AIMEIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\aimeio.dll.
path=
[swdcio]
; To use a custom SEGA World Drivers Championship DLL enter its path here.
; Leave empty if you want to use Segatools built-in gamepad/wheel input.
; If empty, SEGATOOLS_SWDCIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\swdcio.dll.
path=
; -----------------------------------------------------------------------------
+2
View File
@@ -106,6 +106,8 @@ enable=1
; To use a custom Mario & Sonic at the Tokyo 2020 Olympics Arcade IO DLL enter
; its path here. Leave empty if you want to use Segatools built-in keyboard/
; gamepad input.
; If empty, SEGATOOLS_TOKYOIO_PATH is used if set, followed by
; SEGATOOLS_IO_ROOT\tokyoio.dll.
path=
; -----------------------------------------------------------------------------
+58 -1
View File
@@ -17,6 +17,61 @@ Then you can copy `segatools.ini` to `another_config.ini` but with different dns
set SEGATOOLS_CONFIG_PATH=.\another_config.ini
```
## IO DLL path resolution
Custom IO DLL paths are resolved in this order:
1. The section-specific INI value, such as `[mai2io] path=`.
2. The section-specific environment variable, such as `SEGATOOLS_MAI2IO_PATH`.
3. `SEGATOOLS_IO_ROOT` joined with the default IO DLL filename, such as
`%SEGATOOLS_IO_ROOT%\mai2io.dll`.
4. Empty path, which keeps the built-in IO implementation.
INI paths and environment-variable paths support Windows environment variable
expansion, so an INI entry like this is valid:
```ini
[mai2io]
path=%SEGATOOLS_IO_ROOT%\mai2io.dll
```
Supported IO environment variables:
| INI section | Direct environment variable | `SEGATOOLS_IO_ROOT` filename |
| --- | --- | --- |
| `[aimeio]` | `SEGATOOLS_AIMEIO_PATH` | `aimeio.dll` |
| `[apm3io]` | `SEGATOOLS_APM3IO_PATH` | `apm3io.dll` |
| `[carolio]` | `SEGATOOLS_CAROLIO_PATH` | `carolio.dll` |
| `[chuniio]` | `SEGATOOLS_CHUNIIO_PATH` | `chuniio.dll` \* |
| `[cmio]` | `SEGATOOLS_CMIO_PATH` | `cmio.dll` |
| `[cxbio]` | `SEGATOOLS_CXBIO_PATH` | `cxbio.dll` |
| `[divaio]` | `SEGATOOLS_DIVAIO_PATH` | `divaio.dll` |
| `[ektio]` | `SEGATOOLS_EKTIO_PATH` | `ektio.dll` |
| `[fgoio]` | `SEGATOOLS_FGOIO_PATH` | `fgoio.dll` |
| `[idacio]` | `SEGATOOLS_IDACIO_PATH` | `idacio.dll` |
| `[idzio]` | `SEGATOOLS_IDZIO_PATH` | `idzio.dll` |
| `[kemonoio]` | `SEGATOOLS_KEMONOIO_PATH` | `kemonoio.dll` |
| `[mai2io]` | `SEGATOOLS_MAI2IO_PATH` | `mai2io.dll` |
| `[mercuryio]` | `SEGATOOLS_MERCURYIO_PATH` | `mercuryio.dll` |
| `[mu3io]` | `SEGATOOLS_MU3IO_PATH` | `mu3io.dll` |
| `[sekitoio]` | `SEGATOOLS_SEKITOIO_PATH` | `sekitoio.dll` |
| `[swdcio]` | `SEGATOOLS_SWDCIO_PATH` | `swdcio.dll` |
| `[tokyoio]` | `SEGATOOLS_TOKYOIO_PATH` | `tokyoio.dll` |
| `[y3io]` | `SEGATOOLS_Y3IO_PATH` | `y3io.dll` |
\* The `%SEGATOOLS_IO_ROOT%\chuniio.dll` fallback applies to the
single-32-bit-DLL Chunithm hook (`chunihook`) only. Chunithm NEW and later
(`chusanhook`) resolve the single-DLL `[chuniio] path=` / `SEGATOOLS_CHUNIIO_PATH`
from the INI value or environment variable only, with no `SEGATOOLS_IO_ROOT`
default; those builds use the `path32`/`path64` mechanism below for their
`SEGATOOLS_IO_ROOT` defaults.
For Chunithm NEW and later hooks that use separate 32-bit and 64-bit IO DLLs,
`[chuniio] path32=` maps to `SEGATOOLS_CHUNIIO_PATH32` and
`[chuniio] path64=` maps to `SEGATOOLS_CHUNIIO_PATH64`. When only
`SEGATOOLS_IO_ROOT` is set, these hooks look for `chuniio_x86.dll` and
`chuniio_x64.dll`.
## `[aimeio]`
Controls the card reader driver.
@@ -25,6 +80,8 @@ Controls the card reader driver.
Specify a path for a third-party card reader driver DLL. Default is empty
(use built-in emulation based on text files and keyboard input).
If empty, `SEGATOOLS_AIMEIO_PATH` is used if set, followed by
`%SEGATOOLS_IO_ROOT%\aimeio.dll`.
In previous versions of Segatools this was accomplished by replacing the
AIMEIO.DLL file that came with Segatools. Segatools no longer ships with a
@@ -812,4 +869,4 @@ This is a file that will be set to the content of what would be written to the `
This allows whatever executed the game process to react what should happen next (System Test Mode selected, network delivery completed, ...) without requiring admin permissions.
The file is deleted on startup of segatools.
The file is deleted on startup of segatools.
+6 -4
View File
@@ -10,6 +10,7 @@
#include "apm3hook/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void apm3_dll_config_load(
struct apm3_dll_config *cfg,
@@ -18,12 +19,13 @@ void apm3_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"apm3io",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"apm3io",
L"path",
L"SEGATOOLS_APM3IO_PATH",
L"apm3io.dll",
filename);
}
+6 -4
View File
@@ -13,6 +13,7 @@
#include "platform/config.h"
#include "platform/platform.h"
#include "util/io-path.h"
void carol_dll_config_load(
struct carol_dll_config *cfg,
@@ -21,12 +22,13 @@ void carol_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"carolio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"carolio",
L"path",
L"SEGATOOLS_CAROLIO_PATH",
L"carolio.dll",
filename);
}
+6 -4
View File
@@ -19,6 +19,7 @@
#include "platform/config.h"
#include "platform/platform.h"
#include "util/io-path.h"
void chuni_dll_config_load(
struct chuni_dll_config *cfg,
@@ -27,12 +28,13 @@ void chuni_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"chuniio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"chuniio",
L"path",
L"SEGATOOLS_CHUNIIO_PATH",
L"chuniio.dll",
filename);
}
+20 -17
View File
@@ -12,6 +12,7 @@
#include "platform/config.h"
#include "chusanhook/config.h"
#include "util/io-path.h"
// Check windows
#if _WIN32 || _WIN64
@@ -42,32 +43,34 @@ void chuni_dll_config_load(
// path32 for 32bit, path64 for 64bit
// path for 32bit only dlls (internal chu2to3 engine)
GetPrivateProfileStringW(
L"chuniio",
L"path",
L"",
if (io_path_config_load(
cfg->path,
_countof(cfg->path),
filename);
if (cfg->path[0] != L'\0') {
L"chuniio",
L"path",
L"SEGATOOLS_CHUNIIO_PATH",
NULL,
filename)) {
cfg->chu2to3 = 1;
} else {
cfg->chu2to3 = 0;
#if defined(ENV32BIT)
GetPrivateProfileStringW(
L"chuniio",
L"path32",
L"",
cfg->path,
_countof(cfg->path),
filename);
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"chuniio",
L"path32",
L"SEGATOOLS_CHUNIIO_PATH32",
L"chuniio_x86.dll",
filename);
#elif defined(ENV64BIT)
GetPrivateProfileStringW(
L"chuniio",
L"path64",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"chuniio",
L"path64",
L"SEGATOOLS_CHUNIIO_PATH64",
L"chuniio_x64.dll",
filename);
#else
#error "Unknown environment"
+6 -4
View File
@@ -10,6 +10,7 @@
#include "cmhook/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void cm_dll_config_load(
struct cm_dll_config *cfg,
@@ -18,12 +19,13 @@ void cm_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"cmio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"cmio",
L"path",
L"SEGATOOLS_CMIO_PATH",
L"cmio.dll",
filename);
}
+7 -5
View File
@@ -19,6 +19,7 @@
#include "platform/config.h"
#include "platform/platform.h"
#include "util/io-path.h"
void cxb_dll_config_load(
struct cxb_dll_config *cfg,
@@ -27,12 +28,13 @@ void cxb_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"cxbio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"cxbio",
L"path",
L"SEGATOOLS_CXBIO_PATH",
L"cxbio.dll",
filename);
}
@@ -69,4 +71,4 @@ void cxb_hook_config_load(
cxb_dll_config_load(&cfg->dll, filename);
revio_config_load(&cfg->revio, filename);
led_config_load(&cfg->led, filename);
}
}
+6 -4
View File
@@ -15,6 +15,7 @@
#include "platform/config.h"
#include "platform/platform.h"
#include "util/io-path.h"
void diva_dll_config_load(
struct diva_dll_config *cfg,
@@ -23,12 +24,13 @@ void diva_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"divaio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"divaio",
L"path",
L"SEGATOOLS_DIVAIO_PATH",
L"divaio.dll",
filename);
}
+6 -4
View File
@@ -11,6 +11,7 @@
#include "hooklib/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
{
@@ -80,12 +81,13 @@ void ekt_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"ektio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"ektio",
L"path",
L"SEGATOOLS_EKTIO_PATH",
L"ektio.dll",
filename);
}
+6 -4
View File
@@ -10,6 +10,7 @@
#include "fgohook/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void fgo_dll_config_load(
struct fgo_dll_config *cfg,
@@ -18,12 +19,13 @@ void fgo_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"fgoio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"fgoio",
L"path",
L"SEGATOOLS_FGOIO_PATH",
L"fgoio.dll",
filename);
}
+6 -4
View File
@@ -13,6 +13,7 @@
#include "platform/config.h"
#include "platform/platform.h"
#include "util/io-path.h"
void led15070_config_load(struct led15070_config *cfg, const wchar_t *filename)
@@ -59,12 +60,13 @@ void idac_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"idacio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"idacio",
L"path",
L"SEGATOOLS_IDACIO_PATH",
L"idacio.dll",
filename);
}
+6 -4
View File
@@ -18,6 +18,7 @@
#include "platform/config.h"
#include "platform/platform.h"
#include "util/io-path.h"
void led15070_config_load(struct led15070_config *cfg, const wchar_t *filename)
{
@@ -63,12 +64,13 @@ void idz_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"idzio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"idzio",
L"path",
L"SEGATOOLS_IDZIO_PATH",
L"idzio.dll",
filename);
}
+6 -4
View File
@@ -12,6 +12,7 @@
#include "kemonohook/config.h"
#include "platform/config.h"
#include "util/io-path.h"
// Check windows
#if _WIN32 || _WIN64
@@ -41,12 +42,13 @@ void kemono_dll_config_load(
// Always empty, due to amdaemon being 64 bit in 32 bit mode
memset(cfg->path, 0, sizeof(cfg->path));
#elif defined(ENV64BIT)
GetPrivateProfileStringW(
L"kemonoio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"kemonoio",
L"path",
L"SEGATOOLS_KEMONOIO_PATH",
L"kemonoio.dll",
filename);
#else
#error "Unknown environment"
+6 -4
View File
@@ -10,6 +10,7 @@
#include "mai2hook/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void mai2_dll_config_load(
struct mai2_dll_config *cfg,
@@ -18,12 +19,13 @@ void mai2_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"mai2io",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"mai2io",
L"path",
L"SEGATOOLS_MAI2IO_PATH",
L"mai2io.dll",
filename);
}
+6 -4
View File
@@ -11,6 +11,7 @@
#include "mercuryhook/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void mercury_dll_config_load(
struct mercury_dll_config *cfg,
@@ -19,12 +20,13 @@ void mercury_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"mercuryio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"mercuryio",
L"path",
L"SEGATOOLS_MERCURYIO_PATH",
L"mercuryio.dll",
filename);
}
+6 -4
View File
@@ -12,6 +12,7 @@
#include "mu3hook/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void mu3_dll_config_load(
struct mu3_dll_config *cfg,
@@ -20,12 +21,13 @@ void mu3_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"mu3io",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"mu3io",
L"path",
L"SEGATOOLS_MU3IO_PATH",
L"mu3io.dll",
filename);
}
+6 -4
View File
@@ -12,6 +12,7 @@
#include "hooklib/config.h"
#include "platform/config.h"
#include "util/io-path.h"
void led15093_config_load(struct led15093_config *cfg, const wchar_t *filename)
{
@@ -81,12 +82,13 @@ void sekito_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"sekitoio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"sekitoio",
L"path",
L"SEGATOOLS_SEKITOIO_PATH",
L"sekitoio.dll",
filename);
}
+6 -4
View File
@@ -13,6 +13,7 @@
#include "platform/config.h"
#include "platform/platform.h"
#include "util/io-path.h"
void led15070_config_load(struct led15070_config *cfg, const wchar_t *filename)
@@ -59,12 +60,13 @@ void swdc_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"swdcio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"swdcio",
L"path",
L"SEGATOOLS_SWDCIO_PATH",
L"swdcio.dll",
filename);
}
+6 -4
View File
@@ -12,6 +12,7 @@
#include "platform/config.h"
#include "tokyohook/config.h"
#include "util/io-path.h"
void tokyo_dll_config_load(
struct tokyo_dll_config *cfg,
@@ -19,12 +20,13 @@ void tokyo_dll_config_load(
assert(cfg != NULL);
assert(filename != NULL);
GetPrivateProfileStringW(
L"tokyoio",
L"path",
L"",
io_path_config_load(
cfg->path,
_countof(cfg->path),
L"tokyoio",
L"path",
L"SEGATOOLS_TOKYOIO_PATH",
L"tokyoio.dll",
filename);
}