Exemplo n.º 1
0
void FoxPro::setMemo(size_t record, size_t field, SeekableReadStream *value) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	if (f.type != kTypeMemo)
		throw Exception("Field is not of memo type ('%c')", f.type);

	char *data = (char *) r.fields[field];

	if (!value) {
		memset(data, 0x20, f.size);
		updateUpdate();
		return;
	}

	value->seek(0);

	size_t size = value->size();

	size_t block = _memos.size();
	_memos.push_back(new byte[_memoBlockSize]);

	size_t startBlock = block + 1;

	WRITE_BE_UINT32(_memos[block]    , 1);
	WRITE_BE_UINT32(_memos[block] + 4, size);

	bool first = true;
	while (size > 0) {
		size_t n = MIN<size_t>(size, _memoBlockSize - (first ? 8 : 0));

		if (value->read(_memos[block] + (first ? 8 : 0), n) != n)
			throw Exception(kReadError);

		size  -= n;
		block += 1;

		if (size > 0)
			_memos.push_back(new byte[_memoBlockSize]);

		first = false;
	}

	if (f.decimals != 0)
		snprintf(data, f.size, "%*u", f.size, (uint) startBlock);
	else
		snprintf(data, f.size, "%*.*f", f.size, f.decimals, (double) startBlock);

	updateUpdate();
}
Exemplo n.º 2
0
bool createIDMap(PAKFile &out, const ExtractInformation *eI, const int *needList) {
	int dataEntries = 0;
	// Count entries in the need list
	for (const int *n = needList; *n != -1; ++n)
		++dataEntries;

	const int mapSize = 2 + dataEntries * (2 + 1 + 4);
	uint8 *map = new uint8[mapSize];
	uint8 *dst = map;

	WRITE_BE_UINT16(dst, dataEntries); dst += 2;
	for (const int *id = needList; *id != -1; ++id) {
		WRITE_BE_UINT16(dst, *id); dst += 2;
		const ExtractFilename *fDesc = getFilenameDesc(*id);
		if (!fDesc)
			return false;
		*dst++ = getTypeID(fDesc->type);
		WRITE_BE_UINT32(dst, getFilename(eI, *id)); dst += 4;
	}

	char filename[12];
	if (!getFilename(filename, eI, 0)) {
		fprintf(stderr, "ERROR: Could not create ID map for game\n");
		return false;
	}

	out.removeFile(filename);
	if (!out.addFile(filename, map, mapSize)) {
		fprintf(stderr, "ERROR: Could not add ID map \"%s\" to kyra.dat\n", filename);
		return false;
	}

	return true;
}
Exemplo n.º 3
0
int main(int argc, char *argv[]) {
	if (argc != 2) {
		printHelp(argv[0]);
		return -1;
	}

	PAKFile out;

	// First step: Write out all resources.
	outputAllResources(out);

	// Second step: Write all game version information
	std::vector<GameDef> games;
	outputAllGames(out, games);

	// Third step: Write index file
	byte *const indexBuffer = new byte[8 + 2 * games.size()];
	byte *dst = indexBuffer;
	WRITE_BE_UINT32(dst, kKyraDatVersion); dst += 4;
	WRITE_BE_UINT32(dst, games.size()); dst += 4;
	for (std::vector<GameDef>::const_iterator i = games.begin(), end = games.end(); i != end; ++i) {
		WRITE_BE_UINT16(dst, *i); dst += 2;
	}
	if (!out.addFile("INDEX", indexBuffer, 8 + 2 * games.size())) {
		error("couldn't write INDEX file");
	}

	if (!out.saveFile(argv[1])) {
		error("couldn't save changes to '%s'", argv[1]);
	}

	uint8 digest[16];
	if (!md5_file(argv[1], digest, 0))
		error("couldn't calc. md5 for file '%s'", argv[1]);
	FILE *f = fopen(argv[1], "ab");
	if (!f)
		error("couldn't open file '%s'", argv[1]);
	if (fwrite(digest, 1, 16, f) != 16)
		error("couldn't write md5sum to file '%s'", argv[1]);
	fclose(f);

	return 0;
}
Exemplo n.º 4
0
bool updateIndex(PAKFile &out, const ExtractInformation *eI) {
	uint32 size = 0;
	const uint8 *data = out.getFileData("INDEX", &size);

	Index index;
	if (data)
		index = parseIndex(data, size);

	GameDef gameDef = createGameDef(eI);
	if (index.version == kKyraDatVersion) {
		if (std::find(index.gameList.begin(), index.gameList.end(), gameDef) == index.gameList.end()) {
			++index.includedGames;
			index.gameList.push_back(gameDef);
		} else {
			// Already included in the game list, thus we do not need any further processing here.
			return true;
		}
	} else {
		index.version = kKyraDatVersion;
		index.includedGames = 1;
		index.gameList.push_back(gameDef);
	}

	const uint32 indexBufferSize = 8 + index.includedGames * 2;
	uint8 *indexBuffer = new uint8[indexBufferSize];
	assert(indexBuffer);
	uint8 *dst = indexBuffer;
	WRITE_BE_UINT32(dst, index.version); dst += 4;
	WRITE_BE_UINT32(dst, index.includedGames); dst += 4;
	for (Index::GameList::const_iterator i = index.gameList.begin(); i != index.gameList.end(); ++i) {
		WRITE_BE_UINT16(dst, *i); dst += 2;
	}

	out.removeFile("INDEX");
	if (!out.addFile("INDEX", indexBuffer, indexBufferSize)) {
		fprintf(stderr, "ERROR: couldn't update kyra.dat INDEX\n");
		delete[] indexBuffer;
		return false;
	}

	return true;
}
Exemplo n.º 5
0
bool createIDMap(PAKFile &out, const Game *g, const int *needList) {
	int dataEntries = 0;
	// Count entries in the need list and check whether the resources are
	// present
	for (const int *n = needList; *n != -1; ++n) {
		char filename[12];
		if (!getFilename(filename, g, *n) || !out.getFileList()->findEntry(filename)) {
			fprintf(stderr, "ERROR: Could not find need %d for game %04X", *n, createGameDef(g));
			return false;
		}
		++dataEntries;
	}

	const int mapSize = 2 + dataEntries * (2 + 1 + 4);
	uint8 *map = new uint8[mapSize];
	uint8 *dst = map;

	WRITE_BE_UINT16(dst, dataEntries); dst += 2;
	for (const int *id = needList; *id != -1; ++id) {
		WRITE_BE_UINT16(dst, *id); dst += 2;
		const ExtractFilename *fDesc = getFilenameDesc(*id);
		if (!fDesc) {
			delete[] map;
			return false;
		}
		*dst++ = fDesc->type;
		WRITE_BE_UINT32(dst, getFilename(g, *id)); dst += 4;
	}

	char filename[12];
	if (!getFilename(filename, g, 0)) {
		fprintf(stderr, "ERROR: Could not create ID map for game\n");
		delete[] map;
		return false;
	}

	if (!out.addFile(filename, map, mapSize)) {
		fprintf(stderr, "ERROR: Could not add ID map \"%s\" to kyra.dat\n", filename);
		delete[] map;
		return false;
	}

	return true;
}
Exemplo n.º 6
0
Common::ErrorCode Blorb::load() {
	// First, chew through the file and index the chunks
	Common::File f;
	if (!f.open(_filename) || f.size() < 12)
		return Common::kReadingFailed;

	if (f.readUint32BE() != ID_FORM)
		return Common::kReadingFailed;
	f.readUint32BE();
	if (f.readUint32BE() != ID_IFRS)
		return Common::kReadingFailed;
	if (f.readUint32BE() != ID_RIdx)
		return Common::kReadingFailed;

	f.readUint32BE();
	uint count = f.readUint32BE();

	// First read in the resource index
	for (uint idx = 0; idx < count; ++idx) {
		ChunkEntry ce;
		ce._type = f.readUint32BE();
		ce._number = f.readUint32BE();
		ce._offset = f.readUint32BE();

		_chunks.push_back(ce);
	}

	// Further iterate through the resources
	for (uint idx = 0; idx < _chunks.size(); ++idx) {
		ChunkEntry &ce = _chunks[idx];
		f.seek(ce._offset);
		ce._offset += 8;

		ce._id = f.readUint32BE();
		ce._size = f.readUint32BE();

		if (ce._type == ID_Pict) {
			ce._filename = Common::String::format("pic%u", ce._number);
			if (ce._id == ID_JPEG)
				ce._filename += ".jpg";
			else if (ce._id == ID_PNG)
				ce._filename += ".png";
			else if (ce._id == ID_Rect)
				ce._filename += ".rect";

		} else if (ce._type == ID_Snd) {
			ce._filename = Common::String::format("sound%u", ce._number);
			if (ce._id == ID_MIDI)
				ce._filename += ".midi";
			else if (ce._id == ID_MP3)
				ce._filename += ".mp3";
			else if (ce._id == ID_WAVE)
				ce._filename += ".wav";
			else if (ce._id == ID_AIFF || ce._id == ID_FORM)
				ce._filename += ".aiff";
			else if (ce._id == ID_OGG)
				ce._filename += ".ogg"; 
			else if (ce._id == ID_MOD)
				ce._filename += ".mod";

		} else if (ce._type == ID_Data) {
			ce._filename = Common::String::format("data%u", ce._number);

		} else if (ce._type == ID_Exec) {
			char buffer[5];
			WRITE_BE_UINT32(buffer, ce._id);
			buffer[4] = '\0';
			Common::String type(buffer);

			if (
				(_interpType == INTERPRETER_FROTZ && type == "ZCOD") ||
				(_interpType == INTERPRETER_GLULXE && type == "GLUL") ||
				(_interpType == INTERPRETER_TADS2 && type == "TAD2") ||
				(_interpType == INTERPRETER_TADS3 && type == "TAD3") ||
				(_interpType == INTERPRETER_HUGO && type == "HUGO")
			) {
				// Game executable
				ce._filename = "game";
			} else {
				ce._filename = type;
			}
		}
	}

	return Common::kNoError;
}
Exemplo n.º 7
0
void glopTexImage2D(GLContext *c, GLParam *p) {
	int target = p[1].i;
	int level = p[2].i;
	int components = p[3].i;
	int width = p[4].i;
	int height = p[5].i;
	int border = p[6].i;
	int format = p[7].i;
	int type = p[8].i;
	byte *pixels = (byte *)p[9].p;
	GLImage *im;
	byte *pixels1;
	bool do_free_after_rgb2rgba = false;

	Graphics::PixelFormat sourceFormat;
	switch (format) {
		case TGL_RGBA:
			sourceFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
			break;
		case TGL_RGB:
			sourceFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
			break;
		case TGL_BGRA:
			sourceFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
			break;
		case TGL_BGR:
			sourceFormat = Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0);
			break;
		default:
			error("tglTexImage2D: Pixel format not handled.");
	}

	Graphics::PixelFormat pf;
	switch (format) {
		case TGL_RGBA:
		case TGL_RGB:
#if defined(SCUMM_BIG_ENDIAN)
			pf = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
#elif defined(SCUMM_LITTLE_ENDIAN)
			pf = Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
#endif
			break;
		case TGL_BGRA:
		case TGL_BGR:
#if defined(SCUMM_BIG_ENDIAN)
			pf = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 0, 8, 16);
#elif defined(SCUMM_LITTLE_ENDIAN)
			pf = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
#endif
			break;
		default:
			break;
	}
	int bytes = pf.bytesPerPixel;

	// Simply unpack RGB into RGBA with 255 for Alpha.
	// FIXME: This will need additional checks when we get around to adding 24/32-bit backend.
	if (target == TGL_TEXTURE_2D && level == 0 && components == 3 && border == 0 && pixels != NULL) {
		if (format == TGL_RGB || format == TGL_BGR) {
			Graphics::PixelBuffer temp(pf, width * height, DisposeAfterUse::NO);
			Graphics::PixelBuffer pixPtr(sourceFormat, pixels);

			for (int i = 0; i < width * height; ++i) {
				uint8 r, g, b;
				pixPtr.getRGBAt(i, r, g, b);
				temp.setPixelAt(i, 255, r, g, b);
			}
			pixels = temp.getRawBuffer();
			do_free_after_rgb2rgba = true;
		}
	} else if ((format != TGL_RGBA &&
		    format != TGL_RGB &&
		    format != TGL_BGR &&
		    format != TGL_BGRA) ||
		    (type != TGL_UNSIGNED_BYTE &&
		     type != TGL_UNSIGNED_INT_8_8_8_8_REV)) {
		error("tglTexImage2D: combination of parameters not handled");
	}

	pixels1 = new byte[c->_textureSize * c->_textureSize * bytes];
	if (pixels != NULL) {
		if (width != c->_textureSize || height != c->_textureSize) {
			// we use interpolation for better looking result
			gl_resizeImage(pixels1, c->_textureSize, c->_textureSize, pixels, width, height);
			width = c->_textureSize;
			height = c->_textureSize;
		} else {
			memcpy(pixels1, pixels, c->_textureSize * c->_textureSize * bytes);
		}
#if defined(SCUMM_BIG_ENDIAN)
		if (type == TGL_UNSIGNED_INT_8_8_8_8_REV) {
			for (int y = 0; y < height; y++) {
				for (int x = 0; x < width; x++) {
					uint32 offset = (y * width + x) * 4;
					byte *data = pixels1 + offset;
					WRITE_BE_UINT32(data, READ_LE_UINT32(data));
				}
			}
		}
#endif
	}

	c->current_texture->versionNumber++;
	im = &c->current_texture->images[level];
	im->xsize = width;
	im->ysize = height;
	if (im->pixmap)
		im->pixmap.free();
	im->pixmap = Graphics::PixelBuffer(pf, pixels1);

	if (do_free_after_rgb2rgba) {
		// pixels as been assigned to tmp.getRawBuffer() which was created with
		// DisposeAfterUse::NO, therefore delete[] it
		delete[] pixels;
	}
}
Exemplo n.º 8
0
bool BitmapData::loadTile(Common::SeekableReadStream *o) {
#ifdef ENABLE_MONKEY4
	_x = 0;
	_y = 0;
	_format = 1;
	o->seek(0, SEEK_SET);

	/*uint32 id = */o->readUint32LE();
	// Should check that we actually HAVE a TIL
	uint32 bmoffset = o->readUint32LE();
	_numCoords = o->readUint32LE();
	_numLayers = o->readUint32LE();
	_numVerts = o->readUint32LE();

	// skip some 0
	o->seek(16, SEEK_CUR);
	_texc = new float[_numCoords * 4];

	for (uint32 i = 0; i < _numCoords * 4; ++i) {
		char f[4];
		o->read(f, 4);
		_texc[i] = get_float(f);
	}

	_layers = new Layer[_numLayers];
	for (uint32 i = 0; i < _numLayers; ++i) {
		_layers[i]._offset = o->readUint32LE();
		_layers[i]._numImages = o->readUint32LE();
	}

	_verts = new Vert[_numVerts];
	for (uint32 i = 0; i < _numVerts; ++i) {
		_verts[i]._texid = o->readUint32LE();
		_verts[i]._pos = o->readUint32LE();
		_verts[i]._verts = o->readUint32LE();
	}

	o->seek(16, SEEK_CUR);
	int numSubImages = o->readUint32LE();

	char **data = new char *[numSubImages];

	o->seek(16, SEEK_CUR);
	_bpp = o->readUint32LE();

	o->seek(bmoffset + 128);

	_width = o->readUint32LE();
	_height = o->readUint32LE();
	o->seek(-8, SEEK_CUR);

	int size = 4 * _width * _height;
	for (int i = 0; i < numSubImages; ++i) {
		data[i] = new char[size];
		o->seek(8, SEEK_CUR);
		if (_bpp == 16) {
			uint32 *d = (uint32 *)data[i];
			for (int j = 0; j < _width * _height; ++j) {
				uint16 p = o->readUint16LE();
				// These values are shifted left by 3 so that they saturate the color channel
				uint8 b = (p & 0x7C00) >> 7;
				uint8 g = (p & 0x03E0) >> 2;
				uint8 r = (p & 0x001F) << 3;
				uint8 a = (p & 0x8000) ? 0xFF : 0x00;
				// Recombine the color components into a 32 bit RGB value
				uint32 tmp = (r << 24) | (g << 16) | (b << 8) | a;
				WRITE_BE_UINT32(&d[j], tmp);
			}
		} else if (_bpp == 32) {
Exemplo n.º 9
0
static void DumpLong(long i, FILE* D) {
 byte out[4];
 WRITE_BE_UINT32(out, i);
 DumpBlock(out,4,D);
}
Exemplo n.º 10
0
void MidiMusicPlayer::playSEQ(uint32 size, bool loop) {
	// MIDI.DAT holds the file names in DW1 PSX
	Common::String baseName((char *)g_midiBuffer.pDat, size);
	Common::String seqName = baseName + ".SEQ";

	// TODO: Load the instrument bank (<baseName>.VB and <baseName>.VH)

	Common::File seqFile;
	if (!seqFile.open(seqName))
		error("Failed to open SEQ file '%s'", seqName.c_str());

	if (seqFile.readUint32LE() != MKTAG('S', 'E', 'Q', 'p'))
		error("Failed to find SEQp tag");

	// Make sure we don't have a SEP file (with multiple SEQ's inside)
	if (seqFile.readUint32BE() != 1)
		error("Can only play SEQ files, not SEP");

	uint16 ppqn = seqFile.readUint16BE();
	uint32 tempo = seqFile.readUint16BE() << 8;
	tempo |= seqFile.readByte();
	/* uint16 beat = */ seqFile.readUint16BE();

	// SEQ is directly based on SMF and we'll use that to our advantage here
	// and convert to SMF and then use the SMF MidiParser.

	// Calculate the SMF size we'll need
	uint32 dataSize = seqFile.size() - 15;
	uint32 actualSize = dataSize + 7 + 22;

	// Resize the buffer if necessary
	if (g_midiBuffer.size < actualSize) {
		g_midiBuffer.pDat = (byte *)realloc(g_midiBuffer.pDat, actualSize);
		assert(g_midiBuffer.pDat);
	}

	// Now construct the header
	WRITE_BE_UINT32(g_midiBuffer.pDat, MKTAG('M', 'T', 'h', 'd'));
	WRITE_BE_UINT32(g_midiBuffer.pDat + 4, 6); // header size
	WRITE_BE_UINT16(g_midiBuffer.pDat + 8, 0); // type 0
	WRITE_BE_UINT16(g_midiBuffer.pDat + 10, 1); // one track
	WRITE_BE_UINT16(g_midiBuffer.pDat + 12, ppqn);
	WRITE_BE_UINT32(g_midiBuffer.pDat + 14, MKTAG('M', 'T', 'r', 'k'));
	WRITE_BE_UINT32(g_midiBuffer.pDat + 18, dataSize + 7); // SEQ data size + tempo change event size

	// Add in a fake tempo change event
	WRITE_BE_UINT32(g_midiBuffer.pDat + 22, 0x00FF5103); // no delta, meta event, tempo change, param size = 3
	WRITE_BE_UINT16(g_midiBuffer.pDat + 26, tempo >> 8);
	g_midiBuffer.pDat[28] = tempo & 0xFF;

	// Now copy in the rest of the events
	seqFile.read(g_midiBuffer.pDat + 29, dataSize);
	seqFile.close();

	MidiParser *parser = MidiParser::createParser_SMF();
	if (parser->loadMusic(g_midiBuffer.pDat, actualSize)) {
		parser->setTrack(0);
		parser->setMidiDriver(this);
		parser->setTimerRate(getBaseTempo());
		parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
		parser->property(MidiParser::mpSendSustainOffOnNotesOff, 1);

		_parser = parser;

		_isLooping = loop;
		_isPlaying = true;
	} else {
		delete parser;
	}
}