Merge pull request #978 from juhalaukkanen/apple_osx_master_merge

OSX 32bit build
This commit is contained in:
Gregory Hainaut 2016-01-08 20:09:37 +01:00
commit 74db92bee4
45 changed files with 1034 additions and 77 deletions

View File

@ -26,6 +26,21 @@ CoverityBuild=0
cppcheck=0 cppcheck=0
clangTidy=0 clangTidy=0
if [[ $(uname -s) == 'Darwin' ]]; then
ncpu=$(sysctl -n hw.ncpu)
release=$(uname -r)
if [[ ${release:0:2} -lt 13 ]]; then
echo "This old OSX version is not supported! Build will fail."
toolfile=cmake/darwin-compiler-i386-clang.cmake
else
echo "Using Mavericks build with C++11 support."
toolfile=cmake/darwin13-compiler-i386-clang.cmake
fi
else
ncpu=$(grep -w -c processor /proc/cpuinfo)
toolfile=cmake/linux-compiler-i386-multilib.cmake
fi
for ARG in "$@"; do for ARG in "$@"; do
case "$ARG" in case "$ARG" in
--clean ) cleanBuild=1 ;; --clean ) cleanBuild=1 ;;
@ -44,7 +59,7 @@ for ARG in "$@"; do
--wx28 ) flags+=(-DWX28_API=TRUE) ;; --wx28 ) flags+=(-DWX28_API=TRUE) ;;
--gtk3 ) flags+=(-DGTK3_API=TRUE) ;; --gtk3 ) flags+=(-DGTK3_API=TRUE) ;;
--no-simd ) flags+=(-DDISABLE_ADVANCE_SIMD=TRUE) ;; --no-simd ) flags+=(-DDISABLE_ADVANCE_SIMD=TRUE) ;;
--cross-multilib ) flags+=(-DCMAKE_TOOLCHAIN_FILE=cmake/linux-compiler-i386-multilib.cmake); useCross=1; ;; --cross-multilib ) flags+=(-DCMAKE_TOOLCHAIN_FILE=$toolfile); useCross=1; ;;
--no-cross-multilib ) useCross=0; ;; --no-cross-multilib ) useCross=0; ;;
--coverity ) CoverityBuild=1; cleanBuild=1; ;; --coverity ) CoverityBuild=1; cleanBuild=1; ;;
-D* ) flags+=($ARG) ;; -D* ) flags+=($ARG) ;;
@ -98,7 +113,7 @@ fi
if [[ "$useCross" -eq 2 ]] && [[ "$(getconf LONG_BIT 2> /dev/null)" != 32 ]]; then if [[ "$useCross" -eq 2 ]] && [[ "$(getconf LONG_BIT 2> /dev/null)" != 32 ]]; then
echo "Forcing cross compilation." echo "Forcing cross compilation."
flags+=(-DCMAKE_TOOLCHAIN_FILE=cmake/linux-compiler-i386-multilib.cmake) flags+=(-DCMAKE_TOOLCHAIN_FILE=$toolfile)
elif [[ "$useCross" -ne 1 ]]; then elif [[ "$useCross" -ne 1 ]]; then
useCross=0 useCross=0
fi fi
@ -125,11 +140,7 @@ else
cmake "${flags[@]}" $root 2>&1 | tee -a $log cmake "${flags[@]}" $root 2>&1 | tee -a $log
fi fi
if [[ $(uname -s) == 'Darwin' ]]; then
ncpu=$(sysctl -n hw.ncpu)
else
ncpu=$(grep -w -c processor /proc/cpuinfo)
fi
############################################################ ############################################################
# CPP check build # CPP check build
@ -151,7 +162,7 @@ if [[ "$cppcheck" -eq 1 ]] && [[ -x `which cppcheck` ]]; then
log=cpp_check__${flat_d}.log log=cpp_check__${flat_d}.log
rm -f $log rm -f $log
cppcheck $check -j $ncpu --platform=unix32 $define $root/$d |& tee $log cppcheck $check -j $ncpu --platform=unix32 $define $root/$d 2>&1 | tee $log
# Create a small summary (warning it might miss some issues) # Create a small summary (warning it might miss some issues)
fgrep -e "(warning)" -e "(error)" -e "(style)" -e "(performance)" -e "(portability)" $log >> $summary fgrep -e "(warning)" -e "(error)" -e "(style)" -e "(performance)" -e "(portability)" $log >> $summary
done done

View File

@ -250,7 +250,9 @@ set(AGGRESSIVE_WARNING "-Wstrict-aliasing -Wstrict-overflow=2 ")
if (USE_CLANG) if (USE_CLANG)
# -Wno-deprecated-register: glib issue... # -Wno-deprecated-register: glib issue...
set(DEFAULT_WARNINGS "${DEFAULT_WARNINGS} -Wno-deprecated-register") set(DEFAULT_WARNINGS "${DEFAULT_WARNINGS} -Wno-deprecated-register")
set(COMMON_FLAG "${COMMON_FLAG} -no-integrated-as") if (NOT APPLE)
set(COMMON_FLAG "${COMMON_FLAG} -no-integrated-as")
endif()
set(DBG "-g") set(DBG "-g")
else() else()
set(DBG "-ggdb") set(DBG "-ggdb")

View File

@ -7,10 +7,16 @@ if(LIBC_LIBRARIES)
set(LIBC_FIND_QUIETLY TRUE) set(LIBC_FIND_QUIETLY TRUE)
endif(LIBC_LIBRARIES) endif(LIBC_LIBRARIES)
find_library(librt NAMES rt)
find_library(libdl NAMES dl) find_library(libdl NAMES dl)
find_library(libm NAMES m) find_library(libm NAMES m)
set(LIBC_LIBRARIES ${librt} ${libdl} ${libm})
# OSX doesn't have rt. On Linux timer and aio dependency.
if(APPLE)
set(LIBC_LIBRARIES ${librt} ${libdl} ${libm})
else()
find_library(librt NAMES rt)
set(LIBC_LIBRARIES ${librt} ${libdl} ${libm})
endif()
# handle the QUIETLY and REQUIRED arguments and set LIBC_FOUND to TRUE if # handle the QUIETLY and REQUIRED arguments and set LIBC_FOUND to TRUE if
# all listed variables are TRUE # all listed variables are TRUE

View File

@ -31,9 +31,9 @@ else()
list(APPEND wxWidgets_CONFIG_OPTIONS --version=3.0) list(APPEND wxWidgets_CONFIG_OPTIONS --version=3.0)
endif() endif()
if(GTK3_API) if(GTK3_API AND NOT APPLE)
list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk3) list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk3)
else() elseif(NOT APPLE)
list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk2) list(APPEND wxWidgets_CONFIG_OPTIONS --toolkit=gtk2)
endif() endif()

View File

@ -31,6 +31,8 @@ endmacro(print_dep)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
if (GTK2_FOUND OR GTK3_FOUND) if (GTK2_FOUND OR GTK3_FOUND)
set(GTKn_FOUND TRUE) set(GTKn_FOUND TRUE)
elseif(APPLE) # Not we have but that we don't change all if(gtkn) entries
set(GTKn_FOUND TRUE)
else() else()
set(GTKn_FOUND FALSE) set(GTKn_FOUND FALSE)
endif() endif()
@ -71,8 +73,8 @@ else()
set(pcsx2_core FALSE) set(pcsx2_core FALSE)
print_dep("Skip build of pcsx2 core: miss some dependencies" "${msg_dep_pcsx2}") print_dep("Skip build of pcsx2 core: miss some dependencies" "${msg_dep_pcsx2}")
endif() endif()
# Linux need also gtk2 # Linux, BSD, use gtk2, but not OSX
if(UNIX AND pcsx2_core AND NOT GTKn_FOUND) if(UNIX AND pcsx2_core AND NOT GTKn_FOUND AND NOT APPLE)
set(pcsx2_core FALSE) set(pcsx2_core FALSE)
print_dep("Skip build of pcsx2 core: miss some dependencies" "${msg_dep_pcsx2}") print_dep("Skip build of pcsx2 core: miss some dependencies" "${msg_dep_pcsx2}")
endif() endif()
@ -253,7 +255,8 @@ endif()
# -SDL # -SDL
# -common_libs # -common_libs
#--------------------------------------- #---------------------------------------
if(ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND SDLn_FOUND AND common_libs) if((APPLE AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND SDLn_FOUND AND common_libs)
OR (LINUX AND ALSA_FOUND AND PORTAUDIO_FOUND AND SOUNDTOUCH_FOUND AND SDLn_FOUND AND common_libs))
set(spu2-x TRUE) set(spu2-x TRUE)
elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/plugins/spu2-x") elseif(NOT EXISTS "${CMAKE_SOURCE_DIR}/plugins/spu2-x")
set(spu2-x FALSE) set(spu2-x FALSE)

View File

@ -0,0 +1,20 @@
# Tell cmake we are cross compiling and targeting darwin
#set(CMAKE_SYSTEM_NAME Darwin)
#set(CMAKE_SYSTEM_PROCESSOR i686)
# Use clang and target i686-apple-darwin13.0.0 (Mavericks)
set(CMAKE_C_COMPILER clang -m32)
#set(CMAKE_C_COMPILER_TARGET i686-apple-darwin13.0.0)
set(CMAKE_CXX_COMPILER clang++ -m32)
#set(CMAKE_CXX_COMPILER_TARGET i686-apple-darwin13.0.0)
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpmath=sse -msse2")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -msse2")
# If given a CMAKE_FIND_ROOT_PATH then
# FIND_PROGRAM ignores CMAKE_FIND_ROOT_PATH (probably can't run)
# FIND_{LIBRARY,INCLUDE,PACKAGE} only uses the files in CMAKE_FIND_ROOT_PATH.
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@ -20,17 +20,24 @@
#include <string> #include <string>
#include <cstdarg> #include <cstdarg>
#ifdef _MSC_VER #if defined(_MSC_VER)
#include <windows.h> #include <windows.h>
#include <windowsx.h> #include <windowsx.h>
#include <commctrl.h> #include <commctrl.h>
#define EXPORT_C_(type) extern "C" type CALLBACK #define EXPORT_C_(type) extern "C" type CALLBACK
#else
#elif defined(GTK_MAJOR_VERSION)
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <cstring> #include <cstring>
#define EXPORT_C_(type) extern "C" __attribute__((stdcall,externally_visible,visibility("default"))) type #define EXPORT_C_(type) extern "C" __attribute__((stdcall,externally_visible,visibility("default"))) type
#else
#define EXPORT_C_(type) extern "C" __attribute__((stdcall,externally_visible,visibility("default"))) type
#endif #endif
//#include "PS2Edefs.h" //#include "PS2Edefs.h"
@ -183,7 +190,7 @@ struct PluginConf
} }
}; };
#ifdef __linux__ #if defined(GTK_MAJOR_VERSION)
static void SysMessage(const char *fmt, ...) static void SysMessage(const char *fmt, ...)
{ {
@ -243,6 +250,48 @@ static void __forceinline PluginNullAbout(const char *aboutText)
#define ENTRY_POINT /* We don't need no stinkin' entry point! */ #define ENTRY_POINT /* We don't need no stinkin' entry point! */
#elif defined(__WXMAC__) || defined(__APPLE__)
static void SysMessage(const char *fmt, ...)
{
va_list list;
char msg[512];
va_start(list, fmt);
vsprintf(msg, fmt, list);
va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0;
// TODO OSX can we use WX MessageBox here or should Cocoa MessageBox used?
}
static void SysMessage(const wchar_t *fmt, ...)
{
va_list list;
wchar_t msg[512];
va_start(list, fmt);
//vsprintf(msg, fmt, list);
va_end(list);
// TODO OSX can we use WX MessageBox here or should Cocoa MessageBox used?
}
static void __forceinline PluginNullConfigure(std::string desc, int &log)
{
SysMessage("This space intentionally left blank.");
}
static void __forceinline PluginNullAbout(const char *aboutText)
{
SysMessage(aboutText);
}
#define ENTRY_POINT /* We don't need no stinkin' entry point! */ // TODO OSX WTF is this anyway?
#else #else
#define usleep(x) Sleep(x / 1000) #define usleep(x) Sleep(x / 1000)

View File

@ -23,6 +23,14 @@
#define __linux__ #define __linux__
#endif #endif
// make sure __POSIX__ is defined for all systems where we assume POSIX
// compliance
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__) || defined(__LINUX__)
# if !defined(__POSIX__)
# define __POSIX__ 1
# endif
#endif
#include "Pcsx2Types.h" #include "Pcsx2Types.h"
#ifdef _MSC_VER #ifdef _MSC_VER

View File

@ -15,7 +15,7 @@
#pragma once #pragma once
#ifdef __linux__ #if defined(__POSIX__)
# include "lnx_memzero.h" # include "lnx_memzero.h"
#else #else
# include "win_memzero.h" # include "win_memzero.h"

View File

@ -271,7 +271,7 @@ protected:
virtual void CommitBlocks( uptr page, uint blocks ); virtual void CommitBlocks( uptr page, uint blocks );
}; };
#ifdef __linux__ #ifdef __POSIX__
# define PCSX2_PAGEFAULT_PROTECT # define PCSX2_PAGEFAULT_PROTECT
# define PCSX2_PAGEFAULT_EXCEPT # define PCSX2_PAGEFAULT_EXCEPT

View File

@ -19,6 +19,10 @@
#include <errno.h> // EBUSY #include <errno.h> // EBUSY
#include <pthread.h> #include <pthread.h>
#ifdef __APPLE__
#include <mach/semaphore.h>
#endif
#include "Pcsx2Defs.h" #include "Pcsx2Defs.h"
#include "ScopedPtr.h" #include "ScopedPtr.h"
#include "TraceLog.h" #include "TraceLog.h"
@ -66,11 +70,7 @@ extern ConsoleLogSource_Threading pxConLog_Thread;
//#define PCSX2_THREAD_LOCAL 0 // uncomment this line to force-disable native TLS (useful for testing TlsVariable on windows/linux) //#define PCSX2_THREAD_LOCAL 0 // uncomment this line to force-disable native TLS (useful for testing TlsVariable on windows/linux)
#ifndef PCSX2_THREAD_LOCAL #ifndef PCSX2_THREAD_LOCAL
# ifdef __WXMAC__ # define PCSX2_THREAD_LOCAL 1
# define PCSX2_THREAD_LOCAL 0
# else
# define PCSX2_THREAD_LOCAL 1
# endif
#endif #endif
class wxTimeSpan; class wxTimeSpan;
@ -252,7 +252,12 @@ namespace Threading
class Semaphore class Semaphore
{ {
protected: protected:
#ifdef __APPLE__
semaphore_t m_sema;
int m_counter;
#else
sem_t m_sema; sem_t m_sema;
#endif
public: public:
Semaphore(); Semaphore();

View File

@ -44,6 +44,7 @@ endif(CMAKE_BUILD_TYPE STREQUAL Release)
# variable with all sources of this library # variable with all sources of this library
set(UtilitiesSources set(UtilitiesSources
VirtualMemory.cpp
AlignedMalloc.cpp AlignedMalloc.cpp
../../include/Utilities/FixedPointTypes.inl ../../include/Utilities/FixedPointTypes.inl
../../include/Utilities/EventSource.inl ../../include/Utilities/EventSource.inl
@ -57,8 +58,6 @@ set(UtilitiesSources
HashTools.cpp HashTools.cpp
IniInterface.cpp IniInterface.cpp
Linux/LnxHostSys.cpp Linux/LnxHostSys.cpp
Linux/LnxMisc.cpp
Linux/LnxThreads.cpp
Mutex.cpp Mutex.cpp
PathUtils.cpp PathUtils.cpp
PrecompiledHeader.cpp PrecompiledHeader.cpp
@ -68,12 +67,10 @@ set(UtilitiesSources
pxStreams.cpp pxStreams.cpp
pxTranslate.cpp pxTranslate.cpp
pxWindowTextWriter.cpp pxWindowTextWriter.cpp
Semaphore.cpp
StringHelpers.cpp StringHelpers.cpp
ThreadingDialogs.cpp ThreadingDialogs.cpp
ThreadTools.cpp ThreadTools.cpp
vssprintf.cpp vssprintf.cpp
VirtualMemory.cpp
wxAppWithHelpers.cpp wxAppWithHelpers.cpp
wxGuiTools.cpp wxGuiTools.cpp
wxHelpers.cpp wxHelpers.cpp
@ -112,7 +109,22 @@ set(UtilitiesHeaders
../../include/Utilities/wxAppWithHelpers.h ../../include/Utilities/wxAppWithHelpers.h
../../include/Utilities/wxBaseTools.h ../../include/Utilities/wxBaseTools.h
../../include/Utilities/wxGuiTools.h ../../include/Utilities/wxGuiTools.h
PrecompiledHeader.h) PrecompiledHeader.h
)
if(APPLE)
LIST(APPEND UtilitiesSources
Darwin/DarwinThreads.cpp
Darwin/DarwinMisc.cpp
Darwin/DarwinSemaphore.cpp
)
else()
LIST(APPEND UtilitiesSources
Linux/LnxThreads.cpp
Linux/LnxMisc.cpp
Semaphore.cpp
)
endif()
set(UtilitiesFinalSources set(UtilitiesFinalSources
${UtilitiesSources} ${UtilitiesSources}

View File

@ -32,7 +32,7 @@ static DeclareTls(ConsoleColors) conlog_Color( DefaultConsoleColor );
static wxString m_buffer; // used by ConsoleBuffer static wxString m_buffer; // used by ConsoleBuffer
static Mutex m_bufferlock; // used by ConsoleBuffer static Mutex m_bufferlock; // used by ConsoleBuffer
#ifdef __linux__ #ifdef __POSIX__
static FILE *stdout_fp = stdout; static FILE *stdout_fp = stdout;
void Console_SetStdout(FILE *fp) void Console_SetStdout(FILE *fp)

View File

@ -0,0 +1,150 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../PrecompiledHeader.h"
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach_time.h>
#define NELEM(x) \
((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
// Darwin (OSX) is a bit different from Linux when requesting properties of
// the OS because of its BSD/Mach heritage. Helpfully, most of this code
// should translate pretty well to other *BSD systems. (e.g.: the sysctl(3)
// interface).
//
// For an overview of all of Darwin's sysctls, check:
// https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/sysctl.3.html
// Return the total physical memory on the machine, in bytes. Returns 0 on
// failure (not supported by the operating system).
u64 GetPhysicalMemory()
{
static u64 mem = 0;
// fetch the total memory only once, as its an expensive system call and
// doesn't change during the course of the program. Thread-safety is
// ensured by atomic operations with full-barriers (usually compiled
// down to XCHG on x86).
if (__atomic_load_n(&mem, __ATOMIC_SEQ_CST) == 0) {
u64 getmem = 0;
size_t len = sizeof(getmem);
int mib[] = { CTL_HW, HW_MEMSIZE };
if (sysctl(mib, NELEM(mib), &getmem, &len, NULL, 0) < 0) {
perror("sysctl:");
}
__atomic_store_n(&mem, getmem, __ATOMIC_SEQ_CST);
}
return mem;
}
void InitCPUTicks()
{
}
// returns the performance-counter frequency: ticks per second (Hz)
//
// usage:
// u64 seconds_passed = GetCPUTicks() / GetTickFrequency();
// u64 millis_passed = (GetCPUTicks() * 1000) / GetTickFrequency();
//
// NOTE: multiply, subtract, ... your ticks before dividing by
// GetTickFrequency() to maintain good precision.
u64 GetTickFrequency()
{
static u64 freq = 0;
// by the time denom is not 0, the structure will have been fully
// updated and no more atomic accesses are necessary.
if (__atomic_load_n(&freq, __ATOMIC_SEQ_CST) == 0) {
mach_timebase_info_data_t info;
// mach_timebase_info() is a syscall, very slow, that's why we take
// pains to only do it once. On x86(-64), the result is guaranteed
// to be info.denom == info.numer == 1 (i.e.: the frequency is 1e9,
// which means GetCPUTicks is just nanoseconds).
if (mach_timebase_info(&info) != KERN_SUCCESS) {
abort();
}
// store the calculated value atomically
__atomic_store_n(&freq, (u64) 1e9 * (u64) info.denom / (u64) info.numer, __ATOMIC_SEQ_CST);
}
return freq;
}
// return the number of "ticks" since some arbitrary, fixed time in the
// past. On OSX x86(-64), this is actually the number of nanoseconds passed,
// because mach_timebase_info.numer == denom == 1. So "ticks" ==
// nanoseconds.
u64 GetCPUTicks()
{
return mach_absolute_time();
}
wxString GetOSVersionString()
{
wxString version;
static int initialized = 0;
// fetch the OS description only once (thread-safely)
if (__atomic_load_n(&initialized, __ATOMIC_SEQ_CST) == 0) {
char type[32] = {0};
char release[32] = {0};
char arch[32] = {0};
#define SYSCTL_GET(var, base, name) \
do { \
int mib[] = { base, name }; \
size_t len = sizeof(var); \
sysctl(mib, NELEM(mib), NULL, &len, NULL, 0); \
sysctl(mib, NELEM(mib), var, &len, NULL, 0); \
} while (0)
SYSCTL_GET(release, CTL_KERN, KERN_OSRELEASE);
SYSCTL_GET(type, CTL_KERN, KERN_OSTYPE);
SYSCTL_GET(arch, CTL_HW, HW_MACHINE);
#undef SYSCTL_KERN
// I know strcat is not good, but stpcpy is not universally
// available yet.
char buf[128] = {0};
strcat(buf, type);
strcat(buf, " ");
strcat(buf, release);
strcat(buf, " ");
strcat(buf, arch);
version = buf;
__atomic_store_n(&initialized, 1, __ATOMIC_SEQ_CST);
}
return version;
}
void ScreensaverAllow(bool allow)
{
// no-op
}

View File

@ -0,0 +1,243 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstdio>
#include <cassert> // assert
#include <pthread.h> // pthread_setcancelstate()
#include <sys/time.h> // gettimeofday()
#include <mach/mach.h>
#include <mach/task.h> // semaphore_create() and semaphore_destroy()
#include <mach/semaphore.h> // semaphore_*()
#include <mach/mach_error.h> // mach_error_string()
#include <mach/mach_time.h> // mach_absolute_time()
#include "PrecompiledHeader.h"
#include "Threading.h"
#include "ThreadingInternal.h"
#include "wxBaseTools.h"
#include "wxGuiTools.h"
// --------------------------------------------------------------------------------------
// Semaphore Implementation for Darwin/OSX
//
// Sadly, Darwin/OSX needs its own implementation of Semaphores instead of
// relying on phtreads, because OSX unnamed semaphore (the best kind)
// support is very poor.
//
// This implementation makes use of Mach primitives instead. These are also
// what Grand Central Dispatch (GCD) is based on, as far as I understand:
// http://newosxbook.com/articles/GCD.html.
//
// --------------------------------------------------------------------------------------
#define MACH_CHECK(mach_retval) \
do { \
kern_return_t _kr = (mach_retval); \
if (_kr != KERN_SUCCESS) { \
fprintf(stderr, "mach error: %s", mach_error_string(_kr)); \
assert(_kr == KERN_SUCCESS); \
} \
} while (0)
Threading::Semaphore::Semaphore()
{
// other platforms explicitly make a thread-private (unshared) semaphore
// here. But it seems Mach doesn't support that.
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
Threading::Semaphore::~Semaphore() throw()
{
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::Reset()
{
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema));
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *) &m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::Post()
{
MACH_CHECK(semaphore_signal(m_sema));
__atomic_add_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::Post(int multiple)
{
for (int i = 0; i < multiple; ++i) {
MACH_CHECK(semaphore_signal(m_sema));
}
__atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST);
}
void Threading::Semaphore::WaitWithoutYield()
{
pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead.");
MACH_CHECK(semaphore_wait(m_sema));
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
}
bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout)
{
// This method is the reason why there has to be a special Darwin
// implementation of Semaphore. Note that semaphore_timedwait() is prone
// to returning with KERN_ABORTED, which basically signifies that some
// signal has worken it up. The best official "documentation" for
// semaphore_timedwait() is the way it's used in Grand Central Dispatch,
// which is open-source.
// on x86 platforms, mach_absolute_time() returns nanoseconds
// TODO(aktau): on iOS a scale value from mach_timebase_info will be necessary
u64 const kOneThousand = 1000;
u64 const kOneBillion = kOneThousand * kOneThousand * kOneThousand;
u64 const delta = timeout.GetMilliseconds().GetValue() * (kOneThousand * kOneThousand);
mach_timespec_t ts;
kern_return_t kr = KERN_ABORTED;
for (u64 now = mach_absolute_time(), deadline = now + delta;
kr == KERN_ABORTED; now = mach_absolute_time()) {
if (now > deadline) {
// timed out by definition
return false;
}
u64 timeleft = deadline - now;
ts.tv_sec = timeleft / kOneBillion;
ts.tv_nsec = timeleft % kOneBillion;
// possible return values of semaphore_timedwait() (from XNU sources):
// internal kernel val -> return value
// THREAD_INTERRUPTED -> KERN_ABORTED
// THREAD_TIMED_OUT -> KERN_OPERATION_TIMED_OUT
// THREAD_AWAKENED -> KERN_SUCCESS
// THREAD_RESTART -> KERN_TERMINATED
// default -> KERN_FAILURE
kr = semaphore_timedwait(m_sema, ts);
}
if (kr == KERN_OPERATION_TIMED_OUT) {
return false;
}
// while it's entirely possible to have KERN_FAILURE here, we should
// probably assert so we can study and correct the actual error here
// (the thread dying while someone is wainting for it).
MACH_CHECK(kr);
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
return true;
}
// This is a wxApp-safe implementation of Wait, which makes sure and executes the App's
// pending messages *if* the Wait is performed on the Main/GUI thread. This ensures that
// user input continues to be handled and that windows continue to repaint. If the Wait is
// called from another thread, no message pumping is performed.
void Threading::Semaphore::Wait()
{
#if wxUSE_GUI
if(!wxThread::IsMain() || (wxTheApp == NULL)) {
WaitWithoutYield();
}
else if(_WaitGui_RecursionGuard( L"Semaphore::Wait" )) {
ScopedBusyCursor hourglass( Cursor_ReallyBusy );
WaitWithoutYield();
}
else {
while (!WaitWithoutYield(def_yieldgui_interval)) {
YieldToMain();
}
}
#else
WaitWithoutYield();
#endif
}
// This is a wxApp-safe implementation of WaitWithoutYield, which makes sure and executes the App's
// pending messages *if* the Wait is performed on the Main/GUI thread. This ensures that
// user input continues to be handled and that windows continue to repaint. If the Wait is
// called from another thread, no message pumping is performed.
//
// Returns:
// false if the wait timed out before the semaphore was signaled, or true if the signal was
// reached prior to timeout.
//
bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
{
#if wxUSE_GUI
if(!wxThread::IsMain() || (wxTheApp == NULL)) {
return WaitWithoutYield(timeout);
}
else if (_WaitGui_RecursionGuard( L"Semaphore::TimedWait")) {
ScopedBusyCursor hourglass(Cursor_ReallyBusy);
return WaitWithoutYield(timeout);
}
else {
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout));
do {
if (WaitWithoutYield(def_yieldgui_interval)) break;
YieldToMain();
countdown -= def_yieldgui_interval;
} while (countdown.GetMilliseconds() > 0);
return countdown.GetMilliseconds() > 0;
}
#else
return WaitWithoutYield(timeout);
#endif
}
// Performs an uncancellable wait on a semaphore; restoring the thread's previous cancel state
// after the wait has completed. Useful for situations where the semaphore itself is stored on
// the stack and passed to another thread via GUI message or such, avoiding complications where
// the thread might be canceled and the stack value becomes invalid.
//
// Performance note: this function has quite a bit more overhead compared to Semaphore::WaitWithoutYield(), so
// consider manually specifying the thread as uncancellable and using WaitWithoutYield() instead if you need
// to do a lot of no-cancel waits in a tight loop worker thread, for example.
//
// I'm unsure how to do this with pure Mach primitives, the docs in
// osfmk/man seem a bit out of date so perhaps there's a possibility, but
// since as far as I know Mach threads are 1-to-1 on BSD uthreads (and thus
// POSIX threads), this should work. -- aktau
void Threading::Semaphore::WaitNoCancel()
{
int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait();
pthread_setcancelstate(oldstate, NULL);
}
void Threading::Semaphore::WaitNoCancel(const wxTimeSpan& timeout)
{
int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait(timeout);
pthread_setcancelstate(oldstate, NULL);
}
int Threading::Semaphore::Count()
{
return __atomic_load_n(&m_counter, __ATOMIC_SEQ_CST);
}

View File

@ -0,0 +1,133 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../PrecompiledHeader.h"
#include "PersistentThread.h"
#include <unistd.h>
#if !defined(__APPLE__)
# error "DarwinThreads.cpp should only be compiled by projects or makefiles targeted at OSX."
#else
#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <mach/mach_port.h>
// Note: assuming multicore is safer because it forces the interlocked routines to use
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
// having the LOCK prefix is very bad indeed.
__forceinline void Threading::Sleep( int ms )
{
usleep(1000 * ms);
}
// For use in spin/wait loops, acts as a hint to Intel CPUs and should, in theory
// improve performance and reduce cpu power consumption.
__forceinline void Threading::SpinWait()
{
// If this doesn't compile you can just comment it out (it only serves as a
// performance hint and isn't required).
__asm__ ( "pause" );
}
__forceinline void Threading::EnableHiresScheduler()
{
// Darwin has customizable schedulers, see xnu/osfmk/man. Not
// implemented yet though (and not sure if useful for pcsx2).
}
__forceinline void Threading::DisableHiresScheduler()
{
// see EnableHiresScheduler()
}
// Just like on Windows, this is not really the number of ticks per second,
// but just a factor by which one has to divide GetThreadCpuTime() or
// pxThread::GetCpuTime() if one wants to receive a value in seconds. NOTE:
// doing this will of course yield precision loss.
u64 Threading::GetThreadTicksPerSecond()
{
return 1000000; // the *CpuTime() functions return values in microseconds
}
// gets the CPU time used by the current thread (both system and user), in
// microseconds, returns 0 on failure
static u64 getthreadtime(thread_port_t thread) {
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info;
kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO,
(thread_info_t) &info, &count);
if (kr != KERN_SUCCESS) {
return 0;
}
// add system and user time
return (u64) info.user_time.seconds * (u64) 1e6 +
(u64) info.user_time.microseconds +
(u64) info.system_time.seconds * (u64) 1e6 +
(u64) info.system_time.microseconds;
}
// Returns the current timestamp (not relative to a real world clock) in
// units of 100 nanoseconds. The weird units are to mirror the Windows
// counterpart in WinThreads.cpp, which uses the GetThreadTimes() API. On
// OSX/Darwin, this is only accurate up until 1ms (and possibly less), so
// not very good.
u64 Threading::GetThreadCpuTime()
{
// we could also use mach_thread_self() and mach_port_deallocate(), but
// that calls upon mach traps (kinda like system calls). Unless I missed
// something in the COMMPAGE (like Linux vDSO) which makes overrides it
// to be user-space instead. In contract,
// pthread_mach_thread_np(pthread_self()) is entirely in user-space.
u64 us = getthreadtime(pthread_mach_thread_np(pthread_self()));
return us * 10ULL;
}
u64 Threading::pxThread::GetCpuTime() const
{
// Get the cpu time for the thread belonging to this object. Use m_native_id and/or
// m_native_handle to implement it. Return value should be a measure of total time the
// thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(),
// which typically would be an OS-provided scalar or some sort).
if (!m_native_id) {
return 0;
}
return getthreadtime((thread_port_t) m_native_id) * 10ULL;
}
void Threading::pxThread::_platform_specific_OnStartInThread()
{
m_native_id = (uptr) mach_thread_self();
}
void Threading::pxThread::_platform_specific_OnCleanupInThread()
{
// cleanup of handles that were upened in
// _platform_specific_OnStartInThread
mach_port_deallocate(mach_task_self(), (thread_port_t) m_native_id);
}
// name can be up to 16 bytes
void Threading::pxThread::_DoSetThreadName(const char *name)
{
pthread_setname_np(name);
}
#endif

View File

@ -24,6 +24,12 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
// Apple uses the MAP_ANON define instead of MAP_ANONYMOUS, but they mean
// the same thing.
#if defined(__APPLE__) && !defined(MAP_ANONYMOUS)
# define MAP_ANONYMOUS MAP_ANON
#endif
extern void SignalExit(int sig); extern void SignalExit(int sig);
static const uptr m_pagemask = getpagesize()-1; static const uptr m_pagemask = getpagesize()-1;

View File

@ -31,6 +31,57 @@ namespace Threading
// Mutex Implementations // Mutex Implementations
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#if defined(_WIN32) || (defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 200112L)
// good, we have pthread_mutex_timedlock
#define xpthread_mutex_timedlock pthread_mutex_timedlock
#else
// We have to emulate pthread_mutex_timedlock(). This could be a serious
// performance drain if its used a lot.
#include <sys/time.h> // gettimeofday()
// sleep for 10ms at a time
#define TIMEDLOCK_EMU_SLEEP_NS 10000000ULL
// Original POSIX docs:
//
// The pthread_mutex_timedlock() function shall lock the mutex object
// referenced by mutex. If the mutex is already locked, the calling thread
// shall block until the mutex becomes available as in the
// pthread_mutex_lock() function. If the mutex cannot be locked without
// waiting for another thread to unlock the mutex, this wait shall be
// terminated when the specified timeout expires.
//
// This is an implementation that emulates pthread_mutex_timedlock() via
// pthread_mutex_trylock().
static int xpthread_mutex_timedlock(
pthread_mutex_t *mutex,
const struct timespec *abs_timeout)
{
int err = 0;
while ((err = pthread_mutex_trylock(mutex)) == EBUSY) {
// acquiring lock failed, sleep some
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS;
int status;
while ((status = nanosleep(&ts, &ts)) == -1);
// check if the timeout has expired, gettimeofday() is implemented
// efficiently (in userspace) on OSX
struct timeval now;
int res = gettimeofday(&now, NULL);
if (abs_timeout->tv_sec == 0 || now.tv_sec > abs_timeout->tv_sec ||
(u64) now.tv_usec * 1000ULL > (u64) abs_timeout->tv_nsec) {
return ETIMEDOUT;
}
}
return err;
}
#endif
Threading::Mutex::Mutex() Threading::Mutex::Mutex()
{ {
pthread_mutex_init( &m_mutex, NULL ); pthread_mutex_init( &m_mutex, NULL );
@ -125,7 +176,7 @@ bool Threading::Mutex::AcquireWithoutYield( const wxTimeSpan& timeout )
{ {
wxDateTime megafail( wxDateTime::UNow() + timeout ); wxDateTime megafail( wxDateTime::UNow() + timeout );
const timespec fail = { megafail.GetTicks(), megafail.GetMillisecond() * 1000000 }; const timespec fail = { megafail.GetTicks(), megafail.GetMillisecond() * 1000000 };
return pthread_mutex_timedlock( &m_mutex, &fail ) == 0; return xpthread_mutex_timedlock( &m_mutex, &fail ) == 0;
} }
void Threading::Mutex::Release() void Threading::Mutex::Release()

View File

@ -18,8 +18,10 @@
#ifdef WIN32 #ifdef WIN32
# include <Windows.h> # include <Windows.h>
# undef Yield # undef Yield
#else #elif defined(__linux__)
# include <libaio.h> # include <libaio.h>
#elif defined(__APPLE__)
# include <aio.h>
#endif #endif
class AsyncFileReader class AsyncFileReader
@ -70,9 +72,12 @@ class FlatFileReader : public AsyncFileReader
HANDLE hEvent; HANDLE hEvent;
bool asyncInProgress; bool asyncInProgress;
#else #elif defined(__linux__)
int m_fd; // FIXME don't know if overlap as an equivalent on linux int m_fd; // FIXME don't know if overlap as an equivalent on linux
io_context_t m_aio_context; io_context_t m_aio_context;
#elif defined(__POSIX__)
int m_fd; // TODO OSX don't know if overlap as an equivalent on OSX
struct aiocb m_aio_context;
#endif #endif
bool shareWrite; bool shareWrite;

View File

@ -18,7 +18,7 @@
#include "CompressedFileReaderUtils.h" #include "CompressedFileReaderUtils.h"
#include "CsoFileReader.h" #include "CsoFileReader.h"
#include "Pcsx2Types.h" #include "Pcsx2Types.h"
#ifdef __linux__ #ifdef __POSIX__
#include <zlib.h> #include <zlib.h>
#else #else
#include <zlib/zlib.h> #include <zlib/zlib.h>

View File

@ -101,7 +101,7 @@ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef __linux__ #ifdef __POSIX__
#include <zlib.h> #include <zlib.h>
#else #else
#include <zlib/zlib.h> #include <zlib/zlib.h>

View File

@ -63,7 +63,7 @@ set(pcsx2Sources
FiFo.cpp FiFo.cpp
FPU.cpp FPU.cpp
Gif.cpp Gif.cpp
Gif_Logger.cpp Gif_Logger.cpp
Gif_Unit.cpp Gif_Unit.cpp
GS.cpp GS.cpp
GSState.cpp GSState.cpp
@ -82,9 +82,9 @@ set(pcsx2Sources
Memory.cpp Memory.cpp
MMI.cpp MMI.cpp
MTGS.cpp MTGS.cpp
MTVU.cpp MTVU.cpp
MultipartFileReader.cpp MultipartFileReader.cpp
OutputIsoFile.cpp OutputIsoFile.cpp
Patch.cpp Patch.cpp
Patch_Memory.cpp Patch_Memory.cpp
Pcsx2Config.cpp Pcsx2Config.cpp
@ -149,7 +149,7 @@ set(pcsx2Headers
IopMem.h IopMem.h
IopSio2.h IopSio2.h
# Mdec.h # Mdec.h
MTVU.h MTVU.h
Memory.h Memory.h
MemoryTypes.h MemoryTypes.h
NakedAsm.h NakedAsm.h
@ -402,6 +402,12 @@ set(pcsx2LinuxSources
Linux/LnxFlatFileReader.cpp Linux/LnxFlatFileReader.cpp
) )
set(pcsx2OSXSources
# Linux/LnxConsolePipe.cpp
# Linux/LnxKeyCodes.cpp
Darwin/DarwinFlatFileReader.cpp
)
# Linux headers # Linux headers
set(pcsx2LinuxHeaders set(pcsx2LinuxHeaders
) )
@ -588,7 +594,7 @@ set(Common
${pcsx2CDVDHeaders} ${pcsx2CDVDHeaders}
${pcsx2DebugToolsSources} ${pcsx2DebugToolsSources}
${pcsx2GuiSources} ${pcsx2GuiSources}
${pcsx2GuiResources} ${pcsx2GuiResources}
${pcsx2GuiHeaders} ${pcsx2GuiHeaders}
${pcsx2IPUSources} ${pcsx2IPUSources}
${pcsx2IPUHeaders} ${pcsx2IPUHeaders}
@ -620,9 +626,10 @@ if(Windows)
endif() endif()
# MacOSX # MacOSX
if(MacOSX) if(APPLE)
set(Platform set(Platform
) ${pcsx2OSXSources}
${pcsx2LinuxHeaders})
endif() endif()
set(pcsx2FinalSources set(pcsx2FinalSources

View File

@ -0,0 +1,112 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2014 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "AsyncFileReader.h"
#warning This reader is not yet implemented. Crash boom bang if used
//FlatFileReader::FlatFileReader(void)
FlatFileReader::FlatFileReader(bool shareWrite) : shareWrite(shareWrite)
{
printf("FLATC\n");
m_blocksize = 2048;
m_fd = 0;
//m_aio_context = 0;
}
FlatFileReader::~FlatFileReader(void)
{
Close();
}
bool FlatFileReader::Open(const wxString& fileName)
{
printf("OB\n");
m_filename = fileName;
int err = 0; //io_setup(64, &m_aio_context);
if (err) return false;
m_fd = wxOpen(fileName, O_RDONLY, 0);
return (m_fd != 0);
}
int FlatFileReader::ReadSync(void* pBuffer, uint sector, uint count)
{
printf("RAD\n");
BeginRead(pBuffer, sector, count);
return FinishRead();
}
void FlatFileReader::BeginRead(void* pBuffer, uint sector, uint count)
{
printf("RWEADB\n");
u64 offset;
offset = sector * (u64)m_blocksize + m_dataoffset;
u32 bytesToRead = count * m_blocksize;
struct aiocb iocb;
struct aiocb* iocbs = &iocb;
//io_prep_pread(&iocb, m_fd, pBuffer, bytesToRead, offset);
//io_submit(m_aio_context, 1, &iocbs);
}
int FlatFileReader::FinishRead(void)
{
printf("FINISH\n");
u32 bytes;
int min_nr = 1;
int max_nr = 1;
/* struct io_event* events = new io_event[max_nr];
int event = io_getevents(m_aio_context, min_nr, max_nr, events, NULL);
if (event < 1) {
return -1;
}*/
return 1;
}
void FlatFileReader::CancelRead(void)
{
printf("CANCEL\n");
// Will be done when m_aio_context context is destroyed
// Note: io_cancel exists but need the iocb structure as parameter
// int io_cancel(aio_context_t ctx_id, struct iocb *iocb,
// struct io_event *result);
}
void FlatFileReader::Close(void)
{
printf("CLOSE\n");
if (m_fd) close(m_fd);
//io_destroy(m_aio_context);
aio_cancel(m_fd, &m_aio_context);
m_fd = 0;
//m_aio_context = 0;
}
uint FlatFileReader::GetBlockCount(void) const
{
printf("BLOCKS\n");
return (int)(Path::GetFileSize(m_filename) / m_blocksize);
}

View File

@ -335,6 +335,14 @@ extern void __Log( const char* fmt, ... );
# define SysTraceActive(trace) (false) # define SysTraceActive(trace) (false)
#endif #endif
#ifdef __WXMAC__
// Not available on OSX, apparently always double buffered window.
# define SetDoubleBuffered(x)
// TODO OSX OsxKeyCodes.cpp pending
# define NewPipeRedir(x) NULL
#endif
#define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write #define macTrace(trace) SysTraceActive(trace) && SysTrace.trace.Write
#define SIF_LOG macTrace(SIF) #define SIF_LOG macTrace(SIF)

View File

@ -58,7 +58,13 @@ void yuv2rgb_reference(void)
} }
} }
#ifdef _M_X86_32 // TODO OSX optimize me
#ifdef __APPLE__
void yuv2rgb_sse2() {
yuv2rgb_reference();
}
#elif defined(_M_X86_32)
// Everything below is bit accurate to the IPU specification (except maybe rounding). // Everything below is bit accurate to the IPU specification (except maybe rounding).
// Know the specification before you touch it. // Know the specification before you touch it.
#define SSE_BYTES(x) {x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x} #define SSE_BYTES(x) {x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x}

View File

@ -17,7 +17,7 @@
#ifndef NAKED_ASM_H #ifndef NAKED_ASM_H
#define NAKED_ASM_H #define NAKED_ASM_H
#ifdef __linux__ #ifdef __POSIX__
extern "C" extern "C"
{ {

View File

@ -50,6 +50,19 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#endif #endif
// Safe to remove these lines when this is handled properly.
#ifdef __WXMAC__
// Great joy....
#undef EBP
#undef ESP
#undef EDI
#undef ESI
#undef EDX
#undef EAX
#undef EBX
#undef ECX
#include <wx/osx/private.h> // needed to implement the app!
#endif
IMPLEMENT_APP(Pcsx2App) IMPLEMENT_APP(Pcsx2App)
@ -277,6 +290,8 @@ void Pcsx2App::PadKeyDispatch( const keyEvent& ev )
//returns 0 for normal keys and a WXK_* value for special keys //returns 0 for normal keys and a WXK_* value for special keys
#ifdef __WXMSW__ #ifdef __WXMSW__
const int vkey = TranslateVKToWXK(ev.key); const int vkey = TranslateVKToWXK(ev.key);
#elif defined( __WXMAC__ )
const int vkey = wxCharCodeWXToOSX( (wxKeyCode) ev.key );
#elif defined( __WXGTK__ ) #elif defined( __WXGTK__ )
const int vkey = TranslateGDKtoWXK( ev.key ); const int vkey = TranslateGDKtoWXK( ev.key );
#else #else
@ -415,7 +430,7 @@ public:
return Path::Combine( GetDataDir(), L"Langs" ); return Path::Combine( GetDataDir(), L"Langs" );
} }
#ifdef __linux__ #ifdef __POSIX__
wxString GetUserLocalDataDir() const wxString GetUserLocalDataDir() const
{ {
// I got memory corruption inside wxGetEnv when I heavily toggle the GS renderer (F9). It seems wxGetEnv // I got memory corruption inside wxGetEnv when I heavily toggle the GS renderer (F9). It seems wxGetEnv

View File

@ -18,7 +18,7 @@
#include "CpuUsageProvider.h" #include "CpuUsageProvider.h"
#include "System.h" #include "System.h"
#ifndef __linux__ #ifndef __POSIX__
#include "SysThreads.h" #include "SysThreads.h"
#endif #endif

View File

@ -1,7 +1,34 @@
// iVUzerorec.cpp assembly routines // iVUzerorec.cpp assembly routines
// zerofrog(@gmail.com) // zerofrog(@gmail.com)
.intel_syntax noprefix
#ifdef __APPLE__
#define svudispfntemp _svudispfntemp
#define s_TotalVUCycles _s_TotalVUCycles
#define s_callstack _s_callstack
#define s_vu1ebp _s_vu1ebp
#define s_vu1esp _s_vu1esp
#define s_vu1esi _s_vu1esi
#define s_vuedi _s_vuedi
#define s_vuebx _s_vuebx
#define s_saveebx _s_saveebx
#define s_saveecx _s_saveecx
#define s_saveedx _s_saveedx
#define s_saveesi _s_saveesi
#define s_saveedi _s_saveedi
#define s_saveebp _s_saveebp
#define s_writeQ _s_writeQ
#define s_writeP _s_writeP
#define g_curdebugvu _g_curdebugvu
#define SuperVUGetProgram _SuperVUGetProgram
#define SuperVUCleanupProgram _SuperVUCleanupProgram
#define SuperVUExecuteProgram _SuperVUExecuteProgram
#define SuperVUEndProgram _SuperVUEndProgram
#define g_sseVUMXCSR _g_sseVUMXCSR
#define g_sseMXCSR _g_sseMXCSR
#endif
.intel_syntax noprefix
.extern s_TotalVUCycles .extern s_TotalVUCycles
.extern s_callstack .extern s_callstack
.extern s_vu1esp .extern s_vu1esp
@ -26,7 +53,7 @@ SuperVUExecuteProgram:
mov s_vuebx, ebx mov s_vuebx, ebx
mov s_vu1esp, esp mov s_vu1esp, esp
and esp, -16 // align stack for GCC compilance and esp, -16 // align stack for GCC compilance
ldmxcsr g_sseVUMXCSR ldmxcsr g_sseVUMXCSR
mov dword ptr s_writeQ, 0xffffffff mov dword ptr s_writeQ, 0xffffffff
@ -35,17 +62,17 @@ SuperVUExecuteProgram:
.globl SuperVUEndProgram .globl SuperVUEndProgram
SuperVUEndProgram: SuperVUEndProgram:
// restore cpu state // restore cpu state
ldmxcsr g_sseMXCSR ldmxcsr g_sseMXCSR
mov esi, s_vu1esi mov esi, s_vu1esi
mov edi, s_vuedi mov edi, s_vuedi
mov ebx, s_vuebx mov ebx, s_vuebx
mov esp, s_vu1esp mov esp, s_vu1esp
call SuperVUCleanupProgram call SuperVUCleanupProgram
jmp [s_callstack] // so returns correctly jmp [s_callstack] // so returns correctly
#if defined(__linux__) && defined(__ELF__) #if defined(__POSIX__) && defined(__ELF__)
.section .note.GNU-stack,"",%progbits .section .note.GNU-stack,"",%progbits
#endif #endif

View File

@ -20,13 +20,13 @@
#include "sVU_Micro.h" #include "sVU_Micro.h"
//Using assembly code from an external file. //Using assembly code from an external file.
#ifdef __linux__ #ifdef __POSIX__
extern "C" { extern "C" {
#endif #endif
extern void SuperVUExecuteProgram(u32 startpc, int vuindex); extern void SuperVUExecuteProgram(u32 startpc, int vuindex);
extern void SuperVUEndProgram(); extern void SuperVUEndProgram();
extern void svudispfntemp(); extern void svudispfntemp();
#ifdef __linux__ #ifdef __POSIX__
} }
#endif #endif

View File

@ -83,7 +83,7 @@ extern u32 OutputModule;
extern int SndOutLatencyMS; extern int SndOutLatencyMS;
extern int SynchMode; extern int SynchMode;
#ifndef __linux__ #ifndef __POSIX__
extern wchar_t dspPlugin[]; extern wchar_t dspPlugin[];
extern int dspPluginModule; extern int dspPluginModule;

View File

@ -68,7 +68,11 @@ static __forceinline T GetClamped( T src, T min, T max )
return std::min( std::max( src, min ), max ); return std::min( std::max( src, min ), max );
} }
#ifdef __WXMAC__
#include "PS2Eext.h"
#else
extern void SysMessage(const char *fmt, ...); extern void SysMessage(const char *fmt, ...);
#endif
extern void SysMessage(const wchar_t *fmt, ...); extern void SysMessage(const wchar_t *fmt, ...);
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////

View File

@ -17,6 +17,8 @@
// Adapted from ZeroSPU2 code by Zerofrog. Heavily modified by Arcum42. // Adapted from ZeroSPU2 code by Zerofrog. Heavily modified by Arcum42.
#ifdef __linux__
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
#include "Global.h" #include "Global.h"
@ -260,3 +262,5 @@ public:
} static Alsa; } static Alsa;
SndOutModule *AlsaOut = &Alsa; SndOutModule *AlsaOut = &Alsa;
#endif

View File

@ -141,7 +141,9 @@ void ReadSettings()
SynchMode = CfgReadInt( L"OUTPUT", L"Synch_Mode", 0); SynchMode = CfgReadInt( L"OUTPUT", L"Synch_Mode", 0);
PortaudioOut->ReadSettings(); PortaudioOut->ReadSettings();
#ifndef __APPLE__
SDLOut->ReadSettings(); SDLOut->ReadSettings();
#endif
SoundtouchCfg::ReadSettings(); SoundtouchCfg::ReadSettings();
DebugConfig::ReadSettings(); DebugConfig::ReadSettings();
@ -185,7 +187,9 @@ void WriteSettings()
CfgWriteInt(L"DEBUG", L"DelayCycles", delayCycles); CfgWriteInt(L"DEBUG", L"DelayCycles", delayCycles);
PortaudioOut->WriteSettings(); PortaudioOut->WriteSettings();
#ifndef __APPLE__
SDLOut->WriteSettings(); SDLOut->WriteSettings();
#endif
SoundtouchCfg::WriteSettings(); SoundtouchCfg::WriteSettings();
DebugConfig::WriteSettings(); DebugConfig::WriteSettings();
} }
@ -200,6 +204,7 @@ void debug_dialog()
DebugConfig::DisplayDialog(); DebugConfig::DisplayDialog();
} }
#ifdef __linux__
void DisplayDialog() void DisplayDialog()
{ {
int return_value; int return_value;
@ -379,6 +384,12 @@ void DisplayDialog()
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
} }
#else
void DisplayDialog()
{
}
#endif
void configure() void configure()
{ {

View File

@ -18,7 +18,10 @@
#ifndef CONFIG_H_INCLUDED #ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED #define CONFIG_H_INCLUDED
#ifdef __linux__
#include <gtk/gtk.h> #include <gtk/gtk.h>
#endif
#include <string> #include <string>
#include <wx/fileconf.h> #include <wx/fileconf.h>

View File

@ -154,6 +154,7 @@ void WriteSettings()
} }
#ifdef __linux__
void DisplayDialog() void DisplayDialog()
{ {
GtkWidget *dialog; GtkWidget *dialog;
@ -285,5 +286,10 @@ void DisplayDialog()
WriteSettings(); WriteSettings();
} }
#else
void DisplayDialog()
{
}
#endif
} }

View File

@ -71,9 +71,11 @@ namespace SoundtouchCfg
CfgWriteInt( L"SOUNDTOUCH", L"OverlapMS", OverlapMS ); CfgWriteInt( L"SOUNDTOUCH", L"OverlapMS", OverlapMS );
} }
#ifdef __linux__
static GtkWidget *seq_label, *seek_label, *over_label; static GtkWidget *seq_label, *seek_label, *over_label;
static GtkWidget *seq_slide, *seek_slide, *over_slide; static GtkWidget *seq_slide, *seek_slide, *over_slide;
void restore_defaults() void restore_defaults()
{ {
gtk_range_set_value(GTK_RANGE(seq_slide), 30); gtk_range_set_value(GTK_RANGE(seq_slide), 30);
@ -81,6 +83,7 @@ namespace SoundtouchCfg
gtk_range_set_value(GTK_RANGE(over_slide), 10); gtk_range_set_value(GTK_RANGE(over_slide), 10);
} }
void DisplayDialog() void DisplayDialog()
{ {
int return_value; int return_value;
@ -158,4 +161,15 @@ namespace SoundtouchCfg
WriteSettings(); WriteSettings();
} }
#else
void DisplayDialog()
{
}
void restore_defaults()
{
}
#endif
} }

View File

@ -17,10 +17,12 @@
// To be continued... // To be continued...
#include "Dialogs.h" #include "Dialogs.h"
#include <gtk/gtk.h>
#include <cstring> #include <cstring>
#ifdef __linux__
#include <gtk/gtk.h>
void SysMessage(const char *fmt, ...) void SysMessage(const char *fmt, ...)
{ {
va_list list; va_list list;
@ -59,6 +61,7 @@ void SysMessage(const wchar_t *fmt, ...)
gtk_dialog_run (GTK_DIALOG (dialog)); gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
} }
#endif
void DspUpdate() void DspUpdate()
{ {

View File

@ -270,6 +270,20 @@ static __forceinline void GetNextDataDummy(V_Core& thiscore, uint voiceidx)
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
// // // //
#if defined(__clang__)
#include <limits.h>
static s32 rotr(u32 x, u32 s)
{
//return (x >> s) | (x << (32 - s));
return (x >> s) | (x << (sizeof(x) * CHAR_BIT - s));
}
static s32 rotl(u32 x, u32 s)
{
//return (x << s) | (x >> (32 - s));
return (x << s) | (x >> (sizeof(x) * CHAR_BIT - s));
}
#endif
static s32 __forceinline GetNoiseValues() static s32 __forceinline GetNoiseValues()
{ {
@ -292,7 +306,7 @@ static s32 __forceinline GetNoiseValues()
ROR eax,3 ROR eax,3
MOV Seed,eax MOV Seed,eax
} }
#else #elif !defined(__clang__) // Linux with GCC
__asm__ ( __asm__ (
".intel_syntax\n" ".intel_syntax\n"
"MOV %%eax,%1\n" "MOV %%eax,%1\n"
@ -307,6 +321,14 @@ static s32 __forceinline GetNoiseValues()
".att_syntax\n" : "=r"(Seed) :"r"(Seed) ".att_syntax\n" : "=r"(Seed) :"r"(Seed)
: "%eax", "%esi" : "%eax", "%esi"
); );
#else // Clang and others
s32 s = rotr(Seed,5);
s ^= 0x9a;
s32 k = rotl(s,2);
k+=s;
k^=s;
k = rotr(k,3);
Seed=k;
#endif #endif
return retval; return retval;
} }
@ -819,7 +841,7 @@ static int p_cachestat_counter=0;
// Gcc does not want to inline it when lto is enabled because some functions growth too much. // Gcc does not want to inline it when lto is enabled because some functions growth too much.
// The function is big enought to see any speed impact. -- Gregory // The function is big enought to see any speed impact. -- Gregory
#ifndef __linux__ #ifndef __POSIX__
__forceinline __forceinline
#endif #endif
void Mix() void Mix()

View File

@ -20,6 +20,10 @@
#include "Dma.h" #include "Dma.h"
#include "Dialogs.h" #include "Dialogs.h"
#ifdef __POSIX__
#include "PS2Eext.h"
#endif
#include "svnrev.h" #include "svnrev.h"
#ifdef _MSC_VER #ifdef _MSC_VER
@ -446,7 +450,7 @@ EXPORT_C_(s32) SPU2open(void *pDsp)
{ {
SndBuffer::Init(); SndBuffer::Init();
#ifndef __linux__ #ifndef __POSIX__
DspLoadLibrary(dspPlugin,dspPluginModule); DspLoadLibrary(dspPlugin,dspPluginModule);
#endif #endif
WaveDump::Open(); WaveDump::Open();
@ -467,7 +471,7 @@ EXPORT_C_(void) SPU2close()
FileLog("[%10d] SPU2 Close\n",Cycles); FileLog("[%10d] SPU2 Close\n",Cycles);
#ifndef __linux__ #ifndef __POSIX__
DspCloseLibrary(); DspCloseLibrary();
#endif #endif

View File

@ -20,7 +20,7 @@
#include "Pcsx2Defs.h" #include "Pcsx2Defs.h"
#include "PS2Edefs.h" #include "PS2Edefs.h"
#ifdef __linux__ #ifdef __POSIX__
//Until I get around to putting in Linux svn code, this is an unknown svn version. //Until I get around to putting in Linux svn code, this is an unknown svn version.
#define SVN_REV_UNKNOWN #define SVN_REV_UNKNOWN
#endif #endif
@ -51,7 +51,7 @@ EXPORT_C_(void) SPU2irqCallback(void (*SPU2callback)());
#else #else
// These defines are useless and gcc-4.6 complain about redefinition // These defines are useless and gcc-4.6 complain about redefinition
// so we remove them on linux // so we remove them on linux
#ifndef __linux__ #ifndef __POSIX__
EXPORT_C_(void) SPU2readDMA4Mem(u16 *pMem, u32 size); EXPORT_C_(void) SPU2readDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2writeDMA4Mem(u16 *pMem, u32 size); EXPORT_C_(void) SPU2writeDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2interruptDMA4(); EXPORT_C_(void) SPU2interruptDMA4();

View File

@ -92,8 +92,10 @@ SndOutModule* mods[]=
WaveOut, WaveOut,
#endif #endif
PortaudioOut, PortaudioOut,
#ifdef __linux__ #if defined(SPU2X_SDL) || defined(SPU2X_SDL2)
SDLOut, SDLOut,
#endif
#if defined(__linux__) /* && defined(__ALSA__)*/
AlsaOut, AlsaOut,
#endif #endif
NULL // signals the end of our list NULL // signals the end of our list
@ -465,7 +467,7 @@ void SndBuffer::Write( const StereoOut32& Sample )
ssFreeze--; ssFreeze--;
memset( sndTempBuffer, 0, sizeof(StereoOut32) * SndOutPacketSize ); // Play silence memset( sndTempBuffer, 0, sizeof(StereoOut32) * SndOutPacketSize ); // Play silence
} }
#ifndef __linux__ #ifndef __POSIX__
if( dspPluginEnabled ) if( dspPluginEnabled )
{ {
// Convert in, send to winamp DSP, and convert out. // Convert in, send to winamp DSP, and convert out.

View File

@ -673,8 +673,10 @@ extern SndOutModule* DSoundOut;
extern SndOutModule* XAudio2Out; extern SndOutModule* XAudio2Out;
#endif #endif
extern SndOutModule* PortaudioOut; extern SndOutModule* PortaudioOut;
#ifdef __linux__ #if defined(SPU2X_SDL) || defined(SPU2X_SDL2)
extern SndOutModule * const SDLOut; extern SndOutModule * const SDLOut;
#endif
#ifdef __linux__
extern SndOutModule* AlsaOut; extern SndOutModule* AlsaOut;
#endif #endif

View File

@ -588,6 +588,9 @@ public:
#ifdef __linux__ #ifdef __linux__
// By default on linux use the ALSA API (+99% users) -- Gregory // By default on linux use the ALSA API (+99% users) -- Gregory
CfgReadStr( L"PORTAUDIO", L"HostApi", api, L"ALSA" ); CfgReadStr( L"PORTAUDIO", L"HostApi", api, L"ALSA" );
#elif defined(__APPLE__)
// Suppose OSX only has CoreAudio...
CfgReadStr( L"PORTAUDIO", L"HostApi", api, L"CoreAudio" );
#else #else
CfgReadStr( L"PORTAUDIO", L"HostApi", api, L"WASAPI" ); CfgReadStr( L"PORTAUDIO", L"HostApi", api, L"WASAPI" );
#endif #endif

View File

@ -16,7 +16,7 @@
*/ */
#include "Global.h" #include "Global.h"
#ifdef __linux__ #ifdef __POSIX__
#include "WavFile.h" #include "WavFile.h"
#else #else
#include "soundtouch/source/SoundStretch/WavFile.h" #include "soundtouch/source/SoundStretch/WavFile.h"
@ -53,7 +53,7 @@ namespace WaveDump
for( int srcidx=0; srcidx<CoreSrc_Count; srcidx++ ) for( int srcidx=0; srcidx<CoreSrc_Count; srcidx++ )
{ {
safe_delete( m_CoreWav[cidx][srcidx] ); safe_delete( m_CoreWav[cidx][srcidx] );
#ifdef __linux__ #ifdef __POSIX__
sprintf( wavfilename, "logs/spu2x-Core%d-%s.wav", sprintf( wavfilename, "logs/spu2x-Core%d-%s.wav",
cidx, m_tbl_CoreOutputTypeNames[ srcidx ] ); cidx, m_tbl_CoreOutputTypeNames[ srcidx ] );
#else #else