1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 #ifndef __EFFECT_H
20 #define __EFFECT_H
21 
22 /*
23  * $Source: r:/prj/cit/src/inc/RCS/effect.h $
24  * $Revision: 1.35 $
25  * $Author: xemu $
26  * $Date: 1994/11/21 21:05:41 $
27  *
28  */
29 
30 // Includes
31 #include "objects.h"
32 #include "objcrit.h"
33 #include "objgame.h"
34 #include "objwpn.h"
35 
36 #define BLOOD_LIGHT     1
37 #define CAMERA_EXPL     2
38 #define TV_EXPL         3
39 #define SMOKE           4
40 #define PLNT_EXPL       5
41 #define BULL_HIT_WALL   6
42 #define BEAM_HIT_WALL   7
43 #define IMPACT          8
44 #define BULLET_ROBOT    9
45 #define BEAM_ROBOT_LT   10
46 #define BEAM_ROBOT_HVY  11
47 #define M_EXPL1         12
48 #define M_EXPL2         13
49 #define M_EXPL3         14
50 #define LG_EXPL         15
51 #define MAG_HIT         16
52 #define STUN_HIT        17
53 #define PLASMA_HIT      18
54 #define SMOKEY_EXPL     19
55 #define CRATE_EXPL      20
56 #define MNTR_EXPL2      21
57 #define GAS_EXPL        22
58 #define EMP_EXPL        23
59 #define CORPSE_HUM_EXPL 24
60 #define CORPSE_ROB_EXPL 25
61 #define EFFECT_NUMS     25
62 
63 // should these be here - or is this just for special effects in the 3D??
64 #define SHIELD_HIT_EFFECT  40
65 #define SHIELD_GONE_EFFECT 41
66 #define BODY_HIT_EFFECT    42
67 
68 #define CRIT_HIT_NUM 5
69 #define SEVERITIES   2
70 #define AMMO_TYPES   4
71 #define PROJ_TYPE    0
72 #define BEAM_TYPE    1
73 #define HAND_TYPE    2
74 #define GREN_TYPE    3
75 #define NON_CRITTER_EFFECT (CRIT_HIT_NUM - 1)
76 #define SPECIAL_TYPE CRIT_HIT_NUM
77 
78 extern ubyte effect_matrix[CRIT_HIT_NUM][AMMO_TYPES][SEVERITIES];
79 
80 // info about the destruction of an object
81 // (a) should we play an effect?
82 // (b) should we destroy the object DURING the effect
83 // (c) should we play a sound effect?
84 
85 #define EFFECT_VAL(x)           ((x)&0x1F)
86 #define DESTROY_SOUND_EFFECT(x) (((x)&0x60) >> 5)
87 #define DESTROY_OBJ_EFFECT(x)   ((x)&0x80)
88 
89 // these are things about the state of the effects
90 // they are cleverly hidden in the instance data of the effect
91 // in start_frame
92 
93 #define EFFECT_LIGHT_FLAG 0x01
94 
95 #define EFFECT_LIGHT_MAP_SHIFT  3
96 #define EFFECT_LIGHT_MAP_MASK   0x78
97 #define EFFECT_DESTROY_OBJ_FLAG 0x80
98 
99 #define EFFECT_LIGHT_MAP(x)        (((x)&EFFECT_LIGHT_MAP_MASK) >> EFFECT_LIGHT_MAP_SHIFT)
100 #define SET_EFFECT_LIGHT_MAP(x, y) (x = (((x) & ~(EFFECT_LIGHT_MAP_MASK)) | (y << EFFECT_LIGHT_MAP_SHIFT)))
101 #define CLEAR_EFFECT_LIGHT_MAP(x)  ((x) &= ~(EFFECT_LIGHT_MAP_MASK))
102 
103 #define EFFECT_DESTROY_OBJ(x)       ((x) & EFFECT_DESTROY_OBJ_FLAG)
104 #define SET_EFFECT_DESTROY_OBJ(x)   ((x) |= EFFECT_DESTROY_OBJ_FLAG)
105 #define CLEAR_EFFECT_DESTROY_OBJ(x) ((x) &= ~(EFFECT_DESTROY_OBJ_FLAG))
106 
107 #define START_FRAME(x) ((x) & ~(EFFECT_LIGHT_MAP_MASK | EFFECT_DESTROY_OBJ_FLAG))
108 
109 // the effect location
110 #define EFFECT_LOC(id) (objs[id].info.make_info & 0x03)
111 #define SET_EFFECT_LOC(id, x) (objs[id].info.make_info &= (~0x03 | x))
112 #define EFFECT_LEFT 01
113 #define EFFECT_RIGHT 02
114 #define EFFECT_CENTER 03
115 
116 // the effect number
117 #define EFFECT_NUM(id) ((objs[id].info.make_info & 0x7C) >> 2)
118 #define SET_EFFECT_NUM(id, x) (objs[id].info.make_info &= (~0x7C | (x << 2)))
119 
120 // show two effects????????
121 #define EFFECT_DUAL(id) (objs[id].info.make_info & 0x80)
122 #define SET_EFFECT_DUAL(id, x) (objs[id].info.make_info &= (x << 7))
123 
124 // frame count
125 #define EFFECT_FRAME(id) ((objCritters[objs[id].specID].mood & 0x70) >> 4)
126 #define SET_EFFECT_FRAME(id, x) (objCritters[objs[id].specID].mood &= (~0x70 | x << 4))
127 
128 // height's range is from 1-7 (one being the lowest, 3 the center)
129 #define EFFECT_HEIGHT(id) ((objCritters[objs[id].specID].orders & 0x70) >> 4)
130 #define SET_EFFECT_HEIGHT(id, x) (objCritters[objs[id].specID].orders &= (~0x70 | x << 4))
131 
132 // scale's range is from 1-3 (1 being the smallest)
133 #define EFFECT_SCALE(id) \
134     (((objCritters[objs[id].specID].orders & 0x80) >> 6) | ((objCritters[objs[id].specID].mood & 0x80) >> 7))
135 #define SET_EFFECT_SCALE(id, x)                                            \
136     do {                                                                   \
137         objCritters[objs[id].specID].orders &= (0x7F | ((x & 0x02) << 6)); \
138         objCritters[objs[id].specID].mood &= (0x7F | ((x & 0x01) << 7));   \
139     } while (0);
140 
141 #define EFFECT_EIGHTH(id) ((objCritters[objs[id].specID].current_posture & 0xE0) >> 5)
142 #define SET_EFFECT_EIGHTH(id, x) (objCritters[objs[id].specID].current_posture &= (~0xE0 | (x << 5)))
143 
144 #define EFFT2TRIP(num)                                             \
145     ((num <= NUM_TRANSITORY_ANIMATING) ? (BLOOD1_TRIPLE + num - 1) \
146                                        : (EXPLOSION1_TRIPLE + num - (NUM_TRANSITORY_ANIMATING + 1)))
147 
148 #define OBJ_LOC_TO_LIGHT_LOC(val) ((val + 0x80) >> 8)
149 
150 #define CRITTER_LAMP_MASK     0xF0
151 #define CRITTER_LAMP_SHIFT    4
152 #define CRITLIT(id)           (objCritters[objs[id].specID].current_posture)
153 
154 #define CRITLOCX(id)          (objs[id].info.make_info)
155 #define SET_CRITLOCX(id, val) (objs[id].info.make_info = val)
156 #define CRITLOCY(id)          (objCritters[objs[id].specID].ai_mode)
157 #define SET_CRITLOCY(id, val) (objCritters[objs[id].specID].ai_mode = val)
158 
159 #define CRITTER_LAMP(id) ((CRITLIT(id) & CRITTER_LAMP_MASK) >> CRITTER_LAMP_SHIFT)
160 #define SET_CRITTER_LAMP(id, lval) (CRITLIT(id) = ((CRITLIT(id) & (~CRITTER_LAMP_MASK)) | (lval << CRITTER_LAMP_SHIFT)))
161 #define CLEAR_CRITTER_LAMP(id) (CRITLIT(id) &= (~CRITTER_LAMP_MASK))
162 
163 typedef void (*AnimlistCB)(ObjID id, intptr_t user_data);
164 
165 // do_special_effect
166 ObjID do_special_effect(ObjID owner, ubyte effect, ubyte start, ObjID obj, short location);
167 ObjID do_special_effect_location(ObjID owner, ubyte effect, ubyte start, ObjLoc *loc, short location);
168 void advance_animations(void);
169 errtype add_obj_to_animlist(ObjID id, uchar repeat, uchar reverse, uchar cycle, short speed, int cb_id, intptr_t user_data,
170                             short cbtype);
171 errtype remove_obj_from_animlist(ObjID id);
172 errtype animlist_clear();
173 
174 #define MAX_ANIMLIST_SIZE 64
175 
176 #define ANIMCB_REMOVE 1
177 #define ANIMCB_REPEAT 2
178 #define ANIMCB_CYCLE  3
179 
180 #define ANIMFLAG_REPEAT  1
181 #define ANIMFLAG_REVERSE 2
182 #define ANIMFLAG_CYCLE   4
183 
184 typedef struct {
185     ObjID id;
186     uchar flags;
187     short cbtype;
188     int callback;
189     intptr_t user_data;
190     short speed;
191 } AnimListing;
192 
193 #ifdef _EFFECT_SRC
194 short anim_counter = 0;
195 AnimListing animlist[MAX_ANIMLIST_SIZE];
196 #else
197 extern short anim_counter;
198 extern AnimListing animlist[MAX_ANIMLIST_SIZE];
199 #endif
200 
201 #endif // __EFFECT_H
202