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

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

style: remove trailing spaces, fix copyright statements.

File size: 3.2 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
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
13#include "lisp.h"
14#include "specs.h"
15#include "bus_type.h"
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
21  else
22  {
23    int type=item_type(level);
24    if (type==L_CONS_CELL)
25    {
26    long t=0;
27    void *b=level;
28    for (; b && item_type(b)==L_CONS_CELL; b=CDR(b))
29    {
30      t+=sizeof(LList);
31    }
32    if (b) t+=block_size(b);
33    for (b=level; b && item_type(b)==L_CONS_CELL; b=CDR(b))
34      t+=block_size(CAR(b));
35    ret=t;
36    } else if (type== L_NUMBER)
37    { ret=sizeof(LNumber); }
38    else if (type==L_CHARACTER)
39    { ret=sizeof(LChar); }
40    else if (type==L_STRING)
41    {
42      ret=sizeof(LString)+strlen(lstring_value(level))+1;
43      if (ret<8)
44        ret=8;
45    }
46    else if (type==L_POINTER)
47    { ret=sizeof(LPointer); }
48    else ret=0;
49  }
50#ifdef WORD_ALIGN
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);
62  fp->write_uint8(type);
63
64
65  switch (type)
66  {
67    case L_NUMBER :
68    { fp->write_uint32(lnumber_value(level)); } break;
69    case L_CHARACTER :
70    { fp->write_uint16(lcharacter_value(level)); } break;
71    case L_STRING :
72    { long l=strlen(lstring_value(level))+1;
73      fp->write_uint32(l);
74      fp->write(lstring_value(level),l);
75    } break;
76    case L_SYMBOL :
77    { fp->write_uint32((long)level); } break;
78    case L_CONS_CELL :
79    {
80      if (!level) fp->write_uint32(0);
81      else
82      {
83    long t=0;
84    void *b=level;
85    for (; b && item_type(b)==L_CONS_CELL; b=CDR(b)) t++;
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);
92
93    for (b=level; b && item_type(b)==L_CONS_CELL; b=CDR(b))
94      write_level(fp,CAR(b));
95      }
96    } break;
97  }
98}
99
100Cell *load_block(bFILE *fp)
101{
102  int type=fp->read_uint8();
103  switch (type)
104  {
105    case L_NUMBER :
106    { return LNumber::Create(fp->read_uint32()); } break;
107    case L_CHARACTER :
108    { return LChar::Create(fp->read_uint16()); } break;
109    case L_STRING :
110    { long l=fp->read_uint32();
111      LString *s = LString::Create(l);
112      fp->read(lstring_value(s),l);
113      return s;
114    } break;
115    case L_SYMBOL :
116    { return (void *)fp->read_uint32(); } break;
117    case L_CONS_CELL :
118    {
119      long t=fp->read_uint32();
120      if (!t) return NULL;
121      else
122      {
123    long x=abs(t);
124    LList *last=NULL,*first=NULL;
125    while (x)
126    {
127      LList *c = LList::Create();
128      if (first)
129        last->cdr=c;
130      else first=c;
131      last=c;
132      x--;
133    }
134    last->cdr = (t < 0) ? (LObject *)load_block(fp) : NULL;
135
136    for (last=first,x=0; x<abs(t); x++,last=(LList *)last->cdr)
137      last->car = (LObject *)load_block(fp);
138    return first;
139      }
140    }
141  }
142  return NULL;
143}
Note: See TracBrowser for help on using the repository browser.