Multi Thần điện Ninh Tiền Đô 816 bit

  • Thread starter Thread starter SPC700
  • Ngày gửi Ngày gửi
quý thày có share tool dịch game gba không ạ

Tool đều là những thứ ai cũng có thể tìm được thôi bạn.

- Notepad: có sẵn trong Windows/Mac/Linux
- Armips: assembler free cho cả Windows lẫn Mac
- Debugger: free cho cả Windows lẫn Mac
- Kiến thức phần cứng + ngôn ngữ lập trình: sách free cũng nhiều

Mình share khá nhiều project trong này:

Mấy tên game về nước ta hầu hết đều dịch từ hán tự, hoặc chế cháo theo gameplay.
Ví dụ thì nhiều, thậm chí chả liên quan gì như natra ở trên. Hay game "mộc đế " chỉ chung cho dòng turnbase của nin, dù trong game không có ông vua nào mệnh mộc hết. :D

Tên gọi "Mộc đế" có logic đằng sau nó, cũng không phải ngẫu nhiên đâu.

 
Hồi xưa chỗ của tôi chỉ gọi tên game gốc tiếng Anh (Contra, Final Fantasy, Rockman) hoặc tên tiếng Việt (ăn nấm, 2 chàng ngốc, ngôi nhà ma, eo biển xanh), tên Hán Việt (mộc đế chiến kỷ, thập tự chinh), chứ hoàn toàn không dùng tên phiên âm, nên khi nghe Hồn Đấu La tôi kiểu "cái vẹo gì thế"?
À mà theo quan điểm cá nhân tôi thì gọi Hồn Đấu La là Việt hóa cũng không sai, nhiều người như bác có thể quá xem trọng cái từ "Việt Hóa", và bắt buộc nó phải theo một cái luật nhất định thì mới đạt chuẩn để gọi là Việt hóa. Nhưng mà Việt hóa hiểu theo nghĩa rộng thì chỉ là phương pháp chuyển 1 thứ ngôn ngữ nước ngoài ra thành tiếng Việt, để người Việt có thể đọc được, hiểu được, biết được nó phải đọc như thế nào (trong trường hợp là tên gọi). Nên gọi Contra là Hồn Đấu La hay Con-Tra cũng đều có thể xem là Việt hóa. Dịch ngôn ngữ nó chỉ là 1 bộ phận trong Việt hóa nói chung thôi.
 
Chỉnh sửa cuối:
nên khi nghe Hồn Đấu La tôi kiểu "cái vẹo gì thế"?
Thế nên bản dịch tiếng Việt vẫn có tựa đề là Contra thôi, không phải Hồn đấu la.

Nhưng mà Việt hóa hiểu theo nghĩa rộng thì chỉ là phương pháp chuyển 1 thứ ngôn ngữ nước ngoài ra thành tiếng Việt, để người Việt có thể đọc được, hiểu được, biết được nó phải đọc như thế nào (trong trường hợp là tên gọi). Nên gọi Contra là Hồn Đấu La hay Con-Tra cũng đều có thể xem là Việt hóa. Dịch ngôn ngữ nó chỉ là 1 bộ phận trong Việt hóa nói chung thôi.

Chuyển ngữ = dịch = xxx ngữ hóa, không phải xxx hóa.

Chẳng hạn, dịch sang tiếng Việt thì là "Việt ngữ hóa", không phải "Việt hóa".

Đây là nói theo logic của từ ngữ, đúng bản chất của nó.

Dĩ nhiên là ngôn ngữ có tính tự do, không ai cấm ai được cả. Chỉ là câu chuyện nó đúng hay không đúng so với chuẩn mực của đương thời thôi.
 
Ý tôi là khi dùng từ Việt hóa game thì người ta chỉ hiểu theo nghĩa Việt ngữ hóa (gọi tắt thành Việt hóa) chứ có ai hiểu đúng theo logic ngôn ngữ Việt hóa đâu. Cho nên là cứ phiên phiến thôi không cần cứng nhắc quá làm gì.
 
Chỉnh sửa cuối:

Trận đấu trong FE4 được tạo ra như thế nào?

Ai chơi FE lâu năm cũng đều biết là phần đánh nhau của dòng này chỉ là diễn trò, chứ mọi thứ đã được sắp đặt từ trước khi trận đấu diễn ra.
Trận đấu kéo dài bao nhiêu hiệp, bên nào đánh trước, bên nào đánh sau, mỗi bên mất bao nhiêu HP, thi triển những chiêu thức gì? Tất cả đều được định sẵn từ trước trận đấu, còn phần hình ảnh xảy ra sau đó chỉ là diễn họa lại theo cái kịch bản đã được định sẵn đó.

Vậy cái kịch bản đó được hình thành như thế nào?
Thật ra là có tới 2 kịch bản. Tạm gọi là kịch bản lớn và kịch bản nhỏ.
Kịch bản lớn là một table dữ liệu định nghĩa nên diễn biến của toàn bộ trận đấu đó. Mỗi phần tử trong table dữ liệu đó gồm 2 byte, trong đó 1 byte định nghĩa nên hành động và 1 byte còn lại định nghĩa nên số HP mà bên địch mất đi hay nhận được.
Byte định nghĩa nên hành động sẽ quyết định đòn đánh đó trúng hay trật, là đòn thường hay đòn tất sát, là đòn viễn công hay cận chiến, là đòn sát thương hay là phép bơm máu, đòn đó có kết liễu bên địch hay không, vân vân. Mỗi một cụm 2 byte như thế là một event chiến đấu.

Ngay sau khi người chơi chọn vũ khí để tấn công địch thì CPU sẽ dựa trên những dữ kiện sau để tạo thành table kịch bản lớn: chỉ số công/thủ và tốc độ của hai bên, lượng HP, các skill chủ động và skill thụ động, tính năng đặc thù và các thông số vũ khí của hai bên.
Sau khi phần tính toán này hoàn tất thì một màn hình đen sẽ xuất hiện. Màn hình đen này là thứ cần thiết để CPU xóa bối cảnh ngoài map, vẽ cảnh nền của trận đấu cũng như hình ảnh chiến đấu của 2 nhân vật.

Toàn bộ các động tác chiến đấu của mọi class nhân vật đều được chứa trong ROM. Và trong khoảng thời gian màn hình đen tồn tại thì tất cả hình ảnh chiến đấu (sprite) của 2 nhân vật đối tượng được chuyển hết vào RAM, và một phần hình ảnh cần được dùng ngay được chuyển vào VRAM. Hình ảnh được chứa trong VRAM chính là những gì mà bạn nhìn thấy trên màn hình.

Sau khi quá trình chuyển dữ liệu sprite từ ROM vào RAM và VRAM hoàn tất thì màn hình được bật trở lại, dần lộ ra cảnh nền và 2 nhân vật.
Lúc này CPU sẽ quét cái table kịch bản lớn một cách tuần tự từng 2 byte một. Nó đọc từng event chiến đấu trong cái table đó, biến event đó thành hình ảnh và âm thanh.
Và mỗi một event chiến đấu gồm 2 byte như kể trên lại được cấu thành từ nhiều hành động đơn lẻ nhỏ.
Chẳng hạn như trong event lao người chém xuyên qua đối thủ của SWORD MASTER thì gồm 3 hành động nhỏ:
- Động tác ôm kiếm chuẩn bị
- Động tác lao đi chỉ còn một bóng trắng vút xuyên người đối thủ
- Động tác thủ kiếm sau khi chém xuyên đối thủ.

Lúc này CPU cần đến một cái table khác, đó chính là cái kịch bản nhỏ.
Nếu kịch bản lớn là một table dữ liệu gồm nhiều event chiến đấu hợp thành, và mỗi event chiến đấu gồm 2 byte định nghĩa thì kịch bản nhỏ lại là một table dữ liệu được xếp theo kiểu cuốn chiếu. Mỗi thành phần trong table đó là một động tác lẻ của nhân vật, là một con số chỉ đến vị trí hình ảnh của động tác đó trong RAM. CPU sẽ theo dò theo vị trí này mà gửi hình ảnh tương ứng vào VRAM, và kết quả là ta thấy hình ảnh được cập nhật trên màn hình.
Có thể hình dung cách hoạt dụng của table kịch bản lớn và table kịch bản nhỏ như sau.

Kịch bản lớn: A chém B mất 1 HP, B chém lại A nhưng A né được, B lại bồi thêm nhát nữa, và là đòn tất sát khiến A mất 9 HP.

Kịch bản nhỏ:
- A chém B gồm các động tác A1, A2, A3. Các động tác này được thực hiện lần lượt hết A1 rồi đến A2, hết A2 lại đến A3. Chúng được thực hiện trong vòng một số frame được chỉ định trước.
- Tương tự, B chém A gồm các động tác B1 và B2. A né đòn gồm các động tác A5, A6.
- B tung đòn tất sát gồm các động tác B3, B4, B5, B6, B7.

Bởi vì các động tác nhỏ được thực hiện tuần tự từ trước tới sau, cái nào được thực hiện xong sẽ mất đi nên ta nói: nó có tính chất cuốn chiếu.

Hiểu được cách hoạt dụng của 2 table kịch bản chiến đấu thì ta có thể can thiệp vào quá trình xử lý để tạo ra:
- Kịch bản chiến đấu hoàn toàn khác so với xử lý ban đầu.
- Những skill mới bằng cách kết hợp các động tác đơn lẻ theo những trật tự khác nhau
- Những event không tồn tại trong logic gốc của game, kiểu như bên bị đánh vẫn có thể tấn công hay có hành động khác trong khi bên chủ động đang ra đòn.

Và dĩ nhiên, ta hoàn toàn có thể kết hợp cả 3 yếu tố trên với nút bấm trên tay cầm. Khi nhấn combo nút 1 thì sẽ có kịch bản đánh như thế này, khi nhấn combo nút 2 thì sẽ có những skill mới như thế kia.

Dưới đây là phần code nhấn nút để tạo skill mới, kịch bản đánh mới như bạn đã thấy trong mấy video vừa qua. Dĩ nhiên là với cách này thì bạn muốn kéo dài một trận đấu đến bao lâu cũng được. Hoàn toàn không có bất kỳ giới hạn nào.

Lưu ý: phần code này chỉ mới được viết cho class kiếm sĩ. Nếu áp dụng cho các class nhân vật khác thì có thể gây đơ game.



org $958B2E
JML press_button

@anyfreespace
press_button:
press_button:
LDA $E8
CMP #$0010 //R unpause
BNE +
LDA #$0000
STA {flag}
JMP quit_pressing
+
CMP #$0020 //L pause
BNE check_battle_script
LDA #$FFFF
STA {flag}
JMP quit_pressing
check_battle_script:
LDA $E4
CMP #$1200 //start left
BNE +
PHY
PHB
LDA #$4F85
STA $0AE1
SEP #$20
LDA.b #(battle_script_1)>>16
PHA
PLB
REP #$20
LDA #(battle_script_1)
TAY
JSL write_battle_script
PLB
PLY
JMP quit_pressing
+
CMP #$1100 //start right
BNE +
PHY
PHB
LDA #$4F85
STA $0AE1
SEP #$20
LDA.b #(battle_script_2)>>16
PHA
PLB
REP #$20
LDA #(battle_script_2)
TAY
JSL write_battle_script
PLB
PLY
JMP quit_pressing
+
CMP #$1800 //start up
BNE +
PHY
PHB
LDA #$4F85
STA $0AE1
SEP #$20
LDA.b #(recovery_script_1)>>16
PHA
PLB
REP #$20
LDA #(recovery_script_1)
TAY
JSL write_battle_script
PLB
PLY
JMP quit_pressing
+
CMP #$1400 //start down
BNE +
PHY
PHB
LDA #$4F85
STA $0AE1
SEP #$20
LDA.b #(battle_script_3)>>16
PHA
PLB
REP #$20
LDA #(battle_script_3)
TAY
JSL write_battle_script
PLB
PLY
JMP quit_pressing
+
CMP #$2800 //select up
BNE +
PHY
PHB
LDA #$4F85
STA $0AE1
SEP #$20
LDA.b #(battle_script_4)>>16
PHA
PLB
REP #$20
LDA #(battle_script_4)
TAY
JSL write_battle_script
PLB
PLY
JMP quit_pressing
+
CMP #$2200 //select left
BNE +
PHY
PHX
PHB
LDX #$0000
-
LDA battle_animation1,x
STA $7FE144,x
INX #2
CPX #$0006
BNE -
PLX
PLB
PLY
JMP quit_pressing
+
CMP #$2100 //select right
BNE +
PHY
PHX
PHB
LDX #$0000
-
LDA battle_animation2,x
STA $7FE144,x
INX #2
CPX #$0006
BNE -
PLX
PLB
PLY
JMP quit_pressing
+
quit_pressing:
LDA {flag}
BNE + //pause
JSL $95DA1D
JML $958B32 //no pause
+
LDA $E8
CMP #$0020
BNE +
JSL $95DA1D
JML $958B32
+
JSL $95DA1D
JML $958BBF


write_battle_script:
PHX
LDX #$0000
-
LDA $0000,y
STA {battle_script_table},x
INX #2
INY #2
CMP #$FFFF
BNE -
PLX
RTL

battle_script_1:
dw $13FE, $002C, $002C, $002C, $002C
dw $0501, $0501, $0000, $0104, $004D, $004D
dw $004C, $004C, $13FE, $004C, $000C, $14FE, $0200, $0000
dw $0009, $0009, $0000, $13FE, $0009, $000D, $0501, $0F05
dw $15FE, $14FE, $13FE, $000D, $000D, $02FE, $000D, $02FE, $0001
dw $0040, $004C, $0009, $0009, $0009, $000D, $000D, $000D, $000D
dw $0000, $0008, $0104, $0104, $000D, $000D, $0104, $000D, $0104, $000D
dw $14FE, $0000, $13FE, $14FE, $0104, $14FE, $15FE, $1044
dw $14FE, $0505, $14FE, $15FE, $0B05, $000D, $000D
dw $FFFF

battle_script_2:
dw $14FE, $15FE, $0904, $0000, $13FE, $0000, $0104, $0104, $0104
dw $13FE, $02FE, $000D, $02FE, $000D, $02FE, $000D, $02FE, $000D
dw $13FE, $02FE, $0001, $02FE, $0001, $02FE, $0001, $02FE, $0001
dw $14FE, $15FE, $0300, $0E04
dw $13FE, $02FE, $0005, $02FE, $0005, $02FE, $0005, $02FE, $0005
dw $13FE, $0000, $0000, $14FE, $15FE, $0800, $0104
dw $13FE, $02FE, $0001, $14FE, $02FE, $0505, $14FE, $02FE, $0505, $14FE, $02FE, $0505
dw $000C, $000D, $000C, $000D, $000C, $000D, $000C, $14FE, $02FE, $0505
dw $13FE, $0104, $0104, $14FE, $0504, $14FE, $0514
dw $FFFF

battle_script_3:
dw $13FE
dw $0000, $0004, $0004, $0004, $0001, $0001, $0005, $0005, $000C, $000C, $0000
dw $00001, $0001, $0001, $0001, $000D, $000D, $000D, $000C, $000C
dw $000C, $000C, $000C, $000C, $0005, $0005, $0005, $0005, $0005
dw $FFFF

battle_script_4:
dw $0100, $13FE, $0D04, $0D04, $000C, $000C
dw $1B41, $0100, $0008
dw $0049, $13FE, $0008, $000C, $0008, $000C, $000C
dw $0049, $13FE, $0008, $0D04, $000C, $000C, $0100
dw $0049
dw $13FE, $0D04, $0D04, $000C, $000C, $000C
dw $0049, $0008, $13FE, $0008, $000C, $0008, $000C
dw $0049, $0008, $13FE, $000C, $000C, $000C, $0D14
dw $FFFF

battle_animation1:
dw $1203, $1305, $147E
battle_animation2:
dw $0D0B, $4834, $818F

recovery_script_1:
dw $13FE, $0102, $0102, $0102, $0102
dw $002D, $0102, $0102, $0029
dw $14FE, $1002, $0105, $14FE, $1002
dw $0102, $0102
dw $13FE, $0029, $002D, $0325, $0021, $0102
dw $02FE, $0125, $0021, $0102, $0102, $0102
dw $0625, $0102, $02FE, $0021, $0102, $02FE, $0029, $02FE, $0325, $0102, $0625, $0102
dw $FFFF

Screenshot-2026-09-16-at-20-01-42.png

Screenshot-2026-09-16-at-20-03-57.png

Screenshot-2026-09-16-at-20-03-48.png

Screenshot-2026-09-16-at-20-04-50.png
 
Thề tư duy làm game của mấy developer mà được như hồi xưa với công nghệ hiện tại chắc game nó lên 1 tầm cao mới luôn. Hồi xưa giới hạn phần cứng mấy dev nghĩ ra đủ thứ để xoay sở đem lại trải nghiệm hay nhất đẹp nhất nhẹ nhất phải nói kiệt tác luôn
 
Thề tư duy làm game của mấy developer mà được như hồi xưa với công nghệ hiện tại chắc game nó lên 1 tầm cao mới luôn. Hồi xưa giới hạn phần cứng mấy dev nghĩ ra đủ thứ để xoay sở đem lại trải nghiệm hay nhất đẹp nhất nhẹ nhất phải nói kiệt tác luôn

Ngày nay cũng vẫn có đó. Điển hình như ông tác giả của Dark Souls.
 
Salamander là trò bắn phi thuyền của hãng Konami, được phát hành năm 1986 trên máy Arcade, sau được di thực sang máy Famicom năm 1987. Bản NES Mỹ có tên là Life Force, và hầu hết người chơi ở Việt Nam đều biết cái tên này. Tiền bản của nó là Gladius, được Konami phát hành năm 1985, và ở Mỹ thì Gladius được gọi là Nemesis.

Bây giờ thử nhìn vào tên gọi ở bản tiếng Nhật của Life Force.
Nó được gọi là Salamander, một sinh vật thuộc lớp bò sát, gắn liền với hình ảnh thần lửa hay tinh linh chi phối lửa trong thần thoại.
Có tích ghi rằng Salamander là con kỳ nhông sống trong lửa, lại có tích ghi rằng nó là con rắn lửa.
Theo hình ảnh minh họa trên băng game và hộp đựng băng thì ta thấy rõ nó là con rắn.
Vì sao tên gốc Salamander lại được đổi thành Life Force ở bản Mỹ là một câu chuyện khác, còn ở đây ta tập trung vào cái tên Salamander trong tiếng Nhật.

Thông thường, người ta sẽ dùng chữ cứng (Katakana) để ghi lại Salamander thành サラマンダー (âm Nhật: sa-ra-ma-n-dâ), nhưng ở đây người ta không làm như thế.
Họ dùng 4 chữ Hán để biểu đạt âm thanh này, bởi khi đọc lên thì 4 chữ Hán diễn tả tên gọi này cũng có cùng âm thanh như khi nó được viết bằng chữ cứng.
4 chữ này là 沙羅曼蛇 (Hán Việt: sa-la-mạn-xà, Hán Nhật: sa-ra-man-da).

Nói về ý nghĩa thì dĩ nhiên là từng chữ Hán trong cái tên này đều có nghĩa, nhưng khi ghép cả 4 chữ với nhau thì nó không có nghĩa là nghĩa tổng hợp của 4 chữ này.
Khi ghép lại với nhau thì nó không có nghĩa gì cả, mà chức năng của nó chỉ là để mô tả lại âm thanh khi đọc lên.
Ta gọi đó là phiên âm, hệt như khi Konami dùng 3 chữ Hán: hồn, đấu, la để phiên âm từ Contra.

Sa-la (沙羅, âm Hán Nhật: sara) là tên gọi của một loại cây mọc nhiều ở Ấn Độ, và tên của loại cây này nổi tiếng trong cộng đồng Bụt giáo vì nó gắn liền với nơi nhập diệt của Bụt Đà Thích Ca Mâu Ni. Kinh điển ghi Bụt Đà nhập diệt dưới gốc gây sa-la đôi (sa-la song thụ). Hai chữ Hán này cũng thường được dùng để phiên âm tên người nữ giới Tây phương (Sara).

Chữ 曼 có cách đọc theo âm Hán Nhật là "man", và âm Hán Việt chúng ta cũng đọc là "man" hoặc "mạn".
Chữ này có nghĩa là vật kéo dài, sự việc kéo dài, uyển chuyển.
Có rất nhiều chữ Hán có cách đọc là "man", nhưng Konami lại chọn đúng chữ này vì nó gợi liên tưởng đến con rắn uốn lượn, đúng như cái tên Salamander.

Chữ cuối cùng trong tên gọi của game này, chữ 蛇 có cách đọc Hán Việt là "xà", nghĩa là con rắn; còn cách đọc Hán Nhật là "da" hoặc "ja".
Có rất nhiều chữ Hán khác cũng đọc là "da" trong âm Hán Nhật, nhưng Konami chọn đúng chữ "xà" này.

Rõ ràng là nhà sản xuất có ý đồ khi chọn 沙羅曼蛇 (vi: sa-la-mạn-xà, jp: salamanda) để phiên âm danh từ "Salamander" thay vì dùng chữ cứng サラマンダー.
Khi dùng chữ cứng để phiên âm thì bất kỳ ai học hết chương trình tiểu học ở Nhật cũng đều đọc được.
Nhưng khi họ dùng chữ Hán để phiên âm, dĩ nhiên là nó cần trình độ cao hơn để đọc đúng âm, nhưng nó cũng gợi mở được nhiều thứ hơn chỉ là âm đọc thuần túy như khi dùng chữ cứng để phiên âm.
Cụm 4 chữ 沙羅曼蛇 được dùng để phiên âm, bản thân của nó không có ý nghĩa chính thống. Nhưng nó cũng gợi lên trong đầu người đọc rằng 4 chữ này chỉ về con rắn tên Sala.

1789780998246.png
 
Những điểm độc đáo trong hoạt cảnh chiến đấu của FE4 mà các bản FE khác không có được đầy đủ.

1) Không gian chiến đấu
Bề ngang chiếm 2 màn hình, nên nhân vật phải chạy bộ/tế ngựa từ bên cực hữu sang cực tả để đánh đối thủ.
Mấy bản FE đầu tiên cho tới FE3 thì cảnh chiến đấu chỉ là 1 màn hình, tuy nhân vật đứng ở 2 cực nhưng phạm vi di chuyển cũng không xa.
Mấy bản FE GBA thì 2 nhân vật đứng gần sát nhau khi trận đấu bắt đầu, nên không có khái niệm di chuyển.
Không chỉ bề ngang rộng lớn, mà không gian chiến đấu trong FE4 còn mở rộng theo chiều cao. Một số đòn đánh tung mình lên không của nhân vật cũng kéo góc camera lên cao, cho ta thấy một phần cảnh nền mà bình thường không thể thấy được.

2) Tự động điều chỉnh khoảng cách
Mỗi đòn đánh trúng sẽ khiến đối thủ lùi xa một tí, nên sau nhiều lượt đánh trúng liên tiếp thì đối thủ bị đẩy lùi khá xa. Lúc này đòn đánh của bên tấn công không với tới được, nên trước khi ra đòn lần nữa thì bên tấn công sẽ chủ động áp sát đối thủ rồi mới ra đòn.
Đây là một điểm trau chuốt rất hay mà các bản FE sau đó hầu như không còn kế thừa nữa.
FE5, một hậu bản của FE4 thì vẫn còn cơ chế này.

3) Tự động điều chỉnh hướng
Khi một nhân vật đánh ra sau lưng đối thủ, lưng quay vào lưng thì cả 2 nhân vật sẽ được điều chỉnh hướng nhìn sao cho mặt đối mặt nhau. Mấy bản FE sau hình như không có khái niệm đánh ra sau lưng nên cũng chẳng còn cơ chế này.

4) Nhiều phiên bản hoạt ảnh cho một đòn đánh
Điều này được thể hiện rõ qua hoạt ảnh của class Kiếm sĩ/Kiếm sư. Một đòn đánh có nhiều phiên bản hoạt ảnh khác nhau, tùy vào khoảng cách so với đối thủ, tùy vào tính chất đòn đánh đó có kết liễu hay không.
Chẳng hạn với class Kiếm sư, nếu là đòn kết liễu và bên tấn công đang nhập nội thì sẽ phi thân chém lên. Còn nếu đứng từ xa thì sẽ lướt tới cực nhanh, áp sát đối thủ rồi phi thân chém lên. Còn nếu đứng ở khoảng cách vừa thì sẽ phân thân thành 2 ảnh bên tả hữu, rồi lướt chém ngang người đối thủ.

Có thể nói FE4 là đỉnh cao trong thiết kế game của Kaga Shōzō, và rất tiếc là Nintendō không giữ lại hết những tư duy thiết kế này ở các phiên bản sau.

 
Bác có rành mấy cái máy SNES ngày xưa ở Việt Nam không? Tôi nhớ hồi xưa có từng thấy hoặc chơi bản Sailor Moon này, đặc biệt là đoạn thang máy:
Hình như nó là bản Sega Genesis nhưng tôi chắc chắn mình chưa từng nhìn thấy cái máy Sega Genesis nó trông như thế nào luôn, cũng chưa từng chơi giả lập Sega Genesis (tôi còn chẳng biết giả lập nó là cái gì).
 
Cái bản trong video đúng là bản Sega rồi. Mấy game này cùng một dev, trong giai đoạn đó nó spam khá nhiều.
Từ Snes tới Sega, và ngay trên Snes cũng có tới mấy phiên bản. Cách chơi như nhau, nhân vật như nhau, bối cảnh na ná nhau vì nó copy paste từ bản này sang bản kia nên nom quen quen cũng đúng thôi.
 
Bác có rành mấy cái máy SNES ngày xưa ở Việt Nam không? Tôi nhớ hồi xưa có từng thấy hoặc chơi bản Sailor Moon này, đặc biệt là đoạn thang máy:
Hình như nó là bản Sega Genesis nhưng tôi chắc chắn mình chưa từng nhìn thấy cái máy Sega Genesis nó trông như thế nào luôn, cũng chưa từng chơi giả lập Sega Genesis (tôi còn chẳng biết giả lập nó là cái gì).
Trò này của máy 6 nút nhưng hồi đó chỗ khu mình là chỉ trong quán điện tử xèng mới có trò này
 
1790966959416.png
Trong thời gian ngắn mấy ngày vừa qua, hẳn là bạn thấy có khá nhiều bản dịch game retro được sản xuất bởi AI, trong đó số lượng nhiều nhất và độ hoàn thiện cao nhất nằm ở game PS1.

Game SNES và GBA có số lượng bản dịch bởi AI ít hơn, và chất lượng hoàn thiện cũng không cao bằng. Chẳng hạn như font chữ lệch, hiển thị sai,...

Vậy tại sao AI lại có thể dịch game PS1 với độ hoàn thiện khá cao trong khi đối với SNES thì vẫn chưa được?

Câu trả lời nằm ở cấu trúc CPU của từng hệ máy.
Sau đây là một số hệ máy game retro phổ biến.

- NES (FAMICOM): dùng CPU 6502 có trường độ Register là 8 bit.

- SNES (SUPER FAMICOM): dùng CPU 65816 có trường độ Register khả biến, có thể thay đổi linh hoạt giữa 8 bit và 16 bit (vì thế mà trong tên gọi của nó có "816")

- GBA: dùng CPU ARM7TIDMI có 2 mode: ARM mode với 32 bit và Thumb mode với 16 bit

- PS: dùng CPU MIPS R3000A có trường độ Register là 32 bit

Nếu bạn hỏi AI, đâu là hệ máy game dễ phân tích nhất thì câu trả lời luôn là NES/FAMICOM.
Lý do bởi CPU của hệ này đơn giản, dung lượng thấp, và trường độ Register luôn cố định là 8 bit.

Còn nếu bạn hỏi đâu là hệ máy game khó phân tích nhất thì câu trả lời sẽ dao động theo khía cạnh "khó" mà bạn hỏi, nhưng thường là SNES hoặc PS1.

Game hệ PS1 khó phân tích đối với con người bởi dữ liệu của nó rất lớn. CD PS1 thường có dung lượng vài trăm MB. Tuy nhiên con số này không phải là vấn đề gì ghê gớm đối với tốc độ xử lý của AI ngày nay.
Ngược lại, cấu trúc CPU của PS1 khá dễ đối với AI bởi những điểm sau:
- Chủng loại Addressing mode của nó khá ít, khoảng 5 kiểu, như trong bài trước đã giới thiệu
- Kiểu bố trí Memory của nó cực kỳ đơn giản, theo quy tắc thẳng hàng 4 byte. Mỗi cụm dữ liệu, mỗi lệnh xử lý của CPU này luôn theo quy tắc là độ lớn của nó phải là bội số chia hết cho 4. Chính vì thế mà khi AI quét và phân tích dữ liệu của ROM PS1, kết quả là không thể sai. Đây là điểm khác biệt lớn nhất đối với game hệ SNES.

Khi dùng các phần mềm disassmembly để phân tích ROM PS1 thì ta luôn được kết quả đúng, phần code gọn gàng.

Còn với game hệ SNES, mặc dù dung lượng chỉ từ 0.5MB ~ 8MB, trong đó đại đa số game thương mại đều chỉ có dung lượng 1~2MB nhưng nó cực kỳ khó phân tích đối với AI bởi:

- Chủng loại Addressing mode phức tạp nhất trong các hệ này: hơn 20 kiểu.
- Kiểu bố trí Memory của nó không theo quy tắc thẳng hàng. Các lệnh xử lý của SNES không có quy tắc về độ lớn, mà có thể dao động trong khoảng 1~4 byte, nên AI quét dữ liệu game hệ này rất dễ sai.
- Như đã nói ở trên, CPU hệ này có thể cosplay ở 8 bit mode hoặc 16 bit mode, tùy ý người dùng. Do đó, cùng một khối dữ liệu nhưng khi phân tích ở 8 bit mode thì kết quả sẽ khác so với khi phân tích ở 16 bit mode. Chưa hết, CPU này có 3 register chính là A, X và Y. Trong đó, trường độ của A hoàn toàn độc lập với trường độ của X và Y. Do đó, cùng một khối dữ liệu nhưng sẽ cho ra 4 kết quả khác nhau, tùy vào tình huống lúc đó A và X/Y đang ở chế độ nào.
Đó cũng là lý do khiến các phần mềm disassmbly cho SNES thường không hoàn hảo. Người ta chỉ dùng nó cho một đoạn code nhất định khi đã biết rõ trường độ của các Register.
Và AI cũng vậy. Hiện nay AI chưa có chế độ tracking từng Register nên kết quả giải tích của nó nhiều khi không đúng.

Cách duy nhất và dễ dàng để biết chắc chắn các Register đang ở chế độ nào là theo dõi nó khi game đang chạy. Các AI hiện nay không thật sự chạy ROM khi phân tích, mà nó chỉ đơn thuần suy luận logic trong khi không theo dõi sự biến đổi trường độ của Register nên kết quả phân tích sai khá nhiều.

Còn game hệ GBA thì sao?
Hệ này cũng tương đối ít Addressing mode, và cách bố trí Memory cũng thẳng hàng. Ở Thumb mode, mỗi lệnh xử lý chiếm 2 byte, còn ở ARM mode thì mỗi lệnh chiếm 4 byte. Khá đơn giản.

Rốt cuộc, nếu xếp hạng mức độ khó/dễ khi phân tích ROM để hiểu đúng cấu trúc game thì độ khó lần lượt như sau.

- NES (FAMICOM)
- PS1
- GBA
- SNES (SUPER FAMICOM)
 
Back
Top