summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/file_util.cpp18
-rw-r--r--src/common/framebuffer_layout.cpp19
-rw-r--r--src/common/framebuffer_layout.h8
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/common/param_package.cpp120
-rw-r--r--src/common/param_package.h40
-rw-r--r--src/common/x64/cpu_detect.cpp12
9 files changed, 207 insertions, 14 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8a6170257..13277a5c2 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -35,6 +35,7 @@ set(SRCS
memory_util.cpp
microprofile.cpp
misc.cpp
+ param_package.cpp
scm_rev.cpp
string_util.cpp
symbols.cpp
@@ -66,6 +67,7 @@ set(HEADERS
memory_util.h
microprofile.h
microprofileui.h
+ param_package.h
platform.h
quaternion.h
scm_rev.h
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index df234c225..5ab036b34 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -118,8 +118,7 @@ bool IsDirectory(const std::string& filename) {
#endif
if (result < 0) {
- LOG_WARNING(Common_Filesystem, "stat failed on %s: %s", filename.c_str(),
- GetLastErrorMsg());
+ LOG_DEBUG(Common_Filesystem, "stat failed on %s: %s", filename.c_str(), GetLastErrorMsg());
return false;
}
@@ -129,12 +128,12 @@ bool IsDirectory(const std::string& filename) {
// Deletes a given filename, return true on success
// Doesn't supports deleting a directory
bool Delete(const std::string& filename) {
- LOG_INFO(Common_Filesystem, "file %s", filename.c_str());
+ LOG_TRACE(Common_Filesystem, "file %s", filename.c_str());
// Return true because we care about the file no
// being there, not the actual delete.
if (!Exists(filename)) {
- LOG_WARNING(Common_Filesystem, "%s does not exist", filename.c_str());
+ LOG_DEBUG(Common_Filesystem, "%s does not exist", filename.c_str());
return true;
}
@@ -169,8 +168,7 @@ bool CreateDir(const std::string& path) {
return true;
DWORD error = GetLastError();
if (error == ERROR_ALREADY_EXISTS) {
- LOG_WARNING(Common_Filesystem, "CreateDirectory failed on %s: already exists",
- path.c_str());
+ LOG_DEBUG(Common_Filesystem, "CreateDirectory failed on %s: already exists", path.c_str());
return true;
}
LOG_ERROR(Common_Filesystem, "CreateDirectory failed on %s: %i", path.c_str(), error);
@@ -182,7 +180,7 @@ bool CreateDir(const std::string& path) {
int err = errno;
if (err == EEXIST) {
- LOG_WARNING(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str());
+ LOG_DEBUG(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str());
return true;
}
@@ -197,7 +195,7 @@ bool CreateFullPath(const std::string& fullPath) {
LOG_TRACE(Common_Filesystem, "path %s", fullPath.c_str());
if (FileUtil::Exists(fullPath)) {
- LOG_WARNING(Common_Filesystem, "path exists %s", fullPath.c_str());
+ LOG_DEBUG(Common_Filesystem, "path exists %s", fullPath.c_str());
return true;
}
@@ -229,7 +227,7 @@ bool CreateFullPath(const std::string& fullPath) {
// Deletes a directory filename, returns true on success
bool DeleteDir(const std::string& filename) {
- LOG_INFO(Common_Filesystem, "directory %s", filename.c_str());
+ LOG_TRACE(Common_Filesystem, "directory %s", filename.c_str());
// check if a directory
if (!FileUtil::IsDirectory(filename)) {
@@ -693,6 +691,8 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string& new
paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
if (!FileUtil::IsDirectory(paths[D_USER_IDX])) {
paths[D_USER_IDX] = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP;
+ } else {
+ LOG_INFO(Common_Filesystem, "Using the local user directory");
}
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
diff --git a/src/common/framebuffer_layout.cpp b/src/common/framebuffer_layout.cpp
index 46c008d9c..a2a0e7dad 100644
--- a/src/common/framebuffer_layout.cpp
+++ b/src/common/framebuffer_layout.cpp
@@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/framebuffer_layout.h"
+#include "core/settings.h"
#include "video_core/video_core.h"
namespace Layout {
@@ -135,4 +136,22 @@ FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool swapped
res.bottom_screen = swapped ? large_screen : small_screen;
return res;
}
+
+FramebufferLayout CustomFrameLayout(unsigned width, unsigned height) {
+ ASSERT(width > 0);
+ ASSERT(height > 0);
+
+ FramebufferLayout res{width, height, true, true, {}, {}};
+
+ MathUtil::Rectangle<unsigned> top_screen{
+ Settings::values.custom_top_left, Settings::values.custom_top_top,
+ Settings::values.custom_top_right, Settings::values.custom_top_bottom};
+ MathUtil::Rectangle<unsigned> bot_screen{
+ Settings::values.custom_bottom_left, Settings::values.custom_bottom_top,
+ Settings::values.custom_bottom_right, Settings::values.custom_bottom_bottom};
+
+ res.top_screen = top_screen;
+ res.bottom_screen = bot_screen;
+ return res;
+}
}
diff --git a/src/common/framebuffer_layout.h b/src/common/framebuffer_layout.h
index a125646a3..f1df5c55a 100644
--- a/src/common/framebuffer_layout.h
+++ b/src/common/framebuffer_layout.h
@@ -44,4 +44,12 @@ FramebufferLayout SingleFrameLayout(unsigned width, unsigned height, bool is_swa
* @return Newly created FramebufferLayout object with default screen regions initialized
*/
FramebufferLayout LargeFrameLayout(unsigned width, unsigned height, bool is_swapped);
+
+/**
+ * Factory method for constructing a custom FramebufferLayout
+ * @param width Window framebuffer width in pixels
+ * @param height Window framebuffer height in pixels
+ * @return Newly created FramebufferLayout object with default screen regions initialized
+ */
+FramebufferLayout CustomFrameLayout(unsigned width, unsigned height);
}
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 737e1d57f..42f6a9918 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -71,6 +71,7 @@ namespace Log {
CLS(Audio) \
SUB(Audio, DSP) \
SUB(Audio, Sink) \
+ CLS(Input) \
CLS(Loader)
// GetClassName is a macro defined by Windows.h, grrr...
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 4b0f8ff03..1b905f66c 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -89,6 +89,7 @@ enum class Class : ClassType {
Audio_DSP, ///< The HLE implementation of the DSP
Audio_Sink, ///< Emulator audio output backend
Loader, ///< ROM loader
+ Input, ///< Input emulation
Count ///< Total number of logging classes
};
diff --git a/src/common/param_package.cpp b/src/common/param_package.cpp
new file mode 100644
index 000000000..3a6ef8c27
--- /dev/null
+++ b/src/common/param_package.cpp
@@ -0,0 +1,120 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <array>
+#include <vector>
+#include "common/logging/log.h"
+#include "common/param_package.h"
+#include "common/string_util.h"
+
+namespace Common {
+
+constexpr char KEY_VALUE_SEPARATOR = ':';
+constexpr char PARAM_SEPARATOR = ',';
+constexpr char ESCAPE_CHARACTER = '$';
+const std::string KEY_VALUE_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '0'};
+const std::string PARAM_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '1'};
+const std::string ESCAPE_CHARACTER_ESCAPE{ESCAPE_CHARACTER, '2'};
+
+ParamPackage::ParamPackage(const std::string& serialized) {
+ std::vector<std::string> pairs;
+ Common::SplitString(serialized, PARAM_SEPARATOR, pairs);
+
+ for (const std::string& pair : pairs) {
+ std::vector<std::string> key_value;
+ Common::SplitString(pair, KEY_VALUE_SEPARATOR, key_value);
+ if (key_value.size() != 2) {
+ LOG_ERROR(Common, "invalid key pair %s", pair.c_str());
+ continue;
+ }
+
+ for (std::string& part : key_value) {
+ part = Common::ReplaceAll(part, KEY_VALUE_SEPARATOR_ESCAPE, {KEY_VALUE_SEPARATOR});
+ part = Common::ReplaceAll(part, PARAM_SEPARATOR_ESCAPE, {PARAM_SEPARATOR});
+ part = Common::ReplaceAll(part, ESCAPE_CHARACTER_ESCAPE, {ESCAPE_CHARACTER});
+ }
+
+ Set(key_value[0], key_value[1]);
+ }
+}
+
+ParamPackage::ParamPackage(std::initializer_list<DataType::value_type> list) : data(list) {}
+
+std::string ParamPackage::Serialize() const {
+ if (data.empty())
+ return "";
+
+ std::string result;
+
+ for (const auto& pair : data) {
+ std::array<std::string, 2> key_value{{pair.first, pair.second}};
+ for (std::string& part : key_value) {
+ part = Common::ReplaceAll(part, {ESCAPE_CHARACTER}, ESCAPE_CHARACTER_ESCAPE);
+ part = Common::ReplaceAll(part, {PARAM_SEPARATOR}, PARAM_SEPARATOR_ESCAPE);
+ part = Common::ReplaceAll(part, {KEY_VALUE_SEPARATOR}, KEY_VALUE_SEPARATOR_ESCAPE);
+ }
+ result += key_value[0] + KEY_VALUE_SEPARATOR + key_value[1] + PARAM_SEPARATOR;
+ }
+
+ result.pop_back(); // discard the trailing PARAM_SEPARATOR
+ return result;
+}
+
+std::string ParamPackage::Get(const std::string& key, const std::string& default_value) const {
+ auto pair = data.find(key);
+ if (pair == data.end()) {
+ LOG_DEBUG(Common, "key %s not found", key.c_str());
+ return default_value;
+ }
+
+ return pair->second;
+}
+
+int ParamPackage::Get(const std::string& key, int default_value) const {
+ auto pair = data.find(key);
+ if (pair == data.end()) {
+ LOG_DEBUG(Common, "key %s not found", key.c_str());
+ return default_value;
+ }
+
+ try {
+ return std::stoi(pair->second);
+ } catch (const std::logic_error&) {
+ LOG_ERROR(Common, "failed to convert %s to int", pair->second.c_str());
+ return default_value;
+ }
+}
+
+float ParamPackage::Get(const std::string& key, float default_value) const {
+ auto pair = data.find(key);
+ if (pair == data.end()) {
+ LOG_DEBUG(Common, "key %s not found", key.c_str());
+ return default_value;
+ }
+
+ try {
+ return std::stof(pair->second);
+ } catch (const std::logic_error&) {
+ LOG_ERROR(Common, "failed to convert %s to float", pair->second.c_str());
+ return default_value;
+ }
+}
+
+void ParamPackage::Set(const std::string& key, const std::string& value) {
+ data[key] = value;
+}
+
+void ParamPackage::Set(const std::string& key, int value) {
+ data[key] = std::to_string(value);
+}
+
+void ParamPackage::Set(const std::string& key, float value) {
+ data[key] = std::to_string(value);
+}
+
+bool ParamPackage::Has(const std::string& key) const {
+ return data.find(key) != data.end();
+}
+
+} // namespace Common
diff --git a/src/common/param_package.h b/src/common/param_package.h
new file mode 100644
index 000000000..c4c11b221
--- /dev/null
+++ b/src/common/param_package.h
@@ -0,0 +1,40 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <initializer_list>
+#include <string>
+#include <unordered_map>
+
+namespace Common {
+
+/// A string-based key-value container supporting serializing to and deserializing from a string
+class ParamPackage {
+public:
+ using DataType = std::unordered_map<std::string, std::string>;
+
+ ParamPackage() = default;
+ explicit ParamPackage(const std::string& serialized);
+ ParamPackage(std::initializer_list<DataType::value_type> list);
+ ParamPackage(const ParamPackage& other) = default;
+ ParamPackage(ParamPackage&& other) = default;
+
+ ParamPackage& operator=(const ParamPackage& other) = default;
+ ParamPackage& operator=(ParamPackage&& other) = default;
+
+ std::string Serialize() const;
+ std::string Get(const std::string& key, const std::string& default_value) const;
+ int Get(const std::string& key, int default_value) const;
+ float Get(const std::string& key, float default_value) const;
+ void Set(const std::string& key, const std::string& value);
+ void Set(const std::string& key, int value);
+ void Set(const std::string& key, float value);
+ bool Has(const std::string& key) const;
+
+private:
+ DataType data;
+};
+
+} // namespace Common
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index 370ae2c80..2cb3ab9cc 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -8,9 +8,9 @@
#include "common/common_types.h"
#include "cpu_detect.h"
-namespace Common {
-
-#ifndef _MSC_VER
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
#if defined(__DragonFly__) || defined(__FreeBSD__)
// clang-format off
@@ -37,13 +37,15 @@ static inline void __cpuid(int info[4], int function_id) {
}
#define _XCR_XFEATURE_ENABLED_MASK 0
-static u64 _xgetbv(u32 index) {
+static inline u64 _xgetbv(u32 index) {
u32 eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((u64)edx << 32) | eax;
}
-#endif // ifndef _MSC_VER
+#endif // _MSC_VER
+
+namespace Common {
// Detects the various CPU features
static CPUCaps Detect() {