안녕하세요?
두주만에 다시 패미컴 튜토리얼 글로 인사드립니다. 이번 글에서는 게임내의 대사의 출력 과정을 알아보는 시간을 가져 보도록 할게요. 이전의 튜토리얼은 아래 링크에서 확인해 보실수 있습니다.
- 패미컴 (or NES) 게임 한글화 튜토리얼 #03 (타일)
- 패미컴 (or NES) 게임 한글화 튜토리얼 #02 (롬확장)
- 패미컴 (or NES) 게임 한글화 튜토리얼 #01 (개요)
4. 패미컴에서의 대사 출력
지난 글에서 패미컴의 그래픽을 구성하는 최소단위인 ‘타일’
에 관하여 알아보았습니다. 우리가 TV (브라운관)을 통해서 보고 조작하던 패미컴 게임들의 캐릭터/배경들이 사실은 ‘타일’
들의 집합이였죠.
그렇다면 패미컴은 대사를 어떻게 출력할까요? 네, 예상하시는 대로입니다. 그냥 글자의 모양을 가진 ‘타일’
들이 같은 방법을 통해 화면으로 출력될 뿐이죠. 그렇다면 일반적인 게임 내 대사의 출력과정을 알아볼 차례겠네요.
4.1 대사 출력 방법
대사출력 과정은 게임 시스템에 따라서 크게 두가지 방법으로 이루어지며 다음과 같습니다.
1. 패턴테이블에 글자타일을 미리 입력 후, 네임테이블을 수정하는 방법
Fig.1 - 1번 방법 (네임테이블 수정방법)
패턴테이블을 고정 한 후 네임테이블만 수정해서 화면에 대사를 출력하는 방식으로 그림에서 보이는 것 처럼, 대사 코드들이 수행되기 전에 이미 패턴테이블내에 글자 타일들이 입력되어 있는 상황입니다. 따라서 오른쪽에 보이는 네임테이블 (백그라운드)만 수정해서 원하는 대사를 화면에 출력하는 방식입니다. 패턴테이블의 각 타일마다 특별한 번호가 부여되는데 이 번호를 이용해서 네임테이블(백그라운드)를 구성하게 됩니다.
2. 네임테이블을 고정 후 패턴테이블을 수정하는 방법
Fig.2 - 2번 방법 (패턴테이블 수정방법)
반면, 두번째 방법은 네임테이블은 00부터 오름차순으로 이미 구성되어 있고, 해당 패턴테이블에 필요한 글자 타일들을 입력해서 대사를 화면에 출력하는 방식입니다. 두 방법의 차이점이 느껴지시나요?
즉, 네임테이블 (1번방법) 혹은 패턴테이블 (2번방법)을 수정해서 대사를 출력하는 것
이죠. 두 방법 모두 장단점이 있지만, 정식 출시된 거의 대부분의 패미컴 게임에서는 1번의 방법이 사용됩니다.
패턴테이블 내의 한개의 타일을 변경하기 위해서는 16바이트 만큼의 데이타 (타일을 구성하는 데이타)를 PPU에 입력해야하지만, 네임테이블을 변경은 단 1바이트의 데이타 입력으로 가능하기 때문입니다. 앞선 예를 들어 설명하면, ‘Hello World!’ 는 중간의 빈공간을 포함해서 12개의 타일로 이루어져 있는데, 1번 방법으로 대사를 출력하려면 12x16 = 192바이트의 데이타를 PPU 패턴테이블에 입력해야 하지만, 2번 방법을 이용하면 12바이트의 데이타만 PPU 네임테이블에 입력하면 됩니다. 단순 계산상 16배 빨리 대사를 처리할 수 있습니다. 물론 단순히 느려서 뒤의 방법이 잘 사용되지 않는 것은 아닙니다. 더 중요한 이유는 이것이죠.
4.2 Vertical Blank (Vblank)
이 전의 튜토리얼에서 패미컴의 PPU가 동시에 두가지 동작을 수행할 수 없다고 했죠 (*CPU로부터 입력받거나 *화면으로 출력하거나). 다시말해서 PPU에 데이타를 입력하려면 (패턴테이블/네임테이블 입력), CPU와 통신해야 하는데 이러면 화면으로는 아무것도 출력할 수 없겠네요. 아마 검은 화면만 보이게 될거예요. 만약 데이타 입력을 위해 잠깐 PPU를 껐다가 (화면 출력을 껐다가) 입력 후에 켠다면 화면이 깜빡이는 것을 볼 수 있겠네요.
“제가 게임하는 동안에는 대사 중간에 검은화면이나 화면 깜빡임이 보이질 않던데요?” 라고 반문하신다면 이야기를 잘 따라오고 계신거예요.
옛날 브라운관 TV는 전자총을 사용해서 화면의 색상을 표시했습니다. 쉽게, 전자라는 총알을 쏜 후 방향을 잘 조절해서 형광점에 맞추고, 그 전자의 충돌에 의해 방출된 빛을 이용해 색상을 표시하는거에요. 전자를 화면 상단부 왼쪽부터 오른쪽 끝까지 맞추고 (1라인), 한줄 내리고 다시 왼쪽 부터 오른쪽까지 (2라인),…. 반복해서 마지막 라인 (262라인, 화면 하단부 왼쪽부터 오른쪽)까지 맞추면 전자총의 총구가 (정확한 표현은 아닙니다) 화면의 오른쪽 하단을 가리키고 있겠네요. 여기까지의 싸이클을 ‘프레임’
이라고 합니다. 보통은 1초에 60번정도 진행이 되요. 아래의 그림을 보시면 이해가 빠를것 같습니다.
Fig.3 - Vertical blank (Vblank)
한 프레임이 끝나면 다시 전자총의 총구를 화면 오른쪽 하단에서 왼쪽 상단으로 위치시켜야 하는데 이때 생기는 갭을 (혹은 이때 필요한 시간) Vblank라고 합니다. 이 Vblank 때는 화면 업데이트가 잠깐 정지되는데, 이 때를 이용해서 PPU에 데이타를 입력하는 것이죠. 1초에도 60번씩 멈춰서는 TV를 전혀 인식하지 못하는 사람들은 당연히 게임이 물흐르듯이 연속적으로 진행된다고 생각하겠죠.
문제는 여기서 발생됩니다. Vblank가 정말 짧은 시간이라는 것이죠. 게임들이 Vblank기간에 처리해야 하는 코드들은 생각보다 많습니다.
- PPU 수정을 통해서 화면의 정보를 수정 - 화면을 끄지 않는다면 Vblank때만 수정가능
- 스크롤링 수정을 통해서 화면의 스크롤링을 컨트롤 - 화면이 움직이는 게임의 경우 이 작업이 없다면 화면이 깨짐
- 조이스틱의 반응과 연동해서 화면내 캐릭터의 움직임 정보를 수정 - 캐릭터가 움직이는 게임의 경우 이 작업이 없다면 캐릭터가 순간이동
- 음악을 재생 - 음악 재생이 지연됨 (템포가 느려짐 & 끊킴)
즉, 타일 수정 (대사 출력) 이외에도 해야할 작업들이 많기 때문에 꼭 필요한 업데이트만 수행하는게 안정적이며 다른부분의 희생이 없어도 되기 때문에 주로 1번 방법을 이용해서 대사를 출력하는 것입니다.
문제는 일본어나 영어와는 달리 이 방법으로는 완성형 한글을 표기할 수 없다는 거에요. 패턴테이블이 완성형 한글을 모두 넣기에는 턱없이 부족합니다. 같은 이유로 패미컴의 게임에서는 이후 콘솔의 게임들과는 달리 일본어도 히라가나로만 음역 표기된 게임들이 대부분입니다. (한글과 같은 이유때문에 한자를 사용할 수 가 없는거에요) 그래서 한글 완성형이 출력되게 대사루틴을 바꾸려면 1번을 사용하는 게임의 대사루틴을 2번으로 바꿔주어야 하는데, 이게 만만치 않습니다. 추후의 튜토리얼에서 설명할 예정이에요.
4.3 대사 루틴 (롬의 대사데이타 -> CPU ->> PPU)
다시본론으로 돌아와서 일반적인 대사루틴을 조금 더 분석해보도록 하겠습니다. 글자는 ‘타일’
이고, 대사는 패턴테이블에서 '글자 타일의 고유넘버'
입니다.
앞선 예제에서의 ‘Hello World!’ 는 패턴 테이블 고유번호 ‘21 04 0B 0B 0E 3F 30 0E 11 0B 03 34’ 가 되겠네요. 이 대사 데이타가 게임 롬의 어딘가에 들어있을거에요. 위와같이 주어질 수도 있고, 아니면 특별한 계산이 필요한 형태로 롬에 입력되어있을 수도 있죠.
예를들면 롬에는 ’51 34 3B 3B 3E 6F 60 3E 41 3B 33 64’의 데이타가 들어있을 수도 있죠. 이런경우 실제 대사는 앞의 데이타에서 30만큼을 빼준 값이 되겠네요. 경우에 따라서는 조금 더 복잡한 계산이 필요한 경우도 있고, 대사데이터에 필요한 공간을 줄이기 위해서 압축이 되어있는 경우도 있습니다. 이 경우 어떤식으로 압축이 해제되어 최종 대사 데이타가 계산되는지 알아야겠죠.
Fig.4 - 전반적인 그래픽 (타일 and 대사) 출력 과정
위의 이미지를 보시면 롬 내부의 게임 그래픽 데이타가 (타일) 어떤 과정을 거쳐서 화면으로 출력되는지를 알 수 있습니다. 이 시스템을 대사의 처리과정으로 한정한다면,
1) 롬 카트리지 내부의 대사 데이터가 2) 뱅크교환을 통해 CPU로 불려들여지고 3) 필요한 계산을 거쳐서 롬 영역에 결과값이 저장 (버퍼, Buffer) 이 되고 4) Vblank 때 그 계산된 값이 PPU로 입력되는거죠.
물론 이러한 선수과정 (버퍼의 사용, 미리 계산하는 과정) 없이 Vblank때 대사타일 계산부터 입력까지 모두 처리할 수 있지만 소중하고 짧은 Vblank를 낭비하지 않기 위해서 필요한 계산은 미리 해두고 Vblank 때는 PPU 업데이트만 하는 방식이 일반적으로 사용됩니다.
오늘도 글이 길어졌네요. 전반적인 설명과 이론은 이정도만 해도 한글화의 큰 그림을 이해하기에 충분할것 같습니다. 다음의 글부터는 예제를 통해서 조금 더 Practical 한 튜토리얼로 찾아뵙도록 할게요. 게임내의 대사를 찾고 수정하는 본격적인 글들로 찾아뵙겠습니다.
즐거운 하루 되세요!~
한글화하는 과정이 이렇군요. 항상 궁금했었는데ㅎㅎ
좋은 정보 공유 감사합니다!
방문 감사드려요!~ ^^&
용량문제로 각종 꼼수를 쓰던시절이라 한글화도 귀찮군요
그래도 뜯어보면 정말 대단한것 같아요. 정말 타이트하게 최후의 1바이트까지 아껴가며 작성된 게임들도 있더라구요 ㅎㅎ 필요한 코드를 추가하려고 해도 롬에 공간이 없어요 ^^;