KOEI/삼국지 시리즈

삼국지4PK 일판에 한글을 출력시키는 과정. (2부)

K66Google 2022. 3. 4. 14:34

(...1부에 이어서 계속)

 

7. 한글판 PACKGRP2.s4와 HIBACK.s4 파일을 일판에 호환되게 하는 작업

 

스팀 일본어판과 한글판의 파일들은 대부분 다 호환이 되었으나, 유독 두 파일만 호환이 되지 않고 게임이 튕기는 문제가 있었다. 두 파일의 이름은 PACKGRP2.s4HIBACK.s4 파일이었다.

PACKGRP2.s4는 내정상황표, HIBACK.s4는 일기토 모드의 '무력' 텍스트 이미지와 연관이 있는 것으로 의심된다.

그러나 두 파일은 NPK016으로 압축된 파일이라서 바로는 확인할 수가 없었다.

 

조사를 하니까, 같은 코에이 게임 '원평합전'의 이미지 압축 방식이 삼국지4PK와 동일하다고 한다.

그래서 나는 PACKGRP2.s4 파일을 HIKBACK.GP로 바꾸고 원평합전 폴더에 덮어쓴 뒤, 원평합전 이미지 편집기(링크)에서 그림을 불러오는 방식으로 확인해보았다.

색깔은 이상하지만, 일판 PACKGRP2에서는 내정상황표가 확인되었고 한글판 PACKGRP2에서는 확인되지 않았다.

하지만 Crystaltile2에서 NPK016 개수를 확인해보니 일판과 한글판 둘 다 11개였다. 그냥 에디터에서 인식을 못 한 거라고 생각해야 겠다.

 

 

자, 그렇다면... 어떻게 해야 한글판 PACKGRP2.s4를 호환시킬 수 있단 말인가...

나는 위의 원평합전 이미지 편집기의 작동 방식을 유심히 살펴보았다. HIKBACK.GP를 수정하면 해당 파일만 수정한 날짜가 바뀌어야 하는데, 실행파일까지 수정한 날짜가 바뀌고 있다. 즉, NPK016은 실행파일과도 연관이 있다는 것이다. 

그러고보니 대항해시대2 윈도우95판 한글화때도 그랬다. 도저히 엔딩 한글화를 못 해서 포기했는데, 이걸 해결해주신 분도 실행파일 어딘가를 수정하는 방식으로 했다. 뭔가 실행파일 내에 파일 크기 같은 걸 정해두고 정해진 만큼 읽어들이는 방식인건가?

 

그래서 나는 일단 일판과 정발판의 PACKGRP2.s4 파일을 'NPK016' 헤더를 기준으로 분리해보기로 하였다. 예전에 대항해시대2 엔딩 한글화 하겠다고 삽질한적이 있었는데, 그때 만들어두었던 프로그램을 써보기로 한다. 분리하니까 일판과 정발판 모두 11개의 파일이 나왔다. 11개의 파일을 헥스 에디터로 열어서 파일 끝이 얼마인지를 모두 조사했다.

 

* 일판 / 한글판 PACKGRP2 정보.

         일판크기    누적      한글판크기     누적
000.bin 0x46F9                     0x44F3
001.bin 0x1032    0x572B      0x1032     0x5525
002.bin 0x1EA6   0x75D1     0x1EA6    0x73CB
003.bin 0x0455    0x7A26     0x0455      0x7820
004.bin 0x1245    0x8C6B     0x1245     0x8A65
005.bin 0x1311    0x9F7C     0x1311     0x9D76
006.bin 0x132F    0xB2AB     0x132F     0xB0A5
007.bin 0x12F8    0xC5A3     0x12F8     0xC39D
008.bin 0x11D0   0xD773     0x11D0    0xD56D
009.bin 0x10E7    0xE85A     0x10E7    0xE654
010.bin 0x0D64    0xF5BE     0x0D64    0xF3B8

 

일판과 한글판의 크기 차이는 맨 처음 조각을 제외하고는 모두 동일하였다.

다만, 맨 처음 조각 크기가 서로 다르기 때문에 누적 크기 또한 일판과 한글판이 달라지게 되었다.

 

실행파일에서 46 F9를 바이트 플립한 F9 46으로 검색해보았다.

그렇게 하니 많은 위치에서 F9 46이 나왔다. 이 값을 한글판 크기인 F3 44로 바꿔주면 정상 출력이 될까?

나는 검색된 값 하나하나 수정하고 실행하고 튕기면 원상복구하고 다른 위치의 값을 수정하는... 이런 삽질을 하였다.

 

그리고... 

 

 

마침내 튕기지 않고 내정상황표를 정상적으로 출력시킬 수 있었다!!!!

하지만 계산기 쪽이 이상하게 출력되고 있다. 크기 지정을 바꿔서 그런 것으로 보인다. 이것도 실행파일 내에서 크기를 재지정해줘야 하는 건가?

 

 

다른 헥스 값인 0x572B를 바이트 플립(2B 57)해서 검색해보니 2B 57과 그 윗 줄에 A6 1E라는 것을 발견했다.

2B 57과 A6 1E가 붙어있는 걸 보니... 이거 수상하다. 2B 57을 25 55로 바꿔본다.

 

 

그랬더니 계산기도 정상적으로 출력되었다!!!

바로 이거다! 드디어 수수께끼가 풀렸다! 이런 식으로 마지막 조각까지 크기를 재지정해주도록 한다.

 

 

다행히 나머지 부분들은 한 곳에 가지런히 모여있어서 찾으러 다닐 필요가 없었다.

이렇게 한글판 PACKGRP2.s4 파일을 호환시키는 작업은 성공적으로 끝났다.

 

* 결론

0x9C710 대역 : F9 46 -> F3 44

0x16DB0 대역 : 2B 57 -> 25 55

0xE7DE0 대역 
 : D1 75 -> CB 73
 : 26 7A -> 20 78
 : 6B 8C -> 65 8A
 : 7C 9F ->  76 9D

0xE7DF0 대역 
 : AB B2 ->  A5 B0
 : A3 C5 ->  9D C3
 : 73 D7 ->  6D D5
 : 5A E8 ->  54 E6

 

(맨 마지막 누적 크기는 따로 지정하지 않는 것 같다.)

 

이제 남은 건 HIBACK.s4다. 이것도 PACKGRP2.s4 처럼 파일 끝이 얼마인지 조사한다.

 

* 일판 / 한글판 HIBACK.s4 정보.
(한글판은 NPK016과 NPK16 이런 식으로 헤더가 불규칙하게 되어있다.

반면 일판은 모두 NPK016으로 통일되어 있다.)

               일판크기    누적      한글판크기     누적
000.bin    0xC258                      0xC206
001.bin    0x3865     0xFABD     0x3865    0xFA6B
002.bin    0x47B1    0x1426E     0x47B1    0x1421C
003.bin    0x4681    0x188EF     0x4681    0x1889D
004.bin    0x29F8    0x1B2E7     0x29F8   0x1B295
005.bin    0x05CA   0x1B8B1    0x05CA    0x1B85F
006.bin    0x03EA   0x1BC9B    0x03EA   0x1BC49
007.bin    0x01CB   0x1BE66     0x01CB   0x1BE14
008.bin    0x011D   0x1BF83     0x011D   0x1BF31

 

이것도 맨 처음의 조각을 제외하고는 모두 크기가 동일하다. (누적은 달라짐)

 

 

이 파일도 다행히 바꿔야 될 값이 가지런히 한 곳에 모여있었다. (0x1BE14는 빼고)

수정하고 게임을 실행해본다.

 

 

'무력' 이라고 바뀌어서 잘 출력되고 있다. 이것도 호환 성공이다!!!

 

* 결론
0xE4130 대역 : 
58 C2 -> 06 C2
BD FA -> 6B FA

0xE4140 대역 :
6E 42 01 -> 1C 42 01
EF 88 01 -> 9D 88 01

0xE4150 대역 : 
E7 B2 01 -> 95 B2 01
B1 B8 01 -> 5F B8 01

0xE4160 대역 : 
9B BC 01 -> 49 BC 01
E7 B2 01 -> 95 B2 01

0x525A0 대역 :
66 BE 01 -> 14 BE 01

 

(맨 마지막 누적 크기는 따로 지정하지 않는 것 같다.)

 

 

8. 메시지 이식과 메시지 치환 런처에 넣을 브레이크 포인트 조사

 

메시지 이식 작업은 삼국지5PK 한글 출력 패치를 배포한 후에 시작되었다.

그러나 일판 메시지 개수와 한글판 메시지 개수가 달라서 무턱대고 복붙할 수는 없었다. (일판은 38개, 한글판은 42개다.)

조심스럽게 메시지 이식 작업을 마치고 LS11 압축기를 통해 압축하였다.

다행히도 삼국지5PK때와 달리 메시지 용량 제한 문제없는 줄... 알았으나 나중에 있는 게 드러났다. (다행히 외부 메시지 런처가 만들어져 있기 때문에 덜어내기 작업만 하면 되었다.)

그러나 이식 후 몇몇 문장의 말꼬리 등이 어색하게 출력되는 문제가 있어서 이건 배포 후에 천천히 고칠 생각이다.

 

 

메시지 이식이 끝났으니, 이제 치트엔진을 통해 대사 메모리 주소를 파악해본다.

대사는 0x57C470에 들어가는 것으로 보인다.

 

 

0x57C470과 그 주변 주소에 메모리 쓰기 브레이크 포인트를 걸면 0x48BC89에서 멈춘다.

 

 

F8로 진행해보니 값을 쓴 후 더 쓸 값이 있으면 0x48BC66의 JMP 구문을 타고 위로 올라가는 것으로 보인다.

그렇다면 대사를 다 쓸 경우 JMP 밑에 있는 0x48BC6B로 오게 될 것이다. 따라서 대사 브레이크 포인트 지점은 0x48BC6B다.

 

메모리 쓰기 때 멈췄던 주소에서 좀 더 조사를 해보니 대사 마지막 위치 주소와 바이트 카운트 관련 주소도 찾을 수 있었다. 대사 마지막 위치 주소는 0x57CA2C , 바이트 카운트는 0x57CA34였다.

 

 

실행파일 쪽에서 %s로 들어오는 글자는 0x49A8E0에서 먼저 브레이크 포인트를 걸어야 한국어 조사 처리를 할 수 있을 걸로 보인다.

아무튼 런처에 입력할 주소 정보를 다 모았으니까 삼국지5PK때 쓰던 런처를 약간 개조해서 사용하기로 하였다.

 

 

9. 호환성 탭의 256컬러 모드와 런처의 충돌

 

위에서 조사한 관련 정보를 바탕으로 런처를 수정하고 실행하려 했으나, 자꾸만 0x6B4FE216에서 STATUS_ACCESS_VIOLATION 오류가 발생하고 게임이 실행되지 않았다.

 

 

그럼 256컬러 모드를 체크하지 않고 실행하면 어떨까? 대항해시대3에서 쓰이는 CDS95Util의 ddraw.dll을 게임 폴더에 넣었더니, 정상적으로 실행되었다. 다만 일기토 모드와 사운드 모드에서는 옆의 검은 배경이 분홍색 배경으로 뜨는 문제가 있었다.

 

 

어쩌면 런처에서 256컬러 모드 세팅을 하면 어떨까? 하는 생각으로 런처에 관련 코드를 넣어보았지만 똑같이 0x6B4FE216에서 오류가 뜨고 튕겼다.

 

 

도대체 뭐가 문제여서 그러는 건지, 궁금해서 치트엔진을 키고 해당 주소로 가보았다. 그랬더니 모듈에 apphelp.dll 이라고 쓰여있었다.

 

 

Ollydbg로 해당 주소에 가니 무슨 DirectDrawSurface라는 함수를 실행하려다 문제가 생긴 것으로 보인다.

...에라 모르겠다. 그냥 감안하고 플레이해야지 뭐...

 

 

10. 실행 도중 일정 확률로 응답없음에 걸리는 현상

 

한글화 테스트 도중에 화면을 최소화시키는 등, 말 그대로 딴 짓하고 있으면 프로그램이 응답없음에 걸리는 현상을 발견했다. (BGM이 반복 재생되지 않는 걸로 유추할 수 있다.)

이 오류의 발동 조건이 뭔지 정확하게 알 수 없어서 헤매고 있었는데, 우연히도 Ollydbg로 삼국지4PK를 디버그 하는 도중에 발생해줘서 문제의 원인을 파악할 수 있었다.

 

이 부분에서 계속 무한루프를 하고 있어서 응답없음 현상이 발생한 것이었다.

00423407의 JNZ... 에서 위쪽으로 점프를 하게 되는 게 문제의 원인인 것 같다.

887601C2는... 예전에 삼국지4PK 윈도우95판 멀티태스킹 패치를 할 때 본 낯익은 코드다. 설마 코에이가 멀티태스킹 패치를 덜 한 건가?

 

 

그래서 JNZ...의 반대 구문인 JE (=JZ) 로 바꿔주니까 프로그램이 위로 점프하지 않고 아래쪽으로 내려가면서 정상적으로 계속 실행되었다.

 

* 결론
00423407 : JNZ... 를 JE... 로 변경.

 

 

- 스크롤 압박으로 인해 3부에서 계속 -