]> Chaos Git - corbenik/ctrulib.git/commitdiff
NDSP: add mechanism to load the component from an external source
authorfincs <fincs.alt1@gmail.com>
Fri, 2 Oct 2015 21:58:02 +0000 (23:58 +0200)
committerfincs <fincs.alt1@gmail.com>
Fri, 2 Oct 2015 21:58:02 +0000 (23:58 +0200)
libctru/source/ndsp/ndsp-channel.c
libctru/source/ndsp/ndsp.c

index b07a23436a43ad4ad92e09af28117ed549f5d74d..8d533571e096d519e68fbe527eb9c4cb8192b1d2 100644 (file)
@@ -371,7 +371,7 @@ void ndspiReadChnState(void)
                                        chn->wavBufCount--;
                                        bool shouldBreak = seqId == 0 && (wb->sequence_id == st->lastSeqId || st->lastSeqId == 0);
                                        wb = wb->next;
-                                       if (shouldBreak || chn->wavBufCount == 0)
+                                       if (!wb || shouldBreak || chn->wavBufCount == 0)
                                                break;
                                }
                                if (seqId == 0)
index fc41c1ff7ca3f81753566b83b39041b861140774..959caa3c9557ee5321b4a9222bb1275d9b99d213 100644 (file)
@@ -1,5 +1,6 @@
 #include "ndsp-internal.h"
 #include <3ds/services/cfgu.h>
+#include <3ds/services/fs.h>
 
 #define NDSP_THREAD_STACK_SIZE 0x1000
 
@@ -12,6 +13,7 @@ static u32 droppedFrames, frameCount;
 static const void* componentBin;
 static u32 componentSize;
 static u16 componentProgMask, componentDataMask;
+static bool componentFree;
 
 static aptHookCookie aptCookie;
 
@@ -375,15 +377,84 @@ void ndspUseComponent(const void* binary, u32 size, u16 progMask, u16 dataMask)
        componentSize = size;
        componentProgMask = progMask;
        componentDataMask = dataMask;
+       componentFree = false;
+}
+
+bool ndspFindAndLoadComponent(void)
+{
+       extern Handle __get_handle_from_list(const char* name);
+       Result rc;
+       Handle rsrc;
+       void* bin;
+
+       componentProgMask = 0xFF;
+       componentDataMask = 0xFF;
+
+       // Try loading the DSP component from the filesystem
+       do
+       {
+               static const char dsp_filename[] = "/3ds/dspfirm.cdc";
+               FS_archive arch = { ARCH_SDMC, { PATH_EMPTY, 1, (u8*)"" }, 0, 0 };
+               FS_path path = { PATH_CHAR, sizeof(dsp_filename), (u8*)dsp_filename };
+
+               rc = FSUSER_OpenFileDirectly(&rsrc, arch, path, FS_OPEN_READ, FS_ATTRIBUTE_NONE);
+               if (rc) break;
+
+               u64 size = 0;
+               rc = FSFILE_GetSize(rsrc, &size);
+               if (rc) { FSFILE_Close(rsrc); break; }
+
+               bin = malloc(size);
+               if (!bin) { FSFILE_Close(rsrc); break; }
+
+               u32 dummy = 0;
+               rc = FSFILE_Read(rsrc, &dummy, 0, bin, size);
+               FSFILE_Close(rsrc);
+               if (rc) { free(bin); return false; }
+
+               componentBin = bin;
+               componentSize = size;
+               componentFree = true;
+               return true;
+       } while (0);
+
+       // Try loading the DSP component from hb:ndsp
+       rsrc = __get_handle_from_list("hb:ndsp");
+       if (rsrc) do
+       {
+               extern u32 fake_heap_end;
+               u32 mapAddr = (fake_heap_end+0xFFF) &~ 0xFFF;
+               rc = svcMapMemoryBlock(rsrc, mapAddr, 0x3, 0x3);
+               if (rc) break;
+
+               componentSize = *(u32*)(mapAddr + 0x104);
+               bin = malloc(componentSize);
+               if (bin)
+                       memcpy(bin, (void*)mapAddr, componentSize);
+               svcUnmapMemoryBlock(rsrc, mapAddr);
+               if (!bin) break;
+
+               componentBin = bin;
+               componentFree = true;
+               return true;
+       } while (0);
+
+       return false;
 }
 
 static int ndspRefCount = 0;
 
 Result ndspInit(void)
 {
-       Result rc;
+       Result rc = 0;
        if (ndspRefCount++) return 0;
 
+       if (!componentBin && !ndspFindAndLoadComponent())
+       {
+               rc = 1018 | (41 << 10) | (4 << 21) | (27 << 27);
+               goto _fail0;
+       }
+
        LightLock_Init(&ndspMutex);
        ndspInitMaster();
        ndspiInitChn();
@@ -418,6 +489,12 @@ _fail2:
        ndspFinalize(false);
 _fail1:
        dspExit();
+       if (componentFree)
+       {
+               free((void*)componentBin);
+               componentBin = NULL;
+       }
+_fail0:
        ndspRefCount--;
        return rc;
 }
@@ -433,6 +510,11 @@ void ndspExit(void)
        aptUnhook(&aptCookie);
        ndspFinalize(false);
        dspExit();
+       if (componentFree)
+       {
+               free((void*)componentBin);
+               componentBin = NULL;
+       }
 }
 
 u32 ndspGetDroppedFrames(void)