반응형

만년력(달력) 프로그래밍 - Mobile C (GVM, GNEX)

글. 수알치 오상문

 

GNEX IDE를 실행하고 새 프로젝트를 실행합니다. 

에디터 창에 소스 입력 시작 부분을 보면 이미 기본 코딩 내용이 있을 겁니다.

그 설정 그대로 사용했으므로 아래 소스에서,

 

#include "C:\PROGRAM FILES\SINJISOFT\GNEX SDK\include\SScript.h"

 

아래 부분을 그대로 복사해서 넣으면 됩니다.

 

컴파일하고 실행해보면 달력 하나가 뜹니다.

모바일폰 (Nate) 주변의 상하좌우 버튼을 클릭하면 년과 달이 바뀝니다.

 

                년 증가

                     ▲

월 감소  ◀  Nate  ▶   월 증가

                     ▼

                년 감소

 

 

<소스 시작> cal.mc 

 

//-----------------------------------------------------------------
// 제   목 : 만년력 프로그램 (1583년 이후의 만년력)
//
// 작성자 : 오상문 
// 연락처 :

sualchi@daum.net


//
// 컴파일 환경 : 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로는 처음 짜보는 프로그램이라 어설픈 부분이 있을지 모르겠네요.

 

<이상> 

 

반응형

+ Recent posts