본문 바로가기

한글화 프로젝트/클래식 던전 1·X2

[실기검증 완료] 클래식 던전 1·X2 한글 패치 — 아드레날린 C1-2858-3 삽질기

클래식 던전 1·X2 한글 패치는 이미 완료 글까지 올렸지만, 실제로 마방진을 계속 만져 보니 그냥 넘기기 어려운 부분이 남아 있었다. 진행에는 문제가 없어도 자주 보는 칸에 일본어가 섞여 있거나 한글의 크기와 정렬이 어긋나면 플레이할 때마다 은근히 신경이 쓰였다.

그래서 완료 선언을 살짝 번복하고 X1·X2의 마방진 그래픽과 X2의 미번역 작곡 목록을 정리했다. 여기까지는 정말 끝난 줄 알았다. PPSSPP에서는 두 게임이 멀쩡히 부팅됐고 수정한 화면도 잘 나왔다.

그런데 PS Vita의 아드레날린에서 실행하자 X1은 검은 화면 뒤 C1-2858-3을 띄우며 아드레날린 자체가 종료됐고, X2는 검은 화면에서 꼼짝하지 않았다. 한 번 튕기고 나면 Vita도 잠시 정신을 못 차리는 것처럼 보여 처음에는 메모리 문제까지 의심했다. 원본 ISO는 같은 환경에서 잘 돌아갔다. 게임 이름을 한글로 바꾼 것이 문제인가 싶어 파일명도 바꿔 봤지만 결과는 같았다.

마방진 몇 칸을 예쁘게 고치고 끝내려던 작업이, 밤새 281MB짜리 X1 ISO를 VitaShell FTP로 올리고 지우는 실기 디버깅으로 바뀐 순간이었다.

기록을 시간순으로 다시 맞춰 보니 첫 재현이 새벽 2시 17분쯤이었고, X1·X2가 모두 정상이라는 답이 나온 시각은 저녁 7시 26분쯤이었다. 중간에 사용 한도가 걸려 멈춘 시간까지 포함해 사실상 하루를 이 문제 하나에 쓴 셈이다.

처음에는 그럴듯한 범인이 너무 많았다

실기에서만 죽고 PPSSPP에서는 멀쩡하니 의심할 수 있는 것이 한두 개가 아니었다. EBOOT.BIN을 평문 ELF로 바꾼 것이 문제인지, 원본에서는 0으로 채워진 BOOT.BIN에 실행 파일을 넣은 것이 문제인지, DATA.DAT 내부 파일의 위치가 밀린 것인지, ISO의 LBA와 2,048바이트 섹터 정렬이 깨진 것인지, PARAM.SFO의 한글 제목이나 ICON0 때문인지 하나씩 확인했다.

이미 이전 작업에서 다음과 같은 빌드도 만들었다.

  • EBOOT.BIN만 원본 암호화본으로 되돌린 판
  • DATA.DAT를 원본 순서와 배치에 가깝게 되돌린 판
  • BOOT.BIN을 원본의 0 더미로 둔 판
  • 로고·아이콘·한글 제목을 원본으로 되돌린 판
  • 파일 크기와 ISO9660의 LBA를 원본과 비교한 판

하지만 무엇을 되돌리든 결과는 검은 화면이었다. 나중에는 “그거 예전에 했던 거잖아”라고 할 정도로 같은 길을 다시 돌기도 했다. 이전 Codex 세션과 Claude 세션에 흩어진 실험 기록을 제대로 읽지 않고 새 가설을 세우면, 이미 실패한 ISO를 이름만 바꿔 다시 올리는 일이 생겼다.

아드레날린 설정도 만졌다. Inferno 대신 Sony NP9660 드라이버로 바꾸고, ISO 캐시와 고메모리 설정도 의심했다. NP9660에서도 똑같이 검은 화면이었다. 실행 드라이버나 한글 파일명은 범인이 아니었다.

EBOOT이 범인이라고 거의 확신했던 밤

아드레날린과 PSP 커널 로더의 소스까지 따라가니 아주 그럴듯한 이야기가 나왔다. 기본 설정에서는 BOOT.BIN을 읽지 않고 EBOOT.BIN을 실행한다는 점, 평문 ELF가 모듈 정보와 메모리 크기를 잘못 전달할 수 있다는 점, 커펌에서 받아들이는 형태로 ~PSP 헤더 336바이트와 gzip 압축 ELF를 묶을 수 있다는 점이었다.

X1의 가상 주소를 로더가 코드 크기로 잘못 계산하면 약 144MB를 잡으려 할 수 있다는 분석까지 나왔다. “튕긴 뒤 Vita가 한동안 정신을 못 차린다”는 증상과도 너무 잘 맞아 보였다. 원본 헤더의 모듈 정보, 세그먼트 주소, 진입점까지 비교하고 ~PSP + gzip(ELF) 재포장 도구도 만들었다. 헤더에서 바뀐 필드가 의도한 세 곳뿐이고, gzip을 다시 풀었을 때 번역된 ELF와 바이트가 같다는 것까지 확인했다.

그렇게 만든 X1 ISO를 약 281MB 그대로 Vita에 올렸다. 30MB 전송 한도에 걸려 다른 방법을 찾고, VitaShell FTP 주소에 연결하고, 전송이 끝나기를 기다린 뒤 실행했다.

결과는 다시 검은 화면이었다.

날 ELF도 실패하고, ~PSP+gzip도 실패하고, 원본 EBOOT을 넣은 판도 실패했다. 한동안 가장 유력하다고 생각했던 EBOOT 가설은 멋지게 빗나갔다. 나중에 진단G에서 평문 EBOOT을 넣은 완성 구성이 정상 부팅하면서 EBOOT은 완전히 무죄가 됐다. 소스 분석이 틀렸다기보다, 실제 크래시의 원인과 아무 관계가 없는 가능한 문제 하나를 너무 오래 붙잡은 셈이다.

“또 이분법이야?”라고 했지만, 결국 사다리를 다시 만들었다

이미 여러 조합을 시험했으니 또 파일을 반씩 나누자는 말이 반가울 리 없었다. 더구나 X1 ISO 한 번 전송에 281MB, X2는 약 525MB다. FTP가 게임을 실행하는 동안 끊기기 때문에 VitaShell로 돌아와 다시 켜야 했고, 덜 올라간 ISO를 실수로 실행하면 그 자체로 검은 화면이 나와 판정까지 오염된다.

그래도 기존 분할 실험에는 치명적인 문제가 있었다. 당시 모든 한글 자산이 같은 잘못된 압축기로 만들어져 있었다. 어떤 조합을 넣어도 “한글 자산 포함 = 실패”만 나왔으니 파일을 나눠도 범인이 갈리지 않았다. 그래서 이번에는 원본 ISO에 변수 하나만 더하는 누적식 진단 사다리를 새로 만들었다.

단계 실제로 넣은 것 아드레날린 결과 그때 확인한 사실
기준선 일본판 원본 ISO 성공 Vita·아드레날린 환경은 정상
DATA 재포장 기준판 내용은 원본, DATA만 다시 배치 성공 ISO 재구성·LBA·재배치 자체는 무죄
진단A 원본 + 한글 FONT.ARC 검은 화면 폰트 아카이브 안에 첫 번째 범인이 있음
진단B 원본 픽셀을 기존 도구로 재압축한 폰트 검은 화면 그림 내용이 아니라 압축 스트림이 범인
진단C 고친 압축기 + 한글 폰트 성공 첫 번째 원인 수정 확정
완전판 1차 진단C + 대사·DB·그래픽·평문 EBOOT C1-2858-3 원인이 하나 더 남아 있음
수정판B 완전판에서 EBOOT·BOOT만 원본 복귀 C1-2858-3 EBOOT과 BOOT은 무죄
진단D 진단C + 기존 SCRIPT·DATABASE 패커 C1-2858-3 두 번째 범인은 텍스트 저장 구조
진단E 원본 청크 배치를 보존한 SCRIPT·DATABASE 성공 두 번째 원인 수정 확정
진단F E + 오프닝·던전 알림·마방진·로고 성공 수정 그래픽 전부 통과
진단G F + 평문 EBOOT 문자열 51건 성공 X1의 모든 축 통과

표로 놓으면 깔끔하지만 실제로는 각 줄 사이에 ISO 생성, 섹터 비교, 해시 확인, VitaShell FTP 전송, 아드레날린 실행, 실패판 삭제가 들어간다. 전송 중 FTP가 끊겨 20초 간격 재시도 루프를 걸기도 했고, 업로드가 60%나 79%에서 진행 중인 동안에는 “아직 실행하지 말 것”까지 확인해야 했다. 로컬과 Vita에 진단판이 계속 쌓여 이름만 보고도 헷갈리는 지경이 됐다. 최종 정리 때 삭제한 진단 ISO만 11개였다.

첫 번째 진짜 원인 — 같은 그림인데 압축 바이트가 달랐다

진단A에서 FONT.ARC 하나만 바꿔도 죽었다. FONT.BIN의 글자 폭, 내부 파일 배치, 압축 슬롯 크기를 비교했지만 눈에 띄는 이상이 없었다. 그래서 진단B는 일부러 한글을 전혀 넣지 않았다. 원본 폰트 픽셀을 그대로 풀었다가 우리 IMY 인코더로 다시 압축했을 뿐이었다.

압축을 풀면 원본 픽셀과 바이트 단위로 같았고 PPSSPP에서도 정상으로 보였다. 그런데 아드레날린에서는 다시 검은 화면이었다. 이 한 번으로 범인이 확정됐다. 실기는 압축 해제 결과만 보는 것이 아니라, 원본 도구가 만든 압축 명령열의 형태에도 민감했다.

원본과 우리 스트림을 비교해 압축기의 선택 규칙을 역산했다.

  1. 같은 길이의 후보가 겹치면 더 낮은 룩업 위치를 우선한다.
  2. 길이 1인 반복도 특정 명령 형식으로 기록한다.
  3. 정보 스트림 끝을 0으로 채워 데이터 시작을 4바이트에 맞춘다.

세 규칙을 반영하자 두 게임의 원본 IMY 청크 233개 중 232개가 원본과 바이트 단위로 동일하게 재생성됐다. 남은 하나는 X1 로고에서 극히 드문 동률 선택 차이였고 해제 결과와 구조에는 문제가 없었다. 특히 픽셀이 원본과 같은 폰트 페이지 3·4·5는 압축 청크까지 원본과 완전히 같아졌다.

그 인코더로 한글 폰트만 다시 넣은 진단C가 드디어 부팅됐다. 일본어 문장이 한글 슬롯을 엉뚱하게 가리켜 화면은 괴상했지만, 그건 진단판의 의도대로였다. 그날 처음으로 한글 자산이 들어간 ISO가 실기에서 떴다.

“이제 끝”이라고 생각한 직후 또 C1-2858-3

진단C가 성공했으니 새 압축기로 전체 자산을 다시 빌드했다. 대사 4,899건, UI·데이터 3,159건, EBOOT 문자열 51건, 폰트와 마방진·던전 알림·로고까지 전부 넣었다. 모든 IMY 청크도 원본 동일 또는 새 규칙 재현본인지 전수 검사했다.

그런데 완전판은 다시 C1-2858-3으로 죽었다. “또 실패네”, “안 되는 것만 빙빙 도는 것 같다”는 말이 나올 만했다. 고친 인코더가 맞다는 사실과 전체 빌드가 죽는다는 사실이 동시에 성립했으니 원인이 하나 더 있다는 뜻이었다.

EBOOT을 버릴 수는 없어서, 먼저 완전판에서 EBOOT과 BOOT만 원본으로 되돌린 수정판B를 올렸다. 결과는 동일한 오류였다. 덕분에 오래 붙잡았던 EBOOT은 이 시점에서 무죄로 확정됐다.

다음 진단D는 부팅이 확인된 진단C에 SCRIPT.SDT와 DATABASE.DAT만 더했다. 이것도 죽었다. 두 번째 범인 구역이 텍스트 아카이브로 좁혀졌다.

두 번째 진짜 원인 — 번역문이 아니라 저장 자리의 계약

기존 패커는 번역된 압축 청크를 앞쪽부터 다시 붙였다. 파일 안의 내용을 모두 읽을 수 있고 PPSSPP도 문제없이 실행했으니 정상 파일처럼 보였다. 하지만 원본과 비교하니 청크 5개와 3개의 오프셋이 움직였고, 마지막 청크의 행 수를 1,024행으로 키우면서 원본보다 해제 영역이 40,960바이트와 54,272바이트나 커졌다. 원본은 각각 704행과 600행만 기대하고 있었다.

실기 엔진에는 파일 내용뿐 아니라 청크 오프셋, 슬롯 크기, 행 수, 해제 크기까지 사실상 고정 계약이었던 셈이다. PPSSPP는 그 차이를 관대하게 넘겼지만 아드레날린은 그대로 죽었다.

패커를 바꿔 원본 파일에서 각 청크의 위치와 크기를 읽고, 번역 데이터를 그 자리 안에 다시 넣었다. SCRIPT와 DATABASE의 파일 크기, 청크 경계, 오프셋, DATA 테이블을 모두 원본 그대로 유지했다.

마지막에는 DATABASE의 첫 청크가 딱 2바이트를 넘었다. 인코딩 규칙을 비틀거나 슬롯을 늘리는 대신 빨리 가자고!!를 빨리 가자고!로 줄였다. 느낌표 하나를 빼자 42,062바이트가 42,064바이트 슬롯 안에 들어왔다.

이렇게 만든 진단E가 부팅됐다. 대사와 UI까지 한글로 표시됐다. 두 번째 지뢰도 확정적으로 제거된 순간이었다.

E, F, G — 이번에는 하나씩 정말 올라갔다

진단E에 오프닝, 던전 알림, 마방진, 스탯 라벨과 로고를 더한 진단F도 부팅됐다. 로고는 원본 슬롯보다 234바이트 작았지만 테이블 크기를 바꾸지 않고 남은 꼬리를 원본 그대로 보존했다.

마지막 진단G에는 평문 EBOOT을 다시 넣었다. 이것까지 성공했고 직업명, 내구, 마나 같은 EBOOT 문자열도 한글로 나왔다. 처음에 가장 유력하게 의심했던 평문 EBOOT은 최종 구성에서 아무 문제 없이 동작했다.

X1은 여기서 끝났다. 성공한 진단G를 기반으로 정식 타이틀과 아이콘을 넣고, 기존 진단판을 지우고, 같은 ISO를 다시 만들 수 있도록 조립 스크립트까지 고정했다.

X2는 부팅 성공 뒤에 글자가 전부 깨졌다

X1에서 잡은 두 수리를 X2에도 적용했다. SCRIPT와 DATABASE는 원본 크기 그대로 들어갔고 EBOOT 문자열 529건, 마방진과 오프닝까지 포함해 약 525MB ISO를 Vita에 올렸다.

X2도 아드레날린에서 부팅됐다. 이제 끝이라고 생각했는데 화면의 글자가 전부 깨져 있었다. 로고는 멀쩡한데 폰트만 무너진 모습이었다.

원인은 실기 호환이 아니라 복원 과정의 실수였다. X2 폰트 빌더는 원시 픽셀에 PSP용 스위즐을 적용해 압축한다. 그런데 아카이브에서 꺼낸 페이지는 이미 스위즐된 상태였다. 그것을 원시 픽셀로 착각해 한 번 더 스위즐하면서 폰트 전체가 뒤섞인 것이다.

아카이브에서 복구한 폰트는 먼저 언스위즐하고 한글을 합친 뒤 마지막에 딱 한 번만 스위즐하도록 고쳤다. 새 FONT1의 압축 크기가 과거 정상판과 거의 같은 수준으로 돌아왔고, 최종 ISO의 폰트와 매핑으로 클래식 던전 X2 한글패치를 직접 렌더해 글자가 또렷한 것도 확인했다. 교정판을 다시 Vita에 올린 뒤 X2도 정상 표시를 확인했다.

마방진 보강 내용도 그대로 포함했다

대상 추가 적용 내용
클래식 던전 X2 작곡 화면 곡 목록 45개 번역, 마방진 큰 타일 글꼴·외곽선 보정, 흰 타일 확대·정렬, 조각 아이콘 85칸 한글화
클래식 던전 X1 조각 아이콘 32칸 한글화, 큰 타일과 흰 타일의 고정폭 정렬 보정
공통 마나·성장·감쌈·분산·동행·기술·배수처럼 반복해서 보는 마방진 표기 정리

X1 실기 화면에서 확인한 마방진 타일과 조각 아이콘

X2 조각 라벨 비교 — 위는 원본, 아래는 한글 적용 후

X2 큰 타일 비교 — 위는 원본, 아래는 글꼴·외곽선·정렬을 보강한 한글판

X1의 흰 타일은 X2처럼 키우려고 했지만 원본 압축 슬롯 7,004바이트를 23바이트 넘었다. 글자를 키우는 대신 조각 아이콘 32칸을 포기하면 들어가지만, 실제 플레이에서는 아이콘을 살리는 편이 낫다고 판단했다. X1은 현재 크기를 유지하고 정렬을 맞췄으며 X2는 글자 확대와 아이콘 한글화를 모두 유지했다.

최종 실기 확인 범위

대상 PS Vita 아드레날린 6.61 확인 내용
클래식 던전 X1 정상 부팅, 한글 폰트·대사·DB·그래픽, 평문 EBOOT 문자열 로딩
클래식 던전 X2 정상 부팅, 폰트 이중 스위즐 교정 후 한글 표시

이 기록에서 “실기 검증 완료”는 엔딩까지 완주했다는 뜻이 아니다. 아드레날린에서 검은 화면과 C1-2858-3을 만들던 원인을 분리했고, X1·X2의 부팅과 수정 자산 로딩을 실제 기기에서 통과시켰다는 의미다. PSP 실기 커펌은 기기와 CFW 조합이 다양하므로 다른 환경에서 문제가 있다면 모델과 커펌 버전을 함께 알려주면 좋겠다.

최종 패치와 확인값

두 게임 모두 지원하는 일본판 원본 ISO에서 다시 조립하고 xdelta 왕복 적용 결과가 배포 ISO와 바이트 단위로 같은 것을 확인했다.

구분 일본판 원본 SHA-1 실기 대응 xdelta SHA-1
X1 9b72f4aef6079393ae89c735b836b96d70cda910 efcea004f55c94a0aab3851c11db9565fafb18ad
X2 10f8a7d6fb9a7faa2322f93b855bf69b0e9af257 470874c89372559e5c1a3c09d5db3aeef0ec503a

아래 파일은 게임 전체가 아니라, 본인이 보유한 일본판 원본 ISO에 적용하는 차분 패치다.

클래식 던전 X1

클래식 던전 X1 한글패치.xdelta
0.79MB

클래식 던전 X2

클래식 던전 X2 한글패치.xdelta
1.93MB

X1에는 SHA-1이 72b7c362…로 시작하는 다른 판본도 있지만 현재 패치는 지원하지 않는다. 패치 세대마다 한글 글리프 배치가 달라질 수 있으므로 이전 시험판을 사용했다면 새 게임과 설치 데이터 재설치를 권장한다.

완료라고 써 놓고 다시 돌아왔고, 마방진 몇 칸을 고치려던 일이 압축기와 아카이브 패커를 다시 만드는 작업으로 커졌다. 그 과정에서 이미 했던 실험을 다시 하고, 틀린 원인을 확신하고, 수백 MB ISO를 몇 번이나 올리고, 성공한 줄 알았던 X2의 폰트까지 한 번 더 깨뜨렸다.

그래도 마지막에는 “PPSSPP에서 되니까 아마 괜찮다”로 덮지 않았다. 같은 픽셀도 압축 스트림이 다르면 죽는 첫 번째 문제와, 같은 문장도 저장 위치가 달라지면 죽는 두 번째 문제를 각각 실기에서 재현하고 수정했다. 이제 최소한 클래식 던전 1·X2 한글 패치는 에뮬레이터에서만 돌아가는 패치가 아니다. Vita 아드레날린에서도 두 편 모두 정상 부팅과 한글 표시를 확인하고 이번 보강판을 마무리한다.