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
typedef std::map<u32, std::string> TFileNameMap;
TFileNameMap g_FileNameMap;
u32 g_LastDeviceID = 0x13370000;
std::string g_DefaultContentFile;
u32 g_LastDeviceID;
// General IPC functions
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();
while (itr != g_DeviceMap.end())
{
if(itr->second)
delete itr->second;
if (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;
}
g_DeviceMap.clear();
g_FileNameMap.clear();
g_LastDeviceID = IPC_FIRST_FILEIO_ID;
}
void Shutdown()
{
Reset();
g_LastDeviceID = 0x13370000;
g_DefaultContentFile.clear();
Reset(true);
}
// Set default content file
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)
@ -119,7 +150,6 @@ u32 GetDeviceIDByName(const std::string& _rDeviceName)
{
if (itr->second->GetDeviceName() == _rDeviceName)
return itr->first;
++itr;
}
@ -131,105 +161,31 @@ IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID)
if (g_DeviceMap.find(_ID) != g_DeviceMap.end())
return g_DeviceMap[_ID];
// ID = 0 just means it hasn't been created yet
return NULL;
}
void DeleteDeviceByID(u32 ID)
{
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(ID);
if (pDevice != NULL)
{
if (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
// or open a new file handle.
IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName)
// This is called from COMMAND_OPEN_DEVICE. Here we either create a new file handle
IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName)
{
// scan device name and create the right one
IWII_IPC_HLE_Device* pDevice = NULL;
if (_rDeviceName.find("/dev/") != std::string::npos)
{
if (_rDeviceName.c_str() == std::string("/dev/stm/immediate"))
{
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);
}
INFO_LOG(WII_IPC_FILEIO, "IOP: Create FileIO %s", _rDeviceName.c_str());
pDevice = new CWII_IPC_HLE_Device_FileIO(_DeviceID, _rDeviceName);
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
void CopySettingsFile(std::string& DeviceName)
{
@ -259,18 +215,14 @@ void CopySettingsFile(std::string& DeviceName)
void DoState(PointerWrap &p)
{
p.Do(g_LastDeviceID);
p.Do(g_DefaultContentFile);
// AyuanX: I think we should seperate hardware from file handle
// and create hardware at initilization instead of runtime allocation when first accessed
// Currently only USB device needs to be saved
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(GetDeviceIDByName(std::string("/dev/usb/oh1/57e/305")));
if (pDevice)
pDevice->DoState(p);
else
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)
{
// Delete file Handles
@ -295,13 +247,19 @@ void DoState(PointerWrap &p)
{
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)
{
bool CmdSuccess = false;
u32 ClosedDeviceID = 0;
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
u32 DeviceID = Memory::Read_U32(_Address + 8);
@ -323,35 +281,34 @@ void ExecuteCommand(u32 _Address)
u32 Mode = Memory::Read_U32(_Address + 0x10);
DeviceID = GetDeviceIDByName(DeviceName);
// check if a device with this name has been created already
if (DeviceID == 0)
{
// create the new device
// 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"))
if (DeviceName.find("/dev/") != std::string::npos)
{
g_FileNameMap[CurrentDeviceID] = DeviceName;
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, DeviceID=%08x, Mode=%i, CmdSuccess=%i)",
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode, (int)CmdSuccess);
ERROR_LOG(WII_IPC_FILEIO, "Unknown device: %s", DeviceName.c_str());
PanicAlert("Unknown device: %s", DeviceName.c_str());
}
else
{
INFO_LOG(WII_IPC_HLE, "IOP: Open Device (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode);
// create new file handle
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
{
// The device has already been opened and was not closed, reuse the same DeviceID.
CmdSuccess = true;
// The device is already created
pDevice = AccessDeviceByID(DeviceID);
// 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)",
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
// 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
// get a -106 error so that the game call CreateFile and then ReOpen again.
if(pDevice->ReturnFileHandle())
Memory::Write_U32(DeviceID, _Address + 4);
else
pDevice->Open(_Address, newMode);
}
else
{
// We have already opened this device, return -6
Memory::Write_U32(u32(-6), _Address + 4);
}
CmdSuccess = true;
pDevice->Open(_Address, Mode);
}
}
}
break;
case COMMAND_CLOSE_DEVICE:
{
if (pDevice != NULL)
{
{
if (pDevice)
{
pDevice->Close(_Address);
// Delete the device when CLOSE is called, this does not effect
// GenerateReply() for any other purpose than the logging because
// it's a true / false only function
ClosedDeviceID = DeviceID;
// Don't delete hardware
if (!pDevice->IsHardware())
DeleteDeviceByID(DeviceID);
CmdSuccess = true;
}
}
}
break;
@ -457,22 +410,8 @@ void ExecuteCommand(u32 _Address)
if (CmdSuccess)
{
// Generate a reply to the IPC command
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);
}
}
// Generate a reply to the IPC command
WII_IPCInterface::EnqReply(_Address);
}
else
{
@ -532,6 +471,14 @@ void Update()
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
TDeviceMap::const_iterator itr = g_DeviceMap.begin();
@ -543,6 +490,7 @@ void UpdateDevices()
}
++itr;
}
*/
}

View File

@ -24,6 +24,10 @@ class IWII_IPC_HLE_Device;
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
void Init();
@ -31,17 +35,7 @@ void Init();
void Shutdown();
// Reset
void Reset();
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);
void Reset(bool _hard = false);
// Do State
void DoState(PointerWrap &p);
@ -49,8 +43,16 @@ void DoState(PointerWrap &p);
// Set default content file
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);
IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName);
// Update
void Update();

View File

@ -28,9 +28,11 @@ class IWII_IPC_HLE_Device
{
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_DeviceID(_DeviceID)
m_DeviceID(_DeviceID),
m_Hardware(_Hardware),
m_Active(false)
{}
virtual ~IWII_IPC_HLE_Device()
@ -42,8 +44,8 @@ public:
const std::string& GetDeviceName() const { return m_Name; }
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 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 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()); 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 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; }
@ -54,15 +56,16 @@ public:
virtual bool ReturnFileHandle() { return false; }
virtual bool IsHardware() { return m_Hardware; }
virtual bool IsOpened() { return m_Active; }
private:
protected:
// STATE_TO_SAVE
std::string m_Name;
u32 m_DeviceID;
protected:
u32 m_DeviceID;
bool m_Hardware;
bool m_Active;
// ===================================================
/* 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)
{
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
m_Active = true;
return true;
}
bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress)
{
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true;
}

View File

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

View File

@ -40,8 +40,8 @@ std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
return Filename;
}
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName )
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware
, m_pFileHandle(NULL)
, m_FileLength(0)
{
@ -66,7 +66,7 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
// Close always return 0 for success
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
return true;
}
@ -130,6 +130,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
}
Memory::Write_U32(ReturnValue, _CommandAddress+4);
m_Active = 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)
, m_pContentLoader(NULL)
, m_TitleID(-1)
, 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);
@ -91,19 +101,13 @@ CWII_IPC_HLE_Device_es::CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string&
//FindValidTitleIDs();
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)
{
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
}
@ -111,7 +115,8 @@ bool CWII_IPC_HLE_Device_es::Close(u32 _CommandAddress)
{
INFO_LOG(WII_IPC_ES, "ES: Close");
Memory::Write_U32(0, _CommandAddress + 4);
return true;
m_Active = false;
return true;
}
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:
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();
void Load(const std::string& _rDefaultContentFile);
virtual bool Open(u32 _CommandAddress, u32 _Mode);
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);
m_Active = true;
return true;
}
@ -75,6 +76,7 @@ bool CWII_IPC_HLE_Device_fs::Close(u32 _CommandAddress)
// Do we even need to do anything?
INFO_LOG(WII_IPC_NET, "/dev/fs: Close");
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
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");
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
m_Active = 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");
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
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");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = 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");
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
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");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = 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");
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
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);
m_Active = true;
return true;
}
@ -72,6 +73,7 @@ bool CWII_IPC_HLE_Device_sdio_slot0::Close(u32 _CommandAddress)
fclose(m_Card);
Memory::Write_U32(0, _CommandAddress + 0x4);
m_Active = false;
return true;
}

View File

@ -56,6 +56,7 @@ public:
{
ERROR_LOG(WII_IPC_STM, "STM immediate: Open");
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
}
@ -63,6 +64,7 @@ public:
{
ERROR_LOG(WII_IPC_STM, "STM immediate: Close");
Memory::Write_U32(0, _CommandAddress+4);
m_Active = false;
return true;
}
@ -145,13 +147,15 @@ public:
virtual bool Open(u32 _CommandAddress, u32 _Mode)
{
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
return true;
m_Active = true;
return true;
}
virtual bool Close(u32 _CommandAddress)
{
INFO_LOG(WII_IPC_STM, "STM eventhook: Close");
Memory::Write_U32(0, _CommandAddress+4);
m_Active = false;
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_LastCmd(NULL)
, m_PacketCount(0)
, m_FreqDividerSync(0)
, m_FreqDividerMote(0)
{
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 0));
// 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_ACLBuffer);
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)
{
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = 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)
{
Memory::Write_U32(0, _CommandAddress + 4);
m_Active = false;
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()
{
// Check if HCI Pool is not purged
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
// 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())
{
FreqDividerSync++;
if ((m_PacketCount > 0) || (FreqDividerSync > 30)) // Feel free to tweak it
m_FreqDividerSync++;
if ((m_PacketCount > 0) || (m_FreqDividerSync > 30)) // Feel free to tweak it
{
FreqDividerSync = 0;
m_FreqDividerSync = 0;
SendEventNumberOfCompletedPackets(m_WiiMotes[0].GetConnectionHandle(), m_PacketCount);
m_PacketCount = 0;
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
// 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())
{
FreqDividerMote++;
if(FreqDividerMote > 99) // Feel free to tweak it
m_FreqDividerMote++;
if(m_FreqDividerMote > 99) // Feel free to tweak it
{
FreqDividerMote = 0;
m_FreqDividerMote = 0;
CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update();
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)
{
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
m_Active = true;
return true;
}
bool CWII_IPC_HLE_Device_usb_oh0::Close(u32 _CommandAddress)
{
Memory::Write_U32(0, _CommandAddress + 0x4);
m_Active = false;
return true;
}

View File

@ -189,6 +189,8 @@ private:
ACLPool m_ACLPool;
u32 m_LastCmd;
int m_PacketCount;
u32 m_FreqDividerSync;
u32 m_FreqDividerMote;
// Events
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_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, NULL));
m_Active = true;
return true;
}

View File

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