Merge cd. Doesn't dlopen different cd drivers or anything exciting... Yet.

This commit is contained in:
Ragnvald Maartmann-Moe IV 2001-04-09 21:15:09 +00:00
parent 0c00970ae1
commit d7eb585502
30 changed files with 304 additions and 1990 deletions

View file

@ -1393,6 +1393,8 @@ AC_OUTPUT(
include/QF/Makefile
include/win32/version.h
libs/Makefile
libs/audio/Makefile
libs/audio/cd/Makefile
libs/gamecode/Makefile
libs/util/Makefile
qw/include/Makefile

View file

@ -1,7 +1,8 @@
AUTOMAKE_OPTIONS = foreign
includedir = $(prefix)/include/QF
include_HEADERS = asm_i386.h checksum.h cmd.h compat.h console.h crc.h \
cvar.h gcc_attr.h hash.h info.h keys.h link.h mathlib.h mdfour.h \
msg.h pr_comp.h progs.h qargs.h qdefs.h qendian.h qfplist.h qtypes.h \
quakefs.h quakeio.h sizebuf.h sys.h uint32.h va.h ver_check.h \
zone.h
include_HEADERS = asm_i386.h checksum.h cdaudio.h cmd.h compat.h \
console.h crc.h cvar.h gcc_attr.h hash.h info.h \
keys.h link.h mathlib.h mdfour.h msg.h pr_comp.h \
progs.h qargs.h qdefs.h qendian.h qfplist.h qtypes.h \
quakefs.h quakeio.h sizebuf.h sound.h sys.h uint32.h \
va.h ver_check.h zone.h

197
include/QF/sound.h Normal file
View file

@ -0,0 +1,197 @@
/*
sound.h
(description)
Copyright (C) 1996-1997 Id Software, Inc.
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
// sound.h -- client sound i/o functions
#ifndef _SOUND_H
#define _SOUND_H
#include "QF/mathlib.h"
#include "QF/cvar.h"
#include "QF/zone.h"
// !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct
{
int left;
int right;
} portable_samplepair_t;
typedef struct sfx_s
{
char name[MAX_QPATH];
cache_user_t cache;
} sfx_t;
// !!! if this is changed, it much be changed in asm_i386.h too !!!
typedef struct
{
int length;
int loopstart;
int speed;
int width;
int stereo;
byte data[1]; // variable sized
} sfxcache_t;
typedef struct
{
qboolean gamealive;
qboolean soundalive;
qboolean splitbuffer;
int channels;
int samples; // mono samples in buffer
int submission_chunk; // don't mix less than this #
int samplepos; // in mono samples
int samplebits;
int speed;
unsigned char *buffer;
} dma_t;
// !!! if this is changed, it much be changed in asm_i386.h too !!!
typedef struct
{
sfx_t *sfx; // sfx number
int leftvol; // 0-255 volume
int rightvol; // 0-255 volume
int end; // end time in global paintsamples
int pos; // sample position in sfx
int looping; // where to loop, -1 = no looping
int entnum; // to allow overriding a specific sound
int entchannel; //
vec3_t origin; // origin of sound effect
vec_t dist_mult; // distance multiplier (attenuation/clipK)
int master_vol; // 0-255 master volume
int phase; // phase shift between l-r in samples
int oldphase; // phase shift between l-r in samples
} channel_t;
typedef struct
{
int rate;
int width;
int channels;
int loopstart;
int samples;
int dataofs; // chunk starts this many bytes from file start
} wavinfo_t;
void S_Init (void);
void S_Init_Cvars (void);
void S_Startup (void);
void S_Shutdown (void);
void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation);
void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation);
void S_StopSound (int entnum, int entchannel);
void S_StopAllSounds(qboolean clear);
void S_ClearBuffer (void);
void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
void S_ExtraUpdate (void);
void S_BlockSound (void);
sfx_t *S_PrecacheSound (char *sample);
void S_TouchSound (char *sample);
void S_ClearPrecache (void);
void S_BeginPrecaching (void);
void S_EndPrecaching (void);
void S_PaintChannels(int endtime);
void S_InitPaintChannels (void);
// picks a channel based on priorities, empty slots, number of channels
channel_t *SND_PickChannel(int entnum, int entchannel);
// spatializes a channel
void SND_Spatialize(channel_t *ch);
// initializes cycling through a DMA buffer and returns information on it
qboolean SNDDMA_Init(void);
// gets the current DMA position
int SNDDMA_GetDMAPos(void);
// shutdown the DMA xfer.
void SNDDMA_Shutdown(void);
// ====================================================================
// User-setable variables
// ====================================================================
#define MAX_CHANNELS 256
#define MAX_DYNAMIC_CHANNELS 8
extern channel_t channels[MAX_CHANNELS];
// 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds
// MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 = water, etc
// MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels = static sounds
extern int total_channels;
//
// Fake dma is a synchronous faking of the DMA progress used for
// isolating performance in the renderer. The fakedma_updates is
// number of times S_Update() is called per second.
//
extern qboolean fakedma;
extern int fakedma_updates;
extern int paintedtime;
extern int soundtime;
extern vec3_t listener_origin;
extern vec3_t listener_forward;
extern vec3_t listener_right;
extern vec3_t listener_up;
extern volatile dma_t *shm;
extern volatile dma_t sn;
extern vec_t sound_nominal_clip_dist;
extern cvar_t *loadas8bit;
extern cvar_t *bgmvolume;
extern cvar_t *volume;
extern cvar_t *snd_device;
extern cvar_t *snd_rate;
extern cvar_t *snd_bits;
extern cvar_t *snd_stereo;
extern cvar_t *snd_interp;
extern cvar_t *snd_stereo_phase_separation;
extern qboolean snd_initialized;
extern int snd_blocked;
void S_LocalSound (char *s);
sfxcache_t *S_LoadSound (sfx_t *s);
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength);
void SND_InitScaletable (void);
void SNDDMA_Submit(void);
void S_AmbientOff (void);
void S_AmbientOn (void);
#endif // _SOUND_H

View file

@ -1,4 +1,4 @@
SUBDIRS= gamecode util
SUBDIRS= audio gamecode util
clean-local:
rm -f *.a

4
libs/audio/Makefile.am Normal file
View file

@ -0,0 +1,4 @@
SUBDIRS= cd
clean-local:
rm -f *.a

24
libs/audio/cd/Makefile.am Normal file
View file

@ -0,0 +1,24 @@
lib_LTLIBRARIES = libQFcd.la
libQFcd_la_LDFLAGS = -version-info 1:0:0 $(CD_LIBS)
#
# ... CD audio
#
if CDTYPE_LINUX
libQFcd_la_SOURCES= cd_linux.c
endif
if CDTYPE_SDL
libQFcd_la_SOURCES= cd_sdl.c
endif
if CDTYPE_SGI
libQFcd_la_SOURCES= cd_sgi.c
endif
if CDTYPE_WIN32
libQFcd_la_SOURCES= cd_win.c
endif
if CDTYPE_NULL
libQFcd_la_SOURCES= cd_null.c
endif
LIBLIST = libQFcd.la @LIBRARY_SEARCH_PATH@

View file

@ -29,9 +29,6 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@ -41,23 +38,23 @@
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#include <linux/cdrom.h>
#include <time.h>
#include "cdaudio.h"
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <linux/cdrom.h>
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/qargs.h"
#include "sound.h"
#include "QF/sound.h"
static qboolean cdValid = false;
static qboolean playing = false;

View file

@ -30,7 +30,7 @@
# include "config.h"
#endif
#include "cdaudio.h"
#include "QF/cdaudio.h"
void
CDAudio_Play (byte track, qboolean looping)

View file

@ -40,11 +40,11 @@
#include <SDL.h>
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/qargs.h"
#include "sound.h"
#include "QF/sound.h"
static qboolean cdValid = false;
static qboolean initialized = false;

View file

@ -32,14 +32,13 @@
#include <sys/types.h>
#include <errno.h>
#include <dmedia/cdaudio.h>
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/qargs.h"
#include "sound.h"
#include "QF/sound.h"
static qboolean initialized = false;
static qboolean enabled = true;

View file

@ -32,12 +32,12 @@
#include <windows.h>
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/qargs.h"
#include "sound.h"
#include "QF/sound.h"
extern HWND mainwindow;

View file

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = adivtab.h anorm_dots.h anorms.h asm_draw.h asm_ia32.h \
bspfile.h block16.h cdaudio.h chase.h client.h checksum.h cmd.h compat.h \
bspfile.h block16.h chase.h client.h checksum.h cmd.h compat.h \
conproc.h console.h context_x11.h crc.h cvar.h \
dga_check.h d_iface.h d_ifacea.h d_local.h dosisms.h draw.h \
gcc_attr.h gib_error.h gib.h gib_instructions.h \

View file

@ -1,41 +0,0 @@
/*
cdaudio.h
Redbook CD Audio function prototypes
Copyright (C) 1996-1997 Id Software, Inc.
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __cdaudio_h
#define __cdaudio_h
int CDAudio_Init(void);
void CDAudio_Play(byte track, qboolean looping);
void CDAudio_Stop(void);
void CDAudio_Pause(void);
void CDAudio_Resume(void);
void CDAudio_Shutdown(void);
void CDAudio_Update(void);
#endif // __cdaudio_h

View file

@ -38,7 +38,7 @@ bin_PROGRAMS = @NQ_TARGETS@
EXTRA_PROGRAMS= nq-3dfx nq-fbdev nq-glx nq-mgl nq-sdl \
nq-sgl nq-svga nq-wgl nq-x11 nq-server
noinst_LIBRARIES= libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
noinst_LIBRARIES= libqfsys.a libqfsnd.a libqfjs.a libqfnet.a
#if ASM_ARCH
math_ASM= cl_math.S
@ -92,20 +92,6 @@ EXTRA_libqfsnd_a_SOURCES= snd_dma.c snd_mem.c snd_mix.c snd_alsa_0_5.c \
snd_alsa_0_9.c snd_oss.c snd_sun.c snd_win.c snd_null.c \
$(sound_ASM)
#
# ... CD audio
#
if CDTYPE_WIN32
libqfcd_a_SOURCES= cd_win.c
endif
if CDTYPE_LINUX
libqfcd_a_SOURCES= cd_linux.c
endif
if CDTYPE_NULL
libqfcd_a_SOURCES= cd_null.c
endif
EXTRA_libqfcd_a_SOURCES= cd_dos.c cd_win.c cd_linux.c cd_null.c
#
# ... Joystick
#
@ -124,11 +110,14 @@ EXTRA_libqfjs_a_SOURCES= joy_linux.c joy_null.c
libqfnet_a_SOURCES= net_bsd.c net_dgrm.c net_loop.c \
net_main.c net_udp.c net_vcr.c
EXTRA_libqfcd_a_SOURCES=net_dos.c net_bw.c net_ipx.c net_mp.c net_ser.c \
EXTRA_libqfnet_a_SOURCES=net_dos.c net_bw.c net_ipx.c net_mp.c net_ser.c \
net_win.c net_wins.c net_wipx.c
client_LIBS= $(top_builddir)/libs/gamecode/libQFgamecode.la $(top_builddir)/libs/util/libQFutil.la -L. -lqfsys -lqfsnd -lqfcd -lqfjs -lqfnet $(SOUND_LIBS) $(NET_LIBS)
client_LIB_DEPS= libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a
client_LIBS= $(top_builddir)/libs/gamecode/libQFgamecode.la \
$(top_builddir)/libs/util/libQFutil.la \
$(top_builddir)/libs/audio/cd/libQFcd.la \
-L. -lqfsys -lqfsnd -lqfjs -lqfnet $(SOUND_LIBS) $(NET_LIBS)
client_LIB_DEPS= libqfsys.a libqfsnd.a libqfjs.a libqfnet.a
client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_parse.c \
cl_tent.c console.c keys.c sbar.c r_part.c r_view.c \

View file

@ -1,870 +0,0 @@
/*
cd_dos.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <dpmi.h>
#include "dosisms.h"
#define ADDRESS_MODE_HSG 0
#define ADDRESS_MODE_RED_BOOK 1
#define STATUS_ERROR_BIT 0x8000
#define STATUS_BUSY_BIT 0x0200
#define STATUS_DONE_BIT 0x0100
#define STATUS_ERROR_MASK 0x00ff
#define ERROR_WRITE_PROTECT 0
#define ERROR_UNKNOWN_UNIT 1
#define ERROR_DRIVE_NOT_READY 2
#define ERROR_UNKNOWN_COMMAND 3
#define ERROR_CRC_ERROR 4
#define ERROR_BAD_REQUEST_LEN 5
#define ERROR_SEEK_ERROR 6
#define ERROR_UNKNOWN_MEDIA 7
#define ERROR_SECTOR_NOT_FOUND 8
#define ERROR_OUT_OF_PAPER 9
#define ERROR_WRITE_FAULT 10
#define ERROR_READ_FAULT 11
#define ERROR_GENERAL_FAILURE 12
#define ERROR_RESERVED_13 13
#define ERROR_RESERVED_14 14
#define ERROR_BAD_DISK_CHANGE 15
#define COMMAND_READ 3
#define COMMAND_WRITE 12
#define COMMAND_PLAY_AUDIO 132
#define COMMAND_STOP_AUDIO 133
#define COMMAND_RESUME_AUDIO 136
#define READ_REQUEST_AUDIO_CHANNEL_INFO 4
#define READ_REQUEST_DEVICE_STATUS 6
#define READ_REQUEST_MEDIA_CHANGE 9
#define READ_REQUEST_AUDIO_DISK_INFO 10
#define READ_REQUEST_AUDIO_TRACK_INFO 11
#define READ_REQUEST_AUDIO_STATUS 15
#define WRITE_REQUEST_EJECT 0
#define WRITE_REQUEST_RESET 2
#define WRITE_REQUEST_AUDIO_CHANNEL_INFO 3
#define STATUS_DOOR_OPEN 0x00000001
#define STATUS_DOOR_UNLOCKED 0x00000002
#define STATUS_RAW_SUPPORT 0x00000004
#define STATUS_READ_WRITE 0x00000008
#define STATUS_AUDIO_SUPPORT 0x00000010
#define STATUS_INTERLEAVE_SUPPORT 0x00000020
#define STATUS_BIT_6_RESERVED 0x00000040
#define STATUS_PREFETCH_SUPPORT 0x00000080
#define STATUS_AUDIO_MANIPLUATION_SUPPORT 0x00000100
#define STATUS_RED_BOOK_ADDRESS_SUPPORT 0x00000200
#define MEDIA_NOT_CHANGED 1
#define MEDIA_STATUS_UNKNOWN 0
#define MEDIA_CHANGED -1
#define AUDIO_CONTROL_MASK 0xd0
#define AUDIO_CONTROL_DATA_TRACK 0x40
#define AUDIO_CONTROL_AUDIO_2_TRACK 0x00
#define AUDIO_CONTROL_AUDIO_2P_TRACK 0x10
#define AUDIO_CONTROL_AUDIO_4_TRACK 0x80
#define AUDIO_CONTROL_AUDIO_4P_TRACK 0x90
#define AUDIO_STATUS_PAUSED 0x0001
#pragma pack(1)
struct playAudioRequest {
char addressingMode;
int startLocation;
int sectors;
};
struct readRequest {
char mediaDescriptor;
short bufferOffset;
short bufferSegment;
short length;
short startSector;
int volumeID;
};
struct writeRequest {
char mediaDescriptor;
short bufferOffset;
short bufferSegment;
short length;
short startSector;
int volumeID;
};
struct cd_request {
char headerLength;
char unit;
char command;
short status;
char reserved[8];
union {
struct playAudioRequest playAudio;
struct readRequest read;
struct writeRequest write;
} x;
};
struct audioChannelInfo_s {
char code;
char channel0input;
char channel0volume;
char channel1input;
char channel1volume;
char channel2input;
char channel2volume;
char channel3input;
char channel3volume;
};
struct deviceStatus_s {
char code;
int status;
};
struct mediaChange_s {
char code;
char status;
};
struct audioDiskInfo_s {
char code;
char lowTrack;
char highTrack;
int leadOutStart;
};
struct audioTrackInfo_s {
char code;
char track;
int start;
char control;
};
struct audioStatus_s {
char code;
short status;
int PRstartLocation;
int PRendLocation;
};
struct reset_s {
char code;
};
union readInfo_u {
struct audioChannelInfo_s audioChannelInfo;
struct deviceStatus_s deviceStatus;
struct mediaChange_s mediaChange;
struct audioDiskInfo_s audioDiskInfo;
struct audioTrackInfo_s audioTrackInfo;
struct audioStatus_s audioStatus;
struct reset_s reset;
};
#pragma pack()
#define MAXIMUM_TRACKS 100
typedef struct {
int start;
int length;
qboolean isData;
} track_info;
typedef struct {
qboolean valid;
int leadOutAddress;
track_info track[MAXIMUM_TRACKS];
byte lowTrack;
byte highTrack;
} cd_info;
static struct cd_request *cdRequest;
static union readInfo_u *readInfo;
static cd_info cd;
static qboolean playing = false;
static qboolean wasPlaying = false;
static qboolean mediaCheck = false;
static qboolean initialized = false;
static qboolean enabled = true;
static qboolean playLooping = false;
static short cdRequestSegment;
static short cdRequestOffset;
static short readInfoSegment;
static short readInfoOffset;
static byte remap[256];
static byte cdrom;
static byte playTrack;
static byte cdvolume;
static int
RedBookToSector (int rb)
{
byte minute;
byte second;
byte frame;
minute = (rb >> 16) & 0xff;
second = (rb >> 8) & 0xff;
frame = rb & 0xff;
return minute * 60 * 75 + second * 75 + frame;
}
static void
CDAudio_Reset (void)
{
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_WRITE;
cdRequest->status = 0;
cdRequest->x.write.mediaDescriptor = 0;
cdRequest->x.write.bufferOffset = readInfoOffset;
cdRequest->x.write.bufferSegment = readInfoSegment;
cdRequest->x.write.length = sizeof (struct reset_s);
cdRequest->x.write.startSector = 0;
cdRequest->x.write.volumeID = 0;
readInfo->reset.code = WRITE_REQUEST_RESET;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
}
static void
CDAudio_Eject (void)
{
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_WRITE;
cdRequest->status = 0;
cdRequest->x.write.mediaDescriptor = 0;
cdRequest->x.write.bufferOffset = readInfoOffset;
cdRequest->x.write.bufferSegment = readInfoSegment;
cdRequest->x.write.length = sizeof (struct reset_s);
cdRequest->x.write.startSector = 0;
cdRequest->x.write.volumeID = 0;
readInfo->reset.code = WRITE_REQUEST_EJECT;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
}
static int
CDAudio_GetAudioTrackInfo (byte track, int *start)
{
byte control;
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_READ;
cdRequest->status = 0;
cdRequest->x.read.mediaDescriptor = 0;
cdRequest->x.read.bufferOffset = readInfoOffset;
cdRequest->x.read.bufferSegment = readInfoSegment;
cdRequest->x.read.length = sizeof (struct audioTrackInfo_s);
cdRequest->x.read.startSector = 0;
cdRequest->x.read.volumeID = 0;
readInfo->audioTrackInfo.code = READ_REQUEST_AUDIO_TRACK_INFO;
readInfo->audioTrackInfo.track = track;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
if (cdRequest->status & STATUS_ERROR_BIT) {
Con_DPrintf ("CDAudio_GetAudioTrackInfo %04x\n",
cdRequest->status & 0xffff);
return -1;
}
*start = readInfo->audioTrackInfo.start;
control = readInfo->audioTrackInfo.control & AUDIO_CONTROL_MASK;
return (control & AUDIO_CONTROL_DATA_TRACK);
}
static int
CDAudio_GetAudioDiskInfo (void)
{
int n;
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_READ;
cdRequest->status = 0;
cdRequest->x.read.mediaDescriptor = 0;
cdRequest->x.read.bufferOffset = readInfoOffset;
cdRequest->x.read.bufferSegment = readInfoSegment;
cdRequest->x.read.length = sizeof (struct audioDiskInfo_s);
cdRequest->x.read.startSector = 0;
cdRequest->x.read.volumeID = 0;
readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_DISK_INFO;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
if (cdRequest->status & STATUS_ERROR_BIT) {
Con_DPrintf ("CDAudio_GetAudioDiskInfo %04x\n",
cdRequest->status & 0xffff);
return -1;
}
cd.valid = true;
cd.lowTrack = readInfo->audioDiskInfo.lowTrack;
cd.highTrack = readInfo->audioDiskInfo.highTrack;
cd.leadOutAddress = readInfo->audioDiskInfo.leadOutStart;
for (n = cd.lowTrack; n <= cd.highTrack; n++) {
cd.track[n].isData = CDAudio_GetAudioTrackInfo (n, &cd.track[n].start);
if (n > cd.lowTrack) {
cd.track[n - 1].length =
RedBookToSector (cd.track[n].start) -
RedBookToSector (cd.track[n - 1].start);
if (n == cd.highTrack)
cd.track[n].length =
RedBookToSector (cd.leadOutAddress) -
RedBookToSector (cd.track[n].start);
}
}
return 0;
}
static int
CDAudio_GetAudioStatus (void)
{
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_READ;
cdRequest->status = 0;
cdRequest->x.read.mediaDescriptor = 0;
cdRequest->x.read.bufferOffset = readInfoOffset;
cdRequest->x.read.bufferSegment = readInfoSegment;
cdRequest->x.read.length = sizeof (struct audioStatus_s);
cdRequest->x.read.startSector = 0;
cdRequest->x.read.volumeID = 0;
readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_STATUS;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
if (cdRequest->status & STATUS_ERROR_BIT)
return -1;
return 0;
}
static int
CDAudio_MediaChange (void)
{
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_READ;
cdRequest->status = 0;
cdRequest->x.read.mediaDescriptor = 0;
cdRequest->x.read.bufferOffset = readInfoOffset;
cdRequest->x.read.bufferSegment = readInfoSegment;
cdRequest->x.read.length = sizeof (struct mediaChange_s);
cdRequest->x.read.startSector = 0;
cdRequest->x.read.volumeID = 0;
readInfo->mediaChange.code = READ_REQUEST_MEDIA_CHANGE;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
return readInfo->mediaChange.status;
}
// we set the volume to 0 first and then to the desired volume
// some cd-rom drivers seem to need it done this way
void
CDAudio_SetVolume (byte volume)
{
if (!initialized || !enabled)
return;
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_WRITE;
cdRequest->status = 0;
cdRequest->x.read.mediaDescriptor = 0;
cdRequest->x.read.bufferOffset = readInfoOffset;
cdRequest->x.read.bufferSegment = readInfoSegment;
cdRequest->x.read.length = sizeof (struct audioChannelInfo_s);
cdRequest->x.read.startSector = 0;
cdRequest->x.read.volumeID = 0;
readInfo->audioChannelInfo.code = WRITE_REQUEST_AUDIO_CHANNEL_INFO;
readInfo->audioChannelInfo.channel0input = 0;
readInfo->audioChannelInfo.channel0volume = 0;
readInfo->audioChannelInfo.channel1input = 1;
readInfo->audioChannelInfo.channel1volume = 0;
readInfo->audioChannelInfo.channel2input = 2;
readInfo->audioChannelInfo.channel2volume = 0;
readInfo->audioChannelInfo.channel3input = 3;
readInfo->audioChannelInfo.channel3volume = 0;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
readInfo->audioChannelInfo.channel0volume = volume;
readInfo->audioChannelInfo.channel1volume = volume;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
cdvolume = volume;
}
void
CDAudio_Play (byte track, qboolean looping)
{
int volume;
if (!initialized || !enabled)
return;
if (!cd.valid)
return;
track = remap[track];
if (playing) {
if (playTrack == track)
return;
CDAudio_Stop ();
}
playLooping = looping;
if (track < cd.lowTrack || track > cd.highTrack) {
Con_DPrintf ("CDAudio_Play: Bad track number %u.\n", track);
return;
}
playTrack = track;
if (cd.track[track].isData) {
Con_DPrintf ("CDAudio_Play: Can not play data.\n");
return;
}
volume = (int) (bgmvolume->value * 255.0);
if (volume < 0) {
Cvar_SetValue (bgmvolume, 0.0);
volume = 0;
} else if (volume > 255) {
Cvar_SetValue (bgmvolume, 1.0);
volume = 255;
}
CDAudio_SetVolume (volume);
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_PLAY_AUDIO;
cdRequest->status = 0;
cdRequest->x.playAudio.addressingMode = ADDRESS_MODE_RED_BOOK;
cdRequest->x.playAudio.startLocation = cd.track[track].start;
cdRequest->x.playAudio.sectors = cd.track[track].length;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
if (cdRequest->status & STATUS_ERROR_BIT) {
Con_DPrintf ("CDAudio_Play: track %u failed\n", track);
cd.valid = false;
playing = false;
return;
}
playing = true;
}
void
CDAudio_Stop (void)
{
if (!initialized || !enabled)
return;
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_STOP_AUDIO;
cdRequest->status = 0;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
wasPlaying = playing;
playing = false;
}
void
CDAudio_Pause (void)
{
CDAudio_Stop ();
}
void
CDAudio_Resume (void)
{
if (!initialized || !enabled)
return;
if (!cd.valid)
return;
if (!wasPlaying)
return;
cdRequest->headerLength = 13;
cdRequest->unit = 0;
cdRequest->command = COMMAND_RESUME_AUDIO;
cdRequest->status = 0;
regs.x.ax = 0x1510;
regs.x.cx = cdrom;
regs.x.es = cdRequestSegment;
regs.x.bx = cdRequestOffset;
dos_int86 (0x2f);
playing = true;
}
static void
CD_f (void)
{
char *command;
int ret;
int n;
int startAddress;
if (Cmd_Argc () < 2)
return;
command = Cmd_Argv (1);
if (Q_strcasecmp (command, "on") == 0) {
enabled = true;
return;
}
if (Q_strcasecmp (command, "off") == 0) {
if (playing)
CDAudio_Stop ();
enabled = false;
return;
}
if (Q_strcasecmp (command, "reset") == 0) {
enabled = true;
if (playing)
CDAudio_Stop ();
for (n = 0; n < 256; n++)
remap[n] = n;
CDAudio_Reset ();
CDAudio_GetAudioDiskInfo ();
return;
}
if (Q_strcasecmp (command, "remap") == 0) {
ret = Cmd_Argc () - 2;
if (ret <= 0) {
for (n = 1; n < 256; n++)
if (remap[n] != n)
Con_Printf (" %u -> %u\n", n, remap[n]);
return;
}
for (n = 1; n <= ret; n++)
remap[n] = Q_atoi (Cmd_Argv (n + 1));
return;
}
if (!cd.valid) {
Con_Printf ("No CD in player.\n");
return;
}
if (Q_strcasecmp (command, "play") == 0) {
CDAudio_Play (Q_atoi (Cmd_Argv (2)), false);
return;
}
if (Q_strcasecmp (command, "loop") == 0) {
CDAudio_Play (Q_atoi (Cmd_Argv (2)), true);
return;
}
if (Q_strcasecmp (command, "stop") == 0) {
CDAudio_Stop ();
return;
}
if (Q_strcasecmp (command, "pause") == 0) {
CDAudio_Pause ();
return;
}
if (Q_strcasecmp (command, "resume") == 0) {
CDAudio_Resume ();
return;
}
if (Q_strcasecmp (command, "eject") == 0) {
if (playing)
CDAudio_Stop ();
CDAudio_Eject ();
cd.valid = false;
return;
}
if (Q_strcasecmp (command, "info") == 0) {
Con_Printf ("%u tracks\n", cd.highTrack - cd.lowTrack + 1);
for (n = cd.lowTrack; n <= cd.highTrack; n++) {
ret = CDAudio_GetAudioTrackInfo (n, &startAddress);
Con_Printf ("Track %2u: %s at %2u:%02u\n", n,
ret ? "data " : "music", (startAddress >> 16) & 0xff,
(startAddress >> 8) & 0xff);
}
if (playing)
Con_Printf ("Currently %s track %u\n",
playLooping ? "looping" : "playing", playTrack);
Con_Printf ("Volume is %u\n", cdvolume);
CDAudio_MediaChange ();
Con_Printf ("Status %04x\n", cdRequest->status & 0xffff);
return;
}
}
void
CDAudio_Update (void)
{
int ret;
int newVolume;
static double lastUpdate;
if (!initialized || !enabled)
return;
if ((realtime - lastUpdate) < 0.25)
return;
lastUpdate = realtime;
if (mediaCheck) {
static double lastCheck;
if ((realtime - lastCheck) < 5.0)
return;
lastCheck = realtime;
ret = CDAudio_MediaChange ();
if (ret == MEDIA_CHANGED) {
Con_DPrintf ("CDAudio: media changed\n");
playing = false;
wasPlaying = false;
cd.valid = false;
CDAudio_GetAudioDiskInfo ();
return;
}
}
newVolume = (int) (bgmvolume->value * 255.0);
if (newVolume != cdvolume) {
if (newVolume < 0) {
Cvar_SetValue (bgmvolume, 0.0);
newVolume = 0;
} else if (newVolume > 255) {
Cvar_SetValue (bgmvolume, 1.0);
newVolume = 255;
}
CDAudio_SetVolume (newVolume);
}
if (playing) {
CDAudio_GetAudioStatus ();
if ((cdRequest->status & STATUS_BUSY_BIT) == 0) {
playing = false;
if (playLooping)
CDAudio_Play (playTrack, true);
}
}
}
int
CDAudio_Init (void)
{
char *memory;
int n;
if (cls.state == ca_dedicated)
return -1;
if (COM_CheckParm ("-nocdaudio"))
return -1;
if (COM_CheckParm ("-cdmediacheck"))
mediaCheck = true;
regs.x.ax = 0x1500;
regs.x.bx = 0;
dos_int86 (0x2f);
if (regs.x.bx == 0) {
Con_NotifyBox ("MSCDEX not loaded, music is\n"
"disabled. Use \"-nocdaudio\" if you\n"
"wish to avoid this message in the\n"
"future. See README.TXT for help.\n");
return -1;
}
if (regs.x.bx > 1)
Con_DPrintf ("CDAudio_Init: First CD-ROM drive will be used\n");
cdrom = regs.x.cx;
regs.x.ax = 0x150c;
regs.x.bx = 0;
dos_int86 (0x2f);
if (regs.x.bx == 0) {
Con_NotifyBox ("MSCDEX version 2.00 or later\n"
"required for music. See README.TXT\n" "for help.\n");
Con_DPrintf ("CDAudio_Init: MSCDEX version 2.00 or later required.\n");
return -1;
}
memory =
dos_getmemory (sizeof (struct cd_request) + sizeof (union readInfo_u));
if (memory == NULL) {
Con_DPrintf ("CDAudio_Init: Unable to allocate low memory.\n");
return -1;
}
cdRequest = (struct cd_request *) memory;
cdRequestSegment = ptr2real (cdRequest) >> 4;
cdRequestOffset = ptr2real (cdRequest) & 0xf;
readInfo = (union readInfo_u *) (memory + sizeof (struct cd_request));
readInfoSegment = ptr2real (readInfo) >> 4;
readInfoOffset = ptr2real (readInfo) & 0xf;
for (n = 0; n < 256; n++)
remap[n] = n;
initialized = true;
CDAudio_SetVolume (255);
if (CDAudio_GetAudioDiskInfo ()) {
Con_Printf ("CDAudio_Init: No CD in player.\n");
enabled = false;
}
Cmd_AddCommand ("cd", CD_f, "No Description");
Con_Printf ("CD Audio Initialized\n");
return 0;
}
void
CDAudio_Shutdown (void)
{
if (!initialized)
return;
CDAudio_Stop ();
}

View file

@ -1,416 +0,0 @@
/*
cd_linux.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <linux/cdrom.h>
#include "QF/qargs.h"
#include "QF/cmd.h"
#include "cdaudio.h"
#include "QF/console.h"
#include "sound.h"
#include "client.h"
static qboolean cdValid = false;
static qboolean playing = false;
static qboolean wasPlaying = false;
static qboolean initialized = false;
static qboolean enabled = true;
static qboolean playLooping = false;
static float cdvolume;
static byte remap[100];
static byte playTrack;
static byte maxTrack;
static int cdfile = -1;
static char cd_dev[64] = "/dev/cdrom";
static void
CDAudio_Eject (void)
{
if (cdfile == -1 || !enabled)
return; // no cd init'd
if (ioctl (cdfile, CDROMEJECT) == -1)
Con_DPrintf ("ioctl cdromeject failed\n");
}
static void
CDAudio_CloseDoor (void)
{
if (cdfile == -1 || !enabled)
return; // no cd init'd
if (ioctl (cdfile, CDROMCLOSETRAY) == -1)
Con_DPrintf ("ioctl cdromclosetray failed\n");
}
static int
CDAudio_GetAudioDiskInfo (void)
{
struct cdrom_tochdr tochdr;
cdValid = false;
if (ioctl (cdfile, CDROMREADTOCHDR, &tochdr) == -1) {
Con_DPrintf ("ioctl cdromreadtochdr failed\n");
return -1;
}
if (tochdr.cdth_trk0 < 1) {
Con_DPrintf ("CDAudio: no music tracks\n");
return -1;
}
cdValid = true;
maxTrack = tochdr.cdth_trk1;
return 0;
}
void
CDAudio_Play (byte track, qboolean looping)
{
struct cdrom_tocentry entry;
struct cdrom_ti ti;
if (cdfile == -1 || !enabled)
return;
if (!cdValid) {
CDAudio_GetAudioDiskInfo ();
if (!cdValid)
return;
}
track = remap[track];
if (track < 1 || track > maxTrack) {
Con_DPrintf ("CDAudio: Bad track number %u.\n", track);
return;
}
// don't try to play a non-audio track
entry.cdte_track = track;
entry.cdte_format = CDROM_MSF;
if (ioctl (cdfile, CDROMREADTOCENTRY, &entry) == -1) {
Con_DPrintf ("ioctl cdromreadtocentry failed\n");
return;
}
if (entry.cdte_ctrl == CDROM_DATA_TRACK) {
Con_Printf ("CDAudio: track %i is not audio\n", track);
return;
}
if (playing) {
if (playTrack == track)
return;
CDAudio_Stop ();
}
ti.cdti_trk0 = track;
ti.cdti_trk1 = track;
ti.cdti_ind0 = 1;
ti.cdti_ind1 = 99;
if (ioctl (cdfile, CDROMPLAYTRKIND, &ti) == -1) {
Con_DPrintf ("ioctl cdromplaytrkind failed\n");
return;
}
if (ioctl (cdfile, CDROMRESUME) == -1)
Con_DPrintf ("ioctl cdromresume failed\n");
playLooping = looping;
playTrack = track;
playing = true;
if (cdvolume == 0.0)
CDAudio_Pause ();
}
void
CDAudio_Stop (void)
{
if (cdfile == -1 || !enabled)
return;
if (!playing)
return;
if (ioctl (cdfile, CDROMSTOP) == -1)
Con_DPrintf ("ioctl cdromstop failed (%d)\n", errno);
wasPlaying = false;
playing = false;
}
void
CDAudio_Pause (void)
{
if (cdfile == -1 || !enabled)
return;
if (!playing)
return;
if (ioctl (cdfile, CDROMPAUSE) == -1)
Con_DPrintf ("ioctl cdrompause failed\n");
wasPlaying = playing;
playing = false;
}
void
CDAudio_Resume (void)
{
if (cdfile == -1 || !enabled)
return;
if (!cdValid)
return;
if (!wasPlaying)
return;
if (ioctl (cdfile, CDROMRESUME) == -1)
Con_DPrintf ("ioctl cdromresume failed\n");
playing = true;
}
static void
CD_f (void)
{
char *command;
int ret;
int n;
if (Cmd_Argc () < 2)
return;
command = Cmd_Argv (1);
if (strcasecmp (command, "on") == 0) {
enabled = true;
return;
}
if (strcasecmp (command, "off") == 0) {
if (playing)
CDAudio_Stop ();
enabled = false;
return;
}
if (strcasecmp (command, "reset") == 0) {
enabled = true;
if (playing)
CDAudio_Stop ();
for (n = 0; n < 100; n++)
remap[n] = n;
CDAudio_GetAudioDiskInfo ();
return;
}
if (strcasecmp (command, "remap") == 0) {
ret = Cmd_Argc () - 2;
if (ret <= 0) {
for (n = 1; n < 100; n++)
if (remap[n] != n)
Con_Printf (" %u -> %u\n", n, remap[n]);
return;
}
for (n = 1; n <= ret; n++)
remap[n] = atoi (Cmd_Argv (n + 1));
return;
}
if (strcasecmp (command, "close") == 0) {
CDAudio_CloseDoor ();
return;
}
if (!cdValid) {
CDAudio_GetAudioDiskInfo ();
if (!cdValid) {
Con_Printf ("No CD in player.\n");
return;
}
}
if (strcasecmp (command, "play") == 0) {
CDAudio_Play ((byte) atoi (Cmd_Argv (2)), false);
return;
}
if (strcasecmp (command, "loop") == 0) {
CDAudio_Play ((byte) atoi (Cmd_Argv (2)), true);
return;
}
if (strcasecmp (command, "stop") == 0) {
CDAudio_Stop ();
return;
}
if (strcasecmp (command, "pause") == 0) {
CDAudio_Pause ();
return;
}
if (strcasecmp (command, "resume") == 0) {
CDAudio_Resume ();
return;
}
if (strcasecmp (command, "eject") == 0) {
if (playing)
CDAudio_Stop ();
CDAudio_Eject ();
cdValid = false;
return;
}
if (strcasecmp (command, "info") == 0) {
Con_Printf ("%u tracks\n", maxTrack);
if (playing)
Con_Printf ("Currently %s track %u\n",
playLooping ? "looping" : "playing", playTrack);
else if (wasPlaying)
Con_Printf ("Paused %s track %u\n",
playLooping ? "looping" : "playing", playTrack);
Con_Printf ("Volume is %f\n", cdvolume);
return;
}
}
void
CDAudio_Update (void)
{
struct cdrom_subchnl subchnl;
static time_t lastchk;
if (!enabled)
return;
if (bgmvolume->value != cdvolume) {
if (cdvolume) {
Cvar_SetValue (bgmvolume, 0.0);
cdvolume = bgmvolume->value;
CDAudio_Pause ();
} else {
Cvar_SetValue (bgmvolume, 1.0);
cdvolume = bgmvolume->value;
CDAudio_Resume ();
}
}
if (playing && lastchk < time (NULL)) {
lastchk = time (NULL) + 2; // two seconds between chks
subchnl.cdsc_format = CDROM_MSF;
if (ioctl (cdfile, CDROMSUBCHNL, &subchnl) == -1) {
Con_DPrintf ("ioctl cdromsubchnl failed\n");
playing = false;
return;
}
if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
playing = false;
if (playLooping)
CDAudio_Play (playTrack, true);
}
}
}
int
CDAudio_Init (void)
{
int i;
if (cls.state == ca_dedicated)
return -1;
if (COM_CheckParm ("-nocdaudio"))
return -1;
if ((i = COM_CheckParm ("-cddev")) != 0 && i < com_argc - 1) {
strncpy (cd_dev, com_argv[i + 1], sizeof (cd_dev));
cd_dev[sizeof (cd_dev) - 1] = 0;
}
if ((cdfile = open (cd_dev, O_RDONLY)) == -1) {
Con_Printf ("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev,
errno);
cdfile = -1;
return -1;
}
for (i = 0; i < 100; i++)
remap[i] = i;
initialized = true;
enabled = true;
if (CDAudio_GetAudioDiskInfo ()) {
Con_Printf ("CDAudio_Init: No CD in player.\n");
cdValid = false;
}
Cmd_AddCommand ("cd", CD_f, "No Description");
Con_Printf ("CD Audio Initialized\n");
return 0;
}
void
CDAudio_Shutdown (void)
{
if (!initialized)
return;
CDAudio_Stop ();
close (cdfile);
cdfile = -1;
}

View file

@ -1,74 +0,0 @@
/*
cd_null.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
void
CDAudio_Play (byte track, qboolean looping)
{
}
void
CDAudio_Stop (void)
{
}
void
CDAudio_Pause (void)
{
}
void
CDAudio_Resume (void)
{
}
void
CDAudio_Update (void)
{
}
int
CDAudio_Init (void)
{
return 0;
}
void
CDAudio_Shutdown (void)
{
}

View file

@ -1,484 +0,0 @@
/*
cd_win.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
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:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <windows.h>
extern HWND mainwindow;
static qboolean cdValid = false;
static qboolean playing = false;
static qboolean wasPlaying = false;
static qboolean initialized = false;
static qboolean enabled = false;
static qboolean playLooping = false;
static float cdvolume;
static byte remap[100];
static byte cdrom;
static byte playTrack;
static byte maxTrack;
UINT wDeviceID;
static void
CDAudio_Eject (void)
{
DWORD dwReturn;
if (dwReturn =
mciSendCommand (wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD) NULL))
Con_DPrintf ("MCI_SET_DOOR_OPEN failed (%i)\n", dwReturn);
}
static void
CDAudio_CloseDoor (void)
{
DWORD dwReturn;
if (dwReturn =
mciSendCommand (wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD) NULL))
Con_DPrintf ("MCI_SET_DOOR_CLOSED failed (%i)\n", dwReturn);
}
static int
CDAudio_GetAudioDiskInfo (void)
{
DWORD dwReturn;
MCI_STATUS_PARMS mciStatusParms;
cdValid = false;
mciStatusParms.dwItem = MCI_STATUS_READY;
dwReturn =
mciSendCommand (wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT,
(DWORD) (LPVOID) & mciStatusParms);
if (dwReturn) {
Con_DPrintf ("CDAudio: drive ready test - get status failed\n");
return -1;
}
if (!mciStatusParms.dwReturn) {
Con_DPrintf ("CDAudio: drive not ready\n");
return -1;
}
mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
dwReturn =
mciSendCommand (wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT,
(DWORD) (LPVOID) & mciStatusParms);
if (dwReturn) {
Con_DPrintf ("CDAudio: get tracks - status failed\n");
return -1;
}
if (mciStatusParms.dwReturn < 1) {
Con_DPrintf ("CDAudio: no music tracks\n");
return -1;
}
cdValid = true;
maxTrack = mciStatusParms.dwReturn;
return 0;
}
void
CDAudio_Play (byte track, qboolean looping)
{
DWORD dwReturn;
MCI_PLAY_PARMS mciPlayParms;
MCI_STATUS_PARMS mciStatusParms;
if (!enabled)
return;
if (!cdValid) {
CDAudio_GetAudioDiskInfo ();
if (!cdValid)
return;
}
track = remap[track];
if (track < 1 || track > maxTrack) {
Con_DPrintf ("CDAudio: Bad track number %u.\n", track);
return;
}
// don't try to play a non-audio track
mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
mciStatusParms.dwTrack = track;
dwReturn =
mciSendCommand (wDeviceID, MCI_STATUS,
MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT,
(DWORD) (LPVOID) & mciStatusParms);
if (dwReturn) {
Con_DPrintf ("MCI_STATUS failed (%i)\n", dwReturn);
return;
}
if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO) {
Con_Printf ("CDAudio: track %i is not audio\n", track);
return;
}
// get the length of the track to be played
mciStatusParms.dwItem = MCI_STATUS_LENGTH;
mciStatusParms.dwTrack = track;
dwReturn =
mciSendCommand (wDeviceID, MCI_STATUS,
MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT,
(DWORD) (LPVOID) & mciStatusParms);
if (dwReturn) {
Con_DPrintf ("MCI_STATUS failed (%i)\n", dwReturn);
return;
}
if (playing) {
if (playTrack == track)
return;
CDAudio_Stop ();
}
mciPlayParms.dwFrom = MCI_MAKE_TMSF (track, 0, 0, 0);
mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track;
mciPlayParms.dwCallback = (DWORD) mainwindow;
dwReturn =
mciSendCommand (wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO,
(DWORD) (LPVOID) & mciPlayParms);
if (dwReturn) {
Con_DPrintf ("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
return;
}
playLooping = looping;
playTrack = track;
playing = true;
if (cdvolume == 0.0)
CDAudio_Pause ();
}
void
CDAudio_Stop (void)
{
DWORD dwReturn;
if (!enabled)
return;
if (!playing)
return;
if (dwReturn = mciSendCommand (wDeviceID, MCI_STOP, 0, (DWORD) NULL))
Con_DPrintf ("MCI_STOP failed (%i)", dwReturn);
wasPlaying = false;
playing = false;
}
void
CDAudio_Pause (void)
{
DWORD dwReturn;
MCI_GENERIC_PARMS mciGenericParms;
if (!enabled)
return;
if (!playing)
return;
mciGenericParms.dwCallback = (DWORD) mainwindow;
if (dwReturn =
mciSendCommand (wDeviceID, MCI_PAUSE, 0,
(DWORD) (LPVOID) & mciGenericParms))
Con_DPrintf ("MCI_PAUSE failed (%i)", dwReturn);
wasPlaying = playing;
playing = false;
}
void
CDAudio_Resume (void)
{
DWORD dwReturn;
MCI_PLAY_PARMS mciPlayParms;
if (!enabled)
return;
if (!cdValid)
return;
if (!wasPlaying)
return;
mciPlayParms.dwFrom = MCI_MAKE_TMSF (playTrack, 0, 0, 0);
mciPlayParms.dwTo = MCI_MAKE_TMSF (playTrack + 1, 0, 0, 0);
mciPlayParms.dwCallback = (DWORD) mainwindow;
dwReturn =
mciSendCommand (wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY,
(DWORD) (LPVOID) & mciPlayParms);
if (dwReturn) {
Con_DPrintf ("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
return;
}
playing = true;
}
static void
CD_f (void)
{
char *command;
int ret;
int n;
int startAddress;
if (Cmd_Argc () < 2)
return;
command = Cmd_Argv (1);
if (Q_strcasecmp (command, "on") == 0) {
enabled = true;
return;
}
if (Q_strcasecmp (command, "off") == 0) {
if (playing)
CDAudio_Stop ();
enabled = false;
return;
}
if (Q_strcasecmp (command, "reset") == 0) {
enabled = true;
if (playing)
CDAudio_Stop ();
for (n = 0; n < 100; n++)
remap[n] = n;
CDAudio_GetAudioDiskInfo ();
return;
}
if (Q_strcasecmp (command, "remap") == 0) {
ret = Cmd_Argc () - 2;
if (ret <= 0) {
for (n = 1; n < 100; n++)
if (remap[n] != n)
Con_Printf (" %u -> %u\n", n, remap[n]);
return;
}
for (n = 1; n <= ret; n++)
remap[n] = Q_atoi (Cmd_Argv (n + 1));
return;
}
if (Q_strcasecmp (command, "close") == 0) {
CDAudio_CloseDoor ();
return;
}
if (!cdValid) {
CDAudio_GetAudioDiskInfo ();
if (!cdValid) {
Con_Printf ("No CD in player.\n");
return;
}
}
if (Q_strcasecmp (command, "play") == 0) {
CDAudio_Play ((byte) Q_atoi (Cmd_Argv (2)), false);
return;
}
if (Q_strcasecmp (command, "loop") == 0) {
CDAudio_Play ((byte) Q_atoi (Cmd_Argv (2)), true);
return;
}
if (Q_strcasecmp (command, "stop") == 0) {
CDAudio_Stop ();
return;
}
if (Q_strcasecmp (command, "pause") == 0) {
CDAudio_Pause ();
return;
}
if (Q_strcasecmp (command, "resume") == 0) {
CDAudio_Resume ();
return;
}
if (Q_strcasecmp (command, "eject") == 0) {
if (playing)
CDAudio_Stop ();
CDAudio_Eject ();
cdValid = false;
return;
}
if (Q_strcasecmp (command, "info") == 0) {
Con_Printf ("%u tracks\n", maxTrack);
if (playing)
Con_Printf ("Currently %s track %u\n",
playLooping ? "looping" : "playing", playTrack);
else if (wasPlaying)
Con_Printf ("Paused %s track %u\n",
playLooping ? "looping" : "playing", playTrack);
Con_Printf ("Volume is %f\n", cdvolume);
return;
}
}
LONG
CDAudio_MessageHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (lParam != wDeviceID)
return 1;
switch (wParam) {
case MCI_NOTIFY_SUCCESSFUL:
if (playing) {
playing = false;
if (playLooping)
CDAudio_Play (playTrack, true);
}
break;
case MCI_NOTIFY_ABORTED:
case MCI_NOTIFY_SUPERSEDED:
break;
case MCI_NOTIFY_FAILURE:
Con_DPrintf ("MCI_NOTIFY_FAILURE\n");
CDAudio_Stop ();
cdValid = false;
break;
default:
Con_DPrintf ("Unexpected MM_MCINOTIFY type (%i)\n", wParam);
return 1;
}
return 0;
}
void
CDAudio_Update (void)
{
if (!enabled)
return;
if (bgmvolume->value != cdvolume) {
if (cdvolume) {
Cvar_SetValue (bgmvolume, 0.0);
cdvolume = bgmvolume->value;
CDAudio_Pause ();
} else {
Cvar_SetValue (bgmvolume, 1.0);
cdvolume = bgmvolume->value;
CDAudio_Resume ();
}
}
}
int
CDAudio_Init (void)
{
DWORD dwReturn;
MCI_OPEN_PARMS mciOpenParms;
MCI_SET_PARMS mciSetParms;
int n;
if (cls.state == ca_dedicated)
return -1;
if (COM_CheckParm ("-nocdaudio"))
return -1;
mciOpenParms.lpstrDeviceType = "cdaudio";
if (dwReturn =
mciSendCommand (0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE,
(DWORD) (LPVOID) & mciOpenParms)) {
Con_Printf ("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn);
return -1;
}
wDeviceID = mciOpenParms.wDeviceID;
// Set the time format to track/minute/second/frame (TMSF).
mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
if (dwReturn =
mciSendCommand (wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD) (LPVOID) & mciSetParms)) {
Con_Printf ("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn);
mciSendCommand (wDeviceID, MCI_CLOSE, 0, (DWORD) NULL);
return -1;
}
for (n = 0; n < 100; n++)
remap[n] = n;
initialized = true;
enabled = true;
if (CDAudio_GetAudioDiskInfo ()) {
Con_Printf ("CDAudio_Init: No CD in player.\n");
cdValid = false;
}
Cmd_AddCommand ("cd", CD_f, "No Description");
Con_Printf ("CD Audio Initialized\n");
return 0;
}
void
CDAudio_Shutdown (void)
{
if (!initialized)
return;
CDAudio_Stop ();
if (mciSendCommand (wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD) NULL))
Con_DPrintf ("CDAudio_Shutdown: MCI_CLOSE failed\n");
}

View file

@ -35,16 +35,16 @@
#include "client.h"
#include "host.h"
#include "QF/msg.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "cdaudio.h"
#include "QF/msg.h"
#include "QF/sys.h"
#include "sbar.h"
#include "screen.h"
#include "server.h"
#include "game.h"
#include "input.h"
#include "QF/cmd.h"
char *svc_strings[] = {
"svc_bad",

View file

@ -36,18 +36,18 @@
#include "server.h"
#include "view.h"
#include "chase.h"
#include "QF/qargs.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "cdaudio.h"
#include "QF/console.h"
#include "QF/keys.h"
#include "QF/msg.h"
#include "QF/qargs.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "sbar.h"
#include "QF/msg.h"
#include "vid.h"
#include "draw.h"
#include "input.h"
#include "QF/keys.h"
#include "QF/console.h"
#include "QF/sys.h"
#include "screen.h"
#include "gib.h"
#include "sv_progs.h"

View file

@ -33,22 +33,22 @@
#include <stdlib.h>
#include "quakedef.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/keys.h"
#include "QF/qargs.h"
#include "QF/qendian.h"
#include "QF/sound.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "winquake.h"
#include "QF/sys.h"
#include "d_local.h"
#include "resource.h"
#include "in_win.h"
#include "QF/keys.h"
#include "screen.h"
#include "wad.h"
#include "QF/cmd.h"
#include "QF/qendian.h"
#include "draw.h"
#include "QF/console.h"
#include "sound.h"
#include "cdaudio.h"
#include "QF/qargs.h"
#define MINIMUM_MEMORY 0x550000

View file

@ -44,7 +44,7 @@
#include "QF/cmd.h"
#include "QF/qendian.h"
#include "draw.h"
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "QF/console.h"
#include "sbar.h"

View file

@ -2,17 +2,17 @@
AUTOMAKE_OPTIONS= foreign
EXTRA_DIST = adivtab.h anorm_dots.h anorms.h asm_draw.h asm_i386.h block16.h \
block8.h bothdefs.h bspfile.h buildnum.h cdaudio.h checksum.h \
cl_cam.h cl_demo.h cl_ents.h cl_input.h cl_main.h cl_parse.h \
cl_pred.h cl_slist.h cl_tent.h client.h cmd.h commdef.h compat.h \
config.h.in console.h context_x11.h crc.h cvar.h d_iface.h \
d_ifacea.h d_local.h dga_check.h draw.h fbset.h fractalnoise.h gcc_attr.h \
gl_warp_sin.h glquake.h hash.h host.h in_win.h info.h input.h joystick.h \
keys.h link.h locs.h mathlib.h mdfour.h model.h modelgen.h \
msg.h net.h pcx.h pmove.h pr_comp.h progdefs.h progs.h protocol.h \
qargs.h qdefs.h qendian.h qfgl_ext.h qtypes.h quakeasm.h quakefs.h \
quakeio.h r_dynamic.h r_local.h r_shared.h render.h sbar.h screen.h \
server.h sizebuf.h skin.h sound.h spritegn.h sv_pr_cmds.h sys.h tga.h \
block8.h bothdefs.h bspfile.h buildnum.h checksum.h cl_cam.h \
cl_demo.h cl_ents.h cl_input.h cl_main.h cl_parse.h cl_pred.h \
cl_slist.h cl_tent.h client.h cmd.h commdef.h compat.h config.h.in \
console.h context_x11.h crc.h cvar.h d_iface.h d_ifacea.h d_local.h \
dga_check.h draw.h fbset.h fractalnoise.h gcc_attr.h gl_warp_sin.h \
glquake.h hash.h host.h in_win.h info.h input.h joystick.h keys.h \
link.h locs.h mathlib.h mdfour.h model.h modelgen.h msg.h net.h pcx.h \
pmove.h pr_comp.h progdefs.h progs.h protocol.h qargs.h qdefs.h \
qendian.h qfgl_ext.h qtypes.h quakeasm.h quakefs.h quakeio.h \
r_dynamic.h r_local.h r_shared.h render.h sbar.h screen.h server.h \
sizebuf.h skin.h sound.h spritegn.h sv_pr_cmds.h sys.h tga.h \
teamplay.h texture.h uint32.h va.h ver_check.h vid.h view.h wad.h \
winquake.h world.h zone.h \
\

View file

@ -40,7 +40,7 @@ EXTRA_PROGRAMS= qw-client-3dfx qw-client-fbdev \
qw-client-sgl qw-client-svga qw-client-wgl \
qw-client-x11 qw-server
noinst_LIBRARIES= libqfcd.a libqfjs.a libqfnet.a libqfsnd.a libqfsys_cl.a libqfsys_sv.a
noinst_LIBRARIES= libqfjs.a libqfnet.a libqfsnd.a libqfsys_cl.a libqfsys_sv.a
if PACKETLOG
packetlogger = net_packetlog.c
@ -86,7 +86,9 @@ server_SOURCES= sv_ccmds.c sv_cvar.c \
sv_user.c world.c $(world_ASM)
qw_server_SOURCES= $(common_SOURCES) $(server_SOURCES)
qw_server_LDADD= $(top_builddir)/libs/util/libQFutil.la $(top_builddir)/libs/gamecode/libQFgamecode.la -L. -lqfnet -lqfsys_sv $(NET_LIBS) $(DL_LIBS)
qw_server_LDADD= $(top_builddir)/libs/util/libQFutil.la \
$(top_builddir)/libs/gamecode/libQFgamecode.la \
-L. -lqfnet -lqfsys_sv $(NET_LIBS) $(DL_LIBS)
qw_server_DEPENDENCIES= libqfnet.a libqfsys_sv.a
#
@ -135,26 +137,6 @@ EXTRA_libqfsnd_a_SOURCES= snd_dma.c snd_mem.c snd_mix.c snd_alsa_0_5.c \
snd_alsa_0_9.c snd_oss.c snd_sdl.c snd_sgi.c \
snd_sun.c snd_win.c snd_null.c
#
# ... CD audio
#
if CDTYPE_LINUX
libqfcd_a_SOURCES= cd_linux.c
endif
if CDTYPE_SDL
libqfcd_a_SOURCES= cd_sdl.c
endif
if CDTYPE_SGI
libqfcd_a_SOURCES= cd_sgi.c
endif
if CDTYPE_WIN32
libqfcd_a_SOURCES= cd_win.c
endif
if CDTYPE_NULL
libqfcd_a_SOURCES= cd_null.c
endif
EXTRA_libqfcd_a_SOURCES= cd_dos.c cd_linux.c cd_sdl.c cd_sgi.c cd_win.c cd_null.c
#
# ... Joystick
#
@ -170,8 +152,12 @@ endif
libqfjs_a_CFLAGS= $(JOY_CFLAGS)
EXTRA_libqfjs_a_SOURCES= joy_linux.c joy_win.c joy_null.c
CLIENT_LIBS= $(top_builddir)/libs/util/libQFutil.la $(top_builddir)/libs/gamecode/libQFgamecode.la -L. -lqfnet -lqfsys_cl -lqfsnd -lqfcd -lqfjs $(SOUND_LIBS) $(NET_LIBS) $(CD_LIBS) $(JOY_LIBS)
CLIENT_LIB_DEPS= libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a
CLIENT_LIBS= $(top_builddir)/libs/util/libQFutil.la \
$(top_builddir)/libs/gamecode/libQFgamecode.la \
$(top_builddir)/libs/audio/cd/libQFcd.la \
-L. -lqfnet -lqfsys_cl -lqfsnd -lqfjs \
$(SOUND_LIBS) $(NET_LIBS) $(JOY_LIBS)
CLIENT_LIB_DEPS= libqfnet.a libqfsys_cl.a libqfsnd.a libqfjs.a
if ASM_ARCH
client_ASM= snd_mixa.S cl_math.S

View file

@ -60,7 +60,7 @@
#include "bothdefs.h"
#include "buildnum.h"
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "cl_cam.h"
#include "cl_demo.h"
#include "cl_ents.h"
@ -90,7 +90,7 @@
#include "sbar.h"
#include "screen.h"
#include "skin.h"
#include "sound.h"
#include "QF/sound.h"
#include "QF/sys.h"
#include "teamplay.h"
#include "vid.h"

View file

@ -44,7 +44,7 @@
#endif
#include "bothdefs.h"
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "cl_ents.h"
#include "cl_input.h"
#include "cl_main.h"
@ -61,7 +61,7 @@
#include "screen.h"
#include "sbar.h"
#include "skin.h"
#include "sound.h"
#include "QF/sound.h"
#include "teamplay.h"
#include "QF/va.h"
#include "view.h"

View file

@ -32,7 +32,7 @@
#include <stdlib.h>
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "d_local.h"
@ -44,7 +44,7 @@
#include "QF/qendian.h"
#include "resource.h"
#include "screen.h"
#include "sound.h"
#include "QF/sound.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "wad.h"

View file

@ -30,7 +30,7 @@
# include "config.h"
#endif
#include "cdaudio.h"
#include "QF/cdaudio.h"
#include "QF/cmd.h"
#include "QF/console.h"
#include "draw.h"
@ -43,7 +43,7 @@
#include "resource.h"
#include "sbar.h"
#include "screen.h"
#include "sound.h"
#include "QF/sound.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "winquake.h"