Added video transparency for 8/15/16/32 (no 24) bpp for X11 and related:

- Better clipping
- BUG-fix: unit_draw sometimes tries to draw rectangle with width<0
- 8bpp uses a single common 256 color palette (to be used by all palettes)
- VideoDraw..Clip functions no longer separated for each bpp
This commit is contained in:
stephanr 2001-06-06 22:03:00 +00:00
parent 55c4d58637
commit 867543fc79
11 changed files with 4776 additions and 1147 deletions

View file

@ -37,6 +37,24 @@
-- Declarations
----------------------------------------------------------------------------*/
/**
** video mode (color) types
**
** FIXME: The folllowing are assumptions and might not be true for all
** hardware. Note that VMemType16 and VMemType32 support 2 types.
** An idea: convert VMemType32 to the needed coding in the very last
** step, keeping it out of the main code (and this include ;)
**
** VMemType8 : 8 bit (index in a special RGB pallette)
** NOTE: single common palette support added (used in X11)
** VMemType16 :
** 15 bit [5 bit Red|5 bit Green|5 bit Blue]
** 16 bit [5 bit Red|6 bit Green|5 bit Blue]
** VMemType24 : [8 bit Red|8 bit Green|8 bit Blue]
** VMemType32 :
** 24 bit [0|8 bit Red|8 bit Green|8 bit Blue]
** 32 bit [8 bit alpha|8 bit Red|8 bit Green|8 bit Blue]
*/
typedef unsigned char VMemType8; /// 8 bpp modes pointer
typedef unsigned short VMemType16; /// 16 bpp modes pointer
typedef struct { char a,b,c;} VMemType24;/// 24 bpp modes pointer
@ -333,6 +351,23 @@ extern VMemType* Pixels;
/// Loaded system palette. 256-entries long, active system palette.
extern Palette GlobalPalette[256];
/**
** Special 8bpp functionality, only to be used in ../video
*/
extern Palette *commonpalette;
extern unsigned long commonpalette_defined[8];
extern VMemType8 *colorcube8;
extern VMemType8 *lookup25trans8;
extern VMemType8 *lookup50trans8;
extern void (*VideoAllocPalette8)( Palette *palette,
Palette *syspalette,
unsigned long syspalette_defined[8] );
//FIXME: following function should be local in video.c, but this will also
// need VideoCreateNewPalette to be there (will all video still work?).
extern global VMemType8* VideoFindNewPalette8( const VMemType8 *cube,
const Palette *palette );
/**
** Video synchronization speed. Synchronization time in prozent.
** If =0, video framerate is not synchronized. 100 is exact
@ -394,7 +429,7 @@ extern void (*VideoDraw75TransPixel)(SysColors color,int x,int y);
** @param y y coordinate on the screen
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransPixel)(SysColors color,int x,int y,int alpha);
extern void (*VideoDrawTransPixel)(SysColors color,int x,int y,unsigned char alpha);
/**
** Draw pixel clipped to current clip setting.
@ -412,7 +447,7 @@ extern void (*VideoDrawPixelClip)(SysColors color,int x,int y);
** @param x x coordinate on the screen
** @param y y coordinate on the screen
*/
extern void (*VideoDraw25TransPixelClip)(SysColors color,int x,int y);
extern void VideoDraw25TransPixelClip(SysColors color,int x,int y);
/**
** Draw 50% translucent pixel clipped to current clip setting.
@ -421,7 +456,7 @@ extern void (*VideoDraw25TransPixelClip)(SysColors color,int x,int y);
** @param x x coordinate on the screen
** @param y y coordinate on the screen
*/
extern void (*VideoDraw50TransPixelClip)(SysColors color,int x,int y);
extern void VideoDraw50TransPixelClip(SysColors color,int x,int y);
/**
** Draw 75% translucent pixel clipped to current clip setting.
@ -430,7 +465,7 @@ extern void (*VideoDraw50TransPixelClip)(SysColors color,int x,int y);
** @param x x coordinate on the screen
** @param y y coordinate on the screen
*/
extern void (*VideoDraw75TransPixelClip)(SysColors color,int x,int y);
extern void VideoDraw75TransPixelClip(SysColors color,int x,int y);
/**
** Draw translucent pixel clipped to current clip setting.
@ -440,7 +475,7 @@ extern void (*VideoDraw75TransPixelClip)(SysColors color,int x,int y);
** @param y y coordinate on the screen
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransPixelClip)(SysColors color,int x,int y,int alpha);
extern void VideoDrawTransPixelClip(SysColors color,int x,int y,unsigned char alpha);
/**
** Draw vertical line unclipped.
@ -496,7 +531,7 @@ extern void (*VideoDraw75TransVLine)(SysColors color,int x,int y
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransVLine)(SysColors color,int x,int y
,unsigned height,int alpha);
,unsigned height,unsigned char alpha);
/**
** Draw vertical line clipped to current clip setting
@ -506,7 +541,7 @@ extern void (*VideoDrawTransVLine)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param height height of line.
*/
extern void (*VideoDrawVLineClip)(SysColors color,int x,int y
extern void VideoDrawVLineClip(SysColors color,int x,int y
,unsigned height);
/**
@ -517,7 +552,7 @@ extern void (*VideoDrawVLineClip)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param height height of line.
*/
extern void (*VideoDraw25TransVLineClip)(SysColors color,int x,int y
extern void VideoDraw25TransVLineClip(SysColors color,int x,int y
,unsigned height);
/**
@ -528,7 +563,7 @@ extern void (*VideoDraw25TransVLineClip)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param height height of line.
*/
extern void (*VideoDraw50TransVLineClip)(SysColors color,int x,int y
extern void VideoDraw50TransVLineClip(SysColors color,int x,int y
,unsigned height);
/**
@ -539,7 +574,7 @@ extern void (*VideoDraw50TransVLineClip)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param height height of line.
*/
extern void (*VideoDraw75TransVLineClip)(SysColors color,int x,int y
extern void VideoDraw75TransVLineClip(SysColors color,int x,int y
,unsigned height);
/**
@ -551,8 +586,8 @@ extern void (*VideoDraw75TransVLineClip)(SysColors color,int x,int y
** @param height height of line.
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransVLineClip)(SysColors color,int x,int y
,unsigned height,int alpha);
extern void VideoDrawTransVLineClip(SysColors color,int x,int y
,unsigned height,unsigned char alpha);
/**
** Draw horizontal line unclipped.
@ -608,7 +643,7 @@ extern void (*VideoDraw75TransHLine)(SysColors color,int x,int y
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransHLine)(SysColors color,int x,int y
,unsigned width,int alpha);
,unsigned width,unsigned char alpha);
/**
** Draw horizontal line clipped to current clip setting
@ -618,7 +653,7 @@ extern void (*VideoDrawTransHLine)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param width width of line.
*/
extern void (*VideoDrawHLineClip)(SysColors color,int x,int y
extern void VideoDrawHLineClip(SysColors color,int x,int y
,unsigned width);
/**
@ -629,7 +664,7 @@ extern void (*VideoDrawHLineClip)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param width width of line.
*/
extern void (*VideoDraw25TransHLineClip)(SysColors color,int x,int y
extern void VideoDraw25TransHLineClip(SysColors color,int x,int y
,unsigned width);
/**
@ -640,7 +675,7 @@ extern void (*VideoDraw25TransHLineClip)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param width width of line.
*/
extern void (*VideoDraw50TransHLineClip)(SysColors color,int x,int y
extern void VideoDraw50TransHLineClip(SysColors color,int x,int y
,unsigned width);
/**
@ -651,7 +686,7 @@ extern void (*VideoDraw50TransHLineClip)(SysColors color,int x,int y
** @param y y coordinate on the screen
** @param width width of line.
*/
extern void (*VideoDraw75TransHLineClip)(SysColors color,int x,int y
extern void VideoDraw75TransHLineClip(SysColors color,int x,int y
,unsigned width);
/**
@ -663,8 +698,8 @@ extern void (*VideoDraw75TransHLineClip)(SysColors color,int x,int y
** @param width width of line.
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransHLineClip)(SysColors color,int x,int y
,unsigned width,int alpha);
extern void VideoDrawTransHLineClip(SysColors color,int x,int y
,unsigned width,unsigned char alpha);
/**
** Draw line unclipped.
@ -724,7 +759,7 @@ extern void (*VideoDraw75TransLine)(SysColors color,int sx,int sy
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransLine)(SysColors color,int sx,int sy,int dx,int dy
,int alpha);
,unsigned char alpha);
/**
** Draw line clipped to current clip setting
@ -735,7 +770,7 @@ extern void (*VideoDrawTransLine)(SysColors color,int sx,int sy,int dx,int dy
** @param dx Destination x coordinate on the screen
** @param dy Destination y coordinate on the screen
*/
extern void (*VideoDrawLineClip)(SysColors color,int sx,int sy,int dx,int dy);
extern void VideoDrawLineClip(SysColors color,int sx,int sy,int dx,int dy);
/**
** Draw 25% translucent line clipped to current clip setting
@ -746,7 +781,7 @@ extern void (*VideoDrawLineClip)(SysColors color,int sx,int sy,int dx,int dy);
** @param dx Destination x coordinate on the screen
** @param dy Destination y coordinate on the screen
*/
extern void (*VideoDraw25TransLineClip)(SysColors color,int sx,int sy
extern void VideoDraw25TransLineClip(SysColors color,int sx,int sy
,int dx,int dy);
/**
@ -758,7 +793,7 @@ extern void (*VideoDraw25TransLineClip)(SysColors color,int sx,int sy
** @param dx Destination x coordinate on the screen
** @param dy Destination y coordinate on the screen
*/
extern void (*VideoDraw50TransLineClip)(SysColors color,int sx,int sy,
extern void VideoDraw50TransLineClip(SysColors color,int sx,int sy,
int dx,int dy);
/**
@ -770,7 +805,7 @@ extern void (*VideoDraw50TransLineClip)(SysColors color,int sx,int sy,
** @param dx Destination x coordinate on the screen
** @param dy Destination y coordinate on the screen
*/
extern void (*VideoDraw75TransLineClip)(SysColors color,int sx,int sy
extern void VideoDraw75TransLineClip(SysColors color,int sx,int sy
,int dx,int dy);
/**
@ -783,8 +818,8 @@ extern void (*VideoDraw75TransLineClip)(SysColors color,int sx,int sy
** @param dy Destination y coordinate on the screen
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransLineClip)(SysColors color,int sx,int sy
,int dx,int dy,int alpha);
extern void VideoDrawTransLineClip(SysColors color,int sx,int sy
,int dx,int dy,unsigned char alpha);
/**
** Draw rectangle.
@ -845,7 +880,7 @@ extern void (*VideoDraw75TransRectangle)(SysColors color,int x,int y
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransRectangle)(SysColors color,int x,int y
,unsigned w,unsigned h,int alpha);
,unsigned w,unsigned h,unsigned char alpha);
/**
** Draw rectangle clipped.
@ -856,7 +891,7 @@ extern void (*VideoDrawTransRectangle)(SysColors color,int x,int y
** @param h height of rectangle.
** @param w width of rectangle.
*/
extern void (*VideoDrawRectangleClip)(SysColors color,int x,int y
extern void VideoDrawRectangleClip(SysColors color,int x,int y
,unsigned w,unsigned h);
/**
@ -868,7 +903,7 @@ extern void (*VideoDrawRectangleClip)(SysColors color,int x,int y
** @param h height of rectangle.
** @param w width of rectangle.
*/
extern void (*VideoDraw25TransRectangleClip)(SysColors color,int x,int y
extern void VideoDraw25TransRectangleClip(SysColors color,int x,int y
,unsigned w,unsigned h);
/**
@ -880,7 +915,7 @@ extern void (*VideoDraw25TransRectangleClip)(SysColors color,int x,int y
** @param h height of rectangle.
** @param w width of rectangle.
*/
extern void (*VideoDraw50TransRectangleClip)(SysColors color,int x,int y
extern void VideoDraw50TransRectangleClip(SysColors color,int x,int y
,unsigned w,unsigned h);
/**
@ -892,7 +927,7 @@ extern void (*VideoDraw50TransRectangleClip)(SysColors color,int x,int y
** @param h height of rectangle.
** @param w width of rectangle.
*/
extern void (*VideoDraw75TransRectangleClip)(SysColors color,int x,int y
extern void VideoDraw75TransRectangleClip(SysColors color,int x,int y
,unsigned w,unsigned h);
/**
@ -905,8 +940,8 @@ extern void (*VideoDraw75TransRectangleClip)(SysColors color,int x,int y
** @param w width of rectangle.
** @param alpha alpha value of pixel.
*/
extern void (*VideoDrawTransRectangleClip)(SysColors color,int x,int y
,unsigned w,unsigned h,int alpha);
extern void VideoDrawTransRectangleClip(SysColors color,int x,int y
,unsigned w,unsigned h,unsigned char alpha);
/// Does ColorCycling..
extern void (*ColorCycle)(void);
@ -1055,7 +1090,7 @@ extern void VideoDraw75TransCircle(SysColors color,int x,int y,unsigned r);
/// Draw translucent circle.
extern void VideoDrawTransCircle(SysColors color,int x,int y,unsigned r
,int alpha);
,unsigned char alpha);
/// Draw circle clipped.
extern void VideoDrawCircleClip(SysColors color,int x,int y,unsigned r);
@ -1071,27 +1106,27 @@ extern void VideoDraw75TransCircleClip(SysColors color,int x,int y,unsigned r);
/// Draw translucent circle clipped.
extern void VideoDrawTransCircleClip(SysColors color,int x,int y,unsigned r
,int alpha);
,unsigned char alpha);
/// Fill rectangle.
extern void VideoFillRectangle(SysColors color,int x,int y
extern void (*VideoFillRectangle)(SysColors color,int x,int y
,unsigned w,unsigned h);
/// Fill 25% translucent rectangle.
extern void VideoFill25TransRectangle(SysColors color,int x,int y
extern void (*VideoFill25TransRectangle)(SysColors color,int x,int y
,unsigned w,unsigned h);
/// Fill 50% translucent rectangle.
extern void VideoFill50TransRectangle(SysColors color,int x,int y
extern void (*VideoFill50TransRectangle)(SysColors color,int x,int y
,unsigned w,unsigned h);
/// Fill 75% translucent rectangle.
extern void VideoFill75TransRectangle(SysColors color,int x,int y
extern void (*VideoFill75TransRectangle)(SysColors color,int x,int y
,unsigned w,unsigned h);
/// Fill translucent rectangle.
extern void VideoFillTransRectangle(SysColors color,int x,int y
,unsigned w,unsigned h,int alpha);
extern void (*VideoFillTransRectangle)(SysColors color,int x,int y
,unsigned w,unsigned h,unsigned char alpha);
/// Fill rectangle clipped.
extern void VideoFillRectangleClip(SysColors color,int x,int y
@ -1111,7 +1146,7 @@ extern void VideoFill75TransRectangleClip(SysColors color,int x,int y
/// Fill translucent rectangle clipped.
extern void VideoFillTransRectangleClip(SysColors color,int x,int y
,unsigned w,unsigned h,int alpha);
,unsigned w,unsigned h,unsigned char alpha);
/// Fill circle.
extern void VideoFillCircle(SysColors color,int x,int y,unsigned r);
@ -1127,7 +1162,7 @@ extern void VideoFill75TransCircle(SysColors color,int x,int y,unsigned r);
/// Fill translucent circle.
extern void VideoFillTransCircle(SysColors color,int x,int y,unsigned r
,int alpha);
,unsigned char alpha);
/// Fill circle clipped.
extern void VideoFillCircleClip(SysColors color,int x,int y,unsigned r);
@ -1143,7 +1178,7 @@ extern void VideoFill75TransCircleClip(SysColors color,int x,int y,unsigned r);
/// Fill translucent circle clipped.
extern void VideoFillTransCircleClip(SysColors color,int x,int y,unsigned r
,int alpha);
,unsigned char alpha);
/**
** Set clipping for nearly all vector primitives. Functions which support

View file

@ -1017,7 +1017,7 @@ global void VideoDraw8OnlyFog32Alpha(const GraphicData* data,int x,int y)
int da;
dp=VideoMemory8+x+y*VideoWidth;
gp=dp+VideoWidth*TileSizeX;
gp=dp+VideoWidth*TileSizeY;
da=VideoWidth;
while( dp<gp ) {
@ -1105,7 +1105,7 @@ global void VideoDraw16OnlyFog32Alpha(const GraphicData* data,int x,int y)
//int o;
dp=VideoMemory16+x+y*VideoWidth;
gp=dp+VideoWidth*TileSizeX;
gp=dp+VideoWidth*TileSizeY;
da=VideoWidth;
while( dp<gp ) {
@ -1206,7 +1206,7 @@ global void VideoDraw24OnlyFog32Alpha(const GraphicData* data,int x,int y)
int r, g, b, v;
dp=VideoMemory24+x+y*VideoWidth;
gp=dp+VideoWidth*TileSizeX;
gp=dp+VideoWidth*TileSizeY;
da=VideoWidth;
while( dp<gp ) {
@ -1324,7 +1324,7 @@ global void VideoDraw32OnlyFog32Alpha(const GraphicData* data,int x,int y)
int i, r, g, b, v;
dp=VideoMemory32+x+y*VideoWidth;
gp=dp+VideoWidth*TileSizeX;
gp=dp+VideoWidth*TileSizeY;
da=VideoWidth;
while( dp<gp ) {
@ -1608,12 +1608,27 @@ global void InitMapFogOfWar(void)
int rshft,gshft,bshft;
int rloss,gloss,bloss;
switch( VideoDepth ) {
case 8:
n=1<<(sizeof(VMemType8)*8);
if( !FogOfWarAlphaTable ) {
FogOfWarAlphaTable=malloc(n*sizeof(VMemType8));
}
if ( lookup25trans8 ) // if enabled, make use of it in 8bpp ;)
{
unsigned int trans_color, j;
trans_color=Pixels8[ColorBlack];
trans_color<<=8;
//FIXME: determine which lookup table to use based on
// FogOfWarSaturation,FogOfWarContrast and FogOfWarBrightness
for( j=0; j<n; ++j )
((VMemType8*)FogOfWarAlphaTable)[j] =
lookup50trans8[ trans_color | j ];
}
else
{
for( i=0; i<n; ++i ) {
int j;
int l;
@ -1664,6 +1679,7 @@ global void InitMapFogOfWar(void)
,GlobalPalette[l].b);
((VMemType8*)FogOfWarAlphaTable)[i]=l;
}
}
VideoDrawFog=VideoDraw8Fog32Alpha;
VideoDrawOnlyFog=VideoDraw8OnlyFog32Alpha;

View file

@ -12,7 +12,6 @@
//
// (c) Copyright 1998-2001 by Lutz Sammer and Fabrice Rossi
//
// FreeCraft 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.

View file

@ -1,4 +1,3 @@
// ___________ _________ _____ __
// \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_
// | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\
// | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | |

View file

@ -174,6 +174,197 @@ local void DoScrollArea(enum _scroll_state_ TempScrollState, int FastScroll)
MustRedraw|=RedrawMinimap|RedrawCursors;
}
/**
** FOR DEBUG PURPOSE ONLY, BUT DON'T REMOVE PLEASE !!!
**
** Will try all kinds of possible linedraw routines (only one time) upon
** current display, making the job of debugging them more eassier..
*/
global void DebugTestDisplay(void)
{
static int a=0;
int x,y,i;
if ( a ) return;
a=1;
/*Should not show anything (segmentation fault when not properly clipped) */
VideoDrawPixelClip(ColorRed,-1,0);
VideoDrawPixelClip(ColorRed,0,-1);
VideoDrawPixelClip(ColorRed,VideoWidth,0);
VideoDrawPixelClip(ColorRed,0,VideoHeight);
VideoDraw25TransPixelClip(ColorRed,-1,0);
VideoDraw25TransPixelClip(ColorRed,0,-1);
VideoDraw25TransPixelClip(ColorRed,VideoWidth,0);
VideoDraw25TransPixelClip(ColorRed,0,VideoHeight);
VideoDraw50TransPixelClip(ColorRed,-1,0);
VideoDraw50TransPixelClip(ColorRed,0,-1);
VideoDraw50TransPixelClip(ColorRed,VideoWidth,0);
VideoDraw50TransPixelClip(ColorRed,0,VideoHeight);
VideoDraw75TransPixelClip(ColorRed,-1,0);
VideoDraw75TransPixelClip(ColorRed,0,-1);
VideoDraw75TransPixelClip(ColorRed,VideoWidth,0);
VideoDraw75TransPixelClip(ColorRed,0,VideoHeight);
VideoDrawTransPixelClip(ColorRed,-1,0,0);
VideoDrawTransPixelClip(ColorRed,0,-1,0);
VideoDrawTransPixelClip(ColorRed,VideoWidth,0,0);
VideoDrawTransPixelClip(ColorRed,0,VideoHeight,0);
/*Should show blue area getting transparent from left-to-right */
for (y=0;y<50;y++)
for (x=0;x<50;x++)
VideoDrawPixel(ColorBlue,x,y);
for (y=0;y<50;y++)
for (x=50;x<100;x++)
VideoDraw25TransPixel(ColorBlue,x,y);
for (y=0;y<50;y++)
for (x=100;x<150;x++)
VideoDraw50TransPixel(ColorBlue,x,y);
for (y=0;y<50;y++)
for (x=150;x<200;x++)
VideoDraw75TransPixel(ColorBlue,x,y);
for (y=50;y<100;y++)
for (x=0;x<256;x++)
VideoDrawTransPixel(ColorBlue,x,y,x);
/* Should show blue+red horizontal bars just below above drawpixel tests
getting transparent from top-to-bottom. Clipping should prevent segm.fault
*/
for (y=0;y<10;y++)
{
VideoDrawHLine(ColorBlue,0,y+100,VideoWidth-1);
VideoDrawHLineClip(ColorRed,-100,-1,VideoWidth+200);
VideoDrawHLineClip(ColorRed,-100,VideoHeight,VideoWidth+200);
VideoDrawHLineClip(ColorRed,-100,y+110,VideoWidth+200);
VideoDraw25TransHLine(ColorBlue,0,y+120,VideoWidth-1);
VideoDraw25TransHLineClip(ColorRed,-100,-1,VideoWidth+200);
VideoDraw25TransHLineClip(ColorRed,-100,VideoHeight,VideoWidth+200);
VideoDraw25TransHLineClip(ColorRed,-100,y+130,VideoWidth+200);
VideoDraw50TransHLine(ColorBlue,0,y+140,VideoWidth-1);
VideoDraw50TransHLineClip(ColorRed,-100,-1,VideoWidth+200);
VideoDraw50TransHLineClip(ColorRed,-100,VideoHeight,VideoWidth+200);
VideoDraw50TransHLineClip(ColorRed,-100,y+150,VideoWidth+200);
VideoDraw75TransHLine(ColorBlue,0,y+160,VideoWidth-1);
VideoDraw75TransHLineClip(ColorRed,-100,-1,VideoWidth+200);
VideoDraw75TransHLineClip(ColorRed,-100,VideoHeight,VideoWidth+200);
VideoDraw75TransHLineClip(ColorRed,-100,y+170,VideoWidth+200);
}
for (y=0;y<64;y++)
{
VideoDrawTransHLine(ColorBlue,0,y+180,VideoWidth-1,y*4);
VideoDrawTransHLineClip(ColorRed,-100,-1,VideoWidth+200,y*4);
VideoDrawTransHLineClip(ColorRed,-100,VideoHeight,VideoWidth+200,y*4);
VideoDrawTransHLineClip(ColorRed,-100,y+180+64+6+6,VideoWidth+200,(63-y)*4);
}
/* Should show blue+red vertical bars at the right of the screen
getting transparent from left-to-right. Clipping should prevent segm.fault
*/
i = ((VideoWidth-70-70-50)/10)*10; // starting grid pos for two colums
for (x=0;x<64;x++)
{
VideoDrawTransVLine(ColorBlue,i+x,0,VideoHeight-1,x*4);
VideoDrawTransVLineClip(ColorRed,-1,-100,VideoHeight+200,x*4);
VideoDrawTransVLineClip(ColorRed,VideoWidth,-100,VideoHeight+200,x*4);
VideoDrawTransVLineClip(ColorRed,i+76+x,-100,VideoHeight+200,(63-x)*4);
}
i -= 4*2*10;
for (x=0;x<10;x++)
{
VideoDrawVLine(ColorBlue,i+x,0,VideoHeight-1);
VideoDrawVLineClip(ColorRed,-1,-100,VideoHeight+200);
VideoDrawVLineClip(ColorRed,VideoWidth,-100,VideoHeight+200);
VideoDrawVLineClip(ColorRed,i+x+10,-100,VideoHeight+200);
VideoDraw25TransVLine(ColorBlue,i+x+20,0,VideoHeight-1);
VideoDraw25TransVLineClip(ColorRed,-1,-100,VideoHeight+200);
VideoDraw25TransVLineClip(ColorRed,VideoWidth,-100,VideoHeight+200);
VideoDraw25TransVLineClip(ColorRed,i+x+30,-100,VideoHeight+200);
VideoDraw50TransVLine(ColorBlue,i+x+40,0,VideoHeight-1);
VideoDraw50TransVLineClip(ColorRed,-1,-100,VideoHeight+200);
VideoDraw50TransVLineClip(ColorRed,VideoWidth,-100,VideoHeight+200);
VideoDraw50TransVLineClip(ColorRed,i+x+50,-100,VideoHeight+200);
VideoDraw75TransVLine(ColorBlue,i+x+60,0,VideoHeight-1);
VideoDraw75TransVLineClip(ColorRed,-1,-100,VideoHeight+200);
VideoDraw75TransVLineClip(ColorRed,VideoWidth,-100,VideoHeight+200);
VideoDraw75TransVLineClip(ColorRed,i+x+70,-100,VideoHeight+200);
}
/*Should show filled rectangles in screen's top-right corners */
VideoFillRectangleClip(ColorGray,VideoWidth-30,-20,60,40);
VideoFill25TransRectangleClip(ColorBlue,VideoWidth-29,-19,58,38);
VideoFill50TransRectangleClip(ColorRed,VideoWidth-28,-18,56,36);
VideoFill75TransRectangleClip(ColorGreen,VideoWidth-27,-17,54,34);
VideoFillTransRectangleClip(ColorBlue,VideoWidth-26,-16,52,32,64);
/*Should show red area in lower-left getting transparent from left-to-right */
i = ((VideoHeight-20)/10)*10; // starting grid pos for two colums
VideoFillRectangle(ColorRed,0,i,50,20);
VideoFill25TransRectangle(ColorRed,50,i,50,20);
VideoFill50TransRectangle(ColorRed,100,i,50,20);
VideoFill75TransRectangle(ColorRed,150,i,50,20);
i -= 20;
for (x=0;x<256;x++)
VideoFillTransRectangle(ColorRed,x,i,1,20,x);
/*Should show red/green/blue rectangles in lower-left transparent from
left-to-right */
i -= 20;
for (x=0;x<10;x++)
{
VideoDrawRectangle(ColorBlue,x,i+x,50-2*x,20-2*x);
VideoDraw25TransRectangle(ColorBlue,50+x,i+x,50-2*x,20-2*x);
VideoDraw50TransRectangle(ColorBlue,100+x,i+x,50-2*x,20-2*x);
VideoDraw75TransRectangle(ColorBlue,150+x,i+x,50-2*x,20-2*x);
}
i -= 20;
for (x=0;x<256;x++)
VideoDrawTransRectangle(ColorGreen,x,i,1,20,x);
i -= 20;
for (x=0;x<128;x++)
VideoDrawTransRectangle(ColorRed,2*x,i,2,20,x*2);
/*Should show rectangles in screen's bottom-right corners */
VideoDrawRectangleClip(ColorGray,VideoWidth-30,VideoHeight-20,60,40);
VideoDraw25TransRectangleClip(ColorBlue,VideoWidth-29,VideoHeight-19,58,38);
VideoDraw50TransRectangleClip(ColorRed,VideoWidth-28,VideoHeight-18,56,36);
VideoDraw75TransRectangleClip(ColorGreen,VideoWidth-27,VideoHeight-17,54,34);
VideoDrawTransRectangleClip(ColorBlue,VideoWidth-26,VideoHeight-16,52,32,64);
/* Display grid of 10x10 (to detect errors more easier) */
for (y=0;y<VideoHeight;y+=10)
for (x=0;x<VideoWidth;x+=10)
VideoDrawPixel(ColorWhite,x,y);
/*Should show white pixel in lower-right corner (not prevented by clippingi) */
VideoDrawPixelClip(ColorWhite,VideoWidth-1,VideoHeight-1);
/* Draw colorcube (only for 8bpp!) and common+current palette
for (i=0;i<32;i++)
for (y=0;y<32;y++)
for (x=0;x<32;x++)
{
int a,b;
a=(x+(i%10)*32)*2;
b=(y+(i/10)*32)*2;
VideoMemory8[a+b*VideoWidth] =
VideoMemory8[a+1+b*VideoWidth] =
VideoMemory8[a+(b+1)*VideoWidth] =
VideoMemory8[a+1+(b+1)*VideoWidth] =
colorcube8[ (i<<10)|(y<<5)|x ];
}
for (i=0;i<256;i++)
VideoMemory8[i+400*VideoWidth] =
VideoMemory8[i+401*VideoWidth] = i;
for (i=0;i<256;i++)
VideoMemory8[i+403*VideoWidth] =
VideoMemory8[i+404*VideoWidth] = Pixels8[ i ];
*/
/* put it all on screen (when it is not already there ;) */
InvalidateArea(0,0,VideoWidth,VideoHeight);
}
/**
** Display update.
*/
@ -466,6 +657,10 @@ global void GameMainLoop(void)
if( MustRedraw /* && !VideoInterrupts */ ) {
UpdateDisplay();
//Enable when debugging linedraw routines..
//DebugTestDisplay();
//
// If double-buffered mode, we will display the contains of
// VideoMemory. If direct mode this does nothing. In X11 it does

View file

@ -382,7 +382,7 @@ global void LoadDecorations(void)
*/
local void DrawManaBar(int x,int y,const UnitType* type,int full,int ready)
{
int f;
int f, w;
f=(100*ready)/full;
if ( ShowManaHorizontal == 0) {
@ -411,11 +411,13 @@ local void DrawManaBar(int x,int y,const UnitType* type,int full,int ready)
,(f*type->BoxHeight)/100
,4);
}
VideoFillRectangleClip(ColorBlue
w=(f*type->BoxHeight)/100-1;
if ( w > 0 ) // Prevents -1 turning into unsigned int
VideoFillRectangleClip(ColorBlue
,x+(type->TileWidth*TileSizeX-type->BoxWidth)/2+1
,(y+(type->TileHeight*TileSizeY-type->BoxHeight)/2)
+type->BoxHeight+6
,(f*type->BoxHeight)/100-1
,w
,3);
}
}
@ -431,7 +433,7 @@ local void DrawManaBar(int x,int y,const UnitType* type,int full,int ready)
local void DrawDecoration(const Unit* unit,const UnitType* type,int x,int y)
{
int f;
int color;
int color, w;
const UnitStats* stats;
#ifdef REFS_DEBUG
@ -498,11 +500,13 @@ local void DrawDecoration(const Unit* unit,const UnitType* type,int x,int y)
,((f*type->BoxHeight)/100)+1
,5);
}
w = (f*type->BoxHeight)/100-1;
if ( w > 0 ) // Prevents -1 turning into unsigned int
VideoFillRectangleClip(color
,x+((type->TileWidth*TileSizeX-type->BoxWidth)/2)+1
,(y+(type->TileHeight*TileSizeY-type->BoxHeight)/2)
+type->BoxHeight+2
,(f*type->BoxHeight)/100-1
,w
,3);
} else {
VideoFillRectangleClip(color

View file

@ -43,6 +43,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <sys/ipc.h>
#include <sys/shm.h>
@ -175,6 +176,91 @@ local long X11GetTicks(void)
return ticks;
}
/**
** Converts a hardware independend 256 color palette to a hardware
** dependent palette. Letting a system color as index in the result,
** correspond with the right RGB value.
**
** @param palette Hardware independent 256 color palette.
**
** @param syspalette Hardware dependent 256 color palette, to be filled.
**
** @param palette Array denoting which entries in above palette are
** defined by this function.
*/
local void AllocPalette8( Palette *palette,
Palette *syspalette,
unsigned long syspalette_defined[8] )
{
XWindowAttributes xwa;
XColor color;
int average, i, warning_given;
XGetWindowAttributes( TheDisplay, TheMainWindow, &xwa );
average = 0;
color.pad = 0;
color.flags = DoRed | DoGreen | DoBlue;
warning_given=0;
for ( i = 0; i <= 7; i++ )
syspalette_defined[i]=0;
for ( i = 0; i <= 255; i++, palette++ )
{
unsigned int r, g, b;
// -> Video
color.red = (r=palette->r) << 8;
color.green = (g=palette->g) << 8;
color.blue = (b=palette->b) << 8;
if ( XAllocColor( TheDisplay, xwa.colormap, &color ) )
{
unsigned long bit;
int j;
if ( color.pixel > 255 ) // DEBUG: should not happen?
{
fprintf( stderr, "System 8bit color above unsupported 255\n" );
exit( -1 );
}
// Fill palette, to get from system to RGB
j = color.pixel>>5;
bit = 1 << (color.pixel&0x1F);
if ( syspalette_defined[j] & bit )
{
// multiple RGB matches for one sytem color, average RGB values
// Note: happens when a palette with duplicate RGB values is used, but
// might also happen for another reason?
r += syspalette[color.pixel].r + 1;
r >>= 1;
g += syspalette[color.pixel].g + 1;
g >>= 1;
b += syspalette[color.pixel].b + 1;
b >>= 1;
average++;
}
else syspalette_defined[j] |= bit;
syspalette[color.pixel].r = r;
syspalette[color.pixel].g = g;
syspalette[color.pixel].b = b;
}
else if ( !warning_given )
{//Note: this may also happen when more then 256 colors are tried..
// Use VideoFreePalette to unallocate..
warning_given=1;
fprintf( stderr,
"Cannot allocate 8pp color\n"
"Probably another application has taken some colors..\n" );
}
}
// Denote missing colors
if ( average )
fprintf( stderr, "Only %d unique colors available\n", 256-average );
}
/**
** X11 initialize.
*/
@ -248,6 +334,7 @@ foundvisual:
VideoDepth=xvi.depth;
}
VideoBpp=xpfv[i].bits_per_pixel;
printf( "Video X11, %d color, %d bpp\n", VideoDepth, VideoBpp );
if( !VideoWidth ) {
VideoWidth = DEFAULT_VIDEO_WIDTH;
@ -397,6 +484,11 @@ foundvisual:
XAddConnectionWatch(TheDisplay,MyConnectionWatch,NULL);
XFlush(TheDisplay);
//
// Let hardware independent palette be converted.
//
VideoAllocPalette8=AllocPalette8;
}
/**
@ -1126,11 +1218,66 @@ global void WaitEventsAndKeepSync(void)
}
/**
** Create a new hardware dependend palette palette.
** Free a hardware dependend palette.
**
** @param palette Hardware independend palette.
** @param palette Hardware dependend palette.
**
** @return A hardware dependend pixel table.
** FIXME: XFreeColors planes can be used to free an entire range
** of colors; couldn't get it working though..
*/
local void VideoFreePallette(void *pixels)
{
XWindowAttributes xwa;
int i;
char *vp;
unsigned long oldpal[256];
if ( !TheDisplay || !TheMainWindow )
return;
XGetWindowAttributes( TheDisplay, TheMainWindow, &xwa );
if ( pixels )
{
switch( VideoBpp ) {
case 8:
for (i=0;i<256;i++)
oldpal[ i ] = ((VMemType8 *)pixels)[ i ];
break;
case 15:
case 16:
for (i=0;i<256;i++)
oldpal[ i ] = ((VMemType16 *)pixels)[ i ];
break;
case 24:
for (i=0;i<256;i++)
{
vp = (char *)(oldpal + i);
vp[0]=((VMemType24*)pixels)[i].a;
vp[1]=((VMemType24*)pixels)[i].b;
vp[2]=((VMemType24*)pixels)[i].c;
}
break;
case 32:
for (i=0;i<256;i++)
oldpal[ i ] = ((VMemType32 *)pixels)[ i ];
break;
default:
DebugLevel0Fn(": Unknown depth\n");
return;
}
XFreeColors(TheDisplay,xwa.colormap,oldpal,256,0);
}
}
/**
** Allocate a new hardware dependend palette palette.
**
** @param palette Hardware independend palette.
**
** @return A hardware dependend pixel table.
**
** FIXME: VideoFreePallette should be used to free unused colors
*/
global VMemType* VideoCreateNewPalette(const Palette *palette)
{
@ -1145,6 +1292,10 @@ global VMemType* VideoCreateNewPalette(const Palette *palette)
switch( VideoBpp ) {
case 8:
if ( colorcube8 )
// Shortcut: get palette from already allocated common palette.
// FIXME: shortcut should be placed in video.c, for all video support.
return (VMemType*)VideoFindNewPalette8( colorcube8, palette );
pixels=malloc(256*sizeof(VMemType8));
break;
case 15:

File diff suppressed because it is too large Load diff

View file

@ -210,10 +210,9 @@ global void VideoDraw8to8X(const Graphic* sprite,unsigned frame,int x,int y)
pixels=(VMemType8*)sprite->Pixels;
sp=((unsigned char**)sprite->Frames)[frame];
w=sprite->Width;
dp=VideoMemory8+x+y*VideoWidth+w;
dp=VideoMemory8+x+y*VideoWidth+w-1;
da=VideoWidth+w;
ep=dp+VideoWidth*sprite->Height;
do {
lp=dp-w;
do { // 1 line
@ -254,7 +253,7 @@ global void VideoDraw8to16X(const Graphic* sprite,unsigned frame,int x,int y)
pixels=(VMemType16*)sprite->Pixels;
sp=((unsigned char**)sprite->Frames)[frame];
w=sprite->Width;
dp=VideoMemory16+x+y*VideoWidth+w;
dp=VideoMemory16+x+y*VideoWidth+w-1;
da=VideoWidth+w;
ep=dp+VideoWidth*sprite->Height;
@ -298,7 +297,7 @@ global void VideoDraw8to24X(const Graphic* sprite,unsigned frame,int x,int y)
pixels=(VMemType24*)sprite->Pixels;
sp=((unsigned char**)sprite->Frames)[frame];
w=sprite->Width;
dp=VideoMemory24+x+y*VideoWidth+w;
dp=VideoMemory24+x+y*VideoWidth+w-1;
da=VideoWidth+w;
ep=dp+VideoWidth*sprite->Height;
@ -342,7 +341,7 @@ global void VideoDraw8to32X(const Graphic* sprite,unsigned frame,int x,int y)
pixels=(VMemType32*)sprite->Pixels;
sp=((unsigned char**)sprite->Frames)[frame];
w=sprite->Width;
dp=VideoMemory32+x+y*VideoWidth+w;
dp=VideoMemory32+x+y*VideoWidth+w-1;
da=VideoWidth+w;
ep=dp+VideoWidth*sprite->Height;

View file

@ -1231,12 +1231,12 @@ global VMemType* VideoCreateNewPalette(const Palette *palette)
// -> Video
switch( VideoDepth ) {
case 15:
case 15: // RGB=[5bit|5bit|5bit]
((VMemType16*)pixels)[i] = ((r >> 1) << 10)
+ ((g >>1) << 5)
+ (b >> 1);
break;
case 16:
case 16: // RGB=[5bit|6bit|5bit]
((VMemType16*)pixels)[i] = ((r >> 1) << 11)
+ (g << 5)
+ (b >> 1);

View file

@ -157,9 +157,47 @@ global volatile int VideoInterrupts; /// be happy, were are quicker
/// Loaded system palette. 256-entries long, active system palette.
global Palette GlobalPalette[256];
/**
** As a video 8bpp pixel color doesn't have RGB encoded, but denote some
** index (a value from contents Pixels) in a system pallete, the
** following precalculated arrays deliver a shortcut.
** NOTE: all array pointers are NULL in a non 8bpp mode
**
** commonpalette:
** The single main color palette denoting all possible colors on which all
** other palettes (including above GlobalPalette) are based.
** Note:this means other palettes probably doesn't contains unique colors.
**
** commonpalette_defined:
** Denotes the defined entries (as bit index) in above palette.
** Needed as for X11 it is possible we can't get all 256 colors.
**
** colorcube8:
** Array of 32*32*32 system colors, to get from an unsigned int RGB
** (5x5x5 bit) to a system color.
**
** lookup25trans8:
** Array to get from two system colors as unsigned int (color1<<8)|color2
** to a new system color which is aproximately 75% color1 and 25% color2.
** lookup50trans8:
** The same for 50% color1 and 50% color2.
**
** VideoAllocPalette8:
** Funcytion to let hardware independent palette be converted (when set).
*/
global Palette *commonpalette = NULL;
global unsigned long commonpalette_defined[8];
global VMemType8 *colorcube8 = NULL;
global VMemType8 *lookup25trans8 = NULL;
global VMemType8 *lookup50trans8 = NULL;
global void (*VideoAllocPalette8)( Palette *palette,
Palette *syspalette,
unsigned long syspalette_defined[8] )=NULL;
/// Does ColorCycling..
global void (*ColorCycle)(void);
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
@ -287,16 +325,21 @@ global void LoadRGB(Palette *pal, const char *name)
{
FILE *fp;
int i;
unsigned char *p;
unsigned char buffer[256*3];
if((fp=fopen(name,"rb")) == NULL) {
if( (fp=fopen(name,"rb")) == NULL ||
fread(buffer,sizeof(unsigned char),256*3,fp)<256*3 )
{
fprintf(stderr,"Can't load palette %s\n",name);
exit(-1);
}
p=buffer;
for(i=0;i<256;i++){
pal[i].r=fgetc(fp)<<2;
pal[i].g=fgetc(fp)<<2;
pal[i].b=fgetc(fp)<<2;
pal[i].r=(*p++)<<2;
pal[i].g=(*p++)<<2;
pal[i].b=(*p++)<<2;
}
fclose(fp);
@ -570,6 +613,335 @@ local void ColorCycle32(void)
MustRedraw |= RedrawMap | RedrawInfoPanel;
}
/*===========================================================================
Following functions support a single common palette for 8bpp
===========================================================================*/
/**
** Fills a hardware independend palette with most common colors.
** (Only really needed in 8bpp, to get a good representation of all color
** possibilities.)
** NOTE: define BPP8_WINSAFE or BPP8_IRGB for a different version.
** X11 supports BPP8_NORMAL to prevent using a common palette
** (this will deliver "color allocation error" though!)
**
** @param palette 256 color palette, to be filled with most common RGB.
**
** FIXME: Use TheUI settings (brightness, contrast and saturation) and
** visual color range knowledge to reduce the ammount of colors needed.
*/
local void VideoFillCommonPalette8( Palette *palette )
{
#ifdef BPP8_WINSAFE /*---------------------------------------------------------
This pallete generator is consider safe for Windows(tm), as static colors used
by the system are kept and at the original locations.
---------------------------------------------------------------------------*/
const unsigned char win_top[] = {
0, 0, 0,
128, 0, 0,
0, 128, 0,
128, 128, 0,
0, 0, 128,
128, 0, 128,
0, 128, 128,
192, 192, 192,
192, 220, 192,
166, 202, 240 };
const unsigned char win_bottom[] = {
255, 251, 240,
160, 160, 164,
128, 128, 128,
255, 0, 0,
0, 255, 0,
255, 255, 0,
0, 0, 255,
255, 0, 255,
0, 255, 255,
255, 255, 255 };
const unsigned char colorlevel[] = { 0, 87, 138, 181, 220, 255 };
const unsigned char graylevel[] = {
47, 67, 82, 95, 106, 116, 125, 134, 142, 150, 157, 164, 171, 177,
183, 189, 195, 201, 206, 212, 217, 222, 227, 232, 237, 241, 246, 251 };
int i, r, g, b;
/* Fill top of palette with static system colors */
for ( i = 0; i <= 3*9; i += 3, palette++ )
{
palette->r = win_top[ i ];
palette->g = win_top[ i + 1 ];
palette->b = win_top[ i + 2 ];
}
/* Fill 6*6*6 colorcube (without values already present in static parts) */
for ( r = 0; r <= 5; r++ )
for ( g = 0; g <= 5; g++ )
for ( b = 0; b <= 5; b++ )
if ( (r && r != 5) || (g && g != 5) || (b && b != 5) )
{
palette->r = colorlevel[ r ];
palette->g = colorlevel[ g ];
palette->b = colorlevel[ b ];
palette++;
}
/* Fill up remaining non-static part with grayshades */
for ( i = 0; i <= 27; i++, palette++ )
palette->r = palette->g = palette->b = graylevel[ i ];
/* Fill bottom of palette with static system colors */
for ( i = 0; i <= 3*9; i += 3, palette++ )
{
palette->r = win_bottom[ i ];
palette->g = win_bottom[ i + 1 ];
palette->b = win_bottom[ i + 2 ];
}
#else
#ifdef BPP8_IRGB /*------------------------------------------------------------
Palette generator using 8bit encoded as [IIRRGGBB], where I denotes the
intensity of the RGB values along a grayshade axis. Which delivers a better
spread out RGB range, but can not handle extreme values like 255:0:255
---------------------------------------------------------------------------*/
int i, r, g, b;
for ( i = 0; i <= 3*68; i+=68 )
for ( r = 0; r <= 3*17; r+=17 )
for ( g = 0; g <= 3*17; g+=17 )
for ( b = 0; b <= 3*17; b+=17, palette++ )
{
palette->r = i+r;
palette->g = i+g;
palette->b = i+b;
}
#else /* default ------------------------------------------------------------
Experimental palette, defining a colorcube in a hshorter (most common) range
and defining remaining as 40 grayshades over total range.
This delivered best quality in 8bpp gameplay:
- the large range for grayshades is valuable as many items need them
- the shortened colorcube seems just to fit any colors needed.
---------------------------------------------------------------------------*/
int i, r, g, b;
/* Fill 6*6*6 colorcube (shortend and in lower RGB range) */
for ( r = 0; r <= 5; r++ )
for ( g = 0; g <= 5; g++ )
for ( b = 0; b <= 5; b++, palette++ )
{
palette->r = 15+(127*r)/5;
palette->g = 15+(127*g)/5;
palette->b = 15+(127*b)/5;
}
/* Fill up remaining part with grayshades */
for ( i = 0; i <= 39; i++, palette++ )
palette->r = palette->g = palette->b = ((i-216)*255)/39;
#endif
#endif
}
/**
** Fill a colorcube to get from a RGB (5x5x5 bit) to a system 8bpp color
**
** @param palette Array of 256 bytes with hardware dependent color as
** index, delivers RGB value (each in range 0..255).
**
** @param pal_def Denotes which entries (as bit index) in above palette
** are defined (and so may be used in colorcube).
** NOTE: atleast one defined entry should be available
**
** @param cube Array of 32768 (32*32*32) bytes with RGB value (each in
** range 0..31) as index, delivers color index.
*/
local void VideoFillColorcube8( const Palette *palette,
const unsigned long pal_def[8],
VMemType8 *cube )
{
int r, g, b, i;
for ( r = 0; r <= 255; r+=8 )
for ( g = 0; g <= 255; g+=8 )
for ( b = 0; b <= 255; b+=8 )
{
const Palette *pal;
long int mindistance = 255*255*3+1;
int colorfound = 0;
// seek closest color in given palette
for ( pal = palette, i = 0; i <= 255; pal++, i++ )
{
unsigned long bit;
bit = 1 << (i&0x1F);
if ( pal_def[ i>>5 ] & bit )
{
long int distance, xr, xg, xb;
xr = (long int)pal->r - r;
xb = (long int)pal->b - b;
xg = (long int)pal->g - g;
distance = xr*xr + xb*xb + xg*xg;
if ( distance < mindistance )
{
mindistance=distance;
colorfound=i;
}
}
}
// refer RGB to the system color (palette index) found
*cube++ = colorfound;
// fprintf( stderr, "%d %d %d = %d %d %d\n",
// r, g, b, palette[colorfound].r, palette[colorfound].g,
// palette[colorfound].b );
}
}
/**
** Find a new hardware dependend palette, re-using the colors as set in
** the colorcube.
**
** @param cube A 5x5x5 bit colorcube to get from RGB to system color.
**
** @param palette Hardware independend palette of 256 colors.
**
** @return A hardware dependend 8bpp pixel table.
**
*/
global VMemType8* VideoFindNewPalette8( const VMemType8 *cube,
const Palette *palette )
{
VMemType8 *newpixels, *p;
int i;
newpixels=p=malloc(256*sizeof(VMemType8));
i=256;
do
{
int r, g, b;
//FIXME: find a faster way, with rounding..
//r = palette->r>>3;
//g = palette->g>>3;
//b = palette->b>>3;
r = (palette->r*31+15)/255;
g = (palette->g*31+15)/255;
b = (palette->b*31+15)/255;
palette++;
*p++ = cube[ (r<<10) | (g<<5) | b ];
} while ( --i > 0 );
return newpixels;
}
/**
** Fill a lookup table to get from two system colors 8bpp as unsigned int
** (color1<<8)|color2 to a new system color which is alpha% color2 and
** (100-alpha)% color1.
**
** @param palette Already filled 256 color palette, to get from system
** color to RGB.
**
** @param cube Already filled 32*32*32 array of system colors, to get
** from RGB (as 5x5x5 bit) back to system color.
**
** @param lookup Allocated 256*256 array of system colors, to be filled
** as a lookup table for transparency alpha.
**
** @param alpha value in 0..255 denoting 0..100% transparency
*/
local void FillTransLookup8( const Palette *palette,
const VMemType8 *cube,
VMemType8 *lookup,
unsigned char alpha )
{
const Palette *p1, *p2;
unsigned int i, j;
unsigned int alpha1,alpha2,r1, g1, b1, r2, g2, b2;
alpha1=255-alpha;
alpha2=alpha;
for ( p1=palette, i = 256; i > 0; i-- )
{
r1 = alpha1*(unsigned int)p1->r;
g1 = alpha1*(unsigned int)p1->g;
b1 = alpha1*(unsigned int)p1->b;
p1++;
for ( p2=palette, j = 256; j > 0; j-- )
{
r2 = (r1 + alpha2*(unsigned int)p2->r + 255*4)/(255*8);
g2 = (g1 + alpha2*(unsigned int)p2->g + 255*4)/(255*8);
b2 = (b1 + alpha2*(unsigned int)p2->b + 255*4)/(255*8);
p2++;
*lookup++ = cube[ (r2<<10) | (g2<<5) | b2 ];
}
}
}
/**
** Initialize globals based on a single common palette of 256 colors.
** Only needed for 8bpp, which hasn't RGB encoded in its system color.
** FIXME: should be called again when it gets dependent of TheUI settings
** then call VideoFreePalette first to prevent "can not allocate"
*/
local void InitSingleCommonPalette8( void )
{
Palette *tmp;
int i;
if ( (tmp=malloc(256*sizeof(Palette))) &&
(!VideoAllocPalette8 || (commonpalette=malloc(256*sizeof(Palette)))) &&
(colorcube8=malloc(32*32*32*sizeof(VMemType8))) &&
(lookup25trans8=malloc(256*256*sizeof(VMemType8))) &&
(lookup50trans8=malloc(256*256*sizeof(VMemType8))) )
{
// Create one allocated pallette of 256 colors to be used by all
// palettes created later.
// This prevents "can not allocate color" errors, but the downside is
// that a fullscreen graphic can not use its own pallette to the fullest
// (not all colors might be present in the system pallete).
VideoFillCommonPalette8(tmp);
//for ( i=0; i<=255; i++ )
// fprintf( stderr, "%d %d %d\n", tmp[i].r, tmp[i].g, tmp[i].b );
if ( VideoAllocPalette8 )
{ // Palette needs to be converted to hardware dependent palette
VideoAllocPalette8(tmp,commonpalette,commonpalette_defined);
free( tmp );
}
else
{ // Use palette AS-IS FIXME: unused at the moment..
commonpalette = tmp;
for ( i=0; i<=7; i++ )
commonpalette_defined[i]=0xFFFFFFFF;
}
// Create a colorcube to easily get from RGB back to system color
VideoFillColorcube8(commonpalette,commonpalette_defined,colorcube8);
// Create lookup tables to get from one system color to another.
//FIXME: With max 256 unique colors in above colorcube, each RGB axis can
// contain 3root(256)=6.3496.. variations. Currently only 5
// supported (0,25,50,75,100% with/without use of lookup tables).
// So extra levels 12.5% and 37.5% needed for better representation.
FillTransLookup8(commonpalette,colorcube8,lookup25trans8,(255+2)/4);
FillTransLookup8(commonpalette,colorcube8,lookup50trans8,(255+1)/2);
}
else
{
fprintf( stderr, "Out of memory for special 8bpp display mode\n"
"Try another mode if you're low on memory\n" );
exit( -1 );
}
}
/*===========================================================================*/
/**
** Initializes system palette. Also calls SetPlayersPalette to set
** palette for all players.
@ -582,7 +954,7 @@ global void VideoSetPalette(const VMemType* palette)
{
#if 0 // ARI: FIXME: This ruins menu palettes, when loaded via default.cm (introduce refcnt?)
if( Pixels ) {
free(Pixels);
free(Pixels);//FIXME: free unsufficient, XFreeColors needed for X11
}
#endif
Pixels=(VMemType*)palette;
@ -672,6 +1044,15 @@ global void InitVideo(void)
#endif
#endif
//
// Use single common palette to be used for all palettes in 8bpp
//
#ifndef BPP8_NORMAL
if ( UseX11 && VideoBpp == 8 ) // FIXME: to be extended for all video..
InitSingleCommonPalette8();
#endif
//
// Init video sub modules
//