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

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

unix.superglobalmegacorp.com

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