summaryrefslogtreecommitdiff
path: root/src/unix
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2017-03-22 17:56:34 +0100
committerPaweł Redman <pawel.redman@gmail.com>2017-03-22 17:56:34 +0100
commit6a777afc079c2a8d3af3ecd2145fe8dd50567a39 (patch)
tree520f4489cebf8564ef6cb27064ceea45cbc005b3 /src/unix
Funko sources as released by Rotacak.HEADmaster
Diffstat (limited to 'src/unix')
-rw-r--r--src/unix/MacSupport/SLA-dmg.sh30
-rw-r--r--src/unix/MacSupport/SLA.r260
-rw-r--r--src/unix/MacSupport/Tremulous.icnsbin0 -> 78419 bytes
-rw-r--r--src/unix/MacSupport/ioquake3.icnsbin0 -> 35224 bytes
-rw-r--r--src/unix/ftola.s161
-rw-r--r--src/unix/linux_glimp.c1794
-rw-r--r--src/unix/linux_joystick.c212
-rw-r--r--src/unix/linux_local.h50
-rw-r--r--src/unix/linux_qgl.c4206
-rw-r--r--src/unix/linux_signals.c65
-rw-r--r--src/unix/linux_snd.c295
-rw-r--r--src/unix/matha.s425
-rw-r--r--src/unix/qasm.h51
-rw-r--r--src/unix/sdl_glimp.c1755
-rw-r--r--src/unix/sdl_snd.c363
-rw-r--r--src/unix/snapvectora.s104
-rw-r--r--src/unix/snd_mixa.s218
-rw-r--r--src/unix/unix_glw.h39
-rw-r--r--src/unix/unix_main.c1494
-rw-r--r--src/unix/unix_net.c684
-rw-r--r--src/unix/unix_shared.c452
21 files changed, 12658 insertions, 0 deletions
diff --git a/src/unix/MacSupport/SLA-dmg.sh b/src/unix/MacSupport/SLA-dmg.sh
new file mode 100644
index 0000000..51c6e42
--- /dev/null
+++ b/src/unix/MacSupport/SLA-dmg.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# This script appends a SLA.r (Software License Agreement) resource to a .dmg
+#
+# usage is './SLA-dmg.sh SLA.r /path/to/ioquake3.dmg'
+#
+
+if [ "x$1" = "x" ] || [ "x$2" = "x"]; then
+ echo "usage: ./SLA-dmg.sh SLAFILE DMGFILE"
+ exit 1;
+fi
+
+if [ ! -r $1 ]; then
+ echo "$1 is not a readable .r file"
+ exit 1;
+fi
+if [ ! -w $2 ]; then
+ echo "$2 is not writable .dmg file"
+ exit 1;
+fi
+
+hdiutil convert -format UDCO -o tmp.dmg $2 || exit 1
+hdiutil unflatten tmp.dmg || exit 1
+/Developer/Tools/Rez /Developer/Headers/FlatCarbon/*.r $1 -a -o tmp.dmg \
+ || exit 1
+hdiutil flatten tmp.dmg || exit 1
+hdiutil internet-enable -yes tmp.dmg || exit 1
+mv tmp.dmg $2 || (echo "Could not copy tmp.dmg to $2" && exit 1)
+rm tmp.dmg
+echo "SLA $1 successfully added to $2"
diff --git a/src/unix/MacSupport/SLA.r b/src/unix/MacSupport/SLA.r
new file mode 100644
index 0000000..e5edaf0
--- /dev/null
+++ b/src/unix/MacSupport/SLA.r
@@ -0,0 +1,260 @@
+data 'LPic' (5000) {
+ $"0002 0011 0003 0001 0000 0000 0002 0000"
+ $"0008 0003 0000 0001 0004 0000 0004 0005"
+ $"0000 000E 0006 0001 0005 0007 0000 0007"
+ $"0008 0000 0047 0009 0000 0034 000A 0001"
+ $"0035 000B 0001 0020 000C 0000 0011 000D"
+ $"0000 005B 0004 0000 0033 000F 0001 000C"
+ $"0010 0000 000B 000E 0000"
+};
+
+
+data 'TEXT' (5002, "English") {
+"LIMITED USE SOFTWARE LICENSE AGREEMENT\n"
+"\n"
+"\n"
+"\n"
+"This Limited Use Software License Agreement (the \"Agreement\") is a legal"
+"agreement between you, the end-user, and Id Software, Inc. (\"ID\"). BY"
+"CONTINUING THE INSTALLATION OF THIS GAME DEMO PROGRAM ENTITLED QUAKE III:"
+"ARENA (THE \"SOFTWARE\"), BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING"
+"OR COPYING THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE, COMPUTER RAM OR"
+"OTHER STORAGE, YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS "
+"AGREEMENT.\n"
+"\n"
+"\n"
+"\n"
+"1. Grant of License. Subject to the terms and provisions of this"
+"Agreement, ID grants to you the non-exclusive and limited right to use the"
+"Software only in executable or object code form. The term \"Software\""
+"includes all elements of the Software, including, without limitation, data"
+"files and screen displays. You are not receiving any ownership or"
+"proprietary right, title or interest in or to the Software or the "
+"copyright, trademarks, or other rights related thereto. For purposes of"
+"this section, \"use\" means loading the Software into RAM and/or onto "
+"computer hard drive, as well as installation of the Software on a hard"
+"disk or other storage device and means the uses permitted in section 3."
+"hereinbelow. You agree that the Software will not be shipped,"
+"transferred or exported into any country in violation of the U.S. Export"
+"Administration Act (or any other law governing such matters) by you or"
+"anyone at your direction and that you will not utilize and will not"
+"authorize anyone to utilize, in any other manner, the Software in"
+"violation of any applicable law. The Software may not be downloaded"
+"or otherwise exported or exported into (or to a national or resident"
+"of) any country to which the U.S. has embargoed goods or to anyone"
+"or into any country who/which are prohibited, by applicable law, from"
+"receiving such property."
+"\n"
+"\n"
+"\n"
+"2. Prohibitions. You, either directly or indirectly, shall not do"
+"any of the following acts:"
+"\n"
+"\n"
+"\n"
+"a. rent the Software;"
+"\n"
+"\n"
+"\n"
+"b. sell the Software;"
+"\n"
+"\n"
+"\n"
+"c. lease or lend the Software;"
+"\n"
+"\n"
+"\n"
+"d. offer the Software on a \"pay-per-play\" basis;"
+"\n"
+"\n"
+"\n"
+"e. distribute the Software (except as permitted by section 3."
+"hereinbelow);"
+"\n"
+"\n"
+"\n"
+"f. in any other manner and through any medium whatsoever"
+"commercially exploit the Software or use the Software for any commercial"
+"purpose;"
+"\n"
+"\n"
+"\n"
+"g. disassemble, reverse engineer, decompile, modify or alter the"
+"Software including, without limitation, creating or developing extra or"
+"add-on levels for the Software;"
+"\n"
+"\n"
+"\n"
+"h. translate the Software;"
+"\n"
+"\n"
+"\n"
+"i. reproduce or copy the Software (except as permitted by section"
+"3. hereinbelow);"
+"\n"
+"\n"
+"\n"
+"j. publicly display the Software;"
+"\n"
+"\n"
+"\n"
+"k. prepare or develop derivative works based upon the Software; or"
+"\n"
+"\n"
+"\n"
+"l. remove or alter any legal notices or other markings or "
+"legends, such as trademark and copyright notices, affixed on or within"
+"the Software."
+"\n"
+"\n"
+"\n"
+"3. Permitted Distribution and Copying. So long as this Agreement"
+"accompanies each copy you make of the Software, and so long as you fully"
+"comply, at all times, with this Agreement, ID grants to you the"
+"non-exclusive and limited right to copy the Software and to distribute "
+"such copies of the Software free of charge for non-commercial purposes "
+"which shall include the free of charge distribution of copies of the"
+"Software as mounted on the covers of magazines; provided, however, you"
+"shall not copy or distribute the Software in any infringing manner or"
+"in any manner which violates any law or third party right and you shall"
+"not distribute the Software together with any material which is "
+"infringing, libelous, defamatory, obscene, false, misleading, or "
+"otherwise illegal or unlawful. You agree to label conspicuously as "
+"\"SHAREWARE\" or \"DEMO\" each CD or other non-electronic copy of the "
+"Software that you make and distribute. ID reserves all rights not"
+"granted in this Agreement. You shall not commercially distribute the"
+"Software unless you first enter into a separate contract with ID, a"
+"copy of which you may request, but which ID may decline to execute."
+"For more information visit www.quake3arena.com."
+"\n"
+"\n"
+"\n"
+"4. Intellectual Property Rights. The Software and all copyrights,"
+"trademarks and all other conceivable intellectual property rights related"
+"to the Software are owned by ID and are protected by United States"
+"copyright laws, international treaty provisions and all applicable law,"
+"such as the Lanham Act. You must treat the Software like any other"
+"copyrighted material, as required by 17 U.S.C., §101 et seq. and othen"
+"applicable law. You agree to use your best efforts to see that any user"
+"of the Software licensed hereunder complies with this Agreement. You"
+"agree that you are receiving a copy of the Software by license only"
+"and not by sale and that the \"first sale\" doctrine of 17 U.S.C. §10"
+"does not apply to your receipt or use of the Software."
+"\n"
+"\n"
+"\n"
+"5. NO WARRANTIES. ID DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS OR"
+"IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF"
+"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO THE"
+"SOFTWARE. ID DOES NOT WARRANT THAT THE OPERATION OF THE SOFTWARE WILL BE"
+"UNINTERRUPTED OR ERROR FREE OR THAT THE SOFTWARE WILL MEET YOUR SPECIFIC"
+"REQUIREMENTS. ADDITIONAL STATEMENTS SUCH AS PRESENTATIONS, WHETHER ORAL"
+"OR WRITTEN, DO NOT CONSTITUTE WARRANTIES BY ID AND SHOULD NOT BE RELIED"
+"UPON. THIS SECTION 5. SHALL SURVIVE CANCELLATION OR TERMINATION OF THIS"
+"AGREEMENT."
+"\n"
+"\n"
+"\n"
+"6. Governing Law, Venue, Indemnity and Liability Limitation. This"
+"Agreement shall be construed in accordance with and governed by the"
+"applicable laws of the State of Texas and applicable United States federal"
+"law. Copyright and other proprietary matters will be governed by United"
+"States laws and international treaties. Exclusive venue for all"
+"litigation regarding this Agreement shall be in Dallas County, Texas"
+"and you agree to submit to the jurisdiction of the courts in Dallas,"
+"Texas for any such litigation. You agree to indemnify, defend and hold"
+"harmless ID and ID's officers, employees, directors, agents, licensees"
+"(excluding you), successors and assigns from and against all losses,"
+"lawsuits, damages, causes of action and claims relating to and/or"
+"arising from your breach of this Agreement. You agree that your"
+"unauthorized use of the Software, or any part thereof, may immediately"
+"and irreparably damage ID such that ID could not be adequately"
+"compensated solely by a monetary award and that at ID's option ID shall"
+"be entitled to an injunctive order, in addition to all other available"
+"remedies including a monetary award, appropriately restraining and/or"
+"prohibiting such unauthorized use without the necessity of ID posting"
+"bond or other security. IN ANY CASE, ID AND ID'S OFFICERS, EMPLOYEES,"
+"DIRECTORS, AGENTS, LICENSEES, SUBLICENSEES, SUCCESSORS AND ASSIGNS"
+"SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS,"
+"SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT, PUNITIVE OR OTHER SIMILAR"
+"DAMAGES ARISING FROM ANY ALLEGED CLAIM FOR BREACH OF WARRANTY, BREACH"
+"OF CONTRACT, NEGLIGENCE, STRICT PRODUCT LIABILITY, OR OTHER LEGAL"
+"THEORY EVEN IF ID OR ITS AGENT HAVE BEEN ADVISED OF THE POSSIBILITY"
+"OF SUCH DAMAGES OR EVEN IF SUCH DAMAGES ARE FORESEEABLE, OR LIABLE"
+"FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do not allow"
+"the exclusion or limitation of incidental or consequential damages,"
+"so the above limitation or exclusion may not apply to you. This"
+"Section 6. shall survive cancellation or termination of this Agreement."
+"\n"
+"\n"
+"\n"
+"7. U.S. Government Restricted Rights. To the extent applicable,"
+"the United States Government shall only have those rights to use the"
+"Software as expressly stated and expressly limited and restricted in"
+"this Agreement, as provided in 48 C.F.R. §§ 227.7201 through 227.7204,"
+"inclusive."
+"\n"
+"\n"
+"\n"
+"8. General Provisions. Neither this Agreement nor any part or"
+"portion hereof shall be assigned or sublicensed by you. ID may assign its"
+"rights under this Agreement in ID's sole discretion. Should any provision"
+"of this Agreement be held to be void, invalid, unenforceable or illegal by"
+"a court of competent jurisdiction, the validity and enforceability of the"
+"other provisions shall not be affected thereby. If any provision is"
+"determined to be unenforceable by a court of competent jurisdiction, you"
+"agree to a modification of such provision to provide for enforcement of"
+"the provision's intent, to the extent permitted by applicable law."
+"Failure of ID to enforce any provision of this Agreement shall not"
+"constitute or be construed as a waiver of such provision or of the right"
+"to enforce such provision. Immediately upon your failure to comply with"
+"or breach of any term or provision of this Agreement, THIS AGREEMENT"
+"AND YOUR LICENSE SHALL AUTOMATICALLY TERMINATE, WITHOUT NOTICE, AND ID"
+"MAY PURSUE ALL RELIEF AND REMEDIES AGAINST YOU WHICH ARE AVAILABLE UNDER"
+"APPLICABLE LAW AND/OR THIS AGREEMENT. In the event this Agreement is"
+"terminated, you shall have no right to use the Software, in any manner,"
+"and you shall immediately destroy all copies of the Software in your"
+"possession, custody or control."
+"\n"
+"\n"
+"\n"
+"YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, YOU UNDERSTAND THIS"
+"AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE INSTALLATION OF THE"
+"SOFTWARE, BY LOADING OR RUNNING THE SOFTWARE, OR BY PLACING OR COPYING"
+"THE SOFTWARE ONTO YOUR COMPUTER HARD DRIVE OR RAM, YOU AGREE TO BE BOUND"
+"BY THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU FURTHER AGREE THAT,"
+"EXCEPT FOR WRITTEN SEPARATE AGREEMENTS BETWEEN ID AND YOU, THIS "
+"AGREEMENT IS A COMPLETE AND EXCLUSIVE STATEMENT OF THE RIGHTS AND"
+"LIABILITIES OF THE PARTIES HERETO. THIS AGREEMENT SUPERSEDES ALL PRIOR"
+"ORAL AGREEMENTS, PROPOSALS OR UNDERSTANDINGS, AND ANY OTHER"
+"COMMUNICATIONS BETWEEN ID AND YOU RELATING TO THE SUBJECT MATTER OF"
+"THIS AGREEMENT."
+"\n"
+};
+
+resource 'STR#' (5002, "English") {
+ { /* array StringArray: 9 elements */
+ /* [1] */
+ "English",
+ /* [2] */
+ "Agree",
+ /* [3] */
+ "Disagree",
+ /* [4] */
+ "Print",
+ /* [5] */
+ "Save...",
+ /* [6] */
+ "IMPORTANT - Read this License Agreement carefully before clicking on "
+ "the \"Agree\" button. By clicking on the \"Agree\" button, you agree "
+ "to be bound by the terms of the License Agreement.",
+ /* [7] */
+ "Software License Agreement",
+ /* [8] */
+ "This text cannot be saved. This disk may be full or locked, or the file "
+ "may be locked.",
+ /* [9] */
+ "Unable to print. Make sure you have selected a printer."
+ }
+};
+
diff --git a/src/unix/MacSupport/Tremulous.icns b/src/unix/MacSupport/Tremulous.icns
new file mode 100644
index 0000000..c4106ac
--- /dev/null
+++ b/src/unix/MacSupport/Tremulous.icns
Binary files differ
diff --git a/src/unix/MacSupport/ioquake3.icns b/src/unix/MacSupport/ioquake3.icns
new file mode 100644
index 0000000..30e3b67
--- /dev/null
+++ b/src/unix/MacSupport/ioquake3.icns
Binary files differ
diff --git a/src/unix/ftola.s b/src/unix/ftola.s
new file mode 100644
index 0000000..d938fa1
--- /dev/null
+++ b/src/unix/ftola.s
@@ -0,0 +1,161 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Foobar; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+
+//
+// qftol -- fast floating point to long conversion.
+//
+
+// 23/09/05 Ported to gas by intel2gas, best supporting actor Tim Angus
+// <tim@ngus.net>
+
+#include "qasm.h"
+
+#if id386
+
+.data
+
+temp: .single 0.0
+fpucw: .long 0
+
+// Precision Control Field , 2 bits / 0x0300
+// PC24 0x0000 Single precision (24 bits).
+// PC53 0x0200 Double precision (53 bits).
+// PC64 0x0300 Extended precision (64 bits).
+
+// Rounding Control Field, 2 bits / 0x0C00
+// RCN 0x0000 Rounding to nearest (even).
+// RCD 0x0400 Rounding down (directed, minus).
+// RCU 0x0800 Rounding up (directed plus).
+// RC0 0x0C00 Rounding towards zero (chop mode).
+
+
+// rounding towards nearest (even)
+cw027F: .long 0x027F
+cw037F: .long 0x037F
+
+// rounding towards zero (chop mode)
+cw0E7F: .long 0x0E7F
+cw0F7F: .long 0x0F7F
+
+
+.text
+
+//
+// int qftol( void ) - default control word
+//
+
+.globl C(qftol)
+
+C(qftol):
+ fistpl temp
+ movl temp,%eax
+ ret
+
+
+//
+// int qftol027F( void ) - DirectX FPU
+//
+
+.globl C(qftol027F)
+
+C(qftol027F):
+ fnstcw fpucw
+ fldcw cw027F
+ fistpl temp
+ fldcw fpucw
+ movl temp,%eax
+ ret
+
+//
+// int qftol037F( void ) - Linux FPU
+//
+
+.globl C(qftol037F)
+
+C(qftol037F):
+ fnstcw fpucw
+ fldcw cw037F
+ fistpl temp
+ fldcw fpucw
+ movl temp,%eax
+ ret
+
+
+//
+// int qftol0F7F( void ) - ANSI
+//
+
+.globl C(qftol0F7F)
+
+C(qftol0F7F):
+ fnstcw fpucw
+ fldcw cw0F7F
+ fistpl temp
+ fldcw fpucw
+ movl temp,%eax
+ ret
+
+//
+// int qftol0E7F( void )
+//
+
+.globl C(qftol0E7F)
+
+C(qftol0E7F):
+ fnstcw fpucw
+ fldcw cw0E7F
+ fistpl temp
+ fldcw fpucw
+ movl temp,%eax
+ ret
+
+
+
+//
+// long Q_ftol( float q )
+//
+
+.globl C(Q_ftol)
+
+C(Q_ftol):
+ flds 4(%esp)
+ fistpl temp
+ movl temp,%eax
+ ret
+
+
+//
+// long qftol0F7F( float q ) - Linux FPU
+//
+
+.globl C(Q_ftol0F7F)
+
+C(Q_ftol0F7F):
+ fnstcw fpucw
+ flds 4(%esp)
+ fldcw cw0F7F
+ fistpl temp
+ fldcw fpucw
+ movl temp,%eax
+ ret
+#endif
diff --git a/src/unix/linux_glimp.c b/src/unix/linux_glimp.c
new file mode 100644
index 0000000..650c1c9
--- /dev/null
+++ b/src/unix/linux_glimp.c
@@ -0,0 +1,1794 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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
+** GLimp_SetGamma
+**
+*/
+
+#if !USE_SDL_VIDEO
+
+#include <termios.h>
+#include <sys/ioctl.h>
+#ifdef __linux__
+ #include <sys/stat.h>
+ #include <sys/vt.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <signal.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+// bk001204
+#include <dlfcn.h>
+
+// bk001206 - from my Heretic2 by way of Ryan's Fakk2
+// Needed for the new X11_PendingInput() function.
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../renderer/tr_local.h"
+#include "../client/client.h"
+#include "linux_local.h" // bk001130
+
+#include "unix_glw.h"
+
+#include <GL/glx.h>
+
+#include <X11/keysym.h>
+#include <X11/cursorfont.h>
+
+#if !defined(__sun)
+#include <X11/extensions/xf86dga.h>
+#include <X11/extensions/xf86vmode.h>
+#endif
+
+#if defined(__sun)
+#include <X11/Sunkeysym.h>
+#endif
+
+#ifdef _XF86DGA_H_
+#define HAVE_XF86DGA
+#endif
+
+typedef enum
+{
+ RSERR_OK,
+
+ RSERR_INVALID_FULLSCREEN,
+ RSERR_INVALID_MODE,
+
+ RSERR_UNKNOWN
+} rserr_t;
+
+glwstate_t glw_state;
+
+static Display *dpy = NULL;
+static int scrnum;
+static Window win = 0;
+static GLXContext ctx = NULL;
+
+// bk001206 - not needed anymore
+// static qboolean autorepeaton = qtrue;
+
+#define KEY_MASK (KeyPressMask | KeyReleaseMask)
+#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
+ PointerMotionMask | ButtonMotionMask )
+#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask )
+
+static qboolean mouse_avail;
+static qboolean mouse_active = qfalse;
+static int mwx, mwy;
+static int mx = 0, my = 0;
+
+// Time mouse was reset, we ignore the first 50ms of the mouse to allow settling of events
+static int mouseResetTime = 0;
+#define MOUSE_RESET_DELAY 50
+
+static cvar_t *in_mouse;
+static cvar_t *in_dgamouse; // user pref for dga mouse
+static cvar_t *in_shiftedKeys; // obey modifiers for certain keys in non-console (comma, numbers, etc)
+cvar_t *in_subframe;
+cvar_t *in_nograb; // this is strictly for developers
+
+// bk001130 - from cvs1.17 (mkv), but not static
+cvar_t *in_joystick = NULL;
+cvar_t *in_joystickDebug = NULL;
+cvar_t *joy_threshold = NULL;
+
+cvar_t *r_allowSoftwareGL; // don't abort out if the pixelformat claims software
+cvar_t *r_previousglDriver;
+
+qboolean vidmode_ext = qfalse;
+#ifdef HAVE_XF86DGA
+static int vidmode_MajorVersion = 0, vidmode_MinorVersion = 0; // major and minor of XF86VidExtensions
+
+// gamma value of the X display before we start playing with it
+static XF86VidModeGamma vidmode_InitialGamma;
+#endif /* HAVE_XF86DGA */
+
+static int win_x, win_y;
+
+#ifdef HAVE_XF86DGA
+static XF86VidModeModeInfo **vidmodes;
+#endif /* HAVE_XF86DGA */
+//static int default_dotclock_vidmode; // bk001204 - unused
+static int num_vidmodes;
+static qboolean vidmode_active = qfalse;
+
+static int mouse_accel_numerator;
+static int mouse_accel_denominator;
+static int mouse_threshold;
+
+/*
+* Find the first occurrence of find in s.
+*/
+// bk001130 - from cvs1.17 (mkv), const
+// bk001130 - made first argument const
+static const char *Q_stristr( const char *s, const char *find)
+{
+ register char c, sc;
+ register size_t len;
+
+ if ((c = *find++) != 0)
+ {
+ if (c >= 'a' && c <= 'z')
+ {
+ c -= ('a' - 'A');
+ }
+ len = strlen(find);
+ do
+ {
+ do
+ {
+ if ((sc = *s++) == 0)
+ return NULL;
+ if (sc >= 'a' && sc <= 'z')
+ {
+ sc -= ('a' - 'A');
+ }
+ } while (sc != c);
+ } while (Q_stricmpn(s, find, len) != 0);
+ s--;
+ }
+ return s;
+}
+
+/*****************************************************************************
+** KEYBOARD
+** NOTE TTimo the keyboard handling is done with KeySyms
+** that means relying on the keyboard mapping provided by X
+** in-game it would probably be better to use KeyCode (i.e. hardware key codes)
+** you would still need the KeySyms in some cases, such as for the console and all entry textboxes
+** (cause there's nothing worse than a qwerty mapping on a french keyboard)
+**
+** you can turn on some debugging and verbose of the keyboard code with #define KBD_DBG
+******************************************************************************/
+
+//#define KBD_DBG
+
+static char *XLateKey(XKeyEvent *ev, int *key)
+{
+ static unsigned char buf[64];
+ static unsigned char bufnomod[2];
+ KeySym keysym;
+ int XLookupRet;
+
+ *key = 0;
+
+ XLookupRet = XLookupString(ev, buf, sizeof buf, &keysym, 0);
+#ifdef KBD_DBG
+ ri.Printf(PRINT_ALL, "XLookupString ret: %d buf: %s keysym: %x\n", XLookupRet, buf, keysym);
+#endif
+
+ if (!in_shiftedKeys->integer) {
+ // also get a buffer without modifiers held
+ ev->state = 0;
+ XLookupRet = XLookupString(ev, bufnomod, sizeof bufnomod, &keysym, 0);
+#ifdef KBD_DBG
+ ri.Printf(PRINT_ALL, "XLookupString (minus modifiers) ret: %d buf: %s keysym: %x\n", XLookupRet, buf, keysym);
+#endif
+ }
+
+ switch (keysym)
+ {
+ case XK_KP_Page_Up:
+ case XK_KP_9: *key = K_KP_PGUP; break;
+ case XK_Page_Up: *key = K_PGUP; break;
+
+ case XK_KP_Page_Down:
+ case XK_KP_3: *key = K_KP_PGDN; break;
+ case XK_Page_Down: *key = K_PGDN; break;
+
+ case XK_KP_Home: *key = K_KP_HOME; break;
+ case XK_KP_7: *key = K_KP_HOME; break;
+ case XK_Home: *key = K_HOME; break;
+
+ case XK_KP_End:
+ case XK_KP_1: *key = K_KP_END; break;
+ case XK_End: *key = K_END; break;
+
+ case XK_KP_Left: *key = K_KP_LEFTARROW; break;
+ case XK_KP_4: *key = K_KP_LEFTARROW; break;
+ case XK_Left: *key = K_LEFTARROW; break;
+
+ case XK_KP_Right: *key = K_KP_RIGHTARROW; break;
+ case XK_KP_6: *key = K_KP_RIGHTARROW; break;
+ case XK_Right: *key = K_RIGHTARROW; break;
+
+ case XK_KP_Down:
+ case XK_KP_2: *key = K_KP_DOWNARROW; break;
+ case XK_Down: *key = K_DOWNARROW; break;
+
+ case XK_KP_Up:
+ case XK_KP_8: *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;
+
+ // bk001206 - from Ryan's Fakk2
+ //case XK_BackSpace: *key = 8; break; // ctrl-h
+ case XK_BackSpace: *key = K_BACKSPACE; break; // ctrl-h
+
+ case XK_KP_Delete:
+ case XK_KP_Decimal: *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:
+ case XK_KP_0: *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;
+
+ // bk001130 - from cvs1.17 (mkv)
+ case XK_exclam: *key = '1'; break;
+ case XK_at: *key = '2'; break;
+ case XK_numbersign: *key = '3'; break;
+ case XK_dollar: *key = '4'; break;
+ case XK_percent: *key = '5'; break;
+ case XK_asciicircum: *key = '6'; break;
+ case XK_ampersand: *key = '7'; break;
+ case XK_asterisk: *key = '8'; break;
+ case XK_parenleft: *key = '9'; break;
+ case XK_parenright: *key = '0'; break;
+
+ // weird french keyboards ..
+ // NOTE: console toggle is hardcoded in cl_keys.c, can't be unbound
+ // cleaner would be .. using hardware key codes instead of the key syms
+ // could also add a new K_KP_CONSOLE
+ case XK_twosuperior: *key = '~'; break;
+
+ // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=472
+ case XK_space:
+ case XK_KP_Space: *key = K_SPACE; break;
+
+ default:
+ if (XLookupRet == 0)
+ {
+ if (com_developer->value)
+ {
+ ri.Printf(PRINT_ALL, "Warning: XLookupString failed on KeySym %d\n", keysym);
+ }
+ return NULL;
+ }
+ else
+ {
+ // XK_* tests failed, but XLookupString got a buffer, so let's try it
+ if (in_shiftedKeys->integer) {
+ *key = *(unsigned char *)buf;
+ if (*key >= 'A' && *key <= 'Z')
+ *key = *key - 'A' + 'a';
+ // if ctrl is pressed, the keys are not between 'A' and 'Z', for instance ctrl-z == 26 ^Z ^C etc.
+ // see https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=19
+ else if (*key >= 1 && *key <= 26)
+ *key = *key + 'a' - 1;
+ } else {
+ *key = bufnomod[0];
+ }
+ }
+ break;
+ }
+
+ return buf;
+}
+
+// ========================================================================
+// makes a null cursor
+// ========================================================================
+
+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
+ XWarpPointer(dpy, None, win,
+ 0, 0, 0, 0,
+ glConfig.vidWidth / 2, glConfig.vidHeight / 2);
+ XSync(dpy, False);
+
+ XDefineCursor(dpy, win, CreateNullCursor(dpy, win));
+
+ XGrabPointer(dpy, win, // bk010108 - do this earlier?
+ False,
+ MOUSE_MASK,
+ GrabModeAsync, GrabModeAsync,
+ win,
+ None,
+ CurrentTime);
+
+ XGetPointerControl(dpy, &mouse_accel_numerator, &mouse_accel_denominator,
+ &mouse_threshold);
+
+ XChangePointerControl(dpy, True, True, 1, 1, 0);
+
+ XSync(dpy, False);
+
+ mouseResetTime = Sys_Milliseconds ();
+
+#ifdef HAVE_XF86DGA
+ if (in_dgamouse->value)
+ {
+ int MajorVersion, MinorVersion;
+
+ if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion))
+ {
+ // unable to query, probalby not supported, force the setting to 0
+ ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
+ ri.Cvar_Set( "in_dgamouse", "0" );
+ } else
+ {
+ XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse);
+ XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
+ }
+ } else
+#endif /* HAVE_XF86DGA */
+ {
+ mwx = glConfig.vidWidth / 2;
+ mwy = glConfig.vidHeight / 2;
+ mx = my = 0;
+ }
+
+ XGrabKeyboard(dpy, win,
+ False,
+ GrabModeAsync, GrabModeAsync,
+ CurrentTime);
+
+ XSync(dpy, False);
+}
+
+static void uninstall_grabs(void)
+{
+#ifdef HAVE_XF86DGA
+ if (in_dgamouse->value)
+ {
+ if (com_developer->value)
+ ri.Printf( PRINT_ALL, "DGA Mouse - Disabling DGA DirectVideo\n" );
+ XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0);
+ }
+#endif /* HAVE_XF86DGA */
+
+ XChangePointerControl(dpy, qtrue, qtrue, mouse_accel_numerator,
+ mouse_accel_denominator, mouse_threshold);
+
+ XUngrabPointer(dpy, CurrentTime);
+ XUngrabKeyboard(dpy, CurrentTime);
+
+ XWarpPointer(dpy, None, win,
+ 0, 0, 0, 0,
+ glConfig.vidWidth / 2, glConfig.vidHeight / 2);
+
+ // inviso cursor
+ XUndefineCursor(dpy, win);
+}
+
+// bk001206 - from Ryan's Fakk2
+/**
+ * XPending() actually performs a blocking read
+ * if no events available. From Fakk2, by way of
+ * Heretic2, by way of SDL, original idea GGI project.
+ * The benefit of this approach over the quite
+ * badly behaved XAutoRepeatOn/Off is that you get
+ * focus handling for free, which is a major win
+ * with debug and windowed mode. It rests on the
+ * assumption that the X server will use the
+ * same timestamp on press/release event pairs
+ * for key repeats.
+ */
+static qboolean X11_PendingInput(void) {
+
+ assert(dpy != NULL);
+
+ // Flush the display connection
+ // and look to see if events are queued
+ XFlush( dpy );
+ if ( XEventsQueued( dpy, QueuedAlready) )
+ {
+ return qtrue;
+ }
+
+ // More drastic measures are required -- see if X is ready to talk
+ {
+ static struct timeval zero_time;
+ int x11_fd;
+ fd_set fdset;
+
+ x11_fd = ConnectionNumber( dpy );
+ FD_ZERO(&fdset);
+ FD_SET(x11_fd, &fdset);
+ if ( select(x11_fd+1, &fdset, NULL, NULL, &zero_time) == 1 )
+ {
+ return(XPending(dpy));
+ }
+ }
+
+ // Oh well, nothing is ready ..
+ return qfalse;
+}
+
+// bk001206 - from Ryan's Fakk2. See above.
+static qboolean repeated_press(XEvent *event)
+{
+ XEvent peekevent;
+ qboolean repeated = qfalse;
+
+ assert(dpy != NULL);
+
+ if (X11_PendingInput())
+ {
+ XPeekEvent(dpy, &peekevent);
+
+ if ((peekevent.type == KeyPress) &&
+ (peekevent.xkey.keycode == event->xkey.keycode) &&
+ (peekevent.xkey.time == event->xkey.time))
+ {
+ repeated = qtrue;
+ XNextEvent(dpy, &peekevent); // skip event.
+ } // if
+ } // if
+
+ return(repeated);
+} // repeated_press
+
+int Sys_XTimeToSysTime (Time xtime);
+static void HandleEvents(void)
+{
+ int b;
+ int key;
+ XEvent event;
+ qboolean dowarp = qfalse;
+ char *p;
+ int dx, dy;
+ int t = 0; // default to 0 in case we don't set
+
+ if (!dpy)
+ return;
+
+ while (XPending(dpy))
+ {
+ XNextEvent(dpy, &event);
+ switch (event.type)
+ {
+ case KeyPress:
+ t = Sys_XTimeToSysTime(event.xkey.time);
+ p = XLateKey(&event.xkey, &key);
+ if (key)
+ {
+ Sys_QueEvent( t, SE_KEY, key, qtrue, 0, NULL );
+ }
+ if (p)
+ {
+ while (*p)
+ {
+ Sys_QueEvent( t, SE_CHAR, *p++, 0, 0, NULL );
+ }
+ }
+ break;
+
+ case KeyRelease:
+ t = Sys_XTimeToSysTime(event.xkey.time);
+ // bk001206 - handle key repeat w/o XAutRepatOn/Off
+ // also: not done if console/menu is active.
+ // From Ryan's Fakk2.
+ // see game/q_shared.h, KEYCATCH_* . 0 == in 3d game.
+ if (cls.keyCatchers == 0)
+ { // FIXME: KEYCATCH_NONE
+ if (repeated_press(&event) == qtrue)
+ continue;
+ } // if
+ XLateKey(&event.xkey, &key);
+
+ Sys_QueEvent( t, SE_KEY, key, qfalse, 0, NULL );
+ break;
+
+ case MotionNotify:
+ t = Sys_XTimeToSysTime(event.xkey.time);
+ if (mouse_active)
+ {
+#ifdef HAVE_XF86DGA
+ if (in_dgamouse->value)
+ {
+ mx += event.xmotion.x_root;
+ my += event.xmotion.y_root;
+ if (t - mouseResetTime > MOUSE_RESET_DELAY )
+ {
+ Sys_QueEvent( t, SE_MOUSE, mx, my, 0, NULL );
+ }
+ mx = my = 0;
+ } else
+#endif /* HAVE_XF86DGA */
+ {
+ // If it's a center motion, we've just returned from our warp
+ if (event.xmotion.x == glConfig.vidWidth/2 &&
+ event.xmotion.y == glConfig.vidHeight/2)
+ {
+ mwx = glConfig.vidWidth/2;
+ mwy = glConfig.vidHeight/2;
+ if (t - mouseResetTime > MOUSE_RESET_DELAY )
+ {
+ Sys_QueEvent( t, SE_MOUSE, mx, my, 0, NULL );
+ }
+ mx = my = 0;
+ break;
+ }
+
+ dx = ((int)event.xmotion.x - mwx);
+ dy = ((int)event.xmotion.y - mwy);
+ mx += dx;
+ my += dy;
+
+ mwx = event.xmotion.x;
+ mwy = event.xmotion.y;
+ dowarp = qtrue;
+ }
+ }
+ break;
+
+ case ButtonPress:
+ t = Sys_XTimeToSysTime(event.xkey.time);
+ if (event.xbutton.button == 4)
+ {
+ Sys_QueEvent( t, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
+ } else if (event.xbutton.button == 5)
+ {
+ Sys_QueEvent( t, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
+ } else
+ {
+ // NOTE TTimo there seems to be a weird mapping for K_MOUSE1 K_MOUSE2 K_MOUSE3 ..
+ b=-1;
+ if (event.xbutton.button == 1)
+ {
+ b = 0; // K_MOUSE1
+ } else if (event.xbutton.button == 2)
+ {
+ b = 2; // K_MOUSE3
+ } else if (event.xbutton.button == 3)
+ {
+ b = 1; // K_MOUSE2
+ } else if (event.xbutton.button == 6)
+ {
+ b = 3; // K_MOUSE4
+ } else if (event.xbutton.button == 7)
+ {
+ b = 4; // K_MOUSE5
+ };
+
+ Sys_QueEvent( t, SE_KEY, K_MOUSE1 + b, qtrue, 0, NULL );
+ }
+ break;
+
+ case ButtonRelease:
+ t = Sys_XTimeToSysTime(event.xkey.time);
+ if (event.xbutton.button == 4)
+ {
+ Sys_QueEvent( t, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
+ } else if (event.xbutton.button == 5)
+ {
+ Sys_QueEvent( t, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
+ } else
+ {
+ 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;
+ } else if (event.xbutton.button == 6)
+ {
+ b = 3; // K_MOUSE4
+ } else if (event.xbutton.button == 7)
+ {
+ b = 4; // K_MOUSE5
+ };
+ Sys_QueEvent( t, SE_KEY, K_MOUSE1 + b, qfalse, 0, NULL );
+ }
+ 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)
+ {
+ XWarpPointer(dpy,None,win,0,0,0,0,
+ (glConfig.vidWidth/2),(glConfig.vidHeight/2));
+ }
+}
+
+// NOTE TTimo for the tty console input, we didn't rely on those ..
+// it's not very surprising actually cause they are not used otherwise
+void KBD_Init(void)
+{
+}
+
+void KBD_Close(void)
+{
+}
+
+void IN_ActivateMouse( void )
+{
+ if (!mouse_avail || !dpy || !win)
+ return;
+
+ if (!mouse_active)
+ {
+ if (!in_nograb->value)
+ install_grabs();
+ else if (in_dgamouse->value) // force dga mouse to 0 if using nograb
+ ri.Cvar_Set("in_dgamouse", "0");
+ mouse_active = qtrue;
+ }
+}
+
+void IN_DeactivateMouse( void )
+{
+ if (!mouse_avail || !dpy || !win)
+ return;
+
+ if (mouse_active)
+ {
+ if (!in_nograb->value)
+ uninstall_grabs();
+ else if (in_dgamouse->value) // force dga mouse to 0 if using nograb
+ ri.Cvar_Set("in_dgamouse", "0");
+ mouse_active = qfalse;
+ }
+}
+/*****************************************************************************/
+
+/*
+** GLimp_SetGamma
+**
+** This routine should only be called if glConfig.deviceSupportsGamma is TRUE
+*/
+void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] )
+{
+ // NOTE TTimo we get the gamma value from cvar, because we can't work with the s_gammatable
+ // the API wasn't changed to avoid breaking other OSes
+#ifdef HAVE_XF86DGA
+ float g = Cvar_Get("r_gamma", "1.0", 0)->value;
+ XF86VidModeGamma gamma;
+ assert(glConfig.deviceSupportsGamma);
+ gamma.red = g;
+ gamma.green = g;
+ gamma.blue = g;
+ XF86VidModeSetGamma(dpy, scrnum, &gamma);
+#endif /* HAVE_XF86DGA */
+}
+
+/*
+** 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 )
+{
+ if (!ctx || !dpy)
+ return;
+ IN_DeactivateMouse();
+ // bk001206 - replaced with H2/Fakk2 solution
+ // XAutoRepeatOn(dpy);
+ // autorepeaton = qfalse; // bk001130 - from cvs1.17 (mkv)
+ if (dpy)
+ {
+ if (ctx)
+ qglXDestroyContext(dpy, ctx);
+ if (win)
+ XDestroyWindow(dpy, win);
+#ifdef HAVE_XF86DGA
+ if (vidmode_active)
+ XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]);
+ if (glConfig.deviceSupportsGamma)
+ {
+ XF86VidModeSetGamma(dpy, scrnum, &vidmode_InitialGamma);
+ }
+#endif /* HAVE_XF86DGA */
+ // NOTE TTimo opening/closing the display should be necessary only once per run
+ // but it seems QGL_Shutdown gets called in a lot of occasion
+ // in some cases, this XCloseDisplay is known to raise some X errors
+ // ( https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=33 )
+ XCloseDisplay(dpy);
+ }
+ vidmode_active = qfalse;
+ dpy = NULL;
+ win = 0;
+ ctx = NULL;
+
+ memset( &glConfig, 0, sizeof( glConfig ) );
+ memset( &glState, 0, sizeof( glState ) );
+
+ QGL_Shutdown();
+}
+
+/*
+** GLimp_LogComment
+*/
+void GLimp_LogComment( char *comment )
+{
+ if ( glw_state.log_fp )
+ {
+ fprintf( glw_state.log_fp, "%s", comment );
+ }
+}
+
+/*
+** GLW_StartDriverAndSetMode
+*/
+// bk001204 - prototype needed
+int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen );
+static qboolean GLW_StartDriverAndSetMode( const char *drivername,
+ int mode,
+ qboolean fullscreen )
+{
+ rserr_t err;
+
+ // don't ever bother going into fullscreen with a voodoo card
+#if 1 // JDC: I reenabled this
+ if ( Q_stristr( drivername, "Voodoo" ) )
+ {
+ ri.Cvar_Set( "r_fullscreen", "0" );
+ r_fullscreen->modified = qfalse;
+ fullscreen = qfalse;
+ }
+#endif
+
+ if (fullscreen && in_nograb->value)
+ {
+ ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
+ ri.Cvar_Set( "r_fullscreen", "0" );
+ r_fullscreen->modified = qfalse;
+ fullscreen = qfalse;
+ }
+
+ err = GLW_SetMode( drivername, mode, fullscreen );
+
+ switch ( err )
+ {
+ case RSERR_INVALID_FULLSCREEN:
+ ri.Printf( PRINT_ALL, "...WARNING: fullscreen unavailable in this mode\n" );
+ return qfalse;
+ case RSERR_INVALID_MODE:
+ ri.Printf( PRINT_ALL, "...WARNING: could not set the given mode (%d)\n", mode );
+ return qfalse;
+ default:
+ break;
+ }
+ return qtrue;
+}
+
+/*
+** GLW_SetMode
+*/
+int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen )
+{
+ int attrib[] = {
+ GLX_RGBA, // 0
+ GLX_RED_SIZE, 4, // 1, 2
+ GLX_GREEN_SIZE, 4, // 3, 4
+ GLX_BLUE_SIZE, 4, // 5, 6
+ GLX_DOUBLEBUFFER, // 7
+ GLX_DEPTH_SIZE, 1, // 8, 9
+ GLX_STENCIL_SIZE, 1, // 10, 11
+ None
+ };
+ // these match in the array
+#define ATTR_RED_IDX 2
+#define ATTR_GREEN_IDX 4
+#define ATTR_BLUE_IDX 6
+#define ATTR_DEPTH_IDX 9
+#define ATTR_STENCIL_IDX 11
+ Window root;
+ XVisualInfo *visinfo;
+ XSetWindowAttributes attr;
+ XSizeHints sizehints;
+ unsigned long mask;
+ int colorbits, depthbits, stencilbits;
+ int tcolorbits, tdepthbits, tstencilbits;
+ int dga_MajorVersion, dga_MinorVersion;
+ int actualWidth, actualHeight;
+ int i;
+ const char* glstring; // bk001130 - from cvs1.17 (mkv)
+
+ ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");
+
+ ri.Printf (PRINT_ALL, "...setting mode %d:", mode );
+
+ if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
+ {
+ ri.Printf( PRINT_ALL, " invalid mode\n" );
+ return RSERR_INVALID_MODE;
+ }
+ ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);
+
+ 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);
+
+ actualWidth = glConfig.vidWidth;
+ actualHeight = glConfig.vidHeight;
+
+ // Get video mode list
+#ifdef HAVE_XF86DGA
+ if (!XF86VidModeQueryVersion(dpy, &vidmode_MajorVersion, &vidmode_MinorVersion))
+ {
+#endif /* HAVE_XF86DGA */
+ vidmode_ext = qfalse;
+#ifdef HAVE_XF86DGA
+ } else
+ {
+ ri.Printf(PRINT_ALL, "Using XFree86-VidModeExtension Version %d.%d\n",
+ vidmode_MajorVersion, vidmode_MinorVersion);
+ vidmode_ext = qtrue;
+ }
+#endif /* HAVE_XF86DGA */
+
+ // Check for DGA
+ dga_MajorVersion = 0, dga_MinorVersion = 0;
+#ifdef HAVE_XF86DGA
+ if (in_dgamouse->value)
+ {
+ if (!XF86DGAQueryVersion(dpy, &dga_MajorVersion, &dga_MinorVersion))
+ {
+ // unable to query, probably not supported
+ ri.Printf( PRINT_ALL, "Failed to detect XF86DGA Mouse\n" );
+ ri.Cvar_Set( "in_dgamouse", "0" );
+ } else
+ {
+ ri.Printf( PRINT_ALL, "XF86DGA Mouse (Version %d.%d) initialized\n",
+ dga_MajorVersion, dga_MinorVersion);
+ }
+ }
+#endif /* HAVE_XF86DGA */
+
+#ifdef HAVE_XF86DGA
+ 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)
+ {
+ best_dist = 9999999;
+ best_fit = -1;
+
+ for (i = 0; i < num_vidmodes; i++)
+ {
+ if (glConfig.vidWidth > vidmodes[i]->hdisplay ||
+ glConfig.vidHeight > vidmodes[i]->vdisplay)
+ continue;
+
+ x = glConfig.vidWidth - vidmodes[i]->hdisplay;
+ y = glConfig.vidHeight - 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 = qtrue;
+
+ // Move the viewport to top left
+ XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
+
+ ri.Printf(PRINT_ALL, "XFree86-VidModeExtension Activated at %dx%d\n",
+ actualWidth, actualHeight);
+
+ } else
+ {
+ fullscreen = 0;
+ ri.Printf(PRINT_ALL, "XFree86-VidModeExtension: No acceptable modes found\n");
+ }
+ } else
+ {
+ ri.Printf(PRINT_ALL, "XFree86-VidModeExtension: Ignored on non-fullscreen/Voodoo\n");
+ }
+ }
+#endif /* HAVE_XF86DGA */
+
+
+ if (!r_colorbits->value)
+ colorbits = 24;
+ else
+ colorbits = r_colorbits->value;
+
+ if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) )
+ colorbits = 16;
+
+ if (!r_depthbits->value)
+ depthbits = 24;
+ else
+ depthbits = r_depthbits->value;
+ stencilbits = r_stencilbits->value;
+
+ for (i = 0; i < 16; i++)
+ {
+ // 0 - default
+ // 1 - minus colorbits
+ // 2 - minus depthbits
+ // 3 - minus stencil
+ if ((i % 4) == 0 && i)
+ {
+ // one pass, reduce
+ switch (i / 4)
+ {
+ case 2 :
+ if (colorbits == 24)
+ colorbits = 16;
+ break;
+ case 1 :
+ if (depthbits == 24)
+ depthbits = 16;
+ else if (depthbits == 16)
+ depthbits = 8;
+ case 3 :
+ if (stencilbits == 24)
+ stencilbits = 16;
+ else if (stencilbits == 16)
+ stencilbits = 8;
+ }
+ }
+
+ tcolorbits = colorbits;
+ tdepthbits = depthbits;
+ tstencilbits = stencilbits;
+
+ if ((i % 4) == 3)
+ { // reduce colorbits
+ if (tcolorbits == 24)
+ tcolorbits = 16;
+ }
+
+ if ((i % 4) == 2)
+ { // reduce depthbits
+ if (tdepthbits == 24)
+ tdepthbits = 16;
+ else if (tdepthbits == 16)
+ tdepthbits = 8;
+ }
+
+ if ((i % 4) == 1)
+ { // reduce stencilbits
+ if (tstencilbits == 24)
+ tstencilbits = 16;
+ else if (tstencilbits == 16)
+ tstencilbits = 8;
+ else
+ tstencilbits = 0;
+ }
+
+ if (tcolorbits == 24)
+ {
+ attrib[ATTR_RED_IDX] = 8;
+ attrib[ATTR_GREEN_IDX] = 8;
+ attrib[ATTR_BLUE_IDX] = 8;
+ } else
+ {
+ // must be 16 bit
+ attrib[ATTR_RED_IDX] = 4;
+ attrib[ATTR_GREEN_IDX] = 4;
+ attrib[ATTR_BLUE_IDX] = 4;
+ }
+
+ attrib[ATTR_DEPTH_IDX] = tdepthbits; // default to 24 depth
+ attrib[ATTR_STENCIL_IDX] = tstencilbits;
+
+ visinfo = qglXChooseVisual(dpy, scrnum, attrib);
+ if (!visinfo)
+ {
+ continue;
+ }
+
+ ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
+ attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX], attrib[ATTR_BLUE_IDX],
+ attrib[ATTR_DEPTH_IDX], attrib[ATTR_STENCIL_IDX]);
+
+ glConfig.colorBits = tcolorbits;
+ glConfig.depthBits = tdepthbits;
+ glConfig.stencilBits = tstencilbits;
+ break;
+ }
+
+ if (!visinfo)
+ {
+ ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
+ return RSERR_INVALID_MODE;
+ }
+
+ /* window attributes */
+ attr.background_pixel = BlackPixel(dpy, scrnum);
+ 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,
+ actualWidth, actualHeight,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr);
+
+ XStoreName( dpy, win, CLIENT_WINDOW_TITLE );
+
+ /* GH: Don't let the window be resized */
+ sizehints.flags = PMinSize | PMaxSize;
+ sizehints.min_width = sizehints.max_width = actualWidth;
+ sizehints.min_height = sizehints.max_height = actualHeight;
+
+ XSetWMNormalHints( dpy, win, &sizehints );
+
+ XMapWindow( dpy, win );
+
+ if (vidmode_active)
+ XMoveWindow(dpy, win, 0, 0);
+
+ XFlush(dpy);
+ XSync(dpy,False); // bk001130 - from cvs1.17 (mkv)
+ ctx = qglXCreateContext(dpy, visinfo, NULL, True);
+ XSync(dpy,False); // bk001130 - from cvs1.17 (mkv)
+
+ /* GH: Free the visinfo after we're done with it */
+ XFree( visinfo );
+
+ qglXMakeCurrent(dpy, win, ctx);
+
+ // bk001130 - from cvs1.17 (mkv)
+ glstring = (char *)qglGetString (GL_RENDERER);
+ ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );
+
+ // bk010122 - new software token (Indirect)
+ if ( !Q_stricmp( glstring, "Mesa X11")
+ || !Q_stricmp( glstring, "Mesa GLX Indirect") )
+ {
+ if ( !r_allowSoftwareGL->integer )
+ {
+ ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" );
+ ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" );
+ ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername );
+ ri.Printf( PRINT_ALL, " If this is intentional, add\n" );
+ ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" );
+ ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" );
+ ri.Printf( PRINT_ALL, "***********************************************************\n");
+ GLimp_Shutdown( );
+ return RSERR_INVALID_MODE;
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" );
+ }
+ }
+
+ return RSERR_OK;
+}
+
+/*
+** GLW_InitExtensions
+*/
+static void GLW_InitExtensions( void )
+{
+ if ( !r_allowExtensions->integer )
+ {
+ ri.Printf( PRINT_ALL, "*** IGNORING OPENGL EXTENSIONS ***\n" );
+ return;
+ }
+
+ ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
+
+ // GL_S3_s3tc
+ if ( Q_stristr( glConfig.extensions_string, "GL_S3_s3tc" ) )
+ {
+ if ( r_ext_compressed_textures->value )
+ {
+ glConfig.textureCompression = TC_S3TC;
+ ri.Printf( PRINT_ALL, "...using GL_S3_s3tc\n" );
+ } else
+ {
+ glConfig.textureCompression = TC_NONE;
+ ri.Printf( PRINT_ALL, "...ignoring GL_S3_s3tc\n" );
+ }
+ } else
+ {
+ glConfig.textureCompression = TC_NONE;
+ ri.Printf( PRINT_ALL, "...GL_S3_s3tc not found\n" );
+ }
+
+ // GL_EXT_texture_env_add
+ glConfig.textureEnvAddAvailable = qfalse;
+ if ( Q_stristr( glConfig.extensions_string, "EXT_texture_env_add" ) )
+ {
+ if ( r_ext_texture_env_add->integer )
+ {
+ glConfig.textureEnvAddAvailable = qtrue;
+ ri.Printf( PRINT_ALL, "...using GL_EXT_texture_env_add\n" );
+ } else
+ {
+ glConfig.textureEnvAddAvailable = qfalse;
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_env_add\n" );
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_env_add not found\n" );
+ }
+
+ // GL_ARB_multitexture
+ qglMultiTexCoord2fARB = NULL;
+ qglActiveTextureARB = NULL;
+ qglClientActiveTextureARB = NULL;
+ if ( Q_stristr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
+ {
+ if ( r_ext_multitexture->value )
+ {
+ qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) dlsym( glw_state.OpenGLLib, "glMultiTexCoord2fARB" );
+ qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) dlsym( glw_state.OpenGLLib, "glActiveTextureARB" );
+ qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) dlsym( glw_state.OpenGLLib, "glClientActiveTextureARB" );
+
+ if ( qglActiveTextureARB )
+ {
+ GLint glint = 0;
+ qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glint );
+ glConfig.maxActiveTextures = (int) glint;
+
+ if ( glConfig.maxActiveTextures > 1 )
+ {
+ ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
+ } else
+ {
+ qglMultiTexCoord2fARB = NULL;
+ qglActiveTextureARB = NULL;
+ qglClientActiveTextureARB = NULL;
+ ri.Printf( PRINT_ALL, "...not using GL_ARB_multitexture, < 2 texture units\n" );
+ }
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" );
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" );
+ }
+
+ // GL_EXT_compiled_vertex_array
+ if ( Q_stristr( glConfig.extensions_string, "GL_EXT_compiled_vertex_array" ) )
+ {
+ if ( r_ext_compiled_vertex_array->value )
+ {
+ ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
+ qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) dlsym( glw_state.OpenGLLib, "glLockArraysEXT" );
+ qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) dlsym( glw_state.OpenGLLib, "glUnlockArraysEXT" );
+ if (!qglLockArraysEXT || !qglUnlockArraysEXT)
+ {
+ ri.Error (ERR_FATAL, "bad getprocaddress");
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_compiled_vertex_array\n" );
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
+ }
+
+ glConfig.textureFilterAnisotropic = qfalse;
+ if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) )
+ {
+ if ( r_ext_texture_filter_anisotropic->integer ) {
+ qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxAnisotropy );
+ if ( glConfig.maxAnisotropy <= 0 ) {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" );
+ glConfig.maxAnisotropy = 0;
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", glConfig.maxAnisotropy );
+ glConfig.textureFilterAnisotropic = qtrue;
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" );
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" );
+ }
+}
+
+static void GLW_InitGamma(void)
+{
+ /* Minimum extension version required */
+ #define GAMMA_MINMAJOR 2
+ #define GAMMA_MINMINOR 0
+
+ glConfig.deviceSupportsGamma = qfalse;
+
+#ifdef HAVE_XF86DGA
+ if (vidmode_ext)
+ {
+ if (vidmode_MajorVersion < GAMMA_MINMAJOR ||
+ (vidmode_MajorVersion == GAMMA_MINMAJOR && vidmode_MinorVersion < GAMMA_MINMINOR)) {
+ ri.Printf( PRINT_ALL, "XF86 Gamma extension not supported in this version\n");
+ return;
+ }
+ XF86VidModeGetGamma(dpy, scrnum, &vidmode_InitialGamma);
+ ri.Printf( PRINT_ALL, "XF86 Gamma extension initialized\n");
+ glConfig.deviceSupportsGamma = qtrue;
+ }
+#endif /* HAVE_XF86DGA */
+}
+
+/*
+** GLW_LoadOpenGL
+**
+** GLimp_win.c internal function that that attempts to load and use
+** a specific OpenGL DLL.
+*/
+static qboolean GLW_LoadOpenGL( const char *name )
+{
+ qboolean fullscreen;
+
+ ri.Printf( PRINT_ALL, "...loading %s: ", name );
+
+ // disable the 3Dfx splash screen and set gamma
+ // we do this all the time, but it shouldn't hurt anything
+ // on non-3Dfx stuff
+ putenv("FX_GLIDE_NO_SPLASH=0");
+
+ // Mesa VooDoo hacks
+ putenv("MESA_GLX_FX=fullscreen\n");
+
+ // load the QGL layer
+ if ( QGL_Init( name ) )
+ {
+ fullscreen = r_fullscreen->integer;
+
+ // create the window and set up the context
+ if ( !GLW_StartDriverAndSetMode( name, r_mode->integer, fullscreen ) )
+ {
+ if (r_mode->integer != 3)
+ {
+ if ( !GLW_StartDriverAndSetMode( name, 3, fullscreen ) )
+ {
+ goto fail;
+ }
+ } else
+ goto fail;
+ }
+
+ return qtrue;
+ } else
+ {
+ ri.Printf( PRINT_ALL, "failed\n" );
+ }
+ fail:
+
+ QGL_Shutdown();
+
+ return qfalse;
+}
+
+/*
+** XErrorHandler
+** the default X error handler exits the application
+** I found out that on some hosts some operations would raise X errors (GLXUnsupportedPrivateRequest)
+** but those don't seem to be fatal .. so the default would be to just ignore them
+** our implementation mimics the default handler behaviour (not completely cause I'm lazy)
+*/
+int qXErrorHandler(Display *dpy, XErrorEvent *ev)
+{
+ static char buf[1024];
+ XGetErrorText(dpy, ev->error_code, buf, 1024);
+ ri.Printf( PRINT_ALL, "X Error of failed request: %s\n", buf);
+ ri.Printf( PRINT_ALL, " Major opcode of failed request: %d\n", ev->request_code, buf);
+ ri.Printf( PRINT_ALL, " Minor opcode of failed request: %d\n", ev->minor_code);
+ ri.Printf( PRINT_ALL, " Serial number of failed request: %d\n", ev->serial);
+ return 0;
+}
+
+/*
+** GLimp_Init
+**
+** This routine is responsible for initializing the OS specific portions
+** of OpenGL.
+*/
+void GLimp_Init( void )
+{
+ qboolean attemptedlibGL = qfalse;
+ qboolean attempted3Dfx = qfalse;
+ qboolean success = qfalse;
+
+ // guarded, as this is only relevant to SMP renderer thread
+#ifdef SMP
+ if (!XInitThreads())
+ {
+ Com_Printf("GLimp_Init() - XInitThreads() failed, disabling r_smp\n");
+ ri.Cvar_Set( "r_smp", "0" );
+ }
+#endif
+
+ r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH );
+
+ r_previousglDriver = ri.Cvar_Get( "r_previousglDriver", "", CVAR_ROM );
+
+ InitSig();
+
+ IN_Init(); // rcg08312005 moved into glimp.
+
+ // Hack here so that if the UI
+ if ( *r_previousglDriver->string )
+ {
+ // The UI changed it on us, hack it back
+ // This means the renderer can't be changed on the fly
+ ri.Cvar_Set( "r_glDriver", r_previousglDriver->string );
+ }
+
+ // set up our custom error handler for X failures
+ XSetErrorHandler(&qXErrorHandler);
+
+ //
+ // load and initialize the specific OpenGL driver
+ //
+ if ( !GLW_LoadOpenGL( r_glDriver->string ) )
+ {
+ if ( !Q_stricmp( r_glDriver->string, OPENGL_DRIVER_NAME ) )
+ {
+ attemptedlibGL = qtrue;
+ } else if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) )
+ {
+ attempted3Dfx = qtrue;
+ }
+
+ #if 0
+ // TTimo
+ // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=455
+ // old legacy load code, was confusing people who had a bad OpenGL setup
+ if ( !attempted3Dfx && !success )
+ {
+ attempted3Dfx = qtrue;
+ if ( GLW_LoadOpenGL( _3DFX_DRIVER_NAME ) )
+ {
+ ri.Cvar_Set( "r_glDriver", _3DFX_DRIVER_NAME );
+ r_glDriver->modified = qfalse;
+ success = qtrue;
+ }
+ }
+ #endif
+
+ // try ICD before trying 3Dfx standalone driver
+ if ( !attemptedlibGL && !success )
+ {
+ attemptedlibGL = qtrue;
+ if ( GLW_LoadOpenGL( OPENGL_DRIVER_NAME ) )
+ {
+ ri.Cvar_Set( "r_glDriver", OPENGL_DRIVER_NAME );
+ r_glDriver->modified = qfalse;
+ success = qtrue;
+ }
+ }
+
+ if (!success)
+ ri.Error( ERR_FATAL, "GLimp_Init() - could not load OpenGL subsystem\n" );
+
+ }
+
+ // Save it in case the UI stomps it
+ ri.Cvar_Set( "r_previousglDriver", r_glDriver->string );
+
+ // This values force the UI to disable driver selection
+ glConfig.driverType = GLDRV_ICD;
+ glConfig.hardwareType = GLHW_GENERIC;
+
+ // get our config strings
+ Q_strncpyz( glConfig.vendor_string, (char *)qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) );
+ Q_strncpyz( glConfig.renderer_string, (char *)qglGetString (GL_RENDERER), sizeof( glConfig.renderer_string ) );
+ if (*glConfig.renderer_string && glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] == '\n')
+ glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] = 0;
+ Q_strncpyz( glConfig.version_string, (char *)qglGetString (GL_VERSION), sizeof( glConfig.version_string ) );
+ Q_strncpyz( glConfig.extensions_string, (char *)qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) );
+
+ GL_ResolveHardwareType( );
+
+ ri.Cvar_Set( "r_lastValidRenderer", glConfig.renderer_string );
+
+ // initialize extensions
+ GLW_InitExtensions();
+ GLW_InitGamma();
+
+ InitSig(); // not clear why this is at begin & end of function
+
+ return;
+}
+
+
+/*
+** 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)
+{
+ // don't flip if drawing to front buffer
+ if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 )
+ {
+ qglXSwapBuffers(dpy, win);
+ }
+
+ // check logging
+ QGL_EnableLogging( (qboolean)r_logFile->integer ); // bk001205 - was ->value
+}
+
+#ifdef SMP
+/*
+===========================================================
+
+SMP acceleration
+
+===========================================================
+*/
+
+static pthread_mutex_t smpMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t renderCommandsEvent = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t renderCompletedEvent = PTHREAD_COND_INITIALIZER;
+
+static void (*glimpRenderThread)( void );
+
+static void *GLimp_RenderThreadWrapper( void *arg )
+{
+ Com_Printf( "Render thread starting\n" );
+
+ glimpRenderThread();
+
+ qglXMakeCurrent( dpy, None, NULL );
+
+ Com_Printf( "Render thread terminating\n" );
+
+ return arg;
+}
+
+qboolean GLimp_SpawnRenderThread( void (*function)( void ) )
+{
+ pthread_t renderThread;
+ int ret;
+
+ pthread_mutex_init( &smpMutex, NULL );
+
+ pthread_cond_init( &renderCommandsEvent, NULL );
+ pthread_cond_init( &renderCompletedEvent, NULL );
+
+ glimpRenderThread = function;
+
+ ret = pthread_create( &renderThread,
+ NULL, // attributes
+ GLimp_RenderThreadWrapper,
+ NULL ); // argument
+ if ( ret ) {
+ ri.Printf( PRINT_ALL, "pthread_create returned %d: %s", ret, strerror( ret ) );
+ return qfalse;
+ } else {
+ ret = pthread_detach( renderThread );
+ if ( ret ) {
+ ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) );
+ }
+ }
+
+ return qtrue;
+}
+
+static volatile void *smpData = NULL;
+static volatile qboolean smpDataReady;
+
+void *GLimp_RendererSleep( void )
+{
+ void *data;
+
+ qglXMakeCurrent( dpy, None, NULL );
+
+ pthread_mutex_lock( &smpMutex );
+ {
+ smpData = NULL;
+ smpDataReady = qfalse;
+
+ // after this, the front end can exit GLimp_FrontEndSleep
+ pthread_cond_signal( &renderCompletedEvent );
+
+ while ( !smpDataReady ) {
+ pthread_cond_wait( &renderCommandsEvent, &smpMutex );
+ }
+
+ data = (void *)smpData;
+ }
+ pthread_mutex_unlock( &smpMutex );
+
+ qglXMakeCurrent( dpy, win, ctx );
+
+ return data;
+}
+
+void GLimp_FrontEndSleep( void )
+{
+ pthread_mutex_lock( &smpMutex );
+ {
+ while ( smpData ) {
+ pthread_cond_wait( &renderCompletedEvent, &smpMutex );
+ }
+ }
+ pthread_mutex_unlock( &smpMutex );
+
+ qglXMakeCurrent( dpy, win, ctx );
+}
+
+void GLimp_WakeRenderer( void *data )
+{
+ qglXMakeCurrent( dpy, None, NULL );
+
+ pthread_mutex_lock( &smpMutex );
+ {
+ assert( smpData == NULL );
+ smpData = data;
+ smpDataReady = qtrue;
+
+ // after this, the renderer can continue through GLimp_RendererSleep
+ pthread_cond_signal( &renderCommandsEvent );
+ }
+ pthread_mutex_unlock( &smpMutex );
+}
+
+#else
+
+void GLimp_RenderThreadWrapper( void *stub ) {}
+qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) {
+ ri.Printf( PRINT_WARNING, "ERROR: SMP support was disabled at compile time\n");
+ return qfalse;
+}
+void *GLimp_RendererSleep( void ) {
+ return NULL;
+}
+void GLimp_FrontEndSleep( void ) {}
+void GLimp_WakeRenderer( void *data ) {}
+
+#endif
+
+/*****************************************************************************/
+/* MOUSE */
+/*****************************************************************************/
+
+void IN_Init(void) {
+ Com_Printf ("\n------- Input Initialization -------\n");
+ // mouse variables
+ in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
+ in_dgamouse = Cvar_Get ("in_dgamouse", "1", CVAR_ARCHIVE);
+ in_shiftedKeys = Cvar_Get ("in_shiftedKeys", "0", CVAR_ARCHIVE);
+
+ // turn on-off sub-frame timing of X events
+ in_subframe = Cvar_Get ("in_subframe", "1", CVAR_ARCHIVE);
+
+ // developer feature, allows to break without loosing mouse pointer
+ in_nograb = Cvar_Get ("in_nograb", "0", 0);
+
+ // bk001130 - from cvs.17 (mkv), joystick variables
+ in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE|CVAR_LATCH);
+ // bk001130 - changed this to match win32
+ in_joystickDebug = Cvar_Get ("in_debugjoystick", "0", CVAR_TEMP);
+ joy_threshold = Cvar_Get ("joy_threshold", "0.15", CVAR_ARCHIVE); // FIXME: in_joythreshold
+
+ Cvar_Set( "cl_platformSensitivity", "2.0" );
+
+ if (in_mouse->value)
+ mouse_avail = qtrue;
+ else
+ mouse_avail = qfalse;
+
+ IN_StartupJoystick( ); // bk001130 - from cvs1.17 (mkv)
+ Com_Printf ("------------------------------------\n");
+}
+
+void IN_Shutdown(void)
+{
+ mouse_avail = qfalse;
+}
+
+void IN_Frame (void) {
+
+ // bk001130 - from cvs 1.17 (mkv)
+ IN_JoyMove(); // FIXME: disable if on desktop?
+
+ if ( cls.keyCatchers & KEYCATCH_CONSOLE )
+ {
+ // temporarily deactivate if not in the game and
+ // running on the desktop
+ // voodoo always counts as full screen
+ if (Cvar_VariableValue ("r_fullscreen") == 0
+ && strcmp( Cvar_VariableString("r_glDriver"), _3DFX_DRIVER_NAME ) )
+ {
+ IN_DeactivateMouse ();
+ return;
+ }
+ }
+
+ IN_ActivateMouse();
+}
+
+void IN_Activate(void)
+{
+}
+
+// bk001130 - cvs1.17 joystick code (mkv) was here, no linux_joystick.c
+
+void Sys_SendKeyEvents (void) {
+ // XEvent event; // bk001204 - unused
+
+ if (!dpy)
+ return;
+ HandleEvents();
+}
+
+
+// bk010216 - added stubs for non-Linux UNIXes here
+// FIXME - use NO_JOYSTICK or something else generic
+
+#if (defined( __FreeBSD__ ) || defined( __sun)) // rb010123
+void IN_StartupJoystick( void ) {}
+void IN_JoyMove( void ) {}
+#endif
+
+#endif // !USE_SDL_VIDEO
+
diff --git a/src/unix/linux_joystick.c b/src/unix/linux_joystick.c
new file mode 100644
index 0000000..a932f0b
--- /dev/null
+++ b/src/unix/linux_joystick.c
@@ -0,0 +1,212 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+/*
+** linux_joystick.c
+**
+** This file contains ALL Linux specific stuff having to do with the
+** Joystick input. When a port is being made the following functions
+** must be implemented by the port:
+**
+** Authors: mkv, bk
+**
+*/
+
+#if !USE_SDL_VIDEO
+
+#include <linux/joystick.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h> // bk001204
+
+
+#include "../client/client.h"
+#include "linux_local.h"
+
+/* We translate axes movement into keypresses. */
+int joy_keys[16] = {
+ K_LEFTARROW, K_RIGHTARROW,
+ K_UPARROW, K_DOWNARROW,
+ K_JOY16, K_JOY17,
+ K_JOY18, K_JOY19,
+ K_JOY20, K_JOY21,
+ K_JOY22, K_JOY23,
+
+ K_JOY24, K_JOY25,
+ K_JOY26, K_JOY27
+};
+
+/* Our file descriptor for the joystick device. */
+static int joy_fd = -1;
+
+
+// bk001130 - from linux_glimp.c
+extern cvar_t * in_joystick;
+extern cvar_t * in_joystickDebug;
+extern cvar_t * joy_threshold;
+
+
+/**********************************************/
+/* Joystick routines. */
+/**********************************************/
+// bk001130 - from cvs1.17 (mkv), removed from linux_glimp.c
+void IN_StartupJoystick( void )
+{
+ int i = 0;
+
+ joy_fd = -1;
+
+ if( !in_joystick->integer ) {
+ Com_Printf( "Joystick is not active.\n" );
+ return;
+ }
+
+ for( i = 0; i < 4; i++ ) {
+ char filename[PATH_MAX];
+
+ snprintf( filename, PATH_MAX, "/dev/js%d", i );
+
+ joy_fd = open( filename, O_RDONLY | O_NONBLOCK );
+
+ if( joy_fd != -1 ) {
+ struct js_event event;
+ char axes = 0;
+ char buttons = 0;
+ char name[128];
+ int n = -1;
+
+ Com_Printf( "Joystick %s found\n", filename );
+
+ /* Get rid of initialization messages. */
+ do {
+ n = read( joy_fd, &event, sizeof( event ) );
+
+ if( n == -1 ) {
+ break;
+ }
+
+ } while( ( event.type & JS_EVENT_INIT ) );
+
+ /* Get joystick statistics. */
+ ioctl( joy_fd, JSIOCGAXES, &axes );
+ ioctl( joy_fd, JSIOCGBUTTONS, &buttons );
+
+ if( ioctl( joy_fd, JSIOCGNAME( sizeof( name ) ), name ) < 0 ) {
+ strncpy( name, "Unknown", sizeof( name ) );
+ }
+
+ Com_Printf( "Name: %s\n", name );
+ Com_Printf( "Axes: %d\n", axes );
+ Com_Printf( "Buttons: %d\n", buttons );
+
+ /* Our work here is done. */
+ return;
+ }
+
+ }
+
+ /* No soup for you. */
+ if( joy_fd == -1 ) {
+ Com_Printf( "No joystick found.\n" );
+ return;
+ }
+
+}
+
+void IN_JoyMove( void )
+{
+ /* Store instantaneous joystick state. Hack to get around
+ * event model used in Linux joystick driver.
+ */
+ static int axes_state[16];
+ /* Old bits for Quake-style input compares. */
+ static unsigned int old_axes = 0;
+ /* Our current goodies. */
+ unsigned int axes = 0;
+ int i = 0;
+
+ if( joy_fd == -1 ) {
+ return;
+ }
+
+ /* Empty the queue, dispatching button presses immediately
+ * and updating the instantaneous state for the axes.
+ */
+ do {
+ int n = -1;
+ struct js_event event;
+
+ n = read( joy_fd, &event, sizeof( event ) );
+
+ if( n == -1 ) {
+ /* No error, we're non-blocking. */
+ break;
+ }
+
+ if( event.type & JS_EVENT_BUTTON ) {
+ Sys_QueEvent( 0, SE_KEY, K_JOY1 + event.number, event.value, 0, NULL );
+ } else if( event.type & JS_EVENT_AXIS ) {
+
+ if( event.number >= 16 ) {
+ continue;
+ }
+
+ axes_state[event.number] = event.value;
+ } else {
+ Com_Printf( "Unknown joystick event type\n" );
+ }
+
+ } while( 1 );
+
+
+ /* Translate our instantaneous state to bits. */
+ for( i = 0; i < 16; i++ ) {
+ float f = ( (float) axes_state[i] ) / 32767.0f;
+
+ if( f < -joy_threshold->value ) {
+ axes |= ( 1 << ( i * 2 ) );
+ } else if( f > joy_threshold->value ) {
+ axes |= ( 1 << ( ( i * 2 ) + 1 ) );
+ }
+
+ }
+
+ /* Time to update axes state based on old vs. new. */
+ for( i = 0; i < 16; i++ ) {
+
+ if( ( axes & ( 1 << i ) ) && !( old_axes & ( 1 << i ) ) ) {
+ Sys_QueEvent( 0, SE_KEY, joy_keys[i], qtrue, 0, NULL );
+ }
+
+ if( !( axes & ( 1 << i ) ) && ( old_axes & ( 1 << i ) ) ) {
+ Sys_QueEvent( 0, SE_KEY, joy_keys[i], qfalse, 0, NULL );
+ }
+ }
+
+ /* Save for future generations. */
+ old_axes = axes;
+}
+
+#endif // !USE_SDL_VIDEO
+
+
diff --git a/src/unix/linux_local.h b/src/unix/linux_local.h
new file mode 100644
index 0000000..1ab6183
--- /dev/null
+++ b/src/unix/linux_local.h
@@ -0,0 +1,50 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+// linux_local.h: Linux-specific Quake3 header file
+
+void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );
+qboolean Sys_GetPacket ( netadr_t *net_from, msg_t *net_message );
+void Sys_SendKeyEvents (void);
+
+// Input subsystem
+
+void IN_Init (void);
+void IN_Frame (void);
+void IN_Shutdown (void);
+
+
+void IN_JoyMove( void );
+void IN_StartupJoystick( void );
+
+// GL subsystem
+qboolean QGL_Init( const char *dllname );
+void QGL_EnableLogging( qboolean enable );
+void QGL_Shutdown( void );
+
+// bk001130 - win32
+// void IN_JoystickCommands (void);
+
+char *strlwr (char *s);
+
+// signals.c
+void InitSig(void);
diff --git a/src/unix/linux_qgl.c b/src/unix/linux_qgl.c
new file mode 100644
index 0000000..39a0e20
--- /dev/null
+++ b/src/unix/linux_qgl.c
@@ -0,0 +1,4206 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+/*
+** LINUX_QGL.C
+**
+** This file implements the operating system binding of GL to QGL function
+** pointers. When doing a port of Quake2 you must implement the following
+** two functions:
+**
+** QGL_Init() - loads libraries, assigns function pointers, etc.
+** QGL_Shutdown() - unloads libraries, NULLs function pointers
+*/
+
+// bk001204
+#include <unistd.h>
+#include <sys/types.h>
+
+
+#include <float.h>
+#include "../renderer/tr_local.h"
+#include "unix_glw.h"
+
+// bk001129 - from cvs1.17 (mkv)
+//#if defined(__FX__)
+//#include <GL/fxmesa.h>
+//#endif
+//#include <GL/glx.h> // bk010216 - FIXME: all of the above redundant? renderer/qgl.h
+
+#if defined(USE_SDL_VIDEO)
+#include "SDL.h"
+#include "SDL_loadso.h"
+#else
+#include <dlfcn.h>
+#endif
+
+// bk001129 - from cvs1.17 (mkv)
+#if defined(__FX__)
+//FX Mesa Functions
+fxMesaContext (*qfxMesaCreateContext)(GLuint win, GrScreenResolution_t, GrScreenRefresh_t, const GLint attribList[]);
+fxMesaContext (*qfxMesaCreateBestContext)(GLuint win, GLint width, GLint height, const GLint attribList[]);
+void (*qfxMesaDestroyContext)(fxMesaContext ctx);
+void (*qfxMesaMakeCurrent)(fxMesaContext ctx);
+fxMesaContext (*qfxMesaGetCurrentContext)(void);
+void (*qfxMesaSwapBuffers)(void);
+#endif
+
+//GLX Functions
+#if !defined(USE_SDL_VIDEO)
+XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList );
+GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct );
+void (*qglXDestroyContext)( Display *dpy, GLXContext ctx );
+Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx);
+void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask );
+void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable );
+#endif
+
+void ( APIENTRY * qglAccum )(GLenum op, GLfloat value);
+void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref);
+GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences);
+void ( APIENTRY * qglArrayElement )(GLint i);
+void ( APIENTRY * qglBegin )(GLenum mode);
+void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture);
+void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
+void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor);
+void ( APIENTRY * qglCallList )(GLuint list);
+void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists);
+void ( APIENTRY * qglClear )(GLbitfield mask);
+void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+void ( APIENTRY * qglClearDepth )(GLclampd depth);
+void ( APIENTRY * qglClearIndex )(GLfloat c);
+void ( APIENTRY * qglClearStencil )(GLint s);
+void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation);
+void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue);
+void ( APIENTRY * qglColor3bv )(const GLbyte *v);
+void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue);
+void ( APIENTRY * qglColor3dv )(const GLdouble *v);
+void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue);
+void ( APIENTRY * qglColor3fv )(const GLfloat *v);
+void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue);
+void ( APIENTRY * qglColor3iv )(const GLint *v);
+void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue);
+void ( APIENTRY * qglColor3sv )(const GLshort *v);
+void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue);
+void ( APIENTRY * qglColor3ubv )(const GLubyte *v);
+void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue);
+void ( APIENTRY * qglColor3uiv )(const GLuint *v);
+void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue);
+void ( APIENTRY * qglColor3usv )(const GLushort *v);
+void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
+void ( APIENTRY * qglColor4bv )(const GLbyte *v);
+void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+void ( APIENTRY * qglColor4dv )(const GLdouble *v);
+void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+void ( APIENTRY * qglColor4fv )(const GLfloat *v);
+void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha);
+void ( APIENTRY * qglColor4iv )(const GLint *v);
+void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha);
+void ( APIENTRY * qglColor4sv )(const GLshort *v);
+void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+void ( APIENTRY * qglColor4ubv )(const GLubyte *v);
+void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha);
+void ( APIENTRY * qglColor4uiv )(const GLuint *v);
+void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha);
+void ( APIENTRY * qglColor4usv )(const GLushort *v);
+void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode);
+void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
+void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
+void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+void ( APIENTRY * qglCullFace )(GLenum mode);
+void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range);
+void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures);
+void ( APIENTRY * qglDepthFunc )(GLenum func);
+void ( APIENTRY * qglDepthMask )(GLboolean flag);
+void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar);
+void ( APIENTRY * qglDisable )(GLenum cap);
+void ( APIENTRY * qglDisableClientState )(GLenum array);
+void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count);
+void ( APIENTRY * qglDrawBuffer )(GLenum mode);
+void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+void ( APIENTRY * qglEdgeFlag )(GLboolean flag);
+void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer);
+void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag);
+void ( APIENTRY * qglEnable )(GLenum cap);
+void ( APIENTRY * qglEnableClientState )(GLenum array);
+void ( APIENTRY * qglEnd )(void);
+void ( APIENTRY * qglEndList )(void);
+void ( APIENTRY * qglEvalCoord1d )(GLdouble u);
+void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u);
+void ( APIENTRY * qglEvalCoord1f )(GLfloat u);
+void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u);
+void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v);
+void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u);
+void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v);
+void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u);
+void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2);
+void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
+void ( APIENTRY * qglEvalPoint1 )(GLint i);
+void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j);
+void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer);
+void ( APIENTRY * qglFinish )(void);
+void ( APIENTRY * qglFlush )(void);
+void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param);
+void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params);
+void ( APIENTRY * qglFogi )(GLenum pname, GLint param);
+void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params);
+void ( APIENTRY * qglFrontFace )(GLenum mode);
+void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLuint ( APIENTRY * qglGenLists )(GLsizei range);
+void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures);
+void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params);
+void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation);
+void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params);
+GLenum ( APIENTRY * qglGetError )(void);
+void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params);
+void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params);
+void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params);
+void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params);
+void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v);
+void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v);
+void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v);
+void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params);
+void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params);
+void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values);
+void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values);
+void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values);
+void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params);
+void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask);
+const GLubyte * ( APIENTRY * qglGetString )(GLenum name);
+void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params);
+void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params);
+void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params);
+void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params);
+void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params);
+void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params);
+void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params);
+void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params);
+void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params);
+void ( APIENTRY * qglHint )(GLenum target, GLenum mode);
+void ( APIENTRY * qglIndexMask )(GLuint mask);
+void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
+void ( APIENTRY * qglIndexd )(GLdouble c);
+void ( APIENTRY * qglIndexdv )(const GLdouble *c);
+void ( APIENTRY * qglIndexf )(GLfloat c);
+void ( APIENTRY * qglIndexfv )(const GLfloat *c);
+void ( APIENTRY * qglIndexi )(GLint c);
+void ( APIENTRY * qglIndexiv )(const GLint *c);
+void ( APIENTRY * qglIndexs )(GLshort c);
+void ( APIENTRY * qglIndexsv )(const GLshort *c);
+void ( APIENTRY * qglIndexub )(GLubyte c);
+void ( APIENTRY * qglIndexubv )(const GLubyte *c);
+void ( APIENTRY * qglInitNames )(void);
+void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer);
+GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap);
+GLboolean ( APIENTRY * qglIsList )(GLuint list);
+GLboolean ( APIENTRY * qglIsTexture )(GLuint texture);
+void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param);
+void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params);
+void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param);
+void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params);
+void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param);
+void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params);
+void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param);
+void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params);
+void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern);
+void ( APIENTRY * qglLineWidth )(GLfloat width);
+void ( APIENTRY * qglListBase )(GLuint base);
+void ( APIENTRY * qglLoadIdentity )(void);
+void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m);
+void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m);
+void ( APIENTRY * qglLoadName )(GLuint name);
+void ( APIENTRY * qglLogicOp )(GLenum opcode);
+void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2);
+void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2);
+void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
+void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
+void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param);
+void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params);
+void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param);
+void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params);
+void ( APIENTRY * qglMatrixMode )(GLenum mode);
+void ( APIENTRY * qglMultMatrixd )(const GLdouble *m);
+void ( APIENTRY * qglMultMatrixf )(const GLfloat *m);
+void ( APIENTRY * qglNewList )(GLuint list, GLenum mode);
+void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz);
+void ( APIENTRY * qglNormal3bv )(const GLbyte *v);
+void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz);
+void ( APIENTRY * qglNormal3dv )(const GLdouble *v);
+void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz);
+void ( APIENTRY * qglNormal3fv )(const GLfloat *v);
+void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz);
+void ( APIENTRY * qglNormal3iv )(const GLint *v);
+void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz);
+void ( APIENTRY * qglNormal3sv )(const GLshort *v);
+void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
+void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+void ( APIENTRY * qglPassThrough )(GLfloat token);
+void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values);
+void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values);
+void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values);
+void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param);
+void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param);
+void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param);
+void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param);
+void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor);
+void ( APIENTRY * qglPointSize )(GLfloat size);
+void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode);
+void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units);
+void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask);
+void ( APIENTRY * qglPopAttrib )(void);
+void ( APIENTRY * qglPopClientAttrib )(void);
+void ( APIENTRY * qglPopMatrix )(void);
+void ( APIENTRY * qglPopName )(void);
+void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities);
+void ( APIENTRY * qglPushAttrib )(GLbitfield mask);
+void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask);
+void ( APIENTRY * qglPushMatrix )(void);
+void ( APIENTRY * qglPushName )(GLuint name);
+void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y);
+void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v);
+void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y);
+void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v);
+void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y);
+void ( APIENTRY * qglRasterPos2iv )(const GLint *v);
+void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y);
+void ( APIENTRY * qglRasterPos2sv )(const GLshort *v);
+void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z);
+void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v);
+void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z);
+void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v);
+void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z);
+void ( APIENTRY * qglRasterPos3iv )(const GLint *v);
+void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z);
+void ( APIENTRY * qglRasterPos3sv )(const GLshort *v);
+void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v);
+void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v);
+void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w);
+void ( APIENTRY * qglRasterPos4iv )(const GLint *v);
+void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w);
+void ( APIENTRY * qglRasterPos4sv )(const GLshort *v);
+void ( APIENTRY * qglReadBuffer )(GLenum mode);
+void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
+void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2);
+void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2);
+void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2);
+void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2);
+void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
+void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2);
+GLint ( APIENTRY * qglRenderMode )(GLenum mode);
+void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z);
+void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z);
+void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height);
+void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer);
+void ( APIENTRY * qglShadeModel )(GLenum mode);
+void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask);
+void ( APIENTRY * qglStencilMask )(GLuint mask);
+void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass);
+void ( APIENTRY * qglTexCoord1d )(GLdouble s);
+void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v);
+void ( APIENTRY * qglTexCoord1f )(GLfloat s);
+void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v);
+void ( APIENTRY * qglTexCoord1i )(GLint s);
+void ( APIENTRY * qglTexCoord1iv )(const GLint *v);
+void ( APIENTRY * qglTexCoord1s )(GLshort s);
+void ( APIENTRY * qglTexCoord1sv )(const GLshort *v);
+void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t);
+void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v);
+void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t);
+void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v);
+void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t);
+void ( APIENTRY * qglTexCoord2iv )(const GLint *v);
+void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t);
+void ( APIENTRY * qglTexCoord2sv )(const GLshort *v);
+void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r);
+void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v);
+void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r);
+void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v);
+void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r);
+void ( APIENTRY * qglTexCoord3iv )(const GLint *v);
+void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r);
+void ( APIENTRY * qglTexCoord3sv )(const GLshort *v);
+void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v);
+void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v);
+void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q);
+void ( APIENTRY * qglTexCoord4iv )(const GLint *v);
+void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q);
+void ( APIENTRY * qglTexCoord4sv )(const GLshort *v);
+void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param);
+void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params);
+void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param);
+void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params);
+void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param);
+void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params);
+void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param);
+void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params);
+void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param);
+void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params);
+void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param);
+void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
+void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param);
+void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params);
+void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z);
+void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z);
+void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y);
+void ( APIENTRY * qglVertex2dv )(const GLdouble *v);
+void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y);
+void ( APIENTRY * qglVertex2fv )(const GLfloat *v);
+void ( APIENTRY * qglVertex2i )(GLint x, GLint y);
+void ( APIENTRY * qglVertex2iv )(const GLint *v);
+void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y);
+void ( APIENTRY * qglVertex2sv )(const GLshort *v);
+void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z);
+void ( APIENTRY * qglVertex3dv )(const GLdouble *v);
+void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z);
+void ( APIENTRY * qglVertex3fv )(const GLfloat *v);
+void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z);
+void ( APIENTRY * qglVertex3iv )(const GLint *v);
+void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z);
+void ( APIENTRY * qglVertex3sv )(const GLshort *v);
+void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+void ( APIENTRY * qglVertex4dv )(const GLdouble *v);
+void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+void ( APIENTRY * qglVertex4fv )(const GLfloat *v);
+void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w);
+void ( APIENTRY * qglVertex4iv )(const GLint *v);
+void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w);
+void ( APIENTRY * qglVertex4sv )(const GLshort *v);
+void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height);
+
+void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
+void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
+void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
+
+void ( APIENTRY * qglLockArraysEXT)( GLint, GLint);
+void ( APIENTRY * qglUnlockArraysEXT) ( void );
+
+void ( APIENTRY * qglPointParameterfEXT)( GLenum param, GLfloat value );
+void ( APIENTRY * qglPointParameterfvEXT)( GLenum param, const GLfloat *value );
+void ( APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * );
+void ( APIENTRY * qgl3DfxSetPaletteEXT)( GLuint * );
+void ( APIENTRY * qglSelectTextureSGIS)( GLenum );
+void ( APIENTRY * qglMTexCoord2fSGIS)( GLenum, GLfloat, GLfloat );
+
+static void ( APIENTRY * dllAccum )(GLenum op, GLfloat value);
+static void ( APIENTRY * dllAlphaFunc )(GLenum func, GLclampf ref);
+GLboolean ( APIENTRY * dllAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences);
+static void ( APIENTRY * dllArrayElement )(GLint i);
+static void ( APIENTRY * dllBegin )(GLenum mode);
+static void ( APIENTRY * dllBindTexture )(GLenum target, GLuint texture);
+static void ( APIENTRY * dllBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
+static void ( APIENTRY * dllBlendFunc )(GLenum sfactor, GLenum dfactor);
+static void ( APIENTRY * dllCallList )(GLuint list);
+static void ( APIENTRY * dllCallLists )(GLsizei n, GLenum type, const GLvoid *lists);
+static void ( APIENTRY * dllClear )(GLbitfield mask);
+static void ( APIENTRY * dllClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+static void ( APIENTRY * dllClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+static void ( APIENTRY * dllClearDepth )(GLclampd depth);
+static void ( APIENTRY * dllClearIndex )(GLfloat c);
+static void ( APIENTRY * dllClearStencil )(GLint s);
+static void ( APIENTRY * dllClipPlane )(GLenum plane, const GLdouble *equation);
+static void ( APIENTRY * dllColor3b )(GLbyte red, GLbyte green, GLbyte blue);
+static void ( APIENTRY * dllColor3bv )(const GLbyte *v);
+static void ( APIENTRY * dllColor3d )(GLdouble red, GLdouble green, GLdouble blue);
+static void ( APIENTRY * dllColor3dv )(const GLdouble *v);
+static void ( APIENTRY * dllColor3f )(GLfloat red, GLfloat green, GLfloat blue);
+static void ( APIENTRY * dllColor3fv )(const GLfloat *v);
+static void ( APIENTRY * dllColor3i )(GLint red, GLint green, GLint blue);
+static void ( APIENTRY * dllColor3iv )(const GLint *v);
+static void ( APIENTRY * dllColor3s )(GLshort red, GLshort green, GLshort blue);
+static void ( APIENTRY * dllColor3sv )(const GLshort *v);
+static void ( APIENTRY * dllColor3ub )(GLubyte red, GLubyte green, GLubyte blue);
+static void ( APIENTRY * dllColor3ubv )(const GLubyte *v);
+static void ( APIENTRY * dllColor3ui )(GLuint red, GLuint green, GLuint blue);
+static void ( APIENTRY * dllColor3uiv )(const GLuint *v);
+static void ( APIENTRY * dllColor3us )(GLushort red, GLushort green, GLushort blue);
+static void ( APIENTRY * dllColor3usv )(const GLushort *v);
+static void ( APIENTRY * dllColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
+static void ( APIENTRY * dllColor4bv )(const GLbyte *v);
+static void ( APIENTRY * dllColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+static void ( APIENTRY * dllColor4dv )(const GLdouble *v);
+static void ( APIENTRY * dllColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+static void ( APIENTRY * dllColor4fv )(const GLfloat *v);
+static void ( APIENTRY * dllColor4i )(GLint red, GLint green, GLint blue, GLint alpha);
+static void ( APIENTRY * dllColor4iv )(const GLint *v);
+static void ( APIENTRY * dllColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha);
+static void ( APIENTRY * dllColor4sv )(const GLshort *v);
+static void ( APIENTRY * dllColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+static void ( APIENTRY * dllColor4ubv )(const GLubyte *v);
+static void ( APIENTRY * dllColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha);
+static void ( APIENTRY * dllColor4uiv )(const GLuint *v);
+static void ( APIENTRY * dllColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha);
+static void ( APIENTRY * dllColor4usv )(const GLushort *v);
+static void ( APIENTRY * dllColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+static void ( APIENTRY * dllColorMaterial )(GLenum face, GLenum mode);
+static void ( APIENTRY * dllColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+static void ( APIENTRY * dllCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
+static void ( APIENTRY * dllCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
+static void ( APIENTRY * dllCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+static void ( APIENTRY * dllCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+static void ( APIENTRY * dllCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+static void ( APIENTRY * dllCullFace )(GLenum mode);
+static void ( APIENTRY * dllDeleteLists )(GLuint list, GLsizei range);
+static void ( APIENTRY * dllDeleteTextures )(GLsizei n, const GLuint *textures);
+static void ( APIENTRY * dllDepthFunc )(GLenum func);
+static void ( APIENTRY * dllDepthMask )(GLboolean flag);
+static void ( APIENTRY * dllDepthRange )(GLclampd zNear, GLclampd zFar);
+static void ( APIENTRY * dllDisable )(GLenum cap);
+static void ( APIENTRY * dllDisableClientState )(GLenum array);
+static void ( APIENTRY * dllDrawArrays )(GLenum mode, GLint first, GLsizei count);
+static void ( APIENTRY * dllDrawBuffer )(GLenum mode);
+static void ( APIENTRY * dllDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+static void ( APIENTRY * dllDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+static void ( APIENTRY * dllEdgeFlag )(GLboolean flag);
+static void ( APIENTRY * dllEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer);
+static void ( APIENTRY * dllEdgeFlagv )(const GLboolean *flag);
+static void ( APIENTRY * dllEnable )(GLenum cap);
+static void ( APIENTRY * dllEnableClientState )(GLenum array);
+static void ( APIENTRY * dllEnd )(void);
+static void ( APIENTRY * dllEndList )(void);
+static void ( APIENTRY * dllEvalCoord1d )(GLdouble u);
+static void ( APIENTRY * dllEvalCoord1dv )(const GLdouble *u);
+static void ( APIENTRY * dllEvalCoord1f )(GLfloat u);
+static void ( APIENTRY * dllEvalCoord1fv )(const GLfloat *u);
+static void ( APIENTRY * dllEvalCoord2d )(GLdouble u, GLdouble v);
+static void ( APIENTRY * dllEvalCoord2dv )(const GLdouble *u);
+static void ( APIENTRY * dllEvalCoord2f )(GLfloat u, GLfloat v);
+static void ( APIENTRY * dllEvalCoord2fv )(const GLfloat *u);
+static void ( APIENTRY * dllEvalMesh1 )(GLenum mode, GLint i1, GLint i2);
+static void ( APIENTRY * dllEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
+static void ( APIENTRY * dllEvalPoint1 )(GLint i);
+static void ( APIENTRY * dllEvalPoint2 )(GLint i, GLint j);
+static void ( APIENTRY * dllFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer);
+static void ( APIENTRY * dllFinish )(void);
+static void ( APIENTRY * dllFlush )(void);
+static void ( APIENTRY * dllFogf )(GLenum pname, GLfloat param);
+static void ( APIENTRY * dllFogfv )(GLenum pname, const GLfloat *params);
+static void ( APIENTRY * dllFogi )(GLenum pname, GLint param);
+static void ( APIENTRY * dllFogiv )(GLenum pname, const GLint *params);
+static void ( APIENTRY * dllFrontFace )(GLenum mode);
+static void ( APIENTRY * dllFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLuint ( APIENTRY * dllGenLists )(GLsizei range);
+static void ( APIENTRY * dllGenTextures )(GLsizei n, GLuint *textures);
+static void ( APIENTRY * dllGetBooleanv )(GLenum pname, GLboolean *params);
+static void ( APIENTRY * dllGetClipPlane )(GLenum plane, GLdouble *equation);
+static void ( APIENTRY * dllGetDoublev )(GLenum pname, GLdouble *params);
+GLenum ( APIENTRY * dllGetError )(void);
+static void ( APIENTRY * dllGetFloatv )(GLenum pname, GLfloat *params);
+static void ( APIENTRY * dllGetIntegerv )(GLenum pname, GLint *params);
+static void ( APIENTRY * dllGetLightfv )(GLenum light, GLenum pname, GLfloat *params);
+static void ( APIENTRY * dllGetLightiv )(GLenum light, GLenum pname, GLint *params);
+static void ( APIENTRY * dllGetMapdv )(GLenum target, GLenum query, GLdouble *v);
+static void ( APIENTRY * dllGetMapfv )(GLenum target, GLenum query, GLfloat *v);
+static void ( APIENTRY * dllGetMapiv )(GLenum target, GLenum query, GLint *v);
+static void ( APIENTRY * dllGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params);
+static void ( APIENTRY * dllGetMaterialiv )(GLenum face, GLenum pname, GLint *params);
+static void ( APIENTRY * dllGetPixelMapfv )(GLenum map, GLfloat *values);
+static void ( APIENTRY * dllGetPixelMapuiv )(GLenum map, GLuint *values);
+static void ( APIENTRY * dllGetPixelMapusv )(GLenum map, GLushort *values);
+static void ( APIENTRY * dllGetPointerv )(GLenum pname, GLvoid* *params);
+static void ( APIENTRY * dllGetPolygonStipple )(GLubyte *mask);
+const GLubyte * ( APIENTRY * dllGetString )(GLenum name);
+static void ( APIENTRY * dllGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params);
+static void ( APIENTRY * dllGetTexEnviv )(GLenum target, GLenum pname, GLint *params);
+static void ( APIENTRY * dllGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params);
+static void ( APIENTRY * dllGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params);
+static void ( APIENTRY * dllGetTexGeniv )(GLenum coord, GLenum pname, GLint *params);
+static void ( APIENTRY * dllGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+static void ( APIENTRY * dllGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params);
+static void ( APIENTRY * dllGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params);
+static void ( APIENTRY * dllGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params);
+static void ( APIENTRY * dllGetTexParameteriv )(GLenum target, GLenum pname, GLint *params);
+static void ( APIENTRY * dllHint )(GLenum target, GLenum mode);
+static void ( APIENTRY * dllIndexMask )(GLuint mask);
+static void ( APIENTRY * dllIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
+static void ( APIENTRY * dllIndexd )(GLdouble c);
+static void ( APIENTRY * dllIndexdv )(const GLdouble *c);
+static void ( APIENTRY * dllIndexf )(GLfloat c);
+static void ( APIENTRY * dllIndexfv )(const GLfloat *c);
+static void ( APIENTRY * dllIndexi )(GLint c);
+static void ( APIENTRY * dllIndexiv )(const GLint *c);
+static void ( APIENTRY * dllIndexs )(GLshort c);
+static void ( APIENTRY * dllIndexsv )(const GLshort *c);
+static void ( APIENTRY * dllIndexub )(GLubyte c);
+static void ( APIENTRY * dllIndexubv )(const GLubyte *c);
+static void ( APIENTRY * dllInitNames )(void);
+static void ( APIENTRY * dllInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer);
+GLboolean ( APIENTRY * dllIsEnabled )(GLenum cap);
+GLboolean ( APIENTRY * dllIsList )(GLuint list);
+GLboolean ( APIENTRY * dllIsTexture )(GLuint texture);
+static void ( APIENTRY * dllLightModelf )(GLenum pname, GLfloat param);
+static void ( APIENTRY * dllLightModelfv )(GLenum pname, const GLfloat *params);
+static void ( APIENTRY * dllLightModeli )(GLenum pname, GLint param);
+static void ( APIENTRY * dllLightModeliv )(GLenum pname, const GLint *params);
+static void ( APIENTRY * dllLightf )(GLenum light, GLenum pname, GLfloat param);
+static void ( APIENTRY * dllLightfv )(GLenum light, GLenum pname, const GLfloat *params);
+static void ( APIENTRY * dllLighti )(GLenum light, GLenum pname, GLint param);
+static void ( APIENTRY * dllLightiv )(GLenum light, GLenum pname, const GLint *params);
+static void ( APIENTRY * dllLineStipple )(GLint factor, GLushort pattern);
+static void ( APIENTRY * dllLineWidth )(GLfloat width);
+static void ( APIENTRY * dllListBase )(GLuint base);
+static void ( APIENTRY * dllLoadIdentity )(void);
+static void ( APIENTRY * dllLoadMatrixd )(const GLdouble *m);
+static void ( APIENTRY * dllLoadMatrixf )(const GLfloat *m);
+static void ( APIENTRY * dllLoadName )(GLuint name);
+static void ( APIENTRY * dllLogicOp )(GLenum opcode);
+static void ( APIENTRY * dllMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+static void ( APIENTRY * dllMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+static void ( APIENTRY * dllMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+static void ( APIENTRY * dllMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+static void ( APIENTRY * dllMapGrid1d )(GLint un, GLdouble u1, GLdouble u2);
+static void ( APIENTRY * dllMapGrid1f )(GLint un, GLfloat u1, GLfloat u2);
+static void ( APIENTRY * dllMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
+static void ( APIENTRY * dllMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
+static void ( APIENTRY * dllMaterialf )(GLenum face, GLenum pname, GLfloat param);
+static void ( APIENTRY * dllMaterialfv )(GLenum face, GLenum pname, const GLfloat *params);
+static void ( APIENTRY * dllMateriali )(GLenum face, GLenum pname, GLint param);
+static void ( APIENTRY * dllMaterialiv )(GLenum face, GLenum pname, const GLint *params);
+static void ( APIENTRY * dllMatrixMode )(GLenum mode);
+static void ( APIENTRY * dllMultMatrixd )(const GLdouble *m);
+static void ( APIENTRY * dllMultMatrixf )(const GLfloat *m);
+static void ( APIENTRY * dllNewList )(GLuint list, GLenum mode);
+static void ( APIENTRY * dllNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz);
+static void ( APIENTRY * dllNormal3bv )(const GLbyte *v);
+static void ( APIENTRY * dllNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz);
+static void ( APIENTRY * dllNormal3dv )(const GLdouble *v);
+static void ( APIENTRY * dllNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz);
+static void ( APIENTRY * dllNormal3fv )(const GLfloat *v);
+static void ( APIENTRY * dllNormal3i )(GLint nx, GLint ny, GLint nz);
+static void ( APIENTRY * dllNormal3iv )(const GLint *v);
+static void ( APIENTRY * dllNormal3s )(GLshort nx, GLshort ny, GLshort nz);
+static void ( APIENTRY * dllNormal3sv )(const GLshort *v);
+static void ( APIENTRY * dllNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
+static void ( APIENTRY * dllOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+static void ( APIENTRY * dllPassThrough )(GLfloat token);
+static void ( APIENTRY * dllPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values);
+static void ( APIENTRY * dllPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values);
+static void ( APIENTRY * dllPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values);
+static void ( APIENTRY * dllPixelStoref )(GLenum pname, GLfloat param);
+static void ( APIENTRY * dllPixelStorei )(GLenum pname, GLint param);
+static void ( APIENTRY * dllPixelTransferf )(GLenum pname, GLfloat param);
+static void ( APIENTRY * dllPixelTransferi )(GLenum pname, GLint param);
+static void ( APIENTRY * dllPixelZoom )(GLfloat xfactor, GLfloat yfactor);
+static void ( APIENTRY * dllPointSize )(GLfloat size);
+static void ( APIENTRY * dllPolygonMode )(GLenum face, GLenum mode);
+static void ( APIENTRY * dllPolygonOffset )(GLfloat factor, GLfloat units);
+static void ( APIENTRY * dllPolygonStipple )(const GLubyte *mask);
+static void ( APIENTRY * dllPopAttrib )(void);
+static void ( APIENTRY * dllPopClientAttrib )(void);
+static void ( APIENTRY * dllPopMatrix )(void);
+static void ( APIENTRY * dllPopName )(void);
+static void ( APIENTRY * dllPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities);
+static void ( APIENTRY * dllPushAttrib )(GLbitfield mask);
+static void ( APIENTRY * dllPushClientAttrib )(GLbitfield mask);
+static void ( APIENTRY * dllPushMatrix )(void);
+static void ( APIENTRY * dllPushName )(GLuint name);
+static void ( APIENTRY * dllRasterPos2d )(GLdouble x, GLdouble y);
+static void ( APIENTRY * dllRasterPos2dv )(const GLdouble *v);
+static void ( APIENTRY * dllRasterPos2f )(GLfloat x, GLfloat y);
+static void ( APIENTRY * dllRasterPos2fv )(const GLfloat *v);
+static void ( APIENTRY * dllRasterPos2i )(GLint x, GLint y);
+static void ( APIENTRY * dllRasterPos2iv )(const GLint *v);
+static void ( APIENTRY * dllRasterPos2s )(GLshort x, GLshort y);
+static void ( APIENTRY * dllRasterPos2sv )(const GLshort *v);
+static void ( APIENTRY * dllRasterPos3d )(GLdouble x, GLdouble y, GLdouble z);
+static void ( APIENTRY * dllRasterPos3dv )(const GLdouble *v);
+static void ( APIENTRY * dllRasterPos3f )(GLfloat x, GLfloat y, GLfloat z);
+static void ( APIENTRY * dllRasterPos3fv )(const GLfloat *v);
+static void ( APIENTRY * dllRasterPos3i )(GLint x, GLint y, GLint z);
+static void ( APIENTRY * dllRasterPos3iv )(const GLint *v);
+static void ( APIENTRY * dllRasterPos3s )(GLshort x, GLshort y, GLshort z);
+static void ( APIENTRY * dllRasterPos3sv )(const GLshort *v);
+static void ( APIENTRY * dllRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+static void ( APIENTRY * dllRasterPos4dv )(const GLdouble *v);
+static void ( APIENTRY * dllRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+static void ( APIENTRY * dllRasterPos4fv )(const GLfloat *v);
+static void ( APIENTRY * dllRasterPos4i )(GLint x, GLint y, GLint z, GLint w);
+static void ( APIENTRY * dllRasterPos4iv )(const GLint *v);
+static void ( APIENTRY * dllRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w);
+static void ( APIENTRY * dllRasterPos4sv )(const GLshort *v);
+static void ( APIENTRY * dllReadBuffer )(GLenum mode);
+static void ( APIENTRY * dllReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+static void ( APIENTRY * dllRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
+static void ( APIENTRY * dllRectdv )(const GLdouble *v1, const GLdouble *v2);
+static void ( APIENTRY * dllRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+static void ( APIENTRY * dllRectfv )(const GLfloat *v1, const GLfloat *v2);
+static void ( APIENTRY * dllRecti )(GLint x1, GLint y1, GLint x2, GLint y2);
+static void ( APIENTRY * dllRectiv )(const GLint *v1, const GLint *v2);
+static void ( APIENTRY * dllRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
+static void ( APIENTRY * dllRectsv )(const GLshort *v1, const GLshort *v2);
+GLint ( APIENTRY * dllRenderMode )(GLenum mode);
+static void ( APIENTRY * dllRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+static void ( APIENTRY * dllRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+static void ( APIENTRY * dllScaled )(GLdouble x, GLdouble y, GLdouble z);
+static void ( APIENTRY * dllScalef )(GLfloat x, GLfloat y, GLfloat z);
+static void ( APIENTRY * dllScissor )(GLint x, GLint y, GLsizei width, GLsizei height);
+static void ( APIENTRY * dllSelectBuffer )(GLsizei size, GLuint *buffer);
+static void ( APIENTRY * dllShadeModel )(GLenum mode);
+static void ( APIENTRY * dllStencilFunc )(GLenum func, GLint ref, GLuint mask);
+static void ( APIENTRY * dllStencilMask )(GLuint mask);
+static void ( APIENTRY * dllStencilOp )(GLenum fail, GLenum zfail, GLenum zpass);
+static void ( APIENTRY * dllTexCoord1d )(GLdouble s);
+static void ( APIENTRY * dllTexCoord1dv )(const GLdouble *v);
+static void ( APIENTRY * dllTexCoord1f )(GLfloat s);
+static void ( APIENTRY * dllTexCoord1fv )(const GLfloat *v);
+static void ( APIENTRY * dllTexCoord1i )(GLint s);
+static void ( APIENTRY * dllTexCoord1iv )(const GLint *v);
+static void ( APIENTRY * dllTexCoord1s )(GLshort s);
+static void ( APIENTRY * dllTexCoord1sv )(const GLshort *v);
+static void ( APIENTRY * dllTexCoord2d )(GLdouble s, GLdouble t);
+static void ( APIENTRY * dllTexCoord2dv )(const GLdouble *v);
+static void ( APIENTRY * dllTexCoord2f )(GLfloat s, GLfloat t);
+static void ( APIENTRY * dllTexCoord2fv )(const GLfloat *v);
+static void ( APIENTRY * dllTexCoord2i )(GLint s, GLint t);
+static void ( APIENTRY * dllTexCoord2iv )(const GLint *v);
+static void ( APIENTRY * dllTexCoord2s )(GLshort s, GLshort t);
+static void ( APIENTRY * dllTexCoord2sv )(const GLshort *v);
+static void ( APIENTRY * dllTexCoord3d )(GLdouble s, GLdouble t, GLdouble r);
+static void ( APIENTRY * dllTexCoord3dv )(const GLdouble *v);
+static void ( APIENTRY * dllTexCoord3f )(GLfloat s, GLfloat t, GLfloat r);
+static void ( APIENTRY * dllTexCoord3fv )(const GLfloat *v);
+static void ( APIENTRY * dllTexCoord3i )(GLint s, GLint t, GLint r);
+static void ( APIENTRY * dllTexCoord3iv )(const GLint *v);
+static void ( APIENTRY * dllTexCoord3s )(GLshort s, GLshort t, GLshort r);
+static void ( APIENTRY * dllTexCoord3sv )(const GLshort *v);
+static void ( APIENTRY * dllTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+static void ( APIENTRY * dllTexCoord4dv )(const GLdouble *v);
+static void ( APIENTRY * dllTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+static void ( APIENTRY * dllTexCoord4fv )(const GLfloat *v);
+static void ( APIENTRY * dllTexCoord4i )(GLint s, GLint t, GLint r, GLint q);
+static void ( APIENTRY * dllTexCoord4iv )(const GLint *v);
+static void ( APIENTRY * dllTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q);
+static void ( APIENTRY * dllTexCoord4sv )(const GLshort *v);
+static void ( APIENTRY * dllTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+static void ( APIENTRY * dllTexEnvf )(GLenum target, GLenum pname, GLfloat param);
+static void ( APIENTRY * dllTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params);
+static void ( APIENTRY * dllTexEnvi )(GLenum target, GLenum pname, GLint param);
+static void ( APIENTRY * dllTexEnviv )(GLenum target, GLenum pname, const GLint *params);
+static void ( APIENTRY * dllTexGend )(GLenum coord, GLenum pname, GLdouble param);
+static void ( APIENTRY * dllTexGendv )(GLenum coord, GLenum pname, const GLdouble *params);
+static void ( APIENTRY * dllTexGenf )(GLenum coord, GLenum pname, GLfloat param);
+static void ( APIENTRY * dllTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params);
+static void ( APIENTRY * dllTexGeni )(GLenum coord, GLenum pname, GLint param);
+static void ( APIENTRY * dllTexGeniv )(GLenum coord, GLenum pname, const GLint *params);
+static void ( APIENTRY * dllTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+static void ( APIENTRY * dllTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+static void ( APIENTRY * dllTexParameterf )(GLenum target, GLenum pname, GLfloat param);
+static void ( APIENTRY * dllTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
+static void ( APIENTRY * dllTexParameteri )(GLenum target, GLenum pname, GLint param);
+static void ( APIENTRY * dllTexParameteriv )(GLenum target, GLenum pname, const GLint *params);
+static void ( APIENTRY * dllTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+static void ( APIENTRY * dllTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+static void ( APIENTRY * dllTranslated )(GLdouble x, GLdouble y, GLdouble z);
+static void ( APIENTRY * dllTranslatef )(GLfloat x, GLfloat y, GLfloat z);
+static void ( APIENTRY * dllVertex2d )(GLdouble x, GLdouble y);
+static void ( APIENTRY * dllVertex2dv )(const GLdouble *v);
+static void ( APIENTRY * dllVertex2f )(GLfloat x, GLfloat y);
+static void ( APIENTRY * dllVertex2fv )(const GLfloat *v);
+static void ( APIENTRY * dllVertex2i )(GLint x, GLint y);
+static void ( APIENTRY * dllVertex2iv )(const GLint *v);
+static void ( APIENTRY * dllVertex2s )(GLshort x, GLshort y);
+static void ( APIENTRY * dllVertex2sv )(const GLshort *v);
+static void ( APIENTRY * dllVertex3d )(GLdouble x, GLdouble y, GLdouble z);
+static void ( APIENTRY * dllVertex3dv )(const GLdouble *v);
+static void ( APIENTRY * dllVertex3f )(GLfloat x, GLfloat y, GLfloat z);
+static void ( APIENTRY * dllVertex3fv )(const GLfloat *v);
+static void ( APIENTRY * dllVertex3i )(GLint x, GLint y, GLint z);
+static void ( APIENTRY * dllVertex3iv )(const GLint *v);
+static void ( APIENTRY * dllVertex3s )(GLshort x, GLshort y, GLshort z);
+static void ( APIENTRY * dllVertex3sv )(const GLshort *v);
+static void ( APIENTRY * dllVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+static void ( APIENTRY * dllVertex4dv )(const GLdouble *v);
+static void ( APIENTRY * dllVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+static void ( APIENTRY * dllVertex4fv )(const GLfloat *v);
+static void ( APIENTRY * dllVertex4i )(GLint x, GLint y, GLint z, GLint w);
+static void ( APIENTRY * dllVertex4iv )(const GLint *v);
+static void ( APIENTRY * dllVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w);
+static void ( APIENTRY * dllVertex4sv )(const GLshort *v);
+static void ( APIENTRY * dllVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+static void ( APIENTRY * dllViewport )(GLint x, GLint y, GLsizei width, GLsizei height);
+
+static void APIENTRY logAccum(GLenum op, GLfloat value)
+{
+ fprintf( glw_state.log_fp, "glAccum\n" );
+ dllAccum( op, value );
+}
+
+static void APIENTRY logAlphaFunc(GLenum func, GLclampf ref)
+{
+ fprintf( glw_state.log_fp, "glAlphaFunc( 0x%x, %f )\n", (unsigned int) func, ref );
+ dllAlphaFunc( func, ref );
+}
+
+static GLboolean APIENTRY logAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
+{
+ fprintf( glw_state.log_fp, "glAreTexturesResident\n" );
+ return dllAreTexturesResident( n, textures, residences );
+}
+
+static void APIENTRY logArrayElement(GLint i)
+{
+ fprintf( glw_state.log_fp, "glArrayElement\n" );
+ dllArrayElement( i );
+}
+
+static void APIENTRY logBegin(GLenum mode)
+{
+ fprintf( glw_state.log_fp, "glBegin( 0x%x )\n", (unsigned int) mode );
+ dllBegin( mode );
+}
+
+static void APIENTRY logBindTexture(GLenum target, GLuint texture)
+{
+ fprintf( glw_state.log_fp, "glBindTexture( 0x%x, %u )\n", (unsigned int) target, (unsigned int) texture );
+ dllBindTexture( target, texture );
+}
+
+static void APIENTRY logBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
+{
+ fprintf( glw_state.log_fp, "glBitmap\n" );
+ dllBitmap( width, height, xorig, yorig, xmove, ymove, bitmap );
+}
+
+static void APIENTRY logBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ fprintf( glw_state.log_fp, "glBlendFunc( 0x%x, 0x%x )\n", (unsigned int) sfactor, (unsigned int) dfactor );
+ dllBlendFunc( sfactor, dfactor );
+}
+
+static void APIENTRY logCallList(GLuint list)
+{
+ fprintf( glw_state.log_fp, "glCallList( %u )\n", (unsigned int) list );
+ dllCallList( list );
+}
+
+static void APIENTRY logCallLists(GLsizei n, GLenum type, const void *lists)
+{
+ fprintf( glw_state.log_fp, "glCallLists\n" );
+ dllCallLists( n, type, lists );
+}
+
+static void APIENTRY logClear(GLbitfield mask)
+{
+ fprintf( glw_state.log_fp, "glClear\n" );
+ dllClear( mask );
+}
+
+static void APIENTRY logClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ fprintf( glw_state.log_fp, "glClearAccum\n" );
+ dllClearAccum( red, green, blue, alpha );
+}
+
+static void APIENTRY logClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ fprintf( glw_state.log_fp, "glClearColor\n" );
+ dllClearColor( red, green, blue, alpha );
+}
+
+static void APIENTRY logClearDepth(GLclampd depth)
+{
+ fprintf( glw_state.log_fp, "glClearDepth\n" );
+ dllClearDepth( depth );
+}
+
+static void APIENTRY logClearIndex(GLfloat c)
+{
+ fprintf( glw_state.log_fp, "glClearIndex\n" );
+ dllClearIndex( c );
+}
+
+static void APIENTRY logClearStencil(GLint s)
+{
+ fprintf( glw_state.log_fp, "glClearStencil\n" );
+ dllClearStencil( s );
+}
+
+static void APIENTRY logClipPlane(GLenum plane, const GLdouble *equation)
+{
+ fprintf( glw_state.log_fp, "glClipPlane\n" );
+ dllClipPlane( plane, equation );
+}
+
+static void APIENTRY logColor3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+ fprintf( glw_state.log_fp, "glColor3b\n" );
+ dllColor3b( red, green, blue );
+}
+
+static void APIENTRY logColor3bv(const GLbyte *v)
+{
+ fprintf( glw_state.log_fp, "glColor3bv\n" );
+ dllColor3bv( v );
+}
+
+static void APIENTRY logColor3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+ fprintf( glw_state.log_fp, "glColor3d\n" );
+ dllColor3d( red, green, blue );
+}
+
+static void APIENTRY logColor3dv(const GLdouble *v)
+{
+ fprintf( glw_state.log_fp, "glColor3dv\n" );
+ dllColor3dv( v );
+}
+
+static void APIENTRY logColor3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+ fprintf( glw_state.log_fp, "glColor3f\n" );
+ dllColor3f( red, green, blue );
+}
+
+static void APIENTRY logColor3fv(const GLfloat *v)
+{
+ fprintf( glw_state.log_fp, "glColor3fv\n" );
+ dllColor3fv( v );
+}
+
+static void APIENTRY logColor3i(GLint red, GLint green, GLint blue)
+{
+ fprintf( glw_state.log_fp, "glColor3i\n" );
+ dllColor3i( red, green, blue );
+}
+
+static void APIENTRY logColor3iv(const GLint *v)
+{
+ fprintf( glw_state.log_fp, "glColor3iv\n" );
+ dllColor3iv( v );
+}
+
+static void APIENTRY logColor3s(GLshort red, GLshort green, GLshort blue)
+{
+ fprintf( glw_state.log_fp, "glColor3s\n" );
+ dllColor3s( red, green, blue );
+}
+
+static void APIENTRY logColor3sv(const GLshort *v)
+{
+ fprintf( glw_state.log_fp, "glColor3sv\n" );
+ dllColor3sv( v );
+}
+
+static void APIENTRY logColor3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+ fprintf( glw_state.log_fp, "glColor3ub\n" );
+ dllColor3ub( red, green, blue );
+}
+
+static void APIENTRY logColor3ubv(const GLubyte *v)
+{
+ fprintf( glw_state.log_fp, "glColor3ubv\n" );
+ dllColor3ubv( v );
+}
+
+#define SIG( x ) fprintf( glw_state.log_fp, x "\n" )
+
+static void APIENTRY logColor3ui(GLuint red, GLuint green, GLuint blue)
+{
+ SIG( "glColor3ui" );
+ dllColor3ui( red, green, blue );
+}
+
+static void APIENTRY logColor3uiv(const GLuint *v)
+{
+ SIG( "glColor3uiv" );
+ dllColor3uiv( v );
+}
+
+static void APIENTRY logColor3us(GLushort red, GLushort green, GLushort blue)
+{
+ SIG( "glColor3us" );
+ dllColor3us( red, green, blue );
+}
+
+static void APIENTRY logColor3usv(const GLushort *v)
+{
+ SIG( "glColor3usv" );
+ dllColor3usv( v );
+}
+
+static void APIENTRY logColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
+{
+ SIG( "glColor4b" );
+ dllColor4b( red, green, blue, alpha );
+}
+
+static void APIENTRY logColor4bv(const GLbyte *v)
+{
+ SIG( "glColor4bv" );
+ dllColor4bv( v );
+}
+
+static void APIENTRY logColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
+{
+ SIG( "glColor4d" );
+ dllColor4d( red, green, blue, alpha );
+}
+static void APIENTRY logColor4dv(const GLdouble *v)
+{
+ SIG( "glColor4dv" );
+ dllColor4dv( v );
+}
+static void APIENTRY logColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ fprintf( glw_state.log_fp, "glColor4f( %f,%f,%f,%f )\n", red, green, blue, alpha );
+ dllColor4f( red, green, blue, alpha );
+}
+static void APIENTRY logColor4fv(const GLfloat *v)
+{
+ fprintf( glw_state.log_fp, "glColor4fv( %f,%f,%f,%f )\n", v[0], v[1], v[2], v[3] );
+ dllColor4fv( v );
+}
+static void APIENTRY logColor4i(GLint red, GLint green, GLint blue, GLint alpha)
+{
+ SIG( "glColor4i" );
+ dllColor4i( red, green, blue, alpha );
+}
+static void APIENTRY logColor4iv(const GLint *v)
+{
+ SIG( "glColor4iv" );
+ dllColor4iv( v );
+}
+static void APIENTRY logColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
+{
+ SIG( "glColor4s" );
+ dllColor4s( red, green, blue, alpha );
+}
+static void APIENTRY logColor4sv(const GLshort *v)
+{
+ SIG( "glColor4sv" );
+ dllColor4sv( v );
+}
+static void APIENTRY logColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+ SIG( "glColor4b" );
+ dllColor4b( red, green, blue, alpha );
+}
+static void APIENTRY logColor4ubv(const GLubyte *v)
+{
+ SIG( "glColor4ubv" );
+ dllColor4ubv( v );
+}
+static void APIENTRY logColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+{
+ SIG( "glColor4ui" );
+ dllColor4ui( red, green, blue, alpha );
+}
+static void APIENTRY logColor4uiv(const GLuint *v)
+{
+ SIG( "glColor4uiv" );
+ dllColor4uiv( v );
+}
+static void APIENTRY logColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
+{
+ SIG( "glColor4us" );
+ dllColor4us( red, green, blue, alpha );
+}
+static void APIENTRY logColor4usv(const GLushort *v)
+{
+ SIG( "glColor4usv" );
+ dllColor4usv( v );
+}
+static void APIENTRY logColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ SIG( "glColorMask" );
+ dllColorMask( red, green, blue, alpha );
+}
+static void APIENTRY logColorMaterial(GLenum face, GLenum mode)
+{
+ SIG( "glColorMaterial" );
+ dllColorMaterial( face, mode );
+}
+
+static void APIENTRY logColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ SIG( "glColorPointer" );
+ dllColorPointer( size, type, stride, pointer );
+}
+
+static void APIENTRY logCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
+{
+ SIG( "glCopyPixels" );
+ dllCopyPixels( x, y, width, height, type );
+}
+
+static void APIENTRY logCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
+{
+ SIG( "glCopyTexImage1D" );
+ dllCopyTexImage1D( target, level, internalFormat, x, y, width, border );
+}
+
+static void APIENTRY logCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ SIG( "glCopyTexImage2D" );
+ dllCopyTexImage2D( target, level, internalFormat, x, y, width, height, border );
+}
+
+static void APIENTRY logCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+ SIG( "glCopyTexSubImage1D" );
+ dllCopyTexSubImage1D( target, level, xoffset, x, y, width );
+}
+
+static void APIENTRY logCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ SIG( "glCopyTexSubImage2D" );
+ dllCopyTexSubImage2D( target, level, xoffset, yoffset, x, y, width, height );
+}
+
+static void APIENTRY logCullFace(GLenum mode)
+{
+ SIG( "glCullFace" );
+ dllCullFace( mode );
+}
+
+static void APIENTRY logDeleteLists(GLuint list, GLsizei range)
+{
+ SIG( "glDeleteLists" );
+ dllDeleteLists( list, range );
+}
+
+static void APIENTRY logDeleteTextures(GLsizei n, const GLuint *textures)
+{
+ SIG( "glDeleteTextures" );
+ dllDeleteTextures( n, textures );
+}
+
+static void APIENTRY logDepthFunc(GLenum func)
+{
+ SIG( "glDepthFunc" );
+ dllDepthFunc( func );
+}
+
+static void APIENTRY logDepthMask(GLboolean flag)
+{
+ SIG( "glDepthMask" );
+ dllDepthMask( flag );
+}
+
+static void APIENTRY logDepthRange(GLclampd zNear, GLclampd zFar)
+{
+ SIG( "glDepthRange" );
+ dllDepthRange( zNear, zFar );
+}
+
+static void APIENTRY logDisable(GLenum cap)
+{
+ fprintf( glw_state.log_fp, "glDisable( 0x%x )\n", (unsigned int) cap );
+ dllDisable( cap );
+}
+
+static void APIENTRY logDisableClientState(GLenum array)
+{
+ SIG( "glDisableClientState" );
+ dllDisableClientState( array );
+}
+
+static void APIENTRY logDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ SIG( "glDrawArrays" );
+ dllDrawArrays( mode, first, count );
+}
+
+static void APIENTRY logDrawBuffer(GLenum mode)
+{
+ SIG( "glDrawBuffer" );
+ dllDrawBuffer( mode );
+}
+
+static void APIENTRY logDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+ SIG( "glDrawElements" );
+ dllDrawElements( mode, count, type, indices );
+}
+
+static void APIENTRY logDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+{
+ SIG( "glDrawPixels" );
+ dllDrawPixels( width, height, format, type, pixels );
+}
+
+static void APIENTRY logEdgeFlag(GLboolean flag)
+{
+ SIG( "glEdgeFlag" );
+ dllEdgeFlag( flag );
+}
+
+static void APIENTRY logEdgeFlagPointer(GLsizei stride, const void *pointer)
+{
+ SIG( "glEdgeFlagPointer" );
+ dllEdgeFlagPointer( stride, pointer );
+}
+
+static void APIENTRY logEdgeFlagv(const GLboolean *flag)
+{
+ SIG( "glEdgeFlagv" );
+ dllEdgeFlagv( flag );
+}
+
+static void APIENTRY logEnable(GLenum cap)
+{
+ fprintf( glw_state.log_fp, "glEnable( 0x%x )\n", (unsigned int) cap );
+ dllEnable( cap );
+}
+
+static void APIENTRY logEnableClientState(GLenum array)
+{
+ SIG( "glEnableClientState" );
+ dllEnableClientState( array );
+}
+
+static void APIENTRY logEnd(void)
+{
+ SIG( "glEnd" );
+ dllEnd();
+}
+
+static void APIENTRY logEndList(void)
+{
+ SIG( "glEndList" );
+ dllEndList();
+}
+
+static void APIENTRY logEvalCoord1d(GLdouble u)
+{
+ SIG( "glEvalCoord1d" );
+ dllEvalCoord1d( u );
+}
+
+static void APIENTRY logEvalCoord1dv(const GLdouble *u)
+{
+ SIG( "glEvalCoord1dv" );
+ dllEvalCoord1dv( u );
+}
+
+static void APIENTRY logEvalCoord1f(GLfloat u)
+{
+ SIG( "glEvalCoord1f" );
+ dllEvalCoord1f( u );
+}
+
+static void APIENTRY logEvalCoord1fv(const GLfloat *u)
+{
+ SIG( "glEvalCoord1fv" );
+ dllEvalCoord1fv( u );
+}
+static void APIENTRY logEvalCoord2d(GLdouble u, GLdouble v)
+{
+ SIG( "glEvalCoord2d" );
+ dllEvalCoord2d( u, v );
+}
+static void APIENTRY logEvalCoord2dv(const GLdouble *u)
+{
+ SIG( "glEvalCoord2dv" );
+ dllEvalCoord2dv( u );
+}
+static void APIENTRY logEvalCoord2f(GLfloat u, GLfloat v)
+{
+ SIG( "glEvalCoord2f" );
+ dllEvalCoord2f( u, v );
+}
+static void APIENTRY logEvalCoord2fv(const GLfloat *u)
+{
+ SIG( "glEvalCoord2fv" );
+ dllEvalCoord2fv( u );
+}
+
+static void APIENTRY logEvalMesh1(GLenum mode, GLint i1, GLint i2)
+{
+ SIG( "glEvalMesh1" );
+ dllEvalMesh1( mode, i1, i2 );
+}
+static void APIENTRY logEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
+{
+ SIG( "glEvalMesh2" );
+ dllEvalMesh2( mode, i1, i2, j1, j2 );
+}
+static void APIENTRY logEvalPoint1(GLint i)
+{
+ SIG( "glEvalPoint1" );
+ dllEvalPoint1( i );
+}
+static void APIENTRY logEvalPoint2(GLint i, GLint j)
+{
+ SIG( "glEvalPoint2" );
+ dllEvalPoint2( i, j );
+}
+
+static void APIENTRY logFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
+{
+ SIG( "glFeedbackBuffer" );
+ dllFeedbackBuffer( size, type, buffer );
+}
+
+static void APIENTRY logFinish(void)
+{
+ SIG( "glFinish" );
+ dllFinish();
+}
+
+static void APIENTRY logFlush(void)
+{
+ SIG( "glFlush" );
+ dllFlush();
+}
+
+static void APIENTRY logFogf(GLenum pname, GLfloat param)
+{
+ SIG( "glFogf" );
+ dllFogf( pname, param );
+}
+
+static void APIENTRY logFogfv(GLenum pname, const GLfloat *params)
+{
+ SIG( "glFogfv" );
+ dllFogfv( pname, params );
+}
+
+static void APIENTRY logFogi(GLenum pname, GLint param)
+{
+ SIG( "glFogi" );
+ dllFogi( pname, param );
+}
+
+static void APIENTRY logFogiv(GLenum pname, const GLint *params)
+{
+ SIG( "glFogiv" );
+ dllFogiv( pname, params );
+}
+
+static void APIENTRY logFrontFace(GLenum mode)
+{
+ SIG( "glFrontFace" );
+ dllFrontFace( mode );
+}
+
+static void APIENTRY logFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ SIG( "glFrustum" );
+ dllFrustum( left, right, bottom, top, zNear, zFar );
+}
+
+static GLuint APIENTRY logGenLists(GLsizei range)
+{
+ SIG( "glGenLists" );
+ return dllGenLists( range );
+}
+
+static void APIENTRY logGenTextures(GLsizei n, GLuint *textures)
+{
+ SIG( "glGenTextures" );
+ dllGenTextures( n, textures );
+}
+
+static void APIENTRY logGetBooleanv(GLenum pname, GLboolean *params)
+{
+ SIG( "glGetBooleanv" );
+ dllGetBooleanv( pname, params );
+}
+
+static void APIENTRY logGetClipPlane(GLenum plane, GLdouble *equation)
+{
+ SIG( "glGetClipPlane" );
+ dllGetClipPlane( plane, equation );
+}
+
+static void APIENTRY logGetDoublev(GLenum pname, GLdouble *params)
+{
+ SIG( "glGetDoublev" );
+ dllGetDoublev( pname, params );
+}
+
+static GLenum APIENTRY logGetError(void)
+{
+ SIG( "glGetError" );
+ return dllGetError();
+}
+
+static void APIENTRY logGetFloatv(GLenum pname, GLfloat *params)
+{
+ SIG( "glGetFloatv" );
+ dllGetFloatv( pname, params );
+}
+
+static void APIENTRY logGetIntegerv(GLenum pname, GLint *params)
+{
+ SIG( "glGetIntegerv" );
+ dllGetIntegerv( pname, params );
+}
+
+static void APIENTRY logGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+ SIG( "glGetLightfv" );
+ dllGetLightfv( light, pname, params );
+}
+
+static void APIENTRY logGetLightiv(GLenum light, GLenum pname, GLint *params)
+{
+ SIG( "glGetLightiv" );
+ dllGetLightiv( light, pname, params );
+}
+
+static void APIENTRY logGetMapdv(GLenum target, GLenum query, GLdouble *v)
+{
+ SIG( "glGetMapdv" );
+ dllGetMapdv( target, query, v );
+}
+
+static void APIENTRY logGetMapfv(GLenum target, GLenum query, GLfloat *v)
+{
+ SIG( "glGetMapfv" );
+ dllGetMapfv( target, query, v );
+}
+
+static void APIENTRY logGetMapiv(GLenum target, GLenum query, GLint *v)
+{
+ SIG( "glGetMapiv" );
+ dllGetMapiv( target, query, v );
+}
+
+static void APIENTRY logGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+ SIG( "glGetMaterialfv" );
+ dllGetMaterialfv( face, pname, params );
+}
+
+static void APIENTRY logGetMaterialiv(GLenum face, GLenum pname, GLint *params)
+{
+ SIG( "glGetMaterialiv" );
+ dllGetMaterialiv( face, pname, params );
+}
+
+static void APIENTRY logGetPixelMapfv(GLenum map, GLfloat *values)
+{
+ SIG( "glGetPixelMapfv" );
+ dllGetPixelMapfv( map, values );
+}
+
+static void APIENTRY logGetPixelMapuiv(GLenum map, GLuint *values)
+{
+ SIG( "glGetPixelMapuiv" );
+ dllGetPixelMapuiv( map, values );
+}
+
+static void APIENTRY logGetPixelMapusv(GLenum map, GLushort *values)
+{
+ SIG( "glGetPixelMapusv" );
+ dllGetPixelMapusv( map, values );
+}
+
+static void APIENTRY logGetPointerv(GLenum pname, GLvoid* *params)
+{
+ SIG( "glGetPointerv" );
+ dllGetPointerv( pname, params );
+}
+
+static void APIENTRY logGetPolygonStipple(GLubyte *mask)
+{
+ SIG( "glGetPolygonStipple" );
+ dllGetPolygonStipple( mask );
+}
+
+static const GLubyte * APIENTRY logGetString(GLenum name)
+{
+ SIG( "glGetString" );
+ return dllGetString( name );
+}
+
+static void APIENTRY logGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ SIG( "glGetTexEnvfv" );
+ dllGetTexEnvfv( target, pname, params );
+}
+
+static void APIENTRY logGetTexEnviv(GLenum target, GLenum pname, GLint *params)
+{
+ SIG( "glGetTexEnviv" );
+ dllGetTexEnviv( target, pname, params );
+}
+
+static void APIENTRY logGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
+{
+ SIG( "glGetTexGendv" );
+ dllGetTexGendv( coord, pname, params );
+}
+
+static void APIENTRY logGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+ SIG( "glGetTexGenfv" );
+ dllGetTexGenfv( coord, pname, params );
+}
+
+static void APIENTRY logGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+ SIG( "glGetTexGeniv" );
+ dllGetTexGeniv( coord, pname, params );
+}
+
+static void APIENTRY logGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels)
+{
+ SIG( "glGetTexImage" );
+ dllGetTexImage( target, level, format, type, pixels );
+}
+static void APIENTRY logGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params )
+{
+ SIG( "glGetTexLevelParameterfv" );
+ dllGetTexLevelParameterfv( target, level, pname, params );
+}
+
+static void APIENTRY logGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
+{
+ SIG( "glGetTexLevelParameteriv" );
+ dllGetTexLevelParameteriv( target, level, pname, params );
+}
+
+static void APIENTRY logGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ SIG( "glGetTexParameterfv" );
+ dllGetTexParameterfv( target, pname, params );
+}
+
+static void APIENTRY logGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ SIG( "glGetTexParameteriv" );
+ dllGetTexParameteriv( target, pname, params );
+}
+
+static void APIENTRY logHint(GLenum target, GLenum mode)
+{
+ fprintf( glw_state.log_fp, "glHint( 0x%x, 0x%x )\n", (unsigned int) target, (unsigned int) mode );
+ dllHint( target, mode );
+}
+
+static void APIENTRY logIndexMask(GLuint mask)
+{
+ SIG( "glIndexMask" );
+ dllIndexMask( mask );
+}
+
+static void APIENTRY logIndexPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ SIG( "glIndexPointer" );
+ dllIndexPointer( type, stride, pointer );
+}
+
+static void APIENTRY logIndexd(GLdouble c)
+{
+ SIG( "glIndexd" );
+ dllIndexd( c );
+}
+
+static void APIENTRY logIndexdv(const GLdouble *c)
+{
+ SIG( "glIndexdv" );
+ dllIndexdv( c );
+}
+
+static void APIENTRY logIndexf(GLfloat c)
+{
+ SIG( "glIndexf" );
+ dllIndexf( c );
+}
+
+static void APIENTRY logIndexfv(const GLfloat *c)
+{
+ SIG( "glIndexfv" );
+ dllIndexfv( c );
+}
+
+static void APIENTRY logIndexi(GLint c)
+{
+ SIG( "glIndexi" );
+ dllIndexi( c );
+}
+
+static void APIENTRY logIndexiv(const GLint *c)
+{
+ SIG( "glIndexiv" );
+ dllIndexiv( c );
+}
+
+static void APIENTRY logIndexs(GLshort c)
+{
+ SIG( "glIndexs" );
+ dllIndexs( c );
+}
+
+static void APIENTRY logIndexsv(const GLshort *c)
+{
+ SIG( "glIndexsv" );
+ dllIndexsv( c );
+}
+
+static void APIENTRY logIndexub(GLubyte c)
+{
+ SIG( "glIndexub" );
+ dllIndexub( c );
+}
+
+static void APIENTRY logIndexubv(const GLubyte *c)
+{
+ SIG( "glIndexubv" );
+ dllIndexubv( c );
+}
+
+static void APIENTRY logInitNames(void)
+{
+ SIG( "glInitNames" );
+ dllInitNames();
+}
+
+static void APIENTRY logInterleavedArrays(GLenum format, GLsizei stride, const void *pointer)
+{
+ SIG( "glInterleavedArrays" );
+ dllInterleavedArrays( format, stride, pointer );
+}
+
+static GLboolean APIENTRY logIsEnabled(GLenum cap)
+{
+ SIG( "glIsEnabled" );
+ return dllIsEnabled( cap );
+}
+static GLboolean APIENTRY logIsList(GLuint list)
+{
+ SIG( "glIsList" );
+ return dllIsList( list );
+}
+static GLboolean APIENTRY logIsTexture(GLuint texture)
+{
+ SIG( "glIsTexture" );
+ return dllIsTexture( texture );
+}
+
+static void APIENTRY logLightModelf(GLenum pname, GLfloat param)
+{
+ SIG( "glLightModelf" );
+ dllLightModelf( pname, param );
+}
+
+static void APIENTRY logLightModelfv(GLenum pname, const GLfloat *params)
+{
+ SIG( "glLightModelfv" );
+ dllLightModelfv( pname, params );
+}
+
+static void APIENTRY logLightModeli(GLenum pname, GLint param)
+{
+ SIG( "glLightModeli" );
+ dllLightModeli( pname, param );
+
+}
+
+static void APIENTRY logLightModeliv(GLenum pname, const GLint *params)
+{
+ SIG( "glLightModeliv" );
+ dllLightModeliv( pname, params );
+}
+
+static void APIENTRY logLightf(GLenum light, GLenum pname, GLfloat param)
+{
+ SIG( "glLightf" );
+ dllLightf( light, pname, param );
+}
+
+static void APIENTRY logLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+ SIG( "glLightfv" );
+ dllLightfv( light, pname, params );
+}
+
+static void APIENTRY logLighti(GLenum light, GLenum pname, GLint param)
+{
+ SIG( "glLighti" );
+ dllLighti( light, pname, param );
+}
+
+static void APIENTRY logLightiv(GLenum light, GLenum pname, const GLint *params)
+{
+ SIG( "glLightiv" );
+ dllLightiv( light, pname, params );
+}
+
+static void APIENTRY logLineStipple(GLint factor, GLushort pattern)
+{
+ SIG( "glLineStipple" );
+ dllLineStipple( factor, pattern );
+}
+
+static void APIENTRY logLineWidth(GLfloat width)
+{
+ SIG( "glLineWidth" );
+ dllLineWidth( width );
+}
+
+static void APIENTRY logListBase(GLuint base)
+{
+ SIG( "glListBase" );
+ dllListBase( base );
+}
+
+static void APIENTRY logLoadIdentity(void)
+{
+ SIG( "glLoadIdentity" );
+ dllLoadIdentity();
+}
+
+static void APIENTRY logLoadMatrixd(const GLdouble *m)
+{
+ SIG( "glLoadMatrixd" );
+ dllLoadMatrixd( m );
+}
+
+static void APIENTRY logLoadMatrixf(const GLfloat *m)
+{
+ SIG( "glLoadMatrixf" );
+ dllLoadMatrixf( m );
+}
+
+static void APIENTRY logLoadName(GLuint name)
+{
+ SIG( "glLoadName" );
+ dllLoadName( name );
+}
+
+static void APIENTRY logLogicOp(GLenum opcode)
+{
+ SIG( "glLogicOp" );
+ dllLogicOp( opcode );
+}
+
+static void APIENTRY logMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
+{
+ SIG( "glMap1d" );
+ dllMap1d( target, u1, u2, stride, order, points );
+}
+
+static void APIENTRY logMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
+{
+ SIG( "glMap1f" );
+ dllMap1f( target, u1, u2, stride, order, points );
+}
+
+static void APIENTRY logMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
+{
+ SIG( "glMap2d" );
+ dllMap2d( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points );
+}
+
+static void APIENTRY logMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
+{
+ SIG( "glMap2f" );
+ dllMap2f( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points );
+}
+
+static void APIENTRY logMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
+{
+ SIG( "glMapGrid1d" );
+ dllMapGrid1d( un, u1, u2 );
+}
+
+static void APIENTRY logMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
+{
+ SIG( "glMapGrid1f" );
+ dllMapGrid1f( un, u1, u2 );
+}
+
+static void APIENTRY logMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
+{
+ SIG( "glMapGrid2d" );
+ dllMapGrid2d( un, u1, u2, vn, v1, v2 );
+}
+static void APIENTRY logMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
+{
+ SIG( "glMapGrid2f" );
+ dllMapGrid2f( un, u1, u2, vn, v1, v2 );
+}
+static void APIENTRY logMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+ SIG( "glMaterialf" );
+ dllMaterialf( face, pname, param );
+}
+static void APIENTRY logMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ SIG( "glMaterialfv" );
+ dllMaterialfv( face, pname, params );
+}
+
+static void APIENTRY logMateriali(GLenum face, GLenum pname, GLint param)
+{
+ SIG( "glMateriali" );
+ dllMateriali( face, pname, param );
+}
+
+static void APIENTRY logMaterialiv(GLenum face, GLenum pname, const GLint *params)
+{
+ SIG( "glMaterialiv" );
+ dllMaterialiv( face, pname, params );
+}
+
+static void APIENTRY logMatrixMode(GLenum mode)
+{
+ SIG( "glMatrixMode" );
+ dllMatrixMode( mode );
+}
+
+static void APIENTRY logMultMatrixd(const GLdouble *m)
+{
+ SIG( "glMultMatrixd" );
+ dllMultMatrixd( m );
+}
+
+static void APIENTRY logMultMatrixf(const GLfloat *m)
+{
+ SIG( "glMultMatrixf" );
+ dllMultMatrixf( m );
+}
+
+static void APIENTRY logNewList(GLuint list, GLenum mode)
+{
+ SIG( "glNewList" );
+ dllNewList( list, mode );
+}
+
+static void APIENTRY logNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
+{
+ SIG ("glNormal3b" );
+ dllNormal3b( nx, ny, nz );
+}
+
+static void APIENTRY logNormal3bv(const GLbyte *v)
+{
+ SIG( "glNormal3bv" );
+ dllNormal3bv( v );
+}
+
+static void APIENTRY logNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
+{
+ SIG( "glNormal3d" );
+ dllNormal3d( nx, ny, nz );
+}
+
+static void APIENTRY logNormal3dv(const GLdouble *v)
+{
+ SIG( "glNormal3dv" );
+ dllNormal3dv( v );
+}
+
+static void APIENTRY logNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+ SIG( "glNormal3f" );
+ dllNormal3f( nx, ny, nz );
+}
+
+static void APIENTRY logNormal3fv(const GLfloat *v)
+{
+ SIG( "glNormal3fv" );
+ dllNormal3fv( v );
+}
+static void APIENTRY logNormal3i(GLint nx, GLint ny, GLint nz)
+{
+ SIG( "glNormal3i" );
+ dllNormal3i( nx, ny, nz );
+}
+static void APIENTRY logNormal3iv(const GLint *v)
+{
+ SIG( "glNormal3iv" );
+ dllNormal3iv( v );
+}
+static void APIENTRY logNormal3s(GLshort nx, GLshort ny, GLshort nz)
+{
+ SIG( "glNormal3s" );
+ dllNormal3s( nx, ny, nz );
+}
+static void APIENTRY logNormal3sv(const GLshort *v)
+{
+ SIG( "glNormal3sv" );
+ dllNormal3sv( v );
+}
+static void APIENTRY logNormalPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ SIG( "glNormalPointer" );
+ dllNormalPointer( type, stride, pointer );
+}
+static void APIENTRY logOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ SIG( "glOrtho" );
+ dllOrtho( left, right, bottom, top, zNear, zFar );
+}
+
+static void APIENTRY logPassThrough(GLfloat token)
+{
+ SIG( "glPassThrough" );
+ dllPassThrough( token );
+}
+
+static void APIENTRY logPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
+{
+ SIG( "glPixelMapfv" );
+ dllPixelMapfv( map, mapsize, values );
+}
+
+static void APIENTRY logPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
+{
+ SIG( "glPixelMapuiv" );
+ dllPixelMapuiv( map, mapsize, values );
+}
+
+static void APIENTRY logPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
+{
+ SIG( "glPixelMapusv" );
+ dllPixelMapusv( map, mapsize, values );
+}
+static void APIENTRY logPixelStoref(GLenum pname, GLfloat param)
+{
+ SIG( "glPixelStoref" );
+ dllPixelStoref( pname, param );
+}
+static void APIENTRY logPixelStorei(GLenum pname, GLint param)
+{
+ SIG( "glPixelStorei" );
+ dllPixelStorei( pname, param );
+}
+static void APIENTRY logPixelTransferf(GLenum pname, GLfloat param)
+{
+ SIG( "glPixelTransferf" );
+ dllPixelTransferf( pname, param );
+}
+
+static void APIENTRY logPixelTransferi(GLenum pname, GLint param)
+{
+ SIG( "glPixelTransferi" );
+ dllPixelTransferi( pname, param );
+}
+
+static void APIENTRY logPixelZoom(GLfloat xfactor, GLfloat yfactor)
+{
+ SIG( "glPixelZoom" );
+ dllPixelZoom( xfactor, yfactor );
+}
+
+static void APIENTRY logPointSize(GLfloat size)
+{
+ SIG( "glPointSize" );
+ dllPointSize( size );
+}
+
+static void APIENTRY logPolygonMode(GLenum face, GLenum mode)
+{
+ fprintf( glw_state.log_fp, "glPolygonMode( 0x%x, 0x%x )\n", (unsigned int) face, (unsigned int) mode );
+ dllPolygonMode( face, mode );
+}
+
+static void APIENTRY logPolygonOffset(GLfloat factor, GLfloat units)
+{
+ SIG( "glPolygonOffset" );
+ dllPolygonOffset( factor, units );
+}
+static void APIENTRY logPolygonStipple(const GLubyte *mask )
+{
+ SIG( "glPolygonStipple" );
+ dllPolygonStipple( mask );
+}
+static void APIENTRY logPopAttrib(void)
+{
+ SIG( "glPopAttrib" );
+ dllPopAttrib();
+}
+
+static void APIENTRY logPopClientAttrib(void)
+{
+ SIG( "glPopClientAttrib" );
+ dllPopClientAttrib();
+}
+
+static void APIENTRY logPopMatrix(void)
+{
+ SIG( "glPopMatrix" );
+ dllPopMatrix();
+}
+
+static void APIENTRY logPopName(void)
+{
+ SIG( "glPopName" );
+ dllPopName();
+}
+
+static void APIENTRY logPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
+{
+ SIG( "glPrioritizeTextures" );
+ dllPrioritizeTextures( n, textures, priorities );
+}
+
+static void APIENTRY logPushAttrib(GLbitfield mask)
+{
+ SIG( "glPushAttrib" );
+ dllPushAttrib( mask );
+}
+
+static void APIENTRY logPushClientAttrib(GLbitfield mask)
+{
+ SIG( "glPushClientAttrib" );
+ dllPushClientAttrib( mask );
+}
+
+static void APIENTRY logPushMatrix(void)
+{
+ SIG( "glPushMatrix" );
+ dllPushMatrix();
+}
+
+static void APIENTRY logPushName(GLuint name)
+{
+ SIG( "glPushName" );
+ dllPushName( name );
+}
+
+static void APIENTRY logRasterPos2d(GLdouble x, GLdouble y)
+{
+ SIG ("glRasterPot2d" );
+ dllRasterPos2d( x, y );
+}
+
+static void APIENTRY logRasterPos2dv(const GLdouble *v)
+{
+ SIG( "glRasterPos2dv" );
+ dllRasterPos2dv( v );
+}
+
+static void APIENTRY logRasterPos2f(GLfloat x, GLfloat y)
+{
+ SIG( "glRasterPos2f" );
+ dllRasterPos2f( x, y );
+}
+static void APIENTRY logRasterPos2fv(const GLfloat *v)
+{
+ SIG( "glRasterPos2dv" );
+ dllRasterPos2fv( v );
+}
+static void APIENTRY logRasterPos2i(GLint x, GLint y)
+{
+ SIG( "glRasterPos2if" );
+ dllRasterPos2i( x, y );
+}
+static void APIENTRY logRasterPos2iv(const GLint *v)
+{
+ SIG( "glRasterPos2iv" );
+ dllRasterPos2iv( v );
+}
+static void APIENTRY logRasterPos2s(GLshort x, GLshort y)
+{
+ SIG( "glRasterPos2s" );
+ dllRasterPos2s( x, y );
+}
+static void APIENTRY logRasterPos2sv(const GLshort *v)
+{
+ SIG( "glRasterPos2sv" );
+ dllRasterPos2sv( v );
+}
+static void APIENTRY logRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ SIG( "glRasterPos3d" );
+ dllRasterPos3d( x, y, z );
+}
+static void APIENTRY logRasterPos3dv(const GLdouble *v)
+{
+ SIG( "glRasterPos3dv" );
+ dllRasterPos3dv( v );
+}
+static void APIENTRY logRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ SIG( "glRasterPos3f" );
+ dllRasterPos3f( x, y, z );
+}
+static void APIENTRY logRasterPos3fv(const GLfloat *v)
+{
+ SIG( "glRasterPos3fv" );
+ dllRasterPos3fv( v );
+}
+static void APIENTRY logRasterPos3i(GLint x, GLint y, GLint z)
+{
+ SIG( "glRasterPos3i" );
+ dllRasterPos3i( x, y, z );
+}
+static void APIENTRY logRasterPos3iv(const GLint *v)
+{
+ SIG( "glRasterPos3iv" );
+ dllRasterPos3iv( v );
+}
+static void APIENTRY logRasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+ SIG( "glRasterPos3s" );
+ dllRasterPos3s( x, y, z );
+}
+static void APIENTRY logRasterPos3sv(const GLshort *v)
+{
+ SIG( "glRasterPos3sv" );
+ dllRasterPos3sv( v );
+}
+static void APIENTRY logRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ SIG( "glRasterPos4d" );
+ dllRasterPos4d( x, y, z, w );
+}
+static void APIENTRY logRasterPos4dv(const GLdouble *v)
+{
+ SIG( "glRasterPos4dv" );
+ dllRasterPos4dv( v );
+}
+static void APIENTRY logRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ SIG( "glRasterPos4f" );
+ dllRasterPos4f( x, y, z, w );
+}
+static void APIENTRY logRasterPos4fv(const GLfloat *v)
+{
+ SIG( "glRasterPos4fv" );
+ dllRasterPos4fv( v );
+}
+static void APIENTRY logRasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+ SIG( "glRasterPos4i" );
+ dllRasterPos4i( x, y, z, w );
+}
+static void APIENTRY logRasterPos4iv(const GLint *v)
+{
+ SIG( "glRasterPos4iv" );
+ dllRasterPos4iv( v );
+}
+static void APIENTRY logRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ SIG( "glRasterPos4s" );
+ dllRasterPos4s( x, y, z, w );
+}
+static void APIENTRY logRasterPos4sv(const GLshort *v)
+{
+ SIG( "glRasterPos4sv" );
+ dllRasterPos4sv( v );
+}
+static void APIENTRY logReadBuffer(GLenum mode)
+{
+ SIG( "glReadBuffer" );
+ dllReadBuffer( mode );
+}
+static void APIENTRY logReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels)
+{
+ SIG( "glReadPixels" );
+ dllReadPixels( x, y, width, height, format, type, pixels );
+}
+
+static void APIENTRY logRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
+{
+ SIG( "glRectd" );
+ dllRectd( x1, y1, x2, y2 );
+}
+
+static void APIENTRY logRectdv(const GLdouble *v1, const GLdouble *v2)
+{
+ SIG( "glRectdv" );
+ dllRectdv( v1, v2 );
+}
+
+static void APIENTRY logRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ SIG( "glRectf" );
+ dllRectf( x1, y1, x2, y2 );
+}
+
+static void APIENTRY logRectfv(const GLfloat *v1, const GLfloat *v2)
+{
+ SIG( "glRectfv" );
+ dllRectfv( v1, v2 );
+}
+static void APIENTRY logRecti(GLint x1, GLint y1, GLint x2, GLint y2)
+{
+ SIG( "glRecti" );
+ dllRecti( x1, y1, x2, y2 );
+}
+static void APIENTRY logRectiv(const GLint *v1, const GLint *v2)
+{
+ SIG( "glRectiv" );
+ dllRectiv( v1, v2 );
+}
+static void APIENTRY logRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
+{
+ SIG( "glRects" );
+ dllRects( x1, y1, x2, y2 );
+}
+static void APIENTRY logRectsv(const GLshort *v1, const GLshort *v2)
+{
+ SIG( "glRectsv" );
+ dllRectsv( v1, v2 );
+}
+static GLint APIENTRY logRenderMode(GLenum mode)
+{
+ SIG( "glRenderMode" );
+ return dllRenderMode( mode );
+}
+static void APIENTRY logRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ SIG( "glRotated" );
+ dllRotated( angle, x, y, z );
+}
+
+static void APIENTRY logRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ SIG( "glRotatef" );
+ dllRotatef( angle, x, y, z );
+}
+
+static void APIENTRY logScaled(GLdouble x, GLdouble y, GLdouble z)
+{
+ SIG( "glScaled" );
+ dllScaled( x, y, z );
+}
+
+static void APIENTRY logScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ SIG( "glScalef" );
+ dllScalef( x, y, z );
+}
+
+static void APIENTRY logScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ SIG( "glScissor" );
+ dllScissor( x, y, width, height );
+}
+
+static void APIENTRY logSelectBuffer(GLsizei size, GLuint *buffer)
+{
+ SIG( "glSelectBuffer" );
+ dllSelectBuffer( size, buffer );
+}
+
+static void APIENTRY logShadeModel(GLenum mode)
+{
+ SIG( "glShadeModel" );
+ dllShadeModel( mode );
+}
+
+static void APIENTRY logStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ SIG( "glStencilFunc" );
+ dllStencilFunc( func, ref, mask );
+}
+
+static void APIENTRY logStencilMask(GLuint mask)
+{
+ SIG( "glStencilMask" );
+ dllStencilMask( mask );
+}
+
+static void APIENTRY logStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ SIG( "glStencilOp" );
+ dllStencilOp( fail, zfail, zpass );
+}
+
+static void APIENTRY logTexCoord1d(GLdouble s)
+{
+ SIG( "glTexCoord1d" );
+ dllTexCoord1d( s );
+}
+
+static void APIENTRY logTexCoord1dv(const GLdouble *v)
+{
+ SIG( "glTexCoord1dv" );
+ dllTexCoord1dv( v );
+}
+
+static void APIENTRY logTexCoord1f(GLfloat s)
+{
+ SIG( "glTexCoord1f" );
+ dllTexCoord1f( s );
+}
+static void APIENTRY logTexCoord1fv(const GLfloat *v)
+{
+ SIG( "glTexCoord1fv" );
+ dllTexCoord1fv( v );
+}
+static void APIENTRY logTexCoord1i(GLint s)
+{
+ SIG( "glTexCoord1i" );
+ dllTexCoord1i( s );
+}
+static void APIENTRY logTexCoord1iv(const GLint *v)
+{
+ SIG( "glTexCoord1iv" );
+ dllTexCoord1iv( v );
+}
+static void APIENTRY logTexCoord1s(GLshort s)
+{
+ SIG( "glTexCoord1s" );
+ dllTexCoord1s( s );
+}
+static void APIENTRY logTexCoord1sv(const GLshort *v)
+{
+ SIG( "glTexCoord1sv" );
+ dllTexCoord1sv( v );
+}
+static void APIENTRY logTexCoord2d(GLdouble s, GLdouble t)
+{
+ SIG( "glTexCoord2d" );
+ dllTexCoord2d( s, t );
+}
+
+static void APIENTRY logTexCoord2dv(const GLdouble *v)
+{
+ SIG( "glTexCoord2dv" );
+ dllTexCoord2dv( v );
+}
+static void APIENTRY logTexCoord2f(GLfloat s, GLfloat t)
+{
+ SIG( "glTexCoord2f" );
+ dllTexCoord2f( s, t );
+}
+static void APIENTRY logTexCoord2fv(const GLfloat *v)
+{
+ SIG( "glTexCoord2fv" );
+ dllTexCoord2fv( v );
+}
+static void APIENTRY logTexCoord2i(GLint s, GLint t)
+{
+ SIG( "glTexCoord2i" );
+ dllTexCoord2i( s, t );
+}
+static void APIENTRY logTexCoord2iv(const GLint *v)
+{
+ SIG( "glTexCoord2iv" );
+ dllTexCoord2iv( v );
+}
+static void APIENTRY logTexCoord2s(GLshort s, GLshort t)
+{
+ SIG( "glTexCoord2s" );
+ dllTexCoord2s( s, t );
+}
+static void APIENTRY logTexCoord2sv(const GLshort *v)
+{
+ SIG( "glTexCoord2sv" );
+ dllTexCoord2sv( v );
+}
+static void APIENTRY logTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
+{
+ SIG( "glTexCoord3d" );
+ dllTexCoord3d( s, t, r );
+}
+static void APIENTRY logTexCoord3dv(const GLdouble *v)
+{
+ SIG( "glTexCoord3dv" );
+ dllTexCoord3dv( v );
+}
+static void APIENTRY logTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
+{
+ SIG( "glTexCoord3f" );
+ dllTexCoord3f( s, t, r );
+}
+static void APIENTRY logTexCoord3fv(const GLfloat *v)
+{
+ SIG( "glTexCoord3fv" );
+ dllTexCoord3fv( v );
+}
+static void APIENTRY logTexCoord3i(GLint s, GLint t, GLint r)
+{
+ SIG( "glTexCoord3i" );
+ dllTexCoord3i( s, t, r );
+}
+static void APIENTRY logTexCoord3iv(const GLint *v)
+{
+ SIG( "glTexCoord3iv" );
+ dllTexCoord3iv( v );
+}
+static void APIENTRY logTexCoord3s(GLshort s, GLshort t, GLshort r)
+{
+ SIG( "glTexCoord3s" );
+ dllTexCoord3s( s, t, r );
+}
+static void APIENTRY logTexCoord3sv(const GLshort *v)
+{
+ SIG( "glTexCoord3sv" );
+ dllTexCoord3sv( v );
+}
+static void APIENTRY logTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ SIG( "glTexCoord4d" );
+ dllTexCoord4d( s, t, r, q );
+}
+static void APIENTRY logTexCoord4dv(const GLdouble *v)
+{
+ SIG( "glTexCoord4dv" );
+ dllTexCoord4dv( v );
+}
+static void APIENTRY logTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ SIG( "glTexCoord4f" );
+ dllTexCoord4f( s, t, r, q );
+}
+static void APIENTRY logTexCoord4fv(const GLfloat *v)
+{
+ SIG( "glTexCoord4fv" );
+ dllTexCoord4fv( v );
+}
+static void APIENTRY logTexCoord4i(GLint s, GLint t, GLint r, GLint q)
+{
+ SIG( "glTexCoord4i" );
+ dllTexCoord4i( s, t, r, q );
+}
+static void APIENTRY logTexCoord4iv(const GLint *v)
+{
+ SIG( "glTexCoord4iv" );
+ dllTexCoord4iv( v );
+}
+static void APIENTRY logTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ SIG( "glTexCoord4s" );
+ dllTexCoord4s( s, t, r, q );
+}
+static void APIENTRY logTexCoord4sv(const GLshort *v)
+{
+ SIG( "glTexCoord4sv" );
+ dllTexCoord4sv( v );
+}
+static void APIENTRY logTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ SIG( "glTexCoordPointer" );
+ dllTexCoordPointer( size, type, stride, pointer );
+}
+
+static void APIENTRY logTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ fprintf( glw_state.log_fp, "glTexEnvf( 0x%x, 0x%x, %f )\n", (unsigned int) target, (unsigned int) pname, param );
+ dllTexEnvf( target, pname, param );
+}
+
+static void APIENTRY logTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ SIG( "glTexEnvfv" );
+ dllTexEnvfv( target, pname, params );
+}
+
+static void APIENTRY logTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ fprintf( glw_state.log_fp, "glTexEnvi( 0x%x, 0x%x, 0x%x )\n", (unsigned int) target, (unsigned int) pname, (unsigned int) param );
+ dllTexEnvi( target, pname, param );
+}
+static void APIENTRY logTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+ SIG( "glTexEnviv" );
+ dllTexEnviv( target, pname, params );
+}
+
+static void APIENTRY logTexGend(GLenum coord, GLenum pname, GLdouble param)
+{
+ SIG( "glTexGend" );
+ dllTexGend( coord, pname, param );
+}
+
+static void APIENTRY logTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
+{
+ SIG( "glTexGendv" );
+ dllTexGendv( coord, pname, params );
+}
+
+static void APIENTRY logTexGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+ SIG( "glTexGenf" );
+ dllTexGenf( coord, pname, param );
+}
+static void APIENTRY logTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ SIG( "glTexGenfv" );
+ dllTexGenfv( coord, pname, params );
+}
+static void APIENTRY logTexGeni(GLenum coord, GLenum pname, GLint param)
+{
+ SIG( "glTexGeni" );
+ dllTexGeni( coord, pname, param );
+}
+static void APIENTRY logTexGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+ SIG( "glTexGeniv" );
+ dllTexGeniv( coord, pname, params );
+}
+static void APIENTRY logTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels)
+{
+ SIG( "glTexImage1D" );
+ dllTexImage1D( target, level, internalformat, width, border, format, type, pixels );
+}
+static void APIENTRY logTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
+{
+ SIG( "glTexImage2D" );
+ dllTexImage2D( target, level, internalformat, width, height, border, format, type, pixels );
+}
+
+static void APIENTRY logTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ fprintf( glw_state.log_fp, "glTexParameterf( 0x%x, 0x%x, %f )\n", (unsigned int) target, (unsigned int) pname, param );
+ dllTexParameterf( target, pname, param );
+}
+
+static void APIENTRY logTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ SIG( "glTexParameterfv" );
+ dllTexParameterfv( target, pname, params );
+}
+static void APIENTRY logTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ fprintf( glw_state.log_fp, "glTexParameteri( 0x%x, 0x%x, 0x%x )\n", (unsigned int) target, (unsigned int) pname, (unsigned int) param );
+ dllTexParameteri( target, pname, param );
+}
+static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ SIG( "glTexParameteriv" );
+ dllTexParameteriv( target, pname, params );
+}
+static void APIENTRY logTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels)
+{
+ SIG( "glTexSubImage1D" );
+ dllTexSubImage1D( target, level, xoffset, width, format, type, pixels );
+}
+static void APIENTRY logTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+{
+ SIG( "glTexSubImage2D" );
+ dllTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels );
+}
+static void APIENTRY logTranslated(GLdouble x, GLdouble y, GLdouble z)
+{
+ SIG( "glTranslated" );
+ dllTranslated( x, y, z );
+}
+
+static void APIENTRY logTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ SIG( "glTranslatef" );
+ dllTranslatef( x, y, z );
+}
+
+static void APIENTRY logVertex2d(GLdouble x, GLdouble y)
+{
+ SIG( "glVertex2d" );
+ dllVertex2d( x, y );
+}
+
+static void APIENTRY logVertex2dv(const GLdouble *v)
+{
+ SIG( "glVertex2dv" );
+ dllVertex2dv( v );
+}
+static void APIENTRY logVertex2f(GLfloat x, GLfloat y)
+{
+ SIG( "glVertex2f" );
+ dllVertex2f( x, y );
+}
+static void APIENTRY logVertex2fv(const GLfloat *v)
+{
+ SIG( "glVertex2fv" );
+ dllVertex2fv( v );
+}
+static void APIENTRY logVertex2i(GLint x, GLint y)
+{
+ SIG( "glVertex2i" );
+ dllVertex2i( x, y );
+}
+static void APIENTRY logVertex2iv(const GLint *v)
+{
+ SIG( "glVertex2iv" );
+ dllVertex2iv( v );
+}
+static void APIENTRY logVertex2s(GLshort x, GLshort y)
+{
+ SIG( "glVertex2s" );
+ dllVertex2s( x, y );
+}
+static void APIENTRY logVertex2sv(const GLshort *v)
+{
+ SIG( "glVertex2sv" );
+ dllVertex2sv( v );
+}
+static void APIENTRY logVertex3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ SIG( "glVertex3d" );
+ dllVertex3d( x, y, z );
+}
+static void APIENTRY logVertex3dv(const GLdouble *v)
+{
+ SIG( "glVertex3dv" );
+ dllVertex3dv( v );
+}
+static void APIENTRY logVertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ SIG( "glVertex3f" );
+ dllVertex3f( x, y, z );
+}
+static void APIENTRY logVertex3fv(const GLfloat *v)
+{
+ SIG( "glVertex3fv" );
+ dllVertex3fv( v );
+}
+static void APIENTRY logVertex3i(GLint x, GLint y, GLint z)
+{
+ SIG( "glVertex3i" );
+ dllVertex3i( x, y, z );
+}
+static void APIENTRY logVertex3iv(const GLint *v)
+{
+ SIG( "glVertex3iv" );
+ dllVertex3iv( v );
+}
+static void APIENTRY logVertex3s(GLshort x, GLshort y, GLshort z)
+{
+ SIG( "glVertex3s" );
+ dllVertex3s( x, y, z );
+}
+static void APIENTRY logVertex3sv(const GLshort *v)
+{
+ SIG( "glVertex3sv" );
+ dllVertex3sv( v );
+}
+static void APIENTRY logVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ SIG( "glVertex4d" );
+ dllVertex4d( x, y, z, w );
+}
+static void APIENTRY logVertex4dv(const GLdouble *v)
+{
+ SIG( "glVertex4dv" );
+ dllVertex4dv( v );
+}
+static void APIENTRY logVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ SIG( "glVertex4f" );
+ dllVertex4f( x, y, z, w );
+}
+static void APIENTRY logVertex4fv(const GLfloat *v)
+{
+ SIG( "glVertex4fv" );
+ dllVertex4fv( v );
+}
+static void APIENTRY logVertex4i(GLint x, GLint y, GLint z, GLint w)
+{
+ SIG( "glVertex4i" );
+ dllVertex4i( x, y, z, w );
+}
+static void APIENTRY logVertex4iv(const GLint *v)
+{
+ SIG( "glVertex4iv" );
+ dllVertex4iv( v );
+}
+static void APIENTRY logVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ SIG( "glVertex4s" );
+ dllVertex4s( x, y, z, w );
+}
+static void APIENTRY logVertex4sv(const GLshort *v)
+{
+ SIG( "glVertex4sv" );
+ dllVertex4sv( v );
+}
+static void APIENTRY logVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ SIG( "glVertexPointer" );
+ dllVertexPointer( size, type, stride, pointer );
+}
+static void APIENTRY logViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ SIG( "glViewport" );
+ dllViewport( x, y, width, height );
+}
+
+/*
+** QGL_Shutdown
+**
+** Unloads the specified DLL then nulls out all the proc pointers.
+*/
+void QGL_Shutdown( void )
+{
+ if ( glw_state.OpenGLLib )
+ {
+ // 25/09/05 Tim Angus <tim@ngus.net>
+ // Certain combinations of hardware and software, specifically
+ // Linux/SMP/Nvidia/agpgart (OK, OK. MY combination of hardware and
+ // software), seem to cause a catastrophic (hard reboot required) crash
+ // when libGL is dynamically unloaded. I'm unsure of the precise cause,
+ // suffice to say I don't see anything in the Q3 code that could cause it.
+ // I suspect it's an Nvidia driver bug, but without the source or means to
+ // debug I obviously can't prove (or disprove) this. Interestingly (though
+ // perhaps not suprisingly), Enemy Territory and Doom 3 both exhibit the
+ // same problem.
+ //
+ // After many, many reboots and prodding here and there, it seems that a
+ // placing a short delay before libGL is unloaded works around the problem.
+ // This delay is changable via the r_GLlibCoolDownMsec cvar (nice name
+ // huh?), and it defaults to 0. For me, 500 seems to work.
+ if( r_GLlibCoolDownMsec->integer )
+ usleep( r_GLlibCoolDownMsec->integer * 1000 );
+
+ #if USE_SDL_VIDEO
+ SDL_QuitSubSystem(SDL_INIT_VIDEO);
+ #else
+ dlclose ( glw_state.OpenGLLib );
+ #endif
+ glw_state.OpenGLLib = NULL;
+ }
+
+ qglAccum = NULL;
+ qglAlphaFunc = NULL;
+ qglAreTexturesResident = NULL;
+ qglArrayElement = NULL;
+ qglBegin = NULL;
+ qglBindTexture = NULL;
+ qglBitmap = NULL;
+ qglBlendFunc = NULL;
+ qglCallList = NULL;
+ qglCallLists = NULL;
+ qglClear = NULL;
+ qglClearAccum = NULL;
+ qglClearColor = NULL;
+ qglClearDepth = NULL;
+ qglClearIndex = NULL;
+ qglClearStencil = NULL;
+ qglClipPlane = NULL;
+ qglColor3b = NULL;
+ qglColor3bv = NULL;
+ qglColor3d = NULL;
+ qglColor3dv = NULL;
+ qglColor3f = NULL;
+ qglColor3fv = NULL;
+ qglColor3i = NULL;
+ qglColor3iv = NULL;
+ qglColor3s = NULL;
+ qglColor3sv = NULL;
+ qglColor3ub = NULL;
+ qglColor3ubv = NULL;
+ qglColor3ui = NULL;
+ qglColor3uiv = NULL;
+ qglColor3us = NULL;
+ qglColor3usv = NULL;
+ qglColor4b = NULL;
+ qglColor4bv = NULL;
+ qglColor4d = NULL;
+ qglColor4dv = NULL;
+ qglColor4f = NULL;
+ qglColor4fv = NULL;
+ qglColor4i = NULL;
+ qglColor4iv = NULL;
+ qglColor4s = NULL;
+ qglColor4sv = NULL;
+ qglColor4ub = NULL;
+ qglColor4ubv = NULL;
+ qglColor4ui = NULL;
+ qglColor4uiv = NULL;
+ qglColor4us = NULL;
+ qglColor4usv = NULL;
+ qglColorMask = NULL;
+ qglColorMaterial = NULL;
+ qglColorPointer = NULL;
+ qglCopyPixels = NULL;
+ qglCopyTexImage1D = NULL;
+ qglCopyTexImage2D = NULL;
+ qglCopyTexSubImage1D = NULL;
+ qglCopyTexSubImage2D = NULL;
+ qglCullFace = NULL;
+ qglDeleteLists = NULL;
+ qglDeleteTextures = NULL;
+ qglDepthFunc = NULL;
+ qglDepthMask = NULL;
+ qglDepthRange = NULL;
+ qglDisable = NULL;
+ qglDisableClientState = NULL;
+ qglDrawArrays = NULL;
+ qglDrawBuffer = NULL;
+ qglDrawElements = NULL;
+ qglDrawPixels = NULL;
+ qglEdgeFlag = NULL;
+ qglEdgeFlagPointer = NULL;
+ qglEdgeFlagv = NULL;
+ qglEnable = NULL;
+ qglEnableClientState = NULL;
+ qglEnd = NULL;
+ qglEndList = NULL;
+ qglEvalCoord1d = NULL;
+ qglEvalCoord1dv = NULL;
+ qglEvalCoord1f = NULL;
+ qglEvalCoord1fv = NULL;
+ qglEvalCoord2d = NULL;
+ qglEvalCoord2dv = NULL;
+ qglEvalCoord2f = NULL;
+ qglEvalCoord2fv = NULL;
+ qglEvalMesh1 = NULL;
+ qglEvalMesh2 = NULL;
+ qglEvalPoint1 = NULL;
+ qglEvalPoint2 = NULL;
+ qglFeedbackBuffer = NULL;
+ qglFinish = NULL;
+ qglFlush = NULL;
+ qglFogf = NULL;
+ qglFogfv = NULL;
+ qglFogi = NULL;
+ qglFogiv = NULL;
+ qglFrontFace = NULL;
+ qglFrustum = NULL;
+ qglGenLists = NULL;
+ qglGenTextures = NULL;
+ qglGetBooleanv = NULL;
+ qglGetClipPlane = NULL;
+ qglGetDoublev = NULL;
+ qglGetError = NULL;
+ qglGetFloatv = NULL;
+ qglGetIntegerv = NULL;
+ qglGetLightfv = NULL;
+ qglGetLightiv = NULL;
+ qglGetMapdv = NULL;
+ qglGetMapfv = NULL;
+ qglGetMapiv = NULL;
+ qglGetMaterialfv = NULL;
+ qglGetMaterialiv = NULL;
+ qglGetPixelMapfv = NULL;
+ qglGetPixelMapuiv = NULL;
+ qglGetPixelMapusv = NULL;
+ qglGetPointerv = NULL;
+ qglGetPolygonStipple = NULL;
+ qglGetString = NULL;
+ qglGetTexEnvfv = NULL;
+ qglGetTexEnviv = NULL;
+ qglGetTexGendv = NULL;
+ qglGetTexGenfv = NULL;
+ qglGetTexGeniv = NULL;
+ qglGetTexImage = NULL;
+ qglGetTexLevelParameterfv = NULL;
+ qglGetTexLevelParameteriv = NULL;
+ qglGetTexParameterfv = NULL;
+ qglGetTexParameteriv = NULL;
+ qglHint = NULL;
+ qglIndexMask = NULL;
+ qglIndexPointer = NULL;
+ qglIndexd = NULL;
+ qglIndexdv = NULL;
+ qglIndexf = NULL;
+ qglIndexfv = NULL;
+ qglIndexi = NULL;
+ qglIndexiv = NULL;
+ qglIndexs = NULL;
+ qglIndexsv = NULL;
+ qglIndexub = NULL;
+ qglIndexubv = NULL;
+ qglInitNames = NULL;
+ qglInterleavedArrays = NULL;
+ qglIsEnabled = NULL;
+ qglIsList = NULL;
+ qglIsTexture = NULL;
+ qglLightModelf = NULL;
+ qglLightModelfv = NULL;
+ qglLightModeli = NULL;
+ qglLightModeliv = NULL;
+ qglLightf = NULL;
+ qglLightfv = NULL;
+ qglLighti = NULL;
+ qglLightiv = NULL;
+ qglLineStipple = NULL;
+ qglLineWidth = NULL;
+ qglListBase = NULL;
+ qglLoadIdentity = NULL;
+ qglLoadMatrixd = NULL;
+ qglLoadMatrixf = NULL;
+ qglLoadName = NULL;
+ qglLogicOp = NULL;
+ qglMap1d = NULL;
+ qglMap1f = NULL;
+ qglMap2d = NULL;
+ qglMap2f = NULL;
+ qglMapGrid1d = NULL;
+ qglMapGrid1f = NULL;
+ qglMapGrid2d = NULL;
+ qglMapGrid2f = NULL;
+ qglMaterialf = NULL;
+ qglMaterialfv = NULL;
+ qglMateriali = NULL;
+ qglMaterialiv = NULL;
+ qglMatrixMode = NULL;
+ qglMultMatrixd = NULL;
+ qglMultMatrixf = NULL;
+ qglNewList = NULL;
+ qglNormal3b = NULL;
+ qglNormal3bv = NULL;
+ qglNormal3d = NULL;
+ qglNormal3dv = NULL;
+ qglNormal3f = NULL;
+ qglNormal3fv = NULL;
+ qglNormal3i = NULL;
+ qglNormal3iv = NULL;
+ qglNormal3s = NULL;
+ qglNormal3sv = NULL;
+ qglNormalPointer = NULL;
+ qglOrtho = NULL;
+ qglPassThrough = NULL;
+ qglPixelMapfv = NULL;
+ qglPixelMapuiv = NULL;
+ qglPixelMapusv = NULL;
+ qglPixelStoref = NULL;
+ qglPixelStorei = NULL;
+ qglPixelTransferf = NULL;
+ qglPixelTransferi = NULL;
+ qglPixelZoom = NULL;
+ qglPointSize = NULL;
+ qglPolygonMode = NULL;
+ qglPolygonOffset = NULL;
+ qglPolygonStipple = NULL;
+ qglPopAttrib = NULL;
+ qglPopClientAttrib = NULL;
+ qglPopMatrix = NULL;
+ qglPopName = NULL;
+ qglPrioritizeTextures = NULL;
+ qglPushAttrib = NULL;
+ qglPushClientAttrib = NULL;
+ qglPushMatrix = NULL;
+ qglPushName = NULL;
+ qglRasterPos2d = NULL;
+ qglRasterPos2dv = NULL;
+ qglRasterPos2f = NULL;
+ qglRasterPos2fv = NULL;
+ qglRasterPos2i = NULL;
+ qglRasterPos2iv = NULL;
+ qglRasterPos2s = NULL;
+ qglRasterPos2sv = NULL;
+ qglRasterPos3d = NULL;
+ qglRasterPos3dv = NULL;
+ qglRasterPos3f = NULL;
+ qglRasterPos3fv = NULL;
+ qglRasterPos3i = NULL;
+ qglRasterPos3iv = NULL;
+ qglRasterPos3s = NULL;
+ qglRasterPos3sv = NULL;
+ qglRasterPos4d = NULL;
+ qglRasterPos4dv = NULL;
+ qglRasterPos4f = NULL;
+ qglRasterPos4fv = NULL;
+ qglRasterPos4i = NULL;
+ qglRasterPos4iv = NULL;
+ qglRasterPos4s = NULL;
+ qglRasterPos4sv = NULL;
+ qglReadBuffer = NULL;
+ qglReadPixels = NULL;
+ qglRectd = NULL;
+ qglRectdv = NULL;
+ qglRectf = NULL;
+ qglRectfv = NULL;
+ qglRecti = NULL;
+ qglRectiv = NULL;
+ qglRects = NULL;
+ qglRectsv = NULL;
+ qglRenderMode = NULL;
+ qglRotated = NULL;
+ qglRotatef = NULL;
+ qglScaled = NULL;
+ qglScalef = NULL;
+ qglScissor = NULL;
+ qglSelectBuffer = NULL;
+ qglShadeModel = NULL;
+ qglStencilFunc = NULL;
+ qglStencilMask = NULL;
+ qglStencilOp = NULL;
+ qglTexCoord1d = NULL;
+ qglTexCoord1dv = NULL;
+ qglTexCoord1f = NULL;
+ qglTexCoord1fv = NULL;
+ qglTexCoord1i = NULL;
+ qglTexCoord1iv = NULL;
+ qglTexCoord1s = NULL;
+ qglTexCoord1sv = NULL;
+ qglTexCoord2d = NULL;
+ qglTexCoord2dv = NULL;
+ qglTexCoord2f = NULL;
+ qglTexCoord2fv = NULL;
+ qglTexCoord2i = NULL;
+ qglTexCoord2iv = NULL;
+ qglTexCoord2s = NULL;
+ qglTexCoord2sv = NULL;
+ qglTexCoord3d = NULL;
+ qglTexCoord3dv = NULL;
+ qglTexCoord3f = NULL;
+ qglTexCoord3fv = NULL;
+ qglTexCoord3i = NULL;
+ qglTexCoord3iv = NULL;
+ qglTexCoord3s = NULL;
+ qglTexCoord3sv = NULL;
+ qglTexCoord4d = NULL;
+ qglTexCoord4dv = NULL;
+ qglTexCoord4f = NULL;
+ qglTexCoord4fv = NULL;
+ qglTexCoord4i = NULL;
+ qglTexCoord4iv = NULL;
+ qglTexCoord4s = NULL;
+ qglTexCoord4sv = NULL;
+ qglTexCoordPointer = NULL;
+ qglTexEnvf = NULL;
+ qglTexEnvfv = NULL;
+ qglTexEnvi = NULL;
+ qglTexEnviv = NULL;
+ qglTexGend = NULL;
+ qglTexGendv = NULL;
+ qglTexGenf = NULL;
+ qglTexGenfv = NULL;
+ qglTexGeni = NULL;
+ qglTexGeniv = NULL;
+ qglTexImage1D = NULL;
+ qglTexImage2D = NULL;
+ qglTexParameterf = NULL;
+ qglTexParameterfv = NULL;
+ qglTexParameteri = NULL;
+ qglTexParameteriv = NULL;
+ qglTexSubImage1D = NULL;
+ qglTexSubImage2D = NULL;
+ qglTranslated = NULL;
+ qglTranslatef = NULL;
+ qglVertex2d = NULL;
+ qglVertex2dv = NULL;
+ qglVertex2f = NULL;
+ qglVertex2fv = NULL;
+ qglVertex2i = NULL;
+ qglVertex2iv = NULL;
+ qglVertex2s = NULL;
+ qglVertex2sv = NULL;
+ qglVertex3d = NULL;
+ qglVertex3dv = NULL;
+ qglVertex3f = NULL;
+ qglVertex3fv = NULL;
+ qglVertex3i = NULL;
+ qglVertex3iv = NULL;
+ qglVertex3s = NULL;
+ qglVertex3sv = NULL;
+ qglVertex4d = NULL;
+ qglVertex4dv = NULL;
+ qglVertex4f = NULL;
+ qglVertex4fv = NULL;
+ qglVertex4i = NULL;
+ qglVertex4iv = NULL;
+ qglVertex4s = NULL;
+ qglVertex4sv = NULL;
+ qglVertexPointer = NULL;
+ qglViewport = NULL;
+
+// bk001129 - from cvs1.17 (mkv)
+#if defined(__FX__)
+ qfxMesaCreateContext = NULL;
+ qfxMesaCreateBestContext = NULL;
+ qfxMesaDestroyContext = NULL;
+ qfxMesaMakeCurrent = NULL;
+ qfxMesaGetCurrentContext = NULL;
+ qfxMesaSwapBuffers = NULL;
+#endif
+
+#if !defined(USE_SDL_VIDEO)
+ qglXChooseVisual = NULL;
+ qglXCreateContext = NULL;
+ qglXDestroyContext = NULL;
+ qglXMakeCurrent = NULL;
+ qglXCopyContext = NULL;
+ qglXSwapBuffers = NULL;
+#endif
+}
+
+#if USE_SDL_VIDEO
+#define GPA( a ) SDL_GL_GetProcAddress( a )
+qboolean GLimp_sdl_init_video(void);
+#else
+#define GPA( a ) dlsym( glw_state.OpenGLLib, a )
+#endif
+
+void *qwglGetProcAddress(char *symbol)
+{
+ if (glw_state.OpenGLLib)
+ return GPA ( symbol );
+ return NULL;
+}
+
+char *do_dlerror(void);
+
+/*
+** QGL_Init
+**
+** This is responsible for binding our qgl function pointers to
+** the appropriate GL stuff. In Windows this means doing a
+** LoadLibrary and a bunch of calls to GetProcAddress. On other
+** operating systems we need to do the right thing, whatever that
+** might be.
+**
+*/
+
+qboolean QGL_Init( const char *dllname )
+{
+ if (glw_state.OpenGLLib == 0)
+ {
+ #if USE_SDL_VIDEO
+ if (GLimp_sdl_init_video() == qfalse)
+ return qfalse;
+ glw_state.OpenGLLib = (void*)(long)((SDL_GL_LoadLibrary(dllname) == -1) ? 0 : 1);
+ #else
+ glw_state.OpenGLLib = dlopen( dllname, RTLD_LAZY|RTLD_GLOBAL );
+ #endif
+ }
+
+ if (glw_state.OpenGLLib == 0)
+ {
+ char fn[1024];
+ // FILE *fp; // bk001204 - unused
+
+ // if we are not setuid, try current directory
+ if (dllname != NULL) {
+ getcwd(fn, sizeof(fn));
+ Q_strcat(fn, sizeof(fn), "/");
+ Q_strcat(fn, sizeof(fn), dllname);
+
+ #if USE_SDL_VIDEO
+ glw_state.OpenGLLib = (void*)(long)((SDL_GL_LoadLibrary(fn) == -1) ? 0 : 1);
+ #else
+ glw_state.OpenGLLib = dlopen( fn, RTLD_LAZY );
+ #endif
+ if ( glw_state.OpenGLLib == 0 ) {
+ ri.Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf or current dir: %s\n", dllname, do_dlerror());
+ return qfalse;
+ }
+ } else {
+ ri.Printf(PRINT_ALL, "QGL_Init: Can't load %s from /etc/ld.so.conf: %s\n", dllname, do_dlerror());
+ return qfalse;
+ }
+ }
+
+ qglAccum = dllAccum = GPA( "glAccum" );
+ qglAlphaFunc = dllAlphaFunc = GPA( "glAlphaFunc" );
+ qglAreTexturesResident = dllAreTexturesResident = GPA( "glAreTexturesResident" );
+ qglArrayElement = dllArrayElement = GPA( "glArrayElement" );
+ qglBegin = dllBegin = GPA( "glBegin" );
+ qglBindTexture = dllBindTexture = GPA( "glBindTexture" );
+ qglBitmap = dllBitmap = GPA( "glBitmap" );
+ qglBlendFunc = dllBlendFunc = GPA( "glBlendFunc" );
+ qglCallList = dllCallList = GPA( "glCallList" );
+ qglCallLists = dllCallLists = GPA( "glCallLists" );
+ qglClear = dllClear = GPA( "glClear" );
+ qglClearAccum = dllClearAccum = GPA( "glClearAccum" );
+ qglClearColor = dllClearColor = GPA( "glClearColor" );
+ qglClearDepth = dllClearDepth = GPA( "glClearDepth" );
+ qglClearIndex = dllClearIndex = GPA( "glClearIndex" );
+ qglClearStencil = dllClearStencil = GPA( "glClearStencil" );
+ qglClipPlane = dllClipPlane = GPA( "glClipPlane" );
+ qglColor3b = dllColor3b = GPA( "glColor3b" );
+ qglColor3bv = dllColor3bv = GPA( "glColor3bv" );
+ qglColor3d = dllColor3d = GPA( "glColor3d" );
+ qglColor3dv = dllColor3dv = GPA( "glColor3dv" );
+ qglColor3f = dllColor3f = GPA( "glColor3f" );
+ qglColor3fv = dllColor3fv = GPA( "glColor3fv" );
+ qglColor3i = dllColor3i = GPA( "glColor3i" );
+ qglColor3iv = dllColor3iv = GPA( "glColor3iv" );
+ qglColor3s = dllColor3s = GPA( "glColor3s" );
+ qglColor3sv = dllColor3sv = GPA( "glColor3sv" );
+ qglColor3ub = dllColor3ub = GPA( "glColor3ub" );
+ qglColor3ubv = dllColor3ubv = GPA( "glColor3ubv" );
+ qglColor3ui = dllColor3ui = GPA( "glColor3ui" );
+ qglColor3uiv = dllColor3uiv = GPA( "glColor3uiv" );
+ qglColor3us = dllColor3us = GPA( "glColor3us" );
+ qglColor3usv = dllColor3usv = GPA( "glColor3usv" );
+ qglColor4b = dllColor4b = GPA( "glColor4b" );
+ qglColor4bv = dllColor4bv = GPA( "glColor4bv" );
+ qglColor4d = dllColor4d = GPA( "glColor4d" );
+ qglColor4dv = dllColor4dv = GPA( "glColor4dv" );
+ qglColor4f = dllColor4f = GPA( "glColor4f" );
+ qglColor4fv = dllColor4fv = GPA( "glColor4fv" );
+ qglColor4i = dllColor4i = GPA( "glColor4i" );
+ qglColor4iv = dllColor4iv = GPA( "glColor4iv" );
+ qglColor4s = dllColor4s = GPA( "glColor4s" );
+ qglColor4sv = dllColor4sv = GPA( "glColor4sv" );
+ qglColor4ub = dllColor4ub = GPA( "glColor4ub" );
+ qglColor4ubv = dllColor4ubv = GPA( "glColor4ubv" );
+ qglColor4ui = dllColor4ui = GPA( "glColor4ui" );
+ qglColor4uiv = dllColor4uiv = GPA( "glColor4uiv" );
+ qglColor4us = dllColor4us = GPA( "glColor4us" );
+ qglColor4usv = dllColor4usv = GPA( "glColor4usv" );
+ qglColorMask = dllColorMask = GPA( "glColorMask" );
+ qglColorMaterial = dllColorMaterial = GPA( "glColorMaterial" );
+ qglColorPointer = dllColorPointer = GPA( "glColorPointer" );
+ qglCopyPixels = dllCopyPixels = GPA( "glCopyPixels" );
+ qglCopyTexImage1D = dllCopyTexImage1D = GPA( "glCopyTexImage1D" );
+ qglCopyTexImage2D = dllCopyTexImage2D = GPA( "glCopyTexImage2D" );
+ qglCopyTexSubImage1D = dllCopyTexSubImage1D = GPA( "glCopyTexSubImage1D" );
+ qglCopyTexSubImage2D = dllCopyTexSubImage2D = GPA( "glCopyTexSubImage2D" );
+ qglCullFace = dllCullFace = GPA( "glCullFace" );
+ qglDeleteLists = dllDeleteLists = GPA( "glDeleteLists" );
+ qglDeleteTextures = dllDeleteTextures = GPA( "glDeleteTextures" );
+ qglDepthFunc = dllDepthFunc = GPA( "glDepthFunc" );
+ qglDepthMask = dllDepthMask = GPA( "glDepthMask" );
+ qglDepthRange = dllDepthRange = GPA( "glDepthRange" );
+ qglDisable = dllDisable = GPA( "glDisable" );
+ qglDisableClientState = dllDisableClientState = GPA( "glDisableClientState" );
+ qglDrawArrays = dllDrawArrays = GPA( "glDrawArrays" );
+ qglDrawBuffer = dllDrawBuffer = GPA( "glDrawBuffer" );
+ qglDrawElements = dllDrawElements = GPA( "glDrawElements" );
+ qglDrawPixels = dllDrawPixels = GPA( "glDrawPixels" );
+ qglEdgeFlag = dllEdgeFlag = GPA( "glEdgeFlag" );
+ qglEdgeFlagPointer = dllEdgeFlagPointer = GPA( "glEdgeFlagPointer" );
+ qglEdgeFlagv = dllEdgeFlagv = GPA( "glEdgeFlagv" );
+ qglEnable = dllEnable = GPA( "glEnable" );
+ qglEnableClientState = dllEnableClientState = GPA( "glEnableClientState" );
+ qglEnd = dllEnd = GPA( "glEnd" );
+ qglEndList = dllEndList = GPA( "glEndList" );
+ qglEvalCoord1d = dllEvalCoord1d = GPA( "glEvalCoord1d" );
+ qglEvalCoord1dv = dllEvalCoord1dv = GPA( "glEvalCoord1dv" );
+ qglEvalCoord1f = dllEvalCoord1f = GPA( "glEvalCoord1f" );
+ qglEvalCoord1fv = dllEvalCoord1fv = GPA( "glEvalCoord1fv" );
+ qglEvalCoord2d = dllEvalCoord2d = GPA( "glEvalCoord2d" );
+ qglEvalCoord2dv = dllEvalCoord2dv = GPA( "glEvalCoord2dv" );
+ qglEvalCoord2f = dllEvalCoord2f = GPA( "glEvalCoord2f" );
+ qglEvalCoord2fv = dllEvalCoord2fv = GPA( "glEvalCoord2fv" );
+ qglEvalMesh1 = dllEvalMesh1 = GPA( "glEvalMesh1" );
+ qglEvalMesh2 = dllEvalMesh2 = GPA( "glEvalMesh2" );
+ qglEvalPoint1 = dllEvalPoint1 = GPA( "glEvalPoint1" );
+ qglEvalPoint2 = dllEvalPoint2 = GPA( "glEvalPoint2" );
+ qglFeedbackBuffer = dllFeedbackBuffer = GPA( "glFeedbackBuffer" );
+ qglFinish = dllFinish = GPA( "glFinish" );
+ qglFlush = dllFlush = GPA( "glFlush" );
+ qglFogf = dllFogf = GPA( "glFogf" );
+ qglFogfv = dllFogfv = GPA( "glFogfv" );
+ qglFogi = dllFogi = GPA( "glFogi" );
+ qglFogiv = dllFogiv = GPA( "glFogiv" );
+ qglFrontFace = dllFrontFace = GPA( "glFrontFace" );
+ qglFrustum = dllFrustum = GPA( "glFrustum" );
+ qglGenLists = dllGenLists = GPA( "glGenLists" );
+ qglGenTextures = dllGenTextures = GPA( "glGenTextures" );
+ qglGetBooleanv = dllGetBooleanv = GPA( "glGetBooleanv" );
+ qglGetClipPlane = dllGetClipPlane = GPA( "glGetClipPlane" );
+ qglGetDoublev = dllGetDoublev = GPA( "glGetDoublev" );
+ qglGetError = dllGetError = GPA( "glGetError" );
+ qglGetFloatv = dllGetFloatv = GPA( "glGetFloatv" );
+ qglGetIntegerv = dllGetIntegerv = GPA( "glGetIntegerv" );
+ qglGetLightfv = dllGetLightfv = GPA( "glGetLightfv" );
+ qglGetLightiv = dllGetLightiv = GPA( "glGetLightiv" );
+ qglGetMapdv = dllGetMapdv = GPA( "glGetMapdv" );
+ qglGetMapfv = dllGetMapfv = GPA( "glGetMapfv" );
+ qglGetMapiv = dllGetMapiv = GPA( "glGetMapiv" );
+ qglGetMaterialfv = dllGetMaterialfv = GPA( "glGetMaterialfv" );
+ qglGetMaterialiv = dllGetMaterialiv = GPA( "glGetMaterialiv" );
+ qglGetPixelMapfv = dllGetPixelMapfv = GPA( "glGetPixelMapfv" );
+ qglGetPixelMapuiv = dllGetPixelMapuiv = GPA( "glGetPixelMapuiv" );
+ qglGetPixelMapusv = dllGetPixelMapusv = GPA( "glGetPixelMapusv" );
+ qglGetPointerv = dllGetPointerv = GPA( "glGetPointerv" );
+ qglGetPolygonStipple = dllGetPolygonStipple = GPA( "glGetPolygonStipple" );
+ qglGetString = dllGetString = GPA( "glGetString" );
+ qglGetTexEnvfv = dllGetTexEnvfv = GPA( "glGetTexEnvfv" );
+ qglGetTexEnviv = dllGetTexEnviv = GPA( "glGetTexEnviv" );
+ qglGetTexGendv = dllGetTexGendv = GPA( "glGetTexGendv" );
+ qglGetTexGenfv = dllGetTexGenfv = GPA( "glGetTexGenfv" );
+ qglGetTexGeniv = dllGetTexGeniv = GPA( "glGetTexGeniv" );
+ qglGetTexImage = dllGetTexImage = GPA( "glGetTexImage" );
+ qglGetTexParameterfv = dllGetTexParameterfv = GPA( "glGetTexParameterfv" );
+ qglGetTexParameteriv = dllGetTexParameteriv = GPA( "glGetTexParameteriv" );
+ qglHint = dllHint = GPA( "glHint" );
+ qglIndexMask = dllIndexMask = GPA( "glIndexMask" );
+ qglIndexPointer = dllIndexPointer = GPA( "glIndexPointer" );
+ qglIndexd = dllIndexd = GPA( "glIndexd" );
+ qglIndexdv = dllIndexdv = GPA( "glIndexdv" );
+ qglIndexf = dllIndexf = GPA( "glIndexf" );
+ qglIndexfv = dllIndexfv = GPA( "glIndexfv" );
+ qglIndexi = dllIndexi = GPA( "glIndexi" );
+ qglIndexiv = dllIndexiv = GPA( "glIndexiv" );
+ qglIndexs = dllIndexs = GPA( "glIndexs" );
+ qglIndexsv = dllIndexsv = GPA( "glIndexsv" );
+ qglIndexub = dllIndexub = GPA( "glIndexub" );
+ qglIndexubv = dllIndexubv = GPA( "glIndexubv" );
+ qglInitNames = dllInitNames = GPA( "glInitNames" );
+ qglInterleavedArrays = dllInterleavedArrays = GPA( "glInterleavedArrays" );
+ qglIsEnabled = dllIsEnabled = GPA( "glIsEnabled" );
+ qglIsList = dllIsList = GPA( "glIsList" );
+ qglIsTexture = dllIsTexture = GPA( "glIsTexture" );
+ qglLightModelf = dllLightModelf = GPA( "glLightModelf" );
+ qglLightModelfv = dllLightModelfv = GPA( "glLightModelfv" );
+ qglLightModeli = dllLightModeli = GPA( "glLightModeli" );
+ qglLightModeliv = dllLightModeliv = GPA( "glLightModeliv" );
+ qglLightf = dllLightf = GPA( "glLightf" );
+ qglLightfv = dllLightfv = GPA( "glLightfv" );
+ qglLighti = dllLighti = GPA( "glLighti" );
+ qglLightiv = dllLightiv = GPA( "glLightiv" );
+ qglLineStipple = dllLineStipple = GPA( "glLineStipple" );
+ qglLineWidth = dllLineWidth = GPA( "glLineWidth" );
+ qglListBase = dllListBase = GPA( "glListBase" );
+ qglLoadIdentity = dllLoadIdentity = GPA( "glLoadIdentity" );
+ qglLoadMatrixd = dllLoadMatrixd = GPA( "glLoadMatrixd" );
+ qglLoadMatrixf = dllLoadMatrixf = GPA( "glLoadMatrixf" );
+ qglLoadName = dllLoadName = GPA( "glLoadName" );
+ qglLogicOp = dllLogicOp = GPA( "glLogicOp" );
+ qglMap1d = dllMap1d = GPA( "glMap1d" );
+ qglMap1f = dllMap1f = GPA( "glMap1f" );
+ qglMap2d = dllMap2d = GPA( "glMap2d" );
+ qglMap2f = dllMap2f = GPA( "glMap2f" );
+ qglMapGrid1d = dllMapGrid1d = GPA( "glMapGrid1d" );
+ qglMapGrid1f = dllMapGrid1f = GPA( "glMapGrid1f" );
+ qglMapGrid2d = dllMapGrid2d = GPA( "glMapGrid2d" );
+ qglMapGrid2f = dllMapGrid2f = GPA( "glMapGrid2f" );
+ qglMaterialf = dllMaterialf = GPA( "glMaterialf" );
+ qglMaterialfv = dllMaterialfv = GPA( "glMaterialfv" );
+ qglMateriali = dllMateriali = GPA( "glMateriali" );
+ qglMaterialiv = dllMaterialiv = GPA( "glMaterialiv" );
+ qglMatrixMode = dllMatrixMode = GPA( "glMatrixMode" );
+ qglMultMatrixd = dllMultMatrixd = GPA( "glMultMatrixd" );
+ qglMultMatrixf = dllMultMatrixf = GPA( "glMultMatrixf" );
+ qglNewList = dllNewList = GPA( "glNewList" );
+ qglNormal3b = dllNormal3b = GPA( "glNormal3b" );
+ qglNormal3bv = dllNormal3bv = GPA( "glNormal3bv" );
+ qglNormal3d = dllNormal3d = GPA( "glNormal3d" );
+ qglNormal3dv = dllNormal3dv = GPA( "glNormal3dv" );
+ qglNormal3f = dllNormal3f = GPA( "glNormal3f" );
+ qglNormal3fv = dllNormal3fv = GPA( "glNormal3fv" );
+ qglNormal3i = dllNormal3i = GPA( "glNormal3i" );
+ qglNormal3iv = dllNormal3iv = GPA( "glNormal3iv" );
+ qglNormal3s = dllNormal3s = GPA( "glNormal3s" );
+ qglNormal3sv = dllNormal3sv = GPA( "glNormal3sv" );
+ qglNormalPointer = dllNormalPointer = GPA( "glNormalPointer" );
+ qglOrtho = dllOrtho = GPA( "glOrtho" );
+ qglPassThrough = dllPassThrough = GPA( "glPassThrough" );
+ qglPixelMapfv = dllPixelMapfv = GPA( "glPixelMapfv" );
+ qglPixelMapuiv = dllPixelMapuiv = GPA( "glPixelMapuiv" );
+ qglPixelMapusv = dllPixelMapusv = GPA( "glPixelMapusv" );
+ qglPixelStoref = dllPixelStoref = GPA( "glPixelStoref" );
+ qglPixelStorei = dllPixelStorei = GPA( "glPixelStorei" );
+ qglPixelTransferf = dllPixelTransferf = GPA( "glPixelTransferf" );
+ qglPixelTransferi = dllPixelTransferi = GPA( "glPixelTransferi" );
+ qglPixelZoom = dllPixelZoom = GPA( "glPixelZoom" );
+ qglPointSize = dllPointSize = GPA( "glPointSize" );
+ qglPolygonMode = dllPolygonMode = GPA( "glPolygonMode" );
+ qglPolygonOffset = dllPolygonOffset = GPA( "glPolygonOffset" );
+ qglPolygonStipple = dllPolygonStipple = GPA( "glPolygonStipple" );
+ qglPopAttrib = dllPopAttrib = GPA( "glPopAttrib" );
+ qglPopClientAttrib = dllPopClientAttrib = GPA( "glPopClientAttrib" );
+ qglPopMatrix = dllPopMatrix = GPA( "glPopMatrix" );
+ qglPopName = dllPopName = GPA( "glPopName" );
+ qglPrioritizeTextures = dllPrioritizeTextures = GPA( "glPrioritizeTextures" );
+ qglPushAttrib = dllPushAttrib = GPA( "glPushAttrib" );
+ qglPushClientAttrib = dllPushClientAttrib = GPA( "glPushClientAttrib" );
+ qglPushMatrix = dllPushMatrix = GPA( "glPushMatrix" );
+ qglPushName = dllPushName = GPA( "glPushName" );
+ qglRasterPos2d = dllRasterPos2d = GPA( "glRasterPos2d" );
+ qglRasterPos2dv = dllRasterPos2dv = GPA( "glRasterPos2dv" );
+ qglRasterPos2f = dllRasterPos2f = GPA( "glRasterPos2f" );
+ qglRasterPos2fv = dllRasterPos2fv = GPA( "glRasterPos2fv" );
+ qglRasterPos2i = dllRasterPos2i = GPA( "glRasterPos2i" );
+ qglRasterPos2iv = dllRasterPos2iv = GPA( "glRasterPos2iv" );
+ qglRasterPos2s = dllRasterPos2s = GPA( "glRasterPos2s" );
+ qglRasterPos2sv = dllRasterPos2sv = GPA( "glRasterPos2sv" );
+ qglRasterPos3d = dllRasterPos3d = GPA( "glRasterPos3d" );
+ qglRasterPos3dv = dllRasterPos3dv = GPA( "glRasterPos3dv" );
+ qglRasterPos3f = dllRasterPos3f = GPA( "glRasterPos3f" );
+ qglRasterPos3fv = dllRasterPos3fv = GPA( "glRasterPos3fv" );
+ qglRasterPos3i = dllRasterPos3i = GPA( "glRasterPos3i" );
+ qglRasterPos3iv = dllRasterPos3iv = GPA( "glRasterPos3iv" );
+ qglRasterPos3s = dllRasterPos3s = GPA( "glRasterPos3s" );
+ qglRasterPos3sv = dllRasterPos3sv = GPA( "glRasterPos3sv" );
+ qglRasterPos4d = dllRasterPos4d = GPA( "glRasterPos4d" );
+ qglRasterPos4dv = dllRasterPos4dv = GPA( "glRasterPos4dv" );
+ qglRasterPos4f = dllRasterPos4f = GPA( "glRasterPos4f" );
+ qglRasterPos4fv = dllRasterPos4fv = GPA( "glRasterPos4fv" );
+ qglRasterPos4i = dllRasterPos4i = GPA( "glRasterPos4i" );
+ qglRasterPos4iv = dllRasterPos4iv = GPA( "glRasterPos4iv" );
+ qglRasterPos4s = dllRasterPos4s = GPA( "glRasterPos4s" );
+ qglRasterPos4sv = dllRasterPos4sv = GPA( "glRasterPos4sv" );
+ qglReadBuffer = dllReadBuffer = GPA( "glReadBuffer" );
+ qglReadPixels = dllReadPixels = GPA( "glReadPixels" );
+ qglRectd = dllRectd = GPA( "glRectd" );
+ qglRectdv = dllRectdv = GPA( "glRectdv" );
+ qglRectf = dllRectf = GPA( "glRectf" );
+ qglRectfv = dllRectfv = GPA( "glRectfv" );
+ qglRecti = dllRecti = GPA( "glRecti" );
+ qglRectiv = dllRectiv = GPA( "glRectiv" );
+ qglRects = dllRects = GPA( "glRects" );
+ qglRectsv = dllRectsv = GPA( "glRectsv" );
+ qglRenderMode = dllRenderMode = GPA( "glRenderMode" );
+ qglRotated = dllRotated = GPA( "glRotated" );
+ qglRotatef = dllRotatef = GPA( "glRotatef" );
+ qglScaled = dllScaled = GPA( "glScaled" );
+ qglScalef = dllScalef = GPA( "glScalef" );
+ qglScissor = dllScissor = GPA( "glScissor" );
+ qglSelectBuffer = dllSelectBuffer = GPA( "glSelectBuffer" );
+ qglShadeModel = dllShadeModel = GPA( "glShadeModel" );
+ qglStencilFunc = dllStencilFunc = GPA( "glStencilFunc" );
+ qglStencilMask = dllStencilMask = GPA( "glStencilMask" );
+ qglStencilOp = dllStencilOp = GPA( "glStencilOp" );
+ qglTexCoord1d = dllTexCoord1d = GPA( "glTexCoord1d" );
+ qglTexCoord1dv = dllTexCoord1dv = GPA( "glTexCoord1dv" );
+ qglTexCoord1f = dllTexCoord1f = GPA( "glTexCoord1f" );
+ qglTexCoord1fv = dllTexCoord1fv = GPA( "glTexCoord1fv" );
+ qglTexCoord1i = dllTexCoord1i = GPA( "glTexCoord1i" );
+ qglTexCoord1iv = dllTexCoord1iv = GPA( "glTexCoord1iv" );
+ qglTexCoord1s = dllTexCoord1s = GPA( "glTexCoord1s" );
+ qglTexCoord1sv = dllTexCoord1sv = GPA( "glTexCoord1sv" );
+ qglTexCoord2d = dllTexCoord2d = GPA( "glTexCoord2d" );
+ qglTexCoord2dv = dllTexCoord2dv = GPA( "glTexCoord2dv" );
+ qglTexCoord2f = dllTexCoord2f = GPA( "glTexCoord2f" );
+ qglTexCoord2fv = dllTexCoord2fv = GPA( "glTexCoord2fv" );
+ qglTexCoord2i = dllTexCoord2i = GPA( "glTexCoord2i" );
+ qglTexCoord2iv = dllTexCoord2iv = GPA( "glTexCoord2iv" );
+ qglTexCoord2s = dllTexCoord2s = GPA( "glTexCoord2s" );
+ qglTexCoord2sv = dllTexCoord2sv = GPA( "glTexCoord2sv" );
+ qglTexCoord3d = dllTexCoord3d = GPA( "glTexCoord3d" );
+ qglTexCoord3dv = dllTexCoord3dv = GPA( "glTexCoord3dv" );
+ qglTexCoord3f = dllTexCoord3f = GPA( "glTexCoord3f" );
+ qglTexCoord3fv = dllTexCoord3fv = GPA( "glTexCoord3fv" );
+ qglTexCoord3i = dllTexCoord3i = GPA( "glTexCoord3i" );
+ qglTexCoord3iv = dllTexCoord3iv = GPA( "glTexCoord3iv" );
+ qglTexCoord3s = dllTexCoord3s = GPA( "glTexCoord3s" );
+ qglTexCoord3sv = dllTexCoord3sv = GPA( "glTexCoord3sv" );
+ qglTexCoord4d = dllTexCoord4d = GPA( "glTexCoord4d" );
+ qglTexCoord4dv = dllTexCoord4dv = GPA( "glTexCoord4dv" );
+ qglTexCoord4f = dllTexCoord4f = GPA( "glTexCoord4f" );
+ qglTexCoord4fv = dllTexCoord4fv = GPA( "glTexCoord4fv" );
+ qglTexCoord4i = dllTexCoord4i = GPA( "glTexCoord4i" );
+ qglTexCoord4iv = dllTexCoord4iv = GPA( "glTexCoord4iv" );
+ qglTexCoord4s = dllTexCoord4s = GPA( "glTexCoord4s" );
+ qglTexCoord4sv = dllTexCoord4sv = GPA( "glTexCoord4sv" );
+ qglTexCoordPointer = dllTexCoordPointer = GPA( "glTexCoordPointer" );
+ qglTexEnvf = dllTexEnvf = GPA( "glTexEnvf" );
+ qglTexEnvfv = dllTexEnvfv = GPA( "glTexEnvfv" );
+ qglTexEnvi = dllTexEnvi = GPA( "glTexEnvi" );
+ qglTexEnviv = dllTexEnviv = GPA( "glTexEnviv" );
+ qglTexGend = dllTexGend = GPA( "glTexGend" );
+ qglTexGendv = dllTexGendv = GPA( "glTexGendv" );
+ qglTexGenf = dllTexGenf = GPA( "glTexGenf" );
+ qglTexGenfv = dllTexGenfv = GPA( "glTexGenfv" );
+ qglTexGeni = dllTexGeni = GPA( "glTexGeni" );
+ qglTexGeniv = dllTexGeniv = GPA( "glTexGeniv" );
+ qglTexImage1D = dllTexImage1D = GPA( "glTexImage1D" );
+ qglTexImage2D = dllTexImage2D = GPA( "glTexImage2D" );
+ qglTexParameterf = dllTexParameterf = GPA( "glTexParameterf" );
+ qglTexParameterfv = dllTexParameterfv = GPA( "glTexParameterfv" );
+ qglTexParameteri = dllTexParameteri = GPA( "glTexParameteri" );
+ qglTexParameteriv = dllTexParameteriv = GPA( "glTexParameteriv" );
+ qglTexSubImage1D = dllTexSubImage1D = GPA( "glTexSubImage1D" );
+ qglTexSubImage2D = dllTexSubImage2D = GPA( "glTexSubImage2D" );
+ qglTranslated = dllTranslated = GPA( "glTranslated" );
+ qglTranslatef = dllTranslatef = GPA( "glTranslatef" );
+ qglVertex2d = dllVertex2d = GPA( "glVertex2d" );
+ qglVertex2dv = dllVertex2dv = GPA( "glVertex2dv" );
+ qglVertex2f = dllVertex2f = GPA( "glVertex2f" );
+ qglVertex2fv = dllVertex2fv = GPA( "glVertex2fv" );
+ qglVertex2i = dllVertex2i = GPA( "glVertex2i" );
+ qglVertex2iv = dllVertex2iv = GPA( "glVertex2iv" );
+ qglVertex2s = dllVertex2s = GPA( "glVertex2s" );
+ qglVertex2sv = dllVertex2sv = GPA( "glVertex2sv" );
+ qglVertex3d = dllVertex3d = GPA( "glVertex3d" );
+ qglVertex3dv = dllVertex3dv = GPA( "glVertex3dv" );
+ qglVertex3f = dllVertex3f = GPA( "glVertex3f" );
+ qglVertex3fv = dllVertex3fv = GPA( "glVertex3fv" );
+ qglVertex3i = dllVertex3i = GPA( "glVertex3i" );
+ qglVertex3iv = dllVertex3iv = GPA( "glVertex3iv" );
+ qglVertex3s = dllVertex3s = GPA( "glVertex3s" );
+ qglVertex3sv = dllVertex3sv = GPA( "glVertex3sv" );
+ qglVertex4d = dllVertex4d = GPA( "glVertex4d" );
+ qglVertex4dv = dllVertex4dv = GPA( "glVertex4dv" );
+ qglVertex4f = dllVertex4f = GPA( "glVertex4f" );
+ qglVertex4fv = dllVertex4fv = GPA( "glVertex4fv" );
+ qglVertex4i = dllVertex4i = GPA( "glVertex4i" );
+ qglVertex4iv = dllVertex4iv = GPA( "glVertex4iv" );
+ qglVertex4s = dllVertex4s = GPA( "glVertex4s" );
+ qglVertex4sv = dllVertex4sv = GPA( "glVertex4sv" );
+ qglVertexPointer = dllVertexPointer = GPA( "glVertexPointer" );
+ qglViewport = dllViewport = GPA( "glViewport" );
+
+// bk001129 - from cvs1.17 (mkv)
+#if defined(__FX__)
+ qfxMesaCreateContext = GPA("fxMesaCreateContext");
+ qfxMesaCreateBestContext = GPA("fxMesaCreateBestContext");
+ qfxMesaDestroyContext = GPA("fxMesaDestroyContext");
+ qfxMesaMakeCurrent = GPA("fxMesaMakeCurrent");
+ qfxMesaGetCurrentContext = GPA("fxMesaGetCurrentContext");
+ qfxMesaSwapBuffers = GPA("fxMesaSwapBuffers");
+#endif
+
+#if !defined(USE_SDL_VIDEO)
+ qglXChooseVisual = GPA("glXChooseVisual");
+ qglXCreateContext = GPA("glXCreateContext");
+ qglXDestroyContext = GPA("glXDestroyContext");
+ qglXMakeCurrent = GPA("glXMakeCurrent");
+ qglXCopyContext = GPA("glXCopyContext");
+ qglXSwapBuffers = GPA("glXSwapBuffers");
+#endif
+
+ qglLockArraysEXT = NULL;
+ qglUnlockArraysEXT = NULL;
+ qglPointParameterfEXT = NULL;
+ qglPointParameterfvEXT = NULL;
+ qglColorTableEXT = NULL;
+ qgl3DfxSetPaletteEXT = NULL;
+ qglSelectTextureSGIS = NULL;
+ qglMTexCoord2fSGIS = NULL;
+ qglActiveTextureARB = NULL;
+ qglClientActiveTextureARB = NULL;
+ qglMultiTexCoord2fARB = NULL;
+
+ return qtrue;
+}
+
+void QGL_EnableLogging( qboolean enable ) {
+ // bk001205 - fixed for new countdown
+ static qboolean isEnabled = qfalse; // init
+
+ // return if we're already active
+ if ( isEnabled && enable ) {
+ // decrement log counter and stop if it has reached 0
+ ri.Cvar_Set( "r_logFile", va("%d", r_logFile->integer - 1 ) );
+ if ( r_logFile->integer ) {
+ return;
+ }
+ enable = qfalse;
+ }
+
+ // return if we're already disabled
+ if ( !enable && !isEnabled )
+ return;
+
+ isEnabled = enable;
+
+ // bk001205 - old code starts here
+ if ( enable ) {
+ if ( !glw_state.log_fp ) {
+ struct tm *newtime;
+ time_t aclock;
+ char buffer[1024];
+ cvar_t *basedir;
+
+ time( &aclock );
+ newtime = localtime( &aclock );
+
+ asctime( newtime );
+
+ basedir = ri.Cvar_Get( "fs_basepath", "", 0 ); // FIXME: userdir?
+ assert(basedir);
+ Com_sprintf( buffer, sizeof(buffer), "%s/gl.log", basedir->string );
+ glw_state.log_fp = fopen( buffer, "wt" );
+ assert(glw_state.log_fp);
+ ri.Printf(PRINT_ALL, "QGL_EnableLogging(%d): writing %s\n", r_logFile->integer, buffer );
+
+ fprintf( glw_state.log_fp, "%s\n", asctime( newtime ) );
+ }
+
+ qglAccum = logAccum;
+ qglAlphaFunc = logAlphaFunc;
+ qglAreTexturesResident = logAreTexturesResident;
+ qglArrayElement = logArrayElement;
+ qglBegin = logBegin;
+ qglBindTexture = logBindTexture;
+ qglBitmap = logBitmap;
+ qglBlendFunc = logBlendFunc;
+ qglCallList = logCallList;
+ qglCallLists = logCallLists;
+ qglClear = logClear;
+ qglClearAccum = logClearAccum;
+ qglClearColor = logClearColor;
+ qglClearDepth = logClearDepth;
+ qglClearIndex = logClearIndex;
+ qglClearStencil = logClearStencil;
+ qglClipPlane = logClipPlane;
+ qglColor3b = logColor3b;
+ qglColor3bv = logColor3bv;
+ qglColor3d = logColor3d;
+ qglColor3dv = logColor3dv;
+ qglColor3f = logColor3f;
+ qglColor3fv = logColor3fv;
+ qglColor3i = logColor3i;
+ qglColor3iv = logColor3iv;
+ qglColor3s = logColor3s;
+ qglColor3sv = logColor3sv;
+ qglColor3ub = logColor3ub;
+ qglColor3ubv = logColor3ubv;
+ qglColor3ui = logColor3ui;
+ qglColor3uiv = logColor3uiv;
+ qglColor3us = logColor3us;
+ qglColor3usv = logColor3usv;
+ qglColor4b = logColor4b;
+ qglColor4bv = logColor4bv;
+ qglColor4d = logColor4d;
+ qglColor4dv = logColor4dv;
+ qglColor4f = logColor4f;
+ qglColor4fv = logColor4fv;
+ qglColor4i = logColor4i;
+ qglColor4iv = logColor4iv;
+ qglColor4s = logColor4s;
+ qglColor4sv = logColor4sv;
+ qglColor4ub = logColor4ub;
+ qglColor4ubv = logColor4ubv;
+ qglColor4ui = logColor4ui;
+ qglColor4uiv = logColor4uiv;
+ qglColor4us = logColor4us;
+ qglColor4usv = logColor4usv;
+ qglColorMask = logColorMask;
+ qglColorMaterial = logColorMaterial;
+ qglColorPointer = logColorPointer;
+ qglCopyPixels = logCopyPixels;
+ qglCopyTexImage1D = logCopyTexImage1D;
+ qglCopyTexImage2D = logCopyTexImage2D;
+ qglCopyTexSubImage1D = logCopyTexSubImage1D;
+ qglCopyTexSubImage2D = logCopyTexSubImage2D;
+ qglCullFace = logCullFace;
+ qglDeleteLists = logDeleteLists ;
+ qglDeleteTextures = logDeleteTextures ;
+ qglDepthFunc = logDepthFunc ;
+ qglDepthMask = logDepthMask ;
+ qglDepthRange = logDepthRange ;
+ qglDisable = logDisable ;
+ qglDisableClientState = logDisableClientState ;
+ qglDrawArrays = logDrawArrays ;
+ qglDrawBuffer = logDrawBuffer ;
+ qglDrawElements = logDrawElements ;
+ qglDrawPixels = logDrawPixels ;
+ qglEdgeFlag = logEdgeFlag ;
+ qglEdgeFlagPointer = logEdgeFlagPointer ;
+ qglEdgeFlagv = logEdgeFlagv ;
+ qglEnable = logEnable ;
+ qglEnableClientState = logEnableClientState ;
+ qglEnd = logEnd ;
+ qglEndList = logEndList ;
+ qglEvalCoord1d = logEvalCoord1d ;
+ qglEvalCoord1dv = logEvalCoord1dv ;
+ qglEvalCoord1f = logEvalCoord1f ;
+ qglEvalCoord1fv = logEvalCoord1fv ;
+ qglEvalCoord2d = logEvalCoord2d ;
+ qglEvalCoord2dv = logEvalCoord2dv ;
+ qglEvalCoord2f = logEvalCoord2f ;
+ qglEvalCoord2fv = logEvalCoord2fv ;
+ qglEvalMesh1 = logEvalMesh1 ;
+ qglEvalMesh2 = logEvalMesh2 ;
+ qglEvalPoint1 = logEvalPoint1 ;
+ qglEvalPoint2 = logEvalPoint2 ;
+ qglFeedbackBuffer = logFeedbackBuffer ;
+ qglFinish = logFinish ;
+ qglFlush = logFlush ;
+ qglFogf = logFogf ;
+ qglFogfv = logFogfv ;
+ qglFogi = logFogi ;
+ qglFogiv = logFogiv ;
+ qglFrontFace = logFrontFace ;
+ qglFrustum = logFrustum ;
+ qglGenLists = logGenLists ;
+ qglGenTextures = logGenTextures ;
+ qglGetBooleanv = logGetBooleanv ;
+ qglGetClipPlane = logGetClipPlane ;
+ qglGetDoublev = logGetDoublev ;
+ qglGetError = logGetError ;
+ qglGetFloatv = logGetFloatv ;
+ qglGetIntegerv = logGetIntegerv ;
+ qglGetLightfv = logGetLightfv ;
+ qglGetLightiv = logGetLightiv ;
+ qglGetMapdv = logGetMapdv ;
+ qglGetMapfv = logGetMapfv ;
+ qglGetMapiv = logGetMapiv ;
+ qglGetMaterialfv = logGetMaterialfv ;
+ qglGetMaterialiv = logGetMaterialiv ;
+ qglGetPixelMapfv = logGetPixelMapfv ;
+ qglGetPixelMapuiv = logGetPixelMapuiv ;
+ qglGetPixelMapusv = logGetPixelMapusv ;
+ qglGetPointerv = logGetPointerv ;
+ qglGetPolygonStipple = logGetPolygonStipple ;
+ qglGetString = logGetString ;
+ qglGetTexEnvfv = logGetTexEnvfv ;
+ qglGetTexEnviv = logGetTexEnviv ;
+ qglGetTexGendv = logGetTexGendv ;
+ qglGetTexGenfv = logGetTexGenfv ;
+ qglGetTexGeniv = logGetTexGeniv ;
+ qglGetTexImage = logGetTexImage ;
+ qglGetTexLevelParameterfv = logGetTexLevelParameterfv ;
+ qglGetTexLevelParameteriv = logGetTexLevelParameteriv ;
+ qglGetTexParameterfv = logGetTexParameterfv ;
+ qglGetTexParameteriv = logGetTexParameteriv ;
+ qglHint = logHint ;
+ qglIndexMask = logIndexMask ;
+ qglIndexPointer = logIndexPointer ;
+ qglIndexd = logIndexd ;
+ qglIndexdv = logIndexdv ;
+ qglIndexf = logIndexf ;
+ qglIndexfv = logIndexfv ;
+ qglIndexi = logIndexi ;
+ qglIndexiv = logIndexiv ;
+ qglIndexs = logIndexs ;
+ qglIndexsv = logIndexsv ;
+ qglIndexub = logIndexub ;
+ qglIndexubv = logIndexubv ;
+ qglInitNames = logInitNames ;
+ qglInterleavedArrays = logInterleavedArrays ;
+ qglIsEnabled = logIsEnabled ;
+ qglIsList = logIsList ;
+ qglIsTexture = logIsTexture ;
+ qglLightModelf = logLightModelf ;
+ qglLightModelfv = logLightModelfv ;
+ qglLightModeli = logLightModeli ;
+ qglLightModeliv = logLightModeliv ;
+ qglLightf = logLightf ;
+ qglLightfv = logLightfv ;
+ qglLighti = logLighti ;
+ qglLightiv = logLightiv ;
+ qglLineStipple = logLineStipple ;
+ qglLineWidth = logLineWidth ;
+ qglListBase = logListBase ;
+ qglLoadIdentity = logLoadIdentity ;
+ qglLoadMatrixd = logLoadMatrixd ;
+ qglLoadMatrixf = logLoadMatrixf ;
+ qglLoadName = logLoadName ;
+ qglLogicOp = logLogicOp ;
+ qglMap1d = logMap1d ;
+ qglMap1f = logMap1f ;
+ qglMap2d = logMap2d ;
+ qglMap2f = logMap2f ;
+ qglMapGrid1d = logMapGrid1d ;
+ qglMapGrid1f = logMapGrid1f ;
+ qglMapGrid2d = logMapGrid2d ;
+ qglMapGrid2f = logMapGrid2f ;
+ qglMaterialf = logMaterialf ;
+ qglMaterialfv = logMaterialfv ;
+ qglMateriali = logMateriali ;
+ qglMaterialiv = logMaterialiv ;
+ qglMatrixMode = logMatrixMode ;
+ qglMultMatrixd = logMultMatrixd ;
+ qglMultMatrixf = logMultMatrixf ;
+ qglNewList = logNewList ;
+ qglNormal3b = logNormal3b ;
+ qglNormal3bv = logNormal3bv ;
+ qglNormal3d = logNormal3d ;
+ qglNormal3dv = logNormal3dv ;
+ qglNormal3f = logNormal3f ;
+ qglNormal3fv = logNormal3fv ;
+ qglNormal3i = logNormal3i ;
+ qglNormal3iv = logNormal3iv ;
+ qglNormal3s = logNormal3s ;
+ qglNormal3sv = logNormal3sv ;
+ qglNormalPointer = logNormalPointer ;
+ qglOrtho = logOrtho ;
+ qglPassThrough = logPassThrough ;
+ qglPixelMapfv = logPixelMapfv ;
+ qglPixelMapuiv = logPixelMapuiv ;
+ qglPixelMapusv = logPixelMapusv ;
+ qglPixelStoref = logPixelStoref ;
+ qglPixelStorei = logPixelStorei ;
+ qglPixelTransferf = logPixelTransferf ;
+ qglPixelTransferi = logPixelTransferi ;
+ qglPixelZoom = logPixelZoom ;
+ qglPointSize = logPointSize ;
+ qglPolygonMode = logPolygonMode ;
+ qglPolygonOffset = logPolygonOffset ;
+ qglPolygonStipple = logPolygonStipple ;
+ qglPopAttrib = logPopAttrib ;
+ qglPopClientAttrib = logPopClientAttrib ;
+ qglPopMatrix = logPopMatrix ;
+ qglPopName = logPopName ;
+ qglPrioritizeTextures = logPrioritizeTextures ;
+ qglPushAttrib = logPushAttrib ;
+ qglPushClientAttrib = logPushClientAttrib ;
+ qglPushMatrix = logPushMatrix ;
+ qglPushName = logPushName ;
+ qglRasterPos2d = logRasterPos2d ;
+ qglRasterPos2dv = logRasterPos2dv ;
+ qglRasterPos2f = logRasterPos2f ;
+ qglRasterPos2fv = logRasterPos2fv ;
+ qglRasterPos2i = logRasterPos2i ;
+ qglRasterPos2iv = logRasterPos2iv ;
+ qglRasterPos2s = logRasterPos2s ;
+ qglRasterPos2sv = logRasterPos2sv ;
+ qglRasterPos3d = logRasterPos3d ;
+ qglRasterPos3dv = logRasterPos3dv ;
+ qglRasterPos3f = logRasterPos3f ;
+ qglRasterPos3fv = logRasterPos3fv ;
+ qglRasterPos3i = logRasterPos3i ;
+ qglRasterPos3iv = logRasterPos3iv ;
+ qglRasterPos3s = logRasterPos3s ;
+ qglRasterPos3sv = logRasterPos3sv ;
+ qglRasterPos4d = logRasterPos4d ;
+ qglRasterPos4dv = logRasterPos4dv ;
+ qglRasterPos4f = logRasterPos4f ;
+ qglRasterPos4fv = logRasterPos4fv ;
+ qglRasterPos4i = logRasterPos4i ;
+ qglRasterPos4iv = logRasterPos4iv ;
+ qglRasterPos4s = logRasterPos4s ;
+ qglRasterPos4sv = logRasterPos4sv ;
+ qglReadBuffer = logReadBuffer ;
+ qglReadPixels = logReadPixels ;
+ qglRectd = logRectd ;
+ qglRectdv = logRectdv ;
+ qglRectf = logRectf ;
+ qglRectfv = logRectfv ;
+ qglRecti = logRecti ;
+ qglRectiv = logRectiv ;
+ qglRects = logRects ;
+ qglRectsv = logRectsv ;
+ qglRenderMode = logRenderMode ;
+ qglRotated = logRotated ;
+ qglRotatef = logRotatef ;
+ qglScaled = logScaled ;
+ qglScalef = logScalef ;
+ qglScissor = logScissor ;
+ qglSelectBuffer = logSelectBuffer ;
+ qglShadeModel = logShadeModel ;
+ qglStencilFunc = logStencilFunc ;
+ qglStencilMask = logStencilMask ;
+ qglStencilOp = logStencilOp ;
+ qglTexCoord1d = logTexCoord1d ;
+ qglTexCoord1dv = logTexCoord1dv ;
+ qglTexCoord1f = logTexCoord1f ;
+ qglTexCoord1fv = logTexCoord1fv ;
+ qglTexCoord1i = logTexCoord1i ;
+ qglTexCoord1iv = logTexCoord1iv ;
+ qglTexCoord1s = logTexCoord1s ;
+ qglTexCoord1sv = logTexCoord1sv ;
+ qglTexCoord2d = logTexCoord2d ;
+ qglTexCoord2dv = logTexCoord2dv ;
+ qglTexCoord2f = logTexCoord2f ;
+ qglTexCoord2fv = logTexCoord2fv ;
+ qglTexCoord2i = logTexCoord2i ;
+ qglTexCoord2iv = logTexCoord2iv ;
+ qglTexCoord2s = logTexCoord2s ;
+ qglTexCoord2sv = logTexCoord2sv ;
+ qglTexCoord3d = logTexCoord3d ;
+ qglTexCoord3dv = logTexCoord3dv ;
+ qglTexCoord3f = logTexCoord3f ;
+ qglTexCoord3fv = logTexCoord3fv ;
+ qglTexCoord3i = logTexCoord3i ;
+ qglTexCoord3iv = logTexCoord3iv ;
+ qglTexCoord3s = logTexCoord3s ;
+ qglTexCoord3sv = logTexCoord3sv ;
+ qglTexCoord4d = logTexCoord4d ;
+ qglTexCoord4dv = logTexCoord4dv ;
+ qglTexCoord4f = logTexCoord4f ;
+ qglTexCoord4fv = logTexCoord4fv ;
+ qglTexCoord4i = logTexCoord4i ;
+ qglTexCoord4iv = logTexCoord4iv ;
+ qglTexCoord4s = logTexCoord4s ;
+ qglTexCoord4sv = logTexCoord4sv ;
+ qglTexCoordPointer = logTexCoordPointer ;
+ qglTexEnvf = logTexEnvf ;
+ qglTexEnvfv = logTexEnvfv ;
+ qglTexEnvi = logTexEnvi ;
+ qglTexEnviv = logTexEnviv ;
+ qglTexGend = logTexGend ;
+ qglTexGendv = logTexGendv ;
+ qglTexGenf = logTexGenf ;
+ qglTexGenfv = logTexGenfv ;
+ qglTexGeni = logTexGeni ;
+ qglTexGeniv = logTexGeniv ;
+ qglTexImage1D = logTexImage1D ;
+ qglTexImage2D = logTexImage2D ;
+ qglTexParameterf = logTexParameterf ;
+ qglTexParameterfv = logTexParameterfv ;
+ qglTexParameteri = logTexParameteri ;
+ qglTexParameteriv = logTexParameteriv ;
+ qglTexSubImage1D = logTexSubImage1D ;
+ qglTexSubImage2D = logTexSubImage2D ;
+ qglTranslated = logTranslated ;
+ qglTranslatef = logTranslatef ;
+ qglVertex2d = logVertex2d ;
+ qglVertex2dv = logVertex2dv ;
+ qglVertex2f = logVertex2f ;
+ qglVertex2fv = logVertex2fv ;
+ qglVertex2i = logVertex2i ;
+ qglVertex2iv = logVertex2iv ;
+ qglVertex2s = logVertex2s ;
+ qglVertex2sv = logVertex2sv ;
+ qglVertex3d = logVertex3d ;
+ qglVertex3dv = logVertex3dv ;
+ qglVertex3f = logVertex3f ;
+ qglVertex3fv = logVertex3fv ;
+ qglVertex3i = logVertex3i ;
+ qglVertex3iv = logVertex3iv ;
+ qglVertex3s = logVertex3s ;
+ qglVertex3sv = logVertex3sv ;
+ qglVertex4d = logVertex4d ;
+ qglVertex4dv = logVertex4dv ;
+ qglVertex4f = logVertex4f ;
+ qglVertex4fv = logVertex4fv ;
+ qglVertex4i = logVertex4i ;
+ qglVertex4iv = logVertex4iv ;
+ qglVertex4s = logVertex4s ;
+ qglVertex4sv = logVertex4sv ;
+ qglVertexPointer = logVertexPointer ;
+ qglViewport = logViewport ;
+ }
+ else
+ {
+ qglAccum = dllAccum;
+ qglAlphaFunc = dllAlphaFunc;
+ qglAreTexturesResident = dllAreTexturesResident;
+ qglArrayElement = dllArrayElement;
+ qglBegin = dllBegin;
+ qglBindTexture = dllBindTexture;
+ qglBitmap = dllBitmap;
+ qglBlendFunc = dllBlendFunc;
+ qglCallList = dllCallList;
+ qglCallLists = dllCallLists;
+ qglClear = dllClear;
+ qglClearAccum = dllClearAccum;
+ qglClearColor = dllClearColor;
+ qglClearDepth = dllClearDepth;
+ qglClearIndex = dllClearIndex;
+ qglClearStencil = dllClearStencil;
+ qglClipPlane = dllClipPlane;
+ qglColor3b = dllColor3b;
+ qglColor3bv = dllColor3bv;
+ qglColor3d = dllColor3d;
+ qglColor3dv = dllColor3dv;
+ qglColor3f = dllColor3f;
+ qglColor3fv = dllColor3fv;
+ qglColor3i = dllColor3i;
+ qglColor3iv = dllColor3iv;
+ qglColor3s = dllColor3s;
+ qglColor3sv = dllColor3sv;
+ qglColor3ub = dllColor3ub;
+ qglColor3ubv = dllColor3ubv;
+ qglColor3ui = dllColor3ui;
+ qglColor3uiv = dllColor3uiv;
+ qglColor3us = dllColor3us;
+ qglColor3usv = dllColor3usv;
+ qglColor4b = dllColor4b;
+ qglColor4bv = dllColor4bv;
+ qglColor4d = dllColor4d;
+ qglColor4dv = dllColor4dv;
+ qglColor4f = dllColor4f;
+ qglColor4fv = dllColor4fv;
+ qglColor4i = dllColor4i;
+ qglColor4iv = dllColor4iv;
+ qglColor4s = dllColor4s;
+ qglColor4sv = dllColor4sv;
+ qglColor4ub = dllColor4ub;
+ qglColor4ubv = dllColor4ubv;
+ qglColor4ui = dllColor4ui;
+ qglColor4uiv = dllColor4uiv;
+ qglColor4us = dllColor4us;
+ qglColor4usv = dllColor4usv;
+ qglColorMask = dllColorMask;
+ qglColorMaterial = dllColorMaterial;
+ qglColorPointer = dllColorPointer;
+ qglCopyPixels = dllCopyPixels;
+ qglCopyTexImage1D = dllCopyTexImage1D;
+ qglCopyTexImage2D = dllCopyTexImage2D;
+ qglCopyTexSubImage1D = dllCopyTexSubImage1D;
+ qglCopyTexSubImage2D = dllCopyTexSubImage2D;
+ qglCullFace = dllCullFace;
+ qglDeleteLists = dllDeleteLists ;
+ qglDeleteTextures = dllDeleteTextures ;
+ qglDepthFunc = dllDepthFunc ;
+ qglDepthMask = dllDepthMask ;
+ qglDepthRange = dllDepthRange ;
+ qglDisable = dllDisable ;
+ qglDisableClientState = dllDisableClientState ;
+ qglDrawArrays = dllDrawArrays ;
+ qglDrawBuffer = dllDrawBuffer ;
+ qglDrawElements = dllDrawElements ;
+ qglDrawPixels = dllDrawPixels ;
+ qglEdgeFlag = dllEdgeFlag ;
+ qglEdgeFlagPointer = dllEdgeFlagPointer ;
+ qglEdgeFlagv = dllEdgeFlagv ;
+ qglEnable = dllEnable ;
+ qglEnableClientState = dllEnableClientState ;
+ qglEnd = dllEnd ;
+ qglEndList = dllEndList ;
+ qglEvalCoord1d = dllEvalCoord1d ;
+ qglEvalCoord1dv = dllEvalCoord1dv ;
+ qglEvalCoord1f = dllEvalCoord1f ;
+ qglEvalCoord1fv = dllEvalCoord1fv ;
+ qglEvalCoord2d = dllEvalCoord2d ;
+ qglEvalCoord2dv = dllEvalCoord2dv ;
+ qglEvalCoord2f = dllEvalCoord2f ;
+ qglEvalCoord2fv = dllEvalCoord2fv ;
+ qglEvalMesh1 = dllEvalMesh1 ;
+ qglEvalMesh2 = dllEvalMesh2 ;
+ qglEvalPoint1 = dllEvalPoint1 ;
+ qglEvalPoint2 = dllEvalPoint2 ;
+ qglFeedbackBuffer = dllFeedbackBuffer ;
+ qglFinish = dllFinish ;
+ qglFlush = dllFlush ;
+ qglFogf = dllFogf ;
+ qglFogfv = dllFogfv ;
+ qglFogi = dllFogi ;
+ qglFogiv = dllFogiv ;
+ qglFrontFace = dllFrontFace ;
+ qglFrustum = dllFrustum ;
+ qglGenLists = dllGenLists ;
+ qglGenTextures = dllGenTextures ;
+ qglGetBooleanv = dllGetBooleanv ;
+ qglGetClipPlane = dllGetClipPlane ;
+ qglGetDoublev = dllGetDoublev ;
+ qglGetError = dllGetError ;
+ qglGetFloatv = dllGetFloatv ;
+ qglGetIntegerv = dllGetIntegerv ;
+ qglGetLightfv = dllGetLightfv ;
+ qglGetLightiv = dllGetLightiv ;
+ qglGetMapdv = dllGetMapdv ;
+ qglGetMapfv = dllGetMapfv ;
+ qglGetMapiv = dllGetMapiv ;
+ qglGetMaterialfv = dllGetMaterialfv ;
+ qglGetMaterialiv = dllGetMaterialiv ;
+ qglGetPixelMapfv = dllGetPixelMapfv ;
+ qglGetPixelMapuiv = dllGetPixelMapuiv ;
+ qglGetPixelMapusv = dllGetPixelMapusv ;
+ qglGetPointerv = dllGetPointerv ;
+ qglGetPolygonStipple = dllGetPolygonStipple ;
+ qglGetString = dllGetString ;
+ qglGetTexEnvfv = dllGetTexEnvfv ;
+ qglGetTexEnviv = dllGetTexEnviv ;
+ qglGetTexGendv = dllGetTexGendv ;
+ qglGetTexGenfv = dllGetTexGenfv ;
+ qglGetTexGeniv = dllGetTexGeniv ;
+ qglGetTexImage = dllGetTexImage ;
+ qglGetTexLevelParameterfv = dllGetTexLevelParameterfv ;
+ qglGetTexLevelParameteriv = dllGetTexLevelParameteriv ;
+ qglGetTexParameterfv = dllGetTexParameterfv ;
+ qglGetTexParameteriv = dllGetTexParameteriv ;
+ qglHint = dllHint ;
+ qglIndexMask = dllIndexMask ;
+ qglIndexPointer = dllIndexPointer ;
+ qglIndexd = dllIndexd ;
+ qglIndexdv = dllIndexdv ;
+ qglIndexf = dllIndexf ;
+ qglIndexfv = dllIndexfv ;
+ qglIndexi = dllIndexi ;
+ qglIndexiv = dllIndexiv ;
+ qglIndexs = dllIndexs ;
+ qglIndexsv = dllIndexsv ;
+ qglIndexub = dllIndexub ;
+ qglIndexubv = dllIndexubv ;
+ qglInitNames = dllInitNames ;
+ qglInterleavedArrays = dllInterleavedArrays ;
+ qglIsEnabled = dllIsEnabled ;
+ qglIsList = dllIsList ;
+ qglIsTexture = dllIsTexture ;
+ qglLightModelf = dllLightModelf ;
+ qglLightModelfv = dllLightModelfv ;
+ qglLightModeli = dllLightModeli ;
+ qglLightModeliv = dllLightModeliv ;
+ qglLightf = dllLightf ;
+ qglLightfv = dllLightfv ;
+ qglLighti = dllLighti ;
+ qglLightiv = dllLightiv ;
+ qglLineStipple = dllLineStipple ;
+ qglLineWidth = dllLineWidth ;
+ qglListBase = dllListBase ;
+ qglLoadIdentity = dllLoadIdentity ;
+ qglLoadMatrixd = dllLoadMatrixd ;
+ qglLoadMatrixf = dllLoadMatrixf ;
+ qglLoadName = dllLoadName ;
+ qglLogicOp = dllLogicOp ;
+ qglMap1d = dllMap1d ;
+ qglMap1f = dllMap1f ;
+ qglMap2d = dllMap2d ;
+ qglMap2f = dllMap2f ;
+ qglMapGrid1d = dllMapGrid1d ;
+ qglMapGrid1f = dllMapGrid1f ;
+ qglMapGrid2d = dllMapGrid2d ;
+ qglMapGrid2f = dllMapGrid2f ;
+ qglMaterialf = dllMaterialf ;
+ qglMaterialfv = dllMaterialfv ;
+ qglMateriali = dllMateriali ;
+ qglMaterialiv = dllMaterialiv ;
+ qglMatrixMode = dllMatrixMode ;
+ qglMultMatrixd = dllMultMatrixd ;
+ qglMultMatrixf = dllMultMatrixf ;
+ qglNewList = dllNewList ;
+ qglNormal3b = dllNormal3b ;
+ qglNormal3bv = dllNormal3bv ;
+ qglNormal3d = dllNormal3d ;
+ qglNormal3dv = dllNormal3dv ;
+ qglNormal3f = dllNormal3f ;
+ qglNormal3fv = dllNormal3fv ;
+ qglNormal3i = dllNormal3i ;
+ qglNormal3iv = dllNormal3iv ;
+ qglNormal3s = dllNormal3s ;
+ qglNormal3sv = dllNormal3sv ;
+ qglNormalPointer = dllNormalPointer ;
+ qglOrtho = dllOrtho ;
+ qglPassThrough = dllPassThrough ;
+ qglPixelMapfv = dllPixelMapfv ;
+ qglPixelMapuiv = dllPixelMapuiv ;
+ qglPixelMapusv = dllPixelMapusv ;
+ qglPixelStoref = dllPixelStoref ;
+ qglPixelStorei = dllPixelStorei ;
+ qglPixelTransferf = dllPixelTransferf ;
+ qglPixelTransferi = dllPixelTransferi ;
+ qglPixelZoom = dllPixelZoom ;
+ qglPointSize = dllPointSize ;
+ qglPolygonMode = dllPolygonMode ;
+ qglPolygonOffset = dllPolygonOffset ;
+ qglPolygonStipple = dllPolygonStipple ;
+ qglPopAttrib = dllPopAttrib ;
+ qglPopClientAttrib = dllPopClientAttrib ;
+ qglPopMatrix = dllPopMatrix ;
+ qglPopName = dllPopName ;
+ qglPrioritizeTextures = dllPrioritizeTextures ;
+ qglPushAttrib = dllPushAttrib ;
+ qglPushClientAttrib = dllPushClientAttrib ;
+ qglPushMatrix = dllPushMatrix ;
+ qglPushName = dllPushName ;
+ qglRasterPos2d = dllRasterPos2d ;
+ qglRasterPos2dv = dllRasterPos2dv ;
+ qglRasterPos2f = dllRasterPos2f ;
+ qglRasterPos2fv = dllRasterPos2fv ;
+ qglRasterPos2i = dllRasterPos2i ;
+ qglRasterPos2iv = dllRasterPos2iv ;
+ qglRasterPos2s = dllRasterPos2s ;
+ qglRasterPos2sv = dllRasterPos2sv ;
+ qglRasterPos3d = dllRasterPos3d ;
+ qglRasterPos3dv = dllRasterPos3dv ;
+ qglRasterPos3f = dllRasterPos3f ;
+ qglRasterPos3fv = dllRasterPos3fv ;
+ qglRasterPos3i = dllRasterPos3i ;
+ qglRasterPos3iv = dllRasterPos3iv ;
+ qglRasterPos3s = dllRasterPos3s ;
+ qglRasterPos3sv = dllRasterPos3sv ;
+ qglRasterPos4d = dllRasterPos4d ;
+ qglRasterPos4dv = dllRasterPos4dv ;
+ qglRasterPos4f = dllRasterPos4f ;
+ qglRasterPos4fv = dllRasterPos4fv ;
+ qglRasterPos4i = dllRasterPos4i ;
+ qglRasterPos4iv = dllRasterPos4iv ;
+ qglRasterPos4s = dllRasterPos4s ;
+ qglRasterPos4sv = dllRasterPos4sv ;
+ qglReadBuffer = dllReadBuffer ;
+ qglReadPixels = dllReadPixels ;
+ qglRectd = dllRectd ;
+ qglRectdv = dllRectdv ;
+ qglRectf = dllRectf ;
+ qglRectfv = dllRectfv ;
+ qglRecti = dllRecti ;
+ qglRectiv = dllRectiv ;
+ qglRects = dllRects ;
+ qglRectsv = dllRectsv ;
+ qglRenderMode = dllRenderMode ;
+ qglRotated = dllRotated ;
+ qglRotatef = dllRotatef ;
+ qglScaled = dllScaled ;
+ qglScalef = dllScalef ;
+ qglScissor = dllScissor ;
+ qglSelectBuffer = dllSelectBuffer ;
+ qglShadeModel = dllShadeModel ;
+ qglStencilFunc = dllStencilFunc ;
+ qglStencilMask = dllStencilMask ;
+ qglStencilOp = dllStencilOp ;
+ qglTexCoord1d = dllTexCoord1d ;
+ qglTexCoord1dv = dllTexCoord1dv ;
+ qglTexCoord1f = dllTexCoord1f ;
+ qglTexCoord1fv = dllTexCoord1fv ;
+ qglTexCoord1i = dllTexCoord1i ;
+ qglTexCoord1iv = dllTexCoord1iv ;
+ qglTexCoord1s = dllTexCoord1s ;
+ qglTexCoord1sv = dllTexCoord1sv ;
+ qglTexCoord2d = dllTexCoord2d ;
+ qglTexCoord2dv = dllTexCoord2dv ;
+ qglTexCoord2f = dllTexCoord2f ;
+ qglTexCoord2fv = dllTexCoord2fv ;
+ qglTexCoord2i = dllTexCoord2i ;
+ qglTexCoord2iv = dllTexCoord2iv ;
+ qglTexCoord2s = dllTexCoord2s ;
+ qglTexCoord2sv = dllTexCoord2sv ;
+ qglTexCoord3d = dllTexCoord3d ;
+ qglTexCoord3dv = dllTexCoord3dv ;
+ qglTexCoord3f = dllTexCoord3f ;
+ qglTexCoord3fv = dllTexCoord3fv ;
+ qglTexCoord3i = dllTexCoord3i ;
+ qglTexCoord3iv = dllTexCoord3iv ;
+ qglTexCoord3s = dllTexCoord3s ;
+ qglTexCoord3sv = dllTexCoord3sv ;
+ qglTexCoord4d = dllTexCoord4d ;
+ qglTexCoord4dv = dllTexCoord4dv ;
+ qglTexCoord4f = dllTexCoord4f ;
+ qglTexCoord4fv = dllTexCoord4fv ;
+ qglTexCoord4i = dllTexCoord4i ;
+ qglTexCoord4iv = dllTexCoord4iv ;
+ qglTexCoord4s = dllTexCoord4s ;
+ qglTexCoord4sv = dllTexCoord4sv ;
+ qglTexCoordPointer = dllTexCoordPointer ;
+ qglTexEnvf = dllTexEnvf ;
+ qglTexEnvfv = dllTexEnvfv ;
+ qglTexEnvi = dllTexEnvi ;
+ qglTexEnviv = dllTexEnviv ;
+ qglTexGend = dllTexGend ;
+ qglTexGendv = dllTexGendv ;
+ qglTexGenf = dllTexGenf ;
+ qglTexGenfv = dllTexGenfv ;
+ qglTexGeni = dllTexGeni ;
+ qglTexGeniv = dllTexGeniv ;
+ qglTexImage1D = dllTexImage1D ;
+ qglTexImage2D = dllTexImage2D ;
+ qglTexParameterf = dllTexParameterf ;
+ qglTexParameterfv = dllTexParameterfv ;
+ qglTexParameteri = dllTexParameteri ;
+ qglTexParameteriv = dllTexParameteriv ;
+ qglTexSubImage1D = dllTexSubImage1D ;
+ qglTexSubImage2D = dllTexSubImage2D ;
+ qglTranslated = dllTranslated ;
+ qglTranslatef = dllTranslatef ;
+ qglVertex2d = dllVertex2d ;
+ qglVertex2dv = dllVertex2dv ;
+ qglVertex2f = dllVertex2f ;
+ qglVertex2fv = dllVertex2fv ;
+ qglVertex2i = dllVertex2i ;
+ qglVertex2iv = dllVertex2iv ;
+ qglVertex2s = dllVertex2s ;
+ qglVertex2sv = dllVertex2sv ;
+ qglVertex3d = dllVertex3d ;
+ qglVertex3dv = dllVertex3dv ;
+ qglVertex3f = dllVertex3f ;
+ qglVertex3fv = dllVertex3fv ;
+ qglVertex3i = dllVertex3i ;
+ qglVertex3iv = dllVertex3iv ;
+ qglVertex3s = dllVertex3s ;
+ qglVertex3sv = dllVertex3sv ;
+ qglVertex4d = dllVertex4d ;
+ qglVertex4dv = dllVertex4dv ;
+ qglVertex4f = dllVertex4f ;
+ qglVertex4fv = dllVertex4fv ;
+ qglVertex4i = dllVertex4i ;
+ qglVertex4iv = dllVertex4iv ;
+ qglVertex4s = dllVertex4s ;
+ qglVertex4sv = dllVertex4sv ;
+ qglVertexPointer = dllVertexPointer ;
+ qglViewport = dllViewport ;
+ }
+}
+
+
+void GLimp_LogNewFrame( void )
+{
+ fprintf( glw_state.log_fp, "*** R_BeginFrame ***\n" );
+}
+
+
diff --git a/src/unix/linux_signals.c b/src/unix/linux_signals.c
new file mode 100644
index 0000000..72c5a52
--- /dev/null
+++ b/src/unix/linux_signals.c
@@ -0,0 +1,65 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+#include <signal.h>
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+#ifndef DEDICATED
+#include "../renderer/tr_local.h"
+#endif
+
+static qboolean signalcaught = qfalse;;
+
+void Sys_Exit(int); // bk010104 - abstraction
+
+static void signal_handler(int sig) // bk010104 - replace this... (NOTE TTimo huh?)
+{
+ if (signalcaught)
+ {
+ printf("DOUBLE SIGNAL FAULT: Received signal %d, exiting...\n", sig);
+ Sys_Exit(1); // bk010104 - abstraction
+ }
+
+ signalcaught = qtrue;
+ printf("Received signal %d, exiting...\n", sig);
+#ifndef DEDICATED
+ //GLimp_Shutdown(); // bk010104 - shouldn't this be CL_Shutdown
+ // rcg08312005 Agreed: changed to CL_Shutdown... --ryan.
+ CL_Shutdown();
+#endif
+ SV_Shutdown("Signal caught");
+ Sys_Exit(0); // bk010104 - abstraction NOTE TTimo send a 0 to avoid DOUBLE SIGNAL FAULT
+}
+
+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);
+}
diff --git a/src/unix/linux_snd.c b/src/unix/linux_snd.c
new file mode 100644
index 0000000..cc46118
--- /dev/null
+++ b/src/unix/linux_snd.c
@@ -0,0 +1,295 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+
+#if !USE_SDL_SOUND
+
+#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>
+#ifdef __linux__ // rb0101023 - guard this
+#include <linux/soundcard.h>
+#endif
+#ifdef __FreeBSD__ // rb0101023 - added
+#include <sys/soundcard.h>
+#endif
+#include <stdio.h>
+
+#include "../qcommon/q_shared.h"
+#include "../client/snd_local.h"
+
+int audio_fd;
+int snd_inited=0;
+
+cvar_t *sndbits;
+cvar_t *sndspeed;
+cvar_t *sndchannels;
+
+cvar_t *snddevice;
+
+/* Some devices may work only with 48000 */
+static int tryrates[] = { 22050, 11025, 44100, 48000, 8000 };
+
+static qboolean use_custom_memset = qfalse;
+// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371
+void Snd_Memset (void* dest, const int val, const size_t count)
+{
+ int *pDest;
+ int i, iterate;
+
+ if (!use_custom_memset)
+ {
+ Com_Memset(dest,val,count);
+ return;
+ }
+ iterate = count / sizeof(int);
+ pDest = (int*)dest;
+ for(i=0; i<iterate; i++)
+ {
+ pDest[i] = val;
+ }
+}
+
+qboolean SNDDMA_Init(void)
+{
+ int rc;
+ int fmt;
+ int tmp;
+ int i;
+ // char *s; // bk001204 - unused
+ struct audio_buf_info info;
+ int caps;
+
+ if (snd_inited)
+ return 1;
+
+ 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/dsp", CVAR_ARCHIVE);
+ }
+
+ // open /dev/dsp, confirm capability to mmap, and get size of dma buffer
+ if (!audio_fd) {
+ audio_fd = open(snddevice->string, O_RDWR);
+
+ if (audio_fd < 0) {
+ perror(snddevice->string);
+ Com_Printf("Could not open %s\n", snddevice->string);
+ 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;
+ }
+
+
+ /* SNDCTL_DSP_GETOSPACE moved to be called later */
+
+ // 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;
+
+/* mmap() call moved forward */
+
+ 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;
+ }
+
+ if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) {
+ perror("GETOSPACE");
+ Com_Printf("Um, can't do GETOSPACE?\n");
+ close(audio_fd);
+ return 0;
+ }
+
+ dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
+ dma.submission_chunk = 1;
+
+ // memory map the dma buffer
+
+ // TTimo 2001/10/08 added PROT_READ to the mmap
+ // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371
+ // checking Alsa bug, doesn't allow dma alloc with PROT_READ?
+
+ if (!dma.buffer)
+ dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
+ * info.fragsize, PROT_WRITE|PROT_READ, MAP_FILE|MAP_SHARED, audio_fd, 0);
+
+ if (dma.buffer == MAP_FAILED)
+ {
+ Com_Printf("Could not mmap dma buffer PROT_WRITE|PROT_READ\n");
+ Com_Printf("trying mmap PROT_WRITE (with associated better compatibility / less performance code)\n");
+ dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
+ * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
+ // NOTE TTimo could add a variable to force using regular memset on systems that are known to be safe
+ use_custom_memset = qtrue;
+ }
+
+ if (dma.buffer == MAP_FAILED) {
+ perror(snddevice->string);
+ Com_Printf("Could not mmap %s\n", snddevice->string);
+ 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;
+ }
+
+ 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;
+ }
+ return count.ptr / (dma.samplebits / 8);
+}
+
+void SNDDMA_Shutdown(void)
+{
+}
+
+/*
+==============
+SNDDMA_Submit
+
+Send sound to device if buffer isn't really the dma buffer
+===============
+*/
+void SNDDMA_Submit(void)
+{
+}
+
+void SNDDMA_BeginPainting (void)
+{
+}
+
+#endif // !USE_SDL_SOUND
+
diff --git a/src/unix/matha.s b/src/unix/matha.s
new file mode 100644
index 0000000..d8ddb55
--- /dev/null
+++ b/src/unix/matha.s
@@ -0,0 +1,425 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Foobar; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+//
+// math.s
+// x86 assembly-language math routines.
+
+#include "qasm.h"
+
+
+#if id386
+
+ .data
+
+ .align 4
+Ljmptab: .long Lcase0, Lcase1, Lcase2, Lcase3
+ .long Lcase4, Lcase5, Lcase6, Lcase7
+
+ .text
+
+// TODO: rounding needed?
+// stack parameter offset
+#define val 4
+
+.globl C(Invert24To16)
+C(Invert24To16):
+
+ movl val(%esp),%ecx
+ movl $0x100,%edx // 0x10000000000 as dividend
+ cmpl %edx,%ecx
+ jle LOutOfRange
+
+ subl %eax,%eax
+ divl %ecx
+
+ ret
+
+LOutOfRange:
+ movl $0xFFFFFFFF,%eax
+ ret
+
+#if 0
+
+#define in 4
+#define out 8
+
+ .align 2
+.globl C(TransformVector)
+C(TransformVector):
+ movl in(%esp),%eax
+ movl out(%esp),%edx
+
+ flds (%eax) // in[0]
+ fmuls C(vright) // in[0]*vright[0]
+ flds (%eax) // in[0] | in[0]*vright[0]
+ fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0]
+ flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0]
+ fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0]
+
+ flds 4(%eax) // in[1] | ...
+ fmuls C(vright)+4 // in[1]*vright[1] | ...
+ flds 4(%eax) // in[1] | in[1]*vright[1] | ...
+ fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ...
+ flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ...
+ fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ...
+ fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ...
+
+ faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ...
+ faddp %st(0),%st(3) // in[1]*vpn[1] | ...
+ faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
+
+ flds 8(%eax) // in[2] | ...
+ fmuls C(vright)+8 // in[2]*vright[2] | ...
+ flds 8(%eax) // in[2] | in[2]*vright[2] | ...
+ fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ...
+ flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ...
+ fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ...
+ fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ...
+
+ faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ...
+ faddp %st(0),%st(3) // in[2]*vpn[2] | ...
+ faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum
+
+ fstps 8(%edx) // out[2]
+ fstps 4(%edx) // out[1]
+ fstps (%edx) // out[0]
+
+ ret
+
+#endif
+
+#define EMINS 4+4
+#define EMAXS 4+8
+#define P 4+12
+
+ .align 2
+.globl C(BoxOnPlaneSide)
+C(BoxOnPlaneSide):
+ pushl %ebx
+
+ movl P(%esp),%edx
+ movl EMINS(%esp),%ecx
+ xorl %eax,%eax
+ movl EMAXS(%esp),%ebx
+ movb pl_signbits(%edx),%al
+ cmpb $8,%al
+ jge Lerror
+ flds pl_normal(%edx) // p->normal[0]
+ fld %st(0) // p->normal[0] | p->normal[0]
+ // bk000422 - warning: missing prefix `*' in absolute indirect address, maybe misassembled!
+ // bk001129 - fix from Andrew Henderson, was: Ljmptab(,%eax,4)
+ jmp *Ljmptab(,%eax,4)
+
+
+//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
+//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
+Lcase0:
+ fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0]
+ flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] |
+ // p->normal[0]
+ fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] |
+ // p->normal[1]
+ fmuls (%ecx) // p->normal[0]*emins[0] |
+ // p->normal[0]*emaxs[0] | p->normal[1]
+ fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fld %st(0) // p->normal[1] | p->normal[1] |
+ // p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] |
+ // p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] |
+ // p->normal[1] | p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] |
+ // p->normal[2] | p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fmuls 4(%ecx) // p->normal[1]*emins[1] |
+ // p->normal[1]*emaxs[1] |
+ // p->normal[2] | p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] |
+ // p->normal[1]*emins[1] |
+ // p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fld %st(0) // p->normal[2] | p->normal[2] |
+ // p->normal[1]*emaxs[1] |
+ // p->normal[1]*emins[1] |
+ // p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fmuls 8(%ebx) // p->normal[2]*emaxs[2] |
+ // p->normal[2] |
+ // p->normal[1]*emaxs[1] |
+ // p->normal[1]*emins[1] |
+ // p->normal[0]*emaxs[0] |
+ // p->normal[0]*emins[0]
+ fxch %st(5) // p->normal[0]*emins[0] |
+ // p->normal[2] |
+ // p->normal[1]*emaxs[1] |
+ // p->normal[1]*emins[1] |
+ // p->normal[0]*emaxs[0] |
+ // p->normal[2]*emaxs[2]
+ faddp %st(0),%st(3) //p->normal[2] |
+ // p->normal[1]*emaxs[1] |
+ // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
+ // p->normal[0]*emaxs[0] |
+ // p->normal[2]*emaxs[2]
+ fmuls 8(%ecx) //p->normal[2]*emins[2] |
+ // p->normal[1]*emaxs[1] |
+ // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
+ // p->normal[0]*emaxs[0] |
+ // p->normal[2]*emaxs[2]
+ fxch %st(1) //p->normal[1]*emaxs[1] |
+ // p->normal[2]*emins[2] |
+ // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
+ // p->normal[0]*emaxs[0] |
+ // p->normal[2]*emaxs[2]
+ faddp %st(0),%st(3) //p->normal[2]*emins[2] |
+ // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
+ // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
+ // p->normal[2]*emaxs[2]
+ fxch %st(3) //p->normal[2]*emaxs[2] +
+ // p->normal[1]*emins[1]+p->normal[0]*emins[0]|
+ // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]|
+ // p->normal[2]*emins[2]
+ faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]|
+ // dist1 | p->normal[2]*emins[2]
+
+ jmp LSetSides
+
+//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
+//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
+Lcase1:
+ fmuls (%ecx) // emins[0]
+ flds pl_normal+4(%edx)
+ fxch %st(2)
+ fmuls (%ebx) // emaxs[0]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 4(%ebx) // emaxs[1]
+ flds pl_normal+8(%edx)
+ fxch %st(2)
+ fmuls 4(%ecx) // emins[1]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 8(%ebx) // emaxs[2]
+ fxch %st(5)
+ faddp %st(0),%st(3)
+ fmuls 8(%ecx) // emins[2]
+ fxch %st(1)
+ faddp %st(0),%st(3)
+ fxch %st(3)
+ faddp %st(0),%st(2)
+
+ jmp LSetSides
+
+//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
+//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
+Lcase2:
+ fmuls (%ebx) // emaxs[0]
+ flds pl_normal+4(%edx)
+ fxch %st(2)
+ fmuls (%ecx) // emins[0]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 4(%ecx) // emins[1]
+ flds pl_normal+8(%edx)
+ fxch %st(2)
+ fmuls 4(%ebx) // emaxs[1]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 8(%ebx) // emaxs[2]
+ fxch %st(5)
+ faddp %st(0),%st(3)
+ fmuls 8(%ecx) // emins[2]
+ fxch %st(1)
+ faddp %st(0),%st(3)
+ fxch %st(3)
+ faddp %st(0),%st(2)
+
+ jmp LSetSides
+
+//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
+//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
+Lcase3:
+ fmuls (%ecx) // emins[0]
+ flds pl_normal+4(%edx)
+ fxch %st(2)
+ fmuls (%ebx) // emaxs[0]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 4(%ecx) // emins[1]
+ flds pl_normal+8(%edx)
+ fxch %st(2)
+ fmuls 4(%ebx) // emaxs[1]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 8(%ebx) // emaxs[2]
+ fxch %st(5)
+ faddp %st(0),%st(3)
+ fmuls 8(%ecx) // emins[2]
+ fxch %st(1)
+ faddp %st(0),%st(3)
+ fxch %st(3)
+ faddp %st(0),%st(2)
+
+ jmp LSetSides
+
+//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
+//dist2= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
+Lcase4:
+ fmuls (%ebx) // emaxs[0]
+ flds pl_normal+4(%edx)
+ fxch %st(2)
+ fmuls (%ecx) // emins[0]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 4(%ebx) // emaxs[1]
+ flds pl_normal+8(%edx)
+ fxch %st(2)
+ fmuls 4(%ecx) // emins[1]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 8(%ecx) // emins[2]
+ fxch %st(5)
+ faddp %st(0),%st(3)
+ fmuls 8(%ebx) // emaxs[2]
+ fxch %st(1)
+ faddp %st(0),%st(3)
+ fxch %st(3)
+ faddp %st(0),%st(2)
+
+ jmp LSetSides
+
+//dist1= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
+//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
+Lcase5:
+ fmuls (%ecx) // emins[0]
+ flds pl_normal+4(%edx)
+ fxch %st(2)
+ fmuls (%ebx) // emaxs[0]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 4(%ebx) // emaxs[1]
+ flds pl_normal+8(%edx)
+ fxch %st(2)
+ fmuls 4(%ecx) // emins[1]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 8(%ecx) // emins[2]
+ fxch %st(5)
+ faddp %st(0),%st(3)
+ fmuls 8(%ebx) // emaxs[2]
+ fxch %st(1)
+ faddp %st(0),%st(3)
+ fxch %st(3)
+ faddp %st(0),%st(2)
+
+ jmp LSetSides
+
+//dist1= p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
+//dist2= p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
+Lcase6:
+ fmuls (%ebx) // emaxs[0]
+ flds pl_normal+4(%edx)
+ fxch %st(2)
+ fmuls (%ecx) // emins[0]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 4(%ecx) // emins[1]
+ flds pl_normal+8(%edx)
+ fxch %st(2)
+ fmuls 4(%ebx) // emaxs[1]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 8(%ecx) // emins[2]
+ fxch %st(5)
+ faddp %st(0),%st(3)
+ fmuls 8(%ebx) // emaxs[2]
+ fxch %st(1)
+ faddp %st(0),%st(3)
+ fxch %st(3)
+ faddp %st(0),%st(2)
+
+ jmp LSetSides
+
+//dist1= p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
+//dist2= p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
+Lcase7:
+ fmuls (%ecx) // emins[0]
+ flds pl_normal+4(%edx)
+ fxch %st(2)
+ fmuls (%ebx) // emaxs[0]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 4(%ecx) // emins[1]
+ flds pl_normal+8(%edx)
+ fxch %st(2)
+ fmuls 4(%ebx) // emaxs[1]
+ fxch %st(2)
+ fld %st(0)
+ fmuls 8(%ecx) // emins[2]
+ fxch %st(5)
+ faddp %st(0),%st(3)
+ fmuls 8(%ebx) // emaxs[2]
+ fxch %st(1)
+ faddp %st(0),%st(3)
+ fxch %st(3)
+ faddp %st(0),%st(2)
+
+LSetSides:
+
+// sides = 0;
+// if (dist1 >= p->dist)
+// sides = 1;
+// if (dist2 < p->dist)
+// sides |= 2;
+
+ faddp %st(0),%st(2) // dist1 | dist2
+ fcomps pl_dist(%edx)
+ xorl %ecx,%ecx
+ fnstsw %ax
+ fcomps pl_dist(%edx)
+ andb $1,%ah
+ xorb $1,%ah
+ addb %ah,%cl
+
+ fnstsw %ax
+ andb $1,%ah
+ addb %ah,%ah
+ addb %ah,%cl
+
+// return sides;
+
+ popl %ebx
+ movl %ecx,%eax // return status
+
+ ret
+
+
+Lerror:
+ movl 1, %eax
+ ret
+
+#endif // id386
diff --git a/src/unix/qasm.h b/src/unix/qasm.h
new file mode 100644
index 0000000..9ebcb5f
--- /dev/null
+++ b/src/unix/qasm.h
@@ -0,0 +1,51 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+#ifndef __ASM_I386__
+#define __ASM_I386__
+
+#include "../qcommon/q_platform.h"
+
+#if defined(__MINGW32__) || defined(MACOS_X)
+#undef ELF
+#endif
+
+#ifdef __ELF__
+.section .note.GNU-stack,"",@progbits
+#endif
+
+#ifdef ELF
+#define C(label) label
+#else
+#define C(label) _##label
+#endif
+
+// plane_t structure
+// !!! if this is changed, it must be changed in q_shared.h too !!!
+#define pl_normal 0
+#define pl_dist 12
+#define pl_type 16
+#define pl_signbits 17
+#define pl_pad 18
+#define pl_size 20
+
+#endif
diff --git a/src/unix/sdl_glimp.c b/src/unix/sdl_glimp.c
new file mode 100644
index 0000000..dcfa0a8
--- /dev/null
+++ b/src/unix/sdl_glimp.c
@@ -0,0 +1,1755 @@
+
+#if USE_SDL_VIDEO
+
+/*
+ * SDL implementation for Quake 3: Arena's GPL source release.
+ *
+ * I wrote such a beast originally for Loki's port of Heavy Metal: FAKK2,
+ * and then wrote it again for the Linux client of Medal of Honor: Allied
+ * Assault. Third time's a charm, so I'm rewriting this once more for the
+ * GPL release of Quake 3.
+ *
+ * Written by Ryan C. Gordon (icculus@icculus.org). Please refer to
+ * http://ioquake3.org/ for the latest version of this code.
+ *
+ * Patches and comments are welcome at the above address.
+ *
+ * I cut-and-pasted this from linux_glimp.c, and moved it to SDL line-by-line.
+ * There is probably some cruft that could be removed here.
+ *
+ * You should define USE_SDL=1 and then add this to the makefile.
+ * USE_SDL will disable the X11 target.
+ */
+
+/*
+Original copyright on Q3A sources:
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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
+** GLimp_SetGamma
+**
+*/
+
+#include "SDL.h"
+
+#ifdef SMP
+#include "SDL_thread.h"
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if USE_SDL_VIDEO
+#include "SDL.h"
+#include "SDL_loadso.h"
+#else
+#include <dlfcn.h>
+#endif
+
+#include "../renderer/tr_local.h"
+#include "../client/client.h"
+#include "linux_local.h" // bk001130
+
+#include "unix_glw.h"
+
+
+/* Just hack it for now. */
+#ifdef MACOS_X
+#include <IOKit/hidsystem/IOHIDLib.h>
+#include <IOKit/hidsystem/IOHIDParameter.h>
+#include <drivers/event_status_driver.h>
+typedef CGLContextObj QGLContext;
+#define GLimp_GetCurrentContext() CGLGetCurrentContext()
+#define GLimp_SetCurrentContext(ctx) CGLSetCurrentContext(ctx)
+#else
+typedef void *QGLContext;
+#define GLimp_GetCurrentContext() (NULL)
+#define GLimp_SetCurrentContext(ctx)
+#endif
+
+static QGLContext opengl_context;
+
+//#define KBD_DBG
+
+typedef enum
+{
+ RSERR_OK,
+
+ RSERR_INVALID_FULLSCREEN,
+ RSERR_INVALID_MODE,
+
+ RSERR_UNKNOWN
+} rserr_t;
+
+glwstate_t glw_state;
+
+static SDL_Surface *screen = NULL;
+static SDL_Joystick *stick = NULL;
+
+static qboolean mouse_avail = qfalse;
+static qboolean mouse_active = qfalse;
+static qboolean sdlrepeatenabled = qfalse;
+
+static cvar_t *in_mouse;
+static cvar_t *in_disablemacosxmouseaccel;
+#ifdef MACOS_X
+static double originalMouseSpeed = -1.0;
+#endif
+cvar_t *in_subframe;
+cvar_t *in_nograb; // this is strictly for developers
+
+// bk001130 - from cvs1.17 (mkv), but not static
+cvar_t *in_joystick = NULL;
+cvar_t *in_joystickDebug = NULL;
+cvar_t *joy_threshold = NULL;
+
+cvar_t *r_allowSoftwareGL; // don't abort out if the pixelformat claims software
+cvar_t *r_previousglDriver;
+
+qboolean GLimp_sdl_init_video(void)
+{
+ if (!SDL_WasInit(SDL_INIT_VIDEO))
+ {
+ ri.Printf( PRINT_ALL, "Calling SDL_Init(SDL_INIT_VIDEO)...\n");
+ if (SDL_Init(SDL_INIT_VIDEO) == -1)
+ {
+ ri.Printf( PRINT_ALL, "SDL_Init(SDL_INIT_VIDEO) failed: %s\n", SDL_GetError());
+ return qfalse;
+ }
+ ri.Printf( PRINT_ALL, "SDL_Init(SDL_INIT_VIDEO) passed.\n");
+ }
+
+ return qtrue;
+}
+
+
+/*
+* Find the first occurrence of find in s.
+*/
+// bk001130 - from cvs1.17 (mkv), const
+// bk001130 - made first argument const
+static const char *Q_stristr( const char *s, const char *find)
+{
+ register char c, sc;
+ register size_t len;
+
+ if ((c = *find++) != 0)
+ {
+ if (c >= 'a' && c <= 'z')
+ {
+ c -= ('a' - 'A');
+ }
+ len = strlen(find);
+ do
+ {
+ do
+ {
+ if ((sc = *s++) == 0)
+ return NULL;
+ if (sc >= 'a' && sc <= 'z')
+ {
+ sc -= ('a' - 'A');
+ }
+ } while (sc != c);
+ } while (Q_stricmpn(s, find, len) != 0);
+ s--;
+ }
+ return s;
+}
+
+static const char *XLateKey(SDL_keysym *keysym, int *key)
+{
+ static char buf[2] = { '\0', '\0' };
+ *key = 0;
+
+ *buf = '\0';
+
+ // these happen to match the ASCII chars.
+ if ((keysym->sym >= ' ') && (keysym->sym <= '~'))
+ {
+ *key = (int) keysym->sym;
+ }
+ else
+ switch (keysym->sym)
+ {
+ case SDLK_PAGEUP: *key = K_PGUP; break;
+ case SDLK_KP9: *key = K_KP_PGUP; break;
+ case SDLK_PAGEDOWN: *key = K_PGDN; break;
+ case SDLK_KP3: *key = K_KP_PGDN; break;
+ case SDLK_KP7: *key = K_KP_HOME; break;
+ case SDLK_HOME: *key = K_HOME; break;
+ case SDLK_KP1: *key = K_KP_END; break;
+ case SDLK_END: *key = K_END; break;
+ case SDLK_KP4: *key = K_KP_LEFTARROW; break;
+ case SDLK_LEFT: *key = K_LEFTARROW; break;
+ case SDLK_KP6: *key = K_KP_RIGHTARROW; break;
+ case SDLK_RIGHT: *key = K_RIGHTARROW; break;
+ case SDLK_KP2: *key = K_KP_DOWNARROW; break;
+ case SDLK_DOWN: *key = K_DOWNARROW; break;
+ case SDLK_KP8: *key = K_KP_UPARROW; break;
+ case SDLK_UP: *key = K_UPARROW; break;
+ case SDLK_ESCAPE: *key = K_ESCAPE; break;
+ case SDLK_KP_ENTER: *key = K_KP_ENTER; break;
+ case SDLK_RETURN: *key = K_ENTER; break;
+ case SDLK_TAB: *key = K_TAB; break;
+ case SDLK_F1: *key = K_F1; break;
+ case SDLK_F2: *key = K_F2; break;
+ case SDLK_F3: *key = K_F3; break;
+ case SDLK_F4: *key = K_F4; break;
+ case SDLK_F5: *key = K_F5; break;
+ case SDLK_F6: *key = K_F6; break;
+ case SDLK_F7: *key = K_F7; break;
+ case SDLK_F8: *key = K_F8; break;
+ case SDLK_F9: *key = K_F9; break;
+ case SDLK_F10: *key = K_F10; break;
+ case SDLK_F11: *key = K_F11; break;
+ case SDLK_F12: *key = K_F12; break;
+ case SDLK_F13: *key = K_F13; break;
+ case SDLK_F14: *key = K_F14; break;
+ case SDLK_F15: *key = K_F15; break;
+
+ // bk001206 - from Ryan's Fakk2
+ case SDLK_BACKSPACE: *key = K_BACKSPACE; break; // ctrl-h
+ case SDLK_KP_PERIOD: *key = K_KP_DEL; break;
+ case SDLK_DELETE: *key = K_DEL; break;
+ case SDLK_PAUSE: *key = K_PAUSE; break;
+
+ case SDLK_LSHIFT:
+ case SDLK_RSHIFT: *key = K_SHIFT; break;
+
+ case SDLK_LCTRL:
+ case SDLK_RCTRL: *key = K_CTRL; break;
+
+ case SDLK_RMETA:
+ case SDLK_LMETA:
+ case SDLK_RALT:
+ case SDLK_LALT: *key = K_ALT; break;
+
+ case SDLK_LSUPER:
+ case SDLK_RSUPER: *key = K_SUPER; break;
+
+ case SDLK_KP5: *key = K_KP_5; break;
+ case SDLK_INSERT: *key = K_INS; break;
+ case SDLK_KP0: *key = K_KP_INS; break;
+ case SDLK_KP_MULTIPLY: *key = K_KP_STAR; break;
+ case SDLK_KP_PLUS: *key = K_KP_PLUS; break;
+ case SDLK_KP_MINUS: *key = K_KP_MINUS; break;
+ case SDLK_KP_DIVIDE: *key = K_KP_SLASH; break;
+
+ case SDLK_MODE: *key = K_MODE; break;
+ case SDLK_COMPOSE: *key = K_COMPOSE; break;
+ case SDLK_HELP: *key = K_HELP; break;
+ case SDLK_PRINT: *key = K_PRINT; break;
+ case SDLK_SYSREQ: *key = K_SYSREQ; break;
+ case SDLK_BREAK: *key = K_BREAK; break;
+ case SDLK_MENU: *key = K_MENU; break;
+ case SDLK_POWER: *key = K_POWER; break;
+ case SDLK_EURO: *key = K_EURO; break;
+ case SDLK_UNDO: * key = K_UNDO; break;
+ case SDLK_SCROLLOCK: *key = K_SCROLLOCK; break;
+ case SDLK_NUMLOCK: *key = K_KP_NUMLOCK; break;
+ case SDLK_CAPSLOCK: *key = K_CAPSLOCK; break;
+
+ default:
+ if (keysym->sym >= SDLK_WORLD_0 && keysym->sym <= SDLK_WORLD_95)
+ *key = (keysym->sym - SDLK_WORLD_0) + K_WORLD_0;
+ break;
+ }
+
+ if( keysym->unicode <= 127 ) // maps to ASCII?
+ {
+ char ch = (char) keysym->unicode;
+ if (ch == '~')
+ *key = '~'; // console HACK
+
+ // The X11 driver converts to lowercase, but apparently we shouldn't.
+ // There's possibly somewhere else where they covert back. Passing
+ // uppercase to the engine works fine and fixes all-lower input.
+ // (https://bugzilla.icculus.org/show_bug.cgi?id=2364) --ryan.
+ //else if (ch >= 'A' && ch <= 'Z')
+ // ch = ch - 'A' + 'a';
+
+ // translate K_BACKSPACE to ctrl-h for MACOS_X (others?)
+ if (ch == K_BACKSPACE && keysym->sym != SDLK_DELETE)
+ {
+ *key = 'h' - 'a' + 1;
+ buf[0] = *key;
+ }
+ else
+ buf[0] = ch;
+ }
+
+ return buf;
+}
+
+static void install_grabs(void)
+{
+ SDL_WM_GrabInput(SDL_GRAB_ON);
+ SDL_ShowCursor(0);
+
+ // This is a bug in the current SDL/macosx...have to toggle it a few
+ // times to get the cursor to hide.
+#if defined(MACOS_X)
+ SDL_ShowCursor(1);
+ SDL_ShowCursor(0);
+#endif
+}
+
+static void uninstall_grabs(void)
+{
+ SDL_ShowCursor(1);
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+}
+
+static void printkey(const SDL_Event* event)
+{
+#ifdef KBD_DBG
+ printf("key name: %s", SDL_GetKeyName(event->key.keysym.sym));
+ if(event->key.keysym.unicode)
+ {
+ printf(" unicode: %hx", event->key.keysym.unicode);
+ if (event->key.keysym.unicode >= '0'
+ && event->key.keysym.unicode <= '~') // printable?
+ printf(" (%c)", (unsigned char)(event->key.keysym.unicode));
+ }
+ puts("");
+#endif
+}
+
+static void HandleEvents(void)
+{
+ const int t = 0; // always just use the current time.
+ SDL_Event e;
+ const char *p = NULL;
+ int key = 0;
+
+ if (screen == NULL)
+ return; // no SDL context.
+
+ if (cls.keyCatchers == 0)
+ {
+ if (sdlrepeatenabled)
+ {
+ SDL_EnableKeyRepeat(0, 0);
+ sdlrepeatenabled = qfalse;
+ }
+ }
+ else
+ {
+ if (!sdlrepeatenabled)
+ {
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ sdlrepeatenabled = qtrue;
+ }
+ }
+
+ while (SDL_PollEvent(&e))
+ {
+ switch (e.type)
+ {
+ case SDL_KEYDOWN:
+ printkey(&e);
+ p = XLateKey(&e.key.keysym, &key);
+ if (key)
+ {
+ Sys_QueEvent( t, SE_KEY, key, qtrue, 0, NULL );
+ }
+ if (p)
+ {
+ while (*p)
+ {
+ Sys_QueEvent( t, SE_CHAR, *p++, 0, 0, NULL );
+ }
+ }
+ break;
+
+ case SDL_KEYUP:
+ XLateKey(&e.key.keysym, &key);
+ Sys_QueEvent( t, SE_KEY, key, qfalse, 0, NULL );
+ break;
+
+ case SDL_MOUSEMOTION:
+ if (mouse_active)
+ {
+ Sys_QueEvent( t, SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, NULL );
+ }
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ {
+ unsigned char b;
+ switch (e.button.button)
+ {
+ case 1: b = K_MOUSE1; break;
+ case 2: b = K_MOUSE3; break;
+ case 3: b = K_MOUSE2; break;
+ case 4: b = K_MWHEELUP; break;
+ case 5: b = K_MWHEELDOWN; break;
+ case 6: b = K_MOUSE4; break;
+ case 7: b = K_MOUSE5; break;
+ default: b = K_AUX1 + (e.button.button - 8)%16; break;
+ }
+ Sys_QueEvent( t, SE_KEY, b, (e.type == SDL_MOUSEBUTTONDOWN?qtrue:qfalse), 0, NULL );
+ }
+ break;
+
+ case SDL_QUIT:
+ Sys_Quit();
+ break;
+ }
+ }
+}
+
+// NOTE TTimo for the tty console input, we didn't rely on those ..
+// it's not very surprising actually cause they are not used otherwise
+void KBD_Init(void)
+{
+}
+
+void KBD_Close(void)
+{
+}
+
+#ifdef MACOS_X
+io_connect_t IN_GetIOHandle() // mac os x mouse accel hack
+ {
+ io_connect_t iohandle = MACH_PORT_NULL;
+ kern_return_t status;
+ io_service_t iohidsystem = MACH_PORT_NULL;
+ mach_port_t masterport;
+
+ status = IOMasterPort(MACH_PORT_NULL, &masterport);
+ if(status != KERN_SUCCESS)
+ return 0;
+
+ iohidsystem = IORegistryEntryFromPath(masterport, kIOServicePlane ":/IOResources/IOHIDSystem");
+ if(!iohidsystem)
+ return 0;
+
+ status = IOServiceOpen(iohidsystem, mach_task_self(), kIOHIDParamConnectType, &iohandle);
+ IOObjectRelease(iohidsystem);
+
+ return iohandle;
+ }
+#endif
+
+void IN_ActivateMouse( void )
+{
+ if (!mouse_avail || !screen)
+ return;
+
+ #ifdef MACOS_X
+ if (!mouse_active && mouse_avail) // mac os x mouse accel hack
+ {
+ // Save the status of mouse acceleration
+ originalMouseSpeed = -1.0; // in case of error
+ if(in_disablemacosxmouseaccel->integer)
+ {
+ io_connect_t mouseDev = IN_GetIOHandle();
+ if(mouseDev != 0)
+ {
+ if(IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess)
+ {
+ Com_Printf("previous mouse acceleration: %f\n", originalMouseSpeed);
+ if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess)
+ {
+ Com_Printf("Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
+ Cvar_Set ("in_disablemacosxmouseaccel", 0);
+ }
+ }
+ else
+ {
+ Com_Printf("Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n");
+ Cvar_Set ("in_disablemacosxmouseaccel", 0);
+ }
+ IOServiceClose(mouseDev);
+ }
+ else
+ {
+ Com_Printf("Could not disable mouse acceleration (failed at IO_GetIOHandle).\n");
+ Cvar_Set ("in_disablemacosxmouseaccel", 0);
+ }
+ }
+ }
+ #endif
+
+ if (!mouse_active)
+ {
+ if (!in_nograb->value)
+ install_grabs();
+ mouse_active = qtrue;
+ }
+}
+
+void IN_DeactivateMouse( void )
+{
+ if (!mouse_avail || !screen)
+ return;
+
+ #ifdef MACOS_X
+ if (mouse_active) // mac os x mouse accel hack
+ {
+ if(originalMouseSpeed != -1.0)
+ {
+ io_connect_t mouseDev = IN_GetIOHandle();
+ if(mouseDev != 0)
+ {
+ Com_Printf("restoring mouse acceleration to: %f\n", originalMouseSpeed);
+ if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess)
+ Com_Printf("Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
+ IOServiceClose(mouseDev);
+ }
+ else
+ Com_Printf("Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n");
+ }
+ }
+ #endif
+
+ if (mouse_active)
+ {
+ if (!in_nograb->value)
+ uninstall_grabs();
+ mouse_active = qfalse;
+ }
+}
+/*****************************************************************************/
+
+/*
+** GLimp_SetGamma
+**
+** This routine should only be called if glConfig.deviceSupportsGamma is TRUE
+*/
+void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] )
+{
+ Uint16 table[3][256];
+ int i, j;
+// float g;
+
+ if(r_ignorehwgamma->integer)
+ return;
+
+ // taken from win_gamma.c:
+ for (i = 0; i < 256; i++)
+ {
+ table[0][i] = ( ( ( Uint16 ) red[i] ) << 8 ) | red[i];
+ table[1][i] = ( ( ( Uint16 ) green[i] ) << 8 ) | green[i];
+ table[2][i] = ( ( ( Uint16 ) blue[i] ) << 8 ) | blue[i];
+ }
+
+ // enforce constantly increasing
+ for (j = 0; j < 3; j++)
+ {
+ for (i = 1; i < 256; i++)
+ {
+ if (table[j][i] < table[j][i-1])
+ table[j][i] = table[j][i-1];
+ }
+ }
+
+ SDL_SetGammaRamp(table[0], table[1], table[2]);
+
+// g = Cvar_Get("r_gamma", "1.0", 0)->value;
+// SDL_SetGamma(g, g, g);
+}
+
+/*
+** 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 )
+{
+ IN_Shutdown();
+ screen = NULL;
+
+ memset( &glConfig, 0, sizeof( glConfig ) );
+ memset( &glState, 0, sizeof( glState ) );
+
+ QGL_Shutdown();
+}
+
+/*
+** GLimp_LogComment
+*/
+void GLimp_LogComment( char *comment )
+{
+ if ( glw_state.log_fp )
+ {
+ fprintf( glw_state.log_fp, "%s", comment );
+ }
+}
+
+/*
+** GLW_StartDriverAndSetMode
+*/
+// bk001204 - prototype needed
+static int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen );
+static qboolean GLW_StartDriverAndSetMode( const char *drivername,
+ int mode,
+ qboolean fullscreen )
+{
+ rserr_t err;
+
+ if (GLimp_sdl_init_video() == qfalse)
+ return qfalse;
+
+ // don't ever bother going into fullscreen with a voodoo card
+#if 1 // JDC: I reenabled this
+ if ( Q_stristr( drivername, "Voodoo" ) )
+ {
+ ri.Cvar_Set( "r_fullscreen", "0" );
+ r_fullscreen->modified = qfalse;
+ fullscreen = qfalse;
+ }
+#endif
+
+ if (fullscreen && in_nograb->value)
+ {
+ ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
+ ri.Cvar_Set( "r_fullscreen", "0" );
+ r_fullscreen->modified = qfalse;
+ fullscreen = qfalse;
+ }
+
+ err = GLW_SetMode( drivername, mode, fullscreen );
+
+ switch ( err )
+ {
+ case RSERR_INVALID_FULLSCREEN:
+ ri.Printf( PRINT_ALL, "...WARNING: fullscreen unavailable in this mode\n" );
+ return qfalse;
+ case RSERR_INVALID_MODE:
+ ri.Printf( PRINT_ALL, "...WARNING: could not set the given mode (%d)\n", mode );
+ return qfalse;
+ default:
+ break;
+ }
+ return qtrue;
+}
+
+/*
+** GLW_SetMode
+*/
+static int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen )
+{
+ const char* glstring; // bk001130 - from cvs1.17 (mkv)
+ int sdlcolorbits;
+ int colorbits, depthbits, stencilbits;
+ int tcolorbits, tdepthbits, tstencilbits;
+ int i = 0;
+ SDL_Surface *vidscreen = NULL;
+
+ ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");
+
+ ri.Printf (PRINT_ALL, "...setting mode %d:", mode );
+
+ if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
+ {
+ ri.Printf( PRINT_ALL, " invalid mode\n" );
+ return RSERR_INVALID_MODE;
+ }
+ ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);
+
+ Uint32 flags = SDL_OPENGL;
+ if (fullscreen)
+ {
+ flags |= SDL_FULLSCREEN;
+ glConfig.isFullscreen = qtrue;
+ }
+ else
+ glConfig.isFullscreen = qfalse;
+
+ if (!r_colorbits->value)
+ colorbits = 24;
+ else
+ colorbits = r_colorbits->value;
+
+ if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) )
+ colorbits = 16;
+
+ if (!r_depthbits->value)
+ depthbits = 24;
+ else
+ depthbits = r_depthbits->value;
+ stencilbits = r_stencilbits->value;
+
+ for (i = 0; i < 16; i++)
+ {
+ // 0 - default
+ // 1 - minus colorbits
+ // 2 - minus depthbits
+ // 3 - minus stencil
+ if ((i % 4) == 0 && i)
+ {
+ // one pass, reduce
+ switch (i / 4)
+ {
+ case 2 :
+ if (colorbits == 24)
+ colorbits = 16;
+ break;
+ case 1 :
+ if (depthbits == 24)
+ depthbits = 16;
+ else if (depthbits == 16)
+ depthbits = 8;
+ case 3 :
+ if (stencilbits == 24)
+ stencilbits = 16;
+ else if (stencilbits == 16)
+ stencilbits = 8;
+ }
+ }
+
+ tcolorbits = colorbits;
+ tdepthbits = depthbits;
+ tstencilbits = stencilbits;
+
+ if ((i % 4) == 3)
+ { // reduce colorbits
+ if (tcolorbits == 24)
+ tcolorbits = 16;
+ }
+
+ if ((i % 4) == 2)
+ { // reduce depthbits
+ if (tdepthbits == 24)
+ tdepthbits = 16;
+ else if (tdepthbits == 16)
+ tdepthbits = 8;
+ }
+
+ if ((i % 4) == 1)
+ { // reduce stencilbits
+ if (tstencilbits == 24)
+ tstencilbits = 16;
+ else if (tstencilbits == 16)
+ tstencilbits = 8;
+ else
+ tstencilbits = 0;
+ }
+
+ sdlcolorbits = 4;
+ if (tcolorbits == 24)
+ sdlcolorbits = 8;
+
+ SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
+ SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
+ SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
+ SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
+ SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+#if SDL_VERSION_ATLEAST( 1, 2, 10 )
+ if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) )
+ ri.Printf( PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n" );
+#else
+ #warning libSDL >= 1.2.10 required for r_swapInterval support
+#endif // SDL_GL_SWAP_CONTROL
+
+ SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_ICON);
+ SDL_ShowCursor(0);
+ SDL_EnableUNICODE(1);
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ sdlrepeatenabled = qtrue;
+
+ if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
+ {
+ fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
+ continue;
+ }
+
+ opengl_context = GLimp_GetCurrentContext();
+
+ ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
+ sdlcolorbits, sdlcolorbits, sdlcolorbits,
+ tdepthbits, tstencilbits);
+
+ glConfig.colorBits = tcolorbits;
+ glConfig.depthBits = tdepthbits;
+ glConfig.stencilBits = tstencilbits;
+ break;
+ }
+
+ if (!vidscreen)
+ {
+ ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
+ return RSERR_INVALID_MODE;
+ }
+
+ screen = vidscreen;
+
+ // bk001130 - from cvs1.17 (mkv)
+ glstring = (char *) qglGetString (GL_RENDERER);
+ ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );
+
+ // bk010122 - new software token (Indirect)
+ if ( !Q_stricmp( glstring, "Mesa X11")
+ || !Q_stricmp( glstring, "Mesa GLX Indirect") )
+ {
+ if ( !r_allowSoftwareGL->integer )
+ {
+ ri.Printf( PRINT_ALL, "\n\n***********************************************************\n" );
+ ri.Printf( PRINT_ALL, " You are using software Mesa (no hardware acceleration)! \n" );
+ ri.Printf( PRINT_ALL, " Driver DLL used: %s\n", drivername );
+ ri.Printf( PRINT_ALL, " If this is intentional, add\n" );
+ ri.Printf( PRINT_ALL, " \"+set r_allowSoftwareGL 1\"\n" );
+ ri.Printf( PRINT_ALL, " to the command line when starting the game.\n" );
+ ri.Printf( PRINT_ALL, "***********************************************************\n");
+ GLimp_Shutdown( );
+ return RSERR_INVALID_MODE;
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...using software Mesa (r_allowSoftwareGL==1).\n" );
+ }
+ }
+
+ return RSERR_OK;
+}
+
+/*
+** GLW_InitExtensions
+*/
+static void GLW_InitExtensions( void )
+{
+ if ( !r_allowExtensions->integer )
+ {
+ ri.Printf( PRINT_ALL, "*** IGNORING OPENGL EXTENSIONS ***\n" );
+ return;
+ }
+
+ ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
+
+ // GL_S3_s3tc
+ if ( Q_stristr( glConfig.extensions_string, "GL_S3_s3tc" ) )
+ {
+ if ( r_ext_compressed_textures->value )
+ {
+ glConfig.textureCompression = TC_S3TC;
+ ri.Printf( PRINT_ALL, "...using GL_S3_s3tc\n" );
+ } else
+ {
+ glConfig.textureCompression = TC_NONE;
+ ri.Printf( PRINT_ALL, "...ignoring GL_S3_s3tc\n" );
+ }
+ } else
+ {
+ glConfig.textureCompression = TC_NONE;
+ ri.Printf( PRINT_ALL, "...GL_S3_s3tc not found\n" );
+ }
+
+ // GL_EXT_texture_env_add
+ glConfig.textureEnvAddAvailable = qfalse;
+ if ( Q_stristr( glConfig.extensions_string, "EXT_texture_env_add" ) )
+ {
+ if ( r_ext_texture_env_add->integer )
+ {
+ glConfig.textureEnvAddAvailable = qtrue;
+ ri.Printf( PRINT_ALL, "...using GL_EXT_texture_env_add\n" );
+ } else
+ {
+ glConfig.textureEnvAddAvailable = qfalse;
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_env_add\n" );
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_env_add not found\n" );
+ }
+
+ // GL_ARB_multitexture
+ qglMultiTexCoord2fARB = NULL;
+ qglActiveTextureARB = NULL;
+ qglClientActiveTextureARB = NULL;
+ if ( Q_stristr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
+ {
+ if ( r_ext_multitexture->value )
+ {
+ qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) SDL_GL_GetProcAddress( "glMultiTexCoord2fARB" );
+ qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glActiveTextureARB" );
+ qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glClientActiveTextureARB" );
+
+ if ( qglActiveTextureARB )
+ {
+ GLint glint = 0;
+ qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glint );
+ glConfig.maxActiveTextures = (int) glint;
+ if ( glConfig.maxActiveTextures > 1 )
+ {
+ ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
+ } else
+ {
+ qglMultiTexCoord2fARB = NULL;
+ qglActiveTextureARB = NULL;
+ qglClientActiveTextureARB = NULL;
+ ri.Printf( PRINT_ALL, "...not using GL_ARB_multitexture, < 2 texture units\n" );
+ }
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" );
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" );
+ }
+
+ // GL_EXT_compiled_vertex_array
+ if ( Q_stristr( glConfig.extensions_string, "GL_EXT_compiled_vertex_array" ) )
+ {
+ if ( r_ext_compiled_vertex_array->value )
+ {
+ ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
+ qglLockArraysEXT = ( void ( APIENTRY * )( GLint, GLint ) ) SDL_GL_GetProcAddress( "glLockArraysEXT" );
+ qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) SDL_GL_GetProcAddress( "glUnlockArraysEXT" );
+ if (!qglLockArraysEXT || !qglUnlockArraysEXT)
+ {
+ ri.Error (ERR_FATAL, "bad getprocaddress");
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_compiled_vertex_array\n" );
+ }
+ } else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
+ }
+
+ glConfig.textureFilterAnisotropic = qfalse;
+ if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) )
+ {
+ if ( r_ext_texture_filter_anisotropic->integer ) {
+ qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxAnisotropy );
+ if ( glConfig.maxAnisotropy <= 0 ) {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" );
+ glConfig.maxAnisotropy = 0;
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", glConfig.maxAnisotropy );
+ glConfig.textureFilterAnisotropic = qtrue;
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" );
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" );
+ }
+}
+
+static void GLW_InitGamma( void )
+{
+ glConfig.deviceSupportsGamma = qtrue;
+}
+
+/*
+** GLW_LoadOpenGL
+**
+** GLimp_win.c internal function that that attempts to load and use
+** a specific OpenGL DLL.
+*/
+static qboolean GLW_LoadOpenGL( const char *name )
+{
+ qboolean fullscreen;
+
+ ri.Printf( PRINT_ALL, "...loading %s:\n", name );
+
+ // disable the 3Dfx splash screen and set gamma
+ // we do this all the time, but it shouldn't hurt anything
+ // on non-3Dfx stuff
+ putenv("FX_GLIDE_NO_SPLASH=0");
+
+ // Mesa VooDoo hacks
+ putenv("MESA_GLX_FX=fullscreen\n");
+
+ // load the QGL layer
+ if ( QGL_Init( name ) )
+ {
+ fullscreen = r_fullscreen->integer;
+
+ // create the window and set up the context
+ if ( !GLW_StartDriverAndSetMode( name, r_mode->integer, fullscreen ) )
+ {
+ if (r_mode->integer != 3)
+ {
+ if ( !GLW_StartDriverAndSetMode( name, 3, fullscreen ) )
+ {
+ goto fail;
+ }
+ } else
+ goto fail;
+ }
+
+ return qtrue;
+ } else
+ {
+ ri.Printf( PRINT_ALL, "failed\n" );
+ }
+ fail:
+
+ QGL_Shutdown();
+
+ return qfalse;
+}
+
+
+/*
+** GLimp_Init
+**
+** This routine is responsible for initializing the OS specific portions
+** of OpenGL.
+*/
+void GLimp_Init( void )
+{
+ qboolean attemptedlibGL = qfalse;
+ qboolean attempted3Dfx = qfalse;
+ qboolean success = qfalse;
+
+ r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH );
+
+ r_previousglDriver = ri.Cvar_Get( "r_previousglDriver", "", CVAR_ROM );
+
+ InitSig();
+
+ IN_Init(); // rcg08312005 moved into glimp.
+
+ // Hack here so that if the UI
+ if ( *r_previousglDriver->string )
+ {
+ // The UI changed it on us, hack it back
+ // This means the renderer can't be changed on the fly
+ ri.Cvar_Set( "r_glDriver", r_previousglDriver->string );
+ }
+
+ //
+ // load and initialize the specific OpenGL driver
+ //
+ if ( !GLW_LoadOpenGL( r_glDriver->string ) )
+ {
+ if ( !Q_stricmp( r_glDriver->string, OPENGL_DRIVER_NAME ) )
+ {
+ attemptedlibGL = qtrue;
+ } else if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) )
+ {
+ attempted3Dfx = qtrue;
+ }
+
+ #if 0
+ // TTimo
+ // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=455
+ // old legacy load code, was confusing people who had a bad OpenGL setup
+ if ( !attempted3Dfx && !success )
+ {
+ attempted3Dfx = qtrue;
+ if ( GLW_LoadOpenGL( _3DFX_DRIVER_NAME ) )
+ {
+ ri.Cvar_Set( "r_glDriver", _3DFX_DRIVER_NAME );
+ r_glDriver->modified = qfalse;
+ success = qtrue;
+ }
+ }
+ #endif
+
+ // try ICD before trying 3Dfx standalone driver
+ if ( !attemptedlibGL && !success )
+ {
+ attemptedlibGL = qtrue;
+ if ( GLW_LoadOpenGL( OPENGL_DRIVER_NAME ) )
+ {
+ ri.Cvar_Set( "r_glDriver", OPENGL_DRIVER_NAME );
+ r_glDriver->modified = qfalse;
+ success = qtrue;
+ }
+ }
+
+ if (!success)
+ ri.Error( ERR_FATAL, "GLimp_Init() - could not load OpenGL subsystem\n" );
+
+ }
+
+ // Save it in case the UI stomps it
+ ri.Cvar_Set( "r_previousglDriver", r_glDriver->string );
+
+ // This values force the UI to disable driver selection
+ glConfig.driverType = GLDRV_ICD;
+ glConfig.hardwareType = GLHW_GENERIC;
+
+ // get our config strings
+ Q_strncpyz( glConfig.vendor_string, (char *) qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) );
+ Q_strncpyz( glConfig.renderer_string, (char *) qglGetString (GL_RENDERER), sizeof( glConfig.renderer_string ) );
+ if (*glConfig.renderer_string && glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] == '\n')
+ glConfig.renderer_string[strlen(glConfig.renderer_string) - 1] = 0;
+ Q_strncpyz( glConfig.version_string, (char *) qglGetString (GL_VERSION), sizeof( glConfig.version_string ) );
+ Q_strncpyz( glConfig.extensions_string, (char *) qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) );
+
+ GL_ResolveHardwareType( );
+
+ ri.Cvar_Set( "r_lastValidRenderer", glConfig.renderer_string );
+
+ // initialize extensions
+ GLW_InitExtensions();
+ GLW_InitGamma();
+
+ InitSig(); // not clear why this is at begin & end of function
+}
+
+
+/*
+** 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)
+{
+ // don't flip if drawing to front buffer
+ if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 )
+ {
+ SDL_GL_SwapBuffers();
+ }
+
+ if( r_fullscreen->modified )
+ {
+ qboolean fullscreen;
+ qboolean sdlToggled = qfalse;
+ SDL_Surface *s = SDL_GetVideoSurface( );
+
+ if( s )
+ {
+ // Find out the current state
+ if( s->flags & SDL_FULLSCREEN )
+ fullscreen = qtrue;
+ else
+ fullscreen = qfalse;
+
+ // Is the state we want different from the current state?
+ if( !!r_fullscreen->integer != fullscreen )
+ sdlToggled = SDL_WM_ToggleFullScreen( s );
+ else
+ sdlToggled = qtrue;
+ }
+
+ // SDL_WM_ToggleFullScreen didn't work, so do it the slow way
+ if( !sdlToggled )
+ Cbuf_AddText( "vid_restart" );
+
+ r_fullscreen->modified = qfalse;
+ }
+
+ // check logging
+ QGL_EnableLogging( (qboolean)r_logFile->integer ); // bk001205 - was ->value
+}
+
+
+
+#ifdef SMP
+/*
+===========================================================
+
+SMP acceleration
+
+===========================================================
+*/
+
+/*
+ * I have no idea if this will even work...most platforms don't offer
+ * thread-safe OpenGL libraries, and it looks like the original Linux
+ * code counted on each thread claiming the GL context with glXMakeCurrent(),
+ * which you can't currently do in SDL. We'll just have to hope for the best.
+ */
+
+static SDL_mutex *smpMutex = NULL;
+static SDL_cond *renderCommandsEvent = NULL;
+static SDL_cond *renderCompletedEvent = NULL;
+static void (*glimpRenderThread)( void ) = NULL;
+static SDL_Thread *renderThread = NULL;
+
+static void GLimp_ShutdownRenderThread(void)
+{
+ if (smpMutex != NULL)
+ {
+ SDL_DestroyMutex(smpMutex);
+ smpMutex = NULL;
+ }
+
+ if (renderCommandsEvent != NULL)
+ {
+ SDL_DestroyCond(renderCommandsEvent);
+ renderCommandsEvent = NULL;
+ }
+
+ if (renderCompletedEvent != NULL)
+ {
+ SDL_DestroyCond(renderCompletedEvent);
+ renderCompletedEvent = NULL;
+ }
+
+ glimpRenderThread = NULL;
+}
+
+static int GLimp_RenderThreadWrapper( void *arg )
+{
+ Com_Printf( "Render thread starting\n" );
+
+ glimpRenderThread();
+
+ GLimp_SetCurrentContext(NULL);
+
+ Com_Printf( "Render thread terminating\n" );
+
+ return 0;
+}
+
+qboolean GLimp_SpawnRenderThread( void (*function)( void ) )
+{
+ static qboolean warned = qfalse;
+ if (!warned)
+ {
+ Com_Printf("WARNING: You enable r_smp at your own risk!\n");
+ warned = qtrue;
+ }
+
+#ifndef MACOS_X
+ return qfalse; /* better safe than sorry for now. */
+#endif
+
+ if (renderThread != NULL) /* hopefully just a zombie at this point... */
+ {
+ Com_Printf("Already a render thread? Trying to clean it up...\n");
+ SDL_WaitThread(renderThread, NULL);
+ renderThread = NULL;
+ GLimp_ShutdownRenderThread();
+ }
+
+ smpMutex = SDL_CreateMutex();
+ if (smpMutex == NULL)
+ {
+ Com_Printf( "smpMutex creation failed: %s\n", SDL_GetError() );
+ GLimp_ShutdownRenderThread();
+ return qfalse;
+ }
+
+ renderCommandsEvent = SDL_CreateCond();
+ if (renderCommandsEvent == NULL)
+ {
+ Com_Printf( "renderCommandsEvent creation failed: %s\n", SDL_GetError() );
+ GLimp_ShutdownRenderThread();
+ return qfalse;
+ }
+
+ renderCompletedEvent = SDL_CreateCond();
+ if (renderCompletedEvent == NULL)
+ {
+ Com_Printf( "renderCompletedEvent creation failed: %s\n", SDL_GetError() );
+ GLimp_ShutdownRenderThread();
+ return qfalse;
+ }
+
+ glimpRenderThread = function;
+ renderThread = SDL_CreateThread(GLimp_RenderThreadWrapper, NULL);
+ if ( renderThread == NULL ) {
+ ri.Printf( PRINT_ALL, "SDL_CreateThread() returned %s", SDL_GetError() );
+ GLimp_ShutdownRenderThread();
+ return qfalse;
+ } else {
+ // !!! FIXME: No detach API available in SDL!
+ //ret = pthread_detach( renderThread );
+ //if ( ret ) {
+ //ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) );
+ //}
+ }
+
+ return qtrue;
+}
+
+static volatile void *smpData = NULL;
+static volatile qboolean smpDataReady;
+
+void *GLimp_RendererSleep( void )
+{
+ void *data = NULL;
+
+ GLimp_SetCurrentContext(NULL);
+
+ SDL_LockMutex(smpMutex);
+ {
+ smpData = NULL;
+ smpDataReady = qfalse;
+
+ // after this, the front end can exit GLimp_FrontEndSleep
+ SDL_CondSignal(renderCompletedEvent);
+
+ while ( !smpDataReady ) {
+ SDL_CondWait(renderCommandsEvent, smpMutex);
+ }
+
+ data = (void *)smpData;
+ }
+ SDL_UnlockMutex(smpMutex);
+
+ GLimp_SetCurrentContext(opengl_context);
+
+ return data;
+}
+
+void GLimp_FrontEndSleep( void )
+{
+ SDL_LockMutex(smpMutex);
+ {
+ while ( smpData ) {
+ SDL_CondWait(renderCompletedEvent, smpMutex);
+ }
+ }
+ SDL_UnlockMutex(smpMutex);
+
+ GLimp_SetCurrentContext(opengl_context);
+}
+
+void GLimp_WakeRenderer( void *data )
+{
+ GLimp_SetCurrentContext(NULL);
+
+ SDL_LockMutex(smpMutex);
+ {
+ assert( smpData == NULL );
+ smpData = data;
+ smpDataReady = qtrue;
+
+ // after this, the renderer can continue through GLimp_RendererSleep
+ SDL_CondSignal(renderCommandsEvent);
+ }
+ SDL_UnlockMutex(smpMutex);
+}
+
+#else
+
+void GLimp_RenderThreadWrapper( void *stub ) {}
+qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) {
+ ri.Printf( PRINT_WARNING, "ERROR: SMP support was disabled at compile time\n");
+ return qfalse;
+}
+void *GLimp_RendererSleep( void ) {
+ return NULL;
+}
+void GLimp_FrontEndSleep( void ) {}
+void GLimp_WakeRenderer( void *data ) {}
+
+#endif
+
+/*****************************************************************************/
+/* MOUSE */
+/*****************************************************************************/
+
+void IN_Init(void) {
+ Com_Printf ("\n------- Input Initialization -------\n");
+ // mouse variables
+ in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
+ in_disablemacosxmouseaccel = Cvar_Get ("in_disablemacosxmouseaccel", "1", CVAR_ARCHIVE);
+
+ // turn on-off sub-frame timing of X events
+ in_subframe = Cvar_Get ("in_subframe", "1", CVAR_ARCHIVE);
+
+ // developer feature, allows to break without loosing mouse pointer
+ in_nograb = Cvar_Get ("in_nograb", "0", 0);
+
+ // bk001130 - from cvs.17 (mkv), joystick variables
+ in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE|CVAR_LATCH);
+ // bk001130 - changed this to match win32
+ in_joystickDebug = Cvar_Get ("in_debugjoystick", "0", CVAR_TEMP);
+ joy_threshold = Cvar_Get ("joy_threshold", "0.15", CVAR_ARCHIVE); // FIXME: in_joythreshold
+
+#ifdef MACOS_X
+ Cvar_Set( "cl_platformSensitivity", "1.0" );
+#else
+ Cvar_Set( "cl_platformSensitivity", "2.0" );
+#endif
+
+ if (in_mouse->value)
+ mouse_avail = qtrue;
+ else
+ mouse_avail = qfalse;
+
+ IN_StartupJoystick( ); // bk001130 - from cvs1.17 (mkv)
+ Com_Printf ("------------------------------------\n");
+}
+
+void IN_Shutdown(void)
+{
+ IN_DeactivateMouse();
+
+ mouse_avail = qfalse;
+
+ if (stick)
+ {
+ SDL_JoystickClose(stick);
+ stick = NULL;
+ }
+
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+}
+
+void IN_Frame (void) {
+
+ // bk001130 - from cvs 1.17 (mkv)
+ IN_JoyMove(); // FIXME: disable if on desktop?
+
+ if ( cls.keyCatchers & KEYCATCH_CONSOLE )
+ {
+ // temporarily deactivate if not in the game and
+ // running on the desktop
+ // voodoo always counts as full screen
+ if (Cvar_VariableValue ("r_fullscreen") == 0
+ && strcmp( Cvar_VariableString("r_glDriver"), _3DFX_DRIVER_NAME ) )
+ {
+ IN_DeactivateMouse ();
+ return;
+ }
+ }
+
+ IN_ActivateMouse();
+}
+
+void IN_Activate(void)
+{
+}
+
+// bk001130 - cvs1.17 joystick code (mkv) was here, no linux_joystick.c
+
+void Sys_SendKeyEvents (void) {
+ // XEvent event; // bk001204 - unused
+
+ if (!screen)
+ return;
+ HandleEvents();
+}
+
+
+// (moved this back in here from linux_joystick.c, so it's all in one place...
+// --ryan.
+
+/* We translate axes movement into keypresses. */
+static int joy_keys[16] = {
+ K_LEFTARROW, K_RIGHTARROW,
+ K_UPARROW, K_DOWNARROW,
+ K_JOY16, K_JOY17,
+ K_JOY18, K_JOY19,
+ K_JOY20, K_JOY21,
+ K_JOY22, K_JOY23,
+
+ K_JOY24, K_JOY25,
+ K_JOY26, K_JOY27
+};
+
+// translate hat events into keypresses
+// the 4 highest buttons are used for the first hat ...
+static int hat_keys[16] = {
+ K_JOY29, K_JOY30,
+ K_JOY31, K_JOY32,
+ K_JOY25, K_JOY26,
+ K_JOY27, K_JOY28,
+ K_JOY21, K_JOY22,
+ K_JOY23, K_JOY24,
+ K_JOY17, K_JOY18,
+ K_JOY19, K_JOY20
+};
+
+
+// bk001130 - from linux_glimp.c
+extern cvar_t * in_joystick;
+extern cvar_t * in_joystickDebug;
+extern cvar_t * joy_threshold;
+cvar_t *in_joystickNo;
+
+#define ARRAYLEN(x) (sizeof (x) / sizeof (x[0]))
+struct
+{
+ qboolean buttons[16]; // !!! FIXME: these might be too many.
+ unsigned int oldaxes;
+ unsigned int oldhats;
+} stick_state;
+
+
+/**********************************************/
+/* Joystick routines. */
+/**********************************************/
+// bk001130 - from cvs1.17 (mkv), removed from linux_glimp.c
+void IN_StartupJoystick( void )
+{
+ int i = 0;
+ int total = 0;
+
+ if (stick != NULL)
+ SDL_JoystickClose(stick);
+
+ stick = NULL;
+ memset(&stick_state, '\0', sizeof (stick_state));
+
+ if( !in_joystick->integer ) {
+ Com_Printf( "Joystick is not active.\n" );
+ return;
+ }
+
+ if (!SDL_WasInit(SDL_INIT_JOYSTICK))
+ {
+ Com_Printf("Calling SDL_Init(SDL_INIT_JOYSTICK)...\n");
+ if (SDL_Init(SDL_INIT_JOYSTICK) == -1)
+ {
+ Com_Printf("SDL_Init(SDL_INIT_JOYSTICK) failed: %s\n", SDL_GetError());
+ return;
+ }
+ Com_Printf("SDL_Init(SDL_INIT_JOYSTICK) passed.\n");
+ }
+
+ total = SDL_NumJoysticks();
+ Com_Printf("I see %d possible joysticks\n", total);
+ for (i = 0; i < total; i++)
+ Com_Printf("[%d] %s\n", i, SDL_JoystickName(i));
+
+ in_joystickNo = Cvar_Get( "in_joystickNo", "0", CVAR_ARCHIVE );
+ if( in_joystickNo->integer < 0 || in_joystickNo->integer >= total )
+ Cvar_Set( "in_joystickNo", "0" );
+
+ stick = SDL_JoystickOpen( in_joystickNo->integer );
+
+ if (stick == NULL) {
+ Com_Printf( "No joystick opened.\n" );
+ return;
+ }
+
+ Com_Printf( "Joystick %d opened\n", in_joystickNo->integer );
+ Com_Printf( "Name: %s\n", SDL_JoystickName(in_joystickNo->integer) );
+ Com_Printf( "Axes: %d\n", SDL_JoystickNumAxes(stick) );
+ Com_Printf( "Hats: %d\n", SDL_JoystickNumHats(stick) );
+ Com_Printf( "Buttons: %d\n", SDL_JoystickNumButtons(stick) );
+ Com_Printf( "Balls: %d\n", SDL_JoystickNumBalls(stick) );
+
+ SDL_JoystickEventState(SDL_QUERY);
+
+ /* Our work here is done. */
+ return;
+}
+
+void IN_JoyMove( void )
+{
+ qboolean joy_pressed[ARRAYLEN(joy_keys)];
+ unsigned int axes = 0;
+ unsigned int hats = 0;
+ int total = 0;
+ int i = 0;
+
+ if (!stick)
+ return;
+
+ SDL_JoystickUpdate();
+
+ memset(joy_pressed, '\0', sizeof (joy_pressed));
+
+ // update the ball state.
+ total = SDL_JoystickNumBalls(stick);
+ if (total > 0)
+ {
+ int balldx = 0;
+ int balldy = 0;
+ for (i = 0; i < total; i++)
+ {
+ int dx = 0;
+ int dy = 0;
+ SDL_JoystickGetBall(stick, i, &dx, &dy);
+ balldx += dx;
+ balldy += dy;
+ }
+ if (balldx || balldy)
+ {
+ // !!! FIXME: is this good for stick balls, or just mice?
+ // Scale like the mouse input...
+ if (abs(balldx) > 1)
+ balldx *= 2;
+ if (abs(balldy) > 1)
+ balldy *= 2;
+ Sys_QueEvent( 0, SE_MOUSE, balldx, balldy, 0, NULL );
+ }
+ }
+
+ // now query the stick buttons...
+ total = SDL_JoystickNumButtons(stick);
+ if (total > 0)
+ {
+ if (total > ARRAYLEN(stick_state.buttons))
+ total = ARRAYLEN(stick_state.buttons);
+ for (i = 0; i < total; i++)
+ {
+ qboolean pressed = (SDL_JoystickGetButton(stick, i) != 0);
+ if (pressed != stick_state.buttons[i])
+ {
+ Sys_QueEvent( 0, SE_KEY, K_JOY1 + i, pressed, 0, NULL );
+ stick_state.buttons[i] = pressed;
+ }
+ }
+ }
+
+ // look at the hats...
+ total = SDL_JoystickNumHats(stick);
+ if (total > 0)
+ {
+ if (total > 4) total = 4;
+ for (i = 0; i < total; i++)
+ {
+ ((Uint8 *)&hats)[i] = SDL_JoystickGetHat(stick, i);
+ }
+ }
+
+ // update hat state
+ if (hats != stick_state.oldhats)
+ {
+ for( i = 0; i < 4; i++ ) {
+ if( ((Uint8 *)&hats)[i] != ((Uint8 *)&stick_state.oldhats)[i] ) {
+ // release event
+ switch( ((Uint8 *)&stick_state.oldhats)[i] ) {
+ case SDL_HAT_UP:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
+ break;
+ case SDL_HAT_RIGHT:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
+ break;
+ case SDL_HAT_DOWN:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
+ break;
+ case SDL_HAT_LEFT:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
+ break;
+ case SDL_HAT_RIGHTUP:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
+ break;
+ case SDL_HAT_RIGHTDOWN:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qfalse, 0, NULL );
+ break;
+ case SDL_HAT_LEFTUP:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qfalse, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
+ break;
+ case SDL_HAT_LEFTDOWN:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qfalse, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qfalse, 0, NULL );
+ break;
+ default:
+ break;
+ }
+ // press event
+ switch( ((Uint8 *)&hats)[i] ) {
+ case SDL_HAT_UP:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
+ break;
+ case SDL_HAT_RIGHT:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
+ break;
+ case SDL_HAT_DOWN:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
+ break;
+ case SDL_HAT_LEFT:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
+ break;
+ case SDL_HAT_RIGHTUP:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
+ break;
+ case SDL_HAT_RIGHTDOWN:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 1], qtrue, 0, NULL );
+ break;
+ case SDL_HAT_LEFTUP:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 0], qtrue, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
+ break;
+ case SDL_HAT_LEFTDOWN:
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 2], qtrue, 0, NULL );
+ Sys_QueEvent( 0, SE_KEY, hat_keys[4*i + 3], qtrue, 0, NULL );
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ // save hat state
+ stick_state.oldhats = hats;
+
+ // finally, look at the axes...
+ total = SDL_JoystickNumAxes(stick);
+ if (total > 0)
+ {
+ if (total > 16) total = 16;
+ for (i = 0; i < total; i++)
+ {
+ Sint16 axis = SDL_JoystickGetAxis(stick, i);
+ float f = ( (float) axis ) / 32767.0f;
+ if( f < -joy_threshold->value ) {
+ axes |= ( 1 << ( i * 2 ) );
+ } else if( f > joy_threshold->value ) {
+ axes |= ( 1 << ( ( i * 2 ) + 1 ) );
+ }
+ }
+ }
+
+ /* Time to update axes state based on old vs. new. */
+ if (axes != stick_state.oldaxes)
+ {
+ for( i = 0; i < 16; i++ ) {
+ if( ( axes & ( 1 << i ) ) && !( stick_state.oldaxes & ( 1 << i ) ) ) {
+ Sys_QueEvent( 0, SE_KEY, joy_keys[i], qtrue, 0, NULL );
+ }
+
+ if( !( axes & ( 1 << i ) ) && ( stick_state.oldaxes & ( 1 << i ) ) ) {
+ Sys_QueEvent( 0, SE_KEY, joy_keys[i], qfalse, 0, NULL );
+ }
+ }
+ }
+
+ /* Save for future generations. */
+ stick_state.oldaxes = axes;
+}
+
+#endif // USE_SDL_VIDEO
+
+// end sdl_glimp.c ...
+
diff --git a/src/unix/sdl_snd.c b/src/unix/sdl_snd.c
new file mode 100644
index 0000000..8b0aaf0
--- /dev/null
+++ b/src/unix/sdl_snd.c
@@ -0,0 +1,363 @@
+#if USE_SDL_SOUND
+
+/*
+ * SDL implementation for Quake 3: Arena's GPL source release.
+ *
+ * This is a replacement of the Linux/OpenSoundSystem code with
+ * an SDL backend, since it allows us to trivially point just about any
+ * existing 2D audio backend known to man on any platform at the code,
+ * plus it benefits from all of SDL's tapdancing to support buggy drivers,
+ * etc, and gets us free ALSA support, too.
+ *
+ * This is the best idea for a direct modernization of the Linux sound code
+ * in Quake 3. However, it would be nice to replace this with true 3D
+ * positional audio, compliments of OpenAL...
+ *
+ * Written by Ryan C. Gordon (icculus@icculus.org). Please refer to
+ * http://ioquake3.org/ for the latest version of this code.
+ *
+ * Patches and comments are welcome at the above address.
+ *
+ * I cut-and-pasted this from linux_snd.c, and moved it to SDL line-by-line.
+ * There is probably some cruft that could be removed here.
+ *
+ * You should define USE_SDL=1 and then add this to the makefile.
+ * USE_SDL will disable the Open Sound System target.
+ */
+
+/*
+Original copyright on Q3A sources:
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "SDL.h"
+
+#include "../qcommon/q_shared.h"
+#include "../client/snd_local.h"
+
+qboolean snd_inited = qfalse;
+
+cvar_t *s_sdlBits;
+cvar_t *s_sdlSpeed;
+cvar_t *s_sdlChannels;
+cvar_t *s_sdlDevSamps;
+cvar_t *s_sdlMixSamps;
+
+static qboolean use_custom_memset = qfalse;
+
+/*
+===============
+Snd_Memset
+
+https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371
+
+<TTimo> some shitty mess with DMA buffers
+<TTimo> the mmap'ing permissions were write only
+<TTimo> and glibc optimized for mmx would do memcpy with a prefetch and a read
+<TTimo> causing segfaults
+<TTimo> some other systems would not let you mmap the DMA with read permissions
+<TTimo> so I think I ended up attempting opening with read/write, then try write only
+<TTimo> and use my own copy instead of the glibc crap
+===============
+*/
+
+#ifdef Snd_Memset
+#undef Snd_Memset
+#endif
+void Snd_Memset (void* dest, const int val, const size_t count)
+{
+ int *pDest;
+ int i, iterate;
+
+ if (!use_custom_memset)
+ {
+ Com_Memset(dest,val,count);
+ return;
+ }
+ iterate = count / sizeof(int);
+ pDest = (int*)dest;
+ for(i=0; i<iterate; i++)
+ {
+ pDest[i] = val;
+ }
+}
+
+/* The audio callback. All the magic happens here. */
+static int dmapos = 0;
+static int dmasize = 0;
+
+/*
+===============
+sdl_audio_callback
+===============
+*/
+static void sdl_audio_callback(void *userdata, Uint8 *stream, int len)
+{
+ int pos = (dmapos * (dma.samplebits/8));
+ if (pos >= dmasize)
+ dmapos = pos = 0;
+
+ if (!snd_inited) /* shouldn't happen, but just in case... */
+ {
+ memset(stream, '\0', len);
+ return;
+ }
+ else
+ {
+ int tobufend = dmasize - pos; /* bytes to buffer's end. */
+ int len1 = len;
+ int len2 = 0;
+
+ if (len1 > tobufend)
+ {
+ len1 = tobufend;
+ len2 = len - len1;
+ }
+ memcpy(stream, dma.buffer + pos, len1);
+ if (len2 <= 0)
+ dmapos += (len1 / (dma.samplebits/8));
+ else /* wraparound? */
+ {
+ memcpy(stream+len1, dma.buffer, len2);
+ dmapos = (len2 / (dma.samplebits/8));
+ }
+ }
+
+ if (dmapos >= dmasize)
+ dmapos = 0;
+}
+
+static struct
+{
+ Uint16 enumFormat;
+ char *stringFormat;
+} formatToStringTable[ ] =
+{
+ { AUDIO_U8, "AUDIO_U8" },
+ { AUDIO_S8, "AUDIO_S8" },
+ { AUDIO_U16LSB, "AUDIO_U16LSB" },
+ { AUDIO_S16LSB, "AUDIO_S16LSB" },
+ { AUDIO_U16MSB, "AUDIO_U16MSB" },
+ { AUDIO_S16MSB, "AUDIO_S16MSB" }
+};
+
+static int formatToStringTableSize =
+ sizeof( formatToStringTable ) / sizeof( formatToStringTable[ 0 ] );
+
+/*
+===============
+print_audiospec
+===============
+*/
+static void print_audiospec(const char *str, const SDL_AudioSpec *spec)
+{
+ int i;
+ char *fmt = NULL;
+
+ Com_Printf("%s:\n", str);
+
+ for( i = 0; i < formatToStringTableSize; i++ ) {
+ if( spec->format == formatToStringTable[ i ].enumFormat ) {
+ fmt = formatToStringTable[ i ].stringFormat;
+ }
+ }
+
+ if( fmt ) {
+ Com_Printf( " Format: %s\n", fmt );
+ } else {
+ Com_Printf( " Format: " S_COLOR_RED "UNKNOWN\n");
+ }
+
+ Com_Printf( " Freq: %d\n", (int) spec->freq );
+ Com_Printf( " Samples: %d\n", (int) spec->samples );
+ Com_Printf( " Channels: %d\n", (int) spec->channels );
+}
+
+/*
+===============
+SNDDMA_Init
+===============
+*/
+qboolean SNDDMA_Init(void)
+{
+ char drivername[128];
+ SDL_AudioSpec desired;
+ SDL_AudioSpec obtained;
+ int tmp;
+
+ if (snd_inited)
+ return qtrue;
+
+ Com_Printf("Initializing SDL audio driver...\n");
+
+ if (!s_sdlBits) {
+ s_sdlBits = Cvar_Get("s_sdlBits", "16", CVAR_ARCHIVE);
+ s_sdlSpeed = Cvar_Get("s_sdlSpeed", "0", CVAR_ARCHIVE);
+ s_sdlChannels = Cvar_Get("s_sdlChannels", "2", CVAR_ARCHIVE);
+ s_sdlDevSamps = Cvar_Get("s_sdlDevSamps", "0", CVAR_ARCHIVE);
+ s_sdlMixSamps = Cvar_Get("s_sdlMixSamps", "0", CVAR_ARCHIVE);
+ }
+
+ if (!SDL_WasInit(SDL_INIT_AUDIO))
+ {
+ if (SDL_Init(SDL_INIT_AUDIO) == -1)
+ {
+ Com_Printf("SDL_Init(SDL_INIT_AUDIO) failed: %s\n", SDL_GetError());
+ return qfalse;
+ }
+ }
+
+ if (SDL_AudioDriverName(drivername, sizeof (drivername)) == NULL)
+ strcpy(drivername, "(UNKNOWN)");
+ Com_Printf("SDL audio driver is \"%s\".\n", drivername);
+
+ memset(&desired, '\0', sizeof (desired));
+ memset(&obtained, '\0', sizeof (obtained));
+
+ tmp = ((int) s_sdlBits->value);
+ if ((tmp != 16) && (tmp != 8))
+ tmp = 16;
+
+ desired.freq = (int) s_sdlSpeed->value;
+ if(!desired.freq) desired.freq = 22050;
+ desired.format = ((tmp == 16) ? AUDIO_S16SYS : AUDIO_U8);
+
+ // I dunno if this is the best idea, but I'll give it a try...
+ // should probably check a cvar for this...
+ if (s_sdlDevSamps->value)
+ desired.samples = s_sdlDevSamps->value;
+ else
+ {
+ // just pick a sane default.
+ if (desired.freq <= 11025)
+ desired.samples = 256;
+ else if (desired.freq <= 22050)
+ desired.samples = 512;
+ else if (desired.freq <= 44100)
+ desired.samples = 1024;
+ else
+ desired.samples = 2048; // (*shrug*)
+ }
+
+ desired.channels = (int) s_sdlChannels->value;
+ desired.callback = sdl_audio_callback;
+
+ if (SDL_OpenAudio(&desired, &obtained) == -1)
+ {
+ Com_Printf("SDL_OpenAudio() failed: %s\n", SDL_GetError());
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ return qfalse;
+ } // if
+
+ print_audiospec("SDL_AudioSpec", &obtained);
+
+ // dma.samples needs to be big, or id's mixer will just refuse to
+ // work at all; we need to keep it significantly bigger than the
+ // amount of SDL callback samples, and just copy a little each time
+ // the callback runs.
+ // 32768 is what the OSS driver filled in here on my system. I don't
+ // know if it's a good value overall, but at least we know it's
+ // reasonable...this is why I let the user override.
+ tmp = s_sdlMixSamps->value;
+ if (!tmp)
+ tmp = (obtained.samples * obtained.channels) * 10;
+
+ if (tmp & (tmp - 1)) // not a power of two? Seems to confuse something.
+ {
+ int val = 1;
+ while (val < tmp)
+ val <<= 1;
+
+ tmp = val;
+ }
+
+ dmapos = 0;
+ dma.samplebits = obtained.format & 0xFF; // first byte of format is bits.
+ dma.channels = obtained.channels;
+ dma.samples = tmp;
+ dma.submission_chunk = 1;
+ dma.speed = obtained.freq;
+ dmasize = (dma.samples * (dma.samplebits/8));
+ dma.buffer = calloc(1, dmasize);
+
+ Com_Printf("Starting SDL audio callback...\n");
+ SDL_PauseAudio(0); // start callback.
+
+ Com_Printf("SDL audio initialized.\n");
+ snd_inited = qtrue;
+ return qtrue;
+}
+
+/*
+===============
+SNDDMA_GetDMAPos
+===============
+*/
+int SNDDMA_GetDMAPos(void)
+{
+ return dmapos;
+}
+
+/*
+===============
+SNDDMA_Shutdown
+===============
+*/
+void SNDDMA_Shutdown(void)
+{
+ Com_Printf("Closing SDL audio device...\n");
+ SDL_PauseAudio(1);
+ SDL_CloseAudio();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ free(dma.buffer);
+ dma.buffer = NULL;
+ dmapos = dmasize = 0;
+ snd_inited = qfalse;
+ Com_Printf("SDL audio device shut down.\n");
+}
+
+/*
+===============
+SNDDMA_Submit
+
+Send sound to device if buffer isn't really the dma buffer
+===============
+*/
+void SNDDMA_Submit(void)
+{
+ SDL_UnlockAudio();
+}
+
+/*
+===============
+SNDDMA_BeginPainting
+===============
+*/
+void SNDDMA_BeginPainting (void)
+{
+ SDL_LockAudio();
+}
+
+#endif // USE_SDL_SOUND
diff --git a/src/unix/snapvectora.s b/src/unix/snapvectora.s
new file mode 100644
index 0000000..1ccb1a8
--- /dev/null
+++ b/src/unix/snapvectora.s
@@ -0,0 +1,104 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Foobar; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+
+//
+// Sys_SnapVector NASM code (Andrew Henderson)
+// See win32/win_shared.c for the Win32 equivalent
+// This code is provided to ensure that the
+// rounding behavior (and, if necessary, the
+// precision) of DLL and QVM code are identical
+// e.g. for network-visible operations.
+// See ftol.nasm for operations on a single float,
+// as used in compiled VM and DLL code that does
+// not use this system trap.
+//
+
+// 23/09/05 Ported to gas by intel2gas, best supporting actor Tim Angus
+// <tim@ngus.net>
+
+#include "qasm.h"
+
+#if id386
+.data
+
+fpucw: .long 0
+cw037F: .long 0x037F
+
+.text
+
+// void Sys_SnapVector( float *v )
+.globl C(Sys_SnapVector)
+C(Sys_SnapVector):
+ pushl %eax
+ pushl %ebp
+ movl %esp,%ebp
+
+ fnstcw fpucw
+ movl 12(%ebp),%eax
+ fldcw cw037F
+ flds (%eax)
+ fistpl (%eax)
+ fildl (%eax)
+ fstps (%eax)
+ flds 4(%eax)
+ fistpl 4(%eax)
+ fildl 4(%eax)
+ fstps 4(%eax)
+ flds 8(%eax)
+ fistpl 8(%eax)
+ fildl 8(%eax)
+ fstps 8(%eax)
+ fldcw fpucw
+
+ popl %ebp
+ popl %eax
+ ret
+
+// void Sys_SnapVectorCW( float *v, unsigned short int cw )
+.globl C(Sys_SnapVectorCW)
+C(Sys_SnapVectorCW):
+ pushl %eax
+ pushl %ebp
+ movl %esp,%ebp
+
+ fnstcw fpucw
+ movl 12(%ebp),%eax
+ fldcw 16(%ebp)
+ flds (%eax)
+ fistpl (%eax)
+ fildl (%eax)
+ fstps (%eax)
+ flds 4(%eax)
+ fistpl 4(%eax)
+ fildl 4(%eax)
+ fstps 4(%eax)
+ flds 8(%eax)
+ fistpl 8(%eax)
+ fildl 8(%eax)
+ fstps 8(%eax)
+ fldcw fpucw
+
+ popl %ebp
+ popl %eax
+ ret
+#endif
diff --git a/src/unix/snd_mixa.s b/src/unix/snd_mixa.s
new file mode 100644
index 0000000..7971b38
--- /dev/null
+++ b/src/unix/snd_mixa.s
@@ -0,0 +1,218 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Foobar; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+//
+// snd_mixa.s
+// x86 assembly-language sound code
+//
+
+#include "qasm.h"
+
+#if id386
+
+ .text
+
+#if 0
+//----------------------------------------------------------------------
+// 8-bit sound-mixing code
+//----------------------------------------------------------------------
+
+#define ch 4+16
+#define sc 8+16
+#define count 12+16
+
+.globl C(S_PaintChannelFrom8)
+C(S_PaintChannelFrom8):
+ pushl %esi // preserve register variables
+ pushl %edi
+ pushl %ebx
+ pushl %ebp
+
+// int data;
+// short *lscale, *rscale;
+// unsigned char *sfx;
+// int i;
+
+ movl ch(%esp),%ebx
+ movl sc(%esp),%esi
+
+// if (ch->leftvol > 255)
+// ch->leftvol = 255;
+// if (ch->rightvol > 255)
+// ch->rightvol = 255;
+ movl ch_leftvol(%ebx),%eax
+ movl ch_rightvol(%ebx),%edx
+ cmpl $255,%eax
+ jna LLeftSet
+ movl $255,%eax
+LLeftSet:
+ cmpl $255,%edx
+ jna LRightSet
+ movl $255,%edx
+LRightSet:
+
+// lscale = snd_scaletable[ch->leftvol >> 3];
+// rscale = snd_scaletable[ch->rightvol >> 3];
+// sfx = (signed char *)sc->data + ch->pos;
+// ch->pos += count;
+ andl $0xF8,%eax
+ addl $20,%esi
+ movl (%esi),%esi
+ andl $0xF8,%edx
+ movl ch_pos(%ebx),%edi
+ movl count(%esp),%ecx
+ addl %edi,%esi
+ shll $7,%eax
+ addl %ecx,%edi
+ shll $7,%edx
+ movl %edi,ch_pos(%ebx)
+ addl $(C(snd_scaletable)),%eax
+ addl $(C(snd_scaletable)),%edx
+ subl %ebx,%ebx
+ movb -1(%esi,%ecx,1),%bl
+
+ testl $1,%ecx
+ jz LMix8Loop
+
+ movl (%eax,%ebx,4),%edi
+ movl (%edx,%ebx,4),%ebp
+ addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi
+ addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp
+ movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
+ movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
+ movb -2(%esi,%ecx,1),%bl
+
+ decl %ecx
+ jz LDone
+
+// for (i=0 ; i<count ; i++)
+// {
+LMix8Loop:
+
+// data = sfx[i];
+// paintbuffer[i].left += lscale[data];
+// paintbuffer[i].right += rscale[data];
+ movl (%eax,%ebx,4),%edi
+ movl (%edx,%ebx,4),%ebp
+ addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi
+ addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp
+ movb -2(%esi,%ecx,1),%bl
+ movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size)
+ movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size)
+
+ movl (%eax,%ebx,4),%edi
+ movl (%edx,%ebx,4),%ebp
+ movb -3(%esi,%ecx,1),%bl
+ addl C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size),%edi
+ addl C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size),%ebp
+ movl %edi,C(paintbuffer)+psp_left-psp_size*2(,%ecx,psp_size)
+ movl %ebp,C(paintbuffer)+psp_right-psp_size*2(,%ecx,psp_size)
+
+// }
+ subl $2,%ecx
+ jnz LMix8Loop
+
+LDone:
+ popl %ebp
+ popl %ebx
+ popl %edi
+ popl %esi
+
+ ret
+
+
+#endif
+
+//----------------------------------------------------------------------
+// Transfer of stereo buffer to 16-bit DMA buffer code
+//----------------------------------------------------------------------
+
+.globl C(S_WriteLinearBlastStereo16)
+C(S_WriteLinearBlastStereo16):
+ pushl %edi
+ pushl %ebx
+
+// int i;
+// int val;
+ movl C(snd_linear_count),%ecx
+ movl C(snd_p),%ebx
+ movl C(snd_out),%edi
+
+// for (i=0 ; i<snd_linear_count ; i+=2)
+// {
+LWLBLoopTop:
+
+// val = (snd_p[i]*snd_vol)>>8;
+// if (val > 0x7fff)
+// snd_out[i] = 0x7fff;
+// else if (val < (short)0x8000)
+// snd_out[i] = (short)0x8000;
+// else
+// snd_out[i] = val;
+ movl -8(%ebx,%ecx,4),%eax
+ sarl $8,%eax
+ cmpl $0x7FFF,%eax
+ jg LClampHigh
+ cmpl $0xFFFF8000,%eax
+ jnl LClampDone
+ movl $0xFFFF8000,%eax
+ jmp LClampDone
+LClampHigh:
+ movl $0x7FFF,%eax
+LClampDone:
+
+// val = (snd_p[i+1]*snd_vol)>>8;
+// if (val > 0x7fff)
+// snd_out[i+1] = 0x7fff;
+// else if (val < (short)0x8000)
+// snd_out[i+1] = (short)0x8000;
+// else
+// snd_out[i+1] = val;
+ movl -4(%ebx,%ecx,4),%edx
+ sarl $8,%edx
+ cmpl $0x7FFF,%edx
+ jg LClampHigh2
+ cmpl $0xFFFF8000,%edx
+ jnl LClampDone2
+ movl $0xFFFF8000,%edx
+ jmp LClampDone2
+LClampHigh2:
+ movl $0x7FFF,%edx
+LClampDone2:
+ shll $16,%edx
+ andl $0xFFFF,%eax
+ orl %eax,%edx
+ movl %edx,-4(%edi,%ecx,2)
+
+// }
+ subl $2,%ecx
+ jnz LWLBLoopTop
+
+// snd_p += snd_linear_count;
+
+ popl %ebx
+ popl %edi
+
+ ret
+
+#endif // id386
+
diff --git a/src/unix/unix_glw.h b/src/unix/unix_glw.h
new file mode 100644
index 0000000..b239b20
--- /dev/null
+++ b/src/unix/unix_glw.h
@@ -0,0 +1,39 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+#if !( defined __linux__ || defined __FreeBSD__ || defined __sun || defined MACOS_X )
+#error You should include this file only on Linux/FreeBSD/Solaris platforms
+#endif
+
+#ifndef __GLW_LINUX_H__
+#define __GLW_LINUX_H__
+
+typedef struct
+{
+ void *OpenGLLib; // instance of OpenGL library
+
+ FILE *log_fp;
+} glwstate_t;
+
+extern glwstate_t glw_state;
+
+#endif
diff --git a/src/unix/unix_main.c b/src/unix/unix_main.c
new file mode 100644
index 0000000..86d97a1
--- /dev/null
+++ b/src/unix/unix_main.c
@@ -0,0 +1,1494 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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 <libgen.h> // dirname
+#ifdef __linux__ // rb010123
+ #include <mntent.h>
+#endif
+
+#if (defined(DEDICATED) && defined(USE_SDL_VIDEO))
+#undef USE_SDL_VIDEO
+#endif
+
+#if USE_SDL_VIDEO
+#include "SDL.h"
+#include "SDL_loadso.h"
+#else
+#include <dlfcn.h>
+#endif
+
+#ifdef __linux__
+ #include <fpu_control.h> // bk001213 - force dumps on divide by zero
+#endif
+
+#if defined(__sun)
+ #include <sys/file.h>
+#endif
+
+// FIXME TTimo should we gard this? most *nix system should comply?
+#include <termios.h>
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+#include "../renderer/tr_public.h"
+
+#include "linux_local.h" // bk001204
+
+#if idppc_altivec
+ #ifdef MACOS_X
+ #include <sys/sysctl.h>
+ #endif
+#endif
+
+unsigned sys_frame_time;
+
+qboolean stdin_active = qtrue;
+
+// =============================================================
+// tty console variables
+// =============================================================
+
+// enable/disabled tty input mode
+// NOTE TTimo this is used during startup, cannot be changed during run
+static cvar_t *ttycon = NULL;
+// general flag to tell about tty console mode
+static qboolean ttycon_on = qfalse;
+// when printing general stuff to stdout stderr (Sys_Printf)
+// we need to disable the tty console stuff
+// this increments so we can recursively disable
+static int ttycon_hide = 0;
+// some key codes that the terminal may be using
+// TTimo NOTE: I'm not sure how relevant this is
+static int tty_erase;
+static int tty_eof;
+
+static struct termios tty_tc;
+
+static field_t tty_con;
+
+static cvar_t *ttycon_ansicolor = NULL;
+static qboolean ttycon_color_on = qfalse;
+
+// history
+// NOTE TTimo this is a bit duplicate of the graphical console history
+// but it's safer and faster to write our own here
+#define TTY_HISTORY 32
+static field_t ttyEditLines[TTY_HISTORY];
+static int hist_current = -1, hist_count = 0;
+
+// =======================================================================
+// General routines
+// =======================================================================
+
+// bk001207
+#define MEM_THRESHOLD 96*1024*1024
+
+/*
+==================
+Sys_LowPhysicalMemory()
+==================
+*/
+qboolean Sys_LowPhysicalMemory() {
+ //MEMORYSTATUS stat;
+ //GlobalMemoryStatus (&stat);
+ //return (stat.dwTotalPhys <= MEM_THRESHOLD) ? qtrue : qfalse;
+ return qfalse; // bk001207 - FIXME
+}
+
+/*
+==================
+Sys_FunctionCmp
+==================
+*/
+int Sys_FunctionCmp(void *f1, void *f2) {
+ return qtrue;
+}
+
+/*
+==================
+Sys_FunctionCheckSum
+==================
+*/
+int Sys_FunctionCheckSum(void *f1) {
+ return 0;
+}
+
+/*
+==================
+Sys_MonkeyShouldBeSpanked
+==================
+*/
+int Sys_MonkeyShouldBeSpanked( void ) {
+ return 0;
+}
+
+void Sys_BeginProfiling( void ) {
+}
+
+/*
+=================
+Sys_In_Restart_f
+
+Restart the input subsystem
+=================
+*/
+void Sys_In_Restart_f( void )
+{
+ IN_Shutdown();
+ IN_Init();
+}
+
+// =============================================================
+// tty console routines
+// NOTE: if the user is editing a line when something gets printed to the early console then it won't look good
+// so we provide tty_Clear and tty_Show to be called before and after a stdout or stderr output
+// =============================================================
+
+// flush stdin, I suspect some terminals are sending a LOT of shit
+// FIXME TTimo relevant?
+void tty_FlushIn( void )
+{
+ char key;
+ while (read(0, &key, 1)!=-1);
+}
+
+// do a backspace
+// TTimo NOTE: it seems on some terminals just sending '\b' is not enough
+// so for now, in any case we send "\b \b" .. yeah well ..
+// (there may be a way to find out if '\b' alone would work though)
+void tty_Back( void )
+{
+ char key;
+ key = '\b';
+ write(1, &key, 1);
+ key = ' ';
+ write(1, &key, 1);
+ key = '\b';
+ write(1, &key, 1);
+}
+
+// clear the display of the line currently edited
+// bring cursor back to beginning of line
+void tty_Hide( void )
+{
+ int i;
+ assert(ttycon_on);
+ if (ttycon_hide)
+ {
+ ttycon_hide++;
+ return;
+ }
+ if (tty_con.cursor>0)
+ {
+ for (i=0; i<tty_con.cursor; i++)
+ {
+ tty_Back();
+ }
+ }
+ ttycon_hide++;
+}
+
+// show the current line
+// FIXME TTimo need to position the cursor if needed??
+void tty_Show( void )
+{
+ int i;
+ assert(ttycon_on);
+ assert(ttycon_hide>0);
+ ttycon_hide--;
+ if (ttycon_hide == 0)
+ {
+ if (tty_con.cursor)
+ {
+ for (i=0; i<tty_con.cursor; i++)
+ {
+ write(1, tty_con.buffer+i, 1);
+ }
+ }
+ }
+}
+
+// never exit without calling this, or your terminal will be left in a pretty bad state
+void Sys_ConsoleInputShutdown( void )
+{
+ if (ttycon_on)
+ {
+ Com_Printf("Shutdown tty console\n");
+ tcsetattr (0, TCSADRAIN, &tty_tc);
+ }
+}
+
+void Hist_Add(field_t *field)
+{
+ int i;
+ assert(hist_count <= TTY_HISTORY);
+ assert(hist_count >= 0);
+ assert(hist_current >= -1);
+ assert(hist_current <= hist_count);
+ // make some room
+ for (i=TTY_HISTORY-1; i>0; i--)
+ {
+ ttyEditLines[i] = ttyEditLines[i-1];
+ }
+ ttyEditLines[0] = *field;
+ if (hist_count<TTY_HISTORY)
+ {
+ hist_count++;
+ }
+ hist_current = -1; // re-init
+}
+
+field_t *Hist_Prev( void )
+{
+ int hist_prev;
+ assert(hist_count <= TTY_HISTORY);
+ assert(hist_count >= 0);
+ assert(hist_current >= -1);
+ assert(hist_current <= hist_count);
+ hist_prev = hist_current + 1;
+ if (hist_prev >= hist_count)
+ {
+ return NULL;
+ }
+ hist_current++;
+ return &(ttyEditLines[hist_current]);
+}
+
+field_t *Hist_Next( void )
+{
+ assert(hist_count <= TTY_HISTORY);
+ assert(hist_count >= 0);
+ assert(hist_current >= -1);
+ assert(hist_current <= hist_count);
+ if (hist_current >= 0)
+ {
+ hist_current--;
+ }
+ if (hist_current == -1)
+ {
+ return NULL;
+ }
+ return &(ttyEditLines[hist_current]);
+}
+
+// =============================================================
+// general sys routines
+// =============================================================
+
+#if 0
+// NOTE TTimo this is not used .. looks interesting though? protection against buffer overflow kind of stuff?
+void Sys_Printf (char *fmt, ...)
+{
+ va_list argptr;
+ char text[1024];
+ unsigned char *p;
+
+ va_start (argptr,fmt);
+ vsprintf (text,fmt,argptr);
+ va_end (argptr);
+
+ if (strlen(text) > sizeof(text))
+ Sys_Error("memory overwrite in Sys_Printf");
+
+ 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);
+ }
+}
+#endif
+
+// single exit point (regular exit or in case of signal fault)
+void Sys_Exit( int ex ) {
+ Sys_ConsoleInputShutdown();
+
+#ifdef NDEBUG // regular behavior
+
+ // We can't do this
+ // as long as GL DLL's keep installing with atexit...
+ //exit(ex);
+ _exit(ex);
+#else
+
+ // Give me a backtrace on error exits.
+ assert( ex == 0 );
+ exit(ex);
+#endif
+}
+
+
+void Sys_Quit (void) {
+ CL_Shutdown ();
+ fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
+ Sys_Exit(0);
+}
+
+
+#if idppc_altivec && !MACOS_X
+/* This is the brute force way of detecting instruction sets...
+ the code is borrowed from SDL, which got the idea from the libmpeg2
+ library - thanks!
+ */
+#include <signal.h>
+#include <setjmp.h>
+static jmp_buf jmpbuf;
+static void illegal_instruction(int sig)
+{
+ longjmp(jmpbuf, 1);
+}
+#endif
+
+qboolean Sys_DetectAltivec( void )
+{
+ qboolean altivec = qfalse;
+
+#if idppc_altivec
+ #ifdef MACOS_X
+ int selectors[2] = { CTL_HW, HW_VECTORUNIT };
+ int hasVectorUnit = 0;
+ size_t length = sizeof(hasVectorUnit);
+ int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0);
+
+ if( 0 == error )
+ altivec = (hasVectorUnit != 0);
+ #else
+ void (*handler)(int sig);
+ handler = signal(SIGILL, illegal_instruction);
+ if ( setjmp(jmpbuf) == 0 ) {
+ asm volatile ("mtspr 256, %0\n\t"
+ "vand %%v0, %%v0, %%v0"
+ :
+ : "r" (-1));
+ altivec = qtrue;
+ }
+ signal(SIGILL, handler);
+ #endif
+#endif
+
+ return altivec;
+}
+
+void Sys_Init(void)
+{
+
+ Cmd_AddCommand ("in_restart", Sys_In_Restart_f);
+
+ Cvar_Set( "arch", OS_STRING " " ARCH_STRING );
+
+ Cvar_Set( "username", Sys_GetCurrentUser() );
+
+ //IN_Init(); // rcg08312005 moved into glimp.
+
+}
+
+void Sys_Error( const char *error, ...)
+{
+ va_list argptr;
+ char string[1024];
+
+ // change stdin to non blocking
+ // NOTE TTimo not sure how well that goes with tty console mode
+ fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
+
+ // don't bother do a show on this one heh
+ if (ttycon_on)
+ {
+ tty_Hide();
+ }
+
+ CL_Shutdown ();
+
+ va_start (argptr,error);
+ vsprintf (string,error,argptr);
+ va_end (argptr);
+ fprintf(stderr, "Sys_Error: %s\n", string);
+
+ Sys_Exit( 1 ); // bk010104 - use single exit point.
+}
+
+void Sys_Warn (char *warning, ...)
+{
+ va_list argptr;
+ char string[1024];
+
+ va_start (argptr,warning);
+ vsprintf (string,warning,argptr);
+ va_end (argptr);
+
+ if (ttycon_on)
+ {
+ tty_Hide();
+ }
+
+ fprintf(stderr, "Warning: %s", string);
+
+ if (ttycon_on)
+ {
+ tty_Show();
+ }
+}
+
+/*
+============
+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)
+{
+ signal(SIGFPE, floating_point_exception_handler);
+}
+
+// initialize the console input (tty mode if wanted and possible)
+void Sys_ConsoleInputInit( void )
+{
+ struct termios tc;
+
+ // TTimo
+ // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=390
+ // ttycon 0 or 1, if the process is backgrounded (running non interactively)
+ // then SIGTTIN or SIGTOU is emitted, if not catched, turns into a SIGSTP
+ signal(SIGTTIN, SIG_IGN);
+ signal(SIGTTOU, SIG_IGN);
+
+ // FIXME TTimo initialize this in Sys_Init or something?
+ ttycon = Cvar_Get("ttycon", "1", 0);
+ if (ttycon && ttycon->value)
+ {
+ if (isatty(STDIN_FILENO)!=1)
+ {
+ Com_Printf("stdin is not a tty, tty console mode failed\n");
+ Cvar_Set("ttycon", "0");
+ ttycon_on = qfalse;
+ return;
+ }
+ Com_Printf("Started tty console (use +set ttycon 0 to disable)\n");
+ Field_Clear(&tty_con);
+ tcgetattr (0, &tty_tc);
+ tty_erase = tty_tc.c_cc[VERASE];
+ tty_eof = tty_tc.c_cc[VEOF];
+ tc = tty_tc;
+ /*
+ ECHO: don't echo input characters
+ ICANON: enable canonical mode. This enables the special
+ characters EOF, EOL, EOL2, ERASE, KILL, REPRINT,
+ STATUS, and WERASE, and buffers by lines.
+ ISIG: when any of the characters INTR, QUIT, SUSP, or
+ DSUSP are received, generate the corresponding sig­
+ nal
+ */
+ tc.c_lflag &= ~(ECHO | ICANON);
+ /*
+ ISTRIP strip off bit 8
+ INPCK enable input parity checking
+ */
+ tc.c_iflag &= ~(ISTRIP | INPCK);
+ tc.c_cc[VMIN] = 1;
+ tc.c_cc[VTIME] = 0;
+ tcsetattr (0, TCSADRAIN, &tc);
+ ttycon_on = qtrue;
+
+ ttycon_ansicolor = Cvar_Get( "ttycon_ansicolor", "0", CVAR_ARCHIVE );
+ if( ttycon_ansicolor && ttycon_ansicolor->value )
+ {
+ ttycon_color_on = qtrue;
+ }
+ } else
+ ttycon_on = qfalse;
+}
+
+char *Sys_ConsoleInput(void)
+{
+ // we use this when sending back commands
+ static char text[256];
+ int avail;
+ char key;
+ field_t *history;
+
+ if (ttycon && ttycon->value)
+ {
+ avail = read(0, &key, 1);
+ if (avail != -1)
+ {
+ // we have something
+ // backspace?
+ // NOTE TTimo testing a lot of values .. seems it's the only way to get it to work everywhere
+ if ((key == tty_erase) || (key == 127) || (key == 8))
+ {
+ if (tty_con.cursor > 0)
+ {
+ tty_con.cursor--;
+ tty_con.buffer[tty_con.cursor] = '\0';
+ tty_Back();
+ }
+ return NULL;
+ }
+ // check if this is a control char
+ if ((key) && (key) < ' ')
+ {
+ if (key == '\n')
+ {
+ // push it in history
+ Hist_Add(&tty_con);
+ strcpy(text, tty_con.buffer);
+ Field_Clear(&tty_con);
+ key = '\n';
+ write(1, &key, 1);
+ return text;
+ }
+ if (key == '\t')
+ {
+ tty_Hide();
+ Field_AutoComplete( &tty_con );
+ tty_Show();
+ return NULL;
+ }
+ avail = read(0, &key, 1);
+ if (avail != -1)
+ {
+ // VT 100 keys
+ if (key == '[' || key == 'O')
+ {
+ avail = read(0, &key, 1);
+ if (avail != -1)
+ {
+ switch (key)
+ {
+ case 'A':
+ history = Hist_Prev();
+ if (history)
+ {
+ tty_Hide();
+ tty_con = *history;
+ tty_Show();
+ }
+ tty_FlushIn();
+ return NULL;
+ break;
+ case 'B':
+ history = Hist_Next();
+ tty_Hide();
+ if (history)
+ {
+ tty_con = *history;
+ } else
+ {
+ Field_Clear(&tty_con);
+ }
+ tty_Show();
+ tty_FlushIn();
+ return NULL;
+ break;
+ case 'C':
+ return NULL;
+ case 'D':
+ return NULL;
+ }
+ }
+ }
+ }
+ Com_DPrintf("droping ISCTL sequence: %d, tty_erase: %d\n", key, tty_erase);
+ tty_FlushIn();
+ return NULL;
+ }
+ // push regular character
+ tty_con.buffer[tty_con.cursor] = key;
+ tty_con.cursor++;
+ // print the current line (this is differential)
+ write(1, &key, 1);
+ }
+ return NULL;
+ } else
+ {
+ int len;
+ fd_set fdset;
+ struct timeval timeout;
+
+ if (!com_dedicated || !com_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 = qfalse;
+ return NULL;
+ }
+
+ if (len < 1)
+ return NULL;
+ text[len-1] = 0; // rip off the /n and terminate
+
+ return text;
+ }
+}
+
+/*****************************************************************************/
+
+char *do_dlerror(void)
+{
+#if USE_SDL_VIDEO
+ return SDL_GetError();
+#else
+ return dlerror();
+#endif
+}
+
+
+/*
+=================
+Sys_UnloadDll
+
+=================
+*/
+void Sys_UnloadDll( void *dllHandle ) {
+ // bk001206 - verbose error reporting
+ if ( !dllHandle )
+ {
+ Com_Printf("Sys_UnloadDll(NULL)\n");
+ return;
+ }
+
+#if USE_SDL_VIDEO
+ SDL_UnloadObject(dllHandle);
+#else
+ dlclose( dllHandle );
+ {
+ const char* err; // rb010123 - now const
+ err = dlerror();
+ if ( err != NULL )
+ Com_Printf ( "Sys_UnloadGame failed on dlclose: \"%s\"!\n", err );
+ }
+#endif
+}
+
+
+/*
+=================
+Sys_LoadDll
+
+Used to load a development dll instead of a virtual machine
+TTimo:
+changed the load procedure to match VFS logic, and allow developer use
+#1 look down current path
+#2 look in fs_homepath
+#3 look in fs_basepath
+=================
+*/
+
+static void* try_dlopen(const char* base, const char* gamedir, const char* fname, char* fqpath )
+{
+ void* libHandle;
+ char* fn;
+
+ *fqpath = 0;
+
+// bk001129 - was RTLD_LAZY
+#define Q_RTLD RTLD_NOW
+
+ fn = FS_BuildOSPath( base, gamedir, fname );
+ Com_Printf( "Sys_LoadDll(%s)... \n", fn );
+
+#if USE_SDL_VIDEO
+ libHandle = SDL_LoadObject(fn);
+#else
+ libHandle = dlopen( fn, Q_RTLD );
+#endif
+
+ if(!libHandle) {
+ Com_Printf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, do_dlerror() );
+ return NULL;
+ }
+
+ Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn );
+ Q_strncpyz ( fqpath , fn , MAX_QPATH ) ; // added 7/20/02 by T.Ray
+
+ return libHandle;
+}
+
+void *Sys_LoadDll( const char *name, char *fqpath ,
+ intptr_t (**entryPoint)(int, ...),
+ intptr_t (*systemcalls)(intptr_t, ...) )
+{
+ void *libHandle;
+ void (*dllEntry)( intptr_t (*syscallptr)(intptr_t, ...) );
+ char curpath[MAX_OSPATH];
+ char fname[MAX_OSPATH];
+ char *basepath;
+ char *homepath;
+ char *pwdpath;
+ char *cdpath;
+ char *gamedir;
+ const char* err = NULL;
+
+ // bk001206 - let's have some paranoia
+ assert( name );
+
+ getcwd(curpath, sizeof(curpath));
+ snprintf (fname, sizeof(fname), "%s" ARCH_STRING DLL_EXT, name);
+
+ // TODO: use fs_searchpaths from files.c
+ pwdpath = Sys_Cwd();
+ basepath = Cvar_VariableString( "fs_basepath" );
+ homepath = Cvar_VariableString( "fs_homepath" );
+ cdpath = Cvar_VariableString( "fs_cdpath" );
+ gamedir = Cvar_VariableString( "fs_game" );
+
+ libHandle = try_dlopen(pwdpath, gamedir, fname, fqpath);
+
+ if(!libHandle && homepath)
+ libHandle = try_dlopen(homepath, gamedir, fname, fqpath);
+
+ if(!libHandle && basepath)
+ libHandle = try_dlopen(basepath, gamedir, fname, fqpath);
+
+ if(!libHandle && cdpath)
+ libHandle = try_dlopen(cdpath, gamedir, fname, fqpath);
+
+ if(!libHandle) {
+#if 0 // don't abort -- ln
+//#ifndef NDEBUG // bk001206 - in debug abort on failure
+ Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name );
+#else
+ Com_Printf ( "Sys_LoadDll(%s) failed dlopen() completely!\n", name );
+#endif
+ return NULL;
+ }
+
+#if USE_SDL_VIDEO
+ dllEntry = SDL_LoadFunction( libHandle, "dllEntry" );
+ *entryPoint = SDL_LoadFunction( libHandle, "vmMain" );
+#else
+ dllEntry = dlsym( libHandle, "dllEntry" );
+ *entryPoint = dlsym( libHandle, "vmMain" );
+#endif
+
+ if ( !*entryPoint || !dllEntry )
+ {
+ err = do_dlerror();
+#ifndef NDEBUG // bk001206 - in debug abort on failure
+ Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
+#else
+ Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
+#endif
+#if USE_SDL_VIDEO
+ SDL_UnloadObject(libHandle);
+#else
+ dlclose( libHandle );
+ err = do_dlerror();
+ if ( err != NULL ) {
+ Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err );
+ }
+#endif
+
+ return NULL;
+ }
+ Com_Printf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint ); // bk001212
+ dllEntry( systemcalls );
+ Com_Printf ( "Sys_LoadDll(%s) succeeded!\n", name );
+ return libHandle;
+}
+
+/*
+========================================================================
+
+BACKGROUND FILE STREAMING
+
+========================================================================
+*/
+
+#if 1
+
+void Sys_InitStreamThread( void ) {
+}
+
+void Sys_ShutdownStreamThread( void ) {
+}
+
+void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) {
+}
+
+void Sys_EndStreamedFile( fileHandle_t f ) {
+}
+
+int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
+ return FS_Read( buffer, size * count, f );
+}
+
+void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
+ FS_Seek( f, offset, origin );
+}
+
+#else
+
+typedef struct
+{
+ fileHandle_t file;
+ byte *buffer;
+ qboolean eof;
+ int bufferSize;
+ int streamPosition; // next byte to be returned by Sys_StreamRead
+ int threadPosition; // next byte to be read from file
+} streamState_t;
+
+streamState_t stream;
+
+/*
+===============
+Sys_StreamThread
+
+A thread will be sitting in this loop forever
+================
+*/
+void Sys_StreamThread( void )
+{
+ int buffer;
+ int count;
+ int readCount;
+ int bufferPoint;
+ int r;
+
+ // if there is any space left in the buffer, fill it up
+ if ( !stream.eof )
+ {
+ count = stream.bufferSize - (stream.threadPosition - stream.streamPosition);
+ if ( count )
+ {
+ bufferPoint = stream.threadPosition % stream.bufferSize;
+ buffer = stream.bufferSize - bufferPoint;
+ readCount = buffer < count ? buffer : count;
+ r = FS_Read ( stream.buffer + bufferPoint, readCount, stream.file );
+ stream.threadPosition += r;
+
+ if ( r != readCount )
+ stream.eof = qtrue;
+ }
+ }
+}
+
+/*
+===============
+Sys_InitStreamThread
+
+================
+*/
+void Sys_InitStreamThread( void )
+{
+}
+
+/*
+===============
+Sys_ShutdownStreamThread
+
+================
+*/
+void Sys_ShutdownStreamThread( void )
+{
+}
+
+
+/*
+===============
+Sys_BeginStreamedFile
+
+================
+*/
+void Sys_BeginStreamedFile( fileHandle_t f, int readAhead )
+{
+ if ( stream.file )
+ {
+ Com_Error( ERR_FATAL, "Sys_BeginStreamedFile: unclosed stream");
+ }
+
+ stream.file = f;
+ stream.buffer = Z_Malloc( readAhead );
+ stream.bufferSize = readAhead;
+ stream.streamPosition = 0;
+ stream.threadPosition = 0;
+ stream.eof = qfalse;
+}
+
+/*
+===============
+Sys_EndStreamedFile
+
+================
+*/
+void Sys_EndStreamedFile( fileHandle_t f )
+{
+ if ( f != stream.file )
+ {
+ Com_Error( ERR_FATAL, "Sys_EndStreamedFile: wrong file");
+ }
+
+ stream.file = 0;
+ Z_Free( stream.buffer );
+}
+
+
+/*
+===============
+Sys_StreamedRead
+
+================
+*/
+int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f )
+{
+ int available;
+ int remaining;
+ int sleepCount;
+ int copy;
+ int bufferCount;
+ int bufferPoint;
+ byte *dest;
+
+ dest = (byte *)buffer;
+ remaining = size * count;
+
+ if ( remaining <= 0 )
+ {
+ Com_Error( ERR_FATAL, "Streamed read with non-positive size" );
+ }
+
+ sleepCount = 0;
+ while ( remaining > 0 )
+ {
+ available = stream.threadPosition - stream.streamPosition;
+ if ( !available )
+ {
+ if (stream.eof)
+ break;
+ Sys_StreamThread();
+ continue;
+ }
+
+ bufferPoint = stream.streamPosition % stream.bufferSize;
+ bufferCount = stream.bufferSize - bufferPoint;
+
+ copy = available < bufferCount ? available : bufferCount;
+ if ( copy > remaining )
+ {
+ copy = remaining;
+ }
+ memcpy( dest, stream.buffer + bufferPoint, copy );
+ stream.streamPosition += copy;
+ dest += copy;
+ remaining -= copy;
+ }
+
+ return(count * size - remaining) / size;
+}
+
+/*
+===============
+Sys_StreamSeek
+
+================
+*/
+void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
+ // clear to that point
+ FS_Seek( f, offset, origin );
+ stream.streamPosition = 0;
+ stream.threadPosition = 0;
+ stream.eof = qfalse;
+}
+
+#endif
+
+/*
+========================================================================
+
+EVENT LOOP
+
+========================================================================
+*/
+
+// bk000306: upped this from 64
+#define MAX_QUED_EVENTS 256
+#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
+
+sysEvent_t eventQue[MAX_QUED_EVENTS];
+// bk000306: initialize
+int eventHead = 0;
+int eventTail = 0;
+byte sys_packetReceived[MAX_MSGLEN];
+
+/*
+================
+Sys_QueEvent
+
+A time of 0 will get the current time
+Ptr should either be null, or point to a block of data that can
+be freed by the game later.
+================
+*/
+void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {
+ sysEvent_t *ev;
+
+ ev = &eventQue[ eventHead & MASK_QUED_EVENTS ];
+
+ // bk000305 - was missing
+ if ( eventHead - eventTail >= MAX_QUED_EVENTS )
+ {
+ Com_Printf("Sys_QueEvent: overflow\n");
+ // we are discarding an event, but don't leak memory
+ if ( ev->evPtr )
+ {
+ Z_Free( ev->evPtr );
+ }
+ eventTail++;
+ }
+
+ eventHead++;
+
+ if ( time == 0 )
+ {
+ time = Sys_Milliseconds();
+ }
+
+ ev->evTime = time;
+ ev->evType = type;
+ ev->evValue = value;
+ ev->evValue2 = value2;
+ ev->evPtrLength = ptrLength;
+ ev->evPtr = ptr;
+}
+
+/*
+================
+Sys_GetEvent
+
+================
+*/
+sysEvent_t Sys_GetEvent( void ) {
+ sysEvent_t ev;
+ char *s;
+ msg_t netmsg;
+ netadr_t adr;
+
+ // return if we have data
+ if ( eventHead > eventTail )
+ {
+ eventTail++;
+ return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
+ }
+
+ // pump the message loop
+ // in vga this calls KBD_Update, under X, it calls GetEvent
+ Sys_SendKeyEvents ();
+
+ // check for console commands
+ s = Sys_ConsoleInput();
+ if ( s )
+ {
+ char *b;
+ int len;
+
+ len = strlen( s ) + 1;
+ b = Z_Malloc( len );
+ strcpy( b, s );
+ Sys_QueEvent( 0, SE_CONSOLE, 0, 0, len, b );
+ }
+
+ // check for other input devices
+ IN_Frame();
+
+ // check for network packets
+ MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
+ if ( Sys_GetPacket ( &adr, &netmsg ) )
+ {
+ netadr_t *buf;
+ int len;
+
+ // copy out to a seperate buffer for qeueing
+ len = sizeof( netadr_t ) + netmsg.cursize;
+ buf = Z_Malloc( len );
+ *buf = adr;
+ memcpy( buf+1, netmsg.data, netmsg.cursize );
+ Sys_QueEvent( 0, SE_PACKET, 0, 0, len, buf );
+ }
+
+ // return if we have data
+ if ( eventHead > eventTail )
+ {
+ eventTail++;
+ return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
+ }
+
+ // create an empty event to return
+
+ memset( &ev, 0, sizeof( ev ) );
+ ev.evTime = Sys_Milliseconds();
+
+ return ev;
+}
+
+/*****************************************************************************/
+
+qboolean Sys_CheckCD( void ) {
+ return qtrue;
+}
+
+void Sys_AppActivate (void)
+{
+}
+
+char *Sys_GetClipboardData(void)
+{
+ return NULL;
+}
+
+static struct Q3ToAnsiColorTable_s
+{
+ char Q3color;
+ char *ANSIcolor;
+} tty_colorTable[ ] =
+{
+ { COLOR_BLACK, "30" },
+ { COLOR_RED, "31" },
+ { COLOR_GREEN, "32" },
+ { COLOR_YELLOW, "33" },
+ { COLOR_BLUE, "34" },
+ { COLOR_CYAN, "36" },
+ { COLOR_MAGENTA, "35" },
+ { COLOR_WHITE, "0" }
+};
+
+static int tty_colorTableSize =
+ sizeof( tty_colorTable ) / sizeof( tty_colorTable[ 0 ] );
+
+void Sys_ANSIColorify( const char *msg, char *buffer, int bufferSize )
+{
+ int msgLength, pos;
+ int i, j;
+ char *escapeCode;
+ char tempBuffer[ 7 ];
+
+ if( !msg || !buffer )
+ return;
+
+ msgLength = strlen( msg );
+ pos = 0;
+ i = 0;
+ buffer[ 0 ] = '\0';
+
+ while( i < msgLength )
+ {
+ if( msg[ i ] == '\n' )
+ {
+ Com_sprintf( tempBuffer, 7, "%c[0m\n", 0x1B );
+ strncat( buffer, tempBuffer, bufferSize - 1);
+ i++;
+ }
+ else if( msg[ i ] == Q_COLOR_ESCAPE )
+ {
+ i++;
+
+ if( i < msgLength )
+ {
+ escapeCode = NULL;
+ for( j = 0; j < tty_colorTableSize; j++ )
+ {
+ if( msg[ i ] == tty_colorTable[ j ].Q3color )
+ {
+ escapeCode = tty_colorTable[ j ].ANSIcolor;
+ break;
+ }
+ }
+
+ if( escapeCode )
+ {
+ Com_sprintf( tempBuffer, 7, "%c[%sm", 0x1B, escapeCode );
+ strncat( buffer, tempBuffer, bufferSize - 1);
+ }
+
+ i++;
+ }
+ }
+ else
+ {
+ Com_sprintf( tempBuffer, 7, "%c", msg[ i++ ] );
+ strncat( buffer, tempBuffer, bufferSize - 1);
+ }
+ }
+}
+
+void Sys_Print( const char *msg )
+{
+ if (ttycon_on)
+ {
+ tty_Hide();
+ }
+
+ if( ttycon_on && ttycon_color_on )
+ {
+ char ansiColorString[ MAXPRINTMSG ];
+ Sys_ANSIColorify( msg, ansiColorString, MAXPRINTMSG );
+ fputs( ansiColorString, stderr );
+ }
+ else
+ fputs(msg, stderr);
+
+ if (ttycon_on)
+ {
+ tty_Show();
+ }
+}
+
+
+void Sys_ConfigureFPU( void ) { // bk001213 - divide by zero
+#ifdef __linux__
+#ifdef __i386
+#ifndef NDEBUG
+
+ // bk0101022 - enable FPE's in debug mode
+ static int fpu_word = _FPU_DEFAULT & ~(_FPU_MASK_ZM | _FPU_MASK_IM);
+ int current = 0;
+ _FPU_GETCW(current);
+ if ( current!=fpu_word)
+ {
+#if 0
+ Com_Printf("FPU Control 0x%x (was 0x%x)\n", fpu_word, current );
+ _FPU_SETCW( fpu_word );
+ _FPU_GETCW( current );
+ assert(fpu_word==current);
+#endif
+ }
+#else // NDEBUG
+ static int fpu_word = _FPU_DEFAULT;
+ _FPU_SETCW( fpu_word );
+#endif // NDEBUG
+#endif // __i386
+#endif // __linux
+}
+
+void Sys_PrintBinVersion( const char* name ) {
+ char* date = __DATE__;
+ char* time = __TIME__;
+ char* sep = "==============================================================";
+ fprintf( stdout, "\n\n%s\n", sep );
+#ifdef DEDICATED
+ fprintf( stdout, "Linux Tremulous Dedicated Server [%s %s]\n", date, time );
+#else
+ fprintf( stdout, "Linux Tremulous Full Executable [%s %s]\n", date, time );
+#endif
+ fprintf( stdout, " local install: %s\n", name );
+ fprintf( stdout, "%s\n\n", sep );
+}
+
+/*
+=================
+Sys_BinName
+
+This resolves any symlinks to the binary. It's disabled for debug
+builds because there are situations where you are likely to want
+to symlink to binaries and /not/ have the links resolved.
+=================
+*/
+char *Sys_BinName( const char *arg0 )
+{
+ static char dst[ PATH_MAX ];
+
+#ifdef NDEBUG
+
+#ifdef __linux__
+ int n = readlink( "/proc/self/exe", dst, PATH_MAX - 1 );
+
+ if( n >= 0 && n < PATH_MAX )
+ dst[ n ] = '\0';
+ else
+ Q_strncpyz( dst, arg0, PATH_MAX );
+#else
+#warning Sys_BinName not implemented
+ Q_strncpyz( dst, arg0, PATH_MAX );
+#endif
+
+#else
+ Q_strncpyz( dst, arg0, PATH_MAX );
+#endif
+
+ return dst;
+}
+
+void Sys_ParseArgs( int argc, char* argv[] ) {
+
+ if ( argc==2 )
+ {
+ if ( (!strcmp( argv[1], "--version" ))
+ || ( !strcmp( argv[1], "-v" )) )
+ {
+ Sys_PrintBinVersion( Sys_BinName( argv[0] ) );
+ Sys_Exit(0);
+ }
+ }
+}
+
+#ifdef MACOS_X
+/*
+=================
+Sys_EscapeAppBundle
+
+Discovers if passed dir is suffixed with the directory structure of a
+Mac OS X .app bundle. If it is, the .app directory structure is stripped off
+the end and the result is returned. If not, dir is returned untouched.
+
+=================
+*/
+char *Sys_StripAppBundle(char *dir)
+{
+ static char cwd[MAX_OSPATH];
+
+ Q_strncpyz(cwd, dir, sizeof(cwd));
+ if(strcmp(basename(cwd), "MacOS"))
+ return dir;
+ Q_strncpyz(cwd, dirname(cwd), sizeof(cwd));
+ if(strcmp(basename(cwd), "Contents"))
+ return dir;
+ Q_strncpyz(cwd, dirname(cwd), sizeof(cwd));
+ if(!strstr(basename(cwd), ".app"))
+ return dir;
+ Q_strncpyz(cwd, dirname(cwd), sizeof(cwd));
+ return cwd;
+}
+#endif /* MACOS_X */
+
+#ifndef DEFAULT_BASEDIR
+ #ifdef MACOS_X
+ // if run from an .app bundle, we want to also search its containing dir
+ #define DEFAULT_BASEDIR Sys_StripAppBundle(Sys_DefaultCDPath())
+ #else
+ #define DEFAULT_BASEDIR Sys_DefaultCDPath()
+ #endif
+#endif
+
+#include "../client/client.h"
+extern clientStatic_t cls;
+
+int main ( int argc, char* argv[] )
+{
+ // int oldtime, newtime; // bk001204 - unused
+ int len, i;
+ char *cmdline;
+ char cdpath[PATH_MAX] = {0};
+ void Sys_SetDefaultCDPath(const char *path);
+
+ Sys_ParseArgs( argc, argv ); // bk010104 - added this for support
+
+ strncat(cdpath, Sys_BinName( argv[0] ), sizeof(cdpath)-1);
+ Sys_SetDefaultCDPath(dirname(cdpath));
+
+ Sys_SetDefaultInstallPath(DEFAULT_BASEDIR);
+
+ // merge the command line, this is kinda silly
+ for (len = 1, i = 1; i < argc; i++)
+ len += strlen(argv[i]) + 1;
+ cmdline = malloc(len);
+ *cmdline = 0;
+ for (i = 1; i < argc; i++)
+ {
+ if (i > 1)
+ strcat(cmdline, " ");
+ strcat(cmdline, argv[i]);
+ }
+
+ // bk000306 - clear queues
+ memset( &eventQue[0], 0, MAX_QUED_EVENTS*sizeof(sysEvent_t) );
+ memset( &sys_packetReceived[0], 0, MAX_MSGLEN*sizeof(byte) );
+
+ Com_Init(cmdline);
+ NET_Init();
+
+ Sys_ConsoleInputInit();
+
+ fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
+
+#ifdef DEDICATED
+ // init here for dedicated, as we don't have GLimp_Init
+ InitSig();
+#endif
+
+ while (1)
+ {
+#if !defined( DEDICATED ) && USE_SDL_VIDEO
+ int appState = SDL_GetAppState( );
+
+ // If we have no input focus at all, sleep a bit
+ if( !( appState & ( SDL_APPMOUSEFOCUS | SDL_APPINPUTFOCUS ) ) )
+ usleep( 16000 );
+
+ // If we're minimised, sleep a bit more
+ if( !( appState & SDL_APPACTIVE ) )
+ usleep( 32000 );
+#endif
+
+#ifdef __linux__
+ Sys_ConfigureFPU();
+#endif
+ Com_Frame ();
+ }
+
+ return 0;
+}
+
diff --git a/src/unix/unix_net.c b/src/unix/unix_net.c
new file mode 100644
index 0000000..8670667
--- /dev/null
+++ b/src/unix/unix_net.c
@@ -0,0 +1,684 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+// unix_net.c
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+
+#include <unistd.h>
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ // needed for socket_t on OSX 10.2
+ #define _BSD_SOCKLEN_T_
+#endif
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h> // bk001204
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#ifdef MACOS_X
+#import <sys/sockio.h>
+#import <net/if.h>
+#import <net/if_types.h>
+
+#import <arpa/inet.h> // for inet_ntoa()
+#import <net/if_dl.h> // for 'struct sockaddr_dl'
+#endif
+
+#ifdef __sun
+#include <sys/filio.h>
+#endif
+
+static cvar_t *noudp;
+
+netadr_t net_local_adr;
+
+int ip_socket;
+int ipx_socket;
+
+#define MAX_IPS 16
+static int numIP;
+static byte localIP[MAX_IPS][4];
+
+int NET_Socket (char *net_interface, int port);
+char *NET_ErrorString (void);
+
+//=============================================================================
+
+void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
+{
+ memset (s, 0, sizeof(*s));
+
+ if (a->type == NA_BROADCAST)
+ {
+ s->sin_family = AF_INET;
+
+ s->sin_port = a->port;
+ *(int *)&s->sin_addr = -1;
+ }
+ else if (a->type == NA_IP)
+ {
+ s->sin_family = AF_INET;
+
+ *(int *)&s->sin_addr = *(int *)&a->ip;
+ s->sin_port = a->port;
+ }
+}
+
+void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
+{
+ *(int *)&a->ip = *(int *)&s->sin_addr;
+ a->port = s->sin_port;
+ a->type = NA_IP;
+}
+
+char *NET_BaseAdrToString (netadr_t a)
+{
+ static char s[64];
+
+ Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
+
+ return s;
+}
+
+/*
+=============
+Sys_StringToAdr
+
+idnewt
+192.246.40.70
+=============
+*/
+qboolean Sys_StringToSockaddr (const char *s, struct sockaddr *sadr)
+{
+ struct hostent *h;
+ //char *colon; // bk001204 - unused
+
+ memset (sadr, 0, sizeof(*sadr));
+ ((struct sockaddr_in *)sadr)->sin_family = AF_INET;
+
+ ((struct sockaddr_in *)sadr)->sin_port = 0;
+
+ if ( s[0] >= '0' && s[0] <= '9')
+ {
+ *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(s);
+ }
+ else
+ {
+ if (! (h = gethostbyname(s)) )
+ return qfalse;
+ *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
+ }
+
+ return qtrue;
+}
+
+/*
+=============
+Sys_StringToAdr
+
+localhost
+idnewt
+idnewt:28000
+192.246.40.70
+192.246.40.70:28000
+=============
+*/
+qboolean Sys_StringToAdr (const char *s, netadr_t *a)
+{
+ struct sockaddr_in sadr;
+
+ if (!Sys_StringToSockaddr (s, (struct sockaddr *)&sadr))
+ return qfalse;
+
+ SockadrToNetadr (&sadr, a);
+
+ return qtrue;
+}
+
+
+//=============================================================================
+
+qboolean Sys_GetPacket (netadr_t *net_from, msg_t *net_message)
+{
+ int ret;
+ struct sockaddr_in from;
+ socklen_t fromlen;
+ int net_socket;
+ int protocol;
+ int err;
+
+ for (protocol = 0 ; protocol < 2 ; protocol++)
+ {
+ if (protocol == 0)
+ net_socket = ip_socket;
+ else
+ net_socket = ipx_socket;
+
+ if (!net_socket)
+ continue;
+
+ fromlen = sizeof(from);
+ ret = recvfrom (net_socket, net_message->data, net_message->maxsize
+ , 0, (struct sockaddr *)&from, &fromlen);
+
+ SockadrToNetadr (&from, net_from);
+ // bk000305: was missing
+ net_message->readcount = 0;
+
+ if (ret == -1)
+ {
+ err = errno;
+
+ if (err == EWOULDBLOCK || err == ECONNREFUSED)
+ continue;
+ Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
+ NET_AdrToString(*net_from));
+ continue;
+ }
+
+ if (ret == net_message->maxsize)
+ {
+ Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
+ continue;
+ }
+
+ net_message->cursize = ret;
+ return qtrue;
+ }
+
+ return qfalse;
+}
+
+//=============================================================================
+
+void Sys_SendPacket( int length, const void *data, netadr_t to )
+{
+ int ret;
+ struct sockaddr_in addr;
+ int net_socket;
+
+ if (to.type == NA_BROADCAST)
+ {
+ net_socket = ip_socket;
+ }
+ else if (to.type == NA_IP)
+ {
+ net_socket = ip_socket;
+ }
+ else if (to.type == NA_IPX)
+ {
+ net_socket = ipx_socket;
+ }
+ else if (to.type == NA_BROADCAST_IPX)
+ {
+ net_socket = ipx_socket;
+ }
+ else {
+ Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
+ return;
+ }
+
+ if (!net_socket)
+ return;
+
+ NetadrToSockadr (&to, &addr);
+
+ ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
+ if (ret == -1)
+ {
+ Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
+ NET_AdrToString (to));
+ }
+}
+
+
+//=============================================================================
+
+/*
+==================
+Sys_IsLANAddress
+
+LAN clients will have their rate var ignored
+==================
+*/
+qboolean Sys_IsLANAddress (netadr_t adr) {
+ int i;
+
+ if( adr.type == NA_LOOPBACK ) {
+ return qtrue;
+ }
+
+ if( adr.type == NA_IPX ) {
+ return qtrue;
+ }
+
+ if( adr.type != NA_IP ) {
+ return qfalse;
+ }
+
+ // RFC1918:
+ // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
+ // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
+ // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
+ if(adr.ip[0] == 10)
+ return qtrue;
+ if(adr.ip[0] == 172 && (adr.ip[1]&0xf0) == 16)
+ return qtrue;
+ if(adr.ip[0] == 192 && adr.ip[1] == 168)
+ return qtrue;
+
+ // the checks below are bogus, aren't they? -- ln
+
+ // choose which comparison to use based on the class of the address being tested
+ // any local adresses of a different class than the address being tested will fail based on the first byte
+
+ // Class A
+ if( (adr.ip[0] & 0x80) == 0x00 ) {
+ for ( i = 0 ; i < numIP ; i++ ) {
+ if( adr.ip[0] == localIP[i][0] ) {
+ return qtrue;
+ }
+ }
+ // the RFC1918 class a block will pass the above test
+ return qfalse;
+ }
+
+ // Class B
+ if( (adr.ip[0] & 0xc0) == 0x80 ) {
+ for ( i = 0 ; i < numIP ; i++ ) {
+ if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] ) {
+ return qtrue;
+ }
+ // also check against the RFC1918 class b blocks
+ if( adr.ip[0] == 172 && localIP[i][0] == 172 && (adr.ip[1] & 0xf0) == 16 && (localIP[i][1] & 0xf0) == 16 ) {
+ return qtrue;
+ }
+ }
+ return qfalse;
+ }
+
+ // Class C
+ for ( i = 0 ; i < numIP ; i++ ) {
+ if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] && adr.ip[2] == localIP[i][2] ) {
+ return qtrue;
+ }
+ // also check against the RFC1918 class c blocks
+ if( adr.ip[0] == 192 && localIP[i][0] == 192 && adr.ip[1] == 168 && localIP[i][1] == 168 ) {
+ return qtrue;
+ }
+ }
+ return qfalse;
+}
+
+/*
+==================
+Sys_ShowIP
+==================
+*/
+void Sys_ShowIP(void) {
+ int i;
+
+ for (i = 0; i < numIP; i++) {
+ Com_Printf( "IP: %i.%i.%i.%i\n", localIP[i][0], localIP[i][1], localIP[i][2], localIP[i][3] );
+ }
+}
+
+/*
+=====================
+NET_GetLocalAddress
+=====================
+*/
+#ifdef MACOS_X
+// Don't do a forward mapping from the hostname of the machine to the IP.
+// The reason is that we might have obtained an IP address from DHCP and
+// there might not be any name registered for the machine. On Mac OS X,
+// the machine name defaults to 'localhost' and NetInfo has 127.0.0.1
+// listed for this name. Instead, we want to get a list of all the IP
+// network interfaces on the machine. This code adapted from
+// OmniNetworking.
+
+
+#ifdef _SIZEOF_ADDR_IFREQ
+ // tjw: OSX 10.4 does not have sa_len
+ #define IFR_NEXT(ifr) \
+ ((struct ifreq *) ((char *) ifr + _SIZEOF_ADDR_IFREQ(*ifr)))
+#else
+ // tjw: assume that once upon a time some version did have sa_len
+ #define IFR_NEXT(ifr) \
+ ((struct ifreq *) ((char *) (ifr) + sizeof(*(ifr)) + \
+ MAX(0, (int) (ifr)->ifr_addr.sa_len - (int) sizeof((ifr)->ifr_addr))))
+#endif
+
+void NET_GetLocalAddress( void ) {
+ struct ifreq requestBuffer[MAX_IPS], *linkInterface, *inetInterface;
+ struct ifconf ifc;
+ struct ifreq ifr;
+ struct sockaddr_dl *sdl;
+ int interfaceSocket;
+ int family;
+
+ // Set this early so we can just return if there is an error
+ numIP = 0;
+
+ ifc.ifc_len = sizeof(requestBuffer);
+ ifc.ifc_buf = (caddr_t)requestBuffer;
+
+ // Since we get at this info via an ioctl, we need a temporary little socket.
+ // This will only get AF_INET interfaces, but we probably don't care about
+ // anything else. If we do end up caring later, we should add a
+ // ONAddressFamily and at a -interfaces method to it.
+ family = AF_INET;
+ if ((interfaceSocket = socket(family, SOCK_DGRAM, 0)) < 0) {
+ Com_Printf("NET_GetLocalAddress: Unable to create temporary socket, errno = %d\n", errno);
+ return;
+ }
+
+ if (ioctl(interfaceSocket, SIOCGIFCONF, &ifc) != 0) {
+ Com_Printf("NET_GetLocalAddress: Unable to get list of network interfaces, errno = %d\n", errno);
+ return;
+ }
+
+ linkInterface = (struct ifreq *) ifc.ifc_buf;
+ while ((char *) linkInterface < &ifc.ifc_buf[ifc.ifc_len]) {
+ unsigned int nameLength;
+
+ // The ioctl returns both the entries having the address (AF_INET)
+ // and the link layer entries (AF_LINK). The AF_LINK entry has the
+ // link layer address which contains the interface type. This is the
+ // only way I can see to get this information. We cannot assume that
+ // we will get bot an AF_LINK and AF_INET entry since the interface
+ // may not be configured. For example, if you have a 10Mb port on
+ // the motherboard and a 100Mb card, you may not configure the
+ // motherboard port.
+
+ // For each AF_LINK entry...
+ if (linkInterface->ifr_addr.sa_family == AF_LINK) {
+ // if there is a matching AF_INET entry
+ inetInterface = (struct ifreq *) ifc.ifc_buf;
+ while ((char *) inetInterface < &ifc.ifc_buf[ifc.ifc_len]) {
+ if (inetInterface->ifr_addr.sa_family == AF_INET &&
+ !strncmp(inetInterface->ifr_name, linkInterface->ifr_name,
+ sizeof(linkInterface->ifr_name))) {
+
+ for (nameLength = 0; nameLength < IFNAMSIZ; nameLength++)
+ if (!linkInterface->ifr_name[nameLength])
+ break;
+
+ sdl = (struct sockaddr_dl *)&linkInterface->ifr_addr;
+ // Skip loopback interfaces
+ if (sdl->sdl_type != IFT_LOOP) {
+ // Get the local interface address
+ strncpy(ifr.ifr_name, inetInterface->ifr_name, sizeof(ifr.ifr_name));
+ if (ioctl(interfaceSocket, OSIOCGIFADDR, (caddr_t)&ifr) < 0) {
+ Com_Printf("NET_GetLocalAddress: Unable to get local address "
+ "for interface '%s', errno = %d\n", inetInterface->ifr_name, errno);
+ } else {
+ struct sockaddr_in *sin;
+ int ip;
+
+ sin = (struct sockaddr_in *)&ifr.ifr_addr;
+
+ ip = ntohl(sin->sin_addr.s_addr);
+ localIP[ numIP ][0] = (ip >> 24) & 0xff;
+ localIP[ numIP ][1] = (ip >> 16) & 0xff;
+ localIP[ numIP ][2] = (ip >> 8) & 0xff;
+ localIP[ numIP ][3] = (ip >> 0) & 0xff;
+ Com_Printf( "IP: %i.%i.%i.%i (%s)\n",
+ localIP[ numIP ][0], localIP[ numIP ][1],
+ localIP[ numIP ][2], localIP[ numIP ][3],
+ inetInterface->ifr_name);
+ numIP++;
+ }
+ }
+
+ // We will assume that there is only one AF_INET entry per AF_LINK entry.
+ // What happens when we have an interface that has multiple IP addresses, or
+ // can that even happen?
+ // break;
+ }
+ inetInterface = IFR_NEXT(inetInterface);
+ }
+ }
+ linkInterface = IFR_NEXT(linkInterface);
+ }
+
+ close(interfaceSocket);
+}
+
+#else
+void NET_GetLocalAddress( void ) {
+ char hostname[256];
+ struct hostent *hostInfo;
+ // int error; // bk001204 - unused
+ char *p;
+ int ip;
+ int n;
+
+ if ( gethostname( hostname, 256 ) == -1 ) {
+ return;
+ }
+
+ hostInfo = gethostbyname( hostname );
+ if ( !hostInfo ) {
+ return;
+ }
+
+ Com_Printf( "Hostname: %s\n", hostInfo->h_name );
+ n = 0;
+ while( ( p = hostInfo->h_aliases[n++] ) != NULL ) {
+ Com_Printf( "Alias: %s\n", p );
+ }
+
+ if ( hostInfo->h_addrtype != AF_INET ) {
+ return;
+ }
+
+ numIP = 0;
+ while( ( p = hostInfo->h_addr_list[numIP++] ) != NULL && numIP < MAX_IPS ) {
+ ip = ntohl( *(int *)p );
+ localIP[ numIP ][0] = p[0];
+ localIP[ numIP ][1] = p[1];
+ localIP[ numIP ][2] = p[2];
+ localIP[ numIP ][3] = p[3];
+ Com_Printf( "IP: %i.%i.%i.%i\n", ( ip >> 24 ) & 0xff, ( ip >> 16 ) & 0xff, ( ip >> 8 ) & 0xff, ip & 0xff );
+ }
+}
+#endif
+
+/*
+====================
+NET_OpenIP
+====================
+*/
+// bk001204 - prototype needed
+int NET_IPSocket (char *net_interface, int port);
+void NET_OpenIP (void)
+{
+ cvar_t *ip;
+ int port;
+ int i;
+
+ ip = Cvar_Get ("net_ip", "localhost", 0);
+
+ port = Cvar_Get("net_port", va("%i", PORT_SERVER), 0)->value;
+
+ for ( i = 0 ; i < 10 ; i++ ) {
+ ip_socket = NET_IPSocket (ip->string, port + i);
+ if ( ip_socket ) {
+ Cvar_SetValue( "net_port", port + i );
+ NET_GetLocalAddress();
+ return;
+ }
+ }
+ Com_Error (ERR_FATAL, "Couldn't allocate IP port");
+}
+
+
+/*
+====================
+NET_Init
+====================
+*/
+void NET_Init (void)
+{
+ noudp = Cvar_Get ("net_noudp", "0", 0);
+ // open sockets
+ if (! noudp->value) {
+ NET_OpenIP ();
+ }
+}
+
+
+/*
+====================
+NET_IPSocket
+====================
+*/
+int NET_IPSocket (char *net_interface, int port)
+{
+ int newsocket;
+ struct sockaddr_in address;
+ qboolean _qtrue = qtrue;
+ int i = 1;
+
+ if ( net_interface ) {
+ Com_Printf("Opening IP socket: %s:%i\n", net_interface, port );
+ } else {
+ Com_Printf("Opening IP socket: localhost:%i\n", port );
+ }
+
+ if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ {
+ Com_Printf ("ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString());
+ return 0;
+ }
+
+ // make it non-blocking
+ if (ioctl (newsocket, FIONBIO, &_qtrue) == -1)
+ {
+ Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
+ return 0;
+ }
+
+ // make it broadcast capable
+ if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
+ {
+ Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
+ return 0;
+ }
+
+ if (!net_interface || !net_interface[0] || !Q_stricmp(net_interface, "localhost"))
+ address.sin_addr.s_addr = INADDR_ANY;
+ else
+ Sys_StringToSockaddr (net_interface, (struct sockaddr *)&address);
+
+ if (port == PORT_ANY)
+ address.sin_port = 0;
+ else
+ address.sin_port = htons((short)port);
+
+ address.sin_family = AF_INET;
+
+ if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
+ {
+ Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
+ close (newsocket);
+ return 0;
+ }
+
+ return newsocket;
+}
+
+/*
+====================
+NET_Shutdown
+====================
+*/
+void NET_Shutdown (void)
+{
+ if (ip_socket) {
+ close(ip_socket);
+ ip_socket = 0;
+ }
+}
+
+
+/*
+====================
+NET_ErrorString
+====================
+*/
+char *NET_ErrorString (void)
+{
+ int code;
+
+ code = errno;
+ return strerror (code);
+}
+
+// sleeps msec or until net socket is ready
+void NET_Sleep(int msec)
+{
+ struct timeval timeout;
+ fd_set fdset;
+ extern qboolean stdin_active;
+ int highestfd = 0;
+
+ if (!com_dedicated->integer)
+ return; // we're not a server, just run full speed
+
+ FD_ZERO(&fdset);
+ if (stdin_active)
+ {
+ FD_SET(0, &fdset); // stdin is processed too
+ highestfd = 1;
+ }
+ if(ip_socket)
+ {
+ FD_SET(ip_socket, &fdset); // network socket
+ if(ip_socket >= highestfd)
+ highestfd = ip_socket + 1;
+ }
+
+ if(highestfd)
+ {
+ if(msec >= 0)
+ {
+ timeout.tv_sec = msec/1000;
+ timeout.tv_usec = (msec%1000)*1000;
+ select(highestfd, &fdset, NULL, NULL, &timeout);
+ }
+ else
+ {
+ // Block indefinitely
+ select(highestfd, &fdset, NULL, NULL, NULL);
+ }
+ }
+}
+
diff --git a/src/unix/unix_shared.c b/src/unix/unix_shared.c
new file mode 100644
index 0000000..2c238ca
--- /dev/null
+++ b/src/unix/unix_shared.c
@@ -0,0 +1,452 @@
+/*
+===========================================================================
+Copyright (C) 1999-2005 Id Software, Inc.
+Copyright (C) 2000-2006 Tim Angus
+
+This file is part of Tremulous.
+
+Tremulous 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.
+
+Tremulous 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 Tremulous; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <pwd.h>
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+
+//=============================================================================
+
+// Used to determine CD Path
+static char cdPath[MAX_OSPATH];
+
+// Used to determine local installation path
+static char installPath[MAX_OSPATH];
+
+// Used to determine where to store user-specific files
+static char homePath[MAX_OSPATH];
+
+/*
+================
+Sys_Milliseconds
+================
+*/
+/* base time in seconds, that's our origin
+ timeval:tv_sec is an int:
+ assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038
+ using unsigned long data type to work right with Sys_XTimeToSysTime */
+unsigned long sys_timeBase = 0;
+/* current time in ms, using sys_timeBase as origin
+ NOTE: sys_timeBase*1000 + curtime -> ms since the Epoch
+ 0x7fffffff ms - ~24 days
+ although timeval:tv_usec is an int, I'm not sure wether it is actually used as an unsigned int
+ (which would affect the wrap period) */
+int curtime;
+int Sys_Milliseconds (void)
+{
+ struct timeval tp;
+
+ gettimeofday(&tp, NULL);
+
+ if (!sys_timeBase)
+ {
+ sys_timeBase = tp.tv_sec;
+ return tp.tv_usec/1000;
+ }
+
+ curtime = (tp.tv_sec - sys_timeBase)*1000 + tp.tv_usec/1000;
+
+ return curtime;
+}
+
+#if (defined(__linux__) || defined(__FreeBSD__) || defined(__sun)) && !defined(DEDICATED)
+/*
+================
+Sys_XTimeToSysTime
+sub-frame timing of events returned by X
+X uses the Time typedef - unsigned long
+disable with in_subframe 0
+
+ sys_timeBase*1000 is the number of ms since the Epoch of our origin
+ xtime is in ms and uses the Epoch as origin
+ Time data type is an unsigned long: 0xffffffff ms - ~49 days period
+ I didn't find much info in the XWindow documentation about the wrapping
+ we clamp sys_timeBase*1000 to unsigned long, that gives us the current origin for xtime
+ the computation will still work if xtime wraps (at ~49 days period since the Epoch) after we set sys_timeBase
+
+================
+*/
+extern cvar_t *in_subframe;
+int Sys_XTimeToSysTime (unsigned long xtime)
+{
+ int ret, time, test;
+
+ if (!in_subframe->value)
+ {
+ // if you don't want to do any event times corrections
+ return Sys_Milliseconds();
+ }
+
+ // test the wrap issue
+#if 0
+ // reference values for test: sys_timeBase 0x3dc7b5e9 xtime 0x541ea451 (read these from a test run)
+ // xtime will wrap in 0xabe15bae ms >~ 0x2c0056 s (33 days from Nov 5 2002 -> 8 Dec)
+ // NOTE: date -d '1970-01-01 UTC 1039384002 seconds' +%c
+ // use sys_timeBase 0x3dc7b5e9+0x2c0056 = 0x3df3b63f
+ // after around 5s, xtime would have wrapped around
+ // we get 7132, the formula handles the wrap safely
+ unsigned long xtime_aux,base_aux;
+ int test;
+// Com_Printf("sys_timeBase: %p\n", sys_timeBase);
+// Com_Printf("xtime: %p\n", xtime);
+ xtime_aux = 500; // 500 ms after wrap
+ base_aux = 0x3df3b63f; // the base a few seconds before wrap
+ test = xtime_aux - (unsigned long)(base_aux*1000);
+ Com_Printf("xtime wrap test: %d\n", test);
+#endif
+
+ // some X servers (like suse 8.1's) report weird event times
+ // if the game is loading, resolving DNS, etc. we are also getting old events
+ // so we only deal with subframe corrections that look 'normal'
+ ret = xtime - (unsigned long)(sys_timeBase*1000);
+ time = Sys_Milliseconds();
+ test = time - ret;
+ //printf("delta: %d\n", test);
+ if (test < 0 || test > 30) // in normal conditions I've never seen this go above
+ {
+ return time;
+ }
+
+ return ret;
+}
+#endif
+
+//#if 0 // bk001215 - see snapvector.nasm for replacement
+#if !id386 // rcg010206 - using this for PPC builds...
+long fastftol( float f ) { // bk001213 - from win32/win_shared.c
+ //static int tmp;
+ // __asm fld f
+ //__asm fistp tmp
+ //__asm mov eax, tmp
+ return (long)f;
+}
+
+void Sys_SnapVector( float *v ) { // bk001213 - see win32/win_shared.c
+ // bk001213 - old linux
+ v[0] = rint(v[0]);
+ v[1] = rint(v[1]);
+ v[2] = rint(v[2]);
+}
+#endif
+
+
+void Sys_Mkdir( const char *path )
+{
+ mkdir (path, 0777);
+}
+
+char *strlwr (char *s) {
+ if ( s==NULL ) { // bk001204 - paranoia
+ assert(0);
+ return s;
+ }
+ while (*s) {
+ *s = tolower(*s);
+ s++;
+ }
+ return s; // bk001204 - duh
+}
+
+qboolean Sys_RandomBytes( byte *string, int len )
+{
+ FILE *fp;
+
+ fp = fopen( "/dev/urandom", "r" );
+ if( !fp )
+ return qfalse;
+
+ if( !fread( string, sizeof( byte ), len, fp ) ) {
+ fclose( fp );
+ return qfalse;
+ }
+ fclose( fp );
+ return qtrue;
+}
+
+//============================================
+
+#define MAX_FOUND_FILES 0x1000
+
+// bk001129 - new in 1.26
+void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles ) {
+ char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
+ char filename[MAX_OSPATH];
+ DIR *fdir;
+ struct dirent *d;
+ struct stat st;
+
+ if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
+ return;
+ }
+
+ if (strlen(subdirs)) {
+ Com_sprintf( search, sizeof(search), "%s/%s", basedir, subdirs );
+ }
+ else {
+ Com_sprintf( search, sizeof(search), "%s", basedir );
+ }
+
+ if ((fdir = opendir(search)) == NULL) {
+ return;
+ }
+
+ while ((d = readdir(fdir)) != NULL) {
+ Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
+ if (stat(filename, &st) == -1)
+ continue;
+
+ if (st.st_mode & S_IFDIR) {
+ if (Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..")) {
+ if (strlen(subdirs)) {
+ Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name);
+ }
+ else {
+ Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", d->d_name);
+ }
+ Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles );
+ }
+ }
+ if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
+ break;
+ }
+ Com_sprintf( filename, sizeof(filename), "%s/%s", subdirs, d->d_name );
+ if (!Com_FilterPath( filter, filename, qfalse ))
+ continue;
+ list[ *numfiles ] = CopyString( filename );
+ (*numfiles)++;
+ }
+
+ closedir(fdir);
+}
+
+// bk001129 - in 1.17 this used to be
+// char **Sys_ListFiles( const char *directory, const char *extension, int *numfiles, qboolean wantsubs )
+char **Sys_ListFiles( const char *directory, const char *extension, char *filter, int *numfiles, qboolean wantsubs )
+{
+ struct dirent *d;
+ // char *p; // bk001204 - unused
+ DIR *fdir;
+ qboolean dironly = wantsubs;
+ char search[MAX_OSPATH];
+ int nfiles;
+ char **listCopy;
+ char *list[MAX_FOUND_FILES];
+ //int flag; // bk001204 - unused
+ int i;
+ struct stat st;
+
+ int extLen;
+
+ if (filter) {
+
+ nfiles = 0;
+ Sys_ListFilteredFiles( directory, "", filter, list, &nfiles );
+
+ list[ nfiles ] = NULL;
+ *numfiles = nfiles;
+
+ if (!nfiles)
+ return NULL;
+
+ listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
+ for ( i = 0 ; i < nfiles ; i++ ) {
+ listCopy[i] = list[i];
+ }
+ listCopy[i] = NULL;
+
+ return listCopy;
+ }
+
+ if ( !extension)
+ extension = "";
+
+ if ( extension[0] == '/' && extension[1] == 0 ) {
+ extension = "";
+ dironly = qtrue;
+ }
+
+ extLen = strlen( extension );
+
+ // search
+ nfiles = 0;
+
+ if ((fdir = opendir(directory)) == NULL) {
+ *numfiles = 0;
+ return NULL;
+ }
+
+ while ((d = readdir(fdir)) != NULL) {
+ Com_sprintf(search, sizeof(search), "%s/%s", directory, d->d_name);
+ if (stat(search, &st) == -1)
+ continue;
+ if ((dironly && !(st.st_mode & S_IFDIR)) ||
+ (!dironly && (st.st_mode & S_IFDIR)))
+ continue;
+
+ if (*extension) {
+ if ( strlen( d->d_name ) < strlen( extension ) ||
+ Q_stricmp(
+ d->d_name + strlen( d->d_name ) - strlen( extension ),
+ extension ) ) {
+ continue; // didn't match
+ }
+ }
+
+ if ( nfiles == MAX_FOUND_FILES - 1 )
+ break;
+ list[ nfiles ] = CopyString( d->d_name );
+ nfiles++;
+ }
+
+ list[ nfiles ] = NULL;
+
+ closedir(fdir);
+
+ // return a copy of the list
+ *numfiles = nfiles;
+
+ if ( !nfiles ) {
+ return NULL;
+ }
+
+ listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
+ for ( i = 0 ; i < nfiles ; i++ ) {
+ listCopy[i] = list[i];
+ }
+ listCopy[i] = NULL;
+
+ return listCopy;
+}
+
+void Sys_FreeFileList( char **list ) {
+ int i;
+
+ if ( !list ) {
+ return;
+ }
+
+ for ( i = 0 ; list[i] ; i++ ) {
+ Z_Free( list[i] );
+ }
+
+ Z_Free( list );
+}
+
+char *Sys_Cwd( void )
+{
+ static char cwd[MAX_OSPATH];
+
+ getcwd( cwd, sizeof( cwd ) - 1 );
+ cwd[MAX_OSPATH-1] = 0;
+
+ return cwd;
+}
+
+void Sys_SetDefaultCDPath(const char *path)
+{
+ Q_strncpyz(cdPath, path, sizeof(cdPath));
+}
+
+char *Sys_DefaultCDPath(void)
+{
+ return cdPath;
+}
+
+void Sys_SetDefaultInstallPath(const char *path)
+{
+ Q_strncpyz(installPath, path, sizeof(installPath));
+}
+
+char *Sys_DefaultInstallPath(void)
+{
+ if (*installPath)
+ return installPath;
+ else
+ return Sys_Cwd();
+}
+
+void Sys_SetDefaultHomePath(const char *path)
+{
+ Q_strncpyz(homePath, path, sizeof(homePath));
+}
+
+char *Sys_DefaultHomePath(void)
+{
+ char *p;
+
+ if (*homePath)
+ return homePath;
+
+ if ((p = getenv("HOME")) != NULL) {
+ Q_strncpyz(homePath, p, sizeof(homePath));
+#ifdef MACOS_X
+ Q_strcat(homePath, sizeof(homePath), "/Library/Application Support/Tremulous");
+#else
+ Q_strcat(homePath, sizeof(homePath), "/.tremulous");
+#endif
+ if (mkdir(homePath, 0777)) {
+ if (errno != EEXIST)
+ Sys_Error("Unable to create directory \"%s\", error is %s(%d)\n", homePath, strerror(errno), errno);
+ }
+ return homePath;
+ }
+ return ""; // assume current dir
+}
+
+//============================================
+
+int Sys_GetProcessorId( void )
+{
+ return CPUID_GENERIC;
+}
+
+void Sys_ShowConsole( int visLevel, qboolean quitOnClose )
+{
+}
+
+char *Sys_GetCurrentUser( void )
+{
+ struct passwd *p;
+
+ if ( (p = getpwuid( getuid() )) == NULL ) {
+ return "player";
+ }
+ return p->pw_name;
+}
+
+#if defined(__linux__) || defined(__FreeBSD__)
+// TTimo
+// sysconf() in libc, POSIX.1 compliant
+unsigned int Sys_ProcessorCount(void)
+{
+ return sysconf(_SC_NPROCESSORS_ONLN);
+}
+#endif