scummvm/engines/sludge/moreio.cpp
2017-07-13 18:27:45 +02:00

328 lines
6.4 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "allfiles.h"
#include "moreio.h"
#include "newfatal.h"
#include "stringy.h"
#include "sludge.h"
#include "common/debug.h"
#include "common/file.h"
#if defined __unix__ && !(defined __APPLE__)
#include <endian.h>
#if __BYTE_ORDER == __BIG_ENDIAN
#define __BIG_ENDIAN__
#endif
#endif
namespace Sludge {
bool allowAnyFilename = true;
int getch(Common::SeekableReadStream *stream) {
return stream->readByte();
}
void putch(int c, Common::WriteStream *stream) {
stream->writeByte(c);
}
int get2bytes(Common::SeekableReadStream *stream) {
int f1, f2;
f1 = getch(stream);
f2 = getch(stream);
return (f1 * 256 + f2);
}
void put2bytes(int numtoput, Common::WriteStream *stream) {
putch((char) (numtoput / 256), stream);
putch((char) (numtoput % 256), stream);
}
void writeString(char *s, Common::WriteStream *stream) {
int a, len = strlen(s);
put2bytes(len, stream);
for (a = 0; a < len; ++a) {
putch(s[a] + 1, stream);
}
}
char *readString(Common::SeekableReadStream *stream) {
int a, len = get2bytes(stream);
char *s = new char[len + 1];
if (!checkNew(s)) {
return NULL;
}
for (a = 0; a < len; ++a) {
s[a] = (char) (getch(stream) - 1);
}
s[len] = 0;
debug(kSludgeDebugDataLoad, "Read string of length %i: %s", len, s);
return s;
}
float floatSwap(float f) {
union {
float f;
unsigned char b[4];
} dat1, dat2;
dat1.f = f;
dat2.b[0] = dat1.b[3];
dat2.b[1] = dat1.b[2];
dat2.b[2] = dat1.b[1];
dat2.b[3] = dat1.b[0];
return dat2.f;
}
float getFloat(Common::SeekableReadStream *stream) {
float f;
size_t bytes_read = stream->read(&f, sizeof(float));
//fread(& f, sizeof(float), 1, fp);
if (bytes_read != sizeof(float) && stream->err()) {
debug("Reading error in getFloat.\n");
}
#ifdef __BIG_ENDIAN__
return floatSwap(f);
#else
return f;
#endif
}
void putFloat(float f, Common::WriteStream *stream) {
#ifdef __BIG_ENDIAN__
f = floatSwap(f);
#endif
stream->write(&f, sizeof(float));
//fwrite(& f, sizeof(float), 1, fp);
}
short shortSwap(short s) {
unsigned char b1, b2;
b1 = s & 255;
b2 = (s >> 8) & 255;
return (b1 << 8) + b2;
}
short getSigned(Common::SeekableReadStream *stream) {
short f;
size_t bytes_read = stream->read(&f, sizeof(short));
if (bytes_read != sizeof(short) && stream->err()) {
debug("Reading error in getSigned.\n");
}
#ifdef __BIG_ENDIAN__
f = shortSwap(f);
#endif
return f;
}
void putSigned(short f, Common::WriteStream *stream) {
#ifdef __BIG_ENDIAN__
f = shortSwap(f);
#endif
stream->write(&f, sizeof(short));
}
// The following two functions treat signed integers as unsigned.
// That's done on purpose.
int32_t get4bytes(Common::SeekableReadStream *stream) {
int f1, f2, f3, f4;
f1 = getch(stream);
f2 = getch(stream);
f3 = getch(stream);
f4 = getch(stream);
unsigned int x = f1 + f2 * 256 + f3 * 256 * 256 + f4 * 256 * 256 * 256;
return x;
}
void put4bytes(unsigned int i, Common::WriteStream *stream) {
unsigned char f1, f2, f3, f4;
f4 = i / (256 * 256 * 256);
i = i % (256 * 256 * 256);
f3 = i / (256 * 256);
i = i % (256 * 256);
f2 = i / 256;
f1 = i % 256;
putch(f1, stream);
putch(f2, stream);
putch(f3, stream);
putch(f4, stream);
}
char *encodeFilename(char *nameIn) {
if (!nameIn)
return NULL;
if (allowAnyFilename) {
char *newName = new char[strlen(nameIn) * 2 + 1];
if (!checkNew(newName))
return NULL;
int i = 0;
while (*nameIn) {
switch (*nameIn) {
case '<':
newName[i++] = '_';
newName[i++] = 'L';
break;
case '>':
newName[i++] = '_';
newName[i++] = 'G';
break;
case '|':
newName[i++] = '_';
newName[i++] = 'P';
break;
case '_':
newName[i++] = '_';
newName[i++] = 'U';
break;
case '\"':
newName[i++] = '_';
newName[i++] = 'S';
break;
case '\\':
newName[i++] = '_';
newName[i++] = 'B';
break;
case '/':
newName[i++] = '_';
newName[i++] = 'F';
break;
case ':':
newName[i++] = '_';
newName[i++] = 'C';
break;
case '*':
newName[i++] = '_';
newName[i++] = 'A';
break;
case '?':
newName[i++] = '_';
newName[i++] = 'Q';
break;
default:
newName[i++] = *nameIn;
break;
}
newName[i] = 0;
nameIn++;
}
return newName;
} else {
int a;
for (a = 0; nameIn[a]; ++a) {
#ifdef _WIN32
if (nameIn[a] == '/') nameIn[a] = '\\';
#else
if (nameIn[a] == '\\')
nameIn[a] = '/';
#endif
}
return copyString(nameIn);
}
}
char *decodeFilename(char *nameIn) {
if (allowAnyFilename) {
char *newName = new char[strlen(nameIn) + 1];
if (!checkNew(newName))
return NULL;
int i = 0;
while (*nameIn) {
if (*nameIn == '_') {
nameIn++;
switch (*nameIn) {
case 'L':
newName[i] = '<';
nameIn++;
break;
case 'G':
newName[i] = '>';
nameIn++;
break;
case 'P':
newName[i] = '|';
nameIn++;
break;
case 'U':
newName[i] = '_';
nameIn++;
break;
case 'S':
newName[i] = '\"';
nameIn++;
break;
case 'B':
newName[i] = '\\';
nameIn++;
break;
case 'F':
newName[i] = '/';
nameIn++;
break;
case 'C':
newName[i] = ':';
nameIn++;
break;
case 'A':
newName[i] = '*';
nameIn++;
break;
case 'Q':
newName[i] = '?';
nameIn++;
break;
default:
newName[i] = '_';
}
} else {
newName[i] = *nameIn;
nameIn++;
}
i++;
}
newName[i] = 0;
return newName;
} else {
return copyString(nameIn);
}
}
} // End of namespace Sludge