1 #ifndef GLOBALDATA_DEFINE 2 #define GLOBALDATA_DEFINE 3 /* 4 * atanks - obliterate each other with oversize weapons 5 * Copyright (C) 2003 Thomas Hudson 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program 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. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 * 21 */ 22 23 #include "main.h" 24 25 26 #include <sys/types.h> 27 #include <atomic> 28 29 30 #ifndef HAS_DIRENT 31 # if defined(ATANKS_IS_MSVC) 32 # include "extern/dirent.h" 33 # else 34 # include <dirent.h> 35 # endif // Linux 36 # define HAS_DIRENT 1 37 #endif //HAS_DIRENT 38 39 40 #ifdef USE_MUTEX_INSTEAD_OF_SPINLOCK 41 # include <mutex> 42 # define CSpinLock std::mutex 43 #endif // USE_MUTEX_INSTEAD_OF_SPINLOCK 44 45 46 #include "text.h" 47 #include "globaltypes.h" 48 #include "environment.h" 49 50 51 extern int32_t BLACK; 52 53 54 /// Forwards that do not need to be known here 55 struct sDebrisItem; 56 struct sDebrisPool; 57 class PLAYER; 58 class TANK; 59 class VIRTUAL_OBJECT; 60 61 62 #ifndef USE_MUTEX_INSTEAD_OF_SPINLOCK 63 /** @brief minimal spinlock class 64 * It can do nothing but lock and unlock. No recursive locks. 65 * But then it is a lot faster and leaner than mutexes and critical 66 * sections ever can be. ;) 67 **/ 68 class CSpinLock 69 { 70 public: 71 explicit CSpinLock(); 72 ~CSpinLock(); 73 74 CSpinLock(const CSpinLock&) = delete; 75 CSpinLock &operator=(const CSpinLock&) = delete; 76 77 bool hasLock(); 78 void lock(); 79 void unlock(); 80 private: 81 82 abool_t is_destroyed; 83 aflag_t lock_flag; 84 std::thread::id owner_id; 85 }; 86 #endif // USE_MUTEX_INSTEAD_OF_SPINLOCK 87 88 89 /** @class GLOBALDATA 90 * @brief Values used globally during a game round. 91 * 92 * This class holds all values and the corresponding functions for everything 93 * that can change during a game round. 94 * 95 * Everything that is fixed during a game round is consolidated in ENVIRONMENT. 96 **/ 97 class GLOBALDATA 98 { 99 typedef VIRTUAL_OBJECT vobj_t; 100 typedef sDebrisItem item_t; 101 102 public: 103 104 /* ----------------------------------- 105 * --- Constructors and destructor --- 106 * ----------------------------------- 107 */ 108 109 explicit GLOBALDATA (); 110 ~GLOBALDATA(); 111 112 113 /* ---------------------- 114 * --- Public methods --- 115 * ---------------------- 116 */ 117 void addLandSlide (int32_t left, int32_t right, bool do_lock); 118 void addObject (vobj_t* object); 119 bool areTanksInBox (int32_t x1, int32_t y1, int32_t x2, int32_t y2); 120 bool check_time_changed(); // check to see if one second has passed 121 void clear_objects (); 122 void destroy (); 123 void do_updates (); 124 void first_init (); 125 void free_debris_item (item_t* item); 126 int32_t get_avg_bgcolor (int32_t x1, int32_t y1, int32_t x2, int32_t y2, 127 double xv, double yv); 128 int32_t get_command (); 129 TANK* get_curr_tank (); 130 item_t* get_debris_item (int32_t radius); 131 TANK* get_next_tank (bool* wrapped_around); 132 void initialise (); 133 bool isCloseBtnPressed (); 134 bool isDirtInBox (int32_t x1, int32_t y1, int32_t x2, int32_t y2); 135 void load_from_file (FILE* file); 136 void lockClass (eClasses class_); 137 void lockLand (); 138 void make_bgupdate (int32_t x, int32_t y, int32_t w, int32_t h); 139 void make_fullUpdate (); 140 void make_update (int32_t x, int32_t y, int32_t w, int32_t h); 141 void newRound (); 142 void pressCloseButton (); 143 void removeObject (vobj_t* object); 144 void removeTank (TANK* tank); 145 void replace_canvas (); 146 bool save_to_file (FILE* file); 147 void set_curr_tank (TANK* tank_); 148 void set_command (int32_t cmd); 149 void slideLand (); 150 void unlockClass (eClasses class_); 151 void unlockLand (); 152 void unlockLandSlide (int32_t left, int32_t right); 153 154 template<typename Head_T> getHeadOfClass(eClasses class_,Head_T ** head_)155 void getHeadOfClass (eClasses class_, Head_T** head_) 156 { 157 if (class_ < CLASS_COUNT) { 158 objLocks[class_].lock(); 159 *head_ = static_cast<Head_T*>(heads[class_]); 160 objLocks[class_].unlock(); 161 } else 162 *head_ = nullptr; 163 } 164 165 166 167 /* ---------------------- 168 * --- Public members --- 169 * ---------------------- 170 */ 171 172 int32_t AI_clock = -1; 173 BITMAP* canvas = nullptr; 174 const char* client_message = nullptr; // message sent from client to main menu 175 PLAYER* client_player = nullptr; // the index we use to know which one is the player on the client side 176 int32_t curland = 0; 177 int32_t current_drawing_mode = DRAW_MODE_SOLID; 178 uint32_t currentround = 0; 179 int32_t cursky = 0; 180 bool demo_mode = false; 181 bool hasTooMuchDeco = false; // Set to true if the set FPS are too hard to reach. 182 BOX* lastUpdates = nullptr; 183 int32_t lastUpdatesCount = 0; 184 double lastwind = 0.; 185 int32_t naturals_activated = 0; 186 int32_t numTanks = 0; 187 TANK* order[MAXPLAYERS]; 188 bool showScoreBoard = false; 189 bool skippingComputerPlay = false; 190 int32_t stage = STAGE_AIM; 191 bool stopwindow = false; 192 ai32_t* surface = nullptr; 193 char tank_status[128]; 194 int32_t tank_status_colour = BLACK; 195 BITMAP* terrain = nullptr; 196 bool updateMenu = true; 197 BOX* updates = nullptr; 198 char* update_string = nullptr; 199 int32_t used_voices = 0; 200 double wind = 0.; 201 202 203 private: 204 205 typedef sDebrisPool debpool_t; 206 207 208 /* ----------------------- 209 * --- Private methods --- 210 * ----------------------- 211 */ 212 213 // Combine make_update and make_bgupdate with safety checks 214 void addUpdate(int32_t x, int32_t y, int32_t w, int32_t h, BOX* target, 215 int32_t &target_count); 216 217 218 /* ----------------------- 219 * --- Private members --- 220 * ----------------------- 221 */ 222 223 bool close_button_pressed = false; 224 CSpinLock cbpLock; //[c]lose_[b]utton_[p]ressed 225 CSpinLock cmdLock; 226 bool combineUpdates = true; 227 int32_t command = 0; 228 TANK* currTank = nullptr; 229 debpool_t* debris_pool = nullptr; 230 int8_t* done = nullptr; 231 double* dropIncr = nullptr; 232 int32_t* dropTo = nullptr; 233 int32_t* fp = nullptr; 234 vobj_t* heads[CLASS_COUNT]; 235 CSpinLock landLock; 236 CSpinLock objLocks[CLASS_COUNT]; 237 vobj_t* tails[CLASS_COUNT]; 238 int32_t tankindex = 0; 239 int32_t updateCount = 0; 240 double* velocity = nullptr; 241 }; 242 243 #define HAS_GLOBALDATA 1 244 245 #endif 246