ref: eba59fdf4448693b73b19ba12a11bff265d4ddfc
parent: 1eeceb39814a1a0b13cab79a675e81a27477c9e8
author: Simon Howard <[email protected]>
date: Fri Mar 9 18:30:46 EST 2007
Add pcsound Linux driver. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 851
--- a/configure.in
+++ b/configure.in
@@ -22,6 +22,8 @@
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,[
--- a/pcsound/Makefile.am
+++ b/pcsound/Makefile.am
@@ -6,5 +6,6 @@
libpcsound_a_SOURCES = \
pcsound.c pcsound.h \
pcsound_sdl.c \
+ pcsound_linux.c \
pcsound_win32.c
--- a/pcsound/pcsound.c
+++ b/pcsound/pcsound.c
@@ -27,15 +27,24 @@
#include <stdlib.h>
#include <string.h>
+#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
--- 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);
--- /dev/null
+++ b/pcsound/pcsound_linux.c
@@ -1,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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <linux/kd.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#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 */
+