Preliminary i18n improvements
This commit is contained in:
parent
a4de9d9f10
commit
546f29f42e
|
|
@ -150,8 +150,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
|
||||||
VALUE *str = va_arg(ap, VALUE*);
|
VALUE *str = va_arg(ap, VALUE*);
|
||||||
VALUE tmp = *arg;
|
VALUE tmp = *arg;
|
||||||
|
|
||||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
tmp = rb_str_to_str(tmp);
|
||||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
|
||||||
|
|
||||||
*str = tmp;
|
*str = tmp;
|
||||||
++argI;
|
++argI;
|
||||||
|
|
@ -169,8 +168,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
|
||||||
|
|
||||||
VALUE tmp = *arg;
|
VALUE tmp = *arg;
|
||||||
|
|
||||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
tmp = rb_str_to_str(tmp);
|
||||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
|
||||||
|
|
||||||
*s = RSTRING_PTR(tmp);
|
*s = RSTRING_PTR(tmp);
|
||||||
*len = RSTRING_LEN(tmp);
|
*len = RSTRING_LEN(tmp);
|
||||||
|
|
@ -188,8 +186,7 @@ rb_get_args(int argc, VALUE *argv, const char *format, ...)
|
||||||
|
|
||||||
VALUE tmp = *arg++;
|
VALUE tmp = *arg++;
|
||||||
|
|
||||||
if (!RB_TYPE_P(tmp, RUBY_T_STRING))
|
tmp = rb_str_to_str(tmp);
|
||||||
rb_raise(rb_eTypeError, "Argument %d: Expected string", argI);
|
|
||||||
|
|
||||||
*s = RSTRING_PTR(tmp);
|
*s = RSTRING_PTR(tmp);
|
||||||
++argI;
|
++argI;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ void oneshotBindingInit()
|
||||||
//Constants
|
//Constants
|
||||||
rb_const_set(module, rb_intern("USER_NAME"), rb_str_new2(shState->oneshot().userName().c_str()));
|
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("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("INFO"), INT2FIX(Oneshot::MSG_INFO));
|
||||||
rb_const_set(msg, rb_intern("YESNO"), INT2FIX(Oneshot::MSG_YESNO));
|
rb_const_set(msg, rb_intern("YESNO"), INT2FIX(Oneshot::MSG_YESNO));
|
||||||
rb_const_set(msg, rb_intern("WARN"), INT2FIX(Oneshot::MSG_WARN));
|
rb_const_set(msg, rb_intern("WARN"), INT2FIX(Oneshot::MSG_WARN));
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,13 @@ void steamBindingInit()
|
||||||
/* Constants */
|
/* Constants */
|
||||||
#ifdef STEAM
|
#ifdef STEAM
|
||||||
rb_const_set(module, rb_intern("USER_NAME"), rb_str_new2(shState->steam().userName().c_str()));
|
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
|
#else
|
||||||
rb_const_set(module, rb_intern("USER_NAME"), Qnil);
|
rb_const_set(module, rb_intern("USER_NAME"), Qnil);
|
||||||
|
rb_const_set(module, rb_intern("LANG"), Qnil);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class Ed_Message
|
||||||
widths = []
|
widths = []
|
||||||
|
|
||||||
# Pre-process text
|
# 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
|
# Substitute variables, actors, player name, newlines, etc
|
||||||
text_raw.gsub!(/\\v\[([0-9]+)\]/) do
|
text_raw.gsub!(/\\v\[([0-9]+)\]/) do
|
||||||
|
|
|
||||||
|
|
@ -6,34 +6,13 @@ class Game_Oneshot
|
||||||
attr_accessor :plight_timer # start of plight's plight
|
attr_accessor :plight_timer # start of plight's plight
|
||||||
|
|
||||||
def initialize
|
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
|
if user_name[0].casecmp('the') == 0 || user_name[0].casecmp('a') == 0
|
||||||
@player_name = user_name.join(' ')
|
@player_name = user_name.join(' ')
|
||||||
else
|
else
|
||||||
@player_name = user_name[0]
|
@player_name = user_name[0]
|
||||||
end
|
end
|
||||||
@lights = {}
|
@lights = {}
|
||||||
self.lang = Oneshot::LANG
|
|
||||||
@plight_timer = nil
|
@plight_timer = nil
|
||||||
end
|
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
|
end
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ begin
|
||||||
Graphics.frame_rate = 60
|
Graphics.frame_rate = 60
|
||||||
Font.default_size = 20
|
Font.default_size = 20
|
||||||
|
|
||||||
|
# Load persistent data
|
||||||
|
Persistent.load
|
||||||
|
|
||||||
# Prepare for transition
|
# Prepare for transition
|
||||||
Graphics.freeze
|
Graphics.freeze
|
||||||
# Make scene object (title screen)
|
# Make scene object (title screen)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
def save_file_name
|
SAVE_FILE_NAME = Oneshot::SAVE_PATH + '/save.dat'
|
||||||
Oneshot::SAVE_PATH + '/save.dat'
|
|
||||||
end
|
|
||||||
|
|
||||||
def save
|
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
|
# Wrire frame count for measuring play time
|
||||||
Marshal.dump(Graphics.frame_count, file)
|
Marshal.dump(Graphics.frame_count, file)
|
||||||
# Increase save count by 1
|
# Increase save count by 1
|
||||||
|
|
@ -27,8 +25,8 @@ def save
|
||||||
end
|
end
|
||||||
|
|
||||||
def load
|
def load
|
||||||
return false unless FileTest.exist?(save_file_name)
|
return false unless FileTest.exist?(SAVE_FILE_NAME)
|
||||||
File.open(save_file_name, 'rb') do |file|
|
File.open(SAVE_FILE_NAME, 'rb') do |file|
|
||||||
# Read frame count for measuring play time
|
# Read frame count for measuring play time
|
||||||
Graphics.frame_count = Marshal.load(file)
|
Graphics.frame_count = Marshal.load(file)
|
||||||
# Read each type of game object
|
# Read each type of game object
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ class Scene_Title
|
||||||
# Load save game/initialize data
|
# Load save game/initialize data
|
||||||
$game_temp = Game_Temp.new
|
$game_temp = Game_Temp.new
|
||||||
new_game unless load
|
new_game unless load
|
||||||
# Translate database items
|
|
||||||
$tr.translate_database
|
|
||||||
# Make system object
|
# Make system object
|
||||||
$game_system = Game_System.new
|
$game_system = Game_System.new
|
||||||
# Skip title screen if debug mode
|
# Skip title screen if debug mode
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,9 @@ Scene_Battle 4
|
||||||
Scene_Name
|
Scene_Name
|
||||||
Scene_Debug
|
Scene_Debug
|
||||||
|
|
||||||
|
# Persistent data
|
||||||
|
Persistent
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
i18n_Translator
|
i18n_Translator
|
||||||
i18n_Language
|
i18n_Language
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,16 @@ class Language
|
||||||
@character_table_height = character_table_height
|
@character_table_height = character_table_height
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.get(code = :en)
|
def self.get(lc)
|
||||||
return LANGUAGES[code] || LANGUAGES[:en]
|
return LANGUAGES[lc.full] || LANGUAGES[lc.lang] || LANGUAGES[:en]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
FONT_WESTERN = 'Terminus (TTF)'
|
||||||
|
FONT_CJK = 'WenQuanYi Micro Hei'
|
||||||
|
|
||||||
LANGUAGES = {
|
LANGUAGES = {
|
||||||
:en => Language.new(
|
:en => Language.new(
|
||||||
'Terminus (TTF)', [
|
FONT_WESTERN, [
|
||||||
"A","B","C","D","E",
|
"A","B","C","D","E",
|
||||||
"F","G","H","I","J",
|
"F","G","H","I","J",
|
||||||
"K","L","M","N","O",
|
"K","L","M","N","O",
|
||||||
|
|
@ -36,7 +39,7 @@ class Language
|
||||||
], 8
|
], 8
|
||||||
),
|
),
|
||||||
:es => Language.new(
|
:es => Language.new(
|
||||||
'Terminus (TTF)', [
|
FONT_WESTERN, [
|
||||||
"A","B","C","D","E",
|
"A","B","C","D","E",
|
||||||
"F","G","H","I","J",
|
"F","G","H","I","J",
|
||||||
"K","L","M","N","O",
|
"K","L","M","N","O",
|
||||||
|
|
@ -59,7 +62,7 @@ class Language
|
||||||
], 9
|
], 9
|
||||||
),
|
),
|
||||||
:ja => Language.new(
|
:ja => Language.new(
|
||||||
'WenQuanYi Micro Hei', [
|
FONT_CJK, [
|
||||||
"あ","い","う","え","お",
|
"あ","い","う","え","お",
|
||||||
"か","き","く","け","こ",
|
"か","き","く","け","こ",
|
||||||
"さ","し","す","せ","そ",
|
"さ","し","す","せ","そ",
|
||||||
|
|
@ -102,7 +105,7 @@ class Language
|
||||||
], 9
|
], 9
|
||||||
),
|
),
|
||||||
:ko => Language.new(
|
:ko => Language.new(
|
||||||
'WenQuanYi Micro Hei', [
|
FONT_CJK, [
|
||||||
"가","개","갸","거","게",
|
"가","개","갸","거","게",
|
||||||
"겨","고","교","구","규",
|
"겨","고","교","구","규",
|
||||||
"그","기","나","내","냐",
|
"그","기","나","내","냐",
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,13 @@ end
|
||||||
# Translator class: translate text to another language
|
# Translator class: translate text to another language
|
||||||
class Translator
|
class Translator
|
||||||
# Create Translator object
|
# Create Translator object
|
||||||
def initialize(code = :en)
|
def initialize(lc)
|
||||||
if code == :en
|
|
||||||
@data = nil
|
@data = nil
|
||||||
else
|
[lc.full.to_s, lc.lang.to_s].each do |name|
|
||||||
begin
|
begin
|
||||||
@data = load_data("Languages/#{code.to_s}.rxdata")
|
@data = load_data("Langauges/#{name}.rxdata")
|
||||||
|
break
|
||||||
rescue
|
rescue
|
||||||
@data = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -71,10 +70,18 @@ class Translator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Hacky translation helper function
|
# Translatable string
|
||||||
# def tr(text)
|
class TrString
|
||||||
# $tr.script(Kernel.caller.first.split(':', 3)[1], text)
|
def initialize(str)
|
||||||
# end
|
@str = str
|
||||||
def tr(text)
|
end
|
||||||
text
|
|
||||||
|
def to_str
|
||||||
|
@str
|
||||||
|
end
|
||||||
|
alias :to_s :to_str
|
||||||
|
end
|
||||||
|
|
||||||
|
def tr(text)
|
||||||
|
TrString.new(text)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,9 @@ Oneshot::Oneshot(const RGSSThreadData &threadData)
|
||||||
//Get language code
|
//Get language code
|
||||||
WCHAR wlang[9];
|
WCHAR wlang[9];
|
||||||
GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, wlang, sizeof(wlang) / sizeof(WCHAR));
|
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
|
//Get user's name
|
||||||
ULONG size = 0;
|
ULONG size = 0;
|
||||||
|
|
@ -260,9 +262,9 @@ Oneshot::Oneshot(const RGSSThreadData &threadData)
|
||||||
const char *code = (lc_all ? lc_all : lang);
|
const char *code = (lc_all ? lc_all : lang);
|
||||||
if (code)
|
if (code)
|
||||||
{
|
{
|
||||||
//find first non alphanumeric character, copy language code
|
//find first dot, copy language code
|
||||||
int end = 0;
|
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);
|
p->lang = std::string(code, end);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,45 @@
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include "steamshim/steamshim_child.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 */
|
/* Achievements */
|
||||||
static const char *const achievementNames[] = {
|
static const char *const achievementNames[] = {
|
||||||
"SaveWorld",
|
"SaveWorld",
|
||||||
|
|
@ -18,6 +57,7 @@ struct SteamPrivate
|
||||||
std::map<std::string, bool> achievements;
|
std::map<std::string, bool> achievements;
|
||||||
|
|
||||||
std::string userName;
|
std::string userName;
|
||||||
|
std::string lang;
|
||||||
|
|
||||||
SteamPrivate()
|
SteamPrivate()
|
||||||
{
|
{
|
||||||
|
|
@ -66,6 +106,8 @@ struct SteamPrivate
|
||||||
case SHIMEVENT_GETPERSONANAME:
|
case SHIMEVENT_GETPERSONANAME:
|
||||||
userName = e->name;
|
userName = e->name;
|
||||||
break;
|
break;
|
||||||
|
case SHIMEVENT_GETCURRENTGAMELANGUAGE:
|
||||||
|
lang = steamToIsoLang(e->name);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -75,6 +117,7 @@ struct SteamPrivate
|
||||||
bool initialized()
|
bool initialized()
|
||||||
{
|
{
|
||||||
return !userName.empty()
|
return !userName.empty()
|
||||||
|
&& !lang.empty()
|
||||||
&& achievements.size() == NUM_ACHIEVEMENTS;
|
&& achievements.size() == NUM_ACHIEVEMENTS;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -95,6 +138,11 @@ const std::string &Steam::userName() const
|
||||||
return p->userName;
|
return p->userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &Steam::lang() const
|
||||||
|
{
|
||||||
|
return p->lang;
|
||||||
|
}
|
||||||
|
|
||||||
void Steam::unlock(const char *name)
|
void Steam::unlock(const char *name)
|
||||||
{
|
{
|
||||||
p->setAchievement(name, true);
|
p->setAchievement(name, true);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ public:
|
||||||
bool isUnlocked(const char *name);
|
bool isUnlocked(const char *name);
|
||||||
|
|
||||||
const std::string &userName() const;
|
const std::string &userName() const;
|
||||||
|
const std::string &lang() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Steam();
|
Steam();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue