Exemple #1
0
void ScriptInterpreter::copyValue(ScriptValue &destValue, ScriptValue &sourceValue) {

	if (sourceValue.type == -1) {
		debugCN(kDebugScript, "ScriptInterpreter::copyValue() Trying to read uninitialized value!\n");
	}

	switch (destValue.type) {

	case kGameVar:
		_globalVars[destValue.value] = sourceValue;
		break;

	case kRegister:
		_registers[destValue.value] = sourceValue;
		break;

	case kLogicVar:
		// TODO: Move to own method
		if (sourceValue.type == kInteger) {
			_logicGlobals[destValue.value] = sourceValue.value;
		} else {
			debugCN(kDebugScript, "ScriptInterpreter::copyValue() Invalid source value type %d!\n", sourceValue.type);
		}
		break;

	case kKernelVar:
		setKernelVar(destValue.value, sourceValue);
		break;

	default:
		debugCN(kDebugScript, "ScriptInterpreter::copyValue() Invalid dest value type %d!\n", destValue.type);

	}

}
Exemple #2
0
void ScriptInterpreter::dumpGlobalVars() {
	debugCN(kDebugScript, "ScriptInterpreter::dumpGlobalVars()\n");
	for (int i = 0; i < ARRAYSIZE(_globalVars); i++) {
		if (_globalVars[i].type != -1)
			debugCN(kDebugScript, "%03d. type = %02d; value = %d\n", i, _globalVars[i].type, _globalVars[i].value);
	}
}
Exemple #3
0
ScriptFunction *ScriptInterpreter::loadFunction(const Common::String &name) {
	FunctionNameMap::iterator iter = _functionNames.find(name);
	if (iter == _functionNames.end()) {
		debugCN(kDebugScript, "ScriptInterpreter::loadFunction() Function '%s' not found!\n", name.c_str());
		return NULL;
	}
	uint32 funcIndex = (*iter)._value;
	debugCN(kDebugScript, "ScriptInterpreter::loadFunction() index('%s') = %d\n", name.c_str(), funcIndex);
	return loadFunction(funcIndex);
}
Exemple #4
0
void ScriptInterpreter::getKernelVar(int index, ScriptValue &value) {

	debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() index = %d\n", index);

	if (index > _kernelVarsMax) {
		debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() Invalid kernel var index %d!\n", index);
		return;
	}

	debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() name = %s\n", _kernelVars[index].desc);

	ScriptKernelVariable var = _kernelVars[index].var;

	switch (var) {

	case kKernelTrigger:
		value = _vm->_kernel->trigger;
		break;

	case kKernelTriggerMode:
		value = (int)_vm->_kernel->triggerMode;
		break;

	case kKernelContinueHandlingTrigger:
		value = (int)_vm->_kernel->daemonTriggerAvailable;
		break;

	case kGameVersion:
		// TODO
		value = 0;
		break;

	case kGameLanguage:
		// TODO
		value = 0;
		break;

	case kGameNewRoom:
		// TODO
		value = 0;
		break;

	case kPlayerCommandReady:
		value = (int)_vm->_player->commandReady;
		break;

	default:
		debugCN(kDebugScript, "ScriptInterpreter::getKernelVar() Invalid kernel var %d!\n", var);
		//g_system->delayMillis(2000);

	}

}
Exemple #5
0
void ScriptInterpreter::callFunction(uint32 index) {
	// NOTE: This is a temporary hack for script functions not yet in the m4.dat
	if (index == 0xFFFFFFFF)
		return;
	debugCN(kDebugScript, "ScriptInterpreter::callFunction() index = %d [%s]\n", index, _scriptFunctionNames[index].c_str());
	ScriptFunction *subFunction = loadFunction(index);
	if (!subFunction) {
		// This *should* never happen since the linker checks this
		debugCN(kDebugScript, "ScriptInterpreter::callFunction() Function %d could not be loaded!\n", index);
		return;
	}
	runFunction(subFunction);
}
Exemple #6
0
int ScriptInterpreter::o1_hasPlayerSaid() {
	const char *words[3];
	for (int i = 0; i < 3; i++)
		words[i] = STRING(i);
	debugCN(kDebugScript, "'%s', '%s', '%s'\n", words[0], words[1], words[2]);

	int result = _vm->_player->said(words[0], words[1], words[2]);

	debugCN(kDebugScript, "   -> '%d'\n", result);

	RETURN(result);
	return 3;
}
Exemple #7
0
void ScriptInterpreter::dumpArgs(uint32 count) {
	debugCN(kDebugScript, "ScriptInterpreter::dumpArgs() ");
	for (uint32 i = 0; i < count; i++) {
		ScriptValue argValue = getArg(i);
		if (argValue.type == kConstString) {
			debugCN(kDebugScript, "'%s'", toString(argValue));
		} else {
			debugCN(kDebugScript, "%d", argValue.value);
		}
		if (i + 1 < count)
			debugCN(kDebugScript, ", ");
	}
	debugCN(kDebugScript, "\n");
}
Exemple #8
0
int ScriptInterpreter::o1_hasPlayerSaidAny() {
	const char *words[10];
	for (int i = 0; i < 10; i++)
		words[i] = STRING(i);

	debugCN(kDebugScript, "'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'\n",
		words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7], words[8], words[9]);

	int result = _vm->_player->saidAny(words[0], words[1], words[2], words[3], words[4], words[5], words[6], words[7], words[8], words[9]);
	debugCN(kDebugScript, "   -> '%d'\n", result);

	RETURN(result);
	return 10;
}
Exemple #9
0
MystAreaDrag::MystAreaDrag(MohawkEngine_Myst *vm, ResourceType type, Common::SeekableReadStream *rlstStream, MystArea *parent) :
		MystAreaImageSwitch(vm, type, rlstStream, parent) {
	_flagHV = rlstStream->readUint16LE();
	_minH = rlstStream->readUint16LE();
	_maxH = rlstStream->readUint16LE();
	_minV = rlstStream->readUint16LE();
	_maxV = rlstStream->readUint16LE();
	_stepsH = rlstStream->readUint16LE();
	_stepsV = rlstStream->readUint16LE();
	_mouseDownOpcode = rlstStream->readUint16LE();
	_mouseDragOpcode = rlstStream->readUint16LE();
	_mouseUpOpcode = rlstStream->readUint16LE();

	debugC(kDebugResource, "\tdirection: %d", _flagHV);
	debugC(kDebugResource, "\thorizontal min: %d", _minH);
	debugC(kDebugResource, "\thorizontal max: %d", _maxH);
	debugC(kDebugResource, "\tvertical min: %d", _minV);
	debugC(kDebugResource, "\tvertical max: %d", _maxV);
	debugC(kDebugResource, "\thorizontal steps: %d", _stepsH);
	debugC(kDebugResource, "\tvertical steps: %d", _stepsV);
	debugC(kDebugResource, "\t_mouseDownOpcode: %d", _mouseDownOpcode);
	debugC(kDebugResource, "\t_mouseDragOpcode: %d", _mouseDragOpcode);
	debugC(kDebugResource, "\t_mouseUpOpcode: %d", _mouseUpOpcode);

	debugCN(kDebugResource, "Type 11 _mouseDownOpcode: %d\n", _mouseDownOpcode);
	debugCN(kDebugResource, "Type 11 _mouseDragOpcode: %d\n", _mouseDragOpcode);
	debugCN(kDebugResource, "Type 11 _mouseUpOpcode: %d\n", _mouseUpOpcode);

	for (byte i = 0; i < ARRAYSIZE(_lists); i++) {
		debugC(kDebugResource, "\tList %d:", i);

		uint16 listCount = rlstStream->readUint16LE();
		debugC(kDebugResource, "\t%d values", listCount);

		for (uint16 j = 0; j < listCount; j++) {
			_lists[i].push_back(rlstStream->readUint16LE());
			debugC(kDebugResource, "\tValue %d: %d", j, _lists[i][j]);
		}
	}

	_stepH = 0;
	_stepV = 0;

	if (_stepsH)
		_stepH = (_maxH - _minH) / (_stepsH - 1);

	if (_stepsV)
		_stepV = (_maxV - _minV) / (_stepsV - 1);
}
Exemple #10
0
MystResourceType11::MystResourceType11(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) : MystResourceType8(vm, rlstStream, parent) {
	_flagHV = rlstStream->readUint16LE();
	_minH = rlstStream->readUint16LE();
	_maxH = rlstStream->readUint16LE();
	_minV = rlstStream->readUint16LE();
	_maxV = rlstStream->readUint16LE();
	_stepsH = rlstStream->readUint16LE();
	_stepsV = rlstStream->readUint16LE();
	_mouseDownOpcode = rlstStream->readUint16LE();
	_mouseDragOpcode = rlstStream->readUint16LE();
	_mouseUpOpcode = rlstStream->readUint16LE();

	debugC(kDebugResource, "\tdirection: %d", _flagHV);
	debugC(kDebugResource, "\thorizontal min: %d", _minH);
	debugC(kDebugResource, "\thorizontal max: %d", _maxH);
	debugC(kDebugResource, "\tvertical min: %d", _minV);
	debugC(kDebugResource, "\tvertical max: %d", _maxV);
	debugC(kDebugResource, "\thorizontal steps: %d", _stepsH);
	debugC(kDebugResource, "\tvertical steps: %d", _stepsV);
	debugC(kDebugResource, "\t_mouseDownOpcode: %d", _mouseDownOpcode);
	debugC(kDebugResource, "\t_mouseDragOpcode: %d", _mouseDragOpcode);
	debugC(kDebugResource, "\t_mouseUpOpcode: %d", _mouseUpOpcode);

	debugCN(kDebugResource, "Type 11 _mouseDownOpcode: %d\n", _mouseDownOpcode);
	debugCN(kDebugResource, "Type 11 _mouseDragOpcode: %d\n", _mouseDragOpcode);
	debugCN(kDebugResource, "Type 11 _mouseUpOpcode: %d\n", _mouseUpOpcode);

	for (byte i = 0; i < 3; i++) {
		debugC(kDebugResource, "\tList %d:", i);

		_lists[i].listCount = rlstStream->readUint16LE();
		debugC(kDebugResource, "\t%d values", _lists[i].listCount);

		_lists[i].list = new uint16[_lists[i].listCount];
		for (uint16 j = 0; j < _lists[i].listCount; j++) {
			_lists[i].list[j] = rlstStream->readUint16LE();
			debugC(kDebugResource, "\tValue %d: %d", j, _lists[i].list[j]);
		}
	}

	_stepH = 0;
	_stepV = 0;

	if (_stepsH)
		_stepH = (_maxH - _minH) / (_stepsH - 1);

	if (_stepsV)
		_stepV = (_maxV - _minV) / (_stepsV - 1);
}
Exemple #11
0
void SaidArray::load(Common::File *fd) {
	uint32 count = fd->readUint32LE();
	debugCN(kDebugScript, "SaidArray::load() count = %d\n", count);
	for (uint32 i = 0; i < count; i++) {
		SaidArrayItem *item = new SaidArrayItem();
		item->itemName = _inter->loadGlobalString(fd);
		item->digiNameLook = _inter->loadGlobalString(fd);
		item->digiNameTake = _inter->loadGlobalString(fd);
		item->digiNameGear = _inter->loadGlobalString(fd);
		_items.push_back(item);

		debugCN(kDebugScript, "itemName = %s; digiNameLook = %s; digiNameTake = %s; digiNameGear = %s\n",
			item->itemName, item->digiNameLook, item->digiNameTake, item->digiNameGear);

	}
}
Exemple #12
0
int ScriptInterpreter::o1_triggerTimerProc() {
	int value1 = INTEGER(0);
	int value2 = INTEGER(1);
	int value3 = INTEGER(2);
	debugCN(kDebugScript, "%d; %d; %d\n", value1, value2, value3);
	return 3;
}
Exemple #13
0
int ScriptInterpreter::o1_setWalkerLocation() {
	// skip arg 0: walker
	int x = INTEGER(1);
	int y = INTEGER(2);
	debugCN(kDebugScript, "x = %d; y = %d\n", x, y);
	return 3;
}
Exemple #14
0
int ScriptInterpreter::o1_playerHasItem() {
	const char *name = STRING(0);
	debugCN(kDebugScript, "item = '%s'\n", name);
	// TODO
	RETURN(0);
	return 1;
}
Exemple #15
0
const BAFile *BArchive::getFile(uint i) {
	// Check whether requested file exists
	if (i >= _fileCount) {
		return NULL;
	}

	debugCN(2, kDraciArchiverDebugLevel, "Accessing file %d from archive %s... ",
		i, _path.c_str());

	// Check if file has already been opened and return that
	if (_files[i]._data) {
		debugC(2, kDraciArchiverDebugLevel, "Cached");
		return _files + i;
	}

	BAFile *file;

	// file will be NULL if something goes wrong
	if (_isDFW) {
		file = loadFileDFW(i);
	} else {
		file = loadFileBAR(i);
	}

	return file;
}
Exemple #16
0
void MadsM4Engine::dumpFile(const char* filename, bool uncompress) {
	Common::DumpFile f;
	byte buffer[DUMP_BUFFER_SIZE];
	Common::SeekableReadStream *fileS = res()->get(filename);
	
	if (!f.open(filename))
		error("Could not open '%s' for writing", filename);

	int bytesRead = 0;
	warning("Dumping %s, size: %i\n", filename, fileS->size());

	if (!uncompress) {
		while (!fileS->eos()) {
			bytesRead = fileS->read(buffer, DUMP_BUFFER_SIZE);
			f.write(buffer, bytesRead);
		}
	} else {
		MadsPack packData(fileS);
		Common::SeekableReadStream *sourceUnc;
		for (int i = 0; i < packData.getCount(); i++) {
			sourceUnc = packData.getItemStream(i);
			debugCN(kDebugCore, "Dumping compressed chunk %i of %i, size is %i\n", i + 1, packData.getCount(), sourceUnc->size());
			while (!sourceUnc->eos()) {
				bytesRead = sourceUnc->read(buffer, DUMP_BUFFER_SIZE);
				f.write(buffer, bytesRead);
			}
			delete sourceUnc;
		}
	}

	f.close();
	res()->toss(filename);
	res()->purge();
}
Exemple #17
0
void Kernel::roomParser() {
	if (_roomParserFn)
		_vm->_script->runFunction(_roomParserFn);
	else {
		debugCN(kDebugScript, "Kernel::roomParser() _roomParserFn is NULL\n");
	}
}
Exemple #18
0
Common::SeekableReadStream *FileSystem::loadFile(const char *resourceName, bool preloadFlag) {
	const HashFileEntry *hfe = getHashFileEntry(resourceName);
	Common::SeekableReadStream *result = NULL;

	if (hfe) {
		//debugCN(kDebugCore, "FileSystem::loadFile() success opening %s\n", filename);
		HashHagEntry *hagEntry = &_hagEntries[hfe->hagfile];

		if (preloadFlag) {
			// Creates a MemoryReadStream object that contains all of the resource in memory
			hagEntry->hagFile->seek(hfe->offset);
			result = _hagEntries[hfe->hagfile].hagFile->readStream(hfe->size);
		}
		else
			// Creates a SeekableSubReadStream, which will read the data in from disk as the
			// caller reads in data
			result = new Common::SeekableSubReadStream(hagEntry->hagFile, hfe->offset,
				hfe->offset + hfe->size);

	} else {
		debugCN(kDebugCore, "FileSystem::loadFile() error opening %s\n", resourceName);
	}

	return result;
}
Exemple #19
0
SoundSample *ZipSoundArchive::getSample(int i, uint freq) {
	if (i < 0 || i >= (int)_sampleCount) {
		return NULL;
	}
	debugCN(2, kDraciArchiverDebugLevel, "Accessing sample %d.%s from archive %s (format %d@%d, capacity %d): ",
		i, _extension, _path, static_cast<int> (_format), _defaultFreq, _sampleCount);
	if (freq != 0 && (_format != RAW && _format != RAW80)) {
		error("Cannot resample a sound in compressed format");
		return NULL;
	}

	// We cannot really cache anything, because createReadStreamForMember()
	// returns the data as a ReadStream, which is not thread-safe.  We thus
	// read it again each time even if it has possibly been already cached
	// a while ago.  This is not such a problem for dubbing as for regular
	// sound samples.
	SoundSample sample;
	sample._frequency = freq ? freq : _defaultFreq;
	sample._format = _format;
	// Read in the file (without the file header)
	Common::String filename = Common::String::format("%d.%s", i+1, _extension);
	sample._stream = _archive->createReadStreamForMember(filename);
	if (!sample._stream) {
		debugC(2, kDraciArchiverDebugLevel, "Doesn't exist");
		return NULL;
	} else {
		debugC(2, kDraciArchiverDebugLevel, "Read");
		_cache.push_back(sample);
		// Return a pointer that we own and which we will deallocate
		// including its contents.
		return &_cache.back();
	}
}
Exemple #20
0
void Kernel::sectionDaemon() {
	if (_sectionDaemonFn)
		_vm->_script->runFunction(_sectionDaemonFn);
	else {
		debugCN(kDebugScript, "Kernel::sectionDaemon() _sectionDaemonFn is NULL\n");
	}
}
Exemple #21
0
void ScriptInterpreter::derefValue(ScriptValue &value) {

	switch (value.type) {

	case kGameVar:
		value = _globalVars[value.value];
		break;

	case kInteger:
	case kConstString:
	case kDataRef:
	case kLogicVarRef:
		// These need no dereferencing
		break;

	case kRegister:
		value = _registers[value.value];
		break;

	case kLogicVar:
		// TODO: Move to own method
		value = _logicGlobals[value.value];
		break;

	case kKernelVar:
		getKernelVar(value.value, value);
		break;

	default:
		debugCN(kDebugScript, "ScriptInterpreter::derefValue() Invalid value type %d!\n", value.type);

	}

}
Exemple #22
0
void ScriptInterpreter::loadValue(ScriptValue &value) {

	value.type = (ScriptValueType)_runningFunction->readByte();

	switch (value.type) {

	case kGameVar:
	case kInteger:
	case kConstString:
	case kDataRef:
	case kLogicVar:
	case kLogicVarRef:
	case kKernelVar:
		value.value = _runningFunction->readUint32();
		break;

	case kRegister:
		value.value = _runningFunction->readByte();
		break;

	default:
		debugCN(kDebugScript, "ScriptInterpreter::loadValue() Invalid value type %d!\n", value.type);

	}

}
Exemple #23
0
void Testsuite::logPrintf(const char *fmt, ...) {
	// Assuming log message size to be not greater than STRINGBUFLEN i.e 256
	char buffer[STRINGBUFLEN];
	va_list vl;
	va_start(vl, fmt);
	vsnprintf(buffer, STRINGBUFLEN, fmt, vl);
	va_end(vl);
	Common::WriteStream *ws = ConfigParams::instance().getLogWriteStream();

	if (ws) {
		ws->writeString(buffer);
		ws->flush();
		debugCN(kTestbedLogOutput, "%s", buffer);
	} else {
		debugCN(kTestbedLogOutput, "%s", buffer);
	}
}
Exemple #24
0
int ScriptInterpreter::o1_playerHotspotWalkOverride() {
	int x1 = INTEGER(0);
	int y1 = INTEGER(1);
	int x2 = INTEGER(2);
	int y2 = INTEGER(3);
	debugCN(kDebugScript, "(%d, %d); (%d, %d)\n", x1, y1, x2, y2);
	return 4;
}
Exemple #25
0
int ScriptInterpreter::o1_dispatchTrigger() {
	int trigger = INTEGER(0);
	debugCN(kDebugScript, "trigger = %d\n", trigger);

	_vm->_kernel->sendTrigger(trigger);
	//g_system->delayMillis(5000);

	return 1;
}
Exemple #26
0
void Testsuite::logDetailedPrintf(const char *fmt, ...) {
	// Assuming log message size to be not greater than STRINGBUFLEN i.e 256
	// Messages with this function would only be displayed if -d1 is specified on command line
	char buffer[STRINGBUFLEN];
	va_list vl;
	va_start(vl, fmt);
	vsnprintf(buffer, STRINGBUFLEN, fmt, vl);
	va_end(vl);
	Common::WriteStream *ws = ConfigParams::instance().getLogWriteStream();

	if (ws) {
		ws->writeString(buffer);
		ws->flush();
		debugCN(1, kTestbedLogOutput, "%s", buffer);
	} else {
		debugCN(1, kTestbedLogOutput, "%s", buffer);
	}
}
Exemple #27
0
int ScriptInterpreter::o1_wilburSaid() {
	const SaidArray& saidArray = DATA(0, SaidArray);

	int result = 0;

	// NOTE: The "Common::String soundName" stuff is just temporary until playVoice is fixed.

	for (int i = 0; i < saidArray.size(); i++) {
		SaidArrayItem *item = saidArray[i];

		if (_vm->_player->said("LOOK AT", item->itemName) && item->digiNameLook) {
			debugCN(kDebugScript, "  -> LOOK AT: '%s'\n", item->digiNameLook);
			Common::String soundName = Common::String(item->digiNameLook) + ".raw";
			_vm->_sound->playVoice(soundName.c_str(), 100);
			result = 1;
			break;
		}

		if (_vm->_player->said("TAKE", item->itemName) && item->digiNameTake) {
			debugCN(kDebugScript, "  -> TAKE: '%s'\n", item->digiNameTake);
			Common::String soundName = Common::String(item->digiNameTake) + ".raw";
			_vm->_sound->playVoice(soundName.c_str(), 100);
			result = 1;
			break;
		}

		if (_vm->_player->said("GEAR", item->itemName) && item->digiNameGear) {
			debugCN(kDebugScript, "  -> GEAR: '%s'\n", item->digiNameGear);
			Common::String soundName = Common::String(item->digiNameGear) + ".raw";
			_vm->_sound->playVoice(soundName.c_str(), 100);
			result = 1;
			break;
		}

		/*
		debugCN(kDebugScript, "##### itemName = '%s'; digiNameLook = %s; digiNameTake = %s; digiNameGear = %s\n",
			item->itemName, item->digiNameLook, item->digiNameTake, item->digiNameGear);
		*/
	}
	debugCN(kDebugScript, "   -> '%d'\n", result);

	RETURN(result);
	return 1;
}
Exemple #28
0
int ScriptInterpreter::o1_setHotspot() {
	// skip arg 0: hotspot list
	const char *name = STRING(1);
	int value = INTEGER(2);
	debugCN(kDebugScript, "name = '%s' -> %d\n", name, value);

	_vm->_scene->getSceneResources().hotspots->setActive(name, (value != 0));

	return 2;
}
Exemple #29
0
void ScriptInterpreter::callKernelFunction(uint32 index) {

	debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() index = %d\n", index);

	if (index > _kernelFunctionsMax) {
		debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() Invalid kernel functionindex (%d)\n", index);
		return;
	}

	debugCN(kDebugScript, "ScriptInterpreter::callKernelFunction() name = %s\n", _kernelFunctions[index].desc);

	int args = (this->*(_kernelFunctions[index].proc))();
	// Now remove values from the stack if the function used any
	if (args > 4)
		_stackPtr -= args - 4;

	debugCN(kDebugScript, "-------------\n");

}
Exemple #30
0
void Font::setFontM4(const char *filename) {
	Common::SeekableReadStream *fontFile = _vm->res()->openFile(filename);

	if (fontFile->readUint32LE() != MKTAG('F','O','N','T')) {
		debugCN(kDebugGraphics, "Font::Font: FONT tag expected\n");
		return;
	}

	_maxHeight = fontFile->readByte();
	_maxWidth = fontFile->readByte();
	uint32 fontSize = fontFile->readUint32LE();

	//debugCN(kDebugGraphics, "Font::Font: _maxWidth = %d, _maxHeight = %d, fontSize = %d\n", _maxWidth, _maxHeight, fontSize);

	if (fontFile->readUint32LE() != MKTAG('W','I','D','T')) {
		debugCN(kDebugGraphics, "Font::Font: WIDT tag expected\n");
		return;
	}

	_charWidths = new uint8[256];
	fontFile->read(_charWidths, 256);

	if (fontFile->readUint32LE() != MKTAG('O','F','F','S')) {
		debugCN(kDebugGraphics, "Font::Font: OFFS tag expected\n");
		return;
	}

	_charOffs = new uint16[256];

	for (int i = 0; i < 256; i++)
		_charOffs[i] = fontFile->readUint16LE();

	if (fontFile->readUint32LE() != MKTAG('P','I','X','S')) {
		debugCN(kDebugGraphics, "Font::Font: PIXS tag expected\n");
		return;
	}

	_charData = new uint8[fontSize];
	fontFile->read(_charData, fontSize);

	_vm->res()->toss(filename);
}