본문 바로가기

칼럼

나는 이렇게 게임 프로그래머가 되었다 -2-

나는 이렇게 게임 프로그래머가 되었다 -1-

게임을 만들기 위해 공부할 것은 지나치다 싶을 정도로 많습니다. 진심입니다. 진심으로 공부할게 너무 많습니다. 아마 단일 소프트웨어로는 운영체제, DBMS 다음으로 복잡한 물건이 아닌가 싶을 정도입니다. 아마 모두 다 공부하려고 책을 쌓아놓는다면 미리 포기부터하게 될 겁니다. 따라서 흥미가 있는 부분을 하나씩 파헤쳐보는 점진적인 과정이 중요하죠.

옛날 얘기를 좀 해보지요.

제가 게임 프로그래밍을 본격적으로 공부한 것은 94년부터입니다. 그때부터는 게임 프로그래밍에 필요한 것이 뭔지 닥치는 대로 찾아봤죠. 우선 대부분의 게임을 C로 만든다기에 C언어 부터 공부했습니다. 한동안 (한 반년쯤?) 포인터에서 딱 막혀서 탱자탱자 (게임하며) 놀던 기간도 있었지만 대개는 책 보면서 닥치는 대로 짜 봤습니다. 포인터의 개념을 터득한 후에는 책에 나온 도서관리 프로그램 따위의 예제를 짜봤죠.

C로 기본적인 것들을 대충 익히고서는 본격적인 게임에서 많이 쓰이던 그래픽을 어떻게 구현하는지가 궁금했죠. 당시 대부분의 게임이 320*200*8bpp[각주:1], 혹은 640*480*4bpp의 그래픽 품질로 구현되고 있었고, 일부 고사양게임들은 640*480*8bpp의 그래픽 품질을 보여주던 시절이었습니다. 그리고 그중에서도 극히 고사양을 요구하는 (윙커맨더[각주:2]와 같은) 게임들은 640*480*8bpp에서 3D 렌더링을 구현하고 있었습니다. 당연히 이러한 그래픽을 어떻게 구현하는지가 궁금했죠. 그때까지 쓰던 터보 C++ 2.0 에서 제공하는 그래픽 라이브러리(BGI)에서는 저런걸 할 수 없었기 때문이죠. 하더라도 끔찍하게 느린 속도를 감수해야 했죠. 게임에서 쓰던 방식은 아니란 걸 알았습니다.

그 답은 PC통신의 프로그래밍/게임제작 동호회 등을 뒤져가며 인터럽트란 것에 대한 개념을 주워들으면서 얻을 수 있었죠. 하드웨어에 인터럽트를 날리면 하드웨어에서 특정한 동작을 수행하며, 그래픽스 하드웨어에 인터럽트를 날리면 그래픽에 관한 원하는 동작을 수행할 수 있다는 것 정도가 파악되었습니다. 그때부터 여기저기서 찾아본 정보로 (지금도 업데이트되고 있는) Ralph Brown's Interrupt List 라는 것의 존재를 파악했습니다. 거의 모든 하드웨어의 인터럽트 펑션에대한 자세한 정보가 기술되어 있는 리스트였죠. 당시에 조금이라도 프로그래밍을 한다 싶은 사람들은 저마다 하나같이 RalphBrown's Interrupt List가 중요한 참고자료 중 하나였을 겁니다. 저도 DOS에서 그래픽스 라이브러리를 구현해 보는 데에 RBIL이 매우 좋은 참고자료가 되었습니다.

옛날 DOS게임을 할 때 궁금했던 것 중 하나는 게임을 실행하면 (DOOM같은 것들) 프롬프트에 스크롤되어 올라가던 다음과 같은 문구였습니다.
약간 설명을 하자면, 당시 640*480*8bpp 이상의 그래픽 품질을 구현하고자 했을 때 가장 걸림돌이 되었던 것은 16비트 운영체제였던 DOS의 64kb 세그먼트[각주:3] 제한이었습니다. 단순 산술계산으로도 640 * 480 * 8bpp = 2457600bit = 300kb 이기 때문에, 5개의 세그먼트를 오가며 메모리에 접근해야 했죠. 비디오 메모리의 접근 세그먼트를 변경하는 것도 비디오 하드웨어의 인터럽트 펑션중 하나였습니다. 저는 당시 게임에 많이들 쓰고 있던 DOS/4GW의 정체가 이러한 제약과 관련이 있다는 것을 알아낼 수 있었습니다. 이러한 제약은 DOS가 인텔계열 CPU의 리얼모드만을 이용하는 OS이기 때문이며, 이를 보호모드로 전환하면 주소공간이 32비트로 확장되어 최대 4gb에 이르는 메모리를 세그먼트전환 없이 사용할 수 있게 되는 구조였죠. 즉, DOS에서 보호모드를 사용할 수 있게 해주는 실행환경이 바로 DOS/4GW였던 것입니다. DOS/4GW는 당시 최적화가 잘 되기로 소문이 나 있던 Watcom C++과 함께 배포되어 WC의 기본 프로젝트 세팅중 하나로 선택할 수 있었죠. 저는 '세그먼트 전환이 없는 그래픽 라이브러리'를 목표로 어렵사리 (당당하지는 못한 방법이었지만) Watcom C++ 의 한 카피를 구해서 구현 해보았죠.

위의 이야기들은 옛날 이야기고, 지금에 와서는 전혀 쓸 일이 없는 기술들이고, 제가 왜 아직까지 이런 것들을 기억하고 있는지가 신기할 지경인 일들입니다. 하지만 남은 것도 좀 있지요. 인터럽트와 보호모드는 모두 현대 CPU와 OS의 구조를 이해하는데에 결정적인 키워드입니다. 인터럽트 리스트를 뒤져가며 그래픽 라이브러리를 구현해본 것도, 개발툴 매뉴얼을 보며 보호모드 전환을 해본 것도, 모두 현대 컴퓨터의 구조를 이해하는 데에 매우 큰 도움이 된 것 같습니다.
물론, 위의 과정을 거치면서 얻은 가장 큰 소득은, 앞으로 프로그래밍이란 작업을 어떻게 해야 하는 지를 몸으로 익혔다는 점입니다. 바로, "한가지씩 해본다"는 철학이죠.


다음에 계속
나는 이렇게 게임 프로그래머가 되었다 -3-

필자 : Uhm

경력 6년차의 게임 프로그래머. geek의 화신이며 포스를 수련한다는 소문도 있습니다.
홈월드나 토탈어나힐레이션, COH 같은 RTS와 FPS를 좋아하지만 요즘은 아내와 함께 기타히어로를 하는 가정적인 남편이기도 합니다.

언제나 후배들에게  포스의 어두운면에 대한 주의를 설파하는 뼛속까지 프로그래머.
  1. bpp 는 bit per pixel의 약자로 한 점의 색을 나타나는데 사용한 데이타의 양을 나타내는 단어입니다. 8bpp라면 한 점을 나타나는데 8비트를 사용했다는 의미입니다. [본문으로]
  2. 1990년에 처음 선보인 윙커맨더 씨리즈는 이후 새 시리즈가 나올 때마다 사람들이 게임을 하기 위해 컴퓨터를 업그레이드 하는 풍속을 만들 정도로 인기 있는 우주 전투 시뮬레이션 게임이었습니다.

    from wikipidea [본문으로]
  3. 한번에 한 덩어리로 접근이 가능한 메모리의 단위. 전체 메모리에 접근하기 위해서 세그먼트란 단위로 나누어서 현재 세그먼트의 시작점을 기준으로 메모리를 접근하는 segmented memory model에서 사용한다. DOS는 16비트 주소체계를 갖고 있었으므로, 한 세그먼트의 최대크기는 2^16 = 64kb 입니다. [본문으로]