Example #1
0
static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, byte id) {
	Script *script = segMan->getScript(methodAddress.getSegment());
	byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));

	memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
	patchPtr[8] = id;
}
Example #2
0
static void patchGameSaveRestoreCodeSci2(SegManager *segMan, reg_t methodAddress, byte id, bool doRestore) {
	Script *script = segMan->getScript(methodAddress.getSegment());
	byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));
	int kcallOffset;

	if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) {
		if (doRestore) {
			memcpy(patchPtr, patchGameRestoreSci2, sizeof(patchGameRestoreSci2));
			kcallOffset = 9;
		} else {
			memcpy(patchPtr, patchGameSaveSci2, sizeof(patchGameSaveSci2));
			kcallOffset = 10;
		}
	} else {
		if (doRestore) {
			memcpy(patchPtr, patchGameRestoreSci21, sizeof(patchGameRestoreSci21));
			kcallOffset = 10;
		} else {
			memcpy(patchPtr, patchGameSaveSci21, sizeof(patchGameSaveSci21));
			kcallOffset = 11;
		}
	}

	patchPtr[kcallOffset] = id;
	if (g_sci->isBE()) {
		SWAP(patchPtr[kcallOffset + 1], patchPtr[kcallOffset + 2]);
	}
}
Example #3
0
Common::String Kernel::lookupText(reg_t address, int index) {
	char *seeker;
	Resource *textres;

	if (address.getSegment())
		return _segMan->getString(address);

	int textlen;
	int _index = index;
	textres = _resMan->findResource(ResourceId(kResourceTypeText, address.getOffset()), 0);

	if (!textres) {
		error("text.%03d not found", address.getOffset());
		return NULL; /* Will probably segfault */
	}

	textlen = textres->size;
	seeker = (char *) textres->data;

	while (index--)
		while ((textlen--) && (*seeker++))
			;

	if (textlen)
		return seeker;

	error("Index %d out of bounds in text.%03d", _index, address.getOffset());
	return NULL;
}
Example #4
0
void GuestAdditions::syncGK1VolumeFromScummVM(const int16 musicVolume, const int16 dacVolume) const {
	const reg_t soundsId = _state->variables[VAR_GLOBAL][kGlobalVarSounds];
	if (!soundsId.isNull()) {
		List *sounds = _segMan->lookupList(readSelector(_segMan, soundsId, SELECTOR(elements)));
		reg_t soundId = sounds->first;
		while (!soundId.isNull()) {
			Node *sound = _segMan->lookupNode(soundId);
			const int16 type = readSelectorValue(_segMan, sound->value, SELECTOR(type));
			int16 volume;

			if (type == kSoundsMusicType) {
				volume = ConfMan.getBool("mute") ? 0 : musicVolume;
				writeSelectorValue(_segMan, sound->value, SELECTOR(musicVolume), musicVolume);
			} else if (type == kSoundsSoundType) {
				volume = dacVolume;
				writeSelectorValue(_segMan, sound->value, SELECTOR(soundVolume), dacVolume);
			} else {
				error("Unknown sound type %d", type);
			}

			// `setVolume` will set the `vol` property on the sound object;
			// if it did not do this, an invocation of the `setVol` selector
			// would need to be here (though doing so would result in
			// recursion, so don't)
			g_sci->_soundCmd->setVolume(sound->value, volume);
			soundId = sound->succ;
		}
	}
}
Example #5
0
reg_t reg_t::operator+(const reg_t right) const {
	if (isPointer() && right.isNumber()) {
		// Pointer arithmetics. Only some pointer types make sense here
		SegmentObj *mobj = g_sci->getEngineState()->_segMan->getSegmentObj(segment);

		if (!mobj)
			error("[VM]: Attempt to add %d to invalid pointer %04x:%04x", right.offset, PRINT_REG(*this));

		switch (mobj->getType()) {
		case SEG_TYPE_LOCALS:
		case SEG_TYPE_SCRIPT:
		case SEG_TYPE_STACK:
		case SEG_TYPE_DYNMEM:
			return make_reg(segment, offset + right.toSint16());
		default:
			return lookForWorkaround(right);
		}	
	} else if (isNumber() && right.isPointer()) {
		// Adding a pointer to a number, flip the order
		return right + *this;
	} else if (isNumber() && right.isNumber()) {
		// Normal arithmetics
		return make_reg(0, toSint16() + right.toSint16());
	} else {
		return lookForWorkaround(right);
	}
}
Example #6
0
static void patchGameSaveRestoreCodeSci21(SegManager *segMan, reg_t methodAddress, byte id, bool doRestore) {
	Script *script = segMan->getScript(methodAddress.getSegment());
	byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));
	memcpy(patchPtr, patchGameRestoreSaveSci21, sizeof(patchGameRestoreSaveSci21));
	if (doRestore)
		patchPtr[2] = 0x78;	// push1
	patchPtr[9] = id;
}
Example #7
0
reg_t reg_t::operator-(const reg_t right) const {
	if (getSegment() == right.getSegment()) {
		// We can subtract numbers, or pointers with the same segment,
		// an operation which will yield a number like in C
		return make_reg(0, toSint16() - right.toSint16());
	} else {
		return *this + make_reg(right.getSegment(), -right.toSint16());
	}
}
Example #8
0
void GuestAdditions::syncGK2UI() const {
	const reg_t sliderId = _segMan->findObjectByName("soundSlider");
	if (!sliderId.isNull() && _segMan->getObject(sliderId)->isInserted()) {
		const reg_t oldAcc = _state->r_acc;
		invokeSelector(sliderId, SELECTOR(initialOff));
		writeSelector(_segMan, sliderId, SELECTOR(x), _state->r_acc);
		_state->r_acc = oldAcc;
	}
}
Example #9
0
static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, byte id) {
	Script *script = segMan->getScript(methodAddress.getSegment());
	byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));
	if (getSciVersion() <= SCI_VERSION_1_1)
		memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
	else	// SCI2+
		memcpy(patchPtr, patchGameRestoreSaveSci2, sizeof(patchGameRestoreSaveSci2));
	patchPtr[8] = id;
}
Example #10
0
void GuestAdditions::syncSQ6UI() const {
	const reg_t bars[] = { _segMan->findObjectByName("musicBar"),
						   _segMan->findObjectByName("soundBar") };
	for (int i = 0; i < ARRAYSIZE(bars); ++i) {
		const reg_t barId = bars[i];
		if (!barId.isNull()) {
			invokeSelector(barId, SELECTOR(show));
		}
	}
}
Example #11
0
void GuestAdditions::syncShivers1UI(const int16 dacVolume) const {
	const reg_t sliderId = _segMan->findObjectByName("spVolume");
	if (!sliderId.isNull()) {
		const int16 xPosition = dacVolume * 78 / Audio32::kMaxVolume + 32;
		writeSelectorValue(_segMan, sliderId, SELECTOR(x), xPosition);
		if (_segMan->getObject(sliderId)->isInserted()) {
			g_sci->_gfxFrameout->kernelUpdateScreenItem(sliderId);
		}
	}
}
Example #12
0
void GuestAdditions::syncPQ4UI(const int16 musicVolume) const {
	const SegmentId segment = _segMan->getScriptSegment(9, SCRIPT_GET_DONT_LOAD);
	if (segment != 0 && _segMan->getScript(segment)->getLocalsCount() > 2) {
		const reg_t barId = _segMan->getScript(segment)->getLocalsBegin()[2];
		if (!barId.isNull()) {
			reg_t params[] = { make_reg(0, musicVolume) };
			invokeSelector(barId, SELECTOR(setSize), 1, params);
		}
	}
}
Example #13
0
void GuestAdditions::syncLSL6HiresUI(const int16 musicVolume) const {
	const reg_t musicDialId = _segMan->findObjectByName("volumeDial");
	if (!musicDialId.isNull()) {
		writeSelectorValue(_segMan, musicDialId, SELECTOR(curPos), musicVolume);
		writeSelectorValue(_segMan, musicDialId, SELECTOR(cel), musicVolume);
		reg_t params[] = { make_reg(0, musicVolume) };
		invokeSelector(musicDialId, SELECTOR(update), 1, params);
		if (_segMan->getObject(musicDialId)->isInserted()) {
			g_sci->_gfxFrameout->kernelUpdateScreenItem(musicDialId);
		}
	}
}
Example #14
0
void GuestAdditions::syncAudioVolumeGlobalsToScummVM(const int index, const reg_t value) const {
	switch (g_sci->getGameId()) {
	case GID_GK2:
		if (index == kGlobalVarGK2MusicVolume) {
			const int16 musicVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / Audio32::kMaxVolume;
			ConfMan.setInt("music_volume", musicVolume);
		}
		break;

	case GID_LSL6HIRES:
		if (index == kGlobalVarLSL6HiresMusicVolume) {
			const int16 musicVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / kLSL6HiresUIVolumeMax;
			ConfMan.setInt("music_volume", musicVolume);
		}
		break;

	case GID_PHANTASMAGORIA:
		if (index == kGlobalVarPhant1MusicVolume) {
			const int16 musicVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / MUSIC_MASTERVOLUME_MAX;
			ConfMan.setInt("music_volume", musicVolume);
		} else if (index == kGlobalVarPhant1DACVolume) {
			const int16 dacVolume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / Audio32::kMaxVolume;
			ConfMan.setInt("sfx_volume", dacVolume);
			ConfMan.setInt("speech_volume", dacVolume);
		}
		break;

	case GID_TORIN:
		if (index == kGlobalVarTorinMusicVolume ||
			index == kGlobalVarTorinSFXVolume ||
			index == kGlobalVarTorinSpeechVolume) {

			const int16 volume = value.toSint16() * Audio::Mixer::kMaxMixerVolume / 100;

			switch (index) {
			case kGlobalVarTorinMusicVolume:
				ConfMan.setInt("music_volume", volume);
				break;
			case kGlobalVarTorinSFXVolume:
				ConfMan.setInt("sfx_volume", volume);
				break;
			case kGlobalVarTorinSpeechVolume:
				ConfMan.setInt("speech_volume", volume);
				break;
			}
		}
		break;

	default:
		break;
	}
}
Example #15
0
SegmentRef Script::dereference(reg_t pointer) {
	if (pointer.getOffset() > _buf->size()) {
		error("Script::dereference(): Attempt to dereference invalid pointer %04x:%04x into script %d segment (script size=%u)",
				  PRINT_REG(pointer), _nr, _buf->size());
		return SegmentRef();
	}

	SegmentRef ret;
	ret.isRaw = true;
	ret.maxSize = _buf->size() - pointer.getOffset();
	ret.raw = _buf->getUnsafeDataAt(pointer.getOffset(), ret.maxSize);
	return ret;
}
Example #16
0
void GuestAdditions::syncTorinUI(const int16 musicVolume, const int16 sfxVolume, const int16 speechVolume) const {
	const reg_t sliders[] = { _segMan->findObjectByName("oMusicScroll"),
							  _segMan->findObjectByName("oSFXScroll"),
							  _segMan->findObjectByName("oAudioScroll") };
	const int16 values[] = { musicVolume, sfxVolume, speechVolume };
	for (int i = 0; i < ARRAYSIZE(sliders); ++i) {
		const reg_t sliderId = sliders[i];
		if (!sliderId.isNull()) {
			reg_t params[] = { make_reg(0, values[i]) };
			invokeSelector(sliderId, SELECTOR(setPos), 1, params);
		}
	}
}
Example #17
0
void GuestAdditions::syncTextSpeedFromScummVM() const {
	const int16 textSpeed = 8 - (ConfMan.getInt("talkspeed") + 1) * 8 / 255;

	_state->variables[VAR_GLOBAL][kGlobalVarTextSpeed] = make_reg(0, textSpeed);

	if (g_sci->getGameId() == GID_GK1) {
		const reg_t textBarId = _segMan->findObjectByName("textBar");
		if (!textBarId.isNull()) {
			// Resetting the bar position to 0 causes the game to retrieve the
			// new text speed value and re-render
			writeSelectorValue(_segMan, textBarId, SELECTOR(position), 0);
		}
	}
}
Example #18
0
void GuestAdditions::syncQFG4UI(const int16 musicVolume) const {
	const reg_t sliderId = _segMan->findObjectByName("volumeSlider");
	if (!sliderId.isNull()) {
		const int16 yPosition = 84 - musicVolume * 34 / 10;
		writeSelectorValue(_segMan, sliderId, SELECTOR(y), yPosition);

		// There does not seem to be any good way to learn whether the
		// volume slider is visible (and thus eligible for
		// kUpdateScreenItem)
		const reg_t planeId = readSelector(_segMan, sliderId, SELECTOR(plane));
		if (g_sci->_gfxFrameout->getPlanes().findByObject(planeId) != nullptr) {
			g_sci->_gfxFrameout->kernelUpdateScreenItem(sliderId);
		}
	}
}
Example #19
0
void GuestAdditions::syncMessageTypeToScummVMUsingDefaultStrategy(const int index, const reg_t value) {
	if (index == kGlobalVarMessageType) {
		// ScummVM audio options haven't been applied yet. Use this set call
		// as a trigger to apply defaults from ScummVM, ignoring the default
		// value that was just received from the game scripts
		if (!_messageTypeSynced || _state->variables[VAR_GLOBAL][kGlobalVarQuit] == TRUE_REG) {
			_messageTypeSynced = true;
			syncAudioOptionsFromScummVM();
			return;
		}

		ConfMan.setBool("subtitles", value.toSint16() & kMessageTypeSubtitles);
		ConfMan.setBool("speech_mute", !(value.toSint16() & kMessageTypeSpeech));
	}
}
Example #20
0
static bool isSaneNodePointer(SegManager *segMan, reg_t addr) {
	bool havePrev = false;
	reg_t prev = addr;

	do {
		Node *node = segMan->lookupNode(addr, false);

		if (!node) {
			if ((g_sci->getGameId() == GID_ICEMAN) && (g_sci->getEngineState()->currentRoomNumber() == 40)) {
				// ICEMAN: when plotting course, unDrawLast is called by startPlot::changeState
				//  there is no previous entry so we get 0 in here
			} else if ((g_sci->getGameId() == GID_HOYLE1) && (g_sci->getEngineState()->currentRoomNumber() == 3)) {
				// HOYLE1: after sorting cards in hearts, in the next round
				// we get an invalid node - bug #3038433
			} else {
				error("isSaneNodePointer: Node at %04x:%04x wasn't found", PRINT_REG(addr));
			}
			return false;
		}

		if (havePrev && node->pred != prev) {
			error("isSaneNodePointer: Node at %04x:%04x points to invalid predecessor %04x:%04x (should be %04x:%04x)",
					PRINT_REG(addr), PRINT_REG(node->pred), PRINT_REG(prev));

			//node->pred = prev;	// fix the problem in the node
			return false;
		}

		prev = addr;
		addr = node->succ;
		havePrev = true;
	} while (!addr.isNull());

	return true;
}
Example #21
0
void GfxAnimate::kernelAnimate(reg_t listReference, bool cycle, int argc, reg_t *argv) {
	byte old_picNotValid = _screen->_picNotValid;

	if (getSciVersion() >= SCI_VERSION_1_1)
		_palette->palVaryUpdate();

	if (listReference.isNull()) {
		disposeLastCast();
		if (_screen->_picNotValid)
			animateShowPic();
		return;
	}

	List *list = _s->_segMan->lookupList(listReference);
	if (!list)
		error("kAnimate called with non-list as parameter");

	if (cycle) {
		if (!invoke(list, argc, argv))
			return;

		// Look up the list again, as it may have been modified
		list = _s->_segMan->lookupList(listReference);
	}

	Port *oldPort = _ports->setPort((Port *)_ports->_picWind);
	disposeLastCast();

	makeSortedList(list);
	fill(old_picNotValid);

	if (old_picNotValid) {
		// beginUpdate()/endUpdate() were introduced SCI1.
		// Calling those for SCI0 will work most of the time but breaks minor
		// stuff like percentage bar of qfg1ega at the character skill screen.
		if (getSciVersion() >= SCI_VERSION_1_EGA_ONLY)
			_ports->beginUpdate(_ports->_picWind);
		update();
		if (getSciVersion() >= SCI_VERSION_1_EGA_ONLY)
			_ports->endUpdate(_ports->_picWind);
	}

	drawCels();

	if (_screen->_picNotValid)
		animateShowPic();

	updateScreen(old_picNotValid);
	restoreAndDelete(argc, argv);

	// We update the screen here as well, some scenes like EQ1 credits run w/o calling kGetEvent thus we wouldn't update
	//  screen at all
	g_sci->getEventManager()->updateScreen();

	_ports->setPort(oldPort);

	// Now trigger speed throttler
	throttleSpeed();
}
Example #22
0
void Object::initSuperClass(SegManager *segMan, reg_t addr) {
	uint16 superClassOffset = getSuperClassSelector().getOffset();

	if (superClassOffset == 0xffff)			// -1
		setSuperClassSelector(NULL_REG);	// no superclass
	else
		setSuperClassSelector(segMan->getClassAddress(superClassOffset, SCRIPT_GET_LOCK, addr.getSegment()));
}
Example #23
0
uint16 Kernel::findRegType(reg_t reg) {
	// No segment? Must be integer
	if (!reg.getSegment())
		return SIG_TYPE_INTEGER | (reg.getOffset() ? 0 : SIG_TYPE_NULL);

	if (reg.getSegment() == 0xFFFF)
		return SIG_TYPE_UNINITIALIZED;

	// Otherwise it's an object
	SegmentObj *mobj = _segMan->getSegmentObj(reg.getSegment());
	if (!mobj)
		return SIG_TYPE_ERROR;

	uint16 result = 0;
	if (!mobj->isValidOffset(reg.getOffset()))
		result |= SIG_IS_INVALID;

	switch (mobj->getType()) {
	case SEG_TYPE_SCRIPT:
		if (reg.getOffset() <= (*(Script *)mobj).getBufSize() &&
			reg.getOffset() >= (uint)-SCRIPT_OBJECT_MAGIC_OFFSET &&
			(*(Script *)mobj).offsetIsObject(reg.getOffset())) {
			result |= ((Script *)mobj)->getObject(reg.getOffset()) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE;
		} else
			result |= SIG_TYPE_REFERENCE;
		break;
	case SEG_TYPE_CLONES:
		result |= SIG_TYPE_OBJECT;
		break;
	case SEG_TYPE_LOCALS:
	case SEG_TYPE_STACK:
	case SEG_TYPE_DYNMEM:
	case SEG_TYPE_HUNK:
#ifdef ENABLE_SCI32
	case SEG_TYPE_ARRAY:
	case SEG_TYPE_STRING:
#endif
		result |= SIG_TYPE_REFERENCE;
		break;
	case SEG_TYPE_LISTS:
		result |= SIG_TYPE_LIST;
		break;
	case SEG_TYPE_NODES:
		result |= SIG_TYPE_NODE;
		break;
	default:
		return SIG_TYPE_ERROR;
	}
	return result;
}
Example #24
0
void GuestAdditions::syncGK2VolumeFromScummVM(const int16 musicVolume) const {
	_state->variables[VAR_GLOBAL][kGlobalVarGK2MusicVolume] = make_reg(0, musicVolume);

	// Calling `setVol` on all sounds is necessary to propagate the volume
	// change to existing sounds, and matches how game scripts propagate
	// volume changes when the in-game music slider is moved
	const reg_t soundsId = _state->variables[VAR_GLOBAL][kGlobalVarSounds];
	if (!soundsId.isNull()) {
		List *sounds = _segMan->lookupList(readSelector(_segMan, soundsId, SELECTOR(elements)));
		reg_t soundId = sounds->first;
		while (!soundId.isNull()) {
			Node *sound = _segMan->lookupNode(soundId);
			reg_t params[] = { make_reg(0, musicVolume) };
			invokeSelector(sound->value, SELECTOR(setVol), 1, params);
			soundId = sound->succ;
		}
	}
}
Example #25
0
reg_t reg_t::operator%(const reg_t right) const {
	if (isNumber() && right.isNumber() && !right.isNull()) {
		// Support for negative numbers was added in Iceman, and perhaps in
		// SCI0 0.000.685 and later. Theoretically, this wasn't really used
		// in SCI0, so the result is probably unpredictable. Such a case
		// would indicate either a script bug, or a modulo on an unsigned
		// integer larger than 32767. In any case, such a case should be
		// investigated, instead of being silently accepted.
		if (getSciVersion() <= SCI_VERSION_0_LATE && (toSint16() < 0 || right.toSint16() < 0))
			warning("Modulo of a negative number has been requested for SCI0. This *could* lead to issues");
		int16 value = toSint16();
		int16 modulo = ABS(right.toSint16());
		int16 result = value % modulo;
		if (result < 0)
			result += modulo;
		return make_reg(0, result);
	} else
		return lookForWorkaround(right, "modulo");
}
Example #26
0
void MessageState::outputString(reg_t buf, const Common::String &str) {
#ifdef ENABLE_SCI32
	if (getSciVersion() >= SCI_VERSION_2) {
		if (_segMan->getSegmentType(buf.getSegment()) == SEG_TYPE_STRING) {
			SciString *sciString = _segMan->lookupString(buf);
			sciString->setSize(str.size() + 1);
			for (uint32 i = 0; i < str.size(); i++)
				sciString->setValue(i, str.c_str()[i]);
			sciString->setValue(str.size(), 0);
		} else if (_segMan->getSegmentType(buf.getSegment()) == SEG_TYPE_ARRAY) {
			// Happens in the intro of LSL6, we are asked to write the string
			// into an array
			SciArray<reg_t> *sciString = _segMan->lookupArray(buf);
			sciString->setSize(str.size() + 1);
			for (uint32 i = 0; i < str.size(); i++)
				sciString->setValue(i, make_reg(0, str.c_str()[i]));
			sciString->setValue(str.size(), NULL_REG);
		}
	} else {
#endif
		SegmentRef buffer_r = _segMan->dereference(buf);

		if ((unsigned)buffer_r.maxSize >= str.size() + 1) {
			_segMan->strcpy(buf, str.c_str());
		} else {
			// LSL6 sets an exit text here, but the buffer size allocated
			// is too small. Don't display a warning in this case, as we
			// don't use the exit text anyway - bug report #3035533
			if (g_sci->getGameId() == GID_LSL6 && str.hasPrefix("\r\n(c) 1993 Sierra On-Line, Inc")) {
				// LSL6 buggy exit text, don't show warning
			} else {
				warning("Message: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(buf), str.size() + 1, str.c_str());
			}

			// Set buffer to empty string if possible
			if (buffer_r.maxSize > 0)
				_segMan->strcpy(buf, "");
		}
#ifdef ENABLE_SCI32
	}
#endif
}
Example #27
0
void GfxPaint16::bitsGetRect(reg_t memoryHandle, Common::Rect *destRect) {
	byte *memoryPtr = NULL;

	if (!memoryHandle.isNull()) {
		memoryPtr = _segMan->getHunkPointer(memoryHandle);

		if (memoryPtr) {
			_screen->bitsGetRect(memoryPtr, destRect);
		}
	}
}
Example #28
0
Common::Array<reg_t> Script::listAllOutgoingReferences(reg_t addr) const {
	Common::Array<reg_t> tmp;
	if (addr.getOffset() <= _buf->size() && addr.getOffset() >= (uint)-SCRIPT_OBJECT_MAGIC_OFFSET && offsetIsObject(addr.getOffset())) {
		const Object *obj = getObject(addr.getOffset());
		if (obj) {
			// Note all local variables, if we have a local variable environment
			if (_localsSegment)
				tmp.push_back(make_reg(_localsSegment, 0));

			for (uint i = 0; i < obj->getVarCount(); i++)
				tmp.push_back(obj->getVariable(i));
		} else {
			error("Request for outgoing script-object reference at %04x:%04x failed in script %d", PRINT_REG(addr), _nr);
		}
	} else {
		/*		warning("Unexpected request for outgoing script-object references at %04x:%04x", PRINT_REG(addr));*/
		/* Happens e.g. when we're looking into strings */
	}
	return tmp;
}
Example #29
0
reg_t kAddBefore(EngineState *s, int argc, reg_t *argv) {
	List *list = s->_segMan->lookupList(argv[0]);
	Node *firstNode = s->_segMan->lookupNode(argv[1]);
	Node *newNode = s->_segMan->lookupNode(argv[2]);

#ifdef CHECK_LISTS
	checkListPointer(s->_segMan, argv[0]);
#endif

	if (!newNode) {
		error("New 'node' %04x:%04x is not a node", PRINT_REG(argv[2]));
		return NULL_REG;
	}

	if (argc != 3 && argc != 4) {
		error("kAddBefore: Haven't got 3 or 4 arguments, aborting");
		return NULL_REG;
	}

	if (argc == 4)
		newNode->key = argv[3];

	if (firstNode) { // We're really appending before
		const reg_t oldPred = firstNode->pred;

		newNode->succ = argv[1];
		firstNode->pred = argv[2];
		newNode->pred = oldPred;

		if (oldPred.isNull())  // Appended before first node?
			// Set new node as first list node
			list->first = argv[2];
		else
			s->_segMan->lookupNode(oldPred)->succ = argv[2];

	} else {
		addToFront(s, argv[0], argv[2]); // Set as initial list node
	}

	return s->r_acc;
}
Example #30
0
void GfxPaint16::bitsRestore(reg_t memoryHandle) {
	byte *memoryPtr = NULL;

	if (!memoryHandle.isNull()) {
		memoryPtr = _segMan->getHunkPointer(memoryHandle);

		if (memoryPtr) {
			_screen->bitsRestore(memoryPtr);
			_segMan->freeHunkEntry(memoryHandle);
		}
	}
}