1. 간단한 화면 출력 및 버튼 입력
본래 GBA에는 기본적인 OS도 없고 개발환경도 없기에
게임을 개발하려면 공식 개발툴 없이는 모든 작업을 GBA 하드웨어를 직접 조작하는 어셈블리언어를 사용해야 하지만,
수십년이 지난 지금은 여러 비공식 GBA 개발 라이브러리가 제공되고 있다.
이 라이브러리들은 특수한 개발을 하지 않는이상 일반적인 GBA 게임을 개발하는데에
어셈블리언어를 이용하지 않고 C언어만을 이용할 수 있도록 짜여있으며
간단한 함수 몇줄으로 화면을 출력하고 키입력을 받을 수 있기에 개발 난이도를 대폭 낮출 수 있었다.
Tonk 라이브러리는 개발자가 매우 상세하게 튜토리얼을 작성해놨으므로 입문 난이도가 낮아 당분간은 Tonk를 사용한다.
GBA의 화면 표현방식, 키입력 방식을 공부하고 간단한 예제코드를 만들어보기로 했다.
좌우 방향키를 누를때마다 화면에 직선이 일정 갯수만큼 그려지고 지워지는 프로그램이다.
#include <tonc.h>
int main()
{
REG_DISPCNT = DCNT_MODE3 | DCNT_BG2; //화면모드 3
int ii, clk, oldclk;
const int maxLine = 17;
clk = 0;
oldclk = 0;
m3_fill(RGB15(12, 12, 14));
m3_frame(12, 8, 228, 152, CLR_RED);
while (1)
{
vid_vsync();
key_poll();
if (key_hit(KEY_RIGHT) && (clk <= maxLine-1))
{
clk++;
}
else if (key_hit(KEY_LEFT) && (clk >= 0))
{
clk--;
}
if (oldclk != clk)
{
for (ii = 1; ii < maxLine; ii++)
{
m3_line(12 + 11 * ii, 9, 12 + 11 * ii, 151, RGB15(12, 12, 14));
}
for (ii = 1; ii < clk; ii++)
{
m3_line(12 + 11 * ii, 9, 12 + 11 * ii, 151, CLR_LIME);
}
oldclk = clk;
}
}
}
GBA 화면의 찢어짐을 방지하기 위한 Flip이라는 기술(더블 버퍼링과 비슷하지만 다르다)이 있지만
본 예제는 매우 간단한 시험용 코드이므로 최적화에 신경쓰지 않았다. 그러므로 화면모드도 3으로 사용한다.
다만 계속해서 화면을 갱신하면 깜박임이 심해지기 때문에 방향키 좌우를 눌러 그려야 할 선의 갯수가 달라질때만 화면이 갱신되도록 oldclk과 clk을 이용해 갱신 여부를 판단한다.
tonk 기본 예제에선 8프레임당 한번 key_poll()을 입력받게 되어있었다.
나는 그게 지나친 중복입력(바운스 현상)을 방지하기 위한 장치인줄 알았으나
바운스 현상은 이미 key_hit() 함수 선에서 처리가 되어있었고,
키 입력으로 변한 화면이 지나치게 빨리 사라지지 않도록 8프레임간 상태를 유지하는 장치였다.
즉 key_poll()로 한번 입력을 받고 다음 key_poll()이 호출되지 않으면 현재 키입력 상태가 유지된다는 것이다.
그 때문에 몇시간동안 키입력을 한번 하면 한번에 라인 8개가 그려지는 문제를 겪었고
해당 장치를 제거해 프레임마다 key_poll()을 호출하게 바꾸어 문제를 해결했다.