Hướng dẫn dịch Fire Emblem 5 

(Thracia 776)


© Asm65816 2015​


Bài viết này hướng dẫn về phương diện kỹ thuật của quá trình dịch game Fire Emblem (FE) Thracia 776 cho hệ máy Super Famicom sang tiếng Việt.


Đọc bản pdf tại đây (click)



I.Chuẩn bị


+ Rom FE5 không có 200 byte header. Nếu có thì xóa đi (dùng hex editor).
+ Kiến thức cơ bản về hệ nhị phân, hệ thập lục phân.
+ Phần mềm YY-CHR hay bất cứ phần mềm biên tập tile nào.
+ Phần mềm chèn text vào Rom: ở đây dùng Atlas (tải từ www.romhacking.net)
+ Phần mềm dump text từ Rom ra file văn bản: ở đây dùng Catographer (tải từ www.romhacking.net)
+ Hex editor: dùng Windhex (cố định), Stirling (tùy nghi)
+ Phần mềm biên tập ảnh dạng pixel. Ở đây dùng Pixelformer.
+ Phần mềm soạn văn bản: khuyên dùng EmEditor. Không có thì dùng notepad cũng được.
+ Phần mềm Lunar Address (tải từ www.romhacking.net)
+ Phần mềm giả lập cho Super Famicom. Ở đây dùng Snes9X.
+ Phần mềm debugger cho giả lập Super Famicom. Ở đây dùng debugger của Snes9X.
+ Phần mềm tìm kiếm tương đối Search Relative.


II. Xác định, chỉnh sửa bộ font



Đầu tiên ta cần xác định bộ font của FE5 có những đặc tính như thế nào. Bật giả lập, load Rom và chơi một đoạn cho tới khi thấy chữ xuất hiện trên màn hình. Sau đó dùng chức năng chụp màn hình (save screen) lúc chữ xuất hiện. Chú ý chỉ chụp bằng chức năng của giả lập, không chụp bằng chức năng của Windows hay máy ảnh để có hình ảnh trung thực nhất.
Độ phân giải của FE5 cho Super Famicom là 256x224 pixel, khá nhỏ so với những game console đương đại như PlayStation 3 hay Xbox. Cũng dễ hiểu thôi, Super Famicom xuất hiện từ thế kỷ trước, cách PS3 hơn 20 năm mà.
Ví dụ như thế này.

[​IMG]

Rồi dùng phần mềm biên tập ảnh, phóng to phần chữ.

[​IMG]

Khi phóng to, ta thấy chữ có 2 màu trắng và xám. Điều này nói rằng font chữ hội thoại của FE5 là kiểu 2 bit plane hay 2 bpp. Bpp là viết tắt của chữ bit per pixel. 2 bpp nghĩa là 2 bit cho mỗi pixel ảnh. Mỗi byte gồm 8 bit, như vậy mỗi byte dữ liệu sẽ là 4 pixel ảnh.

Vd: giả sử font chữ 1bpp, có chiều cao và chiều rộng là 8x8 pixel. Ta xem những ô trống là 0 (không hiển thị ảnh), những ô có hiển thị ảnh là 1 thì chữ “a” sẽ như sau.

[​IMG]

Đổi chuỗi này sang hệ thập lục, ta được $387EC6C6C6C67F3B. Đây là giá trị cho chữ “a” nếu ta xem bằng Hex editor. Còn khi máy tính (Super Famicom) hoạt động, nó chỉ hiểu được chuỗi 
11100001111110110001101100011011000110110001100111111100111011 mà thôi.

Trên đây là ví dụ về font chữ 1bpp. Còn FE5 lại dùng 2bpp. Thực chất, 2 bpp là dạng triển khai của 1 bpp, trong đó có 1 bit plane thể hiện phần thịt của chữ, 1 bit plane còn lại thể hiện phần bóng mờ của chữ. Nếu font càng sử dụng nhiều bit plane thì nó sẽ có nhiều cấp độ bóng mờ. Nhiều game console sau này sử dụng font nhiều bit plane để tạo ra hiệu ứng đổ bóng nhiều màu, nhiều cấp độ để việc hiển thị chữ được đẹp hơn, rõ ràng hơn so với việc chỉ dùng 1 bit plane (chỉ gồm phần thịt của chữ, không có bóng).
Hãy hình dung font 2 bpp là sự kết hợp lồng ghép của phần thịt chữ và phần bóng. Lấy lại ví dụ chữ “a” bên trên.


[​IMG][​IMG]


Lồng ghép vào nhau


[​IMG]


Đã biết font hội thoại của FE5 là 2 bpp. Giờ ta bật YY-CHR, load Rom, chỉnh chế độ xem là 2Bpp GB. Di chuyển xuống địa chỉ từ $340000 đến $353EE0 sẽ thấy font.


[​IMG]


Để chắc chắn, ta thử thay đổi chữ け xuất hiện trong đoạn thoại đầu game, xem thay đổi trong game thế nào.

Thay đổi trong game

[​IMG]

Vậy đã chắc chắn từ $340000 đến $353EE0 là font hội thoại. Việc tiếp theo là thay thế font chữ Nhật bằng font chữ Việt bằng cách chỉnh sửa bằng YY-CHR hay bất cứ phần mềm biên tập nào khác.

Sau khi thay font, ta sẽ thấy tình trạng như thế này. Dân trong nghề gọi là “tiếng mọi” (cave speak). Bởi trật tự sắp xếp của chữ vẫn còn tuân theo trật tự của tiếng Nhật.

[​IMG]

Việc tiếp theo cần làm là sắp xếp trật tự của câu chữ thành trật tự tiếng Việt. Nhưng trước đó phải làm một số việc khác.



III. Lập table


Table là một kiểu file text liệt kê các ký tự sử dụng trong game được encode với giá trị gì. Đối với PC, trong kiểu encode ANSI thì khi ta gõ chữ “a” trên bàn phím thì phím sẽ truyền một tín hiệu với tần suất là xxx vào trung tâm xử lý, tại đây sẽ phát ra dữ liệu có giá trị là $61, và màn hình thể hiện ra chữ “a”. Tương tự, bất cứ khi nào cần thể hiện chữ ra màn hình, nếu PC đọc được dữ liệu $61 thì nó sẽ cho ra chữ “a”, $62 ra chữ “b”, cứ thế mà tiếp tục, $6B cho chữ “k”.
Hầu như tất cả mọi kiểu encode ký tự đều có giá trị tương đương nhau đối với 26 chữ cái La Tinh, trừ một số bộ font đặc biệt. Tuy nhiên đối với các ký tự có dấu trong tiếng Việt thì giá trị khác nhau tùy thuộc vào kiểu encode. Chẳng hạn với kiểu encode UTF-7 thì chữ “á” có giá trị $2B414F452D, với kiểu UTF-8 without signature thì “á” có giá trị $C3A1, UTF-8 with signature lại có giá trị $EFBBBFC3A1 cho chữ “á”,….

Còn đối với các game console từ thế hệ PlayStation 2 trở về trước thì đa phần đều không tuân theo các chuẩn encode ký tự của PC, do đó khi load game bằng Hex editor thì chỉ thấy được một loạt giá trị Hex chứ không thấy được phần text có nghĩa tương ứng ở cột bên phải của Hex editor.

Bằng cách lập table, ta biết được giá trị hex nào tương đương với ký tự nào trong game. Việc này có 3 ý nghĩa: giúp xác định text trong Hex editor, giúp dump (trích xuất) text từ Rom và giúp chèn lại text vào Rom.
Hình dưới đây là Rom FE5 trong Hex editor tại vị trí $AA490 trở đi, bên phải là cột hiển thị text nhưng hiện tại vẫn chưa thấy được text đúng.

[​IMG]

Như vậy, ta cần phải lập table xác định ký tự nào trong game tương ứng với giá trị nào.
Ở đây ta dùng phương pháp tìm kiếm tương đối va các bước như sau:

1. Chạy game cho tới khi thấy được text. Chọn một cụm từ không quá dài và phải mang tính đặc trưng, ít bị lặp lại trong game. Như hình dưới đây chọn cụm từ “karakumo” vì đây là cụm từ hơi đặc biệt, tần số sử dụng trong hội thoại tiếng Nhật khá ít nên kết quả tìm cũng sẽ được chắt lọc hơn những từ phổ thông.

[​IMG]

2. Mở bảng font của game để xác định vị trí tương đối của từng ký tự. Nếu cho “ka” là vị trí số 1 thì “ku” là số 3, “ke” là số 4, “ko” là số 5. Cũng có thể đặt số 1 cho chữ “a”, khi đó thì “ka” trở thành số 6. Đây chỉ là những vị trí tương đối cho biết chữ này cách chữ kia bao nhiêu chữ thôi, chẳng hạn chữ “e” trong bảng chữ cái La Tinh cách chữ “c” 1 chữ, nên nếu “c” là 1 thì “d” là 2 và “e” là 3.

[​IMG]

Vậy ở đây ta thấy “karakumo” có vị trí 1 đối với “ka”, 34 với “ra”, 3 với “ku” và 30 với “mo”. Ghi nhớ “karakumo” = 1, 34, 3, 30.

3. Đặt file Rom vào cùng thư mục với phần mềm dò tìm tương đối, chạy file RELSEARC.EXE và một giao diện hiện lên, đòi nhập tên file cần tìm và nhập vị trí các ký tự trong chuỗi cần tìm.

[​IMG]

Kết quả tìm kiếm chuỗi 1-34-3-30 (karakumo) cho ra tại địa chỉ $1484B (chữ h sau cùng cho biết chuỗi số trước đó ở hệ thập lục). Vì chuỗi ta tìm khá độc đáo nên chỉ có một kết quả. Trong trường chuỗi cần tìm không quá độc đáo thì dẫn đến nhiều kết quả, và khi đó cần phải thử các kết quả để biết chắc chắn. 
Trong hình trên thì trình dò tìm tương đối báo rằng tại $1484B có chuỗi hex thỏa mãn các điều kiện: ký tự 2 cách 1 là 33 đơn vị, 3 cách 1 là 2 đơn vị và 4 cách 1 là 29 đơn vị. Nói cách khác, cụm từ ta cần tìm đang ở vị trí $1484B.
Trong cửa sổ Windhex, nhấn Ctrl + G và nhập địa chỉ 1484B, Enter để nhảy đến vị trí này. Tại đây ta thấy các giá trị 16-36-17-32…. 
Thử kiểm chứng: $36 - $16= $20 = (32+1)=33, $17-$16=$1=(1+1)=2, 
$32-$16= $1C = (28+1) =29. Hoàn toàn khớp với điều kiện đặt ra.

[​IMG]

Thử thay đổi 16 thành 17, save Rom và chạy game xem có thay đổi gì không.

[​IMG]

Ta tăng từ $16 lên $17 và kết quả chữ “ka” đã biến thành “ki”. Vậy có thể chắc chắn rằng $16 là giá trị của chữ “ka”, và $17 là giá trị của chữ “ki”. Đối với các chữ cái khác, có thể dùng lại phương pháp tìm kiếm tương đối này để dò, hay đơn giản hơn là dùng phương pháp tăng dần hay giảm dần đối với các ký tự đứng trước/sau chữ cái gốc. Vì ta chọn “ka” làm gốc và có giá trị $15 nên đứng ngay trước “ka” là “u” nên “u” có giá trị “$14”.
Khi biết được hết các giá trị này, ta lập file có phần mở rộng .tbl như sau

[​IMG]

Nhớ lưu file ở dạng encode Shift-Jis để đọc trong Windhex. Còn đối với mục đích dump (xuất) hay Insert (chèn) text thì lưu ở bất cứ định dạng nào hỗ trợ ký tự Nhật là được.
Lưu ý là ngoài bộ chữ Kana chiếm 1 byte mỗi ký tự thì FE5 còn sử dụng bộ chữ Hán chiếm 2 byte mỗi ký tự. Vì chữ Hán chiếm 2 byte nên không thể dùng phần mềm dò tìm tương đối để tìm mà chỉ có thể tìm bằng cách sửa đổi các giá trị hex chưa biết trong một đoạn text đã xác định được (vì đã biết hết Kana), xem chữ thay đổi trong game ra sao rồi từ đó dựa vào vị trí của các chữ Hán trong bảng font mà tính.

[​IMG]

Trở lại vị trí $AA490 trong Windhex, load file table đã lập và giờ đây ta có thể thấy được text đã hiển thị đúng trong cột bên phải.
Để tìm vị trí một đoạn text bất kỳ trong game khi đã lập xong table, hãy nhấn Control + K và chọn ký tự Kana cần tìm.
Sau khi lập xong table để đọc và dump (tiếng Nhật) thì cần phải lập một table khác dành cho việc chèn text sau khi dịch vào Rom. Table thứ hai này có cùng các giá trị với table đầu tiên, chỉ thay đổi các ký tự Kana thành các ký tự La Tinh tương ứng mà ta đã chỉnh sửa trong bộ font.


IV. Chỉnh độ rộng của chữ

Có lẽ nhiều người dùng máy tính đã quá quen thuộc với khái niệm độ rộng của ký tự đến nỗi họ không nhận ra nó nữa. Nếu để ý quan sát một chút thì sẽ thấy hầu hết font chữ trên PC đều có độ rộng không bằng nhau cho từng ký tự, chẳng hạn chữ “n” sẽ hẹp hơn chữ “m” và rộng hơn chữ “i”. Thật khó coi nếu tất cả các ký tự La Tinh đều rộng bằng nhau, chẳng hạn như “c á i g ì t h ế n à y ?”

Thuật ngữ gọi bộ font có độ rộng khác nhau giữa các ký tự là “variable width font”, hay chuẩn xác hơn là “proportional font”, còn bộ font có các ký tự rộng bằng nhau là “fixed width font” hay đúng hơn là “mono-spaced font”.

Hầu hết các bộ font trên PC đều là proportional font, do vậy việc dịch game PC thường không đòi hỏi chỉnh lại độ rộng của font chữ, vì nó đã bao hàm sẵn trong bộ font rồi (trừ một vài game PC được port từ console sang). Trái lại, đa phần game console tiếng Nhật thường sử dụng mono-spaced font, tức các ký tự trong bảng chữ đều rộng bằng nhau. Khi ta thay font Nhật đó bằng font La Tinh thì sẽ “t r ô n g r ấ t x ấ u n h ư c o n g ấ u”.
[​IMG]

Như hình trên, sau khi ta thay các ký tự Kana trong bộ font thành ký tự La Tinh thì sẽ nhận thấy một khoảng trống khá rộng theo sau những ký tự này. Lý do là ký tự Kana ban đầu rộng hơn ký tự La Tinh mà ta vẽ lại.
Do vậy, khi dịch game console thì ta luôn phải để tâm tới việc này. Độ rộng của từng ký tự có thể được thay đổi thông qua đoạn code điều chỉnh. Đối với (đa phần) game không đoạn code này thì phải viết thêm, dựa trên routine in chữ ra màn hình của game và việc này đòi hỏi phải có kiến thức về ngôn ngữ Assembly để thực hiện. Còn đối với một số game có sẵn code chỉnh độ rộng như Fire Emblem thì không cần phải có kiến thức về Assembly mà chỉ cần một chút suy luận là làm được, nhưng nếu có hiểu biết về Asm thì công việc sẽ dễ dàng và khoa học hơn.

Cách 1:

+ Đầu tiên chụp màn hình game đối với Rom nguyên gốc chưa chỉnh sửa, chụp chỗ nào có hội thoại và nhớ là chỉ chụp bằng chức năng của giả lập để có độ phân giải đúng (256x224 pixel).
[​IMG]

+ Phóng to ảnh, “đếm” số pixel của từng ký tự. Nên đếm cho những ký tự đứng cạnh nhau trong bảng font. Chẳng hạn như chữ “ke” dưới đây rộng 12 pixel, “ku” là 10 pixel….
[​IMG]

+ Dò tìm chuỗi giá trị vừa tìm được trong Hex editor. Chẳng hạn, ta đã biết “ki” có độ rộng 11 (0B) pixel, ku là 10 (0A) pixel, ke là 12 (0C) pixel, ko là 11 (0B) pixel bằng phương pháp đếm, và ta cũng biết ki, ku, ke, ko đứng liền nhau trong bảng font. Vậy, mở Rom bằng Hex editor và dò tìm chuỗi 0B-0A-0C-0B thì được một số kết quả (chuỗi tìm kiếm càng dài thì kết quả càng chuẩn). Thử từng kết quả để biết rằng chuỗi này bắt đầu tại $A9A50.

+ Kiểm chứng: tại $A9A50 ta thấy chuỗi 0C 0B 0B 0C 0C…. ứng với độ rộng của a, i, u, e, o…. Thử thay các giá trị này thành 0F (16 pixel, rộng hơn ban đầu) thì ta được
[​IMG]

Rõ ràng khoảng cách giữa các ký tự Kana đã dãn rộng ra. Ngược lại, thử thay các giá trị mặc định tại $A9A50 bằng con số nhỏ hơn (chẳng hạn, 07) và ta được
[​IMG]

Như vậy, khoảng cách giữa các chữ Kana đã bị thu hẹp. Điều này cho thấy bắt đầu từ $A9A50 là những con số điều chỉnh độ rộng của từng ký tự trong bảng font.
Hình dưới đây đã điều chỉnh độ rộng của ký tự La Tinh sau khi thay thế font và xóa bỏ chữ Hán, cho kết quả đều đặn dễ nhìn.
[​IMG]

Cách 2: nếu như cách trên có vẻ thủ công và “ăn may” thì cách này đòi hỏi một số kiến thức nhất định về ngôn ngữ Assembly 65816 của máy Snes. Ở đây dùng Debugger của giả lập Snes9X để xác định code độ rộng.

+ Ta đã biết, bộ font bắt đầu bằng chữ Kana “a” tại $340000. Tuy nhiên, địa chỉ này chỉ đúng khi ta xem bằng Hex editor hay các phần mềm trên PC. Còn trên máy Snes, khi nó thực thi chương trình thì địa chỉ này không còn đúng. Có khái niệm gọi là “địa chỉ Snes”, và ở đây dùng phần mềm Lunar Address để xác định (nếu không thì phải dùng kiến thức Memory Mapper của Snes để xác định).
[​IMG]

+ Khai báo các thông tin về loại Rom (FE5 là LoROM) cho Lunar Address, nhập địa chỉ $340000 (PC) và ta được địa chỉ Snes tương ứng là $ E88000.

+ Chạy Debugger của Snes9X, click vào tab “Breakpoint”, nhập địa chỉ E88000 vào trong ô và tích vào ô “read”. Điều này có nghĩa rằng Debugger sẽ thực thi lần lượt các lệnh của chương trình (game), cho tới khi nó gặp phải lệnh “đọc” địa chỉ mà ta vừa ra điều kiện. Lúc này Debugger sẽ đứng lại và hiển thị các thông tin liên quan.

[​IMG][​IMG]


Click vào tab “Skip Op” để kiểm tra lần lượt từng lệnh trong routine đọc địa chỉ E88000, từ đó lần theo các dấu vết (phải hiểu được ý nghĩa của từng lệnh, ở đây tôi không đi sâu vào phần này vì sẽ mất nhiều thời gian) và cuối cùng ta được dẫn tới routine $95/9A20 20 2B 9A JSR $9A2B [$83:9A2B] (bắt đầu tại $A9A20) và routine này kết thúc tại $A9A4F ($95/9A4F 60 RTS). Ngay sau đó (từ $A9A50) là phần code chỉnh độ rộng cho từng ký tự.
 
V. Dump text và Insert


1. Dump


Thuật ngữ "dump" chỉ việc trích xuất text từ Rom/file game ra văn bản để dịch. Việc trích xuất text không chỉ phục vụ mục đích để đọc, mà nó còn có các ý nghĩa thiết thực sau:

1. Dễ đọc, dễ kiểm soát: thường thì để đọc hết hội thoại trong game thì người chơi phải chơi hết game, chơi đến mọi ngóc ngách trong game. Có những hội thoại chỉ xuất hiện khi đã hội đủ một số điều kiện nhất định. Do vậy, để đọc hết hội thoại trong game bằng cách chơi thì tốn rất nhiều thời gian, công sức. Nhưng nếu dump hội thoại ra file văn bản thì ta có thể đọc toàn bộ nội dung thoại một cách dễ dàng, bao gồm cả những đoạn thoại ẩn. Tuy nhiên có thể các đoạn thoại không được sắp xếp theo trật tự diễn tiến thời gian/event như trong game.

2. Tránh bỏ sót khi chèn: với những game có số lượng thoại lớn như Fire Emblem hay Final Fantasy, nếu không trích xuất text ra thì gần như không thể biết được chính xác phải chèn lại vào Rom/file game bao nhiêu câu, dẫn đến chèn thiếu, dịch thiếu. Đây là ý nghĩa quan trọng của việc dump text.

3. Tránh nhầm, thiếu code: một số game sử dụng control code nhúng kèm trong hội thoại như Fire Emblem, Tearring Saga với mật độ rất cao. Control code là phần code điều khiển mọi thứ trong đoạn thoại như làm chữ chua nhanh, chạy chậm, phóng to chữ, đổi màu chữ, chuyển từ nhân vật này sang nhân vật khác, hiển thị avatar nhân vật... Trong quá trình chơi trong game, ta chỉ gián tiếp nhận thấy những tác động của control code (nếu tinh ý) chứ không thể trực tiếp thấy bản thân những code đó. Do vậy, nếu chỉ nhìn text trên màn hình mà dịch rồi chèn lại Rom/file game thì sẽ thiếu control code và đôi khi là dẫn đến đơ game. Final Fantasy IX là một game sử dụng rất nhiều control code trong câu thoại và tất cả chúng đều là code quan trọng, chỉ cần sai lệch hay thiếu một đoạn nhỏ cũng làm hỏng game. Đây là ý nghĩa tối quan trọng của việc dump text
[​IMG]

Một đoạn thoại trong FE5 sau khi dump và phần dịch bên dưới bằng Atlas. Nếu không dump thì sẽ không biết được sự tồn tại của control code nằm trong thoại.

Như vậy, ta đã thấy rõ tầm quan trọng của việc dump text trong quá trình dịch game. Nếu chỉ dịch những game nhỏ với số lượng câu thoại không nhiều, vài đến mười mấy câu đơn giản thì có thể không cần phải dump, nhưng nếu là một game đồ sộ thì nhất định phải cần đến.

Hiện nay có nhiều phần mềm được viết riêng để phục vụ cho mục đích này. Có thể kể đến những cái tên như Script Extractor, Romjuice, Cartographer... Nguyên tắc của chúng đều giống nhau: tham chiếu các giá trị hex ta cung cấp trong table để chuyển đổi thành văn bản trong file xuất ra. Chẳng hạn ta có những entry sau trong tabel

00=0
01=1
02=2
03=3
04=4
05=5
06=6
07=7
08=8
09=9
0A=A
0B=S
0C=M

và trong Rom/file game có đoạn

0A-0B-0C-06-05-08-01-06

thì khi gặp đoạn này, phần mềm sẽ in ra file văn bản với nội dung: ASM65816.
Cách sử dụng những phần mềm này khá đơn giản: cung cấp tên Rom, file game (để cùng thư mục với phần mềm), khai báo địa chỉ bắt đầu và kết thúc của text, khai báo tên file văn bản cần xuất ra.
Tuy nhiên phần mềm Cartographer còn có thêm nhiều chức năng phức tạp/tiện lợi hơn, chẳng hạn như dump theo pointer. Nghĩa là thay vì khai báo địa chỉ bắt đầu và kết thúc của text thì ta khai báo địa chỉ bắt đầu và kết thúc của pointer chỉ đến đoạn text đó. Chức năng này rất lợi hại vì khi chèn text đã dịch vào Rom/file game thì mối quan tâm hàng đầu là pointer chứ không phải địa chỉ chèn vào đâu.
[​IMG]

Ví dụ về dump theo pointer bằng Cartographer. Đọc thêm file readme để biết chi tiết.

2. Insert

Insert, tức chèn văn bản đã dịch vào Rom/file game. Đây là quá trình ngược lại với dump và là bước cuối cùng trong chuỗi thao tác cần thiết để hoàn thành quá trình dịch thuật. Đây cũng là mục đích lớn nhất của quá trình dịch game.
Có nhiều phần mềm phục vụ cho việc này, như Script Insertor, Gizmo, Atlas... Trong đó Atlas của tác giả Klarth nổi bật hơn cả và đã thay thế tất cả những phần mềm kia vì những tính năng tiện lợi của nó. Đặc biệt, Atlas và Cartographer có tính tương thích với nhau rất cao, nên giới dịch game chuyên nghiệp trên Thế giới thường sử dụng bộ đôi này. Nguyên tắc hoạt động của những phần mềm này cũng giống như phần mềm dump văn bản, chỉ ngược chức năng. Chẳng hạn, lấy lại ví dụ trên.

Nếu ta có đoạn văn bản "ASM65816" thì khi chèn vào Rom với file table được cung cấp thì phần mềm sẽ đưa các giá trị hex sau vào:
0A-0B-0C-06-05-08-01-06

Dưới đây là những lợi ích của việc sử dụng Insertor:

1. Nhanh, chuẩn xác vì chỉ cần dịch/gõ như gõ văn bản bình thường, không phải gõ trên Hex editor vừa chậm, vừa dễ sai sót và không hỗ trợ tiếng Việt.

2. Một số công cụ dịch game chuyên dụng tập trung vào một game nào đó có hỗ trợ dịch và chèn văn bản, nhưng tuyệt đại đa số chúng là những công cụ do người Tây phương viết ra nên không hỗ trợ dấu tiếng Việt, khi chèn dẫn đến hỏng Rom/game. Chẳng hạn như Resident Evil 5, Silent Hill trên PC đều có công cụ hỗ trợ dịch, nghĩa là phần mềm sẽ liệt kê hết những câu thoại trong game và bên cạnh là ô để dịch như kiểu ô Excel, nhưng tất cả đều không hỗ trợ dấu tiếng Việt. Nhưng với Atlas, ta có thể gõ bất cứ thứ tiếng gì, miễn là file table và file văn bản dịch phải cùng encoding.


Như vậy, về nguyên tắc thì chỉ cần sử dụng bộ đôi vạn năng Cartographer + Atlas là có thể dịch hết mọi game có trên thị trường, cho mọi hệ máy từ trước đến nay. Dĩ nhiên là để làm được việc này, đôi khi cần phải có thêm kiến thức về Assembly cho hệ máy đó, nếu như game sử dụng những giải thuật "không bình thường". Đối với những game này thì sau quá trình giải mã thì có thể tiến hành dump, insert bằng bộ đôi vạn năng kể trên như bình thường.

VI. Pointer

Trong phần trước có đề cập đến việc dump text và insert. Nhưng để dump (trích xuất) và insert (chèn) thì phải nắm được một yếu tố vô cùng quan trọng khác, đó chính là pointer. Phần này sẽ đề cập đến những cách xác định pointer.

Đa phần game console đều sử dụng pointer table, tức một dãy pointer đứng liền kề nhau. Tuy nhiên, FE4 và FE5 lại không sử dụng pointer table mà chèn pointer chỉ đến câu thoại vào giữa event code. Chẳng hạn:

<code hiển thị map1>
<code bật nhạc đầu map1>
<code hiển thị 2 nhân vật địch xuất hiện>
<pointer 2 nhân vật địch nói chuyện với nhau>
.....


Cho nên việc xác định pointer sẽ khó khăn hơn thông thường.

1. Xác định bằng địa chỉ SNES CPU

Đầu tiên, load Rom bằng Windhex với file table đã xây dựng, ta dễ dàng xác định được đoạn thoại đầu map 1 nằm ở vị trí 0xAA493 (với Rom không header).
Vì FE 5 là Lorom 80:8000 nên dễ dàng tính được offset 0xAA493 tương đương với địa chỉ $95A493 trong SNES CPU. Có thể dùng cách khác là phần mềm Lunar Address nếu không nắm được các đặc điểm của địa chỉ SNES.
[​IMG]

Nếu không rõ Rom đối tượng thuộc loại gì, có header hay không thì chỉ cần click vào tab "Auto detect type" là Lunar Address tự xác định được đó là loại Rom gì.
Tiếp theo, chỉ cần nhập địa chỉ Rom khi mở trên PC vào ô "PC File Address" thì bên ô đối diện ("SNES LoROM") sẽ cho địa chỉ tương ứng trong SNES CPU.
Đoạn thoại ta cần xác định nằm ở 0xAA493 trong PC, tương ứng với $95A493 trong SNES CPU. Đây cũng chính là giá trị pointer của đoạn thoại này.
Vì SNES sử dụng kiểu xếp dữ liệu Little Endian (thứ tự ngược) nên 95A493 phải được đọc thành 93-A4-95. Dò tìm 3 giá trị này trong Rom và ta sẽ được địa chỉ của pointer chỉ đến đoạn thoại này.
Nếu đã biết loại Rom thì không cần dùng đến Lunar Address, mà chỉ cần đổi kiểu xem trong Windhex thì vẫn có thể biết được địa chỉ trong SNES CPU tương ứng bằng cách vào Option --> Display offest as---> SNES Lo-Rom (Fast Rom).

Cách này có ưu điểm là dễ dàng xác định được pointer, không cần hiểu sâu về Asm, nhưng có khuyết điểm là không chuẩn xác hoàn toàn. Bởi vì trong Rom có thể có nhiều địa chỉ cùng giá trị với nhau, nên ta phải kiểm tra từng địa chỉ trong trường hợp này.


2. Xác định bằng Debugger

Dùng Debugger luôn là cách làm khoa học, chuẩn xác và giúp ta hiểu sâu rộng hơn về game, nhưng có khuyết điểm là đòi hỏi phải có một lượng kiến thức nhất định về Asm. Có thể dùng Geiger's Snes9X Debugger để xác định.

Load Rom bằng Debugger, tích vào ô "Trace once" nếu muốn chỉ theo dõi 1 lệnh 1 lần (tránh ngốn Ram) và tích vào ô Logging CPU khi game chạy đến đoạn bắt đầu hội thoại.
[​IMG]

Khi bỏ dấu tích ở ô Logging CPU thì quá trình log kết thúc, file log được lưu vào thư mục Logs. Mở file Log, dễ dàng xác định được đoạn thoại đầu map 1 gồm những đoạn code sau:
Mã:
$8C/88FE 08  PHP  A:88FE X:FFFE Y:0039 P:envmxdizc
$8C/88FF 5A  PHY  A:88FE X:FFFE Y:0039 P:envmxdizc
$8C/8900 AD 2C 17  LDA $172C  [$8C:172C]  A:88FE X:FFFE Y:0039 P:envmxdizc
$8C/8903 89 00 40  BIT #$4000  A:0001 X:FFFE Y:0039 P:envmxdizc
$8C/8906 D0 1B  BNE $1B  [$8923]  A:0001 X:FFFE Y:0039 P:envmxdiZc
$8C/8908 B7 3B  [B]LDA [$3B],y[$FD:83D1][/B]  A:0001 X:FFFE Y:0039 P:envmxdiZc
$8C/890A 8D 46 17  [B]STA $1746  [$8C:1746][/B]  A:A493 X:FFFE Y:0039 P:eNvmxdizc
$8C/890D C8  [B]INY[/B]  A:A493 X:FFFE Y:0039 P:eNvmxdizc
$8C/890E B7 3B  [B]LDA [$3B],y[$FD:83D2][/B]  A:A493 X:FFFE Y:003A P:envmxdizc
$8C/8910 8D 47 17  [B]STA $1747  [$8C:1747][/B]  A:95A4 X:FFFE Y:003A P:eNvmxdizc
$8C/8913 DA  PHX  A:95A4 X:FFFE Y:003A P:eNvmxdizc
$8C/8914 A9 00 82  LDA #$8200  A:95A4 X:FFFE Y:003A P:eNvmxdizc
$8C/8917 85 6E  STA $6E  [$00:006E]  A:8200 X:FFFE Y:003A P:eNvmxdizc
$8C/8919 A9 72 86  LDA #$8672  A:8200 X:FFFE Y:003A P:eNvmxdizc
$8C/891C 85 6D  STA $6D  [$00:006D]  A:8672 X:FFFE Y:003A P:eNvmxdizc
$8C/891E 22 E7 83 8C JSL $8C83E7[$8C:83E7]  A:8672 X:FFFE Y:003A P:eNvmxdizc
Chú ý đoạn bôi đậm,
LDA [$3B],y[$FD:83D1] ; load giá trị tại địa chỉ $3B + giá trị tại địa chỉ $FD83D1 (giá trị của Register Y) vào Register A.
STA $1746 [$8C:1746] ; chứa giá trị của Register A vào địa chỉ $1746 trong Ram.

Đoạn này cho biết, giá trị của pointer được đọc từ (biến số) $3B và $FD83D1, sau đó ghi vào $1746 trong Ram. Vì Ram của SNES bắt đầu từ $7E0000 nên $1746 tương đương với $7E1746. Đây là nơi chứa pointer của tất cả các câu thoại trong game, tuy nhiên chỉ có một pointer duy nhất được thể hiện ở một thời điểm hội thoại nhất định.
[​IMG]

Bật chức năng Hex editor trong Debugger, chọn mục Viewing là RAM và kéo xuống địa chỉ $7E1746, ta sẽ thấy giá trị 93-A9-95 là giá trị của pointer cần tìm. Khi chuyển sang đoạn thoại khác, giá trị này sẽ thay đổi tương ứng. Có thể đóng băng, hay tạo cheat code tại địa chỉ này để xác minh. Khi đó, dù ở bất cứ đoạn nào trong game, thoại vẫn cứ thể hiện là đoạn thoại đầu map 1.
Như vậy ta đã tìm được pointer bằng Debugger.


6 bình luận :

  1. nhìn chóng mặt qá :D, z mới thấy các bác vất vả ntn ...

    ReplyDelete
  2. nhìn chóng mặt qá :D, z mới thấy các bác vất vả ntn ...

    ReplyDelete
  3. bạn có thể làm 1 video trên youtube dịch đại khái vài dòng được không

    ReplyDelete
  4. quá kinh khủng :3 ,em k làm được

    ReplyDelete

 
Top