mirror of
https://git.code.sf.net/p/quake/quake2forge
synced 2025-04-04 08:22:47 +00:00
OpenBSD patch from butter. FreeBSD should only need a slight change to the
bsd/Makefile. Thanks, butter.
This commit is contained in:
parent
3f062fddcb
commit
4e205d709e
14 changed files with 8375 additions and 13 deletions
1488
bsd/Makefile
Normal file
1488
bsd/Makefile
Normal file
File diff suppressed because it is too large
Load diff
431
bsd/cd_bsd.c
Normal file
431
bsd/cd_bsd.c
Normal file
|
@ -0,0 +1,431 @@
|
|||
// 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 <sys/cdio.h>
|
||||
#include <sys/disklabel.h>
|
||||
|
||||
#include "../client/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";
|
||||
|
||||
cvar_t *cd_volume;
|
||||
cvar_t *cd_nocd;
|
||||
cvar_t *cd_dev;
|
||||
|
||||
void CDAudio_Pause(void);
|
||||
|
||||
static void CDAudio_Eject(void)
|
||||
{
|
||||
if (cdfile == -1 || !enabled)
|
||||
return; // no cd init'd
|
||||
|
||||
if ( ioctl(cdfile, CDIOCEJECT) == -1 )
|
||||
Com_DPrintf("ioctl cdioceject failed\n");
|
||||
}
|
||||
|
||||
|
||||
static void CDAudio_CloseDoor(void)
|
||||
{
|
||||
if (cdfile == -1 || !enabled)
|
||||
return; // no cd init'd
|
||||
|
||||
/* No OpenBSD equivalent of this Linux ioctl()
|
||||
* if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 )
|
||||
* Com_DPrintf("ioctl cdromclosetray failed\n");
|
||||
*/
|
||||
Com_DPrintf("ioctl cdromclosetray not supported\n");
|
||||
}
|
||||
|
||||
static int CDAudio_GetAudioDiskInfo(void)
|
||||
{
|
||||
struct ioc_toc_header tochdr;
|
||||
|
||||
cdValid = false;
|
||||
|
||||
if ( ioctl(cdfile, CDIOREADTOCHEADER, &tochdr) == -1 )
|
||||
{
|
||||
Com_DPrintf("ioctl cdioreadtocheader failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tochdr.starting_track < 1)
|
||||
{
|
||||
Com_DPrintf("CDAudio: no music tracks\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cdValid = true;
|
||||
maxTrack = tochdr.ending_track;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_Play(int track, qboolean looping)
|
||||
{
|
||||
struct ioc_read_toc_entry entry;
|
||||
struct cd_toc_entry cd_entry;
|
||||
struct ioc_play_track ti;
|
||||
|
||||
if (cdfile == -1 || !enabled)
|
||||
return;
|
||||
|
||||
if (!cdValid)
|
||||
{
|
||||
CDAudio_GetAudioDiskInfo();
|
||||
if (!cdValid)
|
||||
return;
|
||||
}
|
||||
|
||||
track = remap[track];
|
||||
|
||||
if (track < 1 || track > maxTrack)
|
||||
{
|
||||
Com_DPrintf("CDAudio: Bad track number %u.\n", track);
|
||||
return;
|
||||
}
|
||||
|
||||
// don't try to play a non-audio track
|
||||
entry.starting_track = track;
|
||||
entry.address_format = CD_MSF_FORMAT;
|
||||
entry.data_len = sizeof(struct cd_toc_entry);
|
||||
entry.data = &cd_entry;
|
||||
if ( ioctl(cdfile, CDIOREADTOCENTRYS, &entry) == -1 )
|
||||
{
|
||||
Com_DPrintf("ioctl cdioreadtocentrys failed\n");
|
||||
return;
|
||||
}
|
||||
#define CDROM_DATA_TRACK 4
|
||||
if (cd_entry.control == CDROM_DATA_TRACK)
|
||||
{
|
||||
Com_Printf("CDAudio: track %i is not audio\n", track);
|
||||
return;
|
||||
}
|
||||
|
||||
if (playing)
|
||||
{
|
||||
if (playTrack == track)
|
||||
return;
|
||||
CDAudio_Stop();
|
||||
}
|
||||
|
||||
ti.start_track = track;
|
||||
ti.start_index = 1;
|
||||
ti.end_track = track;
|
||||
ti.end_index = 99;
|
||||
|
||||
if ( ioctl(cdfile, CDIOCPLAYTRACKS, &ti) == -1 )
|
||||
{
|
||||
Com_DPrintf("ioctl cdiocplaytracks failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ioctl(cdfile, CDIOCRESUME) == -1 )
|
||||
Com_DPrintf("ioctl cdiocresume failed\n");
|
||||
|
||||
playLooping = looping;
|
||||
playTrack = track;
|
||||
playing = true;
|
||||
|
||||
if (cd_volume->value == 0.0)
|
||||
CDAudio_Pause ();
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_Stop(void)
|
||||
{
|
||||
if (cdfile == -1 || !enabled)
|
||||
return;
|
||||
|
||||
if (!playing)
|
||||
return;
|
||||
|
||||
if ( ioctl(cdfile, CDIOCSTOP) == -1 )
|
||||
Com_DPrintf("ioctl cdiocstop failed (%d)\n", errno);
|
||||
|
||||
wasPlaying = false;
|
||||
playing = false;
|
||||
}
|
||||
|
||||
void CDAudio_Pause(void)
|
||||
{
|
||||
if (cdfile == -1 || !enabled)
|
||||
return;
|
||||
|
||||
if (!playing)
|
||||
return;
|
||||
|
||||
if ( ioctl(cdfile, CDIOCPAUSE) == -1 )
|
||||
Com_DPrintf("ioctl cdiocpause failed\n");
|
||||
|
||||
wasPlaying = playing;
|
||||
playing = false;
|
||||
}
|
||||
|
||||
|
||||
void CDAudio_Resume(void)
|
||||
{
|
||||
if (cdfile == -1 || !enabled)
|
||||
return;
|
||||
|
||||
if (!cdValid)
|
||||
return;
|
||||
|
||||
if (!wasPlaying)
|
||||
return;
|
||||
|
||||
if ( ioctl(cdfile, CDIOCRESUME) == -1 )
|
||||
Com_DPrintf("ioctl cdiocresume 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)
|
||||
Com_Printf(" %u -> %u\n", n, remap[n]);
|
||||
return;
|
||||
}
|
||||
for (n = 1; n <= ret; n++)
|
||||
remap[n] = atoi(Cmd_Argv (n+1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "close") == 0)
|
||||
{
|
||||
CDAudio_CloseDoor();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cdValid)
|
||||
{
|
||||
CDAudio_GetAudioDiskInfo();
|
||||
if (!cdValid)
|
||||
{
|
||||
Com_Printf("No CD in player.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "play") == 0)
|
||||
{
|
||||
CDAudio_Play((byte)atoi(Cmd_Argv (2)), false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Q_strcasecmp(command, "loop") == 0)
|
||||
{
|
||||
CDAudio_Play((byte)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)
|
||||
{
|
||||
Com_Printf("%u tracks\n", maxTrack);
|
||||
if (playing)
|
||||
Com_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
|
||||
else if (wasPlaying)
|
||||
Com_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
|
||||
Com_Printf("Volume is %f\n", cdvolume);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CDAudio_Update(void)
|
||||
{
|
||||
struct ioc_read_subchannel subchnl;
|
||||
struct cd_sub_channel_info subchnl_info;
|
||||
static time_t lastchk;
|
||||
|
||||
if (cdfile == -1 || !enabled)
|
||||
return;
|
||||
|
||||
if (cd_volume && cd_volume->value != cdvolume)
|
||||
{
|
||||
if (cdvolume)
|
||||
{
|
||||
Cvar_SetValue ("cd_volume", 0.0);
|
||||
cdvolume = cd_volume->value;
|
||||
CDAudio_Pause ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetValue ("cd_volume", 1.0);
|
||||
cdvolume = cd_volume->value;
|
||||
CDAudio_Resume ();
|
||||
}
|
||||
}
|
||||
|
||||
if (playing && lastchk < time(NULL)) {
|
||||
lastchk = time(NULL) + 2; //two seconds between chks
|
||||
subchnl.address_format = CD_MSF_FORMAT;
|
||||
subchnl.data_len = sizeof(struct cd_sub_channel_info);
|
||||
subchnl.data = &subchnl_info;
|
||||
if (ioctl(cdfile, CDIOCREADSUBCHANNEL, &subchnl) == -1 ) {
|
||||
Com_DPrintf("ioctl cdiocreadsubchannel failed\n");
|
||||
playing = false;
|
||||
return;
|
||||
}
|
||||
if (subchnl_info.header.audio_status != CD_AS_PLAY_IN_PROGRESS &&
|
||||
subchnl_info.header.audio_status != CD_AS_PLAY_PAUSED) {
|
||||
playing = false;
|
||||
if (playLooping)
|
||||
CDAudio_Play(playTrack, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CDAudio_Init(void)
|
||||
{
|
||||
int i;
|
||||
cvar_t *cv;
|
||||
extern uid_t saved_euid;
|
||||
|
||||
cv = Cvar_Get ("nocdaudio", "0", CVAR_NOSET);
|
||||
if (cv->value)
|
||||
return -1;
|
||||
|
||||
cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE );
|
||||
if ( cd_nocd->value)
|
||||
return -1;
|
||||
|
||||
cd_volume = Cvar_Get ("cd_volume", "1", CVAR_ARCHIVE);
|
||||
|
||||
cd_dev = Cvar_Get("cd_dev", "/dev/cd0c", CVAR_ARCHIVE);
|
||||
|
||||
seteuid(saved_euid);
|
||||
|
||||
cdfile = open(cd_dev->string, O_RDONLY);
|
||||
|
||||
seteuid(getuid());
|
||||
|
||||
if (cdfile == -1) {
|
||||
Com_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev->string, errno);
|
||||
cdfile = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
remap[i] = i;
|
||||
initialized = true;
|
||||
enabled = true;
|
||||
|
||||
if (CDAudio_GetAudioDiskInfo())
|
||||
{
|
||||
Com_Printf("CDAudio_Init: No CD in player.\n");
|
||||
cdValid = false;
|
||||
}
|
||||
|
||||
Cmd_AddCommand ("cd", CD_f);
|
||||
|
||||
Com_Printf("CD Audio Initialized\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CDAudio_Activate (qboolean active)
|
||||
{
|
||||
if (active)
|
||||
CDAudio_Resume ();
|
||||
else
|
||||
CDAudio_Pause ();
|
||||
}
|
||||
|
||||
void CDAudio_Shutdown(void)
|
||||
{
|
||||
if (!initialized)
|
||||
return;
|
||||
CDAudio_Stop();
|
||||
close(cdfile);
|
||||
cdfile = -1;
|
||||
}
|
865
bsd/gl_glx.c
Normal file
865
bsd/gl_glx.c
Normal file
|
@ -0,0 +1,865 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 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.
|
||||
|
||||
*/
|
||||
/*
|
||||
** GLW_IMP.C
|
||||
**
|
||||
** This file contains ALL Linux specific stuff having to do with the
|
||||
** OpenGL refresh. When a port is being made the following functions
|
||||
** must be implemented by the port:
|
||||
**
|
||||
** GLimp_EndFrame
|
||||
** GLimp_Init
|
||||
** GLimp_Shutdown
|
||||
** GLimp_SwitchFullscreen
|
||||
**
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "../ref_gl/gl_local.h"
|
||||
|
||||
#include "../client/keys.h"
|
||||
|
||||
#include "../linux/rw_linux.h"
|
||||
#include "../linux/glw_linux.h"
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#include <X11/extensions/xf86dga.h>
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
|
||||
glwstate_t glw_state;
|
||||
|
||||
static Display *dpy = NULL;
|
||||
static int scrnum;
|
||||
static Window win;
|
||||
static GLXContext ctx = NULL;
|
||||
|
||||
#define KEY_MASK (KeyPressMask | KeyReleaseMask)
|
||||
#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
|
||||
PointerMotionMask | ButtonMotionMask )
|
||||
#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask )
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MOUSE */
|
||||
/*****************************************************************************/
|
||||
|
||||
// this is inside the renderer shared lib, so these are called from vid_so
|
||||
|
||||
static qboolean mouse_avail;
|
||||
static int mx, my;
|
||||
static int old_mouse_x, old_mouse_y;
|
||||
|
||||
static int win_x, win_y;
|
||||
|
||||
static cvar_t *m_filter;
|
||||
static cvar_t *in_mouse;
|
||||
static cvar_t *in_dgamouse;
|
||||
|
||||
static cvar_t *r_fakeFullscreen;
|
||||
|
||||
static XF86VidModeModeInfo **vidmodes;
|
||||
static int default_dotclock_vidmode;
|
||||
static int num_vidmodes;
|
||||
static qboolean vidmode_active = false;
|
||||
|
||||
static qboolean mlooking;
|
||||
|
||||
static qboolean mouse_active = false;
|
||||
static qboolean dgamouse = false;
|
||||
static qboolean vidmode_ext = false;
|
||||
|
||||
// state struct passed in Init
|
||||
static in_state_t *in_state;
|
||||
|
||||
static cvar_t *sensitivity;
|
||||
static cvar_t *lookstrafe;
|
||||
static cvar_t *m_side;
|
||||
static cvar_t *m_yaw;
|
||||
static cvar_t *m_pitch;
|
||||
static cvar_t *m_forward;
|
||||
static cvar_t *freelook;
|
||||
|
||||
static Cursor CreateNullCursor(Display *display, Window root)
|
||||
{
|
||||
Pixmap cursormask;
|
||||
XGCValues xgc;
|
||||
GC gc;
|
||||
XColor dummycolour;
|
||||
Cursor cursor;
|
||||
|
||||
cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
|
||||
xgc.function = GXclear;
|
||||
gc = XCreateGC(display, cursormask, GCFunction, &xgc);
|
||||
XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
|
||||
dummycolour.pixel = 0;
|
||||
dummycolour.red = 0;
|
||||
dummycolour.flags = 04;
|
||||
cursor = XCreatePixmapCursor(display, cursormask, cursormask,
|
||||
&dummycolour,&dummycolour, 0,0);
|
||||
XFreePixmap(display,cursormask);
|
||||
XFreeGC(display,gc);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static void install_grabs(void)
|
||||
{
|
||||
|
||||
// inviso cursor
|
||||
XDefineCursor(dpy, win, CreateNullCursor(dpy, win));
|
||||
|
||||
XGrabPointer(dpy, win,
|
||||
True,
|
||||
0,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
win,
|
||||
None,
|
||||
CurrentTime);
|
||||
|
||||
if (in_dgamouse->value) {
|
||||
int MajorVersion, MinorVersion;
|
||||
|
||||
if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
|
||||
// unable to query, probalby not supported
|
||||
ri.Con_Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
|
||||
ri.Cvar_Set( "in_dgamouse", "0" );
|
||||
} else {
|
||||
dgamouse = true;
|
||||
XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse);
|
||||
XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
XWarpPointer(dpy, None, win,
|
||||
0, 0, 0, 0,
|
||||
vid.width / 2, vid.height / 2);
|
||||
}
|
||||
|
||||
XGrabKeyboard(dpy, win,
|
||||
False,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime);
|
||||
|
||||
mouse_active = true;
|
||||
|
||||
// XSync(dpy, True);
|
||||
}
|
||||
|
||||
static void uninstall_grabs(void)
|
||||
{
|
||||
if (!dpy || !win)
|
||||
return;
|
||||
|
||||
if (dgamouse) {
|
||||
dgamouse = false;
|
||||
XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0);
|
||||
}
|
||||
|
||||
XUngrabPointer(dpy, CurrentTime);
|
||||
XUngrabKeyboard(dpy, CurrentTime);
|
||||
|
||||
// inviso cursor
|
||||
XUndefineCursor(dpy, win);
|
||||
|
||||
mouse_active = false;
|
||||
}
|
||||
|
||||
static void Force_CenterView_f (void)
|
||||
{
|
||||
in_state->viewangles[PITCH] = 0;
|
||||
}
|
||||
|
||||
static void RW_IN_MLookDown (void)
|
||||
{
|
||||
mlooking = true;
|
||||
}
|
||||
|
||||
static void RW_IN_MLookUp (void)
|
||||
{
|
||||
mlooking = false;
|
||||
in_state->IN_CenterView_fp ();
|
||||
}
|
||||
|
||||
void RW_IN_Init(in_state_t *in_state_p)
|
||||
{
|
||||
int mtype;
|
||||
int i;
|
||||
|
||||
in_state = in_state_p;
|
||||
|
||||
// mouse variables
|
||||
m_filter = ri.Cvar_Get ("m_filter", "0", 0);
|
||||
in_mouse = ri.Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
|
||||
in_dgamouse = ri.Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE);
|
||||
freelook = ri.Cvar_Get( "freelook", "0", 0 );
|
||||
lookstrafe = ri.Cvar_Get ("lookstrafe", "0", 0);
|
||||
sensitivity = ri.Cvar_Get ("sensitivity", "3", 0);
|
||||
m_pitch = ri.Cvar_Get ("m_pitch", "0.022", 0);
|
||||
m_yaw = ri.Cvar_Get ("m_yaw", "0.022", 0);
|
||||
m_forward = ri.Cvar_Get ("m_forward", "1", 0);
|
||||
m_side = ri.Cvar_Get ("m_side", "0.8", 0);
|
||||
|
||||
ri.Cmd_AddCommand ("+mlook", RW_IN_MLookDown);
|
||||
ri.Cmd_AddCommand ("-mlook", RW_IN_MLookUp);
|
||||
|
||||
ri.Cmd_AddCommand ("force_centerview", Force_CenterView_f);
|
||||
|
||||
mx = my = 0.0;
|
||||
mouse_avail = true;
|
||||
}
|
||||
|
||||
void RW_IN_Shutdown(void)
|
||||
{
|
||||
if (mouse_avail) {
|
||||
mouse_avail = false;
|
||||
|
||||
ri.Cmd_RemoveCommand ("+mlook");
|
||||
ri.Cmd_RemoveCommand ("-mlook");
|
||||
ri.Cmd_RemoveCommand ("force_centerview");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Commands
|
||||
===========
|
||||
*/
|
||||
void RW_IN_Commands (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void RW_IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
if (!mouse_avail)
|
||||
return;
|
||||
|
||||
if (m_filter->value)
|
||||
{
|
||||
mx = (mx + old_mouse_x) * 0.5;
|
||||
my = (my + old_mouse_y) * 0.5;
|
||||
}
|
||||
|
||||
old_mouse_x = mx;
|
||||
old_mouse_y = my;
|
||||
|
||||
mx *= sensitivity->value;
|
||||
my *= sensitivity->value;
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ( (*in_state->in_strafe_state & 1) ||
|
||||
(lookstrafe->value && mlooking ))
|
||||
cmd->sidemove += m_side->value * mx;
|
||||
else
|
||||
in_state->viewangles[YAW] -= m_yaw->value * mx;
|
||||
|
||||
if ( (mlooking || freelook->value) &&
|
||||
!(*in_state->in_strafe_state & 1))
|
||||
{
|
||||
in_state->viewangles[PITCH] += m_pitch->value * my;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->forwardmove -= m_forward->value * my;
|
||||
}
|
||||
|
||||
mx = my = 0;
|
||||
}
|
||||
|
||||
static void IN_DeactivateMouse( void )
|
||||
{
|
||||
if (!mouse_avail || !dpy || !win)
|
||||
return;
|
||||
|
||||
if (mouse_active) {
|
||||
uninstall_grabs();
|
||||
mouse_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void IN_ActivateMouse( void )
|
||||
{
|
||||
if (!mouse_avail || !dpy || !win)
|
||||
return;
|
||||
|
||||
if (!mouse_active) {
|
||||
mx = my = 0; // don't spazz
|
||||
install_grabs();
|
||||
mouse_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RW_IN_Frame (void)
|
||||
{
|
||||
}
|
||||
|
||||
void RW_IN_Activate(qboolean active)
|
||||
{
|
||||
if (active || vidmode_active)
|
||||
IN_ActivateMouse();
|
||||
else
|
||||
IN_DeactivateMouse ();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* KEYBOARD */
|
||||
/*****************************************************************************/
|
||||
|
||||
static int XLateKey(XKeyEvent *ev)
|
||||
{
|
||||
|
||||
int key;
|
||||
char buf[64];
|
||||
KeySym keysym;
|
||||
|
||||
key = 0;
|
||||
|
||||
XLookupString(ev, buf, sizeof buf, &keysym, 0);
|
||||
|
||||
switch(keysym)
|
||||
{
|
||||
case XK_KP_Page_Up: key = K_KP_PGUP; break;
|
||||
case XK_Page_Up: key = K_PGUP; break;
|
||||
|
||||
case XK_KP_Page_Down: key = K_KP_PGDN; break;
|
||||
case XK_Page_Down: key = K_PGDN; break;
|
||||
|
||||
case XK_KP_Home: key = K_KP_HOME; break;
|
||||
case XK_Home: key = K_HOME; break;
|
||||
|
||||
case XK_KP_End: key = K_KP_END; break;
|
||||
case XK_End: key = K_END; break;
|
||||
|
||||
case XK_KP_Left: key = K_KP_LEFTARROW; break;
|
||||
case XK_Left: key = K_LEFTARROW; break;
|
||||
|
||||
case XK_KP_Right: key = K_KP_RIGHTARROW; break;
|
||||
case XK_Right: key = K_RIGHTARROW; break;
|
||||
|
||||
case XK_KP_Down: key = K_KP_DOWNARROW; break;
|
||||
case XK_Down: key = K_DOWNARROW; break;
|
||||
|
||||
case XK_KP_Up: key = K_KP_UPARROW; break;
|
||||
case XK_Up: key = K_UPARROW; break;
|
||||
|
||||
case XK_Escape: key = K_ESCAPE; break;
|
||||
|
||||
case XK_KP_Enter: key = K_KP_ENTER; break;
|
||||
case XK_Return: key = K_ENTER; break;
|
||||
|
||||
case XK_Tab: key = K_TAB; break;
|
||||
|
||||
case XK_F1: key = K_F1; break;
|
||||
|
||||
case XK_F2: key = K_F2; break;
|
||||
|
||||
case XK_F3: key = K_F3; break;
|
||||
|
||||
case XK_F4: key = K_F4; break;
|
||||
|
||||
case XK_F5: key = K_F5; break;
|
||||
|
||||
case XK_F6: key = K_F6; break;
|
||||
|
||||
case XK_F7: key = K_F7; break;
|
||||
|
||||
case XK_F8: key = K_F8; break;
|
||||
|
||||
case XK_F9: key = K_F9; break;
|
||||
|
||||
case XK_F10: key = K_F10; break;
|
||||
|
||||
case XK_F11: key = K_F11; break;
|
||||
|
||||
case XK_F12: key = K_F12; break;
|
||||
|
||||
case XK_BackSpace: key = K_BACKSPACE; break;
|
||||
|
||||
case XK_KP_Delete: key = K_KP_DEL; break;
|
||||
case XK_Delete: key = K_DEL; break;
|
||||
|
||||
case XK_Pause: key = K_PAUSE; break;
|
||||
|
||||
case XK_Shift_L:
|
||||
case XK_Shift_R: key = K_SHIFT; break;
|
||||
|
||||
case XK_Execute:
|
||||
case XK_Control_L:
|
||||
case XK_Control_R: key = K_CTRL; break;
|
||||
|
||||
case XK_Alt_L:
|
||||
case XK_Meta_L:
|
||||
case XK_Alt_R:
|
||||
case XK_Meta_R: key = K_ALT; break;
|
||||
|
||||
case XK_KP_Begin: key = K_KP_5; break;
|
||||
|
||||
case XK_Insert:key = K_INS; break;
|
||||
case XK_KP_Insert: key = K_KP_INS; break;
|
||||
|
||||
case XK_KP_Multiply: key = '*'; break;
|
||||
case XK_KP_Add: key = K_KP_PLUS; break;
|
||||
case XK_KP_Subtract: key = K_KP_MINUS; break;
|
||||
case XK_KP_Divide: key = K_KP_SLASH; break;
|
||||
|
||||
#if 0
|
||||
case 0x021: key = '1';break;/* [!] */
|
||||
case 0x040: key = '2';break;/* [@] */
|
||||
case 0x023: key = '3';break;/* [#] */
|
||||
case 0x024: key = '4';break;/* [$] */
|
||||
case 0x025: key = '5';break;/* [%] */
|
||||
case 0x05e: key = '6';break;/* [^] */
|
||||
case 0x026: key = '7';break;/* [&] */
|
||||
case 0x02a: key = '8';break;/* [*] */
|
||||
case 0x028: key = '9';;break;/* [(] */
|
||||
case 0x029: key = '0';break;/* [)] */
|
||||
case 0x05f: key = '-';break;/* [_] */
|
||||
case 0x02b: key = '=';break;/* [+] */
|
||||
case 0x07c: key = '\'';break;/* [|] */
|
||||
case 0x07d: key = '[';break;/* [}] */
|
||||
case 0x07b: key = ']';break;/* [{] */
|
||||
case 0x022: key = '\'';break;/* ["] */
|
||||
case 0x03a: key = ';';break;/* [:] */
|
||||
case 0x03f: key = '/';break;/* [?] */
|
||||
case 0x03e: key = '.';break;/* [>] */
|
||||
case 0x03c: key = ',';break;/* [<] */
|
||||
#endif
|
||||
|
||||
default:
|
||||
key = *(unsigned char*)buf;
|
||||
if (key >= 'A' && key <= 'Z')
|
||||
key = key - 'A' + 'a';
|
||||
if (key >= 1 && key <= 26) /* ctrl+alpha */
|
||||
key = key + 'a' - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
static void HandleEvents(void)
|
||||
{
|
||||
XEvent event;
|
||||
int b;
|
||||
qboolean dowarp = false;
|
||||
int mwx = vid.width/2;
|
||||
int mwy = vid.height/2;
|
||||
|
||||
if (!dpy)
|
||||
return;
|
||||
|
||||
while (XPending(dpy)) {
|
||||
|
||||
XNextEvent(dpy, &event);
|
||||
|
||||
switch(event.type) {
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
if (in_state && in_state->Key_Event_fp)
|
||||
in_state->Key_Event_fp (XLateKey(&event.xkey), event.type == KeyPress);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
if (mouse_active) {
|
||||
if (dgamouse) {
|
||||
mx += (event.xmotion.x + win_x) * 2;
|
||||
my += (event.xmotion.y + win_y) * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx += ((int)event.xmotion.x - mwx) * 2;
|
||||
my += ((int)event.xmotion.y - mwy) * 2;
|
||||
mwx = event.xmotion.x;
|
||||
mwy = event.xmotion.y;
|
||||
|
||||
if (mx || my)
|
||||
dowarp = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ButtonPress:
|
||||
b=-1;
|
||||
if (event.xbutton.button == 1)
|
||||
b = 0;
|
||||
else if (event.xbutton.button == 2)
|
||||
b = 2;
|
||||
else if (event.xbutton.button == 3)
|
||||
b = 1;
|
||||
if (b>=0 && in_state && in_state->Key_Event_fp)
|
||||
in_state->Key_Event_fp (K_MOUSE1 + b, true);
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
b=-1;
|
||||
if (event.xbutton.button == 1)
|
||||
b = 0;
|
||||
else if (event.xbutton.button == 2)
|
||||
b = 2;
|
||||
else if (event.xbutton.button == 3)
|
||||
b = 1;
|
||||
if (b>=0 && in_state && in_state->Key_Event_fp)
|
||||
in_state->Key_Event_fp (K_MOUSE1 + b, false);
|
||||
break;
|
||||
|
||||
case CreateNotify :
|
||||
win_x = event.xcreatewindow.x;
|
||||
win_y = event.xcreatewindow.y;
|
||||
break;
|
||||
|
||||
case ConfigureNotify :
|
||||
win_x = event.xconfigure.x;
|
||||
win_y = event.xconfigure.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dowarp) {
|
||||
/* move the mouse to the window center again */
|
||||
XWarpPointer(dpy,None,win,0,0,0,0, vid.width/2,vid.height/2);
|
||||
}
|
||||
}
|
||||
|
||||
Key_Event_fp_t Key_Event_fp;
|
||||
|
||||
void KBD_Init(Key_Event_fp_t fp)
|
||||
{
|
||||
Key_Event_fp = fp;
|
||||
}
|
||||
|
||||
void KBD_Update(void)
|
||||
{
|
||||
// get events from x server
|
||||
HandleEvents();
|
||||
}
|
||||
|
||||
void KBD_Close(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static qboolean GLimp_SwitchFullscreen( int width, int height );
|
||||
qboolean GLimp_InitGL (void);
|
||||
|
||||
static void signal_handler(int sig)
|
||||
{
|
||||
printf("Received signal %d, exiting...\n", sig);
|
||||
GLimp_Shutdown();
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
static void InitSig(void)
|
||||
{
|
||||
signal(SIGHUP, signal_handler);
|
||||
signal(SIGQUIT, signal_handler);
|
||||
signal(SIGILL, signal_handler);
|
||||
signal(SIGTRAP, signal_handler);
|
||||
signal(SIGIOT, signal_handler);
|
||||
signal(SIGBUS, signal_handler);
|
||||
signal(SIGFPE, signal_handler);
|
||||
signal(SIGSEGV, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_SetMode
|
||||
*/
|
||||
int GLimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
|
||||
{
|
||||
int width, height;
|
||||
int attrib[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None
|
||||
};
|
||||
Window root;
|
||||
XVisualInfo *visinfo;
|
||||
XSetWindowAttributes attr;
|
||||
XSizeHints *sizehints;
|
||||
unsigned long mask;
|
||||
int MajorVersion, MinorVersion;
|
||||
int actualWidth, actualHeight;
|
||||
int i;
|
||||
|
||||
r_fakeFullscreen = ri.Cvar_Get( "r_fakeFullscreen", "0", CVAR_ARCHIVE);
|
||||
|
||||
ri.Con_Printf( PRINT_ALL, "Initializing OpenGL display\n");
|
||||
|
||||
if (fullscreen)
|
||||
ri.Con_Printf (PRINT_ALL, "...setting fullscreen mode %d:", mode );
|
||||
else
|
||||
ri.Con_Printf (PRINT_ALL, "...setting mode %d:", mode );
|
||||
|
||||
if ( !ri.Vid_GetModeInfo( &width, &height, mode ) )
|
||||
{
|
||||
ri.Con_Printf( PRINT_ALL, " invalid mode\n" );
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
ri.Con_Printf( PRINT_ALL, " %d %d\n", width, height );
|
||||
|
||||
// destroy the existing window
|
||||
GLimp_Shutdown ();
|
||||
|
||||
#if 0 // this breaks getenv()? - sbf
|
||||
// Mesa VooDoo hacks
|
||||
if (fullscreen)
|
||||
putenv("MESA_GLX_FX=fullscreen");
|
||||
else
|
||||
putenv("MESA_GLX_FX=window");
|
||||
#endif
|
||||
|
||||
if (!(dpy = XOpenDisplay(NULL))) {
|
||||
fprintf(stderr, "Error couldn't open the X display\n");
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
scrnum = DefaultScreen(dpy);
|
||||
root = RootWindow(dpy, scrnum);
|
||||
|
||||
// Get video mode list
|
||||
MajorVersion = MinorVersion = 0;
|
||||
if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
|
||||
vidmode_ext = false;
|
||||
} else {
|
||||
ri.Con_Printf(PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n",
|
||||
MajorVersion, MinorVersion);
|
||||
vidmode_ext = true;
|
||||
}
|
||||
|
||||
visinfo = qglXChooseVisual(dpy, scrnum, attrib);
|
||||
if (!visinfo) {
|
||||
fprintf(stderr, "Error couldn't get an RGB, Double-buffered, Depth visual\n");
|
||||
return rserr_invalid_mode;
|
||||
}
|
||||
|
||||
if (vidmode_ext) {
|
||||
int best_fit, best_dist, dist, x, y;
|
||||
|
||||
XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);
|
||||
|
||||
// Are we going fullscreen? If so, let's change video mode
|
||||
if (fullscreen && !r_fakeFullscreen->value) {
|
||||
best_dist = 9999999;
|
||||
best_fit = -1;
|
||||
|
||||
for (i = 0; i < num_vidmodes; i++) {
|
||||
if (width > vidmodes[i]->hdisplay ||
|
||||
height > vidmodes[i]->vdisplay)
|
||||
continue;
|
||||
|
||||
x = width - vidmodes[i]->hdisplay;
|
||||
y = height - vidmodes[i]->vdisplay;
|
||||
dist = (x * x) + (y * y);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_fit = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_fit != -1) {
|
||||
actualWidth = vidmodes[best_fit]->hdisplay;
|
||||
actualHeight = vidmodes[best_fit]->vdisplay;
|
||||
|
||||
// change to the mode
|
||||
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
|
||||
vidmode_active = true;
|
||||
|
||||
// Move the viewport to top left
|
||||
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
|
||||
} else
|
||||
fullscreen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* window attributes */
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
|
||||
attr.event_mask = X_MASK;
|
||||
if (vidmode_active) {
|
||||
mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
|
||||
CWEventMask | CWOverrideRedirect;
|
||||
attr.override_redirect = True;
|
||||
attr.backing_store = NotUseful;
|
||||
attr.save_under = False;
|
||||
} else
|
||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
win = XCreateWindow(dpy, root, 0, 0, width, height,
|
||||
0, visinfo->depth, InputOutput,
|
||||
visinfo->visual, mask, &attr);
|
||||
|
||||
sizehints = XAllocSizeHints();
|
||||
if (sizehints) {
|
||||
sizehints->min_width = width;
|
||||
sizehints->min_height = height;
|
||||
sizehints->max_width = width;
|
||||
sizehints->max_height = height;
|
||||
sizehints->base_width = width;
|
||||
sizehints->base_height = vid.height;
|
||||
|
||||
sizehints->flags = PMinSize | PMaxSize | PBaseSize;
|
||||
}
|
||||
|
||||
XSetWMProperties(dpy, win, NULL, NULL, NULL, 0,
|
||||
sizehints, None, None);
|
||||
if (sizehints)
|
||||
XFree(sizehints);
|
||||
|
||||
XMapWindow(dpy, win);
|
||||
|
||||
if (vidmode_active) {
|
||||
XMoveWindow(dpy, win, 0, 0);
|
||||
XRaiseWindow(dpy, win);
|
||||
XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
|
||||
XFlush(dpy);
|
||||
// Move the viewport to top left
|
||||
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
|
||||
}
|
||||
|
||||
XFlush(dpy);
|
||||
|
||||
ctx = qglXCreateContext(dpy, visinfo, NULL, True);
|
||||
|
||||
qglXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
*pwidth = width;
|
||||
*pheight = height;
|
||||
|
||||
// let the sound and input subsystems know about the new window
|
||||
ri.Vid_NewWindow (width, height);
|
||||
|
||||
qglXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
return rserr_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_Shutdown
|
||||
**
|
||||
** This routine does all OS specific shutdown procedures for the OpenGL
|
||||
** subsystem. Under OpenGL this means NULLing out the current DC and
|
||||
** HGLRC, deleting the rendering context, and releasing the DC acquired
|
||||
** for the window. The state structure is also nulled out.
|
||||
**
|
||||
*/
|
||||
void GLimp_Shutdown( void )
|
||||
{
|
||||
uninstall_grabs();
|
||||
mouse_active = false;
|
||||
dgamouse = false;
|
||||
|
||||
if (dpy) {
|
||||
if (ctx)
|
||||
qglXDestroyContext(dpy, ctx);
|
||||
if (win)
|
||||
XDestroyWindow(dpy, win);
|
||||
if (vidmode_active)
|
||||
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]);
|
||||
XUngrabKeyboard(dpy, CurrentTime);
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
ctx = NULL;
|
||||
dpy = NULL;
|
||||
win = 0;
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_Init
|
||||
**
|
||||
** This routine is responsible for initializing the OS specific portions
|
||||
** of OpenGL.
|
||||
*/
|
||||
int GLimp_Init( void *hinstance, void *wndproc )
|
||||
{
|
||||
InitSig();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_BeginFrame
|
||||
*/
|
||||
void GLimp_BeginFrame( float camera_seperation )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_EndFrame
|
||||
**
|
||||
** Responsible for doing a swapbuffers and possibly for other stuff
|
||||
** as yet to be determined. Probably better not to make this a GLimp
|
||||
** function and instead do a call to GLimp_SwapBuffers.
|
||||
*/
|
||||
void GLimp_EndFrame (void)
|
||||
{
|
||||
qglFlush();
|
||||
qglXSwapBuffers(dpy, win);
|
||||
}
|
||||
|
||||
/*
|
||||
** GLimp_AppActivate
|
||||
*/
|
||||
void GLimp_AppActivate( qboolean active )
|
||||
{
|
||||
}
|
||||
|
||||
void Fake_glColorTableEXT( GLenum target, GLenum internalformat,
|
||||
GLsizei width, GLenum format, GLenum type,
|
||||
const GLvoid *table )
|
||||
{
|
||||
byte temptable[256][4];
|
||||
byte *intbl;
|
||||
int i;
|
||||
|
||||
for (intbl = (byte *)table, i = 0; i < 256; i++) {
|
||||
temptable[i][2] = *intbl++;
|
||||
temptable[i][1] = *intbl++;
|
||||
temptable[i][0] = *intbl++;
|
||||
temptable[i][3] = 255;
|
||||
}
|
||||
qgl3DfxSetPaletteEXT((GLuint *)temptable);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------*/
|
||||
/* X11 Input Stuff
|
||||
/*------------------------------------------------*/
|
||||
|
217
bsd/q_shbsd.c
Normal file
217
bsd/q_shbsd.c
Normal file
|
@ -0,0 +1,217 @@
|
|||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "../linux/glob.h"
|
||||
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
//===============================================================================
|
||||
|
||||
byte *membase;
|
||||
int maxhunksize;
|
||||
int curhunksize;
|
||||
|
||||
void *Hunk_Begin (int maxsize)
|
||||
{
|
||||
// reserve a huge chunk of memory, but don't commit any yet
|
||||
maxhunksize = maxsize + sizeof(int);
|
||||
curhunksize = 0;
|
||||
membase = mmap(0, maxhunksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
|
||||
if (membase == NULL || membase == (byte *)-1)
|
||||
Sys_Error("unable to allocate %d bytes", maxsize);
|
||||
|
||||
*((int *)membase) = curhunksize;
|
||||
|
||||
return membase + sizeof(int);
|
||||
}
|
||||
|
||||
void *Hunk_Alloc (int size)
|
||||
{
|
||||
byte *buf;
|
||||
|
||||
// round to cacheline
|
||||
size = (size+31)&~31;
|
||||
if (curhunksize + size > maxhunksize)
|
||||
Sys_Error("Hunk_Alloc overflow");
|
||||
buf = membase + sizeof(int) + curhunksize;
|
||||
curhunksize += size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
int Hunk_End (void)
|
||||
{
|
||||
long pgsz, newsz, modsz;
|
||||
|
||||
pgsz = sysconf(_SC_PAGESIZE);
|
||||
if (pgsz == -1)
|
||||
Sys_Error("Hunk_End: Sysconf() failed: %s", strerror(errno));
|
||||
|
||||
newsz = curhunksize + sizeof(int);
|
||||
|
||||
if (newsz > maxhunksize)
|
||||
Sys_Error("Hunk_End Overflow");
|
||||
else if (newsz < maxhunksize) {
|
||||
modsz = newsz % pgsz;
|
||||
if (modsz) newsz += pgsz - modsz;
|
||||
|
||||
if (munmap(membase + newsz, maxhunksize - newsz) == -1)
|
||||
Sys_Error("Hunk_End: munmap() failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
*((int *)membase) = curhunksize + sizeof(int);
|
||||
|
||||
return curhunksize;
|
||||
}
|
||||
|
||||
void Hunk_Free (void *base)
|
||||
{
|
||||
byte *m;
|
||||
|
||||
if (base) {
|
||||
m = ((byte *)base) - sizeof(int);
|
||||
if (munmap(m, *((int *)m)))
|
||||
Sys_Error("Hunk_Free: munmap failed (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_Milliseconds
|
||||
================
|
||||
*/
|
||||
int curtime;
|
||||
int Sys_Milliseconds (void)
|
||||
{
|
||||
struct timeval tp;
|
||||
struct timezone tzp;
|
||||
static int secbase;
|
||||
|
||||
gettimeofday(&tp, &tzp);
|
||||
|
||||
if (!secbase)
|
||||
{
|
||||
secbase = tp.tv_sec;
|
||||
return tp.tv_usec/1000;
|
||||
}
|
||||
|
||||
curtime = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
|
||||
|
||||
return curtime;
|
||||
}
|
||||
|
||||
void Sys_Mkdir (char *path)
|
||||
{
|
||||
mkdir (path, 0777);
|
||||
}
|
||||
|
||||
char *strlwr (char *s)
|
||||
{
|
||||
while (*s) {
|
||||
*s = tolower(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================
|
||||
|
||||
static char findbase[MAX_OSPATH];
|
||||
static char findpath[MAX_OSPATH];
|
||||
static char findpattern[MAX_OSPATH];
|
||||
static DIR *fdir;
|
||||
|
||||
static qboolean CompareAttributes(char *path, char *name,
|
||||
unsigned musthave, unsigned canthave )
|
||||
{
|
||||
struct stat st;
|
||||
char fn[MAX_OSPATH];
|
||||
|
||||
// . and .. never match
|
||||
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
|
||||
return false;
|
||||
|
||||
sprintf(fn, "%s/%s", path, name);
|
||||
if (stat(fn, &st) == -1)
|
||||
return false; // shouldn't happen
|
||||
|
||||
if ( ( st.st_mode & S_IFDIR ) && ( canthave & SFF_SUBDIR ) )
|
||||
return false;
|
||||
|
||||
if ( ( musthave & SFF_SUBDIR ) && !( st.st_mode & S_IFDIR ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *Sys_FindFirst (char *path, unsigned musthave, unsigned canhave)
|
||||
{
|
||||
struct dirent *d;
|
||||
char *p;
|
||||
|
||||
if (fdir)
|
||||
Sys_Error ("Sys_BeginFind without close");
|
||||
|
||||
// COM_FilePath (path, findbase);
|
||||
strcpy(findbase, path);
|
||||
|
||||
if ((p = strrchr(findbase, '/')) != NULL) {
|
||||
*p = 0;
|
||||
strcpy(findpattern, p + 1);
|
||||
} else
|
||||
strcpy(findpattern, "*");
|
||||
|
||||
if (strcmp(findpattern, "*.*") == 0)
|
||||
strcpy(findpattern, "*");
|
||||
|
||||
if ((fdir = opendir(findbase)) == NULL)
|
||||
return NULL;
|
||||
while ((d = readdir(fdir)) != NULL) {
|
||||
if (!*findpattern || glob_match(findpattern, d->d_name)) {
|
||||
// if (*findpattern)
|
||||
// printf("%s matched %s\n", findpattern, d->d_name);
|
||||
if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
|
||||
sprintf (findpath, "%s/%s", findbase, d->d_name);
|
||||
return findpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *Sys_FindNext (unsigned musthave, unsigned canhave)
|
||||
{
|
||||
struct dirent *d;
|
||||
|
||||
if (fdir == NULL)
|
||||
return NULL;
|
||||
while ((d = readdir(fdir)) != NULL) {
|
||||
if (!*findpattern || glob_match(findpattern, d->d_name)) {
|
||||
// if (*findpattern)
|
||||
// printf("%s matched %s\n", findpattern, d->d_name);
|
||||
if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
|
||||
sprintf (findpath, "%s/%s", findbase, d->d_name);
|
||||
return findpath;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Sys_FindClose (void)
|
||||
{
|
||||
if (fdir != NULL)
|
||||
closedir(fdir);
|
||||
fdir = NULL;
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
|
4130
bsd/qgl_bsd.c
Normal file
4130
bsd/qgl_bsd.c
Normal file
File diff suppressed because it is too large
Load diff
266
bsd/snd_bsd.c
Normal file
266
bsd/snd_bsd.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
#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 <soundcard.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../client/client.h"
|
||||
#include "../client/snd_loc.h"
|
||||
|
||||
int audio_fd;
|
||||
int snd_inited;
|
||||
|
||||
cvar_t *sndbits;
|
||||
cvar_t *sndspeed;
|
||||
cvar_t *sndchannels;
|
||||
cvar_t *snddevice;
|
||||
|
||||
static int tryrates[] = { 11025, 22051, 44100, 8000 };
|
||||
|
||||
qboolean SNDDMA_Init(void)
|
||||
{
|
||||
|
||||
int rc;
|
||||
int fmt;
|
||||
int tmp;
|
||||
int i;
|
||||
char *s;
|
||||
struct audio_buf_info info;
|
||||
int caps;
|
||||
extern uid_t saved_euid;
|
||||
|
||||
if (snd_inited)
|
||||
return;
|
||||
|
||||
if (!snddevice) {
|
||||
sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
|
||||
sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
|
||||
sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
|
||||
snddevice = Cvar_Get("snddevice", "/dev/audio", CVAR_ARCHIVE);
|
||||
}
|
||||
|
||||
// open /dev/dsp, confirm capability to mmap, and get size of dma buffer
|
||||
|
||||
if (!audio_fd) {
|
||||
seteuid(saved_euid);
|
||||
|
||||
audio_fd = open(snddevice->string, O_RDWR);
|
||||
|
||||
seteuid(getuid());
|
||||
|
||||
if (audio_fd < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not open %s\n", snddevice->string);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not reset %s\n", snddevice->string);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Sound driver too old\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
|
||||
{
|
||||
Com_Printf("Sorry but your soundcard can't do this\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
|
||||
{
|
||||
perror("GETOSPACE");
|
||||
Com_Printf("Um, can't do GETOSPACE?\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set sample bits & speed
|
||||
|
||||
dma.samplebits = (int)sndbits->value;
|
||||
if (dma.samplebits != 16 && dma.samplebits != 8)
|
||||
{
|
||||
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
|
||||
if (fmt & AFMT_S16_LE) dma.samplebits = 16;
|
||||
else if (fmt & AFMT_U8) dma.samplebits = 8;
|
||||
}
|
||||
|
||||
dma.speed = (int)sndspeed->value;
|
||||
if (!dma.speed) {
|
||||
for (i=0 ; i<sizeof(tryrates)/4 ; i++)
|
||||
if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
|
||||
dma.speed = tryrates[i];
|
||||
}
|
||||
|
||||
dma.channels = (int)sndchannels->value;
|
||||
if (dma.channels < 1 || dma.channels > 2)
|
||||
dma.channels = 2;
|
||||
|
||||
dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
|
||||
dma.submission_chunk = 1;
|
||||
|
||||
// memory map the dma buffer
|
||||
|
||||
if (!dma.buffer)
|
||||
dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
|
||||
* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
|
||||
if (!dma.buffer)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not mmap %s\n", snddevice->string);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = 0;
|
||||
if (dma.channels == 2)
|
||||
tmp = 1;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not set %s to stereo=%d", snddevice->string, dma.channels);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
if (tmp)
|
||||
dma.channels = 2;
|
||||
else
|
||||
dma.channels = 1;
|
||||
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not set %s speed to %d", snddevice->string, dma.speed);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dma.samplebits == 16)
|
||||
{
|
||||
rc = AFMT_S16_LE;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not support 16-bit data. Try 8-bit.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (dma.samplebits == 8)
|
||||
{
|
||||
rc = AFMT_U8;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not support 8-bit data.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("%d-bit sound not supported.", dma.samplebits);
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// toggle the trigger & start her up
|
||||
|
||||
tmp = 0;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not toggle.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
tmp = PCM_ENABLE_OUTPUT;
|
||||
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
|
||||
if (rc < 0)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Could not toggle.\n");
|
||||
close(audio_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dma.samplepos = 0;
|
||||
|
||||
snd_inited = 1;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int SNDDMA_GetDMAPos(void)
|
||||
{
|
||||
|
||||
struct count_info count;
|
||||
|
||||
if (!snd_inited) return 0;
|
||||
|
||||
if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
|
||||
{
|
||||
perror(snddevice->string);
|
||||
Com_Printf("Uh, sound dead.\n");
|
||||
close(audio_fd);
|
||||
snd_inited = 0;
|
||||
return 0;
|
||||
}
|
||||
// dma.samplepos = (count.bytes / (dma.samplebits / 8)) & (dma.samples-1);
|
||||
// fprintf(stderr, "%d \r", count.ptr);
|
||||
dma.samplepos = count.ptr / (dma.samplebits / 8);
|
||||
|
||||
return dma.samplepos;
|
||||
|
||||
}
|
||||
|
||||
void SNDDMA_Shutdown(void)
|
||||
{
|
||||
#if 0
|
||||
if (snd_inited)
|
||||
{
|
||||
close(audio_fd);
|
||||
snd_inited = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Submit
|
||||
|
||||
Send sound to device if buffer isn't really the dma buffer
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Submit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SNDDMA_BeginPainting (void)
|
||||
{
|
||||
}
|
||||
|
406
bsd/sys_bsd.c
Normal file
406
bsd/sys_bsd.c
Normal file
|
@ -0,0 +1,406 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 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.
|
||||
|
||||
*/
|
||||
#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>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <fstab.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW RTLD_LAZY
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define dlsym(X, Y) dlsym(X, "_"##Y)
|
||||
#endif
|
||||
|
||||
#include "../qcommon/qcommon.h"
|
||||
|
||||
#include "../linux/rw_linux.h"
|
||||
|
||||
cvar_t *nostdout;
|
||||
|
||||
unsigned sys_frame_time;
|
||||
|
||||
uid_t saved_euid;
|
||||
qboolean stdin_active = true;
|
||||
|
||||
// =======================================================================
|
||||
// General routines
|
||||
// =======================================================================
|
||||
|
||||
void Sys_ConsoleOutput (char *string)
|
||||
{
|
||||
if (nostdout && nostdout->value)
|
||||
return;
|
||||
|
||||
fputs(string, stdout);
|
||||
}
|
||||
|
||||
void Sys_Printf (char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
unsigned char *p;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsnprintf (text,1024,fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
if (strlen(text) > sizeof(text))
|
||||
Sys_Error("memory overwrite in Sys_Printf");
|
||||
|
||||
if (nostdout && nostdout->value)
|
||||
return;
|
||||
|
||||
for (p = (unsigned char *)text; *p; p++) {
|
||||
*p &= 0x7f;
|
||||
if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
|
||||
printf("[%02x]", *p);
|
||||
else
|
||||
putc(*p, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void Sys_Quit (void)
|
||||
{
|
||||
CL_Shutdown ();
|
||||
Qcommon_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 (char *error, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
// change stdin to non blocking
|
||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||
|
||||
CL_Shutdown ();
|
||||
Qcommon_Shutdown ();
|
||||
|
||||
va_start (argptr,error);
|
||||
vsnprintf (string,1024,error,argptr);
|
||||
va_end (argptr);
|
||||
fprintf(stderr, "Error: %s\n", string);
|
||||
|
||||
_exit (1);
|
||||
|
||||
}
|
||||
|
||||
void Sys_Warn (char *warning, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
|
||||
va_start (argptr,warning);
|
||||
vsnprintf (string,1024,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 floating_point_exception_handler(int whatever)
|
||||
{
|
||||
// Sys_Warn("floating point exception\n");
|
||||
signal(SIGFPE, floating_point_exception_handler);
|
||||
}
|
||||
|
||||
char *Sys_ConsoleInput(void)
|
||||
{
|
||||
static char text[256];
|
||||
int len;
|
||||
fd_set fdset;
|
||||
struct timeval timeout;
|
||||
|
||||
if (!dedicated || !dedicated->value)
|
||||
return NULL;
|
||||
|
||||
if (!stdin_active)
|
||||
return NULL;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(0, &fdset); // stdin
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
|
||||
return NULL;
|
||||
|
||||
len = read (0, text, sizeof(text));
|
||||
if (len == 0) { // eof!
|
||||
stdin_active = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < 1)
|
||||
return NULL;
|
||||
text[len-1] = 0; // rip off the /n and terminate
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void *game_library;
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_UnloadGame
|
||||
=================
|
||||
*/
|
||||
void Sys_UnloadGame (void)
|
||||
{
|
||||
if (game_library)
|
||||
dlclose (game_library);
|
||||
game_library = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Sys_GetGameAPI
|
||||
|
||||
Loads the game dll
|
||||
=================
|
||||
*/
|
||||
void *Sys_GetGameAPI (void *parms)
|
||||
{
|
||||
void *(*GetGameAPI) (void *);
|
||||
|
||||
char name[MAX_OSPATH];
|
||||
char *path;
|
||||
#if defined __i386__
|
||||
const char *gamename = "gamei386.so";
|
||||
#elif defined __alpha__
|
||||
const char *gamename = "gameaxp.so";
|
||||
#elif defined __powerpc__
|
||||
const char *gamename = "gameppc.so";
|
||||
#else
|
||||
#error Unknown arch
|
||||
#endif
|
||||
|
||||
seteuid(getuid());
|
||||
setegid(getgid());
|
||||
|
||||
if (game_library)
|
||||
Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
|
||||
|
||||
Com_Printf("------- Loading %s -------\n", gamename);
|
||||
|
||||
// now run through the search paths
|
||||
path = NULL;
|
||||
while (1)
|
||||
{
|
||||
path = FS_NextPath (path);
|
||||
if (!path)
|
||||
return NULL; // couldn't find one anywhere
|
||||
snprintf (name, MAX_OSPATH, "%s/%s", path, gamename);
|
||||
game_library = dlopen (name, RTLD_NOW );
|
||||
if (game_library)
|
||||
{
|
||||
Com_DPrintf ("LoadLibrary (%s)\n",name);
|
||||
break;
|
||||
} else {
|
||||
Com_DPrintf ("LoadLibrary (%s) failed\n", name, dlerror());
|
||||
}
|
||||
}
|
||||
|
||||
GetGameAPI = (void *)dlsym (game_library, "GetGameAPI");
|
||||
|
||||
if (!GetGameAPI)
|
||||
{
|
||||
Sys_UnloadGame ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return GetGameAPI (parms);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void Sys_AppActivate (void)
|
||||
{
|
||||
}
|
||||
|
||||
void Sys_SendKeyEvents (void)
|
||||
{
|
||||
#ifndef DEDICATED_ONLY
|
||||
if (KBD_Update_fp)
|
||||
KBD_Update_fp();
|
||||
#endif
|
||||
|
||||
// grab frame time
|
||||
sys_frame_time = Sys_Milliseconds();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
char *Sys_GetClipboardData(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int time, oldtime, newtime;
|
||||
|
||||
// go back to real user for config loads
|
||||
saved_euid = geteuid();
|
||||
seteuid(getuid());
|
||||
|
||||
Qcommon_Init(argc, argv);
|
||||
|
||||
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
||||
|
||||
nostdout = Cvar_Get("nostdout", "0", 0);
|
||||
if (!nostdout->value) {
|
||||
fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
|
||||
// printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION);
|
||||
}
|
||||
|
||||
oldtime = Sys_Milliseconds ();
|
||||
while (1)
|
||||
{
|
||||
// find time spent rendering last frame
|
||||
do {
|
||||
newtime = Sys_Milliseconds ();
|
||||
time = newtime - oldtime;
|
||||
} while (time < 1);
|
||||
Qcommon_Frame (time);
|
||||
oldtime = newtime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Sys_CopyProtect(void)
|
||||
{
|
||||
struct fstab *ent;
|
||||
char path[MAX_OSPATH];
|
||||
struct stat st;
|
||||
qboolean found_cd = false;
|
||||
|
||||
static qboolean checked = false;
|
||||
|
||||
if (checked)
|
||||
return;
|
||||
|
||||
while ((ent = getfsent()) != NULL) {
|
||||
if (strcmp(ent->fs_vfstype, "cd9660") == 0) {
|
||||
// found a cd file system
|
||||
found_cd = true;
|
||||
sprintf(path, "%s/%s", ent->fs_file, "install/data/quake2.exe");
|
||||
if (stat(path, &st) == 0) {
|
||||
// found it
|
||||
checked = true;
|
||||
endfsent();
|
||||
return;
|
||||
}
|
||||
sprintf(path, "%s/%s", ent->fs_file, "Install/Data/quake2.exe");
|
||||
if (stat(path, &st) == 0) {
|
||||
// found it
|
||||
checked = true;
|
||||
endfsent();
|
||||
return;
|
||||
}
|
||||
sprintf(path, "%s/%s", ent->fs_file, "quake2.exe");
|
||||
if (stat(path, &st) == 0) {
|
||||
// found it
|
||||
checked = true;
|
||||
endfsent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
endfsent();
|
||||
|
||||
if (found_cd)
|
||||
Com_Error (ERR_FATAL, "Could not find a Quake2 CD in your CD drive.");
|
||||
Com_Error (ERR_FATAL, "Unable to find a mounted iso9660 file system.\n"
|
||||
"You must mount the Quake2 CD in a cdrom drive in order to play.");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
================
|
||||
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");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
544
bsd/vid_so.c
Normal file
544
bsd/vid_so.c
Normal file
|
@ -0,0 +1,544 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 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.
|
||||
|
||||
*/
|
||||
// Main windowed and fullscreen graphics interface module. This module
|
||||
// is used for both the software and OpenGL rendering versions of the
|
||||
// Quake refresh engine.
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h> // ELF dl loader
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW RTLD_LAZY
|
||||
#endif
|
||||
|
||||
#ifndef RTLD_GLOBAL
|
||||
#define RTLD_GLOBAL 0
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define dlsym(X, Y) dlsym(X, "_"##Y)
|
||||
#endif
|
||||
|
||||
#include "../client/client.h"
|
||||
|
||||
#include "../linux/rw_linux.h"
|
||||
|
||||
// Structure containing functions exported from refresh DLL
|
||||
refexport_t re;
|
||||
|
||||
// Console variables that we need to access from this module
|
||||
cvar_t *vid_gamma;
|
||||
cvar_t *vid_ref; // Name of Refresh DLL loaded
|
||||
cvar_t *vid_xpos; // X coordinate of window position
|
||||
cvar_t *vid_ypos; // Y coordinate of window position
|
||||
cvar_t *vid_fullscreen;
|
||||
|
||||
// Global variables used internally by this module
|
||||
viddef_t viddef; // global video state; used by other modules
|
||||
void *reflib_library; // Handle to refresh DLL
|
||||
qboolean reflib_active = 0;
|
||||
|
||||
#define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
|
||||
|
||||
/** KEYBOARD **************************************************************/
|
||||
|
||||
void Do_Key_Event(int key, qboolean down);
|
||||
|
||||
void (*KBD_Update_fp)(void);
|
||||
void (*KBD_Init_fp)(Key_Event_fp_t fp);
|
||||
void (*KBD_Close_fp)(void);
|
||||
|
||||
/** MOUSE *****************************************************************/
|
||||
|
||||
in_state_t in_state;
|
||||
|
||||
void (*RW_IN_Init_fp)(in_state_t *in_state_p);
|
||||
void (*RW_IN_Shutdown_fp)(void);
|
||||
void (*RW_IN_Activate_fp)(qboolean active);
|
||||
void (*RW_IN_Commands_fp)(void);
|
||||
void (*RW_IN_Move_fp)(usercmd_t *cmd);
|
||||
void (*RW_IN_Frame_fp)(void);
|
||||
|
||||
void Real_IN_Init (void);
|
||||
|
||||
/*
|
||||
==========================================================================
|
||||
|
||||
DLL GLUE
|
||||
|
||||
==========================================================================
|
||||
*/
|
||||
|
||||
#define MAXPRINTMSG 4096
|
||||
void VID_Printf (int print_level, char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char msg[MAXPRINTMSG];
|
||||
static qboolean inupdate;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsnprintf (msg,MAXPRINTMSG,fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
if (print_level == PRINT_ALL)
|
||||
Com_Printf ("%s", msg);
|
||||
else
|
||||
Com_DPrintf ("%s", msg);
|
||||
}
|
||||
|
||||
void VID_Error (int err_level, char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char msg[MAXPRINTMSG];
|
||||
static qboolean inupdate;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsnprintf (msg,MAXPRINTMSG,fmt,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
Com_Error (err_level,"%s", msg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Restart_f
|
||||
|
||||
Console command to re-start the video mode and refresh DLL. We do this
|
||||
simply by setting the modified flag for the vid_ref variable, which will
|
||||
cause the entire video mode and refresh DLL to be reset on the next frame.
|
||||
============
|
||||
*/
|
||||
void VID_Restart_f (void)
|
||||
{
|
||||
vid_ref->modified = true;
|
||||
}
|
||||
|
||||
/*
|
||||
** VID_GetModeInfo
|
||||
*/
|
||||
typedef struct vidmode_s
|
||||
{
|
||||
const char *description;
|
||||
int width, height;
|
||||
int mode;
|
||||
} vidmode_t;
|
||||
|
||||
vidmode_t vid_modes[] =
|
||||
{
|
||||
{ "Mode 0: 320x240", 320, 240, 0 },
|
||||
{ "Mode 1: 400x300", 400, 300, 1 },
|
||||
{ "Mode 2: 512x384", 512, 384, 2 },
|
||||
{ "Mode 3: 640x480", 640, 480, 3 },
|
||||
{ "Mode 4: 800x600", 800, 600, 4 },
|
||||
{ "Mode 5: 960x720", 960, 720, 5 },
|
||||
{ "Mode 6: 1024x768", 1024, 768, 6 },
|
||||
{ "Mode 7: 1152x864", 1152, 864, 7 },
|
||||
{ "Mode 8: 1280x1024", 1280, 1024, 8 },
|
||||
{ "Mode 9: 1600x1200", 1600, 1200, 9 },
|
||||
{ "Mode 10: 2048x1536", 2048, 1536, 10 }
|
||||
};
|
||||
|
||||
qboolean VID_GetModeInfo( int *width, int *height, int mode )
|
||||
{
|
||||
if ( mode < 0 || mode >= VID_NUM_MODES )
|
||||
return false;
|
||||
|
||||
*width = vid_modes[mode].width;
|
||||
*height = vid_modes[mode].height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
** VID_NewWindow
|
||||
*/
|
||||
void VID_NewWindow ( int width, int height)
|
||||
{
|
||||
viddef.width = width;
|
||||
viddef.height = height;
|
||||
}
|
||||
|
||||
void VID_FreeReflib (void)
|
||||
{
|
||||
if (reflib_library) {
|
||||
if (KBD_Close_fp)
|
||||
KBD_Close_fp();
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
dlclose(reflib_library);
|
||||
}
|
||||
|
||||
KBD_Init_fp = NULL;
|
||||
KBD_Update_fp = NULL;
|
||||
KBD_Close_fp = NULL;
|
||||
RW_IN_Init_fp = NULL;
|
||||
RW_IN_Shutdown_fp = NULL;
|
||||
RW_IN_Activate_fp = NULL;
|
||||
RW_IN_Commands_fp = NULL;
|
||||
RW_IN_Move_fp = NULL;
|
||||
RW_IN_Frame_fp = NULL;
|
||||
|
||||
memset (&re, 0, sizeof(re));
|
||||
reflib_library = NULL;
|
||||
reflib_active = false;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
VID_LoadRefresh
|
||||
==============
|
||||
*/
|
||||
qboolean VID_LoadRefresh( char *name )
|
||||
{
|
||||
refimport_t ri;
|
||||
GetRefAPI_t GetRefAPI;
|
||||
char fn[MAX_OSPATH];
|
||||
char *path;
|
||||
struct stat st;
|
||||
extern uid_t saved_euid;
|
||||
FILE *fp;
|
||||
|
||||
if ( reflib_active )
|
||||
{
|
||||
if (KBD_Close_fp)
|
||||
KBD_Close_fp();
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
KBD_Close_fp = NULL;
|
||||
RW_IN_Shutdown_fp = NULL;
|
||||
re.Shutdown();
|
||||
VID_FreeReflib ();
|
||||
}
|
||||
|
||||
Com_Printf( "------- Loading %s -------\n", name );
|
||||
|
||||
//regain root
|
||||
seteuid(saved_euid);
|
||||
|
||||
#if 0
|
||||
if ((fp = fopen(so_file, "r")) == NULL) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: can't open %s (required for location of ref libraries)\n", name, so_file);
|
||||
return false;
|
||||
}
|
||||
fgets(fn, sizeof(fn), fp);
|
||||
fclose(fp);
|
||||
while (*fn && isspace(fn[strlen(fn) - 1]))
|
||||
fn[strlen(fn) - 1] = 0;
|
||||
|
||||
strcat(fn, "/");
|
||||
strcat(fn, name);
|
||||
#endif
|
||||
|
||||
path = Cvar_Get ("basedir", ".", CVAR_NOSET)->string;
|
||||
|
||||
snprintf (fn, MAX_OSPATH, "%s/%s", path, name );
|
||||
|
||||
if (stat(fn, &st) == -1) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
// permission checking
|
||||
if (strstr(fn, "softx") == NULL &&
|
||||
strstr(fn, "glx") == NULL &&
|
||||
strstr(fn, "softsdl") == NULL &&
|
||||
strstr(fn, "sdlgl") == NULL) { // softx doesn't require root
|
||||
#if 0
|
||||
if (st.st_uid != 0) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: ref is not owned by root\n", name);
|
||||
return false;
|
||||
}
|
||||
if ((st.st_mode & 0777) & ~0700) {
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: invalid permissions, must be 700 for security considerations\n", name);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// softx requires we give up root now
|
||||
seteuid(getuid());
|
||||
setegid(getgid());
|
||||
}
|
||||
|
||||
if ( ( reflib_library = dlopen( fn, RTLD_LAZY | RTLD_GLOBAL ) ) == 0 )
|
||||
{
|
||||
Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name , dlerror());
|
||||
return false;
|
||||
}
|
||||
|
||||
Com_Printf( "LoadLibrary(\"%s\")\n", fn );
|
||||
|
||||
ri.Cmd_AddCommand = Cmd_AddCommand;
|
||||
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
|
||||
ri.Cmd_Argc = Cmd_Argc;
|
||||
ri.Cmd_Argv = Cmd_Argv;
|
||||
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
|
||||
ri.Con_Printf = VID_Printf;
|
||||
ri.Sys_Error = VID_Error;
|
||||
ri.FS_LoadFile = FS_LoadFile;
|
||||
ri.FS_FreeFile = FS_FreeFile;
|
||||
ri.FS_Gamedir = FS_Gamedir;
|
||||
ri.Cvar_Get = Cvar_Get;
|
||||
ri.Cvar_Set = Cvar_Set;
|
||||
ri.Cvar_SetValue = Cvar_SetValue;
|
||||
ri.Vid_GetModeInfo = VID_GetModeInfo;
|
||||
ri.Vid_MenuInit = VID_MenuInit;
|
||||
ri.Vid_NewWindow = VID_NewWindow;
|
||||
|
||||
if ( ( GetRefAPI = (void *) dlsym( reflib_library, "GetRefAPI" ) ) == 0 )
|
||||
Com_Error( ERR_FATAL, "dlsym failed on %s", name );
|
||||
|
||||
re = GetRefAPI( ri );
|
||||
|
||||
if (re.api_version != API_VERSION)
|
||||
{
|
||||
VID_FreeReflib ();
|
||||
Com_Error (ERR_FATAL, "%s has incompatible api_version", name);
|
||||
}
|
||||
|
||||
/* Init IN (Mouse) */
|
||||
in_state.IN_CenterView_fp = IN_CenterView;
|
||||
in_state.Key_Event_fp = Do_Key_Event;
|
||||
in_state.viewangles = cl.viewangles;
|
||||
in_state.in_strafe_state = &in_strafe.state;
|
||||
|
||||
if ((RW_IN_Init_fp = dlsym(reflib_library, "RW_IN_Init")) == NULL ||
|
||||
(RW_IN_Shutdown_fp = dlsym(reflib_library, "RW_IN_Shutdown")) == NULL ||
|
||||
(RW_IN_Activate_fp = dlsym(reflib_library, "RW_IN_Activate")) == NULL ||
|
||||
(RW_IN_Commands_fp = dlsym(reflib_library, "RW_IN_Commands")) == NULL ||
|
||||
(RW_IN_Move_fp = dlsym(reflib_library, "RW_IN_Move")) == NULL ||
|
||||
(RW_IN_Frame_fp = dlsym(reflib_library, "RW_IN_Frame")) == NULL)
|
||||
Sys_Error("No RW_IN functions in REF.\n");
|
||||
|
||||
Real_IN_Init();
|
||||
|
||||
if ( re.Init( 0, 0 ) == -1 )
|
||||
{
|
||||
re.Shutdown();
|
||||
VID_FreeReflib ();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Init KBD */
|
||||
#if 1
|
||||
if ((KBD_Init_fp = dlsym(reflib_library, "KBD_Init")) == NULL ||
|
||||
(KBD_Update_fp = dlsym(reflib_library, "KBD_Update")) == NULL ||
|
||||
(KBD_Close_fp = dlsym(reflib_library, "KBD_Close")) == NULL)
|
||||
Sys_Error("No KBD functions in REF.\n");
|
||||
#else
|
||||
{
|
||||
void KBD_Init(void);
|
||||
void KBD_Update(void);
|
||||
void KBD_Close(void);
|
||||
|
||||
KBD_Init_fp = KBD_Init;
|
||||
KBD_Update_fp = KBD_Update;
|
||||
KBD_Close_fp = KBD_Close;
|
||||
}
|
||||
#endif
|
||||
KBD_Init_fp(Do_Key_Event);
|
||||
|
||||
Key_ClearStates();
|
||||
|
||||
// give up root now
|
||||
seteuid(getuid());
|
||||
setegid(getgid());
|
||||
|
||||
Com_Printf( "------------------------------------\n");
|
||||
reflib_active = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_CheckChanges
|
||||
|
||||
This function gets called once just before drawing each frame, and it's sole purpose in life
|
||||
is to check to see if any of the video mode parameters have changed, and if they have to
|
||||
update the rendering DLL and/or video mode to match.
|
||||
============
|
||||
*/
|
||||
void VID_CheckChanges (void)
|
||||
{
|
||||
char name[100];
|
||||
cvar_t *sw_mode;
|
||||
|
||||
if ( vid_ref->modified )
|
||||
{
|
||||
S_StopAllSounds();
|
||||
}
|
||||
|
||||
while (vid_ref->modified)
|
||||
{
|
||||
/*
|
||||
** refresh has changed
|
||||
*/
|
||||
vid_ref->modified = false;
|
||||
vid_fullscreen->modified = true;
|
||||
cl.refresh_prepped = false;
|
||||
cls.disable_screen = true;
|
||||
|
||||
sprintf( name, "ref_%s.so", vid_ref->string );
|
||||
if ( !VID_LoadRefresh( name ) )
|
||||
{
|
||||
if ( strcmp (vid_ref->string, "soft") == 0 ||
|
||||
strcmp (vid_ref->string, "softx") == 0 ) {
|
||||
Com_Printf("Refresh failed\n");
|
||||
sw_mode = Cvar_Get( "sw_mode", "0", 0 );
|
||||
if (sw_mode->value != 0) {
|
||||
Com_Printf("Trying mode 0\n");
|
||||
Cvar_SetValue("sw_mode", 0);
|
||||
if ( !VID_LoadRefresh( name ) )
|
||||
Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!");
|
||||
} else
|
||||
Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!");
|
||||
}
|
||||
|
||||
/* prefer to fall back on X if active */
|
||||
if (getenv("DISPLAY"))
|
||||
Cvar_Set( "vid_ref", "softx" );
|
||||
else
|
||||
Cvar_Set( "vid_ref", "soft" );
|
||||
|
||||
/*
|
||||
** drop the console if we fail to load a refresh
|
||||
*/
|
||||
if ( cls.key_dest != key_console )
|
||||
{
|
||||
Con_ToggleConsole_f();
|
||||
}
|
||||
}
|
||||
cls.disable_screen = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Init
|
||||
============
|
||||
*/
|
||||
void VID_Init (void)
|
||||
{
|
||||
/* Create the video variables so we know how to start the graphics drivers */
|
||||
// if DISPLAY is defined, try X
|
||||
if (getenv("DISPLAY"))
|
||||
vid_ref = Cvar_Get ("vid_ref", "softx", CVAR_ARCHIVE);
|
||||
else
|
||||
vid_ref = Cvar_Get ("vid_ref", "soft", CVAR_ARCHIVE);
|
||||
vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
|
||||
vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
|
||||
vid_fullscreen = Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE);
|
||||
vid_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE );
|
||||
|
||||
/* Add some console commands that we want to handle */
|
||||
Cmd_AddCommand ("vid_restart", VID_Restart_f);
|
||||
|
||||
/* Disable the 3Dfx splash screen */
|
||||
putenv("FX_GLIDE_NO_SPLASH=0");
|
||||
|
||||
/* Start the graphics mode and load refresh DLL */
|
||||
VID_CheckChanges();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Shutdown
|
||||
============
|
||||
*/
|
||||
void VID_Shutdown (void)
|
||||
{
|
||||
if ( reflib_active )
|
||||
{
|
||||
if (KBD_Close_fp)
|
||||
KBD_Close_fp();
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
KBD_Close_fp = NULL;
|
||||
RW_IN_Shutdown_fp = NULL;
|
||||
re.Shutdown ();
|
||||
VID_FreeReflib ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* INPUT */
|
||||
/*****************************************************************************/
|
||||
|
||||
cvar_t *in_joystick;
|
||||
|
||||
// This is fake, it's acutally done by the Refresh load
|
||||
void IN_Init (void)
|
||||
{
|
||||
in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE);
|
||||
}
|
||||
|
||||
void Real_IN_Init (void)
|
||||
{
|
||||
if (RW_IN_Init_fp)
|
||||
RW_IN_Init_fp(&in_state);
|
||||
}
|
||||
|
||||
void IN_Shutdown (void)
|
||||
{
|
||||
if (RW_IN_Shutdown_fp)
|
||||
RW_IN_Shutdown_fp();
|
||||
}
|
||||
|
||||
void IN_Commands (void)
|
||||
{
|
||||
if (RW_IN_Commands_fp)
|
||||
RW_IN_Commands_fp();
|
||||
}
|
||||
|
||||
void IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
if (RW_IN_Move_fp)
|
||||
RW_IN_Move_fp(cmd);
|
||||
}
|
||||
|
||||
void IN_Frame (void)
|
||||
{
|
||||
if (RW_IN_Activate_fp)
|
||||
{
|
||||
if ( !cl.refresh_prepped || cls.key_dest == key_console || cls.key_dest == key_menu)
|
||||
RW_IN_Activate_fp(false);
|
||||
else
|
||||
RW_IN_Activate_fp(true);
|
||||
}
|
||||
|
||||
if (RW_IN_Frame_fp)
|
||||
RW_IN_Frame_fp();
|
||||
}
|
||||
|
||||
void IN_Activate (qboolean active)
|
||||
{
|
||||
}
|
||||
|
||||
void Do_Key_Event(int key, qboolean down)
|
||||
{
|
||||
Key_Event(key, down, Sys_Milliseconds());
|
||||
}
|
||||
|
|
@ -40,11 +40,11 @@ gitem_armor_t jacketarmor_info = { 25, 50, .30, .00, ARMOR_JACKET};
|
|||
gitem_armor_t combatarmor_info = { 50, 100, .60, .30, ARMOR_COMBAT};
|
||||
gitem_armor_t bodyarmor_info = {100, 200, .80, .60, ARMOR_BODY};
|
||||
|
||||
static int jacket_armor_index;
|
||||
static int combat_armor_index;
|
||||
static int body_armor_index;
|
||||
static int power_screen_index;
|
||||
static int power_shield_index;
|
||||
int jacket_armor_index;
|
||||
int combat_armor_index;
|
||||
int body_armor_index;
|
||||
int power_screen_index;
|
||||
int power_shield_index;
|
||||
|
||||
#define HEALTH_IGNORE_MAX 1
|
||||
#define HEALTH_TIMED 2
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "m_player.h"
|
||||
|
||||
|
||||
static qboolean is_quad;
|
||||
qboolean is_quad;
|
||||
static byte is_silenced;
|
||||
|
||||
|
||||
|
|
|
@ -40,11 +40,11 @@ gitem_armor_t jacketarmor_info = { 25, 50, .30, .00, ARMOR_JACKET};
|
|||
gitem_armor_t combatarmor_info = { 50, 100, .60, .30, ARMOR_COMBAT};
|
||||
gitem_armor_t bodyarmor_info = {100, 200, .80, .60, ARMOR_BODY};
|
||||
|
||||
static int jacket_armor_index;
|
||||
static int combat_armor_index;
|
||||
static int body_armor_index;
|
||||
static int power_screen_index;
|
||||
static int power_shield_index;
|
||||
int jacket_armor_index;
|
||||
int combat_armor_index;
|
||||
int body_armor_index;
|
||||
int power_screen_index;
|
||||
int power_shield_index;
|
||||
|
||||
#define HEALTH_IGNORE_MAX 1
|
||||
#define HEALTH_TIMED 2
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "m_player.h"
|
||||
|
||||
|
||||
static qboolean is_quad;
|
||||
qboolean is_quad;
|
||||
static byte is_silenced;
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#ifndef __ASM_I386__
|
||||
#define __ASM_I386__
|
||||
|
||||
#ifdef ELF
|
||||
#if defined ELF && !defined __OpenBSD__
|
||||
#define C(label) label
|
||||
#else
|
||||
#define C(label) _##label
|
||||
|
|
15
ref_gl/qgl.h
15
ref_gl/qgl.h
|
@ -33,6 +33,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#ifdef __linux__
|
||||
//#include <GL/fxmesa.h>
|
||||
#include <GL/glx.h>
|
||||
#ifndef __GLW_LINUX_H
|
||||
#include "../linux/glw_linux.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
qboolean QGL_Init( const char *dllname );
|
||||
|
@ -42,6 +45,16 @@ void QGL_Shutdown( void );
|
|||
# define APIENTRY
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define GPA(X) dlsym(glw_state.OpenGLLib, "_"##X)
|
||||
#else
|
||||
#define GPA(X) dlsym(glw_state.OpenGLLib, X)
|
||||
#endif
|
||||
|
||||
#ifndef qwglGetProcAddress
|
||||
#define qwglGetProcAddress(X) (glw_state.OpenGLLib ? GPA(X) : NULL)
|
||||
#endif
|
||||
|
||||
extern void ( APIENTRY * qglAccum )(GLenum op, GLfloat value);
|
||||
extern void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref);
|
||||
extern GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences);
|
||||
|
@ -433,7 +446,9 @@ extern BOOL ( WINAPI * qwglSetDeviceGammaRampEXT ) ( const unsigned char *pRed,
|
|||
#ifdef __linux__
|
||||
|
||||
// local function in dll
|
||||
#ifndef qwglGetProcAddress
|
||||
extern void *qwglGetProcAddress(char *symbol);
|
||||
#endif
|
||||
|
||||
extern void (*qgl3DfxSetPaletteEXT)(GLuint *);
|
||||
|
||||
|
|
Loading…
Reference in a new issue