Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8557 maxcodehac 1
#include "version.h"
2
 
3
#ifdef USE_DIR3DSPR
4
#include "wl_def.h"
5
#include "wl_shade.h"
6
 
7
// Define directional 3d sprites in wl_act1.cpp (there are two examples)
8
// Make sure you have according entries in ScanInfoPlane in wl_game.cpp.
9
 
10
 
11
void Scale3DShaper(int x1, int x2, int shapenum, uint32_t flags, fixed ny1, fixed ny2,
12
                   fixed nx1, fixed nx2, byte *vbuf, unsigned vbufPitch)
13
{
14
    t_compshape *shape;
15
    unsigned scale1,starty,endy;
16
    word *cmdptr;
17
    byte *line;
18
    byte *vmem;
19
    int dx,len,i,newstart,ycnt,pixheight,screndy,upperedge,scrstarty;
20
    unsigned j;
21
    fixed height,dheight,height1,height2;
22
    int xpos[TEXTURESIZE+1];
23
    int slinex;
24
    fixed dxx=(ny2-ny1)<<8,dzz=(nx2-nx1)<<8;
25
    fixed dxa=0,dza=0;
26
    byte col;
27
 
28
    shape = (t_compshape *) PM_GetSprite(shapenum);
29
 
30
    len=shape->rightpix-shape->leftpix+1;
31
    if(!len) return;
32
 
33
    ny1+=dxx>>9;
34
    nx1+=dzz>>9;
35
 
36
    dxa=-(dxx>>1),dza=-(dzz>>1);
37
    dxx>>=TEXTURESHIFT,dzz>>=TEXTURESHIFT;
38
    dxa+=shape->leftpix*dxx,dza+=shape->leftpix*dzz;
39
 
40
    xpos[0]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);
41
    height1 = heightnumerator/((nx1+(dza>>8))>>8);
42
    height=(((fixed)height1)<<12)+2048;
43
 
44
    for(i=1;i<=len;i++)
45
    {
46
        dxa+=dxx,dza+=dzz;
47
        xpos[i]=(int)((ny1+(dxa>>8))*scale/(nx1+(dza>>8))+centerx);
48
        if(xpos[i-1]>viewwidth) break;
49
    }
50
    len=i-1;
51
    dx = xpos[len] - xpos[0];
52
    if(!dx) return;
53
 
54
    height2 = heightnumerator/((nx1+(dza>>8))>>8);
55
    dheight=(((fixed)height2-(fixed)height1)<<12)/(fixed)dx;
56
 
57
    cmdptr = (word *) shape->dataofs;
58
 
59
    i=0;
60
    if(x2>viewwidth) x2=viewwidth;
61
 
62
    for(i=0;i
63
    {
64
        for(slinex=xpos[i];slinex
65
        {
66
            height+=dheight;
67
            if(slinex<0) continue;
68
 
69
            scale1=(unsigned)(height>>15);
70
 
71
            if(wallheight[slinex]<(height>>12) && scale1 /*&& scale1<=maxscale*/)
72
            {
73
#ifdef USE_SHADING
74
                byte *curshades;
75
                if(flags & FL_FULLBRIGHT)
76
                    curshades = shadetable[0];
77
                else
78
                    curshades = shadetable[GetShade(scale1<<3)];
79
#endif
80
 
81
                pixheight=scale1*SPRITESCALEFACTOR;
82
                upperedge=viewheight/2-scale1;
83
 
84
                line=(byte *)shape + cmdptr[i];
85
 
86
                while((endy = READWORD(line)) != 0)
87
                {
88
                    endy >>= 1;
89
                    newstart = READWORD(line);
90
                    starty = READWORD(line) >> 1;
91
                    j=starty;
92
                    ycnt=j*pixheight;
93
                    screndy=(ycnt>>6)+upperedge;
94
                    if(screndy<0) vmem=vbuf+slinex;
95
                    else vmem=vbuf+screndy*vbufPitch+slinex;
96
                    for(;j
97
                    {
98
                        scrstarty=screndy;
99
                        ycnt+=pixheight;
100
                        screndy=(ycnt>>6)+upperedge;
101
                        if(scrstarty!=screndy && screndy>0)
102
                        {
103
#ifdef USE_SHADING
104
                            col=curshades[((byte *)shape)[newstart+j]];
105
#else
106
                            col=((byte *)shape)[newstart+j];
107
#endif
108
                            if(scrstarty<0) scrstarty=0;
109
                            if(screndy>viewheight) screndy=viewheight,j=endy;
110
 
111
                            while(scrstarty
112
                            {
113
                                *vmem=col;
114
                                vmem+=vbufPitch;
115
                                scrstarty++;
116
                            }
117
                        }
118
                    }
119
                }
120
            }
121
        }
122
    }
123
}
124
 
125
void Scale3DShape(byte *vbuf, unsigned vbufPitch, statobj_t *ob)
126
{
127
    fixed nx1,nx2,ny1,ny2;
128
    int viewx1,viewx2;
129
    fixed diradd;
130
    fixed playx = viewx;
131
    fixed playy = viewy;
132
 
133
    //
134
    // the following values for "diradd" aren't optimized yet
135
    // if you have problems with sprites being visible through wall edges
136
    // where they shouldn't, you can try to adjust these values and SIZEADD
137
    //
138
 
139
#define SIZEADD 1024
140
 
141
    switch(ob->flags & FL_DIR_POS_MASK)
142
    {
143
        case FL_DIR_POS_FW: diradd=0x7ff0+0x8000; break;
144
        case FL_DIR_POS_BW: diradd=-0x7ff0+0x8000; break;
145
        case FL_DIR_POS_MID: diradd=0x8000; break;
146
        default:
147
            Quit("Unknown directional 3d sprite position (shapenum = %i)", ob->shapenum);
148
    }
149
 
150
    if(ob->flags & FL_DIR_VERT_FLAG)     // vertical dir 3d sprite
151
    {
152
        fixed gy1,gy2,gx,gyt1,gyt2,gxt;
153
        //
154
        // translate point to view centered coordinates
155
        //
156
        gy1 = (((long)ob->tiley) << TILESHIFT)+0x8000-playy-0x8000L-SIZEADD;
157
        gy2 = gy1+0x10000L+2*SIZEADD;
158
        gx = (((long)ob->tilex) << TILESHIFT)+diradd-playx;
159
 
160
        //
161
        // calculate newx
162
        //
163
        gxt = FixedMul(gx,viewcos);
164
        gyt1 = FixedMul(gy1,viewsin);
165
        gyt2 = FixedMul(gy2,viewsin);
166
        nx1 = gxt-gyt1;
167
        nx2 = gxt-gyt2;
168
 
169
        //
170
        // calculate newy
171
        //
172
        gxt = FixedMul(gx,viewsin);
173
        gyt1 = FixedMul(gy1,viewcos);
174
        gyt2 = FixedMul(gy2,viewcos);
175
        ny1 = gyt1+gxt;
176
        ny2 = gyt2+gxt;
177
    }
178
    else                                    // horizontal dir 3d sprite
179
    {
180
        fixed gx1,gx2,gy,gxt1,gxt2,gyt;
181
        //
182
        // translate point to view centered coordinates
183
        //
184
        gx1 = (((long)ob->tilex) << TILESHIFT)+0x8000-playx-0x8000L-SIZEADD;
185
        gx2 = gx1+0x10000L+2*SIZEADD;
186
        gy = (((long)ob->tiley) << TILESHIFT)+diradd-playy;
187
 
188
        //
189
        // calculate newx
190
        //
191
        gxt1 = FixedMul(gx1,viewcos);
192
        gxt2 = FixedMul(gx2,viewcos);
193
        gyt = FixedMul(gy,viewsin);
194
        nx1 = gxt1-gyt;
195
        nx2 = gxt2-gyt;
196
 
197
        //
198
        // calculate newy
199
        //
200
        gxt1 = FixedMul(gx1,viewsin);
201
        gxt2 = FixedMul(gx2,viewsin);
202
        gyt = FixedMul(gy,viewcos);
203
        ny1 = gyt+gxt1;
204
        ny2 = gyt+gxt2;
205
    }
206
 
207
    if(nx1 < 0 || nx2 < 0) return;      // TODO: Clip on viewplane
208
 
209
    //
210
    // calculate perspective ratio
211
    //
212
    if(nx1>=0 && nx1<=1792) nx1=1792;
213
    if(nx1<0 && nx1>=-1792) nx1=-1792;
214
    if(nx2>=0 && nx2<=1792) nx2=1792;
215
    if(nx2<0 && nx2>=-1792) nx2=-1792;
216
 
217
    viewx1=(int)(centerx+ny1*scale/nx1);
218
    viewx2=(int)(centerx+ny2*scale/nx2);
219
 
220
    if(viewx2 < viewx1)
221
    {
222
        Scale3DShaper(viewx2,viewx1,ob->shapenum,ob->flags,ny2,ny1,nx2,nx1,vbuf,vbufPitch);
223
    }
224
    else
225
    {
226
        Scale3DShaper(viewx1,viewx2,ob->shapenum,ob->flags,ny1,ny2,nx1,nx2,vbuf,vbufPitch);
227
    }
228
}
229
 
230
#endif