├── .gitattributes ├── .gitignore ├── LICENSE ├── README.MD ├── android ├── AndroidManifest.xml ├── assets │ ├── bigimages │ │ ├── main_menu_background.jpg │ │ ├── main_menu_background.png │ │ └── splash.png │ ├── fonts │ │ ├── combo-font.fnt │ │ ├── combo-font_0.png │ │ ├── font.fnt │ │ ├── font.png │ │ ├── jp-font-small.fnt │ │ ├── jp-font-small_00.png │ │ ├── jp-font-small_01.png │ │ ├── jp-font-small_02.png │ │ ├── jp-font-small_03.png │ │ ├── jp-font-small_04.png │ │ ├── jp-font-small_05.png │ │ ├── jp-font-small_06.png │ │ ├── jp-font-small_07.png │ │ ├── jp-font-small_08.png │ │ ├── jp-font-small_09.png │ │ ├── jp-font-small_10.png │ │ ├── jp-font-small_11.png │ │ ├── jp-font-small_12.png │ │ ├── jp-font-small_13.png │ │ ├── jp-font-small_14.png │ │ ├── jp-font-small_15.png │ │ ├── jp-font-small_16.png │ │ ├── jp-font-small_17.png │ │ ├── jp-font-small_18.png │ │ ├── jp-font-small_19.png │ │ ├── jp-font-small_20.png │ │ ├── jp-font-small_21.png │ │ ├── jp-font-small_22.png │ │ ├── jp-font-small_23.png │ │ ├── jp-font-small_24.png │ │ ├── jp-font-small_25.png │ │ ├── jp-font-small_26.png │ │ ├── jp-font-small_27.png │ │ ├── jp-font-small_28.png │ │ ├── result-font.fnt │ │ ├── result-font_0.png │ │ ├── settings-font.fnt │ │ ├── settings-font_0.png │ │ ├── song-font.fnt │ │ ├── song-font_0.png │ │ ├── song-list.fnt │ │ ├── song-list_00.png │ │ ├── song-list_01.png │ │ ├── song-list_02.png │ │ ├── song-list_03.png │ │ ├── song-list_04.png │ │ ├── song-list_05.png │ │ ├── song-list_06.png │ │ ├── song-list_07.png │ │ ├── song-list_08.png │ │ ├── song-list_09.png │ │ ├── song-list_10.png │ │ ├── song-list_11.png │ │ ├── song-list_12.png │ │ ├── song-list_13.png │ │ ├── song-list_14.png │ │ ├── song-list_15.png │ │ ├── song-list_16.png │ │ ├── song-list_17.png │ │ ├── song-list_18.png │ │ ├── song-list_19.png │ │ ├── song-list_20.png │ │ ├── song-list_21.png │ │ ├── song-list_22.png │ │ ├── song-list_23.png │ │ ├── song-list_24.png │ │ ├── song-list_25.png │ │ ├── song-list_26.png │ │ ├── song-list_27.png │ │ ├── song-list_28.png │ │ ├── song-list_29.png │ │ ├── song-list_30.png │ │ ├── song-list_31.png │ │ ├── song-list_32.png │ │ ├── song-list_33.png │ │ ├── song-list_34.png │ │ ├── song-list_35.png │ │ ├── song-list_36.png │ │ ├── song-list_37.png │ │ ├── song-list_38.png │ │ ├── song-list_39.png │ │ ├── song-list_40.png │ │ ├── song-list_41.png │ │ ├── song-list_42.png │ │ ├── song-list_43.png │ │ ├── song-list_44.png │ │ ├── song-list_45.png │ │ ├── song-list_46.png │ │ ├── song-list_47.png │ │ ├── song-list_48.png │ │ ├── song-list_49.png │ │ ├── song-list_50.png │ │ ├── title-font.fnt │ │ └── title-font_0.png │ ├── hitsounds │ │ ├── no_hit_tap.mp3 │ │ ├── swipe_great.mp3 │ │ ├── swipe_nice.mp3 │ │ ├── swipe_perfect.mp3 │ │ ├── tap_great.mp3 │ │ ├── tap_nice.mp3 │ │ └── tap_perfect.mp3 │ ├── images │ │ ├── acc_bad.png │ │ ├── acc_good.png │ │ ├── acc_great.png │ │ ├── acc_mark.png │ │ ├── acc_perfect.png │ │ ├── bad_late.png │ │ ├── bad_soon.png │ │ ├── circle.png │ │ ├── circle_sim.png │ │ ├── circle_swipe_left.png │ │ ├── circle_swipe_left_sim.png │ │ ├── circle_swipe_right.png │ │ ├── circle_swipe_right_sim.png │ │ ├── good_late.png │ │ ├── good_soon.png │ │ ├── great_late.png │ │ ├── great_soon.png │ │ ├── hold_background.png │ │ ├── knob.png │ │ ├── knob_after.png │ │ ├── knob_before.png │ │ ├── menu_item_down.png │ │ ├── menu_item_idle.png │ │ ├── miss.png │ │ ├── nice_late.png │ │ ├── nice_soon.png │ │ ├── perfect.png │ │ ├── selection_menu_background.png │ │ ├── selection_menu_selected.png │ │ ├── song_selection_menu_background.png │ │ ├── tap.png │ │ ├── tap_pressed.png │ │ └── tap_warn.png │ ├── skins │ │ ├── menuSkin.json │ │ └── splashSkin.json │ └── textures │ │ ├── textures.pack.atlas │ │ ├── textures.pack.png │ │ ├── textures.pack2.png │ │ ├── textures.pack3.png │ │ └── textures.pack4.png ├── build.gradle ├── ic_launcher-web.png ├── libs │ ├── armeabi-v7a │ │ ├── libgdx-box2d.so │ │ ├── libgdx-freetype.so │ │ └── libgdx.so │ ├── armeabi │ │ ├── libgdx-box2d.so │ │ ├── libgdx-freetype.so │ │ └── libgdx.so │ └── x86 │ │ ├── libgdx-box2d.so │ │ ├── libgdx-freetype.so │ │ └── libgdx.so ├── project.properties ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ └── values │ │ ├── strings.xml │ │ └── styles.xml └── src │ └── com │ └── fteams │ └── sstrain │ └── android │ └── AndroidLauncher.java ├── build.gradle ├── core ├── build.gradle └── src │ └── com │ └── fteams │ └── sstrain │ ├── SSTrain.java │ ├── World.java │ ├── assets │ ├── Assets.java │ └── SimplifiedBeatmapLoader.java │ ├── config │ └── GlobalConfiguration.java │ ├── controller │ ├── Crossfader.java │ ├── SongLoader.java │ └── WorldController.java │ ├── entities │ ├── BaseMetadata.java │ ├── Beatmap.java │ ├── BeatmapGroup.java │ ├── Metadata.java │ ├── Note.java │ └── Results.java │ ├── objects │ ├── AccuracyMarker.java │ ├── AccuracyPopup.java │ ├── Circle.java │ └── TapZone.java │ ├── renderer │ └── WorldRenderer.java │ ├── screens │ ├── BeatmapReloadScreen.java │ ├── LiveOptionsScreen.java │ ├── MainMenuScreen.java │ ├── ResultsScreen.java │ ├── SettingsScreen.java │ ├── SongScreen.java │ ├── SongSelectionScreen.java │ └── SplashScreen.java │ └── util │ ├── Accuracy.java │ ├── SongUtils.java │ └── Tips.java ├── desktop ├── build.gradle └── src │ └── com │ └── fteams │ └── sstrain │ └── desktop │ ├── DesktopLauncher.java │ └── TextureSetup.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | /*/build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # IntelliJ files 30 | .idea/ 31 | *.iml 32 | *.ipr 33 | *.iws 34 | 35 | # assets 36 | /*/proguard* 37 | 38 | # trace files 39 | captures/ 40 | *.trace -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 kbz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # SSTrain 2 | An android rhythm game based on The Idolmaster: Cinderella Girls ~Starlight Stage~ in combination with elements from osu! 3 | 4 | Written in JAVA, using the [libgdx library](https://github.com/libgdx/libgdx) -------------------------------------------------------------------------------- /android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /android/assets/bigimages/main_menu_background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/bigimages/main_menu_background.jpg -------------------------------------------------------------------------------- /android/assets/bigimages/main_menu_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/bigimages/main_menu_background.png -------------------------------------------------------------------------------- /android/assets/bigimages/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/bigimages/splash.png -------------------------------------------------------------------------------- /android/assets/fonts/combo-font.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/combo-font.fnt -------------------------------------------------------------------------------- /android/assets/fonts/combo-font_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/combo-font_0.png -------------------------------------------------------------------------------- /android/assets/fonts/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/font.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small.fnt -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_00.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_01.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_02.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_03.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_04.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_05.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_06.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_07.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_08.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_09.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_10.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_11.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_12.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_13.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_14.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_15.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_16.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_17.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_18.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_19.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_20.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_21.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_22.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_23.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_24.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_25.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_26.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_27.png -------------------------------------------------------------------------------- /android/assets/fonts/jp-font-small_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/jp-font-small_28.png -------------------------------------------------------------------------------- /android/assets/fonts/result-font.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/result-font.fnt -------------------------------------------------------------------------------- /android/assets/fonts/result-font_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/result-font_0.png -------------------------------------------------------------------------------- /android/assets/fonts/settings-font.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/settings-font.fnt -------------------------------------------------------------------------------- /android/assets/fonts/settings-font_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/settings-font_0.png -------------------------------------------------------------------------------- /android/assets/fonts/song-font.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-font.fnt -------------------------------------------------------------------------------- /android/assets/fonts/song-font_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-font_0.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list.fnt -------------------------------------------------------------------------------- /android/assets/fonts/song-list_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_00.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_01.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_02.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_03.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_04.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_05.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_06.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_07.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_08.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_09.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_10.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_11.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_12.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_13.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_14.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_15.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_16.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_17.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_18.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_19.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_20.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_21.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_22.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_23.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_24.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_25.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_26.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_27.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_28.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_29.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_30.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_31.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_32.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_33.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_34.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_35.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_36.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_37.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_38.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_39.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_40.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_41.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_42.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_43.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_44.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_45.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_46.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_47.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_48.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_49.png -------------------------------------------------------------------------------- /android/assets/fonts/song-list_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/song-list_50.png -------------------------------------------------------------------------------- /android/assets/fonts/title-font.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/title-font.fnt -------------------------------------------------------------------------------- /android/assets/fonts/title-font_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/fonts/title-font_0.png -------------------------------------------------------------------------------- /android/assets/hitsounds/no_hit_tap.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/hitsounds/no_hit_tap.mp3 -------------------------------------------------------------------------------- /android/assets/hitsounds/swipe_great.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/hitsounds/swipe_great.mp3 -------------------------------------------------------------------------------- /android/assets/hitsounds/swipe_nice.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/hitsounds/swipe_nice.mp3 -------------------------------------------------------------------------------- /android/assets/hitsounds/swipe_perfect.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/hitsounds/swipe_perfect.mp3 -------------------------------------------------------------------------------- /android/assets/hitsounds/tap_great.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/hitsounds/tap_great.mp3 -------------------------------------------------------------------------------- /android/assets/hitsounds/tap_nice.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/hitsounds/tap_nice.mp3 -------------------------------------------------------------------------------- /android/assets/hitsounds/tap_perfect.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/hitsounds/tap_perfect.mp3 -------------------------------------------------------------------------------- /android/assets/images/acc_bad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/acc_bad.png -------------------------------------------------------------------------------- /android/assets/images/acc_good.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/acc_good.png -------------------------------------------------------------------------------- /android/assets/images/acc_great.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/acc_great.png -------------------------------------------------------------------------------- /android/assets/images/acc_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/acc_mark.png -------------------------------------------------------------------------------- /android/assets/images/acc_perfect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/acc_perfect.png -------------------------------------------------------------------------------- /android/assets/images/bad_late.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/bad_late.png -------------------------------------------------------------------------------- /android/assets/images/bad_soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/bad_soon.png -------------------------------------------------------------------------------- /android/assets/images/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/circle.png -------------------------------------------------------------------------------- /android/assets/images/circle_sim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/circle_sim.png -------------------------------------------------------------------------------- /android/assets/images/circle_swipe_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/circle_swipe_left.png -------------------------------------------------------------------------------- /android/assets/images/circle_swipe_left_sim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/circle_swipe_left_sim.png -------------------------------------------------------------------------------- /android/assets/images/circle_swipe_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/circle_swipe_right.png -------------------------------------------------------------------------------- /android/assets/images/circle_swipe_right_sim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/circle_swipe_right_sim.png -------------------------------------------------------------------------------- /android/assets/images/good_late.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/good_late.png -------------------------------------------------------------------------------- /android/assets/images/good_soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/good_soon.png -------------------------------------------------------------------------------- /android/assets/images/great_late.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/great_late.png -------------------------------------------------------------------------------- /android/assets/images/great_soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/great_soon.png -------------------------------------------------------------------------------- /android/assets/images/hold_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/hold_background.png -------------------------------------------------------------------------------- /android/assets/images/knob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/knob.png -------------------------------------------------------------------------------- /android/assets/images/knob_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/knob_after.png -------------------------------------------------------------------------------- /android/assets/images/knob_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/knob_before.png -------------------------------------------------------------------------------- /android/assets/images/menu_item_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/menu_item_down.png -------------------------------------------------------------------------------- /android/assets/images/menu_item_idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/menu_item_idle.png -------------------------------------------------------------------------------- /android/assets/images/miss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/miss.png -------------------------------------------------------------------------------- /android/assets/images/nice_late.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/nice_late.png -------------------------------------------------------------------------------- /android/assets/images/nice_soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/nice_soon.png -------------------------------------------------------------------------------- /android/assets/images/perfect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/perfect.png -------------------------------------------------------------------------------- /android/assets/images/selection_menu_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/selection_menu_background.png -------------------------------------------------------------------------------- /android/assets/images/selection_menu_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/selection_menu_selected.png -------------------------------------------------------------------------------- /android/assets/images/song_selection_menu_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/song_selection_menu_background.png -------------------------------------------------------------------------------- /android/assets/images/tap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/tap.png -------------------------------------------------------------------------------- /android/assets/images/tap_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/tap_pressed.png -------------------------------------------------------------------------------- /android/assets/images/tap_warn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/images/tap_warn.png -------------------------------------------------------------------------------- /android/assets/skins/menuSkin.json: -------------------------------------------------------------------------------- 1 | { 2 | "com.badlogic.gdx.graphics.g2d.BitmapFont": { 3 | "jp-font-small": {"file": "fonts/jp-font-small.fnt"}, 4 | "song-font": {"file": "fonts/song-font.fnt"}, 5 | "result-font": {"file": "fonts/result-font.fnt"}, 6 | "title" : {"file":"fonts/title-font.fnt"}, 7 | "settings-title-font" : {"file": "fonts/settings-font.fnt"}, 8 | "combo" : {"file":"fonts/combo-font.fnt"}, 9 | "song-list" : {"file":"fonts/song-list.fnt"} 10 | }, 11 | "com.badlogic.gdx.graphics.Color": { 12 | "green": { "a": 1, "b": 0, "g": 1, "r": 0 }, 13 | "white": { "a": 1, "b": 1, "g": 1, "r": 1 }, 14 | "red": { "a": 1, "b": 0, "g": 0, "r": 1 }, 15 | "black": { "a": 1, "b": 0, "g": 0, "r": 0 } 16 | }, 17 | "com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle": { 18 | "item1": {"up": "menu_item_idle", "down": "menu_item_down", "font": jp-font-small, "pressedOffsetY": -4} 19 | }, 20 | "com.badlogic.gdx.scenes.scene2d.ui.TextButton$TextButtonStyle": { 21 | "default": { "up": "selection_menu_background" , "down": "selection_menu_selected", "font": jp-font-small, "pressedOffsetY": -4 } 22 | }, 23 | "com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle": { 24 | "default": { "font": jp-font-small}, 25 | "settings_title":{font:settings-title-font, fontColor: black} 26 | "title": { "font": title, fontColor: black}, 27 | "results_title": { "font": song-list , "fontColor": black}, 28 | "results_song_title": { "font": song-list , "fontColor": black}, 29 | "version_label": { "font": song-list , "fontColor": black}, 30 | "song_style_score": { "font": song-font }, 31 | "song_style_combo": { "font": song-font }, 32 | "song_style_result": { "font": song-font, "fontColor": black }, 33 | "song_style_result_values": { "font": result-font, "fontColor": black}, 34 | "song_result_song_title": { "font": jp-font-small, "fontColor": black}, 35 | }, 36 | "com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle": { 37 | "diff_list": {"background": "song_selection_menu_background", "fontColorUnselected": black, "selection": "selection_menu_selected", "fontColorSelected": black, "font": song-list } 38 | }, 39 | "com.badlogic.gdx.scenes.scene2d.ui.ScrollPane$ScrollPaneStyle":{ 40 | "default": { } 41 | }, 42 | "com.badlogic.gdx.scenes.scene2d.ui.ProgressBar$ProgressBarStyle":{ 43 | "default-horizontal": { background: "selection_menu_background",knobBefore: "selection_menu_selected", knobAfter: "selection_menu_background"} 44 | }, 45 | "com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle":{ 46 | "default-horizontal": {background: "knob_after", knobBefore:"knob_before"} 47 | }, 48 | "com.badlogic.gdx.scenes.scene2d.ui.CheckBox$CheckBoxStyle":{ 49 | "default":{checkboxOn: "selection_menu_background", checkboxOff: "selection_menu_background", font: jp-font-small} 50 | } 51 | } -------------------------------------------------------------------------------- /android/assets/skins/splashSkin.json: -------------------------------------------------------------------------------- 1 | { 2 | "com.badlogic.gdx.scenes.scene2d.ui.ProgressBar$ProgressBarStyle":{ 3 | "default-horizontal": { background: "selection_menu_background",knobBefore: "selection_menu_selected", knobAfter: "selection_menu_background"} 4 | } 5 | } -------------------------------------------------------------------------------- /android/assets/textures/textures.pack.atlas: -------------------------------------------------------------------------------- 1 | 2 | textures.pack.png 3 | size: 512,512 4 | format: RGBA8888 5 | filter: Nearest,Nearest 6 | repeat: none 7 | acc_mark 8 | rotate: false 9 | xy: 506, 208 10 | size: 1, 50 11 | orig: 1, 50 12 | offset: 0, 0 13 | index: -1 14 | circle 15 | rotate: false 16 | xy: 2, 2 17 | size: 250, 250 18 | orig: 250, 250 19 | offset: 0, 0 20 | index: -1 21 | circle_sim 22 | rotate: false 23 | xy: 260, 260 24 | size: 250, 250 25 | orig: 250, 250 26 | offset: 0, 0 27 | index: -1 28 | circle_swipe_left 29 | rotate: false 30 | xy: 254, 2 31 | size: 250, 250 32 | orig: 250, 250 33 | offset: 0, 0 34 | index: -1 35 | hold_background 36 | rotate: false 37 | xy: 2, 254 38 | size: 256, 256 39 | orig: 256, 256 40 | offset: 0, 0 41 | index: -1 42 | selection_menu_background 43 | rotate: false 44 | xy: 509, 208 45 | size: 1, 50 46 | orig: 1, 50 47 | offset: 0, 0 48 | index: -1 49 | selection_menu_selected 50 | rotate: false 51 | xy: 506, 156 52 | size: 1, 50 53 | orig: 1, 50 54 | offset: 0, 0 55 | index: -1 56 | 57 | textures.pack2.png 58 | size: 512,512 59 | format: RGBA8888 60 | filter: Nearest,Nearest 61 | repeat: none 62 | circle_swipe_left_sim 63 | rotate: false 64 | xy: 2, 254 65 | size: 250, 250 66 | orig: 250, 250 67 | offset: 0, 0 68 | index: -1 69 | circle_swipe_right 70 | rotate: false 71 | xy: 2, 2 72 | size: 250, 250 73 | orig: 250, 250 74 | offset: 0, 0 75 | index: -1 76 | circle_swipe_right_sim 77 | rotate: false 78 | xy: 254, 254 79 | size: 250, 250 80 | orig: 250, 250 81 | offset: 0, 0 82 | index: -1 83 | tap 84 | rotate: false 85 | xy: 254, 2 86 | size: 250, 250 87 | orig: 250, 250 88 | offset: 0, 0 89 | index: -1 90 | 91 | textures.pack3.png 92 | size: 512,512 93 | format: RGBA8888 94 | filter: Nearest,Nearest 95 | repeat: none 96 | acc_bad 97 | rotate: false 98 | xy: 324, 452 99 | size: 50, 50 100 | orig: 50, 50 101 | offset: 0, 0 102 | index: -1 103 | acc_good 104 | rotate: false 105 | xy: 376, 452 106 | size: 50, 50 107 | orig: 50, 50 108 | offset: 0, 0 109 | index: -1 110 | acc_great 111 | rotate: false 112 | xy: 428, 452 113 | size: 50, 50 114 | orig: 50, 50 115 | offset: 0, 0 116 | index: -1 117 | acc_perfect 118 | rotate: false 119 | xy: 419, 62 120 | size: 50, 50 121 | orig: 50, 50 122 | offset: 0, 0 123 | index: -1 124 | bad_late 125 | rotate: false 126 | xy: 324, 420 127 | size: 65, 30 128 | orig: 65, 30 129 | offset: 0, 0 130 | index: -1 131 | bad_soon 132 | rotate: false 133 | xy: 439, 388 134 | size: 65, 30 135 | orig: 65, 30 136 | offset: 0, 0 137 | index: -1 138 | good_late 139 | rotate: false 140 | xy: 324, 83 141 | size: 93, 30 142 | orig: 93, 30 143 | offset: 0, 0 144 | index: -1 145 | good_soon 146 | rotate: false 147 | xy: 324, 51 148 | size: 93, 30 149 | orig: 93, 30 150 | offset: 0, 0 151 | index: -1 152 | great_late 153 | rotate: false 154 | xy: 324, 388 155 | size: 113, 30 156 | orig: 113, 30 157 | offset: 0, 0 158 | index: -1 159 | great_soon 160 | rotate: false 161 | xy: 391, 420 162 | size: 113, 30 163 | orig: 113, 30 164 | offset: 0, 0 165 | index: -1 166 | knob 167 | rotate: false 168 | xy: 480, 482 169 | size: 20, 20 170 | orig: 20, 20 171 | offset: 0, 0 172 | index: -1 173 | knob_after 174 | rotate: false 175 | xy: 480, 460 176 | size: 20, 20 177 | orig: 20, 20 178 | offset: 0, 0 179 | index: -1 180 | knob_before 181 | rotate: false 182 | xy: 484, 114 183 | size: 20, 20 184 | orig: 20, 20 185 | offset: 0, 0 186 | index: -1 187 | menu_item_down 188 | rotate: false 189 | xy: 2, 402 190 | size: 320, 100 191 | orig: 320, 100 192 | offset: 0, 0 193 | index: -1 194 | menu_item_idle 195 | rotate: false 196 | xy: 2, 34 197 | size: 320, 100 198 | orig: 320, 100 199 | offset: 0, 0 200 | index: -1 201 | miss 202 | rotate: false 203 | xy: 419, 41 204 | size: 90, 19 205 | orig: 90, 19 206 | offset: 0, 0 207 | index: -1 208 | nice_late 209 | rotate: false 210 | xy: 324, 19 211 | size: 93, 30 212 | orig: 93, 30 213 | offset: 0, 0 214 | index: -1 215 | nice_soon 216 | rotate: false 217 | xy: 2, 2 218 | size: 93, 30 219 | orig: 93, 30 220 | offset: 0, 0 221 | index: -1 222 | perfect 223 | rotate: false 224 | xy: 324, 115 225 | size: 158, 19 226 | orig: 158, 19 227 | offset: 0, 0 228 | index: -1 229 | tap_pressed 230 | rotate: false 231 | xy: 2, 150 232 | size: 250, 250 233 | orig: 250, 250 234 | offset: 0, 0 235 | index: -1 236 | tap_warn 237 | rotate: false 238 | xy: 254, 136 239 | size: 250, 250 240 | orig: 250, 250 241 | offset: 0, 0 242 | index: -1 243 | 244 | textures.pack4.png 245 | size: 64,64 246 | format: RGBA8888 247 | filter: Nearest,Nearest 248 | repeat: none 249 | song_selection_menu_background 250 | rotate: false 251 | xy: 2, 2 252 | size: 50, 50 253 | orig: 50, 50 254 | offset: 0, 0 255 | index: -1 256 | -------------------------------------------------------------------------------- /android/assets/textures/textures.pack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/textures/textures.pack.png -------------------------------------------------------------------------------- /android/assets/textures/textures.pack2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/textures/textures.pack2.png -------------------------------------------------------------------------------- /android/assets/textures/textures.pack3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/textures/textures.pack3.png -------------------------------------------------------------------------------- /android/assets/textures/textures.pack4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/assets/textures/textures.pack4.png -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | android { 2 | buildToolsVersion "23.0.1" 3 | compileSdkVersion 20 4 | sourceSets { 5 | main { 6 | manifest.srcFile 'AndroidManifest.xml' 7 | java.srcDirs = ['src'] 8 | aidl.srcDirs = ['src'] 9 | renderscript.srcDirs = ['src'] 10 | res.srcDirs = ['res'] 11 | assets.srcDirs = ['assets'] 12 | jniLibs.srcDirs = ['libs'] 13 | } 14 | 15 | instrumentTest.setRoot('tests') 16 | } 17 | } 18 | 19 | 20 | // called every time gradle gets executed, takes the native dependencies of 21 | // the natives configuration, and extracts them to the proper libs/ folders 22 | // so they get packed with the APK. 23 | task copyAndroidNatives() { 24 | file("libs/armeabi/").mkdirs(); 25 | file("libs/armeabi-v7a/").mkdirs(); 26 | file("libs/x86/").mkdirs(); 27 | 28 | configurations.natives.files.each { jar -> 29 | def outputDir = null 30 | if(jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a") 31 | if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi") 32 | if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86") 33 | if(outputDir != null) { 34 | copy { 35 | from zipTree(jar) 36 | into outputDir 37 | include "*.so" 38 | } 39 | } 40 | } 41 | } 42 | 43 | task run(type: Exec) { 44 | def path 45 | def localProperties = project.file("../local.properties") 46 | if (localProperties.exists()) { 47 | Properties properties = new Properties() 48 | localProperties.withInputStream { instr -> 49 | properties.load(instr) 50 | } 51 | def sdkDir = properties.getProperty('sdk.dir') 52 | if (sdkDir) { 53 | path = sdkDir 54 | } else { 55 | path = "$System.env.ANDROID_HOME" 56 | } 57 | } else { 58 | path = "$System.env.ANDROID_HOME" 59 | } 60 | 61 | def adb = path + "/platform-tools/adb" 62 | commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.fteams.sstrain.android/com.fteams.sstrain.android.AndroidLauncher' 63 | } 64 | 65 | // sets up the Android Eclipse project, using the old Ant based build. 66 | eclipse { 67 | // need to specify Java source sets explicitely, SpringSource Gradle Eclipse plugin 68 | // ignores any nodes added in classpath.file.withXml 69 | sourceSets { 70 | main { 71 | java.srcDirs "src", 'gen' 72 | } 73 | } 74 | 75 | jdt { 76 | sourceCompatibility = 1.6 77 | targetCompatibility = 1.6 78 | } 79 | 80 | classpath { 81 | plusConfigurations += [ project.configurations.compile ] 82 | containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES' 83 | } 84 | 85 | project { 86 | name = appName + "-android" 87 | natures 'com.android.ide.eclipse.adt.AndroidNature' 88 | buildCommands.clear(); 89 | buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder" 90 | buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder" 91 | buildCommand "org.eclipse.jdt.core.javabuilder" 92 | buildCommand "com.android.ide.eclipse.adt.ApkBuilder" 93 | } 94 | } 95 | 96 | // sets up the Android Idea project, using the old Ant based build. 97 | idea { 98 | module { 99 | sourceDirs += file("src"); 100 | scopes = [ COMPILE: [plus:[project.configurations.compile]]] 101 | 102 | iml { 103 | withXml { 104 | def node = it.asNode() 105 | def builder = NodeBuilder.newInstance(); 106 | builder.current = node; 107 | builder.component(name: "FacetManager") { 108 | facet(type: "android", name: "Android") { 109 | configuration { 110 | option(name: "UPDATE_PROPERTY_FILES", value:"true") 111 | } 112 | } 113 | } 114 | } 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /android/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/ic_launcher-web.png -------------------------------------------------------------------------------- /android/libs/armeabi-v7a/libgdx-box2d.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/armeabi-v7a/libgdx-box2d.so -------------------------------------------------------------------------------- /android/libs/armeabi-v7a/libgdx-freetype.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/armeabi-v7a/libgdx-freetype.so -------------------------------------------------------------------------------- /android/libs/armeabi-v7a/libgdx.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/armeabi-v7a/libgdx.so -------------------------------------------------------------------------------- /android/libs/armeabi/libgdx-box2d.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/armeabi/libgdx-box2d.so -------------------------------------------------------------------------------- /android/libs/armeabi/libgdx-freetype.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/armeabi/libgdx-freetype.so -------------------------------------------------------------------------------- /android/libs/armeabi/libgdx.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/armeabi/libgdx.so -------------------------------------------------------------------------------- /android/libs/x86/libgdx-box2d.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/x86/libgdx-box2d.so -------------------------------------------------------------------------------- /android/libs/x86/libgdx-freetype.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/x86/libgdx-freetype.so -------------------------------------------------------------------------------- /android/libs/x86/libgdx.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/libs/x86/libgdx.so -------------------------------------------------------------------------------- /android/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | -------------------------------------------------------------------------------- /android/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/android/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SSTrain 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /android/src/com/fteams/sstrain/android/AndroidLauncher.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.android; 2 | 3 | import android.content.pm.PackageInfo; 4 | import android.content.pm.PackageManager; 5 | import android.os.Bundle; 6 | 7 | import com.badlogic.gdx.backends.android.AndroidApplication; 8 | import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; 9 | import com.fteams.sstrain.SSTrain; 10 | import com.fteams.sstrain.config.GlobalConfiguration; 11 | 12 | public class AndroidLauncher extends AndroidApplication { 13 | @Override 14 | protected void onCreate (Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); 17 | config.useImmersiveMode = true; 18 | try { 19 | PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); 20 | GlobalConfiguration.appVersionName = pInfo.versionName; 21 | } catch (PackageManager.NameNotFoundException e) { 22 | e.printStackTrace(); 23 | } 24 | initialize(new SSTrain(), config); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } 5 | } 6 | dependencies { 7 | classpath 'com.android.tools.build:gradle:1.2.3' 8 | } 9 | } 10 | 11 | allprojects { 12 | apply plugin: "eclipse" 13 | apply plugin: "idea" 14 | 15 | version = '1.0' 16 | ext { 17 | appName = "sstrain" 18 | gdxVersion = '1.7.0' 19 | gsonVersion = '2.3.1' 20 | } 21 | 22 | repositories { 23 | mavenCentral() 24 | maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } 25 | maven { url "https://oss.sonatype.org/content/repositories/releases/" } 26 | } 27 | } 28 | 29 | project(":desktop") { 30 | apply plugin: "java" 31 | 32 | 33 | dependencies { 34 | compile project(":core") 35 | compile "com.google.code.gson:gson:$gsonVersion" 36 | compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" 37 | compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" 38 | compile "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" 39 | compile "com.badlogicgames.gdx:gdx-tools:$gdxVersion" 40 | } 41 | } 42 | 43 | project(":android") { 44 | apply plugin: "android" 45 | 46 | configurations { natives } 47 | 48 | dependencies { 49 | compile project(":core") 50 | compile "com.google.code.gson:gson:2.3.1" 51 | compile "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion" 52 | natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi" 53 | natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a" 54 | natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86" 55 | compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" 56 | natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi" 57 | natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi-v7a" 58 | natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86" 59 | } 60 | } 61 | 62 | project(":core") { 63 | apply plugin: "java" 64 | 65 | 66 | dependencies { 67 | compile "com.google.code.gson:gson:2.3.1" 68 | compile "com.badlogicgames.gdx:gdx:$gdxVersion" 69 | compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" 70 | } 71 | } 72 | 73 | tasks.eclipse.doLast { 74 | delete ".project" 75 | } -------------------------------------------------------------------------------- /core/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "java" 2 | 3 | project.sourceCompatibility = 1.7 4 | [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' 5 | 6 | sourceSets.main.java.srcDirs = [ "src/" ] 7 | 8 | 9 | eclipse.project { 10 | name = appName + "-core" 11 | } 12 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/SSTrain.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.fteams.sstrain.screens.SplashScreen; 5 | 6 | public class SSTrain extends Game { 7 | 8 | @Override 9 | public void create() { 10 | setScreen(new SplashScreen()); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/World.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain; 2 | 3 | import com.badlogic.gdx.utils.Array; 4 | import com.fteams.sstrain.assets.Assets; 5 | import com.fteams.sstrain.config.GlobalConfiguration; 6 | import com.fteams.sstrain.entities.Note; 7 | import com.fteams.sstrain.objects.AccuracyMarker; 8 | import com.fteams.sstrain.objects.AccuracyPopup; 9 | import com.fteams.sstrain.objects.Circle; 10 | import com.fteams.sstrain.objects.TapZone; 11 | import com.fteams.sstrain.util.SongUtils; 12 | 13 | public class World { 14 | int width; 15 | int height; 16 | 17 | public int combo; 18 | public boolean started; 19 | public boolean paused; 20 | public int offsetX; 21 | public int offsetY; 22 | 23 | private Array accuracyMarkers; 24 | private Array accuracyPopups; 25 | 26 | Array tapZones = new Array<>(); 27 | Array circles = new Array<>(); 28 | 29 | public float delay; 30 | 31 | public World() { 32 | createWorld(); 33 | } 34 | 35 | private void createWorld() { 36 | float x = 0f; 37 | float y = 0f; 38 | 39 | float h = 400; 40 | float w = 600; 41 | 42 | float radius = h * 0.065f; 43 | 44 | Double noteSpeed = SongUtils.getSpeedFromConfig(GlobalConfiguration.noteSpeed) / 1000.0; 45 | 46 | delay = Assets.selectedBeatmap.metadata.leadIn != null ? Assets.selectedBeatmap.metadata.leadIn : 0f; 47 | 48 | if (delay < noteSpeed) { 49 | delay += noteSpeed; 50 | } 51 | 52 | for (Note notesInfo : Assets.selectedBeatmap.notes) { 53 | 54 | // we create a copy which is modified based on the live options - speed / a-b repeat 55 | Note copy = copy(notesInfo); 56 | if (GlobalConfiguration.playbackMode != null && GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)) { 57 | if (GlobalConfiguration.aTime != null) { 58 | if (copy.timing < GlobalConfiguration.aTime) { 59 | continue; 60 | } 61 | } 62 | if (GlobalConfiguration.bTime != null) { 63 | if (copy.timing > GlobalConfiguration.bTime + 2f) { 64 | continue; 65 | } 66 | } 67 | } 68 | if (GlobalConfiguration.playbackRate != null) { 69 | copy.timing = copy.timing / GlobalConfiguration.playbackRate; 70 | 71 | } 72 | 73 | x = (copy.endPos - 3) * radius * 4; 74 | Circle mark = new Circle(x, 0, copy, noteSpeed, delay); 75 | circles.add(mark); 76 | } 77 | // System.out.println("Loaded: " + circles.size + " notes"); 78 | 79 | linkCircles(circles); 80 | linkSyncCircles(circles); 81 | 82 | circles.sort(); 83 | 84 | int zoneId = 1; 85 | tapZones = new Array<>(); 86 | 87 | for (int i = 0; i < 11; i++) { 88 | if (i % 2 == 0) 89 | continue; 90 | 91 | x = (i * 2 - 10) * radius; 92 | 93 | TapZone zone = new TapZone(x, -249.0f, zoneId++); 94 | tapZones.add(zone); 95 | } 96 | tapZones.sort(); 97 | this.accuracyMarkers = new Array<>(); 98 | this.accuracyPopups = new Array<>(); 99 | paused = false; 100 | } 101 | 102 | private Note copy(Note notesInfo) { 103 | Note copy = new Note(); 104 | copy.status = notesInfo.status; 105 | copy.timing = notesInfo.timing; 106 | copy.id = notesInfo.id; 107 | copy.nextNoteId = notesInfo.nextNoteId; 108 | copy.prevNoteId = notesInfo.prevNoteId; 109 | copy.endPos = notesInfo.endPos; 110 | copy.startPos = notesInfo.startPos; 111 | copy.groupId = notesInfo.groupId; 112 | copy.sync = notesInfo.sync; 113 | copy.type = notesInfo.type; 114 | return copy; 115 | } 116 | 117 | private void linkCircles(Array circles) { 118 | for (int i = 0; i < circles.size; i++) { 119 | Circle current = circles.get(i); 120 | if (current.note.nextNoteId == 0) 121 | continue; 122 | 123 | Circle next = findNext(circles, current.note.nextNoteId); 124 | 125 | // next can be null in A-B repeat mode since not all the circles are loaded. 126 | if (next != null) { 127 | current.setNextNote(next); 128 | current.nextNote.setPreviousNote(current); 129 | } 130 | // 2 side relation 131 | } 132 | } 133 | 134 | private Circle findNext(Array circles, Long nextNoteId) { 135 | for (Circle circle : circles) { 136 | if (circle.note.id.equals(nextNoteId)) 137 | return circle; 138 | } 139 | return null; 140 | } 141 | 142 | private void linkSyncCircles(Array circles) { 143 | for (int i = 0; i < circles.size; i++) { 144 | Circle mark = circles.get(i); 145 | if (mark.note.sync != 0) { 146 | Circle next = findNextSync(circles, mark.note.timing, mark.note.id); 147 | if (next != null) { 148 | mark.nextSyncNote = next; 149 | } 150 | } 151 | } 152 | 153 | } 154 | 155 | private Circle findNextSync(Array circles, Double timing, Long id) { 156 | for (int i = 0; i < circles.size; i++) { 157 | Circle circle = circles.get(i); 158 | if (circle.note.timing.equals(timing) && circle.note.id > id) { 159 | return circle; 160 | } 161 | } 162 | return null; 163 | } 164 | 165 | public Array getTapZones() { 166 | return tapZones; 167 | } 168 | 169 | public Array getCircles() { 170 | return circles; 171 | } 172 | 173 | public Array getAccuracyMarkers() { 174 | return accuracyMarkers; 175 | } 176 | 177 | public Array getAccuracyPopups() { 178 | return accuracyPopups; 179 | } 180 | 181 | public void setSize(int width, int height, int offsetX, int offsetY) { 182 | this.width = width; 183 | this.height = height; 184 | this.offsetX = offsetX; 185 | this.offsetY = offsetY; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/assets/Assets.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.assets; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.assets.AssetManager; 5 | import com.badlogic.gdx.assets.loaders.resolvers.ExternalFileHandleResolver; 6 | import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver; 7 | import com.badlogic.gdx.audio.Sound; 8 | import com.badlogic.gdx.graphics.Texture; 9 | import com.badlogic.gdx.graphics.g2d.BitmapFont; 10 | import com.badlogic.gdx.graphics.g2d.TextureAtlas; 11 | import com.badlogic.gdx.scenes.scene2d.ui.Skin; 12 | import com.badlogic.gdx.utils.Array; 13 | import com.fteams.sstrain.entities.BaseMetadata; 14 | import com.fteams.sstrain.entities.Beatmap; 15 | import com.fteams.sstrain.entities.BeatmapGroup; 16 | import com.fteams.sstrain.entities.Metadata; 17 | 18 | import java.util.HashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | public class Assets { 23 | 24 | public static AssetManager internalManager = new AssetManager(new InternalFileHandleResolver()); 25 | public static AssetManager externalManager = new AssetManager(new ExternalFileHandleResolver()); 26 | 27 | static { 28 | externalManager.setLoader(List.class, new SimplifiedBeatmapLoader(new ExternalFileHandleResolver())); 29 | } 30 | 31 | public static final String BEATMAP_HOME = "sstrain/beatmaps/"; 32 | public static final String SOUNDFILES_HOME = "sstrain/soundfiles/"; 33 | 34 | public static Beatmap selectedBeatmap; 35 | public static BeatmapGroup selectedGroup; 36 | 37 | public static TextureAtlas atlas; 38 | 39 | public static Skin menuSkin; 40 | public static Sound noHitTapSound; 41 | public static Sound niceTapSound; 42 | public static Sound greatTapSound; 43 | public static Sound perfectTapSound; 44 | public static Sound niceSwipeSound; 45 | public static Sound greatSwipeSound; 46 | public static Sound perfectSwipeSound; 47 | 48 | public static BitmapFont font; 49 | public static BitmapFont songFont; 50 | 51 | public static Texture mainMenuBackgroundTexture; 52 | public static Texture holdBG; 53 | 54 | public static Array songGroup; 55 | 56 | // In here we'll put everything that needs to be loaded in this format: 57 | // manager.load("file location in assets", fileType.class); 58 | // 59 | // libGDX AssetManager currently supports: Pixmap, Texture, BitmapFont, 60 | // TextureAtlas, TiledAtlas, TiledMapRenderer, Music and Sound. 61 | public static void queueLoading() { 62 | internalManager.load("textures/textures.pack.atlas", TextureAtlas.class); 63 | internalManager.load("hitsounds/no_hit_tap.mp3", Sound.class); 64 | internalManager.load("hitsounds/tap_nice.mp3", Sound.class); 65 | internalManager.load("hitsounds/tap_great.mp3", Sound.class); 66 | internalManager.load("hitsounds/tap_perfect.mp3", Sound.class); 67 | internalManager.load("hitsounds/swipe_nice.mp3", Sound.class); 68 | internalManager.load("hitsounds/swipe_great.mp3", Sound.class); 69 | internalManager.load("hitsounds/swipe_perfect.mp3", Sound.class); 70 | internalManager.load("bigimages/main_menu_background.jpg", Texture.class); 71 | internalManager.load("images/hold_background.png", Texture.class); 72 | internalManager.load("fonts/combo-font.fnt", BitmapFont.class); 73 | internalManager.load("fonts/song-font.fnt", BitmapFont.class); 74 | reloadBeatmaps(); 75 | } 76 | 77 | // thanks to libgdx, the manager will not actually load maps which were already loaded, 78 | // so if the same file comes again, it will be skipped 79 | public static void reloadBeatmaps() { 80 | if (Gdx.files.absolute(Gdx.files.getExternalStoragePath() + BEATMAP_HOME).exists()) { 81 | for (String fileName : Gdx.files.absolute(Gdx.files.getExternalStoragePath() + BEATMAP_HOME).file().list()) { 82 | String fullPath = Gdx.files.getExternalStoragePath() + BEATMAP_HOME + fileName; 83 | // if for any reason the user placed .osu/.osz files in the datafiles, we process them 84 | if (Gdx.files.absolute(fullPath).isDirectory() || (!fileName.endsWith(".json"))) 85 | continue; 86 | 87 | externalManager.load(BEATMAP_HOME + fileName, List.class); 88 | } 89 | } else { 90 | (Gdx.files.absolute(Gdx.files.getExternalStoragePath() + "beatmaps")).mkdirs(); 91 | (Gdx.files.absolute(Gdx.files.getExternalStoragePath() + BEATMAP_HOME)).mkdirs(); 92 | (Gdx.files.absolute(Gdx.files.getExternalStoragePath() + SOUNDFILES_HOME)).mkdirs(); 93 | } 94 | } 95 | 96 | // unlike the simple reload, in the hard reload we unload everything from the external manager 97 | // and force a reload of the beatmaps - this will cause .osz files which weren't extracted 98 | // to be processed, .osu files to be converted and music files within the .osz packages 99 | // to be copied over to the /beatmaps/soundfiles/ folder. 100 | public static void hardReloadBeatmaps() { 101 | selectedBeatmap = null; 102 | selectedGroup = null; 103 | externalManager.clear(); 104 | reloadBeatmaps(); 105 | } 106 | 107 | //In here we'll create our skin, so we only have to create it once. 108 | public static void setMenuSkin() { 109 | if (menuSkin == null) 110 | menuSkin = new Skin(Gdx.files.internal("skins/menuSkin.json"), internalManager.get("textures/textures.pack.atlas", TextureAtlas.class)); 111 | } 112 | 113 | public static void setTextures() { 114 | if (atlas == null) 115 | atlas = internalManager.get("textures/textures.pack.atlas"); 116 | 117 | if (mainMenuBackgroundTexture == null) 118 | mainMenuBackgroundTexture = internalManager.get("bigimages/main_menu_background.jpg"); 119 | 120 | if (holdBG == null) 121 | holdBG = internalManager.get("images/hold_background.png"); 122 | } 123 | 124 | public static void setFonts() { 125 | if (font == null) { 126 | font = internalManager.get("fonts/combo-font.fnt"); 127 | } 128 | if (songFont == null) { 129 | songFont= internalManager.get("fonts/song-font.fnt"); 130 | } 131 | 132 | } 133 | 134 | public static void setHitsounds() { 135 | if (noHitTapSound == null) 136 | noHitTapSound = internalManager.get("hitsounds/no_hit_tap.mp3"); 137 | if (niceTapSound == null) 138 | niceTapSound = internalManager.get("hitsounds/tap_nice.mp3"); 139 | if (greatTapSound == null) 140 | greatTapSound = internalManager.get("hitsounds/tap_great.mp3"); 141 | if (perfectTapSound == null) 142 | perfectTapSound = internalManager.get("hitsounds/tap_perfect.mp3"); 143 | if (niceSwipeSound == null) 144 | niceSwipeSound = internalManager.get("hitsounds/swipe_nice.mp3"); 145 | if (greatSwipeSound == null) 146 | greatSwipeSound = internalManager.get("hitsounds/swipe_great.mp3"); 147 | if (perfectSwipeSound == null) 148 | perfectSwipeSound = internalManager.get("hitsounds/swipe_perfect.mp3"); 149 | } 150 | 151 | @SuppressWarnings("unchecked") 152 | public static void setSongs() { 153 | if (songGroup == null) { 154 | songGroup = new Array<>(); 155 | } else { 156 | songGroup.clear(); 157 | } 158 | 159 | Array assets = externalManager.getAssetNames(); 160 | Map groupMap = new HashMap<>(); 161 | 162 | for (String string : assets) { 163 | List beatmaps = externalManager.get(string, List.class); 164 | if (!beatmaps.isEmpty()) { 165 | Metadata metadata = beatmaps.get(0).metadata; 166 | Long liveId = metadata.id; 167 | if (groupMap.get(liveId) == null) { 168 | BeatmapGroup group = new BeatmapGroup(); 169 | group.metadata = new BaseMetadata(); 170 | group.metadata.id = metadata.id; 171 | group.metadata.composer = metadata.composer; 172 | group.metadata.lyricist = metadata.lyricist; 173 | group.metadata.songFile = metadata.songFile; 174 | group.metadata.songName = metadata.songName; 175 | group.metadata.attribute = metadata.attribute; 176 | group.metadata.duration = metadata.duration; 177 | group.beatmaps = new Array<>(); 178 | groupMap.put(liveId, group); 179 | } 180 | 181 | BeatmapGroup group = groupMap.get(liveId); 182 | for (Beatmap beatmap : beatmaps) { 183 | group.beatmaps.add(beatmap); 184 | } 185 | group.beatmaps.sort(); 186 | } 187 | } 188 | for (Long liveId : groupMap.keySet()) { 189 | songGroup.add(groupMap.get(liveId)); 190 | } 191 | songGroup.sort(); 192 | } 193 | 194 | public static boolean update() { 195 | return internalManager.update() && externalManager.update(); 196 | } 197 | 198 | public static float getProgress() { 199 | return (internalManager.getProgress() + externalManager.getProgress()) / 2; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/assets/SimplifiedBeatmapLoader.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.assets; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.assets.AssetDescriptor; 5 | import com.badlogic.gdx.assets.AssetLoaderParameters; 6 | import com.badlogic.gdx.assets.AssetManager; 7 | import com.badlogic.gdx.assets.loaders.AsynchronousAssetLoader; 8 | import com.badlogic.gdx.assets.loaders.FileHandleResolver; 9 | import com.badlogic.gdx.files.FileHandle; 10 | import com.badlogic.gdx.utils.Array; 11 | import com.fteams.sstrain.entities.Beatmap; 12 | import com.fteams.sstrain.entities.Metadata; 13 | import com.fteams.sstrain.entities.Note; 14 | import com.fteams.sstrain.util.SongUtils; 15 | import com.google.gson.Gson; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | public class SimplifiedBeatmapLoader extends AsynchronousAssetLoader { 21 | private List beatmaps; 22 | 23 | public SimplifiedBeatmapLoader(FileHandleResolver resolver) { 24 | super(resolver); 25 | } 26 | 27 | @Override 28 | public void loadAsync(AssetManager manager, String fileName, FileHandle file, BeatmapParameter parameter) { 29 | beatmaps = new ArrayList<>(); 30 | if (fileName.endsWith(".json")) { 31 | loadAsyncStandard(manager, fileName, file, parameter); 32 | } 33 | } 34 | 35 | private void loadAsyncStandard(AssetManager manager, String fileName, FileHandle file, BeatmapParameter parameter) { 36 | 37 | FileHandle handle = resolve(fileName); 38 | String jsonDefinition = handle.readString("UTF-8"); 39 | Beatmap info; 40 | try { 41 | info = new Gson().fromJson(jsonDefinition, Beatmap.class); 42 | info.metadata.fileName = fileName; 43 | beatmaps.add(info); 44 | } catch (Exception e) { 45 | // something went wrong. 46 | e.printStackTrace(); 47 | Gdx.app.error("FILE_LOAD", "Failed to load beatmap from file: "+ fileName); 48 | } 49 | } 50 | 51 | @Override 52 | public Array getDependencies(String fileName, FileHandle file, BeatmapParameter parameter) { 53 | return null; 54 | } 55 | 56 | @Override 57 | public List loadSync(AssetManager manager, String fileName, FileHandle file, BeatmapParameter parameter) { 58 | return beatmaps; 59 | } 60 | 61 | public class BeatmapParameter extends AssetLoaderParameters { 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/config/GlobalConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.config; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.Preferences; 5 | import com.fteams.sstrain.util.SongUtils; 6 | 7 | public class GlobalConfiguration { 8 | 9 | // package info 10 | public static String appVersionName; 11 | 12 | public static int songVolume; 13 | public static int feedbackVolume; 14 | // offset in milliseconds 15 | public static int offset; 16 | public static int inputOffset; 17 | public static int noteSpeed; 18 | public static int overallDifficulty; 19 | // path to beatmaps 20 | public static String pathToBeatmaps; 21 | public static boolean playHintSounds; 22 | public static int sortOrder; 23 | // sorting related 24 | public static int sortMode; 25 | 26 | // display the line in the live screen 27 | public static boolean displayLine; 28 | 29 | // sync config 30 | public static int syncMode; 31 | 32 | public final static int BASE_HEIGHT = 720; 33 | 34 | // not stored/remembered variables: 35 | public static Float playbackRate; 36 | public static Integer playbackMode; 37 | public static Float aTime; 38 | public static Float bTime; 39 | 40 | 41 | public static void loadConfiguration() { 42 | Preferences prefs = Gdx.app.getPreferences("ss_train_config"); 43 | offset = prefs.getInteger("offset", 0); 44 | inputOffset = prefs.getInteger("input_offset", 0); 45 | songVolume = prefs.getInteger("song_vol", 100); 46 | feedbackVolume = prefs.getInteger("feedback_vol", 100); 47 | pathToBeatmaps = prefs.getString("path_to_beatmaps", Gdx.files.getExternalStoragePath() + "sstrain"); 48 | playHintSounds = prefs.getBoolean("play_hint_sounds", false); 49 | noteSpeed = prefs.getInteger("note_speed", 6); 50 | overallDifficulty = prefs.getInteger("overall_difficulty", 7); 51 | displayLine = prefs.getBoolean("display_line", true); 52 | // default to song name sorting 53 | sortMode = prefs.getInteger("sorting_mode", SongUtils.SORTING_MODE_SONG_NAME); 54 | // default ascending order 55 | sortOrder = prefs.getInteger("sorting_order", SongUtils.SORTING_MODE_ASCENDING); 56 | // sync mode 57 | syncMode = prefs.getInteger("sync_mode", SongUtils.SYNC_MODE_1); 58 | 59 | } 60 | 61 | public static void storeConfiguration() { 62 | Preferences prefs = Gdx.app.getPreferences("ss_train_config"); 63 | prefs.putInteger("offset", offset); 64 | prefs.putInteger("input_offset", inputOffset); 65 | prefs.putInteger("song_vol", songVolume); 66 | prefs.putInteger("feedback_vol", feedbackVolume); 67 | prefs.putString("path_to_beatmaps", pathToBeatmaps); 68 | prefs.putBoolean("play_hint_sounds", playHintSounds); 69 | prefs.putInteger("note_speed", noteSpeed); 70 | prefs.putInteger("overall_difficulty", overallDifficulty); 71 | prefs.putBoolean("display_line", displayLine); 72 | prefs.putInteger("sorting_mode", sortMode); 73 | prefs.putInteger("sorting_order", sortOrder); 74 | prefs.putInteger("sync_mode", syncMode); 75 | prefs.flush(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/controller/Crossfader.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.controller; 2 | 3 | import com.badlogic.gdx.audio.Music; 4 | import com.badlogic.gdx.math.MathUtils; 5 | import com.badlogic.gdx.utils.Disposable; 6 | import com.fteams.sstrain.config.GlobalConfiguration; 7 | 8 | public class Crossfader implements Disposable { 9 | private static final float fadeRate = 0.25f; 10 | 11 | private Music fadingIn = null; 12 | private Music fadingOut = null; 13 | private Music enqueued = null; 14 | private boolean enqueuedStop = false; 15 | private float volume; 16 | 17 | public Crossfader() { 18 | volume = GlobalConfiguration.songVolume / 100.0f; 19 | } 20 | 21 | private void disposeOf(Music mus) { 22 | if(mus == null) 23 | return;; 24 | 25 | if(mus.isPlaying()) 26 | mus.stop(); 27 | 28 | mus.dispose(); 29 | } 30 | 31 | private void initMusic(Music mus) { 32 | mus.setLooping(true); 33 | mus.setVolume(0.0f); 34 | mus.play(); 35 | } 36 | 37 | @Override 38 | public void dispose() { 39 | disposeOf(fadingIn); 40 | disposeOf(fadingOut); 41 | disposeOf(enqueued); 42 | fadingIn = null; 43 | fadingOut = null; 44 | enqueued = null; 45 | } 46 | 47 | private void fadeIn() { 48 | if(enqueued != null) 49 | initMusic(enqueued); 50 | 51 | disposeOf(fadingOut); 52 | fadingOut = fadingIn; 53 | fadingIn = enqueued; 54 | enqueued = null; 55 | enqueuedStop = false; 56 | } 57 | 58 | private void tryFadeIn() { 59 | if(enqueued != null || enqueuedStop) 60 | fadeIn(); 61 | } 62 | 63 | public void enqueue(Music mus) { 64 | disposeOf(enqueued); 65 | enqueued = mus; 66 | enqueuedStop = (mus == null); 67 | 68 | if(fadingOut == null) 69 | fadeIn(); 70 | } 71 | 72 | public void update(float delta) { 73 | final float volStep = volume * delta * fadeRate; 74 | 75 | if(fadingIn != null && !fadingIn.isPlaying()) { 76 | fadingIn.dispose(); 77 | fadingIn = null; 78 | } 79 | 80 | if(fadingOut != null && !fadingOut.isPlaying()) { 81 | fadingOut.dispose(); 82 | fadingOut = null; 83 | tryFadeIn(); 84 | } 85 | 86 | if(fadingOut != null) { 87 | final float newVol = MathUtils.clamp(fadingOut.getVolume() - volStep, 0f, volume); 88 | if(newVol > 0f) 89 | fadingOut.setVolume(newVol); 90 | else { 91 | disposeOf(fadingOut); 92 | fadingOut = null; 93 | tryFadeIn(); 94 | } 95 | } 96 | 97 | if(fadingIn != null && fadingIn.getVolume() < volume) { 98 | fadingIn.setVolume(MathUtils.clamp(fadingIn.getVolume() + volStep, 0f, volume)); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/controller/SongLoader.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.controller; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.audio.Music; 5 | import com.badlogic.gdx.files.FileHandle; 6 | import com.fteams.sstrain.assets.Assets; 7 | 8 | public class SongLoader { 9 | private static final String SONGFILE_PREFIX = "sstrain/soundfiles/"; 10 | private static final String[] SONGFILE_PRIO = {".ogg", ".wav", ".mp3"}; 11 | 12 | public static Music loadSongByName(String name) { 13 | try { 14 | // try loading the file 15 | FileHandle handle = Gdx.files.absolute(Gdx.files.getExternalStoragePath() + SONGFILE_PREFIX + name); 16 | return Gdx.audio.newMusic(handle); 17 | } catch(Exception e) { 18 | // if it failed, try loading the file with a different extension (in case the extension was not specified) 19 | FileHandle handle = null; 20 | String path = Gdx.files.getExternalStoragePath() + SONGFILE_PREFIX + name.replaceAll("\\.[a-zA-Z0-9]+$",""); 21 | 22 | for(String ext : SONGFILE_PRIO) { 23 | try { 24 | handle = Gdx.files.absolute(path + ext); 25 | return Gdx.audio.newMusic(handle); 26 | } catch(Exception e2) { 27 | continue; 28 | } 29 | } 30 | 31 | return null; 32 | } 33 | } 34 | 35 | public static Music loadSongFile() { 36 | Music result = null; 37 | 38 | if(Assets.selectedBeatmap.metadata.songFile != null) 39 | result = loadSongByName(Assets.selectedBeatmap.metadata.songFile); 40 | 41 | if(result == null) 42 | result = loadSongByName(Assets.selectedBeatmap.metadata.songName); 43 | 44 | return result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/entities/BaseMetadata.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.entities; 2 | 3 | public class BaseMetadata { 4 | public String songName; 5 | public String songFile; 6 | public String composer; 7 | public String lyricist; 8 | public Long id; 9 | public Double duration; 10 | public Long attribute; 11 | public Long leadIn; 12 | public String fileName; 13 | } 14 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/entities/Beatmap.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.entities; 2 | 3 | import java.util.List; 4 | 5 | public class Beatmap implements Comparable{ 6 | public Metadata metadata; 7 | public List notes; 8 | 9 | @Override 10 | public int compareTo(Beatmap o) { 11 | if (metadata == null) 12 | return 1; 13 | if (o.metadata == null) 14 | return -1; 15 | return metadata.compareTo(o.metadata); 16 | } 17 | 18 | public String toString() 19 | { 20 | return (metadata.difficultyName == null ? "" + metadata.difficulty + "*" : ""+metadata.difficultyName+""); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/entities/BeatmapGroup.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.entities; 2 | 3 | import com.badlogic.gdx.utils.Array; 4 | import com.fteams.sstrain.config.GlobalConfiguration; 5 | import com.fteams.sstrain.util.SongUtils; 6 | 7 | public class BeatmapGroup implements Comparable{ 8 | public BaseMetadata metadata; 9 | public Array beatmaps; 10 | 11 | public String toString() 12 | { 13 | return "["+SongUtils.getAttribute(metadata.attribute) + "] "+ metadata.songName.replaceAll("\\\\n", " "); 14 | } 15 | 16 | @Override 17 | public int compareTo(BeatmapGroup o) { 18 | if (GlobalConfiguration.sortOrder == SongUtils.SORTING_MODE_ASCENDING) { 19 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_FILE_NAME) 20 | return metadata.songFile.compareTo(o.metadata.songFile); 21 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_SONG_NAME) 22 | return metadata.songName.compareTo(o.metadata.songName); 23 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_ATTRIBUTE) 24 | return metadata.attribute.compareTo(o.metadata.attribute); 25 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_SONG_ID) 26 | return metadata.id.intValue() - o.metadata.id.intValue(); 27 | } 28 | else if (GlobalConfiguration.sortOrder == SongUtils.SORTING_MODE_DESCENDING){ 29 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_FILE_NAME) 30 | return -metadata.songFile.compareTo(o.metadata.songFile); 31 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_SONG_NAME) 32 | return -metadata.songName.compareTo(o.metadata.songName); 33 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_ATTRIBUTE) 34 | return -metadata.attribute.compareTo(o.metadata.attribute); 35 | if (GlobalConfiguration.sortMode == SongUtils.SORTING_MODE_SONG_ID) 36 | return -metadata.id.intValue() - o.metadata.id.intValue(); 37 | return -Double.compare(metadata.duration, o.metadata.duration); 38 | } 39 | return Double.compare(metadata.duration, o.metadata.duration); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/entities/Metadata.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.entities; 2 | 3 | import com.fteams.sstrain.util.SongUtils; 4 | 5 | public class Metadata extends BaseMetadata{ 6 | public String difficultyName; 7 | public Long difficulty; 8 | 9 | public int compareTo(Metadata metadata) { 10 | if (songName.equals(metadata.songName)) 11 | { 12 | if (difficulty.equals(metadata.difficulty)) 13 | { 14 | return difficultyName.compareTo(metadata.difficultyName); 15 | } 16 | else return SongUtils.compare(difficulty, metadata.difficulty); 17 | } 18 | return songName.compareTo(metadata.songName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/entities/Note.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.entities; 2 | 3 | public class Note { 4 | public Long id; 5 | public Double timing; 6 | // for types, refer to SongUtils 7 | public Long type; 8 | // origin point [1-5] 9 | public Long startPos; 10 | // tap zone [1-5] 11 | public Long endPos; 12 | public Long status; 13 | // indicates if there's another note with the same timestamp and tags them as >simultaneous< 14 | public Long sync; 15 | // used in linked slides to draw beams between notes 16 | public Long groupId; 17 | // for easy access in groups and holds 18 | public Long nextNoteId; 19 | public Long prevNoteId; 20 | } 21 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/entities/Results.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.entities; 2 | 3 | 4 | import com.fteams.sstrain.config.GlobalConfiguration; 5 | import com.fteams.sstrain.util.Accuracy; 6 | import com.fteams.sstrain.util.SongUtils; 7 | 8 | public class Results { 9 | public static Integer combo; 10 | public static float accuracy; 11 | public static int miss; 12 | public static int bads; 13 | public static int goods; 14 | public static int greats; 15 | public static int perfects; 16 | public static float maxAccuracy; 17 | public static float minAccuracy; 18 | public static float normalizedAccuracy; 19 | public static float unstableRating; 20 | 21 | public static void clear() { 22 | combo = 0; 23 | accuracy = 0; 24 | miss = 0; 25 | bads = 0; 26 | goods = 0; 27 | greats = 0; 28 | perfects = 0; 29 | maxAccuracy = 0; 30 | minAccuracy = 0; 31 | normalizedAccuracy = 0; 32 | unstableRating = 0; 33 | } 34 | 35 | 36 | public static float getAccuracyMultiplierForAccuracy(Accuracy accuracy) { 37 | if (accuracy == Accuracy.PERFECT) { 38 | return 1.0f; 39 | } 40 | if (accuracy == Accuracy.GREAT) { 41 | return 0.75f; 42 | } 43 | if (accuracy == Accuracy.NICE) { 44 | return 0.50f; 45 | } 46 | if (accuracy == Accuracy.BAD) { 47 | return 0.25f; 48 | } 49 | return 0f; 50 | } 51 | 52 | public static Accuracy getAccuracyFor(float timing) { 53 | // Perfect 54 | if (Math.abs(timing) < SongUtils.overallDiffPerfect[GlobalConfiguration.overallDifficulty] / 1000) { 55 | return Accuracy.PERFECT; 56 | } 57 | if (Math.abs(timing) < SongUtils.overallDiffGreat[GlobalConfiguration.overallDifficulty]/ 1000) { 58 | return Accuracy.GREAT; 59 | } 60 | if (Math.abs(timing) < SongUtils.overallDiffNice[GlobalConfiguration.overallDifficulty]/ 1000) { 61 | return Accuracy.NICE; 62 | } 63 | if (Math.abs(timing) < SongUtils.overallDiffBad[GlobalConfiguration.overallDifficulty]/ 1000) { 64 | return Accuracy.BAD; 65 | } 66 | return Accuracy.MISS; 67 | } 68 | 69 | // holds and swipes have bigger windows 70 | public static Accuracy getAccuracyForSwipesAndHolds(float timing) { 71 | return getAccuracyFor(timing * SWIPE_HOLD_MULTIPLIER); 72 | } 73 | 74 | public final static float SWIPE_HOLD_MULTIPLIER = 0.5f; 75 | } 76 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/objects/AccuracyMarker.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.objects; 2 | 3 | // represents the osu-like marker which displays the time 4 | // delay between the expected tap and the actual tap 5 | public class AccuracyMarker { 6 | // stay on screen for 5 seconds 7 | public float displayTime = 5f; 8 | private float time; 9 | public boolean display; 10 | 11 | public AccuracyMarker(float time) { 12 | this.time = time; 13 | display = true; 14 | } 15 | 16 | public void update(float delta) { 17 | if (!display) 18 | return; 19 | displayTime -= delta; 20 | if (displayTime <= 0) { 21 | display = false; 22 | } 23 | } 24 | 25 | public float getAlpha() { 26 | float alpha = displayTime / 5f; 27 | return (alpha >= 1f ? 1f : (alpha <= 0f ? 0f : alpha)); 28 | } 29 | 30 | public float getTime() { 31 | return time; 32 | } 33 | } -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/objects/AccuracyPopup.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.objects; 2 | 3 | import com.fteams.sstrain.util.Accuracy; 4 | 5 | // represents the accuracy pop-up that pops up on screen on tap 6 | // and reads PERFECT / GREAT / NICE / BAD / MISS 7 | public class AccuracyPopup { 8 | 9 | private float screenTime; 10 | public boolean show; 11 | public Accuracy accuracy; 12 | public boolean soon; 13 | public boolean fadeIn; 14 | public float fadeTime = 0.25f; 15 | 16 | public AccuracyPopup(Accuracy accuracy, boolean soon) { 17 | this.screenTime = 0.5f; 18 | this.accuracy = accuracy; 19 | this.soon = soon; 20 | fadeIn = true; 21 | fadeTime = 0.25f; 22 | show = true; 23 | } 24 | 25 | public void update(float delta) { 26 | screenTime -= delta; 27 | fadeTime -= delta; 28 | if (screenTime <= 0 && show) { 29 | show = false; 30 | } 31 | if (fadeTime <= 0 && fadeIn) { 32 | fadeIn = false; 33 | } 34 | } 35 | 36 | public float getSize() { 37 | return 1f + (0.5f - screenTime); 38 | } 39 | 40 | public float getAlpha() { 41 | float alpha = fadeIn ? 0.75f + screenTime : screenTime / 0.25f; 42 | return (alpha >= 1f ? 1f : (alpha <= 0f ? 0f : alpha)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/objects/Circle.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.objects; 2 | 3 | import com.badlogic.gdx.math.MathUtils; 4 | import com.badlogic.gdx.math.Vector2; 5 | import com.fteams.sstrain.assets.Assets; 6 | import com.fteams.sstrain.config.GlobalConfiguration; 7 | import com.fteams.sstrain.entities.Note; 8 | import com.fteams.sstrain.entities.Results; 9 | import com.fteams.sstrain.util.Accuracy; 10 | import com.fteams.sstrain.util.SongUtils; 11 | 12 | public class Circle implements Comparable { 13 | 14 | public Note note; 15 | 16 | public Vector2 origin = new Vector2(); 17 | public Vector2 position = new Vector2(); 18 | Vector2 velocity = new Vector2(); 19 | 20 | public boolean hold; 21 | public Long destination; 22 | Double speed; 23 | public Circle nextNote; 24 | public Circle previousNote; 25 | public Circle nextSyncNote; 26 | 27 | float spawnTime; 28 | float despawnTime; 29 | float startWaitTime; 30 | float endWaitTime; 31 | 32 | float size; 33 | 34 | public float hitTime; 35 | float previousTime; 36 | long previousSystemTime; 37 | 38 | public boolean visible; 39 | public boolean holding; 40 | public boolean waiting; 41 | public boolean soundPlayed; 42 | public boolean miss; 43 | 44 | public float alpha = 1f; 45 | 46 | public Accuracy accuracy; 47 | public boolean processed; 48 | 49 | // holds consist of 2 notes out of which the first one must have type 2 50 | // the second one will either be a type 2 or a type 1 with some effect 51 | // notes with type 1 can be linked to other notes IF the effect != 0 and the groupID is set. 52 | 53 | public Circle(float x, float y, Note note, Double noteSpeed, float delay) { 54 | 55 | float timing = (float) (delay + note.timing * 1f + GlobalConfiguration.offset * 1f / 1000f); 56 | 57 | this.origin.x = x; 58 | this.origin.y = y; 59 | this.position.x = x; 60 | this.position.y = y; 61 | this.note = note; 62 | this.hold = (note.type & SongUtils.NOTE_TYPE_HOLD) != 0; 63 | // position goes 1-5 64 | this.destination = note.endPos; 65 | this.speed = noteSpeed; 66 | this.spawnTime = (float) (timing - speed); 67 | this.startWaitTime = (float) (timing - (hold || !note.status.equals(SongUtils.NOTE_NO_SWIPE) ? 2f : 1f) * SongUtils.overallDiffBad[GlobalConfiguration.overallDifficulty] / 1000f); 68 | this.endWaitTime = (float) (timing + (hold || !note.status.equals(SongUtils.NOTE_NO_SWIPE) ? 2f : 1f) * SongUtils.overallDiffBad[GlobalConfiguration.overallDifficulty] / 1000f); 69 | this.despawnTime = timing * 1.0f; 70 | this.size = 1f; 71 | this.previousSystemTime = 0L; 72 | 73 | hitTime = -9f; 74 | previousTime = 0f; 75 | 76 | initializeVelocity(); 77 | initializeStates(); 78 | } 79 | 80 | private void initializeStates() { 81 | visible = false; 82 | holding = false; 83 | soundPlayed = false; 84 | miss = false; 85 | } 86 | 87 | public void setPreviousNote(Circle previousNote) { 88 | this.previousNote = previousNote; 89 | if (previousNote != null) { 90 | if (previousNote.hold && previousNote.previousNote == null) { 91 | this.startWaitTime = (float) (despawnTime - 2f * SongUtils.overallDiffBad[GlobalConfiguration.overallDifficulty] / 1000f); 92 | this.endWaitTime = (float) (despawnTime + 2f * SongUtils.overallDiffBad[GlobalConfiguration.overallDifficulty] / 1000f); 93 | 94 | } 95 | } 96 | 97 | } 98 | 99 | public void setNextNote(Circle nextNote) { 100 | this.nextNote = nextNote; 101 | } 102 | 103 | private void initializeVelocity() { 104 | // unless the arc movement is implemented, 105 | // the notes will simply fall from the top towards the tap zones 106 | velocity.x = 0; 107 | velocity.y = (float) (-249 / speed); 108 | } 109 | 110 | public void update(float time) { 111 | 112 | if (miss || (accuracy != null && !holding)) { 113 | if (visible) { 114 | visible = false; 115 | } 116 | return; 117 | } 118 | 119 | if (spawnTime <= time && despawnTime > time && !visible) { 120 | visible = true; 121 | } 122 | 123 | if (spawnTime >= time && visible) 124 | visible = false; 125 | 126 | if (visible && despawnTime <= time) { 127 | if (GlobalConfiguration.playHintSounds && !soundPlayed) { 128 | // hint sounds play at 50% of the volume 129 | if (note.status.equals(SongUtils.NOTE_NO_SWIPE)) { 130 | Assets.perfectTapSound.play(GlobalConfiguration.feedbackVolume / 200f); 131 | } else { 132 | Assets.perfectSwipeSound.play(GlobalConfiguration.feedbackVolume / 200f); 133 | } 134 | soundPlayed = true; 135 | } 136 | 137 | if (holding) { 138 | alpha = 1f; 139 | } else { 140 | alpha = MathUtils.clamp((endWaitTime - time) / (endWaitTime - despawnTime), 0f, 1f); 141 | if (alpha == 0f) 142 | visible = false; 143 | } 144 | } 145 | 146 | if (visible) { 147 | // TODO: implement parabolic movement of the notes towards the player and use the origin spot instead of spawning from the same lane (more SS-like) 148 | float scl = time - spawnTime; 149 | if (holding) { 150 | position.set(origin.cpy().x, origin.cpy().y - 249); 151 | } else 152 | position.set(origin.cpy().add(velocity.cpy().scl(scl))); 153 | } 154 | if (startWaitTime <= time && endWaitTime > time && !waiting && accuracy == null) { 155 | waiting = true; 156 | } 157 | 158 | processMiss(time); 159 | previousTime = time; 160 | previousSystemTime = System.currentTimeMillis(); 161 | } 162 | 163 | 164 | private void processMiss(float time) { 165 | // miss if we miss the first note 166 | if (nextNote != null && hold && !holding && endWaitTime <= time && accuracy == null && !miss) { 167 | waiting = false; 168 | miss = true; 169 | accuracy = Accuracy.MISS; 170 | nextNote.miss = true; 171 | nextNote.accuracy = Accuracy.MISS; 172 | nextNote.processed = true; 173 | nextNote.waiting = false; 174 | // System.out.println("MISS-001: didn't hit the note (" + note.id + ")"); 175 | } else if (nextNote == null && endWaitTime <= time && !miss && accuracy == null) { 176 | waiting = false; 177 | miss = true; 178 | accuracy = Accuracy.MISS; 179 | // System.out.println("MISS-002: didn't hit the note (" + note.id + ")"); 180 | } else if (nextNote != null && !hold && endWaitTime <= time && accuracy == null && !miss) { 181 | waiting = false; 182 | miss = true; 183 | accuracy = Accuracy.MISS; 184 | // System.out.println("MISS-003: didn't hit the note (" + note.id + ")"); 185 | } 186 | if (hold && !miss) { 187 | // miss if we hold for too long 188 | if (nextNote != null && nextNote.endWaitTime <= time && nextNote.accuracy == null) { 189 | miss = true; 190 | holding = false; 191 | waiting = false; 192 | // System.out.println("MISS-004: held for too long (" + note.id + ")"); 193 | accuracy = Accuracy.MISS; 194 | } 195 | } 196 | } 197 | 198 | public Accuracy hit() { 199 | // System.out.println("H>" + note.id); 200 | 201 | // HIT DOESN'T COUNT FOR HOLD RELEASE! 202 | if (previousNote != null && previousNote.hold) 203 | return Accuracy.NONE; 204 | 205 | float delta = (System.currentTimeMillis() - previousSystemTime) / 1000f; 206 | float hit = previousTime + delta - despawnTime - GlobalConfiguration.inputOffset / 1000f; 207 | 208 | Accuracy accuracy = hold ? Results.getAccuracyForSwipesAndHolds(hit) : Results.getAccuracyFor(hit); 209 | // If the note was tapped too early, we ignore the tap 210 | if (despawnTime > previousTime && accuracy == Accuracy.MISS) { 211 | return Accuracy.NONE; 212 | } 213 | hitTime = hit; 214 | waiting = false; 215 | if (hold) { 216 | hitTime *= Results.SWIPE_HOLD_MULTIPLIER; 217 | holding = true; 218 | } else { 219 | visible = false; 220 | } 221 | this.accuracy = accuracy; 222 | return accuracy; 223 | } 224 | 225 | public Accuracy release() { 226 | // System.out.println("R>" + note.id); 227 | // if a non-hold is released it it counts as a miss. 228 | // some songs have notes with type 1 and status != 0 for release so we check if the previous note was a hold 229 | if (previousNote != null && previousNote.hold && !note.status.equals(SongUtils.NOTE_NO_SWIPE)) { 230 | accuracy = Accuracy.MISS; 231 | miss = true; 232 | visible = false; 233 | previousNote.release(); 234 | waiting = false; 235 | // only type 2 can gain from a release. 236 | // type 1 with status calls release on swipe 237 | return accuracy; 238 | } 239 | // RELEASE DOESN'T COUNT FOR HOLD START 240 | if (holding) { 241 | holding = false; 242 | visible = false; 243 | } 244 | if (nextNote != null) 245 | return Accuracy.NONE; 246 | 247 | float delta = (System.currentTimeMillis() - previousSystemTime) / 1000f; 248 | float hit = previousTime + delta - despawnTime - GlobalConfiguration.inputOffset / 1000f; 249 | accuracy = Results.getAccuracyForSwipesAndHolds(hit); 250 | previousNote.release(); 251 | waiting = false; 252 | // miss if we release before we start waiting 253 | if (accuracy == Accuracy.MISS) { 254 | waiting = false; 255 | visible = false; 256 | miss = true; 257 | processed = true; 258 | // System.out.println("MISS-005: released hold too early (" + note.id + ")"); 259 | } else { 260 | hitTime = hit; 261 | hitTime *= Results.SWIPE_HOLD_MULTIPLIER; 262 | } 263 | return accuracy; 264 | } 265 | 266 | public Accuracy swipeLeft() { 267 | // some songs have notes with type 2 and status != 0 268 | if (note.status.equals(SongUtils.NOTE_NO_SWIPE) || note.status.equals(SongUtils.NOTE_SWIPE_RIGHT)) { 269 | return Accuracy.NONE; 270 | } 271 | if (previousNote != null && previousNote.hold) { 272 | previousNote.release(); 273 | } 274 | 275 | if (previousNote != null && previousNote.previousNote != null) { 276 | if (previousNote.previousNote.note.status.equals(note.status) && !previousNote.isDone()) { 277 | return Accuracy.NONE; 278 | } 279 | } 280 | float delta = (System.currentTimeMillis() - previousSystemTime) / 1000f; 281 | float hit = previousTime + delta - despawnTime - GlobalConfiguration.inputOffset / 1000f; 282 | Accuracy accuracy = Results.getAccuracyForSwipesAndHolds(hit); 283 | // If the note was tapped too early, we ignore the tap 284 | if (despawnTime > previousTime && accuracy == Accuracy.MISS) { 285 | return Accuracy.NONE; 286 | } 287 | hitTime = hit; 288 | hitTime *= Results.SWIPE_HOLD_MULTIPLIER; 289 | waiting = false; 290 | this.accuracy = accuracy; 291 | visible = false; 292 | return accuracy; 293 | } 294 | 295 | public Accuracy swipeRight() { 296 | // some songs have notes with type 2 and status != 0 297 | // legne on pro, for instance. 298 | if (note.status.equals(SongUtils.NOTE_NO_SWIPE) || note.status.equals(SongUtils.NOTE_SWIPE_LEFT)) { 299 | return Accuracy.NONE; 300 | } 301 | if (previousNote != null && previousNote.hold) { 302 | previousNote.release(); 303 | } 304 | 305 | if (previousNote != null && previousNote.previousNote != null) { 306 | if (previousNote.previousNote.note.status.equals(note.status) && !previousNote.isDone()) { 307 | return Accuracy.NONE; 308 | } 309 | } 310 | 311 | float delta = (System.currentTimeMillis() - previousSystemTime) / 1000f; 312 | float hit = previousTime + delta - despawnTime - GlobalConfiguration.inputOffset / 1000f; 313 | Accuracy accuracy = Results.getAccuracyForSwipesAndHolds(hit); 314 | // If the note was tapped too early, we ignore the tap 315 | if (despawnTime > previousTime && accuracy == Accuracy.MISS) { 316 | return Accuracy.NONE; 317 | } 318 | hitTime = hit; 319 | hitTime *= Results.SWIPE_HOLD_MULTIPLIER; 320 | waiting = false; 321 | this.accuracy = accuracy; 322 | visible = false; 323 | return accuracy; 324 | } 325 | 326 | public boolean isDone() { 327 | return miss || (accuracy != null && !holding); 328 | } 329 | 330 | @Override 331 | public int compareTo(Circle o) { 332 | if (o == null) 333 | return 1; 334 | // if the notes have the same timing, sort them by destination 335 | if (note.timing.equals(o.note.timing)) { 336 | return SongUtils.compare(note.endPos, o.note.endPos); 337 | } 338 | 339 | return Double.compare(note.timing, o.note.timing); 340 | } 341 | } 342 | 343 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/objects/TapZone.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.objects; 2 | 3 | import com.badlogic.gdx.math.Vector2; 4 | import com.fteams.sstrain.util.SongUtils; 5 | 6 | public class TapZone implements Comparable{ 7 | 8 | Integer id; 9 | 10 | public boolean pressed; 11 | public boolean warn; 12 | 13 | Vector2 position = new Vector2(); 14 | public float touchTime = -1f; 15 | 16 | public TapZone(float x, float y, int i) { 17 | this.id = i; 18 | this.position.x = x; 19 | this.position.y = y; 20 | pressed = false; 21 | warn = false; 22 | } 23 | 24 | public void update(float delta) { 25 | 26 | } 27 | 28 | public Integer getId() { 29 | return id; 30 | } 31 | 32 | public Vector2 getPosition() { 33 | return position; 34 | } 35 | 36 | @Override 37 | public int compareTo(TapZone o) { 38 | return SongUtils.compare(id, o.id); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/renderer/WorldRenderer.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.renderer; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.graphics.Color; 5 | import com.badlogic.gdx.graphics.OrthographicCamera; 6 | import com.badlogic.gdx.graphics.g2d.BitmapFont; 7 | import com.badlogic.gdx.graphics.g2d.GlyphLayout; 8 | import com.badlogic.gdx.graphics.g2d.PolygonRegion; 9 | import com.badlogic.gdx.graphics.g2d.PolygonSpriteBatch; 10 | import com.badlogic.gdx.graphics.g2d.TextureAtlas; 11 | import com.badlogic.gdx.graphics.g2d.TextureRegion; 12 | import com.badlogic.gdx.graphics.glutils.ShapeRenderer; 13 | import com.badlogic.gdx.math.Interpolation; 14 | import com.badlogic.gdx.math.MathUtils; 15 | import com.badlogic.gdx.math.Vector2; 16 | import com.fteams.sstrain.World; 17 | import com.fteams.sstrain.assets.Assets; 18 | import com.fteams.sstrain.config.GlobalConfiguration; 19 | import com.fteams.sstrain.entities.Note; 20 | import com.fteams.sstrain.objects.AccuracyMarker; 21 | import com.fteams.sstrain.objects.AccuracyPopup; 22 | import com.fteams.sstrain.objects.Circle; 23 | import com.fteams.sstrain.objects.TapZone; 24 | import com.fteams.sstrain.util.Accuracy; 25 | import com.fteams.sstrain.util.SongUtils; 26 | 27 | public class WorldRenderer { 28 | 29 | private static final float CAMERA_WIDTH = 600f; 30 | private static final float CAMERA_HEIGHT = 400f; 31 | 32 | private World world; 33 | private OrthographicCamera cam; 34 | 35 | // textures 36 | TextureRegion circle; 37 | TextureRegion circleSim; 38 | TextureRegion circleSwipeLeft; 39 | TextureRegion circleSwipeLeftSim; 40 | TextureRegion circleSwipeRight; 41 | TextureRegion circleSwipeRightSim; 42 | 43 | TextureRegion tapZoneIdle; 44 | TextureRegion tapZoneWarn; 45 | TextureRegion tapZonePressed; 46 | 47 | TextureRegion accBadBackground; 48 | TextureRegion accGoodBackground; 49 | TextureRegion accGreatBackground; 50 | TextureRegion accPerfectBackground; 51 | 52 | TextureRegion holdBG; 53 | 54 | TextureRegion accHitMark; 55 | 56 | TextureRegion missMark; 57 | TextureRegion badLateMark; 58 | TextureRegion badSoonMark; 59 | TextureRegion goodLateMark; 60 | TextureRegion goodSoonMark; 61 | TextureRegion greatLateMark; 62 | TextureRegion greatSoonMark; 63 | TextureRegion perfectMark; 64 | 65 | BitmapFont font; 66 | BitmapFont songFont; 67 | 68 | GlyphLayout layout; 69 | 70 | // extra stuff 71 | private PolygonSpriteBatch spriteBatch; 72 | 73 | private ShapeRenderer renderer; 74 | 75 | private int width; 76 | private int height; 77 | private int positionOffsetX; 78 | private int positionOffsetY; 79 | // pixels per unit on X 80 | public float ppuX; 81 | // pixels per unit on Y 82 | public float ppuY; 83 | 84 | private float time; 85 | 86 | short[] triangles = {0, 1, 2, 0, 2, 3}; 87 | 88 | public void setSize(int w, int h, int offsetX, int offsetY) { 89 | this.width = w; 90 | this.height = h; 91 | this.positionOffsetX = offsetX; 92 | this.positionOffsetY = offsetY; 93 | ppuX = (float) width / CAMERA_WIDTH; 94 | ppuY = (float) height / CAMERA_HEIGHT; 95 | } 96 | 97 | public WorldRenderer(World world) { 98 | this.world = world; 99 | this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT); 100 | this.cam.position.set(0f, 0f, 0f); 101 | this.cam.update(); 102 | spriteBatch = new PolygonSpriteBatch(); 103 | renderer = new ShapeRenderer(); 104 | layout = new GlyphLayout(); 105 | loadTextures(); 106 | } 107 | 108 | private void loadTextures() { 109 | TextureAtlas atlas = Assets.atlas; 110 | circle = atlas.findRegion("circle"); 111 | circleSim = atlas.findRegion("circle_sim"); 112 | circleSwipeLeft = atlas.findRegion("circle_swipe_left"); 113 | circleSwipeLeftSim = atlas.findRegion("circle_swipe_left_sim"); 114 | circleSwipeRight = atlas.findRegion("circle_swipe_right"); 115 | circleSwipeRightSim = atlas.findRegion("circle_swipe_right_sim"); 116 | 117 | tapZoneIdle = atlas.findRegion("tap"); 118 | tapZonePressed = atlas.findRegion("tap_pressed"); 119 | tapZoneWarn = atlas.findRegion("tap_warn"); 120 | 121 | accBadBackground = atlas.findRegion("acc_bad"); 122 | accGoodBackground = atlas.findRegion("acc_good"); 123 | accGreatBackground = atlas.findRegion("acc_great"); 124 | accPerfectBackground = atlas.findRegion("acc_perfect"); 125 | accHitMark = atlas.findRegion("acc_mark"); 126 | 127 | holdBG = new TextureRegion(Assets.holdBG); 128 | 129 | missMark = atlas.findRegion("miss"); 130 | badLateMark = atlas.findRegion("bad_late"); 131 | badSoonMark = atlas.findRegion("bad_soon"); 132 | goodLateMark = atlas.findRegion("nice_late"); 133 | goodSoonMark = atlas.findRegion("nice_soon"); 134 | greatLateMark = atlas.findRegion("great_late"); 135 | greatSoonMark = atlas.findRegion("great_soon"); 136 | perfectMark = atlas.findRegion("perfect"); 137 | 138 | font = Assets.font; 139 | songFont = Assets.songFont; 140 | } 141 | 142 | public void render() { 143 | spriteBatch.begin(); 144 | renderer.setProjectionMatrix(cam.combined); 145 | renderer.begin(ShapeRenderer.ShapeType.Line); 146 | drawTapZones(); 147 | drawCircles(); 148 | if (GlobalConfiguration.displayLine) { 149 | drawFlatBar(); 150 | } 151 | drawCombo(); 152 | //drawProgressBar(); 153 | drawAccuracyBar(); 154 | if (!world.started) { 155 | drawTapToBeginMessage(); 156 | } 157 | if (!world.paused) { 158 | drawAccuracy(); 159 | } 160 | if (world.paused) { 161 | drawTapToContinue(); 162 | } 163 | renderer.end(); 164 | spriteBatch.end(); 165 | time += Gdx.graphics.getDeltaTime(); 166 | } 167 | 168 | private void drawFlatBar() { 169 | float centerX = this.positionOffsetX + width / 2; 170 | float y = this.positionOffsetY + height - height * 0.72f; 171 | spriteBatch.draw(accBadBackground, centerX - width / 2f, y, width, height * 0.01f); 172 | } 173 | 174 | private void drawAccuracyBar() { 175 | float centerX = this.positionOffsetX + width / 2; 176 | float y = this.positionOffsetY + height - height * 0.1f; 177 | float bad = (float) (SongUtils.overallDiffBad[GlobalConfiguration.overallDifficulty] * 1f); 178 | float nice = (float) (SongUtils.overallDiffNice[GlobalConfiguration.overallDifficulty] * 1f); 179 | float great = (float) (SongUtils.overallDiffGreat[GlobalConfiguration.overallDifficulty] * 1f); 180 | float perfect = (float) (SongUtils.overallDiffPerfect[GlobalConfiguration.overallDifficulty] * 1f); 181 | float zone = bad / 1000f; 182 | // draw the background (bad level) 183 | spriteBatch.draw(accBadBackground, centerX - width / 6f, y, width / 3f, height * 0.01f); 184 | // draw the background (good level) 185 | spriteBatch.draw(accGoodBackground, centerX - nice / bad * width / 6f, y, nice / bad * width / 3f, height * 0.01f); 186 | // draw the background (great level) 187 | spriteBatch.draw(accGreatBackground, centerX - great / bad * width / 6f, y, great / bad * width / 3f, height * 0.01f); 188 | // draw the background (perfect level) 189 | spriteBatch.draw(accPerfectBackground, centerX - perfect / bad * width / 6f, y, perfect / bad * width / 3f, height * 0.01f); 190 | // draw each of the 'markers' 191 | for (AccuracyMarker accMarker : world.getAccuracyMarkers()) { 192 | if (accMarker.display) { 193 | 194 | spriteBatch.setColor(1, 1, 1, accMarker.getAlpha()); 195 | spriteBatch.draw(accHitMark, centerX + (accMarker.getTime()) * (width / 6f) / zone - accHitMark.getRegionWidth(), y - height * 0.01f, 3f, height * 0.03f); 196 | } 197 | } 198 | spriteBatch.setColor(1, 1, 1, 1); 199 | } 200 | 201 | private void drawTapToBeginMessage() { 202 | String tapToBegin = "Tap to begin!" + (GlobalConfiguration.playbackMode != null && GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT) ? " To exit in A-B Repeat Mode, tap back twice." : ""); 203 | float centerX = this.positionOffsetX + width / 2; 204 | float centerY = this.positionOffsetY + height / 2 + height * 0.15f; 205 | layout.setText(songFont, tapToBegin); 206 | songFont.draw(spriteBatch, tapToBegin, centerX - layout.width / 2, centerY - layout.height / 2); 207 | } 208 | 209 | private void drawTapToContinue() { 210 | String tapToBegin = "Tap to continue!"; 211 | float centerX = this.positionOffsetX + width / 2; 212 | float centerY = this.positionOffsetY + height / 2 + height * 0.15f; 213 | layout.setText(songFont, tapToBegin); 214 | songFont.draw(spriteBatch, tapToBegin, centerX - layout.width / 2, centerY - layout.height / 2); 215 | 216 | String backToExit = "Or press back again to skip to the Results screen."; 217 | centerX = this.positionOffsetX + width / 2; 218 | centerY = this.positionOffsetY + height / 2 + height * 0.1f; 219 | layout.setText(songFont, backToExit); 220 | songFont.draw(spriteBatch, backToExit, centerX - layout.width / 2, centerY - layout.height / 2); 221 | } 222 | 223 | private void drawAccuracy() { 224 | float scale = height / GlobalConfiguration.BASE_HEIGHT; 225 | float centerX = this.positionOffsetX + width / 2; 226 | float centerY = this.positionOffsetY + height / 2 + height * 0.15f; 227 | for (AccuracyPopup popup : world.getAccuracyPopups()) { 228 | if (popup.show) { 229 | TextureRegion region = perfectMark; 230 | if (popup.accuracy == Accuracy.MISS) { 231 | region = missMark; 232 | } 233 | if (popup.accuracy == Accuracy.BAD) { 234 | region = popup.soon ? badSoonMark : badLateMark; 235 | } 236 | if (popup.accuracy == Accuracy.NICE) { 237 | region = popup.soon ? goodSoonMark : goodLateMark; 238 | } 239 | if (popup.accuracy == Accuracy.GREAT) { 240 | region = popup.soon ? greatSoonMark : greatLateMark; 241 | } 242 | spriteBatch.setColor(1, 1, 1, popup.getAlpha()); 243 | spriteBatch.draw(region, centerX - scale * region.getRegionWidth() * popup.getSize() / 2, centerY - scale * region.getRegionHeight() * popup.getSize() / 2, scale * region.getRegionWidth() * popup.getSize(), scale * region.getRegionHeight() * popup.getSize()); 244 | } 245 | } 246 | spriteBatch.setColor(1, 1, 1, 1); 247 | } 248 | 249 | private void drawCombo() { 250 | float centerX = this.positionOffsetX + width / 2; 251 | float centerY = height / 2; 252 | if (world.combo != 0) { 253 | layout.setText(font, "" + world.combo); 254 | font.draw(spriteBatch, "" + world.combo, centerX - layout.width / 2, centerY - layout.height / 2); 255 | } 256 | } 257 | 258 | private void drawTapZones() { 259 | float centerX = this.positionOffsetX + width / 2; 260 | float centerY = this.positionOffsetY + height - height * 0.2f; 261 | float size = height * 0.125f; 262 | for (TapZone tapZone : world.getTapZones()) { 263 | 264 | TextureRegion region = tapZoneIdle; 265 | 266 | if (tapZone.warn) { 267 | region = tapZoneWarn; 268 | } 269 | 270 | if (tapZone.pressed) { 271 | tapZone.touchTime = time; 272 | } 273 | 274 | final float x = centerX + tapZone.getPosition().x * ppuX - size / 2; 275 | final float y = centerY + tapZone.getPosition().y * ppuY - size / 2; 276 | spriteBatch.draw(region, x, y, size, size); 277 | 278 | float alpha = 1f - MathUtils.clamp((time - tapZone.touchTime) * 5f, 0f, 1f); 279 | if (alpha > 0) { 280 | Color c = spriteBatch.getColor(); 281 | spriteBatch.setColor(c.r, c.g, c.b, Interpolation.pow2In.apply(alpha)); 282 | spriteBatch.draw(tapZonePressed, x, y, size, size); 283 | spriteBatch.setColor(c); 284 | } 285 | } 286 | } 287 | 288 | private void drawCircles() { 289 | float centerX = this.positionOffsetX + width / 2; 290 | float centerY = this.positionOffsetY + height - height * 0.2f; 291 | float size = height * 0.1f; 292 | 293 | for (Circle mark : world.getCircles()) { 294 | if (!mark.visible) 295 | continue; 296 | 297 | float alpha = mark.alpha; 298 | // float alpha2 = mark.alpha2; 299 | Color c = spriteBatch.getColor(); 300 | 301 | if (mark.holding) 302 | spriteBatch.setColor(1.0f, 1.0f, 0.5f, alpha * 1f * 0.45f * (0.75f + 0.25f * MathUtils.sin(time * 7f + mark.hitTime))); 303 | else 304 | spriteBatch.setColor(c.r, c.g, c.b, alpha * alpha * 1f * 0.45f); 305 | 306 | if (mark.nextNote != null && !mark.nextNote.isDone()) { 307 | Vector2 org = mark.nextNote.position.cpy(); 308 | org.x *= ppuX; 309 | org.y *= ppuY; 310 | org.x += centerX; 311 | org.y += centerY; 312 | 313 | Vector2 dst = mark.position.cpy(); 314 | dst.x *= ppuX; 315 | if (mark.holding) { 316 | dst.y = -249f; 317 | } 318 | 319 | dst.y *= ppuY; 320 | dst.x += centerX; 321 | dst.y += centerY; 322 | drawHoldBeam(org, dst, size, size); 323 | } 324 | 325 | if (!mark.note.sync.equals(0L)) { 326 | Circle mark2 = mark.nextSyncNote; 327 | // we only check ahead if we got the same note, we don't want overlapping beams 328 | // draw beams only if neither note has been ever hit 329 | if (mark2 != null && mark.accuracy == null && mark2.accuracy == null) { 330 | Vector2 org = mark2.position.cpy(); 331 | org.x *= ppuX; 332 | org.y *= ppuY; 333 | org.x += centerX; 334 | org.y += centerY; 335 | 336 | Vector2 dst = mark.position.cpy(); 337 | dst.x *= ppuX; 338 | dst.y *= ppuY; 339 | dst.x += centerX; 340 | dst.y += centerY; 341 | drawHoldBeam(org, dst, size * 0.1f, size * 0.1f); 342 | } 343 | } 344 | if (mark.visible) { 345 | 346 | spriteBatch.setColor(c.r, c.g, c.b, alpha); 347 | spriteBatch.draw(selectTextureForCircle(mark.note), centerX - size / 2 + mark.position.x * ppuX, centerY - size / 2 + mark.position.y * ppuY, size, size); 348 | 349 | } 350 | spriteBatch.setColor(c); 351 | } 352 | 353 | } 354 | 355 | private void drawHoldBeam(Vector2 from, Vector2 to, float orgSize, float dstSize) { 356 | Vector2 delta = from.cpy().sub(to); 357 | 358 | float w = Math.max(orgSize, dstSize); 359 | float h = delta.len(); 360 | 361 | float tw = holdBG.getRegionWidth(); 362 | float th = holdBG.getRegionHeight(); 363 | 364 | float factorScale = (tw / w) * 0.5f; 365 | float topFactor = Math.max(dstSize - orgSize, 0f) * factorScale; 366 | float botFactor = Math.max(orgSize - dstSize, 0f) * factorScale; 367 | 368 | float[] points = { 369 | topFactor, 370 | 0f, 371 | 372 | botFactor, 373 | th, 374 | 375 | tw - botFactor, 376 | th, 377 | 378 | tw - topFactor, 379 | 0f 380 | }; 381 | 382 | PolygonRegion clamped = new PolygonRegion(holdBG, points, triangles); 383 | spriteBatch.draw(clamped, from.x - w * 0.5f, from.y, w * 0.5f, 0f, w, h, 1f, 1f, delta.angle() + 90); 384 | } 385 | 386 | private TextureRegion selectTextureForCircle(Note note) { 387 | 388 | if (note.sync.intValue() == SongUtils.NOTE_SYNC_ON) { 389 | if (note.status.equals(SongUtils.NOTE_NO_SWIPE)) { 390 | return circleSim; 391 | } else if (note.status.equals(SongUtils.NOTE_SWIPE_LEFT)) { 392 | return circleSwipeLeftSim; 393 | } else if (note.status.equals(SongUtils.NOTE_SWIPE_RIGHT)) { 394 | return circleSwipeRightSim; 395 | } 396 | } else if (note.sync.intValue() == SongUtils.NOTE_SYNC_OFF) { 397 | if (note.status.equals(SongUtils.NOTE_NO_SWIPE)) { 398 | return circle; 399 | } else if (note.status.equals(SongUtils.NOTE_SWIPE_LEFT)) { 400 | return circleSwipeLeft; 401 | } else if (note.status.equals(SongUtils.NOTE_SWIPE_RIGHT)) { 402 | return circleSwipeRight; 403 | } 404 | } 405 | return circle; 406 | } 407 | } 408 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/screens/BeatmapReloadScreen.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.screens; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.badlogic.gdx.Gdx; 5 | import com.badlogic.gdx.Screen; 6 | import com.badlogic.gdx.graphics.GL20; 7 | import com.badlogic.gdx.scenes.scene2d.Stage; 8 | import com.badlogic.gdx.scenes.scene2d.ui.Image; 9 | import com.badlogic.gdx.scenes.scene2d.ui.Label; 10 | import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar; 11 | import com.fteams.sstrain.assets.Assets; 12 | import com.fteams.sstrain.config.GlobalConfiguration; 13 | 14 | public class BeatmapReloadScreen implements Screen { 15 | private Image backgroundImage = new Image(Assets.mainMenuBackgroundTexture); 16 | private Stage stage = new Stage(); 17 | private ProgressBar loadingProgress = new ProgressBar(0.0f, 100f, 0.1f, false, Assets.menuSkin); 18 | int phase = 0; 19 | Label infoLabel = new Label("Performing a hard reload...\n\n" + 20 | "This operation can take anywhere between a couple of seconds to a couple of " + 21 | "minutes depending on the amount of beatmaps loaded, please wait....", Assets.menuSkin, "song_style_result"); 22 | @Override 23 | public void show() { 24 | float scaleFactor = stage.getHeight() / GlobalConfiguration.BASE_HEIGHT; 25 | backgroundImage.setSize(stage.getWidth(), stage.getHeight()); 26 | loadingProgress.setSize(stage.getWidth() * 0.7f, stage.getHeight() * 0.07f); 27 | loadingProgress.setX(stage.getWidth() * 0.15f); 28 | loadingProgress.setY(stage.getHeight() * 0.1f); 29 | 30 | infoLabel.setX(stage.getWidth() * 0.1f); 31 | infoLabel.setY(stage.getHeight() * 0.2f); 32 | infoLabel.setWrap(true); 33 | infoLabel.setWidth(stage.getWidth() * 0.8f); 34 | infoLabel.setHeight(stage.getHeight() * 0.7f); 35 | infoLabel.setFontScale(scaleFactor); 36 | 37 | stage.addActor(backgroundImage); 38 | stage.addActor(loadingProgress); 39 | stage.addActor(infoLabel); 40 | } 41 | 42 | @Override 43 | public void render(float delta) { 44 | Gdx.gl.glClearColor(0, 0, 0, 1); 45 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 46 | stage.act(); 47 | stage.draw(); 48 | 49 | // done loading 50 | if (Assets.update()) 51 | { 52 | 53 | if (phase == 1) { 54 | Assets.setSongs(); 55 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SettingsScreen()); 56 | } 57 | if (phase == 0) 58 | { 59 | phase++; 60 | // this will cause any newly created .rs files to be loaded. 61 | Assets.reloadBeatmaps(); 62 | } 63 | } 64 | loadingProgress.setValue((Assets.getProgress() - 0.5f)* 200f); 65 | loadingProgress.act(delta); 66 | } 67 | 68 | @Override 69 | public void resize(int width, int height) { 70 | 71 | } 72 | 73 | @Override 74 | public void pause() { 75 | 76 | } 77 | 78 | @Override 79 | public void resume() { 80 | 81 | } 82 | 83 | @Override 84 | public void hide() { 85 | 86 | } 87 | 88 | @Override 89 | public void dispose() { 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/screens/LiveOptionsScreen.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.screens; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.badlogic.gdx.Gdx; 5 | import com.badlogic.gdx.Input; 6 | import com.badlogic.gdx.InputMultiplexer; 7 | import com.badlogic.gdx.InputProcessor; 8 | import com.badlogic.gdx.Screen; 9 | import com.badlogic.gdx.audio.Music; 10 | import com.badlogic.gdx.graphics.GL20; 11 | import com.badlogic.gdx.scenes.scene2d.Actor; 12 | import com.badlogic.gdx.scenes.scene2d.InputEvent; 13 | import com.badlogic.gdx.scenes.scene2d.Stage; 14 | import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; 15 | import com.badlogic.gdx.scenes.scene2d.ui.Image; 16 | import com.badlogic.gdx.scenes.scene2d.ui.Label; 17 | import com.badlogic.gdx.scenes.scene2d.ui.Slider; 18 | import com.badlogic.gdx.scenes.scene2d.ui.Table; 19 | import com.badlogic.gdx.scenes.scene2d.ui.TextButton; 20 | import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; 21 | import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; 22 | import com.fteams.sstrain.assets.Assets; 23 | import com.fteams.sstrain.config.GlobalConfiguration; 24 | import com.fteams.sstrain.controller.SongLoader; 25 | import com.fteams.sstrain.util.SongUtils; 26 | 27 | public class LiveOptionsScreen extends ChangeListener implements Screen, InputProcessor { 28 | private Image backgroundImage = new Image(Assets.mainMenuBackgroundTexture); 29 | private Stage stage = new Stage(); 30 | 31 | private TextButton nextButton = new TextButton("Next", Assets.menuSkin, "item1"); 32 | private TextButton backButton = new TextButton("Back", Assets.menuSkin, "item1"); 33 | 34 | private Table table = new Table(); 35 | 36 | private CheckBox abModeChooser; 37 | private Label playbackRateLabel; 38 | private Label playbackRateValueLabel; 39 | 40 | private Slider playbackRateSlider; 41 | private Slider aSlider; 42 | private Slider bSlider; 43 | 44 | private Label aLabel; 45 | private Label bLabel; 46 | 47 | String[] modes = {"Normal", "A-B repeat"}; 48 | 49 | private Float newPlaybackRate; 50 | private Float newAPosition; 51 | private Float newBPosition; 52 | 53 | private Music theSong; 54 | 55 | @Override 56 | public void show() { 57 | 58 | theSong = SongLoader.loadSongFile(); 59 | 60 | float fontScale = stage.getHeight() / GlobalConfiguration.BASE_HEIGHT; 61 | backgroundImage.setSize(stage.getWidth(), stage.getHeight()); 62 | stage.addActor(backgroundImage); 63 | 64 | nextButton.getLabel().setFontScale(fontScale); 65 | backButton.getLabel().setFontScale(fontScale); 66 | 67 | backButton.addListener((new ClickListener() { 68 | @Override 69 | public void clicked(InputEvent event, float x, float y) { 70 | if (theSong != null) 71 | { 72 | theSong.stop(); 73 | theSong.dispose(); 74 | } 75 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SongSelectionScreen()); 76 | } 77 | })); 78 | nextButton.addListener((new ClickListener() { 79 | @Override 80 | public void clicked(InputEvent event, float x, float y) { 81 | if (theSong != null) 82 | { 83 | theSong.stop(); 84 | theSong.dispose(); 85 | } 86 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SongScreen()); 87 | } 88 | })); 89 | 90 | // Playback Rate related stuff: 91 | newPlaybackRate = GlobalConfiguration.playbackRate == null ? 1.0f : GlobalConfiguration.playbackRate; 92 | 93 | playbackRateLabel = new Label("Playback Rate:" + (newPlaybackRate.compareTo(1.0f) == 0 ? "" : "(no music)"), Assets.menuSkin, "song_style_result"); 94 | playbackRateLabel.setFontScale(fontScale); 95 | 96 | playbackRateValueLabel = new Label(String.format("%.2f", newPlaybackRate) + "x", Assets.menuSkin); 97 | playbackRateValueLabel.setFontScale(fontScale); 98 | 99 | playbackRateSlider = new Slider(0.5f, 2.0f, 0.05f, false, Assets.menuSkin); 100 | playbackRateSlider.setValue(newPlaybackRate); 101 | playbackRateSlider.addListener(this); 102 | 103 | table.setWidth(stage.getWidth() * 0.8f); 104 | table.setHeight(stage.getHeight() * 0.8f); 105 | table.setX(stage.getWidth() * 0.1f); 106 | table.setY(stage.getHeight() * 0.1f); 107 | 108 | table.add(playbackRateLabel).width(stage.getWidth() * 0.15f).padTop(stage.getHeight() * 0.01f).padBottom(stage.getHeight() * 0.01f).left(); 109 | table.add(playbackRateValueLabel).right().fillX().row(); 110 | table.add(playbackRateSlider).width(stage.getWidth() * 0.8f).height(playbackRateLabel.getHeight() * fontScale).padTop(stage.getHeight() * 0.01f).padBottom(stage.getHeight() * 0.01f).colspan(2).row(); 111 | table.add().height(playbackRateValueLabel.getHeight() / 2f).row(); 112 | 113 | // AB - repeat mode 114 | abModeChooser = new CheckBox("Game Mode (Tap to change): " + modes[GlobalConfiguration.playbackMode == null ? 0 : GlobalConfiguration.playbackMode], Assets.menuSkin); 115 | 116 | newAPosition = GlobalConfiguration.aTime == null ? 0f : GlobalConfiguration.aTime; 117 | newBPosition = GlobalConfiguration.bTime == null || GlobalConfiguration.bTime > Assets.selectedBeatmap.metadata.duration.floatValue() ? Assets.selectedBeatmap.metadata.duration.floatValue() : GlobalConfiguration.bTime; 118 | 119 | // just to make sure aTime and bTime are not null after this point, we 'set them' 120 | GlobalConfiguration.aTime = newAPosition; 121 | GlobalConfiguration.bTime = newBPosition; 122 | 123 | abModeChooser.getImageCell().width(0); 124 | abModeChooser.getLabel().setFontScale(fontScale); 125 | abModeChooser.addListener(this); 126 | 127 | aSlider = new Slider(0f, Assets.selectedBeatmap.metadata.duration.floatValue() - 6f, 1f, false, Assets.menuSkin); 128 | aSlider.setVisible(GlobalConfiguration.playbackMode != null && GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 129 | aSlider.setValue(newAPosition); 130 | aSlider.addListener(this); 131 | bSlider = new Slider(6f, Assets.selectedBeatmap.metadata.duration.floatValue(), 1f, false, Assets.menuSkin); 132 | bSlider.setVisible(GlobalConfiguration.playbackMode != null && GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 133 | bSlider.setValue(newBPosition); 134 | bSlider.addListener(this); 135 | 136 | aLabel = new Label("Start Time: " +String.format("%.2f", newAPosition) , Assets.menuSkin); 137 | aLabel.setVisible(GlobalConfiguration.playbackMode != null && GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 138 | bLabel = new Label("End Time: " + String.format("%.2f", newBPosition), Assets.menuSkin); 139 | bLabel.setVisible(GlobalConfiguration.playbackMode != null && GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 140 | 141 | aLabel.setFontScale(fontScale); 142 | bLabel.setFontScale(fontScale); 143 | 144 | table.add(abModeChooser).colspan(3).left().padBottom(stage.getHeight() * 0.01f).padTop(stage.getHeight() * 0.01f).row(); 145 | table.add(aLabel).left().row(); 146 | table.add(aSlider).width(stage.getWidth() * 0.8f).height(aLabel.getHeight() * fontScale).padTop(stage.getHeight() * 0.01f).padBottom(stage.getHeight() * 0.01f).colspan(2).row(); 147 | table.add(bLabel).left().row(); 148 | table.add(bSlider).width(stage.getWidth() * 0.8f).height(aLabel.getHeight() * fontScale).padTop(stage.getHeight() * 0.01f).padBottom(stage.getHeight() * 0.01f).colspan(2).row(); 149 | 150 | table.add().height(playbackRateValueLabel.getHeight() / 2f).row(); 151 | 152 | table.add().expand().fill().row(); 153 | table.add(backButton).size(stage.getWidth() * 0.75f / 2, stage.getHeight() * 0.12f); 154 | table.add(nextButton).size(stage.getWidth() * 0.75f / 2, stage.getHeight() * 0.12f); 155 | stage.addActor(table); 156 | 157 | InputMultiplexer impx = new InputMultiplexer(); 158 | impx.addProcessor(this); 159 | impx.addProcessor(stage); 160 | 161 | Gdx.input.setInputProcessor(impx); 162 | Gdx.input.setCatchBackKey(true); 163 | } 164 | 165 | @Override 166 | public void render(float delta) { 167 | Gdx.gl.glClearColor(0, 0, 0, 1); 168 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 169 | 170 | stage.act(); 171 | stage.draw(); 172 | 173 | if (theSong != null && theSong.isPlaying() && theSong.getPosition() > newBPosition) { 174 | theSong.setPosition(newAPosition); 175 | } 176 | } 177 | 178 | @Override 179 | public void resize(int width, int height) { 180 | 181 | } 182 | 183 | @Override 184 | public void pause() { 185 | 186 | } 187 | 188 | @Override 189 | public void resume() { 190 | 191 | } 192 | 193 | @Override 194 | public void hide() { 195 | 196 | } 197 | 198 | @Override 199 | public void dispose() { 200 | 201 | } 202 | 203 | @Override 204 | public boolean keyDown(int keycode) { 205 | return false; 206 | } 207 | 208 | @Override 209 | public boolean keyUp(int keycode) { 210 | if (keycode == Input.Keys.BACK || keycode == Input.Keys.ESCAPE) { 211 | if (theSong != null) 212 | { 213 | theSong.stop(); 214 | theSong.dispose(); 215 | } 216 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SongSelectionScreen()); 217 | // do nothing 218 | return true; 219 | } 220 | return false; 221 | } 222 | 223 | @Override 224 | public boolean keyTyped(char character) { 225 | return false; 226 | } 227 | 228 | @Override 229 | public boolean touchDown(int screenX, int screenY, int pointer, int button) { 230 | return false; 231 | } 232 | 233 | @Override 234 | public boolean touchUp(int screenX, int screenY, int pointer, int button) { 235 | return false; 236 | } 237 | 238 | @Override 239 | public boolean touchDragged(int screenX, int screenY, int pointer) { 240 | return false; 241 | } 242 | 243 | @Override 244 | public boolean mouseMoved(int screenX, int screenY) { 245 | return false; 246 | } 247 | 248 | @Override 249 | public boolean scrolled(int amount) { 250 | return false; 251 | } 252 | 253 | @Override 254 | public void changed(ChangeEvent event, Actor actor) { 255 | if (actor == playbackRateSlider) { 256 | newPlaybackRate = ((Slider) actor).getValue(); 257 | GlobalConfiguration.playbackRate = newPlaybackRate; 258 | playbackRateLabel.setText("Playback Rate" + (newPlaybackRate.compareTo(1.0f) == 0 ? "" : "(no music)")); 259 | playbackRateValueLabel.setText(String.format("%.2f", newPlaybackRate) + "x"); 260 | } 261 | if (actor == aSlider) { 262 | newAPosition = ((Slider) actor).getValue(); 263 | GlobalConfiguration.aTime = newAPosition; 264 | aLabel.setText("Start Time: " + String.format("%.2f", newAPosition)); 265 | if (newAPosition + 5f > newBPosition) { 266 | newBPosition = newAPosition + 5f; 267 | bSlider.setValue(newBPosition); 268 | bLabel.setText("End Time: " + String.format("%.2f", newBPosition)); 269 | GlobalConfiguration.bTime = newBPosition; 270 | } 271 | if (theSong != null) { 272 | theSong.pause(); 273 | theSong.setPosition(newAPosition); 274 | theSong.setVolume(GlobalConfiguration.songVolume / 100f); 275 | theSong.play(); 276 | } 277 | } 278 | if (actor == bSlider) { 279 | newBPosition = ((Slider) actor).getValue(); 280 | GlobalConfiguration.bTime = newBPosition; 281 | bLabel.setText("End Time: " + String.format("%.2f", newBPosition)); 282 | if (newBPosition - 5f < newAPosition) { 283 | newAPosition = newBPosition - 5f; 284 | aSlider.setValue(newAPosition); 285 | aLabel.setText("Start Time: " + String.format("%.2f", newAPosition)); 286 | GlobalConfiguration.aTime = newAPosition; 287 | } 288 | } 289 | if (actor == abModeChooser) { 290 | GlobalConfiguration.playbackMode = GlobalConfiguration.playbackMode == null ? 1 : (GlobalConfiguration.playbackMode + 1) % modes.length; 291 | abModeChooser.setText("Game Mode (Tap to change): " + modes[GlobalConfiguration.playbackMode]); 292 | 293 | aLabel.setVisible(GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 294 | aSlider.setVisible(GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 295 | bLabel.setVisible(GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 296 | bSlider.setVisible(GlobalConfiguration.playbackMode.equals(SongUtils.GAME_MODE_ABREPEAT)); 297 | } 298 | } 299 | } 300 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/screens/MainMenuScreen.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.screens; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.badlogic.gdx.Gdx; 5 | import com.badlogic.gdx.Input; 6 | import com.badlogic.gdx.InputMultiplexer; 7 | import com.badlogic.gdx.InputProcessor; 8 | import com.badlogic.gdx.Screen; 9 | import com.badlogic.gdx.graphics.GL20; 10 | import com.badlogic.gdx.scenes.scene2d.InputEvent; 11 | import com.badlogic.gdx.scenes.scene2d.Stage; 12 | import com.badlogic.gdx.scenes.scene2d.ui.Image; 13 | import com.badlogic.gdx.scenes.scene2d.ui.Label; 14 | import com.badlogic.gdx.scenes.scene2d.ui.Table; 15 | import com.badlogic.gdx.scenes.scene2d.ui.TextButton; 16 | import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; 17 | import com.badlogic.gdx.utils.Align; 18 | import com.fteams.sstrain.assets.Assets; 19 | import com.fteams.sstrain.config.GlobalConfiguration; 20 | import com.fteams.sstrain.util.Tips; 21 | 22 | public class MainMenuScreen implements Screen, InputProcessor { 23 | private Stage stage = new Stage(); 24 | private Image mainMenuBackgroundImage = new Image(Assets.mainMenuBackgroundTexture); 25 | private Table table = new Table(); 26 | 27 | private TextButton buttonPlay = new TextButton("Play/プレイ", Assets.menuSkin, "item1"); 28 | private TextButton buttonSettings = new TextButton("Settings/設定", Assets.menuSkin, "item1"); 29 | 30 | private Label title = new Label("SS Train", Assets.menuSkin, "title"); 31 | 32 | @Override 33 | public void render(float delta) { 34 | Gdx.gl.glClearColor(0, 0, 0, 1); 35 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 36 | stage.act(); 37 | stage.draw(); 38 | } 39 | 40 | @Override 41 | public void resize(int width, int height) { 42 | } 43 | 44 | @Override 45 | public void show() { 46 | 47 | mainMenuBackgroundImage.setSize(stage.getWidth(), stage.getHeight()); 48 | stage.addActor(mainMenuBackgroundImage); 49 | buttonPlay.addListener(new ClickListener() { 50 | @Override 51 | public void clicked(InputEvent event, float x, float y) { 52 | //Same way we moved here from the Splash Screen 53 | //We set it to new Splash because we got no other screens 54 | //otherwise you put the screen there where you want to go 55 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SongSelectionScreen()); 56 | } 57 | }); 58 | buttonSettings.addListener(new ClickListener() { 59 | @Override 60 | public void clicked(InputEvent event, float x, float y) { 61 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SettingsScreen()); 62 | } 63 | }); 64 | 65 | //The elements are displayed in the order you add them. 66 | //The first appear on top, the last at the bottom. 67 | // title font scale = 1 for a 720 height 68 | float fontScale = stage.getHeight() / GlobalConfiguration.BASE_HEIGHT; 69 | 70 | title.setFontScale(fontScale); 71 | table.add(title).padBottom(stage.getHeight() * 0.1f).row(); 72 | 73 | Label versionLabel = new Label("VERSION: " + GlobalConfiguration.appVersionName, Assets.menuSkin, "version_label"); 74 | versionLabel.setFontScale(fontScale / 2f); 75 | versionLabel.setX(stage.getWidth() * 0.075f); 76 | versionLabel.setY(stage.getHeight() * 0.9f); 77 | 78 | Label tipLabel = new Label(Tips.getRandomTip(), Assets.menuSkin, "default"); 79 | tipLabel.setFontScale(fontScale * 0.7f); 80 | tipLabel.setWrap(true); 81 | tipLabel.setX(stage.getWidth() * 0.10f); 82 | tipLabel.setY(stage.getHeight() * 0.15f); 83 | tipLabel.setWidth(stage.getWidth() * 0.8f); 84 | tipLabel.setAlignment(Align.center); 85 | 86 | stage.addActor(versionLabel); 87 | stage.addActor(tipLabel); 88 | 89 | 90 | buttonPlay.getLabel().setFontScale(fontScale); 91 | buttonSettings.getLabel().setFontScale(fontScale); 92 | table.add(buttonPlay).size(stage.getWidth() * 0.2f, stage.getHeight() * 0.10f).padBottom(stage.getHeight() * 0.04f).row(); 93 | table.add(buttonSettings).size(stage.getWidth() * 0.2f, stage.getHeight() * 0.10f).padBottom(stage.getHeight() * 0.04f).row(); 94 | 95 | table.setFillParent(true); 96 | stage.addActor(table); 97 | 98 | InputMultiplexer impx = new InputMultiplexer(); 99 | impx.addProcessor(this); 100 | impx.addProcessor(stage); 101 | 102 | Gdx.input.setInputProcessor(impx); 103 | Gdx.input.setCatchBackKey(true); 104 | } 105 | 106 | @Override 107 | public void hide() { 108 | dispose(); 109 | } 110 | 111 | @Override 112 | public void pause() { 113 | } 114 | 115 | @Override 116 | public void resume() { 117 | } 118 | 119 | @Override 120 | public void dispose() { 121 | stage.dispose(); 122 | } 123 | 124 | @Override 125 | public boolean keyDown(int keycode) { 126 | return false; 127 | } 128 | 129 | @Override 130 | public boolean keyUp(int keycode) { 131 | if (keycode == Input.Keys.BACK || keycode == Input.Keys.ESCAPE) { 132 | // do nothing 133 | return true; 134 | } 135 | return false; 136 | } 137 | 138 | @Override 139 | public boolean keyTyped(char character) { 140 | return false; 141 | } 142 | 143 | @Override 144 | public boolean touchDown(int screenX, int screenY, int pointer, int button) { 145 | return false; 146 | } 147 | 148 | @Override 149 | public boolean touchUp(int screenX, int screenY, int pointer, int button) { 150 | return false; 151 | } 152 | 153 | @Override 154 | public boolean touchDragged(int screenX, int screenY, int pointer) { 155 | return false; 156 | } 157 | 158 | @Override 159 | public boolean mouseMoved(int screenX, int screenY) { 160 | return false; 161 | } 162 | 163 | @Override 164 | public boolean scrolled(int amount) { 165 | return false; 166 | } 167 | } -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/screens/ResultsScreen.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.screens; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.badlogic.gdx.Gdx; 5 | import com.badlogic.gdx.Screen; 6 | import com.badlogic.gdx.graphics.GL20; 7 | import com.badlogic.gdx.graphics.Texture; 8 | import com.badlogic.gdx.scenes.scene2d.InputEvent; 9 | import com.badlogic.gdx.scenes.scene2d.Stage; 10 | import com.badlogic.gdx.scenes.scene2d.ui.Image; 11 | import com.badlogic.gdx.scenes.scene2d.ui.Label; 12 | import com.badlogic.gdx.scenes.scene2d.ui.Table; 13 | import com.badlogic.gdx.scenes.scene2d.ui.TextButton; 14 | import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; 15 | import com.fteams.sstrain.assets.Assets; 16 | import com.fteams.sstrain.config.GlobalConfiguration; 17 | import com.fteams.sstrain.entities.Results; 18 | import com.fteams.sstrain.util.SongUtils; 19 | 20 | public class ResultsScreen implements Screen { 21 | 22 | Stage stage = new Stage(); 23 | private Texture texture = Assets.mainMenuBackgroundTexture; 24 | private Image splashImage = new Image(texture); 25 | private Table table = new Table(); 26 | private Label difficulty = new Label("Difficulty:", Assets.menuSkin, "song_style_result_values"); 27 | private Label difficultyLabel; 28 | private Label approachRateLabel = new Label("Approach Rate:", Assets.menuSkin, "song_style_result_values"); 29 | private Label approachRateConfigLabel; 30 | private Label overallDifficultyLabel = new Label("Overall Difficulty:", Assets.menuSkin, "song_style_result_values"); 31 | private Label overallDifficultyConfigLabel; 32 | private Label accuracyLabel = new Label("Avg. Accuracy:", Assets.menuSkin, "song_style_result_values"); 33 | private Label accuracyResultLabel; 34 | private Label normalizedAccuracyLabel = new Label("% Accuracy:", Assets.menuSkin, "song_style_result_values"); 35 | private Label normalizedAccuracyResultLabel; 36 | private Label accuracyRangeLabel = new Label("Accuracy Range:", Assets.menuSkin, "song_style_result_values"); 37 | private Label accuracyRangeResultLabel; 38 | private Label unstableRatingLabel = new Label("Unstable Rating:", Assets.menuSkin, "song_style_result_values"); 39 | private Label unstableRatingValueLabel; 40 | private Label badLabel = new Label("Bad:", Assets.menuSkin, "song_style_result_values"); 41 | private Label badResultLabel; 42 | private Label goodLabel = new Label("Nice:", Assets.menuSkin, "song_style_result_values"); 43 | private Label goodResultLabel; 44 | private Label greatLabel = new Label("Great", Assets.menuSkin, "song_style_result_values"); 45 | private Label greatResultLabel; 46 | private Label perfectLabel = new Label("Perfect:", Assets.menuSkin, "song_style_result_values"); 47 | private Label perfectResultLabel; 48 | private Label missLabel = new Label("Miss:", Assets.menuSkin, "song_style_result_values"); 49 | private Label missResultLabel; 50 | private Label comboLabel = new Label("Largest Combo:", Assets.menuSkin, "song_style_result_values"); 51 | private Label comboResultLabel; 52 | private Label titleLabel = new Label("Results/結果発表", Assets.menuSkin, "results_title"); 53 | 54 | @Override 55 | public void show() { 56 | // title font scale = 1 for a 720 height 57 | float fontScale = stage.getHeight() / GlobalConfiguration.BASE_HEIGHT; 58 | 59 | splashImage.setHeight(stage.getHeight()); 60 | splashImage.setWidth(stage.getWidth()); 61 | stage.addActor(splashImage); 62 | titleLabel.setX(stage.getWidth() / 2 - titleLabel.getWidth() / 2); 63 | titleLabel.setY(stage.getHeight() - stage.getHeight() * 0.3f); 64 | titleLabel.setFontScale(fontScale); 65 | 66 | table.setFillParent(true); 67 | 68 | difficultyLabel = new Label(Assets.selectedBeatmap.metadata.difficulty == null ? Assets.selectedBeatmap.metadata.difficulty + "*" : Assets.selectedBeatmap.metadata.difficultyName, Assets.menuSkin, "song_style_result_values"); 69 | approachRateConfigLabel = new Label("AR-" + GlobalConfiguration.noteSpeed + " (" + SongUtils.getSpeedFromConfig(GlobalConfiguration.noteSpeed) + " ms)", Assets.menuSkin, "song_style_result_values"); 70 | overallDifficultyConfigLabel = new Label("OD-" + GlobalConfiguration.overallDifficulty + " (" + SongUtils.overallDiffBad[GlobalConfiguration.overallDifficulty] + " ms)", Assets.menuSkin, "song_style_result_values"); 71 | accuracyResultLabel = new Label(String.format("%.2f", Results.accuracy * 1000) + " ms.", Assets.menuSkin, "song_style_result_values"); 72 | accuracyRangeResultLabel = new Label(String.format("%.2f", Results.minAccuracy * 1000) + " ms. to " + String.format("%.2f", Results.maxAccuracy * 1000) + " ms.", Assets.menuSkin, "song_style_result_values"); 73 | normalizedAccuracyResultLabel = new Label(String.format("%.2f", Results.normalizedAccuracy * 100f) + "%", Assets.menuSkin, "song_style_result_values"); 74 | unstableRatingValueLabel = new Label(String.format("%.2f", Results.unstableRating * 1000), Assets.menuSkin, "song_style_result_values"); 75 | missResultLabel = new Label(Integer.toString(Results.miss), Assets.menuSkin, "song_style_result_values"); 76 | badResultLabel = new Label(Integer.toString(Results.bads), Assets.menuSkin, "song_style_result_values"); 77 | goodResultLabel = new Label(Integer.toString(Results.goods), Assets.menuSkin, "song_style_result_values"); 78 | greatResultLabel = new Label(Integer.toString(Results.greats), Assets.menuSkin, "song_style_result_values"); 79 | perfectResultLabel = new Label(Integer.toString(Results.perfects), Assets.menuSkin, "song_style_result_values"); 80 | comboResultLabel = new Label(Integer.toString(Results.combo) + (Results.combo == Assets.selectedBeatmap.notes.size() ? " (FC)" : ""), Assets.menuSkin, "song_style_result_values"); 81 | 82 | difficulty.setFontScale(fontScale); 83 | approachRateConfigLabel.setFontScale(fontScale); 84 | overallDifficultyConfigLabel.setFontScale(fontScale); 85 | accuracyResultLabel.setFontScale(fontScale); 86 | accuracyRangeResultLabel.setFontScale(fontScale); 87 | normalizedAccuracyResultLabel.setFontScale(fontScale); 88 | unstableRatingValueLabel.setFontScale(fontScale); 89 | missResultLabel.setFontScale(fontScale); 90 | badResultLabel.setFontScale(fontScale); 91 | goodResultLabel.setFontScale(fontScale); 92 | greatResultLabel.setFontScale(fontScale); 93 | perfectResultLabel.setFontScale(fontScale); 94 | comboResultLabel.setFontScale(fontScale); 95 | 96 | difficultyLabel.setFontScale(fontScale); 97 | approachRateLabel.setFontScale(fontScale); 98 | overallDifficultyLabel.setFontScale(fontScale); 99 | accuracyLabel.setFontScale(fontScale); 100 | accuracyRangeLabel.setFontScale(fontScale); 101 | normalizedAccuracyLabel.setFontScale(fontScale); 102 | unstableRatingLabel.setFontScale(fontScale); 103 | missLabel.setFontScale(fontScale); 104 | badLabel.setFontScale(fontScale); 105 | perfectLabel.setFontScale(fontScale); 106 | goodLabel.setFontScale(fontScale); 107 | greatLabel.setFontScale(fontScale); 108 | comboLabel.setFontScale(fontScale); 109 | 110 | Label songResultTitle = new Label(Assets.selectedBeatmap.metadata.songName.replaceAll("\\\\n", " "), Assets.menuSkin, "results_song_title"); 111 | songResultTitle.setFontScale(fontScale); 112 | 113 | table.add(songResultTitle).colspan(3).row(); 114 | table.add(titleLabel).colspan(3).padBottom(stage.getHeight() * 0.04f).row(); 115 | 116 | table.add(difficulty).fillX(); 117 | table.add().width(stage.getWidth() * 0.2f); 118 | table.add(difficultyLabel).fillX().row(); 119 | table.add(comboLabel).fillX().padBottom(20); 120 | table.add().width(stage.getWidth() * 0.2f).padBottom(20); 121 | table.add(comboResultLabel).fillX().padBottom(20).row(); 122 | 123 | table.add(approachRateLabel).fillX(); 124 | table.add().width(stage.getWidth() * 0.2f); 125 | table.add(approachRateConfigLabel).fillX().row(); 126 | table.add(overallDifficultyLabel).fillX(); 127 | table.add().width(stage.getWidth() * 0.2f); 128 | table.add(overallDifficultyConfigLabel).fillX().row(); 129 | table.add(normalizedAccuracyLabel).fillX(); 130 | table.add().width(stage.getWidth() * 0.2f); 131 | table.add(normalizedAccuracyResultLabel).fillX().row(); 132 | table.add(accuracyLabel).fillX(); 133 | table.add().width(stage.getWidth() * 0.2f); 134 | table.add(accuracyResultLabel).fillX().row(); 135 | table.add(accuracyRangeLabel).fillX(); 136 | table.add().width(stage.getWidth() * 0.2f); 137 | table.add(accuracyRangeResultLabel).fillX().row(); 138 | table.add(unstableRatingLabel).padBottom(20).fillX(); 139 | table.add().width(stage.getWidth() * 0.2f).padBottom(20); 140 | table.add(unstableRatingValueLabel).padBottom(20).fillX().row(); 141 | 142 | table.add(perfectLabel).fillX(); 143 | table.add().width(stage.getWidth() * 0.2f); 144 | table.add(perfectResultLabel).fillX().row(); 145 | table.add(greatLabel).fillX(); 146 | table.add().width(stage.getWidth() * 0.2f); 147 | table.add(greatResultLabel).fillX().row(); 148 | table.add(goodLabel).fillX(); 149 | table.add().width(stage.getWidth() * 0.2f); 150 | table.add(goodResultLabel).fillX().row(); 151 | table.add(badLabel).fillX(); 152 | table.add().width(stage.getWidth() * 0.2f); 153 | table.add(badResultLabel).fillX().row(); 154 | table.add(missLabel).fillX(); 155 | table.add().width(stage.getWidth() * 0.2f); 156 | table.add(missResultLabel).fillX().row(); 157 | 158 | TextButton retryButton = new TextButton("Retry", Assets.menuSkin, "item1"); 159 | TextButton continueButton = new TextButton("Continue", Assets.menuSkin, "item1"); 160 | 161 | retryButton.getLabel().setFontScale(fontScale); 162 | continueButton.getLabel().setFontScale(fontScale); 163 | 164 | retryButton.addListener(new ClickListener() { 165 | @Override 166 | public void clicked(InputEvent event, float x, float y) { 167 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SongScreen()); 168 | } 169 | }); 170 | continueButton.addListener(new ClickListener() { 171 | @Override 172 | public void clicked(InputEvent event, float x, float y) { 173 | ((Game) Gdx.app.getApplicationListener()).setScreen(new SongSelectionScreen()); 174 | } 175 | }); 176 | 177 | table.add(retryButton).width(stage.getWidth() * 0.3f).height(stage.getHeight() * 0.1f); 178 | table.add().fillX(); 179 | table.add(continueButton).width(stage.getWidth() * 0.3f).height(stage.getHeight() * 0.1f).row(); 180 | stage.addActor(table); 181 | 182 | Gdx.input.setInputProcessor(stage); 183 | } 184 | 185 | @Override 186 | public void render(float delta) { 187 | Gdx.gl.glClearColor(0, 0, 0, 1); 188 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 189 | stage.act(); 190 | stage.draw(); 191 | } 192 | 193 | @Override 194 | public void resize(int width, int height) { 195 | 196 | } 197 | 198 | @Override 199 | public void pause() { 200 | 201 | } 202 | 203 | @Override 204 | public void resume() { 205 | 206 | } 207 | 208 | @Override 209 | public void hide() { 210 | dispose(); 211 | } 212 | 213 | @Override 214 | public void dispose() { 215 | stage.dispose(); 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/screens/SongScreen.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.screens; 2 | 3 | import com.badlogic.gdx.Gdx; 4 | import com.badlogic.gdx.Input; 5 | import com.badlogic.gdx.InputProcessor; 6 | import com.badlogic.gdx.Screen; 7 | import com.badlogic.gdx.graphics.GL20; 8 | import com.fteams.sstrain.World; 9 | import com.fteams.sstrain.controller.WorldController; 10 | import com.fteams.sstrain.entities.Results; 11 | import com.fteams.sstrain.renderer.WorldRenderer; 12 | 13 | public class SongScreen implements Screen, InputProcessor { 14 | private World world; 15 | private WorldRenderer renderer; 16 | private WorldController controller; 17 | private int width; 18 | private int height; 19 | 20 | @Override 21 | public void show() { 22 | world = new World(); 23 | Results.clear(); 24 | renderer = new WorldRenderer(world); 25 | controller = new WorldController(world); 26 | Gdx.input.setInputProcessor(this); 27 | } 28 | 29 | @Override 30 | public void render(float delta) { 31 | Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1); 32 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 33 | 34 | controller.update(delta); 35 | renderer.render(); 36 | } 37 | 38 | @Override 39 | public void resize(int width, int height) { 40 | // use height as base and force a 3:2 ratio 41 | int originalWidth = width; 42 | int newWidth = height * 3 / 2; 43 | 44 | int originalHeight = height; 45 | int newHeight = width * 2 / 3; 46 | 47 | // check which side should be shortened 48 | if (newWidth > width) 49 | { 50 | height = newHeight; 51 | } 52 | else 53 | { 54 | width = newWidth; 55 | } 56 | 57 | renderer.setSize(width, height, (originalWidth - width) / 2, (originalHeight - height)/2); 58 | world.setSize(width, height, (originalWidth - width) /2, (originalHeight - height)/2); 59 | this.width = width; 60 | this.height = height; 61 | } 62 | 63 | @Override 64 | public void pause() { 65 | 66 | } 67 | 68 | @Override 69 | public void resume() { 70 | 71 | } 72 | 73 | @Override 74 | public void hide() { 75 | Gdx.input.setInputProcessor(null); 76 | } 77 | 78 | @Override 79 | public void dispose() { 80 | Gdx.input.setInputProcessor(null); 81 | } 82 | 83 | @Override 84 | public boolean keyDown(int keycode) { 85 | 86 | return false; 87 | } 88 | 89 | @Override 90 | public boolean keyUp(int keycode) { 91 | if (keycode == Input.Keys.BACK || keycode == Input.Keys.ESCAPE) { 92 | // do nothing 93 | controller.back(); 94 | return true; 95 | } 96 | return false; 97 | } 98 | 99 | @Override 100 | public boolean keyTyped(char character) { 101 | return false; 102 | } 103 | 104 | @Override 105 | public boolean touchDown(int screenX, int screenY, int pointer, int button) { 106 | controller.pressed(screenX, screenY, pointer, button, renderer.ppuX, renderer.ppuY, width, height); 107 | return true; 108 | } 109 | 110 | @Override 111 | public boolean touchUp(int screenX, int screenY, int pointer, int button) { 112 | controller.released(screenX, screenY, pointer, button, renderer.ppuX, renderer.ppuY, width, height); 113 | return true; 114 | } 115 | 116 | @Override 117 | public boolean touchDragged(int screenX, int screenY, int pointer) { 118 | controller.dragged(screenX, screenY, pointer, renderer.ppuX, renderer.ppuY, width, height); 119 | return true; 120 | } 121 | 122 | @Override 123 | public boolean mouseMoved(int screenX, int screenY) { 124 | return false; 125 | } 126 | 127 | @Override 128 | public boolean scrolled(int amount) { 129 | return false; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/screens/SongSelectionScreen.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.screens; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.badlogic.gdx.Gdx; 5 | import com.badlogic.gdx.Input; 6 | import com.badlogic.gdx.InputMultiplexer; 7 | import com.badlogic.gdx.InputProcessor; 8 | import com.badlogic.gdx.Screen; 9 | import com.badlogic.gdx.audio.Music; 10 | import com.badlogic.gdx.graphics.GL20; 11 | import com.badlogic.gdx.graphics.g2d.BitmapFont; 12 | import com.badlogic.gdx.scenes.scene2d.Actor; 13 | import com.badlogic.gdx.scenes.scene2d.InputEvent; 14 | import com.badlogic.gdx.scenes.scene2d.Stage; 15 | import com.badlogic.gdx.scenes.scene2d.ui.Image; 16 | import com.badlogic.gdx.scenes.scene2d.ui.List; 17 | import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; 18 | import com.badlogic.gdx.scenes.scene2d.ui.Table; 19 | import com.badlogic.gdx.scenes.scene2d.ui.TextButton; 20 | import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; 21 | import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; 22 | import com.badlogic.gdx.utils.viewport.ExtendViewport; 23 | import com.fteams.sstrain.assets.Assets; 24 | import com.fteams.sstrain.config.GlobalConfiguration; 25 | import com.fteams.sstrain.controller.Crossfader; 26 | import com.fteams.sstrain.controller.SongLoader; 27 | import com.fteams.sstrain.entities.Beatmap; 28 | import com.fteams.sstrain.entities.BeatmapGroup; 29 | 30 | @SuppressWarnings("unchecked") 31 | public class SongSelectionScreen implements Screen, InputProcessor { 32 | 33 | private Stage stage = new Stage(new ExtendViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); 34 | private List songList = new List<>(Assets.menuSkin, "diff_list"); 35 | private ScrollPane songListPane = new ScrollPane(null, Assets.menuSkin); 36 | private List diffList = new List<>(Assets.menuSkin, "diff_list"); 37 | private ScrollPane diffListPane = new ScrollPane(null, Assets.menuSkin); 38 | private Table table = new Table(); 39 | private TextButton nextButton = new TextButton("Next", Assets.menuSkin, "item1"); 40 | private TextButton backButton = new TextButton("Back", Assets.menuSkin, "item1"); 41 | private Image backgroundImage = new Image(Assets.mainMenuBackgroundTexture); 42 | private Crossfader previewCrossfader = new Crossfader(); 43 | 44 | private void stopPreviewSong() { 45 | previewCrossfader.dispose(); 46 | } 47 | 48 | private void updatePreviewSong() { 49 | if(Assets.selectedGroup == null) 50 | return; 51 | 52 | Music previewMusic = null; 53 | String musicFile = Assets.selectedGroup.metadata.songFile; 54 | 55 | if(musicFile != null) 56 | previewMusic = SongLoader.loadSongByName(musicFile); 57 | 58 | if(previewMusic == null) 59 | previewMusic = SongLoader.loadSongByName(Assets.selectedGroup.metadata.songName); 60 | 61 | previewCrossfader.enqueue(previewMusic); 62 | } 63 | 64 | @Override 65 | public void show() { 66 | float scaleFactor = stage.getHeight() / GlobalConfiguration.BASE_HEIGHT; 67 | //The elements are displayed in the order you add them. 68 | //The first appear on top, the last at the bottom. 69 | backgroundImage.setSize(stage.getWidth(), stage.getHeight()); 70 | stage.addActor(backgroundImage); 71 | 72 | Assets.songGroup.sort(); 73 | songList.setItems(Assets.songGroup); 74 | 75 | if (Assets.selectedGroup != null) { 76 | songList.setSelected(Assets.selectedGroup); 77 | diffList.setItems(Assets.selectedGroup.beatmaps); 78 | } else { 79 | if (songList.getItems().size != 0) 80 | { 81 | Assets.selectedGroup = songList.getItems().get(0); 82 | diffList.setItems(Assets.selectedGroup.beatmaps); 83 | } 84 | 85 | } 86 | 87 | songList.addListener(new ChangeListener() { 88 | @Override 89 | public void changed(ChangeEvent event, Actor actor) { 90 | BeatmapGroup previousGroup = Assets.selectedGroup; 91 | BeatmapGroup newSelected = (BeatmapGroup) ((List) actor).getSelected(); 92 | if (previousGroup == newSelected) { 93 | // if the same group was selected we ignore it 94 | return; 95 | } 96 | 97 | Assets.selectedGroup = newSelected; 98 | diffList.setItems(newSelected.beatmaps); 99 | updatePreviewSong(); 100 | } 101 | }); 102 | 103 | if (Assets.selectedBeatmap != null) { 104 | diffList.setSelected(Assets.selectedBeatmap); 105 | } else { 106 | diffList.setSelected(diffList.getItems().size == 0 ? null : diffList.getItems().first()); 107 | } 108 | 109 | diffList.addListener(new ChangeListener() { 110 | @Override 111 | public void changed(ChangeEvent event, Actor actor) { 112 | Beatmap previous = Assets.selectedBeatmap; 113 | Beatmap newSelection = (Beatmap) ((List) actor).getSelected(); 114 | if (previous == newSelection) { 115 | return; 116 | } 117 | Assets.selectedBeatmap = newSelection; 118 | } 119 | }); 120 | 121 | nextButton.getLabel().setFontScale(scaleFactor); 122 | backButton.getLabel().setFontScale(scaleFactor); 123 | 124 | songListPane.setWidget(songList); 125 | songListPane.setWidth(stage.getWidth()); 126 | 127 | diffListPane.setWidget(diffList); 128 | diffListPane.setWidth(stage.getWidth()); 129 | 130 | table.add(songListPane).colspan(3).size(stage.getWidth() * 0.87f, stage.getHeight() * 0.49f).padBottom(stage.getHeight() * 0.01f).row(); 131 | table.add(diffListPane).colspan(3).size(stage.getWidth() * 0.87f, stage.getHeight() * 0.23f).padBottom(stage.getHeight() * 0.01f).padTop(stage.getHeight() * 0.01f).row(); 132 | table.setWidth(stage.getWidth()); 133 | table.setHeight(stage.getHeight()); 134 | 135 | backButton.addListener((new ClickListener() { 136 | @Override 137 | public void clicked(InputEvent event, float x, float y) { 138 | Assets.selectedGroup = songList.getSelected(); 139 | Assets.selectedBeatmap = diffList.getSelected(); 140 | stopPreviewSong(); 141 | ((Game) Gdx.app.getApplicationListener()).setScreen(new MainMenuScreen()); 142 | } 143 | })); 144 | nextButton.addListener((new ClickListener() { 145 | @Override 146 | public void clicked(InputEvent event, float x, float y) { 147 | if (diffList.getSelected() == null) { 148 | return; 149 | } 150 | stopPreviewSong(); 151 | Assets.selectedBeatmap = diffList.getSelected(); 152 | ((Game) Gdx.app.getApplicationListener()).setScreen(new LiveOptionsScreen()); 153 | } 154 | })); 155 | table.add(backButton).size(stage.getWidth() * 0.87f / 2, stage.getHeight() * 0.12f); 156 | table.add(nextButton).size(stage.getWidth() * 0.87f / 2, stage.getHeight() * 0.12f); 157 | stage.addActor(table); 158 | 159 | InputMultiplexer impx = new InputMultiplexer(); 160 | impx.addProcessor(this); 161 | impx.addProcessor(stage); 162 | 163 | Gdx.input.setInputProcessor(impx); 164 | Gdx.input.setCatchBackKey(true); 165 | 166 | updatePreviewSong(); 167 | } 168 | 169 | @Override 170 | public void render(float delta) { 171 | Gdx.gl.glClearColor(0, 0, 0, 1); 172 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 173 | 174 | previewCrossfader.update(delta); 175 | songListPane.act(delta); 176 | stage.act(); 177 | stage.draw(); 178 | } 179 | 180 | 181 | @Override 182 | public void resize(int width, int height) { 183 | 184 | } 185 | 186 | @Override 187 | public void pause() { 188 | 189 | } 190 | 191 | @Override 192 | public void resume() { 193 | 194 | } 195 | 196 | @Override 197 | public void hide() { 198 | dispose(); 199 | } 200 | 201 | @Override 202 | public void dispose() { 203 | stopPreviewSong(); 204 | stage.dispose(); 205 | } 206 | 207 | @Override 208 | public boolean keyDown(int keycode) { 209 | return false; 210 | } 211 | 212 | @Override 213 | public boolean keyUp(int keycode) { 214 | if (keycode == Input.Keys.BACK || keycode == Input.Keys.ESCAPE) { 215 | Assets.selectedBeatmap = diffList.getSelected(); 216 | Assets.selectedGroup = songList.getSelected(); 217 | stopPreviewSong(); 218 | ((Game) Gdx.app.getApplicationListener()).setScreen(new MainMenuScreen()); 219 | // do nothing 220 | return true; 221 | } 222 | return false; 223 | } 224 | 225 | @Override 226 | public boolean keyTyped(char character) { 227 | return false; 228 | } 229 | 230 | @Override 231 | public boolean touchDown(int screenX, int screenY, int pointer, int button) { 232 | return false; 233 | } 234 | 235 | @Override 236 | public boolean touchUp(int screenX, int screenY, int pointer, int button) { 237 | return false; 238 | } 239 | 240 | @Override 241 | public boolean touchDragged(int screenX, int screenY, int pointer) { 242 | return false; 243 | } 244 | 245 | @Override 246 | public boolean mouseMoved(int screenX, int screenY) { 247 | return false; 248 | } 249 | 250 | @Override 251 | public boolean scrolled(int amount) { 252 | return false; 253 | } 254 | 255 | } 256 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/screens/SplashScreen.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.screens; 2 | 3 | import com.badlogic.gdx.Game; 4 | import com.badlogic.gdx.Gdx; 5 | import com.badlogic.gdx.Screen; 6 | import com.badlogic.gdx.graphics.GL20; 7 | import com.badlogic.gdx.graphics.Texture; 8 | import com.badlogic.gdx.graphics.g2d.TextureAtlas; 9 | import com.badlogic.gdx.scenes.scene2d.Stage; 10 | import com.badlogic.gdx.scenes.scene2d.actions.Actions; 11 | import com.badlogic.gdx.scenes.scene2d.ui.Image; 12 | import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar; 13 | import com.badlogic.gdx.scenes.scene2d.ui.Skin; 14 | import com.fteams.sstrain.assets.Assets; 15 | import com.fteams.sstrain.config.GlobalConfiguration; 16 | 17 | public class SplashScreen implements Screen { 18 | private Texture texture = new Texture(Gdx.files.internal("bigimages/splash.png")); 19 | private Image splashImage = new Image(texture); 20 | private Stage stage = new Stage(); 21 | private Skin skin = new Skin(Gdx.files.internal("skins/splashSkin.json"), new TextureAtlas(Gdx.files.internal("textures/textures.pack.atlas"))); 22 | private ProgressBar loadingProgress = new ProgressBar(0.0f, 100f, 0.1f, false, skin); 23 | 24 | public boolean animationDone = false; 25 | int phase = 0; 26 | 27 | @Override 28 | public void render(float delta) { 29 | Gdx.gl.glClearColor(0, 0, 0, 1); 30 | Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 31 | stage.act(); 32 | stage.draw(); 33 | 34 | if (Assets.update()) { // check if all files are loaded 35 | 36 | if (animationDone) { // when the animation is finished, go to MainMenu() 37 | // load the assets to into the Assets class 38 | Assets.setMenuSkin(); 39 | Assets.setHitsounds(); 40 | Assets.setTextures(); 41 | Assets.setFonts(); 42 | if (phase == 1) { 43 | Assets.setSongs(); 44 | ((Game) Gdx.app.getApplicationListener()).setScreen(new MainMenuScreen()); 45 | } 46 | if (phase == 0) { 47 | phase++; 48 | Assets.reloadBeatmaps(); 49 | } 50 | } 51 | } 52 | loadingProgress.setValue(phase == 0 ? Assets.getProgress() * 100f : (Assets.getProgress() - 0.5f) * 200f); 53 | loadingProgress.act(delta); 54 | } 55 | 56 | @Override 57 | public void resize(int width, int height) { 58 | } 59 | 60 | @Override 61 | public void show() { 62 | float sourceHeight = texture.getHeight(); 63 | float targetHeight = stage.getHeight(); 64 | float scale = targetHeight / sourceHeight; 65 | 66 | splashImage.setScale(scale); 67 | splashImage.setX(stage.getWidth() / 2 - (scale * splashImage.getWidth()) / 2); 68 | 69 | loadingProgress.setSize(scale * splashImage.getWidth() * 0.7f, stage.getHeight() * 0.07f); 70 | loadingProgress.setX(splashImage.getX() + scale * splashImage.getWidth() * 0.15f); 71 | loadingProgress.setY(stage.getHeight() * 0.2f); 72 | loadingProgress.setAnimateDuration(0.01f); 73 | 74 | stage.addActor(splashImage); 75 | stage.addActor(loadingProgress); 76 | 77 | //splashImage.setX(stage.getWidth() / 2 - width / 2); 78 | splashImage.addAction(Actions.sequence(Actions.alpha(0) 79 | , Actions.fadeIn(0.75f), Actions.delay(1.5f), Actions.run(new Runnable() { 80 | @Override 81 | public void run() { 82 | animationDone = true; 83 | } 84 | }))); 85 | // Queue loading will load 2 sets of assets: 86 | // internal assets: images and hit sounds 87 | // external assets: beatmaps 88 | // while processing external assets, it may also install .osz beatmaps 89 | // or convert .osu files, which is why after the first pass is completed, 90 | // we update the set of loaded maps to include the recently extracted maps 91 | // if nothing was installed or changed, the second phase won't last long. 92 | Assets.queueLoading(); 93 | GlobalConfiguration.loadConfiguration(); 94 | } 95 | 96 | @Override 97 | public void hide() { 98 | dispose(); 99 | } 100 | 101 | @Override 102 | public void pause() { 103 | } 104 | 105 | @Override 106 | public void resume() { 107 | } 108 | 109 | @Override 110 | public void dispose() { 111 | GlobalConfiguration.storeConfiguration(); 112 | texture.dispose(); 113 | stage.dispose(); 114 | } 115 | } 116 | 117 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/util/Accuracy.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.util; 2 | 3 | public enum Accuracy { 4 | PERFECT, 5 | GREAT, 6 | NICE, 7 | BAD, 8 | MISS, 9 | NONE 10 | } 11 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/util/SongUtils.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.util; 2 | 3 | public class SongUtils { 4 | public final static Long NOTE_TYPE_NORMAL = 1l; 5 | public final static Long NOTE_TYPE_HOLD = 2l; 6 | 7 | public final static Integer NOTE_SYNC_OFF = 0; 8 | public final static Integer NOTE_SYNC_ON = 1; 9 | 10 | public final static Long NOTE_NO_SWIPE = 0L; 11 | public final static Long NOTE_SWIPE_LEFT = 1L; 12 | public final static Long NOTE_SWIPE_RIGHT = 2L; 13 | 14 | public final static Integer SORTING_MODE_FILE_NAME = 0; 15 | public final static Integer SORTING_MODE_SONG_NAME = 1; 16 | public final static Integer SORTING_MODE_SONG_ID = 2; 17 | public final static Integer SORTING_MODE_ATTRIBUTE = 3; 18 | 19 | public final static Integer SORTING_MODE_ASCENDING = 0; 20 | public final static Integer SORTING_MODE_DESCENDING = 1; 21 | 22 | public final static Integer SYNC_MODE_1 = 0; 23 | public final static Integer SYNC_MODE_2 = 1; 24 | public final static Integer SYNC_MODE_3 = 2; 25 | public final static Integer SYNC_DISABLED = 3; 26 | 27 | public final static Integer GAME_MODE_NORMAL = 0; 28 | public final static Integer GAME_MODE_ABREPEAT = 1; 29 | 30 | public final static String[] syncModes = {"Default", "Constant Sync", "Initial Sync", "Disabled"}; 31 | public final static Long[] noteSpeeds = {1800L, 1680L, 1560L, 1440L, 1320L, 1200L, 1050L, 900L, 750L, 600L, 450L}; 32 | 33 | public final static Double[] overallDiffPerfect = {79.5, 73.5, 67.5, 61.5, 56.5, 49.5, 43.5, 37.5, 31.5, 25.5, 19.5}; // -6 34 | public final static Double[] overallDiffGreat = {139.5, 131.5, 123.5, 115.5, 107.5, 99.5, 91.5, 83.5, 75.5, 67.5, 59.5}; // -8 35 | public final static Double[] overallDiffNice = {199.5, 189.5, 179.5, 169.5, 159.5, 149.5, 139.5, 129.5, 119.5, 109.5, 99.5}; // - 10 36 | public final static Double[] overallDiffBad = {249.5, 237.5, 225.5, 213.5, 201.5, 189.5, 177.5, 165.5, 153.5, 141.5, 129.5};// - 12 37 | 38 | public static Long getSpeedFromConfig(Integer noteSpeed) { 39 | return noteSpeeds[noteSpeed]; 40 | } 41 | 42 | public final static String[] attributes = {"Cute", "Cool", "Passion", "ALL"}; 43 | 44 | public static String getAttribute(Long attribute) { 45 | if (attribute == null) { 46 | return "Unknown"; 47 | } 48 | if (attribute == 0) { 49 | return "TUTORIAL"; 50 | } 51 | return attributes[(int) (attribute - 1)]; 52 | } 53 | 54 | public static int compare(int x, int y) { 55 | return (x < y) ? -1 : ((x == y) ? 0 : 1); 56 | } 57 | 58 | public static int compare(long x, long y) { 59 | return (x < y) ? -1 : ((x == y) ? 0 : 1); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /core/src/com/fteams/sstrain/util/Tips.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.util; 2 | 3 | import java.util.Random; 4 | 5 | public class Tips { 6 | public static final String [] tips = { 7 | "Do you feel you're having ease when clearing songs? Try increasing the Overall Difficulty in the Settings > Timing settings.", 8 | "The game feels slow? Try increasing the Approach Rate in the Settings > Timing settings.", 9 | "Did you know that you can load new beatmaps without having to restart the game? Go into Settings > Other > Reload Beatmaps!", 10 | "Can't quite get the beat of the song? Try enabling hint sounds in Settings > Volume settings.", 11 | "Do you feel the timing window is too small? Try decreasing the Overall Difficulty in the Settings > Timing settings.", 12 | "If you can't react fast enough to tap on time, try decreasing the Approach Rate in the Settings > Timing settings.", 13 | "If the notes slow down and speed up, teleport, or stutter, try changing the Sync mode in Settings > Timing settings.", 14 | "Did you know that you can sort the song list in the song selection screen? Check Settings > Other. ", 15 | "Did you know that you can play a small fragment of the song in the A-B Repeat mode?\nWarning: There may be sound sync problems, try different timestamps until something sticks!", 16 | "Did you know that you can change the speed of a song to practice it in slo-mo? Try the changing the playback rate option after selecting a song.\nNote: Due to library limitations, music playback rate can't be changed so these attempts will have no music.", 17 | "Did you notice there's no ads in this app?", 18 | "If you've enjoyed using this app, why not rate it on Google Play?" 19 | }; 20 | 21 | public static String getRandomTip() 22 | { 23 | Random random = new Random(System.nanoTime()); 24 | return "Tip: " + tips[Math.abs(random.nextInt())%tips.length]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /desktop/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "java" 2 | 3 | sourceCompatibility = 1.7 4 | sourceSets.main.java.srcDirs = [ "src/" ] 5 | 6 | project.ext.mainClassName = "com.fteams.sstrain.desktop.DesktopLauncher" 7 | project.ext.assetsDir = new File("../android/assets"); 8 | 9 | task run(dependsOn: classes, type: JavaExec) { 10 | main = project.mainClassName 11 | classpath = sourceSets.main.runtimeClasspath 12 | standardInput = System.in 13 | workingDir = project.assetsDir 14 | ignoreExitValue = true 15 | } 16 | 17 | task dist(type: Jar) { 18 | from files(sourceSets.main.output.classesDir) 19 | from files(sourceSets.main.output.resourcesDir) 20 | from {configurations.compile.collect {zipTree(it)}} 21 | from files(project.assetsDir); 22 | 23 | manifest { 24 | attributes 'Main-Class': project.mainClassName 25 | } 26 | } 27 | 28 | dist.dependsOn classes 29 | 30 | eclipse { 31 | project { 32 | name = appName + "-desktop" 33 | linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/android/assets' 34 | } 35 | } 36 | 37 | task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { 38 | doLast { 39 | def classpath = new XmlParser().parse(file(".classpath")) 40 | new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]); 41 | def writer = new FileWriter(file(".classpath")) 42 | def printer = new XmlNodePrinter(new PrintWriter(writer)) 43 | printer.setPreserveWhitespace(true) 44 | printer.print(classpath) 45 | } 46 | } -------------------------------------------------------------------------------- /desktop/src/com/fteams/sstrain/desktop/DesktopLauncher.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.desktop; 2 | 3 | import com.badlogic.gdx.backends.lwjgl.LwjglApplication; 4 | import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; 5 | import com.fteams.sstrain.SSTrain; 6 | import com.fteams.sstrain.config.GlobalConfiguration; 7 | 8 | public class DesktopLauncher { 9 | public static void main (String[] arg) { 10 | LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); 11 | GlobalConfiguration.appVersionName = "debug build."; 12 | new LwjglApplication(new SSTrain(), "SS Train", 1280, 720); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /desktop/src/com/fteams/sstrain/desktop/TextureSetup.java: -------------------------------------------------------------------------------- 1 | package com.fteams.sstrain.desktop; 2 | 3 | import com.badlogic.gdx.tools.texturepacker.TexturePacker; 4 | 5 | public class TextureSetup { 6 | 7 | public static void main(String[] args) { 8 | TexturePacker.Settings config = new TexturePacker.Settings(); 9 | config.maxWidth = 512; 10 | config.maxHeight = 512; 11 | TexturePacker.process(config, "images/", "textures/", "textures.pack"); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.daemon=true 2 | org.gradle.jvmargs=-Xms128m -Xmx512m 3 | org.gradle.configureondemand=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kbz/SSTrain/333b965798af9b74fff8e2f102ae715d1552c4d0/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Sep 21 13:08:26 CEST 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-2.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'desktop', 'android', 'core' --------------------------------------------------------------------------------