From eba59fdf4448693b73b19ba12a11bff265d4ddfc Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 9 Mar 2007 23:30:46 +0000 Subject: Add pcsound Linux driver. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 851 --- configure.in | 2 + pcsound/Makefile.am | 1 + pcsound/pcsound.c | 9 ++++ pcsound/pcsound.h | 2 + pcsound/pcsound_linux.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 pcsound/pcsound_linux.c diff --git a/configure.in b/configure.in index 7559470f..bf0cdce6 100644 --- a/configure.in +++ b/configure.in @@ -22,6 +22,8 @@ then CFLAGS="-O$OPT_LEVEL -g -Wall $orig_CFLAGS" fi +AC_CHECK_HEADERS([linux/kd.h]) + AM_PATH_SDL(1.1.3) AC_CHECK_LIB(SDL_mixer,Mix_LoadMUS,[ diff --git a/pcsound/Makefile.am b/pcsound/Makefile.am index 77957d72..b51268df 100644 --- a/pcsound/Makefile.am +++ b/pcsound/Makefile.am @@ -6,5 +6,6 @@ noinst_LIBRARIES=libpcsound.a libpcsound_a_SOURCES = \ pcsound.c pcsound.h \ pcsound_sdl.c \ + pcsound_linux.c \ pcsound_win32.c diff --git a/pcsound/pcsound.c b/pcsound/pcsound.c index 9c18eb01..1491ff61 100644 --- a/pcsound/pcsound.c +++ b/pcsound/pcsound.c @@ -27,15 +27,24 @@ #include #include +#include "config.h" #include "pcsound.h" #ifdef _WIN32 extern pcsound_driver_t pcsound_win32_driver; #endif + +#ifdef HAVE_LINUX_KD_H +extern pcsound_driver_t pcsound_linux_driver; +#endif + extern pcsound_driver_t pcsound_sdl_driver; static pcsound_driver_t *drivers[] = { +#ifdef HAVE_LINUX_KD_H + &pcsound_linux_driver, +#endif #ifdef _WIN32 &pcsound_win32_driver, #endif diff --git a/pcsound/pcsound.h b/pcsound/pcsound.h index 1adee416..12a4ffe9 100644 --- a/pcsound/pcsound.h +++ b/pcsound/pcsound.h @@ -26,6 +26,8 @@ #ifndef PCSOUND_H #define PCSOUND_H +#define PCSOUND_8253_FREQUENCY 1193280 + typedef struct pcsound_driver_s pcsound_driver_t; typedef void (*pcsound_callback_func)(int *duration, int *frequency); typedef int (*pcsound_init_func)(pcsound_callback_func callback); diff --git a/pcsound/pcsound_linux.c b/pcsound/pcsound_linux.c new file mode 100644 index 00000000..df2015d5 --- /dev/null +++ b/pcsound/pcsound_linux.c @@ -0,0 +1,126 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2007 Simon Howard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +// DESCRIPTION: +// PC speaker driver for Linux. +// +//----------------------------------------------------------------------------- + +#include "config.h" + +#ifdef HAVE_LINUX_KD_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL.h" +#include "SDL_thread.h" + +#include "pcsound.h" + +#define CONSOLE_DEVICE "/dev/console" + +static int console_handle; +static pcsound_callback_func callback; +static int sound_thread_running = 0; +static SDL_Thread *sound_thread_handle; + +static int SoundThread(void *unused) +{ + int frequency; + int duration; + int cycles; + + while (sound_thread_running) + { + callback(&duration, &frequency); + + if (frequency != 0) + { + cycles = PCSOUND_8253_FREQUENCY / frequency; + } + else + { + cycles = 0; + } + + ioctl(console_handle, KIOCSOUND, cycles); + + usleep(duration * 1000); + } + + return 0; +} + +static int PCSound_Linux_Init(pcsound_callback_func callback_func) +{ + // Try to open the console + + console_handle = open(CONSOLE_DEVICE, O_WRONLY); + + if (console_handle == -1) + { + // Don't have permissions for the console device? + + fprintf(stderr, "PCSound_Linux_Init: Failed to open '%s': %s\n", + CONSOLE_DEVICE, strerror(errno)); + return 0; + } + + if (ioctl(console_handle, KIOCSOUND, 0) < 0) + { + // KIOCSOUND not supported: non-PC linux? + + close(console_handle); + return 0; + } + + // Start a thread up to generate PC speaker output + + callback = callback_func; + sound_thread_running = 1; + + sound_thread_handle = SDL_CreateThread(SoundThread, NULL); + + return 1; +} + +static void PCSound_Linux_Shutdown(void) +{ + sound_thread_running = 0; + SDL_WaitThread(sound_thread_handle, NULL); + close(console_handle); +} + +pcsound_driver_t pcsound_linux_driver = +{ + "Linux", + PCSound_Linux_Init, + PCSound_Linux_Shutdown, +}; + +#endif /* #ifdef HAVE_LINUX_KD_H */ + -- cgit v1.2.3