Exemple #1
0
reg_t SoundCommandParser::kDoSoundSetPriority(int argc, reg_t *argv, reg_t acc) {
	reg_t obj = argv[0];
	int16 value = argv[1].toSint16();

	debugC(kDebugLevelSound, "kDoSound(setPriority): %04x:%04x, %d", PRINT_REG(obj), value);

	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		debugC(kDebugLevelSound, "kDoSound(setPriority): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return acc;
	}

	if (value == -1) {
		uint16 resourceId = musicSlot->resourceId;

		// Set priority from the song data
		Resource *song = _resMan->findResource(ResourceId(kResourceTypeSound, resourceId), 0);
		if (song->data[0] == 0xf0)
			_music->soundSetPriority(musicSlot, song->data[1]);
		else
			warning("kDoSound(setPriority): Attempt to unset song priority when there is no built-in value");

		//pSnd->prio=0;field_15B=0
		writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) & 0xFD);
	} else {
		// Scripted priority

		//pSnd->field_15B=1;
		writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) | 2);
		//DoSOund(0xF,hobj,w)
	}
	return acc;
}
Exemple #2
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;
}
Exemple #3
0
static void addToEnd(EngineState *s, reg_t listRef, reg_t nodeRef) {
	List *list = s->_segMan->lookupList(listRef);
	Node *newNode = s->_segMan->lookupNode(nodeRef);

	debugC(kDebugLevelNodes, "Adding node %04x:%04x to end of list %04x:%04x", PRINT_REG(nodeRef), PRINT_REG(listRef));

	if (!newNode)
		error("Attempt to add non-node (%04x:%04x) to list at %04x:%04x", PRINT_REG(nodeRef), PRINT_REG(listRef));

#ifdef CHECK_LISTS
	checkListPointer(s->_segMan, listRef);
#endif

	newNode->pred = list->last;
	newNode->succ = NULL_REG;

	// Set node to be the first and last node if it's the only node of the list
	if (list->last.isNull())
		list->first = nodeRef;
	else {
		Node *old_n = s->_segMan->lookupNode(list->last);
		old_n->succ = nodeRef;
	}
	list->last = nodeRef;
}
Exemple #4
0
reg_t kFindKey(EngineState *s, int argc, reg_t *argv) {
	reg_t node_pos;
	reg_t key = argv[1];
	reg_t list_pos = argv[0];

	debugC(kDebugLevelNodes, "Looking for key %04x:%04x in list %04x:%04x", PRINT_REG(key), PRINT_REG(list_pos));

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

	node_pos = s->_segMan->lookupList(list_pos)->first;

	debugC(kDebugLevelNodes, "First node at %04x:%04x", PRINT_REG(node_pos));

	while (!node_pos.isNull()) {
		Node *n = s->_segMan->lookupNode(node_pos);
		if (n->key == key) {
			debugC(kDebugLevelNodes, " Found key at %04x:%04x", PRINT_REG(node_pos));
			return node_pos;
		}

		node_pos = n->succ;
		debugC(kDebugLevelNodes, "NextNode at %04x:%04x", PRINT_REG(node_pos));
	}

	debugC(kDebugLevelNodes, "Looking for key without success");
	return NULL_REG;
}
Exemple #5
0
reg_t SoundCommandParser::kDoSoundSendMidi(int argc, reg_t *argv, reg_t acc) {
	reg_t obj = argv[0];
	byte channel = argv[1].toUint16() & 0xf;
	byte midiCmd = argv[2].toUint16() & 0xff;

	// TODO: first there is a 4-parameter variant of this call which needs to get reversed
	//        second the current code isn't 100% accurate, sierra sci does checks on the 4th parameter
	if (argc == 4)
		return acc;

	uint16 controller = argv[3].toUint16();
	uint16 param = argv[4].toUint16();

	debugC(kDebugLevelSound, "kDoSound(sendMidi): %04x:%04x, %d, %d, %d, %d", PRINT_REG(obj), channel, midiCmd, controller, param);
	if (channel)
		channel--; // channel is given 1-based, we are using 0-based

	uint32 midiCommand = (channel | midiCmd) | ((uint32)controller << 8) | ((uint32)param << 16);

	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		// TODO: maybe it's possible to call this with obj == 0:0 and send directly?!
		// if so, allow it
		//_music->sendMidiCommand(_midiCommand);
		warning("kDoSound(sendMidi): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return acc;
	}
	_music->sendMidiCommand(musicSlot, midiCommand);
	return acc;
}
Exemple #6
0
void invokeSelector(EngineState *s, reg_t object, int selectorId,
	int k_argc, StackPtr k_argp, int argc, const reg_t *argv) {
	int i;
	int framesize = 2 + 1 * argc;
	int slc_type;
	StackPtr stackframe = k_argp + k_argc;

	stackframe[0] = make_reg(0, selectorId);  // The selector we want to call
	stackframe[1] = make_reg(0, argc); // Argument count

	slc_type = lookupSelector(s->_segMan, object, selectorId, NULL, NULL);

	if (slc_type == kSelectorNone) {
		error("Selector '%s' of object at %04x:%04x could not be invoked",
		         g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object));
	}
	if (slc_type == kSelectorVariable) {
		error("Attempting to invoke variable selector %s of object %04x:%04x",
			g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object));
	}

	for (i = 0; i < argc; i++)
		stackframe[2 + i] = argv[i]; // Write each argument

	ExecStack *xstack;

	// Now commit the actual function:
	xstack = send_selector(s, object, object, stackframe, framesize, stackframe);

	xstack->sp += argc + 2;
	xstack->fp += argc + 2;

	run_vm(s); // Start a new vm
}
Exemple #7
0
void process_sound_events(EngineState *s) { /* Get all sound events, apply their changes to the heap */
	int result;
	SongHandle handle;
	int cue;

	if (s->_version >= SCI_VERSION_01)
		return;
	/* SCI01 and later explicitly poll for everything */

	while ((result = s->_sound.sfx_poll(&handle, &cue))) {
		reg_t obj = DEFROBNICATE_HANDLE(handle);
		if (!is_object(s, obj)) {
			warning("Non-object %04x:%04x received sound signal (%d/%d)", PRINT_REG(obj), result, cue);
			return;
		}

		switch (result) {

		case SI_LOOP:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x looped (to %d)\n",
			          PRINT_REG(obj), cue);
			/*			PUT_SEL32V(obj, loops, GET_SEL32V(obj, loop) - 1);*/
			PUT_SEL32V(obj, signal, -1);
			break;

		case SI_RELATIVE_CUE:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received relative cue %d\n",
			          PRINT_REG(obj), cue);
			PUT_SEL32V(obj, signal, cue + 0x7f);
			break;

		case SI_ABSOLUTE_CUE:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x received absolute cue %d\n",
			          PRINT_REG(obj), cue);
			PUT_SEL32V(obj, signal, cue);
			break;

		case SI_FINISHED:
			debugC(2, kDebugLevelSound, "[process-sound] Song %04x:%04x finished\n",
			          PRINT_REG(obj));
			PUT_SEL32V(obj, signal, -1);
			PUT_SEL32V(obj, state, _K_SOUND_STATUS_STOPPED);
			break;

		default:
			warning("Unexpected result from sfx_poll: %d", result);
			break;
		}
	}
}
Exemple #8
0
reg_t SoundCommandParser::kDoSoundSetHold(int argc, reg_t *argv, reg_t acc) {
	reg_t obj = argv[0];

	debugC(kDebugLevelSound, "doSoundSetHold: %04x:%04x, %d", PRINT_REG(argv[0]), argv[1].toUint16());

	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		warning("kDoSound(setHold): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return acc;
	}

	// Set the special hold marker ID where the song should be looped at.
	musicSlot->hold = argv[1].toSint16();
	return acc;
}
Exemple #9
0
void writeSelector(SegManager *segMan, reg_t object, Selector selectorId, reg_t value) {
	ObjVarRef address;

	if ((selectorId < 0) || (selectorId > (int)g_sci->getKernel()->getSelectorNamesSize())) {
		error("Attempt to write to invalid selector %d of"
		         " object at %04x:%04x.", selectorId, PRINT_REG(object));
		return;
	}

	if (lookupSelector(segMan, object, selectorId, &address, NULL) != kSelectorVariable)
		error("Selector '%s' of object at %04x:%04x could not be"
		         " written to", g_sci->getKernel()->getSelectorName(selectorId).c_str(), PRINT_REG(object));
	else
		*address.getPointer(segMan) = value;
}
Exemple #10
0
reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness) {
	Plane *plane = g_sci->_gfxFrameout->getPlanes().findByObject(planeObject);
	if (plane == nullptr) {
		error("kAddLine: Plane %04x:%04x not found", PRINT_REG(planeObject));
	}

	Common::Rect gameRect;
	reg_t bitmapId = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);

	CelInfo32 celInfo;
	celInfo.type = kCelTypeMem;
	celInfo.bitmap = bitmapId;
	// SSCI stores the line color on `celInfo`, even though
	// this is not a `kCelTypeColor`, as a hack so that
	// `kUpdateLine` can get the originally used color
	celInfo.color = color;

	ScreenItem *screenItem = new ScreenItem(planeObject, celInfo, gameRect);
	screenItem->_priority = priority;
	screenItem->_fixedPriority = true;

	plane->_screenItemList.add(screenItem);

	return screenItem->_object;
}
Exemple #11
0
void SoundCommandParser::processStopSound(reg_t obj, bool sampleFinishedPlaying) {
	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		warning("kDoSound(stop): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return;
	}

	if (_soundVersion <= SCI_VERSION_0_LATE) {
		writeSelectorValue(_segMan, obj, SELECTOR(state), kSoundStopped);
	} else {
		writeSelectorValue(_segMan, obj, SELECTOR(handle), 0);
	}

	// Set signal selector in sound SCI0 games only, when the sample has
	// finished playing. If we don't set it at all, we get a problem when using
	// vaporizer on the 2 guys. If we set it all the time, we get no music in
	// sq3new and kq1.
	// FIXME: This *may* be wrong, it's impossible to find out in Sierra DOS
	//        SCI, because SCI0 under DOS didn't have sfx drivers included.
	// We need to set signal in sound SCI1+ games all the time.
	if ((_soundVersion > SCI_VERSION_0_LATE) || sampleFinishedPlaying)
		writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);

	musicSlot->dataInc = 0;
	musicSlot->signal = SIGNAL_OFFSET;
	_music->soundStop(musicSlot);
}
Exemple #12
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(getSegment());

		if (!mobj)
			error("[VM]: Attempt to add %d to invalid pointer %04x:%04x", right.getOffset(), 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(getSegment(), getOffset() + right.toSint16());
		default:
			return lookForWorkaround(right, "addition");
		}
	} 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, "addition");
	}
}
Exemple #13
0
void GfxFrameout::printPlaneList(Console *con) {
	for (PlaneList::const_iterator it = _planes.begin(); it != _planes.end(); ++it) {
		PlaneEntry p = *it;
		Common::String curPlaneName = _segMan->getObjectName(p.object);
		Common::Rect r = p.upscaledPlaneRect;
		Common::Rect cr = p.upscaledPlaneClipRect;

		con->DebugPrintf("%04x:%04x (%s): prio %d, lastprio %d, offsetX %d, offsetY %d, pic %d, mirror %d, back %d\n",
							PRINT_REG(p.object), curPlaneName.c_str(),
							(int16)p.priority, (int16)p.lastPriority,
							p.planeOffsetX, p.planeOffsetY, p.pictureId,
							p.planePictureMirrored, p.planeBack);
		con->DebugPrintf("  rect: (%d, %d, %d, %d), clip rect: (%d, %d, %d, %d)\n",
							r.left, r.top, r.right, r.bottom,
							cr.left, cr.top, cr.right, cr.bottom);

		if (p.pictureId != 0xffff && p.pictureId != 0xfffe) {
			con->DebugPrintf("Pictures:\n");

			for (PlanePictureList::iterator pictureIt = _planePictures.begin(); pictureIt != _planePictures.end(); pictureIt++) {
				if (pictureIt->object == p.object) {
					con->DebugPrintf("    Picture %d: x %d, y %d\n", pictureIt->pictureId, pictureIt->startX, pictureIt->startY);
				}
			}
		}
	}
}
Exemple #14
0
void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) {
#ifdef GC_DEBUG
	Object *victim_obj = &(_table[addr.offset]);

	if (!(victim_obj->_flags & OBJECT_FLAG_FREED))
		warning("[GC] Clone %04x:%04x not reachable and not freed (freeing now)", PRINT_REG(addr));
#ifdef GC_DEBUG_VERBOSE
	else
		warning("[GC-DEBUG] Clone %04x:%04x: Freeing", PRINT_REG(addr));

	warning("[GC] Clone had pos %04x:%04x", PRINT_REG(victim_obj->pos));
#endif
#endif

	freeEntry(addr.offset);
}
Exemple #15
0
reg_t kListAt(EngineState *s, int argc, reg_t *argv) {
	if (argc != 2) {
		error("kListAt called with %d parameters", argc);
		return NULL_REG;
	}

	List *list = s->_segMan->lookupList(argv[0]);
	reg_t curAddress = list->first;
	if (list->first.isNull()) {
		error("kListAt tried to reference empty list (%04x:%04x)", PRINT_REG(argv[0]));
		return NULL_REG;
	}
	Node *curNode = s->_segMan->lookupNode(curAddress);
	reg_t curObject = curNode->value;
	int16 listIndex = argv[1].toUint16();
	int curIndex = 0;

	while (curIndex != listIndex) {
		if (curNode->succ.isNull()) {	// end of the list?
			return NULL_REG;
		}

		curAddress = curNode->succ;
		curNode = s->_segMan->lookupNode(curAddress);
		curObject = curNode->value;

		curIndex++;
	}

	return curObject;
}
Exemple #16
0
SegmentRef LocalVariables::dereference(reg_t pointer) {
	SegmentRef ret;
	ret.isRaw = false;	// reg_t based data!
	ret.maxSize = (_locals.size() - pointer.offset / 2) * 2;

	if (pointer.offset & 1) {
		ret.maxSize -= 1;
		ret.skipByte = true;
	}

	if (ret.maxSize > 0) {
		ret.reg = &_locals[pointer.offset / 2];
	} else {
		if ((g_sci->getEngineState()->currentRoomNumber() == 160 ||
			 g_sci->getEngineState()->currentRoomNumber() == 220)
			&& g_sci->getGameId() == GID_LAURABOW2) {
			// WORKAROUND: Happens in two places during the intro of LB2CD, both
			// from kMemory(peek):
			// - room 160: Heap 160 has 83 local variables (0-82), and the game
			//   asks for variables at indices 83 - 90 too.
			// - room 220: Heap 220 has 114 local variables (0-113), and the
			//   game asks for variables at indices 114-120 too.
		} else {
			error("LocalVariables::dereference: Offset at end or out of bounds %04x:%04x", PRINT_REG(pointer));
		}
		ret.reg = 0;
	}
	return ret;
}
Exemple #17
0
reg_t SoundCommandParser::kDoSoundSetLoop(int argc, reg_t *argv, reg_t acc) {
	reg_t obj = argv[0];
	int16 value = argv[1].toSint16();

	debugC(kDebugLevelSound, "kDoSound(setLoop): %04x:%04x, %d", PRINT_REG(obj), value);

	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		// Apparently, it's perfectly normal for a game to call cmdSetSoundLoop
		// before actually initializing the sound and adding it to the playlist
		// with cmdInitSound. Usually, it doesn't matter if the game doesn't
		// request to loop the sound, so in this case, don't throw any warning,
		// otherwise do, because the sound won't be looped.
		if (value == -1) {
			warning("kDoSound(setLoop): Slot not found (%04x:%04x) and the song was requested to be looped", PRINT_REG(obj));
		} else {
			// Doesn't really matter
		}
		return acc;
	}
	if (value == -1) {
		musicSlot->loop = 0xFFFF;
	} else {
		musicSlot->loop = 1; // actually plays the music once
	}

	writeSelectorValue(_segMan, obj, SELECTOR(loop), musicSlot->loop);
	return acc;
}
Exemple #18
0
reg_t kClone(EngineState *s, int argc, reg_t *argv) {
	reg_t parentAddr = argv[0];
	const Object *parentObj = s->_segMan->getObject(parentAddr);
	reg_t cloneAddr;
	Clone *cloneObj; // same as Object*

	if (!parentObj) {
		error("Attempt to clone non-object/class at %04x:%04x failed", PRINT_REG(parentAddr));
		return NULL_REG;
	}

	debugC(kDebugLevelMemory, "Attempting to clone from %04x:%04x", PRINT_REG(parentAddr));

	uint16 infoSelector = parentObj->getInfoSelector().toUint16();
	cloneObj = s->_segMan->allocateClone(&cloneAddr);

	if (!cloneObj) {
		error("Cloning %04x:%04x failed-- internal error", PRINT_REG(parentAddr));
		return NULL_REG;
	}

	// In case the parent object is a clone itself we need to refresh our
	// pointer to it here. This is because calling allocateClone might
	// invalidate all pointers, references and iterators to data in the clones
	// segment.
	//
	// The reason why it might invalidate those is, that the segment code
	// (Table) uses Common::Array for internal storage. Common::Array now
	// might invalidate references to its contained data, when it has to
	// extend the internal storage size.
	if (infoSelector & kInfoFlagClone)
		parentObj = s->_segMan->getObject(parentAddr);

	*cloneObj = *parentObj;

	// Mark as clone
	infoSelector &= ~kInfoFlagClass; // remove class bit
	cloneObj->setInfoSelector(make_reg(0, infoSelector | kInfoFlagClone));

	cloneObj->setSpeciesSelector(cloneObj->getPos());
	if (parentObj->isClass())
		cloneObj->setSuperClassSelector(parentObj->getPos());
	s->_segMan->getScript(parentObj->getPos().getSegment())->incrementLockers();
	s->_segMan->getScript(cloneObj->getPos().getSegment())->incrementLockers();

	return cloneAddr;
}
Exemple #19
0
reg_t SoundCommandParser::kDoSoundPlay(EngineState *s, int argc, reg_t *argv) {
	debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x", PRINT_REG(argv[0]));
	bool playBed = false;
	if (argc >= 2 && !argv[1].isNull())
		playBed = true;
	processPlaySound(argv[0], playBed);
	return s->r_acc;
}
Exemple #20
0
reg_t kNewList(EngineState *s, int argc, reg_t *argv) {
	reg_t listRef;
	List *list = s->_segMan->allocateList(&listRef);
	list->first = list->last = NULL_REG;
	debugC(kDebugLevelNodes, "New listRef at %04x:%04x", PRINT_REG(listRef));

	return listRef; // Return list base address
}
Exemple #21
0
reg_t SoundCommandParser::kDoSoundPause(int argc, reg_t *argv, reg_t acc) {
	if (argc == 1)
		debugC(kDebugLevelSound, "kDoSound(pause): %04x:%04x", PRINT_REG(argv[0]));
	else
		debugC(kDebugLevelSound, "kDoSound(pause): %04x:%04x, %04x:%04x", PRINT_REG(argv[0]), PRINT_REG(argv[1]));

	if (_soundVersion <= SCI_VERSION_0_LATE) {
		// SCI0 games give us 0/1 for either resuming or pausing the current music
		//  this one doesn't count, so pausing 2 times and resuming once means here that we are supposed to resume
		uint16 value = argv[0].toUint16();
		MusicEntry *musicSlot = _music->getActiveSci0MusicSlot();
		switch (value) {
		case 1:
			if ((musicSlot) && (musicSlot->status == kSoundPlaying)) {
				_music->soundPause(musicSlot);
				writeSelectorValue(_segMan, musicSlot->soundObj, SELECTOR(state), kSoundPaused);
			}
			return make_reg(0, 0);
		case 0:
			if ((musicSlot) && (musicSlot->status == kSoundPaused)) {
				_music->soundResume(musicSlot);
				writeSelectorValue(_segMan, musicSlot->soundObj, SELECTOR(state), kSoundPlaying);
				return make_reg(0, 1);
			}
			return make_reg(0, 0);
		default:
			error("kDoSound(pause): parameter 0 is invalid for sound-sci0");
		}
	}

	reg_t obj = argv[0];
	uint16 value = argc > 1 ? argv[1].toUint16() : 0;
	if (!obj.segment) {		// pause the whole playlist
		_music->pauseAll(value);
	} else {	// pause a playlist slot
		MusicEntry *musicSlot = _music->getSlot(obj);
		if (!musicSlot) {
			// This happens quite frequently
			debugC(kDebugLevelSound, "kDoSound(pause): Slot not found (%04x:%04x)", PRINT_REG(obj));
			return acc;
		}

		_music->soundToggle(musicSlot, value);
	}
	return acc;
}
Exemple #22
0
void ScreenItem::update() {
	Plane *plane = g_sci->_gfxFrameout->getPlanes().findByObject(_plane);
	if (plane == nullptr) {
		error("ScreenItem::update: Invalid plane %04x:%04x", PRINT_REG(_plane));
	}

	if (plane->_screenItemList.findByObject(_object) == nullptr) {
		error("ScreenItem::update: %04x:%04x not in plane %04x:%04x", PRINT_REG(_object), PRINT_REG(_plane));
	}

	if (!_created) {
		_updated = g_sci->_gfxFrameout->getScreenCount();
	}
	_deleted = 0;

	delete _celObj;
	_celObj = nullptr;
}
Exemple #23
0
void nrf24_print_status()
{
  uint8_t status = nrf24_read_reg(STATUS);
  PRINT_REG(STATUS);
  PRINT_REG_BIT("TX_FULL", status, TX_FULL_STATUS);
  PRINT_REG_BIT("MAX_RT", status, MAX_RT);
  PRINT_REG_BIT("TX_DS", status, TX_DS);
  PRINT_REG_BIT("RX_DR", status, RX_DR);
}
Exemple #24
0
void SciMusic::sendMidiCommand(MusicEntry *pSnd, uint32 cmd) {
	Common::StackLock lock(_mutex);
	if (!pSnd->pMidiParser)
		error("tried to cmdSendMidi on non midi slot (%04x:%04x)", PRINT_REG(pSnd->soundObj));

	pSnd->pMidiParser->mainThreadBegin();
	pSnd->pMidiParser->sendFromScriptToDriver(cmd);
	pSnd->pMidiParser->mainThreadEnd();
}
Exemple #25
0
void nrf24_print_fifo_status()
{
  uint8_t fifo_status = nrf24_read_reg(FIFO_STATUS);
  PRINT_REG(FIFO_STATUS);
  PRINT_REG_BIT("RX_EMPTY", fifo_status, RX_EMPTY);
  PRINT_REG_BIT("RX_FULL", fifo_status, RX_FULL);
  PRINT_REG_BIT("TX_EMPTY", fifo_status, TX_EMPTY);
  PRINT_REG_BIT("TX_FULL", fifo_status, TX_FULL_FIFO);
}
Exemple #26
0
void run_gc(EngineState *s) {
	SegManager *segMan = s->_segMan;

	// Some debug stuff
	debugC(kDebugLevelGC, "[GC] Running...");
#ifdef GC_DEBUG_CODE
	const char *segnames[SEG_TYPE_MAX + 1];
	int segcount[SEG_TYPE_MAX + 1];
	memset(segnames, 0, sizeof(segnames));
	memset(segcount, 0, sizeof(segcount));
#endif

	// Compute the set of all segments references currently in use.
	AddrSet *activeRefs = findAllActiveReferences(s);

	// Iterate over all segments, and check for each whether it
	// contains stuff that can be collected.
	const Common::Array<SegmentObj *> &heap = segMan->getSegments();
	for (uint seg = 1; seg < heap.size(); seg++) {
		SegmentObj *mobj = heap[seg];

		if (mobj != NULL) {
#ifdef GC_DEBUG_CODE
			const SegmentType type = mobj->getType();
			segnames[type] = segmentTypeNames[type];
#endif

			// Get a list of all deallocatable objects in this segment,
			// then free any which are not referenced from somewhere.
			const Common::Array<reg_t> tmp = mobj->listAllDeallocatable(seg);
			for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) {
				const reg_t addr = *it;
				if (!activeRefs->contains(addr)) {
					// Not found -> we can free it
					mobj->freeAtAddress(segMan, addr);
					debugC(kDebugLevelGC, "[GC] Deallocating %04x:%04x", PRINT_REG(addr));
#ifdef GC_DEBUG_CODE
					segcount[type]++;
#endif
				}
			}

		}
	}

	delete activeRefs;

#ifdef GC_DEBUG_CODE
	// Output debug summary of garbage collection
	debugC(kDebugLevelGC, "[GC] Summary:");
	for (int i = 0; i <= SEG_TYPE_MAX; i++)
		if (segcount[i])
			debugC(kDebugLevelGC, "\t%d\t* %s", segcount[i], segnames[i]);
#endif
}
Exemple #27
0
reg_t SoundCommandParser::kDoSoundUpdate(EngineState *s, int argc, reg_t *argv) {
	reg_t obj = argv[0];

	debugC(kDebugLevelSound, "kDoSound(update): %04x:%04x", PRINT_REG(argv[0]));

	MusicEntry *musicSlot = _music->getSlot(obj);
	if (!musicSlot) {
		warning("kDoSound(update): Slot not found (%04x:%04x)", PRINT_REG(obj));
		return s->r_acc;
	}

	musicSlot->loop = readSelectorValue(_segMan, obj, SELECTOR(loop));
	int16 objVol = CLIP<int>(readSelectorValue(_segMan, obj, SELECTOR(vol)), 0, 255);
	if (objVol != musicSlot->volume)
		_music->soundSetVolume(musicSlot, objVol);
	int16 objPrio = readSelectorValue(_segMan, obj, SELECTOR(priority));
	if (objPrio != musicSlot->priority)
		_music->soundSetPriority(musicSlot, objPrio);
	return s->r_acc;
}
Exemple #28
0
reg_t kNewNode(EngineState *s, int argc, reg_t *argv) {
	reg_t nodeValue = argv[0];
	// Some SCI32 games call this with 1 parameter (e.g. the demo of Phantasmagoria).
	// Set the key to be the same as the value in this case
	reg_t nodeKey = (argc == 2) ? argv[1] : argv[0];
	s->r_acc = s->_segMan->newNode(nodeValue, nodeKey);

	debugC(kDebugLevelNodes, "New nodeRef at %04x:%04x", PRINT_REG(s->r_acc));

	return s->r_acc;
}
Exemple #29
0
void SciMusic::printPlayList(Console *con) {
	Common::StackLock lock(_mutex);

	const char *musicStatus[] = { "Stopped", "Initialized", "Paused", "Playing" };

	for (uint32 i = 0; i < _playList.size(); i++) {
		MusicEntry *song = _playList[i];
		con->DebugPrintf("%d: %04x:%04x, resource id: %d, status: %s, %s type\n", i,
						PRINT_REG(song->soundObj), song->resourceId,
						musicStatus[song->status], song->pMidiParser ? "MIDI" : "digital audio");
	}
}
Exemple #30
0
void WorklistManager::push(reg_t reg) {
	if (!reg.getSegment()) // No numbers
		return;

	debugC(kDebugLevelGC, "[GC] Adding %04x:%04x", PRINT_REG(reg));

	if (_map.contains(reg))
		return; // already dealt with it

	_map.setVal(reg, true);
	_worklist.push_back(reg);
}