Bunch of fixes.

At first I just went in to fix some places that were missing gettext
translations, but on the way as I was doing that, I noticed some
places where ngettext should be used, a bug in the fallback legacy
text rendering, and some things that could be structured better in
the Autoconf / Automake setup. Fixed those.
This commit is contained in:
Layla Marchant 2020-03-06 19:06:48 -05:00
parent 9f15125585
commit d96c8327e4
7 changed files with 92 additions and 62 deletions

View File

@ -17,7 +17,7 @@ PKG_PROG_PKG_CONFIG
AC_PROG_CC AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL
STARFIGHTER_CFLAGS="-DVERSION=\\\"$PACKAGE_VERSION\\\"" STARFIGHTER_CPPFLAGS="-DVERSION=\\\"$PACKAGE_VERSION\\\" -Wall -Wformat-truncation=0"
# Checks for libraries. # Checks for libraries.
AC_SEARCH_LIBS([atanf], [m]) AC_SEARCH_LIBS([atanf], [m])
@ -27,7 +27,7 @@ PKG_CHECK_EXISTS([SDL2_mixer], [
PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image SDL2_mixer SDL2_ttf]) PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image SDL2_mixer SDL2_ttf])
], [ ], [
PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image SDL2_mixer]) PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image SDL2_mixer])
STARFIGHTER_CFLAGS="$STARFIGHTER_CFLAGS -DNOFONT" STARFIGHTER_CPPFLAGS="$STARFIGHTER_CPPFLAGS -DNOFONT"
echo "Note: SDL_ttf not found; Unicode will not be supported." echo "Note: SDL_ttf not found; Unicode will not be supported."
]) ])
], [ ], [
@ -35,41 +35,47 @@ PKG_CHECK_EXISTS([SDL2_mixer], [
PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image SDL2_ttf]) PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image SDL2_ttf])
], [ ], [
PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image]) PKG_CHECK_MODULES([SDL], [sdl2 SDL2_image])
STARFIGHTER_CFLAGS="$STARFIGHTER_CFLAGS -DNOFONT" STARFIGHTER_CPPFLAGS="$STARFIGHTER_CPPFLAGS -DNOFONT"
echo "Note: SDL_ttf not found; Unicode will not be supported." echo "Note: SDL_ttf not found; Unicode will not be supported."
]) ])
STARFIGHTER_CFLAGS="$STARFIGHTER_CFLAGS -DNOSOUND" STARFIGHTER_CPPFLAGS="$STARFIGHTER_CPPFLAGS -DNOSOUND"
echo "Note: SDL_mixer not found; audio will not be supported." echo "Note: SDL_mixer not found; audio will not be supported."
]) ])
PKG_CHECK_MODULES([PANGO], [pango], [ PKG_CHECK_MODULES([PANGO], [pango], [
], [ ], [
STARFIGHTER_CFLAGS="$STARFIGHTER_CFLAGS -DNOFONT" STARFIGHTER_CPPFLAGS="$STARFIGHTER_CPPFLAGS -DNOFONT"
echo "Note: Pango not found; Unicode will not be supported." echo "Note: Pango not found; Unicode will not be supported."
]) ])
AC_ARG_VAR([SF_SCREEN_WIDTH], [The width of the game window in pixels]) AC_ARG_VAR([SF_SCREEN_WIDTH], [The width of the game window in pixels])
AC_ARG_VAR([SF_SCREEN_HEIGHT], [The height of the game window in pixels]) AC_ARG_VAR([SF_SCREEN_HEIGHT], [The height of the game window in pixels])
AC_ARG_VAR([SF_NOFONT], [Set to 1 to manually force the compiler not to include font/Unicode support])
AC_ARG_VAR([SF_RUN_IN_PLACE], [Set to 1 to compile Starfighter to run in-place (instead of installing)]) AC_ARG_VAR([SF_RUN_IN_PLACE], [Set to 1 to compile Starfighter to run in-place (instead of installing)])
AS_IF([test -n "$SF_SCREEN_WIDTH"], [ AS_IF([test -n "$SF_SCREEN_WIDTH"], [
STARFIGHTER_CFLAGS="$STARFIGHTER_CFLAGS -DSCREEN_WIDTH=$SF_SCREEN_WIDTH" STARFIGHTER_CPPFLAGS="$STARFIGHTER_CPPFLAGS -DSCREEN_WIDTH=$SF_SCREEN_WIDTH"
echo "Using default screen width of $SF_SCREEN_WIDTH" echo "Using default screen width of $SF_SCREEN_WIDTH"
], [ ], [
echo "Using built-in screen width default" echo "Using built-in screen width default"
]) ])
AS_IF([test -n "$SF_SCREEN_HEIGHT"], [ AS_IF([test -n "$SF_SCREEN_HEIGHT"], [
STARFIGHTER_CFLAGS="$STARFIGHTER_CFLAGS -DSCREEN_HEIGHT=$SF_SCREEN_HEIGHT" STARFIGHTER_CPPFLAGS="$STARFIGHTER_CPPFLAGS -DSCREEN_HEIGHT=$SF_SCREEN_HEIGHT"
echo "Using default screen height of $SF_SCREEN_HEIGHT" echo "Using default screen height of $SF_SCREEN_HEIGHT"
], [ ], [
echo "Using built-in screen height default" echo "Using built-in screen height default"
]) ])
AS_IF([test -n "$SF_NOFONT"], [
STARFIGHTER_CPPFLAGS="$STARFIGHTER_CPPFLAGS -DNOFONT"
echo "Font/Unicode support manually disabled"
])
AS_IF([test -n "$SF_RUN_IN_PLACE"], [ AS_IF([test -n "$SF_RUN_IN_PLACE"], [
echo "Preparing a run-in-place build" echo "Preparing a run-in-place build"
]) ])
AM_CONDITIONAL([RUN_IN_PLACE], [test -n "$SF_RUN_IN_PLACE"]) AM_CONDITIONAL([RUN_IN_PLACE], [test -n "$SF_RUN_IN_PLACE"])
AC_SUBST([STARFIGHTER_CFLAGS]) AC_SUBST([STARFIGHTER_CPPFLAGS])
# Checks for header files. # Checks for header files.
AC_CHECK_HEADERS([ctype.h errno.h libintl.h locale.h stdio.h stdlib.h string.h time.h math.h pwd.h sys/stat.h unistd.h]) AC_CHECK_HEADERS([ctype.h errno.h libintl.h locale.h stdio.h stdlib.h string.h time.h math.h pwd.h sys/stat.h unistd.h])

View File

@ -6,9 +6,9 @@
bin_PROGRAMS = starfighter bin_PROGRAMS = starfighter
if RUN_IN_PLACE if RUN_IN_PLACE
starfighter_CPPFLAGS = $(STARFIGHTER_CFLAGS) -Wall -Wformat-truncation=0 starfighter_CPPFLAGS = $(STARFIGHTER_CPPFLAGS)
else else
starfighter_CPPFLAGS = $(STARFIGHTER_CFLAGS) -DDATADIR=\"$(pkgdatadir)\" -Wall -Wformat-truncation=0 starfighter_CPPFLAGS = $(STARFIGHTER_CPPFLAGS) -DDATADIR=\"$(pkgdatadir)\"
endif endif
starfighter_CFLAGS = $(SDL_CFLAGS) $(PANGO_CFLAGS) starfighter_CFLAGS = $(SDL_CFLAGS) $(PANGO_CFLAGS)

View File

@ -2113,7 +2113,7 @@ void alien_destroy(Object *alien, Object *attacker)
{ {
/// Dialog (Kline Kethlan) /// Dialog (Kline Kethlan)
/// Used when Kline is killed in the Venus mission. /// Used when Kline is killed in the Venus mission.
radio_setMessage(FS_KLINE, "It was an honor... to have fought you...", 1); radio_setMessage(FS_KLINE, _("It was an honor... to have fought you..."), 1);
alien->dx = alien->dy = 0; alien->dx = alien->dy = 0;
alien->shield = -150; alien->shield = -150;
} }

View File

@ -313,20 +313,27 @@ static void game_doCollectables()
case P_CASH: case P_CASH:
game.cash += collectable->value; game.cash += collectable->value;
game.cashEarned += collectable->value; game.cashEarned += collectable->value;
snprintf(temp, STRMAX_SHORT, "Got $%d ", collectable->value); snprintf(temp, STRMAX_SHORT, ngettext(
/// "%d" must be retained. It is replaced with the amount of money that
/// was picked up.
"Got $%d",
"Got $%d",
collectable->value), collectable->value);
break; break;
case P_ROCKET: case P_ROCKET:
LIMIT_ADD(player.ammo[1], collectable->value, 0, LIMIT_ADD(player.ammo[1], collectable->value, 0,
game.maxRocketAmmo); game.maxRocketAmmo);
if (player.ammo[1] == game.maxRocketAmmo) if (player.ammo[1] == game.maxRocketAmmo)
strcpy(temp, "Rocket Ammo at Maximum"); strcpy(temp, _("Rocket Ammo at Maximum"));
else else
{ {
if (collectable->value > 1) snprintf(temp, STRMAX_SHORT, ngettext(
snprintf(temp, STRMAX_SHORT, "Got %d rockets", collectable->value); /// "%d" must be retained. It is replaced with the number of rockets
else /// picked up.
strcpy(temp, "Got a rocket"); "Got %d rocket",
"Got %d rockets",
collectable->value), collectable->value);
} }
game.rocketPickups += collectable->value; game.rocketPickups += collectable->value;
break; break;
@ -334,7 +341,7 @@ static void game_doCollectables()
case P_SHIELD: case P_SHIELD:
LIMIT_ADD(player.shield, 10, 0, player.maxShield); LIMIT_ADD(player.shield, 10, 0, player.maxShield);
game.shieldPickups ++; game.shieldPickups ++;
strcpy(temp, "Restored 10 shield points"); strcpy(temp, _("Restored 10 shield points"));
break; break;
case P_PLASMA_RATE: case P_PLASMA_RATE:
@ -347,11 +354,11 @@ static void game_doCollectables()
weapons[W_PLAYER_WEAPON].reload[0] - 2); weapons[W_PLAYER_WEAPON].reload[0] - 2);
if (weapons[W_PLAYER_WEAPON].reload[0] <= rate2reload[game.maxPlasmaRate]) if (weapons[W_PLAYER_WEAPON].reload[0] <= rate2reload[game.maxPlasmaRate])
strcpy(temp, "Firing rate already at maximum"); strcpy(temp, _("Firing rate already at maximum"));
else else
{ {
weapons[W_PLAYER_WEAPON].reload[0] -= 2; weapons[W_PLAYER_WEAPON].reload[0] -= 2;
strcpy(temp, "Firing rate increased"); strcpy(temp, _("Firing rate increased"));
} }
} }
else if ((game.area != MISN_INTERCEPTION) || else if ((game.area != MISN_INTERCEPTION) ||
@ -362,16 +369,16 @@ static void game_doCollectables()
0, game.maxPlasmaAmmo); 0, game.maxPlasmaAmmo);
if (weapons[W_PLAYER_WEAPON].reload[0] <= rate2reload[game.maxPlasmaRate]) if (weapons[W_PLAYER_WEAPON].reload[0] <= rate2reload[game.maxPlasmaRate])
strcpy(temp, "Firing rate already at maximum"); strcpy(temp, _("Firing rate already at maximum"));
else else
{ {
weapons[W_PLAYER_WEAPON].reload[0] -= 2; weapons[W_PLAYER_WEAPON].reload[0] -= 2;
strcpy(temp, "Firing rate increased"); strcpy(temp, _("Firing rate increased"));
} }
} }
else else
{ {
strcpy(temp, "Upgrade failed (no plasma ammo)"); strcpy(temp, _("Upgrade failed (no plasma ammo)"));
} }
break; break;
@ -384,11 +391,11 @@ static void game_doCollectables()
game.maxPlasmaOutput, weapons[W_PLAYER_WEAPON].ammo[0] + 1); game.maxPlasmaOutput, weapons[W_PLAYER_WEAPON].ammo[0] + 1);
if (weapons[W_PLAYER_WEAPON].ammo[0] >= game.maxPlasmaOutput) if (weapons[W_PLAYER_WEAPON].ammo[0] >= game.maxPlasmaOutput)
strcpy(temp, "Plasma output already at maximum"); strcpy(temp, _("Plasma output already at maximum"));
else else
{ {
weapons[W_PLAYER_WEAPON].ammo[0]++; weapons[W_PLAYER_WEAPON].ammo[0]++;
strcpy(temp, "Plasma output increased"); strcpy(temp, _("Plasma output increased"));
} }
} }
else if ((game.area != MISN_INTERCEPTION) || else if ((game.area != MISN_INTERCEPTION) ||
@ -399,16 +406,16 @@ static void game_doCollectables()
0, game.maxPlasmaAmmo); 0, game.maxPlasmaAmmo);
if (weapons[W_PLAYER_WEAPON].ammo[0] >= game.maxPlasmaOutput) if (weapons[W_PLAYER_WEAPON].ammo[0] >= game.maxPlasmaOutput)
strcpy(temp, "Plasma output already at maximum"); strcpy(temp, _("Plasma output already at maximum"));
else else
{ {
weapons[W_PLAYER_WEAPON].ammo[0]++; weapons[W_PLAYER_WEAPON].ammo[0]++;
strcpy(temp, "Plasma output increased"); strcpy(temp, _("Plasma output increased"));
} }
} }
else else
{ {
strcpy(temp, "Upgrade failed (no plasma ammo)"); strcpy(temp, _("Upgrade failed (no plasma ammo)"));
} }
break; break;
@ -421,11 +428,11 @@ static void game_doCollectables()
game.maxPlasmaDamage, weapons[W_PLAYER_WEAPON].damage + 1); game.maxPlasmaDamage, weapons[W_PLAYER_WEAPON].damage + 1);
if (weapons[W_PLAYER_WEAPON].damage >= game.maxPlasmaDamage) if (weapons[W_PLAYER_WEAPON].damage >= game.maxPlasmaDamage)
strcpy(temp, "Plasma damage already at maximum"); strcpy(temp, _("Plasma damage already at maximum"));
else else
{ {
weapons[W_PLAYER_WEAPON].damage++; weapons[W_PLAYER_WEAPON].damage++;
strcpy(temp, "Plasma damage increased"); strcpy(temp, _("Plasma damage increased"));
} }
} }
else if ((game.area != MISN_INTERCEPTION) || else if ((game.area != MISN_INTERCEPTION) ||
@ -436,16 +443,16 @@ static void game_doCollectables()
0, game.maxPlasmaAmmo); 0, game.maxPlasmaAmmo);
if (weapons[W_PLAYER_WEAPON].damage >= game.maxPlasmaDamage) if (weapons[W_PLAYER_WEAPON].damage >= game.maxPlasmaDamage)
strcpy(temp, "Plasma damage already at maximum"); strcpy(temp, _("Plasma damage already at maximum"));
else else
{ {
weapons[W_PLAYER_WEAPON].damage++; weapons[W_PLAYER_WEAPON].damage++;
strcpy(temp, "Plasma damage increased"); strcpy(temp, _("Plasma damage increased"));
} }
} }
else else
{ {
strcpy(temp, "Upgrade failed (no plasma ammo)"); strcpy(temp, _("Upgrade failed (no plasma ammo)"));
} }
break; break;
@ -466,51 +473,54 @@ static void game_doCollectables()
weapons[W_PLAYER_WEAPON].reload[0] = rate2reload[5]; weapons[W_PLAYER_WEAPON].reload[0] = rate2reload[5];
weapons[W_PLAYER_WEAPON].flags |= WF_SPREAD; weapons[W_PLAYER_WEAPON].flags |= WF_SPREAD;
strcpy(temp, "Picked up a Super Charge!"); strcpy(temp, _("Picked up a Super Charge!"));
} }
else else
{ {
strcpy(temp, "Damn! Upgrade failed (no plasma ammo)"); /// Rare case of grabbing the super charge when you have no ammo at an
/// interception (which means it won't take effect). The "Damn!" serves
/// as a little sympathetic easter egg for players unfortunate enough to
/// have this happen to them.
strcpy(temp, _("Damn! Upgrade failed (no plasma ammo)"));
} }
break; break;
case P_PLASMA_AMMO: case P_PLASMA_AMMO:
if (player.ammo[0] >= game.maxPlasmaAmmo) if (player.ammo[0] >= game.maxPlasmaAmmo)
strcpy(temp, "Plasma cells already at Maximum"); strcpy(temp, _("Plasma cells already at Maximum"));
else else
{ {
LIMIT_ADD(player.ammo[0], collectable->value, LIMIT_ADD(player.ammo[0], collectable->value,
0, game.maxPlasmaAmmo); 0, game.maxPlasmaAmmo);
if (collectable->value > 1) snprintf(temp, STRMAX_SHORT, ngettext(
{ /// "%d" must be retained. It is replaced with the number of plasma
snprintf(temp, STRMAX_SHORT, "Got %d plasma cells", collectable->value); /// cells picked up.
} "Got %d plasma cell",
else "Got %d plasma cells",
{ collectable->value), collectable->value);
strcpy(temp, "Got a plasma cell");
if ((rand() % 25) == 0)
strcpy(temp, "Got one whole plasma cell (wahoo!)");
}
} }
game.cellPickups += collectable->value; game.cellPickups += collectable->value;
break; break;
case P_CARGO: case P_CARGO:
strcpy(temp, "Picked up some Cargo"); strcpy(temp, _("Picked up some Cargo"));
game.cargoPickups++; game.cargoPickups++;
break; break;
case P_SLAVES: case P_SLAVES:
snprintf(temp, STRMAX_SHORT, "Rescued %d slaves", collectable->value); snprintf(temp, STRMAX_SHORT, ngettext(
"Rescued %d slave",
"Rescued %d slaves",
collectable->value), collectable->value);
game.slavesRescued += collectable->value; game.slavesRescued += collectable->value;
break; break;
case P_ESCAPEPOD: case P_ESCAPEPOD:
strcpy(temp, "Picked up an Escape Pod"); strcpy(temp, _("Picked up an Escape Pod"));
break; break;
case P_ORE: case P_ORE:
strcpy(temp, "Picked up some Ore"); strcpy(temp, _("Picked up some Ore"));
break; break;
} }

View File

@ -159,10 +159,11 @@ void gfx_blit(SDL_Surface *image, int x, int y, SDL_Surface *dest)
In 16 bit mode this is slow. VERY slow. Don't write directly to a surface 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) that constantly needs updating (eg - the main game screen)
*/ */
static int gfx_renderStringBase(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest) static int gfx_renderStringBase(const char *in, int x, int y, int real_x, int fontColor, int wrap, SDL_Surface *dest)
{ {
int i; int i;
int splitword; int splitword;
int creal_x;
SDL_Rect area; SDL_Rect area;
SDL_Rect letter; SDL_Rect letter;
@ -170,6 +171,7 @@ static int gfx_renderStringBase(const char *in, int x, int y, int fontColor, int
area.y = y; area.y = y;
area.w = PIXFONT_W; area.w = PIXFONT_W;
area.h = PIXFONT_H; area.h = PIXFONT_H;
creal_x = real_x;
letter.y = 0; letter.y = 0;
letter.w = PIXFONT_W; letter.w = PIXFONT_W;
@ -191,15 +193,17 @@ static int gfx_renderStringBase(const char *in, int x, int y, int fontColor, int
} }
area.x += PIXFONT_W + 1; area.x += PIXFONT_W + 1;
creal_x += PIXFONT_W + 1;
if (wrap) if (wrap)
{ {
if ((area.x > (dest->w - 70)) && (*in == ' ')) if ((creal_x > (dest->w - 70)) && (*in == ' '))
{ {
area.y += PIXFONT_LINE_HEIGHT; area.y += PIXFONT_LINE_HEIGHT;
area.x = x; area.x = x;
creal_x = real_x;
} }
else if (area.x > (dest->w - 31)) else if (creal_x > (dest->w - 31))
{ {
splitword = 1; splitword = 1;
for (i = 0 ; i < 4 ; i++) for (i = 0 ; i < 4 ; i++)
@ -222,6 +226,7 @@ static int gfx_renderStringBase(const char *in, int x, int y, int fontColor, int
} }
area.y += PIXFONT_LINE_HEIGHT; area.y += PIXFONT_LINE_HEIGHT;
area.x = x; area.x = x;
creal_x = real_x;
} }
} }
} }
@ -232,18 +237,27 @@ static int gfx_renderStringBase(const char *in, int x, int y, int fontColor, int
return area.y; return area.y;
} }
/*
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).
*/
int gfx_renderString(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest) int gfx_renderString(const char *in, int x, int y, int fontColor, int wrap, SDL_Surface *dest)
{ {
if (x == -1) if (x == -1)
x = (dest->w - (strlen(in) * (PIXFONT_W + 1))) / 2; x = (dest->w - (strlen(in) * (PIXFONT_W + 1))) / 2;
gfx_renderStringBase(in, x, y - 1, FONT_OUTLINE, wrap, dest); gfx_renderStringBase(in, x, y - 1, x, FONT_OUTLINE, wrap, dest);
gfx_renderStringBase(in, x, y + 1, FONT_OUTLINE, wrap, dest); gfx_renderStringBase(in, x, y + 1, x, FONT_OUTLINE, wrap, dest);
gfx_renderStringBase(in, x, y + 2, FONT_OUTLINE, wrap, dest); gfx_renderStringBase(in, x, y + 2, x, FONT_OUTLINE, wrap, dest);
gfx_renderStringBase(in, x - 1, y, FONT_OUTLINE, wrap, dest); gfx_renderStringBase(in, x - 1, y, x, FONT_OUTLINE, wrap, dest);
gfx_renderStringBase(in, x - 2, y, FONT_OUTLINE, wrap, dest); gfx_renderStringBase(in, x - 2, y, x, FONT_OUTLINE, wrap, dest);
gfx_renderStringBase(in, x + 1, y, FONT_OUTLINE, wrap, dest); gfx_renderStringBase(in, x + 1, y, x, FONT_OUTLINE, wrap, dest);
return gfx_renderStringBase(in, x, y, fontColor, wrap, dest); return gfx_renderStringBase(in, x, y, x, fontColor, wrap, dest);
} }
#ifdef NOFONT #ifdef NOFONT

View File

@ -1639,7 +1639,7 @@ int intermission()
{ {
/// Retain "%s" as-is. It is replaced with the name of the planet /// Retain "%s" as-is. It is replaced with the name of the planet
/// the player's destination is currently set to. /// the player's destination is currently set to.
snprintf(string, STRMAX_SHORT, "Destination: %s", intermission_planets[game.destinationPlanet].name); snprintf(string, STRMAX_SHORT, _("Destination: %s"), intermission_planets[game.destinationPlanet].name);
gfx_createTextObject(TS_DEST_PLANET, string, 0, 0, FONT_WHITE); gfx_createTextObject(TS_DEST_PLANET, string, 0, 0, FONT_WHITE);
} }