summaryrefslogtreecommitdiff
path: root/plugins/ao/eng_qsf
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-26 12:49:46 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-06-26 12:49:46 +0200
commit5888e168c4185d5cd62305acf558cb6a752a17f0 (patch)
tree6f1278505129be628d9543353345b703cf4463c9 /plugins/ao/eng_qsf
parentc4c49d34513458a2cb73bff87c6fe73b10a2c350 (diff)
adding reentrant API to ao plugin WIP
Diffstat (limited to 'plugins/ao/eng_qsf')
-rw-r--r--plugins/ao/eng_qsf/eng_qsf.c159
1 files changed, 84 insertions, 75 deletions
diff --git a/plugins/ao/eng_qsf/eng_qsf.c b/plugins/ao/eng_qsf/eng_qsf.c
index e2d8f7fd..a00b955a 100644
--- a/plugins/ao/eng_qsf/eng_qsf.c
+++ b/plugins/ao/eng_qsf/eng_qsf.c
@@ -72,16 +72,17 @@ that no encryption is used.
static int32 samples_per_tick = 44100/285;
static int32 samples_to_next_tick = 44100/285;
-static corlett_t *c = NULL;
-static char qsfby[256];
-static uint32 skey1, skey2;
-static uint16 akey;
-static uint8 xkey;
-static int32 uses_kabuki = 0;
-
-static char *Z80ROM, *QSamples;
-static char RAM[0x1000], RAM2[0x1000];
-static int32 cur_bank;
+typedef struct {
+ corlett_t *c;
+ char qsfby[256];
+ uint32 skey1, skey2;
+ uint16 akey;
+ uint8 xkey;
+ int32 uses_kabuki;
+ char *Z80ROM, *QSamples;
+ char RAM[0x1000], RAM2[0x1000];
+ int32 cur_bank;
+} qsf_synth_t;
static struct QSound_interface qsintf =
{
@@ -91,7 +92,7 @@ static struct QSound_interface qsintf =
extern void cps1_decode(unsigned char *rom, int swap_key1,int swap_key2,int addr_key,int xor_key);
-static void qsf_walktags(uint8 *buffer, uint8 *end)
+static void qsf_walktags(qsf_synth_t *s, uint8 *buffer, uint8 *end)
{
uint8 *cbuf = buffer;
uint32 offset, length;
@@ -111,18 +112,18 @@ static void qsf_walktags(uint8 *buffer, uint8 *end)
switch (cbuf[0])
{
case 'Z':
- memcpy(&Z80ROM[offset], &cbuf[11], length);
+ memcpy(&s->Z80ROM[offset], &cbuf[11], length);
break;
case 'S':
- memcpy(&QSamples[offset], &cbuf[11], length);
+ memcpy(&s->QSamples[offset], &cbuf[11], length);
break;
case 'K':
- skey1 = cbuf[11]<<24 | cbuf[12]<<16 | cbuf[13]<<8 | cbuf[14];
- skey2 = cbuf[15]<<24 | cbuf[16]<<16 | cbuf[17]<<8 | cbuf[18];
- akey = cbuf[19]<<8 | cbuf[20];
- xkey = cbuf[20];
+ s->skey1 = cbuf[11]<<24 | cbuf[12]<<16 | cbuf[13]<<8 | cbuf[14];
+ s->skey2 = cbuf[15]<<24 | cbuf[16]<<16 | cbuf[17]<<8 | cbuf[18];
+ s->akey = cbuf[19]<<8 | cbuf[20];
+ s->xkey = cbuf[20];
break;
default:
@@ -140,96 +141,101 @@ static int32 qsf_irq_cb(int param)
return 0x000000ff; // RST_38
}
-int32 qsf_start(uint8 *buffer, uint32 length)
+void *qsf_start(uint8 *buffer, uint32 length)
{
+ qsf_synth_t *s = malloc (sizeof (qsf_synth_t));
+ memset (s, 0, sizeof (qsf_synth_t));
+
uint8 *file, *lib_decoded, *lib_raw_file;
uint64 file_len, lib_len, lib_raw_length;
corlett_t *lib;
z80_init();
- Z80ROM = malloc(512*1024);
- QSamples = malloc(8*1024*1024);
+ s->Z80ROM = malloc(512*1024);
+ s->QSamples = malloc(8*1024*1024);
- skey1 = skey2 = 0;
- akey = 0;
- xkey = 0;
- cur_bank = 0;
+ s->skey1 = s->skey2 = 0;
+ s->akey = 0;
+ s->xkey = 0;
+ s->cur_bank = 0;
- memset(RAM, 0, 0x1000);
- memset(RAM2, 0, 0x1000);
+ memset(s->RAM, 0, 0x1000);
+ memset(s->RAM2, 0, 0x1000);
// Decode the current QSF
- if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS)
+ if (corlett_decode(buffer, length, &file, &file_len, &s->c) != AO_SUCCESS)
{
return AO_FAIL;
}
// Get the library file
- if (c->lib[0] != 0)
+ if (s->c->lib[0] != 0)
{
uint64 tmp_length;
#if DEBUG_LOADER
- printf("Loading library: %s\n", c->lib);
+ printf("Loading library: %s\n", s->c->lib);
#endif
- if (ao_get_lib(c->lib, &lib_raw_file, &tmp_length) != AO_SUCCESS)
+ if (ao_get_lib(s->c->lib, &lib_raw_file, &tmp_length) != AO_SUCCESS)
{
- return AO_FAIL;
+ qsf_stop (s);
+ return NULL;
}
lib_raw_length = tmp_length;
if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS)
{
free(lib_raw_file);
- return AO_FAIL;
+ qsf_stop (s);
+ return NULL;
}
// Free up raw file
free(lib_raw_file);
// use the contents
- qsf_walktags(lib_decoded, lib_decoded+lib_len);
+ qsf_walktags(s, lib_decoded, lib_decoded+lib_len);
// Dispose the corlett structure for the lib - we don't use it
free(lib);
}
// now patch the file into RAM OVER the libraries
- qsf_walktags(file, file+file_len);
+ qsf_walktags(s, file, file+file_len);
free(file);
- if ((skey1 != 0) && (skey2 != 0))
+ if ((s->skey1 != 0) && (s->skey2 != 0))
{
#if DEBUG_LOADER
printf("Decoding Kabuki: skey1 %08x skey2 %08x akey %04x xkey %02x\n", skey1, skey2, akey, xkey);
#endif
- uses_kabuki = 1;
- cps1_decode((unsigned char *)Z80ROM, skey1, skey2, akey, xkey);
+ s->uses_kabuki = 1;
+ cps1_decode((unsigned char *)s->Z80ROM, s->skey1, s->skey2, s->akey, s->xkey);
}
// set qsfby tag
- strcpy(qsfby, "n/a");
- if (c)
+ strcpy(s->qsfby, "n/a");
+ if (s->c)
{
int i;
for (i = 0; i < MAX_UNKNOWN_TAGS; i++)
{
- if (!strcasecmp(c->tag_name[i], "qsfby"))
+ if (!strcasecmp(s->c->tag_name[i], "qsfby"))
{
- strcpy(qsfby, c->tag_data[i]);
+ strcpy(s->qsfby, s->c->tag_data[i]);
}
}
}
z80_reset(NULL);
z80_set_irq_callback(qsf_irq_cb);
- qsintf.sample_rom = QSamples;
+ qsintf.sample_rom = s->QSamples;
qsound_sh_start(&qsintf);
- return AO_SUCCESS;
+ return s;
}
static void timer_tick(void)
@@ -301,15 +307,17 @@ int32 qsf_gen(int16 *buffer, uint32 samples)
return AO_SUCCESS;
}
-int32 qsf_stop(void)
+int32 qsf_stop(void *handle)
{
- free(Z80ROM);
- free(QSamples);
+ qsf_synth_t *s = (qsf_synth_t *)handle;
+ free(s->Z80ROM);
+ free(s->QSamples);
+ free(s);
return AO_SUCCESS;
}
-int32 qsf_command(int32 command, int32 parameter)
+int32 qsf_command(void *handle, int32 command, int32 parameter)
{
switch (command)
{
@@ -320,51 +328,52 @@ int32 qsf_command(int32 command, int32 parameter)
return AO_FAIL;
}
-int32 qsf_fill_info(ao_display_info *info)
+int32 qsf_fill_info(void *handle, ao_display_info *info)
{
- if (c == NULL)
+ qsf_synth_t *s = handle;
+ if (s->c == NULL)
return AO_FAIL;
strcpy(info->title[1], "Name: ");
- sprintf(info->info[1], "%s", c->inf_title);
+ sprintf(info->info[1], "%s", s->c->inf_title);
strcpy(info->title[2], "Game: ");
- sprintf(info->info[2], "%s", c->inf_game);
+ sprintf(info->info[2], "%s", s->c->inf_game);
strcpy(info->title[3], "Artist: ");
- sprintf(info->info[3], "%s", c->inf_artist);
+ sprintf(info->info[3], "%s", s->c->inf_artist);
strcpy(info->title[4], "Copyright: ");
- sprintf(info->info[4], "%s", c->inf_copy);
+ sprintf(info->info[4], "%s", s->c->inf_copy);
strcpy(info->title[5], "Year: ");
- sprintf(info->info[5], "%s", c->inf_year);
+ sprintf(info->info[5], "%s", s->c->inf_year);
strcpy(info->title[6], "Length: ");
- sprintf(info->info[6], "%s", c->inf_length);
+ sprintf(info->info[6], "%s", s->c->inf_length);
strcpy(info->title[7], "Fade: ");
- sprintf(info->info[7], "%s", c->inf_fade);
+ sprintf(info->info[7], "%s", s->c->inf_fade);
strcpy(info->title[8], "Ripper: ");
- sprintf(info->info[8], "%s", qsfby);
+ sprintf(info->info[8], "%s", s->qsfby);
return AO_SUCCESS;
}
-uint8 qsf_memory_read(uint16 addr)
+uint8 qsf_memory_read(qsf_synth_t *s, uint16 addr)
{
if (addr < 0x8000)
{
- return Z80ROM[addr];
+ return s->Z80ROM[addr];
}
else if (addr < 0xc000)
{
- return Z80ROM[(addr - 0x8000) + cur_bank];
+ return s->Z80ROM[(addr - 0x8000) + s->cur_bank];
}
else if (addr <= 0xcfff)
{
- return RAM[addr - 0xc000];
+ return s->RAM[addr - 0xc000];
}
else if (addr == 0xd007)
{
@@ -372,36 +381,36 @@ uint8 qsf_memory_read(uint16 addr)
}
else if (addr >= 0xf000)
{
- return RAM2[addr-0xf000];
+ return s->RAM2[addr-0xf000];
}
}
-uint8 qsf_memory_readop(uint16 addr)
+uint8 qsf_memory_readop(qsf_synth_t *s, uint16 addr)
{
- if (!uses_kabuki)
+ if (!s->uses_kabuki)
{
- return qsf_memory_read(addr);
+ return qsf_memory_read(s, addr);
}
if (addr < 0x8000)
{
- return Z80ROM[addr + (256*1024)];
+ return s->Z80ROM[addr + (256*1024)];
}
- return qsf_memory_read(addr);
+ return qsf_memory_read(s, addr);
}
-uint8 qsf_memory_readport(uint16 addr)
+uint8 qsf_memory_readport(qsf_synth_t *s, uint16 addr)
{
- return Z80ROM[0x11];
+ return s->Z80ROM[0x11];
}
-void qsf_memory_write(uint16 addr, uint8 byte)
+void qsf_memory_write(qsf_synth_t *s, uint16 addr, uint8 byte)
{
if (addr >= 0xc000 && addr <= 0xcfff)
{
- RAM[addr-0xc000] = byte;
+ s->RAM[addr-0xc000] = byte;
return;
}
else if (addr == 0xd000)
@@ -421,17 +430,17 @@ void qsf_memory_write(uint16 addr, uint8 byte)
}
else if (addr == 0xd003)
{
- cur_bank = (0x8000 + (byte & 0xf) * 0x4000);
- if (cur_bank > (256*1024))
+ s->cur_bank = (0x8000 + (byte & 0xf) * 0x4000);
+ if (s->cur_bank > (256*1024))
{
- cur_bank = 0;
+ s->cur_bank = 0;
}
// printf("Z80 bank to %x (%x)\n", cur_bank, byte);
return;
}
else if (addr >= 0xf000)
{
- RAM2[addr-0xf000] = byte;
+ s->RAM2[addr-0xf000] = byte;
return;
}
}