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