diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index eeb6c4fe7c..aeb3c4be16 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -137,6 +137,8 @@ set(SRCS ActionReplay.cpp
IPC_HLE/ICMPLin.cpp
IPC_HLE/NWC24Config.cpp
IPC_HLE/WII_IPC_HLE.cpp
+ IPC_HLE/WII_IPC_HLE_Device.cpp
+ IPC_HLE/WII_IPC_HLE_Device_stub.cpp
IPC_HLE/WII_IPC_HLE_Device_DI.cpp
IPC_HLE/WII_IPC_HLE_Device_es.cpp
IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index b78395639a..7b1745536d 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -171,6 +171,8 @@
+
+
@@ -388,6 +390,7 @@
+
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index a440d4ce11..4a696ec05c 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -555,6 +555,12 @@
IPC HLE %28IOS/Starlet%29
+
+ IPC HLE %28IOS/Starlet%29
+
+
+ IPC HLE %28IOS/Starlet%29
+
IPC HLE %28IOS/Starlet%29\DI
@@ -1127,6 +1133,9 @@
IPC HLE %28IOS/Starlet%29
+
+ IPC HLE %28IOS/Starlet%29
+
IPC HLE %28IOS/Starlet%29
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
index 3e0eb86a96..94bacf5fcf 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
@@ -51,6 +51,7 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC
#include "Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_stm.h"
+#include "Core/IPC_HLE/WII_IPC_HLE_Device_stub.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_emu.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_bt_real.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h"
@@ -625,12 +626,3 @@ void UpdateDevices()
}
} // end of namespace WII_IPC_HLE_Interface
-
-// TODO: create WII_IPC_HLE_Device.cpp ?
-void IWII_IPC_HLE_Device::DoStateShared(PointerWrap& p)
-{
- p.Do(m_Name);
- p.Do(m_DeviceID);
- p.Do(m_Hardware);
- p.Do(m_Active);
-}
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp
new file mode 100644
index 0000000000..d2a8e11490
--- /dev/null
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.cpp
@@ -0,0 +1,181 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Core/IPC_HLE/WII_IPC_HLE.h"
+#include "Common/StringUtil.h"
+#include "Core/HW/Memmap.h"
+#include "Core/HW/SystemTimers.h"
+#include "Core/IPC_HLE/WII_IPC_HLE_Device.h"
+
+SIOCtlVBuffer::SIOCtlVBuffer(const u32 address) : m_Address(address)
+{
+ // These are the Ioctlv parameters in the IOS communication. The BufferVector
+ // is a memory address offset at where the in and out buffer addresses are
+ // stored.
+ Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0
+ NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1
+ NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2
+ BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3
+
+ // The start of the out buffer
+ u32 BufferVectorOffset = BufferVector;
+
+ // Write the address and size for all in messages
+ for (u32 i = 0; i < NumberInBuffer; i++)
+ {
+ SBuffer Buffer;
+ Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
+ BufferVectorOffset += 4;
+ Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
+ BufferVectorOffset += 4;
+ InBuffer.push_back(Buffer);
+ DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size);
+ }
+
+ // Write the address and size for all out or in-out messages
+ for (u32 i = 0; i < NumberPayloadBuffer; i++)
+ {
+ SBuffer Buffer;
+ Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
+ BufferVectorOffset += 4;
+ Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
+ BufferVectorOffset += 4;
+ PayloadBuffer.push_back(Buffer);
+ DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size);
+ }
+}
+
+IWII_IPC_HLE_Device::IWII_IPC_HLE_Device(const u32 device_id, const std::string& device_name,
+ const bool hardware)
+ : m_Name(device_name), m_DeviceID(device_id), m_Hardware(hardware)
+{
+}
+
+void IWII_IPC_HLE_Device::DoState(PointerWrap& p)
+{
+ DoStateShared(p);
+ p.Do(m_Active);
+}
+
+void IWII_IPC_HLE_Device::DoStateShared(PointerWrap& p)
+{
+ p.Do(m_Name);
+ p.Do(m_DeviceID);
+ p.Do(m_Hardware);
+ p.Do(m_Active);
+}
+
+IPCCommandResult IWII_IPC_HLE_Device::Open(u32 command_address, u32 mode)
+{
+ WARN_LOG(WII_IPC_HLE, "%s does not support Open()", m_Name.c_str());
+ Memory::Write_U32(FS_ENOENT, command_address + 4);
+ m_Active = true;
+ return GetDefaultReply();
+}
+
+IPCCommandResult IWII_IPC_HLE_Device::Close(u32 command_address, bool force)
+{
+ WARN_LOG(WII_IPC_HLE, "%s does not support Close()", m_Name.c_str());
+ if (!force)
+ Memory::Write_U32(FS_EINVAL, command_address + 4);
+ m_Active = false;
+ return GetDefaultReply();
+}
+
+IPCCommandResult IWII_IPC_HLE_Device::Seek(u32 command_address)
+{
+ WARN_LOG(WII_IPC_HLE, "%s does not support Seek()", m_Name.c_str());
+ return GetDefaultReply();
+}
+
+IPCCommandResult IWII_IPC_HLE_Device::Read(u32 command_address)
+{
+ WARN_LOG(WII_IPC_HLE, "%s does not support Read()", m_Name.c_str());
+ return GetDefaultReply();
+}
+
+IPCCommandResult IWII_IPC_HLE_Device::Write(u32 command_address)
+{
+ WARN_LOG(WII_IPC_HLE, "%s does not support Write()", m_Name.c_str());
+ return GetDefaultReply();
+}
+
+IPCCommandResult IWII_IPC_HLE_Device::IOCtl(u32 command_address)
+{
+ WARN_LOG(WII_IPC_HLE, "%s does not support IOCtl()", m_Name.c_str());
+ return GetDefaultReply();
+}
+
+IPCCommandResult IWII_IPC_HLE_Device::IOCtlV(u32 command_address)
+{
+ WARN_LOG(WII_IPC_HLE, "%s does not support IOCtlV()", m_Name.c_str());
+ return GetDefaultReply();
+}
+
+// Returns an IPCCommandResult for a reply that takes 250 us (arbitrarily chosen value)
+IPCCommandResult IWII_IPC_HLE_Device::GetDefaultReply()
+{
+ return {true, SystemTimers::GetTicksPerSecond() / 4000};
+}
+
+// Returns an IPCCommandResult with no reply. Useful for async commands that will generate a reply
+// later
+IPCCommandResult IWII_IPC_HLE_Device::GetNoReply()
+{
+ return {false, 0};
+}
+
+// Write out the IPC struct from command_address to num_commands numbers
+// of 4 byte commands.
+void IWII_IPC_HLE_Device::DumpCommands(u32 command_address, size_t num_commands,
+ LogTypes::LOG_TYPE log_type, LogTypes::LOG_LEVELS verbosity)
+{
+ GENERIC_LOG(log_type, verbosity, "CommandDump of %s", GetDeviceName().c_str());
+ for (u32 i = 0; i < num_commands; i++)
+ {
+ GENERIC_LOG(log_type, verbosity, " Command%02i: 0x%08x", i,
+ Memory::Read_U32(command_address + i * 4));
+ }
+}
+
+void IWII_IPC_HLE_Device::DumpAsync(u32 buffer_vector, u32 number_in_buffer, u32 number_io_buffer,
+ LogTypes::LOG_TYPE log_type, LogTypes::LOG_LEVELS verbosity)
+{
+ GENERIC_LOG(log_type, verbosity, "======= DumpAsync ======");
+
+ u32 BufferOffset = buffer_vector;
+ for (u32 i = 0; i < number_in_buffer; i++)
+ {
+ u32 InBuffer = Memory::Read_U32(BufferOffset);
+ BufferOffset += 4;
+ u32 InBufferSize = Memory::Read_U32(BufferOffset);
+ BufferOffset += 4;
+
+ GENERIC_LOG(log_type, LogTypes::LINFO, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i);
+
+ std::string Temp;
+ for (u32 j = 0; j < InBufferSize; j++)
+ {
+ Temp += StringFromFormat("%02x ", Memory::Read_U8(InBuffer + j));
+ }
+
+ GENERIC_LOG(log_type, LogTypes::LDEBUG, " Buffer: %s", Temp.c_str());
+ }
+
+ for (u32 i = 0; i < number_io_buffer; i++)
+ {
+ u32 OutBuffer = Memory::Read_U32(BufferOffset);
+ BufferOffset += 4;
+ u32 OutBufferSize = Memory::Read_U32(BufferOffset);
+ BufferOffset += 4;
+
+ GENERIC_LOG(log_type, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(),
+ i);
+ GENERIC_LOG(log_type, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):", OutBuffer,
+ OutBufferSize);
+
+ if (verbosity >= LogTypes::LOG_LEVELS::LINFO)
+ DumpCommands(OutBuffer, OutBufferSize, log_type, verbosity);
+ }
+}
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h
index f294aff9eb..d96afb34f0 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h
@@ -4,13 +4,14 @@
#pragma once
-#include
+#include
#include
#include
#include "Common/ChunkFile.h"
+#include "Common/CommonTypes.h"
+#include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
-#include "Core/HW/Memmap.h"
#include "Core/IPC_HLE/WII_IPC_HLE.h"
#define FS_SUCCESS (u32)0 // Success
@@ -41,53 +42,13 @@
// A struct for IOS ioctlv calls
struct SIOCtlVBuffer
{
- SIOCtlVBuffer(u32 _Address) : m_Address(_Address)
- {
- // These are the Ioctlv parameters in the IOS communication. The BufferVector
- // is a memory address offset at where the in and out buffer addresses are
- // stored.
- Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0
- NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1
- NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2
- BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3
-
- // The start of the out buffer
- u32 BufferVectorOffset = BufferVector;
-
- // Write the address and size for all in messages
- for (u32 i = 0; i < NumberInBuffer; i++)
- {
- SBuffer Buffer;
- Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
- BufferVectorOffset += 4;
- Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
- BufferVectorOffset += 4;
- InBuffer.push_back(Buffer);
- DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address,
- Buffer.m_Size);
- }
-
- // Write the address and size for all out or in-out messages
- for (u32 i = 0; i < NumberPayloadBuffer; i++)
- {
- SBuffer Buffer;
- Buffer.m_Address = Memory::Read_U32(BufferVectorOffset);
- BufferVectorOffset += 4;
- Buffer.m_Size = Memory::Read_U32(BufferVectorOffset);
- BufferVectorOffset += 4;
- PayloadBuffer.push_back(Buffer);
- DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address,
- Buffer.m_Size);
- }
- }
+ explicit SIOCtlVBuffer(u32 address);
const u32 m_Address;
-
u32 Parameter;
u32 NumberInBuffer;
u32 NumberPayloadBuffer;
u32 BufferVector;
-
struct SBuffer
{
u32 m_Address, m_Size;
@@ -99,164 +60,45 @@ struct SIOCtlVBuffer
class IWII_IPC_HLE_Device
{
public:
- IWII_IPC_HLE_Device(u32 _DeviceID, const std::string& _rName, bool _Hardware = true)
- : m_Name(_rName), m_DeviceID(_DeviceID), m_Hardware(_Hardware), m_Active(false)
- {
- }
+ IWII_IPC_HLE_Device(u32 device_id, const std::string& device_name, bool hardware = true);
- virtual ~IWII_IPC_HLE_Device() {}
+ virtual ~IWII_IPC_HLE_Device() = default;
// Release any resources which might interfere with savestating.
virtual void PrepareForState(PointerWrap::Mode mode) {}
- virtual void DoState(PointerWrap& p)
- {
- DoStateShared(p);
- p.Do(m_Active);
- }
-
+ virtual void DoState(PointerWrap& p);
void DoStateShared(PointerWrap& p);
const std::string& GetDeviceName() const { return m_Name; }
u32 GetDeviceID() const { return m_DeviceID; }
- virtual IPCCommandResult Open(u32 _CommandAddress, u32 _Mode)
- {
- (void)_Mode;
- WARN_LOG(WII_IPC_HLE, "%s does not support Open()", m_Name.c_str());
- Memory::Write_U32(FS_ENOENT, _CommandAddress + 4);
- m_Active = true;
- return GetDefaultReply();
- }
-
- virtual IPCCommandResult Close(u32 _CommandAddress, bool _bForce = false)
- {
- WARN_LOG(WII_IPC_HLE, "%s does not support Close()", m_Name.c_str());
- if (!_bForce)
- Memory::Write_U32(FS_EINVAL, _CommandAddress + 4);
- m_Active = false;
- return GetDefaultReply();
- }
-
-#define UNIMPLEMENTED_CMD(cmd) \
- WARN_LOG(WII_IPC_HLE, "%s does not support " #cmd "()", m_Name.c_str()); \
- return GetDefaultReply();
- virtual IPCCommandResult Seek(u32) { UNIMPLEMENTED_CMD(Seek) }
- virtual IPCCommandResult Read(u32) { UNIMPLEMENTED_CMD(Read) }
- virtual IPCCommandResult Write(u32) { UNIMPLEMENTED_CMD(Write) }
- virtual IPCCommandResult IOCtl(u32) { UNIMPLEMENTED_CMD(IOCtl) }
- virtual IPCCommandResult IOCtlV(u32) { UNIMPLEMENTED_CMD(IOCtlV) }
-#undef UNIMPLEMENTED_CMD
+ virtual IPCCommandResult Open(u32 command_address, u32 mode);
+ virtual IPCCommandResult Close(u32 command_address, bool force = false);
+ virtual IPCCommandResult Seek(u32 command_address);
+ virtual IPCCommandResult Read(u32 command_address);
+ virtual IPCCommandResult Write(u32 command_address);
+ virtual IPCCommandResult IOCtl(u32 command_address);
+ virtual IPCCommandResult IOCtlV(u32 command_address);
virtual u32 Update() { return 0; }
- virtual bool IsHardware() { return m_Hardware; }
- virtual bool IsOpened() { return m_Active; }
- // Returns an IPCCommandResult for a reply that takes 250 us (arbitrarily chosen value)
- static IPCCommandResult GetDefaultReply()
- {
- return {true, SystemTimers::GetTicksPerSecond() / 4000};
- }
- // Returns an IPCCommandResult with no reply. Useful for async commands that will generate a reply
- // later
- static IPCCommandResult GetNoReply() { return {false, 0}; }
+ virtual bool IsHardware() const { return m_Hardware; }
+ virtual bool IsOpened() const { return m_Active; }
+ static IPCCommandResult GetDefaultReply();
+ static IPCCommandResult GetNoReply();
+
std::string m_Name;
protected:
// STATE_TO_SAVE
u32 m_DeviceID;
bool m_Hardware;
- bool m_Active;
+ bool m_Active = false;
- // Write out the IPC struct from _CommandAddress to _NumberOfCommands numbers
+ // Write out the IPC struct from command_address to number_of_commands numbers
// of 4 byte commands.
- void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8,
- LogTypes::LOG_TYPE LogType = LogTypes::WII_IPC_HLE,
- LogTypes::LOG_LEVELS Verbosity = LogTypes::LDEBUG)
- {
- GENERIC_LOG(LogType, Verbosity, "CommandDump of %s", GetDeviceName().c_str());
- for (u32 i = 0; i < _NumberOfCommands; i++)
- {
- GENERIC_LOG(LogType, Verbosity, " Command%02i: 0x%08x", i,
- Memory::Read_U32(_CommandAddress + i * 4));
- }
- }
+ void DumpCommands(u32 command_address, size_t number_of_commands = 8,
+ LogTypes::LOG_TYPE log_type = LogTypes::WII_IPC_HLE,
+ LogTypes::LOG_LEVELS verbosity = LogTypes::LDEBUG);
- void DumpAsync(u32 BufferVector, u32 NumberInBuffer, u32 NumberOutBuffer,
- LogTypes::LOG_TYPE LogType = LogTypes::WII_IPC_HLE,
- LogTypes::LOG_LEVELS Verbosity = LogTypes::LDEBUG)
- {
- GENERIC_LOG(LogType, Verbosity, "======= DumpAsync ======");
-
- u32 BufferOffset = BufferVector;
- for (u32 i = 0; i < NumberInBuffer; i++)
- {
- u32 InBuffer = Memory::Read_U32(BufferOffset);
- BufferOffset += 4;
- u32 InBufferSize = Memory::Read_U32(BufferOffset);
- BufferOffset += 4;
-
- GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(),
- i);
-
- std::string Temp;
- for (u32 j = 0; j < InBufferSize; j++)
- {
- Temp += StringFromFormat("%02x ", Memory::Read_U8(InBuffer + j));
- }
-
- GENERIC_LOG(LogType, LogTypes::LDEBUG, " Buffer: %s", Temp.c_str());
- }
-
- for (u32 i = 0; i < NumberOutBuffer; i++)
- {
- u32 OutBuffer = Memory::Read_U32(BufferOffset);
- BufferOffset += 4;
- u32 OutBufferSize = Memory::Read_U32(BufferOffset);
- BufferOffset += 4;
-
- GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(),
- i);
- GENERIC_LOG(LogType, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):", OutBuffer,
- OutBufferSize);
-
- if (Verbosity >= LogTypes::LOG_LEVELS::LINFO)
- DumpCommands(OutBuffer, OutBufferSize, LogType, Verbosity);
- }
- }
-};
-
-class CWII_IPC_HLE_Device_stub : public IWII_IPC_HLE_Device
-{
-public:
- CWII_IPC_HLE_Device_stub(u32 DeviceID, const std::string& Name)
- : IWII_IPC_HLE_Device(DeviceID, Name)
- {
- }
-
- IPCCommandResult Open(u32 CommandAddress, u32 Mode) override
- {
- (void)Mode;
- WARN_LOG(WII_IPC_HLE, "%s faking Open()", m_Name.c_str());
- Memory::Write_U32(GetDeviceID(), CommandAddress + 4);
- m_Active = true;
- return GetDefaultReply();
- }
- IPCCommandResult Close(u32 CommandAddress, bool bForce = false) override
- {
- WARN_LOG(WII_IPC_HLE, "%s faking Close()", m_Name.c_str());
- if (!bForce)
- Memory::Write_U32(FS_SUCCESS, CommandAddress + 4);
- m_Active = false;
- return GetDefaultReply();
- }
-
- IPCCommandResult IOCtl(u32 CommandAddress) override
- {
- WARN_LOG(WII_IPC_HLE, "%s faking IOCtl()", m_Name.c_str());
- Memory::Write_U32(FS_SUCCESS, CommandAddress + 4);
- return GetDefaultReply();
- }
- IPCCommandResult IOCtlV(u32 CommandAddress) override
- {
- WARN_LOG(WII_IPC_HLE, "%s faking IOCtlV()", m_Name.c_str());
- Memory::Write_U32(FS_SUCCESS, CommandAddress + 4);
- return GetDefaultReply();
- }
+ void DumpAsync(u32 buffer_vector, u32 number_in_buffer, u32 number_io_buffer,
+ LogTypes::LOG_TYPE log_type = LogTypes::WII_IPC_HLE,
+ LogTypes::LOG_LEVELS verbosity = LogTypes::LDEBUG);
};
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
index b49c286efa..295e6b248b 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
@@ -14,6 +14,7 @@
#include "Common/StringUtil.h"
#include "Core/Core.h"
+#include "Core/HW/Memmap.h"
#include "Core/IPC_HLE/WII_IPC_HLE.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_fs.h"
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp
index 2ca7743461..a853cb6773 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_fs.cpp
@@ -12,6 +12,7 @@
#include "Common/NandPaths.h"
#include "Common/StringUtil.h"
+#include "Core/HW/Memmap.h"
#include "Core/HW/SystemTimers.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_fs.h"
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp
index 12d55dd044..3a35f07d75 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp
@@ -9,6 +9,7 @@
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/Debugger/Debugger_SymbolMap.h"
+#include "Core/HW/Memmap.h"
#include "Core/HW/WII_IPC.h"
#include "Core/IPC_HLE/WII_IPC_HLE.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_hid.h"
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h
index bef2de9a7f..5c25e2dfc2 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_net.h
@@ -7,7 +7,6 @@
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Common/Timer.h"
-
#include "Core/HW/EXI_DeviceIPL.h"
#include "Core/HW/Memmap.h"
#include "Core/IPC_HLE/NWC24Config.h"
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp
index e3f571d612..73c84c9d4b 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stm.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "Core/IPC_HLE/WII_IPC_HLE_Device_stm.h"
+#include "Core/HW/Memmap.h"
namespace Core
{
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp
new file mode 100644
index 0000000000..2782f4a745
--- /dev/null
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.cpp
@@ -0,0 +1,43 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Core/IPC_HLE/WII_IPC_HLE_Device_stub.h"
+#include "Common/Logging/Log.h"
+#include "Core/HW/Memmap.h"
+
+CWII_IPC_HLE_Device_stub::CWII_IPC_HLE_Device_stub(u32 device_id, const std::string& device_name)
+ : IWII_IPC_HLE_Device(device_id, device_name)
+{
+}
+
+IPCCommandResult CWII_IPC_HLE_Device_stub::Open(u32 command_address, u32 mode)
+{
+ WARN_LOG(WII_IPC_HLE, "%s faking Open()", m_Name.c_str());
+ Memory::Write_U32(GetDeviceID(), command_address + 4);
+ m_Active = true;
+ return GetDefaultReply();
+}
+
+IPCCommandResult CWII_IPC_HLE_Device_stub::Close(u32 command_address, bool force)
+{
+ WARN_LOG(WII_IPC_HLE, "%s faking Close()", m_Name.c_str());
+ if (!force)
+ Memory::Write_U32(FS_SUCCESS, command_address + 4);
+ m_Active = false;
+ return GetDefaultReply();
+}
+
+IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtl(u32 command_address)
+{
+ WARN_LOG(WII_IPC_HLE, "%s faking IOCtl()", m_Name.c_str());
+ Memory::Write_U32(FS_SUCCESS, command_address + 4);
+ return GetDefaultReply();
+}
+
+IPCCommandResult CWII_IPC_HLE_Device_stub::IOCtlV(u32 command_address)
+{
+ WARN_LOG(WII_IPC_HLE, "%s faking IOCtlV()", m_Name.c_str());
+ Memory::Write_U32(FS_SUCCESS, command_address + 4);
+ return GetDefaultReply();
+}
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h
new file mode 100644
index 0000000000..68449b8172
--- /dev/null
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_stub.h
@@ -0,0 +1,22 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+
+#include "Common/CommonTypes.h"
+#include "Core/IPC_HLE/WII_IPC_HLE.h"
+#include "Core/IPC_HLE/WII_IPC_HLE_Device.h"
+
+class CWII_IPC_HLE_Device_stub : public IWII_IPC_HLE_Device
+{
+public:
+ CWII_IPC_HLE_Device_stub(u32 device_id, const std::string& device_name);
+
+ IPCCommandResult Open(u32 command_address, u32 mode) override;
+ IPCCommandResult Close(u32 command_address, bool force = false) override;
+ IPCCommandResult IOCtl(u32 command_address) override;
+ IPCCommandResult IOCtlV(u32 command_address) override;
+};