1 /* 2 C-Dogs SDL 3 A port of the legendary (and fun) action/arcade cdogs. 4 Copyright (C) 1995 Ronny Wester 5 Copyright (C) 2003 Jeremy Chin 6 Copyright (C) 2003-2007 Lucas Martin-King 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 22 This file incorporates work covered by the following copyright and 23 permission notice: 24 25 Copyright (c) 2013-2017, 2019-2021 Cong Xu 26 All rights reserved. 27 28 Redistribution and use in source and binary forms, with or without 29 modification, are permitted provided that the following conditions are met: 30 31 Redistributions of source code must retain the above copyright notice, this 32 list of conditions and the following disclaimer. 33 Redistributions in binary form must reproduce the above copyright notice, 34 this list of conditions and the following disclaimer in the documentation 35 and/or other materials provided with the distribution. 36 37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 38 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 41 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 42 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 43 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 44 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 45 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 47 POSSIBILITY OF SUCH DAMAGE. 48 */ 49 #pragma once 50 51 #include <assert.h> 52 #include <stdbool.h> 53 #include <stdio.h> /* for stderr */ 54 #include <stdlib.h> 55 #include <string.h> 56 57 #include "color.h" 58 #include "sys_specifics.h" 59 60 // Global variables so their address can be taken (passed into void * funcs) 61 extern bool gTrue; 62 extern bool gFalse; 63 64 #define STRINGIFY(x) #x 65 #define TOSTRING(x) STRINGIFY(x) 66 67 #ifdef _MSC_VER 68 #define CHALT() __debugbreak() 69 #else 70 #define CHALT() 71 #endif 72 73 #define CASSERT(_x, _errmsg) \ 74 { \ 75 volatile bool isOk = _x; \ 76 if (!isOk) \ 77 { \ 78 static char _buf[1024]; \ 79 sprintf( \ 80 _buf, "In %s %d:%s: " _errmsg " (" #_x ")", __FILE__, \ 81 __LINE__, __func__); \ 82 CHALT(); \ 83 assert(_x); \ 84 } \ 85 } 86 87 // Even though malloc(0) may return NULL, we don't account for it for 88 // simplicity and to allow code linters to work better 89 #define _CCHECKALLOC(_func, _var, _size) \ 90 { \ 91 if (_var == NULL) \ 92 { \ 93 exit(1); \ 94 } \ 95 } 96 97 #define CMALLOC(_var, _size) \ 98 { \ 99 _var = malloc(_size); \ 100 _CCHECKALLOC("CMALLOC", _var, (_size)) \ 101 } 102 #define CCALLOC(_var, _size) \ 103 { \ 104 _var = calloc(1, _size); \ 105 _CCHECKALLOC("CCALLOC", _var, (_size)) \ 106 } 107 #define CREALLOC(_var, _size) \ 108 { \ 109 _var = realloc(_var, _size); \ 110 _CCHECKALLOC("CREALLOC", _var, (_size)) \ 111 } 112 #define CSTRDUP(_var, _str) \ 113 { \ 114 CMALLOC(_var, strlen(_str) + 1); \ 115 strcpy(_var, _str); \ 116 } 117 118 #define CFREE(_var) \ 119 { \ 120 free(_var); \ 121 } 122 123 #define UNUSED(expr) (void)(expr); 124 125 #ifndef MAX 126 #define MAX(x, y) ((x) > (y) ? (x) : (y)) 127 #endif 128 #ifndef MIN 129 #define MIN(x, y) ((x) < (y) ? (x) : (y)) 130 #endif 131 #define CLAMP(v, _min, _max) MAX((_min), MIN((_max), (v))) 132 #define CLAMP_OPPOSITE(v, _min, _max) \ 133 ((v) > (_max) ? (_min) : ((v) < (_min) ? (_max) : (v))) 134 #define SIGN(x) ((x) != 0 ? (x) / abs(x) : 1) 135 #define SQUARED(x) ((x) * (x)) 136 #define SWAP(x, y, T) \ 137 do \ 138 { \ 139 T _tmp = x; \ 140 x = y; \ 141 y = _tmp; \ 142 } while (0) 143 144 const char *StrGetFileExt(const char *filename); 145 146 void PathGetDirname(char *buf, const char *path); 147 // Given /path/to/file, return file 148 const char *PathGetBasename(const char *path); 149 void PathGetWithoutExtension(char *buf, const char *path); 150 void PathGetBasenameWithoutExtension(char *buf, const char *path); 151 void RealPath(const char *src, char *dest); 152 void RelPath(char *buf, const char *to, const char *from); 153 void FixPathSeparator(char *dst, const char *src); 154 char *CDogsGetCWD(char *buf); 155 void RelPathFromCWD(char *buf, const char *to); 156 void GetDataFilePath(char *buf, const char *path); 157 158 double Round(double x); 159 160 double ToDegrees(double radians); 161 162 struct vec2 CalcClosestPointOnLineSegmentToPoint( 163 const struct vec2 l1, const struct vec2 l2, const struct vec2 p); 164 165 typedef enum 166 { 167 INPUT_DEVICE_UNSET, 168 INPUT_DEVICE_KEYBOARD, 169 INPUT_DEVICE_MOUSE, 170 INPUT_DEVICE_JOYSTICK, 171 172 // Fake device used for co-op AI 173 INPUT_DEVICE_AI, 174 175 INPUT_DEVICE_COUNT 176 } input_device_e; 177 178 const char *InputDeviceName(const int d, const int deviceIndex); 179 180 typedef enum 181 { 182 ALLYCOLLISION_NORMAL, 183 ALLYCOLLISION_REPEL, 184 ALLYCOLLISION_NONE 185 } AllyCollision; 186 const char *AllyCollisionStr(int a); 187 int StrAllyCollision(const char *str); 188 189 char *IntStr(int i); 190 char *PercentStr(int p); 191 char *Div8Str(int i); 192 void CamelToTitle(char *buf, const char *src); 193 bool StrEndsWith(const char *str, const char *suffix); 194 int Stricmp(const char *a, const char *b); 195 int CompareIntsAsc(const void *v1, const void *v2); 196 int CompareIntsDesc(const void *v1, const void *v2); 197 bool IntsEqual(const void *v1, const void *v2); 198 199 // Helper macros for defining type/str conversion funcs 200 #define T2S(_type, _str) \ 201 case _type: \ 202 return _str; 203 #define S2T(_type, _str) \ 204 if (strcmp(s, _str) == 0) \ 205 { \ 206 return _type; \ 207 } 208 209 #define RAND_INT(_low, _high) \ 210 ((_low) == (_high) ? (_low) : (_low) + (rand() % ((_high) - (_low)))) 211 #define RAND_FLOAT(_low, _high) \ 212 ((_low) + ((float)rand() / RAND_MAX * ((_high) - (_low)))) 213 #define RAND_DOUBLE(_low, _high) \ 214 ((_low) + ((double)rand() / RAND_MAX * ((_high) - (_low)))) 215 #define RAND_BOOL() (RAND_INT(0, 1) == 0) 216 217 typedef enum 218 { 219 BODY_PART_HEAD, 220 BODY_PART_HAIR, 221 BODY_PART_BODY, 222 BODY_PART_LEGS, 223 BODY_PART_GUN_R, 224 BODY_PART_GUN_L, 225 BODY_PART_COUNT 226 } BodyPart; 227 228 BodyPart StrBodyPart(const char *s); 229 230 typedef enum 231 { 232 PLACEMENT_ACCESS_ANY, // place anywhere 233 PLACEMENT_ACCESS_LOCKED, // place in locked rooms 234 PLACEMENT_ACCESS_NOT_LOCKED // don't place in locked rooms 235 } PlacementAccessFlags; 236 237 int Pulse256(const int t); 238