diff --git a/RhythmBullet.sln b/RhythmBullet.sln new file mode 100644 index 0000000..f8a44a5 --- /dev/null +++ b/RhythmBullet.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2019 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RhythmBullet", "RhythmBullet\RhythmBullet.csproj", "{4242553D-40F9-40F0-9AE6-CB6771DD9CF9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4242553D-40F9-40F0-9AE6-CB6771DD9CF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4242553D-40F9-40F0-9AE6-CB6771DD9CF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4242553D-40F9-40F0-9AE6-CB6771DD9CF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4242553D-40F9-40F0-9AE6-CB6771DD9CF9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C7334E35-D9AE-4FF0-A8AE-DC3A1ED7CB86} + EndGlobalSection +EndGlobal diff --git a/RhythmBullet/Content/Content.mgcb b/RhythmBullet/Content/Content.mgcb new file mode 100644 index 0000000..ddc4c36 --- /dev/null +++ b/RhythmBullet/Content/Content.mgcb @@ -0,0 +1,15 @@ + +#----------------------------- Global Properties ----------------------------# + +/outputDir:bin/$(Platform) +/intermediateDir:obj/$(Platform) +/platform:DesktopGL +/config: +/profile:Reach +/compress:False + +#-------------------------------- References --------------------------------# + + +#---------------------------------- Content ---------------------------------# + diff --git a/RhythmBullet/Icon.bmp b/RhythmBullet/Icon.bmp new file mode 100644 index 0000000..2b48165 Binary files /dev/null and b/RhythmBullet/Icon.bmp differ diff --git a/RhythmBullet/Icon.ico b/RhythmBullet/Icon.ico new file mode 100644 index 0000000..7d9dec1 Binary files /dev/null and b/RhythmBullet/Icon.ico differ diff --git a/RhythmBullet/Program.cs b/RhythmBullet/Program.cs new file mode 100644 index 0000000..1aff434 --- /dev/null +++ b/RhythmBullet/Program.cs @@ -0,0 +1,22 @@ +using System; + +namespace RhythmBullet +{ + /// + /// The main class. + /// + public static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + using (var game = new RhythmBulletGame()) + { + game.Run(); + } + } + } +} diff --git a/RhythmBullet/Properties/AssemblyInfo.cs b/RhythmBullet/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..33238ab --- /dev/null +++ b/RhythmBullet/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RhythmBullet")] +[assembly: AssemblyProduct("RhythmBullet")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("78eb6f5c-0f37-458a-9928-0fd0799c93a5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/RhythmBullet/RhythmBullet.csproj b/RhythmBullet/RhythmBullet.csproj new file mode 100644 index 0000000..d1e7e6b --- /dev/null +++ b/RhythmBullet/RhythmBullet.csproj @@ -0,0 +1,123 @@ + + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {4242553D-40F9-40F0-9AE6-CB6771DD9CF9} + WinExe + Properties + RhythmBullet + RhythmBullet + 512 + DesktopGL + v4.5 + + + true + bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\ + DEBUG;TRACE;LINUX + full + AnyCPU + prompt + false + 4 + + + bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\ + TRACE;LINUX + true + pdbonly + AnyCPU + prompt + false + 4 + + + Icon.ico + + + app.manifest + + + + + + + + + + + + $(MonoGameInstallDirectory)\MonoGame\v3.0\Assemblies\DesktopGL\MonoGame.Framework.dll + + + + + + + + + + + + x86\SDL2.dll + PreserveNewest + + + x64\SDL2.dll + PreserveNewest + + + x86\soft_oal.dll + PreserveNewest + + + x64\soft_oal.dll + PreserveNewest + + + x86\libSDL2-2.0.so.0 + PreserveNewest + + + x64\libSDL2-2.0.so.0 + PreserveNewest + + + x86\libopenal.so.1 + PreserveNewest + + + x64\libopenal.so.1 + PreserveNewest + + + libSDL2-2.0.0.dylib + PreserveNewest + + + libopenal.1.dylib + PreserveNewest + + + MonoGame.Framework.dll.config + PreserveNewest + + + + + + + + + + \ No newline at end of file diff --git a/RhythmBullet/RhythmBulletGame.cs b/RhythmBullet/RhythmBulletGame.cs new file mode 100644 index 0000000..a8bff22 --- /dev/null +++ b/RhythmBullet/RhythmBulletGame.cs @@ -0,0 +1,85 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using RhythmBullet.Zer01HD.UI.Screen; + +namespace RhythmBullet +{ + /// + /// This is the main type for your game. + /// + public class RhythmBulletGame : Game + { + private Screen currentScreen; + + GraphicsDeviceManager graphics; + SpriteBatch spriteBatch; + + public RhythmBulletGame() + { + graphics = new GraphicsDeviceManager(this); + Content.RootDirectory = "Content"; + graphics.PreferredBackBufferWidth = 1920; + graphics.PreferredBackBufferHeight = 1080; + } + + /// + /// Allows the game to perform any initialization it needs to before starting to run. + /// This is where it can query for any required services and load any non-graphic + /// related content. Calling base.Initialize will enumerate through any components + /// and initialize them as well. + /// + protected override void Initialize() + { + // TODO: Add your initialization logic here + base.Initialize(); + } + + /// + /// LoadContent will be called once per game and is the place to load + /// all of your content. + /// + protected override void LoadContent() + { + // Create a new SpriteBatch, which can be used to draw textures. + spriteBatch = new SpriteBatch(GraphicsDevice); + // TODO: use this.Content to load your game content here + } + + /// + /// UnloadContent will be called once per game and is the place to unload + /// game-specific content. + /// + protected override void UnloadContent() + { + // TODO: Unload any non ContentManager content here + } + + /// + /// Allows the game to run logic such as updating the world, + /// checking for collisions, gathering input, and playing audio. + /// + /// Provides a snapshot of timing values. + protected override void Update(GameTime gameTime) + { + if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); + + // TODO: Add your update logic here + + base.Update(gameTime); + } + + /// + /// This is called when the game should draw itself. + /// + /// Provides a snapshot of timing values. + protected override void Draw(GameTime gameTime) + { + GraphicsDevice.Clear(Color.CornflowerBlue); + + // TODO: Add your drawing code here + + base.Draw(gameTime); + } + } +} diff --git a/RhythmBullet/Zer01HD/UI/Page/Page.cs b/RhythmBullet/Zer01HD/UI/Page/Page.cs new file mode 100644 index 0000000..8e39ab8 --- /dev/null +++ b/RhythmBullet/Zer01HD/UI/Page/Page.cs @@ -0,0 +1,29 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RhythmBullet.Zer01HD.UI +{ + class Page + { + private int x, y; + public Page() + { + + } + + public void Update(GameTime gameTime) + { + + } + + public void Draw(SpriteBatch batch) + { + + } + } +} diff --git a/RhythmBullet/Zer01HD/UI/Page/PageManager.cs b/RhythmBullet/Zer01HD/UI/Page/PageManager.cs new file mode 100644 index 0000000..df1e898 --- /dev/null +++ b/RhythmBullet/Zer01HD/UI/Page/PageManager.cs @@ -0,0 +1,31 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RhythmBullet.Zer01HD.UI +{ + class PageManager + { + private readonly List pages = new List(); + + public void Act(GameTime gameTime) + { + foreach (Page page in pages) + { + page.act(gameTime); + } + } + + public void Draw(SpriteBatch spriteBatch) + { + foreach (Page page in pages) + { + page.draw(spriteBatch); + } + } + } +} diff --git a/RhythmBullet/Zer01HD/UI/Screen/Screen.cs b/RhythmBullet/Zer01HD/UI/Screen/Screen.cs new file mode 100644 index 0000000..2bf3283 --- /dev/null +++ b/RhythmBullet/Zer01HD/UI/Screen/Screen.cs @@ -0,0 +1,33 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RhythmBullet.Zer01HD.UI.Screen +{ + class Screen + { + public void Update(GameTime gameTime) + { + + } + + public void Draw(SpriteBatch spriteBatch) + { + + } + + public void Show() + { + + } + + public void Hide() + { + + } + } +} diff --git a/RhythmBullet/app.manifest b/RhythmBullet/app.manifest new file mode 100644 index 0000000..ed00b80 --- /dev/null +++ b/RhythmBullet/app.manifest @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true/pm + + + + diff --git a/old/.classpath b/old/.classpath new file mode 100644 index 0000000..e4d0db4 --- /dev/null +++ b/old/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/old/.gradle/4.6/fileChanges/last-build.bin b/old/.gradle/4.6/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/old/.gradle/4.6/fileChanges/last-build.bin differ diff --git a/old/.gradle/4.6/fileHashes/fileHashes.bin b/old/.gradle/4.6/fileHashes/fileHashes.bin new file mode 100644 index 0000000..80d9885 Binary files /dev/null and b/old/.gradle/4.6/fileHashes/fileHashes.bin differ diff --git a/old/.gradle/4.6/fileHashes/fileHashes.lock b/old/.gradle/4.6/fileHashes/fileHashes.lock new file mode 100644 index 0000000..9ac3fd1 Binary files /dev/null and b/old/.gradle/4.6/fileHashes/fileHashes.lock differ diff --git a/old/.gradle/4.6/taskHistory/taskHistory.bin b/old/.gradle/4.6/taskHistory/taskHistory.bin new file mode 100644 index 0000000..c312825 Binary files /dev/null and b/old/.gradle/4.6/taskHistory/taskHistory.bin differ diff --git a/old/.gradle/4.6/taskHistory/taskHistory.lock b/old/.gradle/4.6/taskHistory/taskHistory.lock new file mode 100644 index 0000000..431ea0e Binary files /dev/null and b/old/.gradle/4.6/taskHistory/taskHistory.lock differ diff --git a/old/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/old/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000..cc3c6b5 Binary files /dev/null and b/old/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/old/.gradle/buildOutputCleanup/cache.properties b/old/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..e905e7b --- /dev/null +++ b/old/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Mon Sep 10 00:40:35 CDT 2018 +gradle.version=4.6 diff --git a/old/.gradle/buildOutputCleanup/outputFiles.bin b/old/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000..60d5744 Binary files /dev/null and b/old/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/old/.gradle/vcsWorkingDirs/gc.properties b/old/.gradle/vcsWorkingDirs/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/old/.project b/old/.project new file mode 100644 index 0000000..cb1ec43 --- /dev/null +++ b/old/.project @@ -0,0 +1,42 @@ + + + RhythmBullet + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.springsource.ide.eclipse.gradle.core.nature + org.eclipse.jdt.core.javanature + + + + 1536558856206 + + 26 + + org.eclipse.ui.ide.orFilterMatcher + + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-equals-true-false-android + + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-equals-true-false-core + + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-equals-true-false-desktop + + + + + + diff --git a/old/.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs b/old/.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs new file mode 100644 index 0000000..528428a --- /dev/null +++ b/old/.settings/gradle/org.springsource.ide.eclipse.gradle.core.import.prefs @@ -0,0 +1,9 @@ +#org.springsource.ide.eclipse.gradle.core.preferences.GradleImportPreferences +#Mon Sep 10 00:40:31 CDT 2018 +addResourceFilters=true +afterTasks=afterEclipseImport; +beforeTasks=cleanEclipse;eclipse; +enableAfterTasks=true +enableBeforeTasks=true +enableDependendencyManagement=true +projects=;android;core;desktop; diff --git a/old/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs b/old/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs new file mode 100644 index 0000000..5ca5389 --- /dev/null +++ b/old/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs @@ -0,0 +1,5 @@ +#org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences +#Mon Sep 10 00:40:41 CDT 2018 +build.family.org.gradle.tooling.model.eclipse.HierarchicalEclipseProject=;android;core;desktop; +org.springsource.ide.eclipse.gradle.linkedresources= +org.springsource.ide.eclipse.gradle.rootprojectloc= diff --git a/old/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs b/old/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs new file mode 100644 index 0000000..fa38a70 --- /dev/null +++ b/old/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs @@ -0,0 +1,8 @@ +#org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences +#Mon Sep 10 00:40:36 CDT 2018 +addResourceFilters=true +afterTasks=afterEclipseImport; +beforeTasks=cleanEclipse;eclipse; +enableAfterTasks=true +enableBeforeTasks=true +useHierarchicalNames=false diff --git a/old/android/.classpath b/old/android/.classpath new file mode 100644 index 0000000..aafed56 --- /dev/null +++ b/old/android/.classpath @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/old/android/.project b/old/android/.project new file mode 100644 index 0000000..4336ea1 --- /dev/null +++ b/old/android/.project @@ -0,0 +1,34 @@ + + + RhythmBullet-android + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + org.springsource.ide.eclipse.gradle.core.nature + org.eclipse.jdt.core.javanature + com.android.ide.eclipse.adt.AndroidNature + + diff --git a/old/android/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs b/old/android/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs new file mode 100644 index 0000000..82b46a5 --- /dev/null +++ b/old/android/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs @@ -0,0 +1,4 @@ +#org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences +#Mon Sep 10 00:40:48 CDT 2018 +org.springsource.ide.eclipse.gradle.linkedresources= +org.springsource.ide.eclipse.gradle.rootprojectloc=.. diff --git a/old/android/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs b/old/android/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs new file mode 100644 index 0000000..599cb88 --- /dev/null +++ b/old/android/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs @@ -0,0 +1,8 @@ +#org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences +#Mon Sep 10 00:40:41 CDT 2018 +addResourceFilters=true +afterTasks=afterEclipseImport; +beforeTasks=cleanEclipse;eclipse; +enableAfterTasks=true +enableBeforeTasks=true +useHierarchicalNames=false diff --git a/old/android/.settings/org.eclipse.jdt.core.prefs b/old/android/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..67f499c --- /dev/null +++ b/old/android/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,13 @@ +# +#Mon Sep 10 00:54:15 CDT 2018 +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error diff --git a/old/android/AndroidManifest.xml b/old/android/AndroidManifest.xml new file mode 100644 index 0000000..9919a07 --- /dev/null +++ b/old/android/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + diff --git a/old/android/assets/1280x720/Shooter1.png b/old/android/assets/1280x720/Shooter1.png new file mode 100644 index 0000000..12e54e3 Binary files /dev/null and b/old/android/assets/1280x720/Shooter1.png differ diff --git a/old/android/assets/1280x720/Tech-Circle1.png b/old/android/assets/1280x720/Tech-Circle1.png new file mode 100644 index 0000000..4229dfe Binary files /dev/null and b/old/android/assets/1280x720/Tech-Circle1.png differ diff --git a/old/android/assets/1280x720/backgrounds/mainBG.png b/old/android/assets/1280x720/backgrounds/mainBG.png new file mode 100644 index 0000000..e93e249 Binary files /dev/null and b/old/android/assets/1280x720/backgrounds/mainBG.png differ diff --git a/old/android/assets/1280x720/bar.png b/old/android/assets/1280x720/bar.png new file mode 100644 index 0000000..606fd37 Binary files /dev/null and b/old/android/assets/1280x720/bar.png differ diff --git a/old/android/assets/1280x720/cybercircle1.png b/old/android/assets/1280x720/cybercircle1.png new file mode 100644 index 0000000..c40498d Binary files /dev/null and b/old/android/assets/1280x720/cybercircle1.png differ diff --git a/old/android/assets/1280x720/cybercircle3B.png b/old/android/assets/1280x720/cybercircle3B.png new file mode 100644 index 0000000..a8a2dd6 Binary files /dev/null and b/old/android/assets/1280x720/cybercircle3B.png differ diff --git a/old/android/assets/1280x720/flake.png b/old/android/assets/1280x720/flake.png new file mode 100644 index 0000000..341d8a2 Binary files /dev/null and b/old/android/assets/1280x720/flake.png differ diff --git a/old/android/assets/1280x720/laser.png b/old/android/assets/1280x720/laser.png new file mode 100644 index 0000000..e5aa06b Binary files /dev/null and b/old/android/assets/1280x720/laser.png differ diff --git a/old/android/assets/1280x720/magic1.png b/old/android/assets/1280x720/magic1.png new file mode 100644 index 0000000..e24db14 Binary files /dev/null and b/old/android/assets/1280x720/magic1.png differ diff --git a/old/android/assets/1280x720/pellet.png b/old/android/assets/1280x720/pellet.png new file mode 100644 index 0000000..a9e7562 Binary files /dev/null and b/old/android/assets/1280x720/pellet.png differ diff --git a/old/android/assets/1280x720/polyjet-standard.png b/old/android/assets/1280x720/polyjet-standard.png new file mode 100644 index 0000000..286ad5d Binary files /dev/null and b/old/android/assets/1280x720/polyjet-standard.png differ diff --git a/old/android/assets/1280x720/shard.png b/old/android/assets/1280x720/shard.png new file mode 100644 index 0000000..d1574ea Binary files /dev/null and b/old/android/assets/1280x720/shard.png differ diff --git a/old/android/assets/1280x720/square.png b/old/android/assets/1280x720/square.png new file mode 100644 index 0000000..ad1c849 Binary files /dev/null and b/old/android/assets/1280x720/square.png differ diff --git a/old/android/assets/1280x720/title.png b/old/android/assets/1280x720/title.png new file mode 100644 index 0000000..9be0ad6 Binary files /dev/null and b/old/android/assets/1280x720/title.png differ diff --git a/old/android/assets/1280x720/tpSelector.png b/old/android/assets/1280x720/tpSelector.png new file mode 100644 index 0000000..0796baf Binary files /dev/null and b/old/android/assets/1280x720/tpSelector.png differ diff --git a/old/android/assets/1280x720/void_circle.png b/old/android/assets/1280x720/void_circle.png new file mode 100644 index 0000000..28a9e58 Binary files /dev/null and b/old/android/assets/1280x720/void_circle.png differ diff --git a/old/android/assets/1280x800/Shooter1.png b/old/android/assets/1280x800/Shooter1.png new file mode 100644 index 0000000..75878cb Binary files /dev/null and b/old/android/assets/1280x800/Shooter1.png differ diff --git a/old/android/assets/1280x800/Tech-Circle1.png b/old/android/assets/1280x800/Tech-Circle1.png new file mode 100644 index 0000000..bd661d3 Binary files /dev/null and b/old/android/assets/1280x800/Tech-Circle1.png differ diff --git a/old/android/assets/1280x800/backgrounds/mainBG.png b/old/android/assets/1280x800/backgrounds/mainBG.png new file mode 100644 index 0000000..4c9d321 Binary files /dev/null and b/old/android/assets/1280x800/backgrounds/mainBG.png differ diff --git a/old/android/assets/1280x800/bar.png b/old/android/assets/1280x800/bar.png new file mode 100644 index 0000000..deb93bd Binary files /dev/null and b/old/android/assets/1280x800/bar.png differ diff --git a/old/android/assets/1280x800/cybercircle1.png b/old/android/assets/1280x800/cybercircle1.png new file mode 100644 index 0000000..2edc4d1 Binary files /dev/null and b/old/android/assets/1280x800/cybercircle1.png differ diff --git a/old/android/assets/1280x800/cybercircle3B.png b/old/android/assets/1280x800/cybercircle3B.png new file mode 100644 index 0000000..6f5ab4e Binary files /dev/null and b/old/android/assets/1280x800/cybercircle3B.png differ diff --git a/old/android/assets/1280x800/flake.png b/old/android/assets/1280x800/flake.png new file mode 100644 index 0000000..67076c3 Binary files /dev/null and b/old/android/assets/1280x800/flake.png differ diff --git a/old/android/assets/1280x800/laser.png b/old/android/assets/1280x800/laser.png new file mode 100644 index 0000000..5b82d55 Binary files /dev/null and b/old/android/assets/1280x800/laser.png differ diff --git a/old/android/assets/1280x800/magic1.png b/old/android/assets/1280x800/magic1.png new file mode 100644 index 0000000..22f3f3b Binary files /dev/null and b/old/android/assets/1280x800/magic1.png differ diff --git a/old/android/assets/1280x800/pellet.png b/old/android/assets/1280x800/pellet.png new file mode 100644 index 0000000..7ea8abc Binary files /dev/null and b/old/android/assets/1280x800/pellet.png differ diff --git a/old/android/assets/1280x800/polyjet-standard.png b/old/android/assets/1280x800/polyjet-standard.png new file mode 100644 index 0000000..63fe63d Binary files /dev/null and b/old/android/assets/1280x800/polyjet-standard.png differ diff --git a/old/android/assets/1280x800/shard.png b/old/android/assets/1280x800/shard.png new file mode 100644 index 0000000..a29a60d Binary files /dev/null and b/old/android/assets/1280x800/shard.png differ diff --git a/old/android/assets/1280x800/square.png b/old/android/assets/1280x800/square.png new file mode 100644 index 0000000..4759b27 Binary files /dev/null and b/old/android/assets/1280x800/square.png differ diff --git a/old/android/assets/1280x800/title.png b/old/android/assets/1280x800/title.png new file mode 100644 index 0000000..ca71aa0 Binary files /dev/null and b/old/android/assets/1280x800/title.png differ diff --git a/old/android/assets/1280x800/tpSelector.png b/old/android/assets/1280x800/tpSelector.png new file mode 100644 index 0000000..6228a48 Binary files /dev/null and b/old/android/assets/1280x800/tpSelector.png differ diff --git a/old/android/assets/1280x800/void_circle.png b/old/android/assets/1280x800/void_circle.png new file mode 100644 index 0000000..edca8e5 Binary files /dev/null and b/old/android/assets/1280x800/void_circle.png differ diff --git a/old/android/assets/1366x768/Shooter1.png b/old/android/assets/1366x768/Shooter1.png new file mode 100644 index 0000000..6632c4a Binary files /dev/null and b/old/android/assets/1366x768/Shooter1.png differ diff --git a/old/android/assets/1366x768/Tech-Circle1.png b/old/android/assets/1366x768/Tech-Circle1.png new file mode 100644 index 0000000..bb78f62 Binary files /dev/null and b/old/android/assets/1366x768/Tech-Circle1.png differ diff --git a/old/android/assets/1366x768/backgrounds/mainBG.png b/old/android/assets/1366x768/backgrounds/mainBG.png new file mode 100644 index 0000000..75fd847 Binary files /dev/null and b/old/android/assets/1366x768/backgrounds/mainBG.png differ diff --git a/old/android/assets/1366x768/bar.png b/old/android/assets/1366x768/bar.png new file mode 100644 index 0000000..951f25b Binary files /dev/null and b/old/android/assets/1366x768/bar.png differ diff --git a/old/android/assets/1366x768/cybercircle1.png b/old/android/assets/1366x768/cybercircle1.png new file mode 100644 index 0000000..2d205ef Binary files /dev/null and b/old/android/assets/1366x768/cybercircle1.png differ diff --git a/old/android/assets/1366x768/cybercircle3B.png b/old/android/assets/1366x768/cybercircle3B.png new file mode 100644 index 0000000..8af9f1e Binary files /dev/null and b/old/android/assets/1366x768/cybercircle3B.png differ diff --git a/old/android/assets/1366x768/flake.png b/old/android/assets/1366x768/flake.png new file mode 100644 index 0000000..78056c2 Binary files /dev/null and b/old/android/assets/1366x768/flake.png differ diff --git a/old/android/assets/1366x768/laser.png b/old/android/assets/1366x768/laser.png new file mode 100644 index 0000000..18034cc Binary files /dev/null and b/old/android/assets/1366x768/laser.png differ diff --git a/old/android/assets/1366x768/magic1.png b/old/android/assets/1366x768/magic1.png new file mode 100644 index 0000000..ab2fefd Binary files /dev/null and b/old/android/assets/1366x768/magic1.png differ diff --git a/old/android/assets/1366x768/pellet.png b/old/android/assets/1366x768/pellet.png new file mode 100644 index 0000000..a9e7562 Binary files /dev/null and b/old/android/assets/1366x768/pellet.png differ diff --git a/old/android/assets/1366x768/polyjet-standard.png b/old/android/assets/1366x768/polyjet-standard.png new file mode 100644 index 0000000..9a5c154 Binary files /dev/null and b/old/android/assets/1366x768/polyjet-standard.png differ diff --git a/old/android/assets/1366x768/shard.png b/old/android/assets/1366x768/shard.png new file mode 100644 index 0000000..97083d9 Binary files /dev/null and b/old/android/assets/1366x768/shard.png differ diff --git a/old/android/assets/1366x768/square.png b/old/android/assets/1366x768/square.png new file mode 100644 index 0000000..d2896d5 Binary files /dev/null and b/old/android/assets/1366x768/square.png differ diff --git a/old/android/assets/1366x768/title.png b/old/android/assets/1366x768/title.png new file mode 100644 index 0000000..cd4caf7 Binary files /dev/null and b/old/android/assets/1366x768/title.png differ diff --git a/old/android/assets/1366x768/tpSelector.png b/old/android/assets/1366x768/tpSelector.png new file mode 100644 index 0000000..d8eb20c Binary files /dev/null and b/old/android/assets/1366x768/tpSelector.png differ diff --git a/old/android/assets/1366x768/void_circle.png b/old/android/assets/1366x768/void_circle.png new file mode 100644 index 0000000..eafeb24 Binary files /dev/null and b/old/android/assets/1366x768/void_circle.png differ diff --git a/old/android/assets/1920x1080/Shooter1.png b/old/android/assets/1920x1080/Shooter1.png new file mode 100644 index 0000000..59254c1 Binary files /dev/null and b/old/android/assets/1920x1080/Shooter1.png differ diff --git a/old/android/assets/1920x1080/Tech-Circle1.png b/old/android/assets/1920x1080/Tech-Circle1.png new file mode 100644 index 0000000..73d6ecd Binary files /dev/null and b/old/android/assets/1920x1080/Tech-Circle1.png differ diff --git a/old/android/assets/1920x1080/backgrounds/mainBG.png b/old/android/assets/1920x1080/backgrounds/mainBG.png new file mode 100644 index 0000000..177ecec Binary files /dev/null and b/old/android/assets/1920x1080/backgrounds/mainBG.png differ diff --git a/old/android/assets/1920x1080/bar.png b/old/android/assets/1920x1080/bar.png new file mode 100644 index 0000000..d384455 Binary files /dev/null and b/old/android/assets/1920x1080/bar.png differ diff --git a/old/android/assets/1920x1080/cybercircle1.png b/old/android/assets/1920x1080/cybercircle1.png new file mode 100644 index 0000000..f3c7512 Binary files /dev/null and b/old/android/assets/1920x1080/cybercircle1.png differ diff --git a/old/android/assets/1920x1080/cybercircle3B.png b/old/android/assets/1920x1080/cybercircle3B.png new file mode 100644 index 0000000..13f13ef Binary files /dev/null and b/old/android/assets/1920x1080/cybercircle3B.png differ diff --git a/old/android/assets/1920x1080/flake.png b/old/android/assets/1920x1080/flake.png new file mode 100644 index 0000000..2da5d42 Binary files /dev/null and b/old/android/assets/1920x1080/flake.png differ diff --git a/old/android/assets/1920x1080/laser.png b/old/android/assets/1920x1080/laser.png new file mode 100644 index 0000000..c7e0405 Binary files /dev/null and b/old/android/assets/1920x1080/laser.png differ diff --git a/old/android/assets/1920x1080/magic1.png b/old/android/assets/1920x1080/magic1.png new file mode 100644 index 0000000..8d270ee Binary files /dev/null and b/old/android/assets/1920x1080/magic1.png differ diff --git a/old/android/assets/1920x1080/pellet.png b/old/android/assets/1920x1080/pellet.png new file mode 100644 index 0000000..e578a10 Binary files /dev/null and b/old/android/assets/1920x1080/pellet.png differ diff --git a/old/android/assets/1920x1080/polyjet-standard.png b/old/android/assets/1920x1080/polyjet-standard.png new file mode 100644 index 0000000..cfec492 Binary files /dev/null and b/old/android/assets/1920x1080/polyjet-standard.png differ diff --git a/old/android/assets/1920x1080/shard.png b/old/android/assets/1920x1080/shard.png new file mode 100644 index 0000000..154e2b2 Binary files /dev/null and b/old/android/assets/1920x1080/shard.png differ diff --git a/old/android/assets/1920x1080/square.png b/old/android/assets/1920x1080/square.png new file mode 100644 index 0000000..f351e99 Binary files /dev/null and b/old/android/assets/1920x1080/square.png differ diff --git a/old/android/assets/1920x1080/title.png b/old/android/assets/1920x1080/title.png new file mode 100644 index 0000000..7885f48 Binary files /dev/null and b/old/android/assets/1920x1080/title.png differ diff --git a/old/android/assets/1920x1080/tpSelector.png b/old/android/assets/1920x1080/tpSelector.png new file mode 100644 index 0000000..da02f1e Binary files /dev/null and b/old/android/assets/1920x1080/tpSelector.png differ diff --git a/old/android/assets/1920x1080/void_circle.png b/old/android/assets/1920x1080/void_circle.png new file mode 100644 index 0000000..9dad9e7 Binary files /dev/null and b/old/android/assets/1920x1080/void_circle.png differ diff --git a/old/android/assets/1920x1200/Shooter1.png b/old/android/assets/1920x1200/Shooter1.png new file mode 100644 index 0000000..9ccb7dc Binary files /dev/null and b/old/android/assets/1920x1200/Shooter1.png differ diff --git a/old/android/assets/1920x1200/Tech-Circle1.png b/old/android/assets/1920x1200/Tech-Circle1.png new file mode 100644 index 0000000..973956b Binary files /dev/null and b/old/android/assets/1920x1200/Tech-Circle1.png differ diff --git a/old/android/assets/1920x1200/backgrounds/mainBG.png b/old/android/assets/1920x1200/backgrounds/mainBG.png new file mode 100644 index 0000000..5bd56df Binary files /dev/null and b/old/android/assets/1920x1200/backgrounds/mainBG.png differ diff --git a/old/android/assets/1920x1200/bar.png b/old/android/assets/1920x1200/bar.png new file mode 100644 index 0000000..738b095 Binary files /dev/null and b/old/android/assets/1920x1200/bar.png differ diff --git a/old/android/assets/1920x1200/cybercircle1.png b/old/android/assets/1920x1200/cybercircle1.png new file mode 100644 index 0000000..6938404 Binary files /dev/null and b/old/android/assets/1920x1200/cybercircle1.png differ diff --git a/old/android/assets/1920x1200/cybercircle3B.png b/old/android/assets/1920x1200/cybercircle3B.png new file mode 100644 index 0000000..de638f3 Binary files /dev/null and b/old/android/assets/1920x1200/cybercircle3B.png differ diff --git a/old/android/assets/1920x1200/flake.png b/old/android/assets/1920x1200/flake.png new file mode 100644 index 0000000..858ac5c Binary files /dev/null and b/old/android/assets/1920x1200/flake.png differ diff --git a/old/android/assets/1920x1200/laser.png b/old/android/assets/1920x1200/laser.png new file mode 100644 index 0000000..1528938 Binary files /dev/null and b/old/android/assets/1920x1200/laser.png differ diff --git a/old/android/assets/1920x1200/magic1.png b/old/android/assets/1920x1200/magic1.png new file mode 100644 index 0000000..efcdacf Binary files /dev/null and b/old/android/assets/1920x1200/magic1.png differ diff --git a/old/android/assets/1920x1200/pellet.png b/old/android/assets/1920x1200/pellet.png new file mode 100644 index 0000000..b7ffce2 Binary files /dev/null and b/old/android/assets/1920x1200/pellet.png differ diff --git a/old/android/assets/1920x1200/polyjet-standard.png b/old/android/assets/1920x1200/polyjet-standard.png new file mode 100644 index 0000000..c374e1a Binary files /dev/null and b/old/android/assets/1920x1200/polyjet-standard.png differ diff --git a/old/android/assets/1920x1200/shard.png b/old/android/assets/1920x1200/shard.png new file mode 100644 index 0000000..f952746 Binary files /dev/null and b/old/android/assets/1920x1200/shard.png differ diff --git a/old/android/assets/1920x1200/square.png b/old/android/assets/1920x1200/square.png new file mode 100644 index 0000000..12edf25 Binary files /dev/null and b/old/android/assets/1920x1200/square.png differ diff --git a/old/android/assets/1920x1200/title.png b/old/android/assets/1920x1200/title.png new file mode 100644 index 0000000..1ada752 Binary files /dev/null and b/old/android/assets/1920x1200/title.png differ diff --git a/old/android/assets/1920x1200/tpSelector.png b/old/android/assets/1920x1200/tpSelector.png new file mode 100644 index 0000000..049d468 Binary files /dev/null and b/old/android/assets/1920x1200/tpSelector.png differ diff --git a/old/android/assets/1920x1200/void_circle.png b/old/android/assets/1920x1200/void_circle.png new file mode 100644 index 0000000..c4a71c2 Binary files /dev/null and b/old/android/assets/1920x1200/void_circle.png differ diff --git a/old/android/assets/2560x1440/Shooter1.png b/old/android/assets/2560x1440/Shooter1.png new file mode 100644 index 0000000..5c89fe0 Binary files /dev/null and b/old/android/assets/2560x1440/Shooter1.png differ diff --git a/old/android/assets/2560x1440/Tech-Circle1.png b/old/android/assets/2560x1440/Tech-Circle1.png new file mode 100644 index 0000000..076a8ca Binary files /dev/null and b/old/android/assets/2560x1440/Tech-Circle1.png differ diff --git a/old/android/assets/2560x1440/backgrounds/mainBG.png b/old/android/assets/2560x1440/backgrounds/mainBG.png new file mode 100644 index 0000000..e155bc5 Binary files /dev/null and b/old/android/assets/2560x1440/backgrounds/mainBG.png differ diff --git a/old/android/assets/2560x1440/bar.png b/old/android/assets/2560x1440/bar.png new file mode 100644 index 0000000..c5b6b3a Binary files /dev/null and b/old/android/assets/2560x1440/bar.png differ diff --git a/old/android/assets/2560x1440/cybercircle1.png b/old/android/assets/2560x1440/cybercircle1.png new file mode 100644 index 0000000..2771c97 Binary files /dev/null and b/old/android/assets/2560x1440/cybercircle1.png differ diff --git a/old/android/assets/2560x1440/cybercircle3B.png b/old/android/assets/2560x1440/cybercircle3B.png new file mode 100644 index 0000000..f66907f Binary files /dev/null and b/old/android/assets/2560x1440/cybercircle3B.png differ diff --git a/old/android/assets/2560x1440/flake.png b/old/android/assets/2560x1440/flake.png new file mode 100644 index 0000000..6e50620 Binary files /dev/null and b/old/android/assets/2560x1440/flake.png differ diff --git a/old/android/assets/2560x1440/laser.png b/old/android/assets/2560x1440/laser.png new file mode 100644 index 0000000..6ea99f4 Binary files /dev/null and b/old/android/assets/2560x1440/laser.png differ diff --git a/old/android/assets/2560x1440/magic1.png b/old/android/assets/2560x1440/magic1.png new file mode 100644 index 0000000..5ac0cb7 Binary files /dev/null and b/old/android/assets/2560x1440/magic1.png differ diff --git a/old/android/assets/2560x1440/pellet.png b/old/android/assets/2560x1440/pellet.png new file mode 100644 index 0000000..cffc1ae Binary files /dev/null and b/old/android/assets/2560x1440/pellet.png differ diff --git a/old/android/assets/2560x1440/polyjet-standard.png b/old/android/assets/2560x1440/polyjet-standard.png new file mode 100644 index 0000000..c2b6f32 Binary files /dev/null and b/old/android/assets/2560x1440/polyjet-standard.png differ diff --git a/old/android/assets/2560x1440/shard.png b/old/android/assets/2560x1440/shard.png new file mode 100644 index 0000000..10a036f Binary files /dev/null and b/old/android/assets/2560x1440/shard.png differ diff --git a/old/android/assets/2560x1440/splashlogo.png b/old/android/assets/2560x1440/splashlogo.png new file mode 100644 index 0000000..f2fab6d Binary files /dev/null and b/old/android/assets/2560x1440/splashlogo.png differ diff --git a/old/android/assets/2560x1440/square.png b/old/android/assets/2560x1440/square.png new file mode 100644 index 0000000..70fcf91 Binary files /dev/null and b/old/android/assets/2560x1440/square.png differ diff --git a/old/android/assets/2560x1440/title.png b/old/android/assets/2560x1440/title.png new file mode 100644 index 0000000..dc1274a Binary files /dev/null and b/old/android/assets/2560x1440/title.png differ diff --git a/old/android/assets/2560x1440/tpSelector.png b/old/android/assets/2560x1440/tpSelector.png new file mode 100644 index 0000000..de16a8d Binary files /dev/null and b/old/android/assets/2560x1440/tpSelector.png differ diff --git a/old/android/assets/2560x1440/void_circle.png b/old/android/assets/2560x1440/void_circle.png new file mode 100644 index 0000000..b8ad109 Binary files /dev/null and b/old/android/assets/2560x1440/void_circle.png differ diff --git a/old/android/assets/3840x2160/Shooter1.png b/old/android/assets/3840x2160/Shooter1.png new file mode 100644 index 0000000..fc4adc1 Binary files /dev/null and b/old/android/assets/3840x2160/Shooter1.png differ diff --git a/old/android/assets/3840x2160/Tech-Circle1.png b/old/android/assets/3840x2160/Tech-Circle1.png new file mode 100644 index 0000000..efad7f1 Binary files /dev/null and b/old/android/assets/3840x2160/Tech-Circle1.png differ diff --git a/old/android/assets/3840x2160/backgrounds/mainBG.png b/old/android/assets/3840x2160/backgrounds/mainBG.png new file mode 100644 index 0000000..2c83916 Binary files /dev/null and b/old/android/assets/3840x2160/backgrounds/mainBG.png differ diff --git a/old/android/assets/3840x2160/bar.png b/old/android/assets/3840x2160/bar.png new file mode 100644 index 0000000..aaf5f9c Binary files /dev/null and b/old/android/assets/3840x2160/bar.png differ diff --git a/old/android/assets/3840x2160/cybercircle1.png b/old/android/assets/3840x2160/cybercircle1.png new file mode 100644 index 0000000..e63d232 Binary files /dev/null and b/old/android/assets/3840x2160/cybercircle1.png differ diff --git a/old/android/assets/3840x2160/cybercircle3B.png b/old/android/assets/3840x2160/cybercircle3B.png new file mode 100644 index 0000000..4129106 Binary files /dev/null and b/old/android/assets/3840x2160/cybercircle3B.png differ diff --git a/old/android/assets/3840x2160/flake.png b/old/android/assets/3840x2160/flake.png new file mode 100644 index 0000000..a0cb521 Binary files /dev/null and b/old/android/assets/3840x2160/flake.png differ diff --git a/old/android/assets/3840x2160/laser.png b/old/android/assets/3840x2160/laser.png new file mode 100644 index 0000000..f5d289f Binary files /dev/null and b/old/android/assets/3840x2160/laser.png differ diff --git a/old/android/assets/3840x2160/magic1.png b/old/android/assets/3840x2160/magic1.png new file mode 100644 index 0000000..6229753 Binary files /dev/null and b/old/android/assets/3840x2160/magic1.png differ diff --git a/old/android/assets/3840x2160/pellet.png b/old/android/assets/3840x2160/pellet.png new file mode 100644 index 0000000..576da50 Binary files /dev/null and b/old/android/assets/3840x2160/pellet.png differ diff --git a/old/android/assets/3840x2160/polyjet-standard.png b/old/android/assets/3840x2160/polyjet-standard.png new file mode 100644 index 0000000..893c4fb Binary files /dev/null and b/old/android/assets/3840x2160/polyjet-standard.png differ diff --git a/old/android/assets/3840x2160/shard.png b/old/android/assets/3840x2160/shard.png new file mode 100644 index 0000000..637a04d Binary files /dev/null and b/old/android/assets/3840x2160/shard.png differ diff --git a/old/android/assets/3840x2160/square.png b/old/android/assets/3840x2160/square.png new file mode 100644 index 0000000..2868dca Binary files /dev/null and b/old/android/assets/3840x2160/square.png differ diff --git a/old/android/assets/3840x2160/title.png b/old/android/assets/3840x2160/title.png new file mode 100644 index 0000000..998f2d9 Binary files /dev/null and b/old/android/assets/3840x2160/title.png differ diff --git a/old/android/assets/3840x2160/tpSelector.png b/old/android/assets/3840x2160/tpSelector.png new file mode 100644 index 0000000..465ef5d Binary files /dev/null and b/old/android/assets/3840x2160/tpSelector.png differ diff --git a/old/android/assets/3840x2160/void_circle.png b/old/android/assets/3840x2160/void_circle.png new file mode 100644 index 0000000..396d5f1 Binary files /dev/null and b/old/android/assets/3840x2160/void_circle.png differ diff --git a/old/android/assets/badlogic.jpg b/old/android/assets/badlogic.jpg new file mode 100644 index 0000000..4390da6 Binary files /dev/null and b/old/android/assets/badlogic.jpg differ diff --git a/old/android/assets/defaultCover.png b/old/android/assets/defaultCover.png new file mode 100644 index 0000000..f6cc866 Binary files /dev/null and b/old/android/assets/defaultCover.png differ diff --git a/old/android/assets/fonts/Gasalt-Regular.ttf b/old/android/assets/fonts/Gasalt-Regular.ttf new file mode 100644 index 0000000..79ff0fa Binary files /dev/null and b/old/android/assets/fonts/Gasalt-Regular.ttf differ diff --git a/old/android/assets/fonts/darktech_ldr.ttf b/old/android/assets/fonts/darktech_ldr.ttf new file mode 100644 index 0000000..273716f Binary files /dev/null and b/old/android/assets/fonts/darktech_ldr.ttf differ diff --git a/old/android/assets/fonts/maiden.TTF b/old/android/assets/fonts/maiden.TTF new file mode 100644 index 0000000..cb4b9d9 Binary files /dev/null and b/old/android/assets/fonts/maiden.TTF differ diff --git a/old/android/assets/keyboard.atlas b/old/android/assets/keyboard.atlas new file mode 100644 index 0000000..f0df62f --- /dev/null +++ b/old/android/assets/keyboard.atlas @@ -0,0 +1,650 @@ + +keyboard.png +size: 1024,1024 +format: RGBA8888 +filter: Nearest,Nearest +repeat: none +Keyboard_Black_0 + rotate: false + xy: 2, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_1 + rotate: false + xy: 2, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_2 + rotate: false + xy: 104, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_3 + rotate: false + xy: 2, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_4 + rotate: false + xy: 104, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_5 + rotate: false + xy: 206, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_6 + rotate: false + xy: 2, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_7 + rotate: false + xy: 104, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_8 + rotate: false + xy: 206, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_9 + rotate: false + xy: 308, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F10 + rotate: false + xy: 2, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F11 + rotate: false + xy: 104, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F12 + rotate: false + xy: 206, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_A + rotate: false + xy: 308, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Alt + rotate: false + xy: 410, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Down + rotate: false + xy: 2, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Left + rotate: false + xy: 104, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Right + rotate: false + xy: 206, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Up + rotate: false + xy: 308, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Asterisk + rotate: false + xy: 410, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_B + rotate: false + xy: 512, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Backspace + rotate: false + xy: 2, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Backspace_Alt + rotate: false + xy: 104, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Bracket_Left + rotate: false + xy: 206, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Bracket_Right + rotate: false + xy: 308, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_C + rotate: false + xy: 410, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Caps_Lock + rotate: false + xy: 512, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Command + rotate: false + xy: 614, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Ctrl + rotate: false + xy: 2, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_D + rotate: false + xy: 104, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Del + rotate: false + xy: 206, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_E + rotate: false + xy: 308, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_End + rotate: false + xy: 410, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Enter + rotate: false + xy: 512, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Enter_Alt + rotate: false + xy: 614, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Enter_Tall + rotate: false + xy: 716, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Escape + rotate: false + xy: 2, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F + rotate: false + xy: 104, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F1 + rotate: false + xy: 206, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F2 + rotate: false + xy: 308, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F3 + rotate: false + xy: 410, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F4 + rotate: false + xy: 512, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F5 + rotate: false + xy: 614, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F6 + rotate: false + xy: 716, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F7 + rotate: false + xy: 818, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F8 + rotate: false + xy: 2, 2 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_F9 + rotate: false + xy: 104, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_G + rotate: false + xy: 206, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_H + rotate: false + xy: 308, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Home + rotate: false + xy: 410, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_I + rotate: false + xy: 512, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Insert + rotate: false + xy: 614, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_J + rotate: false + xy: 716, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_K + rotate: false + xy: 818, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_L + rotate: false + xy: 920, 920 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_M + rotate: false + xy: 104, 2 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Mark_Left + rotate: false + xy: 206, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Mark_Right + rotate: false + xy: 308, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Minus + rotate: false + xy: 410, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Mouse_Left + rotate: false + xy: 512, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Mouse_Middle + rotate: false + xy: 614, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Mouse_Right + rotate: false + xy: 716, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Mouse_Simple + rotate: false + xy: 818, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_N + rotate: false + xy: 920, 818 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Num_Lock + rotate: false + xy: 206, 2 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_O + rotate: false + xy: 308, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_P + rotate: false + xy: 410, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Page_Down + rotate: false + xy: 512, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Page_Up + rotate: false + xy: 614, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Plus + rotate: false + xy: 716, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Plus_Tall + rotate: false + xy: 818, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Print_Screen + rotate: false + xy: 920, 716 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Q + rotate: false + xy: 308, 2 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Question + rotate: false + xy: 410, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Quote + rotate: false + xy: 512, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_R + rotate: false + xy: 614, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_S + rotate: false + xy: 716, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Semicolon + rotate: false + xy: 818, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Shift + rotate: false + xy: 920, 614 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Shift_Alt + rotate: false + xy: 410, 2 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Slash + rotate: false + xy: 512, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Space + rotate: false + xy: 614, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_T + rotate: false + xy: 716, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Tab + rotate: false + xy: 818, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Tilda + rotate: false + xy: 920, 512 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_U + rotate: false + xy: 512, 2 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_V + rotate: false + xy: 614, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_W + rotate: false + xy: 716, 206 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Win + rotate: false + xy: 818, 308 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_X + rotate: false + xy: 920, 410 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Y + rotate: false + xy: 614, 2 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +Keyboard_Black_Z + rotate: false + xy: 716, 104 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 diff --git a/old/android/assets/keyboard.png b/old/android/assets/keyboard.png new file mode 100644 index 0000000..6dff14f Binary files /dev/null and b/old/android/assets/keyboard.png differ diff --git a/old/android/assets/music/Alan Walker - Spectre.mp3 b/old/android/assets/music/Alan Walker - Spectre.mp3 new file mode 100644 index 0000000..53f14af Binary files /dev/null and b/old/android/assets/music/Alan Walker - Spectre.mp3 differ diff --git a/old/android/assets/music/Beat_8.mp3 b/old/android/assets/music/Beat_8.mp3 new file mode 100644 index 0000000..83d0158 Binary files /dev/null and b/old/android/assets/music/Beat_8.mp3 differ diff --git a/old/android/assets/particles/3pStar.png b/old/android/assets/particles/3pStar.png new file mode 100644 index 0000000..fce6a34 Binary files /dev/null and b/old/android/assets/particles/3pStar.png differ diff --git a/old/android/assets/particles/4PStar.png b/old/android/assets/particles/4PStar.png new file mode 100644 index 0000000..1de8613 Binary files /dev/null and b/old/android/assets/particles/4PStar.png differ diff --git a/old/android/assets/particles/beateffect.p b/old/android/assets/particles/beateffect.p new file mode 100644 index 0000000..fcb5367 --- /dev/null +++ b/old/android/assets/particles/beateffect.p @@ -0,0 +1,149 @@ +main +- Delay - +active: false +- Duration - +lowMin: 150.0 +lowMax: 150.0 +- Count - +min: 0 +max: 20 +- Emission - +lowMin: 0.0 +lowMax: 0.0 +highMin: 100.0 +highMax: 150.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Life - +lowMin: 0.0 +lowMax: 0.0 +highMin: 2500.0 +highMax: 3000.0 +relative: false +scalingCount: 2 +scaling0: 1.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Life Offset - +active: false +- X Offset - +active: false +- Y Offset - +active: false +- Spawn Shape - +shape: line +- Spawn Width - +lowMin: 0.0 +lowMax: 0.0 +highMin: 3840.0 +highMax: 3840.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Spawn Height - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Scale - +lowMin: 0.0 +lowMax: 0.0 +highMin: 45.0 +highMax: 135.0 +relative: false +scalingCount: 3 +scaling0: 1.0 +scaling1: 1.0 +scaling2: 0.25490198 +timelineCount: 3 +timeline0: 0.0 +timeline1: 0.7876712 +timeline2: 1.0 +- Velocity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 540.0 +highMax: 1080.0 +relative: false +scalingCount: 3 +scaling0: 1.0 +scaling1: 1.0 +scaling2: 0.6666667 +timelineCount: 3 +timeline0: 0.0 +timeline1: 0.69863015 +timeline2: 0.9931507 +- Angle - +active: true +lowMin: 90.0 +lowMax: 90.0 +highMin: 45.0 +highMax: 135.0 +relative: false +scalingCount: 3 +scaling0: 1.0 +scaling1: 0.43137255 +scaling2: 0.13725491 +timelineCount: 3 +timeline0: 0.0 +timeline1: 0.5684931 +timeline2: 0.8630137 +- Rotation - +active: false +- Wind - +active: false +- Gravity - +active: false +- Tint - +colorsCount: 6 +colors0: 0.043137256 +colors1: 0.6392157 +colors2: 0.85490197 +colors3: 0.02745098 +colors4: 0.41960785 +colors5: 0.56078434 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Transparency - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 6 +scaling0: 0.0 +scaling1: 0.19298245 +scaling2: 0.7719298 +scaling3: 1.0 +scaling4: 0.21052632 +scaling5: 0.0 +timelineCount: 6 +timeline0: 0.0 +timeline1: 0.23972602 +timeline2: 0.39726028 +timeline3: 0.60958904 +timeline4: 0.79452056 +timeline5: 1.0 +- Options - +attached: false +continuous: false +aligned: false +additive: true +behind: false +premultipliedAlpha: false +- Image Path - +glow-circle.png diff --git a/old/android/assets/particles/explosion-s.p b/old/android/assets/particles/explosion-s.p new file mode 100644 index 0000000..7f2ff3e --- /dev/null +++ b/old/android/assets/particles/explosion-s.p @@ -0,0 +1,148 @@ +point1 +- Delay - +active: false +- Duration - +lowMin: 50.0 +lowMax: 50.0 +- Count - +min: 0 +max: 30 +- Emission - +lowMin: 0.0 +lowMax: 0.0 +highMin: 500.0 +highMax: 500.0 +relative: false +scalingCount: 2 +scaling0: 1.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Life - +lowMin: 0.0 +lowMax: 0.0 +highMin: 250.0 +highMax: 500.0 +relative: false +scalingCount: 3 +scaling0: 1.0 +scaling1: 1.0 +scaling2: 0.3 +timelineCount: 3 +timeline0: 0.0 +timeline1: 0.66 +timeline2: 1.0 +- Life Offset - +active: false +- X Offset - +active: false +- Y Offset - +active: false +- Spawn Shape - +shape: point +- Spawn Width - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Spawn Height - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Scale - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.5 +highMax: 2.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Velocity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 2.0 +highMax: 8.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Angle - +active: true +lowMin: 90.0 +lowMax: 90.0 +highMin: 0.0 +highMax: 360.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Rotation - +active: true +lowMin: 1.0 +lowMax: 360.0 +highMin: 180.0 +highMax: 180.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Wind - +active: false +- Gravity - +active: false +- Tint - +colorsCount: 6 +colors0: 1.0 +colors1: 0.047058824 +colors2: 0.047058824 +colors3: 1.0 +colors4: 0.92156863 +colors5: 0.047058824 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Transparency - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 4 +scaling0: 0.0 +scaling1: 1.0 +scaling2: 0.31578946 +scaling3: 0.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.2 +timeline2: 0.74657536 +timeline3: 1.0 +- Options - +attached: false +continuous: false +aligned: false +additive: true +behind: false +premultipliedAlpha: false +- Image Path - +4PStar.png diff --git a/old/android/assets/particles/firework-exp-s.p b/old/android/assets/particles/firework-exp-s.p new file mode 100644 index 0000000..eeb443b --- /dev/null +++ b/old/android/assets/particles/firework-exp-s.p @@ -0,0 +1,188 @@ +firework2 +- Delay - +active: false +- Duration - +lowMin: 300.0 +lowMax: 300.0 +- Count - +min: 20 +max: 150 +- Emission - +lowMin: 0.0 +lowMax: 0.0 +highMin: 500.0 +highMax: 500.0 +relative: false +scalingCount: 4 +scaling0: 0.0 +scaling1: 0.0 +scaling2: 1.0 +scaling3: 1.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.5 +timeline2: 0.84246576 +timeline3: 1.0 +- Life - +lowMin: 0.0 +lowMax: 0.0 +highMin: 750.0 +highMax: 1200.0 +relative: false +scalingCount: 2 +scaling0: 1.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Life Offset - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- X Offset - +active: false +- Y Offset - +active: false +- Spawn Shape - +shape: point +- Spawn Width - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Spawn Height - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Scale - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.5 +highMax: 1.5 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Velocity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 8.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 0.10273973 +- Angle - +active: true +lowMin: 0.0 +lowMax: 360.0 +highMin: 0.0 +highMax: 360.0 +relative: false +scalingCount: 1 +scaling0: 0.0 +timelineCount: 1 +timeline0: 0.0 +- Rotation - +active: true +lowMin: 1.0 +lowMax: 360.0 +highMin: 180.0 +highMax: 180.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Wind - +active: false +- Gravity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: -7.5 +highMax: -9.5 +relative: false +scalingCount: 4 +scaling0: 0.0 +scaling1: 0.50980395 +scaling2: 0.78431374 +scaling3: 1.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.10958904 +timeline2: 0.25342464 +timeline3: 0.48630136 +- Tint - +colorsCount: 15 +colors0: 1.0 +colors1: 0.047058824 +colors2: 0.047058824 +colors3: 0.047058824 +colors4: 0.047058824 +colors5: 1.0 +colors6: 0.047058824 +colors7: 1.0 +colors8: 0.2 +colors9: 1.0 +colors10: 0.972549 +colors11: 0.047058824 +colors12: 1.0 +colors13: 0.047058824 +colors14: 0.047058824 +timelineCount: 5 +timeline0: 0.0 +timeline1: 0.2897402 +timeline2: 0.5006605 +timeline3: 0.74372524 +timeline4: 1.0 +- Transparency - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 4 +scaling0: 0.64912283 +scaling1: 1.0 +scaling2: 0.75 +scaling3: 0.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.43150684 +timeline2: 0.8 +timeline3: 1.0 +- Options - +attached: false +continuous: false +aligned: false +additive: true +behind: false +premultipliedAlpha: false +- Image Path - +4PStar.png diff --git a/old/android/assets/particles/firework-exp.p b/old/android/assets/particles/firework-exp.p new file mode 100644 index 0000000..4efd16e --- /dev/null +++ b/old/android/assets/particles/firework-exp.p @@ -0,0 +1,367 @@ +firework1 +- Delay - +active: false +- Duration - +lowMin: 250.0 +lowMax: 250.0 +- Count - +min: 20 +max: 150 +- Emission - +lowMin: 0.0 +lowMax: 0.0 +highMin: 600.0 +highMax: 600.0 +relative: false +scalingCount: 3 +scaling0: 1.0 +scaling1: 1.0 +scaling2: 0.0 +timelineCount: 3 +timeline0: 0.0 +timeline1: 0.50022554 +timeline2: 1.0 +- Life - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1000.0 +highMax: 1500.0 +relative: false +scalingCount: 2 +scaling0: 1.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Life Offset - +active: false +- X Offset - +active: false +- Y Offset - +active: false +- Spawn Shape - +shape: point +- Spawn Width - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Spawn Height - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Scale - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.5 +highMax: 1.5 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Velocity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 6.0 +highMax: 14.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 0.10273973 +- Angle - +active: true +lowMin: 0.0 +lowMax: 360.0 +highMin: 0.0 +highMax: 360.0 +relative: false +scalingCount: 1 +scaling0: 0.0 +timelineCount: 1 +timeline0: 0.0 +- Rotation - +active: true +lowMin: 1.0 +lowMax: 360.0 +highMin: 180.0 +highMax: 180.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Wind - +active: false +- Gravity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: -7.5 +highMax: -9.5 +relative: false +scalingCount: 4 +scaling0: 0.0 +scaling1: 0.50980395 +scaling2: 0.78431374 +scaling3: 1.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.10958904 +timeline2: 0.25342464 +timeline3: 0.48630136 +- Tint - +colorsCount: 15 +colors0: 1.0 +colors1: 0.047058824 +colors2: 0.047058824 +colors3: 1.0 +colors4: 0.99607843 +colors5: 0.047058824 +colors6: 0.047058824 +colors7: 1.0 +colors8: 0.2 +colors9: 0.047058824 +colors10: 0.05490196 +colors11: 1.0 +colors12: 1.0 +colors13: 0.047058824 +colors14: 0.9843137 +timelineCount: 5 +timeline0: 0.0 +timeline1: 0.2897402 +timeline2: 0.5006605 +timeline3: 0.74372524 +timeline4: 1.0 +- Transparency - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 4 +scaling0: 0.64912283 +scaling1: 1.0 +scaling2: 0.75 +scaling3: 0.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.43150684 +timeline2: 0.8 +timeline3: 1.0 +- Options - +attached: false +continuous: false +aligned: false +additive: true +behind: false +premultipliedAlpha: false +- Image Path - +4PStar.png + + +firework2 +- Delay - +active: false +- Duration - +lowMin: 300.0 +lowMax: 300.0 +- Count - +min: 20 +max: 150 +- Emission - +lowMin: 0.0 +lowMax: 0.0 +highMin: 500.0 +highMax: 500.0 +relative: false +scalingCount: 4 +scaling0: 0.0 +scaling1: 0.0 +scaling2: 1.0 +scaling3: 1.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.5 +timeline2: 0.84246576 +timeline3: 1.0 +- Life - +lowMin: 0.0 +lowMax: 0.0 +highMin: 750.0 +highMax: 1200.0 +relative: false +scalingCount: 2 +scaling0: 1.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Life Offset - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- X Offset - +active: false +- Y Offset - +active: false +- Spawn Shape - +shape: point +- Spawn Width - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Spawn Height - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Scale - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.5 +highMax: 1.5 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Velocity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 8.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 0.10273973 +- Angle - +active: true +lowMin: 0.0 +lowMax: 360.0 +highMin: 0.0 +highMax: 360.0 +relative: false +scalingCount: 1 +scaling0: 0.0 +timelineCount: 1 +timeline0: 0.0 +- Rotation - +active: true +lowMin: 1.0 +lowMax: 360.0 +highMin: 180.0 +highMax: 180.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Wind - +active: false +- Gravity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: -7.5 +highMax: -9.5 +relative: false +scalingCount: 4 +scaling0: 0.0 +scaling1: 0.50980395 +scaling2: 0.78431374 +scaling3: 1.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.10958904 +timeline2: 0.25342464 +timeline3: 0.48630136 +- Tint - +colorsCount: 15 +colors0: 1.0 +colors1: 0.047058824 +colors2: 0.047058824 +colors3: 0.047058824 +colors4: 0.047058824 +colors5: 1.0 +colors6: 0.047058824 +colors7: 1.0 +colors8: 0.2 +colors9: 1.0 +colors10: 0.972549 +colors11: 0.047058824 +colors12: 1.0 +colors13: 0.047058824 +colors14: 0.047058824 +timelineCount: 5 +timeline0: 0.0 +timeline1: 0.2897402 +timeline2: 0.5006605 +timeline3: 0.74372524 +timeline4: 1.0 +- Transparency - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 4 +scaling0: 0.64912283 +scaling1: 1.0 +scaling2: 0.75 +scaling3: 0.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.43150684 +timeline2: 0.8 +timeline3: 1.0 +- Options - +attached: false +continuous: false +aligned: false +additive: true +behind: false +premultipliedAlpha: false +- Image Path - +4PStar.png diff --git a/old/android/assets/particles/glow-circle.png b/old/android/assets/particles/glow-circle.png new file mode 100644 index 0000000..96f69a0 Binary files /dev/null and b/old/android/assets/particles/glow-circle.png differ diff --git a/old/android/assets/particles/magic-tech.png b/old/android/assets/particles/magic-tech.png new file mode 100644 index 0000000..ac4a4e1 Binary files /dev/null and b/old/android/assets/particles/magic-tech.png differ diff --git a/old/android/assets/particles/square.png b/old/android/assets/particles/square.png new file mode 100644 index 0000000..fc4c5ca Binary files /dev/null and b/old/android/assets/particles/square.png differ diff --git a/old/android/assets/particles/standard_thrust.p b/old/android/assets/particles/standard_thrust.p new file mode 100644 index 0000000..fcfdb57 --- /dev/null +++ b/old/android/assets/particles/standard_thrust.p @@ -0,0 +1,154 @@ +thrust +- Delay - +active: false +- Duration - +lowMin: 0.0 +lowMax: 0.0 +- Count - +min: 0 +max: 40 +- Emission - +lowMin: 0.0 +lowMax: 0.0 +highMin: 70.0 +highMax: 70.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Life - +lowMin: 0.0 +lowMax: 0.0 +highMin: 400.0 +highMax: 300.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Life Offset - +active: false +- X Offset - +active: false +- Y Offset - +active: false +- Spawn Shape - +shape: point +- Spawn Width - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Spawn Height - +lowMin: 0.0 +lowMax: 0.0 +highMin: 0.0 +highMax: 0.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Scale - +lowMin: 0.0 +lowMax: 1.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 4 +scaling0: 1.0 +scaling1: 0.92156863 +scaling2: 0.627451 +scaling3: 0.0 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.5273973 +timeline2: 0.8082192 +timeline3: 1.0 +- Velocity - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 7.0 +highMax: 7.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Angle - +active: true +lowMin: 60.0 +lowMax: 120.0 +highMin: 90.0 +highMax: 90.0 +relative: false +scalingCount: 5 +scaling0: 0.0 +scaling1: 0.0 +scaling2: 0.23529412 +scaling3: 0.8235294 +scaling4: 1.0 +timelineCount: 5 +timeline0: 0.0 +timeline1: 0.2260274 +timeline2: 0.43835616 +timeline3: 0.82191783 +timeline4: 1.0 +- Rotation - +active: true +lowMin: 0.0 +lowMax: 0.0 +highMin: 4.0 +highMax: 120.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Wind - +active: false +- Gravity - +active: false +- Tint - +colorsCount: 3 +colors0: 0.15294118 +colors1: 0.8627451 +colors2: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Transparency - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 6 +scaling0: 0.0 +scaling1: 0.3508772 +scaling2: 1.0 +scaling3: 0.84210527 +scaling4: 0.64912283 +scaling5: 0.40350878 +timelineCount: 6 +timeline0: 0.0 +timeline1: 0.12328767 +timeline2: 0.26027396 +timeline3: 0.63013697 +timeline4: 0.9246575 +timeline5: 1.0 +- Options - +attached: false +continuous: true +aligned: false +additive: true +behind: false +premultipliedAlpha: false +- Image Path - +square.png diff --git a/old/android/assets/particles/teleport-cloak.p b/old/android/assets/particles/teleport-cloak.p new file mode 100644 index 0000000..4b35fe9 --- /dev/null +++ b/old/android/assets/particles/teleport-cloak.p @@ -0,0 +1,138 @@ +hexagon +- Delay - +active: false +- Duration - +lowMin: 400.0 +lowMax: 400.0 +- Count - +min: 0 +max: 25 +- Emission - +lowMin: 0.0 +lowMax: 0.0 +highMin: 45.0 +highMax: 45.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Life - +lowMin: 0.0 +lowMax: 0.0 +highMin: 400.0 +highMax: 655.0 +relative: false +scalingCount: 4 +scaling0: 0.8235294 +scaling1: 0.47058824 +scaling2: 0.50980395 +scaling3: 0.7254902 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.39726028 +timeline2: 0.5684931 +timeline3: 1.0 +- Life Offset - +active: false +- X Offset - +active: false +- Y Offset - +active: false +- Spawn Shape - +shape: square +- Spawn Width - +lowMin: 0.0 +lowMax: 0.0 +highMin: 3.0 +highMax: 3.0 +relative: false +scalingCount: 3 +scaling0: 1.0 +scaling1: 1.0 +scaling2: 0.0 +timelineCount: 3 +timeline0: 0.0 +timeline1: 0.39923224 +timeline2: 0.59884834 +- Spawn Height - +lowMin: 0.0 +lowMax: 0.0 +highMin: 3.0 +highMax: 3.0 +relative: false +scalingCount: 3 +scaling0: 1.0 +scaling1: 1.0 +scaling2: 0.0 +timelineCount: 3 +timeline0: 0.0 +timeline1: 0.40115163 +timeline2: 0.59692895 +- Scale - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 1 +scaling0: 1.0 +timelineCount: 1 +timeline0: 0.0 +- Velocity - +active: false +- Angle - +active: true +lowMin: 90.0 +lowMax: 90.0 +highMin: 45.0 +highMax: 135.0 +relative: false +scalingCount: 2 +scaling0: 0.0 +scaling1: 0.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Rotation - +active: false +- Wind - +active: false +- Gravity - +active: false +- Tint - +colorsCount: 6 +colors0: 0.047058824 +colors1: 0.627451 +colors2: 1.0 +colors3: 0.078431375 +colors4: 0.047058824 +colors5: 1.0 +timelineCount: 2 +timeline0: 0.0 +timeline1: 1.0 +- Transparency - +lowMin: 0.0 +lowMax: 0.0 +highMin: 1.0 +highMax: 1.0 +relative: false +scalingCount: 4 +scaling0: 0.1754386 +scaling1: 0.7719298 +scaling2: 0.4385965 +scaling3: 0.21052632 +timelineCount: 4 +timeline0: 0.0 +timeline1: 0.25342464 +timeline2: 0.82191783 +timeline3: 1.0 +- Options - +attached: true +continuous: false +aligned: false +additive: true +behind: false +premultipliedAlpha: false +- Image Path - +magic-tech.png diff --git a/old/android/assets/particles/triangle.png b/old/android/assets/particles/triangle.png new file mode 100644 index 0000000..ab997c0 Binary files /dev/null and b/old/android/assets/particles/triangle.png differ diff --git a/old/android/assets/shaders/basic.vsh b/old/android/assets/shaders/basic.vsh new file mode 100644 index 0000000..639bc50 --- /dev/null +++ b/old/android/assets/shaders/basic.vsh @@ -0,0 +1,14 @@ +attribute vec4 a_position; +attribute vec4 a_color; +attribute vec2 a_texCoord0; + +uniform mat4 u_projTrans; + +varying vec4 vColor; +varying vec2 vTexCoord; + +void main() { + vColor = a_color; + vTexCoord = a_texCoord0; + gl_Position = u_projTrans * a_position; +} diff --git a/old/android/assets/shaders/bright_filter.fsh b/old/android/assets/shaders/bright_filter.fsh new file mode 100644 index 0000000..9129746 --- /dev/null +++ b/old/android/assets/shaders/bright_filter.fsh @@ -0,0 +1,22 @@ +#ifdef GL_ES +#define LOWP lowp +precision mediump float; +#else +#define LOWP +#endif + +varying LOWP vec4 vColor; +varying vec2 vTexCoord; + +uniform sampler2D u_texture; + +void main() { + vec4 color = texture(u_texture, vTexCoord); + float brightness = (color.r*0.2126) + (color.g*0.7152) + (color.b * 0.0722); + + if (brightness > 0.6) { + gl_FragColor = color *0.75; + } else { + gl_FragColor = vec4(0.0); + } +} diff --git a/old/android/assets/shaders/chrome_abb.fsh b/old/android/assets/shaders/chrome_abb.fsh new file mode 100644 index 0000000..e69de29 diff --git a/old/android/assets/shaders/combine.fsh b/old/android/assets/shaders/combine.fsh new file mode 100644 index 0000000..11b8b7c --- /dev/null +++ b/old/android/assets/shaders/combine.fsh @@ -0,0 +1,27 @@ +#ifdef GL_ES +#define LOWP lowp +precision mediump float; +#else +#define LOWP +#endif + +varying LOWP vec4 vColor; +varying vec2 vTexCoord; + + +uniform sampler2D u_texture; +uniform sampler2D u_texture1; + +void main() { + vec4 origColor = texture2D(u_texture, vTexCoord); + vec4 blurredColor = texture2D(u_texture1, vTexCoord); + + vec4 result; + result = origColor + blurredColor; + result.a = vColor.a; + result.rgb *= vColor.rgb; + gl_FragColor = result; + + +} + diff --git a/old/android/assets/shaders/gaussian_blur.fsh b/old/android/assets/shaders/gaussian_blur.fsh new file mode 100644 index 0000000..e7145e5 --- /dev/null +++ b/old/android/assets/shaders/gaussian_blur.fsh @@ -0,0 +1,45 @@ +varying vec4 vColor; +varying vec2 vTexCoord; + +uniform sampler2D u_texture; +uniform vec2 resolution; +uniform float radius; +uniform int pass; + +void main() { + //this will be our RGBA sum + vec4 sum = vec4(0.0); + + //our original texcoord for this fragment + vec2 tc = vTexCoord; + + //the amount to blur, i.e. how far off center to sample from + //1.0 -> blur by one pixel + //2.0 -> blur by two pixels, etc. + float blur = radius/resolution.y; + + //the direction of our blur + //(1.0, 0.0) -> x-axis blur + //(0.0, 1.0) -> y-axis blur + float hstep = 1.0; + float vstep = 0.0; + + if (pass == 1) { + hstep = 0.0; + vstep = 1.0; + } + + sum += texture2D(u_texture, vec2(tc.x - 5.0*blur*hstep, tc.y - 5.0*blur*vstep)) * 0.014374; + sum += texture2D(u_texture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.035855; + sum += texture2D(u_texture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.072994; + sum += texture2D(u_texture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.121281; + sum += texture2D(u_texture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.164472; + + sum += texture2D(u_texture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.164472; + sum += texture2D(u_texture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.121281; + sum += texture2D(u_texture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.072994; + sum += texture2D(u_texture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.035855; + sum += texture2D(u_texture, vec2(tc.x + 5.0*blur*hstep, tc.y + 5.0*blur*vstep)) * 0.014374; + + gl_FragColor = sum; +} \ No newline at end of file diff --git a/old/android/assets/shaders/mesh.fsh b/old/android/assets/shaders/mesh.fsh new file mode 100644 index 0000000..0a10a45 --- /dev/null +++ b/old/android/assets/shaders/mesh.fsh @@ -0,0 +1,10 @@ +#ifdef GL_ES +precision mediump float; +#endif + +//input from vertex shader +varying vec4 vColor; + +void main() { + gl_FragColor = vColor; +} \ No newline at end of file diff --git a/old/android/assets/shaders/mesh.vsh b/old/android/assets/shaders/mesh.vsh new file mode 100644 index 0000000..9a9b0ca --- /dev/null +++ b/old/android/assets/shaders/mesh.vsh @@ -0,0 +1,13 @@ +attribute vec2 a_position; +attribute vec4 a_color; + +//our camera matrix +uniform mat4 u_projTrans; + +//send the color out to the fragment shader +varying vec4 vColor; + +void main() { + vColor = a_color; + gl_Position = u_projTrans * vec4(a_position.xy, 0.0, 1.0); +} \ No newline at end of file diff --git a/old/android/assets/sounds/disintegrate.ogg b/old/android/assets/sounds/disintegrate.ogg new file mode 100644 index 0000000..affc432 Binary files /dev/null and b/old/android/assets/sounds/disintegrate.ogg differ diff --git a/old/android/assets/sounds/explosion.ogg b/old/android/assets/sounds/explosion.ogg new file mode 100644 index 0000000..9011613 Binary files /dev/null and b/old/android/assets/sounds/explosion.ogg differ diff --git a/old/android/assets/sounds/laser.ogg b/old/android/assets/sounds/laser.ogg new file mode 100644 index 0000000..e3ea3f5 Binary files /dev/null and b/old/android/assets/sounds/laser.ogg differ diff --git a/old/android/assets/sounds/pop_close.ogg b/old/android/assets/sounds/pop_close.ogg new file mode 100644 index 0000000..9efde8b Binary files /dev/null and b/old/android/assets/sounds/pop_close.ogg differ diff --git a/old/android/assets/sounds/pop_open.ogg b/old/android/assets/sounds/pop_open.ogg new file mode 100644 index 0000000..8de88c5 Binary files /dev/null and b/old/android/assets/sounds/pop_open.ogg differ diff --git a/old/android/assets/splash_texture.png b/old/android/assets/splash_texture.png new file mode 100644 index 0000000..5f1fa4e Binary files /dev/null and b/old/android/assets/splash_texture.png differ diff --git a/old/android/assets/uiskin.atlas b/old/android/assets/uiskin.atlas new file mode 100644 index 0000000..78c174f --- /dev/null +++ b/old/android/assets/uiskin.atlas @@ -0,0 +1,403 @@ + +uiskin.png +size: 256,256 +format: RGBA8888 +filter: Linear,Linear +repeat: none +check-off + rotate: false + xy: 11, 5 + size: 14, 14 + split: 4, 4, 4, 4 + orig: 14, 14 + offset: 0, 0 + index: -1 +check-on + rotate: false + xy: 125, 35 + size: 14, 14 + split: 5, 5, 5, 5 + orig: 14, 14 + offset: 0, 0 + index: -1 +check-disabled + rotate: false + xy: 68, 14 + size: 14, 14 + split: 3, 3, 3, 3 + orig: 14, 14 + offset: 0, 0 + index: -1 +textfield + rotate: false + xy: 11, 5 + size: 14, 14 + split: 3, 3, 3, 3 + orig: 14, 14 + offset: 0, 0 + index: -1 +cursor + rotate: false + xy: 23, 1 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default + rotate: false + xy: 1, 50 + size: 254, 77 + orig: 254, 77 + offset: 0, 0 + index: -1 +default-pane + rotate: false + xy: 11, 1 + size: 5, 3 + split: 1, 1, 1, 1 + orig: 5, 3 + offset: 0, 0 + index: -1 +default-rect-pad + rotate: false + xy: 11, 1 + size: 5, 3 + split: 1, 1, 1, 1 + orig: 5, 3 + offset: 0, 0 + index: -1 +default-pane-noborder + rotate: false + xy: 170, 44 + size: 1, 1 + split: 0, 0, 0, 0 + orig: 1, 1 + offset: 0, 0 + index: -1 +default-rect + rotate: false + xy: 38, 25 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default-rect-down + rotate: false + xy: 170, 46 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default-round + rotate: false + xy: 112, 29 + size: 12, 20 + split: 5, 5, 5, 5 + orig: 12, 20 + offset: 0, 0 + index: -1 +default-round-down + rotate: false + xy: 99, 29 + size: 12, 20 + split: 5, 5, 5, 5 + orig: 12, 20 + offset: 0, 0 + index: -1 +default-round-disabled + rotate: false + xy: 89, 8 + size: 12, 20 + split: 5, 5, 5, 5 + orig: 12, 20 + offset: 0, 0 + index: -1 +default-scroll + rotate: false + xy: 57, 29 + size: 20, 20 + split: 5, 5, 5, 4 + orig: 20, 20 + offset: 0, 0 + index: -1 +default-round-large + rotate: false + xy: 78, 29 + size: 20, 20 + split: 2, 2, 2, 2 + orig: 20, 20 + offset: 0, 0 + index: -1 +default-select + rotate: false + xy: 29, 29 + size: 27, 20 + split: 4, 14, 4, 4 + orig: 27, 20 + offset: 0, 0 + index: -1 +default-select-selection + rotate: false + xy: 26, 16 + size: 3, 3 + split: 1, 1, 1, 1 + orig: 3, 3 + offset: 0, 0 + index: -1 +default-slider + rotate: false + xy: 29, 20 + size: 8, 8 + split: 2, 2, 2, 2 + orig: 8, 8 + offset: 0, 0 + index: -1 +default-slider-knob + rotate: false + xy: 1, 1 + size: 9, 18 + orig: 9, 18 + offset: 0, 0 + index: -1 +vertical-slider-knob + rotate: false + xy: 27, 1 + size: 14, 5 + orig: 14, 5 + offset: 0, 0 + index: -1 +progress-slider-knob + rotate: false + xy: 215, 1 + size:9, 18 + orig: 14, 5 + offset: 0, 0 + index: -1 +default-splitpane + rotate: false + xy: 17, 1 + size: 5, 3 + split: 0, 5, 0, 0 + orig: 5, 3 + offset: 0, 0 + index: -1 +default-splitpane-vertical + rotate: false + xy: 125, 29 + size: 3, 5 + split: 0, 0, 0, 5 + orig: 3, 5 + offset: 0, 0 + index: -1 +default-window + rotate: false + xy: 1, 20 + size: 27, 29 + split: 4, 3, 20, 3 + orig: 27, 29 + offset: 0, 0 + index: -1 +tinted-window + rotate: false + xy: 154, 5 + size: 27, 29 + split: 4, 3, 20, 3 + orig: 27, 29 + offset: 0, 0 + index: -1 +selection + rotate: false + xy: 174, 48 + size: 1, 1 + orig: 1, 1 + offset: 0, 0 + index: -1 +tree-minus + rotate: false + xy: 140, 35 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +tree-plus + rotate: false + xy: 155, 35 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +white + rotate: false + xy: 129, 31 + size: 3, 3 + orig: 3, 3 + offset: 0, 0 + index: -1 +pause + rotate: false + xy: 1, 50 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +pause-down + rotate: false + xy: 1, 96 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +bar-fill + rotate: false + xy: 105, 13 + size: 13, 3 + split: 0, 0, 0, 0 + orig: 13, 3 + offset: 0, 0 + index: -1 +bar-empty + rotate: false + xy: 119, 13 + size: 13, 3 + split: 1, 1, 1, 1 + orig: 13, 3 + offset: 0, 0 + index: -1 +left-button + rotate: false + xy: 42, 8 + size: 12, 20 + split: 1, 4, 3, 3 + orig: 12, 20 + offset: 0, 0 + index: -1 +left-button-down + rotate: false + xy: 55, 8 + size: 12, 20 + split: 1, 4, 3, 3 + orig: 12, 20 + offset: 0, 0 + index: -1 +play + rotate: false + xy: 47, 50 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +play-down + rotate: false + xy: 47, 96 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +fast-forward + rotate: false + xy: 93, 50 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +fast-forward-down + rotate: false + xy: 93, 96 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +rewind + rotate: false + xy: 139, 50 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +rewind-down + rotate: false + xy: 139, 96 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +shuffle + rotate: false + xy: 185, 50 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +shuffle-down + rotate: false; + xy: 185, 96 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +rotate + rotate: false; + xy: 47, 142 + size: 45, 45 + orig: 45, 45 + offset: 0, 0 + index: -1 +holo-pane + rotate: false + xy: 105, 17 + size: 8, 8 + split: 2, 2, 2, 2 + orig: 8, 8 + offset: 0, 0 + index: -1 +holo-pane-down + rotate: false + xy: 133, 8 + size: 20, 20 + split: 2, 2, 2, 2 + orig: 20, 20 + offset: 0, 0 + index: -1 +corner-panel + rotate: false + xy: 182, 1 + size: 32, 32 + split: 15, 15, 15, 15 + orig: 32, 32 + offset: 0, 0 + index: -1 +rect + rotate: false + xy: 176, 35 + size: 14, 14 + split: 3, 3, 3, 3 + orig: 14, 14 + offset: 0, 0 + index: -1 +rect-down + rotate: false + xy: 191, 35 + size: 14, 14 + split: 3, 3, 3, 3 + orig: 14, 14 + offset: 0, 0 + index: -1 +rect-disabled + rotate: false + xy: 206, 35 + size: 14, 14 + split: 3, 3, 3, 3 + orig: 14, 14 + offset: 0, 0 + index: -1 +side-bars + rotate: false + xy: 221, 35 + size: 15, 14 + split: 7, 7, 2, 2 + orig: 15, 14 + offset: 0, 0 + index: -1 \ No newline at end of file diff --git a/old/android/assets/uiskin.png b/old/android/assets/uiskin.png new file mode 100644 index 0000000..aa8491d Binary files /dev/null and b/old/android/assets/uiskin.png differ diff --git a/old/android/assets/uiskin_legacy.png b/old/android/assets/uiskin_legacy.png new file mode 100644 index 0000000..86e641f Binary files /dev/null and b/old/android/assets/uiskin_legacy.png differ diff --git a/old/android/assets/uiskin_legacyB.png b/old/android/assets/uiskin_legacyB.png new file mode 100644 index 0000000..960d314 Binary files /dev/null and b/old/android/assets/uiskin_legacyB.png differ diff --git a/old/android/build.gradle b/old/android/build.gradle new file mode 100644 index 0000000..a4548d3 --- /dev/null +++ b/old/android/build.gradle @@ -0,0 +1,136 @@ +android { + buildToolsVersion "27.0.3" + compileSdkVersion 27 + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = ['src'] + aidl.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + res.srcDirs = ['res'] + assets.srcDirs = ['assets'] + jniLibs.srcDirs = ['libs'] + } + + } + packagingOptions { + exclude 'META-INF/robovm/ios/robovm.xml' + } + defaultConfig { + applicationId "zero1hd.rhythmbullet" + minSdkVersion 9 + targetSdkVersion 27 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + + +// called every time gradle gets executed, takes the native dependencies of +// the natives configuration, and extracts them to the proper libs/ folders +// so they get packed with the APK. +task copyAndroidNatives() { + file("libs/armeabi/").mkdirs(); + file("libs/armeabi-v7a/").mkdirs(); + file("libs/arm64-v8a/").mkdirs(); + file("libs/x86_64/").mkdirs(); + file("libs/x86/").mkdirs(); + + configurations.natives.files.each { jar -> + def outputDir = null + if(jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a") + if(jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a") + if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi") + if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64") + if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86") + if(outputDir != null) { + copy { + from zipTree(jar) + into outputDir + include "*.so" + } + } + } +} + +task run(type: Exec) { + def path + def localProperties = project.file("../local.properties") + if (localProperties.exists()) { + Properties properties = new Properties() + localProperties.withInputStream { instr -> + properties.load(instr) + } + def sdkDir = properties.getProperty('sdk.dir') + if (sdkDir) { + path = sdkDir + } else { + path = "$System.env.ANDROID_HOME" + } + } else { + path = "$System.env.ANDROID_HOME" + } + + def adb = path + "/platform-tools/adb" + commandLine "$adb", 'shell', 'am', 'start', '-n', 'zero1hd.rhythmbullet/zero1hd.rhythmbullet.AndroidLauncher' +} + +// sets up the Android Eclipse project, using the old Ant based build. +eclipse { + // need to specify Java source sets explicitly, SpringSource Gradle Eclipse plugin + // ignores any nodes added in classpath.file.withXml + sourceSets { + main { + java.srcDirs "src", 'gen' + } + } + + jdt { + sourceCompatibility = 1.6 + targetCompatibility = 1.6 + } + + classpath { + plusConfigurations += [ project.configurations.compile ] + containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES' + } + + project { + name = appName + "-android" + natures 'com.android.ide.eclipse.adt.AndroidNature' + buildCommands.clear(); + buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder" + buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder" + buildCommand "org.eclipse.jdt.core.javabuilder" + buildCommand "com.android.ide.eclipse.adt.ApkBuilder" + } +} + +// sets up the Android Idea project, using the old Ant based build. +idea { + module { + sourceDirs += file("src"); + scopes = [ COMPILE: [plus:[project.configurations.compile]]] + + iml { + withXml { + def node = it.asNode() + def builder = NodeBuilder.newInstance(); + builder.current = node; + builder.component(name: "FacetManager") { + facet(type: "android", name: "Android") { + configuration { + option(name: "UPDATE_PROPERTY_FILES", value:"true") + } + } + } + } + } + } +} diff --git a/old/android/gen/zero1hd/rhythmbullet/BuildConfig.java b/old/android/gen/zero1hd/rhythmbullet/BuildConfig.java new file mode 100644 index 0000000..c53e38b --- /dev/null +++ b/old/android/gen/zero1hd/rhythmbullet/BuildConfig.java @@ -0,0 +1,6 @@ +/** Automatically generated file. DO NOT MODIFY */ +package zero1hd.rhythmbullet; + +public final class BuildConfig { + public final static boolean DEBUG = true; +} \ No newline at end of file diff --git a/old/android/gen/zero1hd/rhythmbullet/R.java b/old/android/gen/zero1hd/rhythmbullet/R.java new file mode 100644 index 0000000..37011d4 --- /dev/null +++ b/old/android/gen/zero1hd/rhythmbullet/R.java @@ -0,0 +1,22 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package zero1hd.rhythmbullet; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int ic_launcher=0x7f020000; + } + public static final class string { + public static final int app_name=0x7f030000; + } + public static final class style { + public static final int GdxTheme=0x7f040000; + } +} diff --git a/old/android/ic_launcher-web.png b/old/android/ic_launcher-web.png new file mode 100644 index 0000000..8f0110d Binary files /dev/null and b/old/android/ic_launcher-web.png differ diff --git a/old/android/libs/arm64-v8a/libgdx-freetype.so b/old/android/libs/arm64-v8a/libgdx-freetype.so new file mode 100644 index 0000000..2b7f8ca Binary files /dev/null and b/old/android/libs/arm64-v8a/libgdx-freetype.so differ diff --git a/old/android/libs/arm64-v8a/libgdx.so b/old/android/libs/arm64-v8a/libgdx.so new file mode 100644 index 0000000..24f4c99 Binary files /dev/null and b/old/android/libs/arm64-v8a/libgdx.so differ diff --git a/old/android/libs/armeabi-v7a/libgdx-freetype.so b/old/android/libs/armeabi-v7a/libgdx-freetype.so new file mode 100644 index 0000000..1b4c5d1 Binary files /dev/null and b/old/android/libs/armeabi-v7a/libgdx-freetype.so differ diff --git a/old/android/libs/armeabi-v7a/libgdx.so b/old/android/libs/armeabi-v7a/libgdx.so new file mode 100644 index 0000000..32664c4 Binary files /dev/null and b/old/android/libs/armeabi-v7a/libgdx.so differ diff --git a/old/android/libs/armeabi/libgdx-freetype.so b/old/android/libs/armeabi/libgdx-freetype.so new file mode 100644 index 0000000..c10bf64 Binary files /dev/null and b/old/android/libs/armeabi/libgdx-freetype.so differ diff --git a/old/android/libs/armeabi/libgdx.so b/old/android/libs/armeabi/libgdx.so new file mode 100644 index 0000000..b7fcf3f Binary files /dev/null and b/old/android/libs/armeabi/libgdx.so differ diff --git a/old/android/libs/x86_64/libgdx-freetype.so b/old/android/libs/x86_64/libgdx-freetype.so new file mode 100644 index 0000000..3b05cfc Binary files /dev/null and b/old/android/libs/x86_64/libgdx-freetype.so differ diff --git a/old/android/libs/x86_64/libgdx.so b/old/android/libs/x86_64/libgdx.so new file mode 100644 index 0000000..358f77c Binary files /dev/null and b/old/android/libs/x86_64/libgdx.so differ diff --git a/old/android/proguard-rules.pro b/old/android/proguard-rules.pro new file mode 100644 index 0000000..b166b1e --- /dev/null +++ b/old/android/proguard-rules.pro @@ -0,0 +1,45 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +-verbose + +-dontwarn android.support.** +-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication +-dontwarn com.badlogic.gdx.utils.GdxBuild +-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild +-dontwarn com.badlogic.gdx.jnigen.BuildTarget* +-dontwarn com.badlogic.gdx.graphics.g2d.freetype.FreetypeBuild + +-keep class com.badlogic.gdx.controllers.android.AndroidControllers + +-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* { + (com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration); +} + +-keepclassmembers class com.badlogic.gdx.physics.box2d.World { + boolean contactFilter(long, long); + void beginContact(long); + void endContact(long); + void preSolve(long, long); + void postSolve(long, long); + boolean reportFixture(long); + float reportRayFixture(long, float, float, float, float, float); +} diff --git a/old/android/project.properties b/old/android/project.properties new file mode 100644 index 0000000..3fefa92 --- /dev/null +++ b/old/android/project.properties @@ -0,0 +1,9 @@ +# This file is used by the Eclipse ADT plugin. It is unnecessary for IDEA and Android Studio projects, which +# configure Proguard and the Android target via the build.gradle file. + +# To enable ProGuard to work with Eclipse ADT, uncomment this (available properties: sdk.dir, user.home) +# and ensure proguard.jar in the Android SDK is up to date (or alternately reduce the android target to 23 or lower): +# proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-rules.pro + +# Project target. +target=android-19 diff --git a/old/android/res/drawable-hdpi/ic_launcher.png b/old/android/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..91f696b Binary files /dev/null and b/old/android/res/drawable-hdpi/ic_launcher.png differ diff --git a/old/android/res/drawable-mdpi/ic_launcher.png b/old/android/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..c1ab239 Binary files /dev/null and b/old/android/res/drawable-mdpi/ic_launcher.png differ diff --git a/old/android/res/drawable-xhdpi/ic_launcher.png b/old/android/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..2011cc0 Binary files /dev/null and b/old/android/res/drawable-xhdpi/ic_launcher.png differ diff --git a/old/android/res/drawable-xxhdpi/ic_launcher.png b/old/android/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..25fcef0 Binary files /dev/null and b/old/android/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/old/android/res/drawable-xxxhdpi/ic_launcher.png b/old/android/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..d109946 Binary files /dev/null and b/old/android/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/old/android/res/values/strings.xml b/old/android/res/values/strings.xml new file mode 100644 index 0000000..148fdbc --- /dev/null +++ b/old/android/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + RhythmBullet + + diff --git a/old/android/res/values/styles.xml b/old/android/res/values/styles.xml new file mode 100644 index 0000000..3f00fc5 --- /dev/null +++ b/old/android/res/values/styles.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/old/android/src/zero1hd/rhythmbullet/AndroidLauncher.java b/old/android/src/zero1hd/rhythmbullet/AndroidLauncher.java new file mode 100644 index 0000000..8e9b6d9 --- /dev/null +++ b/old/android/src/zero1hd/rhythmbullet/AndroidLauncher.java @@ -0,0 +1,14 @@ +package zero1hd.rhythmbullet; + +import android.os.Bundle; + +import com.badlogic.gdx.backends.android.AndroidApplication; + +public class AndroidLauncher extends AndroidApplication { + @Override + protected void onCreate (Bundle savedInstanceState) { + super.onCreate(savedInstanceState); +// AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); +// initialize(new RhythmBullet(), config); + } +} diff --git a/old/build.gradle b/old/build.gradle new file mode 100644 index 0000000..bf528ec --- /dev/null +++ b/old/build.gradle @@ -0,0 +1,91 @@ +buildscript { + + + repositories { + mavenLocal() + mavenCentral() + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + maven { url "https://dl.bintray.com/ijabz/maven/" } + jcenter() + google() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.0' + + + } +} + +allprojects { + apply plugin: "eclipse" + apply plugin: "idea" + + version = '1.0' + ext { + appName = "RhythmBullet" + gdxVersion = '1.9.8' + roboVMVersion = '2.3.3' + box2DLightsVersion = '1.4' + ashleyVersion = '1.7.0' + aiVersion = '1.8.0' + } + + repositories { + mavenLocal() + mavenCentral() + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + maven { url "https://oss.sonatype.org/content/repositories/releases/" } + } +} + +project(":desktop") { + apply plugin: "java" + + + dependencies { + compile project(":core") + compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" + compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" + compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" + } +} + +project(":android") { + apply plugin: "android" + + configurations { natives } + + dependencies { + compile project(":core") + compile "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64" + compile "com.badlogicgames.ashley:ashley:$ashleyVersion" + compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" + natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi" + natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a" + natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a" + natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86" + natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86_64" + } +} + +project(":core") { + apply plugin: "java" + + + dependencies { + compile "com.badlogicgames.gdx:gdx:$gdxVersion" + compile "com.badlogicgames.ashley:ashley:$ashleyVersion" + compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" + compile "com.github.rwl:jtransforms:2.4.0" + compile "org.apache.commons:commons-math3:3.2" + } +} + +tasks.eclipse.doLast { + delete ".project" +} \ No newline at end of file diff --git a/old/core/.classpath b/old/core/.classpath new file mode 100644 index 0000000..555bea3 --- /dev/null +++ b/old/core/.classpath @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/old/core/.project b/old/core/.project new file mode 100644 index 0000000..a67050c --- /dev/null +++ b/old/core/.project @@ -0,0 +1,18 @@ + + + RhythmBullet-core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.springsource.ide.eclipse.gradle.core.nature + org.eclipse.jdt.core.javanature + + diff --git a/old/core/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs b/old/core/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs new file mode 100644 index 0000000..74a3dd7 --- /dev/null +++ b/old/core/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs @@ -0,0 +1,4 @@ +#org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences +#Mon Sep 10 00:40:41 CDT 2018 +org.springsource.ide.eclipse.gradle.linkedresources= +org.springsource.ide.eclipse.gradle.rootprojectloc=.. diff --git a/old/core/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs b/old/core/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs new file mode 100644 index 0000000..599cb88 --- /dev/null +++ b/old/core/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs @@ -0,0 +1,8 @@ +#org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences +#Mon Sep 10 00:40:41 CDT 2018 +addResourceFilters=true +afterTasks=afterEclipseImport; +beforeTasks=cleanEclipse;eclipse; +enableAfterTasks=true +enableBeforeTasks=true +useHierarchicalNames=false diff --git a/old/core/.settings/org.eclipse.jdt.core.prefs b/old/core/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/old/core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/old/core/build.gradle b/old/core/build.gradle new file mode 100644 index 0000000..03cd1be --- /dev/null +++ b/old/core/build.gradle @@ -0,0 +1,11 @@ +apply plugin: "java" + +sourceCompatibility = 1.6 +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + +sourceSets.main.java.srcDirs = [ "src/" ] + + +eclipse.project { + name = appName + "-core" +} diff --git a/old/core/lib/jaudiotagger-2.2.3-javadoc.jar b/old/core/lib/jaudiotagger-2.2.3-javadoc.jar new file mode 100644 index 0000000..122f5ae Binary files /dev/null and b/old/core/lib/jaudiotagger-2.2.3-javadoc.jar differ diff --git a/old/core/lib/jaudiotagger-2.2.3-sources.jar b/old/core/lib/jaudiotagger-2.2.3-sources.jar new file mode 100644 index 0000000..31d7173 Binary files /dev/null and b/old/core/lib/jaudiotagger-2.2.3-sources.jar differ diff --git a/old/core/lib/jaudiotagger-2.2.3.jar b/old/core/lib/jaudiotagger-2.2.3.jar new file mode 100644 index 0000000..7069a3b Binary files /dev/null and b/old/core/lib/jaudiotagger-2.2.3.jar differ diff --git a/old/core/src/zero1hd/rhythmbullet/RhythmBullet.java b/old/core/src/zero1hd/rhythmbullet/RhythmBullet.java new file mode 100644 index 0000000..5afdb48 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/RhythmBullet.java @@ -0,0 +1,231 @@ +package zero1hd.rhythmbullet; + +import com.badlogic.gdx.Application; +import com.badlogic.gdx.Game; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.assets.loaders.ParticleEffectLoader; +import com.badlogic.gdx.assets.loaders.SoundLoader; +import com.badlogic.gdx.assets.loaders.TextureAtlasLoader; +import com.badlogic.gdx.assets.loaders.TextureLoader; +import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver; +import com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver.Resolution; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.ParticleEffect; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; + +import zero1hd.rhythmbullet.util.AssetPack; +import zero1hd.rhythmbullet.util.GenericFileTypeHandler; +import zero1hd.rhythmbullet.util.InitialScreen; +import zero1hd.rhythmbullet.util.RoundingResolutionHandler; +import zero1hd.rhythmbullet.util.ScreenConfiguration; +import zero1hd.rhythmbullet.util.ResizeReadyScreen; + + +public class RhythmBullet extends Game { + public static final int WORLD_WIDTH = 64; + public static final int WORLD_HEIGHT = 48; + public static final int SPAWN_CIRCLE_RADIUS = 6; + public static int pixels_per_unit; + private boolean initiated; + private boolean resizing, simpleResizeOnce; + private int screenWidth, screenHeight; + public static final String VERSION = "(1.0.0) R1-PreAlpha"; + + private AssetManager assetManager = new AssetManager(); + private Skin skin; + private Preferences preferences; + private RoundingResolutionHandler rRHandler; + private InitialScreen initialScreen; + private AssetPack assetPack; + private ScreenConfiguration screenConfiguration; + /** + * This should be called before passed to LWJGL. Setup for system-dependent items such as UI and assets. + * @param initialScreen the first screen to go to. + * @param assetPack the asset package to be used. + */ + public void setup(InitialScreen initialScreen, AssetPack assetPack, ScreenConfiguration screenConfiguration) { + this.initialScreen = initialScreen; + this.assetPack = assetPack; + this.screenConfiguration = screenConfiguration; + screenConfiguration.queueBorderless(true); + } + + @Override + public void create() { + setScreen(initialScreen); + Gdx.app.setLogLevel(Application.LOG_DEBUG); + screenWidth = Gdx.graphics.getWidth(); + screenHeight = Gdx.graphics.getHeight(); + initialScreen.init(); + initialLoad(); + } + + private void initialLoad() { + if (initiated) throw new IllegalStateException("Initiation cannot occur more than once."); + + simpleResizeOnce = true; + skin = new Skin(); + assetPack.initiate(); + + preferences = Gdx.app.getPreferences("RhythmBullet Preferences"); + + Resolution[] resolution = { + new Resolution(1280, 720, "1280x720"), + new Resolution(1366, 768, "1366x768"), + new Resolution(1280, 800, "1280x800"), + new Resolution(1920, 1080, "1920x1080"), + new Resolution(1920, 1200, "1920x1200"), + new Resolution(2560, 1440, "2560x1440"), + new Resolution(3840, 2160, "3840x2160") + }; + + InternalFileHandleResolver internalFileResolver = new InternalFileHandleResolver(); + rRHandler = new RoundingResolutionHandler(internalFileResolver, resolution); + GenericFileTypeHandler genericFileFinder = new GenericFileTypeHandler(internalFileResolver); + assetManager.setLoader(TextureAtlas.class, new TextureAtlasLoader(rRHandler)); + assetManager.setLoader(Texture.class, new TextureLoader(rRHandler)); + assetManager.setLoader(ParticleEffect.class, new ParticleEffectLoader(genericFileFinder)); + assetManager.setLoader(Sound.class, new SoundLoader(genericFileFinder)); + + rRHandler.setResolution(getPreferences().getInteger("screen-width"), getPreferences().getInteger("screen-height")); + queueAssets(); + } + + private void initialLoadComplete() { + screenConfiguration.queueBorderless(preferences.getBoolean("borderless", false)); + + skin.addRegions(assetManager.get("uiskin.atlas", TextureAtlas.class)); + pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT)); + if (getPreferences().getBoolean("fullscreen", true)) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } else { + Gdx.graphics.setWindowedMode(getPreferences().getInteger("screen-width"), getPreferences().getInteger("screen-height")); + } + assetPack.generateFonts(skin); + assetPack.setupSkin(skin); + assetPack.complete(assetManager); + + } + + @Override + public void render() { + checkAssetQueue(); + super.render(); + } + + public boolean checkAssetQueue() { + if (assetManager.update()) { + if (resizing) { + Gdx.app.debug("Resize", "Post resize is starting..."); + if (skin != null) skin.dispose(); + skin = new Skin(); + skin.addRegions(assetManager.get("uiskin.atlas", TextureAtlas.class)); + + assetPack.generateFonts(skin); + assetPack.setupSkin(skin); + assetPack.complete(assetManager); + if (getScreen() instanceof ResizeReadyScreen) { + ((ResizeReadyScreen) getScreen()).postAssetLoad(); + } else { + throw new IllegalStateException("Cannot perform window resize on a screen that isn't resize ready."); + } + Gdx.app.debug("Resize", "Post resize has ended."); + resizing = false; + } else if (!initiated) { + initiated = true; + initialLoadComplete(); + setScreen(((InitialScreen) initialScreen).advance(this)); + } + return true; + } + return false; + } + + + @Override + public void setScreen(Screen screen) { + if (screen instanceof ResizeReadyScreen) { + ResizeReadyScreen advancedResizeScreen = (ResizeReadyScreen) screen; + try { + advancedResizeScreen.preAssetLoad(); + } catch (NullPointerException cleanScreen) { + Gdx.app.debug("Screen", "clean screen: " + advancedResizeScreen.getClass().getSimpleName()); + //Tried to perform pre-asset reload, but had uninitialized objects, meaning this is a new screen, or "clean" screen. + } finally { + advancedResizeScreen.postAssetLoad(); + } + } + super.setScreen(screen); + } + + @Override + public void resize(int width, int height) { + if (screenWidth != width || screenHeight != height) { + Gdx.app.debug("resize", "Current size:" + screenWidth + "x" + screenHeight + " new size: " + width + "x" + height); + screenWidth = width; + screenHeight = height; + pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT)); + rRHandler.setResolution(width, height); + preferences.putInteger("screen-width", width); + preferences.putInteger("screen-height", height); + preferences.flush(); + + if (!simpleResizeOnce) { + Gdx.app.debug("Resize", "complex pre-resize is happening. Resizing to " + width + "x" + height); + if (getScreen() instanceof ResizeReadyScreen) { + ((ResizeReadyScreen) getScreen()).preAssetLoad(); + } else { + throw new IllegalStateException("Cannot perform window resize on a screen that isn't using a resize ready screen."); + } + + resizing = true; + assetManager.clear(); + queueAssets(); + } else { + simpleResizeOnce = false; + } + super.resize(width, height); + } + } + + public void queueAssets() { + assetPack.queueTextures(assetManager); + assetPack.queueSFX(assetManager); + assetPack.queueParticles(assetManager); + } + + public AssetManager getAssetManager() { + return assetManager; + } + + public Skin getSkin() { + return skin; + } + + public Preferences getPreferences() { + return preferences; + } + + @Override + public void dispose() { + Gdx.app.debug("Core", "disposing..."); + try { + getScreen().dispose(); + getSkin().dispose(); + assetManager.dispose(); + assetPack.dispose(); + } catch (NullPointerException npe) { + Gdx.app.debug("Core", "Disposal error occurred, possibly caused by failing to complete initialization.", npe); + } + super.dispose(); + } + + public ScreenConfiguration getScreenConfiguration() { + return screenConfiguration; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/AudioMetadataController.java b/old/core/src/zero1hd/rhythmbullet/audio/AudioMetadataController.java new file mode 100644 index 0000000..15bca8a --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/AudioMetadataController.java @@ -0,0 +1,166 @@ +package zero1hd.rhythmbullet.audio; + +import java.util.Comparator; +import java.util.Observable; +import java.util.Observer; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Disposable; +import com.badlogic.gdx.utils.Sort; + +import zero1hd.rhythmbullet.audio.metadata.AudioMetadata; +import zero1hd.rhythmbullet.audio.metadata.MP3Metadata; +import zero1hd.rhythmbullet.audio.metadata.WAVMetadata; + +public class AudioMetadataController extends Observable implements Disposable, Observer { + private MusicList musicList; + private volatile Array metadataArray; + private MetadataLoadingThread loadingThread; + private volatile boolean searching; + private Comparator metadataComparer; + + public AudioMetadataController(MusicList musicList) { + this.musicList = musicList; + metadataArray = new Array<>(); + loadingThread = new MetadataLoadingThread(); + musicList.addObserver(this); + metadataComparer = new Comparator() { + @Override + public int compare(AudioMetadata o1, AudioMetadata o2) { + return o1.getTitle().compareToIgnoreCase(o2.getTitle()); + } + }; + } + + public MusicList getMusicList() { + return musicList; + } + + /** + * Non-blocking, loads on separate thread. + */ + public void loadAudioMetadata() { + if (!loadingThread.start()) { + loadingThread.stop(); + loadingThread = new MetadataLoadingThread(); + loadingThread.start(); + } + } + + /** + * if there is the same amount of metadata as there is music in the music list. + * @return whether or not both sizes are equal. + */ + public boolean isSameSizeMusicList() { + return (metadataArray.size == musicList.getTotal()); + } + + @Override + public void dispose() { + for (int i = 0; i < metadataArray.size; i++) { + metadataArray.get(i).dispose(); + } + } + + public int size() { + return metadataArray.size; + } + + public AudioMetadata getAudioMetadata(int index) { + return metadataArray.get(index); + } + + + public AudioMetadata getAudioMetadata(FileHandle filehandle) { + for (int i = 0; i < metadataArray.size; i++) { + if (metadataArray.get(i).getFileHandle() == filehandle) { + return metadataArray.get(i); + } + } + throw new IllegalArgumentException("Couldn't find file " + filehandle.name()); + } + + public boolean isSearching() { + return searching; + } + + private class MetadataLoadingThread implements Runnable { + private Thread thread; + private String name = "AudioMetadata-Load"; + private volatile boolean work = true; + + @Override + public void run() { + Gdx.app.debug(name, "loading..."); + clear(); + synchronized (this) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + searching = true; + Array tempMetadataArray = new Array<>(); + for (int i = 0; i < musicList.getTotal() && work; i++) { + FileHandle musicFile = musicList.getAudioFileHandle(i); + if (musicFile == null) return; + switch (SupportedFormats.valueOf(musicFile.extension().toUpperCase())) { + case MP3: + tempMetadataArray.add(new MP3Metadata(musicFile)); + break; + case WAV: + tempMetadataArray.add(new WAVMetadata(musicFile)); + break; + default: + break; + } + } + + Sort.instance().sort(tempMetadataArray, metadataComparer); + + if (work) { + metadataArray = tempMetadataArray; + searching = false; + Gdx.app.debug(name, "load complete."); + setChanged(); + notifyObservers(); + } + } + + public boolean start() { + if (thread == null) { + thread = new Thread(this, name); + thread.start(); + return true; + } else { + return false; + } + } + + public void stop() { + work = false; + } + } + + @Override + public void update(Observable o, Object arg) { + if (o == musicList && arg == musicList.states.COMPLETE) { + loadAudioMetadata(); + } + } + + public void clear() { + Gdx.app.postRunnable(() -> { + for (int i = 0; i < metadataArray.size; i++) { + metadataArray.get(i).dispose(); + } + metadataArray.clear(); + synchronized (loadingThread) { + loadingThread.notify(); + } + }); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/AudioProcessorFactory.java b/old/core/src/zero1hd/rhythmbullet/audio/AudioProcessorFactory.java new file mode 100644 index 0000000..fdd39e2 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/AudioProcessorFactory.java @@ -0,0 +1,12 @@ +package zero1hd.rhythmbullet.audio; + +import com.badlogic.gdx.files.FileHandle; + +import zero1hd.rhythmbullet.audio.processor.AudioProcessor; + +public interface AudioProcessorFactory { + /** + * @return a new {@link #zero1hd.rhythmbullet.audio.processor.AudioProcessor()} from the appropriate platform. + */ + public AudioProcessor newMP3AudioProcessor(FileHandle fileHandle); +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/MinimalAudioHeader.java b/old/core/src/zero1hd/rhythmbullet/audio/MinimalAudioHeader.java new file mode 100644 index 0000000..55a028e --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/MinimalAudioHeader.java @@ -0,0 +1,61 @@ +package zero1hd.rhythmbullet.audio; + +import java.io.IOException; + +import org.jaudiotagger.audio.AudioFile; +import org.jaudiotagger.audio.AudioFileIO; +import org.jaudiotagger.audio.AudioHeader; +import org.jaudiotagger.audio.exceptions.CannotReadException; +import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException; +import org.jaudiotagger.audio.exceptions.ReadOnlyFileException; +import org.jaudiotagger.audio.mp3.MP3AudioHeader; +import org.jaudiotagger.audio.mp3.MP3File; +import org.jaudiotagger.tag.TagException; + +import com.badlogic.gdx.files.FileHandle; + +public class MinimalAudioHeader { + private int sampleRate, channelCount; + private SupportedFormats format; + private FileHandle musicFile; + public MinimalAudioHeader(FileHandle musicFile) { + if (musicFile == null) throw new IllegalArgumentException("musicFile for minimal audio headers should not be null."); + this.musicFile = musicFile; + format = SupportedFormats.valueOf(musicFile.extension().toUpperCase()); + try { + AudioFile file = AudioFileIO.read(musicFile.file()); + AudioHeader header = file.getAudioHeader(); + sampleRate = header.getSampleRateAsNumber(); + channelCount = (header.getChannels().equals("Mono") ? 1 : 2); + } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { + e.printStackTrace(); + } + } + + + + public int getSampleRate() { + return sampleRate; + } + + public int getChannelCount() { + return channelCount; + } + + + public long estimateSampleFrames() { + switch (format) { + case MP3: + try { + MP3File file = (MP3File) AudioFileIO.read(musicFile.file()); + MP3AudioHeader header = file.getMP3AudioHeader(); + return header.getNumberOfFrames(); + } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { + e.printStackTrace(); + } + return -1; + default: + return -1; + } + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/MusicController.java b/old/core/src/zero1hd/rhythmbullet/audio/MusicController.java new file mode 100644 index 0000000..74ae39e --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/MusicController.java @@ -0,0 +1,262 @@ +package zero1hd.rhythmbullet.audio; + +import java.util.Observable; +import java.util.Observer; +import java.util.Random; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.audio.Music.OnCompletionListener; +import com.badlogic.gdx.files.FileHandle; + +/** + * Manages current games music playback and does this in tandem with the {@link MusicList} by asking to retrieve files and then feeding it to LibGDX. + * Notifies observers when a new song is loaded. + * The loading model is like taking a disk and loading it into a player. It doesn't necessarily mean it'll play right away, but its ready and the only track that has a stream opened. + * @author yunya + * + */ +public class MusicController extends Observable implements OnCompletionListener, Observer { + public final class States { + public final Integer LOADED = new Integer(0), PLAYING = new Integer(1), PAUSED = new Integer(2); + } + + public final States states = new States(); + private MusicList musicList; + private MinimalAudioHeader musicHeader; + private volatile Music music; + private int currentlyPlayingIndex; + private boolean autoPlay; + private boolean shuffle; + private Random rand; + private Preferences prefs; + + public MusicController(MusicList musicList, Preferences prefs) { + if (prefs == null) throw new NullPointerException("preferences can't be null..."); + if (musicList == null) throw new NullPointerException("music list can't be null..."); + musicList.addObserver(this); + this.prefs = prefs; + this.musicList = musicList; + rand = new Random(); + } + + /** + * This play method automatically sets the volume. + */ + public void play() { + if (music != null) { + Gdx.app.debug("MusicController", "Playing from controller."); + music.play(); + music.setVolume(prefs.getFloat("music vol", 100f)/100f); + setChanged(); + notifyObservers(states.PLAYING); + } else { + Gdx.app.debug("MusicController", "Music isn't loaded!"); + Thread.dumpStack(); + } + } + + /** + * Called to pause current song. Does nothing if no song is playing or loaded. + */ + public void pause() { + if (music != null) { + music.pause(); + setChanged(); + notifyObservers(states.PAUSED); + } + } + + /** + * Loads music based on the index in the {@link MusicList}. + * @param index of music to play + */ + public void setMusicByIndex(int index) { + this.currentlyPlayingIndex = index; + loadMusic(); + } + + /** + * Loads music using the given file. The given file must be found in the {@link MusicList}. + * This function gets the index of the given file within {@link MusicList} and passes that index to {@link #setMusicByIndex(index)}. + * @param fileHandle to use. + */ + public void setMusicByFileHandle(FileHandle fileHandle) { + setMusicByIndex(musicList.getIndexOfFileHandle(fileHandle)); + } + + /** + * Goes to the next track + */ + public void skip() { + currentlyPlayingIndex++; + if (shuffle) { + shuffle(); + } + loadMusic(); + } + + /** + * Goes to the previous track + */ + public void previous() { + currentlyPlayingIndex--; + if (shuffle) { + shuffle(); + } + loadMusic(); + } + + @Override + public void onCompletion(Music music) { + if (autoPlay) { + if (shuffle) { + shuffle(); + } else { + currentlyPlayingIndex++; + } + loadMusic(); + play(); + } + } + + /** + * Shuffles the controller whether the shuffle boolean is true or false. + */ + public void shuffle() { + Gdx.app.debug("MusicListController", "shuffled."); + if (musicList.getTotal() == 0) { + currentlyPlayingIndex = 0; + } else { + currentlyPlayingIndex = rand.nextInt(musicList.getTotal()); + } + } + + public void setAutoPlay(boolean autoPlay) { + this.autoPlay = autoPlay; + } + + public void setShuffle(boolean shuffle) { + this.shuffle = shuffle; + } + + public void setLoop(boolean loop) { + music.setLooping(loop); + } + + public boolean isShuffle() { + return shuffle; + } + + public boolean isAutoPlay() { + return autoPlay; + } + + public boolean isLoop() { + return music.isLooping(); + } + + /** + * Loads the current selected song. + */ + public void loadMusic() { + Gdx.app.debug("MusicListController", "music is being loaded from music list with " + musicList.getTotal() + " songs."); + boolean playing = isPlaying(); + musicHeader = null; + if (music != null) { + music.dispose(); + } + if (currentlyPlayingIndex < 0) { + currentlyPlayingIndex = musicList.getTotal()-1; + } + if (currentlyPlayingIndex >= musicList.getTotal()) { + currentlyPlayingIndex = 0; + } + if (musicList.getTotal() != 0) { + this.music = Gdx.audio.newMusic(musicList.getAudioFileHandle(currentlyPlayingIndex)); + music.setOnCompletionListener(this); + + setChanged(); + + notifyObservers(states.LOADED); + if (playing || autoPlay) { + play(); + } + } + } + + public MusicList getMusicList() { + return musicList; + } + + public FileHandle getCurrentMusicFileHandle() { + return musicList.getSongFileHandleFromIndex(currentlyPlayingIndex); + } + + public MinimalAudioHeader getCurrentMusicHeader() { + if (musicHeader != null) { + return musicHeader; + } else { + return musicHeader = musicList.newMinimalAudioHeader(getCurrentMusicFileHandle()); + } + } + + @Override + public void update(Observable o, Object arg) { + if (o == musicList) { + if (arg == musicList.states.LOADING) { + pause(); + } else if (arg == musicList.states.COMPLETE) { + if (shuffle) { + shuffle(); + } + loadMusic(); + } + } + } + + public String getCurrentSongName() { + return getCurrentMusicFileHandle().nameWithoutExtension(); + } + + public float getCurrentPosition() { + if (music != null) { + return music.getPosition(); + } + return 0; + } + + public void setMusicPosition(float position) { + if (music != null) { + music.setPosition(position); + } + } + + public boolean isPlaying() { + if (music != null) { + return music.isPlaying(); + } + return false; + } + + /** + * Returns the current music. In no circumstances should this be used to begin playing or it would be playing independent of the controller. + * Doing otherwise would mean you are playing the music separately of the controller. + * @return the {@link Music} that is currently "loaded" and ready to play. + */ + public Music getCurrentMusic() { + return music; + } + + public int getCurrentlyPlayingIndex() { + return currentlyPlayingIndex; + } + + public boolean hasSongLoaded() { + if (music != null) { + return true; + } + return false; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/MusicList.java b/old/core/src/zero1hd/rhythmbullet/audio/MusicList.java new file mode 100644 index 0000000..1148d7b --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/MusicList.java @@ -0,0 +1,211 @@ +package zero1hd.rhythmbullet.audio; + +import java.util.Comparator; +import java.util.Observable; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Sort; + +import zero1hd.rhythmbullet.audio.processor.AudioProcessor; +import zero1hd.rhythmbullet.audio.processor.WAVAudioProcessor; + +/** + * A music list made to store paths to all the songs within a given directory. Can activate the music calling {@link #newAudioProcessor(FileHandle)} and its derivatives. + * Is observable, meaning, given there are observers, will notify when the list completes a refresh. + * @author yunya + */ +public class MusicList extends Observable { + public final class States { + public final Integer LOADING = new Integer(0), COMPLETE = new Integer(1), EMPTY = new Integer(2); + } + public States states = new States(); + private Array musicList; + private RecursiveMusicSearchThread searchThread; + private AudioProcessorFactory audioProcFactory; + private volatile boolean searched; + private String searchPath; + private Comparator compare; + + public MusicList(AudioProcessorFactory audioProcessorFactory, String searchPath) { + this.audioProcFactory = audioProcessorFactory; + musicList = new Array<>(); + setSearchPath(searchPath); + + compare = new Comparator() { + + @Override + public int compare(FileHandle o1, FileHandle o2) { + return o1.nameWithoutExtension().compareTo(o2.nameWithoutExtension()); + } + }; + } + + /** + * Asynchronous recursive search on music directory. + * Also notifies listeners that are on the main thread. + * @param refresh does a search whether or not path has changed and whether or not this list has searched before this. + */ + public void attemptAsyncSearch(boolean refresh) { + if (refresh) { + notifyObservers(states.LOADING); + if (searchThread != null) { + if (!searchThread.start()) { + searchThread.stop(); + searchThread = new RecursiveMusicSearchThread("Music Search Thread", Gdx.files.absolute(searchPath)); + searchThread.start(); + } + } else { + searchThread = new RecursiveMusicSearchThread("Music Search Thread", Gdx.files.absolute(searchPath)); + searchThread.start(); + } + } else { + if (!searched || hasChanged()) { + attemptAsyncSearch(true); + } + } + } + + public void setSearchPath(String searchPath) { + if (this.searchPath != null && this.searchPath.equals(searchPath)) return; + this.searchPath = searchPath; + setChanged(); + } + + public String getSearchPath() { + return searchPath; + } + + /** + * @param file + * @return a {@link AudioProcessor} of the given music file. Will return null if theres a format error. + */ + public AudioProcessor newAudioProcessor(FileHandle file) { + switch (SupportedFormats.valueOf(file.extension().toUpperCase())) { + case MP3: + return audioProcFactory.newMP3AudioProcessor(file); + case WAV: + return new WAVAudioProcessor(file); + default: + break; + } + return null; + } + + /** + * + * @param file the music file that you need the header for. + * @return the header containing minimal info of the song. + */ + public MinimalAudioHeader newMinimalAudioHeader(FileHandle file) { + return new MinimalAudioHeader(file); + } + + public AudioProcessor newAudioProcessorFromIndex(int index) { + if (!searched) { + Gdx.app.debug("MusicList", "Warning, this list has not completed it's search..."); + Thread.dumpStack(); + } + if (musicList.size == 0) { + return null; + } + return newAudioProcessor(musicList.get(index)); + } + + + public FileHandle getSongFileHandleFromIndex(int index) { + if (!searched) { + Gdx.app.debug("MusicList", "Warning, this list has not completed it's search..."); + Thread.dumpStack(); + } + if (musicList.size == 0) { + return null; + } + return musicList.get(index); + } + + public FileHandle getAudioFileHandle(int index) { + return musicList.get(index); + } + + public int getIndexOfFileHandle(FileHandle file) { + return musicList.indexOf(file, true); + } + + public boolean isSearched() { + return searched; + } + + /** + * + * @return the amount of audio files discovered. + */ + public int getTotal() { + return musicList.size; + } + + private class RecursiveMusicSearchThread implements Runnable { + private Thread thread; + private String threadName; + private FileHandle directory; + private volatile boolean work; + + public RecursiveMusicSearchThread(String name, FileHandle searchDirectory) { + this.threadName = name; + this.directory = searchDirectory; + } + + @Override + public void run() { + Gdx.app.debug("MusicList", "recursive async search beginning."); + Array obtainedAudioFiles = recursiveMusicSearch(directory); + Sort.instance().sort(obtainedAudioFiles, compare); + if (work) { + musicList = obtainedAudioFiles; + searched = true; + Gdx.app.debug("MusicList", "recursive async search completed."); + setChanged(); + if (musicList.size != 0) { + notifyObservers(states.COMPLETE); + } else { + notifyObservers(states.EMPTY); + } + } + } + + public boolean start() { + if (thread == null) { + work = true; + thread = new Thread(this, threadName); + thread.setDaemon(true); + thread.start(); + return true; + } else { + return false; + } + } + + public void stop() { + work = false; + } + + private Array recursiveMusicSearch(FileHandle fileHandle) { + Array musicFiles = new Array<>(); + FileHandle[] files = fileHandle.list(); + for (int i = 0; i < files.length && work; i++) { + if (files[i].isDirectory()) { + musicFiles.addAll(recursiveMusicSearch(files[i])); + } else { + try { + SupportedFormats.valueOf(files[i].extension().toUpperCase()); + musicFiles.add(files[i]); + } catch (IllegalArgumentException e) { + Gdx.app.log("MusicList", "Unsupported file format: " + files[i].name()); + } + } + } + return musicFiles; + } + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/SupportedFormats.java b/old/core/src/zero1hd/rhythmbullet/audio/SupportedFormats.java new file mode 100644 index 0000000..da39e60 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/SupportedFormats.java @@ -0,0 +1,5 @@ +package zero1hd.rhythmbullet.audio; + +public enum SupportedFormats { + WAV, MP3; +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/analyzer/AudioAnalyzerSection.java b/old/core/src/zero1hd/rhythmbullet/audio/analyzer/AudioAnalyzerSection.java new file mode 100644 index 0000000..b238aac --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/analyzer/AudioAnalyzerSection.java @@ -0,0 +1,49 @@ +package zero1hd.rhythmbullet.audio.analyzer; + +import com.badlogic.gdx.utils.FloatArray; + +public class AudioAnalyzerSection { + private int lower, upper, thresholdRange; + private float thresholdFactor; + private FloatArray peaks; + private int pUID; + + public AudioAnalyzerSection(int lowerBin, int upperBin, float thresholdFactor, int thresholdRange) { + this.upper = upperBin; + this.lower = lowerBin; + this.thresholdRange = thresholdRange; + this.thresholdFactor = thresholdFactor; + } + + public void setPUID(int pUID) { + this.pUID = pUID; + } + + public void setPeaks(FloatArray peaks) { + this.peaks = peaks; + } + + public int getLower() { + return lower; + } + + public int getUpper() { + return upper; + } + + public float getThresholdFactor() { + return thresholdFactor; + } + + public int getThresholdRange() { + return thresholdRange; + } + + public FloatArray getPeaks() { + return peaks; + } + + public int getPUID() { + return pUID; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/analyzer/DynamicAudioAnalyzer.java b/old/core/src/zero1hd/rhythmbullet/audio/analyzer/DynamicAudioAnalyzer.java new file mode 100644 index 0000000..b645d04 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/analyzer/DynamicAudioAnalyzer.java @@ -0,0 +1,148 @@ +package zero1hd.rhythmbullet.audio.analyzer; + +import java.util.Observable; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.utils.FloatArray; +import com.badlogic.gdx.utils.TimeUtils; + +import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D; +import zero1hd.rhythmbullet.audio.processor.AudioProcessor; + +public class DynamicAudioAnalyzer extends Observable implements Runnable { + private volatile boolean work = true; + private Thread thread; + private String threadName = "analyzer"; + private final int WINDOWLENGTH = 1024; + private AudioProcessor processor; + private AudioAnalyzerSection[] sections; + private FloatArray[] flux; + private FloatArray[] threshold; + private volatile int pUID = 0; + private long timer; + + public DynamicAudioAnalyzer(AudioProcessor processor, AudioAnalyzerSection... sections) { + this.sections = sections; + this.processor = processor; + flux = new FloatArray[sections.length]; + threshold = new FloatArray[sections.length]; + + for (int section = 0; section < sections.length; section++) { + flux[section] = new FloatArray(); + threshold[section] = new FloatArray(); + } + } + + @Override + public void run() { + calculateSpectralFlux(); + calculateThreshold(); + calculatePeaks(); + } + + public void start() { + if (thread == null) { + thread = new Thread(this, threadName); + thread.setDaemon(true); + thread.start(); + } else { + throw new IllegalStateException("Cannot have two analyzer threads."); + } + } + + public void stop() { + work = false; + } + + private void calculateSpectralFlux() { + Gdx.app.debug("Spectral Flux Calculation", "Beginning..."); + timer = TimeUtils.millis(); + float[] audioPCM = new float[WINDOWLENGTH]; + float[] spectrum = new float[(WINDOWLENGTH/2)+1]; + float[] lastSpectrum = new float[spectrum.length]; + FloatFFT_1D fft = new FloatFFT_1D(WINDOWLENGTH); + int windowsComplete = 0; + int seedCurrentDigit = 0; + + int totalWindows = (int) processor.getSampleFrames()/WINDOWLENGTH; + while (processor.readFrames(audioPCM) > 0 && work) { + fft.realForward(audioPCM); + + //Building a PUID (Pseudo unique ID) + if (windowsComplete == (seedCurrentDigit*totalWindows/9)) { + float avg = 0; + for (int frame = 0; frame < spectrum.length; frame++) { + avg += spectrum[frame]; + } + avg /= spectrum.length; + if (avg < 0) { + avg *= -1f; + } + pUID +=(int) Math.pow(10, 9-seedCurrentDigit) * ((int)(avg*1000f)-(int)(avg*100f)*10); + seedCurrentDigit ++; + } + + System.arraycopy(spectrum, 0, lastSpectrum, 0, spectrum.length); + System.arraycopy(audioPCM, 0, spectrum, 0, spectrum.length); + + for (int section = 0; section < sections.length; section++) { + float currentFlux = 0; + for (int bin = sections[section].getLower(); bin < sections[section].getUpper(); bin++) { + currentFlux += Math.max(0f, spectrum[bin] - lastSpectrum[bin]); + } + flux[section].add(currentFlux); + } + + windowsComplete++; + } + + for (int section = 0; section < sections.length; section++) { + sections[section].setPUID(pUID); + } + + Gdx.app.debug("Spectral Flux Calculation", "Finished. Took " + (TimeUtils.timeSinceMillis(timer)) + "ms"); + } + + private void calculateThreshold() { + long subTimer = TimeUtils.millis(); + Gdx.app.debug("Threshold Calculation", "Beginning..."); + for (int section = 0; section < sections.length && work; section++) { + FloatArray fluxArray = flux[section]; + for (int bin = 0; bin < fluxArray.size; bin++) { + int range = sections[section].getThresholdRange(); + int start = Math.max(0, bin - range); + int end = Math.min(fluxArray.size, bin + range); + + float average = 0; + for (int pos = start; pos < end; pos++) { + average += fluxArray.get(pos); + } + average /= (end - start); + threshold[section].add(average); + } + } + + Gdx.app.debug("Spectral Flux Calculation", "Finished. Took " + (TimeUtils.timeSinceMillis(subTimer)) + "ms"); + } + + private void calculatePeaks() { + long subTimer = TimeUtils.millis(); + Gdx.app.debug("Peak Calculation", "Beginning..."); + for (int section = 0; section < sections.length && work; section++) { + FloatArray peaks = new FloatArray(); + + for (int bin = 0; bin < threshold[section].size -1; bin++) { + float prunedFlux = flux[section].get(bin) - threshold[section].get(bin); + float prunedNextFlux = flux[section].get(bin + 1) - threshold[section].get(bin + 1); + + peaks.add((prunedFlux > prunedNextFlux) ? prunedFlux : 0); + } + + sections[section].setPeaks(peaks); + } + Gdx.app.debug("Spectral Flux Calculation", "Finished. Took " + (TimeUtils.timeSinceMillis(subTimer)) + "ms. Total time was " + (TimeUtils.timeSinceMillis(timer))); + + setChanged(); + notifyObservers(); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/metadata/AudioMetadata.java b/old/core/src/zero1hd/rhythmbullet/audio/metadata/AudioMetadata.java new file mode 100644 index 0000000..10157bb --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/metadata/AudioMetadata.java @@ -0,0 +1,70 @@ +/** + * Metadata for audio. Not thread-safe. + * @author yunya + * + */ + +package zero1hd.rhythmbullet.audio.metadata; + +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.utils.Disposable; + +public interface AudioMetadata extends Disposable { + /** + * Load the album art data in to memory. + * Will not load if already loaded. + */ + public void loadAlbumCover(); + + /** + * Unloads album art from memory. + * Requires OpenGL context. + */ + public void unloadAlbumCover(); + + /** + * + * @return the author for the song in the metadata. + */ + public String getAuthor(); + + /** + * + * @return the title of the song in the metadata, or if it doesn't exist, the filename without extension and _ is given. + */ + public String getTitle(); + + /** + * + * @return the length of the song with proper fomatting. + */ + public String getDuration(); + + /** + * + * @return the length of the song in seconds. + */ + public int getLength(); + + /** + * Requires a OpenGL context. + * @return the texture. Needs to be loaded before hand or else will return null. + */ + public Texture getAlbumCover(); + + /** + * + * @return returns the genre of the song stored in metadata. + */ + public String getGenre(); + + /** + * + * @return the filehandle. + */ + public FileHandle getFileHandle(); + + @Override + public void dispose(); +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/metadata/MP3Metadata.java b/old/core/src/zero1hd/rhythmbullet/audio/metadata/MP3Metadata.java new file mode 100644 index 0000000..8ac7145 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/metadata/MP3Metadata.java @@ -0,0 +1,124 @@ +package zero1hd.rhythmbullet.audio.metadata; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.jaudiotagger.audio.AudioFileIO; +import org.jaudiotagger.audio.exceptions.CannotReadException; +import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException; +import org.jaudiotagger.audio.exceptions.ReadOnlyFileException; +import org.jaudiotagger.audio.mp3.MP3File; +import org.jaudiotagger.tag.TagException; +import org.jaudiotagger.tag.id3.ID3v23FieldKey; +import org.jaudiotagger.tag.id3.ID3v23Tag; +import org.jaudiotagger.tag.images.Artwork; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; + +public class MP3Metadata implements AudioMetadata { + private String title, author, duration, genre; + private int length; + private Texture albumCover; + private FileHandle fileHandle; + private Pixmap pixmap; + + public MP3Metadata(FileHandle fileHandle) { + this.fileHandle = fileHandle; + + try { + MP3File mp3file = (MP3File) AudioFileIO.read(fileHandle.file()); + ID3v23Tag tag; + tag = (ID3v23Tag) mp3file.getTagAndConvertOrCreateAndSetDefault(); + + length = mp3file.getAudioHeader().getTrackLength(); + SimpleDateFormat f = new SimpleDateFormat("m:ss"); + duration = f.format(new Date(length*1000)); + + author = tag.getFirst(ID3v23FieldKey.ARTIST); + genre = tag.getFirst(ID3v23FieldKey.GENRE); + title = tag.getFirst(ID3v23FieldKey.TITLE); + if (title.isEmpty()) { + title = fileHandle.nameWithoutExtension().replace('_', ' '); + } + } catch (IOException | CannotReadException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { + Gdx.app.error("MP3Metadata", "Failed to read metadata of file: " + fileHandle.name()); + } + } + + @Override + public void loadAlbumCover() { + if (pixmap == null) { + try { + MP3File mp3file; + mp3file = (MP3File) AudioFileIO.read(fileHandle.file()); + Artwork art = mp3file.getTag().getFirstArtwork(); + if (art != null) { + byte[] imageData = art.getBinaryData(); + pixmap = new Pixmap(imageData, 0, imageData.length); + } + + } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { + e.printStackTrace(); + } + } + } + + @Override + public String getAuthor() { + return author; + } + + @Override + public String getTitle() { + return title; + } + + @Override + public String getDuration() { + return duration; + } + + @Override + public int getLength() { + return length; + } + + @Override + public String getGenre() { + return genre; + } + + @Override + public void unloadAlbumCover() { + if (albumCover != null) { + albumCover.dispose(); + albumCover = null; + } + } + + @Override + public Texture getAlbumCover() { + if (pixmap != null && albumCover == null) { + albumCover = new Texture(pixmap); + pixmap.dispose(); + pixmap = null; + } + return albumCover; + } + + @Override + public FileHandle getFileHandle() { + return fileHandle; + } + + @Override + public void dispose() { + unloadAlbumCover(); + } + + +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/metadata/WAVMetadata.java b/old/core/src/zero1hd/rhythmbullet/audio/metadata/WAVMetadata.java new file mode 100644 index 0000000..ce6afb0 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/metadata/WAVMetadata.java @@ -0,0 +1,114 @@ +package zero1hd.rhythmbullet.audio.metadata; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.jaudiotagger.audio.AudioFile; +import org.jaudiotagger.audio.AudioFileIO; +import org.jaudiotagger.audio.exceptions.CannotReadException; +import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException; +import org.jaudiotagger.audio.exceptions.ReadOnlyFileException; +import org.jaudiotagger.tag.FieldKey; +import org.jaudiotagger.tag.Tag; +import org.jaudiotagger.tag.TagException; +import org.jaudiotagger.tag.images.Artwork; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; + +public class WAVMetadata implements AudioMetadata { + private String title, author, duration, genre; + private int length; + private Texture albumCover; + private FileHandle fileHandle; + private Pixmap pixmap; + + public WAVMetadata(FileHandle fileHandle) { + this.fileHandle = fileHandle; + + try { + AudioFile wav = AudioFileIO.read(fileHandle.file()); + length = wav.getAudioHeader().getTrackLength(); + SimpleDateFormat f = new SimpleDateFormat("m:ss"); + duration = f.format(new Date(length*1000)); + + Tag tag = wav.getTag(); + title = tag.getFirst(FieldKey.TITLE); + author = tag.getFirst(FieldKey.ARTIST); + genre = tag.getFirst(FieldKey.GENRE); + if (title.isEmpty()) { + title = fileHandle.nameWithoutExtension().replace('_', ' '); + } + } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { + Gdx.app.error("WAVMetadata", "Failed to read metadata of file: " + fileHandle.name()); + } + } + + @Override + public void loadAlbumCover() { + if (pixmap == null) { + try { + AudioFile wav = AudioFileIO.read(fileHandle.file()); + Artwork art = wav.getTag().getFirstArtwork(); + + if (art != null) { + byte[] imageData = art.getBinaryData(); + pixmap = new Pixmap(imageData, 0, imageData.length); + } + } catch (CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) { + e.printStackTrace(); + } + } + } + @Override + public void unloadAlbumCover() { + if (albumCover != null) { + albumCover.dispose(); + albumCover = null; + } + } + @Override + public String getAuthor() { + return author; + } + @Override + public String getTitle() { + return title; + } + @Override + public String getDuration() { + return duration; + } + + @Override + public int getLength() { + return length; + } + + @Override + public Texture getAlbumCover() { + if (pixmap != null && albumCover == null) { + albumCover = new Texture(pixmap); + pixmap.dispose(); + pixmap = null; + } + return albumCover; + } + @Override + public String getGenre() { + return genre; + } + @Override + public FileHandle getFileHandle() { + return fileHandle; + } + @Override + public void dispose() { + unloadAlbumCover(); + } + + +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/processor/AudioProcessor.java b/old/core/src/zero1hd/rhythmbullet/audio/processor/AudioProcessor.java new file mode 100644 index 0000000..6496443 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/processor/AudioProcessor.java @@ -0,0 +1,44 @@ +package zero1hd.rhythmbullet.audio.processor; + +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Disposable; + +public interface AudioProcessor extends Disposable { + /** + * @return number of channels + */ + public boolean isStereo(); + + /** + * @return sample rate + */ + public int getSampleRate(); + + /** + * Reads samples with interwoven data for stereo. + * stored in 16 bit format (first 8 are the first byte of data while the second 8 are the second byte of data that composes a short value) + * @param pcm the array the samples should fill + * @return the amount of samples read. + */ + public int readSamples(short[] pcm); + + /** + * Reads frames with interwoven data for stereo. + * stored in 16 bit format (first 8 are the first byte of data while the second 8 are the second byte of data that composes a short value) + * @param pcm the array the samples should fill + * @return the amount of samples read. + */ + public int readFrames(float[] pcm); + + /** + * + * @return The music file's {@link FileHandle} + */ + public FileHandle getMusicFileHandle(); + + /** + * + * @return the number of sample frames in the song. + */ + public long getSampleFrames(); +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/processor/WAVAudioProcessor.java b/old/core/src/zero1hd/rhythmbullet/audio/processor/WAVAudioProcessor.java new file mode 100644 index 0000000..8f175ef --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/processor/WAVAudioProcessor.java @@ -0,0 +1,108 @@ +package zero1hd.rhythmbullet.audio.processor; + +import java.io.IOException; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.UnsupportedAudioFileException; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +public class WAVAudioProcessor implements AudioProcessor { + private boolean stereo; + private int sampleRate; + private byte[] buffer; + private FileHandle fileHandle; + private AudioInputStream audioInputStream; + private long sampleFrames; + + public WAVAudioProcessor(FileHandle fileHandle) { + this.fileHandle = fileHandle; + AudioFormat format; + try { + audioInputStream = AudioSystem.getAudioInputStream(fileHandle.file()); + format = audioInputStream.getFormat(); + stereo = format.getChannels() > 1 ? true : false; + sampleRate = (int) format.getSampleRate(); + sampleFrames = audioInputStream.getFrameLength(); + } catch (UnsupportedAudioFileException | IOException e) { + Gdx.app.debug("WAVAudioProcessor", "Couldn't instantiate WAVAUdioProcessor due to error."); + e.printStackTrace(); + } + buffer = new byte[audioInputStream.getFormat().getFrameSize()]; + + } + + public boolean isStereo() { + return stereo; + } + + public int getSampleRate() { + return sampleRate; + } + + @Override + public int readSamples(short[] pcm) { + int framesRead = 0; + for (int sampleID = 0; sampleID < pcm.length; sampleID++) { + try { + if (audioInputStream.read(buffer) > 0) { + pcm[sampleID] = (short) ((buffer[1] << 8) + (buffer[0] & 0x00ff)); + if (stereo) { + short secondChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff)); + sampleID++; + pcm[sampleID] = secondChan; + } + framesRead++; + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + return framesRead; + } + + @Override + public int readFrames(float[] pcm) { + int framesRead = 0; + for (int sampleID = 0; sampleID < pcm.length; sampleID++) { + try { + if (audioInputStream.read(buffer) > 0) { + pcm[sampleID] = (short) ((buffer[1] << 8) + (buffer[0] & 0x00ff)); + if (stereo) { + short secondChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff)); + pcm[sampleID] = secondChan > pcm[sampleID] ? secondChan : pcm[sampleID]; + } + framesRead++; + pcm[sampleID] /= Short.MAX_VALUE+1; + } + } catch (IOException e) { + e.printStackTrace(); + } + + } + return framesRead; + } + + @Override + public FileHandle getMusicFileHandle() { + return fileHandle; + } + + @Override + public long getSampleFrames() { + return sampleFrames; + } + + @Override + public void dispose() { + try { + audioInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/old/core/src/zero1hd/rhythmbullet/audio/visualizer/CircularVisualizer.java b/old/core/src/zero1hd/rhythmbullet/audio/visualizer/CircularVisualizer.java new file mode 100644 index 0000000..38f9bcb --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/visualizer/CircularVisualizer.java @@ -0,0 +1,235 @@ +package zero1hd.rhythmbullet.audio.visualizer; + +import java.util.Comparator; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Mesh; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.VertexAttribute; +import com.badlogic.gdx.graphics.VertexAttributes.Usage; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.Disposable; + +import zero1hd.rhythmbullet.RhythmBullet; + +public class CircularVisualizer implements Disposable { + private PCMSystem pcm; + private int centerX, centerY; + private int r; + private int componentCount = 2 + 1; + private Array circlePoints; + private float[] vertComponents; + private float color; + private Mesh mesh; + private ShaderProgram shader; + private int barCount = 180; + private float barHeightMultiplier = 1.5f; + private float[] audioSpectrum; + private Camera camera; + + public CircularVisualizer(PCMSystem PCMSystem) { + this.pcm = PCMSystem; + shader = new ShaderProgram(Gdx.files.internal("shaders/mesh.vsh"), Gdx.files.internal("shaders/mesh.fsh")); + if (!shader.isCompiled() || shader.getLog().length() != 0) { + Gdx.app.debug("Circular visualizer shader", shader.getLog()); + Gdx.app.exit(); + } + r = RhythmBullet.pixels_per_unit*RhythmBullet.SPAWN_CIRCLE_RADIUS; + } + + /** + * Only should be called when all changes have been done. + */ + public void applyPositionChanges() { + circlePoints = new Array<>(); + createCircleVertices(r); + vertComponents = new float[circlePoints.size * componentCount]; + + if (mesh != null) { + mesh.dispose(); + } + mesh = new Mesh(true, circlePoints.size, 0, new VertexAttribute(Usage.Position, 2, "a_position"), new VertexAttribute(Usage.ColorPacked, 4, "a_color")); + } + + public void setCenter(int x, int y) { + this.centerX = x; + this.centerY = y; + } + + public void drawVisualizer() { + for (int circlePointIndex = 0; circlePointIndex < circlePoints.size; circlePointIndex++) { + for (int comp = 0; comp < componentCount; comp++) { + if (comp != 2) { + vertComponents[circlePointIndex*componentCount + comp] = circlePoints.get(circlePointIndex).x + centerX; + comp++; + vertComponents[circlePointIndex*componentCount + comp] = circlePoints.get(circlePointIndex).y + centerY; + } else { + vertComponents[circlePointIndex*componentCount + comp] = color; + } + } + } + + flush(); + } + + private void flush() { + mesh.setVertices(vertComponents); + Gdx.gl.glDepthMask(false); + Gdx.gl.glEnable(GL20.GL_BLEND); + Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); + + int vertexCount = circlePoints.size; + ((OrthographicCamera) camera).setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + + shader.begin(); + mesh.render(shader, GL20.GL_LINE_STRIP, 0, vertexCount); + shader.end(); + + Gdx.gl.glDepthMask(true); + } + + private void createCircleVertices(int radius) { + int x = radius - 1; + int y = 0; + int dx = 1; + int dy = 1; + int err = dx - (radius << 1); + circlePoints.clear(); + + while (x >= y) { + circlePoints.add(new Vector2(+ x, + y)); + circlePoints.add(new Vector2(+ y, + x)); + circlePoints.add(new Vector2(- y, + x)); + circlePoints.add(new Vector2(- x, + y)); + circlePoints.add(new Vector2(- x, - y)); + circlePoints.add(new Vector2(- y, - x)); + circlePoints.add(new Vector2(+ y, - x)); + circlePoints.add(new Vector2(+ x, - y)); + + if (err <= 0) { + y++; + err += dy; + dy += 2; + } else { + x--; + dx += 2; + err += dx - (radius << 1); + } + } + + circlePoints.sort(new Comparator() { + @Override + public int compare(Vector2 o1, Vector2 o2) { + double deg1; + if (o1.x != 0 || o1.y != 0) { + deg1 = Math.atan(Math.abs(o1.y)/Math.abs(o1.x)); + if (o1.x < 0) { + if (o1.y < 0) { + deg1 += 180; + } else { + deg1 = 180 - deg1; + } + } else { + if (o1.y < 0) { + deg1 = 360 - deg1; + } + } + + } else { + if (o1.x != 0) { + if (o1.x > 0) { + deg1 = 0; + } else { + deg1 = 180; + } + deg1 = 0; + } else { + if (o1.y > 0) { + deg1 = 90; + } else { + deg1 = 270; + } + } + } + + double deg2; + if (o2.x != 0 || o2.y != 0) { + deg2 = Math.atan(Math.abs(o2.y)/Math.abs(o2.x)); + if (o2.x < 0) { + if (o2.y < 0) { + deg2 += 180; + } else { + deg2 = 180 - deg2; + } + } else { + if (o2.y < 0) { + deg2 = 360 - deg2; + } + } + } else { + if (o2.x != 0) { + if (o2.x > 0) { + deg2 = 0; + } else { + deg2 = 180; + } + deg2 = 0; + } else { + if (o2.y > 0) { + deg2 = 90; + } else { + deg2 = 270; + } + } + } + + if ((deg1 - deg2) > 0) { + return 1; + } else if (deg1 - deg2 == 0) { + return 0; + } else { + return -1; + } + + } + }); + } + + public void setColor(float color) { + this.color = color; + } + + @Override + public void dispose() { + mesh.dispose(); + shader.dispose(); + } + + /** + * set the maximum radius + * @param r + */ + public void setR(int r) { + this.r = r; + } + + /** + * get the maximum radius + * @return + */ + public int getR() { + return r; + } + + public void setCamera(Camera camera) { + this.camera = camera; + } + + public Camera getCamera() { + return camera; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/visualizer/DoubleHorizontalVisualizer.java b/old/core/src/zero1hd/rhythmbullet/audio/visualizer/DoubleHorizontalVisualizer.java new file mode 100644 index 0000000..cd02d9d --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/visualizer/DoubleHorizontalVisualizer.java @@ -0,0 +1,212 @@ +package zero1hd.rhythmbullet.audio.visualizer; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.utils.Disposable; + +import zero1hd.rhythmbullet.audio.MusicController; + +public class DoubleHorizontalVisualizer implements Disposable { + private int width, height, barWidth, spaceBetweenBars; + private int x, y; + private ShapeRenderer shapeRenderer; + private PCMSystem pcm; + private float[] amplitudes; + private int[] barHeights; + private int binsPerBar; + private float offset; + private int boundaryThickness; + private boolean debug = false; + private boolean significantBeat; + private float maxAverageAmplitude; + private byte significantFrames; + private byte requiredSignificantFrames; + private float targetDelta; + private float significantThreshold = 0.5f; + private float spacePercentage = 0.7f; + private float baseSensitivity = 0.009f; + private int barCount = 120; + private float barChangeRate = 6.5f; + private int smoothRange = 2; + private int binsToInclude = 120; + private Color color = new Color(0.5f, 0.6f, 0.8f, 0.46f); + private int averageAmplitude; + + /** + * + * @param barCount amount of bars this visualizer should have. + * @param width the width of the visualizer. + * @param spacePercentage the percentage of a bar that should be space. + */ + public DoubleHorizontalVisualizer(int width, int height, float heightSensitivity, int boundaryThickness, int targetFPS, MusicController musicController, PCMSystem PCMSystem) { + this.barWidth = width/barCount; + this.spaceBetweenBars = MathUtils.round(barWidth * spacePercentage); + this.barWidth -= spaceBetweenBars; + this.baseSensitivity *= heightSensitivity; + pcm = PCMSystem; + binsPerBar = (binsToInclude/barCount); + this.width = width; + this.height = height; + amplitudes = new float[barCount]; + barHeights = new int[barCount]; + shapeRenderer = new ShapeRenderer(); + boundaryThickness = barWidth; + offset = (width - (barCount*(barWidth+spaceBetweenBars)-spaceBetweenBars))/2f + x; + this.targetDelta = 1f/targetFPS; + } + + public void act(float delta) { + if (pcm.hasAudioChanged()) { + maxAverageAmplitude = 0; + averageAmplitude = 0; + significantBeat = false; + } + float[] freqBins = pcm.getFrequencyBins(); + averageAmplitude = 0; + for (int bar = 0; bar < amplitudes.length; bar++) { + amplitudes[bar] = 0; + for (int freq = bar*binsPerBar; freq < (bar*binsPerBar) + binsPerBar; freq++) { + amplitudes[bar] += Math.abs(freqBins[freq]) * baseSensitivity; + } + amplitudes[bar] /= binsPerBar; + + averageAmplitude += amplitudes[bar]; + } + + averageAmplitude /= amplitudes.length; + if (averageAmplitude > maxAverageAmplitude) { + maxAverageAmplitude = averageAmplitude; + } + if (averageAmplitude > maxAverageAmplitude*significantThreshold && !significantBeat) { + if (maxAverageAmplitude > 0) { + significantFrames++; + if (significantFrames >= requiredSignificantFrames) { + significantFrames = 0; + significantBeat = true; + } + } + } else { + if (significantBeat) { + significantBeat = false; + requiredSignificantFrames = 16; + } else { + requiredSignificantFrames = 4; + } + significantFrames = 0; + } + + for (int bar = 0; bar < barHeights.length; bar++) { + int smoothCount = 1; + for (int range = 0; range < smoothRange; range++) { + if (bar+range < amplitudes.length) { + amplitudes[bar] += amplitudes[bar+range]; + smoothCount++; + } + if (bar-range > 0) { + amplitudes[bar] += amplitudes[bar-range]; + smoothCount++; + } + } + amplitudes[bar] /= smoothCount; + + + int pixelsMoved = 0; + int difference = MathUtils.round(amplitudes[bar] - barHeights[bar]); + pixelsMoved = MathUtils.floor(difference*targetDelta*barChangeRate); + if (pixelsMoved >= 0) { + if (barHeights[bar] + pixelsMoved > amplitudes[bar]) { + barHeights[bar] += MathUtils.round(difference*targetDelta); + } else { + barHeights[bar] += pixelsMoved; + } + } else { + if (barHeights[bar] + pixelsMoved < amplitudes[bar]) { + barHeights[bar] += MathUtils.round(difference*targetDelta); + } else { + barHeights[bar] += pixelsMoved; + } + } + + } + } + + public void draw(Batch batch, float parentAlpha) { + batch.end(); + Gdx.gl.glEnable(GL20.GL_BLEND); + shapeRenderer.begin(ShapeType.Filled); + shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix()); + shapeRenderer.setTransformMatrix(batch.getTransformMatrix()); + if (boundaryThickness > 0) { + shapeRenderer.rect(x, y, width, boundaryThickness); + shapeRenderer.rect(x, y+height, width, -boundaryThickness); + } + + for (int bar = 0; bar < barCount; bar++) { + shapeRenderer.setColor(color); + shapeRenderer.rect(offset + (spaceBetweenBars+barWidth)*bar, y+height, barWidth, barHeights[bar]); + shapeRenderer.rect(offset + (spaceBetweenBars+barWidth)*bar, y, barWidth, -barHeights[barHeights.length - 1 - bar]); + } + if (debug) { + shapeRenderer.setColor(Color.RED); + shapeRenderer.rect(0, maxAverageAmplitude+y, width, 1); + if (significantBeat) { + shapeRenderer.setColor(Color.GREEN); + } else { + shapeRenderer.setColor(Color.WHITE); + } + shapeRenderer.rect(0, averageAmplitude+y, width, 1); + shapeRenderer.setColor(Color.YELLOW); + shapeRenderer.rect(0, maxAverageAmplitude*significantThreshold + y, width, 1); + } + shapeRenderer.end(); + Gdx.gl.glDisable(GL20.GL_BLEND); + batch.begin(); + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public void setX(int x) { + this.x = x; + } + + public void setY(int y) { + this.y = y; + } + + public void setPosition(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public boolean isSignificantBeat() { + return significantBeat; + } + + public void updateMusic() { + pcm.loadMusic(); + } + + @Override + public void dispose() { + pcm.dispose(); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/audio/visualizer/PCMSystem.java b/old/core/src/zero1hd/rhythmbullet/audio/visualizer/PCMSystem.java new file mode 100644 index 0000000..8a2e092 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/visualizer/PCMSystem.java @@ -0,0 +1,14 @@ +package zero1hd.rhythmbullet.audio.visualizer; + +import com.badlogic.gdx.utils.Disposable; + +public interface PCMSystem extends Disposable { + + float[] getFrequencyBins(); + + int getWindowSize(); + + void loadMusic(); + + boolean hasAudioChanged(); +} \ No newline at end of file diff --git a/old/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WAVSampleReader.java b/old/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WAVSampleReader.java new file mode 100644 index 0000000..708d738 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/audio/wavedecoder/WAVSampleReader.java @@ -0,0 +1,68 @@ +package zero1hd.rhythmbullet.audio.wavedecoder; + +import java.io.IOException; + +import javax.sound.sampled.AudioInputStream; + +public class WAVSampleReader { + private int channels; + private double sampleRate; + private byte[] buffer; + private AudioInputStream audioInputStream; + private boolean mergeChannels; + + public WAVSampleReader(AudioInputStream ais) throws IOException { + audioInputStream = ais; + buffer = new byte[audioInputStream.getFormat().getFrameSize()]; + + channels = audioInputStream.getFormat().getChannels(); + sampleRate = audioInputStream.getFormat().getSampleRate(); + } + + public int getChannels() { + return channels; + } + + public double getSampleRate() { + return sampleRate; + } + + public long getFrameLength() { + return audioInputStream.getFrameLength(); + } + + public int readSamplesAsFrames(float[] samples) throws IOException { + int framesRead = 0; + for (int sampleID = 0; sampleID < samples.length; sampleID++) { + if (audioInputStream.read(buffer) > 0) { + samples[sampleID] += (buffer[1] << 8) + (buffer[0] & 0x00ff); + if (audioInputStream.getFormat().getChannels() > 1) { + short altChan = (short) ((buffer[3] << 8) + (buffer[2] & 0x00ff)); + if (mergeChannels) { + samples[sampleID] = altChan > samples[sampleID] ? altChan : samples[sampleID]; + } else { + sampleID++; + samples[sampleID] = altChan; + } + } + framesRead ++; + samples[sampleID] /= Short.MAX_VALUE+1; + } + + } + return framesRead; + } + + public AudioInputStream getAudioInputStream() { + return audioInputStream; + } + + + public void setMergeChannels(boolean mergeChannels) { + this.mergeChannels = mergeChannels; + } + public boolean isMergeChannels() { + return mergeChannels; + } + +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/CollisionDetector.java b/old/core/src/zero1hd/rhythmbullet/entity/CollisionDetector.java new file mode 100644 index 0000000..8c13551 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/CollisionDetector.java @@ -0,0 +1,56 @@ +package zero1hd.rhythmbullet.entity; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.utils.Array; + +public class CollisionDetector { + Array enemies; + Array allies; + + AssetManager assets; + Preferences prefs; + + private int amassedPoints; + Sound explosionSFX; + public CollisionDetector(Array enemies, Array allies, AssetManager assetManager, Preferences prefs) { + this.enemies = enemies; + this.allies = allies; + assets = assetManager; + this.prefs = prefs; + + } + + public void collisionCheck() { + if ((enemies.size != 0) && (allies.size != 0)) { + for (int f = 0; f < enemies.size; f++) { + Entity enemy = enemies.get(f); + if (enemy.getHitZone() != null) { + for (int s = 0; s < allies.size; s++) { + Entity ally = allies.get(s); + if (ally.getHitZone() != null) { + if (enemy.getHitZone().overlaps(ally.getHitZone())) { + Gdx.app.debug("Collision Detector", "Collision between entities: " + enemy.getClass().getSimpleName() + " and " + ally.getClass().getSimpleName()); + + enemy.collided(ally); + ally.collided(enemy); + + amassedPoints += enemy.getPoints(); + break; + } + } + } + } + } + } + } + + + public int getAmassedPoints() { + int amassedPoints = this.amassedPoints; + this.amassedPoints = 0; + return amassedPoints; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/Entity.java b/old/core/src/zero1hd/rhythmbullet/entity/Entity.java new file mode 100644 index 0000000..28d8785 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/Entity.java @@ -0,0 +1,201 @@ +package zero1hd.rhythmbullet.entity; + +import java.security.InvalidParameterException; + +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Pool.Poolable; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.entity.coordinator.Coordinator; + +public class Entity implements Poolable { + private Coordinator coordinator; + private EntityFrame ef; + + protected AssetManager assets; + protected Preferences prefs; + protected EntityManager ec; + + protected boolean enemy; + protected boolean move = true; + + protected boolean dead; + protected Rectangle hitbox; + protected Sprite sprite; + protected Vector2 rotRatios; + public float angle; + public float speed; + protected float hitBoxScale; + + protected int points; + + /** + * called by the entity frame and only once (when this object is created). + * Used by the frame to setup variables for simple calling later. + * Anything that needs to be setup for the entity on first call should not override this. + * (Unless you call the super of this and then the rest which is fine too). + * This will then call preInit() which is the method you should override. + */ + protected void setup(EntityManager ec, EntityFrame ef) { + this.ec = ec; + this.ef = ef; + assets = ec.getAssets(); + prefs = ec.getPrefs(); + rotRatios = new Vector2(); + hitbox = new Rectangle(); + + preInit(); + } + + /** + * Method to override should any setup need to be done once (on entity first creation). + */ + public void preInit() { + if (sprite.getTexture() == null) throw new NullPointerException("what, your not going to have a texture for your entity?"); + sprite.setOriginCenter(); + } + + public void init(float deg, float speed, int hp) { + rotRatios.set(MathUtils.cosDeg(angle), MathUtils.sinDeg(angle)); + sprite.setSize(sprite.getTexture().getWidth()/RhythmBullet.pixels_per_unit, sprite.getTexture().getHeight()/RhythmBullet.pixels_per_unit); + float r = RhythmBullet.SPAWN_CIRCLE_RADIUS - sprite.getWidth(); + if (r < RhythmBullet.SPAWN_CIRCLE_RADIUS -1) { + throw new InvalidParameterException("Entity is too big! Calculated final distance from center: " + r); + } + sprite.setPosition(r*rotRatios.x, r*rotRatios.y); + updatePosition(); + } + + /** + * Called whenever a collision is detected + * @param entity is the entity that hit this one. + */ + public void collided(Entity entity) { + } + + /** + * gets the box that represents the hit box to calculate whether there is a collision or not + * @return the object that represents the hit box + */ + public Rectangle getHitZone() { + return hitbox; + } + + public boolean isDead() { + return dead; + } + + public void calculate(float delta) { + if (coordinator != null) { + coordinator.coordinate(delta); + } + + if (dead) { + ef.recycleEntity(this); + } + + if (angle >= 360f) { + angle -= 360f; + } + + if (sprite.getX() > RhythmBullet.WORLD_WIDTH || sprite.getY() > RhythmBullet.WORLD_HEIGHT || sprite.getX() < 0-sprite.getWidth() || sprite.getX() < 0-sprite.getWidth()) { + dead = true; + } + + updatePosition(); + } + + public void draw(Batch batch) { + sprite.draw(batch); + batch.setColor(Color.WHITE); + } + + public void moveBy(float x, float y) { + sprite.setCenter(sprite.getX() + x, sprite.getY() + y); + } + + public void updatePosition() { + rotRatios.set(MathUtils.cosDeg(angle), MathUtils.sinDeg(angle)); + sprite.setOriginCenter(); + sprite.setRotation(angle); + hitbox.setCenter(sprite.getOriginX(), sprite.getOriginY()); + } + + @Override + public void reset() { + if (coordinator != null) { + coordinator.clean(); + coordinator = null; + } + rotRatios.set(0, 0); + sprite.setPosition(0, 0); + hitbox.set(0, 0, 0, 0); + sprite.setRotation(0); + sprite.setColor(Color.WHITE); + angle = 0; + speed = 0; + points = 0; + dead = false; + } + + public float getAngle() { + return angle; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + public float getSpeed() { + return speed; + } + + public void setCoordinator(Coordinator coordinator) { + this.coordinator = coordinator; + coordinator.setEntity(this); + } + + public void kill() { + dead = true; + } + + public int getPoints() { + return points + (coordinator != null ? coordinator.getScoreBonus() : 0); + } + + public float getX() { + return sprite.getX(); + } + + public float getY() { + return sprite.getY(); + } + + public void setPosition(float x, float y) { + sprite.setPosition(x, y); + updatePosition(); + } + + public float getWidth() { + return sprite.getWidth(); + } + + public float getHeight() { + return sprite.getHeight(); + } + + public void setSize(float width, float height) { + sprite.setSize(width, height); + } + + public void setHitboxScale(float scale) { + hitbox.setSize(sprite.getWidth()*scale, sprite.getHeight()*scale); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/EntityFrame.java b/old/core/src/zero1hd/rhythmbullet/entity/EntityFrame.java new file mode 100644 index 0000000..91bfc3a --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/EntityFrame.java @@ -0,0 +1,66 @@ +package zero1hd.rhythmbullet.entity; + +import com.badlogic.gdx.utils.Pool; + +public class EntityFrame { + private Pool pool; + private EntityManager ec; + Class ct; + EntityFrame ef; + + /** + * Manages the entities pooling. + * @param entityController + * @param classType + */ + public EntityFrame(EntityManager entityController, Class classType) { + this.ct = classType; + ef = this; + ec = entityController; + pool = new Pool() { + @Override + protected T newObject() { + try { + T entity = ct.newInstance(); + entity.setup(ec, ef); + + return entity; + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + return null; + + } + } + }; + } + + public T buildEntity() { + T entity = pool.obtain(); + + if (entity.enemy) { + ec.activeEnemies.add(entity); + } else { + ec.activeAllies.add(entity); + } + return entity; + } + + + /** + * Free the entity if no longer used. + * @param entity to be freed. + */ + protected void recycleEntity(Entity entity) { + if (entity.enemy) { + ec.activeEnemies.removeValue(entity, true); + } else { + ec.activeAllies.removeValue(entity, true); + } + pool.free(ct.cast(entity)); + } + + @Override + public String toString() { + return ct.getSimpleName(); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/EntityManager.java b/old/core/src/zero1hd/rhythmbullet/entity/EntityManager.java new file mode 100644 index 0000000..fc82563 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/EntityManager.java @@ -0,0 +1,46 @@ +package zero1hd.rhythmbullet.entity; + +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.utils.Array; + +import zero1hd.rhythmbullet.entity.ally.Laser; +import zero1hd.rhythmbullet.entity.enemies.Pellet; +import zero1hd.rhythmbullet.entity.enemies.Shard; + +public class EntityManager { + private AssetManager assets; + private Preferences prefs; + + public Array activeAllies; + public Array activeEnemies; + + public EntityFrame pellet; + public EntityFrame shard; + + public EntityFrame laser; + + public EntityManager(AssetManager assetManager, Preferences preferences) { + activeAllies = new Array(); + activeEnemies = new Array(); + this.assets = assetManager; + this.prefs = preferences; + + setup(); + } + + private void setup() { + pellet = new EntityFrame<>(this, Pellet.class); + shard = new EntityFrame<>(this, Shard.class); + laser = new EntityFrame<>(this, Laser.class); + + } + + public AssetManager getAssets() { + return assets; + } + + public Preferences getPrefs() { + return prefs; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/ally/Laser.java b/old/core/src/zero1hd/rhythmbullet/entity/ally/Laser.java new file mode 100644 index 0000000..3982954 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/ally/Laser.java @@ -0,0 +1,52 @@ +package zero1hd.rhythmbullet.entity.ally; + +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.Sprite; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.entity.Entity; + +public class Laser extends Entity { + Sound sfx; + + @Override + public void preInit() { + sprite = new Sprite(assets.get("laser.png", Texture.class)); + sfx = assets.get("laser.ogg", Sound.class); + setSize(0.25f, 2f); + super.preInit(); + } + + public void init(float x, float y, float rate) { + setPosition(x-getWidth()/2f, y-getHeight()/2f); + speed = rate; + sfx.play(prefs.getFloat("fx vol")/100f); + angle = 90f; + } + + @Override + public void calculate(float delta) { + if (getY() > RhythmBullet.WORLD_HEIGHT) { + dead = true; + } + super.calculate(delta); + } + + @Override + public void draw(Batch batch) { + super.draw(batch); + } + + @Override + public void reset() { + super.reset(); + } + + @Override + public void collided(Entity entity) { + dead = true; + } + +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/ally/PolyjetEntity.java b/old/core/src/zero1hd/rhythmbullet/entity/ally/PolyjetEntity.java new file mode 100644 index 0000000..4e80252 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/ally/PolyjetEntity.java @@ -0,0 +1,95 @@ +package zero1hd.rhythmbullet.entity.ally; + +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.ParticleEffect; +import com.badlogic.gdx.math.Rectangle; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.entity.Entity; + +public class PolyjetEntity extends Entity { + public float health; + private ParticleEffect thrust; + private Texture polyjet; + private ParticleEffect teleportCloak; + public boolean moveLeft, moveRight, moveUp, moveDown, teleporting, accelerate; + private float speed, accel; + private float rate; + private int maxH; + public PolyjetEntity(AssetManager assets, float speed, float accel,int maxHealth, String jet) { + health = 100; + this.speed = speed; + this.accel = accel; + setSize(1.5f, 1.5f); + setPosition(RhythmBullet.WORLD_WIDTH/2 - getWidth()/2, -4f); + maxH = maxHealth; + hitbox = new Rectangle(getX(), getY(), getWidth(), getHeight()); + polyjet = assets.get("polyjet-" + jet + ".png", Texture.class); + thrust = assets.get("standard_thrust.p", ParticleEffect.class); + thrust.start(); + + teleportCloak = assets.get("teleport-cloak.p", ParticleEffect.class); + + } + + @Override + public void calculate(float delta) { + hitbox.setPosition(getX(), getY()); + + thrust.setPosition(getX()+(getWidth())/2 - 1f/16f, getY()-0.2f); + thrust.update(delta); + teleportCloak.setPosition(getX() +(getWidth()-1)/2, getY() + (getHeight()-1)/2); + + hitbox.setPosition(getX(), getY()); + + //Movement! + if (accelerate) { + rate = speed + accel; + } else { + rate = speed; + } + + if (moveLeft && !moveRight) { + moveBy(-(rate*delta), 0); + } + if (moveRight && !moveLeft) { + moveBy(rate*delta, 0); + } + if (moveUp && !moveDown) { + moveBy(0, rate*delta); + } + + if (moveDown && !moveUp) { + moveBy(0, -rate*delta); + } + + if (health <= 0) { + dead = true; + } else if (health > maxH) { + health = maxH; + } + + super.calculate(delta); + } + + @Override + public void draw(Batch batch) { + thrust.draw(batch); + batch.draw(polyjet, getX(), getY(), getWidth(), getHeight()); + super.draw(batch); + } + + @Override + public void collided(Entity entity) { + } + + public Rectangle getHitbox() { + return hitbox; + } + + public void setHealth(float health) { + this.health = health; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/coordinator/Coordinator.java b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/Coordinator.java new file mode 100644 index 0000000..f6cbae6 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/Coordinator.java @@ -0,0 +1,47 @@ +package zero1hd.rhythmbullet.entity.coordinator; + +import com.badlogic.gdx.utils.Pool.Poolable; + +import zero1hd.rhythmbullet.entity.Entity; +import zero1hd.rhythmbullet.entity.EntityManager; + +/** + * Coordinator coordinates movement of an entity. Movement can range from basic pre-determined to more advanced (with condition based behavior). + * @author Yunyang + * + */ +public class Coordinator implements Poolable { + private CoordinatorFrame cf; + protected EntityManager em; + protected Entity entity; + protected int scoreBonus; + + public void setup(EntityManager em, CoordinatorFrame cf) { + this.em = em; + this.cf = cf; + } + + public void init(Entity entity) { + this.entity = entity; + } + + public void coordinate(float delta) { + } + + public void clean() { + cf.recycleCoordinator(this); + } + + public void setEntity(Entity entity) { + this.entity = entity; + } + + @Override + public void reset() { + entity = null; + } + + public int getScoreBonus() { + return scoreBonus; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/coordinator/CoordinatorFrame.java b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/CoordinatorFrame.java new file mode 100644 index 0000000..b968e13 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/CoordinatorFrame.java @@ -0,0 +1,50 @@ +package zero1hd.rhythmbullet.entity.coordinator; + +import com.badlogic.gdx.utils.Pool; + +import zero1hd.rhythmbullet.entity.EntityManager; + +public class CoordinatorFrame { + private Pool pool; + private EntityManager em; + CoordinatorFrame cf; + Class coordinatorType; + + /** + * Similar to an entityFrame, however this time, for a coordinator. + * @param entityManager + * @param classtype + */ + public CoordinatorFrame(EntityManager entityManager, Class classtype) { + this.em = entityManager; + coordinatorType = classtype; + cf = this; + pool = new Pool() { + @Override + protected T newObject() { + try { + T coordinator = coordinatorType.newInstance(); + coordinator.setup(em, cf); + return coordinator; + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + return null; + } + } + }; + } + + public T buildCoordinator() { + T coordinator = pool.obtain(); + return coordinator; + } + + protected void recycleCoordinator(Coordinator coordinator) { + pool.free(coordinatorType.cast(coordinator)); + } + + @Override + public String toString() { + return coordinatorType.getSimpleName(); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/coordinator/CoordinatorManager.java b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/CoordinatorManager.java new file mode 100644 index 0000000..a4ab439 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/CoordinatorManager.java @@ -0,0 +1,20 @@ +package zero1hd.rhythmbullet.entity.coordinator; + +import zero1hd.rhythmbullet.entity.EntityManager; + +public class CoordinatorManager { + private EntityManager em; + + public CoordinatorFrame slowLeft; + public CoordinatorFrame slowRight; + + public CoordinatorManager(EntityManager em) { + this.em = em; + setup(); + } + + private void setup() { + slowLeft = new CoordinatorFrame<>(em, SlowLeftCoordinator.class); + slowRight = new CoordinatorFrame<>(em, SlowRightCoordinator.class); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/coordinator/SlowLeftCoordinator.java b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/SlowLeftCoordinator.java new file mode 100644 index 0000000..1942e6c --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/SlowLeftCoordinator.java @@ -0,0 +1,9 @@ +package zero1hd.rhythmbullet.entity.coordinator; + +public class SlowLeftCoordinator extends Coordinator { + @Override + public void coordinate(float delta) { + entity.angle -= 32*delta; + super.coordinate(delta); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/coordinator/SlowRightCoordinator.java b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/SlowRightCoordinator.java new file mode 100644 index 0000000..9fae5dd --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/coordinator/SlowRightCoordinator.java @@ -0,0 +1,9 @@ +package zero1hd.rhythmbullet.entity.coordinator; + +public class SlowRightCoordinator extends Coordinator { + @Override + public void coordinate(float delta) { + entity.angle += 32*delta; + super.coordinate(delta); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/enemies/Pellet.java b/old/core/src/zero1hd/rhythmbullet/entity/enemies/Pellet.java new file mode 100644 index 0000000..6e5023e --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/enemies/Pellet.java @@ -0,0 +1,40 @@ +package zero1hd.rhythmbullet.entity.enemies; + +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.utils.Pool.Poolable; + +import zero1hd.rhythmbullet.entity.Entity; + +public class Pellet extends Entity implements Poolable { + + @Override + public void preInit() { + sprite = new Sprite(assets.get("pellet.png", Texture.class)); + enemy = true; + setSize(0.5f, 0.5f); + sprite.setColor(0.5f, 1f, 1f, 0.5f); + super.preInit(); + } + + @Override + public void init(float deg, float speed, int hp) { + this.speed = speed; + this.angle = deg; + super.init(deg, speed, hp); + } + + + @Override + public void collided(Entity entity) { + dead = true; + super.collided(entity); + } + + @Override + public void reset() { + dead = false; + super.reset(); + } + +} diff --git a/old/core/src/zero1hd/rhythmbullet/entity/enemies/Shard.java b/old/core/src/zero1hd/rhythmbullet/entity/enemies/Shard.java new file mode 100644 index 0000000..76e4444 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/entity/enemies/Shard.java @@ -0,0 +1,68 @@ +package zero1hd.rhythmbullet.entity.enemies; + +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.math.Rectangle; + +import zero1hd.rhythmbullet.entity.Entity; +import zero1hd.rhythmbullet.entity.ally.Laser; + +public class Shard extends Entity { + private int hp; + private int maxHp; + + @Override + public void preInit() { + sprite = new Sprite(assets.get("shard.png", Texture.class)); + setSize(2f, 2f); + sprite.setSize(3f, 2f); + enemy = true; + super.preInit(); + } + + @Override + public void init(float deg, float speed, int hp) { + this.speed = speed; + this.hp = hp; + maxHp = hp; + this.angle = deg; + super.init(deg, speed, hp); + } + + @Override + public void reset() { + hp = 0; + maxHp = 0; + super.reset(); + } + + @Override + public void calculate(float delta) { + if (hp <= 0) { + dead = true; + } + super.calculate(delta); + } + + @Override + public void draw(Batch batch) { + sprite.setColor(((float)hp/(float)maxHp), ((float)hp/(float)maxHp), ((float)hp/(float)maxHp), 0.5f); + super.draw(batch); + } + + @Override + public void collided(Entity entity) { + if (entity.getClass() == Laser.class) { + hp --; + } else { + dead = true; + } + } + + @Override + public Rectangle getHitZone() { + return hitbox; + } + +} diff --git a/old/core/src/zero1hd/rhythmbullet/game/EntitySpawnInfo.java b/old/core/src/zero1hd/rhythmbullet/game/EntitySpawnInfo.java new file mode 100644 index 0000000..23a1a5e --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/game/EntitySpawnInfo.java @@ -0,0 +1,28 @@ +package zero1hd.rhythmbullet.game; + +import java.util.HashMap; + +import zero1hd.rhythmbullet.entity.Entity; +import zero1hd.rhythmbullet.entity.EntityFrame; +import zero1hd.rhythmbullet.entity.coordinator.Coordinator; +import zero1hd.rhythmbullet.entity.coordinator.CoordinatorFrame; + +public class EntitySpawnInfo { + private EntityFrame entityToSpawn; + private CoordinatorFrame entityCoordinator; + public HashMap parameters; + + + public EntitySpawnInfo(EntityFrame entityToSpawn, CoordinatorFrame coordinator) { + this.entityToSpawn = entityToSpawn; + parameters = new HashMap<>(); + } + + public EntityFrame getEntityToSpawn() { + return entityToSpawn; + } + + public CoordinatorFrame getEntityCoordinator() { + return entityCoordinator; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/game/MapWindowData.java b/old/core/src/zero1hd/rhythmbullet/game/MapWindowData.java new file mode 100644 index 0000000..9a77b8a --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/game/MapWindowData.java @@ -0,0 +1,18 @@ +package zero1hd.rhythmbullet.game; + +import com.badlogic.gdx.utils.Array; + +public class MapWindowData { + Array entityDatas; + public MapWindowData() { + entityDatas = new Array<>(EntitySpawnInfo.class); + } + + public void addEntity(EntitySpawnInfo entity) { + entityDatas.add(entity); + } + + public EntitySpawnInfo[] getArray() { + return entityDatas.toArray(); + } +} \ No newline at end of file diff --git a/old/core/src/zero1hd/rhythmbullet/game/ScoreManager.java b/old/core/src/zero1hd/rhythmbullet/game/ScoreManager.java new file mode 100644 index 0000000..abbdd97 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/game/ScoreManager.java @@ -0,0 +1,26 @@ +package zero1hd.rhythmbullet.game; + +public class ScoreManager { + private int score; + private boolean different; + + public void setScore(int score) { + this.score = score; + different = true; + } + + public int getScore() { + return score; + } + + public void addScore(int addedScore) { + score += addedScore; + different = true; + } + + public boolean checkDifferent() { + boolean current = different; + different = false; + return current; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/graphics/shaders/BloomShader.java b/old/core/src/zero1hd/rhythmbullet/graphics/shaders/BloomShader.java new file mode 100644 index 0000000..5cf49ea --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/graphics/shaders/BloomShader.java @@ -0,0 +1,153 @@ +package zero1hd.rhythmbullet.graphics.shaders; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Pixmap.Format; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.glutils.FrameBuffer; +import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import com.badlogic.gdx.utils.Disposable; +import com.badlogic.gdx.utils.viewport.ScreenViewport; + +public class BloomShader implements Disposable { + private ShaderProgram gaussianBlurShader; + private ShaderProgram brightFilterShader; + private ShaderProgram combineShader; + private FrameBuffer lightFilterBuffer; + private FrameBuffer normalBuffer; + private FrameBuffer hBlur, vBlur; + private TextureRegion fboRegion; + private Batch screenBatch; + private ScreenViewport screenViewport; + + public BloomShader(Batch batch) { + this.screenBatch = batch; + + Gdx.app.debug("Shader", "Loading glow shaders."); + screenViewport = new ScreenViewport(); + screenViewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + ((OrthographicCamera) screenViewport.getCamera()).setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + + Gdx.app.debug("Shader", "using glow shader"); + brightFilterShader = new ShaderProgram(Gdx.files.internal("shaders/basic.vsh"), Gdx.files.internal("shaders/bright_filter.fsh")); + if (!brightFilterShader.isCompiled()) { + Gdx.app.error("Shader failed to compile bright filter shader", brightFilterShader.getLog()); + System.exit(1); + } + if (brightFilterShader.getLog().length() != 0) { + Gdx.app.error("Shader", brightFilterShader.getLog()); + } + + gaussianBlurShader = new ShaderProgram(Gdx.files.internal("shaders/basic.vsh"), Gdx.files.internal("shaders/gaussian_blur.fsh")); + if (!gaussianBlurShader.isCompiled()) { + Gdx.app.error("Shader failed to compile gaussian blur shader", gaussianBlurShader.getLog()); + System.exit(1); + } + if (gaussianBlurShader.getLog().length() != 0) { + Gdx.app.error("Shader", gaussianBlurShader.getLog()); + } + + combineShader = new ShaderProgram(Gdx.files.internal("shaders/basic.vsh"), Gdx.files.internal("shaders/combine.fsh")); + if (!combineShader.isCompiled()) { + Gdx.app.error("Shader failed to compile combination shader", combineShader.getLog()); + System.exit(1); + } + if (combineShader.getLog().length() != 0) { + Gdx.app.error("Shader", combineShader.getLog()); + } + + lightFilterBuffer = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); + normalBuffer = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); + hBlur = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); + vBlur = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false); + + fboRegion = new TextureRegion(normalBuffer.getColorBufferTexture()); + fboRegion.flip(false, true); + + combineShader.begin(); + combineShader.setUniformi("u_texture1", 1); + combineShader.end(); + + gaussianBlurShader.begin(); + gaussianBlurShader.setUniformf("radius", 1.5f); + gaussianBlurShader.setUniformf("resolution", hBlur.getWidth(), vBlur.getHeight()); + gaussianBlurShader.end(); + + vBlur.getColorBufferTexture().bind(1); + lightFilterBuffer.getColorBufferTexture().bind(2); + Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0); + } + + public void begin() { +// Begin drawing a normal version of screen + normalBuffer.begin(); + Gdx.gl.glClearColor(0f, 0f, 0f, 1f); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + } + + public void end(float width, float height) { + normalBuffer.end(); + +// BEGINNING NORMAL SCREEN RENDER + screenViewport.apply(); + +// Begin light filtering + lightFilterBuffer.begin(); + Gdx.gl.glClearColor(0f, 0f, 0f, 1f); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + fboRegion.setTexture(normalBuffer.getColorBufferTexture()); + screenBatch.setShader(brightFilterShader); + screenBatch.setProjectionMatrix(screenViewport.getCamera().combined); + screenBatch.begin(); //SCREEN BATCH STARTS HERE + screenBatch.draw(fboRegion, 0, 0, width, height); + screenBatch.flush(); + lightFilterBuffer.end(); + +// Horizontal gaussian blur + fboRegion.setTexture(lightFilterBuffer.getColorBufferTexture()); + hBlur.begin(); + screenBatch.setShader(gaussianBlurShader); + gaussianBlurShader.setUniformi("pass", 0); + screenBatch.draw(fboRegion, 0f, 0f, width, height); + screenBatch.flush(); + hBlur.end(); + + +// //Vertical gaussian blur + fboRegion.setTexture(hBlur.getColorBufferTexture()); + vBlur.begin(); + gaussianBlurShader.setUniformi("pass", 1); + screenBatch.draw(fboRegion, 0f, 0f, width, height); + screenBatch.flush(); + vBlur.end(); + + Gdx.gl.glClearColor(0f, 0f, 0f, 1f); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + screenBatch.setShader(combineShader); + fboRegion.setTexture(normalBuffer.getColorBufferTexture()); + screenBatch.draw(fboRegion, 0f, 0f, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + screenBatch.setShader(null); + screenBatch.end(); //STAGE BATCH ENDS HERE + } + + @Override + public void dispose() { + brightFilterShader.dispose(); + combineShader.dispose(); + gaussianBlurShader.dispose(); + normalBuffer.dispose(); + lightFilterBuffer.dispose(); + vBlur.dispose(); + hBlur.dispose(); + + brightFilterShader = null; + combineShader = null; + gaussianBlurShader = null; + normalBuffer = null; + lightFilterBuffer = null; + vBlur = null; + hBlur = null; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/graphics/ui/Page.java b/old/core/src/zero1hd/rhythmbullet/graphics/ui/Page.java new file mode 100644 index 0000000..9f3d13f --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/graphics/ui/Page.java @@ -0,0 +1,74 @@ +package zero1hd.rhythmbullet.graphics.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Group; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.Disposable; +import com.badlogic.gdx.utils.viewport.ScreenViewport; + +public class Page extends Group implements Disposable { + private Label pageTitle; + private int baseXPos, baseYPos; + + public Page(int baseXPos, int baseYPos) { + this.baseXPos = baseXPos; + this.baseYPos = baseYPos; + setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + setTouchable(Touchable.childrenOnly); + setToBasePosition(); + setName(getClass().getSimpleName()); + } + + public Page(int baseXPos, int baseYPos, String titleText, Skin skin) { + this(baseXPos, baseYPos); + pageTitle = new Label(titleText, skin, "large-font", skin.getColor("default")); + pageTitle.setPosition(18f, getHeight()-pageTitle.getHeight()-15f); + addActor(pageTitle); + } + + public float getHeightBelowTitle() { + return pageTitle.getY(); + } + + @Override + public void setStage(Stage stage) { + if (stage == null) { + if (!hasParent()) { + dispose(); + } + } else if (!(stage.getViewport() instanceof ScreenViewport)) { + throw new IllegalArgumentException("Pages are explicitly for GUIs, and thus should have a 1:1 ratio between pixel and texture size for maximum clarity. This means that the stage should be using a ScreenViewport."); + } + super.setStage(stage); + } + + public void setCameraPositionToPage(Vector3 cameraPosition) { + cameraPosition.x = (baseXPos+0.5f) * getWidth(); + cameraPosition.y = (baseYPos+0.5f) * getHeight(); + } + + public void setToBasePosition() { + setPosition(baseXPos*getWidth(), baseYPos*getHeight()); + } + + @Override + public void setParent(Group parent) { + if (parent == null && getStage() == null) { + dispose(); + } + super.setParent(parent); + } + + @Override + public void dispose() { + Gdx.app.debug(getClass().getSimpleName(), "Disposing..."); + } + + public void simpleDebug(String message) { + Gdx.app.debug(getClass().getSimpleName(), message); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/HealthBar.java b/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/HealthBar.java new file mode 100644 index 0000000..b68adba --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/HealthBar.java @@ -0,0 +1,71 @@ +package zero1hd.rhythmbullet.graphics.ui.components; + +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup; + +import zero1hd.rhythmbullet.entity.ally.PolyjetEntity; + +public class HealthBar extends WidgetGroup { + Image empty; + Image filler; + float health; + float maxHealth; + + PolyjetEntity pje; + public HealthBar(Skin skin, float maxHealth) { + super(); + filler = new Image(skin.getPatch("bar-fill")); + addActor(filler); + + empty = new Image(skin.getPatch("bar-empty")); + addActor(empty); + + this.maxHealth = maxHealth; + + } + + public void setPolyjetEntity(PolyjetEntity pje) { + this.pje = pje; + } + + public void setHealth(float health) { + this.health = health; + + filler.addAction(Actions.sizeTo(getWidth(), MathUtils.round((health/maxHealth)*getHeight()), 0.1f));; + } + + @Override + public void act(float delta) { + if (pje != null) { + health = pje.health; + } + super.act(delta); + } + + @Override + public void setSize(float width, float height) { + empty.setSize(width, height); + filler.setSize(width, height); + super.setSize(width, height); + } + + @Override + public void setWidth(float width) { + empty.setWidth(width); + filler.setWidth(width); + super.setWidth(width); + } + + @Override + public void setHeight(float height) { + empty.setHeight(height); + super.setHeight(height); + } + + public float getMaxHealth() { + return maxHealth; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/MusicControls.java b/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/MusicControls.java new file mode 100644 index 0000000..2e7287c --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/MusicControls.java @@ -0,0 +1,81 @@ +package zero1hd.rhythmbullet.graphics.ui.components; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; +import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; + +import zero1hd.rhythmbullet.audio.MusicController; + +public class MusicControls extends HorizontalGroup { + private ImageButton reverse, forward; + private CheckBox shuffle, play; + public MusicControls(Skin skin, final MusicController sc) { + reverse = new ImageButton(skin, "rewind-button"); + reverse.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + sc.previous(); + } + }); + addActor(reverse); + + play = new CheckBox(null, skin, "play-button") { + @Override + public void act(float delta) { + if (sc.hasSongLoaded()) { + play.setChecked(sc.isPlaying()); + } else { + play.setChecked(false); + } + super.act(delta); + } + }; + play.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (play.isChecked()) { + sc.play(); + } else { + sc.pause(); + } + super.clicked(event, x, y); + } + }); + addActor(play); + + forward = new ImageButton(skin, "fast-forward-button"); + forward.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + sc.skip(); + } + }); + addActor(forward); + shuffle = new CheckBox(null, skin, "shuffle-button") { + @Override + public void act(float delta) { + shuffle.setChecked(sc.isShuffle()); + super.act(delta); + } + }; + shuffle.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + if (shuffle.isChecked()) { + sc.setShuffle(true); + } else { + sc.setShuffle(false); + } + } + }); + addActor(shuffle); + space(15); + + setSize(getMinWidth(), getMinHeight()); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/ScrollingText.java b/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/ScrollingText.java new file mode 100644 index 0000000..9111e44 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/graphics/ui/components/ScrollingText.java @@ -0,0 +1,205 @@ +package zero1hd.rhythmbullet.graphics.ui.components; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Widget; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack; + +public class ScrollingText extends Widget { + Rectangle scissors = new Rectangle(); + Rectangle clipBounds = new Rectangle(); + + GlyphLayout gLayout; + String text1; + String text2; + BitmapFont font; + private float textHeight; + private float text1Width; + private float text2Width; + + private boolean dupFirstText; + private boolean scrollOnHover; + private boolean scroll; + + private float text1Offset, text2Offset; + + private NinePatch background; + + private Vector2 coords; + + private float targetDelta; + + public ScrollingText(String text, String text2, Skin skin, boolean scrollOnHover, boolean useBackground, float targetDelta) { + super(); + font = skin.getFont("default-font"); + init(text, text2, skin, scrollOnHover, useBackground); + this.targetDelta = targetDelta; + } + + public ScrollingText(String text, String text2, Skin skin, String fontName, Color color, boolean scrollOnHover, boolean useBackground) { + super(); + font = skin.getFont(fontName); + font.setColor(color); + init(text, text2, skin, scrollOnHover, useBackground); + } + + private void init(String text1, String text2, Skin skin, boolean scrollOnHover, boolean useBackground) { + setName(text1); + if (useBackground) { + this.background = skin.getPatch("side-bars"); + } + + this.scrollOnHover = scrollOnHover; + + coords = new Vector2(); + addListener(new ClickListener() { + @Override + public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { + scroll = true; + super.enter(event, x, y, pointer, fromActor); + } + + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + scroll = false; + super.exit(event, x, y, pointer, toActor); + } + + @Override + public void clicked(InputEvent event, float x, float y) { + } + }); + + setText(text1, text2); + layout(); + } + + public float getFontHeight() { + return textHeight; + } + + public float getFontWidth() { + return text1Width; + } + + @Override + public void layout() { + super.layout(); + + if (getHeight() < (textHeight+4)) { + setHeight(textHeight + 4); + } + clipBounds.setSize(getWidth()-2, getHeight()*1.5f); + + text2Offset = clipBounds.getWidth(); + if (text1Width < clipBounds.getWidth()) { + text1Offset = (clipBounds.getWidth()-text1Width)/2f; + } + } + + public void scroll(float delta) { + if (text1Offset >= -text1Width) { + text1Offset -= 60*targetDelta; + if ((text1Offset < - Math.abs((text1Width - clipBounds.getWidth())) - 50) || text2Offset != clipBounds.getWidth()) { + text2Offset -= 60*targetDelta; + if (text2Offset <= -text2Width) { + text2Offset = clipBounds.getWidth(); + } + } + + } else { + text2Offset -= 60*targetDelta; + if (text2Offset < - Math.abs((text2Width - clipBounds.getWidth())) - 50) { + text1Offset = clipBounds.getWidth(); + } + } + } + + @Override + public void act(float delta) { + clipBounds.setSize(getWidth()-2, getHeight()*1.5f); + if (dupFirstText) { + if (text1Width > clipBounds.getWidth()) { + if (scrollOnHover) { + if (scroll || text1Offset < 0 || text1Offset > 2) { + scroll(delta); + } + } else { + scroll(delta); + } + } + } else { + if (text1Width + text2Width > clipBounds.getWidth()) { + if (scrollOnHover) { + if (scroll || text1Offset < 0 || text1Offset > 2) { + scroll(delta); + } + } else { + scroll(delta); + } + } + } + super.act(delta); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + if (background != null) { + background.draw(batch, getX(), getY(), getWidth(), getHeight()); + } + coords.x = getX(); + coords.y = getY(); + + clipBounds.setX(coords.x+1); + clipBounds.setY(coords.y - 0.5f*getHeight()); + + getStage().calculateScissors(clipBounds, scissors); + batch.flush(); + if (ScissorStack.pushScissors(scissors)) { + font.draw(batch, text1, coords.x + text1Offset, coords.y + getFontHeight() + 4); + font.draw(batch, text2, coords.x + text2Offset, coords.y + getFontHeight() + 4); + batch.flush(); + ScissorStack.popScissors(); + } + + super.draw(batch, parentAlpha); + } + + @Override + public float getMinHeight() { + return textHeight; + } + + /** + * Sets the two strings that will be scrolling. + * @param text1 cannot be null. + * @param text2 can be null. + */ + public void setText(String text1, String text2) { + this.text1 = text1; + gLayout = new GlyphLayout(font, text1); + text1Width = gLayout.width; + textHeight = gLayout.height; + + if (text2 != null) { + this.text2 = text2; + gLayout = new GlyphLayout(font, text2); + text2Width = gLayout.width; + } else { + dupFirstText = true; + this.text2 = text1; + this.text2Width = text1Width; + } + + layout(); + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/util/AssetPack.java b/old/core/src/zero1hd/rhythmbullet/util/AssetPack.java new file mode 100644 index 0000000..815e422 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/util/AssetPack.java @@ -0,0 +1,45 @@ +package zero1hd.rhythmbullet.util; + +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.utils.Disposable; + +public interface AssetPack extends Disposable { + + /** + * Called right after the game instance is created and passed to LWJGL. This method is called once for you to instantiate things for later use but require Libgdx functions. + */ + public void initiate(); + + /** + * Game manager calls this when it needs to load textures. + */ + public void queueTextures(AssetManager assetManager); + + /** + * Game manager calls this when it needs to load sound effects. + */ + public void queueSFX(AssetManager assetManager); + + /** + * Game manager calls this when it needs to load particles. + */ + public void queueParticles(AssetManager assetManager); + + /** + * Game manager calls when it needs to load particles. Usually called after textures are loaded since the skin requires the other assets. + * @param skin the skin object to set up. + */ + public void setupSkin(Skin skin); + + /** + * Game manager calls when it needs the fonts to be generated. Usually called right before setting up the skin itself since items in the skin need fonts. + */ + public void generateFonts(Skin skin); + + /** + * Game manager calls this once all assets are loaded. This function should be used to make some in-code adjustments to assets that will be consistent throughout the game for that run. + * @param assetManager gives you access to the assets to modify. + */ + public void complete(AssetManager assetManager); +} diff --git a/old/core/src/zero1hd/rhythmbullet/util/GenericFileTypeHandler.java b/old/core/src/zero1hd/rhythmbullet/util/GenericFileTypeHandler.java new file mode 100644 index 0000000..0a6ddee --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/util/GenericFileTypeHandler.java @@ -0,0 +1,25 @@ +package zero1hd.rhythmbullet.util; + +import com.badlogic.gdx.assets.loaders.FileHandleResolver; +import com.badlogic.gdx.files.FileHandle; + +public class GenericFileTypeHandler implements FileHandleResolver { + private final FileHandleResolver resolver; + + public GenericFileTypeHandler(FileHandleResolver fileResolver) { + resolver = fileResolver; + } + + @Override + public FileHandle resolve(String fileName) { + + if (fileName.endsWith(".p")) { + return resolver.resolve("particles/" +fileName); + } else if (fileName.endsWith(".ogg")) { + return resolver.resolve("sounds/" + fileName); + } else { + return null; + } + } + +} diff --git a/old/core/src/zero1hd/rhythmbullet/util/InitialScreen.java b/old/core/src/zero1hd/rhythmbullet/util/InitialScreen.java new file mode 100644 index 0000000..9cf038c --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/util/InitialScreen.java @@ -0,0 +1,20 @@ +package zero1hd.rhythmbullet.util; + +import com.badlogic.gdx.Screen; + +import zero1hd.rhythmbullet.RhythmBullet; + +public interface InitialScreen extends ResizeReadyScreen { + /** + * Called when everythings loaded and ready to advance. + * Screen should be created on platform. + * @param gameManager the game manager. + * @return the screen that is created. + */ + public Screen advance(RhythmBullet gameManager); + + /** + * Immediately called after the LibGDX instance has been instantiated. + */ + public void init(); +} diff --git a/old/core/src/zero1hd/rhythmbullet/util/ResizeReadyScreen.java b/old/core/src/zero1hd/rhythmbullet/util/ResizeReadyScreen.java new file mode 100644 index 0000000..b4e99a2 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/util/ResizeReadyScreen.java @@ -0,0 +1,15 @@ +package zero1hd.rhythmbullet.util; + +import com.badlogic.gdx.Screen; + +public interface ResizeReadyScreen extends Screen { + /** + * called before assets are cleared from memory. + */ + public void preAssetLoad(); + + /** + * called after transition completes and assets reloaded. + */ + public void postAssetLoad(); +} diff --git a/old/core/src/zero1hd/rhythmbullet/util/RoundingResolutionHandler.java b/old/core/src/zero1hd/rhythmbullet/util/RoundingResolutionHandler.java new file mode 100644 index 0000000..cdd39c5 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/util/RoundingResolutionHandler.java @@ -0,0 +1,77 @@ +package zero1hd.rhythmbullet.util; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.assets.loaders.FileHandleResolver; +import com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver.Resolution; +import com.badlogic.gdx.files.FileHandle; + +public class RoundingResolutionHandler implements FileHandleResolver { + private final Resolution[] descriptors; + private final FileHandleResolver resolver; + private boolean silent = true; + private int width, height; + public RoundingResolutionHandler(FileHandleResolver fileResolver, Resolution... descriptors) { + if (descriptors.length == 0) throw new IllegalArgumentException("At least one Resolution needs to be supplied."); + this.descriptors = descriptors; + this.resolver = fileResolver; + } + + public void setResolution(int width, int height) { + this.width = width; + this.height = height; + } + + public void resetResolution() { + width = Gdx.graphics.getWidth(); + height = Gdx.graphics.getHeight(); + } + + public Resolution chooseRounded(Resolution... descriptors) { + Resolution best = descriptors[0]; + + int leastDifference = -1; + + int w = width, h = height; + + if (w > h) { + for (int i = 0; i < descriptors.length; i++) { + int currentDiff = h - descriptors[i].portraitHeight; + + if (currentDiff < 0) { + currentDiff = currentDiff*-1; + } + + if ((currentDiff < leastDifference) || leastDifference == -1) { + best = descriptors[i]; + leastDifference = currentDiff; + } + } + } else { + for (int i = 0; i < descriptors.length; i++) { + int currentDiff = w - descriptors[i].portraitWidth; + + if (currentDiff < 0) { + currentDiff = currentDiff*-1; + } + + if (currentDiff < leastDifference || leastDifference == -1) { + best = descriptors[i]; + leastDifference = currentDiff; + } + } + } + return best; + } + + @Override + public FileHandle resolve(String fileName) { + Resolution bestRes = chooseRounded(descriptors); + if (!silent) { + Gdx.app.debug("RResolution Handler", "Finding best match for resolution: " + width + "x" + height + " for file: " + fileName); + Gdx.app.debug("RResolution Handler", "Selected folder: " + bestRes.folder); + } + FileHandle resSpecificFile = resolver.resolve(bestRes.folder + "/" + fileName); + if (!resSpecificFile.exists()) resSpecificFile = resolver.resolve(fileName); + return resSpecificFile; + } +} diff --git a/old/core/src/zero1hd/rhythmbullet/util/ScreenConfiguration.java b/old/core/src/zero1hd/rhythmbullet/util/ScreenConfiguration.java new file mode 100644 index 0000000..122dcd2 --- /dev/null +++ b/old/core/src/zero1hd/rhythmbullet/util/ScreenConfiguration.java @@ -0,0 +1,30 @@ +package zero1hd.rhythmbullet.util; + +public interface ScreenConfiguration { + public void setFramesPerSecond(int fps); + + public int getTargetFramesPerSecond(); + + /** + * @param useVsync whether or not to use vSync. + */ + public void setVsync(boolean useVsync); + + public boolean getVsync(); + + public int getScreenWidth(); + + public int getScreenHeight(); + + public int getWindowPosX(); + + public int getWindowPosY(); + + public void setWindowLocationX(int x); + + public void setWindowLocationY(int y); + + public void setWindowLocation(int x, int y); + + public void queueBorderless(boolean borderless); +} diff --git a/old/desktop/.classpath b/old/desktop/.classpath new file mode 100644 index 0000000..a382805 --- /dev/null +++ b/old/desktop/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/old/desktop/.project b/old/desktop/.project new file mode 100644 index 0000000..6478e3d --- /dev/null +++ b/old/desktop/.project @@ -0,0 +1,25 @@ + + + RhythmBullet-desktop + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.springsource.ide.eclipse.gradle.core.nature + org.eclipse.jdt.core.javanature + + + + assets + 2 + PARENT-1-PROJECT_LOC/android/assets + + + diff --git a/old/desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs b/old/desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs new file mode 100644 index 0000000..b6b91f6 --- /dev/null +++ b/old/desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs @@ -0,0 +1,4 @@ +#org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences +#Mon Sep 10 00:40:48 CDT 2018 +org.springsource.ide.eclipse.gradle.linkedresources=assets/; +org.springsource.ide.eclipse.gradle.rootprojectloc=.. diff --git a/old/desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs b/old/desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs new file mode 100644 index 0000000..539dcf9 --- /dev/null +++ b/old/desktop/.settings/gradle/org.springsource.ide.eclipse.gradle.refresh.prefs @@ -0,0 +1,8 @@ +#org.springsource.ide.eclipse.gradle.core.actions.GradleRefreshPreferences +#Mon Sep 10 00:40:48 CDT 2018 +addResourceFilters=true +afterTasks=afterEclipseImport; +beforeTasks=cleanEclipse;eclipse; +enableAfterTasks=true +enableBeforeTasks=true +useHierarchicalNames=false diff --git a/old/desktop/.settings/org.eclipse.jdt.core.prefs b/old/desktop/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/old/desktop/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/old/desktop/build.gradle b/old/desktop/build.gradle new file mode 100644 index 0000000..9d9b713 --- /dev/null +++ b/old/desktop/build.gradle @@ -0,0 +1,55 @@ +apply plugin: "java" + +sourceCompatibility = 1.6 +sourceSets.main.java.srcDirs = [ "src/" ] + +project.ext.mainClassName = "zero1hd.rhythmbullet.desktop.DesktopLauncher" +project.ext.assetsDir = new File("../android/assets"); + +task run(dependsOn: classes, type: JavaExec) { + main = project.mainClassName + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = project.assetsDir + ignoreExitValue = true +} + +task debug(dependsOn: classes, type: JavaExec) { + main = project.mainClassName + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = project.assetsDir + ignoreExitValue = true + debug = true +} + +task dist(type: Jar) { + from files(sourceSets.main.output.classesDir) + from files(sourceSets.main.output.resourcesDir) + from {configurations.compile.collect {zipTree(it)}} + from files(project.assetsDir); + + manifest { + attributes 'Main-Class': project.mainClassName + } +} + +dist.dependsOn classes + +eclipse { + project { + name = appName + "-desktop" + linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/android/assets' + } +} + +task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { + doLast { + def classpath = new XmlParser().parse(file(".classpath")) + new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]); + def writer = new FileWriter(file(".classpath")) + def printer = new XmlNodePrinter(new PrintWriter(writer)) + printer.setPreserveWhitespace(true) + printer.print(classpath) + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/Controls.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/Controls.java new file mode 100644 index 0000000..1cccc7e --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/Controls.java @@ -0,0 +1,45 @@ +package zero1hd.rhythmbullet.desktop; + +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.Input.Keys; + +public enum Controls { + UP("Forward", Keys.UP), DOWN("Backwards", Keys.DOWN), LEFT("Left", Keys.LEFT), RIGHT("Right", Keys.RIGHT), SHOOT("Shoot", Keys.SPACE), ACCELERATE("Boost", Keys.SHIFT_LEFT); + private int keycode; + private final String friendly; + private final int defectKey; + + private Controls(String friendly, int defectKey) { + this.friendly = friendly; + this.defectKey = defectKey; + this.keycode = defectKey; + } + + public Controls setKeycode(int keycode) { + Controls[] controls = Controls.values(); + for (int i = 0; i < controls.length; i++) { + if (controls[i] != this && controls[i].getKeycode() == keycode) { + return controls[i]; + } + } + this.keycode = keycode; + return null; + } + + public int getKeycode() { + return keycode; + } + + public void loadKeyFromPreferences(Preferences preferences) { + setKeycode(preferences.getInteger(name(), defectKey)); + } + + public void saveKeyToPreferences(Preferences preferences) { + preferences.putInteger(name(), keycode); + } + + @Override + public String toString() { + return friendly; + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopAssetPack.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopAssetPack.java new file mode 100644 index 0000000..cdf7eff --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopAssetPack.java @@ -0,0 +1,238 @@ +package zero1hd.rhythmbullet.desktop; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.ParticleEffect; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle; +import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle; +import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; +import com.badlogic.gdx.scenes.scene2d.ui.List.ListStyle; +import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar.ProgressBarStyle; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane.ScrollPaneStyle; +import com.badlogic.gdx.scenes.scene2d.ui.SelectBox.SelectBoxStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Slider.SliderStyle; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; +import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Window.WindowStyle; + +import zero1hd.rhythmbullet.util.AssetPack; + +public class DesktopAssetPack implements AssetPack { + private FreeTypeFontGenerator default_fontGenerator; + private FreeTypeFontGenerator darktech_ldr_fontGenerator; + + @Override + public void initiate() { + default_fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Gasalt-Regular.ttf")); + darktech_ldr_fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/darktech_ldr.ttf")); + } + + @Override + public void queueTextures(AssetManager assetManager) { + assetManager.load("uiskin.atlas", TextureAtlas.class); + assetManager.load("Tech-Circle1.png", Texture.class); + assetManager.load("polyjet-standard.png", Texture.class); + assetManager.load("keyboard.atlas", TextureAtlas.class); + assetManager.load("cybercircle3B.png", Texture.class); + assetManager.load("title.png", Texture.class); + assetManager.load("cybercircle1.png", Texture.class); + assetManager.load("defaultCover.png", Texture.class); + assetManager.load("laser.png", Texture.class); + assetManager.load("pellet.png", Texture.class); + assetManager.load("shard.png", Texture.class); + assetManager.load("bar.png", Texture.class); + assetManager.load("flake.png", Texture.class); + assetManager.load("void_circle.png", Texture.class); + assetManager.load("tpSelector.png", Texture.class); + assetManager.load("backgrounds/mainBG.png", Texture.class); + assetManager.load("magic1.png", Texture.class); + } + + @Override + public void queueSFX(AssetManager assetManager) { + assetManager.load("pop_open.ogg", Sound.class); + assetManager.load("pop_close.ogg", Sound.class); + assetManager.load("laser.ogg", Sound.class); + assetManager.load("explosion.ogg", Sound.class); + assetManager.load("disintegrate.ogg", Sound.class); + } + + @Override + public void queueParticles(AssetManager assetManager) { + assetManager.load("standard_thrust.p", ParticleEffect.class); + assetManager.load("teleport-cloak.p", ParticleEffect.class); + assetManager.load("explosion-s.p", ParticleEffect.class); + assetManager.load("beateffect.p", ParticleEffect.class); + } + + @Override + public void setupSkin(Skin skin) { + skin.add("default", Color.WHITE); + skin.add("inverse", Color.BLACK); + + TextButtonStyle defaultTextButton = new TextButtonStyle(); + defaultTextButton.up = skin.getDrawable("rect"); + defaultTextButton.down = skin.getDrawable("rect-down"); + defaultTextButton.font = skin.getFont("default-font"); + defaultTextButton.fontColor = skin.getColor("default"); + defaultTextButton.disabled = skin.getDrawable("rect-disabled"); + skin.add("default", defaultTextButton); + + TextButtonStyle subTextbutton = new TextButtonStyle(defaultTextButton); + subTextbutton.font = skin.getFont("sub-font"); + skin.add("sub", subTextbutton); + + TextButtonStyle windowTextButton = new TextButtonStyle(defaultTextButton); + windowTextButton.font = skin.getFont("window-font"); + skin.add("window", windowTextButton); + + SliderStyle defaultSlider = new SliderStyle(skin.getDrawable("default-slider"), skin.getDrawable("default-slider-knob")); + skin.add("default-horizontal", defaultSlider); + + SliderStyle vertSlider = new SliderStyle(defaultSlider); + vertSlider.knob = skin.getDrawable("vertical-slider-knob"); + skin.add("default-vertical", vertSlider); + + ProgressBarStyle defaultProgressBar = new ProgressBarStyle(skin.getDrawable("default-slider"), skin.getDrawable("progress-slider-knob")); + + LabelStyle defaultLabel = new LabelStyle(); + defaultLabel.font = skin.getFont("default-font"); + defaultLabel.fontColor = skin.getColor("default"); + skin.add("default", defaultLabel); + + TextFieldStyle defaultTextField = new TextFieldStyle(skin.getFont("sub-font"), skin.getColor("default"), skin.getDrawable("cursor"), skin.getDrawable("selection"), skin.getDrawable("textfield")); + skin.add("default", defaultTextField); + + TextFieldStyle uiTextField = new TextFieldStyle(defaultTextField); + uiTextField.font = skin.getFont("window-font"); + skin.add("ui", uiTextField); + + WindowStyle defaultWindow = new WindowStyle(skin.getFont("window-font"), skin.getColor("default"), skin.getDrawable("default-window")); + skin.add("default", defaultWindow); + + WindowStyle tintedWindow = new WindowStyle(defaultWindow); + tintedWindow.titleFontColor = skin.getColor("inverse"); + tintedWindow.background = skin.getDrawable("tinted-window"); + skin.add("tinted", tintedWindow); + + ListStyle defaultList = new ListStyle(skin.getFont("window-font"), skin.getColor("inverse"), skin.getColor("default"), skin.getDrawable("selection")); + skin.add("default", defaultList); + + ScrollPaneStyle defaultScrollPane = new ScrollPaneStyle(); + defaultScrollPane.vScroll = skin.getDrawable("default-scroll"); + defaultScrollPane.hScrollKnob = skin.getDrawable("default-round-large"); + defaultScrollPane.hScroll = skin.getDrawable("default-scroll"); + defaultScrollPane.vScrollKnob = skin.getDrawable("default-round-large"); + skin.add("default", defaultScrollPane); + + CheckBoxStyle defaultCheckBox = new CheckBoxStyle(skin.getDrawable("check-off"), skin.getDrawable("check-on"), skin.getFont("window-font"), skin.getColor("default")); + defaultCheckBox.checkboxOffDisabled = skin.getDrawable("check-disabled"); + skin.add("default", defaultCheckBox); + + SelectBoxStyle defaultSelectBox = new SelectBoxStyle(skin.getFont("default-font"), skin.getColor("default"), skin.getDrawable("default-select"), defaultScrollPane, defaultList); + skin.add("default", defaultSelectBox); + + Gdx.app.debug("Prelaunch Debug Info", "UI Skin has been defined."); + + CheckBoxStyle playButtonStyle = new CheckBoxStyle(defaultCheckBox); + playButtonStyle.checkboxOn = skin.getDrawable("play-down"); + playButtonStyle.checkboxOff = skin.getDrawable("play"); + skin.add("play-button", playButtonStyle); + + ImageButtonStyle pauseButtonStyle = new ImageButtonStyle(); + pauseButtonStyle.down = skin.getDrawable("pause-down"); + pauseButtonStyle.up = skin.getDrawable("pause"); + skin.add("pause-button", pauseButtonStyle); + + ImageButtonStyle fastForwardButtonStyle = new ImageButtonStyle(); + fastForwardButtonStyle.down = skin.getDrawable("fast-forward-down"); + fastForwardButtonStyle.up = skin.getDrawable("fast-forward"); + skin.add("fast-forward-button", fastForwardButtonStyle); + + ImageButtonStyle reverseButtonStyle = new ImageButtonStyle(); + reverseButtonStyle.down = skin.getDrawable("rewind-down"); + reverseButtonStyle.up = skin.getDrawable("rewind"); + skin.add("rewind-button", reverseButtonStyle); + + CheckBoxStyle shuffleButtonStyle = new CheckBoxStyle(defaultCheckBox); + shuffleButtonStyle.checkboxOff = skin.getDrawable("shuffle"); + shuffleButtonStyle.checkboxOn = skin.getDrawable("shuffle-down"); + skin.add("shuffle-button", shuffleButtonStyle); + + ButtonStyle selectableButton = new ButtonStyle(); + selectableButton.checked = skin.getDrawable("holo-pane-down"); + selectableButton.up = skin.getDrawable("holo-pane"); + skin.add("selectable-button", selectableButton); + + ButtonStyle selectableCleanButton = new ButtonStyle(); + skin.add("selectable-clean-button", selectableCleanButton); + } + + @Override + public void generateFonts(Skin skin) { + int height = Gdx.graphics.getHeight(); + + skin.add("window-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() { + { + size = 18; + } + })); + skin.add("sub-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() { + { + size = fontScale(0.05f, height); + } + })); + skin.add("default-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() { + { + size = fontScale(0.07f, height); + } + })); + skin.add("large-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() { + { + size = fontScale(0.085f, height); + } + })); + skin.add("special-font", darktech_ldr_fontGenerator.generateFont(new FreeTypeFontParameter() { + { + size = fontScale(0.075f, height); + } + })); + } + + public int fontScale(float fontSize, int height) { + int size = MathUtils.round(Gdx.graphics.getDensity()*(fontSize*height)); + if (size >= 200) { + size = 200; + } + return size; + } + + @Override + public void complete(AssetManager assetManager) { + assetManager.get("standard_thrust.p", ParticleEffect.class).flipY(); + + Preferences controlsPrefs = Gdx.app.getPreferences("RhythmBullet_Controls"); + Controls.UP.loadKeyFromPreferences(controlsPrefs); + Controls.DOWN.loadKeyFromPreferences(controlsPrefs); + Controls.LEFT.loadKeyFromPreferences(controlsPrefs); + Controls.RIGHT.loadKeyFromPreferences(controlsPrefs); + Controls.SHOOT.loadKeyFromPreferences(controlsPrefs); + Controls.ACCELERATE.loadKeyFromPreferences(controlsPrefs); + } + + @Override + public void dispose() { + darktech_ldr_fontGenerator.dispose(); + default_fontGenerator.dispose(); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopLauncher.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopLauncher.java new file mode 100644 index 0000000..eadd3e8 --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopLauncher.java @@ -0,0 +1,28 @@ +package zero1hd.rhythmbullet.desktop; + +import com.badlogic.gdx.backends.lwjgl.LwjglApplication; +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.desktop.screens.SplashScreen; + +public class DesktopLauncher { + + public static void main (String[] arg) { + RhythmBullet core; + LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); + DesktopScreenConfiguration screenConfig = new DesktopScreenConfiguration(config); + + config.title = "Rhythm Bullet"; + config.resizable = false; + config.useHDPI = true; + config.samples = 2; + config.width = 320; + config.height = 320; + config.allowSoftwareMode = true; + core = new RhythmBullet(); + core.setup(new SplashScreen(), new DesktopAssetPack(), screenConfig); + + LwjglApplication app = new LwjglApplication(core, config); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopScreenConfiguration.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopScreenConfiguration.java new file mode 100644 index 0000000..4f86650 --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/DesktopScreenConfiguration.java @@ -0,0 +1,79 @@ +package zero1hd.rhythmbullet.desktop; + +import org.lwjgl.opengl.Display; + +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; + +import zero1hd.rhythmbullet.util.ScreenConfiguration; + +public class DesktopScreenConfiguration implements ScreenConfiguration { + private LwjglApplicationConfiguration configuration; + private boolean vSync; + + public DesktopScreenConfiguration(LwjglApplicationConfiguration configuration) { + this.configuration = configuration; + vSync = configuration.vSyncEnabled; + } + + @Override + public void setFramesPerSecond(int fps) { + configuration.foregroundFPS = fps; + } + + + @Override + public int getTargetFramesPerSecond() { + return configuration.foregroundFPS; + } + + @Override + public void setVsync(boolean useVsync) { + configuration.vSyncEnabled = useVsync; + Display.setVSyncEnabled(useVsync); + } + + @Override + public boolean getVsync() { + return vSync; + } + + @Override + public int getScreenWidth() { + return Display.getDesktopDisplayMode().getWidth(); + } + + @Override + public int getScreenHeight() { + return Display.getDesktopDisplayMode().getHeight(); + } + + @Override + public int getWindowPosX() { + return Display.getX(); + } + + @Override + public int getWindowPosY() { + return Display.getY(); + } + + @Override + public void setWindowLocationX(int x) { + Display.setLocation(x, getWindowPosY()); + } + + @Override + public void setWindowLocationY(int y) { + Display.setLocation(getWindowPosX(), y); + } + + @Override + public void setWindowLocation(int x, int y) { + Display.setLocation(x, y); + } + + @Override + public void queueBorderless(boolean borderless) { + System.setProperty("org.lwjgl.opengl.Window.undecorated", String.valueOf(borderless)); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/PCMObtainer.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/PCMObtainer.java new file mode 100644 index 0000000..a451ade --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/PCMObtainer.java @@ -0,0 +1,269 @@ +package zero1hd.rhythmbullet.desktop.audio; + +import static org.lwjgl.openal.AL10.alGetSourcef; + +import java.math.RoundingMode; +import java.nio.ByteBuffer; +import java.nio.ShortBuffer; +import java.text.DecimalFormat; +import java.util.Observable; +import java.util.Observer; + +import org.lwjgl.openal.AL; +import org.lwjgl.openal.AL11; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.backends.lwjgl.audio.OpenALMusic; +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.utils.TimeUtils; +import com.badlogic.gdx.utils.reflect.ClassReflection; +import com.badlogic.gdx.utils.reflect.Field; +import com.badlogic.gdx.utils.reflect.ReflectionException; + +import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D; +import zero1hd.rhythmbullet.audio.MusicController; +import zero1hd.rhythmbullet.audio.visualizer.PCMSystem; + +public class PCMObtainer implements Observer, PCMSystem { + private int windowSize = 1024; + private int sampleRate; + private long millisPerWindow; + private boolean songChanged; + private DecimalFormat df; + private float[] PCM = new float[windowSize]; + private float[] frequencyBins = new float[windowSize / 2]; + private FloatFFT_1D fft = new FloatFFT_1D(windowSize); + private ShortBuffer playingBuffer; + private ShortBuffer intermediateBuffer; + private ShortBuffer buffer; + private volatile int sourceID; + private int channelCount; + private MusicController mc; + private BufferStreamReadThread streamReadThread; + private int windowsRead; + private int currentPlaybackWindow; + private volatile boolean updated; + + public PCMObtainer(MusicController musicController) { + this.mc = musicController; + mc.addObserver(this); + try { + Field bufferField = ClassReflection.getDeclaredField(OpenALMusic.class, "tempBuffer"); + bufferField.setAccessible(true); + buffer = ((ByteBuffer) bufferField.get(null)).asShortBuffer().asReadOnlyBuffer(); + playingBuffer = ShortBuffer.allocate(buffer.capacity()); + intermediateBuffer = ShortBuffer.allocate(buffer.capacity()); + } catch (IllegalArgumentException | SecurityException | ReflectionException e) { + Gdx.app.debug("Visualizer reflection", "Failed attempt at retrieving tempBuffer field.", e); + Gdx.app.exit(); + } + + streamReadThread = new BufferStreamReadThread(); + + df = new DecimalFormat("#.###"); + df.setRoundingMode(RoundingMode.HALF_EVEN); + } + + private boolean calcPCMData() { + synchronized (PCM) { + boolean empty = true; + short chanVal; + for (int sid = 0; sid < PCM.length && sid < playingBuffer.remaining(); sid++) { + PCM[sid] = 0; + for (int channel = 0; channel < channelCount; channel++) { + if (PCM[sid] < (chanVal = playingBuffer.get())) { + PCM[sid] = chanVal; + } + } + PCM[sid] /= Short.MAX_VALUE + 1f; + + if (PCM[sid] != 0) { + empty = false; + } + + } + return empty; + } + } + + private void checkValidityOfPlaybackBuffer() { + // Begin comparison + buffer.rewind(); + if (intermediateBuffer.compareTo(buffer) != 0) { + bufferChanged(); + + // Begin copying current buffer to the comparison buffer + intermediateBuffer.clear(); + intermediateBuffer.put(buffer); + intermediateBuffer.flip(); + } + } + + private void bufferChanged() { + playingBuffer.rewind(); + playingBuffer.put(intermediateBuffer); + playingBuffer.rewind(); + synchronizeBufferWithPlayback(); + } + + private int calculateBufferPosition() { + int offset = (int) alGetSourcef(sourceID, AL11.AL_SAMPLE_OFFSET); + offset = (offset / windowSize) * windowSize; + return offset; + } + + private boolean synchronizeBufferWithPlayback() { + int bufferPos = calculateBufferPosition(); + synchronized (this) { + if (bufferPos <= playingBuffer.limit() && bufferPos >= 0) { + playingBuffer.position(bufferPos); + windowsRead = (int) ((mc.getCurrentPosition() * sampleRate) / windowSize); + return true; + } + } + return false; + } + + @Override + public void loadMusic() { + Gdx.app.debug("PCMObtainer", "music loaded."); + sourceID = -1; + + channelCount = mc.getCurrentMusicHeader().getChannelCount(); + sampleRate = mc.getCurrentMusicHeader().getSampleRate(); + String millisPerWindowF = df.format(windowSize/(float) sampleRate); + millisPerWindow = (long) (Float.valueOf(millisPerWindowF)*1000); + songChanged = true; + + intermediateBuffer.clear(); + playingBuffer.clear(); + begin(); + } + + @Override + public float[] getFrequencyBins() { + if (mc.isPlaying()) { + if (updated) { + synchronized (PCM) { + fft.realForward(PCM); + System.arraycopy(PCM, 1, frequencyBins, 0, frequencyBins.length); + } + updated = false; + } + } else { + for (int freqID = 0; freqID < frequencyBins.length; freqID++) { + frequencyBins[freqID] = 0; + } + } + return frequencyBins; + } + + @Override + public int getWindowSize() { + return windowSize; + } + + + + private class BufferStreamReadThread implements Runnable { + private String name = "PCM-Audio-Processing"; + private Thread thread; + private volatile boolean run = true; + private long timeOfLastRead; + private long waitTime; + @Override + public void run() { + while (run) { + if (mc.isPlaying()) { + //record time of read + timeOfLastRead = TimeUtils.millis(); + + //calculate current pcm data and notify that there is new data + checkValidityOfPlaybackBuffer(); + updated = !calcPCMData(); + windowsRead++; + + //contemplate synchronization + currentPlaybackWindow = MathUtils.round((mc.getCurrentPosition() * sampleRate) / windowSize); + if (windowsRead != currentPlaybackWindow) { + synchronizeBufferWithPlayback(); + } + //wait for a bit before reading again depending on the speed at which the system does playback. + waitTime = Math.max(0, millisPerWindow - TimeUtils.timeSinceMillis(timeOfLastRead)); + try { + Thread.sleep(waitTime); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } else { + + synchronized (this) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + Gdx.app.debug(thread.getName(), "stopped"); + } + + public void start() { + if (thread == null) { + thread = new Thread(this, name); + thread.setDaemon(true); + thread.start(); + } else { + synchronized (this) { + notify(); + } + } + } + + public void stop() { + run = false; + } + } + + @Override + public void update(Observable o, Object arg) { + if (o == mc) { + if (arg == mc.states.LOADED) { + loadMusic(); + } else if (arg == mc.states.PLAYING) { + begin(); + } + } + } + + private void begin() { + if (mc.isPlaying()) { + if (sourceID == -1) { + try { + Field sourceIDField = ClassReflection.getDeclaredField(OpenALMusic.class, "sourceID"); + sourceIDField.setAccessible(true); + sourceID = (int) sourceIDField.get(mc.getCurrentMusic()); + } catch (ReflectionException e) { + e.printStackTrace(); + } + } + streamReadThread.start(); + } + } + + @Override + public void dispose() { + streamReadThread.stop(); + } + + @Override + public boolean hasAudioChanged() { + if (songChanged) { + songChanged = false; + return true; + } else { + return false; + } + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/processor/DesktopAudioProcessorFactory.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/processor/DesktopAudioProcessorFactory.java new file mode 100644 index 0000000..d17f35f --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/processor/DesktopAudioProcessorFactory.java @@ -0,0 +1,14 @@ +package zero1hd.rhythmbullet.desktop.audio.processor; + +import com.badlogic.gdx.files.FileHandle; + +import zero1hd.rhythmbullet.audio.AudioProcessorFactory; +import zero1hd.rhythmbullet.audio.MinimalAudioHeader; +import zero1hd.rhythmbullet.audio.processor.AudioProcessor; + +public class DesktopAudioProcessorFactory implements AudioProcessorFactory { + @Override + public AudioProcessor newMP3AudioProcessor(FileHandle fileHandle) { + return new MP3AudioProcessor(fileHandle, new MinimalAudioHeader(fileHandle)); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/processor/MP3AudioProcessor.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/processor/MP3AudioProcessor.java new file mode 100644 index 0000000..d19387c --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/audio/processor/MP3AudioProcessor.java @@ -0,0 +1,158 @@ +package zero1hd.rhythmbullet.desktop.audio.processor; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.files.FileHandle; + +import javazoom.jl.decoder.Bitstream; +import javazoom.jl.decoder.BitstreamException; +import javazoom.jl.decoder.DecoderException; +import javazoom.jl.decoder.Header; +import javazoom.jl.decoder.MP3Decoder; +import javazoom.jl.decoder.OutputBuffer; +import zero1hd.rhythmbullet.audio.MinimalAudioHeader; +import zero1hd.rhythmbullet.audio.processor.AudioProcessor; + + +public class MP3AudioProcessor implements AudioProcessor { + private boolean stereo; + private int sampleRate; + private long sampleFrames; + private FileHandle fileHandle; + private byte[] currentByteSet; + private byte[] workset; + Bitstream bitstream; + MP3Decoder decoder; + OutputBuffer sampleBuffer; + private int indexHead = -1; + + + public MP3AudioProcessor(FileHandle fileHandle, MinimalAudioHeader minimalAudioHeader) { + this.fileHandle = fileHandle; + + bitstream = new Bitstream(fileHandle.read()); + + + stereo = minimalAudioHeader.getChannelCount() == 1 ? false : true; + sampleRate = minimalAudioHeader.getSampleRate(); + sampleFrames = minimalAudioHeader.estimateSampleFrames(); + + decoder = new MP3Decoder(); + sampleBuffer = new OutputBuffer(stereo ? 2 : 1, false); + decoder.setOutputBuffer(sampleBuffer); + workset = new byte[(stereo ? 2 : 1)*2]; + } + + @Override + public boolean isStereo() { + return stereo; + } + + + @Override + public int getSampleRate() { + return sampleRate; + } + + @Override + public int readSamples(short[] pcm) { + int samplesRead = 0; + for (int sid = 0; sid < pcm.length; sid++) { + for (int wsid = 0; wsid < workset.length; wsid++) { + workset[wsid] = nextByte(); + } + if (currentByteSet != null) { + pcm[sid] += (workset[1] << 8) + (workset[0] & 0x00ff); + if (stereo) { + short altChan = (short) ((workset[3] << 8) + (workset[2] & 0x00ff)); + sid++; + pcm[sid] = altChan; + } + samplesRead ++; + } + } + return samplesRead; + } + + @Override + public int readFrames(float[] pcm) { + int framesRead = 0; + for (int sid = 0; sid < pcm.length; sid++) { + for (int wsid = 0; wsid < workset.length; wsid++) { + workset[wsid] = nextByte(); + } + if (currentByteSet != null) { + pcm[sid] += (workset[1] << 8) + (workset[0] & 0x00ff); + if (stereo) { + short altChan = (short) ((workset[3] << 8) + (workset[2] & 0x00ff)); + pcm[sid] = altChan > pcm[sid] ? altChan : pcm[sid]; + } + framesRead++; + pcm[sid] /= Short.MAX_VALUE+1; + } + } + return framesRead; + } + + public byte nextByte() { + indexHead++; + if (currentByteSet == null || indexHead >= currentByteSet.length) { + loadNextBuffer(); + if (currentByteSet == null) { + return 0; + } + indexHead = 0; + } + + return currentByteSet[indexHead]; + } + + public int loadNextBuffer() { + if (bitstream != null) { + int bytesRead = 0; + try { + Header header = bitstream.readFrame(); + if (header != null) { + + try { + decoder.decodeFrame(header, bitstream); + } catch (ArrayIndexOutOfBoundsException ae) { + Gdx.app.debug("Mp3Manager", "Last buffer reached since array was out of bounds."); + } catch (DecoderException de) { + Gdx.app.error("MP3 Decoder Error", de.toString()); + } + bitstream.closeFrame(); + bytesRead = sampleBuffer.reset(); + currentByteSet = sampleBuffer.getBuffer(); + } else { + currentByteSet = null; + } + } catch (BitstreamException be) { + be.printStackTrace(); + } + return bytesRead; + } else { + return 0; + } + } + + @Override + public FileHandle getMusicFileHandle() { + return fileHandle; + } + + @Override + public long getSampleFrames() { + return sampleFrames; + } + + @Override + public void dispose() { + Gdx.app.debug("MP3Manager", "Disposing..."); + try { + bitstream.close(); + bitstream = null; + } catch (BitstreamException e) { + e.printStackTrace(); + } + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/graphics/ui/components/GraphicsOptions.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/graphics/ui/components/GraphicsOptions.java new file mode 100644 index 0000000..8815847 --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/graphics/ui/components/GraphicsOptions.java @@ -0,0 +1,78 @@ +package zero1hd.rhythmbullet.desktop.graphics.ui.components; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Align; + +public class GraphicsOptions extends Table { + private Label resolutions; + + private ResolutionButton + _3840x2160, + _2560x1440, + _1920x1200, + _1920x1080, + _1280x800, + _1280x720, + _1366x768; + + + public GraphicsOptions(Skin skin, final Preferences prefs) { + align(Align.center); + defaults().space(10f); + resolutions = new Label("Resolutions: ", skin); + add(resolutions).left(); + row(); + + + TextButton fullscreen = new TextButton("Fullscreen", skin); + fullscreen.addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + if (!Gdx.graphics.isFullscreen()) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + prefs.putBoolean("fullscreen", true); + prefs.flush(); + } + } + }); + add(fullscreen).fillX(); + row(); + + _3840x2160 = new ResolutionButton(3840, 2160, skin, prefs); + add(_3840x2160).fillX(); + row(); + + _2560x1440 = new ResolutionButton(2560, 1440, skin, prefs); + add(_2560x1440).fillX(); + row(); + + _1920x1200 = new ResolutionButton(1920, 1200, skin, prefs); + add(_1920x1200).fillX(); + row(); + + _1920x1080 = new ResolutionButton(1920, 1080, skin, prefs); + add(_1920x1080).fillX(); + row(); + + _1280x800 = new ResolutionButton(1280, 800, skin, prefs); + add(_1280x800).fillX(); + row(); + + _1366x768 = new ResolutionButton(1366, 768, skin, prefs); + add(_1366x768).fillX(); + row(); + + _1280x720 = new ResolutionButton(1280, 720, skin, prefs); + add(_1280x720).fillX(); + row(); + pack(); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/graphics/ui/components/ResolutionButton.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/graphics/ui/components/ResolutionButton.java new file mode 100644 index 0000000..2eb5ecb --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/graphics/ui/components/ResolutionButton.java @@ -0,0 +1,36 @@ +package zero1hd.rhythmbullet.desktop.graphics.ui.components; + +import java.awt.Dimension; +import java.awt.Toolkit; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; + +public class ResolutionButton extends TextButton { + + public ResolutionButton(int width, int height, Skin skin, Preferences prefs) { + super(width + "x" + height, skin); + + Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize(); + + if (screenDim.getWidth() < width || screenDim.getHeight() < height) { + setDisabled(true); + } + + addListener(new ChangeListener() { + + @Override + public void changed(ChangeEvent event, Actor actor) { + Gdx.graphics.setWindowedMode(width, height); + prefs.putInteger("screen-width", width); + prefs.putInteger("screen-height", height); + prefs.putBoolean("fullscreen", false); + prefs.flush(); + } + }); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/EndScreen.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/EndScreen.java new file mode 100644 index 0000000..8153fac --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/EndScreen.java @@ -0,0 +1,8 @@ +package zero1hd.rhythmbullet.desktop.screens; + +import com.badlogic.gdx.ScreenAdapter; + +public class EndScreen extends ScreenAdapter { + public EndScreen() { + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/GameScreen.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/GameScreen.java new file mode 100644 index 0000000..c8e0cf4 --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/GameScreen.java @@ -0,0 +1,42 @@ +package zero1hd.rhythmbullet.desktop.screens; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.viewport.ExtendViewport; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.audio.MusicController; +import zero1hd.rhythmbullet.audio.visualizer.CircularVisualizer; +import zero1hd.rhythmbullet.desktop.audio.PCMObtainer; + +public class GameScreen extends ScreenAdapter { + private AssetManager assets; + private SpriteBatch batch; + private ExtendViewport viewport; + private CircularVisualizer circleVisualizer; + + public GameScreen(AssetManager assets, Preferences prefs, MusicController musicController) { + this.assets = assets; + batch = new SpriteBatch(); + viewport = new ExtendViewport(RhythmBullet.WORLD_WIDTH, RhythmBullet.WORLD_HEIGHT); + circleVisualizer = new CircularVisualizer(new PCMObtainer(musicController)); + circleVisualizer.setCenter(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2); + circleVisualizer.setCamera(viewport.getCamera()); + circleVisualizer.setColor(Color.CYAN.toFloatBits()); + circleVisualizer.applyPositionChanges(); + } + + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(0.22f, 0.22f, 0.22f, 1f); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + circleVisualizer.drawVisualizer(); + super.render(delta); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/SplashScreen.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/SplashScreen.java new file mode 100644 index 0000000..4a71d94 --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/SplashScreen.java @@ -0,0 +1,58 @@ +package zero1hd.rhythmbullet.desktop.screens; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.desktop.screens.main.MainScreen; +import zero1hd.rhythmbullet.util.InitialScreen; + +public class SplashScreen extends ScreenAdapter implements InitialScreen { + private Texture splashTexture; + private SpriteBatch batch; + + @Override + public void init() { + batch = new SpriteBatch(); + splashTexture = new Texture(Gdx.files.internal("splash_texture.png")); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(1f, 1f, 1f, 1f); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + batch.begin(); + batch.draw(splashTexture, 0, 0); + batch.end(); + + super.render(delta); + } + + @Override + public void hide() { + splashTexture.dispose(); + super.hide(); + } + + @Override + public void preAssetLoad() { + } + + @Override + public void postAssetLoad() { + } + + @Override + public void resize(int width, int height) { + super.resize(width, height); + } + + @Override + public Screen advance(RhythmBullet game) { + return new MainScreen(game); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/AnalysisPage.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/AnalysisPage.java new file mode 100644 index 0000000..0ee4e9b --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/AnalysisPage.java @@ -0,0 +1,157 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Slider; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; + +import zero1hd.rhythmbullet.audio.AudioMetadataController; +import zero1hd.rhythmbullet.audio.MusicController; +import zero1hd.rhythmbullet.audio.analyzer.AudioAnalyzerSection; +import zero1hd.rhythmbullet.audio.analyzer.DynamicAudioAnalyzer; +import zero1hd.rhythmbullet.audio.metadata.AudioMetadata; +import zero1hd.rhythmbullet.graphics.ui.Page; + +public class AnalysisPage extends Page { + private TextButton backButton; + private DynamicAudioAnalyzer audioAnalyzer; + private Table table; + private Table adjustment; + private Label difficultyModLabel, healthModLabel, speedModLabel; + private Slider difficultyModifierSlider, healthModifierSlider, speedModifierSlider; + private Label diffModPercentLabel, heltModPercentLabel, speeModPercentLabel; + private Label progressLabel; + private TextButton confirmButton; + private Image albumImage; + private AudioMetadataController amc; + private MusicController mc; + + public AnalysisPage(MusicController mc, AudioMetadataController amc, Skin skin, ChangeListener backButtonListener, ChangeListener confirmedButtonListener) { + super(2, 0); + table = new Table(); + table.setFillParent(true); + table.defaults().space(10f); + addActor(table); + adjustment = new Table(); + this.mc = mc; + this.amc = amc; + + difficultyModLabel = new Label("Difficulty Modifier: ", skin, "sub-font", skin.getColor("default")); + difficultyModifierSlider = new Slider(1, 3, 0.5f, false, skin); + diffModPercentLabel = new Label(String.valueOf(difficultyModifierSlider.getValue()) + "x", skin); + difficultyModifierSlider.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + diffModPercentLabel.setText(String.valueOf(difficultyModifierSlider.getValue()) + "x"); + } + }); + + adjustment.add(difficultyModLabel); + adjustment.add(difficultyModifierSlider).minWidth(0.5f*getWidth()); + adjustment.add(diffModPercentLabel).spaceLeft(10f).center().expandX().fill(); + adjustment.row(); + healthModLabel = new Label("Health Modifier: ", skin, "sub-font", skin.getColor("default")); + healthModifierSlider = new Slider(1f, 3f, 0.5f, false, skin); + heltModPercentLabel = new Label(String.valueOf(healthModifierSlider.getValue()) + "x", skin); + healthModifierSlider.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + heltModPercentLabel.setText(String.valueOf(healthModifierSlider.getValue()) + "x"); + } + }); + adjustment.add(healthModLabel); + adjustment.add(healthModifierSlider).fillX(); + adjustment.add(heltModPercentLabel).spaceLeft(10f); + adjustment.row(); + speedModLabel = new Label("Speed Modifier: ", skin, "sub-font", skin.getColor("default")); + speedModifierSlider = new Slider(1, 3, 0.5f, false, skin); + speeModPercentLabel = new Label(String.valueOf(speedModifierSlider.getValue()) + "x", skin); + speedModifierSlider.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + speeModPercentLabel.setText(String.valueOf(speedModifierSlider.getValue()) + "x"); + } + }); + adjustment.add(speedModLabel); + adjustment.add(speedModifierSlider).fillX(); + adjustment.add(speeModPercentLabel).spaceLeft(10f); + adjustment.row(); + + confirmButton = new TextButton("Confirm", skin); + confirmButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + confirmButton.setDisabled(true); + speedModifierSlider.setDisabled(true); + healthModifierSlider.setDisabled(true); + difficultyModifierSlider.setDisabled(true); + + progressLabel.setText("Loading..."); + } + }); + confirmButton.addListener(confirmedButtonListener); + + adjustment.add(confirmButton).colspan(3).fillX(); + adjustment.row(); + progressLabel = new Label("Please confirm... ", skin); + adjustment.add(progressLabel).colspan(2).left().spaceTop(20f); + + backButton = new TextButton("Cancel", skin); + backButton.setWidth(backButton.getWidth() + 20); + backButton.addListener(backButtonListener); + backButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + if (audioAnalyzer != null) { + audioAnalyzer.stop(); + audioAnalyzer = null; + albumImage.setDrawable(null); + mc.setLoop(false); + + } + } + }); + backButton.setPosition(15, getHeight()-backButton.getHeight()-25); + addActor(backButton); + + } + + public void processSong() { + mc.setLoop(true); + AudioMetadata metadata = amc.getAudioMetadata(mc.getCurrentMusicFileHandle()); + metadata.loadAlbumCover(); + albumImage = new Image(metadata.getAlbumCover()); + table.clear(); + table.add(albumImage).size(adjustment.getMinHeight()); + table.row(); + table.add(adjustment); + + AudioAnalyzerSection bass = new AudioAnalyzerSection(1, 5, 1.7f, 3); + AudioAnalyzerSection midSection = new AudioAnalyzerSection(7, 25, 1.5f, 3); + + audioAnalyzer = new DynamicAudioAnalyzer(mc.getMusicList().newAudioProcessor(mc.getCurrentMusicFileHandle()), bass, midSection); + audioAnalyzer.start(); + } + + @Override + public void dispose() { + super.dispose(); + } + + @Override + public void setCameraPositionToPage(Vector3 cameraPosition) { + confirmButton.setDisabled(false); + speedModifierSlider.setDisabled(false); + healthModifierSlider.setDisabled(false); + difficultyModifierSlider.setDisabled(false); + + processSong(); + + super.setCameraPositionToPage(cameraPosition); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/CreditsPage.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/CreditsPage.java new file mode 100644 index 0000000..9ed51d3 --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/CreditsPage.java @@ -0,0 +1,30 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; + +import zero1hd.rhythmbullet.graphics.ui.Page; + +public class CreditsPage extends Page { + + public CreditsPage(Skin skin) { + super(0, 1); + + Label title = new Label("Credits", skin, "large-font", skin.getColor("default")); + title.setPosition(15, getHeight()-title.getHeight()-15); + addActor(title); + + Label subtitle = new Label("This game wouldn't be possible without these people.", skin, "sub-font", skin.getColor("default")); + subtitle.setPosition(title.getX(), title.getY()-subtitle.getHeight()); + addActor(subtitle); + + Label listOfNames = new Label( + "TheClimbingHippo (texture)\n" + + "Crepitus (sound effects)\n" + + "Neoqueto - Darktech LDR (font)\n" + + "Rémi Lagast - Gasalt (font)\n" + + "Timour Jgenti - Iron Maiden (font)", skin, "sub-font", skin.getColor("default")); + listOfNames.setPosition(subtitle.getX()+16, subtitle.getY()-listOfNames.getHeight()-10); + addActor(listOfNames); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/GraphicsPage.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/GraphicsPage.java new file mode 100644 index 0000000..349f280 --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/GraphicsPage.java @@ -0,0 +1,43 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; + +import zero1hd.rhythmbullet.desktop.graphics.ui.components.GraphicsOptions; +import zero1hd.rhythmbullet.graphics.ui.Page; + +public class GraphicsPage extends Page { + private ScrollPane scrollPane; + private GraphicsOptions graphicsTable; + private TextButton backButton; + + public GraphicsPage(Skin skin, Preferences preferences, ChangeListener backButtonListener) { + super(-1, 1); + graphicsTable = new GraphicsOptions(skin, preferences); + scrollPane = new ScrollPane(graphicsTable, skin); + scrollPane.setFadeScrollBars(false); + scrollPane.setFillParent(true); + addActor(scrollPane); + + backButton = new TextButton("Back", skin); + backButton.setPosition(10, getHeight() - 10 - backButton.getHeight()); + backButton.setWidth(backButton.getWidth() + 20); + backButton.addListener(backButtonListener); + + addActor(backButton); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + super.draw(batch, parentAlpha); + } + + @Override + public void act(float delta) { + super.act(delta); + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/KeybindPage.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/KeybindPage.java new file mode 100644 index 0000000..daf3e3e --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/KeybindPage.java @@ -0,0 +1,224 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Array; + +import zero1hd.rhythmbullet.desktop.Controls; +import zero1hd.rhythmbullet.graphics.ui.Page; + +public class KeybindPage extends Page { + private ButtonGroup buttonOptions; + private VerticalGroup group; + private ScrollPane scrollPane; + private Skin skin; + TextureAtlas keyTextures; + private Preferences keyBindPrefs; + private InputListener inputListener; + private ChangeListener checkedListener; + + public KeybindPage(AssetManager assetManager, Skin skin, ChangeListener backButtonListener) { + super(-1, -1); + setTouchable(Touchable.enabled); + this.skin = skin; + keyTextures = assetManager.get("keyboard.atlas", TextureAtlas.class); + this.keyBindPrefs = Gdx.app.getPreferences("PolyJet_Controls"); + TextButton backButton = new TextButton("Back", skin); + backButton.setWidth(backButton.getWidth()+20f); + backButton.setPosition(getWidth()-backButton.getWidth()-15f, getHeight() - backButton.getHeight() - 15f); + backButton.addListener(backButtonListener); + addActor(backButton); + + inputListener = new InputListener() { + @Override + public boolean keyUp(InputEvent event, int keycode) { + KeyChangeButton button = buttonOptions.getChecked(); + if (button != null) { + if (keycode != Keys.ESCAPE) { + button.attemptSetKeycode(keycode); + } + getStage().setKeyboardFocus(null); + } + return super.keyUp(event, keycode); + } + }; + + checkedListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + KeyChangeButton button = (KeyChangeButton) actor; + if (button.isChecked()) { + button.ready(); + } else { + button.done(); + } + } + }; + + buttonOptions = new ButtonGroup<>(); + buttonOptions.setMinCheckCount(0); + buttonOptions.setMaxCheckCount(1); + group = new VerticalGroup(); + group.setTouchable(Touchable.childrenOnly); + group.space(15f); + Controls[] controls = Controls.values(); + for (int i = 0; i < controls.length; i++) { + KeyChangeButton button = new KeyChangeButton(controls[i]); + buttonOptions.add(button); + group.addActor(button); + } + scrollPane = new ScrollPane(group); + scrollPane.setHeight(Math.min(getHeight(), group.getPrefHeight())); + scrollPane.setWidth(group.getPrefWidth()); + scrollPane.setPosition((getWidth()-scrollPane.getWidth())/2f, (getHeight()-scrollPane.getHeight())/2f); + scrollPane.setTouchable(Touchable.childrenOnly); + addActor(scrollPane); + addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (hit(x, y, true) == event.getListenerActor()) { + simpleDebug("unchecking selected key change buttons."); + buttonOptions.uncheckAll(); + } + super.clicked(event, x, y); + } + }); + } + + @Override + public void setCameraPositionToPage(Vector3 cameraPosition) { + getStage().setScrollFocus(scrollPane); + super.setCameraPositionToPage(cameraPosition); + } + + @Override + public void dispose() { + save(); + super.dispose(); + } + public void save() { + keyBindPrefs.flush(); + } + + public class KeyChangeButton extends Button { + private Image keyImage; + private Label nameLabel; + private Controls control; + private boolean error; + + public KeyChangeButton(Controls control) { + super(skin, "selectable-clean-button"); + this.control = control; + nameLabel = new Label(control.toString(), skin); + keyImage = new Image(getIcon(control.getKeycode())); + + add(nameLabel).expandX().left().spaceRight(20f); + add(keyImage).expandX().right(); + + addListener(inputListener); + addListener(checkedListener); + } + + public void attemptSetKeycode(int keycode) { + simpleDebug("Attempting to set keycode to " + keycode); + TextureRegion textureRegion = getIcon(keycode); + if (textureRegion != null) { + setKeycode(keycode, textureRegion); + error = false; + } else { + error = true; + } + setChecked(false); + } + + public void setKeycode(int keycode, TextureRegion texture) { + + Controls conflict = control.setKeycode(keycode); + if (conflict != null) { + Array buttons = buttonOptions.getButtons(); + for (int i = 0; i < buttons.size; i++) { + System.out.println(buttons.get(i).getControl()); + if (buttons.get(i).getControl() == conflict) { + KeyChangeButton b = buttons.get(i); + scrollPane.scrollTo(b.getX(), b.getY(), b.getWidth(), b.getHeight()); + b.done(true); + return; + } + } + } + TextureRegion textureRegion = getIcon(keycode); + if (textureRegion != null) { + keyImage.setDrawable(new TextureRegionDrawable(texture)); + control.saveKeyToPreferences(keyBindPrefs); + } + } + + public void ready() { + getStage().setKeyboardFocus(this); + keyImage.setColor(Color.ORANGE); + } + + public void done() { + done(error); + } + + public void done(boolean error) { + if (error) { + keyImage.addAction(Actions.repeat(3, Actions.sequence(Actions.color(Color.RED, 0.2f), Actions.color(Color.WHITE, 0.1f)))); + } else { + keyImage.addAction(Actions.color(Color.WHITE, 0.2f)); + } + } + + public Controls getControl() { + return control; + } + } + + public TextureRegion getIcon(int keycode) { + switch (keycode) { + case Keys.ALT_LEFT: + case Keys.ALT_RIGHT: + return keyTextures.findRegion("Keyboard_Black_Alt"); + case Keys.SHIFT_LEFT: + case Keys.SHIFT_RIGHT: + return keyTextures.findRegion("Keyboard_Black_Shift"); + case Keys.LEFT_BRACKET: + return keyTextures.findRegion("Keyboard_Black_Bracket_Left"); + case Keys.RIGHT_BRACKET: + return keyTextures.findRegion("Keyboard_Black_Bracket_Right"); + case Keys.SEMICOLON: + return keyTextures.findRegion("Keyboard_Black_Semicolon"); + case Keys.SLASH: + return keyTextures.findRegion("Keyboard_Black_Slash"); + case Keys.NUM: + return keyTextures.findRegion("Keyboard_Black_Num_Lock"); + case Keys.ESCAPE: + return null; + default: + return keyTextures.findRegion("Keyboard_Black_" + Keys.toString(keycode).replace(' ', '_')); + } + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MainPage.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MainPage.java new file mode 100644 index 0000000..bafdb8f --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MainPage.java @@ -0,0 +1,209 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import java.util.Observable; +import java.util.Observer; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.ParticleEffect; +import com.badlogic.gdx.graphics.g2d.ParticleEffectPool; +import com.badlogic.gdx.graphics.g2d.ParticleEffectPool.PooledEffect; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Array; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.audio.MusicController; +import zero1hd.rhythmbullet.audio.AudioMetadataController; +import zero1hd.rhythmbullet.audio.visualizer.DoubleHorizontalVisualizer; +import zero1hd.rhythmbullet.desktop.audio.PCMObtainer; +import zero1hd.rhythmbullet.graphics.ui.Page; +import zero1hd.rhythmbullet.graphics.ui.components.MusicControls; +import zero1hd.rhythmbullet.graphics.ui.components.ScrollingText; +import zero1hd.rhythmbullet.util.ScreenConfiguration; + +public class MainPage extends Page implements Observer { + private MusicController mc; + private AudioMetadataController amc; + + private Label versionLabel; + private Image title; + + private Table menuTable; + private TextButton playButton; + private TextButton optionsButton; + private TextButton quitButton; + + private MusicControls musicControls; + private ScrollingText scrollText; + + private DoubleHorizontalVisualizer dhv; + + private boolean playParticles = true; + private ParticleEffectPool particlePool; + private Array particles; + private float particleScale; + + public MainPage(MusicController musicController, AudioMetadataController mmc, AssetManager assetManager, Skin skin, ScreenConfiguration screenConfiguration, ChangeListener playButtonListener, ChangeListener optionsButtonListener) { + super(0, 0); + this.mc = musicController; + this.mc.addObserver(this); + mc.getMusicList().addObserver(this); + this.amc = mmc; + this.amc.addObserver(this); + + dhv = new DoubleHorizontalVisualizer((int) getWidth(), (int) 0, getHeight(), 0, screenConfiguration.getTargetFramesPerSecond(), mc, new PCMObtainer(mc)); + dhv.setPosition(0, (int) ((getHeight() - dhv.getHeight())/2f)); + + title = new Image(assetManager.get("title.png", Texture.class)); + title.setScale((getHeight()/3f)/title.getHeight()); + if (title.getWidth()*title.getScaleX() > getWidth() - getWidth()*0.075f) { + title.setScale((getWidth()*(1f-0.075f))/title.getWidth()*getScaleX()); + } + title.setPosition((getWidth()-title.getWidth()*title.getScaleX())/2f, (getHeight()-title.getHeight()*title.getScaleY())/2f); + addActor(title); + + versionLabel = new Label("Version: " + RhythmBullet.VERSION, skin, "sub-font", skin.getColor("default")); + versionLabel.setPosition(3, 3); + addActor(versionLabel); + + menuTable = new Table(); + menuTable.setSize(getWidth(), title.getY()); + menuTable.align(Align.center); + menuTable.defaults().space(10f); + addActor(menuTable); + playButton = new TextButton("Start!", skin); + playButton.addListener(playButtonListener); + menuTable.add(playButton).width(Gdx.graphics.getWidth()*0.2f); + + menuTable.row(); + + optionsButton = new TextButton("Options", skin, "sub"); + optionsButton.addListener(optionsButtonListener); + menuTable.add(optionsButton).fillX(); + + menuTable.row(); + + quitButton = new TextButton("Quit", skin, "sub"); + quitButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Gdx.app.exit(); + } + }); + menuTable.add(quitButton).fillX(); + + musicControls = new MusicControls(skin, mc); + musicControls.setPosition((getWidth()-musicControls.getWidth() - 15f), 15f); + addActor(musicControls); + + scrollText = new ScrollingText("...", "...", skin, false, true, 1f/screenConfiguration.getTargetFramesPerSecond()); + scrollText.setWidth(0.5f*getWidth()); + scrollText.setPosition(15, getHeight() - scrollText.getHeight()-30f); + addActor(scrollText); + + if (mc.getMusicList().isSearched() && amc.isSameSizeMusicList()) { + scrollText.setText("Currently playing: " + amc.getAudioMetadata(mc.getCurrentMusicFileHandle()).getTitle(), null); + dhv.updateMusic(); + } + + particles = new Array<>(); + ParticleEffect particle = assetManager.get("beateffect.p", ParticleEffect.class); + particleScale = getWidth()/particle.findEmitter("main").getSpawnWidth().getHighMax(); + particlePool = new ParticleEffectPool(assetManager.get("beateffect.p", ParticleEffect.class), 0, 16); + + } + + @Override + public void act(float delta) { + dhv.act(delta); + super.act(delta); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + dhv.draw(batch, parentAlpha); + updateParticles(batch); + super.draw(batch, parentAlpha); + } + + private void updateParticles(Batch batch) { + if (playParticles) { + if (particles.size < 16 && dhv.isSignificantBeat()) { + PooledEffect particle = particlePool.obtain(); + particle.scaleEffect(particleScale); + particles.add(particle); + } + if (particles.size > 0) { + for (int i = particles.size - 1; i >= 0 && particles.size > 0; i--) { + PooledEffect particle = particles.get(i); + particle.draw(batch, Gdx.graphics.getDeltaTime()); + if (particle.isComplete()) { + particles.removeIndex(i); + particle.free(); + } + } + } + } + } + + public void stopParticles() { + playParticles = false; + } + + @Override + public void dispose() { + dhv.dispose(); + mc.getMusicList().deleteObserver(this); + for (int i = particles.size - 1; i >= 0 && particles.size > 0; i--) { + particles.get(i).free(); + particles.clear(); + } + super.dispose(); + } + + @Override + public void setCameraPositionToPage(Vector3 cameraPosition) { + getStage().setScrollFocus(null); + playParticles = true; + super.setCameraPositionToPage(cameraPosition); + } + + @Override + public void update(Observable o, Object arg) { + if (o == mc) { + if (arg == mc.states.LOADED) { + if (amc.isSameSizeMusicList()) { + scrollText.setText("Currently playing: " + amc.getAudioMetadata(mc.getCurrentMusicFileHandle()).getTitle(), null); + } else { + scrollText.setText("Currently playing: " + mc.getCurrentMusicFileHandle().nameWithoutExtension().replace('_', ' '), null); + } + } else if (arg == mc.states.PAUSED) { + if (amc.isSameSizeMusicList()) { + scrollText.setText("Currently paused: " + amc.getAudioMetadata(mc.getCurrentMusicFileHandle()).getTitle(), null); + } else { + scrollText.setText("Currently paused: " + mc.getCurrentMusicFileHandle().nameWithoutExtension().replace('_', ' '), null); + } + } + } else if (o == amc) { + if (amc.isSameSizeMusicList()) { + scrollText.setText("Currently playing: " + amc.getAudioMetadata(mc.getCurrentMusicFileHandle()).getTitle(), null); + } + } else if (o == mc.getMusicList()) { + if (arg == mc.getMusicList().states.EMPTY) { + scrollText.setText("Couldn't find MP3/WAV files", null); + } else if (arg == mc.getMusicList().states.LOADING) { + scrollText.setText("Loading...", null); + } + } + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MainScreen.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MainScreen.java new file mode 100644 index 0000000..bc8270e --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MainScreen.java @@ -0,0 +1,248 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.viewport.ScreenViewport; + +import zero1hd.rhythmbullet.RhythmBullet; +import zero1hd.rhythmbullet.audio.AudioMetadataController; +import zero1hd.rhythmbullet.audio.MusicList; +import zero1hd.rhythmbullet.audio.MusicController; +import zero1hd.rhythmbullet.desktop.audio.processor.DesktopAudioProcessorFactory; +import zero1hd.rhythmbullet.graphics.shaders.BloomShader; +import zero1hd.rhythmbullet.graphics.ui.Page; +import zero1hd.rhythmbullet.util.ResizeReadyScreen; + +public class MainScreen extends ScreenAdapter implements ResizeReadyScreen { + private Stage stage; + private Vector3 cameraPosition; + private PageChangeListeners listeners; + private String selectedPage; + private MainPage mainPage; + private OptionsPage optionsPage; + private KeybindPage keybindPage; + private GraphicsPage graphicsPage; + private CreditsPage creditsPage; + private MusicSelectionPage musicSelectionPage; + private AnalysisPage analysisPage; + + private MusicController musicController; + private AudioMetadataController musicMetadataController; + + private RhythmBullet rhythmBullet; + + private BloomShader bloomShader; + + private Texture background; + + private Batch screenBatch; + private boolean resizing; + + public MainScreen(RhythmBullet core) { + this.rhythmBullet = core; + stage = new Stage(new ScreenViewport()); + cameraPosition = new Vector3(stage.getCamera().position); + + MusicList musicList = new MusicList(new DesktopAudioProcessorFactory(), core.getPreferences().getString("music dir")); + musicController = new MusicController(musicList, core.getPreferences()); + musicController.setAutoPlay(true); + musicController.setShuffle(true); + musicMetadataController = new AudioMetadataController(musicList); + + listeners = new PageChangeListeners(); + screenBatch = new SpriteBatch(); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(0f, 0f, 0f, 1f); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + if (!resizing) { + stage.act(delta); + if (bloomShader != null) { + bloomShader.begin(); + draw(); + bloomShader.end(stage.getWidth(), stage.getHeight()); + } else { + draw(); + } + } + if (stage.getCamera().position.x != cameraPosition.x || stage.getCamera().position.y != cameraPosition.y) { + stage.getCamera().position.lerp(cameraPosition, 0.15f); + stage.getViewport().apply(); + } + super.render(delta); + } + + private void draw() { + stage.getViewport().apply(); + screenBatch.begin(); + screenBatch.draw(background, 0, 0, stage.getViewport().getScreenWidth(), stage.getViewport().getScreenHeight()); + screenBatch.end(); + stage.draw(); + } + + @Override + public void preAssetLoad() { + resizing = true; + stage.clear(); + if (bloomShader != null) { + bloomShader.dispose(); + bloomShader = null; + } + background = null; + musicController.deleteObservers(); + musicMetadataController.deleteObservers(); + } + + @Override + public void postAssetLoad() { + resizing = false; + bloomShader = new BloomShader(screenBatch); + + background = rhythmBullet.getAssetManager().get("backgrounds/mainBG.png", Texture.class); + + mainPage = new MainPage(musicController, musicMetadataController, rhythmBullet.getAssetManager(), rhythmBullet.getSkin(), rhythmBullet.getScreenConfiguration(), listeners.musicSelectionPageButtonListener, listeners.optionsPageButtonListener); + stage.addActor(mainPage); + //End main menu + + optionsPage = new OptionsPage(musicController, rhythmBullet.getSkin(), rhythmBullet.getPreferences(), listeners.returnToMainPageListener, listeners.graphicsPageButtonListener, listeners.keybindPageButtonListener); + stage.addActor(optionsPage); + + keybindPage = new KeybindPage(rhythmBullet.getAssetManager(), rhythmBullet.getSkin(), listeners.optionsPageButtonListener); + stage.addActor(keybindPage); + + graphicsPage = new GraphicsPage(rhythmBullet.getSkin(), rhythmBullet.getPreferences(), listeners.optionsPageButtonListener); + stage.addActor(graphicsPage); + + creditsPage = new CreditsPage(rhythmBullet.getSkin()); + stage.addActor(creditsPage); + + musicSelectionPage = new MusicSelectionPage(rhythmBullet.getAssetManager(), rhythmBullet.getSkin(), musicController, musicMetadataController, rhythmBullet.getScreenConfiguration(), listeners.returnToMainPageListener, listeners.analysisPageButtonListener); + stage.addActor(musicSelectionPage); + + analysisPage = new AnalysisPage(musicController, musicMetadataController, rhythmBullet.getSkin(), listeners.musicSelectionPageButtonListener, listeners.confirmedSongListener); + stage.addActor(analysisPage); + + musicController.getMusicList().attemptAsyncSearch(false); + + if (selectedPage != null) { + for (Actor actor : stage.getActors().items) { + if (actor.getName().equals(selectedPage)) { + setDisplayedPage((Page) actor); + break; + } + } + } + } + + @Override + public void show() { + Gdx.input.setInputProcessor(stage); + super.show(); + } + + @Override + public void hide() { + saveAll(); + super.hide(); + } + + public void saveAll() { + if (optionsPage != null) { + optionsPage.saveOptions(); + rhythmBullet.getPreferences().flush(); + } + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, false); + super.resize(width, height); + } + + @Override + public void dispose() { + Gdx.app.debug("Mainscreen", "disposing..."); + stage.dispose(); + musicMetadataController.dispose(); + screenBatch.dispose(); + super.dispose(); + } + + public void setDisplayedPage(Page page) { + Gdx.app.debug("Mainscreen", "Switching to " + page.getName()); + page.setCameraPositionToPage(cameraPosition); + this.selectedPage = page.getName(); + } + + private class PageChangeListeners { + ChangeListener musicSelectionPageButtonListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDisplayedPage(musicSelectionPage); + mainPage.stopParticles(); + } + }; + + ChangeListener analysisPageButtonListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDisplayedPage(analysisPage); + } + }; + + ChangeListener returnToMainPageListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDisplayedPage(mainPage); + } + }; + + ChangeListener optionsPageButtonListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDisplayedPage(optionsPage); + mainPage.stopParticles(); + } + }; + + ChangeListener graphicsPageButtonListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDisplayedPage(graphicsPage); + } + }; + + ChangeListener keybindPageButtonListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDisplayedPage(keybindPage); + } + }; + + ChangeListener creditPageButtonListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + setDisplayedPage(creditsPage); + mainPage.stopParticles(); + } + }; + + ChangeListener confirmedSongListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + + } + }; + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MusicSelectionPage.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MusicSelectionPage.java new file mode 100644 index 0000000..198bd8b --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/MusicSelectionPage.java @@ -0,0 +1,585 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import java.util.Observable; +import java.util.Observer; +import java.util.concurrent.LinkedBlockingQueue; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input.Keys; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Array; + +import zero1hd.rhythmbullet.audio.AudioMetadataController; +import zero1hd.rhythmbullet.audio.metadata.AudioMetadata; +import zero1hd.rhythmbullet.audio.MusicController; +import zero1hd.rhythmbullet.graphics.ui.Page; +import zero1hd.rhythmbullet.graphics.ui.components.ScrollingText; +import zero1hd.rhythmbullet.util.ScreenConfiguration; + +public class MusicSelectionPage extends Page implements Observer { + Preferences musicFileAnnotation; + + private MusicController mc; + private AudioMetadataController mmc; + private MusicSelectableButtonGroup selectables; + private VerticalGroup vGroup; + private TextButton back; + private ScrollPane scrollPane; + private ScreenConfiguration screenConfig; + + private musicSelectionLoaderThread selectionLoaderThread; + + private InformationTable musicInfoTable; + + private AssetManager assets; + private Skin skin; + + private boolean down, up; + + private boolean frameUsed; + + private TextButton beginButton; + + private float scrollTimer, scrollDelay = 0.2f, scrollDelMod, songSelectionTimer; + private float musicSelectDelay; + + public MusicSelectionPage(AssetManager assetManager, Skin skin, MusicController musicController, AudioMetadataController musicMetadataController, ScreenConfiguration screenConfiguration, ChangeListener backButtonListener, ChangeListener beginButtonListener) { + super(1, 0); + this.assets = assetManager; + this.mc = musicController; + this.mmc = musicMetadataController; + this.skin = skin; + vGroup = new VerticalGroup(); + vGroup.space(10f); + selectables = new MusicSelectableButtonGroup(); + selectables.setMinCheckCount(0); + musicFileAnnotation = Gdx.app.getPreferences("music_file_annotation"); + this.screenConfig = screenConfiguration; + scrollPane = new ScrollPane(vGroup, skin); + scrollPane.setSize(0.45f*getWidth(), getHeight()); + scrollPane.setOverscroll(false, false); + scrollPane.setColor(Color.BLUE); + addActor(scrollPane); + back = new TextButton("Back", skin); + back.setWidth(back.getWidth()+20f); + back.setPosition(getWidth()-back.getWidth()-15f, getHeight() - back.getHeight() - 15f); + back.addListener(backButtonListener); + addActor(back); + back.toFront(); + + addListener(new InputListener() { + @Override + public boolean keyDown(InputEvent event, int keycode) { + scrollTimer = 0; + scrollDelMod = 1f; + if (keycode == Keys.DOWN) { + down = true; + } + if (keycode == Keys.UP) { + up = true; + } + return super.keyDown(event, keycode); + } + + @Override + public boolean keyUp(InputEvent event, int keycode) { + if (keycode == Keys.DOWN) { + down = false; + } + + if (keycode == Keys.UP) { + up = false; + } + return super.keyUp(event, keycode); + } + }); + + musicInfoTable = new InformationTable(getWidth()-scrollPane.getWidth(), getHeight()); + addActor(musicInfoTable); + + beginButton = new TextButton("Begin", skin); + beginButton.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + if (musicSelectDelay != 0) { + mc.setMusicByFileHandle(getSelectedMusic()); + musicSelectDelay = 0f; + } + } + }); + beginButton.addListener(beginButtonListener); + mmc.addObserver(this); + mc.addObserver(this); + mc.getMusicList().addObserver(this); + selectionLoaderThread = new musicSelectionLoaderThread(); + + musicInfoTable.setToDefault(); + } + + @Override + public void act(float delta) { + + if (frameUsed) { + frameUsed = false; + } + + if (down) { + if (scrollDelMod > 0.25f) { + scrollDelMod -= delta/0.5f; + } + if (scrollTimer <= 0) { + scrollTimer = scrollDelay*scrollDelMod; + scrollDown(); + + } else { + scrollTimer -= delta; + } + } + + if (up) { + if (scrollDelMod > 0.25f) { + scrollDelMod -= delta/0.5f; + } + if (scrollTimer <= 0) { + scrollTimer = scrollDelay*scrollDelMod; + scrollUp(); + } else { + scrollTimer -= delta; + } + } + + if (songSelectionTimer > 0f) { + songSelectionTimer -= delta; + if (songSelectionTimer <= 0f) { + } + } + if (mc.getMusicList().isSearched()) { + if (mc.getMusicList().getTotal() != 0) { + + } + } + + updateList(delta); + + super.act(delta); + } + + private synchronized void updateList(float delta) { + if (mc.getMusicList().isSearched()) { + if (mc.getMusicList().getTotal() != 0) { + if (mmc.isSameSizeMusicList() && !mmc.isSearching()) { + if (selectables.size() != mmc.size()) { + MusicSelectable selectable = new MusicSelectable(mmc.getAudioMetadata(selectables.size())); + selectables.add(selectable); + } else if (selectables.size() != vGroup.getChildren().size) { + vGroup.addActor(selectables.getButtons().get(vGroup.getChildren().size)); + } else { + if (selectables.getChecked() == null) { + selectables.setMinCheckCount(1); + selectables.setChecked(mc.getCurrentMusicFileHandle()); + scrollPane.scrollTo(selectables.getChecked().getX(), selectables.getChecked().getY(), selectables.getChecked().getWidth(), selectables.getChecked().getHeight()); + } else if (selectables.getChecked().getMetadata().getFileHandle() != mc.getCurrentMusicFileHandle()) { + musicSelectDelay += delta; + if (musicSelectDelay >= 1f) { + mc.setMusicByFileHandle(selectables.getChecked().getMetadata().getFileHandle()); + musicSelectDelay = 0; + } + } + } + } + + } else { + //TODO: Error message reporting empty music list or something + } + } + } + + private void scrollDown() { + if (selectables.selectNext()) { + scrollPane.scrollTo(selectables.getChecked().getX(), selectables.getChecked().getY(), selectables.getChecked().getWidth(), selectables.getChecked().getHeight()); + } + } + + private void scrollUp() { + if (selectables.selectPrevious()) { + scrollPane.scrollTo(selectables.getChecked().getX(), selectables.getChecked().getY(), selectables.getChecked().getWidth(), selectables.getChecked().getHeight()); + } + } + + public FileHandle getSelectedMusic() { + return selectables.getChecked().getMetadata().getFileHandle(); + } + + @Override + public void dispose() { + mc.getMusicList().deleteObserver(this); + selectionLoaderThread.stop(); + super.dispose(); + } + + @Override + public void update(Observable o, Object arg) { + if (o == mmc) { + selectionLoaderThread.start(); + } else if (o == mc) { + if (selectables.getChecked() != null && mc.getMusicList().getTotal() == selectables.size() && mc.getCurrentMusicFileHandle() != selectables.getChecked().getMetadata().getFileHandle()) { + selectables.setChecked(mc.getCurrentMusicFileHandle()); + } + } else if (o == mc.getMusicList()) { + if (arg == mc.getMusicList().states.LOADING) { + synchronized (this) { + vGroup.clear(); + selectables.clear(); + musicInfoTable.setToDefault(); + selectionLoaderThread.clear(); + } + } + + } + } + + @Override + public void setCameraPositionToPage(Vector3 cameraPosition) { + getStage().setKeyboardFocus(this); + getStage().setScrollFocus(scrollPane); + super.setCameraPositionToPage(cameraPosition); + } + + private class musicSelectionLoaderThread implements Runnable { + private Thread thread; + private String name = "Music-Selection-Loader-Thread"; + private volatile boolean work = true; + private LinkedBlockingQueue queue; + public musicSelectionLoaderThread() { + queue = new LinkedBlockingQueue<>(); + } + + @Override + public void run() { + while (work) { + try { + MusicSelectable selectable = queue.take(); + if (!selectable.isOffScreen()) { + selectable.getMetadata().loadAlbumCover(); + selectable.loadAttempted(); + simpleDebug("Loaded album cover of " + selectable.getMetadata().getTitle()); + } else { + simpleDebug("Skipping " + selectable.getMetadata().getTitle()); + } + } catch (InterruptedException e) { + simpleDebug("Thread was interupted."); + } + } + } + + public boolean start() { + if (thread == null) { + thread = new Thread(this, name); + thread.setDaemon(true); + thread.start(); + return true; + } + return false; + } + + public void stop() { + clear(); + if (thread != null) { + thread.interrupt(); + } + work = false; + } + + public void clear() { + queue.clear(); + } + + public void queue(MusicSelectable selectable) { + queue.add(selectable); + } + + } + + private class MusicSelectable extends Button { + private Vector2 actualCoords; + private Image albumCoverImage; + private Table informationTable; + private Label name, artist; + private Label time; + private float timeSinceChanged; + private AudioMetadata metadata; + private Texture defaultAlbumArt; + private TextureRegion albumArtTexture; + private volatile boolean offScreen, albumArtDisplayed, albumArtQueued, noReset; + + public MusicSelectable(AudioMetadata metadata) { + super(skin, "selectable-button"); + + this.metadata = metadata; + this.defaultAlbumArt = assets.get("defaultCover.png"); + albumArtTexture = new TextureRegion(defaultAlbumArt); + + albumCoverImage = new Image(); + updateAlbumArtImage(defaultAlbumArt); + + informationTable = new Table(); + informationTable.row().width(0.75f*getWidth()); + name = new Label(metadata.getTitle(), skin, "default-font", skin.getColor("default")); + name.setEllipsis(true); + informationTable.add(name).colspan(2).left().expand(); + informationTable.row(); + artist = new Label(metadata.getAuthor(), skin, "sub-font", skin.getColor("default")); + artist.setEllipsis(true); + informationTable.add(artist).left().width(getWidth()*0.375f); + time = new Label(metadata.getDuration(), skin, "sub-font", skin.getColor("default")); + informationTable.add(time).right(); + add(informationTable).spaceRight(15f).padLeft(15f); + + add(albumCoverImage).right().expandX().size(informationTable.getMinHeight()); + + albumCoverImage.setSize(100, 100); + actualCoords = new Vector2(); + } + + @Override + public void act(float delta) { + actualCoords.x = getX() + getParent().getX(); + actualCoords.y = getY() + getParent().getY(); + + if ((actualCoords.y < 0 - getHeight() - getStage().getHeight()*0.5f || actualCoords.y > getStage().getHeight()*1.5f) && selectables.getChecked() != this) { + offScreenAct(delta); + } else { + onScreenAct(delta); + } + super.act(delta); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + super.draw(batch, parentAlpha); + } + + public void onScreenAct(float delta) { + if (offScreen) { + offScreen = false; + timeSinceChanged = 0; + } else if (timeSinceChanged < 0.05f) { + timeSinceChanged += delta; + } else { + if (!frameUsed && metadata.getAlbumCover() != null && !albumArtDisplayed) { + updateAlbumArtImage(metadata.getAlbumCover()); + albumArtDisplayed = true; + frameUsed = true; + } else if (!albumArtQueued) { + selectionLoaderThread.queue(this); + albumArtQueued = true; + } + } + } + + private void updateAlbumArtImage(Texture texture) { + if (texture == null) throw new IllegalArgumentException("Texture can't be null!"); + albumArtTexture.setRegion(texture); + albumCoverImage.setDrawable(new TextureRegionDrawable(albumArtTexture)); + } + + public void offScreenAct(float delta) { + if (!offScreen) { + offScreen = true; + timeSinceChanged = 0; + } + if (metadata.getAlbumCover() != null) { + timeSinceChanged += delta; + if (timeSinceChanged >= 2) { + updateAlbumArtImage(defaultAlbumArt); + metadata.unloadAlbumCover(); + albumArtDisplayed = false; + albumArtQueued = false; + noReset = false; + } + } + } + + public AudioMetadata getMetadata() { + return metadata; + } + + public FileHandle getFileHandle() { + return metadata.getFileHandle(); + } + + @Override + public float getPrefWidth() { + return scrollPane.getScrollWidth(); + } + + @Override + public float getPrefHeight() { + return super.getPrefHeight(); + } + + public TextureRegion getAlbumArtTexture() { + return albumArtTexture; + } + + public boolean isOffScreen() { + if (offScreen && !noReset) { + albumArtDisplayed = false; + albumArtQueued = false; + } + return offScreen; + } + + public void loadAttempted() { + noReset = true; + } + } + + private class MusicSelectableButtonGroup extends ButtonGroup { + private Array buttons; + + public MusicSelectableButtonGroup() { + buttons = getButtons(); + } + + public void setChecked(FileHandle fileHandle) { + if (fileHandle == null) throw new IllegalArgumentException("fileHandle can't be null."); + MusicSelectable button; + for (int i = 0; i < buttons.size; i++) { + button = buttons.get(i); + if (button.getFileHandle() == fileHandle) { + button.setChecked(true); + return; + } + } + + } + + public boolean selectNext() { + int index = getCheckedIndex() + 1; + if (index == buttons.size) { + return false; + } + buttons.get(index).setChecked(true); + return true; + } + + public boolean selectPrevious() { + int index = getCheckedIndex() - 1; + if (index == -1) { + return false; + } + buttons.get(index).setChecked(true); + return true; + } + + @Override + protected boolean canCheck(MusicSelectable button, boolean newState) { + if (newState) { + musicInfoTable.setDisplayedSelectable(button); + musicSelectDelay = 0f; + } + return super.canCheck(button, newState); + } + + public int size() { + return buttons.size; + } + } + + private class InformationTable extends Table { + private ScrollingText songTitle; + private Label author; + private Label musicDuration; + private Label previousTop; + private Label ratedDifficulty; + private Image albumCover; + + private Table subInformation; + + public InformationTable(float width, float height) { + defaults().center(); + setPosition(scrollPane.getWidth() + scrollPane.getX(), 0); + setSize(width, height); + subInformation = new Table(skin); + albumCover = new Image(assets.get("defaultCover.png", Texture.class)); + songTitle = new ScrollingText("", null, skin, true, true, 1f/screenConfig.getTargetFramesPerSecond()); + author = new Label(null, skin, "sub-font", skin.getColor("default")); + musicDuration = new Label(null, skin, "sub-font", skin.getColor("default")); + previousTop = new Label(null, skin, "sub-font", skin.getColor("default")); + ratedDifficulty = new Label(null, skin, "sub-font", skin.getColor("default")); + } + + public void setDisplayedSelectable(MusicSelectable displayedSelectable) { + if (displayedSelectable != null) { + AudioMetadata metadata = displayedSelectable.getMetadata(); + albumCover.setDrawable(new TextureRegionDrawable(displayedSelectable.getAlbumArtTexture())); + songTitle.setText(metadata.getTitle(), null); + author.setText(metadata.getAuthor()); + musicDuration.setText(metadata.getDuration()); + //TODO previous top + //TODO rated difficulty + beginButton.setDisabled(false); + } else { + albumCover.setDrawable(new TextureRegionDrawable(new TextureRegion(assets.get("defaultCover.png", Texture.class)))); + songTitle.setText("loading...", null); + author.setText("..."); + musicDuration.setText("..."); + previousTop.setText("..."); + ratedDifficulty.setText("..."); + } + } + + public void setToDefault() { + clear(); + subInformation.clear(); + + albumCover.setDrawable(new TextureRegionDrawable(new TextureRegion(assets.get("defaultCover.png", Texture.class)))); + add(albumCover).size(getWidth()/2f).spaceBottom(25f); + row(); + songTitle.setText("...", null); + add(songTitle).width(getWidth()*0.6f).spaceBottom(30f); + row(); + author.setText("..."); + author.setEllipsis(true); + author.setAlignment(Align.center); + subInformation.add(author).expand(); + subInformation.row(); + musicDuration.setText("..."); + subInformation.add(musicDuration); + subInformation.row(); + previousTop.setText("..."); + subInformation.add(previousTop); + subInformation.row(); + ratedDifficulty.setText("..."); + subInformation.add(ratedDifficulty); + add(subInformation).width(0.4f*getWidth()); + row(); + add(beginButton).spaceTop(20f).fillX(); + beginButton.setDisabled(true); + } + } +} diff --git a/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/OptionsPage.java b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/OptionsPage.java new file mode 100644 index 0000000..9fdf0dc --- /dev/null +++ b/old/desktop/src/zero1hd/rhythmbullet/desktop/screens/main/OptionsPage.java @@ -0,0 +1,163 @@ +package zero1hd.rhythmbullet.desktop.screens.main; + +import java.text.NumberFormat; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Preferences; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Slider; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextField; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; + +import zero1hd.rhythmbullet.audio.MusicController; +import zero1hd.rhythmbullet.graphics.ui.Page; + +public class OptionsPage extends Page { + Table optionsTable; + private ProgressBar musicVolSlider; + private ProgressBar fxVolSlider; + private TextField directoryField; + private float musicSearchTimer; + private Preferences prefs; + private NumberFormat percentFormat; + + public OptionsPage(MusicController musicController, Skin skin, Preferences preferences, ChangeListener backButtonListener, ChangeListener graphicsButtonListener, ChangeListener controlsButtonListener) { + super(-1, 0, "General", skin); + this.prefs = preferences; + percentFormat = NumberFormat.getPercentInstance(); + percentFormat.setMaximumFractionDigits(1); + + //Back button + TextButton backButton = new TextButton("Back", skin); + backButton.addListener(backButtonListener); + backButton.setWidth(backButton.getWidth() + 20); + backButton.setPosition(getWidth() - backButton.getWidth() - 10, getHeightBelowTitle() + 5); + addActor(backButton); + + optionsTable = new Table(); + optionsTable.defaults().space(10f); + + addActor(optionsTable); + + Label musicVolSliderLabel = new Label("Music Volume: ", skin); + optionsTable.add(musicVolSliderLabel); + musicVolSlider = new Slider(0, 100, 1f, false, skin); + musicVolSlider.setValue(preferences.getFloat("music vol", 100f)); + optionsTable.add(musicVolSlider).minWidth(0.3f*getWidth()); + final Label musicVolPercentage = new Label(percentFormat.format(musicVolSlider.getPercent()), skin); + musicVolSlider.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + musicVolPercentage.setText(percentFormat.format(musicVolSlider.getPercent())); + musicController.getCurrentMusic().setVolume(musicVolSlider.getPercent()); + preferences.putFloat("music vol", musicVolSlider.getValue()); + } + }); + optionsTable.add(musicVolPercentage).expandX().left(); + + optionsTable.row(); + + Label fxVolSliderLabel = new Label("FX Volume: ", skin); + optionsTable.add(fxVolSliderLabel); + fxVolSlider = new Slider(0, 100, 1f, false, skin); + fxVolSlider.setValue(preferences.getFloat("fx vol", 100f)); + optionsTable.add(fxVolSlider).fillX(); + final Label fxVolPercentage = new Label(percentFormat.format(fxVolSlider.getPercent()), skin); + fxVolSlider.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + fxVolPercentage.setText(percentFormat.format(fxVolSlider.getPercent())); + preferences.putFloat("fx vol", fxVolSlider.getValue()); + } + }); + + optionsTable.add(fxVolPercentage).left(); + + optionsTable.row(); + + Label musicDirectoryLabel = new Label("Music Directory: ", skin); + optionsTable.add(musicDirectoryLabel); + directoryField = new TextField(null, skin ) { + @Override + public void act(float delta) { + if (musicSearchTimer > 0) { + musicSearchTimer -= delta; + if (musicSearchTimer <= 0) { + musicController.getMusicList().setSearchPath(directoryField.getText()); + musicController.getMusicList().attemptAsyncSearch(false); + } + } + super.act(delta); + } + }; + directoryField.setText(preferences.getString("music dir", System.getProperty("user.home")+System.getProperty("file.separator")+"Music")); + directoryField.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + musicSearchTimer = 2; + } + }); + optionsTable.add(directoryField).fillX(); + + optionsTable.row(); + + TextButton keybindSettings = new TextButton("Set Controls", skin); + keybindSettings.addListener(controlsButtonListener); + optionsTable.add(keybindSettings).colspan(2).fillX(); + + optionsTable.row(); + + TextButton graphicsSettings = new TextButton("Graphics", skin); + graphicsSettings.addListener(graphicsButtonListener); + optionsTable.add(graphicsSettings).colspan(2).fillX(); + + optionsTable.row(); + + Label fpsLabel = new Label("", skin) { + @Override + public void act(float delta) { + setText("Current FPS: " + Gdx.graphics.getFramesPerSecond()); + super.act(delta); + } + }; + optionsTable.add(fpsLabel).colspan(2); + + optionsTable.row(); + + Label usageLabel = new Label("Current Usage (JVM): ", skin) { + float refreshTime = 20; + @Override + public void act(float delta) { + refreshTime -= delta; + if (refreshTime <= 0) { + refreshTime = 4; + String formatted = percentFormat.format(((float)(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/(float)Runtime.getRuntime().totalMemory())); + setText("Current usage (JVM): " + formatted); + } + super.act(delta); + } + }; + + optionsTable.add(usageLabel).colspan(2); + + optionsTable.pack(); + optionsTable.setX((getWidth()-optionsTable.getWidth())/2f); + optionsTable.setSize(getWidth() - optionsTable.getX(), backButton.getY()); + } + + public void saveOptions() { + prefs.putString("music dir", directoryField.getText()); + Gdx.app.debug("Preferences", "Saved all basic options page values."); + } + + @Override + public void dispose() { + saveOptions(); + super.dispose(); + } +} diff --git a/old/gradle.properties b/old/gradle.properties new file mode 100644 index 0000000..ff329ac --- /dev/null +++ b/old/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.daemon=true +org.gradle.jvmargs=-Xms128m -Xmx1500m +org.gradle.configureondemand=false diff --git a/old/gradle/wrapper/gradle-wrapper.jar b/old/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..bafc550 Binary files /dev/null and b/old/gradle/wrapper/gradle-wrapper.jar differ diff --git a/old/gradle/wrapper/gradle-wrapper.properties b/old/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..9f7b58b --- /dev/null +++ b/old/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 09 23:06:52 EDT 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip diff --git a/old/gradlew b/old/gradlew new file mode 100644 index 0000000..4453cce --- /dev/null +++ b/old/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/old/gradlew.bat b/old/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/old/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/old/settings.gradle b/old/settings.gradle new file mode 100644 index 0000000..77ae463 --- /dev/null +++ b/old/settings.gradle @@ -0,0 +1 @@ +include 'desktop', 'android', 'core' \ No newline at end of file