Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 1 | //------------------------------------------------------------------------- |
| 2 | /* |
| 3 | Copyright (C) 1996, 2003 - 3D Realms Entertainment |
| 4 | |
| 5 | This file is part of Duke Nukem 3D version 1.5 - Atomic Edition |
| 6 | |
| 7 | Duke Nukem 3D 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. |
| 15 | |
| 16 | See the GNU General Public License for more details. |
| 17 | |
| 18 | You should have received a copy of the GNU General Public License |
| 19 | aint32_t 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 | Original Source: 1996 - Todd Replogle |
| 23 | Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms |
| 24 | */ |
| 25 | //------------------------------------------------------------------------- |
| 26 | |
| 27 | #include <stdio.h> |
| 28 | #include <stdlib.h> |
| 29 | #include <string.h> |
| 30 | #include <stdarg.h> |
| 31 | #include <errno.h> |
| 32 | #include "global.h" |
| 33 | #include "duke3d.h" |
| 34 | |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 35 | char *mymembuf; |
| 36 | uint8_t MusicPtr[72000]; |
| 37 | |
| 38 | |
| 39 | crc32_t crc32lookup[] = { |
| 40 | // good: |
| 41 | { CRC_BASE_GRP_SHAREWARE_13, "SHAREWARE 1.3D", 11035779 }, |
| 42 | { CRC_BASE_GRP_FULL_13, "FULL 1.3D ", 26524524 }, |
| 43 | { CRC_BASE_GRP_PLUTONIUM_14, "PLUTONIUM 1.4 ", 44348015 }, |
| 44 | { CRC_BASE_GRP_ATOMIC_15, "ATOMIC 1.5 ", 44356548 }, |
| 45 | // unknown: |
| 46 | { 0, "HACK/UNKNOWN ", 0} |
| 47 | }; |
| 48 | |
| 49 | uint8_t conVersion = 13; |
| 50 | uint8_t grpVersion = 0; |
| 51 | |
| 52 | // FIX_00015: Backward compliance with older demos (down to demos v27, 28, 116 and 117 only) |
| 53 | |
| 54 | // For BYTEVERSION diff, 27/116 vs 28/117 see extras\duke3d.h vs source\duke3d.h |
| 55 | // from the official source code release. |
| 56 | |
| 57 | int BYTEVERSION_27 = 27; // 1.3 under 1.4 Plutonium. Not supported anymore |
| 58 | int BYTEVERSION_116 = 116; // 1.4 Plutonium. Not supported anymore |
| 59 | |
| 60 | int BYTEVERSION_28 = 28; // 1.3 under 1.5 engine |
| 61 | int BYTEVERSION_117 = 117; // 1.5 Atomic |
| 62 | |
| 63 | int BYTEVERSION_29 = 29; // 1.3 under xDuke v19.6. |
| 64 | int BYTEVERSION_118 = 118; // 1.5 Atomic under xDuke v19.6. |
| 65 | |
| 66 | int BYTEVERSION_1_3 = 1; // for 1.3 demos (Not compatible) |
| 67 | |
| 68 | int BYTEVERSION = 119; // xDuke v19.7 |
| 69 | |
| 70 | short global_random; |
| 71 | short neartagsector, neartagwall, neartagsprite; |
| 72 | |
| 73 | int32_t gc,neartaghitdist,lockclock,max_player_health,max_armour_amount,max_ammo_amount[MAX_WEAPONS]; |
| 74 | |
| 75 | // int32_t temp_data[MAXSPRITES][6]; |
| 76 | struct weaponhit hittype[MAXSPRITES]; |
| 77 | short spriteq[1024],spriteqloc,spriteqamount=64; |
| 78 | |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 79 | struct animwalltype animwall[MAXANIMWALLS]; |
| 80 | short numanimwalls; |
| 81 | int32_t *animateptr[MAXANIMATES], animategoal[MAXANIMATES], animatevel[MAXANIMATES], animatecnt; |
| 82 | // int32_t oanimateval[MAXANIMATES]; |
| 83 | short animatesect[MAXANIMATES]; |
| 84 | int32_t msx[2048],msy[2048]; |
| 85 | short cyclers[MAXCYCLERS][6],numcyclers; |
| 86 | |
| 87 | char fta_quotes[NUMOFFIRSTTIMEACTIVE][64]; |
| 88 | |
| 89 | uint8_t tempbuf[2048]; |
| 90 | uint8_t packbuf[576]; |
| 91 | |
| 92 | char buf[80]; |
| 93 | |
| 94 | short camsprite; |
| 95 | short mirrorwall[64], mirrorsector[64], mirrorcnt; |
| 96 | |
| 97 | int current_menu; |
| 98 | |
| 99 | uint8_t betaname[80]; |
| 100 | |
| 101 | char level_names[44][33]; |
| 102 | char level_file_names[44][128]; |
| 103 | int32_t partime[44],designertime[44]; |
| 104 | char volume_names[4][33] = { "L.A. MELTDOWN", "LUNAR APOCALYPSE", "SHRAPNEL CITY", "" }; // Names are not in 1.3 con files. MUST be in code. |
| 105 | char skill_names[5][33] = { "PIECE OF CAKE", "LET'S ROCK", "COME GET SOME", "DAMN I'M GOOD", "" }; |
| 106 | |
| 107 | volatile int32_t checksume; |
| 108 | int32_t soundsiz[NUM_SOUNDS]; |
| 109 | |
| 110 | short soundps[NUM_SOUNDS],soundpe[NUM_SOUNDS],soundvo[NUM_SOUNDS]; |
| 111 | uint8_t soundm[NUM_SOUNDS],soundpr[NUM_SOUNDS]; |
| 112 | char sounds[NUM_SOUNDS][14]; |
| 113 | |
| 114 | short title_zoom; |
| 115 | |
| 116 | fx_device device; |
| 117 | |
| 118 | SAMPLE Sound[ NUM_SOUNDS ]; |
| 119 | SOUNDOWNER SoundOwner[NUM_SOUNDS][4]; |
| 120 | |
| 121 | uint8_t numplayersprites,earthquaketime; |
| 122 | |
| 123 | int32_t fricxv,fricyv; |
| 124 | struct player_orig po[MAXPLAYERS]; |
| 125 | struct player_struct ps[MAXPLAYERS]; |
| 126 | struct user_defs ud; |
| 127 | |
| 128 | uint8_t pus, pub; |
| 129 | uint8_t syncstat, syncval[MAXPLAYERS][MOVEFIFOSIZ]; |
| 130 | int32_t syncvalhead[MAXPLAYERS], syncvaltail, syncvaltottail; |
| 131 | |
| 132 | input sync[MAXPLAYERS], loc; |
| 133 | input recsync[RECSYNCBUFSIZ]; |
| 134 | int32_t avgfvel, avgsvel, avgavel, avghorz, avgbits; |
| 135 | |
| 136 | |
| 137 | input inputfifo[MOVEFIFOSIZ][MAXPLAYERS]; |
| 138 | input recsync[RECSYNCBUFSIZ]; |
| 139 | |
| 140 | int32_t movefifosendplc; |
| 141 | |
| 142 | //Multiplayer syncing variables |
| 143 | short screenpeek; |
| 144 | int32_t movefifoend[MAXPLAYERS]; |
| 145 | |
| 146 | |
| 147 | //Game recording variables |
| 148 | |
| 149 | uint8_t playerreadyflag[MAXPLAYERS],ready2send; |
| 150 | uint8_t playerquitflag[MAXPLAYERS]; |
| 151 | int32_t vel, svel, angvel, horiz, ototalclock, respawnactortime=768, respawnitemtime=768, groupfile; |
| 152 | |
| 153 | int32_t script[MAXSCRIPTSIZE],*scriptptr,*insptr,*labelcode,labelcnt; |
| 154 | int32_t *actorscrptr[MAXTILES],*parsing_actor; |
| 155 | char *label,*textptr,error,warning ; |
| 156 | uint8_t killit_flag; |
| 157 | uint8_t *music_pointer; |
| 158 | uint8_t actortype[MAXTILES]; |
| 159 | |
| 160 | |
| 161 | uint8_t display_mirror,typebuflen; |
| 162 | char typebuf[41]; |
| 163 | |
| 164 | char music_fn[4][11][13]; |
| 165 | uint8_t music_select; |
| 166 | char env_music_fn[4][13]; |
| 167 | uint8_t rtsplaying; |
| 168 | |
| 169 | |
| 170 | short weaponsandammosprites[15] = { |
| 171 | RPGSPRITE, |
| 172 | CHAINGUNSPRITE, |
| 173 | DEVISTATORAMMO, |
| 174 | RPGAMMO, |
| 175 | RPGAMMO, |
| 176 | JETPACK, |
| 177 | SHIELD, |
| 178 | FIRSTAID, |
| 179 | STEROIDS, |
| 180 | RPGAMMO, |
| 181 | RPGAMMO, |
| 182 | RPGSPRITE, |
| 183 | RPGAMMO, |
| 184 | FREEZESPRITE, |
| 185 | FREEZEAMMO |
| 186 | }; |
| 187 | |
| 188 | int32_t impact_damage; |
| 189 | |
| 190 | //GLOBAL.C - replace the end "my's" with this |
| 191 | int32_t myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel; |
| 192 | short myhoriz, omyhoriz, myhorizoff, omyhorizoff; |
| 193 | short myang, omyang, mycursectnum, myjumpingcounter,frags[MAXPLAYERS][MAXPLAYERS]; |
| 194 | |
| 195 | uint8_t myjumpingtoggle, myonground, myhardlanding, myreturntocenter; |
| 196 | int8_t multiwho, multipos, multiwhat, multiflag; |
| 197 | |
| 198 | int32_t fakemovefifoplc,movefifoplc; |
| 199 | int32_t myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; |
| 200 | int32_t myhorizbak[MOVEFIFOSIZ],dukefriction = 0xcc00, show_shareware; |
| 201 | |
| 202 | short myangbak[MOVEFIFOSIZ]; |
| 203 | char myname[2048] = "XDUKE"; |
| 204 | uint8_t camerashitable,freezerhurtowner=0,lasermode; |
| 205 | // CTW - MODIFICATION |
| 206 | // uint8_t networkmode = 255, movesperpacket = 1,gamequit = 0,playonten = 0,everyothertime; |
| 207 | uint8_t networkmode = 255, movesperpacket = 1,gamequit = 0,everyothertime; |
| 208 | // CTW END - MODIFICATION |
| 209 | int32_t numfreezebounces=3,rpgblastradius,pipebombblastradius,tripbombblastradius,shrinkerblastradius,morterblastradius,bouncemineblastradius,seenineblastradius; |
| 210 | STATUSBARTYPE sbar; |
| 211 | |
| 212 | int32_t myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1; |
| 213 | short numclouds,clouds[128],cloudx[128],cloudy[128]; |
| 214 | int32_t cloudtotalclock = 0,totalmemory = 0; |
| 215 | int32_t numinterpolations = 0, startofdynamicinterpolations = 0; |
| 216 | int32_t oldipos[MAXINTERPOLATIONS]; |
| 217 | int32_t bakipos[MAXINTERPOLATIONS]; |
| 218 | int32_t *curipos[MAXINTERPOLATIONS]; |
| 219 | |
| 220 | |
| 221 | // portability stuff. --ryan. |
| 222 | // A good portion of this was ripped from GPL'd Rise of the Triad. --ryan. |
| 223 | |
| 224 | #ifndef PATH_SEP_CHAR |
| 225 | #define PATH_SEP_CHAR '/' |
| 226 | #endif |
| 227 | |
| 228 | void FixFilePath(char *filename) |
| 229 | { |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 230 | uint8_t *ptr; |
| 231 | uint8_t *lastsep = filename; |
| 232 | |
| 233 | if ((!filename) || (*filename == '\0')) |
| 234 | return; |
| 235 | if(filename[0] != '/') |
| 236 | LOGF("%s is not absolute", filename); |
| 237 | |
| 238 | if (rb->file_exists(filename)) /* File exists; we're good to go. */ |
| 239 | return; |
| 240 | |
| 241 | for (ptr = filename; 1; ptr++) |
| 242 | { |
| 243 | if (*ptr == '\\') |
| 244 | *ptr = PATH_SEP_CHAR; |
| 245 | |
| 246 | if ((*ptr == PATH_SEP_CHAR) || (*ptr == '\0')) |
| 247 | { |
| 248 | uint8_t pch = *ptr; |
| 249 | struct dirent *dent = NULL; |
| 250 | DIR *dir; |
| 251 | |
| 252 | if ((pch == PATH_SEP_CHAR) && (*(ptr + 1) == '\0')) |
| 253 | return; /* eos is pathsep; we're done. */ |
| 254 | |
| 255 | if (lastsep == ptr) |
| 256 | continue; /* absolute path; skip to next one. */ |
| 257 | |
| 258 | *ptr = '\0'; |
| 259 | if (lastsep == filename) { |
| 260 | dir = opendir((*lastsep == PATH_SEP_CHAR) ? "/" : "/"); |
| 261 | |
| 262 | if (*lastsep == PATH_SEP_CHAR) { |
| 263 | lastsep++; |
| 264 | } |
| 265 | } |
| 266 | else |
| 267 | { |
| 268 | *lastsep = '\0'; |
| 269 | dir = opendir(filename); |
| 270 | *lastsep = PATH_SEP_CHAR; |
| 271 | lastsep++; |
| 272 | } |
| 273 | |
| 274 | if (dir == NULL) |
| 275 | { |
| 276 | *ptr = PATH_SEP_CHAR; |
| 277 | return; /* maybe dir doesn't exist? give up. */ |
| 278 | } |
| 279 | |
| 280 | while ((dent = readdir(dir)) != NULL) |
| 281 | { |
| 282 | if (strcasecmp(dent->d_name, lastsep) == 0) |
| 283 | { |
| 284 | /* found match; replace it. */ |
| 285 | strcpy(lastsep, dent->d_name); |
| 286 | break; |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | closedir(dir); |
| 291 | *ptr = pch; |
| 292 | lastsep = ptr; |
| 293 | |
| 294 | if (dent == NULL) |
| 295 | return; /* no match. oh well. */ |
| 296 | |
| 297 | if (pch == '\0') /* eos? */ |
| 298 | return; |
| 299 | } |
| 300 | } |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 301 | } |
| 302 | |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 303 | static int check_pattern_nocase(const char *x, const char *y) |
| 304 | { |
| 305 | if ((x == NULL) || (y == NULL)) |
| 306 | return(0); /* not a match. */ |
| 307 | |
| 308 | while ((*x) && (*y)) |
| 309 | { |
| 310 | if (*x == '*') |
| 311 | { |
| 312 | x++; |
| 313 | while (*y != '\0') |
| 314 | { |
| 315 | if (toupper((int) *x) == toupper((int) *y)) |
| 316 | break; |
| 317 | y++; |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | else if (*x == '?') |
| 322 | { |
| 323 | if (*y == '\0') |
| 324 | return(0); /* anything but EOS is okay. */ |
| 325 | } |
| 326 | |
| 327 | else |
| 328 | { |
| 329 | if (toupper((int) *x) != toupper((int) *y)) |
| 330 | return(0); /* not a match. */ |
| 331 | } |
| 332 | |
| 333 | x++; |
| 334 | y++; |
| 335 | } |
| 336 | |
| 337 | return(*x == *y); /* it's a match (both should be EOS). */ |
| 338 | } |
| 339 | |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 340 | int FindDistance2D(int ix, int iy) |
| 341 | { |
| 342 | int t; |
| 343 | |
| 344 | ix= abs(ix); /* absolute values */ |
| 345 | iy= abs(iy); |
| 346 | |
| 347 | if (ix<iy) |
| 348 | { |
| 349 | int tmp = ix; |
| 350 | ix = iy; |
| 351 | iy = tmp; |
| 352 | } |
| 353 | |
| 354 | t = iy + (iy>>1); |
| 355 | |
| 356 | return (ix - (ix>>5) - (ix>>7) + (t>>2) + (t>>6)); |
| 357 | } |
| 358 | |
| 359 | int FindDistance3D(int ix, int iy, int iz) |
| 360 | { |
| 361 | int t; |
| 362 | |
| 363 | ix= abs(ix); /* absolute values */ |
| 364 | iy= abs(iy); |
| 365 | iz= abs(iz); |
| 366 | |
| 367 | if (ix<iy) |
| 368 | { |
| 369 | int tmp = ix; |
| 370 | ix = iy; |
| 371 | iy = tmp; |
| 372 | } |
| 373 | |
| 374 | if (ix<iz) |
| 375 | { |
| 376 | int tmp = ix; |
| 377 | ix = iz; |
| 378 | iz = tmp; |
| 379 | } |
| 380 | |
| 381 | t = iy + iz; |
| 382 | |
| 383 | return (ix - (ix>>4) + (t>>2) + (t>>3)); |
| 384 | } |
| 385 | #include "SDL.h" |
| 386 | void Error (int errorType, char *error, ...) |
| 387 | { |
| 388 | va_list argptr; |
| 389 | |
| 390 | SDL_Quit(); |
| 391 | |
| 392 | //FCS: http://duke3d.m-klein.com is obscolete :/ ! |
| 393 | /* |
| 394 | if(errorType==EXIT_FAILURE) |
| 395 | printf("ERROR: Please copy that screen and visit http://duke3d.m-klein.com for report:\n"); |
| 396 | else |
| 397 | printf("http://duke3d.m-klein.com\n"); |
| 398 | */ |
| 399 | |
| 400 | |
| 401 | va_start (argptr, error); |
| 402 | vprintf(error, argptr); |
| 403 | va_end (argptr); |
| 404 | |
| 405 | //printf("Press any key to continue...\n"); |
| 406 | |
| 407 | // FIX_00043: Nicer exit on error. Ask the user to hit a key on exits and error exits. |
| 408 | //getch(); |
| 409 | |
| 410 | exit (errorType); |
| 411 | } |
| 412 | |
| 413 | void write2disk(int line, char * cfilename, char *filename2write, char *message) |
| 414 | { |
| 415 | // usage: write2disk(__LINE__, __FILE__, "c:\temp\my_dbug_file.txt", uint8_t * msg); |
| 416 | |
| 417 | int i, k=0; |
| 418 | char filename[2048]; |
| 419 | FILE *pFile; |
| 420 | |
| 421 | for(i=0; cfilename[i]; i++) |
| 422 | { |
| 423 | if(cfilename[i]=='\\') |
| 424 | { |
| 425 | i++; |
| 426 | k = 0; |
| 427 | } |
| 428 | filename[k++]=(cfilename[i]=='.')?0:cfilename[i]; |
| 429 | } |
| 430 | pFile = fopen(filename2write,"a"); |
| 431 | fprintf(pFile,"%-4d %-5s %s", line, filename, message); |
| 432 | fclose(pFile); |
| 433 | } |
| 434 | |
| 435 | int32 SafeOpenAppend (const char *_filename, int32 filetype) |
| 436 | { |
| 437 | int handle; |
| 438 | char filename[MAX_PATH]; |
| 439 | |
| 440 | strncpy(filename, _filename, sizeof (filename)); |
| 441 | filename[sizeof (filename) - 1] = '\0'; |
| 442 | FixFilePath(filename); |
| 443 | |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 444 | handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_APPEND , 0666); |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 445 | |
| 446 | if (handle == -1) |
| 447 | Error (EXIT_FAILURE, "Error opening for append %s: %s",filename,strerror(errno)); |
| 448 | |
| 449 | return handle; |
| 450 | } |
| 451 | |
| 452 | boolean SafeFileExists ( const char * _filename ) |
| 453 | { |
| 454 | char filename[MAX_PATH]; |
| 455 | strncpy(filename, _filename, sizeof (filename)); |
| 456 | filename[sizeof (filename) - 1] = '\0'; |
| 457 | FixFilePath(filename); |
| 458 | |
Vencislav Atanasov | 183e45e | 2019-07-28 23:31:50 +0300 | [diff] [blame^] | 459 | return(rb->file_exists(filename)); |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 460 | } |
| 461 | |
| 462 | |
| 463 | int32 SafeOpenWrite (const char *_filename, int32 filetype) |
| 464 | { |
| 465 | int handle; |
| 466 | char filename[MAX_PATH]; |
| 467 | strncpy(filename, _filename, sizeof (filename)); |
| 468 | filename[sizeof (filename) - 1] = '\0'; |
| 469 | FixFilePath(filename); |
| 470 | |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 471 | handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC |
| 472 | , 0666); |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 473 | |
| 474 | if (handle == -1) |
| 475 | Error (EXIT_FAILURE, "Error opening %s: %s",filename,strerror(errno)); |
| 476 | |
| 477 | return handle; |
| 478 | } |
| 479 | |
| 480 | |
| 481 | |
| 482 | |
| 483 | int32 SafeOpenRead (const char *_filename, int32 filetype) |
| 484 | { |
| 485 | int handle; |
| 486 | char filename[MAX_PATH]; |
| 487 | strncpy(filename, _filename, sizeof (filename)); |
| 488 | filename[sizeof (filename) - 1] = '\0'; |
| 489 | FixFilePath(filename); |
| 490 | |
| 491 | handle = open(filename,O_RDONLY | O_BINARY); |
| 492 | |
| 493 | if (handle == -1) |
| 494 | Error (EXIT_FAILURE, "Error opening %s: %s",filename,strerror(errno)); |
| 495 | |
| 496 | return handle; |
| 497 | } |
| 498 | |
| 499 | |
| 500 | void SafeRead (int32 handle, void *buffer, int32 count) |
| 501 | { |
| 502 | unsigned iocount; |
| 503 | |
| 504 | while (count) |
| 505 | { |
| 506 | iocount = count > 0x8000 ? 0x8000 : count; |
| 507 | if (read (handle,buffer,iocount) != (int)iocount) |
| 508 | Error (EXIT_FAILURE, "File read failure reading %ld bytes",count); |
| 509 | buffer = (void *)( (byte *)buffer + iocount ); |
| 510 | count -= iocount; |
| 511 | } |
| 512 | } |
| 513 | |
| 514 | |
| 515 | void SafeWrite (int32 handle, void *buffer, int32 count) |
| 516 | { |
| 517 | unsigned iocount; |
| 518 | |
| 519 | while (count) |
| 520 | { |
| 521 | iocount = count > 0x8000 ? 0x8000 : count; |
| 522 | if (write (handle,buffer,iocount) != (int)iocount) |
| 523 | Error (EXIT_FAILURE, "File write failure writing %ld bytes",count); |
| 524 | buffer = (void *)( (byte *)buffer + iocount ); |
| 525 | count -= iocount; |
| 526 | } |
| 527 | } |
| 528 | |
| 529 | void SafeWriteString (int handle, char * buffer) |
| 530 | { |
| 531 | unsigned iocount; |
| 532 | |
| 533 | iocount=strlen(buffer); |
| 534 | if (write (handle,buffer,iocount) != (int)iocount) |
| 535 | Error (EXIT_FAILURE, "File write string failure writing %s\n",buffer); |
| 536 | } |
| 537 | |
| 538 | void *SafeMalloc (int32_t size) |
| 539 | { |
| 540 | void *ptr; |
| 541 | |
| 542 | ptr = malloc(size); |
| 543 | |
| 544 | if (!ptr) |
| 545 | Error (EXIT_FAILURE, "SafeMalloc failure for %lu bytes",size); |
| 546 | |
| 547 | return ptr; |
| 548 | } |
| 549 | |
| 550 | void SafeRealloc (void **x, int32 size) |
| 551 | { |
| 552 | void *ptr; |
| 553 | |
| 554 | ptr = realloc(*x, size); |
| 555 | |
| 556 | if (!ptr) |
| 557 | Error (EXIT_FAILURE, "SafeRealloc failure for %lu bytes",size); |
| 558 | |
| 559 | *x = ptr; |
| 560 | } |
| 561 | |
| 562 | void *SafeLevelMalloc (int32_t size) |
| 563 | { |
| 564 | void *ptr; |
| 565 | |
| 566 | ptr = malloc(size); |
| 567 | |
| 568 | if (!ptr) |
| 569 | Error (EXIT_FAILURE, "SafeLevelMalloc failure for %lu bytes",size); |
| 570 | |
| 571 | return ptr; |
| 572 | } |
| 573 | |
| 574 | void SafeFree (void * ptr) |
| 575 | { |
| 576 | if ( ptr == NULL ) |
| 577 | Error (EXIT_FAILURE, "SafeFree : Tried to free a freed pointer\n"); |
| 578 | |
| 579 | free(ptr); |
| 580 | |
| 581 | } |
| 582 | |
| 583 | short SwapShort (short l) |
| 584 | { |
| 585 | byte b1,b2; |
| 586 | |
| 587 | b1 = l&255; |
| 588 | b2 = (l>>8)&255; |
| 589 | |
| 590 | return (b1<<8) + b2; |
| 591 | } |
| 592 | |
| 593 | short KeepShort (short l) |
| 594 | { |
| 595 | return l; |
| 596 | } |
| 597 | |
| 598 | |
| 599 | int32_t Swapint32_t (int32_t l) |
| 600 | { |
| 601 | byte b1,b2,b3,b4; |
| 602 | |
| 603 | b1 = l&255; |
| 604 | b2 = (l>>8)&255; |
| 605 | b3 = (l>>16)&255; |
| 606 | b4 = (l>>24)&255; |
| 607 | |
| 608 | return ((int32_t)b1<<24) + ((int32_t)b2<<16) + ((int32_t)b3<<8) + b4; |
| 609 | } |
| 610 | |
| 611 | int32_t Keepint32_t (int32_t l) |
| 612 | { |
| 613 | return l; |
| 614 | } |
| 615 | |
| 616 | |
| 617 | #undef KeepShort |
| 618 | #undef KeepLong |
| 619 | #undef SwapShort |
| 620 | #undef SwapLong |
| 621 | |
| 622 | void SwapIntelLong(int32_t *l) |
| 623 | { |
| 624 | *l = IntelLong(*l); |
| 625 | } |
| 626 | |
| 627 | void SwapIntelShort(short *s) |
| 628 | { |
| 629 | *s = IntelShort(*s); |
| 630 | } |
| 631 | |
| 632 | void SwapIntelLongArray(int32_t *l, int num) |
| 633 | { |
| 634 | while (num--) { |
| 635 | SwapIntelLong(l); |
| 636 | l++; |
| 637 | } |
| 638 | } |
| 639 | |
| 640 | void SwapIntelShortArray(short *s, int num) |
| 641 | { |
| 642 | while (num--) { |
| 643 | SwapIntelShort(s); |
| 644 | s++; |
| 645 | } |
| 646 | } |
| 647 | |
| 648 | |
| 649 | /* |
| 650 | Copied over from Wolf3D Linux: http://www.icculus.org/wolf3d/ |
| 651 | Modified for ROTT. |
| 652 | Stolen for Duke3D, too. |
| 653 | */ |
| 654 | |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 655 | uint8_t *strlwr(uint8_t *s) |
| 656 | { |
| 657 | uint8_t *p = s; |
| 658 | |
| 659 | while (*p) { |
| 660 | *p = tolower(*p); |
| 661 | p++; |
| 662 | } |
| 663 | |
| 664 | return s; |
| 665 | } |
| 666 | |
| 667 | uint8_t *strupr(uint8_t *s) |
| 668 | { |
| 669 | uint8_t *p = s; |
| 670 | |
| 671 | while (*p) { |
| 672 | *p = toupper(*p); |
| 673 | p++; |
| 674 | } |
| 675 | |
| 676 | return s; |
| 677 | } |
| 678 | |
| 679 | uint8_t *itoa(int value, uint8_t *string, int radix) |
| 680 | { |
| 681 | switch (radix) { |
| 682 | case 10: |
| 683 | sprintf(string, "%d", value); |
| 684 | break; |
| 685 | case 16: |
| 686 | sprintf(string, "%x", value); |
| 687 | break; |
| 688 | default: |
| 689 | STUBBED("unknown radix"); |
| 690 | break; |
| 691 | } |
| 692 | |
| 693 | return string; |
| 694 | } |
| 695 | |
| 696 | uint8_t *ltoa(int32_t value, uint8_t *string, int radix) |
| 697 | { |
| 698 | switch (radix) { |
| 699 | case 10: |
| 700 | sprintf(string, "%d", value); |
| 701 | break; |
| 702 | case 16: |
| 703 | sprintf(string, "%x", value); |
| 704 | break; |
| 705 | default: |
| 706 | STUBBED("unknown radix"); |
| 707 | break; |
| 708 | } |
| 709 | |
| 710 | return string; |
| 711 | } |
| 712 | |
| 713 | uint8_t *ultoa(uint32_t value, uint8_t *string, int radix) |
| 714 | { |
| 715 | switch (radix) { |
| 716 | case 10: |
| 717 | sprintf(string, "%u", value); |
| 718 | break; |
| 719 | case 16: |
| 720 | sprintf(string, "%ux", value); |
| 721 | break; |
| 722 | default: |
| 723 | STUBBED("unknown radix"); |
| 724 | break; |
| 725 | } |
| 726 | |
| 727 | return string; |
| 728 | } |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 729 | |
| 730 | char ApogeePath[256]; |
| 731 | |
| 732 | int setup_homedir (void) |
| 733 | { |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 734 | int err; |
| 735 | |
| 736 | snprintf (ApogeePath, sizeof (ApogeePath), "%s/.duke3d/", getenv ("HOME")); |
| 737 | |
| 738 | //err = mkdir (ApogeePath, S_IRWXU); |
| 739 | err = mkdir (ApogeePath); |
| 740 | if (err == -1 && errno != EEXIST) |
| 741 | { |
| 742 | fprintf (stderr, "Couldn't create preferences directory: %s\n", |
| 743 | strerror (errno)); |
| 744 | return -1; |
| 745 | } |
Franklin Wei | a855d62 | 2017-01-21 15:18:31 -0500 | [diff] [blame] | 746 | |
| 747 | return 0; |
| 748 | } |
| 749 | |
| 750 | |
| 751 | uint8_t CheckParm (char *check) |
| 752 | { |
| 753 | int i; |
| 754 | for (i = 1; i < _argc; i++) |
| 755 | { |
| 756 | if ((*(_argv[i]) == '-') && (strcmpi(_argv[i] + 1, check) == 0)) |
| 757 | return(i); |
| 758 | } |
| 759 | |
| 760 | return(0); |
| 761 | } |
| 762 | |
| 763 | |
| 764 | static void (*shutdown_func)(void) = NULL; |
| 765 | |
| 766 | void RegisterShutdownFunction( void (* shutdown) (void) ) |
| 767 | { |
| 768 | shutdown_func = shutdown; |
| 769 | } |
| 770 | |
| 771 | void Shutdown(void) |
| 772 | { |
| 773 | if (shutdown_func != NULL) |
| 774 | { |
| 775 | shutdown_func(); |
| 776 | shutdown_func = NULL; |
| 777 | } |
| 778 | } |
| 779 | |
| 780 | |