FC 魂斗罗汉化日记 (第四日)

第四日 - 标题界面的游戏介绍

日文的游戏介绍界面

当你在标题界面什么都不干的时候,会已打字的形式显示这一串游戏介绍,然后跳转到游戏试玩界面。

用 YY-CHR 以及 FCEUX 的 PPU 查看器查看: 图层查看

当年的 ROM 卡槽相对来讲还是比较贵的,估计这也是为什么开发者选择了压缩图像。压缩的实现原理很简单:FC 对区块可以设定调色板,每个调色板可以选择四种颜色。一个背景色,一个共用色,以及两个独立的颜色。通过利用调色板的特性,可以储存双倍的单色图片/文字。

因为我不会操纵屏幕上的调色板,于是我选择把中文字模全部使用共用色导入到游戏内: 翻译后文字的字模

打开游戏观察: Imgur

从 Name Table 可以看出,“乃” 这个文字的贴图编码为 02 03 12 13

在 Rom 内也能够正常搜索到结果:

搜寻数据

但是,从这里开始到结束位置的字符数目对不上,于是回到 FCEUX 的调试器,针对写出屏幕下断 (第一个“乃”字的左上角地址为 $2114 ):

屏幕写出断点

断下后发现:这不还是从 $0700 读缓冲区后写出嘛,

PrintNextChar:
>07:CB9B:8D 07 20  STA $2007 = #$00
 07:CB9E:B9 00 07  LDA $0700,Y @ $0704 = #$03
 07:CBA1:C8        INY
 07:CBA2:C9 FF     CMP #$FF
 07:CBA4:D0 F5     BNE PrintNextChar

地址    内存内容
0700    01 21 14 02 03 FF 01 21 34 12 13 FF

0703 下写入断点,看看数据怎么来的: ``` 04:906F:B9 57 91 LDA $9157,Y @ $915F = #$02

04:9072:9D 03 07 STA $0703,X @ $0703 = #$02 04:9075:B9 58 91 LDA $9158,Y @ $9160 = #$03 04:9078:9D 04 07 STA $0704,X @ $0704 = #$03 ```

缕一缕,简单来说,就是从 $915F 读数据然后写出去,而这里则是我们之前搜到的内容;点 Step Out 跳出函数,看上面一行的内容定位函数地址为 $9034,在此处下断。

重启游戏,运行,发现经过此函数的时候,寄存器的内容依次为:00 12 13 12 11

到文件搜索,发现这行内容刚好在刚才搜到的数据前面,数据如下:

          00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00011140     00 12 13 12 11 42 42 C3 04 05 06 07 22 08 09
00011150  09 0A 0A AB 0C 0C 05 04 0B 23 0D 0D 0B 0E 0E AB
00011160  0F 0F 08 10 10 81 FF

把数据与游戏的文字并列查看,效果如下:

而出现重复字符代码的地方,则刚好在相应的帖图块里包含这两个字符。

至于换行,通过观察换行处的字符,可以看见其二进制码的第一位都是 1

使用字库工具生成图库想办法导入到 rom,然后调整文字颜色为公用色。

最后,就是喜闻乐见的代码修改了:

; JSR $9034

;  012DD0:FF        UNDEFINED
; 04:ADC0:FF        UNDEFINED
.org $ADC0

LDA $0008
AND #$40
BNE _LARGE_LETTER           ; 如果是大字就跳 (24x24)
  LDA $0008
  ASL     ; A <<= 2 (字符 * 4)
  ASL
  AND #$7F
  TAY     ; Y = A

  ; A = (a * 4 overflow) ? 20 : 0
  ; Offset = A
  LDA $0008 ; A = [0008]
  AND #$20  ; 20 表示写出位置 + 20
  CLC

  ; 坐标~
  ADC $0042
  STA $0000

  LDA #$00
  ADC $0043
  STA $0001

  ; Load x offset.
  LDX $0021
  LDA #$01
  STA $0700,X
  STA $0706,X

  ; 写出坐标
  LDA $0000
  STA $0702,X
  CLC

  ADC #$20
  STA $0708,X

  LDA $0001
  STA $0701,X

  ADC #$00
  STA $0707,X

  LDA _TITLE_CHAR_TABLE + 0, Y
  STA $0703,X

  LDA _TITLE_CHAR_TABLE + 1, Y
  STA $0704,X

  LDA _TITLE_CHAR_TABLE + 2, Y
  STA $0709,X

  LDA _TITLE_CHAR_TABLE + 3, Y
  STA $070A,X

  LDA #$FF
  STA $0705,X
  STA $070B,X

  TXA     ; A = X
  CLC
  ADC #$0C  ; A += 0x0C
  STA $0021 ; Write x-offset

  ; 向右移动两个字节
  LDA $0042
  CLC
  ADC #$02
  STA $0042

  RTS

_LARGE_LETTER:
  LDA $0008
  CLC
  SBC #$40
  STA $0000


  ASL
  ASL
  ASL
  CLC
  ADC $0000
  TAY       ; Y = A

  LDA $0042
  CLC
  ADC #$20
  STA $0000
  LDA $0043
  ADC #$00
  STA $0001
  LDX $0021
  LDA #$01
  STA $0700,X
  STA $0707,X
  STA $070E,X
  LDA $0042
  STA $0702,X
  LDA $0043
  STA $0701,X
  LDA $0000
  STA $0709,X
  CLC
  ADC #$20
  STA $0710,X
  LDA $0001
  STA $0708,X
  ADC #$00
  STA $070F,X
  LDA $919B,Y
  STA $0703,X
  LDA $919C,Y
  STA $0704,X
  LDA $919D,Y
  STA $0705,X
  LDA $919E,Y
  STA $070A,X
  LDA $919F,Y
  STA $070B,X
  LDA $91A0,Y
  STA $070C,X
  LDA $91A1,Y
  STA $0711,X
  LDA $91A2,Y
  STA $0712,X
  LDA $91A3,Y
  STA $0713,X
  LDA #$FF
  STA $0706,X
  STA $070D,X
  STA $0714,X

  TXA
  CLC
  ADC #$15
  STA $0021

  LDA $0042
  CLC
  ADC #$03
  STA $0042
  RTS


_TITLE_CHAR_TABLE:
  .byte $0,$1,$10,$11
  .byte $2,$3,$12,$13
  .byte $4,$5,$14,$15
  .byte $6,$7,$16,$17
  .byte $8,$9,$18,$19
  .byte $a,$b,$1a,$1b
  .byte $c,$d,$1c,$1d
  .byte $e,$f,$1e,$1f
  .byte $20,$21,$30,$31
  .byte $22,$23,$32,$33
  .byte $24,$25,$34,$35
  .byte $26,$27,$36,$37
  .byte $28,$29,$38,$39
  .byte $2a,$2b,$3a,$3b

  ; 前引号
  ; .byte $2c,$2d,$3c,$3d
  .byte $0B,$00,$00,$00

  ; 逗号
  ; .byte $2e,$2f,$3e,$3f
  .byte $00,$00,$1B,$00

  ; 句号 (10)
  ; .byte $40,$41,$50,$51
  .byte $00,$00,$0A,$00

  ; 之 (11)
  .byte $F7,$F8,$F9,$FA

  ; 名
  .byte $FB,$FC,$FD,$FE

  .byte $46,$47,$56,$57
  .byte $48,$49,$58,$59
  .byte $4a,$4b,$5a,$5b
  .byte $4c,$4d,$5c,$5d
  .byte $4e,$4f,$5e,$5f
  .byte $60,$61,$70,$71
  .byte $62,$63,$72,$73
  .byte $64,$65,$74,$75
  .byte $66,$67,$76,$77
  .byte $68,$69,$78,$79
  .byte $6a,$6b,$7a,$7b
  .byte $6c,$6d,$7c,$7d
  .byte $6e,$6f,$7e,$7f

编译后,把翻译后的数据也一并回写到游戏里看看:

翻译后的游戏介绍

完成啦~

Jixun的头像

Jixun