OSDN Git Service

9c1e102f8643a61b0315d97520cca0c30523fbb3
[proj16/16.git] / src / lib / hb / wl_scale.c
1 // WL_SCALE.C\r
2 \r
3 #include "WL_DEF.H"\r
4 #pragma hdrstop\r
5 \r
6 #define OP_RETF 0xcb\r
7 \r
8 /*\r
9 =============================================================================\r
10 \r
11                                                   GLOBALS\r
12 \r
13 =============================================================================\r
14 */\r
15 \r
16 t_compscale _seg *scaledirectory[MAXSCALEHEIGHT+1];\r
17 long                    fullscalefarcall[MAXSCALEHEIGHT+1];\r
18 \r
19 int                     maxscale,maxscaleshl2;\r
20 \r
21 boolean insetupscaling;\r
22 \r
23 /*\r
24 =============================================================================\r
25 \r
26                                                   LOCALS\r
27 \r
28 =============================================================================\r
29 */\r
30 \r
31 t_compscale     _seg *work;\r
32 unsigned BuildCompScale (int height, memptr *finalspot);\r
33 \r
34 int                     stepbytwo;\r
35 \r
36 //===========================================================================\r
37 \r
38 /*\r
39 ==============\r
40 =\r
41 = BadScale\r
42 =\r
43 ==============\r
44 */\r
45 \r
46 void far BadScale (void)\r
47 {\r
48         Quit ("BadScale called!");\r
49 }\r
50 \r
51 \r
52 /*\r
53 ==========================\r
54 =\r
55 = SetupScaling\r
56 =\r
57 ==========================\r
58 */\r
59 \r
60 void SetupScaling (int maxscaleheight)\r
61 {\r
62         int             i,x,y;\r
63         byte    far *dest;\r
64 \r
65         insetupscaling = true;\r
66 \r
67         maxscaleheight/=2;                      // one scaler every two pixels\r
68 \r
69         maxscale = maxscaleheight-1;\r
70         maxscaleshl2 = maxscale<<2;\r
71 \r
72 //\r
73 // free up old scalers\r
74 //\r
75         for (i=1;i<MAXSCALEHEIGHT;i++)\r
76         {\r
77                 if (scaledirectory[i])\r
78                         MM_FreePtr (&(memptr)scaledirectory[i]);\r
79                 if (i>=stepbytwo)\r
80                         i += 2;\r
81         }\r
82         memset (scaledirectory,0,sizeof(scaledirectory));\r
83 \r
84         MM_SortMem ();\r
85 \r
86 //\r
87 // build the compiled scalers\r
88 //\r
89         stepbytwo = viewheight/2;       // save space by double stepping\r
90         MM_GetPtr (&(memptr)work,20000);\r
91 \r
92         for (i=1;i<=maxscaleheight;i++)\r
93         {\r
94                 BuildCompScale (i*2,&(memptr)scaledirectory[i]);\r
95                 if (i>=stepbytwo)\r
96                         i+= 2;\r
97         }\r
98         MM_FreePtr (&(memptr)work);\r
99 \r
100 //\r
101 // compact memory and lock down scalers\r
102 //\r
103         MM_SortMem ();\r
104         for (i=1;i<=maxscaleheight;i++)\r
105         {\r
106                 MM_SetLock (&(memptr)scaledirectory[i],true);\r
107                 fullscalefarcall[i] = (unsigned)scaledirectory[i];\r
108                 fullscalefarcall[i] <<=16;\r
109                 fullscalefarcall[i] += scaledirectory[i]->codeofs[0];\r
110                 if (i>=stepbytwo)\r
111                 {\r
112                         scaledirectory[i+1] = scaledirectory[i];\r
113                         fullscalefarcall[i+1] = fullscalefarcall[i];\r
114                         scaledirectory[i+2] = scaledirectory[i];\r
115                         fullscalefarcall[i+2] = fullscalefarcall[i];\r
116                         i+=2;\r
117                 }\r
118         }\r
119         scaledirectory[0] = scaledirectory[1];\r
120         fullscalefarcall[0] = fullscalefarcall[1];\r
121 \r
122 //\r
123 // check for oversize wall drawing\r
124 //\r
125         for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)\r
126                 fullscalefarcall[i] = (long)BadScale;\r
127 \r
128         insetupscaling = false;\r
129 }\r
130 \r
131 //===========================================================================\r
132 \r
133 /*\r
134 ========================\r
135 =\r
136 = BuildCompScale\r
137 =\r
138 = Builds a compiled scaler object that will scale a 64 tall object to\r
139 = the given height (centered vertically on the screen)\r
140 =\r
141 = height should be even\r
142 =\r
143 = Call with\r
144 = ---------\r
145 = DS:SI         Source for scale\r
146 = ES:DI         Dest for scale\r
147 =\r
148 = Calling the compiled scaler only destroys AL\r
149 =\r
150 ========================\r
151 */\r
152 \r
153 unsigned BuildCompScale (int height, memptr *finalspot)\r
154 {\r
155         byte            far *code;\r
156 \r
157         int                     i;\r
158         long            fix,step;\r
159         unsigned        src,totalscaled,totalsize;\r
160         int                     startpix,endpix,toppix;\r
161 \r
162 \r
163         step = ((long)height<<16) / 64;\r
164         code = &work->code[0];\r
165         toppix = (viewheight-height)/2;\r
166         fix = 0;\r
167 \r
168         for (src=0;src<=64;src++)\r
169         {\r
170                 startpix = fix>>16;\r
171                 fix += step;\r
172                 endpix = fix>>16;\r
173 \r
174                 if (endpix>startpix)\r
175                         work->width[src] = endpix-startpix;\r
176                 else\r
177                         work->width[src] = 0;\r
178 \r
179 //\r
180 // mark the start of the code\r
181 //\r
182                 work->codeofs[src] = FP_OFF(code);\r
183 \r
184 //\r
185 // compile some code if the source pixel generates any screen pixels\r
186 //\r
187                 startpix+=toppix;\r
188                 endpix+=toppix;\r
189 \r
190                 if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)\r
191                         continue;\r
192 \r
193         //\r
194         // mov al,[si+src]\r
195         //\r
196                 *code++ = 0x8a;\r
197                 *code++ = 0x44;\r
198                 *code++ = src;\r
199 \r
200                 for (;startpix<endpix;startpix++)\r
201                 {\r
202                         if (startpix >= viewheight)\r
203                                 break;                                          // off the bottom of the view area\r
204                         if (startpix < 0)\r
205                                 continue;                                       // not into the view area\r
206 \r
207                 //\r
208                 // mov [es:di+heightofs],al\r
209                 //\r
210                         *code++ = 0x26;\r
211                         *code++ = 0x88;\r
212                         *code++ = 0x85;\r
213                         *((unsigned far *)code)++ = startpix*SCREENBWIDE;\r
214                 }\r
215 \r
216         }\r
217 \r
218 //\r
219 // retf\r
220 //\r
221         *code++ = 0xcb;\r
222 \r
223         totalsize = FP_OFF(code);\r
224         MM_GetPtr (finalspot,totalsize);\r
225         _fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);\r
226 \r
227         return totalsize;\r
228 }\r
229 \r
230 \r
231 /*\r
232 =======================\r
233 =\r
234 = ScaleLine\r
235 =\r
236 = linescale should have the high word set to the segment of the scaler\r
237 =\r
238 =======================\r
239 */\r
240 \r
241 extern  int                     slinex,slinewidth;\r
242 extern  unsigned        far *linecmds;\r
243 extern  long            linescale;\r
244 extern  unsigned        maskword;\r
245 \r
246 byte    mask1,mask2,mask3;\r
247 \r
248 \r
249 void near ScaleLine (void)\r
250 {\r
251 asm     mov     cx,WORD PTR [linescale+2]\r
252 asm     mov     es,cx                                           // segment of scaler\r
253 \r
254 asm     mov bp,WORD PTR [linecmds]\r
255 asm     mov     dx,SC_INDEX+1                           // to set SC_MAPMASK\r
256 \r
257 asm     mov     bx,[slinex]\r
258 asm     mov     di,bx\r
259 asm     shr     di,1                                            // X in bytes\r
260 asm     shr     di,1\r
261 asm     add     di,[bufferofs]\r
262 asm     and     bx,3\r
263 /* begin 8086 hack\r
264 asm     shl     bx,3\r
265 */\r
266 asm push cx\r
267 asm mov cl,3\r
268 asm shl bx,cl\r
269 asm pop cx\r
270 /* end 8086 hack */\r
271 asm     add     bx,[slinewidth]                         // bx = (pixel*8+pixwidth)\r
272 asm     mov     al,BYTE [mapmasks3-1+bx]        // -1 because pixwidth of 1 is first\r
273 asm     mov     ds,WORD PTR [linecmds+2]\r
274 asm     or      al,al\r
275 asm     jz      notthreebyte                            // scale across three bytes\r
276 asm     jmp     threebyte\r
277 notthreebyte:\r
278 asm     mov     al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first\r
279 asm     or      al,al\r
280 asm     jnz     twobyte                                         // scale across two bytes\r
281 \r
282 //\r
283 // one byte scaling\r
284 //\r
285 asm     mov     al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first\r
286 asm     out     dx,al                                           // set map mask register\r
287 \r
288 scalesingle:\r
289 \r
290 asm     mov     bx,[ds:bp]                                      // table location of rtl to patch\r
291 asm     or      bx,bx\r
292 asm     jz      linedone                                        // 0 signals end of segment list\r
293 asm     mov     bx,[es:bx]\r
294 asm     mov     dl,[es:bx]                                      // save old value\r
295 asm     mov     BYTE PTR es:[bx],OP_RETF        // patch a RETF in\r
296 asm     mov     si,[ds:bp+4]                            // table location of entry spot\r
297 asm     mov     ax,[es:si]\r
298 asm     mov     WORD PTR ss:[linescale],ax      // call here to start scaling\r
299 asm     mov     si,[ds:bp+2]                            // corrected top of shape for this segment\r
300 asm     add     bp,6                                            // next segment list\r
301 \r
302 asm     mov     ax,SCREENSEG\r
303 asm     mov     es,ax\r
304 asm     call ss:[linescale]                             // scale the segment of pixels\r
305 \r
306 asm     mov     es,cx                                           // segment of scaler\r
307 asm     mov     BYTE PTR es:[bx],dl                     // unpatch the RETF\r
308 asm     jmp     scalesingle                                     // do the next segment\r
309 \r
310 \r
311 //\r
312 // done\r
313 //\r
314 linedone:\r
315 asm     mov     ax,ss\r
316 asm     mov     ds,ax\r
317 return;\r
318 \r
319 //\r
320 // two byte scaling\r
321 //\r
322 twobyte:\r
323 asm     mov     ss:[mask2],al\r
324 asm     mov     al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first\r
325 asm     mov     ss:[mask1],al\r
326 \r
327 scaledouble:\r
328 \r
329 asm     mov     bx,[ds:bp]                                      // table location of rtl to patch\r
330 asm     or      bx,bx\r
331 asm     jz      linedone                                        // 0 signals end of segment list\r
332 asm     mov     bx,[es:bx]\r
333 asm     mov     cl,[es:bx]                                      // save old value\r
334 asm     mov     BYTE PTR es:[bx],OP_RETF        // patch a RETF in\r
335 asm     mov     si,[ds:bp+4]                            // table location of entry spot\r
336 asm     mov     ax,[es:si]\r
337 asm     mov     WORD PTR ss:[linescale],ax      // call here to start scaling\r
338 asm     mov     si,[ds:bp+2]                            // corrected top of shape for this segment\r
339 asm     add     bp,6                                            // next segment list\r
340 \r
341 asm     mov     ax,SCREENSEG\r
342 asm     mov     es,ax\r
343 asm     mov     al,ss:[mask1]\r
344 asm     out     dx,al                                           // set map mask register\r
345 asm     call ss:[linescale]                             // scale the segment of pixels\r
346 asm     inc     di\r
347 asm     mov     al,ss:[mask2]\r
348 asm     out     dx,al                                           // set map mask register\r
349 asm     call ss:[linescale]                             // scale the segment of pixels\r
350 asm     dec     di\r
351 \r
352 asm     mov     es,WORD PTR ss:[linescale+2] // segment of scaler\r
353 asm     mov     BYTE PTR es:[bx],cl                     // unpatch the RETF\r
354 asm     jmp     scaledouble                                     // do the next segment\r
355 \r
356 \r
357 //\r
358 // three byte scaling\r
359 //\r
360 threebyte:\r
361 asm     mov     ss:[mask3],al\r
362 asm     mov     al,BYTE PTR ss:[mapmasks2-1+bx] // -1 because pixwidth of 1 is first\r
363 asm     mov     ss:[mask2],al\r
364 asm     mov     al,BYTE PTR ss:[mapmasks1-1+bx] // -1 because pixwidth of 1 is first\r
365 asm     mov     ss:[mask1],al\r
366 \r
367 scaletriple:\r
368 \r
369 asm     mov     bx,[ds:bp]                                      // table location of rtl to patch\r
370 asm     or      bx,bx\r
371 asm     jz      linedone                                        // 0 signals end of segment list\r
372 asm     mov     bx,[es:bx]\r
373 asm     mov     cl,[es:bx]                                      // save old value\r
374 asm     mov     BYTE PTR es:[bx],OP_RETF        // patch a RETF in\r
375 asm     mov     si,[ds:bp+4]                            // table location of entry spot\r
376 asm     mov     ax,[es:si]\r
377 asm     mov     WORD PTR ss:[linescale],ax      // call here to start scaling\r
378 asm     mov     si,[ds:bp+2]                            // corrected top of shape for this segment\r
379 asm     add     bp,6                                            // next segment list\r
380 \r
381 asm     mov     ax,SCREENSEG\r
382 asm     mov     es,ax\r
383 asm     mov     al,ss:[mask1]\r
384 asm     out     dx,al                                           // set map mask register\r
385 asm     call ss:[linescale]                             // scale the segment of pixels\r
386 asm     inc     di\r
387 asm     mov     al,ss:[mask2]\r
388 asm     out     dx,al                                           // set map mask register\r
389 asm     call ss:[linescale]                             // scale the segment of pixels\r
390 asm     inc     di\r
391 asm     mov     al,ss:[mask3]\r
392 asm     out     dx,al                                           // set map mask register\r
393 asm     call ss:[linescale]                             // scale the segment of pixels\r
394 asm     dec     di\r
395 asm     dec     di\r
396 \r
397 asm     mov     es,WORD PTR ss:[linescale+2] // segment of scaler\r
398 asm     mov     BYTE PTR es:[bx],cl                     // unpatch the RETF\r
399 asm     jmp     scaletriple                                     // do the next segment\r
400 \r
401 \r
402 }\r
403 \r
404 \r
405 /*\r
406 =======================\r
407 =\r
408 = ScaleShape\r
409 =\r
410 = Draws a compiled shape at [scale] pixels high\r
411 =\r
412 = each vertical line of the shape has a pointer to segment data:\r
413 =       end of segment pixel*2 (0 terminates line) used to patch rtl in scaler\r
414 =       top of virtual line with segment in proper place\r
415 =       start of segment pixel*2, used to jsl into compiled scaler\r
416 =       <repeat>\r
417 =\r
418 = Setup for call\r
419 = --------------\r
420 = GC_MODE                       read mode 1, write mode 2\r
421 = GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff\r
422 = GC_INDEX                      pointing at GC_BITMASK\r
423 =\r
424 =======================\r
425 */\r
426 \r
427 static  long            longtemp;\r
428 \r
429 void ScaleShape (int xcenter, int shapenum, unsigned height)\r
430 {\r
431         t_compshape     _seg *shape;\r
432         t_compscale _seg *comptable;\r
433         unsigned        scale,srcx,stopx,tempx;\r
434         int                     t;\r
435         unsigned        far *cmdptr;\r
436         boolean         leftvis,rightvis;\r
437 \r
438 \r
439         shape = PM_GetSpritePage (shapenum);\r
440 \r
441         scale = height>>3;                                              // low three bits are fractional\r
442         if (!scale || scale>maxscale)\r
443                 return;                                                         // too close or far away\r
444         comptable = scaledirectory[scale];\r
445 \r
446         *(((unsigned *)&linescale)+1)=(unsigned)comptable;      // seg of far call\r
447         *(((unsigned *)&linecmds)+1)=(unsigned)shape;           // seg of shape\r
448 \r
449 //\r
450 // scale to the left (from pixel 31 to shape->leftpix)\r
451 //\r
452         srcx = 32;\r
453         slinex = xcenter;\r
454         stopx = shape->leftpix;\r
455         cmdptr = &shape->dataofs[31-stopx];\r
456 \r
457         while ( --srcx >=stopx && slinex>0)\r
458         {\r
459                 (unsigned)linecmds = *cmdptr--;\r
460                 if ( !(slinewidth = comptable->width[srcx]) )\r
461                         continue;\r
462 \r
463                 if (slinewidth == 1)\r
464                 {\r
465                         slinex--;\r
466                         if (slinex<viewwidth)\r
467                         {\r
468                                 if (wallheight[slinex] >= height)\r
469                                         continue;               // obscured by closer wall\r
470                                 ScaleLine ();\r
471                         }\r
472                         continue;\r
473                 }\r
474 \r
475                 //\r
476                 // handle multi pixel lines\r
477                 //\r
478                 if (slinex>viewwidth)\r
479                 {\r
480                         slinex -= slinewidth;\r
481                         slinewidth = viewwidth-slinex;\r
482                         if (slinewidth<1)\r
483                                 continue;               // still off the right side\r
484                 }\r
485                 else\r
486                 {\r
487                         if (slinewidth>slinex)\r
488                                 slinewidth = slinex;\r
489                         slinex -= slinewidth;\r
490                 }\r
491 \r
492 \r
493                 leftvis = (wallheight[slinex] < height);\r
494                 rightvis = (wallheight[slinex+slinewidth-1] < height);\r
495 \r
496                 if (leftvis)\r
497                 {\r
498                         if (rightvis)\r
499                                 ScaleLine ();\r
500                         else\r
501                         {\r
502                                 while (wallheight[slinex+slinewidth-1] >= height)\r
503                                         slinewidth--;\r
504                                 ScaleLine ();\r
505                         }\r
506                 }\r
507                 else\r
508                 {\r
509                         if (!rightvis)\r
510                                 continue;               // totally obscured\r
511 \r
512                         while (wallheight[slinex] >= height)\r
513                         {\r
514                                 slinex++;\r
515                                 slinewidth--;\r
516                         }\r
517                         ScaleLine ();\r
518                         break;                  // the rest of the shape is gone\r
519                 }\r
520         }\r
521 \r
522 \r
523 //\r
524 // scale to the right\r
525 //\r
526         slinex = xcenter;\r
527         stopx = shape->rightpix;\r
528         if (shape->leftpix<31)\r
529         {\r
530                 srcx = 31;\r
531                 cmdptr = &shape->dataofs[32-shape->leftpix];\r
532         }\r
533         else\r
534         {\r
535                 srcx = shape->leftpix-1;\r
536                 cmdptr = &shape->dataofs[0];\r
537         }\r
538         slinewidth = 0;\r
539 \r
540         while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)\r
541         {\r
542                 (unsigned)linecmds = *cmdptr++;\r
543                 if ( !(slinewidth = comptable->width[srcx]) )\r
544                         continue;\r
545 \r
546                 if (slinewidth == 1)\r
547                 {\r
548                         if (slinex>=0 && wallheight[slinex] < height)\r
549                         {\r
550                                 ScaleLine ();\r
551                         }\r
552                         continue;\r
553                 }\r
554 \r
555                 //\r
556                 // handle multi pixel lines\r
557                 //\r
558                 if (slinex<0)\r
559                 {\r
560                         if (slinewidth <= -slinex)\r
561                                 continue;               // still off the left edge\r
562 \r
563                         slinewidth += slinex;\r
564                         slinex = 0;\r
565                 }\r
566                 else\r
567                 {\r
568                         if (slinex + slinewidth > viewwidth)\r
569                                 slinewidth = viewwidth-slinex;\r
570                 }\r
571 \r
572 \r
573                 leftvis = (wallheight[slinex] < height);\r
574                 rightvis = (wallheight[slinex+slinewidth-1] < height);\r
575 \r
576                 if (leftvis)\r
577                 {\r
578                         if (rightvis)\r
579                         {\r
580                                 ScaleLine ();\r
581                         }\r
582                         else\r
583                         {\r
584                                 while (wallheight[slinex+slinewidth-1] >= height)\r
585                                         slinewidth--;\r
586                                 ScaleLine ();\r
587                                 break;                  // the rest of the shape is gone\r
588                         }\r
589                 }\r
590                 else\r
591                 {\r
592                         if (rightvis)\r
593                         {\r
594                                 while (wallheight[slinex] >= height)\r
595                                 {\r
596                                         slinex++;\r
597                                         slinewidth--;\r
598                                 }\r
599                                 ScaleLine ();\r
600                         }\r
601                         else\r
602                                 continue;               // totally obscured\r
603                 }\r
604         }\r
605 }\r
606 \r
607 \r
608 \r
609 /*\r
610 =======================\r
611 =\r
612 = SimpleScaleShape\r
613 =\r
614 = NO CLIPPING, height in pixels\r
615 =\r
616 = Draws a compiled shape at [scale] pixels high\r
617 =\r
618 = each vertical line of the shape has a pointer to segment data:\r
619 =       end of segment pixel*2 (0 terminates line) used to patch rtl in scaler\r
620 =       top of virtual line with segment in proper place\r
621 =       start of segment pixel*2, used to jsl into compiled scaler\r
622 =       <repeat>\r
623 =\r
624 = Setup for call\r
625 = --------------\r
626 = GC_MODE                       read mode 1, write mode 2\r
627 = GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff\r
628 = GC_INDEX                      pointing at GC_BITMASK\r
629 =\r
630 =======================\r
631 */\r
632 \r
633 void SimpleScaleShape (int xcenter, int shapenum, unsigned height)\r
634 {\r
635         t_compshape     _seg *shape;\r
636         t_compscale _seg *comptable;\r
637         unsigned        scale,srcx,stopx,tempx;\r
638         int                     t;\r
639         unsigned        far *cmdptr;\r
640         boolean         leftvis,rightvis;\r
641 \r
642 \r
643         shape = PM_GetSpritePage (shapenum);\r
644 \r
645         scale = height>>1;\r
646         comptable = scaledirectory[scale];\r
647 \r
648         *(((unsigned *)&linescale)+1)=(unsigned)comptable;      // seg of far call\r
649         *(((unsigned *)&linecmds)+1)=(unsigned)shape;           // seg of shape\r
650 \r
651 //\r
652 // scale to the left (from pixel 31 to shape->leftpix)\r
653 //\r
654         srcx = 32;\r
655         slinex = xcenter;\r
656         stopx = shape->leftpix;\r
657         cmdptr = &shape->dataofs[31-stopx];\r
658 \r
659         while ( --srcx >=stopx )\r
660         {\r
661                 (unsigned)linecmds = *cmdptr--;\r
662                 if ( !(slinewidth = comptable->width[srcx]) )\r
663                         continue;\r
664 \r
665                 slinex -= slinewidth;\r
666                 ScaleLine ();\r
667         }\r
668 \r
669 \r
670 //\r
671 // scale to the right\r
672 //\r
673         slinex = xcenter;\r
674         stopx = shape->rightpix;\r
675         if (shape->leftpix<31)\r
676         {\r
677                 srcx = 31;\r
678                 cmdptr = &shape->dataofs[32-shape->leftpix];\r
679         }\r
680         else\r
681         {\r
682                 srcx = shape->leftpix-1;\r
683                 cmdptr = &shape->dataofs[0];\r
684         }\r
685         slinewidth = 0;\r
686 \r
687         while ( ++srcx <= stopx )\r
688         {\r
689                 (unsigned)linecmds = *cmdptr++;\r
690                 if ( !(slinewidth = comptable->width[srcx]) )\r
691                         continue;\r
692 \r
693                 ScaleLine ();\r
694                 slinex+=slinewidth;\r
695         }\r
696 }\r
697 \r
698 \r
699 \r
700 \r
701 //\r
702 // bit mask tables for drawing scaled strips up to eight pixels wide\r
703 //\r
704 // down here so the STUPID inline assembler doesn't get confused!\r
705 //\r
706 \r
707 \r
708 byte    mapmasks1[4][8] = {\r
709 {1 ,3 ,7 ,15,15,15,15,15},\r
710 {2 ,6 ,14,14,14,14,14,14},\r
711 {4 ,12,12,12,12,12,12,12},\r
712 {8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };\r
713 \r
714 byte    mapmasks2[4][8] = {\r
715 {0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},\r
716 {0 ,0 ,0 ,1 ,3 ,7 ,15,15},\r
717 {0 ,0 ,1 ,3 ,7 ,15,15,15},\r
718 {0 ,1 ,3 ,7 ,15,15,15,15} };\r
719 \r
720 byte    mapmasks3[4][8] = {\r
721 {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},\r
722 {0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},\r
723 {0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},\r
724 {0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };\r
725 \r
726 \r
727 unsigned        wordmasks[8][8] = {\r
728 {0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},\r
729 {0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},\r
730 {0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},\r
731 {0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},\r
732 {0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},\r
733 {0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},\r
734 {0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},\r
735 {0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };\r
736 \r
737 int                     slinex,slinewidth;\r
738 unsigned        far *linecmds;\r
739 long            linescale;\r
740 unsigned        maskword;\r
741 \r