| 170 | } |
| 171 | |
| 172 | bool rldecodecubes(ucharbuf &f, sqr *s, int len, int version, bool silent) // run-length decoding of a series of cubes (version is only relevant, if < 6) |
| 173 | { |
| 174 | sqr *t = NULL, *e = s + len; |
| 175 | while(s < e) |
| 176 | { |
| 177 | int type = f.overread() ? -1 : f.get(); |
| 178 | switch(type) |
| 179 | { |
| 180 | case -1: |
| 181 | { |
| 182 | if(!silent) conoutf("while reading map at %d: unexpected end of file", int(cubicsize - (e - s))); |
| 183 | f.forceoverread(); |
| 184 | silent = true; |
| 185 | sqrdefault(s); |
| 186 | break; |
| 187 | } |
| 188 | case 255: |
| 189 | { |
| 190 | if(!t) { f.forceoverread(); continue; } |
| 191 | int n = f.get(); |
| 192 | loopi(n) memcpy(s++, t, sizeof(sqr)); |
| 193 | s--; |
| 194 | break; |
| 195 | } |
| 196 | case 254: // only in MAPVERSION<=2 |
| 197 | { |
| 198 | if(!t) { f.forceoverread(); continue; } |
| 199 | memcpy(s, t, sizeof(sqr)); |
| 200 | f.get(); f.get(); |
| 201 | break; |
| 202 | } |
| 203 | case SOLID: |
| 204 | { |
| 205 | sqrdefault(s); // takes care of ftex, ctex, floor, ceil and tag |
| 206 | s->type = SOLID; |
| 207 | s->utex = s->wtex = f.get(); |
| 208 | s->vdelta = f.get(); |
| 209 | if(version<=2) { f.get(); f.get(); } |
| 210 | break; |
| 211 | } |
| 212 | case 253: // SOLID with all textures during editing (undo) |
| 213 | type = SOLID; |
| 214 | default: |
| 215 | { |
| 216 | if(type<0 || type>=MAXTYPE) |
| 217 | { |
| 218 | if(!silent) conoutf("while reading map at %d: type %d out of range", int(cubicsize - (e - s)), type); |
| 219 | f.forceoverread(); |
| 220 | continue; |
| 221 | } |
| 222 | sqrdefault(s); |
| 223 | s->type = type; |
| 224 | s->floor = f.get(); |
| 225 | s->ceil = f.get(); |
| 226 | if(s->floor>=s->ceil) s->floor = s->ceil-1; // for pre 12_13 |
| 227 | s->wtex = f.get(); |
| 228 | s->ftex = f.get(); |
| 229 | s->ctex = f.get(); |
no test coverage detected