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 __OBJAPP_H
20 #define __OBJAPP_H
21 
22 #pragma pack(push,2)
23 
24 /*
25 ** $Header: r:/prj/cit/src/inc/RCS/objapp.h 1.25 1994/08/30 07:15:21 xemu Exp $
26 *
27 */
28 
29 //////////////////////////////
30 //
31 // An ObjClass is an enum encompassing all the different classes
32 // in the world.  Be sure to set NUM_CLASSES and CLASS_FIRST
33 // correctly.
34 //
35 // An ObjRefState specifies the location of an ObjRef.
36 //
37 // It is made up of two parts:
38 //
39 //   - ObjRefStateBin is used to choose where to put an ObjRef
40 //     in the world-wide data structure.  All ObjRefs with the
41 //     same ObjRefStateBin are part of the same chain.
42 //
43 //   - ObjRefStateInfo is extra information associated with an
44 //     ObjRef's location.  For example, in Freefall we specify
45 //     here what rendering triangles an object overlaps.  If
46 //     you have no such information in your application, then
47 //     #define NO_OBJ_REF_STATE_INFO.
48 //
49 // There must be a specific ObjRefStateBin which is "null".
50 // For example, it is used to terminate lists of ObjRefStateBins.
51 // The ObjRefStateBinSetNull and -CheckNull macros respectively
52 // set a bin to be null and check if it is null.
53 //
54 // An ObjLoc specifies the location of an Obj.
55 // An ObjInfo contains any extra information that you need to have associated
56 // with each and every object.
57 //
58 // #define HASH_OBJECTS if you want ObjRef chains to be hashed
59 // by location.  You must then define the number of entries, and
60 // how many of those entries are accessible by the hashing function.
61 // (I recommend keeping these in the ratio 2:1).  You must also write
62 // a macro (or function if you prefer) that computes a number n such that
63 // OBJ_HASH_HEAD_ENTRIES_START <= n < OBJ_HASH_ENTRIES, given an
64 // ObjRefStateBin.
65 //
66 // If you do not #define HASH_OBJECTS, you must write a macro that provides
67 // the head of the ObjRef chain for a given bin.  (You are responsible for
68 // keeping a 2-dimensional array of bins, or whatever.)  This must be a macro
69 // so that the object system can take the address of the result.
70 
71 ////////////////////////////// HERE IS THE STUFF YOU MUST CHANGE
72 //                          //
73 //                          ////////////////////////////////
74 
75 //#include <map.h>
76 
77 // #define HASH_OBJECTS
78 #define NO_OBJ_REF_STATE_INFO
79 
80 // enumeration of classes
81 // ## INSERT NEW CLASS HERE
82 // Note these have a fixed size and fixed values in the game files. They are
83 // as defined constants than an enum, and gcc does not like to make enums
84 // 8-bit values.
85 typedef uint8_t ObjClass;
86 #define CLASS_GUN        0
87 #define CLASS_AMMO       1
88 #define CLASS_PHYSICS    2
89 #define CLASS_GRENADE    3
90 #define CLASS_DRUG       4
91 #define CLASS_HARDWARE   5
92 #define CLASS_SOFTWARE   6
93 #define CLASS_BIGSTUFF   7
94 #define CLASS_SMALLSTUFF 8
95 #define CLASS_FIXTURE    9
96 #define CLASS_DOOR      10
97 #define CLASS_ANIMATING 11
98 #define CLASS_TRAP      12
99 #define CLASS_CONTAINER 13
100 #define CLASS_CRITTER   14
101 #define NUM_CLASSES     15
102 #define CLASS_FIRST CLASS_GUN
103 
104 // The total number of objects in the game, and of each type
105 // ## INSERT NEW CLASS HERE
106 //
107 
108 #define NUM_OBJECTS            872
109 #define NUM_OBJECTS_GUN         16
110 #define NUM_OBJECTS_AMMO        32
111 #define NUM_OBJECTS_PHYSICS     32
112 #define NUM_OBJECTS_GRENADE     32
113 #define NUM_OBJECTS_DRUG        32
114 #define NUM_OBJECTS_HARDWARE     8
115 #define NUM_OBJECTS_SOFTWARE    16
116 #define NUM_OBJECTS_BIGSTUFF   176
117 #define NUM_OBJECTS_SMALLSTUFF 128
118 #define NUM_OBJECTS_FIXTURE     64
119 #define NUM_OBJECTS_DOOR        64
120 #define NUM_OBJECTS_ANIMATING   32
121 #define NUM_OBJECTS_TRAP       160
122 #define NUM_OBJECTS_CONTAINER   64
123 #define NUM_OBJECTS_CRITTER     64
124 
125 // THe total number of references of objects
126 #define NUM_REF_OBJECTS 1600
127 
128 // i hate cpp, no sizeof() in #if, so we have to do this
129 #define SIZEOF_AN_OBJREFSTATEBIN 4
130 typedef struct {
131     LGPoint sq;
132 } ObjRefStateBin;
133 
134 #define OBJREF_SQ(ori) (objRefs[ori].state.bin.sq)
135 
136 // i hate cpp, no sizeof() in #if, so we have to do this
137 #define SIZEOF_AN_OBJREFSTATEINFO 1
138 typedef struct {
139     uchar flags;
140 } ObjRefStateInfo;
141 
142 #define ObjRefStateBinSetNull(bin)   PointSetNull((bin).sq)
143 #define ObjRefStateBinCheckNull(bin) (PointCheckNull((bin).sq))
144 
145 // i hate cpp, no sizeof() in #if, so we have to do this
146 #define SIZEOF_AN_OBJLOC 8
147 typedef struct {
148     ushort x, y; // high 8 bits: what square      low 8 bits: where within square
149     ubyte z;
150     ubyte p, h, b;
151 } ObjLoc;
152 
153 #define OBJ_LOC_BIN_X(oloc)  ((oloc).x >> 8u)
154 #define OBJ_LOC_BIN_Y(oloc)  ((oloc).y >> 8u)
155 #define OBJ_LOC_FINE_X(oloc) ((ushort)((oloc).x & 0xFF00u))
156 #define OBJ_LOC_FINE_Y(oloc) ((ushort)((oloc).y & 0xFF00u))
157 #ifdef SAFE_FIX
158 #define OBJ_LOC_VAL_TO_FIX(value) (fix_make((value >> 8), ((value & 0xFF00) << 8)))
159 #else
160 #define OBJ_LOC_VAL_TO_FIX(value) (((fix)value) << 8)
161 #endif
162 
163 typedef struct {
164     char ph;
165     byte type;
166     short current_hp;
167     ubyte make_info;      // maker, as in Zortech MK III laser rifle or whatever
168     ubyte current_frame;  // animdata
169     ubyte time_remainder; // animdata
170     uchar inst_flags;     //  flags for instance data.  right now 0x01 is used by Mahk's render tricks
171 } ObjInfo;
172 
173 typedef struct {
174     int ph;
175     byte type;
176     short current_hp;
177     ubyte make_info;      // maker, as in Zortech MK III laser rifle or whatever
178     ubyte current_frame;  // animdata
179     ubyte time_remainder; // animdata
180     uchar inst_flags;     //  flags for instance data.  right now 0x01 is used by Mahk's render tricks
181 } old_ObjInfo;
182 
183 #ifdef HASH_OBJECTS
184 #define OBJ_HASH_ENTRIES 512
185 #define OBJ_HASH_HEAD_ENTRIES 256
186 #define OBJ_HASH_HEAD_ENTRIES_START (OBJ_HASH_ENTRIES - OBJ_HASH_HEAD_ENTRIES)
187 #define OBJ_HASH_FUNC(bin) \
188     ((((((bin).sq.x) << 2) + ((bin).sq.y)) & (OBJ_HASH_HEAD_ENTRIES - 1)) + OBJ_HASH_HEAD_ENTRIES_START)
189 #define ObjRefHead(bin) (objHashTable[ObjGetHashElem((bin), FALSE)].ref) /* don't change this */
190 #else
191 #define ObjRefHead(bin) (MAP_GET_XY((bin).sq.x, (bin).sq.y))->objRef
192 #endif
193 
194 //                          ////////////////////////////////
195 //                          //
196 ////////////////////////////// WASN'T THAT EASY?
197 
198 typedef struct {
199     ObjRefStateBin bin;
200 } ObjRefState;
201 
202 typedef struct {
203     ObjRefStateBin bin;
204     ObjRefStateInfo info;
205 } oldObjRefState;
206 
207 // The following macros perform simple comparing and copying operations.
208 // If your structures are immensely complicated, you can turn them into
209 // functions.  It will slow things down, though.
210 
211 // isnt it neat that you cant do sizeof(ObjRefStateBin) in a #if
212 // i love cpp with an unholy, inhuman, and altogether pathetic way
213 
214 #if (SIZEOF_AN_OBJREFSTATEBIN == 4)
215 #define ObjRefStateBinEqual(bin1, bin2) (*((int *)(&bin1)) == *((int *)(&bin2)))
216 #elif (SIZEOF_AN_OBJREFSTATEBIN == 2)
217 #define ObjRefStateBinEqual(bin1, bin2) (*((short *)(&bin1)) == *((short *)(&bin2)))
218 #elif (SIZEOF_AN_OBJREFSTATEBIN == 1)
219 #define ObjRefStateBinEqual(bin1, bin2) (*((char *)(&bin1)) == *((char *)(&bin2)))
220 #else
221 #define ObjRefStateBinEqual(bin1, bin2) (!memcmp(&(bin1), &(bin2), sizeof(ObjRefStateBin)))
222 #endif
223 #define ObjRefStateBinCopy(srcbin, dstbin) \
224     do {                                   \
225         dstbin = srcbin;                   \
226     } while (0)
227 
228 #ifndef NO_OBJ_REF_STATE_INFO
229 #if (SIZEOF_AN_OBJREFSTATEINFO == 4)
230 #define ObjRefStateInfoEqual(info1, info2) (*((int *)(&info1)) == *((int *)(&info2)))
231 #elif (SIZEOF_AN_OBJREFSTATEINFO == 2)
232 #define ObjRefStateInfoEqual(info1, info2) (*((short *)(&info1)) == *((short *)(&info2)))
233 #elif (SIZEOF_AN_OBJREFSTATEINFO == 1)
234 #define ObjRefStateInfoEqual(info1, info2) (*((char *)(&info1)) == *((char *)(&info2)))
235 #else
236 #define ObjRefStateInfoEqual(info1, info2) (!memcmp(&(info1), &(info2), sizeof(ObjRefStateInfo)))
237 #endif
238 #define ObjRefStateInfoCopy(srcinfo, dstinfo) \
239     do {                                      \
240         dstinfo = srcinfo;                    \
241     } while (0)
242 #endif
243 
244 #if (SIZEOF_AN_OBJLOC == 4)
245 #define ObjLocEqual(bin1, bin2) (*((int *)(&bin1)) == *((int *)(&bin2)))
246 #elif (SIZEOF_AN_OBJLOC == 2)
247 #define ObjLocEqual(bin1, bin2) (*((short *)(&bin1)) == *((short *)(&bin2)))
248 #elif (SIZEOF_AN_OBJLOC == 1)
249 #define ObjLocEqual(bin1, bin2) (*((char *)(&bin1)) == *((char *)(&bin2)))
250 #else
251 #define ObjLocEqual(bin1, bin2) (!memcmp(&(bin1), &(bin2), sizeof(ObjLoc)))
252 #endif
253 #define ObjLocCopy(srcbin, dstbin) \
254     do {                           \
255         dstbin = srcbin;           \
256     } while (0)
257 
258 ////////////////////////////// MORE STUFF YOU MUST CHANGE
259 //                          //
260 //                          ////////////////////////////////
261 //
262 // You can turn some of the following macros into functions, if they get complicated.
263 //
264 // These are all for the use of the debugging system.  They should print
265 // a user-friendly representation of the appropriate structure into str,
266 // without a trailing newline.
267 
268 #define ObjRefStateSprint(str, refstate)
269 #define ObjRefStateBinSprint(str, bin)
270 #define ObjRefStateInfoSprint(str, info)
271 #define ObjLocSprint(str, loc)
272 #define ObjInfoSprint(str, info)
273 
274 //                          ////////////////////////////////
275 //                          //
276 ////////////////////////////// END OF STUFF YOU MUST CHANGE
277 
278 ////////////////////////////////////////////////////////////
279 //
280 // Here are prototypes of a few functions you should define in
281 // objapp.c.  Any macros above that you decided to turn into functions
282 // should also be defined in objapp.c.
283 //
284 
285 void ObjInfoInit(ObjInfo *info);
286 
287 //////////////////////////////
288 //
289 // This should initialize the following iterator.  Nice name, huh?
290 
291 void ObjRefStateBinIteratorInit(void);
292 
293 //////////////////////////////
294 //
295 // After ObjRefStateBinIteratorInit () has been called, calling this
296 // should put a new valid ObjRefStateBin in bin every time it is called.
297 // It returns FALSE if it has already returned all valid bins (in which
298 // case the value of bin is undefined); otherwise it returns TRUE, of
299 // course.
300 //
301 // It can use static variables; the iterator is guaranteed to be active
302 // only once at a time.
303 
304 uchar ObjRefStateBinIterator(ObjRefStateBin *bin);
305 
306 #pragma pack(pop)
307 
308 #endif // OBJAPP_H
309