1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 #include "rt_def.h"
21 #include "watcom.h"
22 #include <stdio.h>
23 #include <string.h>
24 
25 #ifdef DOS
26 #include <malloc.h>
27 #include <dos.h>
28 #include <conio.h>
29 #endif
30 
31 #include "modexlib.h"
32 #include "rt_util.h"
33 #include "rt_draw.h"
34 #include "rt_scale.h"
35 #include "_rt_scal.h"
36 #include "rt_sc_a.h"
37 #include "engine.h"
38 #include "w_wad.h"
39 #include "z_zone.h"
40 #include "lumpy.h"
41 #include "rt_main.h"
42 #include "rt_ted.h"
43 #include "rt_vid.h"
44 #include "rt_view.h"
45 #include "rt_playr.h"
46 //MED
47 #include "memcheck.h"
48 
49 /*
50 =============================================================================
51 
52                                GLOBALS
53 
54 =============================================================================
55 */
56 
57 // Draw Column vars
58 
59 int dc_texturemid;
60 int dc_iscale;
61 int dc_invscale;
62 int sprtopoffset;
63 int dc_yl;
64 int dc_yh;
65 //byte * dc_firstsource;
66 byte * dc_source;
67 int centeryclipped;
68 int transparentlevel=0;
69 
70 /*
71 ==========================
72 =
73 = SetPlayerLightLevel
74 =
75 ==========================
76 */
77 
SetPlayerLightLevel(void)78 void SetPlayerLightLevel (void)
79 {
80    int i;
81    int lv;
82    int intercept;
83    int height;
84 
85    whereami=23;
86 	if (MISCVARS->GASON==1)
87       {
88 		shadingtable=greenmap+(MISCVARS->gasindex<<8);
89       return;
90       }
91 
92    if (fulllight || fog)
93       {
94       shadingtable=colormap+(1<<12);
95       return;
96       }
97 
98    height=PLAYERHEIGHT;
99 
100 	if (player->angle < FINEANGLES/8 || player->angle > 7*FINEANGLES/8)
101       intercept=(player->x>>11)&0x1c;
102 	else if (player->angle < 3*FINEANGLES/8)
103       intercept=(player->y>>11)&0x1c;
104 	else if (player->angle < 5*FINEANGLES/8)
105       intercept=(player->x>>11)&0x1c;
106 	else
107       intercept=(player->y>>11)&0x1c;
108 
109    if (lightsource)
110       {
111       lv=(((LightSourceAt(player->x>>16,player->y>>16)>>intercept)&0xf)>>1);
112       i=maxshade-(height>>normalshade)-lv;
113       if (i<minshade) i=minshade;
114       shadingtable=colormap+(i<<8);
115       }
116    else
117       {
118       i=maxshade-(height>>normalshade);
119       if (i<minshade) i=minshade;
120       shadingtable=colormap+(i<<8);
121       }
122 }
123 
124 
125 
126 /*
127 ==========================
128 =
129 = SetLightLevel
130 =
131 ==========================
132 */
133 
SetLightLevel(int height)134 void SetLightLevel (int height)
135 {
136    int i;
137 
138    whereami=24;
139 	if (MISCVARS->GASON==1)
140 		{
141 		shadingtable=greenmap+(MISCVARS->gasindex<<8);
142       return;
143       }
144 
145    if (fulllight)
146       {
147       shadingtable=colormap+(1<<12);
148       return;
149       }
150    if (fog)
151       {
152       i=(height>>normalshade)+minshade;
153       if (i>maxshade) i=maxshade;
154       shadingtable=colormap+(i<<8);
155       }
156    else
157       {
158       i=maxshade-(height>>normalshade);
159       if (i<minshade) i=minshade;
160       shadingtable=colormap+(i<<8);
161       }
162 }
163 
164 /*
165 ==========================
166 =
167 = ScaleTransparentPost
168 =
169 ==========================
170 */
ScaleTransparentPost(byte * src,byte * buf,int level)171 void ScaleTransparentPost (byte * src, byte * buf, int level)
172 {
173    int  offset;
174    int  length;
175    int  topscreen;
176    int  bottomscreen;
177    byte * oldlevel;
178    byte * seelevel;
179 #if (DEVELOPMENT == 1)
180    boolean found=false;
181    int  i;
182 #endif
183 
184    whereami=25;
185 #if (DEVELOPMENT == 1)
186    if ((shadingtable>=colormap) && (shadingtable<=(colormap+(31*256))))
187       {
188       found=true;
189       }
190    else if ((shadingtable>=redmap) && (shadingtable<=(redmap+(31*256))))
191       {
192       found=true;
193       }
194    else
195       {
196       for (i=0;i<MAXPLAYERCOLORS;i++)
197          {
198          if ((shadingtable>=playermaps[i]) || (shadingtable<=(playermaps[i]+(31*256))))
199             found=true;
200          }
201       }
202    if (found==false)
203       {
204       Error ("Shadingtable out of range\n");
205       }
206    if ((level<0) || (level>=64))
207       {
208       Error ("translucent level out of range\n");
209       }
210 #endif
211 
212    seelevel=colormap+(((level+64)>>2)<<8);
213    oldlevel=shadingtable;
214    offset=*(src++);
215    for (;offset!=255;)
216       {
217       length=*(src++);
218       topscreen = sprtopoffset + (dc_invscale*offset);
219       bottomscreen = topscreen + (dc_invscale*length);
220       dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
221       dc_yh = ((bottomscreen-1)>>SFRACBITS);
222       if (dc_yh >= viewheight)
223          dc_yh = viewheight-1;
224       if (dc_yl < 0)
225          dc_yl = 0;
226       if ((*src)==254)
227          {
228          shadingtable=seelevel;
229          if (dc_yl <= dc_yh)
230             R_TransColumn (buf);
231          src++;
232          offset=*(src++);
233          shadingtable=oldlevel;
234          }
235       else
236          {
237          if (dc_yl <= dc_yh)
238             {
239             dc_source=src-offset;
240             R_DrawColumn (buf);
241             }
242          src+=length;
243          offset=*(src++);
244          }
245       }
246 
247    whereami=-2;
248 }
249 
250 
ScaleMaskedPost(byte * src,byte * buf)251 void ScaleMaskedPost (byte * src, byte * buf)
252 {
253    int  offset;
254    int  length;
255    int  topscreen;
256    int  bottomscreen;
257 
258    whereami=26;
259    offset=*(src++);
260    for (;offset!=255;)
261       {
262       length=*(src++);
263       topscreen = sprtopoffset + (dc_invscale*offset);
264       bottomscreen = topscreen + (dc_invscale*length);
265       dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
266       dc_yh = ((bottomscreen-1)>>SFRACBITS);
267       if (dc_yh >= viewheight)
268          dc_yh = viewheight-1;
269       if (dc_yl < 0)
270          dc_yl = 0;
271       if (dc_yl <= dc_yh)
272          {
273          dc_source=src-offset;
274          R_DrawColumn (buf);
275 #if (DEVELOPMENT == 1)
276 //         if (dc_firstsource<src)
277 //            SoftError("dc_firstsource=%p src=%p\n",dc_firstsource,src);
278 #endif
279          }
280       src+=length;
281       offset=*(src++);
282       }
283 }
284 
ScaleClippedPost(byte * src,byte * buf)285 void ScaleClippedPost (byte * src, byte * buf)
286 {
287    int  offset;
288    int  length;
289    int  topscreen;
290    int  bottomscreen;
291 
292    whereami=27;
293    offset=*(src++);
294    for (;offset!=255;)
295       {
296       length=*(src++);
297       topscreen = sprtopoffset + (dc_invscale*offset);
298       bottomscreen = topscreen + (dc_invscale*length);
299       dc_yl = (topscreen+SFRACUNIT-1)>>SFRACBITS;
300       dc_yh = ((bottomscreen-1)>>SFRACBITS);
301       if (dc_yh >= viewheight)
302          dc_yh = viewheight-1;
303       if (dc_yl < 0)
304          dc_yl = 0;
305       if (dc_yl <= dc_yh)
306          {
307          dc_source=src-offset;
308          R_DrawClippedColumn (buf);
309          }
310       src+=length;
311       offset=*(src++);
312       }
313 }
314 
ScaleSolidMaskedPost(int color,byte * src,byte * buf)315 void ScaleSolidMaskedPost (int color, byte * src, byte * buf)
316 {
317    int  offset;
318    int  length;
319    int  topscreen;
320    int  bottomscreen;
321 
322    whereami=28;
323    offset=*(src++);
324    for (;offset!=255;)
325       {
326       length=*(src++);
327       topscreen = sprtopoffset + (dc_invscale*offset);
328       bottomscreen = topscreen + (dc_invscale*length);
329       dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
330       dc_yh = ((bottomscreen-1)>>SFRACBITS);
331       if (dc_yh >= viewheight)
332          dc_yh = viewheight-1;
333       if (dc_yl < 0)
334          dc_yl = 0;
335       if (dc_yl <= dc_yh)
336          {
337          dc_source=src-offset;
338          R_DrawSolidColumn (color, buf);
339          }
340       src+=length;
341       offset=*(src++);
342       }
343 
344 }
345 
346 
ScaleTransparentClippedPost(byte * src,byte * buf,int level)347 void ScaleTransparentClippedPost (byte * src, byte * buf, int level)
348 {
349    int  offset;
350    int  length;
351    int  topscreen;
352    int  bottomscreen;
353    byte * oldlevel;
354    byte * seelevel;
355 
356    whereami=29;
357 
358    seelevel=colormap+(((level+64)>>2)<<8);
359    oldlevel=shadingtable;
360    offset=*(src++);
361    for (;offset!=255;)
362       {
363       length=*(src++);
364       topscreen = sprtopoffset + (dc_invscale*offset);
365       bottomscreen = topscreen + (dc_invscale*length);
366       dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
367       dc_yh = ((bottomscreen-1)>>SFRACBITS);
368       if (dc_yh >= viewheight)
369          dc_yh = viewheight-1;
370       if (dc_yl < 0)
371          dc_yl = 0;
372       if ((*src)==254)
373          {
374          shadingtable=seelevel;
375          if (dc_yl <= dc_yh)
376             R_TransColumn (buf);
377          src++;
378          offset=*(src++);
379          shadingtable=oldlevel;
380          }
381       else
382          {
383          if (dc_yl <= dc_yh)
384             {
385             dc_source=src-offset;
386             R_DrawClippedColumn (buf);
387             }
388          src+=length;
389          offset=*(src++);
390          }
391       }
392 
393 }
394 
395 
ScaleMaskedWidePost(byte * src,byte * buf,int x,int width)396 void ScaleMaskedWidePost (byte * src, byte * buf, int x, int width)
397 {
398 #ifdef DOS
399    int  ofs;
400    int  msk;
401 
402    whereami=30;
403    buf+=x>>2;
404    ofs=((x&3)<<3)+(x&3)+width-1;
405    VGAMAPMASK(*((byte *)mapmasks1+ofs));
406    ScaleMaskedPost(src,buf);
407    msk=(byte)*((byte *)mapmasks2+ofs);
408    if (msk==0)
409       return;
410    buf++;
411    VGAMAPMASK(msk);
412    ScaleMaskedPost(src,buf);
413    msk=(byte)*((byte *)mapmasks3+ofs);
414    if (msk==0)
415       return;
416    buf++;
417    VGAMAPMASK(msk);
418    ScaleMaskedPost(src,buf);
419 #else
420 	buf += x;
421 
422 	while (width--) {
423 		ScaleMaskedPost(src,buf);
424 		buf++;
425 	}
426 #endif
427 }
428 
ScaleClippedWidePost(byte * src,byte * buf,int x,int width)429 void ScaleClippedWidePost (byte * src, byte * buf, int x, int width)
430 {
431 #ifdef DOS
432    int  ofs;
433    int  msk;
434 
435    whereami=31;
436    buf+=x>>2;
437    ofs=((x&3)<<3)+(x&3)+width-1;
438    VGAMAPMASK(*((byte *)mapmasks1+ofs));
439    ScaleClippedPost(src,buf);
440    msk=(byte)*((byte *)mapmasks2+ofs);
441    if (msk==0)
442       return;
443 	buf++;
444    VGAMAPMASK(msk);
445    ScaleClippedPost(src,buf);
446    msk=(byte)*((byte *)mapmasks3+ofs);
447    if (msk==0)
448       return;
449    buf++;
450    VGAMAPMASK(msk);
451    ScaleClippedPost(src,buf);
452 #else
453 	buf += x;
454 
455 	while (width--) {
456 		ScaleClippedPost(src,buf);
457 		buf++;
458 	}
459 #endif
460 }
461 
462 
463 /*
464 =======================
465 =
466 = ScaleShape
467 =
468 =======================
469 */
470 
ScaleShape(visobj_t * sprite)471 void ScaleShape (visobj_t * sprite)
472 {
473    byte *shape;
474    int      frac;
475    patch_t *p;
476    int      x1,x2;
477    int      tx;
478    int      size;
479    int      plane;
480 
481    whereami=32;
482    shape=W_CacheLumpNum(sprite->shapenum,PU_CACHE, Cvt_patch_t, 1);
483    p=(patch_t *)shape;
484    size=p->origsize>>7;
485 //   sprite->viewheight<<=1;
486    dc_invscale=sprite->viewheight<<((10-HEIGHTFRACTION)-size);
487    tx=-p->leftoffset;
488    sprite->viewx=(sprite->viewx<<SFRACBITS)-(sprite->viewheight<<(SFRACBITS-HEIGHTFRACTION-1))+(SFRACUNIT>>1);
489 //
490 // calculate edges of the shape
491 //
492         x1 = (sprite->viewx+(tx*dc_invscale))>>SFRACBITS;
493         if (x1 >= viewwidth)
494            {
495            return;               // off the right side
496 			  }
497         tx+=p->width;
498         x2 = ((sprite->viewx+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
499         if (x2 < 0)
500            {
501            return;         // off the left side
502            }
503 
504 // dc_iscale=(1<<(16+6+HEIGHTFRACTION+size))/sprite->viewheight;
505    dc_iscale=0xffffffffu/(unsigned)dc_invscale;
506    dc_texturemid=(((sprite->h1<<size) + p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
507    sprtopoffset=centeryfrac -  FixedMul(dc_texturemid,dc_invscale);
508    shadingtable=sprite->colormap;
509 
510    if (x1<0)
511       {
512       frac=dc_iscale*(-x1);
513       x1=0;
514       }
515    else
516       frac=0;
517    x2 = x2 >= viewwidth ? viewwidth-1 : x2;
518 
519    if (sprite->viewheight>((1<<(HEIGHTFRACTION+6))<<size))
520       {
521       int      texturecolumn;
522       int      lastcolumn;
523       int      startx;
524       int      width;
525 
526       width=1;
527       startx=0;
528       lastcolumn=-1;
529       for (; x1<=x2 ; x1++, frac += dc_iscale)
530         {
531          if (posts[x1].wallheight>sprite->viewheight)
532             {
533             if (lastcolumn>=0)
534                {
535                ScaleMaskedWidePost(((p->collumnofs[lastcolumn])+shape),(byte *)bufferofs,startx,width);
536                width=1;
537                lastcolumn=-1;
538                }
539             continue;
540 				}
541                 texturecolumn = frac>>SFRACBITS;
542          if ((texturecolumn==lastcolumn)&&(width<9))
543             {
544             width++;
545             continue;
546             }
547          else
548             {
549             if (lastcolumn>=0)
550                {
551                ScaleMaskedWidePost(((p->collumnofs[lastcolumn])+shape),(byte *)bufferofs,startx,width);
552                width=1;
553                startx=x1;
554                lastcolumn=texturecolumn;
555                }
556             else
557                {
558                startx=x1;
559                lastcolumn=texturecolumn;
560                }
561             }
562          }
563       if (lastcolumn!=-1)
564          ScaleMaskedWidePost(((p->collumnofs[lastcolumn])+shape),(byte *)bufferofs,startx,width);
565       }
566    else
567       {
568       byte * b;
569       int    startfrac;
570       int    startx;
571 
572       startx=x1;
573       startfrac=frac;
574       if (doublestep>1)
575          {
576 #ifdef DOS
577          for (plane=startx;plane<startx+4;plane+=2,startfrac+=(dc_iscale<<1))
578 #endif
579             {
580             frac=startfrac;
581 //   VGAWRITEMAP(plane&3);
582 #ifdef DOS
583             for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2))
584 #else
585             for (x1=startx;x1<=x2;x1+=2, frac += (dc_iscale<<1))
586 #endif
587                {
588                if (
589                    (posts[x1].wallheight>sprite->viewheight) &&
590                    (posts[x1+1].wallheight>sprite->viewheight)
591                   )
592                   continue;
593                if (x1==viewwidth-1)
594                   ScaleMaskedWidePost(((p->collumnofs[frac>>SFRACBITS])+shape),(byte *)bufferofs,x1,1);
595                else
596                   ScaleMaskedWidePost(((p->collumnofs[frac>>SFRACBITS])+shape),(byte *)bufferofs,x1,2);
597                }
598             }
599          }
600       else
601          {
602 #ifdef DOS
603          for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
604 #endif
605             {
606             frac=startfrac;
607 
608 #ifdef DOS
609             b=(byte *)bufferofs+(plane>>2);
610             VGAWRITEMAP(plane&3);
611 #else
612             b=(byte *)bufferofs+startx;
613 #endif
614 
615 #ifdef DOS
616             for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2),b++)
617 #else
618             for (x1=startx;x1<=x2;x1++, frac += dc_iscale,b++)
619 #endif
620                {
621                if (posts[x1].wallheight>sprite->viewheight)
622                   continue;
623                ScaleMaskedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
624                }
625             }
626          }
627       }
628 }
629 
630 
631 /*
632 =======================
633 =
634 = ScaleTranparentShape
635 =
636 =======================
637 */
638 
ScaleTransparentShape(visobj_t * sprite)639 void ScaleTransparentShape (visobj_t * sprite)
640 {
641    byte *shape;
642    int      frac;
643    transpatch_t *p;
644    int      x1,x2;
645    int      tx;
646    int      size;
647    byte * b;
648    int    startfrac;
649    int    startx;
650    int    plane;
651 
652    whereami=33;
653    shape=W_CacheLumpNum(sprite->shapenum,PU_CACHE, Cvt_transpatch_t, 1);
654    p=(transpatch_t *)shape;
655    size=p->origsize>>7;
656    dc_invscale=sprite->viewheight<<((10-HEIGHTFRACTION)-size);
657    tx=-p->leftoffset;
658    sprite->viewx=(sprite->viewx<<SFRACBITS)-(sprite->viewheight<<(SFRACBITS-HEIGHTFRACTION-1));
659 //
660 // calculate edges of the shape
661 //
662         x1 = (sprite->viewx+(tx*dc_invscale))>>SFRACBITS;
663         if (x1 >= viewwidth)
664            {
665            return;               // off the right side
666            }
667         tx+=p->width;
668         x2 = ((sprite->viewx+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
669         if (x2 < 0)
670            {
671            return;         // off the left side
672 			  }
673 
674 //   dc_iscale=(1<<(16+6+HEIGHTFRACTION+size))/sprite->viewheight;
675    dc_iscale=0xffffffffu/(unsigned)dc_invscale;
676    dc_texturemid=(((sprite->h1<<size)+p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
677    sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
678    shadingtable=sprite->colormap;
679 
680    if (x1<0)
681       {
682       frac=dc_iscale*(-x1);
683       x1=0;
684       }
685    else
686       frac=0;
687    x2 = x2 >= viewwidth ? viewwidth-1 : x2;
688 
689 #if 0
690    for (; x1<=x2 ; x1++, frac += dc_iscale)
691       {
692       if (posts[x1].wallheight>sprite->viewheight)
693          continue;
694       VGAWRITEMAP(x1&3);
695       VGAREADMAP(x1&3);
696       ScaleTransparentPost(((p->collumnofs[frac>>SFRACBITS])+shape),(byte *)bufferofs+(x1>>2),sprite->h2);
697       }
698 #endif
699    startx=x1;
700    startfrac=frac;
701 
702 #ifdef DOS
703    for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
704 #endif
705 
706       {
707       frac=startfrac;
708 
709 #ifdef DOS
710       b=(byte *)bufferofs+(plane>>2);
711       VGAWRITEMAP(plane&3);
712       VGAREADMAP(plane&3);
713 #else
714      b=(byte *)bufferofs+startx;
715 #endif
716 
717 #ifdef DOS
718       for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2),b++)
719 #else
720       for (x1=startx;x1<=x2;x1++, frac += dc_iscale,b++)
721 #endif
722          {
723          if (posts[x1].wallheight>sprite->viewheight)
724             continue;
725          ScaleTransparentPost(((p->collumnofs[frac>>SFRACBITS])+shape),b,sprite->h2);
726          }
727       }
728 }
729 
730 /*
731 =======================
732 =
733 = ScaleSolidShape
734 =
735 =======================
736 */
737 
ScaleSolidShape(visobj_t * sprite)738 void ScaleSolidShape (visobj_t * sprite)
739 {
740    byte *shape;
741    int      frac;
742    patch_t *p;
743    int      x1,x2;
744    int      tx;
745    int      size;
746    int      plane;
747 	byte * b;
748    int    startfrac;
749    int    startx;
750 
751    whereami=34;
752    shape=W_CacheLumpNum(sprite->shapenum,PU_CACHE, Cvt_patch_t, 1);
753    p=(patch_t *)shape;
754    size=p->origsize>>7;
755    dc_invscale=sprite->viewheight<<((10-HEIGHTFRACTION)-size);
756    tx=-p->leftoffset;
757    sprite->viewx=(sprite->viewx<<SFRACBITS)-(sprite->viewheight<<(SFRACBITS-HEIGHTFRACTION-1))+(SFRACUNIT>>1);
758 //
759 // calculate edges of the shape
760 //
761         x1 = (sprite->viewx+(tx*dc_invscale))>>SFRACBITS;
762         if (x1 >= viewwidth)
763            {
764            return;               // off the right side
765            }
766         tx+=p->width;
767         x2 = ((sprite->viewx+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
768         if (x2 < 0)
769            {
770            return;         // off the left side
771            }
772 
773 //   dc_iscale=(1<<(16+6+HEIGHTFRACTION+size))/sprite->viewheight;
774    dc_iscale=0xffffffffu/(unsigned)dc_invscale;
775    dc_texturemid=(((sprite->h1<<size)+p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
776    sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
777    shadingtable=sprite->colormap;
778 
779    if (x1<0)
780       {
781       frac=dc_iscale*(-x1);
782       x1=0;
783       }
784    else
785       frac=0;
786    x2 = x2 >= viewwidth ? viewwidth-1 : x2;
787 
788    startx=x1;
789    startfrac=frac;
790 
791 #ifdef DOS
792    for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
793 #endif
794 
795       {
796 		frac=startfrac;
797 
798 #ifdef DOS
799       b=(byte *)bufferofs+(plane>>2);
800       VGAWRITEMAP(plane&3);
801 #else
802       b=(byte *)bufferofs+startx;
803 #endif
804 
805 #ifdef DOS
806       for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2),b++)
807 #else
808       for (x1=startx;x1<=x2;x1++, frac += dc_iscale,b++)
809 #endif
810          {
811          if (posts[x1].wallheight>sprite->viewheight)
812             continue;
813          ScaleSolidMaskedPost(sprite->h2,((p->collumnofs[frac>>SFRACBITS])+shape),b);
814          }
815       }
816 }
817 
818 
819 /*
820 =======================
821 =
822 = ScaleWeapon
823 =
824 =======================
825 */
826 
ScaleWeapon(int xoff,int y,int shapenum)827 void ScaleWeapon (int xoff, int y, int shapenum)
828 {
829 	byte *shape;
830 	int      frac;
831 	int      h;
832 	patch_t *p;
833 	int      x1,x2;
834 	int      tx;
835 	int      xcent;
836 	byte * b;
837 	int    startfrac;
838 	int    startx;
839    int    plane;
840 
841    whereami=35;
842    SetPlayerLightLevel();
843    shape=W_CacheLumpNum(shapenum,PU_CACHE, Cvt_patch_t, 1);
844    p=(patch_t *)shape;
845    h=((p->origsize*weaponscale)>>17);
846    centeryclipped=(viewheight-h)+FixedMul(y,weaponscale);
847    xcent=centerx+FixedMul(xoff,weaponscale);
848    dc_invscale=(h<<17)/p->origsize;
849 
850 	tx=-p->leftoffset;
851 	xcent=(xcent<<SFRACBITS)-(h<<SFRACBITS);
852 //
853 // calculate edges of the shape
854 //
855 		  x1 = (xcent+(tx*dc_invscale))>>SFRACBITS;
856 		  if (x1 >= viewwidth)
857 					 return;               // off the right side
858         tx+=p->width;
859         x2 = ((xcent+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
860         if (x2 < 0)
861                 return;         // off the left side
862 
863    dc_iscale=0xffffffffu/(unsigned)dc_invscale;
864    dc_texturemid=(((p->origsize>>1)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
865    sprtopoffset=(centeryclipped<<16) - FixedMul(dc_texturemid,dc_invscale);
866 
867 //
868 // store information in a vissprite
869 //
870    if (x1<0)
871 		{
872       frac=dc_iscale*(-x1);
873       x1=0;
874       }
875    else
876       frac=0;
877 
878    x2 = x2 >= viewwidth ? viewwidth-1 : x2;
879 
880 	startx=x1;
881 	startfrac=frac;
882 
883 #ifdef DOS
884    for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
885 #endif
886       {
887       frac=startfrac;
888 #ifdef DOS
889       b=(byte *)bufferofs+(plane>>2);
890 #else
891       b=(byte *)bufferofs+startx;
892 #endif
893       VGAWRITEMAP(plane&3);
894 #ifdef DOS
895       for (x1=plane; x1<=x2 ; x1+=4, frac += dc_iscale<<2,b++)
896 #else
897       for (x1=startx; x1<=x2 ; x1++, frac += dc_iscale,b++)
898 #endif
899          ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
900       }
901 }
902 
903 
904 
905 
906 /*
907 =======================
908 =
909 = DrawUnScaledSprite
910 =
911 =======================
912 */
913 
DrawUnScaledSprite(int x,int y,int shapenum,int shade)914 void DrawUnScaledSprite (int x, int y, int shapenum, int shade)
915 {
916    byte *shape;
917    int      frac;
918    patch_t *p;
919    int      x1,x2;
920    int      tx;
921    int      xcent;
922    byte * b;
923    int    startfrac;
924    int    startx;
925 	int    plane;
926 
927    whereami=36;
928    shadingtable=colormap+(shade<<8);
929    centeryclipped=y;
930    xcent=x;
931    shape=W_CacheLumpNum(shapenum,PU_CACHE, Cvt_patch_t, 1);
932    p=(patch_t *)shape;
933 	dc_invscale=0x10000;
934 
935    tx=-p->leftoffset;
936    xcent-=p->origsize>>1;
937 //
938 // calculate edges of the shape
939 //
940 		  x1 = xcent+tx;
941 		  if (x1 >= viewwidth)
942 					 return;               // off the right side
943 		  tx+=p->width;
944 		  x2 = xcent+tx - 1;
945 		  if (x2 < 0)
946 					 return;         // off the left side
947 
948 	dc_iscale=0x10000;
949    dc_texturemid=(((p->height>>1)+p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
950 	sprtopoffset=(centeryclipped<<16) - dc_texturemid;
951 
952 //
953 // store information in a vissprite
954 //
955    if (x1<0)
956       {
957       frac=dc_iscale*(-x1);
958       x1=0;
959       }
960    else
961       frac = 0;
962 
963    x2 = x2 >= viewwidth ? viewwidth-1 : x2;
964 
965    startx=x1;
966    startfrac=frac;
967 
968 #ifdef DOS
969    for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
970 #endif
971 
972 		{
973 		frac=startfrac;
974 
975 #ifdef DOS
976 		b=(byte *)bufferofs+(plane>>2);
977       VGAWRITEMAP(plane&3);
978 #else
979                 b=(byte *)bufferofs+startx;
980 #endif
981 
982 #ifdef DOS
983 		for (x1=plane; x1<=x2 ; x1+=4, frac += dc_iscale<<2,b++)
984 #else
985 		for (x1=startx; x1<=x2 ; x1++, frac += dc_iscale,b++)
986 #endif
987 			ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
988 		}
989 }
990 
991 
992 /*
993 =======================
994 =
995 = DrawScreenSprite
996 =
997 =======================
998 */
999 
DrawScreenSprite(int x,int y,int shapenum)1000 void DrawScreenSprite (int x, int y, int shapenum)
1001 {
1002    whereami=37;
1003 	ScaleWeapon (x-160, y-200, shapenum);
1004 }
1005 
1006 /*
1007 =======================
1008 =
1009 = DrawPositionedScaledSprite
1010 =
1011 =======================
1012 */
1013 
DrawPositionedScaledSprite(int x,int y,int shapenum,int height,int type)1014 void DrawPositionedScaledSprite (int x, int y, int shapenum, int height, int type)
1015 {
1016 	byte *shape;
1017 	int      frac;
1018 	patch_t *p;
1019 	transpatch_t *tp;
1020 	int      x1,x2;
1021 	int      tx;
1022 	int      xcent;
1023 	byte * b;
1024 	int    startfrac;
1025 	int    startx;
1026 	int    plane;
1027 	int    size;
1028 
1029    whereami=38;
1030    shadingtable=colormap+(1<<12);
1031 	centeryclipped=y;
1032 	xcent=x;
1033 	shape=W_CacheLumpNum(shapenum,PU_CACHE, Cvt_transpatch_t, 1);
1034 	p=(patch_t *)shape;
1035 	tp=(transpatch_t *)shape;
1036 
1037 	size=p->origsize>>7;
1038 	dc_invscale=height<<(10-size);
1039 
1040 	tx=-p->leftoffset;
1041 	xcent=(xcent<<SFRACBITS)-(height<<(SFRACBITS-1));
1042 
1043 //
1044 // calculate edges of the shape
1045 //
1046 		  x1 = (xcent+(tx*dc_invscale))>>SFRACBITS;
1047 		  if (x1 >= viewwidth)
1048 					 return;               // off the right side
1049 		  tx+=p->width;
1050 		  x2 = ((xcent+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
1051 		  if (x2 < 0)
1052 					 return;         // off the left side
1053 
1054    dc_iscale=0xffffffffu/(unsigned)dc_invscale;
1055 //   dc_iscale=(1<<(16+6+size))/height;
1056    dc_texturemid=(((32<<size)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
1057    sprtopoffset=(centeryclipped<<16) - FixedMul(dc_texturemid,dc_invscale);
1058 
1059 //
1060 // store information in a vissprite
1061 //
1062    if (x1<0)
1063       {
1064       frac=dc_iscale*(-x1);
1065       x1=0;
1066       }
1067    else
1068       frac=0;
1069 
1070    x2 = x2 >= viewwidth ? viewwidth-1 : x2;
1071 
1072 	startx=x1;
1073    startfrac=frac;
1074 
1075 #ifdef DOS
1076    for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
1077 #endif
1078 
1079       {
1080       frac=startfrac;
1081 
1082 #ifdef DOS
1083       b=(byte *)bufferofs+(plane>>2);
1084       VGAWRITEMAP(plane&3);
1085       VGAREADMAP(plane&3);
1086 #else
1087       b=(byte *)bufferofs+startx;
1088 #endif
1089 
1090 #ifdef DOS
1091       for (x1=plane; x1<=x2 ; x1+=4, frac += dc_iscale<<2,b++)
1092 #else
1093       for (x1=startx; x1<=x2 ; x1++, frac += dc_iscale,b++)
1094 #endif
1095          if (type==0)
1096             ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
1097          else
1098 				ScaleTransparentClippedPost(((tp->collumnofs[frac>>SFRACBITS])+shape),b,transparentlevel);
1099 		}
1100 }
1101 
1102 
1103 /*
1104 =================
1105 =
1106 = DrawScreenSizedSprite
1107 =
1108 =================
1109 */
DrawScreenSizedSprite(int lump)1110 void DrawScreenSizedSprite (int lump)
1111 {
1112    byte *shape;
1113    int      frac;
1114    patch_t *p;
1115    int      x1,x2;
1116    int      tx;
1117    int      plane;
1118    byte * b;
1119    int    startfrac;
1120 
1121 
1122    whereami=39;
1123    shadingtable=colormap+(1<<12);
1124    shape=W_CacheLumpNum(lump,PU_CACHE, Cvt_patch_t, 1);
1125    p=(patch_t *)shape;
1126    dc_invscale=(viewwidth<<16)/p->origsize;
1127    tx=-p->leftoffset;
1128    centeryclipped=viewheight>>1;
1129 //
1130 // calculate edges of the shape
1131 //
1132         x1 = (tx*dc_invscale)>>SFRACBITS;
1133         if (x1 >= viewwidth)
1134            {
1135            return;               // off the right side
1136 			  }
1137         tx+=p->width;
1138         x2 = ((tx*dc_invscale) >>SFRACBITS) - 1 ;
1139         if (x2 < 0)
1140            {
1141            return;         // off the left side
1142            }
1143 
1144    dc_iscale=0xffffffffu/(unsigned)dc_invscale;
1145    dc_texturemid=(((p->origsize>>1) + p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
1146    sprtopoffset=(centeryclipped<<16) -  FixedMul(dc_texturemid,dc_invscale);
1147 
1148    x2 = (viewwidth-1);
1149 
1150    startfrac=0;
1151 
1152 #ifdef DOS
1153    for (plane=0;plane<4;plane++,startfrac+=dc_iscale)
1154 #endif
1155 
1156       {
1157       frac=startfrac;
1158 
1159 #ifdef DOS
1160       b=(byte *)bufferofs+(plane>>2);
1161       VGAWRITEMAP(plane&3);
1162 #else
1163       b=(byte *)bufferofs;
1164 #endif
1165 
1166 #ifdef DOS
1167       for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2),b++)
1168 #else
1169       for (x1=0;x1<=x2;x1++, frac += dc_iscale,b++)
1170 #endif
1171          {
1172          ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
1173          }
1174       }
1175 }
1176 
1177 #if 0
1178    byte *shape;
1179    int      frac;
1180    patch_t *p;
1181    int      x1,x2;
1182    int      tx;
1183    int      xdc_invscale;
1184    int      xdc_iscale;
1185    byte *   buf;
1186    byte *   b;
1187    int      plane;
1188    int      startx,startfrac;
1189 
1190    whereami=39;
1191    SetPlayerLightLevel();
1192    buf=(byte *)bufferofs;
1193    shape=W_CacheLumpNum(lump,PU_CACHE);
1194    p=(patch_t *)shape;
1195    dc_invscale=(viewheight<<16)/200;
1196 	xdc_invscale=(viewwidth<<16)/320;
1197 
1198    tx=-p->leftoffset;
1199    centeryclipped=viewheight>>1;
1200 //
1201 // calculate edges of the shape
1202 //
1203         x1 = (tx*xdc_invscale)>>SFRACBITS;
1204         if (x1 >= viewwidth)
1205                 return;               // off the right side
1206         tx+=p->width;
1207         x2 = ((tx*xdc_invscale)>>SFRACBITS) - 1 ;
1208 		  if (x2 < 0)
1209                 return;         // off the left side
1210 
1211    dc_iscale=(200*65536)/viewheight;
1212    xdc_iscale=(320*65536)/viewwidth;
1213    dc_texturemid=(((p->height>>1)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
1214    sprtopoffset=(centeryclipped<<16) - FixedMul(dc_texturemid,dc_invscale);
1215 
1216 //
1217 // store information in a vissprite
1218 //
1219    if (x1<0)
1220       {
1221       frac=xdc_iscale*(-x1);
1222       x1=0;
1223       }
1224    else
1225       frac=0;
1226         x2 = x2 >= viewwidth ? viewwidth-1 : x2;
1227 
1228    startx=x1;
1229    startfrac=frac;
1230    for (plane=startx;plane<startx+4;plane++,startfrac+=xdc_iscale)
1231       {
1232       frac=startfrac;
1233       b=(byte *)bufferofs+(plane>>2);
1234       VGAWRITEMAP(plane&3);
1235       for (x1=plane; x1<=x2 ; x1+=4, frac += xdc_iscale<<2,b++)
1236          ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
1237       }
1238 }
1239 #endif
1240 
1241 
1242 
1243 //******************************************************************************
1244 //
1245 // DrawNormalPost
1246 //
1247 //******************************************************************************
1248 
DrawNormalPost(byte * src,byte * buf)1249 void DrawNormalPost (byte * src, byte * buf)
1250 {
1251    int  offset;
1252    int  length;
1253    int  s;
1254 
1255    whereami=40;
1256 
1257    while (1)
1258       {
1259       offset=*(src++);
1260       if (offset==0xff)
1261          return;
1262       else
1263          {
1264             length=*(src++);
1265             for (s=0;s<length;s++) {
1266                 // Spaced out a little for tracking a bug. Should be equivalent.
1267                 byte *saddr = src+s;
1268                 byte *daddr = buf + ylookup[offset + s];
1269                 byte val = *saddr;
1270                 *daddr = val;
1271 //                *(buf+ylookup[offset+s])=*(src+s);
1272             }
1273             src+=length;
1274          }
1275       }
1276 }
1277 
1278 
1279 
1280 //******************************************************************************
1281 //
1282 // DrawNormalSprite
1283 //
1284 //******************************************************************************
1285 
DrawNormalSprite(int x,int y,int shapenum)1286 void DrawNormalSprite (int x, int y, int shapenum)
1287 {
1288    byte *buffer;
1289    int cnt;
1290    byte *shape;
1291    patch_t *p;
1292    int plane;
1293    byte * b;
1294    int startx;
1295 
1296    whereami=41;
1297 
1298    shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
1299    p = (patch_t *)shape;
1300 
1301    if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>320))
1302       Error ("DrawNormalSprite: x is out of range x=%ld\n",x-p->leftoffset+p->width);
1303    if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>200))
1304       Error ("DrawNormalSprite: y is out of range y=%ld\n",y-p->topoffset+p->height);
1305 
1306    startx=x-p->leftoffset;
1307    buffer = (byte*)bufferofs+ylookup[y-p->topoffset];
1308 
1309 #ifdef DOS
1310    for (plane=startx;plane<startx+4;plane++)
1311 #endif
1312       {
1313 #ifdef DOS
1314       b=buffer+(plane>>2);
1315       VGAWRITEMAP(plane&3);
1316 #else
1317       b=buffer+startx;
1318 #endif
1319 
1320 #ifdef DOS
1321       for (cnt = plane-startx; cnt < p->width; cnt+=4,b++)
1322 #else
1323       for (cnt = 0; cnt < p->width; cnt++,b++)
1324 #endif
1325          DrawNormalPost ((byte *)(p->collumnofs[cnt]+shape), b);
1326       }
1327 }
1328 
1329 #ifndef DOS
1330 
R_DrawColumn(byte * buf)1331 void R_DrawColumn (byte * buf)
1332 {
1333 	// This is *NOT* 100% correct - DDOI
1334 	int count;
1335 	int frac, fracstep;
1336 	byte *dest;
1337 
1338 	count = dc_yh - dc_yl + 1;
1339 	if (count < 0) return;
1340 
1341 	dest = buf + ylookup[dc_yl];
1342 
1343 	fracstep = dc_iscale;
1344 	frac = dc_texturemid + (dc_yl-centery)*fracstep;
1345 
1346 	while (count--) {
1347 		*dest = shadingtable[dc_source[(frac>>SFRACBITS)]];
1348 		dest += MAXSCREENWIDTH;
1349 		frac += fracstep;
1350 	}
1351 }
1352 
R_TransColumn(byte * buf)1353 void R_TransColumn (byte * buf)
1354 {
1355 	int count;
1356 	byte *dest;
1357 
1358 	count = dc_yh - dc_yl + 1;
1359 	if (count < 0) return;
1360 
1361 	dest = buf + ylookup[dc_yl];
1362 
1363 	while (count--)
1364 	{
1365 		*dest = shadingtable[*dest];
1366 		dest += MAXSCREENWIDTH;
1367 	}
1368 }
1369 
R_DrawWallColumn(byte * buf)1370 void R_DrawWallColumn (byte * buf)
1371 {
1372 	// This is *NOT* 100% correct - DDOI
1373 	int count;
1374 	int frac, fracstep;
1375 	byte *dest;
1376 
1377 	count = dc_yh - dc_yl;
1378 	if (count < 0) return;
1379 
1380 	dest = buf + ylookup[dc_yl];
1381 
1382 	fracstep = dc_iscale;
1383 	frac = dc_texturemid + (dc_yl-centery)*fracstep;
1384 	frac <<= 10;
1385 	fracstep <<= 10;
1386 
1387 	while (count--) {
1388 		*dest = shadingtable[dc_source[(((unsigned)frac)>>26)]];
1389 		dest += MAXSCREENWIDTH;
1390 		frac += fracstep;
1391 	}
1392 }
1393 
R_DrawClippedColumn(byte * buf)1394 void R_DrawClippedColumn (byte * buf)
1395 {
1396 	// This is *NOT* 100% correct - DDOI
1397 	int count;
1398 	int frac, fracstep;
1399 	byte *dest;
1400 
1401 	count = dc_yh - dc_yl + 1;
1402 	if (count < 0) return;
1403 
1404 	dest = buf + ylookup[dc_yl];
1405 
1406 	fracstep = dc_iscale;
1407 	frac = dc_texturemid + (dc_yl-centeryclipped)*fracstep;
1408 
1409 	while (count--) {
1410 		*dest = shadingtable[dc_source[(((unsigned)frac)>>SFRACBITS)]];
1411 		dest += MAXSCREENWIDTH;
1412 		frac += fracstep;
1413 	}
1414 }
1415 
R_DrawSolidColumn(int color,byte * buf)1416 void R_DrawSolidColumn (int color, byte * buf)
1417 {
1418 	int count;
1419 	int frac, fracstep;
1420 	byte *dest;
1421 
1422 	count = dc_yh - dc_yl + 1;
1423 	if (count < 0) return;
1424 
1425 	dest = buf + ylookup[dc_yl];
1426 
1427 	while (count--)
1428 	{
1429 		*dest = (byte)color;
1430 		dest += MAXSCREENWIDTH;
1431 	}
1432 }
1433 
1434 #endif
1435