Merge 'master' into shader-uids-awesome.

Conflicts:
	Source/Core/VideoCommon/Src/LightingShaderGen.cpp
	Source/Core/VideoCommon/Src/PixelShaderGen.cpp
	Source/Core/VideoCommon/Src/PixelShaderGen.h
	Source/Core/VideoCommon/Src/VertexShaderGen.cpp
This commit is contained in:
NeoBrainX 2013-06-17 12:05:47 +02:00
commit ca22872dae
172 changed files with 4585 additions and 1736 deletions

View file

@ -7,7 +7,8 @@ option(ANDROID "Enables a build for Android" OFF)
option(USE_EGL "Enables EGL OpenGL Interface" OFF) option(USE_EGL "Enables EGL OpenGL Interface" OFF)
option(USE_X11 "Enables X11 Support" ON) option(USE_X11 "Enables X11 Support" ON)
option(USE_WAYLAND "Enables Wayland Support" OFF) option(USE_WAYLAND "Enables Wayland Support" OFF)
option(USE_GLES "Enables GLES And EGL, disables OGL" OFF) option(USE_GLES "Enables GLES2 And EGL, disables OGL" OFF)
option(USE_GLES3 "Enables GLES3 and EGL" OFF)
option(DISABLE_WX "Disable wxWidgets (use CLI interface)" OFF) option(DISABLE_WX "Disable wxWidgets (use CLI interface)" OFF)
option(FASTLOG "Enable all logs" OFF) option(FASTLOG "Enable all logs" OFF)
@ -84,11 +85,11 @@ endfunction(enable_precompiled_headers)
include(FindGit OPTIONAL) include(FindGit OPTIONAL)
if(GIT_FOUND AND NOT DOLPHIN_WC_REVISION) if(GIT_FOUND AND NOT DOLPHIN_WC_REVISION)
# defines DOLPHIN_WC_REVISION # defines DOLPHIN_WC_REVISION
EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
OUTPUT_VARIABLE DOLPHIN_WC_REVISION OUTPUT_VARIABLE DOLPHIN_WC_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
# defines DOLPHIN_WC_DESCRIBE # defines DOLPHIN_WC_DESCRIBE
EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} describe --always --long --dirty EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} describe --always --long --dirty
OUTPUT_VARIABLE DOLPHIN_WC_DESCRIBE OUTPUT_VARIABLE DOLPHIN_WC_DESCRIBE
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
@ -96,7 +97,7 @@ if(GIT_FOUND AND NOT DOLPHIN_WC_REVISION)
STRING(REGEX REPLACE "-[^-]+((-dirty)?)$" "\\1" DOLPHIN_WC_DESCRIBE "${DOLPHIN_WC_DESCRIBE}") STRING(REGEX REPLACE "-[^-]+((-dirty)?)$" "\\1" DOLPHIN_WC_DESCRIBE "${DOLPHIN_WC_DESCRIBE}")
# defines DOLPHIN_WC_BRANCH # defines DOLPHIN_WC_BRANCH
EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
OUTPUT_VARIABLE DOLPHIN_WC_BRANCH OUTPUT_VARIABLE DOLPHIN_WC_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
endif() endif()
@ -261,11 +262,19 @@ endif()
# For now GLES and EGL are tied to each other. # For now GLES and EGL are tied to each other.
# Enabling GLES also disables the OpenGL plugin. # Enabling GLES also disables the OpenGL plugin.
if(USE_GLES) if(USE_GLES3)
message("GLES rendering enabled") message("GLES3 rendering enabled")
add_definitions(-DUSE_GLES=1) add_definitions(-DUSE_GLES=1 -DUSE_EGL=1 -DUSE_GLES3=1)
add_definitions(-DUSE_EGL=1) include_directories(Externals/GLES3)
set(USE_EGL True) set(USE_EGL True)
set(USE_GLES True)
else()
if(USE_GLES)
message("GLES2 rendering enabled. OpenGL disabled")
add_definitions(-DUSE_GLES=1)
add_definitions(-DUSE_EGL=1)
set(USE_EGL True)
endif()
endif() endif()
# For now Wayland and EGL are tied to each other. # For now Wayland and EGL are tied to each other.
# The alternative would be an shm path # The alternative would be an shm path
@ -595,7 +604,7 @@ if(NOT DISABLE_WX AND NOT ANDROID)
FIND_PACKAGE(wxWidgets COMPONENTS core aui adv) FIND_PACKAGE(wxWidgets COMPONENTS core aui adv)
if(wxWidgets_FOUND) if(wxWidgets_FOUND)
EXECUTE_PROCESS( EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
${wxWidgets_CONFIG_OPTIONS} --version ${wxWidgets_CONFIG_OPTIONS} --version
OUTPUT_VARIABLE wxWidgets_VERSION OUTPUT_VARIABLE wxWidgets_VERSION
@ -610,7 +619,7 @@ if(NOT DISABLE_WX AND NOT ANDROID)
endif(wxWidgets_FOUND) endif(wxWidgets_FOUND)
if(wxWidgets_FOUND) if(wxWidgets_FOUND)
EXECUTE_PROCESS( EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
${wxWidgets_CONFIG_OPTIONS} --version ${wxWidgets_CONFIG_OPTIONS} --version
OUTPUT_VARIABLE wxWidgets_VERSION OUTPUT_VARIABLE wxWidgets_VERSION

View file

@ -0,0 +1,16 @@
# GHMD4F - Hitman 2: Silent Assassin
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues =
EmulationStateId = 5
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -30,3 +30,11 @@ $Press Left + Y For Nailgun
52889D30 00000801 52889D30 00000801
0406D250 418201BC 0406D250 418201BC
0406D288 408000C4 0406D288 408000C4
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -0,0 +1,16 @@
# GHMF4F - Hitman 2: Silent Assassin
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues =
EmulationStateId = 5
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -0,0 +1,16 @@
# GHMP4F - Hitman 2: Silent Assassin
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues =
EmulationStateId = 5
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -0,0 +1,18 @@
# GJXP51 - Vexx
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[EmuState]
EmulationStateId = 4
EmulationIssues = Slow because it needs mmu to run.
[OnFrame]
[ActionReplay]
[Gecko]
[Video_Settings]
[Core]
MMU = 1

View file

@ -0,0 +1,16 @@
# GOWD69 - NFS Most Wanted
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues = Videos are messed up, skip them.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -1,7 +1,16 @@
# GOWE69 - NFS Most Wanted # GOWE69 - NFS Most Wanted
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4 EmulationStateId = 4
EmulationIssues = Some GFX Glitches And may be slow. EmulationIssues = Videos are messed up, skip them.
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -0,0 +1,16 @@
# GOWF69 - NFS Most Wanted
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues = Videos are messed up, skip them.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -0,0 +1,16 @@
# GOWJ69 - NFS Most Wanted
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues = Videos are messed up, skip them.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -0,0 +1,16 @@
# GOWP69 - NFS Most Wanted
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues = Videos are messed up, skip them.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -1,8 +1,10 @@
# GWLX6L - Project Zoo # GWLX6L - Project Zoo
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
TLBHack=1 TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 2 EmulationStateId = 4
EmulationIssues = Unespecified codes,report to devs EmulationIssues =
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
+$Bypass FIFO reset
0x8028EE80:dword:0x48000638
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.

View file

@ -0,0 +1,18 @@
# GX2P52 - X-Men Legends 2: Rise of Apocalypse
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 3
EmulationIssues =
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]
[Video_Enhancements]

View file

@ -4,7 +4,7 @@ TLBHack = 1
MMU = 1 MMU = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4 EmulationStateId = 4
EmulationIssues = Needs real xfb for the videos to show up (r6906) EmulationIssues = Needs real xfb for the videos to show up.
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.
[Video] [Video]

View file

@ -0,0 +1,21 @@
# GX3X41 - XIII
[Core] Values set here will override the main dolphin settings.
TLBHack = 1
MMU = 1
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues = Needs real xfb for the videos to show up.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]
[Video_Settings]
UseXFB = True
UseRealXFB = True

View file

@ -1,8 +1,17 @@
# JAAE01 - Super Mario World # JAAE01 - Super Mario World
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = No Sound EmulationIssues =
EmulationStateId = 4 EmulationStateId = 4
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.
[Video] [Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]
[Video_Settings]
SafeTextureCacheColorSamples = 512

View file

@ -1,7 +1,7 @@
# SB3E08 - BASARA # SB3E08 - BASARA
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = Audio synch issues during dialogues, otherwise perfect EmulationIssues =
EmulationStateId = 5 EmulationStateId = 5
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.

View file

@ -1,7 +1,7 @@
# SB3J08 - BASARA # SB3J08 - BASARA
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = Audio synch issues during dialogues, otherwise perfect EmulationIssues =
EmulationStateId = 5 EmulationStateId = 5
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.

View file

@ -1,7 +1,7 @@
# SB3P08 - BASARA # SB3P08 - BASARA
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = Audio synch issues during dialogues, otherwise perfect EmulationIssues =
EmulationStateId = 5 EmulationStateId = 5
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.

View file

@ -0,0 +1,18 @@
# SLWE41 - Where's Waldo? The Fantastic Journey
[Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues = Needs Real Xfb for the pointer to appear.
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]
[Video_Settings]
UseXFB = True
UseRealXFB = True

View file

@ -0,0 +1,17 @@
# SVBE52 - Battleship
[Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues =
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]
[Video_Settings]
SafeTextureCacheColorSamples = 0

View file

@ -0,0 +1,17 @@
# SVBP52 - Battleship
[Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 4
EmulationIssues =
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]
[Video_Settings]
SafeTextureCacheColorSamples = 0

View file

@ -1,10 +1,15 @@
# W8CEXS - BIT.TRIP CORE # W8CEXS - BIT.TRIP CORE
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationStateId = 1 EmulationStateId = 4
EmulationIssues = Requires a Wii save game to boot EmulationIssues =
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.
[Video] [Video]
ProjectionHack = 0 ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko] [Gecko]

View file

@ -2,8 +2,14 @@
[Core] Values set here will override the main dolphin settings. [Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = EmulationIssues =
EmulationStateId = 1 EmulationStateId = 4
[OnFrame] Add memory patches to be applied every frame here. [OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here. [ActionReplay] Add action replay cheats here.
[Video] [Video]
ProjectionHack = 0 ProjectionHack = 0
PH_SZNear = 0
PH_SZFar = 0
PH_ExtraParam = 0
PH_ZNear =
PH_ZFar =
[Gecko]

View file

@ -80,7 +80,7 @@ namespace soundtouch
#undef SOUNDTOUCH_INTEGER_SAMPLES #undef SOUNDTOUCH_INTEGER_SAMPLES
#undef SOUNDTOUCH_FLOAT_SAMPLES #undef SOUNDTOUCH_FLOAT_SAMPLES
#if (defined(__SOFTFP__)) #if (defined(ANDROID) && defined(__SOFTFP__))
// For Android compilation: Force use of Integer samples in case that // For Android compilation: Force use of Integer samples in case that
// compilation uses soft-floating point emulation - soft-fp is way too slow // compilation uses soft-floating point emulation - soft-fp is way too slow
#undef SOUNDTOUCH_FLOAT_SAMPLES #undef SOUNDTOUCH_FLOAT_SAMPLES

1
Source/Android/.idea/.name generated Normal file
View file

@ -0,0 +1 @@
Android

23
Source/Android/.idea/compiler.xml generated Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

View file

@ -0,0 +1,5 @@
<component name="CopyrightManager">
<settings default="">
<module2copyright />
</settings>
</component>

5
Source/Android/.idea/encodings.xml generated Normal file
View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>

View file

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="dexedLibs">
<CLASSES>
<root url="jar://$PROJECT_DIR$/bin/dexedLibs/library-f3f525b7017bd70eb33262cbaaf909f6.jar!/" />
<root url="jar://$PROJECT_DIR$/bin/dexedLibs/library-7180f05db1823245b4a6600ab592b5c5.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

26
Source/Android/.idea/misc.xml generated Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="Android 4.2.2" project-jdk-type="Android SDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="masterDetails">
<states>
<state key="ProjectJDKs.UI">
<settings>
<last-edited>Android 4.2.2</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>

10
Source/Android/.idea/modules.xml generated Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Android.iml" filepath="$PROJECT_DIR$/Android.iml" />
<module fileurl="file://$PROJECT_DIR$/../../Externals/android-menudrawer/library/library.iml" filepath="$PROJECT_DIR$/../../Externals/android-menudrawer/library/library.iml" />
</modules>
</component>
</project>

View file

@ -0,0 +1,5 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>

7
Source/Android/.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>

764
Source/Android/.idea/workspace.xml generated Normal file
View file

@ -0,0 +1,764 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidLayoutPreviewToolWindow">
<option name="state">
<GlobalState>
<option name="visible" value="false" />
</GlobalState>
</option>
</component>
<component name="AndroidLayouts">
<shared>
<config>
<target>android-17</target>
</config>
</shared>
<layouts>
<layout url="file://$PROJECT_DIR$/res/layout/folderbrowser.xml">
<config>
<device>Nexus 4</device>
<theme>@android:style/Theme.Holo</theme>
</config>
</layout>
<layout url="file://$PROJECT_DIR$/res/layout/main.xml">
<config>
<device>Nexus 4</device>
<theme>@android:style/Theme.Holo</theme>
</config>
</layout>
</layouts>
</component>
<component name="BookmarkManager">
<bookmark url="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/DolphinEmulator.java" line="37" />
</component>
<component name="ChangeListManager">
<list default="true" id="682e8195-a9c2-48a7-a941-e8c10f5cb64a" name="Default" comment="" />
<ignored path="Android.iws" />
<ignored path=".idea/workspace.xml" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
<component name="Commander">
<leftPanel />
<rightPanel />
<splitter proportion="0.5" />
</component>
<component name="CreatePatchCommitExecutor">
<option name="PATCH_PATH" value="" />
</component>
<component name="DaemonCodeAnalyzer">
<disable_hints />
</component>
<component name="DebuggerManager">
<breakpoint_any default_suspend_policy="SuspendAll" default_condition_enabled="true">
<breakpoint>
<option name="NOTIFY_CAUGHT" value="true" />
<option name="NOTIFY_UNCAUGHT" value="true" />
<option name="ENABLED" value="false" />
<option name="LOG_ENABLED" value="false" />
<option name="LOG_EXPRESSION_ENABLED" value="false" />
<option name="REMOVE_AFTER_HIT" value="false" />
<option name="SUSPEND_POLICY" value="SuspendAll" />
<option name="SUSPEND" value="true" />
<option name="COUNT_FILTER_ENABLED" value="false" />
<option name="COUNT_FILTER" value="0" />
<option name="CONDITION_ENABLED" value="true" />
<option name="CLASS_FILTERS_ENABLED" value="false" />
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
<option name="CONDITION" value="" />
<option name="LOG_MESSAGE" value="" />
</breakpoint>
<breakpoint>
<option name="NOTIFY_CAUGHT" value="true" />
<option name="NOTIFY_UNCAUGHT" value="true" />
<option name="ENABLED" value="false" />
<option name="LOG_ENABLED" value="false" />
<option name="LOG_EXPRESSION_ENABLED" value="false" />
<option name="REMOVE_AFTER_HIT" value="false" />
<option name="SUSPEND_POLICY" value="SuspendAll" />
<option name="SUSPEND" value="true" />
<option name="COUNT_FILTER_ENABLED" value="false" />
<option name="COUNT_FILTER" value="0" />
<option name="CONDITION_ENABLED" value="true" />
<option name="CLASS_FILTERS_ENABLED" value="false" />
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
<option name="CONDITION" value="" />
<option name="LOG_MESSAGE" value="" />
</breakpoint>
</breakpoint_any>
<ui_properties default_suspend_policy="SuspendAll" default_condition_enabled="true" />
<breakpoint_rules />
<ui_properties />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
<component name="FavoritesManager">
<favorites_list name="Android" />
</component>
<component name="FileEditorManager">
<leaf>
<file leaf-file-name="DolphinEmulator.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/DolphinEmulator.java">
<provider selected="true" editor-type-id="text-editor">
<state line="164" column="4" selection-start="4729" selection-end="4729" vertical-scroll-proportion="0.0" vertical-offset="2445" max-vertical-offset="2640">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="AndroidManifest.xml" pinned="false" current="true" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/AndroidManifest.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="6" column="39" selection-start="248" selection-end="248" vertical-scroll-proportion="0.026223777" vertical-offset="75" max-vertical-offset="735">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="GameListView.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/GameListView.java">
<provider selected="true" editor-type-id="text-editor">
<state line="51" column="78" selection-start="1629" selection-end="1629" vertical-scroll-proportion="0.0" vertical-offset="750" max-vertical-offset="3420">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="FolderBrowser.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/FolderBrowser.java">
<provider selected="true" editor-type-id="text-editor">
<state line="81" column="20" selection-start="2652" selection-end="2652" vertical-scroll-proportion="0.0" vertical-offset="1200" max-vertical-offset="1485">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="prefs.xml" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/res/layout/prefs.xml">
<provider editor-type-id="android-designer">
<state />
</provider>
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="495">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="prefvalues.xml" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/res/values/prefvalues.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="14" column="31" selection-start="392" selection-end="392" vertical-scroll-proportion="0.0" vertical-offset="195" max-vertical-offset="405">
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="PrefsActivity.java" pinned="false" current="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/PrefsActivity.java">
<provider selected="true" editor-type-id="text-editor">
<state line="14" column="0" selection-start="389" selection-end="389" vertical-scroll-proportion="0.0" vertical-offset="195" max-vertical-offset="690">
<folding />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FindManager">
<FindUsagesManager>
<setting name="OPEN_NEW_TAB" value="false" />
</FindUsagesManager>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../.." />
</component>
<component name="GitLogSettings">
<option name="myDateState">
<MyDateState />
</option>
</component>
<component name="IdeDocumentHistory">
<option name="changedFiles">
<list>
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/SideMenuItem.java" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/SettingMenuItem.java" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/SettingMenuAdapter.java" />
<option value="$PROJECT_DIR$/res/layout/fragment_edit_name.xml" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/EditNameDialog.java" />
<option value="$PROJECT_DIR$/res/values/array.xml" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/PrefsFragment.java" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/PrefsActivity.java" />
<option value="$PROJECT_DIR$/res/values/prefs.xml" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/SettingBrowser.java" />
<option value="$PROJECT_DIR$/res/layout/prefs.xml" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/FolderBrowser.java" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/GameListView.java" />
<option value="$PROJECT_DIR$/res/values/prefvalues.xml" />
<option value="$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/DolphinEmulator.java" />
<option value="$PROJECT_DIR$/AndroidManifest.xml" />
</list>
</option>
</component>
<component name="MavenProjectNavigator">
<treeState />
</component>
<component name="ProjectFrameBounds">
<option name="x" value="24" />
<option name="width" value="1342" />
<option name="height" value="744" />
</component>
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State>
<id />
</State>
</expanded-state>
<selected-state>
<State>
<id>Abstraction issues</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="1" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectReloadState">
<option name="STATE" value="0" />
</component>
<component name="ProjectView">
<navigator currentView="Scope" currentSubView="Project Files" proportions="" version="1" splitterProportion="0.5">
<flattenPackages />
<showMembers />
<showModules />
<showLibraryContents />
<hideEmptyPackages />
<abbreviatePackageNames />
<autoscrollToSource />
<autoscrollFromSource />
<sortByType />
</navigator>
<panes>
<pane id="Scope">
<subPane subId="Project Files">
<PATH>
<PATH_ELEMENT USER_OBJECT="Root">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT USER_OBJECT="Root">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
<PATH_ELEMENT USER_OBJECT="Android">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
<PATH_ELEMENT USER_OBJECT="Android">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT USER_OBJECT="Root">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
<PATH_ELEMENT USER_OBJECT="Android">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
<PATH_ELEMENT USER_OBJECT="Android">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
<PATH_ELEMENT USER_OBJECT="src">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
<PATH_ELEMENT USER_OBJECT="org/dolphinemu/dolphinemu">
<option name="myItemId" value="" />
<option name="myItemType" value="" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
<pane id="PackagesPane" />
<pane id="ProjectPane">
<subPane>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="Android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="Android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="Android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="Android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="dolphinemu" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
</panes>
</component>
<component name="PropertiesComponent">
<property name="options.searchVisible" value="true" />
<property name="GoToClass.toSaveIncludeLibraries" value="false" />
<property name="FullScreen" value="false" />
<property name="GoToFile.includeJavaFiles" value="false" />
<property name="MemberChooser.copyJavadoc" value="false" />
<property name="recentsLimit" value="5" />
<property name="options.lastSelected" value="android.dex.compiler" />
<property name="restartRequiresConfirmation" value="true" />
<property name="MemberChooser.sorted" value="false" />
<property name="options.splitter.details.proportions" value="0.2" />
<property name="options.splitter.main.proportions" value="0.3" />
<property name="ANDROID_EXTENDED_DEVICE_CHOOSER_SERIALS" value="192.168.0.188:5555" />
<property name="GoToClass.includeLibraries" value="false" />
<property name="ANDROID_EXTENDED_DEVICE_CHOOSER_AVD" value="YES" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="MemberChooser.showClasses" value="true" />
<property name="dynamic.classpath" value="false" />
</component>
<component name="RunManager" selected="Android Application.Dolphin Emulator">
<configuration default="true" type="Remote" factoryName="Remote">
<option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" value="javadebug" />
<option name="HOST" value="localhost" />
<option name="PORT" value="5005" />
<method />
</configuration>
<configuration default="true" type="AndroidTestRunConfigurationType" factoryName="Android Tests">
<module name="" />
<option name="TESTING_TYPE" value="0" />
<option name="INSTRUMENTATION_RUNNER_CLASS" value="" />
<option name="METHOD_NAME" value="" />
<option name="CLASS_NAME" value="" />
<option name="PACKAGE_NAME" value="" />
<option name="TARGET_SELECTION_MODE" value="EMULATOR" />
<option name="PREFERRED_AVD" value="" />
<option name="USE_COMMAND_LINE" value="true" />
<option name="COMMAND_LINE" value="" />
<option name="WIPE_USER_DATA" value="false" />
<option name="DISABLE_BOOT_ANIMATION" value="false" />
<option name="NETWORK_SPEED" value="full" />
<option name="NETWORK_LATENCY" value="none" />
<option name="CLEAR_LOGCAT" value="false" />
<method />
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="moduleWithDependencies" />
</option>
<envs />
<patterns />
<method />
</configuration>
<configuration default="true" type="AndroidRunConfigurationType" factoryName="Android Application">
<module name="" />
<option name="ACTIVITY_CLASS" value="" />
<option name="MODE" value="default_activity" />
<option name="DEPLOY" value="true" />
<option name="TARGET_SELECTION_MODE" value="EMULATOR" />
<option name="PREFERRED_AVD" value="" />
<option name="USE_COMMAND_LINE" value="true" />
<option name="COMMAND_LINE" value="" />
<option name="WIPE_USER_DATA" value="false" />
<option name="DISABLE_BOOT_ANIMATION" value="false" />
<option name="NETWORK_SPEED" value="full" />
<option name="NETWORK_LATENCY" value="none" />
<option name="CLEAR_LOGCAT" value="false" />
<method />
</configuration>
<configuration default="true" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" />
<option name="VM_PARAMETERS" />
<option name="PROGRAM_PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<module name="" />
<envs />
<method />
</configuration>
<configuration default="true" type="Applet" factoryName="Applet">
<module name="" />
<option name="MAIN_CLASS_NAME" />
<option name="HTML_FILE_NAME" />
<option name="HTML_USED" value="false" />
<option name="WIDTH" value="400" />
<option name="HEIGHT" value="300" />
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
<option name="VM_PARAMETERS" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<method />
</configuration>
<configuration default="false" name="Dolphin Emulator" type="AndroidRunConfigurationType" factoryName="Android Application">
<module name="Android" />
<option name="ACTIVITY_CLASS" value="" />
<option name="MODE" value="default_activity" />
<option name="DEPLOY" value="true" />
<option name="TARGET_SELECTION_MODE" value="SHOW_DIALOG" />
<option name="PREFERRED_AVD" value="" />
<option name="USE_COMMAND_LINE" value="true" />
<option name="COMMAND_LINE" value="" />
<option name="WIPE_USER_DATA" value="false" />
<option name="DISABLE_BOOT_ANIMATION" value="false" />
<option name="NETWORK_SPEED" value="full" />
<option name="NETWORK_LATENCY" value="none" />
<option name="CLEAR_LOGCAT" value="false" />
<RunnerSettings RunnerId="AndroidDebugRunner" />
<ConfigurationWrapper RunnerId="AndroidDebugRunner" />
<method />
</configuration>
<list size="1">
<item index="0" class="java.lang.String" itemvalue="Android Application.Dolphin Emulator" />
</list>
<configuration name="&lt;template&gt;" type="TestNG" default="true" selected="false">
<option name="MAIN_CLASS_NAME" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
</configuration>
<configuration name="&lt;template&gt;" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
</configuration>
<configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
<Host>localhost</Host>
<Port>5050</Port>
</configuration>
</component>
<component name="ShelveChangesManager" show_recycled="false" />
<component name="SvnConfiguration" maxAnnotateRevisions="500" myUseAcceleration="nothing" myAutoUpdateAfterCommit="false" cleanupOnStartRun="false" SSL_PROTOCOLS="all">
<option name="USER" value="" />
<option name="PASSWORD" value="" />
<option name="mySSHConnectionTimeout" value="30000" />
<option name="mySSHReadTimeout" value="30000" />
<option name="LAST_MERGED_REVISION" />
<option name="MERGE_DRY_RUN" value="false" />
<option name="MERGE_DIFF_USE_ANCESTRY" value="true" />
<option name="UPDATE_LOCK_ON_DEMAND" value="false" />
<option name="IGNORE_SPACES_IN_MERGE" value="false" />
<option name="CHECK_NESTED_FOR_QUICK_MERGE" value="false" />
<option name="IGNORE_SPACES_IN_ANNOTATE" value="true" />
<option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true" />
<option name="FORCE_UPDATE" value="false" />
<option name="IGNORE_EXTERNALS" value="false" />
<myIsUseDefaultProxy>false</myIsUseDefaultProxy>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="682e8195-a9c2-48a7-a941-e8c10f5cb64a" name="Default" comment="" />
<created>1368695084085</created>
<updated>1368695084085</updated>
<workItem from="1368695097983" duration="553000" />
<workItem from="1368695712903" duration="805000" />
<workItem from="1368849359745" duration="3003000" />
<workItem from="1368867565839" duration="1956000" />
<workItem from="1368872339338" duration="8211000" />
<workItem from="1368954925765" duration="561000" />
<workItem from="1368955681290" duration="2332000" />
<workItem from="1368958063194" duration="125000" />
<workItem from="1368958842851" duration="47000" />
<workItem from="1369030521257" duration="6092000" />
<workItem from="1369127738883" duration="3497000" />
<workItem from="1369215536267" duration="2414000" />
<workItem from="1369296443609" duration="7832000" />
<workItem from="1369308108390" duration="81000" />
<workItem from="1369310924441" duration="263000" />
<workItem from="1369391881947" duration="6610000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="47388000" />
</component>
<component name="TodoView" selected-index="0">
<todo-panel id="selected-file">
<are-packages-shown value="false" />
<are-modules-shown value="false" />
<flatten-packages value="false" />
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="all">
<are-packages-shown value="true" />
<are-modules-shown value="false" />
<flatten-packages value="false" />
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="default-changelist">
<are-packages-shown value="false" />
<are-modules-shown value="false" />
<flatten-packages value="false" />
<is-autoscroll-to-source value="false" />
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="24" y="0" width="1342" height="744" extended-state="0" />
<editor active="true" />
<layout>
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3110368" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.17851622" sideWeight="0.6912752" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.30769232" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Build Variants" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="true" content_ui="tabs" />
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32998455" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="4" side_tool="true" content_ui="tabs" />
<window_info id="Android" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.7466443" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Palette&#9;" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.13678516" sideWeight="0.6912752" order="2" side_tool="false" content_ui="tabs" />
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32998326" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.2179289" sideWeight="0.6912752" order="0" side_tool="false" content_ui="combo" />
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32998326" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="3" side_tool="false" content_ui="combo" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32718122" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Preview" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.17619784" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32885906" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
</layout>
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="VcsManagerConfiguration">
<option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
<option name="CHECK_NEW_TODO" value="true" />
<option name="myTodoPanelSettings">
<value>
<are-packages-shown value="false" />
<are-modules-shown value="false" />
<flatten-packages value="false" />
<is-autoscroll-to-source value="false" />
</value>
</option>
<option name="PERFORM_UPDATE_IN_BACKGROUND" value="true" />
<option name="PERFORM_COMMIT_IN_BACKGROUND" value="true" />
<option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
<option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true" />
<option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
<option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false" />
<option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="false" />
<option name="CHANGED_ON_SERVER_INTERVAL" value="60" />
<option name="SHOW_ONLY_CHANGED_IN_SELECTION_DIFF" value="true" />
<option name="CHECK_COMMIT_MESSAGE_SPELLING" value="true" />
<option name="DEFAULT_PATCH_EXTENSION" value="patch" />
<option name="SHORT_DIFF_HORIZONTALLY" value="true" />
<option name="SHORT_DIFF_EXTRA_LINES" value="2" />
<option name="SOFT_WRAPS_IN_SHORT_DIFF" value="true" />
<option name="INCLUDE_TEXT_INTO_PATCH" value="false" />
<option name="INCLUDE_TEXT_INTO_SHELF" value="false" />
<option name="SHOW_FILE_HISTORY_DETAILS" value="true" />
<option name="SHOW_VCS_ERROR_NOTIFICATIONS" value="false" />
<option name="SHOW_DIRTY_RECURSIVELY" value="false" />
<option name="LIMIT_HISTORY" value="true" />
<option name="MAXIMUM_HISTORY_ROWS" value="1000" />
<option name="UPDATE_FILTER_SCOPE_NAME" />
<option name="USE_COMMIT_MESSAGE_MARGIN" value="false" />
<option name="COMMIT_MESSAGE_MARGIN_SIZE" value="72" />
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="false" />
<option name="FORCE_NON_EMPTY_COMMENT" value="false" />
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="false" />
<option name="LAST_COMMIT_MESSAGE" />
<option name="MAKE_NEW_CHANGELIST_ACTIVE" value="false" />
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
<option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
<option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
<option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
<option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
<option name="ACTIVE_VCS_NAME" />
<option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
<option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
<option name="UPDATE_FILTER_BY_SCOPE" value="false" />
<option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
<option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/res/values/prefvalues.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/FolderBrowser.java">
<provider selected="true" editor-type-id="text-editor">
<state line="58" column="30" selection-start="1963" selection-end="1963" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/res/layout/prefs.xml">
<provider editor-type-id="android-designer">
<state />
</provider>
<provider selected="true" editor-type-id="text-editor">
<state line="21" column="41" selection-start="857" selection-end="857" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/GameListItem.java">
<provider selected="true" editor-type-id="text-editor">
<state line="30" column="64" selection-start="729" selection-end="729" vertical-scroll-proportion="-0.42105263" vertical-offset="0" max-vertical-offset="0">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/SideMenuAdapter.java">
<provider selected="true" editor-type-id="text-editor">
<state line="11" column="13" selection-start="267" selection-end="267" vertical-scroll-proportion="0.082167834" vertical-offset="0" max-vertical-offset="0">
<folding />
</state>
</provider>
</entry>
<entry file="jar://$APPLICATION_HOME_DIR$/sdk/platforms/android-17/android.jar!/android/app/Activity.class">
<provider selected="true" editor-type-id="text-editor">
<state line="132" column="0" selection-start="5190" selection-end="5190" vertical-scroll-proportion="2.0" vertical-offset="0" max-vertical-offset="0" />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/res/layout/folderbrowser.xml">
<provider selected="true" editor-type-id="android-designer">
<state />
</provider>
<provider editor-type-id="text-editor">
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="0" />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/res/layout/main.xml">
<provider selected="true" editor-type-id="android-designer">
<state />
</provider>
<provider editor-type-id="text-editor">
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="0" />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/res/layout/folderbrowserfooter.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="0" />
</provider>
<provider editor-type-id="android-designer">
<state />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/DolphinEmulator.java">
<provider selected="true" editor-type-id="text-editor">
<state line="164" column="4" selection-start="4729" selection-end="4729" vertical-scroll-proportion="0.0" vertical-offset="2445" max-vertical-offset="2640">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/GameListView.java">
<provider selected="true" editor-type-id="text-editor">
<state line="51" column="78" selection-start="1629" selection-end="1629" vertical-scroll-proportion="0.0" vertical-offset="750" max-vertical-offset="3420">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/FolderBrowser.java">
<provider selected="true" editor-type-id="text-editor">
<state line="81" column="20" selection-start="2652" selection-end="2652" vertical-scroll-proportion="0.0" vertical-offset="1200" max-vertical-offset="1485">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/res/layout/prefs.xml">
<provider editor-type-id="android-designer">
<state />
</provider>
<provider selected="true" editor-type-id="text-editor">
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="495">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/res/values/prefvalues.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="14" column="31" selection-start="392" selection-end="392" vertical-scroll-proportion="0.0" vertical-offset="195" max-vertical-offset="405">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/org/dolphinemu/dolphinemu/PrefsActivity.java">
<provider selected="true" editor-type-id="text-editor">
<state line="14" column="0" selection-start="389" selection-end="389" vertical-scroll-proportion="0.0" vertical-offset="195" max-vertical-offset="690">
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/AndroidManifest.xml">
<provider selected="true" editor-type-id="text-editor">
<state line="6" column="39" selection-start="248" selection-end="248" vertical-scroll-proportion="0.026223777" vertical-offset="75" max-vertical-offset="735">
<folding />
</state>
</provider>
</entry>
</component>
</project>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Dolphin Emulator">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="library" />
</component>
</module>

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.dolphinemu.dolphinemu" package="org.dolphinemu.dolphinemu"
android:versionCode="2" android:versionCode="5"
android:versionName="0.2" > android:versionName="0.5" >
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14"/> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14"/>
@ -28,15 +28,16 @@
<activity <activity
android:name="org.dolphinemu.dolphinemu.GameListView" android:name="org.dolphinemu.dolphinemu.GameListView"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@android:style/Theme"
android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" > android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" >
</activity> </activity>
<activity <activity
android:name="org.dolphinemu.dolphinemu.FolderBrowser" android:name="org.dolphinemu.dolphinemu.FolderBrowser"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@android:style/Theme"
android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" > android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" >
</activity> </activity>
<activity
android:name=".PrefsActivity" >
</activity>
</application> </application>
</manifest> </manifest>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
>
<PreferenceCategory
android:summary="Settings"
android:title="CPU Settings" >
<ListPreference
android:entries="@array/cpuOptions"
android:entryValues="@array/cpuValues"
android:key="cpupref"
android:summary="Emulation core to use"
android:title="CPU Core" />
<CheckBoxPreference
android:key="dualcorepref"
android:summary="On/Off"
android:title="Dual Core" />
</PreferenceCategory>
<PreferenceCategory
android:summary="Settings"
android:title="Video Settings" >
<ListPreference
android:entries="@array/gpuOptions"
android:entryValues="@array/gpuValues"
android:key="gpupref"
android:summary="Video backend to use"
android:title="Video Backend" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="cpuOptions">
<item>Interpreter</item>
<item>ARM JIT Recompiler</item>
</string-array>
<string-array name="cpuValues">
<item>0</item>
<item>3</item>
</string-array>
<string-array name="gpuOptions">
<item>Software Renderer</item>
<item>OpenGL</item>
</string-array>
<string-array name="gpuValues">
<item>Software Renderer</item>
<item>OGL</item>
</string-array>
</resources>

View file

@ -1,13 +1,5 @@
package org.dolphinemu.dolphinemu; package org.dolphinemu.dolphinemu;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import net.simonvt.menudrawer.MenuDrawer;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -18,6 +10,8 @@ import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.WindowManager; import android.view.WindowManager;
import java.io.*;
public class DolphinEmulator<MainActivity> extends Activity public class DolphinEmulator<MainActivity> extends Activity
{ {
static private NativeGLSurfaceView GLview = null; static private NativeGLSurfaceView GLview = null;
@ -143,7 +137,7 @@ public class DolphinEmulator<MainActivity> extends Activity
String FileName = data.getStringExtra("Select"); String FileName = data.getStringExtra("Select");
GLview = new NativeGLSurfaceView(this); GLview = new NativeGLSurfaceView(this);
//this.getWindow().setUiOptions(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN, View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN); this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
GLview.SetDimensions(screenWidth, screenHeight); GLview.SetDimensions(screenWidth, screenHeight);
GLview.SetFileName(FileName); GLview.SetFileName(FileName);
setContentView(GLview); setContentView(GLview);
@ -169,7 +163,7 @@ public class DolphinEmulator<MainActivity> extends Activity
return false; return false;
} }
public boolean overrideKeys() public boolean overrideKeys()
{ {
return false; return false;
} }

View file

@ -1,29 +1,19 @@
package org.dolphinemu.dolphinemu; package org.dolphinemu.dolphinemu;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.simonvt.menudrawer.MenuDrawer;
import android.app.Activity; import android.app.Activity;
import android.app.ListActivity; import android.app.ListActivity;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.view.Gravity; import android.view.Menu;
import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class FolderBrowser extends ListActivity { public class FolderBrowser extends ListActivity {
private GameListAdapter adapter; private GameListAdapter adapter;
@ -59,8 +49,8 @@ public class FolderBrowser extends ListActivity {
Collections.sort(dir); Collections.sort(dir);
Collections.sort(fls); Collections.sort(fls);
dir.addAll(fls); dir.addAll(fls);
if (!f.getName().equalsIgnoreCase("sdcard")) if (!f.getPath().equalsIgnoreCase("/"))
dir.add(0, new GameListItem(getApplicationContext(), "..", "Parent Directory", f.getParent())); dir.add(0, new GameListItem(getApplicationContext(), "..", "Parent Directory", f.getParent()));
adapter = new GameListAdapter(this,R.layout.folderbrowser,dir); adapter = new GameListAdapter(this,R.layout.folderbrowser,dir);
this.setListAdapter(adapter); this.setListAdapter(adapter);
@ -68,7 +58,6 @@ public class FolderBrowser extends ListActivity {
@Override @Override
protected void onListItemClick(ListView l, View v, int position, long id) { protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id); super.onListItemClick(l, v, position, id);
GameListItem o = adapter.getItem(position); GameListItem o = adapter.getItem(position);
if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){ if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){
@ -87,12 +76,18 @@ public class FolderBrowser extends ListActivity {
Fill(currentDir); Fill(currentDir);
} }
@Override @Override
public void onBackPressed() { public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("Add current folder");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.putExtra("Select", currentDir.getPath()); intent.putExtra("Select", currentDir.getPath());
setResult(Activity.RESULT_OK, intent); setResult(Activity.RESULT_OK, intent);
this.finish(); this.finish();
super.onBackPressed(); return true;
} }
} }

View file

@ -1,85 +1,79 @@
package org.dolphinemu.dolphinemu; package org.dolphinemu.dolphinemu;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import net.simonvt.menudrawer.MenuDrawer;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import net.simonvt.menudrawer.MenuDrawer;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class GameListView extends ListActivity { public class GameListView extends ListActivity {
private GameListAdapter adapter; private GameListAdapter adapter;
private static File currentDir = null;
private MenuDrawer mDrawer; private MenuDrawer mDrawer;
private SideMenuAdapter mAdapter; private SideMenuAdapter mAdapter;
private ListView mList;
private static GameListView me; private static GameListView me;
public static native String GetConfig(String Key, String Value, String Default); public static native String GetConfig(String Key, String Value, String Default);
public static native void SetConfig(String Key, String Value, String Default); public static native void SetConfig(String Key, String Value, String Default);
private void Fill(File f) enum keyTypes {TYPE_STRING, TYPE_BOOL};
private void Fill()
{ {
File[]dirs = f.listFiles();
this.setTitle("Game List"); this.setTitle("Game List");
List<GameListItem>dir = new ArrayList<GameListItem>();
List<GameListItem>fls = new ArrayList<GameListItem>(); List<GameListItem>fls = new ArrayList<GameListItem>();
String Directories = GetConfig("General", "GCMPathes", "0");
try int intDirectories = Integer.parseInt(Directories);
for (int a = 0; a < intDirectories; ++a)
{ {
for(File ff: dirs) String BrowseDir = GetConfig("General", "GCMPath" + Integer.toString(a), "");
File currentDir = new File(BrowseDir);
File[]dirs = currentDir.listFiles();
try
{ {
if (ff.getName().charAt(0) != '.') for(File ff: dirs)
if(!ff.isDirectory()) {
if (ff.getName().toLowerCase().contains(".gcm") || if (ff.getName().charAt(0) != '.')
ff.getName().toLowerCase().contains(".iso") || if(!ff.isDirectory())
ff.getName().toLowerCase().contains(".wbfs") || if (ff.getName().toLowerCase().contains(".gcm") ||
ff.getName().toLowerCase().contains(".gcz") || ff.getName().toLowerCase().contains(".iso") ||
ff.getName().toLowerCase().contains(".dol") || ff.getName().toLowerCase().contains(".wbfs") ||
ff.getName().toLowerCase().contains(".elf")) ff.getName().toLowerCase().contains(".gcz") ||
fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath())); ff.getName().toLowerCase().contains(".dol") ||
} ff.getName().toLowerCase().contains(".elf") ||
} ff.getName().toLowerCase().contains(".dff"))
catch(Exception e) fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath()));
{ }
} }
catch(Exception ignored)
{
}
}
Collections.sort(fls);
Collections.sort(dir); adapter = new GameListAdapter(this,R.layout.main, fls);
Collections.sort(fls); this.setListAdapter(adapter);
dir.addAll(fls);
adapter = new GameListAdapter(this,R.layout.main,dir);
this.setListAdapter(adapter);
} }
@Override @Override
protected void onListItemClick(ListView l, View v, int position, long id) { protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id); super.onListItemClick(l, v, position, id);
GameListItem o = adapter.getItem(position); GameListItem o = adapter.getItem(position);
if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){ if(!(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")))
} {
else
{
onFileClick(o.getPath()); onFileClick(o.getPath());
} }
} }
@ -99,16 +93,66 @@ public class GameListView extends ListActivity {
{ {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) switch (requestCode)
{ {
String FileName = data.getStringExtra("Select"); // Browse
Toast.makeText(this, "Folder Selected: " + FileName, Toast.LENGTH_SHORT).show(); case 1:
SetConfig("General", "GCMPathes", "1"); if (resultCode == Activity.RESULT_OK)
SetConfig("General", "GCMPaths0", FileName); {
String FileName = data.getStringExtra("Select");
Toast.makeText(this, "Folder Selected: " + FileName, Toast.LENGTH_SHORT).show();
String Directories = GetConfig("General", "GCMPathes", "0");
int intDirectories = Integer.parseInt(Directories);
Directories = Integer.toString(intDirectories + 1);
SetConfig("General", "GCMPathes", Directories);
SetConfig("General", "GCMPath" + Integer.toString(intDirectories), FileName);
currentDir = new File(FileName); Fill();
Fill(currentDir); }
} break;
// Settings
case 2:
String Keys[] = {
"cpupref",
"dualcorepref",
"gpupref",
};
String ConfigKeys[] = {
"Core-CPUCore",
"Core-CPUThread",
"Core-GFXBackend",
};
keyTypes KeysTypes[] = {
keyTypes.TYPE_STRING,
keyTypes.TYPE_BOOL,
keyTypes.TYPE_STRING,
};
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
// Set our preferences here
for (int a = 0; a < Keys.length; ++a)
{
String ConfigValues[] = ConfigKeys[a].split("-");
String Key = ConfigValues[0];
String Value = ConfigValues[1];
switch(KeysTypes[a])
{
case TYPE_STRING:
String strPref = prefs.getString(Keys[a], "");
SetConfig(Key, Value, strPref);
break;
case TYPE_BOOL:
boolean boolPref = prefs.getBoolean(Keys[a], true);
SetConfig(Key, Value, boolPref ? "True" : "False");
break;
}
}
break;
}
} }
@Override @Override
@ -119,15 +163,14 @@ public class GameListView extends ListActivity {
mDrawer = MenuDrawer.attach(this, MenuDrawer.MENU_DRAG_CONTENT); mDrawer = MenuDrawer.attach(this, MenuDrawer.MENU_DRAG_CONTENT);
String BrowseDir = GetConfig("General", "GCMPaths0", "");
if(currentDir == null) Fill();
currentDir = new File(BrowseDir);
Fill(currentDir);
List<SideMenuItem>dir = new ArrayList<SideMenuItem>(); List<SideMenuItem>dir = new ArrayList<SideMenuItem>();
dir.add(new SideMenuItem("Browse Folder", 0)); dir.add(new SideMenuItem("Browse Folder", 0));
dir.add(new SideMenuItem("Settings", 1));
mList = new ListView(this); ListView mList = new ListView(this);
mAdapter = new SideMenuAdapter(this,R.layout.sidemenu,dir); mAdapter = new SideMenuAdapter(this,R.layout.sidemenu,dir);
mList.setAdapter(mAdapter); mList.setAdapter(mAdapter);
mList.setOnItemClickListener(mItemClickListener); mList.setOnItemClickListener(mItemClickListener);
@ -145,6 +188,11 @@ public class GameListView extends ListActivity {
Intent ListIntent = new Intent(me, FolderBrowser.class); Intent ListIntent = new Intent(me, FolderBrowser.class);
startActivityForResult(ListIntent, 1); startActivityForResult(ListIntent, 1);
break; break;
case 1:
Toast.makeText(me, "Loading up settings", Toast.LENGTH_SHORT).show();
Intent SettingIntent = new Intent(me, PrefsActivity.class);
startActivityForResult(SettingIntent, 2);
break;
default: default:
break; break;
} }
@ -157,25 +205,18 @@ public class GameListView extends ListActivity {
mDrawer.setContentView(layoutResID); mDrawer.setContentView(layoutResID);
onContentChanged(); onContentChanged();
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawer.toggleMenu();
return true;
}
return super.onOptionsItemSelected(item); @Override
} public boolean onKeyUp(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.KEYCODE_MENU|| event.getAction() == KeyEvent.KEYCODE_BACK) {
@Override final int drawerState = mDrawer.getDrawerState();
public void onBackPressed() { if (drawerState == MenuDrawer.STATE_OPEN || drawerState == MenuDrawer.STATE_OPENING) {
final int drawerState = mDrawer.getDrawerState(); mDrawer.closeMenu();
if (drawerState == MenuDrawer.STATE_OPEN || drawerState == MenuDrawer.STATE_OPENING) { return true;
mDrawer.closeMenu(); }
return; mDrawer.openMenu();
} return true;
}
super.onBackPressed(); return false;
} }
} }

View file

@ -0,0 +1,40 @@
package org.dolphinemu.dolphinemu;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2
* Refer to the license.txt file included.
*/
public class PrefsActivity extends PreferenceActivity {
public class PrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.layout.prefs);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content,
new PrefsFragment()).commit();
}
@Override
public void onBackPressed() {
Intent intent = new Intent();
setResult(Activity.RESULT_OK, intent);
this.finish();
super.onBackPressed();
}
}

View file

@ -1,5 +1,11 @@
package org.dolphinemu.dolphinemu; package org.dolphinemu.dolphinemu;
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2
* Refer to the license.txt file included.
*/
public class SideMenuItem implements Comparable<SideMenuItem>{ public class SideMenuItem implements Comparable<SideMenuItem>{
private String m_name; private String m_name;
private int m_id; private int m_id;

View file

@ -124,6 +124,17 @@ void OpenALStream::SoundLoop()
{ {
Common::SetCurrentThreadName("Audio thread - openal"); Common::SetCurrentThreadName("Audio thread - openal");
bool surround_capable = Core::g_CoreStartupParameter.bDPL2Decoder;
#if defined(__APPLE__)
bool float32_capable = false;
const ALenum AL_FORMAT_STEREO_FLOAT32 = 0;
// OSX does not have the alext AL_FORMAT_51CHN32 yet.
surround_capable = false;
const ALenum AL_FORMAT_51CHN32 = 0;
#else
bool float32_capable = true;
#endif
u32 ulFrequency = m_mixer->GetSampleRate(); u32 ulFrequency = m_mixer->GetSampleRate();
numBuffers = Core::g_CoreStartupParameter.iLatency + 2; // OpenAL requires a minimum of two buffers numBuffers = Core::g_CoreStartupParameter.iLatency + 2; // OpenAL requires a minimum of two buffers
@ -136,16 +147,14 @@ void OpenALStream::SoundLoop()
alGenSources(1, &uiSource); alGenSources(1, &uiSource);
// Short Silence // Short Silence
memset(sampleBuffer, 0, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * numBuffers); memset(sampleBuffer, 0, OAL_MAX_SAMPLES * numBuffers * FRAME_SURROUND_FLOAT);
memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * 4); memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * FRAME_STEREO_SHORT);
for (int i = 0; i < numBuffers; i++) for (int i = 0; i < numBuffers; i++)
{ {
#if !defined(__APPLE__) if (surround_capable)
if (Core::g_CoreStartupParameter.bDPL2Decoder) alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * FRAME_SURROUND_FLOAT, ulFrequency);
alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
else else
#endif alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * FRAME_STEREO_SHORT, ulFrequency);
alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * 2 * 2, ulFrequency);
} }
alSourceQueueBuffers(uiSource, numBuffers, uiBuffers); alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
alSourcePlay(uiSource); alSourcePlay(uiSource);
@ -170,13 +179,6 @@ void OpenALStream::SoundLoop()
soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28); soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28);
soundTouch.setSetting(SETTING_OVERLAP_MS, 12); soundTouch.setSetting(SETTING_OVERLAP_MS, 12);
bool surround_capable = Core::g_CoreStartupParameter.bDPL2Decoder;
#if defined(__APPLE__)
bool float32_capable = false;
#else
bool float32_capable = true;
#endif
while (!threadData) while (!threadData)
{ {
// num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD. // num_samples_to_render in this update - depends on SystemTimers::AUDIO_DMA_PERIOD.
@ -193,12 +195,9 @@ void OpenALStream::SoundLoop()
numSamples = m_mixer->Mix(realtimeBuffer, numSamples); numSamples = m_mixer->Mix(realtimeBuffer, numSamples);
// Convert the samples from short to float // Convert the samples from short to float
float dest[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS]; float dest[OAL_MAX_SAMPLES * STEREO_CHANNELS];
for (u32 i = 0; i < numSamples; ++i) for (u32 i = 0; i < numSamples * STEREO_CHANNELS; ++i)
{ dest[i] = (float)realtimeBuffer[i] / (1 << 16);
dest[i * 2 + 0] = (float)realtimeBuffer[i * 2 + 0] / (1 << 16);
dest[i * 2 + 1] = (float)realtimeBuffer[i * 2 + 1] / (1 << 16);
}
soundTouch.putSamples(dest, numSamples); soundTouch.putSamples(dest, numSamples);
@ -230,101 +229,94 @@ void OpenALStream::SoundLoop()
} }
} }
unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * OAL_MAX_BUFFERS); unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * numBuffers);
if (nSamples > minSamples) if (nSamples < minSamples)
continue;
// Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer)
if (iBuffersFilled == 0)
{ {
// Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer) alSourceUnqueueBuffers(uiSource, iBuffersProcessed, uiBufferTemp);
if (iBuffersFilled == 0)
{
alSourceUnqueueBuffers(uiSource, iBuffersProcessed, uiBufferTemp);
ALenum err = alGetError();
if (err != 0)
{
ERROR_LOG(AUDIO, "Error unqueuing buffers: %08x", err);
}
}
#if defined(__APPLE__)
// OSX does not have the alext AL_FORMAT_51CHN32 yet.
surround_capable = false;
#else
if (surround_capable)
{
float dpl2[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
dpl2decode(sampleBuffer, nSamples, dpl2);
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
ALenum err = alGetError();
if (err == AL_INVALID_ENUM)
{
// 5.1 is not supported by the host, fallback to stereo
WARN_LOG(AUDIO, "Unable to set 5.1 surround mode. Updating OpenAL Soft might fix this issue.");
surround_capable = false;
}
else if (err != 0)
{
ERROR_LOG(AUDIO, "Error occurred while buffering data: %08x", err);
}
}
#endif
if (!surround_capable)
{
#if !defined(__APPLE__)
if (float32_capable)
{
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO_FLOAT32, sampleBuffer, nSamples * 4 * 2, ulFrequency);
ALenum err = alGetError();
if (err == AL_INVALID_ENUM)
{
float32_capable = false;
}
else if (err != 0)
{
ERROR_LOG(AUDIO, "Error occurred while buffering float32 data: %08x", err);
}
}
#endif
if (!float32_capable)
{
// Convert the samples from float to short
short stereo[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS];
for (u32 i = 0; i < nSamples; ++i)
{
stereo[i * 2 + 0] = (short)((float)sampleBuffer[i * 2 + 0] * (1 << 16));
stereo[i * 2 + 1] = (short)((float)sampleBuffer[i * 2 + 1] * (1 << 16));
}
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo, nSamples * 2 * 2, ulFrequency);
}
}
alSourceQueueBuffers(uiSource, 1, &uiBufferTemp[iBuffersFilled]);
ALenum err = alGetError(); ALenum err = alGetError();
if (err != 0) if (err != 0)
{ {
ERROR_LOG(AUDIO, "Error queuing buffers: %08x", err); ERROR_LOG(AUDIO, "Error unqueuing buffers: %08x", err);
} }
iBuffersFilled++; }
if (iBuffersFilled == numBuffers) if (surround_capable)
{
float dpl2[OAL_MAX_SAMPLES * OAL_MAX_BUFFERS * SURROUND_CHANNELS];
dpl2decode(sampleBuffer, nSamples, dpl2);
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * FRAME_SURROUND_FLOAT, ulFrequency);
ALenum err = alGetError();
if (err == AL_INVALID_ENUM)
{ {
alSourcePlay(uiSource); // 5.1 is not supported by the host, fallback to stereo
err = alGetError(); WARN_LOG(AUDIO, "Unable to set 5.1 surround mode. Updating OpenAL Soft might fix this issue.");
if (err != 0) surround_capable = false;
}
else if (err != 0)
{
ERROR_LOG(AUDIO, "Error occurred while buffering data: %08x", err);
}
}
else
{
if (float32_capable)
{
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO_FLOAT32, sampleBuffer, nSamples * FRAME_STEREO_FLOAT, ulFrequency);
ALenum err = alGetError();
if (err == AL_INVALID_ENUM)
{ {
ERROR_LOG(AUDIO, "Error occurred during playback: %08x", err); float32_capable = false;
}
else if (err != 0)
{
ERROR_LOG(AUDIO, "Error occurred while buffering float32 data: %08x", err);
} }
} }
alGetSourcei(uiSource, AL_SOURCE_STATE, &iState); else
if (iState != AL_PLAYING)
{ {
// Buffer underrun occurred, resume playback // Convert the samples from float to short
alSourcePlay(uiSource); short stereo[OAL_MAX_SAMPLES * STEREO_CHANNELS * OAL_MAX_BUFFERS];
err = alGetError(); for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
if (err != 0) stereo[i] = (short)((float)sampleBuffer[i] * (1 << 16));
{
ERROR_LOG(AUDIO, "Error occurred resuming playback: %08x", err); alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo, nSamples * FRAME_STEREO_SHORT, ulFrequency);
} }
}
alSourceQueueBuffers(uiSource, 1, &uiBufferTemp[iBuffersFilled]);
ALenum err = alGetError();
if (err != 0)
{
ERROR_LOG(AUDIO, "Error queuing buffers: %08x", err);
}
iBuffersFilled++;
if (iBuffersFilled == numBuffers)
{
alSourcePlay(uiSource);
err = alGetError();
if (err != 0)
{
ERROR_LOG(AUDIO, "Error occurred during playback: %08x", err);
}
}
alGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
if (iState != AL_PLAYING)
{
// Buffer underrun occurred, resume playback
alSourcePlay(uiSource);
err = alGetError();
if (err != 0)
{
ERROR_LOG(AUDIO, "Error occurred resuming playback: %08x", err);
} }
} }
} }

View file

@ -30,11 +30,16 @@
#include <soundtouch/STTypes.h> #include <soundtouch/STTypes.h>
// 16 bit Stereo // 16 bit Stereo
#define SFX_MAX_SOURCE 1 #define SFX_MAX_SOURCE 1
#define OAL_MAX_BUFFERS 32 #define OAL_MAX_BUFFERS 32
#define OAL_MAX_SAMPLES 256 #define OAL_MAX_SAMPLES 256
#define SURROUND_CHANNELS 6 // number of channels in surround mode #define STEREO_CHANNELS 2
#define SIZE_FLOAT 4 // size of a float in bytes #define SURROUND_CHANNELS 6 // number of channels in surround mode
#define SIZE_SHORT 2
#define SIZE_FLOAT 4 // size of a float in bytes
#define FRAME_STEREO_SHORT STEREO_CHANNELS * SIZE_SHORT
#define FRAME_STEREO_FLOAT STEREO_CHANNELS * SIZE_FLOAT
#define FRAME_SURROUND_FLOAT SURROUND_CHANNELS * SIZE_FLOAT
#endif #endif
class OpenALStream: public SoundStream class OpenALStream: public SoundStream
@ -61,8 +66,8 @@ private:
std::thread thread; std::thread thread;
Common::Event soundSyncEvent; Common::Event soundSyncEvent;
short realtimeBuffer[OAL_MAX_SAMPLES * 2]; short realtimeBuffer[OAL_MAX_SAMPLES * STEREO_CHANNELS];
soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS]; soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
ALuint uiBuffers[OAL_MAX_BUFFERS]; ALuint uiBuffers[OAL_MAX_BUFFERS];
ALuint uiSource; ALuint uiSource;
ALfloat fVolume; ALfloat fVolume;

View file

@ -87,6 +87,45 @@ inline u64 _rotr64(u64 x, unsigned int shift){
#define snprintf _snprintf #define snprintf _snprintf
#define vscprintf _vscprintf #define vscprintf _vscprintf
// Locale Cross-Compatibility
#define locale_t _locale_t
#define freelocale _free_locale
#define newlocale(mask, locale, base) _create_locale(mask, locale)
#define LC_GLOBAL_LOCALE ((locale_t)-1)
#define LC_ALL_MASK LC_ALL
#define LC_COLLATE_MASK LC_COLLATE
#define LC_CTYPE_MASK LC_CTYPE
#define LC_MONETARY_MASK LC_MONETARY
#define LC_NUMERIC_MASK LC_NUMERIC
#define LC_TIME_MASK LC_TIME
inline locale_t uselocale(locale_t new_locale)
{
// Retrieve the current per thread locale setting
bool bIsPerThread = (_configthreadlocale(0) == _ENABLE_PER_THREAD_LOCALE);
// Retrieve the current thread-specific locale
locale_t old_locale = bIsPerThread ? _get_current_locale() : LC_GLOBAL_LOCALE;
if(new_locale == LC_GLOBAL_LOCALE)
{
// Restore the global locale
_configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
}
else if(new_locale != NULL)
{
// Configure the thread to set the locale only for this thread
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
// Set all locale categories
for(int i = LC_MIN; i <= LC_MAX; i++)
setlocale(i, new_locale->locinfo->lc_category[i].locale);
}
return old_locale;
}
// 64 bit offsets for windows // 64 bit offsets for windows
#define fseeko _fseeki64 #define fseeko _fseeki64
#define ftello _ftelli64 #define ftello _ftelli64

View file

@ -13,61 +13,54 @@ namespace MathUtil
{ {
u32 ClassifyDouble(double dvalue) u32 ClassifyDouble(double dvalue)
{ {
// TODO: Optimize the below to be as fast as possible. // TODO: Optimize the below to be as fast as possible.
IntDouble value; u64 exp = *(u64*)(&dvalue) & DOUBLE_EXP;
value.d = dvalue; if (exp != DOUBLE_ZERO && exp != DOUBLE_EXP)
u64 sign = value.i & DOUBLE_SIGN; {
u64 exp = value.i & DOUBLE_EXP; // Nice normalized number.
if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP) return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
{ }
// Nice normalized number. else
return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; {
} if (*(u64*)(&dvalue) & DOUBLE_FRAC)
else {
{ if (exp)
u64 mantissa = value.i & DOUBLE_FRAC; {
if (mantissa) return PPC_FPCLASS_QNAN;
{ }
if (exp) else
{ {
return PPC_FPCLASS_QNAN; // Denormalized number.
} return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
else }
{ }
// Denormalized number. else if (exp)
return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; {
} //Infinite
} return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
else if (exp) }
{ else
//Infinite {
return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; //Zero
} return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
else }
{ }
//Zero }
return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
}
}
}
u32 ClassifyFloat(float fvalue) u32 ClassifyFloat(float fvalue)
{ {
// TODO: Optimize the below to be as fast as possible. // TODO: Optimize the below to be as fast as possible.
IntFloat value; u32 exp = *(u32*)(&fvalue) & FLOAT_EXP;
value.f = fvalue;
u32 sign = value.i & FLOAT_SIGN;
u32 exp = value.i & FLOAT_EXP;
if (exp > FLOAT_ZERO && exp < FLOAT_EXP) if (exp > FLOAT_ZERO && exp < FLOAT_EXP)
{ {
// Nice normalized number. // Nice normalized number.
return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN; return *(u32*)(&fvalue) & FLOAT_SIGN ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
} }
else else
{ {
u32 mantissa = value.i & FLOAT_FRAC; if (*(u32*)(&fvalue) & FLOAT_FRAC)
if (mantissa)
{ {
if (exp) if (exp)
{ {
@ -76,18 +69,18 @@ u32 ClassifyFloat(float fvalue)
else else
{ {
// Denormalized number. // Denormalized number.
return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD; return *(u32*)(&fvalue) & FLOAT_SIGN ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
} }
} }
else if (exp) else if (exp)
{ {
// Infinite // Infinite
return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF; return *(u32*)(&fvalue) & FLOAT_SIGN ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
} }
else else
{ {
//Zero //Zero
return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ; return *(u32*)(&fvalue) & FLOAT_SIGN ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
} }
} }
} }

View file

@ -9,7 +9,7 @@
#include "../../../Plugins/Plugin_VideoDX9/Src/VideoBackend.h" #include "../../../Plugins/Plugin_VideoDX9/Src/VideoBackend.h"
#include "../../../Plugins/Plugin_VideoDX11/Src/VideoBackend.h" #include "../../../Plugins/Plugin_VideoDX11/Src/VideoBackend.h"
#endif #endif
#ifndef USE_GLES #if !defined(USE_GLES) || USE_GLES3
#include "../../../Plugins/Plugin_VideoOGL/Src/VideoBackend.h" #include "../../../Plugins/Plugin_VideoOGL/Src/VideoBackend.h"
#endif #endif
#include "../../../Plugins/Plugin_VideoSoftware/Src/VideoBackend.h" #include "../../../Plugins/Plugin_VideoSoftware/Src/VideoBackend.h"
@ -45,7 +45,7 @@ void VideoBackend::PopulateList()
if (IsGteVista()) if (IsGteVista())
g_available_video_backends.push_back(backends[0] = new DX11::VideoBackend); g_available_video_backends.push_back(backends[0] = new DX11::VideoBackend);
#endif #endif
#ifndef USE_GLES #if !defined(USE_GLES) || USE_GLES3
g_available_video_backends.push_back(backends[1] = new OGL::VideoBackend); g_available_video_backends.push_back(backends[1] = new OGL::VideoBackend);
#endif #endif
g_available_video_backends.push_back(backends[3] = new SW::VideoSoftware); g_available_video_backends.push_back(backends[3] = new SW::VideoSoftware);

View file

@ -111,6 +111,7 @@ set(SRCS Src/ActionReplay.cpp
Src/HW/SI.cpp Src/HW/SI.cpp
Src/HW/SI_DeviceAMBaseboard.cpp Src/HW/SI_DeviceAMBaseboard.cpp
Src/HW/SI_Device.cpp Src/HW/SI_Device.cpp
Src/HW/SI_DeviceDanceMat.cpp
Src/HW/SI_DeviceGBA.cpp Src/HW/SI_DeviceGBA.cpp
Src/HW/SI_DeviceGCController.cpp Src/HW/SI_DeviceGCController.cpp
Src/HW/SI_DeviceGCSteeringWheel.cpp Src/HW/SI_DeviceGCSteeringWheel.cpp
@ -216,7 +217,7 @@ endif()
set(LIBS bdisasm inputcommon videosoftware sfml-network) set(LIBS bdisasm inputcommon videosoftware sfml-network)
if(NOT USE_GLES) if(NOT USE_GLES OR USE_GLES3)
set(LIBS ${LIBS} videoogl) set(LIBS ${LIBS} videoogl)
endif() endif()

View file

@ -298,6 +298,7 @@
<ClCompile Include="Src\HW\SI.cpp" /> <ClCompile Include="Src\HW\SI.cpp" />
<ClCompile Include="Src\HW\SI_Device.cpp" /> <ClCompile Include="Src\HW\SI_Device.cpp" />
<ClCompile Include="Src\HW\SI_DeviceAMBaseboard.cpp" /> <ClCompile Include="Src\HW\SI_DeviceAMBaseboard.cpp" />
<ClCompile Include="Src\HW\SI_DeviceDanceMat.cpp" />
<ClCompile Include="Src\HW\SI_DeviceGBA.cpp" /> <ClCompile Include="Src\HW\SI_DeviceGBA.cpp" />
<ClCompile Include="Src\HW\SI_DeviceGCController.cpp" /> <ClCompile Include="Src\HW\SI_DeviceGCController.cpp" />
<ClCompile Include="Src\HW\SI_DeviceGCSteeringWheel.cpp" /> <ClCompile Include="Src\HW\SI_DeviceGCSteeringWheel.cpp" />
@ -498,6 +499,7 @@
<ClInclude Include="Src\HW\SI.h" /> <ClInclude Include="Src\HW\SI.h" />
<ClInclude Include="Src\HW\SI_Device.h" /> <ClInclude Include="Src\HW\SI_Device.h" />
<ClInclude Include="Src\HW\SI_DeviceAMBaseboard.h" /> <ClInclude Include="Src\HW\SI_DeviceAMBaseboard.h" />
<ClInclude Include="Src\HW\SI_DeviceDanceMat.h" />
<ClInclude Include="Src\HW\SI_DeviceGBA.h" /> <ClInclude Include="Src\HW\SI_DeviceGBA.h" />
<ClInclude Include="Src\HW\SI_DeviceGCController.h" /> <ClInclude Include="Src\HW\SI_DeviceGCController.h" />
<ClInclude Include="Src\HW\SI_DeviceGCSteeringWheel.h" /> <ClInclude Include="Src\HW\SI_DeviceGCSteeringWheel.h" />

View file

@ -289,6 +289,9 @@
<ClCompile Include="Src\HW\SI_DeviceGCSteeringWheel.cpp"> <ClCompile Include="Src\HW\SI_DeviceGCSteeringWheel.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter> <Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Src\HW\SI_DeviceDanceMat.cpp">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClCompile>
<ClCompile Include="Src\HW\VideoInterface.cpp"> <ClCompile Include="Src\HW\VideoInterface.cpp">
<Filter>HW %28Flipper/Hollywood%29\VI - Video Interface</Filter> <Filter>HW %28Flipper/Hollywood%29\VI - Video Interface</Filter>
</ClCompile> </ClCompile>
@ -810,6 +813,9 @@
<ClInclude Include="Src\HW\SI_DeviceGCSteeringWheel.h"> <ClInclude Include="Src\HW\SI_DeviceGCSteeringWheel.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter> <Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Src\HW\SI_DeviceDanceMat.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude>
<ClInclude Include="Src\HW\SI.h"> <ClInclude Include="Src\HW\SI.h">
<Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter> <Filter>HW %28Flipper/Hollywood%29\SI - Serial Interface</Filter>
</ClInclude> </ClInclude>

View file

@ -60,6 +60,7 @@ bool BootCore(const std::string& _rFilename)
StartUp.m_BootType = SCoreStartupParameter::BOOT_ISO; StartUp.m_BootType = SCoreStartupParameter::BOOT_ISO;
StartUp.m_strFilename = _rFilename; StartUp.m_strFilename = _rFilename;
SConfig::GetInstance().m_LastFilename = _rFilename; SConfig::GetInstance().m_LastFilename = _rFilename;
SConfig::GetInstance().SaveSettings();
StartUp.bRunCompareClient = false; StartUp.bRunCompareClient = false;
StartUp.bRunCompareServer = false; StartUp.bRunCompareServer = false;
@ -108,20 +109,6 @@ bool BootCore(const std::string& _rFilename)
game_ini.Get("Core", "HLE_BS2", &StartUp.bHLE_BS2, StartUp.bHLE_BS2); game_ini.Get("Core", "HLE_BS2", &StartUp.bHLE_BS2, StartUp.bHLE_BS2);
VideoBackend::ActivateBackend(StartUp.m_strVideoBackend); VideoBackend::ActivateBackend(StartUp.m_strVideoBackend);
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
{
StartUp.bCPUThread = Movie::IsDualCore();
StartUp.bSkipIdle = Movie::IsSkipIdle();
StartUp.bDSPHLE = Movie::IsDSPHLE();
StartUp.bProgressive = Movie::IsProgressive();
StartUp.bFastDiscSpeed = Movie::IsFastDiscSpeed();
StartUp.iCPUCore = Movie::GetCPUMode();
if (Movie::IsUsingMemcard() && Movie::IsStartingFromClearSave() && !StartUp.bWii)
{
if (File::Exists("Movie.raw"))
File::Delete("Movie.raw");
}
}
// Wii settings // Wii settings
if (StartUp.bWii) if (StartUp.bWii)
{ {
@ -130,6 +117,22 @@ bool BootCore(const std::string& _rFilename)
} }
} }
// movie settings
if (Movie::IsPlayingInput() && Movie::IsConfigSaved())
{
StartUp.bCPUThread = Movie::IsDualCore();
StartUp.bSkipIdle = Movie::IsSkipIdle();
StartUp.bDSPHLE = Movie::IsDSPHLE();
StartUp.bProgressive = Movie::IsProgressive();
StartUp.bFastDiscSpeed = Movie::IsFastDiscSpeed();
StartUp.iCPUCore = Movie::GetCPUMode();
if (Movie::IsUsingMemcard() && Movie::IsStartingFromClearSave() && !StartUp.bWii)
{
if (File::Exists("Movie.raw"))
File::Delete("Movie.raw");
}
}
// Run the game // Run the game
// Init the core // Init the core
if (!Core::Init()) if (!Core::Init())

View file

@ -35,6 +35,7 @@ static const struct {
{ "ToggleFullscreen", 70 /* 'F' */, 2 /* wxMOD_CMD */ }, { "ToggleFullscreen", 70 /* 'F' */, 2 /* wxMOD_CMD */ },
{ "Screenshot", 83 /* 'S' */, 2 /* wxMOD_CMD */ }, { "Screenshot", 83 /* 'S' */, 2 /* wxMOD_CMD */ },
{ "Exit", 0, 0 /* wxMOD_NONE */ },
{ "Wiimote1Connect", 49 /* '1' */, 2 /* wxMOD_CMD */ }, { "Wiimote1Connect", 49 /* '1' */, 2 /* wxMOD_CMD */ },
{ "Wiimote2Connect", 50 /* '2' */, 2 /* wxMOD_CMD */ }, { "Wiimote2Connect", 50 /* '2' */, 2 /* wxMOD_CMD */ },
@ -57,6 +58,7 @@ static const struct {
{ "ToggleFullscreen", 13 /* WXK_RETURN */, 1 /* wxMOD_ALT */ }, { "ToggleFullscreen", 13 /* WXK_RETURN */, 1 /* wxMOD_ALT */ },
{ "Screenshot", 348 /* WXK_F9 */, 0 /* wxMOD_NONE */ }, { "Screenshot", 348 /* WXK_F9 */, 0 /* wxMOD_NONE */ },
{ "Exit", 0, 0 /* wxMOD_NONE */ },
{ "Wiimote1Connect", 344 /* WXK_F5 */, 1 /* wxMOD_ALT */ }, { "Wiimote1Connect", 344 /* WXK_F5 */, 1 /* wxMOD_ALT */ },
{ "Wiimote2Connect", 345 /* WXK_F6 */, 1 /* wxMOD_ALT */ }, { "Wiimote2Connect", 345 /* WXK_F6 */, 1 /* wxMOD_ALT */ },
@ -81,6 +83,19 @@ static const struct {
{ "SaveStateSlot6", 345 /* WXK_F6 */, 4 /* wxMOD_SHIFT */ }, { "SaveStateSlot6", 345 /* WXK_F6 */, 4 /* wxMOD_SHIFT */ },
{ "SaveStateSlot7", 346 /* WXK_F7 */, 4 /* wxMOD_SHIFT */ }, { "SaveStateSlot7", 346 /* WXK_F7 */, 4 /* wxMOD_SHIFT */ },
{ "SaveStateSlot8", 347 /* WXK_F8 */, 4 /* wxMOD_SHIFT */ }, { "SaveStateSlot8", 347 /* WXK_F8 */, 4 /* wxMOD_SHIFT */ },
{ "LoadLastState1", 0, 0 /* wxMOD_NONE */ },
{ "LoadLastState2", 0, 0 /* wxMOD_NONE */ },
{ "LoadLastState3", 0, 0 /* wxMOD_NONE */ },
{ "LoadLastState4", 0, 0 /* wxMOD_NONE */ },
{ "LoadLastState5", 0, 0 /* wxMOD_NONE */ },
{ "LoadLastState6", 0, 0 /* wxMOD_NONE */ },
{ "LoadLastState7", 0, 0 /* wxMOD_NONE */ },
{ "LoadLastState8", 0, 0 /* wxMOD_NONE */ },
{ "SaveFirstState", 0, 0 /* wxMOD_NONE */ },
{ "UndoLoadState", 351 /* WXK_F12 */, 0 /* wxMOD_NONE */ },
{ "UndoSaveState", 351 /* WXK_F12 */, 4 /* wxMOD_SHIFT */ },
}; };
SConfig::SConfig() SConfig::SConfig()
@ -319,7 +334,7 @@ void SConfig::LoadSettings()
// Display // Display
ini.Get("Display", "Fullscreen", &m_LocalCoreStartupParameter.bFullscreen, false); ini.Get("Display", "Fullscreen", &m_LocalCoreStartupParameter.bFullscreen, false);
ini.Get("Display", "FullscreenResolution", &m_LocalCoreStartupParameter.strFullscreenResolution, "640x480"); ini.Get("Display", "FullscreenResolution", &m_LocalCoreStartupParameter.strFullscreenResolution, "Auto");
ini.Get("Display", "RenderToMain", &m_LocalCoreStartupParameter.bRenderToMain, false); ini.Get("Display", "RenderToMain", &m_LocalCoreStartupParameter.bRenderToMain, false);
ini.Get("Display", "RenderWindowXPos", &m_LocalCoreStartupParameter.iRenderWindowXPos, -1); ini.Get("Display", "RenderWindowXPos", &m_LocalCoreStartupParameter.iRenderWindowXPos, -1);
ini.Get("Display", "RenderWindowYPos", &m_LocalCoreStartupParameter.iRenderWindowYPos, -1); ini.Get("Display", "RenderWindowYPos", &m_LocalCoreStartupParameter.iRenderWindowYPos, -1);

View file

@ -394,10 +394,10 @@ void EmuThread()
Wiimote::Initialize(g_pWindowHandle); Wiimote::Initialize(g_pWindowHandle);
// Activate wiimotes which don't have source set to "None" // Activate wiimotes which don't have source set to "None"
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) for (unsigned int i = 0; i != MAX_BBMOTES; ++i)
if (g_wiimote_sources[i]) if (g_wiimote_sources[i])
GetUsbPointer()->AccessWiiMote(i | 0x100)-> GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true);
Activate(true);
} }
// The hardware is initialized. // The hardware is initialized.
@ -680,7 +680,8 @@ void UpdateTitle()
u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime); u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime);
// Settings are shown the same for both extended and summary info // Settings are shown the same for both extended and summary info
std::string SSettings = StringFromFormat("%s %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC"); std::string SSettings = StringFromFormat("%s %s | %s | %s", cpu_core_base->GetName(), _CoreParameter.bCPUThread ? "DC" : "SC",
g_video_backend->GetName().c_str(), _CoreParameter.bDSPHLE ? "HLE" : "LLE");
// Use extended or summary information. The summary information does not print the ticks data, // Use extended or summary information. The summary information does not print the ticks data,
// that's more of a debugging interest, it can always be optional of course if someone is interested. // that's more of a debugging interest, it can always be optional of course if someone is interested.
@ -697,7 +698,7 @@ void UpdateTitle()
float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100; float TicksPercentage = (float)diff / (float)(SystemTimers::GetTicksPerSecond() / 1000000) * 100;
std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed); std::string SFPS = StringFromFormat("FPS: %u - VPS: %u - %u%%", FPS, VPS, Speed);
SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)", SFPS += StringFromFormat(" | CPU: %s%i MHz [Real: %i + IdleSkip: %i] / %i MHz (%s%3.0f%%)",
_CoreParameter.bSkipIdle ? "~" : "", _CoreParameter.bSkipIdle ? "~" : "",
(int)(diff), (int)(diff),
@ -710,11 +711,11 @@ void UpdateTitle()
#else // Summary information #else // Summary information
std::string SFPS; std::string SFPS;
if (Movie::IsPlayingInput()) if (Movie::IsPlayingInput())
SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed); SFPS = StringFromFormat("VI: %u/%u - Frame: %u/%u - FPS: %u - VPS: %u - %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_totalFrames, (u32)Movie::g_currentInputCount, (u32)Movie::g_totalInputCount, FPS, VPS, Speed);
else if (Movie::IsRecordingInput()) else if (Movie::IsRecordingInput())
SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - SPEED: %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed); SFPS = StringFromFormat("VI: %u - Frame: %u - FPS: %u - VPS: %u - %u%%", (u32)Movie::g_currentFrame, (u32)Movie::g_currentInputCount, FPS, VPS, Speed);
else else
SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed); SFPS = StringFromFormat("FPS: %u - VPS: %u - %u%%", FPS, VPS, Speed);
#endif #endif
// This is our final "frame counter" string // This is our final "frame counter" string

View file

@ -26,6 +26,7 @@ enum Hotkey
HK_FULLSCREEN, HK_FULLSCREEN,
HK_SCREENSHOT, HK_SCREENSHOT,
HK_EXIT,
HK_WIIMOTE1_CONNECT, HK_WIIMOTE1_CONNECT,
HK_WIIMOTE2_CONNECT, HK_WIIMOTE2_CONNECT,
@ -50,6 +51,19 @@ enum Hotkey
HK_SAVE_STATE_SLOT_7, HK_SAVE_STATE_SLOT_7,
HK_SAVE_STATE_SLOT_8, HK_SAVE_STATE_SLOT_8,
HK_LOAD_LAST_STATE_1,
HK_LOAD_LAST_STATE_2,
HK_LOAD_LAST_STATE_3,
HK_LOAD_LAST_STATE_4,
HK_LOAD_LAST_STATE_5,
HK_LOAD_LAST_STATE_6,
HK_LOAD_LAST_STATE_7,
HK_LOAD_LAST_STATE_8,
HK_SAVE_FIRST_STATE,
HK_UNDO_LOAD_STATE,
HK_UNDO_SAVE_STATE,
NUM_HOTKEYS, NUM_HOTKEYS,
}; };

View file

@ -170,7 +170,10 @@ void EventDoState(PointerWrap &p, BaseEvent* ev)
// we can't savestate ev->type directly because events might not get registered in the same order (or at all) every time. // we can't savestate ev->type directly because events might not get registered in the same order (or at all) every time.
// so, we savestate the event's type's name, and derive ev->type from that when loading. // so, we savestate the event's type's name, and derive ev->type from that when loading.
std::string name = event_types[ev->type].name; std::string name;
if (p.GetMode() != PointerWrap::MODE_READ)
name = event_types[ev->type].name;
p.Do(name); p.Do(name);
if (p.GetMode() == PointerWrap::MODE_READ) if (p.GetMode() == PointerWrap::MODE_READ)
{ {

View file

@ -137,6 +137,7 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename,
{ {
g_dsp.step_counter = 0; g_dsp.step_counter = 0;
cyclesLeft = 0; cyclesLeft = 0;
init_hax = false;
dspjit = NULL; dspjit = NULL;
g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE); g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE);

View file

@ -246,14 +246,9 @@ static void gdsp_idma_in(u16 dsp_addr, u32 addr, u32 size)
} }
WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
g_dsp.iram_crc = DSPHost_CodeLoaded(g_dsp.cpu_ram + (addr & 0x0fffffff), size); DSPHost_CodeLoaded((const u8*)g_dsp.iram + dsp_addr, size);
NOTICE_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc); NOTICE_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc);
if (dspjit)
dspjit->ClearIRAM();
DSPAnalyzer::Analyze();
} }
static void gdsp_idma_out(u16 dsp_addr, u32 addr, u32 size) static void gdsp_idma_out(u16 dsp_addr, u32 addr, u32 size)

View file

@ -15,7 +15,7 @@ void DSPHost_WriteHostMemory(u8 value, u32 addr);
bool DSPHost_OnThread(); bool DSPHost_OnThread();
bool DSPHost_Wii(); bool DSPHost_Wii();
void DSPHost_InterruptRequest(); void DSPHost_InterruptRequest();
u32 DSPHost_CodeLoaded(const u8 *ptr, int size); void DSPHost_CodeLoaded(const u8 *ptr, int size);
void DSPHost_UpdateDebugger(); void DSPHost_UpdateDebugger();
#endif #endif

View file

@ -1563,6 +1563,7 @@ void DSPEmitter::lsrn(const UDSPInstruction opc)
FixupBranch noShift = J_CC(CC_Z); FixupBranch noShift = J_CC(CC_Z);
//CL gets automatically masked with 0x3f on IA32/AMD64 //CL gets automatically masked with 0x3f on IA32/AMD64
//MOVZX(64, 16, RCX, R(RAX)); //MOVZX(64, 16, RCX, R(RAX));
MOV(64, R(RCX), R(RAX));
//AND(16, R(RCX), Imm16(0x3f)); //AND(16, R(RCX), Imm16(0x3f));
TEST(16, R(RAX), Imm16(0x40)); TEST(16, R(RAX), Imm16(0x40));
FixupBranch shiftLeft = J_CC(CC_Z); FixupBranch shiftLeft = J_CC(CC_Z);

View file

@ -63,6 +63,38 @@ u32 GeckoCode::Code::GetAddress() const
return gcaddress + (use_po ? pointer_address : (base_address & 0xFE000000)); return gcaddress + (use_po ? pointer_address : (base_address & 0xFE000000));
} }
// return true if a code exists
bool GeckoCode::Exist(u32 address, u32 data)
{
std::vector<GeckoCode::Code>::const_iterator
codes_iter = codes.begin(),
codes_end = codes.end();
for (; codes_iter != codes_end; ++codes_iter)
{
if (codes_iter->address == address && codes_iter->data == data)
return true;
}
return false;
}
// return true if the code is identical
bool GeckoCode::Compare(GeckoCode compare) const
{
if (codes.size() != compare.codes.size())
return false;
int exist = 0;
std::vector<GeckoCode::Code>::const_iterator
codes_iter = codes.begin(),
codes_end = codes.end();
for (; codes_iter != codes_end; ++codes_iter)
{
if (compare.Exist(codes_iter->address, codes_iter->data))
exist++;
}
return exist == codes.size();
}
static std::mutex active_codes_lock; static std::mutex active_codes_lock;
// currently running code // currently running code

View file

@ -66,6 +66,9 @@ namespace Gecko
std::vector<std::string> notes; std::vector<std::string> notes;
bool enabled; bool enabled;
bool Compare(GeckoCode compare) const;
bool Exist(u32 address, u32 data);
}; };
void SetActiveCodes(const std::vector<GeckoCode>& gcodes); void SetActiveCodes(const std::vector<GeckoCode>& gcodes);

View file

@ -20,6 +20,7 @@
#include "PowerPC/SignatureDB.h" #include "PowerPC/SignatureDB.h"
#include "PowerPC/PPCSymbolDB.h" #include "PowerPC/PPCSymbolDB.h"
#include "CommonPaths.h" #include "CommonPaths.h"
#include "TextureCacheBase.h"
namespace HLE_Misc namespace HLE_Misc
{ {
@ -310,6 +311,7 @@ void ExecuteDOL(u8* dolFile, u32 fileSize)
} }
PowerPC::ppcState.iCache.Reset(); PowerPC::ppcState.iCache.Reset();
TextureCache::RequestInvalidateTextureCache();
CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer(); CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer();
size_t size = s_Usb->m_WiiMotes.size(); size_t size = s_Usb->m_WiiMotes.size();

View file

@ -687,12 +687,29 @@ void UpdateAudioDMA()
void Do_ARAM_DMA() void Do_ARAM_DMA()
{ {
g_dspState.DSPControl.DMAState = 1; if (g_arDMA.Cnt.count == 32)
CoreTiming::ScheduleEvent_Threadsafe(0, et_GenerateDSPInterrupt, INT_ARAM | (1<<16)); {
// Beyond Good and Evil (GGEE41) sends count 32
// Force an early exception check on large transfers. Fixes RE2 audio. // Lost Kingdoms 2 needs the exception check here in DSP HLE mode
if (g_arDMA.Cnt.count > 2048 && g_arDMA.Cnt.count <= 6144) GenerateDSPInterrupt(INT_ARAM);
CoreTiming::ForceExceptionCheck(100); CoreTiming::ForceExceptionCheck(100);
}
else
{
g_dspState.DSPControl.DMAState = 1;
CoreTiming::ScheduleEvent_Threadsafe(0, et_GenerateDSPInterrupt, INT_ARAM | (1<<16));
// Force an early exception check on large transfers. Fixes RE2 audio.
// NFS:HP2 (<= 6144)
// Viewtiful Joe (<= 6144)
// Sonic Mega Collection (> 2048)
// Paper Mario battles (> 32)
// Mario Super Baseball (> 32)
// Knockout Kings 2003 loading (> 32)
// WWE DOR (> 32)
if (g_arDMA.Cnt.count > 2048 && g_arDMA.Cnt.count <= 6144)
CoreTiming::ForceExceptionCheck(100);
}
// Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks // Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks
if (g_arDMA.Cnt.dir) if (g_arDMA.Cnt.dir)

View file

@ -66,9 +66,8 @@ void CUCode_AX::LoadResamplingCoefficients()
WARN_LOG(DSPHLE, "Loading polyphase resampling coeffs from %s", filename.c_str()); WARN_LOG(DSPHLE, "Loading polyphase resampling coeffs from %s", filename.c_str());
FILE* fp = fopen(filename.c_str(), "rb"); File::IOFile fp(filename, "rb");
fread(m_coeffs, 1, 0x1000, fp); fp.ReadBytes(m_coeffs, 0x1000);
fclose(fp);
for (u32 i = 0; i < 0x800; ++i) for (u32 i = 0; i < 0x800; ++i)
m_coeffs[i] = Common::swap16(m_coeffs[i]); m_coeffs[i] = Common::swap16(m_coeffs[i]);

View file

@ -4,6 +4,8 @@
#include "Common.h" #include "Common.h"
#include "Hash.h" #include "Hash.h"
#include "DSP/DSPAnalyzer.h"
#include "DSP/DSPCore.h"
#include "DSP/DSPHost.h" #include "DSP/DSPHost.h"
#include "DSPSymbols.h" #include "DSPSymbols.h"
#include "DSPLLETools.h" #include "DSPLLETools.h"
@ -45,23 +47,23 @@ void DSPHost_InterruptRequest()
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP); DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
} }
u32 DSPHost_CodeLoaded(const u8 *ptr, int size) void DSPHost_CodeLoaded(const u8 *ptr, int size)
{ {
u32 ector_crc = HashEctor(ptr, size); g_dsp.iram_crc = HashEctor(ptr, size);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
DumpDSPCode(ptr, size, ector_crc); DumpDSPCode(ptr, size, g_dsp.iram_crc);
#endif #endif
DSPSymbols::Clear(); DSPSymbols::Clear();
// Auto load text file - if none just disassemble. // Auto load text file - if none just disassemble.
NOTICE_LOG(DSPLLE, "ector_crc: %08x", ector_crc); NOTICE_LOG(DSPLLE, "g_dsp.iram_crc: %08x", g_dsp.iram_crc);
DSPSymbols::Clear(); DSPSymbols::Clear();
bool success = false; bool success = false;
switch (ector_crc) switch (g_dsp.iram_crc)
{ {
case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Zelda.txt"); break; case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Zelda.txt"); break;
case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Luigi.txt"); break; case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Luigi.txt"); break;
@ -86,7 +88,10 @@ u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
DSPHost_UpdateDebugger(); DSPHost_UpdateDebugger();
return ector_crc; if (dspjit)
dspjit->ClearIRAM();
DSPAnalyzer::Analyze();
} }
void DSPHost_UpdateDebugger() void DSPHost_UpdateDebugger()

View file

@ -16,6 +16,7 @@
#include "Core.h" #include "Core.h"
#include "DSPLLEGlobals.h" // Local #include "DSPLLEGlobals.h" // Local
#include "DSP/DSPHost.h"
#include "DSP/DSPInterpreter.h" #include "DSP/DSPInterpreter.h"
#include "DSP/DSPHWInterface.h" #include "DSP/DSPHWInterface.h"
#include "DSP/disassemble.h" #include "DSP/disassemble.h"
@ -67,7 +68,6 @@ void DSPLLE::DoState(PointerWrap &p)
p.Do(g_dsp.reg_stack[i]); p.Do(g_dsp.reg_stack[i]);
} }
p.Do(g_dsp.iram_crc);
p.Do(g_dsp.step_counter); p.Do(g_dsp.step_counter);
p.Do(g_dsp.ifx_regs); p.Do(g_dsp.ifx_regs);
p.Do(g_dsp.mbox[0]); p.Do(g_dsp.mbox[0]);
@ -75,8 +75,11 @@ void DSPLLE::DoState(PointerWrap &p)
UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
p.DoArray(g_dsp.iram, DSP_IRAM_SIZE); p.DoArray(g_dsp.iram, DSP_IRAM_SIZE);
WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
if (p.GetMode() == PointerWrap::MODE_READ)
DSPHost_CodeLoaded((const u8*)g_dsp.iram, DSP_IRAM_BYTE_SIZE);
p.DoArray(g_dsp.dram, DSP_DRAM_SIZE); p.DoArray(g_dsp.dram, DSP_DRAM_SIZE);
p.Do(cyclesLeft); p.Do(cyclesLeft);
p.Do(init_hax);
p.Do(m_cycle_count); p.Do(m_cycle_count);
bool prevInitMixer = m_InitMixer; bool prevInitMixer = m_InitMixer;

View file

@ -530,6 +530,9 @@ void UpdateInterrupts()
{ {
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DI, false); ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DI, false);
} }
// Required for Summoner: A Goddess Reborn
CoreTiming::ForceExceptionCheck(50);
} }
void GenerateDIInterrupt(DI_InterruptType _DVDInterrupt) void GenerateDIInterrupt(DI_InterruptType _DVDInterrupt)

View file

@ -216,6 +216,11 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis)
mcdFile.Close(); mcdFile.Close();
initDirBatPointers();
}
void GCMemcard::initDirBatPointers()
{
if (BE16(dir.UpdateCounter) > (BE16(dir_backup.UpdateCounter))) if (BE16(dir.UpdateCounter) > (BE16(dir_backup.UpdateCounter)))
{ {
CurrentDir = &dir; CurrentDir = &dir;
@ -1274,6 +1279,7 @@ bool GCMemcard::Format(bool sjis, u16 SizeMb)
mc_data_blocks.push_back(b); mc_data_blocks.push_back(b);
} }
initDirBatPointers();
m_valid = true; m_valid = true;
return Save(); return Save();

View file

@ -171,6 +171,7 @@ private:
u32 ImportGciInternal(FILE* gcih, const char *inputFile, const std::string &outputFile); u32 ImportGciInternal(FILE* gcih, const char *inputFile, const std::string &outputFile);
static void FormatInternal(GCMC_Header &GCP); static void FormatInternal(GCMC_Header &GCP);
void initDirBatPointers() ;
public: public:
GCMemcard(const char* fileName, bool forceCreation=false, bool sjis=false); GCMemcard(const char* fileName, bool forceCreation=false, bool sjis=false);

View file

@ -598,9 +598,6 @@ union UPTE2
u32 Hex; u32 Hex;
}; };
u32 pagetable_base = 0;
u32 pagetable_hashmask = 0;
void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite) void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite)
{ {
if (_bWrite) if (_bWrite)
@ -644,8 +641,8 @@ void SDRUpdated()
{ {
return; return;
} }
pagetable_base = htaborg<<16; PowerPC::ppcState.pagetable_base = htaborg<<16;
pagetable_hashmask = ((xx<<10)|0x3ff); PowerPC::ppcState.pagetable_hashmask = ((xx<<10)|0x3ff);
} }
@ -821,7 +818,7 @@ u32 TranslatePageAddress(const u32 _Address, const XCheckTLBFlag _Flag)
// hash function no 1 "xor" .360 // hash function no 1 "xor" .360
u32 hash1 = (VSID ^ page_index); u32 hash1 = (VSID ^ page_index);
u32 pteg_addr = ((hash1 & pagetable_hashmask) << 6) | pagetable_base; u32 pteg_addr = ((hash1 & PowerPC::ppcState.pagetable_hashmask) << 6) | PowerPC::ppcState.pagetable_base;
// hash1 // hash1
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
@ -856,7 +853,7 @@ u32 TranslatePageAddress(const u32 _Address, const XCheckTLBFlag _Flag)
// hash function no 2 "not" .360 // hash function no 2 "not" .360
hash1 = ~hash1; hash1 = ~hash1;
pteg_addr = ((hash1 & pagetable_hashmask) << 6) | pagetable_base; pteg_addr = ((hash1 & PowerPC::ppcState.pagetable_hashmask) << 6) | PowerPC::ppcState.pagetable_base;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
u32 pte = bswap(*(u32*)&pRAM[pteg_addr]); u32 pte = bswap(*(u32*)&pRAM[pteg_addr]);

View file

@ -5,6 +5,7 @@
#include "SI_Device.h" #include "SI_Device.h"
#include "SI_DeviceGCController.h" #include "SI_DeviceGCController.h"
#include "SI_DeviceGCSteeringWheel.h" #include "SI_DeviceGCSteeringWheel.h"
#include "SI_DeviceDanceMat.h"
#include "SI_DeviceGBA.h" #include "SI_DeviceGBA.h"
#include "SI_DeviceAMBaseboard.h" #include "SI_DeviceAMBaseboard.h"
@ -64,6 +65,10 @@ ISIDevice* SIDevice_Create(const SIDevices device, const int port_number)
return new CSIDevice_GCController(device, port_number); return new CSIDevice_GCController(device, port_number);
break; break;
case SIDEVICE_DANCEMAT:
return new CSIDevice_DanceMat(device, port_number);
break;
case SIDEVICE_GC_STEERING: case SIDEVICE_GC_STEERING:
return new CSIDevice_GCSteeringWheel(device, port_number); return new CSIDevice_GCSteeringWheel(device, port_number);
break; break;

View file

@ -34,6 +34,7 @@ enum TSIDevices
SI_GC_CONTROLLER = (SI_TYPE_GC | SI_GC_STANDARD), SI_GC_CONTROLLER = (SI_TYPE_GC | SI_GC_STANDARD),
SI_GC_KEYBOARD = (SI_TYPE_GC | 0x00200000), SI_GC_KEYBOARD = (SI_TYPE_GC | 0x00200000),
SI_GC_STEERING = SI_TYPE_GC, // (shuffle2)I think the "chainsaw" is the same (Or else it's just standard) SI_GC_STEERING = SI_TYPE_GC, // (shuffle2)I think the "chainsaw" is the same (Or else it's just standard)
SI_DANCEMAT = (SI_TYPE_GC | SI_GC_STANDARD | 0x00000300),
SI_AM_BASEBOARD = 0x10110800 // gets ORd with dipswitch state SI_AM_BASEBOARD = 0x10110800 // gets ORd with dipswitch state
}; };
@ -49,6 +50,7 @@ enum SIDevices
SIDEVICE_GC_CONTROLLER, SIDEVICE_GC_CONTROLLER,
SIDEVICE_GC_KEYBOARD, SIDEVICE_GC_KEYBOARD,
SIDEVICE_GC_STEERING, SIDEVICE_GC_STEERING,
SIDEVICE_DANCEMAT,
SIDEVICE_GC_TARUKONGA, SIDEVICE_GC_TARUKONGA,
SIDEVICE_AM_BASEBOARD SIDEVICE_AM_BASEBOARD
}; };

View file

@ -0,0 +1,264 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include <stdio.h>
#include <stdlib.h>
#include "SI.h"
#include "SI_Device.h"
#include "SI_DeviceDanceMat.h"
#include "EXI_Device.h"
#include "EXI_DeviceMic.h"
#include "GCPad.h"
#include "../Movie.h"
#include "../CoreTiming.h"
#include "SystemTimers.h"
#include "ProcessorInterface.h"
#include "../Core.h"
// --- Dance mat gamecube controller ---
CSIDevice_DanceMat::CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber)
: ISIDevice(device, _iDeviceNumber)
, m_TButtonComboStart(0)
, m_TButtonCombo(0)
, m_LastButtonCombo(COMBO_NONE)
{
memset(&m_Origin, 0, sizeof(SOrigin));
m_Origin.uCommand = CMD_ORIGIN;
m_Origin.uOriginStickX = 0x80; // center
m_Origin.uOriginStickY = 0x80;
m_Origin.uSubStickStickX = 0x80;
m_Origin.uSubStickStickY = 0x80;
m_Origin.uTrigger_L = 0x00;
m_Origin.uTrigger_R = 0x00;
// Dunno if we need to do this, game/lib should set it?
m_Mode = 0x03;
}
int CSIDevice_DanceMat::RunBuffer(u8* _pBuffer, int _iLength)
{
// For debug logging only
ISIDevice::RunBuffer(_pBuffer, _iLength);
// Read the command
EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[3]);
// Handle it
switch (command)
{
case CMD_RESET:
*(u32*)&_pBuffer[0] = SI_DANCEMAT;
break;
case CMD_DIRECT:
{
INFO_LOG(SERIALINTERFACE, "PAD - Direct (Length: %d)", _iLength);
u32 high, low;
GetData(high, low);
for (int i = 0; i < (_iLength - 1) / 2; i++)
{
_pBuffer[0 + i] = (high >> (i * 8)) & 0xff;
_pBuffer[4 + i] = (low >> (i * 8)) & 0xff;
}
}
break;
case CMD_ORIGIN:
{
INFO_LOG(SERIALINTERFACE, "PAD - Get Origin");
u8* pCalibration = reinterpret_cast<u8*>(&m_Origin);
for (int i = 0; i < (int)sizeof(SOrigin); i++)
{
_pBuffer[i ^ 3] = *pCalibration++;
}
}
break;
// Recalibrate (FiRES: i am not 100 percent sure about this)
case CMD_RECALIBRATE:
{
INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate");
u8* pCalibration = reinterpret_cast<u8*>(&m_Origin);
for (int i = 0; i < (int)sizeof(SOrigin); i++)
{
_pBuffer[i ^ 3] = *pCalibration++;
}
}
break;
// DEFAULT
default:
{
ERROR_LOG(SERIALINTERFACE, "Unknown SI command (0x%x)", command);
PanicAlert("SI: Unknown command (0x%x)", command);
}
break;
}
return _iLength;
}
// GetData
// Return true on new data (max 7 Bytes and 6 bits ;)
// [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r]
// |\_ ERR_LATCH (error latched - check SISR)
// |_ ERR_STATUS (error on last GetData or SendCmd?)
bool CSIDevice_DanceMat::GetData(u32& _Hi, u32& _Low)
{
SPADStatus PadStatus;
memset(&PadStatus, 0, sizeof(PadStatus));
Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
Movie::CallInputManip(&PadStatus, ISIDevice::m_iDeviceNumber);
u32 netValues[2];
if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus, netValues))
{
_Hi = netValues[0]; // first 4 bytes
_Low = netValues[1]; // last 4 bytes
return true;
}
Movie::SetPolledDevice();
if(Movie::IsPlayingInput())
{
Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber);
Movie::InputUpdate();
}
else if(Movie::IsRecordingInput())
{
Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber);
Movie::InputUpdate();
}
else
{
Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber);
}
// Map the dpad to the blue arrows, the buttons to the orange arrows
// Z = + button, Start = - button
u16 map = 0;
if (PadStatus.button & PAD_BUTTON_UP)
map |= 0x1000;
if (PadStatus.button & PAD_BUTTON_DOWN)
map |= 0x2;
if (PadStatus.button & PAD_BUTTON_LEFT)
map |= 0x8;
if (PadStatus.button & PAD_BUTTON_RIGHT)
map |= 0x4;
if (PadStatus.button & PAD_BUTTON_Y)
map |= 0x200;
if (PadStatus.button & PAD_BUTTON_A)
map |= 0x10;
if (PadStatus.button & PAD_BUTTON_B)
map |= 0x100;
if (PadStatus.button & PAD_BUTTON_X)
map |= 0x800;
if (PadStatus.button & PAD_TRIGGER_Z)
map |= 0x400;
if (PadStatus.button & PAD_BUTTON_START)
map |= 0x1;
_Hi = (u32)(map << 16) | 0x8080;
// Low bits are packed differently per mode
if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7)
{
_Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits
_Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits
_Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits
_Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits
_Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits
}
else if (m_Mode == 1)
{
_Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits
_Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits
_Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits
_Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits
_Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits
_Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits
}
else if (m_Mode == 2)
{
// Identifies the dance mat
_Low = 0x8080ffff;
}
else if (m_Mode == 3)
{
// Analog A/B are always 0
_Low = (u8)PadStatus.triggerRight; // All 8 bits
_Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits
_Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
}
else if (m_Mode == 4)
{
_Low = (u8)(PadStatus.analogB); // All 8 bits
_Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits
// triggerLeft/Right are always 0
_Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits
_Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits
}
return true;
}
// SendCommand
void CSIDevice_DanceMat::SendCommand(u32 _Cmd, u8 _Poll)
{
UCommand command(_Cmd);
switch (command.Command)
{
// Costis sent it in some demos :)
case 0x00:
break;
case CMD_WRITE:
{
unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard
unsigned int uStrength = command.Parameter2;
// get the correct pad number that should rumble locally when using netplay
const u8 numPAD = NetPlay_GetPadNum(ISIDevice::m_iDeviceNumber);
if (numPAD < 4)
Pad::Rumble(numPAD, uType, uStrength);
if (!_Poll)
{
m_Mode = command.Parameter2;
INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode);
}
}
break;
default:
{
ERROR_LOG(SERIALINTERFACE, "Unknown direct command (0x%x)", _Cmd);
PanicAlert("SI: Unknown direct command");
}
break;
}
}
// Savestate support
void CSIDevice_DanceMat::DoState(PointerWrap& p)
{
p.Do(m_Origin);
p.Do(m_Mode);
p.Do(m_TButtonComboStart);
p.Do(m_TButtonCombo);
p.Do(m_LastButtonCombo);
}

View file

@ -0,0 +1,105 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#ifndef _SI_DEVICEDANCEMAT_H
#define _SI_DEVICEDANCEMAT_H
#include "SI_Device.h"
#include "GCPadStatus.h"
// standard gamecube controller
class CSIDevice_DanceMat : public ISIDevice
{
private:
// Commands
enum EBufferCommands
{
CMD_RESET = 0x00,
CMD_DIRECT = 0x40,
CMD_ORIGIN = 0x41,
CMD_RECALIBRATE = 0x42,
};
struct SOrigin
{
u8 uCommand;// Maybe should be button bits?
u8 unk_1; // ..and this would be the other half
u8 uOriginStickX;
u8 uOriginStickY;
u8 uSubStickStickX;
u8 uSubStickStickY;
u8 uTrigger_L;
u8 uTrigger_R;
u8 unk_4;
u8 unk_5;
u8 unk_6;
u8 unk_7;
};
enum EDirectCommands
{
CMD_WRITE = 0x40
};
union UCommand
{
u32 Hex;
struct
{
u32 Parameter1 : 8;
u32 Parameter2 : 8;
u32 Command : 8;
u32 : 8;
};
UCommand() {Hex = 0;}
UCommand(u32 _iValue) {Hex = _iValue;}
};
enum EButtonCombo
{
COMBO_NONE = 0,
COMBO_ORIGIN,
COMBO_RESET
};
// struct to compare input against
// Set on connection and (standard pad only) on button combo
SOrigin m_Origin;
// PADAnalogMode
u8 m_Mode;
// Timer to track special button combos:
// y, X, start for 3 seconds updates origin with current status
// Technically, the above is only on standard pad, wavebird does not support it for example
// b, x, start for 3 seconds triggers reset (PI reset button interrupt)
u64 m_TButtonComboStart, m_TButtonCombo;
// Type of button combo from the last/current poll
EButtonCombo m_LastButtonCombo;
public:
// Constructor
CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber);
// Run the SI Buffer
virtual int RunBuffer(u8* _pBuffer, int _iLength);
// Send and Receive pad input from network
static bool NetPlay_GetInput(u8 numPAD, SPADStatus status, u32 *PADStatus);
static u8 NetPlay_GetPadNum(u8 numPAD);
// Return true on new data
virtual bool GetData(u32& _Hi, u32& _Low);
// Send a command directly
virtual void SendCommand(u32 _Cmd, u8 _Poll);
// Savestate support
virtual void DoState(PointerWrap& p);
};
#endif

View file

@ -804,11 +804,9 @@ static void BeginField(FieldType field)
u32 fbWidth = m_HorizontalStepping.FieldSteps * 16; u32 fbWidth = m_HorizontalStepping.FieldSteps * 16;
u32 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV; u32 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
// TODO: Are the "Bottom Field" and "Top Field" registers actually more // NTSC and PAL have opposite field orders.
// like "First Field" and "Second Field" registers? There's an important FieldType order = (m_DisplayControlRegister.FMT == 0) ? FIELD_LOWER : FIELD_UPPER;
// difference because NTSC and PAL have opposite field orders. u32 xfbAddr = (field == order) ? GetXFBAddressBottom() : GetXFBAddressTop();
u32 xfbAddr = (field == FIELD_LOWER) ? GetXFBAddressBottom() : GetXFBAddressTop();
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" }; static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };

View file

@ -42,9 +42,10 @@ void Shutdown()
void Initialize(void* const hwnd) void Initialize(void* const hwnd)
{ {
// add 4 wiimotes // add 4 wiimotes
for (unsigned int i = 0; i<4; ++i) for (unsigned int i = WIIMOTE_CHAN_0; i<MAX_BBMOTES; ++i)
g_plugin.controllers.push_back(new WiimoteEmu::Wiimote(i)); g_plugin.controllers.push_back(new WiimoteEmu::Wiimote(i));
g_controller_interface.SetHwnd(hwnd); g_controller_interface.SetHwnd(hwnd);
g_controller_interface.Initialize(); g_controller_interface.Initialize();
@ -134,7 +135,7 @@ void Update(int _number)
unsigned int GetAttached() unsigned int GetAttached()
{ {
unsigned int attached = 0; unsigned int attached = 0;
for (unsigned int i=0; i<4; ++i) for (unsigned int i=0; i<MAX_BBMOTES; ++i)
if (g_wiimote_sources[i]) if (g_wiimote_sources[i])
attached |= (1 << i); attached |= (1 << i);
return attached; return attached;
@ -151,7 +152,7 @@ void DoState(u8 **ptr, PointerWrap::Mode mode)
// TODO: // TODO:
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
for (unsigned int i=0; i<4; ++i) for (unsigned int i=0; i<MAX_BBMOTES; ++i)
((WiimoteEmu::Wiimote*)g_plugin.controllers[i])->DoState(p); ((WiimoteEmu::Wiimote*)g_plugin.controllers[i])->DoState(p);
} }

View file

@ -8,7 +8,16 @@
#include "../../InputCommon/Src/InputConfig.h" #include "../../InputCommon/Src/InputConfig.h"
#include "ChunkFile.h" #include "ChunkFile.h"
#define MAX_WIIMOTES 4 enum {
WIIMOTE_CHAN_0 = 0,
WIIMOTE_CHAN_1,
WIIMOTE_CHAN_2,
WIIMOTE_CHAN_3,
WIIMOTE_BALANCE_BOARD,
MAX_WIIMOTES = WIIMOTE_BALANCE_BOARD,
MAX_BBMOTES = 5,
};
#define WIIMOTE_INI_NAME "WiimoteNew" #define WIIMOTE_INI_NAME "WiimoteNew"
@ -20,7 +29,7 @@ enum
WIIMOTE_SRC_HYBRID = 3, // emu + real WIIMOTE_SRC_HYBRID = 3, // emu + real
}; };
extern unsigned int g_wiimote_sources[MAX_WIIMOTES]; extern unsigned int g_wiimote_sources[MAX_BBMOTES];
namespace Wiimote namespace Wiimote
{ {

View file

@ -72,6 +72,7 @@ void Nunchuk::GetState(u8* const data, const bool focus)
m_stick->GetState(&ncdata->jx, &ncdata->jy, 0x80, focus ? 127 : 0); m_stick->GetState(&ncdata->jx, &ncdata->jy, 0x80, focus ? 127 : 0);
AccelData accel; AccelData accel;
accel_cal* calib = (accel_cal*)&reg[0x20];
// tilt // tilt
EmulateTilt(&accel, m_tilt, focus); EmulateTilt(&accel, m_tilt, focus);
@ -81,7 +82,7 @@ void Nunchuk::GetState(u8* const data, const bool focus)
// swing // swing
EmulateSwing(&accel, m_swing); EmulateSwing(&accel, m_swing);
// shake // shake
EmulateShake(&accel, m_shake, m_shake_step); EmulateShake(&accel, calib, m_shake, m_shake_step);
// buttons // buttons
m_buttons->GetState(&ncdata->bt, nunchuk_button_bitmasks); m_buttons->GetState(&ncdata->bt, nunchuk_button_bitmasks);
} }
@ -119,7 +120,6 @@ void Nunchuk::GetState(u8* const data, const bool focus)
} }
wm_accel* dt = (wm_accel*)&ncdata->ax; wm_accel* dt = (wm_accel*)&ncdata->ax;
accel_cal* calib = (accel_cal*)&reg[0x20];
dt->x = u8(trim(accel.x * (calib->one_g.x - calib->zero_g.x) + calib->zero_g.x)); dt->x = u8(trim(accel.x * (calib->one_g.x - calib->zero_g.x) + calib->zero_g.x));
dt->y = u8(trim(accel.y * (calib->one_g.y - calib->zero_g.y) + calib->zero_g.y)); dt->y = u8(trim(accel.y * (calib->one_g.y - calib->zero_g.y) + calib->zero_g.y));
dt->z = u8(trim(accel.z * (calib->one_g.z - calib->zero_g.z) + calib->zero_g.z)); dt->z = u8(trim(accel.z * (calib->one_g.z - calib->zero_g.z) + calib->zero_g.z));

View file

@ -86,6 +86,7 @@ const ReportFeatures reporting_mode_features[] =
}; };
void EmulateShake(AccelData* const accel void EmulateShake(AccelData* const accel
, accel_cal* const calib
, ControllerEmu::Buttons* const buttons_group , ControllerEmu::Buttons* const buttons_group
, u8* const shake_step ) , u8* const shake_step )
{ {
@ -94,7 +95,7 @@ void EmulateShake(AccelData* const accel
auto const shake_step_max = 15; auto const shake_step_max = 15;
// peak G-force // peak G-force
auto const shake_intensity = 3.f; double shake_intensity;
// shake is a bitfield of X,Y,Z shake button states // shake is a bitfield of X,Y,Z shake button states
static const unsigned int btns[] = { 0x01, 0x02, 0x04 }; static const unsigned int btns[] = { 0x01, 0x02, 0x04 };
@ -105,6 +106,9 @@ void EmulateShake(AccelData* const accel
{ {
if (shake & (1 << i)) if (shake & (1 << i))
{ {
double zero = double((&(calib->zero_g.x))[i]);
double one = double((&(calib->one_g.x))[i]);
shake_intensity = max(zero / (one - zero), (255.f - zero) / (one - zero));
(&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * shake_intensity; (&(accel->x))[i] = std::sin(TAU * shake_step[i] / shake_step_max) * shake_intensity;
shake_step[i] = (shake_step[i] + 1) % shake_step_max; shake_step[i] = (shake_step[i] + 1) % shake_step_max;
} }
@ -406,6 +410,7 @@ void Wiimote::GetAccelData(u8* const data, u8* const buttons)
const bool has_focus = HAS_FOCUS; const bool has_focus = HAS_FOCUS;
const bool is_sideways = m_options->settings[1]->value != 0; const bool is_sideways = m_options->settings[1]->value != 0;
const bool is_upright = m_options->settings[2]->value != 0; const bool is_upright = m_options->settings[2]->value != 0;
accel_cal* calib = (accel_cal*)&m_eeprom[0x16];
// ----TILT---- // ----TILT----
EmulateTilt(&m_accel, m_tilt, has_focus, is_sideways, is_upright); EmulateTilt(&m_accel, m_tilt, has_focus, is_sideways, is_upright);
@ -415,11 +420,10 @@ void Wiimote::GetAccelData(u8* const data, u8* const buttons)
if (has_focus) if (has_focus)
{ {
EmulateSwing(&m_accel, m_swing, is_sideways, is_upright); EmulateSwing(&m_accel, m_swing, is_sideways, is_upright);
EmulateShake(&m_accel, m_shake, m_shake_step); EmulateShake(&m_accel, calib, m_shake, m_shake_step);
UDPTLayer::GetAcceleration(m_udp, &m_accel); UDPTLayer::GetAcceleration(m_udp, &m_accel);
} }
wm_accel* dt = (wm_accel*)data; wm_accel* dt = (wm_accel*)data;
accel_cal* calib = (accel_cal*)&m_eeprom[0x16];
double cx,cy,cz; double cx,cy,cz;
cx=trim(m_accel.x*(calib->one_g.x-calib->zero_g.x)+calib->zero_g.x); cx=trim(m_accel.x*(calib->one_g.x-calib->zero_g.x)+calib->zero_g.x);
cy=trim(m_accel.y*(calib->one_g.y-calib->zero_g.y)+calib->zero_g.y); cy=trim(m_accel.y*(calib->one_g.y-calib->zero_g.y)+calib->zero_g.y);

View file

@ -45,6 +45,7 @@ struct ADPCMState
extern const ReportFeatures reporting_mode_features[]; extern const ReportFeatures reporting_mode_features[];
void EmulateShake(AccelData* const accel_data void EmulateShake(AccelData* const accel_data
, accel_cal* const calib
, ControllerEmu::Buttons* const buttons_group , ControllerEmu::Buttons* const buttons_group
, u8* const shake_step); , u8* const shake_step);

View file

@ -32,9 +32,10 @@ WiimoteScanner::~WiimoteScanner()
void WiimoteScanner::Update() void WiimoteScanner::Update()
{} {}
std::vector<Wiimote*> WiimoteScanner::FindWiimotes() void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
{ {
return std::vector<Wiimote*>(); found_wiimotes.clear();
found_board = NULL;
} }
bool WiimoteScanner::IsReady() const bool WiimoteScanner::IsReady() const

View file

@ -63,23 +63,22 @@ WiimoteScanner::~WiimoteScanner()
void WiimoteScanner::Update() void WiimoteScanner::Update()
{} {}
std::vector<Wiimote*> WiimoteScanner::FindWiimotes() void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
{ {
std::vector<Wiimote*> found_wiimotes;
// supposedly 1.28 seconds // supposedly 1.28 seconds
int const wait_len = 1; int const wait_len = 1;
int const max_infos = 255; int const max_infos = 255;
inquiry_info scan_infos[max_infos] = {}; inquiry_info scan_infos[max_infos] = {};
auto* scan_infos_ptr = scan_infos; auto* scan_infos_ptr = scan_infos;
found_board = NULL;
// Scan for bluetooth devices // Scan for bluetooth devices
int const found_devices = hci_inquiry(device_id, wait_len, max_infos, NULL, &scan_infos_ptr, IREQ_CACHE_FLUSH); int const found_devices = hci_inquiry(device_id, wait_len, max_infos, NULL, &scan_infos_ptr, IREQ_CACHE_FLUSH);
if (found_devices < 0) if (found_devices < 0)
{ {
ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices."); ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices.");
return found_wiimotes; return;
} }
DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices); DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices);
@ -91,7 +90,7 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
// BT names are a maximum of 248 bytes apparently // BT names are a maximum of 248 bytes apparently
char name[255] = {}; char name[255] = {};
if (hci_read_remote_name(device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 0) < 0) if (hci_read_remote_name(device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 1000) < 0)
{ {
ERROR_LOG(WIIMOTE, "name request failed"); ERROR_LOG(WIIMOTE, "name request failed");
continue; continue;
@ -119,14 +118,20 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
auto* const wm = new Wiimote; auto* const wm = new Wiimote;
wm->bdaddr = scan_infos[i].bdaddr; wm->bdaddr = scan_infos[i].bdaddr;
found_wiimotes.push_back(wm); if(IsBalanceBoardName(name))
{
NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str); found_board = wm;
NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str);
}
else
{
found_wiimotes.push_back(wm);
NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str);
}
} }
} }
} }
return found_wiimotes;
} }
// Connect to a wiimote with a known address. // Connect to a wiimote with a known address.

View file

@ -87,8 +87,8 @@ inline void init_lib()
hid_lib = LoadLibrary(_T("hid.dll")); hid_lib = LoadLibrary(_T("hid.dll"));
if (!hid_lib) if (!hid_lib)
{ {
PanicAlertT("Failed to load hid.dll"); PanicAlertT("Failed to load hid.dll! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
exit(EXIT_FAILURE); return;
} }
HidD_GetHidGuid = (PHidD_GetHidGuid)GetProcAddress(hid_lib, "HidD_GetHidGuid"); HidD_GetHidGuid = (PHidD_GetHidGuid)GetProcAddress(hid_lib, "HidD_GetHidGuid");
@ -98,15 +98,15 @@ inline void init_lib()
if (!HidD_GetHidGuid || !HidD_GetAttributes || if (!HidD_GetHidGuid || !HidD_GetAttributes ||
!HidD_SetOutputReport || !HidD_GetProductString) !HidD_SetOutputReport || !HidD_GetProductString)
{ {
PanicAlertT("Failed to load hid.dll"); PanicAlertT("Failed to load hid.dll! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
exit(EXIT_FAILURE); return;
} }
bthprops_lib = LoadLibrary(_T("bthprops.cpl")); bthprops_lib = LoadLibrary(_T("bthprops.cpl"));
if (!bthprops_lib) if (!bthprops_lib)
{ {
PanicAlertT("Failed to load bthprops.cpl"); PanicAlertT("Failed to load bthprops.cpl! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
exit(EXIT_FAILURE); return;
} }
Bth_BluetoothFindDeviceClose = (PBth_BluetoothFindDeviceClose)GetProcAddress(bthprops_lib, "BluetoothFindDeviceClose"); Bth_BluetoothFindDeviceClose = (PBth_BluetoothFindDeviceClose)GetProcAddress(bthprops_lib, "BluetoothFindDeviceClose");
@ -128,8 +128,8 @@ inline void init_lib()
!Bth_BluetoothSetServiceState || !Bth_BluetoothAuthenticateDevice || !Bth_BluetoothSetServiceState || !Bth_BluetoothAuthenticateDevice ||
!Bth_BluetoothEnumerateInstalledServices) !Bth_BluetoothEnumerateInstalledServices)
{ {
PanicAlertT("Failed to load bthprops.cpl"); PanicAlertT("Failed to load bthprops.cpl! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
exit(EXIT_FAILURE); return;
} }
initialized = true; initialized = true;
@ -139,6 +139,10 @@ inline void init_lib()
namespace WiimoteReal namespace WiimoteReal
{ {
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len);
int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index);
template <typename T> template <typename T>
void ProcessWiimotes(bool new_scan, T& callback); void ProcessWiimotes(bool new_scan, T& callback);
@ -183,7 +187,7 @@ void WiimoteScanner::Update()
// Does not replace already found wiimotes even if they are disconnected. // Does not replace already found wiimotes even if they are disconnected.
// wm is an array of max_wiimotes wiimotes // wm is an array of max_wiimotes wiimotes
// Returns the total number of found and connected wiimotes. // Returns the total number of found and connected wiimotes.
std::vector<Wiimote*> WiimoteScanner::FindWiimotes() void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
{ {
ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo, BLUETOOTH_DEVICE_INFO_STRUCT& btdi)
{ {
@ -198,8 +202,6 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
// Get all hid devices connected // Get all hid devices connected
HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));
std::vector<Wiimote*> wiimotes;
SP_DEVICE_INTERFACE_DATA device_data; SP_DEVICE_INTERFACE_DATA device_data;
device_data.cbSize = sizeof(device_data); device_data.cbSize = sizeof(device_data);
PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL;
@ -217,7 +219,21 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
{ {
auto const wm = new Wiimote; auto const wm = new Wiimote;
wm->devicepath = detail_data->DevicePath; wm->devicepath = detail_data->DevicePath;
wiimotes.push_back(wm); bool real_wiimote = false, is_bb = false;
CheckDeviceType(wm->devicepath, real_wiimote, is_bb);
if (is_bb)
{
found_board = wm;
}
else if (real_wiimote)
{
found_wiimotes.push_back(wm);
}
else
{
free(wm);
}
} }
free(detail_data); free(detail_data);
@ -229,7 +245,183 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
//if (!wiimotes.empty()) //if (!wiimotes.empty())
// SLEEP(2000); // SLEEP(2000);
return wiimotes; }
int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, int size, int attempts)
{
OVERLAPPED hid_overlap_write = OVERLAPPED();
hid_overlap_write.hEvent = CreateEvent(NULL, true, false, NULL);
enum win_bt_stack_t stack = MSBT_STACK_UNKNOWN;
DWORD written = 0;
for (; attempts>0; --attempts)
{
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size))
{
auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
if (WAIT_TIMEOUT == wait_result)
{
WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A timeout occurred on writing to Wiimote.");
CancelIo(dev_handle);
continue;
}
else if (WAIT_FAILED == wait_result)
{
WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A wait error occurred on writing to Wiimote.");
CancelIo(dev_handle);
continue;
}
if (GetOverlappedResult(dev_handle, &hid_overlap_write, &written, TRUE))
{
break;
}
}
}
CloseHandle(hid_overlap_write.hEvent);
return written;
}
int CheckDeviceType_Read(HANDLE &dev_handle, u8* buf, int attempts)
{
OVERLAPPED hid_overlap_read = OVERLAPPED();
hid_overlap_read.hEvent = CreateEvent(NULL, true, false, NULL);
int read = 0;
for (; attempts>0; --attempts)
{
read = _IORead(dev_handle, hid_overlap_read, buf, 1);
if (read > 0)
break;
}
CloseHandle(hid_overlap_read.hEvent);
return read;
}
// A convoluted way of checking if a device is a Wii Balance Board and if it is a connectable Wiimote.
// Because nothing on Windows should be easy.
// (We can't seem to easily identify the bluetooth device an HID device belongs to...)
void WiimoteScanner::CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb)
{
real_wiimote = false;
is_bb = false;
#ifdef SHARE_WRITE_WIIMOTES
std::lock_guard<std::mutex> lk(g_connected_wiimotes_lock);
if (g_connected_wiimotes.count(devicepath) != 0)
return;
#endif
HANDLE dev_handle = CreateFile(devicepath.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
NULL);
if (dev_handle == INVALID_HANDLE_VALUE)
return;
// enable to only check for official nintendo wiimotes/bb's
bool check_vidpid = false;
HIDD_ATTRIBUTES attrib;
attrib.Size = sizeof(attrib);
if (!check_vidpid ||
(HidD_GetAttributes(dev_handle, &attrib) &&
(attrib.VendorID == 0x057e) &&
(attrib.ProductID == 0x0306)))
{
int rc = 0;
// max_cycles insures we are never stuck here due to bad coding...
int max_cycles = 20;
u8 buf[MAX_PAYLOAD] = {0};
u8 const req_status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0};
rc = CheckDeviceType_Write(dev_handle,
req_status_report,
sizeof(req_status_report),
1);
while (rc > 0 && --max_cycles > 0)
{
if ((rc = CheckDeviceType_Read(dev_handle, buf, 1)) <= 0)
{
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: Read failed...");
break;
}
switch (buf[1])
{
case WM_STATUS_REPORT:
{
real_wiimote = true;
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Status Report");
wm_status_report * wsr = (wm_status_report*)&buf[2];
if (wsr->extension)
{
// Wiimote with extension, we ask it what kind.
u8 read_ext[MAX_PAYLOAD] = {0};
read_ext[0] = WM_SET_REPORT | WM_BT_OUTPUT;
read_ext[1] = WM_READ_DATA;
// Extension type register.
*(u32*)&read_ext[2] = Common::swap32(0x4a400fa);
// Size.
*(u16*)&read_ext[6] = Common::swap16(6);
rc = CheckDeviceType_Write(dev_handle, read_ext, 8, 1);
}
else
{
// Normal Wiimote, exit while and be happy.
rc = -1;
}
break;
}
case WM_ACK_DATA:
{
real_wiimote = true;
//wm_acknowledge * wm = (wm_acknowledge*)&buf[2];
//DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Ack Error: %X ReportID: %X", wm->errorID, wm->reportID);
break;
}
case WM_READ_DATA_REPLY:
{
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Data Reply");
wm_read_data_reply * wrdr
= (wm_read_data_reply*)&buf[2];
// Check if it has returned what we asked.
if (Common::swap16(wrdr->address) == 0x00fa)
{
real_wiimote = true;
// 0x020420A40000ULL means balance board.
u64 ext_type = (*(u64*)&wrdr->data[0]);
// DEBUG_LOG(WIIMOTE,
// "CheckDeviceType: GOT EXT TYPE %llX",
// ext_type);
is_bb = (ext_type == 0x020420A40000ULL) ||
((ext_type & 0xf00000000000ULL) &&
ext_type != 0xffffffffffffULL);
}
else
{
ERROR_LOG(WIIMOTE,
"CheckDeviceType: GOT UNREQUESTED ADDRESS %X",
Common::swap16(wrdr->address));
}
// force end
rc = -1;
break;
}
default:
{
// We let read try again incase there is another packet waiting.
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: GOT UNKNOWN REPLY: %X", buf[1]);
break;
}
}
}
}
CloseHandle(dev_handle);
} }
bool WiimoteScanner::IsReady() const bool WiimoteScanner::IsReady() const
@ -355,7 +547,7 @@ bool Wiimote::IsConnected() const
// positive = read packet // positive = read packet
// negative = didn't read packet // negative = didn't read packet
// zero = error // zero = error
int Wiimote::IORead(u8* buf) int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index)
{ {
// Add data report indicator byte (here, 0xa1) // Add data report indicator byte (here, 0xa1)
buf[0] = 0xa1; buf[0] = 0xa1;
@ -408,78 +600,92 @@ int Wiimote::IORead(u8* buf)
return bytes + 1; return bytes + 1;
} }
int Wiimote::IOWrite(const u8* buf, int len) // positive = read packet
// negative = didn't read packet
// zero = error
int Wiimote::IORead(u8* buf)
{
return _IORead(dev_handle, hid_overlap_read, buf, index);
}
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len)
{ {
switch (stack) switch (stack)
{ {
case MSBT_STACK_UNKNOWN: case MSBT_STACK_UNKNOWN:
{
// Try to auto-detect the stack type
stack = MSBT_STACK_BLUESOLEIL;
if (IOWrite(buf, len))
return 1;
stack = MSBT_STACK_MS;
if (IOWrite(buf, len))
return 1;
stack = MSBT_STACK_UNKNOWN;
break;
}
case MSBT_STACK_MS:
{
auto result = HidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, len - 1);
//FlushFileBuffers(dev_handle);
if (!result)
{ {
auto err = GetLastError(); // Try to auto-detect the stack type
if (err == 121) stack = MSBT_STACK_BLUESOLEIL;
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len))
return 1;
stack = MSBT_STACK_MS;
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len))
return 1;
stack = MSBT_STACK_UNKNOWN;
break;
}
case MSBT_STACK_MS:
{
auto result = HidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, len - 1);
//FlushFileBuffers(dev_handle);
if (!result)
{ {
// Semaphore timeout auto err = GetLastError();
NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote"); if (err == 121)
{
// Semaphore timeout
NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote");
}
else
{
WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err);
}
}
return result;
break;
}
case MSBT_STACK_BLUESOLEIL:
{
u8 big_buf[MAX_PAYLOAD];
if (len < MAX_PAYLOAD)
{
std::copy(buf, buf + len, big_buf);
std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0);
buf = big_buf;
}
ResetEvent(hid_overlap_write.hEvent);
DWORD bytes = 0;
if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write))
{
// WriteFile always returns true with bluesoleil.
return 1;
} }
else else
{ {
WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); auto const err = GetLastError();
if (ERROR_IO_PENDING == err)
{
CancelIo(dev_handle);
}
} }
break;
} }
return result;
break;
}
case MSBT_STACK_BLUESOLEIL:
{
u8 big_buf[MAX_PAYLOAD];
if (len < MAX_PAYLOAD)
{
std::copy(buf, buf + len, big_buf);
std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0);
buf = big_buf;
}
ResetEvent(hid_overlap_write.hEvent);
DWORD bytes = 0;
if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write))
{
// WriteFile always returns true with bluesoleil.
return 1;
}
else
{
auto const err = GetLastError();
if (ERROR_IO_PENDING == err)
{
CancelIo(dev_handle);
}
}
break;
}
} }
return 0; return 0;
} }
int Wiimote::IOWrite(const u8* buf, int len)
{
return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len);
}
// invokes callback for each found wiimote bluetooth device // invokes callback for each found wiimote bluetooth device
template <typename T> template <typename T>
void ProcessWiimotes(bool new_scan, T& callback) void ProcessWiimotes(bool new_scan, T& callback)

View file

@ -116,22 +116,21 @@ WiimoteScanner::~WiimoteScanner()
void WiimoteScanner::Update() void WiimoteScanner::Update()
{} {}
std::vector<Wiimote*> WiimoteScanner::FindWiimotes() void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
{ {
// TODO: find the device in the constructor and save it for later // TODO: find the device in the constructor and save it for later
std::vector<Wiimote*> wiimotes;
IOBluetoothHostController *bth; IOBluetoothHostController *bth;
IOBluetoothDeviceInquiry *bti; IOBluetoothDeviceInquiry *bti;
SearchBT *sbt; SearchBT *sbt;
NSEnumerator *en; NSEnumerator *en;
found_board = NULL;
bth = [[IOBluetoothHostController alloc] init]; bth = [[IOBluetoothHostController alloc] init];
if ([bth addressAsString] == nil) if ([bth addressAsString] == nil)
{ {
WARN_LOG(WIIMOTE, "No bluetooth host controller"); WARN_LOG(WIIMOTE, "No bluetooth host controller");
[bth release]; [bth release];
return wiimotes; return;
} }
sbt = [[SearchBT alloc] init]; sbt = [[SearchBT alloc] init];
@ -162,14 +161,20 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
Wiimote *wm = new Wiimote(); Wiimote *wm = new Wiimote();
wm->btd = dev; wm->btd = dev;
wiimotes.push_back(wm);
if(IsBalanceBoardName([[dev name] UTF8String]))
{
found_board = wm;
}
else
{
found_wiimotes.push_back(wm);
}
} }
[bth release]; [bth release];
[bti release]; [bti release];
[sbt release]; [sbt release];
return wiimotes;
} }
bool WiimoteScanner::IsReady() const bool WiimoteScanner::IsReady() const

View file

@ -17,12 +17,13 @@
#include "../WiimoteEmu/WiimoteHid.h" #include "../WiimoteEmu/WiimoteHid.h"
unsigned int g_wiimote_sources[MAX_WIIMOTES]; unsigned int g_wiimote_sources[MAX_BBMOTES];
namespace WiimoteReal namespace WiimoteReal
{ {
void HandleFoundWiimotes(const std::vector<Wiimote*>&); void HandleFoundWiimotes(const std::vector<Wiimote*>&);
void TryToConnectBalanceBoard(Wiimote*);
void TryToConnectWiimote(Wiimote*); void TryToConnectWiimote(Wiimote*);
void HandleWiimoteDisconnect(int index); void HandleWiimoteDisconnect(int index);
void DoneWithWiimote(int index); void DoneWithWiimote(int index);
@ -31,8 +32,7 @@ bool g_real_wiimotes_initialized = false;
std::recursive_mutex g_refresh_lock; std::recursive_mutex g_refresh_lock;
Wiimote* g_wiimotes[MAX_WIIMOTES]; Wiimote* g_wiimotes[MAX_BBMOTES];
WiimoteScanner g_wiimote_scanner; WiimoteScanner g_wiimote_scanner;
Wiimote::Wiimote() Wiimote::Wiimote()
@ -285,7 +285,7 @@ bool Wiimote::Prepare(int _index)
u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REPORT_MODE, 0, WM_REPORT_CORE}; u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REPORT_MODE, 0, WM_REPORT_CORE};
// Set the active LEDs and turn on rumble. // Set the active LEDs and turn on rumble.
u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_LEDS, u8(WIIMOTE_LED_1 << index | 0x1)}; u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_LEDS, u8(WIIMOTE_LED_1 << (index%WIIMOTE_BALANCE_BOARD) | 0x1)};
// Turn off rumble // Turn off rumble
u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_RUMBLE, 0}; u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_RUMBLE, 0};
@ -325,11 +325,25 @@ unsigned int CalculateWantedWiimotes()
return wanted_wiimotes; return wanted_wiimotes;
} }
unsigned int CalculateWantedBB()
{
unsigned int wanted_bb = 0;
if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD] && !g_wiimotes[WIIMOTE_BALANCE_BOARD])
++wanted_bb;
return wanted_bb;
}
void WiimoteScanner::WantWiimotes(bool do_want) void WiimoteScanner::WantWiimotes(bool do_want)
{ {
m_want_wiimotes = do_want; m_want_wiimotes = do_want;
} }
void WiimoteScanner::WantBB(bool do_want)
{
m_want_bb = do_want;
}
void WiimoteScanner::StartScanning() void WiimoteScanner::StartScanning()
{ {
if (!m_run_thread) if (!m_run_thread)
@ -352,7 +366,7 @@ void CheckForDisconnectedWiimotes()
{ {
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected()) if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected())
HandleWiimoteDisconnect(i); HandleWiimoteDisconnect(i);
} }
@ -366,12 +380,13 @@ void WiimoteScanner::ThreadFunc()
while (m_run_thread) while (m_run_thread)
{ {
std::vector<Wiimote*> found_wiimotes; std::vector<Wiimote*> found_wiimotes;
Wiimote* found_board = NULL;
//NOTICE_LOG(WIIMOTE, "In loop"); //NOTICE_LOG(WIIMOTE, "In loop");
if (m_want_wiimotes) if (m_want_wiimotes || m_want_bb)
{ {
found_wiimotes = FindWiimotes(); FindWiimotes(found_wiimotes, found_board);
} }
else else
{ {
@ -384,7 +399,10 @@ void WiimoteScanner::ThreadFunc()
// TODO: this is a fairly lame place for this // TODO: this is a fairly lame place for this
CheckForDisconnectedWiimotes(); CheckForDisconnectedWiimotes();
HandleFoundWiimotes(found_wiimotes); if(m_want_wiimotes)
HandleFoundWiimotes(found_wiimotes);
if(m_want_bb && found_board)
TryToConnectBalanceBoard(found_board);
//std::this_thread::yield(); //std::this_thread::yield();
Common::SleepCurrentThread(500); Common::SleepCurrentThread(500);
@ -439,6 +457,10 @@ void LoadSettings()
sec.Get("Source", &g_wiimote_sources[i], i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU); sec.Get("Source", &g_wiimote_sources[i], i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU);
} }
std::string secname("BalanceBoard");
IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
sec.Get("Source", &g_wiimote_sources[WIIMOTE_BALANCE_BOARD], WIIMOTE_SRC_NONE);
} }
// config dialog calls this when some settings change // config dialog calls this when some settings change
@ -452,6 +474,7 @@ void Initialize()
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
if (g_real_wiimotes_initialized) if (g_real_wiimotes_initialized)
return; return;
@ -474,20 +497,21 @@ void Shutdown(void)
g_real_wiimotes_initialized = false; g_real_wiimotes_initialized = false;
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
HandleWiimoteDisconnect(i); HandleWiimoteDisconnect(i);
} }
void ChangeWiimoteSource(unsigned int index, int source) void ChangeWiimoteSource(unsigned int index, int source)
{ {
{ {
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
g_wiimote_sources[index] = source;
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
g_wiimote_sources[index] = source;
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
// kill real connection (or swap to different slot) // kill real connection (or swap to different slot)
DoneWithWiimote(index); DoneWithWiimote(index);
} }
// reconnect to the emulator // reconnect to the emulator
@ -500,7 +524,7 @@ void TryToConnectWiimote(Wiimote* wm)
{ {
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock); std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
{ {
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]
&& !g_wiimotes[i]) && !g_wiimotes[i])
@ -525,6 +549,31 @@ void TryToConnectWiimote(Wiimote* wm)
delete wm; delete wm;
} }
void TryToConnectBalanceBoard(Wiimote* wm)
{
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD]
&& !g_wiimotes[WIIMOTE_BALANCE_BOARD])
{
if (wm->Connect() && wm->Prepare(WIIMOTE_BALANCE_BOARD))
{
NOTICE_LOG(WIIMOTE, "Connected to Balance Board %i.", WIIMOTE_BALANCE_BOARD + 1);
std::swap(g_wiimotes[WIIMOTE_BALANCE_BOARD], wm);
g_wiimotes[WIIMOTE_BALANCE_BOARD]->StartThread();
Host_ConnectWiimote(WIIMOTE_BALANCE_BOARD, true);
}
}
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
lk.unlock();
delete wm;
}
void DoneWithWiimote(int index) void DoneWithWiimote(int index)
{ {
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
@ -534,7 +583,7 @@ void DoneWithWiimote(int index)
g_wiimotes[index]->StopThread(); g_wiimotes[index]->StopThread();
// First see if we can use this real Wiimote in another slot. // First see if we can use this real Wiimote in another slot.
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
{ {
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]
&& !g_wiimotes[i]) && !g_wiimotes[i])
@ -560,9 +609,11 @@ void HandleWiimoteDisconnect(int index)
Wiimote* wm = NULL; Wiimote* wm = NULL;
{ {
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
std::swap(wm, g_wiimotes[index]);
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); std::swap(wm, g_wiimotes[index]);
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
} }
if (wm) if (wm)
@ -583,31 +634,35 @@ void Refresh()
g_wiimote_scanner.StopScanning(); g_wiimote_scanner.StopScanning();
{ {
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock); std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
std::vector<Wiimote*> found_wiimotes; std::vector<Wiimote*> found_wiimotes;
Wiimote* found_board = NULL;
if (0 != CalculateWantedWiimotes()) if (0 != CalculateWantedWiimotes() || 0 != CalculateWantedBB())
{
// Don't hang Dolphin when searching
lk.unlock();
found_wiimotes = g_wiimote_scanner.FindWiimotes();
lk.lock();
}
CheckForDisconnectedWiimotes();
// Brief rumble for already connected Wiimotes.
for (int i = 0; i != MAX_WIIMOTES; ++i)
{
if (g_wiimotes[i])
{ {
g_wiimotes[i]->StopThread(); // Don't hang Dolphin when searching
g_wiimotes[i]->Prepare(i); lk.unlock();
g_wiimotes[i]->StartThread(); g_wiimote_scanner.FindWiimotes(found_wiimotes, found_board);
lk.lock();
} }
}
HandleFoundWiimotes(found_wiimotes); CheckForDisconnectedWiimotes();
// Brief rumble for already connected Wiimotes.
// Don't do this for Balance Board as it doesn't have rumble anyway.
for (int i = 0; i < MAX_WIIMOTES; ++i)
{
if (g_wiimotes[i])
{
g_wiimotes[i]->StopThread();
g_wiimotes[i]->Prepare(i);
g_wiimotes[i]->StartThread();
}
}
HandleFoundWiimotes(found_wiimotes);
if(found_board)
TryToConnectBalanceBoard(found_board);
} }
Initialize(); Initialize();
@ -616,7 +671,6 @@ void Refresh()
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
{ {
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock); std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
if (g_wiimotes[_WiimoteNumber]) if (g_wiimotes[_WiimoteNumber])
g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size); g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size);
} }
@ -656,7 +710,14 @@ bool IsValidBluetoothName(const std::string& name)
{ {
return return
"Nintendo RVL-CNT-01" == name || "Nintendo RVL-CNT-01" == name ||
"Nintendo RVL-CNT-01-TR" == name; "Nintendo RVL-CNT-01-TR" == name ||
IsBalanceBoardName(name);
}
bool IsBalanceBoardName(const std::string& name)
{
return
"Nintendo RVL-WBC-01" == name;
} }
}; // end of namespace }; // end of namespace

View file

@ -117,11 +117,12 @@ public:
bool IsReady() const; bool IsReady() const;
void WantWiimotes(bool do_want); void WantWiimotes(bool do_want);
void WantBB(bool do_want);
void StartScanning(); void StartScanning();
void StopScanning(); void StopScanning();
std::vector<Wiimote*> FindWiimotes(); void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&);
// function called when not looking for more wiimotes // function called when not looking for more wiimotes
void Update(); void Update();
@ -133,10 +134,10 @@ private:
volatile bool m_run_thread; volatile bool m_run_thread;
volatile bool m_want_wiimotes; volatile bool m_want_wiimotes;
volatile bool m_want_bb;
#if defined(_WIN32) #if defined(_WIN32)
void CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb);
#elif defined(__linux__) && HAVE_BLUEZ #elif defined(__linux__) && HAVE_BLUEZ
int device_id; int device_id;
int device_sock; int device_sock;
@ -145,7 +146,7 @@ private:
extern std::recursive_mutex g_refresh_lock; extern std::recursive_mutex g_refresh_lock;
extern WiimoteScanner g_wiimote_scanner; extern WiimoteScanner g_wiimote_scanner;
extern Wiimote *g_wiimotes[4]; extern Wiimote *g_wiimotes[MAX_BBMOTES];
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size); void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size);
void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size); void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size);
@ -158,6 +159,7 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes);
void ChangeWiimoteSource(unsigned int index, int source); void ChangeWiimoteSource(unsigned int index, int source);
bool IsValidBluetoothName(const std::string& name); bool IsValidBluetoothName(const std::string& name);
bool IsBalanceBoardName(const std::string& name);
}; // WiimoteReal }; // WiimoteReal

View file

@ -32,7 +32,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
} }
else else
{ {
u8 maxWM = min<u8>(BT_DINF.num_registered, CONF_PAD_MAX_ACTIVE); u8 maxWM = min<u8>(BT_DINF.num_registered, MAX_BBMOTES);
bdaddr_t tmpBD = BDADDR_ANY; bdaddr_t tmpBD = BDADDR_ANY;
u8 i = 0; u8 i = 0;
while (i < maxWM) while (i < maxWM)
@ -43,25 +43,57 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3]; tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3];
tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4]; tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4];
tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5]; tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5];
if(i == WIIMOTE_BALANCE_BOARD)
{
const char * wmName = "Nintendo RVL-WBC-01";
memcpy(BT_DINF.registered[i].name, wmName, 20);
memcpy(BT_DINF.balance_board.name, wmName, 20);
}
else
{
const char * wmName = "Nintendo RVL-CNT-01";
memcpy(BT_DINF.registered[i].name, wmName, 20);
memcpy(BT_DINF.active[i].name, wmName, 20);
}
INFO_LOG(WII_IPC_WIIMOTE, "Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]); INFO_LOG(WII_IPC_WIIMOTE, "Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false)); m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
i++; i++;
} }
while (i < CONF_PAD_MAX_ACTIVE) while (i < MAX_BBMOTES)
{ {
const char * wmName = "Nintendo RVL-CNT-01"; if(i == WIIMOTE_BALANCE_BOARD)
++BT_DINF.num_registered; {
BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i; const char * wmName = "Nintendo RVL-WBC-01";
BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0; ++BT_DINF.num_registered;
BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79; BT_DINF.balance_board.bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i;
BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19; BT_DINF.balance_board.bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0;
BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2; BT_DINF.balance_board.bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79;
BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11; BT_DINF.balance_board.bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19;
memcpy(BT_DINF.registered[i].name, wmName, 20); BT_DINF.balance_board.bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2;
BT_DINF.balance_board.bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11;
memcpy(BT_DINF.registered[i].name, wmName, 20);
memcpy(BT_DINF.balance_board.name, wmName, 20);
INFO_LOG(WII_IPC_WIIMOTE, "Adding to SYSConf Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]); INFO_LOG(WII_IPC_WIIMOTE, "Balance Board %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false)); m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
}
else
{
const char * wmName = "Nintendo RVL-CNT-01";
++BT_DINF.num_registered;
BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i;
BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0;
BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79;
BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19;
BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2;
BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11;
memcpy(BT_DINF.registered[i].name, wmName, 20);
INFO_LOG(WII_IPC_WIIMOTE, "Adding to SYSConf Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
}
i++; i++;
} }
@ -99,18 +131,18 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
p.DoPOD(m_HCIEndpoint); p.DoPOD(m_HCIEndpoint);
p.DoPOD(m_ACLEndpoint); p.DoPOD(m_ACLEndpoint);
p.Do(m_last_ticks); p.Do(m_last_ticks);
p.DoArray(m_PacketCount,4); p.DoArray(m_PacketCount,MAX_BBMOTES);
p.Do(m_ScanEnable); p.Do(m_ScanEnable);
p.Do(m_EventQueue); p.Do(m_EventQueue);
m_acl_pool.DoState(p); m_acl_pool.DoState(p);
for (unsigned int i = 0; i < 4; i++) for (unsigned int i = 0; i < MAX_BBMOTES; i++)
m_WiiMotes[i].DoState(p); m_WiiMotes[i].DoState(p);
// Reset the connection of real and hybrid wiimotes // Reset the connection of real and hybrid wiimotes
if (p.GetMode() == PointerWrap::MODE_READ && SConfig::GetInstance().m_WiimoteReconnectOnLoad) if (p.GetMode() == PointerWrap::MODE_READ && SConfig::GetInstance().m_WiimoteReconnectOnLoad)
{ {
for (unsigned int i = 0; i < 4; i++) for (unsigned int i = 0; i < MAX_BBMOTES; i++)
{ {
if (WIIMOTE_SRC_EMU == g_wiimote_sources[i] || WIIMOTE_SRC_NONE == g_wiimote_sources[i]) if (WIIMOTE_SRC_EMU == g_wiimote_sources[i] || WIIMOTE_SRC_NONE == g_wiimote_sources[i])
continue; continue;

View file

@ -12,6 +12,7 @@
#include "WII_IPC_HLE.h" #include "WII_IPC_HLE.h"
#include "WII_IPC_HLE_Device.h" #include "WII_IPC_HLE_Device.h"
#include "WII_IPC_HLE_WiiMote.h" #include "WII_IPC_HLE_WiiMote.h"
#include "../HW/Wiimote.h"
struct SQueuedEvent struct SQueuedEvent
{ {
@ -193,7 +194,7 @@ private:
} }
} m_acl_pool; } m_acl_pool;
u32 m_PacketCount[4]; u32 m_PacketCount[MAX_BBMOTES];
u64 m_last_ticks; u64 m_last_ticks;
// Send ACL data to a device (wiimote) // Send ACL data to a device (wiimote)
@ -274,7 +275,6 @@ private:
#pragma pack(push,1) #pragma pack(push,1)
#define CONF_PAD_MAX_REGISTERED 10 #define CONF_PAD_MAX_REGISTERED 10
#define CONF_PAD_MAX_ACTIVE 4
struct _conf_pad_device struct _conf_pad_device
{ {
@ -286,7 +286,7 @@ private:
{ {
u8 num_registered; u8 num_registered;
_conf_pad_device registered[CONF_PAD_MAX_REGISTERED]; _conf_pad_device registered[CONF_PAD_MAX_REGISTERED];
_conf_pad_device active[CONF_PAD_MAX_ACTIVE]; _conf_pad_device active[MAX_WIIMOTES];
_conf_pad_device balance_board; _conf_pad_device balance_board;
u8 unknown[0x45]; u8 unknown[0x45];
}; };

View file

@ -37,7 +37,7 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
, m_HIDInterruptChannel_Config(false) , m_HIDInterruptChannel_Config(false)
, m_HIDInterruptChannel_ConfigWait(false) , m_HIDInterruptChannel_ConfigWait(false)
, m_BD(_BD) , m_BD(_BD)
, m_Name("Nintendo RVL-CNT-01") , m_Name(_Number == WIIMOTE_BALANCE_BOARD ? "Nintendo RVL-WBC-01" : "Nintendo RVL-CNT-01")
, m_pHost(_pHost) , m_pHost(_pHost)
{ {
DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number); DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number);
@ -277,13 +277,13 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
break; break;
case L2CAP_PSM_HID_CNTL: case L2CAP_PSM_HID_CNTL:
if (number < 4) if (number < MAX_BBMOTES)
Wiimote::ControlChannel(number, pHeader->dcid, pData, DataSize); Wiimote::ControlChannel(number, pHeader->dcid, pData, DataSize);
break; break;
case L2CAP_PSM_HID_INTR: case L2CAP_PSM_HID_INTR:
{ {
if (number < 4) if (number < MAX_BBMOTES)
{ {
DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel"); DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel");
DEBUG_LOG(WIIMOTE, " Channel ID: %04x", pHeader->dcid); DEBUG_LOG(WIIMOTE, " Channel ID: %04x", pHeader->dcid);

View file

@ -126,11 +126,6 @@ void FrameUpdate()
g_totalFrames = g_currentFrame; g_totalFrames = g_currentFrame;
g_totalLagCount = g_currentLagCount; g_totalLagCount = g_currentLagCount;
} }
if (IsPlayingInput() && IsConfigSaved())
{
SetGraphicsConfig();
}
if (g_bFrameStep) if (g_bFrameStep)
{ {
Core::SetState(Core::CORE_PAUSE); Core::SetState(Core::CORE_PAUSE);
@ -392,7 +387,7 @@ void ChangeWiiPads(bool instantly)
if (instantly && (g_numPads >> 4) == controllers) if (instantly && (g_numPads >> 4) == controllers)
return; return;
for (int i = 0; i < 4; i++) for (int i = 0; i < MAX_BBMOTES; i++)
{ {
g_wiimote_sources[i] = IsUsingWiimote(i) ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE; g_wiimote_sources[i] = IsUsingWiimote(i) ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE;
GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(IsUsingWiimote(i)); GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(IsUsingWiimote(i));
@ -1173,18 +1168,15 @@ void GetSettings()
bProgressive = SConfig::GetInstance().m_LocalCoreStartupParameter.bProgressive; bProgressive = SConfig::GetInstance().m_LocalCoreStartupParameter.bProgressive;
bDSPHLE = SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPHLE; bDSPHLE = SConfig::GetInstance().m_LocalCoreStartupParameter.bDSPHLE;
bFastDiscSpeed = SConfig::GetInstance().m_LocalCoreStartupParameter.bFastDiscSpeed; bFastDiscSpeed = SConfig::GetInstance().m_LocalCoreStartupParameter.bFastDiscSpeed;
videoBackend = SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend; videoBackend = g_video_backend->GetName();
iCPUCore = SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore; iCPUCore = SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore;
if (!Core::g_CoreStartupParameter.bWii) if (!Core::g_CoreStartupParameter.bWii)
g_bClearSave = !File::Exists(SConfig::GetInstance().m_strMemoryCardA); g_bClearSave = !File::Exists(SConfig::GetInstance().m_strMemoryCardA);
bMemcard = SConfig::GetInstance().m_EXIDevice[0] == EXIDEVICE_MEMORYCARD; bMemcard = SConfig::GetInstance().m_EXIDevice[0] == EXIDEVICE_MEMORYCARD;
int temp; for (int i = 0; i < 20; ++i)
for(int i = 0; i < 4; ++i )
{ {
sscanf(SCM_REV_STR + 2 * i, "%2x", &temp ); sscanf(SCM_REV_STR + 2 * i, "%02x", &revision[i]);
revision[i] = temp;
} }
} }

View file

@ -10,6 +10,7 @@
// for gcpad // for gcpad
#include "HW/SI_DeviceGCController.h" #include "HW/SI_DeviceGCController.h"
#include "HW/SI_DeviceGCSteeringWheel.h" #include "HW/SI_DeviceGCSteeringWheel.h"
#include "HW/SI_DeviceDanceMat.h"
// for gctime // for gctime
#include "HW/EXI_DeviceIPL.h" #include "HW/EXI_DeviceIPL.h"
// for wiimote/ OSD messages // for wiimote/ OSD messages
@ -299,6 +300,11 @@ bool CSIDevice_GCSteeringWheel::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus); return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
} }
bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
{
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
}
// called from ---CPU--- thread // called from ---CPU--- thread
// so all players' games get the same time // so all players' games get the same time
u32 CEXIIPL::NetPlay_GetGCTime() u32 CEXIIPL::NetPlay_GetGCTime()
@ -328,6 +334,11 @@ u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD)
return CSIDevice_GCController::NetPlay_GetPadNum(numPAD); return CSIDevice_GCController::NetPlay_GetPadNum(numPAD);
} }
u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD)
{
return CSIDevice_GCController::NetPlay_GetPadNum(numPAD);
}
// called from ---CPU--- thread // called from ---CPU--- thread
// wiimote update / used for frame counting // wiimote update / used for frame counting
//void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number) //void CWII_IPC_HLE_Device_usb_oh1_57e_305::NetPlay_WiimoteUpdate(int _number)

View file

@ -26,31 +26,29 @@ namespace PowerPC
for (u32 m = 0; m < 128; m++) for (u32 m = 0; m < 128; m++)
{ {
u32 b[7]; u32 w;
for (int i = 0; i < 7; i++) b[i] = m & (1<<i); if(m & (1<<0))
u32 w; if(m & (1<<2))
if (b[0]) if(m & (1<<6))
if (b[2]) w=7;
if (b[6]) else
w = 7; w=6;
else else
w = 6; if(m & (1<<5))
else w=5;
if (b[5]) else
w = 5; w=4;
else else
w = 4; if(m & (1<<1))
else if(m & (1<<4))
if (b[1]) w=3;
if (b[4]) else
w = 3; w=2;
else else
w = 2; if(m & (1<<3))
else w=1;
if (b[3]) else
w = 1; w=0;
else
w = 0;
way_from_plru[m] = w; way_from_plru[m] = w;
} }
} }

View file

@ -138,6 +138,8 @@ void Init(int cpu_core)
ppcState.itlb_last = 0; ppcState.itlb_last = 0;
memset(ppcState.itlb_va, 0, sizeof(ppcState.itlb_va)); memset(ppcState.itlb_va, 0, sizeof(ppcState.itlb_va));
memset(ppcState.itlb_pa, 0, sizeof(ppcState.itlb_pa)); memset(ppcState.itlb_pa, 0, sizeof(ppcState.itlb_pa));
ppcState.pagetable_base = 0;
ppcState.pagetable_hashmask = 0;
ResetRegisters(); ResetRegisters();
PPCTables::InitTables(cpu_core); PPCTables::InitTables(cpu_core);

View file

@ -64,6 +64,9 @@ struct GC_ALIGNED64(PowerPCState)
u32 itlb_va[128]; u32 itlb_va[128];
u32 itlb_pa[128]; u32 itlb_pa[128];
u32 pagetable_base;
u32 pagetable_hashmask;
InstructionCache iCache; InstructionCache iCache;
}; };

View file

@ -3,6 +3,7 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "Common.h" #include "Common.h"
#include "Timer.h"
#include "State.h" #include "State.h"
#include "Core.h" #include "Core.h"
#include "ConfigManager.h" #include "ConfigManager.h"
@ -58,13 +59,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread; static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system // Don't forget to increase this after doing changes on the savestate system
static const u32 STATE_VERSION = 16; static const u32 STATE_VERSION = 20;
struct StateHeader
{
u8 gameID[6];
size_t size;
};
enum enum
{ {
@ -159,17 +154,61 @@ void VerifyBuffer(std::vector<u8>& buffer)
Core::PauseAndLock(false, wasUnpaused); Core::PauseAndLock(false, wasUnpaused);
} }
// return state number not in map
int GetEmptySlot(std::map<double, int> m)
{
for (int i = 1; i <= (int)NUM_STATES; i++)
{
bool found = false;
for (std::map<double, int>::iterator it = m.begin(); it != m.end(); it++)
{
if (it->second == i)
{
found = true;
break;
}
}
if (!found) return i;
}
return -1;
}
static std::string MakeStateFilename(int number);
// read state timestamps
std::map<double, int> GetSavedStates()
{
StateHeader header;
std::map<double, int> m;
for (int i = 1; i <= (int)NUM_STATES; i++)
{
if (File::Exists(MakeStateFilename(i)))
{
if (ReadHeader(MakeStateFilename(i), header))
{
double d = Common::Timer::GetDoubleTime() - header.time;
// increase time until unique value is obtained
while (m.find(d) != m.end()) d += .001;
m.insert(std::pair<double,int>(d, i));
}
}
}
return m;
}
struct CompressAndDumpState_args struct CompressAndDumpState_args
{ {
std::vector<u8>* buffer_vector; std::vector<u8>* buffer_vector;
std::mutex* buffer_mutex; std::mutex* buffer_mutex;
std::string filename; std::string filename;
bool wait;
}; };
void CompressAndDumpState(CompressAndDumpState_args save_args) void CompressAndDumpState(CompressAndDumpState_args save_args)
{ {
std::lock_guard<std::mutex> lk(*save_args.buffer_mutex); std::lock_guard<std::mutex> lk(*save_args.buffer_mutex);
g_compressAndDumpStateSyncEvent.Set(); if (!save_args.wait)
g_compressAndDumpStateSyncEvent.Set();
const u8* const buffer_data = &(*(save_args.buffer_vector))[0]; const u8* const buffer_data = &(*(save_args.buffer_vector))[0];
const size_t buffer_size = (save_args.buffer_vector)->size(); const size_t buffer_size = (save_args.buffer_vector)->size();
@ -201,6 +240,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
if (!f) if (!f)
{ {
Core::DisplayMessage("Could not save state", 2000); Core::DisplayMessage("Could not save state", 2000);
g_compressAndDumpStateSyncEvent.Set();
return; return;
} }
@ -208,6 +248,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
StateHeader header; StateHeader header;
memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6); memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6);
header.size = g_use_compression ? buffer_size : 0; header.size = g_use_compression ? buffer_size : 0;
header.time = Common::Timer::GetDoubleTime();
f.WriteArray(&header, 1); f.WriteArray(&header, 1);
@ -216,7 +257,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
lzo_uint i = 0; lzo_uint i = 0;
while (true) while (true)
{ {
lzo_uint cur_len = 0; lzo_uint32 cur_len = 0;
lzo_uint out_len = 0; lzo_uint out_len = 0;
if ((i + IN_LEN) >= buffer_size) if ((i + IN_LEN) >= buffer_size)
@ -228,7 +269,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
PanicAlertT("Internal LZO Error - compression failed"); PanicAlertT("Internal LZO Error - compression failed");
// The size of the data to write is 'out_len' // The size of the data to write is 'out_len'
f.WriteArray(&out_len, 1); f.WriteArray((lzo_uint32*)&out_len, 1);
f.WriteBytes(out, out_len); f.WriteBytes(out, out_len);
if (cur_len != IN_LEN) if (cur_len != IN_LEN)
@ -244,9 +285,10 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
Core::DisplayMessage(StringFromFormat("Saved State to %s", Core::DisplayMessage(StringFromFormat("Saved State to %s",
filename.c_str()).c_str(), 2000); filename.c_str()).c_str(), 2000);
g_compressAndDumpStateSyncEvent.Set();
} }
void SaveAs(const std::string& filename) void SaveAs(const std::string& filename, bool wait)
{ {
// Pause the core while we save the state // Pause the core while we save the state
bool wasUnpaused = Core::PauseAndLock(true); bool wasUnpaused = Core::PauseAndLock(true);
@ -274,6 +316,7 @@ void SaveAs(const std::string& filename)
save_args.buffer_vector = &g_current_buffer; save_args.buffer_vector = &g_current_buffer;
save_args.buffer_mutex = &g_cs_current_buffer; save_args.buffer_mutex = &g_cs_current_buffer;
save_args.filename = filename; save_args.filename = filename;
save_args.wait = wait;
Flush(); Flush();
g_save_thread = std::thread(CompressAndDumpState, save_args); g_save_thread = std::thread(CompressAndDumpState, save_args);
@ -291,6 +334,20 @@ void SaveAs(const std::string& filename)
Core::PauseAndLock(false, wasUnpaused); Core::PauseAndLock(false, wasUnpaused);
} }
bool ReadHeader(const std::string filename, StateHeader& header)
{
Flush();
File::IOFile f(filename, "rb");
if (!f)
{
Core::DisplayMessage("State not found", 2000);
return false;
}
f.ReadArray(&header, 1);
return true;
}
void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_data) void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_data)
{ {
Flush(); Flush();
@ -322,7 +379,7 @@ void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_data)
lzo_uint i = 0; lzo_uint i = 0;
while (true) while (true)
{ {
lzo_uint cur_len = 0; // number of bytes to read lzo_uint32 cur_len = 0; // number of bytes to read
lzo_uint new_len = 0; // number of bytes to write lzo_uint new_len = 0; // number of bytes to write
if (!f.ReadArray(&cur_len, 1)) if (!f.ReadArray(&cur_len, 1))
@ -496,9 +553,9 @@ static std::string MakeStateFilename(int number)
SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), number); SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), number);
} }
void Save(int slot) void Save(int slot, bool wait)
{ {
SaveAs(MakeStateFilename(slot)); SaveAs(MakeStateFilename(slot), wait);
} }
void Load(int slot) void Load(int slot)
@ -511,12 +568,35 @@ void Verify(int slot)
VerifyAt(MakeStateFilename(slot)); VerifyAt(MakeStateFilename(slot));
} }
void LoadLastSaved() void LoadLastSaved(int i)
{ {
if (g_last_filename.empty()) std::map<double, int> savedStates = GetSavedStates();
Core::DisplayMessage("There is no last saved state", 2000);
if (i > (int)savedStates.size())
Core::DisplayMessage("State doesn't exist", 2000);
else else
LoadAs(g_last_filename); {
std::map<double, int>::iterator it = savedStates.begin();
std::advance(it, i-1);
Load(it->second);
}
}
// must wait for state to be written because it must know if all slots are taken
void SaveFirstSaved()
{
std::map<double, int> savedStates = GetSavedStates();
// save to an empty slot
if (savedStates.size() < NUM_STATES)
Save(GetEmptySlot(savedStates), true);
// overwrite the oldest state
else
{
std::map<double, int>::iterator it = savedStates.begin();
std::advance(it, savedStates.size()-1);
Save(it->second, true);
}
} }
void Flush() void Flush()

View file

@ -14,22 +14,34 @@
namespace State namespace State
{ {
// number of states
static const u32 NUM_STATES = 8;
struct StateHeader
{
u8 gameID[6];
u32 size;
double time;
};
void Init(); void Init();
void Shutdown(); void Shutdown();
void EnableCompression(bool compression); void EnableCompression(bool compression);
bool ReadHeader(const std::string filename, StateHeader& header);
// These don't happen instantly - they get scheduled as events. // These don't happen instantly - they get scheduled as events.
// ...But only if we're not in the main cpu thread. // ...But only if we're not in the main cpu thread.
// If we're in the main cpu thread then they run immediately instead // If we're in the main cpu thread then they run immediately instead
// because some things (like Lua) need them to run immediately. // because some things (like Lua) need them to run immediately.
// Slots from 0-99. // Slots from 0-99.
void Save(int slot); void Save(int slot, bool wait = false);
void Load(int slot); void Load(int slot);
void Verify(int slot); void Verify(int slot);
void SaveAs(const std::string &filename); void SaveAs(const std::string &filename, bool wait = false);
void LoadAs(const std::string &filename); void LoadAs(const std::string &filename);
void VerifyAt(const std::string &filename); void VerifyAt(const std::string &filename);
@ -37,7 +49,8 @@ void SaveToBuffer(std::vector<u8>& buffer);
void LoadFromBuffer(std::vector<u8>& buffer); void LoadFromBuffer(std::vector<u8>& buffer);
void VerifyBuffer(std::vector<u8>& buffer); void VerifyBuffer(std::vector<u8>& buffer);
void LoadLastSaved(); void LoadLastSaved(int i = 1);
void SaveFirstSaved();
void UndoSaveState(); void UndoSaveState();
void UndoLoadState(); void UndoLoadState();

View file

@ -172,6 +172,9 @@ if(ANDROID)
${LIBS} ${LIBS}
"-Wl,--no-whole-archive" "-Wl,--no-whole-archive"
) )
add_custom_command(TARGET ${DOLPHIN_EXE} POST_BUILD
COMMAND cp ARGS ${CMAKE_SOURCE_DIR}/libs/armeabi-v7a/lib${DOLPHIN_EXE}.so ${CMAKE_SOURCE_DIR}/Source/Android/libs/armeabi-v7a
)
else() else()
add_executable(${DOLPHIN_EXE} ${SRCS}) add_executable(${DOLPHIN_EXE} ${SRCS})
target_link_libraries(${DOLPHIN_EXE} ${LIBS} ${WXLIBS}) target_link_libraries(${DOLPHIN_EXE} ${LIBS} ${WXLIBS})

View file

@ -14,6 +14,7 @@
#include "WxUtils.h" #include "WxUtils.h"
#define MAX_CHEAT_SEARCH_RESULTS_DISPLAY 256 #define MAX_CHEAT_SEARCH_RESULTS_DISPLAY 256
const wxString title = _("Cheats Manager");
extern std::vector<ActionReplay::ARCode> arCodes; extern std::vector<ActionReplay::ARCode> arCodes;
extern CFrame* main_frame; extern CFrame* main_frame;
@ -22,26 +23,15 @@ extern CFrame* main_frame;
static wxCheatsWindow *g_cheat_window; static wxCheatsWindow *g_cheat_window;
wxCheatsWindow::wxCheatsWindow(wxWindow* const parent) wxCheatsWindow::wxCheatsWindow(wxWindow* const parent)
: wxDialog(parent, wxID_ANY, _("Cheats Manager"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxDIALOG_NO_PARENT) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxDIALOG_NO_PARENT)
{ {
::g_cheat_window = this; ::g_cheat_window = this;
// Create the GUI controls // Create the GUI controls
Init_ChildControls(); Init_ChildControls();
// Load Data // load codes
Load_ARCodes(); UpdateGUI();
// Load Gecko Codes :/
{
const DiscIO::IVolume* const vol = VolumeHandler::GetVolume();
if (vol)
{
m_gameini_path = File::GetUserPath(D_GAMECONFIG_IDX) + vol->GetUniqueID() + ".ini";
m_gameini.Load(m_gameini_path);
m_geckocode_panel->LoadCodes(m_gameini);
}
}
SetSize(wxSize(-1, 600)); SetSize(wxSize(-1, 600));
Center(); Center();
@ -119,7 +109,7 @@ void wxCheatsWindow::Init_ChildControls()
m_Notebook_Main->AddPage(m_Tab_Log, _("Logging")); m_Notebook_Main->AddPage(m_Tab_Log, _("Logging"));
// Button Strip // Button Strip
wxButton* const button_apply = new wxButton(panel, wxID_APPLY, _("Apply"), wxDefaultPosition, wxDefaultSize); button_apply = new wxButton(panel, wxID_APPLY, _("Apply"), wxDefaultPosition, wxDefaultSize);
button_apply->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &wxCheatsWindow::OnEvent_ApplyChanges_Press, this); button_apply->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &wxCheatsWindow::OnEvent_ApplyChanges_Press, this);
wxButton* const button_cancel = new wxButton(panel, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize); wxButton* const button_cancel = new wxButton(panel, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize);
button_cancel->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &wxCheatsWindow::OnEvent_ButtonClose_Press, this); button_cancel->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &wxCheatsWindow::OnEvent_ButtonClose_Press, this);
@ -249,12 +239,34 @@ void wxCheatsWindow::OnEvent_Close(wxCloseEvent& ev)
Destroy(); Destroy();
} }
// load codes for a new ISO ID
void wxCheatsWindow::UpdateGUI()
{
// load code
m_gameini_path = File::GetUserPath(D_GAMECONFIG_IDX) + Core::g_CoreStartupParameter.GetUniqueID() + ".ini";
m_gameini.Load(m_gameini_path);
Load_ARCodes();
Load_GeckoCodes();
// enable controls
button_apply->Enable(Core::IsRunning());
// write the ISO name in the title
if (Core::IsRunning())
SetTitle(title + ": " + Core::g_CoreStartupParameter.GetUniqueID() + " - " + Core::g_CoreStartupParameter.m_strName);
else
SetTitle(title);
}
void wxCheatsWindow::Load_ARCodes() void wxCheatsWindow::Load_ARCodes()
{ {
using namespace ActionReplay; using namespace ActionReplay;
m_CheckListBox_CheatsList->Clear(); m_CheckListBox_CheatsList->Clear();
if (!Core::IsRunning())
return;
indexList.clear(); indexList.clear();
size_t size = GetCodeListSize(); size_t size = GetCodeListSize();
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
@ -269,6 +281,11 @@ void wxCheatsWindow::Load_ARCodes()
} }
} }
void wxCheatsWindow::Load_GeckoCodes()
{
m_geckocode_panel->LoadCodes(m_gameini, Core::g_CoreStartupParameter.GetUniqueID(), true);
}
void wxCheatsWindow::OnEvent_CheatsList_ItemSelected(wxCommandEvent& WXUNUSED (event)) void wxCheatsWindow::OnEvent_CheatsList_ItemSelected(wxCommandEvent& WXUNUSED (event))
{ {
using namespace ActionReplay; using namespace ActionReplay;

Some files were not shown because too many files have changed in this diff Show more