(view as text)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dade7a6..6b5d555 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -363,7 +363,7 @@ if(NOT ANDROID)
 		message("bluez NOT found, disabling bluetooth support")
 	endif(BLUEZ_FOUND)
 
-	check_lib(PULSEAUDIO libpulse-simple QUIET)
+	check_lib(PULSEAUDIO libpulse QUIET)
 	if(PULSEAUDIO_FOUND)
 		add_definitions(-DHAVE_PULSEAUDIO=1)
 		message("PulseAudio found, enabling PulseAudio sound backend")
diff --git a/Source/Core/AudioCommon/PulseAudioStream.cpp b/Source/Core/AudioCommon/PulseAudioStream.cpp
index 13307a8..fe68d0e 100644
--- a/Source/Core/AudioCommon/PulseAudioStream.cpp
+++ b/Source/Core/AudioCommon/PulseAudioStream.cpp
@@ -11,30 +11,28 @@
 
 namespace
 {
-const size_t BUFFER_SAMPLES = 512;
+const size_t BUFFER_SAMPLES = 512; // ~10 ms
 const size_t CHANNEL_COUNT = 2;
-const size_t BUFFER_SIZE = BUFFER_SAMPLES * CHANNEL_COUNT;
+const size_t BUFFER_SIZE = BUFFER_SAMPLES * CHANNEL_COUNT * sizeof(s16);
 }
 
 PulseAudio::PulseAudio(CMixer *mixer)
 	: SoundStream(mixer)
-	, mix_buffer(BUFFER_SIZE)
-	, thread()
-	, run_thread()
-	, pa()
+	, m_thread()
+	, m_run_thread()
 {}
 
 bool PulseAudio::Start()
 {
-	run_thread = true;
-	thread = std::thread(std::mem_fun(&PulseAudio::SoundLoop), this);
+	m_run_thread = true;
+	m_thread = std::thread(std::mem_fun(&PulseAudio::SoundLoop), this);
 	return true;
 }
 
 void PulseAudio::Stop()
 {
-	run_thread = false;
-	thread.join();
+	m_run_thread = false;
+	m_thread.join();
 }
 
 void PulseAudio::Update()
@@ -49,11 +47,11 @@ void PulseAudio::SoundLoop()
 
 	if (PulseInit())
 	{
-		while (run_thread)
-		{
-			m_mixer->Mix(&mix_buffer[0], mix_buffer.size() / CHANNEL_COUNT);
-			Write(&mix_buffer[0], mix_buffer.size() * sizeof(s16));
-		}
+		while (m_run_thread.load() && m_pa_connected == 1 && m_pa_error >= 0)
+			m_pa_error = pa_mainloop_iterate(m_pa_ml, 1, NULL);
+
+		if(m_pa_error < 0)
+			ERROR_LOG(AUDIO, "PulseAudio error: %s", pa_strerror(m_pa_error));
 
 		PulseShutdown();
 	}
@@ -61,39 +59,117 @@ void PulseAudio::SoundLoop()
 
 bool PulseAudio::PulseInit()
 {
-	pa_sample_spec ss = {};
+	m_pa_error = 0;
+	m_pa_connected = 0;
+
+	// create pulseaudio main loop and context
+	// also register the async state callback which is called when the connection to the pa server has changed
+	m_pa_ml = pa_mainloop_new();
+	m_pa_mlapi = pa_mainloop_get_api(m_pa_ml);
+	m_pa_ctx = pa_context_new(m_pa_mlapi, "dolphin-emu");
+	m_pa_error = pa_context_connect(m_pa_ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
+	pa_context_set_state_callback(m_pa_ctx, StateCallback, this);
+
+	// wait until we're connected to the pulseaudio server
+	while (m_pa_connected == 0 && m_pa_error >= 0)
+		m_pa_error = pa_mainloop_iterate(m_pa_ml, 1, NULL);
+
+	if (m_pa_connected == 2 || m_pa_error < 0)
+	{
+		ERROR_LOG(AUDIO, "PulseAudio failed to initialize: %s", pa_strerror(m_pa_error));
+		return false;
+	}
+
+	// create a new audio stream with our sample format
+	// also connect the callbacks for this stream
+	pa_sample_spec ss;
 	ss.format = PA_SAMPLE_S16LE;
 	ss.channels = 2;
 	ss.rate = m_mixer->GetSampleRate();
-
-	int error;
-	pa = pa_simple_new(nullptr, "dolphin-emu", PA_STREAM_PLAYBACK,
-		nullptr, "audio", &ss, nullptr, nullptr, &error);
-
-	if (!pa)
+	m_pa_s = pa_stream_new(m_pa_ctx, "Playback", &ss, NULL);
+	pa_stream_set_write_callback(m_pa_s, WriteCallback, this);
+	pa_stream_set_underflow_callback(m_pa_s, UnderflowCallback, this);
+
+	// connect this audio stream to the default audio playback
+	// limit buffersize to reduce latency
+	m_pa_ba.fragsize = -1;
+	m_pa_ba.maxlength = -1;          // max buffer, so also max latency
+	m_pa_ba.minreq = -1;             // don't read every byte, try to group them _a bit_
+	m_pa_ba.prebuf = -1;             // start as early as possible
+	m_pa_ba.tlength = BUFFER_SIZE;   // designed latency, only change this flag for low latency output
+	pa_stream_flags flags = pa_stream_flags(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE);
+	m_pa_error = pa_stream_connect_playback(m_pa_s, NULL, &m_pa_ba, flags, NULL, NULL);
+	if (m_pa_error < 0)
 	{
-		ERROR_LOG(AUDIO, "PulseAudio failed to initialize: %s",
-			pa_strerror(error));
+		ERROR_LOG(AUDIO, "PulseAudio failed to initialize: %s", pa_strerror(m_pa_error));
 		return false;
 	}
-	else
-	{
-		NOTICE_LOG(AUDIO, "Pulse successfully initialized.");
-		return true;
-	}
+
+	INFO_LOG(AUDIO, "Pulse successfully initialized");
+	return true;
 }
 
 void PulseAudio::PulseShutdown()
 {
-	pa_simple_free(pa);
+	pa_context_disconnect(m_pa_ctx);
+	pa_context_unref(m_pa_ctx);
+	pa_mainloop_free(m_pa_ml);
 }
 
-void PulseAudio::Write(const void *data, size_t length)
+void PulseAudio::StateCallback(pa_context* c)
 {
-	int error;
-	if (pa_simple_write(pa, data, length, &error) < 0)
+	pa_context_state_t state = pa_context_get_state(c);
+	switch (state)
 	{
-		ERROR_LOG(AUDIO, "PulseAudio failed to write data: %s",
-			pa_strerror(error));
+	case PA_CONTEXT_FAILED:
+	case PA_CONTEXT_TERMINATED:
+		m_pa_connected = 2;
+		break;
+	case PA_CONTEXT_READY:
+		m_pa_connected = 1;
+		break;
+	default:
+		break;
 	}
 }
+// on underflow, increase pulseaudio latency in ~10ms steps
+void PulseAudio::UnderflowCallback(pa_stream* s)
+{
+	m_pa_ba.tlength += BUFFER_SIZE;
+	pa_stream_set_buffer_attr(s, &m_pa_ba, NULL, NULL);
+
+	WARN_LOG(AUDIO, "pulseaudio underflow, new latency: %d bytes", m_pa_ba.tlength);
+}
+
+void PulseAudio::WriteCallback(pa_stream* s, size_t length)
+{
+	// fetch dst buffer directly from pulseaudio, so no memcpy is needed
+	void* buffer;
+	m_pa_error = pa_stream_begin_write(s, &buffer, &length);
+
+	if (!buffer || m_pa_error < 0)
+		return; // error will be printed from main loop
+
+	m_mixer->Mix((s16*) buffer, length / sizeof(s16) / CHANNEL_COUNT);
+	m_pa_error = pa_stream_write(s, buffer, length, NULL, 0, PA_SEEK_RELATIVE);
+}
+
+// Callbacks that forward to internal methods (required because PulseAudio is a C API).
+
+void PulseAudio::StateCallback(pa_context* c, void* userdata)
+{
+	PulseAudio* p = (PulseAudio*) userdata;
+	p->StateCallback(c);
+}
+
+void PulseAudio::UnderflowCallback(pa_stream* s, void* userdata)
+{
+	PulseAudio* p = (PulseAudio*) userdata;
+	p->UnderflowCallback(s);
+}
+
+void PulseAudio::WriteCallback(pa_stream* s, size_t length, void* userdata)
+{
+	PulseAudio* p = (PulseAudio*) userdata;
+	p->WriteCallback(s, length);
+}
diff --git a/Source/Core/AudioCommon/PulseAudioStream.h b/Source/Core/AudioCommon/PulseAudioStream.h
index 8be8eae..3164a4e 100644
--- a/Source/Core/AudioCommon/PulseAudioStream.h
+++ b/Source/Core/AudioCommon/PulseAudioStream.h
@@ -6,17 +6,16 @@
 #define _PULSE_AUDIO_STREAM_H
 
 #if defined(HAVE_PULSEAUDIO) && HAVE_PULSEAUDIO
-#include <pulse/simple.h>
-#include <pulse/error.h>
+#include <pulse/pulseaudio.h>
 #endif
 
+#include <atomic>
+
 #include "Common.h"
 #include "SoundStream.h"
 
 #include "Thread.h"
 
-#include <vector>
-
 class PulseAudio : public SoundStream
 {
 #if defined(HAVE_PULSEAUDIO) && HAVE_PULSEAUDIO
@@ -32,18 +31,31 @@ public:
 
 	virtual void Update();
 
+	void StateCallback(pa_context *c);
+	void WriteCallback(pa_stream *s, size_t length);
+	void UnderflowCallback(pa_stream *s);
+
 private:
 	virtual void SoundLoop();
 
 	bool PulseInit();
 	void PulseShutdown();
-	void Write(const void *data, size_t bytes);
 
-	std::vector<s16> mix_buffer;
-	std::thread thread;
-	volatile bool run_thread;
+	// wrapper callback functions, last parameter _must_ be PulseAudio*
+	static void StateCallback(pa_context *c, void *userdata);
+	static void WriteCallback(pa_stream *s, size_t length, void *userdata);
+	static void UnderflowCallback(pa_stream *s, void *userdata);
+
+	std::thread m_thread;
+	std::atomic<bool> m_run_thread;
 
-	pa_simple* pa;
+	int m_pa_error;
+	int m_pa_connected;
+	pa_mainloop *m_pa_ml;
+	pa_mainloop_api *m_pa_mlapi;
+	pa_context *m_pa_ctx;
+	pa_stream *m_pa_s;
+	pa_buffer_attr m_pa_ba;
 #else
 public:
 	PulseAudio(CMixer *mixer) : SoundStream(mixer) {}
diff --git a/Source/Core/Common/CDUtils.cpp b/Source/Core/Common/CDUtils.cpp
index 569ceb3..7e1ebeb 100644
--- a/Source/Core/Common/CDUtils.cpp
+++ b/Source/Core/Common/CDUtils.cpp
@@ -2,6 +2,7 @@
 
 #include "CDUtils.h"
 #include "Common.h"
+#include "StringUtil.h"
 
 #include <memory> // for std::unique_ptr
 #ifdef _WIN32
@@ -150,10 +151,10 @@ static struct
 	};
 
 // Returns true if a device is a block or char device and not a symbolic link
-bool is_device(const char *source_name)
+bool is_device(const std::string& source_name)
 {
 	struct stat buf;
-	if (0 != lstat(source_name, &buf))
+	if (0 != lstat(source_name.c_str(), &buf))
 		return false;
 
 	return ((S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode)) &&
@@ -161,17 +162,15 @@ bool is_device(const char *source_name)
 }
 
 // Check a device to see if it is a DVD/CD-ROM drive
-static bool is_cdrom(const char *drive, char *mnttype)
+static bool is_cdrom(const std::string& drive, char *mnttype)
 {
-	bool is_cd=false;
-	int cdfd;
-
 	// Check if the device exists
 	if (!is_device(drive))
 		return(false);
 
+	bool is_cd=false;
 	// If it does exist, verify that it is a cdrom/dvd drive
-	cdfd = open(drive, (O_RDONLY|O_NONBLOCK), 0);
+	int cdfd = open(drive.c_str(), (O_RDONLY|O_NONBLOCK), 0);
 	if ( cdfd >= 0 )
 	{
 #ifdef __linux__
@@ -186,21 +185,16 @@ static bool is_cdrom(const char *drive, char *mnttype)
 // Returns a pointer to an array of strings with the device names
 std::vector<std::string> cdio_get_devices ()
 {
-	unsigned int i;
-	char drive[40];
 	std::vector<std::string> drives;
-
 	// Scan the system for DVD/CD-ROM drives.
-	for ( i=0; checklist[i].format; ++i )
+	for (unsigned int i = 0; checklist[i].format; ++i)
 	{
-		unsigned int j;
-		for ( j=checklist[i].num_min; j<=checklist[i].num_max; ++j )
+		for (unsigned int j = checklist[i].num_min; j <= checklist[i].num_max; ++j)
 		{
-			sprintf(drive, checklist[i].format, j);
-			if ( (is_cdrom(drive, NULL)) > 0 )
+			std::string drive = StringFromFormat(checklist[i].format, j);
+			if ( (is_cdrom(drive.c_str(), NULL)) > 0 )
 			{
-				std::string str = drive;
-				drives.push_back(str);
+				drives.push_back(std::move(drive));
 			}
 		}
 	}
@@ -222,17 +216,5 @@ bool cdio_is_cdrom(std::string device)
 #endif
 
 	std::vector<std::string> devices = cdio_get_devices();
-	bool res = false;
-	for (auto& odevice : devices)
-	{
-		if (strncmp(odevice.c_str(), device.c_str(), MAX_PATH) == 0)
-		{
-			res = true;
-			break;
-		}
-	}
-
-	devices.clear();
-	return res;
+	return std::find(devices.begin(), devices.end(), device) != devices.end();;
 }
-
diff --git a/Source/Core/Common/IniFile.cpp b/Source/Core/Common/IniFile.cpp
index a1a10ab..b07fb09 100644
--- a/Source/Core/Common/IniFile.cpp
+++ b/Source/Core/Common/IniFile.cpp
@@ -37,7 +37,9 @@ void ParseLine(const std::string& line, std::string* keyOut, std::string* valueO
 
 }
 
-void IniFile::Section::Set(const char* key, const char* newValue)
+const std::string& IniFile::NULL_STRING = "";
+
+void IniFile::Section::Set(const std::string& key, const std::string& newValue)
 {
 	auto it = values.find(key);
 	if (it != values.end())
@@ -49,7 +51,7 @@ void IniFile::Section::Set(const char* key, const char* newValue)
 	}
 }
 
-void IniFile::Section::Set(const char* key, const std::string& newValue, const std::string& defaultValue)
+void IniFile::Section::Set(const std::string& key, const std::string& newValue, const std::string& defaultValue)
 {
 	if (newValue != defaultValue)
 		Set(key, newValue);
@@ -57,7 +59,7 @@ void IniFile::Section::Set(const char* key, const std::string& newValue, const s
 		Delete(key);
 }
 
-void IniFile::Section::Set(const char* key, const float newValue, const float defaultValue)
+void IniFile::Section::Set(const std::string& key, const float newValue, const float defaultValue)
 {
 	if (newValue != defaultValue)
 		Set(key, newValue);
@@ -65,7 +67,7 @@ void IniFile::Section::Set(const char* key, const float newValue, const float de
 		Delete(key);
 }
 
-void IniFile::Section::Set(const char* key, int newValue, int defaultValue)
+void IniFile::Section::Set(const std::string& key, int newValue, int defaultValue)
 {
 	if (newValue != defaultValue)
 		Set(key, newValue);
@@ -73,7 +75,7 @@ void IniFile::Section::Set(const char* key, int newValue, int defaultValue)
 		Delete(key);
 }
 
-void IniFile::Section::Set(const char* key, bool newValue, bool defaultValue)
+void IniFile::Section::Set(const std::string& key, bool newValue, bool defaultValue)
 {
 	if (newValue != defaultValue)
 		Set(key, newValue);
@@ -81,7 +83,7 @@ void IniFile::Section::Set(const char* key, bool newValue, bool defaultValue)
 		Delete(key);
 }
 
-void IniFile::Section::Set(const char* key, const std::vector<std::string>& newValues)
+void IniFile::Section::Set(const std::string& key, const std::vector<std::string>& newValues)
 {
 	std::string temp;
 	// Join the strings with ,
@@ -92,10 +94,10 @@ void IniFile::Section::Set(const char* key, const std::vector<std::string>& newV
 	}
 	// remove last ,
 	temp.resize(temp.length() - 1);
-	Set(key, temp.c_str());
+	Set(key, temp);
 }
 
-bool IniFile::Section::Get(const char* key, std::string* value, const char* defaultValue)
+bool IniFile::Section::Get(const std::string& key, std::string* value, const std::string& defaultValue)
 {
 	auto it = values.find(key);
 	if (it != values.end())
@@ -103,7 +105,7 @@ bool IniFile::Section::Get(const char* key, std::string* value, const char* defa
 		*value = it->second;
 		return true;
 	}
-	else if (defaultValue)
+	else if (&defaultValue != &NULL_STRING)
 	{
 		*value = defaultValue;
 		return true;
@@ -112,10 +114,10 @@ bool IniFile::Section::Get(const char* key, std::string* value, const char* defa
 		return false;
 }
 
-bool IniFile::Section::Get(const char* key, std::vector<std::string>& out)
+bool IniFile::Section::Get(const std::string& key, std::vector<std::string>& out)
 {
 	std::string temp;
-	bool retval = Get(key, &temp, 0);
+	bool retval = Get(key, &temp);
 	if (!retval || temp.empty())
 	{
 		return false;
@@ -138,62 +140,62 @@ bool IniFile::Section::Get(const char* key, std::vector<std::string>& out)
 	return true;
 }
 
-bool IniFile::Section::Get(const char* key, int* value, int defaultValue)
+bool IniFile::Section::Get(const std::string& key, int* value, int defaultValue)
 {
 	std::string temp;
-	bool retval = Get(key, &temp, 0);
-	if (retval && TryParse(temp.c_str(), value))
+	bool retval = Get(key, &temp);
+	if (retval && TryParse(temp, value))
 		return true;
 	*value = defaultValue;
 	return false;
 }
 
-bool IniFile::Section::Get(const char* key, u32* value, u32 defaultValue)
+bool IniFile::Section::Get(const std::string& key, u32* value, u32 defaultValue)
 {
 	std::string temp;
-	bool retval = Get(key, &temp, 0);
+	bool retval = Get(key, &temp);
 	if (retval && TryParse(temp, value))
 		return true;
 	*value = defaultValue;
 	return false;
 }
 
-bool IniFile::Section::Get(const char* key, bool* value, bool defaultValue)
+bool IniFile::Section::Get(const std::string& key, bool* value, bool defaultValue)
 {
 	std::string temp;
-	bool retval = Get(key, &temp, 0);
-	if (retval && TryParse(temp.c_str(), value))
+	bool retval = Get(key, &temp);
+	if (retval && TryParse(temp, value))
 		return true;
 	*value = defaultValue;
 	return false;
 }
 
-bool IniFile::Section::Get(const char* key, float* value, float defaultValue)
+bool IniFile::Section::Get(const std::string& key, float* value, float defaultValue)
 {
 	std::string temp;
-	bool retval = Get(key, &temp, 0);
-	if (retval && TryParse(temp.c_str(), value))
+	bool retval = Get(key, &temp);
+	if (retval && TryParse(temp, value))
 		return true;
 	*value = defaultValue;
 	return false;
 }
 
-bool IniFile::Section::Get(const char* key, double* value, double defaultValue)
+bool IniFile::Section::Get(const std::string& key, double* value, double defaultValue)
 {
 	std::string temp;
-	bool retval = Get(key, &temp, 0);
-	if (retval && TryParse(temp.c_str(), value))
+	bool retval = Get(key, &temp);
+	if (retval && TryParse(temp, value))
 		return true;
 	*value = defaultValue;
 	return false;
 }
 
-bool IniFile::Section::Exists(const char *key) const
+bool IniFile::Section::Exists(const std::string& key) const
 {
 	return values.find(key) != values.end();
 }
 
-bool IniFile::Section::Delete(const char *key)
+bool IniFile::Section::Delete(const std::string& key)
 {
 	auto it = values.find(key);
 	if (it == values.end())
@@ -206,23 +208,23 @@ bool IniFile::Section::Delete(const char *key)
 
 // IniFile
 
-const IniFile::Section* IniFile::GetSection(const char* sectionName) const
+const IniFile::Section* IniFile::GetSection(const std::string& sectionName) const
 {
 	for (const auto& sect : sections)
-		if (!strcasecmp(sect.name.c_str(), sectionName))
+		if (!strcasecmp(sect.name.c_str(), sectionName.c_str()))
 			return (&(sect));
 	return 0;
 }
 
-IniFile::Section* IniFile::GetSection(const char* sectionName)
+IniFile::Section* IniFile::GetSection(const std::string& sectionName)
 {
 	for (auto& sect : sections)
-		if (!strcasecmp(sect.name.c_str(), sectionName))
+		if (!strcasecmp(sect.name.c_str(), sectionName.c_str()))
 			return (&(sect));
 	return 0;
 }
 
-IniFile::Section* IniFile::GetOrCreateSection(const char* sectionName)
+IniFile::Section* IniFile::GetOrCreateSection(const std::string& sectionName)
 {
 	Section* section = GetSection(sectionName);
 	if (!section)
@@ -233,7 +235,7 @@ IniFile::Section* IniFile::GetOrCreateSection(const char* sectionName)
 	return section;
 }
 
-bool IniFile::DeleteSection(const char* sectionName)
+bool IniFile::DeleteSection(const std::string& sectionName)
 {
 	Section* s = GetSection(sectionName);
 	if (!s)
@@ -249,7 +251,7 @@ bool IniFile::DeleteSection(const char* sectionName)
 	return false;
 }
 
-bool IniFile::Exists(const char* sectionName, const char* key) const
+bool IniFile::Exists(const std::string& sectionName, const std::string& key) const
 {
 	const Section* section = GetSection(sectionName);
 	if (!section)
@@ -257,13 +259,13 @@ bool IniFile::Exists(const char* sectionName, const char* key) const
 	return section->Exists(key);
 }
 
-void IniFile::SetLines(const char* sectionName, const std::vector<std::string> &lines)
+void IniFile::SetLines(const std::string& sectionName, const std::vector<std::string> &lines)
 {
 	Section* section = GetOrCreateSection(sectionName);
 	section->lines = lines;
 }
 
-bool IniFile::DeleteKey(const char* sectionName, const char* key)
+bool IniFile::DeleteKey(const std::string& sectionName, const std::string& key)
 {
 	Section* section = GetSection(sectionName);
 	if (!section)
@@ -272,7 +274,7 @@ bool IniFile::DeleteKey(const char* sectionName, const char* key)
 }
 
 // Return a list of all keys in a section
-bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys) const
+bool IniFile::GetKeys(const std::string& sectionName, std::vector<std::string>& keys) const
 {
 	const Section* section = GetSection(sectionName);
 	if (!section)
@@ -282,7 +284,7 @@ bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys) c
 }
 
 // Return a list of all lines in a section
-bool IniFile::GetLines(const char* sectionName, std::vector<std::string>& lines, const bool remove_comments) const
+bool IniFile::GetLines(const std::string& sectionName, std::vector<std::string>& lines, const bool remove_comments) const
 {
 	const Section* section = GetSection(sectionName);
 	if (!section)
@@ -319,7 +321,7 @@ void IniFile::SortSections()
 	std::sort(sections.begin(), sections.end());
 }
 
-bool IniFile::Load(const char* filename, bool keep_current_data)
+bool IniFile::Load(const std::string& filename, bool keep_current_data)
 {
 	// Maximum number of letters in a line
 	static const int MAX_BYTES = 1024*32;
@@ -359,7 +361,7 @@ bool IniFile::Load(const char* filename, bool keep_current_data)
 				{
 					// New section!
 					std::string sub = line.substr(1, endpos - 1);
-					current_section = GetOrCreateSection(sub.c_str());
+					current_section = GetOrCreateSection(sub);
 				}
 			}
 			else
@@ -374,9 +376,9 @@ bool IniFile::Load(const char* filename, bool keep_current_data)
 					// INI is a hack anyway.
 					if ((key == "" && value == "")
 					        || (line.size() >= 1 && (line[0] == '$' || line[0] == '+' || line[0] == '*')))
-						current_section->lines.push_back(line.c_str());
+						current_section->lines.push_back(line);
 					else
-						current_section->Set(key, value.c_str());
+						current_section->Set(key, value);
 				}
 			}
 		}
@@ -386,7 +388,7 @@ bool IniFile::Load(const char* filename, bool keep_current_data)
 	return true;
 }
 
-bool IniFile::Save(const char* filename)
+bool IniFile::Save(const std::string& filename)
 {
 	std::ofstream out;
 	std::string temp = File::GetTempFilenameForAtomicWrite(filename);
@@ -422,20 +424,7 @@ bool IniFile::Save(const char* filename)
 	return File::RenameSync(temp, filename);
 }
 
-
-bool IniFile::Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue)
-{
-	Section* section = GetSection(sectionName);
-	if (!section) {
-		if (defaultValue) {
-			*value = defaultValue;
-		}
-		return false;
-	}
-	return section->Get(key, value, defaultValue);
-}
-
-bool IniFile::Get(const char *sectionName, const char* key, std::vector<std::string>& values)
+bool IniFile::Get(const std::string& sectionName, const std::string& key, std::vector<std::string>& values)
 {
 	Section *section = GetSection(sectionName);
 	if (!section)
@@ -443,7 +432,7 @@ bool IniFile::Get(const char *sectionName, const char* key, std::vector<std::str
 	return section->Get(key, values);
 }
 
-bool IniFile::Get(const char* sectionName, const char* key, int* value, int defaultValue)
+bool IniFile::Get(const std::string& sectionName, const std::string& key, int* value, int defaultValue)
 {
 	Section *section = GetSection(sectionName);
 	if (!section) {
@@ -454,7 +443,7 @@ bool IniFile::Get(const char* sectionName, const char* key, int* value, int defa
 	}
 }
 
-bool IniFile::Get(const char* sectionName, const char* key, u32* value, u32 defaultValue)
+bool IniFile::Get(const std::string& sectionName, const std::string& key, u32* value, u32 defaultValue)
 {
 	Section *section = GetSection(sectionName);
 	if (!section) {
@@ -465,7 +454,7 @@ bool IniFile::Get(const char* sectionName, const char* key, u32* value, u32 defa
 	}
 }
 
-bool IniFile::Get(const char* sectionName, const char* key, bool* value, bool defaultValue)
+bool IniFile::Get(const std::string& sectionName, const std::string& key, bool* value, bool defaultValue)
 {
 	Section *section = GetSection(sectionName);
 	if (!section) {
@@ -476,6 +465,19 @@ bool IniFile::Get(const char* sectionName, const char* key, bool* value, bool de
 	}
 }
 
+bool IniFile::Get(const std::string& sectionName, const std::string& key, std::string* value, const std::string& defaultValue)
+{
+	Section* section = GetSection(sectionName);
+	if (!section) {
+		if (&defaultValue != &NULL_STRING) {
+			*value = defaultValue;
+		}
+		return false;
+	}
+	return section->Get(key, value, defaultValue);
+}
+
+
 
 // Unit test. TODO: Move to the real unit test framework.
 /*
diff --git a/Source/Core/Common/IniFile.h b/Source/Core/Common/IniFile.h
index abfb58b..3ae80a6 100644
--- a/Source/Core/Common/IniFile.h
+++ b/Source/Core/Common/IniFile.h
@@ -32,45 +32,42 @@ public:
 		Section() {}
 		Section(const std::string& _name) : name(_name) {}
 
-		bool Exists(const char *key) const;
-		bool Delete(const char *key);
+		bool Exists(const std::string& key) const;
+		bool Delete(const std::string& key);
 
-		void Set(const char* key, const char* newValue);
-		void Set(const char* key, const std::string& newValue, const std::string& defaultValue);
+		void Set(const std::string& key, const std::string& newValue);
+		void Set(const std::string& key, const std::string& newValue, const std::string& defaultValue);
 
-		void Set(const std::string &key, const std::string &value) {
-			Set(key.c_str(), value.c_str());
-		}
-		bool Get(const char* key, std::string* value, const char* defaultValue);
+ 		bool Get(const std::string& key, std::string* value, const std::string& defaultValue = NULL_STRING);
 
-		void Set(const char* key, u32 newValue) {
-			Set(key, StringFromFormat("0x%08x", newValue).c_str());
+		void Set(const std::string& key, u32 newValue) {
+			Set(key, StringFromFormat("0x%08x", newValue));
 		}
-		void Set(const char* key, float newValue) {
-			Set(key, StringFromFormat("%f", newValue).c_str());
+		void Set(const std::string& key, float newValue) {
+			Set(key, StringFromFormat("%f", newValue));
 		}
-		void Set(const char* key, const float newValue, const float defaultValue);
-		void Set(const char* key, double newValue) {
-			Set(key, StringFromFormat("%f", newValue).c_str());
+		void Set(const std::string& key, const float newValue, const float defaultValue);
+		void Set(const std::string& key, double newValue) {
+			Set(key, StringFromFormat("%f", newValue));
 		}
 
-		void Set(const char* key, int newValue, int defaultValue);
-		void Set(const char* key, int newValue) {
-			Set(key, StringFromInt(newValue).c_str());
+		void Set(const std::string& key, int newValue, int defaultValue);
+		void Set(const std::string& key, int newValue) {
+			Set(key, StringFromInt(newValue));
 		}
 
-		void Set(const char* key, bool newValue, bool defaultValue);
-		void Set(const char* key, bool newValue) {
-			Set(key, StringFromBool(newValue).c_str());
+		void Set(const std::string& key, bool newValue, bool defaultValue);
+		void Set(const std::string& key, bool newValue) {
+			Set(key, StringFromBool(newValue));
 		}
-		void Set(const char* key, const std::vector<std::string>& newValues);
+		void Set(const std::string& key, const std::vector<std::string>& newValues);
 
-		bool Get(const char* key, int* value, int defaultValue = 0);
-		bool Get(const char* key, u32* value, u32 defaultValue = 0);
-		bool Get(const char* key, bool* value, bool defaultValue = false);
-		bool Get(const char* key, float* value, float defaultValue = false);
-		bool Get(const char* key, double* value, double defaultValue = false);
-		bool Get(const char* key, std::vector<std::string>& values);
+		bool Get(const std::string& key, int* value, int defaultValue = 0);
+		bool Get(const std::string& key, u32* value, u32 defaultValue = 0);
+		bool Get(const std::string& key, bool* value, bool defaultValue = false);
+		bool Get(const std::string& key, float* value, float defaultValue = false);
+		bool Get(const std::string& key, double* value, double defaultValue = false);
+		bool Get(const std::string& key, std::vector<std::string>& values);
 
 		bool operator < (const Section& other) const {
 			return name < other.name;
@@ -92,68 +89,65 @@ public:
 	 * @warning Using any other operations than "Get*" and "Exists" is untested and will behave unexpectedly
 	 * @todo This really is just a hack to support having two levels of gameinis (defaults and user-specified) and should eventually be replaced with a less stupid system.
 	 */
-	bool Load(const char* filename, bool keep_current_data = false);
-	bool Load(const std::string &filename, bool keep_current_data = false) { return Load(filename.c_str(), keep_current_data); }
+	bool Load(const std::string& filename, bool keep_current_data = false);
 
-	bool Save(const char* filename);
-	bool Save(const std::string &filename) { return Save(filename.c_str()); }
+	bool Save(const std::string& filename);
 
 	// Returns true if key exists in section
-	bool Exists(const char* sectionName, const char* key) const;
+	bool Exists(const std::string& sectionName, const std::string& key) const;
 
 	// TODO: Get rid of these, in favor of the Section ones.
-	void Set(const char* sectionName, const char* key, const char* newValue) {
+	void Set(const std::string& sectionName, const std::string& key, const std::string& newValue) {
 		GetOrCreateSection(sectionName)->Set(key, newValue);
 	}
-	void Set(const char* sectionName, const char* key, const std::string& newValue) {
-		GetOrCreateSection(sectionName)->Set(key, newValue.c_str());
-	}
-	void Set(const char* sectionName, const char* key, int newValue) {
+	void Set(const std::string& sectionName, const std::string& key, int newValue) {
 		GetOrCreateSection(sectionName)->Set(key, newValue);
 	}
-	void Set(const char* sectionName, const char* key, u32 newValue) {
+	void Set(const std::string& sectionName, const std::string& key, u32 newValue) {
 		GetOrCreateSection(sectionName)->Set(key, newValue);
 	}
-	void Set(const char* sectionName, const char* key, bool newValue) {
+	void Set(const std::string& sectionName, const std::string& key, bool newValue) {
 		GetOrCreateSection(sectionName)->Set(key, newValue);
 	}
-	void Set(const char* sectionName, const char* key, const std::vector<std::string>& newValues) {
+	void Set(const std::string& sectionName, const std::string& key, const std::vector<std::string>& newValues) {
 		GetOrCreateSection(sectionName)->Set(key, newValues);
 	}
 
 	// TODO: Get rid of these, in favor of the Section ones.
-	bool Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue = "");
-	bool Get(const char* sectionName, const char* key, int* value, int defaultValue = 0);
-	bool Get(const char* sectionName, const char* key, u32* value, u32 defaultValue = 0);
-	bool Get(const char* sectionName, const char* key, bool* value, bool defaultValue = false);
-	bool Get(const char* sectionName, const char* key, std::vector<std::string>& values);
+	bool Get(const std::string& sectionName, const std::string& key, int* value, int defaultValue = 0);
+	bool Get(const std::string& sectionName, const std::string& key, u32* value, u32 defaultValue = 0);
+	bool Get(const std::string& sectionName, const std::string& key, bool* value, bool defaultValue = false);
+	bool Get(const std::string& sectionName, const std::string& key, std::vector<std::string>& values);
+	bool Get(const std::string& sectionName, const std::string& key, std::string* value, const std::string& defaultValue = NULL_STRING);
 
-	template<typename T> bool GetIfExists(const char* sectionName, const char* key, T value)
+	template<typename T> bool GetIfExists(const std::string& sectionName, const std::string& key, T value)
 	{
 		if (Exists(sectionName, key))
 			return Get(sectionName, key, value);
 		return false;
 	}
 
-	bool GetKeys(const char* sectionName, std::vector<std::string>& keys) const;
+	bool GetKeys(const std::string& sectionName, std::vector<std::string>& keys) const;
 
-	void SetLines(const char* sectionName, const std::vector<std::string> &lines);
-	bool GetLines(const char* sectionName, std::vector<std::string>& lines, const bool remove_comments = true) const;
+	void SetLines(const std::string& sectionName, const std::vector<std::string> &lines);
+	bool GetLines(const std::string& sectionName, std::vector<std::string>& lines, const bool remove_comments = true) const;
 
-	bool DeleteKey(const char* sectionName, const char* key);
-	bool DeleteSection(const char* sectionName);
+	bool DeleteKey(const std::string& sectionName, const std::string& key);
+	bool DeleteSection(const std::string& sectionName);
 
 	void SortSections();
 
-	Section* GetOrCreateSection(const char* section);
+	Section* GetOrCreateSection(const std::string& section);
 
 private:
 	std::vector<Section> sections;
 
-	const Section* GetSection(const char* section) const;
-	Section* GetSection(const char* section);
-	std::string* GetLine(const char* section, const char* key);
-	void CreateSection(const char* section);
+	const Section* GetSection(const std::string& section) const;
+	Section* GetSection(const std::string& section);
+	std::string* GetLine(const std::string& section, const std::string& key);
+	void CreateSection(const std::string& section);
+	
+	static const std::string& NULL_STRING;
 };
 
 #endif // _INIFILE_H_
diff --git a/Source/Core/Common/Log.h b/Source/Core/Common/Log.h
index b0f3519..8c7a1eb 100644
--- a/Source/Core/Common/Log.h
+++ b/Source/Core/Common/Log.h
@@ -77,6 +77,8 @@ enum LOG_LEVELS
 	LDEBUG   = DEBUG_LEVEL,
 };
 
+static const char LOG_LEVEL_TO_CHAR[7] = "-NEWID";
+
 #define LOGTYPES_LEVELS LogTypes::LOG_LEVELS
 #define LOGTYPES_TYPE LogTypes::LOG_TYPE
 
diff --git a/Source/Core/Common/LogManager.cpp b/Source/Core/Common/LogManager.cpp
index 50c6ab4..5fe218b 100644
--- a/Source/Core/Common/LogManager.cpp
+++ b/Source/Core/Common/LogManager.cpp
@@ -114,7 +114,6 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,
 	const char *file, int line, const char *format, va_list args)
 {
 	char temp[MAX_MSGLEN];
-	char msg[MAX_MSGLEN * 2];
 	LogContainer *log = m_Log[type];
 
 	if (!log->IsEnabled() || level > log->GetLevel() || ! log->HasListeners())
@@ -122,15 +121,15 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,
 
 	CharArrayFromFormatV(temp, MAX_MSGLEN, format, args);
 
-	static const char level_to_char[7] = "-NEWID";
-	sprintf(msg, "%s %s:%u %c[%s]: %s\n",
-		Common::Timer::GetTimeFormatted().c_str(),
-		file, line, level_to_char[(int)level],
-		log->GetShortName(), temp);
+	std::string msg = StringFromFormat("%s %s:%u %c[%s]: %s\n",
+	                                   Common::Timer::GetTimeFormatted().c_str(),
+	                                   file, line, 
+	                                   LogTypes::LOG_LEVEL_TO_CHAR[(int)level],
+	                                   log->GetShortName(), temp);
 #ifdef ANDROID
-	Host_SysMessage(msg);
+	Host_SysMessage(msg.c_str());
 #endif
-	log->Trigger(level, msg);
+	log->Trigger(level, msg.c_str());
 }
 
 void LogManager::Init()
diff --git a/Source/Core/Common/MemArena.cpp b/Source/Core/Common/MemArena.cpp
index e7f3911..699005d 100644
--- a/Source/Core/Common/MemArena.cpp
+++ b/Source/Core/Common/MemArena.cpp
@@ -6,6 +6,7 @@
 
 #include "MemoryUtil.h"
 #include "MemArena.h"
+#include "StringUtil.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -57,20 +58,21 @@ void MemArena::GrabLowMemSpace(size_t size)
 		return;
 	}
 #else
-	char fn[64];
 	for (int i = 0; i < 10000; i++)
 	{
-		sprintf(fn, "dolphinmem.%d", i);
-		fd = shm_open(fn, O_RDWR | O_CREAT | O_EXCL, 0600);
+		std::string file_name = StringFromFormat("dolphinmem.%d", i);
+		fd = shm_open(file_name.c_str(), O_RDWR | O_CREAT | O_EXCL, 0600);
 		if (fd != -1)
+		{
+			shm_unlink(file_name.c_str());
 			break;
-		if (errno != EEXIST)
+		}
+		else if (errno != EEXIST)
 		{
 			ERROR_LOG(MEMMAP, "shm_open failed: %s", strerror(errno));
 			return;
 		}
 	}
-	shm_unlink(fn);
 	if (ftruncate(fd, size) < 0)
 		ERROR_LOG(MEMMAP, "Failed to allocate low memory space");
 #endif
diff --git a/Source/Core/Common/NandPaths.cpp b/Source/Core/Common/NandPaths.cpp
index 3ca5550..52e3904 100644
--- a/Source/Core/Common/NandPaths.cpp
+++ b/Source/Core/Common/NandPaths.cpp
@@ -12,20 +12,16 @@ namespace Common
 
 std::string GetTicketFileName(u64 _titleID)
 {
-	char TicketFilename[1024];
-	sprintf(TicketFilename, "%sticket/%08x/%08x.tik",
-			File::GetUserPath(D_WIIUSER_IDX).c_str(), (u32)(_titleID >> 32), (u32)_titleID);
-
-	return TicketFilename;
+	return StringFromFormat("%sticket/%08x/%08x.tik",
+			File::GetUserPath(D_WIIUSER_IDX).c_str(), 
+			(u32)(_titleID >> 32), (u32)_titleID);
 }
 
 std::string GetTitleDataPath(u64 _titleID)
 {
-	char path[1024];
-	sprintf(path, "%stitle/%08x/%08x/data/",
-			File::GetUserPath(D_WIIUSER_IDX).c_str(), (u32)(_titleID >> 32), (u32)_titleID);
-
-	return path;
+	return StringFromFormat("%stitle/%08x/%08x/data/",
+			File::GetUserPath(D_WIIUSER_IDX).c_str(),
+			(u32)(_titleID >> 32), (u32)_titleID);
 }
 
 std::string GetTMDFileName(u64 _titleID)
@@ -34,11 +30,9 @@ std::string GetTMDFileName(u64 _titleID)
 }
 std::string GetTitleContentPath(u64 _titleID)
 {
-	char ContentPath[1024];
-	sprintf(ContentPath, "%stitle/%08x/%08x/content/",
-			File::GetUserPath(D_WIIUSER_IDX).c_str(), (u32)(_titleID >> 32), (u32)_titleID);
-
-	return ContentPath;
+	return StringFromFormat("%stitle/%08x/%08x/content/",
+			File::GetUserPath(D_WIIUSER_IDX).c_str(), 
+			(u32)(_titleID >> 32), (u32)_titleID);
 }
 
 bool CheckTitleTMD(u64 _titleID)
diff --git a/Source/Core/Common/SettingsHandler.h b/Source/Core/Common/SettingsHandler.h
index 232555d..3666935 100644
--- a/Source/Core/Common/SettingsHandler.h
+++ b/Source/Core/Common/SettingsHandler.h
@@ -22,6 +22,10 @@ public:
 		INITIAL_SEED = 0x73B5DBFA
 	};
 
+	inline void AddSetting(const char *key, const std::string& value)
+	{
+		AddSetting(key, value.c_str());
+	}
 	void AddSetting(const char *key, const char *value);
 
 	const u8 *GetData() const;
diff --git a/Source/Core/Common/Timer.cpp b/Source/Core/Common/Timer.cpp
index 267755f..91a2a2d 100644
--- a/Source/Core/Common/Timer.cpp
+++ b/Source/Core/Common/Timer.cpp
@@ -167,27 +167,23 @@ u64 Timer::GetLocalTimeSinceJan1970()
 std::string Timer::GetTimeFormatted()
 {
 	time_t sysTime;
-	struct tm * gmTime;
-	char formattedTime[13];
-	char tmp[13];
-
 	time(&sysTime);
-	gmTime = localtime(&sysTime);
+	
+	struct tm * gmTime = localtime(&sysTime);
 
+	char tmp[13];
 	strftime(tmp, 6, "%M:%S", gmTime);
 
 	// Now tack on the milliseconds
 #ifdef _WIN32
 	struct timeb tp;
 	(void)::ftime(&tp);
-	sprintf(formattedTime, "%s:%03i", tmp, tp.millitm);
+	return StringFromFormat("%s:%03i", tmp, tp.millitm);
 #else
 	struct timeval t;
 	(void)gettimeofday(&t, NULL);
-	sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000));
+	return StringFromFormat("%s:%03d", tmp, (int)(t.tv_usec / 1000));
 #endif
-
-	return std::string(formattedTime);
 }
 
 // Returns a timestamp with decimals for precise time comparisons
diff --git a/Source/Core/Core/ActionReplay.cpp b/Source/Core/Core/ActionReplay.cpp
index e07f297..5223903 100644
--- a/Source/Core/Core/ActionReplay.cpp
+++ b/Source/Core/Core/ActionReplay.cpp
@@ -246,7 +246,7 @@ void LogInfo(const char *format, ...)
 			{
 				std::string text = temp;
 				text += '\n';
-				arLog.push_back(text.c_str());
+				arLog.push_back(text);
 			}
 		}
 	}
diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h
index da24177..b351ce5 100644
--- a/Source/Core/Core/Boot/Boot.h
+++ b/Source/Core/Core/Boot/Boot.h
@@ -10,6 +10,17 @@
 
 #include "../CoreParameter.h"
 
+#include "Volume.h"
+using DiscIO::IVolume;
+
+typedef struct CountrySetting 
+{
+	const std::string area;
+	const std::string video;
+	const std::string game;
+	const std::string code;
+} CountrySetting;
+	
 class CBoot
 {
 public:
@@ -45,7 +56,7 @@ private:
 	static bool Load_BS2(const std::string& _rBootROMFilename);
 	static void Load_FST(bool _bIsWii);
 
-	static bool SetupWiiMemory(unsigned int _CountryCode);
+	static bool SetupWiiMemory(IVolume::ECountry country);
 };
 
 #endif
diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp
index c7b8483..ef8eae7 100644
--- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp
+++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp
@@ -158,56 +158,28 @@ bool CBoot::EmulatedBS2_GC()
 	return true;
 }
 
-bool CBoot::SetupWiiMemory(unsigned int _CountryCode)
+bool CBoot::SetupWiiMemory(IVolume::ECountry country)
 {
-	INFO_LOG(BOOT, "Setup Wii Memory...");
-
-	// Write the 256 byte setting.txt to memory.
-	std::string settings_Filename(Common::GetTitleDataPath(TITLEID_SYSMENU) + WII_SETTING);
-	std::string area, model, code, video, game;
-
-
-	switch((DiscIO::IVolume::ECountry)_CountryCode)
-	{
-	case DiscIO::IVolume::COUNTRY_KOREA:
-		area = "KOR";
-		video = "NTSC";
-		game = "KR";
-		code = "LKH";
-		break;
-	case DiscIO::IVolume::COUNTRY_TAIWAN:
-		// TODO: Determine if Taiwan have their own specific settings.
-	case DiscIO::IVolume::COUNTRY_JAPAN:
-		area = "JPN";
-		video = "NTSC";
-		game = "JP";
-		code = "LJ";
-		break;
-	case DiscIO::IVolume::COUNTRY_USA:
-		area = "USA";
-		video = "NTSC";
-		game = "US";
-		code = "LU";
-		break;
-	case DiscIO::IVolume::COUNTRY_EUROPE:
-		area = "EUR";
-		video = "PAL";
-		game = "EU";
-		code = "LE";
-		break;
-	default:
-		// PanicAlertT("SetupWiiMem: Unknown country. Wii boot process will be switched to European settings.");
-		area = "EUR";
-		video = "PAL";
-		game = "EU";
-		code = "LE";
-		break;
-	}
-
-	model = "RVL-001(" + area + ")";
+	static const CountrySetting SETTING_EUROPE = {"EUR", "PAL",  "EU", "LE"};
+	static const std::map<IVolume::ECountry, const CountrySetting&> country_settings = {
+		{IVolume::COUNTRY_EUROPE, SETTING_EUROPE},
+		{IVolume::COUNTRY_USA,    {"USA", "NTSC", "US", "LU"}},
+		{IVolume::COUNTRY_JAPAN,  {"JPN", "NTSC", "JP", "LJ"}},
+		{IVolume::COUNTRY_KOREA,  {"KOR", "NTSC", "KR", "LKH"}},
+		//TODO: Determine if Taiwan have their own specific settings.
+		//      Also determine if there are other specific settings
+		//      for other countries.
+		{IVolume::COUNTRY_TAIWAN, {"JPN", "NTSC", "JP", "LJ"}}
+	};
+	auto entryPos = country_settings.find(country);
+	const CountrySetting& country_setting = 
+		(entryPos != country_settings.end()) ? 
+		  entryPos->second : 
+		  SETTING_EUROPE; //Default to EUROPE
 
 	SettingsHandler gen;
-	std::string serno = "";
+	std::string serno;
+	std::string settings_Filename(Common::GetTitleDataPath(TITLEID_SYSMENU) + WII_SETTING);
 	if (File::Exists(settings_Filename))
 	{
 		File::IOFile settingsFileHandle(settings_Filename, "rb");
@@ -230,29 +202,31 @@ bool CBoot::SetupWiiMemory(unsigned int _CountryCode)
 		INFO_LOG(BOOT, "Using serial number: %s", serno.c_str());
 	}
 
-	gen.AddSetting("AREA", area.c_str());
-	gen.AddSetting("MODEL", model.c_str());
+	std::string model = "RVL-001(" + country_setting.area + ")";
+	gen.AddSetting("AREA", country_setting.area);
+	gen.AddSetting("MODEL", model);
 	gen.AddSetting("DVD", "0");
 	gen.AddSetting("MPCH", "0x7FFE");
-	gen.AddSetting("CODE", code.c_str());
-	gen.AddSetting("SERNO", serno.c_str());
-	gen.AddSetting("VIDEO", video.c_str());
-	gen.AddSetting("GAME", game.c_str());
-
-
+	gen.AddSetting("CODE", country_setting.code);
+	gen.AddSetting("SERNO", serno);
+	gen.AddSetting("VIDEO", country_setting.video);
+	gen.AddSetting("GAME", country_setting.game);
+	
 	File::CreateFullPath(settings_Filename);
-
 	{
 		File::IOFile settingsFileHandle(settings_Filename, "wb");
 
 		if (!settingsFileHandle.WriteBytes(gen.GetData(), SettingsHandler::SETTINGS_SIZE))
 		{
-			PanicAlertT("SetupWiiMem: Cant create setting file");
+			PanicAlertT("SetupWiiMemory: Cant create setting.txt file");
 			return false;
 		}
+		// Write the 256 byte setting.txt to memory.
 		Memory::WriteBigEData(gen.GetData(), 0x3800, SettingsHandler::SETTINGS_SIZE);
 	}
 
+	INFO_LOG(BOOT, "Setup Wii Memory...");
+	
 	/*
 	Set hardcoded global variables to Wii memory. These are partly collected from
 	Wiibrew. These values are needed for the games to function correctly. A few
diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp
index e12eb43..517bc3a 100644
--- a/Source/Core/Core/BootManager.cpp
+++ b/Source/Core/Core/BootManager.cpp
@@ -145,7 +145,7 @@ bool BootCore(const std::string& _rFilename)
 		game_ini.Get("Core", "BlockMerging",		&StartUp.bMergeBlocks, StartUp.bMergeBlocks);
 		game_ini.Get("Core", "DSPHLE",				&StartUp.bDSPHLE, StartUp.bDSPHLE);
 		game_ini.Get("Core", "DSPThread",			&StartUp.bDSPThread, StartUp.bDSPThread);
-		game_ini.Get("Core", "GFXBackend",			&StartUp.m_strVideoBackend, StartUp.m_strVideoBackend.c_str());
+		game_ini.Get("Core", "GFXBackend",			&StartUp.m_strVideoBackend, StartUp.m_strVideoBackend);
 		game_ini.Get("Core", "CPUCore",				&StartUp.iCPUCore, StartUp.iCPUCore);
 		game_ini.Get("Core", "HLE_BS2",				&StartUp.bHLE_BS2, StartUp.bHLE_BS2);
 		if (game_ini.Get("Core", "FrameLimit",		&SConfig::GetInstance().m_Framelimit, SConfig::GetInstance().m_Framelimit))
@@ -155,13 +155,13 @@ bool BootCore(const std::string& _rFilename)
 		if (game_ini.Get("DSP", "Volume",			&SConfig::GetInstance().m_Volume, SConfig::GetInstance().m_Volume))
 			config_cache.bSetVolume = true;
 		game_ini.Get("DSP", "EnableJIT",			&SConfig::GetInstance().m_EnableJIT, SConfig::GetInstance().m_EnableJIT);
-		game_ini.Get("DSP", "Backend",				&SConfig::GetInstance().sBackend, SConfig::GetInstance().sBackend.c_str());
+		game_ini.Get("DSP", "Backend",				&SConfig::GetInstance().sBackend, SConfig::GetInstance().sBackend);
 		VideoBackend::ActivateBackend(StartUp.m_strVideoBackend);
 
 		for (unsigned int i = 0; i < MAX_SI_CHANNELS; ++i)
 		{
 			int source;
-			game_ini.Get("Controls", StringFromFormat("PadType%u", i).c_str(), &source, -1);
+			game_ini.Get("Controls", StringFromFormat("PadType%u", i), &source, -1);
 			if (source >= (int) SIDEVICE_NONE && source <= (int) SIDEVICE_AM_BASEBOARD)
 			{
 				SConfig::GetInstance().m_SIDevice[i] = (SIDevices) source;
@@ -178,7 +178,7 @@ bool BootCore(const std::string& _rFilename)
 			int source;
 			for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
 			{
-				game_ini.Get("Controls", StringFromFormat("WiimoteSource%u", i).c_str(), &source, -1);
+				game_ini.Get("Controls", StringFromFormat("WiimoteSource%u", i), &source, -1);
 				if (source != -1 && g_wiimote_sources[i] != (unsigned) source && source >= WIIMOTE_SRC_NONE && source <= WIIMOTE_SRC_HYBRID)
 				{
 					config_cache.bSetWiimoteSource[i] = true;
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index f28dfa5..879f431 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -151,18 +151,14 @@ void SConfig::SaveSettings()
 	ini.Get("General", "GCMPathes", &oldPaths, 0);
 	for (int i = numPaths; i < oldPaths; i++)
 	{
-		char tmp[16];
-		sprintf(tmp, "GCMPath%i", i);
-		ini.DeleteKey("General", tmp);
+		ini.DeleteKey("General", StringFromFormat("GCMPath%i", i));
 	}
 
-	ini.Set("General", "GCMPathes",		numPaths);
+	ini.Set("General", "GCMPathes", numPaths);
 
 	for (int i = 0; i < numPaths; i++)
 	{
-		char tmp[16];
-		sprintf(tmp, "GCMPath%i", i);
-		ini.Set("General", tmp, m_ISOFolder[i]);
+		ini.Set("General", StringFromFormat("GCMPath%i", i), m_ISOFolder[i]);
 	}
 
 	ini.Set("General", "RecursiveGCMPaths", m_RecursiveISOFolder);
@@ -194,7 +190,7 @@ void SConfig::SaveSettings()
 	for (int i = 0; i < NUM_HOTKEYS; i++)
 	{
 		ini.Set("Hotkeys", g_HKData[i].IniText, m_LocalCoreStartupParameter.iHotkey[i]);
-		ini.Set("Hotkeys", (std::string(g_HKData[i].IniText) + "Modifier").c_str(),
+		ini.Set("Hotkeys", (std::string(g_HKData[i].IniText) + "Modifier"),
 				m_LocalCoreStartupParameter.iHotkeyModifier[i]);
 	}
 
@@ -249,13 +245,10 @@ void SConfig::SaveSettings()
 	ini.Set("Core", "SlotB",			m_EXIDevice[1]);
 	ini.Set("Core", "SerialPort1",		m_EXIDevice[2]);
 	ini.Set("Core", "BBA_MAC",			m_bba_mac);
-	char sidevicenum[16];
 	for (int i = 0; i < 4; ++i)
 	{
-		sprintf(sidevicenum, "SIDevice%i", i);
-		ini.Set("Core", sidevicenum, m_SIDevice[i]);
+		ini.Set("Core", StringFromFormat("SIDevice%i", i), m_SIDevice[i]);
 	}
-
 	ini.Set("Core", "WiiSDCard", m_WiiSDCard);
 	ini.Set("Core", "WiiKeyboard", m_WiiKeyboard);
 	ini.Set("Core", "WiimoteContinuousScanning", m_WiimoteContinuousScanning);
@@ -307,11 +300,9 @@ void SConfig::LoadSettings()
 		{
 			for (int i = 0; i < numGCMPaths; i++)
 			{
-				char tmp[16];
-				sprintf(tmp, "GCMPath%i", i);
 				std::string tmpPath;
-				ini.Get("General", tmp, &tmpPath, "");
-				m_ISOFolder.push_back(tmpPath);
+				ini.Get("General", StringFromFormat("GCMPath%i", i), &tmpPath, "");
+				m_ISOFolder.push_back(std::move(tmpPath));
 			}
 		}
 
@@ -348,7 +339,7 @@ void SConfig::LoadSettings()
 		{
 			ini.Get("Hotkeys", g_HKData[i].IniText,
 					&m_LocalCoreStartupParameter.iHotkey[i], g_HKData[i].DefaultKey);
-			ini.Get("Hotkeys", (std::string(g_HKData[i].IniText) + "Modifier").c_str(),
+			ini.Get("Hotkeys", (std::string(g_HKData[i].IniText) + "Modifier"),
 					&m_LocalCoreStartupParameter.iHotkeyModifier[i], g_HKData[i].DefaultModifier);
 		}
 
@@ -410,13 +401,10 @@ void SConfig::LoadSettings()
 		ini.Get("Core", "BBA_MAC",		&m_bba_mac);
 		ini.Get("Core", "TimeProfiling",&m_LocalCoreStartupParameter.bJITILTimeProfiling,		false);
 		ini.Get("Core", "OutputIR",		&m_LocalCoreStartupParameter.bJITILOutputIR,			false);
-		char sidevicenum[16];
 		for (int i = 0; i < 4; ++i)
 		{
-			sprintf(sidevicenum, "SIDevice%i", i);
-			ini.Get("Core", sidevicenum,	(u32*)&m_SIDevice[i], (i == 0) ? SIDEVICE_GC_CONTROLLER : SIDEVICE_NONE);
+			ini.Get("Core", StringFromFormat("SIDevice%i", i), (u32*)&m_SIDevice[i], (i == 0) ? SIDEVICE_GC_CONTROLLER : SIDEVICE_NONE);
 		}
-
 		ini.Get("Core", "WiiSDCard",		&m_WiiSDCard,									false);
 		ini.Get("Core", "WiiKeyboard",		&m_WiiKeyboard,									false);
 		ini.Get("Core", "WiimoteContinuousScanning", &m_WiimoteContinuousScanning,			false);
diff --git a/Source/Core/Core/CoreParameter.cpp b/Source/Core/Core/CoreParameter.cpp
index e7843fe..6bfaedb 100644
--- a/Source/Core/Core/CoreParameter.cpp
+++ b/Source/Core/Core/CoreParameter.cpp
@@ -134,7 +134,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2)
 				bootDrive)
 			{
 				m_BootType = BOOT_ISO;
-				DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(m_strFilename.c_str());
+				DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(m_strFilename);
 				if (pVolume == NULL)
 				{
 					if (bootDrive)
@@ -210,7 +210,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2)
 				bNTSC = true;
 				m_BootType = BOOT_DFF;
 
-				FifoDataFile *ddfFile = FifoDataFile::Load(m_strFilename.c_str(), true);
+				FifoDataFile *ddfFile = FifoDataFile::Load(m_strFilename, true);
 
 				if (ddfFile)
 				{
@@ -220,7 +220,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2)
 			}
 			else if (DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid())
 			{
-				const DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(m_strFilename.c_str());
+				const DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(m_strFilename);
 				const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename);
 
 				if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == NULL)
diff --git a/Source/Core/Core/DSP/DSPCodeUtil.cpp b/Source/Core/Core/DSP/DSPCodeUtil.cpp
index afaaa7d..53e47b7 100644
--- a/Source/Core/Core/DSP/DSPCodeUtil.cpp
+++ b/Source/Core/Core/DSP/DSPCodeUtil.cpp
@@ -110,8 +110,6 @@ void CodeToHeader(const std::vector<u16> &code, std::string _filename,
 	// Pad with nops to 32byte boundary
 	while (code_padded.size() & 0x7f)
 		code_padded.push_back(0);
-
-	char buffer[1024];
 	header.clear();
 	header.reserve(code_padded.size() * 4);
 	header.append("#define NUM_UCODES 1\n\n");
@@ -125,8 +123,7 @@ void CodeToHeader(const std::vector<u16> &code, std::string _filename,
 	{
 		if (j && ((j & 15) == 0))
 			header.append("\n\t\t");
-		sprintf(buffer, "0x%04x, ", code_padded[j]);
-		header.append(buffer);
+		header.append(StringFromFormat("0x%04x, ", code_padded[j]));
 	}
 	header.append("\n\t},\n");
 
@@ -137,7 +134,6 @@ void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>
 				   u32 numCodes, const char *name, std::string &header)
 {
 	std::vector<std::vector<u16> > codes_padded;
-	char buffer[1024];
 	u32 reserveSize = 0;
 	for(u32 i = 0; i < numCodes; i++)
 	{
@@ -148,20 +144,16 @@ void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>
 
 		reserveSize += (u32)codes_padded.at(i).size();
 	}
-
-
 	header.clear();
 	header.reserve(reserveSize * 4);
-	sprintf(buffer, "#define NUM_UCODES %u\n\n", numCodes);
-	header.append(buffer);
+	header.append(StringFromFormat("#define NUM_UCODES %u\n\n", numCodes));
 	header.append("const char* UCODE_NAMES[NUM_UCODES] = {\n");
 	for (u32 i = 0; i < numCodes; i++)
 	{
 		std::string filename;
 		if (! SplitPath(filenames->at(i), NULL, &filename, NULL))
 			filename = filenames->at(i);
-		sprintf(buffer, "\t\"%s\",\n", filename.c_str());
-		header.append(buffer);
+		header.append(StringFromFormat("\t\"%s\",\n", filename.c_str()));
 	}
 	header.append("};\n\n");
 	header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
@@ -176,8 +168,7 @@ void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>
 		{
 			if (j && ((j & 15) == 0))
 				header.append("\n\t\t");
-			sprintf(buffer, "0x%04x, ", codes_padded.at(i).at(j));
-			header.append(buffer);
+			header.append(StringFromFormat("0x%04x, ", codes_padded.at(i).at(j)));
 		}
 		header.append("\n\t},\n");
 	}
diff --git a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp
index d4f1a40..3aa9294 100644
--- a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp
+++ b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp
@@ -151,9 +151,7 @@ void PrintDataBuffer(LogTypes::LOG_TYPE type, u8* _pData, size_t _Size, const ch
 		std::string Temp;
 		for (int i = 0; i < 16; i++)
 		{
-			char Buffer[128];
-			sprintf(Buffer, "%02x ", _pData[j++]);
-			Temp.append(Buffer);
+			Temp.append(StringFromFormat("%02x ", _pData[j++]));
 
 			if (j >= _Size)
 				break;
diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp
index dea6f7f..94724e3 100644
--- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp
+++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp
@@ -565,13 +565,13 @@ void LoadSettings()
 	{
 		std::string secname("Wiimote");
 		secname += (char)('1' + i);
-		IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
+		IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
 
 		sec.Get("Source", &g_wiimote_sources[i], i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU);
 	}
 
 	std::string secname("BalanceBoard");
-	IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
+	IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
 	sec.Get("Source", &g_wiimote_sources[WIIMOTE_BALANCE_BOARD], WIIMOTE_SRC_NONE);
 }
 
diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h
index 49249a2..9838716 100644
--- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h
+++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device.h
@@ -192,9 +192,7 @@ protected:
 			std::string Temp;
 			for (u32 j = 0; j < InBufferSize; j++)
 			{
-				char Buffer[128];
-				sprintf(Buffer, "%02x ", Memory::Read_U8(InBuffer+j));
-				Temp.append(Buffer);
+				Temp += StringFromFormat("%02x ", Memory::Read_U8(InBuffer+j));
 			}
 
 			GENERIC_LOG(LogType, LogTypes::LDEBUG, "    Buffer: %s", Temp.c_str());
diff --git a/Source/Core/Core/PatchEngine.cpp b/Source/Core/Core/PatchEngine.cpp
index f4386ad..8b07bf1 100644
--- a/Source/Core/Core/PatchEngine.cpp
+++ b/Source/Core/Core/PatchEngine.cpp
@@ -53,7 +53,7 @@ void LoadPatchSection(const char *section, std::vector<Patch> &patches,
 	std::string enabledSectionName = std::string(section) + "_Enabled";
 	std::vector<std::string> enabledLines;
 	std::set<std::string> enabledNames;
-	localIni.GetLines(enabledSectionName.c_str(), enabledLines);
+	localIni.GetLines(enabledSectionName, enabledLines);
 	for (auto& line : enabledLines)
 	{
 		if (line.size() != 0 && line[0] == '$')
@@ -140,7 +140,7 @@ static void LoadSpeedhacks(const char *section, std::map<u32, int> &hacks, IniFi
 	{
 		std::string key = *iter;
 		std::string value;
-		ini.Get(section, key.c_str(), &value, "BOGUS");
+		ini.Get(section, key, &value, "BOGUS");
 		if (value != "BOGUS")
 		{
 			u32 address;
diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp
index 325e200..f2d9746 100644
--- a/Source/Core/DiscIO/VolumeGC.cpp
+++ b/Source/Core/DiscIO/VolumeGC.cpp
@@ -54,9 +54,7 @@ std::string CVolumeGC::GetUniqueID() const
 
 std::string CVolumeGC::GetRevisionSpecificUniqueID() const
 {
-	char rev[16];
-	sprintf(rev, "r%d", GetRevision());
-	return GetUniqueID() + rev;
+	return GetUniqueID() + StringFromFormat("r%d", GetRevision());
 }
 
 IVolume::ECountry CVolumeGC::GetCountry() const
diff --git a/Source/Core/DolphinWX/Android/ButtonManager.cpp b/Source/Core/DolphinWX/Android/ButtonManager.cpp
index f451d64..5c71a71 100644
--- a/Source/Core/DolphinWX/Android/ButtonManager.cpp
+++ b/Source/Core/DolphinWX/Android/ButtonManager.cpp
@@ -101,7 +101,7 @@ namespace ButtonManager
 				bool hasbind = false;
 				char modifier = 0;
 				std::string value;
-				ini.Get("Android", config.str().c_str(), &value, "None");
+				ini.Get("Android", config.str(), &value, "None");
 				if (value == "None")
 					continue;
 				if (std::string::npos != value.find("Axis"))
diff --git a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
index 3582866..4f8f712 100644
--- a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
+++ b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
@@ -82,7 +82,7 @@ void CCodeWindow::Load()
 		? Parent->Perspectives[Parent->ActivePerspective].Name : "Perspective 1");
 
 	for (int i = 0; i <= IDM_CODEWINDOW - IDM_LOGWINDOW; i++)
-		ini.Get(_Section.c_str(), SettingName[i], &iNbAffiliation[i], 0);
+		ini.Get(_Section, SettingName[i], &iNbAffiliation[i], 0);
 
 	// Get floating setting
 	for (int i = 0; i <= IDM_CODEWINDOW - IDM_LOGWINDOW; i++)
@@ -121,7 +121,7 @@ void CCodeWindow::Save()
 	// Save notebook affiliations
 	std::string _Section = "P - " + Parent->Perspectives[Parent->ActivePerspective].Name;
 	for (int i = 0; i <= IDM_CODEWINDOW - IDM_LOGWINDOW; i++)
-		ini.Set(_Section.c_str(), SettingName[i], iNbAffiliation[i]);
+		ini.Set(_Section, SettingName[i], iNbAffiliation[i]);
 
 	// Save floating setting
 	for (int i = IDM_LOGWINDOW_PARENT; i <= IDM_CODEWINDOW_PARENT; i++)
diff --git a/Source/Core/DolphinWX/FrameAui.cpp b/Source/Core/DolphinWX/FrameAui.cpp
index 2333541..06778f6 100644
--- a/Source/Core/DolphinWX/FrameAui.cpp
+++ b/Source/Core/DolphinWX/FrameAui.cpp
@@ -917,13 +917,13 @@ void CFrame::LoadIniPerspectives()
 			continue;
 
 		_Section = StringFromFormat("P - %s", Tmp.Name.c_str());
-		ini.Get(_Section.c_str(), "Perspective", &_Perspective,
+		ini.Get(_Section, "Perspective", &_Perspective,
 				"layout2|"
 				"name=Pane 0;caption=Pane 0;state=768;dir=5;prop=100000;|"
 				"name=Pane 1;caption=Pane 1;state=31458108;dir=4;prop=100000;|"
 				"dock_size(5,0,0)=22|dock_size(4,0,0)=333|");
-		ini.Get(_Section.c_str(), "Width", &_Widths, "70,25");
-		ini.Get(_Section.c_str(), "Height", &_Heights, "80,80");
+		ini.Get(_Section, "Width", &_Widths, "70,25");
+		ini.Get(_Section, "Height", &_Heights, "80,80");
 
 		Tmp.Perspective = StrToWxStr(_Perspective);
 
@@ -988,14 +988,14 @@ void CFrame::SaveIniPerspectives()
 		STmp += Perspective.Name + ",";
 	}
 	STmp = STmp.substr(0, STmp.length()-1);
-	ini.Set("Perspectives", "Perspectives", STmp.c_str());
+	ini.Set("Perspectives", "Perspectives", STmp);
 	ini.Set("Perspectives", "Active", ActivePerspective);
 
 	// Save the perspectives
 	for (auto& Perspective : Perspectives)
 	{
 		std::string _Section = "P - " + Perspective.Name;
-		ini.Set(_Section.c_str(), "Perspective", WxStrToStr(Perspective.Perspective));
+		ini.Set(_Section, "Perspective", WxStrToStr(Perspective.Perspective));
 
 		std::string SWidth = "", SHeight = "";
 		for (u32 j = 0; j < Perspective.Width.size(); j++)
@@ -1007,8 +1007,8 @@ void CFrame::SaveIniPerspectives()
 		SWidth = SWidth.substr(0, SWidth.length()-1);
 		SHeight = SHeight.substr(0, SHeight.length()-1);
 
-		ini.Set(_Section.c_str(), "Width", SWidth.c_str());
-		ini.Set(_Section.c_str(), "Height", SHeight.c_str());
+		ini.Set(_Section, "Width", SWidth);
+		ini.Set(_Section, "Height", SHeight);
 	}
 
 	ini.Save(File::GetUserPath(F_DEBUGGERCONFIG_IDX));
diff --git a/Source/Core/DolphinWX/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/WiimoteConfigDiag.cpp
index 5e145ec..0dff321 100644
--- a/Source/Core/DolphinWX/WiimoteConfigDiag.cpp
+++ b/Source/Core/DolphinWX/WiimoteConfigDiag.cpp
@@ -252,13 +252,13 @@ void WiimoteConfigDiag::Save(wxCommandEvent& event)
 	{
 		std::string secname("Wiimote");
 		secname += (char)('1' + i);
-		IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
+		IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
 
 		sec.Set("Source", (int)g_wiimote_sources[i]);
 	}
 
 	std::string secname("BalanceBoard");
-	IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
+	IniFile::Section& sec = *inifile.GetOrCreateSection(secname);
 	sec.Set("Source", (int)g_wiimote_sources[WIIMOTE_BALANCE_BOARD]);
 
 	inifile.Save(ini_filename);
diff --git a/Source/Core/InputCommon/InputConfig.cpp b/Source/Core/InputCommon/InputConfig.cpp
index 41f18c8..b07d5c6 100644
--- a/Source/Core/InputCommon/InputConfig.cpp
+++ b/Source/Core/InputCommon/InputConfig.cpp
@@ -40,15 +40,17 @@ bool InputPlugin::LoadConfig(bool isGC)
 		game_ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() + ".ini", true);
 		for (int i = 0; i < 4; i++)
 		{
-			if (game_ini.Exists("Controls", (type + "Profile" + num[i]).c_str()))
+			if (game_ini.Exists("Controls", (type + "Profile" + num[i])))
 			{
-				game_ini.Get("Controls", (type + "Profile" + num[i]).c_str(), &profile[i]);
-				if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile[i] + ".ini"))
-					useProfile[i] = true;
-				else
+				if (game_ini.Get("Controls", (type + "Profile" + num[i]), &profile[i]))
 				{
-					// TODO: Having a PanicAlert for this is dumb.
-					PanicAlertT("Selected controller profile does not exist");
+					if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile[i] + ".ini"))
+						useProfile[i] = true;
+					else
+					{
+						// TODO: Having a PanicAlert for this is dumb.
+						PanicAlertT("Selected controller profile does not exist");
+					}
 				}
 			}
 		}
@@ -68,7 +70,7 @@ bool InputPlugin::LoadConfig(bool isGC)
 			}
 			else
 			{
-				pad->LoadConfig(inifile.GetOrCreateSection(pad->GetName().c_str()));
+				pad->LoadConfig(inifile.GetOrCreateSection(pad->GetName()));
 			}
 
 			// Update refs
@@ -95,7 +97,7 @@ void InputPlugin::SaveConfig()
 	inifile.Load(ini_filename);
 
 	for (ControllerEmu* pad : controllers)
-		pad->SaveConfig(inifile.GetOrCreateSection(pad->GetName().c_str()));
+		pad->SaveConfig(inifile.GetOrCreateSection(pad->GetName()));
 
 	inifile.Save(ini_filename);
 }
diff --git a/Source/Core/InputCommon/UDPWrapper.cpp b/Source/Core/InputCommon/UDPWrapper.cpp
index 7fc77c4..5d9d203 100644
--- a/Source/Core/InputCommon/UDPWrapper.cpp
+++ b/Source/Core/InputCommon/UDPWrapper.cpp
@@ -4,12 +4,12 @@
 #include <stdlib.h>
 #include <string.h>
 
-const char* DefaultPort(const int index)
+const std::string DefaultPort(const int index)
 {
 	static std::string s;
 	s = "443";
 	s += (char)('2' + index);
-	return s.c_str();
+	return s;
 }
 
 UDPWrapper::UDPWrapper(int indx, const char* const _name) :
@@ -29,13 +29,13 @@ void UDPWrapper::LoadConfig(IniFile::Section *sec, const std::string& defdev, co
 	std::string group( base + name ); group += "/";
 
 	int _updAccel,_updIR,_updButt,_udpEn,_updNun,_updNunAccel;
-	sec->Get((group + "Enable").c_str(),&_udpEn, 0);
-	sec->Get((group + "Port").c_str(), &port, DefaultPort(index));
-	sec->Get((group + "Update_Accel").c_str(), &_updAccel, 1);
-	sec->Get((group + "Update_IR").c_str(), &_updIR, 1);
-	sec->Get((group + "Update_Butt").c_str(), &_updButt, 1);
-	sec->Get((group + "Update_Nunchuk").c_str(), &_updNun, 1);
-	sec->Get((group + "Update_NunchukAccel").c_str(), &_updNunAccel, 0);
+	sec->Get((group + "Enable"),&_udpEn, 0);
+	sec->Get((group + "Port"), &port, DefaultPort(index));
+	sec->Get((group + "Update_Accel"), &_updAccel, 1);
+	sec->Get((group + "Update_IR"), &_updIR, 1);
+	sec->Get((group + "Update_Butt"), &_updButt, 1);
+	sec->Get((group + "Update_Nunchuk"), &_updNun, 1);
+	sec->Get((group + "Update_NunchukAccel"), &_updNunAccel, 0);
 
 	udpEn=(_udpEn>0);
 	updAccel=(_updAccel>0);
@@ -52,13 +52,13 @@ void UDPWrapper::SaveConfig(IniFile::Section *sec, const std::string& defdev, co
 {
 	ControlGroup::SaveConfig(sec,defdev,base);
 	std::string group( base + name ); group += "/";
-	sec->Set((group + "Enable").c_str(), (int)udpEn, 0);
-	sec->Set((group + "Port").c_str(), port, DefaultPort(index));
-	sec->Set((group + "Update_Accel").c_str(), (int)updAccel, 1);
-	sec->Set((group + "Update_IR").c_str(), (int)updIR, 1);
-	sec->Set((group + "Update_Butt").c_str(), (int)updButt, 1);
-	sec->Set((group + "Update_Nunchuk").c_str(), (int)updNun, 1);
-	sec->Set((group + "Update_NunchukAccel").c_str(), (int)updNunAccel, 0);
+	sec->Set((group + "Enable"), (int)udpEn, 0);
+	sec->Set((group + "Port"), port, DefaultPort(index));
+	sec->Set((group + "Update_Accel"), (int)updAccel, 1);
+	sec->Set((group + "Update_IR"), (int)updIR, 1);
+	sec->Set((group + "Update_Butt"), (int)updButt, 1);
+	sec->Set((group + "Update_Nunchuk"), (int)updNun, 1);
+	sec->Set((group + "Update_NunchukAccel"), (int)updNunAccel, 0);
 }
 
 
diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp
index 772bb1f..d3806ae 100644
--- a/Source/Core/VideoCommon/VertexLoader.cpp
+++ b/Source/Core/VideoCommon/VertexLoader.cpp
@@ -600,9 +600,10 @@ void VertexLoader::CompileVertexTranslator()
 
 		if (pFunc == 0)
 		{
-			char temp[256];
-			sprintf(temp,"%i %i %i %i", m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements, m_VtxAttr.NormalIndex3);
-			Host_SysMessage("VertexLoader_Normal::GetFunction returned zero!");
+			Host_SysMessage(
+				StringFromFormat("VertexLoader_Normal::GetFunction(%i %i %i %i) returned zero!", 
+				m_VtxDesc.Normal, m_VtxAttr.NormalFormat, 
+				m_VtxAttr.NormalElements, m_VtxAttr.NormalIndex3).c_str());
 		}
 		WriteCall(pFunc);