Example #1
1
namespace NWM {

// 802.11 broadcast MAC address
constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

constexpr u64 DefaultNetworkUptime = 900000000; // 15 minutes in microseconds.

// Note: These values were taken from a packet capture of an o3DS XL
// broadcasting a Super Smash Bros. 4 lobby.
constexpr u16 DefaultExtraCapabilities = 0x0431;

// Size of the SSID broadcast by an UDS beacon frame.
constexpr u8 UDSBeaconSSIDSize = 8;

// The maximum size of the data stored in the EncryptedData0 tag (24).
constexpr u32 EncryptedDataSizeCutoff = 0xFA;

/**
 * NWM Beacon data encryption key, taken from the NWM module code.
 * We stub this with an all-zeros key as that is enough for Citra's purpose.
 * The real key can be used here to generate beacons that will be accepted by
 * a real 3ds.
 */
constexpr std::array<u8, CryptoPP::AES::BLOCKSIZE> nwm_beacon_key = {};

/**
 * Generates a buffer with the fixed parameters of an 802.11 Beacon frame
 * using dummy values.
 * @returns A buffer with the fixed parameters of the beacon frame.
 */
std::vector<u8> GenerateFixedParameters() {
    std::vector<u8> buffer(sizeof(BeaconFrameHeader));

    BeaconFrameHeader header{};
    // Use a fixed default time for now.
    // TODO(Subv): Perhaps use the difference between now and the time the network was started?
    header.timestamp = DefaultNetworkUptime;
    header.beacon_interval = DefaultBeaconInterval;
    header.capabilities = DefaultExtraCapabilities;

    std::memcpy(buffer.data(), &header, sizeof(header));

    return buffer;
}

/**
 * Generates an SSID tag of an 802.11 Beacon frame with an 8-byte all-zero SSID value.
 * @returns A buffer with the SSID tag.
 */
std::vector<u8> GenerateSSIDTag() {
    std::vector<u8> buffer(sizeof(TagHeader) + UDSBeaconSSIDSize);

    TagHeader tag_header{};
    tag_header.tag_id = static_cast<u8>(TagId::SSID);
    tag_header.length = UDSBeaconSSIDSize;

    std::memcpy(buffer.data(), &tag_header, sizeof(TagHeader));

    // The rest of the buffer is already filled with zeros.

    return buffer;
}

/**
 * Generates a buffer with the basic tagged parameters of an 802.11 Beacon frame
 * such as SSID, Rate Information, Country Information, etc.
 * @returns A buffer with the tagged parameters of the beacon frame.
 */
std::vector<u8> GenerateBasicTaggedParameters() {
    // Append the SSID tag
    std::vector<u8> buffer = GenerateSSIDTag();

    // TODO(Subv): Add the SupportedRates tag.
    // TODO(Subv): Add the DSParameterSet tag.
    // TODO(Subv): Add the TrafficIndicationMap tag.
    // TODO(Subv): Add the CountryInformation tag.
    // TODO(Subv): Add the ERPInformation tag.

    return buffer;
}

/**
 * Generates a buffer with the Dummy Nintendo tag.
 * It is currently unknown what this tag does.
 * TODO(Subv): Figure out if this is needed and what it does.
 * @returns A buffer with the Nintendo tagged parameters of the beacon frame.
 */
std::vector<u8> GenerateNintendoDummyTag() {
    // Note: These values were taken from a packet capture of an o3DS XL
    // broadcasting a Super Smash Bros. 4 lobby.
    constexpr std::array<u8, 3> dummy_data = {0x0A, 0x00, 0x00};

    DummyTag tag{};
    tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific);
    tag.header.length = sizeof(DummyTag) - sizeof(TagHeader);
    tag.oui_type = static_cast<u8>(NintendoTagId::Dummy);
    tag.oui = NintendoOUI;
    tag.data = dummy_data;

    std::vector<u8> buffer(sizeof(DummyTag));
    std::memcpy(buffer.data(), &tag, sizeof(DummyTag));

    return buffer;
}

/**
 * Generates a buffer with the Network Info Nintendo tag.
 * This tag contains the network information of the network that is being broadcast.
 * It also contains the application data provided by the application that opened the network.
 * @returns A buffer with the Nintendo network info parameter of the beacon frame.
 */
std::vector<u8> GenerateNintendoNetworkInfoTag(const NetworkInfo& network_info) {
    NetworkInfoTag tag{};
    tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific);
    tag.header.length =
        sizeof(NetworkInfoTag) - sizeof(TagHeader) + network_info.application_data_size;
    tag.appdata_size = network_info.application_data_size;
    // Set the hash to zero initially, it will be updated once we calculate it.
    tag.sha_hash = {};

    // Ensure the network structure has the correct OUI and OUI type.
    ASSERT(network_info.oui_type == static_cast<u8>(NintendoTagId::NetworkInfo));
    ASSERT(network_info.oui_value == NintendoOUI);

    // Ensure the application data size is less than the maximum value.
    ASSERT_MSG(network_info.application_data_size <= ApplicationDataSize, "Data size is too big.");

    // This tag contains the network info structure starting at the OUI.
    std::memcpy(tag.network_info.data(), &network_info.oui_value, tag.network_info.size());

    // Copy the tag and the data so we can calculate the SHA1 over it.
    std::vector<u8> buffer(sizeof(tag) + network_info.application_data_size);
    std::memcpy(buffer.data(), &tag, sizeof(tag));
    std::memcpy(buffer.data() + sizeof(tag), network_info.application_data.data(),
                network_info.application_data_size);

    // Calculate the SHA1 of the contents of the tag.
    std::array<u8, CryptoPP::SHA1::DIGESTSIZE> hash;
    CryptoPP::SHA1().CalculateDigest(hash.data(),
                                     buffer.data() + offsetof(NetworkInfoTag, network_info),
                                     buffer.size() - sizeof(TagHeader));

    // Copy it directly into the buffer, overwriting the zeros that we had previously placed there.
    std::memcpy(buffer.data() + offsetof(NetworkInfoTag, sha_hash), hash.data(), hash.size());

    return buffer;
}

/*
 * Calculates the CTR used for the AES-CTR encryption of the data stored in the
 * EncryptedDataTags.
 * @returns The CTR used for beacon crypto.
 */
std::array<u8, CryptoPP::AES::BLOCKSIZE> GetBeaconCryptoCTR(const NetworkInfo& network_info) {
    BeaconDataCryptoCTR data{};

    data.host_mac = network_info.host_mac_address;
    data.wlan_comm_id = network_info.wlan_comm_id;
    data.id = network_info.id;
    data.network_id = network_info.network_id;

    std::array<u8, CryptoPP::AES::BLOCKSIZE> hash;
    std::memcpy(hash.data(), &data, sizeof(data));

    return hash;
}

/*
 * Serializes the node information into the format needed for network transfer,
 * and then encrypts it with the NWM key.
 * @returns The serialized and encrypted node information.
 */
std::vector<u8> GeneratedEncryptedData(const NetworkInfo& network_info, const NodeList& nodes) {
    std::vector<u8> buffer(sizeof(BeaconData));

    BeaconData data{};
    std::memcpy(buffer.data(), &data, sizeof(BeaconData));

    for (const NodeInfo& node : nodes) {
        // Serialize each node and convert the data from
        // host byte-order to Big Endian.
        BeaconNodeInfo info{};
        info.friend_code_seed = node.friend_code_seed;
        info.network_node_id = node.network_node_id;
        for (int i = 0; i < info.username.size(); ++i)
            info.username[i] = node.username[i];

        buffer.insert(buffer.end(), reinterpret_cast<u8*>(&info),
                      reinterpret_cast<u8*>(&info) + sizeof(info));
    }

    // Calculate the MD5 hash of the data in the buffer, not including the hash field.
    std::array<u8, CryptoPP::Weak::MD5::DIGESTSIZE> hash;
    CryptoPP::Weak::MD5().CalculateDigest(hash.data(),
                                          buffer.data() + offsetof(BeaconData, bitmask),
                                          buffer.size() - sizeof(data.md5_hash));

    // Copy the hash into the buffer.
    std::memcpy(buffer.data(), hash.data(), hash.size());

    // Encrypt the data using AES-CTR and the NWM beacon key.
    using CryptoPP::AES;
    std::array<u8, AES::BLOCKSIZE> counter = GetBeaconCryptoCTR(network_info);
    CryptoPP::CTR_Mode<AES>::Encryption aes;
    aes.SetKeyWithIV(nwm_beacon_key.data(), AES::BLOCKSIZE, counter.data());
    aes.ProcessData(buffer.data(), buffer.data(), buffer.size());

    return buffer;
}

void DecryptBeaconData(const NetworkInfo& network_info, std::vector<u8>& buffer) {
    // Decrypt the data using AES-CTR and the NWM beacon key.
    using CryptoPP::AES;
    std::array<u8, AES::BLOCKSIZE> counter = GetBeaconCryptoCTR(network_info);
    CryptoPP::CTR_Mode<AES>::Decryption aes;
    aes.SetKeyWithIV(nwm_beacon_key.data(), AES::BLOCKSIZE, counter.data());
    aes.ProcessData(buffer.data(), buffer.data(), buffer.size());
}

/**
 * Generates a buffer with the Network Info Nintendo tag.
 * This tag contains the first portion of the encrypted payload in the 802.11 beacon frame.
 * The encrypted payload contains information about the nodes currently connected to the network.
 * @returns A buffer with the first Nintendo encrypted data parameters of the beacon frame.
 */
std::vector<u8> GenerateNintendoFirstEncryptedDataTag(const NetworkInfo& network_info,
                                                      const NodeList& nodes) {
    const size_t payload_size =
        std::min<size_t>(EncryptedDataSizeCutoff, nodes.size() * sizeof(NodeInfo));

    EncryptedDataTag tag{};
    tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific);
    tag.header.length = static_cast<u8>(sizeof(tag) - sizeof(TagHeader) + payload_size);
    tag.oui_type = static_cast<u8>(NintendoTagId::EncryptedData0);
    tag.oui = NintendoOUI;

    std::vector<u8> buffer(sizeof(tag) + payload_size);
    std::memcpy(buffer.data(), &tag, sizeof(tag));

    std::vector<u8> encrypted_data = GeneratedEncryptedData(network_info, nodes);
    std::memcpy(buffer.data() + sizeof(tag), encrypted_data.data(), payload_size);

    return buffer;
}

/**
 * Generates a buffer with the Network Info Nintendo tag.
 * This tag contains the second portion of the encrypted payload in the 802.11 beacon frame.
 * The encrypted payload contains information about the nodes currently connected to the network.
 * This tag is only present if the payload size is greater than EncryptedDataSizeCutoff (0xFA)
 * bytes.
 * @returns A buffer with the second Nintendo encrypted data parameters of the beacon frame.
 */
std::vector<u8> GenerateNintendoSecondEncryptedDataTag(const NetworkInfo& network_info,
                                                       const NodeList& nodes) {
    // This tag is only present if the payload is larger than EncryptedDataSizeCutoff (0xFA).
    if (nodes.size() * sizeof(NodeInfo) <= EncryptedDataSizeCutoff)
        return {};

    const size_t payload_size = nodes.size() * sizeof(NodeInfo) - EncryptedDataSizeCutoff;

    const size_t tag_length = sizeof(EncryptedDataTag) - sizeof(TagHeader) + payload_size;

    // TODO(Subv): What does the 3DS do when a game has too much data to fit into the tag?
    ASSERT_MSG(tag_length <= 255, "Data is too big.");

    EncryptedDataTag tag{};
    tag.header.tag_id = static_cast<u8>(TagId::VendorSpecific);
    tag.header.length = static_cast<u8>(tag_length);
    tag.oui_type = static_cast<u8>(NintendoTagId::EncryptedData1);
    tag.oui = NintendoOUI;

    std::vector<u8> buffer(sizeof(tag) + payload_size);
    std::memcpy(buffer.data(), &tag, sizeof(tag));

    std::vector<u8> encrypted_data = GeneratedEncryptedData(network_info, nodes);
    std::memcpy(buffer.data() + sizeof(tag), encrypted_data.data() + EncryptedDataSizeCutoff,
                payload_size);

    return buffer;
}

/**
 * Generates a buffer with the Nintendo tagged parameters of an 802.11 Beacon frame
 * for UDS communication.
 * @returns A buffer with the Nintendo tagged parameters of the beacon frame.
 */
std::vector<u8> GenerateNintendoTaggedParameters(const NetworkInfo& network_info,
                                                 const NodeList& nodes) {
    ASSERT_MSG(network_info.max_nodes == nodes.size(), "Inconsistent network state.");

    std::vector<u8> buffer = GenerateNintendoDummyTag();
    std::vector<u8> network_info_tag = GenerateNintendoNetworkInfoTag(network_info);
    std::vector<u8> first_data_tag = GenerateNintendoFirstEncryptedDataTag(network_info, nodes);
    std::vector<u8> second_data_tag = GenerateNintendoSecondEncryptedDataTag(network_info, nodes);

    buffer.insert(buffer.end(), network_info_tag.begin(), network_info_tag.end());
    buffer.insert(buffer.end(), first_data_tag.begin(), first_data_tag.end());
    buffer.insert(buffer.end(), second_data_tag.begin(), second_data_tag.end());

    return buffer;
}

std::vector<u8> GenerateBeaconFrame(const NetworkInfo& network_info, const NodeList& nodes) {
    std::vector<u8> buffer = GenerateFixedParameters();
    std::vector<u8> basic_tags = GenerateBasicTaggedParameters();
    std::vector<u8> nintendo_tags = GenerateNintendoTaggedParameters(network_info, nodes);

    buffer.insert(buffer.end(), basic_tags.begin(), basic_tags.end());
    buffer.insert(buffer.end(), nintendo_tags.begin(), nintendo_tags.end());

    return buffer;
}

} // namespace NWM
Example #2
1
LRESULT COption::ExtractProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
	static CFolderDialog FolderDlg;
	static SOption* pOption = &m_option_tmp;

	// Extraction Settings

	static constexpr std::array<LPCTSTR, 3> ExtractCheckText{{
		_T("Extract each folder"),
		_T("Fix the CRC of OGG files upon extraction"),
		_T("Enable simple decoding")
	}};

	static const std::array<BOOL*, 4> ExtractCheckFlag{{
		&pOption->bCreateFolder, &pOption->bFixOgg, &pOption->bEasyDecrypt, &pOption->bRenameScriptExt
	}};

	static std::array<CCheckBox, ExtractCheckText.size()> ExtractCheck;
	static CCheckBox ExtractCheckAlpha;
	static CLabel ExtractLabelPng, ExtractLabelAlpha, ExtractLabelBuf, ExtractLabelTmp;
	static CRadioBtn ExtractRadioImage, ExtractRadioSave;
	static CUpDown ExtractUpDownPng;
	static CEditBox ExtractEditPng, ExtractEditAlpha, ExtractEditSave, ExtractEditBuf, ExtractEditTmp;
	static CButton ExtractBtnSave, ExtractBtnTmp;
	static CGroupBox ExtractGroupImage, ExtractGroupSave;

	switch (msg)
	{
		case WM_INITDIALOG:
		{
			UINT ID = 10000;
			const int x = 10;
			const int xx = 15;
			int y = 0;

			// Extraction Settings

			for (size_t i = 0; i < ExtractCheckText.size(); i++)
			{
				ExtractCheck[i].Create(hWnd, ExtractCheckText[i], ID++, x, y += 20, 230, 20);
				ExtractCheck[i].SetCheck(*ExtractCheckFlag[i]);
			}

			//

			int y_image = y;
			ExtractGroupImage.Create(hWnd, _T("Output image format"), ID++, x, y_image += 34, 240, 110);
			ExtractRadioImage.Close();
			ExtractRadioImage.Create(hWnd, _T("BMP"), ID++, x + xx, y_image += 18, 50, 20);
			ExtractRadioImage.Create(hWnd, _T("PNG"), ID++, x + xx, y_image += 20, 50, 20);
			ExtractRadioImage.SetCheck(0, pOption->bDstBMP);
			ExtractRadioImage.SetCheck(1, pOption->bDstPNG);
			ExtractLabelPng.Create(hWnd, _T("Compression Level"), ID++, x + xx + 50, y_image + 3, 100, 20);
			ExtractEditPng.Create(hWnd, _T(""), ID++, x + xx + 150, y_image, 40, 22);
			ExtractEditPng.SetLimit(1);
			ExtractUpDownPng.Create(hWnd, ExtractEditPng.GetCtrlHandle(), pOption->CmplvPng, ID++, 9, 0);

			//

			ExtractCheckAlpha.Create(hWnd, _T("Enable alpha blending"), ID++, x + xx, y_image += 22, 140, 20);
			ExtractCheckAlpha.SetCheck(pOption->bAlphaBlend);
			ExtractLabelAlpha.Create(hWnd, _T("Background color"), ID++, x + xx * 2 + 4, y_image += 24, 100, 20);
			ExtractEditAlpha.Create(hWnd, pOption->szBgRGB, ID++, x + xx * 2 + 100, y_image - 4, 100, 22);
			ExtractEditAlpha.SetLimit(6);
			ExtractEditAlpha.Enable(pOption->bAlphaBlend);

			//

			const int x_save = x + 200;
			int y_save = y;

			ExtractGroupSave.Create(hWnd, _T("Destination"), ID++, x_save + 50, y_save += 34, 290, 110);
			ExtractRadioSave.Close();
			ExtractRadioSave.Create(hWnd, _T("Specify each time"), ID++, x_save + xx + 50, y_save += 18, 220, 20);
			ExtractRadioSave.Create(hWnd, _T("Same folder as input source"), ID++, x_save + xx + 50, y_save += 20, 200, 20);
			ExtractRadioSave.Create(hWnd, _T("The following folder"), ID++, x_save + xx + 50, y_save += 20, 200, 20);
			ExtractRadioSave.SetCheck(0, pOption->bSaveSel);
			ExtractRadioSave.SetCheck(1, pOption->bSaveSrc);
			ExtractRadioSave.SetCheck(2, pOption->bSaveDir);
			ExtractEditSave.Create(hWnd, pOption->SaveDir, ID++, x_save + xx * 2 + 40, y_save += 20, 200, 22);
			ExtractEditSave.Enable(pOption->bSaveDir);
			ExtractBtnSave.Create(hWnd, _T("Browse"), ID++, x_save + xx * 2 + 250, y_save + 1, 50, 20);
			ExtractBtnSave.Enable(pOption->bSaveDir);

			//

			y = (y_image > y_save) ? y_image : y_save;
			ExtractLabelBuf.Create(hWnd, _T("Buffer Size(KB)"), ID++, x, y += 44, 100, 20);
			ExtractEditBuf.Create(hWnd, pOption->BufSize, ID++, x + 100, y - 4, 110, 22);

			//

			ExtractLabelTmp.Create(hWnd, _T("Temporary Folder"), ID++, x, y += 24, 100, 20);
			ExtractEditTmp.Create(hWnd, pOption->TmpDir, ID++, x + 100, y - 4, 200, 22);
			ExtractBtnTmp.Create(hWnd, _T("Browse"), ID++, x + 310, y - 3, 50, 20);

			break;
		}

		case WM_COMMAND:
			// Checkbox
			if (LOWORD(wp) >= ExtractCheck.front().GetID() && LOWORD(wp) <= ExtractCheck.back().GetID())
			{
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}

			// Alpha blend check box
			if (LOWORD(wp) == ExtractCheckAlpha.GetID())
			{
				ExtractEditAlpha.Enable(ExtractCheckAlpha.GetCheck());
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}

			//Output image format radio button
			if (LOWORD(wp) >= ExtractRadioImage.GetID(0) && LOWORD(wp) <= ExtractRadioImage.GetID(1))
			{
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}

			// Destination radio button
			if (LOWORD(wp) >= ExtractRadioSave.GetID(0) && LOWORD(wp) <= ExtractRadioSave.GetID(2))
			{
				ExtractEditSave.Enable(ExtractRadioSave.GetCheck(2));
				ExtractBtnSave.Enable(ExtractRadioSave.GetCheck(2));
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}

			// Output folder browse
			if (LOWORD(wp) == ExtractBtnSave.GetID())
			{
				TCHAR szSaveDir[_MAX_DIR];
				ExtractEditSave.GetText(szSaveDir, sizeof(szSaveDir));
				if (FolderDlg.DoModal(hWnd, _T("Select the output folder"), szSaveDir))
					ExtractEditSave.SetText(szSaveDir);
				break;
			}

			// Temporary folder browse
			if (LOWORD(wp) == ExtractBtnTmp.GetID())
			{
				TCHAR szTmpDir[_MAX_DIR];
				ExtractEditTmp.GetText(szTmpDir, sizeof(szTmpDir));
				if (FolderDlg.DoModal(hWnd, _T("Select a temporary folder"), szTmpDir))
					ExtractEditTmp.SetText(szTmpDir);
				break;
			}

			// Contents of the edit box have been changed
			if (HIWORD(wp) == EN_CHANGE)
			{
				PropSheet_Changed(::GetParent(hWnd), hWnd);
				break;
			}
			break;

		case WM_NOTIFY:
		{
			const auto* const hdr = reinterpret_cast<LPNMHDR>(lp);
			switch (hdr->code)
			{
				// OK/Apply, Tabbing
				case PSN_APPLY:
				case PSN_KILLACTIVE:
					// Extraction Settings
					for (size_t i = 0; i < ExtractCheck.size(); i++)
						*ExtractCheckFlag[i] = ExtractCheck[i].GetCheck();
					//
					pOption->bDstBMP = ExtractRadioImage.GetCheck(0);
					pOption->bDstPNG = ExtractRadioImage.GetCheck(1);
					ExtractEditPng.GetText(&pOption->CmplvPng, FALSE);
					//
					pOption->bAlphaBlend = ExtractCheckAlpha.GetCheck();
					ExtractEditAlpha.GetText(&pOption->BgRGB, TRUE);
					_stprintf(pOption->szBgRGB, _T("%06x"), pOption->BgRGB);
					//
					pOption->bSaveSel = ExtractRadioSave.GetCheck(0);
					pOption->bSaveSrc = ExtractRadioSave.GetCheck(1);
					pOption->bSaveDir = ExtractRadioSave.GetCheck(2);
					ExtractEditSave.GetText(pOption->SaveDir);
					//
					ExtractEditBuf.GetText(&pOption->BufSize, FALSE);
					//
					ExtractEditTmp.GetText(pOption->TmpDir);
					// OK/Apply
					if (hdr->code == PSN_APPLY)
						Apply();
					return TRUE;
			}
			break;
		}
	}

	return FALSE;
}
Example #3
0
			[[nodiscard]] std::array<char16, 2>::const_iterator begin() const noexcept
			{
				return m_buffer.begin();
			}
Example #4
0
int nbDims(std::array<T, N> const& p)
{
	return p.size();
}
Example #5
0
namespace coreinit
{

be_wfunc_ptr<void*, uint32_t>*
pMEMAllocFromDefaultHeap;

be_wfunc_ptr<void*, uint32_t, int>*
pMEMAllocFromDefaultHeapEx;

be_wfunc_ptr<void, void*>*
pMEMFreeToDefaultHeap;

static std::array<CommonHeap *, MEMBaseHeapType::Max>
sMemArenas;

static ExpandedHeap *
sSystemHeap = nullptr;

static MemoryList *
sForegroundMemlist = nullptr;

static MemoryList *
sMEM1Memlist = nullptr;

static MemoryList *
sMEM2Memlist = nullptr;

static MemoryList *
findListContainingHeap(CommonHeap *heap)
{
   be_val<uint32_t> start, size, end;
   OSGetForegroundBucket(&start, &size);
   end = start + size;

   if (heap->dataStart >= start && heap->dataEnd <= end) {
      return sForegroundMemlist;
   } else {
      OSGetMemBound(OSMemoryType::MEM1, &start, &size);
      end = start + size;

      if (heap->dataStart >= start && heap->dataEnd <= end) {
         return sMEM1Memlist;
      } else {
         return sMEM2Memlist;
      }
   }
}

static MemoryList *
findListContainingBlock(void *block)
{
   be_val<uint32_t> start, size, end;
   uint32_t addr = memory_untranslate(block);
   OSGetForegroundBucket(&start, &size);
   end = start + size;

   if (addr >= start && addr <= end) {
      return sForegroundMemlist;
   } else {
      OSGetMemBound(OSMemoryType::MEM1, &start, &size);
      end = start + size;

      if (addr >= start && addr <= end) {
         return sMEM1Memlist;
      } else {
         return sMEM2Memlist;
      }
   }
}

static CommonHeap *
findHeapContainingBlock(MemoryList *list, void *block)
{
   CommonHeap *heap = nullptr;
   uint32_t addr = memory_untranslate(block);

   while ((heap = reinterpret_cast<CommonHeap*>(MEMGetNextListObject(list, heap)))) {
      if (addr >= heap->dataStart && addr < heap->dataEnd) {
         auto child = findHeapContainingBlock(&heap->list, block);
         return child ? child : heap;
      }
   }

   return nullptr;
}

void
MEMiInitHeapHead(CommonHeap *heap, MEMiHeapTag tag, uint32_t dataStart, uint32_t dataEnd)
{
   heap->tag = tag;
   MEMInitList(&heap->list, offsetof(CommonHeap, link));
   heap->dataStart = dataStart;
   heap->dataEnd = dataEnd;
   OSInitSpinLock(&heap->lock);
   heap->flags = 0;

   if (auto list = findListContainingHeap(heap)) {
      MEMAppendListObject(list, heap);
   }
}

void
MEMiFinaliseHeap(CommonHeap *heap)
{
   if (auto list = findListContainingHeap(heap)) {
      MEMRemoveListObject(list, heap);
   }
}

void
MEMDumpHeap(CommonHeap *heap)
{
   switch (heap->tag) {
   case MEMiHeapTag::ExpandedHeap:
      MEMiDumpExpHeap(reinterpret_cast<ExpandedHeap*>(heap));
      break;
   case MEMiHeapTag::UnitHeap:
      MEMiDumpUnitHeap(reinterpret_cast<UnitHeap*>(heap));
      break;
   case MEMiHeapTag::FrameHeap:
   case MEMiHeapTag::UserHeap:
   case MEMiHeapTag::BlockHeap:
      gLog->info("Unimplemented MEMDumpHeap type");
   }
}

CommonHeap *
MEMFindContainHeap(void *block)
{
   if (auto list = findListContainingBlock(block)) {
      return findHeapContainingBlock(list, block);
   }

   return nullptr;
}

MEMBaseHeapType
MEMGetArena(CommonHeap *heap)
{
   for (auto i = 0u; i < sMemArenas.size(); ++i) {
      if (sMemArenas[i] == heap) {
         return static_cast<MEMBaseHeapType>(i);
      }
   }

   return MEMBaseHeapType::Invalid;
}

CommonHeap *
MEMGetBaseHeapHandle(MEMBaseHeapType type)
{
   if (type < sMemArenas.size()) {
      return sMemArenas[type];
   } else {
      return nullptr;
   }
}

CommonHeap *
MEMSetBaseHeapHandle(MEMBaseHeapType type, CommonHeap *heap)
{
   if (type < sMemArenas.size()) {
      auto previous = sMemArenas[type];
      sMemArenas[type] = heap;
      return previous;
   } else {
      return nullptr;
   }
}

// TODO: Move to coreinit::internal
void
CoreInitDefaultHeap()
{
   be_val<uint32_t> addr, size;

   // Create expanding heap for MEM2
   OSGetMemBound(OSMemoryType::MEM2, &addr, &size);
   auto mem2 = MEMCreateExpHeap(make_virtual_ptr<ExpandedHeap>(addr), size);
   MEMSetBaseHeapHandle(MEMBaseHeapType::MEM2, reinterpret_cast<CommonHeap*>(mem2));

   // Create frame heap for MEM1
   OSGetMemBound(OSMemoryType::MEM1, &addr, &size);
   auto mem1 = MEMCreateFrmHeap(make_virtual_ptr<FrameHeap>(addr), size);
   MEMSetBaseHeapHandle(MEMBaseHeapType::MEM1, reinterpret_cast<CommonHeap*>(mem1));

   // Create frame heap for Foreground
   OSGetForegroundBucketFreeArea(&addr, &size);
   auto fg = MEMCreateFrmHeap(make_virtual_ptr<FrameHeap>(addr), size);
   MEMSetBaseHeapHandle(MEMBaseHeapType::FG, reinterpret_cast<CommonHeap*>(fg));
}

// TODO: Move to coreinit::internal
void
CoreFreeDefaultHeap()
{
   // Delete all base heaps
   for (auto i = 0u; i < MEMBaseHeapType::Max; ++i) {
      if (sMemArenas[i]) {
         auto heap = reinterpret_cast<CommonHeap*>(sMemArenas[i]);

         switch (heap->tag) {
         case MEMiHeapTag::ExpandedHeap:
            MEMDestroyExpHeap(reinterpret_cast<ExpandedHeap*>(heap));
            break;
         case MEMiHeapTag::FrameHeap:
            MEMDestroyFrmHeap(reinterpret_cast<FrameHeap*>(heap));
            break;
         case MEMiHeapTag::UnitHeap:
         case MEMiHeapTag::UserHeap:
         case MEMiHeapTag::BlockHeap:
         default:
            assert(false);
         }

         sMemArenas[i] = nullptr;
      }
   }

   // Delete system heap
   MEMDestroyExpHeap(sSystemHeap);
   sSystemHeap = nullptr;

   // Free function pointers
   if (pMEMAllocFromDefaultHeap) {
      coreinit::internal::sysFree(pMEMAllocFromDefaultHeap);
      pMEMAllocFromDefaultHeap = nullptr;
   }

   if (pMEMAllocFromDefaultHeapEx) {
      coreinit::internal::sysFree(pMEMAllocFromDefaultHeap);
      pMEMAllocFromDefaultHeap = nullptr;
   }

   if (pMEMFreeToDefaultHeap) {
      coreinit::internal::sysFree(pMEMAllocFromDefaultHeap);
      pMEMAllocFromDefaultHeap = nullptr;
   }
}

void
Module::registerMembaseFunctions()
{
   sMemArenas.fill(nullptr);

   RegisterKernelFunction(MEMGetBaseHeapHandle);
   RegisterKernelFunction(MEMSetBaseHeapHandle);
   RegisterKernelFunction(MEMGetArena);
   RegisterKernelDataName("MEMAllocFromDefaultHeap", pMEMAllocFromDefaultHeap);
   RegisterKernelDataName("MEMAllocFromDefaultHeapEx", pMEMAllocFromDefaultHeapEx);
   RegisterKernelDataName("MEMFreeToDefaultHeap", pMEMFreeToDefaultHeap);
   RegisterKernelFunction(MEMiInitHeapHead);
   RegisterKernelFunction(MEMiFinaliseHeap);
   RegisterKernelFunction(MEMFindContainHeap);
   RegisterKernelFunction(MEMDumpHeap);

   // These are default implementations for function pointers, register as exports
   // so we will have function thunks generated
   RegisterKernelFunctionName("internal_defaultAlloc", coreinit::internal::defaultAllocFromDefaultHeap);
   RegisterKernelFunctionName("internal_defaultAllocEx", coreinit::internal::defaultAllocFromDefaultHeapEx);
   RegisterKernelFunctionName("internal_defaultFree", coreinit::internal::defaultFreeToDefaultHeap);
}

void
Module::initialiseMembase()
{
   sSystemHeap = nullptr;
   sMemArenas.fill(nullptr);

   sForegroundMemlist = coreinit::internal::sysAlloc<MemoryList>();
   MEMInitList(sForegroundMemlist, offsetof(CommonHeap, link));

   sMEM1Memlist = coreinit::internal::sysAlloc<MemoryList>();
   MEMInitList(sMEM1Memlist, offsetof(CommonHeap, link));

   sMEM2Memlist = coreinit::internal::sysAlloc<MemoryList>();
   MEMInitList(sMEM2Memlist, offsetof(CommonHeap, link));

   CoreInitDefaultHeap();

   *pMEMAllocFromDefaultHeap = findExportAddress("internal_defaultAlloc");
   *pMEMAllocFromDefaultHeapEx = findExportAddress("internal_defaultAllocEx");
   *pMEMFreeToDefaultHeap = findExportAddress("internal_defaultFree");
}

namespace internal
{

void *
sysAlloc(size_t size, int alignment)
{
   auto systemHeap = gSystem.getSystemHeap();
   return systemHeap->alloc(size, alignment);
}

void
sysFree(void *addr)
{
   auto systemHeap = gSystem.getSystemHeap();
   return systemHeap->free(addr);
}

char *
sysStrDup(const std::string &src)
{
   auto buffer = reinterpret_cast<char *>(coreinit::internal::sysAlloc(src.size() + 1, 4));
   std::memcpy(buffer, src.data(), src.size());
   buffer[src.size()] = 0;
   return buffer;
}

void *
defaultAllocFromDefaultHeap(uint32_t size)
{
   auto heap = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2);
   return MEMAllocFromExpHeap(reinterpret_cast<ExpandedHeap*>(heap), size);
}

void *
defaultAllocFromDefaultHeapEx(uint32_t size, int alignment)
{
   auto heap = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2);
   return MEMAllocFromExpHeapEx(reinterpret_cast<ExpandedHeap*>(heap), size, alignment);
}

void
defaultFreeToDefaultHeap(void *block)
{
   auto heap = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2);
   return MEMFreeToExpHeap(reinterpret_cast<ExpandedHeap*>(heap), reinterpret_cast<uint8_t *>(block));
}

} // namespace internal

} // namespace coreinit
Example #6
0
const char* PatchTypeAsString(PatchType type)
{
  return s_patch_type_strings.at(static_cast<int>(type));
}
Example #7
0
 static void Serialize(const std::array<T, N>& x, Archive& ar) {
     for (typename std::array<T, N>::const_iterator it = x.begin();
          it != x.end(); ++it)
         Serialization<Archive, T>::Serialize(*it, ar);
 }
static inline bool IsNo31Month(const int Month) {
	static const std::array<int, 5> No31Month = { 2, 4, 6, 9, 11 };
	return std::any_of(No31Month.begin(), No31Month.end(), [Month](const int i) { return Month == i; });
}
Example #9
0
bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z)
{
	int BlockX = m_CenterX + static_cast<int>((a_X - m_Width  / 2) * GetPixelWidth());
	int BlockZ = m_CenterZ + static_cast<int>((a_Z - m_Height / 2) * GetPixelWidth());

	int ChunkX, ChunkZ;
	cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ);

	int RelX = BlockX - (ChunkX * cChunkDef::Width);
	int RelZ = BlockZ - (ChunkZ * cChunkDef::Width);

	ASSERT(m_World != nullptr);

	ColorID PixelData;
	m_World->DoWithChunk(ChunkX, ChunkZ, [&](cChunk & a_Chunk)
		{
			if (!a_Chunk.IsValid())
			{
				return false;
			}

			if (GetDimension() == dimNether)
			{
				// TODO 2014-02-22 xdot: Nether maps

				return false;
			}

			static const std::array<unsigned char, 4> BrightnessID = { { 3, 0, 1, 2 } };  // Darkest to lightest
			BLOCKTYPE TargetBlock;
			NIBBLETYPE TargetMeta;

			auto Height = a_Chunk.GetHeight(RelX, RelZ);
			auto ChunkHeight = cChunkDef::Height;
			a_Chunk.GetBlockTypeMeta(RelX, Height, RelZ, TargetBlock, TargetMeta);
			auto ColourID = BlockHandler(TargetBlock)->GetMapBaseColourID(TargetMeta);

			if (IsBlockWater(TargetBlock))
			{
				ChunkHeight /= 4;
				while (((--Height) != -1) && IsBlockWater(a_Chunk.GetBlock(RelX, Height, RelZ)))
				{
					continue;
				}
			}
			else if (ColourID == 0)
			{
				while (((--Height) != -1) && ((ColourID = BlockHandler(a_Chunk.GetBlock(RelX, Height, RelZ))->GetMapBaseColourID(a_Chunk.GetMeta(RelX, Height, RelZ))) == 0))
				{
					continue;
				}
			}

			// Multiply base color ID by 4 and add brightness ID
			const int BrightnessIDSize = static_cast<int>(BrightnessID.size());
			PixelData = ColourID * 4 + BrightnessID[static_cast<size_t>(Clamp<int>((BrightnessIDSize * Height) / ChunkHeight, 0, BrightnessIDSize - 1))];
			return false;
		}
	);

	SetPixel(a_X, a_Z, PixelData);

	return true;
}
Example #10
0
	std::shared_ptr<AVStream> open_encoder(
		const AVCodec& codec, 
		std::map<std::string, 
		std::string>& options)
	{			
		auto st = 
			avformat_new_stream(
				oc_.get(), 
				&codec);

		if (!st) 		
			BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Could not allocate video-stream.") << boost::errinfo_api_function("av_new_stream"));	

		auto enc = st->codec;
				
		CASPAR_VERIFY(enc);
						
		switch(enc->codec_type)
		{
			case AVMEDIA_TYPE_VIDEO:
			{				
				enc->time_base			  = video_graph_out_->inputs[0]->time_base;
				enc->pix_fmt			  = static_cast<AVPixelFormat>(video_graph_out_->inputs[0]->format);
				enc->sample_aspect_ratio  = st->sample_aspect_ratio = video_graph_out_->inputs[0]->sample_aspect_ratio;
				enc->width				  = video_graph_out_->inputs[0]->w;
				enc->height				  = video_graph_out_->inputs[0]->h;
			
				break;
			}
			case AVMEDIA_TYPE_AUDIO:
			{
				enc->time_base			  = audio_graph_out_->inputs[0]->time_base;
				enc->sample_fmt			  = static_cast<AVSampleFormat>(audio_graph_out_->inputs[0]->format);
				enc->sample_rate		  = audio_graph_out_->inputs[0]->sample_rate;
				enc->channel_layout		  = audio_graph_out_->inputs[0]->channel_layout;
				enc->channels			  = audio_graph_out_->inputs[0]->channels;
			
				break;
			}
		}
										
		if(oc_->oformat->flags & AVFMT_GLOBALHEADER)
			enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
		
		static const std::array<std::string, 4> char_id_map = {{"v", "a", "d", "s"}};

		const auto char_id = char_id_map.at(enc->codec_type);
								
		const auto codec_opts = 
			remove_options(
				options, 
				boost::regex("^(" + char_id + "?[^:]+):" + char_id + "$"));
		
		AVDictionary* av_codec_opts = nullptr;

		to_dict(
			&av_codec_opts, 
			options);

		to_dict(
			&av_codec_opts,
			codec_opts);

		options.clear();
		
		FF(avcodec_open2(
			enc,		
			&codec, 
			av_codec_opts ? &av_codec_opts : nullptr));		

		if(av_codec_opts)
		{
			auto t = 
				av_dict_get(
					av_codec_opts, 
					"", 
					 nullptr, 
					AV_DICT_IGNORE_SUFFIX);

			while(t)
			{
				options[t->key + (codec_opts.find(t->key) != codec_opts.end() ? ":" + char_id : "")] = t->value;

				t = av_dict_get(
						av_codec_opts, 
						"", 
						t, 
						AV_DICT_IGNORE_SUFFIX);
			}

			av_dict_free(&av_codec_opts);
		}
				
		if(enc->codec_type == AVMEDIA_TYPE_AUDIO && !(codec.capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
		{
			CASPAR_ASSERT(enc->frame_size > 0);
			av_buffersink_set_frame_size(audio_graph_out_, 
										 enc->frame_size);
		}
		
		return std::shared_ptr<AVStream>(st, [this](AVStream* st)
		{
			avcodec_close(st->codec);
		});
	}
Example #11
0
#include <Nazara/Core/Serialization.hpp>

#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/MemoryView.hpp>
#include <Nazara/Math/BoundingVolume.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Ray.hpp>
#include <array>

#include <Catch/catch.hpp>

SCENARIO("Serialization", "[CORE][SERIALIZATION]")
{
	GIVEN("A context of serialization")
	{
		std::array<char, 256> datas; // The array must be bigger than any of the serializable classes
		Nz::MemoryView stream(datas.data(), datas.size());

		Nz::SerializationContext context;
		context.stream = &stream;

		WHEN("We serialize basic types")
		{
			THEN("Arithmetical types")
			{
				context.stream->SetCursorPos(0);
				REQUIRE(Serialize(context, 3));
				int value = 0;
				context.stream->SetCursorPos(0);
				REQUIRE(Unserialize(context, &value));
				REQUIRE(value == 3);
Example #12
0
#include <kernel/session/win32_session.h>
#include <thread>
#include <future>
#pragma warning(disable:4996)
namespace kernel {

::std::shared_ptr<win32_session> win32_session::handshake(life_stream raw_stream, session_id_t sid) throw(...)
{
    ::std::array<unsigned char, 512> pipe_name;
    pipe_name.fill(0);
    sprintf((char*)(pipe_name.data()), "opennui_pipe_%d", sid);
    
    auto stream_pair = _message_stream_connection(raw_stream, (char*)pipe_name.data());
    win32_message_stream& cts_stream = stream_pair.first;
    win32_message_stream& stc_stream = stream_pair.second;
    
    ::std::shared_ptr<win32_session> session = ::std::make_shared<win32_session>();
    session->_life_stream = std::move(raw_stream);
    session->_cts_stream  = std::move(cts_stream);
    session->_stc_stream  = std::move(stc_stream);
    session->_session_id  = sid;
    return session;
}

win32_session::session_id_t win32_session::get_id() const
{
    return _session_id;
}

win32_session::life_stream win32_session::get_life_stream()
{
 TrieNode() : nearest_leaf{nullptr}, nearest_leaf_distance{INFu}, ids{nullptr} {
   children.fill(nullptr);
 }
Example #14
0
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int argc = __argc;
    char **argv = __argv;
#else
int main(int argc, char *argv[])
{
#endif
    int seed = time(NULL);
    bool verifyexit = false;
    bool check_mods = false;
    std::string dump;
    dump_mode dmode = dump_mode::TSV;
    std::vector<std::string> opts;
    std::string world; /** if set try to load first save in this world on startup */

    // Set default file paths
#ifdef PREFIX
#define Q(STR) #STR
#define QUOTE(STR) Q(STR)
    PATH_INFO::init_base_path(std::string(QUOTE(PREFIX)));
#else
    PATH_INFO::init_base_path("");
#endif

#if (defined USE_HOME_DIR || defined USE_XDG_DIR)
    PATH_INFO::init_user_dir();
#else
    PATH_INFO::init_user_dir("./");
#endif
    PATH_INFO::set_standard_filenames();

    MAP_SHARING::setDefaults();
    {
        const char *section_default = nullptr;
        const char *section_map_sharing = "Map sharing";
        const char *section_user_directory = "User directories";
        const std::array<arg_handler, 12> first_pass_arguments = {{
            {
                "--seed", "<string of letters and or numbers>",
                "Sets the random number generator's seed value",
                section_default,
                [&seed](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    const unsigned char *hash_input = (const unsigned char *) params[0];
                    seed = djb2_hash(hash_input);
                    return 1;
                }
            },
            {
                "--jsonverify", nullptr,
                "Checks the cdda json files",
                section_default,
                [&verifyexit](int, const char **) -> int {
                    verifyexit = true;
                    return 0;
                }
            },
            {
                "--check-mods", "[mods...]",
                "Checks the json files belonging to cdda mods",
                section_default,
                [&check_mods,&opts]( int n, const char *params[] ) -> int {
                    check_mods = true;
                    test_mode = true;
                    for( int i = 0; i < n; ++i ) {
                        opts.emplace_back( params[ i ] );
                    }
                    return 0;
                }
            },
            {
                "--dump-stats", "<what> [mode = TSV] [opts...]",
                "Dumps item stats",
                section_default,
                [&dump,&dmode,&opts](int n, const char *params[]) -> int {
                    if( n < 1 ) {
                        return -1;
                    }
                    test_mode = true;
                    dump = params[ 0 ];
                    for( int i = 2; i < n; ++i ) {
                        opts.emplace_back( params[ i ] );
                    }
                    if( n >= 2 ) {
                        if( !strcmp( params[ 1 ], "TSV" ) ) {
                            dmode = dump_mode::TSV;
                            return 0;
                        } else if( !strcmp( params[ 1 ], "HTML" ) ) {
                            dmode = dump_mode::HTML;
                            return 0;
                        } else {
                            return -1;
                        }
                    }
                    return 0;
                }
            },
            {
                "--world", "<name>",
                "Load world",
                section_default,
                [&world](int n, const char *params[]) -> int {
                    if( n < 1 ) {
                        return -1;
                    }
                    world = params[0];
                    return 1;
                }
            },
            {
                "--basepath", "<path>",
                "Base path for all game data subdirectories",
                section_default,
                [](int num_args, const char **params) {
                    if (num_args < 1) return -1;
                    PATH_INFO::init_base_path(params[0]);
                    PATH_INFO::set_standard_filenames();
                    return 1;
                }
            },
            {
                "--shared", nullptr,
                "Activates the map-sharing mode",
                section_map_sharing,
                [](int, const char **) -> int {
                    MAP_SHARING::setSharing(true);
                    MAP_SHARING::setCompetitive(true);
                    MAP_SHARING::setWorldmenu(false);
                    return 0;
                }
            },
            {
                "--username", "<name>",
                "Instructs map-sharing code to use this name for your character.",
                section_map_sharing,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    MAP_SHARING::setUsername(params[0]);
                    return 1;
                }
            },
            {
                "--addadmin", "<username>",
                "Instructs map-sharing code to use this name for your character and give you "
                    "access to the cheat functions.",
                section_map_sharing,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    MAP_SHARING::addAdmin(params[0]);
                    return 1;
                }
            },
            {
                "--adddebugger", "<username>",
                "Informs map-sharing code that you're running inside a debugger",
                section_map_sharing,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    MAP_SHARING::addDebugger(params[0]);
                    return 1;
                }
            },
            {
                "--competitive", nullptr,
                "Instructs map-sharing code to disable access to the in-game cheat functions",
                section_map_sharing,
                [](int, const char **) -> int {
                    MAP_SHARING::setCompetitive(true);
                    return 0;
                }
            },
            {
                "--userdir", "<path>",
                "Base path for user-overrides to files from the ./data directory and named below",
                section_user_directory,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::init_user_dir(params[0]);
                    PATH_INFO::set_standard_filenames();
                    return 1;
                }
            }
        }};

        // The following arguments are dependent on one or more of the previous flags and are run
        // in a second pass.
        const std::array<arg_handler, 9> second_pass_arguments = {{
            {
                "--worldmenu", nullptr,
                "Enables the world menu in the map-sharing code",
                section_map_sharing,
                [](int, const char **) -> int {
                    MAP_SHARING::setWorldmenu(true);
                    return true;
                }
            },
            {
                "--datadir", "<directory name>",
                "Sub directory from which game data is loaded",
                nullptr,
                [](int num_args, const char **params) -> int {
                      if (num_args < 1) return -1;
                      PATH_INFO::update_pathname("datadir", params[0]);
                      PATH_INFO::update_datadir();
                      return 1;
                }
            },
            {
                "--savedir", "<directory name>",
                "Subdirectory for game saves",
                section_user_directory,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::update_pathname("savedir", params[0]);
                    return 1;
                }
            },
            {
                "--configdir", "<directory name>",
                "Subdirectory for game configuration",
                section_user_directory,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::update_pathname("config_dir", params[0]);
                    PATH_INFO::update_config_dir();
                    return 1;
                }
            },
            {
                "--memorialdir", "<directory name>",
                "Subdirectory for memorials",
                section_user_directory,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::update_pathname("memorialdir", params[0]);
                    return 1;
                }
            },
            {
                "--optionfile", "<filename>",
                "Name of the options file within the configdir",
                section_user_directory,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::update_pathname("options", params[0]);
                    return 1;
                }
            },
            {
                "--keymapfile", "<filename>",
                "Name of the keymap file within the configdir",
                section_user_directory,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::update_pathname("keymap", params[0]);
                    return 1;
                }
            },
            {
                "--autopickupfile", "<filename>",
                "Name of the autopickup options file within the configdir",
                nullptr,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::update_pathname("autopickup", params[0]);
                    return 1;
                }
            },
            {
                "--motdfile", "<filename>",
                "Name of the message of the day file within the motd directory",
                nullptr,
                [](int num_args, const char **params) -> int {
                    if (num_args < 1) return -1;
                    PATH_INFO::update_pathname("motd", params[0]);
                    return 1;
                }
            },
        }};

        // Process CLI arguments.
        const size_t num_first_pass_arguments =
            sizeof(first_pass_arguments) / sizeof(first_pass_arguments[0]);
        const size_t num_second_pass_arguments =
            sizeof(second_pass_arguments) / sizeof(second_pass_arguments[0]);
        int saved_argc = --argc; // skip program name
        const char **saved_argv = (const char **)++argv;
        while (argc) {
            if(!strcmp(argv[0], "--help")) {
                printHelpMessage(first_pass_arguments.data(), num_first_pass_arguments,
                    second_pass_arguments.data(), num_second_pass_arguments);
                return 0;
            } else {
                bool arg_handled = false;
                for (size_t i = 0; i < num_first_pass_arguments; ++i) {
                    auto &arg_handler = first_pass_arguments[i];
                    if (!strcmp(argv[0], arg_handler.flag)) {
                        argc--;
                        argv++;
                        int args_consumed = arg_handler.handler(argc, (const char **)argv);
                        if (args_consumed < 0) {
                            printf("Failed parsing parameter '%s'\n", *(argv - 1));
                            exit(1);
                        }
                        argc -= args_consumed;
                        argv += args_consumed;
                        arg_handled = true;
                        break;
                    }
                }
                // Skip other options.
                if (!arg_handled) {
                    --argc;
                    ++argv;
                }
            }
        }
        while (saved_argc) {
            bool arg_handled = false;
            for (size_t i = 0; i < num_second_pass_arguments; ++i) {
                auto &arg_handler = second_pass_arguments[i];
                if (!strcmp(saved_argv[0], arg_handler.flag)) {
                    --saved_argc;
                    ++saved_argv;
                    int args_consumed = arg_handler.handler(saved_argc, saved_argv);
                    if (args_consumed < 0) {
                        printf("Failed parsing parameter '%s'\n", *(argv - 1));
                        exit(1);
                    }
                    saved_argc -= args_consumed;
                    saved_argv += args_consumed;
                    arg_handled = true;
                    break;
                }
            }
            // Ingore unknown options.
            if (!arg_handled) {
                --saved_argc;
                ++saved_argv;
            }
        }
    }

    if (!assure_dir_exist(FILENAMES["user_dir"].c_str())) {
        printf("Can't open or create %s. Check permissions.\n",
               FILENAMES["user_dir"].c_str());
        exit(1);
    }

    setupDebug();

    if (setlocale(LC_ALL, "") == NULL) {
        DebugLog(D_WARNING, D_MAIN) << "Error while setlocale(LC_ALL, '').";
    } else {
        try {
            std::locale::global( std::locale( "" ) );
        } catch( const std::exception& ) {
            // if user default locale retrieval isn't implemented by system
            try{
                // default to basic C locale
                std::locale::global( std::locale::classic() );
            } catch( const std::exception &err ) {
                debugmsg( "%s", err.what() );
                exit_handler(-999);
            }
        }
    }

    get_options().init();
    get_options().load();
    set_language();

    // in test mode don't initialize curses to avoid escape sequences being inserted into output stream
    if( !test_mode ) {
         if( initscr() == nullptr ) { // Initialize ncurses
            DebugLog( D_ERROR, DC_ALL ) << "initscr failed!";
            return 1;
        }
        init_interface();
        noecho();  // Don't echo keypresses
        cbreak();  // C-style breaks (e.g. ^C to SIGINT)
        keypad(stdscr, true); // Numpad is numbers
    }

#if !(defined TILES || defined _WIN32 || defined WINDOWS)
    // For tiles or windows, this is handled already in initscr().
    init_colors();
#endif
    // curs_set(0); // Invisible cursor
    set_escdelay(10); // Make escape actually responsive

    srand(seed);

    g = new game;
    // First load and initialize everything that does not
    // depend on the mods.
    try {
        g->load_static_data();
        if (verifyexit) {
            exit_handler(0);
        }
        if( !dump.empty() ) {
            init_colors();
            exit( g->dump_stats( dump, dmode, opts ) ? 0 : 1 );
        }
        if( check_mods ) {
            init_colors();
            loading_ui ui( false );
            exit( g->check_mod_data( opts, ui ) && !test_dirty ? 0 : 1 );
        }
    } catch( const std::exception &err ) {
        debugmsg( "%s", err.what() );
        exit_handler(-999);
    }

    // Now we do the actual game.

    g->init_ui();

    curs_set(0); // Invisible cursor here, because MAPBUFFER.load() is crash-prone

#if (!(defined _WIN32 || defined WINDOWS))
    struct sigaction sigIntHandler;
    sigIntHandler.sa_handler = exit_handler;
    sigemptyset(&sigIntHandler.sa_mask);
    sigIntHandler.sa_flags = 0;
    sigaction(SIGINT, &sigIntHandler, NULL);
#endif

    while( true ) {
        if( !world.empty() ) {
            if( !g->load( world ) ) {
                break;
            }
            world.clear(); // ensure quit returns to opening screen

        } else {
            main_menu menu;
            if( !menu.opening_screen() ) {
                break;
            }
        }

        while( !g->do_turn() );
    };


    exit_handler(-999);
    return 0;
}
void EUTelGeometryTelescopeGeoDescription::master2LocalVec( int sensorID, std::array<double,3> const & globalVec, std::array<double,3>& localVec) {
	this->master2LocalVec(sensorID, globalVec.data(), localVec.data());
}
Example #16
0
#include <Nazara/Audio/Algorithm.hpp>
#include <Catch/catch.hpp>

#include <array>

TEST_CASE("MixToMono", "[AUDIO][ALGORITHM]")
{
	SECTION("Mix two channels together")
	{
		std::array<int, 4> input{ 1, 3, 5, 3 };
		std::array<int, 2> output{ 0, 0 };

		// Two channels and two frames !
		Nz::MixToMono(input.data(), output.data(), 2, 2);

		std::array<int, 2> theoric{ 2, 4 }; // It's the mean of the two channels
		REQUIRE(output == theoric);
	}
}
Example #17
0
namespace PatchEngine
{
constexpr std::array<const char*, 3> s_patch_type_strings{{
    "byte",
    "word",
    "dword",
}};

static std::vector<Patch> s_on_frame;
static std::map<u32, int> s_speed_hacks;

const char* PatchTypeAsString(PatchType type)
{
  return s_patch_type_strings.at(static_cast<int>(type));
}

void LoadPatchSection(const std::string& section, std::vector<Patch>& patches, IniFile& globalIni,
                      IniFile& localIni)
{
  // Load the name of all enabled patches
  std::string enabledSectionName = section + "_Enabled";
  std::vector<std::string> enabledLines;
  std::set<std::string> enabledNames;
  localIni.GetLines(enabledSectionName, &enabledLines);
  for (const std::string& line : enabledLines)
  {
    if (!line.empty() && line[0] == '$')
    {
      std::string name = line.substr(1, line.size() - 1);
      enabledNames.insert(name);
    }
  }

  const IniFile* inis[2] = {&globalIni, &localIni};

  for (const IniFile* ini : inis)
  {
    std::vector<std::string> lines;
    Patch currentPatch;
    ini->GetLines(section, &lines);

    for (std::string& line : lines)
    {
      if (line.empty())
        continue;

      if (line[0] == '$')
      {
        // Take care of the previous code
        if (!currentPatch.name.empty())
        {
          patches.push_back(currentPatch);
        }
        currentPatch.entries.clear();

        // Set active and name
        currentPatch.name = line.substr(1, line.size() - 1);
        currentPatch.active = enabledNames.find(currentPatch.name) != enabledNames.end();
        currentPatch.user_defined = (ini == &localIni);
      }
      else
      {
        std::string::size_type loc = line.find('=');

        if (loc != std::string::npos)
        {
          line[loc] = ':';
        }

        const std::vector<std::string> items = SplitString(line, ':');

        if (items.size() >= 3)
        {
          PatchEntry pE;
          bool success = true;
          success &= TryParse(items[0], &pE.address);
          success &= TryParse(items[2], &pE.value);

          const auto iter =
              std::find(s_patch_type_strings.begin(), s_patch_type_strings.end(), items[1]);
          pE.type = PatchType(std::distance(s_patch_type_strings.begin(), iter));

          success &= (pE.type != (PatchType)3);
          if (success)
          {
            currentPatch.entries.push_back(pE);
          }
        }
      }
    }

    if (!currentPatch.name.empty() && !currentPatch.entries.empty())
    {
      patches.push_back(currentPatch);
    }
  }
}

static void LoadSpeedhacks(const std::string& section, IniFile& ini)
{
  std::vector<std::string> keys;
  ini.GetKeys(section, &keys);
  for (const std::string& key : keys)
  {
    std::string value;
    ini.GetOrCreateSection(section)->Get(key, &value, "BOGUS");
    if (value != "BOGUS")
    {
      u32 address;
      u32 cycles;
      bool success = true;
      success &= TryParse(key, &address);
      success &= TryParse(value, &cycles);
      if (success)
      {
        s_speed_hacks[address] = static_cast<int>(cycles);
      }
    }
  }
}

int GetSpeedhackCycles(const u32 addr)
{
  const auto iter = s_speed_hacks.find(addr);
  if (iter == s_speed_hacks.end())
    return 0;

  return iter->second;
}

void LoadPatches()
{
  IniFile merged = SConfig::GetInstance().LoadGameIni();
  IniFile globalIni = SConfig::GetInstance().LoadDefaultGameIni();
  IniFile localIni = SConfig::GetInstance().LoadLocalGameIni();

  LoadPatchSection("OnFrame", s_on_frame, globalIni, localIni);

  // Check if I'm syncing Codes
  if (Config::Get(Config::MAIN_CODE_SYNC_OVERRIDE))
  {
    Gecko::SetSyncedCodesAsActive();
    ActionReplay::SetSyncedCodesAsActive();
  }
  else
  {
    Gecko::SetActiveCodes(Gecko::LoadCodes(globalIni, localIni));
    ActionReplay::LoadAndApplyCodes(globalIni, localIni);
  }

  LoadSpeedhacks("Speedhacks", merged);
}

static void ApplyPatches(const std::vector<Patch>& patches)
{
  for (const Patch& patch : patches)
  {
    if (patch.active)
    {
      for (const PatchEntry& entry : patch.entries)
      {
        u32 addr = entry.address;
        u32 value = entry.value;
        switch (entry.type)
        {
        case PatchType::Patch8Bit:
          PowerPC::HostWrite_U8(static_cast<u8>(value), addr);
          break;
        case PatchType::Patch16Bit:
          PowerPC::HostWrite_U16(static_cast<u16>(value), addr);
          break;
        case PatchType::Patch32Bit:
          PowerPC::HostWrite_U32(value, addr);
          break;
        default:
          // unknown patchtype
          break;
        }
      }
    }
  }
}

// Requires MSR.DR, MSR.IR
// There's no perfect way to do this, it's just a heuristic.
// We require at least 2 stack frames, if the stack is shallower than that then it won't work.
static bool IsStackSane()
{
  DEBUG_ASSERT(MSR.DR && MSR.IR);

  // Check the stack pointer
  u32 SP = GPR(1);
  if (!PowerPC::HostIsRAMAddress(SP))
    return false;

  // Read the frame pointer from the stack (find 2nd frame from top), assert that it makes sense
  u32 next_SP = PowerPC::HostRead_U32(SP);
  if (next_SP <= SP || !PowerPC::HostIsRAMAddress(next_SP) ||
      !PowerPC::HostIsRAMAddress(next_SP + 4))
    return false;

  // Check the link register makes sense (that it points to a valid IBAT address)
  const u32 address = PowerPC::HostRead_U32(next_SP + 4);
  return PowerPC::HostIsInstructionRAMAddress(address) && 0 != PowerPC::HostRead_U32(address);
}

bool ApplyFramePatches()
{
  // Because we're using the VI Interrupt to time this instead of patching the game with a
  // callback hook we can end up catching the game in an exception vector.
  // We deal with this by returning false so that SystemTimers will reschedule us in a few cycles
  // where we can try again after the CPU hopefully returns back to the normal instruction flow.
  if (!MSR.DR || !MSR.IR || !IsStackSane())
  {
    DEBUG_LOG(
        ACTIONREPLAY,
        "Need to retry later. CPU configuration is currently incorrect. PC = 0x%08X, MSR = 0x%08X",
        PC, MSR.Hex);
    return false;
  }

  ApplyPatches(s_on_frame);

  // Run the Gecko code handler
  Gecko::RunCodeHandler();
  ActionReplay::RunAllActive();

  return true;
}

void Shutdown()
{
  s_on_frame.clear();
  s_speed_hacks.clear();
  ActionReplay::ApplyCodes({});
  Gecko::Shutdown();
}

void Reload()
{
  Shutdown();
  LoadPatches();
}

}  // namespace
Example #18
0
 /*!
  * \brief By default all elements are set to zero.
  */
 Matrix(){ d.fill( T(0.0) ); }
Example #19
0
void LoadPatchSection(const std::string& section, std::vector<Patch>& patches, IniFile& globalIni,
                      IniFile& localIni)
{
  // Load the name of all enabled patches
  std::string enabledSectionName = section + "_Enabled";
  std::vector<std::string> enabledLines;
  std::set<std::string> enabledNames;
  localIni.GetLines(enabledSectionName, &enabledLines);
  for (const std::string& line : enabledLines)
  {
    if (!line.empty() && line[0] == '$')
    {
      std::string name = line.substr(1, line.size() - 1);
      enabledNames.insert(name);
    }
  }

  const IniFile* inis[2] = {&globalIni, &localIni};

  for (const IniFile* ini : inis)
  {
    std::vector<std::string> lines;
    Patch currentPatch;
    ini->GetLines(section, &lines);

    for (std::string& line : lines)
    {
      if (line.empty())
        continue;

      if (line[0] == '$')
      {
        // Take care of the previous code
        if (!currentPatch.name.empty())
        {
          patches.push_back(currentPatch);
        }
        currentPatch.entries.clear();

        // Set active and name
        currentPatch.name = line.substr(1, line.size() - 1);
        currentPatch.active = enabledNames.find(currentPatch.name) != enabledNames.end();
        currentPatch.user_defined = (ini == &localIni);
      }
      else
      {
        std::string::size_type loc = line.find('=');

        if (loc != std::string::npos)
        {
          line[loc] = ':';
        }

        const std::vector<std::string> items = SplitString(line, ':');

        if (items.size() >= 3)
        {
          PatchEntry pE;
          bool success = true;
          success &= TryParse(items[0], &pE.address);
          success &= TryParse(items[2], &pE.value);

          const auto iter =
              std::find(s_patch_type_strings.begin(), s_patch_type_strings.end(), items[1]);
          pE.type = PatchType(std::distance(s_patch_type_strings.begin(), iter));

          success &= (pE.type != (PatchType)3);
          if (success)
          {
            currentPatch.entries.push_back(pE);
          }
        }
      }
    }

    if (!currentPatch.name.empty() && !currentPatch.entries.empty())
    {
      patches.push_back(currentPatch);
    }
  }
}
Example #20
0
 /*!
  * \brief Constructor using a user defined default value to fill the container.
  * \param value default value
  */
 Matrix(const T& value){ d.fill(value); }
Example #21
0
T get(std::array<T,N> const& p, int i)
{
	return i < p.size() ? p[i] : 0;
}
Example #22
0
 /*!
  * \brief Return a pointer to the first element of the data container.
  * \return A pointer to the first element of the data container.
  */
 T* data(){ return d.data(); }
 vector<T> vec(const std::array<T, n>& arr) {
   return vector<T>(arr.begin(), arr.end());
 }
Example #24
0
 /*!
  * \brief Return a const pointer to the first element of the data container.
  * \return A const pointer to the first element of the data container.
  */
 const T* data() const { return d.data(); }
Example #25
0
void PageRecord::StartOutput() {
	assert(m_page_started);

	if(m_output_started)
		return;

	if(m_simple_synth != NULL) {
		m_simple_synth->PlaySequence(SEQUENCE_RECORD_START.data(), SEQUENCE_RECORD_START.size());
		usleep(200000);
	}

	try {

		Logger::LogInfo("[PageRecord::StartOutput] " + tr("Starting output ..."));

		if(m_output_manager == NULL) {

			// set the file name
			if(m_separate_files)
				m_output_settings.file = GetNewSegmentFile(m_file_base);

			// for OpenGL recording, detect the application size
			if(m_video_area == PageInput::VIDEO_AREA_GLINJECT && !m_video_scaling) {
				if(m_gl_inject_input == NULL) {
					Logger::LogError("[PageRecord::StartOutput] " + tr("Error: Could not get the size of the OpenGL application because the GLInject input has not been created."));
					throw GLInjectException();
				}
				m_gl_inject_input->GetCurrentSize(&m_video_in_width, &m_video_in_height);
				if(m_video_in_width == 0 && m_video_in_height == 0) {
					Logger::LogError("[PageRecord::StartOutput] " + tr("Error: Could not get the size of the OpenGL application. Either the "
									 "application wasn't started correctly, or the application hasn't created an OpenGL window yet. If "
									 "you want to start recording before starting the application, you have to enable scaling and enter "
									 "the video size manually."));
					throw GLInjectException();
				}
			}

			// calculate the output width and height
			if(m_video_scaling) {
				// Only even width and height is allowed because the final images are encoded as YUV.
				m_output_settings.video_width = m_video_scaled_width / 2 * 2;
				m_output_settings.video_height = m_video_scaled_height / 2 * 2;
			} else if(m_video_area == PageInput::VIDEO_AREA_GLINJECT) {
				// The input size is the size of the OpenGL application and can't be changed. The output size is set to the current size of the application.
				m_output_settings.video_width = m_video_in_width / 2 * 2;
				m_output_settings.video_height = m_video_in_height / 2 * 2;
			} else {
				// If the user did not explicitly select scaling, then don't force scaling just because the recording area is one pixel too large.
				// One missing row/column of pixels is probably better than a blurry video (and scaling is SLOW).
				m_video_in_width = m_video_in_width / 2 * 2;
				m_video_in_height = m_video_in_height / 2 * 2;
				m_output_settings.video_width = m_video_in_width;
				m_output_settings.video_height = m_video_in_height;
			}

			// start the output
			m_output_manager.reset(new OutputManager(m_output_settings));

		} else {

			// start a new segment
			m_output_manager->GetSynchronizer()->NewSegment();

		}

		Logger::LogInfo("[PageRecord::StartOutput] " + tr("Started output."));

		m_output_started = true;
		m_recorded_something = true;
		UpdateSysTray();
		UpdateRecordPauseButton();
		UpdateInput();

	} catch(...) {
		Logger::LogError("[PageRecord::StartOutput] " + tr("Error: Something went wrong during initialization."));
	}

}
 void operator()(msgpack::object& o, const std::array<unsigned char, N>& v) const {
     uint32_t size = checked_get_container_size(v.size());
     o.type = msgpack::type::BIN;
     o.via.bin.ptr = reinterpret_cast<char const*>(v.data());
     o.via.bin.size = size;
 }
Example #27
0
// protected
bool IPAddressV6::inBinarySubnet(const std::array<uint8_t, 2> addr,
                                 size_t numBits) const {
    const unsigned char* subbytes = mask(numBits).bytes();
    return (std::memcmp(addr.data(), subbytes, 2) == 0);
}
void EUTelGeometryTelescopeGeoDescription::local2Master( int sensorID, std::array<double,3> const & localPos, std::array<double,3>& globalPos) {
	this->local2Master(sensorID, localPos.data(), globalPos.data());
}
std::string LibusbSoundplaneDriver::getSerialNumberString() const
{
	const std::array<unsigned char, 64> serialNumber = mSerialNumber.load();
	return std::string(reinterpret_cast<const char *>(serialNumber.data()));
}
void
Module::initialiseExceptions()
{
   sExceptionCallbacks.fill(nullptr);
}