Annotation of early-roguelike/rogue3/state.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: state.c - Portable Rogue Save State Code
! 3:
! 4: Copyright (C) 1999, 2000, 2005, 2007, 2008 Nicholas J. Kisseberth
! 5: All rights reserved.
! 6:
! 7: Redistribution and use in source and binary forms, with or without
! 8: modification, are permitted provided that the following conditions
! 9: are met:
! 10: 1. Redistributions of source code must retain the above copyright
! 11: notice, this list of conditions and the following disclaimer.
! 12: 2. Redistributions in binary form must reproduce the above copyright
! 13: notice, this list of conditions and the following disclaimer in the
! 14: documentation and/or other materials provided with the distribution.
! 15: 3. Neither the name(s) of the author(s) nor the names of other contributors
! 16: may be used to endorse or promote products derived from this software
! 17: without specific prior written permission.
! 18:
! 19: THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
! 20: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 21: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 22: ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
! 23: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 24: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 25: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 26: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 27: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 28: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 29: SUCH DAMAGE.
! 30: */
! 31:
! 32: #include <stdlib.h>
! 33: #include <string.h>
! 34: #include <curses.h>
! 35: #include <errno.h>
! 36: #include "rogue.h"
! 37:
! 38: /************************************************************************/
! 39: /* Save State Code */
! 40: /************************************************************************/
! 41:
! 42: #define RSID_STATS 0xABCD0001
! 43: #define RSID_THING 0xABCD0002
! 44: #define RSID_THING_NULL 0xDEAD0002
! 45: #define RSID_OBJECT 0xABCD0003
! 46: #define RSID_MAGICITEMS 0xABCD0004
! 47: #define RSID_KNOWS 0xABCD0005
! 48: #define RSID_GUESSES 0xABCD0006
! 49: #define RSID_OBJECTLIST 0xABCD0007
! 50: #define RSID_BAGOBJECT 0xABCD0008
! 51: #define RSID_MONSTERLIST 0xABCD0009
! 52: #define RSID_MONSTERSTATS 0xABCD000A
! 53: #define RSID_MONSTERS 0xABCD000B
! 54: #define RSID_TRAP 0xABCD000C
! 55: #define RSID_WINDOW 0xABCD000D
! 56: #define RSID_DAEMONS 0xABCD000E
! 57: #define RSID_IWEAPS 0xABCD000F
! 58: #define RSID_IARMOR 0xABCD0010
! 59: #define RSID_SPELLS 0xABCD0011
! 60: #define RSID_ILIST 0xABCD0012
! 61: #define RSID_HLIST 0xABCD0013
! 62: #define RSID_DEATHTYPE 0xABCD0014
! 63: #define RSID_CTYPES 0XABCD0015
! 64: #define RSID_COORDLIST 0XABCD0016
! 65: #define RSID_ROOMS 0XABCD0017
! 66:
! 67: #define READSTAT (format_error || read_error )
! 68: #define WRITESTAT (write_error)
! 69:
! 70: static int read_error = FALSE;
! 71: static int write_error = FALSE;
! 72: static int format_error = FALSE;
! 73: static int endian = 0x01020304;
! 74: #define big_endian ( *((char *)&endian) == 0x01 )
! 75:
! 76: void
! 77: rs_write(FILE *savef, const void *ptr, size_t size)
! 78: {
! 79: encwrite(ptr, size, savef);
! 80: }
! 81:
! 82: void
! 83: rs_read(FILE *savef, void *ptr, size_t size)
! 84: {
! 85: encread(ptr, size, savef);
! 86: }
! 87:
! 88: void
! 89: rs_write_int(FILE *savef, int c)
! 90: {
! 91: char bytes[4];
! 92: char *buf = (char *) &c;
! 93:
! 94: if (big_endian)
! 95: {
! 96: bytes[3] = buf[0];
! 97: bytes[2] = buf[1];
! 98: bytes[1] = buf[2];
! 99: bytes[0] = buf[3];
! 100: buf = bytes;
! 101: }
! 102:
! 103: rs_write(savef, buf, 4);
! 104: }
! 105:
! 106: void
! 107: rs_read_int(FILE *savef, int *i)
! 108: {
! 109: char bytes[4];
! 110: int input = 0;
! 111: char *buf = (char *)&input;
! 112:
! 113: rs_read(savef, &input, 4);
! 114:
! 115: if (encerror())
! 116: return;
! 117:
! 118: if (big_endian)
! 119: {
! 120: bytes[3] = buf[0];
! 121: bytes[2] = buf[1];
! 122: bytes[1] = buf[2];
! 123: bytes[0] = buf[3];
! 124: buf = bytes;
! 125: }
! 126:
! 127: *i = *((int *) buf);
! 128: }
! 129:
! 130: void
! 131: rs_write_uint(FILE *savef, unsigned int c)
! 132: {
! 133: char bytes[4];
! 134: char *buf = (char *) &c;
! 135:
! 136: if (big_endian)
! 137: {
! 138: bytes[3] = buf[0];
! 139: bytes[2] = buf[1];
! 140: bytes[1] = buf[2];
! 141: bytes[0] = buf[3];
! 142: buf = bytes;
! 143: }
! 144:
! 145: rs_write(savef, buf, 4);
! 146: }
! 147:
! 148: void
! 149: rs_read_uint(FILE *savef, unsigned int *i)
! 150: {
! 151: char bytes[4];
! 152: int input = 0;
! 153: char *buf = (char *)&input;
! 154:
! 155: rs_read(savef, &input, 4);
! 156:
! 157: if (encerror())
! 158: return;
! 159:
! 160: if (big_endian)
! 161: {
! 162: bytes[3] = buf[0];
! 163: bytes[2] = buf[1];
! 164: bytes[1] = buf[2];
! 165: bytes[0] = buf[3];
! 166: buf = bytes;
! 167: }
! 168:
! 169: *i = *((unsigned int *) buf);
! 170: }
! 171:
! 172: void
! 173: rs_write_chars(FILE *savef, const char *c, int cnt)
! 174: {
! 175: rs_write_int(savef, cnt);
! 176: rs_write(savef, c, cnt);
! 177: }
! 178:
! 179: void
! 180: rs_read_chars(FILE *savef, char *i, int cnt)
! 181: {
! 182: int value = 0;
! 183:
! 184: rs_read_int(savef, &value);
! 185:
! 186: if (!encerror() && (value != cnt))
! 187: encseterr(EILSEQ);
! 188:
! 189: rs_read(savef, i, cnt);
! 190: }
! 191:
! 192: void
! 193: rs_write_ints(FILE *savef, int *c, int cnt)
! 194: {
! 195: int n = 0;
! 196:
! 197: rs_write_int(savef, cnt);
! 198:
! 199: for(n = 0; n < cnt; n++)
! 200: rs_write_int(savef,c[n]);
! 201: }
! 202:
! 203: void
! 204: rs_read_ints(FILE *savef, int *i, int cnt)
! 205: {
! 206: int n, value;
! 207:
! 208: rs_read_int(savef,&value);
! 209:
! 210: if (!encerror() && (value != cnt))
! 211: encseterr(EILSEQ);
! 212:
! 213: for(n = 0; n < cnt; n++)
! 214: rs_read_int(savef, &i[n]);
! 215: }
! 216:
! 217: void
! 218: rs_write_marker(FILE *savef, int id)
! 219: {
! 220: rs_write_int(savef, id);
! 221: }
! 222:
! 223: void
! 224: rs_read_marker(FILE *savef, int id)
! 225: {
! 226: int nid;
! 227:
! 228: rs_read_int(savef, &nid);
! 229:
! 230: if (!encerror() && (id != nid))
! 231: encseterr(EILSEQ);
! 232: }
! 233:
! 234: /******************************************************************************/
! 235:
! 236: void
! 237: rs_write_string(FILE *savef, const char *s)
! 238: {
! 239: int len = 0;
! 240:
! 241: len = (s == NULL) ? 0 : (int) strlen(s) + 1;
! 242:
! 243: rs_write_int(savef, len);
! 244: rs_write_chars(savef, s, len);
! 245: }
! 246:
! 247: void
! 248: rs_read_string(FILE *savef, char *s, int max)
! 249: {
! 250: int len = 0;
! 251:
! 252: rs_read_int(savef, &len);
! 253:
! 254: if (!encerror() && (len > max))
! 255: encseterr(EILSEQ);
! 256:
! 257: rs_read_chars(savef, s, len);
! 258: }
! 259:
! 260: void
! 261: rs_read_new_string(FILE *savef, char **s)
! 262: {
! 263: int len=0;
! 264: char *buf=0;
! 265:
! 266: rs_read_int(savef, &len);
! 267:
! 268: if (encerror())
! 269: return;
! 270:
! 271: if (len == 0)
! 272: buf = NULL;
! 273: else
! 274: {
! 275: buf = malloc(len);
! 276:
! 277: if (buf == NULL)
! 278: encseterr(ENOMEM);
! 279: }
! 280:
! 281: rs_read_chars(savef, buf, len);
! 282:
! 283: *s = buf;
! 284: }
! 285:
! 286: void
! 287: rs_write_string_index(FILE *savef, char *master[], int max, char *str)
! 288: {
! 289: int i;
! 290:
! 291: for(i = 0; i < max; i++)
! 292: if (str == master[i])
! 293: {
! 294: rs_write_int(savef, i);
! 295: return;
! 296: }
! 297:
! 298: rs_write_int(savef,-1);
! 299: }
! 300:
! 301: void
! 302: rs_read_string_index(FILE *savef, char *master[], int maxindex, char **str)
! 303: {
! 304: int i;
! 305:
! 306: rs_read_int(savef, &i);
! 307:
! 308: if (!encerror() && (i > maxindex))
! 309: encseterr(EILSEQ);
! 310: else if (i >= 0)
! 311: *str = master[i];
! 312: else
! 313: *str = NULL;
! 314: }
! 315:
! 316: void
! 317: rs_write_coord(FILE *savef, coord c)
! 318: {
! 319: rs_write_int(savef, c.x);
! 320: rs_write_int(savef, c.y);
! 321: }
! 322:
! 323: void
! 324: rs_read_coord(FILE *savef, coord *c)
! 325: {
! 326: coord in;
! 327:
! 328: rs_read_int(savef,&in.x);
! 329: rs_read_int(savef,&in.y);
! 330:
! 331: if (!encerror())
! 332: {
! 333: c->x = in.x;
! 334: c->y = in.y;
! 335: }
! 336: }
! 337:
! 338: void
! 339: rs_write_str_t(FILE *savef, str_t str)
! 340: {
! 341: rs_write_int(savef, str.st_str);
! 342: rs_write_int(savef, str.st_add);
! 343: }
! 344:
! 345: void
! 346: rs_read_str_t(FILE *savef, str_t *str)
! 347: {
! 348: str_t in;
! 349:
! 350: rs_read_int(savef,&in.st_str);
! 351: rs_read_int(savef,&in.st_add);
! 352:
! 353: if (!encerror())
! 354: {
! 355: str->st_str = in.st_str;
! 356: str->st_add = in.st_add;
! 357: }
! 358: }
! 359:
! 360: void
! 361: rs_write_window(FILE *savef, WINDOW *win)
! 362: {
! 363: int row,col,height,width;
! 364:
! 365: width = getmaxx(win);
! 366: height = getmaxy(win);
! 367:
! 368: rs_write_marker(savef,RSID_WINDOW);
! 369: rs_write_int(savef,height);
! 370: rs_write_int(savef,width);
! 371:
! 372: for(row=0;row<height;row++)
! 373: for(col=0;col<width;col++)
! 374: rs_write_int(savef, mvwinch(win,row,col));
! 375: }
! 376:
! 377: void
! 378: rs_read_window(FILE *savef, WINDOW *win)
! 379: {
! 380: int row,col,maxlines,maxcols,value,width,height;
! 381:
! 382: width = getmaxx(win);
! 383: height = getmaxy(win);
! 384:
! 385: rs_read_marker(savef, RSID_WINDOW);
! 386:
! 387: rs_read_int(savef, &maxlines);
! 388: rs_read_int(savef, &maxcols);
! 389:
! 390: if (encerror())
! 391: return;
! 392:
! 393: for(row = 0; row < maxlines; row++)
! 394: for(col = 0; col < maxcols; col++)
! 395: {
! 396: rs_read_int(savef, &value);
! 397:
! 398: if ((row < height) && (col < width))
! 399: mvwaddch(win,row,col,value);
! 400: }
! 401: }
! 402:
! 403: /******************************************************************************/
! 404:
! 405: void *
! 406: get_list_item(struct linked_list *l, int i)
! 407: {
! 408: int cnt;
! 409:
! 410: for(cnt = 0; l != NULL; cnt++, l = l->l_next)
! 411: if (cnt == i)
! 412: return(l->l_data);
! 413:
! 414: return(NULL);
! 415: }
! 416:
! 417: int
! 418: find_list_ptr(struct linked_list *l, void *ptr)
! 419: {
! 420: int cnt;
! 421:
! 422: for(cnt = 0; l != NULL; cnt++, l = l->l_next)
! 423: if (l->l_data == ptr)
! 424: return(cnt);
! 425:
! 426: return(-1);
! 427: }
! 428:
! 429: int
! 430: list_size(struct linked_list *l)
! 431: {
! 432: int cnt;
! 433:
! 434: for(cnt = 0; l != NULL; cnt++, l = l->l_next)
! 435: if (l->l_data == NULL)
! 436: return(cnt);
! 437:
! 438: return(cnt);
! 439: }
! 440:
! 441: /******************************************************************************/
! 442:
! 443: void
! 444: rs_write_stats(FILE *savef, struct stats *s)
! 445: {
! 446: rs_write_marker(savef, RSID_STATS);
! 447: rs_write_str_t(savef, s->s_str);
! 448: rs_write_int(savef, s->s_exp);
! 449: rs_write_int(savef, s->s_lvl);
! 450: rs_write_int(savef, s->s_arm);
! 451: rs_write_int(savef, s->s_hpt);
! 452: rs_write_chars(savef, s->s_dmg, sizeof(s->s_dmg));
! 453: }
! 454:
! 455:
! 456: void
! 457: rs_read_stats(FILE *savef, struct stats *s)
! 458: {
! 459: rs_read_marker(savef, RSID_STATS);
! 460: rs_read_str_t(savef,&s->s_str);
! 461: rs_read_int(savef,&s->s_exp);
! 462: rs_read_int(savef,&s->s_lvl);
! 463: rs_read_int(savef,&s->s_arm);
! 464: rs_read_int(savef,&s->s_hpt);
! 465: rs_read_chars(savef,s->s_dmg,sizeof(s->s_dmg));
! 466: }
! 467:
! 468:
! 469: void
! 470: rs_write_scrolls(FILE *savef)
! 471: {
! 472: int i;
! 473:
! 474: for(i = 0; i < MAXSCROLLS; i++)
! 475: {
! 476: rs_write_string(savef,s_names[i]);
! 477: rs_write_int(savef,s_know[i]);
! 478: rs_write_string(savef,s_guess[i]);
! 479: }
! 480: }
! 481:
! 482: void
! 483: rs_read_scrolls(FILE *savef)
! 484: {
! 485: int i;
! 486:
! 487: for(i = 0; i < MAXSCROLLS; i++)
! 488: {
! 489: rs_read_new_string(savef,&s_names[i]);
! 490: rs_read_int(savef,&s_know[i]);
! 491: rs_read_new_string(savef,&s_guess[i]);
! 492: }
! 493: }
! 494:
! 495: void
! 496: rs_write_potions(FILE *savef)
! 497: {
! 498: int i;
! 499:
! 500: for(i = 0; i < MAXPOTIONS; i++)
! 501: {
! 502: rs_write_string_index(savef, rainbow, cNCOLORS, p_colors[i]);
! 503: rs_write_int(savef,p_know[i]);
! 504: rs_write_string(savef,p_guess[i]);
! 505: }
! 506: }
! 507:
! 508: void
! 509: rs_read_potions(FILE *savef)
! 510: {
! 511: int i;
! 512:
! 513: for(i = 0; i < MAXPOTIONS; i++)
! 514: {
! 515: rs_read_string_index(savef, rainbow, cNCOLORS, &p_colors[i]);
! 516: rs_read_int(savef,&p_know[i]);
! 517: rs_read_new_string(savef,&p_guess[i]);
! 518: }
! 519: }
! 520:
! 521: void
! 522: rs_write_rings(FILE *savef)
! 523: {
! 524: int i;
! 525:
! 526: for(i = 0; i < MAXRINGS; i++)
! 527: {
! 528: rs_write_string_index(savef, stones, cNSTONES, r_stones[i]);
! 529: rs_write_int(savef,r_know[i]);
! 530: rs_write_string(savef,r_guess[i]);
! 531: }
! 532: }
! 533:
! 534: void
! 535: rs_read_rings(FILE *savef)
! 536: {
! 537: int i;
! 538:
! 539: for(i = 0; i < MAXRINGS; i++)
! 540: {
! 541: rs_read_string_index(savef, stones, cNSTONES, &r_stones[i]);
! 542: rs_read_int(savef,&r_know[i]);
! 543: rs_read_new_string(savef,&r_guess[i]);
! 544: }
! 545: }
! 546:
! 547: void
! 548: rs_write_sticks(FILE *savef)
! 549: {
! 550: int i;
! 551:
! 552: for (i = 0; i < MAXSTICKS; i++)
! 553: {
! 554: if (strcmp(ws_type[i],"staff") == 0)
! 555: {
! 556: rs_write_int(savef,0);
! 557: rs_write_string_index(savef, wood, cNWOOD, ws_made[i]);
! 558: }
! 559: else
! 560: {
! 561: rs_write_int(savef,1);
! 562: rs_write_string_index(savef, metal, cNMETAL, ws_made[i]);
! 563: }
! 564: rs_write_int(savef, ws_know[i]);
! 565: rs_write_string(savef, ws_guess[i]);
! 566: }
! 567: }
! 568:
! 569: void
! 570: rs_read_sticks(FILE *savef)
! 571: {
! 572: int i = 0, list = 0;
! 573:
! 574: for(i = 0; i < MAXSTICKS; i++)
! 575: {
! 576: rs_read_int(savef,&list);
! 577:
! 578: if (list == 0)
! 579: {
! 580: rs_read_string_index(savef, wood, cNWOOD, &ws_made[i]);
! 581: ws_type[i] = "staff";
! 582: }
! 583: else
! 584: {
! 585: rs_read_string_index(savef, metal, cNMETAL, &ws_made[i]);
! 586: ws_type[i] = "wand";
! 587: }
! 588: rs_read_int(savef, &ws_know[i]);
! 589: rs_read_new_string(savef, &ws_guess[i]);
! 590: }
! 591: }
! 592:
! 593: void
! 594: rs_write_daemons(FILE *savef, struct delayed_action *dlist, int cnt)
! 595: {
! 596: int i = 0;
! 597: int func = 0;
! 598:
! 599: rs_write_marker(savef, RSID_DAEMONS);
! 600: rs_write_int(savef, cnt);
! 601:
! 602: for(i = 0; i < cnt; i++)
! 603: {
! 604: if (dlist[i].d_func == rollwand)
! 605: func = 1;
! 606: else if (dlist[i].d_func == doctor)
! 607: func = 2;
! 608: else if (dlist[i].d_func == stomach)
! 609: func = 3;
! 610: else if (dlist[i].d_func == runners)
! 611: func = 4;
! 612: else if (dlist[i].d_func == swander)
! 613: func = 5;
! 614: else if (dlist[i].d_func == nohaste)
! 615: func = 6;
! 616: else if (dlist[i].d_func == unconfuse)
! 617: func = 7;
! 618: else if (dlist[i].d_func == unsee)
! 619: func = 8;
! 620: else if (dlist[i].d_func == sight)
! 621: func = 9;
! 622: else if (dlist[i].d_func == NULL)
! 623: func = 0;
! 624: else
! 625: func = -1;
! 626:
! 627: rs_write_int(savef, dlist[i].d_type);
! 628: rs_write_int(savef, func);
! 629: rs_write_int(savef, dlist[i].d_arg);
! 630: rs_write_int(savef, dlist[i].d_time);
! 631: }
! 632: }
! 633:
! 634: void
! 635: rs_read_daemons(FILE *savef, struct delayed_action *dlist, int cnt)
! 636: {
! 637: int i = 0;
! 638: int func = 0;
! 639: int value = 0;
! 640:
! 641: rs_read_marker(savef, RSID_DAEMONS);
! 642: rs_read_int(savef, &value);
! 643:
! 644: if (!encerror() && (value > cnt))
! 645: {
! 646: encseterr(EILSEQ);
! 647: return;
! 648: }
! 649:
! 650: for(i=0; i < cnt; i++)
! 651: {
! 652: func = 0;
! 653: rs_read_int(savef, &dlist[i].d_type);
! 654: rs_read_int(savef, &func);
! 655: rs_read_int(savef, &dlist[i].d_arg);
! 656: rs_read_int(savef, &dlist[i].d_time);
! 657:
! 658: if (encerror())
! 659: return;
! 660:
! 661: switch(func)
! 662: {
! 663: case 1: dlist[i].d_func = rollwand;
! 664: break;
! 665: case 2: dlist[i].d_func = doctor;
! 666: break;
! 667: case 3: dlist[i].d_func = stomach;
! 668: break;
! 669: case 4: dlist[i].d_func = runners;
! 670: break;
! 671: case 5: dlist[i].d_func = swander;
! 672: break;
! 673: case 6: dlist[i].d_func = nohaste;
! 674: break;
! 675: case 7: dlist[i].d_func = unconfuse;
! 676: break;
! 677: case 8: dlist[i].d_func = unsee;
! 678: break;
! 679: case 9: dlist[i].d_func = sight;
! 680: break;
! 681: default:dlist[i].d_func = NULL;
! 682: break;
! 683: }
! 684: if (dlist[i].d_func == NULL)
! 685: {
! 686: dlist[i].d_type = 0;
! 687: dlist[i].d_arg = 0;
! 688: dlist[i].d_time = 0;
! 689: }
! 690: }
! 691: }
! 692:
! 693: void
! 694: rs_write_room(FILE *savef, struct room *r)
! 695: {
! 696: rs_write_coord(savef, r->r_pos);
! 697: rs_write_coord(savef, r->r_max);
! 698: rs_write_coord(savef, r->r_gold);
! 699: rs_write_int(savef, r->r_goldval);
! 700: rs_write_int(savef, r->r_flags);
! 701: rs_write_int(savef, r->r_nexits);
! 702: rs_write_coord(savef, r->r_exit[0]);
! 703: rs_write_coord(savef, r->r_exit[1]);
! 704: rs_write_coord(savef, r->r_exit[2]);
! 705: rs_write_coord(savef, r->r_exit[3]);
! 706: }
! 707:
! 708: void
! 709: rs_read_room(FILE *savef, struct room *r)
! 710: {
! 711: rs_read_coord(savef,&r->r_pos);
! 712: rs_read_coord(savef,&r->r_max);
! 713: rs_read_coord(savef,&r->r_gold);
! 714: rs_read_int(savef,&r->r_goldval);
! 715: rs_read_int(savef,&r->r_flags);
! 716: rs_read_int(savef,&r->r_nexits);
! 717: rs_read_coord(savef,&r->r_exit[0]);
! 718: rs_read_coord(savef,&r->r_exit[1]);
! 719: rs_read_coord(savef,&r->r_exit[2]);
! 720: rs_read_coord(savef,&r->r_exit[3]);
! 721: }
! 722:
! 723: void
! 724: rs_write_rooms(FILE *savef, struct room r[], int cnt)
! 725: {
! 726: int n = 0;
! 727:
! 728: rs_write_int(savef, cnt);
! 729:
! 730: for(n = 0; n < cnt; n++)
! 731: rs_write_room(savef, &r[n]);
! 732: }
! 733:
! 734: void
! 735: rs_read_rooms(FILE *savef, struct room *r, int cnt)
! 736: {
! 737: int value = 0, n = 0;
! 738:
! 739: rs_read_int(savef,&value);
! 740:
! 741: if (!encerror() && (value > cnt))
! 742: encseterr(EILSEQ);
! 743: else
! 744: for(n = 0; n < value; n++)
! 745: rs_read_room(savef,&r[n]);
! 746: }
! 747:
! 748: void
! 749: rs_write_room_reference(FILE *savef, struct room *rp)
! 750: {
! 751: int i, room = -1;
! 752:
! 753: for (i = 0; i < MAXROOMS; i++)
! 754: if (&rooms[i] == rp)
! 755: room = i;
! 756:
! 757: rs_write_int(savef, room);
! 758: }
! 759:
! 760: void
! 761: rs_read_room_reference(FILE *savef, struct room **rp)
! 762: {
! 763: int i;
! 764:
! 765: rs_read_int(savef, &i);
! 766:
! 767: if (!encerror()) {
! 768: if (i >= 0 && i < MAXROOMS)
! 769: *rp = &rooms[i];
! 770: else
! 771: *rp = NULL;
! 772: }
! 773: }
! 774:
! 775: void
! 776: rs_write_object(FILE *savef, struct object *o)
! 777: {
! 778: rs_write_marker(savef, RSID_OBJECT);
! 779: rs_write_int(savef, o->o_type);
! 780: rs_write_coord(savef, o->o_pos);
! 781: rs_write_int(savef, o->o_launch);
! 782: rs_write_chars(savef, o->o_damage, sizeof(o->o_damage));
! 783: rs_write_chars(savef, o->o_hurldmg, sizeof(o->o_hurldmg));
! 784: rs_write_int(savef, o->o_count);
! 785: rs_write_int(savef, o->o_which);
! 786: rs_write_int(savef, o->o_hplus);
! 787: rs_write_int(savef, o->o_dplus);
! 788: rs_write_int(savef, o->o_ac);
! 789: rs_write_int(savef, o->o_flags);
! 790: rs_write_int(savef, o->o_group);
! 791: }
! 792:
! 793: void
! 794: rs_read_object(FILE *savef, struct object *o)
! 795: {
! 796: rs_read_marker(savef, RSID_OBJECT);
! 797: rs_read_int(savef, &o->o_type);
! 798: rs_read_coord(savef, &o->o_pos);
! 799: rs_read_int(savef, &o->o_launch);
! 800: rs_read_chars(savef, o->o_damage, sizeof(o->o_damage));
! 801: rs_read_chars(savef, o->o_hurldmg, sizeof(o->o_hurldmg));
! 802: rs_read_int(savef, &o->o_count);
! 803: rs_read_int(savef, &o->o_which);
! 804: rs_read_int(savef, &o->o_hplus);
! 805: rs_read_int(savef, &o->o_dplus);
! 806: rs_read_int(savef,&o->o_ac);
! 807: rs_read_int(savef,&o->o_flags);
! 808: rs_read_int(savef,&o->o_group);
! 809: }
! 810:
! 811: void
! 812: rs_write_object_list(FILE *savef, struct linked_list *l)
! 813: {
! 814: rs_write_marker(savef, RSID_OBJECTLIST);
! 815: rs_write_int(savef, list_size(l));
! 816:
! 817: for( ;l != NULL; l = l->l_next)
! 818: rs_write_object(savef, (struct object *) l->l_data);
! 819: }
! 820:
! 821: void
! 822: rs_read_object_list(FILE *savef, struct linked_list **list)
! 823: {
! 824: int i, cnt;
! 825: struct linked_list *l = NULL, *previous = NULL, *head = NULL;
! 826:
! 827: rs_read_marker(savef, RSID_OBJECTLIST);
! 828: rs_read_int(savef, &cnt);
! 829:
! 830: if (encerror())
! 831: return;
! 832:
! 833: for (i = 0; i < cnt; i++)
! 834: {
! 835: l = new_item(sizeof(struct object));
! 836:
! 837: memset(l->l_data,0,sizeof(struct object));
! 838:
! 839: l->l_prev = previous;
! 840:
! 841: if (previous != NULL)
! 842: previous->l_next = l;
! 843:
! 844: rs_read_object(savef,(struct object *) l->l_data);
! 845:
! 846: if (previous == NULL)
! 847: head = l;
! 848:
! 849: previous = l;
! 850: }
! 851:
! 852: if (l != NULL)
! 853: l->l_next = NULL;
! 854:
! 855: *list = head;
! 856: }
! 857:
! 858: void
! 859: rs_write_object_reference(FILE *savef, struct linked_list *list, struct object *item)
! 860: {
! 861: int i;
! 862:
! 863: i = find_list_ptr(list, item);
! 864:
! 865: rs_write_int(savef, i);
! 866: }
! 867:
! 868: void
! 869: rs_read_object_reference(FILE *savef, struct linked_list *list, struct object **item)
! 870: {
! 871: int i;
! 872:
! 873: rs_read_int(savef, &i);
! 874:
! 875: if (!encerror())
! 876: *item = get_list_item(list,i);
! 877: else
! 878: *item = NULL;
! 879: }
! 880:
! 881: int
! 882: find_room_coord(const struct room *rmlist, const coord *c, int n)
! 883: {
! 884: int i = 0;
! 885:
! 886: for(i = 0; i < n; i++)
! 887: if(&rmlist[i].r_gold == c)
! 888: return(i);
! 889:
! 890: return(-1);
! 891: }
! 892:
! 893: int
! 894: find_thing_coord(struct linked_list *monlist, coord *c)
! 895: {
! 896: struct linked_list *mitem;
! 897: struct thing *tp;
! 898: int i = 0;
! 899:
! 900: for(mitem = monlist; mitem != NULL; mitem = mitem->l_next)
! 901: {
! 902: tp = THINGPTR(mitem);
! 903:
! 904: if (c == &tp->t_pos)
! 905: return(i);
! 906:
! 907: i++;
! 908: }
! 909:
! 910: return(-1);
! 911: }
! 912:
! 913: int
! 914: find_object_coord(struct linked_list *objlist, coord *c)
! 915: {
! 916: struct linked_list *oitem;
! 917: struct object *obj;
! 918: int i = 0;
! 919:
! 920: for(oitem = objlist; oitem != NULL; oitem = oitem->l_next)
! 921: {
! 922: obj = OBJPTR(oitem);
! 923:
! 924: if (c == &obj->o_pos)
! 925: return(i);
! 926:
! 927: i++;
! 928: }
! 929:
! 930: return(-1);
! 931: }
! 932:
! 933: void
! 934: rs_write_thing(FILE *savef, struct thing *t)
! 935: {
! 936: int i = -1;
! 937:
! 938: rs_write_marker(savef, RSID_THING);
! 939:
! 940: if (t == NULL)
! 941: {
! 942: rs_write_int(savef, 0);
! 943: return;
! 944: }
! 945:
! 946: rs_write_int(savef, 1);
! 947: rs_write_coord(savef, t->t_pos);
! 948: rs_write_int(savef, t->t_turn);
! 949: rs_write_int(savef, t->t_type);
! 950: rs_write_int(savef, t->t_disguise);
! 951: rs_write_int(savef, t->t_oldch);
! 952:
! 953: /*
! 954: t_dest can be:
! 955: 0,0: NULL
! 956: 0,1: location of hero
! 957: 1,i: location of a thing (monster)
! 958: 2,i: location of an object
! 959: 3,i: location of gold in a room
! 960:
! 961: We need to remember what we are chasing rather than
! 962: the current location of what we are chasing.
! 963: */
! 964:
! 965: if (t->t_dest == &hero)
! 966: {
! 967: rs_write_int(savef,0);
! 968: rs_write_int(savef,1);
! 969: }
! 970: else if (t->t_dest != NULL)
! 971: {
! 972: i = find_thing_coord(mlist, t->t_dest);
! 973:
! 974: if (i >=0 )
! 975: {
! 976: rs_write_int(savef,1);
! 977: rs_write_int(savef,i);
! 978: }
! 979: else
! 980: {
! 981: i = find_object_coord(lvl_obj, t->t_dest);
! 982:
! 983: if (i >= 0)
! 984: {
! 985: rs_write_int(savef,2);
! 986: rs_write_int(savef,i);
! 987: }
! 988: else
! 989: {
! 990: i = find_room_coord(rooms, t->t_dest, MAXROOMS);
! 991:
! 992: if (i >= 0)
! 993: {
! 994: rs_write_int(savef,3);
! 995: rs_write_int(savef,i);
! 996: }
! 997: else
! 998: {
! 999: rs_write_int(savef, 0);
! 1000: rs_write_int(savef,1); /* chase the hero anyway */
! 1001: }
! 1002: }
! 1003: }
! 1004: }
! 1005: else
! 1006: {
! 1007: rs_write_int(savef,0);
! 1008: rs_write_int(savef,0);
! 1009: }
! 1010:
! 1011: rs_write_int(savef, t->t_flags);
! 1012: rs_write_stats(savef, &t->t_stats);
! 1013: rs_write_object_list(savef, t->t_pack);
! 1014: }
! 1015:
! 1016: void
! 1017: rs_read_thing(FILE *savef, struct thing *t)
! 1018: {
! 1019: int listid = 0, index = -1;
! 1020: struct linked_list *item;
! 1021:
! 1022: rs_read_marker(savef, RSID_THING);
! 1023: rs_read_int(savef, &index);
! 1024:
! 1025: if (encerror())
! 1026: return;
! 1027:
! 1028: if (index == 0)
! 1029: return;
! 1030:
! 1031: rs_read_coord(savef,&t->t_pos);
! 1032: rs_read_int(savef,&t->t_turn);
! 1033: rs_read_int(savef,&t->t_type);
! 1034: rs_read_int(savef,&t->t_disguise);
! 1035: rs_read_int(savef,&t->t_oldch);
! 1036:
! 1037: /*
! 1038: t_dest can be (listid,index):
! 1039: 0,0: NULL
! 1040: 0,1: location of hero
! 1041: 1,i: location of a thing (monster)
! 1042: 2,i: location of an object
! 1043: 3,i: location of gold in a room
! 1044:
! 1045: We need to remember what we are chasing rather than
! 1046: the current location of what we are chasing.
! 1047: */
! 1048:
! 1049: rs_read_int(savef, &listid);
! 1050: rs_read_int(savef, &index);
! 1051: t->t_reserved = -1;
! 1052:
! 1053: if (encerror())
! 1054: return;
! 1055:
! 1056: if (listid == 0) /* hero or NULL */
! 1057: {
! 1058: if (index == 1)
! 1059: t->t_dest = &hero;
! 1060: else
! 1061: t->t_dest = NULL;
! 1062: }
! 1063: else if (listid == 1) /* monster/thing */
! 1064: {
! 1065: t->t_dest = NULL;
! 1066: t->t_reserved = index;
! 1067: }
! 1068: else if (listid == 2) /* object */
! 1069: {
! 1070: struct object *obj;
! 1071:
! 1072: item = get_list_item(lvl_obj,index);
! 1073:
! 1074: if (item != NULL)
! 1075: {
! 1076: obj = OBJPTR(item);
! 1077: t->t_dest = &obj->o_pos;
! 1078: }
! 1079: }
! 1080: else if (listid == 3) /* gold */
! 1081: {
! 1082: t->t_dest = &rooms[index].r_gold;
! 1083: }
! 1084: else
! 1085: t->t_dest = NULL;
! 1086:
! 1087: rs_read_int(savef,&t->t_flags);
! 1088: rs_read_stats(savef,&t->t_stats);
! 1089: rs_read_object_list(savef,&t->t_pack);
! 1090: }
! 1091:
! 1092: void
! 1093: rs_fix_thing(struct thing *t)
! 1094: {
! 1095: struct linked_list *item;
! 1096: struct thing *tp;
! 1097:
! 1098: if (t->t_reserved < 0)
! 1099: return;
! 1100:
! 1101: item = get_list_item(mlist,t->t_reserved);
! 1102:
! 1103: if (item != NULL)
! 1104: {
! 1105: tp = THINGPTR(item);
! 1106: t->t_dest = &tp->t_pos;
! 1107: }
! 1108: }
! 1109:
! 1110: void
! 1111: rs_write_thing_list(FILE *savef, struct linked_list *l)
! 1112: {
! 1113: int cnt = 0;
! 1114:
! 1115: rs_write_marker(savef, RSID_MONSTERLIST);
! 1116:
! 1117: cnt = list_size(l);
! 1118:
! 1119: rs_write_int(savef, cnt);
! 1120:
! 1121: if (cnt < 1)
! 1122: return;
! 1123:
! 1124: while (l != NULL) {
! 1125: rs_write_thing(savef, (struct thing *)l->l_data);
! 1126: l = l->l_next;
! 1127: }
! 1128: }
! 1129:
! 1130: void
! 1131: rs_read_thing_list(FILE *savef, struct linked_list **list)
! 1132: {
! 1133: int i, cnt;
! 1134: struct linked_list *l = NULL, *previous = NULL, *head = NULL;
! 1135:
! 1136: rs_read_marker(savef, RSID_MONSTERLIST);
! 1137: rs_read_int(savef, &cnt);
! 1138:
! 1139: if (encerror())
! 1140: return;
! 1141:
! 1142: for (i = 0; i < cnt; i++)
! 1143: {
! 1144: l = new_item(sizeof(struct thing));
! 1145:
! 1146: l->l_prev = previous;
! 1147:
! 1148: if (previous != NULL)
! 1149: previous->l_next = l;
! 1150:
! 1151: rs_read_thing(savef,(struct thing *)l->l_data);
! 1152:
! 1153: if (previous == NULL)
! 1154: head = l;
! 1155:
! 1156: previous = l;
! 1157: }
! 1158:
! 1159: if (l != NULL)
! 1160: l->l_next = NULL;
! 1161:
! 1162: *list = head;
! 1163: }
! 1164:
! 1165: void
! 1166: rs_fix_thing_list(struct linked_list *list)
! 1167: {
! 1168: struct linked_list *item;
! 1169:
! 1170: for(item = list; item != NULL; item = item->l_next)
! 1171: rs_fix_thing(THINGPTR(item));
! 1172: }
! 1173:
! 1174: void
! 1175: rs_fix_magic_items(struct magic_item *mi, int cnt)
! 1176: {
! 1177: int i;
! 1178:
! 1179: for (i = 0; i < cnt; i++)
! 1180: if (i > 0)
! 1181: mi[i].mi_prob += mi[i-1].mi_prob;
! 1182: }
! 1183:
! 1184: void
! 1185: rs_fix_monsters(struct monster mons[26])
! 1186: {
! 1187: sprintf(mons['F'-'A'].m_stats.s_dmg,"%dd1",fung_hit);
! 1188: }
! 1189:
! 1190: void
! 1191: rs_write_trap(FILE *savef, struct trap *trap)
! 1192: {
! 1193: rs_write_coord(savef, trap->tr_pos);
! 1194: rs_write_int(savef, trap->tr_type);
! 1195: rs_write_int(savef, trap->tr_flags);
! 1196: }
! 1197:
! 1198: void
! 1199: rs_read_trap(FILE *savef, struct trap *trap)
! 1200: {
! 1201: rs_read_coord(savef,&trap->tr_pos);
! 1202: rs_read_int(savef,&trap->tr_type);
! 1203: rs_read_int(savef,&trap->tr_flags);
! 1204: }
! 1205:
! 1206: void
! 1207: rs_write_traps(FILE *savef, struct trap t[], int cnt)
! 1208: {
! 1209: int n = 0;
! 1210:
! 1211: rs_write_marker(savef, RSID_MONSTERS);
! 1212: rs_write_int(savef, cnt);
! 1213:
! 1214: for(n = 0; n < cnt; n++)
! 1215: rs_write_trap(savef, &t[n]);
! 1216: }
! 1217:
! 1218: void
! 1219: rs_read_traps(FILE *savef, struct trap *t, int cnt)
! 1220: {
! 1221: int value = 0, n = 0;
! 1222:
! 1223: rs_read_marker(savef, RSID_MONSTERS);
! 1224:
! 1225: rs_read_int(savef,&value);
! 1226:
! 1227: if (!encerror() && (value > cnt))
! 1228: encseterr(EILSEQ);
! 1229:
! 1230: for(n = 0; n < value; n++)
! 1231: rs_read_trap(savef,&t[n]);
! 1232: }
! 1233:
! 1234: int
! 1235: rs_save_file(FILE *savef)
! 1236: {
! 1237: encclearerr();
! 1238:
! 1239: rs_write_thing(savef, &player);
! 1240: rs_write_object_list(savef, lvl_obj);
! 1241: rs_write_thing_list(savef, mlist);
! 1242: rs_write_traps(savef, traps, MAXTRAPS);
! 1243: rs_write_rooms(savef, rooms, MAXROOMS);
! 1244: rs_write_room_reference(savef, oldrp);
! 1245: rs_write_stats(savef,&max_stats);
! 1246: rs_write_object_reference(savef, player.t_pack, cur_weapon);
! 1247: rs_write_object_reference(savef, player.t_pack, cur_armor);
! 1248: rs_write_object_reference(savef, player.t_pack, cur_ring[0]);
! 1249: rs_write_object_reference(savef, player.t_pack, cur_ring[1]);
! 1250: rs_write_int(savef, level);
! 1251: rs_write_int(savef, purse);
! 1252: rs_write_int(savef, mpos);
! 1253: rs_write_int(savef, ntraps);
! 1254: rs_write_int(savef, no_move);
! 1255: rs_write_int(savef, no_command);
! 1256: rs_write_int(savef, inpack);
! 1257: rs_write_int(savef, max_hp);
! 1258: rs_write_int(savef, total);
! 1259: rs_write_int(savef, lastscore);
! 1260: rs_write_int(savef, no_food);
! 1261: rs_write_int(savef, seed);
! 1262: rs_write_int(savef, count);
! 1263: rs_write_int(savef, dnum);
! 1264: rs_write_int(savef, fung_hit);
! 1265: rs_write_int(savef, quiet);
! 1266: rs_write_int(savef, max_level);
! 1267: rs_write_int(savef, food_left);
! 1268: rs_write_int(savef, group);
! 1269: rs_write_int(savef, hungry_state);
! 1270: rs_write_int(savef, take);
! 1271: rs_write_int(savef, runch);
! 1272: rs_write_scrolls(savef);
! 1273: rs_write_potions(savef);
! 1274: rs_write_rings(savef);
! 1275: rs_write_sticks(savef);
! 1276: rs_write_chars(savef,whoami,80);
! 1277: rs_write_chars(savef,fruit,80);
! 1278: rs_write_window(savef, cw);
! 1279: rs_write_window(savef, mw);
! 1280: rs_write_window(savef, stdscr);
! 1281: rs_write_int(savef, running);
! 1282: rs_write_int(savef, playing);
! 1283: rs_write_int(savef, wizard);
! 1284: rs_write_int(savef, after);
! 1285: rs_write_int(savef, notify);
! 1286: rs_write_int(savef, fight_flush);
! 1287: rs_write_int(savef, terse);
! 1288: rs_write_int(savef, door_stop);
! 1289: rs_write_int(savef, jump);
! 1290: rs_write_int(savef, slow_invent);
! 1291: rs_write_int(savef, firstmove);
! 1292: rs_write_int(savef, waswizard);
! 1293: rs_write_int(savef, askme);
! 1294: rs_write_int(savef, amulet);
! 1295: rs_write_int(savef, in_shell);
! 1296: rs_write_coord(savef, oldpos);
! 1297: rs_write_coord(savef, delta);
! 1298: rs_write_coord(savef, ch_ret); /* chase.c */
! 1299: rs_write_daemons(savef, &d_list[0], 20); /* daemon.c */
! 1300: rs_write_int(savef,between); /* daemons.c */
! 1301: rs_write_int(savef,num_checks); /* main.c */
! 1302: rs_write_chars(savef,lvl_mons,sizeof(lvl_mons)); /* monsters.c */
! 1303: rs_write_chars(savef,wand_mons,sizeof(wand_mons)); /* monsters.c */
! 1304:
! 1305: return( encclearerr() );
! 1306: }
! 1307:
! 1308: int
! 1309: rs_restore_file(FILE *savef)
! 1310: {
! 1311: encclearerr();
! 1312:
! 1313: rs_read_thing(savef, &player);
! 1314: rs_read_object_list(savef, &lvl_obj);
! 1315: rs_read_thing_list(savef, &mlist);
! 1316: rs_fix_thing(&player);
! 1317: rs_fix_thing_list(mlist);
! 1318: rs_read_traps(savef, traps, MAXTRAPS);
! 1319: rs_read_rooms(savef, rooms, MAXROOMS);
! 1320: rs_read_room_reference(savef, &oldrp);
! 1321: rs_read_stats(savef,&max_stats);
! 1322: rs_read_object_reference(savef, player.t_pack, &cur_weapon);
! 1323: rs_read_object_reference(savef, player.t_pack, &cur_armor);
! 1324: rs_read_object_reference(savef, player.t_pack, &cur_ring[0]);
! 1325: rs_read_object_reference(savef, player.t_pack, &cur_ring[1]);
! 1326: rs_fix_magic_items(things,NUMTHINGS);
! 1327: rs_fix_magic_items(s_magic,MAXSCROLLS);
! 1328: rs_fix_magic_items(p_magic,MAXPOTIONS);
! 1329: rs_fix_magic_items(r_magic,MAXRINGS);
! 1330: rs_fix_magic_items(ws_magic,MAXSTICKS);
! 1331: rs_read_int(savef, &level);
! 1332: rs_read_int(savef, &purse);
! 1333: rs_read_int(savef, &mpos);
! 1334: rs_read_int(savef, &ntraps);
! 1335: rs_read_int(savef, &no_move);
! 1336: rs_read_int(savef, &no_command);
! 1337: rs_read_int(savef, &inpack);
! 1338: rs_read_int(savef, &max_hp);
! 1339: rs_read_int(savef, &total);
! 1340: rs_read_int(savef, &lastscore);
! 1341: rs_read_int(savef, &no_food);
! 1342: rs_read_int(savef, &seed);
! 1343: rs_read_int(savef, &count);
! 1344: rs_read_int(savef, &dnum);
! 1345: rs_read_int(savef, &fung_hit);
! 1346: rs_read_int(savef, &quiet);
! 1347: rs_read_int(savef, &max_level);
! 1348: rs_read_int(savef, &food_left);
! 1349: rs_read_int(savef, &group);
! 1350: rs_read_int(savef, &hungry_state);
! 1351: rs_read_int(savef, &take);
! 1352: rs_read_int(savef, &runch);
! 1353: rs_read_scrolls(savef);
! 1354: rs_read_potions(savef);
! 1355: rs_read_rings(savef);
! 1356: rs_read_sticks(savef);
! 1357: rs_read_chars(savef,whoami,80);
! 1358: rs_read_chars(savef,fruit,80);
! 1359: rs_read_window(savef, cw);
! 1360: rs_read_window(savef, mw);
! 1361: rs_read_window(savef, stdscr);
! 1362: rs_read_int(savef, &running);
! 1363: rs_read_int(savef, &playing);
! 1364: rs_read_int(savef, &wizard);
! 1365: rs_read_int(savef, &after);
! 1366: rs_read_int(savef, ¬ify);
! 1367: rs_read_int(savef, &fight_flush);
! 1368: rs_read_int(savef, &terse);
! 1369: rs_read_int(savef, &door_stop);
! 1370: rs_read_int(savef, &jump);
! 1371: rs_read_int(savef, &slow_invent);
! 1372: rs_read_int(savef, &firstmove);
! 1373: rs_read_int(savef, &waswizard);
! 1374: rs_read_int(savef, &askme);
! 1375: rs_read_int(savef, &amulet);
! 1376: rs_read_int(savef, &in_shell);
! 1377: rs_read_coord(savef,&oldpos);
! 1378: rs_read_coord(savef,&delta);
! 1379: rs_read_coord(savef, &ch_ret); /* chase.c */
! 1380: rs_read_daemons(savef, d_list, 20); /* daemon.c */
! 1381: rs_read_int(savef,&between); /* daemons.c */
! 1382: rs_read_int(savef,&num_checks); /* main.c */
! 1383: rs_read_chars(savef, lvl_mons, sizeof(lvl_mons)); /* monsters.c */
! 1384: rs_read_chars(savef, wand_mons, sizeof(wand_mons)); /* monsters.c */
! 1385: rs_fix_monsters(monsters);
! 1386:
! 1387: return( encclearerr() );
! 1388: }
CVSweb