123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- /*
- Copyright (C) 1997-2001 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- /*
- ** RW_DIB.C
- **
- ** This handles DIB section management under Windows.
- **
- */
- #include "..\ref_soft\r_local.h"
- #include "rw_win.h"
- #ifndef _WIN32
- # error You should not be trying to compile this file on this platform
- #endif
- static qboolean s_systemcolors_saved;
- static HGDIOBJ previously_selected_GDI_obj;
- static int s_syspalindices[] =
- {
- COLOR_ACTIVEBORDER,
- COLOR_ACTIVECAPTION,
- COLOR_APPWORKSPACE,
- COLOR_BACKGROUND,
- COLOR_BTNFACE,
- COLOR_BTNSHADOW,
- COLOR_BTNTEXT,
- COLOR_CAPTIONTEXT,
- COLOR_GRAYTEXT,
- COLOR_HIGHLIGHT,
- COLOR_HIGHLIGHTTEXT,
- COLOR_INACTIVEBORDER,
- COLOR_INACTIVECAPTION,
- COLOR_MENU,
- COLOR_MENUTEXT,
- COLOR_SCROLLBAR,
- COLOR_WINDOW,
- COLOR_WINDOWFRAME,
- COLOR_WINDOWTEXT
- };
- #define NUM_SYS_COLORS ( sizeof( s_syspalindices ) / sizeof( int ) )
- static int s_oldsyscolors[NUM_SYS_COLORS];
- typedef struct dibinfo
- {
- BITMAPINFOHEADER header;
- RGBQUAD acolors[256];
- } dibinfo_t;
- typedef struct
- {
- WORD palVersion;
- WORD palNumEntries;
- PALETTEENTRY palEntries[256];
- } identitypalette_t;
- static identitypalette_t s_ipal;
- static void DIB_SaveSystemColors( void );
- static void DIB_RestoreSystemColors( void );
- /*
- ** DIB_Init
- **
- ** Builds our DIB section
- */
- qboolean DIB_Init( unsigned char **ppbuffer, int *ppitch )
- {
- dibinfo_t dibheader;
- BITMAPINFO *pbmiDIB = ( BITMAPINFO * ) &dibheader;
- int i;
- memset( &dibheader, 0, sizeof( dibheader ) );
- /*
- ** grab a DC
- */
- if ( !sww_state.hDC )
- {
- if ( ( sww_state.hDC = GetDC( sww_state.hWnd ) ) == NULL )
- return false;
- }
- /*
- ** figure out if we're running in an 8-bit display mode
- */
- if ( GetDeviceCaps( sww_state.hDC, RASTERCAPS ) & RC_PALETTE )
- {
- sww_state.palettized = true;
- // save system colors
- if ( !s_systemcolors_saved )
- {
- DIB_SaveSystemColors();
- s_systemcolors_saved = true;
- }
- }
- else
- {
- sww_state.palettized = false;
- }
- /*
- ** fill in the BITMAPINFO struct
- */
- pbmiDIB->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmiDIB->bmiHeader.biWidth = vid.width;
- pbmiDIB->bmiHeader.biHeight = vid.height;
- pbmiDIB->bmiHeader.biPlanes = 1;
- pbmiDIB->bmiHeader.biBitCount = 8;
- pbmiDIB->bmiHeader.biCompression = BI_RGB;
- pbmiDIB->bmiHeader.biSizeImage = 0;
- pbmiDIB->bmiHeader.biXPelsPerMeter = 0;
- pbmiDIB->bmiHeader.biYPelsPerMeter = 0;
- pbmiDIB->bmiHeader.biClrUsed = 256;
- pbmiDIB->bmiHeader.biClrImportant = 256;
- /*
- ** fill in the palette
- */
- for ( i = 0; i < 256; i++ )
- {
- dibheader.acolors[i].rgbRed = ( d_8to24table[i] >> 0 ) & 0xff;
- dibheader.acolors[i].rgbGreen = ( d_8to24table[i] >> 8 ) & 0xff;
- dibheader.acolors[i].rgbBlue = ( d_8to24table[i] >> 16 ) & 0xff;
- }
- /*
- ** create the DIB section
- */
- sww_state.hDIBSection = CreateDIBSection( sww_state.hDC,
- pbmiDIB,
- DIB_RGB_COLORS,
- &sww_state.pDIBBase,
- NULL,
- 0 );
- if ( sww_state.hDIBSection == NULL )
- {
- ri.Con_Printf( PRINT_ALL, "DIB_Init() - CreateDIBSection failed\n" );
- goto fail;
- }
- if ( pbmiDIB->bmiHeader.biHeight > 0 )
- {
- // bottom up
- *ppbuffer = sww_state.pDIBBase + ( vid.height - 1 ) * vid.width;
- *ppitch = -vid.width;
- }
- else
- {
- // top down
- *ppbuffer = sww_state.pDIBBase;
- *ppitch = vid.width;
- }
- /*
- ** clear the DIB memory buffer
- */
- memset( sww_state.pDIBBase, 0xff, vid.width * vid.height );
- if ( ( sww_state.hdcDIBSection = CreateCompatibleDC( sww_state.hDC ) ) == NULL )
- {
- ri.Con_Printf( PRINT_ALL, "DIB_Init() - CreateCompatibleDC failed\n" );
- goto fail;
- }
- if ( ( previously_selected_GDI_obj = SelectObject( sww_state.hdcDIBSection, sww_state.hDIBSection ) ) == NULL )
- {
- ri.Con_Printf( PRINT_ALL, "DIB_Init() - SelectObject failed\n" );
- goto fail;
- }
- return true;
- fail:
- DIB_Shutdown();
- return false;
-
- }
- /*
- ** DIB_SetPalette
- **
- ** Sets the color table in our DIB section, and also sets the system palette
- ** into an identity mode if we're running in an 8-bit palettized display mode.
- **
- ** The palette is expected to be 1024 bytes, in the format:
- **
- ** R = offset 0
- ** G = offset 1
- ** B = offset 2
- ** A = offset 3
- */
- void DIB_SetPalette( const unsigned char *_pal )
- {
- const unsigned char *pal = _pal;
- LOGPALETTE *pLogPal = ( LOGPALETTE * ) &s_ipal;
- RGBQUAD colors[256];
- int i;
- int ret;
- HDC hDC = sww_state.hDC;
- /*
- ** set the DIB color table
- */
- if ( sww_state.hdcDIBSection )
- {
- for ( i = 0; i < 256; i++, pal += 4 )
- {
- colors[i].rgbRed = pal[0];
- colors[i].rgbGreen = pal[1];
- colors[i].rgbBlue = pal[2];
- colors[i].rgbReserved = 0;
- }
- colors[0].rgbRed = 0;
- colors[0].rgbGreen = 0;
- colors[0].rgbBlue = 0;
- colors[255].rgbRed = 0xff;
- colors[255].rgbGreen = 0xff;
- colors[255].rgbBlue = 0xff;
- if ( SetDIBColorTable( sww_state.hdcDIBSection, 0, 256, colors ) == 0 )
- {
- ri.Con_Printf( PRINT_ALL, "DIB_SetPalette() - SetDIBColorTable failed\n" );
- }
- }
- /*
- ** for 8-bit color desktop modes we set up the palette for maximum
- ** speed by going into an identity palette mode.
- */
- if ( sww_state.palettized )
- {
- int i;
- HPALETTE hpalOld;
- if ( SetSystemPaletteUse( hDC, SYSPAL_NOSTATIC ) == SYSPAL_ERROR )
- {
- ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - SetSystemPaletteUse() failed\n" );
- }
- /*
- ** destroy our old palette
- */
- if ( sww_state.hPal )
- {
- DeleteObject( sww_state.hPal );
- sww_state.hPal = 0;
- }
- /*
- ** take up all physical palette entries to flush out anything that's currently
- ** in the palette
- */
- pLogPal->palVersion = 0x300;
- pLogPal->palNumEntries = 256;
- for ( i = 0, pal = _pal; i < 256; i++, pal += 4 )
- {
- pLogPal->palPalEntry[i].peRed = pal[0];
- pLogPal->palPalEntry[i].peGreen = pal[1];
- pLogPal->palPalEntry[i].peBlue = pal[2];
- pLogPal->palPalEntry[i].peFlags = PC_RESERVED | PC_NOCOLLAPSE;
- }
- pLogPal->palPalEntry[0].peRed = 0;
- pLogPal->palPalEntry[0].peGreen = 0;
- pLogPal->palPalEntry[0].peBlue = 0;
- pLogPal->palPalEntry[0].peFlags = 0;
- pLogPal->palPalEntry[255].peRed = 0xff;
- pLogPal->palPalEntry[255].peGreen = 0xff;
- pLogPal->palPalEntry[255].peBlue = 0xff;
- pLogPal->palPalEntry[255].peFlags = 0;
- if ( ( sww_state.hPal = CreatePalette( pLogPal ) ) == NULL )
- {
- ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - CreatePalette failed(%x)\n", GetLastError() );
- }
- if ( ( hpalOld = SelectPalette( hDC, sww_state.hPal, FALSE ) ) == NULL )
- {
- ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - SelectPalette failed(%x)\n",GetLastError() );
- }
- if ( sww_state.hpalOld == NULL )
- sww_state.hpalOld = hpalOld;
- if ( ( ret = RealizePalette( hDC ) ) != pLogPal->palNumEntries )
- {
- ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - RealizePalette set %d entries\n", ret );
- }
- }
- }
- /*
- ** DIB_Shutdown
- */
- void DIB_Shutdown( void )
- {
- if ( sww_state.palettized && s_systemcolors_saved )
- DIB_RestoreSystemColors();
- if ( sww_state.hPal )
- {
- DeleteObject( sww_state.hPal );
- sww_state.hPal = 0;
- }
- if ( sww_state.hpalOld )
- {
- SelectPalette( sww_state.hDC, sww_state.hpalOld, FALSE );
- RealizePalette( sww_state.hDC );
- sww_state.hpalOld = NULL;
- }
- if ( sww_state.hdcDIBSection )
- {
- SelectObject( sww_state.hdcDIBSection, previously_selected_GDI_obj );
- DeleteDC( sww_state.hdcDIBSection );
- sww_state.hdcDIBSection = NULL;
- }
- if ( sww_state.hDIBSection )
- {
- DeleteObject( sww_state.hDIBSection );
- sww_state.hDIBSection = NULL;
- sww_state.pDIBBase = NULL;
- }
- if ( sww_state.hDC )
- {
- ReleaseDC( sww_state.hWnd, sww_state.hDC );
- sww_state.hDC = 0;
- }
- }
- /*
- ** DIB_Save/RestoreSystemColors
- */
- static void DIB_RestoreSystemColors( void )
- {
- SetSystemPaletteUse( sww_state.hDC, SYSPAL_STATIC );
- SetSysColors( NUM_SYS_COLORS, s_syspalindices, s_oldsyscolors );
- }
- static void DIB_SaveSystemColors( void )
- {
- int i;
- for ( i = 0; i < NUM_SYS_COLORS; i++ )
- s_oldsyscolors[i] = GetSysColor( s_syspalindices[i] );
- }
|