A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 989 lines 31 kB view raw
1/* Emacs style mode select -*- C++ -*- 2 *----------------------------------------------------------------------------- 3 * 4 * 5 * PrBoom a Doom port merged with LxDoom and LSDLDoom 6 * based on BOOM, a modified and improved DOOM engine 7 * Copyright (C) 1999 by 8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman 9 * Copyright (C) 1999-2000 by 10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 25 * 02111-1307, USA. 26 * 27 * DESCRIPTION: 28 * Archiving: SaveGame I/O. 29 * 30 *-----------------------------------------------------------------------------*/ 31 32#include "doomstat.h" 33#include "r_main.h" 34#include "p_maputl.h" 35#include "p_spec.h" 36#include "p_tick.h" 37#include "p_saveg.h" 38#include "m_random.h" 39#include "am_map.h" 40#include "p_enemy.h" 41#include "i_system.h" 42#include "rockmacros.h" 43byte *save_p; 44 45// Pads save_p to a 4-byte boundary 46// so that the load/save works on SGI&Gecko. 47#define PADSAVEP() do { save_p += (4 - ((intptr_t) save_p & 3)) & 3; } while (0) 48// 49// P_ArchivePlayers 50// 51void P_ArchivePlayers (void) 52{ 53 int i; 54 55 CheckSaveGame(sizeof(player_t) * MAXPLAYERS); // killough 56 for (i=0 ; i<MAXPLAYERS ; i++) 57 if (playeringame[i]) 58 { 59 int j; 60 player_t *dest; 61 62 PADSAVEP(); 63 dest = (player_t *) save_p; 64 memcpy(dest, &players[i], sizeof(player_t)); 65 save_p += sizeof(player_t); 66 for (j=0; j<NUMPSPRITES; j++) 67 if (dest->psprites[j].state) 68 dest->psprites[j].state = 69 (state_t *)(dest->psprites[j].state-states); 70 } 71} 72 73// 74// P_UnArchivePlayers 75// 76void P_UnArchivePlayers (void) 77{ 78 int i; 79 80 for (i=0 ; i<MAXPLAYERS ; i++) 81 if (playeringame[i]) 82 { 83 int j; 84 85 PADSAVEP(); 86 87 memcpy(&players[i], save_p, sizeof(player_t)); 88 save_p += sizeof(player_t); 89 90 // will be set when unarc thinker 91 players[i].mo = NULL; 92 players[i].message = NULL; 93 players[i].attacker = NULL; 94 95 for (j=0 ; j<NUMPSPRITES ; j++) 96 if (players[i]. psprites[j].state) 97 players[i]. psprites[j].state = 98 &states[ (intptr_t)players[i].psprites[j].state ]; 99 } 100} 101 102 103// 104// P_ArchiveWorld 105// 106void P_ArchiveWorld (void) 107{ 108 int i; 109 const sector_t *sec; 110 const line_t *li; 111 const side_t *si; 112 short *put; 113 114 // killough 3/22/98: fix bug caused by hoisting save_p too early 115 // killough 10/98: adjust size for changes below 116 size_t size = 117 (sizeof(short)*5 + sizeof sec->floorheight + sizeof sec->ceilingheight) 118 * numsectors + sizeof(short)*3*numlines + 4; 119 120 for (i=0; i<numlines; i++) 121 { 122 if (lines[i].sidenum[0] != -1) 123 size += 124 sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; 125 if (lines[i].sidenum[1] != -1) 126 size += 127 sizeof(short)*3 + sizeof si->textureoffset + sizeof si->rowoffset; 128 } 129 130 CheckSaveGame(size); // killough 131 132 PADSAVEP(); // killough 3/22/98 133 134 put = (short *)save_p; 135 136 // do sectors 137 for (i=0, sec = sectors ; i<numsectors ; i++,sec++) 138 { 139 // killough 10/98: save full floor & ceiling heights, including fraction 140 memcpy(put, &sec->floorheight, sizeof sec->floorheight); 141 put = (void *)((char *) put + sizeof sec->floorheight); 142 memcpy(put, &sec->ceilingheight, sizeof sec->ceilingheight); 143 put = (void *)((char *) put + sizeof sec->ceilingheight); 144 145 *put++ = sec->floorpic; 146 *put++ = sec->ceilingpic; 147 *put++ = sec->lightlevel; 148 *put++ = sec->special; // needed? yes -- transfer types 149 *put++ = sec->tag; // needed? need them -- killough 150 } 151 152 // do lines 153 for (i=0, li = lines ; i<numlines ; i++,li++) 154 { 155 int j; 156 157 *put++ = li->flags; 158 *put++ = li->special; 159 *put++ = li->tag; 160 161 for (j=0; j<2; j++) 162 if (li->sidenum[j] != -1) 163 { 164 si = &sides[li->sidenum[j]]; 165 166 // killough 10/98: save full sidedef offsets, 167 // preserving fractional scroll offsets 168 169 memcpy(put, &si->textureoffset, sizeof si->textureoffset); 170 put = (void *)((char *) put + sizeof si->textureoffset); 171 memcpy(put, &si->rowoffset, sizeof si->rowoffset); 172 put = (void *)((char *) put + sizeof si->rowoffset); 173 174 *put++ = si->toptexture; 175 *put++ = si->bottomtexture; 176 *put++ = si->midtexture; 177 } 178 } 179 save_p = (byte *) put; 180} 181 182 183 184// 185// P_UnArchiveWorld 186// 187void P_UnArchiveWorld (void) 188{ 189 int i; 190 sector_t *sec; 191 line_t *li; 192 const short *get; 193 194 PADSAVEP(); // killough 3/22/98 195 196 get = (short *) save_p; 197 198 // do sectors 199 for (i=0, sec = sectors ; i<numsectors ; i++,sec++) 200 { 201 // killough 10/98: load full floor & ceiling heights, including fractions 202 203 memcpy(&sec->floorheight, get, sizeof sec->floorheight); 204 get = (void *)((char *) get + sizeof sec->floorheight); 205 memcpy(&sec->ceilingheight, get, sizeof sec->ceilingheight); 206 get = (void *)((char *) get + sizeof sec->ceilingheight); 207 208 sec->floorpic = *get++; 209 sec->ceilingpic = *get++; 210 sec->lightlevel = *get++; 211 sec->special = *get++; 212 sec->tag = *get++; 213 sec->ceilingdata = 0; //jff 2/22/98 now three thinker fields, not two 214 sec->floordata = 0; 215 sec->lightingdata = 0; 216 sec->soundtarget = 0; 217 } 218 219 // do lines 220 for (i=0, li = lines ; i<numlines ; i++,li++) 221 { 222 int j; 223 224 li->flags = *get++; 225 li->special = *get++; 226 li->tag = *get++; 227 for (j=0 ; j<2 ; j++) 228 if (li->sidenum[j] != -1) 229 { 230 side_t *si = &sides[li->sidenum[j]]; 231 232 // killough 10/98: load full sidedef offsets, including fractions 233 234 memcpy(&si->textureoffset, get, sizeof si->textureoffset); 235 get = (void *)((char *) get + sizeof si->textureoffset); 236 memcpy(&si->rowoffset, get, sizeof si->rowoffset); 237 get = (void *)((char *) get + sizeof si->rowoffset); 238 239 si->toptexture = *get++; 240 si->bottomtexture = *get++; 241 si->midtexture = *get++; 242 } 243 } 244 save_p = (byte *) get; 245} 246 247// 248// Thinkers 249// 250 251enum { 252 tc_end, 253 tc_mobj 254}; 255typedef unsigned thinkerclass_t; 256 257// phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the 258// thinker indices could be used by the code that saves sector info. 259 260static int number_of_thinkers; 261 262void P_ThinkerToIndex(void) 263{ 264 thinker_t *th; 265 266 // killough 2/14/98: 267 // count the number of thinkers, and mark each one with its index, using 268 // the prev field as a placeholder, since it can be restored later. 269 270 number_of_thinkers = 0; 271 for (th = thinkercap.next ; th != &thinkercap ; th=th->next) 272 if (th->function == P_MobjThinker) 273 th->prev = (thinker_t *)(intptr_t)(++number_of_thinkers); 274} 275 276// phares 9/13/98: Moved this code outside of P_ArchiveThinkers so the 277// thinker indices could be used by the code that saves sector info. 278 279void P_IndexToThinker(void) 280{ 281 // killough 2/14/98: restore prev pointers 282 thinker_t *th; 283 thinker_t *prev = &thinkercap; 284 285 for (th = thinkercap.next ; th != &thinkercap ; prev=th, th=th->next) 286 th->prev = prev; 287} 288 289// 290// P_ArchiveThinkers 291// 292// 2/14/98 killough: substantially modified to fix savegame bugs 293 294void P_ArchiveThinkers (void) 295{ 296 thinker_t *th; 297 298 CheckSaveGame(sizeof brain); // killough 3/26/98: Save boss brain state 299 memcpy(save_p, &brain, sizeof brain); 300 save_p += sizeof brain; 301 302 /* check that enough room is available in savegame buffer 303 * - killough 2/14/98 304 * cph - use number_of_thinkers saved by P_ThinkerToIndex above 305 */ 306 CheckSaveGame(number_of_thinkers*(sizeof(mobj_t)+4)); 307 308 // save off the current thinkers 309 for (th = thinkercap.next ; th != &thinkercap ; th=th->next) 310 if (th->function == P_MobjThinker) 311 { 312 mobj_t *mobj; 313 314 *save_p++ = tc_mobj; 315 PADSAVEP(); 316 mobj = (mobj_t *)save_p; 317 memcpy (mobj, th, sizeof(*mobj)); 318 save_p += sizeof(*mobj); 319 mobj->state = (state_t *)(mobj->state - states); 320 321 // killough 2/14/98: convert pointers into indices. 322 // Fixes many savegame problems, by properly saving 323 // target and tracer fields. Note: we store NULL if 324 // the thinker pointed to by these fields is not a 325 // mobj thinker. 326 327 if (mobj->target) 328 mobj->target = mobj->target->thinker.function == 329 P_MobjThinker ? 330 (mobj_t *) mobj->target->thinker.prev : NULL; 331 332 if (mobj->tracer) 333 mobj->tracer = mobj->tracer->thinker.function == 334 P_MobjThinker ? 335 (mobj_t *) mobj->tracer->thinker.prev : NULL; 336 337 // killough 2/14/98: new field: save last known enemy. Prevents 338 // monsters from going to sleep after killing monsters and not 339 // seeing player anymore. 340 341 if (mobj->lastenemy) 342 mobj->lastenemy = mobj->lastenemy->thinker.function == 343 P_MobjThinker ? 344 (mobj_t *) mobj->lastenemy->thinker.prev : NULL; 345 346 // killough 2/14/98: end changes 347 348 if (mobj->above_thing) // phares 349 mobj->above_thing = mobj->above_thing->thinker.function == 350 P_MobjThinker ? 351 (mobj_t *) mobj->above_thing->thinker.prev : NULL; 352 353 if (mobj->below_thing) 354 mobj->below_thing = mobj->below_thing->thinker.function == 355 P_MobjThinker ? 356 (mobj_t *) mobj->below_thing->thinker.prev : NULL; // phares 357 358 if (mobj->player) 359 mobj->player = (player_t *)((mobj->player-players) + 1); 360 } 361 362 // add a terminating marker 363 *save_p++ = tc_end; 364 365 // killough 9/14/98: save soundtargets 366 { 367 int i; 368 CheckSaveGame(numsectors * sizeof(mobj_t *)); // killough 9/14/98 369 for (i = 0; i < numsectors; i++) 370 { 371 mobj_t *target = sectors[i].soundtarget; 372 if (target) 373 target = (mobj_t *) target->thinker.prev; 374 memcpy(save_p, &target, sizeof target); 375 save_p += sizeof target; 376 } 377 } 378} 379 380/* 381 * killough 11/98 382 * 383 * Same as P_SetTarget() in p_tick.c, except that the target is nullified 384 * first, so that no old target's reference count is decreased (when loading 385 * savegames, old targets are indices, not really pointers to targets). 386 */ 387 388static void P_SetNewTarget(mobj_t **mop, mobj_t *targ) 389{ 390 *mop = NULL; 391 P_SetTarget(mop, targ); 392} 393 394// 395// P_UnArchiveThinkers 396// 397// 2/14/98 killough: substantially modified to fix savegame bugs 398// 399 400void P_UnArchiveThinkers (void) 401{ 402 thinker_t *th; 403 mobj_t **mobj_p; // killough 2/14/98: Translation table 404 size_t size; // killough 2/14/98: size of or index into table 405 406 totallive = 0; 407 // killough 3/26/98: Load boss brain state 408 memcpy(&brain, save_p, sizeof brain); 409 save_p += sizeof brain; 410 411 // remove all the current thinkers 412 for (th = thinkercap.next; th != &thinkercap; ) 413 { 414 thinker_t *next = th->next; 415 if (th->function == P_MobjThinker) 416 P_RemoveMobj ((mobj_t *) th); 417 else 418 Z_Free (th); 419 th = next; 420 } 421 P_InitThinkers (); 422 423 // killough 2/14/98: count number of thinkers by skipping through them 424 { 425 byte *sp = save_p; // save pointer and skip header 426 for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 427 { // skip all entries, adding up count 428 PADSAVEP(); 429 save_p += sizeof(mobj_t); 430 } 431 432 if (*--save_p != tc_end) 433 I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p); 434 435 // first table entry special: 0 maps to NULL 436 *(mobj_p = malloc(size * sizeof *mobj_p)) = 0; // table of pointers 437 save_p = sp; // restore save pointer 438 } 439 440 // read in saved thinkers 441 for (size = 1; *save_p++ == tc_mobj; size++) // killough 2/14/98 442 { 443 mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL); 444 445 // killough 2/14/98 -- insert pointers to thinkers into table, in order: 446 mobj_p[size] = mobj; 447 448 PADSAVEP(); 449 memcpy (mobj, save_p, sizeof(mobj_t)); 450 save_p += sizeof(mobj_t); 451 mobj->state = states + (intptr_t) mobj->state; 452 453 if (mobj->player) 454 (mobj->player = &players[(intptr_t) mobj->player - 1]) -> mo = mobj; 455 456 P_SetThingPosition (mobj); 457 mobj->info = &mobjinfo[mobj->type]; 458 459 // killough 2/28/98: 460 // Fix for falling down into a wall after savegame loaded: 461 // mobj->floorz = mobj->subsector->sector->floorheight; 462 // mobj->ceilingz = mobj->subsector->sector->ceilingheight; 463 464 mobj->thinker.function = P_MobjThinker; 465 P_AddThinker (&mobj->thinker); 466 467 if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE))) 468 totallive++; 469 } 470 471 // killough 2/14/98: adjust target and tracer fields, plus 472 // lastenemy field, to correctly point to mobj thinkers. 473 // NULL entries automatically handled by first table entry. 474 // 475 // killough 11/98: use P_SetNewTarget() to set fields 476 477 for (th = thinkercap.next ; th != &thinkercap ; th=th->next) 478 { 479 P_SetNewTarget(&((mobj_t *) th)->target, 480 mobj_p[(size_t)((mobj_t *)th)->target]); 481 482 P_SetNewTarget(&((mobj_t *) th)->tracer, 483 mobj_p[(size_t)((mobj_t *)th)->tracer]); 484 485 P_SetNewTarget(&((mobj_t *) th)->lastenemy, 486 mobj_p[(size_t)((mobj_t *)th)->lastenemy]); 487 488 // phares: added two new fields for Sprite Height problem 489 490 P_SetNewTarget(&((mobj_t *) th)->above_thing, 491 mobj_p[(size_t)((mobj_t *)th)->above_thing]); 492 493 P_SetNewTarget(&((mobj_t *) th)->below_thing, 494 mobj_p[(size_t)((mobj_t *)th)->below_thing]); 495 } 496 497 { // killough 9/14/98: restore soundtargets 498 int i; 499 for (i = 0; i < numsectors; i++) 500 { 501 mobj_t *target; 502 memcpy(&target, save_p, sizeof target); 503 save_p += sizeof target; 504 P_SetNewTarget(&sectors[i].soundtarget, mobj_p[(size_t) target]); 505 } 506 } 507 508 free(mobj_p); // free translation table 509 510 // killough 3/26/98: Spawn icon landings: 511 if (gamemode == commercial) 512 P_SpawnBrainTargets(); 513} 514 515// 516// P_ArchiveSpecials 517// 518enum { 519 tc_ceiling, 520 tc_door, 521 tc_floor, 522 tc_plat, 523 tc_flash, 524 tc_strobe, 525 tc_glow, 526 tc_elevator, //jff 2/22/98 new elevator type thinker 527 tc_scroll, // killough 3/7/98: new scroll effect thinker 528 tc_pusher, // phares 3/22/98: new push/pull effect thinker 529 tc_flicker, // killough 10/4/98 530 tc_endspecials 531}; 532unsigned specials_e; 533 534// 535// Things to handle: 536// 537// T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list 538// T_VerticalDoor, (vldoor_t: sector_t * swizzle), 539// T_MoveFloor, (floormove_t: sector_t * swizzle), 540// T_LightFlash, (lightflash_t: sector_t * swizzle), 541// T_StrobeFlash, (strobe_t: sector_t *), 542// T_Glow, (glow_t: sector_t *), 543// T_PlatRaise, (plat_t: sector_t *), - active list 544// T_MoveElevator, (plat_t: sector_t *), - active list // jff 2/22/98 545// T_Scroll // killough 3/7/98 546// T_Pusher // phares 3/22/98 547// T_FireFlicker // killough 10/4/98 548// 549 550void P_ArchiveSpecials (void) 551{ 552 thinker_t *th; 553 size_t size = 0; // killough 554 555 // save off the current thinkers (memory size calculation -- killough) 556 557 for (th = thinkercap.next ; th != &thinkercap ; th=th->next) 558 if (!th->function) 559 { 560 platlist_t *pl; 561 ceilinglist_t *cl; //jff 2/22/98 need this for ceilings too now 562 for (pl=activeplats; pl; pl=pl->next) 563 if (pl->plat == (plat_t *) th) // killough 2/14/98 564 { 565 size += 4+sizeof(plat_t); 566 goto end; 567 } 568 for (cl=activeceilings; cl; cl=cl->next) // search for activeceiling 569 if (cl->ceiling == (ceiling_t *) th) //jff 2/22/98 570 { 571 size += 4+sizeof(ceiling_t); 572 goto end; 573 } 574end:; 575 } 576 else 577 size += 578 th->function==T_MoveCeiling ? 4+sizeof(ceiling_t) : 579 th->function==T_VerticalDoor ? 4+sizeof(vldoor_t) : 580 th->function==T_MoveFloor ? 4+sizeof(floormove_t): 581 th->function==T_PlatRaise ? 4+sizeof(plat_t) : 582 th->function==T_LightFlash ? 4+sizeof(lightflash_t): 583 th->function==T_StrobeFlash ? 4+sizeof(strobe_t) : 584 th->function==T_Glow ? 4+sizeof(glow_t) : 585 th->function==T_MoveElevator ? 4+sizeof(elevator_t): 586 th->function==T_Scroll ? 4+sizeof(scroll_t) : 587 th->function==T_Pusher ? 4+sizeof(pusher_t) : 588 th->function==T_FireFlicker? 4+sizeof(fireflicker_t) : 589 0; 590 591 CheckSaveGame(size); // killough 592 593 // save off the current thinkers 594 for (th=thinkercap.next; th!=&thinkercap; th=th->next) 595 { 596 if (!th->function) 597 { 598 platlist_t *pl; 599 ceilinglist_t *cl; //jff 2/22/98 add iter variable for ceilings 600 601 // killough 2/8/98: fix plat original height bug. 602 // Since acv==NULL, this could be a plat in stasis. 603 // so check the active plats list, and save this 604 // plat (jff: or ceiling) even if it is in stasis. 605 606 for (pl=activeplats; pl; pl=pl->next) 607 if (pl->plat == (plat_t *) th) // killough 2/14/98 608 goto plat; 609 610 for (cl=activeceilings; cl; cl=cl->next) 611 if (cl->ceiling == (ceiling_t *) th) //jff 2/22/98 612 goto ceiling; 613 614 continue; 615 } 616 617 if (th->function == T_MoveCeiling) 618 { 619 ceiling_t *ceiling; 620ceiling: // killough 2/14/98 621 *save_p++ = tc_ceiling; 622 PADSAVEP(); 623 ceiling = (ceiling_t *)save_p; 624 memcpy (ceiling, th, sizeof(*ceiling)); 625 save_p += sizeof(*ceiling); 626 ceiling->sector = (sector_t *)(ceiling->sector - sectors); 627 continue; 628 } 629 630 if (th->function == T_VerticalDoor) 631 { 632 vldoor_t *door; 633 *save_p++ = tc_door; 634 PADSAVEP(); 635 door = (vldoor_t *) save_p; 636 memcpy (door, th, sizeof *door); 637 save_p += sizeof(*door); 638 door->sector = (sector_t *)(door->sector - sectors); 639 //jff 1/31/98 archive line remembered by door as well 640 door->line = (line_t *) (door->line ? door->line-lines : -1); 641 continue; 642 } 643 644 if (th->function == T_MoveFloor) 645 { 646 floormove_t *floor; 647 *save_p++ = tc_floor; 648 PADSAVEP(); 649 floor = (floormove_t *)save_p; 650 memcpy (floor, th, sizeof(*floor)); 651 save_p += sizeof(*floor); 652 floor->sector = (sector_t *)(floor->sector - sectors); 653 continue; 654 } 655 656 if (th->function == T_PlatRaise) 657 { 658 plat_t *plat; 659plat: // killough 2/14/98: added fix for original plat height above 660 *save_p++ = tc_plat; 661 PADSAVEP(); 662 plat = (plat_t *)save_p; 663 memcpy (plat, th, sizeof(*plat)); 664 save_p += sizeof(*plat); 665 plat->sector = (sector_t *)(plat->sector - sectors); 666 continue; 667 } 668 669 if (th->function == T_LightFlash) 670 { 671 lightflash_t *flash; 672 *save_p++ = tc_flash; 673 PADSAVEP(); 674 flash = (lightflash_t *)save_p; 675 memcpy (flash, th, sizeof(*flash)); 676 save_p += sizeof(*flash); 677 flash->sector = (sector_t *)(flash->sector - sectors); 678 continue; 679 } 680 681 if (th->function == T_StrobeFlash) 682 { 683 strobe_t *strobe; 684 *save_p++ = tc_strobe; 685 PADSAVEP(); 686 strobe = (strobe_t *)save_p; 687 memcpy (strobe, th, sizeof(*strobe)); 688 save_p += sizeof(*strobe); 689 strobe->sector = (sector_t *)(strobe->sector - sectors); 690 continue; 691 } 692 693 if (th->function == T_Glow) 694 { 695 glow_t *glow; 696 *save_p++ = tc_glow; 697 PADSAVEP(); 698 glow = (glow_t *)save_p; 699 memcpy (glow, th, sizeof(*glow)); 700 save_p += sizeof(*glow); 701 glow->sector = (sector_t *)(glow->sector - sectors); 702 continue; 703 } 704 705 // killough 10/4/98: save flickers 706 if (th->function == T_FireFlicker) 707 { 708 fireflicker_t *flicker; 709 *save_p++ = tc_flicker; 710 PADSAVEP(); 711 flicker = (fireflicker_t *)save_p; 712 memcpy (flicker, th, sizeof(*flicker)); 713 save_p += sizeof(*flicker); 714 flicker->sector = (sector_t *)(flicker->sector - sectors); 715 continue; 716 } 717 718 //jff 2/22/98 new case for elevators 719 if (th->function == T_MoveElevator) 720 { 721 elevator_t *elevator; //jff 2/22/98 722 *save_p++ = tc_elevator; 723 PADSAVEP(); 724 elevator = (elevator_t *)save_p; 725 memcpy (elevator, th, sizeof(*elevator)); 726 save_p += sizeof(*elevator); 727 elevator->sector = (sector_t *)(elevator->sector - sectors); 728 continue; 729 } 730 731 // killough 3/7/98: Scroll effect thinkers 732 if (th->function == T_Scroll) 733 { 734 *save_p++ = tc_scroll; 735 memcpy (save_p, th, sizeof(scroll_t)); 736 save_p += sizeof(scroll_t); 737 continue; 738 } 739 740 // phares 3/22/98: Push/Pull effect thinkers 741 742 if (th->function == T_Pusher) 743 { 744 *save_p++ = tc_pusher; 745 memcpy (save_p, th, sizeof(pusher_t)); 746 save_p += sizeof(pusher_t); 747 continue; 748 } 749 } 750 751 // add a terminating marker 752 *save_p++ = tc_endspecials; 753} 754 755 756// 757// P_UnArchiveSpecials 758// 759void P_UnArchiveSpecials (void) 760{ 761 byte tclass; 762 763 // read in saved thinkers 764 while ((tclass = *save_p++) != tc_endspecials) // killough 2/14/98 765 switch (tclass) 766 { 767 case tc_ceiling: 768 PADSAVEP(); 769 { 770 ceiling_t *ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL); 771 memcpy (ceiling, save_p, sizeof(*ceiling)); 772 save_p += sizeof(*ceiling); 773 ceiling->sector = &sectors[(intptr_t)ceiling->sector]; 774 ceiling->sector->ceilingdata = ceiling; //jff 2/22/98 775 776 if (ceiling->thinker.function) 777 ceiling->thinker.function = T_MoveCeiling; 778 779 P_AddThinker (&ceiling->thinker); 780 P_AddActiveCeiling(ceiling); 781 break; 782 } 783 784 case tc_door: 785 PADSAVEP(); 786 { 787 vldoor_t *door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL); 788 memcpy (door, save_p, sizeof(*door)); 789 save_p += sizeof(*door); 790 door->sector = &sectors[(intptr_t)door->sector]; 791 792 //jff 1/31/98 unarchive line remembered by door as well 793 door->line = (intptr_t)door->line!=-1? &lines[(intptr_t)door->line] : NULL; 794 795 door->sector->ceilingdata = door; //jff 2/22/98 796 door->thinker.function = T_VerticalDoor; 797 P_AddThinker (&door->thinker); 798 break; 799 } 800 801 case tc_floor: 802 PADSAVEP(); 803 { 804 floormove_t *floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL); 805 memcpy (floor, save_p, sizeof(*floor)); 806 save_p += sizeof(*floor); 807 floor->sector = &sectors[(intptr_t)floor->sector]; 808 floor->sector->floordata = floor; //jff 2/22/98 809 floor->thinker.function = T_MoveFloor; 810 P_AddThinker (&floor->thinker); 811 break; 812 } 813 814 case tc_plat: 815 PADSAVEP(); 816 { 817 plat_t *plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL); 818 memcpy (plat, save_p, sizeof(*plat)); 819 save_p += sizeof(*plat); 820 plat->sector = &sectors[(intptr_t)plat->sector]; 821 plat->sector->floordata = plat; //jff 2/22/98 822 823 if (plat->thinker.function) 824 plat->thinker.function = T_PlatRaise; 825 826 P_AddThinker (&plat->thinker); 827 P_AddActivePlat(plat); 828 break; 829 } 830 831 case tc_flash: 832 PADSAVEP(); 833 { 834 lightflash_t *flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL); 835 memcpy (flash, save_p, sizeof(*flash)); 836 save_p += sizeof(*flash); 837 flash->sector = &sectors[(intptr_t)flash->sector]; 838 flash->thinker.function = T_LightFlash; 839 P_AddThinker (&flash->thinker); 840 break; 841 } 842 843 case tc_strobe: 844 PADSAVEP(); 845 { 846 strobe_t *strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL); 847 memcpy (strobe, save_p, sizeof(*strobe)); 848 save_p += sizeof(*strobe); 849 strobe->sector = &sectors[(intptr_t)strobe->sector]; 850 strobe->thinker.function = T_StrobeFlash; 851 P_AddThinker (&strobe->thinker); 852 break; 853 } 854 855 case tc_glow: 856 PADSAVEP(); 857 { 858 glow_t *glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL); 859 memcpy (glow, save_p, sizeof(*glow)); 860 save_p += sizeof(*glow); 861 glow->sector = &sectors[(intptr_t)glow->sector]; 862 glow->thinker.function = T_Glow; 863 P_AddThinker (&glow->thinker); 864 break; 865 } 866 867 case tc_flicker: // killough 10/4/98 868 PADSAVEP(); 869 { 870 fireflicker_t *flicker = Z_Malloc (sizeof(*flicker), PU_LEVEL, NULL); 871 memcpy (flicker, save_p, sizeof(*flicker)); 872 save_p += sizeof(*flicker); 873 flicker->sector = &sectors[(intptr_t)flicker->sector]; 874 flicker->thinker.function = T_FireFlicker; 875 P_AddThinker (&flicker->thinker); 876 break; 877 } 878 879 //jff 2/22/98 new case for elevators 880 case tc_elevator: 881 PADSAVEP(); 882 { 883 elevator_t *elevator = Z_Malloc (sizeof(*elevator), PU_LEVEL, NULL); 884 memcpy (elevator, save_p, sizeof(*elevator)); 885 save_p += sizeof(*elevator); 886 elevator->sector = &sectors[(intptr_t)elevator->sector]; 887 elevator->sector->floordata = elevator; //jff 2/22/98 888 elevator->sector->ceilingdata = elevator; //jff 2/22/98 889 elevator->thinker.function = T_MoveElevator; 890 P_AddThinker (&elevator->thinker); 891 break; 892 } 893 894 case tc_scroll: // killough 3/7/98: scroll effect thinkers 895 { 896 scroll_t *scroll = Z_Malloc (sizeof(scroll_t), PU_LEVEL, NULL); 897 memcpy (scroll, save_p, sizeof(scroll_t)); 898 save_p += sizeof(scroll_t); 899 scroll->thinker.function = T_Scroll; 900 P_AddThinker(&scroll->thinker); 901 break; 902 } 903 904 case tc_pusher: // phares 3/22/98: new Push/Pull effect thinkers 905 { 906 pusher_t *pusher = Z_Malloc (sizeof(pusher_t), PU_LEVEL, NULL); 907 memcpy (pusher, save_p, sizeof(pusher_t)); 908 save_p += sizeof(pusher_t); 909 pusher->thinker.function = T_Pusher; 910 pusher->source = P_GetPushThing(pusher->affectee); 911 P_AddThinker(&pusher->thinker); 912 break; 913 } 914 915 default: 916 I_Error("P_UnarchiveSpecials: Unknown tclass %i in savegame", tclass); 917 } 918} 919 920// killough 2/16/98: save/restore random number generator state information 921 922void P_ArchiveRNG(void) 923{ 924 CheckSaveGame(sizeof rng); 925 memcpy(save_p, &rng, sizeof rng); 926 save_p += sizeof rng; 927} 928 929void P_UnArchiveRNG(void) 930{ 931 memcpy(&rng, save_p, sizeof rng); 932 save_p += sizeof rng; 933} 934 935// killough 2/22/98: Save/restore automap state 936// killough 2/22/98: Save/restore automap state 937void P_ArchiveMap(void) 938{ 939 int zero = 0, one = 1; 940 CheckSaveGame(2 * sizeof zero + sizeof markpointnum + 941 markpointnum * sizeof *markpoints + 942 sizeof automapmode + sizeof one); 943 944 memcpy(save_p, &automapmode, sizeof automapmode); 945 save_p += sizeof automapmode; 946 memcpy(save_p, &one, sizeof one); // CPhipps - used to be viewactive, now 947 save_p += sizeof one; // that's worked out locally by D_Display 948 memcpy(save_p, &zero, sizeof zero); // CPhipps - used to be followplayer 949 save_p += sizeof zero; // that is now part of automapmode 950 memcpy(save_p, &zero, sizeof zero); // CPhipps - used to be automap_grid, ditto 951 save_p += sizeof zero; 952 memcpy(save_p, &markpointnum, sizeof markpointnum); 953 save_p += sizeof markpointnum; 954 955 if (markpointnum) 956 { 957 memcpy(save_p, markpoints, sizeof *markpoints * markpointnum); 958 save_p += markpointnum * sizeof *markpoints; 959 } 960} 961 962void P_UnArchiveMap(void) 963{ 964 int unused; 965 memcpy(&automapmode, save_p, sizeof automapmode); 966 save_p += sizeof automapmode; 967 memcpy(&unused, save_p, sizeof unused); 968 save_p += sizeof unused; 969 memcpy(&unused, save_p, sizeof unused); 970 save_p += sizeof unused; 971 memcpy(&unused, save_p, sizeof unused); 972 save_p += sizeof unused; 973 974 if (automapmode & am_active) 975 AM_Start(); 976 977 memcpy(&markpointnum, save_p, sizeof markpointnum); 978 save_p += sizeof markpointnum; 979 980 if (markpointnum) 981 { 982 while (markpointnum >= markpointnum_max) 983 markpoints = realloc(markpoints, sizeof *markpoints * 984 (markpointnum_max = markpointnum_max ? markpointnum_max*2 : 16)); 985 memcpy(markpoints, save_p, markpointnum * sizeof *markpoints); 986 save_p += markpointnum * sizeof *markpoints; 987 } 988} 989