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

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

CVSweb