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_X11 "Enables X11 Support" ON)
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(FASTLOG "Enable all logs" OFF)
@ -84,11 +85,11 @@ endfunction(enable_precompiled_headers)
include(FindGit OPTIONAL)
if(GIT_FOUND AND NOT 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_STRIP_TRAILING_WHITESPACE)
# 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_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}")
# 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_STRIP_TRAILING_WHITESPACE)
endif()
@ -261,11 +262,19 @@ endif()
# For now GLES and EGL are tied to each other.
# Enabling GLES also disables the OpenGL plugin.
if(USE_GLES)
message("GLES rendering enabled")
add_definitions(-DUSE_GLES=1)
add_definitions(-DUSE_EGL=1)
if(USE_GLES3)
message("GLES3 rendering enabled")
add_definitions(-DUSE_GLES=1 -DUSE_EGL=1 -DUSE_GLES3=1)
include_directories(Externals/GLES3)
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()
# For now Wayland and EGL are tied to each other.
# 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)
if(wxWidgets_FOUND)
EXECUTE_PROCESS(
EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
${wxWidgets_CONFIG_OPTIONS} --version
OUTPUT_VARIABLE wxWidgets_VERSION
@ -610,7 +619,7 @@ if(NOT DISABLE_WX AND NOT ANDROID)
endif(wxWidgets_FOUND)
if(wxWidgets_FOUND)
EXECUTE_PROCESS(
EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}"
${wxWidgets_CONFIG_OPTIONS} --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
0406D250 418201BC
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
[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 = Some GFX Glitches And may be slow.
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 @@
# 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
[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.
EmulationStateId = 2
EmulationIssues = Unespecified codes,report to devs
EmulationStateId = 4
EmulationIssues =
[OnFrame] Add memory patches to be applied every frame here.
+$Bypass FIFO reset
0x8028EE80:dword:0x48000638
[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
[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 (r6906)
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]

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
[Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues = No Sound
EmulationStateId = 4
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.
[Video]
# JAAE01 - Super Mario World
[Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues =
EmulationStateId = 4
[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 = 512

View File

@ -1,7 +1,7 @@
# SB3E08 - BASARA
[Core] Values set here will override the main dolphin settings.
[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
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.

View File

@ -1,7 +1,7 @@
# SB3J08 - BASARA
[Core] Values set here will override the main dolphin settings.
[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
[OnFrame] Add memory patches to be applied every frame here.
[ActionReplay] Add action replay cheats here.

View File

@ -1,7 +1,7 @@
# SB3P08 - BASARA
[Core] Values set here will override the main dolphin settings.
[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
[OnFrame] Add memory patches to be applied every frame 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
[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 = 1
EmulationIssues = Requires a Wii save game to boot
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]

View File

@ -2,8 +2,14 @@
[Core] Values set here will override the main dolphin settings.
[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.
EmulationIssues =
EmulationStateId = 1
EmulationStateId = 4
[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

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

View File

@ -0,0 +1 @@
Android

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>

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>

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>

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>

View File

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

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"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.dolphinemu.dolphinemu"
android:versionCode="2"
android:versionName="0.2" >
android:versionCode="5"
android:versionName="0.5" >
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14"/>
@ -28,15 +28,16 @@
<activity
android:name="org.dolphinemu.dolphinemu.GameListView"
android:label="@string/app_name"
android:theme="@android:style/Theme"
android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" >
</activity>
<activity
<activity
android:name="org.dolphinemu.dolphinemu.FolderBrowser"
android:label="@string/app_name"
android:theme="@android:style/Theme"
android:configChanges="orientation|locale|keyboard|keyboardHidden|navigation|fontScale|uiMode" >
</activity>
<activity
android:name=".PrefsActivity" >
</activity>
</application>
</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;
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.content.Context;
import android.content.Intent;
@ -18,6 +10,8 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.WindowManager;
import java.io.*;
public class DolphinEmulator<MainActivity> extends Activity
{
static private NativeGLSurfaceView GLview = null;
@ -25,7 +19,7 @@ public class DolphinEmulator<MainActivity> extends Activity
private float screenWidth;
private float screenHeight;
public static native void onTouchEvent(int Action, float X, float Y);
static
@ -143,7 +137,7 @@ public class DolphinEmulator<MainActivity> extends Activity
String FileName = data.getStringExtra("Select");
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.SetFileName(FileName);
setContentView(GLview);
@ -169,7 +163,7 @@ public class DolphinEmulator<MainActivity> extends Activity
return false;
}
public boolean overrideKeys()
public boolean overrideKeys()
{
return false;
}

View File

@ -1,29 +1,19 @@
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.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
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.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 {
private GameListAdapter adapter;
@ -59,8 +49,8 @@ public class FolderBrowser extends ListActivity {
Collections.sort(dir);
Collections.sort(fls);
dir.addAll(fls);
if (!f.getName().equalsIgnoreCase("sdcard"))
dir.add(0, new GameListItem(getApplicationContext(), "..", "Parent Directory", f.getParent()));
if (!f.getPath().equalsIgnoreCase("/"))
dir.add(0, new GameListItem(getApplicationContext(), "..", "Parent Directory", f.getParent()));
adapter = new GameListAdapter(this,R.layout.folderbrowser,dir);
this.setListAdapter(adapter);
@ -68,7 +58,6 @@ public class FolderBrowser extends ListActivity {
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
GameListItem o = adapter.getItem(position);
if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){
@ -87,12 +76,18 @@ public class FolderBrowser extends ListActivity {
Fill(currentDir);
}
@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.putExtra("Select", currentDir.getPath());
setResult(Activity.RESULT_OK, intent);
this.finish();
super.onBackPressed();
this.finish();
return true;
}
}

View File

@ -1,85 +1,79 @@
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.util.ArrayList;
import java.util.Collections;
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 {
private GameListAdapter adapter;
private static File currentDir = null;
private MenuDrawer mDrawer;
private SideMenuAdapter mAdapter;
private ListView mList;
private static GameListView me;
public static native String GetConfig(String Key, String Value, String Default);
public static native void SetConfig(String Key, String Value, String Default);
enum keyTypes {TYPE_STRING, TYPE_BOOL};
private void Fill(File f)
private void Fill()
{
File[]dirs = f.listFiles();
this.setTitle("Game List");
List<GameListItem>dir = new ArrayList<GameListItem>();
List<GameListItem>fls = new ArrayList<GameListItem>();
try
String Directories = GetConfig("General", "GCMPathes", "0");
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) != '.')
if(!ff.isDirectory())
if (ff.getName().toLowerCase().contains(".gcm") ||
ff.getName().toLowerCase().contains(".iso") ||
ff.getName().toLowerCase().contains(".wbfs") ||
ff.getName().toLowerCase().contains(".gcz") ||
ff.getName().toLowerCase().contains(".dol") ||
ff.getName().toLowerCase().contains(".elf"))
fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath()));
}
}
catch(Exception e)
{
}
Collections.sort(dir);
Collections.sort(fls);
dir.addAll(fls);
adapter = new GameListAdapter(this,R.layout.main,dir);
this.setListAdapter(adapter);
for(File ff: dirs)
{
if (ff.getName().charAt(0) != '.')
if(!ff.isDirectory())
if (ff.getName().toLowerCase().contains(".gcm") ||
ff.getName().toLowerCase().contains(".iso") ||
ff.getName().toLowerCase().contains(".wbfs") ||
ff.getName().toLowerCase().contains(".gcz") ||
ff.getName().toLowerCase().contains(".dol") ||
ff.getName().toLowerCase().contains(".elf") ||
ff.getName().toLowerCase().contains(".dff"))
fls.add(new GameListItem(getApplicationContext(), ff.getName(),"File Size: "+ff.length(),ff.getAbsolutePath()));
}
}
catch(Exception ignored)
{
}
}
Collections.sort(fls);
adapter = new GameListAdapter(this,R.layout.main, fls);
this.setListAdapter(adapter);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
GameListItem o = adapter.getItem(position);
if(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")){
}
else
{
if(!(o.getData().equalsIgnoreCase("folder")||o.getData().equalsIgnoreCase("parent directory")))
{
onFileClick(o.getPath());
}
}
@ -98,17 +92,67 @@ public class GameListView extends ListActivity {
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK)
{
String FileName = data.getStringExtra("Select");
Toast.makeText(this, "Folder Selected: " + FileName, Toast.LENGTH_SHORT).show();
SetConfig("General", "GCMPathes", "1");
SetConfig("General", "GCMPaths0", FileName);
currentDir = new File(FileName);
Fill(currentDir);
}
switch (requestCode)
{
// Browse
case 1:
if (resultCode == Activity.RESULT_OK)
{
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);
Fill();
}
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
@ -119,15 +163,14 @@ public class GameListView extends ListActivity {
mDrawer = MenuDrawer.attach(this, MenuDrawer.MENU_DRAG_CONTENT);
String BrowseDir = GetConfig("General", "GCMPaths0", "");
if(currentDir == null)
currentDir = new File(BrowseDir);
Fill(currentDir);
Fill();
List<SideMenuItem>dir = new ArrayList<SideMenuItem>();
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);
mList.setAdapter(mAdapter);
mList.setOnItemClickListener(mItemClickListener);
@ -145,6 +188,11 @@ public class GameListView extends ListActivity {
Intent ListIntent = new Intent(me, FolderBrowser.class);
startActivityForResult(ListIntent, 1);
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:
break;
}
@ -157,25 +205,18 @@ public class GameListView extends ListActivity {
mDrawer.setContentView(layoutResID);
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 void onBackPressed() {
final int drawerState = mDrawer.getDrawerState();
if (drawerState == MenuDrawer.STATE_OPEN || drawerState == MenuDrawer.STATE_OPENING) {
mDrawer.closeMenu();
return;
}
super.onBackPressed();
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.KEYCODE_MENU|| event.getAction() == KeyEvent.KEYCODE_BACK) {
final int drawerState = mDrawer.getDrawerState();
if (drawerState == MenuDrawer.STATE_OPEN || drawerState == MenuDrawer.STATE_OPENING) {
mDrawer.closeMenu();
return true;
}
mDrawer.openMenu();
return true;
}
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;
/**
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2
* Refer to the license.txt file included.
*/
public class SideMenuItem implements Comparable<SideMenuItem>{
private String m_name;
private int m_id;

View File

@ -97,7 +97,7 @@ void OpenALStream::SetVolume(int volume)
fVolume = (float)volume / 100.0f;
if (uiSource)
alSourcef(uiSource, AL_GAIN, fVolume);
alSourcef(uiSource, AL_GAIN, fVolume);
}
void OpenALStream::Update()
@ -124,6 +124,17 @@ void OpenALStream::SoundLoop()
{
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();
numBuffers = Core::g_CoreStartupParameter.iLatency + 2; // OpenAL requires a minimum of two buffers
@ -136,22 +147,20 @@ void OpenALStream::SoundLoop()
alGenSources(1, &uiSource);
// Short Silence
memset(sampleBuffer, 0, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * numBuffers);
memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * 4);
memset(sampleBuffer, 0, OAL_MAX_SAMPLES * numBuffers * FRAME_SURROUND_FLOAT);
memset(realtimeBuffer, 0, OAL_MAX_SAMPLES * FRAME_STEREO_SHORT);
for (int i = 0; i < numBuffers; i++)
{
#if !defined(__APPLE__)
if (Core::g_CoreStartupParameter.bDPL2Decoder)
alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * SIZE_FLOAT * SURROUND_CHANNELS, ulFrequency);
if (surround_capable)
alBufferData(uiBuffers[i], AL_FORMAT_51CHN32, sampleBuffer, 4 * FRAME_SURROUND_FLOAT, ulFrequency);
else
#endif
alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * 2 * 2, ulFrequency);
alBufferData(uiBuffers[i], AL_FORMAT_STEREO16, realtimeBuffer, 4 * FRAME_STEREO_SHORT, ulFrequency);
}
alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
alSourcePlay(uiSource);
// Set the default sound volume as saved in the config file.
alSourcef(uiSource, AL_GAIN, fVolume);
alSourcef(uiSource, AL_GAIN, fVolume);
// TODO: Error handling
//ALenum err = alGetError();
@ -170,14 +179,7 @@ void OpenALStream::SoundLoop()
soundTouch.setSetting(SETTING_SEEKWINDOW_MS, 28);
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.
const u32 stereo_16_bit_size = 4;
@ -193,12 +195,9 @@ void OpenALStream::SoundLoop()
numSamples = m_mixer->Mix(realtimeBuffer, numSamples);
// Convert the samples from short to float
float dest[OAL_MAX_SAMPLES * 2 * 2 * OAL_MAX_BUFFERS];
for (u32 i = 0; i < numSamples; ++i)
{
dest[i * 2 + 0] = (float)realtimeBuffer[i * 2 + 0] / (1 << 16);
dest[i * 2 + 1] = (float)realtimeBuffer[i * 2 + 1] / (1 << 16);
}
float dest[OAL_MAX_SAMPLES * STEREO_CHANNELS];
for (u32 i = 0; i < numSamples * STEREO_CHANNELS; ++i)
dest[i] = (float)realtimeBuffer[i] / (1 << 16);
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)
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]);
alSourceUnqueueBuffers(uiSource, iBuffersProcessed, uiBufferTemp);
ALenum err = alGetError();
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);
err = alGetError();
if (err != 0)
// 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);
}
}
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);
if (iState != AL_PLAYING)
else
{
// Buffer underrun occurred, resume playback
alSourcePlay(uiSource);
err = alGetError();
if (err != 0)
{
ERROR_LOG(AUDIO, "Error occurred resuming playback: %08x", err);
}
// Convert the samples from float to short
short stereo[OAL_MAX_SAMPLES * STEREO_CHANNELS * OAL_MAX_BUFFERS];
for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
stereo[i] = (short)((float)sampleBuffer[i] * (1 << 16));
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>
// 16 bit Stereo
#define SFX_MAX_SOURCE 1
#define OAL_MAX_BUFFERS 32
#define OAL_MAX_SAMPLES 256
#define SURROUND_CHANNELS 6 // number of channels in surround mode
#define SIZE_FLOAT 4 // size of a float in bytes
#define SFX_MAX_SOURCE 1
#define OAL_MAX_BUFFERS 32
#define OAL_MAX_SAMPLES 256
#define STEREO_CHANNELS 2
#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
class OpenALStream: public SoundStream
@ -61,8 +66,8 @@ private:
std::thread thread;
Common::Event soundSyncEvent;
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
short realtimeBuffer[OAL_MAX_SAMPLES * STEREO_CHANNELS];
soundtouch::SAMPLETYPE sampleBuffer[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
ALuint uiBuffers[OAL_MAX_BUFFERS];
ALuint uiSource;
ALfloat fVolume;

View File

@ -86,6 +86,45 @@ inline u64 _rotr64(u64 x, unsigned int shift){
#define unlink _unlink
#define snprintf _snprintf
#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
#define fseeko _fseeki64

View File

@ -13,61 +13,54 @@ namespace MathUtil
{
u32 ClassifyDouble(double dvalue)
{
// TODO: Optimize the below to be as fast as possible.
IntDouble value;
value.d = dvalue;
u64 sign = value.i & DOUBLE_SIGN;
u64 exp = value.i & DOUBLE_EXP;
if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP)
{
// Nice normalized number.
return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
}
else
{
u64 mantissa = value.i & DOUBLE_FRAC;
if (mantissa)
{
if (exp)
{
return PPC_FPCLASS_QNAN;
}
else
{
// Denormalized number.
return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
}
}
else if (exp)
{
//Infinite
return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
}
else
{
//Zero
return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
}
}
}
{
// TODO: Optimize the below to be as fast as possible.
u64 exp = *(u64*)(&dvalue) & DOUBLE_EXP;
if (exp != DOUBLE_ZERO && exp != DOUBLE_EXP)
{
// Nice normalized number.
return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
}
else
{
if (*(u64*)(&dvalue) & DOUBLE_FRAC)
{
if (exp)
{
return PPC_FPCLASS_QNAN;
}
else
{
// Denormalized number.
return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
}
}
else if (exp)
{
//Infinite
return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
}
else
{
//Zero
return *(u64*)(&dvalue)&DOUBLE_SIGN ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
}
}
}
u32 ClassifyFloat(float fvalue)
{
// TODO: Optimize the below to be as fast as possible.
IntFloat value;
value.f = fvalue;
u32 sign = value.i & FLOAT_SIGN;
u32 exp = value.i & FLOAT_EXP;
u32 exp = *(u32*)(&fvalue) & FLOAT_EXP;
if (exp > FLOAT_ZERO && exp < FLOAT_EXP)
{
// Nice normalized number.
return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
return *(u32*)(&fvalue) & FLOAT_SIGN ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
}
else
{
u32 mantissa = value.i & FLOAT_FRAC;
if (mantissa)
if (*(u32*)(&fvalue) & FLOAT_FRAC)
{
if (exp)
{
@ -76,18 +69,18 @@ u32 ClassifyFloat(float fvalue)
else
{
// Denormalized number.
return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
return *(u32*)(&fvalue) & FLOAT_SIGN ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
}
}
else if (exp)
{
// Infinite
return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
return *(u32*)(&fvalue) & FLOAT_SIGN ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
}
else
{
//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_VideoDX11/Src/VideoBackend.h"
#endif
#ifndef USE_GLES
#if !defined(USE_GLES) || USE_GLES3
#include "../../../Plugins/Plugin_VideoOGL/Src/VideoBackend.h"
#endif
#include "../../../Plugins/Plugin_VideoSoftware/Src/VideoBackend.h"
@ -45,7 +45,7 @@ void VideoBackend::PopulateList()
if (IsGteVista())
g_available_video_backends.push_back(backends[0] = new DX11::VideoBackend);
#endif
#ifndef USE_GLES
#if !defined(USE_GLES) || USE_GLES3
g_available_video_backends.push_back(backends[1] = new OGL::VideoBackend);
#endif
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_DeviceAMBaseboard.cpp
Src/HW/SI_Device.cpp
Src/HW/SI_DeviceDanceMat.cpp
Src/HW/SI_DeviceGBA.cpp
Src/HW/SI_DeviceGCController.cpp
Src/HW/SI_DeviceGCSteeringWheel.cpp
@ -216,7 +217,7 @@ endif()
set(LIBS bdisasm inputcommon videosoftware sfml-network)
if(NOT USE_GLES)
if(NOT USE_GLES OR USE_GLES3)
set(LIBS ${LIBS} videoogl)
endif()

View File

@ -298,6 +298,7 @@
<ClCompile Include="Src\HW\SI.cpp" />
<ClCompile Include="Src\HW\SI_Device.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_DeviceGCController.cpp" />
<ClCompile Include="Src\HW\SI_DeviceGCSteeringWheel.cpp" />
@ -498,6 +499,7 @@
<ClInclude Include="Src\HW\SI.h" />
<ClInclude Include="Src\HW\SI_Device.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_DeviceGCController.h" />
<ClInclude Include="Src\HW\SI_DeviceGCSteeringWheel.h" />

View File

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

View File

@ -60,6 +60,7 @@ bool BootCore(const std::string& _rFilename)
StartUp.m_BootType = SCoreStartupParameter::BOOT_ISO;
StartUp.m_strFilename = _rFilename;
SConfig::GetInstance().m_LastFilename = _rFilename;
SConfig::GetInstance().SaveSettings();
StartUp.bRunCompareClient = 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);
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
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
// Init the core
if (!Core::Init())

View File

@ -35,6 +35,7 @@ static const struct {
{ "ToggleFullscreen", 70 /* 'F' */, 2 /* wxMOD_CMD */ },
{ "Screenshot", 83 /* 'S' */, 2 /* wxMOD_CMD */ },
{ "Exit", 0, 0 /* wxMOD_NONE */ },
{ "Wiimote1Connect", 49 /* '1' */, 2 /* wxMOD_CMD */ },
{ "Wiimote2Connect", 50 /* '2' */, 2 /* wxMOD_CMD */ },
@ -57,6 +58,7 @@ static const struct {
{ "ToggleFullscreen", 13 /* WXK_RETURN */, 1 /* wxMOD_ALT */ },
{ "Screenshot", 348 /* WXK_F9 */, 0 /* wxMOD_NONE */ },
{ "Exit", 0, 0 /* wxMOD_NONE */ },
{ "Wiimote1Connect", 344 /* WXK_F5 */, 1 /* wxMOD_ALT */ },
{ "Wiimote2Connect", 345 /* WXK_F6 */, 1 /* wxMOD_ALT */ },
@ -81,6 +83,19 @@ static const struct {
{ "SaveStateSlot6", 345 /* WXK_F6 */, 4 /* wxMOD_SHIFT */ },
{ "SaveStateSlot7", 346 /* WXK_F7 */, 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()
@ -319,7 +334,7 @@ void SConfig::LoadSettings()
// Display
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", "RenderWindowXPos", &m_LocalCoreStartupParameter.iRenderWindowXPos, -1);
ini.Get("Display", "RenderWindowYPos", &m_LocalCoreStartupParameter.iRenderWindowYPos, -1);

View File

@ -394,10 +394,10 @@ void EmuThread()
Wiimote::Initialize(g_pWindowHandle);
// 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])
GetUsbPointer()->AccessWiiMote(i | 0x100)->
Activate(true);
GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true);
}
// The hardware is initialized.
@ -680,7 +680,8 @@ void UpdateTitle()
u32 Speed = DrawnVideo * (100 * 1000) / (VideoInterface::TargetRefreshRate * ElapseTime);
// 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,
// 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;
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%%)",
_CoreParameter.bSkipIdle ? "~" : "",
(int)(diff),
@ -710,11 +711,11 @@ void UpdateTitle()
#else // Summary information
std::string SFPS;
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())
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
SFPS = StringFromFormat("FPS: %u - VPS: %u - SPEED: %u%%", FPS, VPS, Speed);
SFPS = StringFromFormat("FPS: %u - VPS: %u - %u%%", FPS, VPS, Speed);
#endif
// This is our final "frame counter" string

View File

@ -26,6 +26,7 @@ enum Hotkey
HK_FULLSCREEN,
HK_SCREENSHOT,
HK_EXIT,
HK_WIIMOTE1_CONNECT,
HK_WIIMOTE2_CONNECT,
@ -50,6 +51,19 @@ enum Hotkey
HK_SAVE_STATE_SLOT_7,
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,
};

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.
// 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);
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;
cyclesLeft = 0;
init_hax = false;
dspjit = NULL;
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);
g_dsp.iram_crc = DSPHost_CodeLoaded(g_dsp.cpu_ram + (addr & 0x0fffffff), size);
NOTICE_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc);
DSPHost_CodeLoaded((const u8*)g_dsp.iram + dsp_addr, size);
if (dspjit)
dspjit->ClearIRAM();
DSPAnalyzer::Analyze();
NOTICE_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)", addr, dsp_addr, g_dsp.iram_crc);
}
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_Wii();
void DSPHost_InterruptRequest();
u32 DSPHost_CodeLoaded(const u8 *ptr, int size);
void DSPHost_CodeLoaded(const u8 *ptr, int size);
void DSPHost_UpdateDebugger();
#endif

View File

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

View File

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

View File

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

View File

@ -687,12 +687,29 @@ void UpdateAudioDMA()
void Do_ARAM_DMA()
{
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.
if (g_arDMA.Cnt.count > 2048 && g_arDMA.Cnt.count <= 6144)
if (g_arDMA.Cnt.count == 32)
{
// Beyond Good and Evil (GGEE41) sends count 32
// Lost Kingdoms 2 needs the exception check here in DSP HLE mode
GenerateDSPInterrupt(INT_ARAM);
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
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());
FILE* fp = fopen(filename.c_str(), "rb");
fread(m_coeffs, 1, 0x1000, fp);
fclose(fp);
File::IOFile fp(filename, "rb");
fp.ReadBytes(m_coeffs, 0x1000);
for (u32 i = 0; i < 0x800; ++i)
m_coeffs[i] = Common::swap16(m_coeffs[i]);

View File

@ -4,6 +4,8 @@
#include "Common.h"
#include "Hash.h"
#include "DSP/DSPAnalyzer.h"
#include "DSP/DSPCore.h"
#include "DSP/DSPHost.h"
#include "DSPSymbols.h"
#include "DSPLLETools.h"
@ -45,23 +47,23 @@ void DSPHost_InterruptRequest()
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)
DumpDSPCode(ptr, size, ector_crc);
DumpDSPCode(ptr, size, g_dsp.iram_crc);
#endif
DSPSymbols::Clear();
// 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();
bool success = false;
switch (ector_crc)
switch (g_dsp.iram_crc)
{
case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../docs/DSP/DSP_UC_Zelda.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();
return ector_crc;
if (dspjit)
dspjit->ClearIRAM();
DSPAnalyzer::Analyze();
}
void DSPHost_UpdateDebugger()

View File

@ -16,6 +16,7 @@
#include "Core.h"
#include "DSPLLEGlobals.h" // Local
#include "DSP/DSPHost.h"
#include "DSP/DSPInterpreter.h"
#include "DSP/DSPHWInterface.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.iram_crc);
p.Do(g_dsp.step_counter);
p.Do(g_dsp.ifx_regs);
p.Do(g_dsp.mbox[0]);
@ -75,8 +75,11 @@ void DSPLLE::DoState(PointerWrap &p)
UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
p.DoArray(g_dsp.iram, DSP_IRAM_SIZE);
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.Do(cyclesLeft);
p.Do(init_hax);
p.Do(m_cycle_count);
bool prevInitMixer = m_InitMixer;

View File

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

View File

@ -215,7 +215,12 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis)
}
mcdFile.Close();
initDirBatPointers();
}
void GCMemcard::initDirBatPointers()
{
if (BE16(dir.UpdateCounter) > (BE16(dir_backup.UpdateCounter)))
{
CurrentDir = &dir;
@ -1273,7 +1278,8 @@ bool GCMemcard::Format(bool sjis, u16 SizeMb)
GCMBlock b;
mc_data_blocks.push_back(b);
}
initDirBatPointers();
m_valid = true;
return Save();

View File

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

View File

@ -598,9 +598,6 @@ union UPTE2
u32 Hex;
};
u32 pagetable_base = 0;
u32 pagetable_hashmask = 0;
void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite)
{
if (_bWrite)
@ -644,8 +641,8 @@ void SDRUpdated()
{
return;
}
pagetable_base = htaborg<<16;
pagetable_hashmask = ((xx<<10)|0x3ff);
PowerPC::ppcState.pagetable_base = htaborg<<16;
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
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
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
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++)
{
u32 pte = bswap(*(u32*)&pRAM[pteg_addr]);

View File

@ -5,6 +5,7 @@
#include "SI_Device.h"
#include "SI_DeviceGCController.h"
#include "SI_DeviceGCSteeringWheel.h"
#include "SI_DeviceDanceMat.h"
#include "SI_DeviceGBA.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);
break;
case SIDEVICE_DANCEMAT:
return new CSIDevice_DanceMat(device, port_number);
break;
case SIDEVICE_GC_STEERING:
return new CSIDevice_GCSteeringWheel(device, port_number);
break;

View File

@ -34,6 +34,7 @@ enum TSIDevices
SI_GC_CONTROLLER = (SI_TYPE_GC | SI_GC_STANDARD),
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_DANCEMAT = (SI_TYPE_GC | SI_GC_STANDARD | 0x00000300),
SI_AM_BASEBOARD = 0x10110800 // gets ORd with dipswitch state
};
@ -49,6 +50,7 @@ enum SIDevices
SIDEVICE_GC_CONTROLLER,
SIDEVICE_GC_KEYBOARD,
SIDEVICE_GC_STEERING,
SIDEVICE_DANCEMAT,
SIDEVICE_GC_TARUKONGA,
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 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
// TODO: Are the "Bottom Field" and "Top Field" registers actually more
// like "First Field" and "Second Field" registers? There's an important
// difference because NTSC and PAL have opposite field orders.
u32 xfbAddr = (field == FIELD_LOWER) ? GetXFBAddressBottom() : GetXFBAddressTop();
// NTSC and PAL have opposite field orders.
FieldType order = (m_DisplayControlRegister.FMT == 0) ? FIELD_LOWER : FIELD_UPPER;
u32 xfbAddr = (field == order) ? GetXFBAddressBottom() : GetXFBAddressTop();
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };

View File

@ -42,9 +42,10 @@ void Shutdown()
void Initialize(void* const hwnd)
{
// 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_controller_interface.SetHwnd(hwnd);
g_controller_interface.Initialize();
@ -134,7 +135,7 @@ void Update(int _number)
unsigned int GetAttached()
{
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])
attached |= (1 << i);
return attached;
@ -151,7 +152,7 @@ void DoState(u8 **ptr, PointerWrap::Mode mode)
// TODO:
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);
}

View File

@ -8,7 +8,16 @@
#include "../../InputCommon/Src/InputConfig.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"
@ -20,7 +29,7 @@ enum
WIIMOTE_SRC_HYBRID = 3, // emu + real
};
extern unsigned int g_wiimote_sources[MAX_WIIMOTES];
extern unsigned int g_wiimote_sources[MAX_BBMOTES];
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);
AccelData accel;
accel_cal* calib = (accel_cal*)&reg[0x20];
// tilt
EmulateTilt(&accel, m_tilt, focus);
@ -81,7 +82,7 @@ void Nunchuk::GetState(u8* const data, const bool focus)
// swing
EmulateSwing(&accel, m_swing);
// shake
EmulateShake(&accel, m_shake, m_shake_step);
EmulateShake(&accel, calib, m_shake, m_shake_step);
// buttons
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;
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->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));

View File

@ -86,6 +86,7 @@ const ReportFeatures reporting_mode_features[] =
};
void EmulateShake(AccelData* const accel
, accel_cal* const calib
, ControllerEmu::Buttons* const buttons_group
, u8* const shake_step )
{
@ -94,7 +95,7 @@ void EmulateShake(AccelData* const accel
auto const shake_step_max = 15;
// peak G-force
auto const shake_intensity = 3.f;
double shake_intensity;
// shake is a bitfield of X,Y,Z shake button states
static const unsigned int btns[] = { 0x01, 0x02, 0x04 };
@ -105,6 +106,9 @@ void EmulateShake(AccelData* const accel
{
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;
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 is_sideways = m_options->settings[1]->value != 0;
const bool is_upright = m_options->settings[2]->value != 0;
accel_cal* calib = (accel_cal*)&m_eeprom[0x16];
// ----TILT----
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)
{
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);
}
wm_accel* dt = (wm_accel*)data;
accel_cal* calib = (accel_cal*)&m_eeprom[0x16];
double cx,cy,cz;
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);

View File

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

View File

@ -32,9 +32,10 @@ WiimoteScanner::~WiimoteScanner()
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

View File

@ -63,23 +63,22 @@ WiimoteScanner::~WiimoteScanner()
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
int const wait_len = 1;
int const max_infos = 255;
inquiry_info scan_infos[max_infos] = {};
auto* scan_infos_ptr = scan_infos;
found_board = NULL;
// Scan for bluetooth devices
int const found_devices = hci_inquiry(device_id, wait_len, max_infos, NULL, &scan_infos_ptr, IREQ_CACHE_FLUSH);
if (found_devices < 0)
{
ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices.");
return found_wiimotes;
return;
}
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
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");
continue;
@ -119,14 +118,20 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
auto* const wm = new Wiimote;
wm->bdaddr = scan_infos[i].bdaddr;
found_wiimotes.push_back(wm);
NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str);
if(IsBalanceBoardName(name))
{
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.

View File

@ -87,8 +87,8 @@ inline void init_lib()
hid_lib = LoadLibrary(_T("hid.dll"));
if (!hid_lib)
{
PanicAlertT("Failed to load hid.dll");
exit(EXIT_FAILURE);
PanicAlertT("Failed to load hid.dll! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
return;
}
HidD_GetHidGuid = (PHidD_GetHidGuid)GetProcAddress(hid_lib, "HidD_GetHidGuid");
@ -98,15 +98,15 @@ inline void init_lib()
if (!HidD_GetHidGuid || !HidD_GetAttributes ||
!HidD_SetOutputReport || !HidD_GetProductString)
{
PanicAlertT("Failed to load hid.dll");
exit(EXIT_FAILURE);
PanicAlertT("Failed to load hid.dll! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
return;
}
bthprops_lib = LoadLibrary(_T("bthprops.cpl"));
if (!bthprops_lib)
{
PanicAlertT("Failed to load bthprops.cpl");
exit(EXIT_FAILURE);
PanicAlertT("Failed to load bthprops.cpl! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
return;
}
Bth_BluetoothFindDeviceClose = (PBth_BluetoothFindDeviceClose)GetProcAddress(bthprops_lib, "BluetoothFindDeviceClose");
@ -128,8 +128,8 @@ inline void init_lib()
!Bth_BluetoothSetServiceState || !Bth_BluetoothAuthenticateDevice ||
!Bth_BluetoothEnumerateInstalledServices)
{
PanicAlertT("Failed to load bthprops.cpl");
exit(EXIT_FAILURE);
PanicAlertT("Failed to load bthprops.cpl! Connecting real Wiimotes won't work and Dolphin might crash unexpectedly!");
return;
}
initialized = true;
@ -138,6 +138,10 @@ inline void init_lib()
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>
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.
// wm is an array of max_wiimotes 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)
{
@ -198,8 +202,6 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
// Get all hid devices connected
HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));
std::vector<Wiimote*> wiimotes;
SP_DEVICE_INTERFACE_DATA device_data;
device_data.cbSize = sizeof(device_data);
PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL;
@ -214,10 +216,24 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
// Query the data for this device
if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL))
{
{
auto const wm = new Wiimote;
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);
@ -229,7 +245,183 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
//if (!wiimotes.empty())
// 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
@ -355,7 +547,7 @@ bool Wiimote::IsConnected() const
// positive = read packet
// negative = didn't read packet
// 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)
buf[0] = 0xa1;
@ -408,78 +600,92 @@ int Wiimote::IORead(u8* buf)
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)
{
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)
case MSBT_STACK_UNKNOWN:
{
auto err = GetLastError();
if (err == 121)
// Try to auto-detect the stack type
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
NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote");
auto err = GetLastError();
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
{
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;
}
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
template <typename T>
void ProcessWiimotes(bool new_scan, T& callback)
@ -498,7 +704,7 @@ void ProcessWiimotes(bool new_scan, T& callback)
BLUETOOTH_FIND_RADIO_PARAMS radioParam;
radioParam.dwSize = sizeof(radioParam);
HANDLE hRadio;
// TODO: save radio(s) in the WiimoteScanner constructor?

View File

@ -116,22 +116,21 @@ WiimoteScanner::~WiimoteScanner()
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
std::vector<Wiimote*> wiimotes;
IOBluetoothHostController *bth;
IOBluetoothDeviceInquiry *bti;
SearchBT *sbt;
NSEnumerator *en;
found_board = NULL;
bth = [[IOBluetoothHostController alloc] init];
if ([bth addressAsString] == nil)
{
WARN_LOG(WIIMOTE, "No bluetooth host controller");
[bth release];
return wiimotes;
return;
}
sbt = [[SearchBT alloc] init];
@ -162,14 +161,20 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
Wiimote *wm = new Wiimote();
wm->btd = dev;
wiimotes.push_back(wm);
if(IsBalanceBoardName([[dev name] UTF8String]))
{
found_board = wm;
}
else
{
found_wiimotes.push_back(wm);
}
}
[bth release];
[bti release];
[sbt release];
return wiimotes;
}
bool WiimoteScanner::IsReady() const

View File

@ -17,12 +17,13 @@
#include "../WiimoteEmu/WiimoteHid.h"
unsigned int g_wiimote_sources[MAX_WIIMOTES];
unsigned int g_wiimote_sources[MAX_BBMOTES];
namespace WiimoteReal
{
void HandleFoundWiimotes(const std::vector<Wiimote*>&);
void TryToConnectBalanceBoard(Wiimote*);
void TryToConnectWiimote(Wiimote*);
void HandleWiimoteDisconnect(int index);
void DoneWithWiimote(int index);
@ -31,8 +32,7 @@ bool g_real_wiimotes_initialized = false;
std::recursive_mutex g_refresh_lock;
Wiimote* g_wiimotes[MAX_WIIMOTES];
Wiimote* g_wiimotes[MAX_BBMOTES];
WiimoteScanner g_wiimote_scanner;
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};
// 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
u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_RUMBLE, 0};
@ -325,11 +325,25 @@ unsigned int CalculateWantedWiimotes()
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)
{
m_want_wiimotes = do_want;
}
void WiimoteScanner::WantBB(bool do_want)
{
m_want_bb = do_want;
}
void WiimoteScanner::StartScanning()
{
if (!m_run_thread)
@ -352,7 +366,7 @@ void CheckForDisconnectedWiimotes()
{
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())
HandleWiimoteDisconnect(i);
}
@ -366,12 +380,13 @@ void WiimoteScanner::ThreadFunc()
while (m_run_thread)
{
std::vector<Wiimote*> found_wiimotes;
Wiimote* found_board = NULL;
//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
{
@ -384,7 +399,10 @@ void WiimoteScanner::ThreadFunc()
// TODO: this is a fairly lame place for this
CheckForDisconnectedWiimotes();
HandleFoundWiimotes(found_wiimotes);
if(m_want_wiimotes)
HandleFoundWiimotes(found_wiimotes);
if(m_want_bb && found_board)
TryToConnectBalanceBoard(found_board);
//std::this_thread::yield();
Common::SleepCurrentThread(500);
@ -439,6 +457,10 @@ void LoadSettings()
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
@ -452,6 +474,7 @@ void Initialize()
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
if (g_real_wiimotes_initialized)
return;
@ -474,20 +497,21 @@ void Shutdown(void)
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);
}
void ChangeWiimoteSource(unsigned int index, int source)
{
{
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
g_wiimote_sources[index] = source;
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
// kill real connection (or swap to different slot)
DoneWithWiimote(index);
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());
// kill real connection (or swap to different slot)
DoneWithWiimote(index);
}
// reconnect to the emulator
@ -500,7 +524,7 @@ void TryToConnectWiimote(Wiimote* wm)
{
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]
&& !g_wiimotes[i])
@ -525,16 +549,41 @@ void TryToConnectWiimote(Wiimote* 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)
{
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
if (g_wiimotes[index])
{
g_wiimotes[index]->StopThread();
// 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]
&& !g_wiimotes[i])
@ -560,9 +609,11 @@ void HandleWiimoteDisconnect(int index)
Wiimote* wm = NULL;
{
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
std::swap(wm, g_wiimotes[index]);
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
std::swap(wm, g_wiimotes[index]);
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
}
if (wm)
@ -583,31 +634,35 @@ void Refresh()
g_wiimote_scanner.StopScanning();
{
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
std::vector<Wiimote*> found_wiimotes;
if (0 != CalculateWantedWiimotes())
{
// 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])
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
std::vector<Wiimote*> found_wiimotes;
Wiimote* found_board = NULL;
if (0 != CalculateWantedWiimotes() || 0 != CalculateWantedBB())
{
g_wiimotes[i]->StopThread();
g_wiimotes[i]->Prepare(i);
g_wiimotes[i]->StartThread();
// Don't hang Dolphin when searching
lk.unlock();
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();
@ -616,7 +671,6 @@ void Refresh()
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
{
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
if (g_wiimotes[_WiimoteNumber])
g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size);
}
@ -656,7 +710,14 @@ bool IsValidBluetoothName(const std::string& name)
{
return
"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

View File

@ -117,11 +117,12 @@ public:
bool IsReady() const;
void WantWiimotes(bool do_want);
void WantBB(bool do_want);
void StartScanning();
void StopScanning();
std::vector<Wiimote*> FindWiimotes();
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&);
// function called when not looking for more wiimotes
void Update();
@ -133,10 +134,10 @@ private:
volatile bool m_run_thread;
volatile bool m_want_wiimotes;
volatile bool m_want_bb;
#if defined(_WIN32)
void CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb);
#elif defined(__linux__) && HAVE_BLUEZ
int device_id;
int device_sock;
@ -145,7 +146,7 @@ private:
extern std::recursive_mutex g_refresh_lock;
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 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);
bool IsValidBluetoothName(const std::string& name);
bool IsBalanceBoardName(const std::string& name);
}; // 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
{
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;
u8 i = 0;
while (i < maxWM)
@ -43,28 +43,60 @@ 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[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];
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]);
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
i++;
}
while (i < CONF_PAD_MAX_ACTIVE)
while (i < MAX_BBMOTES)
{
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);
if(i == WIIMOTE_BALANCE_BOARD)
{
const char * wmName = "Nintendo RVL-WBC-01";
++BT_DINF.num_registered;
BT_DINF.balance_board.bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i;
BT_DINF.balance_board.bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0;
BT_DINF.balance_board.bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79;
BT_DINF.balance_board.bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19;
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, "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));
}
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));
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++;
}
// save now so that when games load sysconf file it includes the new wiimotes
// and the correct order for connected wiimotes
if (!SConfig::GetInstance().m_SYSCONF->SetArrayData("BT.DINF", (u8*)&BT_DINF, sizeof(_conf_pads)) || !SConfig::GetInstance().m_SYSCONF->Save())
@ -99,18 +131,18 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
p.DoPOD(m_HCIEndpoint);
p.DoPOD(m_ACLEndpoint);
p.Do(m_last_ticks);
p.DoArray(m_PacketCount,4);
p.DoArray(m_PacketCount,MAX_BBMOTES);
p.Do(m_ScanEnable);
p.Do(m_EventQueue);
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);
// Reset the connection of real and hybrid wiimotes
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])
continue;

View File

@ -12,6 +12,7 @@
#include "WII_IPC_HLE.h"
#include "WII_IPC_HLE_Device.h"
#include "WII_IPC_HLE_WiiMote.h"
#include "../HW/Wiimote.h"
struct SQueuedEvent
{
@ -193,7 +194,7 @@ private:
}
} m_acl_pool;
u32 m_PacketCount[4];
u32 m_PacketCount[MAX_BBMOTES];
u64 m_last_ticks;
// Send ACL data to a device (wiimote)
@ -274,7 +275,6 @@ private:
#pragma pack(push,1)
#define CONF_PAD_MAX_REGISTERED 10
#define CONF_PAD_MAX_ACTIVE 4
struct _conf_pad_device
{
@ -286,7 +286,7 @@ private:
{
u8 num_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;
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_ConfigWait(false)
, 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)
{
DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number);
@ -277,13 +277,13 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
break;
case L2CAP_PSM_HID_CNTL:
if (number < 4)
if (number < MAX_BBMOTES)
Wiimote::ControlChannel(number, pHeader->dcid, pData, DataSize);
break;
case L2CAP_PSM_HID_INTR:
{
if (number < 4)
if (number < MAX_BBMOTES)
{
DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel");
DEBUG_LOG(WIIMOTE, " Channel ID: %04x", pHeader->dcid);

View File

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

View File

@ -10,6 +10,7 @@
// for gcpad
#include "HW/SI_DeviceGCController.h"
#include "HW/SI_DeviceGCSteeringWheel.h"
#include "HW/SI_DeviceDanceMat.h"
// for gctime
#include "HW/EXI_DeviceIPL.h"
// 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);
}
bool CSIDevice_DanceMat::NetPlay_GetInput(u8 numPAD, SPADStatus PadStatus, u32 *PADStatus)
{
return CSIDevice_GCController::NetPlay_GetInput(numPAD, PadStatus, PADStatus);
}
// called from ---CPU--- thread
// so all players' games get the same time
u32 CEXIIPL::NetPlay_GetGCTime()
@ -328,6 +334,11 @@ u8 CSIDevice_GCSteeringWheel::NetPlay_GetPadNum(u8 numPAD)
return CSIDevice_GCController::NetPlay_GetPadNum(numPAD);
}
u8 CSIDevice_DanceMat::NetPlay_GetPadNum(u8 numPAD)
{
return CSIDevice_GCController::NetPlay_GetPadNum(numPAD);
}
// called from ---CPU--- thread
// wiimote update / used for frame counting
//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++)
{
u32 b[7];
for (int i = 0; i < 7; i++) b[i] = m & (1<<i);
u32 w;
if (b[0])
if (b[2])
if (b[6])
w = 7;
else
w = 6;
else
if (b[5])
w = 5;
else
w = 4;
else
if (b[1])
if (b[4])
w = 3;
else
w = 2;
else
if (b[3])
w = 1;
else
w = 0;
u32 w;
if(m & (1<<0))
if(m & (1<<2))
if(m & (1<<6))
w=7;
else
w=6;
else
if(m & (1<<5))
w=5;
else
w=4;
else
if(m & (1<<1))
if(m & (1<<4))
w=3;
else
w=2;
else
if(m & (1<<3))
w=1;
else
w=0;
way_from_plru[m] = w;
}
}

View File

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

View File

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

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "Common.h"
#include "Timer.h"
#include "State.h"
#include "Core.h"
#include "ConfigManager.h"
@ -58,13 +59,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system
static const u32 STATE_VERSION = 16;
struct StateHeader
{
u8 gameID[6];
size_t size;
};
static const u32 STATE_VERSION = 20;
enum
{
@ -159,17 +154,61 @@ void VerifyBuffer(std::vector<u8>& buffer)
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
{
std::vector<u8>* buffer_vector;
std::mutex* buffer_mutex;
std::string filename;
bool wait;
};
void CompressAndDumpState(CompressAndDumpState_args save_args)
{
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 size_t buffer_size = (save_args.buffer_vector)->size();
@ -201,6 +240,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
if (!f)
{
Core::DisplayMessage("Could not save state", 2000);
g_compressAndDumpStateSyncEvent.Set();
return;
}
@ -208,6 +248,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
StateHeader header;
memcpy(header.gameID, SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID().c_str(), 6);
header.size = g_use_compression ? buffer_size : 0;
header.time = Common::Timer::GetDoubleTime();
f.WriteArray(&header, 1);
@ -216,7 +257,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
lzo_uint i = 0;
while (true)
{
lzo_uint cur_len = 0;
lzo_uint32 cur_len = 0;
lzo_uint out_len = 0;
if ((i + IN_LEN) >= buffer_size)
@ -228,7 +269,7 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
PanicAlertT("Internal LZO Error - compression failed");
// 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);
if (cur_len != IN_LEN)
@ -244,9 +285,10 @@ void CompressAndDumpState(CompressAndDumpState_args save_args)
Core::DisplayMessage(StringFromFormat("Saved State to %s",
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
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_mutex = &g_cs_current_buffer;
save_args.filename = filename;
save_args.wait = wait;
Flush();
g_save_thread = std::thread(CompressAndDumpState, save_args);
@ -291,6 +334,20 @@ void SaveAs(const std::string& filename)
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)
{
Flush();
@ -322,7 +379,7 @@ void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_data)
lzo_uint i = 0;
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
if (!f.ReadArray(&cur_len, 1))
@ -496,9 +553,9 @@ static std::string MakeStateFilename(int 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)
@ -511,12 +568,35 @@ void Verify(int slot)
VerifyAt(MakeStateFilename(slot));
}
void LoadLastSaved()
void LoadLastSaved(int i)
{
if (g_last_filename.empty())
Core::DisplayMessage("There is no last saved state", 2000);
std::map<double, int> savedStates = GetSavedStates();
if (i > (int)savedStates.size())
Core::DisplayMessage("State doesn't exist", 2000);
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()

View File

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

View File

@ -172,6 +172,9 @@ if(ANDROID)
${LIBS}
"-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()
add_executable(${DOLPHIN_EXE} ${SRCS})
target_link_libraries(${DOLPHIN_EXE} ${LIBS} ${WXLIBS})

View File

@ -14,6 +14,7 @@
#include "WxUtils.h"
#define MAX_CHEAT_SEARCH_RESULTS_DISPLAY 256
const wxString title = _("Cheats Manager");
extern std::vector<ActionReplay::ARCode> arCodes;
extern CFrame* main_frame;
@ -22,26 +23,15 @@ extern CFrame* main_frame;
static wxCheatsWindow *g_cheat_window;
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;
// Create the GUI controls
Init_ChildControls();
// Load Data
Load_ARCodes();
// 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);
}
}
// load codes
UpdateGUI();
SetSize(wxSize(-1, 600));
Center();
@ -119,7 +109,7 @@ void wxCheatsWindow::Init_ChildControls()
m_Notebook_Main->AddPage(m_Tab_Log, _("Logging"));
// 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);
wxButton* const button_cancel = new wxButton(panel, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize);
button_cancel->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &wxCheatsWindow::OnEvent_ButtonClose_Press, this);
@ -249,12 +239,34 @@ void wxCheatsWindow::OnEvent_Close(wxCloseEvent& ev)
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()
{
using namespace ActionReplay;
m_CheckListBox_CheatsList->Clear();
if (!Core::IsRunning())
return;
indexList.clear();
size_t size = GetCodeListSize();
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))
{
using namespace ActionReplay;

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