Tracker playback via DUMB
This commit is contained in:
parent
6ad3ae8e9c
commit
e7c85e960d
11 changed files with 255 additions and 457 deletions
|
@ -39,7 +39,7 @@ CC=gcc -m32
|
|||
BASE_CFLAGS=-Dstricmp=strcasecmp
|
||||
RELEASE_CFLAGS=$(BASE_CFLAGS)
|
||||
DEBUG_CFLAGS=$(BASE_CFLAGS) -g
|
||||
LDFLAGS=-lm -ldl
|
||||
LDFLAGS=-lm -ldl /usr/local/lib/libdumb.a
|
||||
XLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext -lXxf86dga
|
||||
XCFLAGS=-DX11
|
||||
|
||||
|
@ -143,7 +143,8 @@ X11_OBJS = \
|
|||
$(BUILDDIR)/obj/view.o \
|
||||
$(BUILDDIR)/obj/wad.o \
|
||||
$(BUILDDIR)/obj/world.o \
|
||||
$(BUILDDIR)/obj/cd_linux.o \
|
||||
$(BUILDDIR)/obj/tracker_linux.o \
|
||||
$(BUILDDIR)/obj/cd_null.o \
|
||||
$(BUILDDIR)/obj/sys_linux.o \
|
||||
$(BUILDDIR)/obj/vid_x.o \
|
||||
$(BUILDDIR)/obj/snd_dma.o \
|
||||
|
@ -376,7 +377,10 @@ $(BUILDDIR)/obj/wad.o : $(MOUNT_DIR)/wad.c
|
|||
$(BUILDDIR)/obj/world.o : $(MOUNT_DIR)/world.c
|
||||
$(DO_X11_CC)
|
||||
|
||||
$(BUILDDIR)/obj/cd_linux.o : $(MOUNT_DIR)/cd_linux.c
|
||||
$(BUILDDIR)/obj/tracker_linux.o : $(MOUNT_DIR)/tracker_linux.c
|
||||
$(DO_X11_CC)
|
||||
|
||||
$(BUILDDIR)/obj/cd_null.o : $(MOUNT_DIR)/cd_null.c
|
||||
$(DO_X11_CC)
|
||||
|
||||
$(BUILDDIR)/obj/sys_linux.o :$(MOUNT_DIR)/sys_linux.c
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
// stupid workaround file for playing back midis.
|
||||
|
||||
|
||||
|
||||
// BO
|
|
@ -140,4 +140,3 @@ LBPatch14:
|
|||
LBPatch15:
|
||||
movb %cl,1(%edi)
|
||||
addl $0x2,%edi
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define MAX_MAP_PLANES 32767
|
||||
#define MAX_MAP_NODES 32767 // because negative shorts are contents
|
||||
#define MAX_MAP_CLIPNODES 65535 //
|
||||
#define MAX_MAP_CLIPNODES 65535
|
||||
#define MAX_MAP_LEAFS 32768
|
||||
#define MAX_MAP_VERTS 65535
|
||||
#define MAX_MAP_FACES 65535
|
||||
|
@ -58,7 +58,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define MAX_MAP_PLANES 32767
|
||||
#define MAX_MAP_NODES 32767 // because negative shorts are contents
|
||||
#define MAX_MAP_CLIPNODES 32767 //
|
||||
#define MAX_MAP_CLIPNODES 32767
|
||||
#define MAX_MAP_LEAFS 8192
|
||||
#define MAX_MAP_VERTS 65535
|
||||
#define MAX_MAP_FACES 32767
|
||||
|
@ -165,8 +165,6 @@ typedef struct
|
|||
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
|
||||
} dplane_t;
|
||||
|
||||
|
||||
|
||||
#define CONTENTS_EMPTY -1
|
||||
#define CONTENTS_SOLID -2
|
||||
#define CONTENTS_WATER -3
|
||||
|
@ -176,20 +174,19 @@ typedef struct
|
|||
#define CONTENTS_ORIGIN -7 // removed at csg time
|
||||
#define CONTENTS_CLIP -8 // changed to contents_solid
|
||||
|
||||
#define CONTENTS_CURRENT_0 -9
|
||||
#define CONTENTS_CURRENT_90 -10
|
||||
#define CONTENTS_CURRENT_0 -9
|
||||
#define CONTENTS_CURRENT_90 -10
|
||||
#define CONTENTS_CURRENT_180 -11
|
||||
#define CONTENTS_CURRENT_270 -12
|
||||
#define CONTENTS_CURRENT_UP -13
|
||||
#define CONTENTS_CURRENT_UP -13
|
||||
#define CONTENTS_CURRENT_DOWN -14
|
||||
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||
typedef struct
|
||||
{
|
||||
int planenum;
|
||||
int planenum;
|
||||
short children[2]; // negative numbers are -(leafs+1), not nodes
|
||||
short mins[3]; // for sphere culling
|
||||
short mins[3]; // for sphere culling
|
||||
short maxs[3];
|
||||
unsigned short firstface;
|
||||
unsigned short numfaces; // counting both sides
|
||||
|
@ -197,18 +194,18 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
int planenum;
|
||||
int planenum;
|
||||
short children[2]; // negative numbers are contents
|
||||
} dclipnode_t;
|
||||
|
||||
|
||||
typedef struct texinfo_s
|
||||
{
|
||||
float vecs[2][4]; // [s/t][xyz offset]
|
||||
int miptex;
|
||||
int flags;
|
||||
float vecs[2][4]; // [s/t][xyz offset]
|
||||
int miptex;
|
||||
int flags;
|
||||
} texinfo_t;
|
||||
#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
|
||||
#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision
|
||||
|
||||
// note that edge 0 is never used, because negative edge nums are used for
|
||||
// counterclockwise use of the edge in a face
|
||||
|
@ -232,21 +229,19 @@ typedef struct
|
|||
int lightofs; // start of [numstyles*surfsize] samples
|
||||
} dface_t;
|
||||
|
||||
|
||||
|
||||
#define AMBIENT_WATER 0
|
||||
#define AMBIENT_SKY 1
|
||||
#define AMBIENT_SKY 1
|
||||
#define AMBIENT_SLIME 2
|
||||
#define AMBIENT_LAVA 3
|
||||
|
||||
#define NUM_AMBIENTS 4 // automatic ambient sounds
|
||||
#define NUM_AMBIENTS 4 // automatic ambient sounds
|
||||
|
||||
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
|
||||
// all other leafs need visibility info
|
||||
typedef struct
|
||||
{
|
||||
int contents;
|
||||
int visofs; // -1 = no visibility info
|
||||
int visofs; // -1 = no visibility info
|
||||
|
||||
short mins[3]; // for frustum culling
|
||||
short maxs[3];
|
||||
|
@ -265,7 +260,6 @@ typedef struct
|
|||
#define ANGLE_UP -1
|
||||
#define ANGLE_DOWN -2
|
||||
|
||||
|
||||
// the utilities get to be lazy and just use large static arrays
|
||||
|
||||
extern int nummodels;
|
||||
|
|
|
@ -1,416 +0,0 @@
|
|||
/*
|
||||
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 the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
|
||||
// rights reserved.
|
||||
|
||||
#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 "quakedef.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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
void CDAudio_Update(void)
|
||||
{
|
||||
struct cdrom_subchnl subchnl;
|
||||
static time_t lastchk;
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if (bgmvolume->value != cdvolume)
|
||||
{
|
||||
if (cdvolume)
|
||||
{
|
||||
Cvar_Set (bgmvolume, "0");
|
||||
cdvolume = bgmvolume->value;
|
||||
CDAudio_Pause ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_Set (bgmvolume, "1");
|
||||
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);
|
||||
|
||||
Con_Printf("CD Audio Initialized\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_Shutdown(void)
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
CDAudio_Stop();
|
||||
close(cdfile);
|
||||
cdfile = -1;
|
||||
}
|
|
@ -17,12 +17,6 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifdef DUMB
|
||||
//typedef struct DUMBFILE DUMBERFILE;
|
||||
struct DUMBFILE_SYSTEM *duhfile;
|
||||
struct DUH *duhsong;
|
||||
//struct DUH *duhgame; // experimental ingame sounding
|
||||
#endif
|
||||
int CDAudio_Init(void);
|
||||
void CDAudio_Play(byte track, qboolean looping);
|
||||
void CDAudio_Stop(void);
|
||||
|
|
|
@ -1459,14 +1459,14 @@ void CL_ParseServerMessage (void)
|
|||
|
||||
if (cl.paused)
|
||||
{
|
||||
CDAudio_Pause ();
|
||||
Tracker_Pause ();
|
||||
#ifdef _WIN32
|
||||
VID_HandlePause (true);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
CDAudio_Resume ();
|
||||
Tracker_Resume ();
|
||||
#ifdef _WIN32
|
||||
VID_HandlePause (false);
|
||||
#endif
|
||||
|
@ -1527,9 +1527,9 @@ void CL_ParseServerMessage (void)
|
|||
cl.cdtrack = MSG_ReadByte ();
|
||||
cl.looptrack = MSG_ReadByte ();
|
||||
if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
|
||||
CDAudio_Play ((byte)cls.forcetrack, true);
|
||||
Tracker_Play ((byte)cls.forcetrack, true);
|
||||
else
|
||||
CDAudio_Play ((byte)cl.cdtrack, true);
|
||||
Tracker_Play ((byte)cl.cdtrack, true);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -954,6 +954,7 @@ void _Host_Frame (float time)
|
|||
MIDI_Update(); // leilei - update our midi
|
||||
#endif
|
||||
CDAudio_Update();
|
||||
Tracker_Update();
|
||||
|
||||
if (host_speeds->value)
|
||||
{
|
||||
|
@ -1439,7 +1440,7 @@ void Host_Init (quakeparms_t *parms)
|
|||
//TW CDAudio_Init_Cvars(); // 2001-09-18 New cvar system by Maddes (Init)
|
||||
#ifndef BENCH
|
||||
CDAudio_Init ();
|
||||
|
||||
Tracker_Init ();
|
||||
Sbar_Init ();
|
||||
#endif
|
||||
CL_Init ();
|
||||
|
@ -1498,6 +1499,7 @@ void Host_Shutdown(void)
|
|||
Host_WriteConfiguration ();
|
||||
#endif
|
||||
CDAudio_Shutdown ();
|
||||
Tracker_Shutdown ();
|
||||
NET_Shutdown ();
|
||||
S_Shutdown();
|
||||
IN_Shutdown ();
|
||||
|
|
|
@ -463,6 +463,7 @@ typedef struct
|
|||
#include "menu.h"
|
||||
#include "crc.h"
|
||||
#include "cdaudio.h"
|
||||
#include "tracker.h"
|
||||
|
||||
#ifdef GLQUAKE
|
||||
#include "glquake.h"
|
||||
|
|
26
WinQuake/tracker.h
Normal file
26
WinQuake/tracker.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
Copyright (C) 2015 Marco "eukara" Hladik
|
||||
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.
|
||||
|
||||
*/
|
||||
int Tracker_Init(void);
|
||||
void Tracker_Play(byte track, qboolean looping);
|
||||
void Tracker_Stop(void);
|
||||
void Tracker_Pause(void);
|
||||
void Tracker_Resume(void);
|
||||
void Tracker_Shutdown(void);
|
||||
void Tracker_Update(void);
|
199
WinQuake/tracker_linux.c
Normal file
199
WinQuake/tracker_linux.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
Copyright (C) 2015 Marco "eukara" Hladik
|
||||
|
||||
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 "quakedef.h"
|
||||
#include <dumb.h>
|
||||
|
||||
// eukara - added in tracker playback using DUMB - UNIX ONLY!
|
||||
char name[256];
|
||||
DUH *trackmod; // The music file ~eukara
|
||||
DUH_SIGRENDERER *sr; // The DUMB renderer
|
||||
FILE *oss_device; // output device (by default /dev/dsp for OSS)
|
||||
|
||||
// Set up the renderer options
|
||||
static int depth = 16; // by default 16bit, only affects output not internal 32bit processing
|
||||
static int unsign = 0;
|
||||
static int freq = 22050;// 22050 is enough for most music
|
||||
static int n_channels = 2; // stereo action
|
||||
static float cdvolume = 0.8f; // default cdvolume...?
|
||||
static float delay = 0.0f; // You shouldn't need to touch this.
|
||||
static float delta; // For the speed, combination of frequency
|
||||
static int bufsize;
|
||||
static qboolean playing = false;// Is the music playing or not?
|
||||
|
||||
union {
|
||||
short s16[2048]; // was 8192
|
||||
char s8[4096]; // was twice as the thing above
|
||||
} buffer;
|
||||
|
||||
void Tracker_Play(byte track, qboolean looping)
|
||||
{
|
||||
dumb_register_stdfiles(); // Initialize loading files
|
||||
|
||||
// Attempt to load every format imaginable, TODO: better method?
|
||||
sprintf (name, "%s/music/track%d.it", com_gamedir, track);
|
||||
trackmod = dumb_load_it(name);
|
||||
if (!trackmod) {
|
||||
sprintf (name, "%s/music/track%d.xm", com_gamedir, track);
|
||||
trackmod = dumb_load_xm(name);
|
||||
if (!trackmod) {
|
||||
sprintf (name, "%s/music/track%d.s3m", com_gamedir, track);
|
||||
trackmod = dumb_load_s3m(name);
|
||||
if (!trackmod) {
|
||||
sprintf (name, "%s/music/track%d.mod", com_gamedir, track);
|
||||
trackmod = dumb_load_mod(name);
|
||||
if (!trackmod) {
|
||||
fprintf(stderr, "Unable to open %s!\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let us know which track you are playing
|
||||
Con_Printf("Playing %s\n", name);
|
||||
sr = duh_start_sigrenderer(trackmod, 0, n_channels, 0); // start rendering, action happens in Tracker_Update
|
||||
if (!sr) { // If it doesn't want to render, stop it before it's too late
|
||||
unload_duh(trackmod); // Unload the track safely
|
||||
fprintf(stderr, "Unable to play file!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
delta = 61536.0f / freq; // This affects the speed
|
||||
bufsize = depth == 16 ? 2048 : 4096; // Buffer size, small buffer = laggy music; big buff = laggy game
|
||||
bufsize /= n_channels; // Tell him we are hopefully stereo
|
||||
playing = true; // Announce that we have a track playing
|
||||
}
|
||||
|
||||
void Tracker_Stop(void)
|
||||
{
|
||||
playing = false; // Not playing the song anymore to prevent Tracker_Update
|
||||
Con_Printf("Stopping %s\n", name); // Just print that we are stopping whatever track
|
||||
duh_end_sigrenderer(sr); // Stop the renderer safely
|
||||
unload_duh(trackmod); // Unload the song!
|
||||
}
|
||||
|
||||
void Tracker_Pause(void)
|
||||
{
|
||||
playing = false; // Prevent from Tracker_Update from happening
|
||||
Con_Printf("Paused %s\n", name);
|
||||
}
|
||||
|
||||
void Tracker_Resume(void)
|
||||
{
|
||||
// Just making sure we aren't calling Tracker_Update with no song...
|
||||
if(!trackmod || !sr)
|
||||
return;
|
||||
|
||||
playing = true; // Tracker_Update should now be triggered again
|
||||
Con_Printf("Resuming %s\n", name);
|
||||
}
|
||||
|
||||
|
||||
static void Tracker_f (void)
|
||||
{
|
||||
char *command;
|
||||
int ret;
|
||||
int n;
|
||||
|
||||
if (Cmd_Argc() < 2)
|
||||
return;
|
||||
|
||||
command = Cmd_Argv (1);
|
||||
|
||||
if (Q_strcasecmp(command, "play") == 0)
|
||||
{
|
||||
Tracker_Play((byte)Q_atoi(Cmd_Argv (2)), false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "stop") == 0)
|
||||
{
|
||||
Tracker_Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "volume") == 0)
|
||||
{
|
||||
cdvolume = (float)Q_atoi(Cmd_Argv (2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "frequency") == 0)
|
||||
{
|
||||
freq = (int)Q_atoi(Cmd_Argv (2));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "pause") == 0)
|
||||
{
|
||||
Tracker_Pause();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "resume") == 0)
|
||||
{
|
||||
Tracker_Resume();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Tracker_Update(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Only update when a song is playing and the renderer works...
|
||||
if (!sr)
|
||||
return;
|
||||
if(playing == false)
|
||||
return;
|
||||
|
||||
// Render the song
|
||||
int l = duh_render(sr, depth, unsign, cdvolume, delta, bufsize, &buffer);
|
||||
if (depth == 16) { // On 16 bit, fill the buffer accordingly
|
||||
for (i = 0; i < l * n_channels; i++) {
|
||||
short val = buffer.s16[i];
|
||||
buffer.s8[i*2] = (char)val;
|
||||
buffer.s8[i*2+1] = (char)(val >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Write this into the engine's soundbuffer instead for speed!
|
||||
fwrite(buffer.s8, 1, l * n_channels * (depth >> 3), oss_device); // write it into OSS' device
|
||||
}
|
||||
|
||||
int Tracker_Init(void)
|
||||
{
|
||||
oss_device = fopen("/dev/dsp", "wb"); // /dev/dsp is the standard OSS output
|
||||
if(oss_device == NULL) // just get out if there's none
|
||||
return 0;
|
||||
|
||||
Cmd_AddCommand ("dumb", Tracker_f); // link DUMB
|
||||
Con_Printf("DUMB Initialized\n"); // Tell them we are ready
|
||||
return 1; // return that we have successfully initialised
|
||||
}
|
||||
|
||||
void Tracker_Shutdown(void)
|
||||
{
|
||||
Tracker_Stop(); // First stop the track
|
||||
fclose(oss_device); // Close the device
|
||||
dumb_exit(); // Kill DUMB
|
||||
}
|
Loading…
Reference in a new issue