This is the doxygen documentation for gtkboard.

.
Main Page   Data Structures   File List   Data Fields   Globals  

aaball.c

Go to the documentation of this file.
00001 /*  This file is a part of gtkboard, a board games system.
00002     Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
00017 
00018 */
00019 #include <stdio.h>
00020 #include <math.h>
00021 #include <glib.h>
00022 #include <string.h>
00023 
00024 #include "aaball.h"
00025 
00026 
00031 static char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8' ,
00032                                         '9', 'A', 'B', 'C', 'D', 'E', 'F'};
00033 
00034 
00035 static int pixmap_get_color(int fg, int bg, float ratio)
00036 {
00037         int f1, f2, f3, b1, b2, b3, w1, w2, w3;
00038         float lw, lf, lb;
00039         if (ratio < 0) ratio = 0;
00040         if (ratio > 1) ratio = 1;
00041         // FIXME: could we have problems with equality of floats?
00042         if (ratio == 0)
00043         {
00044                 w1 = fg >> 16;
00045                 w2 = (fg >> 8) & 0xff;
00046                 w3 = fg & 0xff;
00047         }
00048         else if (ratio == 1)
00049         {
00050                 w1 = bg >> 16;
00051                 w2 = (bg >> 8) & 0xff;
00052                 w3 = bg & 0xff;
00053         }
00054         else
00055         {
00056                 f1 = fg >> 16;
00057                 f2 = (fg >> 8) & 0xff;
00058                 f3 = fg & 0xff;
00059                 b1 = bg >> 16;
00060                 b2 = (bg >> 8) & 0xff;
00061                 b3 = bg & 0xff;
00062                 w1 =  (1 - ratio) * f1 +  (ratio) * b1;
00063                 w2 =  (1 - ratio) * f2 +  (ratio) * b2;
00064                 w3 =  (1 - ratio) * f3 +  (ratio) * b3;
00065                 lf = sqrt(f1 * f1 + f2 * f2 + f3 * f3);
00066                 lb = sqrt(b1 * b1 + b2 * b2 + b3 * b3);
00067                 lw = sqrt(w1 * w1 + w2 * w2 + w3 * w3);
00068                 lw /= ((1 - ratio) * lf + ratio * lb);
00069                 w1 /= lw; if (w1 > 0xff) w1 = 0xff;
00070                 w2 /= lw; if (w2 > 0xff) w2 = 0xff;
00071                 w3 /= lw; if (w3 > 0xff) w3 = 0xff;
00072         }
00073         return (w1 << 16) + (w2 << 8) + w3;
00074 }
00075 
00076 static char *pixmap_get_hex_color(int fg, int bg, float ratio)
00077 {
00078         int red, green, blue, val;
00079         static char color[7] = { 0 };
00080         val = pixmap_get_color (fg, bg, ratio);
00081         red = val >> 16;
00082         green = (val >> 8) & 0xff;
00083         blue = val & 0xff;
00084         color[0] = hex[red/16];
00085         color[1] = hex[red%16];
00086         color[2] = hex[green/16];
00087         color[3] = hex[green%16];
00088         color[4] = hex[blue/16];
00089         color[5] = hex[blue%16];
00090         return color;
00091 }
00092         
00093 static char *pixmap_map [256];
00094 
00096 
00103 char ** pixmap_ball_gen(int len, char *pixbuf, int fg, int bg, float rad, float grad)
00104 {
00105         char **map = pixmap_map;
00106         char *buf = pixbuf;
00107         static char colbuf[18][20];
00108         int i, j;
00109         for(i=0; i<18; i++) map[i] = colbuf[i];
00110         g_snprintf(map[0], 20, "%d %d 16 1", len, len);
00111         for(i=0; i<16; i++)
00112         {
00113                 g_snprintf (map[i+1], 20, "%c c #%s", hex[i],
00114                                 pixmap_get_hex_color(fg, bg, i / 15.0));
00115         }
00116         for (i=0; i<len; i++)
00117         {
00118                 char *ptr = map[i+17] = buf + i * (len+1);
00119                 for (j=0; j<len; j++)
00120                 {
00121                         int mid = len/2, x = i - mid, y = j - mid;
00122                         float q = (x * x + y * y) / rad / rad;
00123                         int  k;
00124                         if (q<1) *ptr++ = '0';else
00125                         for(k=1; k<16; k++)
00126                                 if ((q >= 1 + (k-1) / grad && q < 1 + k/grad) || k == 15)
00127                                 { *ptr++ = hex[k]; break; }
00128                 }
00129                 *ptr++ = 0;
00130         }
00131         map[17+len] = NULL;
00132         return map;
00133 }
00134 
00135 static void rgbmap_ball_gen_real (int len, unsigned char *rgbbuf, int fg, float rad, float grad, float midx, float midy)
00136 {
00137         int i, j;
00138         unsigned char *bufp = rgbbuf;
00139         for (i=0; i<len; i++)
00140         for (j=0; j<len; j++)
00141         {
00142                 float x = i - midx, y = j - midy;
00143                 float q = (x * x + y * y) / rad / rad;
00144                 int bg = (bufp[0] << 16) + (bufp[1] << 8) + bufp[2];
00145                 int color = q < 1 ? fg : pixmap_get_color (fg, bg, (q - 1) * grad / 16);
00146                 *bufp++ = color >> 16;
00147                 *bufp++ = (color >> 8) & 0xFF;
00148                 *bufp++ = color & 0xFF;
00149         }
00150 }
00151 
00152 void rgbmap_square_gen (int len, unsigned char *rgbbuf, int fg, int bg, float side)
00153 {
00154         int i, j;
00155         unsigned char *bufp = rgbbuf;
00156         for (i=0; i<len; i++)
00157         for (j=0; j<len; j++)
00158         {
00159                 float x = 2*i - len, y = 2*j - len;
00160                 int color;
00161                 if (x < 0) x = -x;
00162                 if (y < 0) y = -y;
00163                 color =  x < side && y < side ? fg : bg;
00164                 *bufp++ = color >> 16;
00165                 *bufp++ = (color >> 8) & 0xFF;
00166                 *bufp++ = color & 0xFF;
00167         }
00168 }
00169 
00170 void rgbmap_ball_gen (int len, unsigned char *rgbbuf, int fg, int bg, float rad, float grad)
00171 {
00172         int i, j;
00173         unsigned char *bufp = rgbbuf;
00174         for (i=0; i<len; i++)
00175         for (j=0; j<len; j++)
00176         {
00177                 *bufp++ = bg >> 16;
00178                 *bufp++ = (bg >> 8) & 0xFF;
00179                 *bufp++ = bg & 0xFF;
00180         }
00181         rgbmap_ball_gen_real (len, rgbbuf, fg, rad, grad, len/2, len/2);
00182 }
00183 
00185 void rgbmap_ball_gen_nobg (int len, unsigned char *rgbbuf, int fg, int bg, float rad, float grad)
00186 {
00187         rgbmap_ball_gen_real (len, rgbbuf, fg, rad, grad, len/2, len/2);
00188 }
00189 
00190 void rgbmap_ball_shadow_gen (int len, unsigned char *rgbbuf, int fg, int bg, float rad, float grad, int shadowlen)
00191 {
00192         int i, j;
00193         unsigned char *bufp = rgbbuf;
00194         int red, green, blue, lighting_color, shadow_color;
00195         float shadow_factor = 0.25;
00196         red   = (fg >> 16) / 4 + 192;
00197         green = ((fg >>  8) & 0xff) / 4 + 192;
00198         blue  = (fg & 0xff) / 4 + 192;
00199         lighting_color = (red << 16) + (green << 8) + blue;
00200         red   = (fg >> 16) * shadow_factor;
00201         green = ((fg >>  8) & 0xff) * shadow_factor;
00202         blue  = (fg & 0xff) * shadow_factor;
00203         shadow_color = (red << 16) + (green << 8) + blue;
00204         for (i=0; i<len; i++)
00205         for (j=0; j<len; j++)
00206         {
00207                 *bufp++ = bg >> 16;
00208                 *bufp++ = (bg >> 8) & 0xFF;
00209                 *bufp++ = bg & 0xFF;
00210         }
00211         rgbmap_ball_gen_real (len, rgbbuf, shadow_color, rad, grad, 
00212                         (len + shadowlen)/2, (len + shadowlen)/2);
00213         rgbmap_ball_gen_real (len, rgbbuf, lighting_color, rad, grad, 
00214                         (len - 1.5 * shadowlen)/2, (len - 1.5 * shadowlen)/2);
00215         rgbmap_ball_gen_real (len, rgbbuf, fg, rad, grad, 
00216                         (len - shadowlen)/2, (len - shadowlen)/2);
00217 }
00218 
00219         
00221 char ** pixmap_header_gen(int len, char *pixbuf, int fg, int bg)
00222 {
00223         char **map = pixmap_map;
00224         char *buf = pixbuf;
00225         static char colbuf[18][20];
00226         int i, j;
00227         for(i=0; i<18; i++) map[i] = colbuf[i];
00228         g_snprintf(map[0], 20, "%d %d 16 1", len, len);
00229         for(i=0; i<16; i++)
00230         {
00231                 g_snprintf (map[i+1], 20, "%c c #%s", hex[i],
00232                                 pixmap_get_hex_color(fg, bg, i / 15.0));
00233         }
00234         for (i=0; i<len; i++)
00235                 map[i+17] = buf + i * (len+1);
00236         map[17+len] = NULL;
00237         return map;
00238 }
00239 
00240 
00242 
00243 char ** pixmap_die_gen(int len, char *pixbuf, int fg, int bg, float rad, float grad, int num)
00244 {
00245         char **map = pixmap_map;
00246         char *buf = pixbuf;
00247         static char colbuf[18][20];
00248         int i, j, k;
00249         float cenx[6][6] = 
00250         {
00251                 { 0.5 },
00252                 { 0.25, 0.75},
00253                 { 0.2, 0.5, 0.8 },
00254                 { 0.25, 0.25, 0.75, 0.75 },
00255                 { 0.2, 0.2, 0.5, 0.8, 0.8 },
00256                 { 0.25, 0.25, 0.25, 0.75, 0.75, 0.75 }
00257         };
00258         float ceny[6][6] = 
00259         {
00260                 { 0.5 },
00261                 { 0.25, 0.75},
00262                 { 0.2, 0.5, 0.8 },
00263                 { 0.25, 0.75, 0.25, 0.75 },
00264                 { 0.2, 0.8, 0.5, 0.2, 0.8 },
00265                 { 0.2, 0.5, 0.8, 0.2, 0.5, 0.8 }
00266         };
00267         for(i=0; i<18; i++) map[i] = colbuf[i];
00268         g_snprintf(map[0], 20, "%d %d 16 1", len, len);
00269         for(i=0; i<16; i++)
00270         {
00271                 g_snprintf (map[i+1], 20, "%c c #%s", hex[i],
00272                                 pixmap_get_hex_color(fg, bg, i / 15.0));
00273         }
00274         for (i=0; i<len; i++)
00275         {
00276                 char *ptr = map[i+17] = buf + i * (len+1);
00277                 memset (ptr, 'F', len);
00278                 ptr[len] = 0;
00279                 for (k=0; k<num; k++)
00280                 {
00281                         float midx = cenx[num-1][k] * len;
00282                         float midy = (1 - ceny[num-1][k]) * len;
00283                         for (j=0; j<len; j++)
00284                         {
00285                                 float x = i - midx, y = j - midy;
00286                                 float q = (x * x + y * y) / rad / rad;
00287                                 int  k;
00288                                 if (q < 1) {ptr[j] = '0';}
00289                                 else
00290                                 for(k=1; k<16; k++)
00291                                         if ((q >= 1 + (k-1) / grad && q < 1 + k/grad))
00292                                         { ptr[j] = hex[k]; break; }
00293                         }
00294                 }
00295         }
00296         map[17+len] = NULL;
00297         return map;
00298 }
00299