프로그래밍/SGDK 메가드라이브 개발

메가드라이브 게임 만들기 #3 - 이미지 처리

windship 2019. 6. 4. 14:13

 메가드라이브에서 이미지와 텍스트를 표시하기 위해서는 이미지의 형식에 대해 이해할 필요가 있습니다. SGDK에는 ResComp라고 하는, 이미지나 음악 파일을 다루기 위한 유용한 도구가 포함되어 있어, 비교적 쉽게 이미지를 다룰 수 있도록 되어 있습니다. 여기서는 그 사용법을 정리해 보겠습니다.

 

<메가드라이브의 이미지 형식>

 

 이것은 메가드라이브에서 표시가 가능한 512색의 컬러 차트입니다. 각 채널이 3비트인 RGB 색상으로 되어 있습니다.

 

 일반적으로 메가드라이브라고 하면 발색 수가 적다는 인상이 있지만, 사실 사용 가능한 색상은 이 정도로 많습니다. 인간의 눈은 인접한 색상의 차이와 색의 조합은 섬세하게 식별할 수 있지만, 하나하나의 색상의 인식은 상당히 모호합니다. 그렇다는 것은, 결국 궁리하기 나름이라는 것으로, 512색으로도 상당한 표현을 할 수 있다고 생각합니다.

 

 다만 이 512색 중에서, 한 장의 그림에는 임의의 15색을 골라 사용해야 합니다(16색 중 1색은 배경색이 되므로).

 

 EDGE 등의 이미지 편집 소프트웨어는 8비트의 RGB 색상( 빨강, 초록, 파랑 각 채널이 각각 256단계)에서 편집하는 것이 표준적인 사양입니다. 그래서 필자는 각 채널의 값을 0, 36, 73, 109, 146, 182, 219, 255 8단계로 분류하여 이 값에 한정한 이미지 편집을 하고 있습니다.

 

 EDGE에서 팩맨 스타일의 도트 그림을 그려 보았습니다(여전히 센스가 없습니다).

 

 색상 파레트의 맨 위쪽 16색만을 사용하고 있고, 가장 왼쪽의 0번째의 색은 투명색(첫번째 파레트 : PAL 0의 경우 배경색)입니다.

 

 파레트의 빨강, 초록, 파랑 채널의 각 값을 0, 36, 73, 109, 146, 182, 219, 255 중의 하나로 하면 SGDK에 가져와도 감색되지 않고 원한 색이 그대로 출력되는 것입니다. 

 

 '16색으로 저장한다'를 체크하고, PNG 형식으로 저장합니다. 이 파일은 스프라이트로 사용할 예정입니다.

 

gr_char.png

 

 마찬가지로 배경 이미지를 만들고 16색 포맷으로 저장합니다.

 

gr_map.png

 

 SGDK에는 폰트도 준비가 되어 있지만, 이번에는 ATARI FONT로 변경했습니다. ASCII 코드로, 0x20 ~ 0x7F(32 ~ 127)까지의 문자입니다.

 

gr_font.png

 

<이미지와 문자를 표시해 본다>

 

 실제로 메가드라이브에서 이미지와 문자를 표시해 보겠습니다.

 

 그림을 넣을 res 폴더를 프로젝트 안에 만들고, 방금 전의 이미지 파일(gr_font.png, gr_map.png)를 만든 res 폴더에 넣습니다. 또한 ResComp에서 이미지를 로드하게 해 주는 파일 gfx.res를 생성한 뒤, 안에는 다음 두 줄의 코드를 넣습니다. gfx.h는 자동으로 생성되는 것 같습니다.

 

IMAGE image_font "gr_font.png"-1

IMAGE image_map "gr_map.png"-1

 

 main.c의 코드는 다음과 같이 합니다.

 

#include <genesis.h>

#include "gfx.h"

#define TILE_MAP  TILE_USERINDEX  /* gr_map.png의 타일 셋의 VRAM 상의 위치 */

int main()
{

    /* 폰트 디자인의 설정 */
    VDP_loadFont(image_font.tileset, TRUE);

    /* 타일 셋을 읽어들인다 */
    VDP_loadTileSet(image_map.tileset, TILE_MAP, FALSE);

    /* 파레트 데이터를 읽어들인다 */
    VDP_setPalette(PAL0, image_map.palette->data);

    /* 폰트의 파레트 설정 */
    VDP_setTextPalette(PAL0);

    /* 배경맵을 표시 */
    VDP_setMap(PLAN_A, image_map.map, TILE_ATTR_FULL(PAL0, 0, 0, 0, TILE_MAP), 1, 0);

    /* 문자를 표시 */
    VDP_drawTextBG (PLAN_A, "HIGH SCORE", 30,1);
    VDP_drawTextBG (PLAN_A, "   000000", 30,3);
    VDP_drawTextBG (PLAN_A, "1UP", 30,5);
    VDP_drawTextBG (PLAN_A, "   000000", 30,7);
    VDP_drawTextBG (PLAN_A, "CREDIT 00", 30,26);

    while(1)
    {
        
// program
    }
    return (0);
}

 

 실행하면 이렇게 됩니다.

 

 소스 파일 : CookieMan.zip

 

<ResComp에서 사용하는 Image 구조체에 대해>

 

 SGDK에는 이미지를 다루는 구조체인 Image가 준비되어 있어, 여기에는 Palette, TileSet, Map 구조체의 포인터가 멤버로 포함되어 있습니다. ResComp에서 PNG 파일을 가져오면 Image 구조로 로드됩니다.

 

typedef struct
{
    Palette *palette;
    TileSet *tileset;
    Map *map;
} Image;

 

 이런 구조체입니다.

 

 Palette 구조체는, 512 색상 중 어떤 16색을 사용할 것인지에 대한 색상의 지정 데이터입니다.

 

typedef struct
{
    u16 index;
    u16 length;
    u16 *data;
} Palette;

 

 TileSet에는 이미지에 사용되는 타일 데이터(패턴)이 포함되어 있습니다.

 

typedef struct
{
    u16 compression;
    u16 numTile;
    u32 *tiles;
} TileSet;

 

Map에는 이미지의 크기, 타일 맵(이미지의 어떤 위치에서 어떤 패턴이 사용되고 있는지 알려주는 데이터)이 포함되어 있습니다.

 

typedef struct
{
    u16 compression;
    u16 w;
    u16 h;
    u16 *tilemap;
} Map;