2P by neo 3달전 | ★ favorite | 댓글 1개

왜 Zig로 게임보이 어드밴스 게임을 작성했는가

  • 게임보이 어드밴스의 매력
    게임보이 어드밴스는 현대적인 CPU(32비트 ARM, 많은 레지스터)를 가지고 있지만, 오래된 타일 기반 렌더러를 사용함. 이는 NES가 80년대에 사용했던 방식과 유사함. 닌텐도의 마지막 타일 기반 시스템 중 하나로, 아핀 변환, 투명도, 스프라이트 효과 등 다양한 기능을 제공함.

  • Zig 언어 선택 이유
    초기에는 C++로 게임보이 어드밴스 프로젝트를 시작했으나, Zig로 첫 완전한 게임을 작성함. Zig는 아직 베타 버전이고, 게임보이 어드밴스가 출시된 지 15년 후에 만들어진 언어임에도 불구하고, 임베디드 프로그래밍에 적합한 기능을 제공함.

툴체인

  • Linux와 devKitPro
    Linux를 사용하면서 패키지 관리의 어려움을 겪었고, Nintendo DS용 3D 장면을 만들 때 devKitPro를 사용해야 했음. 이는 GCC 툴체인, 라이브러리, 개발 도구를 포함하고 있음. ArchLinux 패키지 관리자를 통해 설치해야 하는 번거로움이 있음.

  • Zig의 장점
    Zig는 크로스 컴파일을 쉽게 해주며, 복잡한 패키지 관리자를 설정할 필요가 없음. Zig의 빌드 시스템은 build.zig 파일의 build 함수를 실행하여 빌드를 진행함. 이는 빌드 프로세스를 간소화하고 오류를 줄여줌.

Packed Structs

  • Packed Structs의 중요성
    게임보이 어드밴스는 고급 API 호출 없이 레지스터를 통해 하드웨어를 제어함. Zig의 packed struct는 메모리 레이아웃을 최적화하여 하드웨어 제어를 쉽게 해줌. 이는 게임보이 어드밴스 프로그래밍에 매우 유용한 기능임.

Comptime

  • 컴파일 타임 코드 실행
    Zig는 컴파일 타임에 코드를 실행할 수 있는 기능을 제공함. 이는 런타임에 데이터를 압축하지 않고 컴파일 타임에 압축할 수 있게 해줌. Zig의 이 기능은 데이터를 쉽게 압축할 수 있게 해줌.

표준 라이브러리

  • Zig의 유연한 표준 라이브러리
    Zig의 표준 라이브러리는 제네릭을 지원하며, 메모리 할당 함수에 메모리 할당자를 인자로 받을 수 있음. 이는 사용자 정의 메모리 할당 방식을 사용할 수 있게 해줌. Zig의 표준 라이브러리는 하드웨어 제약이 있는 환경에서도 유연하게 사용할 수 있음.

문제점

  • 인라인 어셈블리
    Zig는 인라인 어셈블리를 지원하지만, 출력이 하나만 가능함. 이는 GBA의 BIOS 함수에서 여러 값을 출력해야 할 때 문제가 됨.

  • Thumb 코드/ARM 코드
    게임보이 어드밴스의 CPU는 ARM 모드와 Thumb 모드를 지원함. Zig에서는 ARM과 Thumb 모드를 명시적으로 지정할 수 없음.

  • 이상한 메모리
    게임보이 어드밴스의 비디오 메모리는 8비트 단위로 쓸 수 없으며, 이는 그래픽이 엉망이 되는 문제를 유발함. Zig는 메모리 복사 시 memcpy를 사용하여 최적화하지만, 이는 GBA의 "이상한 메모리"와 충돌할 수 있음.

Hacker News 의견
  • 특정 주소 범위의 메모리 접근 방식을 지정할 수 있는 방법이 필요함. Zig 문서에서 volatile을 사용해도 해결되지 않으면 컴파일러에 버그를 제보할 것을 권장함
  • 5년 전 Linux를 사용하기 시작한 이유는 Windows에서 Python을 설정하는 방법을 몰랐기 때문임. 1997-2015년 동안 Windows가 지배적인 운영체제였고, 이로 인해 젊은 층의 지식 부족이 심화되었음. 초기에는 인터넷 접근이 보편적이지 않았고, 프로그래밍 환경이 없는 운영체제는 프로그래밍 기회를 놓치게 했음
  • Game Boy Advance에서 비디오 메모리를 8비트 단위로 쓸 수 없으며, 그렇게 하면 그래픽이 엉망이 됨. 에뮬레이터에서는 작동했지만 실제 하드웨어에서는 문제를 발견하고 수정해야 했음. Nim 언어를 위한 GBA 툴체인이 개발되었음
  • 컴파일러가 메모리 복사 함수를 memcpy로 대체하는 최적화를 수행할 때가 있음. 사용자 공간에서만 이 최적화가 이루어질 것으로 예상했으며, -nostdlib 옵션으로 이를 자동으로 처리할 수 있을 것으로 기대했음
  • C에서 packed structs를 사용하는 방법으로 비트필드를 제안함. 유효한 C 코드 예시를 제공함
  • Game Boy Advance의 메모리 문제를 해결하기 위한 방법이 필요함. LLVM이 이 기능을 지원하는지 궁금하며, Zig에 통합하는 것이 어렵지 않을 것이라고 생각함