Preliminary i18n improvements

This commit is contained in:
Mathew Velasquez 2016-02-28 20:38:21 -05:00
parent a4de9d9f10
commit 546f29f42e
15 changed files with 166 additions and 59 deletions

View file

@ -150,8 +150,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
VALUE *str = va_arg(ap, VALUE*);
VALUE tmp = *arg;
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
tmp = rb_str_to_str(tmp);
*str = tmp;
++argI;
@ -169,8 +168,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
VALUE tmp = *arg;
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
tmp = rb_str_to_str(tmp);
*s = RSTRING_PTR(tmp);
*len = RSTRING_LEN(tmp);
@ -188,8 +186,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
VALUE tmp = *arg++;
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
tmp = rb_str_to_str(tmp);
*s = RSTRING_PTR(tmp);
++argI;

View file

@ -47,7 +47,7 @@ void oneshotBindingInit()
//Constants
rb_const_set(module, rb_intern("USER_NAME"), rb_str_new2(shState->oneshot().userName().c_str()));
rb_const_set(module, rb_intern("SAVE_PATH"), rb_str_new2(shState->oneshot().savePath().c_str()));
rb_const_set(module, rb_intern("LANG"), ID2SYM(rb_intern(shState->oneshot().lang().c_str())));
rb_const_set(module, rb_intern("LANG"), rb_str_new2(shState->oneshot().lang().c_str()));
rb_const_set(msg, rb_intern("INFO"), INT2FIX(Oneshot::MSG_INFO));
rb_const_set(msg, rb_intern("YESNO"), INT2FIX(Oneshot::MSG_YESNO));
rb_const_set(msg, rb_intern("WARN"), INT2FIX(Oneshot::MSG_WARN));

View file

@ -65,8 +65,13 @@ void steamBindingInit()
/* Constants */
#ifdef STEAM
rb_const_set(module, rb_intern("USER_NAME"), rb_str_new2(shState->steam().userName().c_str()));
if (shState->steam().lang().empty())
rb_const_set(module, rb_intern("LANG"), Qnil);
else
rb_const_set(module, rb_intern("LANG"), rb_str_new2(shState->steam().lang().c_str()));
#else
rb_const_set(module, rb_intern("USER_NAME"), Qnil);
rb_const_set(module, rb_intern("LANG"), Qnil);
#endif
/* Functions */

View file

@ -61,7 +61,7 @@ class Ed_Message
widths = []
# Pre-process text
text_raw = $game_temp.message_ed_text
text_raw = $game_temp.message_ed_text.to_str
# Substitute variables, actors, player name, newlines, etc
text_raw.gsub!(/\\v\[([0-9]+)\]/) do

View file

@ -6,34 +6,13 @@ class Game_Oneshot
attr_accessor :plight_timer # start of plight's plight
def initialize
user_name = Oneshot::USER_NAME.split(/\s+/)
user_name = (Steam.enabled? ? Steam::USER_NAME : Oneshot::USER_NAME).split(/\s+/)
if user_name[0].casecmp('the') == 0 || user_name[0].casecmp('a') == 0
@player_name = user_name.join(' ')
else
@player_name = user_name[0]
end
@lights = {}
self.lang = Oneshot::LANG
@plight_timer = nil
end
# lang
def lang
@lang
end
def lang=(val)
@lang = val
$tr = Translator.new(val)
$language = Language.get(val)
Font.default_name = $language.font
Oneshot.set_yes_no(tr('Yes'), tr('No'))
end
# MARSHAL
def marshal_dump
[@player_name, @lang, @plight_timer]
end
def marshal_load(array)
@player_name, self.lang, @plight_timer = array
end
end

View file

@ -8,6 +8,9 @@ begin
Graphics.frame_rate = 60
Font.default_size = 20
# Load persistent data
Persistent.load
# Prepare for transition
Graphics.freeze
# Make scene object (title screen)

63
scripts/Persistent.rb Normal file
View file

@ -0,0 +1,63 @@
# Persistent data independent from save file.
# Stores settings and the like.
class LanguageCode
attr_accessor :full
attr_accessor :lang
attr_accessor :region
def initialize(str)
parts = str.split(/[_-]/)
if parts.size == 1
@lang, @region = parts.first.downcase.to_sym, nil
@full = @lang
elsif parts.size == 2
@lang, @region = parts.first.downcase.to_sym, parts.last.upcase.to_sym
@full = (parts.first.downcase + '_' + parts.last.upcase).to_sym
else
raise "malformed language code: #{str}"
end
end
end
class Persistent
attr_reader :lang
def initialize
self.lang = LanguageCode.new(Steam::LANG || Oneshot::LANG)
end
# Members
def lang=(val)
@lang = val
$tr = Translator.new(@lang)
$lang = Language.get(@lang)
Font.default_name = $lang.font
Oneshot.set_yes_no(tr('Yes'), tr('No'))
end
# MARSHAL
def marshal_dump
[@lang]
end
def marshal_load(array)
self.lang = array.first
end
# Save/Load global instance of persistent
FILE_NAME = Oneshot::SAVE_PATH + '/persistent.dat'
def self.save
File.open(FILE_NAME, 'wb') do |file|
Marshal.dump($persistent, file)
end
end
def self.load
if FileTest.exist?(FILE_NAME)
File.open(FILE_NAME, 'rb') do |file|
$persistent = Marshal.load(file)
end
else
$persistent = Persistent.new
end
end
end

View file

@ -1,9 +1,7 @@
def save_file_name
Oneshot::SAVE_PATH + '/save.dat'
end
SAVE_FILE_NAME = Oneshot::SAVE_PATH + '/save.dat'
def save
File.open(save_file_name, 'wb') do |file|
File.open(SAVE_FILE_NAME, 'wb') do |file|
# Wrire frame count for measuring play time
Marshal.dump(Graphics.frame_count, file)
# Increase save count by 1
@ -27,8 +25,8 @@ def save
end
def load
return false unless FileTest.exist?(save_file_name)
File.open(save_file_name, 'rb') do |file|
return false unless FileTest.exist?(SAVE_FILE_NAME)
File.open(SAVE_FILE_NAME, 'rb') do |file|
# Read frame count for measuring play time
Graphics.frame_count = Marshal.load(file)
# Read each type of game object

View file

@ -29,8 +29,6 @@ class Scene_Title
# Load save game/initialize data
$game_temp = Game_Temp.new
new_game unless load
# Translate database items
$tr.translate_database
# Make system object
$game_system = Game_System.new
# Skip title screen if debug mode

View file

@ -96,6 +96,9 @@ Scene_Battle 4
Scene_Name
Scene_Debug
# Persistent data
Persistent
# Internationalization
i18n_Translator
i18n_Language

View file

@ -9,13 +9,16 @@ class Language
@character_table_height = character_table_height
end
def self.get(code = :en)
return LANGUAGES[code] || LANGUAGES[:en]
def self.get(lc)
return LANGUAGES[lc.full] || LANGUAGES[lc.lang] || LANGUAGES[:en]
end
FONT_WESTERN = 'Terminus (TTF)'
FONT_CJK = 'WenQuanYi Micro Hei'
LANGUAGES = {
:en => Language.new(
'Terminus (TTF)', [
FONT_WESTERN, [
"A","B","C","D","E",
"F","G","H","I","J",
"K","L","M","N","O",
@ -36,7 +39,7 @@ class Language
], 8
),
:es => Language.new(
'Terminus (TTF)', [
FONT_WESTERN, [
"A","B","C","D","E",
"F","G","H","I","J",
"K","L","M","N","O",
@ -59,7 +62,7 @@ class Language
], 9
),
:ja => Language.new(
'WenQuanYi Micro Hei', [
FONT_CJK, [
"","","","","",
"","","","","",
"","","","","",
@ -102,7 +105,7 @@ class Language
], 9
),
:ko => Language.new(
'WenQuanYi Micro Hei', [
FONT_CJK, [
"","","","","",
"","","","","",
"","","","","",

View file

@ -11,14 +11,13 @@ end
# Translator class: translate text to another language
class Translator
# Create Translator object
def initialize(code = :en)
if code == :en
@data = nil
else
def initialize(lc)
@data = nil
[lc.full.to_s, lc.lang.to_s].each do |name|
begin
@data = load_data("Languages/#{code.to_s}.rxdata")
@data = load_data("Langauges/#{name}.rxdata")
break
rescue
@data = nil
end
end
end
@ -71,10 +70,18 @@ class Translator
end
end
# Hacky translation helper function
# def tr(text)
# $tr.script(Kernel.caller.first.split(':', 3)[1], text)
# end
def tr(text)
text
# Translatable string
class TrString
def initialize(str)
@str = str
end
def to_str
@str
end
alias :to_s :to_str
end
def tr(text)
TrString.new(text)
end

View file

@ -227,7 +227,9 @@ Oneshot::Oneshot(const RGSSThreadData &threadData)
//Get language code
WCHAR wlang[9];
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, wlang, sizeof(wlang) / sizeof(WCHAR));
p->lang = w32_fromWide(wlang);
p->lang = w32_fromWide(wlang) + "_";
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, wlang, sizeof(wlang) / sizeof(WCHAR));
p->lang += w32_fromWide(wlang);
//Get user's name
ULONG size = 0;
@ -260,9 +262,9 @@ Oneshot::Oneshot(const RGSSThreadData &threadData)
const char *code = (lc_all ? lc_all : lang);
if (code)
{
//find first non alphanumeric character, copy language code
//find first dot, copy language code
int end = 0;
for (; code[end] && (code[end] >= 'a' && code[end] <= 'z'); ++end) {}
for (; code[end] && code[end] != '.'; ++end) {}
p->lang = std::string(code, end);
}
else

View file

@ -5,6 +5,45 @@
#include <SDL2/SDL.h>
#include "steamshim/steamshim_child.h"
/* Language map */
static const std::map<std::string, std::string> langToCode = {
{"brazilian", "pt_BR"},
{"bulgarian", "bg"},
{"czech", "cz"},
{"danish", "da"},
{"dutch", "nl"},
{"english", "en"},
{"finnish", "fi"},
{"french", "fr"},
{"german", "de"},
{"greek", "el"},
{"hungarian", "hu"},
{"italian", "it"},
{"japanese", "ja"},
{"koreana", "ko"},
{"korean", "ko"},
{"norwegian", "no"},
{"polish", "pl"},
{"portuguese", "pt"},
{"romanian", "ro"},
{"russian", "ru"},
{"schinese", "zh_CN"},
{"spanish", "es"},
{"swedish", "sv"},
{"tchinese", "zh_TW"},
{"thai", "th"},
{"turkish", "tr"},
{"ukrainian", "uk"},
};
static std::string steamToIsoLang(const char *steamLang)
{
auto it = langToCode.find(steamLang);
if (it != langToCode.end())
return it->second;
return "en";
}
/* Achievements */
static const char *const achievementNames[] = {
"SaveWorld",
@ -18,6 +57,7 @@ struct SteamPrivate
std::map<std::string, bool> achievements;
std::string userName;
std::string lang;
SteamPrivate()
{
@ -66,6 +106,8 @@ struct SteamPrivate
case SHIMEVENT_GETPERSONANAME:
userName = e->name;
break;
case SHIMEVENT_GETCURRENTGAMELANGUAGE:
lang = steamToIsoLang(e->name);
default:
break;
}
@ -75,6 +117,7 @@ struct SteamPrivate
bool initialized()
{
return !userName.empty()
&& !lang.empty()
&& achievements.size() == NUM_ACHIEVEMENTS;
}
};
@ -95,6 +138,11 @@ const std::string &Steam::userName() const
return p->userName;
}
const std::string &Steam::lang() const
{
return p->lang;
}
void Steam::unlock(const char *name)
{
p->setAchievement(name, true);

View file

@ -13,6 +13,7 @@ public:
bool isUnlocked(const char *name);
const std::string &userName() const;
const std::string &lang() const;
private:
Steam();