DEADSOFTWARE

50f02fdf16b7d6afe30e9aa32ed60da50e33167f
[flatwaifu.git] / src / miscc.c
1 /*
2 Copyright (C) Prikol Software 1996-1997
3 Copyright (C) Aleksey Volynskov 1996-1997
4 Copyright (C) <ARembo@gmail.com> 2011
6 This file is part of the Doom2D:Rembo project.
8 Doom2D:Rembo is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation.
12 Doom2D:Rembo is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/> or
19 write to the Free Software Foundation, Inc.,
20 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
23 #include "glob.h"
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include "files.h"
29 #include "memory.h"
30 #include "sound.h"
31 #include "view.h"
32 #include "bmap.h"
33 #include "dots.h"
34 #include "monster.h"
35 #include "misc.h"
36 #include "render.h"
38 //#define WD 200
39 //#define HT 98
41 #define MAX_YV 30
43 byte z_dot;
44 byte z_mon;
45 static void *bulsnd[2];
46 static byte wfront;
48 int Z_sign(int a) {
49 if(a>0) return 1;
50 if(a<0) return -1;
51 return 0;
52 }
54 int Z_dec(int a,int b) {
55 if(abs(a)<=b) return 0;
56 if(a>0) return a-b;
57 if(a<0) return a+b;
58 return 0;
59 }
61 void *Z_getsnd(char n[6]) {
62 char s[8];
63 s[0] = 'D';
64 s[1] = 'S';
65 strncpy(&s[2], n, 6);
66 return S_load(s);
67 }
69 int Z_sound (void *s, int v) {
70 if (s != NULL) {
71 S_play(s, 0, v);
72 // TODO ???
73 //S_play(s, -1, 1024, v);
74 //return F_getreslen(((int*)s)[-1])/605;
75 return 0;
76 } else {
77 return 0;
78 }
79 }
81 #define GAS_START (MN__LAST-MN_DEMON+5)
82 #define GAS_TOTAL (MN__LAST-MN_DEMON+16+10)
84 void Z_initst(void) {
85 bulsnd[0]=Z_getsnd("BUL1");
86 bulsnd[1]=Z_getsnd("BUL2");
87 }
89 int Z_canstand(int x,int y,int r) {
90 int i;
92 i=(x-r)/CELW;
93 x=(x+r)/CELW;
94 y=(y+1)/CELH;
95 if(y>=FLDH || y<0) return 0;
96 if(i<0) i=0;
97 if(x>=FLDW) x=FLDW-1;
98 for(;i<=x;++i)
99 if(fld[y][i]==1 || fld[y][i]==2 || fld[y][i]==4)
100 if(!z_dot) return 1;
101 else if(!((walf[fldf[y][i]]|walf[fldb[y][i]])&2)) return 1;
102 return 0;
105 static int Z_hitceil(int x,int y,int r,int h) {
106 int i;
108 i=(x-r)/CELW;
109 x=(x+r)/CELW;
110 y=(y-h+1)/CELH;
111 if(y>=FLDH || y<0) return 0;
112 if(i<0) i=0;
113 if(x>=FLDW) x=FLDW-1;
114 for(;i<=x;++i)
115 if(fld[y][i]==1 || fld[y][i]==2)
116 if(!z_dot) return 1;
117 else if(!((walf[fldf[y][i]]|walf[fldb[y][i]])&2)) return 1;
118 return 0;
121 int Z_canfit(int x,int y,int r,int h) {
122 int i,j,sx,sy;
124 sx=(x-r)/CELW;
125 sy=(y-h+1)/CELH;
126 if(sx<0) sx=0;
127 if(sy<0) sy=0;
128 x=(x+r)/CELW;
129 y=(y-0)/CELH;
130 if(x>=FLDW) x=FLDW-1;
131 if(y>=FLDH) y=FLDH-1;
132 for(i=sx;i<=x;++i)
133 for(j=sy;j<=y;++j)
134 if(fld[j][i]==1 || fld[j][i]==2)
135 if(!z_dot) return 0;
136 else if(!((walf[fldf[j][i]]|walf[fldb[j][i]])&2)) return 0;
137 return 1;
140 static int Z_inlift(int x,int y,int r,int h) {
141 int i,j,sx,sy;
143 sx=(x-r)/CELW;
144 sy=(y-h+1)/CELH;
145 if(sx<0) sx=0;
146 if(sy<0) sy=0;
147 x=(x+r)/CELW;
148 y=(y-1)/CELH;
149 if(x>=FLDW) x=FLDW-1;
150 if(y>=FLDH) y=FLDH-1;
151 for(i=sx;i<=x;++i)
152 for(j=sy;j<=y;++j)
153 if(fld[j][i]==9 || fld[j][i]==10) return fld[j][i]-8;
154 return 0;
157 static int Z_isblocked(int x,int y,int r,int h,int xv) {
158 int i,j,sx,sy;
160 sx=(x-r)/CELW;
161 sy=(y-h+1)/CELH;
162 if(sx<0) sx=0;
163 if(sy<0) sy=0;
164 x=(x+r)/CELW;
165 y=(y-1)/CELH;
166 if(xv<0) x=sx;
167 else if(xv>0) sx=x;
168 if(x>=FLDW) x=FLDW-1;
169 if(y>=FLDH) y=FLDH-1;
170 for(i=sx;i<=x;++i)
171 for(j=sy;j<=y;++j)
172 if(fld[j][i]==8) return 1;
173 return 0;
176 int Z_istrapped(int x,int y,int r,int h) {
177 int i,j,sx,sy;
179 sx=(x-r)/CELW;
180 sy=(y-h+1)/CELH;
181 if(sx<0) sx=0;
182 if(sy<0) sy=0;
183 x=(x+r)/CELW;
184 y=(y-1)/CELH;
185 if(x>=FLDW) x=FLDW-1;
186 if(y>=FLDH) y=FLDH-1;
187 for(i=sx;i<=x;++i)
188 for(j=sy;j<=y;++j)
189 if(fld[j][i]==255) return 1;
190 return 0;
193 void Z_set_speed(obj_t *o,int s) {
194 int m;
196 if(!(m=max(abs(o->xv),abs(o->yv)))) m=1;
197 o->xv=o->xv*s/m;o->yv=o->yv*s/m;
200 int Z_inwater(int x,int y,int r,int h) {
201 int i,j,sx,sy;
203 sx=(x-r)/CELW;
204 sy=(y-h+1)/CELH;
205 if(sx<0) sx=0;
206 if(sy<0) sy=0;
207 x=(x+r)/CELW;
208 y=(y-h/2)/CELH;
209 if(x>=FLDW) x=FLDW-1;
210 if(y>=FLDH) y=FLDH-1;
211 for(i=sx;i<=x;++i)
212 for(j=sy;j<=y;++j)
213 if(fld[j][i]>=5 && fld[j][i]<=7) {wfront=fldf[j][i];return 1;}
214 return 0;
217 int Z_getacid(int x,int y,int r,int h) {
218 int i,j,sx,sy,a;
219 static byte tab[4]={0,5,10,20};
221 a=0;
222 sx=(x-r)/CELW;
223 sy=(y-h+1)/CELH;
224 if(sx<0) sx=0;
225 if(sy<0) sy=0;
226 x=(x+r)/CELW;
227 y=y/CELH;
228 if(x>=FLDW) x=FLDW-1;
229 if(y>=FLDH) y=FLDH-1;
230 for(i=sx;i<=x;++i)
231 for(j=sy;j<=y;++j)
232 if(fld[j][i]==6) a|=1;
233 else if(fld[j][i]==7) a|=2;
234 return tab[a];
237 int Z_canbreathe(int x,int y,int r,int h) {
238 int i,j,sx,sy;
240 sx=(x-r)/CELW;
241 sy=(y-h+1)/CELH;
242 if(sx<0) sx=0;
243 if(sy<0) sy=0;
244 x=(x+r)/CELW;
245 y=(y-h/2)/CELH;
246 if(x>=FLDW) x=FLDW-1;
247 if(y>=FLDH) y=FLDH-1;
248 if(sx>x || sy>y) return 1;
249 for(i=sx;i<=x;++i)
250 for(j=sy;j<=y;++j)
251 if(fld[j][i]==0 || fld[j][i]==3 || fld[j][i]==9 || fld[j][i]==10) return 1;
252 return 0;
255 int Z_overlap(obj_t *a,obj_t *b) {
256 if(a->x - a->r > b->x + b->r) return 0;
257 if(a->x + a->r < b->x - b->r) return 0;
258 if(a->y <= b->y - b->h) return 0;
259 if(a->y - a->h >= b->y) return 0;
260 return 1;
263 static void Z_kickobj(obj_t *o,int x,int y,int pwr) {
264 int dx,dy,m;
266 dx=o->x-x;dy=o->y-o->h/2-y;
267 if(!(m=max(abs(dx),abs(dy)))) m=1;
268 o->vx+=(long)dx*pwr/m;
269 o->vy+=(long)dy*pwr/m;
272 int Z_cansee(int x,int y,int xd,int yd) {
273 register dword d,m;
274 int sx,sy;
275 dword xe,ye,s,i;
277 if((xd-=x)>0) sx=1;
278 else if(xd<0) sx=-1;
279 else sx=0;
280 if((yd-=y)>0) sy=1;
281 else if(yd<0) sy=-1;
282 else sy=0;
283 if(!xd && !yd) return 1;
284 if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd;
285 xe=ye=0;
286 for(i=0;i<=d;) {
287 if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) return 0;
288 if((bmap[y>>5][x>>5]&BM_WALL)) {
289 if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) return 0;
290 if((xe+=(xd<<3))>=d) {
291 x+=xe/d*sx;xe=xe%d;
293 if((ye+=(yd<<3))>=d) {
294 y+=ye/d*sy;ye=ye%d;
296 i+=8;
297 }else{
298 if(sx==0) m=0;
299 else{m=x&31;if(sx>0) m^=31; ++m;}
300 if(sy==0) s=0;
301 else{s=y&31;if(sy>0) s^=31; ++s;}
302 if((s<m && s!=0) || m==0) m=s;
303 i+=m;
304 x+=(xd*m+xe)/d*sx;xe=(xd*m+xe)%d;
305 y+=(yd*m+ye)/d*sy;ye=(yd*m+ye)%d;
308 return 1;
311 int Z_look(obj_t *a,obj_t *b,int d) {
312 if(Z_sign(b->x-a->x)!=d*2-1) return 0;
313 return Z_cansee(a->x,a->y-a->h/2,b->x,b->y-b->h/2);
316 #define wvel(v) if((xv=abs(v)+1)>5) v=Z_dec(v,xv/2-2)
318 int Z_moveobj(obj_t *p) {
319 static int x,y,xv,yv,r,h,lx,ly,st;
320 static byte inw;
322 st=0;
323 switch(Z_inlift(x=p->x,y=p->y,r=p->r,h=p->h)) {
324 case 0:
325 if(++p->yv>MAX_YV) --p->yv;
326 break;
327 case 1:
328 if(--p->yv < -5) ++p->yv;
329 break;
330 case 2:
331 if(p->yv > 5) {--p->yv;break;}
332 ++p->yv;break;
334 if((inw=Z_inwater(x,y,r,h))!=0) {
335 st|=Z_INWATER;
336 wvel(p->xv);
337 wvel(p->yv);
338 wvel(p->vx);
339 wvel(p->vy);
341 p->vx=Z_dec(p->vx,1);
342 p->vy=Z_dec(p->vy,1);
343 xv=p->xv+p->vx;yv=p->yv+p->vy;
344 while(xv || yv) {
345 if(x<-100 || x>=FLDW*8+100 || y<-100 || y>=FLDH*8+100)
346 {st|=Z_FALLOUT;}
348 lx=x;
349 x+=(abs(xv)<=7)?xv:((xv>0)?7:-7);
350 if(z_mon) if(Z_isblocked(x,y,r,h,xv)) st|=Z_BLOCK;
351 if(!Z_canfit(x,y,r,h)) {
352 if(xv==0) x=lx;
353 else if(xv<0) x=((lx-r)&0xFFF8)+r;
354 else x=((lx+r)&0xFFF8)-r+7;
355 xv=p->xv=p->vx=0;st|=Z_HITWALL;
357 xv-=(abs(xv)<=7)?xv:((xv>0)?7:-7);
359 ly=y;
360 y+=(abs(yv)<=7)?yv:((yv>0)?7:-7);
361 if(yv>=8) --y;
362 if(yv<0 && Z_hitceil(x,y,r,h)) {
363 y=((ly-h+1)&0xFFF8)+h-1;
364 yv=p->vy=1;p->yv=0;st|=Z_HITCEIL;
366 if(yv>0 && Z_canstand(x,y,r)) {
367 y=((y+1)&0xFFF8)-1;
368 yv=p->yv=p->vy=0;st|=Z_HITLAND;
370 yv-=(abs(yv)<=7)?yv:((yv>0)?7:-7);
372 p->x=x;p->y=y;
373 if(Z_inwater(x,y,r,h)) {
374 st|=Z_INWATER;
375 if(!inw) st|=Z_HITWATER;
376 }else if(inw) st|=Z_HITAIR;
377 return st;
380 void Z_splash (obj_t *p, int n) {
381 Z_sound(bulsnd[0], 128);
382 DOT_water(p->x, p->y-p->h / 2, p->xv + p->vx, p->yv + p->vy, n, R_get_special_id(wfront) - 1);
385 void Z_calc_time(dword t,word *h,word *m,word *s)
387 t = t * DELAY;
388 t = t / 1000;
389 *s = t % 60;
390 t = t - *s;
391 t = t / 60;
392 *m = t % 60;
393 t = t - *m;
394 t = t / 60;
395 *h = t;
398 #define SWAP_VAR(a, b) do { unsigned char t = a; a = b; b = t; } while(0)
400 static int16_t short2swap (int16_t x) {
401 union {
402 uint8_t a[2];
403 int16_t x;
404 } y;
405 y.x = x;
406 SWAP_VAR(y.a[0], y.a[1]);
407 return y.x;
410 static int32_t int2swap (int32_t x) {
411 union {
412 uint8_t a[4];
413 int32_t x;
414 } y;
415 y.x = x;
416 SWAP_VAR(y.a[0], y.a[3]);
417 SWAP_VAR(y.a[1], y.a[2]);
418 return y.x;
421 #undef SWAP_VAR
423 int16_t short2host (int16_t x) {
424 #if __BIG_ENDIAN__
425 return short2swap(x);
426 #else
427 return x;
428 #endif
431 int32_t int2host (int32_t x) {
432 #if __BIG_ENDIAN__
433 return int2swap(x);
434 #else
435 return x;
436 #endif