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