[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

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