Annotation of quake1/gl_vidnt.new, revision 1.1.1.1

1.1       root        1: // gl_vidnt.c -- NT GL vid component
                      2: 
                      3: #include "quakedef.h"
                      4: #include "winquake.h"
                      5: #include "resource.h"
                      6: 
                      7: #define MAX_MODE_LIST  30
                      8: #define VID_ROW_SIZE   3
                      9: #define WARP_WIDTH             320
                     10: #define WARP_HEIGHT            200
                     11: #define MAXWIDTH               1600
                     12: #define MAXHEIGHT              1200
                     13: 
                     14: #define MODE_WINDOWED                  0
                     15: #define MODE_SETTABLE_WINDOW   2
                     16: #define NO_MODE                                        (MODE_WINDOWED - 1)
                     17: #define MODE_FULLSCREEN_DEFAULT        (MODE_WINDOWED + 3)
                     18: 
                     19: typedef struct {
                     20:        modestate_t     type;
                     21:        int                     width;
                     22:        int                     height;
                     23:        int                     modenum;
                     24:        int                     dib;
                     25:        int                     fullscreen;
                     26:        int                     bpp;
                     27:        int                     halfscreen;
                     28:        char            modedesc[13];
                     29: } vmode_t;
                     30: 
                     31: static vmode_t modelist[MAX_MODE_LIST];
                     32: static int             nummodes;
                     33: static vmode_t *pcurrentmode;
                     34: static vmode_t badmode;
                     35: 
                     36: static DEVMODE gdevmode;
                     37: static qboolean        startwindowed = 0;
                     38: static int             firstupdate = 1;
                     39: static qboolean        vid_initialized = false;
                     40: static int             vid_fulldib_on_focus_mode;
                     41: static qboolean        force_minimized, in_mode_set, force_mode_set;
                     42: static int             windowed_mouse;
                     43: static HICON   hIcon;
                     44: 
                     45: int                    DIBWidth, DIBHeight;
                     46: RECT           WindowRect;
                     47: DWORD          WindowStyle, ExWindowStyle;
                     48: 
                     49: HWND   mainwindow, dibwindow;
                     50: MGLDC  *dibdc = NULL,*windc = NULL;
                     51: 
                     52: int                    vid_modenum = NO_MODE;
                     53: int                    vid_testingmode, vid_realmode;
                     54: double         vid_testendtime;
                     55: int                    vid_default = MODE_WINDOWED;
                     56: static int     windowed_default;
                     57: 
                     58: unsigned char  vid_curpal[256*3];
                     59: 
                     60: HGLRC  baseRC;
                     61: HDC            maindc;
                     62: HWND   mainwindow;
                     63: RECT   winrect;
                     64: 
                     65: glvert_t glv;
                     66: 
                     67: cvar_t gl_ztrick = {"gl_ztrick","0"};
                     68: 
                     69: HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow);
                     70: 
                     71: viddef_t       vid;                            // global video state
                     72: 
                     73: unsigned short d_8to16table[256];
                     74: unsigned       d_8to24table[256];
                     75: 
                     76: float          gldepthmin, gldepthmax;
                     77: 
                     78: int    scr_skipupdate;
                     79: qboolean DDActive;
                     80: modestate_t    modestate = MS_UNINIT;
                     81: 
                     82: void VID_MenuDraw (void);
                     83: void VID_MenuKey (int key);
                     84: 
                     85: LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
                     86: void AppActivate(BOOL fActive, BOOL minimize);
                     87: void DestroyDIBWindow (void);
                     88: void DestroyFullDIBWindow (void);
                     89: char *VID_GetModeDescription (int mode);
                     90: void ClearAllStates (void);
                     91: void VID_UpdateWindowStatus (void);
                     92: 
                     93: PROC glArrayElementEXT;
                     94: PROC glColorPointerEXT;
                     95: PROC glTexCoordPointerEXT;
                     96: PROC glVertexPointerEXT;
                     97: 
                     98: //====================================
                     99: 
                    100: cvar_t         vid_mode = {"vid_mode","0", false};
                    101: // Note that 0 is MODE_WINDOWED
                    102: cvar_t         _vid_default_mode = {"_vid_default_mode","0", true};
                    103: // Note that 3 is MODE_FULLSCREEN_DEFAULT
                    104: cvar_t         _vid_default_mode_win = {"_vid_default_mode_win","3", true};
                    105: cvar_t         vid_wait = {"vid_wait","0"};
                    106: cvar_t         vid_nopageflip = {"vid_nopageflip","0", true};
                    107: cvar_t         _vid_wait_override = {"_vid_wait_override", "0", true};
                    108: cvar_t         vid_config_x = {"vid_config_x","800", true};
                    109: cvar_t         vid_config_y = {"vid_config_y","600", true};
                    110: cvar_t         vid_stretch_by_2 = {"vid_stretch_by_2","1", true};
                    111: cvar_t         _windowed_mouse = {"_windowed_mouse","0", true};
                    112: 
                    113: int                    window_center_x, window_center_y, window_x, window_y, window_width, window_height;
                    114: RECT           window_rect;
                    115: qboolean       in_mode_set;
                    116: qboolean       vid_fulldib_on_focus_mode;
                    117: qboolean       force_minimized;
                    118: 
                    119: // direct draw software compatability stuff
                    120: 
                    121: void VID_HandlePause (qboolean pause)
                    122: {
                    123: }
                    124: 
                    125: void VID_ForceLockState (int lk)
                    126: {
                    127: }
                    128: 
                    129: void VID_LockBuffer (void)
                    130: {
                    131: }
                    132: 
                    133: void VID_UnlockBuffer (void)
                    134: {
                    135: }
                    136: 
                    137: int VID_ForceUnlockedAndReturnState (void)
                    138: {
                    139:        return 0;
                    140: }
                    141: 
                    142: void   VID_Update (vrect_t *rects)
                    143: {
                    144: }
                    145: 
                    146: void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
                    147: {
                    148: }
                    149: 
                    150: void D_EndDirectRect (int x, int y, int width, int height)
                    151: {
                    152: }
                    153: 
                    154: 
                    155: void initFatalError(void)
                    156: {
                    157:        MGL_exit();
                    158:        MGL_fatalError(MGL_errorMsg(MGL_result()));
                    159:        exit(EXIT_FAILURE);
                    160: }
                    161: 
                    162: 
                    163: void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify)
                    164: {
                    165:     RECT    RectCenter;
                    166:     int     CenterX, CenterY;
                    167: 
                    168:        if (lefttopjustify)
                    169:        {
                    170:                CenterX = 0;
                    171:                CenterY = 0;
                    172:        }
                    173:        else
                    174:        {
                    175:            CenterX = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
                    176:                CenterY = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
                    177:                CenterX = (CenterX < 0) ? 0: CenterX;
                    178:                CenterY = (CenterY < 0) ? 0: CenterY;
                    179:        }
                    180: 
                    181:        SetWindowPos (hWndCenter, NULL, CenterX, CenterY, 0, 0,
                    182:                                  SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME);
                    183: }
                    184: 
                    185: qboolean VID_SetWindowedMode (int modenum)
                    186: {
                    187:        HDC                             hdc;
                    188:        pixel_format_t  pf;
                    189:        int                             lastmodestate;
                    190: 
                    191:        DDActive = 0;
                    192:        lastmodestate = modestate;
                    193: 
                    194:        DestroyFullDIBWindow ();
                    195: 
                    196: // KJB: Signal to the MGL that we are going back to windowed mode
                    197:        if (!MGL_changeDisplayMode(grWINDOWED))
                    198:                initFatalError();
                    199: 
                    200:        WindowRect.top = WindowRect.left = 0;
                    201: 
                    202:        WindowRect.right = modelist[modenum].width;
                    203:        WindowRect.bottom = modelist[modenum].height;
                    204: 
                    205:        DIBWidth = modelist[modenum].width;
                    206:        DIBHeight = modelist[modenum].height;
                    207: 
                    208:        WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU |
                    209:                                  WS_MINIMIZEBOX;
                    210:        ExWindowStyle = 0;
                    211:        AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, 0);
                    212: 
                    213:        if (lastmodestate != MS_WINDOWED)
                    214:        {
                    215:                // Create the DIB window
                    216:                dibwindow = CreateWindowEx (
                    217:                         ExWindowStyle,
                    218:                         "WinQuake",
                    219:                         "GLQuake",
                    220:                         WindowStyle,
                    221:                         0, 0,
                    222:                         WindowRect.right - WindowRect.left,
                    223:                         WindowRect.bottom - WindowRect.top,
                    224:                         NULL,
                    225:                         NULL,
                    226:                         global_hInstance,
                    227:                         NULL);
                    228: 
                    229:                if (!dibwindow)
                    230:                        Sys_Error ("Couldn't create DIB window");
                    231:        }
                    232:        else
                    233:        {
                    234:                if (!SetWindowPos (dibwindow,
                    235:                                                   NULL,
                    236:                                                   0, 0,
                    237:                                                   WindowRect.right - WindowRect.left,
                    238:                                                   WindowRect.bottom - WindowRect.top,
                    239:                                                   SWP_NOCOPYBITS | SWP_NOZORDER |
                    240:                                                    SWP_HIDEWINDOW))
                    241:                {
                    242:                        Sys_Error ("Couldn't resize DIB window");
                    243:                }
                    244:        }
                    245: 
                    246:        // Center and show the DIB window
                    247:        CenterWindow(dibwindow, WindowRect.right - WindowRect.left,
                    248:                                 WindowRect.bottom - WindowRect.top, false);
                    249: 
                    250:        if (force_minimized)
                    251:                ShowWindow (dibwindow, SW_MINIMIZE);
                    252:        else
                    253:                ShowWindow (dibwindow, SW_SHOWDEFAULT);
                    254: 
                    255:        UpdateWindow (dibwindow);
                    256: 
                    257:        modestate = MS_WINDOWED;
                    258:        vid_fulldib_on_focus_mode = 0;
                    259: 
                    260: // because we have set the background brush for the window to NULL
                    261: // (to avoid flickering when re-sizing the window on the desktop),
                    262: // we clear the window to black when created, otherwise it will be
                    263: // empty while Quake starts up.
                    264:        hdc = GetDC(dibwindow);
                    265:        PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS);
                    266:        ReleaseDC(dibwindow, hdc);
                    267: 
                    268:        /* Create the MGL window DC and the MGL memory DC */
                    269:        if ((windc = MGL_createWindowedDC(dibwindow)) == NULL)
                    270:                MGL_fatalError("Unable to create Windowed DC!");
                    271: 
                    272:        if ((dibdc = MGL_createMemoryDC(DIBWidth,DIBHeight,8,&pf)) == NULL)
                    273:                MGL_fatalError("Unable to create Memory DC!");
                    274: 
                    275:        MGL_makeCurrentDC(dibdc);
                    276: 
                    277:        vid.buffer = vid.conbuffer = vid.direct = dibdc->surface;
                    278:        vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine;
                    279:        vid.numpages = 1;
                    280:        vid.maxwarpwidth = WARP_WIDTH;
                    281:        vid.maxwarpheight = WARP_HEIGHT;
                    282:        vid.height = vid.conheight = DIBHeight;
                    283:        vid.width = vid.conwidth = DIBWidth;
                    284:        vid.aspect = ((float)vid.height / (float)vid.width) *
                    285:                                (320.0 / 240.0);
                    286: 
                    287:        mainwindow = dibwindow;
                    288: 
                    289:        SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon);
                    290:        SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon);
                    291: 
                    292:        return true;
                    293: }
                    294: 
                    295: 
                    296: qboolean VID_SetFullDIBMode (int modenum)
                    297: {
                    298:        HDC                             hdc;
                    299:        pixel_format_t  pf;
                    300:        int                             lastmodestate;
                    301: 
                    302:        DDActive = 0;
                    303: 
                    304:        DestroyDIBWindow ();
                    305: 
                    306:        // KJB: Signal to the MGL that we are going back to windowed mode
                    307:        if (!MGL_changeDisplayMode(grWINDOWED))
                    308:                initFatalError();
                    309: 
                    310:        gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
                    311:        gdevmode.dmBitsPerPel = modelist[modenum].bpp;
                    312:        gdevmode.dmPelsWidth = modelist[modenum].width <<
                    313:                                                   modelist[modenum].halfscreen;
                    314:        gdevmode.dmPelsHeight = modelist[modenum].height;
                    315:        gdevmode.dmSize = sizeof (gdevmode);
                    316: 
                    317:        if (ChangeDisplaySettings (&gdevmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
                    318:                Sys_Error ("Couldn't set fullscreen DIB mode");
                    319: 
                    320:        lastmodestate = modestate;
                    321:        modestate = MS_FULLDIB;
                    322:        vid_fulldib_on_focus_mode = modenum;
                    323: 
                    324:        WindowRect.top = WindowRect.left = 0;
                    325: 
                    326:        hdc = GetDC(NULL);
                    327: 
                    328:        WindowRect.right = modelist[modenum].width;
                    329:        WindowRect.bottom = modelist[modenum].height;
                    330: 
                    331:        ReleaseDC(NULL,hdc);
                    332: 
                    333:        DIBWidth = modelist[modenum].width;
                    334:        DIBHeight = modelist[modenum].height;
                    335: 
                    336:        WindowStyle = WS_POPUP;
                    337:        ExWindowStyle = 0;
                    338:        AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, 0);
                    339: 
                    340:        if (lastmodestate != MS_FULLDIB)
                    341:        {
                    342:                // Create the DIB window
                    343:                dibwindow = CreateWindowEx (
                    344:                         ExWindowStyle,
                    345:                         "WinQuake",
                    346:                         "GLQuake",
                    347:                         WindowStyle,
                    348:                         0, 0,
                    349:                         WindowRect.right - WindowRect.left,
                    350:                         WindowRect.bottom - WindowRect.top,
                    351:                         NULL,
                    352:                         NULL,
                    353:                         global_hInstance,
                    354:                         NULL);
                    355: 
                    356:                if (!dibwindow)
                    357:                        Sys_Error ("Couldn't create DIB window");
                    358:        }
                    359:        else
                    360:        {
                    361:                if (!SetWindowPos (dibwindow,
                    362:                                                   NULL,
                    363:                                                   0, 0,
                    364:                                                   WindowRect.right - WindowRect.left,
                    365:                                                   WindowRect.bottom - WindowRect.top,
                    366:                                                   SWP_NOCOPYBITS | SWP_NOZORDER))
                    367:                {
                    368:                        Sys_Error ("Couldn't resize DIB window");
                    369:                }
                    370:        }
                    371: 
                    372:        // Center and show the DIB window
                    373:        CenterWindow(dibwindow,
                    374:                                 WindowRect.right - WindowRect.left,
                    375:                                 WindowRect.bottom - WindowRect.top,
                    376:                                 modelist[modenum].halfscreen);
                    377:        ShowWindow (dibwindow, SW_SHOWDEFAULT);
                    378:        UpdateWindow (dibwindow);
                    379: 
                    380:        // Because we have set the background brush for the window to NULL
                    381:        // (to avoid flickering when re-sizing the window on the desktop), we
                    382:        // clear the window to black when created, otherwise it will be
                    383:        // empty while Quake starts up.
                    384:        hdc = GetDC(dibwindow);
                    385:        PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS);
                    386:        ReleaseDC(dibwindow, hdc);
                    387: 
                    388:        /* Create the MGL window DC and the MGL memory DC */
                    389:        if ((windc = MGL_createWindowedDC(dibwindow)) == NULL)
                    390:                MGL_fatalError("Unable to create Fullscreen DIB DC!");
                    391: 
                    392:        if ((dibdc = MGL_createMemoryDC(DIBWidth,DIBHeight,8,&pf)) == NULL)
                    393:                MGL_fatalError("Unable to create Memory DC!");
                    394: 
                    395:        MGL_makeCurrentDC(dibdc);
                    396: 
                    397:        vid.buffer = vid.conbuffer = vid.direct = dibdc->surface;
                    398:        vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine;
                    399:        vid.numpages = 1;
                    400:        vid.maxwarpwidth = WARP_WIDTH;
                    401:        vid.maxwarpheight = WARP_HEIGHT;
                    402:        vid.height = vid.conheight = DIBHeight;
                    403:        vid.width = vid.conwidth = DIBWidth;
                    404:        vid.aspect = ((float)vid.height / (float)vid.width) *
                    405:                                (320.0 / 240.0);
                    406: 
                    407: // needed because we're not getting WM_MOVE messages fullscreen on NT
                    408:        window_x = 0;
                    409:        window_y = 0;
                    410: 
                    411:        mainwindow = dibwindow;
                    412:        return true;
                    413: }
                    414: 
                    415: 
                    416: void VID_RestoreOldMode (int original_mode)
                    417: {
                    418:        static qboolean inerror = false;
                    419: 
                    420:        if (inerror)
                    421:                return;
                    422: 
                    423:        in_mode_set = false;
                    424:        inerror = true;
                    425: 
                    426: // make sure mode set happens (video mode changes)
                    427:        vid_modenum = original_mode - 1;
                    428: 
                    429:        if (!VID_SetMode (original_mode, vid_curpal))
                    430:        {
                    431:                vid_modenum = MODE_WINDOWED - 1;
                    432: 
                    433:                if (!VID_SetMode (windowed_default, vid_curpal))
                    434:                        Sys_Error ("Can't set any video mode");
                    435:        }
                    436: 
                    437:        inerror = false;
                    438: }
                    439: 
                    440: 
                    441: int VID_SetMode (int modenum, unsigned char *palette)
                    442: {
                    443:        int                             original_mode, temp;
                    444:        qboolean                stat;
                    445:     MSG                                msg;
                    446:        HDC                             hdc;
                    447: 
                    448:        while ((modenum >= nummodes) || (modenum < 0))
                    449:        {
                    450:                if (vid_modenum == NO_MODE)
                    451:                {
                    452:                        if (modenum == vid_default)
                    453:                        {
                    454:                                modenum = windowed_default;
                    455:                        }
                    456:                        else
                    457:                        {
                    458:                                modenum = vid_default;
                    459:                        }
                    460: 
                    461:                        Cvar_SetValue ("vid_mode", (float)modenum);
                    462:                }
                    463:                else
                    464:                {
                    465:                        Cvar_SetValue ("vid_mode", (float)vid_modenum);
                    466:                        return 0;
                    467:                }
                    468:        }
                    469: 
                    470:        if (!force_mode_set && (modenum == vid_modenum))
                    471:                return true;
                    472: 
                    473: // so Con_Printfs don't mess us up by forcing vid and snd updates
                    474:        temp = scr_disabled_for_loading;
                    475:        scr_disabled_for_loading = true;
                    476:        in_mode_set = true;
                    477: 
                    478:        Snd_ReleaseBuffer ();
                    479:        CDAudio_Pause ();
                    480: 
                    481:        if (vid_modenum == NO_MODE)
                    482:                original_mode = windowed_default;
                    483:        else
                    484:                original_mode = vid_modenum;
                    485: 
                    486:        // Set either the fullscreen or windowed mode
                    487:        if (modelist[modenum].type == MS_WINDOWED)
                    488:        {
                    489:                if (_windowed_mouse.value)
                    490:                {
                    491:                        stat = VID_SetWindowedMode(modenum);
                    492:                        IN_ActivateMouse ();
                    493:                        IN_HideMouse ();
                    494:                }
                    495:                else
                    496:                {
                    497:                        IN_DeactivateMouse ();
                    498:                        IN_ShowMouse ();
                    499:                        stat = VID_SetWindowedMode(modenum);
                    500:                }
                    501:        }
                    502:        else if (modelist[modenum].type == MS_FULLDIB)
                    503:        {
                    504:                stat = VID_SetFullDIBMode(modenum);
                    505:                IN_ActivateMouse ();
                    506:                IN_HideMouse ();
                    507:        }
                    508:        else
                    509:        {
                    510:                Sys_Error ("VID_SetMode: Bad mode type in modelist");
                    511:        }
                    512: 
                    513:        window_width = vid.width;
                    514:        window_height = vid.height;
                    515:        VID_UpdateWindowStatus ();
                    516: 
                    517:        CDAudio_Resume ();
                    518:        Snd_AcquireBuffer ();
                    519:        scr_disabled_for_loading = temp;
                    520: 
                    521:        if (!stat)
                    522:        {
                    523:                VID_RestoreOldMode (original_mode);
                    524:                return false;
                    525:        }
                    526: 
                    527: // now we try to make sure we get the focus on the mode switch, because
                    528: // sometimes in some systems we don't.  We grab the foreground, then
                    529: // finish setting up, pump all our messages, and sleep for a little while
                    530: // to let messages finish bouncing around the system, then we put
                    531: // ourselves at the top of the z order, then grab the foreground again,
                    532: // Who knows if it helps, but it probably doesn't hurt
                    533:        if (!force_minimized)
                    534:                SetForegroundWindow (mainwindow);
                    535: 
                    536:        VID_SetPalette (palette);
                    537: 
                    538:        vid_modenum = modenum;
                    539:        Cvar_SetValue ("vid_mode", (float)vid_modenum);
                    540: 
                    541:        while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
                    542:        {
                    543:        TranslateMessage (&msg);
                    544:        DispatchMessage (&msg);
                    545:        }
                    546: 
                    547:        Sleep (100);
                    548: 
                    549:        if (!force_minimized)
                    550:        {
                    551:                SetWindowPos (mainwindow, HWND_TOP, 0, 0, 0, 0,
                    552:                                  SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW |
                    553:                                  SWP_NOCOPYBITS);
                    554: 
                    555:                SetForegroundWindow (mainwindow);
                    556:        }
                    557: 
                    558: // fix the leftover Alt from any Alt-Tab or the like that switched us away
                    559:        ClearAllStates ();
                    560: 
                    561:        if (!msg_suppress_1)
                    562:                Con_SafePrintf ("%s\n", VID_GetModeDescription (vid_modenum));
                    563: 
                    564:        VID_SetPalette (palette);
                    565: 
                    566:        in_mode_set = false;
                    567:        vid.recalc_refdef = 1;
                    568: 
                    569:        return true;
                    570: }
                    571: 
                    572: 
                    573: /*
                    574: ================
                    575: VID_UpdateWindowStatus
                    576: ================
                    577: */
                    578: void VID_UpdateWindowStatus (void)
                    579: {
                    580: 
                    581:        window_rect.left = window_x;
                    582:        window_rect.top = window_y;
                    583:        window_rect.right = window_x + window_width;
                    584:        window_rect.bottom = window_y + window_height;
                    585:        window_center_x = (window_rect.left + window_rect.right) / 2;
                    586:        window_center_y = (window_rect.top + window_rect.bottom) / 2;
                    587: 
                    588:        IN_UpdateClipCursor ();
                    589: }
                    590: 
                    591: 
                    592: //====================================
                    593: 
                    594: BINDTEXFUNCPTR bindTexFunc;
                    595: DELTEXFUNCPTR delTexFunc;
                    596: 
                    597: #define TEXTURE_EXT_STRING "GL_EXT_texture_object"
                    598: 
                    599: 
                    600: void CheckTextureExtensions (void)
                    601: {
                    602:        char            *tmp;
                    603:        qboolean        texture_ext;
                    604: 
                    605: 
                    606:        texture_ext = FALSE;
                    607:        /* check for texture extension */
                    608:        tmp = (unsigned char *)glGetString(GL_EXTENSIONS);
                    609:        while (*tmp)
                    610:        {
                    611:                if (strncmp((const char*)tmp, TEXTURE_EXT_STRING, strlen(TEXTURE_EXT_STRING)) == 0)
                    612:                        texture_ext = TRUE;
                    613:                tmp++;
                    614:        }
                    615: 
                    616:        if (!texture_ext || COM_CheckParm ("-gl11") )
                    617:        {
                    618: #if 0  //@@@
                    619:                bindTexFunc = glBindTexture;
                    620:                delTexFunc = glDeleteTextures;
                    621: #endif
                    622:                return;
                    623:        }
                    624: 
                    625: /* load library and get procedure adresses for texture extension API */
                    626:        if ((bindTexFunc = (BINDTEXFUNCPTR)
                    627:                wglGetProcAddress((LPCSTR) "glBindTextureEXT")) == NULL)
                    628:        {
                    629:                Sys_Error ("GetProcAddress for BindTextureEXT failed");
                    630:                return;
                    631:        }
                    632:        if ((delTexFunc = (DELTEXFUNCPTR)
                    633:                wglGetProcAddress((LPCSTR) "glDeleteTexturesEXT")) == NULL)
                    634:        {
                    635:                Sys_Error ("GetProcAddress for DeleteTexturesEXT failed");
                    636:                return;
                    637:        }
                    638: 
                    639: }
                    640: 
                    641: void CheckArrayExtensions (void)
                    642: {
                    643:        char            *tmp;
                    644: 
                    645:        /* check for texture extension */
                    646:        tmp = (unsigned char *)glGetString(GL_EXTENSIONS);
                    647:        while (*tmp)
                    648:        {
                    649:                if (strncmp((const char*)tmp, "GL_EXT_vertex_array", strlen("GL_EXT_vertex_array")) == 0)
                    650:                {
                    651:                        if (
                    652: ((glArrayElementEXT = wglGetProcAddress("glArrayElementEXT")) == NULL) ||
                    653: ((glColorPointerEXT = wglGetProcAddress("glColorPointerEXT")) == NULL) ||
                    654: ((glTexCoordPointerEXT = wglGetProcAddress("glTexCoordPointerEXT")) == NULL) ||
                    655: ((glVertexPointerEXT = wglGetProcAddress("glVertexPointerEXT")) == NULL) )
                    656:                        {
                    657:                                Sys_Error ("GetProcAddress for vertex extension failed");
                    658:                                return;
                    659:                        }
                    660:                        return;
                    661:                }
                    662:                tmp++;
                    663:        }
                    664: 
                    665:        Sys_Error ("Vertex array extension not present");
                    666: }
                    667: 
                    668: //int          texture_mode = GL_NEAREST;
                    669: //int          texture_mode = GL_NEAREST_MIPMAP_NEAREST;
                    670: //int          texture_mode = GL_NEAREST_MIPMAP_LINEAR;
                    671: int            texture_mode = GL_LINEAR;
                    672: //int          texture_mode = GL_LINEAR_MIPMAP_NEAREST;
                    673: //int          texture_mode = GL_LINEAR_MIPMAP_LINEAR;
                    674: 
                    675: int            texture_extension_number = 1;
                    676: 
                    677: /*
                    678: ===============
                    679: GL_Init
                    680: ===============
                    681: */
                    682: void GL_Init (void)
                    683: {
                    684:        CheckTextureExtensions ();
                    685: 
                    686:        glCullFace(GL_FRONT);
                    687:        glEnable(GL_TEXTURE_2D);
                    688:        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
                    689:        glShadeModel (GL_FLAT);
                    690: 
                    691:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                    692:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                    693:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                    694:        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                    695: 
                    696:        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                    697: 
                    698: //     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                    699:        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
                    700: 
                    701: #if 0
                    702:        CheckArrayExtensions ();
                    703: 
                    704:        glEnable (GL_VERTEX_ARRAY_EXT);
                    705:        glEnable (GL_TEXTURE_COORD_ARRAY_EXT);
                    706:        glVertexPointerEXT (3, GL_FLOAT, 0, 0, &glv.x);
                    707:        glTexCoordPointerEXT (2, GL_FLOAT, 0, 0, &glv.s);
                    708:        glColorPointerEXT (3, GL_FLOAT, 0, 0, &glv.r);
                    709: #endif
                    710: }
                    711: 
                    712: /*
                    713: =================
                    714: GL_BeginRendering
                    715: 
                    716: =================
                    717: */
                    718: void GL_BeginRendering (int *width, int *height)
                    719: {
                    720:        extern cvar_t gl_clear;
                    721: 
                    722:        GetClientRect(mainwindow, &winrect);
                    723:        *width = winrect.right - winrect.left;
                    724:        *height = winrect.bottom - winrect.top;
                    725: 
                    726:     if (!wglMakeCurrent( maindc, baseRC ))
                    727:                Sys_Error ("wglMakeCurrent failed");
                    728: 
                    729:        if (gl_ztrick.value)
                    730:        {
                    731:                static int trickframe;
                    732: 
                    733:                if (gl_clear.value)
                    734:                        glClear (GL_COLOR_BUFFER_BIT);
                    735: 
                    736:                trickframe++;
                    737:                if (trickframe & 1)
                    738:                {
                    739:                        gldepthmin = 0;
                    740:                        gldepthmax = 0.49999;
                    741:                        glDepthFunc (GL_LEQUAL);
                    742:                }
                    743:                else
                    744:                {
                    745:                        gldepthmin = 1;
                    746:                        gldepthmax = 0.5;
                    747:                        glDepthFunc (GL_GEQUAL);
                    748:                }
                    749:        }
                    750:        else
                    751:        {
                    752:                if (gl_clear.value)
                    753:                        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    754:                else
                    755:                        glClear (GL_DEPTH_BUFFER_BIT);
                    756:                gldepthmin = 0;
                    757:                gldepthmax = 1;
                    758:                glDepthFunc (GL_LEQUAL);
                    759:        }
                    760: 
                    761:        glDepthRange (gldepthmin, gldepthmax);
                    762:        glViewport (0, 0, *width, *height);
                    763: }
                    764: 
                    765: void GL_EndRendering (void)
                    766: {
                    767:        SwapBuffers(maindc);
                    768: }
                    769: 
                    770: 
                    771: 
                    772: 
                    773: void   VID_SetPalette (unsigned char *palette)
                    774: {
                    775:        byte    *pal;
                    776:        int             r,g,b,v;
                    777:        int             i;
                    778:        unsigned        *table;
                    779:        
                    780:        
                    781: //
                    782: // 8 8 8 encoding
                    783: //
                    784:        pal = palette;
                    785:        table = d_8to24table;
                    786:        
                    787:        for (i=0 ; i<256 ; i++)
                    788:        {
                    789:                r = pal[0];
                    790:                g = pal[1];
                    791:                b = pal[2];
                    792:                pal += 3;
                    793:                
                    794: //             v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
                    795: //             v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
                    796:                v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
                    797:                *table++ = v;
                    798:        }
                    799: 
                    800:        d_8to24table[255] &= 0xffffff;  // 255 is transparent
                    801: }
                    802: 
                    803: BOOL   gammaworks;
                    804: void   VID_ShiftPalette (unsigned char *palette)
                    805: {
                    806:        extern  byte ramps[3][256];
                    807:        
                    808: //     VID_SetPalette (palette);
                    809:        gammaworks = SetDeviceGammaRamp (maindc, ramps);
                    810: }
                    811: 
                    812: 
                    813: void   VID_Shutdown (void)
                    814: {
                    815:        HDC                             hdc;
                    816: 
                    817:        if (vid_initialized)
                    818:        {
                    819:                if (modestate == MS_FULLDIB)
                    820:                        ChangeDisplaySettings (NULL, 0);
                    821: 
                    822:                PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)mainwindow, (LPARAM)0);
                    823:                PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0);
                    824: 
                    825:                AppActivate(false, false);
                    826:                DestroyDIBWindow ();
                    827:                DestroyFullDIBWindow ();
                    828:                MGL_exit();
                    829:                vid_testingmode = 0;
                    830:        }
                    831: }
                    832: 
                    833: 
                    834: //==========================================================================
                    835: 
                    836: 
                    837: BOOL bSetupPixelFormat(HDC hDC)
                    838: {
                    839:     static PIXELFORMATDESCRIPTOR pfd = {
                    840:        sizeof(PIXELFORMATDESCRIPTOR),  // size of this pfd
                    841:        1,                              // version number
                    842:        PFD_DRAW_TO_WINDOW              // support window
                    843:        |  PFD_SUPPORT_OPENGL   // support OpenGL
                    844:        |  PFD_DOUBLEBUFFER ,   // double buffered
                    845:        PFD_TYPE_RGBA,                  // RGBA type
                    846:        24,                             // 24-bit color depth
                    847:        0, 0, 0, 0, 0, 0,               // color bits ignored
                    848:        0,                              // no alpha buffer
                    849:        0,                              // shift bit ignored
                    850:        0,                              // no accumulation buffer
                    851:        0, 0, 0, 0,                     // accum bits ignored
                    852:        32,                             // 32-bit z-buffer      
                    853:        0,                              // no stencil buffer
                    854:        0,                              // no auxiliary buffer
                    855:        PFD_MAIN_PLANE,                 // main layer
                    856:        0,                              // reserved
                    857:        0, 0, 0                         // layer masks ignored
                    858:     };
                    859:     int pixelformat;
                    860: 
                    861:     if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 )
                    862:     {
                    863:         MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
                    864:         return FALSE;
                    865:     }
                    866: 
                    867:     if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE)
                    868:     {
                    869:         MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
                    870:         return FALSE;
                    871:     }
                    872: 
                    873:     return TRUE;
                    874: }
                    875: 
                    876: 
                    877: 
                    878: byte        scantokey[128] = 
                    879:                                        { 
                    880: //  0           1       2       3       4       5       6       7 
                    881: //  8           9       A       B       C       D       E       F 
                    882:        0  ,    27,     '1',    '2',    '3',    '4',    '5',    '6', 
                    883:        '7',    '8',    '9',    '0',    '-',    '=',    K_BACKSPACE, 9, // 0 
                    884:        'q',    'w',    'e',    'r',    't',    'y',    'u',    'i', 
                    885:        'o',    'p',    '[',    ']',    13 ,    K_CTRL,'a',  's',      // 1 
                    886:        'd',    'f',    'g',    'h',    'j',    'k',    'l',    ';', 
                    887:        '\'' ,    '`',    K_SHIFT,'\\',  'z',    'x',    'c',    'v',      // 2 
                    888:        'b',    'n',    'm',    ',',    '.',    '/',    K_SHIFT,'*', 
                    889:        K_ALT,' ',   0  ,    K_F1, K_F2, K_F3, K_F4, K_F5,   // 3 
                    890:        K_F6, K_F7, K_F8, K_F9, K_F10,0  ,    0  , K_HOME, 
                    891:        K_UPARROW,K_PGUP,'-',K_LEFTARROW,'5',K_RIGHTARROW,'+',K_END, //4 
                    892:        K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0,             0,              K_F11, 
                    893:        K_F12,0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 5 
                    894:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
                    895:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 6 
                    896:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
                    897:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0         // 7 
                    898:                                        }; 
                    899: 
                    900: byte        shiftscantokey[128] = 
                    901:                                        { 
                    902: //  0           1       2       3       4       5       6       7 
                    903: //  8           9       A       B       C       D       E       F 
                    904:        0  ,    27,     '!',    '@',    '#',    '$',    '%',    '^', 
                    905:        '&',    '*',    '(',    ')',    '_',    '+',    K_BACKSPACE, 9, // 0 
                    906:        'Q',    'W',    'E',    'R',    'T',    'Y',    'U',    'I', 
                    907:        'O',    'P',    '{',    '}',    13 ,    K_CTRL,'A',  'S',      // 1 
                    908:        'D',    'F',    'G',    'H',    'J',    'K',    'L',    ':', 
                    909:        '"' ,    '~',    K_SHIFT,'|',  'Z',    'X',    'C',    'V',      // 2 
                    910:        'B',    'N',    'M',    '<',    '>',    '?',    K_SHIFT,'*', 
                    911:        K_ALT,' ',   0  ,    K_F1, K_F2, K_F3, K_F4, K_F5,   // 3 
                    912:        K_F6, K_F7, K_F8, K_F9, K_F10,0  ,    0  , K_HOME, 
                    913:        K_UPARROW,K_PGUP,'_',K_LEFTARROW,'%',K_RIGHTARROW,'+',K_END, //4 
                    914:        K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0,             0,              K_F11, 
                    915:        K_F12,0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 5 
                    916:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
                    917:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 6 
                    918:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0, 
                    919:        0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0         // 7 
                    920:                                        }; 
                    921: 
                    922: 
                    923: /*
                    924: =======
                    925: MapKey
                    926: 
                    927: Map from windows to quake keynums
                    928: =======
                    929: */
                    930: int MapKey (int key)
                    931: {
                    932:        key = (key>>16)&255;
                    933:        if (key > 127)
                    934:                return 0;
                    935:        return scantokey[key];
                    936: }
                    937: 
                    938: /*
                    939: ===================================================================
                    940: 
                    941: MAIN WINDOW
                    942: 
                    943: ===================================================================
                    944: */
                    945: 
                    946: /*
                    947: ================
                    948: ClearAllStates
                    949: ================
                    950: */
                    951: void ClearAllStates (void)
                    952: {
                    953:        int             i;
                    954:        
                    955: // send an up event for each key, to make sure the server clears them all
                    956:        for (i=0 ; i<256 ; i++)
                    957:        {
                    958:                Key_Event (i, false);
                    959:        }
                    960: 
                    961:        Key_ClearStates ();
                    962:        IN_ClearStates ();
                    963: }
                    964: 
                    965: void AppActivate(BOOL fActive, BOOL minimize)
                    966: /****************************************************************************
                    967: *
                    968: * Function:     AppActivate
                    969: * Parameters:   fActive - True if app is activating
                    970: *
                    971: * Description:  If the application is activating, then swap the system
                    972: *               into SYSPAL_NOSTATIC mode so that our palettes will display
                    973: *               correctly.
                    974: *
                    975: ****************************************************************************/
                    976: {
                    977:     HDC                        hdc;
                    978:     int                        i, t;
                    979:        static BOOL     sound_active;
                    980: 
                    981:        ActiveApp = fActive;
                    982:        Minimized = minimize;
                    983: 
                    984: // enable/disable sound on focus gain/loss
                    985:        if (!ActiveApp && sound_active)
                    986:        {
                    987:                S_BlockSound ();
                    988:                Snd_ReleaseBuffer ();
                    989:                sound_active = false;
                    990:        }
                    991:        else if (ActiveApp && !sound_active)
                    992:        {
                    993:                Snd_AcquireBuffer ();
                    994:                S_UnblockSound ();
                    995:                sound_active = true;
                    996:        }
                    997: 
                    998: // minimize/restore fulldib windows/mouse-capture normal windows on demand
                    999:        if (!in_mode_set)
                   1000:        {
                   1001:                if (fActive)
                   1002:                {
                   1003:                        if (vid_fulldib_on_focus_mode)
                   1004:                        {
                   1005:                                msg_suppress_1 = true;  // don't want to see normal mode set message
                   1006:                                VID_SetMode (vid_fulldib_on_focus_mode, vid_curpal);
                   1007:                                msg_suppress_1 = false;
                   1008: 
                   1009:                                t = in_mode_set;
                   1010:                                in_mode_set = true;
                   1011:                                AppActivate (true, false);
                   1012:                                in_mode_set = t;
                   1013: 
                   1014:                                IN_ActivateMouse ();
                   1015:                                IN_HideMouse ();
                   1016:                        }
                   1017:                        else if ((modestate == MS_WINDOWED) && _windowed_mouse.value)
                   1018:                        {
                   1019:                                IN_ActivateMouse ();
                   1020:                                IN_HideMouse ();
                   1021:                        }
                   1022:                }
                   1023: 
                   1024:                if (!fActive)
                   1025:                {
                   1026:                        if (modestate == MS_FULLDIB)
                   1027:                        {
                   1028:                                force_minimized = true;
                   1029:                                i = vid_fulldib_on_focus_mode;
                   1030:                                msg_suppress_1 = true;  // don't want to see normal mode set message
                   1031:                                VID_SetMode (windowed_default, vid_curpal);
                   1032:                                msg_suppress_1 = false;
                   1033:                                vid_fulldib_on_focus_mode = i;
                   1034:                                force_minimized = false;
                   1035: 
                   1036:                        // we never seem to get WM_ACTIVATE inactive from this mode set, so we'll
                   1037:                        // do it manually
                   1038:                                t = in_mode_set;
                   1039:                                in_mode_set = true;
                   1040:                                AppActivate (false, true);
                   1041:                                in_mode_set = t;
                   1042: 
                   1043:                                IN_DeactivateMouse ();
                   1044:                                IN_ShowMouse ();
                   1045:                        }
                   1046:                        else if ((modestate == MS_WINDOWED) && _windowed_mouse.value)
                   1047:                        {
                   1048:                                IN_DeactivateMouse ();
                   1049:                                IN_ShowMouse ();
                   1050:                        }
                   1051:                }
                   1052:        }
                   1053: }
                   1054: 
                   1055: 
                   1056: /* main window procedure */
                   1057: LONG WINAPI MainWndProc (
                   1058:     HWND    hWnd,
                   1059:     UINT    uMsg,
                   1060:     WPARAM  wParam,
                   1061:     LPARAM  lParam)
                   1062: {
                   1063:     LONG    lRet = 1;
                   1064:     RECT       rect;
                   1065:        int             fwKeys, xPos, yPos, fActive, fMinimized, temp;
                   1066: 
                   1067:     GetClientRect(hWnd, &rect);
                   1068: 
                   1069:     switch (uMsg)
                   1070:     {
                   1071:                case WM_CREATE:
                   1072:                {
                   1073:                        //@@@
                   1074:                }
                   1075:                break;
                   1076: 
                   1077:                case WM_MOVE:
                   1078:                        window_x = (int) LOWORD(lParam);
                   1079:                        window_y = (int) HIWORD(lParam);
                   1080:                        VID_UpdateWindowStatus ();
                   1081:                        break;
                   1082: 
                   1083:                case WM_KEYDOWN:
                   1084:                case WM_SYSKEYDOWN:
                   1085:                        Key_Event (MapKey(lParam), true);
                   1086:                        break;
                   1087:                        
                   1088:                case WM_KEYUP:
                   1089:                case WM_SYSKEYUP:
                   1090:                        Key_Event (MapKey(lParam), false);
                   1091:                        break;
                   1092: 
                   1093:        // this is complicated because Win32 seems to pack multiple mouse events into
                   1094:        // one update sometimes, so we always check all states and look for events
                   1095:                case WM_LBUTTONDOWN:
                   1096:                case WM_LBUTTONUP:
                   1097:                case WM_RBUTTONDOWN:
                   1098:                case WM_RBUTTONUP:
                   1099:                case WM_MBUTTONDOWN:
                   1100:                case WM_MBUTTONUP:
                   1101:                case WM_MOUSEMOVE:
                   1102:                        temp = 0;
                   1103: 
                   1104:                        if (wParam & MK_LBUTTON)
                   1105:                                temp |= 1;
                   1106: 
                   1107:                        if (wParam & MK_RBUTTON)
                   1108:                                temp |= 2;
                   1109: 
                   1110:                        if (wParam & MK_MBUTTON)
                   1111:                                temp |= 4;
                   1112: 
                   1113:                        IN_MouseEvent (temp);
                   1114: 
                   1115:                        break;
                   1116: 
                   1117: 
                   1118:        case WM_SIZE:
                   1119:             break;
                   1120: 
                   1121:            case WM_CLOSE:
                   1122:         {
                   1123:            HGLRC hRC;
                   1124:            HDC   hDC;
                   1125: 
                   1126:                 /* release and free the device context and rendering context */
                   1127:            hRC = wglGetCurrentContext();
                   1128:            hDC = wglGetCurrentDC();
                   1129: 
                   1130:            wglMakeCurrent(NULL, NULL);
                   1131: 
                   1132:            if (hRC)
                   1133:                wglDeleteContext(hRC);
                   1134:            if (hDC)
                   1135:                ReleaseDC(hWnd, hDC);
                   1136: 
                   1137:             /* call destroy window to cleanup and go away */
                   1138:             DestroyWindow (hWnd);
                   1139:         }
                   1140:         break;
                   1141: 
                   1142:                case WM_ACTIVATE:
                   1143:                        fActive = LOWORD(wParam);
                   1144:                        fMinimized = (BOOL) HIWORD(wParam);
                   1145:                        AppActivate(!(fActive == WA_INACTIVE), fMinimized);
                   1146: 
                   1147:                // fix the leftover Alt from any Alt-Tab or the like that switched us away
                   1148:                        ClearAllStates ();
                   1149: 
                   1150:                        break;
                   1151: 
                   1152:            case WM_DESTROY:
                   1153:         {
                   1154:            HGLRC hRC;
                   1155:            HDC   hDC;
                   1156: 
                   1157:                 /* release and free the device context and rendering context */
                   1158:            hRC = wglGetCurrentContext();
                   1159:            hDC = wglGetCurrentDC();
                   1160: 
                   1161:            wglMakeCurrent(NULL, NULL);
                   1162: 
                   1163:            if (hRC)
                   1164:                wglDeleteContext(hRC);
                   1165:            if (hDC)
                   1166:                ReleaseDC(hWnd, hDC);
                   1167: 
                   1168:             PostQuitMessage (0);
                   1169:         }
                   1170:         break;
                   1171: 
                   1172:        default:
                   1173:             /* pass all unhandled messages to DefWindowProc */
                   1174:             lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
                   1175:         break;
                   1176:     }
                   1177: 
                   1178:     /* return 1 if handled message, 0 if not */
                   1179:     return lRet;
                   1180: }
                   1181: 
                   1182: 
                   1183: /*
                   1184: =================
                   1185: VID_NumModes
                   1186: =================
                   1187: */
                   1188: int VID_NumModes (void)
                   1189: {
                   1190:        return nummodes;
                   1191: }
                   1192: 
                   1193:        
                   1194: /*
                   1195: =================
                   1196: VID_GetModePtr
                   1197: =================
                   1198: */
                   1199: vmode_t *VID_GetModePtr (int modenum)
                   1200: {
                   1201: 
                   1202:        if ((modenum >= 0) && (modenum < nummodes))
                   1203:                return &modelist[modenum];
                   1204:        else
                   1205:                return &badmode;
                   1206: }
                   1207: 
                   1208: 
                   1209: /*
                   1210: =================
                   1211: VID_GetModeDescription
                   1212: =================
                   1213: */
                   1214: char *VID_GetModeDescription (int mode)
                   1215: {
                   1216:        char            *pinfo;
                   1217:        vmode_t         *pv;
                   1218: 
                   1219:        if ((mode < 0) || (mode >= nummodes))
                   1220:                return NULL;
                   1221: 
                   1222:        pv = VID_GetModePtr (mode);
                   1223:        pinfo = pv->modedesc;
                   1224:        return pinfo;
                   1225: }
                   1226: 
                   1227: 
                   1228: /*
                   1229: =================
                   1230: VID_GetModeDescription2
                   1231: 
                   1232: Tacks on "windowed" or "fullscreen"
                   1233: =================
                   1234: */
                   1235: char *VID_GetModeDescription2 (int mode)
                   1236: {
                   1237:        static char     pinfo[40];
                   1238:        vmode_t         *pv;
                   1239: 
                   1240:        if ((mode < 0) || (mode >= nummodes))
                   1241:                return NULL;
                   1242: 
                   1243:        pv = VID_GetModePtr (mode);
                   1244: 
                   1245:        if (modelist[mode].type == MS_FULLDIB)
                   1246:        {
                   1247:                sprintf(pinfo,"%s fullscreen", pv->modedesc);
                   1248:        }
                   1249:        else
                   1250:        {
                   1251:                sprintf(pinfo, "%s windowed", pv->modedesc);
                   1252:        }
                   1253: 
                   1254:        return pinfo;
                   1255: }
                   1256: 
                   1257: 
                   1258: // KJB: Added this to return the mode driver name in description for console
                   1259: 
                   1260: char *VID_GetExtModeDescription (int mode)
                   1261: {
                   1262:        static char     pinfo[40];
                   1263:        vmode_t         *pv;
                   1264: 
                   1265:        if ((mode < 0) || (mode >= nummodes))
                   1266:                return NULL;
                   1267: 
                   1268:        pv = VID_GetModePtr (mode);
                   1269:        if (modelist[mode].type == MS_FULLDIB)
                   1270:        {
                   1271:                sprintf(pinfo,"%s fullscreen DIB", pv->modedesc);
                   1272:        }
                   1273:        else
                   1274:        {
                   1275:                sprintf(pinfo, "%s windowed", pv->modedesc);
                   1276:        }
                   1277: 
                   1278:        return pinfo;
                   1279: }
                   1280: 
                   1281: 
                   1282: void DestroyDIBWindow (void)
                   1283: {
                   1284: 
                   1285:        if (modestate == MS_WINDOWED)
                   1286:        {
                   1287:                // Destroy the DIB window and associated MGL DC's
                   1288:                DestroyWindow(dibwindow);
                   1289:                MGL_destroyDC(windc);
                   1290:                MGL_destroyDC(dibdc);
                   1291:                windc = dibdc = NULL;
                   1292:        }
                   1293: }
                   1294: 
                   1295: 
                   1296: void DestroyFullDIBWindow (void)
                   1297: {
                   1298:        if (modestate == MS_FULLDIB)
                   1299:        {
                   1300:                ChangeDisplaySettings (NULL, 0);
                   1301: 
                   1302:        // Destroy the fullscreen DIB window and associated MGL DC's
                   1303:                DestroyWindow(dibwindow);
                   1304:                MGL_destroyDC(windc);
                   1305:                MGL_destroyDC(dibdc);
                   1306:                windc = dibdc = NULL;
                   1307:        }
                   1308: }
                   1309: 
                   1310: 
                   1311: /*
                   1312: =================
                   1313: VID_DescribeCurrentMode_f
                   1314: =================
                   1315: */
                   1316: void VID_DescribeCurrentMode_f (void)
                   1317: {
                   1318:        Con_Printf ("%s\n", VID_GetExtModeDescription (vid_modenum));
                   1319: }
                   1320: 
                   1321: 
                   1322: /*
                   1323: =================
                   1324: VID_NumModes_f
                   1325: =================
                   1326: */
                   1327: void VID_NumModes_f (void)
                   1328: {
                   1329: 
                   1330:        if (nummodes == 1)
                   1331:                Con_Printf ("%d video mode is available\n", nummodes);
                   1332:        else
                   1333:                Con_Printf ("%d video modes are available\n", nummodes);
                   1334: }
                   1335: 
                   1336: 
                   1337: /*
                   1338: =================
                   1339: VID_DescribeMode_f
                   1340: =================
                   1341: */
                   1342: void VID_DescribeMode_f (void)
                   1343: {
                   1344:        int             modenum;
                   1345:        
                   1346:        modenum = Q_atoi (Cmd_Argv(1));
                   1347: 
                   1348:        Con_Printf ("%s\n", VID_GetExtModeDescription (modenum));
                   1349: }
                   1350: 
                   1351: 
                   1352: /*
                   1353: =================
                   1354: VID_DescribeModes_f
                   1355: =================
                   1356: */
                   1357: void VID_DescribeModes_f (void)
                   1358: {
                   1359:        int                     i, lnummodes;
                   1360:        char            *pinfo;
                   1361:        vmode_t         *pv;
                   1362: 
                   1363:        lnummodes = VID_NumModes ();
                   1364: 
                   1365:        for (i=0 ; i<lnummodes ; i++)
                   1366:        {
                   1367:                pv = VID_GetModePtr (i);
                   1368:                pinfo = VID_GetExtModeDescription (i);
                   1369:                Con_Printf ("%2d: %s\n", i, pinfo);
                   1370:        }
                   1371: }
                   1372: 
                   1373: 
                   1374: /*
                   1375: =================
                   1376: VID_TestMode_f
                   1377: =================
                   1378: */
                   1379: void VID_TestMode_f (void)
                   1380: {
                   1381:        int             modenum;
                   1382:        double  testduration;
                   1383: 
                   1384:        if (!vid_testingmode)
                   1385:        {
                   1386:                modenum = Q_atoi (Cmd_Argv(1));
                   1387: 
                   1388:                if (VID_SetMode (modenum, vid_curpal))
                   1389:                {
                   1390:                        vid_testingmode = 1;
                   1391:                        testduration = Q_atof (Cmd_Argv(2));
                   1392:                        if (testduration == 0)
                   1393:                                testduration = 5.0;
                   1394:                        vid_testendtime = realtime + testduration;
                   1395:                }
                   1396:        }
                   1397: }
                   1398: 
                   1399: 
                   1400: /*
                   1401: =================
                   1402: VID_ForceMode_f
                   1403: =================
                   1404: */
                   1405: void VID_ForceMode_f (void)
                   1406: {
                   1407:        int             modenum;
                   1408:        double  testduration;
                   1409: 
                   1410:        if (!vid_testingmode)
                   1411:        {
                   1412:                modenum = Q_atoi (Cmd_Argv(1));
                   1413: 
                   1414:                force_mode_set = 1;
                   1415:                VID_SetMode (modenum, vid_curpal);
                   1416:                force_mode_set = 0;
                   1417:        }
                   1418: }
                   1419: 
                   1420: 
                   1421: void registerAllMemDrivers(void)
                   1422: {
                   1423:        /* Register memory context drivers */
                   1424:        MGL_registerDriver(MGL_PACKED8NAME,PACKED8_driver);
                   1425: }
                   1426: 
                   1427: 
                   1428: void VID_InitMGLDIB (HINSTANCE hInstance)
                   1429: {
                   1430:        WNDCLASS                wc;
                   1431:        HDC                             hdc;
                   1432:        int                             i;
                   1433: 
                   1434:        hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON2));
                   1435: 
                   1436:        /* Register the frame class */
                   1437:     wc.style         = 0;
                   1438:     wc.lpfnWndProc   = (WNDPROC)MainWndProc;
                   1439:     wc.cbClsExtra    = 0;
                   1440:     wc.cbWndExtra    = 0;
                   1441:     wc.hInstance     = hInstance;
                   1442:     wc.hIcon         = 0;
                   1443:     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
                   1444:        wc.hbrBackground = NULL;
                   1445:     wc.lpszMenuName  = 0;
                   1446:     wc.lpszClassName = "WinQuake";
                   1447: 
                   1448:     if (!RegisterClass (&wc) )
                   1449:                Sys_Error ("Couldn't register window class");
                   1450: 
                   1451:        /* Find the size for the DIB window */
                   1452:        /* Initialise the MGL for windowed operation */
                   1453:        MGL_setAppInstance(hInstance);
                   1454:        MGL_registerEventProc(MainWndProc);
                   1455:        registerAllMemDrivers();
                   1456:        MGL_initWindowed("");
                   1457: 
                   1458:        modelist[0].type = MS_WINDOWED;
                   1459:        modelist[0].width = 320;
                   1460:        modelist[0].height = 240;
                   1461:        strcpy (modelist[0].modedesc, "320x240");
                   1462:        modelist[0].modenum = MODE_WINDOWED;
                   1463:        modelist[0].dib = 1;
                   1464:        modelist[0].fullscreen = 0;
                   1465:        modelist[0].halfscreen = 0;
                   1466:        modelist[0].bpp = 0;
                   1467: 
                   1468:        modelist[1].type = MS_WINDOWED;
                   1469:        modelist[1].width = 640;
                   1470:        modelist[1].height = 480;
                   1471:        strcpy (modelist[1].modedesc, "640x480");
                   1472:        modelist[1].modenum = MODE_WINDOWED + 1;
                   1473:        modelist[1].dib = 1;
                   1474:        modelist[1].fullscreen = 0;
                   1475:        modelist[1].halfscreen = 0;
                   1476:        modelist[1].bpp = 0;
                   1477: 
                   1478:        modelist[2].type = MS_WINDOWED;
                   1479:        modelist[2].width = 800;
                   1480:        modelist[2].height = 600;
                   1481:        strcpy (modelist[2].modedesc, "800x600");
                   1482:        modelist[2].modenum = MODE_WINDOWED + 2;
                   1483:        modelist[2].dib = 1;
                   1484:        modelist[2].fullscreen = 0;
                   1485:        modelist[2].halfscreen = 0;
                   1486:        modelist[2].bpp = 0;
                   1487: 
                   1488:        vid_default = MODE_WINDOWED;
                   1489:        windowed_default = vid_default;
                   1490: 
                   1491:        ReleaseDC(NULL,hdc);
                   1492: 
                   1493:        nummodes = 3;   // reserve space for windowed mode
                   1494: 
                   1495:        DDActive = 0;
                   1496: }
                   1497: 
                   1498: 
                   1499: /*
                   1500: =================
                   1501: VID_InitFullDIB
                   1502: =================
                   1503: */
                   1504: void VID_InitFullDIB (HINSTANCE hInstance)
                   1505: {
                   1506:        DEVMODE devmode;
                   1507:        int             i, modenum, cmodes, originalnummodes;
                   1508:        BOOL    stat;
                   1509: 
                   1510: // enumerate >8 bpp modes
                   1511:        originalnummodes = nummodes;
                   1512:        modenum = 0;
                   1513: 
                   1514:        do
                   1515:        {
                   1516:                stat = EnumDisplaySettings (NULL, modenum, &devmode);
                   1517: 
                   1518:                if ((devmode.dmBitsPerPel > 8) &&
                   1519:                        (devmode.dmPelsWidth <= MAXWIDTH) &&
                   1520:                        (devmode.dmPelsHeight <= MAXHEIGHT) &&
                   1521:                        (nummodes < MAX_MODE_LIST))
                   1522:                {
                   1523:                        devmode.dmFields = DM_BITSPERPEL |
                   1524:                                                           DM_PELSWIDTH |
                   1525:                                                           DM_PELSHEIGHT;
                   1526: 
                   1527:                        if (ChangeDisplaySettings (&devmode, CDS_TEST | CDS_FULLSCREEN) ==
                   1528:                                        DISP_CHANGE_SUCCESSFUL)
                   1529:                        {
                   1530:                                modelist[nummodes].type = MS_FULLDIB;
                   1531:                                modelist[nummodes].width = devmode.dmPelsWidth;
                   1532:                                modelist[nummodes].height = devmode.dmPelsHeight;
                   1533:                                modelist[nummodes].modenum = 0;
                   1534:                                modelist[nummodes].halfscreen = 0;
                   1535:                                modelist[nummodes].dib = 1;
                   1536:                                modelist[nummodes].fullscreen = 1;
                   1537:                                modelist[nummodes].bpp = devmode.dmBitsPerPel;
                   1538:                                sprintf (modelist[nummodes].modedesc, "%dx%d",
                   1539:                                                 devmode.dmPelsWidth, devmode.dmPelsHeight);
                   1540: 
                   1541:                        // if the width is more than twice the height, reduce it by half because this
                   1542:                        // is probably a dual-screen monitor
                   1543:                                if (!COM_CheckParm("-noadjustaspect"))
                   1544:                                {
                   1545:                                        if (modelist[nummodes].width > (modelist[nummodes].height << 1))
                   1546:                                        {
                   1547:                                                modelist[nummodes].width >>= 1;
                   1548:                                                modelist[nummodes].halfscreen = 1;
                   1549:                                                sprintf (modelist[nummodes].modedesc, "%dx%d",
                   1550:                                                                 modelist[nummodes].width,
                   1551:                                                                 modelist[nummodes].height);
                   1552:                                        }
                   1553:                                }
                   1554: 
                   1555:                                nummodes++;
                   1556:                        }
                   1557:                }
                   1558: 
                   1559:                modenum++;
                   1560:        } while (stat);
                   1561: 
                   1562:        if (nummodes != originalnummodes)
                   1563:                vid_default = MODE_FULLSCREEN_DEFAULT;
                   1564:        else
                   1565:                Con_SafePrintf ("No fullscreen DIB modes found\n");
                   1566: }
                   1567: 
                   1568: 
                   1569: /*
                   1570: ===================
                   1571: VID_Init
                   1572: ===================
                   1573: */
                   1574: void   VID_Init (unsigned char *palette)
                   1575: {
                   1576:        int             i;
                   1577:        int             basenummodes;
                   1578:        byte    *ptmp;
                   1579:        char    gldir[MAX_OSPATH];
                   1580: 
                   1581:        Cvar_RegisterVariable (&vid_mode);
                   1582:        Cvar_RegisterVariable (&vid_wait);
                   1583:        Cvar_RegisterVariable (&vid_nopageflip);
                   1584:        Cvar_RegisterVariable (&_vid_wait_override);
                   1585:        Cvar_RegisterVariable (&_vid_default_mode);
                   1586:        Cvar_RegisterVariable (&_vid_default_mode_win);
                   1587:        Cvar_RegisterVariable (&vid_config_x);
                   1588:        Cvar_RegisterVariable (&vid_config_y);
                   1589:        Cvar_RegisterVariable (&vid_stretch_by_2);
                   1590:        Cvar_RegisterVariable (&_windowed_mouse);
                   1591:        Cvar_RegisterVariable (&gl_ztrick);
                   1592: 
                   1593: 
                   1594:        Cmd_AddCommand ("vid_testmode", VID_TestMode_f);
                   1595:        Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
                   1596:        Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f);
                   1597:        Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f);
                   1598:        Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f);
                   1599:        Cmd_AddCommand ("vid_forcemode", VID_ForceMode_f);
                   1600: 
                   1601:        VID_InitMGLDIB (global_hInstance);
                   1602: 
                   1603:        basenummodes = nummodes;
                   1604: 
                   1605:        VID_InitFullDIB (global_hInstance);
                   1606: 
                   1607:        vid_initialized = true;
                   1608: 
                   1609:        vid.maxwarpwidth = WARP_WIDTH;
                   1610:        vid.maxwarpheight = WARP_HEIGHT;
                   1611:        vid.colormap = host_colormap;
                   1612:        vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
                   1613:        vid_testingmode = 0;
                   1614: 
                   1615:        if (COM_CheckParm("-startwindowed"))
                   1616:        {
                   1617:                startwindowed = 1;
                   1618:                vid_default = windowed_default;
                   1619:        }
                   1620: 
                   1621:        VID_SetMode (vid_default, palette);
                   1622: 
                   1623:        sprintf (gldir, "%s/glquake", com_gamedir);
                   1624:        Sys_mkdir (gldir);
                   1625: 
                   1626:     maindc = GetDC(mainwindow);
                   1627:        bSetupPixelFormat(maindc);
                   1628: 
                   1629:     baseRC = wglCreateContext( maindc );
                   1630:        if (!baseRC)
                   1631:                Sys_Error ("wglCreateContect failed");
                   1632:     if (!wglMakeCurrent( maindc, baseRC ))
                   1633:                Sys_Error ("wglMakeCurrent failed");
                   1634: 
                   1635:        GL_Init ();
                   1636: 
                   1637:        vid_realmode = vid_modenum;
                   1638: 
                   1639:        VID_SetPalette (palette);
                   1640: 
                   1641:        vid_menudrawfn = VID_MenuDraw;
                   1642:        vid_menukeyfn = VID_MenuKey;
                   1643: 
                   1644:        strcpy (badmode.modedesc, "Bad mode");
                   1645: }
                   1646: 
                   1647: 
                   1648: //========================================================
                   1649: // Video menu stuff
                   1650: //========================================================
                   1651: 
                   1652: extern void M_Menu_Options_f (void);
                   1653: extern void M_Print (int cx, int cy, char *str);
                   1654: extern void M_PrintWhite (int cx, int cy, char *str);
                   1655: extern void M_DrawCharacter (int cx, int line, int num);
                   1656: extern void M_DrawTransPic (int x, int y, qpic_t *pic);
                   1657: extern void M_DrawPic (int x, int y, qpic_t *pic);
                   1658: 
                   1659: static int     vid_line, vid_wmodes;
                   1660: 
                   1661: typedef struct
                   1662: {
                   1663:        int             modenum;
                   1664:        char    *desc;
                   1665:        int             iscur;
                   1666: } modedesc_t;
                   1667: 
                   1668: #define MAX_COLUMN_SIZE                5
                   1669: #define MODE_AREA_HEIGHT       (MAX_COLUMN_SIZE + 6)
                   1670: #define MAX_MODEDESCS          (MAX_COLUMN_SIZE*3)
                   1671: 
                   1672: static modedesc_t      modedescs[MAX_MODEDESCS];
                   1673: 
                   1674: /*
                   1675: ================
                   1676: VID_MenuDraw
                   1677: ================
                   1678: */
                   1679: void VID_MenuDraw (void)
                   1680: {
                   1681:        qpic_t          *p;
                   1682:        char            *ptr;
                   1683:        int                     lnummodes, i, j, k, column, row, dup, dupmode;
                   1684:        char            temp[100];
                   1685:        vmode_t         *pv;
                   1686: 
                   1687:        p = Draw_CachePic ("gfx/vidmodes.lmp");
                   1688:        M_DrawPic ( (320-p->width)/2, 4, p);
                   1689: 
                   1690:        for (i=0 ; i<3 ; i++)
                   1691:        {
                   1692:                ptr = VID_GetModeDescription (i);
                   1693:                modedescs[i].modenum = modelist[i].modenum;
                   1694:                modedescs[i].desc = ptr;
                   1695:                modedescs[i].iscur = 0;
                   1696: 
                   1697:                if (vid_modenum == i)
                   1698:                        modedescs[i].iscur = 1;
                   1699:        }
                   1700: 
                   1701:        vid_wmodes = 3;
                   1702:        lnummodes = VID_NumModes ();
                   1703:        
                   1704:        for (i=3 ; i<lnummodes ; i++)
                   1705:        {
                   1706:                ptr = VID_GetModeDescription (i);
                   1707:                pv = VID_GetModePtr (i);
                   1708: 
                   1709:                k = vid_wmodes;
                   1710: 
                   1711:                modedescs[k].modenum = i;
                   1712:                modedescs[k].desc = ptr;
                   1713:                modedescs[k].iscur = 0;
                   1714: 
                   1715:                if (i == vid_modenum)
                   1716:                        modedescs[k].iscur = 1;
                   1717: 
                   1718:                vid_wmodes++;
                   1719:        }
                   1720: 
                   1721:        M_Print (13*8, 36, "Windowed Modes");
                   1722: 
                   1723:        column = 16;
                   1724:        row = 36+2*8;
                   1725: 
                   1726:        for (i=0 ; i<3; i++)
                   1727:        {
                   1728:                if (modedescs[i].iscur)
                   1729:                        M_PrintWhite (column, row, modedescs[i].desc);
                   1730:                else
                   1731:                        M_Print (column, row, modedescs[i].desc);
                   1732: 
                   1733:                column += 13*8;
                   1734:        }
                   1735: 
                   1736:        if (vid_wmodes > 3)
                   1737:        {
                   1738:                M_Print (12*8, 36+4*8, "Fullscreen Modes");
                   1739: 
                   1740:                column = 16;
                   1741:                row = 36+6*8;
                   1742: 
                   1743:                for (i=3 ; i<vid_wmodes ; i++)
                   1744:                {
                   1745:                        if (modedescs[i].iscur)
                   1746:                                M_PrintWhite (column, row, modedescs[i].desc);
                   1747:                        else
                   1748:                                M_Print (column, row, modedescs[i].desc);
                   1749: 
                   1750:                        column += 13*8;
                   1751: 
                   1752:                        if (((i - 3) % VID_ROW_SIZE) == (VID_ROW_SIZE - 1))
                   1753:                        {
                   1754:                                column = 16;
                   1755:                                row += 8;
                   1756:                        }
                   1757:                }
                   1758:        }
                   1759: 
                   1760: // line cursor
                   1761:        if (vid_testingmode)
                   1762:        {
                   1763:                sprintf (temp, "TESTING %s",
                   1764:                                modedescs[vid_line].desc);
                   1765:                M_Print (13*8, 36 + MODE_AREA_HEIGHT * 8 + 8*4, temp);
                   1766:                M_Print (9*8, 36 + MODE_AREA_HEIGHT * 8 + 8*6,
                   1767:                                "Please wait 5 seconds...");
                   1768:        }
                   1769:        else
                   1770:        {
                   1771:                M_Print (9*8, 36 + MODE_AREA_HEIGHT * 8 + 8,
                   1772:                                "Press Enter to set mode");
                   1773:                M_Print (6*8, 36 + MODE_AREA_HEIGHT * 8 + 8*3,
                   1774:                                "T to test mode for 5 seconds");
                   1775:                ptr = VID_GetModeDescription2 (vid_modenum);
                   1776: 
                   1777:                if (ptr)
                   1778:                {
                   1779:                        sprintf (temp, "D to set default: %s", ptr);
                   1780:                        M_Print (2*8, 36 + MODE_AREA_HEIGHT * 8 + 8*5, temp);
                   1781:                }
                   1782: 
                   1783:                ptr = VID_GetModeDescription2 ((int)_vid_default_mode_win.value);
                   1784: 
                   1785:                if (ptr)
                   1786:                {
                   1787:                        sprintf (temp, "Current default: %s", ptr);
                   1788:                        M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*6, temp);
                   1789:                }
                   1790: 
                   1791:                M_Print (15*8, 36 + MODE_AREA_HEIGHT * 8 + 8*8,
                   1792:                                "Esc to exit");
                   1793: 
                   1794:                row = 36 + 2*8 + (vid_line / VID_ROW_SIZE) * 8;
                   1795:                column = 8 + (vid_line % VID_ROW_SIZE) * 13*8;
                   1796: 
                   1797:                if (vid_line >= 3)
                   1798:                        row += 3*8;
                   1799: 
                   1800:                M_DrawCharacter (column, row, 12+((int)(realtime*4)&1));
                   1801:        }
                   1802: }
                   1803: 
                   1804: 
                   1805: /*
                   1806: ================
                   1807: VID_MenuKey
                   1808: ================
                   1809: */
                   1810: void VID_MenuKey (int key)
                   1811: {
                   1812:        if (vid_testingmode)
                   1813:                return;
                   1814: 
                   1815:        switch (key)
                   1816:        {
                   1817:        case K_ESCAPE:
                   1818:                S_LocalSound ("misc/menu1.wav");
                   1819:                M_Menu_Options_f ();
                   1820:                break;
                   1821: 
                   1822:        case K_LEFTARROW:
                   1823:                S_LocalSound ("misc/menu1.wav");
                   1824:                vid_line = ((vid_line / VID_ROW_SIZE) * VID_ROW_SIZE) +
                   1825:                                   ((vid_line + 2) % VID_ROW_SIZE);
                   1826: 
                   1827:                if (vid_line >= vid_wmodes)
                   1828:                        vid_line = vid_wmodes - 1;
                   1829:                break;
                   1830: 
                   1831:        case K_RIGHTARROW:
                   1832:                S_LocalSound ("misc/menu1.wav");
                   1833:                vid_line = ((vid_line / VID_ROW_SIZE) * VID_ROW_SIZE) +
                   1834:                                   ((vid_line + 4) % VID_ROW_SIZE);
                   1835: 
                   1836:                if (vid_line >= vid_wmodes)
                   1837:                        vid_line = (vid_line / VID_ROW_SIZE) * VID_ROW_SIZE;
                   1838:                break;
                   1839: 
                   1840:        case K_UPARROW:
                   1841:                S_LocalSound ("misc/menu1.wav");
                   1842:                vid_line -= VID_ROW_SIZE;
                   1843: 
                   1844:                if (vid_line < 0)
                   1845:                {
                   1846:                        vid_line += ((vid_wmodes + (VID_ROW_SIZE - 1)) /
                   1847:                                        VID_ROW_SIZE) * VID_ROW_SIZE;
                   1848: 
                   1849:                        while (vid_line >= vid_wmodes)
                   1850:                                vid_line -= VID_ROW_SIZE;
                   1851:                }
                   1852:                break;
                   1853: 
                   1854:        case K_DOWNARROW:
                   1855:                S_LocalSound ("misc/menu1.wav");
                   1856:                vid_line += VID_ROW_SIZE;
                   1857: 
                   1858:                if (vid_line >= vid_wmodes)
                   1859:                {
                   1860:                        vid_line -= ((vid_wmodes + (VID_ROW_SIZE - 1)) /
                   1861:                                        VID_ROW_SIZE) * VID_ROW_SIZE;
                   1862: 
                   1863:                        while (vid_line < 0)
                   1864:                                vid_line += VID_ROW_SIZE;
                   1865:                }
                   1866:                break;
                   1867: 
                   1868:        case K_ENTER:
                   1869:                S_LocalSound ("misc/menu1.wav");
                   1870:                VID_SetMode (modedescs[vid_line].modenum, vid_curpal);
                   1871:                break;
                   1872: 
                   1873:        case 'T':
                   1874:        case 't':
                   1875:                S_LocalSound ("misc/menu1.wav");
                   1876:        // have to set this before setting the mode because WM_PAINT
                   1877:        // happens during the mode set and does a VID_Update, which
                   1878:        // checks vid_testingmode
                   1879:                vid_testingmode = 1;
                   1880:                vid_testendtime = realtime + 5.0;
                   1881: 
                   1882:                if (!VID_SetMode (modedescs[vid_line].modenum, vid_curpal))
                   1883:                {
                   1884:                        vid_testingmode = 0;
                   1885:                }
                   1886:                break;
                   1887: 
                   1888:        case 'D':
                   1889:        case 'd':
                   1890:                S_LocalSound ("misc/menu1.wav");
                   1891:                firstupdate = 0;
                   1892:                Cvar_SetValue ("_vid_default_mode_win", vid_modenum);
                   1893:                break;
                   1894: 
                   1895:        default:
                   1896:                break;
                   1897:        }
                   1898: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.