|
|
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_DIB.C 22: ** 23: ** This handles DIB section management under Windows. 24: ** 25: */ 26: #include "..\ref_soft\r_local.h" 27: #include "rw_win.h" 28: 29: #ifndef _WIN32 30: # error You should not be trying to compile this file on this platform 31: #endif 32: 33: static qboolean s_systemcolors_saved; 34: 35: static HGDIOBJ previously_selected_GDI_obj; 36: 37: static int s_syspalindices[] = 38: { 39: COLOR_ACTIVEBORDER, 40: COLOR_ACTIVECAPTION, 41: COLOR_APPWORKSPACE, 42: COLOR_BACKGROUND, 43: COLOR_BTNFACE, 44: COLOR_BTNSHADOW, 45: COLOR_BTNTEXT, 46: COLOR_CAPTIONTEXT, 47: COLOR_GRAYTEXT, 48: COLOR_HIGHLIGHT, 49: COLOR_HIGHLIGHTTEXT, 50: COLOR_INACTIVEBORDER, 51: 52: COLOR_INACTIVECAPTION, 53: COLOR_MENU, 54: COLOR_MENUTEXT, 55: COLOR_SCROLLBAR, 56: COLOR_WINDOW, 57: COLOR_WINDOWFRAME, 58: COLOR_WINDOWTEXT 59: }; 60: 61: #define NUM_SYS_COLORS ( sizeof( s_syspalindices ) / sizeof( int ) ) 62: 63: static int s_oldsyscolors[NUM_SYS_COLORS]; 64: 65: typedef struct dibinfo 66: { 67: BITMAPINFOHEADER header; 68: RGBQUAD acolors[256]; 69: } dibinfo_t; 70: 71: typedef struct 72: { 73: WORD palVersion; 74: WORD palNumEntries; 75: PALETTEENTRY palEntries[256]; 76: } identitypalette_t; 77: 78: static identitypalette_t s_ipal; 79: 80: static void DIB_SaveSystemColors( void ); 81: static void DIB_RestoreSystemColors( void ); 82: 83: /* 84: ** DIB_Init 85: ** 86: ** Builds our DIB section 87: */ 88: qboolean DIB_Init( unsigned char **ppbuffer, int *ppitch ) 89: { 90: dibinfo_t dibheader; 91: BITMAPINFO *pbmiDIB = ( BITMAPINFO * ) &dibheader; 92: int i; 93: 94: memset( &dibheader, 0, sizeof( dibheader ) ); 95: 96: /* 97: ** grab a DC 98: */ 99: if ( !sww_state.hDC ) 100: { 101: if ( ( sww_state.hDC = GetDC( sww_state.hWnd ) ) == NULL ) 102: return false; 103: } 104: 105: /* 106: ** figure out if we're running in an 8-bit display mode 107: */ 108: if ( GetDeviceCaps( sww_state.hDC, RASTERCAPS ) & RC_PALETTE ) 109: { 110: sww_state.palettized = true; 111: 112: // save system colors 113: if ( !s_systemcolors_saved ) 114: { 115: DIB_SaveSystemColors(); 116: s_systemcolors_saved = true; 117: } 118: } 119: else 120: { 121: sww_state.palettized = false; 122: } 123: 124: /* 125: ** fill in the BITMAPINFO struct 126: */ 127: pbmiDIB->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 128: pbmiDIB->bmiHeader.biWidth = vid.width; 129: pbmiDIB->bmiHeader.biHeight = vid.height; 130: pbmiDIB->bmiHeader.biPlanes = 1; 131: pbmiDIB->bmiHeader.biBitCount = 8; 132: pbmiDIB->bmiHeader.biCompression = BI_RGB; 133: pbmiDIB->bmiHeader.biSizeImage = 0; 134: pbmiDIB->bmiHeader.biXPelsPerMeter = 0; 135: pbmiDIB->bmiHeader.biYPelsPerMeter = 0; 136: pbmiDIB->bmiHeader.biClrUsed = 256; 137: pbmiDIB->bmiHeader.biClrImportant = 256; 138: 139: /* 140: ** fill in the palette 141: */ 142: for ( i = 0; i < 256; i++ ) 143: { 144: dibheader.acolors[i].rgbRed = ( d_8to24table[i] >> 0 ) & 0xff; 145: dibheader.acolors[i].rgbGreen = ( d_8to24table[i] >> 8 ) & 0xff; 146: dibheader.acolors[i].rgbBlue = ( d_8to24table[i] >> 16 ) & 0xff; 147: } 148: 149: /* 150: ** create the DIB section 151: */ 152: sww_state.hDIBSection = CreateDIBSection( sww_state.hDC, 153: pbmiDIB, 154: DIB_RGB_COLORS, 155: &sww_state.pDIBBase, 156: NULL, 157: 0 ); 158: 159: if ( sww_state.hDIBSection == NULL ) 160: { 161: ri.Con_Printf( PRINT_ALL, "DIB_Init() - CreateDIBSection failed\n" ); 162: goto fail; 163: } 164: 165: if ( pbmiDIB->bmiHeader.biHeight > 0 ) 166: { 167: // bottom up 168: *ppbuffer = sww_state.pDIBBase + ( vid.height - 1 ) * vid.width; 169: *ppitch = -vid.width; 170: } 171: else 172: { 173: // top down 174: *ppbuffer = sww_state.pDIBBase; 175: *ppitch = vid.width; 176: } 177: 178: /* 179: ** clear the DIB memory buffer 180: */ 181: memset( sww_state.pDIBBase, 0xff, vid.width * vid.height ); 182: 183: if ( ( sww_state.hdcDIBSection = CreateCompatibleDC( sww_state.hDC ) ) == NULL ) 184: { 185: ri.Con_Printf( PRINT_ALL, "DIB_Init() - CreateCompatibleDC failed\n" ); 186: goto fail; 187: } 188: if ( ( previously_selected_GDI_obj = SelectObject( sww_state.hdcDIBSection, sww_state.hDIBSection ) ) == NULL ) 189: { 190: ri.Con_Printf( PRINT_ALL, "DIB_Init() - SelectObject failed\n" ); 191: goto fail; 192: } 193: 194: return true; 195: 196: fail: 197: DIB_Shutdown(); 198: return false; 199: 200: } 201: 202: /* 203: ** DIB_SetPalette 204: ** 205: ** Sets the color table in our DIB section, and also sets the system palette 206: ** into an identity mode if we're running in an 8-bit palettized display mode. 207: ** 208: ** The palette is expected to be 1024 bytes, in the format: 209: ** 210: ** R = offset 0 211: ** G = offset 1 212: ** B = offset 2 213: ** A = offset 3 214: */ 215: void DIB_SetPalette( const unsigned char *_pal ) 216: { 217: const unsigned char *pal = _pal; 218: LOGPALETTE *pLogPal = ( LOGPALETTE * ) &s_ipal; 219: RGBQUAD colors[256]; 220: int i; 221: int ret; 222: HDC hDC = sww_state.hDC; 223: 224: /* 225: ** set the DIB color table 226: */ 227: if ( sww_state.hdcDIBSection ) 228: { 229: for ( i = 0; i < 256; i++, pal += 4 ) 230: { 231: colors[i].rgbRed = pal[0]; 232: colors[i].rgbGreen = pal[1]; 233: colors[i].rgbBlue = pal[2]; 234: colors[i].rgbReserved = 0; 235: } 236: 237: colors[0].rgbRed = 0; 238: colors[0].rgbGreen = 0; 239: colors[0].rgbBlue = 0; 240: 241: colors[255].rgbRed = 0xff; 242: colors[255].rgbGreen = 0xff; 243: colors[255].rgbBlue = 0xff; 244: 245: if ( SetDIBColorTable( sww_state.hdcDIBSection, 0, 256, colors ) == 0 ) 246: { 247: ri.Con_Printf( PRINT_ALL, "DIB_SetPalette() - SetDIBColorTable failed\n" ); 248: } 249: } 250: 251: /* 252: ** for 8-bit color desktop modes we set up the palette for maximum 253: ** speed by going into an identity palette mode. 254: */ 255: if ( sww_state.palettized ) 256: { 257: int i; 258: HPALETTE hpalOld; 259: 260: if ( SetSystemPaletteUse( hDC, SYSPAL_NOSTATIC ) == SYSPAL_ERROR ) 261: { 262: ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - SetSystemPaletteUse() failed\n" ); 263: } 264: 265: /* 266: ** destroy our old palette 267: */ 268: if ( sww_state.hPal ) 269: { 270: DeleteObject( sww_state.hPal ); 271: sww_state.hPal = 0; 272: } 273: 274: /* 275: ** take up all physical palette entries to flush out anything that's currently 276: ** in the palette 277: */ 278: pLogPal->palVersion = 0x300; 279: pLogPal->palNumEntries = 256; 280: 281: for ( i = 0, pal = _pal; i < 256; i++, pal += 4 ) 282: { 283: pLogPal->palPalEntry[i].peRed = pal[0]; 284: pLogPal->palPalEntry[i].peGreen = pal[1]; 285: pLogPal->palPalEntry[i].peBlue = pal[2]; 286: pLogPal->palPalEntry[i].peFlags = PC_RESERVED | PC_NOCOLLAPSE; 287: } 288: pLogPal->palPalEntry[0].peRed = 0; 289: pLogPal->palPalEntry[0].peGreen = 0; 290: pLogPal->palPalEntry[0].peBlue = 0; 291: pLogPal->palPalEntry[0].peFlags = 0; 292: pLogPal->palPalEntry[255].peRed = 0xff; 293: pLogPal->palPalEntry[255].peGreen = 0xff; 294: pLogPal->palPalEntry[255].peBlue = 0xff; 295: pLogPal->palPalEntry[255].peFlags = 0; 296: 297: if ( ( sww_state.hPal = CreatePalette( pLogPal ) ) == NULL ) 298: { 299: ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - CreatePalette failed(%x)\n", GetLastError() ); 300: } 301: 302: if ( ( hpalOld = SelectPalette( hDC, sww_state.hPal, FALSE ) ) == NULL ) 303: { 304: ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - SelectPalette failed(%x)\n",GetLastError() ); 305: } 306: 307: if ( sww_state.hpalOld == NULL ) 308: sww_state.hpalOld = hpalOld; 309: 310: if ( ( ret = RealizePalette( hDC ) ) != pLogPal->palNumEntries ) 311: { 312: ri.Sys_Error( ERR_FATAL, "DIB_SetPalette() - RealizePalette set %d entries\n", ret ); 313: } 314: } 315: } 316: 317: /* 318: ** DIB_Shutdown 319: */ 320: void DIB_Shutdown( void ) 321: { 322: if ( sww_state.palettized && s_systemcolors_saved ) 323: DIB_RestoreSystemColors(); 324: 325: if ( sww_state.hPal ) 326: { 327: DeleteObject( sww_state.hPal ); 328: sww_state.hPal = 0; 329: } 330: 331: if ( sww_state.hpalOld ) 332: { 333: SelectPalette( sww_state.hDC, sww_state.hpalOld, FALSE ); 334: RealizePalette( sww_state.hDC ); 335: sww_state.hpalOld = NULL; 336: } 337: 338: if ( sww_state.hdcDIBSection ) 339: { 340: SelectObject( sww_state.hdcDIBSection, previously_selected_GDI_obj ); 341: DeleteDC( sww_state.hdcDIBSection ); 342: sww_state.hdcDIBSection = NULL; 343: } 344: 345: if ( sww_state.hDIBSection ) 346: { 347: DeleteObject( sww_state.hDIBSection ); 348: sww_state.hDIBSection = NULL; 349: sww_state.pDIBBase = NULL; 350: } 351: 352: if ( sww_state.hDC ) 353: { 354: ReleaseDC( sww_state.hWnd, sww_state.hDC ); 355: sww_state.hDC = 0; 356: } 357: } 358: 359: 360: /* 361: ** DIB_Save/RestoreSystemColors 362: */ 363: static void DIB_RestoreSystemColors( void ) 364: { 365: SetSystemPaletteUse( sww_state.hDC, SYSPAL_STATIC ); 366: SetSysColors( NUM_SYS_COLORS, s_syspalindices, s_oldsyscolors ); 367: } 368: 369: static void DIB_SaveSystemColors( void ) 370: { 371: int i; 372: 373: for ( i = 0; i < NUM_SYS_COLORS; i++ ) 374: s_oldsyscolors[i] = GetSysColor( s_syspalindices[i] ); 375: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.