1 /*
2 Copyright (C) 2003 Parallel Realities
3 Copyright (C) 2011, 2012, 2013 Guus Sliepen
4 Copyright (C) 2015-2020 The Diligent Circle <diligentcircle@riseup.net>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 3
9 of the License, or (at your option) any later version.
10
11 This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ctype.h>
21 #include <libintl.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "SDL.h"
26 #include "SDL_image.h"
27
28
29 #ifndef NOFONT
30
31 // Undef MIN and MAX since pango-break.h includes these macros
32 // (avoids compiler warnings)
33 #ifdef MIN
34 #undef MIN
35 #endif
36
37 #ifdef MAX
38 #undef MAX
39 #endif
40
41 #include "SDL_ttf.h"
42 #include <pango/pango-break.h>
43
44 #endif
45
46
47 #include "defs.h"
48 #include "structs.h"
49
50 #include "alien.h"
51 #include "engine.h"
52 #include "game.h"
53 #include "screen.h"
54 #include "weapons.h"
55
56 SDL_Surface *gfx_unscaledBackground;
57 SDL_Surface *gfx_background;
58 SDL_Surface *gfx_sprites[SP_MAX];
59 SDL_Surface *gfx_faceSprites[FS_MAX];
60 SDL_Surface *gfx_shipSprites[SS_MAX];
61 SDL_Surface *gfx_fontSprites[FONT_MAX];
62 SDL_Surface *gfx_shopSprites[SHOP_S_MAX];
63 TextObject gfx_textSprites[TS_MAX];
64 SDL_Surface *gfx_messageBox;
65
66 #ifndef NOFONT
67 TTF_Font *gfx_unicodeFont;
68 #endif
69
gfx_init()70 void gfx_init()
71 {
72 screen_bufferHead = malloc(sizeof(*screen_bufferHead));
73 if (screen_bufferHead == NULL)
74 {
75 engine_error("Failed to allocate memory for buffer head.");
76 }
77 screen_bufferHead->next = NULL;
78 screen_bufferTail = screen_bufferHead;
79
80 for (int i = 0 ; i < SP_MAX ; i++)
81 gfx_sprites[i] = NULL;
82
83 for (int i = 0 ; i < SS_MAX ; i++)
84 gfx_shipSprites[i] = NULL;
85
86 for (int i = 0 ; i < TS_MAX ; i++)
87 gfx_textSprites[i].image = NULL;
88
89 for (int i = 0 ; i < SHOP_S_MAX ; i++)
90 gfx_shopSprites[i] = NULL;
91
92 for (int i = 0 ; i < FONT_MAX ; i++)
93 gfx_fontSprites[i] = NULL;
94
95 gfx_background = NULL;
96 gfx_messageBox = NULL;
97
98 screen = NULL;
99
100 #ifndef NOFONT
101 if (TTF_Init() < 0)
102 {
103 printf("ERROR: Could not initialize TTF: %s\n", TTF_GetError());
104 exit(1);
105 }
106
107 /// If the TakaoGothic font is able to display the text of the language
108 /// being translated to, DO NOT CHANGE THIS! If, however, the language
109 /// requires characters not available in the default font, you can
110 /// place that font in the "data" directory and indicate the name of the
111 /// alternate font as a translation to "TakaoPGothic.ttf" (leaving the
112 /// rest of the string unchanged). Please ensure that the font displays
113 /// correctly with ALL text (space is limited and some fonts take up
114 /// more space than others), and also check the license of the font
115 /// before distributing to make sure you are allowed to do so.
116 gfx_unicodeFont = TTF_OpenFont(_("data/TakaoPGothic.ttf"), 13);
117 if (gfx_unicodeFont == NULL)
118 {
119 printf("ERROR: TTF_OpenFont: %s\n", TTF_GetError());
120 exit(1);
121 }
122 TTF_SetFontStyle(gfx_unicodeFont, TTF_STYLE_BOLD);
123 #endif
124 }
125
gfx_setTransparent(SDL_Surface * sprite)126 SDL_Surface *gfx_setTransparent(SDL_Surface *sprite)
127 {
128 SDL_SetColorKey(sprite, SDL_TRUE, SDL_MapRGB(sprite->format, 0, 0, 0));
129 return sprite;
130 }
131
gfx_blit(SDL_Surface * image,int x,int y,SDL_Surface * dest)132 void gfx_blit(SDL_Surface *image, int x, int y, SDL_Surface *dest)
133 {
134 SDL_Rect blitRect;
135
136 // Exit early if image is not on dest at all
137 if (x + image->w < 0 || x >= dest->w || y + image->h < 0 || y >= dest->h)
138 return;
139
140 // Set up a rectangle to draw to
141 blitRect.x = x;
142 blitRect.y = y;
143 blitRect.w = image->w;
144 blitRect.h = image->h;
145
146 /* Blit onto the destination surface */
147 if (SDL_BlitSurface(image, NULL, dest, &blitRect) < 0)
148 {
149 printf("BlitSurface error: %s\n", SDL_GetError());
150 engine_showError(2, "");
151 }
152
153 // Only if it is to the screen, mark the region as damaged
154 if (dest == screen)
155 screen_addBuffer(blitRect.x, blitRect.y, blitRect.w, blitRect.h);
156 }
157
158 /*
159 In 16 bit mode this is slow. VERY slow. Don't write directly to a surface
160 that constantly needs updating (eg - the main game screen)
161 */
gfx_renderStringBase(const char * in,int x,int y,int real_x,int fontColor,int wrap,SDL_Surface * dest)162 static int gfx_renderStringBase(const char *in, int x, int y, int real_x, int fontColor, int wrap, SDL_Surface *dest)
163 {
164 int i;
165 int splitword;
166 int creal_x;
167 SDL_Rect area;
168 SDL_Rect letter;
169
170 area.x = x;
171 area.y = y;
172 area.w = PIXFONT_W;
173 area.h = PIXFONT_H;
174 creal_x = real_x;
175
176 letter.y = 0;
177 letter.w = PIXFONT_W;
178 letter.h = PIXFONT_H;
179
180 while (*in != '\0')
181 {
182 if (*in != ' ')
183 {
184 letter.x = (*in - 33);
185 letter.x *= PIXFONT_W;
186
187 /* Blit onto the screen surface */
188 if (SDL_BlitSurface(gfx_fontSprites[fontColor], &letter, dest, &area) < 0)
189 {
190 printf("BlitSurface error: %s\n", SDL_GetError());
191 engine_showError(2, "");
192 }
193 }
194
195 area.x += PIXFONT_W + 1;
196 creal_x += PIXFONT_W + 1;
197
198 if (wrap)
199 {
200 if ((creal_x > (dest->w - 70)) && (*in == ' '))
201 {
202 area.y += PIXFONT_LINE_HEIGHT;
203 area.x = x;
204 creal_x = real_x;
205 }
206 else if (creal_x > (dest->w - 31))
207 {
208 splitword = 1;
209 for (i = 0 ; i < 4 ; i++)
210 {
211 if (!isalpha(*(in + i)))
212 {
213 splitword = 0;
214 break;
215 }
216 }
217
218 if (splitword)
219 {
220 letter.x = (int)('-') - 33;
221 letter.x *= PIXFONT_W;
222 if (SDL_BlitSurface(gfx_fontSprites[fontColor], &letter, dest, &area) < 0)
223 {
224 printf("BlitSurface error: %s\n", SDL_GetError());
225 engine_showError(2, "");
226 }
227 area.y += PIXFONT_LINE_HEIGHT;
228 area.x = x;
229 creal_x = real_x;
230 }
231 }
232 }
233
234 in++;
235 }
236
237 return area.y;
238 }
239
240 /*
241 Legacy text rendering function, the original one which only supports
242 ASCII. Generally not used anymore with the exception of some title
243 screen bits that remain untranslated, but also used as a fallback if the
244 game is compiled without SDL_ttf and Pango. Works OK on the English
245 text, but not likely to work well with translations (and won't work at
246 all for languages like Chinese or Japanese based on non-Latin
247 alphabets).
248 */
gfx_renderString(const char * in,int x,int y,int fontColor,int wrap,SDL_Surface * dest)249 int gfx_renderString(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest)
250 {
251 if (x == -1)
252 x = (dest->w - (strlen(in) * (PIXFONT_W + 1))) / 2;
253
254 gfx_renderStringBase(in, x, y - 1, x, FONT_OUTLINE, wrap, dest);
255 gfx_renderStringBase(in, x, y + 1, x, FONT_OUTLINE, wrap, dest);
256 gfx_renderStringBase(in, x, y + 2, x, FONT_OUTLINE, wrap, dest);
257 gfx_renderStringBase(in, x - 1, y, x, FONT_OUTLINE, wrap, dest);
258 gfx_renderStringBase(in, x - 2, y, x, FONT_OUTLINE, wrap, dest);
259 gfx_renderStringBase(in, x + 1, y, x, FONT_OUTLINE, wrap, dest);
260 return gfx_renderStringBase(in, x, y, x, fontColor, wrap, dest);
261 }
262
263 #ifdef NOFONT
gfx_unicodeWidth(const char * in)264 int gfx_unicodeWidth(const char *in)
265 {
266 return (PIXFONT_W + 1) * strlen(in);
267 }
268
gfx_renderUnicode(const char * in,int x,int y,int fontColor,int wrap,SDL_Surface * dest)269 int gfx_renderUnicode(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest)
270 {
271 return gfx_renderString(in, x, y, fontColor, wrap, dest);
272 }
273
274 #else
gfx_charIsUTF8Start(unsigned char c)275 static int gfx_charIsUTF8Start(unsigned char c)
276 {
277 // Top bit not set (single byte ASCII character)
278 if ((c & 0x80) == 0)
279 return 1;
280
281 // Top two bits set (start of multi-byte character)
282 if ((c & 0x80) && (c & 0x40))
283 return 1;
284
285 // Top bit set, but second bit not set (somewhere in the middle)
286 return 0;
287 }
288
gfx_unicodeWidth(const char * in)289 int gfx_unicodeWidth(const char *in)
290 {
291 int w;
292
293 if (TTF_SizeUTF8(gfx_unicodeFont, in, &w, NULL) < 0)
294 {
295 engine_error(TTF_GetError());
296 }
297
298 return w;
299 }
300
gfx_renderUnicodeBase(const char * in,int x,int y,int real_x,int fontColor,int wrap,SDL_Surface * dest)301 int gfx_renderUnicodeBase(const char *in, int x, int y, int real_x, int fontColor, int wrap, SDL_Surface *dest)
302 {
303 SDL_Surface *textSurf;
304 SDL_Color color;
305 int w, h;
306 int avail_w;
307 int changed;
308 int breakPoints[STRMAX];
309 int nBreakPoints;
310 char testStr[STRMAX];
311 char remainingStr[STRMAX];
312 PangoLogAttr logAttrs[STRMAX];
313 int nLogAttrs;
314 int i;
315 SDL_Rect area;
316
317 if (strcmp(in, "") == 0)
318 return y;
319
320 avail_w = dest->w - real_x;
321
322 switch (fontColor)
323 {
324 case FONT_WHITE:
325 color.r = 255;
326 color.g = 255;
327 color.b = 255;
328 break;
329 case FONT_RED:
330 color.r = 255;
331 color.g = 0;
332 color.b = 0;
333 break;
334 case FONT_YELLOW:
335 color.r = 255;
336 color.g = 255;
337 color.b = 0;
338 break;
339 case FONT_GREEN:
340 color.r = 0;
341 color.g = 255;
342 color.b = 0;
343 break;
344 case FONT_CYAN:
345 color.r = 0;
346 color.g = 255;
347 color.b = 255;
348 break;
349 case FONT_OUTLINE:
350 color.r = 0;
351 color.g = 0;
352 color.b = 10;
353 break;
354 default:
355 color.r = 255;
356 color.g = 255;
357 color.b = 255;
358 }
359
360 if (gfx_unicodeFont != NULL)
361 {
362 strcpy(remainingStr, in);
363 if (TTF_SizeUTF8(gfx_unicodeFont, remainingStr, &w, &h) < 0)
364 {
365 engine_error(TTF_GetError());
366 }
367
368 changed = wrap;
369 while (changed && (w > avail_w))
370 {
371 nLogAttrs = strlen(remainingStr) + 1;
372 pango_get_log_attrs(remainingStr, strlen(remainingStr), -1, NULL, logAttrs, nLogAttrs);
373
374 nBreakPoints = 0;
375 for (i = 0; i < nLogAttrs; i++)
376 {
377 if (logAttrs[i].is_line_break
378 && gfx_charIsUTF8Start(remainingStr[i]))
379 {
380 breakPoints[nBreakPoints] = i;
381 nBreakPoints++;
382 }
383 }
384
385 changed = 0;
386 for (i = nBreakPoints - 1; i >= 0; i--)
387 {
388 strncpy(testStr, remainingStr, breakPoints[i]);
389 testStr[breakPoints[i]] = '\0';
390 if (TTF_SizeUTF8(gfx_unicodeFont, testStr, &w, &h) < 0)
391 {
392 engine_error(TTF_GetError());
393 }
394 if (w <= avail_w)
395 {
396 textSurf = TTF_RenderUTF8_Blended(gfx_unicodeFont, testStr, color);
397 if (textSurf == NULL)
398 {
399 printf("While rendering testStr \"%s\" as unicode...\n", testStr);
400 engine_error("Attempted to render UTF8, got null surface!");
401 }
402
403 area.x = x;
404 area.y = y;
405 area.w = textSurf->w;
406 area.h = textSurf->h;
407 if (SDL_BlitSurface(textSurf, NULL, dest, &area) < 0)
408 {
409 printf("BlitSurface error: %s\n", SDL_GetError());
410 engine_showError(2, "");
411 }
412 SDL_FreeSurface(textSurf);
413 textSurf = NULL;
414 y += TTF_FontHeight(gfx_unicodeFont) + 1;
415
416 memmove(remainingStr, remainingStr + breakPoints[i],
417 (strlen(remainingStr) - breakPoints[i]) + 1);
418 changed = 1;
419 break;
420 }
421 }
422
423 if (TTF_SizeUTF8(gfx_unicodeFont, remainingStr, &w, &h) < 0)
424 {
425 engine_error(TTF_GetError());
426 }
427 }
428 textSurf = TTF_RenderUTF8_Blended(gfx_unicodeFont, remainingStr, color);
429 if (textSurf == NULL)
430 {
431 printf("While rendering remainingStr \"%s\" as unicode...\n", remainingStr);
432 engine_error("Attempted to render UTF8, got null surface!");
433 }
434
435 area.x = x;
436 area.y = y;
437 area.w = textSurf->w;
438 area.h = textSurf->h;
439 if (SDL_BlitSurface(textSurf, NULL, dest, &area) < 0)
440 {
441 printf("BlitSurface error: %s\n", SDL_GetError());
442 engine_showError(2, "");
443 }
444 SDL_FreeSurface(textSurf);
445 textSurf = NULL;
446 y += TTF_FontHeight(gfx_unicodeFont) + 1;
447 }
448 else
449 {
450 engine_warn("gfx_unicodeFont is NULL!");
451 }
452
453 return y;
454 }
455
gfx_renderUnicode(const char * in,int x,int y,int fontColor,int wrap,SDL_Surface * dest)456 int gfx_renderUnicode(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest)
457 {
458 int w;
459
460 if (x == -1)
461 {
462 TTF_SizeUTF8(gfx_unicodeFont, in, &w, NULL);
463 x = (dest->w - MIN(w, dest->w)) / 2;
464 }
465
466 gfx_renderUnicodeBase(in, x, y - 1, x, FONT_OUTLINE, wrap, dest);
467 gfx_renderUnicodeBase(in, x, y + 1, x, FONT_OUTLINE, wrap, dest);
468 gfx_renderUnicodeBase(in, x, y + 2, x, FONT_OUTLINE, wrap, dest);
469 gfx_renderUnicodeBase(in, x - 1, y, x, FONT_OUTLINE, wrap, dest);
470 gfx_renderUnicodeBase(in, x - 2, y, x, FONT_OUTLINE, wrap, dest);
471 gfx_renderUnicodeBase(in, x + 1, y, x, FONT_OUTLINE, wrap, dest);
472 return gfx_renderUnicodeBase(in, x, y, x, fontColor, wrap, dest);
473 }
474 #endif
475
476 /*
477 * Set the pixel at (x, y) to the given value
478 * NOTE: The surface must be locked before calling this!
479 */
gfx_putPixel(SDL_Surface * surface,int x,int y,Uint32 pixel)480 void gfx_putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
481 {
482 int bpp = surface->format->BytesPerPixel;
483 /* Here p is the address to the pixel we want to set */
484 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
485
486 switch(bpp)
487 {
488 case 1:
489 *p = pixel;
490 break;
491
492 case 2:
493 *(Uint16 *)p = pixel;
494 break;
495
496 case 3:
497 if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
498 {
499 p[0] = (pixel >> 16) & 0xff;
500 p[1] = (pixel >> 8) & 0xff;
501 p[2] = pixel & 0xff;
502 }
503 else
504 {
505 p[0] = pixel & 0xff;
506 p[1] = (pixel >> 8) & 0xff;
507 p[2] = (pixel >> 16) & 0xff;
508 }
509 break;
510
511 case 4:
512 *(Uint32 *)p = pixel;
513 break;
514 }
515 }
516
517 /*
518 A quick(?) circle draw function. This code was posted to the SDL
519 mailing list... I didn't write it myself.
520 */
gfx_drawCircle(int xc,int yc,int R,SDL_Surface * PIX,int col)521 void gfx_drawCircle(int xc, int yc, int R, SDL_Surface *PIX, int col)
522 {
523 int x = 0;
524 int xx = 0;
525 int y = R;
526 int yy = 2 * R;
527 int p = 1 - R;
528
529 gfx_putPixel(PIX, xc, yc - y, col);
530 gfx_putPixel(PIX, xc, yc + y, col);
531 gfx_putPixel(PIX, xc - y, yc, col);
532 gfx_putPixel(PIX, xc + y, yc, col);
533
534 while (x < y)
535 {
536 xx += 2;
537 x++;
538 if (p >= 0)
539 {
540 yy -= 2;
541 y--;
542 p -= yy;
543 }
544 p += xx + 1;
545
546 gfx_putPixel(PIX, xc - x, yc - y, col);
547 gfx_putPixel(PIX, xc + x, yc - y, col);
548 gfx_putPixel(PIX, xc - x, yc + y, col);
549 gfx_putPixel(PIX, xc + x, yc + y, col);
550 gfx_putPixel(PIX, xc - y, yc - x, col);
551 gfx_putPixel(PIX, xc + y, yc - x, col);
552 gfx_putPixel(PIX, xc - y, yc + x, col);
553 gfx_putPixel(PIX, xc + y, yc + x, col);
554 }
555
556 if ((x = y))
557 {
558 gfx_putPixel(PIX, xc - x, yc - y, col);
559 gfx_putPixel(PIX, xc + x, yc - y, col);
560 gfx_putPixel(PIX, xc - x, yc + y, col);
561 gfx_putPixel(PIX, xc + x, yc + y, col);
562 }
563 }
564
gfx_drawRect(SDL_Surface * dest,int x,int y,int w,int h,Uint8 red,Uint8 green,Uint8 blue)565 void gfx_drawRect(SDL_Surface *dest, int x, int y, int w, int h, Uint8 red, Uint8 green, Uint8 blue)
566 {
567 SDL_Rect r = {x, y, w, h};
568 SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, red, green, blue));
569
570 r.h = 1;
571 SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 255, 255, 255));
572
573 r.w = 1;
574 r.h = h;
575 SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 255, 255, 255));
576
577 r.y = y + h;
578 r.w = w;
579 r.h = 1;
580 SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 128, 128, 128));
581
582 r.x = x + w;
583 r.y = y + 1;
584 r.w = 1;
585 r.h = h - 1;
586 SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 128, 128, 128));
587 }
588
gfx_createSurface(int width,int height)589 SDL_Surface *gfx_createSurface(int width, int height)
590 {
591 SDL_Surface *surface;
592 Uint32 rmask, gmask, bmask, amask;
593
594 /* SDL interprets each pixel as a 32-bit number, so our masks must depend
595 on the endianness (byte order) of the machine */
596 #if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
597 rmask = 0xff000000;
598 gmask = 0x00ff0000;
599 bmask = 0x0000ff00;
600 amask = 0x000000ff;
601 #else
602 rmask = 0x000000ff;
603 gmask = 0x0000ff00;
604 bmask = 0x00ff0000;
605 amask = 0xff000000;
606 #endif
607
608 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);
609
610 if (surface == NULL) {
611 printf("CreateRGBSurface failed: %s\n", SDL_GetError());
612 engine_showError(2, "");
613 }
614
615 return surface;
616 }
617
gfx_createTextSurface(const char * inString,int color)618 SDL_Surface *gfx_createTextSurface(const char *inString, int color)
619 {
620 int w, h, th;
621
622 #ifndef NOFONT
623 if (TTF_SizeUTF8(gfx_unicodeFont, inString, &w, &th) < 0)
624 {
625 engine_error(TTF_GetError());
626 }
627 w += 2;
628 th += 2;
629 h = MAX(th, PIXFONT_LINE_HEIGHT);
630 #else
631 w = strlen(inString) * (PIXFONT_W + 1) + 1;
632 th = PIXFONT_H;
633 h = MAX(PIXFONT_LINE_HEIGHT, PIXFONT_H + 2);
634 #endif
635
636 SDL_Surface *surface = gfx_createSurface(w, h);
637
638 gfx_renderUnicode(inString, 1, (h - th) / 2, color, 0, surface);
639
640 return gfx_setTransparent(surface);
641 }
642
gfx_createTextObject(int index,const char * inString,int x,int y,int fontColor)643 void gfx_createTextObject(int index, const char *inString, int x, int y, int fontColor)
644 {
645 // Reset the life of the text object
646 gfx_textSprites[index].life = 0;
647
648 /* Shortcut: if we already rendered the same string in the same color, don't render it again. */
649 // TODO: Double-check this, I think it's trying to test if gfx_textSprites[index].image is NULL.
650 // Also, check what `text` will be when "empty".
651 if (gfx_textSprites[index].text && gfx_textSprites[index].image
652 && (gfx_textSprites[index].fontColor == fontColor)
653 && (strcmp(gfx_textSprites[index].text, inString) == 0))
654 {
655 gfx_textSprites[index].x = x;
656 gfx_textSprites[index].y = y;
657 return;
658 }
659
660 strcpy(gfx_textSprites[index].text, inString);
661 gfx_textSprites[index].x = x;
662 gfx_textSprites[index].y = y;
663 gfx_textSprites[index].fontColor = fontColor;
664 if (gfx_textSprites[index].image != NULL)
665 {
666 SDL_FreeSurface(gfx_textSprites[index].image);
667 }
668 gfx_textSprites[index].image = gfx_createTextSurface(inString, fontColor);
669 }
670
gfx_createAlphaRect(int width,int height,Uint8 red,Uint8 green,Uint8 blue)671 SDL_Surface *gfx_createAlphaRect(int width, int height, Uint8 red, Uint8 green, Uint8 blue)
672 {
673 SDL_Surface *surface = gfx_createSurface(width, height);
674
675 SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, red, green, blue));
676
677 SDL_SetSurfaceAlphaMod(surface, 128);
678
679 return surface;
680 }
681
gfx_createMessageBox(SDL_Surface * face,const char * message,int transparent)682 void gfx_createMessageBox(SDL_Surface *face, const char *message, int transparent)
683 {
684 int border = 5;
685 int x = border;
686 int y = border;
687
688 if (gfx_messageBox != NULL)
689 {
690 SDL_FreeSurface(gfx_messageBox);
691 gfx_messageBox = NULL;
692 }
693
694 if (transparent)
695 gfx_messageBox = gfx_createAlphaRect(550, 60, 0x00, 0x00, 0x00);
696 else
697 gfx_messageBox = gfx_createSurface(550, 60);
698
699 if (face != NULL)
700 {
701 gfx_drawRect(gfx_messageBox, 0, 0, gfx_messageBox->w - 1, gfx_messageBox->h - 1, 0x00, 0x00, 0xaa);
702 gfx_blit(face, border, border, gfx_messageBox);
703 x = (2 * border) + face->w;
704 }
705 else
706 {
707 gfx_drawRect(gfx_messageBox, 0, 0, gfx_messageBox->w - 1, gfx_messageBox->h - 1, 0x00, 0x00, 0x00);
708 x = border;
709 }
710
711 gfx_renderUnicode(message, x, y, FONT_WHITE, 1, gfx_messageBox);
712 }
713
gfx_loadImage(const char * filename)714 SDL_Surface *gfx_loadImage(const char *filename)
715 {
716 SDL_Surface *image, *newImage;
717
718 image = IMG_Load(filename);
719
720 if (image == NULL) {
721 printf("Couldn't load %s: %s\n", filename, SDL_GetError());
722 engine_showError(0, filename);
723 }
724
725 newImage = SDL_ConvertSurface(image, screen->format, 0);
726 if ( newImage ) {
727 SDL_FreeSurface(image);
728 }
729 else
730 {
731 // This happens when we are loading the window icon image
732 newImage = image;
733 }
734
735 return gfx_setTransparent(newImage);
736 }
737
gfx_free()738 void gfx_free()
739 {
740 for (int i = 0 ; i < SP_MAX ; i++)
741 {
742 if (gfx_sprites[i] != NULL)
743 {
744 SDL_FreeSurface(gfx_sprites[i]);
745 gfx_sprites[i] = NULL;
746 }
747 }
748
749 for (int i = 0 ; i < FS_MAX ; i++)
750 {
751 if (gfx_faceSprites[i] != NULL)
752 {
753 SDL_FreeSurface(gfx_faceSprites[i]);
754 gfx_faceSprites[i] = NULL;
755 }
756 }
757
758 for (int i = 0 ; i < SS_MAX ; i++)
759 {
760 if (gfx_shipSprites[i] != NULL)
761 {
762 SDL_FreeSurface(gfx_shipSprites[i]);
763 gfx_shipSprites[i] = NULL;
764 }
765 }
766
767 for (int i = 0 ; i < TS_MAX ; i++)
768 {
769 if (gfx_textSprites[i].image != NULL)
770 {
771 SDL_FreeSurface(gfx_textSprites[i].image);
772 gfx_textSprites[i].image = NULL;
773 }
774 }
775
776 for (int i = 0 ; i < SHOP_S_MAX ; i++)
777 {
778 if (gfx_shopSprites[i] != NULL)
779 {
780 SDL_FreeSurface(gfx_shopSprites[i]);
781 gfx_shopSprites[i] = NULL;
782 }
783 }
784
785 if (gfx_messageBox != NULL)
786 {
787 SDL_FreeSurface(gfx_messageBox);
788 gfx_messageBox = NULL;
789 }
790 }
791
gfx_scaleBackground()792 void gfx_scaleBackground()
793 {
794 if (gfx_background != NULL)
795 {
796 SDL_FreeSurface(gfx_background);
797 gfx_background = NULL;
798 }
799 gfx_background = gfx_createSurface(screen->w, screen->h);
800 if (gfx_background == NULL)
801 engine_error("Failed to create surface for scaled background");
802
803 SDL_SetColorKey(gfx_background, 0, 0);
804 SDL_BlitScaled(gfx_unscaledBackground, NULL, gfx_background, NULL);
805 }
806
gfx_loadBackground(const char * filename)807 void gfx_loadBackground(const char *filename)
808 {
809 if (gfx_unscaledBackground != NULL)
810 {
811 SDL_FreeSurface(gfx_unscaledBackground);
812 gfx_unscaledBackground = NULL;
813 }
814 gfx_unscaledBackground = gfx_loadImage(filename);
815 if (gfx_unscaledBackground == NULL)
816 engine_error("Failed to load unscaled background image");
817
818 SDL_SetColorKey(gfx_unscaledBackground, 0, 0);
819 gfx_scaleBackground();
820 }
821
gfx_loadSprites()822 void gfx_loadSprites()
823 {
824 Uint32 *p32;
825 Uint16 *p16;
826 Uint8 *p8;
827
828 gfx_free();
829
830 // Faces
831 gfx_faceSprites[FS_CHRIS] = gfx_loadImage("gfx/face_chris.png");
832 gfx_faceSprites[FS_SID] = gfx_loadImage("gfx/face_sid.png");
833 gfx_faceSprites[FS_KRASS] = gfx_loadImage("gfx/face_krass.png");
834 gfx_faceSprites[FS_PHOEBE] = gfx_loadImage("gfx/face_phoebe.png");
835 gfx_faceSprites[FS_URSULA] = gfx_loadImage("gfx/face_ursula.png");
836 gfx_faceSprites[FS_KLINE] = gfx_loadImage("gfx/face_kline.png");
837 gfx_faceSprites[FS_CREW] = gfx_loadImage("gfx/face_crew.png");
838
839 // Ships
840 gfx_shipSprites[SS_FIREFLY] = gfx_loadImage("gfx/firefly1.png");
841 gfx_shipSprites[SS_FIREFLY_L] = gfx_loadImage("gfx/firefly2.png");
842 gfx_shipSprites[SS_SID] = gfx_loadImage("gfx/sid1.png");
843 gfx_shipSprites[SS_SID_L] = gfx_loadImage("gfx/sid2.png");
844 gfx_shipSprites[SS_FRIEND] = gfx_loadImage("gfx/wingmate1.png");
845 gfx_shipSprites[SS_FRIEND_L] = gfx_loadImage("gfx/wingmate2.png");
846 gfx_shipSprites[SS_GOODTRANSPORT] = gfx_loadImage("gfx/goodTrans1.png");
847 gfx_shipSprites[SS_GOODTRANSPORT_L] = gfx_loadImage("gfx/goodTrans2.png");
848 gfx_shipSprites[SS_REBELCARRIER] = gfx_loadImage("gfx/rebelCarrier1.png");
849 gfx_shipSprites[SS_REBELCARRIER_L] = gfx_loadImage("gfx/rebelCarrier2.png");
850 gfx_shipSprites[SS_DUALFIGHTER] = gfx_loadImage("gfx/dualFighter1.png");
851 gfx_shipSprites[SS_DUALFIGHTER_L] = gfx_loadImage("gfx/dualFighter2.png");
852 gfx_shipSprites[SS_MISSILEBOAT] = gfx_loadImage("gfx/missileBoat1.png");
853 gfx_shipSprites[SS_MISSILEBOAT_L] = gfx_loadImage("gfx/missileBoat2.png");
854 gfx_shipSprites[SS_PROTOFIGHTER] = gfx_loadImage("gfx/eliteFighter1.png");
855 gfx_shipSprites[SS_PROTOFIGHTER_L] = gfx_loadImage("gfx/eliteFighter2.png");
856 gfx_shipSprites[SS_AIMFIGHTER] = gfx_loadImage("gfx/aimFighter1.png");
857 gfx_shipSprites[SS_AIMFIGHTER_L] = gfx_loadImage("gfx/aimFighter2.png");
858 gfx_shipSprites[SS_DRONE] = gfx_loadImage("gfx/drone1.png");
859 gfx_shipSprites[SS_DRONE_L] = gfx_loadImage("gfx/drone2.png");
860 gfx_shipSprites[SS_MINER] = gfx_loadImage("gfx/miner1.png");
861 gfx_shipSprites[SS_MINER_L] = gfx_loadImage("gfx/miner2.png");
862 gfx_shipSprites[SS_ESCORT] = gfx_loadImage("gfx/escort1.png");
863 gfx_shipSprites[SS_ESCORT_L] = gfx_loadImage("gfx/escort2.png");
864 gfx_shipSprites[SS_MOBILE_RAY] = gfx_loadImage("gfx/mobileCannon1.png");
865 gfx_shipSprites[SS_MOBILE_RAY_L] = gfx_loadImage("gfx/mobileCannon2.png");
866 gfx_shipSprites[SS_TRANSPORTSHIP] = gfx_loadImage("gfx/transport1.png");
867 gfx_shipSprites[SS_TRANSPORTSHIP_L] = gfx_loadImage("gfx/transport2.png");
868 gfx_shipSprites[SS_CARGOSHIP] = gfx_loadImage("gfx/tug1.png");
869 gfx_shipSprites[SS_CARGOSHIP_L] = gfx_loadImage("gfx/tug2.png");
870 gfx_shipSprites[SS_SLAVETRANSPORT] = gfx_loadImage("gfx/slaveTrans1.png");
871 gfx_shipSprites[SS_SLAVETRANSPORT_L] = gfx_loadImage("gfx/slaveTrans2.png");
872 gfx_shipSprites[SS_BARRIER] = gfx_loadImage("gfx/barrier.png");
873 gfx_shipSprites[SS_MOBILESHIELD] = gfx_loadImage("gfx/mobileShield1.png");
874 gfx_shipSprites[SS_MOBILESHIELD_L] = gfx_loadImage("gfx/mobileShield2.png");
875 gfx_shipSprites[SS_ASTEROID] = gfx_loadImage("gfx/asteroid1.png");
876 gfx_shipSprites[SS_ASTEROID_SMALL] = gfx_loadImage("gfx/asteroid2.png");
877 gfx_shipSprites[SS_ASTEROID_SMALL_L] = gfx_loadImage("gfx/asteroid3.png");
878 gfx_shipSprites[SS_CLOAKFIGHTER] = gfx_loadImage("gfx/cloakShip1.png");
879 gfx_shipSprites[SS_CLOAKFIGHTER_L] = gfx_loadImage("gfx/cloakShip2.png");
880 gfx_shipSprites[SS_EVILURSULA] = gfx_loadImage("gfx/evilUrsula1.png");
881 gfx_shipSprites[SS_EVILURSULA_L] = gfx_loadImage("gfx/evilUrsula2.png");
882 gfx_shipSprites[SS_KRASS] = gfx_loadImage("gfx/merc1.png");
883 gfx_shipSprites[SS_KRASS_L] = gfx_loadImage("gfx/merc2.png");
884 gfx_shipSprites[SS_FRIGATE] = gfx_loadImage("gfx/frigateBody1.png");
885 gfx_shipSprites[SS_FRIGATE_L] = gfx_loadImage("gfx/frigateBody2.png");
886 gfx_shipSprites[SS_FRIGATE_WING1] = gfx_loadImage("gfx/frigateGun11.png");
887 gfx_shipSprites[SS_FRIGATE_WING1_L] = gfx_loadImage("gfx/frigateGun12.png");
888 gfx_shipSprites[SS_FRIGATE_WING2] = gfx_loadImage("gfx/frigateGun21.png");
889 gfx_shipSprites[SS_FRIGATE_WING2_L] = gfx_loadImage("gfx/frigateGun22.png");
890 gfx_shipSprites[SS_MINERBOSS] = gfx_loadImage("gfx/mineBoss1.png");
891 gfx_shipSprites[SS_MINERBOSS_L] = gfx_loadImage("gfx/mineBoss2.png");
892 gfx_shipSprites[SS_MINERBOSS_WING1] = gfx_loadImage("gfx/mineBossWing11.png");
893 gfx_shipSprites[SS_MINERBOSS_WING1_L] = gfx_loadImage("gfx/mineBossWing12.png");
894 gfx_shipSprites[SS_MINERBOSS_WING2] = gfx_loadImage("gfx/mineBossWing21.png");
895 gfx_shipSprites[SS_MINERBOSS_WING2_L] = gfx_loadImage("gfx/mineBossWing22.png");
896 gfx_shipSprites[SS_MINERBOSS_WING3] = gfx_loadImage("gfx/mineBossWing31.png");
897 gfx_shipSprites[SS_MINERBOSS_WING3_L] = gfx_loadImage("gfx/mineBossWing32.png");
898 gfx_shipSprites[SS_MINERBOSS_WING4] = gfx_loadImage("gfx/mineBossWing41.png");
899 gfx_shipSprites[SS_MINERBOSS_WING4_L] = gfx_loadImage("gfx/mineBossWing42.png");
900 gfx_shipSprites[SS_EXEC] = gfx_loadImage("gfx/execTrans1.png");
901 gfx_shipSprites[SS_EXEC_L] = gfx_loadImage("gfx/execTrans2.png");
902 gfx_shipSprites[SS_PLUTOBOSS] = gfx_loadImage("gfx/plutoBoss1.png");
903 gfx_shipSprites[SS_PLUTOBOSS_L] = gfx_loadImage("gfx/plutoBoss2.png");
904 gfx_shipSprites[SS_URANUSBOSS] = gfx_loadImage("gfx/splitBoss11.png");
905 gfx_shipSprites[SS_URANUSBOSS_L] = gfx_loadImage("gfx/splitBoss12.png");
906 gfx_shipSprites[SS_URANUSBOSS_WING1] = gfx_loadImage("gfx/splitBoss21.png");
907 gfx_shipSprites[SS_URANUSBOSS_WING1_L] = gfx_loadImage("gfx/splitBoss22.png");
908 gfx_shipSprites[SS_URANUSBOSS_WING2] = gfx_loadImage("gfx/splitBoss31.png");
909 gfx_shipSprites[SS_URANUSBOSS_WING2_L] = gfx_loadImage("gfx/splitBoss32.png");
910 gfx_shipSprites[SS_KLINE] = gfx_loadImage("gfx/kline11.png");
911 gfx_shipSprites[SS_KLINE_L] = gfx_loadImage("gfx/kline12.png");
912
913 /*
914 Create images of ships being hit that show a lot of red
915 */
916 for (int i = SS_HIT_INDEX ; i < SS_MAX ; i++)
917 {
918 if (gfx_shipSprites[i - SS_HIT_INDEX] == NULL)
919 continue;
920 gfx_shipSprites[i] = gfx_createSurface(gfx_shipSprites[i - SS_HIT_INDEX]->w,
921 gfx_shipSprites[i - SS_HIT_INDEX]->h);
922 SDL_SetSurfaceBlendMode(gfx_shipSprites[i - SS_HIT_INDEX], SDL_BLENDMODE_NONE);
923 gfx_blit(gfx_shipSprites[i - SS_HIT_INDEX], 0, 0, gfx_shipSprites[i]);
924 SDL_SetSurfaceBlendMode(gfx_shipSprites[i - SS_HIT_INDEX], SDL_BLENDMODE_BLEND);
925
926 switch (gfx_shipSprites[i]->format->BitsPerPixel)
927 {
928 case 32:
929 SDL_LockSurface(gfx_shipSprites[i]);
930 p32 = (Uint32 *)gfx_shipSprites[i]->pixels;
931 for (int j = 0; j < gfx_shipSprites[i]->w * gfx_shipSprites[i]->h; j++)
932 {
933 if (p32[j])
934 p32[j] |= gfx_shipSprites[i]->format->Rmask;
935 }
936 SDL_UnlockSurface(gfx_shipSprites[i]);
937 break;
938
939 case 16:
940 SDL_LockSurface(gfx_shipSprites[i]);
941 p16 = (Uint16 *)gfx_shipSprites[i]->pixels;
942 for (int j = 0; j < gfx_shipSprites[i]->w * gfx_shipSprites[i]->h; j++)
943 {
944 if (p16[j])
945 p16[j] |= gfx_shipSprites[i]->format->Rmask;
946 }
947 SDL_UnlockSurface(gfx_shipSprites[i]);
948 break;
949
950 case 8:
951 SDL_LockSurface(gfx_shipSprites[i]);
952 p8 = (Uint8 *)gfx_shipSprites[i]->pixels;
953 for (int j = 0; j < gfx_shipSprites[i]->w * gfx_shipSprites[i]->h; j++)
954 {
955 if (p8[j])
956 p8[j] = SDL_MapRGB(gfx_shipSprites[i]->format, 255, 0, 0);
957 }
958 SDL_UnlockSurface(gfx_shipSprites[i]);
959 break;
960 }
961
962 SDL_SetColorKey(gfx_shipSprites[i], SDL_TRUE,
963 SDL_MapRGB(gfx_shipSprites[i]->format, 0, 0, 0));
964 }
965
966 // Other sprites
967 gfx_sprites[SP_PLASMA_GREEN] = gfx_loadImage("gfx/plasmaGreen.png");
968 gfx_sprites[SP_PLASMA_RED] = gfx_loadImage("gfx/plasmaRed.png");
969 gfx_sprites[SP_DIR_PLASMA_GREEN] = gfx_loadImage("gfx/greenDir.png");
970 gfx_sprites[SP_DIR_PLASMA_RED] = gfx_loadImage("gfx/redDir.png");
971 gfx_sprites[SP_ROCKET] = gfx_loadImage("gfx/rocket1.png");
972 gfx_sprites[SP_ROCKET_L] = gfx_loadImage("gfx/rocket2.png");
973 gfx_sprites[SP_SMALL_EXPLOSION] = gfx_loadImage("gfx/explode1.png");
974 gfx_sprites[SP_SMALL_EXPLOSION_2] = gfx_loadImage("gfx/explode2.png");
975 gfx_sprites[SP_SMALL_EXPLOSION_3] = gfx_loadImage("gfx/explode3.png");
976 gfx_sprites[SP_SMALL_EXPLOSION_L] = gfx_loadImage("gfx/explode4.png");
977 gfx_sprites[SP_BIG_EXPLOSION] = gfx_loadImage("gfx/explode05.png");
978 gfx_sprites[SP_BIG_EXPLOSION_2] = gfx_loadImage("gfx/explode06.png");
979 gfx_sprites[SP_BIG_EXPLOSION_3] = gfx_loadImage("gfx/explode07.png");
980 gfx_sprites[SP_BIG_EXPLOSION_L] = gfx_loadImage("gfx/explode08.png");
981 gfx_sprites[SP_SMOKE] = gfx_loadImage("gfx/explode9.png");
982 gfx_sprites[SP_SMOKE_2] = gfx_loadImage("gfx/explode10.png");
983 gfx_sprites[SP_SMOKE_3] = gfx_loadImage("gfx/explode11.png");
984 gfx_sprites[SP_SMOKE_L] = gfx_loadImage("gfx/explode12.png");
985 gfx_sprites[SP_TINY_EXPLOSION] = gfx_loadImage("gfx/explode13.png");
986 gfx_sprites[SP_TINY_EXPLOSION_2] = gfx_loadImage("gfx/explode14.png");
987 gfx_sprites[SP_TINY_EXPLOSION_3] = gfx_loadImage("gfx/explode15.png");
988 gfx_sprites[SP_TINY_EXPLOSION_L] = gfx_loadImage("gfx/explode16.png");
989 gfx_sprites[SP_ELECTRICAL] = gfx_loadImage("gfx/elec1.png");
990 gfx_sprites[SP_ELECTRICAL_2] = gfx_loadImage("gfx/elec2.png");
991 gfx_sprites[SP_ELECTRICAL_3] = gfx_loadImage("gfx/elec3.png");
992 gfx_sprites[SP_ELECTRICAL_L] = gfx_loadImage("gfx/elec4.png");
993 gfx_sprites[SP_PICKUP_MONEY] = gfx_loadImage("gfx/dollar.png");
994 gfx_sprites[SP_PICKUP_PLASMA] = gfx_loadImage("gfx/rocket.png");
995 gfx_sprites[SP_PICKUP_SHIELD] = gfx_loadImage("gfx/heart.png");
996 gfx_sprites[SP_PICKUP_PLASMA_OUTPUT] = gfx_loadImage("gfx/plasmaAmmo.png");
997 gfx_sprites[SP_PICKUP_PLASMA_RATE] = gfx_loadImage("gfx/plasmaRate.png");
998 gfx_sprites[SP_PICKUP_PLASMA_POWER] = gfx_loadImage("gfx/plasmaDamage.png");
999 gfx_sprites[SP_CHAIN_LINK] = gfx_loadImage("gfx/chainLink.png");
1000 gfx_sprites[SP_MINE] = gfx_loadImage("gfx/mine.png");
1001 gfx_sprites[SP_CARGO] = gfx_loadImage("gfx/cargo1.png");
1002 gfx_sprites[SP_ION] = gfx_loadImage("gfx/stunBolt.png");
1003 gfx_sprites[SP_ARROW_NORTH] = gfx_loadImage("gfx/arrowNorth.png");
1004 gfx_sprites[SP_ARROW_NORTHEAST] = gfx_loadImage("gfx/arrowNorthEast.png");
1005 gfx_sprites[SP_ARROW_EAST] = gfx_loadImage("gfx/arrowEast.png");
1006 gfx_sprites[SP_ARROW_SOUTHEAST] = gfx_loadImage("gfx/arrowSouthEast.png");
1007 gfx_sprites[SP_ARROW_SOUTH] = gfx_loadImage("gfx/arrowSouth.png");
1008 gfx_sprites[SP_ARROW_SOUTHWEST] = gfx_loadImage("gfx/arrowSouthWest.png");
1009 gfx_sprites[SP_ARROW_WEST] = gfx_loadImage("gfx/arrowWest.png");
1010 gfx_sprites[SP_ARROW_NORTHWEST] = gfx_loadImage("gfx/arrowNorthWest.png");
1011 gfx_sprites[SP_ARROW_FRIEND_NORTH] = gfx_loadImage("gfx/friendArrowNorth.png");
1012 gfx_sprites[SP_ARROW_FRIEND_NORTHEAST] = gfx_loadImage("gfx/friendArrowNorthEast.png");
1013 gfx_sprites[SP_ARROW_FRIEND_EAST] = gfx_loadImage("gfx/friendArrowEast.png");
1014 gfx_sprites[SP_ARROW_FRIEND_SOUTHEAST] = gfx_loadImage("gfx/friendArrowSouthEast.png");
1015 gfx_sprites[SP_ARROW_FRIEND_SOUTH] = gfx_loadImage("gfx/friendArrowSouth.png");
1016 gfx_sprites[SP_ARROW_FRIEND_SOUTHWEST] = gfx_loadImage("gfx/friendArrowSouthWest.png");
1017 gfx_sprites[SP_ARROW_FRIEND_WEST] = gfx_loadImage("gfx/friendArrowWest.png");
1018 gfx_sprites[SP_ARROW_FRIEND_NORTHWEST] = gfx_loadImage("gfx/friendArrowNorthWest.png");
1019 gfx_sprites[SP_INDICATOR_TARGET] = gfx_loadImage("gfx/targetText.png");
1020 gfx_sprites[SP_INDICATOR_SID] = gfx_loadImage("gfx/sidText.png");
1021 gfx_sprites[SP_INDICATOR_PHOEBE] = gfx_loadImage("gfx/phoebeText.png");
1022 gfx_sprites[SP_INDICATOR_URSULA] = gfx_loadImage("gfx/ursulaText.png");
1023 gfx_sprites[SP_INDICATOR_KLINE] = gfx_loadImage("gfx/klineText.png");
1024 gfx_sprites[SP_ESCAPE_POD] = gfx_loadImage("gfx/pod.png");
1025 gfx_sprites[SP_ORE] = gfx_loadImage("gfx/ore1.png");
1026 gfx_sprites[SP_ORE_2] = gfx_loadImage("gfx/ore2.png");
1027 gfx_sprites[SP_ORE_L] = gfx_loadImage("gfx/ore3.png");
1028 gfx_sprites[SP_PICKUP_ROCKETS] = gfx_loadImage("gfx/rocketAmmo.png");
1029 gfx_sprites[SP_SUPERCHARGE] = gfx_loadImage("gfx/superCharge.png");
1030
1031 gfx_loadBackground(systemBackground[game.system]);
1032
1033 for (int i = 0 ; i < CD_MAX ; i++)
1034 {
1035 if (gfx_shipSprites[alien_defs[i].imageIndex[0]] != NULL)
1036 {
1037 alien_defs[i].image[0] = gfx_shipSprites[alien_defs[i].imageIndex[0]];
1038 alien_defs[i].image[1] = gfx_shipSprites[alien_defs[i].imageIndex[1]];
1039 alien_defs[i].engineX = alien_defs[i].image[0]->w;
1040 alien_defs[i].engineY = (alien_defs[i].image[0]->h / 2);
1041 }
1042 }
1043
1044 for (int i = 0 ; i < W_MAX ; i++)
1045 {
1046 weapons[i].image[0] = gfx_sprites[weapons[i].imageIndex[0]];
1047 weapons[i].image[1] = gfx_sprites[weapons[i].imageIndex[1]];
1048 }
1049 }
1050
1051 /*
1052 Custom loading to alter the font color before doing
1053 all other things
1054 */
gfx_loadFont()1055 void gfx_loadFont()
1056 {
1057 SDL_Surface *image, *newImage;
1058
1059 for (int i = 0 ; i < FONT_MAX ; i++)
1060 {
1061 image = IMG_Load("gfx/smallFont.png");
1062
1063 if (image == NULL) {
1064 printf("Couldn't load game font! (%s) Exitting.\n", SDL_GetError());
1065 exit(1);
1066 }
1067
1068 switch(i)
1069 {
1070 case FONT_RED:
1071 SDL_SetSurfaceColorMod(image, 255, 0, 0);
1072 break;
1073 case FONT_YELLOW:
1074 SDL_SetSurfaceColorMod(image, 255, 255, 0);
1075 break;
1076 case FONT_GREEN:
1077 SDL_SetSurfaceColorMod(image, 0, 255, 0);
1078 break;
1079 case FONT_CYAN:
1080 SDL_SetSurfaceColorMod(image, 0, 255, 255);
1081 break;
1082 case FONT_OUTLINE:
1083 SDL_SetSurfaceColorMod(image, 0, 0, 10);
1084 break;
1085 }
1086
1087 newImage = SDL_ConvertSurface(image, screen->format, 0);
1088
1089 gfx_fontSprites[i] = gfx_setTransparent(newImage);
1090
1091 SDL_FreeSurface(image);
1092 }
1093 }
1094