Adds IsDrive to FileUtil for win32,

Adds booting from drive to gui. disabled as it is currently too slow unless it is a virtual drive

Changes DriveUtil to start checking at D: as it is unlikely that a, b, or c will be a cd/dvd drive

Addes DriveBlob functions, untested on linux/osx probably needs more work

Removes duplicate message from EXI_DeviceMemoryCard.cpp when creating a brand new memcard



git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2345 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
LPFaint99 2009-02-21 23:44:40 +00:00
parent b4b94fe594
commit 9cfa4e9385
14 changed files with 270 additions and 101 deletions

View File

@ -29,7 +29,7 @@ void GetAllRemovableDrives(std::vector<std::string> *drives) {
HANDLE hDisk; HANDLE hDisk;
DISK_GEOMETRY diskGeometry; DISK_GEOMETRY diskGeometry;
for (int i = 'A'; i < 'Z'; i++) for (int i = 'D'; i < 'Z'; i++)
{ {
char path[MAX_PATH]; char path[MAX_PATH];
sprintf(path, "\\\\.\\%c:", i); sprintf(path, "\\\\.\\%c:", i);
@ -55,4 +55,3 @@ void GetAllRemovableDrives(std::vector<std::string> *drives) {
// stat("/media/cdrom") or whatever etc etc // stat("/media/cdrom") or whatever etc etc
#endif #endif
} }

View File

@ -69,6 +69,18 @@ bool Exists(const char *filename)
return (result == 0); return (result == 0);
} }
bool IsDisk(const char *filename)
{
#ifdef _WIN32
std::string copy = filename;
if (copy.size() < 4 && copy.c_str()[1] == ':')
return true;
#else
// TODO: add linux \ osx
#endif
return false;
}
bool IsDirectory(const char *filename) bool IsDirectory(const char *filename)
{ {
struct stat file_info; struct stat file_info;

View File

@ -40,6 +40,7 @@ bool Exists(const char *filename);
void Launch(const char *filename); void Launch(const char *filename);
void Explore(const char *path); void Explore(const char *path);
bool IsDirectory(const char *filename); bool IsDirectory(const char *filename);
bool IsDisk(const char *filename);
bool CreateDir(const char *filename); bool CreateDir(const char *filename);
bool CreateDirectoryStructure(const std::string& _rFullPath); bool CreateDirectoryStructure(const std::string& _rFullPath);
bool Delete(const char *filename); bool Delete(const char *filename);

View File

@ -162,7 +162,7 @@ std::string* IniFile::GetLine(Section* section, const char* key, std::string* va
std::string lineKey; std::string lineKey;
ParseLine(line, &lineKey, valueOut, commentOut); ParseLine(line, &lineKey, valueOut, commentOut);
if (!stricmp(lineKey.c_str(), key)) if (!strcasecmp(lineKey.c_str(), key))
{ {
return &line; return &line;
} }

View File

@ -58,102 +58,106 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
{ {
std::string Region(EUR_DIR); std::string Region(EUR_DIR);
switch (_BootBios) switch (_BootBios)
{ {
case BOOT_DEFAULT: case BOOT_DEFAULT:
{ {
/* Check if the file exist, we may have gotten it from a --elf command line bool bootDrive = File::IsDisk(m_strFilename.c_str());
that gave an incorrect file name */ // Check if the file exist, we may have gotten it from a --elf command line
if (!File::Exists(m_strFilename.c_str())) // that gave an incorrect file name
{ if (!bootDrive && !File::Exists(m_strFilename.c_str()))
{
PanicAlert("The file you specified (%s) does not exists", m_strFilename.c_str()); PanicAlert("The file you specified (%s) does not exists", m_strFilename.c_str());
return false; return false;
} }
std::string Extension; std::string Extension;
SplitPath(m_strFilename, NULL, NULL, &Extension); SplitPath(m_strFilename, NULL, NULL, &Extension);
if (!strcasecmp(Extension.c_str(), ".gcm") || if (!strcasecmp(Extension.c_str(), ".gcm") ||
!strcasecmp(Extension.c_str(), ".iso") || !strcasecmp(Extension.c_str(), ".iso") ||
!strcasecmp(Extension.c_str(), ".gcz") ) !strcasecmp(Extension.c_str(), ".gcz") ||
{ bootDrive)
m_BootType = BOOT_ISO; {
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(m_strFilename.c_str()); m_BootType = BOOT_ISO;
if (pVolume == NULL) DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(m_strFilename.c_str());
{ if (pVolume == NULL)
PanicAlert("Your GCM/ISO file seems to be invalid, or not a GC/Wii ISO."); {
return false;
} PanicAlert(bootDrive ? "Drive could not be mounted" :
"Your GCM/ISO file seems to be invalid, or not a GC/Wii ISO." );
return false;
}
m_strName = pVolume->GetName(); m_strName = pVolume->GetName();
m_strUniqueID = pVolume->GetUniqueID(); m_strUniqueID = pVolume->GetUniqueID();
// Check if we have a Wii disc // Check if we have a Wii disc
bWii = DiscIO::IsVolumeWiiDisc(pVolume); bWii = DiscIO::IsVolumeWiiDisc(pVolume);
switch (pVolume->GetCountry()) switch (pVolume->GetCountry())
{ {
case DiscIO::IVolume::COUNTRY_USA: case DiscIO::IVolume::COUNTRY_USA:
bNTSC = true; bNTSC = true;
Region = USA_DIR; Region = USA_DIR;
break; break;
case DiscIO::IVolume::COUNTRY_JAP: case DiscIO::IVolume::COUNTRY_JAP:
bNTSC = true; bNTSC = true;
Region = JAP_DIR; Region = JAP_DIR;
break; break;
case DiscIO::IVolume::COUNTRY_EUROPE: case DiscIO::IVolume::COUNTRY_EUROPE:
case DiscIO::IVolume::COUNTRY_FRANCE: case DiscIO::IVolume::COUNTRY_FRANCE:
bNTSC = false; bNTSC = false;
Region = EUR_DIR; Region = EUR_DIR;
break; break;
default: default:
PanicAlert("Your GCM/ISO file seems to be invalid (invalid country)."); PanicAlert("Your GCM/ISO file seems to be invalid (invalid country).");
return false; return false;
} }
delete pVolume; delete pVolume;
} }
else if (!strcasecmp(Extension.c_str(), ".elf")) else if (!strcasecmp(Extension.c_str(), ".elf"))
{ {
bWii = CBoot::IsElfWii(m_strFilename.c_str()); bWii = CBoot::IsElfWii(m_strFilename.c_str());
Region = USA_DIR; Region = USA_DIR;
m_BootType = BOOT_ELF; m_BootType = BOOT_ELF;
bNTSC = true; bNTSC = true;
} }
else if (!strcasecmp(Extension.c_str(), ".dol")) else if (!strcasecmp(Extension.c_str(), ".dol"))
{ {
bWii = CDolLoader::IsDolWii(m_strFilename.c_str()); bWii = CDolLoader::IsDolWii(m_strFilename.c_str());
Region = USA_DIR; Region = USA_DIR;
m_BootType = BOOT_DOL; m_BootType = BOOT_DOL;
bNTSC = true; bNTSC = true;
} }
else else
{ {
PanicAlert("Could not recognize ISO file %s", m_strFilename.c_str()); PanicAlert("Could not recognize ISO file %s", m_strFilename.c_str());
return false; return false;
} }
} }
break; break;
case BOOT_BIOS_USA: case BOOT_BIOS_USA:
Region = USA_DIR; Region = USA_DIR;
m_strFilename.clear();
bNTSC = true;
break;
case BOOT_BIOS_JAP:
Region = JAP_DIR;
m_strFilename.clear(); m_strFilename.clear();
bNTSC = true; bNTSC = true;
break; break;
case BOOT_BIOS_EUR: case BOOT_BIOS_JAP:
Region = EUR_DIR; Region = JAP_DIR;
m_strFilename.clear(); m_strFilename.clear();
bNTSC = false; bNTSC = true;
break; break;
}
case BOOT_BIOS_EUR:
Region = EUR_DIR;
m_strFilename.clear();
bNTSC = false;
break;
}
// Setup paths // Setup paths
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, Region, true); CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, Region, true);

View File

@ -32,7 +32,7 @@ void SetDiscInside(bool _DiscInside);
void SwapDisc(const char * fileName); void SwapDisc(const char * fileName);
// Lid Functions // Lid Functions
void SetLidOpen(bool open); void SetLidOpen(bool open = true);
bool IsLidOpen(); bool IsLidOpen();
// DVD Access Functions // DVD Access Functions

View File

@ -97,7 +97,6 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
LOG(EXPANSIONINTERFACE, "No memory card found. Will create new."); LOG(EXPANSIONINTERFACE, "No memory card found. Will create new.");
Flush(); Flush();
Core::DisplayMessage(StringFromFormat("Wrote memory card %i contents to %s.", card_index + 1, m_strFilename.c_str()), 4000);
} }
} }
@ -132,7 +131,7 @@ void CEXIMemoryCard::Flush(bool exiting)
if (!exiting) if (!exiting)
{ {
Core::DisplayMessage(StringFromFormat("Wrote memory card %i contents to %s.", card_index, m_strFilename.c_str()).c_str(), 4000); Core::DisplayMessage(StringFromFormat("Wrote memory card %c contents to %s", card_index ? 'B' : 'A', m_strFilename.c_str()).c_str(), 4000);
} }
} }
////////////////////////////////////// //////////////////////////////////////

View File

@ -94,8 +94,8 @@ bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr)
IBlobReader* CreateBlobReader(const char* filename) IBlobReader* CreateBlobReader(const char* filename)
{ {
//if (strlen(filename) < 4 && filename[1] == ':') // Drive, for sure. if(File::IsDisk(filename))
// return DriveReader::Create(filename); return DriveReader::Create(filename);
if (!File::Exists(filename)) if (!File::Exists(filename))
return 0; return 0;

View File

@ -16,10 +16,138 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "stdafx.h" #include "stdafx.h"
#include "DriveBlob.h" #include "DriveBlob.h"
namespace DiscIO namespace DiscIO
{ {
DriveReader::DriveReader(const char *drive)
{
#ifdef _WIN32
char path[MAX_PATH];
strncpy(path, drive, 3);
path[2] = 0;
sprintf(path, "\\\\.\\%s", drive);
hDisc = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDisc == INVALID_HANDLE_VALUE)
{
PanicAlert("Load from DVD backup failed");
}
else
{
SetSectorSize(2048);
#ifdef _LOCKDRIVE
// Lock the compact disc in the CD-ROM drive to prevent accidental
// removal while reading from it.
pmrLockCDROM.PreventMediaRemoval = TRUE;
DeviceIoControl (hDisc, IOCTL_CDROM_MEDIA_REMOVAL,
&pmrLockCDROM, sizeof(pmrLockCDROM), NULL,
0, &dwNotUsed, NULL);
#endif
}
#else
file_ = fopen(drive, "rb");
if (!file_)
PanicAlert("Load from DVD backup failed");
else
SetSectorSize(2048);
#endif
} // DriveReader::DriveReader
DriveReader::~DriveReader()
{
#ifdef _WIN32
#ifdef _LOCKDRIVE // Do we want to lock the drive?
// Unlock the disc in the CD-ROM drive.
pmrLockCDROM.PreventMediaRemoval = FALSE;
DeviceIoControl (hDisc, IOCTL_CDROM_MEDIA_REMOVAL,
&pmrLockCDROM, sizeof(pmrLockCDROM), NULL,
0, &dwNotUsed, NULL);
#endif
CloseHandle(hDisc);
#else
fclose(file_);
#endif
} // DriveReader::~DriveReader
DriveReader * DriveReader::Create(const char *drive)
{
return new DriveReader(drive);
}
bool DriveReader::Read(u64 offset, u64 nbytes, u8* out_ptr)
{
u64 startingBlock = offset / m_blocksize;
u64 remain = nbytes;
int positionInBlock = (int)(offset % m_blocksize);
u64 block = startingBlock;
while (remain > 0)
{
const u8* data = GetBlockData(block);
if (!data)
return false;
u32 toCopy = m_blocksize - positionInBlock;
if (toCopy >= remain)
{
// yay, we are done!
memcpy(out_ptr, data + positionInBlock, (size_t)remain);
return true;
}
else
{
memcpy(out_ptr, data + positionInBlock, toCopy);
out_ptr += toCopy;
remain -= toCopy;
positionInBlock = 0;
block++;
}
}
return true;
} // DriveReader::Read
void DriveReader::GetBlock(u64 block_num, u8 *out_ptr)
{
u32 NotUsed;
u8 * lpSector = new u8[m_blocksize];
#ifdef _WIN32
// TODO: Fix for 64bit block_num, SetFilePointer uses LONG
SetFilePointer (hDisc, m_blocksize*block_num, NULL, FILE_BEGIN);
if(!ReadFile(hDisc, lpSector, m_blocksize, (LPDWORD)&NotUsed, NULL))
PanicAlert("DRE");
#else
fseek(file_, m_blocksize*block_num, SEEK_SET);
fread(lpSector, 1, m_blocksize, file_);
#endif
memcpy(out_ptr, lpSector, m_blocksize);
delete lpSector;
}
void DriveReader::SetSectorSize(int blocksize)
{
for (int i = 0; i < CACHE_SIZE; i++)
{
cache[i] = new u8[blocksize];
cache_tags[i] = (u64)(s64) - 1;
}
m_blocksize = blocksize;
}
const u8 *DriveReader::GetBlockData(u64 block_num)
{
if (cache_tags[0] == block_num)
{
return cache[0];
}
else
{
GetBlock(block_num, cache[0]);
cache_tags[0] = block_num;
return cache[0];
}
}
} // namespace } // namespace

View File

@ -22,36 +22,41 @@
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include <winioctl.h>
#endif #endif
namespace DiscIO namespace DiscIO
{ {
#ifdef _WIN32
class DriveReader : public SectorReader class DriveReader : public SectorReader
{ {
HANDLE hDisc;
private: private:
DriveReader(const char *drive) { DriveReader(const char *drive);
/* void DriveReader::SetSectorSize(int blocksize);
char path[MAX_PATH]; enum { CACHE_SIZE = 32 };
strncpy(path, drive, 3); int m_blocksize;
path[2] = 0; u8* cache[CACHE_SIZE];
sprintf(path, "\\\\.\\%s", drive); u64 cache_tags[CACHE_SIZE];
hDisc = CreateFile(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); int cache_age[CACHE_SIZE];
SetSectorSize(2048); void GetBlock(u64 block_num, u8 *out_ptr);
*/ #ifdef _WIN32
} HANDLE hDisc;
PREVENT_MEDIA_REMOVAL pmrLockCDROM;
#else
FILE* file_;
#endif
s64 size;
u64 *block_pointers;
public: public:
static DriveReader *Create(const char *drive) { static DriveReader *Create(const char *drive);
return NULL;// new DriveReader(drive); ~DriveReader();
} u64 GetDataSize() const { return size; }
u64 GetRawSize() const { return size; }
bool Read(u64 offset, u64 nbytes, u8* out_ptr);
const u8 *GetBlockData(u64 block_num);
}; };
#endif

View File

@ -259,6 +259,7 @@ EVT_MENU(IDM_TOGGLE_TOOLBAR, CFrame::OnToggleToolbar)
EVT_MENU(IDM_TOGGLE_STATUSBAR, CFrame::OnToggleStatusbar) EVT_MENU(IDM_TOGGLE_STATUSBAR, CFrame::OnToggleStatusbar)
EVT_MENU_RANGE(IDM_LOADSLOT1, IDM_LOADSLOT10, CFrame::OnLoadState) EVT_MENU_RANGE(IDM_LOADSLOT1, IDM_LOADSLOT10, CFrame::OnLoadState)
EVT_MENU_RANGE(IDM_SAVESLOT1, IDM_SAVESLOT10, CFrame::OnSaveState) EVT_MENU_RANGE(IDM_SAVESLOT1, IDM_SAVESLOT10, CFrame::OnSaveState)
EVT_MENU_RANGE(IDM_DRIVE1, IDM_DRIVE24, CFrame::OnBootDrive)
EVT_SIZE(CFrame::OnResize) EVT_SIZE(CFrame::OnResize)
EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, CFrame::OnGameListCtrl_ItemActivated) EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, CFrame::OnGameListCtrl_ItemActivated)

View File

@ -26,7 +26,7 @@
#include <wx/busyinfo.h> #include <wx/busyinfo.h>
#include <wx/mstream.h> #include <wx/mstream.h>
//////////////////////////////// ////////////////////////////////
#include "DriveUtil.h"
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// A shortcut to access the bitmaps // A shortcut to access the bitmaps
@ -97,6 +97,7 @@ class CFrame : public wxFrame
wxToolBar* TheToolBar; wxToolBar* TheToolBar;
wxToolBarToolBase* m_ToolPlay; wxToolBarToolBase* m_ToolPlay;
std::vector<std::string> drives;
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// Music mod // Music mod
@ -173,6 +174,7 @@ class CFrame : public wxFrame
void OnOpen(wxCommandEvent& event); void DoOpen(bool Boot); // File menu void OnOpen(wxCommandEvent& event); void DoOpen(bool Boot); // File menu
void OnRefresh(wxCommandEvent& event); void OnRefresh(wxCommandEvent& event);
void OnBrowse(wxCommandEvent& event); void OnBrowse(wxCommandEvent& event);
void OnBootDrive(wxCommandEvent& event);
void OnPlay(wxCommandEvent& event); // Emulation void OnPlay(wxCommandEvent& event); // Emulation
void OnChangeDisc(wxCommandEvent& event); void OnChangeDisc(wxCommandEvent& event);

View File

@ -101,6 +101,16 @@ void CFrame::CreateMenu()
m_pMenuItemOpen = fileMenu->Append(wxID_OPEN, _T("&Open...\tCtrl+O")); m_pMenuItemOpen = fileMenu->Append(wxID_OPEN, _T("&Open...\tCtrl+O"));
fileMenu->Append(wxID_REFRESH, _T("&Refresh")); fileMenu->Append(wxID_REFRESH, _T("&Refresh"));
fileMenu->Append(IDM_BROWSE, _T("&Browse for ISOs...")); fileMenu->Append(IDM_BROWSE, _T("&Browse for ISOs..."));
// change to test drive loading, currently very slow on win32, not tested on linux/os x
// works ok on a virtual drive with GC Games, Wii games do not load
#if 0
wxMenu *externalDrive = new wxMenu;
fileMenu->AppendSubMenu(externalDrive, _T("&Load From Drive"));
GetAllRemovableDrives(&drives);
for (int i = 0; i < drives.size() && i < 24; i++) {
externalDrive->Append(IDM_DRIVE1 + i, wxString::Format(_T("%s"), drives.at(i).c_str()));
}
#endif
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
fileMenu->Append(wxID_EXIT, _T("E&xit"), _T("Alt+F4")); fileMenu->Append(wxID_EXIT, _T("E&xit"), _T("Alt+F4"));
@ -452,7 +462,7 @@ void CFrame::DoOpen(bool Boot)
void CFrame::OnChangeDisc(wxCommandEvent& WXUNUSED (event)) void CFrame::OnChangeDisc(wxCommandEvent& WXUNUSED (event))
{ {
DVDInterface::SetLidOpen(true); DVDInterface::SetLidOpen();
DoOpen(false); DoOpen(false);
DVDInterface::SetLidOpen(false); DVDInterface::SetLidOpen(false);
} }
@ -461,6 +471,12 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
{ {
BootGame(); BootGame();
} }
void CFrame::OnBootDrive(wxCommandEvent& event)
{
BootManager::BootCore(drives.at(event.GetId()-IDM_DRIVE1).c_str());
}
//////////////////////////////////////////////////// ////////////////////////////////////////////////////

View File

@ -54,6 +54,8 @@ enum
IDM_PLAY, IDM_PLAY,
IDM_STOP, IDM_STOP,
IDM_BROWSE, IDM_BROWSE,
IDM_DRIVE1,
IDM_DRIVE24 = IDM_DRIVE1 + 23,//248,
IDM_MEMCARD, // Misc menu IDM_MEMCARD, // Misc menu
IDM_CHEATS, IDM_CHEATS,