DEADSOFTWARE

7c69aeab6ac4e48e168747732a49982b4a17e05b
[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"
37 //#define WD 200
38 //#define HT 98
40 #define MAX_YV 30
42 extern dword walf[256];
44 byte z_dot=0;
46 extern void *walp[256];
48 static void *bulsnd[2];
50 int Z_sign(int a) {
51 if(a>0) return 1;
52 if(a<0) return -1;
53 return 0;
54 }
56 int Z_dec(int a,int b) {
57 if(abs(a)<=b) return 0;
58 if(a>0) return a-b;
59 if(a<0) return a+b;
60 return 0;
61 }
63 void *Z_getsnd(char n[6]) {
64 char s[8];
66 //if(snd_type==-1) return NULL;
67 strncpy(s+2,n,6);s[0]='D';
68 s[1]='S';
70 int id = F_getresid(s);
71 int loaded = M_was_locked(id);
72 snd_t *snd = M_lock(id);
73 if (snd != NULL && !loaded) {
74 snd->len = int2host(snd->len);
75 snd->rate = int2host(snd->rate);
76 snd->lstart = int2host(snd->lstart);
77 snd->llen = int2host(snd->llen);
78 }
79 return snd;
80 }
82 int Z_sound(void *s,int v) {
83 //if(snd_type==-1) return 0;
84 if(!s) return 0;
85 S_play(s,-1,1024,v);
86 return F_getreslen(((int*)s)[-1])/605;
87 }
89 #define GAS_START (MN__LAST-MN_DEMON+5)
90 #define GAS_TOTAL (MN__LAST-MN_DEMON+16+10)
92 void Z_initst(void) {
93 bulsnd[0]=Z_getsnd("BUL1");
94 bulsnd[1]=Z_getsnd("BUL2");
95 }
97 int Z_canstand(int x,int y,int r) {
98 int i;
100 i=(x-r)/CELW;
101 x=(x+r)/CELW;
102 y=(y+1)/CELH;
103 if(y>=FLDH || y<0) return 0;
104 if(i<0) i=0;
105 if(x>=FLDW) x=FLDW-1;
106 for(;i<=x;++i)
107 if(fld[y][i]==1 || fld[y][i]==2 || fld[y][i]==4)
108 if(!z_dot) return 1;
109 else if(!((walf[fldf[y][i]]|walf[fldb[y][i]])&2)) return 1;
110 return 0;
113 int Z_hitceil(int x,int y,int r,int h) {
114 int i;
116 i=(x-r)/CELW;
117 x=(x+r)/CELW;
118 y=(y-h+1)/CELH;
119 if(y>=FLDH || y<0) return 0;
120 if(i<0) i=0;
121 if(x>=FLDW) x=FLDW-1;
122 for(;i<=x;++i)
123 if(fld[y][i]==1 || fld[y][i]==2)
124 if(!z_dot) return 1;
125 else if(!((walf[fldf[y][i]]|walf[fldb[y][i]])&2)) return 1;
126 return 0;
129 int Z_canfit(int x,int y,int r,int h) {
130 int i,j,sx,sy;
132 sx=(x-r)/CELW;
133 sy=(y-h+1)/CELH;
134 if(sx<0) sx=0;
135 if(sy<0) sy=0;
136 x=(x+r)/CELW;
137 y=(y-0)/CELH;
138 if(x>=FLDW) x=FLDW-1;
139 if(y>=FLDH) y=FLDH-1;
140 for(i=sx;i<=x;++i)
141 for(j=sy;j<=y;++j)
142 if(fld[j][i]==1 || fld[j][i]==2)
143 if(!z_dot) return 0;
144 else if(!((walf[fldf[j][i]]|walf[fldb[j][i]])&2)) return 0;
145 return 1;
148 int Z_inlift(int x,int y,int r,int h) {
149 int i,j,sx,sy;
151 sx=(x-r)/CELW;
152 sy=(y-h+1)/CELH;
153 if(sx<0) sx=0;
154 if(sy<0) sy=0;
155 x=(x+r)/CELW;
156 y=(y-1)/CELH;
157 if(x>=FLDW) x=FLDW-1;
158 if(y>=FLDH) y=FLDH-1;
159 for(i=sx;i<=x;++i)
160 for(j=sy;j<=y;++j)
161 if(fld[j][i]==9 || fld[j][i]==10) return fld[j][i]-8;
162 return 0;
165 int Z_isblocked(int x,int y,int r,int h,int xv) {
166 int i,j,sx,sy;
168 sx=(x-r)/CELW;
169 sy=(y-h+1)/CELH;
170 if(sx<0) sx=0;
171 if(sy<0) sy=0;
172 x=(x+r)/CELW;
173 y=(y-1)/CELH;
174 if(xv<0) x=sx;
175 else if(xv>0) sx=x;
176 if(x>=FLDW) x=FLDW-1;
177 if(y>=FLDH) y=FLDH-1;
178 for(i=sx;i<=x;++i)
179 for(j=sy;j<=y;++j)
180 if(fld[j][i]==8) return 1;
181 return 0;
184 int Z_istrapped(int x,int y,int r,int h) {
185 int i,j,sx,sy;
187 sx=(x-r)/CELW;
188 sy=(y-h+1)/CELH;
189 if(sx<0) sx=0;
190 if(sy<0) sy=0;
191 x=(x+r)/CELW;
192 y=(y-1)/CELH;
193 if(x>=FLDW) x=FLDW-1;
194 if(y>=FLDH) y=FLDH-1;
195 for(i=sx;i<=x;++i)
196 for(j=sy;j<=y;++j)
197 if(fld[j][i]==255) return 1;
198 return 0;
201 void Z_set_speed(obj_t *o,int s) {
202 int m;
204 if(!(m=max(abs(o->xv),abs(o->yv)))) m=1;
205 o->xv=o->xv*s/m;o->yv=o->yv*s/m;
208 static byte wfront;
210 int Z_inwater(int x,int y,int r,int h) {
211 int i,j,sx,sy;
213 sx=(x-r)/CELW;
214 sy=(y-h+1)/CELH;
215 if(sx<0) sx=0;
216 if(sy<0) sy=0;
217 x=(x+r)/CELW;
218 y=(y-h/2)/CELH;
219 if(x>=FLDW) x=FLDW-1;
220 if(y>=FLDH) y=FLDH-1;
221 for(i=sx;i<=x;++i)
222 for(j=sy;j<=y;++j)
223 if(fld[j][i]>=5 && fld[j][i]<=7) {wfront=fldf[j][i];return 1;}
224 return 0;
227 int Z_getacid(int x,int y,int r,int h) {
228 int i,j,sx,sy,a;
229 static byte tab[4]={0,5,10,20};
231 a=0;
232 sx=(x-r)/CELW;
233 sy=(y-h+1)/CELH;
234 if(sx<0) sx=0;
235 if(sy<0) sy=0;
236 x=(x+r)/CELW;
237 y=y/CELH;
238 if(x>=FLDW) x=FLDW-1;
239 if(y>=FLDH) y=FLDH-1;
240 for(i=sx;i<=x;++i)
241 for(j=sy;j<=y;++j)
242 if(fld[j][i]==6) a|=1;
243 else if(fld[j][i]==7) a|=2;
244 return tab[a];
247 int Z_canbreathe(int x,int y,int r,int h) {
248 int i,j,sx,sy;
250 sx=(x-r)/CELW;
251 sy=(y-h+1)/CELH;
252 if(sx<0) sx=0;
253 if(sy<0) sy=0;
254 x=(x+r)/CELW;
255 y=(y-h/2)/CELH;
256 if(x>=FLDW) x=FLDW-1;
257 if(y>=FLDH) y=FLDH-1;
258 if(sx>x || sy>y) return 1;
259 for(i=sx;i<=x;++i)
260 for(j=sy;j<=y;++j)
261 if(fld[j][i]==0 || fld[j][i]==3 || fld[j][i]==9 || fld[j][i]==10) return 1;
262 return 0;
265 int Z_overlap(obj_t *a,obj_t *b) {
266 if(a->x - a->r > b->x + b->r) return 0;
267 if(a->x + a->r < b->x - b->r) return 0;
268 if(a->y <= b->y - b->h) return 0;
269 if(a->y - a->h >= b->y) return 0;
270 return 1;
273 void Z_kickobj(obj_t *o,int x,int y,int pwr) {
274 int dx,dy,m;
276 dx=o->x-x;dy=o->y-o->h/2-y;
277 if(!(m=max(abs(dx),abs(dy)))) m=1;
278 o->vx+=(long)dx*pwr/m;
279 o->vy+=(long)dy*pwr/m;
282 int Z_cansee(int x,int y,int xd,int yd) {
283 register dword d,m;
284 int sx,sy;
285 dword xe,ye,s,i;
287 if((xd-=x)>0) sx=1;
288 else if(xd<0) sx=-1;
289 else sx=0;
290 if((yd-=y)>0) sy=1;
291 else if(yd<0) sy=-1;
292 else sy=0;
293 if(!xd && !yd) return 1;
294 if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd;
295 xe=ye=0;
296 for(i=0;i<=d;) {
297 if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) return 0;
298 if((bmap[y>>5][x>>5]&BM_WALL)) {
299 if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) return 0;
300 if((xe+=(xd<<3))>=d) {
301 x+=xe/d*sx;xe=xe%d;
303 if((ye+=(yd<<3))>=d) {
304 y+=ye/d*sy;ye=ye%d;
306 i+=8;
307 }else{
308 if(sx==0) m=0;
309 else{m=x&31;if(sx>0) m^=31; ++m;}
310 if(sy==0) s=0;
311 else{s=y&31;if(sy>0) s^=31; ++s;}
312 if((s<m && s!=0) || m==0) m=s;
313 i+=m;
314 x+=(xd*m+xe)/d*sx;xe=(xd*m+xe)%d;
315 y+=(yd*m+ye)/d*sy;ye=(yd*m+ye)%d;
318 return 1;
321 int Z_look(obj_t *a,obj_t *b,int d) {
322 if(Z_sign(b->x-a->x)!=d*2-1) return 0;
323 return Z_cansee(a->x,a->y-a->h/2,b->x,b->y-b->h/2);
326 #define wvel(v) if((xv=abs(v)+1)>5) v=Z_dec(v,xv/2-2)
328 byte z_mon=0;
330 int Z_moveobj(obj_t *p) {
331 static int x,y,xv,yv,r,h,lx,ly,st;
332 static byte inw;
334 st=0;
335 switch(Z_inlift(x=p->x,y=p->y,r=p->r,h=p->h)) {
336 case 0:
337 if(++p->yv>MAX_YV) --p->yv;
338 break;
339 case 1:
340 if(--p->yv < -5) ++p->yv;
341 break;
342 case 2:
343 if(p->yv > 5) {--p->yv;break;}
344 ++p->yv;break;
346 if((inw=Z_inwater(x,y,r,h))!=0) {
347 st|=Z_INWATER;
348 wvel(p->xv);
349 wvel(p->yv);
350 wvel(p->vx);
351 wvel(p->vy);
353 p->vx=Z_dec(p->vx,1);
354 p->vy=Z_dec(p->vy,1);
355 xv=p->xv+p->vx;yv=p->yv+p->vy;
356 while(xv || yv) {
357 if(x<-100 || x>=FLDW*8+100 || y<-100 || y>=FLDH*8+100)
358 {st|=Z_FALLOUT;}
360 lx=x;
361 x+=(abs(xv)<=7)?xv:((xv>0)?7:-7);
362 if(z_mon) if(Z_isblocked(x,y,r,h,xv)) st|=Z_BLOCK;
363 if(!Z_canfit(x,y,r,h)) {
364 if(xv==0) x=lx;
365 else if(xv<0) x=((lx-r)&0xFFF8)+r;
366 else x=((lx+r)&0xFFF8)-r+7;
367 xv=p->xv=p->vx=0;st|=Z_HITWALL;
369 xv-=(abs(xv)<=7)?xv:((xv>0)?7:-7);
371 ly=y;
372 y+=(abs(yv)<=7)?yv:((yv>0)?7:-7);
373 if(yv>=8) --y;
374 if(yv<0 && Z_hitceil(x,y,r,h)) {
375 y=((ly-h+1)&0xFFF8)+h-1;
376 yv=p->vy=1;p->yv=0;st|=Z_HITCEIL;
378 if(yv>0 && Z_canstand(x,y,r)) {
379 y=((y+1)&0xFFF8)-1;
380 yv=p->yv=p->vy=0;st|=Z_HITLAND;
382 yv-=(abs(yv)<=7)?yv:((yv>0)?7:-7);
384 p->x=x;p->y=y;
385 if(Z_inwater(x,y,r,h)) {
386 st|=Z_INWATER;
387 if(!inw) st|=Z_HITWATER;
388 }else if(inw) st|=Z_HITAIR;
389 return st;
392 void Z_splash(obj_t *p,int n) {
393 Z_sound(bulsnd[0],128);
394 DOT_water(p->x,p->y-p->h/2,p->xv+p->vx,p->yv+p->vy,n,
395 (intptr_t)walp[wfront]-1);
398 void Z_calc_time(dword t,word *h,word *m,word *s)
400 t = t * DELAY;
401 t = t / 1000;
402 *s = t % 60;
403 t = t - *s;
404 t = t / 60;
405 *m = t % 60;
406 t = t - *m;
407 t = t / 60;
408 *h = t;
411 #define SWAP_VAR(a, b) do { unsigned char t = a; a = b; b = t; } while(0)
413 int16_t short2swap (int16_t x) {
414 union {
415 uint8_t a[2];
416 int16_t x;
417 } y;
418 y.x = x;
419 SWAP_VAR(y.a[0], y.a[1]);
420 return y.x;
423 int32_t int2swap (int32_t x) {
424 union {
425 uint8_t a[4];
426 int32_t x;
427 } y;
428 y.x = x;
429 SWAP_VAR(y.a[0], y.a[3]);
430 SWAP_VAR(y.a[1], y.a[2]);
431 return y.x;
434 #undef SWAP_VAR
436 int16_t short2host (int16_t x) {
437 #if __BIG_ENDIAN__
438 return short2swap(x);
439 #else
440 return x;
441 #endif
444 int32_t int2host (int32_t x) {
445 #if __BIG_ENDIAN__
446 return int2swap(x);
447 #else
448 return x;
449 #endif