diff options
Diffstat (limited to 'sdl/main.c')
-rw-r--r-- | sdl/main.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/sdl/main.c b/sdl/main.c new file mode 100644 index 0000000..43053a3 --- /dev/null +++ b/sdl/main.c @@ -0,0 +1,170 @@ +#include <SDL.h> +#include <stdbool.h> +#include "pacc/pacc.h" +#include "fmdsp/fmdsp-pacc.h" +#include "libopna/opna.h" +#include "libopna/opnatimer.h" +#include "fmdriver/fmdriver.h" +#include "common/fmplayer_file.h" +#include "common/fmplayer_common.h" + +bool loadgl(void); + +enum { + SRATE = 55467, + BUFLEN = 1024, +}; + +static struct { + struct opna opna; + struct opna_timer timer; + struct fmdriver_work work; + struct fmplayer_file *fmfile; + const char *currpath; + SDL_Window *win; + SDL_AudioDeviceID adev; + struct ppz8 ppz8; + char adpcmram[OPNA_ADPCM_RAM_SIZE]; + struct fmdsp_pacc *fp; +} g; + +static void audiocb(void *ptr, Uint8 *bufptr, int len) { + int frames = len / (sizeof(int16_t)*2); + int16_t *buf = (int16_t *)bufptr; + memset(buf, 0, len); + opna_timer_mix(&g.timer, buf, frames); +} + +static void openfile(const char *path) { + enum fmplayer_file_error error; + struct fmplayer_file *file = fmplayer_file_alloc(path, &error); + if (!file) { + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_ERROR, + "cannot open file", + fmplayer_file_strerror(error), + g.win); + return; + } + SDL_LockAudioDevice(g.adev); + fmplayer_file_free(g.fmfile); + g.fmfile = file; + fmplayer_init_work_opna(&g.work, &g.ppz8, &g.opna, &g.timer, &g.adpcmram); + fmplayer_file_load(&g.work, g.fmfile, 1); + fmdsp_pacc_set(g.fp, &g.work, &g.opna); + SDL_UnlockAudioDevice(g.adev); + SDL_PauseAudioDevice(g.adev, 0); +} + +int main(int argc, char **argv) { + if (__builtin_cpu_supports("sse2")) opna_ssg_sinc_calc_func = opna_ssg_sinc_calc_sse2; + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { + SDL_Log("Cannot initialize SDL\n"); + return 1; + } + + SDL_AudioSpec aspec = { + .freq = SRATE, + .format = AUDIO_S16SYS, + .channels = 2, + .samples = BUFLEN, + .callback = audiocb, + }; + g.adev = SDL_OpenAudioDevice(0, 0, &aspec, 0, 0); + if (!g.adev) { + SDL_Log("Cannot open audio device\n"); + SDL_Quit(); + return 0; + } + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); +#ifdef PACC_GL_ES +#ifdef PACC_GL_3 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); +#else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); +#endif +#else // PACC_GL_ES +#ifdef PACC_GL_3 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); +#else + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); +#endif +#endif // PACC_GL_ES + g.win = SDL_CreateWindow( + "FMPlayer SDL", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + 640*2, 400*2, + SDL_WINDOW_OPENGL); + if (!g.win) { + SDL_Log("Cannot create window\n"); + SDL_Quit(); + return 1; + } + + SDL_GLContext glctx = SDL_GL_CreateContext(g.win); + if (!glctx) { + SDL_Log("Cannot create OpenGL context\n"); + SDL_Quit(); + return 1; + } + + SDL_GL_SetSwapInterval(1); + + if (!loadgl()) { + SDL_Log("Cannot load OpenGL functions\n"); + SDL_Quit(); + return 1; + } + + struct pacc_vtable pacc; + struct pacc_ctx *pc = pacc_init_gl(640, 400, &pacc); + if (!pc) { + SDL_Log("Cannot initialize pacc\n"); + SDL_Quit(); + return 1; + } + + g.fp = fmdsp_pacc_init(pc, &pacc); + if (!g.fp) { + SDL_Log("Cannot initialize fmdsp\n"); + SDL_Quit(); + return 1; + } + + SDL_EventState(SDL_DROPFILE, SDL_ENABLE); + + SDL_Event e; + bool end = false; + while (!end) { + while (SDL_PollEvent(&e)) { + switch (e.type) { + case SDL_QUIT: + end = true; + break; + case SDL_DROPFILE: + openfile(e.drop.file); + SDL_free(e.drop.file); + break; + } + } + fmdsp_pacc_render(g.fp); + SDL_GL_SwapWindow(g.win); + } + + fmdsp_pacc_release(g.fp); + pacc.pacc_delete(pc); + + SDL_Quit(); + return 0; +} |