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