Files needed for linux to compile properly.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@156 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2004-09-07 18:18:02 +00:00
parent 5a872df165
commit 8b9eb9f5f8
3 changed files with 986 additions and 0 deletions

310
engine/client/snd_linux.c Normal file
View File

@ -0,0 +1,310 @@
#ifdef __CYGWIN__
#include "quakedef.h"
int SNDDMA_Init(soundcardinfo_t *sc)
{
Con_Printf("Cygwin targets do not have sound. Sorry.\n");
return 0;
}
void S_Init(void)
{
Con_Printf("Cygwin targets do not have sound. Sorry.\n");
}
void S_Startup (void){}
void S_Restart_f (void){}
void SNDDMA_SetUnderWater(qboolean underwater) {}
void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, int width){}
void S_Shutdown (void){}
void S_ShutdownCur (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 (soundcardinfo_t *sc){}
void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up){}
void S_ExtraUpdate (void){}
sfx_t *S_PrecacheSound (char *sample)
{
return NULL;
}
void S_TouchSound (char *sample){}
void S_LocalSound (char *s){}
void S_ClearPrecache (void){}
void S_BeginPrecaching (void){}
void S_EndPrecaching (void){}
cvar_t bgmvolume;
cvar_t volume;
cvar_t precache;
int snd_speed;
#else
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/wait.h>
#include <linux/soundcard.h>
#include <stdio.h>
#include "quakedef.h"
qboolean snd_firsttime = true;
static int tryrates[] = { 11025, 22051, 44100, 8000 };
soundcardinfo_t *sndcardinfo;
void SNDDMA_SetUnderWater(qboolean underwater) //simply a stub. Any ideas how to actually implement this properly?
{
}
void S_UpdateCapture(void) //any ideas how to get microphone input?
{
}
int SNDDMA_Init(soundcardinfo_t *sc)
{ //FIXME: implement snd_multipledevices somehow.
int rc;
int fmt;
int tmp;
int i;
char *s;
struct audio_buf_info info;
int caps;
char *snddev = NULL;
cvar_t *devname;
soundcardinfo_t *ec;
devname = Cvar_Get("snd_devicename", "/dev/dsp", 0, "Sound controls");
snddev = devname->string;
for (ec = sndcardinfo; ec; ec = ec->next)
if (!strcmp(ec->name, snddev))
return 2;
// open the sound device, confirm capability to mmap, and get size of dma buffer
Q_strncpyz(sc->name, snddev, sizeof(sc->name));
printf("Initing sound device %s\n", snddev);
sc->audio_fd = open(snddev, O_RDWR);
if (sc->audio_fd < 0)
{
perror(snddev);
Con_Printf("Could not open %s\n", snddev);
SNDDMA_Shutdown(sc);
return 0;
}
rc = ioctl(sc->audio_fd, SNDCTL_DSP_RESET, 0);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not reset %s\n", snddev);
SNDDMA_Shutdown(sc);
return 0;
}
if (ioctl(sc->audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
{
perror(snddev);
Con_Printf("Sound driver too old\n");
SNDDMA_Shutdown(sc);
return 0;
}
if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
{
Con_Printf("Sorry but your soundcard can't do this\n");
SNDDMA_Shutdown(sc);
return 0;
}
if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
{
perror("GETOSPACE");
Con_Printf("Um, can't do GETOSPACE?\n");
SNDDMA_Shutdown(sc);
return 0;
}
sc->sn.splitbuffer = 0;
// set sample bits & speed
s = getenv("QUAKE_SOUND_SAMPLEBITS");
if (s) sc->sn.samplebits = atoi(s);
else if ((i = COM_CheckParm("-sndbits")) != 0)
sc->sn.samplebits = atoi(com_argv[i+1]);
if (sc->sn.samplebits != 16 && sc->sn.samplebits != 8)
{
ioctl(sc->audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
if (fmt & AFMT_S16_LE)
sc->sn.samplebits = 16;
else if (fmt & AFMT_U8)
sc->sn.samplebits = 8;
}
s = getenv("QUAKE_SOUND_SPEED");
if (s) sc->sn.speed = atoi(s);
else if ((i = COM_CheckParm("-sndspeed")) != 0)
sc->sn.speed = atoi(com_argv[i+1]);
else
{
if (!sc->sn.speed || ioctl(sc->audio_fd, SNDCTL_DSP_SPEED, &sc->sn.speed)) //use the default - menu set value.
{ //humph, default didn't work. Go for random preset ones that should work.
for (i=0 ; i<sizeof(tryrates)/4 ; i++)
if (!ioctl(sc->audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
sc->sn.speed = tryrates[i];
}
}
s = getenv("QUAKE_SOUND_CHANNELS");
if (s) sc->sn.numchannels = atoi(s);
else if ((i = COM_CheckParm("-sndmono")) != 0)
sc->sn.numchannels = 1;
else if ((i = COM_CheckParm("-sndstereo")) != 0)
sc->sn.numchannels = 2;
else sc->sn.numchannels = 2;
sc->sn.samples = info.fragstotal * info.fragsize / (sc->sn.samplebits/8);
sc->sn.submission_chunk = 1;
// memory map the dma buffer
sc->sn.buffer = (unsigned char *) mmap(NULL, info.fragstotal
* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, sc->audio_fd, 0);
if (!sc->sn.buffer)
{
perror(snddev);
Con_Printf("Could not mmap %s\n", snddev);
SNDDMA_Shutdown(sc);
return 0;
}
tmp = 0;
if (sc->sn.numchannels == 2)
tmp = 1;
rc = ioctl(sc->audio_fd, SNDCTL_DSP_STEREO, &tmp);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not set %s to stereo=%d", snddev, sc->sn.numchannels);
SNDDMA_Shutdown(sc);
return 0;
}
if (tmp)
sc->sn.numchannels = 2;
else
sc->sn.numchannels = 1;
rc = ioctl(sc->audio_fd, SNDCTL_DSP_SPEED, &sc->sn.speed);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not set %s speed to %d", snddev, sc->sn.speed);
SNDDMA_Shutdown(sc);
return 0;
}
if (sc->sn.samplebits == 16)
{
rc = AFMT_S16_LE;
rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not support 16-bit data. Try 8-bit.\n");
SNDDMA_Shutdown(sc);
return 0;
}
}
else if (sc->sn.samplebits == 8)
{
rc = AFMT_U8;
rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not support 8-bit data.\n");
SNDDMA_Shutdown(sc);
return 0;
}
}
else
{
perror(snddev);
Con_Printf("%d-bit sound not supported.", sc->sn.samplebits);
SNDDMA_Shutdown(sc);
return 0;
}
// toggle the trigger & start her up
tmp = 0;
rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not toggle.\n");
SNDDMA_Shutdown(sc);
return 0;
}
tmp = PCM_ENABLE_OUTPUT;
rc = ioctl(sc->audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
if (rc < 0)
{
perror(snddev);
Con_Printf("Could not toggle.\n");
SNDDMA_Shutdown(sc);
return 0;
}
sc->sn.samplepos = 0;
return 1;
}
int SNDDMA_GetDMAPos(soundcardinfo_t *sc)
{
struct count_info count;
if (ioctl(sc->audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
{
perror("/dev/dsp");
Con_Printf("Uh, sound dead.\n");
close(sc->audio_fd);
return 0;
}
// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1);
// fprintf(stderr, "%d \r", count.ptr);
sc->sn.samplepos = count.ptr / (sc->sn.samplebits / 8);
return sc->sn.samplepos;
}
void SNDDMA_Shutdown(soundcardinfo_t *sc)
{
if (sc->sn.buffer) //close it properly, so we can go and restart it later.
munmap(sc->sn.buffer, sc->sn.samples * (sc->sn.samplebits/8));
if (sc->audio_fd)
close(sc->audio_fd);
*sc->name = '\0';
}
/*
==============
SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
===============
*/
void SNDDMA_Submit(soundcardinfo_t *sc)
{
}
#endif

95
engine/client/sys_dosa.s Normal file
View File

@ -0,0 +1,95 @@
//
// sys_dosa.s
// x86 assembly-language DOS-dependent routines.
#include "asm_i386.h"
#include "quakeasm.h"
.data
.align 4
fpenv:
.long 0, 0, 0, 0, 0, 0, 0, 0
.text
.globl C(MaskExceptions)
C(MaskExceptions):
fnstenv fpenv
orl $0x3F,fpenv
fldenv fpenv
ret
#if 0
.globl C(unmaskexceptions)
C(unmaskexceptions):
fnstenv fpenv
andl $0xFFFFFFE0,fpenv
fldenv fpenv
ret
#endif
.data
.align 4
.globl ceil_cw, single_cw, full_cw, cw, pushed_cw
ceil_cw: .long 0
single_cw: .long 0
full_cw: .long 0
cw: .long 0
pushed_cw: .long 0
.text
.globl C(Sys_LowFPPrecision)
C(Sys_LowFPPrecision):
fldcw single_cw
ret
.globl C(Sys_HighFPPrecision)
C(Sys_HighFPPrecision):
fldcw full_cw
ret
.globl C(Sys_PushFPCW_SetHigh)
C(Sys_PushFPCW_SetHigh):
fnstcw pushed_cw
fldcw full_cw
ret
.globl C(Sys_PopFPCW)
C(Sys_PopFPCW):
fldcw pushed_cw
ret
.globl C(Sys_SetFPCW)
C(Sys_SetFPCW):
fnstcw cw
movl cw,%eax
#if id386
andb $0xF0,%ah
orb $0x03,%ah // round mode, 64-bit precision
#endif
movl %eax,full_cw
#if id386
andb $0xF0,%ah
orb $0x0C,%ah // chop mode, single precision
#endif
movl %eax,single_cw
#if id386
andb $0xF0,%ah
orb $0x08,%ah // ceil mode, single precision
#endif
movl %eax,ceil_cw
ret

581
engine/client/sys_linux.c Normal file
View File

@ -0,0 +1,581 @@
/*
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.
*/
//well, linux or cygwin (windows with posix emulation layer), anyway...
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#ifndef __CYGWIN__
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#include <sys/stat.h>
#include <string.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <errno.h>
#include "quakedef.h"
#undef malloc
int noconinput = 0;
int nostdout = 0;
char *basedir = ".";
char *cachedir = "/tmp";
cvar_t sys_linerefresh = {"sys_linerefresh","0"};// set for entity display
qboolean Sys_InitTerminal (void) //we either have one or we don't.
{
return true;
}
void Sys_CloseTerminal (void)
{
}
qboolean isDedicated;
// =======================================================================
// General routines
// =======================================================================
void Sys_DebugNumber(int y, int val)
{
}
/*
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char text[1024];
va_start (argptr,fmt);
_vsnprintf (text,sizeof(text)-1, fmt,argptr);
va_end (argptr);
fprintf(stderr, "%s", text);
Con_Print (text);
}
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char text[1024], *t_p;
int l, r;
if (nostdout)
return;
va_start (argptr,fmt);
_vsnprintf (text,sizeof(text)-1, fmt,argptr);
va_end (argptr);
l = strlen(text);
t_p = text;
// make sure everything goes through, even though we are non-blocking
while (l)
{
r = write (1, text, l);
if (r != l)
sleep (0);
if (r > 0)
{
t_p += r;
l -= r;
}
}
}
*/
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char text[2048];
unsigned char *p;
va_start (argptr,fmt);
_vsnprintf (text,sizeof(text)-1, fmt,argptr);
va_end (argptr);
if (strlen(text) > sizeof(text))
Sys_Error("memory overwrite in Sys_Printf");
if (nostdout)
return;
for (p = (unsigned char *)text; *p; p++)
if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
printf("[%02x]", *p);
else
putc(*p, stdout);
}
void Sys_Quit (void)
{
Host_Shutdown();
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
exit(0);
}
void Sys_Init(void)
{
#if id386
Sys_SetFPCW();
#endif
}
void Sys_Error (const char *error, ...)
{
va_list argptr;
char string[1024];
// change stdin to non blocking
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
va_start (argptr,error);
_vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr);
fprintf(stderr, "Error: %s\n", string);
*(int*)NULL = 0;
Host_Shutdown ();
exit (1);
}
void Sys_Warn (char *warning, ...)
{
va_list argptr;
char string[1024];
va_start (argptr,warning);
_vsnprintf (string,sizeof(string)-1, warning,argptr);
va_end (argptr);
fprintf(stderr, "Warning: %s", string);
}
/*
============
Sys_FileTime
returns -1 if not present
============
*/
int Sys_FileTime (char *path)
{
struct stat buf;
if (stat (path,&buf) == -1)
return -1;
return buf.st_mtime;
}
void Sys_mkdir (char *path)
{
mkdir (path, 0777);
}
qboolean Sys_remove (char *path)
{
return system(va("rm \"%s\"", path));
}
int Sys_FileOpenRead (char *path, int *handle)
{
int h;
struct stat fileinfo;
h = open (path, O_RDONLY, 0666);
*handle = h;
if (h == -1)
return -1;
if (fstat (h,&fileinfo) == -1)
Sys_Error ("Error fstating %s", path);
return fileinfo.st_size;
}
int Sys_FileOpenWrite (char *path)
{
int handle;
umask (0);
handle = open(path,O_RDWR | O_CREAT | O_TRUNC
, 0666);
if (handle == -1)
Sys_Error ("Error opening %s: %s", path,strerror(errno));
return handle;
}
int Sys_FileWrite (int handle, void *src, int count)
{
return write (handle, src, count);
}
void Sys_FileClose (int handle)
{
close (handle);
}
void Sys_FileSeek (int handle, int position)
{
lseek (handle, position, SEEK_SET);
}
int Sys_FileRead (int handle, void *dest, int count)
{
return read (handle, dest, count);
}
void Sys_DebugLog(char *file, char *fmt, ...)
{
va_list argptr;
static char data[1024];
int fd;
va_start(argptr, fmt);
_vsnprintf (data,sizeof(data)-1, fmt, argptr);
va_end(argptr);
if (strlen(data) > sizeof(data))
Sys_Error("Sys_DebugLog's buffer was stomped\n");
// fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666);
fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
write(fd, data, strlen(data));
close(fd);
}
void Sys_EditFile(char *filename)
{
char cmd[256];
char *term;
char *editor;
term = getenv("TERM");
if (term && !strcmp(term, "xterm"))
{
editor = getenv("VISUAL");
if (!editor)
editor = getenv("EDITOR");
if (!editor)
editor = getenv("EDIT");
if (!editor)
editor = "vi";
sprintf(cmd, "xterm -e %s %s", editor, filename);
system(cmd);
}
}
//1 if match
//FIXME: make windows like - *.* becomes *
int wildcmp(char *wild, char *string) {
char *cp, *mp;
while ((*string) && (*wild != '*')) {
if ((*wild != *string) && (*wild != '?')) {
return 0;
}
wild++;
string++;
}
while (*string) {
if (*wild == '*') {
if (!*++wild) {
return 1;
}
mp = wild;
cp = string+1;
} else if ((*wild == *string) || (*wild == '?')) {
wild++;
string++;
} else {
wild = mp;
string = cp++;
}
}
while (*wild == '*') {
wild++;
}
return !*wild;
}
int Sys_EnumerateFiles (char *gpath, char *match, int (*func)(char *, int, void *), void *parm)
{
#include <dirent.h>
DIR *dir, *dir2;
char apath[MAX_OSPATH];
char file[MAX_OSPATH];
char truepath[MAX_OSPATH];
char *s;
struct dirent *ent;
//printf("path = %s\n", gpath);
//printf("match = %s\n", match);
if (!gpath)
gpath = "";
*apath = '\0';
Q_strncpyz(apath, match, sizeof(apath));
for (s = apath+strlen(apath)-1; s >= apath; s--)
{
if (*s == '/')
{
s[1] = '\0';
match += s - apath+1;
break;
}
}
if (s < apath) //didn't find a '/'
*apath = '\0';
sprintf(truepath, "%s/%s", gpath, apath);
//printf("truepath = %s\n", truepath);
//printf("gamepath = %s\n", gpath);
//printf("apppath = %s\n", apath);
//printf("match = %s\n", match);
dir = opendir(truepath);
if (!dir)
{
Con_Printf("Failed to open dir");
return true;
}
do
{
ent = readdir(dir);
if (!ent)
break;
if (*ent->d_name != '.')
if (wildcmp(match, ent->d_name))
{
snprintf(file, sizeof(file)-1, "%s/%s", gpath, ent->d_name);
//would use stat, but it breaks on fat32.
if ((dir2 = opendir(file)))
{
closedir(dir2);
snprintf(file, sizeof(file)-1, "%s%s/", apath, ent->d_name);
//printf("is directory = %s\n", file);
}
else
{
snprintf(file, sizeof(file)-1, "%s%s", apath, ent->d_name);
//printf("file = %s\n", file);
}
if (!func(file, -2, parm))
{
closedir(dir);
return false;
}
}
} while(1);
closedir(dir);
return true;
}
double Sys_DoubleTime (void)
{
struct timeval tp;
struct timezone tzp;
static int secbase;
gettimeofday(&tp, &tzp);
if (!secbase)
{
secbase = tp.tv_sec;
return tp.tv_usec/1000000.0;
}
return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
}
void Sys_UnloadGame (void)
{
}
void *Sys_GetGameAPI (void *parms)
{
return NULL;
}
// =======================================================================
// Sleeps for microseconds
// =======================================================================
static volatile int oktogo;
void alarm_handler(int x)
{
oktogo=1;
}
void Sys_LineRefresh(void)
{
}
void floating_point_exception_handler(int whatever)
{
// Sys_Warn("floating point exception\n");
signal(SIGFPE, floating_point_exception_handler);
}
char *Sys_ConsoleInput(void)
{
#if 0
static char text[256];
int len;
if (cls.state == ca_dedicated) {
len = read (0, text, sizeof(text));
if (len < 1)
return NULL;
text[len-1] = 0; // rip off the /n and terminate
return text;
}
#endif
return NULL;
}
#if !id386
void Sys_HighFPPrecision (void)
{
}
void Sys_LowFPPrecision (void)
{
}
#endif
int skipframes;
int main (int c, char **v)
{
double time, oldtime, newtime;
quakeparms_t parms;
int j;
// static char cwd[1024];
// signal(SIGFPE, floating_point_exception_handler);
signal(SIGFPE, SIG_IGN);
memset(&parms, 0, sizeof(parms));
COM_InitArgv(c, v);
TL_InitLanguages();
parms.argc = com_argc;
parms.argv = com_argv;
parms.memsize = 16*1024*1024;
j = COM_CheckParm("-mem");
if (j)
parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
parms.membase = malloc (parms.memsize);
parms.basedir = basedir;
// caching is disabled by default, use -cachedir to enable
// parms.cachedir = cachedir;
noconinput = COM_CheckParm("-noconinput");
if (!noconinput)
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
if (COM_CheckParm("-nostdout"))
nostdout = 1;
Sys_Init();
Host_Init(&parms);
oldtime = Sys_DoubleTime ();
while (1)
{
// find time spent rendering last frame
newtime = Sys_DoubleTime ();
time = newtime - oldtime;
Host_Frame(time);
oldtime = newtime;
}
}
/*
================
Sys_MakeCodeWriteable
================
*/
void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
{
int r;
unsigned long addr;
int psize = getpagesize();
addr = (startaddr & ~(psize-1)) - psize;
// fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
// addr, startaddr+length, length);
r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
if (r < 0)
Sys_Error("Protection change failed\n");
}