1 /* ---------------------------------------------------------------------- *
2 * pixmap.c
3 * This file is part of lincity.
4 * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
5 * ---------------------------------------------------------------------- */
6 /* The pixmap contains only the main screen, not the border.
7 * When pix doubled, pixmap does contain the doubled pixels.
8 * ---------------------------------------------------------------------- */
9 #include "lcconfig.h"
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <assert.h>
13 #include <math.h>
14 #include "lcstring.h"
15
16 #include "lin-city.h"
17 #include "lctypes.h"
18 #include "cliglobs.h"
19 #include "pixmap.h"
20
21 #if defined (LC_X11)
22 #include <X11/Xlib.h>
23 #include <X11/Xatom.h>
24 #include <X11/Xutil.h>
25 #include <X11/keysym.h>
26 #include <X11/keysymdef.h>
27 #include "lcx11.h"
28 #endif
29
30
31 #define USE_IMAGES 1
32
33 /* ---------------------------------------------------------------------- *
34 * Private global variables
35 * ---------------------------------------------------------------------- */
36 char* pixmap = NULL;
37 int pixmap_height = 0;
38 int pixmap_width = 0;
39
40
41 /* ---------------------------------------------------------------------- *
42 * Public functions
43 * ---------------------------------------------------------------------- */
44 #ifdef USE_PIXMAPS
45 void
init_pixmaps()46 init_pixmaps ()
47 {
48 int i;
49 for (i = 1; i < NUM_OF_TYPES; i++) {
50 icon_pixmap[i] = 0;
51 }
52
53 init_icon_pixmap (CST_GREEN);
54 /* powerlines */
55 init_icon_pixmap (CST_POWERL_H_L);
56 init_icon_pixmap (CST_POWERL_V_L);
57 init_icon_pixmap (CST_POWERL_LD_L);
58 init_icon_pixmap (CST_POWERL_RD_L);
59 init_icon_pixmap (CST_POWERL_LU_L);
60 init_icon_pixmap (CST_POWERL_RU_L);
61 init_icon_pixmap (CST_POWERL_LDU_L);
62 init_icon_pixmap (CST_POWERL_LDR_L);
63 init_icon_pixmap (CST_POWERL_LUR_L);
64 init_icon_pixmap (CST_POWERL_UDR_L);
65 init_icon_pixmap (CST_POWERL_LUDR_L);
66 prog_box ("", 6);
67 init_icon_pixmap (CST_POWERL_H_D);
68 init_icon_pixmap (CST_POWERL_V_D);
69 init_icon_pixmap (CST_POWERL_LD_D);
70 init_icon_pixmap (CST_POWERL_RD_D);
71 init_icon_pixmap (CST_POWERL_LU_D);
72 init_icon_pixmap (CST_POWERL_RU_D);
73 init_icon_pixmap (CST_POWERL_LDU_D);
74 init_icon_pixmap (CST_POWERL_LDR_D);
75 init_icon_pixmap (CST_POWERL_LUR_D);
76 init_icon_pixmap (CST_POWERL_UDR_D);
77 init_icon_pixmap (CST_POWERL_LUDR_D);
78 /* HT windmills */
79 init_icon_pixmap (CST_WINDMILL_1_G);
80 init_icon_pixmap (CST_WINDMILL_2_G);
81 init_icon_pixmap (CST_WINDMILL_3_G);
82 prog_box ("", 12);
83 init_icon_pixmap (CST_WINDMILL_1_RG);
84 init_icon_pixmap (CST_WINDMILL_2_RG);
85 init_icon_pixmap (CST_WINDMILL_3_RG);
86 init_icon_pixmap (CST_WINDMILL_1_R);
87 init_icon_pixmap (CST_WINDMILL_2_R);
88 init_icon_pixmap (CST_WINDMILL_3_R);
89 /*LT windmills */
90 init_icon_pixmap (CST_WINDMILL_1_W);
91 init_icon_pixmap (CST_WINDMILL_2_W);
92 init_icon_pixmap (CST_WINDMILL_3_W);
93 /* communes */
94 init_icon_pixmap (CST_COMMUNE_1);
95 init_icon_pixmap (CST_COMMUNE_2);
96 init_icon_pixmap (CST_COMMUNE_3);
97 init_icon_pixmap (CST_COMMUNE_4);
98 init_icon_pixmap (CST_COMMUNE_5);
99 prog_box ("", 18);
100 init_icon_pixmap (CST_COMMUNE_6);
101 init_icon_pixmap (CST_COMMUNE_7);
102 init_icon_pixmap (CST_COMMUNE_8);
103 init_icon_pixmap (CST_COMMUNE_9);
104 init_icon_pixmap (CST_COMMUNE_10);
105 init_icon_pixmap (CST_COMMUNE_11);
106 init_icon_pixmap (CST_COMMUNE_12);
107 init_icon_pixmap (CST_COMMUNE_13);
108 init_icon_pixmap (CST_COMMUNE_14);
109 /* farms (3 7 11 and 15 are the only ones needed) */
110 init_icon_pixmap (CST_FARM_O3);
111 init_icon_pixmap (CST_FARM_O7);
112 init_icon_pixmap (CST_FARM_O11);
113 init_icon_pixmap (CST_FARM_O15);
114 /* Lt. Industry */
115 prog_box ("", 24);
116 init_icon_pixmap (CST_INDUSTRY_L_C);
117 init_icon_pixmap (CST_INDUSTRY_L_Q1);
118 init_icon_pixmap (CST_INDUSTRY_L_Q2);
119 init_icon_pixmap (CST_INDUSTRY_L_Q3);
120 init_icon_pixmap (CST_INDUSTRY_L_Q4);
121 init_icon_pixmap (CST_INDUSTRY_L_L1);
122 init_icon_pixmap (CST_INDUSTRY_L_L2);
123 init_icon_pixmap (CST_INDUSTRY_L_L3);
124 init_icon_pixmap (CST_INDUSTRY_L_L4);
125 init_icon_pixmap (CST_INDUSTRY_L_M1);
126 init_icon_pixmap (CST_INDUSTRY_L_M2);
127 init_icon_pixmap (CST_INDUSTRY_L_M3);
128 init_icon_pixmap (CST_INDUSTRY_L_M4);
129 init_icon_pixmap (CST_INDUSTRY_L_H1);
130 init_icon_pixmap (CST_INDUSTRY_L_H2);
131 prog_box ("", 30);
132 init_icon_pixmap (CST_INDUSTRY_L_H3);
133 init_icon_pixmap (CST_INDUSTRY_L_H4);
134 /* Hv. Industry */
135 init_icon_pixmap (CST_INDUSTRY_H_C);
136 init_icon_pixmap (CST_INDUSTRY_H_L1);
137 init_icon_pixmap (CST_INDUSTRY_H_L2);
138 init_icon_pixmap (CST_INDUSTRY_H_L3);
139 init_icon_pixmap (CST_INDUSTRY_H_L4);
140 init_icon_pixmap (CST_INDUSTRY_H_L5);
141 init_icon_pixmap (CST_INDUSTRY_H_L6);
142 init_icon_pixmap (CST_INDUSTRY_H_L7);
143 init_icon_pixmap (CST_INDUSTRY_H_L8);
144 init_icon_pixmap (CST_INDUSTRY_H_M1);
145 init_icon_pixmap (CST_INDUSTRY_H_M2);
146 init_icon_pixmap (CST_INDUSTRY_H_M3);
147 init_icon_pixmap (CST_INDUSTRY_H_M4);
148 prog_box ("", 36);
149 init_icon_pixmap (CST_INDUSTRY_H_M5);
150 init_icon_pixmap (CST_INDUSTRY_H_M6);
151 init_icon_pixmap (CST_INDUSTRY_H_M7);
152 init_icon_pixmap (CST_INDUSTRY_H_M8);
153 init_icon_pixmap (CST_INDUSTRY_H_H1);
154 init_icon_pixmap (CST_INDUSTRY_H_H2);
155 init_icon_pixmap (CST_INDUSTRY_H_H3);
156 init_icon_pixmap (CST_INDUSTRY_H_H4);
157 init_icon_pixmap (CST_INDUSTRY_H_H5);
158 init_icon_pixmap (CST_INDUSTRY_H_H6);
159 init_icon_pixmap (CST_INDUSTRY_H_H7);
160 init_icon_pixmap (CST_INDUSTRY_H_H8);
161 /* water */
162 prog_box ("", 42);
163 init_icon_pixmap (CST_WATER);
164 init_icon_pixmap (CST_WATER_D);
165 init_icon_pixmap (CST_WATER_R);
166 init_icon_pixmap (CST_WATER_U);
167 init_icon_pixmap (CST_WATER_L);
168 init_icon_pixmap (CST_WATER_LR);
169 init_icon_pixmap (CST_WATER_UD);
170 init_icon_pixmap (CST_WATER_LD);
171 init_icon_pixmap (CST_WATER_RD);
172 init_icon_pixmap (CST_WATER_LU);
173 init_icon_pixmap (CST_WATER_UR);
174 init_icon_pixmap (CST_WATER_LUD);
175 init_icon_pixmap (CST_WATER_LRD);
176 init_icon_pixmap (CST_WATER_LUR);
177 init_icon_pixmap (CST_WATER_URD);
178 init_icon_pixmap (CST_WATER_LURD);
179 /* tracks */
180 init_icon_pixmap (CST_TRACK_LR);
181 prog_box ("", 48);
182 init_icon_pixmap (CST_TRACK_LU);
183 init_icon_pixmap (CST_TRACK_LD);
184 init_icon_pixmap (CST_TRACK_UD);
185 init_icon_pixmap (CST_TRACK_UR);
186 init_icon_pixmap (CST_TRACK_DR);
187 init_icon_pixmap (CST_TRACK_LUR);
188 init_icon_pixmap (CST_TRACK_LDR);
189 init_icon_pixmap (CST_TRACK_LUD);
190 init_icon_pixmap (CST_TRACK_UDR);
191 init_icon_pixmap (CST_TRACK_LUDR);
192 /* roads */
193 init_icon_pixmap (CST_ROAD_LR);
194 init_icon_pixmap (CST_ROAD_LU);
195 init_icon_pixmap (CST_ROAD_LD);
196 init_icon_pixmap (CST_ROAD_UD);
197 init_icon_pixmap (CST_ROAD_UR);
198 init_icon_pixmap (CST_ROAD_DR);
199 init_icon_pixmap (CST_ROAD_LUR);
200 init_icon_pixmap (CST_ROAD_LDR);
201 prog_box ("", 54);
202 init_icon_pixmap (CST_ROAD_LUD);
203 init_icon_pixmap (CST_ROAD_UDR);
204 init_icon_pixmap (CST_ROAD_LUDR);
205 /* rail */
206 init_icon_pixmap (CST_RAIL_LR);
207 init_icon_pixmap (CST_RAIL_LU);
208 init_icon_pixmap (CST_RAIL_LD);
209 init_icon_pixmap (CST_RAIL_UD);
210 init_icon_pixmap (CST_RAIL_UR);
211 init_icon_pixmap (CST_RAIL_DR);
212 init_icon_pixmap (CST_RAIL_LUR);
213 init_icon_pixmap (CST_RAIL_LDR);
214 init_icon_pixmap (CST_RAIL_LUD);
215 init_icon_pixmap (CST_RAIL_UDR);
216 init_icon_pixmap (CST_RAIL_LUDR);
217 /* potteries */
218 prog_box ("", 60);
219 init_icon_pixmap (CST_POTTERY_0);
220 init_icon_pixmap (CST_POTTERY_1);
221 init_icon_pixmap (CST_POTTERY_2);
222 init_icon_pixmap (CST_POTTERY_3);
223 init_icon_pixmap (CST_POTTERY_4);
224 init_icon_pixmap (CST_POTTERY_5);
225 init_icon_pixmap (CST_POTTERY_6);
226 init_icon_pixmap (CST_POTTERY_7);
227 init_icon_pixmap (CST_POTTERY_8);
228 init_icon_pixmap (CST_POTTERY_9);
229 init_icon_pixmap (CST_POTTERY_10);
230 /* mills */
231 init_icon_pixmap (CST_MILL_0);
232 init_icon_pixmap (CST_MILL_1);
233 init_icon_pixmap (CST_MILL_2);
234 init_icon_pixmap (CST_MILL_3);
235 init_icon_pixmap (CST_MILL_4);
236 prog_box ("", 66);
237 init_icon_pixmap (CST_MILL_5);
238 init_icon_pixmap (CST_MILL_6);
239 /* blacksmiths */
240 init_icon_pixmap (CST_BLACKSMITH_0);
241 init_icon_pixmap (CST_BLACKSMITH_1);
242 init_icon_pixmap (CST_BLACKSMITH_2);
243 init_icon_pixmap (CST_BLACKSMITH_3);
244 init_icon_pixmap (CST_BLACKSMITH_4);
245 init_icon_pixmap (CST_BLACKSMITH_5);
246 init_icon_pixmap (CST_BLACKSMITH_6);
247 /* residences */
248 init_icon_pixmap (CST_RESIDENCE_LL);
249 init_icon_pixmap (CST_RESIDENCE_ML);
250 init_icon_pixmap (CST_RESIDENCE_HL);
251 init_icon_pixmap (CST_RESIDENCE_LH);
252 init_icon_pixmap (CST_RESIDENCE_MH);
253 init_icon_pixmap (CST_RESIDENCE_HH);
254 /* coal power */
255 init_icon_pixmap (CST_POWERS_COAL_EMPTY);
256 init_icon_pixmap (CST_POWERS_COAL_LOW);
257 prog_box ("", 72);
258 init_icon_pixmap (CST_POWERS_COAL_MED);
259 init_icon_pixmap (CST_POWERS_COAL_FULL);
260 /* substations */
261 init_icon_pixmap (CST_SUBSTATION_R);
262 init_icon_pixmap (CST_SUBSTATION_G);
263 init_icon_pixmap (CST_SUBSTATION_RG);
264 /* markets */
265 init_icon_pixmap (CST_MARKET_EMPTY);
266 init_icon_pixmap (CST_MARKET_LOW);
267 init_icon_pixmap (CST_MARKET_MED);
268 init_icon_pixmap (CST_MARKET_FULL);
269 /* coal mines */
270 init_icon_pixmap (CST_COALMINE_EMPTY);
271 init_icon_pixmap (CST_COALMINE_LOW);
272 init_icon_pixmap (CST_COALMINE_MED);
273 init_icon_pixmap (CST_COALMINE_FULL);
274 /* ore mines */
275 prog_box ("", 78);
276 init_icon_pixmap (CST_OREMINE_1);
277 init_icon_pixmap (CST_OREMINE_2);
278 init_icon_pixmap (CST_OREMINE_3);
279 init_icon_pixmap (CST_OREMINE_4);
280 init_icon_pixmap (CST_OREMINE_5);
281 init_icon_pixmap (CST_OREMINE_6);
282 init_icon_pixmap (CST_OREMINE_7);
283 init_icon_pixmap (CST_OREMINE_8);
284 /* tips */
285 init_icon_pixmap (CST_TIP_0);
286 init_icon_pixmap (CST_TIP_1);
287 init_icon_pixmap (CST_TIP_2);
288 init_icon_pixmap (CST_TIP_3);
289 init_icon_pixmap (CST_TIP_4);
290 init_icon_pixmap (CST_TIP_5);
291 init_icon_pixmap (CST_TIP_6);
292 init_icon_pixmap (CST_TIP_7);
293 init_icon_pixmap (CST_TIP_8);
294 /* rockets */
295 prog_box ("", 84);
296 init_icon_pixmap (CST_ROCKET_1);
297 init_icon_pixmap (CST_ROCKET_2);
298 init_icon_pixmap (CST_ROCKET_3);
299 init_icon_pixmap (CST_ROCKET_4);
300 init_icon_pixmap (CST_ROCKET_5);
301 init_icon_pixmap (CST_ROCKET_6);
302 init_icon_pixmap (CST_ROCKET_7);
303 init_icon_pixmap (CST_ROCKET_FLOWN);
304 /* fire stations */
305 init_icon_pixmap (CST_FIRESTATION_1);
306 init_icon_pixmap (CST_FIRESTATION_2);
307 init_icon_pixmap (CST_FIRESTATION_3);
308 init_icon_pixmap (CST_FIRESTATION_4);
309 init_icon_pixmap (CST_FIRESTATION_5);
310 init_icon_pixmap (CST_FIRESTATION_6);
311 init_icon_pixmap (CST_FIRESTATION_7);
312 init_icon_pixmap (CST_FIRESTATION_8);
313 init_icon_pixmap (CST_FIRESTATION_9);
314 init_icon_pixmap (CST_FIRESTATION_10);
315 /* cricket */
316 prog_box ("", 90);
317 init_icon_pixmap (CST_CRICKET_1);
318 init_icon_pixmap (CST_CRICKET_2);
319 init_icon_pixmap (CST_CRICKET_3);
320 init_icon_pixmap (CST_CRICKET_4);
321 init_icon_pixmap (CST_CRICKET_5);
322 init_icon_pixmap (CST_CRICKET_6);
323 init_icon_pixmap (CST_CRICKET_7);
324 /* fire */
325 init_icon_pixmap (CST_FIRE_1);
326 init_icon_pixmap (CST_FIRE_2);
327 init_icon_pixmap (CST_FIRE_3);
328 init_icon_pixmap (CST_FIRE_4);
329 init_icon_pixmap (CST_FIRE_5);
330 init_icon_pixmap (CST_FIRE_DONE1);
331 init_icon_pixmap (CST_FIRE_DONE2);
332 init_icon_pixmap (CST_FIRE_DONE3);
333 init_icon_pixmap (CST_FIRE_DONE4);
334
335 /* others */
336 init_icon_pixmap (CST_PARKLAND_PLANE);
337 init_icon_pixmap (CST_RECYCLE);
338 init_icon_pixmap (CST_HEALTH);
339 init_icon_pixmap (CST_BURNT);
340 init_icon_pixmap (CST_MONUMENT_5);
341 init_icon_pixmap (CST_SCHOOL);
342 init_icon_pixmap (CST_SHANTY);
343 prog_box ("", 96);
344 init_icon_pixmap (CST_POWERS_SOLAR);
345 init_icon_pixmap (CST_UNIVERSITY);
346 init_icon_pixmap (CST_EX_PORT);
347 }
348
349 void
initialize_pixmap(void)350 initialize_pixmap (void)
351 {
352 int i;
353 pixmap_height = display.winH - 2*borderx;
354 pixmap_width = display.winW - 2*bordery;
355 pixmap = (char*) malloc (pixmap_height * pixmap_width * sizeof(char));
356 for (i = 0; i < pixmap_height * pixmap_width; i++) {
357 pixmap[i] = 0;
358 }
359 }
360
361 void
free_pixmap(void)362 free_pixmap (void)
363 {
364 free (pixmap);
365 pixmap = 0;
366 }
367
368 void
resize_pixmap(int new_width,int new_height)369 resize_pixmap (int new_width, int new_height)
370 {
371 int i;
372 if (new_width > pixmap_width || new_height > pixmap_height) {
373 char* new_pixmap;
374 if (new_width < pixmap_width) new_width = pixmap_width;
375 if (new_height < pixmap_height) new_height = pixmap_height;
376 new_pixmap = (char*) malloc (new_height * new_width * sizeof(char));
377 for (i = 0; i < pixmap_height * pixmap_width; i++) {
378 pixmap[i] = 0; /* GCS -- Why? */
379 }
380 free (pixmap);
381 pixmap = new_pixmap;
382 pixmap_width = new_width;
383 pixmap_height = new_height;
384 }
385 }
386
387 /* KBR 10/19/2002 MSVC was not happy with this being inline for release build */
388 /* GCS 02/02/2003 That's because of the external reference in lcwin32.c.
389 For some reason, MSVC likes it in the header, while gcc
390 likes it in the file. Still need to fix this in autoconf,
391 but for now this will do. */
392 #if !defined (WIN32)
393 int
pixmap_index(int x,int y)394 pixmap_index (int x, int y)
395 {
396 return y*pixmap_width + x;
397 }
398 #endif
399
400 int
pixmap_getpixel(int x,int y)401 pixmap_getpixel (int x, int y)
402 {
403 return (int) pixmap[pixmap_index(x,y)];
404 }
405
406 void
pixmap_setpixel(int x,int y,int col)407 pixmap_setpixel (int x, int y, int col)
408 {
409 pixmap[pixmap_index(x,y)] = col;
410 }
411
412 void
pixmap_hline(int x1,int y1,int x2,int col)413 pixmap_hline (int x1, int y1, int x2, int col)
414 {
415 int i, j;
416 i = pixmap_index (x1, y1);
417 for (j = 0; j <= x2 - x1; j++)
418 pixmap[i+j] = col;
419 }
420
421 void
pixmap_vline(int x1,int y1,int y2,int col)422 pixmap_vline (int x1, int y1, int y2, int col)
423 {
424 int i, j;
425 i = pixmap_index (x1, y1);
426 for (j = 0; j <= y2 - y1; j++)
427 pixmap[i+j*pixmap_width] = col;
428 }
429
430 void
pixmap_fillbox(int x,int y,int w,int h,int col)431 pixmap_fillbox (int x, int y, int w, int h, int col)
432 {
433 int xx, yy;
434 int i = pixmap_index (x, y);
435 for (yy = y; yy < y + h; yy++) {
436 for (xx = x; xx < x + w; xx++) {
437 pixmap[i++] = col;
438 }
439 i += pixmap_width - w;
440 }
441 }
442
443 void
pixmap_putbox(char * src,int src_x,int src_y,int src_w,int dst_x,int dst_y,int w,int h)444 pixmap_putbox (char* src, int src_x, int src_y, int src_w,
445 int dst_x, int dst_y, int w, int h)
446 {
447 int x, y;
448 int i = pixmap_index (dst_x, dst_y);
449 int j = src_x + src_y * src_w;
450 for (y = src_y; y < src_y + h; y++) {
451 for (x = src_x; x < src_x + w; x++) {
452 pixmap[i++] = src[j++];
453 }
454 i += pixmap_width - w;
455 j += src_w - w;
456 }
457 }
458
459 void
update_pixmap(int x1,int y1,int sizex,int sizey,int dx,int dy,int real_size,char * g)460 update_pixmap (int x1, int y1, int sizex, int sizey, int dx, int dy,
461 int real_size, char *g)
462 {
463 /* Copy graphic from g into pixmap */
464 char *i, *j;
465 int x, y;
466 for (y = 0; y < sizey; y++) {
467 i = pixmap + pixmap_index (dx, dy + y);
468 j = (g + ((y1 + y) * real_size * 16 + x1));
469 for (x = 0; x < sizex; x++)
470 *(i++) = *(j++);
471 }
472 }
473
474 #endif /* USE_PIXMAPS */
475