Highly Complete: Add exception handling for NCSF
SSEQPlayer throws exceptions, there should be exception handling to catch them and fail gracefully. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
7777e50f03
commit
d835c252fa
1 changed files with 80 additions and 49 deletions
|
@ -1062,32 +1062,44 @@ static int usf_info(void *context, const char *name, const char *value) {
|
||||||
|
|
||||||
if(state.state) free(state.state);
|
if(state.state) free(state.state);
|
||||||
} else if(type == 0x25) {
|
} else if(type == 0x25) {
|
||||||
struct ncsf_loader_state *state = new struct ncsf_loader_state;
|
struct ncsf_loader_state *state = NULL;
|
||||||
|
Player *player = NULL;
|
||||||
|
|
||||||
if(psf_load([currentUrl UTF8String], &source_callbacks, 0x25, ncsf_loader, state, 0, 0, 0) <= 0) {
|
try {
|
||||||
|
state = new struct ncsf_loader_state;
|
||||||
|
|
||||||
|
if(psf_load([currentUrl UTF8String], &source_callbacks, 0x25, ncsf_loader, state, 0, 0, 0) <= 0) {
|
||||||
|
delete state;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
player = new Player;
|
||||||
|
|
||||||
|
player->interpolation = INTERPOLATION_SINC;
|
||||||
|
|
||||||
|
PseudoFile file;
|
||||||
|
file.data = &state->sdatData;
|
||||||
|
|
||||||
|
state->sdat.reset(new SDAT(file, state->sseq));
|
||||||
|
|
||||||
|
auto *sseqToPlay = state->sdat->sseq.get();
|
||||||
|
|
||||||
|
player->sampleRate = 44100;
|
||||||
|
player->Setup(sseqToPlay);
|
||||||
|
player->Timer();
|
||||||
|
|
||||||
|
state->outputBuffer.resize(1024 * sizeof(int16_t) * 2);
|
||||||
|
|
||||||
|
emulatorCore = (uint8_t *)player;
|
||||||
|
emulatorExtra = state;
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught creating NCSF player: %s", e.what());
|
||||||
|
emulatorCore = NULL;
|
||||||
|
emulatorExtra = NULL;
|
||||||
|
delete player;
|
||||||
delete state;
|
delete state;
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player *player = new Player;
|
|
||||||
|
|
||||||
player->interpolation = INTERPOLATION_SINC;
|
|
||||||
|
|
||||||
PseudoFile file;
|
|
||||||
file.data = &state->sdatData;
|
|
||||||
|
|
||||||
state->sdat.reset(new SDAT(file, state->sseq));
|
|
||||||
|
|
||||||
auto *sseqToPlay = state->sdat->sseq.get();
|
|
||||||
|
|
||||||
player->sampleRate = 44100;
|
|
||||||
player->Setup(sseqToPlay);
|
|
||||||
player->Timer();
|
|
||||||
|
|
||||||
state->outputBuffer.resize(1024 * sizeof(int16_t) * 2);
|
|
||||||
|
|
||||||
emulatorCore = (uint8_t *)player;
|
|
||||||
emulatorExtra = state;
|
|
||||||
} else if(type == 0x41) {
|
} else if(type == 0x41) {
|
||||||
struct qsf_loader_state *state = (struct qsf_loader_state *)calloc(1, sizeof(*state));
|
struct qsf_loader_state *state = (struct qsf_loader_state *)calloc(1, sizeof(*state));
|
||||||
|
|
||||||
|
@ -1281,18 +1293,23 @@ static int usf_info(void *context, const char *name, const char *value) {
|
||||||
NDS_state *state = (NDS_state *)emulatorCore;
|
NDS_state *state = (NDS_state *)emulatorCore;
|
||||||
state_render(state, (s16 *)buf, frames);
|
state_render(state, (s16 *)buf, frames);
|
||||||
} else if(type == 0x25) {
|
} else if(type == 0x25) {
|
||||||
Player *player = (Player *)emulatorCore;
|
try {
|
||||||
ncsf_loader_state *state = (ncsf_loader_state *)emulatorExtra;
|
Player *player = (Player *)emulatorCore;
|
||||||
std::vector<uint8_t> &buffer = state->outputBuffer;
|
ncsf_loader_state *state = (ncsf_loader_state *)emulatorExtra;
|
||||||
unsigned long frames_to_do = frames;
|
std::vector<uint8_t> &buffer = state->outputBuffer;
|
||||||
while(frames_to_do) {
|
unsigned long frames_to_do = frames;
|
||||||
unsigned frames_this_run = 1024;
|
while(frames_to_do) {
|
||||||
if(frames_this_run > frames_to_do)
|
unsigned frames_this_run = 1024;
|
||||||
frames_this_run = (unsigned int)frames_to_do;
|
if(frames_this_run > frames_to_do)
|
||||||
player->GenerateSamples(buffer, 0, frames_this_run);
|
frames_this_run = (unsigned int)frames_to_do;
|
||||||
memcpy(buf, &buffer[0], frames_this_run * sizeof(int16_t) * 2);
|
player->GenerateSamples(buffer, 0, frames_this_run);
|
||||||
buf = ((uint8_t *)buf) + frames_this_run * sizeof(int16_t) * 2;
|
memcpy(buf, &buffer[0], frames_this_run * sizeof(int16_t) * 2);
|
||||||
frames_to_do -= frames_this_run;
|
buf = ((uint8_t *)buf) + frames_this_run * sizeof(int16_t) * 2;
|
||||||
|
frames_to_do -= frames_this_run;
|
||||||
|
}
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught while playing NCSF: %s", e.what());
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
} else if(type == 0x41) {
|
} else if(type == 0x41) {
|
||||||
uint32_t howmany = frames;
|
uint32_t howmany = frames;
|
||||||
|
@ -1367,8 +1384,12 @@ static int usf_info(void *context, const char *name, const char *value) {
|
||||||
state_deinit(state);
|
state_deinit(state);
|
||||||
free(state);
|
free(state);
|
||||||
} else if(type == 0x25) {
|
} else if(type == 0x25) {
|
||||||
Player *player = (Player *)emulatorCore;
|
try {
|
||||||
delete player;
|
Player *player = (Player *)emulatorCore;
|
||||||
|
delete player;
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught deleting NCSF player: %s", e.what());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
free(emulatorCore);
|
free(emulatorCore);
|
||||||
}
|
}
|
||||||
|
@ -1387,8 +1408,12 @@ static int usf_info(void *context, const char *name, const char *value) {
|
||||||
free(emulatorExtra);
|
free(emulatorExtra);
|
||||||
emulatorExtra = nil;
|
emulatorExtra = nil;
|
||||||
} else if(type == 0x25 && emulatorExtra) {
|
} else if(type == 0x25 && emulatorExtra) {
|
||||||
struct ncsf_loader_state *state = (struct ncsf_loader_state *)emulatorExtra;
|
try {
|
||||||
delete state;
|
struct ncsf_loader_state *state = (struct ncsf_loader_state *)emulatorExtra;
|
||||||
|
delete state;
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught deleting NCSF state: %s", e.what());
|
||||||
|
}
|
||||||
emulatorExtra = nil;
|
emulatorExtra = nil;
|
||||||
} else if(type == 0x41 && emulatorExtra) {
|
} else if(type == 0x41 && emulatorExtra) {
|
||||||
struct qsf_loader_state *state = (struct qsf_loader_state *)emulatorExtra;
|
struct qsf_loader_state *state = (struct qsf_loader_state *)emulatorExtra;
|
||||||
|
@ -1497,22 +1522,28 @@ static int usf_info(void *context, const char *name, const char *value) {
|
||||||
|
|
||||||
framesRead = frame;
|
framesRead = frame;
|
||||||
} else if(type == 0x25) {
|
} else if(type == 0x25) {
|
||||||
Player *player = (Player *)emulatorCore;
|
try {
|
||||||
ncsf_loader_state *state = (ncsf_loader_state *)emulatorExtra;
|
Player *player = (Player *)emulatorCore;
|
||||||
std::vector<uint8_t> &buffer = state->outputBuffer;
|
ncsf_loader_state *state = (ncsf_loader_state *)emulatorExtra;
|
||||||
|
std::vector<uint8_t> &buffer = state->outputBuffer;
|
||||||
|
|
||||||
long frames_to_run = frame - framesRead;
|
long frames_to_run = frame - framesRead;
|
||||||
|
|
||||||
while(frames_to_run) {
|
while(frames_to_run) {
|
||||||
int frames_to_render = 1024;
|
int frames_to_render = 1024;
|
||||||
if(frames_to_render > frames_to_run) frames_to_render = (int)frames_to_run;
|
if(frames_to_render > frames_to_run) frames_to_render = (int)frames_to_run;
|
||||||
|
|
||||||
player->GenerateSamples(buffer, 0, frames_to_render);
|
player->GenerateSamples(buffer, 0, frames_to_render);
|
||||||
|
|
||||||
frames_to_run -= frames_to_render;
|
frames_to_run -= frames_to_render;
|
||||||
|
}
|
||||||
|
|
||||||
|
framesRead = frame;
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ALog(@"Exception caught while seeking in NCSF: %s", e.what());
|
||||||
|
framesRead = 0;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
framesRead = frame;
|
|
||||||
} else if(type == 0x41) {
|
} else if(type == 0x41) {
|
||||||
do {
|
do {
|
||||||
uint32_t howmany = (uint32_t)(frame - framesRead);
|
uint32_t howmany = (uint32_t)(frame - framesRead);
|
||||||
|
|
Loading…
Reference in a new issue