123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- /* $Id: gen_minimap.c,v 1.23 2001/04/29 15:41:05 glop Exp $ */
- #include "client.h"
- #define OFFSET(X, Y) (((X) + (Y) * MINI_MAP_SIZE) * 4)
- #define RED(X,Y) (OFFSET(X, Y) + 0)
- #define GREEN(X,Y) (OFFSET(X, Y) + 1)
- #define BLUE(X,Y) (OFFSET(X, Y) + 2)
- #define ID(X,Y) (OFFSET(X, Y) + 3)
- #define RED_COLOR(map, id) ((map)->players[(id)]->colors[2])
- #define GREEN_COLOR(map, id) ((map)->players[(id)]->colors[1])
- #define BLUE_COLOR(map, id) ((map)->players[(id)]->colors[0])
- #define CONV_X(map, X) (((X) * MINI_MAP_SIZE) / ((map)->sizex + 0.1))
- #define CONV_Y(map, Y) (((Y) * MINI_MAP_SIZE) / ((map)->sizey + 0.1))
- static void mm_plot_point_ex(guchar *minimap, guchar id, guchar sat, int x, int y,
- guchar r, guchar g, guchar b)
- {
- int temp;
- if ((x < 0) || (x >= MINI_MAP_SIZE))
- return;
- if ((y < 0) || (y >= MINI_MAP_SIZE))
- return;
- if (minimap[ID(x, y)] == id)
- return;
- temp = minimap[RED(x,y)];
- if (temp < sat)
- {
- temp += r;
- if (temp > sat)
- temp = sat;
- minimap[RED(x,y)] = temp;
- }
- temp = minimap[GREEN(x,y)];
- if (temp < sat)
- {
- temp += g;
- if (temp > sat)
- temp = sat;
- minimap[GREEN(x,y)] = temp;
- }
-
- temp = minimap[BLUE(x,y)];
- if (temp < sat)
- {
- temp += b;
- if (temp > sat)
- temp = sat;
- minimap[BLUE(x,y)] = temp;
- }
- minimap[ID(x, y)] = id;
- }
- static void mm_plot_point(guchar *minimap, int x, int y,
- guchar r, guchar g, guchar b)
- {
- int temp;
- if ((x < 0) || (x >= MINI_MAP_SIZE))
- return;
- if ((y < 0) || (y >= MINI_MAP_SIZE))
- return;
- temp = minimap[RED(x,y)] + r;
- if (temp > 0xFF)
- temp = 0xFF;
- minimap[RED(x,y)] = temp;
- temp = minimap[GREEN(x,y)] + g;
- if (temp > 0xFF)
- temp = 0xFF;
- minimap[GREEN(x,y)] = temp;
- temp = minimap[BLUE(x,y)] + b;
- if (temp > 0xFF)
- temp = 0xFF;
- minimap[BLUE(x,y)] = temp;
- }
- static void mm_plot_line(guchar *minimap, int x1, int y1, int x2, int y2,
- guchar r, guchar g, guchar b)
- {
- float a;
- int diffx, diffy;
- int x, y;
- diffx = x1 - x2;
- diffy = y1 - y2;
- if (!diffx && !diffy)
- mm_plot_point(minimap, x1, y2, r, g, b);
- else
- {
- if (ABS(diffx) > ABS(diffy))
- {
- a = (float)diffy / diffx;
- if (x1 > x2)
- {
- x = x2;
- x2 = x1;
- x1 = x;
- y = y1;
- y1 = y2;
- y2 = y;
- }
- else
- x = x1;
- while (x != x2)
- {
- mm_plot_point(minimap, x, y1 + (x - x1) * a, r, g, b);
- x++;
- }
- }
- else
- {
- a = (float)diffx / diffy;
- if (y1 > y2)
- {
- y = y2;
- y2 = y1;
- y1 = y;
- x = x1;
- x1 = x2;
- x2 = x;
- }
- else
- y = y1;
- while (y != y2)
- {
- mm_plot_point(minimap, x1 + (y - y1) * a, y, r, g, b);
- y++;
- }
- }
- }
- }
- static float mm_rotate_x(float x, float y, float cs, float sn)
- {
- return cs * x + sn * y;
- }
- static float mm_rotate_y(float x, float y, float cs, float sn)
- {
- return cs * y - sn * x;
- }
- static int mm_distance(int x1, int y1, int x2, int y2)
- {
- return (SQR(x2 - x1) + SQR(y2 - y1));
- }
- static void mm_plot_triangle(guchar *minimap, guchar id, guchar sat,
- int x1, int y1, int x2, int y2, int x3, int y3,
- int dist, guchar cr, guchar cg, guchar cb)
- {
- int swap;
- float delta1, delta2, delta3;
- float xa, xb;
- int x, y;
- int memx = x1, memy = y1;
- if (y1 > y2)
- {
- swap = x1;
- x1 = x2;
- x2 = swap;
- swap = y1;
- y1 = y2;
- y2 = swap;
- }
- if (y1 > y3)
- {
- swap = x3;
- x3 = x1;
- x1 = swap;
- swap = y1;
- y1 = y3;
- y3 = swap;
- }
-
- if (y2 > y3)
- {
- swap = x3;
- x3 = x2;
- x2 = swap;
-
- swap = y3;
- y3 = y2;
- y2 = swap;
- }
- /* determination des coefficients directeurs */
- if (y1 != y3)
- delta1 = ((float)x1-x3)/(y1-y3);
- else
- delta1 = 0;
-
- if (y1 != y2)
- delta2 = ((float)x2-x1)/(y2-y1);
- else
- delta2 = 0;
-
- if (y2 != y3)
- delta3 = ((float)x3-x2)/(y3-y2);
- else
- delta3 = 0;
-
- /* PremiŠre partie du triangle ( tracage des section horizontale) */
- xa = x1;
- xb = x1;
- if (y1 != y2)
- {
- if (delta1 < delta2)
- for (y = y1; y < y2; y++)
- {
- xa = xa + delta1;
- xb = xb + delta2;
- for (x = xa; x < xb; x++)
- if (mm_distance(memx, memy, x, y) <= dist)
- mm_plot_point_ex(minimap, id, sat, x, y, cr, cg, cb);
- }
- else
- for (y = y1; y < y2; y++)
- {
- xa = xa + delta1;
- xb = xb + delta2;
- for (x = xb; x < xa; x++)
- if (mm_distance(memx, memy, x, y) <= dist)
- mm_plot_point_ex(minimap, id, sat, x, y, cr, cg, cb);
- }
- }
- else
- xb = x2;
- /* Deuxieme partie du triangle ( tracage des section horizontale) */
- if (y2 != y3)
- {
- if (delta3 < delta1)
- for (y = y2; y < y3; y++)
- {
- xa = xa + delta1;
- xb = xb + delta3;
- for (x = xa; x < xb; x++)
- if (mm_distance(memx, memy, x, y) <= dist)
- mm_plot_point_ex(minimap, id, sat, x, y, cr, cg, cb);
- }
- else
- for (y = y2; y < y3; y++)
- {
- xa = xa + delta1;
- xb = xb + delta3;
- for (x = xb; x < xa; x++)
- if (mm_distance(memx, memy, x, y) <= dist)
- mm_plot_point_ex(minimap, id, sat, x, y, cr, cg, cb);
- }
- }
- }
- static void mm_plot_cone(guchar *minimap, guchar id, guchar sat,
- float x1, float y1, float x2, float y2,
- float angle, guchar r, guchar g, guchar b)
- {
- float cs, sn, csi;
- float x, y, xc, xd, yc, yd;
- gboolean call_sub = FALSE;
- x = x2 - x1;
- y = y2 - y1;
- if (angle > M_PI_2)
- {
- call_sub = TRUE;
- angle /= 2;
- }
- cs = cos(angle / 2);
- sn = sin(angle / 2);
- xc = mm_rotate_x(x, y, cs, sn);
- xd = mm_rotate_x(x, y, cs, -sn);
- yc = mm_rotate_y(x, y, cs, sn);
- yd = mm_rotate_y(x, y, cs, -sn);
- if (call_sub)
- {
- mm_plot_cone(minimap, id, sat, x1, y1, xc + x1, yc + y1, angle, r, g, b);
- mm_plot_cone(minimap, id, sat, x1, y1, xd + x1, yd + y1, angle, r, g, b);
- return;
- }
- csi = 1 / cs;
- xc = xc * csi + x1;
- xd = xd * csi + x1;
- yc = yc * csi + y1;
- yd = yd * csi + y1;
- mm_plot_triangle(minimap, id, sat, x1, y1, xc, yc, xd, yd,
- mm_distance(x1, y1, x2, y2), r, g, b);
- }
- static void mm_plot_r4d2(const map_t *map, obj_t *obj, guchar *minimap)
- {
- int x = CONV_X(map, obj->posx);
- int y = CONV_Y(map, obj->posy);
- guchar *couleurs;
- if ((obj->team_id == 0) || (obj->team_id > map->nb_players))
- return;
- couleurs = map->players[obj->team_id]->colors;
- mm_plot_point(minimap, x, y,
- couleurs[2],
- couleurs[1],
- couleurs[0]);
- mm_plot_point(minimap, x+1, y,
- couleurs[2],
- couleurs[1],
- couleurs[0]);
- mm_plot_point(minimap, x, y+1,
- couleurs[2],
- couleurs[1],
- couleurs[0]);
- mm_plot_point(minimap, x-1, y,
- couleurs[2],
- couleurs[1],
- couleurs[0]);
- mm_plot_point(minimap, x, y-1,
- couleurs[2],
- couleurs[1],
- couleurs[0]);
- }
- static void mm_plot_akx(const map_t *map, obj_t *obj, guchar *minimap)
- {
- int id = obj->team_id;
- int x, y, x2, y2;
- int dx, dy;
- x = CONV_X(map, obj->posx);
- y = CONV_Y(map, obj->posy);
- x2 = CONV_X(map, obj->tx);
- y2 = CONV_Y(map, obj->ty);
- if (id > map->nb_players)
- id = 0;
- mm_plot_point(minimap, x, y, 0xFF, 0xFF, 0xFF);
- for (dx = -2; dx <= 2; dx++)
- for (dy = -2; dy <= 2; dy++)
- mm_plot_point(minimap, x + dx, y + dy,
- map->players[id]->colors[2],
- map->players[id]->colors[1],
- map->players[id]->colors[0]);
- /* affichage pulse */
- if (obj->action == act_akx_pulse)
- mm_plot_cone(minimap, 1+(guchar)obj->id, PULSE_SAT, x, y, x2, y2,
- obj->angle,
- map->players[id]->colors[2] / DIVID_PULSE_MINI,
- map->players[id]->colors[1] / DIVID_PULSE_MINI,
- map->players[id]->colors[0] / DIVID_PULSE_MINI);
-
- /* affichage link */
- if (obj->action == act_akx_link)
- mm_plot_line(minimap, x, y,
- CONV_X(map, map->objects[obj->target]->posx),
- CONV_Y(map, map->objects[obj->target]->posy),
- map->players[id]->colors[2],
- map->players[id]->colors[1],
- map->players[id]->colors[0]);
- }
- /* Zone de la vue principale */
- static void mm_plot_rectangle(guchar *minimap, const conf_t *conf)
- {
- int x1, y1, x2, y2;
- float ratiox, ratioy;
- int y, l, *buf;
- ratiox = MINI_MAP_SIZE / (conf->map->sizex * conf->big_zoom);
- ratioy = MINI_MAP_SIZE / (conf->map->sizey * conf->big_zoom);
- x1 = conf->big_ofs_x * ratiox;
- y1 = conf->big_ofs_y * ratioy;
- x2 = x1 + MAP_SIZE * ratiox;
- y2 = y1 + MAP_SIZE * ratioy;
- x1 = CLAMP(x1, 0, MINI_MAP_SIZE - 1);
- x2 = CLAMP(x2, 0, MINI_MAP_SIZE - 1);
- y1 = CLAMP(y1, 0, MINI_MAP_SIZE - 1);
- y2 = CLAMP(y2, 0, MINI_MAP_SIZE - 1);
- buf = (void *) minimap;
- memset(buf + x1 + y1 * MINI_MAP_SIZE, 255, (x2 - x1) * 4);
- memset(buf + x1 + y2 * MINI_MAP_SIZE, 255, (x2 - x1) * 4);
- memset(&l, 255, 4);
- for (y = y1 + 1; y < y2; y++)
- {
- buf[x1 + y * MINI_MAP_SIZE] = l;
- buf[x2 + y * MINI_MAP_SIZE] = l;
- }
- }
- guchar *gen_minimap(const conf_t *conf, gboolean force)
- {
- static guchar *minimap = NULL;
- int cpt;
- obj_t *obj;
- if (minimap == NULL)
- {
- minimap = g_malloc(4 * SQR(MINI_MAP_SIZE));
- bzero(minimap, SQR(MINI_MAP_SIZE) * 4);
- }
- if (!force)
- return minimap;
- if (conf->map == NULL)
- return minimap;
- bzero(minimap, SQR(MINI_MAP_SIZE) * 4);
- for (cpt = 0; cpt < conf->map->nb_objects; cpt++)
- {
- obj = conf->map->objects[cpt];
- switch (obj->type)
- {
- case obj_r4d2 :
- mm_plot_r4d2(conf->map, obj, minimap);
- break;
- case obj_akx :
- mm_plot_akx(conf->map, obj, minimap);
- break;
- }
- }
- mm_plot_rectangle(minimap, conf);
- return minimap;
- }
- static guchar my_creneau(int val)
- {
- if (val >= 0)
- return CLAMP((120 - val) * 0xFF / 120, 0, 0xFF);
- else
- return CLAMP((120 + val) * 0xFF / 120, 0, 0xFF);
- }
- void gen_colors(int id, int nbr, player_t *play)
- {
- int angle;
- angle = (360 * id) / nbr; /* position => angle dans spectre */
- if (angle > 180)
- angle = angle - 360;
- play->colors[2] = my_creneau(angle);
- play->colors[1] = my_creneau(angle - 120);
- play->colors[0] = my_creneau(angle + 120);
- play->gdkcol = g_malloc(sizeof(*(play->gdkcol)));
- pl_make_color(play->gdkcol,
- play->colors[2], play->colors[1], play->colors[0]);
- }
|