본문 바로가기
미연시/한글화 강의

기본적인 한글패치 제작 방법 (미연시) ② (AdvHD/ws2 엔진)

by 카토레아 2024. 4. 24.

https://katorea.tistory.com/37

 

기본적인 한글패치 제작 방법 (미연시) ①

가장 먼저 언급해두고자 합니다. 저도 이런 작업에 대해서 누구에게 배운 적도 없고, 프로그래밍을 잘 하는 것도 아닙니다. 제가 누굴 가르칠 수준은 아니라는 것은 잘 알고 있습니다만, 그렇기

katorea.tistory.com

 

 

1편에서 이어서 적겠습니다.

 

이 글에서는 스팀판의 경우를 예시로 해보겠습니다.

 

2편인만큼 1편과 반복되는 내용들은 설명을 줄여서 하겠습니다.

 

 

 

게임이 설치된 폴더를 보니 1편에서 했던 복각판과 같은 압축 형식처럼 보이네요.

 

정보를 알고 있으니 바로 Rio.arc를 Garbro를 사용해 열어보겠습니다.

 

 

 

 

열어보니 ws2파일들이 보이네요.

 

아마 willplus사의 두번째 압축 포맷인 것 같습니다.

 

Garbro에서 아카이브 생성까지 지원하고 있는 포맷이므로,

 

운좋게도 언팩과 리팩 과정을 모두 바로 해결했네요.

 

Rio.arc에 들어있는 파일들을 모두 추출합니다.

 

메모장으로 연 모습

 

 

가장 간단하게는 이렇게 메모장으로도 수정할 수 있습니다.

 

하지만 물론 작업이 매우 힘들어지는데다

 

저의 경우는 이미 번역해 놓은 텍스트가 있기 때문에,

 

ws2파일 속의 텍스트를 편집하기 좋은 형태로 바꿔주겠습니다.

 

 

1편에서 했던 것처럼 규칙을 찾습니다.

 

이 파일은 구조가 상당히 간결합니다.

 

보면 인물이름 앞에는 %LC(15254C43)가 붙고,
지문이나 대사 앞에는 char(63686172)가, 끝에는 %K%P(254B2550)이 붙습니다.

 

이걸 바탕으로 텍스트를 추출하는 코드를 짭니다.

 

저는 어떤 기능을 하는 함수를 조합해서 작업을 수행해야 할까를 생각하고,

chatGPT에게 함수를 만들어달라고 해서 사용하고 있습니다.

 

추출 코드 빌드

 

 

자기가 사용하기 편하도록 자신만의 코드를 작성하면 됩니다.

 

저는 번역해놓은 텍스트가 있으므로 바로 붙여넣기 할 수 있는 형태로 추출했습니다.

 

추출 결과

 

텍스트를 번역하고

 

번역한 텍스트를 다시 넣어주는 코드를 짜서 번역 작업을 완료합니다.

 

이미 작성해놓은 추출의 역과정이기 때문에 코드 빌드가 비교적 쉽습니다.

 

삽입 코드 빌드

 

 

삽입 결과

 

 

여기까지의 내용은 1편과 크게 다를 것 없습니다.


 

 

이제 실행파일을 봅시다.

 

그런데 실행파일이 디버깅이 안됩니다.

 

 

아마도 steam의 보안에 의해 디버깅이 제한되는 것 같습니다.

 

Steamless라는 유틸을 사용해서 DRM을 해제해주었습니다.

 

 

해제하고 Createfont를 검색해서 찾습니다.

 

하지만 보이지 않습니다.

 

이럴 경우엔 대신해서 multibytetowidechar 함수를 검색해봅니다.

 

 

 

 

multibytetowidechar함수는 코드 페이지 값을 사용합니다.

 

일본 코드 페이지 번호는 932, 한국은 949입니다.

 

16진수로 932는 3A4, 949는 3B5입니다.

 

이 3A4라는 상수는 매우 특정적이기 때문에, 바로 3A4라는 상수를 검색해도 됩니다.

 

찾았다면 3A4를 3B5로 수정해줍니다.

 

 

 

 

하지만 실행해보니 글자가 나오지 않네요.

 

이렇게 글자가 점으로 나오는 걸 보니 폰트 문제인 것 같습니다.

 

데이터는 올바르게 읽어들이고 내보내고 있지만, 자체 폰트를 사용하고 있어

 

한국어에 해당하는 폰트가 없어 화면에 나타내지 못하고 있는거죠.

 

게임 파일 안에 Font.arc가 있으니 아마 이 추측이 맞을 것 같습니다.

 

 

 

관련 정보를 찾다보니 운좋게도 다른분이 관련되서 작업 해놓으신 게 있네요.

 

받아서 사용해봅니다.

 

 

 

잘 나오네요.

 

패치 파일이 d3d9.dll 인 것을 보니 아마 다이렉트x와 관련된 것 같습니다.

 

이대로도 충분히 좋으니 그대로 사용하기로 했습니다.

 

 

완료된 것처럼 보이지만

이대로 진행하면 오류가 나는 부분이 생깁니다.

번역을 하면서 문자열의 길이가 달라졌기 때문인데요.

 

데이터 파일은 텍스트 데이터와 opcode가 섞여 있는 상태입니다.

opcode는 컴퓨터의 명령어라고 생각하면 됩니다.

어떤 그림을 표시해라, 음성을 재생해라, 텍스트를 표시해라 이런 식으로 말이죠.

 

이 중에는 파일의 주소값이나 길이를 불러오는 경우가 있기 때문에
텍스트의 길이가 변경되었을 경우 파일의 크기와 주소값이 전체적으로 변해

올바르게 불러오지 못해 오류가 발생하는 것입니다.

 

간단한 예시를 보겠습니다.

 

선택지가 나오는 상황

 

대표적으로 선택지가 그렇습니다.

 

이 선택지의 경우 글의 흐름을 나타내보자면

 

                  (선택지A) - 글A

                /                          \

공통문장a                              공통문장b

                \                           /

                   (선택지B) -글B

 

이런식입니다.

 

선택지에 따라 다른 문장을 표시한 다음, 다시 원래 흐름으로 돌아가는 구조이죠.

 

하지만 데이터 파일은 2차원이 아니라 1차원으로 일렬적으로 나열되어 있는 구조입니다.

 

거기서 어떻게 위와 같은 흐름을 구현할 수 있을까요?

 

여러 답이 있을 수 있겠지만 이 게임에서 사용하는 구조는 다음과 같습니다.

 

공통문장a - ①

(선택지A) + 선택시 글A의 주소로 점프하라는 명령 - ②

(선택지B) + 선택시 글B의 주소로 점프하라는 명령 - ③

글A + 공통문장b의 주소로 점프하라는 명령 - ④

글B + 공통문장b의 주소로 점프하라는 명령 - ⑤

공통문장b ⑥

 

(점프하라는=읽어들이라는)

 

만약 선택지 A를 고른다면 데이터의 흐름은,

① → ② → ④ → ⑥

이런 식으로 되겠죠.

 

이런 식으로 중간에 있는 데이터들을 건너뛸 수 있게 되어 있습니다.

 

우리가 해야 할 일은 이런 구조를 파악하고,

특정 주소를 가리키고 있는 주소값을 바뀐 주소값에 맞게 수정해 주는 일입니다.

 

위 상황을 예시로 다시 한번 보면,

 

 

 

이런식으로 나타나 있는 것을 볼 수 있습니다.

 

데이터가 리틀 엔디안 형식으로 저장되어 있는데, 읽을 때 오른쪽에서 왼쪽으로 읽어야 한다는 뜻입니다. 

 

예시로 260A 같은 경우, 주소값 0A26을 나타내고 있는 것입니다.

 

주소값 앞에 공통적으로 06이 나타나 있는 것도 볼 수 있습니다.

어셈블리 명령어 PUSH를 나타내는 듯 합니다.

 

번역된 텍스트를 넣어서 주소값이 달라졌다면 달라진 주소값에 맞게 위의 값들을 수정해주면 됩니다.

 

예시로 선택지의 한 가지 경우를 들었고,

실제로는 더욱 여러가지 상황이 있을 것입니다.

진행하면서 상황에 맞춰서 구조를 유추하면 됩니다.

 

 

 

이제 남은 작업들은 작은 부분들인데다

여기까지만 해도 (게임 플레이에는 지장이 없는) 핵심적인 내용은 얼추 다뤘다고 생각하고,

한 글에 담기에는 글의 내용이 조금 길어지는 감이 있으므로

 

다음 글에서 파이널 컴플리트판의 경우를 다룰 때

함께 자잘한 부분들을 담기로 하며 이만 줄이겠습니다.

 

댓글