1
0
mirror of https://git.FreeBSD.org/ports.git synced 2025-01-22 08:58:47 +00:00

- Add support for playing .ogg music files in all search paths.

Obtained from:	http://svn.quakedev.com/viewcvs.cgi/qudos/trunk/
This commit is contained in:
Alejandro Pulver 2006-12-30 13:56:45 +00:00
parent 440a168de8
commit 9c3f65219f
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=181049
5 changed files with 654 additions and 2 deletions

View File

@ -7,7 +7,7 @@
PORTNAME= kmquake2
PORTVERSION= 0.19
PORTREVISION= 2
PORTREVISION= 3
CATEGORIES= games
MASTER_SITES= http://qudos.quakedev.com/linux/quake2/engines/KMQuake2/:src \
http://qexpo2005.quakedev.com/uploaded/54/:data \

View File

@ -0,0 +1,390 @@
--- ./client/snd_ogg.c.orig Sun Apr 9 09:28:58 2006
+++ ./client/snd_ogg.c Sat Dec 30 01:12:08 2006
@@ -1,4 +1,21 @@
/*
+* 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.
+*/
+
+/*
==========================================================
OGG Vorbis decoding
@@ -8,12 +25,9 @@
#include <sys/time.h>
#include <errno.h>
-
-#include "client.h"
-
-#ifdef OGGVORBIS
#include <vorbis/vorbisfile.h>
+#include "client.h"
#include "snd_loc.h"
#include "snd_ogg.h"
@@ -22,6 +36,7 @@
qboolean ogg_first_init = true; /* First initialization flag. */
qboolean ogg_started = false; /* Initialization flag. */
+byte *ogg_buffer; /* File buffer. */
char **ogg_filelist; /* List of Ogg Vorbis files. */
char ovBuf[4096]; /* Buffer for sound. */
int ogg_curfile; /* Index of currently played file. */
@@ -29,6 +44,7 @@
int ovSection; /* Position in Ogg Vorbis file. */
ogg_status_t ogg_status; /* Status indicator. */
cvar_t *ogg_autoplay; /* Play this song when started. */
+cvar_t *ogg_check; /* Check Ogg files or not. */
cvar_t *ogg_playlist; /* Playlist. */
cvar_t *ogg_sequence; /* Sequence play indicator. */
cvar_t *ogg_volume; /* Music volume. */
@@ -59,6 +75,7 @@
/* Cvars. */
ogg_autoplay = Cvar_Get("ogg_autoplay", "?", CVAR_ARCHIVE);
+ ogg_check = Cvar_Get("ogg_check", "0", CVAR_ARCHIVE);
ogg_playlist = Cvar_Get("ogg_playlist", "playlist", CVAR_ARCHIVE);
ogg_sequence = Cvar_Get("ogg_sequence", "next", CVAR_ARCHIVE);
ogg_volume = Cvar_Get("ogg_volume", "0.7", CVAR_ARCHIVE);
@@ -67,6 +84,7 @@
Cmd_AddCommand("ogg_list", OGG_ListCmd);
Cmd_AddCommand("ogg_pause", OGG_PauseCmd);
Cmd_AddCommand("ogg_play", OGG_PlayCmd);
+ Cmd_AddCommand("ogg_reinit", OGG_Reinit);
Cmd_AddCommand("ogg_resume", OGG_ResumeCmd);
Cmd_AddCommand("ogg_seek", OGG_SeekCmd);
Cmd_AddCommand("ogg_status", OGG_StatusCmd);
@@ -82,6 +100,7 @@
/* Check if we have Ogg Vorbis files. */
if (ogg_numfiles <= 0) {
Com_Printf("No Ogg Vorbis files found.\n");
+ ogg_started = true; /* For OGG_Shutdown(). */
OGG_Shutdown();
return;
}
@@ -89,6 +108,7 @@
/* Initialize variables. */
if (ogg_first_init) {
srand(time(NULL));
+ ogg_buffer = NULL;
ogg_curfile = -1;
ogg_status = STOP;
ogg_first_init = false;
@@ -112,7 +132,6 @@
*/
void OGG_Shutdown(void)
{
- int i; /* Loop counter. */
if (!ogg_started)
return;
@@ -122,15 +141,13 @@
OGG_Stop();
/* Free the list of files. */
- for (i = 0; i < ogg_numfiles; i++)
- free(ogg_filelist[i]);
- if (ogg_numfiles > 0)
- free(ogg_filelist);
+ FS_FreeList(ogg_filelist, ogg_numfiles + 1);
/* Remove console commands. */
Cmd_RemoveCommand("ogg_list");
Cmd_RemoveCommand("ogg_pause");
Cmd_RemoveCommand("ogg_play");
+ Cmd_RemoveCommand("ogg_reinit");
Cmd_RemoveCommand("ogg_resume");
Cmd_RemoveCommand("ogg_seek");
Cmd_RemoveCommand("ogg_status");
@@ -162,17 +179,21 @@
*/
qboolean OGG_Check(char *name)
{
- qboolean res; /* Return value. */
- FILE *fp; /* File pointer. */
- OggVorbis_File ovf; /* Ogg Vorbis file. */
+ qboolean res; /* Return value. */
+ byte *buffer; /* File buffer. */
+ int size; /* File size. */
+ OggVorbis_File ovf; /* Ogg Vorbis file. */
+
+ if (ogg_check->value == 0)
+ return (true);
res = false;
- if ((fp = fopen(name, "r")) != NULL) {
- if (ov_test(fp, &ovf, NULL, 0) == 0) {
+ if ((size = FS_LoadFile(name, (void**)&buffer)) > 0) {
+ if (ov_test(NULL, &ovf, (char *)buffer, size) == 0) {
res = true;
ov_clear(&ovf);
- } else
- fclose(fp);
+ }
+ FS_FreeFile(buffer);
}
return (res);
@@ -229,23 +250,15 @@
Load list of Ogg Vorbis files in "music".
==========
*/
-void FS_FreeList(char **list, int nfiles);
-char **FS_ListFiles(char *findname, int *numfiles, unsigned musthave, unsigned canthave);
void OGG_LoadFileList(void)
{
char **list; /* List of .ogg files. */
- char oggpath[MAX_OSPATH]; /* Path to .ogg files. */
int i; /* Loop counter. */
int j; /* Real position in list. */
- int length; /* Name length. */
- /* Set search path. */
- strncpy(oggpath, fs_basedir->string, sizeof(oggpath)-1);
- oggpath[sizeof(oggpath)-1] = '\0';
- strncat(oggpath, "/music/*.ogg", sizeof(oggpath)-strlen(oggpath)-1);
-
/* Get file list. */
- list = FS_ListFiles(oggpath, &ogg_numfiles, 0, SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
+ list = FS_ListFiles2(va("%s/*.ogg", OGG_DIR), &ogg_numfiles, 0,
+ SFF_SUBDIR | SFF_HIDDEN | SFF_SYSTEM);
ogg_numfiles--;
/* Check if there are posible Ogg files. */
@@ -257,17 +270,15 @@
/* Add valid Ogg Vorbis file to the list. */
for (i = 0, j = 0; i < ogg_numfiles; i++) {
- if (!OGG_Check(list[i]))
+ if (!OGG_Check(list[i])) {
+ free(list[i]);
continue;
- length = strlen(list[j]);
- ogg_filelist[j] = malloc(length+1);
- strncpy(ogg_filelist[j], list[j], length);
- ogg_filelist[j][length] = '\0';
- j++;
+ }
+ ogg_filelist[j++] = list[i];
}
/* Free the file list. */
- FS_FreeList(list, ogg_numfiles);
+ free(list);
/* Adjust the list size (remove space for invalid music files). */
ogg_numfiles = j;
@@ -283,54 +294,40 @@
*/
void OGG_LoadPlaylist(char *playlist)
{
- char *buffer; /* Buffer to read the file. */
- char *name; /* Name of music file. */
+ byte *buffer; /* Buffer to read the file. */
char *ptr; /* Pointer for parsing the file. */
int i; /* Loop counter. */
- int j; /* Real position in list. */
- int length; /* Length of buffer and strings. */
- FILE *fp; /* File pointer. */
+ int size; /* Length of buffer and strings. */
/* Open playlist. */
- if ((fp = fopen(va("%s/music/%s", fs_basedir->string, playlist), "r")) == NULL) {
+ if ((size = FS_LoadFile(va("%s/%s.lst", OGG_DIR, ogg_playlist->string),
+ (void **)&buffer)) < 0) {
Com_Printf("OGG_LoadPlaylist: could not open playlist: %s.\n", strerror(errno));
return;
}
- /* Read playlist into buffer. */
- fseek(fp, 0, SEEK_END);
- length = ftell(fp);
- fseek(fp, 0, SEEK_SET);
- buffer = malloc(length);
- fread(buffer, length, 1, fp);
-
/* Count the files in playlist. */
- ptr = buffer;
- while ((name = COM_Parse(&ptr))[0] != '\0')
- ogg_numfiles++;
+ for (ptr = strtok((char *)buffer, "\n");
+ ptr != NULL;
+ ptr = strtok(NULL, "\n")) {
+ if ((byte *)ptr != buffer)
+ ptr[-1] = '\n';
+ if (OGG_Check(va("%s/%s", OGG_DIR, ptr)))
+ ogg_numfiles++;
+ }
/* Allocate file list. */
ogg_filelist = malloc(sizeof(char *) * ogg_numfiles);
- /* Add valid Ogg Vorbis file to the list. */
- ptr = buffer;
- for (i = 0, j = 0; i < ogg_numfiles; i++) {
- name = va("%s/music/%s.ogg", fs_basedir->string, COM_Parse(&ptr));
- if (!OGG_Check(name))
- continue;
- length = strlen(name);
- ogg_filelist[j] = malloc(length+1);
- strncpy(ogg_filelist[j], name, length);
- ogg_filelist[j][length] = '\0';
- j++;
- }
-
- /* Adjust the list size (remove space for invalid music files). */
- ogg_numfiles = j;
- ogg_filelist = realloc(ogg_filelist, sizeof(char *) * ogg_numfiles);
+ i = 0;
+ for (ptr = strtok((char *)buffer, "\n");
+ ptr != NULL;
+ ptr = strtok(NULL, "\n"))
+ if (OGG_Check(va("%s/%s", OGG_DIR, ptr)))
+ ogg_filelist[i++] = strdup(va("%s/%s", OGG_DIR, ptr));
/* Free file buffer. */
- free(buffer);
+ FS_FreeFile(buffer);
}
/*
@@ -342,9 +339,9 @@
*/
qboolean OGG_Open(ogg_seek_t type, int offset)
{
- int pos; /* Absolute position. */
- int res; /* Error indicator. */
- FILE *fp; /* File pointer. */
+ int size; /* File size. */
+ int pos; /* Absolute position. */
+ int res; /* Error indicator. */
pos = -1;
@@ -378,15 +375,15 @@
}
/* Find file. */
- if ((fp = fopen(ogg_filelist[pos], "r")) == NULL) {
+ if ((size = FS_LoadFile(ogg_filelist[pos], (void **)&ogg_buffer)) == -1) {
Com_Printf("OGG_Open: could not open %d (%s): %s.\n", pos, ogg_filelist[pos], strerror(errno));
return (false);
}
/* Open ogg vorbis file. */
- if ((res = ov_open(fp, &ovFile, NULL, 0)) < 0) {
+ if ((res = ov_open(NULL, &ovFile, (char *)ogg_buffer, size)) < 0) {
Com_Printf("OGG_Open: '%s' is not a valid Ogg Vorbis file (error %i).\n", ogg_filelist[pos], res);
- fclose(fp);
+ FS_FreeFile(ogg_buffer);
return (false);
}
@@ -395,9 +392,8 @@
ogg_curfile = pos;
ogg_status = PLAY;
- //OGG_StatusCmd();
Com_Printf("Playing file %d '%s'\n", pos, ogg_filelist[pos]);
-
+
return (true);
}
@@ -413,7 +409,7 @@
char *name; /* File name. */
int i; /* Loop counter. */
- name = va("%s/music/%s.ogg", fs_basedir->string, filename);
+ name = va("%s/%s.ogg", OGG_DIR, filename);
for (i = 0; i < ogg_numfiles; i++)
if (strcmp(name, ogg_filelist[i]) == 0)
@@ -482,11 +478,19 @@
Stop playing the current file.
==========
*/
-void OGG_Stop( void )
+void OGG_Stop(void)
{
+ if (ogg_status == STOP)
+ return;
+
ov_clear(&ovFile);
ogg_status = STOP;
+
+ if (ogg_buffer != NULL) {
+ FS_FreeFile(ogg_buffer);
+ ogg_buffer = NULL;
+ }
}
/*
@@ -498,6 +502,7 @@
*/
void OGG_Stream(void)
{
+
if (!ogg_started)
return;
@@ -617,9 +622,6 @@
{
int i;
- if (!ogg_started)
- return;
-
for (i = 0; i < ogg_numfiles; i++)
Com_Printf("%d %s\n", i+1, ogg_filelist[i]);
@@ -687,9 +689,6 @@
void OGG_PlayCmd( void )
{
- if (!ogg_started)
- return;
-
if (Cmd_Argc() < 2) {
Com_Printf("Usage: ogg_play {filename | #n | ? | >n | <n}\n");
return;
@@ -722,6 +721,9 @@
void OGG_SeekCmd(void)
{
+ if (ogg_status != STOP)
+ return;
+
if (Cmd_Argc() < 2) {
Com_Printf("Usage: ogg_seek {n | <n | >n}\n");
return;
@@ -760,9 +762,11 @@
ogg_curfile+1, ogg_filelist[ogg_curfile], ov_time_tell(&ovFile));
break;
case STOP:
- Com_Printf("Stopped file %d (%s).\n",
- ogg_curfile+1, ogg_filelist[ogg_curfile]);
+ if (ogg_curfile == -1)
+ Com_Printf("Stopped.\n");
+ else
+ Com_Printf("Stopped file %d (%s).\n",
+ ogg_curfile+1, ogg_filelist[ogg_curfile]);
break;
}
}
-#endif

View File

@ -0,0 +1,92 @@
--- ./client/snd_ogg.h.orig Sun Apr 9 09:21:42 2006
+++ ./client/snd_ogg.h Sat Dec 30 01:12:03 2006
@@ -1,14 +1,33 @@
/*
-==========================================================
-
- OGG Vorbis decoding
-
-==========================================================
+* 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.
*/
+/*
+ * ==========================================================
+ *
+ * OGG Vorbis decoding
+ *
+ * ==========================================================
+ */
+
#ifndef _SND_OGG_H_
#define _SND_OGG_H_
+#define OGG_DIR "music"
+
typedef enum {
PLAY,
PAUSE,
@@ -20,29 +39,29 @@
REL
} ogg_seek_t;
-void OGG_Init(void);
-void OGG_Shutdown(void);
-void OGG_Reinit(void);
-qboolean OGG_Check(char *name);
-void OGG_Seek(ogg_seek_t type, double offset);
-void OGG_LoadFileList(void);
-void OGG_LoadPlaylist(char *name);
-qboolean OGG_Open(ogg_seek_t type, int offset);
-qboolean OGG_OpenName(char *filename);
-int OGG_Read(void);
-void OGG_Sequence(void);
-void OGG_Stop(void);
-void OGG_Stream(void);
-void S_RawSamplesVol(int samples, int rate, int width, int channels, byte *data, float volume);
+void OGG_Init (void);
+void OGG_Shutdown(void);
+void OGG_Reinit(void);
+qboolean OGG_Check(char *name);
+void OGG_Seek (ogg_seek_t type, double offset);
+void OGG_LoadFileList(void);
+void OGG_LoadPlaylist(char *name);
+qboolean OGG_Open(ogg_seek_t type, int offset);
+qboolean OGG_OpenName(char *filename);
+int OGG_Read (void);
+void OGG_Sequence(void);
+void OGG_Stop (void);
+void OGG_Stream(void);
+void S_RawSamplesVol(int samples, int rate, int width, int channels, byte * data, float volume);
/* Console commands. */
-void OGG_ListCmd(void);
-void OGG_ParseCmd(char *arg);
-void OGG_PauseCmd(void);
-void OGG_PlayCmd(void);
-void OGG_ResumeCmd(void);
-void OGG_SeekCmd(void);
-void OGG_StatusCmd(void);
+void OGG_ListCmd(void);
+void OGG_ParseCmd(char *arg);
+void OGG_PauseCmd(void);
+void OGG_PlayCmd(void);
+void OGG_ResumeCmd(void);
+void OGG_SeekCmd(void);
+void OGG_StatusCmd(void);
#endif

View File

@ -1,5 +1,5 @@
--- qcommon/files.c.orig Thu Mar 23 06:30:01 2006
+++ qcommon/files.c Fri Jul 28 14:54:41 2006
+++ qcommon/files.c Sat Dec 30 01:23:45 2006
@@ -1314,7 +1314,7 @@
char *homedir; /* Home directory. */
@ -67,3 +67,163 @@
FS_AddHomeAsGameDirectory(dir);
#endif
}
@@ -1799,6 +1797,159 @@
return (list);
}
#endif
+
+/*
+ * CompareAttributesPack
+ *
+ * Compare file attributes (musthave and canthave) in packed files. If
+ * "output" is not NULL, "size" is greater than zero and the file matches the
+ * attributes then a copy of the matching string will be placed there (with
+ * SFF_SUBDIR it changes).
+ *
+ * Returns a boolean value, true if the attributes match the file.
+ */
+qboolean
+ComparePackFiles(const char *findname, const char *name,
+ unsigned musthave, unsigned canthave, char *output, int size)
+{
+ qboolean retval;
+ char *ptr;
+ char buffer[MAX_OSPATH];
+
+ Q_strncpyz(buffer, name, sizeof(buffer));
+
+ if ((canthave & SFF_SUBDIR) && name[strlen(name)-1] == '/')
+ return (false);
+
+ if (musthave & SFF_SUBDIR) {
+ if ((ptr = strrchr(buffer, '/')) != NULL)
+ *ptr = '\0';
+ else
+ return (false);
+ }
+
+ if ((musthave & SFF_HIDDEN) || (canthave & SFF_HIDDEN)) {
+ if ((ptr = strrchr(buffer, '/')) == NULL)
+ ptr = buffer;
+ if (((musthave & SFF_HIDDEN) && ptr[1] != '.') ||
+ ((canthave & SFF_HIDDEN) && ptr[1] == '.'))
+ return (false);
+ }
+
+ if (canthave & SFF_RDONLY)
+ return (false);
+
+ retval = glob_match((char *)findname, buffer);
+
+ if (retval && output != NULL)
+ Q_strncpyz(output, buffer, size);
+
+ return (retval);
+}
+
+/*
+ * FS_ListFiles2
+ *
+ * Create a list of files that match a criteria.
+ *
+ * Searchs are relative to the game directory and use all the search paths
+ * including .pak and .pk3 files.
+ */
+char **
+FS_ListFiles2(char *findname, int *numfiles, unsigned musthave, unsigned canthave)
+{
+ fsSearchPath_t *search; /* Search path. */
+ int i, j; /* Loop counters. */
+ int nfiles; /* Number of files found. */
+ int tmpnfiles; /* Temp number of files. */
+ char **tmplist; /* Temporary list of files. */
+ char **list; /* List of files found. */
+ char path[MAX_OSPATH]; /* Temporary path. */
+
+ nfiles = 0;
+ list = malloc(sizeof(char *));
+
+ for (search = fs_searchPaths; search != NULL; search = search->next) {
+ if (search->pack != NULL) {
+ if (canthave & SFF_INPACK)
+ continue;
+
+ for (i = 0, j = 0; i < search->pack->numFiles; i++)
+ if (ComparePackFiles(findname,
+ search->pack->files[i].name,
+ musthave, canthave, NULL, 0))
+ j++;
+ if (j == 0)
+ continue;
+ nfiles += j;
+ list = realloc(list, nfiles * sizeof(char *));
+ for (i = 0, j = nfiles - j;
+ i < search->pack->numFiles;
+ i++)
+ if (ComparePackFiles(findname,
+ search->pack->files[i].name,
+ musthave, canthave, path, sizeof(path)))
+ list[j++] = strdup(path);
+ } else if (search->path != NULL) {
+ if (musthave & SFF_INPACK)
+ continue;
+
+ Com_sprintf(path, sizeof(path), "%s/%s",
+ search->path, findname);
+ tmplist = FS_ListFiles(path, &tmpnfiles, musthave,
+ canthave);
+ if (tmplist != NULL) {
+ tmpnfiles--;
+ nfiles += tmpnfiles;
+ list = realloc(list, nfiles * sizeof(char *));
+ for (i = 0, j = nfiles - tmpnfiles;
+ i < tmpnfiles;
+ i++, j++)
+ list[j] = strdup(tmplist[i] +
+ strlen(search->path) + 1);
+ FS_FreeList(tmplist, tmpnfiles + 1);
+ }
+ }
+ }
+
+ /* Delete duplicates. */
+ tmpnfiles = 0;
+ for (i = 0; i < nfiles; i++) {
+ if (list[i] == NULL)
+ continue;
+ for (j = i + 1; j < nfiles; j++)
+ if (list[j] != NULL &&
+ strcmp(list[i], list[j]) == 0) {
+ free(list[j]);
+ list[j] = NULL;
+ tmpnfiles++;
+ }
+ }
+
+ if (tmpnfiles > 0) {
+ nfiles -= tmpnfiles;
+ tmplist = malloc(nfiles * sizeof(char *));
+ for (i = 0, j = 0; i < nfiles + tmpnfiles; i++)
+ if (list[i] != NULL)
+ tmplist[j++] = list[i];
+ free(list);
+ list = tmplist;
+ }
+
+ /* Add a guard. */
+ if (nfiles > 0) {
+ nfiles++;
+ list = realloc(list, nfiles * sizeof(char *));
+ list[nfiles - 1] = NULL;
+ } else {
+ free(list);
+ list = NULL;
+ }
+
+ *numfiles = nfiles;
+
+ return (list);
+}
/*
================

View File

@ -0,0 +1,10 @@
--- qcommon/qcommon.h.orig Wed Dec 28 21:01:15 2005
+++ qcommon/qcommon.h Sat Dec 30 01:22:07 2006
@@ -758,6 +758,7 @@
==============================================================
*/
+#define SFF_INPACK 0x20 /* For FS_ListFiles2(). */
typedef int fileHandle_t;