Subversion Repositories Kolibri OS

Rev

Rev 8557 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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