mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-04-25 13:59:13 -05:00
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:
Generated
+1
@@ -0,0 +1 @@
|
||||
Android
|
||||
Generated
+23
@@ -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>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="">
|
||||
<module2copyright />
|
||||
</settings>
|
||||
</component>
|
||||
Generated
+5
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
||||
+10
@@ -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>
|
||||
Generated
+26
@@ -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>
|
||||
|
||||
Generated
+10
@@ -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>
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<state>
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</state>
|
||||
</component>
|
||||
Generated
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
Generated
+764
@@ -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="<template>" 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="<template>" 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="<template>" 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	" 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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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" };
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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*)®[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*)®[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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -64,6 +64,9 @@ struct GC_ALIGNED64(PowerPCState)
|
||||
u32 itlb_va[128];
|
||||
u32 itlb_pa[128];
|
||||
|
||||
u32 pagetable_base;
|
||||
u32 pagetable_hashmask;
|
||||
|
||||
InstructionCache iCache;
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -96,6 +96,7 @@ class wxCheatsWindow : public wxDialog
|
||||
public:
|
||||
wxCheatsWindow(wxWindow* const parent);
|
||||
~wxCheatsWindow();
|
||||
void UpdateGUI();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -105,6 +106,7 @@ class wxCheatsWindow : public wxDialog
|
||||
};
|
||||
|
||||
// --- GUI Controls ---
|
||||
wxButton* button_apply;
|
||||
wxNotebook *m_Notebook_Main;
|
||||
|
||||
wxPanel *m_Tab_Cheats;
|
||||
@@ -134,6 +136,7 @@ class wxCheatsWindow : public wxDialog
|
||||
void Init_ChildControls();
|
||||
|
||||
void Load_ARCodes();
|
||||
void Load_GeckoCodes();
|
||||
|
||||
// --- Wx Events Handlers ---
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ static const wxLanguage langIds[] =
|
||||
|
||||
#define SIDEV_STDCONT_STR _trans("Standard Controller")
|
||||
#define SIDEV_STEERING_STR _trans("Steering Wheel")
|
||||
#define SIDEV_DANCEMAT_STR _trans("Dance Mat")
|
||||
#define SIDEV_BONGO_STR _trans("TaruKonga (Bongos)")
|
||||
#define SIDEV_GBA_STR "GBA"
|
||||
#define SIDEV_AM_BB_STR _trans("AM-Baseboard")
|
||||
@@ -388,6 +389,7 @@ void CConfigMain::InitializeGUIValues()
|
||||
SIDevices.Add(_(DEV_NONE_STR));
|
||||
SIDevices.Add(_(SIDEV_STDCONT_STR));
|
||||
SIDevices.Add(_(SIDEV_STEERING_STR));
|
||||
SIDevices.Add(_(SIDEV_DANCEMAT_STR));
|
||||
SIDevices.Add(_(SIDEV_BONGO_STR));
|
||||
SIDevices.Add(_(SIDEV_GBA_STR));
|
||||
SIDevices.Add(_(SIDEV_AM_BB_STR));
|
||||
@@ -443,15 +445,18 @@ void CConfigMain::InitializeGUIValues()
|
||||
case SIDEVICE_GC_STEERING:
|
||||
GCSIDevice[i]->SetStringSelection(SIDevices[2]);
|
||||
break;
|
||||
case SIDEVICE_GC_TARUKONGA:
|
||||
case SIDEVICE_DANCEMAT:
|
||||
GCSIDevice[i]->SetStringSelection(SIDevices[3]);
|
||||
break;
|
||||
case SIDEVICE_GC_GBA:
|
||||
case SIDEVICE_GC_TARUKONGA:
|
||||
GCSIDevice[i]->SetStringSelection(SIDevices[4]);
|
||||
break;
|
||||
case SIDEVICE_AM_BASEBOARD:
|
||||
case SIDEVICE_GC_GBA:
|
||||
GCSIDevice[i]->SetStringSelection(SIDevices[5]);
|
||||
break;
|
||||
case SIDEVICE_AM_BASEBOARD:
|
||||
GCSIDevice[i]->SetStringSelection(SIDevices[6]);
|
||||
break;
|
||||
default:
|
||||
GCSIDevice[i]->SetStringSelection(SIDevices[0]);
|
||||
break;
|
||||
@@ -1103,6 +1108,8 @@ void CConfigMain::ChooseSIDevice(wxString deviceName, int deviceNum)
|
||||
tempType = SIDEVICE_GC_CONTROLLER;
|
||||
else if (!deviceName.compare(WXSTR_TRANS(SIDEV_STEERING_STR)))
|
||||
tempType = SIDEVICE_GC_STEERING;
|
||||
else if (!deviceName.compare(WXSTR_TRANS(SIDEV_DANCEMAT_STR)))
|
||||
tempType = SIDEVICE_DANCEMAT;
|
||||
else if (!deviceName.compare(WXSTR_TRANS(SIDEV_BONGO_STR)))
|
||||
tempType = SIDEVICE_GC_TARUKONGA;
|
||||
else if (!deviceName.compare(wxT(SIDEV_GBA_STR)))
|
||||
|
||||
@@ -34,8 +34,8 @@ FifoPlayerDlg::FifoPlayerDlg(wxWindow * const parent) :
|
||||
{
|
||||
CreateGUIControls();
|
||||
|
||||
sMutex.lock();
|
||||
m_EvtHandler = GetEventHandler();
|
||||
sMutex.lock();
|
||||
m_EvtHandler = GetEventHandler();
|
||||
sMutex.unlock();
|
||||
|
||||
FifoPlayer::GetInstance().SetFileLoadedCallback(FileLoaded);
|
||||
@@ -55,7 +55,7 @@ FifoPlayerDlg::~FifoPlayerDlg()
|
||||
m_ObjectToCtrl->Unbind(wxEVT_COMMAND_SPINCTRL_UPDATED, &FifoPlayerDlg::OnObjectTo, this);
|
||||
m_EarlyMemoryUpdates->Unbind(wxEVT_COMMAND_CHECKBOX_CLICKED, &FifoPlayerDlg::OnCheckEarlyMemoryUpdates, this);
|
||||
m_RecordStop->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnRecordStop, this);
|
||||
m_Save->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnSaveFile, this);
|
||||
m_Save->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnSaveFile, this);
|
||||
m_FramesToRecordCtrl->Unbind(wxEVT_COMMAND_SPINCTRL_UPDATED, &FifoPlayerDlg::OnNumFramesToRecord, this);
|
||||
m_Close->Unbind(wxEVT_COMMAND_BUTTON_CLICKED, &FifoPlayerDlg::OnCloseClick, this);
|
||||
|
||||
@@ -65,7 +65,7 @@ FifoPlayerDlg::~FifoPlayerDlg()
|
||||
|
||||
FifoPlayer::GetInstance().SetFrameWrittenCallback(NULL);
|
||||
|
||||
sMutex.lock();
|
||||
sMutex.lock();
|
||||
m_EvtHandler = NULL;
|
||||
sMutex.unlock();
|
||||
}
|
||||
@@ -192,7 +192,8 @@ void FifoPlayerDlg::CreateGUIControls()
|
||||
m_FramesToRecordLabel->Wrap(-1);
|
||||
sRecordingOptions->Add(m_FramesToRecordLabel, 0, wxALL, 5);
|
||||
|
||||
m_FramesToRecordCtrl = new wxSpinCtrl(m_RecordPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 10000, 1);
|
||||
wxString initialNum = wxString::Format(_T("%d"), m_FramesToRecord);
|
||||
m_FramesToRecordCtrl = new wxSpinCtrl(m_RecordPage, wxID_ANY, initialNum, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 10000, 1);
|
||||
sRecordingOptions->Add(m_FramesToRecordCtrl, 0, wxALL, 5);
|
||||
|
||||
sRecordPage->Add(sRecordingOptions, 0, wxEXPAND, 5);
|
||||
@@ -252,9 +253,7 @@ void FifoPlayerDlg::CreateGUIControls()
|
||||
m_findNext = new wxButton(m_AnalyzePage, wxID_ANY, _("Find next"));
|
||||
m_findPrevious = new wxButton(m_AnalyzePage, wxID_ANY, _("Find previous"));
|
||||
|
||||
m_beginSearch->Disable();
|
||||
m_findNext->Disable();
|
||||
m_findPrevious->Disable();
|
||||
ResetSearch();
|
||||
|
||||
sSearchButtons->Add(m_beginSearch, 0, wxALL, 5);
|
||||
sSearchButtons->Add(m_findNext, 0, wxALL, 5);
|
||||
@@ -407,8 +406,8 @@ void FifoPlayerDlg::OnRecordStop(wxCommandEvent& WXUNUSED(event))
|
||||
// Then stop recording
|
||||
recorder.StopRecording();
|
||||
|
||||
// and disable the button to stop recording
|
||||
m_RecordStop->Disable();
|
||||
// and change the button label accordingly.
|
||||
m_RecordStop->SetLabel(_("Record"));
|
||||
}
|
||||
else // Recorder is actually about to start recording
|
||||
{
|
||||
@@ -499,16 +498,12 @@ void FifoPlayerDlg::OnBeginSearch(wxCommandEvent& event)
|
||||
|
||||
ChangeSearchResult(0);
|
||||
m_beginSearch->Disable();
|
||||
m_findNext->Enable();
|
||||
m_findPrevious->Enable();
|
||||
m_numResultsText->SetLabel(wxString::Format(_("Found %d results for \'"), search_results.size()) + m_searchField->GetValue() + _("\'"));
|
||||
}
|
||||
|
||||
void FifoPlayerDlg::OnSearchFieldTextChanged(wxCommandEvent& event)
|
||||
{
|
||||
m_beginSearch->Enable(m_searchField->GetLineLength(0) > 0);
|
||||
m_findNext->Disable();
|
||||
m_findPrevious->Disable();
|
||||
ResetSearch();
|
||||
}
|
||||
|
||||
void FifoPlayerDlg::OnFindNextClick(wxCommandEvent& event)
|
||||
@@ -551,7 +546,7 @@ void FifoPlayerDlg::OnFindPreviousClick(wxCommandEvent& event)
|
||||
|
||||
void FifoPlayerDlg::ChangeSearchResult(unsigned int result_idx)
|
||||
{
|
||||
if (search_results.size() > result_idx)
|
||||
if (result_idx < search_results.size()) // if index is valid
|
||||
{
|
||||
m_search_result_idx = result_idx;
|
||||
int prev_frame = m_framesList->GetSelection();
|
||||
@@ -577,6 +572,9 @@ void FifoPlayerDlg::ChangeSearchResult(unsigned int result_idx)
|
||||
ev.SetInt(m_objectCmdList->GetSelection());
|
||||
OnObjectCmdListSelectionChanged(ev);
|
||||
}
|
||||
|
||||
m_findNext->Enable(result_idx+1 < search_results.size());
|
||||
m_findPrevious->Enable(result_idx != 0);
|
||||
}
|
||||
else if (search_results.size())
|
||||
{
|
||||
@@ -584,6 +582,15 @@ void FifoPlayerDlg::ChangeSearchResult(unsigned int result_idx)
|
||||
}
|
||||
}
|
||||
|
||||
void FifoPlayerDlg::ResetSearch()
|
||||
{
|
||||
m_beginSearch->Enable(m_searchField->GetLineLength(0) > 0);
|
||||
m_findNext->Disable();
|
||||
m_findPrevious->Disable();
|
||||
|
||||
search_results.clear();
|
||||
}
|
||||
|
||||
void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event)
|
||||
{
|
||||
FifoPlayer& player = FifoPlayer::GetInstance();
|
||||
@@ -600,6 +607,8 @@ void FifoPlayerDlg::OnFrameListSelectionChanged(wxCommandEvent& event)
|
||||
wxCommandEvent ev = wxCommandEvent(wxEVT_COMMAND_LISTBOX_SELECTED);
|
||||
ev.SetInt(-1);
|
||||
OnObjectListSelectionChanged(ev);
|
||||
|
||||
ResetSearch();
|
||||
}
|
||||
|
||||
void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event)
|
||||
@@ -727,6 +736,8 @@ void FifoPlayerDlg::OnObjectListSelectionChanged(wxCommandEvent& event)
|
||||
wxCommandEvent ev = wxCommandEvent(wxEVT_COMMAND_LISTBOX_SELECTED);
|
||||
ev.SetInt(-1);
|
||||
OnObjectCmdListSelectionChanged(ev);
|
||||
|
||||
ResetSearch();
|
||||
}
|
||||
|
||||
void FifoPlayerDlg::OnObjectCmdListSelectionChanged(wxCommandEvent& event)
|
||||
|
||||
@@ -37,6 +37,7 @@ private:
|
||||
void OnFindPreviousClick(wxCommandEvent& event);
|
||||
void OnSearchFieldTextChanged(wxCommandEvent& event);
|
||||
void ChangeSearchResult(unsigned int result_idx);
|
||||
void ResetSearch();
|
||||
|
||||
void OnRecordingFinished(wxEvent& event);
|
||||
void OnFrameWritten(wxEvent& event);
|
||||
|
||||
@@ -204,13 +204,14 @@ EVT_MENU_RANGE(IDM_LOGWINDOW, IDM_VIDEOWINDOW, CFrame::OnToggleWindow)
|
||||
|
||||
EVT_MENU(IDM_PURGECACHE, CFrame::GameListChanged)
|
||||
|
||||
EVT_MENU(IDM_LOADLASTSTATE, CFrame::OnLoadLastState)
|
||||
EVT_MENU(IDM_SAVEFIRSTSTATE, CFrame::OnSaveFirstState)
|
||||
EVT_MENU(IDM_UNDOLOADSTATE, CFrame::OnUndoLoadState)
|
||||
EVT_MENU(IDM_UNDOSAVESTATE, CFrame::OnUndoSaveState)
|
||||
EVT_MENU(IDM_LOADSTATEFILE, CFrame::OnLoadStateFromFile)
|
||||
EVT_MENU(IDM_SAVESTATEFILE, CFrame::OnSaveStateToFile)
|
||||
|
||||
EVT_MENU_RANGE(IDM_LOADSLOT1, IDM_LOADSLOT8, CFrame::OnLoadState)
|
||||
EVT_MENU_RANGE(IDM_LOADLAST1, IDM_LOADLAST8, CFrame::OnLoadLastState)
|
||||
EVT_MENU_RANGE(IDM_SAVESLOT1, IDM_SAVESLOT8, CFrame::OnSaveState)
|
||||
EVT_MENU_RANGE(IDM_FRAMESKIP0, IDM_FRAMESKIP9, CFrame::OnFrameSkip)
|
||||
EVT_MENU_RANGE(IDM_DRIVE1, IDM_DRIVE24, CFrame::OnBootDrive)
|
||||
@@ -719,104 +720,56 @@ int GetCmdForHotkey(unsigned int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case HK_OPEN:
|
||||
return wxID_OPEN;
|
||||
case HK_OPEN: return wxID_OPEN;
|
||||
case HK_CHANGE_DISC: return IDM_CHANGEDISC;
|
||||
case HK_REFRESH_LIST: return wxID_REFRESH;
|
||||
case HK_PLAY_PAUSE: return IDM_PLAY;
|
||||
case HK_STOP: return IDM_STOP;
|
||||
case HK_RESET: return IDM_RESET;
|
||||
case HK_FRAME_ADVANCE: return IDM_FRAMESTEP;
|
||||
case HK_START_RECORDING: return IDM_RECORD;
|
||||
case HK_PLAY_RECORDING: return IDM_PLAYRECORD;
|
||||
case HK_EXPORT_RECORDING: return IDM_RECORDEXPORT;
|
||||
case HK_READ_ONLY_MODE: return IDM_RECORDREADONLY;
|
||||
case HK_FULLSCREEN: return IDM_TOGGLE_FULLSCREEN;
|
||||
case HK_SCREENSHOT: return IDM_SCREENSHOT;
|
||||
case HK_EXIT: return wxID_EXIT;
|
||||
|
||||
case HK_CHANGE_DISC:
|
||||
return IDM_CHANGEDISC;
|
||||
case HK_WIIMOTE1_CONNECT: return IDM_CONNECT_WIIMOTE1;
|
||||
case HK_WIIMOTE2_CONNECT: return IDM_CONNECT_WIIMOTE2;
|
||||
case HK_WIIMOTE3_CONNECT: return IDM_CONNECT_WIIMOTE3;
|
||||
case HK_WIIMOTE4_CONNECT: return IDM_CONNECT_WIIMOTE4;
|
||||
|
||||
case HK_REFRESH_LIST:
|
||||
return wxID_REFRESH;
|
||||
case HK_LOAD_STATE_SLOT_1: return IDM_LOADSLOT1;
|
||||
case HK_LOAD_STATE_SLOT_2: return IDM_LOADSLOT2;
|
||||
case HK_LOAD_STATE_SLOT_3: return IDM_LOADSLOT3;
|
||||
case HK_LOAD_STATE_SLOT_4: return IDM_LOADSLOT4;
|
||||
case HK_LOAD_STATE_SLOT_5: return IDM_LOADSLOT5;
|
||||
case HK_LOAD_STATE_SLOT_6: return IDM_LOADSLOT6;
|
||||
case HK_LOAD_STATE_SLOT_7: return IDM_LOADSLOT7;
|
||||
case HK_LOAD_STATE_SLOT_8: return IDM_LOADSLOT8;
|
||||
|
||||
case HK_PLAY_PAUSE:
|
||||
return IDM_PLAY;
|
||||
case HK_SAVE_STATE_SLOT_1: return IDM_SAVESLOT1;
|
||||
case HK_SAVE_STATE_SLOT_2: return IDM_SAVESLOT2;
|
||||
case HK_SAVE_STATE_SLOT_3: return IDM_SAVESLOT3;
|
||||
case HK_SAVE_STATE_SLOT_4: return IDM_SAVESLOT4;
|
||||
case HK_SAVE_STATE_SLOT_5: return IDM_SAVESLOT5;
|
||||
case HK_SAVE_STATE_SLOT_6: return IDM_SAVESLOT6;
|
||||
case HK_SAVE_STATE_SLOT_7: return IDM_SAVESLOT7;
|
||||
case HK_SAVE_STATE_SLOT_8: return IDM_SAVESLOT8;
|
||||
|
||||
case HK_STOP:
|
||||
return IDM_STOP;
|
||||
case HK_LOAD_LAST_STATE_1: return IDM_LOADLAST1;
|
||||
case HK_LOAD_LAST_STATE_2: return IDM_LOADLAST2;
|
||||
case HK_LOAD_LAST_STATE_3: return IDM_LOADLAST3;
|
||||
case HK_LOAD_LAST_STATE_4: return IDM_LOADLAST4;
|
||||
case HK_LOAD_LAST_STATE_5: return IDM_LOADLAST5;
|
||||
case HK_LOAD_LAST_STATE_6: return IDM_LOADLAST6;
|
||||
case HK_LOAD_LAST_STATE_7: return IDM_LOADLAST7;
|
||||
case HK_LOAD_LAST_STATE_8: return IDM_LOADLAST8;
|
||||
|
||||
case HK_RESET:
|
||||
return IDM_RESET;
|
||||
|
||||
case HK_FRAME_ADVANCE:
|
||||
return IDM_FRAMESTEP;
|
||||
|
||||
case HK_START_RECORDING:
|
||||
return IDM_RECORD;
|
||||
|
||||
case HK_PLAY_RECORDING:
|
||||
return IDM_PLAYRECORD;
|
||||
|
||||
case HK_EXPORT_RECORDING:
|
||||
return IDM_RECORDEXPORT;
|
||||
|
||||
case HK_READ_ONLY_MODE:
|
||||
return IDM_RECORDREADONLY;
|
||||
|
||||
case HK_FULLSCREEN:
|
||||
return IDM_TOGGLE_FULLSCREEN;
|
||||
|
||||
case HK_SCREENSHOT:
|
||||
return IDM_SCREENSHOT;
|
||||
|
||||
case HK_WIIMOTE1_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE1;
|
||||
|
||||
case HK_WIIMOTE2_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE2;
|
||||
|
||||
case HK_WIIMOTE3_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE3;
|
||||
|
||||
case HK_WIIMOTE4_CONNECT:
|
||||
return IDM_CONNECT_WIIMOTE4;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_1:
|
||||
return IDM_LOADSLOT1;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_2:
|
||||
return IDM_LOADSLOT2;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_3:
|
||||
return IDM_LOADSLOT3;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_4:
|
||||
return IDM_LOADSLOT4;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_5:
|
||||
return IDM_LOADSLOT5;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_6:
|
||||
return IDM_LOADSLOT6;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_7:
|
||||
return IDM_LOADSLOT7;
|
||||
|
||||
case HK_LOAD_STATE_SLOT_8:
|
||||
return IDM_LOADSLOT8;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_1:
|
||||
return IDM_SAVESLOT1;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_2:
|
||||
return IDM_SAVESLOT2;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_3:
|
||||
return IDM_SAVESLOT3;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_4:
|
||||
return IDM_SAVESLOT4;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_5:
|
||||
return IDM_SAVESLOT5;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_6:
|
||||
return IDM_SAVESLOT6;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_7:
|
||||
return IDM_SAVESLOT7;
|
||||
|
||||
case HK_SAVE_STATE_SLOT_8:
|
||||
return IDM_SAVESLOT8;
|
||||
case HK_SAVE_FIRST_STATE: return IDM_SAVEFIRSTSTATE;
|
||||
case HK_UNDO_LOAD_STATE: return IDM_UNDOLOADSTATE;
|
||||
case HK_UNDO_SAVE_STATE: return IDM_UNDOSAVESTATE;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -859,6 +812,8 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
|
||||
// Screenshot hotkey
|
||||
else if (IsHotkey(event, HK_SCREENSHOT))
|
||||
Core::SaveScreenShot();
|
||||
else if (IsHotkey(event, HK_EXIT))
|
||||
wxPostEvent(this, wxCommandEvent(wxID_EXIT));
|
||||
// Wiimote connect and disconnect hotkeys
|
||||
else if (IsHotkey(event, HK_WIIMOTE1_CONNECT))
|
||||
WiimoteId = 0;
|
||||
@@ -868,28 +823,6 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
|
||||
WiimoteId = 2;
|
||||
else if (IsHotkey(event, HK_WIIMOTE4_CONNECT))
|
||||
WiimoteId = 3;
|
||||
// State save and state load hotkeys
|
||||
/*else if (event.GetKeyCode() >= WXK_F1 && event.GetKeyCode() <= WXK_F8)
|
||||
{
|
||||
int slot_number = event.GetKeyCode() - WXK_F1 + 1;
|
||||
if (event.GetModifiers() == wxMOD_NONE)
|
||||
State::Load(slot_number);
|
||||
else if (event.GetModifiers() == wxMOD_SHIFT)
|
||||
State::Save(slot_number);
|
||||
else
|
||||
event.Skip();
|
||||
}*/
|
||||
else if (event.GetKeyCode() == WXK_F11 && event.GetModifiers() == wxMOD_NONE)
|
||||
State::LoadLastSaved();
|
||||
else if (event.GetKeyCode() == WXK_F12)
|
||||
{
|
||||
if (event.GetModifiers() == wxMOD_NONE)
|
||||
State::UndoSaveState();
|
||||
else if (event.GetModifiers() == wxMOD_SHIFT)
|
||||
State::UndoLoadState();
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int i = NUM_HOTKEYS;
|
||||
|
||||
@@ -289,6 +289,7 @@ private:
|
||||
void OnLoadStateFromFile(wxCommandEvent& event);
|
||||
void OnSaveStateToFile(wxCommandEvent& event);
|
||||
void OnLoadLastState(wxCommandEvent& event);
|
||||
void OnSaveFirstState(wxCommandEvent& event);
|
||||
void OnUndoLoadState(wxCommandEvent& event);
|
||||
void OnUndoSaveState(wxCommandEvent& event);
|
||||
|
||||
|
||||
@@ -150,26 +150,25 @@ void CFrame::CreateMenu()
|
||||
emulationMenu->Append(IDM_SAVESTATE, _("Sa&ve State"), saveMenu);
|
||||
|
||||
saveMenu->Append(IDM_SAVESTATEFILE, _("Save State..."));
|
||||
loadMenu->Append(IDM_UNDOSAVESTATE, _("Last Overwritten State") + wxString(wxT("\tF12")));
|
||||
saveMenu->Append(IDM_SAVEFIRSTSTATE, GetMenuLabel(HK_SAVE_FIRST_STATE));
|
||||
loadMenu->Append(IDM_UNDOSAVESTATE, GetMenuLabel(HK_UNDO_SAVE_STATE));
|
||||
saveMenu->AppendSeparator();
|
||||
|
||||
loadMenu->Append(IDM_LOADSTATEFILE, _("Load State..."));
|
||||
|
||||
// Reserve F11 for the "step into" function in the debugger
|
||||
if (g_pCodeWindow)
|
||||
loadMenu->Append(IDM_LOADLASTSTATE, _("Last Saved State"));
|
||||
else
|
||||
loadMenu->Append(IDM_LOADLASTSTATE, _("Last Saved State") + wxString(wxT("\tF11")));
|
||||
|
||||
loadMenu->Append(IDM_UNDOLOADSTATE, _("Undo Load State") + wxString(wxT("\tShift+F12")));
|
||||
loadMenu->Append(IDM_UNDOLOADSTATE, GetMenuLabel(HK_UNDO_LOAD_STATE));
|
||||
loadMenu->AppendSeparator();
|
||||
|
||||
for (int i = 1; i <= 8; i++)
|
||||
for (unsigned int i = 1; i <= State::NUM_STATES; i++)
|
||||
{
|
||||
loadMenu->Append(IDM_LOADSLOT1 + i - 1, GetMenuLabel(HK_LOAD_STATE_SLOT_1 + i - 1));
|
||||
saveMenu->Append(IDM_SAVESLOT1 + i - 1, GetMenuLabel(HK_SAVE_STATE_SLOT_1 + i - 1));
|
||||
}
|
||||
|
||||
loadMenu->AppendSeparator();
|
||||
for (unsigned int i = 1; i <= State::NUM_STATES; i++)
|
||||
loadMenu->Append(IDM_LOADLAST1 + i - 1, GetMenuLabel(HK_LOAD_LAST_STATE_1 + i - 1));
|
||||
|
||||
m_MenuBar->Append(emulationMenu, _("&Emulation"));
|
||||
|
||||
// Options menu
|
||||
@@ -360,6 +359,9 @@ wxString CFrame::GetMenuLabel(int Id)
|
||||
case HK_SCREENSHOT:
|
||||
Label = _("Take Screenshot");
|
||||
break;
|
||||
case HK_EXIT:
|
||||
Label = _("Exit");
|
||||
break;
|
||||
|
||||
case HK_WIIMOTE1_CONNECT:
|
||||
case HK_WIIMOTE2_CONNECT:
|
||||
@@ -393,6 +395,22 @@ wxString CFrame::GetMenuLabel(int Id)
|
||||
Id - HK_SAVE_STATE_SLOT_1 + 1);
|
||||
break;
|
||||
|
||||
case HK_LOAD_LAST_STATE_1:
|
||||
case HK_LOAD_LAST_STATE_2:
|
||||
case HK_LOAD_LAST_STATE_3:
|
||||
case HK_LOAD_LAST_STATE_4:
|
||||
case HK_LOAD_LAST_STATE_5:
|
||||
case HK_LOAD_LAST_STATE_6:
|
||||
case HK_LOAD_LAST_STATE_7:
|
||||
case HK_LOAD_LAST_STATE_8:
|
||||
Label = wxString::Format(_("Last %i"),
|
||||
Id - HK_LOAD_LAST_STATE_1 + 1);
|
||||
break;
|
||||
|
||||
case HK_SAVE_FIRST_STATE: Label = wxString("Save Oldest State"); break;
|
||||
case HK_UNDO_LOAD_STATE: Label = wxString("Undo Load State"); break;
|
||||
case HK_UNDO_SAVE_STATE: Label = wxString("Undo Save State"); break;
|
||||
|
||||
default:
|
||||
Label = wxString::Format(_("Undefined %i"), Id);
|
||||
}
|
||||
@@ -780,7 +798,7 @@ void CFrame::OnRenderParentResize(wxSizeEvent& event)
|
||||
void CFrame::ToggleDisplayMode(bool bFullscreen)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (bFullscreen)
|
||||
if (bFullscreen && SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution != "Auto")
|
||||
{
|
||||
DEVMODE dmScreenSettings;
|
||||
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
|
||||
@@ -799,7 +817,8 @@ void CFrame::ToggleDisplayMode(bool bFullscreen)
|
||||
ChangeDisplaySettings(NULL, CDS_FULLSCREEN);
|
||||
}
|
||||
#elif defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||
m_XRRConfig->ToggleDisplayMode(bFullscreen);
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution != "Auto")
|
||||
m_XRRConfig->ToggleDisplayMode(bFullscreen);
|
||||
#elif defined __APPLE__
|
||||
if(bFullscreen)
|
||||
CGDisplayHideCursor(CGMainDisplayID());
|
||||
@@ -1115,6 +1134,7 @@ void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event))
|
||||
CConfigMain ConfigMain(this);
|
||||
if (ConfigMain.ShowModal() == wxID_OK)
|
||||
m_GameListCtrl->Update();
|
||||
UpdateGUI();
|
||||
}
|
||||
|
||||
void CFrame::OnConfigGFX(wxCommandEvent& WXUNUSED (event))
|
||||
@@ -1437,10 +1457,20 @@ void CFrame::OnSaveStateToFile(wxCommandEvent& WXUNUSED (event))
|
||||
State::SaveAs(WxStrToStr(path));
|
||||
}
|
||||
|
||||
void CFrame::OnLoadLastState(wxCommandEvent& WXUNUSED (event))
|
||||
void CFrame::OnLoadLastState(wxCommandEvent& event)
|
||||
{
|
||||
if (Core::IsRunningAndStarted())
|
||||
State::LoadLastSaved();
|
||||
{
|
||||
int id = event.GetId();
|
||||
int slot = id - IDM_LOADLAST1 + 1;
|
||||
State::LoadLastSaved(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void CFrame::OnSaveFirstState(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||
State::SaveFirstSaved();
|
||||
}
|
||||
|
||||
void CFrame::OnUndoLoadState(wxCommandEvent& WXUNUSED (event))
|
||||
@@ -1540,6 +1570,9 @@ void CFrame::UpdateGUI()
|
||||
if (DiscIO::CNANDContentManager::Access().GetNANDLoader(TITLEID_SYSMENU).IsValid())
|
||||
GetMenuBar()->FindItem(IDM_LOAD_WII_MENU)->Enable(!Initialized);
|
||||
|
||||
// Tools
|
||||
GetMenuBar()->FindItem(IDM_CHEATS)->Enable(SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats);
|
||||
|
||||
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Enable(RunningWii);
|
||||
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Enable(RunningWii);
|
||||
GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE3)->Enable(RunningWii);
|
||||
@@ -1647,6 +1680,15 @@ void CFrame::UpdateGUI()
|
||||
|
||||
// Commit changes to manager
|
||||
m_Mgr->Update();
|
||||
|
||||
// Update non-modal windows
|
||||
if (g_CheatsWindow)
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableCheats)
|
||||
g_CheatsWindow->UpdateGUI();
|
||||
else
|
||||
g_CheatsWindow->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void CFrame::UpdateGameList()
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef __HOTKEYDIALOG_h__
|
||||
#define __HOTKEYDIALOG_h__
|
||||
#ifndef __GCMICDIALOG_h__
|
||||
#define __GCMICDIALOG_h__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/textctrl.h>
|
||||
|
||||
@@ -52,7 +52,11 @@ bool cInterfaceEGL::Create(void *&window_handle)
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 24,
|
||||
#ifdef USE_GLES
|
||||
#ifdef USE_GLES3
|
||||
EGL_RENDERABLE_TYPE, (1 << 6) /* EGL_OPENGL_ES3_BIT */,
|
||||
#else
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
#endif
|
||||
#else
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
// Show the current FPS
|
||||
void cInterfaceGLX::UpdateFPSDisplay(const char *text)
|
||||
{
|
||||
XStoreName(GLWin.dpy, GLWin.win, text);
|
||||
XStoreName(GLWin.evdpy, GLWin.win, text);
|
||||
}
|
||||
|
||||
void cInterfaceGLX::SwapInterval(int Interval)
|
||||
@@ -136,7 +136,7 @@ bool cInterfaceGLX::MakeCurrent()
|
||||
#if defined(HAVE_WX) && (HAVE_WX)
|
||||
Host_GetRenderWindowSize(GLWin.x, GLWin.y,
|
||||
(int&)GLWin.width, (int&)GLWin.height);
|
||||
XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y,
|
||||
XMoveResizeWindow(GLWin.evdpy, GLWin.win, GLWin.x, GLWin.y,
|
||||
GLWin.width, GLWin.height);
|
||||
#endif
|
||||
return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
|
||||
|
||||
@@ -115,7 +115,10 @@ out:
|
||||
#if HAVE_X11
|
||||
if (selected_platform != EGL_PLATFORM_X11) {
|
||||
if (GLWin.dpy)
|
||||
{
|
||||
XCloseDisplay(GLWin.dpy);
|
||||
XCloseDisplay(GLWin.evdpy);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (selected_platform == EGL_PLATFORM_NONE)
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#if USE_EGL
|
||||
bool cXInterface::ServerConnect(void)
|
||||
{
|
||||
GLWin.evdpy = XOpenDisplay(NULL);
|
||||
GLWin.dpy = XOpenDisplay(NULL);
|
||||
|
||||
if (!GLWin.evdpy)
|
||||
if (!GLWin.dpy)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -39,7 +39,7 @@ bool cXInterface::Initialize(void *config)
|
||||
int num_visuals;
|
||||
EGLint vid;
|
||||
|
||||
if (!GLWin.evdpy) {
|
||||
if (!GLWin.dpy) {
|
||||
printf("Error: couldn't open X display\n");
|
||||
return false;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ bool cXInterface::Initialize(void *config)
|
||||
|
||||
/* The X window visual must match the EGL config */
|
||||
visTemplate.visualid = vid;
|
||||
GLWin.vi = XGetVisualInfo(GLWin.evdpy, VisualIDMask, &visTemplate, &num_visuals);
|
||||
GLWin.vi = XGetVisualInfo(GLWin.dpy, VisualIDMask, &visTemplate, &num_visuals);
|
||||
if (!GLWin.vi) {
|
||||
printf("Error: couldn't get X visual\n");
|
||||
exit(1);
|
||||
@@ -64,12 +64,12 @@ bool cXInterface::Initialize(void *config)
|
||||
GLWin.width = _twidth;
|
||||
GLWin.height = _theight;
|
||||
|
||||
GLWin.dpy = XOpenDisplay(NULL);
|
||||
GLWin.evdpy = XOpenDisplay(NULL);
|
||||
GLWin.parent = GLWin.win;
|
||||
GLWin.screen = DefaultScreen(GLWin.evdpy);
|
||||
GLWin.screen = DefaultScreen(GLWin.dpy);
|
||||
|
||||
if (GLWin.parent == 0)
|
||||
GLWin.parent = RootWindow(GLWin.evdpy, GLWin.screen);
|
||||
GLWin.parent = RootWindow(GLWin.dpy, GLWin.screen);
|
||||
|
||||
/* Set initial projection/viewing transformation.
|
||||
* We can't be sure we'll get a ConfigureNotify event when the window
|
||||
@@ -82,7 +82,7 @@ bool cXInterface::Initialize(void *config)
|
||||
|
||||
void *cXInterface::EGLGetDisplay(void)
|
||||
{
|
||||
return eglGetDisplay(GLWin.evdpy);
|
||||
return eglGetDisplay(GLWin.dpy);
|
||||
}
|
||||
|
||||
void *cXInterface::CreateWindow(void)
|
||||
@@ -90,22 +90,22 @@ void *cXInterface::CreateWindow(void)
|
||||
Atom wmProtocols[1];
|
||||
|
||||
// Setup window attributes
|
||||
GLWin.attr.colormap = XCreateColormap(GLWin.dpy,
|
||||
GLWin.attr.colormap = XCreateColormap(GLWin.evdpy,
|
||||
GLWin.parent, GLWin.vi->visual, AllocNone);
|
||||
GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask;
|
||||
GLWin.attr.background_pixel = BlackPixel(GLWin.dpy, GLWin.screen);
|
||||
GLWin.attr.background_pixel = BlackPixel(GLWin.evdpy, GLWin.screen);
|
||||
GLWin.attr.border_pixel = 0;
|
||||
|
||||
// Create the window
|
||||
GLWin.win = XCreateWindow(GLWin.dpy, GLWin.parent,
|
||||
GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent,
|
||||
GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0,
|
||||
GLWin.vi->depth, InputOutput, GLWin.vi->visual,
|
||||
CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
|
||||
wmProtocols[0] = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True);
|
||||
XSetWMProtocols(GLWin.dpy, GLWin.win, wmProtocols, 1);
|
||||
XSetStandardProperties(GLWin.dpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL);
|
||||
XMapRaised(GLWin.dpy, GLWin.win);
|
||||
XSync(GLWin.dpy, True);
|
||||
wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True);
|
||||
XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1);
|
||||
XSetStandardProperties(GLWin.evdpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL);
|
||||
XMapRaised(GLWin.evdpy, GLWin.win);
|
||||
XSync(GLWin.evdpy, True);
|
||||
|
||||
GLWin.xEventThread = std::thread(&cXInterface::XEventThread, this);
|
||||
// Control window size and picture scaling
|
||||
@@ -116,16 +116,16 @@ void *cXInterface::CreateWindow(void)
|
||||
|
||||
void cXInterface::DestroyWindow(void)
|
||||
{
|
||||
XDestroyWindow(GLWin.dpy, GLWin.win);
|
||||
XDestroyWindow(GLWin.evdpy, GLWin.win);
|
||||
GLWin.win = 0;
|
||||
if (GLWin.xEventThread.joinable())
|
||||
GLWin.xEventThread.join();
|
||||
XFreeColormap(GLWin.dpy, GLWin.attr.colormap);
|
||||
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
|
||||
}
|
||||
|
||||
void cXInterface::UpdateFPSDisplay(const char *text)
|
||||
{
|
||||
XStoreName(GLWin.dpy, GLWin.win, text);
|
||||
XStoreName(GLWin.evdpy, GLWin.win, text);
|
||||
}
|
||||
|
||||
void cXInterface::XEventThread()
|
||||
@@ -157,7 +157,7 @@ void cX11Window::CreateXWindow(void)
|
||||
|
||||
void cX11Window::DestroyXWindow(void)
|
||||
{
|
||||
XUnmapWindow(GLWin.dpy, GLWin.win);
|
||||
XUnmapWindow(GLWin.evdpy, GLWin.win);
|
||||
GLWin.win = 0;
|
||||
if (GLWin.xEventThread.joinable())
|
||||
GLWin.xEventThread.join();
|
||||
@@ -175,9 +175,9 @@ void cX11Window::XEventThread()
|
||||
{
|
||||
XEvent event;
|
||||
KeySym key;
|
||||
for (int num_events = XPending(GLWin.dpy); num_events > 0; num_events--)
|
||||
for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--)
|
||||
{
|
||||
XNextEvent(GLWin.dpy, &event);
|
||||
XNextEvent(GLWin.evdpy, &event);
|
||||
switch(event.type) {
|
||||
case KeyPress:
|
||||
key = XLookupKeysym((XKeyEvent*)&event, 0);
|
||||
@@ -305,17 +305,17 @@ void cX11Window::XEventThread()
|
||||
case ConfigureNotify:
|
||||
Window winDummy;
|
||||
unsigned int borderDummy, depthDummy;
|
||||
XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
|
||||
XGetGeometry(GLWin.evdpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y,
|
||||
&GLWin.width, &GLWin.height, &borderDummy, &depthDummy);
|
||||
GLInterface->SetBackBufferDimensions(GLWin.width, GLWin.height);
|
||||
break;
|
||||
case ClientMessage:
|
||||
if ((unsigned long) event.xclient.data.l[0] ==
|
||||
XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", False))
|
||||
XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False))
|
||||
Host_Message(WM_USER_STOP);
|
||||
if ((unsigned long) event.xclient.data.l[0] ==
|
||||
XInternAtom(GLWin.dpy, "RESIZE", False))
|
||||
XMoveResizeWindow(GLWin.dpy, GLWin.win,
|
||||
XInternAtom(GLWin.evdpy, "RESIZE", False))
|
||||
XMoveResizeWindow(GLWin.evdpy, GLWin.win,
|
||||
event.xclient.data.l[1], event.xclient.data.l[2],
|
||||
event.xclient.data.l[3], event.xclient.data.l[4]);
|
||||
break;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "GeckoCodeDiag.h"
|
||||
#include "Core.h"
|
||||
#include "WxUtils.h"
|
||||
|
||||
#include <SFML/Network/Http.hpp>
|
||||
@@ -41,7 +42,8 @@ CodeConfigPanel::CodeConfigPanel(wxWindow* const parent)
|
||||
|
||||
// button sizer
|
||||
wxBoxSizer* const sizer_buttons = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxButton* const btn_download = new wxButton(this, -1, _("Download Codes (WiiRD Database)"), wxDefaultPosition, wxSize(128, -1));
|
||||
btn_download = new wxButton(this, -1, _("Download Codes (WiiRD Database)"), wxDefaultPosition, wxSize(128, -1));
|
||||
btn_download->Enable(false);
|
||||
btn_download->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &CodeConfigPanel::DownloadCodes, this);
|
||||
sizer_buttons->AddStretchSpacer(1);
|
||||
sizer_buttons->Add(btn_download, 1, wxEXPAND);
|
||||
@@ -58,8 +60,11 @@ CodeConfigPanel::CodeConfigPanel(wxWindow* const parent)
|
||||
SetSizerAndFit(sizer_main);
|
||||
}
|
||||
|
||||
void CodeConfigPanel::UpdateCodeList()
|
||||
void CodeConfigPanel::UpdateCodeList(bool checkRunning)
|
||||
{
|
||||
// disable the button if it doesn't have an effect
|
||||
btn_download->Enable((!checkRunning || Core::IsRunning()) && !m_gameid.empty());
|
||||
|
||||
m_listbox_gcodes->Clear();
|
||||
// add the codes to the listbox
|
||||
std::vector<GeckoCode>::const_iterator
|
||||
@@ -76,14 +81,15 @@ void CodeConfigPanel::UpdateCodeList()
|
||||
UpdateInfoBox(evt);
|
||||
}
|
||||
|
||||
void CodeConfigPanel::LoadCodes(const IniFile& inifile, const std::string& gameid)
|
||||
void CodeConfigPanel::LoadCodes(const IniFile& inifile, const std::string& gameid, bool checkRunning)
|
||||
{
|
||||
m_gameid = gameid;
|
||||
|
||||
m_gcodes.clear();
|
||||
Gecko::LoadCodes(inifile, m_gcodes);
|
||||
if (!checkRunning || Core::IsRunning())
|
||||
Gecko::LoadCodes(inifile, m_gcodes);
|
||||
|
||||
UpdateCodeList();
|
||||
UpdateCodeList(checkRunning);
|
||||
}
|
||||
|
||||
void CodeConfigPanel::ToggleCode(wxCommandEvent& evt)
|
||||
@@ -277,9 +283,8 @@ void CodeConfigPanel::DownloadCodes(wxCommandEvent&)
|
||||
break;
|
||||
}
|
||||
|
||||
// code with this name+creator exists
|
||||
if (existing_gcodes_iter->name == gcodes_iter->name &&
|
||||
existing_gcodes_iter->creator == gcodes_iter->creator)
|
||||
// code exists
|
||||
if (existing_gcodes_iter->Compare(*gcodes_iter))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
CodeConfigPanel(wxWindow* const parent);
|
||||
|
||||
|
||||
void LoadCodes(const IniFile& inifile, const std::string& gameid = "");
|
||||
void LoadCodes(const IniFile& inifile, const std::string& gameid = "", bool checkRunning = false);
|
||||
const std::vector<GeckoCode>& GetCodes() const { return m_gcodes; }
|
||||
|
||||
protected:
|
||||
@@ -29,7 +29,7 @@ protected:
|
||||
void DownloadCodes(wxCommandEvent&);
|
||||
//void ApplyChanges(wxCommandEvent&);
|
||||
|
||||
void UpdateCodeList();
|
||||
void UpdateCodeList(bool checkRunning = false);
|
||||
|
||||
private:
|
||||
std::vector<GeckoCode> m_gcodes;
|
||||
@@ -44,7 +44,7 @@ private:
|
||||
wxTextCtrl *textctrl_notes;
|
||||
wxListBox *listbox_codes;
|
||||
} m_infobox;
|
||||
|
||||
wxButton* btn_download;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ enum
|
||||
{
|
||||
IDM_LOADSTATE = 200, // File menu
|
||||
IDM_SAVESTATE,
|
||||
IDM_LOADLASTSTATE,
|
||||
IDM_SAVEFIRSTSTATE,
|
||||
IDM_UNDOLOADSTATE,
|
||||
IDM_UNDOSAVESTATE,
|
||||
IDM_LOADSTATEFILE,
|
||||
@@ -46,6 +46,14 @@ enum
|
||||
IDM_LOADSLOT6,
|
||||
IDM_LOADSLOT7,
|
||||
IDM_LOADSLOT8,
|
||||
IDM_LOADLAST1,
|
||||
IDM_LOADLAST2,
|
||||
IDM_LOADLAST3,
|
||||
IDM_LOADLAST4,
|
||||
IDM_LOADLAST5,
|
||||
IDM_LOADLAST6,
|
||||
IDM_LOADLAST7,
|
||||
IDM_LOADLAST8,
|
||||
IDM_FRAMESKIP0,
|
||||
IDM_FRAMESKIP1,
|
||||
IDM_FRAMESKIP2,
|
||||
|
||||
@@ -179,6 +179,7 @@ void HotkeyConfigDialog::CreateHotkeyGUIControls(void)
|
||||
|
||||
_("Toggle Fullscreen"),
|
||||
_("Take Screenshot"),
|
||||
_("Exit"),
|
||||
|
||||
_("Connect Wiimote 1"),
|
||||
_("Connect Wiimote 2"),
|
||||
@@ -201,7 +202,20 @@ void HotkeyConfigDialog::CreateHotkeyGUIControls(void)
|
||||
_("Save State Slot 5"),
|
||||
_("Save State Slot 6"),
|
||||
_("Save State Slot 7"),
|
||||
_("Save State Slot 8")
|
||||
_("Save State Slot 8"),
|
||||
|
||||
_("Load State Last 1"),
|
||||
_("Load State Last 2"),
|
||||
_("Load State Last 3"),
|
||||
_("Load State Last 4"),
|
||||
_("Load State Last 5"),
|
||||
_("Load State Last 6"),
|
||||
_("Load State Last 7"),
|
||||
_("Load State Last 8"),
|
||||
|
||||
_("Save Oldest State"),
|
||||
_("Undo Load State"),
|
||||
_("Undo Save State")
|
||||
};
|
||||
|
||||
const int page_breaks[3] = {HK_OPEN, HK_LOAD_STATE_SLOT_1, NUM_HOTKEYS};
|
||||
|
||||
@@ -818,14 +818,24 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event)
|
||||
void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event)
|
||||
{
|
||||
std::vector<const DiscIO::SFileInfo *> fst;
|
||||
DiscIO::IFileSystem *FS = 0;
|
||||
DiscIO::IFileSystem *FS = NULL;
|
||||
wxString Path = wxDirSelector(_("Choose the folder to extract to"));
|
||||
|
||||
if (Path.empty())
|
||||
return;
|
||||
|
||||
if (DiscIO::IsVolumeWiiDisc(OpenISO))
|
||||
FS = WiiDisc.at(1).FileSystem;
|
||||
if(WiiDisc.size() > 0)
|
||||
{
|
||||
// Get the filesystem of the LAST partition
|
||||
FS = WiiDisc.at(WiiDisc.size() - 1).FileSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlertT("No partitions found for: %s!",
|
||||
WxStrToStr(Path).c_str());
|
||||
return;
|
||||
}
|
||||
else
|
||||
FS = pFileSystem;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "InputConfigDiag.h"
|
||||
#include "UDPConfigDiag.h"
|
||||
#include "WxUtils.h"
|
||||
#include "HW/Wiimote.h"
|
||||
|
||||
void GamepadPage::ConfigUDPWii(wxCommandEvent &event)
|
||||
{
|
||||
@@ -947,7 +948,7 @@ InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin
|
||||
, m_plugin(plugin)
|
||||
{
|
||||
m_pad_notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT);
|
||||
for (unsigned int i = 0; i < plugin.controllers.size(); ++i)
|
||||
for (unsigned int i = 0; i < std::min(plugin.controllers.size(), (size_t)MAX_WIIMOTES); ++i)
|
||||
{
|
||||
GamepadPage* gp = new GamepadPage(m_pad_notebook, m_plugin, i, this);
|
||||
m_padpages.push_back(gp);
|
||||
|
||||
@@ -89,13 +89,53 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
||||
dc.DrawRectangle( 0, 31 - z*31, 64, 2);
|
||||
}
|
||||
|
||||
// circle for visual aid for diagonal adjustment
|
||||
// octagon for visual aid for diagonal adjustment
|
||||
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
if ( GROUP_TYPE_STICK == (*g)->control_group->type )
|
||||
{
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawCircle( 32, 32, 32);
|
||||
// outline and fill colors
|
||||
wxBrush LightGrayBrush(_T("#dddddd"));
|
||||
wxPen LightGrayPen(_T("#bfbfbf"));
|
||||
dc.SetBrush(LightGrayBrush);
|
||||
dc.SetPen(LightGrayPen);
|
||||
|
||||
// polygon offset
|
||||
float max
|
||||
, diagonal
|
||||
, box = 64
|
||||
, d_of = box / 256.0
|
||||
, x_of = box / 2.0;
|
||||
|
||||
if ((*g)->control_group->name == "Main Stick")
|
||||
{
|
||||
max = (87.0 / 127.0) * 100;
|
||||
diagonal = (55.0 / 127.0) * 100.0;
|
||||
}
|
||||
else if ((*g)->control_group->name == "C-Stick")
|
||||
{
|
||||
max = (74.0 / 127.0) * 100;
|
||||
diagonal = (46.0 / 127.0) * 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = (82.0 / 127.0) * 100;
|
||||
diagonal = (58.0 / 127.0) * 100;
|
||||
}
|
||||
|
||||
// polygon corners
|
||||
wxPoint Points[8];
|
||||
Points[0].x = (int)(0.0 * d_of + x_of); Points[0].y = (int)(max * d_of + x_of);
|
||||
Points[1].x = (int)(diagonal * d_of + x_of); Points[1].y = (int)(diagonal * d_of + x_of);
|
||||
Points[2].x = (int)(max * d_of + x_of); Points[2].y = (int)(0.0 * d_of + x_of);
|
||||
Points[3].x = (int)(diagonal * d_of + x_of); Points[3].y = (int)(-diagonal * d_of + x_of);
|
||||
Points[4].x = (int)(0.0 * d_of + x_of); Points[4].y = (int)(-max * d_of + x_of);
|
||||
Points[5].x = (int)(-diagonal * d_of + x_of); Points[5].y = (int)(-diagonal * d_of + x_of);
|
||||
Points[6].x = (int)(-max * d_of + x_of); Points[6].y = (int)(0.0 * d_of + x_of);
|
||||
Points[7].x = (int)(-diagonal * d_of + x_of); Points[7].y = (int)(diagonal * d_of + x_of);
|
||||
|
||||
// draw polygon
|
||||
dc.DrawPolygon(8, Points);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -106,7 +146,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event))
|
||||
{
|
||||
// deadzone circle
|
||||
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
|
||||
dc.DrawCircle( 32, 32, ((*g)->control_group)->settings[0]->value * 32 );
|
||||
dc.DrawCircle( 32, 32, ((*g)->control_group)->settings[SETTING_DEADZONE]->value * 32 );
|
||||
}
|
||||
|
||||
// raw dot
|
||||
|
||||
@@ -113,7 +113,7 @@ void Host_SysMessage(const char *fmt, ...)
|
||||
char msg[512];
|
||||
|
||||
va_start(list, fmt);
|
||||
vsprintf(msg, fmt, list);
|
||||
vsnprintf(msg, 512, fmt, list);
|
||||
va_end(list);
|
||||
|
||||
size_t len = strlen(msg);
|
||||
|
||||
@@ -87,6 +87,7 @@ wxString aa_desc = wxTRANSLATE("Reduces the amount of aliasing caused by rasteri
|
||||
wxString scaled_efb_copy_desc = wxTRANSLATE("Greatly increases quality of textures generated using render to texture effects.\nRaising the internal resolution will improve the effect of this setting.\nSlightly decreases performance and possibly causes issues (although unlikely).\n\nIf unsure, leave this checked.");
|
||||
wxString pixel_lighting_desc = wxTRANSLATE("Calculate lighting of 3D graphics per-pixel rather than per vertex.\nDecreases emulation speed by some percent (depending on your GPU).\nThis usually is a safe enhancement, but might cause issues sometimes.\n\nIf unsure, leave this unchecked.");
|
||||
wxString hacked_buffer_upload_desc = wxTRANSLATE("Use a hacked upload strategy to stream vertices.\nThis usually speed up, but is forbidden by OpenGL specification and may causes heavy glitches.\n\nIf unsure, leave this unchecked.");
|
||||
wxString fast_depth_calc_desc = wxTRANSLATE("Use a less accurate algorithm to calculate depth values.\nCauses issues in a few games but might give a decent speedup.\n\nIf unsure, leave this checked.");
|
||||
wxString force_filtering_desc = wxTRANSLATE("Force texture filtering even if the emulated game explicitly disabled it.\nImproves texture quality slightly but causes glitches in some games.\n\nIf unsure, leave this unchecked.");
|
||||
wxString _3d_vision_desc = wxTRANSLATE("Enable 3D effects via stereoscopy using Nvidia 3D Vision technology if it's supported by your GPU.\nPossibly causes issues.\nRequires fullscreen to work.\n\nIf unsure, leave this unchecked.");
|
||||
wxString internal_res_desc = wxTRANSLATE("Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain games.\n\"Multiple of 640x528\" is a bit slower than \"Window Size\" but yields less issues. Generally speaking, the lower the internal resolution is, the better your performance will be.\n\nIf unsure, select 640x528.");
|
||||
@@ -130,6 +131,7 @@ wxString shader_errors_desc = wxTRANSLATE("Usually if shader compilation fails,
|
||||
wxArrayString GetListOfResolutions()
|
||||
{
|
||||
wxArrayString retlist;
|
||||
retlist.Add("Auto");
|
||||
#ifdef _WIN32
|
||||
DWORD iModeNum = 0;
|
||||
DEVMODE dmi;
|
||||
@@ -496,15 +498,12 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con
|
||||
// - other hacks
|
||||
{
|
||||
wxGridSizer* const szr_other = new wxGridSizer(2, 5, 5);
|
||||
SettingCheckBox* hacked_buffer_upload_cb;
|
||||
szr_other->Add(CreateCheckBox(page_hacks, _("Cache Display Lists"), wxGetTranslation(dlc_desc), vconfig.bDlistCachingEnable));
|
||||
szr_other->Add(CreateCheckBox(page_hacks, _("Disable Destination Alpha"), wxGetTranslation(disable_dstalpha_desc), vconfig.bDstAlphaPass));
|
||||
szr_other->Add(CreateCheckBox(page_hacks, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL));
|
||||
szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder));
|
||||
szr_other->Add(hacked_buffer_upload_cb = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload));
|
||||
|
||||
if (Core::GetState() != Core::CORE_UNINITIALIZED)
|
||||
hacked_buffer_upload_cb->Disable();
|
||||
szr_other->Add(CreateCheckBox(page_hacks, _("Fast Depth Calculation"), wxGetTranslation(fast_depth_calc_desc), vconfig.bFastDepthCalc));
|
||||
szr_other->Add(hacked_buffer_upload = CreateCheckBox(page_hacks, _("Hacked Buffer Upload"), wxGetTranslation(hacked_buffer_upload_desc), vconfig.bHackedBufferUpload));
|
||||
|
||||
wxStaticBoxSizer* const group_other = new wxStaticBoxSizer(wxVERTICAL, page_hacks, _("Other"));
|
||||
group_other->Add(szr_other, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "Core.h"
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/textctrl.h>
|
||||
@@ -165,6 +166,10 @@ protected:
|
||||
// XFB
|
||||
virtual_xfb->Enable(vconfig.bUseXFB);
|
||||
real_xfb->Enable(vconfig.bUseXFB);
|
||||
|
||||
// OGL Hacked buffer
|
||||
hacked_buffer_upload->Enable(Core::GetState() == Core::CORE_UNINITIALIZED && vconfig.backend_info.APIType == API_OPENGL);
|
||||
hacked_buffer_upload->Show(vconfig.backend_info.APIType == API_OPENGL);
|
||||
|
||||
ev.Skip();
|
||||
}
|
||||
@@ -194,6 +199,7 @@ protected:
|
||||
SettingRadioButton* efbcopy_ram;
|
||||
SettingCheckBox* cache_efb_copies;
|
||||
SettingCheckBox* emulate_efb_format_changes;
|
||||
SettingCheckBox* hacked_buffer_upload;
|
||||
|
||||
SettingRadioButton* virtual_xfb;
|
||||
SettingRadioButton* real_xfb;
|
||||
|
||||
@@ -15,7 +15,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
|
||||
wxStaticText* wiimote_label[4];
|
||||
wxChoice* wiimote_source_ch[4];
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||
{
|
||||
wxString str;
|
||||
str.Printf(_("Wiimote %i"), i + 1);
|
||||
@@ -54,8 +54,25 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
|
||||
wiimote_sizer->Add(wiimote_configure_bt[i]);
|
||||
}
|
||||
wiimote_group->Add(wiimote_sizer, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
// "BalanceBoard" layout
|
||||
wxStaticBoxSizer* const bb_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Balance Board"));
|
||||
wxFlexGridSizer* const bb_sizer = new wxFlexGridSizer(1, 5, 5);
|
||||
int source_ctrl_id = wxWindow::NewControlId();
|
||||
m_wiimote_index_from_ctrl_id.insert(std::pair<wxWindowID, unsigned int>(source_ctrl_id, WIIMOTE_BALANCE_BOARD));
|
||||
const wxString src_choices[] = { _("None"), _("Real Balance Board") };
|
||||
wxChoice* bb_source = new wxChoice(this, source_ctrl_id, wxDefaultPosition, wxDefaultSize, sizeof(src_choices)/sizeof(*src_choices), src_choices);
|
||||
bb_source->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &WiimoteConfigDiag::SelectSource, this);
|
||||
|
||||
m_orig_wiimote_sources[WIIMOTE_BALANCE_BOARD] = g_wiimote_sources[WIIMOTE_BALANCE_BOARD];
|
||||
bb_source->Select(m_orig_wiimote_sources[WIIMOTE_BALANCE_BOARD] ? 1 : 0);
|
||||
|
||||
bb_sizer->Add(bb_source, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
bb_group->Add(bb_sizer, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
|
||||
// "Real wiimotes" controls
|
||||
wxButton* const refresh_btn = new wxButton(this, -1, _("Refresh"), wxDefaultPosition);
|
||||
refresh_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::RefreshRealWiimotes, this);
|
||||
@@ -166,6 +183,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
|
||||
|
||||
// Dialog layout
|
||||
main_sizer->Add(wiimote_group, 0, wxEXPAND | wxALL, 5);
|
||||
main_sizer->Add(bb_group, 0, wxEXPAND | wxALL, 5);
|
||||
main_sizer->Add(real_wiimotes_group, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
main_sizer->Add(general_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
@@ -196,17 +214,23 @@ void WiimoteConfigDiag::SelectSource(wxCommandEvent& event)
|
||||
// Revert if the dialog is canceled.
|
||||
int index = m_wiimote_index_from_ctrl_id[event.GetId()];
|
||||
|
||||
WiimoteReal::ChangeWiimoteSource(index, event.GetInt());
|
||||
|
||||
if (g_wiimote_sources[index] != WIIMOTE_SRC_EMU && g_wiimote_sources[index] != WIIMOTE_SRC_HYBRID)
|
||||
wiimote_configure_bt[index]->Disable();
|
||||
if(index != WIIMOTE_BALANCE_BOARD)
|
||||
{
|
||||
WiimoteReal::ChangeWiimoteSource(index, event.GetInt());
|
||||
if (g_wiimote_sources[index] != WIIMOTE_SRC_EMU && g_wiimote_sources[index] != WIIMOTE_SRC_HYBRID)
|
||||
wiimote_configure_bt[index]->Disable();
|
||||
else
|
||||
wiimote_configure_bt[index]->Enable();
|
||||
}
|
||||
else
|
||||
wiimote_configure_bt[index]->Enable();
|
||||
{
|
||||
WiimoteReal::ChangeWiimoteSource(index, event.GetInt() ? WIIMOTE_SRC_REAL : WIIMOTE_SRC_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
void WiimoteConfigDiag::RevertSource()
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < MAX_BBMOTES; ++i)
|
||||
g_wiimote_sources[i] = m_orig_wiimote_sources[i];
|
||||
}
|
||||
|
||||
@@ -225,6 +249,10 @@ void WiimoteConfigDiag::Save(wxCommandEvent& event)
|
||||
|
||||
sec.Set("Source", (int)g_wiimote_sources[i]);
|
||||
}
|
||||
|
||||
std::string secname("BalanceBoard");
|
||||
IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
|
||||
sec.Set("Source", (int)g_wiimote_sources[WIIMOTE_BALANCE_BOARD]);
|
||||
|
||||
inifile.Save(ini_filename);
|
||||
|
||||
|
||||
@@ -76,9 +76,9 @@ private:
|
||||
wxNotebook* m_pad_notebook;
|
||||
|
||||
std::map<wxWindowID, unsigned int> m_wiimote_index_from_ctrl_id;
|
||||
unsigned int m_orig_wiimote_sources[4];
|
||||
unsigned int m_orig_wiimote_sources[MAX_BBMOTES];
|
||||
|
||||
wxButton* wiimote_configure_bt[4];
|
||||
wxButton* wiimote_configure_bt[MAX_WIIMOTES];
|
||||
std::map<wxWindowID, unsigned int> m_wiimote_index_from_conf_bt_id;
|
||||
};
|
||||
|
||||
|
||||
@@ -200,6 +200,9 @@ XRRConfiguration::~XRRConfiguration()
|
||||
|
||||
void XRRConfiguration::Update()
|
||||
{
|
||||
if(SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution == "Auto")
|
||||
return;
|
||||
|
||||
if (!bValid)
|
||||
return;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user