From 867543fc797a942823a79653c23e7f801971b148 Mon Sep 17 00:00:00 2001 From: stephanr <> Date: Wed, 6 Jun 2001 22:03:00 +0000 Subject: [PATCH] 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 --- src/include/video.h | 123 +- src/map/map_fog.cpp | 24 +- src/sound/sound_id.cpp | 1 - src/stratagus/groups.cpp | 1 - src/stratagus/mainloop.cpp | 195 ++ src/unit/unit_draw.cpp | 14 +- src/video/X11.cpp | 157 +- src/video/linedraw.cpp | 5004 ++++++++++++++++++++++++++++-------- src/video/sprite.cpp | 9 +- src/video/svgalib.cpp | 4 +- src/video/video.cpp | 391 ++- 11 files changed, 4776 insertions(+), 1147 deletions(-) diff --git a/src/include/video.h b/src/include/video.h index bdb015ee4..70d98980b 100644 --- a/src/include/video.h +++ b/src/include/video.h @@ -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 diff --git a/src/map/map_fog.cpp b/src/map/map_fog.cpp index 294878595..69e63e265 100644 --- a/src/map/map_fog.cpp +++ b/src/map/map_fog.cpp @@ -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; diff --git a/src/sound/sound_id.cpp b/src/sound/sound_id.cpp index cf55383b9..365fc241d 100644 --- a/src/sound/sound_id.cpp +++ b/src/sound/sound_id.cpp @@ -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. diff --git a/src/stratagus/groups.cpp b/src/stratagus/groups.cpp index 3bb1ef4a3..c3fc906a2 100644 --- a/src/stratagus/groups.cpp +++ b/src/stratagus/groups.cpp @@ -1,4 +1,3 @@ -// ___________ _________ _____ __ // \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_ // | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\ // | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | | diff --git a/src/stratagus/mainloop.cpp b/src/stratagus/mainloop.cpp index 1f36ad313..294666277 100644 --- a/src/stratagus/mainloop.cpp +++ b/src/stratagus/mainloop.cpp @@ -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 diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp index bf01523a5..674bdbe98 100644 --- a/src/unit/unit_draw.cpp +++ b/src/unit/unit_draw.cpp @@ -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 diff --git a/src/video/X11.cpp b/src/video/X11.cpp index 96bd3480f..f417693b3 100644 --- a/src/video/X11.cpp +++ b/src/video/X11.cpp @@ -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: diff --git a/src/video/linedraw.cpp b/src/video/linedraw.cpp index d2c415f1a..90ae6eb4a 100644 --- a/src/video/linedraw.cpp +++ b/src/video/linedraw.cpp @@ -53,7 +53,6 @@ extern int ClipY2; /// current clipping bottom right /*---------------------------------------------------------------------------- -- Variables ----------------------------------------------------------------------------*/ - /** ** Draw pixel unclipped. ** @@ -93,12 +92,20 @@ global void (*VideoDraw75TransPixel)(SysColors color,int x,int y); /** ** Draw translucent pixel unclipped. ** + ** All upfollowing translucent routines follow: + ** newcolor = ((oldcolor-color)*alpha)/255+color + ** + ** FIXME: the following delivers better rounding, but is slower and can + ** not be calculate in an unsigned char (can deliver overflow): + ** newcolor = (oldcolor*alpha+color*(255-alpha)+127)/255 + ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen ** @param alpha alpha value of pixel. */ -global void (*VideoDrawTransPixel)(SysColors color,int x,int y,int alpha); +global void (*VideoDrawTransPixel)(SysColors color,int x,int y, + unsigned char alpha); /** ** Draw pixel clipped to current clip setting. @@ -109,43 +116,6 @@ global void (*VideoDrawTransPixel)(SysColors color,int x,int y,int alpha); */ global void (*VideoDrawPixelClip)(SysColors color,int x,int y); - /** - ** Draw 25% translucent pixel clipped to current clip setting. - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - */ -global void (*VideoDraw25TransPixelClip)(SysColors color,int x,int y); - - /** - ** Draw 50% translucent pixel clipped to current clip setting. - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - */ -global void (*VideoDraw50TransPixelClip)(SysColors color,int x,int y); - - /** - ** Draw 75% translucent pixel clipped to current clip setting. - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - */ -global void (*VideoDraw75TransPixelClip)(SysColors color,int x,int y); - - /** - ** Draw translucent pixel clipped to current clip setting. - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param alpha alpha value of pixel. - */ -global void (*VideoDrawTransPixelClip)(SysColors color,int x,int y,int alpha); - /** ** Draw vertical line unclipped. ** @@ -200,63 +170,7 @@ global void (*VideoDraw75TransVLine)(SysColors color,int x,int y ** @param alpha alpha value of pixel. */ global void (*VideoDrawTransVLine)(SysColors color,int x,int y - ,unsigned height,int alpha); - - /** - ** Draw vertical line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param height height of line. - */ -global void (*VideoDrawVLineClip)(SysColors color,int x,int y - ,unsigned height); - - /** - ** Draw 25% translucent vertical line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param height height of line. - */ -global void (*VideoDraw25TransVLineClip)(SysColors color,int x,int y - ,unsigned height); - - /** - ** Draw 50% translucent vertical line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param height height of line. - */ -global void (*VideoDraw50TransVLineClip)(SysColors color,int x,int y - ,unsigned height); - - /** - ** Draw 75% translucent vertical line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param height height of line. - */ -global void (*VideoDraw75TransVLineClip)(SysColors color,int x,int y - ,unsigned height); - - /** - ** Draw translucent vertical line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param height height of line. - ** @param alpha alpha value of pixel. - */ -global void (*VideoDrawTransVLineClip)(SysColors color,int x,int y - ,unsigned height,int alpha); + ,unsigned height,unsigned char alpha); /** ** Draw horizontal line unclipped. @@ -312,63 +226,7 @@ global void (*VideoDraw75TransHLine)(SysColors color,int x,int y ** @param alpha alpha value of pixel. */ global void (*VideoDrawTransHLine)(SysColors color,int x,int y - ,unsigned width,int alpha); - - /** - ** Draw horizontal line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param width width of line. - */ -global void (*VideoDrawHLineClip)(SysColors color,int x,int y - ,unsigned width); - - /** - ** Draw 25% translucent horizontal line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param width width of line. - */ -global void (*VideoDraw25TransHLineClip)(SysColors color,int x,int y - ,unsigned width); - - /** - ** Draw 50% translucent horizontal line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param width width of line. - */ -global void (*VideoDraw50TransHLineClip)(SysColors color,int x,int y - ,unsigned width); - - /** - ** Draw 75% translucent horizontal line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param width width of line. - */ -global void (*VideoDraw75TransHLineClip)(SysColors color,int x,int y - ,unsigned width); - - /** - ** Draw translucent horizontal line clipped to current clip setting - ** - ** @param color Color index. - ** @param x x coordinate on the screen - ** @param y y coordinate on the screen - ** @param width width of line. - ** @param alpha alpha value of pixel. - */ -global void (*VideoDrawTransHLineClip)(SysColors color,int x,int y - ,unsigned width,int alpha); + ,unsigned width,unsigned char alpha); /** ** Draw line unclipped. @@ -428,67 +286,7 @@ global void (*VideoDraw75TransLine)(SysColors color,int sx,int sy ** @param alpha alpha value of pixel. */ global void (*VideoDrawTransLine)(SysColors color,int sx,int sy,int dx,int dy - ,int alpha); - - /** - ** Draw line clipped to current clip setting - ** - ** @param color Color index. - ** @param sx Source x coordinate on the screen - ** @param sy Source y coordinate on the screen - ** @param dx Destination x coordinate on the screen - ** @param dy Destination y coordinate on the screen - */ -global void (*VideoDrawLineClip)(SysColors color,int sx,int sy,int dx,int dy); - - /** - ** Draw 25% translucent line clipped to current clip setting - ** - ** @param color Color index. - ** @param sx Source x coordinate on the screen - ** @param sy Source y coordinate on the screen - ** @param dx Destination x coordinate on the screen - ** @param dy Destination y coordinate on the screen - */ -global void (*VideoDraw25TransLineClip)(SysColors color,int sx,int sy - ,int dx,int dy); - - /** - ** Draw 50% translucent line clipped to current clip setting - ** - ** @param color Color index. - ** @param sx Source x coordinate on the screen - ** @param sy Source y coordinate on the screen - ** @param dx Destination x coordinate on the screen - ** @param dy Destination y coordinate on the screen - */ -global void (*VideoDraw50TransLineClip)(SysColors color,int sx,int sy, - int dx,int dy); - - /** - ** Draw 75% translucent line clipped to current clip setting - ** - ** @param color Color index. - ** @param sx Source x coordinate on the screen - ** @param sy Source y coordinate on the screen - ** @param dx Destination x coordinate on the screen - ** @param dy Destination y coordinate on the screen - */ -global void (*VideoDraw75TransLineClip)(SysColors color,int sx,int sy - ,int dx,int dy); - - /** - ** Draw translucent line clipped to current clip setting - ** - ** @param color Color index. - ** @param sx Source x coordinate on the screen - ** @param sy Source y coordinate on the screen - ** @param dx Destination x coordinate on the screen - ** @param dy Destination y coordinate on the screen - ** @param alpha alpha value of pixel. - */ -global void (*VideoDrawTransLineClip)(SysColors color,int sx,int sy - ,int dx,int dy,int alpha); + ,unsigned char alpha); /** ** Draw rectangle. @@ -549,10 +347,10 @@ global void (*VideoDraw75TransRectangle)(SysColors color,int x,int y ** @param alpha alpha value of pixel. */ global void (*VideoDrawTransRectangle)(SysColors color,int x,int y - ,unsigned w,unsigned h,int alpha); + ,unsigned w,unsigned h,unsigned char alpha); /** - ** Draw rectangle clipped. + ** Fill rectangle. ** ** @param color Color index. ** @param x x coordinate on the screen @@ -560,11 +358,11 @@ global void (*VideoDrawTransRectangle)(SysColors color,int x,int y ** @param h height of rectangle. ** @param w width of rectangle. */ -global void (*VideoDrawRectangleClip)(SysColors color,int x,int y +global void (*VideoFillRectangle)(SysColors color,int x,int y ,unsigned w,unsigned h); /** - ** Draw 25% translucent rectangle clipped. + ** Draw 25% translucent filled rectangle. ** ** @param color Color index. ** @param x x coordinate on the screen @@ -572,11 +370,11 @@ global void (*VideoDrawRectangleClip)(SysColors color,int x,int y ** @param h height of rectangle. ** @param w width of rectangle. */ -global void (*VideoDraw25TransRectangleClip)(SysColors color,int x,int y +global void (*VideoFill25TransRectangle)(SysColors color,int x,int y ,unsigned w,unsigned h); /** - ** Draw 50% translucent rectangle clipped. + ** Draw 50% translucent filled rectangle. ** ** @param color Color index. ** @param x x coordinate on the screen @@ -584,11 +382,11 @@ global void (*VideoDraw25TransRectangleClip)(SysColors color,int x,int y ** @param h height of rectangle. ** @param w width of rectangle. */ -global void (*VideoDraw50TransRectangleClip)(SysColors color,int x,int y +global void (*VideoFill50TransRectangle)(SysColors color,int x,int y ,unsigned w,unsigned h); /** - ** Draw 75% translucent rectangle clipped. + ** Draw 75% translucent filled rectangle. ** ** @param color Color index. ** @param x x coordinate on the screen @@ -596,11 +394,11 @@ global void (*VideoDraw50TransRectangleClip)(SysColors color,int x,int y ** @param h height of rectangle. ** @param w width of rectangle. */ -global void (*VideoDraw75TransRectangleClip)(SysColors color,int x,int y +global void (*VideoFill75TransRectangle)(SysColors color,int x,int y ,unsigned w,unsigned h); /** - ** Draw translucent rectangle clipped. + ** Draw translucent filled rectangle. ** ** @param color Color index. ** @param x x coordinate on the screen @@ -609,13 +407,138 @@ global void (*VideoDraw75TransRectangleClip)(SysColors color,int x,int y ** @param w width of rectangle. ** @param alpha alpha value of pixel. */ -global void (*VideoDrawTransRectangleClip)(SysColors color,int x,int y - ,unsigned w,unsigned h,int alpha); +global void (*VideoFillTransRectangle)(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha); /*---------------------------------------------------------------------------- -- Local functions ----------------------------------------------------------------------------*/ +/** +** Dump bits in debugger (DEBUG only) +** +** @param bits bits to display +*/ +static void DebugBits( unsigned long bits ) +{ + unsigned long i; + + for ( i = ((~(unsigned long)0)>>1)+1; i > 0; i>>=1 ) + if ( bits & i ) + putc( '1', stderr ); + else putc( '0', stderr ); + putc( '\n', stderr ); +} + +// =========================================================================== +// Color +// =========================================================================== + +/** +** Calculate brightness from a given RGB color value +** ( UNUSED, move to video.c? ) +** +** @param r Color Red-value. +** @param g Color Green-value. +** @param b Color Blue-value. +*/ +static unsigned char RGBtoBrightness( unsigned char r, + unsigned char g, + unsigned char b ) +{ + unsigned int brightness; +// "The weights to compute true CIE luminance from linear red, green and blue +// (indicated without prime symbols), for the Rec. 709, are these:" +// brightness = 0.2125*r+0.7154*g+0.0721*b" (from Poynton's color FAQ) + brightness = (unsigned int)r*3+(unsigned int)g*10+(unsigned int)b; + return brightness/14; +} + +/** +** Calculate brightness upon a given RGB color value +** ( UNUSED, move to video.c? ) +** +** @param alpha Brightness value +** @param r Color Red-value. +** @param g Color Green-value. +** @param b Color Blue-value. +*/ +static unsigned char ScaleRGB( unsigned char alpha, + unsigned char *r, + unsigned char *g, + unsigned char *b ) +{ + unsigned long int f; + + f = (*r * alpha * 3) >> 8; // could overflow with 0b10 + if ( f & 0xFF00 ) + f = 0xFF; + *r = f; + f = (*g * alpha * 10) >> 8; // could overflow with 0b101 + if ( f & 0xFF00 ) + f = 0xFF; + *g = f; + f = (*b * alpha) >> 8; + *b = f; +} + +/** +** Calculate intensity 0..15 from a given RGB color value +** FIXME: will not work, improve and move to video.c? +** +** @param r Color Red-value in 0..15 +** @param g Color Green-value in 0..15 +** @param b Color Blue-value in 0..15 +*/ +static unsigned char rgb2intensity( unsigned char r, + unsigned char g, + unsigned char b ) +{ + unsigned int i; + i = (r + g + b) / 3; + return i; +} + +/** +** Convert IRGB to unsigned long RGB (for further calculation) +** ( UNUSED, move to video.c? ) +** +** @param r Color Red-value. +** +** |IIRR|GGBB| --> |0000|0000|RRRR|0000|00GG|GG00|0000|BBBB| +*/ +static unsigned long irgb2rgb( unsigned char irgb ) +{ + unsigned long f; + + f=(((irgb<<16)|(irgb<<8)|irgb)&0x00300C03)*(1+(irgb&0xC0)); + return f; +} + +/** +** Convert unsigned long RGB to IRGB +** FIXME: will not work, improve and move to video.c? +** +** @param r Color Red-value. +** +** |0000|0000|RRRR|0000|00GG|GG00|0000|BBBB| --> |IIRR|GGBB| +*/ +static unsigned char rgb2irgb( unsigned long rgb ) +{ + unsigned char i, r, g, b; + + r=(rgb&0x00F00000)>>20; + g=(rgb&0x00003C00)>>10; + b=rgb&0x0000000F; + i=rgb2intensity( r, g, b ); +// r=r%; +// g=g%; +// b=b%; + i=(i<<6)|(r<<4)|(g<<2)|b; + return i; +} + + // =========================================================================== // Pixel // =========================================================================== @@ -668,6 +591,461 @@ local void DrawPixel32(SysColors color,int x,int y) VideoMemory32[x+y*VideoWidth]=Pixels32[color]; } +/** +** Draw 25% translucent pixel unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw25TransPixel8(SysColors color,int x,int y) +{ + VMemType8 *p; + + p = VideoMemory8+x+y*VideoWidth; + *p = lookup25trans8[ (Pixels8[color]<<8) | *p ]; +} + +/** +** Draw 25% translucent pixel unclipped into 15bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw25TransPixel15(SysColors color,int x,int y) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x03E07C1F)*3; + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; +} + +/** +** Draw 25% translucent pixel unclipped into 16bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw25TransPixel16(SysColors color,int x,int y) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x07E0F81F)*3; + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; +} + +/** +** Draw 25% translucent pixel unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw25TransPixel24(SysColors color,int x,int y) +{ +//FIXME: does 24bpp represents R|G|B? + VideoMemory24[x+y*VideoWidth]=Pixels24[color]; +} + +/** +** Draw 25% translucent pixel unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw25TransPixel32(SysColors color,int x,int y) +{ + VMemType32 *p; + unsigned long sp1, sp2, dp1, dp2; + + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=((sp1&0xFF00FF00)>>8)*3; + sp1=(sp1&0x00FF00FF)*3; + + p=VideoMemory32+y*VideoWidth+x; + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); +} + +/** +** Draw 50% translucent pixel unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw50TransPixel8(SysColors color,int x,int y) +{ + VMemType8 *p; + + p = VideoMemory8+x+y*VideoWidth; + *p = lookup50trans8[ (Pixels8[color]<<8) | *p ]; +} + +/** +** Draw 50% translucent pixel unclipped into 15bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw50TransPixel15(SysColors color,int x,int y) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + *p=(dp>>16)|dp; +} + +/** +** Draw 50% translucent pixel unclipped into 16bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw50TransPixel16(SysColors color,int x,int y) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + *p=(dp>>16)|dp; +} + +/** +** Draw 50% translucent pixel unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw50TransPixel24(SysColors color,int x,int y) +{ +//FIXME: does 24bpp represents R|G|B? + VideoMemory24[x+y*VideoWidth]=Pixels24[color]; +} + +/** +** Draw 50% translucent pixel unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw50TransPixel32(SysColors color,int x,int y) +{ + VMemType32 *p; + unsigned long sp1, sp2, dp1, dp2; + + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + p=VideoMemory32+y*VideoWidth+x; + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p=(dp1|(dp2<<8)); +} + +/** +** Draw 75% translucent pixel unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw75TransPixel8(SysColors color,int x,int y) +{ + VMemType8 *p; + + p = VideoMemory8+x+y*VideoWidth; + *p = lookup25trans8[ (*p<<8) | Pixels8[color] ]; +} + +/** +** Draw 75% translucent pixel unclipped into 15bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw75TransPixel15(SysColors color,int x,int y) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; +} + +/** +** Draw 75% translucent pixel unclipped into 16bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw75TransPixel16(SysColors color,int x,int y) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; +} + +/** +** Draw 75% translucent pixel unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw75TransPixel24(SysColors color,int x,int y) +{ +//FIXME: does 24bpp represents R|G|B? + VideoMemory24[x+y*VideoWidth]=Pixels24[color]; +} + +/** +** Draw 75% translucent pixel unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +local void Draw75TransPixel32(SysColors color,int x,int y) +{ + VMemType32 *p; + unsigned long sp1, sp2, dp1, dp2; + + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + p=VideoMemory32+y*VideoWidth+x; + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); +} + +/** +** Draw translucent pixel unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +*/ +local void DrawTransPixel8(SysColors color,int x,int y + ,unsigned char alpha) +{ + VMemType8 *p = VideoMemory8+x+y*VideoWidth; + switch ( ((unsigned int)alpha * 4) / 255 ) + { + case 0: + *p = Pixels8[color]; + break; + case 1: + *p = lookup25trans8[ (Pixels8[color]<<8) | *p ]; + break; + case 2: + *p = lookup50trans8[ (*p<<8) | Pixels8[color] ]; + break; + case 3: + *p = lookup25trans8[ (*p<<8) | Pixels8[color] ]; + break; + default: + break; + } +} + +/** +** Draw pixel unclipped into 8bit framebuffer (ignoring alpha). +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +*/ +local void DrawNoTransPixel8(SysColors color,int x,int y + ,unsigned char alpha) +{ + DrawPixel8(color,x,y); +} + +/** +** Draw translucent pixel unclipped into 15bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +** +** For 15bit |-RRRRRGGGGGBBBBB|, we need for each 5bit offically: +** (5bit - 5bit) * 8bit alpha = 14bit signed int +** +** But Lutz has a smarter way, all in one unsigned 32bit: +** color = |------GGGGG-----RRRRR------BBBBB| +** c1 - c2 = |-SSSSSGGGGGSSSSSRRRRR-SSSSSBBBBB| +** * alpha = |-GGGGGGGGGGSRRRRRRRRR-SBBBBBBBBB| +** newcolor = |------GGGGG-----RRRRR------BBBBB| +*/ +local void DrawTransPixel15(SysColors color,int x,int y + ,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + alpha>>=3; //FIXME: only 5bits available between colors + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; //FIXME: alpha==256 unreached + *p=(dp>>16)|dp; +} + +/** +** Draw translucent pixel unclipped into 16bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +** +** For 16bit |RRRRRGGGGGGBBBBB|, we need offically: +** (5bit - 5bit) * 8bit alpha = 14bit signed int +** (6bit - 6bit) * 8bit alpha = 15bit signed int +** +** But Lutz has a smarter way, all in one unsigned 32bit: +** color = |-----GGGGGG-----RRRRR------BBBBB| +** c1 - c2 = |SSSSSGGGGGGSSSSSRRRRRSSSSSSBBBBB| +** * alpha = |SGGGGGGGGGGSRRRRRRRRRSBBBBBBBBBB| +** newcolor = |-----GGGGGG-----RRRRR------BBBBB| +*/ +local void DrawTransPixel16(SysColors color,int x,int y + ,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp,dp; + p=VideoMemory16+x+y*VideoWidth; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + alpha>>=3; //FIXME: only 5bits available between colors + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; //FIXME: alpha==256 unreached + *p=(dp>>16)|dp; +} + +/** +** Draw translucent pixel unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +*/ +local void DrawTransPixel24(SysColors color,int x,int y + ,unsigned char alpha) +{ +//FIXME: does 24bpp represents R|G|B? + VideoMemory24[x+y*VideoWidth]=Pixels24[color]; +} + +/** +** Draw translucent pixel unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +** +** For 32bit |AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB|, we need offically: +** (8bit - 8bit) * 8bit alpha = 17bit signed int +** +** a smarter way, all in two unsigned 32bit: +** color(1) = |--------RRRRRRRR--------BBBBBBBB| +** c1(1)-c2(1) = |SSSSSSSSRRRRRRRRSSSSSSSSBBBBBBBB| +** * alpha = |SRRRRRRRRRRRRRRRSBBBBBBBBBBBBBBB| +** newcolor(1) = |--------RRRRRRRR--------BBBBBBBB| +** +** color(2) = |--------AAAAAAAA--------GGGGGGGG| +** c1(2)-c2(2) = |SSSSSSSSAAAAAAAASSSSSSSSGGGGGGGG| +** * alpha = |SAAAAAAAAAAAAAAASGGGGGGGGGGGGGGG| +** newcolor(2) = |--------AAAAAAAA--------GGGGGGGG| +** +** FIXME: alpha blending the A-value of 32bit may not be needed.. always 0 +*/ +local void DrawTransPixel32(SysColors color,int x,int y + ,unsigned char alpha) +{ + VMemType32 *p; + unsigned long sp1, sp2, dp1, dp2; + + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + p=VideoMemory32+y*VideoWidth+x; + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + //FIXME: alpha==256 unreached + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); +} + /** ** Draw pixel clipped to current clip setting into 8bit framebuffer. ** @@ -678,7 +1056,7 @@ local void DrawPixel32(SysColors color,int x,int y) local void DrawPixelClip8(SysColors color,int x,int y) { // Clipping: - if( x<ClipX1 || x>=ClipX2 || y<ClipY1 || y>=ClipY2 ) { + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { return; } VideoMemory8[x+y*VideoWidth]=Pixels8[color]; @@ -694,7 +1072,7 @@ local void DrawPixelClip8(SysColors color,int x,int y) local void DrawPixelClip16(SysColors color,int x,int y) { // Clipping: - if( x<ClipX1 || x>=ClipX2 || y<ClipY1 || y>=ClipY2 ) { + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { return; } VideoMemory16[x+y*VideoWidth]=Pixels16[color]; @@ -710,7 +1088,7 @@ local void DrawPixelClip16(SysColors color,int x,int y) local void DrawPixelClip24(SysColors color,int x,int y) { // Clipping: - if( x<ClipX1 || x>=ClipX2 || y<ClipY1 || y>=ClipY2 ) { + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { return; } VideoMemory24[x+y*VideoWidth]=Pixels24[color]; @@ -726,12 +1104,82 @@ local void DrawPixelClip24(SysColors color,int x,int y) local void DrawPixelClip32(SysColors color,int x,int y) { // Clipping: - if( x<ClipX1 || x>=ClipX2 || y<ClipY1 || y>=ClipY2 ) { + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { return; } VideoMemory32[x+y*VideoWidth]=Pixels32[color]; } +/** +** Draw 25% translucent pixel clipped to current clip setting. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +global void VideoDraw25TransPixelClip(SysColors color,int x,int y) +{ + // Clipping: + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { + return; + } + VideoDraw25TransPixel(color,x,y); +} + +/** +** Draw 50% translucent pixel clipped to current clip setting. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +global void VideoDraw50TransPixelClip(SysColors color,int x,int y) +{ + // Clipping: + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { + return; + } + VideoDraw50TransPixel(color,x,y); +} + +/** +** Draw 75% translucent pixel clipped to current clip setting. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +*/ +global void VideoDraw75TransPixelClip(SysColors color,int x,int y) +{ + // Clipping: + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { + return; + } + VideoDraw75TransPixel(color,x,y); +} + +/** +** Draw translucent pixel clipped to current clip setting. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixels. +*/ +global void VideoDrawTransPixelClip(SysColors color,int x,int y + ,unsigned char alpha) +{ + // Clipping: + if( x<ClipX1 || x>ClipX2 || y<ClipY1 || y>ClipY2 ) { + return; + } + VideoDrawTransPixel(color,x,y,alpha); +} + +// =========================================================================== +// Horizontal Line +// =========================================================================== + /** ** Draw horizontal line unclipped into 8bit framebuffer. ** @@ -757,17 +1205,13 @@ local void DrawHLine8(SysColors color,int x,int y,unsigned width) } } -// =========================================================================== -// Horizontal Line -// =========================================================================== - /** ** Draw horizontal line unclipped into 16bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void DrawHLine16(SysColors color,int x,int y,unsigned width) { @@ -796,7 +1240,7 @@ local void DrawHLine16(SysColors color,int x,int y,unsigned width) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void DrawHLine24(SysColors color,int x,int y,unsigned width) { @@ -821,7 +1265,7 @@ local void DrawHLine24(SysColors color,int x,int y,unsigned width) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void DrawHLine32(SysColors color,int x,int y,unsigned width) { @@ -840,13 +1284,35 @@ local void DrawHLine32(SysColors color,int x,int y,unsigned width) } } +/** +** Draw 25% translucent horizontal line unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw25TransHLine8(SysColors color,int x,int y,unsigned width) +{ + VMemType8 *p, *e; + unsigned int c; + + p=VideoMemory8+x+y*VideoWidth; + e=p+width; + c=Pixels8[color]<<8; + + while( p<e ) { + *p++ = lookup25trans8[ c | *p ]; + } +} + /** ** Draw 25% translucent horizontal line unclipped into 15bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void Draw25TransHLine15(SysColors color,int x,int y,unsigned width) { @@ -859,10 +1325,11 @@ local void Draw25TransHLine15(SysColors color,int x,int y,unsigned width) p=VideoMemory16+y*w+x; e=p+width; sp=Pixels16[color]; + // FIXME: pre multiply? sp=(((sp<<16)|sp)&0x03E07C1F)*3; while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x03E07C1F; @@ -877,7 +1344,7 @@ local void Draw25TransHLine15(SysColors color,int x,int y,unsigned width) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void Draw25TransHLine16(SysColors color,int x,int y,unsigned width) { @@ -890,25 +1357,97 @@ local void Draw25TransHLine16(SysColors color,int x,int y,unsigned width) p=VideoMemory16+y*w+x; e=p+width; sp=Pixels16[color]; + // FIXME: pre multiply? sp=(((sp<<16)|sp)&0x07E0F81F)*3; while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x07E0F81F; - dp=((dp+sp)>>1)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; *p++=(dp>>16)|dp; } } +/** +** Draw 25% translucent horizontal line unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw25TransHLine24(SysColors color,int x,int y,unsigned width) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawHLine24(color,x,y,width); // no trans functionaility for the moment :( +} + +/** +** Draw 25% translucent horizontal line unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw25TransHLine32(SysColors color,int x,int y,unsigned width) +{ + VMemType32 *p, *e; + unsigned long sp1, sp2; + int w; + + w=VideoWidth; + p=VideoMemory32+y*w+x; + e=p+width; + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=((sp1&0xFF00FF00)>>8)*3; + sp1=(sp1&0x00FF00FF)*3; + + while( p<e ) { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } +} + +/** +** Draw 50% translucent horizontal line unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw50TransHLine8(SysColors color,int x,int y,unsigned width) +{ + VMemType8 *p, *e; + unsigned int c; + + p=VideoMemory8+x+y*VideoWidth; + e=p+width; + c=Pixels8[color]<<8; + + while( p<e ) { + *p++ = lookup50trans8[ c | *p ]; + } +} + /** ** Draw 50% translucent horizontal line unclipped into 15bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void Draw50TransHLine15(SysColors color,int x,int y,unsigned width) { @@ -924,7 +1463,7 @@ local void Draw50TransHLine15(SysColors color,int x,int y,unsigned width) sp=((sp<<16)|sp)&0x03E07C1F; while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x03E07C1F; @@ -939,7 +1478,7 @@ local void Draw50TransHLine15(SysColors color,int x,int y,unsigned width) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void Draw50TransHLine16(SysColors color,int x,int y,unsigned width) { @@ -955,7 +1494,7 @@ local void Draw50TransHLine16(SysColors color,int x,int y,unsigned width) sp=((sp<<16)|sp)&0x07E0F81F; while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x07E0F81F; @@ -964,13 +1503,83 @@ local void Draw50TransHLine16(SysColors color,int x,int y,unsigned width) } } +/** +** Draw 50% translucent horizontal line unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw50TransHLine24(SysColors color,int x,int y,unsigned width) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawHLine24(color,x,y,width); // no trans functionaility for the moment :( +} + +/** +** Draw 50% translucent horizontal line unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw50TransHLine32(SysColors color,int x,int y,unsigned width) +{ + VMemType32 *p, *e; + unsigned long sp1, sp2; + int w; + + w=VideoWidth; + p=VideoMemory32+y*w+x; + e=p+width; + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + while( p<e ) { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } +} + +/** +** Draw 75% translucent horizontal line unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw75TransHLine8(SysColors color,int x,int y,unsigned width) +{ + VMemType8 *p, *e; + unsigned int c; + + p=VideoMemory8+x+y*VideoWidth; + e=p+width; + c=Pixels8[color]; + + while( p<e ) { + *p++ = lookup25trans8[ (*p<<8) | c ]; + } +} + /** ** Draw 75% translucent horizontal line unclipped into 15bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void Draw75TransHLine15(SysColors color,int x,int y,unsigned width) { @@ -986,7 +1595,7 @@ local void Draw75TransHLine15(SysColors color,int x,int y,unsigned width) sp=((sp<<16)|sp)&0x03E07C1F; while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x03E07C1F; @@ -1001,7 +1610,7 @@ local void Draw75TransHLine15(SysColors color,int x,int y,unsigned width) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ local void Draw75TransHLine16(SysColors color,int x,int y,unsigned width) { @@ -1017,7 +1626,7 @@ local void Draw75TransHLine16(SysColors color,int x,int y,unsigned width) sp=((sp<<16)|sp)&0x07E0F81F; while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x07E0F81F; @@ -1026,37 +1635,144 @@ local void Draw75TransHLine16(SysColors color,int x,int y,unsigned width) } } +/** +** Draw 75% translucent horizontal line unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw75TransHLine24(SysColors color,int x,int y,unsigned width) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawHLine24(color,x,y,width); // no trans functionaility for the moment :( +} + +/** +** Draw 75% translucent horizontal line unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +*/ +local void Draw75TransHLine32(SysColors color,int x,int y,unsigned width) +{ + VMemType32 *p, *e; + unsigned long sp1, sp2; + int w; + + w=VideoWidth; + p=VideoMemory32+y*w+x; + e=p+width; + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + while( p<e ) { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } +} + +/** +** Draw translucent horizontal line unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param width width of line (0=don't draw). +** @param alpha alpha value of pixels. +*/ +local void DrawTransHLine8(SysColors color,int x,int y,unsigned width + ,unsigned char alpha) +{ + VMemType8 *p, *e; + unsigned int c; + + p=VideoMemory8+x+y*VideoWidth; + e=p+width; + c=Pixels8[color]; + + switch ( ((unsigned int)alpha * 4) / 255 ) + { + case 0: + while( p<e ) { + *p++ = c; + } + break; + case 1: + while( p<e ) { + *p++ = lookup25trans8[ (*p<<8) | c ]; + } + break; + case 2: + c<<=8; + while( p<e ) { + *p++ = lookup50trans8[ c | *p ]; + } + break; + case 3: + c<<=8; + while( p<e ) { + *p++ = lookup25trans8[ c | *p ]; + } + break; + default: + break; + } +} + +/** +** Draw horizontal line unclipped into 8bit framebuffer (ignoring alpha). +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +*/ +local void DrawNoTransHLine8(SysColors color,int x,int y,unsigned width + ,unsigned char alpha) +{ + DrawHLine8(color,x,y,width); +} + /** ** Draw translucent horizontal line unclipped into 15bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). ** @param alpha alpha value of pixels. */ local void DrawTransHLine15(SysColors color,int x,int y,unsigned width - ,int alpha) + ,unsigned char alpha) { - VMemType16* p; - VMemType16* e; - int w; + VMemType16 *p, *e; unsigned long sp; - w=VideoWidth; - p=VideoMemory16+y*w+x; + p=VideoMemory16+y*VideoWidth+x; e=p+width; sp=Pixels16[color]; // FIXME: pre multiply? sp=((sp<<16)|sp)&0x03E07C1F; - alpha>>=3; // only 5bits + alpha>>=3; // FIXME: only 5bits while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x03E07C1F; - dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; //FIXME: alpha==256 unreached *p++=(dp>>16)|dp; } } @@ -1067,363 +1783,205 @@ local void DrawTransHLine15(SysColors color,int x,int y,unsigned width ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). ** @param alpha alpha value of pixels. */ local void DrawTransHLine16(SysColors color,int x,int y,unsigned width - ,int alpha) + ,unsigned char alpha) { - VMemType16* p; - VMemType16* e; - int w; + VMemType16 *p, *e; unsigned long sp; - w=VideoWidth; - p=VideoMemory16+y*w+x; + p=VideoMemory16+y*VideoWidth+x; e=p+width; sp=Pixels16[color]; // FIXME: pre multiply? sp=((sp<<16)|sp)&0x07E0F81F; - alpha>>=3; // only 5bits + alpha>>=3; // FIXME: only 5bits while( p<e ) { - unsigned dp; + unsigned long dp; dp=*p; dp=((dp<<16)|dp)&0x07E0F81F; - dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; //FIXME: alpha==256 unreached *p++=(dp>>16)|dp; } } /** -** Draw horizontal line clipped into 8bit framebuffer. +** Draw translucent horizontal line unclipped into 24bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). +** @param alpha alpha value of pixels. */ -local void DrawHLineClip8(SysColors color,int x,int y,unsigned width) +local void DrawTransHLine24(SysColors color,int x,int y,unsigned width + ,unsigned char alpha) { - int f; + VMemType24 c, *p, *e; + unsigned int spR, spG, spB; - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } + p=VideoMemory24+y*VideoWidth+x; + e=p+width; + c=Pixels24[color]; + spR=c.a; + spG=c.b; + spB=c.c; + // FIXME: untested; does 24bpp holds R|G|B ? + //FIXME: alpha==256 unreached - DrawHLine8(color,x,y,width); + while( p<e ) { + unsigned int i; + + c=*p; + + i=c.a; + i=((i-spR)*alpha)>>8+spR; + c.a=i&0xFF; + + i=c.b; + i=((i-spG)*alpha)>>8+spG; + c.b=i&0xFF; + + i=c.c; + i=((i-spB)*alpha)>>8+spB; + c.c=i&0xFF; + + *p++=c; + } } /** -** Draw horizontal line clipped into 16bit framebuffer. +** Draw translucent horizontal line unclipped into 32bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). +** @param alpha alpha value of pixels. */ -local void DrawHLineClip16(SysColors color,int x,int y,unsigned width) +local void DrawTransHLine32(SysColors color,int x,int y,unsigned width + ,unsigned char alpha) { - int f; + VMemType32 *p, *e; + unsigned long sp1, sp2; - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } + p=VideoMemory32+y*VideoWidth+x; + e=p+width; + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; - DrawHLine16(color,x,y,width); + alpha>>=1; + + while( p<e ) { + unsigned long dp1,dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + //FIXME: alpha==256 unreached + dp1=((((dp1-sp1)*alpha)>>7)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>7)+sp2)&0x00FF00FF; + + *p++=(dp1|(dp2<<8)); + } +} + +#define CLIP_HLINE(x,y,width) { \ + if( y<ClipY1 || y>ClipY2 ) { \ + return; \ + } \ + if( x<ClipX1 ) { \ + int f=ClipX1-x; \ + if( width<=f ) { \ + return; \ + } \ + width-=f; \ + x=ClipX1; \ + } \ + if( (x+width)>ClipX2+1 ) { \ + if( x>ClipX2 ) { \ + return; \ + } \ + width=ClipX2-x+1; \ + } \ } /** -** Draw horizontal line clipped into 24bit framebuffer. +** Draw horizontal line clipped. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ -local void DrawHLineClip24(SysColors color,int x,int y,unsigned width) +global void VideoDrawHLineClip(SysColors color,int x,int y,unsigned width) { - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - DrawHLine24(color,x,y,width); + CLIP_HLINE(x,y,width); + VideoDrawHLine(color,x,y,width); } /** -** Draw horizontal line clipped into 32bit framebuffer. +** Draw 25% translucent horizontal line clipped. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ -local void DrawHLineClip32(SysColors color,int x,int y,unsigned width) +global void VideoDraw25TransHLineClip(SysColors color,int x,int y,unsigned width) { - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - DrawHLine32(color,x,y,width); + CLIP_HLINE(x,y,width); + VideoDraw25TransHLine(color,x,y,width); } /** -** Draw 25% translucent horizontal line clipped into 15bit framebuffer. +** Draw 50% translucent horizontal line clipped. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ -local void Draw25TransHLineClip15(SysColors color,int x,int y,unsigned width) +global void VideoDraw50TransHLineClip(SysColors color,int x,int y,unsigned width) { - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - Draw25TransHLine15(color,x,y,width); + CLIP_HLINE(x,y,width); + VideoDraw50TransHLine(color,x,y,width); } /** -** Draw 25% translucent horizontal line clipped into 16bit framebuffer. +** Draw 75% translucent horizontal line clipped. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param width width of line. +** @param width width of line (0=don't draw). */ -local void Draw25TransHLineClip16(SysColors color,int x,int y,unsigned width) +global void VideoDraw75TransHLineClip(SysColors color,int x,int y,unsigned width) { - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - Draw25TransHLine16(color,x,y,width); + CLIP_HLINE(x,y,width); + VideoDraw75TransHLine(color,x,y,width); } /** -** Draw 50% translucent horizontal line clipped into 15bit framebuffer. +** Draw translucent horizontal line clipped. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen ** @param width width of line. +** @param alpha alpha value of pixels. */ -local void Draw50TransHLineClip15(SysColors color,int x,int y,unsigned width) +global void VideoDrawTransHLineClip(SysColors color,int x,int y,unsigned width + ,unsigned char alpha) { - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - Draw50TransHLine15(color,x,y,width); -} - -/** -** Draw 50% translucent horizontal line clipped into 16bit framebuffer. -** -** @param color Color index. -** @param x x coordinate on the screen -** @param y y coordinate on the screen -** @param width width of line. -*/ -local void Draw50TransHLineClip16(SysColors color,int x,int y,unsigned width) -{ - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - Draw50TransHLine16(color,x,y,width); -} - -/** -** Draw 75% translucent horizontal line clipped into 15bit framebuffer. -** -** @param color Color index. -** @param x x coordinate on the screen -** @param y y coordinate on the screen -** @param width width of line. -*/ -local void Draw75TransHLineClip15(SysColors color,int x,int y,unsigned width) -{ - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - Draw75TransHLine15(color,x,y,width); -} - -/** -** Draw 75% translucent horizontal line clipped into 16bit framebuffer. -** -** @param color Color index. -** @param x x coordinate on the screen -** @param y y coordinate on the screen -** @param width width of line. -*/ -local void Draw75TransHLineClip16(SysColors color,int x,int y,unsigned width) -{ - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - Draw75TransHLine16(color,x,y,width); + CLIP_HLINE(x,y,width); + VideoDrawTransHLine(color,x,y,width,alpha); } // =========================================================================== @@ -1436,7 +1994,7 @@ local void Draw75TransHLineClip16(SysColors color,int x,int y,unsigned width) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ local void DrawVLine8(SysColors color,int x,int y,unsigned height) { @@ -1461,7 +2019,7 @@ local void DrawVLine8(SysColors color,int x,int y,unsigned height) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ local void DrawVLine16(SysColors color,int x,int y,unsigned height) { @@ -1486,7 +2044,7 @@ local void DrawVLine16(SysColors color,int x,int y,unsigned height) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ local void DrawVLine24(SysColors color,int x,int y,unsigned height) { @@ -1511,7 +2069,7 @@ local void DrawVLine24(SysColors color,int x,int y,unsigned height) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ local void DrawVLine32(SysColors color,int x,int y,unsigned height) { @@ -1531,186 +2089,687 @@ local void DrawVLine32(SysColors color,int x,int y,unsigned height) } /** -** Draw vertical line clipped into 8bit framebuffer. +** Draw 25% translucent vertical line unclipped into 8bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ -local void DrawVLineClip8(SysColors color,int x,int y,unsigned height) +local void Draw25TransVLine8(SysColors color,int x,int y,unsigned height) { - VMemType8* p; - VMemType8* e; - int w; - int f; + VMemType8 *p; + unsigned int c, w; - // Clipping: - if( x<ClipX1 || x>=ClipX2 ) { - return; - } - if( y<ClipY1 ) { - f=ClipY1-y; - y=ClipY1; - if( height<f ) { - return; - } - height-=f; - } - if( (y+height)>ClipY2 ) { - if( height<ClipY2-y ) { - return; - } - height=ClipY2-y; - } - - w=VideoWidth; - p=VideoMemory8+y*w+x; - e=p+height*w; - f=Pixels8[color]; - while( p<e ) { - *p=f; - p+=w; + w = VideoWidth; + p = VideoMemory8+x+y*w; + c = Pixels8[color]<<8; + while( height-- ) { + *p = lookup25trans8[ c | *p ]; + p+=w; } } /** -** Draw vertical line clipped into 16bit framebuffer. +** Draw 25% translucent vertical line unclipped into 15bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ -local void DrawVLineClip16(SysColors color,int x,int y,unsigned height) +local void Draw25TransVLine15(SysColors color,int x,int y,unsigned height) { - VMemType16* p; - VMemType16* e; - int w; - int f; - - // Clipping: - if( x<ClipX1 || x>=ClipX2 ) { - return; - } - if( y<ClipY1 ) { - f=ClipY1-y; - y=ClipY1; - if( height<f ) { - return; - } - height-=f; - } - if( (y+height)>ClipY2 ) { - if( height<ClipY2-y ) { - return; - } - height=ClipY2-y; - } - if( height>640 ) - abort(); + VMemType16 *p; + unsigned long sp; + unsigned int w; w=VideoWidth; p=VideoMemory16+y*w+x; - e=p+height*w; - f=Pixels16[color]; - while( p<e ) { - *p=f; - p+=w; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x03E07C1F)*3; + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; + p+=w; } } /** -** Draw vertical line clipped into 24bit framebuffer. +** Draw 25% translucent vertical line unclipped into 16bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ -local void DrawVLineClip24(SysColors color,int x,int y,unsigned height) +local void Draw25TransVLine16(SysColors color,int x,int y,unsigned height) { - VMemType24* p; - VMemType24* e; - int w; - int t; - VMemType24 f; - - // Clipping: - if( x<ClipX1 || x>=ClipX2 ) { - return; - } - if( y<ClipY1 ) { - t=ClipY1-y; - y=ClipY1; - if( height<t ) { - return; - } - height-=t; - } - if( (y+height)>ClipY2 ) { - if( height<ClipY2-y ) { - return; - } - height=ClipY2-y; - } - if( height>640 ) - abort(); + VMemType16 *p; + unsigned long sp; + unsigned int w; w=VideoWidth; - p=VideoMemory24+y*w+x; - e=p+height*w; - f=Pixels24[color]; - while( p<e ) { - *p=f; - p+=w; + p=VideoMemory16+y*w+x; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x07E0F81F)*3; + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; + p+=w; } } /** -** Draw vertical line clipped into 32bit framebuffer. +** Draw 25% translucent vertical line unclipped into 24bit framebuffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param height height of line. +** @param height height of line (0=don't draw). */ -local void DrawVLineClip32(SysColors color,int x,int y,unsigned height) +local void Draw25TransVLine24(SysColors color,int x,int y,unsigned height) { - VMemType32* p; - VMemType32* e; - int w; - int f; + // FIXME: does 24bpp holds R|G|B ? + DrawVLine24(color,x,y,height); // no trans functionaility for the moment :( +} - // Clipping: - if( x<ClipX1 || x>=ClipX2 ) { - return; - } - if( y<ClipY1 ) { - f=ClipY1-y; - y=ClipY1; - if( height<f ) { - return; - } - height-=f; - } - if( (y+height)>ClipY2 ) { - if( height<ClipY2-y ) { - return; - } - height=ClipY2-y; - } +/** +** Draw 25% translucent vertical line unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw25TransVLine32(SysColors color,int x,int y,unsigned height) +{ + VMemType32 *p; + unsigned long sp1,sp2; + unsigned int w; w=VideoWidth; p=VideoMemory32+y*w+x; - e=p+height*w; - f=Pixels32[color]; - while( p<e ) { - *p=f; - p+=w; + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=((sp1&0xFF00FF00)>>8)*3; + sp1=(sp1&0x00FF00FF)*3; + + while( height-- ) { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=w; } } +/** +** Draw 50% translucent vertical line unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw50TransVLine8(SysColors color,int x,int y,unsigned height) +{ + VMemType8 *p; + unsigned int c, w; + + w = VideoWidth; + p = VideoMemory8+x+y*w; + c = Pixels8[color]<<8; + while( height-- ) { + *p = lookup50trans8[ c | *p ]; + p+=w; + } +} + +/** +** Draw 50% translucent vertical line unclipped into 15bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw50TransVLine15(SysColors color,int x,int y,unsigned height) +{ + VMemType16 *p; + unsigned long sp; + unsigned int w; + + w=VideoWidth; + p=VideoMemory16+y*w+x; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + *p=(dp>>16)|dp; + p+=w; + } +} + +/** +** Draw 50% translucent vertical line unclipped into 16bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw50TransVLine16(SysColors color,int x,int y,unsigned height) +{ + VMemType16 *p; + unsigned long sp; + unsigned int w; + + w=VideoWidth; + p=VideoMemory16+y*w+x; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=((sp<<16)|sp)&0x07E0F81F; + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + *p=(dp>>16)|dp; + p+=w; + } +} + +/** +** Draw 50% translucent vertical line unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw50TransVLine24(SysColors color,int x,int y,unsigned height) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawVLine24(color,x,y,height); // no trans functionaility for the moment :( +} + +/** +** Draw 50% translucent vertical line unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw50TransVLine32(SysColors color,int x,int y,unsigned height) +{ + VMemType32 *p; + unsigned long sp1,sp2; + unsigned int w; + + w=VideoWidth; + p=VideoMemory32+y*w+x; + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + while( height-- ) { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=w; + } +} + +/** +** Draw 75% translucent vertical line unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw75TransVLine8(SysColors color,int x,int y,unsigned height) +{ + VMemType8 *p; + unsigned int c, w; + + w = VideoWidth; + p = VideoMemory8+x+y*w; + c = Pixels8[color]; + while( height-- ) { + *p = lookup25trans8[ (*p<<8) | c ]; + p+=w; + } +} + +/** +** Draw 75% translucent vertical line unclipped into 15bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw75TransVLine15(SysColors color,int x,int y,unsigned height) +{ + VMemType16 *p; + unsigned long sp; + unsigned int w; + + w=VideoWidth; + p=VideoMemory16+y*w+x; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=((sp<<16)|sp)&0x03E07C1F; + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; + p+=w; + } +} + +/** +** Draw 75% translucent vertical line unclipped into 16bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw75TransVLine16(SysColors color,int x,int y,unsigned height) +{ + VMemType16 *p; + unsigned long sp; + unsigned int w; + + w=VideoWidth; + p=VideoMemory16+y*w+x; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=((sp<<16)|sp)&0x07E0F81F; + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; + p+=w; + } +} + +/** +** Draw 75% translucent vertical line unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw75TransVLine24(SysColors color,int x,int y,unsigned height) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawVLine24(color,x,y,height); // no trans functionaility for the moment :( +} + +/** +** Draw 75% translucent vertical line unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +local void Draw75TransVLine32(SysColors color,int x,int y,unsigned height) +{ + VMemType32 *p; + unsigned long sp1,sp2; + unsigned int w; + + w=VideoWidth; + p=VideoMemory32+y*w+x; + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + while( height-- ) { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=w; + } +} + +/** +** Draw translucent vertical line unclipped into 8bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +** @param alpha alpha value of pixels. +*/ +local void DrawTransVLine8(SysColors color,int x,int y,unsigned height + ,unsigned char alpha) +{ + VMemType8 *p; + unsigned int c, w; + + w = VideoWidth; + p = VideoMemory8+x+y*w; + c = Pixels8[color]; + + switch ( ((unsigned int)alpha * 4) / 255 ) + { + case 0: + while( height-- ) { + *p = c; + p+=w; + } + break; + case 1: + while( height-- ) { + *p = lookup25trans8[ (*p<<8) | c ]; + p+=w; + } + break; + case 2: + c<<=8; + while( height-- ) { + *p = lookup50trans8[ c | *p ]; + p+=w; + } + break; + case 3: + c<<=8; + while( height-- ) { + *p = lookup25trans8[ c | *p ]; + p+=w; + } + break; + default: + break; + } +} + +/** +** Draw vertical line unclipped into 8bit framebuffer (ignoring alpha). +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +*/ +local void DrawNoTransVLine8(SysColors color,int x,int y,unsigned height + ,unsigned char alpha) +{ + DrawVLine8(color,x,y,height); +} + +/** +** Draw translucent vertical line unclipped into 15bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +** @param alpha alpha value of pixels. +*/ +local void DrawTransVLine15(SysColors color,int x,int y,unsigned height + ,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp; + unsigned int w; + + w=VideoWidth; + p=VideoMemory16+y*w+x; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=((sp<<16)|sp)&0x03E07C1F; + alpha>>=3; // FIXME: only 5bits + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; //FIXME: alpha==256 unreached + *p=(dp>>16)|dp; + p+=w; + } +} + +/** +** Draw translucent vertical line unclipped into 16bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +** @param alpha alpha value of pixels. +*/ +local void DrawTransVLine16(SysColors color,int x,int y,unsigned height + ,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp; + unsigned int w; + + w=VideoWidth; + p=VideoMemory16+y*w+x; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=((sp<<16)|sp)&0x07E0F81F; + alpha>>=3; // FIXME: only 5bits + + while( height-- ) { + unsigned long dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; //FIXME: alpha==256 unreached + *p=(dp>>16)|dp; + p+=w; + } +} + +/** +** Draw translucent vertical line unclipped into 24bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +** @param alpha alpha value of pixels. +*/ +local void DrawTransVLine24(SysColors color,int x,int y,unsigned height + ,unsigned char alpha) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawVLine24(color,x,y,height); // no trans functionaility for the moment :( +} + +/** +** Draw translucent vertical line unclipped into 32bit framebuffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +** @param alpha alpha value of pixels. +*/ +local void DrawTransVLine32(SysColors color,int x,int y,unsigned height + ,unsigned char alpha) +{ + VMemType32 *p; + unsigned long sp1,sp2; + unsigned int w; + + w=VideoWidth; + p=VideoMemory32+y*w+x; + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + while( height-- ) { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + //FIXME: alpha==256 unreached + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=w; + } +} + +#define CLIP_VLINE(x,y,width) { \ + if( x<ClipX1 || x>ClipX2 ) { \ + return; \ + } \ + if( y<ClipY1 ) { \ + int f=ClipY1-y; \ + if( height<=f ) { \ + return; \ + } \ + height-=f; \ + y=ClipY1; \ + } \ + if( (y+height)>ClipY2+1 ) { \ + if( y>ClipY2 ) { \ + return; \ + } \ + height=ClipY2-y+1; \ + } \ +} + +/** +** Draw vertical line clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +global void VideoDrawVLineClip(SysColors color,int x,int y,unsigned height) +{ + CLIP_VLINE(x,y,height); + VideoDrawVLine(color,x,y,height); +} + +/** +** Draw 25% translucent vertical line clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +global void VideoDraw25TransVLineClip(SysColors color,int x,int y, + unsigned height) +{ + CLIP_VLINE(x,y,height); + VideoDraw25TransVLine(color,x,y,height); +} + +/** +** Draw 50% translucent vertical line clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +global void VideoDraw50TransVLineClip(SysColors color,int x,int y, + unsigned height) +{ + CLIP_VLINE(x,y,height); + VideoDraw50TransVLine(color,x,y,height); +} + +/** +** Draw 75% translucent vertical line clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +*/ +global void VideoDraw75TransVLineClip(SysColors color,int x,int y, + unsigned height) +{ + CLIP_VLINE(x,y,height); + VideoDraw75TransVLine(color,x,y,height); +} + +/** +** Draw translucent vertical line clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param height height of line (0=don't draw). +** @param alpha alpha value of pixels. +*/ +global void VideoDrawTransVLineClip(SysColors color,int x,int y, + unsigned height,unsigned char alpha) +{ + CLIP_VLINE(x,y,height); + VideoDrawTransVLine(color,x,y,height,alpha); +} + // =========================================================================== // General Line // =========================================================================== @@ -1724,7 +2783,7 @@ local void DrawVLineClip32(SysColors color,int x,int y,unsigned height) ** @param x2 Destination x coordinate on the screen ** @param y2 Destination y coordinate on the screen */ -global void DrawLine8(SysColors color,int x1,int y1,int x2,int y2) +local void DrawLine8(SysColors color,int x1,int y1,int x2,int y2) { int d; int dx; @@ -1736,17 +2795,17 @@ global void DrawLine8(SysColors color,int x1,int y1,int x2,int y2) if( x1==x2 ) { if( y1<y2 ) { - DrawVLine8(color,x1,y1,y2-y1); + DrawVLine8(color,x1,y1,y2-y1+1); } else { - DrawVLine8(color,x2,y2,y1-y2); + DrawVLine8(color,x2,y2,y1-y2+1); } return; } if( y1==y2 ) { if( x1<x2 ) { - DrawHLine8(color,x1,y1,x2-x1); + DrawHLine8(color,x1,y1,x2-x1+1); } else { - DrawHLine8(color,x2,y2,x1-x2); + DrawHLine8(color,x2,y2,x1-x2+1); } return; } @@ -1807,7 +2866,7 @@ global void DrawLine8(SysColors color,int x1,int y1,int x2,int y2) } while( y1!=y2) { // diagonal line - x1+=xstep; + //x1+=xstep; p+=xstep; y1++; p+=w; @@ -1824,7 +2883,7 @@ global void DrawLine8(SysColors color,int x1,int y1,int x2,int y2) ** @param x2 Destination x coordinate on the screen ** @param y2 Destination y coordinate on the screen */ -global void DrawLine16(SysColors color,int x1,int y1,int x2,int y2) +local void DrawLine16(SysColors color,int x1,int y1,int x2,int y2) { int d; int dx; @@ -1836,17 +2895,17 @@ global void DrawLine16(SysColors color,int x1,int y1,int x2,int y2) if( x1==x2 ) { if( y1<y2 ) { - DrawVLine16(color,x1,y1,y2-y1); + DrawVLine16(color,x1,y1,y2-y1+1); } else { - DrawVLine16(color,x2,y2,y1-y2); + DrawVLine16(color,x2,y2,y1-y2+1); } return; } if( y1==y2 ) { if( x1<x2 ) { - DrawHLine16(color,x1,y1,x2-x1); + DrawHLine16(color,x1,y1,x2-x1+1); } else { - DrawHLine16(color,x2,y2,x1-x2); + DrawHLine16(color,x2,y2,x1-x2+1); } return; } @@ -1907,7 +2966,7 @@ global void DrawLine16(SysColors color,int x1,int y1,int x2,int y2) } while( y1!=y2) { // diagonal line - x1+=xstep; + //x1+=xstep; p+=xstep; y1++; p+=w; @@ -1924,7 +2983,7 @@ global void DrawLine16(SysColors color,int x1,int y1,int x2,int y2) ** @param x2 Destination x coordinate on the screen ** @param y2 Destination y coordinate on the screen */ -global void DrawLine24(SysColors color,int x1,int y1,int x2,int y2) +local void DrawLine24(SysColors color,int x1,int y1,int x2,int y2) { int d; int dx; @@ -1936,17 +2995,17 @@ global void DrawLine24(SysColors color,int x1,int y1,int x2,int y2) if( x1==x2 ) { if( y1<y2 ) { - DrawVLine24(color,x1,y1,y2-y1); + DrawVLine24(color,x1,y1,y2-y1+1); } else { - DrawVLine24(color,x2,y2,y1-y2); + DrawVLine24(color,x2,y2,y1-y2+1); } return; } if( y1==y2 ) { if( x1<x2 ) { - DrawHLine24(color,x1,y1,x2-x1); + DrawHLine24(color,x1,y1,x2-x1+1); } else { - DrawHLine24(color,x2,y2,x1-x2); + DrawHLine24(color,x2,y2,x1-x2+1); } return; } @@ -2007,7 +3066,7 @@ global void DrawLine24(SysColors color,int x1,int y1,int x2,int y2) } while( y1!=y2) { // diagonal line - x1+=xstep; + //x1+=xstep; p+=xstep; y1++; p+=w; @@ -2024,7 +3083,7 @@ global void DrawLine24(SysColors color,int x1,int y1,int x2,int y2) ** @param x2 Destination x coordinate on the screen ** @param y2 Destination y coordinate on the screen */ -global void DrawLine32(SysColors color,int x1,int y1,int x2,int y2) +local void DrawLine32(SysColors color,int x1,int y1,int x2,int y2) { int d; int dx; @@ -2036,17 +3095,17 @@ global void DrawLine32(SysColors color,int x1,int y1,int x2,int y2) if( x1==x2 ) { if( y1<y2 ) { - DrawVLine32(color,x1,y1,y2-y1); + DrawVLine32(color,x1,y1,y2-y1+1); } else { - DrawVLine32(color,x2,y2,y1-y2); + DrawVLine32(color,x2,y2,y1-y2+1); } return; } if( y1==y2 ) { if( x1<x2 ) { - DrawHLine32(color,x1,y1,x2-x1); + DrawHLine32(color,x1,y1,x2-x1+1); } else { - DrawHLine32(color,x2,y2,x1-x2); + DrawHLine32(color,x2,y2,x1-x2+1); } return; } @@ -2107,7 +3166,7 @@ global void DrawLine32(SysColors color,int x1,int y1,int x2,int y2) } while( y1!=y2) { // diagonal line - x1+=xstep; + //x1+=xstep; p+=xstep; y1++; p+=w; @@ -2151,7 +3210,7 @@ local int ClipTest(double p,double q,double *u1,double *u2) } /** -** Draw line clipped into 8bit framebuffer. +** Draw line clipped. ** ** @param color Color index. ** @param x1 Source x coordinate on the screen @@ -2159,7 +3218,7 @@ local int ClipTest(double p,double q,double *u1,double *u2) ** @param x2 Destination x coordinate on the screen ** @param y2 Destination y coordinate on the screen */ -global void DrawLineClip8(SysColors color,int x1,int y1,int x2,int y2) +global void VideoDrawLineClip(SysColors color,int x1,int y1,int x2,int y2) { double u1; double u2; @@ -2189,139 +3248,7 @@ global void DrawLineClip8(SysColors color,int x1,int y1,int x2,int y2) x1,y1,x2,y2); return; } - DrawLine8(color,x1,y1,x2,y2); - } - } -} - -/** -** Draw line clipped into 16bit framebuffer. -** -** @param color Color index. -** @param x1 Source x coordinate on the screen -** @param y1 Source y coordinate on the screen -** @param x2 Destination x coordinate on the screen -** @param y2 Destination y coordinate on the screen -*/ -global void DrawLineClip16(SysColors color,int x1,int y1,int x2,int y2) -{ - double u1; - double u2; - int dx; - int dy; - - u1 = 0.0; - u2 = 1.0; - dx = x2-x1; - if (ClipTest(-dx,x1-ClipX1, &u1, &u2) - && ClipTest(dx,ClipX2-x1, &u1, &u2)) { - dy = y2-y1; - if (ClipTest(-dy, y1-ClipY1, &u1, &u2) - && ClipTest(dy,ClipY2-y1, &u1, &u2)) { - if (u1 > 0) { - x1 = (x1 + u1*dx) + 0.5; - y1 = (y1 + u1*dy) + 0.5; - } - if (u2 < 1) { - x2 = (x1 + u2*dx) + 0.5; - y2 = (y1 + u2*dy) + 0.5; - } - - if( x1<0 || x2<0 || x1>VideoWidth || x2>VideoWidth - || y1<0 || y2<0 || y1>VideoHeight || y2>VideoHeight ) { - DebugLevel0Fn("Wrong coordinates %d,%d %d,%d\n", - x1,y1,x2,y2); - return; - } - DrawLine16(color,x1,y1,x2,y2); - } - } -} - -/** -** Draw line clipped into 24bit framebuffer. -** -** @param color Color index. -** @param x1 Source x coordinate on the screen -** @param y1 Source y coordinate on the screen -** @param x2 Destination x coordinate on the screen -** @param y2 Destination y coordinate on the screen -*/ -global void DrawLineClip24(SysColors color,int x1,int y1,int x2,int y2) -{ - double u1; - double u2; - int dx; - int dy; - - u1 = 0.0; - u2 = 1.0; - dx = x2-x1; - if (ClipTest(-dx,x1-ClipX1, &u1, &u2) - && ClipTest(dx,ClipX2-x1, &u1, &u2)) { - dy = y2-y1; - if (ClipTest(-dy, y1-ClipY1, &u1, &u2) - && ClipTest(dy,ClipY2-y1, &u1, &u2)) { - if (u1 > 0) { - x1 = (x1 + u1*dx) + 0.5; - y1 = (y1 + u1*dy) + 0.5; - } - if (u2 < 1) { - x2 = (x1 + u2*dx) + 0.5; - y2 = (y1 + u2*dy) + 0.5; - } - - if( x1<0 || x2<0 || x1>VideoWidth || x2>VideoWidth - || y1<0 || y2<0 || y1>VideoHeight || y2>VideoHeight ) { - DebugLevel0Fn("Wrong coordinates %d,%d %d,%d\n", - x1,y1,x2,y2); - return; - } - DrawLine24(color,x1,y1,x2,y2); - } - } -} - -/** -** Draw line clipped into 32bit framebuffer. -** -** @param color Color index. -** @param x1 Source x coordinate on the screen -** @param y1 Source y coordinate on the screen -** @param x2 Destination x coordinate on the screen -** @param y2 Destination y coordinate on the screen -*/ -global void DrawLineClip32(SysColors color,int x1,int y1,int x2,int y2) -{ - double u1; - double u2; - int dx; - int dy; - - u1 = 0.0; - u2 = 1.0; - dx = x2-x1; - if (ClipTest(-dx,x1-ClipX1, &u1, &u2) - && ClipTest(dx,ClipX2-x1, &u1, &u2)) { - dy = y2-y1; - if (ClipTest(-dy, y1-ClipY1, &u1, &u2) - && ClipTest(dy,ClipY2-y1, &u1, &u2)) { - if (u1 > 0) { - x1 = (x1 + u1*dx) + 0.5; - y1 = (y1 + u1*dy) + 0.5; - } - if (u2 < 1) { - x2 = (x1 + u2*dx) + 0.5; - y2 = (y1 + u2*dy) + 0.5; - } - - if( x1<0 || x2<0 || x1>VideoWidth || x2>VideoWidth - || y1<0 || y2<0 || y1>VideoHeight || y2>VideoHeight ) { - DebugLevel0Fn("Wrong coordinates %d,%d %d,%d\n", - x1,y1,x2,y2); - return; - } - DrawLine32(color,x1,y1,x2,y2); + VideoDrawLine(color,x1,y1,x2,y2); } } } @@ -2336,16 +3263,32 @@ global void DrawLineClip32(SysColors color,int x1,int y1,int x2,int y2) ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangle8(SysColors color,int x,int y +local void DrawRectangle8(SysColors color,int x,int y ,unsigned w,unsigned h) { - DrawHLine8(color,x,y,w); - DrawVLine8(color,x,y+1,h); - DrawHLine8(color,x+1,y+h,w); - DrawVLine8(color,x+w,y,h); + VMemType8 *p, f; + unsigned swidth, ofs; + + f=Pixels8[color]; + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + if ( h && (ofs=w) ) { + do *p++=f; // Draw top horizontal line, FIXME: 4 bytes in one go + while( --ofs ); + if ( --h ) { + p+=(swidth-w); + ofs=w-1; + while( --h ) { // Draw vertical line(s) + p[ofs]=*p=f; //FIXME: draws pixel twice for w==1 :( + p+=swidth; + } + do *p++=f; // Draw bottom horizontal line, FIXME: 4 bytes in one go + while( ofs-- ); + } + } } /** @@ -2354,16 +3297,32 @@ global void DrawRectangle8(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangle16(SysColors color,int x,int y +local void DrawRectangle16(SysColors color,int x,int y ,unsigned w,unsigned h) { - DrawHLine16(color,x,y,w); - DrawVLine16(color,x,y+1,h); - DrawHLine16(color,x+1,y+h,w); - DrawVLine16(color,x+w,y,h); + VMemType16 *p, f; + unsigned swidth, ofs; + + f=Pixels16[color]; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + if ( h && (ofs=w) ) { + do *p++=f; // Draw top horizontal line + while( --ofs ); + if ( --h ) { + p+=(swidth-w); + ofs=w-1; + while( --h ) { // Draw vertical line(s) + p[ofs]=*p=f; //FIXME: draws pixel twice for w==1 :( + p+=swidth; + } + do *p++=f; // Draw bottom horizontal line + while( ofs-- ); + } + } } /** @@ -2372,16 +3331,32 @@ global void DrawRectangle16(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangle24(SysColors color,int x,int y +local void DrawRectangle24(SysColors color,int x,int y ,unsigned w,unsigned h) { - DrawHLine24(color,x,y,w); - DrawVLine24(color,x,y+1,h); - DrawHLine24(color,x+1,y+h,w); - DrawVLine24(color,x+w,y,h); + VMemType24 *p, f; + unsigned swidth, ofs; + + f=Pixels24[color]; + swidth=VideoWidth; + p=VideoMemory24+y*swidth+x; + if ( h && (ofs=w) ) { + do *p++=f; // Draw top horizontal line + while( --ofs ); + if ( --h ) { + p+=(swidth-w); + ofs=w-1; + while( --h ) { // Draw vertical line(s) + p[ofs]=*p=f; //FIXME: draws pixel twice for w==1 :( + p+=swidth; + } + do *p++=f; // Draw bottom horizontal line + while( ofs-- ); + } + } } /** @@ -2390,92 +3365,1205 @@ global void DrawRectangle24(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangle32(SysColors color,int x,int y +local void DrawRectangle32(SysColors color,int x,int y ,unsigned w,unsigned h) { - DrawHLine32(color,x,y,w); - DrawVLine32(color,x,y+1,h); - DrawHLine32(color,x+1,y+h,w); - DrawVLine32(color,x+w,y,h); + VMemType32 *p, f; + unsigned swidth, ofs; + + f=Pixels32[color]; + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + if ( h && (ofs=w) ) { + do *p++=f; // Draw top horizontal line + while( --ofs ); + if ( --h ) { + p+=(swidth-w); + ofs=w-1; + while( --h ) { // Draw vertical line(s) + p[ofs]=*p=f; //FIXME: draws pixel twice for w==1 :( + p+=swidth; + } + do *p++=f; // Draw bottom horizontal line + while( ofs-- ); + } + } } /** -** Draw rectangle clipped into 8bpp frame buffer. +** Draw 25% translucent rectangle into 8bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangleClip8(SysColors color,int x,int y +local void Draw25TransRectangle8(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - DrawHLineClip8(color,x,y,w); - DrawVLineClip8(color,x,y+1,h); - DrawHLineClip8(color,x+1,y+h,w); - DrawVLineClip8(color,x+w,y,h); + VMemType8 *p; + unsigned int swidth, ofs, c; + + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + c=Pixels8[color]<<8; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + *p++ = lookup25trans8[ c | *p ]; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + p[ofs] = lookup25trans8[ c | p[ofs] ]; + *p = lookup25trans8[ c | *p ]; + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + *p = lookup25trans8[ c | *p ]; + p+=swidth; + } + + do { // Draw bottom horizontal line + *p++ = lookup25trans8[ c | *p ]; + } while( ofs-- ); + } + } } /** -** Draw rectangle clipped into 16bpp frame buffer. +** Draw 25% translucent rectangle into 15bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangleClip16(SysColors color,int x,int y +local void Draw25TransRectangle15(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - DrawHLineClip16(color,x,y,w); - DrawVLineClip16(color,x,y+1,h); - DrawHLineClip16(color,x+1,y+h,w); - DrawVLineClip16(color,x+w,y,h); + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x03E07C1F)*3; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } } /** -** Draw rectangle clipped into 24bpp frame buffer. +** Draw 25% translucent rectangle into 16bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangleClip24(SysColors color,int x,int y +local void Draw25TransRectangle16(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - DrawHLineClip24(color,x,y,w); - DrawVLineClip24(color,x,y+1,h); - DrawHLineClip24(color,x+1,y+h,w); - DrawVLineClip24(color,x+w,y,h); + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x07E0F81F)*3; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } } /** -** Draw rectangle clipped into 32bpp frame buffer. +** Draw 25% translucent rectangle into 24bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void DrawRectangleClip32(SysColors color,int x,int y +local void Draw25TransRectangle24(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - DrawHLineClip32(color,x,y,w); - DrawVLineClip32(color,x,y+1,h); - DrawHLineClip32(color,x+1,y+h,w); - DrawVLineClip32(color,x+w,y,h); +//FIXME: does 24bpp represents R|G|B? + DrawRectangle24(color,x,y,w,h); // no trans functionaility for the moment :( +} + +/** +** Draw 25% translucent rectangle into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw25TransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType32 *p; + unsigned long sp1,sp2,dp1,dp2; + unsigned swidth, ofs; + + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=((sp1&0xFF00FF00)>>8)*3; + sp1=(sp1&0x00FF00FF)*3; + + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp1=p[ofs]; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + p[ofs]=(dp1|(dp2<<8)); + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + p+=swidth; + } + + do { // Draw bottom horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( ofs-- ); + } + } +} + +/** +** Draw 50% translucent rectangle into 8bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw50TransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType8 *p; + unsigned int swidth, ofs, c; + + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + c=Pixels8[color]<<8; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + *p++ = lookup50trans8[ c | *p ]; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + p[ofs] = lookup50trans8[ c | p[ofs] ]; + *p = lookup50trans8[ c | *p ]; + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + *p = lookup50trans8[ c | *p ]; + p+=swidth; + } + + do { // Draw bottom horizontal line + *p++ = lookup50trans8[ c | *p ]; + } while( ofs-- ); + } + } +} + +/** +** Draw 50% translucent rectangle into 15bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw50TransRectangle15(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } +} + +/** +** Draw 50% translucent rectangle into 16bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw50TransRectangle16(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } +} + +/** +** Draw 50% translucent rectangle into 24bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw50TransRectangle24(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ +//FIXME: does 24bpp represents R|G|B? + DrawRectangle24(color,x,y,w,h); // no trans functionaility for the moment :( +} + +/** +** Draw 50% translucent rectangle into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw50TransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType32 *p; + unsigned long sp1,sp2,dp1,dp2; + unsigned swidth, ofs; + + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp1=p[ofs]; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + p[ofs]=(dp1|(dp2<<8)); + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + p+=swidth; + } + + do { // Draw bottom horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( ofs-- ); + } + } +} + +/** +** Draw 75% translucent rectangle into 8bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw75TransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType8 *p; + unsigned int swidth, ofs, c; + + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + c=Pixels8[color]; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + *p++ = lookup25trans8[ (*p<<8) | c ]; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + p[ofs] = lookup25trans8[ (p[ofs]<<8) | c ]; + *p = lookup25trans8[ (*p<<8) | c ]; + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + *p = lookup25trans8[ (*p<<8) | c ]; + p+=swidth; + } + + do { // Draw bottom horizontal line + *p++ = lookup25trans8[ (*p<<8) | c ]; + } while( ofs-- ); + } + } +} + +/** +** Draw 75% translucent rectangle into 15bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw75TransRectangle15(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } +} + +/** +** Draw 75% translucent rectangle into 16bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw75TransRectangle16(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } +} + +/** +** Draw 75% translucent rectangle into 24bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw75TransRectangle24(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ +//FIXME: does 24bpp represents R|G|B? + DrawRectangle24(color,x,y,w,h); // no trans functionaility for the moment :( +} + +/** +** Draw 75% translucent rectangle into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void Draw75TransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType32 *p; + unsigned long sp1,sp2,dp1,dp2; + unsigned swidth, ofs; + + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp1=p[ofs]; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + p[ofs]=(dp1|(dp2<<8)); + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + p+=swidth; + } + + do { // Draw bottom horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( ofs-- ); + } + } +} + +/** +** Draw translucent rectangle into 8bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawTransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + switch ( ((unsigned int)alpha * 4) / 255 ) + { + case 0: + DrawRectangle8(color,x,y,w,h); + break; + case 1: + Draw25TransRectangle8(color,x,y,w,h); + break; + case 2: + Draw50TransRectangle8(color,x,y,w,h); + break; + case 3: + Draw75TransRectangle8(color,x,y,w,h); + break; + default: + break; + } +} + +/** +** Draw rectangle into 8bpp frame buffer (ignoring alpha). +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param alpha alpha value of pixel. +*/ +local void DrawNoTransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + DrawRectangle8(color,x,y,w,h); +} + +/** +** Draw translucent rectangle into 15bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawTransRectangle15(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + //FIXME: alpha==256 unreached + alpha>>=3; //FIXME: only 5bits + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } +} + +/** +** Draw translucent rectangle into 16bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawTransRectangle16(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp,dp; + unsigned swidth, ofs; + + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + //FIXME: alpha==256 unreached + alpha>>=3; //FIXME: only 5bits + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( --ofs ); + + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp=p[ofs]; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; + p[ofs]=(dp>>16)|dp; + + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; + *p=(dp>>16)|dp; + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; + *p=(dp>>16)|dp; + p+=swidth; + } + + do { // Draw bottom horizontal line + dp=*p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while( ofs-- ); + } + } +} + +/** +** Draw translucent rectangle into 24bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawTransRectangle24(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ +//FIXME: does 24bpp represents R|G|B? + DrawRectangle24(color,x,y,w,h); // no trans functionaility for the moment :( +} + +/** +** Draw translucent rectangle into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawTransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + VMemType32 *p; + unsigned long sp1,sp2,dp1,dp2; + unsigned swidth, ofs; + + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + //FIXME: alpha==256 unreached + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + if ( h && (ofs=w) ) { + do { // Draw top horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( --ofs ); + if ( --h ) { + p+=(swidth-w); + if ((ofs=w-1)) + while( --h ) { // Draw two vertical lines + dp1=p[ofs]; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + p[ofs]=(dp1|(dp2<<8)); + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + + p+=swidth; + } + else + while( --h ) { // Draw one vertical line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + *p=(dp1|(dp2<<8)); + p+=swidth; + } + + do { // Draw bottom horizontal line + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while( ofs-- ); + } + } +} + +#define CLIP_RECTANGLE(x,y,width,height) { \ + unsigned f; \ + if( x<ClipX1 ) { \ + f=ClipX1-x; \ + if( width<=f ) { \ + return; \ + } \ + width-=f; \ + x=ClipX1; \ + } \ + if( (x+width)>ClipX2+1 ) { \ + if( x>ClipX2 ) { \ + return; \ + } \ + width=ClipX2-x+1; \ + } \ + if( y<ClipY1 ) { \ + f=ClipY1-y; \ + if( height<=f ) { \ + return; \ + } \ + height-=f; \ + y=ClipY1; \ + } \ + if( (y+height)>ClipY2+1 ) { \ + if( y>ClipY2 ) { \ + return; \ + } \ + height=ClipY2-y+1; \ + } \ +} + +/** +** Draw rectangle clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +global void VideoDrawRectangleClip(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + CLIP_RECTANGLE(x,y,w,h); + VideoDrawRectangle(color,x,y,w,h); +} + +/** +** Draw 25% translucent rectangle clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +global void VideoDraw25TransRectangleClip(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + CLIP_RECTANGLE(x,y,w,h); + VideoDraw25TransRectangle(color,x,y,w,h); +} + +/** +** Draw 50% translucent rectangle clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +global void VideoDraw50TransRectangleClip(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + CLIP_RECTANGLE(x,y,w,h); + VideoDraw50TransRectangle(color,x,y,w,h); +} + +/** +** Draw 75% translucent rectangle clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +global void VideoDraw75TransRectangleClip(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + CLIP_RECTANGLE(x,y,w,h); + VideoDraw75TransRectangle(color,x,y,w,h); +} + +/** +** Draw translucent rectangle clipped. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +global void VideoDrawTransRectangleClip(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + CLIP_RECTANGLE(x,y,w,h); + VideoDrawTransRectangle(color,x,y,w,h,alpha); } // =========================================================================== @@ -2608,70 +4696,809 @@ global void VideoDrawCircleClip(SysColors color,int x,int y,unsigned r) // =========================================================================== /** -** Fill rectangle clipped. +** Fill rectangle into 8bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void VideoFillRectangle(SysColors color,int x,int y +local void DrawFillRectangle8(SysColors color,int x,int y ,unsigned w,unsigned h) { + VMemType8 *p, f; + unsigned int swidth, i; + + f=Pixels8[color]; + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + swidth-=w; + if ( w ) while( h-- ) { - VideoDrawHLine(color,x,y++,w); + i=w; + do *p++=f; + while ( --i ); + p+=swidth; } } /** -** Fill rectangle 25% translucent clipped. +** Fill rectangle into 16bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void VideoFill25TransRectangle(SysColors color,int x,int y +local void DrawFillRectangle16(SysColors color,int x,int y ,unsigned w,unsigned h) { + VMemType16 *p, f; + unsigned int swidth, i; + + f=Pixels16[color]; + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + if ( w ) while( h-- ) { - VideoDraw25TransHLine(color,x,y++,w); + i=w; + do *p++=f; + while ( --i ); + p+=swidth; } } /** -** Fill rectangle 50% translucent clipped. +** Fill rectangle into 24bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void VideoFill50TransRectangle(SysColors color,int x,int y +local void DrawFillRectangle24(SysColors color,int x,int y ,unsigned w,unsigned h) { + VMemType24 *p, f; + unsigned int swidth, i; + + f=Pixels24[color]; + swidth=VideoWidth; + p=VideoMemory24+y*swidth+x; + swidth-=w; + if ( w ) while( h-- ) { - VideoDraw50TransHLine(color,x,y++,w); + i=w; + do *p++=f; + while ( --i ); + p+=swidth; } } /** -** Fill rectangle 75% translucent clipped. +** Fill rectangle into 32bpp frame buffer. ** ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ -global void VideoFill75TransRectangle(SysColors color,int x,int y +local void DrawFillRectangle32(SysColors color,int x,int y ,unsigned w,unsigned h) { + VMemType32 *p, f; + unsigned int swidth, i; + + f=Pixels32[color]; + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + swidth-=w; + if ( w ) while( h-- ) { - VideoDraw75TransHLine(color,x,y++,w); + i=w; + do *p++=f; + while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 25% translucent clipped into 8bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill25TransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType8 *p; + unsigned int i, swidth, c; + + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + swidth-=w; + c=Pixels8[color]<<8; + + if ( w ) + while( h-- ) { + i=w; + do { + *p++ = lookup25trans8[ c | *p ]; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 25% translucent clipped into 15bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill25TransRectangle15(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x03E07C1F)*3; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>2)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 25% translucent clipped into 16bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill25TransRectangle16(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + // FIXME: pre multiply? + sp=(((sp<<16)|sp)&0x07E0F81F)*3; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>2)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 25% translucent clipped into 24bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill25TransRectangle24(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawFillRectangle24(color,x,y,w,h); // no trans functionaility :( +} + +/** +** Fill rectangle 25% translucent clipped into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill25TransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType32 *p; + unsigned long sp1, sp2; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + swidth-=w; + + sp1=Pixels32[color]; + // FIXME: pre multiply? + sp2=((sp1&0xFF00FF00)>>8)*3; + sp1=(sp1&0x00FF00FF)*3; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>2)&0x00FF00FF; + dp2=((dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 50% translucent clipped into 8bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill50TransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType8 *p; + unsigned int i, swidth, c; + + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + swidth-=w; + c=Pixels8[color]<<8; + + if ( w ) + while( h-- ) { + i=w; + do { + *p++ = lookup50trans8[ c | *p ]; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 50% translucent clipped into 15bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill50TransRectangle15(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=((dp+sp)>>1)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 50% translucent clipped into 16bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill50TransRectangle16(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((dp+sp)>>1)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 50% translucent clipped into 24bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill50TransRectangle24(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + // FIXME: how does 24bpp represents RGB ? + DrawFillRectangle24(color,x,y,w,h); // no trans functionaility :( +} + +/** +** Fill rectangle 50% translucent clipped into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill50TransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType32 *p; + unsigned long sp1, sp2; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + swidth-=w; + + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=((dp1+sp1)>>1)&0x00FF00FF; + dp2=((dp2+sp2)>>1)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 75% translucent clipped into 8bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill75TransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType8 *p; + unsigned int i, swidth, c; + + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + swidth-=w; + c=Pixels8[color]; + + if ( w ) + while( h-- ) { + i=w; + do { + *p++ = lookup25trans8[ (*p<<8) | c ]; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 75% translucent clipped into 15bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill75TransRectangle15(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x03E07C1F; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x03E07C1F; + dp=(((dp<<1)+dp+sp)>>2)&0x03E07C1F; + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 75% translucent clipped into 16bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill75TransRectangle16(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=(((dp<<1)+dp+sp)>>2)&0x07E0F81F; + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Fill rectangle 75% translucent clipped into 24bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill75TransRectangle24(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + // FIXME: does 24bpp holds R|G|B ? + DrawFillRectangle24(color,x,y,w,h); // no trans functionaility :( +} + +/** +** Fill rectangle 75% translucent clipped into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +*/ +local void DrawFill75TransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h) +{ + VMemType32 *p; + unsigned long sp1, sp2; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + swidth-=w; + + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + dp1=(((dp1<<1)+dp1+sp1)>>2)&0x00FF00FF; + dp2=(((dp2<<1)+dp2+sp2)>>2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while ( --i ); + p+=swidth; + } +} + +/** +** Draw translucent rectangle into 8bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawFillTransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + VMemType8 *p; + unsigned int i, swidth, c; + + swidth=VideoWidth; + p=VideoMemory8+y*swidth+x; + swidth-=w; + c=Pixels8[color]; + + if ( w ) + switch ( ((unsigned int)alpha * 4) / 255 ) + { + case 0: + while( h-- ) { + i=w; + do { + *p++ = c; + } while ( --i ); + p+=swidth; + } + break; + case 1: + c<<=8; + while( h-- ) { + i=w; + do { + *p++ = lookup25trans8[ *p | c ]; + } while ( --i ); + p+=swidth; + } + break; + case 2: + c<<=8; + while( h-- ) { + i=w; + do { + *p++ = lookup50trans8[ *p | c ]; + } while ( --i ); + p+=swidth; + } + break; + case 3: + while( h-- ) { + i=w; + do { + *p++ = lookup25trans8[ (*p<<8) | c ]; + } while ( --i ); + p+=swidth; + } + break; + default: + break; + } +} + +/** +** Draw rectangle into 8bpp frame buffer (ignoring alpha). +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawFillNoTransRectangle8(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + DrawFillRectangle8(color,x,y,w,h); +} + +/** +** Draw translucent rectangle into 15bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawFillTransRectangle15(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + alpha>>=3; //FIXME: only 5bits + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x03E07C1F; //FIXME: alpha==256 unreached + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Draw translucent rectangle into 16bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawFillTransRectangle16(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + VMemType16 *p; + unsigned long sp; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory16+y*swidth+x; + swidth-=w; + sp=Pixels16[color]; + sp=((sp<<16)|sp)&0x07E0F81F; + alpha>>=3; //FIXME: only 5bits + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp = *p; + dp=((dp<<16)|dp)&0x07E0F81F; + dp=((((dp-sp)*alpha)>>5)+sp)&0x07E0F81F; //FIXME: alpha==256 unreached + *p++=(dp>>16)|dp; + } while ( --i ); + p+=swidth; + } +} + +/** +** Draw translucent rectangle into 24bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawFillTransRectangle24(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ +//FIXME: does 24bpp represents R|G|B? + DrawFillRectangle24(color,x,y,w,h); // no trans functionaility :( +} + +/** +** Draw translucent rectangle into 32bpp frame buffer. +** +** @param color Color index. +** @param x x coordinate on the screen +** @param y y coordinate on the screen +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). +** @param alpha alpha value of pixel. +*/ +local void DrawFillTransRectangle32(SysColors color,int x,int y + ,unsigned w,unsigned h,unsigned char alpha) +{ + VMemType32 *p; + unsigned long sp1, sp2; + unsigned int i, swidth; + + swidth=VideoWidth; + p=VideoMemory32+y*swidth+x; + swidth-=w; + + sp1=Pixels32[color]; + sp2=(sp1&0xFF00FF00)>>8; + sp1&=0x00FF00FF; + + if ( w ) + while( h-- ) { + i=w; + do { + unsigned long dp1, dp2; + + dp1=*p; + dp2=(dp1&0xFF00FF00)>>8; + dp1&=0x00FF00FF; + + //FIXME: alpha==256 unreached + dp1=((((dp1-sp1)*alpha)>>8)+sp1)&0x00FF00FF; + dp2=((((dp2-sp2)*alpha)>>8)+sp2)&0x00FF00FF; + *p++=(dp1|(dp2<<8)); + } while ( --i ); + p+=swidth; } } @@ -2681,16 +5508,14 @@ global void VideoFill75TransRectangle(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ global void VideoFillRectangleClip(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - while( h-- ) { - VideoDrawHLineClip(color,x,y++,w); - } + CLIP_RECTANGLE(x,y,w,h); + VideoFillRectangle(color,x,y,w,h); } /** @@ -2699,16 +5524,14 @@ global void VideoFillRectangleClip(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ global void VideoFill25TransRectangleClip(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - while( h-- ) { - VideoDraw25TransHLineClip(color,x,y++,w); - } + CLIP_RECTANGLE(x,y,w,h); + VideoFill25TransRectangle(color,x,y,w,h); } /** @@ -2717,16 +5540,14 @@ global void VideoFill25TransRectangleClip(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ global void VideoFill50TransRectangleClip(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - while( h-- ) { - VideoDraw50TransHLineClip(color,x,y++,w); - } + CLIP_RECTANGLE(x,y,w,h); + VideoFill50TransRectangle(color,x,y,w,h); } /** @@ -2735,16 +5556,14 @@ global void VideoFill50TransRectangleClip(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). */ global void VideoFill75TransRectangleClip(SysColors color,int x,int y ,unsigned w,unsigned h) { - // FIXME: Clip here - while( h-- ) { - VideoDraw75TransHLineClip(color,x,y++,w); - } + CLIP_RECTANGLE(x,y,w,h); + VideoFill75TransRectangle(color,x,y,w,h); } /** @@ -2753,87 +5572,15 @@ global void VideoFill75TransRectangleClip(SysColors color,int x,int y ** @param color Color index. ** @param x x coordinate on the screen ** @param y y coordinate on the screen -** @param h height of rectangle. -** @param w width of rectangle. +** @param h height of rectangle (0=don't draw). +** @param w width of rectangle (0=don't draw). ** @param alpha alpha value of pixels. */ global void VideoFillTransRectangleClip(SysColors color,int x,int y - ,unsigned w,unsigned h,int alpha) + ,unsigned w,unsigned h,unsigned char alpha) { - // FIXME: Clip here - while( h-- ) { - VideoDrawTransHLineClip(color,x,y++,w,alpha); - } -} - -/** -** Draw translucent horizontal line clipped into 15bit framebuffer. -** -** @param color Color index. -** @param x x coordinate on the screen -** @param y y coordinate on the screen -** @param width width of line. -** @param alpha alpha value of pixels. -*/ -local void DrawTransHLineClip15(SysColors color,int x,int y,unsigned width - ,int alpha) -{ - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - DrawTransHLine15(color,x,y,width,alpha); -} - -/** -** Draw translucent horizontal line clipped into 16bit framebuffer. -** -** @param color Color index. -** @param x x coordinate on the screen -** @param y y coordinate on the screen -** @param width width of line. -** @param alpha alpha value of pixels. -*/ -local void DrawTransHLineClip16(SysColors color,int x,int y,unsigned width - ,int alpha) -{ - int f; - - if( y<ClipY1 || y>=ClipY2 ) { // Clipping: - return; - } - if( x<ClipX1 ) { - f=ClipX1-x; - x=ClipX1; - if( width<f ) { - return; - } - width-=f; - } - if( (x+width)>ClipX2 ) { - if( width<ClipX2-x ) { - return; - } - width=ClipX2-x; - } - - DrawTransHLine16(color,x,y,width,alpha); + CLIP_RECTANGLE(x,y,w,h); + VideoFillTransRectangle(color,x,y,w,h,alpha); } // =========================================================================== @@ -3035,84 +5782,187 @@ global void InitLineDraw(void) { switch( VideoBpp ) { case 8: - VideoDrawPixel=DrawPixel8; - VideoDrawPixelClip=DrawPixelClip8; - VideoDrawHLine=DrawHLine8; - VideoDrawHLineClip=DrawHLineClip8; - VideoDrawVLine=DrawVLine8; - VideoDrawVLineClip=DrawVLineClip8; - VideoDrawLine=DrawLine8; - VideoDrawLineClip=DrawLineClip8; - VideoDrawRectangle=DrawRectangle8; - VideoDrawRectangleClip=DrawRectangleClip8; + if ( lookup25trans8 && lookup50trans8 ) + { + VideoDrawPixel = DrawPixel8; + VideoDraw25TransPixel = Draw25TransPixel8; + VideoDraw50TransPixel = Draw50TransPixel8; + VideoDraw75TransPixel = Draw75TransPixel8; + VideoDrawTransPixel = DrawTransPixel8; + VideoDrawPixelClip = DrawPixelClip8; + VideoDrawHLine = DrawHLine8; + VideoDraw25TransHLine = Draw25TransHLine8; + VideoDraw50TransHLine = Draw50TransHLine8; + VideoDraw75TransHLine = Draw75TransHLine8; + VideoDrawTransHLine = DrawTransHLine8; + VideoDrawVLine = DrawVLine8; + VideoDraw25TransVLine = Draw25TransVLine8; + VideoDraw50TransVLine = Draw50TransVLine8; + VideoDraw75TransVLine = Draw75TransVLine8; + VideoDrawTransVLine = DrawTransVLine8; + VideoDrawLine = DrawLine8; + VideoDrawRectangle = DrawRectangle8; + VideoDraw25TransRectangle = Draw25TransRectangle8; + VideoDraw50TransRectangle = Draw50TransRectangle8; + VideoDraw75TransRectangle = Draw75TransRectangle8; + VideoDrawTransRectangle = DrawTransRectangle8; + VideoFillRectangle = DrawFillRectangle8; + VideoFill25TransRectangle = DrawFill25TransRectangle8; + VideoFill50TransRectangle = DrawFill50TransRectangle8; + VideoFill75TransRectangle = DrawFill75TransRectangle8; + VideoFillTransRectangle = DrawFillTransRectangle8; + } + else + { + printf( "(transparency support disabled)\n" ); + VideoDrawPixel = + VideoDraw25TransPixel = + VideoDraw50TransPixel = + VideoDraw75TransPixel = DrawPixel8; + VideoDrawTransPixel = DrawNoTransPixel8; + VideoDrawPixelClip = DrawPixelClip8; + VideoDrawHLine = + VideoDraw25TransHLine = + VideoDraw50TransHLine = + VideoDraw75TransHLine = DrawHLine8; + VideoDrawTransHLine = DrawNoTransHLine8; + VideoDrawVLine = + VideoDraw25TransVLine = + VideoDraw50TransVLine = + VideoDraw75TransVLine = DrawVLine8; + VideoDrawTransVLine = DrawNoTransVLine8; + VideoDrawLine = DrawLine8; + VideoDrawRectangle = + VideoDraw25TransRectangle = + VideoDraw50TransRectangle = + VideoDraw75TransRectangle = DrawRectangle8; + VideoDrawTransRectangle = DrawNoTransRectangle8; + VideoFillRectangle = + VideoFill25TransRectangle = + VideoFill50TransRectangle = + VideoFill75TransRectangle = DrawFillRectangle8; + VideoFillTransRectangle = DrawFillNoTransRectangle8; + } break; case 15: - VideoDrawPixel=DrawPixel16; - VideoDrawPixelClip=DrawPixelClip16; - VideoDrawHLine=DrawHLine16; - VideoDrawHLineClip=DrawHLineClip16; - VideoDraw25TransHLine=Draw25TransHLine15; - VideoDraw25TransHLineClip=Draw25TransHLineClip15; - VideoDraw50TransHLine=Draw50TransHLine15; - VideoDraw50TransHLineClip=Draw50TransHLineClip15; - VideoDraw75TransHLine=Draw75TransHLine15; - VideoDraw75TransHLineClip=Draw75TransHLineClip15; - VideoDrawTransHLine=DrawTransHLine15; - VideoDrawTransHLineClip=DrawTransHLineClip15; - VideoDrawVLine=DrawVLine16; - VideoDrawVLineClip=DrawVLineClip16; - VideoDrawLine=DrawLine16; - VideoDrawLineClip=DrawLineClip16; - VideoDrawRectangle=DrawRectangle16; - VideoDrawRectangleClip=DrawRectangleClip16; + VideoDrawPixel = DrawPixel16; + VideoDraw25TransPixel = Draw25TransPixel15; + VideoDraw50TransPixel = Draw50TransPixel15; + VideoDraw75TransPixel = Draw75TransPixel15; + VideoDrawTransPixel = DrawTransPixel15; + VideoDrawPixelClip = DrawPixelClip16; + VideoDrawHLine = DrawHLine16; + VideoDraw25TransHLine = Draw25TransHLine15; + VideoDraw50TransHLine = Draw50TransHLine15; + VideoDraw75TransHLine = Draw75TransHLine15; + VideoDrawTransHLine = DrawTransHLine15; + VideoDrawVLine = DrawVLine16; + VideoDraw25TransVLine = Draw25TransVLine15; + VideoDraw50TransVLine = Draw50TransVLine15; + VideoDraw75TransVLine = Draw75TransVLine15; + VideoDrawTransVLine = DrawTransVLine15; + VideoDrawLine = DrawLine16; + VideoDrawRectangle = DrawRectangle16; + VideoDraw25TransRectangle = Draw25TransRectangle15; + VideoDraw50TransRectangle = Draw50TransRectangle15; + VideoDraw75TransRectangle = Draw75TransRectangle15; + VideoDrawTransRectangle = DrawTransRectangle15; + VideoFillRectangle = DrawFillRectangle16; + VideoFill25TransRectangle = DrawFill25TransRectangle15; + VideoFill50TransRectangle = DrawFill50TransRectangle15; + VideoFill75TransRectangle = DrawFill75TransRectangle15; + VideoFillTransRectangle = DrawFillTransRectangle15; break; case 16: - VideoDrawPixel=DrawPixel16; - VideoDrawPixelClip=DrawPixelClip16; - VideoDrawHLine=DrawHLine16; - VideoDrawHLineClip=DrawHLineClip16; - VideoDraw25TransHLine=Draw25TransHLine16; - VideoDraw25TransHLineClip=Draw25TransHLineClip16; - VideoDraw50TransHLine=Draw50TransHLine16; - VideoDraw50TransHLineClip=Draw50TransHLineClip16; - VideoDraw75TransHLine=Draw75TransHLine16; - VideoDraw75TransHLineClip=Draw75TransHLineClip16; - VideoDrawTransHLine=DrawTransHLine16; - VideoDrawTransHLineClip=DrawTransHLineClip16; - VideoDrawVLine=DrawVLine16; - VideoDrawVLineClip=DrawVLineClip16; - VideoDrawLine=DrawLine16; - VideoDrawLineClip=DrawLineClip16; - VideoDrawRectangle=DrawRectangle16; - VideoDrawRectangleClip=DrawRectangleClip16; + VideoDrawPixel = DrawPixel16; + VideoDraw25TransPixel = Draw25TransPixel16; + VideoDraw50TransPixel = Draw50TransPixel16; + VideoDraw75TransPixel = Draw75TransPixel16; + VideoDrawTransPixel = DrawTransPixel16; + VideoDrawPixelClip = DrawPixelClip16; + VideoDrawHLine = DrawHLine16; + VideoDraw25TransHLine = Draw25TransHLine16; + VideoDraw50TransHLine = Draw50TransHLine16; + VideoDraw75TransHLine = Draw75TransHLine16; + VideoDrawTransHLine = DrawTransHLine16; + VideoDrawVLine = DrawVLine16; + VideoDraw25TransVLine = Draw25TransVLine16; + VideoDraw50TransVLine = Draw50TransVLine16; + VideoDraw75TransVLine = Draw75TransVLine16; + VideoDrawTransVLine = DrawTransVLine16; + VideoDrawLine = DrawLine16; + VideoDrawRectangle = DrawRectangle16; + VideoDraw25TransRectangle = Draw25TransRectangle16; + VideoDraw50TransRectangle = Draw50TransRectangle16; + VideoDraw75TransRectangle = Draw75TransRectangle16; + VideoDrawTransRectangle = DrawTransRectangle16; + VideoFillRectangle = DrawFillRectangle16; + VideoFill25TransRectangle = DrawFill25TransRectangle16; + VideoFill50TransRectangle = DrawFill50TransRectangle16; + VideoFill75TransRectangle = DrawFill75TransRectangle16; + VideoFillTransRectangle = DrawFillTransRectangle16; break; case 24: - VideoDrawPixel=DrawPixel24; - VideoDrawPixelClip=DrawPixelClip24; - VideoDrawHLine=DrawHLine24; - VideoDrawHLineClip=DrawHLineClip24; - VideoDrawVLine=DrawVLine24; - VideoDrawVLineClip=DrawVLineClip24; - VideoDrawLine=DrawLine24; - VideoDrawLineClip=DrawLineClip24; - VideoDrawRectangle=DrawRectangle24; - VideoDrawRectangleClip=DrawRectangleClip24; + VideoDrawPixel = DrawPixel24; + VideoDraw25TransPixel = Draw25TransPixel24; + VideoDraw50TransPixel = Draw50TransPixel24; + VideoDraw75TransPixel = Draw75TransPixel24; + VideoDrawTransPixel = DrawTransPixel24; + VideoDrawPixelClip = DrawPixelClip24; + VideoDrawHLine = DrawHLine24; + VideoDraw25TransHLine = Draw25TransHLine24; + VideoDraw50TransHLine = Draw50TransHLine24; + VideoDraw75TransHLine = Draw75TransHLine24; + VideoDrawTransHLine = DrawTransHLine24; + VideoDrawVLine = DrawVLine24; + VideoDraw25TransVLine = Draw25TransVLine24; + VideoDraw50TransVLine = Draw50TransVLine24; + VideoDraw75TransVLine = Draw75TransVLine24; + VideoDrawTransVLine = DrawTransVLine24; + VideoDrawLine = DrawLine24; + VideoDrawRectangle = DrawRectangle24; + VideoDraw25TransRectangle = Draw25TransRectangle24; + VideoDraw50TransRectangle = Draw50TransRectangle24; + VideoDraw75TransRectangle = Draw75TransRectangle24; + VideoDrawTransRectangle = DrawTransRectangle24; + VideoFillRectangle = DrawFillRectangle24; + VideoFill25TransRectangle = DrawFill25TransRectangle24; + VideoFill50TransRectangle = DrawFill50TransRectangle24; + VideoFill75TransRectangle = DrawFill75TransRectangle24; + VideoFillTransRectangle = DrawFillTransRectangle24; break; case 32: - VideoDrawPixel=DrawPixel32; - VideoDrawPixelClip=DrawPixelClip32; - VideoDrawHLine=DrawHLine32; - VideoDrawHLineClip=DrawHLineClip32; - VideoDrawVLine=DrawVLine32; - VideoDrawVLineClip=DrawVLineClip32; - VideoDrawLine=DrawLine32; - VideoDrawLineClip=DrawLineClip32; - VideoDrawRectangle=DrawRectangle32; - VideoDrawRectangleClip=DrawRectangleClip32; + VideoDrawPixel = DrawPixel32; + VideoDraw25TransPixel = Draw25TransPixel32; + VideoDraw50TransPixel = Draw50TransPixel32; + VideoDraw75TransPixel = Draw75TransPixel32; + VideoDrawTransPixel = DrawTransPixel32; + VideoDrawPixelClip = DrawPixelClip32; + VideoDrawHLine = DrawHLine32; + VideoDraw25TransHLine = Draw25TransHLine32; + VideoDraw50TransHLine = Draw50TransHLine32; + VideoDraw75TransHLine = Draw75TransHLine32; + VideoDrawTransHLine = DrawTransHLine32; + VideoDrawVLine = DrawVLine32; + VideoDraw25TransVLine = Draw25TransVLine32; + VideoDraw50TransVLine = Draw50TransVLine32; + VideoDraw75TransVLine = Draw75TransVLine32; + VideoDrawTransVLine = DrawTransVLine32; + VideoDrawLine = DrawLine32; + VideoDrawRectangle = DrawRectangle32; + VideoDraw25TransRectangle = Draw25TransRectangle32; + VideoDraw50TransRectangle = Draw50TransRectangle32; + VideoDraw75TransRectangle = Draw75TransRectangle32; + VideoDrawTransRectangle = DrawTransRectangle32; + VideoFillRectangle = DrawFillRectangle32; + VideoFill25TransRectangle = DrawFill25TransRectangle32; + VideoFill50TransRectangle = DrawFill50TransRectangle32; + VideoFill75TransRectangle = DrawFill75TransRectangle32; + VideoFillTransRectangle = DrawFillTransRectangle32; break; default: diff --git a/src/video/sprite.cpp b/src/video/sprite.cpp index 6db21a42c..829ac485f 100644 --- a/src/video/sprite.cpp +++ b/src/video/sprite.cpp @@ -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; diff --git a/src/video/svgalib.cpp b/src/video/svgalib.cpp index a1e612334..61e2415a9 100644 --- a/src/video/svgalib.cpp +++ b/src/video/svgalib.cpp @@ -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); diff --git a/src/video/video.cpp b/src/video/video.cpp index d0446180e..58933560c 100644 --- a/src/video/video.cpp +++ b/src/video/video.cpp @@ -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 //