Skip to content

Commit 32c399d

Browse files
committed
FF8: Enable override_path option for FF8
1 parent e58e970 commit 32c399d

9 files changed

+90
-22
lines changed

Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- External textures: Fix filename lookup which can match more textures than it should in a VRAM page ( https://github.com/julianxhokaxhiu/FFNx/pull/687 )
2222
- External textures: Split `battle/A8DEF.TIM` into three files to avoid redundant textures ( https://github.com/julianxhokaxhiu/FFNx/pull/687 )
2323
- External music: Fix music get stopped in Fisherman's Horizon concert ( https://github.com/julianxhokaxhiu/FFNx/pull/694 )
24+
- Files: Enable support for `override_path` option ( https://github.com/julianxhokaxhiu/FFNx/pull/705 )
2425
- Rendering: Avoid texture reupload in case of palette swap ( https://github.com/julianxhokaxhiu/FFNx/pull/687 )
2526
- Rendering: Fix texture unload when multiple palettes are written ( https://github.com/julianxhokaxhiu/FFNx/pull/687 )
2627
- Rendering: Prevent the game from sending textures with half-alpha colors ( https://github.com/julianxhokaxhiu/FFNx/pull/687 )

src/common.cpp

+13-7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "ff8/engine.h"
6666
#include "ff8/uv_patch.h"
6767
#include "ff8/ambient.h"
68+
#include "ff8/file.h"
6869

6970
#include "wine.h"
7071

@@ -3261,11 +3262,16 @@ __declspec(dllexport) LSTATUS __stdcall dotemuRegQueryValueExA(HKEY hKey, LPCSTR
32613262

32623263
__declspec(dllexport) HANDLE __stdcall dotemuCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
32633264
{
3265+
if (ff8_fs_last_fopen_is_redirected())
3266+
{
3267+
return CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
3268+
}
3269+
32643270
HANDLE ret = INVALID_HANDLE_VALUE;
32653271

32663272
if (strstr(lpFileName, "CD:") != NULL)
32673273
{
3268-
CHAR newPath[260]{ 0 };
3274+
CHAR newPath[MAX_PATH]{ 0 };
32693275
uint8_t requiredDisk = *(uint8_t*)(*(DWORD*)ff8_externals.requiredDisk + 0xCC);
32703276
CHAR diskAsChar[2];
32713277

@@ -3289,31 +3295,31 @@ __declspec(dllexport) HANDLE __stdcall dotemuCreateFileA(LPCSTR lpFileName, DWOR
32893295
}
32903296
else if (strstr(lpFileName, "app.log") || strstr(lpFileName, "ff8input.cfg"))
32913297
{
3292-
CHAR newPath[260]{ 0 };
3298+
CHAR newPath[MAX_PATH]{ 0 };
32933299

32943300
// Search for the last '\' character and get a pointer to the next char
32953301
const char* pos = strrchr(lpFileName, 92) + 1;
32963302

3297-
get_userdata_path(newPath, 260, false);
3303+
get_userdata_path(newPath, sizeof(newPath), false);
32983304
PathAppendA(newPath, JP_VERSION ? "ff8input_jp.cfg" : pos);
32993305

33003306
ret = CreateFileA(newPath, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
33013307
}
33023308
else if (strstr(lpFileName, "temp.fi") || strstr(lpFileName, "temp.fl") || strstr(lpFileName, "temp.fs") || strstr(lpFileName, "temp_evn.") || strstr(lpFileName, "temp_odd."))
33033309
{
3304-
CHAR newPath[260]{ 0 };
3310+
CHAR newPath[MAX_PATH]{ 0 };
33053311

33063312
// Search for the last '\' character and get a pointer to the next char
33073313
const char* pos = strrchr(lpFileName, 92) + 1;
33083314

3309-
get_userdata_path(newPath, 260, false);
3315+
get_userdata_path(newPath, sizeof(newPath), false);
33103316
PathAppendA(newPath, pos);
33113317

33123318
ret = CreateFileA(newPath, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
33133319
}
33143320
else if (strstr(lpFileName, ".fi") != NULL || strstr(lpFileName, ".fl") != NULL || strstr(lpFileName, ".fs") != NULL)
33153321
{
3316-
CHAR newPath[260]{ 0 };
3322+
CHAR newPath[MAX_PATH]{ 0 };
33173323

33183324
// Search for the last '\' character and get a pointer to the next char
33193325
const char* pos = strrchr(lpFileName, 92) + 1;
@@ -3325,7 +3331,7 @@ __declspec(dllexport) HANDLE __stdcall dotemuCreateFileA(LPCSTR lpFileName, DWOR
33253331
}
33263332
else if (StrStrIA(lpFileName, R"(SAVE\)") != NULL) // SAVE\SLOTX\saveN or save\chocorpg
33273333
{
3328-
CHAR newPath[260]{ 0 };
3334+
CHAR newPath[MAX_PATH]{ 0 };
33293335
CHAR saveFileName[50]{ 0 };
33303336

33313337
// Search for the next character pointer after "SAVE\"

src/ff8.h

+1
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ struct ff8_externals
10511051
uint32_t (*sm_pc_read)(char*,void*);
10521052
uint32_t get_disk_number;
10531053
char* disk_data_path;
1054+
const char *app_path;
10541055
uint32_t swirl_main_loop;
10551056
uint32_t field_main_loop;
10561057
uint32_t field_main_exit;

src/ff8/file.cpp

+47-4
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
#include "file.h"
2424
#include "../ff8.h"
2525
#include "../log.h"
26+
#include "../redirect.h"
2627

2728
#include <fcntl.h>
2829
#include <io.h>
2930

3031
char next_direct_file[MAX_PATH] = "";
32+
bool last_fopen_is_redirected = false;
3133

3234
size_t get_fl_prefix_size()
3335
{
@@ -115,14 +117,25 @@ void ff8_fs_archive_free_file_container_sub_archive(ff8_file_container *file_con
115117
return ff8_externals.free_file_container(file_container);
116118
}
117119

120+
bool ff8_attempt_redirection(const char *in, char *out, size_t size)
121+
{
122+
// Remove AppPath from input
123+
if (strncmp(in, ff8_externals.app_path, strlen(ff8_externals.app_path)) == 0) {
124+
// +1 because the last '\' is stripped from AppPath by the game
125+
in += strlen(ff8_externals.app_path) + 1;
126+
}
127+
128+
return attempt_redirection(in, out, size) != -1;
129+
}
130+
118131
int ff8_open(const char *fileName, int oflag, ...)
119132
{
120133
va_list va;
121134

122135
va_start(va, oflag);
123136
int pmode = va_arg(va, int);
124137

125-
if (trace_all || trace_files) ffnx_trace("%s: %s pmode=%X\n", __func__, fileName, pmode);
138+
if (trace_all || trace_files) ffnx_trace("%s: %s oflag=%X pmode=%X\n", __func__, fileName, oflag, pmode);
126139

127140
if (next_direct_file && *next_direct_file != '\0')
128141
{
@@ -135,7 +148,16 @@ int ff8_open(const char *fileName, int oflag, ...)
135148
return ret;
136149
}
137150

138-
return ff8_externals._sopen(fileName, oflag, 64, pmode);
151+
char _filename[MAX_PATH]{ 0 };
152+
bool is_redirected = ff8_attempt_redirection(fileName, _filename, sizeof(_filename));
153+
154+
last_fopen_is_redirected = is_redirected;
155+
156+
int ret = ff8_externals._sopen(is_redirected ? _filename : fileName, oflag, 64, pmode);
157+
158+
last_fopen_is_redirected = false;
159+
160+
return ret;
139161
}
140162

141163
FILE *ff8_fopen(const char *fileName, const char *mode)
@@ -153,7 +175,16 @@ FILE *ff8_fopen(const char *fileName, const char *mode)
153175
return file;
154176
}
155177

156-
return ff8_externals._fsopen(fileName, mode, 64);
178+
char _filename[MAX_PATH]{ 0 };
179+
bool is_redirected = ff8_attempt_redirection(fileName, _filename, sizeof(_filename));
180+
181+
last_fopen_is_redirected = is_redirected;
182+
183+
FILE *file = ff8_externals._fsopen(is_redirected ? _filename : fileName, mode, 64);
184+
185+
last_fopen_is_redirected = false;
186+
187+
return file;
157188
}
158189

159190
ff8_file *ff8_open_file(ff8_file_context *infos, const char *fs_path)
@@ -234,8 +265,15 @@ ff8_file *ff8_open_file(ff8_file_context *infos, const char *fs_path)
234265
}
235266
else
236267
{
268+
char _filename[256]{ 0 };
269+
bool is_redirected = ff8_attempt_redirection(fullpath, _filename, sizeof(_filename));
270+
271+
last_fopen_is_redirected = is_redirected;
272+
237273
// We need to use the external _open, and not the official one
238-
file->fd = ff8_externals._sopen(fullpath, oflag, 64, pmode);
274+
file->fd = ff8_externals._sopen(is_redirected ? _filename : fullpath, oflag, 64, pmode);
275+
276+
last_fopen_is_redirected = false;
239277
}
240278

241279
file->is_open = 1;
@@ -253,3 +291,8 @@ ff8_file *ff8_open_file(ff8_file_context *infos, const char *fs_path)
253291

254292
return file;
255293
}
294+
295+
bool ff8_fs_last_fopen_is_redirected()
296+
{
297+
return last_fopen_is_redirected;
298+
}

src/ff8/file.h

+2
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ uint32_t(*ff8_read_file)(uint32_t count, void* buffer, struct ff8_file* file);
3737
void (*ff8_close_file)(struct ff8_file* file);
3838

3939
void ff8_fs_lang_string(char *data);
40+
41+
bool ff8_fs_last_fopen_is_redirected();

src/ff8_data.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ void ff8_find_externals()
9898
ff8_externals.get_disk_number = get_relative_call(ff8_externals.main_loop, 0x1A);
9999
ff8_externals.disk_data_path = (char*)get_absolute_value(ff8_externals.get_disk_number, 0xF);
100100
ff8_externals.set_game_paths = (void (*)(int, char*, const char*))get_relative_call(ff8_externals.init_config, 0x3E);
101+
ff8_externals.app_path = (const char*)get_absolute_value(uint32_t(ff8_externals.set_game_paths), 0x9A);
101102

102103
ff8_externals.savemap = (uint32_t**)get_absolute_value(ff8_externals.main_loop, 0x21);
103104

src/game_cfg.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424

2525
#include "patch.h"
2626

27+
void normalize_path(char *name)
28+
{
29+
int idx = 0;
30+
while (name[idx] != 0)
31+
{
32+
if (name[idx] == '/') name[idx] = '\\';
33+
idx++;
34+
}
35+
}
36+
2737
void set_game_paths(int install_options, char *_app_path, const char *_dataDrive)
2838
{
2939
char fileName[MAX_PATH] = {};
@@ -33,6 +43,7 @@ void set_game_paths(int install_options, char *_app_path, const char *_dataDrive
3343
ffnx_info("Overriding AppPath with %s\n", app_path.c_str());
3444
strncpy(fileName, app_path.c_str(), sizeof(fileName));
3545
_app_path = fileName;
46+
normalize_path(_app_path);
3647
}
3748

3849
if (!steam_edition && !data_drive.empty())

src/redirect.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,17 @@
2525

2626
#include "redirect.h"
2727

28-
int attempt_redirection(char* in, char* out, size_t size, bool wantsSteamPath)
28+
int attempt_redirection(const char* in, char* out, size_t size, bool wantsSteamPath)
2929
{
3030
std::string newIn(in);
3131

32-
std::transform(newIn.begin(), newIn.end(), newIn.begin(), ::tolower);
32+
if (!ff8)
33+
{
34+
std::transform(newIn.begin(), newIn.end(), newIn.begin(), ::tolower);
35+
}
3336

34-
bool isSavegame = strstr(newIn.data(), ".ff7") != NULL;
35-
bool isCacheFile = strstr(newIn.data(), ".p") != NULL;
37+
bool isSavegame = !ff8 && strstr(newIn.data(), ".ff7") != NULL;
38+
bool isCacheFile = !ff8 && strstr(newIn.data(), ".p") != NULL;
3639

3740
if (wantsSteamPath && !fileExists(in))
3841
{
@@ -133,11 +136,11 @@ int attempt_redirection(char* in, char* out, size_t size, bool wantsSteamPath)
133136
}
134137
else if (!isCacheFile)
135138
{
136-
const char* pos = strstr(newIn.data(), "data");
139+
const char* pos = ff8 ? newIn.data() : strstr(newIn.data(), "data");
137140

138141
if (pos != NULL)
139142
{
140-
pos += 5;
143+
pos += ff8 ? 0 : 5;
141144
}
142145
else
143146
{
@@ -169,9 +172,9 @@ int attempt_redirection(char* in, char* out, size_t size, bool wantsSteamPath)
169172
return -1;
170173
}
171174

172-
int redirect_path_with_override(char* in, char* out, size_t out_size)
175+
int redirect_path_with_override(const char* in, char* out, size_t out_size)
173176
{
174-
char _newFilename[260]{ 0 };
177+
char _newFilename[MAX_PATH]{ 0 };
175178

176179
// Attempt another redirection based on Steam/eStore logic
177180
int redirect_status = attempt_redirection(in, _newFilename, sizeof(_newFilename), steam_edition || estore_edition);
@@ -206,4 +209,4 @@ int redirect_path_with_override(char* in, char* out, size_t out_size)
206209
}
207210

208211
return redirect_status;
209-
}
212+
}

src/redirect.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@
1919
// GNU General Public License for more details. //
2020
/****************************************************************************/
2121

22-
int attempt_redirection(char* in, char* out, size_t size, bool wantsSteamPath = false);
23-
int redirect_path_with_override(char* in, char* out, size_t out_size);
22+
int attempt_redirection(const char* in, char* out, size_t size, bool wantsSteamPath = false);
23+
int redirect_path_with_override(const char* in, char* out, size_t out_size);

0 commit comments

Comments
 (0)