// 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; }
FontLib(u32 paramPtr) : fontHRes_(128.0f), fontVRes_(128.0f) { Memory::ReadStruct(paramPtr, ¶ms_); // We use the same strange scheme that JPCSP uses. u32 allocSize = 4 + 4 * params_.numFonts; PostAllocCallback *action = (PostAllocCallback *) __KernelCreateAction(actionPostAllocCallback); action->SetFontLib(GetListID()); u32 args[2] = { params_.userDataAddr, allocSize }; __KernelDirectMipsCall(params_.allocFuncAddr, action, args, 2, true); }
// 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; }