Bài viết: Asm65816

Nhiều bạn PM hỏi tôi cách dịch game, tôi trả lời cứ đọc mấy bài hướng dẫn tôi viết. Và câu hỏi mà tôi hay nhận được nhất là:

- Giúp em cách gõ tiếng Việt trong game
- Nó (game) không hỗ trợ Unicode, em gõ tiếng Việt nó toàn ra ký tự gì đâu
- ......

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

Đại loại là nhiều vấn đề liên quan tới việc hiển thị dấu tiếng Việt trong game.

Bài viết này tôi mượn Captain Tsubasa trên SFC để minh họa cụ thể nhất quá trình dịch một game từ tiếng ABCXYZ sang tiếng Việt như thế nào, áp dụng những nguyên tắc cơ bản mà tôi từng giới thiệu trong bài hướng dẫn dịch game console/PC và nhiều bài khác. Bài này cũng sẽ đi sâu vào phân tích ở góc độ Assembly để giúp người đọc hiểu cặn kẽ hơn những gì có trong game.


Chuẩn bị

Để theo được bài viết này, bạn cần chuẩn bị một số thứ tối thiểu như sau:

1. Kiến thức về hệ nhị phân (Binary, Bin) và hệ thập lục (Hexadecimal, Hex), kiến thức về bit và byte. Không nhắc lại ở đây vì những bài viết về hai hệ số này đã tràn ngập Google rồi, tôi không tốn thời gian gõ lại làm gì.

2. Một chút thời gian rãnh. Không nhiều lắm, nhưng đủ để đọc hết bài viết này và làm theo. Có thể chia thành nhiều kỳ, số kỳ không hạn chế, tùy vào độ rãnh (háng) của bạn.

3 Giả lập kiêm Debugger để chạy game SNES. Trên Net có kha khá, nhưng khuyên dùng Snes9X. Tải về tại đây (click vào). Cũng có thể dùng Bsnes plus.

4. Rom Captain Tsubasa III, tiếng Nhật.

5. Trình Hex Editor. Có vô vàn, nhưng tôi hay dùng Stirling vì sự tiện dụng của nó. Tải bản tiếng Việt của Stirling tại đây (click vào). Ngoài ra cũng cần dùng Windhex của tác giả Bongo, chủ yếu để đọc text trong Rom. Tải tại Google.


6. Trình assembler cho Snes: có kha khá, nhưng tôi dùng Xkas. Google để tải về.

7. Lunar Address, tiện ích chuyển đổi giữa địa chỉ PC và địa chỉ SNES. Tải về tại đây (click vào).

8. Lunar Expand, tiện ích để mở rộng rom SNES.

9. Cần thêm YY-CHR để biên tập font.

10. Search Relative để dò tìm tương đối. Tải tại Google.com

11. Ứng dụng trích xuất text dựa trên table. Có khá nhiều, nhưng tốt nhất là Cartographer. Tải từ Google.com. Nếu có khả năng, hãy tự code.

12. Ứng dụng chèn text vào game dựa trên table. Có khá nhiều, nhưng tốt nhất là Atlas. Tải từ Google.com. Nếu có khả năng, hãy tự code.

12. Cuối cùng, à chưa phải cuối cùng. Một chút kiên nhẫn. Không cần nhiều lắm, chỉ cần đủ để đọc lại bài này từ đầu chí cuối sau khi đọc hết mà vẫn không hiểu gì.

13. Đây mới là cuối cùng. Cần một bộ óc bình thường như cân đường hộp sữa. Không cần cái đầu quá nhanh như Core i7 hay Snapdragon 820, nhưng nếu nhanh được như vậy thì càng tốt. Chỉ cần làm được 5 phép tính cộng trừ nhân chia số có 2 chữ số trong thời gian 1 phút là đủ tiêu chuẩn.


Xác định text



Vì đây là bản dịch, nên dĩ nhiên thứ ta cần quan tâm trên hết chính là text. Nó tồn tại sẵn trong Rom, và khi CPU đọc được nó thì sẽ hiển thị lên màn hình cho bạn thấy. Tuy nhiên text trong Rom không dễ gì thấy được bằng mắt thường, ngay cả khi mở Rom bằng hex editor.

[​IMG]

Chẳng hạn như hình ảnh trên, ngay cả khi biết được địa chỉ chứa text nhưng mở Rom lên, bạn chỉ thấy được những con số. Bởi vì những game thế hệ cũ trên SNES, PSX đều không dùng chuẩn Ascii hay Shift-Jis, Unicode để lưu text. Chúng có kiểu mã hóa của riêng chúng và không game nào giống game nào. Cho nên một trong những bước đầu tiên cần phải làm khi dịch những game cũ kiểu này là xác định kiểu encoding của nó.

Có nhiều cách để xác định và ở đây tôi giới thiệu cách đơn giản nhất.

1. Đầu tiên thử tìm một đoạn text dễ kiếm, có đặc trưng và không bị trùng lặp. Tôi thường chọn những đoạn đầu game hay gần điểm save để dễ dàng kiểm chứng. 


[​IMG]

Việc xác định đặc trưng của một đoạn text phụ thuộc khá nhiều vào cái "sense" (khiếu) của bạn. Khéo thì sẽ chọn được đoạn độc đáo, không trùng lặp với những cụm từ khác để quá trình tìm kiếm được nhanh hơn. Đoạn tôi chọn trong khoanh đỏ khá độc đáo và gần như cả game chỉ có mỗi sự kết hợp này.

2. Mở Rom bằng YY-CHR, xem thử font có bị nén hay mã hóa không. Sau một hồi cuộn lên cuộn xuống cũng tìm được. May thật, bộ font lộ thiên.

[​IMG]

Trong bất kỳ ngôn ngữ nào, các chữ cái cũng đều được sắp xếp theo trật tự nhất định. Nếu trong bảng chữ La Tinh, đó là a, b, c, d,... thì trong bảng chữ cái tiếng Nhật lại là a, i, u, e,.... (あ, い, う,...)
Do vậy, nếu giả định あ có giá trị là 1, thì い đứng ngay sau đó có giá trị là 2, và う là 3,....

Để coi, căn cứ trên trật tự xếp chữ trong bộ font này thì cụm text được khoanh tròn kia là:

6-2-13-41

3. Bật Relative search, gõ tên file đối tượng và thứ tự tương đối của các chữ cái trong đoạn text kia.

[​IMG]

Chỉ có một kết quả tại địa chỉ $3D265 là thỏa mãn điều kiện đặt ra. Nếu việc xác định đoạn text để tìm kiếm ở bước 1. không khéo thì ở đây có thể sẽ có nhiều kết quả, và ta sẽ phải thử lần lượt từng kết quả để biết chính xác.

4. Thử kiểm tra kết quả vừa tìm được. Bật hex editor, tại địa chỉ $3D265 là giá trị 06. Thử đổi thành 09, save Rom và bật giả lập lên...

[​IMG]

Và kiểm tra lại kết quả...

[​IMG]

Ta thấy, thay 06 thành 09 và kết quả hiển thị thay đổi từ chữ か thành chữ け
Vậy có nghĩa là đã tìm đúng. Nếu 09=け thì chữ tiếp theo, こ sẽ là 0A.

5. Lập file table. Về cơ bản, đó là file văn bản có phần mở rộng .tbl.
Áp dụng cái logic trật tự trên để lập table cho cả bộ font.

Như thế này... 


[​IMG]

Giờ bật Windhex, load Rom và thử so sánh khi có và không load kèm table.


[​IMG]

Rõ ràng, với file table thì ta dễ dàng xác định được text trong Hex editor.

Bây giờ tôi hướng dẫn một cách xác định text khác mà không cần dùng đến thủ thuật tìm kiếm tương đối. Cách này áp dụng kiến thức về phần cứng của SNES để tìm.

1.Bật Debugger Geiger, chạy game đến một đoạn text ở đầu game cho dễ xác định, chẳng hạn như cảnh này.


[​IMG]

Hình ảnh hiển thị trên màn hình SNES là kết quả tổng hợp của nhiều lớp (layer) đồ họa, gọi là Background (bối cảnh) chồng chất lên nhau. Các loại giả lập hiện nay đều có chức năng bật, tắt từng BG. Trong Geiger, mặc định khi nhấn phím 1 thì giả lập sẽ bật/tắt BG 1, phím 2 để bật tắt BG 2,.... Kết quả sau khi nhấn thử một loạt phím số thì biết được:

- Cảnh nền (sân vận động) trong ảnh trên nằm ở BG2.
- Phần chữ (text) nằm ở BG3.
- Phình hình ảnh bình luận viên là sprite, và nó nằm ở BG5.

[​IMG]

Còn nhiều thông tin khác nữa, nhưng ta chỉ quan tâm tới BG3 chứa text. Bây giờ tắt mỗi BG2 đi, để bối cảnh không còn hiển thị phần sân vận động.

2. Nhấn vào tab "Show Hex" trên debug console của Geiger để bật Hex editor nội bộ của giả lập này. Tiếp tục, chọn dòng "Viewing" là "Vram" và click vào "Dump" để trích xuất toàn bộ Vram của thời điểm hiện tại. Có thể bật phần dump này bằng Yy-chr và ta thấy được những thành phần đồ họa đang được hiển thị trên màn hình.

[​IMG]

3. Nhấn vào nút "What's used" trên debug console của Geiger để biết các thành phần đồ họa nào đang được sử dụng trong cảnh hiện tại.

[​IMG]

Ta có các thông tin sau:


V-blank NMI enabled
H-DMA 0 [1] 0x038E3C->0x2126 inc continue 0x7E8E3C indirect addressing
H-DMA 1 [1] 0x038E51->0x2128 inc continue 0x7E8E51 indirect addressing
DMA 7 0 0x7E2200->0x2104 Num: 544 inc
VRAM write address: 0x7f1e(nByte), Full Graphic: 0, Address inc: 1
BG0: VOffset:0, HOffset:0, W:32, H:64, TS:8, BA:0x1800, TA:0x5000
BG1: VOffset:0, HOffset:65310, W:64, H:32, TS:8, BA:0x3800, TA:0x6000
BG2: VOffset:0, HOffset:0, W:32, H:32, TS:8, BA:0x7c00, TA:0x7000
BG3: VOffset:0, HOffset:0, W:32, H:32, TS:8, BA:0x0000, TA:0x0000
Main screen (always on): BG1,BG2,OBJ,
Sub-screen (always on): 

Window 1 (0, 0, 13, 00): BG0(O-OR),BG1(O-OR),OBJ(O-OR),
Window 2 (0, 0): 
Fixed colour: 000000

Dòng BG2 chứa các thông số về tileset, tilemap hiển thị ở BG3. Trong đó:

- TS: chính là tile size, kích thước của tile. TS:8 cho biết BG này sử dụng tile có kích thước 8x8 pixel, tức kích thước font chữ của chúng ta.
- BA: chính là tilemap. BA:0x7c00 cho biết tile map của chúng ta bắt đầu tại địa chỉ $7C00 tại Vram (Video ram, phần RAM hiển thị hình ảnh của SNES).
- TA: chính là tileset. TA:0x7000 cho biết tileset của chúng ta bắt đầu tại địa chỉ $7000 trong Vram.

Giải thích ý nghĩa:

- Một đặc điểm của địa chỉ VRam của SNES là nó gấp đôi so với địa chỉ hiển thị. Nếu TA bắt đầu tại $7000 thì có nghĩa là nó bắt đầu tại $7000 x 2 = $E000 trong Vram. BA bắt đầu tại $7C00 thì trong Vram, địa chỉ của nó là $7C00 x 2 = $F800.
- TA (Tileset): hiểu nôm na là một bộ các tile. Còn nhớ khi ta mở Rom bằng YY-chr để xem font? Mỗi một chữ cái là một tile, và nguyên cả bộ font đó là một tileset. Vốn nó là một phần dữ liệu trong Rom và được tải vào trong Vram để hiển thị.

Đây là tileset trong Rom, bắt đầu tại $34800.

[​IMG]



Còn đây là tileset khi được tải vào Vram. Xem bằng cách dùng Yy-chr để mở file dump của Vram lúc nãy. Ta thấy địa chỉ của tileset bắt đầu ở $E000.

[​IMG]

- BA (Tilemap) được hiểu nôm na là một bản đồ phân bố, bố trí các tile trên màn hình. Màn hình SNES thể hiện được 32 tile trong một dòng, mỗi tile có kích thước 8 pixel theo bề ngang. Do vậy, bề ngang của màn hình SNES có độ phân giải: 32 x 8 = 256 điểm ảnh. Khi chụp ảnh màn hình giả lập, bạn sẽ thấy kích thước to hơn 256 là vì giả lập có chức năng upscale. Nếu bỏ chức năng này đi thì hình ảnh hiển thị sẽ thu nhỏ về 256 pixel.
- Mỗi một tile được thể hiện bằng một byte, đi kèm với một byte khác thể hiện tính chất của tile đó. Do vậy, một tile trong Vram chiếm 2 byte, và một dòng trên màn hình SNES là 64 byte.
- Ta đã biết BA của cảnh hiện tại bắt đầu tại $F800 trong Vram. Điều này có nghĩa, các tile được dùng để vẽ khắp màn hình từ góc trên cùng bên trái, xuống dưới cùng bên phải màn hình. Vị trí góc trên bên trái bắt đầu tại $F800. Bắt đầu từ đây, ta thấy một chuỗi giá trị 0000000000000....
Thử thay đổi byte đầu tiên (tại $F800) thành 01, và ta được kết quả sau.

[​IMG]

Nhìn lên góc trên, bên trái, ta thấy xuất hiện chữ あ. Như vậy, chữ này có giá trị là 01. Tiếp tục thử các giá trị khác, bằng cách này ta xây dựng được table mà không cần phải dò tìm tương đối. Cách này cho kết quả chuẩn xác hơn, nhanh chóng hơn.


Trích text

Sau khi lập được table, dễ dàng xác định được text nằm đâu trong Rom. Từ đó tiến hành dump (xuất) text từ Rom ra file văn bản để dịch thuật.
Mục đích của việc dump text gồm:

1. Kiểm soát code nằm lẫn trong khối text
2. Phục vụ cho quá trình chèn text sau khi dịch

Ngoài ra nó còn có tác dụng phụ là giúp việc đọc được tốt hơn so với khi đọc bằng Hex editor.
Để trích text, nếu có khả năng thì bạn nên tự code một phần mềm chuyên dụng cho việc này. Tuy nhiên cũng có khá nhiều phần mềm có sẵn phục vụ cho mục đích này, và trong số đó thì Cartographer là phần mềm tốt nhất, có thể dump text với nhiều kiểu khác nhau như dump trực tiếp khối text, hay gián tiếp qua pointer. Và tất cả mọi phần mềm dump text đều làm việc trên một nguyên tắc chung, là quy đổi mã code thập lục thành chữ cái tương ứng mà ta quy định trong table.
Giả dụ, trong table đã lập ở bước trên, ta có 01=あ thì khi gặp phải hex code 01 trong đoạn text cho sẵn, phần mềm sẽ xuất ra ký tự あ.

Cách sử dụng Cartographer được hướng dẫn cụ thể trong file readme đi kèm. Tạo một file.bat để chung với thư mục Cartographer.exe và Rom, có nội dung như sau:


cartographer Tsubasa3.smc dumpscript.txt abc -s

Trong đó .smc là tên Rom đối tượng, .txt là tên file lệnh điều khiển Cartographer, abc là file text xuất ra (mặc định là .txt), -s/-m là tham số cho phép gộp nhiều kết quả vào một file hay tách thành nhiều file.

Đây là kết quả dump một đoạn.

[​IMG]



0 bình luận :

Post a Comment

 
Top