Annotation of quake2/win32/rw_imp.c, revision 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.