샬롬~
우우우, 이런...
저번에 실수를 했더군요. ex001이 아니라 제가 실행한 것은 ex000이었습니다. -_-
ex001은 단순히 사각형 하나 출력하는 거지, 16bit 변환 이야기는 없었습니다. T_T 예, 저의 실수입니다... 목숨만은... -_-
여담이지만.. ex001을 보시면... 상당히 짧습니다. 소스가.. 적당한 매력이지요.. ^^
이번에는 실제로 코딩을.... 후후후.... 일단 간단히 움직이는 사각형을 구현하도록 하죠. 물론, 사용자의 입력에 따라서 움직여야 하겠죠? Surface니 Flip이니 하는 개념은....... 제가 예전에 (몇년 전이지?-_-) 쓴 'TC로 게임 만들기'를 참조함이.. -_- ( DOS 시절 게임 만드신 분이라면.. Page라는 개념을 아실 겁니다. 그거죠. T_T )
자, 일단..... VC++에서 GP32용 Project를 만들기 위해서는.. 상당히 귀찮은 작업이 필요한데... work/docs/dev_ko/index.htm을 보시면... 아니, 바로 가는 걸로 찾아보죠. ^^ work/docs/dev_ko/vc/project.htm을 보시면 됩니다.
그런데.... 하여튼.. 저는 귀찮아서.. work/project/template를 바로 이용하겠습니다. 원래는 이걸 가지고 복사해서 삽질하라고 써있는데.. 귀찮아서..... -_-
win32 application project 생성해주듯이.. GP32 application project 생성하는 것도 만들면 좋은데....... 나중에 시간이 나면.... 해보도록 하겠습니다만... 제가 약속은 잘 안지키는 놈이라서..... -_- 예, 그런 거죠.. 쿨럭.. 털썩.. 부들......
work/project/template/win32에 들어가면.. template.dsw가 있습니다. 그걸 더블 클릭을 하면.. 무언가 나오죠. 화면에 사각형을 출력하는 예제인데... 아래의 소스로 교체를 해봅시다. ^^
#include "gpdef.h"
#include "gpgraphic.h"
#include "gpmain.h"
GPDRAWSURFACE gpDraw;
void GpMain( void *arg )
{
GpLcdSurfaceGet( &gpDraw, 0 );
GpSurfaceSet( &gpDraw );
if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) ) GpLcdEnable();
GpRectFill( NULL, &gpDraw, 0, 0, gpDraw.buf_w, gpDraw.buf_h, 0x00 );
GpRectFill( NULL, &gpDraw, 120, 60, 80, 80, 0xFF );
}
원래 예제는 Surface 하나짜리라서... 좀 바꿨습니다. 이건 쓸데 없는 건 일단 최소화를 해본 거죠.. ^^ ( 과연 최소화가 맞나? -_- ) 일단 사각형을 움직이기 전에 위의 소스부터 분석하고..... 사각형을 움직여보죠... 후후후... +_+
GP32 Application의 main은 GpMain입니다. Win32 Application의 main이 WinMain인 것과 마찬가지....
맨 첨의 GPDRAWSURFACE gpDraw;를 봅시다. 이게 바로 DOS 시절의 Page 개념인 Surface를 정의하는 겁니다. 그냥 화면...의 개념으로 보시면 됩니다. 예, 간단하죠? ^^
LCD Surface, 그냥 LCD 화면을 얻는 거죠. 위에 정의한 gpDraw란 변수는 그냥 정의만 된거지.. 아직 아무 값도 안가지는 거잖아요. 실제로 쓸 수 있게 Surface Get을 때려주는 거죠.
자, 그 담에 실제로 화면을 세팅을 해주는 건... GpSurface Set입니다. ( 이미 눈치까신 분이 있겠지만.. GP32 API는... Gp가 앞에 붙습니다. ^^ )
if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) ) GpLcdEnable();
이 녀석은... 실제로 LCD 화면을 사용하는 건데.... (Enable) 앞에 있는 조건은.. LCD 쓸 수 있는지 체크 정도죠. 실제로는 이게 없어도 되는데 (Default가 Enable이거든요^^) 그냥 넣었습니다.
실제로 GP32 기계에선 어떻게 되는지 모르니까... -_- 여기까지 했으면.. 준비는 끝난 겁니다. 실제로 여기까지만 하고 실행해도 하얀 화면이 뜨죠. ^^ 그런데.. 아무 것도 안그리면 좀 썰렁하니..... 일단 화면을 검게 지우고 상자를 하나 그려보죠.
GpRectFill( NULL, &gpDraw, 0, 0, gpDraw.buf_w, gpDraw.buf_h, 0x00 );
이건 (0,0)부터 화면 크기만한 상자를 그리는 겁니다. 즉, 화면을 0x00(black)으로 지우는 거죠. ^^
GpRectFill( NULL, &gpDraw, 120, 60, 80, 80, 0xFF );
이건 0xFF(white)로 상자를 그려주는 겁니다. 후후후... 대단히 간단합니다. ^^ 예, 그런 거죠. ^^
그럼 이번엔 실제로 키보드의 입력을 받아서 움직이게 해볼까요? ^^
#include "gpdef.h"
#include "gpgraphic.h"
#include "gpmain.h"
GPDRAWSURFACE gpDraw;
void GpMain( void *arg )
{
unsigned char keydata; // 키보드 입력을 받기 위한 녀석...
int x = 120; // 상자의 X 좌표
int y = 60;` // 상자의 Y 좌표
GpLcdSurfaceGet( &gpDraw, 0 );
GpSurfaceSet( &gpDraw );
if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) ) GpLcdEnable();
while( 1 ) // 루프를 돌려보죠~ +_+
{
keydata = GpKeyGet(); // 키 입력을 받을까요?
if( keydata & GPC_VK_UP ) y--; // UP
if( keydata & GPC_VK_DOWN ) y++; // DOWN
if( keydata & GPC_VK_LEFT ) x--; // LEFT
if( keydata & GPC_VK_RIGHT ) x++; // RIGHT
GpRectFill( NULL, &gpDraw, 0, 0, gpDraw.buf_w, gpDraw.buf_h, 0x00 );
GpRectFill( NULL, &gpDraw, x, y, 80, 80, 0xFF );
}
}
아까의 소스와 달라진 부분에는 주석이 붙어있습니다. 참고하시고~ ^^ 자, 이번에는 키 입력을 받는 게 추가가 됐는데... 매우 간단합니다. 제가 뭐라고 부연 설명을 하는게 어색할 정도죠. -_-
여기까지 하면.. 우리의 목적이 일단 달성된 거 같은데... 실행해보면 조금 이상하죠? 상자가 상당히 깜빡거립니다. +_+
왜 그런가하고 식음을 전폐하고 고민을 하니.... 화면을 지우고 상자를 그리기 때문에 그런 거죠. 화면을 지울 때 상자가 함께 지워지고, 상자를 다시 그리고.. 당연히 깜빡거리는 거 아니겠습니까... ^^
그런데... 그게 당연하다고 존나 깜빡거리는 걸 게임이라고 내놓으려니.. 자존심이 허락하지 않네요. ^^;;; 그럼 어찌할까요..... 설명하기 귀찮으니.. 일단은 아래의 소스로 살짝 수정을 해볼까요?
#include "gpdef.h"
#include "gpgraphic.h"
#include "gpmain.h"
GPDRAWSURFACE gpDraw[2]; // Surface를 2개로 잡을까여? ^^
int nflip = 0; // Surface Flip을 위한 변수
void GpMain( void *arg )
{
unsigned char keydata;
int x = 120;
int y = 60;
GpLcdSurfaceGet( &gpDraw[0], 0 ); // 자자, 0번 Surface
GpLcdSurfaceGet( &gpDraw[1], 1 ); // 이번에는 1번 Surface
GpSurfaceSet( &gpDraw[0] );
if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) ) GpLcdEnable();
while( 1 )
{
keydata = GpKeyGet();
if( keydata & GPC_VK_UP ) y--;
if( keydata & GPC_VK_DOWN ) y++;
if( keydata & GPC_VK_LEFT ) x--;
if( keydata & GPC_VK_RIGHT ) x++;
GpRectFill( NULL, &gpDraw[nflip], 0, 0, gpDraw[nflip].buf_w, gpDraw[nflip].buf_h, 0x00 );
GpRectFill( NULL, &gpDraw[nflip], x, y, 80, 80, 0xFF );
GpSurfaceFlip( &gpDraw[nflip] ); // Surface Flip을 감행!!
nflip = ( nflip + 1 ) % 2; // Flip을 위한 변수를 변신~
}
}
움하하핫.......... 드디어 안깜빡이는 상자다......... T_T 이제 이번 글은 접기로.. 쿨럭.. -_-
예, 간단히 설명을 하죠. 여기서 포인트는 Surface를 2개 만든다는 점과 Surface Flip이라는 녀석이죠. 아까 깜빡거리는 문제에 대한 해답을 생각해볼까요?
일단 문제가 되는 건.... 우리가 무언가 작업을 하는게-그림을 그리는게- 유저에게 보인다는 거죠. 그렇다면.... 그 화면을 두놈을 만들어서.... 한 화면을 보여주고.. 다른 화면에 그림을 그려서.. 순식간에 두 화면을 바꿔치면(Flip) 되지 않겠느냐.... 이거죠. ^^ 바로 그 개념입니다. 별로 어려운 건 없으니까요.. 그냥 쓱~하고 보시면 아항~하고 이해가 가실 겁니다. DOS 시절처럼 인터럽트 호출해서 13h모드 만들고.. 그런 짓은 없으니.. ( 아아, Plane Mode의 추억이여.. 털썩... -_-;;;;; )
일단... 이번에는 여기까지입니다. 특별한 설명이 없는 날림인 점... 대단히 죄송합니다. T_T 어짜피.. 이 글을 보시는 분들은.... 나름대로 게임 프로그래밍을 공부하신 분들이라고 가정하고... (퍽퍽) 다음에는.... 좀 더 심오한 삽질로 들어가도록 하겠습니다. ^^
--2002.04.10 아샬
P.S. 사실... 빨리 쓰려다 보니.. 좀 성의가 없네요. 오랜만에 쓰다보니.... 글 쓰는데.. 정성을 다하기가.. 어렵습니다. 죄송 T_T
지피껨 만들기로 돌아가기
| 제일 위로 |
| 최종 수정 일시: 01월 05일(2003년) 12:52 AM 편집 | 정보 | 차이 | 비슷한 페이지 DebugInfo |
| 유용한 페이지들: 분류 분류 | 자유로운 연습장 SandBox | 무작위 페이지들 RandomPages | 인기있는 페이지들 MostPopular |