Enable localization of game text

This commit is contained in:
tdixon 2017-03-03 16:53:16 -04:00
parent 0f3217d16d
commit cfd30bbca6
9 changed files with 144 additions and 32 deletions

View file

@ -25,9 +25,9 @@ module EdText
sleep 0.2 sleep 0.2
end end
result = nil result = nil
text = Language.tr(text.to_s.gsub(/\s*\n\s*/, " ").strip)
thread = Thread.new do thread = Thread.new do
result = Oneshot.msgbox(type, text result = Oneshot.msgbox(type, text
.gsub(/\s+\n\s+/, " ")
.gsub("\\p", $game_oneshot.player_name) + .gsub("\\p", $game_oneshot.player_name) +
" " * 10) " " * 10)
# HACK: Fuck # HACK: Fuck

View file

@ -19,6 +19,10 @@ class Interpreter
# Create full text string # Create full text string
choices = false choices = false
text = @list[@index].parameters[0].strip text = @list[@index].parameters[0].strip
# Translate text
text = Language.tr(text).clone
if text.start_with?('$') if text.start_with?('$')
is_doc = true is_doc = true
text.slice!(0) text.slice!(0)
@ -31,11 +35,11 @@ class Interpreter
# 401: another line of text # 401: another line of text
if @list[@index+1].code == 401 if @list[@index+1].code == 401
@index += 1 @index += 1
text << " " << @list[@index].parameters[0].rstrip text << " " << Language.tr(@list[@index].parameters[0].rstrip).clone
elsif @list[@index+1].code == 101 && (is_doc || is_credits) elsif @list[@index+1].code == 101 && (is_doc || is_credits)
# 101: Another message box # 101: Another message box
# Tack on if we're a doc # Tack on if we're a doc
new_text = @list[@index+1].parameters[0].strip new_text = Language.tr(@list[@index+1].parameters[0].strip).clone
if new_text.start_with?('$') if new_text.start_with?('$')
text << "\n\n" << new_text[1..-1] text << "\n\n" << new_text[1..-1]
@index += 1 @index += 1
@ -64,9 +68,7 @@ class Interpreter
end end
text.gsub!(/\s*\\n\s*/, '\\n') text.gsub!(/\s*\\n\s*/, '\\n')
text.strip! text.strip!
text = Language.tr(text)
# Translate text
text = Language.tr(text).clone
# Parse first line for portrait specifier # Parse first line for portrait specifier
if text[0,1] == '@' if text[0,1] == '@'

View file

@ -16,7 +16,6 @@ begin
# Load persistent data # Load persistent data
Persistent.load Persistent.load
$persistent.lang = 'ja'
# Prepare for transition # Prepare for transition
Graphics.freeze Graphics.freeze

View file

@ -39,6 +39,10 @@ class Persistent
Language.set(@lang) Language.set(@lang)
end end
def langcode
self.lang.full.to_s
end
# MARSHAL # MARSHAL
def marshal_dump def marshal_dump
[@lang] [@lang]
@ -49,7 +53,7 @@ class Persistent
# Save/Load global instance of persistent # Save/Load global instance of persistent
FILE_NAME = Oneshot::SAVE_PATH + '/persistent.dat' FILE_NAME = Oneshot::SAVE_PATH + '/persistent.dat'
def self.save def save
File.open(FILE_NAME, 'wb') do |file| File.open(FILE_NAME, 'wb') do |file|
Marshal.dump($persistent, file) Marshal.dump($persistent, file)
end end

View file

@ -98,7 +98,7 @@ class Scene_Map
# either telling them they can't quit during a cutscene # either telling them they can't quit during a cutscene
# or telling them they're saving and quitting # or telling them they're saving and quitting
if $game_system.map_interpreter.running? if $game_system.map_interpreter.running?
EdText.info("You cannot perform this action during cutscenes.") EdText.info(tr("You cannot perform this action during cutscenes."))
return return
else else
$game_temp.common_event_id = 35 $game_temp.common_event_id = 35

View file

@ -5,9 +5,9 @@ class Window_MainMenu < Window_Selectable
# Set up menu options # Set up menu options
@commands = Array.new @commands = Array.new
@commands << tr('Travel') @commands << 'Travel'
@commands << tr('Notes') @commands << 'Notes'
@commands << tr('Settings') @commands << 'Settings'
@item_max = @commands.size @item_max = @commands.size
@column_max = @item_max @column_max = @item_max
@ -47,7 +47,7 @@ class Window_MainMenu < Window_Selectable
# Update item # Update item
rect = Rect.new(w * index, 0, w - 32, 32) rect = Rect.new(w * index, 0, w - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
self.contents.draw_text(rect, @commands[index], 1) self.contents.draw_text(rect, tr(@commands[index]), 1)
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Disable Item # * Disable Item
@ -59,6 +59,10 @@ class Window_MainMenu < Window_Selectable
# Open/show the menu # Open/show the menu
def open def open
# redraw in case language has been updated
for i in 0...@item_max
draw_item(i, normal_color)
end
self.opacity = 0 self.opacity = 0
self.contents_opacity = 0 self.contents_opacity = 0
self.visible = true self.visible = true

View file

@ -7,6 +7,7 @@ class Window_Settings
SETTINGS_FILE_NAME = Oneshot::SAVE_PATH + '/settings.conf' SETTINGS_FILE_NAME = Oneshot::SAVE_PATH + '/settings.conf'
def save_settings def save_settings
$persistent.save
File.open(SETTINGS_FILE_NAME, 'w') do |file| File.open(SETTINGS_FILE_NAME, 'w') do |file|
file.puts('bgm_volume=' + Audio.bgm_volume.to_s) file.puts('bgm_volume=' + Audio.bgm_volume.to_s)
file.puts('sfx_volume=' + Audio.sfx_volume.to_s) file.puts('sfx_volume=' + Audio.sfx_volume.to_s)
@ -75,6 +76,7 @@ class Window_Settings
@title.bitmap.font.size = 40 @title.bitmap.font.size = 40
@title.y = TITLE_TOP_MARGIN @title.y = TITLE_TOP_MARGIN
@title.x = MARGIN @title.x = MARGIN
Language.register_text_sprite(self.class.name + "_title", @title)
@data_sprites = [] @data_sprites = []
@viewport.z = 9998 @viewport.z = 9998
@ -110,10 +112,16 @@ class Window_Settings
tr('Default movement'), tr('Default movement'),
tr('Colorblind mode'), tr('Colorblind mode'),
tr('Frameskip'), tr('Frameskip'),
tr('Language'),
tr('Configure Controls (Press F1)'), tr('Configure Controls (Press F1)'),
] ]
@index = 0 @index = 0
# Load our language settings from persistent, stored differently
@lang_index = Language::LANGUAGES.index($persistent.langcode)
if @lang_index.nil?
@lang_index = 0
end
# Create title # Create title
@title.bitmap.clear @title.bitmap.clear
@ -126,6 +134,7 @@ class Window_Settings
spr.x = MARGIN spr.x = MARGIN
spr.y = TITLE_MARGIN + TITLE_TOP_MARGIN + ITEM_SPACING * i spr.y = TITLE_MARGIN + TITLE_TOP_MARGIN + ITEM_SPACING * i
spr.opacity = 0 spr.opacity = 0
Language.register_text_sprite(self.class.name + "_option_#{i}", spr)
redraw_setting(spr, i) redraw_setting(spr, i)
@data_sprites << spr @data_sprites << spr
@ -168,9 +177,13 @@ class Window_Settings
else else
spr.bitmap.draw_text(260, 0, spr.bitmap.width, spr.bitmap.height, tr("OFF")) spr.bitmap.draw_text(260, 0, spr.bitmap.width, spr.bitmap.height, tr("OFF"))
end end
when 6 # Language
l = Language::LANGUAGES[@lang_index] rescue Language::LANGUAGES[0]
spr.bitmap.draw_text(260, 0, spr.bitmap.width, spr.bitmap.height, l)
end end
end end
def redraw_setting_index(i) def redraw_setting_index(i)
if !@data_sprites.kind_of?(Array) if !@data_sprites.kind_of?(Array)
return return
@ -181,6 +194,16 @@ class Window_Settings
redraw_setting(@data_sprites[i], i) redraw_setting(@data_sprites[i], i)
end end
def redraw_all_settings
@title.bitmap.clear
@title.bitmap.draw_text(0, 0, @title.bitmap.width, @title.bitmap.height, tr("Settings"))
for i in 0..7
redraw_setting_index(i)
end
end
def update def update
if @fade_in if @fade_in
self.opacity += 20 self.opacity += 20
@ -276,15 +299,16 @@ class Window_Settings
Audio.bgm_volume -= 1 Audio.bgm_volume -= 1
if old_vol > 1 if old_vol > 1
Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.bgm_volume/2) + 75) Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.bgm_volume/2) + 75)
redraw_setting_index(0)
end end
elsif Input.trigger?(Input::RIGHT) || (Input.press?(Input::RIGHT) && (@right_hold_timer >= 15)) elsif Input.trigger?(Input::RIGHT) || (Input.press?(Input::RIGHT) && (@right_hold_timer >= 15))
@right_hold_timer -= 2 @right_hold_timer -= 2
Audio.bgm_volume += 1 Audio.bgm_volume += 1
if old_vol < 100 if old_vol < 100
Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.bgm_volume/2) + 75) Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.bgm_volume/2) + 75)
end
end
redraw_setting_index(0) redraw_setting_index(0)
end
end
when 1 #sfx vol when 1 #sfx vol
old_vol = Audio.sfx_volume old_vol = Audio.sfx_volume
@ -293,15 +317,16 @@ class Window_Settings
Audio.sfx_volume -= 1 Audio.sfx_volume -= 1
if old_vol > 1 if old_vol > 1
Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.sfx_volume/2) + 75) Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.sfx_volume/2) + 75)
redraw_setting_index(1)
end end
elsif Input.trigger?(Input::RIGHT) || (Input.press?(Input::RIGHT) && (@right_hold_timer >= 15)) elsif Input.trigger?(Input::RIGHT) || (Input.press?(Input::RIGHT) && (@right_hold_timer >= 15))
@right_hold_timer -= 2 @right_hold_timer -= 2
Audio.sfx_volume += 1 Audio.sfx_volume += 1
if old_vol < 100 if old_vol < 100
Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.sfx_volume/2) + 75) Audio.se_play("Audio/SE/text_robot.wav", 70, (Audio.sfx_volume/2) + 75)
end
end
redraw_setting_index(1) redraw_setting_index(1)
end
end
when 2 #fullscreen when 2 #fullscreen
if Input.trigger?(Input::ACTION) || Input.trigger?(Input::LEFT) || Input.trigger?(Input::RIGHT) if Input.trigger?(Input::ACTION) || Input.trigger?(Input::LEFT) || Input.trigger?(Input::RIGHT)
@ -354,6 +379,24 @@ class Window_Settings
end end
redraw_setting_index(5) redraw_setting_index(5)
end end
when 6 #language
if Input.trigger?(Input::ACTION) || Input.trigger?(Input::RIGHT)
@lang_index += 1
if @lang_index >= Language::LANGUAGES.length
@lang_index = 0
end
$persistent.lang = Language::LANGUAGES[@lang_index]
redraw_all_settings()
end
if Input.trigger?(Input::LEFT)
@lang_index -= 1
if @lang_index < 0
@lang_index = Language::LANGUAGES.length - 1
end
$persistent.lang = Language::LANGUAGES[@lang_index]
redraw_all_settings()
end
end end
if Input.trigger?(Input::CANCEL) if Input.trigger?(Input::CANCEL)

View file

@ -100,7 +100,7 @@ Persistent
# Internationalization # Internationalization
i18n_Language i18n_Language
i18n_English i18n_Japanese
# Data # Data
Data_Item Data_Item

View file

@ -1,32 +1,56 @@
# Classes for translating text similar to GNU gettext # Classes for translating text similar to GNU gettext
# Translator class: translate text to another language # Translator class: translate text to another language
# for debug REMOVE BEFORE COMMITTING
require "zlib"
class Language class Language
FONT_WESTERN = 'Terminus (TTF)' FONT_WESTERN = 'Terminus (TTF)'
FONT_CJK = 'WenQuanYi Micro Hei' FONT_CJK = 'WenQuanYi Micro Hei'
LANG_WESTERN = [
'en', 'fr', 'pt_BR'
]
LANG_CJK = [
'ja', 'ko', 'zh_CN'
]
LANGUAGES = LANG_WESTERN + LANG_CJK
class << self class << self
def set(lc) def set(lc)
dbg_print(lc.lang)
@data = nil
@tr = nil @tr = nil
script = nil script = nil
[lc.full.to_s, lc.lang.to_s].each do |name| [lc.full.to_s, lc.lang.to_s].each do |name|
begin path = "Languages/#{name}.loc"
@tr, script = load_data("Languages/#{name}.rxdata") dbg_print(path)
break if FileTest.exist?(path)
rescue File.open(path, "rb") do |file|
@data = Marshal.load(file)
if LANG_CJK.include? name
Font.default_name = FONT_CJK
else
Font.default_name = FONT_WESTERN
end end
end end
exec(script) if script end
end
reset_fonts(@text_sprites)
Oneshot.set_yes_no(tr('Yes'), tr('No')) Oneshot.set_yes_no(tr('Yes'), tr('No'))
end end
# Translate some text # Translate some text
def tr(string) def tr(string)
#dbg_print(caller_locations(1, 1).first.tap{|loc| puts "#{loc.path}:#{loc.lineno}"})
dbg_print(string)
if @data if @data
@data[Zlib::crc32(string)] || string rv = @data[Zlib::crc32(string)] || string
else else
string rv = string
end end
dbg_print(rv)
return rv
end end
# Turn all database items into translatable strings # Turn all database items into translatable strings
@ -41,6 +65,42 @@ class Language
end end
end end
end end
def dbg_print(str)
dbg = IO.new(STDERR.fileno)
if str.nil?
dbg.write("null\n")
else
dbg.write(str.to_s + "\n")
end
dbg.close()
end
def register_text_sprite(key, spr)
dbg_print(key)
if @text_sprites.nil?
@text_sprites = Hash.new()
end
@text_sprites[key] = spr
end
def reset_fonts(sprites)
if sprites.kind_of?(Array)
sprites.each do |spr|
if spr.kind_of?(Sprite)
spr.bitmap.font.name = Font.default_name
end
end
elsif sprites.kind_of?(Hash)
sprites.each_value do |spr|
if spr.kind_of?(Sprite)
spr.bitmap.font.name = Font.default_name
end
end
elsif sprites.kind_of?(Sprite)
sprites.bitmap.font.name = Font.default_name
end
end
end end
end end