DEADSOFTWARE

4ec8117a26a12bff82048fc138da3f7eed9b5d43
[flatwaifu.git] / src / smoke.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 <stdlib.h>
25 #include "vga.h"
26 #include "view.h"
27 #include "smoke.h"
28 #include "fx.h"
29 #include "misc.h"
31 #define MAXSR 20
33 #define SMSN 10
34 #define FLSN 8
36 #pragma pack(1)
37 typedef struct{
38 int x,y,xv,yv;
39 byte t,s;
40 short o;
41 }smoke_t;
42 #pragma pack()
44 static smoke_t sm[MAXSMOK];
45 static int sr_r,sxr[MAXSR],syr[MAXSR];
46 static int lsm;
48 static void *spr[SMSN],*fspr[FLSN];
49 static void *burnsnd;
50 static int burntm=0;
52 byte flametab[16]={
53 0xBC,0xBA,0xB8,0xB6,0xB4,0xB2,0xB0,0xD5,0xD6,0xD7,0xA1,0xA0,0xE3,0xE2,0xE1,0xE0
54 };
56 void SMK_savegame(FILE* h) {
57 int i,n;
59 for(i=n=0;i<MAXSMOK;++i) if(sm[i].t) ++n;
60 myfwrite(&n,1,4,h);
61 for(i=0;i<MAXSMOK;++i) if(sm[i].t) myfwrite(&sm[i],1,sizeof(sm[0]),h);
62 }
64 void SMK_loadgame(FILE* h) {
65 int n;
67 myfread(&n,1,4,h);
68 myfread(sm,1,n*sizeof(sm[0]),h);
69 }
71 void SMK_init(void) {
72 int i;
74 for(i=0;i<MAXSMOK;++i) {sm[i].t=0;}
75 lsm=0;
76 burntm=0;
77 }
79 void SMK_alloc(void) {
80 int i;
82 burnsnd=Z_getsnd("BURN");
83 for(i=0;i<SMSN;++i) spr[i]=Z_getspr("SMOK",i,0,NULL);
84 for(i=0;i<FLSN;++i) fspr[i]=Z_getspr("FLAM",i,0,NULL);
85 for(i=0;i<MAXSR;++i) {
86 sxr[i]=myrand(256*2+1)-256;
87 syr[i]=myrand(256*2+1)-256;
88 }
89 sr_r=0;
90 }
92 static void inclast(void) {
93 if(++lsm>=MAXSMOK) lsm=0;
94 }
96 void SMK_act(void) {
97 int i,ox,oy;
98 static obj_t o;
100 if(burntm) --burntm;
101 for(i=0;i<MAXSMOK;++i) if(sm[i].t) {
102 if(sm[i].s) {
103 ox=sm[i].x;oy=sm[i].y;
104 sm[i].xv=Z_dec(sm[i].xv,20);
105 sm[i].yv=Z_dec(sm[i].yv,20);
106 sm[i].x+=sm[i].xv/2;sm[i].y+=sm[i].yv/2;
107 if(!Z_canfit(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) {
108 sm[i].x=ox;sm[i].y=oy;
109 }else if(Z_inwater(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) {
110 sm[i].x=ox;sm[i].y=oy;
112 ox=sm[i].x;oy=sm[i].y;
113 sm[i].x+=sm[i].xv/2;sm[i].y+=sm[i].yv/2;
114 if(!Z_canfit(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) {
115 sm[i].x=ox;sm[i].y=oy;
116 }else if(Z_inwater(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) {
117 sm[i].x=ox;sm[i].y=oy;
119 if(sm[i].o!=-3) {
120 o.x=sm[i].x>>8;o.y=sm[i].y>>8;
121 o.xv=sm[i].xv>>10;o.yv=sm[i].yv>>10;
122 o.vx=o.vy=0;
123 if(!(g_time&3)) Z_hit(&o,1,sm[i].o,HIT_FLAME);
125 }else{
126 ox=sm[i].x;oy=sm[i].y;
127 sm[i].xv=Z_dec(sm[i].xv,20);
128 sm[i].yv=Z_dec(sm[i].yv,20);
129 sm[i].x+=sm[i].xv;sm[i].y+=sm[i].yv;
130 if(!Z_canfit(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) {
131 sm[i].x=ox;sm[i].y=oy;
132 }else if(Z_inwater(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) {
133 sm[i].x=ox;sm[i].y=oy;
136 --sm[i].t;
140 void SMK_draw(void) {
141 int i,s;
143 for(i=0;i<MAXSMOK;++i) if(sm[i].t) switch(sm[i].s) {
144 case 0:
145 if((s=sm[i].t)>=(SMSN-1)*3) s=0; else s=SMSN-1-s/3;
146 V_sprf((sm[i].x>>8)-w_x+WD/2,(sm[i].y>>8)-w_y+HT/2+1+w_o,spr[s],&smoke_sprf);//V_sprf((sm[i].x>>8)-w_x+100,(sm[i].y>>8)-w_y+50+w_o,spr[s],&smoke_sprf);
147 break;
148 case 1:
149 if((s=sm[i].t)>=(FLSN-1)) s=0; else s=FLSN-1-s;
150 V_sprf((sm[i].x>>8)-w_x+WD/2,(sm[i].y>>8)-w_y+HT/2+1+w_o,fspr[s],&flame_sprf);//V_sprf((sm[i].x>>8)-w_x+100,(sm[i].y>>8)-w_y+50+w_o,fspr[s],&flame_sprf);
151 break;
155 void SMK_add(int x,int y,int xv,int yv,byte t,byte s,short o) {
156 int i;
158 if(!Z_canfit(x>>8,(y>>8)+3,3,7)) return;
159 if(Z_inwater(x>>8,(y>>8)+3,3,7)) {FX_bubble(x>>8,y>>8,xv,yv,1);return;}
160 i=lsm;
161 sm[i].x=x;sm[i].y=y;
162 sm[i].xv=xv;sm[i].yv=yv;
163 sm[i].t=t;sm[i].s=s;
164 sm[i].o=o;
165 inclast();
168 void SMK_gas(int x0,int y0,int xr,int yr,int xv,int yv,int k) {
169 int i,x,y;
170 static int sxv,syv;
172 xv=-xv;yv=-yv;
173 sxv=xv*k;syv=yv*k;
174 k=max(abs(xv),abs(yv));
175 if(!k) return;
176 for(i=0;i<=k;i+=3) {
177 x=((xv*i/k+x0)<<8)+sxr[sr_r]*xr;
178 y=((yv*i/k+y0)<<8)+syr[sr_r]*yr;
179 if(++sr_r>=MAXSR) sr_r=0;
180 SMK_add(x,y,sxv,syv,SMSN*3,0,-3);
184 void SMK_flame(int x0,int y0,int ox,int oy,int xr,int yr,int xv,int yv,int k,int o) {
185 int i,x,y;
186 static int sxv,syv;
188 sxv=xv*k;syv=yv*k;
189 xv=xv-(ox<<8);yv=yv-(oy<<8);
190 k=max(abs(xv),abs(yv));
191 if(!k) return;
192 if(!burntm) burntm=Z_sound(burnsnd,128);
193 for(i=0;i<=k;i+=200) {
194 x=xv*i/k+(x0<<8)+sxr[sr_r]*xr;
195 y=yv*i/k+(y0<<8)+syr[sr_r]*yr;
196 if(++sr_r>=MAXSR) sr_r=0;
197 SMK_add(x,y,sxv,syv,FLSN,1,o);