From 3d89e0a94cd78c63d12c8b41d68645067cf5adf3 Mon Sep 17 00:00:00 2001
From: Matthias Ernst <info@matthias-ernst.eu>
Date: Tue, 27 Oct 2015 22:40:34 +0100
Subject: [PATCH] Added CSND stub.

---
 src/core/hle/service/csnd_snd.cpp | 57 ++++++++++++++++++++++++++++---
 src/core/hle/service/csnd_snd.h   | 13 +++++++
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp
index 6a1d961acb..ce2877f572 100644
--- a/src/core/hle/service/csnd_snd.cpp
+++ b/src/core/hle/service/csnd_snd.cpp
@@ -3,6 +3,8 @@
 // Refer to the license.txt file included.
 
 #include "core/hle/hle.h"
+#include "core/hle/kernel/mutex.h"
+#include "core/hle/kernel/shared_memory.h"
 #include "core/hle/service/csnd_snd.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -11,11 +13,11 @@
 namespace CSND_SND {
 
 const Interface::FunctionInfo FunctionTable[] = {
-    {0x00010140, nullptr,               "Initialize"},
-    {0x00020000, nullptr,               "Shutdown"},
-    {0x00030040, nullptr,               "ExecuteType0Commands"},
+    {0x00010140, Initialize,            "Initialize"},
+    {0x00020000, Shutdown,              "Shutdown"},
+    {0x00030040, ExecuteType0Commands,  "ExecuteType0Commands"},
     {0x00040080, nullptr,               "ExecuteType1Commands"},
-    {0x00050000, nullptr,               "AcquireSoundChannels"},
+    {0x00050000, AcquireSoundChannels,  "AcquireSoundChannels"},
     {0x00060000, nullptr,               "ReleaseSoundChannels"},
     {0x00070000, nullptr,               "AcquireCaptureDevice"},
     {0x00080040, nullptr,               "ReleaseCaptureDevice"},
@@ -31,4 +33,51 @@ Interface::Interface() {
     Register(FunctionTable);
 }
 
+static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr;
+static Kernel::SharedPtr<Kernel::Mutex> mutex = nullptr;
+
+void Initialize(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+
+    shared_memory = Kernel::SharedMemory::Create(cmd_buff[1],
+            Kernel::MemoryPermission::ReadWrite,
+            Kernel::MemoryPermission::ReadWrite, "CSNDSharedMem");
+
+    mutex = Kernel::Mutex::Create(false);
+
+    cmd_buff[1] = 0;
+    cmd_buff[2] = 0x4000000;
+    cmd_buff[3] = Kernel::g_handle_table.Create(mutex).MoveFrom();
+    cmd_buff[4] = Kernel::g_handle_table.Create(shared_memory).MoveFrom();
+}
+
+void ExecuteType0Commands(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+
+    if (shared_memory != nullptr) {
+        struct Type0Command* command = reinterpret_cast<struct Type0Command*>(
+                shared_memory->GetPointer(cmd_buff[1]));
+        if (command == nullptr) {
+            cmd_buff[1] = 1;
+        }else{
+            LOG_WARNING(Service, "(STUBBED) CSND_SND::ExecuteType0Commands");
+            command->finished |= 1;
+            cmd_buff[1] = 0;
+        }
+    }else{
+        cmd_buff[1] = 1;
+    }
+}
+
+void AcquireSoundChannels(Service::Interface* self) {
+    u32* cmd_buff = Kernel::GetCommandBuffer();
+    cmd_buff[1] = 0;
+    cmd_buff[2] = 0xFFFFFF00;
+}
+
+void Shutdown(Service::Interface* self) {
+    shared_memory = nullptr;
+    mutex = nullptr;
+}
+
 } // namespace
diff --git a/src/core/hle/service/csnd_snd.h b/src/core/hle/service/csnd_snd.h
index a84752473c..e861f3327d 100644
--- a/src/core/hle/service/csnd_snd.h
+++ b/src/core/hle/service/csnd_snd.h
@@ -20,4 +20,17 @@ public:
     }
 };
 
+struct Type0Command {
+    // command id and next command offset
+    u32 command_id;
+    u32 finished;
+    u32 flags;
+    u8  parameters[20];
+};
+
+void Initialize(Service::Interface* self);
+void ExecuteType0Commands(Service::Interface* self);
+void AcquireSoundChannels(Service::Interface* self);
+void Shutdown(Service::Interface* self);
+
 } // namespace