Ejemplo n.º 1
0
bool ShaderProgramLoader::load(type& res, const std::string& name, const context_type* context)
{
    UberShader::IdType id = context->ubershader_pool.create();
    UberShader& ubershader = context->ubershader_pool.get(id);

    size_t defs_pos = name.find_first_of('&');
    const std::string& defs = defs_pos == std::string::npos ? std::string() : name.substr(defs_pos + 1, name.size() - defs_pos);
    const std::vector<std::string>& definitions = utils::split(defs, ",");

    const std::string& actual_filename = defs_pos == std::string::npos ? name  : name.substr(0, defs_pos);
    std::string filename_with_extension = actual_filename + detail::shader_extension;
    std::ifstream f(filename_with_extension.c_str());
    if (!f.is_open())
    {
        WARN_LOG("Can't open file:" << filename_with_extension);
        return false;
    }
    const std::vector<std::string>& file_content = utils::read_lines(f);
    f.close();

    std::vector<UberShader::Info> infos;
    detail::parse_defs(infos, file_content);
    size_t total = 1;
    if (!infos.empty())
    {
        const UberShader::Info& last = infos.back();
        total = last.offset * (last.high - last.low + 1);
    }

    bool result = false;
    for (size_t i = 0; i < total; ++i)
    {
        ShaderProgram::IdType shader_id = context->shader_pool.create();
        ShaderProgram& shader_program = context->shader_pool.get(shader_id);

        std::vector<std::string> data;
        data.reserve(1024);
        for (size_t j = 0; j < definitions.size(); ++j)
            data.push_back(std::string("#define ") + definitions[j]);

        std::string debug_defs;
        for (size_t j = 0; j < infos.size(); ++j)
        {
            size_t value = infos[j].low + (i / infos[j].offset) % (infos[j].high - infos[j].low + 1);
            std::string def = "#define " + infos[j].name + " " + types_cast<std::string>(value);
            debug_defs += def;
            debug_defs += " ";
            data.push_back(def);
        }

        data.insert(data.end(), file_content.begin(), file_content.end());

        ShaderInitializationParams params;
        detail::LoadContext load_context;
        load_context.filename = filename_with_extension;
        load_context.level = 0;
        load_context.tag_found = false;
        params.csdata = detail::load_shader_impl(params, data, detail::compute_shader_tag, load_context);
        if (params.csdata.empty())
        {
            load_context.tag_found = false;
            params.vsdata = detail::load_shader_impl(params, data, detail::vertex_shader_tag, load_context);
            load_context.tag_found = false;
            params.fsdata = detail::load_shader_impl(params, data, detail::fragment_shader_tag, load_context);
            load_context.tag_found = false;
            params.gsdata = detail::load_shader_impl(params, data, detail::geometry_shader_tag, load_context);
        }
        // TODO: parse GLSL errors to find the correct line with error
        
        const std::vector<std::string>& vs_tmp = utils::split(params.vsdata, "\n", true);
        const std::vector<std::string>& fs_tmp = utils::split(params.fsdata, "\n", true);
        const std::vector<std::string>& cs_tmp = utils::split(params.csdata, "\n", true);
        const std::vector<std::string>& gs_tmp = utils::split(params.gsdata, "\n", true);
        UNUSED(vs_tmp);
        UNUSED(fs_tmp);
        UNUSED(cs_tmp);
        UNUSED(gs_tmp);

        detail::update_shader_data(params, context);

        result = shader_program.init(params);
        if (!result)
        {
            ASSERT(0, "Shader compilation failed: " << name << "\n" << debug_defs);
            continue;
        }

        ubershader.add(i, shader_id);
    }
    if (!result) return false;

    ubershader.set_infos(infos);
    res.shader_program_handle = ubershader.id();
    return true;
}
Ejemplo n.º 2
0
int ThreadManForKernel_ceadeb47(u32 usec)
{	
	WARN_LOG(SCEKERNEL,"ThreadManForKernel_ceadeb47:Not support this patcher");
	return sceKernelDelayThread(usec);
}
Ejemplo n.º 3
0
int PSPSaveDialog::Init(int paramAddr)
{
	// Ignore if already running
	if (GetStatus() != SCE_UTILITY_STATUS_NONE) {
		ERROR_LOG_REPORT(SCEUTILITY, "A save request is already running, not starting a new one");
		return SCE_ERROR_UTILITY_INVALID_STATUS;
	}
	
	requestAddr = paramAddr;
	int size = Memory::Read_U32(requestAddr);
	memset(&request, 0, sizeof(request));
	// Only copy the right size to support different save request format
	if (size != SAVEDATA_DIALOG_SIZE_V1 && size != SAVEDATA_DIALOG_SIZE_V2 && size != SAVEDATA_DIALOG_SIZE_V3) {
		ERROR_LOG_REPORT(SCEUTILITY, "sceUtilitySavedataInitStart: invalid size %d", size);
		return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE;
	}
	Memory::Memcpy(&request, requestAddr, size);
	Memory::Memcpy(&originalRequest, requestAddr, size);

	int retval = param.SetPspParam(&request);

	const u32 mode = (u32)param.GetPspParam()->mode;
	const char *modeName = mode < ARRAY_SIZE(utilitySavedataTypeNames) ? utilitySavedataTypeNames[mode] : "UNKNOWN";
	INFO_LOG(SCEUTILITY,"sceUtilitySavedataInitStart(%08x) - %s (%d)", paramAddr, modeName, mode);
	INFO_LOG(SCEUTILITY,"sceUtilitySavedataInitStart(%08x) : Game key (hex): %s", paramAddr, param.GetKey(param.GetPspParam()).c_str());

	yesnoChoice = 1;
	switch ((SceUtilitySavedataFocus)(u32)param.GetPspParam()->focus)
	{
	case SCE_UTILITY_SAVEDATA_FOCUS_NAME:
		currentSelectedSave = param.GetSaveNameIndex(param.GetPspParam());
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTLIST:
		currentSelectedSave = param.GetFirstListSave();
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_LASTLIST:
		currentSelectedSave = param.GetLastListSave();
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_LATEST:
		currentSelectedSave = param.GetLatestSave();
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_OLDEST:
		currentSelectedSave = param.GetOldestSave();
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTDATA:
		currentSelectedSave = param.GetFirstDataSave();
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_LASTDATA:
		currentSelectedSave = param.GetLastDataSave();
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY:
		currentSelectedSave = param.GetFirstEmptySave();
		break;
	case SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY:
		currentSelectedSave = param.GetLastEmptySave();
		break;
	default:
		WARN_LOG(SCEUTILITY, "Unknown save list focus option: %d", param.GetPspParam()->focus);
		currentSelectedSave = 0;
		break;
	}

	switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode)
	{
		case SCE_UTILITY_SAVEDATA_TYPE_LOAD:
			DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			if (param.GetFileInfo(0).size != 0)
				display = DS_LOAD_CONFIRM;
			else
				display = DS_LOAD_NODATA;
			break;
		case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD:
			DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			display = DS_NONE;
			// Is this necessary?
			// currentSelectedSave = param.GetSelectedSave();
			break;
		case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD:
			DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			if(param.GetFilenameCount() == 0)
				display = DS_LOAD_NODATA;
			else
				display = DS_LOAD_LIST_CHOICE;
			break;
		case SCE_UTILITY_SAVEDATA_TYPE_SAVE:
			DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			if (param.GetFileInfo(0).size != 0)
			{
				yesnoChoice = 0;
				display = DS_SAVE_CONFIRM_OVERWRITE;
			}
			else
				display = DS_SAVE_CONFIRM;
			break;
		case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE:
			DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			display = DS_NONE;
			// Is this necessary?
			// currentSelectedSave = param.GetSelectedSave();
			break;
		case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE:
			DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			display = DS_SAVE_LIST_CHOICE;
			break;
		case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE:
			DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			if(param.GetFilenameCount() == 0)
				display = DS_DELETE_NODATA;
			else
				display = DS_DELETE_LIST_CHOICE;
			break;
		case SCE_UTILITY_SAVEDATA_TYPE_SIZES:
		case SCE_UTILITY_SAVEDATA_TYPE_LIST:
		case SCE_UTILITY_SAVEDATA_TYPE_FILES:
		case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE:
		case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE:
		case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE:
		case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA:
		case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE:
		case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA:
		case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE:
		case SCE_UTILITY_SAVEDATA_TYPE_READDATA:
		case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA:
			display = DS_NONE;
			break;

		case SCE_UTILITY_SAVEDATA_TYPE_DELETE: // When run on a PSP, displays a list of all saves on the PSP. Weird. (Not really, it's to let you free up space)
			display = DS_DELETE_LIST_CHOICE;
			break;
		default:
		{
			ERROR_LOG_REPORT(SCEUTILITY, "Load/Save function %d not coded. Title: %s Save: %s File: %s", (SceUtilitySavedataType)(u32)param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str());
			param.GetPspParam()->common.result = 0;
			ChangeStatusInit(SAVEDATA_INIT_DELAY_US);
			display = DS_NONE;
			return 0; // Return 0 should allow the game to continue, but missing function must be implemented and returning the right value or the game can block.
		}
		break;
	}

	if (retval < 0) {
		ChangeStatusShutdown(SAVEDATA_SHUTDOWN_DELAY_US);
	} else {
		ChangeStatusInit(SAVEDATA_INIT_DELAY_US);
	}

	UpdateButtons();
	StartFade(true);

	/*INFO_LOG(SCEUTILITY,"Dump Param :");
	INFO_LOG(SCEUTILITY,"size : %d",param.GetPspParam()->size);
	INFO_LOG(SCEUTILITY,"language : %d",param.GetPspParam()->language);
	INFO_LOG(SCEUTILITY,"buttonSwap : %d",param.GetPspParam()->buttonSwap);
	INFO_LOG(SCEUTILITY,"result : %d",param.GetPspParam()->common.result);
	INFO_LOG(SCEUTILITY,"mode : %d",param.GetPspParam()->mode);
	INFO_LOG(SCEUTILITY,"bind : %d",param.GetPspParam()->bind);
	INFO_LOG(SCEUTILITY,"overwriteMode : %d",param.GetPspParam()->overwriteMode);
	INFO_LOG(SCEUTILITY,"gameName : %s",param.GetGameName(param.GetPspParam()).c_str());
	INFO_LOG(SCEUTILITY,"saveName : %s",param.GetPspParam()->saveName);
	INFO_LOG(SCEUTILITY,"saveNameList : %08x",*((unsigned int*)&param.GetPspParam()->saveNameList));
	INFO_LOG(SCEUTILITY,"fileName : %s",param.GetPspParam()->fileName);
	INFO_LOG(SCEUTILITY,"dataBuf : %08x",*((unsigned int*)&param.GetPspParam()->dataBuf));
	INFO_LOG(SCEUTILITY,"dataBufSize : %u",param.GetPspParam()->dataBufSize);
	INFO_LOG(SCEUTILITY,"dataSize : %u",param.GetPspParam()->dataSize);

	INFO_LOG(SCEUTILITY,"sfo title : %s",param.GetPspParam()->sfoParam.title);
	INFO_LOG(SCEUTILITY,"sfo savedataTitle : %s",param.GetPspParam()->sfoParam.savedataTitle);
	INFO_LOG(SCEUTILITY,"sfo detail : %s",param.GetPspParam()->sfoParam.detail);

	INFO_LOG(SCEUTILITY,"icon0 data : %08x",*((unsigned int*)&param.GetPspParam()->icon0FileData.buf));
	INFO_LOG(SCEUTILITY,"icon0 size : %u",param.GetPspParam()->icon0FileData.bufSize);

	INFO_LOG(SCEUTILITY,"icon1 data : %08x",*((unsigned int*)&param.GetPspParam()->icon1FileData.buf));
	INFO_LOG(SCEUTILITY,"icon1 size : %u",param.GetPspParam()->icon1FileData.bufSize);

	INFO_LOG(SCEUTILITY,"pic1 data : %08x",*((unsigned int*)&param.GetPspParam()->pic1FileData.buf));
	INFO_LOG(SCEUTILITY,"pic1 size : %u",param.GetPspParam()->pic1FileData.bufSize);

	INFO_LOG(SCEUTILITY,"snd0 data : %08x",*((unsigned int*)&param.GetPspParam()->snd0FileData.buf));
	INFO_LOG(SCEUTILITY,"snd0 size : %u",param.GetPspParam()->snd0FileData.bufSize);*/
	return retval;
}
Ejemplo n.º 4
0
int Interpreter::SingleStepInner(void)
{
	static UGeckoInstruction instCode;
	u32 function = m_EndBlock ? HLE::GetFunctionIndex(PC) : 0; // Check for HLE functions after branches
	if (function != 0)
	{
		int type = HLE::GetFunctionTypeByIndex(function);
		if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE)
		{
			int flags = HLE::GetFunctionFlagsByIndex(function);
			if (HLE::IsEnabled(flags))
			{
				HLEFunction(function);
				if (type == HLE::HLE_HOOK_START)
				{
					// Run the original.
					function = 0;
				}
			}
			else
			{
				function = 0;
			}
		}
	}

	if (function == 0)
	{
		#ifdef USE_GDBSTUB
		if (gdb_active() && gdb_bp_x(PC)) {

			Host_UpdateDisasmDialog();

			gdb_signal(SIGTRAP);
			gdb_handle_exception();
		}
		#endif

		NPC = PC + sizeof(UGeckoInstruction);
		instCode.hex = Memory::Read_Opcode(PC);

		// Uncomment to trace the interpreter
		//if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
		//	startTrace = 1;
		//else
		//	startTrace = 0;

		if (startTrace)
		{
			Trace(instCode);
		}

		if (instCode.hex != 0)
		{
			UReg_MSR& msr = (UReg_MSR&)MSR;
			if (msr.FP)  //If FPU is enabled, just execute
			{
				m_opTable[instCode.OPCD](instCode);
				if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
				{
					PowerPC::CheckExceptions();
					m_EndBlock = true;
				}
			}
			else
			{
				// check if we have to generate a FPU unavailable exception
				if (!PPCTables::UsesFPU(instCode))
				{
					m_opTable[instCode.OPCD](instCode);
					if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
					{
						PowerPC::CheckExceptions();
						m_EndBlock = true;
					}
				}
				else
				{
					Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE);
					PowerPC::CheckExceptions();
					m_EndBlock = true;
				}
			}
		}
		else
		{
			// Memory exception on instruction fetch
			PowerPC::CheckExceptions();
			m_EndBlock = true;
		}
	}
	last_pc = PC;
	PC = NPC;

#if defined(_DEBUG) || defined(DEBUGFAST)
	if (PowerPC::ppcState.gpr[1] == 0)
	{
		WARN_LOG(POWERPC, "%i Corrupt stack", PowerPC::ppcState.DebugCount);
	}
	PowerPC::ppcState.DebugCount++;
#endif
	patches();

	GekkoOPInfo *opinfo = GetOpInfo(instCode);
	return opinfo->numCycles;
}
Ejemplo n.º 5
0
int ThreadManForKernel_446d8de6(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr)
{
	WARN_LOG(SCEKERNEL,"ThreadManForKernel_446d8de6:Not support this patcher");
	return sceKernelCreateThread(threadName, entry, prio, stacksize,  attr, optionAddr);
}
Ejemplo n.º 6
0
IPCCommandResult NetIPTop::IOCtl(const IOCtlRequest& request)
{
  if (Core::g_want_determinism)
  {
    return GetDefaultReply(IPC_EACCES);
  }

  s32 return_value = 0;
  switch (request.request)
  {
  case IOCTL_SO_STARTUP:
  {
    request.Log(GetDeviceName(), LogTypes::IOS_WC24);
    break;
  }
  case IOCTL_SO_SOCKET:
  {
    u32 af = Memory::Read_U32(request.buffer_in);
    u32 type = Memory::Read_U32(request.buffer_in + 4);
    u32 prot = Memory::Read_U32(request.buffer_in + 8);

    WiiSockMan& sm = WiiSockMan::GetInstance();
    return_value = sm.NewSocket(af, type, prot);
    INFO_LOG(IOS_NET, "IOCTL_SO_SOCKET "
                      "Socket: %08x (%d,%d,%d), BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
             return_value, af, type, prot, request.buffer_in, request.buffer_in_size,
             request.buffer_out, request.buffer_out_size);
    break;
  }
  case IOCTL_SO_ICMPSOCKET:
  {
    u32 pf = Memory::Read_U32(request.buffer_in);

    WiiSockMan& sm = WiiSockMan::GetInstance();
    return_value = sm.NewSocket(pf, SOCK_RAW, IPPROTO_ICMP);
    INFO_LOG(IOS_NET, "IOCTL_SO_ICMPSOCKET(%x) %d", pf, return_value);
    break;
  }
  case IOCTL_SO_CLOSE:
  case IOCTL_SO_ICMPCLOSE:
  {
    u32 fd = Memory::Read_U32(request.buffer_in);
    WiiSockMan& sm = WiiSockMan::GetInstance();
    return_value = sm.DeleteSocket(fd);
    INFO_LOG(IOS_NET, "%s(%x) %x",
             request.request == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE", fd,
             return_value);
    break;
  }
  case IOCTL_SO_ACCEPT:
  case IOCTL_SO_BIND:
  case IOCTL_SO_CONNECT:
  case IOCTL_SO_FCNTL:
  {
    u32 fd = Memory::Read_U32(request.buffer_in);
    WiiSockMan& sm = WiiSockMan::GetInstance();
    sm.DoSock(fd, request, static_cast<NET_IOCTL>(request.request));
    return GetNoReply();
  }
  /////////////////////////////////////////////////////////////
  //                  TODO: Tidy all below                   //
  /////////////////////////////////////////////////////////////
  case IOCTL_SO_SHUTDOWN:
  {
    request.Log(GetDeviceName(), LogTypes::IOS_WC24);

    u32 fd = Memory::Read_U32(request.buffer_in);
    u32 how = Memory::Read_U32(request.buffer_in + 4);
    int ret = shutdown(fd, how);
    return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SHUTDOWN", false);
    break;
  }
  case IOCTL_SO_LISTEN:
  {
    u32 fd = Memory::Read_U32(request.buffer_in);
    u32 BACKLOG = Memory::Read_U32(request.buffer_in + 0x04);
    u32 ret = listen(fd, BACKLOG);
    return_value = WiiSockMan::GetNetErrorCode(ret, "SO_LISTEN", false);
    request.Log(GetDeviceName(), LogTypes::IOS_WC24);
    break;
  }
  case IOCTL_SO_GETSOCKOPT:
  {
    u32 fd = Memory::Read_U32(request.buffer_out);
    u32 level = Memory::Read_U32(request.buffer_out + 4);
    u32 optname = Memory::Read_U32(request.buffer_out + 8);

    request.Log(GetDeviceName(), LogTypes::IOS_WC24);

    // Do the level/optname translation
    int nat_level = -1, nat_optname = -1;

    for (auto& map : opt_level_mapping)
      if (level == map[1])
        nat_level = map[0];

    for (auto& map : opt_name_mapping)
      if (optname == map[1])
        nat_optname = map[0];

    u8 optval[20];
    u32 optlen = 4;

    int ret = getsockopt(fd, nat_level, nat_optname, (char*)&optval, (socklen_t*)&optlen);
    return_value = WiiSockMan::GetNetErrorCode(ret, "SO_GETSOCKOPT", false);

    Memory::Write_U32(optlen, request.buffer_out + 0xC);
    Memory::CopyToEmu(request.buffer_out + 0x10, optval, optlen);

    if (optname == SO_ERROR)
    {
      s32 last_error = WiiSockMan::GetInstance().GetLastNetError();

      Memory::Write_U32(sizeof(s32), request.buffer_out + 0xC);
      Memory::Write_U32(last_error, request.buffer_out + 0x10);
    }
    break;
  }

  case IOCTL_SO_SETSOCKOPT:
  {
    u32 fd = Memory::Read_U32(request.buffer_in);
    u32 level = Memory::Read_U32(request.buffer_in + 4);
    u32 optname = Memory::Read_U32(request.buffer_in + 8);
    u32 optlen = Memory::Read_U32(request.buffer_in + 0xc);
    u8 optval[20];
    optlen = std::min(optlen, (u32)sizeof(optval));
    Memory::CopyFromEmu(optval, request.buffer_in + 0x10, optlen);

    INFO_LOG(IOS_NET, "IOCTL_SO_SETSOCKOPT(%08x, %08x, %08x, %08x) "
                      "BufferIn: (%08x, %i), BufferOut: (%08x, %i)"
                      "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx "
                      "%02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx",
             fd, level, optname, optlen, request.buffer_in, request.buffer_in_size,
             request.buffer_out, request.buffer_out_size, optval[0], optval[1], optval[2],
             optval[3], optval[4], optval[5], optval[6], optval[7], optval[8], optval[9],
             optval[10], optval[11], optval[12], optval[13], optval[14], optval[15], optval[16],
             optval[17], optval[18], optval[19]);

    // TODO: bug booto about this, 0x2005 most likely timeout related, default value on Wii is ,
    // 0x2001 is most likely tcpnodelay
    if (level == 6 && (optname == 0x2005 || optname == 0x2001))
    {
      return_value = 0;
      break;
    }

    // Do the level/optname translation
    int nat_level = -1, nat_optname = -1;

    for (auto& map : opt_level_mapping)
      if (level == map[1])
        nat_level = map[0];

    for (auto& map : opt_name_mapping)
      if (optname == map[1])
        nat_optname = map[0];

    if (nat_level == -1 || nat_optname == -1)
    {
      INFO_LOG(IOS_NET, "SO_SETSOCKOPT: unknown level %d or optname %d", level, optname);

      // Default to the given level/optname. They match on Windows...
      nat_level = level;
      nat_optname = optname;
    }

    int ret = setsockopt(fd, nat_level, nat_optname, (char*)optval, optlen);
    return_value = WiiSockMan::GetNetErrorCode(ret, "SO_SETSOCKOPT", false);
    break;
  }
  case IOCTL_SO_GETSOCKNAME:
  {
    u32 fd = Memory::Read_U32(request.buffer_in);

    request.Log(GetDeviceName(), LogTypes::IOS_WC24);

    sockaddr sa;
    socklen_t sa_len;
    sa_len = sizeof(sa);
    int ret = getsockname(fd, &sa, &sa_len);

    if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
      WARN_LOG(IOS_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating");

    if (request.buffer_out_size > 0)
      Memory::Write_U8(request.buffer_out_size, request.buffer_out);
    if (request.buffer_out_size > 1)
      Memory::Write_U8(sa.sa_family & 0xFF, request.buffer_out + 1);
    if (request.buffer_out_size > 2)
      Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data,
                        std::min<size_t>(sizeof(sa.sa_data), request.buffer_out_size - 2));
    return_value = ret;
    break;
  }
  case IOCTL_SO_GETPEERNAME:
  {
    u32 fd = Memory::Read_U32(request.buffer_in);

    sockaddr sa;
    socklen_t sa_len;
    sa_len = sizeof(sa);

    int ret = getpeername(fd, &sa, &sa_len);

    if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
      WARN_LOG(IOS_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating");

    if (request.buffer_out_size > 0)
      Memory::Write_U8(request.buffer_out_size, request.buffer_out);
    if (request.buffer_out_size > 1)
      Memory::Write_U8(AF_INET, request.buffer_out + 1);
    if (request.buffer_out_size > 2)
      Memory::CopyToEmu(request.buffer_out + 2, &sa.sa_data,
                        std::min<size_t>(sizeof(sa.sa_data), request.buffer_out_size - 2));

    INFO_LOG(IOS_NET, "IOCTL_SO_GETPEERNAME(%x)", fd);

    return_value = ret;
    break;
  }

  case IOCTL_SO_GETHOSTID:
  {
    request.Log(GetDeviceName(), LogTypes::IOS_WC24);

#ifdef _WIN32
    DWORD forwardTableSize, ipTableSize, result;
    DWORD ifIndex = -1;
    std::unique_ptr<MIB_IPFORWARDTABLE> forwardTable;
    std::unique_ptr<MIB_IPADDRTABLE> ipTable;

    forwardTableSize = 0;
    if (GetIpForwardTable(nullptr, &forwardTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
    {
      forwardTable =
          std::unique_ptr<MIB_IPFORWARDTABLE>((PMIB_IPFORWARDTABLE) operator new(forwardTableSize));
    }

    ipTableSize = 0;
    if (GetIpAddrTable(nullptr, &ipTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
    {
      ipTable = std::unique_ptr<MIB_IPADDRTABLE>((PMIB_IPADDRTABLE) operator new(ipTableSize));
    }

    // find the interface IP used for the default route and use that
    result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE);
    while (result == NO_ERROR ||
           result == ERROR_MORE_DATA)  // can return ERROR_MORE_DATA on XP even after the first call
    {
      for (DWORD i = 0; i < forwardTable->dwNumEntries; ++i)
      {
        if (forwardTable->table[i].dwForwardDest == 0)
        {
          ifIndex = forwardTable->table[i].dwForwardIfIndex;
          break;
        }
      }

      if (result == NO_ERROR || ifIndex != -1)
        break;

      result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE);
    }

    if (ifIndex != -1 && GetIpAddrTable(ipTable.get(), &ipTableSize, FALSE) == NO_ERROR)
    {
      for (DWORD i = 0; i < ipTable->dwNumEntries; ++i)
      {
        if (ipTable->table[i].dwIndex == ifIndex)
        {
          return_value = Common::swap32(ipTable->table[i].dwAddr);
          break;
        }
      }
    }
#endif

    // default placeholder, in case of failure
    if (return_value == 0)
      return_value = 192 << 24 | 168 << 16 | 1 << 8 | 150;
    break;
  }

  case IOCTL_SO_INETATON:
  {
    std::string hostname = Memory::GetString(request.buffer_in);
    struct hostent* remoteHost = gethostbyname(hostname.c_str());

    if (remoteHost == nullptr || remoteHost->h_addr_list == nullptr ||
        remoteHost->h_addr_list[0] == nullptr)
    {
      INFO_LOG(IOS_NET, "IOCTL_SO_INETATON = -1 "
                        "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: None",
               hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out,
               request.buffer_out_size);
      return_value = 0;
    }
    else
    {
      Memory::Write_U32(Common::swap32(*(u32*)remoteHost->h_addr_list[0]), request.buffer_out);
      INFO_LOG(IOS_NET, "IOCTL_SO_INETATON = 0 "
                        "%s, BufferIn: (%08x, %i), BufferOut: (%08x, %i), IP Found: %08X",
               hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out,
               request.buffer_out_size, Common::swap32(*(u32*)remoteHost->h_addr_list[0]));
      return_value = 1;
    }
    break;
  }

  case IOCTL_SO_INETPTON:
  {
    std::string address = Memory::GetString(request.buffer_in);
    INFO_LOG(IOS_NET, "IOCTL_SO_INETPTON "
                      "(Translating: %s)",
             address.c_str());
    return_value = inet_pton(address.c_str(), Memory::GetPointer(request.buffer_out + 4));
    break;
  }

  case IOCTL_SO_INETNTOP:
  {
    // u32 af = Memory::Read_U32(BufferIn);
    // u32 validAddress = Memory::Read_U32(request.buffer_in + 4);
    // u32 src = Memory::Read_U32(request.buffer_in + 8);
    char ip_s[16];
    sprintf(ip_s, "%i.%i.%i.%i", Memory::Read_U8(request.buffer_in + 8),
            Memory::Read_U8(request.buffer_in + 8 + 1), Memory::Read_U8(request.buffer_in + 8 + 2),
            Memory::Read_U8(request.buffer_in + 8 + 3));
    INFO_LOG(IOS_NET, "IOCTL_SO_INETNTOP %s", ip_s);
    Memory::CopyToEmu(request.buffer_out, (u8*)ip_s, strlen(ip_s));
    break;
  }

  case IOCTL_SO_POLL:
  {
    // Map Wii/native poll events types
    struct
    {
      int native;
      int wii;
    } mapping[] = {
        {POLLRDNORM, 0x0001}, {POLLRDBAND, 0x0002}, {POLLPRI, 0x0004}, {POLLWRNORM, 0x0008},
        {POLLWRBAND, 0x0010}, {POLLERR, 0x0020},    {POLLHUP, 0x0040}, {POLLNVAL, 0x0080},
    };

    u32 unknown = Memory::Read_U32(request.buffer_in);
    u32 timeout = Memory::Read_U32(request.buffer_in + 4);

    int nfds = request.buffer_out_size / 0xc;
    if (nfds == 0)
      ERROR_LOG(IOS_NET, "Hidden POLL");

    std::vector<pollfd_t> ufds(nfds);

    for (int i = 0; i < nfds; ++i)
    {
      ufds[i].fd = Memory::Read_U32(request.buffer_out + 0xc * i);           // fd
      int events = Memory::Read_U32(request.buffer_out + 0xc * i + 4);       // events
      ufds[i].revents = Memory::Read_U32(request.buffer_out + 0xc * i + 8);  // revents

      // Translate Wii to native events
      int unhandled_events = events;
      ufds[i].events = 0;
      for (auto& map : mapping)
      {
        if (events & map.wii)
          ufds[i].events |= map.native;
        unhandled_events &= ~map.wii;
      }
      DEBUG_LOG(IOS_NET, "IOCTL_SO_POLL(%d) "
                         "Sock: %08x, Unknown: %08x, Events: %08x, "
                         "NativeEvents: %08x",
                i, ufds[i].fd, unknown, events, ufds[i].events);

      // Do not pass return-only events to the native poll
      ufds[i].events &= ~(POLLERR | POLLHUP | POLLNVAL | UNSUPPORTED_WSAPOLL);

      if (unhandled_events)
        ERROR_LOG(IOS_NET, "SO_POLL: unhandled Wii event types: %04x", unhandled_events);
    }

    int ret = poll(ufds.data(), nfds, timeout);
    ret = WiiSockMan::GetNetErrorCode(ret, "SO_POLL", false);

    for (int i = 0; i < nfds; ++i)
    {
      // Translate native to Wii events
      int revents = 0;
      for (auto& map : mapping)
      {
        if (ufds[i].revents & map.native)
          revents |= map.wii;
      }

      // No need to change fd or events as they are input only.
      // Memory::Write_U32(ufds[i].fd, request.buffer_out + 0xc*i); //fd
      // Memory::Write_U32(events, request.buffer_out + 0xc*i + 4); //events
      Memory::Write_U32(revents, request.buffer_out + 0xc * i + 8);  // revents

      DEBUG_LOG(IOS_NET, "IOCTL_SO_POLL socket %d wevents %08X events %08X revents %08X", i,
                revents, ufds[i].events, ufds[i].revents);
    }

    return_value = ret;
    break;
  }

  case IOCTL_SO_GETHOSTBYNAME:
  {
    if (request.buffer_out_size != 0x460)
    {
      ERROR_LOG(IOS_NET, "Bad buffer size for IOCTL_SO_GETHOSTBYNAME");
      return_value = -1;
      break;
    }

    std::string hostname = Memory::GetString(request.buffer_in);
    hostent* remoteHost = gethostbyname(hostname.c_str());

    INFO_LOG(IOS_NET, "IOCTL_SO_GETHOSTBYNAME "
                      "Address: %s, BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
             hostname.c_str(), request.buffer_in, request.buffer_in_size, request.buffer_out,
             request.buffer_out_size);

    if (remoteHost)
    {
      for (int i = 0; remoteHost->h_aliases[i]; ++i)
      {
        DEBUG_LOG(IOS_NET, "alias%i:%s", i, remoteHost->h_aliases[i]);
      }

      for (int i = 0; remoteHost->h_addr_list[i]; ++i)
      {
        u32 ip = Common::swap32(*(u32*)(remoteHost->h_addr_list[i]));
        std::string ip_s = StringFromFormat("%i.%i.%i.%i", ip >> 24, (ip >> 16) & 0xff,
                                            (ip >> 8) & 0xff, ip & 0xff);
        DEBUG_LOG(IOS_NET, "addr%i:%s", i, ip_s.c_str());
      }

      // Host name; located immediately after struct
      static const u32 GETHOSTBYNAME_STRUCT_SIZE = 0x10;
      static const u32 GETHOSTBYNAME_IP_LIST_OFFSET = 0x110;
      // Limit host name length to avoid buffer overflow.
      u32 name_length = (u32)strlen(remoteHost->h_name) + 1;
      if (name_length > (GETHOSTBYNAME_IP_LIST_OFFSET - GETHOSTBYNAME_STRUCT_SIZE))
      {
        ERROR_LOG(IOS_NET, "Hostname too long in IOCTL_SO_GETHOSTBYNAME");
        return_value = -1;
        break;
      }
      Memory::CopyToEmu(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, remoteHost->h_name,
                        name_length);
      Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_STRUCT_SIZE, request.buffer_out);

      // IP address list; located at offset 0x110.
      u32 num_ip_addr = 0;
      while (remoteHost->h_addr_list[num_ip_addr])
        num_ip_addr++;
      // Limit number of IP addresses to avoid buffer overflow.
      // (0x460 - 0x340) / sizeof(pointer) == 72
      static const u32 GETHOSTBYNAME_MAX_ADDRESSES = 71;
      num_ip_addr = std::min(num_ip_addr, GETHOSTBYNAME_MAX_ADDRESSES);
      for (u32 i = 0; i < num_ip_addr; ++i)
      {
        u32 addr = request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4;
        Memory::Write_U32_Swap(*(u32*)(remoteHost->h_addr_list[i]), addr);
      }

      // List of pointers to IP addresses; located at offset 0x340.
      // This must be exact: PPC code to convert the struct hardcodes
      // this offset.
      static const u32 GETHOSTBYNAME_IP_PTR_LIST_OFFSET = 0x340;
      Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET,
                        request.buffer_out + 12);
      for (u32 i = 0; i < num_ip_addr; ++i)
      {
        u32 addr = request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + i * 4;
        Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_LIST_OFFSET + i * 4, addr);
      }
      Memory::Write_U32(0, request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4);

      // Aliases - empty. (Hardware doesn't return anything.)
      Memory::Write_U32(request.buffer_out + GETHOSTBYNAME_IP_PTR_LIST_OFFSET + num_ip_addr * 4,
                        request.buffer_out + 4);

      // Returned struct must be ipv4.
      _assert_msg_(IOS_NET,
                   remoteHost->h_addrtype == AF_INET && remoteHost->h_length == sizeof(u32),
                   "returned host info is not IPv4");
      Memory::Write_U16(AF_INET, request.buffer_out + 8);
      Memory::Write_U16(sizeof(u32), request.buffer_out + 10);

      return_value = 0;
    }
    else
    {
      return_value = -1;
    }

    break;
  }

  case IOCTL_SO_ICMPCANCEL:
    ERROR_LOG(IOS_NET, "IOCTL_SO_ICMPCANCEL");

  default:
    request.DumpUnknown(GetDeviceName(), LogTypes::IOS_NET);
  }
Ejemplo n.º 7
0
// The front SD slot
IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress)
{
  u32 Cmd = Memory::Read_U32(_CommandAddress + 0xC);

  u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
  u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
  u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
  u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);

  // As a safety precaution we fill the out buffer with zeros to avoid
  // returning nonsense values
  Memory::Memset(BufferOut, 0, BufferOutSize);

  u32 ReturnValue = 0;
  switch (Cmd)
  {
  case IOCTL_WRITEHCR:
  {
    u32 reg = Memory::Read_U32(BufferIn);
    u32 val = Memory::Read_U32(BufferIn + 16);

    INFO_LOG(WII_IPC_SD, "IOCTL_WRITEHCR 0x%08x - 0x%08x", reg, val);

    if (reg >= 0x200)
    {
      WARN_LOG(WII_IPC_SD, "IOCTL_WRITEHCR out of range");
      break;
    }

    if ((reg == HCR_CLOCKCONTROL) && (val & 1))
    {
      // Clock is set to oscillate, enable bit 1 to say it's stable
      m_Registers[reg] = val | 2;
    }
    else if ((reg == HCR_SOFTWARERESET) && val)
    {
      // When a reset is specified, the register gets cleared
      m_Registers[reg] = 0;
    }
    else
    {
      // Default to just storing the new value
      m_Registers[reg] = val;
    }
  }
  break;

  case IOCTL_READHCR:
  {
    u32 reg = Memory::Read_U32(BufferIn);

    if (reg >= 0x200)
    {
      WARN_LOG(WII_IPC_SD, "IOCTL_READHCR out of range");
      break;
    }

    u32 val = m_Registers[reg];
    INFO_LOG(WII_IPC_SD, "IOCTL_READHCR 0x%08x - 0x%08x", reg, val);

    // Just reading the register
    Memory::Write_U32(val, BufferOut);
  }
  break;

  case IOCTL_RESETCARD:
    INFO_LOG(WII_IPC_SD, "IOCTL_RESETCARD");
    if (m_Card)
      m_Status |= CARD_INITIALIZED;
    // Returns 16bit RCA and 16bit 0s (meaning success)
    Memory::Write_U32(0x9f620000, BufferOut);
    break;

  case IOCTL_SETCLK:
  {
    INFO_LOG(WII_IPC_SD, "IOCTL_SETCLK");
    // libogc only sets it to 1 and makes sure the return isn't negative...
    // one half of the sdclk divisor: a power of two or zero.
    u32 clock = Memory::Read_U32(BufferIn);
    if (clock != 1)
      INFO_LOG(WII_IPC_SD, "Setting to %i, interesting", clock);
  }
  break;

  case IOCTL_SENDCMD:
    INFO_LOG(WII_IPC_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(BufferIn), _CommandAddress);
    ReturnValue = ExecuteCommand(BufferIn, BufferInSize, 0, 0, BufferOut, BufferOutSize);
    break;

  case IOCTL_GETSTATUS:
    if (SConfig::GetInstance().m_WiiSDCard)
      m_Status |= CARD_INSERTED;
    else
      m_Status = CARD_NOT_EXIST;
    INFO_LOG(WII_IPC_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s",
             (m_Status & CARD_INSERTED) ? "inserted" : "not present",
             (m_Status & CARD_INITIALIZED) ? " and initialized" : "");
    Memory::Write_U32(m_Status, BufferOut);
    break;

  case IOCTL_GETOCR:
    INFO_LOG(WII_IPC_SD, "IOCTL_GETOCR");
    Memory::Write_U32(0x80ff8000, BufferOut);
    break;

  default:
    ERROR_LOG(WII_IPC_SD, "Unknown SD IOCtl command (0x%08x)", Cmd);
    break;
  }

  // INFO_LOG(WII_IPC_SD, "InBuffer");
  // DumpCommands(BufferIn, BufferInSize / 4, LogTypes::WII_IPC_SD);
  // INFO_LOG(WII_IPC_SD, "OutBuffer");
  // DumpCommands(BufferOut, BufferOutSize/4, LogTypes::WII_IPC_SD);

  if (ReturnValue == RET_EVENT_REGISTER)
  {
    // async
    m_event.addr = _CommandAddress;
    Memory::Write_U32(0, _CommandAddress + 0x4);
    // Check if the condition is already true
    EventNotify();
    return GetNoReply();
  }
  else if (ReturnValue == RET_EVENT_UNREGISTER)
  {
    // release returns 0
    // unknown sd int
    // technically we do it out of order, oh well
    EnqueueReply(m_event.addr, EVENT_INVALID);
    m_event.addr = 0;
    m_event.type = EVENT_NONE;
    Memory::Write_U32(0, _CommandAddress + 0x4);
    return GetDefaultReply();
  }
  else
  {
    Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
    return GetDefaultReply();
  }
}
Ejemplo n.º 8
0
void CWII_IPC_HLE_Device_usb_oh0_57e_308::SetRegister(const u32 cmd_ptr)
{
	WARN_LOG(OSHLE, "cmd -> %s",
		ArrayToString(Memory::GetPointer(cmd_ptr), 10, 16).c_str());

	const u8 reg = Memory::Read_U8(cmd_ptr + 1) & ~1;
	const u16 arg1 = Memory::Read_U16(cmd_ptr + 2);
	const u16 arg2 = Memory::Read_U16(cmd_ptr + 4);
	//u16 arg3 = Memory::Read_U16(cmd_ptr + 6);
	//u16 count = Memory::Read_U16(cmd_ptr + 8);

	_dbg_assert_(OSHLE, Memory::Read_U8(cmd_ptr) == 0x9a);
	_dbg_assert_(OSHLE, (Memory::Read_U8(cmd_ptr + 1) & 1) == 0);

	switch (reg)
	{
	case SAMPLER_STATE:
		sampler.sample_on = !!arg1;
		break;
	case SAMPLER_FREQ:
		switch (arg1)
		{
		case FREQ_8KHZ:
			sampler.freq = 8000;
			break;
		case FREQ_11KHZ:
			sampler.freq = 11025;
			break;
		case FREQ_RESERVED:
		case FREQ_16KHZ:
		default:
			sampler.freq = 16000;
			break;
		}
		break;
	case SAMPLER_GAIN:
		switch (arg1 & ~0x300)
		{
		case GAIN_00dB:
			sampler.gain = 0;
			break;
		case GAIN_15dB:
			sampler.gain = 15;
			break;
		case GAIN_30dB:
			sampler.gain = 30;
			break;
		case GAIN_36dB:
		default:
			sampler.gain = 36;
			break;
		}
		break;
	case EC_STATE:
		sampler.ec_reset = !!arg1;
		break;
	case SP_STATE:
		switch (arg1)
		{
		case SP_ENABLE:
			sampler.sp_on = arg2 == 0;
			break;
		case SP_SIN:
			break;
		case SP_SOUT:
			break;
		case SP_RIN:
			break;
		}
		break;
	case SAMPLER_MUTE:
		sampler.mute = !!arg1;
		break;
	}
}
Ejemplo n.º 9
0
void CWII_IPC_HLE_Device_usb_oh0_57e_308::GetRegister(const u32 cmd_ptr) const
{
	const u8 reg = Memory::Read_U8(cmd_ptr + 1) & ~1;
	const u32 arg1 = cmd_ptr + 2;
	const u32 arg2 = cmd_ptr + 4;

	_dbg_assert_(OSHLE, Memory::Read_U8(cmd_ptr) == 0x9a);
	_dbg_assert_(OSHLE, (Memory::Read_U8(cmd_ptr + 1) & 1) == 1);

	switch (reg)
	{
	case SAMPLER_STATE:
		Memory::Write_U16(sampler.sample_on ? 1 : 0, arg1);
		break;
	case SAMPLER_FREQ:
		switch (sampler.freq)
		{
		case 8000:
			Memory::Write_U16(FREQ_8KHZ, arg1);
			break;
		case 11025:
			Memory::Write_U16(FREQ_11KHZ, arg1);
			break;
		case 16000:
		default:
			Memory::Write_U16(FREQ_16KHZ, arg1);
			break;
		}
		break;
	case SAMPLER_GAIN:
		switch (sampler.gain)
		{
		case 0:
			Memory::Write_U16(0x300 | GAIN_00dB, arg1);
			break;
		case 15:
			Memory::Write_U16(0x300 | GAIN_15dB, arg1);
			break;
		case 30:
			Memory::Write_U16(0x300 | GAIN_30dB, arg1);
			break;
		case 36:
		default:
			Memory::Write_U16(0x300 | GAIN_36dB, arg1);
			break;
		}
		break;
	case EC_STATE:
		Memory::Write_U16(sampler.ec_reset ? 1 : 0, arg1);
		break;
	case SP_STATE:
		switch (Memory::Read_U16(arg1))
		{
		case SP_ENABLE:
			Memory::Write_U16(sampler.sp_on ? 0 : 1, arg2);
			break;
		case SP_SIN:
			break;
		case SP_SOUT:
			Memory::Write_U16(0x39B0, arg2); // 6dB TODO actually calc?
			break;
		case SP_RIN:
			break;
		}
		break;
	case SAMPLER_MUTE:
		Memory::Write_U16(sampler.mute ? 1 : 0, arg1);
		break;
	}

	WARN_LOG(OSHLE, "cmd <- %s",
		ArrayToString(Memory::GetPointer(cmd_ptr), 10, 16).c_str());
}
Ejemplo n.º 10
0
IPCCommandResult CWII_IPC_HLE_Device_usb_ven::IOCtl(u32 CommandAddress)
{
	IPCCommandResult SendReply = GetNoReply();
	u32 Command			= Memory::Read_U32(CommandAddress + 0x0c);
	u32 BufferIn		= Memory::Read_U32(CommandAddress + 0x10);
	u32 BufferInSize	= Memory::Read_U32(CommandAddress + 0x14);
	u32 BufferOut		= Memory::Read_U32(CommandAddress + 0x18);
	u32 BufferOutSize	= Memory::Read_U32(CommandAddress + 0x1c);

	WARN_LOG(OSHLE, "%s - IOCtl:%x", GetDeviceName().c_str(), Command);
	WARN_LOG(OSHLE, "%x:%x %x:%x", BufferIn, BufferInSize, BufferOut, BufferOutSize);

	switch (Command)
	{
	case USBV5_IOCTL_GETVERSION:
		Memory::Write_U32(0x50001, BufferOut);
		SendReply = GetDefaultReply();
		break;

	case USBV5_IOCTL_GETDEVICECHANGE:
		{
		// fd
		Memory::Write_U32(0xcd000030, BufferOut);
		// vid, pid
		Memory::Write_U32(0x046d0a03, BufferOut + 4);
		// token
		//Memory::Write_U32(0, BufferOut + 8);
		
		// sent on change
		static bool firstcall = true;
		if (firstcall)
			SendReply = GetDefaultReply(), firstcall = false;
		// num devices
		Memory::Write_U32(1, CommandAddress + 4);
		return SendReply;
		}
		break;

	case USBV5_IOCTL_ATTACHFINISH:
		SendReply = GetDefaultReply();
		break;

	case USBV5_IOCTL_SUSPEND_RESUME:
		WARN_LOG(OSHLE, "device:%i resumed:%i", Memory::Read_U32(BufferIn), Memory::Read_U32(BufferIn + 4));
		SendReply = GetDefaultReply();
		break;

	case USBV5_IOCTL_GETDEVPARAMS:
		{
		s32 device = Memory::Read_U32(BufferIn);
		u32 unk = Memory::Read_U32(BufferIn + 4);

		WARN_LOG(OSHLE, "USBV5_IOCTL_GETDEVPARAMS device:%i unk:%i", device, unk);

		Memory::Write_U32(0, BufferOut);

		SendReply = GetDefaultReply();
		}
		break;

	default:
		//WARN_LOG(OSHLE, "%x:%x %x:%x", BufferIn, BufferInSize, BufferOut, BufferOutSize);
		break;
	}

	Memory::Write_U32(0, CommandAddress + 4);
	return SendReply;
}
Ejemplo n.º 11
0
IPCCommandResult CWII_IPC_HLE_Device_usb_oh0_57e_308::IOCtlV(u32 CommandAddress)
{
	IPCCommandResult SendReply = GetNoReply();

	SIOCtlVBuffer CommandBuffer(CommandAddress);

	switch (CommandBuffer.Parameter)
	{
	case USBV0_IOCTL_CTRLMSG:
		{
			USBSetupPacket setup_packet;
			setup_packet.bmRequestType	= *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address);
			setup_packet.bRequest		= *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address);
			setup_packet.wValue			= *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address);
			setup_packet.wIndex			= *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address);
			setup_packet.wLength		= *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address);

			const u32 payload_addr = CommandBuffer.PayloadBuffer[0].m_Address;

			static bool initialized = false;

#define DIR_TO_DEV	0
#define DIR_TO_HOST	1
#define TYPE_STANDARD	0
#define TYPE_VENDOR		2
#define RECP_DEV	0
#define RECP_INT	1
#define RECP_ENDP	2
#define USBHDR(dir, type, recipient, request) \
	((((dir << 7) | (type << 5) | recipient) << 8) | request)

			switch (((u16)setup_packet.bmRequestType << 8) | setup_packet.bRequest)
			{
			case USBHDR(DIR_TO_DEV, TYPE_STANDARD, RECP_INT, 11):
				_dbg_assert_(OSHLE, setup_packet.wValue == 1);
				break;
			case USBHDR(DIR_TO_HOST, TYPE_STANDARD, RECP_INT, 10):
				Memory::Write_U8(1, payload_addr);
				break;
			case USBHDR(DIR_TO_HOST, TYPE_VENDOR, RECP_INT, 6):
				if (!initialized)
					Memory::Write_U8(0, payload_addr), initialized = true;
				else
					Memory::Write_U8(1, payload_addr);
				break;
			case USBHDR(DIR_TO_DEV, TYPE_VENDOR, RECP_INT, 1):
				SetRegister(payload_addr);
				break;
			case USBHDR(DIR_TO_HOST, TYPE_VENDOR, RECP_INT, 2):
				GetRegister(payload_addr);
				break;
			case USBHDR(DIR_TO_DEV, TYPE_VENDOR, RECP_INT, 0):
				initialized = false;
				break;
			default:
				WARN_LOG(OSHLE, "UNK %02x %02x %04x %04x",
					setup_packet.bmRequestType, setup_packet.bRequest,
					setup_packet.wValue, setup_packet.wLength);
				break;
			}

			// command finished, send a reply to command
			WII_IPC_HLE_Interface::EnqueueReply(CommandBuffer.m_Address);
		}
		break;

	case USBV0_IOCTL_BLKMSG:
		{
		u8 Command = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address);

		switch (Command)
		{
		// used for sending firmware
		case DATA_OUT:
			{
			u16 len = Memory::Read_U16(CommandBuffer.InBuffer[1].m_Address);
			WARN_LOG(OSHLE, "SEND DATA %x %x %x", len, CommandBuffer.PayloadBuffer[0].m_Address, CommandBuffer.PayloadBuffer[0].m_Size);
			SendReply = GetDefaultReply();
			}
			break;

		default:
			WARN_LOG(OSHLE, "UNK BLKMSG %i", Command);
			break;
		}
		}
		break;

	case USBV0_IOCTL_ISOMSG:
		{
		// endp 81 = mic -> console
		// endp 03 = console -> mic
		u8 endpoint = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address);
		u16 length = Memory::Read_U16(CommandBuffer.InBuffer[1].m_Address);
		u8 num_packets = Memory::Read_U8(CommandBuffer.InBuffer[2].m_Address);
		u16 *packet_sizes = (u16*)Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address);
		u8 *packets = Memory::GetPointer(CommandBuffer.PayloadBuffer[1].m_Address);

		/*
		for (int i = 0; i < num_packets; i++)
		{
			u16 packet_len = Common::swap16(packet_sizes[i]);
			WARN_LOG(OSHLE, "packet %i [%i] to endpoint %02x", i, packet_len, endpoint);
			WARN_LOG(OSHLE, "%s", ArrayToString(packets, packet_len, 16).c_str());
			packets += packet_len;
		}
		*/
		
		if (endpoint == AUDIO_IN)
			for (u16 *sample = (u16*)packets; sample != (u16*)(packets + length); sample++)
				*sample = 0x8000;
		
		// TODO actual responses should obey some kinda timey thing
		SendReply = GetDefaultReply();
		}
		break;

	default:
		WARN_LOG(OSHLE, "%s - IOCtlV:", GetDeviceName().c_str());
		WARN_LOG(OSHLE, "    Parameter: 0x%x", CommandBuffer.Parameter);
		WARN_LOG(OSHLE, "    NumberIn: 0x%08x", CommandBuffer.NumberInBuffer);
		WARN_LOG(OSHLE, "    NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer);
		WARN_LOG(OSHLE, "    BufferVector: 0x%08x", CommandBuffer.BufferVector);
		//DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer, LogTypes::OSHLE, LogTypes::LWARNING);
		break;
	}

	Memory::Write_U32(0, CommandAddress + 4);
	return SendReply;
}
Ejemplo n.º 12
0
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written)
{
	switch (stack)
	{
		case MSBT_STACK_UNKNOWN:
		{
			// Try to auto-detect the stack type
			stack = MSBT_STACK_BLUESOLEIL;
			if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written))
				return 1;

			stack = MSBT_STACK_MS;
			if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written))
				return 1;

			stack = MSBT_STACK_UNKNOWN;
			break;
		}
		case MSBT_STACK_MS:
		{
			auto result = pHidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, (ULONG)(len - 1));
			//FlushFileBuffers(dev_handle);

			if (!result)
			{
				auto err = GetLastError();
				if (err == 121)
				{
					// Semaphore timeout
					NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]:  Unable to send data to the Wiimote");
				}
				else if (err != 0x1F)  // Some third-party adapters (DolphinBar) use this
				                       // error code to signal the absence of a Wiimote
				                       // linked to the HID device.
				{
					WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err);
				}
			}

			if (written)
				*written = (result ? (DWORD)len : 0);

			return result;
		}
		case MSBT_STACK_BLUESOLEIL:
		{
			u8 big_buf[MAX_PAYLOAD];
			if (len < MAX_PAYLOAD)
			{
				std::copy(buf, buf + len, big_buf);
				std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0);
				buf = big_buf;
			}

			ResetEvent(hid_overlap_write.hEvent);
			DWORD bytes = 0;
			if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write))
			{
				// If the number of written bytes is requested, block until we can provide
				// this information to the called.
				if (written)
				{
					auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
					if (WAIT_TIMEOUT == wait_result)
					{
						WARN_LOG(WIIMOTE, "_IOWrite: A timeout occurred on writing to Wiimote.");
						CancelIo(dev_handle);
						*written = 0;
					}
					else if (WAIT_FAILED == wait_result)
					{
						WARN_LOG(WIIMOTE, "_IOWrite: A wait error occurred on writing to Wiimote.");
						CancelIo(dev_handle);
						*written = 0;
					}
					else if (!GetOverlappedResult(dev_handle, &hid_overlap_write, written, TRUE))
						*written = 0;
				}
				return 1;
			}
			else
			{
				auto const err = GetLastError();
				if (ERROR_IO_PENDING == err)
				{
					CancelIo(dev_handle);
				}
				return 0;
			}
		}
	}

	return 0;
}
Ejemplo n.º 13
0
int xio_validate_rdma_op(struct xio_vmsg *vmsg,
			 struct xio_sge *rsg_list, size_t rsize,
			 int op_size)
{
	struct xio_iovec_ex *liov;
	uint64_t	raddr;
	uint32_t	rlen;
	uint64_t	laddr;
	uint32_t	llen;
	uint32_t	tot_len = 0;
	size_t lsize;
	int l, r;

	if (rsize < 1) {
		ERROR_LOG("rsize:%zu\n", rsize);
		return -1;
	}

	if (vmsg->data_iovlen > XIO_MAX_IOV || vmsg->data_iovlen == 0) {
		WARN_LOG("IOV size %zu\n", vmsg->data_iovlen);
		return -EINVAL;
	}

	lsize = vmsg->data_iovlen;
	liov  = vmsg->data_iov;

	r = 0;
	rlen  = rsg_list[r].length;
	raddr = rsg_list[r].addr;

	l = 0;
	laddr = uint64_from_ptr(liov[l].iov_base);
	llen  = liov[l].iov_len;

	while (1) {
		if (rlen < llen) {
			r++;
			tot_len	+= rlen;
			if (r == rsize)
				break;
			llen	-= rlen;
			laddr	+= rlen;
			raddr	= rsg_list[r].addr;
			rlen	= rsg_list[r].length;
		} else if (llen < rlen) {
			/* check page alignment when source buff spans more
			 * then one destination buffer */
			l++;
			tot_len += llen;
			if (l == lsize)
				break;
			rlen	-= llen;
			raddr	+= llen;
			laddr	= uint64_from_ptr(liov[l].iov_base);
			llen	= liov[l].iov_len;
		} else {
			l++;
			r++;
			tot_len	+= llen;
			if ((l == lsize) || (r == rsize))
				break;

			laddr	= uint64_from_ptr(liov[l].iov_base);
			llen	= liov[l].iov_len;
			raddr	= rsg_list[r].addr;
			rlen	= rsg_list[r].length;
		}
	}

	/* not enough buffers to complete */
	if (tot_len < op_size) {
		ERROR_LOG("iovec exausted\n");
		return -1;
	}

	return 0;
}
Ejemplo n.º 14
0
bool VideoBackend::Initialize(void* window_handle)
{
  if (!LoadVulkanLibrary())
  {
    PanicAlert("Failed to load Vulkan library.");
    return false;
  }

  // HACK: Use InitBackendInfo to initially populate backend features.
  // This is because things like stereo get disabled when the config is validated,
  // which happens before our device is created (settings control instance behavior),
  // and we don't want that to happen if the device actually supports it.
  InitBackendInfo();
  InitializeShared();

  // Check for presence of the debug layer before trying to enable it
  bool enable_validation_layer = g_Config.bEnableValidationLayer;
  if (enable_validation_layer && !VulkanContext::CheckValidationLayerAvailablility())
  {
    WARN_LOG(VIDEO, "Validation layer requested but not available, disabling.");
    enable_validation_layer = false;
  }

  // Create Vulkan instance, needed before we can create a surface.
  bool enable_surface = (window_handle != nullptr);
  VkInstance instance =
      VulkanContext::CreateVulkanInstance(enable_surface, enable_validation_layer);
  if (instance == VK_NULL_HANDLE)
  {
    PanicAlert("Failed to create Vulkan instance.");
    UnloadVulkanLibrary();
    ShutdownShared();
    return false;
  }

  // Load instance function pointers
  if (!LoadVulkanInstanceFunctions(instance))
  {
    PanicAlert("Failed to load Vulkan instance functions.");
    vkDestroyInstance(instance, nullptr);
    UnloadVulkanLibrary();
    ShutdownShared();
    return false;
  }

  // Create Vulkan surface
  VkSurfaceKHR surface = VK_NULL_HANDLE;
  if (enable_surface)
  {
    surface = SwapChain::CreateVulkanSurface(instance, window_handle);
    if (surface == VK_NULL_HANDLE)
    {
      PanicAlert("Failed to create Vulkan surface.");
      vkDestroyInstance(instance, nullptr);
      UnloadVulkanLibrary();
      ShutdownShared();
      return false;
    }
  }

  // Fill the adapter list, and check if the user has selected an invalid device
  // For some reason nvidia's driver crashes randomly if you call vkEnumeratePhysicalDevices
  // after creating a device..
  VulkanContext::GPUList gpu_list = VulkanContext::EnumerateGPUs(instance);
  size_t selected_adapter_index = static_cast<size_t>(g_Config.iAdapter);
  if (gpu_list.empty())
  {
    PanicAlert("No Vulkan physical devices available.");
    if (surface != VK_NULL_HANDLE)
      vkDestroySurfaceKHR(instance, surface, nullptr);

    vkDestroyInstance(instance, nullptr);
    UnloadVulkanLibrary();
    ShutdownShared();
    return false;
  }
  else if (selected_adapter_index >= gpu_list.size())
  {
    WARN_LOG(VIDEO, "Vulkan adapter index out of range, selecting first adapter.");
    selected_adapter_index = 0;
  }

  // Pass ownership over to VulkanContext, and let it take care of everything.
  g_vulkan_context = VulkanContext::Create(instance, gpu_list[selected_adapter_index], surface,
                                           &g_Config, enable_validation_layer);
  if (!g_vulkan_context)
  {
    PanicAlert("Failed to create Vulkan device");
    UnloadVulkanLibrary();
    ShutdownShared();
    return false;
  }

  // Create swap chain. This has to be done early so that the target size is correct for auto-scale.
  std::unique_ptr<SwapChain> swap_chain;
  if (surface != VK_NULL_HANDLE)
  {
    swap_chain = SwapChain::Create(window_handle, surface, g_Config.IsVSync());
    if (!swap_chain)
    {
      PanicAlert("Failed to create Vulkan swap chain.");
      return false;
    }
  }

  // Create command buffers. We do this separately because the other classes depend on it.
  g_command_buffer_mgr = std::make_unique<CommandBufferManager>(g_Config.bBackendMultithreading);
  if (!g_command_buffer_mgr->Initialize())
  {
    PanicAlert("Failed to create Vulkan command buffers");
    g_command_buffer_mgr.reset();
    g_vulkan_context.reset();
    UnloadVulkanLibrary();
    ShutdownShared();
    return false;
  }

  // Create main wrapper instances.
  g_object_cache = std::make_unique<ObjectCache>();
  g_framebuffer_manager = std::make_unique<FramebufferManager>();
  g_renderer = std::make_unique<Renderer>(std::move(swap_chain));

  // Invoke init methods on main wrapper classes.
  // These have to be done before the others because the destructors
  // for the remaining classes may call methods on these.
  if (!g_object_cache->Initialize() || !FramebufferManager::GetInstance()->Initialize() ||
      !StateTracker::CreateInstance() || !Renderer::GetInstance()->Initialize())
  {
    PanicAlert("Failed to initialize Vulkan classes.");
    g_renderer.reset();
    StateTracker::DestroyInstance();
    g_framebuffer_manager.reset();
    g_object_cache.reset();
    g_command_buffer_mgr.reset();
    g_vulkan_context.reset();
    UnloadVulkanLibrary();
    ShutdownShared();
    return false;
  }

  // Create remaining wrapper instances.
  g_vertex_manager = std::make_unique<VertexManager>();
  g_texture_cache = std::make_unique<TextureCache>();
  g_perf_query = std::make_unique<PerfQuery>();
  if (!VertexManager::GetInstance()->Initialize() || !TextureCache::GetInstance()->Initialize() ||
      !PerfQuery::GetInstance()->Initialize())
  {
    PanicAlert("Failed to initialize Vulkan classes.");
    g_perf_query.reset();
    g_texture_cache.reset();
    g_vertex_manager.reset();
    g_renderer.reset();
    StateTracker::DestroyInstance();
    g_framebuffer_manager.reset();
    g_object_cache.reset();
    g_command_buffer_mgr.reset();
    g_vulkan_context.reset();
    UnloadVulkanLibrary();
    ShutdownShared();
    return false;
  }

  return true;
}
Ejemplo n.º 15
0
void TraversalClient::HandleServerPacket(TraversalPacket* packet)
{
  u8 ok = 1;
  switch (packet->type)
  {
  case TraversalPacketAck:
    if (!packet->ack.ok)
    {
      OnFailure(ServerForgotAboutUs);
      break;
    }
    for (auto it = m_OutgoingTraversalPackets.begin(); it != m_OutgoingTraversalPackets.end(); ++it)
    {
      if (it->packet.requestId == packet->requestId)
      {
        m_OutgoingTraversalPackets.erase(it);
        break;
      }
    }
    break;
  case TraversalPacketHelloFromServer:
    if (m_State != Connecting)
      break;
    if (!packet->helloFromServer.ok)
    {
      OnFailure(VersionTooOld);
      break;
    }
    m_HostId = packet->helloFromServer.yourHostId;
    m_State = Connected;
    if (m_Client)
      m_Client->OnTraversalStateChanged();
    break;
  case TraversalPacketPleaseSendPacket:
  {
    // security is overrated.
    ENetAddress addr = MakeENetAddress(&packet->pleaseSendPacket.address);
    if (addr.port != 0)
    {
      char message[] = "Hello from Dolphin Netplay...";
      ENetBuffer buf;
      buf.data = message;
      buf.dataLength = sizeof(message) - 1;
      enet_socket_send(m_NetHost->socket, &addr, &buf, 1);
    }
    else
    {
      // invalid IPV6
      ok = 0;
    }
    break;
  }
  case TraversalPacketConnectReady:
  case TraversalPacketConnectFailed:
  {
    if (!m_PendingConnect || packet->connectReady.requestId != m_ConnectRequestId)
      break;

    m_PendingConnect = false;

    if (!m_Client)
      break;

    if (packet->type == TraversalPacketConnectReady)
      m_Client->OnConnectReady(MakeENetAddress(&packet->connectReady.address));
    else
      m_Client->OnConnectFailed(packet->connectFailed.reason);
    break;
  }
  default:
    WARN_LOG(NETPLAY, "Received unknown packet with type %d", packet->type);
    break;
  }
  if (packet->type != TraversalPacketAck)
  {
    TraversalPacket ack = {};
    ack.type = TraversalPacketAck;
    ack.requestId = packet->requestId;
    ack.ack.ok = ok;

    ENetBuffer buf;
    buf.data = &ack;
    buf.dataLength = sizeof(ack);
    if (enet_socket_send(m_NetHost->socket, &m_ServerAddress, &buf, 1) == -1)
      OnFailure(SocketSendError);
  }
}
Ejemplo n.º 16
0
IPCCommandResult CWII_IPC_HLE_Device_usb_oh0_46d_a03::IOCtlV(u32 CommandAddress)
{
	IPCCommandResult SendReply = GetNoReply();

	SIOCtlVBuffer CommandBuffer(CommandAddress);

	switch (CommandBuffer.Parameter)
	{
	case USBV0_IOCTL_CTRLMSG:
		{
			USBSetupPacket setup_packet;
			setup_packet.bmRequestType	= *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address);
			setup_packet.bRequest		= *( u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address);
			setup_packet.wValue			= *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address);
			setup_packet.wIndex			= *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address);
			setup_packet.wLength		= *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address);

			const u32 payload_addr = CommandBuffer.PayloadBuffer[0].m_Address;

#define DIR_TO_DEV	0
#define DIR_TO_HOST	1
#define TYPE_STANDARD	0
#define TYPE_CLASS		1
#define TYPE_VENDOR		2
#define RECP_DEV	0
#define RECP_INT	1
#define RECP_ENDP	2
#define USBHDR(dir, type, recipient, request) \
	((((dir << 7) | (type << 5) | recipient) << 8) | request)

			switch (((u16)setup_packet.bmRequestType << 8) | setup_packet.bRequest)
			{
			case USBHDR(DIR_TO_HOST, TYPE_STANDARD, RECP_DEV, 6):
				// GET_DESCRIPTOR
				switch (setup_packet.wValue >> 8)
				{
					// CONFIGURATION
				case 2:
					{
					const usb_configurationdesc config = { 9, 2, 121, 2, 1, 3, 0x80, 30 };
					if (setup_packet.wLength == 9)
					{
						memcpy(Memory::GetPointer(payload_addr), &config, setup_packet.wLength);
					}
					else
					{
						#define LE24(x) (x & 0xff), ((x >> 8) & 0xff), (x >> 16)
						#pragma pack(push, 1)
						struct {
							usb_configurationdesc config;
							usb_interfacedesc int0;
							struct audiocontrol_hdr {
								u8 bLength;
								u8 bDescriptorType;
								u8 bDescriptorSubtype;
							};
							struct {
								audiocontrol_hdr hdr;
								u16 bcdADC;
								u16 wTotalLength;
								u8 bInCollection;
								u8 baInterfaceNr;
							} audiocontrol_header;
							struct {
								audiocontrol_hdr hdr;
								u8 bTerminalID;
								u16 wTerminalType;
								u8 bAssocTerminal;
								u8 bNrChannels;
								u16 wChannelConfig;
								u8 iChannelNames;
								u8 iTerminal;
							} audiocontrol_input_terminal;
							struct {
								audiocontrol_hdr hdr;
								u8 bUnitID;
								u8 bSourceID;
								u8 bControlSize;
								u8 bmaControls0;
								u8 bmaControls1;
								u8 iFeature;
							} audiocontrol_feature_unit;
							struct {
								audiocontrol_hdr hdr;
								u8 bTerminalID;
								u16 wTerminalType;
								u8 bAssocTerminal;
								u8 bSourceID;
								u8 iTerminal;
							} audiocontrol_output_terminal;
							usb_interfacedesc int1;
							usb_interfacedesc int2;
							struct {
								audiocontrol_hdr hdr;
								u8 bTerminalLink;
								u8 bDelay;
								u16 wFormatTag;
							} audiocontrol_as_general;
							struct {
								audiocontrol_hdr hdr;
								u8 bFormatType;
								u8 bNrChannels;
								u8 bSubframeSize;
								u8 bBitResolution;
								u8 bSamFreqType;
								u8 tSamFreq[3 * 5];
							} audiocontrol_format_type;
							usb_endpointdesc endp;
							struct {
								audiocontrol_hdr hdr;
								u8 bmAttributes;
								u8 bLockDelayUnits;
								u16 wLockDelay;
							} audiocontrol_ep_general;
						} const fullconfig = {
							config,
								{ 9, 4, 0, 0, 0, 1, 1, 0, 0 },
									{ 9, 36, 1, 0x100, 39, 1, 1 },
									{ 12, 36, 2, 13, 0x201, 0, 1, 0, 0, 0 },
									{ 9, 36, 6, 2, 13, 1, 3, 0 },
									{ 9, 36, 3, 10, 0x101, 0, 2, 0 },
								{ 9, 4, 1, 0, 0, 1, 2, 0, 0 },
								{ 9, 4, 1, 1, 1, 1, 2, 0, 0 },
									{ 7, 36, 1, 10, 0, 1 },
									{ 23, 36, 2, 1, 1, 2, 16, 5,
										LE24(8000), LE24(11025), LE24(22050),
										LE24(44100), LE24(48000) },
									{ 9, 5, 0x84, 13, 0x60, 1, 0, 0	},
										{ 7, 37, 1, 1, 2, 1 }
						};
						#pragma pack(pop)
						#undef LE24
						memcpy(Memory::GetPointer(payload_addr), &fullconfig, setup_packet.wLength);
					}

					Memory::Write_U32(sizeof(USBSetupPacket) + setup_packet.wLength, CommandAddress + 4);
					return GetDefaultReply();
					}
					break;

				default:
					goto outerdefault;
				}
				break;

			case USBHDR(DIR_TO_HOST, TYPE_CLASS, RECP_INT, 0x82):
			case USBHDR(DIR_TO_HOST, TYPE_CLASS, RECP_INT, 0x83):
				if (setup_packet.bRequest & 1)
					Memory::Write_U16(0x7fff, payload_addr);
				else
					Memory::Write_U16(0x8000, payload_addr);
				break;

			case USBHDR(DIR_TO_DEV, TYPE_CLASS, RECP_ENDP, 1):
				{
				u32 freq = *(u32*)Memory::GetPointer(payload_addr) & 0xffffff;
				WARN_LOG(OSHLE, "set freq: %x", freq);
				}
				break;

			case USBHDR(DIR_TO_DEV, TYPE_STANDARD, RECP_INT, 11):
				break;

			outerdefault:
			default:
				WARN_LOG(OSHLE, "UNK %02x %02x %04x %04x",
					setup_packet.bmRequestType, setup_packet.bRequest,
					setup_packet.wValue, setup_packet.wLength);
				break;
			}

			// command finished, send a reply to command
			WII_IPC_HLE_Interface::EnqueueReply(CommandBuffer.m_Address);
		}
		break;

	case USBV0_IOCTL_ISOMSG:
		{
		// endp 81 = mic -> console
		// endp 03 = console -> mic
		u8 endpoint = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address);
		u16 length = Memory::Read_U16(CommandBuffer.InBuffer[1].m_Address);
		u8 num_packets = Memory::Read_U8(CommandBuffer.InBuffer[2].m_Address);
		u16 *packet_sizes = (u16*)Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address);
		u8 *packets = Memory::GetPointer(CommandBuffer.PayloadBuffer[1].m_Address);

		u16 packet_len = Common::swap16(packet_sizes[0]);
		WARN_LOG(OSHLE, "%i to endpoint %02x", packet_len, endpoint);

		/*
		for (int i = 0; i < num_packets; i++)
		{
			u16 packet_len = Common::swap16(packet_sizes[i]);
			WARN_LOG(OSHLE, "packet %i [%i] to endpoint %02x", i, packet_len, endpoint);
			WARN_LOG(OSHLE, "%s", ArrayToString(packets, packet_len, 16).c_str());
			packets += packet_len;
		}
		*/
		
		if (endpoint == AUDIO_IN)
			for (u16 *sample = (u16*)packets; sample != (u16*)(packets + length); sample++)
				*sample = 0;
		
		// TODO actual responses should obey some kinda timey thing
		SendReply = GetDefaultReply();
		}
		break;

	default:
		WARN_LOG(OSHLE, "%s - IOCtlV:", GetDeviceName().c_str());
		WARN_LOG(OSHLE, "    Parameter: 0x%x", CommandBuffer.Parameter);
		WARN_LOG(OSHLE, "    NumberIn: 0x%08x", CommandBuffer.NumberInBuffer);
		WARN_LOG(OSHLE, "    NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer);
		WARN_LOG(OSHLE, "    BufferVector: 0x%08x", CommandBuffer.BufferVector);
		//DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer, LogTypes::OSHLE, LogTypes::LWARNING);
		break;
	}

	Memory::Write_U32(0, CommandAddress + 4);
	return SendReply;
}
Ejemplo n.º 17
0
void ExecuteCommand(u32 _Address)
{
    IPCCommandResult result = IPC_NO_REPLY;

    IPCCommandType Command = static_cast<IPCCommandType>(Memory::Read_U32(_Address));
    s32 DeviceID = Memory::Read_U32(_Address + 8);

    IWII_IPC_HLE_Device* pDevice = (DeviceID >= 0 && DeviceID < IPC_MAX_FDS) ? g_FdMap[DeviceID] : nullptr;

    INFO_LOG(WII_IPC_HLE, "-->> Execute Command Address: 0x%08x (code: %x, device: %x) %p", _Address, Command, DeviceID, pDevice);

    switch (Command)
    {
    case IPC_CMD_OPEN:
    {
        u32 Mode = Memory::Read_U32(_Address + 0x10);
        DeviceID = getFreeDeviceId();

        std::string DeviceName = Memory::GetString(Memory::Read_U32(_Address + 0xC));

        WARN_LOG(WII_IPC_HLE, "Trying to open %s as %d", DeviceName.c_str(), DeviceID);
        if (DeviceID >= 0)
        {
            if (DeviceName.find("/dev/es") == 0)
            {
                u32 j;
                for (j=0; j<ES_MAX_COUNT; j++)
                {
                    if (!es_inuse[j])
                    {
                        es_inuse[j] = true;
                        g_FdMap[DeviceID] = es_handles[j];
                        result = es_handles[j]->Open(_Address, Mode);
                        Memory::Write_U32(DeviceID, _Address+4);
                        break;
                    }
                }

                if (j == ES_MAX_COUNT)
                {
                    Memory::Write_U32(FS_EESEXHAUSTED, _Address + 4);
                    result = IPC_DEFAULT_REPLY;
                }
            }
            else if (DeviceName.find("/dev/") == 0)
            {
                pDevice = GetDeviceByName(DeviceName);
                if (pDevice)
                {
                    g_FdMap[DeviceID] = pDevice;
                    result = pDevice->Open(_Address, Mode);
                    INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)",
                             pDevice->GetDeviceName().c_str(), DeviceID, Mode);
                    Memory::Write_U32(DeviceID, _Address+4);
                }
                else
                {
                    WARN_LOG(WII_IPC_HLE, "Unimplemented device: %s", DeviceName.c_str());
                    Memory::Write_U32(FS_ENOENT, _Address+4);
                    result = IPC_DEFAULT_REPLY;
                }
            }
            else
            {
                pDevice = CreateFileIO(DeviceID, DeviceName);
                result = pDevice->Open(_Address, Mode);

                INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)",
                         pDevice->GetDeviceName().c_str(), DeviceID, Mode);
                if (Memory::Read_U32(_Address + 4) == (u32)DeviceID)
                {
                    g_FdMap[DeviceID] = pDevice;
                }
                else
                {
                    delete pDevice;
                    pDevice = nullptr;
                }
            }
        }
        else
        {
            Memory::Write_U32(FS_EFDEXHAUSTED, _Address + 4);
            result = IPC_DEFAULT_REPLY;
        }
        break;
    }
    case IPC_CMD_CLOSE:
    {
        if (pDevice)
        {
            result = pDevice->Close(_Address);

            for (u32 j=0; j<ES_MAX_COUNT; j++)
            {
                if (es_handles[j] == g_FdMap[DeviceID])
                {
                    es_inuse[j] = false;
                }
            }

            g_FdMap[DeviceID] = nullptr;

            // Don't delete hardware
            if (!pDevice->IsHardware())
            {
                delete pDevice;
                pDevice = nullptr;
            }
        }
        else
        {
            Memory::Write_U32(FS_EINVAL, _Address + 4);
            result = IPC_DEFAULT_REPLY;
        }
        break;
    }
    case IPC_CMD_READ:
    {
        if (pDevice)
        {
            result = pDevice->Read(_Address);
        }
        else
        {
            Memory::Write_U32(FS_EINVAL, _Address + 4);
            result = IPC_DEFAULT_REPLY;
        }
        break;
    }
    case IPC_CMD_WRITE:
    {
        if (pDevice)
        {
            result = pDevice->Write(_Address);
        }
        else
        {
            Memory::Write_U32(FS_EINVAL, _Address + 4);
            result = IPC_DEFAULT_REPLY;
        }
        break;
    }
    case IPC_CMD_SEEK:
    {
        if (pDevice)
        {
            result = pDevice->Seek(_Address);
        }
        else
        {
            Memory::Write_U32(FS_EINVAL, _Address + 4);
            result = IPC_DEFAULT_REPLY;
        }
        break;
    }
    case IPC_CMD_IOCTL:
    {
        if (pDevice)
        {
            result = pDevice->IOCtl(_Address);
        }
        break;
    }
    case IPC_CMD_IOCTLV:
    {
        if (pDevice)
        {
            result = pDevice->IOCtlV(_Address);
        }
        break;
    }
    default:
    {
        _dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address);
        break;
    }
    }

    // Ensure replies happen in order
    const s64 ticks_until_last_reply = last_reply_time - CoreTiming::GetTicks();
    if (ticks_until_last_reply > 0)
        result.reply_delay_ticks += ticks_until_last_reply;
    last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks;

    if (result.send_reply)
    {
        // The original hardware overwrites the command type with the async reply type.
        Memory::Write_U32(IPC_REP_ASYNC, _Address);
        // IOS also seems to write back the command that was responded to in the FD field.
        Memory::Write_U32(Command, _Address + 8);
        // Generate a reply to the IPC command
        EnqueueReply(_Address, (int)result.reply_delay_ticks);
    }
}
Ejemplo n.º 18
0
u32 ISOFileSystem::OpenFile(std::string filename, FileAccess access, const char *devicename)
{
	// LBN unittest
	/*
	u32 a, b;
	if (parseLBN("/sce_lbn0x307aa_size0xefffe000", &a, &b)) {
		ERROR_LOG(FILESYS, "lbn: %08x %08x", a, b);
	} else {
		ERROR_LOG(FILESYS, "faillbn: %08x %08x", a, b);
	}*/


	OpenFileEntry entry;
	entry.isRawSector = false;
	entry.isBlockSectorMode = false;

	if (filename.compare(0,8,"/sce_lbn") == 0)
	{
		u32 sectorStart = 0xFFFFFFFF, readSize = 0xFFFFFFFF;
		parseLBN(filename, &sectorStart, &readSize);
		if (sectorStart >= blockDevice->GetNumBlocks())
		{
			WARN_LOG(FILESYS, "Unable to open raw sector: %s, sector %08x, max %08x", filename.c_str(), sectorStart, blockDevice->GetNumBlocks());
			return 0;
		}

		DEBUG_LOG(FILESYS, "Got a raw sector open: %s, sector %08x, size %08x", filename.c_str(), sectorStart, readSize);
		u32 newHandle = hAlloc->GetNewHandle();
		entry.seekPos = 0;
		entry.file = 0;
		entry.isRawSector = true;
		entry.sectorStart = sectorStart;
		entry.openSize = readSize;
		// when open as "umd1:/sce_lbn0x0_size0x6B49D200", that mean open umd1 as a block device.
		// the param in sceIoLseek and sceIoRead is lba mode. we must mark it.
		if(strncmp(devicename, "umd0:", 5)==0 || strncmp(devicename, "umd1:", 5)==0)
			entry.isBlockSectorMode = true;

		entries[newHandle] = entry;
		return newHandle;
	}

	if (access & FILEACCESS_WRITE)
	{
		ERROR_LOG(FILESYS, "Can't open file %s with write access on an ISO partition", filename.c_str());
		return 0;
	}

	// May return entireISO for "umd0:"
	entry.file = GetFromPath(filename);
	if (!entry.file){
		return 0;
	}

	if (entry.file==&entireISO)
		entry.isBlockSectorMode = true;

	entry.seekPos = 0;

	u32 newHandle = hAlloc->GetNewHandle();
	entries[newHandle] = entry;
	return newHandle;
}
Ejemplo n.º 19
0
bool SConfig::AutoSetup(EBootBS2 _BootBS2)
{
	std::string set_region_dir(EUR_DIR);

	switch (_BootBS2)
	{
	case BOOT_DEFAULT:
		{
			bool bootDrive = cdio_is_cdrom(m_strFilename);
			// Check if the file exist, we may have gotten it from a --elf command line
			// that gave an incorrect file name
			if (!bootDrive && !File::Exists(m_strFilename))
			{
				PanicAlertT("The specified file \"%s\" does not exist", m_strFilename.c_str());
				return false;
			}

			std::string Extension;
			SplitPath(m_strFilename, nullptr, nullptr, &Extension);
			if (!strcasecmp(Extension.c_str(), ".gcm") ||
				!strcasecmp(Extension.c_str(), ".iso") ||
				!strcasecmp(Extension.c_str(), ".wbfs") ||
				!strcasecmp(Extension.c_str(), ".ciso") ||
				!strcasecmp(Extension.c_str(), ".gcz") ||
				bootDrive)
			{
				m_BootType = BOOT_ISO;
				std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename));
				if (pVolume == nullptr)
				{
					if (bootDrive)
						PanicAlertT("Could not read \"%s\".  "
								"There is no disc in the drive, or it is not a GC/Wii backup.  "
								"Please note that original GameCube and Wii discs cannot be read "
								"by most PC DVD drives.", m_strFilename.c_str());
					else
						PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.",
								m_strFilename.c_str());
					return false;
				}
				m_strName = pVolume->GetInternalName();
				m_strUniqueID = pVolume->GetUniqueID();
				m_revision = pVolume->GetRevision();

				// Check if we have a Wii disc
				bWii = pVolume.get()->GetVolumeType() == DiscIO::IVolume::WII_DISC;

				const char* retrieved_region_dir = GetRegionOfCountry(pVolume->GetCountry());
				if (!retrieved_region_dir)
				{
					if (!PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)."
						"\nContinue with PAL region?"))
						return false;
					retrieved_region_dir = EUR_DIR;
				}

				set_region_dir = retrieved_region_dir;
				bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR;
			}
			else if (!strcasecmp(Extension.c_str(), ".elf"))
			{
				bWii = CBoot::IsElfWii(m_strFilename);
				// TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL.
				// This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz, without forcing all GC homebrew to 50Hz.
				// In the future, it probably makes sense to add a Region setting for homebrew somewhere in the emulator config.
				bNTSC = bWii ? false : true;
				set_region_dir = bNTSC ? USA_DIR : EUR_DIR;
				m_BootType = BOOT_ELF;
			}
			else if (!strcasecmp(Extension.c_str(), ".dol"))
			{
				CDolLoader dolfile(m_strFilename);
				bWii = dolfile.IsWii();
				// TODO: See the ELF code above.
				bNTSC = bWii ? false : true;
				set_region_dir = bNTSC ? USA_DIR : EUR_DIR;
				m_BootType = BOOT_DOL;
			}
			else if (!strcasecmp(Extension.c_str(), ".dff"))
			{
				bWii = true;
				set_region_dir = USA_DIR;
				bNTSC = true;
				m_BootType = BOOT_DFF;

				std::unique_ptr<FifoDataFile> ddfFile(FifoDataFile::Load(m_strFilename, true));

				if (ddfFile)
				{
					bWii = ddfFile->GetIsWii();
				}
			}
			else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid())
			{
				std::unique_ptr<DiscIO::IVolume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename));
				const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename);

				if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == nullptr)
				{
					//WAD is valid yet cannot be booted. Install instead.
					u64 installed = DiscIO::CNANDContentManager::Access().Install_WiiWAD(m_strFilename);
					if (installed)
						SuccessAlertT("The WAD has been installed successfully");
					return false; //do not boot
				}

				const char* retrieved_region_dir = GetRegionOfCountry(ContentLoader.GetCountry());
				set_region_dir = retrieved_region_dir ? retrieved_region_dir : EUR_DIR;
				bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR;

				bWii = true;
				m_BootType = BOOT_WII_NAND;

				if (pVolume)
				{
					m_strName = pVolume->GetInternalName();
					m_strUniqueID = pVolume->GetUniqueID();
				}
				else
				{
					// null pVolume means that we are loading from nand folder (Most Likely Wii Menu)
					// if this is the second boot we would be using the Name and id of the last title
					m_strName.clear();
					m_strUniqueID.clear();
				}

				// Use the TitleIDhex for name and/or unique ID if launching from nand folder
				// or if it is not ascii characters (specifically sysmenu could potentially apply to other things)
				std::string titleidstr = StringFromFormat("%016" PRIx64, ContentLoader.GetTitleID());

				if (m_strName.empty())
				{
					m_strName = titleidstr;
				}
				if (m_strUniqueID.empty())
				{
					m_strUniqueID = titleidstr;
				}
			}
			else
			{
				PanicAlertT("Could not recognize ISO file %s", m_strFilename.c_str());
				return false;
			}
		}
		break;

	case BOOT_BS2_USA:
		set_region_dir = USA_DIR;
		m_strFilename.clear();
		bNTSC = true;
		break;

	case BOOT_BS2_JAP:
		set_region_dir = JAP_DIR;
		m_strFilename.clear();
		bNTSC = true;
		break;

	case BOOT_BS2_EUR:
		set_region_dir = EUR_DIR;
		m_strFilename.clear();
		bNTSC = false;
		break;
	}

	// Setup paths
	CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, set_region_dir, true);
	CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, set_region_dir, false);
	m_strSRAM = File::GetUserPath(F_GCSRAM_IDX);
	if (!bWii)
	{
		if (!bHLE_BS2)
		{
			m_strBootROM = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + set_region_dir + DIR_SEP GC_IPL;
			if (!File::Exists(m_strBootROM))
				m_strBootROM = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + set_region_dir + DIR_SEP GC_IPL;

			if (!File::Exists(m_strBootROM))
			{
				WARN_LOG(BOOT, "Bootrom file %s not found - using HLE.", m_strBootROM.c_str());
				bHLE_BS2 = true;
			}
		}
	}
	else if (bWii && !bHLE_BS2)
	{
		WARN_LOG(BOOT, "GC bootrom file will not be loaded for Wii mode.");
		bHLE_BS2 = true;
	}

	return true;
}
Ejemplo n.º 20
0
IVolume::ECountry CountrySwitch(u8 CountryCode)
{
	switch (CountryCode)
	{
		// Region free - fall through to European defaults for now
		case 'A':


		// PAL
		case 'D': // German
			return IVolume::COUNTRY_GERMANY;
			break;

		case 'X': // Used by a couple PAL games
		case 'Y': // German, french

		case 'L': // Japanese import to PAL regions
		case 'M': // Japanese import to PAL regions
		case 'S': // Spanish-speaking regions
		case 'P':
		case 'U': // Australia
			return IVolume::COUNTRY_EUROPE;
			break;

		case 'F':
			return IVolume::COUNTRY_FRANCE;
			break;

		case 'I':
			return IVolume::COUNTRY_ITALY;
			break;

		case 'R':
			return IVolume::COUNTRY_RUSSIA;
			break;

		// NTSC
		case 'E':
		case 'N': // Japanese import to USA and other NTSC regions
		case 'Z': // Prince Of Persia - The Forgotten Sands (WII)
			return IVolume::COUNTRY_USA;
			break;

		case 'J':
			return IVolume::COUNTRY_JAPAN;
			break;

		case 'K':
		case 'T': // Korea with English language
		case 'Q': // Korea with Japanese language
			return IVolume::COUNTRY_KOREA;
			break;

		case 'O':
			return IVolume::COUNTRY_SDK;
			break;

		case 'W':
			return IVolume::COUNTRY_TAIWAN;
			break;

		default:
			if (CountryCode > 'A') // Silently ignore IOS wads
				WARN_LOG(DISCIO, "Unknown Country Code! %c", CountryCode);
			return IVolume::COUNTRY_UNKNOWN;
			break;
	}
}
Ejemplo n.º 21
0
int scePsmfPlayerGetAudioOutSize(u32 psmfPlayer) 
{
	WARN_LOG(HLE, "scePsmfPlayerGetAudioOutSize(%08x)", psmfPlayer);
	return audioSamplesBytes;
}
Ejemplo n.º 22
0
void CEXIMemoryCard::TransferByte(u8& byte)
{
  DEBUG_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: > %02x", byte);
  if (m_uPosition == 0)
  {
    command = byte;  // first byte is command
    byte = 0xFF;     // would be tristate, but we don't care.

    switch (command)  // This seems silly, do we really need it?
    {
    case cmdNintendoID:
    case cmdReadArray:
    case cmdArrayToBuffer:
    case cmdSetInterrupt:
    case cmdWriteBuffer:
    case cmdReadStatus:
    case cmdReadID:
    case cmdReadErrorBuffer:
    case cmdWakeUp:
    case cmdSleep:
    case cmdClearStatus:
    case cmdSectorErase:
    case cmdPageProgram:
    case cmdExtraByteProgram:
    case cmdChipErase:
      DEBUG_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: command %02x at position 0. seems normal.",
                command);
      break;
    default:
      WARN_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: command %02x at position 0", command);
      break;
    }
    if (command == cmdClearStatus)
    {
      status &= ~MC_STATUS_PROGRAMEERROR;
      status &= ~MC_STATUS_ERASEERROR;

      status |= MC_STATUS_READY;

      m_bInterruptSet = 0;

      byte = 0xFF;
      m_uPosition = 0;
    }
  }
  else
  {
    switch (command)
    {
    case cmdNintendoID:
      //
      // Nintendo card:
      // 00 | 80 00 00 00 10 00 00 00
      // "bigben" card:
      // 00 | ff 00 00 05 10 00 00 00 00 00 00 00 00 00 00
      // we do it the Nintendo way.
      if (m_uPosition == 1)
        byte = 0x80;  // dummy cycle
      else
        byte = (u8)(memorycard->GetCardId() >> (24 - (((m_uPosition - 2) & 3) * 8)));
      break;

    case cmdReadArray:
      switch (m_uPosition)
      {
      case 1:  // AD1
        address = byte << 17;
        byte = 0xFF;
        break;
      case 2:  // AD2
        address |= byte << 9;
        break;
      case 3:  // AD3
        address |= (byte & 3) << 7;
        break;
      case 4:  // BA
        address |= (byte & 0x7F);
        break;
      }
      if (m_uPosition > 1)  // not specified for 1..8, anyway
      {
        memorycard->Read(address & (memory_card_size - 1), 1, &byte);
        // after 9 bytes, we start incrementing the address,
        // but only the sector offset - the pointer wraps around
        if (m_uPosition >= 9)
          address = (address & ~0x1FF) | ((address + 1) & 0x1FF);
      }
      break;

    case cmdReadStatus:
      // (unspecified for byte 1)
      byte = status;
      break;

    case cmdReadID:
      if (m_uPosition == 1)  // (unspecified)
        byte = (u8)(card_id >> 8);
      else
        byte = (u8)((m_uPosition & 1) ? (card_id) : (card_id >> 8));
      break;

    case cmdSectorErase:
      switch (m_uPosition)
      {
      case 1:  // AD1
        address = byte << 17;
        break;
      case 2:  // AD2
        address |= byte << 9;
        break;
      }
      byte = 0xFF;
      break;

    case cmdSetInterrupt:
      if (m_uPosition == 1)
      {
        interruptSwitch = byte;
      }
      byte = 0xFF;
      break;

    case cmdChipErase:
      byte = 0xFF;
      break;

    case cmdPageProgram:
      switch (m_uPosition)
      {
      case 1:  // AD1
        address = byte << 17;
        break;
      case 2:  // AD2
        address |= byte << 9;
        break;
      case 3:  // AD3
        address |= (byte & 3) << 7;
        break;
      case 4:  // BA
        address |= (byte & 0x7F);
        break;
      }

      if (m_uPosition >= 5)
        programming_buffer[((m_uPosition - 5) & 0x7F)] = byte;  // wrap around after 128 bytes

      byte = 0xFF;
      break;

    default:
      WARN_LOG(EXPANSIONINTERFACE, "EXI MEMCARD: unknown command byte %02x\n", byte);
      byte = 0xFF;
    }
  }
Ejemplo n.º 23
0
// called from ---UPnP--- thread
// discovers the IGD
static bool InitUPnP()
{
  static bool s_inited = false;
  static bool s_error = false;

  // Don't init if already inited
  if (s_inited)
    return true;

  // Don't init if it failed before
  if (s_error)
    return false;

  s_urls = {};
  s_data = {};

  // Find all UPnP devices
  int upnperror = 0;
  std::unique_ptr<UPNPDev, decltype(&freeUPNPDevlist)> devlist(nullptr, freeUPNPDevlist);
#if MINIUPNPC_API_VERSION >= 14
  devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, 2, &upnperror));
#else
  devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, &upnperror));
#endif
  if (!devlist)
  {
    WARN_LOG(NETPLAY, "An error occurred trying to discover UPnP devices.");

    s_error = true;

    return false;
  }

  // Look for the IGD
  for (UPNPDev* dev = devlist.get(); dev; dev = dev->pNext)
  {
    if (!std::strstr(dev->st, "InternetGatewayDevice"))
      continue;

    int desc_xml_size = 0;
    std::unique_ptr<char, decltype(&std::free)> desc_xml(nullptr, std::free);
    int statusCode = 200;
#if MINIUPNPC_API_VERSION >= 16
    desc_xml.reset(
      static_cast<char*>(miniwget_getaddr(dev->descURL, &desc_xml_size, s_our_ip.data(),
        static_cast<int>(s_our_ip.size()), 0, &statusCode)));
#else
    desc_xml.reset(static_cast<char*>(miniwget_getaddr(
      dev->descURL, &desc_xml_size, s_our_ip.data(), static_cast<int>(s_our_ip.size()), 0)));
#endif
    if (desc_xml && statusCode == 200)
    {
      parserootdesc(desc_xml.get(), desc_xml_size, &s_data);
      GetUPNPUrls(&s_urls, &s_data, dev->descURL, 0);

      NOTICE_LOG(NETPLAY, "Got info from IGD at %s.", dev->descURL);
      break;
    }
    else
    {
      WARN_LOG(NETPLAY, "Error getting info from IGD at %s.", dev->descURL);
    }
  }

  s_inited = true;

  return true;
}
Ejemplo n.º 24
0
bool PointGeometryShader::SetShader(u32 components, float pointSize,
	float texOffset, float vpWidth, float vpHeight, const bool* texOffsetEnable)
{
	if (!m_ready)
		return false;

	// Make sure geometry shader for "components" is available
	ComboMap::iterator shaderIt = m_shaders.find(components);
	if (shaderIt == m_shaders.end())
	{
		// Generate new shader. Warning: not thread-safe.
		static char buffer[16384];
		ShaderCode code;
		code.SetBuffer(buffer);
		GenerateVSOutputStructForGS(code, API_D3D);
		code.Write("\n%s", POINT_GS_COMMON);

		std::stringstream numTexCoordsStream;
		numTexCoordsStream << xfregs.numTexGen.numTexGens;

		INFO_LOG(VIDEO, "Compiling point geometry shader for components 0x%.08X (num texcoords %d)",
			components, xfregs.numTexGen.numTexGens);

		const std::string& numTexCoordsStr = numTexCoordsStream.str();
		D3D_SHADER_MACRO macros[] = {
			{ "NUM_TEXCOORDS", numTexCoordsStr.c_str() },
			{ nullptr, nullptr }
		};
		ID3D11GeometryShader* newShader = D3D::CompileAndCreateGeometryShader(code.GetBuffer(), unsigned int(strlen(code.GetBuffer())), macros);
		if (!newShader)
		{
			WARN_LOG(VIDEO, "Point geometry shader for components 0x%.08X failed to compile", components);
			// Add dummy shader to prevent trying to compile again
			m_shaders[components] = nullptr;
			return false;
		}

		shaderIt = m_shaders.insert(std::make_pair(components, newShader)).first;
	}

	if (shaderIt != m_shaders.end())
	{
		if (shaderIt->second)
		{
			D3D11_MAPPED_SUBRESOURCE map;
			HRESULT hr = D3D::context->Map(m_paramsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
			if (SUCCEEDED(hr))
			{
				PointGSParams* params = (PointGSParams*)map.pData;
				params->PointSize = pointSize;

				params->TexOffset = texOffset;
				params->VpWidth = vpWidth;
				params->VpHeight = vpHeight;
				for (int i = 0; i < 8; ++i)
					params->TexOffsetEnable[i] = texOffsetEnable[i] ? 1.f : 0.f;

				D3D::context->Unmap(m_paramsBuffer, 0);
			}
			else
				ERROR_LOG(VIDEO, "Failed to map point gs params buffer");

			DEBUG_LOG(VIDEO, "Point params: size %f, texOffset %f, vpWidth %f, vpHeight %f",
				pointSize, texOffset, vpWidth, vpHeight);

			D3D::context->GSSetShader(shaderIt->second, nullptr, 0);
			D3D::context->GSSetConstantBuffers(0, 1, &m_paramsBuffer);

			return true;
		}
		else
			return false;
	}
	else
		return false;
}
Ejemplo n.º 25
0
int ThreadManForKernel_f475845d(SceUID threadToStartID, int argSize, u32 argBlockPtr)
{	
	WARN_LOG(SCEKERNEL,"ThreadManForKernel_f475845d:Not support this patcher");
	return sceKernelStartThread(threadToStartID,argSize,argBlockPtr);
}
Ejemplo n.º 26
0
void UCConfMgr::AddConfMember(void)
{
	TUP_RESULT tRet = TUP_FAIL;

	if(!m_strCalleeNum.empty())
	{
		STConfParam item={0};
		item.memStatus = CONF_MEM_INVITING;
		if(m_bIsUCAccount)
		{			
			item.memType = UC_ACCOUNT;
			strcpy_s(item.ucAcc,STRING_LENGTH,m_strCalleeAccount.c_str());
			//添加讨论组UC成员
			UCGroupMgr::Instance().AddUCMemberInGroup(m_strGroupID,m_strCalleeAccount);
			UCGroupMgr::Instance().AddLocalUCMember(m_strGroupID,m_strCalleeAccount,m_strCalleeNum);

		}
		else
		{
			item.memType = UC_IPPHONE;
			strcpy_s(item.ucAcc,STRING_LENGTH,m_strCalleeNum.c_str());
			//增加讨论群组电话用户
			UCGroupMgr::Instance().AddPhoneMemberInGroup(m_strGroupID,m_strCalleeNum);	
			UCGroupMgr::Instance().AddLocalPhoneMember(m_strGroupID,m_strCalleeNum);
		}
		NotifyConfUI(item);

		tRet = tup_call_serverconf_add_attendee(m_uiConfID,1,m_strCalleeNum.c_str(),m_strCalleeNum.size()+1);
		if(tRet != TUP_SUCCESS)
		{
			WARN_LOG("tup_call_serverconf_add_attendee add %s failed",m_strCalleeNum.c_str());
			item.memStatus = CONF_MEM_DEL;
			NotifyConfUI(item);
		}
	}

	
	//要先加UC用户群组再加电话用户,否则被叫端收不到话机用户的增加消息
	UCMemList::iterator ucit = m_confUCMemList.begin();
	UCMemList::iterator ucitEnd = m_confUCMemList.end();
	for(;ucit != ucitEnd;ucit++)
	{
		std::string strBindNO = (*ucit).second;
		if(strBindNO != m_strCalleeNum)//避免重复邀请
		{		
			std::string strAccount = (*ucit).first;
			STConfParam item;
			item.memStatus = CONF_MEM_INVITING;
			item.memType = UC_ACCOUNT;
			strcpy_s(item.ucAcc,STRING_LENGTH,strAccount.c_str());
			NotifyConfUI(item);

			//添加讨论组UC成员
			UCGroupMgr::Instance().AddUCMemberInGroup(m_strGroupID,strAccount);
			UCGroupMgr::Instance().AddLocalUCMember(m_strGroupID,strAccount,strBindNO);

			tRet = tup_call_serverconf_add_attendee(m_uiConfID,1,strBindNO.c_str(),strBindNO.size()+1);
			if(tRet != TUP_SUCCESS)
			{
				WARN_LOG("tup_call_serverconf_add_attendee add %s:%s failed,reason %d",strAccount.c_str(),strBindNO.c_str(),tRet);
				item.memStatus = CONF_MEM_DEL;
				NotifyConfUI(item);
			}
		}
	}

	std::string strGroup;
	PhoneMemList::iterator it = m_confPhoneMemList.begin();
	PhoneMemList::iterator itEnd = m_confPhoneMemList.end();
	for(;it != itEnd;it++)
	{
		std::string strPhoneNum = *it;
		if(strPhoneNum != m_strCalleeNum)//避免重复邀请
		{
			STConfParam item;
			item.memStatus = CONF_MEM_INVITING;
			item.memType = UC_IPPHONE;
			strcpy_s(item.ucAcc,STRING_LENGTH,strPhoneNum.c_str());
			NotifyConfUI(item);

			//增加讨论群组电话用户
			UCGroupMgr::Instance().AddPhoneMemberInGroup(m_strGroupID,strPhoneNum);	
			UCGroupMgr::Instance().AddLocalPhoneMember(m_strGroupID,strPhoneNum);

			tRet = tup_call_serverconf_add_attendee(m_uiConfID,1,strPhoneNum.c_str(),strPhoneNum.size()+1);
			if(tRet != TUP_SUCCESS)
			{
				WARN_LOG("tup_call_serverconf_add_attendee add %s failed",strPhoneNum.c_str());
				item.memStatus = CONF_MEM_DEL;
				NotifyConfUI(item);
			}
		}		
	}

	//主席也要放到成员列表里面
	m_strChairManAccount = UCRegMgr::Instance().GetSelfAccount();
	m_strChairManBindNo = UCRegMgr::Instance().GetBindNO();
	m_confUCMemList[m_strChairManAccount] = m_strChairManBindNo;

	//清除信息
	m_strCalleeNum.clear();
	m_strCalleeAccount.clear();
	m_bIsUCAccount = false;
}
Ejemplo n.º 27
0
int LoadExecForKernel_4AC57943(SceUID cbId) 
{
	WARN_LOG(SCEKERNEL,"LoadExecForKernel_4AC57943:Not support this patcher");
	return sceKernelRegisterExitCallback(cbId);//not sure right
}
Ejemplo n.º 28
0
SceUID sceKernelCreateTls(const char *name, u32 partition, u32 attr, u32 blockSize, u32 count, u32 optionsPtr)
{
	if (!name)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid name", SCE_KERNEL_ERROR_NO_MEMORY);
		return SCE_KERNEL_ERROR_NO_MEMORY;
	}
	if ((attr & ~PSP_TLS_ATTR_KNOWN) >= 0x100)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid attr parameter: %08x", SCE_KERNEL_ERROR_ILLEGAL_ATTR, attr);
		return SCE_KERNEL_ERROR_ILLEGAL_ATTR;
	}
	if (partition < 1 || partition > 9 || partition == 7)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, partition);
		return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT;
	}
	// We only support user right now.
	if (partition != 2 && partition != 6)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid partition %d", SCE_KERNEL_ERROR_ILLEGAL_PERM, partition);
		return SCE_KERNEL_ERROR_ILLEGAL_PERM;
	}

	// There's probably a simpler way to get this same basic formula...
	// This is based on results from a PSP.
	bool illegalMemSize = blockSize == 0 || count == 0;
	if (!illegalMemSize && (u64) blockSize > ((0x100000000ULL / (u64) count) - 4ULL))
		illegalMemSize = true;
	if (!illegalMemSize && (u64) count >= 0x100000000ULL / (((u64) blockSize + 3ULL) & ~3ULL))
		illegalMemSize = true;
	if (illegalMemSize)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): invalid blockSize/count", SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE);
		return SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE;
	}

	int index = -1;
	for (int i = 0; i < TLS_NUM_INDEXES; ++i)
		if (tlsUsedIndexes[i] == false)
		{
			index = i;
			break;
		}

	if (index == -1)
	{
		WARN_LOG_REPORT(HLE, "%08x=sceKernelCreateTls(): ran out of indexes for TLS objects", PSP_ERROR_TOO_MANY_TLS);
		return PSP_ERROR_TOO_MANY_TLS;
	}

	u32 totalSize = blockSize * count;
	u32 blockPtr = userMemory.Alloc(totalSize, (attr & PSP_TLS_ATTR_HIGHMEM) != 0, name);
	userMemory.ListBlocks();

	if (blockPtr == (u32) -1)
	{
		ERROR_LOG(HLE, "%08x=sceKernelCreateTls(%s, %d, %08x, %d, %d, %08x): failed to allocate memory", SCE_KERNEL_ERROR_NO_MEMORY, name, partition, attr, blockSize, count, optionsPtr);
		return SCE_KERNEL_ERROR_NO_MEMORY;
	}

	TLS *tls = new TLS();
	SceUID id = kernelObjects.Create(tls);

	tls->ntls.size = sizeof(tls->ntls);
	strncpy(tls->ntls.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
	tls->ntls.name[KERNELOBJECT_MAX_NAME_LENGTH] = 0;
	tls->ntls.attr = attr;
	tls->ntls.index = index;
	tlsUsedIndexes[index] = true;
	tls->ntls.blockSize = blockSize;
	tls->ntls.totalBlocks = count;
	tls->ntls.freeBlocks = count;
	tls->ntls.numWaitThreads = 0;
	tls->address = blockPtr;
	tls->usage.resize(count, 0);

	WARN_LOG(HLE, "%08x=sceKernelCreateTls(%s, %d, %08x, %d, %d, %08x)", id, name, partition, attr, blockSize, count, optionsPtr);

	// TODO: just alignment?
	if (optionsPtr != 0)
		WARN_LOG(HLE, "sceKernelCreateTls(%s) unsupported options parameter: %08x", name, optionsPtr);
	if ((attr & PSP_TLS_ATTR_PRIORITY) != 0)
		WARN_LOG(HLE, "sceKernelCreateTls(%s) unsupported attr parameter: %08x", name, attr);

	return id;
}
Ejemplo n.º 29
0
static int sceCccIsValidUCS2(u32 c)
{
	WARN_LOG(HLE, "UNIMPL sceCccIsValidUCS2(%08x)", c);
	return c != 0;
}
Ejemplo n.º 30
0
u32 sceAudioOutput2Release()
{
	WARN_LOG(HLE,"sceAudioOutput2Release()");
	chans[0].reserved = false;
	return 0;
}