Ejemplo n.º 1
0
// Program signals that it has written data to the ringbuffer and gets a callback ?
u32 sceMpegRingbufferPut(u32 ringbufferAddr, u32 numPackets, u32 available)
{
	DEBUG_LOG(HLE, "sceMpegRingbufferPut(%08x, %i, %i)", ringbufferAddr, numPackets, available);
	numPackets = std::min(numPackets, available);
	if (numPackets <= 0)
		return 0;

	SceMpegRingBuffer ringbuffer;
	Memory::ReadStruct(ringbufferAddr, &ringbuffer);

	MpegContext *ctx = getMpegCtx(ringbuffer.mpeg);
	if (!ctx) {
		WARN_LOG(HLE, "sceMpegRingbufferPut(%08x, %i, %i): bad mpeg handle %08x", ringbufferAddr, numPackets, available, ringbuffer.mpeg);
		return 0;
	}

	// Execute callback function as a direct MipsCall, no blocking here so no messing around with wait states etc
	if (ringbuffer.callback_addr) {
		PostPutAction *action = (PostPutAction *)__KernelCreateAction(actionPostPut);
		action->setRingAddr(ringbufferAddr);
		// TODO: Should call this multiple times until we get numPackets.
		// Normally this would be if it did not read enough, but also if available > packets.
		// Should ultimately return the TOTAL number of returned packets.
		u32 packetsThisRound = std::min(numPackets, (u32)ringbuffer.packets);
		u32 args[3] = {(u32)ringbuffer.data, packetsThisRound, (u32)ringbuffer.callback_args};
		__KernelDirectMipsCall(ringbuffer.callback_addr, action, args, 3, false);
	} else {
		ERROR_LOG(HLE, "sceMpegRingbufferPut: callback_addr zero");
	}
	return 0;
}
Ejemplo n.º 2
0
// Program signals that it has written data to the ringbuffer and gets a callback ?
u32 sceMpegRingbufferPut(u32 ringbufferAddr, u32 numPackets, u32 available)
{
	DEBUG_LOG(HLE, "sceMpegRingbufferPut(%08x, %i, %i)", ringbufferAddr, numPackets, available);
	numPackets = std::min(numPackets, available);
	if (numPackets <= 0) {
		ERROR_LOG(HLE, "sub-zero number of packets put");
		return 0;
	}

	SceMpegRingBuffer ringbuffer;
	Memory::ReadStruct(ringbufferAddr, &ringbuffer);

	MpegContext *ctx = getMpegCtx(ringbuffer.mpeg);
	if (!ctx) {
		WARN_LOG(HLE, "sceMpegRingbufferPut(%08x, %i, %i): bad mpeg handle %08x", ringbufferAddr, numPackets, available, ringbuffer.mpeg);
		return 0;
	}

	// Clamp to length of mpeg stream - this seems like a hack as we don't have access to the context here really
	int mpegStreamPackets = (ctx->mpegStreamSize + ringbuffer.packetSize - 1) / ringbuffer.packetSize;
	int remainingPackets = mpegStreamPackets - ringbuffer.packetsRead;
	if (remainingPackets < 0) {
		remainingPackets = 0;
	}
	numPackets = std::min(numPackets, (u32)remainingPackets);

	// Execute callback function as a direct MipsCall, no blocking here so no messing around with wait states etc
	if (ringbuffer.callback_addr) {
		PostPutAction *action = (PostPutAction *) __KernelCreateAction(actionPostPut);
		action->setRingAddr(ringbufferAddr);
		u32 args[3] = {(u32)ringbuffer.data, numPackets, (u32)ringbuffer.callback_args};
		__KernelDirectMipsCall(ringbuffer.callback_addr, action, args, 3, false);
	} else {
		ERROR_LOG(HLE, "sceMpegRingbufferPut: callback_addr zero");
	}
	return 0;
}