source: abuse/trunk/src/lcache.cpp @ 494

Last change on this file since 494 was 494, checked in by Sam Hocevar, 12 years ago

style: remove trailing spaces, fix copyright statements.

File size: 3.2 KB
RevLine 
[56]1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
[494]4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
[56]5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com or
8 *  Jonathan Clark.
9 */
10
11#include "config.h"
12
[481]13#include "lisp.h"
14#include "specs.h"
15#include "bus_type.h"
[2]16
17long block_size(Cell *level)  // return size needed to recreate this block
18{
19  int ret;
20  if (!level) ret=0;    // NULL pointers don't need to be stored
[124]21  else
[2]22  {
23    int type=item_type(level);
24    if (type==L_CONS_CELL)
25    {
[124]26    long t=0;
27    void *b=level;
[494]28    for (; b && item_type(b)==L_CONS_CELL; b=CDR(b))
[124]29    {
[492]30      t+=sizeof(LList);
[124]31    }
32    if (b) t+=block_size(b);
[494]33    for (b=level; b && item_type(b)==L_CONS_CELL; b=CDR(b))
[124]34      t+=block_size(CAR(b));
35    ret=t;
[2]36    } else if (type== L_NUMBER)
[492]37    { ret=sizeof(LNumber); }
[2]38    else if (type==L_CHARACTER)
[492]39    { ret=sizeof(LChar); }
[2]40    else if (type==L_STRING)
[124]41    {
[492]42      ret=sizeof(LString)+strlen(lstring_value(level))+1;
[2]43      if (ret<8)
44        ret=8;
45    }
46    else if (type==L_POINTER)
[492]47    { ret=sizeof(LPointer); }
[2]48    else ret=0;
49  }
[19]50#ifdef WORD_ALIGN
[2]51  return (ret+3)&(~3);
52#else
53  return ret;
54#endif
55}
56
57
58
59void write_level(bFILE *fp, Cell *level)
60{
61  int type=item_type(level);
[17]62  fp->write_uint8(type);
[2]63
64
65  switch (type)
66  {
67    case L_NUMBER :
[17]68    { fp->write_uint32(lnumber_value(level)); } break;
[2]69    case L_CHARACTER :
[17]70    { fp->write_uint16(lcharacter_value(level)); } break;
[2]71    case L_STRING :
72    { long l=strlen(lstring_value(level))+1;
[17]73      fp->write_uint32(l);
[124]74      fp->write(lstring_value(level),l);
[2]75    } break;
76    case L_SYMBOL :
[17]77    { fp->write_uint32((long)level); } break;
[2]78    case L_CONS_CELL :
79    {
[17]80      if (!level) fp->write_uint32(0);
[2]81      else
82      {
[124]83    long t=0;
84    void *b=level;
[494]85    for (; b && item_type(b)==L_CONS_CELL; b=CDR(b)) t++;
[124]86    if (b)
87    {
88      fp->write_uint32(-t);      // negative number means dotted list
89      write_level(fp,b);       // save end of dotted list
90    }
91    else fp->write_uint32(t);
[2]92
[494]93    for (b=level; b && item_type(b)==L_CONS_CELL; b=CDR(b))
[124]94      write_level(fp,CAR(b));
[2]95      }
96    } break;
97  }
98}
99
100Cell *load_block(bFILE *fp)
101{
[17]102  int type=fp->read_uint8();
[2]103  switch (type)
[124]104  {
[2]105    case L_NUMBER :
[492]106    { return LNumber::Create(fp->read_uint32()); } break;
[2]107    case L_CHARACTER :
[493]108    { return LChar::Create(fp->read_uint16()); } break;
[2]109    case L_STRING :
[17]110    { long l=fp->read_uint32();
[492]111      LString *s = LString::Create(l);
[2]112      fp->read(lstring_value(s),l);
113      return s;
114    } break;
115    case L_SYMBOL :
[17]116    { return (void *)fp->read_uint32(); } break;
[2]117    case L_CONS_CELL :
118    {
[17]119      long t=fp->read_uint32();
[2]120      if (!t) return NULL;
121      else
122      {
[124]123    long x=abs(t);
[492]124    LList *last=NULL,*first=NULL;
[124]125    while (x)
126    {
[492]127      LList *c = LList::Create();
[124]128      if (first)
129        last->cdr=c;
130      else first=c;
131      last=c;
132      x--;
133    }
[492]134    last->cdr = (t < 0) ? (LObject *)load_block(fp) : NULL;
[490]135
[494]136    for (last=first,x=0; x<abs(t); x++,last=(LList *)last->cdr)
[492]137      last->car = (LObject *)load_block(fp);
[124]138    return first;
[2]139      }
140    }
141  }
142  return NULL;
143}
Note: See TracBrowser for help on using the repository browser.