xnb.js 개발일지(1)

Lybell·2022년 6월 22일
0

xnb.js 개발일지

목록 보기
1/6
post-custom-banner

이 시리즈는 제가 개인 프로젝트 등을 제작하면서 배운 프로그래밍/CS 지식을 정리해둔 시리즈입니다.

서론

나는 xnb.js라는 xnb 파일 조작 라이브러리를 개발하고 있다.
이 라이브러리는 xnb 파일을 언팩 및 패킹할 수 있는 콘솔 프로그램 XnbCli를 기반으로 제작되었다. 현재는 xnb.js 1.1.0이 릴리즈된 상태고, 1.2 업데이트를 제작하고 있다.
xnb.js 라이브러리를 체험할 수 있게, web xnb converter도 같이 제작하여 서비스하고 있는 상태다.

개발 동기

이 블로그에서 처음 xnb.js를 소개하는 것이라 간단한 개발 동기를 소개하겠다.
xnb.js는 내 또다른 프로젝트인 Stardew Dressup을 위해 제작되었다. Stardew Dressup은 스타듀 밸리라는 게임의 플레이어 커스터마이징을 시뮬레이션할 수 있는 웹 어플리케이션인데, 이 웹 앱의 기능 중 xnb 파일을 불러넣어서 의상의 텍스처를 변경할 수 있는 기능을 구현할 예정이다.(스타듀밸리에는 리텍스처라고 해서, 게임 내에 데이터를 저장한 xnb 파일을 다른 파일로 교체해서 데이터를 바꾸는 생태계가 존재한다.)

하지만 xnb 파일을 언팩할 수 있는 라이브러리는 세상에 존재하지 않았고, 결국 직접 제작할 수밖에 없었다. 다행이도, 자바스크립트로 제작되었고 LGPL 3.0 라이선스를 채택한 XnbCli가 있었기 때문에, 이를 개작하여 xnb.js라는 라이브러리를 제작하였다.

xnb.js는 브라우저에서도 xnb 파일을 다룰 수 있으며, 이를 통해 다양한 xna game studio/monogame 기반 게임의 유틸리티 웹 어플리케이션을 제작할 수 있음이 기대된다. 또한, 데스트탑이 없는 유저들 역시 스마트폰으로 웹 어플리케이션을 이용할 수 있기 때문에 진입장벽이 해소되는 효과 역시 가진다.

개발 상황

xnb.js 1.2에서는 다음과 같은 기능이 추가된다.

  • 헤더 json/yaml 파일 없이 png, tbin 파일을 xnb 파일로 변환할 수 있는 기능
  • Texture2D 데이터를 언팩할 때 format이 2인 데이터 언팩 가능

현재는 png 파일 단독으로 xnb 파일로 변환하는 기능을 완료하였고, 2번째 기능을 제작 중이다.

png 파일 직접 패킹

기존까지 png 파일은 단독으로 xnb 파일로 패킹할 수 없다고 알려져 있고, 실제로도 그래 왔다. png 파일을 xnb 파일로 변환하기 위해서는, 다음의 과정이 수행되었다.

  1. 바꾸려는 xnb 파일을 XnbExtract 등으로 언팩한 뒤, json/yaml 파일을 추출한다.
  2. 해당 json/yaml 파일과 함께 png 파일을 xnb로 패킹한다.

png 파일 단독으로 xnb 파일로 패킹할 수 없는 이유는 xnb 파일로 패킹할 때 헤더 데이터가 존재해야 했기 때문이다. 하지만, xnb 파일을 언팩하다, 모든 xnb 헤더 파일은 동일하다는 것을 알게 되었고, 헤더 파일을 xnb.js에서 주입할 수 있으면 png 파일 단독으로 xnb 파일로 만들 수 있을까 생각했다.

모든 png 텍스처 파일 기반 xnb 파일의 헤더는 다음의 데이터를 가지고 있다.

  • header
    - target : "w" (windows)
    - formatVersion : 5 (xna game studio 4.0)
    - hidef : true
    - compression : true
  • readers : 길이가 1인 배열
    - type : Microsoft.Xna.Framework.Content.Texture2DReader, Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553
    - version : 0
  • content
    - format : 0

실제로 게임에서 xnb 파일을 읽을 때 유효하게 작용되는 것은 readers와, content의 format 데이터이다. 타겟이 pc가 아닌 안드로이드 스타듀밸리에서 pc 스타듀밸리 헤더 기반 xnb 파일을 읽을 수 있기 때문이다.

readers의 type은 xnb 파일에 저장된 데이터의 타입을 의미하는데, png 파일은 텍스처 데이터이므로, Microsoft.Xna.Framework.Content.Texture2DReader를 사용한다. type에 있는 PublicKeyToken은 공용 키 토큰으로, 타입 리더의 어셈블리의 서명 같은 것이라고 생각하면 된다. Microsoft.Xna.Framework의 공용 키 토큰은 842cf8be1de50553으로 고정되어 있다.

content의 format은 텍스처 데이터가 어떻게 저장되어 있는지를 나타내는 포맷으로, 그 종류는 다음과 같다.

  • 0 : 32bit rgba
  • 1 : 16bit rgb (R 5bit, G 6bit, B 5bit)
  • 2 : 16bit rgba (RGB 각 5bit, A 1bit)
  • 3 : 16bit rgba (RGBA 각 4bit)
  • 4 : DXT1
  • 5 : DXT3
  • 6 : DXT5

모든 png 파일은 32bit rgba 포맷을 사용하므로, 0을 포맷 값으로 가진다.

profile
홍익인간이 되고 싶은 꿈꾸는 방랑자
post-custom-banner

0개의 댓글