2011-08-24 14:14:44 +02:00
|
|
|
/*
|
|
|
|
Copyright (C) 2003 Parallel Realities
|
2015-03-01 21:37:32 +01:00
|
|
|
Copyright (C) 2011, 2012, 2013 Guus Sliepen
|
2020-12-26 06:10:10 +01:00
|
|
|
Copyright (C) 2015-2020 The Diligent Circle <diligentcircle@riseup.net>
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
2015-02-26 17:20:36 +01:00
|
|
|
as published by the Free Software Foundation; either version 3
|
2011-08-24 14:14:44 +02:00
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2015-02-26 17:20:36 +01:00
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2011-08-24 14:14:44 +02:00
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2015-02-26 17:20:36 +01:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2011-08-24 14:14:44 +02:00
|
|
|
*/
|
|
|
|
|
2015-06-16 05:56:20 +02:00
|
|
|
#include <ctype.h>
|
2019-06-06 04:13:48 +02:00
|
|
|
#include <libintl.h>
|
2017-01-25 16:48:29 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2015-06-16 05:56:20 +02:00
|
|
|
|
2017-01-21 05:48:53 +01:00
|
|
|
#include "SDL.h"
|
|
|
|
#include "SDL_image.h"
|
2019-06-04 03:05:38 +02:00
|
|
|
|
2019-06-06 04:13:48 +02:00
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
#ifndef NOFONT
|
2019-06-06 04:13:48 +02:00
|
|
|
|
|
|
|
// Undef MIN and MAX since pango-break.h includes these macros
|
|
|
|
// (avoids compiler warnings)
|
|
|
|
#ifdef MIN
|
|
|
|
#undef MIN
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef MAX
|
|
|
|
#undef MAX
|
|
|
|
#endif
|
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
#include "SDL_ttf.h"
|
2019-06-04 15:31:45 +02:00
|
|
|
#include <pango/pango-break.h>
|
2019-06-06 04:13:48 +02:00
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
#endif
|
2011-08-26 21:29:04 +02:00
|
|
|
|
2019-06-06 04:13:48 +02:00
|
|
|
|
2016-11-26 00:21:31 +01:00
|
|
|
#include "defs.h"
|
|
|
|
#include "structs.h"
|
|
|
|
|
2017-01-21 05:48:53 +01:00
|
|
|
#include "alien.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "game.h"
|
|
|
|
#include "screen.h"
|
|
|
|
#include "weapons.h"
|
|
|
|
|
2019-05-30 22:46:55 +02:00
|
|
|
SDL_Surface *gfx_unscaledBackground;
|
2015-11-07 01:43:34 +01:00
|
|
|
SDL_Surface *gfx_background;
|
Fixed more magic numbers.
God, this one was definitely the biggest headache of all of the
magic number erasing. Never did I expect such cryptic problems.
The first problem was that the entirety of the player's weapon
struct was a part of the save file, *including the weapon's "image
indexes"*. Since the indexes have been changed, and the originally
used one is now unavailable when it's requested, this was causing
a segfault later on. Had to fix this by setting the image index
when the game is loaded.
The second problem was related to another bug I've been confused
about for years: the one that causes mobile rays to fire 5 green
shots. The entire reason those shots were green was because
the weapon's image indexes were undefined, and *that was causing
them to default to 0*. 0 was simply the index of green plasma.
Of course, though, now attempting to use that image causes a
segfault, so for now, I've fixed this by changing the image index
of the mobile rays to the red plasma bolts.
There are still some magic numbers left, related to the intermission
screen. But the hardest part is now done, thank God.
2016-01-06 04:12:29 +01:00
|
|
|
SDL_Surface *gfx_sprites[SP_MAX];
|
2016-01-04 15:07:30 +01:00
|
|
|
SDL_Surface *gfx_faceSprites[FS_MAX];
|
2016-01-04 22:34:29 +01:00
|
|
|
SDL_Surface *gfx_shipSprites[SS_MAX];
|
Fixed more magic numbers.
God, this one was definitely the biggest headache of all of the
magic number erasing. Never did I expect such cryptic problems.
The first problem was that the entirety of the player's weapon
struct was a part of the save file, *including the weapon's "image
indexes"*. Since the indexes have been changed, and the originally
used one is now unavailable when it's requested, this was causing
a segfault later on. Had to fix this by setting the image index
when the game is loaded.
The second problem was related to another bug I've been confused
about for years: the one that causes mobile rays to fire 5 green
shots. The entire reason those shots were green was because
the weapon's image indexes were undefined, and *that was causing
them to default to 0*. 0 was simply the index of green plasma.
Of course, though, now attempting to use that image causes a
segfault, so for now, I've fixed this by changing the image index
of the mobile rays to the red plasma bolts.
There are still some magic numbers left, related to the intermission
screen. But the hardest part is now done, thank God.
2016-01-06 04:12:29 +01:00
|
|
|
SDL_Surface *gfx_fontSprites[FONT_MAX];
|
2016-01-05 04:25:00 +01:00
|
|
|
SDL_Surface *gfx_shopSprites[SHOP_S_MAX];
|
2016-11-26 00:35:25 +01:00
|
|
|
TextObject gfx_textSprites[TS_MAX];
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_Surface *gfx_messageBox;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
#ifndef NOFONT
|
|
|
|
TTF_Font *gfx_unicodeFont;
|
|
|
|
#endif
|
|
|
|
|
2015-09-26 14:49:21 +02:00
|
|
|
void gfx_init()
|
2011-08-24 14:14:44 +02:00
|
|
|
{
|
2019-05-23 17:25:54 +02:00
|
|
|
screen_bufferHead = malloc(sizeof(*screen_bufferHead));
|
2019-05-20 00:22:53 +02:00
|
|
|
if (screen_bufferHead == NULL)
|
|
|
|
{
|
|
|
|
engine_error("Failed to allocate memory for buffer head.");
|
|
|
|
}
|
2015-11-02 23:53:05 +01:00
|
|
|
screen_bufferHead->next = NULL;
|
|
|
|
screen_bufferTail = screen_bufferHead;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
Fixed more magic numbers.
God, this one was definitely the biggest headache of all of the
magic number erasing. Never did I expect such cryptic problems.
The first problem was that the entirety of the player's weapon
struct was a part of the save file, *including the weapon's "image
indexes"*. Since the indexes have been changed, and the originally
used one is now unavailable when it's requested, this was causing
a segfault later on. Had to fix this by setting the image index
when the game is loaded.
The second problem was related to another bug I've been confused
about for years: the one that causes mobile rays to fire 5 green
shots. The entire reason those shots were green was because
the weapon's image indexes were undefined, and *that was causing
them to default to 0*. 0 was simply the index of green plasma.
Of course, though, now attempting to use that image causes a
segfault, so for now, I've fixed this by changing the image index
of the mobile rays to the red plasma bolts.
There are still some magic numbers left, related to the intermission
screen. But the hardest part is now done, thank God.
2016-01-06 04:12:29 +01:00
|
|
|
for (int i = 0 ; i < SP_MAX ; i++)
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_sprites[i] = NULL;
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2016-01-04 22:34:29 +01:00
|
|
|
for (int i = 0 ; i < SS_MAX ; i++)
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_shipSprites[i] = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2016-01-04 18:41:19 +01:00
|
|
|
for (int i = 0 ; i < TS_MAX ; i++)
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_textSprites[i].image = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2016-01-05 04:25:00 +01:00
|
|
|
for (int i = 0 ; i < SHOP_S_MAX ; i++)
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_shopSprites[i] = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
Fixed more magic numbers.
God, this one was definitely the biggest headache of all of the
magic number erasing. Never did I expect such cryptic problems.
The first problem was that the entirety of the player's weapon
struct was a part of the save file, *including the weapon's "image
indexes"*. Since the indexes have been changed, and the originally
used one is now unavailable when it's requested, this was causing
a segfault later on. Had to fix this by setting the image index
when the game is loaded.
The second problem was related to another bug I've been confused
about for years: the one that causes mobile rays to fire 5 green
shots. The entire reason those shots were green was because
the weapon's image indexes were undefined, and *that was causing
them to default to 0*. 0 was simply the index of green plasma.
Of course, though, now attempting to use that image causes a
segfault, so for now, I've fixed this by changing the image index
of the mobile rays to the red plasma bolts.
There are still some magic numbers left, related to the intermission
screen. But the hardest part is now done, thank God.
2016-01-06 04:12:29 +01:00
|
|
|
for (int i = 0 ; i < FONT_MAX ; i++)
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_fontSprites[i] = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-11-07 01:43:34 +01:00
|
|
|
gfx_background = NULL;
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_messageBox = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
screen = NULL;
|
2019-06-02 17:28:26 +02:00
|
|
|
|
|
|
|
#ifndef NOFONT
|
2019-06-04 03:05:38 +02:00
|
|
|
if (TTF_Init() < 0)
|
|
|
|
{
|
|
|
|
printf("ERROR: Could not initialize TTF: %s\n", TTF_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2019-06-06 04:13:48 +02:00
|
|
|
/// If the TakaoGothic font is able to display the text of the language
|
|
|
|
/// being translated to, DO NOT CHANGE THIS! If, however, the language
|
|
|
|
/// requires characters not available in the default font, you can
|
|
|
|
/// place that font in the "data" directory and indicate the name of the
|
|
|
|
/// alternate font as a translation to "TakaoPGothic.ttf" (leaving the
|
|
|
|
/// rest of the string unchanged). Please ensure that the font displays
|
|
|
|
/// correctly with ALL text (space is limited and some fonts take up
|
|
|
|
/// more space than others), and also check the license of the font
|
|
|
|
/// before distributing to make sure you are allowed to do so.
|
|
|
|
gfx_unicodeFont = TTF_OpenFont(_("data/TakaoPGothic.ttf"), 13);
|
2019-06-02 17:28:26 +02:00
|
|
|
if (gfx_unicodeFont == NULL)
|
|
|
|
{
|
|
|
|
printf("ERROR: TTF_OpenFont: %s\n", TTF_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-06-04 17:45:57 +02:00
|
|
|
TTF_SetFontStyle(gfx_unicodeFont, TTF_STYLE_BOLD);
|
2019-06-02 17:28:26 +02:00
|
|
|
#endif
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2015-09-26 14:49:21 +02:00
|
|
|
SDL_Surface *gfx_setTransparent(SDL_Surface *sprite)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2013-10-01 14:33:33 +02:00
|
|
|
SDL_SetColorKey(sprite, SDL_TRUE, SDL_MapRGB(sprite->format, 0, 0, 0));
|
2011-08-26 23:53:46 +02:00
|
|
|
return sprite;
|
|
|
|
}
|
|
|
|
|
2015-09-26 14:49:21 +02:00
|
|
|
void gfx_blit(SDL_Surface *image, int x, int y, SDL_Surface *dest)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-02 22:59:48 +01:00
|
|
|
SDL_Rect blitRect;
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
// Exit early if image is not on dest at all
|
2015-03-01 03:49:56 +01:00
|
|
|
if (x + image->w < 0 || x >= dest->w || y + image->h < 0 || y >= dest->h)
|
2011-08-26 23:53:46 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Set up a rectangle to draw to
|
|
|
|
blitRect.x = x;
|
|
|
|
blitRect.y = y;
|
|
|
|
blitRect.w = image->w;
|
|
|
|
blitRect.h = image->h;
|
|
|
|
|
|
|
|
/* Blit onto the destination surface */
|
2015-03-01 03:49:56 +01:00
|
|
|
if (SDL_BlitSurface(image, NULL, dest, &blitRect) < 0)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
|
|
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
2016-01-02 22:59:48 +01:00
|
|
|
engine_showError(2, "");
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2015-03-31 19:02:09 +02:00
|
|
|
// Only if it is to the screen, mark the region as damaged
|
2015-03-01 03:49:56 +01:00
|
|
|
if (dest == screen)
|
2015-11-02 23:53:05 +01:00
|
|
|
screen_addBuffer(blitRect.x, blitRect.y, blitRect.w, blitRect.h);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
In 16 bit mode this is slow. VERY slow. Don't write directly to a surface
|
|
|
|
that constantly needs updating (eg - the main game screen)
|
|
|
|
*/
|
2020-03-07 01:06:48 +01:00
|
|
|
static int gfx_renderStringBase(const char *in, int x, int y, int real_x, int fontColor, int wrap, SDL_Surface *dest)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2015-06-16 05:56:20 +02:00
|
|
|
int i;
|
|
|
|
int splitword;
|
2020-03-07 01:06:48 +01:00
|
|
|
int creal_x;
|
2011-08-26 23:53:46 +02:00
|
|
|
SDL_Rect area;
|
2015-06-16 05:56:20 +02:00
|
|
|
SDL_Rect letter;
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
area.x = x;
|
|
|
|
area.y = y;
|
2019-06-06 04:13:48 +02:00
|
|
|
area.w = PIXFONT_W;
|
|
|
|
area.h = PIXFONT_H;
|
2020-03-07 01:06:48 +01:00
|
|
|
creal_x = real_x;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
letter.y = 0;
|
2019-06-06 04:13:48 +02:00
|
|
|
letter.w = PIXFONT_W;
|
|
|
|
letter.h = PIXFONT_H;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
while (*in != '\0')
|
|
|
|
{
|
2015-06-16 05:56:20 +02:00
|
|
|
if (*in != ' ')
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
|
|
|
letter.x = (*in - 33);
|
2019-06-06 04:13:48 +02:00
|
|
|
letter.x *= PIXFONT_W;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
/* Blit onto the screen surface */
|
2016-01-04 04:39:16 +01:00
|
|
|
if (SDL_BlitSurface(gfx_fontSprites[fontColor], &letter, dest, &area) < 0)
|
2015-06-16 05:56:20 +02:00
|
|
|
{
|
2011-08-26 23:53:46 +02:00
|
|
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
2016-01-02 22:59:48 +01:00
|
|
|
engine_showError(2, "");
|
2015-06-16 05:56:20 +02:00
|
|
|
}
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-06 04:13:48 +02:00
|
|
|
area.x += PIXFONT_W + 1;
|
2020-03-07 01:06:48 +01:00
|
|
|
creal_x += PIXFONT_W + 1;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
if (wrap)
|
|
|
|
{
|
2020-03-07 01:06:48 +01:00
|
|
|
if ((creal_x > (dest->w - 70)) && (*in == ' '))
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2019-06-06 04:13:48 +02:00
|
|
|
area.y += PIXFONT_LINE_HEIGHT;
|
2011-08-26 23:53:46 +02:00
|
|
|
area.x = x;
|
2020-03-07 01:06:48 +01:00
|
|
|
creal_x = real_x;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
2020-03-07 01:06:48 +01:00
|
|
|
else if (creal_x > (dest->w - 31))
|
2015-06-16 05:56:20 +02:00
|
|
|
{
|
|
|
|
splitword = 1;
|
|
|
|
for (i = 0 ; i < 4 ; i++)
|
|
|
|
{
|
|
|
|
if (!isalpha(*(in + i)))
|
|
|
|
{
|
|
|
|
splitword = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (splitword)
|
|
|
|
{
|
|
|
|
letter.x = (int)('-') - 33;
|
2019-06-06 04:13:48 +02:00
|
|
|
letter.x *= PIXFONT_W;
|
2016-01-04 04:39:16 +01:00
|
|
|
if (SDL_BlitSurface(gfx_fontSprites[fontColor], &letter, dest, &area) < 0)
|
2015-06-16 05:56:20 +02:00
|
|
|
{
|
|
|
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
2016-01-02 22:59:48 +01:00
|
|
|
engine_showError(2, "");
|
2015-06-16 05:56:20 +02:00
|
|
|
}
|
2019-06-06 04:13:48 +02:00
|
|
|
area.y += PIXFONT_LINE_HEIGHT;
|
2015-06-16 05:56:20 +02:00
|
|
|
area.x = x;
|
2020-03-07 01:06:48 +01:00
|
|
|
creal_x = real_x;
|
2015-06-16 05:56:20 +02:00
|
|
|
}
|
|
|
|
}
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
in++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return area.y;
|
|
|
|
}
|
|
|
|
|
2020-03-07 01:06:48 +01:00
|
|
|
/*
|
|
|
|
Legacy text rendering function, the original one which only supports
|
|
|
|
ASCII. Generally not used anymore with the exception of some title
|
|
|
|
screen bits that remain untranslated, but also used as a fallback if the
|
|
|
|
game is compiled without SDL_ttf and Pango. Works OK on the English
|
|
|
|
text, but not likely to work well with translations (and won't work at
|
|
|
|
all for languages like Chinese or Japanese based on non-Latin
|
|
|
|
alphabets).
|
|
|
|
*/
|
2015-11-04 02:26:56 +01:00
|
|
|
int gfx_renderString(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2015-11-06 16:12:57 +01:00
|
|
|
if (x == -1)
|
2019-06-06 04:13:48 +02:00
|
|
|
x = (dest->w - (strlen(in) * (PIXFONT_W + 1))) / 2;
|
2015-11-06 16:12:57 +01:00
|
|
|
|
2020-03-07 01:06:48 +01:00
|
|
|
gfx_renderStringBase(in, x, y - 1, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderStringBase(in, x, y + 1, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderStringBase(in, x, y + 2, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderStringBase(in, x - 1, y, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderStringBase(in, x - 2, y, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderStringBase(in, x + 1, y, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
return gfx_renderStringBase(in, x, y, x, fontColor, wrap, dest);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
#ifdef NOFONT
|
2019-06-12 16:57:16 +02:00
|
|
|
int gfx_unicodeWidth(const char *in)
|
|
|
|
{
|
|
|
|
return (PIXFONT_W + 1) * strlen(in);
|
|
|
|
}
|
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
int gfx_renderUnicode(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest)
|
|
|
|
{
|
|
|
|
return gfx_renderString(in, x, y, fontColor, wrap, dest);
|
|
|
|
}
|
2019-06-12 16:57:16 +02:00
|
|
|
|
2019-06-02 17:28:26 +02:00
|
|
|
#else
|
2020-07-27 16:12:47 +02:00
|
|
|
static int gfx_charIsUTF8Start(unsigned char c)
|
|
|
|
{
|
|
|
|
// Top bit not set (single byte ASCII character)
|
|
|
|
if ((c & 0x80) == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
// Top two bits set (start of multi-byte character)
|
|
|
|
if ((c & 0x80) && (c & 0x40))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
// Top bit set, but second bit not set (somewhere in the middle)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-06-12 16:57:16 +02:00
|
|
|
int gfx_unicodeWidth(const char *in)
|
|
|
|
{
|
|
|
|
int w;
|
|
|
|
|
|
|
|
if (TTF_SizeUTF8(gfx_unicodeFont, in, &w, NULL) < 0)
|
|
|
|
{
|
|
|
|
engine_error(TTF_GetError());
|
|
|
|
}
|
|
|
|
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
2019-06-15 20:26:50 +02:00
|
|
|
int gfx_renderUnicodeBase(const char *in, int x, int y, int real_x, int fontColor, int wrap, SDL_Surface *dest)
|
2019-06-02 17:28:26 +02:00
|
|
|
{
|
|
|
|
SDL_Surface *textSurf;
|
|
|
|
SDL_Color color;
|
|
|
|
int w, h;
|
2019-06-06 04:13:48 +02:00
|
|
|
int avail_w;
|
2019-06-04 03:05:38 +02:00
|
|
|
int changed;
|
2019-06-02 17:28:26 +02:00
|
|
|
int breakPoints[STRMAX];
|
|
|
|
int nBreakPoints;
|
2019-06-04 15:31:45 +02:00
|
|
|
char testStr[STRMAX];
|
2019-06-03 21:54:02 +02:00
|
|
|
char remainingStr[STRMAX];
|
2019-06-04 04:36:03 +02:00
|
|
|
PangoLogAttr logAttrs[STRMAX];
|
|
|
|
int nLogAttrs;
|
2019-06-04 15:31:45 +02:00
|
|
|
int i;
|
2019-06-03 01:53:03 +02:00
|
|
|
SDL_Rect area;
|
2019-06-06 04:13:48 +02:00
|
|
|
|
2019-06-07 06:18:24 +02:00
|
|
|
if (strcmp(in, "") == 0)
|
|
|
|
return y;
|
|
|
|
|
2019-06-15 20:26:50 +02:00
|
|
|
avail_w = dest->w - real_x;
|
2019-06-06 04:13:48 +02:00
|
|
|
|
2019-06-04 15:49:26 +02:00
|
|
|
switch (fontColor)
|
|
|
|
{
|
|
|
|
case FONT_WHITE:
|
|
|
|
color.r = 255;
|
|
|
|
color.g = 255;
|
|
|
|
color.b = 255;
|
|
|
|
break;
|
|
|
|
case FONT_RED:
|
|
|
|
color.r = 255;
|
|
|
|
color.g = 0;
|
|
|
|
color.b = 0;
|
|
|
|
break;
|
|
|
|
case FONT_YELLOW:
|
|
|
|
color.r = 255;
|
|
|
|
color.g = 255;
|
|
|
|
color.b = 0;
|
|
|
|
break;
|
|
|
|
case FONT_GREEN:
|
|
|
|
color.r = 0;
|
|
|
|
color.g = 255;
|
|
|
|
color.b = 0;
|
|
|
|
break;
|
|
|
|
case FONT_CYAN:
|
|
|
|
color.r = 0;
|
|
|
|
color.g = 255;
|
|
|
|
color.b = 255;
|
|
|
|
break;
|
|
|
|
case FONT_OUTLINE:
|
|
|
|
color.r = 0;
|
|
|
|
color.g = 0;
|
|
|
|
color.b = 10;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
color.r = 255;
|
|
|
|
color.g = 255;
|
|
|
|
color.b = 255;
|
|
|
|
}
|
2019-06-02 17:28:26 +02:00
|
|
|
|
|
|
|
if (gfx_unicodeFont != NULL)
|
|
|
|
{
|
2019-06-03 20:05:31 +02:00
|
|
|
strcpy(remainingStr, in);
|
|
|
|
if (TTF_SizeUTF8(gfx_unicodeFont, remainingStr, &w, &h) < 0)
|
2019-06-02 17:28:26 +02:00
|
|
|
{
|
|
|
|
engine_error(TTF_GetError());
|
|
|
|
}
|
2019-06-02 23:40:32 +02:00
|
|
|
|
2019-06-06 04:13:48 +02:00
|
|
|
changed = wrap;
|
|
|
|
while (changed && (w > avail_w))
|
2019-06-02 17:28:26 +02:00
|
|
|
{
|
2019-06-04 04:36:03 +02:00
|
|
|
nLogAttrs = strlen(remainingStr) + 1;
|
|
|
|
pango_get_log_attrs(remainingStr, strlen(remainingStr), -1, NULL, logAttrs, nLogAttrs);
|
2019-06-06 04:13:48 +02:00
|
|
|
|
2019-06-03 20:05:31 +02:00
|
|
|
nBreakPoints = 0;
|
2019-06-04 04:36:03 +02:00
|
|
|
for (i = 0; i < nLogAttrs; i++)
|
2019-06-02 17:28:26 +02:00
|
|
|
{
|
2020-07-27 16:12:47 +02:00
|
|
|
if (logAttrs[i].is_line_break
|
|
|
|
&& gfx_charIsUTF8Start(remainingStr[i]))
|
2019-06-02 17:28:26 +02:00
|
|
|
{
|
2020-07-25 16:58:53 +02:00
|
|
|
breakPoints[nBreakPoints] = i;
|
2019-06-04 04:36:03 +02:00
|
|
|
nBreakPoints++;
|
2019-06-02 17:28:26 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-02 23:40:32 +02:00
|
|
|
|
2019-06-04 03:05:38 +02:00
|
|
|
changed = 0;
|
2019-06-02 23:40:32 +02:00
|
|
|
for (i = nBreakPoints - 1; i >= 0; i--)
|
2019-06-02 17:28:26 +02:00
|
|
|
{
|
2019-06-03 21:54:02 +02:00
|
|
|
strncpy(testStr, remainingStr, breakPoints[i]);
|
2019-06-04 15:31:45 +02:00
|
|
|
testStr[breakPoints[i]] = '\0';
|
2019-06-02 23:40:32 +02:00
|
|
|
if (TTF_SizeUTF8(gfx_unicodeFont, testStr, &w, &h) < 0)
|
|
|
|
{
|
|
|
|
engine_error(TTF_GetError());
|
|
|
|
}
|
2019-06-06 04:13:48 +02:00
|
|
|
if (w <= avail_w)
|
2019-06-02 17:28:26 +02:00
|
|
|
{
|
2019-06-07 06:18:24 +02:00
|
|
|
textSurf = TTF_RenderUTF8_Blended(gfx_unicodeFont, testStr, color);
|
|
|
|
if (textSurf == NULL)
|
|
|
|
{
|
|
|
|
printf("While rendering testStr \"%s\" as unicode...\n", testStr);
|
|
|
|
engine_error("Attempted to render UTF8, got null surface!");
|
|
|
|
}
|
|
|
|
|
2019-06-03 01:53:03 +02:00
|
|
|
area.x = x;
|
|
|
|
area.y = y;
|
2019-06-03 21:54:02 +02:00
|
|
|
area.w = textSurf->w;
|
|
|
|
area.h = textSurf->h;
|
2019-06-03 01:53:03 +02:00
|
|
|
if (SDL_BlitSurface(textSurf, NULL, dest, &area) < 0)
|
|
|
|
{
|
|
|
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
|
|
|
engine_showError(2, "");
|
|
|
|
}
|
2019-06-04 15:31:45 +02:00
|
|
|
SDL_FreeSurface(textSurf);
|
|
|
|
textSurf = NULL;
|
2019-06-06 04:13:48 +02:00
|
|
|
y += TTF_FontHeight(gfx_unicodeFont) + 1;
|
|
|
|
|
2019-06-04 15:31:45 +02:00
|
|
|
memmove(remainingStr, remainingStr + breakPoints[i],
|
|
|
|
(strlen(remainingStr) - breakPoints[i]) + 1);
|
2019-06-04 03:05:38 +02:00
|
|
|
changed = 1;
|
2019-06-02 23:40:32 +02:00
|
|
|
break;
|
2019-06-02 17:28:26 +02:00
|
|
|
}
|
2019-06-02 23:40:32 +02:00
|
|
|
}
|
2019-06-02 17:28:26 +02:00
|
|
|
|
2019-06-02 23:40:32 +02:00
|
|
|
if (TTF_SizeUTF8(gfx_unicodeFont, remainingStr, &w, &h) < 0)
|
|
|
|
{
|
|
|
|
engine_error(TTF_GetError());
|
2019-06-02 17:28:26 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-07 06:18:24 +02:00
|
|
|
textSurf = TTF_RenderUTF8_Blended(gfx_unicodeFont, remainingStr, color);
|
|
|
|
if (textSurf == NULL)
|
|
|
|
{
|
|
|
|
printf("While rendering remainingStr \"%s\" as unicode...\n", remainingStr);
|
|
|
|
engine_error("Attempted to render UTF8, got null surface!");
|
|
|
|
}
|
|
|
|
|
2019-06-04 03:05:38 +02:00
|
|
|
area.x = x;
|
|
|
|
area.y = y;
|
|
|
|
area.w = textSurf->w;
|
|
|
|
area.h = textSurf->h;
|
|
|
|
if (SDL_BlitSurface(textSurf, NULL, dest, &area) < 0)
|
|
|
|
{
|
|
|
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
|
|
|
engine_showError(2, "");
|
|
|
|
}
|
2019-06-07 06:18:24 +02:00
|
|
|
SDL_FreeSurface(textSurf);
|
|
|
|
textSurf = NULL;
|
2019-06-06 04:13:48 +02:00
|
|
|
y += TTF_FontHeight(gfx_unicodeFont) + 1;
|
2019-06-04 03:05:38 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
engine_warn("gfx_unicodeFont is NULL!");
|
2019-06-02 17:28:26 +02:00
|
|
|
}
|
2019-06-03 01:53:03 +02:00
|
|
|
|
|
|
|
return y;
|
2019-06-02 17:28:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int gfx_renderUnicode(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest)
|
|
|
|
{
|
2019-06-06 04:13:48 +02:00
|
|
|
int w;
|
|
|
|
|
|
|
|
if (x == -1)
|
|
|
|
{
|
|
|
|
TTF_SizeUTF8(gfx_unicodeFont, in, &w, NULL);
|
|
|
|
x = (dest->w - MIN(w, dest->w)) / 2;
|
|
|
|
}
|
|
|
|
|
2019-06-15 20:26:50 +02:00
|
|
|
gfx_renderUnicodeBase(in, x, y - 1, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderUnicodeBase(in, x, y + 1, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderUnicodeBase(in, x, y + 2, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderUnicodeBase(in, x - 1, y, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderUnicodeBase(in, x - 2, y, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
gfx_renderUnicodeBase(in, x + 1, y, x, FONT_OUTLINE, wrap, dest);
|
|
|
|
return gfx_renderUnicodeBase(in, x, y, x, fontColor, wrap, dest);
|
2019-06-02 17:28:26 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
/*
|
|
|
|
* Set the pixel at (x, y) to the given value
|
|
|
|
* NOTE: The surface must be locked before calling this!
|
|
|
|
*/
|
2015-11-07 03:35:07 +01:00
|
|
|
void gfx_putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2015-03-01 03:49:06 +01:00
|
|
|
int bpp = surface->format->BytesPerPixel;
|
|
|
|
/* Here p is the address to the pixel we want to set */
|
|
|
|
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-03-01 03:49:06 +01:00
|
|
|
switch(bpp)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
*p = pixel;
|
|
|
|
break;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-03-01 03:49:06 +01:00
|
|
|
case 2:
|
|
|
|
*(Uint16 *)p = pixel;
|
|
|
|
break;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-03-01 03:49:06 +01:00
|
|
|
case 3:
|
|
|
|
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
|
|
|
{
|
2011-08-26 23:53:46 +02:00
|
|
|
p[0] = (pixel >> 16) & 0xff;
|
|
|
|
p[1] = (pixel >> 8) & 0xff;
|
|
|
|
p[2] = pixel & 0xff;
|
2015-03-01 03:49:06 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-08-26 23:53:46 +02:00
|
|
|
p[0] = pixel & 0xff;
|
|
|
|
p[1] = (pixel >> 8) & 0xff;
|
|
|
|
p[2] = (pixel >> 16) & 0xff;
|
2015-03-01 03:49:06 +01:00
|
|
|
}
|
|
|
|
break;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-03-01 03:49:06 +01:00
|
|
|
case 4:
|
|
|
|
*(Uint32 *)p = pixel;
|
|
|
|
break;
|
|
|
|
}
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
A quick(?) circle draw function. This code was posted to the SDL
|
|
|
|
mailing list... I didn't write it myself.
|
|
|
|
*/
|
2015-11-20 20:11:12 +01:00
|
|
|
void gfx_drawCircle(int xc, int yc, int R, SDL_Surface *PIX, int col)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-02 22:59:48 +01:00
|
|
|
int x = 0;
|
|
|
|
int xx = 0;
|
|
|
|
int y = R;
|
|
|
|
int yy = 2 * R;
|
2015-03-01 03:49:06 +01:00
|
|
|
int p = 1 - R;
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-11-07 03:35:07 +01:00
|
|
|
gfx_putPixel(PIX, xc, yc - y, col);
|
|
|
|
gfx_putPixel(PIX, xc, yc + y, col);
|
|
|
|
gfx_putPixel(PIX, xc - y, yc, col);
|
|
|
|
gfx_putPixel(PIX, xc + y, yc, col);
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-03-01 03:49:06 +01:00
|
|
|
while (x < y)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
|
|
|
xx += 2;
|
2015-03-01 03:49:06 +01:00
|
|
|
x++;
|
2011-08-26 23:53:46 +02:00
|
|
|
if (p >= 0)
|
|
|
|
{
|
|
|
|
yy -= 2;
|
2015-03-01 03:49:06 +01:00
|
|
|
y--;
|
2011-08-26 23:53:46 +02:00
|
|
|
p -= yy;
|
|
|
|
}
|
|
|
|
p += xx + 1;
|
|
|
|
|
2015-11-07 03:35:07 +01:00
|
|
|
gfx_putPixel(PIX, xc - x, yc - y, col);
|
|
|
|
gfx_putPixel(PIX, xc + x, yc - y, col);
|
|
|
|
gfx_putPixel(PIX, xc - x, yc + y, col);
|
|
|
|
gfx_putPixel(PIX, xc + x, yc + y, col);
|
|
|
|
gfx_putPixel(PIX, xc - y, yc - x, col);
|
|
|
|
gfx_putPixel(PIX, xc + y, yc - x, col);
|
|
|
|
gfx_putPixel(PIX, xc - y, yc + x, col);
|
|
|
|
gfx_putPixel(PIX, xc + y, yc + x, col);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((x = y))
|
|
|
|
{
|
2015-11-07 03:35:07 +01:00
|
|
|
gfx_putPixel(PIX, xc - x, yc - y, col);
|
|
|
|
gfx_putPixel(PIX, xc + x, yc - y, col);
|
|
|
|
gfx_putPixel(PIX, xc - x, yc + y, col);
|
|
|
|
gfx_putPixel(PIX, xc + x, yc + y, col);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-31 16:47:27 +01:00
|
|
|
void gfx_drawRect(SDL_Surface *dest, int x, int y, int w, int h, Uint8 red, Uint8 green, Uint8 blue)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2017-01-22 06:22:03 +01:00
|
|
|
SDL_Rect r = {x, y, w, h};
|
2011-08-26 23:53:46 +02:00
|
|
|
SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, red, green, blue));
|
|
|
|
|
2017-01-28 06:56:31 +01:00
|
|
|
r.h = 1;
|
|
|
|
SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 255, 255, 255));
|
|
|
|
|
|
|
|
r.w = 1;
|
|
|
|
r.h = h;
|
|
|
|
SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 255, 255, 255));
|
|
|
|
|
|
|
|
r.y = y + h;
|
|
|
|
r.w = w;
|
|
|
|
r.h = 1;
|
|
|
|
SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 128, 128, 128));
|
|
|
|
|
|
|
|
r.x = x + w;
|
|
|
|
r.y = y + 1;
|
|
|
|
r.w = 1;
|
|
|
|
r.h = h - 1;
|
|
|
|
SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, 128, 128, 128));
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2015-12-31 16:47:27 +01:00
|
|
|
SDL_Surface *gfx_createSurface(int width, int height)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2013-09-30 16:52:43 +02:00
|
|
|
SDL_Surface *surface;
|
2011-08-26 23:53:46 +02:00
|
|
|
Uint32 rmask, gmask, bmask, amask;
|
|
|
|
|
|
|
|
/* SDL interprets each pixel as a 32-bit number, so our masks must depend
|
|
|
|
on the endianness (byte order) of the machine */
|
|
|
|
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
|
|
|
rmask = 0xff000000;
|
|
|
|
gmask = 0x00ff0000;
|
|
|
|
bmask = 0x0000ff00;
|
|
|
|
amask = 0x000000ff;
|
|
|
|
#else
|
|
|
|
rmask = 0x000000ff;
|
|
|
|
gmask = 0x0000ff00;
|
|
|
|
bmask = 0x00ff0000;
|
|
|
|
amask = 0xff000000;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);
|
|
|
|
|
|
|
|
if (surface == NULL) {
|
|
|
|
printf("CreateRGBSurface failed: %s\n", SDL_GetError());
|
2016-01-02 22:59:48 +01:00
|
|
|
engine_showError(2, "");
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2013-09-30 16:52:43 +02:00
|
|
|
return surface;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2015-12-31 16:47:27 +01:00
|
|
|
SDL_Surface *gfx_createTextSurface(const char *inString, int color)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2019-06-07 06:18:24 +02:00
|
|
|
int w, h, th;
|
|
|
|
|
|
|
|
#ifndef NOFONT
|
|
|
|
if (TTF_SizeUTF8(gfx_unicodeFont, inString, &w, &th) < 0)
|
|
|
|
{
|
|
|
|
engine_error(TTF_GetError());
|
|
|
|
}
|
|
|
|
w += 2;
|
|
|
|
th += 2;
|
|
|
|
h = MAX(th, PIXFONT_LINE_HEIGHT);
|
|
|
|
#else
|
|
|
|
w = strlen(inString) * (PIXFONT_W + 1) + 1;
|
|
|
|
th = PIXFONT_H;
|
|
|
|
h = MAX(PIXFONT_LINE_HEIGHT, PIXFONT_H + 2);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SDL_Surface *surface = gfx_createSurface(w, h);
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2019-06-07 06:18:24 +02:00
|
|
|
gfx_renderUnicode(inString, 1, (h - th) / 2, color, 0, surface);
|
2011-08-26 23:53:46 +02:00
|
|
|
|
2015-09-26 14:49:21 +02:00
|
|
|
return gfx_setTransparent(surface);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
2011-08-24 14:14:44 +02:00
|
|
|
|
2015-12-31 16:47:27 +01:00
|
|
|
void gfx_createTextObject(int index, const char *inString, int x, int y, int fontColor)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2017-03-27 05:52:05 +02:00
|
|
|
// Reset the life of the text object
|
|
|
|
gfx_textSprites[index].life = 0;
|
|
|
|
|
2011-08-26 23:53:46 +02:00
|
|
|
/* Shortcut: if we already rendered the same string in the same color, don't render it again. */
|
2020-11-23 05:33:26 +01:00
|
|
|
// TODO: Double-check this, I think it's trying to test if gfx_textSprites[index].image is NULL.
|
|
|
|
// Also, check what `text` will be when "empty".
|
|
|
|
if (gfx_textSprites[index].text && gfx_textSprites[index].image
|
|
|
|
&& (gfx_textSprites[index].fontColor == fontColor)
|
|
|
|
&& (strcmp(gfx_textSprites[index].text, inString) == 0))
|
2017-03-27 05:52:05 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_textSprites[index].x = x;
|
|
|
|
gfx_textSprites[index].y = y;
|
2011-08-26 23:53:46 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-04 04:39:16 +01:00
|
|
|
strcpy(gfx_textSprites[index].text, inString);
|
|
|
|
gfx_textSprites[index].x = x;
|
|
|
|
gfx_textSprites[index].y = y;
|
|
|
|
gfx_textSprites[index].fontColor = fontColor;
|
|
|
|
if (gfx_textSprites[index].image != NULL)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_FreeSurface(gfx_textSprites[index].image);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_textSprites[index].image = gfx_createTextSurface(inString, fontColor);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2016-01-02 22:59:48 +01:00
|
|
|
SDL_Surface *gfx_createAlphaRect(int width, int height, Uint8 red, Uint8 green, Uint8 blue)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2015-12-31 16:47:27 +01:00
|
|
|
SDL_Surface *surface = gfx_createSurface(width, height);
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, red, green, blue));
|
|
|
|
|
2013-09-30 16:52:43 +02:00
|
|
|
SDL_SetSurfaceAlphaMod(surface, 128);
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
return surface;
|
|
|
|
}
|
|
|
|
|
2016-01-07 02:35:37 +01:00
|
|
|
void gfx_createMessageBox(SDL_Surface *face, const char *message, int transparent)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2019-06-04 17:45:57 +02:00
|
|
|
int border = 5;
|
|
|
|
int x = border;
|
|
|
|
int y = border;
|
2016-01-02 22:59:48 +01:00
|
|
|
|
2016-01-04 04:39:16 +01:00
|
|
|
if (gfx_messageBox != NULL)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_FreeSurface(gfx_messageBox);
|
|
|
|
gfx_messageBox = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (transparent)
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_messageBox = gfx_createAlphaRect(550, 60, 0x00, 0x00, 0x00);
|
2011-08-26 23:53:46 +02:00
|
|
|
else
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_messageBox = gfx_createSurface(550, 60);
|
2011-08-26 23:53:46 +02:00
|
|
|
|
|
|
|
if (face != NULL)
|
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_drawRect(gfx_messageBox, 0, 0, gfx_messageBox->w - 1, gfx_messageBox->h - 1, 0x00, 0x00, 0xaa);
|
2019-06-04 17:45:57 +02:00
|
|
|
gfx_blit(face, border, border, gfx_messageBox);
|
|
|
|
x = (2 * border) + face->w;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
gfx_drawRect(gfx_messageBox, 0, 0, gfx_messageBox->w - 1, gfx_messageBox->h - 1, 0x00, 0x00, 0x00);
|
2019-06-04 17:45:57 +02:00
|
|
|
x = border;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
2019-06-06 04:13:48 +02:00
|
|
|
|
2019-06-20 03:29:02 +02:00
|
|
|
gfx_renderUnicode(message, x, y, FONT_WHITE, 1, gfx_messageBox);
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
|
2016-01-02 22:59:48 +01:00
|
|
|
SDL_Surface *gfx_loadImage(const char *filename)
|
|
|
|
{
|
|
|
|
SDL_Surface *image, *newImage;
|
|
|
|
|
|
|
|
image = IMG_Load(filename);
|
|
|
|
|
|
|
|
if (image == NULL) {
|
|
|
|
printf("Couldn't load %s: %s\n", filename, SDL_GetError());
|
|
|
|
engine_showError(0, filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
newImage = SDL_ConvertSurface(image, screen->format, 0);
|
|
|
|
if ( newImage ) {
|
|
|
|
SDL_FreeSurface(image);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// This happens when we are loading the window icon image
|
|
|
|
newImage = image;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gfx_setTransparent(newImage);
|
|
|
|
}
|
|
|
|
|
|
|
|
void gfx_free()
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
Fixed more magic numbers.
God, this one was definitely the biggest headache of all of the
magic number erasing. Never did I expect such cryptic problems.
The first problem was that the entirety of the player's weapon
struct was a part of the save file, *including the weapon's "image
indexes"*. Since the indexes have been changed, and the originally
used one is now unavailable when it's requested, this was causing
a segfault later on. Had to fix this by setting the image index
when the game is loaded.
The second problem was related to another bug I've been confused
about for years: the one that causes mobile rays to fire 5 green
shots. The entire reason those shots were green was because
the weapon's image indexes were undefined, and *that was causing
them to default to 0*. 0 was simply the index of green plasma.
Of course, though, now attempting to use that image causes a
segfault, so for now, I've fixed this by changing the image index
of the mobile rays to the red plasma bolts.
There are still some magic numbers left, related to the intermission
screen. But the hardest part is now done, thank God.
2016-01-06 04:12:29 +01:00
|
|
|
for (int i = 0 ; i < SP_MAX ; i++)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
if (gfx_sprites[i] != NULL)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_FreeSurface(gfx_sprites[i]);
|
|
|
|
gfx_sprites[i] = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-04 18:41:19 +01:00
|
|
|
for (int i = 0 ; i < FS_MAX ; i++)
|
|
|
|
{
|
|
|
|
if (gfx_faceSprites[i] != NULL)
|
|
|
|
{
|
|
|
|
SDL_FreeSurface(gfx_faceSprites[i]);
|
|
|
|
gfx_faceSprites[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-04 22:34:29 +01:00
|
|
|
for (int i = 0 ; i < SS_MAX ; i++)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
if (gfx_shipSprites[i] != NULL)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_FreeSurface(gfx_shipSprites[i]);
|
|
|
|
gfx_shipSprites[i] = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-04 18:41:19 +01:00
|
|
|
for (int i = 0 ; i < TS_MAX ; i++)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
if (gfx_textSprites[i].image != NULL)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_FreeSurface(gfx_textSprites[i].image);
|
|
|
|
gfx_textSprites[i].image = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 04:25:00 +01:00
|
|
|
for (int i = 0 ; i < SHOP_S_MAX ; i++)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
if (gfx_shopSprites[i] != NULL)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_FreeSurface(gfx_shopSprites[i]);
|
|
|
|
gfx_shopSprites[i] = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-04 04:39:16 +01:00
|
|
|
if (gfx_messageBox != NULL)
|
2011-08-26 23:53:46 +02:00
|
|
|
{
|
2016-01-04 04:39:16 +01:00
|
|
|
SDL_FreeSurface(gfx_messageBox);
|
|
|
|
gfx_messageBox = NULL;
|
2011-08-26 23:53:46 +02:00
|
|
|
}
|
|
|
|
}
|
2016-11-25 18:50:32 +01:00
|
|
|
|
2019-05-30 22:46:55 +02:00
|
|
|
void gfx_scaleBackground()
|
2016-11-25 18:50:32 +01:00
|
|
|
{
|
|
|
|
if (gfx_background != NULL)
|
|
|
|
{
|
|
|
|
SDL_FreeSurface(gfx_background);
|
|
|
|
gfx_background = NULL;
|
|
|
|
}
|
2017-02-21 03:46:35 +01:00
|
|
|
gfx_background = gfx_createSurface(screen->w, screen->h);
|
2019-05-30 22:46:55 +02:00
|
|
|
if (gfx_background == NULL)
|
|
|
|
engine_error("Failed to create surface for scaled background");
|
|
|
|
|
2017-02-21 03:46:35 +01:00
|
|
|
SDL_SetColorKey(gfx_background, 0, 0);
|
2019-05-30 22:46:55 +02:00
|
|
|
SDL_BlitScaled(gfx_unscaledBackground, NULL, gfx_background, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void gfx_loadBackground(const char *filename)
|
|
|
|
{
|
|
|
|
if (gfx_unscaledBackground != NULL)
|
|
|
|
{
|
|
|
|
SDL_FreeSurface(gfx_unscaledBackground);
|
|
|
|
gfx_unscaledBackground = NULL;
|
|
|
|
}
|
|
|
|
gfx_unscaledBackground = gfx_loadImage(filename);
|
|
|
|
if (gfx_unscaledBackground == NULL)
|
|
|
|
engine_error("Failed to load unscaled background image");
|
|
|
|
|
|
|
|
SDL_SetColorKey(gfx_unscaledBackground, 0, 0);
|
|
|
|
gfx_scaleBackground();
|
2016-11-25 18:50:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void gfx_loadSprites()
|
|
|
|
{
|
|
|
|
Uint32 *p32;
|
|
|
|
Uint16 *p16;
|
|
|
|
Uint8 *p8;
|
|
|
|
|
|
|
|
gfx_free();
|
|
|
|
|
|
|
|
// Faces
|
|
|
|
gfx_faceSprites[FS_CHRIS] = gfx_loadImage("gfx/face_chris.png");
|
|
|
|
gfx_faceSprites[FS_SID] = gfx_loadImage("gfx/face_sid.png");
|
|
|
|
gfx_faceSprites[FS_KRASS] = gfx_loadImage("gfx/face_krass.png");
|
|
|
|
gfx_faceSprites[FS_PHOEBE] = gfx_loadImage("gfx/face_phoebe.png");
|
|
|
|
gfx_faceSprites[FS_URSULA] = gfx_loadImage("gfx/face_ursula.png");
|
|
|
|
gfx_faceSprites[FS_KLINE] = gfx_loadImage("gfx/face_kline.png");
|
|
|
|
gfx_faceSprites[FS_CREW] = gfx_loadImage("gfx/face_crew.png");
|
|
|
|
|
|
|
|
// Ships
|
|
|
|
gfx_shipSprites[SS_FIREFLY] = gfx_loadImage("gfx/firefly1.png");
|
|
|
|
gfx_shipSprites[SS_FIREFLY_L] = gfx_loadImage("gfx/firefly2.png");
|
|
|
|
gfx_shipSprites[SS_SID] = gfx_loadImage("gfx/sid1.png");
|
|
|
|
gfx_shipSprites[SS_SID_L] = gfx_loadImage("gfx/sid2.png");
|
|
|
|
gfx_shipSprites[SS_FRIEND] = gfx_loadImage("gfx/wingmate1.png");
|
|
|
|
gfx_shipSprites[SS_FRIEND_L] = gfx_loadImage("gfx/wingmate2.png");
|
|
|
|
gfx_shipSprites[SS_GOODTRANSPORT] = gfx_loadImage("gfx/goodTrans1.png");
|
|
|
|
gfx_shipSprites[SS_GOODTRANSPORT_L] = gfx_loadImage("gfx/goodTrans2.png");
|
|
|
|
gfx_shipSprites[SS_REBELCARRIER] = gfx_loadImage("gfx/rebelCarrier1.png");
|
|
|
|
gfx_shipSprites[SS_REBELCARRIER_L] = gfx_loadImage("gfx/rebelCarrier2.png");
|
|
|
|
gfx_shipSprites[SS_DUALFIGHTER] = gfx_loadImage("gfx/dualFighter1.png");
|
|
|
|
gfx_shipSprites[SS_DUALFIGHTER_L] = gfx_loadImage("gfx/dualFighter2.png");
|
|
|
|
gfx_shipSprites[SS_MISSILEBOAT] = gfx_loadImage("gfx/missileBoat1.png");
|
|
|
|
gfx_shipSprites[SS_MISSILEBOAT_L] = gfx_loadImage("gfx/missileBoat2.png");
|
|
|
|
gfx_shipSprites[SS_PROTOFIGHTER] = gfx_loadImage("gfx/eliteFighter1.png");
|
|
|
|
gfx_shipSprites[SS_PROTOFIGHTER_L] = gfx_loadImage("gfx/eliteFighter2.png");
|
|
|
|
gfx_shipSprites[SS_AIMFIGHTER] = gfx_loadImage("gfx/aimFighter1.png");
|
|
|
|
gfx_shipSprites[SS_AIMFIGHTER_L] = gfx_loadImage("gfx/aimFighter2.png");
|
|
|
|
gfx_shipSprites[SS_DRONE] = gfx_loadImage("gfx/drone1.png");
|
|
|
|
gfx_shipSprites[SS_DRONE_L] = gfx_loadImage("gfx/drone2.png");
|
|
|
|
gfx_shipSprites[SS_MINER] = gfx_loadImage("gfx/miner1.png");
|
|
|
|
gfx_shipSprites[SS_MINER_L] = gfx_loadImage("gfx/miner2.png");
|
|
|
|
gfx_shipSprites[SS_ESCORT] = gfx_loadImage("gfx/escort1.png");
|
|
|
|
gfx_shipSprites[SS_ESCORT_L] = gfx_loadImage("gfx/escort2.png");
|
|
|
|
gfx_shipSprites[SS_MOBILE_RAY] = gfx_loadImage("gfx/mobileCannon1.png");
|
|
|
|
gfx_shipSprites[SS_MOBILE_RAY_L] = gfx_loadImage("gfx/mobileCannon2.png");
|
|
|
|
gfx_shipSprites[SS_TRANSPORTSHIP] = gfx_loadImage("gfx/transport1.png");
|
|
|
|
gfx_shipSprites[SS_TRANSPORTSHIP_L] = gfx_loadImage("gfx/transport2.png");
|
|
|
|
gfx_shipSprites[SS_CARGOSHIP] = gfx_loadImage("gfx/tug1.png");
|
|
|
|
gfx_shipSprites[SS_CARGOSHIP_L] = gfx_loadImage("gfx/tug2.png");
|
|
|
|
gfx_shipSprites[SS_SLAVETRANSPORT] = gfx_loadImage("gfx/slaveTrans1.png");
|
|
|
|
gfx_shipSprites[SS_SLAVETRANSPORT_L] = gfx_loadImage("gfx/slaveTrans2.png");
|
|
|
|
gfx_shipSprites[SS_BARRIER] = gfx_loadImage("gfx/barrier.png");
|
|
|
|
gfx_shipSprites[SS_MOBILESHIELD] = gfx_loadImage("gfx/mobileShield1.png");
|
|
|
|
gfx_shipSprites[SS_MOBILESHIELD_L] = gfx_loadImage("gfx/mobileShield2.png");
|
|
|
|
gfx_shipSprites[SS_ASTEROID] = gfx_loadImage("gfx/asteroid1.png");
|
|
|
|
gfx_shipSprites[SS_ASTEROID_SMALL] = gfx_loadImage("gfx/asteroid2.png");
|
|
|
|
gfx_shipSprites[SS_ASTEROID_SMALL_L] = gfx_loadImage("gfx/asteroid3.png");
|
|
|
|
gfx_shipSprites[SS_CLOAKFIGHTER] = gfx_loadImage("gfx/cloakShip1.png");
|
|
|
|
gfx_shipSprites[SS_CLOAKFIGHTER_L] = gfx_loadImage("gfx/cloakShip2.png");
|
|
|
|
gfx_shipSprites[SS_EVILURSULA] = gfx_loadImage("gfx/evilUrsula1.png");
|
|
|
|
gfx_shipSprites[SS_EVILURSULA_L] = gfx_loadImage("gfx/evilUrsula2.png");
|
|
|
|
gfx_shipSprites[SS_KRASS] = gfx_loadImage("gfx/merc1.png");
|
|
|
|
gfx_shipSprites[SS_KRASS_L] = gfx_loadImage("gfx/merc2.png");
|
|
|
|
gfx_shipSprites[SS_FRIGATE] = gfx_loadImage("gfx/frigateBody1.png");
|
|
|
|
gfx_shipSprites[SS_FRIGATE_L] = gfx_loadImage("gfx/frigateBody2.png");
|
|
|
|
gfx_shipSprites[SS_FRIGATE_WING1] = gfx_loadImage("gfx/frigateGun11.png");
|
|
|
|
gfx_shipSprites[SS_FRIGATE_WING1_L] = gfx_loadImage("gfx/frigateGun12.png");
|
|
|
|
gfx_shipSprites[SS_FRIGATE_WING2] = gfx_loadImage("gfx/frigateGun21.png");
|
|
|
|
gfx_shipSprites[SS_FRIGATE_WING2_L] = gfx_loadImage("gfx/frigateGun22.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS] = gfx_loadImage("gfx/mineBoss1.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_L] = gfx_loadImage("gfx/mineBoss2.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING1] = gfx_loadImage("gfx/mineBossWing11.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING1_L] = gfx_loadImage("gfx/mineBossWing12.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING2] = gfx_loadImage("gfx/mineBossWing21.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING2_L] = gfx_loadImage("gfx/mineBossWing22.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING3] = gfx_loadImage("gfx/mineBossWing31.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING3_L] = gfx_loadImage("gfx/mineBossWing32.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING4] = gfx_loadImage("gfx/mineBossWing41.png");
|
|
|
|
gfx_shipSprites[SS_MINERBOSS_WING4_L] = gfx_loadImage("gfx/mineBossWing42.png");
|
|
|
|
gfx_shipSprites[SS_EXEC] = gfx_loadImage("gfx/execTrans1.png");
|
|
|
|
gfx_shipSprites[SS_EXEC_L] = gfx_loadImage("gfx/execTrans2.png");
|
|
|
|
gfx_shipSprites[SS_PLUTOBOSS] = gfx_loadImage("gfx/plutoBoss1.png");
|
|
|
|
gfx_shipSprites[SS_PLUTOBOSS_L] = gfx_loadImage("gfx/plutoBoss2.png");
|
|
|
|
gfx_shipSprites[SS_URANUSBOSS] = gfx_loadImage("gfx/splitBoss11.png");
|
|
|
|
gfx_shipSprites[SS_URANUSBOSS_L] = gfx_loadImage("gfx/splitBoss12.png");
|
|
|
|
gfx_shipSprites[SS_URANUSBOSS_WING1] = gfx_loadImage("gfx/splitBoss21.png");
|
|
|
|
gfx_shipSprites[SS_URANUSBOSS_WING1_L] = gfx_loadImage("gfx/splitBoss22.png");
|
|
|
|
gfx_shipSprites[SS_URANUSBOSS_WING2] = gfx_loadImage("gfx/splitBoss31.png");
|
|
|
|
gfx_shipSprites[SS_URANUSBOSS_WING2_L] = gfx_loadImage("gfx/splitBoss32.png");
|
|
|
|
gfx_shipSprites[SS_KLINE] = gfx_loadImage("gfx/kline11.png");
|
|
|
|
gfx_shipSprites[SS_KLINE_L] = gfx_loadImage("gfx/kline12.png");
|
|
|
|
|
|
|
|
/*
|
|
|
|
Create images of ships being hit that show a lot of red
|
|
|
|
*/
|
|
|
|
for (int i = SS_HIT_INDEX ; i < SS_MAX ; i++)
|
|
|
|
{
|
|
|
|
if (gfx_shipSprites[i - SS_HIT_INDEX] == NULL)
|
|
|
|
continue;
|
|
|
|
gfx_shipSprites[i] = gfx_createSurface(gfx_shipSprites[i - SS_HIT_INDEX]->w,
|
|
|
|
gfx_shipSprites[i - SS_HIT_INDEX]->h);
|
|
|
|
SDL_SetSurfaceBlendMode(gfx_shipSprites[i - SS_HIT_INDEX], SDL_BLENDMODE_NONE);
|
|
|
|
gfx_blit(gfx_shipSprites[i - SS_HIT_INDEX], 0, 0, gfx_shipSprites[i]);
|
|
|
|
SDL_SetSurfaceBlendMode(gfx_shipSprites[i - SS_HIT_INDEX], SDL_BLENDMODE_BLEND);
|
|
|
|
|
|
|
|
switch (gfx_shipSprites[i]->format->BitsPerPixel)
|
|
|
|
{
|
|
|
|
case 32:
|
|
|
|
SDL_LockSurface(gfx_shipSprites[i]);
|
|
|
|
p32 = (Uint32 *)gfx_shipSprites[i]->pixels;
|
|
|
|
for (int j = 0; j < gfx_shipSprites[i]->w * gfx_shipSprites[i]->h; j++)
|
|
|
|
{
|
|
|
|
if (p32[j])
|
|
|
|
p32[j] |= gfx_shipSprites[i]->format->Rmask;
|
|
|
|
}
|
|
|
|
SDL_UnlockSurface(gfx_shipSprites[i]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 16:
|
|
|
|
SDL_LockSurface(gfx_shipSprites[i]);
|
|
|
|
p16 = (Uint16 *)gfx_shipSprites[i]->pixels;
|
|
|
|
for (int j = 0; j < gfx_shipSprites[i]->w * gfx_shipSprites[i]->h; j++)
|
|
|
|
{
|
|
|
|
if (p16[j])
|
|
|
|
p16[j] |= gfx_shipSprites[i]->format->Rmask;
|
|
|
|
}
|
|
|
|
SDL_UnlockSurface(gfx_shipSprites[i]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
SDL_LockSurface(gfx_shipSprites[i]);
|
|
|
|
p8 = (Uint8 *)gfx_shipSprites[i]->pixels;
|
|
|
|
for (int j = 0; j < gfx_shipSprites[i]->w * gfx_shipSprites[i]->h; j++)
|
|
|
|
{
|
|
|
|
if (p8[j])
|
|
|
|
p8[j] = SDL_MapRGB(gfx_shipSprites[i]->format, 255, 0, 0);
|
|
|
|
}
|
|
|
|
SDL_UnlockSurface(gfx_shipSprites[i]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_SetColorKey(gfx_shipSprites[i], SDL_TRUE,
|
|
|
|
SDL_MapRGB(gfx_shipSprites[i]->format, 0, 0, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Other sprites
|
|
|
|
gfx_sprites[SP_PLASMA_GREEN] = gfx_loadImage("gfx/plasmaGreen.png");
|
|
|
|
gfx_sprites[SP_PLASMA_RED] = gfx_loadImage("gfx/plasmaRed.png");
|
|
|
|
gfx_sprites[SP_DIR_PLASMA_GREEN] = gfx_loadImage("gfx/greenDir.png");
|
|
|
|
gfx_sprites[SP_DIR_PLASMA_RED] = gfx_loadImage("gfx/redDir.png");
|
|
|
|
gfx_sprites[SP_ROCKET] = gfx_loadImage("gfx/rocket1.png");
|
|
|
|
gfx_sprites[SP_ROCKET_L] = gfx_loadImage("gfx/rocket2.png");
|
|
|
|
gfx_sprites[SP_SMALL_EXPLOSION] = gfx_loadImage("gfx/explode1.png");
|
|
|
|
gfx_sprites[SP_SMALL_EXPLOSION_2] = gfx_loadImage("gfx/explode2.png");
|
|
|
|
gfx_sprites[SP_SMALL_EXPLOSION_3] = gfx_loadImage("gfx/explode3.png");
|
|
|
|
gfx_sprites[SP_SMALL_EXPLOSION_L] = gfx_loadImage("gfx/explode4.png");
|
|
|
|
gfx_sprites[SP_BIG_EXPLOSION] = gfx_loadImage("gfx/explode05.png");
|
|
|
|
gfx_sprites[SP_BIG_EXPLOSION_2] = gfx_loadImage("gfx/explode06.png");
|
|
|
|
gfx_sprites[SP_BIG_EXPLOSION_3] = gfx_loadImage("gfx/explode07.png");
|
|
|
|
gfx_sprites[SP_BIG_EXPLOSION_L] = gfx_loadImage("gfx/explode08.png");
|
|
|
|
gfx_sprites[SP_SMOKE] = gfx_loadImage("gfx/explode9.png");
|
|
|
|
gfx_sprites[SP_SMOKE_2] = gfx_loadImage("gfx/explode10.png");
|
|
|
|
gfx_sprites[SP_SMOKE_3] = gfx_loadImage("gfx/explode11.png");
|
|
|
|
gfx_sprites[SP_SMOKE_L] = gfx_loadImage("gfx/explode12.png");
|
|
|
|
gfx_sprites[SP_TINY_EXPLOSION] = gfx_loadImage("gfx/explode13.png");
|
|
|
|
gfx_sprites[SP_TINY_EXPLOSION_2] = gfx_loadImage("gfx/explode14.png");
|
|
|
|
gfx_sprites[SP_TINY_EXPLOSION_3] = gfx_loadImage("gfx/explode15.png");
|
|
|
|
gfx_sprites[SP_TINY_EXPLOSION_L] = gfx_loadImage("gfx/explode16.png");
|
|
|
|
gfx_sprites[SP_ELECTRICAL] = gfx_loadImage("gfx/elec1.png");
|
|
|
|
gfx_sprites[SP_ELECTRICAL_2] = gfx_loadImage("gfx/elec2.png");
|
|
|
|
gfx_sprites[SP_ELECTRICAL_3] = gfx_loadImage("gfx/elec3.png");
|
|
|
|
gfx_sprites[SP_ELECTRICAL_L] = gfx_loadImage("gfx/elec4.png");
|
|
|
|
gfx_sprites[SP_PICKUP_MONEY] = gfx_loadImage("gfx/dollar.png");
|
|
|
|
gfx_sprites[SP_PICKUP_PLASMA] = gfx_loadImage("gfx/rocket.png");
|
|
|
|
gfx_sprites[SP_PICKUP_SHIELD] = gfx_loadImage("gfx/heart.png");
|
|
|
|
gfx_sprites[SP_PICKUP_PLASMA_OUTPUT] = gfx_loadImage("gfx/plasmaAmmo.png");
|
|
|
|
gfx_sprites[SP_PICKUP_PLASMA_RATE] = gfx_loadImage("gfx/plasmaRate.png");
|
|
|
|
gfx_sprites[SP_PICKUP_PLASMA_POWER] = gfx_loadImage("gfx/plasmaDamage.png");
|
|
|
|
gfx_sprites[SP_CHAIN_LINK] = gfx_loadImage("gfx/chainLink.png");
|
|
|
|
gfx_sprites[SP_MINE] = gfx_loadImage("gfx/mine.png");
|
|
|
|
gfx_sprites[SP_CARGO] = gfx_loadImage("gfx/cargo1.png");
|
|
|
|
gfx_sprites[SP_ION] = gfx_loadImage("gfx/stunBolt.png");
|
|
|
|
gfx_sprites[SP_ARROW_NORTH] = gfx_loadImage("gfx/arrowNorth.png");
|
|
|
|
gfx_sprites[SP_ARROW_NORTHEAST] = gfx_loadImage("gfx/arrowNorthEast.png");
|
|
|
|
gfx_sprites[SP_ARROW_EAST] = gfx_loadImage("gfx/arrowEast.png");
|
|
|
|
gfx_sprites[SP_ARROW_SOUTHEAST] = gfx_loadImage("gfx/arrowSouthEast.png");
|
|
|
|
gfx_sprites[SP_ARROW_SOUTH] = gfx_loadImage("gfx/arrowSouth.png");
|
|
|
|
gfx_sprites[SP_ARROW_SOUTHWEST] = gfx_loadImage("gfx/arrowSouthWest.png");
|
|
|
|
gfx_sprites[SP_ARROW_WEST] = gfx_loadImage("gfx/arrowWest.png");
|
|
|
|
gfx_sprites[SP_ARROW_NORTHWEST] = gfx_loadImage("gfx/arrowNorthWest.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_NORTH] = gfx_loadImage("gfx/friendArrowNorth.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_NORTHEAST] = gfx_loadImage("gfx/friendArrowNorthEast.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_EAST] = gfx_loadImage("gfx/friendArrowEast.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_SOUTHEAST] = gfx_loadImage("gfx/friendArrowSouthEast.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_SOUTH] = gfx_loadImage("gfx/friendArrowSouth.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_SOUTHWEST] = gfx_loadImage("gfx/friendArrowSouthWest.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_WEST] = gfx_loadImage("gfx/friendArrowWest.png");
|
|
|
|
gfx_sprites[SP_ARROW_FRIEND_NORTHWEST] = gfx_loadImage("gfx/friendArrowNorthWest.png");
|
|
|
|
gfx_sprites[SP_INDICATOR_TARGET] = gfx_loadImage("gfx/targetText.png");
|
|
|
|
gfx_sprites[SP_INDICATOR_SID] = gfx_loadImage("gfx/sidText.png");
|
|
|
|
gfx_sprites[SP_INDICATOR_PHOEBE] = gfx_loadImage("gfx/phoebeText.png");
|
|
|
|
gfx_sprites[SP_INDICATOR_URSULA] = gfx_loadImage("gfx/ursulaText.png");
|
|
|
|
gfx_sprites[SP_INDICATOR_KLINE] = gfx_loadImage("gfx/klineText.png");
|
|
|
|
gfx_sprites[SP_ESCAPE_POD] = gfx_loadImage("gfx/pod.png");
|
|
|
|
gfx_sprites[SP_ORE] = gfx_loadImage("gfx/ore1.png");
|
|
|
|
gfx_sprites[SP_ORE_2] = gfx_loadImage("gfx/ore2.png");
|
|
|
|
gfx_sprites[SP_ORE_L] = gfx_loadImage("gfx/ore3.png");
|
|
|
|
gfx_sprites[SP_PICKUP_ROCKETS] = gfx_loadImage("gfx/rocketAmmo.png");
|
|
|
|
gfx_sprites[SP_SUPERCHARGE] = gfx_loadImage("gfx/superCharge.png");
|
|
|
|
|
|
|
|
gfx_loadBackground(systemBackground[game.system]);
|
|
|
|
|
|
|
|
for (int i = 0 ; i < CD_MAX ; i++)
|
|
|
|
{
|
|
|
|
if (gfx_shipSprites[alien_defs[i].imageIndex[0]] != NULL)
|
|
|
|
{
|
|
|
|
alien_defs[i].image[0] = gfx_shipSprites[alien_defs[i].imageIndex[0]];
|
|
|
|
alien_defs[i].image[1] = gfx_shipSprites[alien_defs[i].imageIndex[1]];
|
|
|
|
alien_defs[i].engineX = alien_defs[i].image[0]->w;
|
|
|
|
alien_defs[i].engineY = (alien_defs[i].image[0]->h / 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0 ; i < W_MAX ; i++)
|
|
|
|
{
|
2016-11-25 19:47:12 +01:00
|
|
|
weapons[i].image[0] = gfx_sprites[weapons[i].imageIndex[0]];
|
|
|
|
weapons[i].image[1] = gfx_sprites[weapons[i].imageIndex[1]];
|
2016-11-25 18:50:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Custom loading to alter the font color before doing
|
|
|
|
all other things
|
|
|
|
*/
|
|
|
|
void gfx_loadFont()
|
|
|
|
{
|
|
|
|
SDL_Surface *image, *newImage;
|
|
|
|
|
|
|
|
for (int i = 0 ; i < FONT_MAX ; i++)
|
|
|
|
{
|
|
|
|
image = IMG_Load("gfx/smallFont.png");
|
|
|
|
|
|
|
|
if (image == NULL) {
|
|
|
|
printf("Couldn't load game font! (%s) Exitting.\n", SDL_GetError());
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(i)
|
|
|
|
{
|
|
|
|
case FONT_RED:
|
|
|
|
SDL_SetSurfaceColorMod(image, 255, 0, 0);
|
|
|
|
break;
|
|
|
|
case FONT_YELLOW:
|
|
|
|
SDL_SetSurfaceColorMod(image, 255, 255, 0);
|
|
|
|
break;
|
|
|
|
case FONT_GREEN:
|
|
|
|
SDL_SetSurfaceColorMod(image, 0, 255, 0);
|
|
|
|
break;
|
|
|
|
case FONT_CYAN:
|
|
|
|
SDL_SetSurfaceColorMod(image, 0, 255, 255);
|
|
|
|
break;
|
|
|
|
case FONT_OUTLINE:
|
|
|
|
SDL_SetSurfaceColorMod(image, 0, 0, 10);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
newImage = SDL_ConvertSurface(image, screen->format, 0);
|
|
|
|
|
|
|
|
gfx_fontSprites[i] = gfx_setTransparent(newImage);
|
|
|
|
|
|
|
|
SDL_FreeSurface(image);
|
|
|
|
}
|
|
|
|
}
|