generated from kdx/gint-project-template
252 lines
7.0 KiB
C++
252 lines
7.0 KiB
C++
#include <gint/display.h>
|
|
#include <math.h>
|
|
#include "primitives.h"
|
|
|
|
|
|
/* return the sign of the number given in parameter*/
|
|
/* -1 if x<0 0 if x=0 and +1 if x>0 */
|
|
int _sgn( int x )
|
|
{
|
|
if(x>=0)
|
|
return 1;
|
|
else if(x<0)
|
|
return -1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/* return the absolute value of the number given in parameter*/
|
|
int _abs( int x )
|
|
{
|
|
if(x>=0)
|
|
return x;
|
|
else
|
|
return -1*x;
|
|
}
|
|
|
|
/* draw a pixel at coordinates (X,Y) of color (R,G,B) */
|
|
/* all color values (R,G,B) to be in the range 0..255 */
|
|
inline void _fastPixelRGB( unsigned int X, unsigned int Y, unsigned char R, unsigned char G, unsigned char B )
|
|
{
|
|
if ( X<DWIDTH && Y<DHEIGHT)
|
|
{
|
|
//dpixel( X, Y, C_RGB(R,G,B) );
|
|
unsigned int color = (((R>>3) << 11) | ((G>>2) << 5 ) | (B>>3));
|
|
gint_vram[ Y*DWIDTH + X ] = color;
|
|
}
|
|
}
|
|
|
|
inline void _fastGetPixelRGB( unsigned int X, unsigned int Y, unsigned char *R, unsigned char *G, unsigned char *B )
|
|
{
|
|
unsigned int color = gint_vram[ Y*DWIDTH + X ];
|
|
*R = (((color >> 11 ) & 0b11111 ) << 3);
|
|
*G = (((color >> 5) & 0b111111) << 2);
|
|
*B = ((color & 0b11111) << 3);
|
|
}
|
|
|
|
/* return the color of the pixel at coordinates (X,Y) */
|
|
/* modifies R,G,B given as parameters */
|
|
/* all returns R,G,B are in range 0..255 */
|
|
void _getPixelRGB( unsigned int X, unsigned int Y, unsigned char *R, unsigned char *G, unsigned char *B )
|
|
{
|
|
if (X<DWIDTH && Y<DHEIGHT)
|
|
{
|
|
unsigned int color = gint_vram[ Y*DWIDTH + X ];
|
|
*R = (((color >> 11 ) & 0b11111 ) << 3);
|
|
*G = (((color >> 5) & 0b111111) << 2);
|
|
*B = ((color & 0b11111) << 3);
|
|
}
|
|
}
|
|
|
|
inline void _calculateBlendRGBA( unsigned int X, unsigned int Y, unsigned char *R, unsigned char *G, unsigned char *B, unsigned char A )
|
|
{
|
|
unsigned char Ro, Go, Bo;
|
|
_fastGetPixelRGB( X, Y, &Ro, &Go, &Bo );
|
|
*R = Ro + (((*R-Ro)*A) >> 8);
|
|
*G = Go + (((*G-Go)*A) >> 8);
|
|
*B = Bo + (((*B-Bo)*A) >> 8);
|
|
}
|
|
|
|
void _pixelRGBA( unsigned int X, unsigned int Y, unsigned char R, unsigned char G, unsigned char B, unsigned char A )
|
|
{
|
|
if (X<DWIDTH && Y<DHEIGHT)
|
|
{
|
|
if (A==0) return;
|
|
else if (A==255) _fastPixelRGB( X, Y, R, G, B );
|
|
else
|
|
{
|
|
unsigned char Rf = R;
|
|
unsigned char Gf = G;
|
|
unsigned char Bf = B;
|
|
_calculateBlendRGBA( X, Y, &Rf, &Gf, &Bf, A );
|
|
_fastPixelRGB( X, Y, Rf, Gf, Bf );
|
|
}
|
|
}
|
|
}
|
|
|
|
void _lineRGBA( unsigned int X1, unsigned int Y1, unsigned int X2, unsigned int Y2, unsigned char R, unsigned char G, unsigned char B, unsigned char A )
|
|
{
|
|
int x,y,dx,dy,swp,temp,s1,s2,p,i;
|
|
|
|
x=X1;
|
|
y=Y1;
|
|
dx=_abs(X2-X1);
|
|
dy=_abs(Y2-Y1);
|
|
s1=_sgn(X2-X1);
|
|
s2=_sgn(Y2-Y1);
|
|
swp=0;
|
|
|
|
_pixelRGBA( X1, Y1, R, G, B, A );
|
|
|
|
if(dy>dx)
|
|
{
|
|
temp=dx;
|
|
dx=dy;
|
|
dy=temp;
|
|
swp=1;
|
|
}
|
|
p=2*dy-dx;
|
|
for(i=0; i<=dx; i++)
|
|
{
|
|
_pixelRGBA( x, y, R, G, B, A );
|
|
|
|
while(p>=0)
|
|
{
|
|
p=p-2*dx;
|
|
if(swp)
|
|
x+=s1;
|
|
else
|
|
y+=s2;
|
|
}
|
|
p=p+2*dy;
|
|
if(swp)
|
|
y+=s2;
|
|
else
|
|
x+=s1;
|
|
}
|
|
}
|
|
|
|
void _hLineRGBA( unsigned int X1, unsigned int X2, unsigned int Y, unsigned char R, unsigned char G, unsigned char B, unsigned char A )
|
|
{
|
|
if( X1<=X2 )
|
|
{
|
|
for(int k=X1; k<=X2; k++)
|
|
{
|
|
_pixelRGBA(k,Y,R,G,B,A);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int k=X2; k<=X1; k++)
|
|
{
|
|
_pixelRGBA(k,Y,R,G,B,A);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void _rectangleRGBA( unsigned int X1, unsigned int Y1, unsigned int X2, unsigned int Y2, unsigned char R, unsigned char G, unsigned char B, unsigned char A )
|
|
{
|
|
|
|
_lineRGBA( X1, Y1, X1, Y2, R, G, B, A ) ;
|
|
_lineRGBA( X1, Y2, X2, Y2, R, G, B, A ) ;
|
|
_lineRGBA( X2, Y2, X2, Y1, R, G, B, A ) ;
|
|
_lineRGBA( X2, Y1, X1, Y1, R, G, B, A ) ;
|
|
|
|
}
|
|
|
|
void _boxRGBA( unsigned int X1, unsigned int Y1, unsigned int X2, unsigned int Y2, unsigned char R, unsigned char G, unsigned char B, unsigned char A )
|
|
{
|
|
if (Y1<=Y2)
|
|
{
|
|
for( unsigned int k=Y1; k<=Y2; k++)
|
|
_lineRGBA( X1, k, X2, k, R, G, B, A ) ;
|
|
}
|
|
else
|
|
{
|
|
for( unsigned int k=Y2; k<=Y1; k++)
|
|
_lineRGBA( X1, k, X2, k, R, G, B, A ) ;
|
|
}
|
|
|
|
}
|
|
|
|
void _circleRGBA( unsigned int X1, unsigned int Y1, unsigned int Rad, unsigned char R, unsigned char G, unsigned char B, unsigned char A )
|
|
{
|
|
|
|
int x,y,p;
|
|
|
|
x=0;
|
|
y=Rad;
|
|
p=3-2*Rad;
|
|
|
|
_pixelRGBA(X1+x,Y1+y,R,G,B,A);
|
|
_pixelRGBA(X1+x,Y1-y,R,G,B,A);
|
|
_pixelRGBA(X1-x,Y1+y,R,G,B,A);
|
|
_pixelRGBA(X1-x,Y1-y,R,G,B,A);
|
|
_pixelRGBA(X1+y,Y1+x,R,G,B,A);
|
|
_pixelRGBA(X1+y,Y1-x,R,G,B,A);
|
|
_pixelRGBA(X1-y,Y1+x,R,G,B,A);
|
|
_pixelRGBA(X1-y,Y1-x,R,G,B,A);
|
|
|
|
while(x<y)
|
|
{
|
|
if(p<0)
|
|
{
|
|
x++;
|
|
p=p+4*x+6;
|
|
}
|
|
else
|
|
{
|
|
x++;
|
|
y--;
|
|
p=p+4*(x-y)+10;
|
|
}
|
|
_pixelRGBA(X1+x,Y1+y,R,G,B,A);
|
|
_pixelRGBA(X1+x,Y1-y,R,G,B,A);
|
|
_pixelRGBA(X1-x,Y1+y,R,G,B,A);
|
|
_pixelRGBA(X1-x,Y1-y,R,G,B,A);
|
|
_pixelRGBA(X1+y,Y1+x,R,G,B,A);
|
|
_pixelRGBA(X1+y,Y1-x,R,G,B,A);
|
|
_pixelRGBA(X1-y,Y1+x,R,G,B,A);
|
|
_pixelRGBA(X1-y,Y1-x,R,G,B,A);
|
|
}
|
|
|
|
}
|
|
|
|
void _filledCircleRGBA( unsigned int X1, unsigned int Y1, unsigned int Rad, unsigned char R, unsigned char G, unsigned char B, unsigned char A )
|
|
{
|
|
|
|
int x,y,p;
|
|
|
|
x=0;
|
|
y=Rad;
|
|
p=3-2*Rad;
|
|
|
|
_hLineRGBA(X1+x,X1-x,Y1+y,R,G,B,A);
|
|
_hLineRGBA(X1+x,X1-x,Y1-y,R,G,B,A);
|
|
_hLineRGBA(X1+y,X1-y,Y1+x,R,G,B,A);
|
|
_hLineRGBA(X1+y,X1-y,Y1-x,R,G,B,A);
|
|
|
|
while(x<y)
|
|
{
|
|
if(p<0)
|
|
{
|
|
x++;
|
|
p=p+4*x+6;
|
|
}
|
|
else
|
|
{
|
|
x++;
|
|
y--;
|
|
p=p+4*(x-y)+10;
|
|
}
|
|
|
|
_hLineRGBA(X1+x,X1-x,Y1+y,R,G,B,A);
|
|
_hLineRGBA(X1+x,X1-x,Y1-y,R,G,B,A);
|
|
_hLineRGBA(X1+y,X1-y,Y1+x,R,G,B,A);
|
|
_hLineRGBA(X1+y,X1-y,Y1-x,R,G,B,A);
|
|
}
|
|
|
|
}
|