📄 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 huge *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 huge *) p, // tally the on bits
sbp);
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(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 (_bios_keybrd(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
*
* ******************************************************************** */
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
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -