Author Topic: Support for every language (That you can fit in ASCII!)  (Read 17034 times)

0 Members and 2 Guests are viewing this topic.

Offline niffiwan

  • 211
  • Eluder Class
Re: Support for every language (That you can fit in ASCII!)
1) Currently, the "Non-English Character Index" field (which, as I said earlier, is for special symbols and not accented letters) takes only one parameter. However, as I pointed out here, font03.vp has the special characters at a unique offset, so there's no way for a HUD gauge that uses special characters to use font03.vp and still display correctly. The "Non-English Character Index" field should somehow be expanded to take three parameters, one for each font.

I don't much like the idea of splitting the special characters field into 3 in strings.tbl. I think that making it a font property defined in fonts.tbl is a better idea. If the setting isn't found, then it falls back to the language default.

I'm currently looking at fixing mantis 2883.  Just to clarify, its not that you don't want to expand "struct lang_info", its more that you want the extra font offsets defined in font.tbl, with the value in strings.tbl to be a "default" value in the case that this info is not defined in fonts.tbl? (although putting the indexes in fonts.tbl sort of makes this value in string.tbl redundant?) If these values are put into fonts.tbl, I think each value will need a corresponding language entry that it refers to.  i.e. something like:

Code: [Select]
#Fonts

$Font: font01.vf
  +Language: English
  +Special Character Index: 127
  +Language: German
  +Special Character Index: 164
  +Language: French
  +Special Character Index: 164
  +Language: Polish
  +Special Character Index: 127
$Font: font02.vf
  +Language: all
  +Special Character Index: none
$Font: font03.vf
  +Language: all
  +Special Character Index: 176   (NOTE: font02 & font03 are based on the only data we have so far, i.e. English & German)

#End

(although I'm not convinced adding the special keyword "all" is worth it, "none" is required due to font02.vf, although -1 could work as well here)

Lastly, if we don't get rid of it, I'll change the "+Non English Character Index:" in strings.tbl to "+Special Character Index".



2) When displaying non-ASCII characters, the game does some remapping from ISO Latin-1 to its own mapping. However, it doesn't do this with the fiction viewer. Because of this, if a default font that supports accented characters is used there, then non-ASCII characters will not display correctly.

I've seen something in the code to do with an umlaut translaction for German (lcl_fix_umlauts), maybe that just needs to be added to the fiction viewer?  I think this is worth a new/separate mantis ticket.

3) For this last problem, I'll quote myself on something that we're adding to the next version of FSPort:
Quote
Most of the FreeSpace 2 multiplayer missions are still being parsed in the mission simulator. This is a problem because, with the new tstrings.tbl, the XSTR structures for many of their names now point to strings that are longer than 32 characters, causing a boatload of warnings to be thrown in the mission simulator if the language is set to Spanish.

We're going to have to block all the FS2 missions somehow. Right now, we can block single-player campaigns and their missions, but that's it. Perhaps this can be expanded somehow to block single (non-campaign) missions as well as multiplayer missions and campaigns. (If that can't be done, then we could use dummy files...)

So, yeah, the ignore-campaign feature should be expanded to cover single missions and multiplayer missions and campaigns. Also, any XSTR structures found in ignored campaigns and missions should not be translated.

IIRC Goober5000 made some more localisation changes after this feature went in, and I think it involved whether some strings (used as indexes) were translated or not.  So, is this still an issue?  Also, is there a case to be made for making FSO handle strings longer than 32 chars?  Or would that overflow the available space in the interface?  Anyway, the ignore-campaign change sounds a bit tricky to me, I don't believe there's anything which associates single player campaigns to single/standalone missions or multiplayer missions. 
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: Support for every language (That you can fit in ASCII!)
I was thinking that we'd leave the current setting in in strings.tbl (Changed to "+Special Character Index") as the default and then have the setting in fonts.tbl work as an override for any fonts that need it. So you wouldn't need an "all" keyword since the language was already defined in strings.tbl.


I had planned to fix that all last weekend and then I got swamped with work. :(
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Re: Support for every language (That you can fit in ASCII!)
IIRC Goober5000 made some more localisation changes after this feature went in, and I think it involved whether some strings (used as indexes) were translated or not.  So, is this still an issue?  Also, is there a case to be made for making FSO handle strings longer than 32 chars?  Or would that overflow the available space in the interface?  Anyway, the ignore-campaign change sounds a bit tricky to me, I don't believe there's anything which associates single player campaigns to single/standalone missions or multiplayer missions.

The fix I made was for something else entirely.  Originally, the tech-add-intel sexp didn't check the XSTR ID, so if you were using a different language pack you'd still be looking for the English intel name.  The problem Yarn mentions has to do with the lengths of strings after they are translated, especially if the translation indexes change.

This will need to be fixed with some sort of hack.  Adding a mission blacklist is not going to work because the problem could happen with any mission.  The best solution, I think, is to add a custom check to the mission loading screen so that any mission whose translated name overflows the string length will simply not be displayed in the menu -- or perhaps will have its English name displayed instead.

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: Support for every language (That you can fit in ASCII!)
I think that's just going to inspire another bug report further down the line about how some of the missions aren't displayed or are displayed in the wrong language. Even a truncated name would be better than both of those.

What are the chances of support for greater than 32 characters though?
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Re: Support for every language (That you can fit in ASCII!)
The 32-character limit really isn't the problem.  The problem is that if you install a mod with a new tstrings.tbl, all of the XSTR indexes will be messed up.  Instead of the following mission listing...

Quote
M-01.fs2, All Alone
M-02.fs2, Forward Edge Battle Area
M-03.fs2, Blockade Run
M-04.fs2, Rebel Intercept

...you'd end up with something like this...

Quote
M-01.fs2, You survived your first sortie against the Shivans. Though we had only a small opposing force to contend with, survival is half the battle. The C.O.s of both the Carthage and Dahshor commend our squadron for the outstanding cover we provided. The Shivan Cain cruiser and its complement of fighters might have destroyed these vessels had we not intervened. Well done, pilot.
M-02.fs2, EMP Missile
M-03.fs2, Bombers should be your highest priority when protecting the Aquitaine.
M-04.fs2, credits, or check specs

That's why I favor using the English phrase, because we know for sure that the English phrase is saying the right thing even if it's not in the right language.  And the chances are still fairly good that someone will be able to recognize a mission title in English.  (Or, as I suggested earlier, doing an on-the-fly blacklist if an XSTR overflows its length.)
« Last Edit: October 24, 2013, 12:01:47 am by Goober5000 »

  

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: Support for every language (That you can fit in ASCII!)
The solution of only doing something when it's over 32 characters leaves with a problem where some missions will appear with incorrect names while others won't even appear. In either case, when you run the mission they'll also be horrifically broken.

If you've installed a mod with a new string.tbl, you probably shouldn't be seeing those missions in the first place. Although I can't think of any method off the top of my head to actually test for that.


EDIT : I assume the problem is tstrings.tbl not strings.tbl. Mission names shouldn't be in strings.tbl really unless :v: did something rather stupid.
« Last Edit: October 24, 2013, 01:10:52 am by karajorma »
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Re: Support for every language (That you can fit in ASCII!)
Yes, you'll note that my post specifies tstrings.tbl, not strings.tbl.  Yarn discovered this problem in the course of configuring ST:R for localization.

And yes, examples like EMP Missile in my list above will still satisfy the 32-character limit and make it through the filter.  You're phrasing your post as if I hadn't already thought of that. :p  That's why I also suggested defaulting to English names for all mission titles.  It's not perfect, but it will avoid hosing the mission list.

The best option would be for the code to somehow detect that the mod is using a different tstrings.tbl, but, as you say, that's a tricky problem.  One method that just came to mind is performing two lookups on the XSTR, one for the default language and one for the user's language.  If the string provided by the mission file is different from the default language string in tstrings.tbl, then lcl_ext_localize should set a flag (or even just return false).  Then it would be the responsibility of the mission loading code to skip the mission with that badly translated name.

The only risk of this method is if the untranslated string isn't exactly equal to the default language string, for whatever reason -- maybe there was a typo, or maybe there was an update that wasn't sync'd in both places.

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: Support for every language (That you can fit in ASCII!)
Yeah, I thought of something similar about 30 seconds later but I was already out the door. :D

I think that's what we're going to have to do. Using the English names just shunts the problem one step further down the line.
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline Yarn

  • 210
Re: Support for every language (That you can fit in ASCII!)
I found a serious bug concerning *-lcl.tbm files. If it's not fixed, then modders adding additional languages will have to include their own mv_core-lcl.tbm (which will likely be called mv_root-lcl.tbm in the future) just to prevent a crash. It's also contrary to how TBMs are expected to work. The Mantis ticket is here: http://scp.indiegames.us/mantis/view.php?id=2941
"Your fighter is running out of oil.  Please check under the hood and add more if necessary"
--strings.tbl, entry 177

"Freespace is very tired.  It is shutting down to get some rest."
--strings.tbl, entry 178

 

Offline karajorma

  • King Louie - Jungle VIP
  • Administrator
  • 214
    • Karajorma's Freespace FAQ
Re: Support for every language (That you can fit in ASCII!)
Assigned it to myself. I'll look into this one tomorrow or Sunday.
Karajorma's Freespace FAQ. It's almost like asking me yourself.

[ Diaspora ] - [ Seeds Of Rebellion ] - [ Mind Games ]

 

Offline niffiwan

  • 211
  • Eluder Class
Re: Support for every language (That you can fit in ASCII!)
I've created a patch to implement setting individual indexes for fonts, mostly as per my post above.  One difference is the lack of a keyword for "no index", just set 0 in this case.  See attached for a test table (which has invalid indexes for those fonts, but it gives the general idea).

Note that this requires the patch from mantis 2883 to be applied 1st, and because it's a patch on a non-committed-patch, I can't provide it in SVN format.  I will do so when the patch for 2883 is committed.  And I'll create & post a build for testing as well, maybe tomorrow.

SVN format patch is now provided below, and the fonts.tbl is now inline to avoid be eaten by the attachment monster... but the build is finally still MIA  :nervous:
And here is the build.

A review of this patch would be much appreciated :)

Code: [Select]
Index: code/hud/hudtarget.cpp
===================================================================
--- code/hud/hudtarget.cpp (revision 9992)
+++ code/hud/hudtarget.cpp (working copy)
@@ -5750,6 +5750,18 @@
 {
 }
 
+void HudGaugeWeapons::initLinkIcon()
+{
+ ubyte sc = lcl_get_font_index(font_num);
+ // default to a '>' if the font has no special chars
+ // seems about the closest normal char to the triangle
+ if (sc == 0) {
+ Weapon_link_icon = ubyte ('>');
+ } else {
+ Weapon_link_icon = sc + 2;
+ }
+}
+
 void HudGaugeWeapons::initTopOffsetX(int x, int x_b)
 {
  top_offset_x[0] = x;
@@ -6000,7 +6012,7 @@
 
  // indicate if this is linked or currently armed
  if ( ((sw->current_primary_bank == i) && !(Player_ship->flags & SF_PRIMARY_LINKED)) || ((Player_ship->flags & SF_PRIMARY_LINKED) && !(Weapon_info[sw->primary_bank_weapons[i]].wi_flags3 & WIF3_NOLINK))) {
- renderPrintf(position[0] + Weapon_plink_offset_x, name_y, EG_NULL, "%c", Lcl_special_chars + 2);
+ renderPrintf(position[0] + Weapon_plink_offset_x, name_y, EG_NULL, "%c", Weapon_link_icon);
  }
 
  // either render this primary's image or its name
@@ -6064,11 +6076,11 @@
 
  if ( sw->current_secondary_bank == i ) {
  // show that this is the current secondary armed
- renderPrintf(position[0] + Weapon_sunlinked_offset_x, name_y, EG_NULL, "%c", Lcl_special_chars + 2);
+ renderPrintf(position[0] + Weapon_sunlinked_offset_x, name_y, EG_NULL, "%c", Weapon_link_icon);
 
  // indicate if this is linked
  if ( Player_ship->flags & SF_SECONDARY_DUAL_FIRE ) {
- renderPrintf(position[0] + Weapon_slinked_offset_x, name_y, EG_NULL, "%c", Lcl_special_chars + 2);
+ renderPrintf(position[0] + Weapon_slinked_offset_x, name_y, EG_NULL, "%c", Weapon_link_icon);
  }
 
  // show secondary weapon's image or print its name
@@ -6679,6 +6691,17 @@
 
 }
 
+void HudGaugeWeaponList::initLinkIcon() {
+ ubyte sc = lcl_get_font_index(font_num);
+ // default to a '>' if the font has no special chars
+ // seems about the closest normal char to the triangle
+ if (sc == 0) {
+ Weapon_link_icon = ubyte ('>');
+ } else {
+ Weapon_link_icon = sc + 2;
+ }
+}
+
 void HudGaugeWeaponList::initBitmaps(char *fname_first, char *fname_entry, char *fname_last)
 {
  _background_first.first_frame = bm_load_animation(fname_first, &_background_first.num_frames);
@@ -6859,7 +6882,7 @@
 
  // indicate if this is linked or currently armed
  if ( (sw->current_primary_bank == i) || (Player_ship->flags & SF_PRIMARY_LINKED) ) {
- renderPrintf(position[0] + _plink_offset_x, position[1] + text_y_offset, EG_NULL, "%c", Lcl_special_chars + 2);
+ renderPrintf(position[0] + _plink_offset_x, position[1] + text_y_offset, EG_NULL, "%c", Weapon_link_icon);
  }
 
  // either render this primary's image or its name
@@ -6971,11 +6994,11 @@
 
  if ( sw->current_secondary_bank == i ) {
  // show that this is the current secondary armed
- renderPrintf(position[0] + _sunlinked_offset_x, position[1] + text_y_offset, EG_NULL, "%c", Lcl_special_chars + 2);
+ renderPrintf(position[0] + _sunlinked_offset_x, position[1] + text_y_offset, EG_NULL, "%c", Weapon_link_icon);
 
  // indicate if this is linked
  if ( Player_ship->flags & SF_SECONDARY_DUAL_FIRE ) {
- renderPrintf(position[0] + _slinked_offset_x, position[1] + text_y_offset, EG_NULL, "%c", Lcl_special_chars + 2);
+ renderPrintf(position[0] + _slinked_offset_x, position[1] + text_y_offset, EG_NULL, "%c", Weapon_link_icon);
  }
 
  // show secondary weapon's image or print its name
Index: code/hud/hudreticle.cpp
===================================================================
--- code/hud/hudreticle.cpp (revision 9992)
+++ code/hud/hudreticle.cpp (working copy)
@@ -398,6 +398,16 @@
  Match_speed_offsets[0] = x;
  Match_speed_offsets[1] = y;
  Use_custom_match_speed = custom;
+
+ ubyte sc = lcl_get_font_index(font_num);
+ // NOTE: default to normal m because either
+ // a) the german font has no special m (its an a)
+ // b) the font has no special characters
+ if (sc == 0 || Lcl_gr) {
+ Match_speed_icon = ubyte ('m');
+ } else {
+ Match_speed_icon = sc + 3;
+ }
 }
 
 void HudGaugeThrottle::initBitmaps(char *fname)
@@ -567,13 +577,7 @@
  }
  } else if ( Players[Player_num].flags & PLAYER_FLAGS_MATCH_TARGET ) {
  if ( Use_custom_match_speed ) {
- if (Lcl_gr) {
- // print an m, cuz the voice says its an m. 
- // its a normal m cuz the german font has no special m (its an a)
- renderString(position[0] + Match_speed_offsets[0], position[1] + Match_speed_offsets[1], "m");
- } else {
- renderPrintf(position[0] + Match_speed_offsets[0], position[1] + Match_speed_offsets[1], "%c", Lcl_special_chars + 3);
- }
+ renderPrintf(position[0] + Match_speed_offsets[0], position[1] + Match_speed_offsets[1], "%c", Match_speed_icon);
  } else {
  int offset;
  if ( current_speed <= 9.5 ) {
@@ -582,13 +586,7 @@
  offset = 3;
  }
 
- if (Lcl_gr) {
- // print an m, cuz the voice says its an m. 
- // its a normal m cuz the german font has no special m (its an a)
- renderString(sx+offset, sy + h, "m");
- } else {
- renderPrintf(sx+offset, sy + h, "%c", Lcl_special_chars + 3);
- }
+ renderPrintf(sx+offset, sy + h, "%c", Match_speed_icon);
  }
  }
 }
Index: code/hud/hudtarget.h
===================================================================
--- code/hud/hudtarget.h (revision 9992)
+++ code/hud/hudtarget.h (working copy)
@@ -314,6 +314,7 @@
  int Weapon_sreload_offset_x;
  int Weapon_slinked_offset_x;
  int Weapon_sunlinked_offset_x;
+ ubyte Weapon_link_icon;
 
  int top_primary_h;
  int pname_start_offset_y;
@@ -340,6 +341,7 @@
  void initStartNameOffsetsY(int p_y, int s_y);
  void initPrimaryHeights(int top_h, int text_h);
  void initSecondaryHeights(int top_h, int text_h);
+ void initLinkIcon();
 
  void render(float frametime);
  void pageIn();
@@ -352,6 +354,7 @@
  hud_frames _background_first;
  hud_frames _background_entry;
  hud_frames _background_last;
+ ubyte Weapon_link_icon;
 
  int _bg_first_offset_x;
  int _bg_entry_offset_x;
@@ -379,6 +382,7 @@
  void initHeaderOffsets(int x, int y);
  void initEntryStartY(int y);
  void initEntryHeight(int h);
+ void initLinkIcon();
 
  virtual void render(float frametime);
  void pageIn();
Index: code/hud/hudreticle.h
===================================================================
--- code/hud/hudreticle.h (revision 9992)
+++ code/hud/hudreticle.h (working copy)
@@ -81,6 +81,7 @@
 
  int Match_speed_offsets[2];
  bool Use_custom_match_speed;
+ ubyte Match_speed_icon;
 
  bool Show_background;
 public:
Index: code/hud/hudparse.cpp
===================================================================
--- code/hud/hudparse.cpp (revision 9992)
+++ code/hud/hudparse.cpp (working copy)
@@ -3701,6 +3701,7 @@
  hud_gauge->lockConfigColor(lock_color);
  hud_gauge->updateColor(colors[0], colors[1], colors[2]);
  hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
+ hud_gauge->initInfinityIcon();
 
  if(ship_idx->at(0) >= 0) {
  for (SCP_vector<int>::iterator ship_index = ship_idx->begin(); ship_index != ship_idx->end(); ++ship_index) {
@@ -3863,6 +3864,7 @@
  hud_gauge->updateColor(colors[0], colors[1], colors[2]);
  hud_gauge->lockConfigColor(lock_color);
  hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
+ hud_gauge->initInfinityIcon();
 
  if(ship_idx->at(0) >= 0) {
  for (SCP_vector<int>::iterator ship_index = ship_idx->begin(); ship_index != ship_idx->end(); ++ship_index) {
@@ -4949,6 +4951,7 @@
  hud_gauge->updateColor(colors[0], colors[1], colors[2]);
  hud_gauge->lockConfigColor(lock_color);
  hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
+ hud_gauge->initLinkIcon();
 
  if(ship_idx->at(0) >= 0) {
  for (SCP_vector<int>::iterator ship_index = ship_idx->begin(); ship_index != ship_idx->end(); ++ship_index) {
@@ -8345,6 +8348,7 @@
  hud_gauge->updateColor(colors[0], colors[1], colors[2]);
  hud_gauge->lockConfigColor(lock_color);
  hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
+ hud_gauge->initLinkIcon();
 
  if(ship_idx->at(0) >= 0) {
  for (SCP_vector<int>::iterator ship_index = ship_idx->begin(); ship_index != ship_idx->end(); ++ship_index) {
@@ -8540,6 +8544,7 @@
  hud_gauge->updateColor(colors[0], colors[1], colors[2]);
  hud_gauge->lockConfigColor(lock_color);
  hud_gauge->initCockpitTarget(display_name, display_offset[0], display_offset[1], display_size[0], display_size[1], canvas_size[0], canvas_size[1]);
+ hud_gauge->initLinkIcon();
 
  if(ship_idx->at(0) >= 0) {
  for (SCP_vector<int>::iterator ship_index = ship_idx->begin(); ship_index != ship_idx->end(); ++ship_index) {
Index: code/radar/radarsetup.cpp
===================================================================
--- code/radar/radarsetup.cpp (revision 9992)
+++ code/radar/radarsetup.cpp (working copy)
@@ -383,6 +383,18 @@
 {
 }
 
+void HudGaugeRadar::initInfinityIcon()
+{
+ ubyte sc = lcl_get_font_index(font_num);
+ // default to a '*' if the font has no special chars
+ // nothing is really close to the infinity symbol...
+ if (sc == 0) {
+ Radar_infinity_icon = ubyte ('*');
+ } else {
+ Radar_infinity_icon = sc;
+ }
+}
+
 void HudGaugeRadar::initRadius(int w, int h)
 {
  Radar_radius[0] = w;
@@ -438,14 +450,18 @@
 
  int w,h;
  gr_set_font(FONT1);
+ ubyte sc = lcl_get_font_index(FONT1);
+ if (sc == 0) {
+ Warning(LOCATION, "1st font doesn't have a special characters index, radar may not work");
+ }
 
- Small_blip_string[0] = ubyte(SMALL_BLIP_CHAR);
+ Small_blip_string[0] = sc + 5;
  Small_blip_string[1] = 0;
  gr_get_string_size( &w, &h, Small_blip_string );
  Small_blip_offset_x = -w/2;
  Small_blip_offset_y = -h/2;
 
- Large_blip_string[0] = ubyte(LARGE_BLIP_CHAR);
+ Large_blip_string[0] = sc + 6;
  Large_blip_string[1] = 0;
  gr_get_string_size( &w, &h, Large_blip_string );
  Large_blip_offset_x = -w/2;
@@ -456,8 +472,6 @@
 
 void HudGaugeRadar::drawRange()
 {
- char buf[32];
-
  // hud_set_bright_color();
  setGaugeColor(HUD_C_BRIGHT);
 
@@ -472,8 +486,7 @@
  break;
 
  case RR_INFINITY:
- sprintf(buf, NOX("%c"), Lcl_special_chars);
- renderPrintf(position[0] + Radar_dist_offsets[RR_INFINITY][0], position[1] + Radar_dist_offsets[RR_INFINITY][1], buf);
+ renderPrintf(position[0] + Radar_dist_offsets[RR_INFINITY][0], position[1] + Radar_dist_offsets[RR_INFINITY][1], "%c", Radar_infinity_icon);
  break;
 
  default:
Index: code/radar/radarsetup.h
===================================================================
--- code/radar/radarsetup.h (revision 9992)
+++ code/radar/radarsetup.h (working copy)
@@ -15,9 +15,6 @@
 #include "hud/hudconfig.h"
 #include "hud/hud.h"
 
-#define SMALL_BLIP_CHAR (Lcl_special_chars + 5)
-#define LARGE_BLIP_CHAR (Lcl_special_chars + 6)
-
 //which radar type are we using
 //to add another radar type, begin by adding a RADAR_MODE_* define and increment MAX_RADAR_MODES
 #define RADAR_MODE_STANDARD 0
@@ -128,6 +125,7 @@
 
  char Small_blip_string[2];
  char Large_blip_string[2];
+ ubyte Radar_infinity_icon;
 public:
  HudGaugeRadar();
  HudGaugeRadar(int _gauge_object, int r, int g, int b);
@@ -136,6 +134,7 @@
  void initDistanceShortOffsets(int x, int y);
  void initDistanceLongOffsets(int x, int y);
  void initDistanceInfinityOffsets(int x, int y);
+ void initInfinityIcon();
 
  void drawRange();
  virtual void render(float frametime);
Index: code/graphics/font.cpp
===================================================================
--- code/graphics/font.cpp (revision 9992)
+++ code/graphics/font.cpp (working copy)
@@ -16,6 +16,7 @@
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <limits.h>
 
 #include "graphics/2d.h"
 #include "cfile/cfile.h"
@@ -125,14 +126,13 @@
 /**
  * Draws a character centered on x
  */
-void gr_char_centered(int x, int y, char chr)
+void gr_char_centered(int x, int y, char chr, ubyte sc1)
 {
  char str[2];
- int w, sc;
+ int w;
 
- sc = Lcl_special_chars;
  if (chr == '1')
- chr = (char)(sc + 1);
+ chr = (char)sc1;
 
  str[0] = chr;
  str[1] = 0;
@@ -143,7 +143,8 @@
 void gr_print_timestamp(int x, int y, fix timestamp)
 {
  char h[2], m[3], s[3];
- int w, c;
+ int w, c, font_num;
+ ubyte sc;
 
  int time = (int)f2fl(timestamp);  // convert to seconds
 
@@ -158,16 +159,29 @@
  gr_string(x + w, y, ":");
  gr_string(x + w * 3 + c, y, ":");
 
+ font_num = gr_get_current_fontnum();
+ if (font_num == -1) {
+ Warning(LOCATION, "Font not set - timestamps may not work correctly");
+ sc = 0;
+ } else {
+ sc = lcl_get_font_index(font_num);
+ }
+ if (sc == 0) {
+ sc = ubyte ('1'); // make do with non-mono-spaced 1
+ } else {
+ sc += 1;
+ }
+
  x += w / 2;
- gr_char_centered(x, y, h[0]);
+ gr_char_centered(x, y, h[0], sc);
  x += w + c;
- gr_char_centered(x, y, m[0]);
+ gr_char_centered(x, y, m[0], sc);
  x += w;
- gr_char_centered(x, y, m[1]);
+ gr_char_centered(x, y, m[1], sc);
  x += w + c;
- gr_char_centered(x, y, s[0]);
+ gr_char_centered(x, y, s[0], sc);
  x += w;
- gr_char_centered(x, y, s[1]);
+ gr_char_centered(x, y, s[1], sc);
 }
 
 int gr_get_font_height()
@@ -533,7 +547,7 @@
 
 void parse_fonts_tbl(char *only_parse_first_font, size_t only_parse_first_font_size)
 {
- int rval;
+ int rval, i;
  char *filename;
 
  // choose file name
@@ -579,6 +593,35 @@
  int font_id = gr_create_font(font_filename);
  if (font_id < 0) {
  Warning(LOCATION, "Could not create font from typeface '%s'!", font_filename);
+ skip_to_start_of_string_either("#End","$Font:");
+ } else {
+ while (optional_string("+Language:")) {
+ char lang_name[LCL_LANG_NAME_LEN + 1];
+ int special_char_index;
+
+ stuff_string(lang_name, F_NAME, LCL_LANG_NAME_LEN + 1);
+ required_string("+Special Character Index:");
+ stuff_int(&special_char_index);
+
+ // is the index sane?
+ // realistically, it has to be less than UCHAR_MAX to fit all the special chars, but not sure how many there are for all fonts & langs
+ // e.g. English font03.vf has 72 special chars?
+ if (special_char_index < 0 || special_char_index >= UCHAR_MAX) {
+ Error(LOCATION, "Special character index (%d) for font (%s), language (%s) is invalid, must be 0 - %u", special_char_index, font_filename, lang_name, UCHAR_MAX-1);
+ }
+
+ // find language and set the index, or if not found move to the next one
+ for (i = 0; i < (int)Lcl_languages.size(); ++i) {
+ if (!strcmp(Lcl_languages[i].lang_name, lang_name)) {
+ Lcl_languages[i].special_char_indexes[Num_fonts-1] = (ubyte)special_char_index;
+ break;
+ }
+ }
+
+ if (i >= (int)Lcl_languages.size()) {
+ Warning(LOCATION, "Ignoring font (%s) that specified an invalid language (%s); not built-in or in strings.tbl", font_filename, lang_name);
+ }
+ }
  }
  }

Code: [Select]
#Fonts

$Font: font01.vf
+Language: English
+Special Character Index: 130
+Language: French
+Special Character Index: 170
+Language: German
+Special Character Index: 170
+Language: Polish
+Special Character Index: 130
$Font: font02.vf
$Font: font03.vf
+Language: English
+Special Character Index: 140
+Language: French
+Special Character Index: 180
+Language: German
+Special Character Index: 180
+Language: Polish
+Special Character Index: 140

#End

[attachment deleted by ninja]
« Last Edit: October 31, 2013, 05:06:38 am by niffiwan »
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline Yarn

  • 210
Re: Support for every language (That you can fit in ASCII!)
If I'm not mistaken, fonts.tbl currently works only with subtitles and the fiction viewer. If this is true, then you'll have to expand it somehow to work with all text in the game.

It turns out that's actually wrong. Using 3.7.0, I tried using a font table to switch font01.vf and font03.vf and it did seem to work everywhere. It looks like the wiki page is wrong in this regard. EDIT: Just tried this with 3.6.12 and it worked there too.
« Last Edit: October 31, 2013, 02:52:45 am by Yarn »
"Your fighter is running out of oil.  Please check under the hood and add more if necessary"
--strings.tbl, entry 177

"Freespace is very tired.  It is shutting down to get some rest."
--strings.tbl, entry 178

 

Offline niffiwan

  • 211
  • Eluder Class
Re: Support for every language (That you can fit in ASCII!)
yeah, the fonts.tbl parser just grabs the fonts in order and adds them to FSO.  Putting font03 1st results in it being used where-ever font01 is normally used.  The wiki obviously needs an update on that... maybe fonts04 & 05 can only used in the fiction viewer/subtitles?  Actually, better include the hud as well since many gauges let you specify whatever font you've configured.

(and I finally built & uploaded the build)
Creating a fs2_open.log | Red Alert Bug = Hex Edit | MediaVPs 2014: Bigger HUD gauges | 32bit libs for 64bit Ubuntu
----
Debian Packages (testing/unstable): Freespace2 | wxLauncher
----
m|m: I think I'm suffering from Stockholm syndrome. Bmpman is starting to make sense and it's actually written reasonably well...

 

Offline Goober5000

  • HLP Loremaster
  • Moderator
  • 214
    • Goober5000 Productions
Re: Support for every language (That you can fit in ASCII!)
I guess I worded that wiki statement badly.  The subtitles and the fiction viewer can be manually set to any font in fonts.tbl, but all the rest of the fonts are hardcoded.  Except they are hardcoded to the first three fonts that are parsed.  (Originally they were hardcoded to just font01, font02, and font03.)

 

Offline Yarn

  • 210
Re: Support for every language (That you can fit in ASCII!)
I've got a few ideas that pertain to this feature:

1) Provide a way to mark parts of tables so that they're parsed only for certain languages. Here's one way it could be done:
Code: [Select]
;;Localize: German;;

; This section is parsed only if the current language is German.

;;Localize: French;;

; This section is parsed only if the current language is French.

;;Localize: default;;

; This section is parsed only if the sections above were not parsed.
; Note that this section must come last.

;;Localize: end;; ; Anything after this is parsed regardless of the current language.
This kind of structure would be most useful in help.tbl, where most of the parameters are appropriate for only one language. It would also be useful in hud_gauges.tbl, where gauges and parts of gauges could be configured differently for certain languages. (The code already does a similar thing with the ETS letters and the number in the kills gauge.)

2) I think it would be better to have the language stuff in its own file (like languages.tbl) rather than strings.tbl. Why? Well, if you search the source code for "Lcl_gr", you'll see just how many and what kind of hacks exist for German. French and Polish also have hacks like these, though not as many. Presumably, we'll eventually want to allow modders to define some of this stuff themselves, and the best place to do that would be in the language definitions that are currently in strings.tbl. By moving the definitions to another file, we can avoid cluttering strings.tbl with things that have nothing to do with internal XSTRs (which is what strings.tbl was originally designed for). Furthermore, if this file is required to exist outside the VPs, then the problem with needing to read through the VPs multiple times would be solved.
"Your fighter is running out of oil.  Please check under the hood and add more if necessary"
--strings.tbl, entry 177

"Freespace is very tired.  It is shutting down to get some rest."
--strings.tbl, entry 178