2P by GN⁺ | ★ favorite | 댓글 1개
  • doom-htophtop의 프로세스 목록을 그래픽 출력처럼 사용해 Doom 계열 게임 화면을 ASCII 형태로 보여주는 실험적 프로젝트임
  • 실행에는 WAD 게임 데이터 파일이 필요하며, 저장소에는 freedoom1.wad가 포함되어 있고 classic shareware DOOM1.wad는 별도 다운로드 대상으로 안내됨
  • 동작 방식은 Doom 프로세스가 화면 줄 수만큼 자식 프로세스를 만들고, 각 프로세스가 공유 메모리에서 받은 한 줄을 자신의 argv[0] 에 써서 htop의 프로세스 이름 영역에 프레임을 구성하는 방식임
  • htop은 프로세스 이름을 매번 갱신하도록 설정해야 하며, -d 1로 약 10 FPS 새로고침을 목표로 하고 -s M_VIRT로 가상 메모리 기준 정렬을 사용함
  • 키보드 입력은 키보드 장치를 여는 간단한 keylogger 방식이라 sudo가 필요할 수 있고, Ubuntu 22.04에서만 테스트되어 WSL과 Arch는 장치 경로 조정이 필요함

프로젝트 목적과 실행 형태

  • doom-htophtop이 고전 비디오게임 그래픽을 렌더링하는 데 쓰일 수 있는지 확인하기 위해 만든 프로젝트임
  • 결과 화면은 Doom을 htop의 프로세스 목록 위에 ASCII 영상처럼 표시하는 형태임
  • 프로젝트는 ozkl/doomgeneric을 포크했으며, Doom 실행 관련 무거운 작업은 해당 프로젝트가 담당함

빌드와 필요한 게임 데이터

  • 빌드는 doomgeneric 디렉터리에서 make -j8로 수행함
cd doomgeneric
make -j8
  • 실행하려면 WAD 게임 데이터 파일이 필요함
    • 저장소에는 freedoom1.wad가 포함되어 있으며, 크레딧은 The Freedoom project에 있음
    • classic free shareware 버전 DOOM1.wadDoom Wiki에서 받을 수 있음
    • DOOM1.wad는 GitHub에 올려도 법적으로 괜찮은지 확신하지 못해 포함하지 않았음

실행 방법과 htop 설정

  • 실행 전 중요한 작업을 저장하라는 안내가 있으며, 테스트 환경은 12년 된 Lenovo ThinkPad T430s, 8GB RAM, Intel Core i7-3520M @ 2.90GHz, Ubuntu 22.04였고 정상 동작함
  • 기본 실행 명령은 다음과 같음
sed -i 's/update_process_names=0/update_process_names=1/' ~/.config/htop/htoprc
sudo ./doom-htop -iwad freedoom1.wad
htop -d 1 -s M_VIRT
  • doom-htophtop 중 어느 것을 먼저 실행해도 상관없음
  • sudo는 키보드 장치를 열기 위해서만 필요함
    • sudo 없이 실행하면 입력은 어렵지만 화면은 볼 수 있음
  • htop -d 110 FPS 새로고침을 노린 설정임
  • htop -s M_VIRT는 가상 메모리 할당량 기준으로 프로세스를 정렬해 관련 프로세스가 보기 좋게 묶이도록 하기 위한 설정임
  • 정렬이 잘 맞지 않으면 main.cPROCS_MALLOC_SIZE 값을 조정할 수 있음
  • sed 명령은 htop이 기본적으로 프로세스 이름을 매번 갱신하지 않기 때문에 필요함

내부 동작 방식

  • 저장소는 기존 doomgeneric에 주로 세 파일을 추가함
    • main.c
    • keylogger.c
    • ascii_stuff.c
  • ascii_stuff.c에는 단순 이미지-to-ASCII 변환기가 생성한 긴 if 문이 들어 있음
  • 메인 Doom 프로세스는 ASCII 변환 이미지의 줄 수만큼 프로세스를 fork로 생성함
  • 메인 프로세스는 각 자식 프로세스와 공유 메모리 세그먼트를 만들고, 이미지의 각 줄을 대응하는 프로세스의 메모리 세그먼트에 복사함
  • 각 자식 프로세스는 자신의 세그먼트에서 내용을 복사해 argv[0]을 덮어씀
  • htop은 프로세스 이름으로 표시되는 argv[0] 값을 갱신하면서 화면의 한 줄씩을 보여주게 됨

정렬 아이디어와 입력 처리

  • 초기 아이디어는 CPU 사용량 기준 정렬이었고, 특정 CPU 사용률을 소비하는 프로세스를 만들려 했지만 구현이 어려웠음
  • Linux의 nice 값도 고려했지만 일반 사용자에게 가능한 값이 19개뿐이라 더 나은 그래픽에는 부족하다고 판단함
  • 최종적으로 가상 메모리 할당량을 사용했으며, 프로세스별로 꽤 구체적으로 조정할 수 있다고 봄
  • 모든 fork 프로세스가 같은 양의 메모리를 할당해도 테스트 시스템에서는 htop이 프레임을 올바른 순서로 보여줌
    • 동률일 때 생성 시간 기준으로 정렬되는 것일 수 있다고 추정함
    • 다만 다른 시스템에서 어떻게 동작할지 확신하지 못해 같은 값에 의존하지 않음
  • 키 입력은 키보드 장치를 여는 간단한 keylogger로 처리함
    • 이 방식 덕분에 htop이 열려 있지 않아도 게임은 백그라운드에서 계속 실행됨

플랫폼과 문제 해결

  • 테스트는 Ubuntu 22.04에서만 수행됨
  • WSL과 Arch에서는 키보드 장치 이름이 다르며, 이식이 필요함
  • 키보드가 동작하지 않으면 main.c#define KEYBOARD_DEVICE 값을 확인해야 함
    • /dev/input/by-path에서 kbd가 들어간 항목을 찾아 선택하는 방법이 안내됨
  • 프레임이 멈춰 있으면 sed 명령이 적용되지 않았을 수 있음
    • htop에서 F2 → “Display options” → “Update process names on every refresh”를 체크해 수동으로 설정할 수 있음
  • ~/.config/htop/htoprc가 없다는 오류는 htop을 한 번도 실행하지 않았을 때 발생할 수 있음
    • htop을 실행했다가 종료한 뒤 sed 명령을 다시 실행하면 됨
  • 메인 Doom 프로세스가 크래시해 좀비 프로세스가 많이 남으면 다음 명령으로 정리함
sudo pkill doom-htop

남은 작업과 라이선스

  • htop은 방향키로 이동할 때 화면을 움직여 게임 조작 중 불편할 수 있음
    • 게임 시작 후 a를 눌러 프로세서 선택 메뉴로 포커스를 바꾸는 단순한 우회책이 제안됨
  • 제작 이유는 funny였음
  • Freedoom은 메인 디렉터리의 freedoom-license.txt에 있는 BSD 유사 라이선스로 배포됨
  • 나머지 코드는 GPL로 보인다고 안내됨

댓글과 토론

Hacker News 의견들
  • 생각해 보면 “비디오”를 ASCII로 렌더링한 뒤 프로세스 이름에 넣는 건 꽤 쉬워 보이기도 함
    DNS 위에서 돌아가는 장난감 프로젝트들과 비슷하고, README에서도 대부분의 작업은 다른 프로젝트가 했다고 하니 특별해 보이지 않을 수 있음
    반면 htop을 무언가의 렌더링 엔진으로 볼 생각은 전혀 못 했을 것 같아서, 정말 놀랍고 인상적인 소프트웨어 해킹임

    • 대충 생각하면 쉬워 보이지만, 실제로는 좋은 대비와 성능을 얻는 게 그렇게 사소하지 않음
      libaa나 libcaca만 봐도 이 주제에 수백 시간을 쓴 예가 있음
    • 개념적으로 이해하기는 쉬울 수 있지만, 구현은 꽤 어려워 보임
  • 거꾸로 된 PSDoom[1] 같은 셈인가 봄
    이 제출물은 프로세스 관리자로 Doom을 플레이하는 것이고, PSDoom은 Doom으로 프로세스 관리를 하는 것임
    [1]: https://psdoom.sourceforge.net

    • 반대 방향도 보고 싶다고 쓰려 했는데, 이미 존재한다는 게 놀랍지는 않음
      현재 Linux에서 돌도록 포팅한 영상도 있음: https://youtu.be/Pf7rpde49NU
      다만 top 대체품으로 좀 더 실제로 유용하면 좋겠음. 몬스터 크기는 메모리 사용량, 공격성은 CPU 사용량에 기반하고, 방은 사용자별로 나누며, 스레드와 부모/자식 프로세스도 관계가 보이게 할 수 있음
      잠자는 프로세스는 당연히 자고, 좀비 프로세스는 공간에 얼어붙어 있거나 투명해서 통과 가능하게 만들 수 있음. 무기는 kill 시그널에 대응시키면 됨
      더 추가할 것도 많지만 그러면 점점 Doom에서 멀어짐
    • rm -rf랑 같이 쓰면 재미있겠음
  • 이런 걸 할 시간이 어떻게 나는지 정말 궁금함
    이런 멋진 걸 볼수록 내 능력에 대한 확신이 점점 줄어듦
    이전 작업을 활용해서 ASCII로 다시 렌더링하고 프로세스에 매핑한 것이라는 얘기도 있었지만, 그게 결코 적은 작업은 아님
    얼마나 걸렸을지 궁금하고, 이 업계에 꽤 오래 있었는데도 아무것도 모르는 느낌임. 멋지지만 스스로가 엄청 바보처럼 느껴짐

    • 따뜻한 말 고맙고, 너무 자책하지 않아도 됨
      본인이 생각하는 것보다 훨씬 많은 걸 알고 있을 가능성이 큼
      이 작업은 주말 내내와 하루 정도, 그리고 시간이 날 때 며칠 더 조금씩 작업해서 만들었음
      댓글 어딘가와 README에도 썼듯이, Doom을 더 이식성 있게 만드는 어려운 작업은 fork한 doom-generic 프로젝트가 해둔 것임: https://github.com/ozkl/doomgeneric
    • 하루 8시간 일하고 출퇴근 1시간이면 15시간이 남음
      먹고 자고 씻고 이것저것 해야 하지만, 그런 건 신경 쓰지 않으면 15시간 그대로 남음
      3년이면 충분히 만들 시간이 있음
      이제 6502용 레이캐스터를 마저 끝내야겠음
    • 너무 익숙한 느낌임
      친구들의 Instagram에 올라온 완벽한 집 사진을 보며 자존감을 깎아내리는 것의 프로그래머 버전 같음
      대부분 가끔은 그렇게 느낄 것이고, 대응 방법도 있지만 똑똑한 사람들 주변에 있다 보면 생기는 아주 정상적인 부작용임
    • 이런 걸 볼 때마다 아이가 없던 시절을 떠올리게 됨
  • “무언가에 Doom 넣기” 흐름은 거의 완성 단계에 도달한 느낌이고, 이제는 일상적인 것들을 Doom 안에 넣기 시작할 때가 됐음
    Doom 안의 Todo 목록이나 캘린더를 상상해 보면 됨

    • 엄밀히 말하면 그건 Doom 안의 Todo 목록이나 캘린더가 아니라, Todo 목록이나 캘린더 안에서 돌아가는 Doom임
      Todo 앱 쪽은 이미 체크박스로 렌더링한 Doom이 있으니[1], 그걸 Todo 앱에 통합하는 건 독자의 연습 문제로 남겨두면 됨
      [1]: https://healeycodes.github.io/doom-checkboxes/
    • “무언가에 Doom 넣기” 흐름이 끝나간다고 느낀다면, 아직 이 세계에 새로 온 것 같음
    • “조류가 DOOM을 플레이한다”를 봤을 때도 똑같이 생각했음
  • 이 프로젝트를 일주일쯤 전에 우연히 보고 여기 올렸지만 반응이 없었음
    이제 프론트 페이지에 올라온 걸 보니 반갑고, 이런 재미 위주의 해키한 프로젝트가 올라오는 게 좋음

  • 훌륭한 해킹임
    해커 정신이 아직 살아 있는 걸 보면 기분이 좋아짐

  • 가끔 사람들은 기술을 너무 멀리 가져가지만, 이번은 그런 경우가 아님

  • Windows 작업 관리자에서 돌린 Bad Apple이 떠오름
    https://youtu.be/sBeI30ccb6g

  • 순수하고 멋진 광기임. A+

  • 앞으로 이 게임이 또 어디에서 실행될지 상상도 안 됨