Remove legacy X11/DGA/FBDEV/ESD etc support

This commit is contained in:
Seg 2020-12-12 13:32:05 -08:00
parent 7e845b6ea2
commit 256f93b221
9 changed files with 4 additions and 4579 deletions

View File

@ -1,110 +0,0 @@
README file for networking under IRIX
by Brian J. Johnson 7/23/2002
version 1.0
==================================================
BasiliskII does not currently support networking natively on IRIX.
That is, the emulated Ethernet card does not do anything. There's no
reason one couldn't use raw domain sockets and the snoop(7p) facility
to do networking, but so far no one has written the required glue
code.
However, it is possible to do TCP/IP networking with BasiliskII on
IRIX via PPP, by connecting an emulated serial port to the IRIX PPP
daemon. Here are the steps to set it up:
Set up PPP on IRIX
------------------
You need root privileges to do this.
First, make sure you have eoe.sw.ppp and eoe.sw.uucp installed:
IRIS# versions eoe.sw.ppp eoe.sw.uucp
I = Installed, R = Removed
Name Date Description
I eoe 07/22/2002 IRIX Execution Environment, 6.5.17m
I eoe.sw 07/22/2002 IRIX Execution Environment Software
I eoe.sw.ppp 07/22/2002 Point-to-Point Protocol Software
I eoe.sw.uucp 07/22/2002 UUCP Utilities
If they aren't installed, install them from your distribution CDs.
Next, pick IP addresses for the IRIX and MacOS sides of the PPP
connection. You may want to ask your local network administrator
about this, but any two unused addresses on your local subnet should
work.
Edit /etc/ppp.conf and add these three lines:
_NET_INCOMING
remotehost=<MacOS PPP IP address>
localhost=<IRIX PPP IP address>
(Replace the angle brackets and the text in them with the appropriate
IP addresses.)
Next, make a script to set up the environment properly when invoking
pppd from BasiliskII. You can name this whatever you want; I chose
/usr/etc/ppp-b2:
IRIS# whoami
root
IRIS# cat < /usr/etc/ppp-b2
#!/bin/sh
export USER=_NET_INCOMING
exec /usr/etc/ppp "$@"
IRIS# chmod 4775 /usr/etc/ppp-b2
Rewrite this in perl or python or C or whatever if you don't like
setuid shell scripts. The alternative is to run BasiliskII as root:
pppd _must_ be run as root.
Configure BasiliskII to start the PPP daemon
--------------------------------------------
Start up BasiliskII, and in the serial devices tab, enter:
|exec /usr/etc/ppp-b2
Supply the name you used for the script you created. Be sure to
include the leading pipe symbol ("|").
The "exec" causes your PPP startup script to replace the shell
BasiliskII runs to interpret the command. It's not strictly
necessary, but cuts down on the number of extra processes hanging
about.
Install a PPP client on MacOS
-----------------------------
The details of this step will vary depending on your PPP client
software. Set it up for a "direct" connection, with no modem chatting
or login scripting. For instance, with FreePPP I set the "Connect:"
item on the "Edit..." screen under the "Accounts" tab to "Directly".
Be sure to select the correct serial port. The serial port speed
shouldn't matter (BasiliskII ignores it), but I set it to 115200 bps.
Next, configure MacOS's TCP/IP stack. If you're using Open Transport,
Open the TCP/IP control panel and select "Using PPP Server" under the
"Configure" item. Copy IRIX's DNS client info. from /etc/resolv.conf
to the control panel: the addresses from the "nameserver" lines go in
the "Name server addr.:" box, and the domains from the "search" lines
go in the "Search domains:" box. The steps should be similar for
MacTCP.
Now fire up PPP. Your PPP client should establish communication with
the IRIX PPP daemon, and you're off and running.
Disclaimer
----------
I haven't tried this procedure from scratch on a freshly installed
system, so I might have missed a step somewhere. But it should get
you close....

View File

@ -1,680 +0,0 @@
/*
* audio_irix.cpp - Audio support, SGI Irix implementation
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* 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
*/
#include "sysdeps.h"
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <dmedia/audio.h>
#include <dmedia/dmedia.h>
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "audio.h"
#include "audio_defs.h"
#define DEBUG 0
#include "debug.h"
// The currently selected audio parameters (indices in audio_sample_rates[]
// etc. vectors)
static int audio_sample_rate_index = 0;
static int audio_sample_size_index = 0;
static int audio_channel_count_index = 0;
// Global variables
static int audio_fd = -1; // fd from audio library
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read
static bool sem_inited = false; // Flag: audio_irq_done_sem initialized
static int sound_buffer_size; // Size of sound buffer in bytes
static int sound_buffer_fill_point; // Fill buffer when this many frames are empty
static uint8 silence_byte = 0; // Byte value to use to fill sound buffers with silence
static pthread_t stream_thread; // Audio streaming thread
static pthread_attr_t stream_thread_attr; // Streaming thread attributes
static bool stream_thread_active = false; // Flag: streaming thread installed
static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread
static bool current_main_mute = false; // Flag: output muted
static bool current_speaker_mute = false; // Flag: speaker muted
static uint32 current_main_volume = 0; // Output volume
static uint32 current_speaker_volume = 0; // Speaker volume
// IRIX libaudio control structures
static ALconfig config;
static ALport port;
// Prototypes
static void *stream_func(void *arg);
static uint32 read_volume(void);
static bool read_mute(void);
static void set_mute(bool mute);
/*
* Initialization
*/
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index];
AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index];
AudioStatus.channels = audio_channel_counts[audio_channel_count_index];
}
bool open_audio(void)
{
ALpv pv[2];
printf("Using libaudio audio output\n");
// Get supported sample formats
if (audio_sample_sizes.empty()) {
// All sample sizes are supported
audio_sample_sizes.push_back(8);
audio_sample_sizes.push_back(16);
// Assume at least two channels are supported. Some IRIX boxes
// can do 4 or more... MacOS only handles up to 2.
audio_channel_counts.push_back(1);
audio_channel_counts.push_back(2);
if (audio_sample_sizes.empty() || audio_channel_counts.empty()) {
WarningAlert(GetString(STR_AUDIO_FORMAT_WARN));
alClosePort(port);
audio_fd = -1;
return false;
}
audio_sample_rates.push_back( 8000 << 16);
audio_sample_rates.push_back(11025 << 16);
audio_sample_rates.push_back(22050 << 16);
audio_sample_rates.push_back(44100 << 16);
// Default to highest supported values
audio_sample_rate_index = audio_sample_rates.size() - 1;
audio_sample_size_index = audio_sample_sizes.size() - 1;
audio_channel_count_index = audio_channel_counts.size() - 1;
}
// Set the sample format
D(bug("Size %d, channels %d, rate %d\n",
audio_sample_sizes[audio_sample_size_index],
audio_channel_counts[audio_channel_count_index],
audio_sample_rates[audio_sample_rate_index] >> 16));
config = alNewConfig();
alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP);
if (audio_sample_sizes[audio_sample_size_index] == 8) {
alSetWidth(config, AL_SAMPLE_8);
}
else {
alSetWidth(config, AL_SAMPLE_16);
}
alSetChannels(config, audio_channel_counts[audio_channel_count_index]);
alSetDevice(config, AL_DEFAULT_OUTPUT); // Allow selecting via prefs?
// Try to open the audio library
port = alOpenPort("BasiliskII", "w", config);
if (port == NULL) {
fprintf(stderr, "ERROR: Cannot open audio port: %s\n",
alGetErrorString(oserror()));
WarningAlert(GetString(STR_NO_AUDIO_WARN));
return false;
}
// Set the sample rate
pv[0].param = AL_RATE;
pv[0].value.ll = alDoubleToFixed(audio_sample_rates[audio_sample_rate_index] >> 16);
pv[1].param = AL_MASTER_CLOCK;
pv[1].value.i = AL_CRYSTAL_MCLK_TYPE;
if (alSetParams(AL_DEFAULT_OUTPUT, pv, 2) < 0) {
fprintf(stderr, "ERROR: libaudio setparams failed: %s\n",
alGetErrorString(oserror()));
alClosePort(port);
return false;
}
// Compute sound buffer size and libaudio refill point
config = alGetConfig(port);
audio_frames_per_block = alGetQueueSize(config);
if (audio_frames_per_block < 0) {
fprintf(stderr, "ERROR: couldn't get queue size: %s\n",
alGetErrorString(oserror()));
alClosePort(port);
return false;
}
D(bug("alGetQueueSize %d, width %d, channels %d\n",
audio_frames_per_block,
alGetWidth(config),
alGetChannels(config)));
// Put a limit on the Mac sound buffer size, to decrease delay
#define AUDIO_BUFFER_MSEC 50 // milliseconds of sound to buffer
int target_frames_per_block =
(audio_sample_rates[audio_sample_rate_index] >> 16) *
AUDIO_BUFFER_MSEC / 1000;
if (audio_frames_per_block > target_frames_per_block)
audio_frames_per_block = target_frames_per_block;
D(bug("frames per block %d\n", audio_frames_per_block));
alZeroFrames(port, audio_frames_per_block); // so we don't underflow
// Try to keep the buffer pretty full
sound_buffer_fill_point = alGetQueueSize(config) -
2 * audio_frames_per_block;
if (sound_buffer_fill_point < 0)
sound_buffer_fill_point = alGetQueueSize(config) / 3;
D(bug("fill point %d\n", sound_buffer_fill_point));
sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) *
audio_channel_counts[audio_channel_count_index] *
audio_frames_per_block;
set_audio_status_format();
// Get a file descriptor we can select() on
audio_fd = alGetFD(port);
if (audio_fd < 0) {
fprintf(stderr, "ERROR: couldn't get libaudio file descriptor: %s\n",
alGetErrorString(oserror()));
alClosePort(port);
return false;
}
// Initialize volume, mute settings
current_main_volume = current_speaker_volume = read_volume();
current_main_mute = current_speaker_mute = read_mute();
// Start streaming thread
Set_pthread_attr(&stream_thread_attr, 0);
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0);
// Everything went fine
audio_open = true;
return true;
}
void AudioInit(void)
{
// Init audio status (reasonable defaults) and feature flags
AudioStatus.sample_rate = 44100 << 16;
AudioStatus.sample_size = 16;
AudioStatus.channels = 2;
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
// Init semaphore
if (sem_init(&audio_irq_done_sem, 0, 0) < 0)
return;
sem_inited = true;
// Open and initialize audio device
open_audio();
}
/*
* Deinitialization
*/
static void close_audio(void)
{
// Stop stream and delete semaphore
if (stream_thread_active) {
stream_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
pthread_cancel(stream_thread);
#endif
pthread_join(stream_thread, NULL);
stream_thread_active = false;
stream_thread_cancel = false;
}
// Close audio library
alClosePort(port);
audio_open = false;
}
void AudioExit(void)
{
// Close audio device
close_audio();
// Delete semaphore
if (sem_inited) {
sem_destroy(&audio_irq_done_sem);
sem_inited = false;
}
}
/*
* First source added, start audio stream
*/
void audio_enter_stream()
{
// Streaming thread is always running to avoid clicking noises
}
/*
* Last source removed, stop audio stream
*/
void audio_exit_stream()
{
// Streaming thread is always running to avoid clicking noises
}
/*
* Streaming function
*/
static void *stream_func(void *arg)
{
int32 *last_buffer = new int32[sound_buffer_size / 4];
fd_set audio_fdset;
int numfds, was_error;
numfds = audio_fd + 1;
FD_ZERO(&audio_fdset);
while (!stream_thread_cancel) {
if (AudioStatus.num_sources) {
// Trigger audio interrupt to get new buffer
D(bug("stream: triggering irq\n"));
SetInterruptFlag(INTFLAG_AUDIO);
TriggerInterrupt();
D(bug("stream: waiting for ack\n"));
sem_wait(&audio_irq_done_sem);
D(bug("stream: ack received\n"));
// Get size of audio data
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
if (!current_main_mute &&
!current_speaker_mute &&
apple_stream_info) {
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
D(bug("stream: work_size %d\n", work_size));
if (work_size > sound_buffer_size)
work_size = sound_buffer_size;
if (work_size == 0)
goto silence;
// Send data to audio library. Convert 8-bit data
// unsigned->signed
// It works fine for 8-bit mono, but not stereo.
if (AudioStatus.sample_size == 8) {
uint32 *p = (uint32 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer));
uint32 *q = (uint32 *)last_buffer;
int r = work_size >> 2;
// XXX not quite right....
while (r--)
*q++ = *p++ ^ 0x80808080;
if (work_size != sound_buffer_size)
memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size);
alWriteFrames(port, last_buffer, audio_frames_per_block);
}
else if (work_size == sound_buffer_size)
alWriteFrames(port, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), audio_frames_per_block);
else {
// Last buffer
Mac2Host_memcpy(last_buffer, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size);
alWriteFrames(port, last_buffer, audio_frames_per_block);
}
D(bug("stream: data written\n"));
} else
goto silence;
} else {
// Audio not active, play silence
silence: // D(bug("stream: silence\n"));
alZeroFrames(port, audio_frames_per_block);
}
// Wait for fill point to be reached (may be immediate)
if (alSetFillPoint(port, sound_buffer_fill_point) < 0) {
fprintf(stderr, "ERROR: alSetFillPoint failed: %s\n",
alGetErrorString(oserror()));
// Should stop the audio here....
}
do {
errno = 0;
FD_SET(audio_fd, &audio_fdset);
was_error = select(numfds, NULL, &audio_fdset, NULL, NULL);
} while(was_error < 0 && (errno == EINTR));
if (was_error < 0) {
fprintf(stderr, "ERROR: select returned %d, errno %d\n",
was_error, errno);
// Should stop audio here....
}
}
delete[] last_buffer;
return NULL;
}
/*
* Read or set the current output volume using the audio library
*/
static uint32 read_volume(void)
{
ALpv x[2];
ALfixed gain[8];
double maxgain, mingain;
ALparamInfo pi;
uint32 ret = 0x01000100; // default, maximum value
int dev = alGetDevice(config);
// Fetch the maximum and minimum gain settings
alGetParamInfo(dev, AL_GAIN, &pi);
maxgain = alFixedToDouble(pi.max.ll);
mingain = alFixedToDouble(pi.min.ll);
// printf("maxgain = %lf dB, mingain = %lf dB\n", maxgain, mingain);
// Get the current gain values
x[0].param = AL_GAIN;
x[0].value.ptr = gain;
x[0].sizeIn = sizeof(gain) / sizeof(gain[0]);
x[1].param = AL_CHANNELS;
if (alGetParams(dev, x, 2) < 0) {
printf("alGetParams failed: %s\n", alGetErrorString(oserror()));
}
else {
if (x[0].sizeOut < 0) {
printf("AL_GAIN was an unrecognized parameter\n");
}
else {
double v;
uint32 left, right;
// Left
v = alFixedToDouble(gain[0]);
if (v < mingain)
v = mingain; // handle gain == -inf
v = (v - mingain) / (maxgain - mingain); // scale to 0..1
left = (uint32)(v * (double)256); // convert to 8.8 fixed point
// Right
if (x[0].sizeOut <= 1) { // handle a mono interface
right = left;
}
else {
v = alFixedToDouble(gain[1]);
if (v < mingain)
v = mingain; // handle gain == -inf
v = (v - mingain) / (maxgain - mingain); // scale to 0..1
right = (uint32)(v * (double)256); // convert to 8.8 fixed point
}
ret = (left << 16) | right;
}
}
return ret;
}
static void set_volume(uint32 vol)
{
ALpv x[1];
ALfixed gain[2]; // left and right
double maxgain, mingain;
ALparamInfo pi;
int dev = alGetDevice(config);
// Fetch the maximum and minimum gain settings
alGetParamInfo(dev, AL_GAIN, &pi);
maxgain = alFixedToDouble(pi.max.ll);
mingain = alFixedToDouble(pi.min.ll);
// Set the new gain values
x[0].param = AL_GAIN;
x[0].value.ptr = gain;
x[0].sizeIn = sizeof(gain) / sizeof(gain[0]);
uint32 left = vol >> 16;
uint32 right = vol & 0xffff;
double lv, rv;
if (left == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) {
lv = AL_NEG_INFINITY;
}
else {
lv = ((double)left / 256) * (maxgain - mingain) + mingain;
}
if (right == 0 && pi.specialVals & AL_NEG_INFINITY_BIT) {
rv = AL_NEG_INFINITY;
}
else {
rv = ((double)right / 256) * (maxgain - mingain) + mingain;
}
D(bug("set_volume: left=%lf dB, right=%lf dB\n", lv, rv));
gain[0] = alDoubleToFixed(lv);
gain[1] = alDoubleToFixed(rv);
if (alSetParams(dev, x, 1) < 0) {
printf("alSetParams failed: %s\n", alGetErrorString(oserror()));
}
}
/*
* Read or set the mute setting using the audio library
*/
static bool read_mute(void)
{
bool ret;
int dev = alGetDevice(config);
ALpv x;
x.param = AL_MUTE;
if (alGetParams(dev, &x, 1) < 0) {
printf("alSetParams failed: %s\n", alGetErrorString(oserror()));
return current_main_mute; // Or just return false?
}
ret = x.value.i;
D(bug("read_mute: mute=%d\n", ret));
return ret;
}
static void set_mute(bool mute)
{
D(bug("set_mute: mute=%ld\n", mute));
int dev = alGetDevice(config);
ALpv x;
x.param = AL_MUTE;
x.value.i = mute;
if (alSetParams(dev, &x, 1) < 0) {
printf("alSetParams failed: %s\n", alGetErrorString(oserror()));
}
}
/*
* MacOS audio interrupt, read next data block
*/
void AudioInterrupt(void)
{
D(bug("AudioInterrupt\n"));
// Get data from apple mixer
if (AudioStatus.mixer) {
M68kRegisters r;
r.a[0] = audio_data + adatStreamInfo;
r.a[1] = AudioStatus.mixer;
Execute68k(audio_data + adatGetSourceData, &r);
D(bug(" GetSourceData() returns %08lx\n", r.d[0]));
} else
WriteMacInt32(audio_data + adatStreamInfo, 0);
// Signal stream function
sem_post(&audio_irq_done_sem);
D(bug("AudioInterrupt done\n"));
}
/*
* Set sampling parameters
* "index" is an index into the audio_sample_rates[] etc. vectors
* It is guaranteed that AudioStatus.num_sources == 0
*/
bool audio_set_sample_rate(int index)
{
close_audio();
audio_sample_rate_index = index;
return open_audio();
}
bool audio_set_sample_size(int index)
{
close_audio();
audio_sample_size_index = index;
return open_audio();
}
bool audio_set_channels(int index)
{
close_audio();
audio_channel_count_index = index;
return open_audio();
}
/*
* Get/set volume controls (volume values received/returned have the left channel
* volume in the upper 16 bits and the right channel volume in the lower 16 bits;
* both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume"))
*/
bool audio_get_main_mute(void)
{
D(bug("audio_get_main_mute: mute=%ld\n", current_main_mute));
return current_main_mute;
}
uint32 audio_get_main_volume(void)
{
uint32 ret = current_main_volume;
D(bug("audio_get_main_volume: vol=0x%x\n", ret));
return ret;
}
bool audio_get_speaker_mute(void)
{
D(bug("audio_get_speaker_mute: mute=%ld\n", current_speaker_mute));
return current_speaker_mute;
}
uint32 audio_get_speaker_volume(void)
{
uint32 ret = current_speaker_volume;
D(bug("audio_get_speaker_volume: vol=0x%x\n", ret));
return ret;
}
void audio_set_main_mute(bool mute)
{
D(bug("audio_set_main_mute: mute=%ld\n", mute));
if (mute != current_main_mute) {
current_main_mute = mute;
}
set_mute(current_main_mute);
}
void audio_set_main_volume(uint32 vol)
{
D(bug("audio_set_main_volume: vol=%x\n", vol));
current_main_volume = vol;
set_volume(vol);
}
void audio_set_speaker_mute(bool mute)
{
D(bug("audio_set_speaker_mute: mute=%ld\n", mute));
if (mute != current_speaker_mute) {
current_speaker_mute = mute;
}
set_mute(current_speaker_mute);
}
void audio_set_speaker_volume(uint32 vol)
{
D(bug("audio_set_speaker_volume: vol=%x\n", vol));
current_speaker_volume = vol;
set_volume(vol);
}

View File

@ -1,44 +0,0 @@
/*
* Irix/unaligned.c - Optimized unaligned access for Irix
*
* Basilisk II (C) 1997-2005 Christian Bauer
*
* 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
*/
#ifdef sgi
#include "sysdeps.h"
/* Tell the compiler to pack data on 1-byte boundaries
* (i.e. arbitrary alignment). Requires SGI MIPSPro compilers. */
#pragma pack(1)
typedef struct _ual32 {
uae_u32 v;
} ual32_t;
typedef struct _ual16 {
uae_u16 v;
} ual16_t;
#pragma pack(0)
/* The compiler is smart enough to inline these when you build with "-ipa" */
uae_u32 do_get_mem_long(uae_u32 *a) {return ((ual32_t *)a)->v;}
uae_u32 do_get_mem_word(uae_u16 *a) {return ((ual16_t *)a)->v;}
void do_put_mem_long(uae_u32 *a, uae_u32 v) {((ual32_t *)a)->v = v;}
void do_put_mem_word(uae_u16 *a, uae_u32 v) {((ual16_t *)a)->v = v;}
#endif /* sgi */

View File

@ -1,320 +0,0 @@
/*
* audio_solaris.cpp - Audio support, Solaris implementation
*
* Adapted from Frodo's Solaris sound routines by Marc Chabanas
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* 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
*/
#include "sysdeps.h"
#include <sys/ioctl.h>
#include <sys/audioio.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "audio.h"
#include "audio_defs.h"
#define DEBUG 0
#include "debug.h"
// Global variables
static int fd = -1; // fd of /dev/audio
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read
static pthread_t stream_thread; // Audio streaming thread
static pthread_attr_t stream_thread_attr; // Streaming thread attributes
static bool stream_thread_active = false;
static int sound_buffer_size; // Size of sound buffer in bytes
// Prototypes
static void *stream_func(void *arg);
/*
* Initialization
*/
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
AudioStatus.sample_rate = audio_sample_rates[0];
AudioStatus.sample_size = audio_sample_sizes[0];
AudioStatus.channels = audio_channel_counts[0];
}
void AudioInit(void)
{
char str[256];
// Init audio status and feature flags
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(2);
set_audio_status_format();
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
// Init semaphore
if (sem_init(&audio_irq_done_sem, 0, 0) < 0)
return;
// Open /dev/audio
fd = open("/dev/audio", O_WRONLY | O_NDELAY);
if (fd < 0) {
sprintf(str, GetString(STR_NO_AUDIO_DEV_WARN), "/dev/audio", strerror(errno));
WarningAlert(str);
sem_destroy(&audio_irq_done_sem);
return;
}
// Set audio parameters
struct audio_info info;
AUDIO_INITINFO(&info);
info.play.sample_rate = AudioStatus.sample_rate >> 16;
info.play.channels = AudioStatus.channels;
info.play.precision = AudioStatus.sample_size;
info.play.encoding = AUDIO_ENCODING_LINEAR;
info.play.port = AUDIO_SPEAKER;
if (ioctl(fd, AUDIO_SETINFO, &info)) {
WarningAlert(GetString(STR_AUDIO_FORMAT_WARN));
close(fd);
fd = -1;
sem_destroy(&audio_irq_done_sem);
return;
}
// 2048 frames per buffer
audio_frames_per_block = 2048;
sound_buffer_size = (AudioStatus.sample_size>>3) * AudioStatus.channels * audio_frames_per_block;
// Start audio thread
Set_pthread_attr(&stream_thread_attr, 0);
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0);
// Everything OK
audio_open = true;
}
/*
* Deinitialization
*/
void AudioExit(void)
{
// Stop audio thread
if (stream_thread_active) {
pthread_cancel(stream_thread);
pthread_join(stream_thread, NULL);
sem_destroy(&audio_irq_done_sem);
stream_thread_active = false;
}
// Close /dev/audio
if (fd > 0) {
ioctl(fd, AUDIO_DRAIN);
close(fd);
}
}
/*
* First source added, start audio stream
*/
void audio_enter_stream()
{
}
/*
* Last source removed, stop audio stream
*/
void audio_exit_stream()
{
}
/*
* Streaming function
*/
static uint32 apple_stream_info; // Mac address of SoundComponentData struct describing next buffer
static void *stream_func(void *arg)
{
int16 *silent_buffer = new int16[sound_buffer_size / 2];
int16 *last_buffer = new int16[sound_buffer_size / 2];
memset(silent_buffer, 0, sound_buffer_size);
uint_t sent = 0, delta;
struct audio_info status;
for (;;) {
if (AudioStatus.num_sources) {
// Trigger audio interrupt to get new buffer
D(bug("stream: triggering irq\n"));
SetInterruptFlag(INTFLAG_AUDIO);
TriggerInterrupt();
D(bug("stream: waiting for ack\n"));
sem_wait(&audio_irq_done_sem);
D(bug("stream: ack received\n"));
// Get size of audio data
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
if (apple_stream_info) {
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
D(bug("stream: work_size %d\n", work_size));
if (work_size > sound_buffer_size)
work_size = sound_buffer_size;
if (work_size == 0)
goto silence;
// Send data to audio port
if (work_size == sound_buffer_size)
write(fd, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), sound_buffer_size);
else {
// Last buffer
Mac2Host_memcpy(last_buffer, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
memset((uint8 *)last_buffer + work_size, 0, sound_buffer_size - work_size);
write(fd, last_buffer, sound_buffer_size);
}
D(bug("stream: data written\n"));
} else
goto silence;
} else {
// Audio not active, play silence
silence: write(fd, silent_buffer, sound_buffer_size);
}
// We allow a maximum of three buffers to be sent
sent += audio_frames_per_block;
ioctl(fd, AUDIO_GETINFO, &status);
while ((delta = sent - status.play.samples) > (audio_frames_per_block * 3)) {
unsigned int sl = 1000000 * (delta - audio_frames_per_block * 3) / (AudioStatus.sample_rate >> 16);
usleep(sl);
ioctl(fd, AUDIO_GETINFO, &status);
}
}
return NULL;
}
/*
* MacOS audio interrupt, read next data block
*/
void AudioInterrupt(void)
{
D(bug("AudioInterrupt\n"));
// Get data from apple mixer
if (AudioStatus.mixer) {
M68kRegisters r;
r.a[0] = audio_data + adatStreamInfo;
r.a[1] = AudioStatus.mixer;
Execute68k(audio_data + adatGetSourceData, &r);
D(bug(" GetSourceData() returns %08lx\n", r.d[0]));
} else
WriteMacInt32(audio_data + adatStreamInfo, 0);
// Signal stream function
sem_post(&audio_irq_done_sem);
D(bug("AudioInterrupt done\n"));
}
/*
* Set sampling parameters
* "index" is an index into the audio_sample_rates[] etc. arrays
* It is guaranteed that AudioStatus.num_sources == 0
*/
bool audio_set_sample_rate(int index)
{
return true;
}
bool audio_set_sample_size(int index)
{
return true;
}
bool audio_set_channels(int index)
{
return true;
}
/*
* Get/set volume controls (volume values received/returned have the left channel
* volume in the upper 16 bits and the right channel volume in the lower 16 bits;
* both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume"))
*/
bool audio_get_main_mute(void)
{
return false;
}
uint32 audio_get_main_volume(void)
{
return 0x01000100;
}
bool audio_get_speaker_mute(void)
{
return false;
}
uint32 audio_get_speaker_volume(void)
{
return 0x01000100;
}
void audio_set_main_mute(bool mute)
{
}
void audio_set_main_volume(uint32 vol)
{
}
void audio_set_speaker_mute(bool mute)
{
}
void audio_set_speaker_volume(uint32 vol)
{
}

View File

@ -1,558 +0,0 @@
/*
* audio_oss_esd.cpp - Audio support, implementation for OSS and ESD (Linux and FreeBSD)
*
* Basilisk II (C) 1997-2008 Christian Bauer
*
* 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
*/
#include "sysdeps.h"
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#ifdef __linux__
#include <linux/soundcard.h>
#endif
#ifdef __FreeBSD__
#include <sys/soundcard.h>
#endif
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "audio.h"
#include "audio_defs.h"
#ifdef ENABLE_ESD
#include <esd.h>
#endif
#define DEBUG 0
#include "debug.h"
// The currently selected audio parameters (indices in audio_sample_rates[] etc. vectors)
static int audio_sample_rate_index = 0;
static int audio_sample_size_index = 0;
static int audio_channel_count_index = 0;
// Global variables
static bool is_dsp_audio = false; // Flag: is DSP audio
static int audio_fd = -1; // fd of dsp or ESD
static int mixer_fd = -1; // fd of mixer
static sem_t audio_irq_done_sem; // Signal from interrupt to streaming thread: data block read
static bool sem_inited = false; // Flag: audio_irq_done_sem initialized
static int sound_buffer_size; // Size of sound buffer in bytes
static bool little_endian = false; // Flag: DSP accepts only little-endian 16-bit sound data
static uint8 silence_byte; // Byte value to use to fill sound buffers with silence
static pthread_t stream_thread; // Audio streaming thread
static pthread_attr_t stream_thread_attr; // Streaming thread attributes
static bool stream_thread_active = false; // Flag: streaming thread installed
static volatile bool stream_thread_cancel = false; // Flag: cancel streaming thread
// Prototypes
static void *stream_func(void *arg);
/*
* Initialization
*/
// Set AudioStatus to reflect current audio stream format
static void set_audio_status_format(void)
{
AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index];
AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index];
AudioStatus.channels = audio_channel_counts[audio_channel_count_index];
}
// Init using the dsp device, returns false on error
static bool open_dsp(void)
{
// Open the device
const char *dsp = PrefsFindString("dsp");
audio_fd = open(dsp, O_WRONLY);
if (audio_fd < 0) {
fprintf(stderr, "WARNING: Cannot open %s (%s)\n", dsp, strerror(errno));
return false;
}
printf("Using %s audio output\n", dsp);
is_dsp_audio = true;
// Get supported sample formats
if (audio_sample_sizes.empty()) {
unsigned long format;
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &format);
if (format & AFMT_U8)
audio_sample_sizes.push_back(8);
if (format & (AFMT_S16_BE | AFMT_S16_LE))
audio_sample_sizes.push_back(16);
int stereo = 0;
if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 0)
audio_channel_counts.push_back(1);
stereo = 1;
if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) == 0 && stereo == 1)
audio_channel_counts.push_back(2);
if (audio_sample_sizes.empty() || audio_channel_counts.empty()) {
WarningAlert(GetString(STR_AUDIO_FORMAT_WARN));
close(audio_fd);
audio_fd = -1;
return false;
}
audio_sample_rates.push_back(11025 << 16);
audio_sample_rates.push_back(22050 << 16);
int rate = 44100;
ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate);
if (rate > 22050)
audio_sample_rates.push_back(rate << 16);
// Default to highest supported values
audio_sample_rate_index = audio_sample_rates.size() - 1;
audio_sample_size_index = audio_sample_sizes.size() - 1;
audio_channel_count_index = audio_channel_counts.size() - 1;
}
// Set DSP parameters
unsigned long format;
if (audio_sample_sizes[audio_sample_size_index] == 8) {
format = AFMT_U8;
little_endian = false;
silence_byte = 0x80;
} else {
unsigned long sup_format;
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &sup_format);
if (sup_format & AFMT_S16_BE) {
little_endian = false;
format = AFMT_S16_BE;
} else {
little_endian = true;
format = AFMT_S16_LE;
}
silence_byte = 0;
}
ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
int frag = 0x0004000c; // Block size: 4096 frames
ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag);
int stereo = (audio_channel_counts[audio_channel_count_index] == 2);
ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo);
int rate = audio_sample_rates[audio_sample_rate_index] >> 16;
ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate);
// Get sound buffer size
ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &audio_frames_per_block);
D(bug("DSP_GETBLKSIZE %d\n", audio_frames_per_block));
return true;
}
// Init using ESD, returns false on error
static bool open_esd(void)
{
#ifdef ENABLE_ESD
int rate;
esd_format_t format = ESD_STREAM | ESD_PLAY;
if (audio_sample_sizes.empty()) {
// Default values
rate = 44100;
format |= (ESD_BITS16 | ESD_STEREO);
} else {
rate = audio_sample_rates[audio_sample_rate_index] >> 16;
if (audio_sample_sizes[audio_sample_size_index] == 8)
format |= ESD_BITS8;
else
format |= ESD_BITS16;
if (audio_channel_counts[audio_channel_count_index] == 1)
format |= ESD_MONO;
else
format |= ESD_STEREO;
}
#if WORDS_BIGENDIAN
little_endian = false;
#else
little_endian = true;
#endif
silence_byte = 0; // Is this correct for 8-bit mode?
// Open connection to ESD server
audio_fd = esd_play_stream(format, rate, NULL, NULL);
if (audio_fd < 0) {
fprintf(stderr, "WARNING: Cannot open ESD connection\n");
return false;
}
printf("Using ESD audio output\n");
// ESD supports a variety of twisted little audio formats, all different
if (audio_sample_sizes.empty()) {
// The reason we do this here is that we don't want to add sample
// rates etc. unless the ESD server connection could be opened
// (if ESD fails, dsp might be tried next)
audio_sample_rates.push_back(11025 << 16);
audio_sample_rates.push_back(22050 << 16);
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(8);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(1);
audio_channel_counts.push_back(2);
// Default to highest supported values
audio_sample_rate_index = audio_sample_rates.size() - 1;
audio_sample_size_index = audio_sample_sizes.size() - 1;
audio_channel_count_index = audio_channel_counts.size() - 1;
}
// Sound buffer size = 4096 frames
audio_frames_per_block = 4096;
return true;
#else
// ESD is not enabled, shut up the compiler
return false;
#endif
}
static bool open_audio(void)
{
#ifdef ENABLE_ESD
// If ESPEAKER is set, the user probably wants to use ESD, so try that first
if (getenv("ESPEAKER"))
if (open_esd())
goto dev_opened;
#endif
// Try to open dsp
if (open_dsp())
goto dev_opened;
#ifdef ENABLE_ESD
// Hm, dsp failed so we try ESD again if ESPEAKER wasn't set
if (!getenv("ESPEAKER"))
if (open_esd())
goto dev_opened;
#endif
// No audio device succeeded
WarningAlert(GetString(STR_NO_AUDIO_WARN));
return false;
// Device opened, set AudioStatus
dev_opened:
sound_buffer_size = (audio_sample_sizes[audio_sample_size_index] >> 3) * audio_channel_counts[audio_channel_count_index] * audio_frames_per_block;
set_audio_status_format();
// Start streaming thread
Set_pthread_attr(&stream_thread_attr, 0);
stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0);
// Everything went fine
audio_open = true;
return true;
}
void AudioInit(void)
{
// Init audio status (reasonable defaults) and feature flags
AudioStatus.sample_rate = 44100 << 16;
AudioStatus.sample_size = 16;
AudioStatus.channels = 2;
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
// Init semaphore
if (sem_init(&audio_irq_done_sem, 0, 0) < 0)
return;
sem_inited = true;
// Try to open the mixer device
const char *mixer = PrefsFindString("mixer");
mixer_fd = open(mixer, O_RDWR);
if (mixer_fd < 0)
printf("WARNING: Cannot open %s (%s)\n", mixer, strerror(errno));
// Open and initialize audio device
open_audio();
}
/*
* Deinitialization
*/
static void close_audio(void)
{
// Stop stream and delete semaphore
if (stream_thread_active) {
stream_thread_cancel = true;
#ifdef HAVE_PTHREAD_CANCEL
pthread_cancel(stream_thread);
#endif
pthread_join(stream_thread, NULL);
stream_thread_active = false;
}
// Close dsp or ESD socket
if (audio_fd >= 0) {
close(audio_fd);
audio_fd = -1;
}
audio_open = false;
}
void AudioExit(void)
{
// Stop the device immediately. Otherwise, close() sends
// SNDCTL_DSP_SYNC, which may hang
if (is_dsp_audio)
ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
// Close audio device
close_audio();
// Delete semaphore
if (sem_inited) {
sem_destroy(&audio_irq_done_sem);
sem_inited = false;
}
// Close mixer device
if (mixer_fd >= 0) {
close(mixer_fd);
mixer_fd = -1;
}
}
/*
* First source added, start audio stream
*/
void audio_enter_stream()
{
// Streaming thread is always running to avoid clicking noises
}
/*
* Last source removed, stop audio stream
*/
void audio_exit_stream()
{
// Streaming thread is always running to avoid clicking noises
}
/*
* Streaming function
*/
static void *stream_func(void *arg)
{
int16 *silent_buffer = new int16[sound_buffer_size / 2];
int16 *last_buffer = new int16[sound_buffer_size / 2];
memset(silent_buffer, silence_byte, sound_buffer_size);
while (!stream_thread_cancel) {
if (AudioStatus.num_sources) {
// Trigger audio interrupt to get new buffer
D(bug("stream: triggering irq\n"));
SetInterruptFlag(INTFLAG_AUDIO);
TriggerInterrupt();
D(bug("stream: waiting for ack\n"));
sem_wait(&audio_irq_done_sem);
D(bug("stream: ack received\n"));
// Get size of audio data
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
if (apple_stream_info) {
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
D(bug("stream: work_size %d\n", work_size));
if (work_size > sound_buffer_size)
work_size = sound_buffer_size;
if (work_size == 0)
goto silence;
// Send data to DSP
if (work_size == sound_buffer_size && !little_endian)
write(audio_fd, Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer)), sound_buffer_size);
else {
// Last buffer or little-endian DSP
if (little_endian) {
int16 *p = (int16 *)Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer));
for (int i=0; i<work_size/2; i++)
last_buffer[i] = ntohs(p[i]);
} else
Mac2Host_memcpy(last_buffer, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
memset((uint8 *)last_buffer + work_size, silence_byte, sound_buffer_size - work_size);
write(audio_fd, last_buffer, sound_buffer_size);
}
D(bug("stream: data written\n"));
} else
goto silence;
} else {
// Audio not active, play silence
silence: write(audio_fd, silent_buffer, sound_buffer_size);
}
}
delete[] silent_buffer;
delete[] last_buffer;
return NULL;
}
/*
* MacOS audio interrupt, read next data block
*/
void AudioInterrupt(void)
{
D(bug("AudioInterrupt\n"));
// Get data from apple mixer
if (AudioStatus.mixer) {
M68kRegisters r;
r.a[0] = audio_data + adatStreamInfo;
r.a[1] = AudioStatus.mixer;
Execute68k(audio_data + adatGetSourceData, &r);
D(bug(" GetSourceData() returns %08lx\n", r.d[0]));
} else
WriteMacInt32(audio_data + adatStreamInfo, 0);
// Signal stream function
sem_post(&audio_irq_done_sem);
D(bug("AudioInterrupt done\n"));
}
/*
* Set sampling parameters
* "index" is an index into the audio_sample_rates[] etc. vectors
* It is guaranteed that AudioStatus.num_sources == 0
*/
bool audio_set_sample_rate(int index)
{
close_audio();
audio_sample_rate_index = index;
return open_audio();
}
bool audio_set_sample_size(int index)
{
close_audio();
audio_sample_size_index = index;
return open_audio();
}
bool audio_set_channels(int index)
{
close_audio();
audio_channel_count_index = index;
return open_audio();
}
/*
* Get/set volume controls (volume values received/returned have the left channel
* volume in the upper 16 bits and the right channel volume in the lower 16 bits;
* both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume"))
*/
bool audio_get_main_mute(void)
{
return false;
}
uint32 audio_get_main_volume(void)
{
if (mixer_fd >= 0) {
int vol;
if (ioctl(mixer_fd, SOUND_MIXER_READ_PCM, &vol) == 0) {
int left = vol >> 8;
int right = vol & 0xff;
return ((left * 256 / 100) << 16) | (right * 256 / 100);
}
}
return 0x01000100;
}
bool audio_get_speaker_mute(void)
{
return false;
}
uint32 audio_get_speaker_volume(void)
{
if (mixer_fd >= 0) {
int vol;
if (ioctl(mixer_fd, SOUND_MIXER_READ_VOLUME, &vol) == 0) {
int left = vol >> 8;
int right = vol & 0xff;
return ((left * 256 / 100) << 16) | (right * 256 / 100);
}
}
return 0x01000100;
}
void audio_set_main_mute(bool mute)
{
}
void audio_set_main_volume(uint32 vol)
{
if (mixer_fd >= 0) {
int left = vol >> 16;
int right = vol & 0xffff;
int p = ((left * 100 / 256) << 8) | (right * 100 / 256);
ioctl(mixer_fd, SOUND_MIXER_WRITE_PCM, &p);
}
}
void audio_set_speaker_mute(bool mute)
{
}
void audio_set_speaker_volume(uint32 vol)
{
if (mixer_fd >= 0) {
int left = vol >> 16;
int right = vol & 0xffff;
int p = ((left * 100 / 256) << 8) | (right * 100 / 256);
ioctl(mixer_fd, SOUND_MIXER_WRITE_VOLUME, &p);
}
}

View File

@ -25,9 +25,6 @@ dnl Mac OS X Sound
AC_ARG_ENABLE(macosx-sound, [ --enable-macosx-sound enable Mac OS X Sound [default=no]], [WANT_MACOSX_SOUND=$enableval], [WANT_MACOSX_SOUND=no])
dnl Video options.
AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes])
AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes])
AC_ARG_ENABLE(fbdev-dga, [ --enable-fbdev-dga use direct frame buffer access via /dev/fb [default=yes]], [WANT_FBDEV_DGA=$enableval], [WANT_FBDEV_DGA=yes])
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=yes]], [WANT_VOSF=$enableval], [WANT_VOSF=yes])
dnl SDL options.
@ -71,7 +68,6 @@ AC_ARG_ENABLE(addressing,
])
dnl External packages.
AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes])
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]],
[case "$withval" in
gtk1) WANT_GTK="gtk";;
@ -280,9 +276,6 @@ dnl Do we need SDL?
WANT_SDL=no
if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
WANT_SDL=yes
WANT_XF86_DGA=no
WANT_XF86_VIDMODE=no
WANT_FBDEV_DGA=no
SDL_SUPPORT="$SDL_SUPPORT video"
fi
if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then
@ -350,15 +343,10 @@ else
SDL_SUPPORT="none"
fi
dnl We need X11, if not using SDL or Mac GUI.
dnl We need SDL or Mac GUI.
if [[ "x$WANT_SDL_VIDEO" = "xno" -a "x$WANT_MACOSX_GUI" = "xno" ]]; then
AC_PATH_XTRA
if [[ "x$no_x" = "xyes" ]]; then
AC_MSG_ERROR([You need X11 to run Basilisk II.])
fi
CFLAGS="$CFLAGS $X_CFLAGS"
CXXFLAGS="$CXXFLAGS $X_CFLAGS"
LIBS="$LIBS $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS"
AC_MSG_ERROR([You need SDL or macOS to run Basilisk II.])
fi
dnl BINCUE
@ -413,35 +401,6 @@ AC_CHECK_FUNCS(sem_init, , [
fi
])
dnl We use DGA (XFree86 or fbdev) if possible.
if [[ "x$WANT_XF86_DGA" = "xyes" ]]; then
AC_CHECK_LIB(Xxf86dga, XF86DGAQueryExtension, [
AC_DEFINE(ENABLE_XF86_DGA, 1, [Define if using XFree86 DGA extension.])
LIBS="$LIBS -lXxf86dga"
if [[ "x$WANT_FBDEV_DGA" = "xyes" ]]; then
AC_MSG_WARN([Cannot have both --enable-xf86-dga and --enable-fbdev-dga, ignoring --enable-fbdev-dga.])
WANT_FBDEV_DGA=no
fi
], [
AC_MSG_WARN([Could not find XFree86 DGA extension, ignoring --enable-xf86-dga.])
WANT_XF86_DGA=no
])
fi
if [[ "x$WANT_FBDEV_DGA" = "xyes" ]]; then
AC_DEFINE(ENABLE_FBDEV_DGA, 1, [Define if using DGA with framebuffer device.])
fi
dnl We use XFree86 VidMode if possible.
if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then
AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryExtension, [
AC_DEFINE(ENABLE_XF86_VIDMODE, 1, [Define if using XFree86 DGA extension.])
LIBS="$LIBS -lXxf86vm"
], [
AC_MSG_WARN([Could not find XFree86 VidMode extension, ignoring --enable-xf86-vidmode.])
WANT_XF86_VIDMODE=no
])
fi
dnl We use GTK+ if possible.
UISRCS=../dummy/prefs_editor_dummy.cpp
case "x$WANT_GTK" in
@ -494,19 +453,6 @@ if [[ "$WANT_GTK" = "no" ]]; then
fi
AC_SUBST(STANDALONE_GUI, [$WANT_STANDALONE_GUI])
dnl We use ESD if possible.
if [[ "x$WANT_ESD" = "xyes" ]]; then
AM_PATH_ESD(0.2.8, [
AC_DEFINE(ENABLE_ESD, 1, [Define is using ESD.])
CFLAGS="$CFLAGS $ESD_CFLAGS"
CXXFLAGS="$CXXFLAGS $ESD_CFLAGS"
LIBS="$LIBS $ESD_LIBS"
], [
AC_MSG_WARN([Could not find ESD, disabling ESD support.])
WANT_ESD=no
])
fi
dnl We use 64-bit file size support if possible.
AC_SYS_LARGEFILE
@ -730,12 +676,10 @@ EXTRASYSSRCS=
case "$target_os" in
linux*)
ETHERSRC=ether_unix.cpp
AUDIOSRC=audio_oss_esd.cpp
SCSISRC=Linux/scsi_linux.cpp
;;
freebsd*)
ETHERSRC=ether_unix.cpp
AUDIOSRC=audio_oss_esd.cpp
DEFINES="$DEFINES -DBSD_COMP"
CXXFLAGS="$CXXFLAGS -fpermissive"
dnl Check for the CAM library
@ -760,15 +704,9 @@ netbsd*)
ETHERSRC=ether_unix.cpp
;;
solaris*)
AUDIOSRC=Solaris/audio_solaris.cpp
DEFINES="$DEFINES -DBSD_COMP -D_POSIX_PTHREAD_SEMANTICS"
;;
irix*)
AUDIOSRC=Irix/audio_irix.cpp
EXTRASYSSRCS=Irix/unaligned.c
LIBS="$LIBS -laudio"
WANT_ESD=no
dnl Check if our compiler supports -IPA (MIPSPro)
HAVE_IPA=no
ocflags="$CFLAGS"
@ -885,7 +823,6 @@ if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
fi
fi
elif [[ "x$WANT_MACOSX_GUI" != "xyes" ]]; then
VIDEOSRCS="video_x.cpp"
KEYCODES="keycodes"
EXTRASYSSRCS="$EXTRASYSSRCS clip_unix.cpp"
fi
@ -1818,11 +1755,7 @@ echo SDL major-version ...................... : $WANT_SDL_VERSION_MAJOR
echo BINCUE support ......................... : $have_bincue
echo LIBVHD support ......................... : $have_libvhd
echo VDE support ............................ : $have_vdeplug
echo XFree86 DGA support .................... : $WANT_XF86_DGA
echo XFree86 VidMode support ................ : $WANT_XF86_VIDMODE
echo fbdev DGA support ...................... : $WANT_FBDEV_DGA
echo Enable video on SEGV signals ........... : $WANT_VOSF
echo ESD sound support ...................... : $WANT_ESD
echo GTK user interface ..................... : $WANT_GTK
echo mon debugger support ................... : $WANT_MON
echo Use JIT compiler ....................... : $WANT_JIT

View File

@ -31,10 +31,6 @@
# include <SDL_main.h>
#endif
#ifndef USE_SDL_VIDEO
# include <X11/Xlib.h>
#endif
#ifdef HAVE_PTHREADS
# include <pthread.h>
#endif
@ -54,11 +50,6 @@
# endif
#endif
#ifdef ENABLE_XF86_DGA
# include <X11/Xutil.h>
# include <X11/extensions/Xxf86dga.h>
#endif
#include <string>
using std::string;
@ -105,16 +96,6 @@ bool CPUIs68060;
int FPUType;
bool TwentyFourBitAddressing;
// Global variables
#ifndef USE_SDL_VIDEO
extern char *x_display_name; // X11 display name
extern Display *x_display; // X11 display handle
#ifdef X11_LOCK_TYPE
X11_LOCK_TYPE x_display_lock = X11_LOCK_INIT; // X11 display lock
#endif
#endif
static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes
#ifdef HAVE_PTHREADS
@ -367,12 +348,6 @@ int main(int argc, char **argv)
for (int i=1; i<argc; i++) {
if (strcmp(argv[i], "--help") == 0) {
usage(argv[0]);
#ifndef USE_SDL_VIDEO
} else if (strcmp(argv[i], "--display") == 0) {
i++; // don't remove the argument, gtk_init() needs it too
if (i < argc)
x_display_name = strdup(argv[i]);
#endif
} else if (strcmp(argv[i], "--gui-connection") == 0) {
argv[i++] = NULL;
if (i < argc) {
@ -475,22 +450,6 @@ int main(int argc, char **argv)
}
}
#ifndef USE_SDL_VIDEO
// Open display
x_display = XOpenDisplay(x_display_name);
if (x_display == NULL) {
char str[256];
sprintf(str, GetString(STR_NO_XSERVER_ERR), XDisplayName(x_display_name));
ErrorAlert(str);
QuitEmulator();
}
#if defined(ENABLE_XF86_DGA) && !defined(ENABLE_MON)
// Fork out, so we can return from fullscreen mode when things get ugly
XF86DGAForkApp(DefaultScreen(x_display));
#endif
#endif
#ifdef USE_SDL
// Initialize SDL system
int sdl_flags = 0;
@ -785,12 +744,6 @@ void QuitEmulator(void)
// Exit preferences
PrefsExit();
// Close X11 server connection
#ifndef USE_SDL_VIDEO
if (x_display)
XCloseDisplay(x_display);
#endif
// Notify GUI we are about to leave
if (gui_connection) {
if (rpc_method_invoke(gui_connection, RPC_METHOD_EXIT, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR)

View File

@ -858,33 +858,15 @@ static GtkWidget *l_frameskip, *l_display_x, *l_display_y;
static int display_type;
static int dis_width, dis_height;
#ifdef ENABLE_FBDEV_DGA
static GtkWidget *w_fbdev_name, *w_fbdevice_file;
static GtkWidget *l_fbdev_name, *l_fbdevice_file;
static char fbdev_name[256];
#endif
static GtkWidget *w_dspdevice_file, *w_mixerdevice_file;
// Hide/show graphics widgets
static void hide_show_graphics_widgets(void)
{
switch (display_type) {
case DISPLAY_WINDOW:
gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip);
#ifdef ENABLE_FBDEV_DGA
gtk_widget_show(w_display_x); gtk_widget_show(l_display_x);
gtk_widget_show(w_display_y); gtk_widget_show(l_display_y);
gtk_widget_hide(w_fbdev_name); gtk_widget_hide(l_fbdev_name);
#endif
break;
case DISPLAY_SCREEN:
gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip);
#ifdef ENABLE_FBDEV_DGA
gtk_widget_hide(w_display_x); gtk_widget_hide(l_display_x);
gtk_widget_hide(w_display_y); gtk_widget_hide(l_display_y);
gtk_widget_show(w_fbdev_name); gtk_widget_show(l_fbdev_name);
#endif
break;
}
}
@ -913,11 +895,8 @@ static void mn_60hz(...) {PrefsReplaceInt32("frameskip", 1);}
static void mn_dynamic(...) {PrefsReplaceInt32("frameskip", 0);}
// Set sensitivity of widgets
static void set_graphics_sensitive(void)
{
static void set_graphics_sensitive(void){
const bool sound_enabled = !PrefsFindBool("nosound");
gtk_widget_set_sensitive(w_dspdevice_file, sound_enabled);
gtk_widget_set_sensitive(w_mixerdevice_file, sound_enabled);
}
// "Disable Sound Output" button toggled
@ -933,19 +912,12 @@ static void parse_graphics_prefs(void)
display_type = DISPLAY_WINDOW;
dis_width = 512;
dis_height = 384;
#ifdef ENABLE_FBDEV_DGA
fbdev_name[0] = 0;
#endif
const char *str = PrefsFindString("screen");
if (str) {
if (sscanf(str, "win/%d/%d", &dis_width, &dis_height) == 2)
display_type = DISPLAY_WINDOW;
#ifdef ENABLE_FBDEV_DGA
else if (sscanf(str, "dga/%255s", fbdev_name) == 1)
#else
else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
#endif
if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
display_type = DISPLAY_SCREEN;
}
}
@ -967,28 +939,13 @@ static void read_graphics_settings(void)
sprintf(pref, "win/%d/%d", dis_width, dis_height);
break;
case DISPLAY_SCREEN:
#ifdef ENABLE_FBDEV_DGA
str = gtk_entry_get_text(GTK_ENTRY(w_fbdev_name));
sprintf(pref, "dga/%s", str);
#else
sprintf(pref, "dga/%d/%d", dis_width, dis_height);
#endif
break;
default:
PrefsRemoveItem("screen");
return;
}
PrefsReplaceString("screen", pref);
#ifdef ENABLE_FBDEV_DGA
str = get_file_entry_path(w_fbdevice_file);
if (str && strlen(str))
PrefsReplaceString("fbdevicefile", str);
else
PrefsRemoveItem("fbdevicefile");
#endif
PrefsReplaceString("dsp", get_file_entry_path(w_dspdevice_file));
PrefsReplaceString("mixer", get_file_entry_path(w_mixerdevice_file));
}
// Create "Graphics/Sound" pane
@ -1094,30 +1051,14 @@ static void create_graphics_pane(GtkWidget *top)
gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 3, 4, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
w_display_y = GTK_COMBO(combo)->entry;
#ifdef ENABLE_FBDEV_DGA
l_fbdev_name = gtk_label_new(GetString(STR_FBDEV_NAME_CTRL));
gtk_widget_show(l_fbdev_name);
gtk_table_attach(GTK_TABLE(table), l_fbdev_name, 0, 1, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
w_fbdev_name = gtk_entry_new();
gtk_widget_show(w_fbdev_name);
gtk_entry_set_text(GTK_ENTRY(w_fbdev_name), fbdev_name);
gtk_table_attach(GTK_TABLE(table), w_fbdev_name, 1, 2, 4, 5, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
w_fbdevice_file = make_file_entry(box, STR_FBDEVICE_FILE_CTRL, "fbdevicefile");
#endif
make_separator(box);
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
w_dspdevice_file = make_file_entry(box, STR_DSPDEVICE_FILE_CTRL, "dsp");
w_mixerdevice_file = make_file_entry(box, STR_MIXERDEVICE_FILE_CTRL, "mixer");
set_graphics_sensitive();
hide_show_graphics_widgets();
}
/*
* "Input" pane
*/

File diff suppressed because it is too large Load Diff