/* THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. */ #define WIN95 #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include "ddraw.h" #include "types.h" #include "mem.h" #include "gr.h" #include "cfile.h" #include "error.h" #include "mono.h" #include "fix.h" #include "key.h" #include "winapp.h" #include "dd.h" typedef struct LOGPAL256 { WORD ver; WORD num; PALETTEENTRY ScratchPal[256]; } LOGPAL256; // Special -------------------------------------------------------------------- extern int gr_installed; // Globals -------------------------------------------------------------------- ubyte gr_palette[256*3]; // Main Palette in RGB ubyte gr_current_pal[256*3]; // Current Valid Palette in RGB ubyte gr_fade_table[256*34]; // Fade Palette Table in RGB ubyte gr_palette_gamma = 0; int gr_palette_gamma_param = 0; ubyte gr_palette_faded_out = 1; int grd_fades_disabled=0; // Used to skip fading for development static LPDIRECTDRAWPALETTE _lpDDPalActive = 0; static LPDIRECTDRAW lpDD = NULL; static BOOL PalGDI = FALSE; static HPALETTE hPalGDI = 0; static LOGPAL256 PalGDIData; void ClearSystemPalette(); // Functions ------------------------------------------------------------------ void grwin_set_winpalette(LPDIRECTDRAW lpdd, LPDIRECTDRAWPALETTE lpDDPal) { _lpDDPalActive = lpDDPal; lpDD = lpdd; } LPDIRECTDRAWPALETTE grwin_get_winpalette(void) { return _lpDDPalActive; } void grwin_cleanup_palette() { if (hPalGDI) DeleteObject(hPalGDI); } void grwin_set_palette_exclusive(int yes) { if (yes) { PalGDI = FALSE; if (hPalGDI) DeleteObject(hPalGDI); hPalGDI = 0; } else { HDC hdc; ClearSystemPalette(); PalGDI = TRUE; PalGDIData.ver = 0x300; PalGDIData.num = 256; hPalGDI = CreatePalette((PLOGPALETTE)&PalGDIData); hdc = GetDC(GetLibraryWindow()); SelectPalette(hdc, hPalGDI, FALSE); ReleaseDC(GetLibraryWindow(), hdc); } } void grwin_gdi_realizepal(HDC hdc) { if (PalGDI) { SelectPalette(hdc, hPalGDI, FALSE); RealizePalette(hdc); } } // ---------------------------------------------------------------------------- void gr_palette_set_gamma( int gamma ) { if ( gamma < 0 ) gamma = 0; if ( gamma > 8 ) gamma = 8; if (gr_palette_gamma_param != gamma ) { gr_palette_gamma_param = gamma; gr_palette_gamma = gamma; if (!gr_palette_faded_out) { gr_palette_load( gr_palette ); } } } int gr_palette_get_gamma() { return gr_palette_gamma_param; } void gr_use_palette_table( char * filename ) { CFILE *fp; int i,fsize; fp = cfopen( filename, "rb" ); if ( fp==NULL) Error("Can't open palette file <%s>",filename); fsize = cfilelength( fp ); Assert( fsize == 9472 ); cfread( gr_palette, 256*3, 1, fp ); cfread( gr_fade_table, 256*34, 1, fp ); cfclose(fp); // This is the TRANSPARENCY COLOR for (i=0; i> 15; Computed_colors[add_index].r = r; Computed_colors[add_index].g = g; Computed_colors[add_index].b = b; Computed_colors[add_index].color_num = color_num; } void init_computed_colors(void) { int i; for (i=0; i 4) { color_record trec; trec = Computed_colors[i-1]; Computed_colors[i-1] = Computed_colors[i]; Computed_colors[i] = trec; return Computed_colors[i-1].color_num; } return Computed_colors[i].color_num; } // r &= 63; // g &= 63; // b &= 63; best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]); best_index = 0; if (best_value==0) { add_computed_color(r, g, b, best_index); return best_index; } j=0; // only go to 255, 'cause we dont want to check the transparent color. for (i=1; i<254; i++ ) { j += 3; value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]); if ( value < best_value ) { if (value==0) { add_computed_color(r, g, b, i); return i; } best_value = value; best_index = i; } } add_computed_color(r, g, b, best_index); return best_index; } int gr_find_closest_color_15bpp( int rgb ) { return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 ); } int gr_find_closest_color_current( int r, int g, int b ) { int i, j; int best_value, best_index, value; // r &= 63; // g &= 63; // b &= 63; best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]); best_index = 0; if (best_value==0) return best_index; j=0; // only go to 255, 'cause we dont want to check the transparent color. for (i=1; i<254; i++ ) { j += 3; value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]); if ( value < best_value ) { if (value==0) return i; best_value = value; best_index = i; } } return best_index; } static int last_r=0, last_g=0, last_b=0; void gr_palette_step_up( int r, int g, int b ) { HRESULT ddresult; int i; ubyte *p; int temp; Assert(_lpDDPalActive!=0); if (gr_palette_faded_out) return; if ( (r==last_r) && (g==last_g) && (b==last_b) ) return; last_r = r; last_g = g; last_b = b; p=gr_palette; for (i=0; i<256; i++ ) { temp = (int)(*p++) + r + gr_palette_gamma; if (temp<0) temp=0; else if (temp>63) temp=63; PalGDIData.ScratchPal[i].peRed = temp << 2; temp = (int)(*p++) + g + gr_palette_gamma; if (temp<0) temp=0; else if (temp>63) temp=63; PalGDIData.ScratchPal[i].peGreen = temp << 2; temp = (int)(*p++) + b + gr_palette_gamma; if (temp<0) temp=0; else if (temp>63) temp=63; PalGDIData.ScratchPal[i].peBlue = temp << 2; PalGDIData.ScratchPal[i].peFlags = PC_NOCOLLAPSE; } if (!PalGDI) { ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal); Assert(ddresult == DD_OK); } else { HDC hdc; hdc = GetDC(GetLibraryWindow()); SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal); RealizePalette(hdc); ReleaseDC(GetLibraryWindow(), hdc); } } void gr_palette_clear() { int i; HRESULT ddresult; Assert(_lpDDPalActive!=0); // Zero out Palette for (i = 0; i < 256; i++) { PalGDIData.ScratchPal[i].peRed = PalGDIData.ScratchPal[i].peBlue = PalGDIData.ScratchPal[i].peGreen = 0; PalGDIData.ScratchPal[i].peFlags = 0; } if (!hPalGDI) { ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal); Assert(ddresult == DD_OK); } else { HDC hdc; hdc = GetDC(GetLibraryWindow()); SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal); RealizePalette(hdc); ReleaseDC(GetLibraryWindow(), hdc); } gr_palette_faded_out = 1; if (GRMODEINFO(emul)) DDClearDisplay(); } void gr_palette_load( ubyte * pal ) { int i; ubyte c; HRESULT ddresult; Assert(_lpDDPalActive!=0); for (i=0; i<256; i++ ) { c = pal[i*3] + gr_palette_gamma; if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peRed = c << 2; gr_current_pal[i*3] = pal[i*3]; c = pal[i*3+1] + gr_palette_gamma; if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peGreen = c << 2; gr_current_pal[i*3+1] = pal[i*3+1]; c = pal[i*3+2] + gr_palette_gamma; if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peBlue = c << 2; gr_current_pal[i*3+2] = pal[i*3+2]; PalGDIData.ScratchPal[i].peFlags = 0; } if (!hPalGDI) { ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal); Assert(ddresult == DD_OK); } else { HDC hdc; hdc = GetDC(GetLibraryWindow()); SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal); RealizePalette(hdc); ReleaseDC(GetLibraryWindow(), hdc); } gr_palette_faded_out = 0; init_computed_colors(); } extern void gr_sync_display(void); int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys ) { ubyte c; int i,j; HRESULT ddresult; fix fade_palette[768]; fix fade_palette_delta[768]; allow_keys = allow_keys; Assert(_lpDDPalActive!=0); if (gr_palette_faded_out) return 0; #ifndef NDEBUG if (grd_fades_disabled) { gr_palette_clear(); return 0; } #endif for (i=0; i<768; i++ ) { fade_palette[i] = i2f(pal[i]+gr_palette_gamma); fade_palette_delta[i] = fade_palette[i] / nsteps; } for (j=0; j 63 ) c = 63; PalGDIData.ScratchPal[i].peRed = c << 2; c = f2i(fade_palette[i*3+1]); if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peGreen = c << 2; c = f2i(fade_palette[i*3+2]); if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peBlue = c << 2; PalGDIData.ScratchPal[i].peFlags = 0; } if (!hPalGDI) { IDirectDraw_WaitForVerticalBlank(lpDD, DDWAITVB_BLOCKBEGIN, NULL); ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal); Assert(ddresult == DD_OK); } else { HDC hdc; hdc = GetDC(GetLibraryWindow()); SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal); RealizePalette(hdc); ReleaseDC(GetLibraryWindow(), hdc); } } gr_palette_faded_out = 1; if (GRMODEINFO(emul)) DDClearDisplay(); return 0; } int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys) { HRESULT ddresult; int i,j; ubyte c; fix fade_palette[768]; fix fade_palette_delta[768]; allow_keys = allow_keys; Assert(_lpDDPalActive!=0); if (!gr_palette_faded_out) return 0; #ifndef NDEBUG if (grd_fades_disabled) { gr_palette_load(pal); return 0; } #endif for (i=0; i<768; i++ ) { gr_current_pal[i] = pal[i]; fade_palette[i] = 0; fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps; } for (j=0; j i2f(pal[i*3]+gr_palette_gamma) ) fade_palette[i*3] = i2f(pal[i*3]+gr_palette_gamma); if (fade_palette[i*3+1] > i2f(pal[i*3+1]+gr_palette_gamma) ) fade_palette[i*3+1] = i2f(pal[i*3+1]+gr_palette_gamma); if (fade_palette[i*3+2] > i2f(pal[i*3+2]+gr_palette_gamma) ) fade_palette[i*3+2] = i2f(pal[i*3+2]+gr_palette_gamma); c = f2i(fade_palette[i*3]); if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peRed = c << 2; c = f2i(fade_palette[i*3+1]); if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peGreen = c << 2; c = f2i(fade_palette[i*3+2]); if ( c > 63 ) c = 63; PalGDIData.ScratchPal[i].peBlue = c << 2; PalGDIData.ScratchPal[i].peFlags = 0; } if (!hPalGDI) { IDirectDraw_WaitForVerticalBlank(lpDD, DDWAITVB_BLOCKBEGIN, NULL); ddresult = IDirectDrawPalette_SetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal); Assert (ddresult == DD_OK); } else { HDC hdc; hdc = GetDC(GetLibraryWindow()); SetPaletteEntries(hPalGDI, 0, PalGDIData.num, PalGDIData.ScratchPal); RealizePalette(hdc); ReleaseDC(GetLibraryWindow(), hdc); } } gr_palette_faded_out = 0; return 0; } void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b ) { int i; ubyte r1, g1, b1; for (i=0; i<256; i++ ) { r1 = gr_palette[i*3+0] + r; if ( r1 > 63 ) r1 = 63; g1 = gr_palette[i*3+1] + g; if ( g1 > 63 ) g1 = 63; b1 = gr_palette[i*3+2] + b; if ( b1 > 63 ) b1 = 63; table[i] = gr_find_closest_color( r1, g1, b1 ); } } void gr_palette_read(ubyte * palette) { int i; HRESULT ddresult; Assert(_lpDDPalActive!=0); if (!hPalGDI) { ddresult = IDirectDrawPalette_GetEntries(_lpDDPalActive, 0, 0, 256, PalGDIData.ScratchPal); Assert(ddresult == DD_OK); } else { SetPaletteEntries(hPalGDI, 0, 256, PalGDIData.ScratchPal); } for (i=0; i<256; i++ ) { *palette++ = PalGDIData.ScratchPal[i].peRed >> 2; *palette++ = PalGDIData.ScratchPal[i].peGreen >> 2; *palette++ = PalGDIData.ScratchPal[i].peBlue >> 2; } } void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size) { memcpy(gr_palette, pal, size); Num_computed_colors = 0; } // GDI Palette Functions taken from ancient WinG version void ClearSystemPalette() { LOGPAL256 palette = { 0x300, 256, }; HPALETTE screenpal = 0; HDC screenDC; int counter; // Reset system palette to black to quicken WinG. for (counter = 0; counter < 256; counter++) { palette.ScratchPal[counter].peRed = 0; palette.ScratchPal[counter].peGreen = 0; palette.ScratchPal[counter].peBlue = 0; palette.ScratchPal[counter].peFlags = PC_NOCOLLAPSE; } // Create, select, realize, and deselect/delete palette. screenDC = GetDC(NULL); screenpal = CreatePalette((LOGPALETTE*)&palette); screenpal = SelectPalette(screenDC, screenpal, FALSE); RealizePalette(screenDC); screenpal = SelectPalette(screenDC, screenpal, FALSE); DeleteObject(screenpal); ReleaseDC(NULL, screenDC); }