mirror of https://github.com/PCSX2/pcsx2.git
Merge pull request #978 from juhalaukkanen/apple_osx_master_merge
OSX 32bit build
This commit is contained in:
commit
74db92bee4
27
build.sh
27
build.sh
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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"
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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, ...);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue