├── storagechooser
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── res
│ │ │ ├── drawable-nodpi
│ │ │ │ ├── apk.png
│ │ │ │ ├── doc.png
│ │ │ │ ├── mov.png
│ │ │ │ ├── pdf.png
│ │ │ │ ├── pic.png
│ │ │ │ ├── web.png
│ │ │ │ ├── zip.png
│ │ │ │ ├── excel.png
│ │ │ │ ├── font.png
│ │ │ │ ├── link.png
│ │ │ │ ├── music.png
│ │ │ │ ├── torrent.png
│ │ │ │ └── ic_folder_icon.png
│ │ │ ├── drawable-hdpi
│ │ │ │ ├── ic_check_black_18dp.png
│ │ │ │ ├── ic_check_black_24dp.png
│ │ │ │ ├── ic_check_black_36dp.png
│ │ │ │ ├── ic_check_black_48dp.png
│ │ │ │ ├── ic_check_white_18dp.png
│ │ │ │ ├── ic_check_white_24dp.png
│ │ │ │ ├── ic_check_white_36dp.png
│ │ │ │ ├── ic_check_white_48dp.png
│ │ │ │ ├── ic_check_grey600_18dp.png
│ │ │ │ ├── ic_check_grey600_24dp.png
│ │ │ │ ├── ic_check_grey600_36dp.png
│ │ │ │ ├── ic_check_grey600_48dp.png
│ │ │ │ ├── ic_chevron_left_black_18dp.png
│ │ │ │ ├── ic_chevron_left_black_24dp.png
│ │ │ │ ├── ic_chevron_left_black_36dp.png
│ │ │ │ ├── ic_chevron_left_black_48dp.png
│ │ │ │ ├── ic_chevron_left_white_18dp.png
│ │ │ │ ├── ic_chevron_left_white_24dp.png
│ │ │ │ ├── ic_chevron_left_white_36dp.png
│ │ │ │ ├── ic_chevron_left_white_48dp.png
│ │ │ │ ├── ic_chevron_left_grey600_18dp.png
│ │ │ │ ├── ic_chevron_left_grey600_24dp.png
│ │ │ │ ├── ic_chevron_left_grey600_36dp.png
│ │ │ │ └── ic_chevron_left_grey600_48dp.png
│ │ │ ├── drawable-mdpi
│ │ │ │ ├── ic_check_black_18dp.png
│ │ │ │ ├── ic_check_black_24dp.png
│ │ │ │ ├── ic_check_black_36dp.png
│ │ │ │ ├── ic_check_black_48dp.png
│ │ │ │ ├── ic_check_white_18dp.png
│ │ │ │ ├── ic_check_white_24dp.png
│ │ │ │ ├── ic_check_white_36dp.png
│ │ │ │ ├── ic_check_white_48dp.png
│ │ │ │ ├── ic_check_grey600_18dp.png
│ │ │ │ ├── ic_check_grey600_24dp.png
│ │ │ │ ├── ic_check_grey600_36dp.png
│ │ │ │ ├── ic_check_grey600_48dp.png
│ │ │ │ ├── ic_chevron_left_black_18dp.png
│ │ │ │ ├── ic_chevron_left_black_24dp.png
│ │ │ │ ├── ic_chevron_left_black_36dp.png
│ │ │ │ ├── ic_chevron_left_black_48dp.png
│ │ │ │ ├── ic_chevron_left_white_18dp.png
│ │ │ │ ├── ic_chevron_left_white_24dp.png
│ │ │ │ ├── ic_chevron_left_white_36dp.png
│ │ │ │ ├── ic_chevron_left_white_48dp.png
│ │ │ │ ├── ic_chevron_left_grey600_18dp.png
│ │ │ │ ├── ic_chevron_left_grey600_24dp.png
│ │ │ │ ├── ic_chevron_left_grey600_36dp.png
│ │ │ │ └── ic_chevron_left_grey600_48dp.png
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── ic_check_black_18dp.png
│ │ │ │ ├── ic_check_black_24dp.png
│ │ │ │ ├── ic_check_black_36dp.png
│ │ │ │ ├── ic_check_black_48dp.png
│ │ │ │ ├── ic_check_grey600_18dp.png
│ │ │ │ ├── ic_check_grey600_24dp.png
│ │ │ │ ├── ic_check_grey600_36dp.png
│ │ │ │ ├── ic_check_grey600_48dp.png
│ │ │ │ ├── ic_check_white_18dp.png
│ │ │ │ ├── ic_check_white_24dp.png
│ │ │ │ ├── ic_check_white_36dp.png
│ │ │ │ ├── ic_check_white_48dp.png
│ │ │ │ ├── ic_chevron_left_black_18dp.png
│ │ │ │ ├── ic_chevron_left_black_24dp.png
│ │ │ │ ├── ic_chevron_left_black_36dp.png
│ │ │ │ ├── ic_chevron_left_black_48dp.png
│ │ │ │ ├── ic_chevron_left_white_18dp.png
│ │ │ │ ├── ic_chevron_left_white_24dp.png
│ │ │ │ ├── ic_chevron_left_white_36dp.png
│ │ │ │ ├── ic_chevron_left_white_48dp.png
│ │ │ │ ├── ic_chevron_left_grey600_18dp.png
│ │ │ │ ├── ic_chevron_left_grey600_24dp.png
│ │ │ │ ├── ic_chevron_left_grey600_36dp.png
│ │ │ │ └── ic_chevron_left_grey600_48dp.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ ├── ic_check_black_18dp.png
│ │ │ │ ├── ic_check_black_24dp.png
│ │ │ │ ├── ic_check_black_36dp.png
│ │ │ │ ├── ic_check_black_48dp.png
│ │ │ │ ├── ic_check_white_18dp.png
│ │ │ │ ├── ic_check_white_24dp.png
│ │ │ │ ├── ic_check_white_36dp.png
│ │ │ │ ├── ic_check_white_48dp.png
│ │ │ │ ├── ic_check_grey600_18dp.png
│ │ │ │ ├── ic_check_grey600_24dp.png
│ │ │ │ ├── ic_check_grey600_36dp.png
│ │ │ │ ├── ic_check_grey600_48dp.png
│ │ │ │ ├── ic_chevron_left_black_18dp.png
│ │ │ │ ├── ic_chevron_left_black_24dp.png
│ │ │ │ ├── ic_chevron_left_black_36dp.png
│ │ │ │ ├── ic_chevron_left_black_48dp.png
│ │ │ │ ├── ic_chevron_left_white_18dp.png
│ │ │ │ ├── ic_chevron_left_white_24dp.png
│ │ │ │ ├── ic_chevron_left_white_36dp.png
│ │ │ │ ├── ic_chevron_left_white_48dp.png
│ │ │ │ ├── ic_chevron_left_grey600_18dp.png
│ │ │ │ ├── ic_chevron_left_grey600_24dp.png
│ │ │ │ ├── ic_chevron_left_grey600_36dp.png
│ │ │ │ └── ic_chevron_left_grey600_48dp.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ │ ├── ic_check_black_18dp.png
│ │ │ │ ├── ic_check_black_24dp.png
│ │ │ │ ├── ic_check_black_36dp.png
│ │ │ │ ├── ic_check_black_48dp.png
│ │ │ │ ├── ic_check_white_18dp.png
│ │ │ │ ├── ic_check_white_24dp.png
│ │ │ │ ├── ic_check_white_36dp.png
│ │ │ │ ├── ic_check_white_48dp.png
│ │ │ │ ├── ic_check_grey600_18dp.png
│ │ │ │ ├── ic_check_grey600_24dp.png
│ │ │ │ ├── ic_check_grey600_36dp.png
│ │ │ │ ├── ic_check_grey600_48dp.png
│ │ │ │ ├── ic_chevron_left_black_18dp.png
│ │ │ │ ├── ic_chevron_left_black_24dp.png
│ │ │ │ ├── ic_chevron_left_black_36dp.png
│ │ │ │ ├── ic_chevron_left_black_48dp.png
│ │ │ │ ├── ic_chevron_left_white_18dp.png
│ │ │ │ ├── ic_chevron_left_white_24dp.png
│ │ │ │ ├── ic_chevron_left_white_36dp.png
│ │ │ │ ├── ic_chevron_left_white_48dp.png
│ │ │ │ ├── ic_chevron_left_grey600_18dp.png
│ │ │ │ ├── ic_chevron_left_grey600_24dp.png
│ │ │ │ ├── ic_chevron_left_grey600_36dp.png
│ │ │ │ └── ic_chevron_left_grey600_48dp.png
│ │ │ ├── animator
│ │ │ │ ├── rotation.xml
│ │ │ │ └── rotation_reverse.xml
│ │ │ ├── drawable
│ │ │ │ ├── path_layout_bg.xml
│ │ │ │ ├── divider.xml
│ │ │ │ └── plus.xml
│ │ │ ├── drawable-v21
│ │ │ │ ├── drawable_plus_to_close.xml
│ │ │ │ ├── drawable_close_to_plus.xml
│ │ │ │ └── ripple.xml
│ │ │ ├── layout-v21
│ │ │ │ └── layout_new_folder_iv.xml
│ │ │ ├── anim
│ │ │ │ ├── anim_multiple_button.xml
│ │ │ │ ├── anim_multiple_button_end.xml
│ │ │ │ ├── anim_new_folder_view.xml
│ │ │ │ ├── anim_close_folder_view.xml
│ │ │ │ └── anim_address_bar.xml
│ │ │ ├── layout
│ │ │ │ ├── layout_new_folder_iv.xml
│ │ │ │ ├── row_paths.xml
│ │ │ │ ├── row_storage.xml
│ │ │ │ ├── row_custom_paths.xml
│ │ │ │ └── storage_list.xml
│ │ │ ├── values-night
│ │ │ │ └── colors.xml
│ │ │ └── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── colors.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── codekidlabs
│ │ │ └── storagechooser
│ │ │ ├── exceptions
│ │ │ └── MemoryNotAccessibleException.java
│ │ │ ├── utils
│ │ │ ├── ResourceUtil.java
│ │ │ ├── FileUtil.java
│ │ │ ├── DiskUtil.java
│ │ │ ├── MemoryUtil.java
│ │ │ └── ThumbnailUtil.java
│ │ │ ├── animators
│ │ │ └── MemorybarAnimation.java
│ │ │ ├── models
│ │ │ └── Storages.java
│ │ │ ├── Content.java
│ │ │ └── adapters
│ │ │ └── SecondaryChooserAdapter.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── codekidlabs
│ │ │ └── storagechooser
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── codekidlabs
│ │ └── storagechooser
│ │ └── ExampleInstrumentedTest.java
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── proguard-rules.pro
├── build.gradle
└── gradlew.bat
├── app
├── src
│ ├── main
│ │ ├── .gitignore
│ │ ├── ic_launcher-web.png
│ │ ├── res
│ │ │ ├── drawable
│ │ │ │ ├── run.png
│ │ │ │ ├── use.png
│ │ │ │ ├── jump.png
│ │ │ │ ├── load.png
│ │ │ │ ├── mouse.png
│ │ │ │ ├── pause.png
│ │ │ │ ├── save.png
│ │ │ │ ├── sneak.png
│ │ │ │ ├── wait.png
│ │ │ │ ├── attack.png
│ │ │ │ ├── journal.png
│ │ │ │ ├── keyboard.png
│ │ │ │ ├── toggle.png
│ │ │ │ ├── inventory.png
│ │ │ │ ├── pointer_arrow.png
│ │ │ │ ├── third_person.png
│ │ │ │ ├── toggle_magic.png
│ │ │ │ ├── toggle_weapon.png
│ │ │ │ ├── ic_drag_handle_black_24dp.xml
│ │ │ │ └── load.xml
│ │ │ ├── values
│ │ │ │ ├── themes.xml
│ │ │ │ └── styles.xml
│ │ │ ├── menu
│ │ │ │ └── menu_settings.xml
│ │ │ ├── layout
│ │ │ │ ├── mod_item.xml
│ │ │ │ ├── main.xml
│ │ │ │ ├── activity_mods.xml
│ │ │ │ └── configure_controls.xml
│ │ │ └── xml
│ │ │ │ └── settings.xml
│ │ ├── java
│ │ │ ├── utils
│ │ │ │ ├── BugsnagApiKey.kt
│ │ │ │ ├── Utils.kt
│ │ │ │ └── MyApp.kt
│ │ │ ├── org
│ │ │ │ └── libsdl
│ │ │ │ │ └── app
│ │ │ │ │ ├── HIDDevice.java
│ │ │ │ │ └── SDL.java
│ │ │ ├── parser
│ │ │ │ └── CommandlineParser.kt
│ │ │ ├── ui
│ │ │ │ ├── controls
│ │ │ │ │ ├── GamepadEmulator.kt
│ │ │ │ │ ├── JoystickLeft.kt
│ │ │ │ │ ├── JoystickRight.kt
│ │ │ │ │ ├── ButtonTouchListener.kt
│ │ │ │ │ ├── OscAttackButton.kt
│ │ │ │ │ └── Joystick.kt
│ │ │ │ └── activity
│ │ │ │ │ ├── ModsActivity.kt
│ │ │ │ │ └── ConfigureControls.kt
│ │ │ ├── permission
│ │ │ │ └── PermissionHelper.kt
│ │ │ ├── mods
│ │ │ │ ├── ModsDatabase.kt
│ │ │ │ ├── Mod.kt
│ │ │ │ ├── ModMoveCallback.kt
│ │ │ │ └── ModsAdapter.kt
│ │ │ ├── file
│ │ │ │ ├── Writer.kt
│ │ │ │ ├── utils
│ │ │ │ │ └── CopyFilesFromAssets.kt
│ │ │ │ ├── IniConverter.kt
│ │ │ │ └── GameInstaller.kt
│ │ │ ├── constants
│ │ │ │ └── Constants.kt
│ │ │ └── cursor
│ │ │ │ └── MouseCursor.kt
│ │ ├── gdb.sh
│ │ └── AndroidManifest.xml
│ ├── nightly
│ │ ├── ic_launcher-web.png
│ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── values
│ │ │ ├── strings.xml
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── colors.xml
│ │ │ └── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ ├── mainline
│ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ ├── ic_launcher_round.png
│ │ │ └── ic_launcher_foreground.png
│ │ │ ├── values
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── colors.xml
│ │ │ └── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ ├── debug
│ │ └── res
│ │ │ └── values
│ │ │ └── strings.xml
│ └── test
│ │ └── java
│ │ └── file
│ │ └── IniConverterTest.kt
├── openmw.base.cfg
├── lint.xml
└── build.gradle
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ └── bug_report.md
└── workflows
│ └── main.yml
├── settings.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradlew.bat
└── README.md
/storagechooser/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/src/main/.gitignore:
--------------------------------------------------------------------------------
1 | gdb.exec
2 | jni
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':storagechooser'
3 |
--------------------------------------------------------------------------------
/app/openmw.base.cfg:
--------------------------------------------------------------------------------
1 | no-sound=0
2 | encoding=win1252
3 | data="specify-me!"
4 |
--------------------------------------------------------------------------------
/storagechooser/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | android.enableJetifier=true
2 | android.useAndroidX=true
3 | org.gradle.jvmargs=-Xmx16384m
4 |
--------------------------------------------------------------------------------
/app/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/run.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/run.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/use.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/use.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/drawable/jump.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/jump.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/load.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/load.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/mouse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/mouse.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/pause.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/save.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sneak.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/sneak.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/wait.png
--------------------------------------------------------------------------------
/app/src/nightly/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/ic_launcher-web.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/attack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/attack.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/journal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/journal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/keyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/keyboard.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/toggle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/toggle.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/inventory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/inventory.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/pointer_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/pointer_arrow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/third_person.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/third_person.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/toggle_magic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/toggle_magic.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/toggle_weapon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/main/res/drawable/toggle_weapon.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/storagechooser/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/apk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/apk.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/doc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/doc.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/mov.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/mov.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/pdf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/pdf.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/pic.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/web.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/zip.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/excel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/excel.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/font.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/font.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/link.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/music.png
--------------------------------------------------------------------------------
/app/src/debug/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | OMW (Debug)
4 |
5 |
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/nightly/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | OMW Nightly
4 |
5 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/torrent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/torrent.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/mainline/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/app/src/nightly/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-nodpi/ic_folder_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-nodpi/ic_folder_icon.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_white_48dp.png
--------------------------------------------------------------------------------
/app/src/mainline/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #373737
4 |
5 |
--------------------------------------------------------------------------------
/app/src/nightly/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #373737
4 |
5 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_check_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_check_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_check_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_check_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_check_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-hdpi/ic_chevron_left_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-mdpi/ic_chevron_left_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xhdpi/ic_chevron_left_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_black_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_white_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxhdpi/ic_chevron_left_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_18dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_18dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_24dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_36dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_48dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SCARaw/Android-OpenMW/HEAD/storagechooser/src/main/res/drawable-xxxhdpi/ic_chevron_left_grey600_48dp.png
--------------------------------------------------------------------------------
/storagechooser/src/main/res/animator/rotation.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build
3 | jniLibs
4 | .idea
5 | local.properties
6 | *.iml
7 | obj
8 | assets
9 | .gdb_history
10 | app/wrap
11 | fabric.properties
12 | captures
13 | *.apk
14 | output.json
15 | .ccls-cache
16 | app/nightly
17 | app/mainline
18 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/animator/rotation_reverse.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/mainline/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2196F3
4 | #1976D2
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/nightly/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #00002A
4 | #000000
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable/path_layout_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun Aug 30 17:32:13 EDT 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/storagechooser/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-v21/drawable_plus_to_close.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-v21/drawable_close_to_plus.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable-v21/ripple.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/mainline/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/nightly/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/exceptions/MemoryNotAccessibleException.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.exceptions;
2 |
3 |
4 | public class MemoryNotAccessibleException extends Exception {
5 |
6 | public MemoryNotAccessibleException(String message) {
7 | super(message);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable/divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/layout-v21/layout_new_folder_iv.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/anim/anim_multiple_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_drag_handle_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/anim/anim_multiple_button_end.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/anim/anim_new_folder_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/anim/anim_close_folder_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/layout/layout_new_folder_iv.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/java/utils/BugsnagApiKey.kt:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | /**
4 | * This provides a global access to bugsnag api key.
5 | * To enable crash reporting, put a valid bugsnag api key here.
6 | * And mark this file as unchanged in git tree with:
7 | * git update-index --assume-unchanged BugsnagApiKey.kt
8 | */
9 | object BugsnagApiKey {
10 | // Put your Bugsnag API key here to enable crash reporting
11 | const val API_KEY = ""
12 | }
13 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/layout/row_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/anim/anim_address_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
15 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2196F3
4 | #1976D2
5 | #FBC02D
6 |
7 | #de6565
8 | #7bde65
9 | #c14b84
10 | #6b3fa1
11 | #3fa19f
12 |
13 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/drawable/plus.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
11 |
14 |
15 |
--------------------------------------------------------------------------------
/storagechooser/src/test/java/com/codekidlabs/storagechooser/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.assertEquals;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/load.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Storage Chooser
3 | Choose Storage
4 | Choose External Storage
5 |
6 | External storage
7 |
8 | USB storage
9 | %1$s free
10 | %1$s is not sufficient for current operation. Please clear out some space.
11 | The storage you have chosen is not accessible.
12 |
13 |
--------------------------------------------------------------------------------
/storagechooser/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Users\Home\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/java/org/libsdl/app/HIDDevice.java:
--------------------------------------------------------------------------------
1 | package org.libsdl.app;
2 |
3 | import android.hardware.usb.UsbDevice;
4 |
5 | interface HIDDevice
6 | {
7 | public int getId();
8 | public int getVendorId();
9 | public int getProductId();
10 | public String getSerialNumber();
11 | public int getVersion();
12 | public String getManufacturerName();
13 | public String getProductName();
14 | public UsbDevice getDevice();
15 | public boolean open();
16 | public int sendFeatureReport(byte[] report);
17 | public int sendOutputReport(byte[] report);
18 | public boolean getFeatureReport(byte[] report);
19 | public void setFrozen(boolean frozen);
20 | public void close();
21 | public void shutdown();
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/gdb.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 | cd $DIR
6 |
7 | # first argument: arch of the executable used (you have to figure it out yourself!)
8 | ARCH=${1:-arm}
9 | source ../../../buildscripts/include/version.sh
10 |
11 | # set up fake "jni" so that ndk-gdb can find a "valid" Android.mk
12 | rm -rf jni && mkdir jni
13 | echo "APP_ABI := $ABI" > jni/Android.mk
14 |
15 | rm -f gdb.exec
16 | echo "shell rm -rf jni" >> gdb.exec
17 | echo "set solib-search-path ../../../buildscripts/symbols/$ABI/" >> gdb.exec
18 | echo "set history save on" >> gdb.exec
19 | echo "set breakpoint pending on" >> gdb.exec
20 |
21 | ../../../buildscripts/toolchain/ndk/ndk-gdb --attach is.xyz.omw_nightly.debug -x "gdb.exec"
22 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/utils/ResourceUtil.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.utils;
2 |
3 |
4 | import android.content.Context;
5 | import androidx.core.content.ContextCompat;
6 | import androidx.core.graphics.ColorUtils;
7 |
8 | import com.codekidlabs.storagechooser.R;
9 |
10 | public class ResourceUtil {
11 |
12 | private Context context;
13 |
14 | public ResourceUtil(Context context) {
15 | this.context = context;
16 | }
17 |
18 | public int getColor(int id) {
19 | return ContextCompat.getColor(context, id);
20 | }
21 |
22 | public int getAppliedAlpha(int color) {
23 | return ColorUtils.setAlphaComponent(color, 50);
24 | }
25 |
26 | public int getPrimaryColorWithAlpha() {
27 | return getAppliedAlpha(getColor(R.color.colorPrimary));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Smartphone (please complete the following information):**
27 | - Device: [e.g. Google Pixel]
28 | - OS: [e.g. Android 9]
29 | - Version: [e.g. 22]
30 | - App source: [e.g. Github, Google Play store, F-Droid, self-built]
31 |
32 | **Additional context**
33 | Add any other context about the problem here.
34 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_settings.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/storagechooser/src/androidTest/java/com/codekidlabs/storagechooser/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.assertEquals;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.codekidlabs.storagechooser.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/animators/MemorybarAnimation.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.animators;
2 |
3 | import android.view.animation.Animation;
4 | import android.view.animation.Transformation;
5 | import android.widget.ProgressBar;
6 |
7 | /**
8 | * display a nice animation when chooser dialog is shown
9 | */
10 |
11 | public class MemorybarAnimation extends Animation {
12 |
13 | private ProgressBar progressBar;
14 | private float from;
15 | private float to;
16 |
17 |
18 | public MemorybarAnimation(ProgressBar progressBar, int from, int to) {
19 | this.progressBar = progressBar;
20 | this.from = from;
21 | this.to = to;
22 | }
23 |
24 | @Override
25 | protected void applyTransformation(float interpolatedTime, Transformation t) {
26 | super.applyTransformation(interpolatedTime, t);
27 | float animatedProgress = from + (to - from) * interpolatedTime;
28 | progressBar.setProgress((int) animatedProgress);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/layout/row_storage.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
19 |
20 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/layout/row_custom_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
16 |
17 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
9 |
10 |
13 |
14 |
20 |
21 |
24 |
25 |
29 |
30 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/models/Storages.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.models;
2 |
3 | /**
4 | * A model that is used as the element to store any data regarding storage volumes/disks
5 | */
6 | public class Storages {
7 |
8 | String storageTitle;
9 | String storagePath;
10 | String memoryTotalSize;
11 | String memoryAvailableSize;
12 |
13 |
14 | public String getStorageTitle() {
15 | return storageTitle;
16 | }
17 |
18 | public void setStorageTitle(String storageTitle) {
19 | this.storageTitle = storageTitle;
20 | }
21 |
22 | public String getStoragePath() {
23 | return storagePath;
24 | }
25 |
26 | public void setStoragePath(String storagePath) {
27 | this.storagePath = storagePath;
28 | }
29 |
30 | public String getMemoryTotalSize() {
31 | return memoryTotalSize;
32 | }
33 |
34 | public void setMemoryTotalSize(String memoryTotalSize) {
35 | this.memoryTotalSize = memoryTotalSize;
36 | }
37 |
38 | public String getMemoryAvailableSize() {
39 | return memoryAvailableSize;
40 | }
41 |
42 | public void setMemoryAvailableSize(String memoryAvailableSize) {
43 | this.memoryAvailableSize = memoryAvailableSize;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/mod_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
30 |
31 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
16 |
17 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/java/utils/Utils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2017 sandstranger
3 | Copyright (C) 2018, 2019 Ilya Zhuravlev
4 |
5 | This file is part of OpenMW-Android.
6 |
7 | OpenMW-Android is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | OpenMW-Android is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with OpenMW-Android. If not, see .
19 | */
20 |
21 | package utils
22 |
23 | import android.app.Activity
24 | import android.view.View
25 |
26 | object Utils {
27 | fun hideAndroidControls(activity: Activity) {
28 | activity.window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
29 | or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
30 | or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
31 | or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
32 | or View.SYSTEM_UI_FLAG_FULLSCREEN
33 | or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/parser/CommandlineParser.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2016 sandstranger
3 | Copyright (C) 2018 Ilya Zhuravlev
4 |
5 | This file is part of OpenMW-Android.
6 |
7 | OpenMW-Android is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | OpenMW-Android is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with OpenMW-Android. If not, see .
19 | */
20 |
21 | package parser
22 |
23 | import java.util.ArrayList
24 | import java.util.Collections
25 |
26 | class CommandlineParser(data: String) {
27 | private val args = ArrayList()
28 | val argv: Array
29 |
30 | val argc: Int
31 | get() = args.size
32 |
33 | init {
34 | args.clear()
35 | args.add("openmw")
36 | if (data.contains("--")) {
37 | Collections.addAll(args, *data.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
38 | }
39 | argv = args.toTypedArray()
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/test/java/file/IniConverterTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package file
21 |
22 | import org.junit.Test
23 |
24 | import org.junit.Assert.*
25 |
26 | class IniConverterTest {
27 |
28 | @Test
29 | fun convertSimple() {
30 | val ini = IniConverter("""
31 | [Something]
32 | ; A comment
33 | ; Another comment
34 | Long key with spaces=Some value also with spaces
35 |
36 | [Another thing]
37 | First=Value
38 | This ones empty=
39 | Second=Another value
40 | """.trimIndent())
41 | val res = ini.convert()
42 | assertEquals(
43 | "fallback=Something_Long_key_with_spaces,Some value also with spaces\n" +
44 | "fallback=Another_thing_First,Value\n" +
45 | "fallback=Another_thing_Second,Another value\n",
46 | res)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/storagechooser/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | group = 'com.github.codekidX'
4 |
5 | android {
6 | compileSdkVersion 28
7 |
8 | defaultConfig {
9 | minSdkVersion 16
10 | targetSdkVersion 28
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
15 |
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 |
24 | android.defaultConfig.vectorDrawables.useSupportLibrary = true
25 | }
26 |
27 | dependencies {
28 | implementation fileTree(dir: 'libs', include: ['*.jar'])
29 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0-alpha4', {
30 | exclude group: 'com.android.support', module: 'support-annotations'
31 | })
32 | implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
33 | implementation 'com.google.android.material:material:1.0.0-beta01'
34 | testImplementation 'junit:junit:4.12'
35 | }
36 |
37 | task javadoc(type: Javadoc) {
38 | failOnError false
39 | source = android.sourceSets.main.java.sourceFiles
40 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
41 | classpath += configurations.compile
42 | }
43 |
44 | // build a jar with javadoc
45 | task javadocJar(type: Jar, dependsOn: javadoc) {
46 | classifier = 'javadoc'
47 | from javadoc.destinationDir
48 | }
49 |
50 | artifacts {
51 | archives javadocJar
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/controls/GamepadEmulator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2018, 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package ui.controls
21 |
22 | import org.libsdl.app.SDLControllerManager
23 |
24 | internal object GamepadEmulator {
25 |
26 | private var registered = false
27 |
28 | fun updateStick(stickId: Int, x: Float, y: Float) {
29 | // random device ID to make sure it doesn't conflict with anything
30 | val deviceId = 1384510555
31 |
32 | if (!registered) {
33 | registered = true
34 | SDLControllerManager.nativeAddJoystick(deviceId, "Virtual", "Virtual",
35 | 0xbad, 0xf00d,
36 | false, -0x1,
37 | 4, 0, 0)
38 | }
39 |
40 | SDLControllerManager.onNativeJoy(deviceId, stickId * 2, x)
41 | SDLControllerManager.onNativeJoy(deviceId, stickId * 2 + 1, y)
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/layout/storage_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
30 |
31 |
32 |
33 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/java/permission/PermissionHelper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2016 sandstranger
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package permission
21 |
22 | import android.Manifest
23 | import android.app.Activity
24 | import android.content.pm.PackageManager
25 | import android.os.Build
26 | import androidx.core.app.ActivityCompat
27 | import androidx.core.content.ContextCompat
28 |
29 | object PermissionHelper {
30 | fun getWriteExternalStoragePermission(activity: Activity) {
31 | if (Build.VERSION.SDK_INT >= 23) {
32 | if (ContextCompat.checkSelfPermission(activity,
33 | Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
34 | if (!ActivityCompat.shouldShowRequestPermissionRationale(activity,
35 | Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
36 | ActivityCompat.requestPermissions(activity,
37 | arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 23
38 | )
39 | }
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
16 |
17 |
21 |
22 |
25 |
26 |
33 |
34 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/java/mods/ModsDatabase.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package mods
21 |
22 | import android.content.Context
23 | import android.database.sqlite.SQLiteDatabase
24 | import org.jetbrains.anko.db.*
25 |
26 | class ModsDatabaseOpenHelper private constructor(ctx: Context)
27 | : ManagedSQLiteOpenHelper(ctx, "ModsDatabase", null, 1) {
28 |
29 | init {
30 | instance = this
31 | }
32 |
33 | companion object {
34 | private var instance: ModsDatabaseOpenHelper? = null
35 |
36 | @Synchronized
37 | fun getInstance(ctx: Context) = instance ?: ModsDatabaseOpenHelper(ctx.applicationContext)
38 | }
39 |
40 | override fun onCreate(db: SQLiteDatabase) {
41 | db.createTable("mod", true,
42 | "type" to INTEGER,
43 | "filename" to TEXT,
44 | "load_order" to INTEGER,
45 | "enabled" to INTEGER)
46 | db.createIndex("mod_type", "mod", false, true,
47 | "type")
48 | db.createIndex("mod_filename", "mod", false, true,
49 | "filename")
50 | db.createIndex("mod_type_name", "mod", true, true,
51 | "type", "filename")
52 | }
53 |
54 | override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
55 | }
56 | }
57 |
58 | // Access property for Context
59 | val Context.database: ModsDatabaseOpenHelper
60 | get() = ModsDatabaseOpenHelper.getInstance(this)
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_mods.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
24 |
25 |
29 |
30 |
34 |
35 |
36 |
40 |
41 |
45 |
46 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
18 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
39 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 | strategy:
8 | matrix:
9 | arch: [arm, arm64, x86, x86_64]
10 |
11 | runs-on: ubuntu-18.04
12 |
13 | env:
14 | CMAKE_VERSION: 3.18.4
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 |
19 | - name: Install dependencies
20 | run: |
21 | sudo apt-get install -y build-essential gcc-multilib python unzip pkg-config p7zip-full
22 | cd /home/runner/
23 | wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz
24 | tar xvf cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz
25 |
26 | - name: Build native libraries
27 | run: |
28 | export PATH=/home/runner/cmake-$CMAKE_VERSION-Linux-x86_64/bin/:$PATH
29 | cd buildscripts
30 | ./build.sh --arch ${{ matrix.arch }}
31 |
32 | - name: Build the APK
33 | run: |
34 | ARCH=${{ matrix.arch }} source buildscripts/include/version.sh
35 | sed -i "s/abiFilters.*/abiFilters '$ABI'/" app/build.gradle
36 | export ANDROID_NDK_HOME=$(pwd)/buildscripts/toolchain/ndk/
37 | ./gradlew assembleNightlyDebug
38 |
39 | - name: Compress symbols
40 | run: |
41 | cd buildscripts
42 | ./package-symbols.sh
43 | mv symbols.7z ../symbols-$(git rev-parse --short "$GITHUB_SHA")-${{ matrix.arch }}.7z
44 |
45 | - name: Collect outputs
46 | id: getfilename
47 | run: |
48 | mv app/build/outputs/apk/nightly/debug/omw_debug_*.apk omw-debug-$(git rev-parse --short "$GITHUB_SHA")-${{ matrix.arch }}.apk
49 | echo "::set-output name=apk_file::$(ls omw-debug-*.apk | sed 's/\(.*\)\..*/\1/')"
50 | echo "::set-output name=symbols_file::$(ls symbols-*.7z | sed 's/\(.*\)\..*/\1/')"
51 |
52 | - name: Upload the APK
53 | uses: actions/upload-artifact@v1
54 | with:
55 | name: ${{ steps.getfilename.outputs.apk_file }}
56 | path: ${{ steps.getfilename.outputs.apk_file }}.apk
57 |
58 | - name: Upload debug symbols
59 | uses: actions/upload-artifact@v1
60 | with:
61 | name: ${{ steps.getfilename.outputs.symbols_file }}
62 | path: ${{ steps.getfilename.outputs.symbols_file }}.7z
63 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/controls/JoystickLeft.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2018, 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package ui.controls
21 |
22 | import android.content.Context
23 | import androidx.core.math.MathUtils
24 | import android.util.AttributeSet
25 |
26 | class JoystickLeft : Joystick {
27 |
28 | constructor(context: Context) : super(context)
29 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
30 | constructor(context: Context, attrs: AttributeSet, defStyle: Int)
31 | : super(context, attrs, defStyle)
32 |
33 | override fun updateStick() {
34 | if (down) {
35 | // GamepadEmulator takes values on a scale [-1; 1] so convert our values
36 | val w = (width / 3).toFloat()
37 | var diffX = currentX - initialX
38 | var diffY = currentY - initialY
39 |
40 | val bias = 0.3f
41 |
42 | if (Math.abs(diffX) > Math.abs(diffY)) {
43 | diffY = Math.signum(diffY) * Math.max(0f, Math.abs(diffY) - bias * Math.abs(diffX))
44 | } else {
45 | diffX = Math.signum(diffX) * Math.max(0f, Math.abs(diffX) - bias * Math.abs(diffY))
46 | }
47 |
48 | val dx = MathUtils.clamp(diffX / w + 0.2f * Math.signum(diffX), -1f, 1f)
49 | val dy = MathUtils.clamp(diffY / w + 0.2f * Math.signum(diffY), -1f, 1f)
50 | GamepadEmulator.updateStick(stickId, dx, dy)
51 | } else {
52 | GamepadEmulator.updateStick(stickId, 0f, 0f)
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'com.bugsnag.android.gradle'
5 |
6 | ext {
7 | versionFile = new File(project.rootDir, 'app/src/main/assets/libopenmw/resources/version')
8 | calculateVersion = {
9 | stream = new FileInputStream(versionFile)
10 | return stream.readLines()[0].trim() + "-" + project.android.defaultConfig.versionCode.toString()
11 | }
12 | }
13 |
14 | android {
15 | compileSdkVersion 29
16 |
17 | sourceSets {
18 | main {
19 | resources {
20 | srcDir {
21 | "wrap/res"
22 | }
23 | }
24 | }
25 | }
26 |
27 | defaultConfig {
28 | applicationId "is.docent27.omw"
29 | versionCode 47
30 | versionName "0.47"
31 | minSdkVersion 21
32 | targetSdkVersion 29
33 |
34 | ndk {
35 | abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"
36 | }
37 | }
38 |
39 | lintOptions {
40 | checkReleaseBuilds false
41 | }
42 |
43 | compileOptions {
44 | targetCompatibility 1.8
45 | sourceCompatibility 1.8
46 | }
47 |
48 | buildTypes {
49 | release {
50 | minifyEnabled false
51 | }
52 |
53 | debug {
54 | debuggable false
55 | }
56 | }
57 |
58 | flavorDimensions "version"
59 | productFlavors {
60 | mainline {
61 | dimension "version"
62 | }
63 |
64 | nightly {
65 | dimension "version"
66 | }
67 | }
68 |
69 | applicationVariants.all { variant ->
70 | variant.outputs.all {
71 | outputFileName = "omw_${variant.buildType.name}_${defaultConfig.versionName}.apk"
72 | }
73 | }
74 | }
75 |
76 | dependencies {
77 | implementation 'androidx.appcompat:appcompat:1.3.1'
78 | implementation 'com.google.android.material:material:1.4.0'
79 | implementation 'androidx.recyclerview:recyclerview:1.2.1'
80 | implementation project(':storagechooser')
81 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
82 | implementation "org.jetbrains.anko:anko-sqlite:$anko_version"
83 | implementation 'com.bugsnag:bugsnag-android-ndk:4.+'
84 | testImplementation 'junit:junit:4.13.2'
85 | }
86 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/utils/FileUtil.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileFilter;
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | /**
9 | * manages each and everything related to file api
10 | */
11 |
12 | public class FileUtil {
13 |
14 | public static boolean createDirectory(String name, String path) {
15 | File dir = new File(path + "/" + name);
16 | return dir.mkdirs();
17 | }
18 |
19 | public static boolean isDir(String path) {
20 | return new File(path).isDirectory();
21 | }
22 |
23 | public File[] listFilesAsDir(String dirPath) {
24 | return new File(dirPath).listFiles(new FileFilter() {
25 | @Override
26 | public boolean accept(File file) {
27 | return file.isDirectory();
28 | }
29 | });
30 | }
31 |
32 | public File[] listFilesInDir(String dirPath) {
33 | return new File(dirPath).listFiles();
34 | }
35 |
36 | public String[] arrangeAscending(String[] dirNames) {
37 | Arrays.sort(dirNames);
38 | return dirNames;
39 | }
40 |
41 | /**
42 | * Removes non-operationaal directories which are either used by only the system or
43 | * not used by anyone
44 | */
45 | public void removeNonOperational(List volumeList) {
46 | // segregate the list
47 |
48 | for (int i = 0; i < volumeList.size(); i++) {
49 | String volumeName = volumeList.get(i).getName();
50 | if (volumeName.equals(MemoryUtil.SELF_DIR_NAME)) {
51 | volumeList.remove(i);
52 | }
53 | if (volumeName.equals(MemoryUtil.EMULATED_DIR_NAME)) {
54 | volumeList.remove(i);
55 | }
56 | if (volumeName.equals(MemoryUtil.EMULATED_DIR_KNOX)) {
57 | volumeList.remove(i);
58 | }
59 | if (volumeName.equals(MemoryUtil.SDCARD0_DIR_NAME)) {
60 | volumeList.remove(i);
61 | }
62 | }
63 | }
64 |
65 | public String[] fileListToStringArray(List dirNames) {
66 | String[] dirList = new String[dirNames.size()];
67 | for (int i = 0; i < dirNames.size(); i++) {
68 | dirList[i] = dirNames.get(i);
69 | }
70 | return dirList;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/file/Writer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2016 sandstranger
3 | Copyright (C) 2019 Ilya Zhuravlev
4 |
5 | This file is part of OpenMW-Android.
6 |
7 | OpenMW-Android is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | OpenMW-Android is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with OpenMW-Android. If not, see .
19 | */
20 |
21 | package file
22 |
23 | import java.io.BufferedReader
24 | import java.io.File
25 | import java.io.FileInputStream
26 | import java.io.FileWriter
27 | import java.io.IOException
28 | import java.io.InputStreamReader
29 |
30 | object Writer {
31 |
32 | /**
33 | * Replaces a key=value in config file with the new value
34 | * @param path Path to the configuration file to edit
35 | * @param key Key to replace
36 | * @param value New value to put
37 | */
38 | @Throws(IOException::class)
39 | fun write(path: String, key: String, value: String) {
40 | // Create a new empty file if it doesn't already exist
41 | val fin = File(path)
42 |
43 | fin.createNewFile()
44 |
45 | val file = FileInputStream(path)
46 | val reader = BufferedReader(InputStreamReader(file))
47 | var line: String? = reader.readLine()
48 | val builder = StringBuilder()
49 | var contains = false
50 | while (line != null) {
51 | if (line.startsWith(key) && !contains) {
52 | builder.append("$key=$value")
53 | contains = true
54 | } else
55 | builder.append(line)
56 | builder.append("\n")
57 | line = reader.readLine()
58 | }
59 | if (!contains)
60 | builder.append("$key=$value")
61 |
62 | reader.close()
63 | val writer = FileWriter(path)
64 | writer.write(builder.toString())
65 | writer.flush()
66 | writer.close()
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/controls/JoystickRight.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2018, 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package ui.controls
21 |
22 | import android.annotation.SuppressLint
23 | import android.content.Context
24 | import android.util.AttributeSet
25 | import android.view.MotionEvent
26 |
27 | import org.libsdl.app.SDLActivity
28 |
29 | class JoystickRight : Joystick {
30 |
31 | private var curX: Float = 0.toFloat()
32 | private var curY: Float = 0.toFloat()
33 |
34 | constructor(context: Context) : super(context)
35 |
36 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
37 |
38 | constructor(context: Context, attrs: AttributeSet, defStyle: Int)
39 | : super(context, attrs, defStyle)
40 |
41 | @SuppressLint("ClickableViewAccessibility")
42 | override fun onTouchEvent(event: MotionEvent): Boolean {
43 | when (event.actionMasked) {
44 | MotionEvent.ACTION_DOWN -> {
45 | curX = event.x
46 | curY = event.y
47 | }
48 | MotionEvent.ACTION_MOVE -> {
49 | val newX = event.x
50 | val newY = event.y
51 |
52 | // this isn't configurable here but configurable in openmw built-in settings
53 | val mouseScalingFactor = 900f
54 |
55 | val movementX = (newX - curX) * mouseScalingFactor / width
56 | val movementY = (newY - curY) * mouseScalingFactor / height
57 |
58 | SDLActivity.sendRelativeMouseMotion(Math.round(movementX), Math.round(movementY))
59 |
60 | curX = newX
61 | curY = newY
62 | }
63 | }
64 |
65 | return super.onTouchEvent(event)
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/constants/Constants.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2015, 2016 sandstranger
3 | Copyright (C) 2019 Ilya Zhuravlev
4 |
5 | This file is part of OpenMW-Android.
6 |
7 | OpenMW-Android is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | OpenMW-Android is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with OpenMW-Android. If not, see .
19 | */
20 |
21 | package constants
22 |
23 | object Constants {
24 | val APP_PREFERENCES = "settings"
25 | val HIDE_CONTROLS = "pref_hide_controls"
26 |
27 | // TODO: the comment below is outdated
28 | // Base path: [/sdcard]/Android/data/[com.libopenmw.openmw]/
29 | // * /sdcard - in theory, can be different, haven't seen any on modern android though
30 | // * com.libopenmw.openmw - our application id
31 | //
32 | // $base/share - savedata, shouldn't touch this
33 | // $base/resources - resource files from openmw, ok to overwrite
34 | // $base/openmw - default settings, ok to overwrite
35 | // $base/config - user settings
36 |
37 | // e.g. /sdcard/omw
38 | var USER_FILE_STORAGE = ""
39 |
40 | // e.g. /data/data/is.xyz.omw/files/config/defaults.bin
41 | var DEFAULTS_BIN = ""
42 |
43 | // e.g. /data/data/is.xyz.omw/files/config/openmw.cfg
44 | var OPENMW_CFG = ""
45 |
46 | // e.g. /data/data/is.xyz.omw/files/config/openmw.base.cfg
47 | var OPENMW_BASE_CFG = ""
48 |
49 | // e.g. /data/data/is.xyz.omw/files/config/openmw.fallback.cfg
50 | var OPENMW_FALLBACK_CFG = ""
51 |
52 | // e.g. /data/data/is.xyz.omw/files/resources
53 | var RESOURCES = ""
54 |
55 | // e.g. /data/data/is.xyz.omw/files/config
56 | var GLOBAL_CONFIG = ""
57 |
58 | // e.g. /sdcard/omw/config
59 | var USER_CONFIG = ""
60 |
61 | // e.g. /sdcard/omw/config/openmw.cfg
62 | var USER_OPENMW_CFG = ""
63 |
64 | // Contains app version code for currently deployed resources; redeployed on mismatch
65 | // e.g. /data/data/is.xyz.omw/files/stamp
66 | var VERSION_STAMP = ""
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/file/utils/CopyFilesFromAssets.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2016 sandstranger
3 | Copyright (C) 2019 Ilya Zhuravlev
4 |
5 | This file is part of OpenMW-Android.
6 |
7 | OpenMW-Android is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | OpenMW-Android is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with OpenMW-Android. If not, see .
19 | */
20 |
21 | package file.utils
22 |
23 | import java.io.File
24 | import java.io.FileOutputStream
25 | import java.io.IOException
26 |
27 | import android.content.Context
28 |
29 | /**
30 | * Helper class to handle copying assets to the storage
31 | * @param context Android context to use
32 | */
33 | class CopyFilesFromAssets(private val context: Context) {
34 |
35 | /**
36 | * Copies assets recursively
37 | * @param src Source directory in assets
38 | * @param dst Destination directory on disk, absolute path
39 | */
40 | fun copy(src: String, dst: String) {
41 | val assetManager = context.assets
42 | try {
43 | val assets = assetManager.list(src) ?: return
44 | if (assets.isEmpty()) {
45 | copyFile(src, dst)
46 | } else {
47 | // Recurse into a subdirectory
48 | val dir = File(dst)
49 | if (!dir.exists())
50 | dir.mkdirs()
51 | for (i in assets.indices) {
52 | copy(src + "/" + assets[i], dst + "/" + assets[i])
53 | }
54 | }
55 | } catch (ex: IOException) {
56 | }
57 | }
58 |
59 | /**
60 | * Copies a single file from assets to disk
61 | * @param src Path of source file inside assets
62 | * @param dst Absolute path to destination file on disk
63 | */
64 | private fun copyFile(src: String, dst: String) {
65 | try {
66 | val inp = context.assets.open(src)
67 | val out = FileOutputStream(dst)
68 |
69 | inp.copyTo(out)
70 | out.flush()
71 |
72 | inp.close()
73 | out.close()
74 | } catch (e: IOException) {
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/storagechooser/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/file/IniConverter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package file
21 |
22 | /**
23 | * Converts morrowind.ini to fallback= format
24 | * @param data Contents of morrowind.ini as a string
25 | */
26 | class IniConverter(private val data: String) {
27 |
28 | /**
29 | * Performs the actual conversion
30 | * @return String contents of the output file in openmw's fallback format
31 | */
32 | fun convert(): String {
33 | var category = ""
34 | var output = ""
35 |
36 | data
37 | // Split into lines
38 | .lines()
39 | // Trim whitespace/newlines
40 | .map { it.trim() }
41 | // Remove comments and empty lines
42 | .filter { it.isNotEmpty() && !it.startsWith(";") }
43 | .forEach {
44 | if (it.startsWith("[") && it.endsWith("]")) {
45 | // It's a category
46 | category = it.substring(1, it.length - 1).replace(" ", "_")
47 | } else if (it.contains("=")) {
48 | // It's a key-value pair
49 | val converted = convertLine(it)
50 | if (converted.isNotEmpty())
51 | output += "fallback=${category}_$converted\n"
52 | }
53 | }
54 |
55 | return output
56 | }
57 |
58 | /**
59 | * Converts a single morrowind setting line into openmw format
60 | * (replacing spaces with _ and = with ,)
61 | * @param line Line to convert
62 | * @return Converted result, note that this does not include the fallback=Category_ part
63 | */
64 | private fun convertLine(line: String): String {
65 | // key and value are separated by = in mw and by , in omw
66 | val kv = line.split("=".toRegex(), 2)
67 | val key = kv[0].replace(" ", "_")
68 | val value = kv[1]
69 |
70 | if (key.isEmpty() || value.isEmpty())
71 | return ""
72 |
73 | return "$key,$value"
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/configure_controls.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
19 |
20 |
27 |
28 |
35 |
36 |
37 |
38 |
42 |
43 |
50 |
51 |
58 |
59 |
60 |
61 |
67 |
68 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/controls/ButtonTouchListener.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2015, 2016 sandstranger
3 | Copyright (C) 2018, 2019 Ilya Zhuravlev
4 |
5 | This file is part of OpenMW-Android.
6 |
7 | OpenMW-Android is free software: you can redistribute it and/or modify
8 | it under the terms of the GNU General Public License as published by
9 | the Free Software Foundation, either version 3 of the License, or
10 | (at your option) any later version.
11 |
12 | OpenMW-Android is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | GNU General Public License for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with OpenMW-Android. If not, see .
19 | */
20 |
21 |
22 | package ui.controls
23 |
24 | import android.annotation.SuppressLint
25 | import android.view.MotionEvent
26 | import android.view.View
27 | import android.view.View.OnTouchListener
28 |
29 | import org.libsdl.app.SDLActivity
30 |
31 | class ButtonTouchListener(private val keyCode: Int, private val needEmulateMouse: Boolean) : OnTouchListener {
32 |
33 | enum class Movement {
34 | KEY_DOWN,
35 | KEY_UP,
36 | MOUSE_DOWN,
37 | MOUSE_UP
38 | }
39 |
40 | @SuppressLint("ClickableViewAccessibility")
41 | override fun onTouch(v: View, event: MotionEvent): Boolean {
42 | when (event.action) {
43 | MotionEvent.ACTION_DOWN -> {
44 | onTouchDown()
45 | return true
46 | }
47 | MotionEvent.ACTION_UP -> {
48 | onTouchUp()
49 | return true
50 | }
51 | MotionEvent.ACTION_CANCEL -> {
52 | onTouchUp()
53 | return true
54 | }
55 | }
56 | return false
57 | }
58 |
59 | private fun onTouchDown() {
60 | if (!needEmulateMouse) {
61 | eventMovement(Movement.KEY_DOWN)
62 | } else {
63 | eventMovement(Movement.MOUSE_DOWN)
64 | }
65 | }
66 |
67 | private fun onTouchUp() {
68 | if (!needEmulateMouse) {
69 | eventMovement(Movement.KEY_UP)
70 | } else {
71 | eventMovement(Movement.MOUSE_UP)
72 | }
73 | }
74 |
75 | private fun eventMovement(event: Movement) {
76 | when (event) {
77 | Movement.KEY_DOWN -> SDLActivity.onNativeKeyDown(keyCode)
78 | Movement.KEY_UP -> SDLActivity.onNativeKeyUp(keyCode)
79 | Movement.MOUSE_DOWN -> SDLActivity.sendMouseButton(1, keyCode)
80 | Movement.MOUSE_UP -> SDLActivity.sendMouseButton(0, keyCode)
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/mods/Mod.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package mods
21 |
22 | import android.database.sqlite.SQLiteDatabase
23 | import org.jetbrains.anko.db.*
24 |
25 | enum class ModType(val v: Int) {
26 | Plugin(1),
27 | Resource(2);
28 |
29 | companion object {
30 | private val reverseValues: Map = values().associate { it.v to it }
31 | fun valueFrom(i: Int): ModType = reverseValues.getValue(i)
32 | }
33 | }
34 |
35 | /**
36 | * Representation of a single mod in the database
37 | * @param type Type of the mod: plugin or resource
38 | * @param filename Filename of the mod, without the path
39 | * @param order Load order, or order in the list
40 | * @param enabled Whether the mod is enabled
41 | */
42 | class Mod(val type: ModType, val filename: String, var order: Int, var enabled: Boolean) {
43 |
44 | /// Set to true when DB update is needed to keep consistency
45 | var dirty: Boolean = false
46 |
47 | /**
48 | * Updates the representation of this mod in the database
49 | * @param db Database connection
50 | */
51 | fun update(db: SQLiteDatabase) {
52 | db.update("mod",
53 | "load_order" to order,
54 | "enabled" to enabled)
55 | .whereArgs("filename = {filename} AND type = {type}",
56 | "filename" to filename,
57 | "type" to type.v).exec()
58 | }
59 |
60 | /**
61 | * Inserts this mod into the database
62 | * @param db Database connection
63 | */
64 | fun insert(db: SQLiteDatabase) {
65 | db.insert("mod",
66 | "type" to type.v,
67 | "filename" to filename,
68 | "load_order" to order,
69 | "enabled" to (if (enabled) 1 else 0))
70 | }
71 | }
72 |
73 | class ModRowParser : RowParser {
74 | override fun parseRow(columns: Array): Mod {
75 | return Mod(
76 | ModType.valueFrom((columns[0] as Long).toInt()),
77 | columns[1] as String,
78 | (columns[2] as Long).toInt(),
79 | (columns[3] as Long) != 0L)
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/utils/DiskUtil.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.utils;
2 |
3 |
4 | import android.content.SharedPreferences;
5 | import android.os.Build;
6 | import android.os.Bundle;
7 | import android.util.Log;
8 |
9 | import com.codekidlabs.storagechooser.StorageChooser;
10 | import com.codekidlabs.storagechooser.fragments.SecondaryChooserFragment;
11 | import com.codekidlabs.storagechooser.models.Config;
12 |
13 | public class DiskUtil {
14 |
15 | public static final String IN_KB = "KiB";
16 | public static final String IN_MB = "MiB";
17 | public static final String IN_GB = "GiB";
18 | public static final String SC_PREFERENCE_KEY = "storage_chooser_path";
19 | public static java.lang.String SC_CHOOSER_FLAG = "storage_chooser_type";
20 |
21 | public static int getSdkVersion() {
22 | return Build.VERSION.SDK_INT;
23 | }
24 |
25 | public static void saveChooserPathPreference(SharedPreferences sharedPreferences, String path) {
26 | try {
27 | SharedPreferences.Editor editor = sharedPreferences.edit();
28 | editor.putString(SC_PREFERENCE_KEY, path);
29 | editor.apply();
30 | } catch (NullPointerException e) {
31 | Log.e("StorageChooser", "No sharedPreference was supplied. Supply sharedPreferencesObject via withPreference() or disable saving with actionSave(false)");
32 | }
33 | }
34 |
35 | public static boolean isLollipopAndAbove() {
36 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
37 | }
38 |
39 | /**
40 | * secondary choosers are dialogs apart from overview (CustomChooserFragment and FilePickerFragment)
41 | * Configs :-
42 | * setType()
43 | * allowCustomPath()
44 | *
45 | * @param dirPath root path(starting-point) for the secondary choosers
46 | * @param config configuration from developer
47 | */
48 |
49 | public static void showSecondaryChooser(String dirPath, Config config) {
50 |
51 | Bundle bundle = new Bundle();
52 | bundle.putString(DiskUtil.SC_PREFERENCE_KEY, dirPath);
53 |
54 | switch (config.getSecondaryAction()) {
55 | case StorageChooser.NONE:
56 | break;
57 | case StorageChooser.DIRECTORY_CHOOSER:
58 | bundle.putBoolean(DiskUtil.SC_CHOOSER_FLAG, false);
59 | SecondaryChooserFragment c = new SecondaryChooserFragment();
60 | c.setArguments(bundle);
61 | c.show(config.getFragmentManager(), "custom_chooser");
62 | break;
63 | case StorageChooser.FILE_PICKER:
64 | bundle.putBoolean(DiskUtil.SC_CHOOSER_FLAG, true);
65 | SecondaryChooserFragment f = new SecondaryChooserFragment();
66 | f.setArguments(bundle);
67 | f.show(config.getFragmentManager(), "file_picker");
68 | break;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/utils/MyApp.kt:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import android.app.Application
4 | import android.content.pm.PackageManager
5 | import android.os.Environment
6 | import android.preference.PreferenceManager
7 | import android.util.Base64
8 | import android.util.Log
9 | import com.bugsnag.android.Bugsnag
10 | import com.bugsnag.android.Configuration
11 | import com.libopenmw.openmw.BuildConfig
12 | import constants.Constants
13 | import java.io.File
14 | import java.security.MessageDigest
15 |
16 | class MyApp : Application() {
17 |
18 | var defaultScaling = 0f
19 |
20 | override fun onCreate() {
21 | app = this
22 |
23 | super.onCreate()
24 |
25 | // Set up global paths
26 | // Slug will be either omw or omw_nightly
27 | val slug = BuildConfig.APPLICATION_ID.split(".")[2]
28 | Constants.USER_FILE_STORAGE = Environment.getExternalStorageDirectory().toString() + "/$slug/"
29 | Constants.USER_CONFIG = "${Constants.USER_FILE_STORAGE}/config"
30 | Constants.USER_OPENMW_CFG = "${Constants.USER_CONFIG}/openmw.cfg"
31 | Constants.DEFAULTS_BIN = File(filesDir, "config/defaults.bin").absolutePath
32 | Constants.OPENMW_CFG = File(filesDir, "config/openmw.cfg").absolutePath
33 | Constants.OPENMW_BASE_CFG = File(filesDir, "config/openmw.base.cfg").absolutePath
34 | Constants.OPENMW_FALLBACK_CFG = File(filesDir, "config/openmw.fallback.cfg").absolutePath
35 | Constants.RESOURCES = File(filesDir, "resources").absolutePath
36 | Constants.GLOBAL_CONFIG = File(filesDir, "config").absolutePath
37 | Constants.VERSION_STAMP = File(filesDir, "stamp").absolutePath
38 |
39 | // Enable bugsnag only when API key is provided and we have user consent
40 | // Also don't enable bugsnag in debug builds
41 | if (isProductionBuild() && BugsnagApiKey.API_KEY.isNotEmpty() && !BuildConfig.DEBUG) {
42 | haveBugsnagApiKey = true
43 |
44 | val prefs = PreferenceManager.getDefaultSharedPreferences(this)
45 | if (prefs.getString("bugsnag_consent", "false")!! == "true") {
46 | val config = Configuration(BugsnagApiKey.API_KEY)
47 | config.buildUUID = ""
48 | Bugsnag.init(this, config)
49 | reportCrashes = true
50 | }
51 | }
52 | }
53 |
54 | private fun isProductionBuild(): Boolean {
55 | val sig = applicationContext.packageManager.getPackageInfo(applicationContext.packageName, PackageManager.GET_SIGNATURES).signatures[0]
56 | val digest: MessageDigest = MessageDigest.getInstance("SHA-256")
57 | val hashBytes: ByteArray = digest.digest(sig.toByteArray())
58 | val hash: String = Base64.encodeToString(hashBytes, Base64.NO_WRAP)
59 | return hash == "cOqSYH3ucLraOQ7wyg/v8UKTGHlxP8N8JTN6UXO7rV0="
60 | }
61 |
62 | companion object {
63 | var reportCrashes = false
64 | var haveBugsnagApiKey = false
65 | lateinit var app: MyApp
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/storagechooser/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #2d6c55
4 | #235644
5 | #ff9c40
6 |
7 | #d6c8f5f3
8 | #89606060
9 |
10 | #70ffffff
11 | #50ffffff
12 | #53000000
13 |
14 |
15 | #de6565
16 | #7bde65
17 | #c14b84
18 | #6b3fa1
19 | #3fa19f
20 |
21 |
22 |
23 | - @color/colorPrimary
24 | - @android:color/white
25 | - @android:color/white
26 | - @android:color/black
27 | - @color/colorPrimary
28 | - @color/colorAccent
29 |
30 |
31 | - @color/colorPrimary
32 | - @android:color/white
33 | - @android:color/black
34 | - @android:color/white
35 | - @color/chevronBgColor
36 | - #da6c6c
37 | - #da6c6c
38 | - #da6c6c
39 | - @color/colorPrimary
40 |
41 |
42 |
43 |
44 | - @color/colorPrimary
45 | - @android:color/white
46 | - @android:color/black
47 | - @android:color/white
48 | - #da6c6c
49 | - @color/colorPrimary
50 |
51 |
52 | - @color/colorPrimary
53 | - @android:color/black
54 | - @android:color/white
55 | - @android:color/white
56 | - @color/chevronBgColor
57 | - #da6c6c
58 | - #da6c6c
59 | - #da6c6c
60 | - #da6c6c
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/java/mods/ModMoveCallback.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package mods
21 |
22 | import androidx.recyclerview.widget.RecyclerView
23 | import androidx.recyclerview.widget.ItemTouchHelper
24 |
25 | /**
26 | * Callback for dragging the mods around to change load order
27 | */
28 | class ModMoveCallback(private val mAdapter: ModsAdapter) : ItemTouchHelper.Callback() {
29 |
30 | override fun isLongPressDragEnabled(): Boolean {
31 | return true
32 | }
33 |
34 | override fun isItemViewSwipeEnabled(): Boolean {
35 | return false
36 | }
37 |
38 |
39 | override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) {
40 |
41 | }
42 |
43 | override fun getMovementFlags(recyclerView: RecyclerView,
44 | viewHolder: RecyclerView.ViewHolder): Int {
45 | val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
46 | return ItemTouchHelper.Callback.makeMovementFlags(dragFlags, 0)
47 | }
48 |
49 | override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder,
50 | target: RecyclerView.ViewHolder): Boolean {
51 | mAdapter.onRowMoved(viewHolder.adapterPosition, target.adapterPosition)
52 | return true
53 | }
54 |
55 | override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?,
56 | actionState: Int) {
57 | if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
58 | if (viewHolder is ModsAdapter.ModViewHolder) {
59 | mAdapter.onRowSelected(viewHolder)
60 | }
61 | }
62 |
63 | super.onSelectedChanged(viewHolder, actionState)
64 | }
65 |
66 | override fun clearView(recyclerView: RecyclerView,
67 | viewHolder: RecyclerView.ViewHolder) {
68 | super.clearView(recyclerView, viewHolder)
69 |
70 | if (viewHolder is ModsAdapter.ModViewHolder) {
71 | mAdapter.onRowClear(viewHolder)
72 | }
73 | }
74 |
75 | /**
76 | * Speed up dragging of a list element
77 | */
78 | override fun interpolateOutOfBoundsScroll(recyclerView: RecyclerView, viewSize: Int,
79 | viewSizeOutOfBounds: Int, totalSize: Int,
80 | msSinceStartScroll: Long): Int {
81 | val direction = Math.signum(viewSizeOutOfBounds.toFloat()).toInt()
82 | return 20 * direction
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android OpenMW
2 |
3 | FAQ & Info
4 |
5 | Version 47.0 EN
6 |
7 | This is barely functional 0.47 with fixed mess after Docent and a lot of hopium and not much coding knowledge
8 |
9 | Version fix rendering of flora and map to provide stable framerate and consistent experience in the game
10 |
11 | Build does not leave oddities or artifacts from Graphic Herbalism integration
12 |
13 | # Feedback and help
14 | feel free to submit any fixes or issues you can find, just keep in mind i mostly wanna have fun playing, developing is more as side hobby
15 | i also don't feel very competent with android systems therefor all help is appreciated
16 |
17 | # Guide to run Morrowind on Android
18 | https://www.nexusmods.com/morrowind/articles/408
19 |
20 | if you need it
21 |
22 |
23 |
24 |
25 | # Making your own build
26 |
27 | There are two steps for building OpenMW for Android. The first step is building C/C++ libraries. The second step is building the Java launcher.
28 | Prerequisites
29 |
30 | You will need some standard tools installed that you probably already have (bash, gcc, g++, sha256sum, unzip).
31 |
32 | CMake 3.6.0 or newer is required, you can download the latest version here (and place in your PATH) if your distro ships with an outdated version.
33 |
34 | Additionally, to build the launcher you will need Android SDK installed, it is suggested that you use Android Studio which can set it up for you (see step 2).
35 | Step 1: Build the libraries
36 |
37 | Go into the buildscripts directory and run ./build.sh. The script will automatically download the Android native toolchain and all dependencies, and will compile and install them.
38 | Step 2: Build the Java launcher
39 |
40 | To get an APK file you can install, open the openmw-android directory in Android Studio and run the project.
41 |
42 | Alternatively, if you do not have Android Studio installed or would rather not use it, run ./gradlew assembleDebug from the root directory of this repository. The resulting APK, located at ./app/build/outputs/apk/debug/app-debug.apk, can be transferred to the device and installed.
43 | Notes for developers
44 | Debugging native code
45 |
46 | You can debug native code with ndk-gdb. To use it, once you've built both libraries and the apk and installed the apk, run the application and let it stay on the main menu. Then cd to app/src/main and run ./gdb.sh [arch]. The arch variable has to match the library your device will be using (one of arm, arm64, x86_64, x86; arm is the default).
47 |
48 | This also automatically enables gdb to use unstripped libraries, so you get proper symbols, source code references, etc.
49 | Running Address Sanitizer
50 |
51 | To compile everything with ASAN:
52 |
53 | # Clean previous build
54 | ./clean.sh
55 | # Build with ASAN enabled & debug symbols
56 | ./build.sh --ccache --asan --debug
57 | # Or: ./build.sh --ccache --asan --debug --arch arm64
58 |
59 | Then open Android Studio and compile and install the project.
60 |
61 | To get symbolized output:
62 |
63 | adb logcat | ./tool/asan_symbolize.py --demangle -s ./symbols/armeabi-v7a/
64 | # Or: adb logcat | ./tool/asan_symbolize.py --demangle -s ./symbols/arm64-v8a/
65 |
66 | Credits:
67 | SCARaw
68 | Docent
69 | XYZ
70 | Source code
71 | Original Java code written by sandstranger. Build scripts originally written by sandstranger and bwhaines.
72 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/controls/OscAttackButton.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package ui.controls
21 |
22 | import android.annotation.SuppressLint
23 | import android.content.Context
24 | import android.view.MotionEvent
25 | import android.view.View
26 | import android.widget.ImageView
27 | import org.libsdl.app.SDLActivity
28 |
29 | /**
30 | * The attack button is special in that it allows us to control the camera a little
31 | */
32 | class OscAttackButton(
33 | uniqueId: String,
34 | visibility: OscVisibility,
35 | private val imageSrc: Int,
36 | defaultX: Int,
37 | defaultY: Int,
38 | private val keyCode: Int,
39 | defaultSize: Int = 50
40 | ) : OscElement(uniqueId, visibility, defaultX, defaultY, defaultSize) {
41 |
42 | private var curX = 0f
43 | private var curY = 0f
44 | private var downFrom = 0L
45 |
46 | @SuppressLint("ClickableViewAccessibility")
47 | override fun makeView(ctx: Context) {
48 | val v = ImageView(ctx)
49 | v.setImageResource(imageSrc)
50 | // fix blurry icons on old android
51 | v.scaleType = ImageView.ScaleType.FIT_XY
52 | v.setOnTouchListener(View.OnTouchListener { _, motionEvent ->
53 | onMotionEvent(motionEvent)
54 | return@OnTouchListener true
55 | })
56 | v.tag = this
57 |
58 | view = v
59 | }
60 |
61 | /**
62 | * Process events, emulating mouse clicks on down/up and movement on move
63 | */
64 | private fun onMotionEvent(ev: MotionEvent) {
65 | when (ev.actionMasked) {
66 | MotionEvent.ACTION_DOWN -> {
67 | SDLActivity.sendMouseButton(1, keyCode)
68 | curX = ev.x
69 | curY = ev.y
70 | downFrom = System.currentTimeMillis()
71 | }
72 | MotionEvent.ACTION_MOVE -> {
73 | val newX = ev.x
74 | val newY = ev.y
75 |
76 | // Must hold button for specified ms to activate
77 | if (System.currentTimeMillis() - downFrom > 100) {
78 | val mouseScalingFactor = 400f
79 |
80 | val movementX = (newX - curX) * mouseScalingFactor / view!!.width
81 | val movementY = (newY - curY) * mouseScalingFactor / view!!.height
82 |
83 | SDLActivity.sendRelativeMouseMotion(Math.round(movementX), Math.round(movementY))
84 | }
85 |
86 | curX = newX
87 | curY = newY
88 | }
89 | MotionEvent.ACTION_UP -> SDLActivity.sendMouseButton(0, keyCode)
90 | }
91 | }
92 |
93 | }
--------------------------------------------------------------------------------
/app/src/main/java/org/libsdl/app/SDL.java:
--------------------------------------------------------------------------------
1 | package org.libsdl.app;
2 |
3 | import android.content.Context;
4 |
5 | import java.lang.reflect.*;
6 |
7 | /**
8 | SDL library initialization
9 | */
10 | public class SDL {
11 |
12 | // This function should be called first and sets up the native code
13 | // so it can call into the Java classes
14 | public static void setupJNI() {
15 | SDLActivity.nativeSetupJNI();
16 | SDLAudioManager.nativeSetupJNI();
17 | SDLControllerManager.nativeSetupJNI();
18 | }
19 |
20 | // This function should be called each time the activity is started
21 | public static void initialize() {
22 | setContext(null);
23 |
24 | SDLActivity.initialize();
25 | SDLAudioManager.initialize();
26 | SDLControllerManager.initialize();
27 | }
28 |
29 | // This function stores the current activity (SDL or not)
30 | public static void setContext(Context context) {
31 | mContext = context;
32 | }
33 |
34 | public static Context getContext() {
35 | return mContext;
36 | }
37 |
38 | public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
39 |
40 | if (libraryName == null) {
41 | throw new NullPointerException("No library name provided.");
42 | }
43 |
44 | try {
45 | // Let's see if we have ReLinker available in the project. This is necessary for
46 | // some projects that have huge numbers of local libraries bundled, and thus may
47 | // trip a bug in Android's native library loader which ReLinker works around. (If
48 | // loadLibrary works properly, ReLinker will simply use the normal Android method
49 | // internally.)
50 | //
51 | // To use ReLinker, just add it as a dependency. For more information, see
52 | // https://github.com/KeepSafe/ReLinker for ReLinker's repository.
53 | //
54 | Class relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
55 | Class relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
56 | Class contextClass = mContext.getClassLoader().loadClass("android.content.Context");
57 | Class stringClass = mContext.getClassLoader().loadClass("java.lang.String");
58 |
59 | // Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
60 | // they've changed during updates.
61 | Method forceMethod = relinkClass.getDeclaredMethod("force");
62 | Object relinkInstance = forceMethod.invoke(null);
63 | Class relinkInstanceClass = relinkInstance.getClass();
64 |
65 | // Actually load the library!
66 | Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
67 | loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
68 | }
69 | catch (final Throwable e) {
70 | // Fall back
71 | try {
72 | System.loadLibrary(libraryName);
73 | }
74 | catch (final UnsatisfiedLinkError ule) {
75 | throw ule;
76 | }
77 | catch (final SecurityException se) {
78 | throw se;
79 | }
80 | }
81 | }
82 |
83 | protected static Context mContext;
84 | }
85 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/Content.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser;
2 |
3 | /**
4 | * Content class handles changes to dialog's view and whatever is in it
5 | */
6 |
7 | public class Content {
8 |
9 | private String selectLabel = "Select";
10 | private String createLabel = "Create";
11 | private String newFolderLabel = "New Folder";
12 | private String cancelLabel = "Cancel";
13 | private String overviewHeading = "Choose Storage";
14 | private String internalStorageText = "Internal Storage";
15 | private String freeSpaceText = "%s free";
16 | private String folderCreatedToastText = "Folder Created";
17 | private String folderErrorToastText = "Error occured while creating folder. Try again.";
18 | private String textfieldHintText = "Folder Name";
19 | private String textfieldErrorText = "Empty Folder Name";
20 |
21 |
22 | public String getSelectLabel() {
23 | return selectLabel;
24 | }
25 |
26 | public void setSelectLabel(String selectLabel) {
27 | this.selectLabel = selectLabel;
28 | }
29 |
30 | public String getCreateLabel() {
31 | return createLabel;
32 | }
33 |
34 | public void setCreateLabel(String createLabel) {
35 | this.createLabel = createLabel;
36 | }
37 |
38 | public String getNewFolderLabel() {
39 | return newFolderLabel;
40 | }
41 |
42 | public void setNewFolderLabel(String newFolderLabel) {
43 | this.newFolderLabel = newFolderLabel;
44 | }
45 |
46 | public String getCancelLabel() {
47 | return cancelLabel;
48 | }
49 |
50 | public void setCancelLabel(String cancelLabel) {
51 | this.cancelLabel = cancelLabel;
52 | }
53 |
54 | public String getOverviewHeading() {
55 | return overviewHeading;
56 | }
57 |
58 | public void setOverviewHeading(String overviewHeading) {
59 | this.overviewHeading = overviewHeading;
60 | }
61 |
62 | public String getInternalStorageText() {
63 | return internalStorageText;
64 | }
65 |
66 | public void setInternalStorageText(String internalStorageText) {
67 | this.internalStorageText = internalStorageText;
68 | }
69 |
70 | public String getFreeSpaceText() {
71 | return freeSpaceText;
72 | }
73 |
74 | public void setFreeSpaceText(String freeSpaceText) {
75 | this.freeSpaceText = freeSpaceText;
76 | }
77 |
78 | public String getFolderCreatedToastText() {
79 | return folderCreatedToastText;
80 | }
81 |
82 | public void setFolderCreatedToastText(String folderCreatedToastText) {
83 | this.folderCreatedToastText = folderCreatedToastText;
84 | }
85 |
86 | public String getFolderErrorToastText() {
87 | return folderErrorToastText;
88 | }
89 |
90 | public void setFolderErrorToastText(String folderErrorToastText) {
91 | this.folderErrorToastText = folderErrorToastText;
92 | }
93 |
94 | public String getTextfieldHintText() {
95 | return textfieldHintText;
96 | }
97 |
98 | public void setTextfieldHintText(String textfieldHintText) {
99 | this.textfieldHintText = textfieldHintText;
100 | }
101 |
102 | public String getTextfieldErrorText() {
103 | return textfieldErrorText;
104 | }
105 |
106 | public void setTextfieldErrorText(String textfieldErrorText) {
107 | this.textfieldErrorText = textfieldErrorText;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/activity/ModsActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package ui.activity
21 |
22 | import com.libopenmw.openmw.R
23 |
24 | import androidx.appcompat.app.AppCompatActivity
25 | import android.os.Bundle
26 | import com.google.android.material.tabs.TabLayout
27 | import androidx.recyclerview.widget.RecyclerView
28 | import androidx.recyclerview.widget.ItemTouchHelper
29 | import androidx.recyclerview.widget.LinearLayoutManager
30 | import file.GameInstaller
31 | import kotlinx.android.synthetic.main.activity_mods.*
32 | import mods.*
33 | import android.view.MenuItem
34 |
35 |
36 | class ModsActivity : AppCompatActivity() {
37 |
38 | override fun onCreate(savedInstanceState: Bundle?) {
39 | super.onCreate(savedInstanceState)
40 | setContentView(R.layout.activity_mods)
41 |
42 | setSupportActionBar(findViewById(R.id.mods_toolbar))
43 |
44 | // Enable the "back" icon in the action bar
45 | supportActionBar?.setDisplayHomeAsUpEnabled(true)
46 |
47 | // Switch tabs between plugins/resources
48 | tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
49 | override fun onTabSelected(tab: TabLayout.Tab) {
50 | flipper.displayedChild = tab.position
51 | }
52 |
53 | override fun onTabUnselected(tab: TabLayout.Tab) {
54 | }
55 |
56 | override fun onTabReselected(tab: TabLayout.Tab) {
57 | }
58 | })
59 |
60 | // Set up adapters for the lists
61 | setupModList(findViewById(R.id.list_mods), ModType.Plugin)
62 | setupModList(findViewById(R.id.list_resources), ModType.Resource)
63 | }
64 |
65 | /**
66 | * Connects a user-interface RecyclerView to underlying mod data on the disk
67 | * @param list The list displayed to the user
68 | * @param type Type of the mods this list will contain
69 | */
70 | private fun setupModList(list: RecyclerView, type: ModType) {
71 | val dataFiles = GameInstaller.getDataFiles(this)
72 |
73 | val linearLayoutManager = LinearLayoutManager(this)
74 | linearLayoutManager.orientation = RecyclerView.VERTICAL
75 | list.layoutManager = linearLayoutManager
76 |
77 | // Set up the adapter using the specified ModsCollection
78 | val adapter = ModsAdapter(ModsCollection(type, dataFiles, database))
79 |
80 | // Set up the drag-and-drop callback
81 | val callback = ModMoveCallback(adapter)
82 | val touchHelper = ItemTouchHelper(callback)
83 | touchHelper.attachToRecyclerView(list)
84 |
85 | adapter.touchHelper = touchHelper
86 |
87 | list.adapter = adapter
88 | }
89 |
90 | /**
91 | * Makes the "back" icon in the actionbar perform the back operation
92 | */
93 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
94 | return when (item.itemId) {
95 | android.R.id.home -> {
96 | onBackPressed()
97 | true
98 | }
99 |
100 | else -> super.onOptionsItemSelected(item)
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/controls/Joystick.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2018, 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package ui.controls
21 |
22 | import android.annotation.SuppressLint
23 | import android.content.Context
24 | import android.graphics.Canvas
25 | import android.graphics.Color
26 | import android.graphics.Paint
27 | import android.util.AttributeSet
28 | import android.util.TypedValue
29 | import android.view.MotionEvent
30 | import android.view.View
31 |
32 | open class Joystick : View {
33 |
34 | // Initial touch position
35 | protected var initialX = 0f
36 | protected var initialY = 0f
37 |
38 | // Current touch position
39 | protected var currentX = -1f
40 | protected var currentY = -1f
41 |
42 | // Whether the finger is down
43 | protected var down = false
44 |
45 | // left or right stick
46 | protected var stickId = 0
47 |
48 | // width of a stroke to draw stick circles
49 | private var strokeWidth = 0
50 |
51 | private val paint = Paint()
52 |
53 | constructor(context: Context) : super(context) {
54 | init()
55 | }
56 |
57 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
58 | init()
59 | }
60 |
61 | constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
62 | init()
63 | }
64 |
65 | private fun init() {
66 | strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2f, context.resources.displayMetrics).toInt()
67 | }
68 |
69 | fun setStick(id: Int) {
70 | stickId = id
71 | }
72 |
73 | public override fun onDraw(canvas: Canvas) {
74 | super.onDraw(canvas)
75 |
76 | paint.style = Paint.Style.STROKE
77 | paint.strokeWidth = strokeWidth.toFloat()
78 | paint.color = Color.GRAY
79 |
80 | if (down) {
81 | // Draw initial touch
82 | canvas.drawCircle(initialX, initialY, width / 10f, paint)
83 |
84 | // Draw current stick position
85 | canvas.drawCircle(currentX, currentY, width / 5f, paint)
86 | } else {
87 | // Draw the outline
88 | canvas.drawCircle(width / 2f, height / 2f,
89 | width / 2f - strokeWidth, paint)
90 | }
91 | }
92 |
93 | public override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
94 | setMeasuredDimension(widthMeasureSpec, heightMeasureSpec)
95 | }
96 |
97 | @SuppressLint("ClickableViewAccessibility")
98 | override fun onTouchEvent(event: MotionEvent): Boolean {
99 | when (event.actionMasked) {
100 | MotionEvent.ACTION_DOWN -> {
101 | initialX = event.x
102 | initialY = event.y
103 | currentX = initialX
104 | currentY = initialY
105 | down = true
106 | }
107 | MotionEvent.ACTION_MOVE -> {
108 | currentX = event.x
109 | currentY = event.y
110 | }
111 | MotionEvent.ACTION_UP -> {
112 | down = false
113 | // make sure it's hidden
114 | currentY = -1f
115 | currentX = -1f
116 | }
117 | }
118 |
119 | updateStick()
120 | invalidate()
121 | return true
122 | }
123 |
124 | protected open fun updateStick() {}
125 | }
126 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/adapters/SecondaryChooserAdapter.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.adapters;
2 |
3 | import android.content.Context;
4 | import android.text.SpannableStringBuilder;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.BaseAdapter;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 |
12 | import com.codekidlabs.storagechooser.R;
13 | import com.codekidlabs.storagechooser.StorageChooser;
14 | import com.codekidlabs.storagechooser.fragments.ChooserDialogFragment;
15 | import com.codekidlabs.storagechooser.utils.FileUtil;
16 | import com.codekidlabs.storagechooser.utils.ResourceUtil;
17 | import com.codekidlabs.storagechooser.utils.ThumbnailUtil;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | public class SecondaryChooserAdapter extends BaseAdapter {
23 |
24 | public static boolean shouldEnable = true;
25 | public ArrayList selectedPaths;
26 | public String prefixPath;
27 | private List storagesList;
28 | private Context mContext;
29 | private int[] scheme;
30 | private ThumbnailUtil thumbnailUtil;
31 | private ResourceUtil resourceUtil;
32 |
33 | private String listTypeface;
34 | private boolean fromAssets;
35 |
36 |
37 | public SecondaryChooserAdapter(List storagesList, Context mContext, int[] scheme,
38 | String listTypeface, boolean fromAssets) {
39 | this.storagesList = storagesList;
40 | this.mContext = mContext;
41 | this.scheme = scheme;
42 | this.listTypeface = listTypeface;
43 | this.fromAssets = fromAssets;
44 |
45 | // create instance once
46 | thumbnailUtil = new ThumbnailUtil(mContext);
47 | resourceUtil = new ResourceUtil(mContext);
48 | selectedPaths = new ArrayList<>();
49 | }
50 |
51 | @Override
52 | public int getCount() {
53 | return storagesList.size();
54 | }
55 |
56 | @Override
57 | public Object getItem(int i) {
58 | return storagesList.get(i);
59 | }
60 |
61 | @Override
62 | public long getItemId(int i) {
63 | return i;
64 | }
65 |
66 | @Override
67 | public View getView(int i, View view, ViewGroup viewGroup) {
68 | LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
69 |
70 | View rootView = inflater.inflate(R.layout.row_custom_paths, viewGroup, false);
71 |
72 | ImageView pathFolderIcon = rootView.findViewById(R.id.path_folder_icon);
73 | if (FileUtil.isDir(prefixPath + "/" + storagesList.get(i))) {
74 | applyFolderTint(pathFolderIcon);
75 | }
76 |
77 | thumbnailUtil.init(pathFolderIcon, storagesList.get(i));
78 |
79 | TextView storageName = rootView.findViewById(R.id.storage_name);
80 | storageName.setText(storagesList.get(i));
81 |
82 | if (listTypeface != null) {
83 | storageName.setTypeface(ChooserDialogFragment.getSCTypeface(mContext, listTypeface,
84 | fromAssets));
85 | }
86 |
87 |
88 | storageName.setTextColor(scheme[StorageChooser.Theme.SEC_TEXT_INDEX]);
89 |
90 | if (selectedPaths.contains(i)) {
91 | rootView.setBackgroundColor(resourceUtil.getPrimaryColorWithAlpha());
92 | }
93 |
94 | return rootView;
95 | }
96 |
97 |
98 | /**
99 | * return the spannable index of character '('
100 | *
101 | * @param str SpannableStringBuilder to apply typeface changes
102 | * @return index of '('
103 | */
104 | private int getSpannableIndex(SpannableStringBuilder str) {
105 | return str.toString().indexOf("(") + 1;
106 | }
107 |
108 | public String getPrefixPath() {
109 | return prefixPath;
110 | }
111 |
112 | public void setPrefixPath(String path) {
113 | this.prefixPath = path;
114 | }
115 |
116 | private void applyFolderTint(ImageView im) {
117 | im.setColorFilter(scheme[StorageChooser.Theme.SEC_FOLDER_TINT_INDEX]);
118 | }
119 |
120 | @Override
121 | public boolean isEnabled(int position) {
122 | return shouldEnable;
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/app/src/main/java/mods/ModsAdapter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package mods
21 |
22 | import android.annotation.SuppressLint
23 | import android.graphics.Color
24 | import androidx.recyclerview.widget.RecyclerView
25 | import androidx.recyclerview.widget.ItemTouchHelper
26 | import android.view.LayoutInflater
27 | import android.view.MotionEvent
28 | import android.view.View
29 | import android.view.ViewGroup
30 | import android.widget.CheckBox
31 | import android.widget.ImageView
32 | import android.widget.TextView
33 | import com.libopenmw.openmw.R
34 | import java.util.*
35 |
36 | /**
37 | * An adapter to put a ModsCollection into a UI list
38 | */
39 | class ModsAdapter(private val collection: ModsCollection) : RecyclerView.Adapter() {
40 |
41 | lateinit var touchHelper: ItemTouchHelper
42 |
43 | /**
44 | * A row representation of a mod
45 | */
46 | inner class ModViewHolder(internal var rowView: View) : RecyclerView.ViewHolder(rowView) {
47 | val mTitle: TextView = rowView.findViewById(R.id.txtTitle)
48 | val mHandle: ImageView = rowView.findViewById(R.id.handle)
49 | val mCheckbox: CheckBox = rowView.findViewById(R.id.modCheckbox)
50 | }
51 |
52 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ModViewHolder {
53 | val itemView = LayoutInflater.from(parent.context).inflate(R.layout.mod_item, parent, false)
54 | return ModViewHolder(itemView)
55 | }
56 |
57 | @SuppressLint("ClickableViewAccessibility")
58 | override fun onBindViewHolder(holder: ModViewHolder, position: Int) {
59 | val mod = collection.mods[position]
60 | holder.mTitle.text = mod.filename
61 | holder.mHandle.setOnTouchListener { _, event ->
62 | if (event.action == MotionEvent.ACTION_DOWN) {
63 | touchHelper.startDrag(holder)
64 | }
65 | false
66 | }
67 | holder.mCheckbox.isChecked = mod.enabled
68 | holder.mCheckbox.setOnClickListener {
69 | mod.enabled = (it as CheckBox).isChecked
70 | mod.dirty = true
71 | collection.update()
72 | }
73 | }
74 |
75 | override fun getItemCount(): Int {
76 | return collection.mods.size
77 | }
78 |
79 | private fun swapMods(from: Int, to: Int) {
80 | // Swap the orders
81 | val tmp = collection.mods[from].order
82 | collection.mods[from].order = collection.mods[to].order
83 | collection.mods[to].order = tmp
84 |
85 | // Swap the mods inside the list
86 | Collections.swap(collection.mods, from, to)
87 |
88 | // Mark mods as dirty to update when the user releases currently dragged mod
89 | collection.mods[from].dirty = true
90 | collection.mods[to].dirty = true
91 | }
92 |
93 | fun onRowMoved(fromPosition: Int, toPosition: Int) {
94 | if (fromPosition < toPosition) {
95 | for (i in fromPosition until toPosition) {
96 | swapMods(i, i + 1)
97 | }
98 | } else {
99 | for (i in fromPosition downTo toPosition + 1) {
100 | swapMods(i, i - 1)
101 | }
102 | }
103 | notifyItemMoved(fromPosition, toPosition)
104 | }
105 |
106 | fun onRowSelected(modViewHolder: ModViewHolder) {
107 | modViewHolder.rowView.setBackgroundColor(Color.LTGRAY)
108 | }
109 |
110 | fun onRowClear(modViewHolder: ModViewHolder) {
111 | modViewHolder.rowView.setBackgroundColor(Color.WHITE)
112 | collection.update()
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/utils/MemoryUtil.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.utils;
2 |
3 |
4 | import android.os.StatFs;
5 |
6 | import java.io.File;
7 | import java.util.ArrayList;
8 | import java.util.Collections;
9 | import java.util.List;
10 |
11 | public class MemoryUtil {
12 |
13 | public static final String SELF_DIR_NAME = "self";
14 | public static final String EMULATED_DIR_NAME = "emulated";
15 | public static final String EMULATED_DIR_KNOX = "knox-emulated";
16 | public static final String SDCARD0_DIR_NAME = "sdcard0";
17 | public static final String CONTAINER = "container";
18 | private static final String ERROR = "error";
19 |
20 | public boolean isExternalStoragePresent() {
21 | return getStorageListSize() != 1;
22 | }
23 |
24 | /**
25 | * Returns an the number of the files inside '/storage' directory
26 | *
27 | * @return int - number of storages present except the redundant once
28 | */
29 | public int getStorageListSize() {
30 | File storageDir = new File("/storage");
31 | List volumeList = new ArrayList<>();
32 | Collections.addAll(volumeList, storageDir.listFiles());
33 | // segregate the list
34 | for (int i = 0; i < volumeList.size(); i++) {
35 | String storageName = volumeList.get(i).getName();
36 | if (storageName.equals(SELF_DIR_NAME) ||
37 | storageName.equals(EMULATED_DIR_KNOX) ||
38 | storageName.equals(EMULATED_DIR_KNOX) ||
39 | storageName.equals(SDCARD0_DIR_NAME) ||
40 | storageName.equals(CONTAINER)) {
41 | volumeList.remove(i);
42 | }
43 | }
44 |
45 | return volumeList.size();
46 | }
47 |
48 |
49 | /**
50 | * calculate available/free size of any directory
51 | *
52 | * @param path path of the storage
53 | * @return size in bytes
54 | */
55 | public long getAvailableMemorySize(String path) {
56 | File file = new File(path);
57 | StatFs stat = new StatFs(file.getPath());
58 | long blockSize = stat.getBlockSize();
59 | long availableBlocks = stat.getAvailableBlocks();
60 | return availableBlocks * blockSize;
61 | }
62 |
63 | /**
64 | * calculate total size of any directory
65 | *
66 | * @param path path of the storage
67 | * @return size in bytes
68 | */
69 | public long getTotalMemorySize(String path) {
70 | File file = new File(path);
71 | StatFs stat = new StatFs(file.getPath());
72 | long blockSize = stat.getBlockSize();
73 | long totalBlocks = stat.getBlockCount();
74 | return totalBlocks * blockSize;
75 | }
76 |
77 | /**
78 | * mainly to format the available bytes into user readable string
79 | *
80 | * @param size long - value gained from the getTotalMemorySize() and getAvailableMemorySize()
81 | * using StatFs
82 | * @return a formatted string with KiB, MiB, GiB suffix
83 | */
84 | public String formatSize(long size) {
85 | String suffix = null;
86 |
87 | if (size >= 1024) {
88 | suffix = "KiB";
89 | size /= 1024;
90 | if (size >= 1024) {
91 | suffix = "MiB";
92 | size /= 1024;
93 | if (size >= 1024) {
94 | suffix = "GiB";
95 | size /= 1024;
96 | }
97 | }
98 | }
99 |
100 | StringBuilder resultBuffer = new StringBuilder(Long.toString(size));
101 |
102 | int commaOffset = resultBuffer.length() - 3;
103 | while (commaOffset > 0) {
104 | resultBuffer.insert(commaOffset, ',');
105 | commaOffset -= 3;
106 | }
107 |
108 | if (suffix != null) resultBuffer.append(suffix);
109 | return resultBuffer.toString();
110 | }
111 |
112 | public long suffixedSize(long size, String suffix) {
113 |
114 | switch (suffix) {
115 | case "KiB":
116 | return size / 1024;
117 | case "MiB":
118 | return (long) (size / Math.pow(1024, 2));
119 | case "GiB":
120 | return (long) (size / Math.pow(1024, 3));
121 | default:
122 | return 0;
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/app/src/main/java/ui/activity/ConfigureControls.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2018, 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package ui.activity
21 |
22 | import com.libopenmw.openmw.R
23 |
24 | import android.app.Activity
25 | import android.graphics.Color
26 | import android.os.Bundle
27 | import android.view.MotionEvent
28 | import android.view.View
29 | import android.widget.RelativeLayout
30 |
31 | import ui.controls.Osc
32 | import ui.controls.OscElement
33 | import ui.controls.VIRTUAL_SCREEN_HEIGHT
34 | import ui.controls.VIRTUAL_SCREEN_WIDTH
35 | import utils.Utils.hideAndroidControls
36 |
37 | class ConfigureCallback(activity: Activity) : View.OnTouchListener {
38 |
39 | var currentView: View? = null
40 | private var layout: RelativeLayout = activity.findViewById(R.id.controlsContainer)
41 | private var origX: Float = 0.0f
42 | private var origY: Float = 0.0f
43 | private var startX: Float = 0.0f
44 | private var startY: Float = 0.0f
45 |
46 | override fun onTouch(v: View, event: MotionEvent): Boolean {
47 | when (event.actionMasked) {
48 | MotionEvent.ACTION_DOWN -> {
49 | currentView?.setBackgroundColor(Color.TRANSPARENT)
50 | currentView = v
51 | v.setBackgroundColor(Color.RED)
52 | origX = v.x
53 | origY = v.y
54 | startX = event.rawX
55 | startY = event.rawY
56 | }
57 | MotionEvent.ACTION_MOVE -> if (currentView != null) {
58 | val view = currentView!!
59 | val x = ((event.rawX - startX) + origX).toInt()
60 | val y = ((event.rawY - startY) + origY).toInt()
61 |
62 | val el = view.tag as OscElement
63 | el.changePosition(x * VIRTUAL_SCREEN_WIDTH / layout.width, y * VIRTUAL_SCREEN_HEIGHT / layout.height)
64 | el.updateView()
65 | }
66 | }
67 |
68 | return true
69 | }
70 |
71 | }
72 |
73 | class ConfigureControls : Activity() {
74 |
75 | private var callback: ConfigureCallback? = null
76 | private var osc = Osc()
77 |
78 | public override fun onCreate(savedInstanceState: Bundle?) {
79 | super.onCreate(savedInstanceState)
80 |
81 | setContentView(R.layout.configure_controls)
82 |
83 | val cb = ConfigureCallback(this)
84 | callback = cb
85 |
86 | val container: RelativeLayout = findViewById(R.id.controlsContainer)
87 | osc.placeConfigurableElements(container, cb)
88 | }
89 |
90 | override fun onWindowFocusChanged(hasFocus: Boolean) {
91 | if (hasFocus) {
92 | hideAndroidControls(this)
93 | }
94 | }
95 |
96 | private fun changeOpacity(delta: Float) {
97 | val view = callback?.currentView ?: return
98 | val el = view.tag as OscElement
99 | el.changeOpacity(delta)
100 | el.updateView()
101 | }
102 |
103 | private fun changeSize(delta: Int) {
104 | val view = callback?.currentView ?: return
105 | val el = view.tag as OscElement
106 | el.changeSize(delta)
107 | el.updateView()
108 | }
109 |
110 | fun clickOpacityPlus(v: View) {
111 | changeOpacity(0.1f)
112 | }
113 |
114 | fun clickOpacityMinus(v: View) {
115 | changeOpacity(-0.1f)
116 | }
117 |
118 | fun clickSizePlus(v: View) {
119 | changeSize(5)
120 | }
121 |
122 | fun clickSizeMinus(v: View) {
123 | changeSize(-5)
124 | }
125 |
126 | fun clickResetControls(v: View) {
127 | osc.resetElements(applicationContext)
128 | }
129 |
130 | fun clickBack(v: View) {
131 | finish()
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
16 |
17 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
34 |
35 |
42 |
43 |
50 |
51 |
60 |
61 |
64 |
65 |
68 |
69 |
72 |
73 |
76 |
77 |
83 |
84 |
87 |
88 |
89 |
90 |
99 |
100 |
101 |
102 |
106 |
107 |
111 |
112 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/app/src/main/java/file/GameInstaller.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package file
21 |
22 | import android.content.Context
23 | import android.preference.PreferenceManager
24 | import constants.Constants
25 | import java.io.File
26 | import java.io.IOException
27 | import java.nio.charset.Charset
28 |
29 | /**
30 | * Class responsible for initial game setup which involves
31 | * transforming morrowind.ini into openmw.cfg
32 | */
33 | class GameInstaller(path: String) {
34 |
35 | val dir = File(path)
36 |
37 | /**
38 | * Lists the root directory and finds a file or directory named "name",
39 | * doing case-insensitive checks
40 | * @param name Name to search
41 | * @return File object if it was found, null otherwise
42 | */
43 | private fun findCaseInsensitive(name: String): File? {
44 | val nameLower = name.toLowerCase()
45 | return dir
46 | .list { _, fileName -> fileName.toLowerCase() == nameLower }
47 | .map { File(dir, it) }
48 | .firstOrNull()
49 | }
50 |
51 | /**
52 | * Checks that the "path" directory contains a morrowind.ini,
53 | * and that there's a "Data Files" directory
54 | */
55 | fun check(): Boolean {
56 | // Root directory must exist and be a directory
57 | if (!dir.exists() || !dir.isDirectory)
58 | return false
59 |
60 | // morrowind.ini as well as data files must exist
61 | return findCaseInsensitive(INI_NAME) != null
62 | && findCaseInsensitive(DATA_NAME) != null
63 | }
64 |
65 | /**
66 | * Returns path to the Data Files directory as a string
67 | */
68 | fun findDataFiles(): String {
69 | return File(dir, DATA_NAME).absolutePath
70 | }
71 |
72 | /**
73 | * Adds a .nomedia to the game folder so that it doesn't bloat up the gallery
74 | * If this fails, then who cares
75 | */
76 | fun setNomedia() {
77 | try {
78 | val file = File(dir, ".nomedia")
79 | if (!file.exists())
80 | file.createNewFile()
81 | } catch (e: IOException) {
82 | }
83 | }
84 |
85 | /**
86 | * Converts morrowind.ini into openmw format and places it into our resources directory
87 | * (properly named and everything)
88 | * @param encoding Game encoding as entered by the user; one of pref_encoding_values
89 | * @return Whether the conversion succeeded
90 | */
91 | fun convertIni(encoding: String): Boolean {
92 | val file = findCaseInsensitive(INI_NAME) ?: return false
93 |
94 | val charset = when (encoding) {
95 | "win1250" -> Charset.forName("windows-1250")
96 | "win1251" -> Charset.forName("windows-1251")
97 | else -> Charset.forName("windows-1252")
98 | }
99 |
100 | val contents = file.readText(charset)
101 | if (contents.isEmpty())
102 | return false
103 |
104 | val ini = IniConverter(contents)
105 | val output = ini.convert()
106 | // there's gotta be something in the output as well
107 | if (output.isEmpty())
108 | return false
109 |
110 | File(File(Constants.OPENMW_FALLBACK_CFG).parent).mkdirs()
111 | File(Constants.OPENMW_FALLBACK_CFG).writeText(output)
112 |
113 | return true
114 | }
115 |
116 | companion object {
117 | const val INI_NAME = "Morrowind.ini"
118 | const val DATA_NAME = "Data Files"
119 | const val DEFAULT_CHARSET_PREF = "win1252"
120 |
121 | /**
122 | * Returns path of Data Files, making use of path to the game from the settings
123 | * @param ctx Android context
124 | * @return Absolute path to data files as a string
125 | */
126 | fun getDataFiles(ctx: Context): String {
127 | val gamePath = PreferenceManager.getDefaultSharedPreferences(ctx)
128 | .getString("game_files", "")!!
129 | val inst = GameInstaller(gamePath)
130 | return inst.findDataFiles()
131 | }
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/storagechooser/src/main/java/com/codekidlabs/storagechooser/utils/ThumbnailUtil.java:
--------------------------------------------------------------------------------
1 | package com.codekidlabs.storagechooser.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.drawable.Drawable;
5 | import androidx.core.content.ContextCompat;
6 | import android.widget.ImageView;
7 |
8 | import com.codekidlabs.storagechooser.R;
9 |
10 | public class ThumbnailUtil {
11 |
12 | // Constant extensions
13 | private static final String TEXT_FILE = "txt";
14 | private static final String LOG_FILE = "log";
15 | private static final String CSV_FILE = "csv";
16 | private static final String PROP_FILE = "prop";
17 | // video files
18 | private static final String VIDEO_FILE = "mp4";
19 | private static final String VIDEO_MOV_FILE = "mov";
20 | private static final String VIDEO_AVI_FILE = "avi";
21 | private static final String VIDEO_MKV_FILE = "mkv";
22 | // audio files
23 | private static final String AUDIO_FILE = "mp3";
24 | // image files
25 | private static final String JPEG_FILE = "jpeg";
26 | private static final String JPG_FILE = "jpg";
27 | private static final String PNG_FILE = "png";
28 | private static final String GIF_FILE = "gif";
29 | //archive files
30 | private static final String APK_FILE = "apk";
31 | private static final String ZIP_FILE = "zip";
32 | private static final String RAR_FILE = "rar";
33 | private static final String TAR_GZ_FILE = "gz";
34 | private static final String TAR_FILE = "tar";
35 | // office files
36 | private static final String DOC_FILE = "doc";
37 | private static final String PPT_FILE = "ppt";
38 | private static final String EXCEL_FILE = "xls";
39 | private static final String PDF_FILE = "pdf";
40 | // font files
41 | private static final String TTF_FILE = "ttf";
42 | private static final String OTF_FILE = "otf";
43 | // torrent files
44 | private static final String TORRENtT_FILE = "torrent";
45 | //web files
46 | private static final String HTML_FILE = "html";
47 | private static final String PHP_FILE = "php";
48 | private static final String CSS_FILE = "css";
49 | private static final String CR_DL_FILE = "crdownload";
50 | private Context mContext;
51 |
52 | public ThumbnailUtil(Context mContext) {
53 | this.mContext = mContext;
54 | }
55 |
56 | public void init(ImageView imageView, String filePath) {
57 | thumbnailPipe(imageView, filePath);
58 | }
59 |
60 | private void thumbnailPipe(ImageView imageView, String filePath) {
61 | String extension = getExtension(filePath);
62 |
63 |
64 | switch (extension) {
65 | case TEXT_FILE:
66 | case CSV_FILE:
67 | case DOC_FILE:
68 | case PROP_FILE:
69 | case LOG_FILE:
70 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.doc));
71 | break;
72 | case VIDEO_FILE:
73 | case VIDEO_AVI_FILE:
74 | case VIDEO_MOV_FILE:
75 | case VIDEO_MKV_FILE:
76 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.mov));
77 | break;
78 | case APK_FILE:
79 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.apk));
80 | break;
81 | case AUDIO_FILE:
82 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.music));
83 | break;
84 | case ZIP_FILE:
85 | case RAR_FILE:
86 | case TAR_FILE:
87 | case TAR_GZ_FILE:
88 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.zip));
89 | break;
90 | case JPEG_FILE:
91 | case JPG_FILE:
92 | case PNG_FILE:
93 | case GIF_FILE:
94 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.pic));
95 | break;
96 | case TTF_FILE:
97 | case OTF_FILE:
98 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.font));
99 | break;
100 | case HTML_FILE:
101 | case PHP_FILE:
102 | case CSS_FILE:
103 | case CR_DL_FILE:
104 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.web));
105 | break;
106 | case TORRENtT_FILE:
107 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.torrent));
108 | break;
109 | case PDF_FILE:
110 | imageView.setImageDrawable(getDrawableFromRes(R.drawable.pdf));
111 | break;
112 | }
113 | }
114 |
115 | private Drawable getDrawableFromRes(int id) {
116 | return ContextCompat.getDrawable(mContext, id);
117 | }
118 |
119 | private String getExtension(String path) {
120 | return path.substring(path.lastIndexOf(".") + 1, path.length());
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/cursor/MouseCursor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (C) 2018, 2019 Ilya Zhuravlev
3 |
4 | This file is part of OpenMW-Android.
5 |
6 | OpenMW-Android is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | OpenMW-Android is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with OpenMW-Android. If not, see .
18 | */
19 |
20 | package cursor
21 |
22 | import android.content.Context
23 | import android.util.AttributeSet
24 | import android.util.TypedValue
25 | import android.view.Choreographer
26 | import android.view.View
27 | import android.widget.RelativeLayout
28 |
29 | import com.libopenmw.openmw.R
30 |
31 | import org.libsdl.app.SDLActivity
32 |
33 | import ui.activity.GameActivity
34 | import ui.activity.MainActivity
35 | import ui.activity.MouseMode
36 | import ui.controls.Osc
37 |
38 | /**
39 | * An image view which doesn't downsize itself when moved to the border of a RelativeLayout
40 | * (not sure if original behavior is intended)
41 | */
42 | internal class FixedSizeImageView : androidx.appcompat.widget.AppCompatImageView {
43 |
44 | // Just something so that it's visible
45 | private var fixedWidth = 10
46 | private var fixedHeight = 10
47 |
48 | // Default constructors for studio UI editor
49 | constructor(context: Context): super(context)
50 | constructor(context: Context, attrs: AttributeSet): super(context, attrs)
51 | constructor(context: Context, attrs: AttributeSet, defStyle: Int):
52 | super(context, attrs, defStyle)
53 |
54 | /**
55 | * @param w Fixed width of this view
56 | * @param h Fixed height of this view
57 | */
58 | constructor(context: Context, w: Int, h: Int): super(context) {
59 | fixedWidth = w
60 | fixedHeight = h
61 | }
62 |
63 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
64 | setMeasuredDimension(fixedWidth, fixedHeight)
65 | }
66 | }
67 |
68 | class MouseCursor(activity: GameActivity, private val osc: Osc?) : Choreographer.FrameCallback {
69 |
70 | private val choreographer: Choreographer
71 | private val cursor: FixedSizeImageView
72 | private var prevMouseShown = -1
73 |
74 | init {
75 | val height = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30f,
76 | activity.resources.displayMetrics).toInt()
77 | val width = Math.round(height / 1.5).toInt()
78 |
79 | cursor = FixedSizeImageView(activity, width, height)
80 | cursor.setImageResource(R.drawable.pointer_arrow)
81 |
82 | cursor.layoutParams = RelativeLayout.LayoutParams(width, height)
83 |
84 | activity.layout.addView(cursor)
85 |
86 | choreographer = Choreographer.getInstance()
87 | choreographer.postFrameCallback(this)
88 | }
89 |
90 | override fun doFrame(frameTimeNanos: Long) {
91 | // Check if we need to switch osc widgets visibility
92 | val mouseShown = SDLActivity.isMouseShown()
93 | if (osc != null && mouseShown != prevMouseShown) {
94 | if (GameActivity.mouseMode == MouseMode.Touch) {
95 | // If the player has default mouse-mode enabled, trigger it here
96 | osc.mouseVisible = mouseShown != 0
97 | }
98 | osc.showBasedOnState()
99 | }
100 |
101 | if (GameActivity.mouseMode == MouseMode.Touch || mouseShown == 0 || (osc != null && osc.keyboardVisible)) {
102 | cursor.visibility = View.GONE
103 | } else {
104 | cursor.visibility = View.VISIBLE
105 |
106 | val surface = SDLActivity.getSurface()
107 |
108 | var translateX = 1.0f
109 | var translateY = 1.0f
110 |
111 | if (MainActivity.resolutionX > 0) {
112 | translateX = 1.0f * surface.width / MainActivity.resolutionX
113 | translateY = 1.0f * surface.height / MainActivity.resolutionY
114 | }
115 |
116 | val mouseX = SDLActivity.getMouseX()
117 | val mouseY = SDLActivity.getMouseY()
118 |
119 | // calling setX/setY here results in a bug cropping part of the mouse cursor
120 | // changing LayoutParams works as expected...
121 | val params = cursor.layoutParams as RelativeLayout.LayoutParams
122 | params.leftMargin = (mouseX * translateX + surface.left).toInt()
123 | params.topMargin = (mouseY * translateY + surface.top).toInt()
124 | cursor.layoutParams = params
125 | }
126 |
127 | prevMouseShown = mouseShown
128 | choreographer.postFrameCallback(this)
129 | }
130 | }
131 |
--------------------------------------------------------------------------------