[BACK]Return to state.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / arogue5

Annotation of early-roguelike/arogue5/state.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:     state.c - Portable Rogue Save State Code
        !             3:
        !             4:     Copyright (C) 1999, 2000, 2005 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: /************************************************************************/
        !            33: /* Save State Code                                                      */
        !            34: /************************************************************************/
        !            35:
        !            36: #define RSID_STATS        0xABCD0001
        !            37: #define RSID_MSTATS       0xABCD0002
        !            38: #define RSID_THING        0xABCD0003
        !            39: #define RSID_OBJECT       0xABCD0004
        !            40: #define RSID_MAGICITEMS   0xABCD0005
        !            41: #define RSID_KNOWS        0xABCD0006
        !            42: #define RSID_GUESSES      0xABCD0007
        !            43: #define RSID_OBJECTLIST   0xABCD0008
        !            44: #define RSID_BAGOBJECT    0xABCD0009
        !            45: #define RSID_MONSTERLIST  0xABCD000A
        !            46: #define RSID_MONSTERSTATS 0xABCD000B
        !            47: #define RSID_MONSTERS     0xABCD000C
        !            48: #define RSID_TRAP         0xABCD000D
        !            49: #define RSID_WINDOW       0xABCD000E
        !            50: #define RSID_DAEMONS      0xABCD000F
        !            51: #define RSID_STICKS       0xABCD0010
        !            52: #define RSID_IARMOR       0xABCD0011
        !            53: #define RSID_SPELLS       0xABCD0012
        !            54: #define RSID_ILIST        0xABCD0013
        !            55: #define RSID_HLIST        0xABCD0014
        !            56: #define RSID_DEATHTYPE    0xABCD0015
        !            57: #define RSID_CTYPES       0XABCD0016
        !            58: #define RSID_COORDLIST    0XABCD0017
        !            59: #define RSID_ROOMS        0XABCD0018
        !            60:
        !            61: #include <curses.h>
        !            62: #include <stdio.h>
        !            63: #include <stdlib.h>
        !            64: #include <string.h>
        !            65: #include "rogue.h"
        !            66:
        !            67: int rs_read_int(FILE *inf, int *i);
        !            68: int rs_write_int(FILE *savef, int c);
        !            69: int list_size(struct linked_list *l);
        !            70: int rs_write_object_list(FILE *savef, struct linked_list *l);
        !            71: int rs_read_object_list(FILE *inf, struct linked_list **list);
        !            72:
        !            73: #define READSTAT (format_error || read_error )
        !            74: #define WRITESTAT (write_error)
        !            75:
        !            76: static int read_error   = FALSE;
        !            77: static int write_error  = FALSE;
        !            78: static int format_error = FALSE;
        !            79: static int endian = 0x01020304;
        !            80: #define  big_endian ( *((char *)&endian) == 0x01 )
        !            81:
        !            82: int
        !            83: rs_write(FILE *savef, void *ptr, size_t size)
        !            84: {
        !            85:     if (write_error)
        !            86:         return(WRITESTAT);
        !            87:
        !            88:     if (encwrite(ptr, size, savef) != size)
        !            89:         write_error = 1;
        !            90:
        !            91:     return(WRITESTAT);
        !            92: }
        !            93:
        !            94: int
        !            95: rs_read(FILE *inf, void *ptr, size_t size)
        !            96: {
        !            97:     if (read_error || format_error)
        !            98:         return(READSTAT);
        !            99:
        !           100:     if (encread(ptr, size, inf) != size)
        !           101:         read_error = 1;
        !           102:
        !           103:     return(READSTAT);
        !           104: }
        !           105:
        !           106: int
        !           107: rs_write_uchar(FILE *savef, unsigned char c)
        !           108: {
        !           109:     if (write_error)
        !           110:         return(WRITESTAT);
        !           111:
        !           112:     rs_write(savef, &c, 1);
        !           113:
        !           114:     return(WRITESTAT);
        !           115: }
        !           116:
        !           117: int
        !           118: rs_read_uchar(FILE *inf, unsigned char *c)
        !           119: {
        !           120:     if (read_error || format_error)
        !           121:         return(READSTAT);
        !           122:
        !           123:     rs_read(inf, c, 1);
        !           124:
        !           125:     return(READSTAT);
        !           126: }
        !           127:
        !           128: int
        !           129: rs_write_char(FILE *savef, char c)
        !           130: {
        !           131:     if (write_error)
        !           132:         return(WRITESTAT);
        !           133:
        !           134:     rs_write(savef, &c, 1);
        !           135:
        !           136:     return(WRITESTAT);
        !           137: }
        !           138:
        !           139: int
        !           140: rs_read_char(FILE *inf, char *c)
        !           141: {
        !           142:     if (read_error || format_error)
        !           143:         return(READSTAT);
        !           144:
        !           145:     rs_read(inf, c, 1);
        !           146:
        !           147:     return(READSTAT);
        !           148: }
        !           149:
        !           150: int
        !           151: rs_write_chars(FILE *savef, char *c, int count)
        !           152: {
        !           153:     if (write_error)
        !           154:         return(WRITESTAT);
        !           155:
        !           156:     rs_write_int(savef, count);
        !           157:     rs_write(savef, c, count);
        !           158:
        !           159:     return(WRITESTAT);
        !           160: }
        !           161:
        !           162: int
        !           163: rs_read_chars(FILE *inf, char *i, int count)
        !           164: {
        !           165:     int value = 0;
        !           166:
        !           167:     if (read_error || format_error)
        !           168:         return(READSTAT);
        !           169:
        !           170:     rs_read_int(inf, &value);
        !           171:
        !           172:     if (value != count)
        !           173:         format_error = TRUE;
        !           174:
        !           175:     rs_read(inf, i, count);
        !           176:
        !           177:     return(READSTAT);
        !           178: }
        !           179:
        !           180: int
        !           181: rs_write_int(FILE *savef, int c)
        !           182: {
        !           183:     unsigned char bytes[4];
        !           184:     unsigned char *buf = (unsigned char *) &c;
        !           185:
        !           186:     if (write_error)
        !           187:         return(WRITESTAT);
        !           188:
        !           189:     if (big_endian)
        !           190:     {
        !           191:         bytes[3] = buf[0];
        !           192:         bytes[2] = buf[1];
        !           193:         bytes[1] = buf[2];
        !           194:         bytes[0] = buf[3];
        !           195:         buf = bytes;
        !           196:     }
        !           197:
        !           198:     rs_write(savef, buf, 4);
        !           199:
        !           200:     return(WRITESTAT);
        !           201: }
        !           202:
        !           203: int
        !           204: rs_read_int(FILE *inf, int *i)
        !           205: {
        !           206:     unsigned char bytes[4];
        !           207:     int input = 0;
        !           208:     unsigned char *buf = (unsigned char *)&input;
        !           209:
        !           210:     if (read_error || format_error)
        !           211:         return(READSTAT);
        !           212:
        !           213:     rs_read(inf, &input, 4);
        !           214:
        !           215:     if (big_endian)
        !           216:     {
        !           217:         bytes[3] = buf[0];
        !           218:         bytes[2] = buf[1];
        !           219:         bytes[1] = buf[2];
        !           220:         bytes[0] = buf[3];
        !           221:         buf = bytes;
        !           222:     }
        !           223:
        !           224:     *i = *((int *) buf);
        !           225:
        !           226:     return(READSTAT);
        !           227: }
        !           228:
        !           229: int
        !           230: rs_write_ints(FILE *savef, int *c, int count)
        !           231: {
        !           232:     int n = 0;
        !           233:
        !           234:     if (write_error)
        !           235:         return(WRITESTAT);
        !           236:
        !           237:     rs_write_int(savef, count);
        !           238:
        !           239:     for(n = 0; n < count; n++)
        !           240:         if( rs_write_int(savef,c[n]) != 0)
        !           241:             break;
        !           242:
        !           243:     return(WRITESTAT);
        !           244: }
        !           245:
        !           246: int
        !           247: rs_read_ints(FILE *inf, int *i, int count)
        !           248: {
        !           249:     int n, value;
        !           250:
        !           251:     if (read_error || format_error)
        !           252:         return(READSTAT);
        !           253:
        !           254:     rs_read_int(inf,&value);
        !           255:
        !           256:     if (value != count)
        !           257:         format_error = TRUE;
        !           258:
        !           259:     for(n = 0; n < count; n++)
        !           260:         if (rs_read_int(inf, &i[n]) != 0)
        !           261:             break;
        !           262:
        !           263:     return(READSTAT);
        !           264: }
        !           265:
        !           266: int
        !           267: rs_write_boolean(FILE *savef, bool c)
        !           268: {
        !           269:     unsigned char buf = (c == 0) ? 0 : 1;
        !           270:
        !           271:     if (write_error)
        !           272:         return(WRITESTAT);
        !           273:
        !           274:     rs_write(savef, &buf, 1);
        !           275:
        !           276:     return(WRITESTAT);
        !           277: }
        !           278:
        !           279: int
        !           280: rs_read_boolean(FILE *inf, bool *i)
        !           281: {
        !           282:     unsigned char buf = 0;
        !           283:
        !           284:     if (read_error || format_error)
        !           285:         return(READSTAT);
        !           286:
        !           287:     rs_read(inf, &buf, 1);
        !           288:
        !           289:     *i = (buf != 0);
        !           290:
        !           291:     return(READSTAT);
        !           292: }
        !           293:
        !           294: int
        !           295: rs_write_booleans(FILE *savef, bool *c, int count)
        !           296: {
        !           297:     int n = 0;
        !           298:
        !           299:     if (write_error)
        !           300:         return(WRITESTAT);
        !           301:
        !           302:     rs_write_int(savef, count);
        !           303:
        !           304:     for(n = 0; n < count; n++)
        !           305:         if (rs_write_boolean(savef, c[n]) != 0)
        !           306:             break;
        !           307:
        !           308:     return(WRITESTAT);
        !           309: }
        !           310:
        !           311: int
        !           312: rs_read_booleans(FILE *inf, bool *i, int count)
        !           313: {
        !           314:     int n = 0, value = 0;
        !           315:
        !           316:     if (read_error || format_error)
        !           317:         return(READSTAT);
        !           318:
        !           319:     rs_read_int(inf,&value);
        !           320:
        !           321:     if (value != count)
        !           322:         format_error = TRUE;
        !           323:
        !           324:     for(n = 0; n < count; n++)
        !           325:         if (rs_read_boolean(inf, &i[n]) != 0)
        !           326:             break;
        !           327:
        !           328:     return(READSTAT);
        !           329: }
        !           330:
        !           331: int
        !           332: rs_write_short(FILE *savef, short c)
        !           333: {
        !           334:     unsigned char bytes[2];
        !           335:     unsigned char *buf = (unsigned char *) &c;
        !           336:
        !           337:     if (write_error)
        !           338:         return(WRITESTAT);
        !           339:
        !           340:     if (big_endian)
        !           341:     {
        !           342:         bytes[1] = buf[0];
        !           343:         bytes[0] = buf[1];
        !           344:         buf = bytes;
        !           345:     }
        !           346:
        !           347:     rs_write(savef, buf, 2);
        !           348:
        !           349:     return(WRITESTAT);
        !           350: }
        !           351:
        !           352: int
        !           353: rs_read_short(FILE *inf, short *i)
        !           354: {
        !           355:     unsigned char bytes[2];
        !           356:     short  input;
        !           357:     unsigned char *buf = (unsigned char *)&input;
        !           358:
        !           359:     if (read_error || format_error)
        !           360:         return(READSTAT);
        !           361:
        !           362:     rs_read(inf, &input, 2);
        !           363:
        !           364:     if (big_endian)
        !           365:     {
        !           366:         bytes[1] = buf[0];
        !           367:         bytes[0] = buf[1];
        !           368:         buf = bytes;
        !           369:     }
        !           370:
        !           371:     *i = *((short *) buf);
        !           372:
        !           373:     return(READSTAT);
        !           374: }
        !           375:
        !           376: int
        !           377: rs_write_shorts(FILE *savef, short *c, int count)
        !           378: {
        !           379:     int n = 0;
        !           380:
        !           381:     if (write_error)
        !           382:         return(WRITESTAT);
        !           383:
        !           384:     rs_write_int(savef, count);
        !           385:
        !           386:     for(n = 0; n < count; n++)
        !           387:         if (rs_write_short(savef, c[n]) != 0)
        !           388:             break;
        !           389:
        !           390:     return(WRITESTAT);
        !           391: }
        !           392:
        !           393: int
        !           394: rs_read_shorts(FILE *inf, short *i, int count)
        !           395: {
        !           396:     int n = 0, value = 0;
        !           397:
        !           398:     if (read_error || format_error)
        !           399:         return(READSTAT);
        !           400:
        !           401:     rs_read_int(inf,&value);
        !           402:
        !           403:     if (value != count)
        !           404:         format_error = TRUE;
        !           405:
        !           406:     for(n = 0; n < value; n++)
        !           407:         if (rs_read_short(inf, &i[n]) != 0)
        !           408:             break;
        !           409:
        !           410:     return(READSTAT);
        !           411: }
        !           412:
        !           413: int
        !           414: rs_write_ushort(FILE *savef, unsigned short c)
        !           415: {
        !           416:     unsigned char bytes[2];
        !           417:     unsigned char *buf = (unsigned char *) &c;
        !           418:
        !           419:     if (write_error)
        !           420:         return(WRITESTAT);
        !           421:
        !           422:     if (big_endian)
        !           423:     {
        !           424:         bytes[1] = buf[0];
        !           425:         bytes[0] = buf[1];
        !           426:         buf = bytes;
        !           427:     }
        !           428:
        !           429:     rs_write(savef, buf, 2);
        !           430:
        !           431:     return(WRITESTAT);
        !           432: }
        !           433:
        !           434: int
        !           435: rs_read_ushort(FILE *inf, unsigned short *i)
        !           436: {
        !           437:     unsigned char bytes[2];
        !           438:     unsigned short  input;
        !           439:     unsigned char *buf = (unsigned char *)&input;
        !           440:
        !           441:     if (read_error || format_error)
        !           442:         return(READSTAT);
        !           443:
        !           444:     rs_read(inf, &input, 2);
        !           445:
        !           446:     if (big_endian)
        !           447:     {
        !           448:         bytes[1] = buf[0];
        !           449:         bytes[0] = buf[1];
        !           450:         buf = bytes;
        !           451:     }
        !           452:
        !           453:     *i = *((unsigned short *) buf);
        !           454:
        !           455:     return(READSTAT);
        !           456: }
        !           457:
        !           458: int
        !           459: rs_write_uint(FILE *savef, unsigned int c)
        !           460: {
        !           461:     unsigned char bytes[4];
        !           462:     unsigned char *buf = (unsigned char *) &c;
        !           463:
        !           464:     if (write_error)
        !           465:         return(WRITESTAT);
        !           466:
        !           467:     if (big_endian)
        !           468:     {
        !           469:         bytes[3] = buf[0];
        !           470:         bytes[2] = buf[1];
        !           471:         bytes[1] = buf[2];
        !           472:         bytes[0] = buf[3];
        !           473:         buf = bytes;
        !           474:     }
        !           475:
        !           476:     rs_write(savef, buf, 4);
        !           477:
        !           478:     return(WRITESTAT);
        !           479: }
        !           480:
        !           481: int
        !           482: rs_read_uint(FILE *inf, unsigned int *i)
        !           483: {
        !           484:     unsigned char bytes[4];
        !           485:     int  input;
        !           486:     unsigned char *buf = (unsigned char *)&input;
        !           487:
        !           488:     if (read_error || format_error)
        !           489:         return(READSTAT);
        !           490:
        !           491:     rs_read(inf, &input, 4);
        !           492:
        !           493:     if (big_endian)
        !           494:     {
        !           495:         bytes[3] = buf[0];
        !           496:         bytes[2] = buf[1];
        !           497:         bytes[1] = buf[2];
        !           498:         bytes[0] = buf[3];
        !           499:         buf = bytes;
        !           500:     }
        !           501:
        !           502:     *i = *((unsigned int *) buf);
        !           503:
        !           504:     return(READSTAT);
        !           505: }
        !           506:
        !           507: int
        !           508: rs_write_long(FILE *savef, long c)
        !           509: {
        !           510:     int c2;
        !           511:     unsigned char bytes[4];
        !           512:     unsigned char *buf = (unsigned char *)&c;
        !           513:
        !           514:     if (write_error)
        !           515:         return(WRITESTAT);
        !           516:
        !           517:     if (sizeof(long) == 8)
        !           518:     {
        !           519:         c2 = c;
        !           520:         buf = (unsigned char *) &c2;
        !           521:     }
        !           522:
        !           523:     if (big_endian)
        !           524:     {
        !           525:         bytes[3] = buf[0];
        !           526:         bytes[2] = buf[1];
        !           527:         bytes[1] = buf[2];
        !           528:         bytes[0] = buf[3];
        !           529:         buf = bytes;
        !           530:     }
        !           531:
        !           532:     rs_write(savef, buf, 4);
        !           533:
        !           534:     return(WRITESTAT);
        !           535: }
        !           536:
        !           537: int
        !           538: rs_read_long(FILE *inf, long *i)
        !           539: {
        !           540:     unsigned char bytes[4];
        !           541:     long input;
        !           542:     unsigned char *buf = (unsigned char *) &input;
        !           543:
        !           544:     if (read_error || format_error)
        !           545:         return(READSTAT);
        !           546:
        !           547:     rs_read(inf, &input, 4);
        !           548:
        !           549:     if (big_endian)
        !           550:     {
        !           551:         bytes[3] = buf[0];
        !           552:         bytes[2] = buf[1];
        !           553:         bytes[1] = buf[2];
        !           554:         bytes[0] = buf[3];
        !           555:         buf = bytes;
        !           556:     }
        !           557:
        !           558:     *i = *((long *) buf);
        !           559:
        !           560:     return(READSTAT);
        !           561: }
        !           562:
        !           563: int
        !           564: rs_write_longs(FILE *savef, long *c, int count)
        !           565: {
        !           566:     int n = 0;
        !           567:
        !           568:     if (write_error)
        !           569:         return(WRITESTAT);
        !           570:
        !           571:     rs_write_int(savef,count);
        !           572:
        !           573:     for(n = 0; n < count; n++)
        !           574:         rs_write_long(savef, c[n]);
        !           575:
        !           576:     return(WRITESTAT);
        !           577: }
        !           578:
        !           579: int
        !           580: rs_read_longs(FILE *inf, long *i, int count)
        !           581: {
        !           582:     int n = 0, value = 0;
        !           583:
        !           584:     if (read_error || format_error)
        !           585:         return(READSTAT);
        !           586:
        !           587:     rs_read_int(inf,&value);
        !           588:
        !           589:     if (value != count)
        !           590:         format_error = TRUE;
        !           591:
        !           592:     for(n = 0; n < value; n++)
        !           593:         if (rs_read_long(inf, &i[n]) != 0)
        !           594:             break;
        !           595:
        !           596:     return(READSTAT);
        !           597: }
        !           598:
        !           599: int
        !           600: rs_write_ulong(FILE *savef, unsigned long c)
        !           601: {
        !           602:     unsigned int c2;
        !           603:     unsigned char bytes[4];
        !           604:     unsigned char *buf = (unsigned char *)&c;
        !           605:
        !           606:     if (write_error)
        !           607:         return(WRITESTAT);
        !           608:
        !           609:     if ( (sizeof(long) == 8) && (sizeof(int) == 4) )
        !           610:     {
        !           611:         c2 = c;
        !           612:         buf = (unsigned char *) &c2;
        !           613:     }
        !           614:
        !           615:     if (big_endian)
        !           616:     {
        !           617:         bytes[3] = buf[0];
        !           618:         bytes[2] = buf[1];
        !           619:         bytes[1] = buf[2];
        !           620:         bytes[0] = buf[3];
        !           621:         buf = bytes;
        !           622:     }
        !           623:
        !           624:     rs_write(savef, buf, 4);
        !           625:
        !           626:     return(WRITESTAT);
        !           627: }
        !           628:
        !           629: int
        !           630: rs_read_ulong(FILE *inf, unsigned long *i)
        !           631: {
        !           632:     unsigned char bytes[4];
        !           633:     unsigned long input;
        !           634:     unsigned char *buf = (unsigned char *) &input;
        !           635:
        !           636:     if (read_error || format_error)
        !           637:         return(READSTAT);
        !           638:
        !           639:     rs_read(inf, &input, 4);
        !           640:
        !           641:     if (big_endian)
        !           642:     {
        !           643:         bytes[3] = buf[0];
        !           644:         bytes[2] = buf[1];
        !           645:         bytes[1] = buf[2];
        !           646:         bytes[0] = buf[3];
        !           647:         buf = bytes;
        !           648:     }
        !           649:
        !           650:     if ( (sizeof(long) == 8) && (sizeof(int) == 4) )
        !           651:       *i = *((unsigned int *) buf);
        !           652:     else
        !           653:       *i = *((unsigned long *) buf);
        !           654:
        !           655:     return(READSTAT);
        !           656: }
        !           657:
        !           658: int
        !           659: rs_write_ulongs(FILE *savef, unsigned long *c, int count)
        !           660: {
        !           661:     int n = 0;
        !           662:
        !           663:     if (write_error)
        !           664:         return(WRITESTAT);
        !           665:
        !           666:     rs_write_int(savef,count);
        !           667:
        !           668:     for(n = 0; n < count; n++)
        !           669:         if (rs_write_ulong(savef,c[n]) != 0)
        !           670:             break;
        !           671:
        !           672:     return(WRITESTAT);
        !           673: }
        !           674:
        !           675: int
        !           676: rs_read_ulongs(FILE *inf, unsigned long *i, int count)
        !           677: {
        !           678:     int n = 0, value = 0;
        !           679:
        !           680:     if (read_error || format_error)
        !           681:         return(READSTAT);
        !           682:
        !           683:     rs_read_int(inf,&value);
        !           684:
        !           685:     if (value != count)
        !           686:         format_error = TRUE;
        !           687:
        !           688:     for(n = 0; n < count; n++)
        !           689:         if (rs_read_ulong(inf, &i[n]) != 0)
        !           690:             break;
        !           691:
        !           692:     return(READSTAT);
        !           693: }
        !           694:
        !           695: int
        !           696: rs_write_marker(FILE *savef, int id)
        !           697: {
        !           698:     if (write_error)
        !           699:         return(WRITESTAT);
        !           700:
        !           701:     rs_write_int(savef, id);
        !           702:
        !           703:     return(WRITESTAT);
        !           704: }
        !           705:
        !           706: int
        !           707: rs_read_marker(FILE *inf, int id)
        !           708: {
        !           709:     int nid;
        !           710:
        !           711:     if (read_error || format_error)
        !           712:         return(READSTAT);
        !           713:
        !           714:     if (rs_read_int(inf, &nid) == 0)
        !           715:         if (id != nid)
        !           716:             format_error = 1;
        !           717:
        !           718:     return(READSTAT);
        !           719: }
        !           720:
        !           721:
        !           722:
        !           723: /******************************************************************************/
        !           724:
        !           725: int
        !           726: rs_write_string(FILE *savef, char *s)
        !           727: {
        !           728:     int len = 0;
        !           729:
        !           730:     if (write_error)
        !           731:         return(WRITESTAT);
        !           732:
        !           733:     len = (s == NULL) ? 0 : (int) strlen(s) + 1;
        !           734:
        !           735:     rs_write_int(savef, len);
        !           736:     rs_write_chars(savef, s, len);
        !           737:
        !           738:     return(WRITESTAT);
        !           739: }
        !           740:
        !           741: int
        !           742: rs_read_string(FILE *inf, char *s, int max)
        !           743: {
        !           744:     int len = 0;
        !           745:
        !           746:     if (read_error || format_error)
        !           747:         return(READSTAT);
        !           748:
        !           749:     rs_read_int(inf, &len);
        !           750:
        !           751:     if (len > max)
        !           752:         format_error = TRUE;
        !           753:
        !           754:     rs_read_chars(inf, s, len);
        !           755:
        !           756:     return(READSTAT);
        !           757: }
        !           758:
        !           759: int
        !           760: rs_read_new_string(FILE *inf, char **s)
        !           761: {
        !           762:     int len=0;
        !           763:     char *buf=0;
        !           764:
        !           765:     if (read_error || format_error)
        !           766:         return(READSTAT);
        !           767:
        !           768:     rs_read_int(inf, &len);
        !           769:
        !           770:     if (len == 0)
        !           771:         buf = NULL;
        !           772:     else
        !           773:     {
        !           774:         buf = malloc(len);
        !           775:
        !           776:         if (buf == NULL)
        !           777:             read_error = TRUE;
        !           778:     }
        !           779:
        !           780:     rs_read_chars(inf, buf, len);
        !           781:
        !           782:     *s = buf;
        !           783:
        !           784:     return(READSTAT);
        !           785: }
        !           786:
        !           787: int
        !           788: rs_write_strings(FILE *savef, char *s[], int count)
        !           789: {
        !           790:     int n = 0;
        !           791:
        !           792:     if (write_error)
        !           793:         return(WRITESTAT);
        !           794:
        !           795:     rs_write_int(savef, count);
        !           796:
        !           797:     for(n = 0; n < count; n++)
        !           798:         if (rs_write_string(savef, s[n]) != 0)
        !           799:             break;
        !           800:
        !           801:     return(WRITESTAT);
        !           802: }
        !           803:
        !           804: int
        !           805: rs_read_strings(FILE *inf, char **s, int count, int max)
        !           806: {
        !           807:     int n     = 0;
        !           808:     int value = 0;
        !           809:
        !           810:     if (read_error || format_error)
        !           811:         return(READSTAT);
        !           812:
        !           813:     rs_read_int(inf, &value);
        !           814:
        !           815:     if (value != count)
        !           816:         format_error = TRUE;
        !           817:
        !           818:     for(n = 0; n < count; n++)
        !           819:         if (rs_read_string(inf, s[n], max) != 0)
        !           820:             break;
        !           821:
        !           822:     return(READSTAT);
        !           823: }
        !           824:
        !           825: int
        !           826: rs_read_new_strings(FILE *inf, char **s, int count)
        !           827: {
        !           828:     int n     = 0;
        !           829:     int value = 0;
        !           830:
        !           831:     if (read_error || format_error)
        !           832:         return(READSTAT);
        !           833:
        !           834:     rs_read_int(inf, &value);
        !           835:
        !           836:     if (value != count)
        !           837:         format_error = TRUE;
        !           838:
        !           839:     for(n = 0; n < count; n++)
        !           840:         if (rs_read_new_string(inf, &s[n]) != 0)
        !           841:             break;
        !           842:
        !           843:     return(READSTAT);
        !           844: }
        !           845:
        !           846: int
        !           847: rs_write_string_index(FILE *savef, char *master[], int max, const char *str)
        !           848: {
        !           849:     int i;
        !           850:
        !           851:     if (write_error)
        !           852:         return(WRITESTAT);
        !           853:
        !           854:     for(i = 0; i < max; i++)
        !           855:         if (str == master[i])
        !           856:             return( rs_write_int(savef, i) );
        !           857:
        !           858:     return( rs_write_int(savef,-1) );
        !           859: }
        !           860:
        !           861: int
        !           862: rs_read_string_index(FILE *inf, char *master[], int maxindex, char **str)
        !           863: {
        !           864:     int i;
        !           865:
        !           866:     if (read_error || format_error)
        !           867:         return(READSTAT);
        !           868:
        !           869:     rs_read_int(inf, &i);
        !           870:
        !           871:     if (i > maxindex)
        !           872:         format_error = TRUE;
        !           873:     else if (i >= 0)
        !           874:         *str = master[i];
        !           875:     else
        !           876:         *str = NULL;
        !           877:
        !           878:     return(READSTAT);
        !           879: }
        !           880:
        !           881: int
        !           882: rs_write_coord(FILE *savef, coord c)
        !           883: {
        !           884:     if (write_error)
        !           885:         return(WRITESTAT);
        !           886:
        !           887:     rs_write_int(savef, c.x);
        !           888:     rs_write_int(savef, c.y);
        !           889:
        !           890:     return(WRITESTAT);
        !           891: }
        !           892:
        !           893: int
        !           894: rs_read_coord(FILE *inf, coord *c)
        !           895: {
        !           896:     coord in;
        !           897:
        !           898:     if (read_error || format_error)
        !           899:         return(READSTAT);
        !           900:
        !           901:     rs_read_int(inf,&in.x);
        !           902:     rs_read_int(inf,&in.y);
        !           903:
        !           904:     if (READSTAT == 0)
        !           905:     {
        !           906:         c->x = in.x;
        !           907:         c->y = in.y;
        !           908:     }
        !           909:
        !           910:     return(READSTAT);
        !           911: }
        !           912:
        !           913: int
        !           914: rs_write_coord_list(FILE *savef, struct linked_list *l)
        !           915: {
        !           916:     rs_write_marker(savef, RSID_COORDLIST);
        !           917:     rs_write_int(savef, list_size(l));
        !           918:
        !           919:     while (l != NULL)
        !           920:     {
        !           921:         rs_write_coord(savef, *(coord *) l->l_data);
        !           922:         l = l->l_next;
        !           923:     }
        !           924:
        !           925:     return(WRITESTAT);
        !           926: }
        !           927:
        !           928: int
        !           929: rs_read_coord_list(FILE *inf, struct linked_list **list)
        !           930: {
        !           931:     int i, cnt;
        !           932:     struct linked_list *l = NULL, *previous = NULL, *head = NULL;
        !           933:
        !           934:     rs_read_marker(inf, RSID_COORDLIST);
        !           935:
        !           936:     if (rs_read_int(inf,&cnt) != 0)
        !           937:        return(READSTAT);
        !           938:
        !           939:     for (i = 0; i < cnt; i++)
        !           940:     {
        !           941:        l = new_item(sizeof(coord));
        !           942:         l->l_prev = previous;
        !           943:
        !           944:         if (previous != NULL)
        !           945:            previous->l_next = l;
        !           946:
        !           947:         rs_read_coord(inf,(coord *) l->l_data);
        !           948:
        !           949:        if (previous == NULL)
        !           950:            head = l;
        !           951:
        !           952:        previous = l;
        !           953:     }
        !           954:
        !           955:     if (l != NULL)
        !           956:        l->l_next = NULL;
        !           957:
        !           958:     *list = head;
        !           959:
        !           960:     return(READSTAT);
        !           961: }
        !           962:
        !           963: int
        !           964: rs_write_window(FILE *savef, WINDOW *win)
        !           965: {
        !           966:     int row,col,height,width;
        !           967:
        !           968:     if (write_error)
        !           969:         return(WRITESTAT);
        !           970:
        !           971:     width  = getmaxx(win);
        !           972:     height = getmaxy(win);
        !           973:
        !           974:     rs_write_marker(savef,RSID_WINDOW);
        !           975:     rs_write_int(savef,height);
        !           976:     rs_write_int(savef,width);
        !           977:
        !           978:     for(row=0;row<height;row++)
        !           979:         for(col=0;col<width;col++)
        !           980:             if (rs_write_int(savef, mvwinch(win,row,col)) != 0)
        !           981:                 return(WRITESTAT);
        !           982:
        !           983:     return(WRITESTAT);
        !           984: }
        !           985:
        !           986: int
        !           987: rs_read_window(FILE *inf, WINDOW *win)
        !           988: {
        !           989:     int row,col,maxlines,maxcols,value,width,height;
        !           990:
        !           991:     if (read_error || format_error)
        !           992:         return(READSTAT);
        !           993:
        !           994:     width  = getmaxx(win);
        !           995:     height = getmaxy(win);
        !           996:
        !           997:     rs_read_marker(inf, RSID_WINDOW);
        !           998:
        !           999:     rs_read_int(inf, &maxlines);
        !          1000:     rs_read_int(inf, &maxcols);
        !          1001:
        !          1002:     for(row = 0; row < maxlines; row++)
        !          1003:         for(col = 0; col < maxcols; col++)
        !          1004:         {
        !          1005:             if (rs_read_int(inf, &value) != 0)
        !          1006:                 return(READSTAT);
        !          1007:
        !          1008:             if ((row < height) && (col < width))
        !          1009:                 mvwaddch(win,row,col,value);
        !          1010:         }
        !          1011:
        !          1012:     return(READSTAT);
        !          1013: }
        !          1014:
        !          1015: /******************************************************************************/
        !          1016:
        !          1017: void *
        !          1018: get_list_item(struct linked_list *l, int i)
        !          1019: {
        !          1020:     int count;
        !          1021:
        !          1022:     for(count = 0; l != NULL; count++, l = l->l_next)
        !          1023:         if (count == i)
        !          1024:            return(l->l_data);
        !          1025:
        !          1026:     return(NULL);
        !          1027: }
        !          1028:
        !          1029: int
        !          1030: find_list_ptr(struct linked_list *l, void *ptr)
        !          1031: {
        !          1032:     int count;
        !          1033:
        !          1034:     for(count = 0; l != NULL; count++, l = l->l_next)
        !          1035:         if (l->l_data == ptr)
        !          1036:             return(count);
        !          1037:
        !          1038:     return(-1);
        !          1039: }
        !          1040:
        !          1041: int
        !          1042: list_size(struct linked_list *l)
        !          1043: {
        !          1044:     int count;
        !          1045:
        !          1046:     for(count = 0; l != NULL; count++, l = l->l_next)
        !          1047:         ;
        !          1048:
        !          1049:     return(count);
        !          1050: }
        !          1051:
        !          1052: /******************************************************************************/
        !          1053:
        !          1054: int
        !          1055: rs_write_levtype(FILE *savef, LEVTYPE c)
        !          1056: {
        !          1057:     int lt;
        !          1058:
        !          1059:     switch(c)
        !          1060:     {
        !          1061:         case NORMLEV: lt = 1; break;
        !          1062:         case POSTLEV: lt = 2; break;
        !          1063:         case MAZELEV: lt = 3; break;
        !          1064:         case OUTSIDE: lt = 4; break;
        !          1065:         default: lt = -1; break;
        !          1066:     }
        !          1067:
        !          1068:     rs_write_int(savef,lt);
        !          1069:
        !          1070:     return(WRITESTAT);
        !          1071: }
        !          1072:
        !          1073: int
        !          1074: rs_read_levtype(FILE *inf, LEVTYPE *l)
        !          1075: {
        !          1076:     int lt;
        !          1077:
        !          1078:     rs_read_int(inf, &lt);
        !          1079:
        !          1080:     switch(lt)
        !          1081:     {
        !          1082:         case 1: *l = NORMLEV; break;
        !          1083:         case 2: *l = POSTLEV; break;
        !          1084:         case 3: *l = MAZELEV; break;
        !          1085:         case 4: *l = OUTSIDE; break;
        !          1086:         default: *l = NORMLEV; break;
        !          1087:     }
        !          1088:
        !          1089:     return(READSTAT);
        !          1090: }
        !          1091:
        !          1092: int
        !          1093: rs_write_stats(FILE *savef, struct stats *s)
        !          1094: {
        !          1095:     if (write_error)
        !          1096:         return(WRITESTAT);
        !          1097:
        !          1098:     rs_write_marker(savef, RSID_STATS);
        !          1099:     rs_write_short(savef, s->s_str);
        !          1100:     rs_write_short(savef, s->s_intel);
        !          1101:     rs_write_short(savef, s->s_wisdom);
        !          1102:     rs_write_short(savef, s->s_dext);
        !          1103:     rs_write_short(savef, s->s_const);
        !          1104:     rs_write_short(savef, s->s_charisma);
        !          1105:     rs_write_ulong(savef, s->s_exp);
        !          1106:     rs_write_int(savef, s->s_lvl);
        !          1107:     rs_write_int(savef, s->s_arm);
        !          1108:     rs_write_int(savef, s->s_hpt);
        !          1109:     rs_write_int(savef, s->s_pack);
        !          1110:     rs_write_int(savef, s->s_carry);
        !          1111:     rs_write(savef, s->s_dmg, sizeof(s->s_dmg));
        !          1112:
        !          1113:     return(WRITESTAT);
        !          1114: }
        !          1115:
        !          1116: int
        !          1117: rs_read_stats(FILE *inf, struct stats *s)
        !          1118: {
        !          1119:     if (read_error || format_error)
        !          1120:         return(READSTAT);
        !          1121:
        !          1122:     rs_read_marker(inf, RSID_STATS);
        !          1123:     rs_read_short(inf,&s->s_str);
        !          1124:     rs_read_short(inf,&s->s_intel);
        !          1125:     rs_read_short(inf,&s->s_wisdom);
        !          1126:     rs_read_short(inf,&s->s_dext);
        !          1127:     rs_read_short(inf,&s->s_const);
        !          1128:     rs_read_short(inf,&s->s_charisma);
        !          1129:     rs_read_ulong(inf,&s->s_exp);
        !          1130:     rs_read_int(inf,&s->s_lvl);
        !          1131:     rs_read_int(inf,&s->s_arm);
        !          1132:     rs_read_int(inf,&s->s_hpt);
        !          1133:     rs_read_int(inf,&s->s_pack);
        !          1134:     rs_read_int(inf,&s->s_carry);
        !          1135:
        !          1136:     rs_read(inf,s->s_dmg,sizeof(s->s_dmg));
        !          1137:
        !          1138:     return(READSTAT);
        !          1139: }
        !          1140:
        !          1141: int
        !          1142: rs_write_magic_items(FILE *savef, struct magic_item *i, int count)
        !          1143: {
        !          1144:     int n;
        !          1145:
        !          1146:     rs_write_marker(savef, RSID_MAGICITEMS);
        !          1147:     rs_write_int(savef, count);
        !          1148:
        !          1149:     for(n = 0; n < count; n++)
        !          1150:     {
        !          1151:         rs_write_int(savef,i[n].mi_prob);
        !          1152:     }
        !          1153:
        !          1154:     return(WRITESTAT);
        !          1155: }
        !          1156:
        !          1157: int
        !          1158: rs_read_magic_items(FILE *inf, struct magic_item *mi, int count)
        !          1159: {
        !          1160:     int n;
        !          1161:     int value;
        !          1162:
        !          1163:     rs_read_marker(inf, RSID_MAGICITEMS);
        !          1164:
        !          1165:     rs_read_int(inf, &value);
        !          1166:
        !          1167:     if (value != count)
        !          1168:        format_error = 1;
        !          1169:     else
        !          1170:     {
        !          1171:        for(n = 0; n < value; n++)
        !          1172:         {
        !          1173:            rs_read_int(inf,&mi[n].mi_prob);
        !          1174:         }
        !          1175:     }
        !          1176:
        !          1177:     return(READSTAT);
        !          1178: }
        !          1179:
        !          1180: int
        !          1181: rs_write_scrolls(FILE *savef)
        !          1182: {
        !          1183:     int i;
        !          1184:
        !          1185:     if (write_error)
        !          1186:         return(WRITESTAT);
        !          1187:
        !          1188:     for(i = 0; i < MAXSCROLLS; i++)
        !          1189:     {
        !          1190:         rs_write_string(savef, s_names[i]);
        !          1191:        rs_write_boolean(savef,s_know[i]);
        !          1192:         rs_write_string(savef,s_guess[i]);
        !          1193:     }
        !          1194:
        !          1195:     return(WRITESTAT);
        !          1196: }
        !          1197:
        !          1198: int
        !          1199: rs_read_scrolls(FILE *inf)
        !          1200: {
        !          1201:     int i;
        !          1202:
        !          1203:     if (read_error || format_error)
        !          1204:         return(READSTAT);
        !          1205:
        !          1206:     for(i = 0; i < MAXSCROLLS; i++)
        !          1207:     {
        !          1208:         rs_read_new_string(inf,&s_names[i]);
        !          1209:         rs_read_boolean(inf,&s_know[i]);
        !          1210:         rs_read_new_string(inf,&s_guess[i]);
        !          1211:     }
        !          1212:
        !          1213:     return(READSTAT);
        !          1214: }
        !          1215:
        !          1216: int
        !          1217: rs_write_potions(FILE *savef)
        !          1218: {
        !          1219:     int i;
        !          1220:
        !          1221:     if (write_error)
        !          1222:         return(WRITESTAT);
        !          1223:
        !          1224:     for(i = 0; i < MAXPOTIONS; i++)
        !          1225:     {
        !          1226:        rs_write_string_index(savef,rainbow,NCOLORS,p_colors[i]);
        !          1227:         rs_write_boolean(savef,p_know[i]);
        !          1228:         rs_write_string(savef,p_guess[i]);
        !          1229:     }
        !          1230:
        !          1231:     return(WRITESTAT);
        !          1232: }
        !          1233:
        !          1234: int
        !          1235: rs_read_potions(FILE *inf)
        !          1236: {
        !          1237:     int i;
        !          1238:
        !          1239:     if (read_error || format_error)
        !          1240:         return(READSTAT);
        !          1241:
        !          1242:     for(i = 0; i < MAXPOTIONS; i++)
        !          1243:     {
        !          1244:         rs_read_string_index(inf,rainbow,NCOLORS,&p_colors[i]);
        !          1245:        rs_read_boolean(inf,&p_know[i]);
        !          1246:         rs_read_new_string(inf,&p_guess[i]);
        !          1247:     }
        !          1248:
        !          1249:     return(READSTAT);
        !          1250: }
        !          1251:
        !          1252: int
        !          1253: rs_write_rings(FILE *savef)
        !          1254: {
        !          1255:     int i;
        !          1256:
        !          1257:     if (write_error)
        !          1258:         return(WRITESTAT);
        !          1259:
        !          1260:     for(i = 0; i < MAXRINGS; i++)
        !          1261:     {
        !          1262:        rs_write_string_index(savef,stones,NSTONES,r_stones[i]);
        !          1263:         rs_write_boolean(savef,r_know[i]);
        !          1264:         rs_write_string(savef,r_guess[i]);
        !          1265:     }
        !          1266:
        !          1267:     return(WRITESTAT);
        !          1268: }
        !          1269:
        !          1270: int
        !          1271: rs_read_rings(FILE *inf)
        !          1272: {
        !          1273:     int i;
        !          1274:
        !          1275:     if (read_error || format_error)
        !          1276:         return(READSTAT);
        !          1277:
        !          1278:     for(i = 0; i < MAXRINGS; i++)
        !          1279:     {
        !          1280:         rs_read_string_index(inf,stones,NSTONES,&r_stones[i]);
        !          1281:        rs_read_boolean(inf,&r_know[i]);
        !          1282:         rs_read_new_string(inf,&r_guess[i]);
        !          1283:     }
        !          1284:
        !          1285:     return(READSTAT);
        !          1286: }
        !          1287:
        !          1288: int
        !          1289: rs_write_sticks(FILE *savef)
        !          1290: {
        !          1291:     int i;
        !          1292:
        !          1293:     if (write_error)
        !          1294:         return(WRITESTAT);
        !          1295:
        !          1296:     rs_write_marker(savef, RSID_STICKS);
        !          1297:
        !          1298:     for (i = 0; i < MAXSTICKS; i++)
        !          1299:     {
        !          1300:         if (strcmp(ws_type[i],"staff") == 0)
        !          1301:         {
        !          1302:             rs_write_int(savef,0);
        !          1303:            rs_write_string_index(savef,wood,NWOOD,ws_made[i]);
        !          1304:         }
        !          1305:         else
        !          1306:         {
        !          1307:             rs_write_int(savef,1);
        !          1308:            rs_write_string_index(savef,metal,NMETAL,ws_made[i]);
        !          1309:         }
        !          1310:
        !          1311:        rs_write_boolean(savef, ws_know[i]);
        !          1312:         rs_write_string(savef, ws_guess[i]);
        !          1313:     }
        !          1314:
        !          1315:     return(WRITESTAT);
        !          1316: }
        !          1317:
        !          1318: int
        !          1319: rs_read_sticks(FILE *inf)
        !          1320: {
        !          1321:     int i = 0, j = 0, list = 0;
        !          1322:
        !          1323:     if (read_error || format_error)
        !          1324:         return(READSTAT);
        !          1325:
        !          1326:     rs_read_marker(inf, RSID_STICKS);
        !          1327:
        !          1328:     for(i = 0; i < MAXSTICKS; i++)
        !          1329:     {
        !          1330:         rs_read_int(inf,&list);
        !          1331:         ws_made[i] = NULL;
        !          1332:
        !          1333:         if (list == 0)
        !          1334:         {
        !          1335:            rs_read_string_index(inf,wood,NWOOD,&ws_made[i]);
        !          1336:             ws_type[i] = "staff";
        !          1337:         }
        !          1338:         else
        !          1339:         {
        !          1340:            rs_read_string_index(inf,metal,NMETAL,&ws_made[i]);
        !          1341:            ws_type[i] = "wand";
        !          1342:         }
        !          1343:        rs_read_boolean(inf, &ws_know[i]);
        !          1344:         rs_read_new_string(inf, &ws_guess[i]);
        !          1345:     }
        !          1346:
        !          1347:     return(READSTAT);
        !          1348: }
        !          1349:
        !          1350: /* Assigns a number to an alchemy jug associated with a fuse, so it can be
        !          1351:  * found and reassociated when restoring.
        !          1352:  * 1 - 31: slot in pack
        !          1353:  * 32+   : on floor
        !          1354:  * Hopefully monsters do not pick them up.
        !          1355:  */
        !          1356: int number_alchemy_jug(struct object *obj) {
        !          1357:     struct object *tobj = NULL;
        !          1358:     struct linked_list *item;
        !          1359:     int i = 1;
        !          1360:     for (item = player.t_pack; item != NULL; item = next(item), i++) {
        !          1361:        tobj = OBJPTR(item);
        !          1362:        if (tobj         == obj         &&
        !          1363:            tobj->o_type == MM          &&
        !          1364:            tobj->o_which== MM_JUG)
        !          1365:                break;
        !          1366:     }
        !          1367:     if (item == NULL) {
        !          1368:        for (item = lvl_obj, i = 32; item != NULL; item = next(item), i++) {
        !          1369:            tobj = OBJPTR(item);
        !          1370:            if (tobj         == obj             &&
        !          1371:                tobj->o_type == MM              &&
        !          1372:                tobj->o_which== MM_JUG)
        !          1373:                    break;
        !          1374:        }
        !          1375:     }
        !          1376:     if (item == NULL)
        !          1377:       return 0;
        !          1378:     return i;
        !          1379: }
        !          1380:
        !          1381: /* Takes an alchemy jug number and tracks down the object. */
        !          1382: struct object *find_alchemy_jug(int n) {
        !          1383:     struct object *tobj;
        !          1384:     struct linked_list *item;
        !          1385:
        !          1386:     if (n <= 0) {
        !          1387:         return NULL;
        !          1388:     }
        !          1389:     else if (n < 32) {
        !          1390:         item = player.t_pack;
        !          1391:         n -= 1;
        !          1392:     }
        !          1393:     else if (n < 1024) {
        !          1394:         item = lvl_obj;
        !          1395:         n -= 32;
        !          1396:     }
        !          1397:     else {
        !          1398:         /* This is likely a bug, not 1024 actual items on the floor. */
        !          1399:         return NULL;
        !          1400:     }
        !          1401:     while (item != NULL && n > 0) {
        !          1402:         item = next(item);
        !          1403:         n--;
        !          1404:     }
        !          1405:     if (item == NULL)
        !          1406:         return NULL;
        !          1407:     tobj = OBJPTR(item);
        !          1408:     if (tobj->o_type != MM || tobj->o_which != MM_JUG)
        !          1409:         return NULL;
        !          1410:     return tobj;
        !          1411: }
        !          1412:
        !          1413: int
        !          1414: rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count)
        !          1415: {
        !          1416:     int i = 0;
        !          1417:     int func = 0;
        !          1418:
        !          1419:     if (write_error)
        !          1420:         return(WRITESTAT);
        !          1421:
        !          1422:     rs_write_marker(savef, RSID_DAEMONS);
        !          1423:     rs_write_int(savef, count);
        !          1424:
        !          1425:     for(i = 0; i < count; i++)
        !          1426:     {
        !          1427:         if ( d_list[i].d_func == rollwand)
        !          1428:             func = 1;
        !          1429:         else if ( d_list[i].d_func == doctor)
        !          1430:             func = 2;
        !          1431:         else if ( d_list[i].d_func == stomach)
        !          1432:             func = 3;
        !          1433:         else if ( d_list[i].d_func == runners)
        !          1434:             func = 4;
        !          1435:         else if ( d_list[i].d_func == swander)
        !          1436:             func = 5;
        !          1437:         else if ( d_list[i].d_func == trap_look)
        !          1438:             func = 6;
        !          1439:         else if ( d_list[i].d_func == ring_search)
        !          1440:             func = 7;
        !          1441:         else if ( d_list[i].d_func == ring_teleport)
        !          1442:             func = 8;
        !          1443:         else if ( d_list[i].d_func == strangle)
        !          1444:             func = 9;
        !          1445:         else if ( d_list[i].d_func == fumble)
        !          1446:             func = 10;
        !          1447:         else if ( d_list[i].d_func == wghtchk)
        !          1448:             func = 11;
        !          1449:         else if ( d_list[i].d_func == unstink)
        !          1450:             func = 12;
        !          1451:         else if ( d_list[i].d_func == res_strength)
        !          1452:             func = 13;
        !          1453:         else if ( d_list[i].d_func == un_itch)
        !          1454:             func = 14;
        !          1455:         else if ( d_list[i].d_func == cure_disease)
        !          1456:             func = 15;
        !          1457:         else if ( d_list[i].d_func == unconfuse)
        !          1458:             func = 16;
        !          1459:         else if ( d_list[i].d_func == suffocate)
        !          1460:             func = 17;
        !          1461:         else if ( d_list[i].d_func == undance)
        !          1462:             func = 18;
        !          1463:         else if ( d_list[i].d_func == alchemy)
        !          1464:             func = 19;
        !          1465:         else if ( d_list[i].d_func == dust_appear)
        !          1466:             func = 20;
        !          1467:         else if ( d_list[i].d_func == unchoke)
        !          1468:             func = 21;
        !          1469:         else if ( d_list[i].d_func == sight)
        !          1470:             func = 22;
        !          1471:         else if ( d_list[i].d_func == noslow)
        !          1472:             func = 23;
        !          1473:         else if ( d_list[i].d_func == nohaste)
        !          1474:             func = 24;
        !          1475:         else if ( d_list[i].d_func == unclrhead)
        !          1476:             func = 25;
        !          1477:         else if ( d_list[i].d_func == unsee)
        !          1478:             func = 26;
        !          1479:         else if ( d_list[i].d_func == unphase)
        !          1480:             func = 27;
        !          1481:         else if ( d_list[i].d_func == land)
        !          1482:             func = 28;
        !          1483:         else if ( d_list[i].d_func == appear)
        !          1484:             func = 29;
        !          1485:         else if (d_list[i].d_func == NULL)
        !          1486:             func = 0;
        !          1487:         else
        !          1488:             func = -1;
        !          1489:
        !          1490:         rs_write_int(savef, d_list[i].d_type);
        !          1491:         rs_write_int(savef, func);
        !          1492:         /* d_arg is a pointer and can't actually be saved and restored. */
        !          1493:         if (func == 19)
        !          1494:             rs_write_int(savef, number_alchemy_jug(d_list[i].d_arg));
        !          1495:         else
        !          1496:             rs_write_int(savef, 0);
        !          1497:         rs_write_int(savef, d_list[i].d_time);
        !          1498:     }
        !          1499:
        !          1500:     return(WRITESTAT);
        !          1501: }
        !          1502:
        !          1503: int
        !          1504: rs_read_daemons(FILE *inf, struct delayed_action *d_list, int count)
        !          1505: {
        !          1506:     int i = 0;
        !          1507:     int func = 0;
        !          1508:     int value = 0;
        !          1509:     int dummy = 0;
        !          1510:
        !          1511:     if (read_error || format_error)
        !          1512:         return(READSTAT);
        !          1513:
        !          1514:     rs_read_marker(inf, RSID_DAEMONS);
        !          1515:     rs_read_int(inf, &value);
        !          1516:
        !          1517:     if (value > count)
        !          1518:         format_error = TRUE;
        !          1519:
        !          1520:
        !          1521:     for(i=0; i < count; i++)
        !          1522:     {
        !          1523:        func = 0;
        !          1524:         rs_read_int(inf, &d_list[i].d_type);
        !          1525:         rs_read_int(inf, &func);
        !          1526:
        !          1527:         switch(func)
        !          1528:         {
        !          1529:            case  1: d_list[i].d_func = rollwand;
        !          1530:                     break;
        !          1531:             case  2: d_list[i].d_func = doctor;
        !          1532:                     break;
        !          1533:             case 3: d_list[i].d_func = stomach;
        !          1534:                     break;
        !          1535:             case  4: d_list[i].d_func = runners;
        !          1536:                      break;
        !          1537:             case  5: d_list[i].d_func = swander;
        !          1538:                      break;
        !          1539:             case  6: d_list[i].d_func = trap_look;
        !          1540:                      break;
        !          1541:             case  7: d_list[i].d_func = ring_search;
        !          1542:                      break;
        !          1543:             case  8: d_list[i].d_func = ring_teleport;
        !          1544:                      break;
        !          1545:             case  9: d_list[i].d_func = strangle;
        !          1546:                      break;
        !          1547:             case 10: d_list[i].d_func = fumble;
        !          1548:                      break;
        !          1549:             case 11: d_list[i].d_func = wghtchk;
        !          1550:                      break;
        !          1551:             case 12: d_list[i].d_func = unstink;
        !          1552:                      break;
        !          1553:             case 13: d_list[i].d_func = res_strength;
        !          1554:                      break;
        !          1555:             case 14: d_list[i].d_func = un_itch;
        !          1556:                      break;
        !          1557:             case 15: d_list[i].d_func = cure_disease;
        !          1558:                      break;
        !          1559:             case 16: d_list[i].d_func = unconfuse;
        !          1560:                      break;
        !          1561:             case 17: d_list[i].d_func = suffocate;
        !          1562:                      break;
        !          1563:             case 18: d_list[i].d_func = undance;
        !          1564:                      break;
        !          1565:             case 19: d_list[i].d_func = alchemy;
        !          1566:                      break;
        !          1567:             case 20: d_list[i].d_func = dust_appear;
        !          1568:                      break;
        !          1569:             case 21: d_list[i].d_func = unchoke;
        !          1570:                      break;
        !          1571:             case 22: d_list[i].d_func = sight;
        !          1572:                      break;
        !          1573:             case 23: d_list[i].d_func = noslow;
        !          1574:                      break;
        !          1575:             case 24: d_list[i].d_func = nohaste;
        !          1576:                      break;
        !          1577:             case 25: d_list[i].d_func = unclrhead;
        !          1578:                      break;
        !          1579:             case 26: d_list[i].d_func = unsee;
        !          1580:                      break;
        !          1581:             case 27: d_list[i].d_func = unphase;
        !          1582:                      break;
        !          1583:             case 28: d_list[i].d_func = land;
        !          1584:                      break;
        !          1585:             case 29: d_list[i].d_func = appear;
        !          1586:                      break;
        !          1587:            case  0:
        !          1588:             case -1:
        !          1589:             default: d_list[i].d_func = NULL;
        !          1590:                      break;
        !          1591:         }
        !          1592:
        !          1593:         /* Most functions don't use the argument. */
        !          1594:         rs_read_int(inf, &dummy);
        !          1595:         if (func == 2)
        !          1596:             d_list[i].d_arg = &player;
        !          1597:         else if (func == 19)
        !          1598:             d_list[i].d_arg = find_alchemy_jug(dummy);
        !          1599:         else
        !          1600:             d_list[i].d_arg = NULL;
        !          1601:
        !          1602:         rs_read_int(inf, &d_list[i].d_time);
        !          1603:
        !          1604:        if (d_list[i].d_func == NULL)
        !          1605:        {
        !          1606:            d_list[i].d_time = 0;
        !          1607:            d_list[i].d_type = 0;
        !          1608:        }
        !          1609:     }
        !          1610:
        !          1611:     return(READSTAT);
        !          1612: }
        !          1613:
        !          1614: int
        !          1615: rs_write_room(FILE *savef, struct room *r)
        !          1616: {
        !          1617:     struct linked_list *l;
        !          1618:     int i;
        !          1619:
        !          1620:     if (write_error)
        !          1621:         return(WRITESTAT);
        !          1622:
        !          1623:     rs_write_coord(savef, r->r_pos);
        !          1624:     rs_write_coord(savef, r->r_max);
        !          1625:     rs_write_long(savef, r->r_flags);
        !          1626:
        !          1627:     l = r->r_fires;
        !          1628:     i = list_size(l);
        !          1629:
        !          1630:     rs_write_int(savef, i);
        !          1631:
        !          1632:     if (i >0)
        !          1633:        while (l != NULL)
        !          1634:         {
        !          1635:            i = find_list_ptr(mlist, l->l_data);
        !          1636:             rs_write_int(savef,i);
        !          1637:             l = l->l_next;
        !          1638:         }
        !          1639:
        !          1640:     rs_write_coord_list(savef, r->r_exit);
        !          1641:
        !          1642:     return(WRITESTAT);
        !          1643: }
        !          1644:
        !          1645: int
        !          1646: rs_read_room(FILE *inf, struct room *r)
        !          1647: {
        !          1648:     int value = 0, n = 0, i = 0, index = 0, id = 0;
        !          1649:     struct linked_list *fires=NULL, *item = NULL;
        !          1650:
        !          1651:     if (read_error || format_error)
        !          1652:         return(READSTAT);
        !          1653:
        !          1654:     rs_read_coord(inf,&r->r_pos);
        !          1655:     rs_read_coord(inf,&r->r_max);
        !          1656:     rs_read_long(inf,&r->r_flags);
        !          1657:
        !          1658:     rs_read_int(inf, &i);
        !          1659:     fires = NULL;
        !          1660:
        !          1661:     while (i>0)
        !          1662:     {
        !          1663:        rs_read_int(inf,&index);
        !          1664:
        !          1665:         if (index >= 0)
        !          1666:         {
        !          1667:            void *data;
        !          1668:             data = get_list_item(mlist,index);
        !          1669:             item = creat_item();
        !          1670:             item->l_data = data;
        !          1671:             if (fires == NULL)
        !          1672:                fires = item;
        !          1673:             else
        !          1674:                attach(fires,item);
        !          1675:         }
        !          1676:         i--;
        !          1677:     }
        !          1678:
        !          1679:     r->r_fires=fires;
        !          1680:
        !          1681:     rs_read_coord_list(inf, &r->r_exit);
        !          1682:
        !          1683:     return(READSTAT);
        !          1684: }
        !          1685:
        !          1686: int
        !          1687: rs_write_rooms(FILE *savef, struct room r[], int count)
        !          1688: {
        !          1689:     int n = 0;
        !          1690:
        !          1691:     if (write_error)
        !          1692:         return(WRITESTAT);
        !          1693:
        !          1694:     rs_write_int(savef, count);
        !          1695:
        !          1696:     for(n = 0; n < count; n++)
        !          1697:         rs_write_room(savef, &r[n]);
        !          1698:
        !          1699:     return(WRITESTAT);
        !          1700: }
        !          1701:
        !          1702: int
        !          1703: rs_read_rooms(FILE *inf, struct room *r, int count)
        !          1704: {
        !          1705:     int value = 0, n = 0;
        !          1706:
        !          1707:     if (read_error || format_error)
        !          1708:         return(READSTAT);
        !          1709:
        !          1710:     rs_read_int(inf,&value);
        !          1711:
        !          1712:     if (value > count)
        !          1713:         format_error = TRUE;
        !          1714:
        !          1715:     for(n = 0; n < value; n++)
        !          1716:         rs_read_room(inf,&r[n]);
        !          1717:
        !          1718:     return(READSTAT);
        !          1719: }
        !          1720:
        !          1721: int
        !          1722: rs_write_room_reference(FILE *savef, struct room *rp)
        !          1723: {
        !          1724:     int i, room = -1;
        !          1725:
        !          1726:     if (write_error)
        !          1727:         return(WRITESTAT);
        !          1728:
        !          1729:     for (i = 0; i < MAXROOMS; i++)
        !          1730:         if (&rooms[i] == rp)
        !          1731:             room = i;
        !          1732:
        !          1733:     rs_write_int(savef, room);
        !          1734:
        !          1735:     return(WRITESTAT);
        !          1736: }
        !          1737:
        !          1738: int
        !          1739: rs_read_room_reference(FILE *inf, struct room **rp)
        !          1740: {
        !          1741:     int i;
        !          1742:
        !          1743:     if (read_error || format_error)
        !          1744:         return(READSTAT);
        !          1745:
        !          1746:     rs_read_int(inf, &i);
        !          1747:
        !          1748:     if (i >= 0 && i < MAXROOMS)
        !          1749:         *rp = &rooms[i];
        !          1750:     else
        !          1751:         *rp = NULL;
        !          1752:
        !          1753:     return(READSTAT);
        !          1754: }
        !          1755:
        !          1756: int
        !          1757: rs_write_door_reference(FILE *savef, coord *exit)
        !          1758: {
        !          1759:     int i, idx;
        !          1760:
        !          1761:     for (i = 0; i < MAXROOMS; i++)
        !          1762:     {
        !          1763:        idx = find_list_ptr(rooms[i].r_exit, exit);
        !          1764:
        !          1765:        if (idx != -1)
        !          1766:            break;
        !          1767:     }
        !          1768:
        !          1769:     if (i >= MAXROOMS)
        !          1770:     {
        !          1771:         rs_write_int(savef,-1);
        !          1772:        rs_write_int(savef,-1);
        !          1773:        if (exit != NULL)
        !          1774:            abort();
        !          1775:     }
        !          1776:     else
        !          1777:     {
        !          1778:        rs_write_int(savef,i);
        !          1779:        rs_write_int(savef,idx);
        !          1780:     }
        !          1781:
        !          1782:     return(WRITESTAT);
        !          1783: }
        !          1784:
        !          1785: int
        !          1786: rs_read_door_reference(FILE *inf, coord **exit)
        !          1787: {
        !          1788:     int i, idx;
        !          1789:
        !          1790:     rs_read_int(inf, &i);
        !          1791:     rs_read_int(inf, &idx);
        !          1792:
        !          1793:     if ( (i == -1) || (idx == -1) )
        !          1794:        *exit = NULL;
        !          1795:     else
        !          1796:        *exit = get_list_item(rooms[i].r_exit, idx);
        !          1797:
        !          1798:     return(READSTAT);
        !          1799: }
        !          1800:
        !          1801: int
        !          1802: rs_write_traps(FILE *savef, struct trap *trap,int count)
        !          1803: {
        !          1804:     int n;
        !          1805:
        !          1806:     rs_write_int(savef, RSID_TRAP);
        !          1807:     rs_write_int(savef, count);
        !          1808:
        !          1809:     for(n=0; n<count; n++)
        !          1810:     {
        !          1811:         rs_write_char(savef, trap[n].tr_type);
        !          1812:         rs_write_char(savef, trap[n].tr_show);
        !          1813:         rs_write_coord(savef, trap[n].tr_pos);
        !          1814:         rs_write_long(savef, trap[n].tr_flags);
        !          1815:     }
        !          1816:
        !          1817:     return (WRITESTAT);
        !          1818: }
        !          1819:
        !          1820: int
        !          1821: rs_read_traps(FILE *inf, struct trap *trap, int count)
        !          1822: {
        !          1823:     int id = 0, value = 0, n = 0;
        !          1824:
        !          1825:     if (rs_read_int(inf,&id) != 0)
        !          1826:         format_error = TRUE;
        !          1827:     else if (rs_read_int(inf,&value) != 0)
        !          1828:     {
        !          1829:         if (value != count)
        !          1830:            format_error = TRUE;
        !          1831:     }
        !          1832:     else
        !          1833:     {
        !          1834:        for(n=0;n<value;n++)
        !          1835:         {
        !          1836:            rs_read_char(inf,&trap[n].tr_type);
        !          1837:             rs_read_char(inf,&trap[n].tr_show);
        !          1838:             rs_read_coord(inf,&trap[n].tr_pos);
        !          1839:             rs_read_long(inf,&trap[n].tr_flags);
        !          1840:        }
        !          1841:     }
        !          1842:
        !          1843:     return(READSTAT);
        !          1844: }
        !          1845:
        !          1846: int
        !          1847: rs_write_monsters(FILE *savef, struct monster *m, int count)
        !          1848: {
        !          1849:     int n;
        !          1850:
        !          1851:     if (write_error)
        !          1852:         return(WRITESTAT);
        !          1853:
        !          1854:     rs_write_marker(savef, RSID_MONSTERS);
        !          1855:     rs_write_int(savef, count);
        !          1856:
        !          1857:     for(n=0;n<count;n++)
        !          1858:     {
        !          1859:         rs_write_boolean(savef, m[n].m_normal);
        !          1860:         rs_write_boolean(savef, m[n].m_wander);
        !          1861:         rs_write_short(savef, m[n].m_numsum);
        !          1862:     }
        !          1863:
        !          1864:     return(WRITESTAT);
        !          1865: }
        !          1866:
        !          1867: int
        !          1868: rs_read_monsters(FILE *inf, struct monster *m, int count)
        !          1869: {
        !          1870:     int value = 0, n = 0;
        !          1871:
        !          1872:     if (read_error || format_error)
        !          1873:         return(READSTAT);
        !          1874:
        !          1875:     rs_read_marker(inf, RSID_MONSTERS);
        !          1876:
        !          1877:     rs_read_int(inf, &value);
        !          1878:
        !          1879:     if (value != count)
        !          1880:         format_error = TRUE;
        !          1881:
        !          1882:     for(n = 0; n < count; n++)
        !          1883:     {
        !          1884:         rs_read_boolean(inf, &m[n].m_normal);
        !          1885:         rs_read_boolean(inf, &m[n].m_wander);
        !          1886:        rs_read_short(inf, &m[n].m_numsum);
        !          1887:     }
        !          1888:
        !          1889:     return(READSTAT);
        !          1890: }
        !          1891:
        !          1892: int
        !          1893: rs_write_object(FILE *savef, struct object *o)
        !          1894: {
        !          1895:     if (write_error)
        !          1896:         return(WRITESTAT);
        !          1897:
        !          1898:     rs_write_marker(savef, RSID_OBJECT);
        !          1899:     rs_write_int(savef, o->o_type);
        !          1900:     rs_write_coord(savef, o->o_pos);
        !          1901:     rs_write_char(savef, o->o_launch);
        !          1902:     rs_write(savef, o->o_damage, sizeof(o->o_damage));
        !          1903:     rs_write(savef, o->o_hurldmg, sizeof(o->o_hurldmg));
        !          1904:     rs_write_object_list(savef, o->contents);
        !          1905:     rs_write_int(savef, o->o_count);
        !          1906:     rs_write_int(savef, o->o_which);
        !          1907:     rs_write_int(savef, o->o_hplus);
        !          1908:     rs_write_int(savef, o->o_dplus);
        !          1909:     rs_write_int(savef, o->o_ac);
        !          1910:     rs_write_long(savef, o->o_flags);
        !          1911:     rs_write_int(savef, o->o_group);
        !          1912:     rs_write_int(savef, o->o_weight);
        !          1913:     rs_write(savef, o->o_mark, MARKLEN);
        !          1914:
        !          1915:
        !          1916:     return(WRITESTAT);
        !          1917: }
        !          1918:
        !          1919: int
        !          1920: rs_read_object(FILE *inf, struct object *o)
        !          1921: {
        !          1922:     if (read_error || format_error)
        !          1923:         return(READSTAT);
        !          1924:
        !          1925:     rs_read_marker(inf, RSID_OBJECT);
        !          1926:     rs_read_int(inf, &o->o_type);
        !          1927:     rs_read_coord(inf, &o->o_pos);
        !          1928:     rs_read_char(inf, &o->o_launch);
        !          1929:     rs_read(inf, o->o_damage, sizeof(o->o_damage));
        !          1930:     rs_read(inf, o->o_hurldmg, sizeof(o->o_hurldmg));
        !          1931:     rs_read_object_list(inf,&o->contents);
        !          1932:     rs_read_int(inf, &o->o_count);
        !          1933:     rs_read_int(inf, &o->o_which);
        !          1934:     rs_read_int(inf, &o->o_hplus);
        !          1935:     rs_read_int(inf, &o->o_dplus);
        !          1936:     rs_read_int(inf, &o->o_ac);
        !          1937:     rs_read_long(inf,&o->o_flags);
        !          1938:     rs_read_int(inf, &o->o_group);
        !          1939:     rs_read_int(inf, &o->o_weight);
        !          1940:     rs_read(inf, o->o_mark, MARKLEN);
        !          1941:
        !          1942:     return(READSTAT);
        !          1943: }
        !          1944:
        !          1945: int
        !          1946: rs_write_object_list(FILE *savef, struct linked_list *l)
        !          1947: {
        !          1948:     if (write_error)
        !          1949:         return(WRITESTAT);
        !          1950:
        !          1951:     rs_write_marker(savef, RSID_OBJECTLIST);
        !          1952:     rs_write_int(savef, list_size(l));
        !          1953:
        !          1954:     for( ;l != NULL; l = l->l_next)
        !          1955:         rs_write_object(savef, OBJPTR(l));
        !          1956:
        !          1957:     return(WRITESTAT);
        !          1958: }
        !          1959:
        !          1960: int
        !          1961: rs_read_object_list(FILE *inf, struct linked_list **list)
        !          1962: {
        !          1963:     int i, cnt;
        !          1964:     struct linked_list *l = NULL, *previous = NULL, *head = NULL;
        !          1965:
        !          1966:     if (read_error || format_error)
        !          1967:         return(READSTAT);
        !          1968:
        !          1969:     rs_read_marker(inf, RSID_OBJECTLIST);
        !          1970:     rs_read_int(inf, &cnt);
        !          1971:
        !          1972:     for (i = 0; i < cnt; i++)
        !          1973:     {
        !          1974:         l = new_item(sizeof(struct object));
        !          1975:
        !          1976:        l->l_prev = previous;
        !          1977:
        !          1978:         if (previous != NULL)
        !          1979:             previous->l_next = l;
        !          1980:
        !          1981:         rs_read_object(inf,OBJPTR(l));
        !          1982:
        !          1983:         if (previous == NULL)
        !          1984:             head = l;
        !          1985:
        !          1986:         previous = l;
        !          1987:     }
        !          1988:
        !          1989:     if (l != NULL)
        !          1990:         l->l_next = NULL;
        !          1991:
        !          1992:     *list = head;
        !          1993:
        !          1994:     return(READSTAT);
        !          1995: }
        !          1996:
        !          1997: int
        !          1998: rs_write_object_reference(FILE *savef, struct linked_list *list, struct object *item)
        !          1999: {
        !          2000:     int i;
        !          2001:
        !          2002:     if (write_error)
        !          2003:         return(WRITESTAT);
        !          2004:
        !          2005:     i = find_list_ptr(list, item);
        !          2006:
        !          2007:     rs_write_int(savef, i);
        !          2008:
        !          2009:     return(WRITESTAT);
        !          2010: }
        !          2011:
        !          2012: int
        !          2013: rs_read_object_reference(FILE *inf, struct linked_list *list, struct object **item)
        !          2014: {
        !          2015:     int i;
        !          2016:
        !          2017:     if (read_error || format_error)
        !          2018:         return(READSTAT);
        !          2019:
        !          2020:     rs_read_int(inf, &i);
        !          2021:
        !          2022:     *item = get_list_item(list,i);
        !          2023:
        !          2024:     return(READSTAT);
        !          2025: }
        !          2026:
        !          2027: int
        !          2028: find_thing_coord(struct linked_list *monlist, coord *c)
        !          2029: {
        !          2030:     struct linked_list *mitem;
        !          2031:     struct thing *tp;
        !          2032:     int i = 0;
        !          2033:
        !          2034:     for(mitem = monlist; mitem != NULL; mitem = mitem->l_next)
        !          2035:     {
        !          2036:         tp = THINGPTR(mitem);
        !          2037:
        !          2038:         if (c == &tp->t_pos)
        !          2039:             return(i);
        !          2040:
        !          2041:         i++;
        !          2042:     }
        !          2043:
        !          2044:     return(-1);
        !          2045: }
        !          2046:
        !          2047: int
        !          2048: find_object_coord(struct linked_list *objlist, coord *c)
        !          2049: {
        !          2050:     struct linked_list *oitem;
        !          2051:     struct object *obj;
        !          2052:     int i = 0;
        !          2053:
        !          2054:     for(oitem = objlist; oitem != NULL; oitem = oitem->l_next)
        !          2055:     {
        !          2056:         obj = OBJPTR(oitem);
        !          2057:
        !          2058:         if (c == &obj->o_pos)
        !          2059:             return(i);
        !          2060:
        !          2061:         i++;
        !          2062:     }
        !          2063:
        !          2064:     return(-1);
        !          2065: }
        !          2066:
        !          2067: int
        !          2068: rs_write_thing(FILE *savef, struct thing *t)
        !          2069: {
        !          2070:     int i = -1;
        !          2071:
        !          2072:     if (write_error)
        !          2073:         return(WRITESTAT);
        !          2074:
        !          2075:     rs_write_marker(savef, RSID_THING);
        !          2076:
        !          2077:     if (t == NULL)
        !          2078:     {
        !          2079:         rs_write_int(savef, 0);
        !          2080:         return(WRITESTAT);
        !          2081:     }
        !          2082:
        !          2083:     rs_write_int(savef, 1);
        !          2084:
        !          2085:     rs_write_boolean(savef, t->t_turn);
        !          2086:     rs_write_boolean(savef, t->t_wasshot);
        !          2087:     rs_write_char(savef, t->t_type);
        !          2088:     rs_write_char(savef, t->t_disguise);
        !          2089:     rs_write_char(savef, t->t_oldch);
        !          2090:
        !          2091:     rs_write_short(savef, t->t_ctype);
        !          2092:     rs_write_short(savef, t->t_index);
        !          2093:     rs_write_short(savef, t->t_no_move);
        !          2094:     rs_write_short(savef, t->t_quiet);
        !          2095:
        !          2096:     rs_write_door_reference(savef, t->t_doorgoal);
        !          2097:
        !          2098:     rs_write_coord(savef, t->t_pos);
        !          2099:     rs_write_coord(savef, t->t_oldpos);
        !          2100:
        !          2101:     /*
        !          2102:         t_dest can be:
        !          2103:         0,0: NULL
        !          2104:         0,1: location of hero
        !          2105:         0,3: global coord 'delta'
        !          2106:         1,i: location of a thing (monster)
        !          2107:         2,i: location of an object
        !          2108:         3,i: location of gold in a room
        !          2109:
        !          2110:         We need to remember what we are chasing rather than
        !          2111:         the current location of what we are chasing.
        !          2112:     */
        !          2113:
        !          2114:     if (t->t_dest == &hero)
        !          2115:     {
        !          2116:         rs_write_int(savef,0);
        !          2117:         rs_write_int(savef,1);
        !          2118:     }
        !          2119:     else if (t->t_dest != NULL)
        !          2120:     {
        !          2121:         i = find_thing_coord(mlist, t->t_dest);
        !          2122:
        !          2123:         if (i >=0 )
        !          2124:         {
        !          2125:             rs_write_int(savef,1);
        !          2126:             rs_write_int(savef,i);
        !          2127:         }
        !          2128:         else
        !          2129:         {
        !          2130:             i = find_object_coord(lvl_obj, t->t_dest);
        !          2131:
        !          2132:             if (i >= 0)
        !          2133:             {
        !          2134:                 rs_write_int(savef,2);
        !          2135:                 rs_write_int(savef,i);
        !          2136:             }
        !          2137:             else
        !          2138:             {
        !          2139:                 rs_write_int(savef, 0);
        !          2140:                 rs_write_int(savef,1); /* chase the hero anyway */
        !          2141:             }
        !          2142:         }
        !          2143:     }
        !          2144:     else
        !          2145:     {
        !          2146:         rs_write_int(savef,0);
        !          2147:         rs_write_int(savef,0);
        !          2148:     }
        !          2149:
        !          2150:     rs_write_ulongs(savef, t->t_flags, 16);
        !          2151:     rs_write_object_list(savef, t->t_pack);
        !          2152:     rs_write_stats(savef, &t->t_stats);
        !          2153:     rs_write_stats(savef, &t->maxstats);
        !          2154:
        !          2155:     return(WRITESTAT);
        !          2156: }
        !          2157:
        !          2158: int
        !          2159: rs_read_thing(FILE *inf, struct thing *t)
        !          2160: {
        !          2161:     int listid = 0, index = -1;
        !          2162:
        !          2163:     if (read_error || format_error)
        !          2164:         return(READSTAT);
        !          2165:
        !          2166:     rs_read_marker(inf, RSID_THING);
        !          2167:
        !          2168:     rs_read_int(inf, &index);
        !          2169:
        !          2170:     if (index == 0)
        !          2171:         return(READSTAT);
        !          2172:
        !          2173:     rs_read_boolean(inf, &t->t_turn);
        !          2174:     rs_read_boolean(inf, &t->t_wasshot);
        !          2175:     rs_read_char(inf, &t->t_type);
        !          2176:     rs_read_char(inf, &t->t_disguise);
        !          2177:     rs_read_char(inf, &t->t_oldch);
        !          2178:     rs_read_short(inf, &t->t_ctype);
        !          2179:     rs_read_short(inf, &t->t_index);
        !          2180:     rs_read_short(inf, &t->t_no_move);
        !          2181:     rs_read_short(inf, &t->t_quiet);
        !          2182:     rs_read_door_reference(inf,&t->t_doorgoal);
        !          2183:     rs_read_coord(inf, &t->t_pos);
        !          2184:     rs_read_coord(inf, &t->t_oldpos);
        !          2185:
        !          2186:     /*
        !          2187:        t_dest can be (listid,index):
        !          2188:            0,0: NULL
        !          2189:             0,1: location of hero
        !          2190:             1,i: location of a thing (monster)
        !          2191:             2,i: location of an object
        !          2192:             3,i: location of gold in a room
        !          2193:
        !          2194:        We need to remember what we are chasing rather than
        !          2195:         the current location of what we are chasing.
        !          2196:     */
        !          2197:
        !          2198:     rs_read_int(inf, &listid);
        !          2199:     rs_read_int(inf, &index);
        !          2200:     t->t_reserved = -1;
        !          2201:
        !          2202:     if (listid == 0) /* hero or NULL */
        !          2203:     {
        !          2204:        if (index == 1)
        !          2205:            t->t_dest = &hero;
        !          2206:         else
        !          2207:            t->t_dest = NULL;
        !          2208:     }
        !          2209:     else if (listid == 1) /* monster/thing */
        !          2210:     {
        !          2211:        t->t_dest     = NULL;
        !          2212:         t->t_reserved = index;
        !          2213:     }
        !          2214:     else if (listid == 2) /* object */
        !          2215:     {
        !          2216:        struct object *obj;
        !          2217:
        !          2218:         obj = get_list_item(lvl_obj, index);
        !          2219:
        !          2220:         if (obj != NULL)
        !          2221:         {
        !          2222:             t->t_dest = &obj->o_pos;
        !          2223:         }
        !          2224:     }
        !          2225:     else
        !          2226:        t->t_dest = NULL;
        !          2227:
        !          2228:     rs_read_ulongs(inf, t->t_flags, 16);
        !          2229:     rs_read_object_list(inf, &t->t_pack);
        !          2230:     rs_read_stats(inf, &t->t_stats);
        !          2231:     rs_read_stats(inf, &t->maxstats);
        !          2232:
        !          2233:     return(READSTAT);
        !          2234: }
        !          2235:
        !          2236: void
        !          2237: rs_fix_thing(struct thing *t)
        !          2238: {
        !          2239:     struct thing *tp;
        !          2240:
        !          2241:     if (t->t_reserved < 0)
        !          2242:         return;
        !          2243:
        !          2244:     tp = get_list_item(mlist,t->t_reserved);
        !          2245:
        !          2246:     if (tp != NULL)
        !          2247:     {
        !          2248:         t->t_dest = &tp->t_pos;
        !          2249:     }
        !          2250: }
        !          2251:
        !          2252: int
        !          2253: rs_write_thing_list(FILE *savef, struct linked_list *l)
        !          2254: {
        !          2255:     int cnt = 0;
        !          2256:
        !          2257:     if (write_error)
        !          2258:         return(WRITESTAT);
        !          2259:
        !          2260:     rs_write_marker(savef, RSID_MONSTERLIST);
        !          2261:
        !          2262:     cnt = list_size(l);
        !          2263:
        !          2264:     rs_write_int(savef, cnt);
        !          2265:
        !          2266:     if (cnt < 1)
        !          2267:         return(WRITESTAT);
        !          2268:
        !          2269:     while (l != NULL) {
        !          2270:         rs_write_thing(savef, (struct thing *)l->l_data);
        !          2271:         l = l->l_next;
        !          2272:     }
        !          2273:
        !          2274:     return(WRITESTAT);
        !          2275: }
        !          2276:
        !          2277: int
        !          2278: rs_read_thing_list(FILE *inf, struct linked_list **list)
        !          2279: {
        !          2280:     int i, cnt;
        !          2281:     struct linked_list *l = NULL, *previous = NULL, *head = NULL;
        !          2282:
        !          2283:     if (read_error || format_error)
        !          2284:         return(READSTAT);
        !          2285:
        !          2286:     rs_read_marker(inf, RSID_MONSTERLIST);
        !          2287:
        !          2288:     rs_read_int(inf, &cnt);
        !          2289:
        !          2290:     for (i = 0; i < cnt; i++)
        !          2291:     {
        !          2292:         l = new_item(sizeof(struct thing));
        !          2293:
        !          2294:         l->l_prev = previous;
        !          2295:
        !          2296:         if (previous != NULL)
        !          2297:             previous->l_next = l;
        !          2298:
        !          2299:         rs_read_thing(inf,THINGPTR(l));
        !          2300:
        !          2301:         if (previous == NULL)
        !          2302:             head = l;
        !          2303:
        !          2304:         previous = l;
        !          2305:     }
        !          2306:
        !          2307:     if (l != NULL)
        !          2308:         l->l_next = NULL;
        !          2309:
        !          2310:     *list = head;
        !          2311:
        !          2312:     return(READSTAT);
        !          2313: }
        !          2314:
        !          2315: void
        !          2316: rs_fix_thing_list(struct linked_list *list)
        !          2317: {
        !          2318:     struct linked_list *item;
        !          2319:
        !          2320:     for(item = list; item != NULL; item = item->l_next)
        !          2321:         rs_fix_thing(THINGPTR(item));
        !          2322: }
        !          2323:
        !          2324: int
        !          2325: rs_save_file(FILE *savef)
        !          2326: {
        !          2327:     int i;
        !          2328:
        !          2329:     if (write_error)
        !          2330:         return(WRITESTAT);
        !          2331:
        !          2332:     rs_write_object_list(savef, lvl_obj);
        !          2333:     rs_write_thing(savef, &player);
        !          2334:     rs_write_thing_list(savef, mlist);
        !          2335:     rs_write_thing_list(savef, tlist);
        !          2336:     rs_write_thing_list(savef, monst_dead);
        !          2337:
        !          2338:     rs_write_traps(savef, traps, MAXTRAPS);
        !          2339:     rs_write_rooms(savef, rooms, MAXROOMS);
        !          2340:     rs_write_room_reference(savef, oldrp);
        !          2341:
        !          2342:     rs_write_object_reference(savef, player.t_pack, cur_armor);
        !          2343:
        !          2344:     for(i = 0; i < NUM_FINGERS; i++)
        !          2345:         rs_write_object_reference(savef, player.t_pack, cur_ring[i]);
        !          2346:
        !          2347:     for(i = 0; i < NUM_MM; i++)
        !          2348:         rs_write_object_reference(savef, player.t_pack, cur_misc[i]);
        !          2349:
        !          2350:     rs_write_ints(savef, cur_relic, MAXRELIC);
        !          2351:
        !          2352:     rs_write_object_reference(savef, player.t_pack, cur_weapon);
        !          2353:
        !          2354:     rs_write_int(savef, char_type);
        !          2355:     rs_write_int(savef, foodlev);
        !          2356:     rs_write_int(savef, ntraps);
        !          2357:     rs_write_int(savef, trader);
        !          2358:     rs_write_int(savef, curprice);
        !          2359:     rs_write_int(savef, no_move);
        !          2360:     rs_write_int(savef, seed);
        !          2361:     rs_write_int(savef, dnum);
        !          2362:     rs_write_int(savef, max_level);
        !          2363:     rs_write_int(savef, cur_max);
        !          2364:     rs_write_int(savef, lost_dext);
        !          2365:     rs_write_int(savef, no_command);
        !          2366:     rs_write_int(savef, level);
        !          2367:     rs_write_int(savef, purse);
        !          2368:     rs_write_int(savef, inpack);
        !          2369:     rs_write_int(savef, total);
        !          2370:     rs_write_int(savef, no_food);
        !          2371:     rs_write_int(savef, foods_this_level);
        !          2372:     rs_write_int(savef, count);
        !          2373:     rs_write_int(savef, food_left);
        !          2374:     rs_write_int(savef, group);
        !          2375:     rs_write_int(savef, hungry_state);
        !          2376:     rs_write_int(savef, infest_dam);
        !          2377:     rs_write_int(savef, lost_str);
        !          2378:     rs_write_int(savef, lastscore);
        !          2379:     rs_write_int(savef, hold_count);
        !          2380:     rs_write_int(savef, trap_tries);
        !          2381:     rs_write_int(savef, pray_time);
        !          2382:     rs_write_int(savef, spell_power);
        !          2383:     rs_write_int(savef, turns);
        !          2384:     rs_write_int(savef, quest_item);
        !          2385:     rs_write_char(savef, nfloors);
        !          2386:     rs_write(savef, curpurch, LINELEN*2);
        !          2387:     rs_write_char(savef, PLAYER);
        !          2388:     rs_write_char(savef, take);
        !          2389:     rs_write(savef, prbuf, LINELEN);
        !          2390:     rs_write_char(savef, runch);
        !          2391:     rs_write(savef, whoami, LINELEN);
        !          2392:     rs_write(savef, fruit, LINELEN);
        !          2393:     rs_write_scrolls(savef);
        !          2394:     rs_write_potions(savef);
        !          2395:     rs_write_rings(savef);
        !          2396:     rs_write_sticks(savef);
        !          2397:     for(i = 0; i < MAXMM; i++)
        !          2398:         rs_write_string(savef, m_guess[i]);
        !          2399:     rs_write_window(savef, cw);
        !          2400:     rs_write_window(savef, mw);
        !          2401:     rs_write_window(savef, stdscr);
        !          2402:     rs_write_boolean(savef, pool_teleport);
        !          2403:     rs_write_boolean(savef, inwhgt);
        !          2404:     rs_write_boolean(savef, after);
        !          2405:     rs_write_boolean(savef, waswizard);
        !          2406:     rs_write_booleans(savef, m_know, MAXMM);
        !          2407:     rs_write_boolean(savef, playing);
        !          2408:     rs_write_boolean(savef, running);
        !          2409:     rs_write_boolean(savef, wizard);
        !          2410:     rs_write_boolean(savef, notify);
        !          2411:     rs_write_boolean(savef, fight_flush);
        !          2412:     rs_write_boolean(savef, terse);
        !          2413:     rs_write_boolean(savef, auto_pickup);
        !          2414:     rs_write_boolean(savef, door_stop);
        !          2415:     rs_write_boolean(savef, jump);
        !          2416:     rs_write_boolean(savef, slow_invent);
        !          2417:     rs_write_boolean(savef, firstmove);
        !          2418:     rs_write_boolean(savef, askme);
        !          2419:     rs_write_boolean(savef, in_shell);
        !          2420:     rs_write_boolean(savef, daytime);
        !          2421:     rs_write_coord(savef, delta);
        !          2422:     rs_write_levtype(savef, levtype);
        !          2423:
        !          2424:     rs_write_monsters(savef, monsters, NUMMONST+1);
        !          2425:
        !          2426:     rs_write_magic_items(savef, things, NUMTHINGS);
        !          2427:     rs_write_magic_items(savef, s_magic, MAXSCROLLS);
        !          2428:     rs_write_magic_items(savef, p_magic, MAXPOTIONS);
        !          2429:     rs_write_magic_items(savef, r_magic, MAXRINGS);
        !          2430:     rs_write_magic_items(savef, ws_magic, MAXSTICKS);
        !          2431:     rs_write_magic_items(savef, m_magic, MAXMM);
        !          2432:
        !          2433:
        !          2434:     rs_write_coord(savef, ch_ret);
        !          2435:     rs_write_int(savef, demoncnt);
        !          2436:     rs_write_int(savef, fusecnt);
        !          2437:     rs_write_daemons(savef, d_list, MAXDAEMONS);
        !          2438:     rs_write_daemons(savef, f_list, MAXFUSES);
        !          2439:     rs_write_int(savef, between);
        !          2440:
        !          2441:     fflush(savef);
        !          2442:
        !          2443:     return(WRITESTAT);
        !          2444: }
        !          2445:
        !          2446: int
        !          2447: rs_restore_file(FILE *inf)
        !          2448: {
        !          2449:     int i;
        !          2450:
        !          2451:     if (read_error || format_error)
        !          2452:         return(READSTAT);
        !          2453:
        !          2454:     rs_read_object_list(inf, &lvl_obj);
        !          2455:     rs_read_thing(inf, &player);
        !          2456:     rs_read_thing_list(inf, &mlist);
        !          2457:     rs_read_thing_list(inf, &tlist);
        !          2458:     rs_read_thing_list(inf, &monst_dead);
        !          2459:
        !          2460:     rs_fix_thing(&player);
        !          2461:     rs_fix_thing_list(mlist);
        !          2462:     rs_fix_thing_list(tlist);
        !          2463:     rs_fix_thing_list(monst_dead);
        !          2464:
        !          2465:     rs_read_traps(inf, traps, MAXTRAPS);
        !          2466:     rs_read_rooms(inf, rooms, MAXROOMS);
        !          2467:     rs_read_room_reference(inf, &oldrp);
        !          2468:
        !          2469:     rs_read_object_reference(inf, player.t_pack, &cur_armor);
        !          2470:
        !          2471:     for(i = 0; i < NUM_FINGERS; i++)
        !          2472:         rs_read_object_reference(inf, player.t_pack, &cur_ring[i]);
        !          2473:
        !          2474:     for(i = 0; i < NUM_MM; i++)
        !          2475:         rs_read_object_reference(inf, player.t_pack, &cur_misc[i]);
        !          2476:
        !          2477:     rs_read_ints(inf, cur_relic, MAXRELIC);
        !          2478:
        !          2479:     rs_read_object_reference(inf, player.t_pack, &cur_weapon);
        !          2480:
        !          2481:     rs_read_int(inf, &char_type);
        !          2482:     rs_read_int(inf, &foodlev);
        !          2483:     rs_read_int(inf, &ntraps);
        !          2484:     rs_read_int(inf, &trader);
        !          2485:     rs_read_int(inf, &curprice);
        !          2486:     rs_read_int(inf, &no_move);
        !          2487:     rs_read_int(inf, &seed);
        !          2488:     rs_read_int(inf, &dnum);
        !          2489:     rs_read_int(inf, &max_level);
        !          2490:     rs_read_int(inf, &cur_max);
        !          2491:     rs_read_int(inf, &lost_dext);
        !          2492:     rs_read_int(inf, &no_command);
        !          2493:     rs_read_int(inf, &level);
        !          2494:     rs_read_int(inf, &purse);
        !          2495:     rs_read_int(inf, &inpack);
        !          2496:     rs_read_int(inf, &total);
        !          2497:     rs_read_int(inf, &no_food);
        !          2498:     rs_read_int(inf, &foods_this_level);
        !          2499:     rs_read_int(inf, &count);
        !          2500:     rs_read_int(inf, &food_left);
        !          2501:     rs_read_int(inf, &group);
        !          2502:     rs_read_int(inf, &hungry_state);
        !          2503:     rs_read_int(inf, &infest_dam);
        !          2504:     rs_read_int(inf, &lost_str);
        !          2505:     rs_read_int(inf, &lastscore);
        !          2506:     rs_read_int(inf, &hold_count);
        !          2507:     rs_read_int(inf, &trap_tries);
        !          2508:     rs_read_int(inf, &pray_time);
        !          2509:     rs_read_int(inf, &spell_power);
        !          2510:     rs_read_int(inf, &turns);
        !          2511:     rs_read_int(inf, &quest_item);
        !          2512:     rs_read_char(inf, &nfloors);
        !          2513:     rs_read(inf, &curpurch, LINELEN*2);
        !          2514:     rs_read_char(inf, &PLAYER);
        !          2515:     rs_read_char(inf, &take);
        !          2516:     rs_read(inf, &prbuf, LINELEN);
        !          2517:     rs_read_char(inf, &runch);
        !          2518:     rs_read(inf, &whoami, LINELEN);
        !          2519:     rs_read(inf, &fruit, LINELEN);
        !          2520:     rs_read_scrolls(inf);
        !          2521:     rs_read_potions(inf);
        !          2522:     rs_read_rings(inf);
        !          2523:     rs_read_sticks(inf);
        !          2524:     for(i = 0; i < MAXMM; i++)
        !          2525:         rs_read_new_string(inf, &m_guess[i]);
        !          2526:     rs_read_window(inf, cw);
        !          2527:     rs_read_window(inf, mw);
        !          2528:     rs_read_window(inf, stdscr);
        !          2529:     rs_read_boolean(inf, &pool_teleport);
        !          2530:     rs_read_boolean(inf, &inwhgt);
        !          2531:     rs_read_boolean(inf, &after);
        !          2532:     rs_read_boolean(inf, &waswizard);
        !          2533:     rs_read_booleans(inf, m_know, MAXMM);
        !          2534:     rs_read_boolean(inf, &playing);
        !          2535:     rs_read_boolean(inf, &running);
        !          2536:     rs_read_boolean(inf, &wizard);
        !          2537:     rs_read_boolean(inf, &notify);
        !          2538:     rs_read_boolean(inf, &fight_flush);
        !          2539:     rs_read_boolean(inf, &terse);
        !          2540:     rs_read_boolean(inf, &auto_pickup);
        !          2541:     rs_read_boolean(inf, &door_stop);
        !          2542:     rs_read_boolean(inf, &jump);
        !          2543:     rs_read_boolean(inf, &slow_invent);
        !          2544:     rs_read_boolean(inf, &firstmove);
        !          2545:     rs_read_boolean(inf, &askme);
        !          2546:     rs_read_boolean(inf, &in_shell);
        !          2547:     rs_read_boolean(inf, &daytime);
        !          2548:     rs_read_coord(inf, &delta);
        !          2549:     rs_read_levtype(inf, &levtype);
        !          2550:
        !          2551:     rs_read_monsters(inf, monsters, NUMMONST+1);
        !          2552:
        !          2553:     rs_read_magic_items(inf, things, NUMTHINGS);
        !          2554:     rs_read_magic_items(inf, s_magic, MAXSCROLLS);
        !          2555:     rs_read_magic_items(inf, p_magic, MAXPOTIONS);
        !          2556:     rs_read_magic_items(inf, r_magic, MAXRINGS);
        !          2557:     rs_read_magic_items(inf, ws_magic, MAXSTICKS);
        !          2558:     rs_read_magic_items(inf, m_magic, MAXMM);
        !          2559:
        !          2560:     rs_read_coord(inf, &ch_ret);
        !          2561:     rs_read_int(inf, &demoncnt);
        !          2562:     rs_read_int(inf, &fusecnt);
        !          2563:     rs_read_daemons(inf, d_list, MAXDAEMONS);
        !          2564:     rs_read_daemons(inf, f_list, MAXFUSES);
        !          2565:     rs_read_int(inf, &between);
        !          2566:
        !          2567:     return(READSTAT);
        !          2568: }

CVSweb