vid_dll.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // Main windowed and fullscreen graphics interface module. This module
  16. // is used for both the software and OpenGL rendering versions of the
  17. // Quake refresh engine.
  18. #include <assert.h>
  19. #include <float.h>
  20. #include "..\client\client.h"
  21. #include "winquake.h"
  22. //#include "zmouse.h"
  23. // Structure containing functions exported from refresh DLL
  24. refexport_t re;
  25. cvar_t *win_noalttab;
  26. #ifndef WM_MOUSEWHEEL
  27. #define WM_MOUSEWHEEL (WM_MOUSELAST+1) // message that will be supported by the OS
  28. #endif
  29. static UINT MSH_MOUSEWHEEL;
  30. // Console variables that we need to access from this module
  31. cvar_t *vid_gamma;
  32. cvar_t *vid_ref; // Name of Refresh DLL loaded
  33. cvar_t *vid_xpos; // X coordinate of window position
  34. cvar_t *vid_ypos; // Y coordinate of window position
  35. cvar_t *vid_fullscreen;
  36. // Global variables used internally by this module
  37. viddef_t viddef; // global video state; used by other modules
  38. HINSTANCE reflib_library; // Handle to refresh DLL
  39. qboolean reflib_active = 0;
  40. HWND cl_hwnd; // Main window handle for life of program
  41. #define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
  42. LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  43. static qboolean s_alttab_disabled;
  44. extern unsigned sys_msg_time;
  45. /*
  46. ** WIN32 helper functions
  47. */
  48. extern qboolean s_win95;
  49. static void WIN_DisableAltTab( void )
  50. {
  51. if ( s_alttab_disabled )
  52. return;
  53. if ( s_win95 )
  54. {
  55. BOOL old;
  56. SystemParametersInfo( SPI_SCREENSAVERRUNNING, 1, &old, 0 );
  57. }
  58. else
  59. {
  60. RegisterHotKey( 0, 0, MOD_ALT, VK_TAB );
  61. RegisterHotKey( 0, 1, MOD_ALT, VK_RETURN );
  62. }
  63. s_alttab_disabled = true;
  64. }
  65. static void WIN_EnableAltTab( void )
  66. {
  67. if ( s_alttab_disabled )
  68. {
  69. if ( s_win95 )
  70. {
  71. BOOL old;
  72. SystemParametersInfo( SPI_SCREENSAVERRUNNING, 0, &old, 0 );
  73. }
  74. else
  75. {
  76. UnregisterHotKey( 0, 0 );
  77. UnregisterHotKey( 0, 1 );
  78. }
  79. s_alttab_disabled = false;
  80. }
  81. }
  82. /*
  83. ==========================================================================
  84. DLL GLUE
  85. ==========================================================================
  86. */
  87. #define MAXPRINTMSG 4096
  88. void VID_Printf (int print_level, char *fmt, ...)
  89. {
  90. va_list argptr;
  91. char msg[MAXPRINTMSG];
  92. static qboolean inupdate;
  93. va_start (argptr,fmt);
  94. vsprintf (msg,fmt,argptr);
  95. va_end (argptr);
  96. if (print_level == PRINT_ALL)
  97. {
  98. Com_Printf ("%s", msg);
  99. }
  100. else if ( print_level == PRINT_DEVELOPER )
  101. {
  102. Com_DPrintf ("%s", msg);
  103. }
  104. else if ( print_level == PRINT_ALERT )
  105. {
  106. MessageBox( 0, msg, "PRINT_ALERT", MB_ICONWARNING );
  107. OutputDebugString( msg );
  108. }
  109. }
  110. void VID_Error (int err_level, char *fmt, ...)
  111. {
  112. va_list argptr;
  113. char msg[MAXPRINTMSG];
  114. static qboolean inupdate;
  115. va_start (argptr,fmt);
  116. vsprintf (msg,fmt,argptr);
  117. va_end (argptr);
  118. Com_Error (err_level,"%s", msg);
  119. }
  120. //==========================================================================
  121. byte scantokey[128] =
  122. {
  123. // 0 1 2 3 4 5 6 7
  124. // 8 9 A B C D E F
  125. 0 , 27, '1', '2', '3', '4', '5', '6',
  126. '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0
  127. 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
  128. 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1
  129. 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
  130. '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2
  131. 'b', 'n', 'm', ',', '.', '/', K_SHIFT,'*',
  132. K_ALT,' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
  133. K_F6, K_F7, K_F8, K_F9, K_F10, K_PAUSE, 0 , K_HOME,
  134. K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW, K_KP_PLUS,K_END, //4
  135. K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0, 0, K_F11,
  136. K_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
  137. 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
  138. 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
  139. 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
  140. 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
  141. };
  142. /*
  143. =======
  144. MapKey
  145. Map from windows to quake keynums
  146. =======
  147. */
  148. int MapKey (int key)
  149. {
  150. int result;
  151. int modified = ( key >> 16 ) & 255;
  152. qboolean is_extended = false;
  153. if ( modified > 127)
  154. return 0;
  155. if ( key & ( 1 << 24 ) )
  156. is_extended = true;
  157. result = scantokey[modified];
  158. if ( !is_extended )
  159. {
  160. switch ( result )
  161. {
  162. case K_HOME:
  163. return K_KP_HOME;
  164. case K_UPARROW:
  165. return K_KP_UPARROW;
  166. case K_PGUP:
  167. return K_KP_PGUP;
  168. case K_LEFTARROW:
  169. return K_KP_LEFTARROW;
  170. case K_RIGHTARROW:
  171. return K_KP_RIGHTARROW;
  172. case K_END:
  173. return K_KP_END;
  174. case K_DOWNARROW:
  175. return K_KP_DOWNARROW;
  176. case K_PGDN:
  177. return K_KP_PGDN;
  178. case K_INS:
  179. return K_KP_INS;
  180. case K_DEL:
  181. return K_KP_DEL;
  182. default:
  183. return result;
  184. }
  185. }
  186. else
  187. {
  188. switch ( result )
  189. {
  190. case 0x0D:
  191. return K_KP_ENTER;
  192. case 0x2F:
  193. return K_KP_SLASH;
  194. case 0xAF:
  195. return K_KP_PLUS;
  196. }
  197. return result;
  198. }
  199. }
  200. void AppActivate(BOOL fActive, BOOL minimize)
  201. {
  202. Minimized = minimize;
  203. Key_ClearStates();
  204. // we don't want to act like we're active if we're minimized
  205. if (fActive && !Minimized)
  206. ActiveApp = true;
  207. else
  208. ActiveApp = false;
  209. // minimize/restore mouse-capture on demand
  210. if (!ActiveApp)
  211. {
  212. IN_Activate (false);
  213. CDAudio_Activate (false);
  214. S_Activate (false);
  215. if ( win_noalttab->value )
  216. {
  217. WIN_EnableAltTab();
  218. }
  219. }
  220. else
  221. {
  222. IN_Activate (true);
  223. CDAudio_Activate (true);
  224. S_Activate (true);
  225. if ( win_noalttab->value )
  226. {
  227. WIN_DisableAltTab();
  228. }
  229. }
  230. }
  231. /*
  232. ====================
  233. MainWndProc
  234. main window procedure
  235. ====================
  236. */
  237. LONG WINAPI MainWndProc (
  238. HWND hWnd,
  239. UINT uMsg,
  240. WPARAM wParam,
  241. LPARAM lParam)
  242. {
  243. LONG lRet = 0;
  244. if ( uMsg == MSH_MOUSEWHEEL )
  245. {
  246. if ( ( ( int ) wParam ) > 0 )
  247. {
  248. Key_Event( K_MWHEELUP, true, sys_msg_time );
  249. Key_Event( K_MWHEELUP, false, sys_msg_time );
  250. }
  251. else
  252. {
  253. Key_Event( K_MWHEELDOWN, true, sys_msg_time );
  254. Key_Event( K_MWHEELDOWN, false, sys_msg_time );
  255. }
  256. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  257. }
  258. switch (uMsg)
  259. {
  260. case WM_MOUSEWHEEL:
  261. /*
  262. ** this chunk of code theoretically only works under NT4 and Win98
  263. ** since this message doesn't exist under Win95
  264. */
  265. if ( ( short ) HIWORD( wParam ) > 0 )
  266. {
  267. Key_Event( K_MWHEELUP, true, sys_msg_time );
  268. Key_Event( K_MWHEELUP, false, sys_msg_time );
  269. }
  270. else
  271. {
  272. Key_Event( K_MWHEELDOWN, true, sys_msg_time );
  273. Key_Event( K_MWHEELDOWN, false, sys_msg_time );
  274. }
  275. break;
  276. case WM_HOTKEY:
  277. return 0;
  278. case WM_CREATE:
  279. cl_hwnd = hWnd;
  280. MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG");
  281. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  282. case WM_PAINT:
  283. SCR_DirtyScreen (); // force entire screen to update next frame
  284. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  285. case WM_DESTROY:
  286. // let sound and input know about this?
  287. cl_hwnd = NULL;
  288. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  289. case WM_ACTIVATE:
  290. {
  291. int fActive, fMinimized;
  292. // KJB: Watch this for problems in fullscreen modes with Alt-tabbing.
  293. fActive = LOWORD(wParam);
  294. fMinimized = (BOOL) HIWORD(wParam);
  295. AppActivate( fActive != WA_INACTIVE, fMinimized);
  296. if ( reflib_active )
  297. re.AppActivate( !( fActive == WA_INACTIVE ) );
  298. }
  299. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  300. case WM_MOVE:
  301. {
  302. int xPos, yPos;
  303. RECT r;
  304. int style;
  305. if (!vid_fullscreen->value)
  306. {
  307. xPos = (short) LOWORD(lParam); // horizontal position
  308. yPos = (short) HIWORD(lParam); // vertical position
  309. r.left = 0;
  310. r.top = 0;
  311. r.right = 1;
  312. r.bottom = 1;
  313. style = GetWindowLong( hWnd, GWL_STYLE );
  314. AdjustWindowRect( &r, style, FALSE );
  315. Cvar_SetValue( "vid_xpos", xPos + r.left);
  316. Cvar_SetValue( "vid_ypos", yPos + r.top);
  317. vid_xpos->modified = false;
  318. vid_ypos->modified = false;
  319. if (ActiveApp)
  320. IN_Activate (true);
  321. }
  322. }
  323. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  324. // this is complicated because Win32 seems to pack multiple mouse events into
  325. // one update sometimes, so we always check all states and look for events
  326. case WM_LBUTTONDOWN:
  327. case WM_LBUTTONUP:
  328. case WM_RBUTTONDOWN:
  329. case WM_RBUTTONUP:
  330. case WM_MBUTTONDOWN:
  331. case WM_MBUTTONUP:
  332. case WM_MOUSEMOVE:
  333. {
  334. int temp;
  335. temp = 0;
  336. if (wParam & MK_LBUTTON)
  337. temp |= 1;
  338. if (wParam & MK_RBUTTON)
  339. temp |= 2;
  340. if (wParam & MK_MBUTTON)
  341. temp |= 4;
  342. IN_MouseEvent (temp);
  343. }
  344. break;
  345. case WM_SYSCOMMAND:
  346. if ( wParam == SC_SCREENSAVE )
  347. return 0;
  348. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  349. case WM_SYSKEYDOWN:
  350. if ( wParam == 13 )
  351. {
  352. if ( vid_fullscreen )
  353. {
  354. Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
  355. }
  356. return 0;
  357. }
  358. // fall through
  359. case WM_KEYDOWN:
  360. Key_Event( MapKey( lParam ), true, sys_msg_time);
  361. break;
  362. case WM_SYSKEYUP:
  363. case WM_KEYUP:
  364. Key_Event( MapKey( lParam ), false, sys_msg_time);
  365. break;
  366. case MM_MCINOTIFY:
  367. {
  368. LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  369. lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam);
  370. }
  371. break;
  372. default: // pass all unhandled messages to DefWindowProc
  373. return DefWindowProc (hWnd, uMsg, wParam, lParam);
  374. }
  375. /* return 0 if handled message, 1 if not */
  376. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  377. }
  378. /*
  379. ============
  380. VID_Restart_f
  381. Console command to re-start the video mode and refresh DLL. We do this
  382. simply by setting the modified flag for the vid_ref variable, which will
  383. cause the entire video mode and refresh DLL to be reset on the next frame.
  384. ============
  385. */
  386. void VID_Restart_f (void)
  387. {
  388. vid_ref->modified = true;
  389. }
  390. void VID_Front_f( void )
  391. {
  392. SetWindowLong( cl_hwnd, GWL_EXSTYLE, WS_EX_TOPMOST );
  393. SetForegroundWindow( cl_hwnd );
  394. }
  395. /*
  396. ** VID_GetModeInfo
  397. */
  398. typedef struct vidmode_s
  399. {
  400. const char *description;
  401. int width, height;
  402. int mode;
  403. } vidmode_t;
  404. vidmode_t vid_modes[] =
  405. {
  406. { "Mode 0: 320x240", 320, 240, 0 },
  407. { "Mode 1: 400x300", 400, 300, 1 },
  408. { "Mode 2: 512x384", 512, 384, 2 },
  409. { "Mode 3: 640x480", 640, 480, 3 },
  410. { "Mode 4: 800x600", 800, 600, 4 },
  411. { "Mode 5: 960x720", 960, 720, 5 },
  412. { "Mode 6: 1024x768", 1024, 768, 6 },
  413. { "Mode 7: 1152x864", 1152, 864, 7 },
  414. { "Mode 8: 1280x960", 1280, 960, 8 },
  415. { "Mode 9: 1600x1200", 1600, 1200, 9 }
  416. };
  417. qboolean VID_GetModeInfo( int *width, int *height, int mode )
  418. {
  419. if ( mode < 0 || mode >= VID_NUM_MODES )
  420. return false;
  421. *width = vid_modes[mode].width;
  422. *height = vid_modes[mode].height;
  423. return true;
  424. }
  425. /*
  426. ** VID_UpdateWindowPosAndSize
  427. */
  428. void VID_UpdateWindowPosAndSize( int x, int y )
  429. {
  430. RECT r;
  431. int style;
  432. int w, h;
  433. r.left = 0;
  434. r.top = 0;
  435. r.right = viddef.width;
  436. r.bottom = viddef.height;
  437. style = GetWindowLong( cl_hwnd, GWL_STYLE );
  438. AdjustWindowRect( &r, style, FALSE );
  439. w = r.right - r.left;
  440. h = r.bottom - r.top;
  441. MoveWindow( cl_hwnd, vid_xpos->value, vid_ypos->value, w, h, TRUE );
  442. }
  443. /*
  444. ** VID_NewWindow
  445. */
  446. void VID_NewWindow ( int width, int height)
  447. {
  448. viddef.width = width;
  449. viddef.height = height;
  450. cl.force_refdef = true; // can't use a paused refdef
  451. }
  452. void VID_FreeReflib (void)
  453. {
  454. if ( !FreeLibrary( reflib_library ) )
  455. Com_Error( ERR_FATAL, "Reflib FreeLibrary failed" );
  456. memset (&re, 0, sizeof(re));
  457. reflib_library = NULL;
  458. reflib_active = false;
  459. }
  460. /*
  461. ==============
  462. VID_LoadRefresh
  463. ==============
  464. */
  465. qboolean VID_LoadRefresh( char *name )
  466. {
  467. refimport_t ri;
  468. GetRefAPI_t GetRefAPI;
  469. if ( reflib_active )
  470. {
  471. re.Shutdown();
  472. VID_FreeReflib ();
  473. }
  474. Com_Printf( "------- Loading %s -------\n", name );
  475. if ( ( reflib_library = LoadLibrary( name ) ) == 0 )
  476. {
  477. Com_Printf( "LoadLibrary(\"%s\") failed\n", name );
  478. return false;
  479. }
  480. ri.Cmd_AddCommand = Cmd_AddCommand;
  481. ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
  482. ri.Cmd_Argc = Cmd_Argc;
  483. ri.Cmd_Argv = Cmd_Argv;
  484. ri.Cmd_ExecuteText = Cbuf_ExecuteText;
  485. ri.Con_Printf = VID_Printf;
  486. ri.Sys_Error = VID_Error;
  487. ri.FS_LoadFile = FS_LoadFile;
  488. ri.FS_FreeFile = FS_FreeFile;
  489. ri.FS_Gamedir = FS_Gamedir;
  490. ri.Cvar_Get = Cvar_Get;
  491. ri.Cvar_Set = Cvar_Set;
  492. ri.Cvar_SetValue = Cvar_SetValue;
  493. ri.Vid_GetModeInfo = VID_GetModeInfo;
  494. ri.Vid_MenuInit = VID_MenuInit;
  495. ri.Vid_NewWindow = VID_NewWindow;
  496. if ( ( GetRefAPI = (void *) GetProcAddress( reflib_library, "GetRefAPI" ) ) == 0 )
  497. Com_Error( ERR_FATAL, "GetProcAddress failed on %s", name );
  498. re = GetRefAPI( ri );
  499. if (re.api_version != API_VERSION)
  500. {
  501. VID_FreeReflib ();
  502. Com_Error (ERR_FATAL, "%s has incompatible api_version", name);
  503. }
  504. if ( re.Init( global_hInstance, MainWndProc ) == -1 )
  505. {
  506. re.Shutdown();
  507. VID_FreeReflib ();
  508. return false;
  509. }
  510. Com_Printf( "------------------------------------\n");
  511. reflib_active = true;
  512. //======
  513. //PGM
  514. vidref_val = VIDREF_OTHER;
  515. if(vid_ref)
  516. {
  517. if(!strcmp (vid_ref->string, "gl"))
  518. vidref_val = VIDREF_GL;
  519. else if(!strcmp(vid_ref->string, "soft"))
  520. vidref_val = VIDREF_SOFT;
  521. }
  522. //PGM
  523. //======
  524. return true;
  525. }
  526. /*
  527. ============
  528. VID_CheckChanges
  529. This function gets called once just before drawing each frame, and it's sole purpose in life
  530. is to check to see if any of the video mode parameters have changed, and if they have to
  531. update the rendering DLL and/or video mode to match.
  532. ============
  533. */
  534. void VID_CheckChanges (void)
  535. {
  536. char name[100];
  537. if ( win_noalttab->modified )
  538. {
  539. if ( win_noalttab->value )
  540. {
  541. WIN_DisableAltTab();
  542. }
  543. else
  544. {
  545. WIN_EnableAltTab();
  546. }
  547. win_noalttab->modified = false;
  548. }
  549. if ( vid_ref->modified )
  550. {
  551. cl.force_refdef = true; // can't use a paused refdef
  552. S_StopAllSounds();
  553. }
  554. while (vid_ref->modified)
  555. {
  556. /*
  557. ** refresh has changed
  558. */
  559. vid_ref->modified = false;
  560. vid_fullscreen->modified = true;
  561. cl.refresh_prepped = false;
  562. cls.disable_screen = true;
  563. Com_sprintf( name, sizeof(name), "ref_%s.dll", vid_ref->string );
  564. if ( !VID_LoadRefresh( name ) )
  565. {
  566. if ( strcmp (vid_ref->string, "soft") == 0 )
  567. Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!");
  568. Cvar_Set( "vid_ref", "soft" );
  569. /*
  570. ** drop the console if we fail to load a refresh
  571. */
  572. if ( cls.key_dest != key_console )
  573. {
  574. Con_ToggleConsole_f();
  575. }
  576. }
  577. cls.disable_screen = false;
  578. }
  579. /*
  580. ** update our window position
  581. */
  582. if ( vid_xpos->modified || vid_ypos->modified )
  583. {
  584. if (!vid_fullscreen->value)
  585. VID_UpdateWindowPosAndSize( vid_xpos->value, vid_ypos->value );
  586. vid_xpos->modified = false;
  587. vid_ypos->modified = false;
  588. }
  589. }
  590. /*
  591. ============
  592. VID_Init
  593. ============
  594. */
  595. void VID_Init (void)
  596. {
  597. /* Create the video variables so we know how to start the graphics drivers */
  598. vid_ref = Cvar_Get ("vid_ref", "soft", CVAR_ARCHIVE);
  599. vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
  600. vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
  601. vid_fullscreen = Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE);
  602. vid_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE );
  603. win_noalttab = Cvar_Get( "win_noalttab", "0", CVAR_ARCHIVE );
  604. /* Add some console commands that we want to handle */
  605. Cmd_AddCommand ("vid_restart", VID_Restart_f);
  606. Cmd_AddCommand ("vid_front", VID_Front_f);
  607. /*
  608. ** this is a gross hack but necessary to clamp the mode for 3Dfx
  609. */
  610. #if 0
  611. {
  612. cvar_t *gl_driver = Cvar_Get( "gl_driver", "opengl32", 0 );
  613. cvar_t *gl_mode = Cvar_Get( "gl_mode", "3", 0 );
  614. if ( stricmp( gl_driver->string, "3dfxgl" ) == 0 )
  615. {
  616. Cvar_SetValue( "gl_mode", 3 );
  617. viddef.width = 640;
  618. viddef.height = 480;
  619. }
  620. }
  621. #endif
  622. /* Disable the 3Dfx splash screen */
  623. putenv("FX_GLIDE_NO_SPLASH=0");
  624. /* Start the graphics mode and load refresh DLL */
  625. VID_CheckChanges();
  626. }
  627. /*
  628. ============
  629. VID_Shutdown
  630. ============
  631. */
  632. void VID_Shutdown (void)
  633. {
  634. if ( reflib_active )
  635. {
  636. re.Shutdown ();
  637. VID_FreeReflib ();
  638. }
  639. }