home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / PD126 / PD.C next >
Text File  |  1992-03-08  |  7KB  |  276 lines

  1. /********************************************************************
  2.         PopDATE - RESIDENT CODE & DATA
  3.         (c) Copyright 1992 by Omega Point, Inc.
  4.            Author: Ratko V. Tomic
  5. *********************************************************************/
  6.  
  7. #include "cr.h"
  8.  
  9.  
  10. /********************************************************************
  11.       Definitions/Utilities used by the TSR
  12. *********************************************************************/
  13.  
  14. #define GREG_YEAR  1582    /* Gregorian calendar from Fri, Oct 15, 1582 */
  15. #define GREG_MON   10    /* Julian calendar was valid earlier          */
  16. #define GREG_DAY   15
  17.  
  18. #define MAX_YEAR  32000
  19.  
  20. int x0=8,y0=14;        /* Upper Left corner for calendar     */
  21. int wdx,wdy;        /* Window sizes                 */
  22. int mx,my;        /* Coordinates for day of month numbers  */
  23. int rvx,rvy;        /* Saved coordinates for last highlight  */
  24.  
  25. int col;        /* Column for days of month         */
  26. word *buf;        /* Buffer with calendar image/save image */
  27. char str[4]="25";    /* Used for conversions of numbers     */
  28. #define lead0 str[3]    /* Last byte of str[]=flag for leading 0 */
  29.  
  30. /*                 0    1    2    3    4    5   */
  31. byte cal_atr[6]={0x13,0x1B,0x71,0x74,0x4E,0x7C};
  32.  
  33. #define atr_low   cal_atr[0]
  34. #define atr_high  cal_atr[1]
  35. #define atr_bord  cal_atr[2]
  36. #define atr_arrow cal_atr[3]
  37. #define atr_rev   cal_atr[4]
  38. #define atr_dw    cal_atr[5]
  39.  
  40.  
  41. /*** Set X,Y to upper left corner ***/
  42.  
  43. corner()
  44. {
  45.    crs_x=x0; crs_y=y0;
  46. }
  47.  
  48. bottom()
  49. {
  50.    crs_x=x0+4; crs_y=y0+wdy-1;
  51.    vid_atr=atr_bord;
  52. }
  53.  
  54. /*** Swap screen image from buffer with Video RAM image  ***/
  55. /*** This is an efficient way to save and restore screen ***/
  56.  
  57. swap_screen()
  58. {
  59.    corner();
  60.    swap_blk(wdx,wdy,buf);
  61. }
  62.  
  63. /*** DISPLAY 2 DIGIT NUMBER ***/
  64.  
  65. show_num(int Num)
  66. { char *s=str;
  67.   int w;
  68.     *s=(w=Num)/10;
  69.     s[1]=w%10;
  70.     *(word*)s|=0x3030;            /* Convert to ASCII */
  71.     if (!lead0 && w<10) *s=0x20;    /* Remove leading 0 */
  72.     dsp(s); crs_x++;
  73. }
  74.  
  75. /*** DISPLAY LIST OF NUMBERS, WRAP INSIDE CALENDAR BOX ***/
  76.  
  77. show_lst(int Start,int Cnt)
  78. { int n,c;
  79.  
  80.     n=Start; c=Cnt;
  81.     vid_atr=atr_high;    /* Set-up high/low attributes */
  82.     if (c<15)
  83.       vid_atr=atr_low;
  84.     do {
  85.        show_num(n++);
  86.        crs_x++;
  87.        if (++col==7)    /* Wrap around after 7th day */
  88.          {
  89.      col=0;
  90.      crs_y++; crs_x=mx;
  91.      }
  92.        }
  93.     while(--c);
  94. }
  95.  
  96. show_time(TIME_REC *Time)
  97. { char *t;
  98.   int am;
  99.     bottom(); crs_x+=15;
  100.     t=&Time->hours;
  101.     am='A';
  102.     if (*t>12)
  103.       {
  104.       *t-=12; am='P';
  105.       }
  106.     if (!*t) {*t=12; am='P';}
  107.     lead0=0;
  108.     do { 
  109.        show_num(*t);
  110.        lead0=1;
  111.        }
  112.     while(--t>(char*)Time);
  113.     dsp(&am);
  114. }
  115.  
  116. /***************************************************************
  117.     CALENDAR COMPUTATIONS & DISPLAY
  118. ****************************************************************/
  119.  
  120. char mstr[12*4]=  "Jan\x0" "Feb\x0" "Mar\x0" "Apr\x0" "May\x0"
  121.           "Jun\x0" "Jul\x0" "Aug\x0" "Sep\x0" "Oct\x0"
  122.           "Nov\x0" "Dec\x0";
  123.  
  124. char mlen[13]= {31,31,28,31,30,31,30,31,31,30,31,30,31};
  125.  
  126.  
  127. /******************************************
  128.      Set length of February 
  129. *******************************************/
  130.  
  131. void set_feb(word Year)
  132. { word y=Year;
  133.   char *m=mlen+2;
  134.     *m=28;            /* Assume non-leap year   */
  135.     if (y&3) return;        /* Not div by 4 - regular */
  136.     (*m)++;            /* Div by 4 - assume leap */
  137.     if (!(y%100) && y%400)  /* Except when div by 100 */
  138.     (*m)--;            /* but not if div by 400  */
  139. }
  140.  
  141. /******************************************************
  142.    Compute day of week (Mon=0,Tue=1,..Sun=6)
  143. *******************************************************/
  144.  
  145. int day_of_week(DATE_REC *d)
  146. { int i;
  147.   word y,w;
  148.     set_feb(y=d->year);
  149.     w=(y+y/4-y/100+y/400);
  150.     i=0; y=d->month;
  151.     while (++i<y)
  152.       w+=mlen[i];
  153.     return (w+d->day_of_month+5-(mlen[2]&1))%7;
  154. }
  155.  
  156. /*********************************************
  157.     DISPLAY CALENDAR
  158. **********************************************/
  159.  
  160. void show_cal(TD_REC *d)
  161. { int m,d1,dw,c;
  162.  
  163.     crs_x=rvx; crs_y=rvy;    /* Remove earlier highlight */
  164.     vid_atr=atr_high;
  165.     hor_atr(4);
  166.  
  167.     lead0=col=0;        /* No leading 0 for days in month */
  168.     crs_x=mx; crs_y=my;
  169.     dw=day_of_week((DATE_REC*)&d->day);
  170.     d1=(dw+36-d->day)%7;    /* 1st day of this month */
  171.     if (!d1) d1=7;
  172.     m=d->mon;
  173.     show_lst(mlen[m-1]-(d1-1),d1); /* Show previous month, few days */
  174.     show_lst(1,c=mlen[m]);       /* Show current month */
  175.     show_lst(1,42-(c+d1));       /* Show next month, few days */
  176.  
  177.     bottom();            /* Display line at the bottom */
  178.     dsp(mstr+m*4-4);        /* Display current month */
  179.     crs_x++;
  180.     show_num(d->day);        /* Display day of month */
  181.     lead0++; crs_x++;
  182.     show_num(d->year/100);    /* Display year */
  183.     crs_x--;
  184.     show_num(d->year%100);
  185.     
  186.     corner();
  187.     hor_atr(wdx);        /* Remove old day-of-week highlight */
  188.     rvx=(crs_x+=2+(dw<<=2));
  189.     vid_atr=atr_arrow;
  190.     hor_atr(4);            /* Highlight current day-of-week */
  191.     vid_atr=atr_rev;        /* Reverse video on day of month */
  192.     rvy=(crs_y+=1+(d->day+d1-1)/7);
  193.     hor_atr(4);            /* Show day of month */
  194.  
  195. }
  196.  
  197.  
  198. /**************************************************************
  199.         MAIN CONTROL LOOP
  200. ***************************************************************/
  201.  
  202. run_calendar()
  203. { TD_REC td;
  204.   int cy,sy;    /* Current year, selected year, prev year */
  205.   char cm,sm;   /* Current month, selected month, prev month */
  206.   char cd;
  207.  
  208.     cd=cm=sm=cy=sy=0;
  209.  
  210.     while(1)
  211.        {
  212. Redo:
  213.        dos_td(&td);
  214.        show_time((TIME_REC*)&td);
  215.        if (cy==sy && cm==sm)    /* Displaying cy,cm month */
  216.          {
  217.      if (td.year!=cy || td.mon!=cm || td.day!=cd)
  218.        {
  219.        cy=sy=td.year;
  220.        cm=sm=td.mon;
  221.        cd=td.day;
  222.        show_cal(&td);
  223.        }
  224.      }
  225.        if (!anykey()) continue;
  226.        switch (pckey())
  227.          {
  228.      default:    cy=sy; cm=sm; cd=0;
  229.              goto Redo;
  230.      case K_LEFT:    if (sm>1) {sm--; break;}
  231.              sm=12;
  232.      case K_UP:    sy--; break;
  233.      case K_RIGHT:    if (sm<12) {sm++; break;}
  234.              sm=1;
  235.      case K_DN:    sy++; break;
  236.      case K_PGUP:   sy-=10; break;
  237.      case K_PGDN:    sy+=10; break;
  238.      case 0x1B:    ;
  239.      case K_ESC:    goto Done;
  240.      }
  241.        td.day=1;
  242.        if (sy>=MAX_YEAR) sy=MAX_YEAR;
  243.        if (sy<=GREG_YEAR)
  244.          {
  245.      sy=GREG_YEAR;
  246.      if (sm<=GREG_MON) 
  247.        {
  248.        sm=GREG_MON;
  249.        td.day=GREG_DAY;
  250.        }
  251.      }
  252.        td.year=sy; td.mon=sm;
  253.        cd=0;
  254.        show_cal(&td);
  255.        }
  256. Done:
  257.     flush_kbd();
  258. }
  259.  
  260.  
  261. /***************************************************************
  262.           HOTKEY SERVICE
  263. ***************************************************************/
  264.  
  265.  
  266. void service()
  267. {
  268.     if (dos_busy(20))    /* We need DOS for current date time */
  269.       return;
  270.     chk_video();
  271.     swap_screen();
  272.     _hkey_again=0;
  273.     run_calendar();
  274.     swap_screen();
  275. }
  276.