gen_bigmap.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. /* $Id: gen_bigmap.c,v 1.22 2001/04/29 22:07:44 kilobug Exp $ */
  2. #include "client.h"
  3. #define OFFSET2(SX, X, Y) (((X) + (Y) * (SX)) * 4)
  4. #define IRD(SX, X,Y) (OFFSET2(SX, X, Y) + 0)
  5. #define IGR(SX, X,Y) (OFFSET2(SX, X, Y) + 1)
  6. #define IBL(SX, X,Y) (OFFSET2(SX, X, Y) + 2)
  7. #define MASK(SX, X,Y) (OFFSET2(SX, X, Y) + 3)
  8. #define OFFSET(X, Y) (OFFSET2(MAP_SIZE, X, Y))
  9. #define RED(X,Y) (OFFSET(X, Y) + 0)
  10. #define GREEN(X,Y) (OFFSET(X, Y) + 1)
  11. #define BLUE(X,Y) (OFFSET(X, Y) + 2)
  12. #define ID(X,Y) (OFFSET(X, Y) + 3)
  13. #define RED_COLOR(map, id) ((map)->players[(id)]->colors[2])
  14. #define GREEN_COLOR(map, id) ((map)->players[(id)]->colors[1])
  15. #define BLUE_COLOR(map, id) ((map)->players[(id)]->colors[0])
  16. #define CONV_X(map, X) (((X) * MAP_SIZE) / ((map)->sizex + 0.1))
  17. #define CONV_Y(map, Y) (((Y) * MAP_SIZE) / ((map)->sizey + 0.1))
  18. static void bm_plot_point_ex(guchar *bigmap, guchar id, int x,
  19. int y, int r, int g, int b)
  20. {
  21. int offset;
  22. offset = OFFSET(x, y);
  23. if (bigmap[offset + 3] == id)
  24. return;
  25. bigmap[offset + 3] = id;
  26. bigmap[offset + 0] = gl_config->convtb[bigmap[offset + 0] + r * 256];
  27. bigmap[offset + 1] = gl_config->convtb[bigmap[offset + 1] + g * 256];
  28. bigmap[offset + 2] = gl_config->convtb[bigmap[offset + 2] + b * 256];
  29. }
  30. static void bm_plot_point(guchar *bigmap, int x, int y,
  31. guchar r, guchar g, guchar b)
  32. {
  33. int temp;
  34. if ((x < 0) || (x >= MAP_SIZE))
  35. return;
  36. if ((y < 0) || (y >= MAP_SIZE))
  37. return;
  38. temp = bigmap[RED(x,y)] + r;
  39. if (temp > 0xFF)
  40. temp = 0xFF;
  41. bigmap[RED(x,y)] = temp;
  42. temp = bigmap[GREEN(x,y)] + g;
  43. if (temp > 0xFF)
  44. temp = 0xFF;
  45. bigmap[GREEN(x,y)] = temp;
  46. temp = bigmap[BLUE(x,y)] + b;
  47. if (temp > 0xFF)
  48. temp = 0xFF;
  49. bigmap[BLUE(x,y)] = temp;
  50. }
  51. static void bm_plot_line(guchar *bigmap, int x1, int y1, int x2, int y2,
  52. guchar r, guchar g, guchar b)
  53. {
  54. float a;
  55. int diffx, diffy;
  56. int x, y;
  57. diffx = x1 - x2;
  58. diffy = y1 - y2;
  59. if (!diffx && !diffy)
  60. bm_plot_point(bigmap, x1, y2, r, g, b);
  61. else
  62. {
  63. if (ABS(diffx) > ABS(diffy))
  64. {
  65. a = (float)diffy / diffx;
  66. if (x1 > x2)
  67. {
  68. x = x2;
  69. x2 = x1;
  70. x1 = x;
  71. y = y1;
  72. y1 = y2;
  73. y2 = y;
  74. }
  75. else
  76. x = x1;
  77. while (x != x2)
  78. {
  79. bm_plot_point(bigmap, x, y1 + (x - x1) * a, r, g, b);
  80. x++;
  81. }
  82. }
  83. else
  84. {
  85. a = (float)diffx / diffy;
  86. if (y1 > y2)
  87. {
  88. y = y2;
  89. y2 = y1;
  90. y1 = y;
  91. x = x1;
  92. x1 = x2;
  93. x2 = x;
  94. }
  95. else
  96. y = y1;
  97. while (y != y2)
  98. {
  99. bm_plot_point(bigmap, x1 + (y - y1) * a, y, r, g, b);
  100. y++;
  101. }
  102. }
  103. }
  104. }
  105. static float bm_rotate_x(float x, float y, float cs, float sn)
  106. {
  107. return cs * x + sn * y;
  108. }
  109. static float bm_rotate_y(float x, float y, float cs, float sn)
  110. {
  111. return cs * y - sn * x;
  112. }
  113. static int bm_distance(int x1, int y1, int x2, int y2)
  114. {
  115. return (SQR(x2 - x1) + SQR(y2 - y1));
  116. }
  117. static void bm_plot_triangle(guchar *bigmap, guchar id,
  118. int x1, int y1, int x2, int y2, int x3, int y3,
  119. int dist, guchar cr, guchar cg, guchar cb)
  120. {
  121. int swap;
  122. float delta1, delta2, delta3;
  123. float xa, xb, txa, txb;
  124. int x, y, begy, endy;
  125. int memx = x1, memy = y1;
  126. int rac;
  127. if (y1 > y2)
  128. {
  129. swap = x1;
  130. x1 = x2;
  131. x2 = swap;
  132. swap = y1;
  133. y1 = y2;
  134. y2 = swap;
  135. }
  136. if (y1 > y3)
  137. {
  138. swap = x3;
  139. x3 = x1;
  140. x1 = swap;
  141. swap = y1;
  142. y1 = y3;
  143. y3 = swap;
  144. }
  145. if (y2 > y3)
  146. {
  147. swap = x3;
  148. x3 = x2;
  149. x2 = swap;
  150. swap = y3;
  151. y3 = y2;
  152. y2 = swap;
  153. }
  154. /* determination des coefficients directeurs */
  155. if (y1 != y3)
  156. delta1 = ((float)x1-x3)/(y1-y3);
  157. else
  158. delta1 = 0;
  159. if (y1 != y2)
  160. delta2 = ((float)x2-x1)/(y2-y1);
  161. else
  162. delta2 = 0;
  163. if (y2 != y3)
  164. delta3 = ((float)x3-x2)/(y3-y2);
  165. else
  166. delta3 = 0;
  167. /* PremiŠre partie du triangle ( tracage des section horizontale) */
  168. xa = x1;
  169. xb = x1;
  170. if (y1 != y2)
  171. {
  172. if (y1 < 0)
  173. {
  174. xa -= delta1 * y1;
  175. xb -= delta2 * y1;
  176. begy = 0;
  177. }
  178. else
  179. begy = y1;
  180. if (y2 > (MAP_SIZE-1))
  181. endy = MAP_SIZE-1;
  182. else
  183. endy = y2;
  184. if (delta1 < delta2)
  185. for (y = begy; y < endy; y++)
  186. {
  187. xa = xa + delta1;
  188. xb = xb + delta2;
  189. txa = MAX(0, xa);
  190. txb = MIN(MAP_SIZE-1, xb);
  191. rac = sqrt(dist - SQR(y - memy));
  192. txa = MAX(txa, memx - rac);
  193. txb = MIN(txb, memx + rac);
  194. for (x = txa; x < txb; x++)
  195. bm_plot_point_ex(bigmap, id, x, y, cr, cg, cb);
  196. }
  197. else
  198. for (y = begy; y < endy; y++)
  199. {
  200. xa = xa + delta1;
  201. xb = xb + delta2;
  202. txb = MAX(0, xb);
  203. txa = MIN(MAP_SIZE-1, xa);
  204. rac = sqrt(dist - SQR(y - memy));
  205. txb = MAX(txb, memx - rac);
  206. txa = MIN(txa, memx + rac);
  207. for (x = txb; x < txa; x++)
  208. bm_plot_point_ex(bigmap, id, x, y, cr, cg, cb);
  209. }
  210. xa = x1 + delta1 * (y2 - y1);
  211. xb = x1 + delta2 * (y2 - y1);
  212. }
  213. else
  214. xb = x2;
  215. /* Deuxieme partie du triangle ( tracage des section horizontale) */
  216. if (y2 != y3)
  217. {
  218. if (y2 < 0)
  219. {
  220. xa -= delta1 * y2;
  221. xb -= delta3 * y2;
  222. begy = 0;
  223. }
  224. else
  225. begy = y2;
  226. if (y3 > (MAP_SIZE-1))
  227. endy = MAP_SIZE-1;
  228. else
  229. endy = y3;
  230. if (delta3 < delta1)
  231. for (y = begy; y < endy; y++)
  232. {
  233. xa = xa + delta1;
  234. xb = xb + delta3;
  235. txa = MAX(0, xa);
  236. txb = MIN(MAP_SIZE-1, xb);
  237. rac = sqrt(dist - SQR(y - memy));
  238. txa = MAX(txa, memx - rac);
  239. txb = MIN(txb, memx + rac);
  240. for (x = txa; x < txb; x++)
  241. bm_plot_point_ex(bigmap, id, x, y, cr, cg, cb);
  242. }
  243. else
  244. for (y = begy; y < endy; y++)
  245. {
  246. xa = xa + delta1;
  247. xb = xb + delta3;
  248. txb = MAX(0, xb);
  249. txa = MIN(MAP_SIZE-1, xa);
  250. rac = sqrt(dist - SQR(y - memy));
  251. txb = MAX(txb, memx - rac);
  252. txa = MIN(txa, memx + rac);
  253. for (x = txb; x < txa; x++)
  254. bm_plot_point_ex(bigmap, id, x, y, cr, cg, cb);
  255. }
  256. }
  257. }
  258. static void bm_plot_cone(guchar *bigmap, guchar id,
  259. float x1, float y1, float x2, float y2,
  260. float angle, guchar r, guchar g, guchar b)
  261. {
  262. float cs, sn, csi;
  263. float x, y, xc, xd, yc, yd;
  264. gboolean call_sub = FALSE;
  265. x = x2 - x1;
  266. y = y2 - y1;
  267. if (angle > M_PI_2)
  268. {
  269. call_sub = TRUE;
  270. angle /= 2;
  271. }
  272. cs = cos(angle / 2);
  273. sn = sin(angle / 2);
  274. xc = bm_rotate_x(x, y, cs, sn);
  275. xd = bm_rotate_x(x, y, cs, -sn);
  276. yc = bm_rotate_y(x, y, cs, sn);
  277. yd = bm_rotate_y(x, y, cs, -sn);
  278. if (call_sub)
  279. {
  280. bm_plot_cone(bigmap, id, x1, y1, xc + x1, yc + y1, angle, r, g, b);
  281. bm_plot_cone(bigmap, id, x1, y1, xd + x1, yd + y1, angle, r, g, b);
  282. return;
  283. }
  284. csi = 1 / cs;
  285. xc = xc * csi + x1;
  286. xd = xd * csi + x1;
  287. yc = yc * csi + y1;
  288. yd = yd * csi + y1;
  289. bm_plot_triangle(bigmap, id, x1, y1, xc, yc, xd, yd,
  290. bm_distance(x1, y1, x2, y2), r, g, b);
  291. }
  292. static void plot_sprite(guchar *bigmap, const image_t *img, int x, int y)
  293. {
  294. int x1, y1, sx, sy, ex, ey;
  295. const int *src;
  296. int *dst;
  297. if (img == NULL)
  298. return;
  299. x -= img->sx / 2;
  300. y -= img->sy / 2;
  301. if ((x + img->sx < 0) || (x >= MAP_SIZE))
  302. return;
  303. if ((y + img->sy < 0) || (y >= MAP_SIZE))
  304. return;
  305. src = (void *) img->data;
  306. dst = (void *) bigmap;
  307. dst += x + y * MAP_SIZE;
  308. sy = MAX(-y, 0);
  309. sx = MAX(-x, 0);
  310. ey = MIN(img->sy, MAP_SIZE - y);
  311. ex = MIN(img->sx, MAP_SIZE - x);
  312. for (y1 = sy; y1 < ey; y1++)
  313. for (x1 = sx; x1 < ex; x1++)
  314. if (img->data[MASK(img->sx, x1, y1)] == 0)
  315. dst[y1 * MAP_SIZE + x1] = src[y1 * img->sx + x1];
  316. }
  317. static void bm_plot_object(const conf_t *conf, const obj_t *obj,
  318. guchar *bigmap, const image_t *sprite)
  319. {
  320. int x, y;
  321. x = obj->posx * conf->big_zoom - conf->big_ofs_x;
  322. y = obj->posy * conf->big_zoom - conf->big_ofs_y;
  323. plot_sprite(bigmap, sprite, x, y);
  324. }
  325. static void bm_plot_r4d2(const conf_t *conf, const obj_t *obj, guchar *bigmap)
  326. {
  327. int tid;
  328. tid = obj->team_id;
  329. if (tid > conf->map->nb_players)
  330. tid = 0;
  331. bm_plot_object(conf, obj, bigmap, conf->map->players[tid]->r4d2);
  332. }
  333. static void bm_plot_pulse(guchar *bigmap, const conf_t *conf,
  334. const obj_t *obj, guchar *colors)
  335. {
  336. float x, y, x2, y2;
  337. int id;
  338. id = obj->team_id;
  339. x = obj->posx * conf->big_zoom - conf->big_ofs_x;
  340. y = obj->posy * conf->big_zoom - conf->big_ofs_y;
  341. x2 = obj->tx * conf->big_zoom - conf->big_ofs_x;
  342. y2 = obj->ty * conf->big_zoom - conf->big_ofs_y;
  343. bm_plot_cone(bigmap, (guchar)obj->id+1, x, y, x2, y2,
  344. obj->angle,
  345. conf->map->players[id]->colors[2] * 0.3667 * 1.5,
  346. conf->map->players[id]->colors[1] * 0.1864 * 1.5,
  347. conf->map->players[id]->colors[0]);
  348. }
  349. static void bm_plot_link(guchar *bigmap, const conf_t *conf,
  350. const obj_t *obj, guchar *colors)
  351. {
  352. int x, y, x2, y2;
  353. x = obj->posx * conf->big_zoom - conf->big_ofs_x;
  354. y = obj->posy * conf->big_zoom - conf->big_ofs_y;
  355. x2 = conf->map->objects[obj->target]->posx *
  356. conf->big_zoom - conf->big_ofs_x;
  357. y2 = conf->map->objects[obj->target]->posy *
  358. conf->big_zoom - conf->big_ofs_y;
  359. bm_plot_line(bigmap, x, y, x2, y2, colors[2], colors[1], colors[0]);
  360. }
  361. static void bm_plot_akx(const conf_t *conf, const obj_t *obj, guchar *bigmap)
  362. {
  363. int tid;
  364. tid = obj->team_id;
  365. if (tid > conf->map->nb_players)
  366. tid = 0;
  367. bm_plot_object(conf, obj, bigmap, conf->map->players[tid]->akx);
  368. }
  369. static void bm_plot_pulse_link(const conf_t *conf, const obj_t *obj,
  370. guchar *bigmap)
  371. {
  372. int tid;
  373. tid = obj->team_id;
  374. if (tid > conf->map->nb_players)
  375. tid = 0;
  376. /* affichage pulse */
  377. if (obj->action == act_akx_pulse)
  378. bm_plot_pulse(bigmap, conf, obj, conf->map->players[tid]->colors);
  379. /* affichage link */
  380. if (obj->action == act_akx_link)
  381. bm_plot_link(bigmap, conf, obj, conf->map->players[tid]->colors);
  382. }
  383. static void plot_pic_block(guchar *dest, image_t *src, int x, int ox, int oy)
  384. {
  385. int y, size, rox = 0;
  386. int so, rsx;
  387. if (x == 0)
  388. rox = ox;
  389. else
  390. dest += (x * src->sx - ox) * 4;
  391. size = MIN(MAP_SIZE - x * src->sx + ox, src->sx - rox) * 4;
  392. if (size <= 0)
  393. return;
  394. so = (oy * src->sx + rox) * 4;
  395. rsx = src->sx * 4;
  396. for (y = 0; y < src->sy - oy; y++, so += rsx)
  397. memcpy(dest + y * MAP_SIZE * 4, src->data + so, size);
  398. so = rox * 4;
  399. for (; y < src->sy; y++, so += rsx)
  400. memcpy(dest + y * MAP_SIZE * 4, src->data + so, size);
  401. }
  402. static void plot_background(guchar *bigmap, image_t *fond, int ox, int oy)
  403. {
  404. int x, y, size;
  405. if (fond == NULL)
  406. return;
  407. /* Calcul des offsets réels */
  408. oy = oy % (fond->sy);
  409. while (oy < 0)
  410. oy += fond->sy;
  411. ox = ox % (fond->sx);
  412. while (ox < 0)
  413. ox += fond->sx;
  414. /* First block line */
  415. for (x = 0; x <= MAP_SIZE / fond->sx + 1; x++)
  416. plot_pic_block(bigmap, fond, x, ox, oy);
  417. /* Other lines */
  418. for (y = 1; y <= MAP_SIZE / fond->sy; y++)
  419. {
  420. size = MAP_SIZE * MIN(fond->sy, MAP_SIZE - y * fond->sy) * 4;
  421. memcpy(bigmap + y * fond->sy * MAP_SIZE * 4, bigmap, size);
  422. }
  423. }
  424. guchar *gen_bigmap(conf_t *conf, gboolean force)
  425. {
  426. int cpt;
  427. obj_t *obj;
  428. image_t *background;
  429. if (conf->big_radar)
  430. return gen_bigmap2(conf, force);
  431. background = conf->background;
  432. if (conf->map != NULL)
  433. if (conf->map->background != NULL)
  434. background = conf->map->background;
  435. if (conf->screen == NULL)
  436. {
  437. conf->screen = g_malloc(4 * SQR(MAP_SIZE));
  438. plot_background(conf->screen, background, conf->big_ofs_x,
  439. conf->big_ofs_y);
  440. }
  441. if (!force)
  442. return conf->screen;
  443. if (conf->map == NULL)
  444. return conf->screen;
  445. plot_background(conf->screen, background, conf->big_ofs_x,
  446. conf->big_ofs_y);
  447. if (conf->big_pulse)
  448. for (cpt = 0; cpt < conf->map->nb_objects; cpt++)
  449. {
  450. obj = conf->map->objects[cpt];
  451. if (obj->type == obj_akx)
  452. bm_plot_pulse_link(conf, obj, conf->screen);
  453. }
  454. for (cpt = 0; cpt < conf->map->nb_objects; cpt++)
  455. {
  456. obj = conf->map->objects[cpt];
  457. switch (obj->type)
  458. {
  459. case obj_r4d2 :
  460. bm_plot_r4d2(conf, obj, conf->screen);
  461. break;
  462. case obj_akx :
  463. bm_plot_akx(conf, obj, conf->screen);
  464. break;
  465. }
  466. }
  467. return conf->screen;
  468. }