자, 앞강좌에 이어서 계속적으로 진행하도록하겠습니다...
프로젝트 세팅까지는 다 끝내셨죠?? 그럼 이제부터는 본격적으로 소스를 짜보도록 하죠...
#include "../Myinclude/WIPIHeader.h"
MC_GrpContext cxt;
MC_GrpFrameBuffer bpl;
void startClet(int argc, char *args[])
{
MC_knlPrintk("드뎌, 첫번째 어플이에요!!\n");
bpl = MC_grpGetScreenFrameBuffer(0);
MC_grpInitContext(&cxt);
}
void pauseClet()
{
}
void destroyClet()
{
}
void resumeClet()
{
}
void paintClet(int x, int y, int w, int h)
{
M_Int32 width;
M_Int32 height;
width = MC_GRP_GET_FRAME_BUFFER_WIDTH(bpl);
height = MC_GRP_GET_FRAME_BUFFER_HEIGHT(bpl);
MC_grpDrawString(bpl, width / 5, height / 2, "위피야, 안녕!!", -1, &cxt);
}
void handleCletEvent(int type, int parm1, int parm2)
{
}
이 소스가 바로 우리가 오늘 어렵게 세팅해가며 작성할 첫번째 어플입니다...
정말 간단해보이죠?? 아니라구요?? ㅡ_ㅡ;;; 간단한건뎅....ㅋ.....
어쨋든간에 이런 기본적인 소스는 알고 계시는 분들도 많겠지만, 늘 강조하듯이...
기초가 중요한 거거든요....자, 한줄한줄 분석해보자구요....
#include "../Myinclude/WIPIHeader.h"
이부분은 C 언어의 전처리과정과 동일한 부분입니다.
즉, C 언어의 #include <stdio.h> 과 거의 동일한 의미로 쓰인 거죠....
WIPI 자체의 API들을 미리 불러들여서 저희가 사용할 수 있도록 컴파일러에게 알려주는거죠...
근데 왜 #include "WIPIHeader.h" 이렇게 쓰지 않고 저렇게 길게 썼냐면....
아까도 말씀드렸듯이, 저희가 정한 'Myinclude' 라는 폴더안에 헤더파일이 있기 때문에....
저런식으로 상대경로로 지정해주는 거랍니다.... ^^;;
MC_GrpContext cxt;
이 부분은 위피에서 사용하는 그래픽 컨텍스트를 선언하는 부분이에요....
변수선언하듯이 cxt 라는 그래픽 컨텍스트 구조체를 선언하는거죠...
이 그래픽 컨텍스트에는 여러가지 정보들이 들어있어요....잠깐, 구조체 내용을 살펴볼까요??
struct _MC_GrpContext
{
int m_mask;
int m_clip[4];
int m_fgpxl;
int m_bgpxl;
int m_transpxl;
int m_alpha;
int m_offsetX;
int m_offsetY;
C_GrpPixelOpProc m_pfnPixelOp;
int m_param1;
int m_reserved;
int m_font;
int m_style;
};
이 구조체 안에는 클리핑 영역, 전경색, 배경색, 알파값, 폰트, 스타일 등 여러가지 정보들이
저장되어 있습니다. 솔직히 저도 다는 몰라요....ㅡ_ㅡ;;
그러나 보통은 전경색이나 배경색을 바꾸기 위해 사용되구요, 폰트도 가끔 바꿔주고...
암튼, 화면에 무엇인가를 뿌려줄때는 꼭 이 그래픽 컨텍스트가 있어야하죠....^^;; 하하...(얼렁뚱당..)
MC_GrpFrameBuffer bpl;
그 다음에 이 부분은 그래픽 프레임 버퍼 구조체를 선언하는 부분이에요....
역시나 이 구조체를 잠깐 살펴볼까요??
struct _MC_GrpFrameBuffer
{
M_Int32 w; // 프레임 버퍼의 폭(Pixel 단위)
M_Int32 h; // 프레임 버퍼의 높이(Pixel 단위)
M_Int32 bpl; // 프레임 버퍼의 한 줄당 바이트 수; 패딩(Padding)되는 바이트까지 포함.
M_Int32 bpp; // 프레임 버퍼의 한 픽셀당 비트 수
M_Int32 frameBufID; // 실제적은 프레임 버퍼의 ID
};
이런 정보들이 들어있네요...주석은 헤더파일에 달려있는 거 그대로 인용했구요....
(치사하게, 그래픽 컨텍스트 구조체에는 영어로 주석이 달려있더라구요....ㅡ_ㅡ;;;;;)
음, 프레임 버퍼라는건 쉽게 말해서 가상의 LCD라고 이해하시는게 좋을거 같아요....
물론, 정확히 말해서는 그냥 버퍼 공간일 뿐이지만....이해하시기 편하시도록 하기위해선....
가상 LCD라고 생각하세요... 그러니깐 여러개의 그래픽 객체(글자나 도형이나 이미지나 여러가지)들을
이 가상 LCD에 미리 다 집어넣고 그 다음에 최종적으로 단말기 LCD에 뿌려주거든요...
음, 그러니깐 버퍼가 뭔지 다들 아시죠?? 빈 공간에 이것저것 모아놓고선 한번에 보내주는거에요...
그럼 왜 이런방식으로 처리를 하냐면, 보통 입'출력의 과정이 가장 리소스를 많이 먹거든요...
사소한 거 하나하나까지 계속 출력하다보면 가뜩이나 느린 단말기에서 버벅거릴수가 있기때문에,
미리 프레임버퍼에 처리할 객체들을 모아놓고 필요할때마다 한번에 처리하는거죠....
그래서 프레임 버퍼에 있는 내용을 단말 LCD로 내보내는 MC_grpFlushLcd()라는 함수가 있어요...
저는 이렇게 알고 있는데, 제대로 이해하고 있는건지 모르겠네요.....^^;; 훗....(배째라식 강의)
그러면 대충 프레임 버퍼에 대해 이해하신거죠?? 그렇다고 믿을게요....ㅋ.....
void startClet(int argc, char *args[])
{
}
이 부분은 C 언어의 main 함수와 같아요....즉, 진입점 함수죠....
아따 그럼 진입점 함수가 뭐냐... 음, 쉽게 말해서 프로그램이 시작되면 가장 먼저 실행되는 함수에요...
그러니까 출발점 같은거죠... 어플이 출발하는 곳을 알려주는것처럼....
중요한 건, 이 startClet() 함수는 따~악, 1번밖에 실행이 안되요... 그러니깐 다시 실행시키고 싶으면,
어플을 종료했다가 다시 실행하는 방법밖에 없죠...그래서 보통 이 함수에는 어플 전반에 걸쳐서 쓰이는
변수들의 기본값들을 세팅하는데 많이 쓰입니다...
저희 어플에서는 어떤 것들이 쓰였지요???
MC_knlPrintk("드뎌, 첫번째 어플이에요!!\n");
으음, 이 부분은 왜 아로마 위피 실행하면 뒤에 검은 창이 하나 나오죠... 도스 창처럼....
그부분을 커널이라고 부르는데, 보통 디버깅할때 유용하게 사용합니다....
그러나 디버깅은 보통 비쥬얼 툴이 다 알아서 해주죠...ㅡ_ㅡ;;
전, 비쥬얼 툴 디버깅 할 줄 몰라서 이 커널을 자주 애용했다는.....ㅠ_ㅠ
아무튼, 그 커널창에 표시해주는 함수가 바로 MC_knlPrintk() 입니다...
함수 사용법은 C 언어의 printf() 함수와 동일하구요... 메타문자와 형식지정문자 사용 가능합니다~
어플 실행시키고 커널창 보시면 "드뎌, 첫번째 어플이에요!!" 라고 찍히신 걸 볼 수 있을거에요....
bpl = MC_grpGetScreenFrameBuffer(0);
이 부분은 아까 선언한 bpl 프레임 버퍼 구조체 변수에 스크린 버퍼를 가져오는 부분입니다.
즉, 현재 단말기의 화면 정보를 가져온다고 생각하시면 쉬워요...
괄호안의 '0' 은 메인 LCD를 말하는거구요... '1'을 집어넣으면 외부 액정있죠?? (듀얼 폴더)
그 외부액정의 프레임 버퍼를 가져옵니다...(슬라이드 타입은 메인 LCD 액정 하나죠...)
MC_grpInitContext(&cxt);
이 부분 역시 아까 선언했던 그래픽 컨텍스트를 초기화 시키는 부분입니다...
이 함수를 이용하여 초기화를 하게 되면 기본값으로 세팅이 됩니다.
'폰트는 기본 시스템 폰트가 되고, 색상은 검정색, 그리기 모드는 일반 모드, 클리핑 영역은 해제되고,
상대 좌표의 원점은 (0, 0)이 된다' 고 API가 친절히 설명해주고 있어요....^^
void pauseClet()
{
}
이 pauseClet() 함수는 어플이 일시정지 되었을때 실행되는 함수입니다.
즉, 어플을 실행중에 전화가 온 경우에 이 함수가 실행되면서 어플은 잠시 멈추고 전화를 받겠지요...
그러면 보통 전화를 끊고 다시 어플을 실행하기 위해 필요한 정보를 저장하기도 하고 그런답니다~
그치만, 보통 에뮬에서 테스트할때는 잘 사용하지 않는 편이에요...
void destroyClet()
{
}
destroyClet() 함수는 어플이 종료될 때 자동으로 실행되는 함수입니다.
startClet() 함수와는 반대지요?? 그래서 보통, 그동안 사용했던 리소스들을 제거하는데 사용합니다.
하지만, 그러지 않아도 위피 플랫폼이 알아서 제거해준데요...ㅋ...검증되지 않았음....
void resumeClet()
{
}
resumeClet() 함수는 pauseClet() 함수에 의해 어플 실행이 중지되었다가, 다시 실행될때 호출됩니다.
그러니까 게임을 막 하고 있는데 전화가 오면 pauseClet() 함수가 실행이 되고, 전화를 다시 끊으면
이 resumeClet() 함수가 실행이 되는거지요... 보통, pauseClet() 함수에 저장되었던 변수들을
다시 원상복구 시키는데 사용되곤 합니다... 이 함수 역시 에뮬상에서 테스트 할때는 잘 쓰이지 않아요.
void paintClet(int x, int y, int w, int h)
{
}
아마 이 함수와 핸들 함수가 가장 중요하지 않을까 생각하는데...ㅋ.....
이름을 보면 알수 있듯이, 화면을 그려주는 함수입니다...
파라메터 x, y, w, h 에는 대충 눈짐작으로 알 수 있듯이, 그려줄 x, y 좌표값과 w, h 가로, 세로 길이가
들어가게 됩니다. 이 paintClet() 함수는 MC_grpRepaint() 함수에 의해 다시 호출될 수 있습니다...^^
글구, paintClet() 함수를 실행하면 아까 말씀드렸던 MC_grpFlushLcd() 함수를 호출하지 않아도
알아서 마지막에 프레임 버퍼를 단말기 화면으로 내보내줍니다... 편한 놈이지요....ㅋ....
자, 그럼 우리는 무엇을 그렸나 볼까요??
M_Int32 width;
M_Int32 height;
지역 변수로 width와 height 라는 정수형 변수를 선언했습니다.
데이터 타입 'M_Int32' 는 C 언어의 'signed int' 형과 같다고 보시면 됩니다.
어차피 새로운 데이터 타입이 아니고 'typedef' 로 재정의되어 있는 것 뿐이거든요...
width = MC_GRP_GET_FRAME_BUFFER_WIDTH(bpl);
height = MC_GRP_GET_FRAME_BUFFER_HEIGHT(bpl);
이 부분은 방금 선언한 두 변수에 bpl에 정의되어 있는 프레임 버퍼의 가로 길이와 세로 길이를
가져오는 부분입니다. 말씀드리지 않아도 'width' 가 가로고 'height' 가 세로인건 아시죠?? ^^;;;
아마도 아로마 위피 에뮬에서는 가로 길이 120, 세로 길이 160을 가져 올거에요...
MC_grpDrawString(bpl, width / 5, height / 2, "위피야, 안녕!!", -1, &cxt);
자, 이부분이 오늘의 핵심 뽀인트죠... 사실, 이 한 줄 할라고 지금껏 이 고생을...흑흑...ㅠ_ㅠ
우선 MC_grpDrawString() 함수의 원형부터 확인해 보실까요??
void MC_grpDrawString(MC_GrpFrameBuffer dst, M_Int32 x, M_Int32 y,
const M_Char *str, M_Int32 len, MC_GrpContext *pgc)
원형은 이렇게 되어 있네요....그러면 각각의 파라메터부터 분석해 보죠....
dst 는 프레임 버퍼죠...저희가 처음에 선언했던 'bpl' 이 되겠네요...
x, y 는 문자열을 그려줄(찍어줄) 화면상의 좌표 값을 의미합니다...
*str 은 실제 화면에 보여줄 문자의 내용이죠...
len 은 화면에 보여줄 문자열의 길이입니다. 여기서 '-1'이라고 쓴 건
'-1'이라고 쓰면 '널 문자를 만날때까지 모두 찍어라' 라는 의미이기 때문이에요~
*pgc 은 아~까 전에 선언했던 그래픽 컨텍스트를 의미합니다...
그럼 대충 이해가 되시나요??
즉, MC_grpDrawString(bpl, width / 5, height / 2, "위피야, 안녕!!", -1, &cxt); 이 부분을
우리 말로 다시 풀이하면 프레임 버퍼 가로 24(120/5), 세로 80(160/2) 되는 지점에 '위피야 안녕'
이라는 글자를 cxt 의 설정대로(즉, 검은색으로) 널 스트링을 만날때까지(즉, 모두) 그려주세요...
이런 뜻이 되겠죠.... 쉽게 설명한다고 했는데 어떻게 다들 이해하신건지....쩝...ㅡ_ㅡ;;
void handleCletEvent(int type, int parm1, int parm2)
{
}
마지막으로 이부분은 현재는 아무 것도 없지만 정말 너무나도 중요한 함수입니다.
이벤트를 처리해주는 함수죠... 지금 어플이야 이벤트가 없기때문에 아무것도 없지만,
앞으로 게임을 작성하시다보면 이 함수와 친하게 지내셔야 될꺼에요...ㅋ....^^;;;
그럼 파라메터를 보면요....
type 이 파라메터엔 이벤트의 종류가 들어갑니다... 즉, 키를 눌러서 발생한 이벤트인지 아니면,
키를 눌렀다 띨때 발생한 이벤트인지 뭐 그런것들이 들어가죠.....
parm1 에는 이벤트 발생시 발생한 키값이 들어갑니다... 그러니까 키 누름 이벤트가 발생했으면,
어떤 키가 눌러졌는지 그 정보가 들어가는거지요...
parm2 는 확장성을 위해 제공된다고 하던데... 별로 사용되지는 않습니다....^^;;
이벤트 함수는 이벤트 처리 강좌 시간에 더욱 자세하게 알아보도록 할게요~~
자, 그럼 이렇게 해서 만든 우리의 어플을 실행해보아야죠.....
소스를 다 코딩하셨으면 컴파일을 해주세용~~에러가 안나야 정상입니당....ㅡ_ㅡ;;;
에러가 나시는 분들은 '질문게시판'에 적어주세요...ㅠ_ㅠ...벌써 에러나면 안되는뎅....
컴파일과 빌드 모두 제대로 성공하셨으면 'HelloWipi' 폴더안의 'Debug' 라는 폴더를 보시면요...
'client.dll' 라는 파일이 있을거에요.... 그럼, 'Myinclude' 폴더 안에 있는 'Clet$CletCard.class'
파일과 'Clet.class' 파일을 복사해 오세요.... 그 담에는 이 세가지 파일을 선택하시구요....
알집이 있으시면 알집으로 압축을 해주시는데요, 주의하실 점은 압축 파일 종류를 반드시
'jar' 로 해주셔야 되요.... 이렇게 해서 압축이 되셨으면 아로마 위피를 실행시키시구요....
방금 만드신 'HelloWipi.jar' 파일을 선택하시고 'Clet'이라고 적어주시면 실행 오케이~
사실, 이렇게 번거롭게 jar 파일을 만들지 않고 배치파일을 이용하는 방법도 있는데....
그 방법은 다른 강좌에서 알려드리도록 하겠습니당....
(사실, 지금 제가 막 졸려서 제정신이 아니거든요...취침 시간 12시를 오버해서리...ㅋㅋ...)
이렇게 해서, 처음으로 만든 어플 '위피야, 안녕' 을 보았는데요....
어떻게 다들 이해가 잘 되셨는지 모르겠네요....아무래도 제가 글주변이 없다보니깐....
마음은 계속 쉽게 설명해야하는데, 하면서도 막상 쓰고보면 마음에 안들더라구요....^^;;
그래도 앞으로 분발해서 열심히 할테니깐, 여러분들도 제 강좌 보시면 악플이라도 좋으니...
답글을 좀 달아주시길....그래야 글 쓰는사람도 힘이 납니당.... *^^*
오늘은 여러분께 양해를 구해야 할 게 있어요....사실, 지금 너무 졸려서리.....
강좌를 텍스트 파일, 한글 파일, 워드 파일로 만들어서 같이 올려야 하는데.......
그러지 못할거 같아요....대신, 내일 중으로 꼭 올리도록 하겠습니다....
혹시나 제 강좌에 틀린점이나 궁금한 점이 있으시면 언제든지 질문게시판을 이용해주시길....
그럼, 전 이만 오늘은 꿈나라로 가겠습니다...ㅋ.....
다들 좋은 꿈 꾸시고... 낼 다음 강좌에서 뵙죠....
이상, 케이신비였습니다....꾸벅~
====================================================================
허접한 강좌이지만 그래두 저작권은 저에게 있답니다.
다른 곳으로 퍼가셔도 괜찮지만, 그래도 메일정도는 보내주세요~ ^^
====================================================================
첫댓글 하핫...내힘으로 한건 아니지만..그래도 핸폰 액정위에 무언가를 만들어 보게 됬네요.ㅋㅋ 형 고맙구여~ 앞으로도 기대하겠음다~^^* 앞으로 질문 공세 나갈테니 준비하세욥~ㅋㅋ
강좌 잘 보고 갑니다.. ^^
네넵...감사요~
강좌 너무 고맙습니다. 사실 이렇게 친절하게 설명 해주시는 분 없는데... 정말 감사하게 생각하구요. 바쁘다는 것도 봤습니다. 앞으로 틈틈이라도 원활한 활동 부탁드립니다. 위피 개발회사를 들어가고픈 이제 시작하는 사람.........입니다.
비주얼 씨에 셋팅을 할때 WIFIHeader파일이 있는곳을 경로로 설정해놓으면 간편히 인클루드 시킬수 있을거 같네요. 다아시는거겠지만요.^^;
정말 감사하네요 이제야 제가 위피에 대해 알아가는것 같아요...
정말 감사합니다 쵝오
감사합니다 ^^