Improve error handling
Signed-off-by: Mahyar Koshkouei <deltabeard@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,15 @@
|
|||||||
|
#include <3ds.h>
|
||||||
|
|
||||||
/* Errors that can't be explained with errno */
|
/* Errors that can't be explained with errno */
|
||||||
#define NDSP_INIT_FAIL 1000
|
#define NDSP_INIT_FAIL 1000
|
||||||
#define DECODER_INIT_FAIL 1001
|
#define DECODER_INIT_FAIL 1001
|
||||||
#define FILE_NOT_SUPPORTED 1002
|
#define FILE_NOT_SUPPORTED 1002
|
||||||
|
|
||||||
|
struct errInfo_t
|
||||||
|
{
|
||||||
|
volatile int* error;
|
||||||
|
Handle* failEvent;
|
||||||
|
volatile char* errstr;
|
||||||
|
};
|
||||||
|
|
||||||
|
char* ctrmus_strerror(int err);
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "all.h"
|
#include "all.h"
|
||||||
|
#include "error.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
|
|
||||||
|
volatile bool runThreads = true;
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
PrintConsole topScreen;
|
PrintConsole topScreen;
|
||||||
@@ -26,6 +29,12 @@ int main(int argc, char **argv)
|
|||||||
int fileMax;
|
int fileMax;
|
||||||
int fileNum = 0;
|
int fileNum = 0;
|
||||||
int from = 0;
|
int from = 0;
|
||||||
|
Thread watchdogThread;
|
||||||
|
Handle* playbackFailEvent = malloc(sizeof(Handle));
|
||||||
|
struct watchdogInfo* watchdogInfoIn;
|
||||||
|
struct errInfo_t* errInfo;
|
||||||
|
static volatile int error;
|
||||||
|
static volatile char* errorstr = NULL;
|
||||||
|
|
||||||
gfxInitDefault();
|
gfxInitDefault();
|
||||||
sdmcInit();
|
sdmcInit();
|
||||||
@@ -33,6 +42,17 @@ int main(int argc, char **argv)
|
|||||||
consoleInit(GFX_BOTTOM, &bottomScreen);
|
consoleInit(GFX_BOTTOM, &bottomScreen);
|
||||||
consoleSelect(&bottomScreen);
|
consoleSelect(&bottomScreen);
|
||||||
|
|
||||||
|
svcCreateEvent(playbackFailEvent, RESET_ONESHOT);
|
||||||
|
watchdogInfoIn = calloc(1, sizeof(struct watchdogInfo));
|
||||||
|
errInfo = calloc(1, sizeof(struct errInfo_t));
|
||||||
|
errInfo->error = &error;
|
||||||
|
errInfo->failEvent = playbackFailEvent;
|
||||||
|
errInfo->errstr = errorstr;
|
||||||
|
watchdogInfoIn->screen = &topScreen;
|
||||||
|
watchdogInfoIn->errInfo = errInfo;
|
||||||
|
watchdogThread = threadCreate(playbackWatchdog, watchdogInfoIn, 4 * 1024, 0x20, -2, true);
|
||||||
|
|
||||||
|
printf("%p", playbackFailEvent);
|
||||||
chdir(DEFAULT_DIR);
|
chdir(DEFAULT_DIR);
|
||||||
chdir("MUSIC");
|
chdir("MUSIC");
|
||||||
if(listDir(from, MAX_LIST, 0) < 0)
|
if(listDir(from, MAX_LIST, 0) < 0)
|
||||||
@@ -66,6 +86,8 @@ int main(int argc, char **argv)
|
|||||||
kDown = hidKeysDown();
|
kDown = hidKeysDown();
|
||||||
kHeld = hidKeysHeld();
|
kHeld = hidKeysHeld();
|
||||||
|
|
||||||
|
consoleSelect(&bottomScreen);
|
||||||
|
|
||||||
/* Exit ctrmus */
|
/* Exit ctrmus */
|
||||||
if(kDown & KEY_START)
|
if(kDown & KEY_START)
|
||||||
break;
|
break;
|
||||||
@@ -92,25 +114,26 @@ int main(int argc, char **argv)
|
|||||||
else
|
else
|
||||||
puts("Playing");
|
puts("Playing");
|
||||||
|
|
||||||
consoleSelect(&bottomScreen);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show controls */
|
/* Show controls */
|
||||||
else if(kDown & KEY_LEFT)
|
if(kDown & KEY_LEFT)
|
||||||
{
|
{
|
||||||
consoleSelect(&topScreen);
|
consoleSelect(&topScreen);
|
||||||
showControls();
|
showControls();
|
||||||
consoleSelect(&bottomScreen);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Stop */
|
/* Stop */
|
||||||
if(kDown & KEY_X)
|
if(kDown & KEY_B)
|
||||||
{
|
{
|
||||||
stopPlayback();
|
stopPlayback();
|
||||||
changeFile(NULL);
|
changeFile(NULL, NULL, NULL);
|
||||||
continue;
|
consoleSelect(&topScreen);
|
||||||
|
puts("Stopped");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if((kDown & KEY_UP ||
|
if((kDown & KEY_UP ||
|
||||||
@@ -196,7 +219,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
consoleSelect(&topScreen);
|
consoleSelect(&topScreen);
|
||||||
changeFile(ep->d_name);
|
changeFile(ep->d_name, &error, playbackFailEvent);
|
||||||
consoleSelect(&bottomScreen);
|
consoleSelect(&bottomScreen);
|
||||||
|
|
||||||
if(closedir(dp) != 0)
|
if(closedir(dp) != 0)
|
||||||
@@ -214,8 +237,9 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
puts("Exiting...");
|
puts("Exiting...");
|
||||||
|
runThreads = false;
|
||||||
stopPlayback();
|
stopPlayback();
|
||||||
changeFile(NULL);
|
changeFile(NULL, NULL, NULL);
|
||||||
|
|
||||||
gfxExit();
|
gfxExit();
|
||||||
sdmcExit();
|
sdmcExit();
|
||||||
@@ -242,17 +266,46 @@ static void showControls(void)
|
|||||||
{
|
{
|
||||||
printf("Button mappings:\n"
|
printf("Button mappings:\n"
|
||||||
"Pause: L+R or L+Up\n"
|
"Pause: L+R or L+Up\n"
|
||||||
"Stop: X\n"
|
"Stop: L+B\n"
|
||||||
"A: Open File\n"
|
"A: Open File\n"
|
||||||
"B: Go up folder\n"
|
"B: Go up folder\n"
|
||||||
"Start: Exit\n");
|
"Start: Exit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int changeFile(const char* ep_file)
|
void playbackWatchdog(void* infoIn)
|
||||||
|
{
|
||||||
|
struct watchdogInfo* info = infoIn;
|
||||||
|
|
||||||
|
while(runThreads)
|
||||||
|
{
|
||||||
|
svcWaitSynchronization(*info->errInfo->failEvent, U64_MAX);
|
||||||
|
svcClearEvent(*info->errInfo->failEvent);
|
||||||
|
consoleSelect(info->screen);
|
||||||
|
printf("Here %s:%d err:%d\n", __func__, __LINE__, *info->errInfo->error);
|
||||||
|
#if 0
|
||||||
|
if(*info->error != 0)
|
||||||
|
{
|
||||||
|
printf("An error occurred: %s", ctrmus_strerror(*info->error));
|
||||||
|
if(info->str != NULL)
|
||||||
|
printf(" %s", info->str);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
info->str = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int changeFile(const char* ep_file, volatile int* error, Handle* failEvent)
|
||||||
{
|
{
|
||||||
s32 prio;
|
s32 prio;
|
||||||
static Thread thread = NULL;
|
static Thread thread = NULL;
|
||||||
static char* file = NULL;
|
static struct playbackInfo* info = NULL;
|
||||||
|
|
||||||
|
if(info == NULL)
|
||||||
|
info = calloc(1, sizeof(struct playbackInfo));
|
||||||
|
|
||||||
if(ep_file != NULL && getFileType(ep_file) < 0)
|
if(ep_file != NULL && getFileType(ep_file) < 0)
|
||||||
{
|
{
|
||||||
@@ -274,18 +327,19 @@ static int changeFile(const char* ep_file)
|
|||||||
thread = NULL;
|
thread = NULL;
|
||||||
|
|
||||||
/* free allocated file string */
|
/* free allocated file string */
|
||||||
delete(file);
|
delete(info->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ep_file == NULL)
|
if(ep_file == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
file = strdup(ep_file);
|
info->file = strdup(ep_file);
|
||||||
printf("Playing: %s\n", file);
|
info->errInfo->error = error;
|
||||||
|
info->errInfo->failEvent = failEvent;
|
||||||
|
printf("Playing: %s\n", info->file);
|
||||||
|
|
||||||
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
|
||||||
thread = threadCreate(playFile, file, 32 * 1024, prio - 1,
|
thread = threadCreate(playFile, info, 32 * 1024, prio - 1, -2, false);
|
||||||
-2, false);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,17 @@
|
|||||||
/* Maximum number of lines that can be displayed */
|
/* Maximum number of lines that can be displayed */
|
||||||
#define MAX_LIST 27
|
#define MAX_LIST 27
|
||||||
|
|
||||||
|
struct watchdogInfo
|
||||||
|
{
|
||||||
|
PrintConsole* screen;
|
||||||
|
struct errInfo_t* errInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
void playbackWatchdog(void* infoIn);
|
||||||
|
|
||||||
static void showControls(void);
|
static void showControls(void);
|
||||||
|
|
||||||
static int changeFile(const char* ep_file);
|
static int changeFile(const char* ep_file, volatile int* error, Handle* failEvent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get number of files in current working folder
|
* Get number of files in current working folder
|
||||||
|
|||||||
@@ -10,21 +10,25 @@
|
|||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
#include "wav.h"
|
#include "wav.h"
|
||||||
|
|
||||||
volatile bool stop = false;
|
static volatile bool stop = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should only be called from a new thread only.
|
* Should only be called from a new thread only.
|
||||||
*/
|
*/
|
||||||
void playFile(void* fileIn)
|
void playFile(void* infoIn)
|
||||||
{
|
{
|
||||||
struct decoder_fn decoder;
|
struct decoder_fn decoder;
|
||||||
|
struct playbackInfo* info = infoIn;
|
||||||
int16_t* buffer1 = NULL;
|
int16_t* buffer1 = NULL;
|
||||||
int16_t* buffer2 = NULL;
|
int16_t* buffer2 = NULL;
|
||||||
ndspWaveBuf waveBuf[2];
|
ndspWaveBuf waveBuf[2];
|
||||||
bool lastbuf = false;
|
bool lastbuf = false;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
const char* file = fileIn;
|
const char* file = info->file;
|
||||||
|
|
||||||
|
//info->str = strdup("Testing.");
|
||||||
|
errno = 12;
|
||||||
|
goto err;
|
||||||
/* Reset previous stop command */
|
/* Reset previous stop command */
|
||||||
stop = false;
|
stop = false;
|
||||||
|
|
||||||
@@ -47,20 +51,19 @@ void playFile(void* fileIn)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
threadExit(0);
|
goto err;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(R_FAILED(ndspInit()))
|
if(R_FAILED(ndspInit()))
|
||||||
{
|
{
|
||||||
errno = NDSP_INIT_FAIL;
|
errno = NDSP_INIT_FAIL;
|
||||||
goto out;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((ret = (*decoder.init)(file)) != 0)
|
if((ret = (*decoder.init)(file)) != 0)
|
||||||
{
|
{
|
||||||
errno = DECODER_INIT_FAIL;
|
errno = DECODER_INIT_FAIL;
|
||||||
goto out;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer1 = linearAlloc(decoder.buffSize * sizeof(int16_t));
|
buffer1 = linearAlloc(decoder.buffSize * sizeof(int16_t));
|
||||||
@@ -140,14 +143,19 @@ void playFile(void* fileIn)
|
|||||||
DSP_FlushDataCache(buffer2, decoder.buffSize * sizeof(int16_t));
|
DSP_FlushDataCache(buffer2, decoder.buffSize * sizeof(int16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
(*decoder.exit)();
|
(*decoder.exit)();
|
||||||
|
out:
|
||||||
ndspChnWaveBufClear(CHANNEL);
|
ndspChnWaveBufClear(CHANNEL);
|
||||||
ndspExit();
|
ndspExit();
|
||||||
linearFree(buffer1);
|
linearFree(buffer1);
|
||||||
linearFree(buffer2);
|
linearFree(buffer2);
|
||||||
threadExit(0);
|
threadExit(0);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
*info->errInfo->error = errno;
|
||||||
|
svcSignalEvent(*info->errInfo->failEvent);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,7 +8,13 @@ enum file_types
|
|||||||
FILE_TYPE_MP3
|
FILE_TYPE_MP3
|
||||||
};
|
};
|
||||||
|
|
||||||
void playFile(void* fileIn);
|
struct playbackInfo
|
||||||
|
{
|
||||||
|
char* file;
|
||||||
|
struct errInfo_t* errInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
void playFile(void* infoIn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause or play current file.
|
* Pause or play current file.
|
||||||
|
|||||||
Reference in New Issue
Block a user