1P by GN⁺ | ★ favorite | 댓글 1개
  • Magicore Anomala는 1985년 출시된 Amiga의 그래픽·사운드 능력으로 전체 화면 CG와 애니메이션식 전환을 구현하지만, 게임 엔진 안에서는 RAM 배치와 화면 분할, 스프라이트 제약을 동시에 풀어야 함
  • 일반적인 Amiga 500 구성에서는 그래픽·사운드에 쓸 수 있는 Chip RAM이 512KB뿐이라, 320x240·32색 CG의 48KB 비압축 크기가 큰 부담이 됨
  • CG는 ZX0 압축으로 약 8KB까지 줄여 확장 RAM에 두고, 표시 직전에 Chip RAM으로 풀면서 기존 화면 메모리 48,000바이트를 재사용함
  • 전환 효과는 copper가 특정 스캔라인에서 하드웨어 레지스터를 바꾸고 bitplane DMA를 끄고 켜는 방식으로 만들며, CPU는 매 프레임 split 폭에 맞춰 copperlist 값을 조정함
  • 배경의 motion lines는 Amiga 스프라이트의 색상·재사용·bitplane 의존성을 우회해야 하며, attached sprites와 더미 제어 비트, 1개 bitplane 유지, BPLMOD1 조정이 핵심 장치가 됨

Amiga 500에서 전체 화면 CG를 넣는 RAM 문제

  • Magicore Anomala의 대상 플랫폼은 일반적인 Amiga 500이며, 구성은 512KB Chip RAM과 512KB 확장 RAM임
    • Amiga 칩셋이 그래픽과 사운드 출력에 사용할 수 있는 메모리는 Chip RAM뿐임
    • 확장 RAM은 CPU만 접근할 수 있어 그래픽·사운드용으로 직접 쓰기 어려움
  • 전체 화면 캐릭터 그래픽(CG)은 320x240 비트맵의 32색 이미지이며, 비압축 상태에서 48KB를 차지함
    • 공통 애셋, 레벨 데이터, 화면 메모리 할당까지 고려하면 48KB는 큰 오버헤드임
  • 최근 추가된 애셋 압축 지원은 ZX0 압축 형식을 사용함
    • 압축된 CG는 약 8KB로 줄어듦
    • 레벨 애셋 로드 시 압축된 CG를 확장 RAM에 넣음
    • 표시 직전에 Chip RAM으로 압축 해제함

48KB Chip RAM을 새로 확보하지 않는 방식

  • CG를 위해 별도의 48KB 빈 Chip RAM을 찾지 않고, 기존 화면 메모리 일부를 재사용함
    • 방 배경 이미지
    • 위험 오브젝트 렌더링용 화면 레이어
    • 텍스트박스 화면 영역
  • 이 세 메모리 영역은 RAM에서 연속되어 있고, 합산 크기가 48,000바이트로 CG의 정확한 크기와 일치함
  • 방 배경 이미지는 CG 표시가 끝난 뒤 복원할 수 있어 덮어써도 문제가 없음
  • CG 압축 해제에는 약 500ms가 걸리지만, 컷신 흐름 안에 넣어 로딩처럼 보이지 않게 함
  • Magicore Anomala의 게임플레이 proof-of-concept 영상은 YouTube에서 볼 수 있음

화면 분할 효과와 copper 사용

  • 처음에는 세로 wipe 전환을 고려했지만, 보기 좋게 만들려면 스캔라인마다 색상 팔레트를 조정하는 그라디언트가 필요했음
    • copper만으로는 수평 블랭크 하나에서 32색을 모두 설정하기 어렵다고 판단함
    • “racing the beam”을 다루고 싶지 않아 화면 분할 효과를 선택함
  • 화면 분할 효과는 일반 시청자에게 더 멋져 보이고, Amiga의 copper가 사실상 이런 효과에 맞게 설계된 것처럼 동작함
    • 비슷한 효과가 Amiga Workbench에 내장된 사례는 이 영상에서 확인할 수 있음
  • 구현에는 Amiga의 두 기능이 함께 쓰임
    • copper는 CPU와 병렬로 자체 명령 목록을 실행하고, 특정 화면 라인에서 하드웨어 레지스터를 바꿀 수 있음
    • 화면 포인터를 하드웨어 레지스터로 설정해 화면 메모리를 Chip RAM의 어느 위치로든 바꿀 수 있음

bitplane DMA를 멈췄다가 다시 이어 그리기

  • 예시로 메인 화면 메모리가 0x20000에서 시작하면, 일반적으로 copper가 bitplane DMA 레지스터에 이 주소를 설정함
    • bitplane을 활성화하면 DMA가 해당 메모리 영역을 순서대로 읽으며 화면에 그림
  • 각 수평 라인이 0x100바이트를 차지할 때 화면 포인터를 0x20800으로 설정하면, 화면이 8라인 위로 스크롤된 것처럼 보임
    • 화면 시작점이 메모리상 8라인 아래로 이동하기 때문임
  • 분할의 위쪽 절반은 이 방식으로 위로 스크롤함
  • split 지점에서 copper는 bitplane DMA를 끄고 배경색을 빨간색으로 바꿈
    • bitplane 관련 하드웨어 레지스터는 그 시점에서 사실상 멈춤
    • split의 아래쪽에 도달하면 배경색을 복구하고 bitplane DMA를 다시 켬
    • 화면은 멈췄던 위치에서 다시 이어 그려지지만, 실제 표시 위치는 더 아래가 됨
  • 매 프레임 CPU는 split의 현재 폭에 따라 vs_TCopTopvs_TCopBottom을 조정함
    • 위쪽 split을 위한 화면 포인터 조정도 함께 이뤄지지만, 코드 예시에는 포함되지 않음

“woosh” 모션 라인을 위한 스프라이트 우회

  • 애니메이션식 배경의 motion lines는 스프라이트로 그림
    • 스프라이트는 화면 메모리와 독립적으로 그려지고 이동할 수 있어 이 용도에 적합함
    • 다만 Amiga 스프라이트는 제한이 많고 다루기 복잡함
  • 색상 제약

    • 스프라이트는 bitplane과 색상 팔레트를 공유하므로 가능한 적은 색상만 써야 함
    • motion lines는 3색만 사용해 CG에 28색, 배경에 1색을 남김
    • Amiga에서는 스프라이트 쌍마다 사용하는 팔레트 색상 범위가 다름
      • 첫 두 스프라이트는 색상 16-19를 사용함
      • 다음 두 스프라이트는 색상 20-23을 사용함
    • 두 스프라이트를 attach하면 16색 팔레트를 가진 하나의 스프라이트처럼 동작하며 색상 16-31을 사용할 수 있음
    • motion lines는 4개의 attached sprites를 사용하고, 그래픽에서는 색상 29-31만 씀
  • 같은 스프라이트 그래픽을 여러 위치에 쓰기

    • 스프라이트 그래픽의 처음 4바이트는 위치와 높이를 지정하는 제어 비트
    • 같은 그래픽을 여러 위치에 그리려면 이 구조가 문제가 됨
    • 하드웨어 레지스터로 스프라이트 제어 비트를 직접 설정하려 했지만, 화면에 표시되게 만들지 못함
    • Amiga sprite DMA는 bitplane DMA처럼 스프라이트 데이터 포인터를 따라가며 화면에 그림
    • 해결 방식은 4바이트짜리 가짜 스프라이트 8개를 만드는 것임
      • 이 가짜 스프라이트는 제어 비트만 포함함
      • 모든 스프라이트 포인터를 먼저 가짜 스프라이트로 설정함
      • 약 19라인에서 sprite DMA가 포인터를 보고 제어 비트를 장전함
      • 그 뒤 모든 포인터를 실제 “motion line” 그래픽으로 바꿈
    • 결과적으로 DMA는 서로 다른 위치에 스프라이트를 그리도록 장전된 상태에서 같은 그래픽을 사용하며, 이 전환은 copperlist에서 처리됨

bitplane을 끄면 스프라이트도 사라지는 문제

  • CG가 화면 상단에 도달하기 전에는 화면 위쪽과 CG 시작 지점 사이에 빈 공간이 있음
    • 이때 bitplane을 켜 두면 화면에 잡데이터가 그려짐
  • 해당 영역에서는 bitplane을 꺼서 DMA가 잡데이터를 읽지 않게 해야 함
  • 문제는 bitplane을 끄면 스프라이트도 그려지지 않는다는 점
    • motion lines가 CG의 경계 안에서만 보이는 현상이 생김
  • 해결책은 bitplane을 완전히 끄지 않고 1개만 켠 채, 화면 포인터를 빈 데이터로 설정하는 방식임
    • 화면에는 무언가를 그리지만 결과적으로 아무것도 보이지 않게 함
  • 빈 화면 전체를 마련할 필요는 없음
    • 1비트 픽셀 기준 320픽셀 한 줄은 320비트, 즉 40바이트임
    • BPLMOD1-40으로 설정하면 각 라인 뒤에 포인터가 40바이트 뒤로 돌아가 같은 40바이트를 반복해서 그림
    • 화면의 safety margin에 있는 처음 40바이트를 비워두면 충분함

결과와 남은 세부 과제

  • 처음에는 RAM 요구량 때문에 이런 CG를 게임에 넣을지 확신하지 못했지만, 데이터 압축 구현 뒤 오버헤드가 매우 합리적인 수준임을 확인함
  • Magicore에 추가적인 시각적 장식을 넣을 수 있게 됨
  • 다루지 않은 작은 과제도 남아 있음
    • 예를 들어 100px motion line이 화면 위로 벗어난 뒤 아래쪽이 갑자기 사라지지 않게 만드는 문제
  • 이 효과는 blitter를 전혀 사용하지 않음
  • Amiga는 1980년대 후반 사람들에게 인상적이었던 것처럼, 오늘날에도 컬러 그래픽 표시 능력으로 사람들에게 인상을 줄 수 있는 플랫폼으로 남아 있음

댓글과 토론

Hacker News 의견들
  • Racing the beam”이 무슨 뜻인지 정확히 알겠음. 예전에는 vsync된 루틴의 시작과 끝에서 빔 색을 다르게 바꿔서 프레임당 몇 스캔라인만큼의 CPU 시간을 쓸 수 있는지 계산했음
    이 용도로 쓰던 주소가 $dff180이었던 걸 기억함. 색상 팔레트 0이라 비트맵 영역 바깥 화면 가장자리에도 항상 보였음
    그 요령도 인터넷 없이 전부 입소문으로 배웠고, 요즘도 그 칩셋에서 더 뽑아내려는 사람들이 있는 줄은 몰랐음

  • Amiga에서 게임을 만들 시간을 내는 사람들이 어떤 층인지 진짜 궁금함. 젊은 사람들은 이런 오래된 컴퓨터에 관심이 없을 것 같고, 그걸 쓰며 자란 사람들은 가족과 일 때문에 바쁠 듯함
    바쁘지 않더라도 똑같이 재미있고 최신 감각도 유지할 수 있는 프로젝트가 너무 많음. 그래도 정말 멋지다

    • 1991년생이고, Windows 95 PC로 넘어가기 전 집에 Amiga 1000이 있었음. 그래서 늘 Amiga에 향수가 있었고, 그 성능을 만든 독특하고 강력한 칩들을 더 이해하면서 애정이 커졌음
      지금은 전업 인디 게임 개발자로 일함. Amiga 게임을 만드는 건 평생의 꿈에 가까웠고, 이제 그걸 해낼 기술이 생겼다고 봄
      오늘날의 도구와 널리 퍼진 지식을 활용하면, 현대적인 설계 원칙을 가진 게임 경험으로 사랑받던 클래식 하드웨어에 새 생명을 불어넣을 수 있음을 보여주고 싶음
    • 많은 사람에게는 Amiga, C64, Atari, ZX Spectrum만큼 재미있는 게 없음
      인생의 모든 걸 커리어와 연결하면 인생 전체가 일이 되어버림
      Photoshop이 있는데 왜 유화를 연습하냐고 묻거나, Tesla가 있는데 왜 빈티지 자동차를 복원하냐고 묻는 것과 비슷함
    • 이 그룹에 들어갈 만큼 어리진 않을 수 있지만, 내 시대보다 조금 앞선 컴퓨터들을 많이 좋아함. Commodore 64를 구해서 콘덴서를 교체하고, PLA도 바꾸고, 듀얼 SID와 “지역 전환” 개조까지 넣었음
      지역 전환 개조는 VIC-II 두 개와 발진기 두 개를 전환해야 해서 꽤 복잡함. MSX2도 갖고 있는데, 많이 하진 않았지만 매력이 큼
      이런 기계에 실제로 코드를 쓸 시간을 내는 건 어렵지만, 대부분의 직장인 취미처럼 영감이 올 때 밤과 주말을 쏟는 문제라고 봄
      레트로컴퓨팅은 매혹적이고 보람 있는 훌륭한 취미임. 다만 시간보다도 부품을 구하는 가격과 난이도가 더 불만임
      컴퓨터 시장에서 “앤티크”나 “빈티지” 딱지가 붙은 건 뭐든 비싸게 팔려는 사람이 많아진 듯해서 아쉬움
      나이가 더 많은 쪽은 직접 말하긴 어렵지만, 아직 Commodore 64 데모를 만드는 사람들 중 일부는 어린 시절과 다시 연결되려는 마음이 커 보임
      Bonzai와 Pretzel Logic의 비교적 최근 데모 “Mojo”처럼 거의 그런 이야기를 직접 들려주는 작품도 있음. demoscene 작품에서 “진지한” 스토리텔링을 하려는 건 좀 오글거리지만, 그래도 정감 있어서 좋음
      시간이 많이 드는 취미지만, 정말 시간을 내고 싶으면 결국 방법을 찾게 됨
      [1]: https://csdb.dk/release/?id=232966, https://www.youtube.com/watch?v=HXi3oJ9huiI
    • 새 게임 컨트롤러를 오래된 컴퓨터에 연결하는 인터페이스를 만드는 친구가 있음. 여기서는 Nintendo Balance Board로 Commodore 64의 Decathlon을 플레이하게 연결함
      [1] https://retro.moe/2024/02/04/bluepad32-v4-0/
      [2] https://www.youtube.com/watch?v=Nj5fZlt_834
    • 원글 작성자보다 5살 많음. 팬데믹 초기에 재미로 어셈블리를 배우려고 Atari, Amiga와 몇 가지 자료를 모았음. Udemy 강의도 있음
      https://www.udemy.com/course/programming-games-for-the-atari...
      재택근무를 하면 여유 시간이 더 생길 거라고 생각했지만 현실은 아니었음. 그래도 언젠가 계속 작업해야 함
  • Amiga에서 일본 콘솔풍 게임이 어떻게 보였을지, 그리고 Amiga가 성능이 부족했던 건지 아니면 대부분 게임의 디자인이 취향이 아니었던 건지 늘 궁금했음
    Bonk는 Factor 5가 훌륭하게 이식했지만, 그들은 거의 마법사였음

  • “평범한 Amiga 500에는 512KB Chip RAM과 512KB 확장 RAM이 있다”는 부분은 살짝 부정확함. 기본 A500에는 512KB Chip RAM만 있었음
    많은 사용자가 A501 RAM 확장을 추가해서 그래픽 하드웨어가 직접 접근할 수 없는 512KB Fast RAM을 더했음
    Fast RAM이라고 표기됐지만, 확장 구조 때문에 실제 Fast RAM보다 느렸음

    • 이른바 Slow RAM
      대부분의 A500 소유자는 512KB 트랩도어 확장을 갖고 있었음. Monkey Island 같은 게임을 포함해 많은 소프트웨어가 총 1MB RAM 없이는 실행되지 않았음
      요즘은 공개 하드웨어 설계의 저렴한 트랩도어 확장이 널리 나와 있고, 1.5MB Slow RAM, 총 1MB가 되도록 하는 512KB Chip RAM, RTC까지 제공함
  • 이런 제약 안에서 코딩하는 데는 믿기 어려울 만큼 끌리는 무언가가 있음

    • “예술의 적은 제약의 부재다”
  • IE 반가움. Amiga를 파고드는 모습 보니 좋음

  • 내가 했던 Amiga와 다른 Amiga를 가지고 논 사람들이 많은 것 같다는 느낌이 듦. 멋져 보이는 게임은 분명 있었지만 Nintendo NES도 그랬고, 둘 다 그렇게 애틋하게 돌아보진 않음
    그래도 이런 애니메이션이 어떻게 만들어졌는지 보여주는 건 아주 멋짐

    • 둘 다 갖고 있었는데, Amiga는 솔직히 두 세대 앞선 기계처럼 느껴졌음. 하드웨어 차이를 보면 놀랄 일도 아님
      Amiga는 정말 모든 걸 다 넣은 시스템이었음. 고급 32비트 CPU, 그래픽 가속, 훌륭한 오디오, NES의 말 그대로 256배 RAM을 갖고 있었음
      SNES조차 근접하지 못했고, Sega Saturn 시대가 되어서야 Amiga를 넘어서는 기계를 봤음
    • 혹시 확인차 묻자면, 이건 지금 개발 중인 새 게임이라는 건 알고 있는지?
      https://www.youtube.com/watch?v=4SB20aFHc08