1 /*
2 XorGramana Copyright 2009 James W. Morris, james@jwm-art.net
3
4 This file is part of XorGramana.
5
6 XorGramana is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 XorGramana is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XorGramana. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "icons.h"
20 #include "gfx.h"
21
22 struct xg_icon icon_details[ICON_XXX]=
23 {
24 { "floor", ' ' },
25 { "wall", '#' },
26 { "h-field", '-' },
27 { "v-field", '|' },
28 { "hash", '0' },
29 { "star", '1' },
30 { "map", 'M' },
31 { "teleport", '+' },
32 { "exit", 'E' },
33 { "mask", '@' },
34 { "dot", '.' },
35 { "blank", '_' },
36 { "a", 'a' },
37 { "b", 'b' },
38 { "c", 'c' },
39 { "d", 'd' },
40 { "e", 'e' },
41 { "f", 'f' },
42 { "g", 'g' },
43 { "h", 'h' },
44 { "i", 'i' },
45 { "j", 'j' },
46 { "k", 'k' },
47 { "l", 'l' },
48 { "m", 'm' },
49 { "n", 'n' },
50 { "o", 'o' },
51 { "p", 'p' },
52 { "q", 'q' },
53 { "r", 'r' },
54 { "s", 's' },
55 { "t", 't' },
56 { "u", 'u' },
57 { "v", 'v' },
58 { "w", 'w' },
59 { "x", 'x' },
60 { "y", 'y' },
61 { "z", 'z' },
62 { "0", '0' },
63 { "1", '1' },
64 { "2", '2' },
65 { "3", '3' },
66 { "4", '4' },
67 { "5", '5' },
68 { "6", '6' },
69 { "7", '7' },
70 { "8", '8' },
71 { "9", '9' },
72 /***** THE FOLLOWING ARE NOT SPECIFIABLE IN MAP FILE *****/
73 /***** (hence '\0' as map character specifier) *****/
74 { "exit_open", '\0'},
75 { "space", '\0'}, /* opaque */
76 { "space", '\0'}, /* transparent */
77 { "explode01", '\0'},
78 { "explode02", '\0'},
79 { "explode03", '\0'},
80 { "explode04", '\0'},
81 { "explode05", '\0'},
82 { "line-l", '\0'},
83 { "line-r", '\0'},
84 { "line-t", '\0'},
85 { "line-b", '\0'},
86 { "line-tl", '\0'},
87 { "line-tr", '\0'},
88 { "line-bl", '\0'},
89 { "line-br", '\0'}
90 };
91
92 char* wall_names[WALL_XXX]=
93 {
94 "wall1",
95 "wall2",
96 "wall3",
97 "wall4",
98 "wall5",
99 "wall6",
100 "wall7",
101 "wall4",
102 "wall1",
103 "wall3",
104 "wall2",
105 "wall5",
106 "wall3",
107 "wall2",
108 "wall7",
109 "wall6",
110 };
111
112 char* floor_names[WALL_XXX]=
113 {
114 "floor1",
115 "floor2",
116 "floor3",
117 "floor4",
118 "floor5",
119 "floor6",
120 "floor7",
121 "floor1",
122 "floor2",
123 "floor7",
124 "floor3",
125 "floor5",
126 "floor6",
127 "floor4",
128 "floor2",
129 "floor1",
130 };
131
132 char* edge_names[WALL_XXX][EDGE_XXX]=
133 {
134 { "edge1_t", "edge1_b", "edge1_l", "edge1_r" },
135 { "edge2_t", "edge2_b", "edge2_l", "edge2_r" },
136 { "edge3_t", "edge3_b", "edge3_l", "edge3_r" },
137 { "edge4_t", "edge4_b", "edge4_l", "edge4_r" },
138 { "edge5_t", "edge5_b", "edge5_l", "edge5_r" },
139 { "edge6_t", "edge6_b", "edge6_l", "edge6_r" },
140 { "edge7_t", "edge7_b", "edge7_l", "edge7_r" },
141 { "edge5_t", "edge5_b", "edge5_l", "edge5_r" },
142 { "edge4_t", "edge4_b", "edge4_l", "edge4_r" },
143 { "edge2_t", "edge2_b", "edge2_l", "edge2_r" },
144 { "edge3_t", "edge3_b", "edge3_l", "edge3_r" },
145 { "edge1_t", "edge1_b", "edge1_l", "edge1_r" },
146 { "edge7_t", "edge7_b", "edge7_l", "edge7_r" },
147 { "edge6_t", "edge6_b", "edge6_l", "edge6_r" },
148 { "edge7_t", "edge7_b", "edge7_l", "edge7_r" },
149 { "edge4_t", "edge4_b", "edge4_l", "edge4_r" },
150 };
151
152 char* indicator_names[DIRIND_XXX]=
153 {
154 "grav_u","grav_d","grav_l","grav_r",
155 "push_u","push_d","push_l","push_r",
156 "hard_push_u","hard_push_d","hard_push_l","hard_push_r",
157 "explode_h","explode_v"
158 };
159
160 SDL_Surface* walls[WALL_XXX]={0};
161 SDL_Surface* floors[WALL_XXX]={0};
162 SDL_Surface* hs_walls[WALL_XXX]={0};
163 SDL_Surface* hs_floors[WALL_XXX]={0};
164 SDL_Surface* wall_edges[WALL_XXX][EDGE_XXX]={{0}};
165 SDL_Surface* indicators[DIRIND_XXX]={0};
166 SDL_Surface* edged_walls[ICON_EDGE_TBLR-ICON_EDGE_T]={0};
167
168 SDL_Surface* icons[ICON_XXX]={0};
169 SDL_Surface* hs_icons[ICON_XXX]={0};
170 SDL_Surface* icons_with_indicators[ICON_XXX]={0};
171
172 ss_t current_wall_texture=-1;
173 enum ICON spc_icon=ICON_FLOOR;
174
175 /* private functions */
176 SDL_Surface* icon_half_assed_size(SDL_Surface* s, bool transparent, int tr_r, int tr_g, int tr_b);
177 void generate_wall_edging(su_t wall);
178
init_icons(void)179 void init_icons(void)
180 {
181 char buf[256];
182 int i;
183 #ifdef ICON_DEBUG
184 printf("Loading icons...\n");
185 #endif
186 for(i=ICON_WALL+1;i<ICON_LOADED_XXX;i++){
187 strcpy(buf,"/usr/local/share/xorgramana/GFX/");
188 strcat(buf,icon_details[i].fname);
189 strcat(buf,ICON_EXT);
190 switch(i){
191 /* opaque icons */
192 case ICON_FLOOR:
193 case ICON_EXIT_OPEN:
194 case ICON_LINE_L:
195 case ICON_LINE_R:
196 case ICON_LINE_T:
197 case ICON_LINE_B:
198 case ICON_LINE_TL:
199 case ICON_LINE_TR:
200 case ICON_LINE_BL:
201 case ICON_LINE_BR:
202 case ICON_SPACE_OPAQUE:
203 icons[i]=load_image(buf,FALSE,0,0,0);
204 hs_icons[i]=icon_half_assed_size(icons[i],FALSE,0,0,0);
205 break;
206 default:
207 /* icons with black as transparency */
208 icons[i]=load_image(buf,TRUE,0,0,0);
209 hs_icons[i]=icon_half_assed_size(icons[i],TRUE,0,0,0);
210 break;
211 }
212 }
213 for(i=0;i<WALL_XXX;i++){
214 /* walls */
215 strcpy(buf,"/usr/local/share/xorgramana/GFX/");
216 strcat(buf,wall_names[i]);
217 strcat(buf,ICON_EXT);
218 walls[i]=load_image(buf,FALSE,0,0,0);
219 hs_walls[i]=icon_half_assed_size(walls[i],FALSE,0,0,0);
220 /* floors */
221 strcpy(buf,"/usr/local/share/xorgramana/GFX/");
222 strcat(buf,floor_names[i]);
223 strcat(buf,ICON_EXT);
224 floors[i]=load_image(buf,FALSE,0,0,0);
225 hs_floors[i]=icon_half_assed_size(floors[i],FALSE,0,0,0);
226 }
227 for(i=0;i<DIRIND_XXX;i++){
228 strcpy(buf,"/usr/local/share/xorgramana/GFX/");
229 strcat(buf,indicator_names[i]);
230 strcat(buf,ICON_EXT);
231 indicators[i]=load_image(buf,TRUE,0,0,0);
232 }
233 int j;
234 for(i=0;i<WALL_XXX;i++){
235 for(j=0;j<EDGE_XXX;j++){
236 strcpy(buf,"/usr/local/share/xorgramana/GFX/");
237 strcat(buf,edge_names[i][j]);
238 strcat(buf,ICON_EXT);
239 wall_edges[i][j]=load_image(buf,TRUE,0xff,0xff,0xff);
240 }
241 }
242 }
243
init_wall(lvl_t level,bool show)244 void init_wall(lvl_t level, bool show)
245 {
246 int w=(level>0?((level-1)%WALL_XXX):0);
247 int n;
248 icons[ICON_FLOOR]=floors[w];
249 hs_icons[ICON_FLOOR]=hs_floors[w];
250 if(!show){
251 icons[ICON_WALL]=icons[ICON_FLOOR];
252 hs_icons[ICON_WALL]=hs_icons[ICON_FLOOR];
253 for(n=ICON_EDGE_T;n<=ICON_EDGE_TBLR;n++)
254 icons[n]=icons[ICON_FLOOR];
255 /* won't bother with half-sized edged walls */
256 return;
257 }
258 icons[ICON_WALL]=walls[w];
259 hs_icons[ICON_WALL]=hs_walls[w];
260 if(current_wall_texture!=level){
261 current_wall_texture=level;
262 generate_wall_edging(w);
263 }
264 for(n=ICON_EDGE_T;n<=ICON_EDGE_TBLR;n++){
265 if(!(icons[n]=edged_walls[n-ICON_EDGE_T]))
266 icons[n]=icons[ICON_WALL];
267 }
268 /* won't bother with half-sized edged walls */
269 }
270
icons_cleanup()271 void icons_cleanup()
272 {
273 int i,w;
274 for(i=0;i<ICON_LOADED_XXX;i++){
275 if(i!=ICON_WALL&&i!=ICON_FLOOR){
276 if(icons[i]){
277 SDL_FreeSurface(icons[i]);
278 SDL_FreeSurface(hs_icons[i]);
279 }
280 }
281 }
282 for(i=0;i<WALL_XXX;i++){
283 if(walls[i]){
284 SDL_FreeSurface(walls[i]);
285 SDL_FreeSurface(hs_walls[i]);
286 }
287 if(floors[i]){
288 SDL_FreeSurface(floors[i]);
289 SDL_FreeSurface(hs_floors[i]);
290 }
291 }
292 for(i=0;i<DIRIND_XXX;i++){
293 if(indicators[i])
294 SDL_FreeSurface(indicators[i]);
295 }
296 for(w=0;w<WALL_XXX;w++){
297 for(i=0;i<EDGE_XXX;i++)
298 if(wall_edges[w][i])
299 SDL_FreeSurface(wall_edges[w][i]);
300 }
301 for(i=ICON_EDGE_T;i<=ICON_EDGE_TBLR;i++)
302 if(edged_walls[i-ICON_EDGE_T])
303 SDL_FreeSurface(edged_walls[i-ICON_EDGE_T]);
304 }
305
mapchar_to_icon(char c)306 su_t mapchar_to_icon(char c)
307 {
308 int n;
309 if(c<32)
310 return ICON_FLOOR;
311 for(n=0;n<=ICON_9;n++)
312 if(icon_details[n].mapchar==c)
313 return n;
314 return ICON_FLOOR;
315 }
316
char_to_icon(char c)317 su_t char_to_icon(char c)
318 {
319 if(c>='A'&&c<='Z')
320 return ICON_A+c-'A';
321 if(c>='a'&&c<='z')
322 return ICON_A+c-'a';
323 if(c>='0'&&c<='9')
324 return ICON_1+c-'1';
325 switch(c){
326 case '#': return ICON_PLAYER0;
327 case '*': return ICON_PLAYER1;
328 case '+': return ICON_TELEPORT;
329 case '-': return ICON_H_FIELD;
330 case '|': return ICON_V_FIELD;
331 case '.': return ICON_DOT;
332 case ' ': return spc_icon;
333 case '_': return ICON_FLOOR;
334 default: return spc_icon;
335 }
336 }
337
set_space_icon(enum SPACE_CHAR spc)338 void set_space_icon(enum SPACE_CHAR spc)
339 {
340 switch(spc){
341 case SPC_TRAN: spc_icon=ICON_SPACE_TRAN; break;
342 case SPC_OPAQUE: spc_icon=ICON_SPACE_OPAQUE; break;
343 default: spc_icon=ICON_FLOOR; break;
344 }
345 }
346
load_image(char * name,bool transparent,int tr_r,int tr_g,int tr_b)347 SDL_Surface *load_image(char *name, bool transparent, int tr_r, int tr_g, int tr_b)
348 {
349 SDL_Surface *temp=IMG_Load(name);
350 SDL_Surface *image;
351 if(!temp){
352 fprintf(stderr,"Failed to load image %s\n",name);
353 return NULL;
354 }
355 if(transparent)
356 SDL_SetColorKey(temp,
357 (SDL_SRCCOLORKEY|SDL_RLEACCEL),
358 SDL_MapRGB(temp->format,
359 tr_r, tr_g, tr_b));
360 else
361 SDL_SetColorKey(temp,
362 (SDL_RLEACCEL),
363 SDL_MapRGB(temp->format,
364 0, 0, 0));
365 image=SDL_DisplayFormat(temp);
366 SDL_FreeSurface(temp);
367 if(!image){
368 fprintf(stderr,"Failed to convert image %s to native format\n", name);
369 return NULL;
370 }
371 return image;
372 }
373
icon_duplicate(SDL_Surface * s,bool transparent,int tr_r,int tr_g,int tr_b)374 SDL_Surface* icon_duplicate(SDL_Surface* s, bool transparent, int tr_r, int tr_g, int tr_b)
375 {
376 SDL_Surface* temp;
377 SDL_Surface* ret;
378 Sint32 x,y;
379 if(!s)
380 return 0;
381 temp=SDL_CreateRGBSurface(
382 s->flags,s->w,s->h,
383 s->format->BitsPerPixel,
384 s->format->Rmask,s->format->Gmask,
385 s->format->Bmask,s->format->Amask);
386 SDL_LockSurface(s);
387 SDL_LockSurface(temp);
388 for(y=0;y<s->h;y++)
389 for(x=0;x<s->w;x++)
390 putpixel(temp,x,y,getpixel(s,x,y));
391 SDL_UnlockSurface(s);
392 SDL_UnlockSurface(temp);
393 if(transparent)
394 SDL_SetColorKey(temp,
395 (SDL_SRCCOLORKEY|SDL_RLEACCEL),
396 SDL_MapRGB(temp->format,
397 tr_r, tr_g, tr_b));
398 else
399 SDL_SetColorKey(temp,
400 (SDL_RLEACCEL),
401 SDL_MapRGB(temp->format,
402 0, 0, 0));
403 ret=SDL_DisplayFormat(temp);
404 SDL_FreeSurface(temp);
405 return ret;
406 }
407
icon_half_assed_size(SDL_Surface * s,bool transparent,int tr_r,int tr_g,int tr_b)408 SDL_Surface* icon_half_assed_size(SDL_Surface* s, bool transparent, int tr_r, int tr_g, int tr_b)
409 {
410 SDL_Surface* temp;
411 SDL_Surface* ret;
412 Sint32 x,y;
413 Sint32 hw;
414 Sint32 hh;
415 if(!s)
416 return 0;
417 hw=s->w/2;
418 hh=s->h/2;
419 temp=SDL_CreateRGBSurface(
420 s->flags,hw,hh,
421 s->format->BitsPerPixel,
422 s->format->Rmask,s->format->Gmask,
423 s->format->Bmask,s->format->Amask);
424 SDL_LockSurface(s);
425 SDL_LockSurface(temp);
426 for(y=0;y<hh;y++)
427 for(x=0;x<hw;x++)
428 putpixel(temp,x,y,getpixel(s,x*2,y*2));
429 SDL_UnlockSurface(s);
430 SDL_UnlockSurface(temp);
431 if(transparent)
432 SDL_SetColorKey(temp,
433 (SDL_SRCCOLORKEY|SDL_RLEACCEL),
434 SDL_MapRGB(temp->format,
435 tr_r, tr_g, tr_b));
436 else
437 SDL_SetColorKey(temp,
438 (SDL_RLEACCEL),
439 SDL_MapRGB(temp->format,
440 0, 0, 0));
441 ret=SDL_DisplayFormat(temp);
442 SDL_FreeSurface(temp);
443 return ret;
444 }
445
446 /* private functions */
447
generate_wall_edging(su_t wall)448 void generate_wall_edging(su_t wall)
449 {
450 int n;
451 int o;
452 SDL_Surface *temp;
453 if(!icons[ICON_WALL])
454 return;
455 for(n=ICON_EDGE_T;n<=ICON_EDGE_TBLR;n++){
456 int w=n-ICON_EDGE_T;
457 if(edged_walls[w]){
458 SDL_FreeSurface(edged_walls[w]);
459 edged_walls[w]=0;
460 }
461 temp=icon_duplicate(icons[ICON_WALL],FALSE,0,0,0);
462 switch(n){
463 case ICON_EDGE_T: o=EDGE_T; break;
464 case ICON_EDGE_B: o=EDGE_B; break;
465 case ICON_EDGE_L: o=EDGE_L; break;
466 case ICON_EDGE_R: o=EDGE_R; break;
467 case ICON_EDGE_TB: o=EDGE_TB; break;
468 case ICON_EDGE_LR: o=EDGE_LR; break;
469 case ICON_EDGE_TL: o=EDGE_TL; break;
470 case ICON_EDGE_TR: o=EDGE_TR; break;
471 case ICON_EDGE_BL: o=EDGE_BL; break;
472 case ICON_EDGE_BR: o=EDGE_BR; break;
473 case ICON_EDGE_TBL: o=EDGE_TBL; break;
474 case ICON_EDGE_TBR: o=EDGE_TBR; break;
475 case ICON_EDGE_TLR: o=EDGE_TLR; break;
476 case ICON_EDGE_BLR: o=EDGE_BLR; break;
477 default: o=EDGE_TBLR;break;
478 }
479 if(o&EDGE_T)
480 overlay_image(temp,wall_edges[wall][0],0,0);
481 if(o&EDGE_B)
482 overlay_image(temp,wall_edges[wall][1],0,0);
483 if(o&EDGE_L)
484 overlay_image(temp,wall_edges[wall][2],0,0);
485 if(o&EDGE_R)
486 overlay_image(temp,wall_edges[wall][3],0,0);
487 SDL_SetColorKey(temp,
488 (SDL_SRCCOLORKEY|SDL_RLEACCEL),
489 SDL_MapRGB(temp->format,
490 0, 0, 0));
491 edged_walls[n-ICON_EDGE_T]=SDL_DisplayFormat(temp);
492 SDL_FreeSurface(temp);
493 }
494 }
495