Merge branch 'localization' into chroma-intergration

This commit is contained in:
tdixon 2017-10-10 21:39:58 -03:00
commit 695d2af03a
18 changed files with 652 additions and 203 deletions

View file

@ -2,6 +2,7 @@
#include "binding-types.h" #include "binding-types.h"
#include "pipe.h" #include "pipe.h"
#include "debugwriter.h" #include "debugwriter.h"
#include "i18n.h"
#include <SDL.h> #include <SDL.h>
@ -73,9 +74,14 @@ RB_METHOD(journalSet)
// Record message // Record message
SDL_LockMutex(mutex); SDL_LockMutex(mutex);
message_len = strlen(name); message_len = strlen(name);
memcpy((char*)message_buffer, name, message_len); strcpy((char*)message_buffer, name);
strcpy((char*)message_buffer + message_len, (char*)lang_buffer); if (message_len > 0) {
message_len += strlen((char*)lang_buffer); // in the case where journal is being sent empty string
// do not append the language suffix, because empty string
// is the signifier to terminate the journal
strcpy((char*)message_buffer + message_len, (char*)lang_buffer);
message_len += strlen((char*)lang_buffer);
}
SDL_UnlockMutex(mutex); SDL_UnlockMutex(mutex);
#if defined _WIN32 #if defined _WIN32
@ -127,6 +133,7 @@ RB_METHOD(journalSetLang)
const char *lang; const char *lang;
rb_get_args(argc, argv, "z", &lang RB_ARG_END); rb_get_args(argc, argv, "z", &lang RB_ARG_END);
strcpy((char*)lang_buffer+1, lang); strcpy((char*)lang_buffer+1, lang);
loadLocale(lang);
return Qnil; return Qnil;
} }

View file

@ -62,7 +62,7 @@ win32 {
w32/niko.c \ w32/niko.c \
w32/journal.c w32/journal.c
LIBS += -lgdi32 -lshlwapi LIBS += -lgdi32 -lshell32 -luuid -lole32
RC_FILE = w32/resources.rc RC_FILE = w32/resources.rc
} }

View file

@ -1,5 +1,8 @@
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#include <windows.h> #include <windows.h>
#include <shlwapi.h> #include <stdio.h>
#include <objbase.h>
#include <shlobj.h> #include <shlobj.h>
#define DEFAULT_WIDTH 800 #define DEFAULT_WIDTH 800
@ -67,7 +70,6 @@ LRESULT CALLBACK journal_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
} }
// IPC thread // IPC thread
#include <stdio.h>
DWORD WINAPI ipc_thread(LPVOID lpParam) DWORD WINAPI ipc_thread(LPVOID lpParam)
{ {
(void)lpParam; (void)lpParam;
@ -110,20 +112,53 @@ DWORD WINAPI ipc_thread(LPVOID lpParam)
return 0; return 0;
} }
// check if the file "My Documents/My Games/Oneshot/save_progress.oneshot" exist
// if not, load the "default" image background
// if it does exist, try to read the last 8.. or so.. bytes from the file.
// this (should) contain a string like [XX_XX] or [XX] indicating the user's
// language code. This will be apended with an underscore to "save"
// to give the localized image file IFF the lang str exists
void init_check_save(WCHAR* save_path) {
FILE* savefile = _wfopen(save_path, L"rb");
char imgfile[16] = {0};
char langbuf[9] = {0};
char* openbrace = 0;
char* closebrace = 0;
if (savefile) {
strcpy(imgfile, "save");
fseek(savefile, -8, SEEK_END);
fread(langbuf, 1, 8, savefile);
fclose(savefile);
openbrace = strchr(langbuf, '[');
closebrace = strchr(langbuf, ']');
if (openbrace && closebrace && openbrace < closebrace) {
//we very probably have a language code here.
//so, lets do some hacky string manipulation to
//name our image file
imgfile[4] = '_';
strncpy(imgfile+5, openbrace+1, closebrace-(openbrace+1));
}
loadImage(imgfile);
} else {
loadImage("default");
}
}
int do_journal() int do_journal()
{ {
// Create // Create
HINSTANCE module = GetModuleHandleW(NULL); HINSTANCE module = GetModuleHandleW(NULL);
// Default image // Default image
WCHAR save_path[MAX_PATH]; WCHAR save_path[MAX_PATH];
SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, save_path); PWSTR folder_path = NULL;
SHGetKnownFolderPath((REFKNOWNFOLDERID)&FOLDERID_Documents, 0, NULL, &folder_path);
wcscpy(save_path, folder_path);
wcscat(save_path, L"\\My Games\\Oneshot\\save_progress.oneshot"); wcscat(save_path, L"\\My Games\\Oneshot\\save_progress.oneshot");
if (PathFileExistsW(save_path)) { CoTaskMemFree(folder_path);
loadImage("save"); init_check_save(save_path);
} else {
loadImage("default");
}
// Initial image // Initial image
char message[IN_BUFFER_SIZE]; char message[IN_BUFFER_SIZE];

View file

@ -161,7 +161,8 @@ HEADERS += \
chromasdk/ChromaSDKImpl.h \ chromasdk/ChromaSDKImpl.h \
chromasdk/RzChromaSDKDefines.h \ chromasdk/RzChromaSDKDefines.h \
chromasdk/RzChromaSDKTypes.h \ chromasdk/RzChromaSDKTypes.h \
chromasdk/RzErrors.h chromasdk/RzErrors.h \
src/i18n.h
SOURCES += \ SOURCES += \
src/main.cpp \ src/main.cpp \
@ -205,7 +206,8 @@ SOURCES += \
binding-mri/journal-binding.cpp \ binding-mri/journal-binding.cpp \
chromasdk/FrameController.cpp \ chromasdk/FrameController.cpp \
chromasdk/ChromaSdkImpl.cpp \ chromasdk/ChromaSdkImpl.cpp \
binding-mri/chroma-binding.cpp binding-mri/chroma-binding.cpp \
src/i18n.cpp
STEAM { STEAM {
HEADERS += src/steam.h steamshim/steamshim_child.h HEADERS += src/steam.h steamshim/steamshim_child.h

View file

@ -9,14 +9,26 @@ class Doc_Message
def initialize def initialize
@viewport = Viewport.new(0, 0, 640, 480) @viewport = Viewport.new(0, 0, 640, 480)
@sprite_bg = Sprite.new(@viewport) @sprite_bg = Sprite.new(@viewport)
if $game_switches[124] == true @sprite_scroll_up = Sprite.new(@viewport)
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red') @sprite_scroll_down = Sprite.new(@viewport)
else if $game_switches[124] == true
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red')
@sprite_scroll_up.bitmap = RPG::Cache.picture('scroll_up_red')
@sprite_scroll_down.bitmap = RPG::Cache.picture('scroll_down_red')
else
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_blue') #Bitmap.new(640, 480) @sprite_bg.bitmap = RPG::Cache.picture('lined_paper_blue') #Bitmap.new(640, 480)
end @sprite_scroll_up.bitmap = RPG::Cache.picture('scroll_up_blue')
@sprite_scroll_down.bitmap = RPG::Cache.picture('scroll_down_blue')
end
@sprite_bg.zoom_x = @sprite_bg.zoom_y = 2 @sprite_bg.zoom_x = @sprite_bg.zoom_y = 2
@sprite_bg.x = 120 @sprite_bg.x = 120
@sprite_bg.y = 24 @sprite_bg.y = 24
@sprite_scroll_up.zoom_x = @sprite_scroll_up.zoom_y = 2
@sprite_scroll_up.x = 524
@sprite_scroll_up.y = 24
@sprite_scroll_down.zoom_x = @sprite_scroll_down.zoom_y = 2
@sprite_scroll_down.x = 524
@sprite_scroll_down.y = 424
#@sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 128)) #@sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 128))
@sprite_text = Sprite.new(@viewport) @sprite_text = Sprite.new(@viewport)
@contents = Bitmap.new(200, 216) @contents = Bitmap.new(200, 216)
@ -33,6 +45,11 @@ class Doc_Message
@sprite_bg.opacity = 0 @sprite_bg.opacity = 0
@sprite_text.opacity = 0 @sprite_text.opacity = 0
@sprite_scroll_down.opacity = 0
@sprite_scroll_up.opacity = 0
@y_offset = 0
@scroll_limit = 0
# Animation flags # Animation flags
@fade_in = false @fade_in = false
@ -59,6 +76,7 @@ class Doc_Message
$game_temp.message_proc = nil $game_temp.message_proc = nil
end end
$game_temp.message_doc_text = nil $game_temp.message_doc_text = nil
@y_offset = 0
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Refresh: Load new message text and pre-process it # * Refresh: Load new message text and pre-process it
@ -68,11 +86,11 @@ class Doc_Message
text = '' text = ''
y = -1 y = -1
if $game_switches[124] == true if $game_switches[124] == true
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red') @sprite_bg.bitmap = RPG::Cache.picture('lined_paper_red')
else else
@sprite_bg.bitmap = RPG::Cache.picture('lined_paper_blue') #Bitmap.new(640, 480) @sprite_bg.bitmap = RPG::Cache.picture('lined_paper_blue') #Bitmap.new(640, 480)
end end
# Pre-process text # Pre-process text
text_raw = $game_temp.message_doc_text.to_str text_raw = $game_temp.message_doc_text.to_str
@ -92,7 +110,8 @@ class Doc_Message
text_raw.gsub!("\\\\", "\\") text_raw.gsub!("\\\\", "\\")
# Now split text into lines by measuring text metrics # Now split text into lines by measuring text metrics
x = y = 0 x = 0
y = 1
maxwidth = @contents.width - HORIZ_MARGIN * 2 maxwidth = @contents.width - HORIZ_MARGIN * 2
spacesize = @contents.text_size(' ') spacesize = @contents.text_size(' ')
for i in text_raw.split(/ /) for i in text_raw.split(/ /)
@ -126,6 +145,11 @@ class Doc_Message
end end
end end
@scroll_limit = 11 - y
if @scroll_limit > 0
@scroll_limit = 0
end
# Prepare renderer # Prepare renderer
@contents.clear @contents.clear
@contents.font.color = Color.new(100, 92, 255, 255) @contents.font.color = Color.new(100, 92, 255, 255)
@ -133,7 +157,7 @@ class Doc_Message
@contents.font.color = Color.new(255, 92, 100, 255) @contents.font.color = Color.new(255, 92, 100, 255)
end end
x = 0 x = 0
y = 0 y = 1
# Get 1 text character in c (loop until unable to get text) # Get 1 text character in c (loop until unable to get text)
while ((c = text.slice!(/./m)) != nil) while ((c = text.slice!(/./m)) != nil)
@ -155,7 +179,7 @@ class Doc_Message
next next
end end
# Draw text # Draw text
@contents.draw_text(HORIZ_MARGIN + x, VERT_MARGIN + (y + 1) * 18 - spacesize.height, 40, 18, c) @contents.draw_text(HORIZ_MARGIN + x, VERT_MARGIN + (y + @y_offset) * 18 - spacesize.height, 40, 18, c)
# Add x to drawn text width # Add x to drawn text width
x += @contents.text_size(c).width x += @contents.text_size(c).width
end end
@ -176,7 +200,6 @@ class Doc_Message
@viewport.visible = false @viewport.visible = false
$game_temp.message_window_showing = false $game_temp.message_window_showing = false
end end
return
end end
# Handle fade-in effect # Handle fade-in effect
@ -189,6 +212,23 @@ class Doc_Message
@fade_in = false @fade_in = false
$game_temp.message_window_showing = true $game_temp.message_window_showing = true
end end
end
# set the scroll indicators to the opacity of the bg,
# or 0 if they cannot scroll further
if @y_offset < 0
@sprite_scroll_up.opacity = @sprite_bg.opacity
else
@sprite_scroll_up.opacity = 0
end
if @y_offset > @scroll_limit
@sprite_scroll_down.opacity = @sprite_bg.opacity
else
@sprite_scroll_down.opacity = 0
end
# don't perform control actions while fading msg box
if @fade_in || @fade_out
return return
end end
@ -197,6 +237,14 @@ class Doc_Message
terminate_message terminate_message
@fade_out = true @fade_out = true
end end
if Input.trigger?(Input::UP) && @y_offset < 0
@y_offset += 1
refresh()
end
if Input.trigger?(Input::DOWN) && @y_offset > @scroll_limit
@y_offset -= 1
refresh()
end
end end
# Message is over and should be hidden or advanced to next # Message is over and should be hidden or advanced to next

View file

@ -32,6 +32,23 @@ end
module Wallpaper module Wallpaper
def self.set_persistent(name, color) def self.set_persistent(name, color)
if (name == 'save_w32')
case $persistent.langcode
when 'fr'
name = $persistent.langcode + "\\" + name
when 'pt_BR'
name = $persistent.langcode + "\\" + name
when 'es'
name = $persistent.langcode + "\\" + name
when 'ja'
name = $persistent.langcode + "\\" + name
when 'ko'
name = $persistent.langcode + "\\" + name
when 'zh_CN'
name = $persistent.langcode + "\\" + name
end
end
$game_oneshot.wallpaper = name $game_oneshot.wallpaper = name
$game_oneshot.wallpaper_color = color $game_oneshot.wallpaper_color = color
Wallpaper.set(name, color) Wallpaper.set(name, color)

View file

@ -11,7 +11,11 @@ class Interpreter
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def command_101 def command_101
# If other text has been set to message_text # If other text has been set to message_text
if $game_temp.message_text != nil || $game_temp.message_ed_text != nil || $game_temp.message_doc_text != nil || $game_temp.message_desktop_text != nil || $game_temp.message_credits_text != nil if $game_temp.message_text != nil ||
$game_temp.message_ed_text != nil ||
$game_temp.message_doc_text != nil ||
$game_temp.message_desktop_text != nil ||
$game_temp.message_credits_text != nil
# End # End
return false return false
end end

View file

@ -17,14 +17,134 @@ DOCUMENT_TEXT = \
DOCUMENT_POSTGAME_TEXT = "The code you need is " DOCUMENT_POSTGAME_TEXT = "The code you need is "
DOCUMENT_TEXT_ES = \
"Me agrada s̵̨a̴̕͠l̀͞u̵d͡a̵r̨̨̧te ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"Esta es̷̸͢ m̕͞͡i̕ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞ m͞͡e͜ǹs͜a̵j̕͜e̵͜ y me temo que ha de ser breve. \n"\
"Te hago entrega de un diario. Parte de él está escrito e҉n͟͏ ҉u͘͢n̡a l̀͢e͏͘͝n̷̷ģ͝ú͜҉a̷̛͏ ̢q̸͏u̵̕e̸ ̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"S͏҉͝i̸̡͘͟n̢͠ ̨́͜e̷m̸̶̴͡b́̕á̢r̛͢g̡̛͝o҉̀͟͏̡, ̷͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞n̕ ĺ̕͜ee̢͘ ͏͝y̵̵͟ ̶̛ sabrás qué hacer. \n"\
"También te he d͟͞e̸̴j̡a͝d̡̢͠o͡҉ u̶n͏͘ą̵̧ ̸͜má̧͘s̴c̨̛a̧r͜͠á̷̕ b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"B̶u̧şca ̧u҉n͘a ̸caj͟a̵ ̨f͡u̵e͘r̕t́e de͠ mètal̨ en̡ ͝l͏a ͝mi͝n͞a̶ ̴s͠i̡t̡úad̢a ̕al ęst͡e, ̶e̕n u͡n͟ ̀pu̡nt̢o̶ ͝e̶ntr͏e ͢el o̷céano y ̵e͟l m̢i̷ra͢d͞oŕ. \n\n"\
\
"He aquí el código: "
DOCUMENT_POSTGAME_TEXT_ES = "He aquí el código: "
DOCUMENT_TEXT_PT_BR = \
"Olá, ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"È̴̷̵͝s̕͠t͠͏͏a҉́̀̕̕ h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ ḿ̶e͘n̸͟s̵̢͞a̷̴͞g̷͟è͞m̵͝, e infelizmente preciso ser breve. \n"\
"Eu lhe deixei um diário, que contém partes escritas numa ĺ͡í̧͘͢ńg͏ua҉͠ ̴q̶u̵͠e y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞ —̨ ͞lei̧͜a͢͞-áş ͢e ̛͘͠você saberá o que fazer. \n"\
"Também lhe d̵͠ȩ̢ì̴xe͘i ̷̸ưm̀ą̸ ́͞má̵s҉͡c̸̨͟ą͠ŕa͟ b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"P̵r̡o͢cu̧r͞e͡ ͏u҉m͞ ͘cof̢re ͢de͠ ̛me̢tal na̶ pedrȩir͏a ą ҉les̷té,̴ ́e̴nt̡r̨e҉ o̕ ma͜r ę o̴ p͜on̡t́o̕ ̡de͘ o̵b̀s̴e͢r҉va̵ç̨ão̡.\n\n"\
\
"O código necessário é: "
DOCUMENT_POSTGAME_TEXT_PT_BR = "He aquí el código: "
DOCUMENT_TEXT_FR = \
"Bonjour ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"C̷͞'̡̨ȩ̀͜s̶̷̢̕t̶̸́҉ h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ ͟m͏ȩ͢͢s̴͡s̀͟҉a̵͡g͝e̸͡,̕͏̡ et j'ai bien peur de devoir être bref. \n"\
"Je vous ai laissé un carnet, en partie écrit dans u̢͏͡n͏͟ȩ ̧͜͝l҉͢àngu͝e͘ ҉̸q̕͞ue y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞ ̧͜͏L̢i̷̛se̢͏҉z͟͏-̨̕͞l͞à͜͏ ̴e̴͝t̕ ̀͝vous saurez quoi faire. \n"\
"Je vous ai aussi lai̴s̛̀̀s̢̡ȩ́̕ ͝͠ừn̛̛͠ ́͡m͜҉a̕͝s̸̶qu̴e̴̢̛,b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"Cher͞c̷he̴z un c͞o͜ff́r͞e-f̴or͟t͟ ̸en͏ ͝mé̛tal͏ ͟da̶nş ͟l͏a͠ ͝cąr͡r͠i̡èŗe à͞ l͘'͞e͜s̵t, ̷q͘uel̷q҉ue̴ ́part e͠ntre͞ ̡l'o̕c͠éań ̡et le̷ p̛os͏te ͡d̴'̕ob͟s͏er̀vat͜iòn͘.̡ ͝\n\n"\
\
"Le code nécessaire est : "
DOCUMENT_POSTGAME_TEXT_FR = "Le code nécessaire est : "
DOCUMENT_TEXT_JA = \
"親愛なる ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"君にメッセージをh̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ 手̛͜҉短̧͢に̷͏要̷̨件̧͘͜͢を̸̕͜͜͞説明しなければならない。\n"\
"1冊の日記を残̶̧́し̢͝͠た̴͘͠。̵̸̀̕ y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̕͏͏͢͞な̷̨̡͝言͠҉̡語͏҉で書かれている。\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞n̕読̵͏め̧͡ば̴̛̀͠成すべきことがわかるはずだ。\n"\
"他にマ̨̧̧ス̷́͟͜ク̧͏͏͏̛͘͞残̴̵し̧̀た́͡。̀͢҉҉b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"東͠に͡向か͜い͢、海と見͠晴し͜台̡と̡の間のど͘こかにあ̸る採石場̸で̛金͜庫͘を̶探̢すんだ̴。̸\n\n"\
\
"必要なコードは次の通りだ: "
DOCUMENT_POSTGAME_TEXT_JA = "必要なコードは次の通りだ: "
DOCUMENT_TEXT_KO = \
"안녕하십̴̵̢͟҉니̵́̕͢͞까̡́͡ ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"처̷̨̀́͞음̸̵̵̧҉h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ 간̨҉̶̡҉략̢̧하̸̷̡͠게҉̛͢͞ 써야 한다는 걱정이 앞서는군요.\n"\
"당신께 일지를 남겨두었습니다. 일̷̡̕͠지͢͜의҉̀͘͠ y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞.̶ą̶͟͞n̕ 읽́͟어͢͡҉보̕͢͞͞시̧̕͢면̷̡͠ 무엇을 해야 할지 알게 될 것입니다.\n"\
"그리고 마̴̴̨̡스̧͘̕̕͝크̡͝͠͝도͏̶̡̡́ ̶̷͘͟͞두҉̴͘었͞͠҉͠습̧̧̨̕͢니̸̧̀͢다̨͘͟,̵̷ b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"바̶다̧와̧ ͡초소͟ ́지́역͞ ͜사이́ 동͝쪽 ̴채͞석장에̸서͠ 금̡속 금̵고를̡ ̢찾아보십시오͟.̡\n\n"\
\
"필요한 코드는 다음과 같습니다. "
DOCUMENT_POSTGAME_TEXT_KO = "필요한 코드는 다음과 같습니다. "
DOCUMENT_TEXT_ZH_CN = \
"亲爱̷̷͟͝͡的̸̀̀ ̷̡̠͇̼͉̻̦͓́͜͡ ̶̤̦̯͖͚͓̮͓̣̤̰͇́̕ ̴͜͏͈̭̦͙̦̯̟̗̜̼̠̦͘ ̶̶̡̢̲̱̜̹̰̻̘̪̳̫͕̙̕ ̡҉͎̦̙̰̻͉̜̝̺͚̻͇̞̺̦͓́ ̨̘̤̜̞͍̩̠̱̦̫͔̹̩͍͇̜͈́̕͞ͅͅ ̴̴̧̣͍̘̰̗̮̜̰̲̣̙̲̝͚̩̦̭̀͡ ̧̗͚̱͓̥̖͍͕̀ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀ ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎́̀\n\n\n"\
\
\
"虽̸̛̀͡然̡́ ̨҉͟͞h̡͜͠҉ ̷̛i̵̶̷͝ ̵̀͢͢s͜ ͟͏̷̵̡ ̨͟͡ ͏ ̷i҉̷̧̀ ̴̡̕s͠ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙ ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥̦̱́ͅ ̫̪͇̗̲̭̤͖̫̣͇͔͘ ͕͚͎̦͓̺̤̳̙̝͟ͅ ̸͉̫̘̩͙͖̼̣̞̞̰̼̞͕̀T ̶̗͓͎͓̦̙̭̳̻̫̥̯̱͚̦͔͍͙͟ ̶͜҉͏̞̺̙̥̦̪͇̯̳͍̬̱̰̘̺̠̀ ̴̼̘͇͎͙̘̜̀̀͞ ̴̢̹̥͚͎̮͍̥̲̟͓̹̞̤̠͉̳̝̫́̀ͅ ̛̫͎̤̥̰̩̹̬͞ ͟҉̞̭̼̞̯̰͈̘̟̣̜̰͖͙̼͙̙A ̨̳͚͍̤̦̪͔̲̬̻̯͍͉̥́ͅu̦̱ ̵̸̹̼̞͚̹̟̺͎̜̖̦͠ ̴̢̳͔̻͕̮͇̱̀͡ͅͅ ̘̟̺̫̪̺͙̦̳̻͙̣̳́́͝͝ ̤͍͍̭͙̦̤͖͕̯͍̜́͜ͅr ̷̶̥̠͍͚͜͞.̴͜/͞m̵̧.̧̨̧́͘.̶͘͝͡-̡̢͟-̷̧͠͝͝-̴̨͜͢y͡҉̧/̀͏͏͘.͜͞.҉̡̀͢-̡̧̕͜-̸͘͜f̷̧͘͜.̨́͜.͞͞.̴̶͞ ,҉̴̛͠但̸̨̕恐̴̡͞怕́我̡只能简短地说明情况。\n"\
"我为你准备了一本日͏̛̀͢͞志̸̡͜҉̕但̶͟是̨͘͢͡͞y̴̴͝/͟͝͝/̧͝͡-҉̵̸͡-͏͡o͏͜͝/̶̡̡/͡/͏̵̵̵̀/͏́́ų̨̕͘ ͟҉̴ ̧͠͏͝ ͘̕͟͠͞w̛͘͟͡͠/̵̢͠/̷́͞͞/҉̸̛̀͡ļ̴̕͢͡l̢̛̕͘͜ ̵̀͝͠n͝o̵͢͠=̵̷̨̡͡.̷̴̷̡̡.̷̵͘͟t̶̶̸̡ ̷́͜u͏̴́/̀/̵̧͢͞͡ǹd̀͟͠è͢҉̢̢-͠҉-̧҉̢-̶̧-̷̶͘s̵̶̷̢͠t̡̛a̧ ̶̴̧͝ ̷̸̡ ̸́͞ ͢ ̶̸̡̛͞n̢͠d̸̵ ҉̢͠͠a̴͡͠t̛͏̀͟͠ ̨̢͢͝f̷̵/̵̢̡̢/̧̢҉̵/̨͟͝r͏-̕͟͟͠=̢̕͘͟s̵͟͏t͞͞͡\n"\
"H҉.̧̕.̸̵.̸̨̛̕͠-͘͜/̵͏҉/̸͘̕w̴͏͟e̷̢͜v̵͟͜͟(̢̕҉͟ę̸̀͜͞r̶̷͠͠҉ ̵̡͡ ̵̕͡͠ ҉̷ ̴̵̛͢,̧́҉ ͘͠͞ ͞͠ǫ̷̵̛̀n҉̡͡/̶̢/̵̸҉/̴̸̢́/̡͞/̀͘̕͢/̨͟c̵̷ ̨̛͘͡͞ ̨͏̛ ̷̶̡̧͜ ̵̨̀͜e̸̢͢͟ ̴͝y҉̸̛́/̵̵̶̨/̢͘/̴͟/͡=͢͏=̡͘=̷̢=҉̴̢/̸̧̧͞/̛̕/̶̨́͠/̶̨̧̕͜.̵.̴͝.̷̶͡u̧͝ ͘͘͜҉.̢̨̕͝͏ ̸̶̵̶̢ ̶̡ ̧̀c̀͢͞͞.͡.̴̶́͟͠.͞͏͘.̨̧͘͞.̴҉͞阅̸̨̛͝读҉͠͏̧́日̶̴志̵́͢后你就知道做怎么做了。\n"\
"同时我也为你̵̛́͏准̸̴̡̀备̧͞了̶̧̢́一̧̧̕幅̴͠͡面̶͘͝具̴̸̧͡b̷̢͘͞ ̛̀͘͢͝c̡͜҉ ̀͟͠ ̶̡͘͜ ͞҉͜͏ ̷͜͏ ̡́́͠ ̢ ̀͏ ̕͜ ̵̷͘ ̶̴̴̵ę̷̷͜ ̴̸҉̀Í͡ ̸͘͞ ̨͢͜͡͡ ́͢͏͢ ̢̡́́͞ ̷̶̸̀͝ ̸͠ ̶̷̧̀̀ ̵̵̵̢́ ̷̵̛͡ ̕͝ ̷̕͠҉̡ ̸k͟͞͝ǹ͠͏͡ ̶̸̶͢͠ ̨͟͞͡ ҉̶ ͟͏̸ ̢̕ ̴͡͠ ̴̕͡҉͢ ̴͟͟ ̶͞͠w҉͝ ̢̨͟ ̵̕ ̧̢͜͢ ̴̀̕͞ ̀͟͟͠ ̛͢͏ ̡̧̀̀ ̨̢͘ ̕͜y̢̨̛͘͟ǫ͡u҉͢͟͏͟ ̷̛̀ ̴̕͞ ̢͡ẃ̴̡͡͝ ͘͜͝͏ ̧̀͜͡ ̶͢ ̵̶̸̨ ̵ļ́͡͡҉ ̶̧ ̸͡͠͠ ̷͏̸̵͟ ̸̴̀̕͝ ̸͏̧̀͝ ́͢͠ ͏̧̡͟͝ ̡̕͢͟n̕̕̕ ̷̴͟͝͏ ̡̡͝ ́́ ͏͝͏͟ ͜͡͏̴̛e̷̸͏d̸̡͜ ̷́͜͝i̵̶̢̢̧t̴́.͜͢\n\n"\
\
"在͝采石̕场东边͢寻找̀一̶个͝金͠属保̢险箱̶,̕它就̀在海洋与侦́察哨̀之间。\n\n"\
\
"你所需要的代码:"
DOCUMENT_POSTGAME_TEXT_ZH_CN = "你所需要的代码:"
def safe_puzzle_write def safe_puzzle_write
doc_text = DOCUMENT_TEXT
case $persistent.langcode
when 'fr'
doc_text = DOCUMENT_TEXT_FR
when 'pt_BR'
doc_text = DOCUMENT_TEXT_PT_BR
when 'es'
doc_text = DOCUMENT_TEXT_ES
when 'ja'
doc_text = DOCUMENT_TEXT_JA
when 'ko'
doc_text = DOCUMENT_TEXT_KO
when 'zh_CN'
doc_text = DOCUMENT_TEXT_ZH_CN
end
File.open(Oneshot::DOCS_PATH + "/DOCUMENT.oneshot.txt", 'w') do |file| File.open(Oneshot::DOCS_PATH + "/DOCUMENT.oneshot.txt", 'w') do |file|
file.puts(DOCUMENT_TEXT + $game_variables[20].to_s) file.puts(doc_text + $game_variables[20].to_s)
end end
end end
def safe_puzzle_postgame_write def safe_puzzle_postgame_write
doc_text = DOCUMENT_POSTGAME_TEXT
case $persistent.langcode
when 'fr'
doc_text = DOCUMENT_POSTGAME_TEXT_FR
when 'pt_BR'
doc_text = DOCUMENT_POSTGAME_TEXT_PT_BR
when 'es'
doc_text = DOCUMENT_POSTGAME_TEXT_ES
when 'ja'
doc_text = DOCUMENT_POSTGAME_TEXT_JA
when 'ko'
doc_text = DOCUMENT_POSTGAME_TEXT_KO
when 'zh_CN'
doc_text = DOCUMENT_POSTGAME_TEXT_ZH_CN
end
File.open(Oneshot::DOCS_PATH + "/DOCUMENT.oneshot.txt", 'w') do |file| File.open(Oneshot::DOCS_PATH + "/DOCUMENT.oneshot.txt", 'w') do |file|
file.puts(DOCUMENT_POSTGAME_TEXT + $game_variables[20].to_s) file.puts(doc_text + $game_variables[20].to_s)
end end
end end

View file

@ -42,17 +42,3 @@ class Tone
self.red == 0 && self.green == 0 && self.blue == 0 && self.gray == 0 self.red == 0 && self.green == 0 && self.blue == 0 && self.gray == 0
end end
end end
module Graphics
class << self
alias_method :update_native, :update
def update
#if $game_map.map_id == 97
# Oneshot.allow_exit false
#elsif $game_system.map_interpreter
# Oneshot.allow_exit ($scene == nil)
#end
update_native
end
end
end

View file

@ -140,7 +140,7 @@ module Script
end end
return false return false
end end
def self.countdown_extend_over def self.countdown_extend_over
equinox = Time.new(2017, 03, 27) equinox = Time.new(2017, 03, 27)
diff = equinox - Time.now diff = equinox - Time.now
@ -149,7 +149,7 @@ module Script
end end
return false return false
end end
def self.cdown_update(equinox) def self.cdown_update(equinox)
diff = equinox - Time.now diff = equinox - Time.now
if(diff < 0) if(diff < 0)
@ -217,7 +217,7 @@ module Script
def self.countdown_update def self.countdown_update
return cdown_update(Time.new(2017, 03, 27)) return cdown_update(Time.new(2017, 03, 27))
end end
def self.countdown_extend_update def self.countdown_extend_update
return cdown_update(Time.new(2017, 03, 27)) return cdown_update(Time.new(2017, 03, 27))
end end
@ -254,7 +254,7 @@ module Script
end end
end end
end end
def self.niko_reflection_enc_update def self.niko_reflection_enc_update
for event in $game_map.events.values for event in $game_map.events.values
if event.name == "niko reflection" if event.name == "niko reflection"
@ -268,7 +268,7 @@ module Script
if event.real_y > 19*128 if event.real_y > 19*128
event.real_y = 19*128 event.real_y = 19*128
end end
if event.x > 14 if event.x > 14
event.x = 14 event.x = 14
elsif event.x < 6 elsif event.x < 6
@ -279,7 +279,7 @@ module Script
elsif event.real_x < (6*128) + 32 elsif event.real_x < (6*128) + 32
event.real_x = (6*128) + 32 event.real_x = (6*128) + 32
end end
event.direction = $game_player.direction event.direction = $game_player.direction
event.pattern = $game_player.pattern event.pattern = $game_player.pattern
case event.direction case event.direction
@ -292,8 +292,8 @@ module Script
end end
end end
end end
def self.niko_reflection_peng_update def self.niko_reflection_peng_update
for event in $game_map.events.values for event in $game_map.events.values
if event.name == "niko reflection" if event.name == "niko reflection"
@ -307,7 +307,7 @@ module Script
if event.real_y > 19*128 if event.real_y > 19*128
event.real_y = 19*128 event.real_y = 19*128
end end
if event.x > 14 if event.x > 14
event.x = 14 event.x = 14
elsif event.x < 6 elsif event.x < 6
@ -318,7 +318,7 @@ module Script
elsif event.real_x < (6*128) + 32 elsif event.real_x < (6*128) + 32
event.real_x = (6*128) + 32 event.real_x = (6*128) + 32
end end
return return
end end
end end
@ -373,11 +373,11 @@ module Script
end end
def self.copy_journal def self.copy_journal
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games") unless File.exists?(Oneshot::DOCS_PATH + "/My Games")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot")
begin begin
File.open("_______.exe", "rb") do |input| File.open("_______.exe", "rb") do |input|
File.open(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\_______.exe","wb") do |output| File.open(Oneshot::DOCS_PATH + "/My Games/Oneshot/_______.exe","wb") do |output|
while buff = input.read(4096) while buff = input.read(4096)
output.write(buff) output.write(buff)
end end
@ -388,7 +388,7 @@ module Script
end end
if File.exists?("README.txt") if File.exists?("README.txt")
File.open("README.txt", "rb") do |input| File.open("README.txt", "rb") do |input|
File.open(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\README.txt","wb") do |output| File.open(Oneshot::DOCS_PATH + "/My Games/Oneshot/README.txt","wb") do |output|
while buff = input.read(4096) while buff = input.read(4096)
output.write(buff) output.write(buff)
end end
@ -396,43 +396,43 @@ module Script
end end
end end
end end
def self.create_boxes def self.create_boxes
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games") unless File.exists?(Oneshot::DOCS_PATH + "/My Games")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal1") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal1") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal1") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal1")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal2") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal2") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal2") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal2")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal3") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal3") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal3") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal3")
Dir.mkdir(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal") unless File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal") Dir.mkdir(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal") unless File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal")
end end
def self.delete_if_exists(f_name) def self.delete_if_exists(f_name)
File.delete(f_name) unless !File.exists?(f_name) File.delete(f_name) unless !File.exists?(f_name)
end end
def self.clear_boxes def self.clear_boxes
for i in 1..3 for i in 1..3
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal" + i.to_s portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal" + i.to_s
case i case i
when 1 when 1
delete_if_exists(portal_path + "\\blue_npc_prototype.png") delete_if_exists(portal_path + "/blue_npc_prototype.png")
delete_if_exists(portal_path + "\\proto1.png") delete_if_exists(portal_path + "/proto1.png")
delete_if_exists(portal_path + "\\keyB.txt") delete_if_exists(portal_path + "/keyB.txt")
when 2 when 2
delete_if_exists(portal_path + "\\green_npc_cedric.png") delete_if_exists(portal_path + "/green_npc_cedric.png")
delete_if_exists(portal_path + "\\cedric.png") delete_if_exists(portal_path + "/cedric.png")
delete_if_exists(portal_path + "\\keyG.txt") delete_if_exists(portal_path + "/keyG.txt")
when 3 when 3
delete_if_exists(portal_path + "\\red_rue.png") delete_if_exists(portal_path + "/red_rue.png")
delete_if_exists(portal_path + "\\rue.png") delete_if_exists(portal_path + "/rue.png")
delete_if_exists(portal_path + "\\keyR.txt") delete_if_exists(portal_path + "/keyR.txt")
end end
end end
delete_if_exists(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal\\keyB.txt") delete_if_exists(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal/keyB.txt")
delete_if_exists(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal\\keyG.txt") delete_if_exists(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal/keyG.txt")
delete_if_exists(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal\\keyR.txt") delete_if_exists(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal/keyR.txt")
end end
def self.copy_file(src, dst) def self.copy_file(src, dst)
begin begin
File.open(src, "rb") do |input| File.open(src, "rb") do |input|
@ -446,79 +446,89 @@ module Script
#this probably means the file already exists and is open, so no need to create it again #this probably means the file already exists and is open, so no need to create it again
end end
end end
def self.write_key(dst, str) def self.write_key(dst, str)
File.open(dst, 'w') do |file| File.open(dst, 'w') do |file|
file.puts(str) file.puts(str)
end end
end end
def self.put_key_in_box(numb) def self.put_key_in_box(numb)
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal" + numb.to_s portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal" + numb.to_s
case numb case numb
when 1 when 1
copy_file("Graphics\\Characters\\blue_npc_prototype.png", portal_path + "\\blue_npc_prototype.png") copy_file("Graphics/Characters/blue_npc_prototype.png", portal_path + "/blue_npc_prototype.png")
copy_file("Graphics\\Faces\\proto1.png", portal_path + "\\proto1.png") copy_file("Graphics/Faces/proto1.png", portal_path + "/proto1.png")
write_key(portal_path + "\\keyB.txt", PROTO_TEXT) write_key(portal_path + "/keyB.txt", PROTO_TEXT)
when 2 when 2
copy_file("Graphics\\Characters\\green_npc_cedric.png", portal_path + "\\green_npc_cedric.png") copy_file("Graphics/Characters/green_npc_cedric.png", portal_path + "/green_npc_cedric.png")
copy_file("Graphics\\Faces\\cedric.png", portal_path + "\\cedric.png") copy_file("Graphics/Faces/cedric.png", portal_path + "/cedric.png")
write_key(portal_path + "\\keyG.txt", CEDRIC_TEXT) write_key(portal_path + "/keyG.txt", CEDRIC_TEXT)
when 3 when 3
copy_file("Graphics\\Characters\\red_rue.png", portal_path + "\\red_rue.png") copy_file("Graphics/Characters/red_rue.png", portal_path + "/red_rue.png")
copy_file("Graphics\\Faces\\rue.png", portal_path + "\\rue.png") copy_file("Graphics/Faces/rue.png", portal_path + "/rue.png")
write_key(portal_path + "\\keyR.txt", RUE_TEXT) write_key(portal_path + "/keyR.txt", RUE_TEXT)
end end
end end
def self.password1 def self.password1
copy_file("Graphics\\Fogs\\_\\scenario1\\pw1.png", Oneshot::DOCS_PATH + "\\ONESHOT_password1.png") locale = $persistent.langcode
copy_file("Graphics\\Fogs\\_\\scenario1\\pw2.png", Oneshot::DOCS_PATH + "\\ONESHOT_password2.png") if !Language::LANGUAGES.include? locale
copy_file("Graphics\\Fogs\\_\\scenario1\\pw3.png", Oneshot::DOCS_PATH + "\\ONESHOT_password3.png") locale = 'en'
copy_file("Graphics\\Fogs\\_\\scenario1\\pw4.png", Oneshot::DOCS_PATH + "\\ONESHOT_password4.png") end
source_dir = "Graphics/Fogs/_/scenario1/" + locale.downcase
copy_file(source_dir + "/pw1.png", Oneshot::DOCS_PATH + "/ONESHOT_password1.png")
copy_file(source_dir + "/pw2.png", Oneshot::DOCS_PATH + "/ONESHOT_password2.png")
copy_file(source_dir + "/pw3.png", Oneshot::DOCS_PATH + "/ONESHOT_password3.png")
copy_file(source_dir + "/pw4.png", Oneshot::DOCS_PATH + "/ONESHOT_password4.png")
end end
def self.password2 def self.password2
copy_file("Graphics\\Fogs\\_\\scenario2\\pw1.png", Oneshot::DOCS_PATH + "\\ONESHOT_password1.png") locale = $persistent.langcode
copy_file("Graphics\\Fogs\\_\\scenario2\\pw2.png", Oneshot::DOCS_PATH + "\\ONESHOT_password2.png") if !Language::LANGUAGES.include? locale
copy_file("Graphics\\Fogs\\_\\scenario2\\pw3.png", Oneshot::DOCS_PATH + "\\ONESHOT_password3.png") locale = 'en'
copy_file("Graphics\\Fogs\\_\\scenario2\\pw4.png", Oneshot::DOCS_PATH + "\\ONESHOT_password4.png") end
source_dir = "Graphics/Fogs/_/scenario2/" + locale.downcase
copy_file(source_dir + "/pw1.png", Oneshot::DOCS_PATH + "/ONESHOT_password1.png")
copy_file(source_dir + "/pw2.png", Oneshot::DOCS_PATH + "/ONESHOT_password2.png")
copy_file(source_dir + "/pw3.png", Oneshot::DOCS_PATH + "/ONESHOT_password3.png")
copy_file(source_dir + "/pw4.png", Oneshot::DOCS_PATH + "/ONESHOT_password4.png")
end end
=begin =begin
def self.take_key_out_of_box(numb) def self.take_key_out_of_box(numb)
if File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Box" + numb.to_s + "\\key" + numb.to_s + ".png") if File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/Box" + numb.to_s + "/key" + numb.to_s + ".png")
File.delete(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Box" + numb.to_s + "\\key" + numb.to_s + ".png") File.delete(Oneshot::DOCS_PATH + "/My Games/Oneshot/Box" + numb.to_s + "/key" + numb.to_s + ".png")
end end
if File.exists?(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigBox\\key" + numb.to_s + ".png") if File.exists?(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigBox/key" + numb.to_s + ".png")
File.delete(Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigBox\\key" + numb.to_s + ".png") File.delete(Oneshot::DOCS_PATH + "/My Games/Oneshot/BigBox/key" + numb.to_s + ".png")
end end
end end
=end =end
def self.is_key_in_box(numb) def self.is_key_in_box(numb)
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\Portal" + numb.to_s portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/Portal" + numb.to_s
case numb case numb
when 1 when 1
return File.exists?(portal_path + "\\keyB.txt") return File.exists?(portal_path + "/keyB.txt")
when 2 when 2
return File.exists?(portal_path + "\\keyG.txt") return File.exists?(portal_path + "/keyG.txt")
when 3 when 3
return File.exists?(portal_path + "\\keyR.txt") return File.exists?(portal_path + "/keyR.txt")
end end
return false return false
end end
def self.is_key_in_bigbox(numb) def self.is_key_in_bigbox(numb)
portal_path = Oneshot::DOCS_PATH + "\\My Games\\Oneshot\\BigPortal" portal_path = Oneshot::DOCS_PATH + "/My Games/Oneshot/BigPortal"
case numb case numb
when 1 when 1
return File.exists?(portal_path + "\\keyB.txt") return File.exists?(portal_path + "/keyB.txt")
when 2 when 2
return File.exists?(portal_path + "\\keyG.txt") return File.exists?(portal_path + "/keyG.txt")
when 3 when 3
return File.exists?(portal_path + "\\keyR.txt") return File.exists?(portal_path + "/keyR.txt")
end end
return false return false
end end
@ -559,10 +569,10 @@ def check_exit(min, max, x: -1, y: -1)
end end
def loadQASave(fname) def loadQASave(fname)
filename = "testing_saves/" + fname + ".rxdata" filename = "testing_saves/" + fname + ".rxdata"
# If file doesn't exist # If file doesn't exist
unless FileTest.exist?(filename) unless FileTest.exist?(filename)
filename = "testing_saves_postgame/" + fname + ".rxdata" filename = "testing_saves_postgame/" + fname + ".rxdata"
unless FileTest.exist?(filename) unless FileTest.exist?(filename)
# Play buzzer SE # Play buzzer SE
$game_system.se_play($data_system.buzzer_se) $game_system.se_play($data_system.buzzer_se)
@ -571,7 +581,7 @@ def loadQASave(fname)
end end
# Play load SE # Play load SE
$game_system.se_play($data_system.load_se) $game_system.se_play($data_system.load_se)
# Read save data # Read save data
file = File.open(filename, "rb") file = File.open(filename, "rb")
# Read character data for drawing save file # Read character data for drawing save file

View file

@ -7,9 +7,14 @@ class Sprite_MapText < Sprite
@real_x = x * 4 * 32 @real_x = x * 4 * 32
@real_y = y * 4 * 32 @real_y = y * 4 * 32
self.zoom_x = 2
self.zoom_y = 2
self.bitmap = Bitmap.new(200, 24) self.bitmap = Bitmap.new(200, 24)
if (Language::FONT_WESTERN == Font.default_name)
self.zoom_x = 2
self.zoom_y = 2
else
self.zoom_x = 1.5
self.zoom_y = 1.5
end
#calculate text width #calculate text width
spacewidth = self.bitmap.text_size(' ').width spacewidth = self.bitmap.text_size(' ').width

View file

@ -1,4 +1,4 @@
Font.default_name = Language::FONT_CJK Font.default_name = Language::FONT_J
class Language class Language
def self.create_input def self.create_input

View file

@ -7,14 +7,18 @@
class Language class Language
FONT_WESTERN = 'Terminus (TTF)' FONT_WESTERN = 'Terminus (TTF)'
FONT_CJK = 'WenQuanYi Micro Hei' FONT_CK = 'WenQuanYi Micro Hei'
FONT_J = 'HigashiOme Gothic regular'
LANG_WESTERN = [ LANG_WESTERN = [
'en', 'fr', 'pt_BR', 'es' 'en', 'fr', 'pt_BR', 'es'
] ]
LANG_CJK = [ LANG_J = [
'ja', 'ko', 'zh_CN' 'ja'
] ]
LANGUAGES = LANG_WESTERN + LANG_CJK LANG_CK = [
'ko', 'zh_CN'
]
LANGUAGES = LANG_WESTERN + LANG_CK + LANG_J
class << self class << self
def set(lc) def set(lc)
@ -28,12 +32,15 @@ class Language
if FileTest.exist?(path) if FileTest.exist?(path)
File.open(path, "rb") do |file| File.open(path, "rb") do |file|
@data = Marshal.load(file) @data = Marshal.load(file)
if LANG_CJK.include? name if LANG_CK.include? name
Font.default_name = FONT_CJK Font.default_name = FONT_CK
elsif LANG_J.include? name
Font.default_name = FONT_J
else else
Font.default_name = FONT_WESTERN Font.default_name = FONT_WESTERN
end end
Journal.setLang(name) Journal.setLang(name)
dbg_print(Font.default_name)
end end
end end
end end
@ -44,14 +51,13 @@ class Language
# 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(caller_locations(1, 1).first.tap{|loc| puts "#{loc.path}:#{loc.lineno}"})
dbg_print(string)
if @data if @data
rv = @data[Zlib::crc32(string)] || string rv = @data[Zlib::crc32(string)] || string
else else
rv = string rv = string
end end
dbg_print(rv) dbg_print(string + " -> " + rv)
return rv return String.new(rv)
end end
# Turn all database items into translatable strings # Turn all database items into translatable strings

86
src/i18n.cpp Normal file
View file

@ -0,0 +1,86 @@
/*
Really hacked-together naiive implementation of gettext
*/
#include "i18n.h"
#include "debugwriter.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const char* LOC_HEADER = "ONELOC\x10";
char** strdict = 0;
unsigned int nStr = 0;
int family = LOCALE_FAMILY_LATIN;
int getLocaleFamily() {
Debug() << "Get family:" << family;
return family;
}
const char* findtext(unsigned int msgid, const char* fallback) {
Debug() << "Looking for msg" << msgid << fallback;
if (msgid >= nStr) {
return fallback;
} else {
Debug() << "found" << strdict[msgid];
return strdict[msgid];
}
}
void unloadLocale() {
for (unsigned int i = 0; i < nStr; i++) {
free(strdict[i]);
}
free(strdict);
strdict = 0;
nStr = 0;
}
void _setLocaleFamily(const char* locale) {
if (!strcmp(locale, "ja")
|| !strcmp(locale, "ko")
|| !strcmp(locale, "zh_CN")) {
family = LOCALE_FAMILY_ASIAN;
} else {
family = LOCALE_FAMILY_LATIN;
}
}
void loadLocale(const char* locale) {
Debug() << "Load locale:" << locale;
char pathbuf[100];
FILE* locfile;
char header[8];
unsigned int i;
int strSize = 0;
unloadLocale();
_setLocaleFamily(locale);
sprintf(pathbuf, "Languages/internal/%s.loc", locale);
locfile = fopen(pathbuf, "rb");
if (locfile) {
fread(header, 1, 8, locfile);
if (!strcmp(header, LOC_HEADER)) {
//read number of strs in this file
fread(&nStr, 4, 1, locfile);
strdict = (char**)malloc(sizeof(char*) * nStr);
for (i = 0; i < nStr; i++) {
//read the size of the next string
fread(&strSize, 4, 1, locfile);
strdict[i] = (char*)malloc(strSize+1);
if (strSize > 0) {
//read the contents of the next string
fread(strdict[i], 1, strSize, locfile);
strdict[i][strSize] = 0;
Debug() << "localization #" << i << " : " << strdict[i] << "|" << strSize;
}
strdict[i][strSize] = 0;
}
}
fclose(locfile);
}
}

14
src/i18n.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef I18N_H
#define I18N_H
#include "trstr.h"
void unloadLocale();
void loadLocale(const char* locale);
const char* findtext(unsigned int msgid, const char* fallback);
int getLocaleFamily();
#define LOCALE_FAMILY_LATIN 1
#define LOCALE_FAMILY_ASIAN 2
#endif /* end of include guard: I18N_H */

View file

@ -37,6 +37,7 @@
#include "debugwriter.h" #include "debugwriter.h"
#include "exception.h" #include "exception.h"
#include "gl-fun.h" #include "gl-fun.h"
#include "i18n.h"
#include "binding.h" #include "binding.h"
@ -359,6 +360,8 @@ int main(int argc, char *argv[])
Debug() << "Shutting down."; Debug() << "Shutting down.";
unloadLocale();
alcCloseDevice(alcDev); alcCloseDevice(alcDev);
SDL_DestroyWindow(win); SDL_DestroyWindow(win);

View file

@ -34,6 +34,9 @@
#include "etc-internal.h" #include "etc-internal.h"
#include "util.h" #include "util.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "i18n.h"
#include "debugwriter.h"
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
@ -45,8 +48,11 @@ const uint8_t cBgDark = 20;
const uint8_t cLine = 0; const uint8_t cLine = 0;
const uint8_t cText = 255; const uint8_t cText = 255;
const char *const fontFamily = "Terminus (TTF)"; // const char *const fontFamilyLatin = "Terminus (TTF)";
const uint8_t fontSize = 12; const char *const fontFamilyLatin = "WenQuanYi Micro Hei";
const uint8_t fontSizeLatin = 12;
const char *const fontFamilyAsian = "WenQuanYi Micro Hei";
const uint8_t fontSizeAsian = 16;
static bool pointInRect(const SDL_Rect &r, int x, int y) static bool pointInRect(const SDL_Rect &r, int x, int y)
{ {
@ -55,51 +61,86 @@ static bool pointInRect(const SDL_Rect &r, int x, int y)
typedef SettingsMenuPrivate SMP; typedef SettingsMenuPrivate SMP;
#define BTN_STRING(btn) { Input:: btn, #btn } #define BTN_STRING(btn, id) { Input:: btn, id, #btn }
struct VButton struct VButton
{ {
Input::ButtonCode code; Input::ButtonCode code;
int trstrId;
const char *str; const char *str;
} static const vButtons[] = } static const vButtons[] =
{ {
BTN_STRING(Up), BTN_STRING(Up, TRSTR_KEYBIND_UP),
BTN_STRING(Left), BTN_STRING(Left, TRSTR_KEYBIND_LEFT),
BTN_STRING(Action), BTN_STRING(Action, TRSTR_KEYBIND_ACTION),
BTN_STRING(Cancel), BTN_STRING(Cancel, TRSTR_KEYBIND_CANCEL),
BTN_STRING(Menu), BTN_STRING(Menu, TRSTR_KEYBIND_MENU),
BTN_STRING(L), BTN_STRING(L, TRSTR_KEYBIND_L),
BTN_STRING(Down), BTN_STRING(Down, TRSTR_KEYBIND_DOWN),
BTN_STRING(Right), BTN_STRING(Right, TRSTR_KEYBIND_RIGHT),
BTN_STRING(Run), BTN_STRING(Run, TRSTR_KEYBIND_RUN),
BTN_STRING(Deactivate), BTN_STRING(Deactivate, TRSTR_KEYBIND_DEACTIVATE),
BTN_STRING(Items), BTN_STRING(Items, TRSTR_KEYBIND_ITEMS),
BTN_STRING(R), BTN_STRING(R, TRSTR_KEYBIND_R),
}; };
static elementsN(vButtons); static elementsN(vButtons);
const char* getButtonName(int buttonId) {
switch (buttonId) {
case 0:
return findtext(TRSTR_KEYBIND_A, "A Button");
break;
case 1:
return findtext(TRSTR_KEYBIND_B, "B Button");
break;
case 2:
return findtext(TRSTR_KEYBIND_X, "X Button");
break;
case 3:
return findtext(TRSTR_KEYBIND_Y, "Y Button");
break;
case 4:
return findtext(TRSTR_KEYBIND_BACK, "Back Button");
break;
case 5:
return findtext(TRSTR_KEYBIND_GUIDE, "Guide Button");
break;
case 6:
return findtext(TRSTR_KEYBIND_START, "Start Button");
break;
case 7:
return findtext(TRSTR_KEYBIND_LSTICK, "Left Stick");
break;
case 8:
return findtext(TRSTR_KEYBIND_RSTICK, "Right Stick");
break;
case 9:
return findtext(TRSTR_KEYBIND_LSHOULDER, "Left Shoulder");
break;
case 10:
return findtext(TRSTR_KEYBIND_RSHOULDER, "Right Shoulder");
break;
case 11:
return findtext(TRSTR_KEYBIND_PADU, "D-Pad (Up)");
break;
case 12:
return findtext(TRSTR_KEYBIND_PADD, "D-Pad (Down)");
break;
case 13:
return findtext(TRSTR_KEYBIND_PADL, "D-Pad (Left)");
break;
case 14:
return findtext(TRSTR_KEYBIND_PADR, "D-Pad (Right)");
break;
default:
return findtext(TRSTR_KEYBIND_UNK, "Unknown key");
}
}
/* Human readable string representation */ /* Human readable string representation */
std::string sourceDescString(const SourceDesc &src) std::string sourceDescString(const SourceDesc &src)
{ {
static const char *const gcButtonNames[SDL_CONTROLLER_BUTTON_MAX] = {
"A Button",
"B Button",
"X Button",
"Y Button",
"Back Button",
"Guide Button",
"Start Button",
"Left Stick",
"Right Stick",
"Left Shoulder",
"Right Shoulder",
"D-Pad (Up)",
"D-Pad (Down)",
"D-Pad (Left)",
"D-Pad (Right)",
};
char buf[128]; char buf[128];
char pos; char pos;
@ -111,52 +152,55 @@ std::string sourceDescString(const SourceDesc &src)
case Key: case Key:
{ {
if (src.d.scan == SDL_SCANCODE_LSHIFT) if (src.d.scan == SDL_SCANCODE_LSHIFT)
return "Shift"; return findtext(TRSTR_KEYBIND_SHIFT, "Shift");
SDL_Keycode key = SDL_GetKeyFromScancode(src.d.scan); SDL_Keycode key = SDL_GetKeyFromScancode(src.d.scan);
const char *str = SDL_GetKeyName(key); const char *str = SDL_GetKeyName(key);
if (*str == '\0') if (*str == '\0') {
return "Unknown key"; return findtext(TRSTR_KEYBIND_UNK, "Unknown key");
else } else {
return std::string(str) + " Key"; snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_KEYFMT, "%s Key"), str);
return buf;
}
} }
case CButton: case CButton:
snprintf(buf, sizeof(buf), "%s", gcButtonNames[src.d.jb]); snprintf(buf, sizeof(buf), "%s", getButtonName(src.d.jb));
return buf; return buf;
case CAxis: case CAxis:
switch (src.d.ja.axis) { switch (src.d.ja.axis) {
case SDL_CONTROLLER_AXIS_LEFTX: case SDL_CONTROLLER_AXIS_LEFTX:
if (src.d.ja.dir == Negative) if (src.d.ja.dir == Negative)
return "Left Stick (Left)"; return findtext(TRSTR_KEYBIND_LSTICKL, "Left Stick (Left)");
else else
return "Left Stick (Right)"; return findtext(TRSTR_KEYBIND_LSTICKR, "Left Stick (Right)");
case SDL_CONTROLLER_AXIS_LEFTY: case SDL_CONTROLLER_AXIS_LEFTY:
if (src.d.ja.dir == Negative) if (src.d.ja.dir == Negative)
return "Left Stick (Up)"; return findtext(TRSTR_KEYBIND_LSTICKU, "Left Stick (Up)");
else else
return "Left Stick (Down)"; return findtext(TRSTR_KEYBIND_LSTICKD, "Left Stick (Down)");
case SDL_CONTROLLER_AXIS_RIGHTX: case SDL_CONTROLLER_AXIS_RIGHTX:
if (src.d.ja.dir == Negative) if (src.d.ja.dir == Negative)
return "Right Stick (Left)"; return findtext(TRSTR_KEYBIND_RSTICKL, "Right Stick (Left)");
else else
return "Right Stick (Right)"; return findtext(TRSTR_KEYBIND_RSTICKR, "Right Stick (Right)");
case SDL_CONTROLLER_AXIS_RIGHTY: case SDL_CONTROLLER_AXIS_RIGHTY:
if (src.d.ja.dir == Negative) if (src.d.ja.dir == Negative)
return "Right Stick (Up)"; return findtext(TRSTR_KEYBIND_RSTICKU, "Right Stick (Up)");
else else
return "Right Stick (Down)"; return findtext(TRSTR_KEYBIND_RSTICKD, "Right Stick (Down)");
case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
return "Left Trigger"; return findtext(TRSTR_KEYBIND_LTRIGGER, "Left Trigger");
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
return "Right Trigger"; return findtext(TRSTR_KEYBIND_RTRIGGER, "Right Trigger");
} }
return ""; return "";
case JButton: case JButton:
snprintf(buf, sizeof(buf), "Joy Button %d", src.d.jb); snprintf(buf, sizeof(buf),
findtext(TRSTR_KEYBIND_JOYBTTNFMT, "Joy Button %d"), src.d.jb);
return buf; return buf;
case JHat: case JHat:
@ -181,12 +225,12 @@ std::string sourceDescString(const SourceDesc &src)
default: default:
pos = '-'; pos = '-';
} }
snprintf(buf, sizeof(buf), "Joy Hat %d:%c", snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_JOYHATFMT, "Joy Hat %d:%c"),
src.d.jh.hat, pos); src.d.jh.hat, pos);
return buf; return buf;
case JAxis: case JAxis:
snprintf(buf, sizeof(buf), "Joy Axis %d%c", snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_JOYAXISFMT, "Joy Axis %d%c"),
src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+'); src.d.ja.axis, src.d.ja.dir == Negative ? '-' : '+');
return buf; return buf;
} }
@ -495,9 +539,12 @@ struct SettingsMenuPrivate
int x, int y, int alignW, int x, int y, int alignW,
Justification just, SDL_Color c, bool bold = false) Justification just, SDL_Color c, bool bold = false)
{ {
Debug() << "draw text:" << str;
SDL_Surface *txt = createTextSurface(str, c, bold); SDL_Surface *txt = createTextSurface(str, c, bold);
blitTextSurf(surf, x, y, alignW, txt, just); if (txt) {
SDL_FreeSurface(txt); blitTextSurf(surf, x, y, alignW, txt, just);
SDL_FreeSurface(txt);
}
} }
void drawText(SDL_Surface *surf, const char *str, void drawText(SDL_Surface *surf, const char *str,
@ -586,7 +633,9 @@ struct SettingsMenuPrivate
if (state == AwaitingInput) if (state == AwaitingInput)
{ {
char buf[64]; char buf[64];
snprintf(buf, sizeof(buf), "Press key or joystick button for \"%s\"", captureName); snprintf(buf, sizeof(buf), findtext(TRSTR_KEYBIND_KEYPROMPT,
"Press key or joystick button for \"%s\""),
captureName);
drawOff = Vec2i(); drawOff = Vec2i();
@ -871,7 +920,7 @@ void BindingWidget::drawHandler(SDL_Surface *surf)
p->strokeRectInner(surf, cLine, 0, 0, rect.w, rect.h, 2); p->strokeRectInner(surf, cLine, 0, 0, rect.w, rect.h, 2);
/* Virtual button name */ /* Virtual button name */
p->drawText(surf, vb.str, 1, rect.h/2, cellOffX, Center, true); p->drawText(surf, findtext(vb.trstrId, vb.str), 1, rect.h/2, cellOffX, Center, true);
/* Cell frames */ /* Cell frames */
p->strokeLineV(surf, cLine, cellOffX, 0, rect.h, 2); p->strokeLineV(surf, cLine, cellOffX, 0, rect.h, 2);
@ -1027,13 +1076,18 @@ SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
p->hasFocus = false; p->hasFocus = false;
p->destroyReq = false; p->destroyReq = false;
p->window = SDL_CreateWindow("Key bindings", p->window = SDL_CreateWindow(findtext(TRSTR_KEYBIND_TITLE, "Key bindings"),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
winSize.x, winSize.y, SDL_WINDOW_INPUT_FOCUS); winSize.x, winSize.y, SDL_WINDOW_INPUT_FOCUS);
p->winSurf = SDL_GetWindowSurface(p->window); p->winSurf = SDL_GetWindowSurface(p->window);
p->winID = SDL_GetWindowID(p->window); p->winID = SDL_GetWindowID(p->window);
p->font = shState->fontState().getFont(fontFamily, fontSize); if (getLocaleFamily() == LOCALE_FAMILY_ASIAN) {
p->font = shState->fontState().getFont(fontFamilyAsian, fontSizeAsian);
} else {
p->font = shState->fontState().getFont(fontFamilyLatin, fontSizeLatin);
}
p->rgb = p->winSurf->format; p->rgb = p->winSurf->format;
@ -1067,24 +1121,24 @@ SettingsMenu::SettingsMenu(RGSSThreadData &rtData)
IntRect btRects[] = IntRect btRects[] =
{ {
IntRect(16, buttonY, 112, buttonH), IntRect(16, buttonY, 220, buttonH),
IntRect(winSize.x-16-64*2-8, buttonY, 64, buttonH), IntRect(winSize.x-16-80*2-8, buttonY, 80, buttonH),
IntRect(winSize.x-16-64, buttonY, 64, buttonH) IntRect(winSize.x-16-80, buttonY, 80, buttonH)
}; };
p->buttons.push_back(Button(p, btRects[0], "Reset defaults", &SMP::onResetToDefault)); p->buttons.push_back(Button(p, btRects[0], findtext(TRSTR_KEYBIND_RESET, "Reset defaults"), &SMP::onResetToDefault));
p->buttons.push_back(Button(p, btRects[1], "Cancel", &SMP::onCancel)); p->buttons.push_back(Button(p, btRects[1], findtext(TRSTR_CANCEL, "Cancel"), &SMP::onCancel));
p->buttons.push_back(Button(p, btRects[2], "Accept", &SMP::onAccept)); p->buttons.push_back(Button(p, btRects[2], findtext(TRSTR_ACCEPT, "Accept"), &SMP::onAccept));
for (size_t i = 0; i< p->buttons.size(); ++i) for (size_t i = 0; i< p->buttons.size(); ++i)
p->widgets.push_back(&p->buttons[i]); p->widgets.push_back(&p->buttons[i]);
/* Labels */ /* Labels */
const char *info = "Use left click to bind a slot, right click to clear its binding"; const char *info = findtext(TRSTR_KEYBIND_INSTRUCT, "Use left click to bind a slot, right click to clear its binding");
p->infoLabel = Label(p, IntRect(16, 16, winSize.x, 16), info, cText, cText, cText); p->infoLabel = Label(p, IntRect(16, 16, winSize.x - 32, 16), info, cText, cText, cText);
const char *warn = "Warning: Same physical action bound to multiple slots"; const char *warn = findtext(TRSTR_KEYBIND_CONFLICT, "Warning: Same physical action bound to multiple slots");
p->dupWarnLabel = Label(p, IntRect(16, 40, winSize.x, 16), warn, 255, 0, 0); p->dupWarnLabel = Label(p, IntRect(16, 40, winSize.x - 32, 16), warn, 255, 0, 0);
p->widgets.push_back(&p->infoLabel); p->widgets.push_back(&p->infoLabel);
p->widgets.push_back(&p->dupWarnLabel); p->widgets.push_back(&p->dupWarnLabel);

52
src/trstr.h Normal file
View file

@ -0,0 +1,52 @@
#define TRSTR_EMPTY 0
#define TRSTR_JOURNAL_TITLE 1
#define TRSTR_KEYBIND_A 2
#define TRSTR_KEYBIND_B 3
#define TRSTR_KEYBIND_X 4
#define TRSTR_KEYBIND_Y 5
#define TRSTR_KEYBIND_BACK 6
#define TRSTR_KEYBIND_GUIDE 7
#define TRSTR_KEYBIND_START 8
#define TRSTR_KEYBIND_LSTICK 9
#define TRSTR_KEYBIND_RSTICK 10
#define TRSTR_KEYBIND_LSHOULDER 11
#define TRSTR_KEYBIND_RSHOULDER 12
#define TRSTR_KEYBIND_PADU 13
#define TRSTR_KEYBIND_PADD 14
#define TRSTR_KEYBIND_PADL 15
#define TRSTR_KEYBIND_PADR 16
#define TRSTR_KEYBIND_SHIFT 17
#define TRSTR_KEYBIND_UNK 18
#define TRSTR_KEYBIND_KEYFMT 19
#define TRSTR_KEYBIND_LSTICKL 20
#define TRSTR_KEYBIND_LSTICKR 21
#define TRSTR_KEYBIND_LSTICKU 22
#define TRSTR_KEYBIND_LSTICKD 23
#define TRSTR_KEYBIND_RSTICKL 24
#define TRSTR_KEYBIND_RSTICKR 25
#define TRSTR_KEYBIND_RSTICKU 26
#define TRSTR_KEYBIND_RSTICKD 27
#define TRSTR_KEYBIND_LTRIGGER 28
#define TRSTR_KEYBIND_RTRIGGER 29
#define TRSTR_KEYBIND_JOYBTTNFMT 30
#define TRSTR_KEYBIND_JOYHATFMT 31
#define TRSTR_KEYBIND_JOYAXISFMT 32
#define TRSTR_KEYBIND_KEYPROMPT 33
#define TRSTR_KEYBIND_TITLE 34
#define TRSTR_KEYBIND_RESET 35
#define TRSTR_CANCEL 36
#define TRSTR_ACCEPT 37
#define TRSTR_KEYBIND_INSTRUCT 38
#define TRSTR_KEYBIND_CONFLICT 39
#define TRSTR_KEYBIND_UP 40
#define TRSTR_KEYBIND_LEFT 41
#define TRSTR_KEYBIND_ACTION 42
#define TRSTR_KEYBIND_MENU 43
#define TRSTR_KEYBIND_CANCEL 44
#define TRSTR_KEYBIND_L 45
#define TRSTR_KEYBIND_DOWN 46
#define TRSTR_KEYBIND_RIGHT 47
#define TRSTR_KEYBIND_RUN 48
#define TRSTR_KEYBIND_DEACTIVATE 49
#define TRSTR_KEYBIND_ITEMS 50
#define TRSTR_KEYBIND_R 51