Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8557 maxcodehac 1
// WL_DRAW.C
2
 
3
#include "wl_def.h"
4
#pragma hdrstop
5
 
6
#include "wl_cloudsky.h"
7
#include "wl_atmos.h"
8
#include "wl_shade.h"
9
 
10
/*
11
=============================================================================
12
 
13
                               LOCAL CONSTANTS
14
 
15
=============================================================================
16
*/
17
 
18
// the door is the last picture before the sprites
19
#define DOORWALL        (PMSpriteStart-8)
20
 
21
#define ACTORSIZE       0x4000
22
 
23
/*
24
=============================================================================
25
 
26
                              GLOBAL VARIABLES
27
 
28
=============================================================================
29
*/
30
 
31
static byte *vbuf = NULL;
32
unsigned vbufPitch = 0;
33
 
34
int32_t    lasttimecount;
35
int32_t    frameon;
36
boolean fpscounter;
37
 
38
int fps_frames=0, fps_time=0, fps=0;
39
 
40
int *wallheight;
41
int min_wallheight;
42
 
43
//
44
// math tables
45
//
46
short *pixelangle;
47
int32_t finetangent[FINEANGLES/4];
48
fixed sintable[ANGLES+ANGLES/4];
49
fixed *costable = sintable+(ANGLES/4);
50
 
51
//
52
// refresh variables
53
//
54
fixed   viewx,viewy;                    // the focal point
55
short   viewangle;
56
fixed   viewsin,viewcos;
57
 
58
void    TransformActor (objtype *ob);
59
void    BuildTables (void);
60
void    ClearScreen (void);
61
int     CalcRotate (objtype *ob);
62
void    DrawScaleds (void);
63
void    CalcTics (void);
64
void    ThreeDRefresh (void);
65
 
66
 
67
 
68
//
69
// wall optimization variables
70
//
71
int     lastside;               // true for vertical
72
int32_t    lastintercept;
73
int     lasttilehit;
74
int     lasttexture;
75
 
76
//
77
// ray tracing variables
78
//
79
short    focaltx,focalty,viewtx,viewty;
80
longword xpartialup,xpartialdown,ypartialup,ypartialdown;
81
 
82
short   midangle,angle;
83
 
84
word    tilehit;
85
int     pixx;
86
 
87
short   xtile,ytile;
88
short   xtilestep,ytilestep;
89
int32_t    xintercept,yintercept;
90
word    xstep,ystep;
91
word    xspot,yspot;
92
int     texdelta;
93
 
94
word horizwall[MAXWALLTILES],vertwall[MAXWALLTILES];
95
 
96
 
97
/*
98
============================================================================
99
 
100
                           3 - D  DEFINITIONS
101
 
102
============================================================================
103
*/
104
 
105
/*
106
========================
107
=
108
= TransformActor
109
=
110
= Takes paramaters:
111
=   gx,gy               : globalx/globaly of point
112
=
113
= globals:
114
=   viewx,viewy         : point of view
115
=   viewcos,viewsin     : sin/cos of viewangle
116
=   scale               : conversion from global value to screen value
117
=
118
= sets:
119
=   screenx,transx,transy,screenheight: projected edge location and size
120
=
121
========================
122
*/
123
 
124
 
125
//
126
// transform actor
127
//
128
void TransformActor (objtype *ob)
129
{
130
    fixed gx,gy,gxt,gyt,nx,ny;
131
 
132
//
133
// translate point to view centered coordinates
134
//
135
    gx = ob->x-viewx;
136
    gy = ob->y-viewy;
137
 
138
//
139
// calculate newx
140
//
141
    gxt = FixedMul(gx,viewcos);
142
    gyt = FixedMul(gy,viewsin);
143
    nx = gxt-gyt-ACTORSIZE;         // fudge the shape forward a bit, because
144
                                    // the midpoint could put parts of the shape
145
                                    // into an adjacent wall
146
 
147
//
148
// calculate newy
149
//
150
    gxt = FixedMul(gx,viewsin);
151
    gyt = FixedMul(gy,viewcos);
152
    ny = gyt+gxt;
153
 
154
//
155
// calculate perspective ratio
156
//
157
    ob->transx = nx;
158
    ob->transy = ny;
159
 
160
    if (nx
161
    {
162
        ob->viewheight = 0;
163
        return;
164
    }
165
 
166
    ob->viewx = (word)(centerx + ny*scale/nx);
167
 
168
//
169
// calculate height (heightnumerator/(nx>>8))
170
//
171
    ob->viewheight = (word)(heightnumerator/(nx>>8));
172
}
173
 
174
//==========================================================================
175
 
176
/*
177
========================
178
=
179
= TransformTile
180
=
181
= Takes paramaters:
182
=   tx,ty               : tile the object is centered in
183
=
184
= globals:
185
=   viewx,viewy         : point of view
186
=   viewcos,viewsin     : sin/cos of viewangle
187
=   scale               : conversion from global value to screen value
188
=
189
= sets:
190
=   screenx,transx,transy,screenheight: projected edge location and size
191
=
192
= Returns true if the tile is withing getting distance
193
=
194
========================
195
*/
196
 
197
boolean TransformTile (int tx, int ty, short *dispx, short *dispheight)
198
{
199
    fixed gx,gy,gxt,gyt,nx,ny;
200
 
201
//
202
// translate point to view centered coordinates
203
//
204
    gx = ((int32_t)tx<
205
    gy = ((int32_t)ty<
206
 
207
//
208
// calculate newx
209
//
210
    gxt = FixedMul(gx,viewcos);
211
    gyt = FixedMul(gy,viewsin);
212
    nx = gxt-gyt-0x2000;            // 0x2000 is size of object
213
 
214
//
215
// calculate newy
216
//
217
    gxt = FixedMul(gx,viewsin);
218
    gyt = FixedMul(gy,viewcos);
219
    ny = gyt+gxt;
220
 
221
 
222
//
223
// calculate height / perspective ratio
224
//
225
    if (nx
226
        *dispheight = 0;
227
    else
228
    {
229
        *dispx = (short)(centerx + ny*scale/nx);
230
        *dispheight = (short)(heightnumerator/(nx>>8));
231
    }
232
 
233
//
234
// see if it should be grabbed
235
//
236
    if (nx-TILEGLOBAL/2 && ny
237
        return true;
238
    else
239
        return false;
240
}
241
 
242
//==========================================================================
243
 
244
/*
245
====================
246
=
247
= CalcHeight
248
=
249
= Calculates the height of xintercept,yintercept from viewx,viewy
250
=
251
====================
252
*/
253
 
254
int CalcHeight()
255
{
256
    fixed z = FixedMul(xintercept - viewx, viewcos)
257
        - FixedMul(yintercept - viewy, viewsin);
258
    if(z < MINDIST) z = MINDIST;
259
    int height = heightnumerator / (z >> 8);
260
    if(height < min_wallheight) min_wallheight = height;
261
    return height;
262
}
263
 
264
//==========================================================================
265
 
266
/*
267
===================
268
=
269
= ScalePost
270
=
271
===================
272
*/
273
 
274
byte *postsource;
275
int postx;
276
int postwidth;
277
 
278
void ScalePost()
279
{
280
    int ywcount, yoffs, yw, yd, yendoffs;
281
    byte col;
282
 
283
#ifdef USE_SHADING
284
    byte *curshades = shadetable[GetShade(wallheight[postx])];
285
#endif
286
 
287
    ywcount = yd = wallheight[postx] >> 3;
288
    if(yd <= 0) yd = 100;
289
 
290
    yoffs = (viewheight / 2 - ywcount) * vbufPitch;
291
    if(yoffs < 0) yoffs = 0;
292
    yoffs += postx;
293
 
294
    yendoffs = viewheight / 2 + ywcount - 1;
295
    yw=TEXTURESIZE-1;
296
 
297
    while(yendoffs >= viewheight)
298
    {
299
        ywcount -= TEXTURESIZE/2;
300
        while(ywcount <= 0)
301
        {
302
            ywcount += yd;
303
            yw--;
304
        }
305
        yendoffs--;
306
    }
307
    if(yw < 0) return;
308
 
309
#ifdef USE_SHADING
310
    col = curshades[postsource[yw]];
311
#else
312
    col = postsource[yw];
313
#endif
314
    yendoffs = yendoffs * vbufPitch + postx;
315
    while(yoffs <= yendoffs)
316
    {
317
        vbuf[yendoffs] = col;
318
        ywcount -= TEXTURESIZE/2;
319
        if(ywcount <= 0)
320
        {
321
            do
322
            {
323
                ywcount += yd;
324
                yw--;
325
            }
326
            while(ywcount <= 0);
327
            if(yw < 0) break;
328
#ifdef USE_SHADING
329
            col = curshades[postsource[yw]];
330
#else
331
            col = postsource[yw];
332
#endif
333
        }
334
        yendoffs -= vbufPitch;
335
    }
336
}
337
 
338
void GlobalScalePost(byte *vidbuf, unsigned pitch)
339
{
340
    vbuf = vidbuf;
341
    vbufPitch = pitch;
342
    ScalePost();
343
}
344
 
345
/*
346
====================
347
=
348
= HitVertWall
349
=
350
= tilehit bit 7 is 0, because it's not a door tile
351
= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
352
=
353
====================
354
*/
355
 
356
void HitVertWall (void)
357
{
358
    int wallpic;
359
    int texture;
360
 
361
    texture = ((yintercept+texdelta)>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
362
    if (xtilestep == -1)
363
    {
364
        texture = TEXTUREMASK-texture;
365
        xintercept += TILEGLOBAL;
366
    }
367
 
368
    if(lastside==1 && lastintercept==xtile && lasttilehit==tilehit && !(lasttilehit & 0x40))
369
    {
370
        if((pixx&3) && texture == lasttexture)
371
        {
372
            ScalePost();
373
            postx = pixx;
374
            wallheight[pixx] = wallheight[pixx-1];
375
            return;
376
        }
377
        ScalePost();
378
        wallheight[pixx] = CalcHeight();
379
        postsource+=texture-lasttexture;
380
        postwidth=1;
381
        postx=pixx;
382
        lasttexture=texture;
383
        return;
384
    }
385
 
386
    if(lastside!=-1) ScalePost();
387
 
388
    lastside=1;
389
    lastintercept=xtile;
390
    lasttilehit=tilehit;
391
    lasttexture=texture;
392
    wallheight[pixx] = CalcHeight();
393
    postx = pixx;
394
    postwidth = 1;
395
 
396
    if (tilehit & 0x40)
397
    {                                                               // check for adjacent doors
398
        ytile = (short)(yintercept>>TILESHIFT);
399
        if ( tilemap[xtile-xtilestep][ytile]&0x80 )
400
            wallpic = DOORWALL+3;
401
        else
402
            wallpic = vertwall[tilehit & ~0x40];
403
    }
404
    else
405
        wallpic = vertwall[tilehit];
406
 
407
    postsource = PM_GetTexture(wallpic) + texture;
408
}
409
 
410
 
411
/*
412
====================
413
=
414
= HitHorizWall
415
=
416
= tilehit bit 7 is 0, because it's not a door tile
417
= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
418
=
419
====================
420
*/
421
 
422
void HitHorizWall (void)
423
{
424
    int wallpic;
425
    int texture;
426
 
427
    texture = ((xintercept+texdelta)>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
428
    if (ytilestep == -1)
429
        yintercept += TILEGLOBAL;
430
    else
431
        texture = TEXTUREMASK-texture;
432
 
433
    if(lastside==0 && lastintercept==ytile && lasttilehit==tilehit && !(lasttilehit & 0x40))
434
    {
435
        if((pixx&3) && texture == lasttexture)
436
        {
437
            ScalePost();
438
            postx=pixx;
439
            wallheight[pixx] = wallheight[pixx-1];
440
            return;
441
        }
442
        ScalePost();
443
        wallheight[pixx] = CalcHeight();
444
        postsource+=texture-lasttexture;
445
        postwidth=1;
446
        postx=pixx;
447
        lasttexture=texture;
448
        return;
449
    }
450
 
451
    if(lastside!=-1) ScalePost();
452
 
453
    lastside=0;
454
    lastintercept=ytile;
455
    lasttilehit=tilehit;
456
    lasttexture=texture;
457
    wallheight[pixx] = CalcHeight();
458
    postx = pixx;
459
    postwidth = 1;
460
 
461
    if (tilehit & 0x40)
462
    {                                                               // check for adjacent doors
463
        xtile = (short)(xintercept>>TILESHIFT);
464
        if ( tilemap[xtile][ytile-ytilestep]&0x80)
465
            wallpic = DOORWALL+2;
466
        else
467
            wallpic = horizwall[tilehit & ~0x40];
468
    }
469
    else
470
        wallpic = horizwall[tilehit];
471
 
472
    postsource = PM_GetTexture(wallpic) + texture;
473
}
474
 
475
//==========================================================================
476
 
477
/*
478
====================
479
=
480
= HitHorizDoor
481
=
482
====================
483
*/
484
 
485
void HitHorizDoor (void)
486
{
487
    int doorpage;
488
    int doornum;
489
    int texture;
490
 
491
    doornum = tilehit&0x7f;
492
    texture = ((xintercept-doorposition[doornum])>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
493
 
494
    if(lasttilehit==tilehit)
495
    {
496
        if((pixx&3) && texture == lasttexture)
497
        {
498
            ScalePost();
499
            postx=pixx;
500
            wallheight[pixx] = wallheight[pixx-1];
501
            return;
502
        }
503
        ScalePost();
504
        wallheight[pixx] = CalcHeight();
505
        postsource+=texture-lasttexture;
506
        postwidth=1;
507
        postx=pixx;
508
        lasttexture=texture;
509
        return;
510
    }
511
 
512
    if(lastside!=-1) ScalePost();
513
 
514
    lastside=2;
515
    lasttilehit=tilehit;
516
    lasttexture=texture;
517
    wallheight[pixx] = CalcHeight();
518
    postx = pixx;
519
    postwidth = 1;
520
 
521
    switch(doorobjlist[doornum].lock)
522
    {
523
        case dr_normal:
524
            doorpage = DOORWALL;
525
            break;
526
        case dr_lock1:
527
        case dr_lock2:
528
        case dr_lock3:
529
        case dr_lock4:
530
            doorpage = DOORWALL+6;
531
            break;
532
        case dr_elevator:
533
            doorpage = DOORWALL+4;
534
            break;
535
    }
536
 
537
    postsource = PM_GetTexture(doorpage) + texture;
538
}
539
 
540
//==========================================================================
541
 
542
/*
543
====================
544
=
545
= HitVertDoor
546
=
547
====================
548
*/
549
 
550
void HitVertDoor (void)
551
{
552
    int doorpage;
553
    int doornum;
554
    int texture;
555
 
556
    doornum = tilehit&0x7f;
557
    texture = ((yintercept-doorposition[doornum])>>TEXTUREFROMFIXEDSHIFT)&TEXTUREMASK;
558
 
559
    if(lasttilehit==tilehit)
560
    {
561
        if((pixx&3) && texture == lasttexture)
562
        {
563
            ScalePost();
564
            postx=pixx;
565
            wallheight[pixx] = wallheight[pixx-1];
566
            return;
567
        }
568
        ScalePost();
569
        wallheight[pixx] = CalcHeight();
570
        postsource+=texture-lasttexture;
571
        postwidth=1;
572
        postx=pixx;
573
        lasttexture=texture;
574
        return;
575
    }
576
 
577
    if(lastside!=-1) ScalePost();
578
 
579
    lastside=2;
580
    lasttilehit=tilehit;
581
    lasttexture=texture;
582
    wallheight[pixx] = CalcHeight();
583
    postx = pixx;
584
    postwidth = 1;
585
 
586
    switch(doorobjlist[doornum].lock)
587
    {
588
        case dr_normal:
589
            doorpage = DOORWALL+1;
590
            break;
591
        case dr_lock1:
592
        case dr_lock2:
593
        case dr_lock3:
594
        case dr_lock4:
595
            doorpage = DOORWALL+7;
596
            break;
597
        case dr_elevator:
598
            doorpage = DOORWALL+5;
599
            break;
600
    }
601
 
602
    postsource = PM_GetTexture(doorpage) + texture;
603
}
604
 
605
//==========================================================================
606
 
607
#define HitHorizBorder HitHorizWall
608
#define HitVertBorder HitVertWall
609
 
610
//==========================================================================
611
 
612
byte vgaCeiling[]=
613
{
614
#ifndef SPEAR
615
 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0xbf,
616
 0x4e,0x4e,0x4e,0x1d,0x8d,0x4e,0x1d,0x2d,0x1d,0x8d,
617
 0x1d,0x1d,0x1d,0x1d,0x1d,0x2d,0xdd,0x1d,0x1d,0x98,
618
 
619
 0x1d,0x9d,0x2d,0xdd,0xdd,0x9d,0x2d,0x4d,0x1d,0xdd,
620
 0x7d,0x1d,0x2d,0x2d,0xdd,0xd7,0x1d,0x1d,0x1d,0x2d,
621
 0x1d,0x1d,0x1d,0x1d,0xdd,0xdd,0x7d,0xdd,0xdd,0xdd
622
#else
623
 0x6f,0x4f,0x1d,0xde,0xdf,0x2e,0x7f,0x9e,0xae,0x7f,
624
 0x1d,0xde,0xdf,0xde,0xdf,0xde,0xe1,0xdc,0x2e,0x1d,0xdc
625
#endif
626
};
627
 
628
/*
629
=====================
630
=
631
= VGAClearScreen
632
=
633
=====================
634
*/
635
 
636
void VGAClearScreen (void)
637
{
638
    byte ceiling=vgaCeiling[gamestate.episode*10+mapon];
639
 
640
    int y;
641
    byte *ptr = vbuf;
642
#ifdef USE_SHADING
643
    for(y = 0; y < viewheight / 2; y++, ptr += vbufPitch)
644
        memset(ptr, shadetable[GetShade((viewheight / 2 - y) << 3)][ceiling], viewwidth);
645
    for(; y < viewheight; y++, ptr += vbufPitch)
646
        memset(ptr, shadetable[GetShade((y - viewheight / 2) << 3)][0x19], viewwidth);
647
#else
648
    for(y = 0; y < viewheight / 2; y++, ptr += vbufPitch)
649
        memset(ptr, ceiling, viewwidth);
650
    for(; y < viewheight; y++, ptr += vbufPitch)
651
        memset(ptr, 0x19, viewwidth);
652
#endif
653
}
654
 
655
//==========================================================================
656
 
657
/*
658
=====================
659
=
660
= CalcRotate
661
=
662
=====================
663
*/
664
 
665
int CalcRotate (objtype *ob)
666
{
667
    int angle, viewangle;
668
 
669
    // this isn't exactly correct, as it should vary by a trig value,
670
    // but it is close enough with only eight rotations
671
 
672
    viewangle = player->angle + (centerx - ob->viewx)/8;
673
 
674
    if (ob->obclass == rocketobj || ob->obclass == hrocketobj)
675
        angle = (viewangle-180) - ob->angle;
676
    else
677
        angle = (viewangle-180) - dirangle[ob->dir];
678
 
679
    angle+=ANGLES/16;
680
    while (angle>=ANGLES)
681
        angle-=ANGLES;
682
    while (angle<0)
683
        angle+=ANGLES;
684
 
685
    if (ob->state->rotate == 2)             // 2 rotation pain frame
686
        return 0;               // pain with shooting frame bugfix
687
 
688
    return angle/(ANGLES/8);
689
}
690
 
691
void ScaleShape (int xcenter, int shapenum, unsigned height, uint32_t flags)
692
{
693
    t_compshape *shape;
694
    unsigned scale,pixheight;
695
    unsigned starty,endy;
696
    word *cmdptr;
697
    byte *cline;
698
    byte *line;
699
    byte *vmem;
700
    int actx,i,upperedge;
701
    short newstart;
702
    int scrstarty,screndy,lpix,rpix,pixcnt,ycnt;
703
    unsigned j;
704
    byte col;
705
 
706
#ifdef USE_SHADING
707
    byte *curshades;
708
    if(flags & FL_FULLBRIGHT)
709
        curshades = shadetable[0];
710
    else
711
        curshades = shadetable[GetShade(height)];
712
#endif
713
 
714
    shape = (t_compshape *) PM_GetSprite(shapenum);
715
 
716
    scale=height>>3;                 // low three bits are fractional
717
    if(!scale) return;   // too close or far away
718
 
719
    pixheight=scale*SPRITESCALEFACTOR;
720
    actx=xcenter-scale;
721
    upperedge=viewheight/2-scale;
722
 
723
    cmdptr=(word *) shape->dataofs;
724
 
725
    for(i=shape->leftpix,pixcnt=i*pixheight,rpix=(pixcnt>>6)+actx;i<=shape->rightpix;i++,cmdptr++)
726
    {
727
        lpix=rpix;
728
        if(lpix>=viewwidth) break;
729
        pixcnt+=pixheight;
730
        rpix=(pixcnt>>6)+actx;
731
        if(lpix!=rpix && rpix>0)
732
        {
733
            if(lpix<0) lpix=0;
734
            if(rpix>viewwidth) rpix=viewwidth,i=shape->rightpix+1;
735
            cline=(byte *)shape + *cmdptr;
736
            while(lpix
737
            {
738
                if(wallheight[lpix]<=(int)height)
739
                {
740
                    line=cline;
741
                    while((endy = READWORD(line)) != 0)
742
                    {
743
                        endy >>= 1;
744
                        newstart = READWORD(line);
745
                        starty = READWORD(line) >> 1;
746
                        j=starty;
747
                        ycnt=j*pixheight;
748
                        screndy=(ycnt>>6)+upperedge;
749
                        if(screndy<0) vmem=vbuf+lpix;
750
                        else vmem=vbuf+screndy*vbufPitch+lpix;
751
                        for(;j
752
                        {
753
                            scrstarty=screndy;
754
                            ycnt+=pixheight;
755
                            screndy=(ycnt>>6)+upperedge;
756
                            if(scrstarty!=screndy && screndy>0)
757
                            {
758
#ifdef USE_SHADING
759
                                col=curshades[((byte *)shape)[newstart+j]];
760
#else
761
                                col=((byte *)shape)[newstart+j];
762
#endif
763
                                if(scrstarty<0) scrstarty=0;
764
                                if(screndy>viewheight) screndy=viewheight,j=endy;
765
 
766
                                while(scrstarty
767
                                {
768
                                    *vmem=col;
769
                                    vmem+=vbufPitch;
770
                                    scrstarty++;
771
                                }
772
                            }
773
                        }
774
                    }
775
                }
776
                lpix++;
777
            }
778
        }
779
    }
780
}
781
 
782
void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
783
{
784
    t_compshape   *shape;
785
    unsigned scale,pixheight;
786
    unsigned starty,endy;
787
    word *cmdptr;
788
    byte *cline;
789
    byte *line;
790
    int actx,i,upperedge;
791
    short newstart;
792
    int scrstarty,screndy,lpix,rpix,pixcnt,ycnt;
793
    unsigned j;
794
    byte col;
795
    byte *vmem;
796
 
797
    shape = (t_compshape *) PM_GetSprite(shapenum);
798
 
799
    scale=height>>1;
800
    pixheight=scale*SPRITESCALEFACTOR;
801
    actx=xcenter-scale;
802
    upperedge=viewheight/2-scale;
803
 
804
    cmdptr=shape->dataofs;
805
 
806
    for(i=shape->leftpix,pixcnt=i*pixheight,rpix=(pixcnt>>6)+actx;i<=shape->rightpix;i++,cmdptr++)
807
    {
808
        lpix=rpix;
809
        if(lpix>=viewwidth) break;
810
        pixcnt+=pixheight;
811
        rpix=(pixcnt>>6)+actx;
812
        if(lpix!=rpix && rpix>0)
813
        {
814
            if(lpix<0) lpix=0;
815
            if(rpix>viewwidth) rpix=viewwidth,i=shape->rightpix+1;
816
            cline = (byte *)shape + *cmdptr;
817
            while(lpix
818
            {
819
                line=cline;
820
                while((endy = READWORD(line)) != 0)
821
                {
822
                    endy >>= 1;
823
                    newstart = READWORD(line);
824
                    starty = READWORD(line) >> 1;
825
                    j=starty;
826
                    ycnt=j*pixheight;
827
                    screndy=(ycnt>>6)+upperedge;
828
                    if(screndy<0) vmem=vbuf+lpix;
829
                    else vmem=vbuf+screndy*vbufPitch+lpix;
830
                    for(;j
831
                    {
832
                        scrstarty=screndy;
833
                        ycnt+=pixheight;
834
                        screndy=(ycnt>>6)+upperedge;
835
                        if(scrstarty!=screndy && screndy>0)
836
                        {
837
                            col=((byte *)shape)[newstart+j];
838
                            if(scrstarty<0) scrstarty=0;
839
                            if(screndy>viewheight) screndy=viewheight,j=endy;
840
 
841
                            while(scrstarty
842
                            {
843
                                *vmem=col;
844
                                vmem+=vbufPitch;
845
                                scrstarty++;
846
                            }
847
                        }
848
                    }
849
                }
850
                lpix++;
851
            }
852
        }
853
    }
854
}
855
 
856
/*
857
=====================
858
=
859
= DrawScaleds
860
=
861
= Draws all objects that are visable
862
=
863
=====================
864
*/
865
 
866
#define MAXVISABLE 250
867
 
868
typedef struct
869
{
870
    short      viewx,
871
               viewheight,
872
               shapenum;
873
    short      flags;          // this must be changed to uint32_t, when you
874
                               // you need more than 16-flags for drawing
875
#ifdef USE_DIR3DSPR
876
    statobj_t *transsprite;
877
#endif
878
} visobj_t;
879
 
880
visobj_t vislist[MAXVISABLE];
881
visobj_t *visptr,*visstep,*farthest;
882
 
883
void DrawScaleds (void)
884
{
885
    int      i,least,numvisable,height;
886
    byte     *tilespot,*visspot;
887
    unsigned spotloc;
888
 
889
    statobj_t *statptr;
890
    objtype   *obj;
891
 
892
    visptr = &vislist[0];
893
 
894
//
895
// place static objects
896
//
897
    for (statptr = &statobjlist[0] ; statptr !=laststatobj ; statptr++)
898
    {
899
        if ((visptr->shapenum = statptr->shapenum) == -1)
900
            continue;                                               // object has been deleted
901
 
902
        if (!*statptr->visspot)
903
            continue;                                               // not visable
904
 
905
        if (TransformTile (statptr->tilex,statptr->tiley,
906
            &visptr->viewx,&visptr->viewheight) && statptr->flags & FL_BONUS)
907
        {
908
            GetBonus (statptr);
909
            if(statptr->shapenum == -1)
910
                continue;                                           // object has been taken
911
        }
912
 
913
        if (!visptr->viewheight)
914
            continue;                                               // to close to the object
915
 
916
#ifdef USE_DIR3DSPR
917
        if(statptr->flags & FL_DIR_MASK)
918
            visptr->transsprite=statptr;
919
        else
920
            visptr->transsprite=NULL;
921
#endif
922
 
923
        if (visptr < &vislist[MAXVISABLE-1])    // don't let it overflow
924
        {
925
            visptr->flags = (short) statptr->flags;
926
            visptr++;
927
        }
928
    }
929
 
930
//
931
// place active objects
932
//
933
    for (obj = player->next;obj;obj=obj->next)
934
    {
935
        if ((visptr->shapenum = obj->state->shapenum)==0)
936
            continue;                                               // no shape
937
 
938
        spotloc = (obj->tilex<tiley;   // optimize: keep in struct?
939
        visspot = &spotvis[0][0]+spotloc;
940
        tilespot = &tilemap[0][0]+spotloc;
941
 
942
        //
943
        // could be in any of the nine surrounding tiles
944
        //
945
        if (*visspot
946
            || ( *(visspot-1) && !*(tilespot-1) )
947
            || ( *(visspot+1) && !*(tilespot+1) )
948
            || ( *(visspot-65) && !*(tilespot-65) )
949
            || ( *(visspot-64) && !*(tilespot-64) )
950
            || ( *(visspot-63) && !*(tilespot-63) )
951
            || ( *(visspot+65) && !*(tilespot+65) )
952
            || ( *(visspot+64) && !*(tilespot+64) )
953
            || ( *(visspot+63) && !*(tilespot+63) ) )
954
        {
955
            obj->active = ac_yes;
956
            TransformActor (obj);
957
            if (!obj->viewheight)
958
                continue;                                               // too close or far away
959
 
960
            visptr->viewx = obj->viewx;
961
            visptr->viewheight = obj->viewheight;
962
            if (visptr->shapenum == -1)
963
                visptr->shapenum = obj->temp1;  // special shape
964
 
965
            if (obj->state->rotate)
966
                visptr->shapenum += CalcRotate (obj);
967
 
968
            if (visptr < &vislist[MAXVISABLE-1])    // don't let it overflow
969
            {
970
                visptr->flags = (short) obj->flags;
971
#ifdef USE_DIR3DSPR
972
                visptr->transsprite = NULL;
973
#endif
974
                visptr++;
975
            }
976
            obj->flags |= FL_VISABLE;
977
        }
978
        else
979
            obj->flags &= ~FL_VISABLE;
980
    }
981
 
982
//
983
// draw from back to front
984
//
985
    numvisable = (int) (visptr-&vislist[0]);
986
 
987
    if (!numvisable)
988
        return;                                                                 // no visable objects
989
 
990
    for (i = 0; i
991
    {
992
        least = 32000;
993
        for (visstep=&vislist[0] ; visstep
994
        {
995
            height = visstep->viewheight;
996
            if (height < least)
997
            {
998
                least = height;
999
                farthest = visstep;
1000
            }
1001
        }
1002
        //
1003
        // draw farthest
1004
        //
1005
#ifdef USE_DIR3DSPR
1006
        if(farthest->transsprite)
1007
            Scale3DShape(vbuf, vbufPitch, farthest->transsprite);
1008
        else
1009
#endif
1010
            ScaleShape(farthest->viewx, farthest->shapenum, farthest->viewheight, farthest->flags);
1011
 
1012
        farthest->viewheight = 32000;
1013
    }
1014
}
1015
 
1016
//==========================================================================
1017
 
1018
/*
1019
==============
1020
=
1021
= DrawPlayerWeapon
1022
=
1023
= Draw the player's hands
1024
=
1025
==============
1026
*/
1027
 
1028
int weaponscale[NUMWEAPONS] = {SPR_KNIFEREADY, SPR_PISTOLREADY,
1029
    SPR_MACHINEGUNREADY, SPR_CHAINREADY};
1030
 
1031
void DrawPlayerWeapon (void)
1032
{
1033
    int shapenum;
1034
 
1035
#ifndef SPEAR
1036
    if (gamestate.victoryflag)
1037
    {
1038
#ifndef APOGEE_1_0
1039
        if (player->state == &s_deathcam && (GetTimeCount()&32) )
1040
            SimpleScaleShape(viewwidth/2,SPR_DEATHCAM,viewheight+1);
1041
#endif
1042
        return;
1043
    }
1044
#endif
1045
 
1046
    if (gamestate.weapon != -1)
1047
    {
1048
        shapenum = weaponscale[gamestate.weapon]+gamestate.weaponframe;
1049
        SimpleScaleShape(viewwidth/2,shapenum,viewheight+1);
1050
    }
1051
 
1052
    if (demorecord || demoplayback)
1053
        SimpleScaleShape(viewwidth/2,SPR_DEMO,viewheight+1);
1054
}
1055
 
1056
 
1057
//==========================================================================
1058
 
1059
 
1060
/*
1061
=====================
1062
=
1063
= CalcTics
1064
=
1065
=====================
1066
*/
1067
 
1068
void CalcTics (void)
1069
{
1070
//
1071
// calculate tics since last refresh for adaptive timing
1072
//
1073
    if (lasttimecount > (int32_t) GetTimeCount())
1074
        lasttimecount = GetTimeCount();    // if the game was paused a LONG time
1075
 
1076
    uint32_t curtime = SDL_GetTicks();
1077
    tics = (curtime * 7) / 100 - lasttimecount;
1078
    if(!tics)
1079
    {
1080
        // wait until end of current tic
1081
        SDL_Delay(((lasttimecount + 1) * 100) / 7 - curtime);
1082
        tics = 1;
1083
    }
1084
 
1085
    lasttimecount += tics;
1086
 
1087
    if (tics>MAXTICS)
1088
        tics = MAXTICS;
1089
}
1090
 
1091
 
1092
//==========================================================================
1093
 
1094
void AsmRefresh()
1095
{
1096
    int32_t xstep,ystep;
1097
    longword xpartial,ypartial;
1098
    boolean playerInPushwallBackTile = tilemap[focaltx][focalty] == 64;
1099
 
1100
    for(pixx=0;pixx
1101
    {
1102
        short angl=midangle+pixelangle[pixx];
1103
        if(angl<0) angl+=FINEANGLES;
1104
        if(angl>=3600) angl-=FINEANGLES;
1105
        if(angl<900)
1106
        {
1107
            xtilestep=1;
1108
            ytilestep=-1;
1109
            xstep=finetangent[900-1-angl];
1110
            ystep=-finetangent[angl];
1111
            xpartial=xpartialup;
1112
            ypartial=ypartialdown;
1113
        }
1114
        else if(angl<1800)
1115
        {
1116
            xtilestep=-1;
1117
            ytilestep=-1;
1118
            xstep=-finetangent[angl-900];
1119
            ystep=-finetangent[1800-1-angl];
1120
            xpartial=xpartialdown;
1121
            ypartial=ypartialdown;
1122
        }
1123
        else if(angl<2700)
1124
        {
1125
            xtilestep=-1;
1126
            ytilestep=1;
1127
            xstep=-finetangent[2700-1-angl];
1128
            ystep=finetangent[angl-1800];
1129
            xpartial=xpartialdown;
1130
            ypartial=ypartialup;
1131
        }
1132
        else if(angl<3600)
1133
        {
1134
            xtilestep=1;
1135
            ytilestep=1;
1136
            xstep=finetangent[angl-2700];
1137
            ystep=finetangent[3600-1-angl];
1138
            xpartial=xpartialup;
1139
            ypartial=ypartialup;
1140
        }
1141
        yintercept=FixedMul(ystep,xpartial)+viewy;
1142
        xtile=focaltx+xtilestep;
1143
        xspot=(word)((xtile<>16));
1144
        xintercept=FixedMul(xstep,ypartial)+viewx;
1145
        ytile=focalty+ytilestep;
1146
        yspot=(word)((((uint32_t)xintercept>>16)<
1147
        texdelta=0;
1148
 
1149
        // Special treatment when player is in back tile of pushwall
1150
        if(playerInPushwallBackTile)
1151
        {
1152
            if(    pwalldir == di_east && xtilestep ==  1
1153
                || pwalldir == di_west && xtilestep == -1)
1154
            {
1155
                int32_t yintbuf = yintercept - ((ystep * (64 - pwallpos)) >> 6);
1156
                if((yintbuf >> 16) == focalty)   // ray hits pushwall back?
1157
                {
1158
                    if(pwalldir == di_east)
1159
                        xintercept = (focaltx << TILESHIFT) + (pwallpos << 10);
1160
                    else
1161
                        xintercept = (focaltx << TILESHIFT) - TILEGLOBAL + ((64 - pwallpos) << 10);
1162
                    yintercept = yintbuf;
1163
                    ytile = (short) (yintercept >> TILESHIFT);
1164
                    tilehit = pwalltile;
1165
                    HitVertWall();
1166
                    continue;
1167
                }
1168
            }
1169
            else if(pwalldir == di_south && ytilestep ==  1
1170
                ||  pwalldir == di_north && ytilestep == -1)
1171
            {
1172
                int32_t xintbuf = xintercept - ((xstep * (64 - pwallpos)) >> 6);
1173
                if((xintbuf >> 16) == focaltx)   // ray hits pushwall back?
1174
                {
1175
                    xintercept = xintbuf;
1176
                    if(pwalldir == di_south)
1177
                        yintercept = (focalty << TILESHIFT) + (pwallpos << 10);
1178
                    else
1179
                        yintercept = (focalty << TILESHIFT) - TILEGLOBAL + ((64 - pwallpos) << 10);
1180
                    xtile = (short) (xintercept >> TILESHIFT);
1181
                    tilehit = pwalltile;
1182
                    HitHorizWall();
1183
                    continue;
1184
                }
1185
            }
1186
        }
1187
 
1188
        do
1189
        {
1190
            if(ytilestep==-1 && (yintercept>>16)<=ytile) goto horizentry;
1191
            if(ytilestep==1 && (yintercept>>16)>=ytile) goto horizentry;
1192
vertentry:
1193
            if((uint32_t)yintercept>mapheight*65536-1 || (word)xtile>=mapwidth)
1194
            {
1195
                if(xtile<0) xintercept=0, xtile=0;
1196
                else if(xtile>=mapwidth) xintercept=mapwidth<
1197
                else xtile=(short) (xintercept >> TILESHIFT);
1198
                if(yintercept<0) yintercept=0, ytile=0;
1199
                else if(yintercept>=(mapheight<
1200
                yspot=0xffff;
1201
                tilehit=0;
1202
                HitHorizBorder();
1203
                break;
1204
            }
1205
            if(xspot>=maparea) break;
1206
            tilehit=((byte *)tilemap)[xspot];
1207
            if(tilehit)
1208
            {
1209
                if(tilehit&0x80)
1210
                {
1211
                    int32_t yintbuf=yintercept+(ystep>>1);
1212
                    if((yintbuf>>16)!=(yintercept>>16))
1213
                        goto passvert;
1214
                    if((word)yintbuf
1215
                        goto passvert;
1216
                    yintercept=yintbuf;
1217
                    xintercept=(xtile<
1218
                    ytile = (short) (yintercept >> TILESHIFT);
1219
                    HitVertDoor();
1220
                }
1221
                else
1222
                {
1223
                    if(tilehit==64)
1224
                    {
1225
                        if(pwalldir==di_west || pwalldir==di_east)
1226
                        {
1227
	                        int32_t yintbuf;
1228
                            int pwallposnorm;
1229
                            int pwallposinv;
1230
                            if(pwalldir==di_west)
1231
                            {
1232
                                pwallposnorm = 64-pwallpos;
1233
                                pwallposinv = pwallpos;
1234
                            }
1235
                            else
1236
                            {
1237
                                pwallposnorm = pwallpos;
1238
                                pwallposinv = 64-pwallpos;
1239
                            }
1240
                            if(pwalldir == di_east && xtile==pwallx && ((uint32_t)yintercept>>16)==pwally
1241
                                || pwalldir == di_west && !(xtile==pwallx && ((uint32_t)yintercept>>16)==pwally))
1242
                            {
1243
                                yintbuf=yintercept+((ystep*pwallposnorm)>>6);
1244
                                if((yintbuf>>16)!=(yintercept>>16))
1245
                                    goto passvert;
1246
 
1247
                                xintercept=(xtile<
1248
                                yintercept=yintbuf;
1249
                                ytile = (short) (yintercept >> TILESHIFT);
1250
                                tilehit=pwalltile;
1251
                                HitVertWall();
1252
                            }
1253
                            else
1254
                            {
1255
                                yintbuf=yintercept+((ystep*pwallposinv)>>6);
1256
                                if((yintbuf>>16)!=(yintercept>>16))
1257
                                    goto passvert;
1258
 
1259
                                xintercept=(xtile<
1260
                                yintercept=yintbuf;
1261
                                ytile = (short) (yintercept >> TILESHIFT);
1262
                                tilehit=pwalltile;
1263
                                HitVertWall();
1264
                            }
1265
                        }
1266
                        else
1267
                        {
1268
                            int pwallposi = pwallpos;
1269
                            if(pwalldir==di_north) pwallposi = 64-pwallpos;
1270
                            if(pwalldir==di_south && (word)yintercept<(pwallposi<<10)
1271
                                || pwalldir==di_north && (word)yintercept>(pwallposi<<10))
1272
                            {
1273
                                if(((uint32_t)yintercept>>16)==pwally && xtile==pwallx)
1274
                                {
1275
                                    if(pwalldir==di_south && (int32_t)((word)yintercept)+ystep<(pwallposi<<10)
1276
                                            || pwalldir==di_north && (int32_t)((word)yintercept)+ystep>(pwallposi<<10))
1277
                                        goto passvert;
1278
 
1279
                                    if(pwalldir==di_south)
1280
                                        yintercept=(yintercept&0xffff0000)+(pwallposi<<10);
1281
                                    else
1282
                                        yintercept=(yintercept&0xffff0000)-TILEGLOBAL+(pwallposi<<10);
1283
                                    xintercept=xintercept-((xstep*(64-pwallpos))>>6);
1284
                                    xtile = (short) (xintercept >> TILESHIFT);
1285
                                    tilehit=pwalltile;
1286
                                    HitHorizWall();
1287
                                }
1288
                                else
1289
                                {
1290
                                    texdelta = -(pwallposi<<10);
1291
                                    xintercept=xtile<
1292
                                    ytile = (short) (yintercept >> TILESHIFT);
1293
                                    tilehit=pwalltile;
1294
                                    HitVertWall();
1295
                                }
1296
                            }
1297
                            else
1298
                            {
1299
                                if(((uint32_t)yintercept>>16)==pwally && xtile==pwallx)
1300
                                {
1301
                                    texdelta = -(pwallposi<<10);
1302
                                    xintercept=xtile<
1303
                                    ytile = (short) (yintercept >> TILESHIFT);
1304
                                    tilehit=pwalltile;
1305
                                    HitVertWall();
1306
                                }
1307
                                else
1308
                                {
1309
                                    if(pwalldir==di_south && (int32_t)((word)yintercept)+ystep>(pwallposi<<10)
1310
                                            || pwalldir==di_north && (int32_t)((word)yintercept)+ystep<(pwallposi<<10))
1311
                                        goto passvert;
1312
 
1313
                                    if(pwalldir==di_south)
1314
                                        yintercept=(yintercept&0xffff0000)-((64-pwallpos)<<10);
1315
                                    else
1316
                                        yintercept=(yintercept&0xffff0000)+((64-pwallpos)<<10);
1317
                                    xintercept=xintercept-((xstep*pwallpos)>>6);
1318
                                    xtile = (short) (xintercept >> TILESHIFT);
1319
                                    tilehit=pwalltile;
1320
                                    HitHorizWall();
1321
                                }
1322
                            }
1323
                        }
1324
                    }
1325
                    else
1326
                    {
1327
                        xintercept=xtile<
1328
                        ytile = (short) (yintercept >> TILESHIFT);
1329
                        HitVertWall();
1330
                    }
1331
                }
1332
                break;
1333
            }
1334
passvert:
1335
            *((byte *)spotvis+xspot)=1;
1336
            xtile+=xtilestep;
1337
            yintercept+=ystep;
1338
            xspot=(word)((xtile<>16));
1339
        }
1340
        while(1);
1341
        continue;
1342
 
1343
        do
1344
        {
1345
            if(xtilestep==-1 && (xintercept>>16)<=xtile) goto vertentry;
1346
            if(xtilestep==1 && (xintercept>>16)>=xtile) goto vertentry;
1347
horizentry:
1348
            if((uint32_t)xintercept>mapwidth*65536-1 || (word)ytile>=mapheight)
1349
            {
1350
                if(ytile<0) yintercept=0, ytile=0;
1351
                else if(ytile>=mapheight) yintercept=mapheight<
1352
                else ytile=(short) (yintercept >> TILESHIFT);
1353
                if(xintercept<0) xintercept=0, xtile=0;
1354
                else if(xintercept>=(mapwidth<
1355
                xspot=0xffff;
1356
                tilehit=0;
1357
                HitVertBorder();
1358
                break;
1359
            }
1360
            if(yspot>=maparea) break;
1361
            tilehit=((byte *)tilemap)[yspot];
1362
            if(tilehit)
1363
            {
1364
                if(tilehit&0x80)
1365
                {
1366
                    int32_t xintbuf=xintercept+(xstep>>1);
1367
                    if((xintbuf>>16)!=(xintercept>>16))
1368
                        goto passhoriz;
1369
                    if((word)xintbuf
1370
                        goto passhoriz;
1371
                    xintercept=xintbuf;
1372
                    yintercept=(ytile<
1373
                    xtile = (short) (xintercept >> TILESHIFT);
1374
                    HitHorizDoor();
1375
                }
1376
                else
1377
                {
1378
                    if(tilehit==64)
1379
                    {
1380
                        if(pwalldir==di_north || pwalldir==di_south)
1381
                        {
1382
                            int32_t xintbuf;
1383
                            int pwallposnorm;
1384
                            int pwallposinv;
1385
                            if(pwalldir==di_north)
1386
                            {
1387
                                pwallposnorm = 64-pwallpos;
1388
                                pwallposinv = pwallpos;
1389
                            }
1390
                            else
1391
                            {
1392
                                pwallposnorm = pwallpos;
1393
                                pwallposinv = 64-pwallpos;
1394
                            }
1395
                            if(pwalldir == di_south && ytile==pwally && ((uint32_t)xintercept>>16)==pwallx
1396
                                || pwalldir == di_north && !(ytile==pwally && ((uint32_t)xintercept>>16)==pwallx))
1397
                            {
1398
                                xintbuf=xintercept+((xstep*pwallposnorm)>>6);
1399
                                if((xintbuf>>16)!=(xintercept>>16))
1400
                                    goto passhoriz;
1401
 
1402
                                yintercept=(ytile<
1403
                                xintercept=xintbuf;
1404
                                xtile = (short) (xintercept >> TILESHIFT);
1405
                                tilehit=pwalltile;
1406
                                HitHorizWall();
1407
                            }
1408
                            else
1409
                            {
1410
                                xintbuf=xintercept+((xstep*pwallposinv)>>6);
1411
                                if((xintbuf>>16)!=(xintercept>>16))
1412
                                    goto passhoriz;
1413
 
1414
                                yintercept=(ytile<
1415
                                xintercept=xintbuf;
1416
                                xtile = (short) (xintercept >> TILESHIFT);
1417
                                tilehit=pwalltile;
1418
                                HitHorizWall();
1419
                            }
1420
                        }
1421
                        else
1422
                        {
1423
                            int pwallposi = pwallpos;
1424
                            if(pwalldir==di_west) pwallposi = 64-pwallpos;
1425
                            if(pwalldir==di_east && (word)xintercept<(pwallposi<<10)
1426
                                    || pwalldir==di_west && (word)xintercept>(pwallposi<<10))
1427
                            {
1428
                                if(((uint32_t)xintercept>>16)==pwallx && ytile==pwally)
1429
                                {
1430
                                    if(pwalldir==di_east && (int32_t)((word)xintercept)+xstep<(pwallposi<<10)
1431
                                            || pwalldir==di_west && (int32_t)((word)xintercept)+xstep>(pwallposi<<10))
1432
                                        goto passhoriz;
1433
 
1434
                                    if(pwalldir==di_east)
1435
                                        xintercept=(xintercept&0xffff0000)+(pwallposi<<10);
1436
                                    else
1437
                                        xintercept=(xintercept&0xffff0000)-TILEGLOBAL+(pwallposi<<10);
1438
                                    yintercept=yintercept-((ystep*(64-pwallpos))>>6);
1439
                                    ytile = (short) (yintercept >> TILESHIFT);
1440
                                    tilehit=pwalltile;
1441
                                    HitVertWall();
1442
                                }
1443
                                else
1444
                                {
1445
                                    texdelta = -(pwallposi<<10);
1446
                                    yintercept=ytile<
1447
                                    xtile = (short) (xintercept >> TILESHIFT);
1448
                                    tilehit=pwalltile;
1449
                                    HitHorizWall();
1450
                                }
1451
                            }
1452
                            else
1453
                            {
1454
                                if(((uint32_t)xintercept>>16)==pwallx && ytile==pwally)
1455
                                {
1456
                                    texdelta = -(pwallposi<<10);
1457
                                    yintercept=ytile<
1458
                                    xtile = (short) (xintercept >> TILESHIFT);
1459
                                    tilehit=pwalltile;
1460
                                    HitHorizWall();
1461
                                }
1462
                                else
1463
                                {
1464
                                    if(pwalldir==di_east && (int32_t)((word)xintercept)+xstep>(pwallposi<<10)
1465
                                            || pwalldir==di_west && (int32_t)((word)xintercept)+xstep<(pwallposi<<10))
1466
                                        goto passhoriz;
1467
 
1468
                                    if(pwalldir==di_east)
1469
                                        xintercept=(xintercept&0xffff0000)-((64-pwallpos)<<10);
1470
                                    else
1471
                                        xintercept=(xintercept&0xffff0000)+((64-pwallpos)<<10);
1472
                                    yintercept=yintercept-((ystep*pwallpos)>>6);
1473
                                    ytile = (short) (yintercept >> TILESHIFT);
1474
                                    tilehit=pwalltile;
1475
                                    HitVertWall();
1476
                                }
1477
                            }
1478
                        }
1479
                    }
1480
                    else
1481
                    {
1482
                        yintercept=ytile<
1483
                        xtile = (short) (xintercept >> TILESHIFT);
1484
                        HitHorizWall();
1485
                    }
1486
                }
1487
                break;
1488
            }
1489
passhoriz:
1490
            *((byte *)spotvis+yspot)=1;
1491
            ytile+=ytilestep;
1492
            xintercept+=xstep;
1493
            yspot=(word)((((uint32_t)xintercept>>16)<
1494
        }
1495
        while(1);
1496
    }
1497
}
1498
 
1499
/*
1500
====================
1501
=
1502
= WallRefresh
1503
=
1504
====================
1505
*/
1506
 
1507
void WallRefresh (void)
1508
{
1509
    xpartialdown = viewx&(TILEGLOBAL-1);
1510
    xpartialup = TILEGLOBAL-xpartialdown;
1511
    ypartialdown = viewy&(TILEGLOBAL-1);
1512
    ypartialup = TILEGLOBAL-ypartialdown;
1513
 
1514
    min_wallheight = viewheight;
1515
    lastside = -1;                  // the first pixel is on a new wall
1516
    AsmRefresh ();
1517
    ScalePost ();                   // no more optimization on last post
1518
}
1519
 
1520
void CalcViewVariables()
1521
{
1522
    viewangle = player->angle;
1523
    midangle = viewangle*(FINEANGLES/ANGLES);
1524
    viewsin = sintable[viewangle];
1525
    viewcos = costable[viewangle];
1526
    viewx = player->x - FixedMul(focallength,viewcos);
1527
    viewy = player->y + FixedMul(focallength,viewsin);
1528
 
1529
    focaltx = (short)(viewx>>TILESHIFT);
1530
    focalty = (short)(viewy>>TILESHIFT);
1531
 
1532
    viewtx = (short)(player->x >> TILESHIFT);
1533
    viewty = (short)(player->y >> TILESHIFT);
1534
}
1535
 
1536
//==========================================================================
1537
 
1538
/*
1539
========================
1540
=
1541
= ThreeDRefresh
1542
=
1543
========================
1544
*/
1545
 
1546
void    ThreeDRefresh (void)
1547
{
1548
//
1549
// clear out the traced array
1550
//
1551
    memset(spotvis,0,maparea);
1552
    spotvis[player->tilex][player->tiley] = 1;       // Detect all sprites over player fix
1553
 
1554
    vbuf = VL_LockSurface(screenBuffer);
1555
    if(vbuf == NULL) return;
1556
 
1557
    vbuf += screenofs;
1558
    vbufPitch = bufferPitch;
1559
 
1560
    CalcViewVariables();
1561
 
1562
//
1563
// follow the walls from there to the right, drawing as we go
1564
//
1565
    VGAClearScreen ();
1566
#if defined(USE_FEATUREFLAGS) && defined(USE_STARSKY)
1567
    if(GetFeatureFlags() & FF_STARSKY)
1568
        DrawStarSky(vbuf, vbufPitch);
1569
#endif
1570
 
1571
    WallRefresh ();
1572
 
1573
#if defined(USE_FEATUREFLAGS) && defined(USE_PARALLAX)
1574
    if(GetFeatureFlags() & FF_PARALLAXSKY)
1575
        DrawParallax(vbuf, vbufPitch);
1576
#endif
1577
#if defined(USE_FEATUREFLAGS) && defined(USE_CLOUDSKY)
1578
    if(GetFeatureFlags() & FF_CLOUDSKY)
1579
        DrawClouds(vbuf, vbufPitch, min_wallheight);
1580
#endif
1581
#ifdef USE_FLOORCEILINGTEX
1582
    DrawFloorAndCeiling(vbuf, vbufPitch, min_wallheight);
1583
#endif
1584
 
1585
//
1586
// draw all the scaled images
1587
//
1588
    DrawScaleds();                  // draw scaled stuff
1589
 
1590
#if defined(USE_FEATUREFLAGS) && defined(USE_RAIN)
1591
    if(GetFeatureFlags() & FF_RAIN)
1592
        DrawRain(vbuf, vbufPitch);
1593
#endif
1594
#if defined(USE_FEATUREFLAGS) && defined(USE_SNOW)
1595
    if(GetFeatureFlags() & FF_SNOW)
1596
        DrawSnow(vbuf, vbufPitch);
1597
#endif
1598
 
1599
    DrawPlayerWeapon ();    // draw player's hands
1600
 
1601
    if(Keyboard[sc_Tab] && viewsize == 21 && gamestate.weapon != -1)
1602
        ShowActStatus();
1603
 
1604
    VL_UnlockSurface(screenBuffer);
1605
    vbuf = NULL;
1606
 
1607
//
1608
// show screen and time last cycle
1609
//
1610
 
1611
    if (fizzlein)
1612
    {
1613
        FizzleFade(screenBuffer, 0, 0, screenWidth, screenHeight, 20, false);
1614
        fizzlein = false;
1615
 
1616
        lasttimecount = GetTimeCount();          // don't make a big tic count
1617
    }
1618
    else
1619
    {
1620
#ifndef REMDEBUG
1621
        if (fpscounter)
1622
        {
1623
            fontnumber = 0;
1624
            SETFONTCOLOR(7,127);
1625
            PrintX=4; PrintY=1;
1626
            VWB_Bar(0,0,50,10,bordercol);
1627
            US_PrintSigned(fps);
1628
            US_Print(" fps");
1629
        }
1630
#endif
1631
        SDL_BlitSurface(screenBuffer, NULL, screen, NULL);
1632
        SDL_Flip(screen);
1633
    }
1634
 
1635
#ifndef REMDEBUG
1636
    if (fpscounter)
1637
    {
1638
        fps_frames++;
1639
        fps_time+=tics;
1640
 
1641
        if(fps_time>35)
1642
        {
1643
            fps_time-=35;
1644
            fps=fps_frames<<1;
1645
            fps_frames=0;
1646
        }
1647
    }
1648
#endif
1649
}