aboutsummaryrefslogtreecommitdiff
path: root/tr8vm.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-05-15 12:31:46 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-05-18 12:19:16 +0100
commit06f50ed77949cee495a1d8d98fec16648a5c8ea9 (patch)
tree6a138f6692c32f66cc98b9331dbc7d57e5b35543 /tr8vm.c
parentccf1ea4a34a789da326a321589c2757e5b1d749c (diff)
downloadtr8vm-06f50ed77949cee495a1d8d98fec16648a5c8ea9.tar.gz
tr8vm-06f50ed77949cee495a1d8d98fec16648a5c8ea9.zip
Added OPL3 supportsound-opl3
Diffstat (limited to 'tr8vm.c')
-rw-r--r--tr8vm.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/tr8vm.c b/tr8vm.c
index e75ba9f..fd64c0f 100644
--- a/tr8vm.c
+++ b/tr8vm.c
@@ -27,6 +27,7 @@
#include <string.h>
#include "SDL.h"
+#include "opl3.h"
#include "vm.h"
@@ -42,6 +43,10 @@
#define WINDOW_W (TR8_W * WINDOW_SCALE)
#define WINDOW_H (TR8_H * WINDOW_SCALE)
+#define TR8_SAMPLE_RATE 44100
+#define TR8_SAMPLE_CHANNELS 1
+#define TR8_SAMPLE_SIZE 1024
+
static void resize_full_screen(SDL_Window *win, SDL_Renderer *renderer, int fullscreen, SDL_Rect *s)
{
if (!fullscreen)
@@ -157,6 +162,26 @@ static void update_ctl(SDL_Event *ev)
}
}
+SDL_mutex *amutex = NULL;
+
+opl3_chip opl;
+uint8_t snd_reg[2] = { 0 };
+
+static void audio_callback(void *userdata, uint8_t *stream, int32_t len)
+{
+ if (!SDL_LockMutex(amutex))
+ {
+ SDL_memset(stream, 0, len);
+ while (len >= 2)
+ {
+ OPL3_GenerateResampled((opl3_chip *)userdata, (int16_t *)stream);
+ stream += 2;
+ len -= 2;
+ }
+ SDL_UnlockMutex(amutex);
+ }
+}
+
uint8_t blt_set = 0;
uint8_t blt_paramc = 0;
uint8_t blt_param[6] = { 0 };
@@ -240,6 +265,34 @@ uint8_t port(uint8_t p, uint8_t v)
blt_param[blt_paramc++] = v;
return p;
+ /* sound register selector primary */
+ case 0xc0:
+ snd_reg[0] = v & 0xff;
+ return p;
+
+ /* sound data primary */
+ case 0xc1:
+ if (!SDL_LockMutex(amutex))
+ {
+ OPL3_WriteReg(&opl, snd_reg[0], v);
+ SDL_UnlockMutex(amutex);
+ }
+ return p;
+
+ /* sound register selector secondary */
+ case 0xc2:
+ snd_reg[1] = v & 0xff;
+ return p;
+
+ /* sound data secondary */
+ case 0xc3:
+ if (!SDL_LockMutex(amutex))
+ {
+ OPL3_WriteReg(&opl, 0x100 | snd_reg[1], v);
+ SDL_UnlockMutex(amutex);
+ }
+ return p;
+
/* controller 1 */
case 0xf0:
return ctl[0];
@@ -298,6 +351,33 @@ int main(int argc, char *argv[])
return 1;
}
+ /* init audio */
+ OPL3_Reset(&opl, TR8_SAMPLE_RATE);
+
+ amutex = SDL_CreateMutex();
+ if (!amutex)
+ {
+ fprintf(stderr, "Failed to create mutex: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ SDL_AudioSpec audio_spec, audio_want;
+
+ SDL_memset(&audio_want, 0, sizeof(audio_want));
+
+ audio_want.freq = TR8_SAMPLE_RATE,
+ audio_want.format = AUDIO_S16,
+ audio_want.channels = TR8_SAMPLE_CHANNELS,
+ audio_want.callback = audio_callback,
+ audio_want.userdata = (void *)&opl;
+ audio_want.samples = TR8_SAMPLE_SIZE;
+
+ SDL_AudioDeviceID audio = SDL_OpenAudioDevice(NULL, 0, &audio_want, &audio_spec, 0);
+ if (audio == 0)
+ fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError());
+ else
+ SDL_PauseAudioDevice(audio, 0);
+
SDL_Window *screen = SDL_CreateWindow(APP_NAME " " APP_VERSION,
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
WINDOW_W, WINDOW_H,
@@ -411,6 +491,12 @@ int main(int argc, char *argv[])
if (fb)
SDL_DestroyTexture(fb);
+ if (audio > 0)
+ SDL_CloseAudioDevice(audio);
+
+ if (amutex)
+ SDL_DestroyMutex(amutex);
+
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(screen);