OSDN Git Service

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