안녕하세요?
모처럼만에 패미컴 튜토리얼 글을 이어갈 수 있게 되었네요. 지난 일주일간의 여가시간을 송두리째 앗아갔던 버그를 드디어 잡아냈습니다! 나중에 버그픽스 이야기를 할 때 자세히 적어둘 기회가 있을 것 같네요.
패미컴 (or NES) 게임 한글화 튜토리얼 #02
패미컴 (or NES) 게임 한글화 튜토리얼 #01
3. 패미컴의 화면 구성
본론으로 돌아와서 이번 글에서는 '패미컴은 어떻게 화면을 출력하는가?'
의 답을 찾아가는 여정을 적어둘까 합니다. 한글화와 별로 연관성이 없어보이지만, 이 부분에 관한 기초 없이는 앞으로 다룰 코드 수정을 이해하기 어려울것이라 생각해서 튜토리얼 부분으로 편입해서 글을 써나가도록 하겠습니다. 지겹지 않게 필요한 부분만 최대한 간단히 알려드릴게요.
3.1 타일 (Tile)
그 첫번째 과정으로 '패미컴은 무엇을 화면에 출력하는가?'
를 알아야 합니다.
Fig.1 - 스프라이트 예제 (마리오)
모두가 아시는 닌텐도의 대표 캐릭터인 마리오군을 소환해봅니다 (Fig.1). 이미지 안의 마리오는 불쌍하게도 8칸으로 잘려져 있습니다. 네, 맞습니다. 유기적으로 한몸처럼 움직이던 배관공 마리오는 사실 8개의 '타일'
로 이루어진 타일들의 세트였던 것이죠.
그러면 타일이란 무엇일까요? 직관적으로 여러분들의 주방이나 화장실에 붙어있는 정사각형의 그것을 떠올리신다면, 정확합니다. 단지 그것이 8칸 8줄 총 64개의 작은 정사각형으로 좀 더 세분화 되어졌을 뿐이죠. 즉, 패미컴의 그래픽을 구성하는 최소단위인 타일은 64개의 점 '도트, 픽셀'
로 이루어져 있습니다. 위의 마리오 그림의 왼쪽 상단에 자세히 그려져 있군요.
여기서 타일을 구성하는 64개의 점들을 각각 전구라고 생각해보아요. 만약, 각각의 전구들을 제어할 수 있는 64개의 스위치가 있다면 그것들을 켜고 끄면서 여러 모양을 만들어낼 수 있겠지요. 즉, 한개의 타일을 표시하려면 최소 64개의 비트 (1비트는 2진수로 on/off의 시그널입니다, 스위치 같은 느낌이에요) = 8바이트의 데이타가 필요합니다.
하지만, 8바이트의 데이타만으로 타일을 표시한다면 단 두개의 색 이외에는 표시할 수 없겠지요. 앞선 전구 이야기로 돌아가보면 8바이트의 데이타(64개의 스위치)로는 파란색의 전구도 빨간색의 전구도 켤 수 없습니다. 오직 흑색(Off)과 백색(On)이 있을 뿐이죠.
다행히(?) 패미컴에서의 타일은 16바이트의 데이타셋으로 구성되어집니다. 따라서 한개의 타일 내에서 총 4가지나 (!) 되는 색상을 사용할 수 있어요! (물론 패미컴에서 사용가능한 색상셋은 총 64개며, 그나마도 같은 색상을 제외하면 그것보다도 줄어들죠, 색상셋은 Fig2에서 확인하실 수 있습니다)
Fig.2 - NES 색상 셋 (출처)
3.2 패턴테이블 (Pattern table) & 네임테이블 (Nametable)
간단히 말씀드리면, 패턴테이블은 앞서 설명드린 타일들의 세트
입니다. 0번과 1번세트으로 구성되어져 있으며, 각 세트는 256개의 타일들로 이루어져 있습니다. 이 타일들을 이용해서 화면에서 움직이고 있는 동적 캐릭터 (스프라이트)와 배경 (백그라운드)의 모든 그래픽을 표시하는 것이죠. 즉, 패턴테이블에 없는 타일을 화면에 표시할 수는 없습니다. 스프라이트와 백그라운드는 아래 그림을 통해 한눈에 알아보실 수 있을 것 같아요.
Fig.3 - 스프라이트와 백그라운드
백그라운드를 구성하는 타일들의 세트를 네임테이블
이라고 합니다. 한 화면을 구성할 때 총 32x30 =960 타일, 한개의 타일들이 8x8이므로 총 256x240 개의 도트(픽셀) 로 구성합니다. 네, 패미컴의 화면 해상도는 10년전의 핸드폰보다도 낮습니다. 패턴테이블과 네임테이블의 설명은 다음의 그림에서 직관적으로 확인하실 수 있을것 같네요.
Fig.4 - 패턴테이블과 네임테이블
그림에서 나타난 것 처럼 패턴테이블 내의 타일들은 고유한 숫자를 가지며 그 숫자들의 조합으로 네임테이블의 화면을 구성하는 것이죠. 패턴테이블은 타일들의 세트이므로 각각 타일들의 데이타가 들어있습니다. 그 예로 그림에 보이는 40번 타일의 데이타를 살펴보면 아래와 같습니다 (40번 타일의 모양을 기억해두세요)
FIG.5 - 타일 데이타 세트 (16바이트) 예시
한개의 타일 (40번 타일 = 맨 아래 그림)을 구성하려면 총 128개의 스위치 (16바이트)가 필요하겠죠. 첫번째 64개의 스위치는 각각 1과0을 두번째 64개의 스위치 역시 각각 1과 0을 표시합니다. 하지만 두번째 스위치의 1의 실제 의미는 1이 아니고 2입니다. 따라서 두 스위치의 합연산을 통해 얻어진 마지막 타일은 0,1,2,3의 총 4가지의 숫자를 가지게 되는 것이죠. 이 숫자의 의미는 색상이므로 총 4가지의 색상을 표시할 수 있는 것입니다. 다만, 예제로 보여드린 40번 타일의 경우 두가지의 색상밖에 없으니 맨 마지막 타일 그림에서 3이 없는 것이죠.
3.3 Picture Processing Unit (PPU) 메모리맵
이제 앞서 말씀드린 타일 데이타세트 (패턴테이블), 백그라운드 타일세트 (네임테이블)이 어디에 저장되고 어디에서 엑세스 되는지를 알아봐야겠네요.
패미컴은 특이하게도 PPU가 따로 있어서 그래픽 데이타를 출력해줍니다. 즉 CPU에서 연산을 통해 혹은 뱅크교체를 통해 얻어진 타일들의 데이타 (패턴테이블), 타일셋 (네임테이블)들이 1) PPU로 옮겨지고, 그 후 2) 화면에 출력되는 것이죠. 하지만, 이 바보같은 PPU는 CPU로 부터 데이타를 받는 것과 화면으로 출력하는 것을 동시에 수행하지 못합니다. 즉, CPU 와 통신하거나, 화면을 출력하거나 둘중 하나만 할 수 있는 것이죠 (이부분은 완성형한글 출력에 중요한 부분이므로 나중에 따로 하나의 글로 따로 다뤄야 할 것 같아요)
다시 본론으로 돌아와서, 아래의 그림을 보면 PPU의 메모리맵과 해당 메모리영역에 어떠한 데이타들이 포함되는지 알 수 있겠네요. PPU는 총 16KB의 메모리로 이루어져있습니다 (CPU는 64KB였죠, MB가 아닙니다)
Fig. 6 - PPU 메모리맵
메모리맵에서 보시는 바와 같이 네임테이블과 패턴테이블 이외에도 다른 요소들이 있지만, 스크롤 & 미러링관련 요소들과 색상관련요소들은 한글화에서 필요하지 않는 부분이기 때문에 생략하도록 합니다. 만약 여러분들이 슈퍼마리오 브로스게임에 록맨캐릭터가 나오길 원하신다면 혹은 캐릭터의 색상을 수정하시고자 한다면, 이부분 역시 자세히 다뤄야겠지요.
모두 긴 글 읽으시느라 수고 많으셨습니다. 여기까지 해서 '패미컴은 화면에 무엇을 출력하는가?'
에 관한 의문은 풀리셨을거라 생각합니다. 어떻게 화면을 출력하는지에 대한 부분은 튜토리얼이 진행됨에 따라 그때 그때 조금씩 다루도록 하겠습니다. 어차피 출력루틴을 바꾸는것이 완성형 한글화에 있어서 필수적이기 때문이죠 (레지스터와 코드들만 따로 다루기에는 너무 난해하고 지루합니다)
지금 작성하고있는 튜토리얼과 진행중인 한글화가 동시에 진행되고 있어서 글이 쓰여지는 주기가 느려지고 있는 것 같네요. 원래 알고 있었던 내용을 쓰는 것이 아니라 한글화를 진행하면서 새로 알아가고 있는 것들을 정리하는 차원에서 쓰고 있는 것이라 어쩔 수 없는 것 같습니다 (공부하고 이해하는데 시간이 많이 걸리네요).
조만간 다음글에서 뵙도록 할게요. 모두 즐거운 하루 보내세요!@~
PS) 선행되고 있는 한글화는 출력루틴 수정까지는 완료가 되었어요! 이제 한글을 쓸 수가 있답니다.
10년전핸드폰이면 패미컴같은건 상대도안되는 고사양이긴하죠 ㅎㅎㅎㅎ
네, 첫 스마트폰 옴니아도 사양은 물론이고 해상도도 480x800이었네요 ㅎㅎ
이야! 좋은 글 입니다.
bit의 세계를 보는 것도 즐겁네요.
PPU는 그래픽 출력을 담당하는 unit이네요.
요즘 하는 프로그래밍에 비하면 엄청나게 제약이 많아 보입니다.
슈퍼마리오를 어떻게 코딩한건지 도무지 감이 오지 않네요.. 저 하드웨어를 가지고 그 조작성이라니..
앞으로도 연재 부탁드립니다! :D
그러게요 ㅎㅎ 슈퍼마리오 초기작은 고작 40KB의 용량으로 구현해낸 게임이라고 하네요. 방문 감사드려요! 읽어주시는 분이 계셔서 힘이 됩니다 &^^