www.pudn.com > commutil.zip > FVIEW.CPP


// ******************************************************************** // 
//                                                                      // 
//      FVIEW.CPP                                                       // 
//      Copyright (c) 1993, Michael Holmes and Bob Flanders             // 
//      C++ Communication Utilities                                     // 
//                                                                      // 
//      This file contains the routines under the VIEW main menu        // 
//      entry.  These routines provide for the viewing of a G3 fax      // 
//      on a VGA screen.                                                // 
//                                                                      // 
// ******************************************************************** // 
 
#define VIDEO_GET_MODE()    r.x.ax = 0x0f00;            \ 
                            int86(0x10, &r, &r) 
 
#define VIDEO_SET_MODE(a)   r.x.ax = a;                 \ 
                            r.x.bx = 0;                 \ 
                            int86(0x10, &r, &r) 
#define VIDEO_DOT(a, b, c)  r.x.ax = 0x0c00 | c;        \ 
                            r.x.bx = 0;                 \ 
                            r.x.cx = a; r.x.dx = b;     \ 
                            int86(0x10, &r, &r) 
#define VIDEO_WRITE(a)      r.x.ax = 0x0e00 | a;        \ 
                            r.x.bx = 7;                 \ 
                            int86(0x10, &r, &r) 
#define VIDEO_POS(a, b)     r.x.ax = 0x0200;            \ 
                            r.h.bh = 0;                 \ 
                            r.x.dx = (b << 8) | a;      \ 
                            int86(0x10, &r, &r) 
#define VIDEO_STRING(a)     { for (char *s = a; *s; s++)\ 
                                { VIDEO_WRITE(*s); } } 
#define VIDEO_CLR()         r.x.ax = 0x0700;            \ 
                            r.h.bh = 7;                 \ 
                            r.x.cx = 0;                 \ 
                            r.x.dx = 0x1e4f;            \ 
                            int86(0x10, &r, &r) 
 
 
 
/* ******************************************************************** * 
 * 
 *  f_bit_count() -- return total number of bits on based on zoom 
 * 
 * ******************************************************************** */ 
 
int     f_bit_count(char *p,                // start of line 
                    int  sb,                // starting bit number 
                    int  z)                 // zoom (number of bits) 
{ 
int     total = 0,                          // total bits on 
        i, j,                               // loop control 
        sbp;                                // start bit prime 
 
 
for (i = 0; i < z; i++, p += LINE)          // for each line 
    for (j = 0, sbp = sb; j < z; j++, sbp++)// ..and each bit in zoom 
        total += get_bit((UCHAR *) p, sbp); // tally the on bits 
 
return(total);                              // return with "on" bit count 
 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  f_show_part() -- draw a portion of a page on the screen 
 * 
 * ******************************************************************** */ 
 
void    f_show_part(int x, int y,           // column and row base 
                    int z,                  // zoom level 
                    int pg)                 // page number 
{ 
int     i, ii, j, jj,                       // loop control 
        imax, jmax,                         // ..and more loop control 
        w;                                  // work bit collector 
char    huge *p,                            // work pointer 
        buf[80];                            // string buffer 
union   REGS r;                             // cpu registers 
static 
char    f_colors[3][10] =                   // zoom level to video dots 
    { 
    { 0, 1, 1 },                            // 1 bit zoom (2 bits max) 
    { 0, 0, 1, 1, 1 },                      // 2 bit zoom (4 bits max) 
    { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }        // 3 bit zoom (9 bits max) 
    }; 
 
sprintf(buf, "%s  Page %d  Zoom %d",        // prepare bottom line 
            f_filename, pg, z);             // ..to keep user informed 
 
VIDEO_CLR();                                // clear screen 
VIDEO_POS(0, 29);                           // get to bottom line 
VIDEO_STRING(buf);                          // ..and give status 
 
p = &page[(long) y * LINE];                 // find bitmap start point 
 
imax = 640;                                 // use screen width 
jmax = 480;                                 // ..and max line count 
 
for (j = y, jj = 0;                         // for each line .. 
            jj < jmax && j < LINES;         // ..loop till bottom of screen 
            j += z, jj++, p += (LINE * z))  // ..or end of data 
    { 
    for (i = x, ii = 0;                     // and write dots until out 
                ii < imax && i < PELS;      // ..of source bits in bitmap 
                i += z, ii++)               // ..or screen 
        { 
        w = f_bit_count((char *) p, i, z);  // get some bits 
 
        if (f_colors[z - 1][w])             // q. enough bits on? 
            { 
            VIDEO_DOT(ii, jj, 0);           // a. yes .. display a dot 
            } 
        } 
 
    if (bioskey(1))                         // q. key available? 
        return;                             // a. yes .. return to caller 
    } 
 
VIDEO_POS(0, 29);                           // get to bottom line 
VIDEO_STRING(buf);                          // ..and give status 
 
} 
 
 
 
/* ******************************************************************** * 
 * 
 *  f_view() -- view a fax on the screen 
 * 
 * ******************************************************************** */ 
 
#pragma argsused 
 
int     f_view(int cc, int rr)              // column and row 
{ 
int     x, y,                               // page positioning 
        z,                                  // zoom factor 
        pn = 1,                             // fax page number 
        k = 1,                              // keystroke buffer 
        qf = 0;                             // quit flag 
char    old_mode,                           // old video mode 
        buf[50];                            // string buffer 
union   REGS r;                             // cpu registers 
Window  v_win(1, 1, 80, 25,                 // define temporary window 
            menu_cn, menu_cr);              // ..using system colors 
 
 
if (f_handle == -1)                         // q. file open? 
    return(ESC);                            // a. no .. just return 
 
v_win.Open(none);                           // open window to save screen 
 
VIDEO_GET_MODE();                           // get current video mode 
old_mode = r.h.al;                          // ..and save for later 
 
VIDEO_SET_MODE(0x11);                       // select video mode 
VIDEO_GET_MODE();                           // get current video mode 
 
if (r.h.al != 0x11)                         // q. unsupported mode? 
    { 
    VIDEO_SET_MODE(old_mode);               // a. yes .. select old mode 
    return(ESC);                            // ..and just return 
    } 
 
sprintf(buf, fmt_msg, pn);                  // format information message 
VIDEO_CLR();                                // clear screen 
VIDEO_POS(31, 15);                          // center on the screen 
VIDEO_STRING(buf);                          // ..and give status 
 
if (f_read_g3(pn))                          // q. 1st page available? 
    qf = 1;                                 // a. no .. set quit flag 
 
x = y = 0;                                  // start at top left of page 
z = 1;                                      // set zoom to max level 
 
while (NOT qf)                              // loop until quit requested 
    { 
    if (k)                                  // q. need to show something? 
        f_show_part(x, y, z, pn);           // a. yes .. part of a page 
 
    while (NOT (k = get_key(NO_ALT)))       // wait for a key 
        ;                                   // ..before continuing 
 
    switch (k)                              // handle user's input 
        { 
        case LEFT:                          // left key 
            if ((x - 576) >= 0)             // q. can show more on left? 
                x -= 576;                   // a. yes .. set up coordinate 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep a little 
                } 
 
            break;                          // ..then get next key 
 
        case RIGHT:                         // right key 
            if ((x + 576) < PELS)           // q. more to show on right? 
                x += 576;                   // a. yes .. set up coordinate 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep a little 
                } 
 
            break;                          // ..then get next key 
 
        case HOME:                          // home key 
            x = y = 0;                      // reset pointers to top left 
            break;                          // ..and wait for next key 
 
        case END:                           // end key 
            x = 0;                          // get to left margin 
            y = LINES - 200;                // ..and bottom of page 
            break;                          // ..and wait for next key 
 
        case INSERT:                        // insert key 
        case '+':                           // ..or plus key 
            if (z > 1)                      // q. room to increase detail? 
                z--;                        // a. yes .. change zoom 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep a little 
                } 
 
            break;                          // ..and wait for next key 
 
        case DELETE:                        // delete key 
        case '-':                           // ..or minus key 
            if (z < 3)                      // q. room to decrease detail? 
                z++;                        // a. yes .. change zoom 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep a little 
                } 
 
            break;                          // ..and wait for next key 
 
        case UP:                            // up arrow key 
            if ((y - 200) >= 0)             // q. room to move up? 
                y -= 200;                   // a. yes .. adjust coordinate 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep instead 
                } 
 
            break;                          // ..and get next key 
 
        case DOWN:                          // down arrow key 
        case CR:                            // carriage return 
            if ((y + 200) < LINES)          // q. room to move down? 
                y += 200;                   // a. yes .. adjust coordinate 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep instead 
                } 
 
            break;                          // ..and get next key 
 
        case PAGE_UP:                       // page up 
            if (pn > 1)                     // q. previous page available? 
                {                           // a. yes .. format prev page 
                sprintf(buf, fmt_msg, --pn);// format information message 
                VIDEO_CLR();                // clear screen 
                VIDEO_POS(31, 15);          // center on the screen 
                VIDEO_STRING(buf);          // ..and give status 
 
                f_read_g3(pn);              // format previous page 
                x = y = 0;                  // ..and set up indices 
                } 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep instead 
                } 
 
            break;                          // ..and get next key 
 
        case PAGE_DOWN:                     // page down 
            if (pn < f_pgcnt)               // q. next page available? 
                {                           // a. yes .. format prev page 
                sprintf(buf, fmt_msg, ++pn);// format information message 
                VIDEO_CLR();                // clear screen 
                VIDEO_POS(31, 15);          // center on the screen 
                VIDEO_STRING(buf);          // ..and give status 
 
                f_read_g3(pn);              // format the page 
                x = y = 0;                  // ..and set up indices 
                } 
             else 
                { 
                k = 0;                      // else .. don't re-draw screen 
                printf(BELL);               // ..but beep instead 
                } 
 
            break;                          // ..and get next key 
 
        case ESC:                           // escape key 
            qf = 1;                         // set quit flag 
            break;                          // ..and exit loop 
 
        default:                            // error case 
            printf(BELL);                   // ring the bell 
            k = 0;                          // don't re-draw the screen 
            break;                          // ..and wait for next key 
        } 
    } 
 
 
VIDEO_SET_MODE(old_mode);                   // select old video mode 
return(ESC);                                // finally, rtn to caller 
 
}