diff options
Diffstat (limited to 'src/unix')
| -rw-r--r-- | src/unix/MacSupport/SLA-dmg.sh | 30 | ||||
| -rw-r--r-- | src/unix/MacSupport/SLA.r | 260 | ||||
| -rw-r--r-- | src/unix/MacSupport/Tremulous.icns | bin | 0 -> 78419 bytes | |||
| -rw-r--r-- | src/unix/MacSupport/ioquake3.icns | bin | 0 -> 35224 bytes | |||
| -rw-r--r-- | src/unix/ftola.s | 161 | ||||
| -rw-r--r-- | src/unix/linux_glimp.c | 1794 | ||||
| -rw-r--r-- | src/unix/linux_joystick.c | 212 | ||||
| -rw-r--r-- | src/unix/linux_local.h | 50 | ||||
| -rw-r--r-- | src/unix/linux_qgl.c | 4206 | ||||
| -rw-r--r-- | src/unix/linux_signals.c | 65 | ||||
| -rw-r--r-- | src/unix/linux_snd.c | 295 | ||||
| -rw-r--r-- | src/unix/matha.s | 425 | ||||
| -rw-r--r-- | src/unix/qasm.h | 51 | ||||
| -rw-r--r-- | src/unix/sdl_glimp.c | 1755 | ||||
| -rw-r--r-- | src/unix/sdl_snd.c | 363 | ||||
| -rw-r--r-- | src/unix/snapvectora.s | 104 | ||||
| -rw-r--r-- | src/unix/snd_mixa.s | 218 | ||||
| -rw-r--r-- | src/unix/unix_glw.h | 39 | ||||
| -rw-r--r-- | src/unix/unix_main.c | 1494 | ||||
| -rw-r--r-- | src/unix/unix_net.c | 684 | ||||
| -rw-r--r-- | src/unix/unix_shared.c | 452 | 
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 Binary files differnew file mode 100644 index 0000000..c4106ac --- /dev/null +++ b/src/unix/MacSupport/Tremulous.icns diff --git a/src/unix/MacSupport/ioquake3.icns b/src/unix/MacSupport/ioquake3.icns Binary files differnew file mode 100644 index 0000000..30e3b67 --- /dev/null +++ b/src/unix/MacSupport/ioquake3.icns 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  | 
