Commit 8759023d authored by Adriano Moura's avatar Adriano Moura
Browse files

Changes to acomodate quakespasm audio.

The FS functions are the bulk of this one.
parent 7988a7e1
......@@ -61,6 +61,7 @@ SOURCES_C := \
$(CORE_DIR)/common/sbar.c \
$(CORE_DIR)/common/screen.c \
$(CORE_DIR)/common/shell.c \
$(CORE_DIR)/common/bgmusic.c \
$(CORE_DIR)/common/snd_dma.c \
$(CORE_DIR)/common/snd_mem.c \
$(CORE_DIR)/common/snd_mix.c \
......
#include "quakedef.h"
#include "console.h"
#include "common.h"
#include "cmd.h"
#include "sound.h"
#include "cdaudio.h"
#include "bgmusic.h"
qboolean BGM_Init (void) {
return;
}
void BGM_Shutdown (void) {
return;
}
void BGM_Play (const char *filename) {
return;
}
void BGM_Stop (void) {
return;
}
void BGM_Update (void) {
return;
}
void BGM_Pause (void) {
return;
}
void BGM_Resume (void) {
return;
}
void BGM_PlayCDtrack (byte track, qboolean looping) {
return;
}
/*
* Background music handling for Quakespasm (adapted from uHexen2)
* Handles streaming music as raw sound samples and runs the midi driver
*
* Copyright (C) 1999-2005 Id Software, Inc.
* Copyright (C) 2010-2012 O.Sezer <sezero@users.sourceforge.net>
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef _BGMUSIC_H_
#define _BGMUSIC_H_
extern qboolean bgmloop;
extern cvar_t bgm_extmusic;
qboolean BGM_Init (void);
void BGM_Shutdown (void);
void BGM_Play (const char *filename);
void BGM_Stop (void);
void BGM_Update (void);
void BGM_Pause (void);
void BGM_Resume (void);
void BGM_PlayCDtrack (byte track, qboolean looping);
#endif /* _BGMUSIC_H_ */
......@@ -47,22 +47,6 @@ static float cdvolume;
static void CDAudio_SetVolume_f(struct cvar_s *var);
cvar_t bgmvolume = {
"bgmvolume",
"1",
true,
#ifdef NQ_HACK
0,
#endif
#ifdef QW_HACK
0,
#endif
0,
CDAudio_SetVolume_f,
NULL,
NULL
};
static void
CDAudio_Eject(void)
{
......@@ -164,31 +148,31 @@ CDAudio_Resume(void)
}
void
int
CDAudio_Play(byte track, qboolean looping)
{
int err;
if (!enabled)
return;
return -1;
if (!cdValid) {
CDAudio_GetAudioDiskInfo();
if (!cdValid)
return;
return -1;
}
track = remap[track];
if (track < 1 || track > maxTrack) {
Con_DPrintf("CDAudio: Bad track number %u.\n", track);
return;
return -1;
}
if (!CDDrv_IsAudioTrack(track)) {
Con_Printf("CDAudio: track %i is not audio\n", track);
return;
return -1;
}
if (playing) {
if (playTrack == track)
return;
return -1;
CDAudio_Stop();
}
err = CDDrv_PlayTrack(track);
......@@ -199,6 +183,7 @@ CDAudio_Play(byte track, qboolean looping)
}
if (cdvolume == 0.0)
CDAudio_Pause();
return 0;
}
void
......@@ -348,7 +333,6 @@ CDAudio_Init(void)
Con_Printf("CDAudio_Init: No CD in player.\n");
cdValid = false;
}
Cvar_RegisterVariable(&bgmvolume);
return 0;
}
......
......@@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "qtypes.h"
int CDAudio_Init(void);
void CDAudio_Play(byte track, qboolean looping);
int CDAudio_Play(byte track, qboolean looping);
void CDAudio_Stop(void);
void CDAudio_Pause(void);
void CDAudio_Resume(void);
......
......@@ -33,6 +33,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "screen.h"
#include "server.h"
#include "sound.h"
#include "bgmusic.h"
#include "cdaudio.h"
/* we need to declare some mouse variables here,
* because the menu system
......@@ -144,6 +146,8 @@ void CL_Disconnect(void)
/* stop sounds (especially looping!) */
S_StopAllSounds(true);
BGM_Stop();
CDAudio_Stop();
/* Clear up view, remove palette shift */
scr_centertime_off = 0;
......
......@@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "screen.h"
#include "server.h"
#include "sound.h"
#include "bgmusic.h"
#include "sys.h"
static const char *svc_strings[] = {
......@@ -1118,9 +1119,15 @@ CL_ParseServerMessage(void)
case svc_setpause:
cl.paused = MSG_ReadByte();
if (cl.paused)
{
CDAudio_Pause();
BGM_Pause();
}
else
{
CDAudio_Resume();
BGM_Resume();
}
break;
case svc_signonnum:
......@@ -1160,9 +1167,9 @@ CL_ParseServerMessage(void)
cl.looptrack = MSG_ReadByte();
if ((cls.demoplayback || cls.demorecording)
&& (cls.forcetrack != -1))
CDAudio_Play((byte)cls.forcetrack, true);
else
CDAudio_Play((byte)cl.cdtrack, true);
BGM_PlayCDtrack ((byte)cls.forcetrack, true);
else
BGM_PlayCDtrack ((byte)cl.cdtrack, true);
break;
case svc_intermission:
......
/*
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2002-2009 John Fitzgibbons and others
Copyright (C) 2010-2014 QuakeSpasm developers
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
......@@ -25,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#ifdef NQ_HACK
#include "quakedef.h"
......@@ -861,7 +864,7 @@ COM_FileExtension
============
*/
#ifdef NQ_HACK
static const char *COM_FileExtension(const char *in)
const char *COM_FileExtension(const char *in)
{
static char exten[8];
const char *dot;
......@@ -1394,7 +1397,7 @@ If the requested file is inside a packfile, a new FILE * will be opened
into the file.
===========
*/
int file_from_pak; // global indicating file came from pack file
int file_from_pak; // global indicating file came from pack file
int COM_FOpenFile(const char *filename, FILE **file)
{
......@@ -1452,6 +1455,61 @@ int COM_FOpenFile(const char *filename, FILE **file)
return -1;
}
/*
===========
COM_FileExists
Returns whether the file is found in the quake filesystem.
===========
*/
qboolean COM_FileExists (const char *filename)
{
searchpath_t *search;
char path[MAX_OSPATH];
pack_t *pak;
int i;
int findtime;
file_from_pak = 0;
// search through the path, one element at a time
for (search = com_searchpaths; search; search = search->next)
{
// is the element a pak file?
if (search->pack)
{
// look through all the pak file elements
pak = search->pack;
for (i = 0; i < pak->numfiles; i++)
if (!strcmp(pak->files[i].name, filename))
{ // found it!
com_filesize = pak->files[i].filelen;
file_from_pak = 1;
return true;
}
} else {
// check a file in the directory tree
if (!static_registered)
{
// if not a registered version, don't ever go beyond base
if (strchr(filename, '/') || strchr(filename, '\\'))
continue;
}
snprintf(path, sizeof(path), "%s/%s", search->filename, filename);
findtime = Sys_FileTime(path);
if (findtime == -1)
continue;
return true;
}
}
Sys_Printf("FindFile: can't find %s\n", filename);
com_filesize = -1;
return false;
}
static void COM_ScanDirDir(struct stree_root *root, struct RDIR *dir, const char *pfx,
const char *ext, qboolean stripext)
{
......@@ -2417,3 +2475,173 @@ int build_number(void)
return b;
}
#endif /* QW_HACK */
/* The following FS_*() stdio replacements are necessary if one is
* to perform non-sequential reads on files reopened on pak files
* because we need the bookkeeping about file start/end positions.
* Allocating and filling in the fshandle_t structure is the users'
* responsibility when the file is initially opened. */
size_t FS_fread(void *ptr, size_t size, size_t nmemb, fshandle_t *fh)
{
long byte_size;
long bytes_read;
size_t nmemb_read;
if (!fh) {
errno = EBADF;
return 0;
}
if (!ptr) {
errno = EFAULT;
return 0;
}
if (!size || !nmemb) { /* no error, just zero bytes wanted */
errno = 0;
return 0;
}
byte_size = nmemb * size;
if (byte_size > fh->length - fh->pos) /* just read to end */
byte_size = fh->length - fh->pos;
bytes_read = fread(ptr, 1, byte_size, fh->file);
fh->pos += bytes_read;
/* fread() must return the number of elements read,
* not the total number of bytes. */
nmemb_read = bytes_read / size;
/* even if the last member is only read partially
* it is counted as a whole in the return value. */
if (bytes_read % size)
nmemb_read++;
return nmemb_read;
}
int FS_fseek(fshandle_t *fh, long offset, int whence)
{
/* I don't care about 64 bit off_t or fseeko() here.
* the quake/hexen2 file system is 32 bits, anyway. */
int ret;
if (!fh) {
errno = EBADF;
return -1;
}
/* the relative file position shouldn't be smaller
* than zero or bigger than the filesize. */
switch (whence)
{
case SEEK_SET:
break;
case SEEK_CUR:
offset += fh->pos;
break;
case SEEK_END:
offset = fh->length + offset;
break;
default:
errno = EINVAL;
return -1;
}
if (offset < 0) {
errno = EINVAL;
return -1;
}
if (offset > fh->length) /* just seek to end */
offset = fh->length;
ret = fseek(fh->file, fh->start + offset, SEEK_SET);
if (ret < 0)
return ret;
fh->pos = offset;
return 0;
}
int FS_fclose(fshandle_t *fh)
{
if (!fh) {
errno = EBADF;
return -1;
}
return fclose(fh->file);
}
long FS_ftell(fshandle_t *fh)
{
if (!fh) {
errno = EBADF;
return -1;
}
return fh->pos;
}
void FS_rewind(fshandle_t *fh)
{
if (!fh) return;
clearerr(fh->file);
fseek(fh->file, fh->start, SEEK_SET);
fh->pos = 0;
}
int FS_feof(fshandle_t *fh)
{
if (!fh) {
errno = EBADF;
return -1;
}
if (fh->pos >= fh->length)
return -1;
return 0;
}
int FS_ferror(fshandle_t *fh)
{
if (!fh) {
errno = EBADF;
return -1;
}
return ferror(fh->file);
}
int FS_fgetc(fshandle_t *fh)
{
if (!fh) {
errno = EBADF;
return EOF;
}
if (fh->pos >= fh->length)
return EOF;
fh->pos += 1;
return fgetc(fh->file);
}
char *FS_fgets(char *s, int size, fshandle_t *fh)
{
char *ret;
if (FS_feof(fh))
return NULL;
if (size > (fh->length - fh->pos) + 1)
size = (fh->length - fh->pos) + 1;
ret = fgets(s, size, fh->file);
fh->pos = ftell(fh->file) - fh->start;
return ret;
}
long FS_filelength (fshandle_t *fh)
{
if (!fh) {
errno = EBADF;
return -1;
}
return fh->length;
}
......@@ -181,6 +181,8 @@ void COM_Init(void);
void COM_InitArgv(int argc, const char **argv);
const char *COM_SkipPath(const char *pathname);
const char *COM_FileExtension(const char *in);
qboolean COM_FileExists(const char *filename);
void COM_StripExtension(char *filename);
void COM_FileBase(const char *in, char *out, size_t buflen);
void COM_DefaultExtension(char *path, const char *extension);
......@@ -197,6 +199,7 @@ struct cache_user_s;
extern char com_basedir[MAX_OSPATH];
extern char com_gamedir[MAX_OSPATH];
extern int file_from_pak; // global indicating that file came from a pak
void COM_WriteFile(const char *filename, const void *data, int len);
int COM_FOpenFile(const char *filename, FILE **file);
......@@ -243,4 +246,30 @@ extern char gamedirfile[];
extern byte palmap2[64][64][64]; // 18-bit lookup table
/* The following FS_*() stdio replacements are necessary if one is
* to perform non-sequential reads on files reopened on pak files
* because we need the bookkeeping about file start/end positions.
* Allocating and filling in the fshandle_t structure is the users'
* responsibility when the file is initially opened. */
typedef struct _fshandle_t
{
FILE *file;
qboolean pak; /* is the file read from a pak */
long start; /* file or data start position */
long length; /* file or data size */
long pos; /* current position relative to start */
} fshandle_t;
size_t FS_fread(void *ptr, size_t size, size_t nmemb, fshandle_t *fh);
int FS_fseek(fshandle_t *fh, long offset, int whence);
long FS_ftell(fshandle_t *fh);
void FS_rewind(fshandle_t *fh);
int FS_feof(fshandle_t *fh);
int FS_ferror(fshandle_t *fh);
int FS_fclose(fshandle_t *fh);
int FS_fgetc(fshandle_t *fh);
char *FS_fgets(char *s, int size, fshandle_t *fh);
long FS_filelength (fshandle_t *fh);
#endif /* COMMON_H */
......@@ -306,6 +306,9 @@ void Cvar_RegisterVariable(cvar_t *variable)
value[511] = '\0';
variable->string = (const char*)Z_Malloc(1);
if (!(variable->flags & CVAR_CALLBACK))
variable->callback = NULL;
/*
* FIXME (BARF) - readonly cvars need to be initialised
* developer 1 allows set
......@@ -317,6 +320,21 @@ void Cvar_RegisterVariable(cvar_t *variable)
developer.value = old_developer;
}
/*
============
Cvar_SetCallback
Set a callback function to the var
============
*/
void Cvar_SetCallback (cvar_t *var, cvar_callback func)
{
var->callback = func;
if (func)
var->flags |= CVAR_CALLBACK;
else var->flags &= ~CVAR_CALLBACK;
}
/*
============
Cvar_Command
......
......@@ -103,6 +103,7 @@ typedef struct cvar_s {
#define CVAR_DEVELOPER (1U << 0) /* can't set during normal play */
#define CVAR_OBSOLETE (1U << 1) /* cvar has no effect; basically removed */
#define CVAR_CALLBACK (1U << 2)
/*
* register a cvar that already has the name, string, and optionally the
......@@ -110,6 +111,8 @@ typedef struct cvar_s {
*/
void Cvar_RegisterVariable(cvar_t *variable);
void Cvar_SetCallback(cvar_t *var, cvar_callback func);
/* equivelant to "<name> <variable>" typed at the console */
void Cvar_Set(const char *var_name, const char *value);
......
......@@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "screen.h"
#include "server.h"
#include "sound.h"
#include "bgmusic.h"
#include "sys.h"
#include "view.h"
#include "wad.h"
......@@ -816,6 +817,7 @@ Host_Init(quakeparms_t *parms)
S_Init();
CDAudio_Init();
BGM_Init();
Sbar_Init();
CL_Init();
......@@ -865,6 +867,7 @@ Host_Shutdown(void)
CDAudio_Shutdown();
NET_Shutdown();
BGM_Shutdown();
S_Shutdown();
IN_Shutdown();
......
......@@ -45,7 +45,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "d_local.h"
#include "sys.h"
#include "qtypes.h"
#include "sound.h"
#include "bgmusic.h"
#include "keys.h"
#include "cdaudio_driver.h"
......@@ -1138,6 +1140,8 @@ static unsigned audio_buffer_ptr;
static void audio_process(void)
{
/* adds music raw samples and/or advances midi driver */
BGM_Update();
/* update audio */
if (cls.state == ca_active)
{
......@@ -1168,13 +1172,14 @@ static void audio_callback(void)
}
}