Chủ Nhật, 23 tháng 4, 2017

[PSX]Hướng dẫn dịch thuật FF IX

Trong thời gian qua, chúng tôi nhận được nhiều câu hỏi quan tâm đến mục game của trang blog này, trong đó có một số câu hỏi cụ thể về cách thức dịch game console.
Mặc dù đã có bài viết hướng dẫn phương pháp luận về dịch game console/PC đăng trên diễn đàn GameVN vào năm 2010, nhưng bài viết khá cũ, hình ảnh minh họa không còn nguyên vẹn nên Asm65816 đã viết một bài hướng dẫn khác, cụ thể là Final Fantasy IX cho máy PlayStation. Nay chúng tôi đăng lại ở đây.
Asm65816 cũng là tác giả những bản dịch Việt văn trong mục game trên blog này.

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




 Hướng dẫn dịch thuật Final Fantasy IX




Tác giả: Asm65816, hay Yugisokubodai trong một số cộng đồng.
Trang game: http://gokuraku-shujo.blogspot.com/search/label/Game
Kênh Youtube: http://youtube/Yugisokubodai

1.Khái quát

Final Fantasy IX (từ đây trở xuống: FF9) là game RPG do hãng Square Soft (hiện nay, tại thời điểm 2015, là Square Enix) phát hành vào ngày mồng 7 tháng 7 năm 2000 cho hệ máy chơi game PlayStation (từ đây trở xuống: PSX) của hãng Sony. Game thuộc thể loại RPG, một người chơi và là phiên bản thứ chín trong series Final Fantasy.
FF9 được phát hành với ngôn ngữ ban đầu là tiếng Nhật, sau đó có thêm bản tiếng Anh và các ngôn ngữ Tây Âu vào thời gian sau đó. Bài viết này hướng dẫn cách chuyển ngữ FF9 sang Việt ngữ hay bất kỳ ngôn ngữ đích nào khác, với ví dụ ngôn ngữ nguồn là tiếng Nhật.
Hiện nay, đã có công cụ Hades Workshop của tác giả Pháp quốc Tirlititi cho phép biên dịch toàn bộ hội thoại trong game, cũng như một phần của Menu, tên Item và một vài đoạn text hiển thị khác. Công cụ này cho phép người dùng chỉnh sửa text hiển thị trong game một cách dễ dàng mà không đòi hỏi người dùng bất kỳ kiến thức nào, ngoại trừ khả năng gõ bàn phím và khả năng dịch thuật ngôn ngữ.
Tuy nhiên, công cụ này vẫn còn rất nhiều hạn chế như tồn tại nhiều bug (đang khắc phục dần qua các phiên bản), cũng như không thể dịch toàn bộ (100%) text hiển thị trong game, chẳng hạn một số command, tên bài, các thông báo trong Chocograph, vân vân.




 



Bài viết này nhằm mục đích hướng dẫn người đọc đến những kiến thức cần thiết cho việc dịch game, thông qua đó người đọc có thể nắm bắt kiến thức, hiểu biết ở một mức độ nhất định về phương pháp dịch thuật cho FF9 nói riêng và cho bất kỳ game nào khác, nói chung. Bài viết này không dành cho người không thích học hỏi, không ham hiểu biết và chỉ thích dùng những công cụ sẵn có để dịch thuật.
Bài này hướng đến đối tượng cầu tiến, ham học hỏi, tìm tòi và có nhu cầu hiểu biết cặn kẽ về việc mình muốn làm, đang làm và dự định sẽ làm. Áp dụng những kiến thức trong bài này, người đọc có thể dịch 100% text hiển thị trong game, bao gồm hết tất cả hội thoại chính và các thông báo, hiển thị cho Menu,…. Qua đây, người đọc cũng có thể tùy chỉnh tối ưu cho bản dịch của mình hơn so với khi sử dụng công cụ Hades Workshop, bởi lẽ bài viết này đi vào cốt lõi, bản chất của mọi khía cạnh gặp phải trong quá trình dịch FF9.

2.Tiền đề tri thức

Để có thể lãnh hội những kiến thức đề cập trong bài này ở mức tối đa, người đọc cần chuẩn bị sẵn những tri thức, kiến thức tiền đề không được đề cập đến ở đây, mà tác giả mặc định cho là người đọc đã nắm rõ.

Phần bắt buộc

a. Khả năng tìm kiếm bằng Google: không có khả năng này thì tốt nhất là đừng đọc bài viết này. Mọi kiến thức, công cụ đều có được thông qua khả năng này.
b. Kiến thức sơ lược về dịch game: xem thêm bài “hướng dẫn dịch game console”, tác giả Asm65816 đăng trên diễn đàn GameVN, năm 2010. Những kiến thức này bao gồm Pointer, bitplane, tìm kiếm tương đối, table,…
c. Kiến thức về bit, byte.
d. Kiến thức về hệ số thập lục
e. Kiến thức về Endian: Little, Big.
f. Kiến thức về CD-rom: LBA, sector,…
g. Kiến thức về hệ số thập phân, thập lục, nhị phân, cũng như cách chuyển đổi giữa các hệ số này, cách tính toán với chúng.
h. Khả năng sử dụng Hex Editor.

Phần không bắt buộc

Là những kiến thức mà nếu người đọc nắm biết được trước thì sẽ dễ dàng, thuận tiện hơn.
a. Hiểu biết về hệ máy PSX.
b. Hiểu biết về ngôn ngữ Assembly của PSX.
c. Hiểu biết, sử dụng thành thạo Debugger của PSX.



3.Khái quát về máy PlayStation


PlayStation (một số dịch phẩm Việt văn gọi là “trạm chơi” ) là tên của một loại máy chơi game, cũng là thương hiệu đã cầu chứng của hãng Sony. Những thông tin chung chung về hệ máy này thì người đọc có thể tự tìm hiểu qua Google chấm com, còn ở đây chỉ nói những nét khái quát từ khía cạnh kỹ thuật (liên quan đến hack dịch game) của nó.
Hai đặc điểm lớn nhất của PSX so với các thế hệ máy chơi game trước đó như Famicom, Super Famicom (Nintendō), Mega Drive (Sega),… là khả năng lưu trữ lớn do sử dụng công nghệ ổ đĩa CD-ROM/XA với khả năng lưu trữ dữ liệu (khác) và âm thanh trên cùng một đĩa, thay vì sử dụng cardtridge. Khả năng diễn toán của PSX lớn hơn nhiều vì sử dụng bộ vi xử lý 32 bit (sẽ đề cập bên dưới) nên đưa tới hiệu quả hình ảnh, âm thanh tốt hơn các hệ máy trước đó.
Vào cuối thập niên 80, công nghệ CD-ROM đã xuất hiện trên thị trường, nhưng ứng dụng còn chậm chạp, thì đến thập niên 90 của thế kỷ trước, Sony đã có một bước đi đúng với công nghệ này khi cho ra đời máy PSX. Xét từ khía cạnh lưu trữ dữ liệu, nếu máy Famicom và Super Famicom sử dụng cardtridge để lưu trữ hết các file cần thiết của game vào “một cục”, với dung lượng hết sức hạn chế (cao nhất là 48 Megabit đối với Super Famicom), thì công nghệ CD cho phép lưu trữ dữ liệu lên đến 660 Megabyte, và các file cần thiết để chạy game không bị dồn chung “một cục” mà được lưu trữ riêng biệt trên các sector. Dĩ nhiên trong thực tế, nhiều nhà sản xuất dùng giải thuật nén, mã hóa nên khi mở CD-ROM ra thì chỉ thấy 01 file duy nhất. Và cũng hiếm có game nào trên PSX sử dụng hết 660 Mb của đĩa. Chính vì từng file riêng biệt nên game PSX luôn tồn tại một thành phần quan trọng, gọi là “Table of Contents” (tạm dịch là mục lục nội dung) hay gọi tắt là TOC. Đây là thành phần ghi (đăng ký) nơi bắt đầu của các file nội dung. Nắm rõ thành phần này là một yếu tố quan trọng trong việc hack dịch game PSX, vì ta sẽ cần đến, thay đổi, đăng ký lại TOC trong trường hợp muốn mở rộng thêm dung lượng của bản dịch.

Đặc điểm thứ hai của PSX là khả năng diễn toán lớn. Sở dĩ được như vậy vì máy PSX sử dụng bộ vi xử lý R3000A 32 bit, ngôn ngữ lập trình MIPS với khả năng thực hiện hàng triệu lệnh mỗi giây. Tương đồng với PSX còn có máy Nintendō 64 (N64) với bộ vi xử lý R4000i, với khả năng diễn toán tốt hơn và nhiều lệnh hơn PSX một tí.

Ta hay nghe cụm từ “hệ điều hành 32 bit”, “hệ điều hành 64 bit”, Windows 32 bit,… Thực chất, đó chính là sức chứa của các Register của bộ vi xử lý. Có thể nói Register là hạch tâm của CPU. Đó là một phần của bộ vi xử lý, một vùng để lưu trữ bất cứ loại dữ liệu nào, bao gồm cả lệnh thực thi. Register là khu vực có thể viết (ghi) tự do giống như Ram, và có cấu tạo cho phép ghi nhanh chóng vì thường xuyên được sử dụng đến.
Bản thân từ “Regist” có nghĩa là “lưu trữ”, và “Register” mang nghĩa là thứ, đồ để lưu trữ thứ gì đó. Trong ngôn ngữ Assembly thì khi nói đến “lưu trữ thứ gì đó”, thì đó là lưu trữ giá trị.
Register của máy PSX có sức chứa 32 bit, có nghĩa là nó có khả năng lưu trữ, diễn toán dữ liệu trong phạm vi từ $00000000 cho đến $FFFFFFFF.
Ta cũng thường nghe cụm từ “đồ họa 8 bit”, hay “âm thanh 8 bit” khi nói đến hình ảnh và âm thanh của máy Famicom, hay “có vẻ giống” Famicom. Sở dĩ gọi như vậy là vì máy Famicom sử dụng Register chỉ có sức chứa 8 bit, nên chỉ có khả năng diễn toán trong phạm vi từ $00 cho đến $FF, hay 256 byte về độ rộng. Chính vì vậy nên hình ảnh và âm thanh của Famicom bị mất đi rất nhiều so với mong muốn của nhà lập trình. Còn máy Super Famicom sử dụng bộ vi sử lý 650C816 với Register 16 bit, gấp đôi so với Famicom nên hình ảnh và âm thanh trung thực, chi tiết hơn Famicom rất nhiều, nhưng kém hơn PSX với Register 32 bit.

Ngoài ra, cũng cần biết thêm PSX có Ram chính lên đến 2Mb và 1Mb cho Vram (Video ram). Hình ảnh hiển thị của PSX là 4:3, thích hợp với Tivi thời đó, với màn hình gần như là hình vuông, so với tỷ lệ 16:9 của màn hình Tivi bây giờ (thời điểm 2015). Độ phân giải của PSX thường là 256x240, 364x240, 320x240, 640x480. Độ phân giải tùy thuộc vào từng game, hệ màu của game. Nhìn chung ít có game nào lên đến 640x480 như Bloody Roar, còn đa phần game NTSC đều có độ phân giải 320x240, bao gồm cả FF9.


4.Ngôn ngữ Assembly

Assembly, viết tắt là Asm, dịch Việt văn là “hợp ngữ” hay đôi khi còn gọi nôm na là “ngôn ngữ máy”, là loại ngôn ngữ cấp thấp (bậc thấp) mà máy tính (không phải “máy vi tính”) có thể hiểu được và thực thi. Ngôn ngữ bậc cao (cấp cao) là ngôn ngữ mà con người có thể hiểu được dễ dàng, như Pascal, C,… Nhưng máy tính không thể hiểu được những loại ngôn ngữ này, vì vậy nên cần phải dịch code viết từ các loại ngôn ngữ cấp cao này sang ngôn ngữ cấp thấp để máy tính có thể thực hiện. Mỗi loại máy tính đều có cấu trúc khác nhau, nên chúng sử dụng ngôn ngữ Asm khác nhau. Chẳng hạn Famicom dùng ngôn ngữ 650C, Super Famicom dùng 650C816, PSX dùng MIPS,…

Thực chất, máy tính là loại thiết bị ngu đần gần nhất quả Đất. Nó không thể hiểu bất cứ thứ gì khác ngoài con số “0” và con số “1”, tương đương với hai trạng thái “tắt” và “mở” của bóng đèn. Do vậy, để yêu cầu tên đầy tớ ngu đần này làm việc thì ông chủ (con người) rất khổ sở. Thay vì nói
“Phát cho tao tiếng bíp” thì người chủ phải nói “0100010011100011000110”,
thay vì nói “tăng độ sáng cho màn hình lên mức 2” thì phải nói “1101101010100010101000101010101”, vân vân.

Nhưng nếu chủ mà nói chỉ toàn “0” và “1” như vậy thì chắc thà đập đầu vào tường, cắn lưỡi tự sát còn sướng hơn. Hai người nước khác nhau, không hiểu tiếng của nhau còn có thể ra hiệu, chỉ trỏ, dùng ánh mắt để truyền đạt cho nhau hiểu. Nhưng máy tính thì không có tay chân, mắt mũi lưỡi mồm, hay bất cứ thứ gì khác ngoài “0” và “1” trong bộ não lợn của nó.

Chính vì khổ còn hơn con chó như vậy nên người chủ mới cần đến người hùng Assembly, biệt danh là Asm. Thực chất anh chàng này làm nghề phiên dịch, vì có thể hiểu được cả tiếng người lẫn tiếng của thằng đần máy tính.
Chẳng hạn, đối với máy tính thì “100010” nghĩa là “nói to lên”, thì Asm sẽ dùng các chữ cái NTL để giúp con người hiểu được, “100100001010111” nghĩa là “cho mày nghỉ ngơi” thì Asm dùng các chữ cái CMN để diễn đạt cho người hiểu, “1100100101” nghĩa là “cút mẹ mày đi!” thì Asm dùng các chữ CMM.
Do đó, nếu người chủ muốn yêu cầu với máy tính “nói to lên”, rồi “cho mày nghỉ ngơi”, sau đó là “cút mẹ mày đi!” thì sẽ nhờ Asm bằng cách nói

NTL
CMN
CMM

Thì lúc này Asm sẽ dịch sang ngôn ngữ của máy là

100010
100100001010111
1100100101
để máy tính thực hiện tuần tự các mệnh lệnh của ông chủ.

Chính vì vậy nên có thể nói, Asm điều khiển tất cả mọi thứ mà máy tính thực hiện. Có bao giờ bạn đọc tự hỏi bên trong file .EXE là thứ gì? Nó là Asm.

Để giúp người đọc hình dung một cách cụ thể hơn về Asm, dưới đây là một đoạn mã trong game Mario trên máy Super Famicom với ngôn ngữ 65816. Phần bên tay trái, màu đỏ là lệnh, bên tay mặt, màu đen là comment (giải thích).
Dcb “INIT” Routine mở đầu
LDA#$00 Tải giá trị “0” vào Register A
STA $0DBF Ghi giá trị trong Register A vào vị trí $0DBF trong Ram
LDA#$00 Tải giá trị “0” vào Register A
STA$0FB3 Ghi giá trị của Register A (đang là 0) vào vị trí $0FB3
RTL Trở về Routine chính

Đoạn chương trình này cho thấy, giá trị ban đầu tại vị trí $0DBF trong Ram là 0, và địa chỉ này quản lý số đồng tiền của Mario. Tương tự, giá trị ban đầu của địa chỉ $0FB3 là 0, và địa chỉ này quản lý số mạng bonus của Mario. Như vậy, qua đoạn này ta thấy ban đầu Mario được cấp cho 0 đồng cắc và 0 mạng bonus.

Dcb “MAIN” Routine chính
INC$0DBF Tăng giá trị tại $0DBF lên 1 đơn vị
LDA$0DBF Tải giá trị tại $0DBF vào Register A
CMP#$64 So sánh giá trị trong Register A với 100
BEQ LABEL Nếu so sánh bên trên có kết quả bằng (=) thì nhảy sang Routine LABEL
LDA$0DBF Tải giá trị tại $0DBF vào Register A
BEQ LABEL2 Nếu so sánh bên trên có kết quả bằng (=) thì nhảy sang Routine LABEL2
RTL

Qua đoạn này ta thấy, số đồng cắc được tăng lên 1, và đến khi đạt giá trị 100 thì máy sẽ nhảy sang Routine LABEL và LABEL2.

LABEL
LDA#$00 Tải giá trị 0 vào Register A
STA $0DBF Ghi trá trị của Register A (đang là 0) và $0DBF
RTL

Qua Routine này, ta thấy giá trị tại $0DBF, địa chỉ quản lý số đồng cắc, bị chuyển về 0.

LABEL 2
INC$0FB3 Tăng giá trị tại địa chỉ $0FB3 lên 1 đơn vị

RTL


Qua Routine này, ta thấy số mạng bonus của Mario được tăng thêm 1.


Như vậy, qua cả 4 Routine là INIT, MAIN và LABEL và LABEL2 thì hiểu được ban đầu Mario có 0 đồng cắc. Mỗi khi Mario “ăn” thì số cắc tăng thêm 1, cho đến khi đạt 100 cắc thì số này chuyển về 0, và Mario được thêm 1 mạng bonus. Cho nên, nếu muốn hack sao cho Mario chỉ cần “ăn” 3 cắc là được thưởng 1 mạng thì chỉ cần sửa dòng

CMP#$64 thành CMP#$03 là được.

Trong ví dụ trên, LDA#$00 là cách viết theo lối phiên dịch của Asm, còn thực ra máy tính (bộ vi xử lý) sẽ hiểu là $A9 $00. Hay theo hệ nhị phân là 10101001 và 0. Trong đó $A9 được gọi là opcode (gọi tắt của operation code) còn $00 là tham số của opcode $A9. Tham số này được gọi bằng thuật ngữ operand. Bản thân opcode chỉ là con số, nên rất khó nhớ. Vì thế người ta thay bằng 3 chữ cái LDA (Load Accumulator) cho dễ nhớ, và những chữ cái đại diện cho opcode như vậy được gọi Mnemonic (nghĩa là hỗ trợ cho bộ nhớ).
※ Mỗi hệ máy khác nhau dùng mỗi kiểu ngôn ngữ Asm khác nhau. Bản thân các ngôn ngữ này cũng khác nhau như tiếng Việt khác tiếng Anh, khác tiếng Đức. Mỗi loại có những đặc điểm riêng mà chỉ có học mới biết. Nhưng khi đã nắm được một ngôn ngữ rồi thì việc học ngôn ngữ khác cũng khá dễ dàng. Giống như khi đã học được tiếng Phạn thì việc học tiếng La Tinh cũng khá nhẹ nhàng.



5.Debugger


Debugger bản thân nó là một phần mềm giả lập kèm theo chức năng Debug. Nó cho phép người dùng theo dõi giả lập (máy) đang thực thi những lệnh nào, Routine nào, và chuẩn bị làm những gì tiếp theo. Debugger cũng có ích trong việc theo dõi Vram, biết được những gì đang hiển thị trên màn hình, chúng được upload lên Vram từ đâu.

Có nhiều loại Debugger cho cùng một hệ máy, và mỗi loại có cách sử dụng khác nhau nhưng tựu trung đều dựa trên nền tảng Asm. Vậy nên để hiểu được Debugger thì cần phải nắm rõ Asm của hệ máy đó.

Sử dụng Debugger là một vũ khí lợi hại trong việc hack game. Cách sử dụng Debugger cũng như tìm chúng ở đâu, người đọc có thể hỏi Google chấm com.




No$psx là một trong số nhiều Debugger cho PSX.


6.Ngôn ngữ MIPS

MIPS là ngôn ngữ Asm của máy PSX. Hiện tại vẫn chưa có tài liệu hoàn chỉnh cho ngôn ngữ này, nhưng vì bộ vi xử lý của PSX cùng hệ với bộ vi xử lý của N64 nên có thể tìm đọc tài liệu Asm của N64 để hiểu được MIPS. Phần này chỉ giới thiệu những nét khái quát nhất về MIPS.

Đầu tiên, để máy thực hiện việc gì đó thì cần phải có chỉ thị, hay lệnh. Lệnh là thứ mà máy dùng để xử lý các giá trị được chứa trong các Register. Như đã nói trên, Register của PSX là 32 bit nên các giá trị này được phép dao động trong khoảng từ 0x00000000 cho tới 0xFFFFFFFF. PSX có tất cả 32 Register, trong đó có 29 Register được sử dụng tự do (từ đây về sau, Register X được viết tắt là rX) vì r0 luôn là 0, r29 lưu trữ offset của Stack pointer và r31 lưu trữ offset đặc biệt.

Mọi chỉ thị, hay lệnh trong MIPS đều là 32 bit, trong đó phần opcode chiếm 6 bit. Phần opcode này, hay mnemonic nếu viết theo lối phiên dịch cho người đọc, cho biết rõ tính chất của câu lệnh. Chẳng hạn, trong lệnh “quét nhà 5 phút” thì phần “quét nhà” là tính chất của lệnh, hay opcode, mnemonic, còn “5 phút” là tham số của lệnh, hay operand.

Nếu ngôn ngữ 65816 có các mnemonic được viết hoa toàn bộ thì các mnemonic trong MIPS đều viết thường.

Phần opcode luôn được đọc đầu tiên, sau đó mới đến phần còn lại của lệnh (tham số). Nhưng vì MIPS dùng lối sắp xếp dữ liệu theo trật tự Little endian nên bộ vi xử lý sẽ đọc một chuỗi liên tiếp 4 byte (hay còn gọi là 1 word) từ byte cuối cùng cho đến byte đầu tiên.

Ví dụ, dưới đây là một đoạn các lệnh trong Ram
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

Khi gặp đoạn dữ liệu này, con chip sẽ đọc
Word1= 03 02 01 00
Word2= 07 06 05 04
Word3= 0B 0A 09 08
Word4= 0F 0E 0D 0C

Trong đó phần bôi vàng là opcode. Qua đây cũng cần ghi nhớ, PSX đọc giá trị với trật tự đảo ngược theo lối Little endian. Đây cũng là đặc điểm chung của tất cả các máy console mà tôi biết.

MIPS có 3 kiểu lệnh chính, đó là kiểu lệnh J, kiểu lệnh I và kiểu lệnh R. Ở đây giới thiệu sơ qua về lệnh J, hay Jump. Lệnh này cho phép game đọc (nhảy đến) phần khác của code. Các lệnh J đều có đặc điểm là lệnh nằm ngay sau lệnh nhảy sẽ được thực thi ngay sau bản thân lệnh nhảy, rồi mới tới lệnh tại vị trí nhảy đến. Trong các lệnh nhảy, phần opcode 6 bit được đọc trước tiên, sau đó mới đến phần địa chỉ thuộc 26 bit còn lại. Giá trị của 26 bit được nhân với 4 để xác định offset của Ram cần nhảy đến.

Chẳng hạn, có mnemonic j (nhảy đến địa chỉ xác định) với opcode là $08.
Ví dụ dưới đây là một lệnh nhảy
01 02 03 08 là j 0x030201*4 = j 0xC0804

Qua đây cũng cần ghi nhớ, giá trị chia hết cho 4 là một đặc điểm của PSX.

Hai kiểu lệnh còn lại là I (Immediate) và R (Register). Kiểu lệnh I cho phép máy biên tập một Register với một giá trị xác định bởi con số 16 bit. Kiểu lệnh I liên quan đến Load, phân nhánh, điều kiện... Còn kiểu lệnh R cho phép máy biên tập các Register với giá trị được lưu trữ trong Register khác. Kiểu lệnh này liên quan nhiều đến cộng trừ nhân chia, shift byte...

Trên đây là những nét khái quát chung về ngôn ngữ Asm cũng như MIPS Asm. Đây là những kỹ năng lợi hại phục vụ cho việc hack game, dịch game. Người đọc quan tâm có thể tìm hiểu sâu hơn tại Google chấm com.



7. Làm việc với bộ nhớ



Học ở phổ thông thì chắc ai cũng biết Rom là gì và Ram là gì, và chúng khác nhau như thế nào. Lợi dụng Ram là điều quan trọng trong dịch game. Nếu như không lợi dụng Ram thì bạn sẽ mất rất nhiều thời gian trong việc tìm dữ liệu, chỉnh sửa trong Rom rồi load vào game. Như đã nói trên, Ram chính của máy PSX có dung lượng 2Mb, Vram là 1Mb trong khi Rom có thể lên đến 700Mb. Như vậy tìm dữ liệu ở đâu nhanh hơn, làm việc ở đâu dễ dàng hơn thì bạn đọc đã rõ.
Một ưu điểm nữa là khi làm việc trên Ram, ta có thể nhanh chóng thay đổi, chỉnh sửa lại những chỉnh sửa, thay đổi đã không mang lại kết quả ưng ý. Sau khi đã hoàn toàn toại ý thì có thể copy những chỉnh sửa, thay đổi này vào Rom. Nếu không dùng cách này mà thay đổi trực tiếp lên Rom, nếu thay đổi không mang lại kết quả ưng ý thì việc save và load khiến mất rất nhiều thời gian.
Thông thường, những gì cần thiết để thể hiện lên màn hình, để tính toán trong một đoạn game xác định đều nằm hết trong Ram và Vram. Để làm việc với bộ nhớ, có thể dùng những phần mềm can thiệp vào bộ nhớ như Cheat Engine hay Art Money đều được.
Ngoài ra, các loại giả lập cho console còn có một thế mạnh khác mà ta còn có thể lợi dụng như bộ nhớ. Đó là chức năng quick save. Người thường dùng giả lập thì hẳn không ai xa lạ với chức năng này.
Gợi ý: vì sao quick load có thể khôi phục toàn bộ nội dung của màn hình và những tính toán ngầm bên trong game ngay thời điểm ta dùng quick save? Có thể lợi dụng được gì ở nó?



8. Lập table



Nếu đã nắm vững lý thuyết về dịch game thì có lẽ không ai xa lạ với khái niệm table. Có thể nói, lập table là một trong những (nếu không muốn nói là một) quan trọng nhất của việc dịch game. Thành hay bại đều phụ thuộc vào table. Một sai sót nhỏ trong table có thể dẫn đến thất bại nghiêm trọng. Vì sao nói vậy?
Vì nếu lập table sai thì ta không thể dump (trích) đúng văn bản được, hay nghiêm trọng hơn là không chèn văn bản đúng vào game được. Nếu không có table, ta không thể đưa chữ vào game. Do đó nói table tuy nhỏ nhưng lại là xương sống của toàn bộ quá trình dịch game. Do vậy cần đầu tư nhiều thời gian cho khâu lập table. Bù lại, sau khi hoàn chỉnh thì gần như sẽ không còn phải động đến (làm việc với) nó trong suốt quá trình dịch nữa, chỉ việc sử dụng thôi.
Cơ bản là có 2 loại table. Một loại dùng để dump (trích) và một loại để insert (chèn) văn bản. Nếu ngôn ngữ nguồn và ngôn ngữ đích là một, thì có thể dùng chung một loại table. Đây là trường hợp khi ta muốn chỉnh sửa nội dung của một bản dịch hay một ngôn ngữ nào đó bằng chính ngôn ngữ đó. Trường hợp thường gặp hơn là ngôn ngữ nguồn và ngôn ngữ đích khác nhau, do đó bắt buộc table trích xuất và table chèn phải khác nhau. Tuy nhiên, chúng có thể giống nhau ở một mức độ nào đó (các ký tự, ký hiệu chung của cả 2 ngôn ngữ,…)
Một lý do khác để lập table là đa phần game console được mã hóa không theo bảng mã ASCII, nếu không có table thì khó lòng xác định được nội dung cần dịch nằm ở đâu trong Rom, và cũng không thể dịch nội dung đó sang ngôn ngữ đích.
Nếu game sử dụng bảng mã ASCII cho ký tự thì có thể không cần table, có thể xem và dịch trực tiếp bằng Hex editor, dù cách này dễ mang lại sai sót.
Có một hiểu lầm đáng tiếc, là nhiều người vẫn nghĩ việc dịch game đơn giản chỉ là bật Hex editor lên, load Rom rồi gõ lại nội dung bằng chính Hex editor. Cách này chỉ áp dụng được đối với những game sử dụng mã ASCII. Còn game không dùng mã ASCII thì rất khó áp dụng, và có thể dẫn tới nhiều sai sót và lỗi nếu không có kiến thức về mã ký tự. Chẳng hạn, bạn muốn chữ “ỡ” (o với dấu móc và dấu ngã) xuất hiện trong game. Khi gõ ký tự “ỡ”, Hex editor sẽ nhập $1EE1 vào trong Rom, tốn mất 16 bit trong khi game chỉ chấp nhận 8 bit cho mỗi ký tự. Việc này có thể dẫn đến những sai lệch có thể làm hỏng game.
Một table phải bao gồm đầy đủ 2 loại code, là code gọi ký tự và code điều khiển. Code gọi ký tự là những code mà khi gặp phải, game sẽ in ký tự lên màn hình. Còn code điều khiển là những code có chức năng nhất định, nhưng thường là “vô hình”. Chẳng hạn như code ngắt dòng, code kết thúc câu, code làm đổi màu chữ, code làm chữ chạy chậm lại, code phóng to/thu nhỏ chữ,…
FF9 là game sử dụng rất nhiều code điều khiển. Gần như trước mỗi câu thoại đều có code điều khiển không chức năng này thì cũng chức năng nọ. Trong số đó thì code kết thúc hội thoại là quan trọng nhất. Bởi nếu không có code kết thúc, game sẽ đọc từ chỗ bắt đầu cho tới hết dữ liệu, liên tu bất tận và không bao giờ dừng lại. 



9. Vận dụng Pointer


Pointer là một loại dữ liệu chỉ cho game biết phải đọc câu thoại, văn bản nào từ vị trí nào. Hầu như mọi pointer văn bản trong FF9 đều là 16 bit, nên mỗi pointer có thể chỉ được trong phạm vi từ $0000 đến $FFFF.
Nếu nói table là xương sống thì phải nói pointer là linh hồn của quá trình dịch game. Vận dụng pointer hợp lý sẽ giải quyết được vấn đề dung lượng mà không cần dùng đến giải thuật nén dữ liệu hay mở rộng Rom. Một bản dịch chất lượng phải hội đủ hai yếu tố là chuẩn xác và thăng hoa. Để dịch được chuẩn xác và thăng hoa, thường thì số ký tự sử dụng trong ngôn ngữ đích sẽ nhiều hơn trong ngôn ngữ nguồn. Do đó sẽ nảy sinh vấn đề dung lượng.
Chẳng hạn, dịch “cảm ơn” sẽ không đầy đủ ý như “cảm ơn nhiều” đối với câu nguồn “thank you very much”. Qua đây thấy rõ để dịch chuẩn và hay thì thường cần nhiều từ hơn dịch đại khái. Hãy xem vì sao việc vận dụng pointer giúp ta giải quyết được vấn đề dung lượng để dịch.

Ví dụ 1: Mỗi nhân vật trong FF9 đều có các chỉ số Str, Mgc, Def, Mdf, Eva. Dưới đây là dữ liệu của 2 nhân vật Vivi và Dagger (đứng kế tiếp nhau) nguyên bản trong game.

<Vivi><Str><Mgc><Def><Mdf><Eva><Dagger><Str><Mgc>< Def><Mdf><Eva>

Ở đây có 12 pointer, mỗi pointer chỉ đến từng vị trí bắt đầu của từng tham số. Pointer 1 chỉ đến tên của Vivi, pointer 2 chỉ đến Str của Vivi, pointer 3 chỉ đến Mgc của Vivi…
Khi viết lại, nếu vận dụng pointer thì ta có thể viết

<Vivi><Str><Mgc><Def><Mdf><Eva><Dagger>

Mặc dù cũng là 12 pointer, nhưng bằng cách cho pointer 2 và pointer 8 cùng chỉ về <Str>, pointer 3 và pointer 9 cùng chỉ về <Mgc>… thì ta đã tiết kiệm được một khoảng đáng kể.

Ví dụ 2: thông thường, câu/từ dịch ra ngôn ngữ đích dài hơn câu/từ cùng ý trong ngôn ngữ nguồn. Nhưng không phải lúc nào cũng vậy. Chẳng hạn ta có 2 câu liên tiếp nhau


Buddha is not a God
Buddha did not tell anything in his whole life 
Giả định mỗi ký tự, bao gồm cả khoảng trắng, là 01 byte thì rõ ràng, câu đầu có độ dài 19 byte, câu sau dài 46 byte. Do vậy, ta có tổng là 65 byte để dịch sang tiếng Việt.


Phật không phải là vị thần (26 byte)
Phật vốn vô ngôn suốt cuộc đời ngài (35 byte) 
Như vậy có thể thấy câu đầu tuy dịch sang tiếng Việt chiếm nhiều ký tự hơn câu gốc, nhưng câu sau lại ít ký tự hơn, và tổng số byte cho bản dịch là 61 byte, thừa sức đáp ứng yêu cầu đặt ra (trong vòng 65 byte).
Nếu như không dùng pointer thì bản dịch sẽ trông như


Phật không phải là vị thần
vị thần ốn vô ngôn suốt cuộc đời ngài 
Vì sao có sự đứt đoạn ở câu số 2? Vì câu đầu trong ngôn ngữ nguồn chỉ có 19 byte trong khi câu dịch chiếm 26 byte, tức dài hơn 7 byte và 7 byte này lấn sang vị trí bắt đầu của câu thứ 2. Hoặc nếu ngắt ở câu đầu thì sẽ như thế này
Phật không phải là
Phật vốn vô ngôn suốt cuộc đời ngài
Cả hai trường hợp trên đều dẫn đến việc ngữ nghĩa thể hiện không đầy đủ. Bằng việc sử dụng pointer, ta định nghĩa lại vị trí bắt đầu của câu số 2 lùi về sau 7 byte, nên sẽ thể hiện được đầy đủ là


Phật không phải là vị thần 
Phật vốn vô ngôn suốt cuộc đời ngài
 
Ví dụ 3: ta có một số Item được sắp xếp liên tiếp như sau
Kim_cương<end>Kiếm_Kim_cương<end>Búa_sắt< end>Cung_vàng<end>
Ta có 4 pointer chỉ về 4 vị trí bắt đầu của từng món đồ. Nếu vận dụng pointer hợp lý, ta có thể viết là
Kiếm_Kim_cương<end> Búa_sắt<end>Cung_vàng<end>
Với pointer 1 chỉ từ “Kiếm”, game sẽ đọc nguyên cụm là “Kiếm_Kim_cương” và pointer 2 chỉ từ “Kim”, nó sẽ đọc từ đó đến hết cụm, là “Kim_cương”.



10. Đối tượng làm việc

FF9 là game PSX, nên dĩ nhiên là được lưu trữ vào CD-Rom. Nếu cho vào ổ đĩa CD/DVD của máy tính thì ta thấy có thư mục gốc bao gồm nhiều file và thư mục khác. Tuy nhiên, nếu tải file .Iso hay .bin từ Internet mà người ta đã rip từ CD ra thì ta chỉ thấy là một file duy nhất. Nhưng thực sự dữ liệu của FF9 hay bất kỳ game PSX nào khác, đều không phải là một file duy nhất mà là một tổ hợp nhiều file.
Có thể dùng những phần mềm mở CD-Rom như Cdmage để xem và xử lý. Dưới đây là danh sách những file/folder trong đĩa CD FF9.

• Folder OPENING: chứa file FMVD001.STR
• Folder SEQ01: chứa các file .STR
• Folder SEQ02: chứa các file .STR
• Folder SEQ03: chứa các file .STR
• FF9.IMG
• SLPS_020.00 (đối với bản tiếng Nhật)
• SYSTEM.CNF





Các file có phần mở rộng .STR đều là định dạng video của PSX. FMVD001.STR trong thư mục OPENING chứa đoạn video mở đầu game. Ta có thể chuyển đổi .STR sang .avi để xem trên máy tính, thêm phụ đề bằng các phần mềm chuyên dụng rồi chuyển ngược lại sang .STR để chơi trên PSX. Tuy nhiên video của FF9 hầu như không có tiếng nói nên không cần thiết phải thêm phụ đề như một số game RPG khác.
File FF9.IMG là một trong hai đối tượng làm việc chính khi bắt đầu dịch thuật. File này chứa gần như mọi thông tin, dữ liệu chính yếu của game. Font chữ, hầu hết hội thoại, hình ảnh trong game, các event,… đều nằm trong FF9.IMG.
File SLPS là file đặc trưng của game trên PSX và luôn hiện diện. Con số theo sau SLPS là số ID của game. Do vậy cùng là FF9 nhưng bản tiếng Nhật có số khác với các phiên bản ngôn ngữ khác. Khi game chạy, file SLPS luôn được đọc vào bộ nhớ, và nó chứa một phần dữ liệu thường xuyên được truy cập trong game.
Đối với FF9 thì file SLPS chứa thông tin về hệ thống Menu, text giải thích trong Menu. Một số text nằm trong FF9.IMG lại có pointer nằm trong SLPS.
File SYSTEM.CNF chứa thông tin về hệ thống, và gần như không dính dáng tới dữ liệu game.
Các phần mềm biên tập CD đều có chức năng trích file riêng lẻ từ CD để chỉnh sửa, sau đó import trở lại.



11. Cấu trúc game

Có vẻ như đây là phần không liên quan gì đến việc dịch game, nhưng thực ra lại liên quan mật thiết khi bạn đã đạt được một mức độ nhất định nào đó trong mảng này. Như đã nói nhiều lần, dịch game tức là hack game, chứ không đơn thuần là dịch văn bản thuần túy như dịch sách báo, tiểu thuyết. Do đó người dịch cũng cần nhiều kiến thức về mảng cấu trúc, lập trình của game (Assembly), dù nhiều nhóm dịch phân chia người dịch chỉ cần dịch, không cần phải biết kỹ thuật. Còn đối với người phụ trách mảng kỹ thuật, việc nắm rõ cấu trúc game là một vũ khí hết sức lợi hại, nó hỗ trợ tối đa trong việc hack dịch.
Có thể nói yếu tố quan trọng nhất của cấu trúc game là các Event, hay gọi nôm na là “suột” của cả chương trình. Event là một sự kiện nào đó xảy ra trong game. Lấy ví dụ với đoạn mở đầu trong FF9, cảnh Zitane (bản tiếng Anh là Zidane) xuất hiện với ngọn nến trong khoang tàu Prima Vista. Sau khi thắp nến giữa căn phòng, đám trộm Tantalus xuất hiện và xảy ra trận chiến với thủ lãnh Baku. Đây là một loạt những Event liên tiếp nhau. Nhưng nếu mở rộng định nghĩa thì bất cứ sự chuyển biến lớn nhỏ nào trong game cũng đều là Event hết, từ việc di chuyển nhân vật, bật Menu cho tới kích hoạt các trận đánh, hội thoại.
Event chính là thứ làm nên câu chuyện, từ mọi yếu tố nhỏ tới lớn, gắn kết chúng với nhau. Nhưng một mình Event thì chưa đủ, mà người ta còn phải xây dựng một kho dữ liệu đồ sộ để gọi ra trong Event. Chẳng hạn, người ta xây dựng hình ảnh (đồ họa) của nhân vật Zitane bước sang trái, sang phải, đi lên, đi xuống… và chứa nó vào kho dữ liệu. Khi nhấn nút sang trái, phải…. trên Controller, tín hiệu được truyền vào phần xử lý Event và lập tức gọi ra hình ảnh sang trái, phải… đã xây dựng sẵn trong kho dữ liệu. Do vậy màn hình sẽ hiển thị hình ảnh nhân vật Zitane bước theo hướng nút bấm.
Một ví dụ khác, nhà sản xuất viết sẵn các đoạn hội thoại giữa các nhân vật, cũng như hình ảnh động tác (giơ tay, lắc đầu,…) của những nhân vật đó rồi chứa vào kho dữ liệu. Thực chất thì những dữ liệu này hoàn toàn không tự thể hiện được nó, mà phải cần đến Event. Khi đến đoạn cần xuất hiện, máy sẽ đọc nội dung của Event và thi hành lần lượt những lệnh trong đó, như gọi hình ảnh nhân vật A trong kho dữ liệu, di chuyển A sang phải 3 bước, gọi hội thoại 1 của A và cho xuất hiện 3 giây. Sau đó gọi hình ảnh của nhân vật B di chuyển tới gần A, lắc đầu, gọi hội thoại 1 của B,….. Một loạt những chuyển biến này được gắn kết chặt chẽ với nhau trong nội dung Event.
Do vậy, việc nắm rõ Event tức là nắm rõ cấu trúc của game. Khi đó ta có thể thay đổi hoàn toàn nội dung của game, từ hình ảnh hiển thị cho tới hội thoại, âm thanh và nhiều yếu tố khác. Bản thân việc dịch (thay đổi) hội thoại trong game chỉ là một phần nhỏ của việc thay đổi Event.



12. Mở rộng dữ liệu

Phần trên có nói, ngoài khả năng ngôn ngữ của người dịch thì yếu tố quan trọng khác để có một bản dịch hay chính là việc có thể viết (dịch) những gì muốn viết vào game hay không. Có thể bạn có khả năng dịch rất hay trên “giấy tờ”, nhưng vì dung lượng hội thoại không cho phép nên buộc phải dùng những cách diễn đạt khác ngắn gọn hơn cho phù hợp, đi kèm với những mất mát về ý nghĩa và sắc thái của câu nói. Do đó điều kiện cần để có một bản dịch hay là phải viết được những gì mình muốn viết.
Mở rộng giới hạn dữ liệu là một trong những cách để có thể diễn đạt hết ý mình muốn. Nếu đa phần game trên PC không bị hạn chế dung lượng chứa, thì đa phần game trên console như Famicom, Super Famicom, PlayStation, Mega Drive, GameCube.…. đều bị giới hạn dung lượng bởi thiết bị lưu trữ vật lý (Cardtridge, CD, DVD…) và cấu hình phần cứng của hệ console đó. Do đó, không gian lưu trữ của game console “chật hẹp” hơn game PC rất nhiều, nên giải quyết việc này cũng phức tạp hơn. Nếu game đã sử dụng hết không gian lưu trữ tối đa được cho phép trên thiết bị vật lý, thì về lý thuyết là bạn không thể nới giới hạn đó thêm được nữa. Chẳng hạn, nếu gặp một game trên PSX có dung lượng dưới 660 Megabyte thì có thể lợi dụng phần còn trống để chứa thêm dữ liệu mới. Nhưng nếu game đã dùng hết 660 Mb thì sẽ không thể mở rộng thêm được nữa.

Tuy nhiên, nếu chỉ đơn thuần là dịch phần chữ thì cũng không đáng lo ngại lắm. Vì văn bản (text) là một trong những thứ có dung lượng nhỏ nhất trong dữ liệu game. Tùy game, nhưng thường thì mỗi byte tương đương với một ký tự. FF9 sử dụng tối đa $FFFF byte cho mỗi kho chứa text, tức là bạn được quyền dịch sang ngôn ngữ đích tối đa là 65535 ký tự. Nhưng thực tế thì con số này ít hơn vì trong mỗi kho dữ liệu đó còn chứa thêm code Event điều khiển hội thoại và nhiều thứ khác. Thực tế thì hầu như trong game luôn tồn tại những dữ liệu không cần thiết, không bao giờ xuất hiện trong quá trình chơi. Đấy là những dữ liệu được làm ra trong quá trình phát triển, nhưng bị loại bỏ trong quá trình biên tập. Có thể đó là hình ảnh, âm thanh, hội thoại hay những đoạn mã tính toán thứ gì đó. Ta có thể lợi dụng không gian chứa những thành phần này để làm nơi chứa dữ liệu cần của mình. Hoặc như FF9, bạn có thể mở rộng giới hạn $FFFF byte cho mỗi kho thoại thành con số lớn hơn. Nhưng cả 2 cách này đòi hỏi phải viết lại nhiều đoạn mã, viết thêm mã và khai báo địa chỉ của khu vực dữ liệu mới. Chỉ nên thực hiện việc mở rộng kho dữ liệu khi bạn quá rành về cấu trúc, Event và Asm của hệ máy đó.

13. Nén dữ liệu

Nếu việc mở rộng dữ liệu đòi hỏi nhiều kiến thức và ít an toàn, nhiều nguy hiểm dẫn tới lỗ, đơ game… thì việc nén dữ liệu lại đơn giản hơn và an toàn hơn.
Nén tức là nhồi nhét càng nhiều thứ càng tốt vào một vật chứa. Cụ thể trong mảng dịch game thì đó là việc thể hiện càng nhiều chữ với số byte càng ít càng tốt. Có nhiều phương pháp nén. Chẳng hạn sau khi viết/dịch xong một kho hội thoại với dung lượng 1000 byte, ta dùng giải thuật nén chỉ còn 100 byte. Nhưng lúc này đòi hỏi phải có thêm phần mã để giải nén khi máy đọc tới đoạn thoại đó. Ngoài ra, còn 2 cách nén phổ biến khác trong mảng dịch game như dưới đây.

a. Dual Tide Encoding (DTE): nếu thông thường, mỗi đơn vị byte thể hiện một ký tự thì với DTE, mỗi đơn vị byte thể hiện được hai ký tự. Có nghĩa là dung lượng thoại sẽ giảm một nửa với DTE.
b. Multi Tide Encoding (MTE): mỗi đơn vị byte thể hiện được nhiều ký tự, một câu, hay nhiều câu…. Cách nén này mang lại hiệu quả rất lớn nếu vận dụng đúng cách. Với MTE, ta xây dựng một thư viện chứa những từ, cụm từ hay câu thường được sử dụng trong game. Với mỗi đơn vị byte đặc thù chỉ đến một đơn vị từ/cụm từ trong thư viện đó, ta có thể tiết kiệm đáng kể dung lượng. Chẳng hạn, nếu bình thường cụm từ “xin lỗi” chiếm 7 byte, và được lặp đi lặp lại nhiều lần thì với việc xây dựng thư viện chứa từ này và cho một byte đặc thù chỉ vào đó, thì mỗi khi màn hình thể hiện cụm từ “xin lỗi” thì ta chỉ mất 1 byte mà thôi.

Tuy đơn giản hơn cách nén đầu tiên, nhưng cả DTE và MTE đều yêu cầu kiến thức về Asm để thực hiện. Đối với một số game thì nhà sản xuất đã viết sẵn mã DTE và MTE, ta chỉ việc tìm đến và thay đổi nội dung theo ý mình. Việc này đơn giản hơn những game không có sẵn mà ta phải viết mới. FF9 bản Nhật/Anh ngữ không có sẵn mã DTE hay thư viện MTE, nhưng ta vẫn có thể nén dữ liệu như kiểu MTE một cách đơn giản như đề cập đến ở phần sau.




Phần chuyên sâu



14. Font chữ

Một trong những việc hàng đầu cần làm khi dịch game là xác định font chữ và thay đổi nó. Hầu như mọi game Nhật Bản, game Tây phương đều sử dụng bộ font không chứa ký tự có dấu tiếng Việt, nên khi dịch những game này thì cần phải thay đổi sang font có thể hiển thị tiếng Việt. Và font chữ cũng là phần mà nhiều người hiểu lầm, hiểu lẫn lộn nhất.
Có rất nhiều ý kiến hỏi, đại loại như, “tại sao tôi mở file game bằng Hex editor, đã tìm thấy phần thoại nhưng gõ tiếng Việt lại bị lỗi hiển thị trong game?”
Việc này liên quan đến sự khác biệt giữa font máy tính và font của các game console. Phần bên giải thích rõ hơn cho phần đã bàn ở mục 8. (lập table).

Font PC và font console: ngày nay, các máy tính cá nhân và game dành riêng cho loại máy này thường sử dụng font vector, trong khi phần lớn game console sử dụng loại font bitmap, tức là mỗi ký tự là một dạng hình ảnh. Và font cho PC có nhiều loại, mỗi loại có những đặc tính chức năng khác nhau chứ không đơn thuần là khác nhau về mặt thẩm mỹ. Chẳng hạn, bộ font ANSI chỉ gồm các ký tự cơ bản, một số dấu câu chứ không có đầy đủ những ký tự có dấu của tiếng Việt, hay chữ Hán, chữ Kana trong tiếng Nhật…. Còn bộ font Unicode được dùng cho các ngôn ngữ không phải là ngôn ngữ Tây phương thông thường, nên nó bao hàm đầy đủ những ký tự cần thiết của tiếng Việt, tiếng Hoa, tiếng Nhật, tiếng Thái…. Trong khi đó thì bộ font cho game console chỉ chứa những ký tự mà bản thân game dùng đến. 

Tuy nhiên, ngoài việc là một tập hợp những ký tự (ở dạng vector hay bitmap) và mặt thẩm mỹ (ngoại quan) ra thì còn một yếu tố quan trọng nữa để xác định bộ font, đó là dạng thức encoding của nó. Có thể hiểu encoding của một bộ font là việc gán một giá trị nào đó cho mỗi ký tự trong font. Chẳng hạn, theo lối encoding tiêu chuẩn ASCII thì ký tự M có giá trị là $4D. Đối với những ký tự cơ bản từ A, a cho đến Z và z thì giá trị của chúng là như nhau ở mọi bộ font cho PC. Tuy nhiên, đối với những ký tự “lạ” (hiếm gặp, như ký tự có dấu tiếng Việt) thì tùy vào lối encoding mà chúng có giá trị khác nhau.
Ví dụ: ký tự “â” trong bộ font Unicode có giá trị là $1EA5. Tức là khi máy tính gặp giá trị này thì nó sẽ thể hiện “â” ra màn hình. Trong khi đó, nếu theo lối encoding Unicode-UTF8 thì ký tự “â” chiếm 3 byte, là $E1BAA5. 

Tuyệt đại đa số game console sử dụng lối encoding của riêng nó, không theo chuẩn như những bộ font cho PC và cũng không có game nào giống game nào. Do đó, khi bạn gõ ký tự “M” bằng Hex editor vào game thì dữ liệu được nhập vào là $4D, nhưng giá trị này lại thể hiện một ký tự khác trong game. Đây là một trong những điều khiến việc dịch game cho console khó khăn hơn dịch game cho PC. 

Bộ font cho game console là một tập hợp những hình ảnh ký tự đứng cạnh nhau và được encoding sao cho mỗi giá trị hex chỉ đến mỗi ký tự trong đó. Tức là tùy vào giá trị mà máy đọc được, nó sẽ thể hiện ra màn hình ký tự thứ bao nhiêu trong bộ font chứ không quan tâm đó là ký tự gì. Do vậy, khi dịch game console, ngoài việc sửa ngoại quan của font chữ thì còn phải nắm rõ lối encoding của nó như đã đề cập ở mục 8. (lập table).

Font của FF9: thực chất là một dạng hình ảnh với định dạng TIM của Sony. Có thể dễ dàng tìm thấy bộ font của FF9 bằng các phần mềm chuyên dụng như Tim Viewer. Nhưng bộ font thực sự được sử dụng trong game không thể phát hiện được bằng Tim Viewer, vì nó đã bị loại bỏ phần header của định dạng tim nên phần mềm không phát hiện được. Bộ font thực nằm ở $ 321836~$ 330D40 trong file FF9.IMG.



Sau khi thay thế phần chữ trong bộ font thì bạn sẽ nhận thấy hội thoại lúc này là một mớ hỗn độn không ý nghĩa gì. Thuật ngữ của dân dịch game gọi đây là “cavespeak” (tiếng mọi) vì tuy phần ký tự đã thay đổi nhưng phần trật tự sắp xếp (ngữ pháp) của ký tự vẫn giữ nguyên như ở ngôn ngữ nguồn, nên ta thấy nó hỗn độn và vô nghĩa ở ngôn ngữ đích. Do vậy, việc tiếp theo là chỉnh sửa lại trật tự này thành câu cú có nghĩa ở ngôn ngữ đích.


15. Độ rộng ký tự

Người để ý sẽ nhận thấy mỗi ký tự La Tinh có độ rộng khác nhau, chẳng hạn chữ “i” thì hẹp hơn chữ “a”, còn các ký tự Hán hay Kana trong tiếng Nhật có độ rộng gần bằng nhau. Và một yếu tố quan trọng nữa để cấu thành nên bộ font chính là độ rộng của từng ký tự trong đó.
Nếu font thể hiện ra màn hình độ rộng của từng ký tự là riêng biệt thì đó là font variable width (độ rộng biến thiên), hay tên chính thức là proportional font. Còn bộ font thể hiện ra màn hình độ rộng chung nhất cho mọi ký tự có tên là fixed width (độ rộng cố định) hay tên chính thức là mono-spaced font. Dĩ nhiên là để thể hiện các ngôn ngữ dùng chữ cái La Tinh thì proportional font cho tính thẩm mỹ cao hơn là mono-spaced font.

Nhưng bộ font với độ rộng các chữ đều nhau lại thích hợp với tiếng Nhật nên chúng thường được sử dụng cho những game này. Khi dịch sang ngôn ngữ dùng chữ cái La Tinh, cần phải thêm code điều chỉnh lại độ rộng của từng ký tự trong font. Nhưng cũng có một số game tiếng Nhật dùng proportional font để thể hiện, trong đó có FF9. Nên ta chỉ cần tìm tới đoạn mã chỉnh độ rộng của ký tự và sửa đổi lại theo ý mình.

Phần dữ liệu độ rộng biến thiên của từng ký tự trong FF9 nằm ở file FF9.IMG và bắt đầu tại $321830 đối với bản tiếng Nhật. 




Hình ảnh trong một game tôi dịch khi không dùng proportional font




Và khi có dùng proportional font


Mỗi một ký tự trong bảng font của FF9 được xác định bằng 4 yếu tố, mỗi yếu tố là 1 byte trong phần dữ liệu độ rộng: tọa độ X, tọa độ Y của ký tự trong bản font, độ rộng của ký tự đó, khoảng cách của nó với ký tự tiếp sau. Việc chỉnh sửa độ rộng giúp text được hiển thị đẹp hơn, và có nhiều không gian trống hơn trong những nơi chật hẹp như Menu. So sánh 2 hình ảnh dưới đây.




Ngoài ra, ta có thể lợi dụng độ rộng của mỗi ký tự để thực hiện nén phần thoại theo kiểu DTE một cách đơn giản mà không cần phải có kiến thức về Asm.


15. Các mục liên quan đến Menu

Bao gồm chữ hiển thị trong Menu, tên Item, tên Ability, địa danh, text giải thích cho Item, Ability…. Đây là phần hơi rườm rà vì chúng không nằm tập trung ở một nơi mà rải rải nhiều nơi. Có những phần text và Pointer lại nằm ở những file khác nhau. Có thể tìm chúng một cách đơn giản nhờ table và Windhex. Dưới đây là liệt kê một vài mục tiêu biểu.

+ Command: trong FF9.IMG, text ở $829D9-$82EA2 (Pointer 16 bit 827A4,827A6-829CE,829CD)
+ Mô tả Item trong trận đấu: text và Pointer ở FF9.IMG $811CC-$82593 (Pointer 16 bit $82598-$82797)
+ Text trong Menu trang bị ở IMG $E47C0-$E4842 (Pointer 16 bit $E47A0-$E47BC)
+ Giải thích Item trong Menu: text ở file FF9.IMG trong khi Pointer lại nằm ở file SLPS_020.00. Text: $EDAC8-$EFE76, Pointer 16 bit: $5971E-$5A90D, cách quảng 10 byte.
+ Tên Item quan trọng: text và Pointer đều nằm ở SLPS: $5B0F8-$5B495 (Ptr 16 bit $5B618-$5BE11)
+ Giải thích cho Item quan trọng: text ở IMG và Pointer ở SLPS. Text: $102DF4-$103A6D. Pointer 16 bit: $5B61A-$5BE13, cách quảng 6 byte.
+ Nội dung của Item quan trọng: text ở IMG và Pointer ở SLPS. Text: $103B20-$106320, Pointer 16 bit: $5B61E-$5BE0F, cách quảng 6 byte.
+ Tên bài: text và Pointer đều ở IMG $B9390-$B97A9 Ptr 16 bit $B92BC-$B938D, cách quảng 2 byte.
+ Thông tin trong trận đánh: tất cả ở file IMG. Text: $B9390-$B97A9 Ptr 16 bit: $B92BC-B938D, cách quảng 2 byte.
+ Thông tin sau trận đánh: tất cả ở file IMG. Text: $7D5A4-$7D732 Ptr 16 bit: $7D504-$7D5A1, cách quảng 2 byte.

Ngoài ra còn rất nhiều phần liên quan đến Menu. Tất cả chúng đều dùng Pointer 16 bit, trừ phần địa danh không có Pointer.


16. World và Field

World và Field là 2 khái niệm quen thuộc đối với series Final Fantasy. World là thế giới bên ngoài, khoảng không bên ngoài các Field và hàm chứa Field. Field là những khoảng không gian nhỏ hơn, nơi người chơi không đụng độ quái vật ngẫu nhiên. Có thể đó là các thành phố, làng mạc, nhà cửa trong game. Toàn bộ dữ liệu ở World và Field đều nằm trong FF9.IMG.

World
Text hiển thị ở World chủ yếu là phần thoại với Möguri giúp Save game và một số thông báo như điều khiển Chocobo, điều khiển phi thuyền. Trong mỗi đĩa có tất cả 15 kho dữ liệu chứa văn bản hiển thị ở World, và tất cả chúng đều có cấu trúc chung như sau:

<Pointer chức năng><Kích thước khung thoại><Pointer đến text><00>
<Text hiển thị>

Trong đó:
+Pointer chức năng: chỉ đến những phần mã đặc biệt như chỉnh thời gian hiển thị khung thoại, vị trí xuất hiện…. Nếu không có yêu cầu đặc biệt thì giá trị của Pointer này đồng nhất với giá trị của Pointer chỉ đến phần text.
+Kích thước khung thoại: mã điều chỉnh độ dài, rộng của khung thoại.
+Pointer đến text: mỗi Pointer chỉ đến mỗi câu xuất hiện ở phần <text hiển thị>.
+Text hiển thị: là văn bản xuất hiện ở World khi có Event. Trong phần này luôn chứa địa danh và Pointer chèn luôn trong phần text.

+ World map1: $6ED208-$6EE3BF (Ptr 16 bit $6ECF38-$6ED205, cách quảng 02 byte)
Embeded ptr:$6ED20B-6ED284 
+ World map2: $7013E0-$702597 (Ptr 16 bit $701110-$7013DD, cách quảng 02 byte)
Embed ptr $7013E3 -$70145C 
+ Worldmap3 $7180E4-$71929B (ptr $717E14-$7180E1)
Embed ptr 7180E7-718160
+ Wordmap 4 $739194 -$73A34B (ptr $738EC4-$739191)
Embed ptr $739197-739210
+ Worldmap 5 $7429F0-743BA7 (ptr $742720 -$7429ED)
Embeded ptr $7429F3-$742A6C 
+ Worldmap 6 $7631EB-$76439F (ptr $762F18- $7631E5)
Embeded ptr $7631E8-$763264
+ Worldmap7 $7755C0-$776777 (ptr $7752F0 -$7755BD)
Embeded ptr $7755C3-$77563C
+ Worldmap8 $7975AC-$798763 (ptr $7972DC -$7975A9)
Embeded ptr $7975AF-$797628
+ Worldmap9 $7B94E0-$7BA697 (ptr $7B9210-$7B94DD)
Embeded ptr $7B94E3-$7B955C
+ World10 $7DB7D0-$7DC987(ptr $7DB500-$7DB7CD)
Embeded ptr $7DB7D3-$7DB84C
+ World11 $7F346C-$7F4623(ptr $7F319C-$7F3469)
Embeded ptr $7F346F-$7F34E8
+ World12 $80B430-$80C5E7 (ptr $80B160-$80B42D)
Embeded ptr $80B433-$80B4AC
+ World13 $81C1D0-$81D387 (ptr $81BF00-$81C1CD)
Embeded ptr $81C1D3-$81C24C
+ Worldmap14 $83D18C-$83E343 (ptr $83CEBC-$83D189)
Embeded ptr $83D18F-$83D208
+ Worldmap15 $83D18C-$83E343 (ptr $85E6BC-$85E989)
Embeded ptr $85E98F-$85EA08


Field
Cũng như FF8, FF9 chứa tất cả hội thoại xuất hiện trong cùng Field vào chung một kho dữ liệu bất chấp thứ tự xuất hiện. Chẳng hạn, kho dữ liệu chứa text xuất hiện ở Alexandria bao gồm cả phần text ở cả 4 đĩa.
Cấu trúc sử dụng cũng như ở phần World.
<Pointer chức năng><Kích thước khung thoại><Pointer đến text><00>
<Text hiển thị>

Trong phần <Text hiển thị> hàm chứa Pointer chỉ đến phần tên của các Möguri.
Dưới đây là một vài liệt kê.

+ Prima Vista1:$64AC3C-$64D880 (Ptr $64A024, cách quảng 02 byte)
+ Alexandria: $671594-$676162 (Ptr $670824 -$671591)
+ Thành Alexandria: $650AB4-$653FB6 (Ptr $650024- $650AB1)
+ Khu rừng ma: $65701C-$65982A (Ptr $656824-$657019)
+ Hang băng: $65C6BC-$65E850 (Ptr $65C02C-$65C6B9)
+ Prima Vista2: $6794FC- $67D588 (Ptr $678824-$6794F9)
………
Trong phần dữ liệu ở Field luôn có những phần hội thoại “ẩn” vốn được viết ra nhưng lại bị loại bỏ ở khâu biên tập. Ta có thể phục hồi lại những câu thoại này bằng cách chỉnh sửa phần Event.


17. Tổng kết

Trên đây là 16 mục về việc dịch thuật FF9. Để thực hiện được bản dịch theo hướng dẫn này, người đọc cần phải nắm rõ những kiến thức cơ bản về dịch game như đã nói ở phần đầu. Khi đã nắm rõ thì kết hợp với hướng dẫn này, người đọc không những dịch được FF9 sang thứ tiếng mình muốn, mà còn có thể áp dụng những điều ở đây vào trong nhiều game khác, cho những hệ máy khác.





Hình ảnh khi dịch hoàn chỉnh

http://youtube.com/Yugisokubodai
http://gokuraku-shujo.blogspot.com/search/label/Game



Không có nhận xét nào:

Đăng nhận xét