Ejemplo n.º 1
0
int sceDisplayAdjustAccumulatedHcount(int value) {
	if (value < 0) {
		ERROR_LOG_REPORT(SCEDISPLAY, "sceDisplayAdjustAccumulatedHcount(%d): invalid value", value);
		return SCE_KERNEL_ERROR_INVALID_VALUE;
	}

	// Since it includes the current hCount, find the difference to apply to the base.
	u32 accumHCount = __DisplayGetAccumulatedHcount();
	int diff = value - accumHCount;
	hCountBase += diff;

	DEBUG_LOG(SCEDISPLAY, "sceDisplayAdjustAccumulatedHcount(%d)", value);
	return 0;
}
Ejemplo n.º 2
0
void GPUCommon::ProcessEvent(GPUEvent ev) {
	switch (ev.type) {
	case GPU_EVENT_PROCESS_QUEUE:
		ProcessDLQueueInternal();
		break;

	case GPU_EVENT_REAPPLY_GFX_STATE:
		ReapplyGfxStateInternal();
		break;

	default:
		ERROR_LOG_REPORT(G3D, "Unexpected GPU event type: %d", (int)ev);
	}
}
Ejemplo n.º 3
0
MpegContext *getMpegCtx(u32 mpegAddr) {
	u32 mpeg = Memory::Read_U32(mpegAddr);

	// TODO: Remove.
	if (mpegMap.find(mpeg) == mpegMap.end())
	{
		ERROR_LOG_REPORT(HLE, "Bad mpeg handle %08x - using last one (%08x) instead", mpeg, lastMpegHandle);
		mpeg = lastMpegHandle;
	}

	if (mpegMap.find(mpeg) == mpegMap.end())
		return NULL;
	return mpegMap[mpeg];
}
Ejemplo n.º 4
0
void __KernelEventFlagBeginCallback(SceUID threadID, SceUID prevCallbackId)
{
	SceUID pauseKey = prevCallbackId == 0 ? threadID : prevCallbackId;

	u32 error;
	SceUID flagID = __KernelGetWaitID(threadID, WAITTYPE_EVENTFLAG, error);
	u32 timeoutPtr = __KernelGetWaitTimeoutPtr(threadID, error);
	EventFlag *flag = flagID == 0 ? NULL : kernelObjects.Get<EventFlag>(flagID, error);
	if (flag)
	{

		// This means two callbacks in a row.  PSP crashes if the same callback runs inside itself.
		// TODO: Handle this better?
		if (flag->pausedWaits.find(pauseKey) != flag->pausedWaits.end())
			return;

		EventFlagTh waitData = {0};
		for (size_t i = 0; i < flag->waitingThreads.size(); i++)
		{
			EventFlagTh *t = &flag->waitingThreads[i];
			if (t->tid == threadID)
			{
				waitData = *t;
				// TODO: Hmm, what about priority/fifo order?  Does it lose its place in line?
				flag->waitingThreads.erase(flag->waitingThreads.begin() + i);
				break;
			}
		}

		if (waitData.tid != threadID)
		{
			ERROR_LOG_REPORT(HLE, "sceKernelWaitEventFlagCB: wait not found to pause for callback");
			return;
		}

		if (timeoutPtr != 0 && eventFlagWaitTimer != -1)
		{
			s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventFlagWaitTimer, threadID);
			waitData.pausedTimeout = CoreTiming::GetTicks() + cyclesLeft;
		}
		else
			waitData.pausedTimeout = 0;

		flag->pausedWaits[pauseKey] = waitData;
		DEBUG_LOG(HLE, "sceKernelWaitEventFlagCB: Suspending lock wait for callback");
	}
	else
		WARN_LOG_REPORT(HLE, "sceKernelWaitEventFlagCB: beginning callback with bad wait id?");
}
Ejemplo n.º 5
0
int sceKernelVolatileMemUnlock(int type) {
	if (type != 0) {
		ERROR_LOG_REPORT(HLE, "sceKernelVolatileMemUnlock(%i) - invalid mode", type);
		return SCE_KERNEL_ERROR_INVALID_MODE;
	}
	if (volatileMemLocked) {
		volatileMemLocked = false;

		// Wake someone, always fifo.
		bool wokeThreads = false;
		u32 error;
		while (!volatileWaitingThreads.empty() && !volatileMemLocked) {
			VolatileWaitingThread waitInfo = volatileWaitingThreads.front();
			volatileWaitingThreads.erase(volatileWaitingThreads.begin());

			int waitID = __KernelGetWaitID(waitInfo.threadID, WAITTYPE_VMEM, error);
			// If they were force-released, just skip.
			if (waitID == 1 && __KernelVolatileMemLock(0, waitInfo.addrPtr, waitInfo.sizePtr) == 0) {
				__KernelResumeThreadFromWait(waitInfo.threadID, 0);
				wokeThreads = true;
			}
		}

		if (wokeThreads) {
			INFO_LOG(HLE, "sceKernelVolatileMemUnlock(%i) handed over to another thread", type);
			hleReSchedule("volatile mem unlocked");
		} else {
			DEBUG_LOG(HLE, "sceKernelVolatileMemUnlock(%i)", type);
		}
	} else {
		ERROR_LOG_REPORT(HLE, "sceKernelVolatileMemUnlock(%i) FAILED - not locked", type);
		// I guess it must use a sema.
		return SCE_KERNEL_ERROR_SEMA_OVF;
	}
	return 0;
}
Ejemplo n.º 6
0
int sceAudiocodecInit(u32 ctxPtr, int codec) {
	if (isValidCodec(codec)) {
		// Create audio decoder for given audio codec and push it into AudioList
		if (removeDecoder(ctxPtr)) {
			WARN_LOG_REPORT(HLE, "sceAudiocodecInit(%08x, %d): replacing existing context", ctxPtr, codec);
		}
		auto decoder = new SimpleAudio(ctxPtr, codec);
		audioList[ctxPtr] = decoder;
		INFO_LOG(ME, "sceAudiocodecInit(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
		DEBUG_LOG(ME, "Number of playing sceAudioCodec audios : %d", (int)audioList.size());
		return 0;
	}
	ERROR_LOG_REPORT(ME, "sceAudiocodecInit(%08x, %i (%s)): Unknown audio codec %i", ctxPtr, codec, GetCodecName(codec), codec);
	return 0;
}
Ejemplo n.º 7
0
size_t DirectoryFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size, int &usec) {
	EntryMap::iterator iter = entries.find(handle);
	if (iter != entries.end()) {
		if (size < 0) {
			ERROR_LOG_REPORT(FILESYS, "Invalid read for %lld bytes from disk %s", size, iter->second.guestFilename.c_str());
			return 0;
		}

		size_t bytesRead = iter->second.hFile.Read(pointer,size);
		return bytesRead;
	} else {
		//This shouldn't happen...
		ERROR_LOG(FILESYS,"Cannot read file that hasn't been opened: %08x", handle);
		return 0;
	}
}
Ejemplo n.º 8
0
void ApplyPrefixST(float *v, u32 data, VectorSize size)
{
	// Possible optimization shortcut:
	if (data == 0xe4)
		return;

	int n = GetNumVectorElements(size);
	float origV[4];
	static const float constantArray[8] = {0.f, 1.f, 2.f, 0.5f, 3.f, 1.f/3.f, 0.25f, 1.f/6.f};

	for (int i = 0; i < n; i++)
	{
		origV[i] = v[i];
	}

	for (int i = 0; i < n; i++)
	{
		int regnum = (data >> (i*2)) & 3;
		int abs    = (data >> (8+i)) & 1;
		int negate = (data >> (16+i)) & 1;
		int constants = (data >> (12+i)) & 1;

		if (!constants)
		{
			// Prefix may say "z, z, z, z" but if this is a pair, we force to x.
			// TODO: But some ops seem to use const 0 instead?
			if (regnum >= n) {
				ERROR_LOG_REPORT(CPU, "Invalid VFPU swizzle: %08x: %i / %d at PC = %08x (%s)", data, regnum, n, currentMIPS->pc, currentMIPS->DisasmAt(currentMIPS->pc));
				//for (int i = 0; i < 12; i++) {
				//	ERROR_LOG(CPU, "  vfpuCtrl[%i] = %08x", i, currentMIPS->vfpuCtrl[i]);
				//}
				regnum = 0;
			}

			v[i] = origV[regnum];
			if (abs)
				v[i] = fabs(v[i]);
		}
		else
		{
			v[i] = constantArray[regnum + (abs<<2)];
		}

		if (negate)
			v[i] = -v[i];
	}
}
Ejemplo n.º 9
0
int sceKernelAllocateTls(SceUID uid)
{
	// TODO: Allocate downward if PSP_TLS_ATTR_HIGHMEM?
	DEBUG_LOG(HLE, "sceKernelAllocateTls(%08x)", uid);
	u32 error;
	TLS *tls = kernelObjects.Get<TLS>(uid, error);
	if (tls)
	{
		SceUID threadID = __KernelGetCurThread();
		int allocBlock = -1;

		// If the thread already has one, return it.
		for (size_t i = 0; i < tls->ntls.totalBlocks && allocBlock == -1; ++i)
		{
			if (tls->usage[i] == threadID)
				allocBlock = (int) i;
		}

		if (allocBlock == -1)
		{
			for (size_t i = 0; i < tls->ntls.totalBlocks && allocBlock == -1; ++i)
			{
				// The PSP doesn't give the same block out twice in a row, even if freed.
				if (tls->usage[tls->next] == 0)
					allocBlock = tls->next;
				tls->next = (tls->next + 1) % tls->ntls.blockSize;
			}

			if (allocBlock != -1)
			{
				tls->usage[allocBlock] = threadID;
				--tls->ntls.freeBlocks;
			}
		}

		if (allocBlock == -1)
		{
			// TODO: Wait here, wake when one is free.
			ERROR_LOG_REPORT(HLE, "sceKernelAllocateTls: should wait");
			return -1;
		}

		return tls->address + allocBlock * tls->ntls.blockSize;
	}
	else
		return error;
}
Ejemplo n.º 10
0
int sceFontGetCharGlyphImage_Clip(u32 fontHandle, u32 charCode, u32 glyphImagePtr, int clipXPos, int clipYPos, int clipWidth, int clipHeight) {
	if (!Memory::IsValidAddress(glyphImagePtr)) {
		ERROR_LOG(HLE, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i): bad glyphImage pointer", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight);
		return ERROR_FONT_INVALID_PARAMETER;
	}
	LoadedFont *font = GetLoadedFont(fontHandle, false);
	if (!font) {
		ERROR_LOG_REPORT(HLE, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i): bad font", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight);
		return ERROR_FONT_INVALID_PARAMETER;
	}

	INFO_LOG(HLE, "sceFontGetCharGlyphImage_Clip(%08x, %i, %08x, %i, %i, %i, %i)", fontHandle, charCode, glyphImagePtr, clipXPos, clipYPos, clipWidth, clipHeight);
	auto glyph = Memory::GetStruct<const GlyphImage>(glyphImagePtr);
	int altCharCode = font->GetFontLib()->GetAltCharCode();
	font->GetPGF()->DrawCharacter(glyph, clipXPos, clipYPos, clipXPos + clipWidth, clipYPos + clipHeight, charCode, altCharCode, FONT_PGF_CHARGLYPH);
	return 0;
}
Ejemplo n.º 11
0
u32 sceUtilityLoadModule(u32 module)
{
	// TODO: Not all modules between 0x100 and 0x601 are valid.
	if (module < 0x100 || module > 0x601)
	{
		ERROR_LOG_REPORT(HLE, "sceUtilityLoadModule(%i): invalid module id", module);
		return SCE_ERROR_MODULE_BAD_ID;
	}

	DEBUG_LOG(HLE, "sceUtilityLoadModule(%i)", module);
	// TODO: Each module has its own timing, technically, but this is a low-end.
	// Note: Some modules have dependencies, but they still resched.
	if (module == 0x3FF)
		return hleDelayResult(0, "utility module loaded", 130);
	else
		return hleDelayResult(0, "utility module loaded", 25000);
}
Ejemplo n.º 12
0
u32 sceUtilityUnloadModule(u32 module)
{
	// TODO: Not all modules between 0x100 and 0x601 are valid.
	if (module < 0x100 || module > 0x601)
	{
		ERROR_LOG_REPORT(HLE, "sceUtilityUnloadModule(%i): invalid module id", module);
		return SCE_ERROR_MODULE_BAD_ID;
	}

	DEBUG_LOG(HLE, "sceUtilityUnloadModule(%i)", module);
	// TODO: Each module has its own timing, technically, but this is a low-end.
	// Note: If not loaded, it should not reschedule actually...
	if (module == 0x3FF)
		return hleDelayResult(0, "utility module unloaded", 110);
	else
		return hleDelayResult(0, "utility module unloaded", 400);
}
Ejemplo n.º 13
0
int sceFontGetCharGlyphImage(u32 fontHandle, u32 charCode, u32 glyphImagePtr) {
	if (!Memory::IsValidAddress(glyphImagePtr)) {
		ERROR_LOG(HLE, "sceFontGetCharGlyphImage(%x, %x, %x): bad glyphImage pointer", fontHandle, charCode, glyphImagePtr);
		return ERROR_FONT_INVALID_PARAMETER;
	}
	LoadedFont *font = GetLoadedFont(fontHandle, false);
	if (!font) {
		ERROR_LOG_REPORT(HLE, "sceFontGetCharGlyphImage(%x, %x, %x): bad font", fontHandle, charCode, glyphImagePtr);
		return ERROR_FONT_INVALID_PARAMETER;
	}

	DEBUG_LOG(HLE, "sceFontGetCharGlyphImage(%x, %x, %x)", fontHandle, charCode, glyphImagePtr);
	auto glyph = Memory::GetStruct<const GlyphImage>(glyphImagePtr);
	int altCharCode = font->GetFontLib()->GetAltCharCode();
	font->GetPGF()->DrawCharacter(glyph, 0, 0, 8192, 8192, charCode, altCharCode, FONT_PGF_CHARGLYPH);
	return 0;
}
Ejemplo n.º 14
0
int MediaEngine::getAudioSamples(u32 bufferPtr) {
	if (!Memory::IsValidAddress(bufferPtr)) {
		ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr);
	}

	u8 *buffer = Memory::GetPointer(bufferPtr);
	if (!m_demux) {
		return 0;
	}

	// When m_demux , increment pts 
	m_audiopts += 4180;
	
	// Demux now (rather than on add data) so that we select the right stream.
	m_demux->demux(m_audioStream);

	u8 *audioFrame = 0;
	int headerCode1, headerCode2;
	int frameSize = m_demux->getNextaudioFrame(&audioFrame, &headerCode1, &headerCode2);
	if (frameSize == 0) {
		m_noAudioData = true;
		return 0;
	}
	int outbytes = 0;

	if (m_audioContext != NULL) {
		if (!AudioDecode(m_audioContext, audioFrame, frameSize, &outbytes, buffer)) {
			ERROR_LOG(ME, "Audio (%s) decode failed during video playback", GetCodecName(m_audioType));
		}
	}

	if (headerCode1 == 0x24) {
		// it a mono atrac3plus, convert it to stereo
		s16 *outbuf = (s16*)buffer;
		s16 *inbuf = (s16*)buffer;
		for (int i = 0x800 - 1; i >= 0; i--) {
			s16 sample = inbuf[i];
			outbuf[i * 2] = sample;
			outbuf[i * 2 + 1] = sample;
		}
	}

	m_noAudioData = false;
	return 0x2000;
}
Ejemplo n.º 15
0
int sceFontGetFontInfo(u32 fontHandle, u32 fontInfoPtr) {
	if (!Memory::IsValidAddress(fontInfoPtr)) {
		ERROR_LOG(HLE, "sceFontGetFontInfo(%x, %x): bad fontInfo pointer", fontHandle, fontInfoPtr);
		return ERROR_FONT_INVALID_PARAMETER;
	}
	LoadedFont *font = GetLoadedFont(fontHandle, true);
	if (!font) {
		ERROR_LOG_REPORT(HLE, "sceFontGetFontInfo(%x, %x): bad font", fontHandle, fontInfoPtr);
		return ERROR_FONT_INVALID_PARAMETER;
	}

	DEBUG_LOG(HLE, "sceFontGetFontInfo(%x, %x)", fontHandle, fontInfoPtr);
	auto fi = Memory::GetStruct<PGFFontInfo>(fontInfoPtr);
	font->GetPGF()->GetFontInfo(fi);
	fi->fontStyle = font->GetFont()->GetFontStyle();

	return 0;
}
Ejemplo n.º 16
0
SceUID KernelObjectPool::Create(KernelObject *obj, int rangeBottom, int rangeTop) {
	if (rangeTop > maxCount)
		rangeTop = maxCount;
	if (nextID >= rangeBottom && nextID < rangeTop)
		rangeBottom = nextID++;

	for (int i = rangeBottom; i < rangeTop; i++) {
		if (!occupied[i]) {
			occupied[i] = true;
			pool[i] = obj;
			pool[i]->uid = i + handleOffset;
			return i + handleOffset;
		}
	}

	ERROR_LOG_REPORT(SCEKERNEL, "Unable to allocate kernel object, too many objects slots in use.");
	return 0;
}
Ejemplo n.º 17
0
int sceFontGetCharInfo(u32 fontHandle, u32 charCode, u32 charInfoPtr) {
	if (!Memory::IsValidAddress(charInfoPtr)) {
		ERROR_LOG(HLE, "sceFontGetCharInfo(%08x, %i, %08x): bad charInfo pointer", fontHandle, charCode, charInfoPtr);
		return ERROR_FONT_INVALID_PARAMETER;
	}
	LoadedFont *font = GetLoadedFont(fontHandle, false);
	if (!font) {
		// The PSP crashes, but we assume it'd work like sceFontGetFontInfo(), and not touch charInfo.
		ERROR_LOG_REPORT(HLE, "sceFontGetCharInfo(%08x, %i, %08x): bad font", fontHandle, charCode, charInfoPtr);
		return ERROR_FONT_INVALID_PARAMETER;
	}

	DEBUG_LOG(HLE, "sceFontGetCharInfo(%08x, %i, %08x)", fontHandle, charCode, charInfoPtr);
	auto charInfo = Memory::GetStruct<PGFCharInfo>(charInfoPtr);
	font->GetPGF()->GetCharInfo(charCode, charInfo);

	return 0;
}
Ejemplo n.º 18
0
int sceKernelVolatileMemTryLock(int type, u32 paddr, u32 psize) {
	u32 error = __KernelVolatileMemLock(type, paddr, psize);

	switch (error) {
	case 0:
		DEBUG_LOG(HLE, "sceKernelVolatileMemTryLock(%i, %08x, %08x) - success", type, paddr, psize);
		break;

	case ERROR_POWER_VMEM_IN_USE:
		ERROR_LOG(HLE, "sceKernelVolatileMemTryLock(%i, %08x, %08x) - already locked!", type, paddr, psize);
		break;

	default:
		ERROR_LOG_REPORT(HLE, "%08x=sceKernelVolatileMemTryLock(%i, %08x, %08x) - error", type, paddr, psize, error);
		break;
	}

	return error;
}
Ejemplo n.º 19
0
void D3D9_Resize(HWND window) {
    // This should only be called from the emu thread.

    int xres, yres;
    GetRes(xres, yres);
    bool w_changed = pp.BackBufferWidth != xres;
    bool h_changed = pp.BackBufferHeight != yres;

    if (device && (w_changed || h_changed)) {
        DX9::fbo_shutdown();

        pp.BackBufferWidth = xres;
        pp.BackBufferHeight = yres;
        HRESULT hr = device->Reset(&pp);
        if (FAILED(hr)) {
            ERROR_LOG_REPORT(G3D, "Unable to reset device: %s", DXGetErrorStringA(hr));
            PanicAlert("Unable to reset D3D9 device: %s", DXGetErrorStringA(hr));
        }
        DX9::fbo_init(d3d);
    }
}
Ejemplo n.º 20
0
int MediaEngine::getAudioSamples(u32 bufferPtr) {
	if (!Memory::IsValidAddress(bufferPtr)) {
		ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr);
	}

	u8 *buffer = Memory::GetPointer(bufferPtr);
	if (!m_demux) {
		return 0;
	}

	u8 *audioFrame = 0;
	int headerCode1, headerCode2;
	int frameSize = getNextAudioFrame(&audioFrame, &headerCode1, &headerCode2);
	if (frameSize == 0) {
		return 0;
	}
	int outbytes = 0;

	if (m_audioContext != NULL) {
		if (!m_audioContext->Decode(audioFrame, frameSize, buffer, &outbytes)) {
			ERROR_LOG(ME, "Audio (%s) decode failed during video playback", GetCodecName(m_audioType));
		}
#ifndef MOBILE_DEVICE
		CBreakPoints::ExecMemCheck(bufferPtr, true, outbytes, currentMIPS->pc);
#endif
	}

	if (headerCode1 == 0x24) {
		// it a mono atrac3plus, convert it to stereo
		s16 *outbuf = (s16*)buffer;
		s16 *inbuf = (s16*)buffer;
		for (int i = 0x800 - 1; i >= 0; i--) {
			s16 sample = inbuf[i];
			outbuf[i * 2] = sample;
			outbuf[i * 2 + 1] = sample;
		}
	}

	return 0x2000;
}
void D3D9Context::Resize() {
	// This should only be called from the emu thread.

	int xres, yres;
	GetRes(hWnd, xres, yres);
	bool w_changed = pp.BackBufferWidth != xres;
	bool h_changed = pp.BackBufferHeight != yres;

	if (device && (w_changed || h_changed)) {
		DX9::fbo_shutdown();

		pp.BackBufferWidth = xres;
		pp.BackBufferHeight = yres;
		HRESULT hr = device->Reset(&pp);
		if (FAILED(hr)) {
      // Had to remove DXGetErrorStringA calls here because dxerr.lib is deprecated and will not link with VS 2015.
			ERROR_LOG_REPORT(G3D, "Unable to reset D3D device");
			PanicAlert("Unable to reset D3D9 device");
		}
		DX9::fbo_init(d3d);
	}
}
Ejemplo n.º 22
0
bool WriteSyscall(const char *moduleName, u32 nib, u32 address)
{
	if (nib == 0)
	{
		WARN_LOG_REPORT(HLE, "Wrote patched out nid=0 syscall (%s)", moduleName);
		Memory::Write_U32(MIPS_MAKE_JR_RA(), address); //patched out?
		Memory::Write_U32(MIPS_MAKE_NOP(), address+4); //patched out?
		return true;
	}
	int modindex = GetModuleIndex(moduleName);
	if (modindex != -1)
	{
		Memory::Write_U32(MIPS_MAKE_JR_RA(), address); // jr ra
		Memory::Write_U32(GetSyscallOp(moduleName, nib), address + 4);
		return true;
	}
	else
	{
		ERROR_LOG_REPORT(HLE, "Unable to write unknown syscall: %s/%08x", moduleName, nib);
		return false;
	}
}
Ejemplo n.º 23
0
void Jit::WriteExit(u32 destination, int exit_num)
{
	_dbg_assert_msg_(JIT, exit_num < MAX_JIT_BLOCK_EXITS, "Expected a valid exit_num");

	if (!Memory::IsValidAddress(destination)) {
		ERROR_LOG_REPORT(JIT, "Trying to write block exit to illegal destination %08x: pc = %08x", destination, currentMIPS->pc);
	}
	// If we need to verify coreState and rewind, we may not jump yet.
	if (js.afterOp & (JitState::AFTER_CORE_STATE | JitState::AFTER_REWIND_PC_BAD_STATE))
	{
		// CORE_RUNNING is <= CORE_NEXTFRAME.
		CMP(32, M((void*)&coreState), Imm32(CORE_NEXTFRAME));
		FixupBranch skipCheck = J_CC(CC_LE);
		MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
		WriteSyscallExit();
		SetJumpTarget(skipCheck);

		js.afterOp = JitState::AFTER_NONE;
	}

	WriteDowncount();

	//If nobody has taken care of this yet (this can be removed when all branches are done)
	JitBlock *b = js.curBlock;
	b->exitAddress[exit_num] = destination;
	b->exitPtrs[exit_num] = GetWritableCodePtr();

	// Link opportunity!
	int block = blocks.GetBlockNumberFromStartAddress(destination);
	if (block >= 0 && jo.enableBlocklink) {
		// It exists! Joy of joy!
		JMP(blocks.GetBlock(block)->checkedEntry, true);
		b->linkStatus[exit_num] = true;
	} else {
		// No blocklinking.
		MOV(32, M(&mips_->pc), Imm32(destination));
		JMP(asm_.dispatcher, true);
	}
}
Ejemplo n.º 24
0
u32 scePsmfPlayerConfigPlayer(u32 psmfPlayer, int configMode, int configAttr) 
{
	PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
	if (!psmfplayer) {
		ERROR_LOG(HLE, "scePsmfPlayerConfigPlayer(%08x, %i, %i): invalid psmf player", psmfPlayer, configMode, configAttr);
		return ERROR_PSMF_NOT_FOUND;
	}
	if (configMode == PSMF_PLAYER_CONFIG_MODE_LOOP) {
		INFO_LOG(HLE, "scePsmfPlayerConfigPlayer(%08x, loop, %i)", psmfPlayer, configAttr);
		videoLoopStatus = configAttr;
	} else if (configMode == PSMF_PLAYER_CONFIG_MODE_PIXEL_TYPE) {
		INFO_LOG(HLE, "scePsmfPlayerConfigPlayer(%08x, pixelType, %i)", psmfPlayer, configAttr);
		// Does -1 mean default or something?
		if (configAttr != -1) {
			videoPixelMode = configAttr;
		}
	} else {
		ERROR_LOG_REPORT(HLE, "scePsmfPlayerConfigPlayer(%08x, %i, %i): unknown parameter", psmfPlayer, configMode, configAttr);
	}

	return 0;
}
Ejemplo n.º 25
0
int MediaEngine::getAudioSamples(u32 bufferPtr) {
	if (!Memory::IsValidAddress(bufferPtr)) {
		ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr);
	}

	u8 *buffer = Memory::GetPointer(bufferPtr);
	if (!m_demux) {
		return 0;
	}
	u8 *audioFrame = 0;
	int headerCode1, headerCode2;
	int frameSize = m_demux->getNextaudioFrame(&audioFrame, &headerCode1, &headerCode2);
	if (frameSize == 0) {
		m_noAudioData = true;
		return 0;
	}
	int outbytes = 0;

	if (m_audioContext != NULL) {
		if (!AT3Decode(m_audioContext, audioFrame, frameSize, &outbytes, buffer)) {
			ERROR_LOG(ME, "AT3 decode failed during video playback");
		}
	}

	if (headerCode1 == 0x24) {
		// it a mono atrac3plus, convert it to stereo
		s16 *outbuf = (s16*)buffer;
		s16 *inbuf = (s16*)buffer;
		for (int i = 0x800 - 1; i >= 0; i--) {
			s16 sample = inbuf[i];
			outbuf[i * 2] = sample;
			outbuf[i * 2 + 1] = sample;
		}
	}
	m_audiopts += 4180;
	m_noAudioData = false;
	return 0x2000;
}
Ejemplo n.º 26
0
static u32 sceUtilityUnloadModule(u32 module) {
	const ModuleLoadInfo *info = __UtilityModuleInfo(module);
	if (!info) {
		ERROR_LOG_REPORT(SCEUTILITY, "sceUtilityUnloadModule(%i): invalid module id", module);
		return SCE_ERROR_MODULE_BAD_ID;
	}

	if (currentlyLoadedModules.find(module) == currentlyLoadedModules.end()) {
		WARN_LOG(SCEUTILITY, "sceUtilityUnloadModule(%i): not yet loaded", module);
		return SCE_ERROR_MODULE_NOT_LOADED;
	}
	if (currentlyLoadedModules[module] != 0) {
		userMemory.Free(currentlyLoadedModules[module]);
	}
	currentlyLoadedModules.erase(module);

	INFO_LOG(SCEUTILITY, "sceUtilityUnloadModule(%i)", module);
	// TODO: Each module has its own timing, technically, but this is a low-end.
	if (module == 0x3FF)
		return hleDelayResult(0, "utility module unloaded", 110);
	else
		return hleDelayResult(0, "utility module unloaded", 400);
}
Ejemplo n.º 27
0
	virtual void handleResult(PendingInterrupt& pend)
	{
		GeInterruptData intrdata = ge_pending_cb.front();
		ge_pending_cb.pop_front();

		DisplayList* dl = gpu->getList(intrdata.listid);
		if (!dl->interruptsEnabled)
		{
			ERROR_LOG_REPORT(SCEGE, "Unable to finish GE interrupt: list has interrupts disabled, should not happen");
			return;
		}

		switch (dl->signal)
		{
		case PSP_GE_SIGNAL_HANDLER_SUSPEND:
			if (sceKernelGetCompiledSdkVersion() <= 0x02000010)
			{
				// uofw says dl->state = endCmd & 0xFF;
				DisplayListState newState = static_cast<DisplayListState>(Memory::ReadUnchecked_U32(intrdata.pc - 4) & 0xFF);
				//dl->status = static_cast<DisplayListStatus>(Memory::ReadUnchecked_U32(intrdata.pc) & 0xFF);
				//if(dl->status < 0 || dl->status > PSP_GE_LIST_PAUSED)
				//	ERROR_LOG(SCEGE, "Weird DL status after signal suspend %x", dl->status);
				if (newState != PSP_GE_DL_STATE_RUNNING)
					DEBUG_LOG_REPORT(SCEGE, "GE Interrupt: newState might be %d", newState);

				if (dl->state != PSP_GE_DL_STATE_NONE && dl->state != PSP_GE_DL_STATE_COMPLETED) {
					dl->state = PSP_GE_DL_STATE_QUEUED;
				}
			}
			break;
		default:
			break;
		}

		gpu->InterruptEnd(intrdata.listid);
	}
Ejemplo n.º 28
0
u32 sceUtilityUnloadModule(u32 module)
{
	// TODO: Not all modules between 0x100 and 0x601 are valid.
	if (module < 0x100 || module > 0x601)
	{
		ERROR_LOG_REPORT(SCEUTILITY, "sceUtilityUnloadModule(%i): invalid module id", module);
		return SCE_ERROR_MODULE_BAD_ID;
	}

	if (currentlyLoadedModules.find(module) == currentlyLoadedModules.end())
	{
		WARN_LOG(SCEUTILITY, "sceUtilityUnloadModule(%i): not yet loaded", module);
		return SCE_ERROR_MODULE_NOT_LOADED;
	}
	currentlyLoadedModules.erase(module);

	INFO_LOG(SCEUTILITY, "sceUtilityUnloadModule(%i)", module);
	// TODO: Each module has its own timing, technically, but this is a low-end.
	// Note: If not loaded, it should not reschedule actually...
	if (module == 0x3FF)
		return hleDelayResult(0, "utility module unloaded", 110);
	else
		return hleDelayResult(0, "utility module unloaded", 400);
}
Ejemplo n.º 29
0
static int sceKernelVolatileMemTryLock(int type, u32 paddr, u32 psize) {
	u32 error = __KernelVolatileMemLock(type, paddr, psize);

	switch (error) {
	case 0:
		// HACK: This fixes Crash Tag Team Racing.
		// Should only wait 1200 cycles though according to Unknown's testing,
		// and with that it's still broken. So it's not this, unfortunately.
		// Leaving it in for the 0.9.8 release anyway.
		hleEatCycles(500000);
		DEBUG_LOG(HLE, "sceKernelVolatileMemTryLock(%i, %08x, %08x) - success", type, paddr, psize);
		break;

	case SCE_KERNEL_ERROR_POWER_VMEM_IN_USE:
		ERROR_LOG(HLE, "sceKernelVolatileMemTryLock(%i, %08x, %08x) - already locked!", type, paddr, psize);
		break;

	default:
		ERROR_LOG_REPORT(HLE, "%08x=sceKernelVolatileMemTryLock(%i, %08x, %08x) - error", type, paddr, psize, error);
		break;
	}

	return error;
}
Ejemplo n.º 30
0
static u32 sceUtilityLoadModule(u32 module) {
	const ModuleLoadInfo *info = __UtilityModuleInfo(module);
	if (!info) {
		ERROR_LOG_REPORT(SCEUTILITY, "sceUtilityLoadModule(%i): invalid module id", module);
		return SCE_ERROR_MODULE_BAD_ID;
	}
	if (currentlyLoadedModules.find(module) != currentlyLoadedModules.end()) {
		ERROR_LOG(SCEUTILITY, "sceUtilityLoadModule(%i): already loaded", module);
		return SCE_ERROR_MODULE_ALREADY_LOADED;
	}

	// Some games, like Kamen Rider Climax Heroes OOO, require an error if dependencies aren't loaded yet.
	for (const int *dep = info->dependencies; dep && *dep == 0; ++dep) {
		if (currentlyLoadedModules.find(*dep) == currentlyLoadedModules.end()) {
			ERROR_LOG(SCEUTILITY, "sceUtilityLoadModule(%i): dependent module %i not loaded", module, *dep);
			return hleDelayResult(SCE_KERNEL_ERROR_LIBRARY_NOTFOUND, "utility module load attempt", 25000);
		}
	}

	INFO_LOG(SCEUTILITY, "sceUtilityLoadModule(%i)", module);

	u32 allocSize = info->size;
	char name[64];
	snprintf(name, sizeof(name), "UtilityModule/%x", module);
	if (allocSize != 0) {
		currentlyLoadedModules[module] = userMemory.Alloc(allocSize, false, name);
	} else {
		currentlyLoadedModules[module] = 0;
	}

	// TODO: Each module has its own timing, technically, but this is a low-end.
	if (module == 0x3FF)
		return hleDelayResult(0, "utility module loaded", 130);
	else
		return hleDelayResult(0, "utility module loaded", 25000);
}