mirror of
https://github.com/libretro/snes9x.git
synced 2026-10-17 15:25:43 +00:00
Pull the libretro VFS stack into libretro/libretro-common (from the snes9x2010 tree's curated copy): vfs_implementation, file_stream, file_stream_transforms, file_path/file_path_io, the compat family (strl/posix_string/strcasestr/snprintf/fopen_utf8), encoding_utf, stdstring and rtime, plus the include tree. libretro.h is upgraded to the current version -- required because file_path_io uses the retro_vfs_stat_64_t extension the old 2020-era header predates. A file_stream_transforms.h header is reconstructed from the .c's signatures (the source tree ships the implementation without it). Makefile.common builds these outside STATIC_LINKING, same split as snes9x2010: statically linked frontends export all of these symbols themselves. retro_set_environment now requests RETRO_ENVIRONMENT_GET_VFS_INTERFACE and initializes filestream and path with it; without a frontend VFS, filestream falls back to its local implementation. Conversion: - The FSTREAM macro layer in snes9x.h moves wholesale from the ZLIB/stdio dual implementation to RFILE (rfopen family), which converts every STREAM/fStream consumer at once: stream.cpp, snapshot.cpp, msu1's fStream path, conffile parsing, memmap's soft-patch loader and snes9x.cpp. Compressed (.gz) stream support is gone by design -- the frontend handles compressed content. REOPEN_FSTREAM / reopenStreamFromFd (fdopen-based, no VFS equivalent, zero callers) are deleted. - Direct stdio converted to RFILE: memmap (BIOS + SRTC RTC data), crosshairs (text format), cheats2 (load/save), apu (SPC dump), conffile SaveTo, bsx (Satellaview stream files; SBSX struct fields retyped), libretro.cpp's BIOS loader, and the DEBUGGER trace handles in debug.h / snes9x.cpp / cpuops.cpp. - bml switches from std::ifstream to filestream_read_file plus an std::istringstream; the parser itself now takes std::istream. - minizip's ioapi.c backend is rewritten on RFILE, so unzOpen (zipped ROM loading, MSU-1 .msu1 packs) goes through the VFS; the stdio fopen64/fseeko64 platform selection in ioapi.h is removed. The unused minizip tools (zip.c, miniunz.c, minizip.c, mztools, iowin32) are deleted. zlib remains linked for DEFLATE decompression only. - crosshairs' HAVE_LIBPNG block is removed: never defined in this build, and png_init_io requires stdio FILE. stderr/stdout console logging is intentionally untouched -- it is not file I/O. After conversion, a tree-wide audit finds no fopen family, gzopen, fstream, or fdopen outside libretro-common. Validation: - Functional VFS smoke: loading a ROM by path (data == NULL) through memmap -> fStream -> filestream produces the byte-identical m7 test ROM hash, and loading the same ROM from a .zip exercises loadzip -> unzip -> the RFILE ioapi backend with the identical hash again. - Full gauntlet byte-exact: Contra III savestate vs pre-port oracle, Mega Man X2, Mode 5 bright/dim, m7 option matrix, probe (serialize size 823407). - ASan+UBSan+LSan over the probe, the path-load and the zip-load scenarios: zero findings in the new I/O paths; the only report is a pre-existing 288-byte S9xGetCommandT leak (controls.cpp input bindings, unrelated). Untested but converted by the same mechanical mapping: SRTC RTC file, BS-X Satellaview streams, cheat file save, SPC dump, DEBUGGER traces.
389 lines
8.0 KiB
C++
389 lines
8.0 KiB
C++
/*****************************************************************************\
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
This file is licensed under the Snes9x License.
|
|
For further information, consult the LICENSE file in the root directory.
|
|
\*****************************************************************************/
|
|
|
|
#include "port.h"
|
|
#include "crosshairs.h"
|
|
#include <streams/file_stream_transforms.h>
|
|
|
|
static const char *crosshairs[32] =
|
|
{
|
|
"` " // Crosshair 0 (no image)
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" ",
|
|
|
|
"` " // Crosshair 1 (the classic small dot)
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" #. "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" ",
|
|
|
|
"` " // Crosshair 2 (a standard cross)
|
|
" "
|
|
" "
|
|
" "
|
|
" .#. "
|
|
" .#. "
|
|
" ...#... "
|
|
" ####### "
|
|
" ...#... "
|
|
" .#. "
|
|
" .#. "
|
|
" "
|
|
" "
|
|
" "
|
|
" ",
|
|
|
|
"` .#. " // Crosshair 3 (a standard cross)
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
".......#......."
|
|
"###############"
|
|
".......#......."
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. ",
|
|
|
|
"` " // Crosshair 4 (an X)
|
|
" "
|
|
" "
|
|
" . . "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#.#. "
|
|
" .#. "
|
|
" .#.#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" . . "
|
|
" "
|
|
" "
|
|
" ",
|
|
|
|
"`. . " // Crosshair 5 (an X)
|
|
".#. .#."
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#.#. "
|
|
" .#. "
|
|
" .#.#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
".#. .#."
|
|
" . . ",
|
|
|
|
"` " // Crosshair 6 (a combo)
|
|
" "
|
|
" "
|
|
" "
|
|
" # . # "
|
|
" # . # "
|
|
" #.# "
|
|
" ...#... "
|
|
" #.# "
|
|
" # . # "
|
|
" # . # "
|
|
" "
|
|
" "
|
|
" "
|
|
" ",
|
|
|
|
"` . " // Crosshair 7 (a combo)
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" #.# "
|
|
".......#......."
|
|
" #.# "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" . ",
|
|
|
|
"` # " // Crosshair 8 (a diamond cross)
|
|
" #.# "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
"#......#......#"
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" #.# "
|
|
" # ",
|
|
|
|
"` ### " // Crosshair 9 (a circle cross)
|
|
" ## . ## "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
"# . #"
|
|
"#......#......#"
|
|
"# . #"
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" ## . ## "
|
|
" ### ",
|
|
|
|
"` .#. " // Crosshair 10 (a square cross)
|
|
" .#. "
|
|
" .#. "
|
|
" ....#.... "
|
|
" .#######. "
|
|
" .# #. "
|
|
"....# #...."
|
|
"##### #####"
|
|
"....# #...."
|
|
" .# #. "
|
|
" .#######. "
|
|
" ....#.... "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. ",
|
|
|
|
"` .#. " // Crosshair 11 (an interrupted cross)
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" "
|
|
"..... ....."
|
|
"##### #####"
|
|
"..... ....."
|
|
" "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. "
|
|
" .#. ",
|
|
|
|
"`. . " // Crosshair 12 (an interrupted X)
|
|
".#. .#."
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
" .#. .#. "
|
|
".#. .#."
|
|
" . . ",
|
|
|
|
"` . " // Crosshair 13 (an interrupted combo)
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" "
|
|
" "
|
|
"..... ....."
|
|
" "
|
|
" "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" # . # "
|
|
" . ",
|
|
|
|
"`#### #### " // Crosshair 14
|
|
"#.... ....#"
|
|
"#. .#"
|
|
"#. .#"
|
|
"#. .#"
|
|
" # "
|
|
" # "
|
|
" ##### "
|
|
" # "
|
|
" # "
|
|
"#. .#"
|
|
"#. .#"
|
|
"#. .#"
|
|
"#.... ....#"
|
|
" #### #### ",
|
|
|
|
"` .# #. " // Crosshair 15
|
|
" .# #. "
|
|
" .# #. "
|
|
"....# #...."
|
|
"##### #####"
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
" "
|
|
"##### #####"
|
|
"....# #...."
|
|
" .# #. "
|
|
" .# #. "
|
|
" .# #. ",
|
|
|
|
"` # " // Crosshair 16
|
|
" # "
|
|
" # "
|
|
" ....#.... "
|
|
" . # . "
|
|
" . # . "
|
|
" . # . "
|
|
"###############"
|
|
" . # . "
|
|
" . # . "
|
|
" . # . "
|
|
" ....#.... "
|
|
" # "
|
|
" # "
|
|
" # ",
|
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
|
|
bool S9xLoadCrosshairFile (int idx, const char *filename)
|
|
{
|
|
if (idx < 1 || idx > 31)
|
|
return (false);
|
|
|
|
char *s = (char *) calloc(15 * 15 + 1, sizeof(char));
|
|
if (s == NULL)
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: malloc error while reading ");
|
|
perror(filename);
|
|
return (false);
|
|
}
|
|
|
|
RFILE *fp = rfopen(filename, "rb");
|
|
if (fp == NULL)
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: Couldn't open ");
|
|
perror(filename);
|
|
free(s);
|
|
return (false);
|
|
}
|
|
|
|
size_t l = rfread(s, 1, 8, fp);
|
|
if (l != 8)
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
|
free(s);
|
|
rfclose(fp);
|
|
return (false);
|
|
}
|
|
|
|
/* PNG crosshair support removed with the libretro VFS conversion: it
|
|
was dead in this build (HAVE_LIBPNG never defined) and png_init_io
|
|
requires stdio FILE I/O. Text-format crosshair files remain. */
|
|
{
|
|
l = rfread(s + 8, 1, 15 - 8, fp);
|
|
if (l != 15 - 8)
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: File is too short!\n");
|
|
free(s);
|
|
rfclose(fp);
|
|
return (false);
|
|
}
|
|
|
|
if (rfgetc(fp) != '\n')
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
|
free(s);
|
|
rfclose(fp);
|
|
return (false);
|
|
}
|
|
|
|
for (int r = 1; r < 15; r++)
|
|
{
|
|
l = rfread(s + r * 15, 1, 15, fp);
|
|
if (l != 15)
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: File is too short! (note: PNG support is not available)\n");
|
|
free(s);
|
|
rfclose(fp);
|
|
return (false);
|
|
}
|
|
|
|
if (rfgetc(fp) != '\n')
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
|
free(s);
|
|
rfclose(fp);
|
|
return (false);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 15 * 15; i++)
|
|
{
|
|
if (s[i] != ' ' && s[i] != '#' && s[i] != '.')
|
|
{
|
|
fprintf(stderr, "S9xLoadCrosshairFile: Invalid file format! (note: PNG support is not available)\n");
|
|
free(s);
|
|
rfclose(fp);
|
|
return (false);
|
|
}
|
|
}
|
|
}
|
|
|
|
rfclose(fp);
|
|
|
|
if (crosshairs[idx] != NULL && crosshairs[idx][0] != '`')
|
|
free((void *) crosshairs[idx]);
|
|
crosshairs[idx] = s;
|
|
|
|
return (true);
|
|
}
|
|
|
|
const char * S9xGetCrosshair (int idx)
|
|
{
|
|
if (idx < 0 || idx > 31)
|
|
return (NULL);
|
|
|
|
return (crosshairs[idx]);
|
|
}
|