만년력(달력) 프로그래밍 - Mobile C (GVM, GNEX)
글. 수알치 오상문
GNEX IDE를 실행하고 새 프로젝트를 실행합니다.
에디터 창에 소스 입력 시작 부분을 보면 이미 기본 코딩 내용이 있을 겁니다.
그 설정 그대로 사용했으므로 아래 소스에서,
#include "C:\PROGRAM FILES\SINJISOFT\GNEX SDK\include\SScript.h"
아래 부분을 그대로 복사해서 넣으면 됩니다.
컴파일하고 실행해보면 달력 하나가 뜹니다.
모바일폰 (Nate) 주변의 상하좌우 버튼을 클릭하면 년과 달이 바뀝니다.
년 증가
▲
월 감소 ◀ Nate ▶ 월 증가
▼
년 감소
<소스 시작> cal.mc
//-----------------------------------------------------------------
// 제 목 : 만년력 프로그램 (1583년 이후의 만년력)
//
// 작성자 : 오상문
// 연락처 :
//
// 컴파일 환경 : GNEX SDK (Mobile C 언어)
// 최종 갱신 : 2004년 5월 13일
//
// 참고 1 : 출력부와 키입력 처리부를 손질하면 일반 C에서도 활용 가능
// 참고 2 : GNEX IDE의 기본 프로젝트 옵션 사용
//-----------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////
// cal.mc - Auto Created by GNEX IDE
%{
#DEFINE PLAYERVER 4
#DEFINE LCDCLASS 255
#DEFINE IMAGETYPE 255
#DEFINE AUDIOTYPE 255
#DEFINE APPTYPE 1
#DEFINE APPCPID 60000
#DEFINE APPID 1
#DEFINE APPNAME "GNEX App"
#DEFINE COMPTYPE 0
#DEFINE AGENTTYPE 0
#DEFINE VALIDCOUNT 255
#DEFINE VALIDTERM 255
#DEFINE DIRECTRUN 0
#DEFINE STORETYPE 0
#DEFINE APPVER 1
%}
#include "C:\PROGRAM FILES\SINJISOFT\GNEX SDK\include\SScript.h"
// <-- 새 프로젝트 시작하고 이곳 아래 부분의 소스를 그대로 복사하여 컴파일 실행함 -->
// 1583년 이전 년도까지의 윤년 횟수 (그레고리력 가상 기준)
#define SUM_LEAP_1582 383
#define ERROR_CODE -1
// [n] = n-1 월까지의 전체 일자 합 (예; [5] = 5월 이전까지의 전체 일자)
int iSumMon[] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
// 월별 최대 날짜 (2월은 평년 기준, 28일), iMon[1] = 1월 최대 날짜
int iMon[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
string wday[] = {"일", "월", "화", "수", "목", "금", "토"};
// 한달 달력 데이터를 담을 정수형 배열, 7일씩 6줄
int iCal[6][7]; // iCal[0][0] 에서 iCal[5][6]
int Date[4]; // 현재 년도와 월
// 윤년인지 알려준다. (반환 값 1 = 윤년, 0 = 평년)
int isLeapYear(int year)
{
return(((year%400) == 0) || ((year%4) == 0) && ((year%100) != 0));
}
// 1583년부터 입력된 년도 바로 전년까지의 윤년 숫자를 알려준다.
int CountLeapYear(int end_year)
{
// 1583년과 1584년은 바로 값을 돌려준다
if ((end_year == 1583) || (end_year == 1584)) {
return 0;
}
else if(end_year > 1584) { // 나머지는 계산 값 돌려줌
end_year--;
return((end_year/4) - (end_year/100) + (end_year/400) - SUM_LEAP_1582);
}
else
return ERROR_CODE; // -1 에러 코드
}
// 1583년부터 입력된 년도 바로 전년까지의 평년 숫자를 알려준다.
int CountNormalYear(int end_year)
{
if (end_year == 1583) { // 1583년과 1584년은 바로 값을 돌려준다
return 0;
}
else if (end_year == 1584) {
return 1;
}
else if (end_year > 1584) { // 나머지 년도는 계산 값 돌려줌
return(end_year - 1583 - CountLeapYear(end_year));
}
else
return ERROR_CODE; // -1 에러 코드
}
// 달력 초기화 (반환값 0~6 = 해당월 첫날의 요일, -1 = ERROR)
int InitMonData(int year, int month)
{
int ly, py, yo; // ly 윤년, py 평면, yo 요일계산
int days, leap; // days 이전달까지의 날짜 합, leap 윤달 보정값
int i, j, k;
if( (month < 1) || (month > 12) || (year < 1583) )
return ERROR_CODE; // 범위 초과 ERROR_CODE = -1
ly = CountLeapYear(year); // 윤년 숫자
py = CountNormalYear(year); // 평년 숫자
yo = ((ly * 2) + py) % 7; // 윤년 2, 평년 1씩 요일 증가
yo = (yo + 6) % 7; // 6 : 1583년 1월 1일은 토요일(6)
// 계산 결과는 해당년도 1월1일의 요일
leap = isLeapYear(year); // 윤달 : 1, 평달 : 0
days = iSumMon[month] + leap; // 그 이전 달까지의 전체 날짜 구함
yo = (yo + days) % 7; // 결과는 입력 월의 1일에 해당하는 요일
for (i = 0; i < 6; i++)
for (j = 0; j < 7; j++)
iCal[i][j] = 0; // 캘린더 초기화
// 2월은 윤달 보정 (초기화 겸함)
iMon[2] = 28 + leap;
// 캘린더 버퍼에 날짜 할당
for (i = 0; i < iMon[month]; i++)
iCal[(i+yo)/7][(i+yo)%7] = i+1;
return yo; // 해당 월 1일에 해당하는 요일을 돌려줌
}
// 달력을 화면에 출력하는 함수 (입력 값: year 년도와 month 월)
int CalOutput(int year, int month)
{
int i, j;
string ss, ss2;
if( InitMonData(year, month) == ERROR_CODE )
return ERROR_CODE; // 버퍼 초기화
// 캘린더 버퍼 데이터 출력부
// 이 부분은 테스트용이니 디자인 손질이 더 필요함.
ClearWhite();
IntToAscii(ss, year); // 이하 몇 줄은 년도와 월 출력
DrawText(35+5, 2, ss);
DrawText(35+30, 2, ". ");
IntToAscii(ss, month);
DrawText(35+40, 2, ss);
DrawHLine(5, 123, 20); // 선 긋기
for (i=0; i<7; i++) // 요일 출력
DrawText(i*18+5,25, wday[i]);
DrawHLine(5, 123, 40); // 선 긋기
for (i=0; i<6; i++) { // 실제 날짜 출력
for (j=0; j<7; j++) {
if(iCal[i][j] != 0) {
IntToAscii(ss, iCal[i][j]);
if(j%7==0) // 일요일이면 빨간색
SetFontColor(78,0);
else // 평일은 검정색 사용
SetFontColor(3,0);
DrawText(j*18+5,i*14+45, ss);
SetFontColor(3,0);
}
}
}
Flush();
return 1;
}
// 키 입력에 맞게 달력 년도와 월을 바꾸어줌
void EVENT_KEYPRESS()
{
switch ( swData )
{
case SWAP_KEY_UP : // 위 키 (년도 증가)
Date[0] += 1;
break;
case SWAP_KEY_DOWN : // 아래 키 (년도 감소)
Date[0] -= 1;
break;
case SWAP_KEY_RIGHT : // 오른쪽 키 (월 증가)
Date[1] += 1;
break;
case SWAP_KEY_LEFT : // 왼쪽 키 (월 감소)
Date[1] -= 1;
break;
}
// 월이 범위 벗어나면 년도 증감하고 전후 월로 바뀜
if(Date[1] < 1) {
Date[1] = 12;
Date[0] -= 1;
} else if(Date[1] > 12) {
Date[1] = 1;
Date[0] += 1;
}
// 년도가 1583년 이전이면 1583년 1월로 초기화
if(Date[0] < 1583) {
Date[0] = 1583;
Date[1] = 1;
}
if( CalOutput(Date[0], Date[1]) == ERROR_CODE ) {
ClearWhite();
DrawText(0,0, "ERROR!");
Flush();
}
}
void main()
{
GetDate(Date); // 시스템 현재 일자를 얻음
if( CalOutput(Date[0], Date[1]) == ERROR_CODE ) {
ClearWhite();
DrawText(0,0, "ERROR!");
Flush();
}
}
//-------------------------------------------------------------
<소스 끝> cal.mc
GNEX SDK에서 테스트했는데 GVM에서도 가능하리라 생각합니다.
Mobile C로는 처음 짜보는 프로그램이라 어설픈 부분이 있을지 모르겠네요.
<이상>
'Mobile APP' 카테고리의 다른 글
256색상표 (모바일C) (0) | 2011.03.27 |
---|---|
16색상표 (모바일C) (0) | 2011.03.27 |
아이폰 앱 디자인에서 지켜야할 것 (흔한 실수들) (0) | 2011.01.07 |
윈도우 폰 7 (Windows Phone 7) 무료 전자책 - 찰스펫졸드 지음 (0) | 2010.12.10 |
아이폰 애플리케이션 개발환경과 시작 (0) | 2010.01.07 |