mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-11-01 00:15:14 +01:00
edf269f97d
- added: mapped zooming and turbo mode to classic controller - added: preliminary usb support (loading) - changed: sram and freezes now saved by filename, not internal romname. If you have multiple versions of the same game, you can now have srams and freezes for each version. A prompt to convert to the new naming is provided for sram only. - changed: by default, autoload/save sram and freeze enabled
485 lines
12 KiB
C++
485 lines
12 KiB
C++
/****************************************************************************
|
|
* Snes9x 1.50
|
|
*
|
|
* Nintendo Gamecube Port
|
|
* softdev July 2006
|
|
* crunchy2 May 2007
|
|
*
|
|
* smbload.cpp
|
|
*
|
|
* Load ROMS from a Network share.
|
|
****************************************************************************/
|
|
#include <gccore.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <ogcsys.h>
|
|
#include <network.h>
|
|
extern "C"
|
|
{
|
|
#include "smb.h"
|
|
}
|
|
#include "unzip.h"
|
|
#include "memmap.h"
|
|
#include "video.h"
|
|
#include "ftfont.h"
|
|
#include "dvd.h"
|
|
#include "filesel.h"
|
|
#include "sram.h"
|
|
#include "preferences.h"
|
|
#include "smbload.h"
|
|
#include "Snes9xGx.h"
|
|
#include <zlib.h>
|
|
|
|
static int connected = 0;
|
|
static int netinited = 0;
|
|
|
|
char output[16384];
|
|
unsigned int SMBTimer = 0;
|
|
extern unsigned char savebuffer[];
|
|
|
|
#define ZIPCHUNK 16384
|
|
#define SMBTIMEOUT ( 3600 ) /*** Some implementations timeout in 10 minutes ***/
|
|
SMBINFO smbinfo =
|
|
{ GC_IP, GW_IP, MASK, SMB_IP,
|
|
SMB_USER, SMB_PWD, SMB_GCID, SMB_SVID, SMB_SHARE
|
|
};
|
|
|
|
extern FILEENTRIES filelist[MAXFILES];
|
|
|
|
/****************************************************************************
|
|
* Mount SMB Share
|
|
****************************************************************************/
|
|
void
|
|
ConnectSMB ()
|
|
{
|
|
int ret;
|
|
|
|
if (SMBTimer > SMBTIMEOUT)
|
|
{
|
|
connected = 0;
|
|
SMBTimer = 0;
|
|
}
|
|
|
|
if (connected == 0)
|
|
{
|
|
|
|
if (netinited == 0)
|
|
{
|
|
ShowAction ((char*) "Setting up network interface ...");
|
|
ret = if_config (smbinfo.gcip, smbinfo.gwip, smbinfo.mask, 0);
|
|
netinited = 1;
|
|
}
|
|
|
|
ShowAction ((char*) "Connecting to share ...");
|
|
SMB_Destroy ();
|
|
|
|
if (SMB_Init (smbinfo.smbuser, smbinfo.smbpwd,
|
|
smbinfo.smbgcid, smbinfo.smbsvid, smbinfo.smbshare,
|
|
smbinfo.smbip) != SMB_SUCCESS)
|
|
{
|
|
WaitPrompt((char*) "Failed to connect to SMB share");
|
|
connected = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
connected = 1;
|
|
|
|
}
|
|
|
|
/****************************************************************************
|
|
* parseSMBDirectory
|
|
*
|
|
* Load the share directory and put in the filelist array
|
|
*****************************************************************************/
|
|
int
|
|
parseSMBDirectory ()
|
|
{
|
|
char searchpath[1024];
|
|
int filecount = 0;
|
|
SMBDIRENTRY smbdir;
|
|
|
|
ConnectSMB ();
|
|
|
|
strcpy (searchpath, SNESROMDIR);
|
|
strcat (searchpath, "\\*.*");
|
|
|
|
if (SMB_FindFirst
|
|
(searchpath, SMB_SRCH_READONLY | SMB_SRCH_SYSTEM | SMB_SRCH_HIDDEN,
|
|
&smbdir) != SMB_SUCCESS)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
do
|
|
{
|
|
memset (&filelist[filecount], 0, sizeof (FILEENTRIES));
|
|
filelist[filecount].length = smbdir.size_low;
|
|
smbdir.name[MAXJOLIET] = 0;
|
|
|
|
/*** Update display name ***/
|
|
memcpy (&filelist[filecount].displayname, smbdir.name, MAXDISPLAY);
|
|
filelist[filecount].displayname[MAXDISPLAY] = 0;
|
|
|
|
strcpy (filelist[filecount].filename, smbdir.name);
|
|
filecount++;
|
|
|
|
}
|
|
while (SMB_FindNext (&smbdir) == SMB_SUCCESS);
|
|
|
|
SMB_FindClose ();
|
|
|
|
return filecount;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Load SMB file
|
|
****************************************************************************/
|
|
int
|
|
LoadSMBFile (char *filename, int length)
|
|
{
|
|
char buffer[128];
|
|
int offset = 0;
|
|
int bytesread = 0;
|
|
int total = 0;
|
|
char filepath[1024];
|
|
SMBFILE smbfile;
|
|
char *rbuffer;
|
|
char zipbuffer[16384];
|
|
int pass = 0;
|
|
int zip = 0;
|
|
PKZIPHEADER pkzip;
|
|
z_stream zs;
|
|
int res, outbytes;
|
|
|
|
strcpy (filepath, SNESROMDIR);
|
|
strcat (filepath, "\\");
|
|
strcat (filepath, filename);
|
|
rbuffer = (char *) Memory.ROM;
|
|
outbytes = 0;
|
|
int have = 0;
|
|
|
|
ConnectSMB ();
|
|
|
|
if ( connected )
|
|
{
|
|
|
|
/*** Open the file for reading ***/
|
|
smbfile =
|
|
SMB_Open (filepath, SMB_OPEN_READING | SMB_DENY_NONE, SMB_OF_OPEN);
|
|
if (smbfile)
|
|
{
|
|
while (total < length)
|
|
{
|
|
bytesread = SMB_Read (zipbuffer, 16384, offset, smbfile);
|
|
|
|
if (pass == 0)
|
|
{
|
|
/*** Is this a Zip file ? ***/
|
|
zip = IsZipFile (zipbuffer);
|
|
if (zip)
|
|
{
|
|
memcpy (&pkzip, zipbuffer, sizeof (PKZIPHEADER));
|
|
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
|
|
memset (&zs, 0, sizeof (zs));
|
|
zs.zalloc = Z_NULL;
|
|
zs.zfree = Z_NULL;
|
|
zs.opaque = Z_NULL;
|
|
zs.avail_in = 0;
|
|
zs.next_in = Z_NULL;
|
|
res = inflateInit2 (&zs, -MAX_WBITS);
|
|
|
|
if (res != Z_OK)
|
|
{
|
|
SMB_Close (smbfile);
|
|
return 0;
|
|
}
|
|
|
|
zs.avail_in =
|
|
16384 - (sizeof (PKZIPHEADER) +
|
|
FLIP16 (pkzip.filenameLength) +
|
|
FLIP16 (pkzip.extraDataLength));
|
|
zs.next_in =
|
|
(Bytef *) zipbuffer + (sizeof (PKZIPHEADER) +
|
|
FLIP16 (pkzip.filenameLength) +
|
|
FLIP16 (pkzip.extraDataLength));
|
|
}
|
|
}
|
|
|
|
if (zip)
|
|
{
|
|
if (pass)
|
|
{
|
|
zs.avail_in = bytesread;
|
|
zs.next_in = (Bytef *) zipbuffer;
|
|
}
|
|
|
|
do
|
|
{
|
|
zs.avail_out = ZIPCHUNK;
|
|
zs.next_out = (Bytef *) output;
|
|
|
|
res = inflate (&zs, Z_NO_FLUSH);
|
|
|
|
have = ZIPCHUNK - zs.avail_out;
|
|
|
|
if (have)
|
|
{
|
|
memcpy (rbuffer + outbytes, output, have);
|
|
outbytes += have;
|
|
}
|
|
}
|
|
while (zs.avail_out == 0);
|
|
}
|
|
else
|
|
memcpy (rbuffer + offset, zipbuffer, bytesread);
|
|
|
|
total += bytesread;
|
|
offset += bytesread;
|
|
|
|
if (!zip)
|
|
{
|
|
sprintf (buffer, "Read %d of %d bytes", total, length);
|
|
ShowProgress (buffer, total, length);
|
|
}
|
|
else
|
|
{
|
|
sprintf (buffer, "Unzipped %d of %d", outbytes,
|
|
pkzip.uncompressedSize);
|
|
ShowProgress (buffer, outbytes, pkzip.uncompressedSize);
|
|
}
|
|
//ShowAction (buffer);
|
|
|
|
pass++;
|
|
|
|
}
|
|
|
|
if (zip)
|
|
{
|
|
inflateEnd (&zs);
|
|
total = outbytes;
|
|
}
|
|
|
|
SMB_Close (smbfile);
|
|
|
|
return total;
|
|
}
|
|
else
|
|
{
|
|
WaitPrompt((char*) "SMB Reading Failed!");
|
|
//while (1);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Write savebuffer to SMB file
|
|
****************************************************************************/
|
|
int
|
|
SaveBufferToSMB (char *filepath, int datasize, bool8 silent)
|
|
{
|
|
SMBFILE smbfile;
|
|
int dsize = datasize;
|
|
int wrote = 0;
|
|
int offset = 0;
|
|
|
|
ConnectSMB ();
|
|
|
|
if ( connected )
|
|
{
|
|
smbfile =
|
|
SMB_Open (filepath, SMB_OPEN_WRITING | SMB_DENY_NONE,
|
|
SMB_OF_CREATE | SMB_OF_TRUNCATE);
|
|
|
|
if (smbfile)
|
|
{
|
|
while (dsize > 0)
|
|
{
|
|
if (dsize > 1024)
|
|
wrote =
|
|
SMB_Write ((char *) savebuffer + offset, 1024, offset, smbfile);
|
|
else
|
|
wrote =
|
|
SMB_Write ((char *) savebuffer + offset, dsize, offset, smbfile);
|
|
|
|
offset += wrote;
|
|
dsize -= wrote;
|
|
}
|
|
|
|
SMB_Close (smbfile);
|
|
SMBTimer = 0;
|
|
|
|
return offset;
|
|
}
|
|
else
|
|
{
|
|
char msg[100];
|
|
sprintf(msg, "Couldn't save SMB:%s", filepath);
|
|
WaitPrompt (msg);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Load savebuffer from SMB file
|
|
****************************************************************************/
|
|
int
|
|
LoadBufferFromSMB (char *filepath, bool8 silent)
|
|
{
|
|
SMBFILE smbfile;
|
|
int ret;
|
|
int offset = 0;
|
|
|
|
ConnectSMB ();
|
|
|
|
if ( connected )
|
|
{
|
|
smbfile =
|
|
SMB_Open (filepath, SMB_OPEN_READING | SMB_DENY_NONE, SMB_OF_OPEN);
|
|
|
|
if (!smbfile)
|
|
{
|
|
if (!silent)
|
|
{
|
|
char msg[100];
|
|
sprintf(msg, "Couldn't open SMB:%s", filepath);
|
|
WaitPrompt (msg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
memset (savebuffer, 0, 0x22000);
|
|
|
|
while ((ret =
|
|
SMB_Read ((char *) savebuffer + offset, 1024, offset,
|
|
smbfile)) > 0)
|
|
offset += ret;
|
|
|
|
SMB_Close (smbfile);
|
|
|
|
return offset;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Save SRAM to SMB
|
|
****************************************************************************/
|
|
void
|
|
SaveSRAMToSMB (bool8 silent)
|
|
{
|
|
char filepath[1024];
|
|
int datasize;
|
|
int offset;
|
|
|
|
sprintf (filepath, "%s\\%s.srm", SNESSAVEDIR, Memory.ROMFilename);
|
|
|
|
if (!silent)
|
|
ShowAction ((char*) "Saving SRAM to SMB...");
|
|
|
|
datasize = prepareEXPORTsavedata ();
|
|
|
|
if ( datasize )
|
|
{
|
|
offset = SaveBufferToSMB (filepath, datasize, silent);
|
|
|
|
if ( (offset > 0) && (!silent) )
|
|
{
|
|
sprintf (filepath, "Wrote %d bytes", offset);
|
|
WaitPrompt (filepath);
|
|
}
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Load SRAM from SMB
|
|
****************************************************************************/
|
|
void
|
|
LoadSRAMFromSMB (bool8 silent)
|
|
{
|
|
char filepath[1024];
|
|
int offset;
|
|
|
|
sprintf (filepath, "%s\\%s.srm", SNESSAVEDIR, Memory.ROMFilename);
|
|
ShowAction ((char*) "Loading SRAM from SMB...");
|
|
|
|
offset = LoadBufferFromSMB (filepath, silent);
|
|
|
|
if (offset > 0)
|
|
{
|
|
decodesavedata (offset);
|
|
if ( !silent )
|
|
{
|
|
sprintf (filepath, "Loaded %d bytes", offset);
|
|
WaitPrompt(filepath);
|
|
}
|
|
S9xSoftReset();
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Save Preferences to SMB
|
|
****************************************************************************/
|
|
void
|
|
SavePrefsToSMB (bool8 silent)
|
|
{
|
|
char filepath[1024];
|
|
int datasize;
|
|
int offset;
|
|
|
|
sprintf (filepath, "%s\\%s", SNESSAVEDIR, PREFS_FILE_NAME);
|
|
|
|
if (!silent)
|
|
ShowAction ((char*) "Saving preferences to SMB...");
|
|
|
|
datasize = preparePrefsData ();
|
|
|
|
if ( datasize )
|
|
{
|
|
offset = SaveBufferToSMB (filepath, datasize, silent);
|
|
|
|
if ( (offset > 0) && (!silent) )
|
|
{
|
|
sprintf (filepath, "Wrote %d bytes", offset);
|
|
WaitPrompt (filepath);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* Load Preferences from SMB
|
|
****************************************************************************/
|
|
void
|
|
LoadPrefsFromSMB (bool8 silent)
|
|
{
|
|
char filepath[1024];
|
|
int offset;
|
|
|
|
ShowAction ((char*) "Loading preferences from SMB...");
|
|
|
|
sprintf (filepath, "%s\\%s", SNESSAVEDIR, PREFS_FILE_NAME);
|
|
|
|
offset = LoadBufferFromSMB (filepath, silent);
|
|
|
|
if (offset > 0)
|
|
{
|
|
decodePrefsData ();
|
|
if ( !silent )
|
|
{
|
|
sprintf (filepath, "Loaded %d bytes", offset);
|
|
WaitPrompt(filepath);
|
|
}
|
|
}
|
|
}
|