From 06e640532aa093902e81f09aa18de1b084fcc5ce Mon Sep 17 00:00:00 2001
From: NeoBrainX <NeoBrainX@gmail.com>
Date: Sat, 27 Aug 2011 20:42:11 +0200
Subject: [PATCH] Various changes which improve FreeBSD support. Patches by
 martymac, all credits go to him ;)

---
 CMakeLists.txt                          |  2 +-
 Source/Core/Common/Src/CPUDetect.cpp    |  9 +++++
 Source/Core/Common/Src/CommonFuncs.h    |  6 ++++
 Source/Core/Common/Src/MemoryUtil.cpp   | 48 +++++++++++++++++++++----
 Source/Core/Core/Src/MemTools.cpp       |  2 +-
 Source/Core/DolphinWX/CMakeLists.txt    |  3 ++
 Source/Core/VideoCommon/Src/AVIDump.cpp |  4 +++
 7 files changed, 66 insertions(+), 8 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d0d6a3ae8f..e870304dc4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -463,7 +463,7 @@ if(GETTEXT_FOUND AND NOT DISABLE_WX)
 	file(GLOB LINGUAS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} Languages/po/*.po) 
 	GETTEXT_CREATE_TRANSLATIONS(Languages/po/dolphin-emu.pot ALL ${LINGUAS})
 endif()
-if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+if((NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD"))
 	install(FILES Data/license.txt DESTINATION ${datadir})
 endif()
 
diff --git a/Source/Core/Common/Src/CPUDetect.cpp b/Source/Core/Common/Src/CPUDetect.cpp
index 810c5d2a59..7c231b0a69 100644
--- a/Source/Core/Common/Src/CPUDetect.cpp
+++ b/Source/Core/Common/Src/CPUDetect.cpp
@@ -32,6 +32,10 @@
 //#include <config/i386/cpuid.h>
 #include <xmmintrin.h>
 
+#if defined __FreeBSD__
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#else
 static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
 						    unsigned int *ecx, unsigned int *edx)
 {
@@ -65,15 +69,20 @@ static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
 		);
 #endif
 }
+#endif /* defined __FreeBSD__ */
 
 static void __cpuid(int info[4], int x)
 {
+#if defined __FreeBSD__
+    do_cpuid((unsigned int)x, (unsigned int*)info);
+#else
 	unsigned int eax = x, ebx = 0, ecx = 0, edx = 0;
 	do_cpuid(&eax, &ebx, &ecx, &edx);
 	info[0] = eax;
 	info[1] = ebx;
 	info[2] = ecx;
 	info[3] = edx;
+#endif
 }
 
 #endif
diff --git a/Source/Core/Common/Src/CommonFuncs.h b/Source/Core/Common/Src/CommonFuncs.h
index 7dd156f42e..c79137780d 100644
--- a/Source/Core/Common/Src/CommonFuncs.h
+++ b/Source/Core/Common/Src/CommonFuncs.h
@@ -45,6 +45,8 @@ _mm_shuffle_epi8(__m128i a, __m128i mask)
 #include <errno.h>
 #ifdef __linux__
 #include <byteswap.h>
+#elif defined __FreeBSD__
+#include <sys/endian.h>
 #endif
 
 // go to debugger mode
@@ -137,6 +139,10 @@ inline __attribute__((always_inline)) u32 swap32(u32 _data)
 	{return __builtin_bswap32(_data);}
 inline __attribute__((always_inline)) u64 swap64(u64 _data)
 	{return __builtin_bswap64(_data);}
+#elif __FreeBSD__
+inline u16 swap16(u16 _data) {return bswap16(_data);}
+inline u32 swap32(u32 _data) {return bswap32(_data);}
+inline u64 swap64(u64 _data) {return bswap64(_data);}
 #else
 // Slow generic implementation.
 inline u16 swap16(u16 data) {return (data >> 8) | (data << 8);}
diff --git a/Source/Core/Common/Src/MemoryUtil.cpp b/Source/Core/Common/Src/MemoryUtil.cpp
index bc65f856f4..65c70e0c5e 100644
--- a/Source/Core/Common/Src/MemoryUtil.cpp
+++ b/Source/Core/Common/Src/MemoryUtil.cpp
@@ -27,28 +27,64 @@
 #include <stdio.h>
 #endif
 
+#if !defined(MAP_32BIT)
+#include <unistd.h>
+#define PAGE_MASK     (getpagesize() - 1)
+#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
+#endif
+
 // This is purposely not a full wrapper for virtualalloc/mmap, but it
 // provides exactly the primitive operations that Dolphin needs.
 
 void* AllocateExecutableMemory(size_t size, bool low)
 {
-#ifdef _WIN32
+	static char *map_hint = 0;
+#if defined(__x86_64__) && !defined(MAP_32BIT)
+	if (low && (!map_hint))
+		map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
+#endif
+
+#if defined(_WIN32)
 	void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 #else
-	void* ptr = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+	void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
 		MAP_ANON | MAP_PRIVATE
-#if defined __linux__ && defined __x86_64__
+#if defined(__x86_64__)
+#if defined(MAP_32BIT)
 		| (low ? MAP_32BIT : 0)
-#endif
+#else
+		| (low ? MAP_FIXED : 0)
+#endif /* defined(MAP_32BIT) */
+#endif /* defined(__x86_64__) */
 		, -1, 0);
-#endif
+#endif /* defined(_WIN32) */
 
 	// printf("Mapped executable memory at %p (size %ld)\n", ptr,
 	//	(unsigned long)size);
 	
+#if defined(__FreeBSD__)
+	if (ptr == MAP_FAILED)
+	{
+		ptr = NULL;
+#else
 	if (ptr == NULL)
+	{
+#endif	
 		PanicAlert("Failed to allocate executable memory");
-#ifdef _M_X64
+	}
+#if defined(__x86_64__) && !defined(MAP_32BIT)
+	else
+	{
+		if (low)
+		{
+			map_hint += size;
+			map_hint = (char*)round_page(map_hint); /* round up to the next page */
+			// printf("Next map will (hopefully) be at %p\n", map_hint);
+		}
+	}
+#endif
+
+#if defined(_M_X64)
 	if ((u64)ptr >= 0x80000000 && low == true)
 		PanicAlert("Executable memory ended up above 2GB!");
 #endif
diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp
index 469ae32684..bb6fef6439 100644
--- a/Source/Core/Core/Src/MemTools.cpp
+++ b/Source/Core/Core/Src/MemTools.cpp
@@ -160,7 +160,7 @@ void InstallExceptionHandler()
 
 #else  // _WIN32
 
-#if defined __APPLE__ || defined __linux__ || defined _WIN32
+#if defined __APPLE__ || defined __linux__ || defined __FreeBSD__ || defined _WIN32
 #ifndef _WIN32
 #include <execinfo.h>
 #endif
diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt
index 7890c9fe96..5fc433009f 100644
--- a/Source/Core/DolphinWX/CMakeLists.txt
+++ b/Source/Core/DolphinWX/CMakeLists.txt
@@ -9,6 +9,9 @@ set(LIBS	core
 			sfml-network
 			SDL
 			GL
+			avcodec
+			avformat
+			swscale
 			${XRANDR_LIBRARIES}
 			${X11_LIBRARIES})
 
diff --git a/Source/Core/VideoCommon/Src/AVIDump.cpp b/Source/Core/VideoCommon/Src/AVIDump.cpp
index cfd34e5cdb..a5a6098489 100644
--- a/Source/Core/VideoCommon/Src/AVIDump.cpp
+++ b/Source/Core/VideoCommon/Src/AVIDump.cpp
@@ -15,6 +15,10 @@
 // Official SVN repository and contact information can be found at
 // http://code.google.com/p/dolphin-emu/
 
+#if defined(__FreeBSD__)
+#define __STDC_CONSTANT_MACROS 1
+#endif 
+
 #include "AVIDump.h"
 #include "HW/VideoInterface.h" //for TargetRefreshRate
 #include "VideoConfig.h"