Annotation of quake2/win32/rw_imp.c, revision 1.1.1.2

1.1       root        1: /*
1.1.1.2 ! root        2: Copyright (C) 1997-2001 Id Software, Inc.
        !             3: 
        !             4: This program is free software; you can redistribute it and/or
        !             5: modify it under the terms of the GNU General Public License
        !             6: as published by the Free Software Foundation; either version 2
        !             7: of the License, or (at your option) any later version.
        !             8: 
        !             9: This program is distributed in the hope that it will be useful,
        !            10: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
        !            12: 
        !            13: See the GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with this program; if not, write to the Free Software
        !            17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            18: 
        !            19: */
        !            20: /*
1.1       root       21: ** RW_IMP.C
                     22: **
                     23: ** This file contains ALL Win32 specific stuff having to do with the
                     24: ** software refresh.  When a port is being made the following functions
                     25: ** must be implemented by the port:
                     26: **
                     27: ** SWimp_EndFrame
                     28: ** SWimp_Init
                     29: ** SWimp_SetPalette
                     30: ** SWimp_Shutdown
                     31: */
                     32: #include "..\ref_soft\r_local.h"
                     33: #include "rw_win.h"
                     34: #include "winquake.h"
                     35: 
                     36: // Console variables that we need to access from this module
                     37: 
                     38: swwstate_t sww_state;
                     39: 
                     40: /*
                     41: ** VID_CreateWindow
                     42: */
                     43: #define        WINDOW_CLASS_NAME "Quake 2"
                     44: 
                     45: void VID_CreateWindow( int width, int height, int stylebits )
                     46: {
                     47:        WNDCLASS                wc;
                     48:        RECT                    r;
                     49:        cvar_t                  *vid_xpos, *vid_ypos, *vid_fullscreen;
                     50:        int                             x, y, w, h;
                     51:        int                             exstyle;
                     52: 
                     53:        vid_xpos = ri.Cvar_Get ("vid_xpos", "0", 0);
                     54:        vid_ypos = ri.Cvar_Get ("vid_ypos", "0", 0);
                     55:        vid_fullscreen = ri.Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE );
                     56: 
                     57:        if ( vid_fullscreen->value )
                     58:                exstyle = WS_EX_TOPMOST;
                     59:        else
                     60:                exstyle = 0;
                     61: 
                     62:        /* Register the frame class */
                     63:     wc.style         = 0;
                     64:     wc.lpfnWndProc   = (WNDPROC)sww_state.wndproc;
                     65:     wc.cbClsExtra    = 0;
                     66:     wc.cbWndExtra    = 0;
                     67:     wc.hInstance     = sww_state.hInstance;
                     68:     wc.hIcon         = 0;
                     69:     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
                     70:        wc.hbrBackground = (void *)COLOR_GRAYTEXT;
                     71:     wc.lpszMenuName  = 0;
                     72:     wc.lpszClassName = WINDOW_CLASS_NAME;
                     73: 
                     74:     if (!RegisterClass (&wc) )
                     75:                ri.Sys_Error (ERR_FATAL, "Couldn't register window class");
                     76: 
                     77:        r.left = 0;
                     78:        r.top = 0;
                     79:        r.right  = width;
                     80:        r.bottom = height;
                     81: 
                     82:        AdjustWindowRect (&r, stylebits, FALSE);
                     83: 
                     84:        w = r.right - r.left;
                     85:        h = r.bottom - r.top;
                     86:        x = vid_xpos->value;
                     87:        y = vid_ypos->value;
                     88: 
                     89:        sww_state.hWnd = CreateWindowEx (
                     90:                exstyle,
                     91:                 WINDOW_CLASS_NAME,
                     92:                 "Quake 2",
                     93:                 stylebits,
                     94:                 x, y, w, h,
                     95:                 NULL,
                     96:                 NULL,
                     97:                 sww_state.hInstance,
                     98:                 NULL);
                     99: 
                    100:        if (!sww_state.hWnd)
                    101:                ri.Sys_Error (ERR_FATAL, "Couldn't create window");
                    102:        
                    103:        ShowWindow( sww_state.hWnd, SW_SHOWNORMAL );
                    104:        UpdateWindow( sww_state.hWnd );
                    105:        SetForegroundWindow( sww_state.hWnd );
                    106:        SetFocus( sww_state.hWnd );
                    107: 
                    108:        // let the sound and input subsystems know about the new window
                    109:        ri.Vid_NewWindow (width, height);
                    110: }
                    111: 
                    112: /*
                    113: ** SWimp_Init
                    114: **
                    115: ** This routine is responsible for initializing the implementation
                    116: ** specific stuff in a software rendering subsystem.
                    117: */
                    118: int SWimp_Init( void *hInstance, void *wndProc )
                    119: {
                    120:        sww_state.hInstance = ( HINSTANCE ) hInstance;
                    121:        sww_state.wndproc = wndProc;
                    122: 
                    123:        return true;
                    124: }
                    125: 
                    126: /*
                    127: ** SWimp_InitGraphics
                    128: **
                    129: ** This initializes the software refresh's implementation specific
                    130: ** graphics subsystem.  In the case of Windows it creates DIB or
                    131: ** DDRAW surfaces.
                    132: **
                    133: ** The necessary width and height parameters are grabbed from
                    134: ** vid.width and vid.height.
                    135: */
                    136: static qboolean SWimp_InitGraphics( qboolean fullscreen )
                    137: {
                    138:        // free resources in use
                    139:        SWimp_Shutdown ();
                    140: 
                    141:        // create a new window
                    142:        VID_CreateWindow (vid.width, vid.height, WINDOW_STYLE);
                    143: 
                    144:        // initialize the appropriate subsystem
                    145:        if ( !fullscreen )
                    146:        {
                    147:                if ( !DIB_Init( &vid.buffer, &vid.rowbytes ) )
                    148:                {
                    149:                        vid.buffer = 0;
                    150:                        vid.rowbytes = 0;
                    151: 
                    152:                        return false;
                    153:                }
                    154:        }
                    155:        else
                    156:        {
                    157:                if ( !DDRAW_Init( &vid.buffer, &vid.rowbytes ) )
                    158:                {
                    159:                        vid.buffer = 0;
                    160:                        vid.rowbytes = 0;
                    161: 
                    162:                        return false;
                    163:                }
                    164:        }
                    165: 
                    166:        return true;
                    167: }
                    168: 
                    169: /*
                    170: ** SWimp_EndFrame
                    171: **
                    172: ** This does an implementation specific copy from the backbuffer to the
                    173: ** front buffer.  In the Win32 case it uses BitBlt or BltFast depending
                    174: ** on whether we're using DIB sections/GDI or DDRAW.
                    175: */
                    176: void SWimp_EndFrame (void)
                    177: {
                    178:        if ( !sw_state.fullscreen )
                    179:        {
                    180:                if ( sww_state.palettized )
                    181:                {
                    182: //                     holdpal = SelectPalette(hdcScreen, hpalDIB, FALSE);
                    183: //                     RealizePalette(hdcScreen);
                    184:                }
                    185: 
                    186:            
                    187:                BitBlt( sww_state.hDC,
                    188:                            0, 0,
                    189:                                vid.width,
                    190:                                vid.height,
                    191:                                sww_state.hdcDIBSection,
                    192:                                0, 0,
                    193:                                SRCCOPY );
                    194: 
                    195:                if ( sww_state.palettized )
                    196:                {
                    197: //                     SelectPalette(hdcScreen, holdpal, FALSE);
                    198:                }
                    199:        }
                    200:        else
                    201:        {
                    202:                RECT r;
                    203:                HRESULT rval;
                    204:                DDSURFACEDESC ddsd;
                    205: 
                    206:                r.left = 0;
                    207:                r.top = 0;
                    208:                r.right = vid.width;
                    209:                r.bottom = vid.height;
                    210: 
                    211:                sww_state.lpddsOffScreenBuffer->lpVtbl->Unlock( sww_state.lpddsOffScreenBuffer, vid.buffer );
                    212: 
                    213:                if ( sww_state.modex )
                    214:                {
                    215:                        if ( ( rval = sww_state.lpddsBackBuffer->lpVtbl->BltFast( sww_state.lpddsBackBuffer,
                    216:                                                                                                                                        0, 0,
                    217:                                                                                                                                        sww_state.lpddsOffScreenBuffer, 
                    218:                                                                                                                                        &r, 
                    219:                                                                                                                                        DDBLTFAST_WAIT ) ) == DDERR_SURFACELOST )
                    220:                        {
                    221:                                sww_state.lpddsBackBuffer->lpVtbl->Restore( sww_state.lpddsBackBuffer );
                    222:                                sww_state.lpddsBackBuffer->lpVtbl->BltFast( sww_state.lpddsBackBuffer,
                    223:                                                                                                                        0, 0,
                    224:                                                                                                                        sww_state.lpddsOffScreenBuffer, 
                    225:                                                                                                                        &r, 
                    226:                                                                                                                        DDBLTFAST_WAIT );
                    227:                        }
                    228: 
                    229:                        if ( ( rval = sww_state.lpddsFrontBuffer->lpVtbl->Flip( sww_state.lpddsFrontBuffer,
                    230:                                                                                                                         NULL, DDFLIP_WAIT ) ) == DDERR_SURFACELOST )
                    231:                        {
                    232:                                sww_state.lpddsFrontBuffer->lpVtbl->Restore( sww_state.lpddsFrontBuffer );
                    233:                                sww_state.lpddsFrontBuffer->lpVtbl->Flip( sww_state.lpddsFrontBuffer, NULL, DDFLIP_WAIT );
                    234:                        }
                    235:                }
                    236:                else
                    237:                {
                    238:                        if ( ( rval = sww_state.lpddsBackBuffer->lpVtbl->BltFast( sww_state.lpddsFrontBuffer,
                    239:                                                                                                                                        0, 0,
                    240:                                                                                                                                        sww_state.lpddsOffScreenBuffer, 
                    241:                                                                                                                                        &r, 
                    242:                                                                                                                                        DDBLTFAST_WAIT ) ) == DDERR_SURFACELOST )
                    243:                        {
                    244:                                sww_state.lpddsBackBuffer->lpVtbl->Restore( sww_state.lpddsFrontBuffer );
                    245:                                sww_state.lpddsBackBuffer->lpVtbl->BltFast( sww_state.lpddsFrontBuffer,
                    246:                                                                                                                        0, 0,
                    247:                                                                                                                        sww_state.lpddsOffScreenBuffer, 
                    248:                                                                                                                        &r, 
                    249:                                                                                                                        DDBLTFAST_WAIT );
                    250:                        }
                    251:                }
                    252: 
                    253:                memset( &ddsd, 0, sizeof( ddsd ) );
                    254:                ddsd.dwSize = sizeof( ddsd );
                    255:        
                    256:                sww_state.lpddsOffScreenBuffer->lpVtbl->Lock( sww_state.lpddsOffScreenBuffer, NULL, &ddsd, DDLOCK_WAIT, NULL );
                    257: 
                    258:                vid.buffer = ddsd.lpSurface;
                    259:                vid.rowbytes = ddsd.lPitch;
                    260:        }
                    261: }
                    262: 
                    263: /*
                    264: ** SWimp_SetMode
                    265: */
                    266: rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
                    267: {
                    268:        const char *win_fs[] = { "W", "FS" };
                    269:        rserr_t retval = rserr_ok;
                    270: 
                    271:        ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode );
                    272: 
                    273:        if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) )
                    274:        {
                    275:                ri.Con_Printf( PRINT_ALL, " invalid mode\n" );
                    276:                return rserr_invalid_mode;
                    277:        }
                    278: 
                    279:        ri.Con_Printf( PRINT_ALL, " %d %d %s\n", *pwidth, *pheight, win_fs[fullscreen] );
                    280: 
                    281:        sww_state.initializing = true;
                    282:        if ( fullscreen )
                    283:        {
                    284:                if ( !SWimp_InitGraphics( 1 ) )
                    285:                {
                    286:                        if ( SWimp_InitGraphics( 0 ) )
                    287:                        {
                    288:                                // mode is legal but not as fullscreen
                    289:                                fullscreen = 0;
                    290:                                retval = rserr_invalid_fullscreen;
                    291:                        }
                    292:                        else
                    293:                        {
                    294:                                // failed to set a valid mode in windowed mode
                    295:                                retval = rserr_unknown;
                    296:                        }
                    297:                }
                    298:        }
                    299:        else
                    300:        {
                    301:                // failure to set a valid mode in windowed mode
                    302:                if ( !SWimp_InitGraphics( fullscreen ) )
                    303:                {
                    304:                        sww_state.initializing = true;
                    305:                        return rserr_unknown;
                    306:                }
                    307:        }
                    308: 
                    309:        sw_state.fullscreen = fullscreen;
                    310: #if 0
                    311:        if ( retval != rserr_unknown )
                    312:        {
                    313:                if ( retval == rserr_invalid_fullscreen ||
                    314:                         ( retval == rserr_ok && !fullscreen ) )
                    315:                {
                    316:                        SetWindowLong( sww_state.hWnd, GWL_STYLE, WINDOW_STYLE );
                    317:                }
                    318:        }
                    319: #endif
                    320:        R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
                    321:        sww_state.initializing = true;
                    322: 
                    323:        return retval;
                    324: }
                    325: 
                    326: /*
                    327: ** SWimp_SetPalette
                    328: **
                    329: ** System specific palette setting routine.  A NULL palette means
                    330: ** to use the existing palette.  The palette is expected to be in
                    331: ** a padded 4-byte xRGB format.
                    332: */
                    333: void SWimp_SetPalette( const unsigned char *palette )
                    334: {
                    335:        // MGL - what the fuck was kendall doing here?!
                    336:        // clear screen to black and change palette
                    337:        //      for (i=0 ; i<vid.height ; i++)
                    338:        //              memset (vid.buffer + i*vid.rowbytes, 0, vid.width);
                    339: 
                    340:        if ( !palette )
                    341:                palette = ( const unsigned char * ) sw_state.currentpalette;
                    342: 
                    343:        if ( !sw_state.fullscreen )
                    344:        {
                    345:                DIB_SetPalette( ( const unsigned char * ) palette );
                    346:        }
                    347:        else
                    348:        {
                    349:                DDRAW_SetPalette( ( const unsigned char * ) palette );
                    350:        }
                    351: }
                    352: 
                    353: /*
                    354: ** SWimp_Shutdown
                    355: **
                    356: ** System specific graphics subsystem shutdown routine.  Destroys
                    357: ** DIBs or DDRAW surfaces as appropriate.
                    358: */
                    359: void SWimp_Shutdown( void )
                    360: {
                    361:        ri.Con_Printf( PRINT_ALL, "Shutting down SW imp\n" );
                    362:        DIB_Shutdown();
                    363:        DDRAW_Shutdown();
                    364: 
                    365:        if ( sww_state.hWnd )
                    366:        {
                    367:                ri.Con_Printf( PRINT_ALL, "...destroying window\n" );
                    368:                ShowWindow( sww_state.hWnd, SW_SHOWNORMAL );    // prevents leaving empty slots in the taskbar
                    369:                DestroyWindow (sww_state.hWnd);
                    370:                sww_state.hWnd = NULL;
                    371:                UnregisterClass (WINDOW_CLASS_NAME, sww_state.hInstance);
                    372:        }
                    373: }
                    374: 
                    375: /*
                    376: ** SWimp_AppActivate
                    377: */
                    378: void SWimp_AppActivate( qboolean active )
                    379: {
                    380:        if ( active )
                    381:        {
                    382:                if ( sww_state.hWnd )
                    383:                {
                    384:                        SetForegroundWindow( sww_state.hWnd );
                    385:                        ShowWindow( sww_state.hWnd, SW_RESTORE );
                    386:                }
                    387:        }
                    388:        else
                    389:        {
                    390:                if ( sww_state.hWnd )
                    391:                {
                    392:                        if ( sww_state.initializing )
                    393:                                return;
                    394:                        if ( vid_fullscreen->value )
                    395:                                ShowWindow( sww_state.hWnd, SW_MINIMIZE );
                    396:                }
                    397:        }
                    398: }
                    399: 
                    400: //===============================================================================
                    401: 
                    402: 
                    403: /*
                    404: ================
                    405: Sys_MakeCodeWriteable
                    406: ================
                    407: */
                    408: void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
                    409: {
                    410:        DWORD  flOldProtect;
                    411: 
                    412:        if (!VirtualProtect((LPVOID)startaddr, length, PAGE_READWRITE, &flOldProtect))
                    413:                ri.Sys_Error(ERR_FATAL, "Protection change failed\n");
                    414: }
                    415: 
                    416: /*
                    417: ** Sys_SetFPCW
                    418: **
                    419: ** For reference:
                    420: **
                    421: ** 1
                    422: ** 5               0
                    423: ** xxxxRRPP.xxxxxxxx
                    424: **
                    425: ** PP = 00 = 24-bit single precision
                    426: ** PP = 01 = reserved
                    427: ** PP = 10 = 53-bit double precision
                    428: ** PP = 11 = 64-bit extended precision
                    429: **
                    430: ** RR = 00 = round to nearest
                    431: ** RR = 01 = round down (towards -inf, floor)
                    432: ** RR = 10 = round up (towards +inf, ceil)
                    433: ** RR = 11 = round to zero (truncate/towards 0)
                    434: **
                    435: */
                    436: #if !id386
                    437: void Sys_SetFPCW (void)
                    438: {
                    439: }
                    440: #else
                    441: unsigned fpu_ceil_cw, fpu_chop_cw, fpu_full_cw, fpu_cw, fpu_pushed_cw;
                    442: unsigned fpu_sp24_cw, fpu_sp24_ceil_cw;
                    443: 
                    444: void Sys_SetFPCW( void )
                    445: {
                    446:        __asm xor eax, eax
                    447: 
                    448:        __asm fnstcw  word ptr fpu_cw
                    449:        __asm mov ax, word ptr fpu_cw
                    450: 
                    451:        __asm and ah, 0f0h
                    452:        __asm or  ah, 003h          ; round to nearest mode, extended precision
                    453:        __asm mov fpu_full_cw, eax
                    454: 
                    455:        __asm and ah, 0f0h
                    456:        __asm or  ah, 00fh          ; RTZ/truncate/chop mode, extended precision
                    457:        __asm mov fpu_chop_cw, eax
                    458: 
                    459:        __asm and ah, 0f0h
                    460:        __asm or  ah, 00bh          ; ceil mode, extended precision
                    461:        __asm mov fpu_ceil_cw, eax
                    462: 
                    463:        __asm and ah, 0f0h          ; round to nearest, 24-bit single precision
                    464:        __asm mov fpu_sp24_cw, eax
                    465: 
                    466:        __asm and ah, 0f0h          ; ceil mode, 24-bit single precision
                    467:        __asm or  ah, 008h          ; 
                    468:        __asm mov fpu_sp24_ceil_cw, eax
                    469: }
                    470: #endif
                    471: 

unix.superglobalmegacorp.com

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