home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
CMDS
/
pcxview_mm1.lzh
/
PCXVIEW
/
pcxview.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-12-15
|
7KB
|
311 lines
#include <stdio.h>
#include <modes.h>
#include <types.h>
#include <signal.h>
#include "getargs.h"
extern errno;
extern char *pixels, *pcxpixels;
extern int Width, Height;
extern short BytesPerLine;
#define TABSIZE (sizeof(Argtab)/sizeof(ARG))
int actwin = -1, oldfile, signum, pauselen = -1;
int iflag, hflag, xflag, yflag, mflag, scale = 1;
int xoffset, yoffset, ny;
short h_pos, v_pos, ncolors, gotsig;
short screen_type, screen_width, screen_height, x_max, y_max, factor;
unsigned char *scraddr, *sptr, *scrend;
unsigned char colormap[256][3];
ARG Argtab[] =
{{'h', BOOLEAN, &hflag, "display header info only"},
{'i', BOOLEAN, &iflag, "read file from standard input"},
{'m', BOOLEAN, &mflag, "mouse scrolling"},
{'p', INTEGER, &pauselen, "pause in secs (0 = no pause, -1= wait for user)"},
{'s', INTEGER, &scale, "scale factor, must be 1 or 2"},
{'x', INTEGER, &xflag, "x offset in percent"},
{'y', INTEGER, &yflag, "y offset in percent"},
};
gotsignl(signum)
{
gotsig = signum;
if (signum != SIGQUIT && signum != SIGINT)
return;
Select(0);
exit(signum);
}
int wait4user(argc, argv)
int argc;
char **argv;
{
char c;
MCurOn(actwin);
if (pauselen > 0)
sleep(pauselen);
else if (pauselen < 0) {
if (mflag) {
_ss_sbar(actwin, h_pos, v_pos);
Bell(actwin);
return mmenu(actwin, argc, argv);
} else {
Bell(actwin);
do {
read(actwin, &c, 1);
} while (c != 13);
}
}
return 0;
}
main(argc, argv)
int argc;
char **argv;
{
int res, i;
register int y;
argc = getargs(argc, argv, Argtab, TABSIZE);
if (argc < 2 && !iflag)
usage();
if ( scale != 1 && scale != 2 ) {
fprintf(stderr, "scale %d must be 1 or 2 - ignored\n", scale);
scale = 1;
}
if (xflag < 0 || xflag >= 100) {
fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", xflag);
xflag = 0;
}
if (yflag < 0 || yflag >= 100) {
fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", yflag);
yflag = 0;
}
intercept(gotsignl);
if ( iflag )
argc++;
for (i = 1; i < argc; i++) {
pcx_read(argv[i]);
screen_width = 384;
screen_height = 480;
y_max = 56;
if (ncolors > 16) {
screen_type = 9;
x_max = 45;
factor = 3 - scale;
} else {
screen_type = 7;
x_max = 93;
factor = 1;
}
if (!hflag) {
oldfile = actwin;
actwin = open("/w", S_IWRITE | S_IREAD);
if (actwin == EOF)
exit(_errmsg(errno, "cannot open '/w'\n"));
DWEnd(actwin);
if (DWSet(actwin, screen_type, 0, 0, x_max + 3, screen_height / 8,
0, 0, 0) == EOF)
exit(_errmsg(errno, "cannot DWSet\n"));
CurOff(actwin);
ScaleSw(actwin, 0);
scraddr = (unsigned char *) _gs_scadd(actwin);
if (scraddr == NULL)
exit(_errmsg(errno, "cannot _gs_scadd\n"));
scrend = scraddr + screen_width*screen_height;
if (!hflag) {
h_pos = v_pos = 0;
Clear(actwin);
_ss_sbar(actwin, h_pos, v_pos);
}
} else
continue;
xoffset = xflag * Width / 100;
yoffset = yflag * Height / 100;
if ( ncolors <= 16 )
xoffset /= 2;
if ( _ss_palette(actwin, 0, colormap, 3 * ncolors) == -1 )
exit(_errmsg(errno, "cannot set palette\n"));
if (mflag) {
scraddr += 16 * screen_width + 8;
openwin(actwin);
_ss_tbar(actwin, argv[i]);
}
Select(actwin);
MCurOff(actwin);
if ( oldfile > 0 )
close(oldfile);
sptr = scraddr;
pcxpixels = pixels;
ny = ( ncolors <= 16 && scale > 1 ) ? Height/scale : Height;
for (y = 0; y < ny; y++) {
if ( scale > 1 )
rescale(pcxpixels, Width, scale);
if (mflag)
put_scanline_m(pcxpixels, Width/scale, y);
else
put_scanline(pcxpixels, Width/scale, y);
if ( ncolors > 16 )
pcxpixels += Width;
else
pcxpixels += Width*scale;
}
res = wait4user(argc, argv);
if (res == -1 && i > 1)
i -= 2;
if (res > 0)
i = res - 1;
free(pixels);
}
Select(0);
}
put_scanline(a, r_s, n) /* pixels -> scraddr */
unsigned char *a;
int r_s, n;
{
register int count;
register unsigned char *dest, *src, *next;
if ( ncolors <= 16 )
r_s /= 2;
r_s -= xoffset;
if (n < yoffset || n - yoffset > screen_height / factor|| r_s < 0)
return;
count = (r_s < screen_width) ? r_s : screen_width;
dest = sptr;
src = a + xoffset;
if ( ncolors > 16 ) {
next = dest + screen_width;
if ( scale > 1 ) {
while (count--)
*dest++ = *src++;
sptr += screen_width;
} else {
while (count--)
*dest++ = *next++ = *src++;
sptr += screen_width * 2;
}
} else {
while (count--)
*dest++ = *src++;
sptr += screen_width;
}
}
put_scanline_m(a, r_s, n) /* pixels -> scraddr */
unsigned char *a;
int r_s, n;
{
register int count;
register unsigned char *dest, *src, *next;
if ( ncolors <= 16 )
r_s /= 2;
r_s -= xoffset;
if (n < yoffset || n - yoffset > (screen_height - 24) / factor|| r_s < 0)
return;
count = (r_s < screen_width - 16) ? r_s : screen_width - 16;
dest = sptr;
src = a + xoffset;
if ( ncolors > 16 ) {
next = dest + screen_width;
if ( scale > 1 ) {
while (count--)
*dest++ = *src++;
sptr += screen_width;
} else {
while (count--)
*dest++ = *next++ = *src++;
sptr += screen_width * 2;
}
} else {
while (count--)
*dest++ = *src++;
sptr += screen_width;
}
}
int repaint(x, y)
int x, y;
{
register int i;
if (BytesPerLine < screen_width*scale - 16 && x > 0)
return 0;
if (ny < screen_height / factor - 12 && y > 0)
return 0;
xoffset = x * (BytesPerLine - screen_width + 16) / x_max;
yoffset = y * (ny - (screen_height - 24) / factor) / y_max;
pcxpixels = pixels;
sptr = scraddr;
Clear(actwin);
for (i = 0; i < ny; i++) {
put_scanline_m(pcxpixels, Width/scale, i);
if ( ncolors > 16 )
pcxpixels += Width;
else
pcxpixels += Width*scale;
}
return 1;
}
usage()
{
fprintf(stderr, "OS-9 PCXView 1.0 by Andrzej Kotanski\n");
fprintf(stderr, "usage: pcxview <filenames> [-<option> ...]\n");
fprintf(stderr, " displays pcx pictures on MM/1 screen");
fprintf(stderr, "\n\n");
pr_usage(Argtab, TABSIZE);
exit(0);
}
rescale(pixels, linelen, sc)
register u_char *pixels;
register int linelen;
register int sc;
{
register int i;
register u_char *ptr = pixels;
for ( i = 0; i < linelen; i += sc ) {
*pixels++ = *ptr;
ptr += sc;
}
}