summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/wl_dir3dspr.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/wl_dir3dspr.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/wl_dir3dspr.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/wl_dir3dspr.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/wl_dir3dspr.c b/apps/plugins/sdl/progs/wolf3d/wl_dir3dspr.c
new file mode 100644
index 0000000000..4bae691621
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/wl_dir3dspr.c
@@ -0,0 +1,230 @@
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
11void 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<len;i++)
63 {
64 for(slinex=xpos[i];slinex<xpos[i+1] && slinex<x2;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<endy;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<screndy)
112 {
113 *vmem=col;
114 vmem+=vbufPitch;
115 scrstarty++;
116 }
117 }
118 }
119 }
120 }
121 }
122 }
123}
124
125void 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