1 |
greg |
2.1 |
#ifndef lint |
2 |
greg |
2.12 |
static const char RCSid[] = "$Id: vgaimage.c,v 2.11 2004/01/02 12:47:01 schorsch Exp $"; |
3 |
greg |
2.1 |
#endif |
4 |
|
|
/* |
5 |
|
|
* vgaimage.c - driver for VGA board under DOS |
6 |
|
|
*/ |
7 |
|
|
|
8 |
schorsch |
2.11 |
#include <stdio.h> |
9 |
|
|
|
10 |
greg |
2.1 |
#include "standard.h" |
11 |
|
|
#include <graph.h> |
12 |
|
|
#include "color.h" |
13 |
|
|
#include "random.h" |
14 |
|
|
#include "resolu.h" |
15 |
|
|
#include <dos.h> |
16 |
|
|
#include <i86.h> |
17 |
|
|
|
18 |
greg |
2.3 |
#define M_RDOWN 0x8 |
19 |
|
|
#define M_RUP 0x10 |
20 |
|
|
#define M_LDOWN 0x2 |
21 |
|
|
#define M_LUP 0x4 |
22 |
|
|
#define M_MOTION 0x1 |
23 |
greg |
2.1 |
|
24 |
|
|
int crad; |
25 |
|
|
int mouse_event = 0; |
26 |
|
|
int mouse_xpos = -1; |
27 |
|
|
int mouse_ypos = -1; |
28 |
|
|
|
29 |
greg |
2.3 |
#define hide_cursor() move_cursor(-1,-1) |
30 |
|
|
#define show_cursor() move_cursor(mouse_xpos,mouse_ypos) |
31 |
greg |
2.1 |
|
32 |
greg |
2.3 |
#define CTRL(c) ((c)-'@') |
33 |
greg |
2.1 |
|
34 |
greg |
2.3 |
#define MAXWIDTH 1024 |
35 |
|
|
#define MAXHEIGHT 768 |
36 |
greg |
2.1 |
|
37 |
|
|
short ourblack = 0; ourwhite = 1; |
38 |
|
|
|
39 |
greg |
2.3 |
double gamcor = 2.2; /* gamma correction */ |
40 |
greg |
2.1 |
|
41 |
greg |
2.3 |
int dither = 1; /* dither colors? */ |
42 |
greg |
2.1 |
|
43 |
greg |
2.3 |
int maxcolors = 0; /* maximum colors */ |
44 |
|
|
int minpix = 0; /* minimum pixel value */ |
45 |
|
|
int greyscale = 0; /* in grey */ |
46 |
greg |
2.1 |
|
47 |
greg |
2.3 |
int scale = 0; /* scalefactor; power of two */ |
48 |
greg |
2.1 |
|
49 |
greg |
2.3 |
COLR scanline[MAXWIDTH]; /* scan line buffer */ |
50 |
greg |
2.1 |
|
51 |
greg |
2.3 |
int xmax, ymax; /* picture dimensions */ |
52 |
|
|
FILE *fin = stdin; /* input file */ |
53 |
|
|
long scanpos[MAXHEIGHT]; /* scan line positions in file */ |
54 |
|
|
int cury = 0; /* current scan location */ |
55 |
greg |
2.1 |
|
56 |
greg |
2.3 |
double exposure = 1.0; /* exposure compensation used */ |
57 |
greg |
2.1 |
|
58 |
greg |
2.3 |
int wrongformat = 0; /* input in another format? */ |
59 |
greg |
2.1 |
|
60 |
|
|
struct { |
61 |
|
|
int xmin, ymin, xsiz, ysiz; |
62 |
greg |
2.3 |
} box = {0, 0, 0, 0}; /* current box */ |
63 |
greg |
2.1 |
|
64 |
|
|
int initialized = 0; |
65 |
|
|
int cheight, cwidth; |
66 |
|
|
|
67 |
greg |
2.3 |
#define postext(x,y) _settextposition(1+(y)/cheight,1+(x)/cwidth) |
68 |
greg |
2.1 |
|
69 |
|
|
char *progname; |
70 |
|
|
|
71 |
|
|
char errmsg[128]; |
72 |
|
|
|
73 |
greg |
2.3 |
extern BYTE clrtab[256][3]; /* global color map */ |
74 |
greg |
2.1 |
|
75 |
schorsch |
2.11 |
static gethfunc headline; |
76 |
greg |
2.1 |
|
77 |
|
|
|
78 |
|
|
main(argc, argv) |
79 |
|
|
int argc; |
80 |
|
|
char *argv[]; |
81 |
|
|
{ |
82 |
|
|
extern char *getenv(), *fixargv0(); |
83 |
|
|
char *gv; |
84 |
|
|
int i; |
85 |
greg |
2.3 |
|
86 |
greg |
2.1 |
progname = argv[0] = fixargv0(argv[0]); |
87 |
greg |
2.8 |
if ((gv = getenv("DISPLAY_GAMMA")) != NULL) |
88 |
greg |
2.1 |
gamcor = atof(gv); |
89 |
|
|
|
90 |
|
|
for (i = 1; i < argc; i++) |
91 |
|
|
if (argv[i][0] == '-') |
92 |
|
|
switch (argv[i][1]) { |
93 |
|
|
case 'c': |
94 |
|
|
maxcolors = atoi(argv[++i]); |
95 |
|
|
break; |
96 |
|
|
case 'b': |
97 |
|
|
greyscale = !greyscale; |
98 |
|
|
break; |
99 |
|
|
case 'm': |
100 |
|
|
maxcolors = 2; |
101 |
|
|
break; |
102 |
|
|
case 'd': |
103 |
|
|
dither = !dither; |
104 |
|
|
break; |
105 |
|
|
case 'e': |
106 |
|
|
if (argv[i+1][0] != '+' && argv[i+1][0] != '-') |
107 |
|
|
goto userr; |
108 |
|
|
scale = atoi(argv[++i]); |
109 |
|
|
break; |
110 |
|
|
case 'g': |
111 |
|
|
gamcor = atof(argv[++i]); |
112 |
|
|
break; |
113 |
|
|
default: |
114 |
|
|
goto userr; |
115 |
|
|
} |
116 |
|
|
else |
117 |
|
|
break; |
118 |
|
|
|
119 |
greg |
2.3 |
if (i == argc-1) { /* open picture */ |
120 |
greg |
2.1 |
fin = fopen(argv[i], "r"); |
121 |
|
|
if (fin == NULL) { |
122 |
|
|
sprintf(errmsg, "cannot open file \"%s\"", argv[i]); |
123 |
|
|
quiterr(errmsg); |
124 |
|
|
} |
125 |
|
|
} else if (i != argc) |
126 |
|
|
goto userr; |
127 |
|
|
setmode(fileno(fin), O_BINARY); |
128 |
|
|
/* get header */ |
129 |
|
|
getheader(fin, headline, NULL); |
130 |
|
|
/* get picture dimensions */ |
131 |
|
|
if (wrongformat || fgetresolu(&xmax, &ymax, fin) < 0) |
132 |
|
|
quiterr("bad picture format"); |
133 |
|
|
if (xmax > MAXWIDTH | ymax > MAXHEIGHT) |
134 |
|
|
quiterr("input picture too large for VGA"); |
135 |
|
|
|
136 |
greg |
2.3 |
init(); /* initialize and display */ |
137 |
greg |
2.1 |
|
138 |
greg |
2.3 |
while (docommand()) /* loop on command */ |
139 |
greg |
2.1 |
; |
140 |
|
|
quiterr(NULL); |
141 |
|
|
userr: |
142 |
|
|
fprintf(stderr, |
143 |
|
|
"Usage: %s [-b][-m][-d][-c ncolors][-e +/-stops] file\n", progname); |
144 |
|
|
exit(1); |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
|
148 |
schorsch |
2.11 |
static int |
149 |
|
|
headline( /* get relevant info from header */ |
150 |
|
|
char *s, |
151 |
|
|
void *p |
152 |
|
|
) |
153 |
greg |
2.1 |
{ |
154 |
|
|
char fmt[32]; |
155 |
|
|
|
156 |
|
|
if (isexpos(s)) |
157 |
|
|
exposure *= exposval(s); |
158 |
|
|
else if (isformat(s)) { |
159 |
|
|
formatval(fmt, s); |
160 |
|
|
wrongformat = strcmp(fmt, COLRFMT); |
161 |
|
|
} |
162 |
gwlarson |
2.9 |
return(0); |
163 |
greg |
2.1 |
} |
164 |
|
|
|
165 |
|
|
|
166 |
greg |
2.3 |
init() /* initialize and load display */ |
167 |
greg |
2.1 |
{ |
168 |
|
|
static struct { |
169 |
greg |
2.3 |
short mode; |
170 |
|
|
short xsiz, ysiz; |
171 |
|
|
} video[] = { |
172 |
greg |
2.1 |
{_MRES256COLOR, 320, 200}, |
173 |
greg |
2.6 |
{_VRES256COLOR, 640, 480}, |
174 |
greg |
2.1 |
{_SVRES256COLOR, 800, 600}, |
175 |
|
|
{_XRES256COLOR, 1024, 768}, |
176 |
greg |
2.6 |
{-1, 0, 0} |
177 |
greg |
2.1 |
}; |
178 |
greg |
2.3 |
struct videoconfig config; |
179 |
|
|
register int i; |
180 |
greg |
2.1 |
/* pick a card... */ |
181 |
|
|
for (i = 0; video[i].mode != -1; i++) |
182 |
|
|
if (video[i].xsiz >= xmax && video[i].ysiz >= ymax) |
183 |
|
|
break; |
184 |
|
|
if (video[i].mode == -1) |
185 |
|
|
quiterr("input picture too large"); |
186 |
|
|
if (_setvideomode(video[i].mode) == 0) |
187 |
|
|
quiterr("inadequate display card for picture"); |
188 |
greg |
2.4 |
ms_init(); |
189 |
greg |
2.1 |
initialized = 1; |
190 |
|
|
_getvideoconfig(&config); |
191 |
greg |
2.5 |
if (maxcolors == 0 | maxcolors > config.numcolors) |
192 |
|
|
maxcolors = config.numcolors-2; |
193 |
|
|
if (maxcolors <= config.numcolors-2) |
194 |
|
|
minpix = 2; |
195 |
|
|
else |
196 |
|
|
ourwhite = maxcolors-1; |
197 |
|
|
_settextcolor(ourwhite); |
198 |
greg |
2.1 |
cheight = config.numypixels/config.numtextrows; |
199 |
|
|
cwidth = config.numxpixels/config.numtextcols; |
200 |
|
|
/* clear scan position array */ |
201 |
|
|
for (i = 0; i < ymax; i++) |
202 |
|
|
scanpos[i] = -1; |
203 |
|
|
/* display image */ |
204 |
|
|
if (greyscale) |
205 |
|
|
greyimage(); |
206 |
|
|
else |
207 |
|
|
mappedimage(); |
208 |
|
|
} |
209 |
|
|
|
210 |
|
|
|
211 |
greg |
2.3 |
quiterr(err) /* print message and exit */ |
212 |
greg |
2.1 |
char *err; |
213 |
|
|
{ |
214 |
greg |
2.4 |
if (initialized) { |
215 |
|
|
ms_done(); |
216 |
greg |
2.1 |
_setvideomode(_DEFAULTMODE); |
217 |
greg |
2.4 |
} |
218 |
greg |
2.1 |
if (err != NULL) { |
219 |
|
|
fprintf(stderr, "%s: %s\n", progname, err); |
220 |
|
|
exit(1); |
221 |
|
|
} |
222 |
|
|
exit(0); |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
|
226 |
|
|
int |
227 |
greg |
2.3 |
docommand() /* execute command */ |
228 |
greg |
2.1 |
{ |
229 |
|
|
char buf[64]; |
230 |
|
|
COLOR cval; |
231 |
|
|
int com; |
232 |
greg |
2.3 |
double comp; |
233 |
greg |
2.1 |
|
234 |
|
|
while (!kbhit()) |
235 |
|
|
watch_mouse(); |
236 |
|
|
com = getch(); |
237 |
greg |
2.3 |
switch (com) { /* interpret command */ |
238 |
greg |
2.1 |
case 'q': |
239 |
greg |
2.3 |
case CTRL('Z'): /* quit */ |
240 |
greg |
2.1 |
return(0); |
241 |
|
|
case '\n': |
242 |
|
|
case '\r': |
243 |
|
|
case 'l': |
244 |
greg |
2.3 |
case 'c': /* value */ |
245 |
greg |
2.1 |
if (avgbox(cval) == -1) |
246 |
|
|
return(-1); |
247 |
|
|
switch (com) { |
248 |
|
|
case '\n': |
249 |
greg |
2.3 |
case '\r': /* radiance */ |
250 |
greg |
2.1 |
sprintf(buf, "%.3f", intens(cval)/exposure); |
251 |
|
|
break; |
252 |
greg |
2.3 |
case 'l': /* luminance */ |
253 |
greg |
2.1 |
sprintf(buf, "%.0fL", luminance(cval)/exposure); |
254 |
|
|
break; |
255 |
greg |
2.3 |
case 'c': /* color */ |
256 |
greg |
2.1 |
comp = pow(2.0, (double)scale); |
257 |
|
|
sprintf(buf, "(%.2f,%.2f,%.2f)", |
258 |
|
|
colval(cval,RED)*comp, |
259 |
|
|
colval(cval,GRN)*comp, |
260 |
|
|
colval(cval,BLU)*comp); |
261 |
|
|
break; |
262 |
|
|
} |
263 |
|
|
postext(box.xmin+box.xsiz/2, box.ymin+box.ysiz/2); |
264 |
greg |
2.2 |
hide_cursor(); |
265 |
greg |
2.1 |
_outtext(buf); |
266 |
greg |
2.2 |
show_cursor(); |
267 |
greg |
2.1 |
return(1); |
268 |
|
|
default: |
269 |
|
|
return(-1); |
270 |
|
|
} |
271 |
|
|
} |
272 |
|
|
|
273 |
|
|
|
274 |
greg |
2.3 |
watch_mouse() /* look after mousie */ |
275 |
greg |
2.1 |
{ |
276 |
greg |
2.3 |
int a_x, a_y, l_x, l_y; |
277 |
greg |
2.1 |
|
278 |
|
|
if (mouse_event & M_MOTION) |
279 |
|
|
move_cursor(mouse_xpos, mouse_ypos); |
280 |
|
|
if (!(mouse_event & M_LDOWN)) |
281 |
|
|
return; |
282 |
|
|
l_x = a_x = mouse_xpos; l_y = a_y = mouse_ypos; |
283 |
greg |
2.2 |
hide_cursor(); |
284 |
greg |
2.3 |
revbox(a_x, a_y, l_x, l_y); /* show box */ |
285 |
greg |
2.1 |
do { |
286 |
|
|
mouse_event = 0; |
287 |
|
|
while (!mouse_event) |
288 |
|
|
; |
289 |
|
|
if (mouse_event & M_MOTION) { |
290 |
|
|
revbox(a_x, a_y, l_x, l_y); |
291 |
|
|
revbox(a_x, a_y, l_x=mouse_xpos, l_y=mouse_ypos); |
292 |
|
|
} |
293 |
|
|
} while (!(mouse_event & M_LUP)); |
294 |
greg |
2.3 |
revbox(a_x, a_y, l_x, l_y); /* hide box */ |
295 |
greg |
2.2 |
show_cursor(); |
296 |
greg |
2.1 |
box.xmin = mouse_xpos; |
297 |
|
|
box.ymin = mouse_ypos; |
298 |
|
|
if (box.xmin > a_x) { |
299 |
|
|
box.xsiz = box.xmin - a_x + 1; |
300 |
|
|
box.xmin = a_x; |
301 |
|
|
} else { |
302 |
|
|
box.xsiz = a_x - box.xmin + 1; |
303 |
|
|
} |
304 |
|
|
if (box.ymin > a_y) { |
305 |
|
|
box.ysiz = box.ymin - a_y + 1; |
306 |
|
|
box.ymin = a_y; |
307 |
|
|
} else { |
308 |
|
|
box.ysiz = a_y - box.ymin + 1; |
309 |
|
|
} |
310 |
|
|
mouse_event = 0; |
311 |
|
|
} |
312 |
|
|
|
313 |
|
|
|
314 |
greg |
2.3 |
revbox(x0, y0, x1, y1) /* draw box with reversed lines */ |
315 |
greg |
2.1 |
int x0, y0, x1, y1; |
316 |
|
|
{ |
317 |
|
|
_setplotaction(_GXOR); |
318 |
|
|
_setcolor(255); |
319 |
|
|
_moveto(x0, y0); |
320 |
|
|
_lineto(x1, y0); |
321 |
|
|
_lineto(x1, y1); |
322 |
|
|
_lineto(x0, y1); |
323 |
|
|
_lineto(x0, y0); |
324 |
|
|
} |
325 |
|
|
|
326 |
|
|
|
327 |
|
|
int |
328 |
greg |
2.3 |
avgbox(clr) /* average color over current box */ |
329 |
greg |
2.1 |
COLOR clr; |
330 |
|
|
{ |
331 |
|
|
static COLOR lc; |
332 |
|
|
static int ll, lr, lt, lb; |
333 |
|
|
int left, right, top, bottom; |
334 |
|
|
int y; |
335 |
greg |
2.3 |
double d; |
336 |
greg |
2.1 |
COLOR ctmp; |
337 |
|
|
register int x; |
338 |
|
|
|
339 |
|
|
setcolor(clr, 0.0, 0.0, 0.0); |
340 |
|
|
left = box.xmin; |
341 |
|
|
right = left + box.xsiz; |
342 |
|
|
if (left < 0) |
343 |
|
|
left = 0; |
344 |
|
|
if (right > xmax) |
345 |
|
|
right = xmax; |
346 |
|
|
if (left >= right) |
347 |
|
|
return(-1); |
348 |
|
|
top = box.ymin; |
349 |
|
|
bottom = top + box.ysiz; |
350 |
|
|
if (top < 0) |
351 |
|
|
top = 0; |
352 |
|
|
if (bottom > ymax) |
353 |
|
|
bottom = ymax; |
354 |
|
|
if (top >= bottom) |
355 |
|
|
return(-1); |
356 |
|
|
if (left == ll && right == lr && top == lt && bottom == lb) { |
357 |
|
|
copycolor(clr, lc); |
358 |
|
|
return(0); |
359 |
|
|
} |
360 |
|
|
for (y = top; y < bottom; y++) { |
361 |
|
|
if (getscan(y) == -1) |
362 |
|
|
return(-1); |
363 |
|
|
for (x = left; x < right; x++) { |
364 |
|
|
colr_color(ctmp, scanline[x]); |
365 |
|
|
addcolor(clr, ctmp); |
366 |
|
|
} |
367 |
|
|
} |
368 |
|
|
d = 1.0/((right-left)*(bottom-top)); |
369 |
|
|
scalecolor(clr, d); |
370 |
|
|
ll = left; lr = right; lt = top; lb = bottom; |
371 |
|
|
copycolor(lc, clr); |
372 |
|
|
return(0); |
373 |
|
|
} |
374 |
|
|
|
375 |
|
|
|
376 |
greg |
2.3 |
setpalette() /* set our palette using clrtab */ |
377 |
greg |
2.1 |
{ |
378 |
greg |
2.3 |
long cvals[256]; |
379 |
|
|
register int i; |
380 |
greg |
2.1 |
|
381 |
greg |
2.5 |
cvals[ourblack] = _BLACK; |
382 |
|
|
cvals[ourwhite] = _BRIGHTWHITE; |
383 |
greg |
2.1 |
for (i = 0; i < maxcolors; i++) |
384 |
greg |
2.7 |
cvals[i+minpix] = (long)clrtab[i][BLU]<<14 & 0x3f0000L | |
385 |
greg |
2.1 |
clrtab[i][GRN]<<6 & 0x3f00 | |
386 |
|
|
clrtab[i][RED]>>2; |
387 |
|
|
_remapallpalette(cvals); |
388 |
|
|
} |
389 |
|
|
|
390 |
|
|
|
391 |
greg |
2.3 |
greyimage() /* display greyscale image */ |
392 |
greg |
2.1 |
{ |
393 |
greg |
2.3 |
short thiscolor, lastcolor = -1; |
394 |
|
|
int y; |
395 |
|
|
register int x; |
396 |
greg |
2.1 |
/* set gamma correction */ |
397 |
|
|
setcolrgam(gamcor); |
398 |
|
|
/* set up color map */ |
399 |
|
|
for (x = 0; x < maxcolors; x++) |
400 |
greg |
2.5 |
clrtab[x][RED] = clrtab[x][GRN] = clrtab[x][BLU] = |
401 |
|
|
((long)x*256 + 128)/maxcolors; |
402 |
greg |
2.1 |
setpalette(); |
403 |
|
|
_setplotaction(_GPSET); |
404 |
|
|
/* read and display file */ |
405 |
|
|
for (y = 0; y < ymax; y++) { |
406 |
|
|
getscan(y); |
407 |
|
|
if (scale) |
408 |
|
|
shiftcolrs(scanline, xmax, scale); |
409 |
greg |
2.5 |
for (x = 0; x < xmax; x++) |
410 |
|
|
scanline[x][GRN] = normbright(scanline[x]); |
411 |
greg |
2.1 |
colrs_gambs(scanline, xmax); |
412 |
|
|
if (maxcolors < 256) |
413 |
greg |
2.3 |
for (x = 0; x < xmax; x++) { |
414 |
greg |
2.5 |
thiscolor = ((long)scanline[x][GRN] * |
415 |
|
|
maxcolors + maxcolors/2) / 256; |
416 |
greg |
2.1 |
if (thiscolor != lastcolor) |
417 |
|
|
_setcolor((lastcolor=thiscolor)+minpix); |
418 |
|
|
_setpixel(x, y); |
419 |
|
|
} |
420 |
|
|
else |
421 |
|
|
for (x = 0; x < xmax; x++) { |
422 |
greg |
2.5 |
thiscolor = scanline[x][GRN]; |
423 |
greg |
2.1 |
if (thiscolor != lastcolor) |
424 |
|
|
_setcolor((lastcolor=thiscolor)+minpix); |
425 |
|
|
_setpixel(x, y); |
426 |
|
|
} |
427 |
|
|
} |
428 |
|
|
} |
429 |
|
|
|
430 |
|
|
|
431 |
greg |
2.3 |
mappedimage() /* display color-mapped image */ |
432 |
greg |
2.1 |
{ |
433 |
greg |
2.3 |
BYTE bscan[MAXWIDTH]; |
434 |
|
|
int y; |
435 |
|
|
register int x; |
436 |
greg |
2.1 |
/* set gamma correction */ |
437 |
|
|
setcolrgam(gamcor); |
438 |
|
|
/* make histogram */ |
439 |
greg |
2.4 |
_outtext("Quantizing image -- Please wait..."); |
440 |
greg |
2.1 |
new_histo(); |
441 |
|
|
for (y = 0; y < ymax; y++) { |
442 |
|
|
if (getscan(y) < 0) |
443 |
|
|
quiterr("seek error in getmapped"); |
444 |
|
|
if (scale) |
445 |
|
|
shiftcolrs(scanline, xmax, scale); |
446 |
|
|
colrs_gambs(scanline, xmax); |
447 |
|
|
cnt_colrs(scanline, xmax); |
448 |
|
|
} |
449 |
|
|
/* map pixels */ |
450 |
|
|
if (!new_clrtab(maxcolors)) |
451 |
|
|
quiterr("cannot create color map"); |
452 |
|
|
setpalette(); |
453 |
|
|
_setplotaction(_GPSET); |
454 |
|
|
/* display image */ |
455 |
|
|
for (y = 0; y < ymax; y++) { |
456 |
|
|
if (getscan(y) < 0) |
457 |
|
|
quiterr("seek error in getmapped"); |
458 |
|
|
if (scale) |
459 |
|
|
shiftcolrs(scanline, xmax, scale); |
460 |
|
|
colrs_gambs(scanline, xmax); |
461 |
|
|
if (dither) |
462 |
|
|
dith_colrs(bscan, scanline, xmax); |
463 |
|
|
else |
464 |
|
|
map_colrs(bscan, scanline, xmax); |
465 |
|
|
for (x = 0; x < xmax; x++) { |
466 |
|
|
if (x==0 || bscan[x] != bscan[x-1]) |
467 |
|
|
_setcolor(bscan[x]+minpix); |
468 |
|
|
_setpixel(x, y); |
469 |
|
|
} |
470 |
|
|
} |
471 |
|
|
} |
472 |
|
|
|
473 |
|
|
|
474 |
|
|
getscan(y) |
475 |
|
|
int y; |
476 |
|
|
{ |
477 |
|
|
if (y != cury) { |
478 |
|
|
if (scanpos[y] == -1) |
479 |
|
|
return(-1); |
480 |
|
|
if (fseek(fin, scanpos[y], 0) == -1) |
481 |
|
|
quiterr("fseek error"); |
482 |
|
|
cury = y; |
483 |
greg |
2.5 |
} else if (fin != stdin && scanpos[y] == -1) |
484 |
greg |
2.1 |
scanpos[y] = ftell(fin); |
485 |
|
|
|
486 |
|
|
if (freadcolrs(scanline, xmax, fin) < 0) |
487 |
|
|
quiterr("picture read error"); |
488 |
|
|
|
489 |
|
|
cury++; |
490 |
|
|
return(0); |
491 |
|
|
} |
492 |
|
|
|
493 |
|
|
|
494 |
|
|
/* |
495 |
|
|
* Microsoft Mouse handling routines |
496 |
|
|
*/ |
497 |
|
|
|
498 |
|
|
|
499 |
|
|
#pragma off (check_stack) |
500 |
|
|
void _loadds far mouse_handler (int max, int mcx, int mdx) |
501 |
|
|
{ |
502 |
|
|
#pragma aux mouse_handler parm [EAX] [ECX] [EDX] |
503 |
|
|
mouse_event = max; |
504 |
|
|
mouse_xpos = mcx; |
505 |
greg |
2.3 |
mouse_ypos = mdx; |
506 |
greg |
2.1 |
} |
507 |
|
|
#pragma on (check_stack) |
508 |
|
|
|
509 |
|
|
|
510 |
|
|
void |
511 |
greg |
2.3 |
move_cursor(newx, newy) /* move cursor to new position */ |
512 |
greg |
2.1 |
int newx, newy; |
513 |
|
|
{ |
514 |
|
|
static char *imp = NULL; |
515 |
|
|
static int curx = -1, cury = -1; |
516 |
greg |
2.3 |
#define xcmin (curx-crad<0 ? 0 : curx-crad) |
517 |
|
|
#define ycmin (cury-crad<0 ? 0 : cury-crad) |
518 |
|
|
#define xcmax (curx+crad>=xmax ? xmax-1 : curx+crad) |
519 |
|
|
#define ycmax (cury+crad>=ymax ? ymax-1 : cury+crad) |
520 |
greg |
2.1 |
|
521 |
|
|
if (newx == curx & newy == cury) |
522 |
|
|
return; |
523 |
greg |
2.3 |
if (imp == NULL && |
524 |
greg |
2.1 |
(imp = bmalloc(_imagesize(0,0,2*crad+1,2*crad+1))) == NULL) { |
525 |
|
|
quiterr("out of memory in move_cursor"); |
526 |
|
|
} |
527 |
greg |
2.3 |
if (curx >= 0 & cury >= 0) /* clear old cursor */ |
528 |
greg |
2.1 |
_putimage(xcmin, ycmin, imp, _GPSET); |
529 |
|
|
/* record new position */ |
530 |
|
|
curx = newx; cury = newy; |
531 |
|
|
if (curx < 0 | cury < 0) |
532 |
greg |
2.3 |
return; /* no cursor */ |
533 |
greg |
2.1 |
/* save under new cursor */ |
534 |
|
|
_getimage(xcmin, ycmin, xcmax, ycmax, imp); |
535 |
|
|
/* draw new cursor */ |
536 |
|
|
_setplotaction(_GPSET); |
537 |
|
|
_setcolor(ourwhite); |
538 |
|
|
_rectangle(_GFILLINTERIOR, xcmin, cury-1, xcmax, cury+1); |
539 |
|
|
_rectangle(_GFILLINTERIOR, curx-1, ycmin, curx+1, ycmax); |
540 |
|
|
_setcolor(ourblack); |
541 |
|
|
_moveto(xcmin+1, cury); |
542 |
|
|
_lineto(xcmax-1, cury); |
543 |
|
|
_moveto(curx, ycmin+1); |
544 |
|
|
_lineto(curx, ycmax-1); |
545 |
|
|
#undef xcmin |
546 |
|
|
#undef ycmin |
547 |
|
|
#undef xcmax |
548 |
|
|
#undef ycmax |
549 |
|
|
} |
550 |
|
|
|
551 |
|
|
|
552 |
|
|
int |
553 |
|
|
ms_init() |
554 |
|
|
{ |
555 |
|
|
struct SREGS sregs; |
556 |
|
|
union REGS inregs, outregs; |
557 |
|
|
int far *ptr; |
558 |
|
|
int (far *function_ptr)(); |
559 |
|
|
|
560 |
|
|
segread(&sregs); |
561 |
|
|
|
562 |
|
|
/* check for mouse driver */ |
563 |
|
|
|
564 |
|
|
inregs.w.ax = 0; |
565 |
|
|
int386 (0x33, &inregs, &outregs); |
566 |
|
|
if( outregs.w.ax != -1 ) { |
567 |
|
|
return(0); |
568 |
|
|
} |
569 |
|
|
|
570 |
|
|
crad = ymax/40; |
571 |
greg |
2.3 |
|
572 |
|
|
/* set screen limits */ |
573 |
|
|
|
574 |
|
|
inregs.w.ax = 0x7; /* horizontal resolution */ |
575 |
|
|
inregs.w.cx = 0; |
576 |
|
|
inregs.w.dx = xmax-1; |
577 |
|
|
int386x( 0x33, &inregs, &outregs, &sregs ); |
578 |
|
|
inregs.w.ax = 0x8; /* vertical resolution */ |
579 |
|
|
inregs.w.cx = 0; |
580 |
|
|
inregs.w.dx = ymax-1; |
581 |
|
|
int386x( 0x33, &inregs, &outregs, &sregs ); |
582 |
|
|
|
583 |
greg |
2.1 |
/* install watcher */ |
584 |
|
|
|
585 |
|
|
inregs.w.ax = 0xC; |
586 |
|
|
inregs.w.cx = M_LDOWN | M_LUP | M_MOTION; |
587 |
|
|
function_ptr = mouse_handler; |
588 |
|
|
inregs.x.edx = FP_OFF( function_ptr ); |
589 |
greg |
2.3 |
sregs.es = FP_SEG( function_ptr ); |
590 |
greg |
2.1 |
int386x( 0x33, &inregs, &outregs, &sregs ); |
591 |
greg |
2.3 |
|
592 |
greg |
2.1 |
return(1); |
593 |
|
|
} |
594 |
greg |
2.4 |
|
595 |
|
|
ms_done() |
596 |
|
|
{ |
597 |
|
|
union REGS inregs, outregs; |
598 |
|
|
|
599 |
|
|
/* uninstall watcher */ |
600 |
|
|
|
601 |
|
|
inregs.w.ax = 0; |
602 |
|
|
int386 (0x33, &inregs, &outregs); |
603 |
|
|
} |