Summary
Songs from previous styles do not load at all when launching the game using bemanitools 5.44. Version 5.43 works fine.
Expected behavior
Old songs should be playable
Current behavior
Old songs simply kick you right back to the song selection screen
Detailed Description
On the songwheel, the old songs all show a BPM of 000 and have no preview. Selecting a broken song will show the transition screen, then go right back to the song selection screen without advancing to the next stage. Absolutely nothing has changed in this setup except for replacing bemanitools 5.43 with 5.44. I've also tried deleting all the backup data and making new backup data by launching with bemanitools 5.44, but that didn't help.
At a glance, this seems to affect all songs from Resort Anthem and earlier, but no songs from Lincle.
I tried on both CGDev and Arcana, as well as with no network, on the offchance it was a network issue.
Trying to play a dan course (just for fun) crashed the game.
Looking at the log showed me a bunch of stuff like this:
[2023/04/07 21:37:27] M:ifs-snd-redir: Sound data redirect: /sd00/0100/0100a.2dx -> /data/sound/0100/0100a.2dx
[2023/04/07 21:37:27] M:ifs-snd-redir: Success, use /data/sound/0100/0100a.2dx
(that example is when I picked a dan course and it immediately crashed, there's nothing in the log after that)
There is no /data/sound/0100 folder, nor a lot of other folders that one would expect to be there. It seems Lincle stores a bunch of its sound data packed into ifs files in the data/imagefs folder.
edit: oh, taking another look at the log, it looks like bemanitools is attempting to mount those IFS files into those nonexistent /data/sound/ folders, clearly something is going wrong though
edit2: It occurred to me that this might be caused by a readonly issue with the data folder, so I made sure the data folder and everything in it was not read-only, this issue is still occurring
Steps to reproduce
Start the game
Start a new credit
Try to select a song from a style earlier than Lincle. Notice the lack of preview and the BPM listing of 000
Select a broken song
Bemanitools version(s) affected
5.44 only
Game(s) and version(s) affected
beatmania IIDX 19 Lincle
Command line arguments
Nothing other than the defaults in gamestart.bat
Summary
Songs from previous styles do not load at all when launching the game using bemanitools 5.44. Version 5.43 works fine.
Expected behavior
Old songs should be playable
Current behavior
Old songs simply kick you right back to the song selection screen
Detailed Description
On the songwheel, the old songs all show a BPM of 000 and have no preview. Selecting a broken song will show the transition screen, then go right back to the song selection screen without advancing to the next stage. Absolutely nothing has changed in this setup except for replacing bemanitools 5.43 with 5.44. I've also tried deleting all the backup data and making new backup data by launching with bemanitools 5.44, but that didn't help.
At a glance, this seems to affect all songs from Resort Anthem and earlier, but no songs from Lincle.
I tried on both CGDev and Arcana, as well as with no network, on the offchance it was a network issue.
Trying to play a dan course (just for fun) crashed the game.
Looking at the log showed me a bunch of stuff like this:
```
[2023/04/07 21:37:27] M:ifs-snd-redir: Sound data redirect: /sd00/0100/0100a.2dx -> /data/sound/0100/0100a.2dx
[2023/04/07 21:37:27] M:ifs-snd-redir: Success, use /data/sound/0100/0100a.2dx
```
(that example is when I picked a dan course and it immediately crashed, there's nothing in the log after that)
There is no /data/sound/0100 folder, nor a lot of other folders that one would expect to be there. It seems Lincle stores a bunch of its sound data packed into ifs files in the data/imagefs folder.
edit: oh, taking another look at the log, it looks like bemanitools is *attempting* to mount those IFS files into those nonexistent /data/sound/ folders, clearly something is going wrong though
edit2: It occurred to me that this might be caused by a readonly issue with the data folder, so I made sure the data folder and everything in it was not read-only, this issue is still occurring
Steps to reproduce
1. Start the game
2. Start a new credit
3. Try to select a song from a style earlier than Lincle. Notice the lack of preview and the BPM listing of 000
4. Select a broken song
Bemanitools version(s) affected
5.44 only
Game(s) and version(s) affected
beatmania IIDX 19 Lincle
Command line arguments
Nothing other than the defaults in gamestart.bat
APIs used
None
OS version
Windows 11 Pro Canary 25330
Hardware specs
CPU: Intel Core i7-12700H, 2300 Mhz
RAM: 16 GB
GPU: NVIDIA GeForce RTX 3060 Laptop GPU, 6 GB
Controllers/IO: Built-in laptop keyboard (10keyless)
So taking a cursory look at the code, when the my_avs_fs_open function is called in ifs-snd-redir.c, real_avs_fs_open seems to be returning a non-null handle even though the file doesn't exist. Commenting out the success case and falling back to using the imagefs files instead will fix this, as you'd imagine, but I don't know if removing this functionality will break the timebase thing you added in 5.44
This is all I did to change the code to get it to work, in case I worded it confusingly above:
So taking a cursory look at the code, when the my_avs_fs_open function is called in ifs-snd-redir.c, real_avs_fs_open seems to be returning a non-null handle even though the file doesn't exist. Commenting out the success case and falling back to using the imagefs files instead will fix this, as you'd imagine, but I don't know if removing this functionality will break the timebase thing you added in 5.44
This is all I did to change the code to get it to work, in case I worded it confusingly above:
```
//if (handle != NULL) {
// log_misc("Success, use %s", redir_path);
// return handle;
//} else {
log_misc("Failure, use %s", path);
return real_avs_fs_open(path, mode, flags);
//}
```
Thanks for triaging the problem. I have to take a look and test this again. I remember I ran into some confusing parts and also had songs not loading. This resolved after I cleaned up my code, I thought. I might have missed something and forgot to test it in the end.
Thanks for triaging the problem. I have to take a look and test this again. I remember I ran into some confusing parts and also had songs not loading. This resolved after I cleaned up my code, I thought. I might have missed something and forgot to test it in the end.
handle = real_avs_fs_open(redir_path, mode, flags);
if (handle != NULL) {
log_misc("Success, use %s", redir_path);
return handle;
} else {
log_misc("Failure, use %s", path);
return real_avs_fs_open(path, mode, flags);
}
As mentioned in post above it's failing here.
In AVS2 library, avs_fs_open should only returns a 32-bit value regardless in x86 or x64 builds, and will error out with return value has highest bit set to 1, but not setting the return value to 0. This means checking it fail should be try with handle & 0x80000000 or if you set return type to int32_t you can just check if it less than 0. Also, it will consider open failed with return value 0.
Here's the fix I come up with:
static int32_t (*real_avs_fs_open)(const char *path, int mode, int flags);
static int32_t my_avs_fs_open(const char *path, int mode, int flags);
static const struct hook_symbol iidxhook5_ifs_snd_redir_hook_syms[] = {
{.name = "XC058ba50000b6", // avs_fs_open
.patch = my_avs_fs_open,
.link = (void **) &real_avs_fs_open},
};
static int32_t my_avs_fs_open(const char *path, int mode, int flags)
{
int32_t handle;
char redir_path[MAX_PATH];
// Trap virtual path /sd00/*, /sd01/*, /sd02/*, /sd03/* that contain
// sound data that is stored in ifs files in data/imagefs
// Create a generice override strategy by redirecting to local folder
// /sound/*. Check if open succeeds and return that. Otherwise, stay on
// imagefs path to stay compatible with stock data.
if (!strncmp(path, "/sd0", 4)) {
strcpy(redir_path, "/data/sound");
strcat(redir_path, &path[5]);
log_misc("Sound data redirect: %s -> %s", path, redir_path);
handle = real_avs_fs_open(redir_path, mode, flags);
if (handle > 0) {
log_misc("Success, use %s", redir_path);
return handle;
} else {
log_misc("Failure, use %s", path);
return real_avs_fs_open(path, mode, flags);
}
}
return real_avs_fs_open(path, mode, flags);
}
Now it will be a bit deeper.
What is this hook doing
At first, it seems that it will redirect all sound data open from imagefs file to plain file if exists. But these are what I found in bm2dx.dll from KDZJAA2012090300:
// dword_1011AC78
int mid_exclude_array[] = { 208, 404, 509, 844, 847, 954, 1115, 1126, 1150, 1250 };
// sub_1007E240
int get_imagefs_id(int mid) {
for (int i = 0; i < _countof(mid_exclude_array); i++) {
if (mid == mid_exclude_array[i]) return 4;
}
if (mid < 1000) return 0;
if (mid < 1400) return 1;
if (mid < 1700) return 2;
if (mid < 1900) return 3;
return 4;
}
// sub_1007E2C0
void get_snd_real_path(int* _this, const char* path_snd, char* buf, size_t sz_buf) {
if (path_snd && buf) {
_snprintf_s(buf, sz_buf, sz_buf, "%s%s", "/data/sound/", path_snd);
int mid = 0;
if (sscanf_s(path_snd, "%d/*.*", &mid)) {
int snd_file_id = get_imagefs_id(mid);
if (snd_file_id <= 3
&& _this[snd_file_id + 20] > 0)
_snprintf_s(buf, sz_buf, sz_buf, "/sd%02d/%s", snd_file_id, path_snd);
}
}
}
So what this mean is in vallina IIDX 19 LINCLE the hook will try to map every file that not exists in /data/sound/* to /data/sound/*, which means it will always failed to serve its purpose.
Either you manually extract all /data/imagefs/*.ifs to sound folder or using something like omnimix, this hook will always do nothing since for the game, non-ifs sound file will never use /sd%02d/ prefix.
I'm not sure if it's for some other hooks like monitor check, but at the moment this hook does nothing and maybe consider can be removed I guess...?
Just get this issue also, and it should be fixable.
## How it caused
So after checking the log I saw something in it:
```
...
[2024/12/06 17:48:20] M:ifs-snd-redir: Sound data redirect: /sd00/0100/0100.1 -> /data/sound/0100/0100.1
[2024/12/06 17:48:39] M:ifs-snd-redir: Success, use /data/sound/0100/0100.1
[2024/12/06 17:48:39] M:ifs-snd-redir: Sound data redirect: /sd00/0101/0101.1 -> /data/sound/0101/0101.1
[2024/12/06 17:48:44] M:ifs-snd-redir: Success, use /data/sound/0101/0101.1
[2024/12/06 17:48:44] M:ifs-snd-redir: Sound data redirect: /sd00/0103/0103.1 -> /data/sound/0103/0103.1
[2024/12/06 17:48:44] M:ifs-snd-redir: Success, use /data/sound/0103/0103.1
[2024/12/06 17:48:44] M:ifs-snd-redir: Sound data redirect: /sd00/0104/0104.1 -> /data/sound/0104/0104.1
[2024/12/06 17:48:44] M:ifs-snd-redir: Success, use /data/sound/0104/0104.1
[2024/12/06 17:48:44] M:ifs-snd-redir: Sound data redirect: /sd00/0105/0105.1 -> /data/sound/0105/0105.1
[2024/12/06 17:48:45] M:ifs-snd-redir: Success, use /data/sound/0105/0105.1
[2024/12/06 17:48:45] M:ifs-snd-redir: Sound data redirect: /sd00/0106/0106.1 -> /data/sound/0106/0106.1
[2024/12/06 17:48:46] M:ifs-snd-redir: Success, use /data/sound/0106/0106.1
[2024/12/06 17:48:46] M:ifs-snd-redir: Sound data redirect: /sd00/0108/0108.1 -> /data/sound/0108/0108.1
[2024/12/06 17:48:46] M:ifs-snd-redir: Success, use /data/sound/0108/0108.1
...
```
Which are impossible since these file aren't exists there. In fact, they should be in ``/data/imagefs/sd%02d.ifs`` instead.
Then I check the function call from it in [src/main/iidxhook5/ifs-snd-redir.c](https://github.com/djhackersdev/bemanitools/blob/48668837a8f68fe2e2a5b11f5caf378f3d5422d3/src/main/iidxhook5/ifs-snd-redir.c) :
```
handle = real_avs_fs_open(redir_path, mode, flags);
if (handle != NULL) {
log_misc("Success, use %s", redir_path);
return handle;
} else {
log_misc("Failure, use %s", path);
return real_avs_fs_open(path, mode, flags);
}
```
As mentioned in post above it's failing here.
In AVS2 library, avs_fs_open should only returns a 32-bit value regardless in x86 or x64 builds, and will error out with return value has highest bit set to 1, but not setting the return value to 0. This means checking it fail should be try with ``handle & 0x80000000`` or if you set return type to ``int32_t`` you can just check if it less than 0. Also, it will consider open failed with return value 0.
Here's the fix I come up with:
```
static int32_t (*real_avs_fs_open)(const char *path, int mode, int flags);
static int32_t my_avs_fs_open(const char *path, int mode, int flags);
static const struct hook_symbol iidxhook5_ifs_snd_redir_hook_syms[] = {
{.name = "XC058ba50000b6", // avs_fs_open
.patch = my_avs_fs_open,
.link = (void **) &real_avs_fs_open},
};
static int32_t my_avs_fs_open(const char *path, int mode, int flags)
{
int32_t handle;
char redir_path[MAX_PATH];
// Trap virtual path /sd00/*, /sd01/*, /sd02/*, /sd03/* that contain
// sound data that is stored in ifs files in data/imagefs
// Create a generice override strategy by redirecting to local folder
// /sound/*. Check if open succeeds and return that. Otherwise, stay on
// imagefs path to stay compatible with stock data.
if (!strncmp(path, "/sd0", 4)) {
strcpy(redir_path, "/data/sound");
strcat(redir_path, &path[5]);
log_misc("Sound data redirect: %s -> %s", path, redir_path);
handle = real_avs_fs_open(redir_path, mode, flags);
if (handle > 0) {
log_misc("Success, use %s", redir_path);
return handle;
} else {
log_misc("Failure, use %s", path);
return real_avs_fs_open(path, mode, flags);
}
}
return real_avs_fs_open(path, mode, flags);
}
```
Now it will be a bit deeper.
## What is this hook doing
At first, it seems that it will redirect all sound data open from imagefs file to plain file if exists. But these are what I found in ``bm2dx.dll`` from ``KDZJAA2012090300``:
```
// dword_1011AC78
int mid_exclude_array[] = { 208, 404, 509, 844, 847, 954, 1115, 1126, 1150, 1250 };
// sub_1007E240
int get_imagefs_id(int mid) {
for (int i = 0; i < _countof(mid_exclude_array); i++) {
if (mid == mid_exclude_array[i]) return 4;
}
if (mid < 1000) return 0;
if (mid < 1400) return 1;
if (mid < 1700) return 2;
if (mid < 1900) return 3;
return 4;
}
// sub_1007E2C0
void get_snd_real_path(int* _this, const char* path_snd, char* buf, size_t sz_buf) {
if (path_snd && buf) {
_snprintf_s(buf, sz_buf, sz_buf, "%s%s", "/data/sound/", path_snd);
int mid = 0;
if (sscanf_s(path_snd, "%d/*.*", &mid)) {
int snd_file_id = get_imagefs_id(mid);
if (snd_file_id <= 3
&& _this[snd_file_id + 20] > 0)
_snprintf_s(buf, sz_buf, sz_buf, "/sd%02d/%s", snd_file_id, path_snd);
}
}
}
```
And here's the content of my sound folder:
```
M:\BEMANI\iidx\KDZJAA2012090300\contents\data\sound>dir /ad/w/b
0208
0404
0422
0509
0844
0847
0954
1115
1126
1150
1250
1900
1901
1902
1903
1904
1905
...
```
So what this mean is in vallina IIDX 19 LINCLE the hook will try to map every file that not exists in ``/data/sound/*`` to ``/data/sound/*``, which means it will always failed to serve its purpose.
Either you manually extract all ``/data/imagefs/*.ifs`` to sound folder or using something like omnimix, this hook will always do nothing since for the game, non-ifs sound file will never use ``/sd%02d/`` prefix.
I'm not sure if it's for some other hooks like monitor check, but at the moment this hook does nothing and maybe consider can be removed I guess...?
Quick fix if you don't want to recompile by your own:
Open iidxhook5.dll, find hex 85C08944241C742B896C2408, replace with 85C08944241C7C2B896C2408 (replace 0x74 (jz) to 0x7C (jl))
Quick fix if you don't want to recompile by your own:
Open ``iidxhook5.dll``, find hex ``85C08944241C742B896C2408``, replace with ``85C08944241C7C2B896C2408`` (replace ``0x74 (jz)`` to ``0x7C (jl)``)
I haven't gotten around to work on this issue so far, and it's also not clear when I will.
Some context that might not be obvious:
The idea of the current code is to work around the issue that bemanitools's timebase feature has not considered avs file access so far. The "fix" for me was to extract the ifs files to plain files and read them from /data/sound. With all sound data as plain files, the current timebase implementation works as well.
Otherwise, the code will serve no purpose.
The better solution to this would probably be to support timebase with the ifs files.
This was done in the context of another project to run the game on modern hardware.
I haven't gotten around to work on this issue so far, and it's also not clear when I will.
Some context that might not be obvious:
The idea of the current code is to work around the issue that bemanitools's timebase feature has not considered avs file access so far. The "fix" for me was to extract the ifs files to plain files and read them from `/data/sound`. With all sound data as plain files, the current timebase implementation works as well.
Otherwise, the code will serve no purpose.
The better solution to this would probably be to support timebase with the ifs files.
This was done in the context of another project to run the game on modern hardware.
For this I think one of the work around will be use avs_fs_copy the /sd%02d/%04d/%04d.1 to somewhere like /timebase_cached/%04d.1 if not exists, then redir with the function above.
Another workaround will be hooking avs_fs_open, avs_fs_close and avs_fs_read. When open .1 files throw the handle into something like map, use avs_fs_read to read the whole file into a temporary buffer, then modify the chart in memory. When the game call avs_fs_read on handle that matches, provide data from modified buffer instead of the file (may need to hook seek function also). And of course remove the handle and destroy the buffer on close.
For this I think one of the work around will be use ``avs_fs_copy`` the ``/sd%02d/%04d/%04d.1`` to somewhere like ``/timebase_cached/%04d.1`` if not exists, then redir with the function above.
Another workaround will be hooking ``avs_fs_open``, ``avs_fs_close`` and ``avs_fs_read``. When open ``.1`` files throw the handle into something like map, use ``avs_fs_read`` to read the whole file into a temporary buffer, then modify the chart in memory. When the game call ``avs_fs_read`` on handle that matches, provide data from modified buffer instead of the file (may need to hook seek function also). And of course remove the handle and destroy the buffer on close.
For this I think one of the work around will be use avs_fs_copy the /sd%02d/%04d/%04d.1 to somewhere like /timebase_cached/%04d.1 if not exists, then redir with the function above.
I would label that even as a good solution to the problem and not just a workaround.
Another workaround will be hooking avs_fs_open, avs_fs_close and avs_fs_read. When open .1 files throw the handle into something like map, use avs_fs_read to read the whole file into a temporary buffer, then modify the chart in memory. When the game call avs_fs_read on handle that matches, provide data from modified buffer instead of the file (may need to hook seek function also). And of course remove the handle and destroy the buffer on close.
Yeah, that's about what I had in mind. It's essentially the same approach that timebase is doing already, but using the standard file API and not the AVS fs API.
I think both are very valid and good solution directions to address the actual problem. Would you be up for implementing one of them? I leave the decision up to you which one to pick.
I am around for support regarding questions and code review if you need me for that. Looking forward to more external contributions driving the project, and not just having it depend on my limited capacity.
> For this I think one of the work around will be use `avs_fs_copy` the `/sd%02d/%04d/%04d.1` to somewhere like `/timebase_cached/%04d.1` if not exists, then redir with the function above.
I would label that even as a good solution to the problem and not just a workaround.
> Another workaround will be hooking `avs_fs_open`, `avs_fs_close` and `avs_fs_read`. When open `.1` files throw the handle into something like map, use `avs_fs_read` to read the whole file into a temporary buffer, then modify the chart in memory. When the game call `avs_fs_read` on handle that matches, provide data from modified buffer instead of the file (may need to hook seek function also). And of course remove the handle and destroy the buffer on close.
Yeah, that's about what I had in mind. It's essentially the same approach that timebase is doing already, but using the standard file API and not the AVS fs API.
I think both are very valid and good solution directions to address the actual problem. Would you be up for implementing one of them? I leave the decision up to you which one to pick.
I am around for support regarding questions and code review if you need me for that. Looking forward to more external contributions driving the project, and not just having it depend on my limited capacity.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Songs from previous styles do not load at all when launching the game using bemanitools 5.44. Version 5.43 works fine.
Expected behavior
Old songs should be playable
Current behavior
Old songs simply kick you right back to the song selection screen
Detailed Description
On the songwheel, the old songs all show a BPM of 000 and have no preview. Selecting a broken song will show the transition screen, then go right back to the song selection screen without advancing to the next stage. Absolutely nothing has changed in this setup except for replacing bemanitools 5.43 with 5.44. I've also tried deleting all the backup data and making new backup data by launching with bemanitools 5.44, but that didn't help.
At a glance, this seems to affect all songs from Resort Anthem and earlier, but no songs from Lincle.
I tried on both CGDev and Arcana, as well as with no network, on the offchance it was a network issue.
Trying to play a dan course (just for fun) crashed the game.
Looking at the log showed me a bunch of stuff like this:
(that example is when I picked a dan course and it immediately crashed, there's nothing in the log after that)
There is no /data/sound/0100 folder, nor a lot of other folders that one would expect to be there. It seems Lincle stores a bunch of its sound data packed into ifs files in the data/imagefs folder.
edit: oh, taking another look at the log, it looks like bemanitools is attempting to mount those IFS files into those nonexistent /data/sound/ folders, clearly something is going wrong though
edit2: It occurred to me that this might be caused by a readonly issue with the data folder, so I made sure the data folder and everything in it was not read-only, this issue is still occurring
Steps to reproduce
Bemanitools version(s) affected
5.44 only
Game(s) and version(s) affected
beatmania IIDX 19 Lincle
Command line arguments
Nothing other than the defaults in gamestart.bat
APIs used
None
OS version
Windows 11 Pro Canary 25330
Hardware specs
CPU: Intel Core i7-12700H, 2300 Mhz
RAM: 16 GB
GPU: NVIDIA GeForce RTX 3060 Laptop GPU, 6 GB
Controllers/IO: Built-in laptop keyboard (10keyless)
So taking a cursory look at the code, when the my_avs_fs_open function is called in ifs-snd-redir.c, real_avs_fs_open seems to be returning a non-null handle even though the file doesn't exist. Commenting out the success case and falling back to using the imagefs files instead will fix this, as you'd imagine, but I don't know if removing this functionality will break the timebase thing you added in 5.44
This is all I did to change the code to get it to work, in case I worded it confusingly above:
Thanks for triaging the problem. I have to take a look and test this again. I remember I ran into some confusing parts and also had songs not loading. This resolved after I cleaned up my code, I thought. I might have missed something and forgot to test it in the end.
bump. also having this issue with 5.44, using an older version works fine.
Just get this issue also, and it should be fixable.
How it caused
So after checking the log I saw something in it:
Which are impossible since these file aren't exists there. In fact, they should be in
/data/imagefs/sd%02d.ifsinstead.Then I check the function call from it in src/main/iidxhook5/ifs-snd-redir.c :
As mentioned in post above it's failing here.
In AVS2 library, avs_fs_open should only returns a 32-bit value regardless in x86 or x64 builds, and will error out with return value has highest bit set to 1, but not setting the return value to 0. This means checking it fail should be try with
handle & 0x80000000or if you set return type toint32_tyou can just check if it less than 0. Also, it will consider open failed with return value 0.Here's the fix I come up with:
Now it will be a bit deeper.
What is this hook doing
At first, it seems that it will redirect all sound data open from imagefs file to plain file if exists. But these are what I found in
bm2dx.dllfromKDZJAA2012090300:And here's the content of my sound folder:
So what this mean is in vallina IIDX 19 LINCLE the hook will try to map every file that not exists in
/data/sound/*to/data/sound/*, which means it will always failed to serve its purpose.Either you manually extract all
/data/imagefs/*.ifsto sound folder or using something like omnimix, this hook will always do nothing since for the game, non-ifs sound file will never use/sd%02d/prefix.I'm not sure if it's for some other hooks like monitor check, but at the moment this hook does nothing and maybe consider can be removed I guess...?
Quick fix if you don't want to recompile by your own:
Open
iidxhook5.dll, find hex85C08944241C742B896C2408, replace with85C08944241C7C2B896C2408(replace0x74 (jz)to0x7C (jl))I haven't gotten around to work on this issue so far, and it's also not clear when I will.
Some context that might not be obvious:
The idea of the current code is to work around the issue that bemanitools's timebase feature has not considered avs file access so far. The "fix" for me was to extract the ifs files to plain files and read them from
/data/sound. With all sound data as plain files, the current timebase implementation works as well.Otherwise, the code will serve no purpose.
The better solution to this would probably be to support timebase with the ifs files.
This was done in the context of another project to run the game on modern hardware.
For this I think one of the work around will be use
avs_fs_copythe/sd%02d/%04d/%04d.1to somewhere like/timebase_cached/%04d.1if not exists, then redir with the function above.Another workaround will be hooking
avs_fs_open,avs_fs_closeandavs_fs_read. When open.1files throw the handle into something like map, useavs_fs_readto read the whole file into a temporary buffer, then modify the chart in memory. When the game callavs_fs_readon handle that matches, provide data from modified buffer instead of the file (may need to hook seek function also). And of course remove the handle and destroy the buffer on close.I would label that even as a good solution to the problem and not just a workaround.
Yeah, that's about what I had in mind. It's essentially the same approach that timebase is doing already, but using the standard file API and not the AVS fs API.
I think both are very valid and good solution directions to address the actual problem. Would you be up for implementing one of them? I leave the decision up to you which one to pick.
I am around for support regarding questions and code review if you need me for that. Looking forward to more external contributions driving the project, and not just having it depend on my limited capacity.