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