OK, now all hardware devices are pre-created, so theoretically you can save/load state anytime anywhere, no need to wait for game title to show.

Besides this should boost the performance by a little.

Warning: Remember to set "Framelimit" to: Auto or 60, or else Emu Wiimote will lose sync in a second.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4613 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2009-11-26 09:50:50 +00:00
parent 8405c4049d
commit 7a6241da81
16 changed files with 191 additions and 202 deletions

View File

@ -76,40 +76,71 @@ TDeviceMap g_DeviceMap;
// STATE_TO_SAVE // STATE_TO_SAVE
typedef std::map<u32, std::string> TFileNameMap; typedef std::map<u32, std::string> TFileNameMap;
TFileNameMap g_FileNameMap; TFileNameMap g_FileNameMap;
u32 g_LastDeviceID;
u32 g_LastDeviceID = 0x13370000;
std::string g_DefaultContentFile;
// General IPC functions // General IPC functions
void Init() void Init()
{ {
_dbg_assert_msg_(WII_IPC, g_DeviceMap.empty(), "DeviceMap isnt empty on init"); _dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init");
u32 i = IPC_FIRST_HARDWARE_ID;
// Build hardware devices
g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_oh1_57e_305(i, std::string("/dev/usb/oh1/57e/305")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stm_immediate(i, std::string("/dev/stm/immediate")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stm_eventhook(i, std::string("/dev/stm/eventhook")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_fs(i, std::string("/dev/fs")); i++;
// Warning: "/dev/es" must be created after "/dev/fs", not before
g_DeviceMap[i] = new CWII_IPC_HLE_Device_es(i, std::string("/dev/es")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_di(i, std::string("/dev/di")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_request(i, std::string("/dev/net/kd/request")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_time(i, std::string("/dev/net/kd/time")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_ncd_manage(i, std::string("/dev/net/ncd/manage")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_ip_top(i, std::string("/dev/net/ip/top")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_oh0(i, std::string("/dev/usb/oh0")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++;
//g_DeviceMap[i] = new CWII_IPC_HLE_Device_Error(i, std::string("_Unknown_Device_")); i++;
g_LastDeviceID = IPC_FIRST_FILEIO_ID;
} }
void Reset() void Reset(bool _hard)
{ {
TDeviceMap::const_iterator itr = g_DeviceMap.begin(); TDeviceMap::const_iterator itr = g_DeviceMap.begin();
while (itr != g_DeviceMap.end()) while (itr != g_DeviceMap.end())
{ {
if(itr->second) if (itr->second)
delete itr->second; {
if (_hard||(!itr->second->IsHardware()))
{
// Hardware should not be deleted unless it is a hard reset
delete itr->second;
g_DeviceMap.erase(itr->first);
}
}
else
{
// Erase invalid device
g_DeviceMap.erase(itr->first);
}
++itr; ++itr;
} }
g_DeviceMap.clear();
g_FileNameMap.clear(); g_FileNameMap.clear();
g_LastDeviceID = IPC_FIRST_FILEIO_ID;
} }
void Shutdown() void Shutdown()
{ {
Reset(); Reset(true);
g_LastDeviceID = 0x13370000;
g_DefaultContentFile.clear();
} }
// Set default content file // Set default content file
void SetDefaultContentFile(const std::string& _rFilename) void SetDefaultContentFile(const std::string& _rFilename)
{ {
g_DefaultContentFile = _rFilename; CWII_IPC_HLE_Device_es* pDevice = (CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
if (pDevice)
pDevice->Load(_rFilename);
} }
u32 GetDeviceIDByName(const std::string& _rDeviceName) u32 GetDeviceIDByName(const std::string& _rDeviceName)
@ -119,7 +150,6 @@ u32 GetDeviceIDByName(const std::string& _rDeviceName)
{ {
if (itr->second->GetDeviceName() == _rDeviceName) if (itr->second->GetDeviceName() == _rDeviceName)
return itr->first; return itr->first;
++itr; ++itr;
} }
@ -131,105 +161,31 @@ IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID)
if (g_DeviceMap.find(_ID) != g_DeviceMap.end()) if (g_DeviceMap.find(_ID) != g_DeviceMap.end())
return g_DeviceMap[_ID]; return g_DeviceMap[_ID];
// ID = 0 just means it hasn't been created yet
return NULL; return NULL;
} }
void DeleteDeviceByID(u32 ID) void DeleteDeviceByID(u32 ID)
{ {
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(ID); IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(ID);
if (pDevice != NULL) if (pDevice)
{
delete pDevice; delete pDevice;
g_DeviceMap.erase(ID);
} g_DeviceMap.erase(ID);
g_FileNameMap.erase(ID);
} }
// This is called from COMMAND_OPEN_DEVICE. Here we either create a new device // This is called from COMMAND_OPEN_DEVICE. Here we either create a new file handle
// or open a new file handle. IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName)
IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName)
{ {
// scan device name and create the right one // scan device name and create the right one
IWII_IPC_HLE_Device* pDevice = NULL; IWII_IPC_HLE_Device* pDevice = NULL;
if (_rDeviceName.find("/dev/") != std::string::npos)
{ INFO_LOG(WII_IPC_FILEIO, "IOP: Create FileIO %s", _rDeviceName.c_str());
if (_rDeviceName.c_str() == std::string("/dev/stm/immediate")) pDevice = new CWII_IPC_HLE_Device_FileIO(_DeviceID, _rDeviceName);
{
pDevice = new CWII_IPC_HLE_Device_stm_immediate(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/stm/eventhook"))
{
pDevice = new CWII_IPC_HLE_Device_stm_eventhook(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/di"))
{
pDevice = new CWII_IPC_HLE_Device_di(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/fs"))
{
pDevice = new CWII_IPC_HLE_Device_fs(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/net/kd/request"))
{
pDevice = new CWII_IPC_HLE_Device_net_kd_request(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/net/kd/time"))
{
pDevice = new CWII_IPC_HLE_Device_net_kd_time(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/net/ncd/manage"))
{
pDevice = new CWII_IPC_HLE_Device_net_ncd_manage(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/net/ip/top"))
{
pDevice = new CWII_IPC_HLE_Device_net_ip_top(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.c_str() == std::string("/dev/es"))
{
pDevice = new CWII_IPC_HLE_Device_es(_DeviceID, _rDeviceName, g_DefaultContentFile);
}
else if (_rDeviceName.find("/dev/usb/oh1/57e/305") != std::string::npos)
{
pDevice = new CWII_IPC_HLE_Device_usb_oh1_57e_305(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.find("/dev/usb/oh0") != std::string::npos)
{
pDevice = new CWII_IPC_HLE_Device_usb_oh0(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.find("/dev/usb/kbd") != std::string::npos)
{
pDevice = new CWII_IPC_HLE_Device_usb_kbd(_DeviceID, _rDeviceName);
}
else if (_rDeviceName.find("/dev/sdio/slot0") != std::string::npos)
{
pDevice = new CWII_IPC_HLE_Device_sdio_slot0(_DeviceID, _rDeviceName);
}
else
{
ERROR_LOG(WII_IPC_FILEIO, "Unknown device: %s", _rDeviceName.c_str());
PanicAlert("Unknown device: %s", _rDeviceName.c_str());
pDevice = new CWII_IPC_HLE_Device_Error(u32(-1), _rDeviceName);
}
}
else
{
INFO_LOG(WII_IPC_FILEIO, "IOP: Create Device %s", _rDeviceName.c_str());
pDevice = new CWII_IPC_HLE_Device_FileIO(_DeviceID, _rDeviceName);
}
return pDevice; return pDevice;
} }
// ===================================================
/* This generates an acknowledgment to IPC calls. This function is called from
IPC_CONTROL_REGISTER requests in WII_IPC.cpp. The acknowledgment _Address will
start with 0x033e...., it will be for the _CommandAddress 0x133e...., from
debugging I also noticed that the Ioctl arguments are stored temporarily in
0x933e.... with the same .... as in the _CommandAddress. */
// ----------------
// Let the game read the setting.txt file // Let the game read the setting.txt file
void CopySettingsFile(std::string& DeviceName) void CopySettingsFile(std::string& DeviceName)
{ {
@ -259,18 +215,14 @@ void CopySettingsFile(std::string& DeviceName)
void DoState(PointerWrap &p) void DoState(PointerWrap &p)
{ {
p.Do(g_LastDeviceID); p.Do(g_LastDeviceID);
p.Do(g_DefaultContentFile);
// AyuanX: I think we should seperate hardware from file handle // Currently only USB device needs to be saved
// and create hardware at initilization instead of runtime allocation when first accessed
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(GetDeviceIDByName(std::string("/dev/usb/oh1/57e/305"))); IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(GetDeviceIDByName(std::string("/dev/usb/oh1/57e/305")));
if (pDevice) if (pDevice)
pDevice->DoState(p); pDevice->DoState(p);
else else
PanicAlert("WII_IPC_HLE: Save/Load State failed, Device /dev/usb/oh1/57e/305 doesn't exist!"); PanicAlert("WII_IPC_HLE: Save/Load State failed, Device /dev/usb/oh1/57e/305 doesn't exist!");
// Let's just hope hardware device IDs are constant throughout the game
// If there is any ID overlapping between hardware IDs and file IDs, we are dead
if (p.GetMode() == PointerWrap::MODE_READ) if (p.GetMode() == PointerWrap::MODE_READ)
{ {
// Delete file Handles // Delete file Handles
@ -295,13 +247,19 @@ void DoState(PointerWrap &p)
{ {
p.Do(g_FileNameMap); p.Do(g_FileNameMap);
} }
} }
// ===================================================
/* This generates an acknowledgment to IPC calls. This function is called from
IPC_CONTROL_REGISTER requests in WII_IPC.cpp. The acknowledgment _Address will
start with 0x033e...., it will be for the _CommandAddress 0x133e...., from
debugging I also noticed that the Ioctl arguments are stored temporarily in
0x933e.... with the same .... as in the _CommandAddress. */
// ----------------
void ExecuteCommand(u32 _Address) void ExecuteCommand(u32 _Address)
{ {
bool CmdSuccess = false; bool CmdSuccess = false;
u32 ClosedDeviceID = 0;
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address)); ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
u32 DeviceID = Memory::Read_U32(_Address + 8); u32 DeviceID = Memory::Read_U32(_Address + 8);
@ -323,35 +281,34 @@ void ExecuteCommand(u32 _Address)
u32 Mode = Memory::Read_U32(_Address + 0x10); u32 Mode = Memory::Read_U32(_Address + 0x10);
DeviceID = GetDeviceIDByName(DeviceName); DeviceID = GetDeviceIDByName(DeviceName);
// check if a device with this name has been created already // check if a device with this name has been created already
if (DeviceID == 0) if (DeviceID == 0)
{ {
// create the new device if (DeviceName.find("/dev/") != std::string::npos)
// alternatively we could pre create all devices and put them in a directory tree structure
// then this would just return a pointer to the wanted device.
u32 CurrentDeviceID = g_LastDeviceID;
pDevice = CreateDevice(CurrentDeviceID, DeviceName);
g_DeviceMap[CurrentDeviceID] = pDevice;
g_LastDeviceID++;
CmdSuccess = pDevice->Open(_Address, Mode);
if(pDevice->GetDeviceName().find("/dev/") == std::string::npos)
// || pDevice->GetDeviceName().c_str() == std::string("/dev/fs"))
{ {
g_FileNameMap[CurrentDeviceID] = DeviceName; ERROR_LOG(WII_IPC_FILEIO, "Unknown device: %s", DeviceName.c_str());
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, DeviceID=%08x, Mode=%i, CmdSuccess=%i)", PanicAlert("Unknown device: %s", DeviceName.c_str());
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode, (int)CmdSuccess);
} }
else else
{ {
INFO_LOG(WII_IPC_HLE, "IOP: Open Device (Device=%s, DeviceID=%08x, Mode=%i)", // create new file handle
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode); u32 CurrentDeviceID = g_LastDeviceID;
pDevice = CreateFileIO(CurrentDeviceID, DeviceName);
g_DeviceMap[CurrentDeviceID] = pDevice;
g_FileNameMap[CurrentDeviceID] = DeviceName;
g_LastDeviceID++;
CmdSuccess = pDevice->Open(_Address, Mode);
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode);
} }
} }
else else
{ {
// The device has already been opened and was not closed, reuse the same DeviceID. CmdSuccess = true;
// The device is already created
pDevice = AccessDeviceByID(DeviceID); pDevice = AccessDeviceByID(DeviceID);
// If we return -6 here after a Open > Failed > CREATE_FILE > ReOpen call // If we return -6 here after a Open > Failed > CREATE_FILE > ReOpen call
@ -365,43 +322,39 @@ void ExecuteCommand(u32 _Address)
INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)", INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), DeviceID, Mode); pDevice->GetDeviceName().c_str(), DeviceID, Mode);
if(DeviceName.find("/dev/") == std::string::npos) if(pDevice->IsHardware())
{
// We have already opened this device, return -6
if(pDevice->IsOpened())
Memory::Write_U32(u32(-6), _Address + 4);
else
pDevice->Open(_Address, Mode);
}
else
{ {
u32 newMode = Memory::Read_U32(_Address + 0x10);
// We may not have a file handle at this point, in Mario Kart I got a // We may not have a file handle at this point, in Mario Kart I got a
// Open > Failed > ... other stuff > ReOpen call sequence, in that case // Open > Failed > ... other stuff > ReOpen call sequence, in that case
// we have no file and no file handle, so we call Open again to basically // we have no file and no file handle, so we call Open again to basically
// get a -106 error so that the game call CreateFile and then ReOpen again. // get a -106 error so that the game call CreateFile and then ReOpen again.
if(pDevice->ReturnFileHandle()) if(pDevice->ReturnFileHandle())
Memory::Write_U32(DeviceID, _Address + 4); Memory::Write_U32(DeviceID, _Address + 4);
else else
pDevice->Open(_Address, newMode); pDevice->Open(_Address, Mode);
} }
else
{
// We have already opened this device, return -6
Memory::Write_U32(u32(-6), _Address + 4);
}
CmdSuccess = true;
} }
} }
break; break;
case COMMAND_CLOSE_DEVICE: case COMMAND_CLOSE_DEVICE:
{ {
if (pDevice != NULL) if (pDevice)
{ {
pDevice->Close(_Address); pDevice->Close(_Address);
// Don't delete hardware
// Delete the device when CLOSE is called, this does not effect if (!pDevice->IsHardware())
// GenerateReply() for any other purpose than the logging because DeleteDeviceByID(DeviceID);
// it's a true / false only function
ClosedDeviceID = DeviceID;
CmdSuccess = true; CmdSuccess = true;
} }
} }
break; break;
@ -457,22 +410,8 @@ void ExecuteCommand(u32 _Address)
if (CmdSuccess) if (CmdSuccess)
{ {
// Generate a reply to the IPC command // Generate a reply to the IPC command
WII_IPCInterface::EnqReply(_Address); WII_IPCInterface::EnqReply(_Address);
u32 DeviceID = Memory::Read_U32(_Address + 8);
// DeviceID == 0 means it's used for devices that weren't created yet
if (DeviceID != 0)
{
if (g_DeviceMap.find(DeviceID) == g_DeviceMap.end())
ERROR_LOG(WII_IPC_HLE, "IOP: Reply to unknown device ID (DeviceID=%i)", DeviceID);
if (ClosedDeviceID > 0 && (ClosedDeviceID == DeviceID))
{
DeleteDeviceByID(DeviceID);
g_FileNameMap.erase(DeviceID);
}
}
} }
else else
{ {
@ -532,6 +471,14 @@ void Update()
void UpdateDevices() void UpdateDevices()
{ {
// This is called frequently so better make this route simple
// currently we only have one device: USB that needs update and its ID is fixed to IPC_FIRST_HARDWARE_ID
// So let's skip the query and call it directly, which will speed up a lot
//
IWII_IPC_HLE_Device* pDevice = g_DeviceMap[IPC_FIRST_HARDWARE_ID];
if (pDevice->IsOpened())
pDevice->Update();
/*
// check if a device must be updated // check if a device must be updated
TDeviceMap::const_iterator itr = g_DeviceMap.begin(); TDeviceMap::const_iterator itr = g_DeviceMap.begin();
@ -543,6 +490,7 @@ void UpdateDevices()
} }
++itr; ++itr;
} }
*/
} }

View File

@ -24,6 +24,10 @@ class IWII_IPC_HLE_Device;
namespace WII_IPC_HLE_Interface namespace WII_IPC_HLE_Interface
{ {
#define IPC_FIRST_HARDWARE_ID 0x13370000 // first IPC device ID
#define IPC_FIRST_FILEIO_ID 0x13380000 // first IPC file ID
// Init // Init
void Init(); void Init();
@ -31,17 +35,7 @@ void Init();
void Shutdown(); void Shutdown();
// Reset // Reset
void Reset(); void Reset(bool _hard = false);
void DeleteDeviceByID(u32 ID);
u32 GetDeviceIDByName(const std::string& _rDeviceName);
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
void DeleteDeviceByID(u32 _ID);
IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName);
// Do State // Do State
void DoState(PointerWrap &p); void DoState(PointerWrap &p);
@ -49,8 +43,16 @@ void DoState(PointerWrap &p);
// Set default content file // Set default content file
void SetDefaultContentFile(const std::string& _rFilename); void SetDefaultContentFile(const std::string& _rFilename);
u32 GetDeviceIDByName(const std::string& _rDeviceName);
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
void DeleteDeviceByID(u32 _ID);
void CopySettingsFile(std::string& DeviceName); void CopySettingsFile(std::string& DeviceName);
IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName);
// Update // Update
void Update(); void Update();

View File

@ -28,9 +28,11 @@ class IWII_IPC_HLE_Device
{ {
public: public:
IWII_IPC_HLE_Device(u32 _DeviceID, const std::string& _rName) : IWII_IPC_HLE_Device(u32 _DeviceID, const std::string& _rName, bool _Hardware = true) :
m_Name(_rName), m_Name(_rName),
m_DeviceID(_DeviceID) m_DeviceID(_DeviceID),
m_Hardware(_Hardware),
m_Active(false)
{} {}
virtual ~IWII_IPC_HLE_Device() virtual ~IWII_IPC_HLE_Device()
@ -42,8 +44,8 @@ public:
const std::string& GetDeviceName() const { return m_Name; } const std::string& GetDeviceName() const { return m_Name; }
u32 GetDeviceID() const { return m_DeviceID; } u32 GetDeviceID() const { return m_DeviceID; }
virtual bool Open(u32 _CommandAddress, u32 _Mode) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Open()", m_Name.c_str()); return true; } virtual bool Open(u32 _CommandAddress, u32 _Mode) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Open()", m_Name.c_str()); m_Active = true; return true; }
virtual bool Close(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Close()", m_Name.c_str()); return true; } virtual bool Close(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Close()", m_Name.c_str()); m_Active = false; return true; }
virtual bool Seek(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Seek()", m_Name.c_str()); return true; } virtual bool Seek(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Seek()", m_Name.c_str()); return true; }
virtual bool Read(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Read()", m_Name.c_str()); return true; } virtual bool Read(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Read()", m_Name.c_str()); return true; }
virtual bool Write(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Write()", m_Name.c_str()); return true; } virtual bool Write(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Write()", m_Name.c_str()); return true; }
@ -54,15 +56,16 @@ public:
virtual bool ReturnFileHandle() { return false; } virtual bool ReturnFileHandle() { return false; }
virtual bool IsHardware() { return m_Hardware; }
virtual bool IsOpened() { return m_Active; }
private: protected:
// STATE_TO_SAVE // STATE_TO_SAVE
std::string m_Name; std::string m_Name;
u32 m_DeviceID; u32 m_DeviceID;
bool m_Hardware;
bool m_Active;
protected:
// =================================================== // ===================================================
/* A struct for IOS ioctlv calls */ /* A struct for IOS ioctlv calls */

View File

@ -61,12 +61,14 @@ CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di()
bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode) bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode)
{ {
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
m_Active = true;
return true; return true;
} }
bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress) bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress)
{ {
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true; return true;
} }

View File

@ -35,6 +35,7 @@ public:
{ {
PanicAlert("CWII_IPC_HLE_Device_Error"); PanicAlert("CWII_IPC_HLE_Device_Error");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
}; };

View File

@ -40,8 +40,8 @@ std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
return Filename; return Filename;
} }
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName ) CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
, m_pFileHandle(NULL) , m_pFileHandle(NULL)
, m_FileLength(0) , m_FileLength(0)
{ {
@ -66,7 +66,7 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
// Close always return 0 for success // Close always return 0 for success
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true; return true;
} }
@ -130,6 +130,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
} }
Memory::Write_U32(ReturnValue, _CommandAddress+4); Memory::Write_U32(ReturnValue, _CommandAddress+4);
m_Active = true;
return true; return true;
} }

View File

@ -55,11 +55,21 @@
CWII_IPC_HLE_Device_es::CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName, const std::string& _rDefaultContentFile) CWII_IPC_HLE_Device_es::CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_pContentLoader(NULL) , m_pContentLoader(NULL)
, m_TitleID(-1) , m_TitleID(-1)
, AccessIdentID(0x6000000) , AccessIdentID(0x6000000)
{
}
CWII_IPC_HLE_Device_es::~CWII_IPC_HLE_Device_es()
{
// Leave deletion of the INANDContentLoader objects to CNANDContentManager, don't do it here!
m_NANDContent.clear();
}
void CWII_IPC_HLE_Device_es::Load(const std::string& _rDefaultContentFile)
{ {
m_pContentLoader = &DiscIO::CNANDContentManager::Access().GetNANDLoader(_rDefaultContentFile); m_pContentLoader = &DiscIO::CNANDContentManager::Access().GetNANDLoader(_rDefaultContentFile);
@ -91,19 +101,13 @@ CWII_IPC_HLE_Device_es::CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string&
//FindValidTitleIDs(); //FindValidTitleIDs();
INFO_LOG(WII_IPC_ES, "Set default title to %08x/%08x", (u32)(m_TitleID>>32), (u32)m_TitleID); INFO_LOG(WII_IPC_ES, "Set default title to %08x/%08x", (u32)(m_TitleID>>32), (u32)m_TitleID);
} }
CWII_IPC_HLE_Device_es::~CWII_IPC_HLE_Device_es()
{
// Leave deletion of the INANDContentLoader objects to CNANDContentManager, don't do it here!
m_NANDContent.clear();
}
bool CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode) bool CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode)
{ {
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
@ -111,7 +115,8 @@ bool CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_ES, "ES: Close"); INFO_LOG(WII_IPC_ES, "ES: Close");
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
return true; m_Active = false;
return true;
} }
bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)

View File

@ -26,10 +26,12 @@ class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device
{ {
public: public:
CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName, const std::string& _rDefaultContentFile); CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName);
virtual ~CWII_IPC_HLE_Device_es(); virtual ~CWII_IPC_HLE_Device_es();
void Load(const std::string& _rDefaultContentFile);
virtual bool Open(u32 _CommandAddress, u32 _Mode); virtual bool Open(u32 _CommandAddress, u32 _Mode);
virtual bool Close(u32 _CommandAddress); virtual bool Close(u32 _CommandAddress);

View File

@ -67,6 +67,7 @@ bool CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode)
} }
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
@ -75,6 +76,7 @@ bool CWII_IPC_HLE_Device_fs::Close(u32 _CommandAddress)
// Do we even need to do anything? // Do we even need to do anything?
INFO_LOG(WII_IPC_NET, "/dev/fs: Close"); INFO_LOG(WII_IPC_NET, "/dev/fs: Close");
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true; return true;
} }

View File

@ -75,6 +75,7 @@ bool CWII_IPC_HLE_Device_net_kd_request::Open(u32 _CommandAddress, u32 _Mode)
{ {
INFO_LOG(WII_IPC_NET, "NET_KD_REQ: Open"); INFO_LOG(WII_IPC_NET, "NET_KD_REQ: Open");
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
m_Active = true;
return true; return true;
} }
@ -82,6 +83,7 @@ bool CWII_IPC_HLE_Device_net_kd_request::Close(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_NET, "NET_KD_REQ: Close"); INFO_LOG(WII_IPC_NET, "NET_KD_REQ: Close");
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true; return true;
} }
@ -164,6 +166,7 @@ bool CWII_IPC_HLE_Device_net_ncd_manage::Open(u32 _CommandAddress, u32 _Mode)
{ {
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Open"); INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Open");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
@ -171,6 +174,7 @@ bool CWII_IPC_HLE_Device_net_ncd_manage::Close(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Close"); INFO_LOG(WII_IPC_NET, "NET_NCD_MANAGE: Close");
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true; return true;
} }
@ -213,6 +217,7 @@ bool CWII_IPC_HLE_Device_net_ip_top::Open(u32 _CommandAddress, u32 _Mode)
{ {
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Open"); INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Open");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
@ -220,6 +225,7 @@ bool CWII_IPC_HLE_Device_net_ip_top::Close(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Close"); INFO_LOG(WII_IPC_NET, "NET_IP_TOP: Close");
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true; return true;
} }

View File

@ -61,6 +61,7 @@ bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode)
} }
Memory::Write_U32(GetDeviceID(), _CommandAddress + 0x4); Memory::Write_U32(GetDeviceID(), _CommandAddress + 0x4);
m_Active = true;
return true; return true;
} }
@ -72,6 +73,7 @@ bool CWII_IPC_HLE_Device_sdio_slot0::Close(u32 _CommandAddress)
fclose(m_Card); fclose(m_Card);
Memory::Write_U32(0, _CommandAddress + 0x4); Memory::Write_U32(0, _CommandAddress + 0x4);
m_Active = false;
return true; return true;
} }

View File

@ -56,6 +56,7 @@ public:
{ {
ERROR_LOG(WII_IPC_STM, "STM immediate: Open"); ERROR_LOG(WII_IPC_STM, "STM immediate: Open");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
@ -63,6 +64,7 @@ public:
{ {
ERROR_LOG(WII_IPC_STM, "STM immediate: Close"); ERROR_LOG(WII_IPC_STM, "STM immediate: Close");
Memory::Write_U32(0, _CommandAddress+4); Memory::Write_U32(0, _CommandAddress+4);
m_Active = false;
return true; return true;
} }
@ -145,13 +147,15 @@ public:
virtual bool Open(u32 _CommandAddress, u32 _Mode) virtual bool Open(u32 _CommandAddress, u32 _Mode)
{ {
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
return true; m_Active = true;
return true;
} }
virtual bool Close(u32 _CommandAddress) virtual bool Close(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_STM, "STM eventhook: Close"); INFO_LOG(WII_IPC_STM, "STM eventhook: Close");
Memory::Write_U32(0, _CommandAddress+4); Memory::Write_U32(0, _CommandAddress+4);
m_Active = false;
return true; return true;
} }

View File

@ -43,6 +43,8 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
, m_ACLPool(0) , m_ACLPool(0)
, m_LastCmd(NULL) , m_LastCmd(NULL)
, m_PacketCount(0) , m_PacketCount(0)
, m_FreqDividerSync(0)
, m_FreqDividerMote(0)
{ {
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 0)); m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 0));
// Connect one Wiimote by default // Connect one Wiimote by default
@ -77,6 +79,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
p.Do(m_HCIPool); p.Do(m_HCIPool);
p.Do(m_ACLBuffer); p.Do(m_ACLBuffer);
p.Do(m_ACLPool); p.Do(m_ACLPool);
p.Do(m_FreqDividerSync);
p.Do(m_FreqDividerMote);
} }
// =================================================== // ===================================================
@ -84,6 +88,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode) bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode)
{ {
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
@ -92,6 +97,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode)
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Close(u32 _CommandAddress) bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Close(u32 _CommandAddress)
{ {
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true; return true;
} }
@ -371,6 +377,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeACLPool()
// ---------------- // ----------------
u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
{ {
// Check if HCI Pool is not purged // Check if HCI Pool is not purged
if (m_HCIPool.m_number > 0) if (m_HCIPool.m_number > 0)
{ {
@ -445,13 +452,12 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
// or CPU will disconnect WiiMote automatically // or CPU will disconnect WiiMote automatically
// but don't send too many or it will jam the bus and cost extra CPU time // but don't send too many or it will jam the bus and cost extra CPU time
// //
static u32 FreqDividerSync = 0;
if (m_HCIBuffer.m_address && !WII_IPCInterface::GetAddress() && m_WiiMotes[0].IsConnected()) if (m_HCIBuffer.m_address && !WII_IPCInterface::GetAddress() && m_WiiMotes[0].IsConnected())
{ {
FreqDividerSync++; m_FreqDividerSync++;
if ((m_PacketCount > 0) || (FreqDividerSync > 30)) // Feel free to tweak it if ((m_PacketCount > 0) || (m_FreqDividerSync > 30)) // Feel free to tweak it
{ {
FreqDividerSync = 0; m_FreqDividerSync = 0;
SendEventNumberOfCompletedPackets(m_WiiMotes[0].GetConnectionHandle(), m_PacketCount); SendEventNumberOfCompletedPackets(m_WiiMotes[0].GetConnectionHandle(), m_PacketCount);
m_PacketCount = 0; m_PacketCount = 0;
return true; return true;
@ -464,13 +470,12 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
// Besides, decreasing its reporting frequency also brings us great FPS boost // Besides, decreasing its reporting frequency also brings us great FPS boost
// Now I am making it running at 1/100 frequency of IPC which is already fast enough for human input // Now I am making it running at 1/100 frequency of IPC which is already fast enough for human input
// //
static u32 FreqDividerMote = 0;
if (m_ACLBuffer.m_address && !WII_IPCInterface::GetAddress() && !m_LastCmd && m_WiiMotes[0].IsLinked()) if (m_ACLBuffer.m_address && !WII_IPCInterface::GetAddress() && !m_LastCmd && m_WiiMotes[0].IsLinked())
{ {
FreqDividerMote++; m_FreqDividerMote++;
if(FreqDividerMote > 99) // Feel free to tweak it if(m_FreqDividerMote > 99) // Feel free to tweak it
{ {
FreqDividerMote = 0; m_FreqDividerMote = 0;
CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update(); CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update();
return true; return true;
} }
@ -2132,12 +2137,14 @@ CWII_IPC_HLE_Device_usb_oh0::~CWII_IPC_HLE_Device_usb_oh0()
bool CWII_IPC_HLE_Device_usb_oh0::Open(u32 _CommandAddress, u32 _Mode) bool CWII_IPC_HLE_Device_usb_oh0::Open(u32 _CommandAddress, u32 _Mode)
{ {
Memory::Write_U32(GetDeviceID(), _CommandAddress+4); Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true; return true;
} }
bool CWII_IPC_HLE_Device_usb_oh0::Close(u32 _CommandAddress) bool CWII_IPC_HLE_Device_usb_oh0::Close(u32 _CommandAddress)
{ {
Memory::Write_U32(0, _CommandAddress + 0x4); Memory::Write_U32(0, _CommandAddress + 0x4);
m_Active = false;
return true; return true;
} }

View File

@ -189,6 +189,8 @@ private:
ACLPool m_ACLPool; ACLPool m_ACLPool;
u32 m_LastCmd; u32 m_LastCmd;
int m_PacketCount; int m_PacketCount;
u32 m_FreqDividerSync;
u32 m_FreqDividerMote;
// Events // Events
void AddEventToQueue(const SQueuedEvent& _event); void AddEventToQueue(const SQueuedEvent& _event);

View File

@ -40,7 +40,7 @@ bool CWII_IPC_HLE_Device_usb_kbd::Open(u32 _CommandAddress, u32 _Mode)
m_OldModifiers = 0x00; m_OldModifiers = 0x00;
m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, NULL)); m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, NULL));
m_Active = true;
return true; return true;
} }

View File

@ -237,6 +237,8 @@ void CWII_IPC_HLE_WiiMote::EventDisconnect()
{ {
m_Connected = false; m_Connected = false;
m_Linked = false; m_Linked = false;
// Clear channel flags
EventCommandWriteLinkPolicy();
} }
bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode) bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode)