generalized the loading-from-archive code to work with any archive format and to load any kind of file from archives (although nothing but the roms may work yet and i will have to fiddle with things as requested). I probably broke the sdl build; just stub the two new FCEUD_ functions in the most brainless way possible and it should work.
This commit is contained in:
parent
5c22d93e11
commit
bc54e2abba
10
src/driver.h
10
src/driver.h
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "types.h"
|
||||
#include "git.h"
|
||||
#include "file.h"
|
||||
|
||||
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode);
|
||||
inline FILE *FCEUD_UTF8fopen(const std::string &n, const char *mode) { return FCEUD_UTF8fopen(n.c_str(),mode); }
|
||||
|
@ -93,8 +94,8 @@ void FCEUI_GetRenderPlanes(bool& sprites, bool& bg);
|
|||
FCEUGI *FCEUI_LoadGame(const char *name, int OverwriteVidMode);
|
||||
|
||||
//same as FCEUI_LoadGame, except that it can load from a tempfile.
|
||||
//name is the actual path to open; logicalname is what the emulator should think it is
|
||||
FCEUGI *FCEUI_LoadGameVirtual(const char *name, const char *logicalname, int OverwriteVidMode);
|
||||
//name is the logical path to open; archiveFilename is the archive which contains name
|
||||
FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode);
|
||||
|
||||
//general purpose emulator initialization. returns true if successful
|
||||
bool FCEUI_Initialize();
|
||||
|
@ -318,6 +319,11 @@ enum EFCEUI
|
|||
//checks whether an EFCEUI is valid right now
|
||||
bool FCEU_IsValidUI(EFCEUI ui);
|
||||
|
||||
//if you want to autopilot this, pass in an innerfilename to try and automatically load
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename);
|
||||
|
||||
//scans a file to see if it is an archive you can handle
|
||||
ArchiveScanRecord FCEUD_ScanArchive(std::string fname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
//if you want to autopilot this, pass in an innerfilename to try and automatically load
|
||||
void do7zip(HWND hParent, std::string fname, std::string* innerFilename=0);
|
Binary file not shown.
|
@ -8,11 +8,14 @@
|
|||
#include <OleAuto.h>
|
||||
|
||||
#include "7zip/IArchive.h"
|
||||
#include "file.h"
|
||||
#include "utils/memorystream.h"
|
||||
#include "utils/guid.h"
|
||||
|
||||
#include "driver.h"
|
||||
#include "main.h"
|
||||
|
||||
DEFINE_GUID(CLSID_CFormat7z,0x23170F69,0x40C1,0x278A,0x10,0x00,0x00,0x01,0x10,0x07,0x00,0x00);
|
||||
DEFINE_GUID(CLSID_CFormat_07,0x23170F69,0x40C1,0x278A,0x10,0x00,0x00,0x01,0x10,0x07,0x00,0x00);
|
||||
|
||||
class OutStream : public IArchiveExtractCallback
|
||||
{
|
||||
|
@ -269,7 +272,7 @@ class LibRef
|
|||
public:
|
||||
HMODULE hmod;
|
||||
LibRef(const char* fname) {
|
||||
hmod = LoadLibrary("7zxa.dll");
|
||||
hmod = LoadLibrary(fname);
|
||||
}
|
||||
~LibRef() {
|
||||
if(hmod)
|
||||
|
@ -327,24 +330,135 @@ static BOOL CALLBACK ArchiveFileSelectorCallback(HWND hwndDlg, UINT uMsg, WPARAM
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void do7zip(HWND hParent, std::string fname, std::string* innerFilename)
|
||||
typedef UINT32 (WINAPI *CreateObjectFunc)(const GUID*,const GUID*,void**);
|
||||
|
||||
struct FormatRecord
|
||||
{
|
||||
LibRef libref("7zxa.dll");
|
||||
std::vector<char> signature;
|
||||
GUID guid;
|
||||
};
|
||||
|
||||
typedef std::vector<FormatRecord> TFormatRecords;
|
||||
TFormatRecords formatRecords;
|
||||
|
||||
void initArchiveSystem()
|
||||
{
|
||||
LibRef libref("7z.dll");
|
||||
if(!libref.hmod)
|
||||
{
|
||||
//couldnt initialize archive system
|
||||
}
|
||||
|
||||
typedef HRESULT (WINAPI *GetNumberOfFormatsFunc)(UINT32 *numFormats);
|
||||
typedef HRESULT (WINAPI *GetHandlerProperty2Func)(UInt32 formatIndex, PROPID propID, PROPVARIANT *value);
|
||||
|
||||
GetNumberOfFormatsFunc GetNumberOfFormats = (GetNumberOfFormatsFunc)GetProcAddress(libref.hmod,"GetNumberOfFormats");
|
||||
GetHandlerProperty2Func GetHandlerProperty2 = (GetHandlerProperty2Func)GetProcAddress(libref.hmod,"GetHandlerProperty2");
|
||||
|
||||
|
||||
UINT32 numFormats;
|
||||
GetNumberOfFormats(&numFormats);
|
||||
|
||||
for(uint32 i=0;i<numFormats;i++)
|
||||
{
|
||||
PROPVARIANT prop;
|
||||
prop.vt = VT_EMPTY;
|
||||
|
||||
GetHandlerProperty2(i,NArchive::kStartSignature,&prop);
|
||||
|
||||
FormatRecord fr;
|
||||
int len = SysStringLen(prop.bstrVal);
|
||||
fr.signature.reserve(len);
|
||||
for(int j=0;j<len;j++)
|
||||
fr.signature.push_back(((char*)prop.bstrVal)[j]);
|
||||
|
||||
GetHandlerProperty2(i,NArchive::kClassID,&prop);
|
||||
memcpy((char*)&fr.guid,(char*)prop.bstrVal,16);
|
||||
|
||||
formatRecords.push_back(fr);
|
||||
|
||||
::VariantClear( reinterpret_cast<VARIANTARG*>(&prop) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ArchiveScanRecord FCEUD_ScanArchive(std::string fname)
|
||||
{
|
||||
LibRef libref("7z.dll");
|
||||
if(!libref.hmod)
|
||||
return ArchiveScanRecord();
|
||||
|
||||
//check the file against the signatures
|
||||
std::fstream* inf = FCEUD_UTF8_fstream(fname,"rb");
|
||||
int matchingFormat = -1;
|
||||
for(uint32 i=0;i<(int)formatRecords.size();i++)
|
||||
{
|
||||
inf->seekg(0);
|
||||
int size = formatRecords[i].signature.size();
|
||||
if(size==0)
|
||||
continue; //WHY??
|
||||
char* temp = new char[size];
|
||||
inf->read((char*)temp,size);
|
||||
if(!memcmp(&formatRecords[i].signature[0],temp,size))
|
||||
{
|
||||
delete[] temp;
|
||||
matchingFormat = i;
|
||||
break;
|
||||
}
|
||||
delete[] temp;
|
||||
}
|
||||
delete inf;
|
||||
|
||||
if(matchingFormat == -1)
|
||||
return ArchiveScanRecord();
|
||||
|
||||
CreateObjectFunc CreateObject = (CreateObjectFunc)GetProcAddress(libref.hmod,"CreateObject");
|
||||
if(!CreateObject)
|
||||
return ArchiveScanRecord();
|
||||
IInArchive* object;
|
||||
if (!FAILED(CreateObject( &formatRecords[matchingFormat].guid, &IID_IInArchive, (void**)&object )))
|
||||
{
|
||||
//fetch the start signature
|
||||
InFileStream ifs(fname);
|
||||
if (SUCCEEDED(object->Open(&ifs,0,0)))
|
||||
{
|
||||
uint32 numFiles;
|
||||
if (SUCCEEDED(object->GetNumberOfItems(&numFiles)))
|
||||
{
|
||||
object->Release();
|
||||
return ArchiveScanRecord(matchingFormat,(int)numFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object->Release();
|
||||
|
||||
return ArchiveScanRecord();
|
||||
}
|
||||
|
||||
extern HWND hAppWnd;
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename)
|
||||
{
|
||||
FCEUFILE* fp = 0;
|
||||
|
||||
LibRef libref("7z.dll");
|
||||
if(!libref.hmod) {
|
||||
MessageBox(hParent,"Could not locate 7zxa.dll","Failure launching 7z archive browser",0);
|
||||
return;
|
||||
MessageBox(hAppWnd,"Could not locate 7z.dll","Failure launching archive browser",0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef UINT32 (WINAPI *CreateObjectFunc)(const GUID*,const GUID*,void**);
|
||||
CreateObjectFunc CreateObject = (CreateObjectFunc)GetProcAddress(libref.hmod,"CreateObject");
|
||||
if(!CreateObject)
|
||||
{
|
||||
MessageBox(hParent,"7zxa.dll was invalid","Failure launching 7z archive browser",0);
|
||||
return;
|
||||
MessageBox(hAppWnd,"7z.dll was invalid","Failure launching archive browser",0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
IInArchive* object;
|
||||
if (!FAILED(CreateObject( &CLSID_CFormat7z, &IID_IInArchive, (void**)&object )))
|
||||
if (!FAILED(CreateObject( &formatRecords[asr.type].guid, &IID_IInArchive, (void**)&object )))
|
||||
{
|
||||
InFileStream ifs(fname);
|
||||
if (SUCCEEDED(object->Open(&ifs,0,0)))
|
||||
|
@ -402,24 +516,29 @@ void do7zip(HWND hParent, std::string fname, std::string* innerFilename)
|
|||
}
|
||||
else
|
||||
//or use the UI if we're not
|
||||
ret = DialogBoxParam(fceu_hInstance, "7ZIPARCHIVEDIALOG", hParent, ArchiveFileSelectorCallback, (LPARAM)0);
|
||||
ret = DialogBoxParam(fceu_hInstance, "ARCHIVECHOOSERDIALOG", hAppWnd, ArchiveFileSelectorCallback, (LPARAM)0);
|
||||
|
||||
if(ret != LB_ERR)
|
||||
{
|
||||
FileSelectorContext::Item& item = fileSelectorContext.items[ret];
|
||||
std::vector<char> data(item.size);
|
||||
OutStream outStream( item.index, &data[0], item.size);
|
||||
memorystream* ms = new memorystream(item.size);
|
||||
OutStream outStream( item.index, ms->buf(), item.size);
|
||||
const uint32 indices[1] = {item.index};
|
||||
if (SUCCEEDED(object->Extract(indices,1,0,&outStream)))
|
||||
{
|
||||
char* tempname = tmpnam(0);
|
||||
FILE* outf = fopen(tempname,"wb");
|
||||
fwrite(&data[0],1,item.size,outf);
|
||||
fclose(outf);
|
||||
void ALoad(char *nameo,char* actualfile,char* archiveFile);
|
||||
ALoad((char*)item.name.c_str(),tempname,(char*)fname.c_str());
|
||||
|
||||
} //if we extracted the file correctly
|
||||
//if we extracted the file correctly
|
||||
fp = new FCEUFILE();
|
||||
fp->archiveFilename = fname;
|
||||
fp->filename = fileSelectorContext.items[ret].name;
|
||||
fp->archiveIndex = ret;
|
||||
fp->mode = FCEUFILE::READ;
|
||||
fp->size = fileSelectorContext.items[ret].size;
|
||||
fp->stream = ms;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete ms;
|
||||
}
|
||||
|
||||
} //if returned a file from the fileselector
|
||||
|
||||
|
@ -427,4 +546,6 @@ void do7zip(HWND hParent, std::string fname, std::string* innerFilename)
|
|||
} //if we opened the 7z correctly
|
||||
object->Release();
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _ARCHIVE_H_
|
||||
#define _ARCHIVE_H_
|
||||
|
||||
void initArchiveSystem();
|
||||
|
||||
#endif
|
|
@ -39,6 +39,7 @@
|
|||
#include "../../state.h"
|
||||
#include "../../debug.h"
|
||||
#include "../../movie.h"
|
||||
#include "archive.h"
|
||||
#include "input.h"
|
||||
#include "netplay.h"
|
||||
#include "memwatch.h"
|
||||
|
@ -555,6 +556,8 @@ int main(int argc,char *argv[])
|
|||
{
|
||||
char *t;
|
||||
|
||||
initArchiveSystem();
|
||||
|
||||
if(timeBeginPeriod(1) != TIMERR_NOERROR)
|
||||
{
|
||||
AddLogText("Error setting timer granularity to 1ms.", DO_ADD_NEWLINE);
|
||||
|
|
|
@ -1392,14 +1392,14 @@ BEGIN
|
|||
EDITTEXT IDC_PPUVIEW_SCANLINE,72,176,27,12
|
||||
END
|
||||
|
||||
7ZIPARCHIVEDIALOG DIALOGEX 0, 0, 265, 159
|
||||
ARCHIVECHOOSERDIALOG DIALOGEX 0, 0, 265, 159
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Choose File From Archive"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,146,138,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,208,138,50,14
|
||||
LISTBOX IDC_LIST1,7,7,251,120,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
|
||||
LISTBOX IDC_LIST1,7,7,251,120,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
TEXTHOOKER DIALOGEX 0, 0, 456, 327
|
||||
|
@ -1596,7 +1596,7 @@ BEGIN
|
|||
BOTTOMMARGIN, 66
|
||||
END
|
||||
|
||||
"7ZIPARCHIVEDIALOG", DIALOG
|
||||
"ARCHIVECHOOSERDIALOG", DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 258
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "joystick.h"
|
||||
#include "oldmovie.h"
|
||||
#include "movie.h"
|
||||
#include "7zip.h"
|
||||
#include "texthook.h"
|
||||
#include "guiconfig.h"
|
||||
#include "timing.h"
|
||||
|
@ -149,13 +148,7 @@ int GetCheckedAutoFireOffset()
|
|||
|
||||
// Internal functions
|
||||
|
||||
void SplitRecentArchiveFilename(std::string src, std::string& archive, std::string& file)
|
||||
{
|
||||
src = src.substr(1);
|
||||
size_t pipe = src.find_first_of('|');
|
||||
archive = src.substr(0,pipe);
|
||||
file = src.substr(pipe+1);
|
||||
}
|
||||
|
||||
|
||||
static void ConvertFCM(HWND hwndOwner)
|
||||
{
|
||||
|
@ -401,12 +394,10 @@ void UpdateRMenu(HMENU menu, char **strs, unsigned int mitem, unsigned int basei
|
|||
continue;
|
||||
|
||||
std::string tmp = strs[x];
|
||||
if(tmp[0] == '|')
|
||||
{
|
||||
std::string archiveName, fileName;
|
||||
SplitRecentArchiveFilename(tmp,archiveName,fileName);
|
||||
std::string archiveName, fileName, fileToOpen;
|
||||
FCEU_SplitArchiveFilename(tmp,archiveName,fileName,fileToOpen);
|
||||
if(archiveName != "")
|
||||
tmp = archiveName + " <" + fileName + ">";
|
||||
}
|
||||
|
||||
//clamp this string to 128 chars
|
||||
if(tmp.size()>128)
|
||||
|
@ -567,11 +558,9 @@ void FCEUD_HideMenuToggle(void)
|
|||
ToggleHideMenu();
|
||||
}
|
||||
|
||||
void ALoad(char *nameo,char* actualfile,char* archiveFile)
|
||||
void ALoad(char *nameo, char* innerFilename)
|
||||
{
|
||||
bool isvirtual = (actualfile!=0);
|
||||
if(!isvirtual) actualfile = nameo;
|
||||
if(FCEUI_LoadGameVirtual(actualfile, nameo, 1))
|
||||
if(FCEUI_LoadGameVirtual(nameo, 1))
|
||||
{
|
||||
pal_emulation = FCEUI_GetCurrentVidSystem(0, 0);
|
||||
|
||||
|
@ -579,10 +568,9 @@ void ALoad(char *nameo,char* actualfile,char* archiveFile)
|
|||
|
||||
SetMainWindowStuff();
|
||||
|
||||
//todo-add recent files from archives somehow
|
||||
std::string recentFileName = nameo;
|
||||
if(archiveFile)
|
||||
recentFileName = (std::string)"|" + archiveFile + "|" + nameo;
|
||||
if(GameInfo->archiveFilename)
|
||||
recentFileName = (std::string)GameInfo->archiveFilename + "|" + GameInfo->filename;
|
||||
else
|
||||
recentFileName = nameo;
|
||||
|
||||
|
@ -633,17 +621,7 @@ void LoadNewGamey(HWND hParent, const char *initialdir)
|
|||
// Show the Open File dialog
|
||||
if(GetOpenFileName(&ofn))
|
||||
{
|
||||
//if the user selected a 7zip file, then we have some work to do..
|
||||
//todo - scan file instead of checking extension
|
||||
std::string fname = nameo;
|
||||
if(fname.substr(fname.size()-3,3) == ".7z")
|
||||
{
|
||||
do7zip(hParent, fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
ALoad(nameo,0);
|
||||
}
|
||||
ALoad(nameo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,7 +753,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|||
if((ftmp=(char*)malloc(len))) //mbg merge 7/17/06 added cast
|
||||
{
|
||||
DragQueryFile((HDROP)wParam,0,ftmp,len); //mbg merge 7/17/06 changed (HANDLE) to (HDROP)
|
||||
ALoad(ftmp,0);
|
||||
ALoad(ftmp);
|
||||
free(ftmp);
|
||||
}
|
||||
}
|
||||
|
@ -793,14 +771,7 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|||
char*& fname = recent_files[wParam - MENU_FIRST_RECENT_FILE];
|
||||
if(fname)
|
||||
{
|
||||
if(fname[0] == '|')
|
||||
{
|
||||
std::string fnamestr = fname, archiveName, fileName;
|
||||
SplitRecentArchiveFilename(fnamestr,archiveName,fileName);
|
||||
do7zip(hWnd,archiveName,&fileName);
|
||||
}
|
||||
else
|
||||
ALoad(fname,0);
|
||||
ALoad(fname);
|
||||
}
|
||||
}
|
||||
switch(LOWORD(wParam))
|
||||
|
|
|
@ -23,7 +23,7 @@ void ByebyeWindow();
|
|||
void DoTimingConfigFix();
|
||||
int CreateMainWindow();
|
||||
void UpdateCheckedMenuItems();
|
||||
void ALoad(char *nameo,char* actualfile=0, char* archiveFile=0);
|
||||
void ALoad(char* nameo, char* innerFilename=0);
|
||||
void LoadNewGamey(HWND hParent, const char *initialdir);
|
||||
int BrowseForFolder(HWND hParent, const char *htext, char *buf);
|
||||
void UpdateCheckedMenuItems();
|
||||
|
|
28
src/fceu.cpp
28
src/fceu.cpp
|
@ -59,9 +59,16 @@
|
|||
|
||||
int AFon, AFoff, AutoFireOffset = 0; //For keeping track of autofire settings
|
||||
|
||||
unsigned int LagCounter = 0; //This will increment everytime input is not polled by the game
|
||||
bool lagCounterDisplay = false;
|
||||
bool lagFlag = true;
|
||||
FCEUGI::FCEUGI()
|
||||
: filename(0)
|
||||
, archiveFilename(0)
|
||||
{}
|
||||
|
||||
FCEUGI::~FCEUGI()
|
||||
{
|
||||
if(filename) delete filename;
|
||||
if(archiveFilename) delete archiveFilename;
|
||||
}
|
||||
|
||||
static void CloseGame(void)
|
||||
{
|
||||
|
@ -312,7 +319,7 @@ int NSFLoad(FCEUFILE *fp);
|
|||
//char lastLoadedGameName [2048] = {0,}; // hack for movie WRAM clearing on record from poweron
|
||||
|
||||
|
||||
FCEUGI *FCEUI_LoadGameVirtual(const char *name, const char *logicalname, int OverwriteVidMode)
|
||||
FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode)
|
||||
{
|
||||
//mbg merge 7/17/07 - why is this here
|
||||
//#ifdef WIN32
|
||||
|
@ -325,10 +332,11 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, const char *logicalname, int Ove
|
|||
char *ipsfn;
|
||||
|
||||
FCEU_printf("Loading %s...\n\n",name);
|
||||
GetFileBase(logicalname);
|
||||
|
||||
ipsfn=strdup(FCEU_MakeFName(FCEUMKF_IPS,0,0).c_str());
|
||||
fp=FCEU_fopen(name,ipsfn,"rb",0);
|
||||
GetFileBase(fp->filename.c_str());
|
||||
|
||||
free(ipsfn);
|
||||
|
||||
if(!fp) {
|
||||
|
@ -345,9 +353,12 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, const char *logicalname, int Ove
|
|||
AutosaveStatus[2] = AutosaveStatus[3] = 0;
|
||||
|
||||
CloseGame();
|
||||
GameInfo = new FCEUGI;
|
||||
GameInfo = new FCEUGI();
|
||||
memset(GameInfo, 0, sizeof(FCEUGI));
|
||||
|
||||
GameInfo->filename = strdup(fp->filename.c_str());
|
||||
if(fp->archiveFilename != "") GameInfo->archiveFilename = strdup(fp->archiveFilename.c_str());
|
||||
|
||||
GameInfo->soundchan = 0;
|
||||
GameInfo->soundrate = 0;
|
||||
GameInfo->name=0;
|
||||
|
@ -401,7 +412,7 @@ endlseq:
|
|||
|
||||
FCEUGI *FCEUI_LoadGame(const char *name, int OverwriteVidMode)
|
||||
{
|
||||
return FCEUI_LoadGameVirtual(name,name,OverwriteVidMode);
|
||||
return FCEUI_LoadGameVirtual(name,OverwriteVidMode);
|
||||
}
|
||||
|
||||
|
||||
|
@ -502,6 +513,9 @@ void UpdateAutosave(void);
|
|||
///Skip may be passed in, if FRAMESKIP is #defined, to cause this to emulate more than one frame
|
||||
void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int skip)
|
||||
{
|
||||
extern unsigned int LagCounter;
|
||||
extern bool lagCounterDisplay;
|
||||
extern bool lagFlag;
|
||||
lagFlag = true;
|
||||
int r,ssize;
|
||||
|
||||
|
|
409
src/file.cpp
409
src/file.cpp
|
@ -26,7 +26,9 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "file.h"
|
||||
|
@ -211,377 +213,162 @@ doret:
|
|||
#define strcasecmp strcmp
|
||||
#endif
|
||||
|
||||
void FCEU_SplitArchiveFilename(std::string src, std::string& archive, std::string& file, std::string& fileToOpen)
|
||||
{
|
||||
size_t pipe = src.find_first_of('|');
|
||||
if(pipe == std::string::npos)
|
||||
{
|
||||
archive = "";
|
||||
file = src;
|
||||
fileToOpen = src;
|
||||
}
|
||||
else
|
||||
{
|
||||
archive = src.substr(0,pipe);
|
||||
file = src.substr(pipe+1);
|
||||
fileToOpen = archive;
|
||||
}
|
||||
}
|
||||
|
||||
FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext)
|
||||
{
|
||||
FILE *ipsfile=0;
|
||||
FCEUFILE *fceufp;
|
||||
void *t;
|
||||
FCEUFILE *fceufp=0;
|
||||
|
||||
if(ipsfn && strchr(mode,'r'))
|
||||
bool read = (std::string)mode == "rb";
|
||||
bool write = (std::string)mode == "wb";
|
||||
if(read&&write || (!read&&!write))
|
||||
{
|
||||
FCEU_PrintError("invalid file open mode specified (only wb and rb are supported)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string archive,fname,fileToOpen;
|
||||
FCEU_SplitArchiveFilename(path,archive,fname,fileToOpen);
|
||||
|
||||
|
||||
//try to setup the ips file
|
||||
if(ipsfn && read)
|
||||
ipsfile=FCEUD_UTF8fopen(ipsfn,"rb");
|
||||
|
||||
fceufp=(FCEUFILE *)malloc(sizeof(FCEUFILE));
|
||||
|
||||
if(read)
|
||||
{
|
||||
unzFile tz;
|
||||
if((tz=unzOpen(path))) // If it's not a zip file, use regular file handlers.
|
||||
// Assuming file type by extension usually works,
|
||||
// but I don't like it. :)
|
||||
ArchiveScanRecord asr = FCEUD_ScanArchive(fileToOpen);
|
||||
if(asr.numFiles == 0)
|
||||
{
|
||||
if(unzGoToFirstFile(tz)==UNZ_OK)
|
||||
//if the archive contained no files, try to open it the old fashioned way
|
||||
std::fstream* fp = FCEUD_UTF8_fstream(fileToOpen,mode);
|
||||
if(!fp)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
char tempu[512]; // Longer filenames might be possible, but I don't
|
||||
// think people would name files that long in zip files...
|
||||
unzGetCurrentFileInfo(tz,0,tempu,512,0,0,0,0);
|
||||
tempu[511]=0;
|
||||
if(strlen(tempu)>=4)
|
||||
{
|
||||
char *za=tempu+strlen(tempu)-4;
|
||||
|
||||
if(!ext)
|
||||
{
|
||||
if(!strcasecmp(za,".nes") || !strcasecmp(za,".fds") ||
|
||||
!strcasecmp(za,".nsf") || !strcasecmp(za,".unf") ||
|
||||
!strcasecmp(za,".nez"))
|
||||
break;
|
||||
}
|
||||
else if(!strcasecmp(za,ext))
|
||||
break;
|
||||
}
|
||||
if(strlen(tempu)>=5)
|
||||
{
|
||||
if(!strcasecmp(tempu+strlen(tempu)-5,".unif"))
|
||||
break;
|
||||
}
|
||||
if(unzGoToNextFile(tz)!=UNZ_OK)
|
||||
{
|
||||
if(unzGoToFirstFile(tz)!=UNZ_OK) goto zpfail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(unzOpenCurrentFile(tz)!=UNZ_OK)
|
||||
goto zpfail;
|
||||
}
|
||||
else
|
||||
{
|
||||
zpfail:
|
||||
free(fceufp);
|
||||
unzClose(tz);
|
||||
return 0;
|
||||
}
|
||||
if(!(fceufp->fp=MakeMemWrap(tz,2)))
|
||||
{
|
||||
free(fceufp);
|
||||
return(0);
|
||||
}
|
||||
fceufp->type=2;
|
||||
if(ipsfile)
|
||||
ApplyIPS(ipsfile,(MEMWRAP *)fceufp->fp);
|
||||
return(fceufp);
|
||||
fceufp = new FCEUFILE();
|
||||
fceufp->filename = fileToOpen;
|
||||
fceufp->archiveIndex = -1;
|
||||
fceufp->stream = (std::iostream*)fp;
|
||||
FCEU_fseek(fceufp,0,SEEK_END);
|
||||
fceufp->size = FCEU_ftell(fceufp);
|
||||
FCEU_fseek(fceufp,0,SEEK_SET);
|
||||
return fceufp;
|
||||
}
|
||||
}
|
||||
|
||||
if((t=FCEUD_UTF8fopen(path,"rb")))
|
||||
{
|
||||
uint32 magic;
|
||||
|
||||
magic=fgetc((FILE *)t);
|
||||
magic|=fgetc((FILE *)t)<<8;
|
||||
magic|=fgetc((FILE *)t)<<16;
|
||||
|
||||
if(magic!=0x088b1f) /* Not gzip... */
|
||||
fclose((FILE *)t);
|
||||
else /* Probably gzip */
|
||||
else
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = dup(fileno( (FILE *)t));
|
||||
|
||||
fclose((FILE*)t); //mbg merge 7/17/06 - cast to FILE*
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
if((t=gzdopen(fd,mode)))
|
||||
{
|
||||
fceufp->type=1;
|
||||
fceufp->fp=t;
|
||||
if(ipsfile)
|
||||
{
|
||||
fceufp->fp=MakeMemWrap(t,1);
|
||||
gzclose(t);
|
||||
|
||||
if(fceufp->fp)
|
||||
{
|
||||
free(fceufp);
|
||||
return(0);
|
||||
}
|
||||
|
||||
fceufp->type=3;
|
||||
ApplyIPS(ipsfile,(MEMWRAP *)fceufp->fp);
|
||||
}
|
||||
return(fceufp);
|
||||
}
|
||||
close(fd);
|
||||
//open an archive file
|
||||
if(archive == "")
|
||||
fceufp = FCEUD_OpenArchive(asr, fileToOpen, 0);
|
||||
else
|
||||
fceufp = FCEUD_OpenArchive(asr, archive, &fname);
|
||||
return fceufp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if((t=FCEUD_UTF8fopen(path,mode)))
|
||||
{
|
||||
fseek((FILE *)t,0,SEEK_SET);
|
||||
fceufp->type=0;
|
||||
fceufp->fp=t;
|
||||
if(ipsfile)
|
||||
{
|
||||
if(!(fceufp->fp=MakeMemWrap(t,0)))
|
||||
{
|
||||
free(fceufp);
|
||||
return(0);
|
||||
}
|
||||
fceufp->type=3;
|
||||
ApplyIPS(ipsfile,(MEMWRAP *)fceufp->fp);
|
||||
}
|
||||
return(fceufp);
|
||||
}
|
||||
|
||||
free(fceufp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FCEU_fclose(FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==1)
|
||||
{
|
||||
gzclose(fp->fp);
|
||||
}
|
||||
else if(fp->type>=2)
|
||||
{
|
||||
free(((MEMWRAP*)(fp->fp))->data);
|
||||
free(fp->fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose((FILE *)fp->fp);
|
||||
}
|
||||
free(fp);
|
||||
delete fp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==1)
|
||||
{
|
||||
return gzread(fp->fp,ptr,size*nmemb);
|
||||
}
|
||||
else if(fp->type>=2)
|
||||
{
|
||||
MEMWRAP *wz;
|
||||
uint32 total=size*nmemb;
|
||||
|
||||
wz=(MEMWRAP*)fp->fp;
|
||||
if(wz->location>=wz->size) return 0;
|
||||
|
||||
if((wz->location+total)>wz->size)
|
||||
{
|
||||
int ak=wz->size-wz->location;
|
||||
memcpy((uint8*)ptr,wz->data+wz->location,ak);
|
||||
wz->location=wz->size;
|
||||
return(ak/size);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy((uint8*)ptr,wz->data+wz->location,total);
|
||||
wz->location+=total;
|
||||
return nmemb;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return fread(ptr,size,nmemb,(FILE *)fp->fp);
|
||||
}
|
||||
fp->stream->read((char*)ptr,size*nmemb);
|
||||
uint32 read = fp->stream->gcount();
|
||||
return read/size;
|
||||
}
|
||||
|
||||
uint64 FCEU_fwrite(void *ptr, size_t size, size_t nmemb, FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==1)
|
||||
{
|
||||
return gzwrite(fp->fp,ptr,size*nmemb);
|
||||
}
|
||||
else if(fp->type>=2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return fwrite(ptr,size,nmemb,(FILE *)fp->fp);
|
||||
fp->stream->write((char*)ptr,size*nmemb);
|
||||
//todo - how do we tell how many bytes we wrote?
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
int FCEU_fseek(FCEUFILE *fp, long offset, int whence)
|
||||
{
|
||||
if(fp->type==1)
|
||||
{
|
||||
return( (gzseek(fp->fp,offset,whence)>0)?0:-1);
|
||||
}
|
||||
else if(fp->type>=2)
|
||||
{
|
||||
MEMWRAP *wz;
|
||||
wz=(MEMWRAP*)fp->fp;
|
||||
//if(fp->type==1)
|
||||
//{
|
||||
// return( (gzseek(fp->fp,offset,whence)>0)?0:-1);
|
||||
//}
|
||||
//else if(fp->type>=2)
|
||||
//{
|
||||
// MEMWRAP *wz;
|
||||
// wz=(MEMWRAP*)fp->fp;
|
||||
|
||||
switch(whence)
|
||||
{
|
||||
case SEEK_SET:if(offset>=(long)wz->size) //mbg merge 7/17/06 - added cast to long
|
||||
return(-1);
|
||||
wz->location=offset;break;
|
||||
case SEEK_CUR:if(offset+wz->location>wz->size)
|
||||
return (-1);
|
||||
wz->location+=offset;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return fseek((FILE *)fp->fp,offset,whence);
|
||||
// switch(whence)
|
||||
// {
|
||||
// case SEEK_SET:if(offset>=(long)wz->size) //mbg merge 7/17/06 - added cast to long
|
||||
// return(-1);
|
||||
// wz->location=offset;break;
|
||||
// case SEEK_CUR:if(offset+wz->location>wz->size)
|
||||
// return (-1);
|
||||
// wz->location+=offset;
|
||||
// break;
|
||||
// }
|
||||
// return 0;
|
||||
//}
|
||||
//else
|
||||
// return fseek((FILE *)fp->fp,offset,whence);
|
||||
|
||||
fp->stream->seekg(offset,(std::ios_base::seekdir)whence);
|
||||
fp->stream->seekp(offset,(std::ios_base::seekdir)whence);
|
||||
|
||||
return FCEU_ftell(fp);
|
||||
}
|
||||
|
||||
uint64 FCEU_ftell(FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==1)
|
||||
{
|
||||
return gztell(fp->fp);
|
||||
}
|
||||
else if(fp->type>=2)
|
||||
{
|
||||
return (((MEMWRAP *)(fp->fp))->location);
|
||||
}
|
||||
if(fp->mode == FCEUFILE::READ)
|
||||
return fp->stream->tellg();
|
||||
else
|
||||
return ftell((FILE *)fp->fp);
|
||||
}
|
||||
|
||||
void FCEU_autosave(FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==1)
|
||||
{
|
||||
gzrewind(fp->fp);
|
||||
}
|
||||
else if(fp->type>=2)
|
||||
{
|
||||
((MEMWRAP *)(fp->fp))->location=0;
|
||||
}
|
||||
else
|
||||
//Autosave load
|
||||
fseek((FILE*)fp->fp,0,SEEK_SET); //mbg merge 7/17/06 - added cast to FILE*
|
||||
return fp->stream->tellp();
|
||||
}
|
||||
|
||||
int FCEU_read16le(uint16 *val, FCEUFILE *fp)
|
||||
{
|
||||
uint8 t[4]; //mbg merge 7/17/06 - changed size from 2 to 4 to avoid dangerous problem with uint32* poking
|
||||
|
||||
if(fp->type>=1)
|
||||
{
|
||||
if(fp->type>=2)
|
||||
{
|
||||
MEMWRAP *wz;
|
||||
wz=(MEMWRAP *)fp->fp;
|
||||
if(wz->location+2>wz->size)
|
||||
{return 0;}
|
||||
*(uint32 *)t=*(uint32 *)(wz->data+wz->location);
|
||||
wz->location+=2;
|
||||
}
|
||||
else if(fp->type==1)
|
||||
if(gzread(fp->fp,&t,2)!=2) return(0);
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fread(t,1,2,(FILE *)fp->fp)!=2) return(0);
|
||||
}
|
||||
*val=t[0]|(t[1]<<8);
|
||||
return(1);
|
||||
return read16le(val,fp->stream);
|
||||
}
|
||||
|
||||
int FCEU_read32le(uint32 *Bufo, FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type>=1)
|
||||
{
|
||||
uint8 t[4];
|
||||
#ifndef LSB_FIRST
|
||||
uint8 x[4];
|
||||
#endif
|
||||
if(fp->type>=2)
|
||||
{
|
||||
MEMWRAP *wz;
|
||||
wz=(MEMWRAP *)fp->fp;
|
||||
if(wz->location+4>wz->size)
|
||||
{return 0;}
|
||||
*(uint32 *)t=*(uint32 *)(wz->data+wz->location);
|
||||
wz->location+=4;
|
||||
}
|
||||
else if(fp->type==1)
|
||||
gzread(fp->fp,&t,4);
|
||||
#ifndef LSB_FIRST
|
||||
x[0]=t[3];
|
||||
x[1]=t[2];
|
||||
x[2]=t[1];
|
||||
x[3]=t[0];
|
||||
*(uint32*)Bufo=*(uint32*)x;
|
||||
#else
|
||||
*(uint32*)Bufo=*(uint32*)t;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return read32le(Bufo,(FILE *)fp->fp);
|
||||
}
|
||||
return read32le(Bufo, fp->stream);
|
||||
}
|
||||
|
||||
int FCEU_fgetc(FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==1)
|
||||
return gzgetc(fp->fp);
|
||||
else if(fp->type>=2)
|
||||
{
|
||||
MEMWRAP *wz;
|
||||
wz=(MEMWRAP *)fp->fp;
|
||||
if(wz->location<wz->size)
|
||||
return wz->data[wz->location++];
|
||||
return EOF;
|
||||
}
|
||||
else
|
||||
return fgetc((FILE *)fp->fp);
|
||||
return fp->stream->get();
|
||||
}
|
||||
|
||||
uint64 FCEU_fgetsize(FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==1)
|
||||
{
|
||||
int x,t;
|
||||
t=gztell(fp->fp);
|
||||
gzrewind(fp->fp);
|
||||
for(x=0; gzgetc(fp->fp) != EOF; x++);
|
||||
gzseek(fp->fp,t,SEEK_SET);
|
||||
return(x);
|
||||
}
|
||||
else if(fp->type>=2)
|
||||
return ((MEMWRAP*)(fp->fp))->size;
|
||||
else
|
||||
{
|
||||
long t,r;
|
||||
t=ftell((FILE *)fp->fp);
|
||||
fseek((FILE *)fp->fp,0,SEEK_END);
|
||||
r=ftell((FILE *)fp->fp);
|
||||
fseek((FILE *)fp->fp,t,SEEK_SET);
|
||||
return r;
|
||||
}
|
||||
return fp->size;
|
||||
}
|
||||
|
||||
int FCEU_fisarchive(FCEUFILE *fp)
|
||||
{
|
||||
if(fp->type==2)
|
||||
return 1;
|
||||
return 0;
|
||||
if(fp->archiveIndex==0) return 0;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
std::string GetMfn() //Retrieves the movie filename from curMovieFilename (for adding to savestate and auto-save files)
|
||||
|
@ -619,7 +406,7 @@ void FCEUI_SetDirOverride(int which, char *n)
|
|||
odirs[which] = n;
|
||||
}
|
||||
|
||||
if(GameInfo) /* Rebuild cache of present states/movies. */
|
||||
if(GameInfo) //Rebuild cache of present states/movies.
|
||||
{
|
||||
if(which==FCEUIOD_STATES)
|
||||
{
|
||||
|
|
46
src/file.h
46
src/file.h
|
@ -2,11 +2,47 @@
|
|||
#define _FCEU_FILE_H_
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "types.h"
|
||||
|
||||
struct FCEUFILE {
|
||||
//void *fp; // FILE* or ptr to ZIPWRAP
|
||||
//uint32 type; // 0=normal file, 1=gzip, 2=zip
|
||||
std::iostream *stream;
|
||||
std::string filename;
|
||||
std::string archiveFilename;
|
||||
int archiveIndex;
|
||||
int size;
|
||||
|
||||
FCEUFILE()
|
||||
: stream(0)
|
||||
{}
|
||||
|
||||
~FCEUFILE()
|
||||
{
|
||||
if(stream) delete stream;
|
||||
}
|
||||
|
||||
enum {
|
||||
READ, WRITE, READWRITE
|
||||
} mode;
|
||||
};
|
||||
|
||||
struct ArchiveScanRecord
|
||||
{
|
||||
ArchiveScanRecord()
|
||||
: type(-1)
|
||||
, numFiles(0)
|
||||
{}
|
||||
ArchiveScanRecord(int _type, int _numFiles)
|
||||
{
|
||||
type = _type;
|
||||
numFiles = _numFiles;
|
||||
}
|
||||
int type;
|
||||
int numFiles;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *fp; // FILE* or ptr to ZIPWRAP
|
||||
uint32 type; // 0=normal file, 1=gzip, 2=zip
|
||||
} FCEUFILE;
|
||||
|
||||
FCEUFILE *FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext);
|
||||
int FCEU_fclose(FCEUFILE*);
|
||||
|
@ -14,7 +50,6 @@ uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE*);
|
|||
uint64 FCEU_fwrite(void *ptr, size_t size, size_t nmemb, FCEUFILE*);
|
||||
int FCEU_fseek(FCEUFILE*, long offset, int whence);
|
||||
uint64 FCEU_ftell(FCEUFILE*);
|
||||
void FCEU_autosave(FCEUFILE*);
|
||||
int FCEU_read32le(uint32 *Bufo, FCEUFILE*);
|
||||
int FCEU_read16le(uint16 *Bufo, FCEUFILE*);
|
||||
int FCEU_fgetc(FCEUFILE*);
|
||||
|
@ -27,6 +62,7 @@ void GetFileBase(const char *f);
|
|||
std::string FCEU_GetPath(int type);
|
||||
std::string FCEU_MakePath(int type, const char* filebase);
|
||||
std::string FCEU_MakeFName(int type, int id1, char *cd1);
|
||||
void FCEU_SplitArchiveFilename(std::string src, std::string& archive, std::string& file, std::string& fileToOpen);
|
||||
|
||||
#define FCEUMKF_STATE 1
|
||||
#define FCEUMKF_SNAP 2
|
||||
|
|
11
src/git.h
11
src/git.h
|
@ -109,8 +109,11 @@ inline const char* ESIFC_Name(ESIFC esifc)
|
|||
|
||||
#include "utils/md5.h"
|
||||
|
||||
typedef struct
|
||||
struct FCEUGI
|
||||
{
|
||||
FCEUGI();
|
||||
~FCEUGI();
|
||||
|
||||
uint8 *name; //Game name, UTF8 encoding
|
||||
int mappernum;
|
||||
|
||||
|
@ -125,5 +128,9 @@ typedef struct
|
|||
//mbg 6/8/08 - ???
|
||||
int soundrate; //For Ogg Vorbis expansion sound wacky support. 0 for default.
|
||||
int soundchan; //Number of sound channels.
|
||||
} FCEUGI;
|
||||
|
||||
char* filename;
|
||||
char* archiveFilename;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -75,9 +75,9 @@ extern INPUTCFC *FCEU_InitTopRider(void);
|
|||
extern INPUTCFC *FCEU_InitBarcodeWorld(void);
|
||||
//---------------
|
||||
|
||||
extern unsigned int LagCounter;
|
||||
extern bool lagCounterDisplay;
|
||||
extern bool lagFlag;
|
||||
unsigned int LagCounter;
|
||||
bool lagCounterDisplay;
|
||||
bool lagFlag;
|
||||
static uint8 joy_readbit[2];
|
||||
uint8 joy[4]={0,0,0,0}; //HACK - should be static but movie needs it
|
||||
static uint8 LastStrobe;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
//#include <unistd.h> //mbg merge 7/17/06 removed
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "types.h"
|
||||
|
|
|
@ -108,6 +108,19 @@ int read32le(uint32 *Bufo, FILE *fp)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int read16le(uint16 *Bufo, std::istream *is)
|
||||
{
|
||||
uint16 buf;
|
||||
if(is->read((char*)&buf,2).gcount() != 2)
|
||||
return 0;
|
||||
#ifdef LSB_FIRST
|
||||
*Bufo=buf;
|
||||
#else
|
||||
*Bufo = FCEU_de16lsb(&buf)
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
///reads a little endian 64bit value from the specified file
|
||||
int read64le(uint64 *Bufo, std::istream *is)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,8 @@ int write64le(uint64 b, std::ostream* os);
|
|||
int read64le(uint64 *Bufo, std::istream *is);
|
||||
int read32le(uint32 *Bufo, std::istream *is);
|
||||
int read32le(uint32 *Bufo, FILE *fp);
|
||||
int read16le(uint16 *Bufo, std::istream *is);
|
||||
|
||||
void FlipByteOrder(uint8 *src, uint32 count);
|
||||
|
||||
void FCEU_en32lsb(uint8 *, uint32);
|
||||
|
|
|
@ -30,6 +30,17 @@ private:
|
|||
|
||||
public:
|
||||
|
||||
memory_streambuf(int _capacity)
|
||||
: buf(new T[capacity=_capacity])
|
||||
, myBuf(true)
|
||||
, length(_capacity)
|
||||
, ww(0)
|
||||
, usevec(0)
|
||||
{
|
||||
sync();
|
||||
}
|
||||
|
||||
|
||||
memory_streambuf()
|
||||
: buf(new T[capacity = 128])
|
||||
, myBuf(true)
|
||||
|
@ -243,6 +254,11 @@ public:
|
|||
: std::basic_iostream<char, std::char_traits<char> >(&streambuf)
|
||||
{}
|
||||
|
||||
memorystream(int size)
|
||||
: std::basic_iostream<char, std::char_traits<char> >(&streambuf)
|
||||
, streambuf(size)
|
||||
{}
|
||||
|
||||
memorystream(char* usebuf, int buflength)
|
||||
: std::basic_iostream<char, std::char_traits<char> >(&streambuf)
|
||||
, streambuf(usebuf, buflength)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
del /s fceux.zip
|
||||
cd ..\output
|
||||
..\vc8\zip -X -9 -r ..\vc8\fceux.zip fceux.exe fceux.chm 7zxa.dll palettes
|
||||
..\vc8\zip -X -9 -r ..\vc8\fceux.zip fceux.exe fceux.chm 7z.dll palettes
|
||||
cd ..\vc8
|
|
@ -97,7 +97,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="xcopy /y /d $(ProjectDir)\..\src\drivers\win\7zxa.dll $(OutDir)"
|
||||
CommandLine="xcopy /y /d $(ProjectDir)\..\src\drivers\win\7z.dll $(OutDir)"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
|
@ -181,7 +181,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="xcopy /d $(ProjectDir)\..\src\drivers\win\7zxa.dll $(OutDir)
upx ..\output\fceux.exe"
|
||||
CommandLine="xcopy /d $(ProjectDir)\..\src\drivers\win\7z.dll $(OutDir)
upx ..\output\fceux.exe
"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
|
@ -705,11 +705,11 @@
|
|||
Name="win"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\src\drivers\win\7zip.cpp"
|
||||
RelativePath="..\src\drivers\win\archive.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\drivers\win\7zip.h"
|
||||
RelativePath="..\src\drivers\win\archive.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
|
Loading…
Reference in New Issue