/**************************************************************************** * Snes9x 1.50 * * Nintendo Gamecube Port * softdev July 2006 * crunchy2 May 2007 * * smbload.cpp * * Load ROMS from a Network share. ****************************************************************************/ #include #include #include #include #include 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 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.ROMName); 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.ROMName); 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); } } }