先簡單解釋 Retropie 是啥東西。這名字拆開是 Retro 與 Pie ,直接翻譯是「復古(遊戲)」+「派」,顧名思義,就是把樹莓派(Raspiberry)變成為復古電玩遊戲機的一套免費開源的軟體系統。經過數年的發展後,早已不限於樹莓派,而是以 Debian Linux 為基礎作業系統上的設備(個人電腦、樹莓派、ODroid C1/C2/XU3/XU4...),且支援的家機、街機等各種遊戲平台也越來越多。其實 Retropie 本質上算是一個整合復古遊戲的平台,後端引入數十種電玩的模擬核心(包含知名的 RetroArch 複合型復古電玩模擬核心),前端的遊戲管理介面使用一套名為 EmulationStation 的軟體,並可搭配各種外掛和佈景主題,打造出各種客製化風格的復古遊戲平台。其實類似 Retropie 這類的軟體還有好幾個,例如 Recalbox、Batocera,架構也都很像,前端也都是 EmulationStation 介面,差別在於 Retropie 允許用戶自製更多的客製項目,而 Recalbox、Batocera 完成度更高,支援更多的 SoC 電腦,中文介面等等,不過客製彈性也就相對變少。講白話一點,想要裝完就能上手使用,可以考慮 Recalbox、Batocera 這類,找對應的機型下載安裝即用,若想要自己搞一台充滿個人風格的復古遊戲機,可以從 Retropie 開始慢慢折騰。
然後呢,兩年前買了一組 GPi Case + 樹莓派 zero W 做遊戲掌機,前陣子再把樹莓派升級成 zero 2 W,可以玩遊戲變多、變得更實用好玩了(中間發生一次 GPi Case 無預警故障,費盡洪荒之力再把它 DIY 修好,詳細歷程寫在這篇文章「GPi Case 維修紀事」),千挑百選找到 SupremeTeam 製作的版本,它是用 Retropie 加上各種魔改手段而成,對它唯一不滿的地方是英文介面,在 2.8 吋 320x240 解析度上閱讀英文介面,實在是頗傷眼力,所以嘗試著把它改成中文介面。
萬萬沒想到,一旦真的動手改下去,才發現這個水有多深、坑有多大,所以才有這篇文章。不過本文的技術成份不高,大多是個人的辛路歷程...
首先用 Google 搜尋「Retropie 中文化」,資訊量不少,不過全都是「遊戲名稱中文化」或是「遊戲描述中文化」的做法。基於 Retropie 魔改的系統版本幾乎都是外國人做的,有的版本對中文支援很差,而解決的方式也不難,不外乎就是改用支援中文的字型 Font、安裝本地化、中文套件這類小手段就夠了。至於針對前端 EmulationStation 操作介面的中文化,卻是一個也沒有找到。爬文過程中讀到某篇 Blog 文章提到「官方的版本不支援中文介面,習慣了就好」,我才意識到 Retropie 可能不像 Recalbox、Batocera 具備多語系架構。於是我下載 Retropie 使用的 EmulationStation 版本,檢視程式碼,確認了該篇文章的說法為真,截至目前為止只有支援英文。
雖然官方不支援,但跟我有相同想法的人也一定也不少吧?或許有非官方支援多語系的版本才對。於是我又改了關鍵字搜尋,總算找到一個支援本地化+多語系架構的 EmulationStation 版本了。作者 flyinghead 也採用開放原始碼的方式發表。我把他的原始碼放到樹莓派 4B 編譯執行,前端的中文介面是有了,不過進去遊戲再回到前端,就變成國防布黑畫面。該多語版作者其實也有說明,原因出在後來樹莓派 4B 使用了新版顯示驅動(原文),而該版本最後一次更新時間是 2019 年 6 月 15,不支援後來才上市的樹莓派 4B(2019 年 6 月下旬),有點可惜。
以上是我從茫茫網路中,找到所有與 EmulationStation 中文版前端的全部資訊,看來中文化這條路,最遠似乎只能走到這裡了。接下來怎麼辦?
既然沒有,那就自己來吧!已經記不得第幾次這樣搞了,算一算我踩過的坑,不差這一個。
其實 flyinghead 的多語系舊版已提供了大量資訊,把他的程式碼跟 Retropie 官方版交叉比對之後,就會知道怎麼改。
EmulationStation 是用 C++ 寫的,多語版作者 flyinghead 採用的是標準的 Boost (本地化) + gettext(多語)的方案,與官方的最新版 Retropie 程式碼互相比對之後,很快就找出如何修改的邏輯如下:
- 移植多語系文本檔案至官方版相同的位置。
- 移植 Locale.h 至官方版相同的位置。
- 改寫官方版 CMakeLists.txt 加入 Boost 與 gettext 的編譯設定(可參考多語系舊版的 CMakeLists.txt)
- 改寫官方版 main.cpp 加入引用 Locale.h 和啟用多語系設定(可參考多語系舊版的 main.cpp)
- 修改程式中需要翻譯的英文詞句,由 "XXXX" 改寫為 _("XXXX") 或 _("XXXX").c_str() 或 N_("XXXX"),並適當的必要加入 #include "Locale.h" 引用。極少數的地方需整段改寫,替換為多語系的寫法。
EmulationStation 前端程式的多語化工程,歸納後其實就只有這 5 個大項而已。前 4 項就是複製貼上的操作邏輯,不用 3 分鍾就可以改好,真正最麻煩的地方是第 5 項,要逐一比對操作流程中每支程式出現在介面上的詞條位置,內容差異而產生的不同寫法、編譯檢查、反覆修正翻譯用詞等,不能一概而論,改起來非常耗時,每天的進度很有限。
一開始還抱持著「愚公移山」的精神,改了好幾天,幾乎把所有閒暇時間全都佔滿,卻是越改越沒動力。心想,哪天 EmulationStation 改版了,我是不是得再全部重來一次?
所以我終於體會多語版作者 flyinghead 的心情,這種事情做過一次就不會想再做第二次,畢竟沒人付薪水,再多的熱情也會被消磨殆盡。
於是我停下腳步,想想是否有更有效率的方法呢?最後想到,乾脆開發一支程式,一鍵處理上面提到的 5 個大項,說不定以後應付改版就輕鬆許多呢?
想著想著,程式就生出來了...
上圖這支程式取名「ES Localize Tool」,意即「ES 本地化工具」,而「一鍵修改原始碼」的技術核心,則是採用了「Regular Expression」(中文為正規表達式、又稱正規運算式、正規表示法、規則運算式、常規表示法...)的方法。至於具體的開發方式,則是再度請出微軟的 Visual Studio Code 這套強大又免費的工具,一張圖即可說明:
以上圖為例,正規運算式:
(addEditableTextComponent|HelpPrompt|std::make_shared<TextComponent>)\((.+), ?"([^"]+)"([,)]+)
搜尋所有的 EmulationStation 原始碼中,符合條件的有 31 個檔案,88個地方符合。也就是說光是這條正規運算就能處理掉 31 個檔案,共 88 個可修改的地方,直接套用,不用一個一個手動改。改完後編譯看看,如果結果正確,就把這條正規運算式寫到程式的資料庫裡。當然不會每次找出的規則都能如此順利,很多正規運算修改的範圍只有 1 個而已。
就這樣,反覆測試撰寫正規運算式,以上 5 個修改大項,總共寫了六十多條正規運算式。每一條都是一個字母一個字母慢慢敲、反覆嘗試、逐一編譯檢視成果。
「ES Localize Tool」主程式只用了幾個小時就寫好了,不過 60 幾條正規運算式又是前前後後花了好幾天的時間。雖然一樣也是辛苦工,不過若未來的 EmulationStation 原始碼沒有大幅更動時,預估這支程式還是能有效應付,降低未來改版後重工的可能性。若將來發現編譯無效的部分,只需增修運算式的資料庫即可,不需砍掉重練。
由「ES Localize Tool」的統計結果為:68 條正規運算,處理 357 條翻譯詞彙,共 439 個修改,透過這支自製工具,只需動動滑鼠,幾秒內就可完成,節省超級鉅量的時間,並可直接產出支援本地化+多語系版本的 EmulationStation 前端程式碼。雖然不敢說有全數翻譯到,不過一般的操作下,幾乎已經看不到英文標題。
「ES Localize Tool」使用 PyQt5 開發,提供視窗操作介面,並支援跨平台執行(Windows / macOS / Linux...),不過要編譯 EmulationStation 還是得回到 Linux 環境就是了。另外也有提供 Console mode 的版本,也就是在終端介面打指令、用問答的方式,適合在沒有桌面環境的系統下操作。程式碼的部分我放在 Github 上了,其他細部的說明也在上面。
另外我也提供直接安裝 Retropie 多語系版(含中文化)的方法,詳情可以到這裡瞧瞧。
後記
「EmulationStation」中文化算是我近期「既然沒有,就自己來」的搞事系列中,踩的坑最深,時間花最多的項目(補充:此紀錄已被 2022.12.03「黑蘋果二號復活記」超越)。有人說「Regular Expression」是區分碼農等級的標準之一,透過 Regular Expression 的使用,終究還是從深坑裡成功爬了出來,並實現「一鍵處理」的終極目標,也算是一次不錯的踩坑經驗。
補充:
Linux base 系統自行安裝其他版本的 Python
描述:在開發「ES Localize Tool」的過程中,一度使用只支援 Python 3.8+ 的指令( shutil 套件的 copytree 與 rmtree 指令,在 3.8 新增 dirs_exist_ok 參數 )。然而 Retropie 最新版 4.8 版目前僅相容於 Debian 10 Buster( Retropie 使用的 SDL2 套件是客製版,目前還不支援 Debian 11 Bullesys),且 Debian 10 Buster 內建的 Python 版本只有 3.7,因此「ES Localize Tool」不能在 Debian 10 Buster + Retropie 4.8 的樹莓派 4B 上運作,實用性因此打了折扣。
後來改寫「ES Localize Tool」解決這個問題(其實魔改 python 3.7 的 shutil 套件也可以解決。參考來源1,來源2),不過過程中也學到如何在較舊的系統上自行安裝新版 Python,以下做個筆記當紀錄。
以安裝 3.10.4 版為例,指令如下:
ver=3.10
vernum=${ver}.4
sudo apt-get update
sudo apt-get install -y build-essential tk-dev libncurses5-dev libncursesw5-dev libreadline6-dev libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev libffi-dev
wget https://www.python.org/ftp/python/${vernum}/Python-${vernum}.tar.xz
tar -vxf Python-${vernum}.tar.xz
cd Python-${vernum}
./configure --enable-shared --enable-optimizations --prefix=/usr
make -j4
編譯完成之後,執行安裝:
sudo make altinstall
(註:使用 sudo make install 會將原本內建的 python 版本蓋掉,不建議。)
將原本的 python 指令導向自行安裝的 python
sudo update-alternatives --install /usr/bin/python python /usr/bin/python${ver} 1
並可以使用 pip3.x 指令(例如 pip3.10 install xxxx)來安裝對應的套件。
PyQt5 出現 「Could not load the Qt platform plugin "xcb" in "" even though it was found.」錯誤
描述:在嘗試使用上述自行安裝 Python 版本,用 pip3.10 安裝 pyqt5 之後,運行「ES Localize Tool」出現錯誤。
分析(參考來源):
1. ~/.bashrc 加入一行 export QT_DEBUG_PLUGINS=1
2. 開啟終端機執行 PyQt5 程式,會顯示錯誤明細:
"Cannot load library /usr/lib/python3.10/site-packages/PyQt5/Qt5/plugins/platforms/libqxcb.so: (libxcb-xinerama.so.0: 無法開啟共用目的檔: 沒有此一檔案或目錄)"
移到 /usr/lib/python3.10/site-packages/PyQt5/Qt5/plugins/platforms 目錄,執行:
ldd libqxcb.so
會出現一行
libxcb-xinerama.so.0 => not found
表示少了 libxcb-xinerama.so 函式庫。
3. 解法有兩種方式:
方法1:sudo apt install python3-pyqt5,裝完之後再 autoremove 即可
方法2:sudo apt install libxcb-xinerama0
再執行 ldd libqxcb.so 就不會出現 libxcb-xinerama.so.0 => not found 報錯了。
留言列表