Fixed Pokepark 2! Maybe... :D Don't trust save states, although I think they are correct. File fd's were too large. Let me know if file related loading stops working in some games. fds are many to 1, not 1 to 1. ES has two instances available at a time. Sadly a clean up requires changing IWII_IPC_HLE_Device Constructor, as a deviceID doesn't make much sense per device. I won't do this until we have less branches :|
This commit is contained in:
parent
0ed8af2287
commit
6fe495e1aa
|
@ -68,8 +68,13 @@ 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;
|
|
||||||
u32 g_LastDeviceID;
|
#define IPC_MAX_FDS 0x18
|
||||||
|
#define ES_MAX_COUNT 2
|
||||||
|
IWII_IPC_HLE_Device* g_FdMap[IPC_MAX_FDS];
|
||||||
|
bool es_inuse[ES_MAX_COUNT];
|
||||||
|
IWII_IPC_HLE_Device* es_handles[ES_MAX_COUNT];
|
||||||
|
|
||||||
|
|
||||||
typedef std::deque<u32> ipc_msg_queue;
|
typedef std::deque<u32> ipc_msg_queue;
|
||||||
static ipc_msg_queue request_queue; // ppc -> arm
|
static ipc_msg_queue request_queue; // ppc -> arm
|
||||||
|
@ -78,14 +83,27 @@ static ipc_msg_queue reply_queue; // arm -> ppc
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init");
|
_dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init");
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
for(i=0; i<IPC_MAX_FDS; i++){
|
||||||
|
g_FdMap[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
u32 i = IPC_FIRST_HARDWARE_ID;
|
i = 0;
|
||||||
// Build hardware devices
|
// 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_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_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_stm_eventhook(i, std::string("/dev/stm/eventhook")); i++;
|
||||||
g_DeviceMap[i] = new CWII_IPC_HLE_Device_fs(i, std::string("/dev/fs")); i++;
|
g_DeviceMap[i] = new CWII_IPC_HLE_Device_fs(i, std::string("/dev/fs")); i++;
|
||||||
g_DeviceMap[i] = new CWII_IPC_HLE_Device_es(i, std::string("/dev/es")); i++;
|
|
||||||
|
// IOS allows two ES devices at a time<
|
||||||
|
u32 j;
|
||||||
|
for (j=0; j<ES_MAX_COUNT; j++)
|
||||||
|
{
|
||||||
|
g_DeviceMap[i] = es_handles[j] = new CWII_IPC_HLE_Device_es(i, std::string("/dev/es")); i++;
|
||||||
|
es_inuse[j] = false;
|
||||||
|
}
|
||||||
|
|
||||||
g_DeviceMap[i] = new CWII_IPC_HLE_Device_di(i, std::string("/dev/di")); 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_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_kd_time(i, std::string("/dev/net/kd/time")); i++;
|
||||||
|
@ -96,13 +114,23 @@ void Init()
|
||||||
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++;
|
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++;
|
||||||
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++;
|
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++;
|
||||||
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++;
|
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++;
|
||||||
g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_"));
|
g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++;
|
||||||
|
|
||||||
g_LastDeviceID = IPC_FIRST_FILEIO_ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset(bool _bHard)
|
void Reset(bool _bHard)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
for (i=0; i<IPC_MAX_FDS; i++){
|
||||||
|
if (g_FdMap[i] != NULL && !g_FdMap[i]->IsHardware())
|
||||||
|
{
|
||||||
|
// close all files and delete their resources
|
||||||
|
g_FdMap[i]->Close(0, true);
|
||||||
|
delete g_FdMap[i];
|
||||||
|
}
|
||||||
|
g_FdMap[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
TDeviceMap::iterator itr = g_DeviceMap.begin();
|
TDeviceMap::iterator itr = g_DeviceMap.begin();
|
||||||
while (itr != g_DeviceMap.end())
|
while (itr != g_DeviceMap.end())
|
||||||
{
|
{
|
||||||
|
@ -111,21 +139,17 @@ void Reset(bool _bHard)
|
||||||
// Force close
|
// Force close
|
||||||
itr->second->Close(0, true);
|
itr->second->Close(0, true);
|
||||||
// Hardware should not be deleted unless it is a hard reset
|
// Hardware should not be deleted unless it is a hard reset
|
||||||
if (_bHard || !itr->second->IsHardware())
|
if (_bHard)
|
||||||
delete itr->second;
|
delete itr->second;
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
// Skip hardware devices if not a hard reset
|
if (_bHard)
|
||||||
itr = (_bHard) ? g_DeviceMap.begin() : g_DeviceMap.lower_bound(IPC_FIRST_FILEIO_ID);
|
{
|
||||||
// Erase devices
|
g_DeviceMap.erase(g_DeviceMap.begin(), g_DeviceMap.end());
|
||||||
g_DeviceMap.erase(itr, g_DeviceMap.end());
|
}
|
||||||
g_FileNameMap.clear();
|
|
||||||
|
|
||||||
request_queue.clear();
|
request_queue.clear();
|
||||||
reply_queue.clear();
|
reply_queue.clear();
|
||||||
|
|
||||||
g_LastDeviceID = IPC_FIRST_FILEIO_ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
|
@ -135,41 +159,52 @@ void Shutdown()
|
||||||
|
|
||||||
void SetDefaultContentFile(const std::string& _rFilename)
|
void SetDefaultContentFile(const std::string& _rFilename)
|
||||||
{
|
{
|
||||||
CWII_IPC_HLE_Device_es* pDevice =
|
TDeviceMap::const_iterator itr = g_DeviceMap.begin();
|
||||||
(CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
|
while(itr != g_DeviceMap.end())
|
||||||
if (pDevice)
|
{
|
||||||
pDevice->LoadWAD(_rFilename);
|
if (itr->second && itr->second->GetDeviceName().find(std::string("/dev/es")) == 0)
|
||||||
|
{
|
||||||
|
((CWII_IPC_HLE_Device_es*)itr->second)->LoadWAD(_rFilename);
|
||||||
|
}
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ES_DIVerify(u8 *_pTMD, u32 _sz)
|
void ES_DIVerify(u8 *_pTMD, u32 _sz)
|
||||||
{
|
{
|
||||||
CWII_IPC_HLE_Device_es* pDevice =
|
CWII_IPC_HLE_Device_es::ES_DIVerify(_pTMD, _sz);
|
||||||
(CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es")));
|
|
||||||
if (pDevice)
|
|
||||||
pDevice->ES_DIVerify(_pTMD, _sz);
|
|
||||||
else
|
|
||||||
ERROR_LOG(WII_IPC_ES, "DIVerify called but /dev/es is not available");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDIO_EventNotify()
|
void SDIO_EventNotify()
|
||||||
{
|
{
|
||||||
CWII_IPC_HLE_Device_sdio_slot0 *pDevice =
|
CWII_IPC_HLE_Device_sdio_slot0 *pDevice =
|
||||||
(CWII_IPC_HLE_Device_sdio_slot0*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/sdio/slot0")));
|
(CWII_IPC_HLE_Device_sdio_slot0*)GetDeviceByName(std::string("/dev/sdio/slot0"));
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
pDevice->EventNotify();
|
pDevice->EventNotify();
|
||||||
}
|
}
|
||||||
|
int getFreeDeviceId()
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
for(i=0; i<IPC_MAX_FDS; i++){
|
||||||
|
if (g_FdMap[i] == NULL)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int GetDeviceIDByName(const std::string& _rDeviceName)
|
IWII_IPC_HLE_Device* GetDeviceByName(const std::string& _rDeviceName)
|
||||||
{
|
{
|
||||||
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->GetDeviceName() == _rDeviceName)
|
if (itr->second && itr->second->GetDeviceName() == _rDeviceName)
|
||||||
return itr->first;
|
return itr->second;
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID)
|
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID)
|
||||||
|
@ -177,17 +212,7 @@ 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];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteDeviceByID(u32 ID)
|
|
||||||
{
|
|
||||||
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(ID);
|
|
||||||
if (pDevice)
|
|
||||||
delete pDevice;
|
|
||||||
|
|
||||||
g_DeviceMap.erase(ID);
|
|
||||||
g_FileNameMap.erase(ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is called from ExecuteCommand() COMMAND_OPEN_DEVICE
|
// This is called from ExecuteCommand() COMMAND_OPEN_DEVICE
|
||||||
|
@ -205,60 +230,82 @@ IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(g_LastDeviceID);
|
p.Do(request_queue);
|
||||||
|
p.Do(reply_queue);
|
||||||
|
|
||||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
TDeviceMap::const_iterator itr;
|
||||||
{
|
|
||||||
TFileNameMap::const_iterator itr;
|
itr = g_DeviceMap.begin();
|
||||||
// Delete file Handles
|
while (itr != g_DeviceMap.end())
|
||||||
itr = g_FileNameMap.begin();
|
{
|
||||||
while (itr != g_FileNameMap.end())
|
if (itr->second->IsHardware())
|
||||||
{
|
|
||||||
TDeviceMap::const_iterator devitr = g_DeviceMap.find(itr->first);
|
|
||||||
if (devitr != g_DeviceMap.end())
|
|
||||||
{
|
{
|
||||||
if (devitr->second)
|
itr->second->DoState(p);
|
||||||
delete devitr->second;
|
|
||||||
g_DeviceMap.erase(itr->first);
|
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||||
|
{
|
||||||
|
u32 i;
|
||||||
|
for (i=0; i<IPC_MAX_FDS; i++){
|
||||||
|
u32 exists;
|
||||||
|
p.Do(exists);
|
||||||
|
if (exists){
|
||||||
|
u32 isHw;
|
||||||
|
p.Do(isHw);
|
||||||
|
if (isHw)
|
||||||
|
{
|
||||||
|
u32 hwId;
|
||||||
|
p.Do(hwId);
|
||||||
|
g_FdMap[i] = AccessDeviceByID(hwId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_FdMap[i] = new CWII_IPC_HLE_Device_FileIO(i, "");
|
||||||
|
g_FdMap[i]->DoState(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_FdMap[i] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Load file names
|
for (i=0; i<ES_MAX_COUNT; i++)
|
||||||
p.Do(g_FileNameMap);
|
|
||||||
// Rebuild file handles
|
|
||||||
itr = g_FileNameMap.begin();
|
|
||||||
while (itr != g_FileNameMap.end())
|
|
||||||
{
|
{
|
||||||
g_DeviceMap[itr->first] = new CWII_IPC_HLE_Device_FileIO(itr->first, itr->second);
|
p.Do(es_inuse[i]);
|
||||||
++itr;
|
u32 handleID = es_handles[i]->GetDeviceID();
|
||||||
|
p.Do(handleID);
|
||||||
|
|
||||||
|
es_handles[i] = AccessDeviceByID(handleID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p.Do(g_FileNameMap);
|
u32 i;
|
||||||
}
|
for (i=0; i<IPC_MAX_FDS; i++){
|
||||||
|
u32 exists = g_FdMap[i] ? 1 : 0;
|
||||||
p.Do(request_queue);
|
p.Do(exists);
|
||||||
p.Do(reply_queue);
|
if (exists){
|
||||||
|
u32 isHw = g_FdMap[i]->IsHardware() ? 1 : 0;
|
||||||
|
p.Do(isHw);
|
||||||
TDeviceMap::const_iterator itr;
|
if (isHw)
|
||||||
//first, all the real devices
|
{
|
||||||
//(because we need fs to be deserialized first)
|
u32 hwId = g_FdMap[i]->GetDeviceID();
|
||||||
itr = g_DeviceMap.begin();
|
p.Do(hwId);
|
||||||
while (itr != g_DeviceMap.end())
|
}
|
||||||
{
|
else
|
||||||
if (itr->second->IsHardware())
|
{
|
||||||
itr->second->DoState(p);
|
g_FdMap[i]->DoState(p);
|
||||||
++itr;
|
}
|
||||||
}
|
}
|
||||||
//then all the files
|
}
|
||||||
itr = g_DeviceMap.begin();
|
for (i=0; i<ES_MAX_COUNT; i++)
|
||||||
while (itr != g_DeviceMap.end())
|
{
|
||||||
{
|
p.Do(es_inuse[i]);
|
||||||
if (!itr->second->IsHardware())
|
u32 handleID = es_handles[i]->GetDeviceID();
|
||||||
itr->second->DoState(p);
|
p.Do(handleID);
|
||||||
++itr;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,67 +314,106 @@ void ExecuteCommand(u32 _Address)
|
||||||
bool CmdSuccess = false;
|
bool CmdSuccess = false;
|
||||||
|
|
||||||
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
|
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
|
||||||
int DeviceID = Memory::Read_U32(_Address + 8);
|
volatile int DeviceID = Memory::Read_U32(_Address + 8);
|
||||||
IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
|
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_HLE, "-->> Execute Command Address: 0x%08x (code: %x, device: %x) ", _Address, Command, DeviceID);
|
IWII_IPC_HLE_Device* pDevice = (DeviceID >= 0 && DeviceID < IPC_MAX_FDS) ? g_FdMap[DeviceID] : NULL;
|
||||||
|
|
||||||
|
INFO_LOG(WII_IPC_HLE, "-->> Execute Command Address: 0x%08x (code: %x, device: %x) %p", _Address, Command, DeviceID, pDevice);
|
||||||
|
|
||||||
switch (Command)
|
switch (Command)
|
||||||
{
|
{
|
||||||
case COMMAND_OPEN_DEVICE:
|
case COMMAND_OPEN_DEVICE:
|
||||||
{
|
{
|
||||||
// Create a new HLE device. The Mode and DeviceName is given to us but we
|
u32 Mode = Memory::Read_U32(_Address + 0x10);
|
||||||
// generate a DeviceID to be used for access to this device until it is Closed.
|
DeviceID = getFreeDeviceId();
|
||||||
std::string DeviceName;
|
|
||||||
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC));
|
std::string DeviceName;
|
||||||
|
Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC));
|
||||||
|
|
||||||
u32 Mode = Memory::Read_U32(_Address + 0x10);
|
|
||||||
DeviceID = GetDeviceIDByName(DeviceName);
|
WARN_LOG(WII_IPC_HLE, "Tried to open %s as %d", DeviceName.c_str(), DeviceID);
|
||||||
|
if (DeviceID >= 0)
|
||||||
// check if a device with this name has been created already
|
{
|
||||||
if (DeviceName.find("/dev/") == std::string::npos || DeviceID == -1)
|
if (DeviceName.find("/dev/es") == 0)
|
||||||
{
|
{
|
||||||
if (DeviceName.find("/dev/") == 0)
|
u32 j;
|
||||||
|
for (j=0; j<ES_MAX_COUNT; j++)
|
||||||
{
|
{
|
||||||
WARN_LOG(WII_IPC_HLE, "Unimplemented device: %s", DeviceName.c_str());
|
if (!es_inuse[j])
|
||||||
|
{
|
||||||
|
es_inuse[j] = true;
|
||||||
|
g_FdMap[DeviceID] = es_handles[j];
|
||||||
|
CmdSuccess = es_handles[j]->Open(_Address, Mode);
|
||||||
|
Memory::Write_U32(DeviceID, _Address+4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(j == ES_MAX_COUNT)
|
||||||
|
{
|
||||||
|
Memory::Write_U32(FS_EESEXHAUSTED, _Address + 4);
|
||||||
|
CmdSuccess = true;
|
||||||
|
}
|
||||||
|
|
||||||
pDevice = AccessDeviceByID(GetDeviceIDByName(std::string("_Unimplemented_Device_")));
|
}
|
||||||
|
else if (DeviceName.find("/dev/") == 0)
|
||||||
|
{
|
||||||
|
pDevice = GetDeviceByName(DeviceName);
|
||||||
|
if (pDevice)
|
||||||
|
{
|
||||||
|
g_FdMap[DeviceID] = pDevice;
|
||||||
CmdSuccess = pDevice->Open(_Address, Mode);
|
CmdSuccess = pDevice->Open(_Address, Mode);
|
||||||
|
INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)",
|
||||||
|
pDevice->GetDeviceName().c_str(), DeviceID, Mode);
|
||||||
|
Memory::Write_U32(DeviceID, _Address+4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// create new file handle
|
WARN_LOG(WII_IPC_HLE, "Unimplemented device: %s", DeviceName.c_str());
|
||||||
u32 CurrentDeviceID = g_LastDeviceID;
|
pDevice = GetDeviceByName(std::string("_Unimplemented_Device_"));
|
||||||
pDevice = CreateFileIO(CurrentDeviceID, DeviceName);
|
|
||||||
g_DeviceMap[CurrentDeviceID] = pDevice;
|
|
||||||
g_FileNameMap[CurrentDeviceID] = DeviceName;
|
|
||||||
g_LastDeviceID++;
|
|
||||||
|
|
||||||
CmdSuccess = pDevice->Open(_Address, Mode);
|
CmdSuccess = pDevice->Open(_Address, Mode);
|
||||||
|
g_FdMap[DeviceID] = pDevice;
|
||||||
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)",
|
Memory::Write_U32(DeviceID, _Address+4);
|
||||||
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// F|RES: prolly the re-open is just a mode change
|
IWII_IPC_HLE_Device* pDevice = CreateFileIO(DeviceID, DeviceName);
|
||||||
pDevice = AccessDeviceByID(DeviceID);
|
|
||||||
CmdSuccess = pDevice->Open(_Address, Mode);
|
CmdSuccess = pDevice->Open(_Address, Mode);
|
||||||
|
|
||||||
INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)",
|
INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)",
|
||||||
pDevice->GetDeviceName().c_str(), DeviceID, Mode);
|
pDevice->GetDeviceName().c_str(), DeviceID, Mode);
|
||||||
}
|
if(Memory::Read_U32(_Address + 4) == DeviceID)
|
||||||
}
|
g_FdMap[DeviceID] = pDevice;
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Memory::Write_U32(FS_EFDEXHAUSTED, _Address + 4);
|
||||||
|
CmdSuccess = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case COMMAND_CLOSE_DEVICE:
|
case COMMAND_CLOSE_DEVICE:
|
||||||
if (pDevice)
|
{
|
||||||
|
if (pDevice)
|
||||||
{
|
{
|
||||||
CmdSuccess = pDevice->Close(_Address);
|
CmdSuccess = pDevice->Close(_Address);
|
||||||
|
|
||||||
|
u32 j;
|
||||||
|
for (j=0; j<ES_MAX_COUNT; j++)
|
||||||
|
{
|
||||||
|
if (es_handles[j] == g_FdMap[DeviceID])
|
||||||
|
{
|
||||||
|
es_inuse[j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_FdMap[DeviceID] = NULL;
|
||||||
|
|
||||||
// Don't delete hardware
|
// Don't delete hardware
|
||||||
if (!pDevice->IsHardware())
|
if (!pDevice->IsHardware())
|
||||||
DeleteDeviceByID(DeviceID);
|
delete pDevice;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -335,50 +421,67 @@ void ExecuteCommand(u32 _Address)
|
||||||
CmdSuccess = true;
|
CmdSuccess = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case COMMAND_READ:
|
case COMMAND_READ:
|
||||||
|
{
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
|
{
|
||||||
CmdSuccess = pDevice->Read(_Address);
|
CmdSuccess = pDevice->Read(_Address);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Memory::Write_U32(FS_EINVAL, _Address + 4);
|
Memory::Write_U32(FS_EINVAL, _Address + 4);
|
||||||
CmdSuccess = true;
|
CmdSuccess = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case COMMAND_WRITE:
|
case COMMAND_WRITE:
|
||||||
|
{
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
|
{
|
||||||
CmdSuccess = pDevice->Write(_Address);
|
CmdSuccess = pDevice->Write(_Address);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Memory::Write_U32(FS_EINVAL, _Address + 4);
|
Memory::Write_U32(FS_EINVAL, _Address + 4);
|
||||||
CmdSuccess = true;
|
CmdSuccess = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case COMMAND_SEEK:
|
case COMMAND_SEEK:
|
||||||
|
{
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
|
{
|
||||||
CmdSuccess = pDevice->Seek(_Address);
|
CmdSuccess = pDevice->Seek(_Address);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Memory::Write_U32(FS_EINVAL, _Address + 4);
|
Memory::Write_U32(FS_EINVAL, _Address + 4);
|
||||||
CmdSuccess = true;
|
CmdSuccess = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case COMMAND_IOCTL:
|
case COMMAND_IOCTL:
|
||||||
|
{
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
|
{
|
||||||
CmdSuccess = pDevice->IOCtl(_Address);
|
CmdSuccess = pDevice->IOCtl(_Address);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case COMMAND_IOCTLV:
|
case COMMAND_IOCTLV:
|
||||||
|
{
|
||||||
if (pDevice)
|
if (pDevice)
|
||||||
|
{
|
||||||
CmdSuccess = pDevice->IOCtlV(_Address);
|
CmdSuccess = pDevice->IOCtlV(_Address);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
_dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address);
|
_dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// It seems that the original hardware overwrites the command after it has been
|
// It seems that the original hardware overwrites the command after it has been
|
||||||
|
@ -450,8 +553,7 @@ void Update()
|
||||||
void UpdateDevices()
|
void UpdateDevices()
|
||||||
{
|
{
|
||||||
// Check if a hardware device must be updated
|
// Check if a hardware device must be updated
|
||||||
TDeviceMap::const_iterator itrEnd = g_DeviceMap.lower_bound(IPC_FIRST_FILEIO_ID);
|
for (TDeviceMap::const_iterator itr = g_DeviceMap.begin(); itr != g_DeviceMap.end(); ++itr) {
|
||||||
for (TDeviceMap::const_iterator itr = g_DeviceMap.begin(); itr != itrEnd; ++itr) {
|
|
||||||
if (itr->second->IsOpened() && itr->second->Update()) {
|
if (itr->second->IsOpened() && itr->second->Update()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,9 @@ class IWII_IPC_HLE_Device;
|
||||||
namespace WII_IPC_HLE_Interface
|
namespace WII_IPC_HLE_Interface
|
||||||
{
|
{
|
||||||
|
|
||||||
#define IPC_FIRST_HARDWARE_ID 0 // first IPC device ID
|
#define IPC_FIRST_ID 0x00 // first IPC device ID
|
||||||
#define IPC_FIRST_FILEIO_ID 33 // first IPC file ID
|
#define IPC_MAX_FILES 0x10 // first IPC file ID
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
@ -46,14 +46,13 @@ void ES_DIVerify(u8 *_pTMD, u32 _sz);
|
||||||
|
|
||||||
void SDIO_EventNotify();
|
void SDIO_EventNotify();
|
||||||
|
|
||||||
int GetDeviceIDByName(const std::string& _rDeviceName);
|
|
||||||
|
|
||||||
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
|
|
||||||
|
|
||||||
void DeleteDeviceByID(u32 _ID);
|
|
||||||
|
|
||||||
IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName);
|
IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName);
|
||||||
|
|
||||||
|
IWII_IPC_HLE_Device* GetDeviceByName(const std::string& _rDeviceName);
|
||||||
|
IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID);
|
||||||
|
int getFreeDeviceId();
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class PointerWrap;
|
||||||
#define FS_ENOENT2 (u32)-106 // File not found
|
#define FS_ENOENT2 (u32)-106 // File not found
|
||||||
#define FS_ENFILE (u32)-107 // Too many fds open
|
#define FS_ENFILE (u32)-107 // Too many fds open
|
||||||
#define FS_EFBIG (u32)-108 // max block count reached?
|
#define FS_EFBIG (u32)-108 // max block count reached?
|
||||||
#define FS_ENFILE2 (u32)-109 // Too many fds open
|
#define FS_EFDEXHAUSTED (u32)-109 // Too many fds open
|
||||||
#define FS_ENAMELEN (u32)-110 // pathname is too long
|
#define FS_ENAMELEN (u32)-110 // pathname is too long
|
||||||
#define FS_EFDOPEN (u32)-111 // FD is already open
|
#define FS_EFDOPEN (u32)-111 // FD is already open
|
||||||
#define FS_EIO2 (u32)-114 // returned on ECC error
|
#define FS_EIO2 (u32)-114 // returned on ECC error
|
||||||
|
@ -47,6 +47,7 @@ class PointerWrap;
|
||||||
#define FS_EDIRDEPTH (u32)-116 // max directory depth exceeded
|
#define FS_EDIRDEPTH (u32)-116 // max directory depth exceeded
|
||||||
#define FS_EBUSY2 (u32)-118 // Resource busy
|
#define FS_EBUSY2 (u32)-118 // Resource busy
|
||||||
//#define FS_EFATAL (u32)-119 // fatal error not used by IOS as fatal ERROR
|
//#define FS_EFATAL (u32)-119 // fatal error not used by IOS as fatal ERROR
|
||||||
|
#define FS_EESEXHAUSTED (u32)-1016 // Max of 2 ES handles at a time
|
||||||
|
|
||||||
class IWII_IPC_HLE_Device
|
class IWII_IPC_HLE_Device
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
static Common::replace_v replacements;
|
static Common::replace_v replacements;
|
||||||
|
|
||||||
// This is used by several of the FileIO and /dev/fs/ functions
|
// This is used by several of the FileIO and /dev/fs functions
|
||||||
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
|
std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
|
||||||
{
|
{
|
||||||
std::string path_full = File::GetUserPath(D_WIIROOT_IDX);
|
std::string path_full = File::GetUserPath(D_WIIROOT_IDX);
|
||||||
|
@ -128,7 +128,7 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
|
|
||||||
// The file must exist before we can open it
|
// The file must exist before we can open it
|
||||||
// It should be created by ISFS_CreateFile, not here
|
// It should be created by ISFS_CreateFile, not here
|
||||||
if(File::Exists(m_Filename))
|
if (File::Exists(m_Filename))
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: Open %s (%s == %08X)", m_Name.c_str(), Modes[_Mode], _Mode);
|
||||||
ReturnValue = m_DeviceID;
|
ReturnValue = m_DeviceID;
|
||||||
|
@ -149,21 +149,22 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_FileIO::OpenFile()
|
bool CWII_IPC_HLE_Device_FileIO::OpenFile()
|
||||||
{
|
{
|
||||||
switch(m_Mode)
|
switch (m_Mode)
|
||||||
{
|
{
|
||||||
case ISFS_OPEN_READ:
|
case ISFS_OPEN_READ:
|
||||||
|
{
|
||||||
m_pFileHandle.Open(m_Filename, "rb");
|
m_pFileHandle.Open(m_Filename, "rb");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// "r+b" is technically wrong, but OPEN_WRITE should not truncate the file as "wb" does.
|
|
||||||
case ISFS_OPEN_WRITE:
|
case ISFS_OPEN_WRITE:
|
||||||
m_pFileHandle.Open(m_Filename, "r+b");
|
m_pFileHandle.Open(m_Filename, "r+b");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ISFS_OPEN_RW:
|
case ISFS_OPEN_RW:
|
||||||
|
{
|
||||||
m_pFileHandle.Open(m_Filename, "r+b");
|
m_pFileHandle.Open(m_Filename, "r+b");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode);
|
PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode);
|
||||||
break;
|
break;
|
||||||
|
@ -178,21 +179,21 @@ void CWII_IPC_HLE_Device_FileIO::CloseFile()
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
u32 ReturnValue = FS_RESULT_FATAL;
|
u32 ReturnValue = FS_RESULT_FATAL;
|
||||||
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
const s32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||||
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
const s32 Mode = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
|
|
||||||
|
|
||||||
if(OpenFile())
|
if (OpenFile())
|
||||||
{
|
{
|
||||||
ReturnValue = FS_RESULT_FATAL;
|
ReturnValue = FS_RESULT_FATAL;
|
||||||
|
|
||||||
const u64 fileSize = m_pFileHandle.GetSize();
|
const u64 fileSize = m_pFileHandle.GetSize();
|
||||||
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize);
|
||||||
switch(Mode){
|
switch (Mode){
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
if(SeekPosition >=0 && SeekPosition <= fileSize)
|
if (SeekPosition >=0 && SeekPosition <= fileSize)
|
||||||
{
|
{
|
||||||
m_SeekPos = SeekPosition;
|
m_SeekPos = SeekPosition;
|
||||||
ReturnValue = m_SeekPos;
|
ReturnValue = m_SeekPos;
|
||||||
|
@ -202,7 +203,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
s32 wantedPos = SeekPosition+m_SeekPos;
|
s32 wantedPos = SeekPosition+m_SeekPos;
|
||||||
if(wantedPos >=0 && wantedPos <= fileSize)
|
if (wantedPos >=0 && wantedPos <= fileSize)
|
||||||
{
|
{
|
||||||
m_SeekPos = wantedPos;
|
m_SeekPos = wantedPos;
|
||||||
ReturnValue = m_SeekPos;
|
ReturnValue = m_SeekPos;
|
||||||
|
@ -212,7 +213,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
s32 wantedPos = fileSize+m_SeekPos;
|
s32 wantedPos = fileSize+m_SeekPos;
|
||||||
if(wantedPos >=0 && wantedPos <= fileSize)
|
if (wantedPos >=0 && wantedPos <= fileSize)
|
||||||
{
|
{
|
||||||
m_SeekPos = wantedPos;
|
m_SeekPos = wantedPos;
|
||||||
ReturnValue = m_SeekPos;
|
ReturnValue = m_SeekPos;
|
||||||
|
@ -244,7 +245,7 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
||||||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
|
|
||||||
|
|
||||||
if(OpenFile())
|
if (OpenFile())
|
||||||
{
|
{
|
||||||
if (m_Mode == ISFS_OPEN_WRITE)
|
if (m_Mode == ISFS_OPEN_WRITE)
|
||||||
{
|
{
|
||||||
|
@ -284,7 +285,7 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
||||||
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
const u32 Size = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
|
|
||||||
|
|
||||||
if(OpenFile())
|
if (OpenFile())
|
||||||
{
|
{
|
||||||
if (m_Mode == ISFS_OPEN_READ)
|
if (m_Mode == ISFS_OPEN_READ)
|
||||||
{
|
{
|
||||||
|
@ -318,21 +319,14 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
DumpCommands(_CommandAddress);
|
DumpCommands(_CommandAddress);
|
||||||
#endif
|
#endif
|
||||||
const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
const u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
||||||
|
u32 ReturnValue = 0;
|
||||||
|
|
||||||
//u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
switch (Parameter)
|
||||||
//u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
|
|
||||||
//u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
|
||||||
//u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
|
|
||||||
|
|
||||||
// Return Value
|
|
||||||
u32 ReturnValue = 0; // no error
|
|
||||||
|
|
||||||
switch(Parameter)
|
|
||||||
{
|
{
|
||||||
case ISFS_IOCTL_GETFILESTATS:
|
case ISFS_IOCTL_GETFILESTATS:
|
||||||
{
|
{
|
||||||
if(OpenFile())
|
if (OpenFile())
|
||||||
{
|
{
|
||||||
u32 m_FileLength = (u32)m_pFileHandle.GetSize();
|
u32 m_FileLength = (u32)m_pFileHandle.GetSize();
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
virtual bool Close(u32 _CommandAddress, bool _bForce);
|
virtual bool Close(u32 _CommandAddress, bool _bForce);
|
||||||
|
|
||||||
virtual bool IOCtlV(u32 _CommandAddress);
|
virtual bool IOCtlV(u32 _CommandAddress);
|
||||||
u32 ES_DIVerify(u8 *_pTMD, u32 _sz);
|
static u32 ES_DIVerify(u8 *_pTMD, u32 _sz);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
Loading…
Reference in New Issue