diff --git a/CMakeLists.txt b/CMakeLists.txt index df5e123..4744ee9 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,7 @@ endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") set(FINAL_EXTENSION ".exe") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Android") else() if(MSVC) list(APPEND EXTRA_CXX_FLAGS "/DXLIB_BASED 1") @@ -430,10 +431,23 @@ if(USE_FTD2XX_FOR_NEW_DS_LOOPY) endif() endif() -FetchContent_MakeAvailable(SFML ${FETCH_CONTENT_MAKE_AVAILABLE_LIBRARIES}) -# Find libusb -set(LIBUSB_INCLUDE_DIR ${libusb_SOURCE_DIR}/libusb/libusb) -FetchContent_MakeAvailable(${FETCH_CONTENT_MAKE_AVAILABLE_LIBRARIES_SEPARATE}) +if(NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Android")) + FetchContent_MakeAvailable(SFML ${FETCH_CONTENT_MAKE_AVAILABLE_LIBRARIES}) + # Find libusb + set(LIBUSB_INCLUDE_DIR ${libusb_SOURCE_DIR}/libusb/libusb) + FetchContent_MakeAvailable(${FETCH_CONTENT_MAKE_AVAILABLE_LIBRARIES_SEPARATE}) +else() + set(SFML_DIR "${CMAKE_ANDROID_NDK}/sources/third_party/sfml/lib/${CMAKE_ANDROID_ARCH_ABI}/cmake/SFML") + # Find SFML + find_package(SFML 3 REQUIRED COMPONENTS Graphics Audio Window System Main) + set(OLD_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) + set(CMAKE_MODULE_PATH ${SFML_DIR}) + find_package(EGL REQUIRED) + find_package(GLES REQUIRED) + set(CMAKE_MODULE_PATH ${OLD_CMAKE_MODULE_PATH}) + set(LIBUSB_DIR "${CMAKE_ANDROID_NDK}/sources/third_party/libusb") + set(LIBUSB_INCLUDE_DIR ${LIBUSB_DIR}/include/libusb) +endif() set(EXTRA_INCLUDE_DIRECTORIES "") if(USE_FTD3XX_FOR_N3DSXL_LOOPY) @@ -443,7 +457,7 @@ if(USE_FTD2XX_FOR_NEW_DS_LOOPY) list(APPEND EXTRA_INCLUDE_DIRECTORIES ${ftd2xx_BINARY_DIR}/${FTD2XX_SUBFOLDER}) endif() if(USE_LIBUSB_SUPPORT) - list(APPEND EXTRA_INCLUDE_DIRECTORIES ${libusb_SOURCE_DIR}/libusb/libusb) + list(APPEND EXTRA_INCLUDE_DIRECTORIES ${LIBUSB_INCLUDE_DIR}) endif() if(IS_DIRECTORY "${sfml_SOURCE_DIR}") @@ -547,14 +561,34 @@ else() set_source_files_properties(source/conversions.cpp PROPERTIES COMPILE_OPTIONS "$<$:-O3;-funroll-loops>") endif() -add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/TextRectanglePool.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp source/Menus/AudioDeviceMenu.cpp source/Menus/SeparatorMenu.cpp source/Menus/ColorCorrectionMenu.cpp source/Menus/Main3DMenu.cpp source/Menus/SecondScreen3DRelativePositionMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES}) +set(EXECUTABLE_SOURCE_FILES source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/TextRectanglePool.cpp source/WindowScreen.cpp source/WindowScreen_Menu.cpp source/devicecapture.cpp source/conversions.cpp source/ExtraButtons.cpp source/Menus/ConnectionMenu.cpp source/Menus/OptionSelectionMenu.cpp source/Menus/MainMenu.cpp source/Menus/VideoMenu.cpp source/Menus/CropMenu.cpp source/Menus/PARMenu.cpp source/Menus/RotationMenu.cpp source/Menus/OffsetMenu.cpp source/Menus/AudioMenu.cpp source/Menus/BFIMenu.cpp source/Menus/RelativePositionMenu.cpp source/Menus/ResolutionMenu.cpp source/Menus/FileConfigMenu.cpp source/Menus/ExtraSettingsMenu.cpp source/Menus/StatusMenu.cpp source/Menus/LicenseMenu.cpp source/WindowCommands.cpp source/Menus/ShortcutMenu.cpp source/Menus/ActionSelectionMenu.cpp source/Menus/ScalingRatioMenu.cpp source/Menus/ISNitroMenu.cpp source/Menus/VideoEffectsMenu.cpp source/CaptureDataBuffers.cpp source/Menus/InputMenu.cpp source/Menus/AudioDeviceMenu.cpp source/Menus/SeparatorMenu.cpp source/Menus/ColorCorrectionMenu.cpp source/Menus/Main3DMenu.cpp source/Menus/SecondScreen3DRelativePositionMenu.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp ${TOOLS_DATA_DIR}/shaders_list.cpp ${SOURCE_CPP_EXTRA_FILES}) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + if(MSVC) + list(APPEND EXTRA_CXX_FLAGS "/DSFML_SYSTEM_ANDROID") + else() + list(APPEND EXTRA_CXX_FLAGS "-DSFML_SYSTEM_ANDROID") + endif() + # Create the cc3dsfs.so library that contains the application's c++ code + add_library(${OUTPUT_NAME} SHARED ${EXECUTABLE_SOURCE_FILES}) + list(APPEND EXTRA_LIBRARIES android) + list(APPEND EXTRA_LIBRARIES log) + list(APPEND EXTRA_LIBRARIES EGL::EGL) + list(APPEND EXTRA_LIBRARIES GLES::GLES) +else() + add_executable(${OUTPUT_NAME} ${EXECUTABLE_SOURCE_FILES}) +endif() if(NOT ("${EXTRA_DEPENDENCIES}" STREQUAL "")) add_dependencies(${OUTPUT_NAME} ${EXTRA_DEPENDENCIES}) endif() target_link_libraries(${OUTPUT_NAME} PRIVATE SFML::Graphics SFML::Audio SFML::Window SFML::System ${EXTRA_LIBRARIES}) if(USE_LIBUSB_SUPPORT) - target_link_libraries(${OUTPUT_NAME} PRIVATE usb-1.0) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + target_link_libraries(${OUTPUT_NAME} PRIVATE ${LIBUSB_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}/libusb1.0.so) + else() + target_link_libraries(${OUTPUT_NAME} PRIVATE usb-1.0) + endif() endif() if(USE_FTD3XX_FOR_N3DSXL_LOOPY) target_link_libraries(${OUTPUT_NAME} PRIVATE ${ftd3xx_BINARY_DIR}/${FTD3XX_SUBFOLDER}/${FTD3XX_LIB}) @@ -566,6 +600,14 @@ target_include_directories(${OUTPUT_NAME} PRIVATE ${EXTRA_INCLUDE_DIRECTORIES} $ target_compile_features(${OUTPUT_NAME} PRIVATE cxx_std_20) target_compile_options(${OUTPUT_NAME} PRIVATE ${EXTRA_CXX_FLAGS}) +if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + target_link_libraries(${OUTPUT_NAME} PUBLIC + -Wl,--whole-archive + SFML::Main + -Wl,--no-whole-archive + ) +endif() + add_custom_command( OUTPUT ${TOOLS_DATA_DIR}/font_ttf.cpp COMMENT "Convert font to binary" diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..15b3e20 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,9 @@ +local.properties +.idea +.gradle +build +android.iml +app/build +app/.cxx +app/.externalNativeBuild +app/src/main/obj diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts new file mode 100644 index 0000000..fd45e93 --- /dev/null +++ b/android/app/build.gradle.kts @@ -0,0 +1,48 @@ +val NDK_VERSION by extra(project.properties["NDK_VERSION"] as? String ?: "26.1.10909125") +val ARCH_ABI by extra(project.properties["ARCH_ABI"] as? String ?: "arm64-v8a") +val MIN_SDK by extra((project.properties["MIN_SDK"] as? String ?: "21").toInt()) +val TARGET_SDK by extra((project.properties["TARGET_SDK"] as? String ?: "33").toInt()) +val STL_TYPE by extra(project.properties["STL_TYPE"] as? String ?: "c++_shared") +val SFML_STATIC by extra(project.properties["SFML_STATIC"] as? String ?: "OFF") + +plugins { + id("com.android.application") +} + +android { + namespace = "org.cc3dsfs.android" + ndkVersion = NDK_VERSION + compileSdk = TARGET_SDK + defaultConfig { + applicationId = "org.cc3dsfs.android" + minSdk = MIN_SDK + targetSdk = TARGET_SDK + versionCode = 1 + versionName = "1.0" + ndk { + abiFilters.add(ARCH_ABI) + } + externalNativeBuild { + cmake { + arguments.add("-DCMAKE_SYSTEM_NAME=Android") + arguments.add("-DANDROID_STL=${STL_TYPE}") + arguments.add("-DSFML_STATIC_LIBRARIES=${SFML_STATIC}") + } + } + } + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + } + } + externalNativeBuild { + cmake { + path("../../CMakeLists.txt") + } + } +} + +dependencies { + implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) +} diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..635a52e --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable-hdpi/sfml_logo.png b/android/app/src/main/res/drawable-hdpi/sfml_logo.png new file mode 100644 index 0000000..7bae333 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/sfml_logo.png differ diff --git a/android/app/src/main/res/drawable-ldpi/sfml_logo.png b/android/app/src/main/res/drawable-ldpi/sfml_logo.png new file mode 100644 index 0000000..6552c56 Binary files /dev/null and b/android/app/src/main/res/drawable-ldpi/sfml_logo.png differ diff --git a/android/app/src/main/res/drawable-mdpi/sfml_logo.png b/android/app/src/main/res/drawable-mdpi/sfml_logo.png new file mode 100644 index 0000000..8778688 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/sfml_logo.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/sfml_logo.png b/android/app/src/main/res/drawable-xhdpi/sfml_logo.png new file mode 100644 index 0000000..ff0d3aa Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/sfml_logo.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/sfml_logo.png b/android/app/src/main/res/drawable-xxhdpi/sfml_logo.png new file mode 100644 index 0000000..8a66e84 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/sfml_logo.png differ diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..b5c8f82 --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + cc3dsfs + diff --git a/android/app/src/main/res/xml/device_filter.xml b/android/app/src/main/res/xml/device_filter.xml new file mode 100644 index 0000000..ddf9928 --- /dev/null +++ b/android/app/src/main/res/xml/device_filter.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/android/build.gradle.kts b/android/build.gradle.kts new file mode 100644 index 0000000..e86cd52 --- /dev/null +++ b/android/build.gradle.kts @@ -0,0 +1,27 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + classpath("com.android.tools.build:gradle:7.4.1") + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +tasks.withType { + gradleVersion = "7.6.2" + distributionType = Wrapper.DistributionType.BIN +} + +tasks.register("clean", Delete::class) { + delete(rootProject.layout.buildDirectory) +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..db4051e --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +android.native.buildOutput=verbose diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7f93135 Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..66c01cf --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/android/gradlew b/android/gradlew new file mode 100644 index 0000000..0adc8e1 --- /dev/null +++ b/android/gradlew @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts new file mode 100644 index 0000000..15a801b --- /dev/null +++ b/android/settings.gradle.kts @@ -0,0 +1 @@ +include(":app") diff --git a/docker-scripts/docker_build_android b/docker-scripts/docker_build_android index 7248a1a..bc74938 100644 --- a/docker-scripts/docker_build_android +++ b/docker-scripts/docker_build_android @@ -1,16 +1,20 @@ #!/bin/sh SFML_EXTRACTED_TO_FOLDER=~ +LIBUSB_EXTRACTED_TO_FOLDER=~ SFML_EXTRACTED_FOLDER=${SFML_EXTRACTED_TO_FOLDER}/SFML-master +LIBUSB_EXTRACTED_FOLDER=${LIBUSB_EXTRACTED_TO_FOLDER}/libusb-master BUILD_ARCH_COMMAND=docker-scripts/docker_build_android_single_arch STL_CHOSEN=c++_static RELEASE_TYPE=Debug OUT_FOLDER=~/cc3dsfs/build -ANDROID_FOLDER=${SFML_EXTRACTED_FOLDER}/examples/android +ANDROID_FOLDER=android export LANG=C.UTF-8 -(cd ${SFML_EXTRACTED_TO_FOLDER} ; wget https://github.com/SFML/SFML/archive/refs/heads/master.zip ; unzip master.zip) +(cd ${SFML_EXTRACTED_TO_FOLDER} ; rm -f master.zip ; wget https://github.com/SFML/SFML/archive/refs/heads/master.zip ; unzip master.zip) +(cd ${LIBUSB_EXTRACTED_TO_FOLDER} ; rm -f master.zip ; wget https://github.com/libusb/libusb/archive/refs/heads/master.zip ; unzip master.zip) +(cd ${LIBUSB_EXTRACTED_FOLDER}/android/jni ; ndk-build ; mkdir -p ${ANDROID_NDK_HOME}/sources/third_party/libusb/include ; cp -r ../libs/ ${ANDROID_NDK_HOME}/sources/third_party/libusb ; cp -r ../../libusb ${ANDROID_NDK_HOME}/sources/third_party/libusb/include ) #${BUILD_ARCH_COMMAND} ${SFML_EXTRACTED_FOLDER} armeabi-v7a ${STL_CHOSEN} ${RELEASE_TYPE} ${OUT_FOLDER} ${ANDROID_FOLDER} ${BUILD_ARCH_COMMAND} ${SFML_EXTRACTED_FOLDER} arm64-v8a ${STL_CHOSEN} ${RELEASE_TYPE} ${OUT_FOLDER} ${ANDROID_FOLDER} diff --git a/docker-scripts/docker_build_android_single_arch b/docker-scripts/docker_build_android_single_arch index 5aa0bbd..80a7490 100644 --- a/docker-scripts/docker_build_android_single_arch +++ b/docker-scripts/docker_build_android_single_arch @@ -29,4 +29,5 @@ LOWER_RELEASE_TYPE=$(to_lower $RELEASE_TYPE) # Default with gradle-wrapper, slow in docker #./gradlew assemble${RELEASE_TYPE} ${GRADLE_FLAGS} # Use the pre-donwloaded gradle to speed build up + (cd ${ANDROID_FOLDER} && gradle assemble${RELEASE_TYPE} ${GRADLE_FLAGS} && mkdir -p ${OUT_FOLDER} && cp app/build/outputs/apk/${LOWER_RELEASE_TYPE}/*.apk ${OUT_FOLDER}) diff --git a/include/Menus/OptionSelectionMenu.hpp b/include/Menus/OptionSelectionMenu.hpp index 8c8831d..49ba207 100755 --- a/include/Menus/OptionSelectionMenu.hpp +++ b/include/Menus/OptionSelectionMenu.hpp @@ -22,7 +22,7 @@ public: virtual ~OptionSelectionMenu(); bool poll(SFEvent &event_data); void draw(float scaling_factor, sf::RenderTarget &window); - void reset_data(); + void reset_data(bool full_reset); std::chrono::time_point last_input_processed_time; virtual void reset_output_option(); protected: diff --git a/include/Menus/RelativePositionMenu.hpp b/include/Menus/RelativePositionMenu.hpp index 3e2fedf..1ba973e 100755 --- a/include/Menus/RelativePositionMenu.hpp +++ b/include/Menus/RelativePositionMenu.hpp @@ -24,7 +24,7 @@ public: virtual ~RelativePositionMenu(); bool poll(SFEvent &event_data); void draw(float scaling_factor, sf::RenderTarget &window); - void reset_data(); + void reset_data(bool full_reset); std::chrono::time_point last_input_processed_time; void reset_output_option(); void prepare(float scaling_factor, int view_size_x, int view_size_y, BottomRelativePosition curr_bottom_pos); diff --git a/include/frontend.hpp b/include/frontend.hpp index b4c2b1c..0e8db8d 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -138,6 +138,7 @@ private: AudioData* audio_data; std::chrono::time_point last_mouse_action_time; std::chrono::time_point last_window_creation_time; + std::chrono::time_point last_touch_left_time; HeldTime touch_right_click_action; HeldTime touch_action; HeldTime pgdown_action; @@ -147,6 +148,7 @@ private: HeldTime right_click_action; HeldTime controller_button_action; bool consumed_touch_long_press; + const float touch_short_press_timer = 0.2f; const float touch_long_press_timer = 1.5f; const float mouse_timeout = 5.0f; const float v_sync_timeout = 5.0f; diff --git a/source/Menus/OptionSelectionMenu.cpp b/source/Menus/OptionSelectionMenu.cpp index 272d9e5..b57f93a 100755 --- a/source/Menus/OptionSelectionMenu.cpp +++ b/source/Menus/OptionSelectionMenu.cpp @@ -86,11 +86,13 @@ bool OptionSelectionMenu::can_execute_action() { return false; } -void OptionSelectionMenu::reset_data() { +void OptionSelectionMenu::reset_data(bool full_reset) { this->last_input_processed_time = std::chrono::high_resolution_clock::now(); - this->reset_output_option(); - this->future_data.option_selected = -1; - this->future_data.page = 0; + if(full_reset) { + this->reset_output_option(); + this->future_data.option_selected = -1; + this->future_data.page = 0; + } } bool OptionSelectionMenu::is_option_location_left(int option) { diff --git a/source/Menus/RelativePositionMenu.cpp b/source/Menus/RelativePositionMenu.cpp index 9f21da2..4964e3d 100755 --- a/source/Menus/RelativePositionMenu.cpp +++ b/source/Menus/RelativePositionMenu.cpp @@ -139,10 +139,12 @@ void RelativePositionMenu::insert_data() { this->prepare_options(); } -void RelativePositionMenu::reset_data() { +void RelativePositionMenu::reset_data(bool full_reset) { this->last_input_processed_time = std::chrono::high_resolution_clock::now(); - this->reset_output_option(); - this->future_data.option_selected = -1; + if(full_reset) { + this->reset_output_option(); + this->future_data.option_selected = -1; + } } bool RelativePositionMenu::is_option_element(int option) { diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index cacb6aa..243e547 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -113,6 +113,7 @@ WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, Disp this->audio_data = audio_data; this->last_window_creation_time = std::chrono::high_resolution_clock::now(); this->last_mouse_action_time = std::chrono::high_resolution_clock::now(); + this->last_touch_left_time = std::chrono::high_resolution_clock::now(); this->last_draw_time = std::chrono::high_resolution_clock::now(); this->last_poll_time = std::chrono::high_resolution_clock::now(); this->touch_right_click_action.started = false; diff --git a/source/WindowScreen_Menu.cpp b/source/WindowScreen_Menu.cpp index b5a20c9..57c2e5b 100755 --- a/source/WindowScreen_Menu.cpp +++ b/source/WindowScreen_Menu.cpp @@ -846,13 +846,19 @@ void WindowScreen::setup_no_menu() { this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } +void WindowScreen::setup_connection_menu(std::vector *devices_list, bool reset_data) { + // Skip the check here. It's special. + this->curr_menu = CONNECT_MENU_TYPE; + this->connection_menu->reset_data(reset_data); + this->connection_menu->insert_data(devices_list); +} + void WindowScreen::setup_main_menu(bool reset_data, bool skip_setup_check) { if((!skip_setup_check) && (!this->can_setup_menu())) return; if(this->curr_menu != MAIN_MENU_TYPE) { this->curr_menu = MAIN_MENU_TYPE; - if(reset_data) - this->main_menu->reset_data(); + this->main_menu->reset_data(reset_data); this->main_menu->insert_data(this->m_stype, this->m_info.is_fullscreen, this->display_data->mono_app_mode, &this->capture_status->device, this->capture_status->connected); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -863,8 +869,7 @@ void WindowScreen::setup_input_menu(bool reset_data) { return; if(this->curr_menu != INPUT_MENU_TYPE) { this->curr_menu = INPUT_MENU_TYPE; - if(reset_data) - this->input_menu->reset_data(); + this->input_menu->reset_data(reset_data); this->input_menu->insert_data(is_shortcut_valid(), are_extra_buttons_usable()); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -877,8 +882,7 @@ void WindowScreen::setup_audio_devices_menu(bool reset_data){ this->possible_audio_devices.clear(); this->possible_audio_devices = sf::PlaybackDevice::getAvailableDevices(); this->curr_menu = AUDIO_DEVICE_MENU_TYPE; - if(reset_data) - this->audio_device_menu->reset_data(); + this->audio_device_menu->reset_data(reset_data); this->audio_device_menu->insert_data(&this->possible_audio_devices); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -889,8 +893,7 @@ void WindowScreen::setup_video_menu(bool reset_data) { return; if(this->curr_menu != VIDEO_MENU_TYPE) { this->curr_menu = VIDEO_MENU_TYPE; - if(reset_data) - this->video_menu->reset_data(); + this->video_menu->reset_data(reset_data); this->video_menu->insert_data(this->m_stype, this->m_info.is_fullscreen, (!this->m_info.is_fullscreen) || this->m_info.failed_fullscreen); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -901,8 +904,7 @@ void WindowScreen::setup_crop_menu(bool reset_data) { return; if(this->curr_menu != CROP_MENU_TYPE) { this->curr_menu = CROP_MENU_TYPE; - if(reset_data) - this->crop_menu->reset_data(); + this->crop_menu->reset_data(reset_data); this->crop_menu->insert_data(this->get_crop_data_vector(&this->m_info)); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -916,8 +918,7 @@ void WindowScreen::setup_par_menu(bool is_top, bool reset_data) { wanted_type = BOTTOM_PAR_MENU_TYPE; if(this->curr_menu != wanted_type) { this->curr_menu = wanted_type; - if(reset_data) - this->par_menu->reset_data(); + this->par_menu->reset_data(reset_data); std::string title_piece = ""; if((is_top) && (this->m_stype == ScreenType::JOINT)) title_piece = "Top"; @@ -934,8 +935,7 @@ void WindowScreen::setup_offset_menu(bool reset_data) { return; if(this->curr_menu != OFFSET_MENU_TYPE) { this->curr_menu = OFFSET_MENU_TYPE; - if(reset_data) - this->offset_menu->reset_data(); + this->offset_menu->reset_data(reset_data); this->offset_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -946,8 +946,7 @@ void WindowScreen::setup_rotation_menu(bool reset_data) { return; if(this->curr_menu != ROTATION_MENU_TYPE) { this->curr_menu = ROTATION_MENU_TYPE; - if(reset_data) - this->rotation_menu->reset_data(); + this->rotation_menu->reset_data(reset_data); this->rotation_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -958,8 +957,7 @@ void WindowScreen::setup_audio_menu(bool reset_data) { return; if(this->curr_menu != AUDIO_MENU_TYPE) { this->curr_menu = AUDIO_MENU_TYPE; - if(reset_data) - this->audio_menu->reset_data(); + this->audio_menu->reset_data(reset_data); this->audio_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -970,8 +968,7 @@ void WindowScreen::setup_bfi_menu(bool reset_data) { return; if(this->curr_menu != BFI_MENU_TYPE) { this->curr_menu = BFI_MENU_TYPE; - if(reset_data) - this->bfi_menu->reset_data(); + this->bfi_menu->reset_data(reset_data); this->bfi_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1015,8 +1012,7 @@ void WindowScreen::setup_fileconfig_menu(bool is_save, bool reset_data, bool ski this->possible_files.erase(this->possible_files.begin()); } this->curr_menu = wanted_type; - if(reset_data) - this->fileconfig_menu->reset_data(); + this->fileconfig_menu->reset_data(reset_data); std::string title_piece = "Load"; if(is_save) title_piece = "Save"; @@ -1048,8 +1044,7 @@ void WindowScreen::setup_resolution_menu(bool reset_data) { } if(this->possible_resolutions.size() > 0) { this->curr_menu = RESOLUTION_MENU_TYPE; - if(reset_data) - this->resolution_menu->reset_data(); + this->resolution_menu->reset_data(reset_data); this->resolution_menu->insert_data(&this->possible_resolutions, sf::VideoMode::getDesktopMode()); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1061,8 +1056,7 @@ void WindowScreen::setup_extra_menu(bool reset_data) { return; if(this->curr_menu != EXTRA_MENU_TYPE) { this->curr_menu = EXTRA_MENU_TYPE; - if(reset_data) - this->extra_menu->reset_data(); + this->extra_menu->reset_data(reset_data); this->extra_menu->insert_data(this->m_stype, this->m_info.is_fullscreen); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1073,8 +1067,7 @@ void WindowScreen::setup_action_selection_menu(bool reset_data) { return; if(this->curr_menu != ACTION_SELECTION_MENU_TYPE) { this->curr_menu = ACTION_SELECTION_MENU_TYPE; - if(reset_data) - this->action_selection_menu->reset_data(); + this->action_selection_menu->reset_data(reset_data); this->possible_actions.clear(); create_window_commands_list(this->possible_actions, this->possible_buttons_extras[this->chosen_button] && this->display_data->mono_app_mode); this->action_selection_menu->insert_data(this->possible_actions); @@ -1089,8 +1082,7 @@ void WindowScreen::setup_shortcuts_menu(bool reset_data) { return; if(this->curr_menu != SHORTCUTS_MENU_TYPE) { this->curr_menu = SHORTCUTS_MENU_TYPE; - if(reset_data) - this->shortcut_menu->reset_data(); + this->shortcut_menu->reset_data(reset_data); this->possible_buttons_names.clear(); this->possible_buttons_ptrs.clear(); this->possible_buttons_extras.clear(); @@ -1114,8 +1106,7 @@ void WindowScreen::setup_status_menu(bool reset_data) { return; if(this->curr_menu != STATUS_MENU_TYPE) { this->curr_menu = STATUS_MENU_TYPE; - if(reset_data) - this->status_menu->reset_data(); + this->status_menu->reset_data(reset_data); this->status_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1126,8 +1117,7 @@ void WindowScreen::setup_licenses_menu(bool reset_data) { return; if(this->curr_menu != LICENSES_MENU_TYPE) { this->curr_menu = LICENSES_MENU_TYPE; - if(reset_data) - this->license_menu->reset_data(); + this->license_menu->reset_data(reset_data); this->license_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1138,8 +1128,7 @@ void WindowScreen::setup_relative_pos_menu(bool reset_data) { return; if(this->curr_menu != RELATIVE_POS_MENU_TYPE) { this->curr_menu = RELATIVE_POS_MENU_TYPE; - if(reset_data) - this->relpos_menu->reset_data(); + this->relpos_menu->reset_data(reset_data); this->relpos_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1150,8 +1139,7 @@ void WindowScreen::setup_scaling_ratio_menu(bool reset_data) { return; if(this->curr_menu != SCALING_RATIO_MENU_TYPE) { this->curr_menu = SCALING_RATIO_MENU_TYPE; - if(reset_data) - this->scaling_ratio_menu->reset_data(); + this->scaling_ratio_menu->reset_data(reset_data); this->scaling_ratio_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1162,8 +1150,7 @@ void WindowScreen::setup_is_nitro_menu(bool reset_data) { return; if(this->curr_menu != ISN_MENU_TYPE) { this->curr_menu = ISN_MENU_TYPE; - if(reset_data) - this->is_nitro_menu->reset_data(); + this->is_nitro_menu->reset_data(reset_data); this->is_nitro_menu->insert_data(&this->capture_status->device); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1174,8 +1161,7 @@ void WindowScreen::setup_video_effects_menu(bool reset_data) { return; if(this->curr_menu != VIDEO_EFFECTS_MENU_TYPE) { this->curr_menu = VIDEO_EFFECTS_MENU_TYPE; - if(reset_data) - this->video_effects_menu->reset_data(); + this->video_effects_menu->reset_data(reset_data); this->video_effects_menu->insert_data(); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1186,8 +1172,7 @@ void WindowScreen::setup_separator_menu(bool reset_data) { return; if(this->curr_menu != SEPARATOR_MENU_TYPE) { this->curr_menu = SEPARATOR_MENU_TYPE; - if(reset_data) - this->separator_menu->reset_data(); + this->separator_menu->reset_data(reset_data); this->separator_menu->insert_data(this->m_info.is_fullscreen); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1198,8 +1183,7 @@ void WindowScreen::setup_color_correction_menu(bool reset_data) { return; if(this->curr_menu != COLOR_CORRECTION_MENU_TYPE) { this->curr_menu = COLOR_CORRECTION_MENU_TYPE; - if(reset_data) - this->color_correction_menu->reset_data(); + this->color_correction_menu->reset_data(reset_data); this->color_correction_menu->insert_data(&this->possible_color_profiles); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1210,8 +1194,7 @@ void WindowScreen::setup_main_3d_menu(bool reset_data) { return; if(this->curr_menu != MAIN_3D_MENU_TYPE) { this->curr_menu = MAIN_3D_MENU_TYPE; - if(reset_data) - this->main_3d_menu->reset_data(); + this->main_3d_menu->reset_data(reset_data); this->main_3d_menu->insert_data(this->m_stype); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -1222,8 +1205,7 @@ void WindowScreen::setup_second_screen_3d_relpos_menu(bool reset_data) { return; if(this->curr_menu != SECOND_SCREEN_RELATIVE_POS_MENU_TYPE) { this->curr_menu = SECOND_SCREEN_RELATIVE_POS_MENU_TYPE; - if(reset_data) - this->second_screen_3d_relpos_menu->reset_data(); + this->second_screen_3d_relpos_menu->reset_data(reset_data); this->second_screen_3d_relpos_menu->insert_data(this->m_stype); this->last_menu_change_time = std::chrono::high_resolution_clock::now(); } @@ -2372,14 +2354,6 @@ void WindowScreen::poll(bool do_everything) { } } -void WindowScreen::setup_connection_menu(std::vector *devices_list, bool reset_data) { - // Skip the check here. It's special. - this->curr_menu = CONNECT_MENU_TYPE; - if(reset_data) - this->connection_menu->reset_data(); - this->connection_menu->insert_data(devices_list); -} - int WindowScreen::check_connection_menu_result() { return this->connection_menu->selected_index; } @@ -2549,7 +2523,11 @@ void WindowScreen::poll_window(bool do_everything) { events_queue.emplace(true, sf::Mouse::Button::Right, touch_pos); this->touch_right_click_action.start_time = std::chrono::high_resolution_clock::now(); } - events_queue.emplace(true, sf::Mouse::Button::Left, touch_pos); + const std::chrono::duration difftouch = curr_time - this->last_touch_left_time; + if(difftouch.count() > this->touch_short_press_timer) { + events_queue.emplace(true, sf::Mouse::Button::Left, touch_pos); + this->last_touch_left_time = std::chrono::high_resolution_clock::now(); + } } if(this->shared_data->input_data.enable_controller_input) joystick_axis_poll(this->events_queue); diff --git a/source/cc3dsfs.cpp b/source/cc3dsfs.cpp index 8afbf4b..3d1ae65 100755 --- a/source/cc3dsfs.cpp +++ b/source/cc3dsfs.cpp @@ -777,9 +777,14 @@ int main(int argc, char **argv) { int power_id = -1; bool use_pud_up = true; bool created_proper_folder = create_out_folder(); + bool mono_app_default_value = false; + #ifdef SFML_SYSTEM_ANDROID + mono_app_default_value = true; + #endif override_all_data override_data; + override_data.mono_app = mono_app_default_value; for (int i = 1; i < argc; i++) { - if(parse_existence_arg(i, argv, override_data.mono_app, true, "--mono_app")) + if(parse_existence_arg(i, argv, override_data.mono_app, !mono_app_default_value, "--mono_app")) continue; if(parse_existence_arg(i, argv, override_data.recovery_mode, true, "--recovery_mode")) continue; @@ -835,9 +840,15 @@ int main(int argc, char **argv) { if(parse_existence_arg(i, argv, use_pud_up, false, "--pi_pud_down")) continue; #endif + std::string mono_app_action_str = "Enables"; + std::string default_mono_app_strn = "Disabled"; + if(mono_app_default_value) { + mono_app_action_str = "Disables"; + default_mono_app_strn = "Enabled"; + } std::cout << "Help:" << std::endl; - std::cout << " --mono_app Enables special mode for when only this application" << std::endl; - std::cout << " should run on the system. Disabled by default." << std::endl; + std::cout << " --mono_app "<< mono_app_action_str << " special mode for when only this application" << std::endl; + std::cout << " should run on the system. " << default_mono_app_strn << " by default." << std::endl; std::cout << " --recovery_mode Resets to the defaults." << std::endl; std::cout << " --pos_x_both Set default x position for the window with both screens." << std::endl; std::cout << " --pos_y_both Set default y position for the window with both screens." << std::endl;