1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 22:43:24 +08:00

Compare commits

...

6039 Commits

958 changed files with 63114 additions and 15008 deletions
+52 -22
View File
@@ -1,36 +1,66 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch VisualTests",
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop.VisualTests/bin/Debug/osu!.exe",
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": "build",
"runtimeExecutable": null,
"env": {},
"externalConsole": false
},
{
"name": "Launch Desktop",
"configurations": [{
"name": "osu! VisualTests (Debug)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop/bin/Debug/osu!.exe",
"args": [],
"args": [
"--tests"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "build",
"preLaunchTask": "Build (Debug)",
"runtimeExecutable": null,
"env": {},
"externalConsole": false
"console": "internalConsole"
},
{
"name": "Attach",
"name": "osu! VisualTests (Release)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "attach",
"address": "localhost",
"port": 55555
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop/bin/Release/osu!.exe",
"args": [
"--tests"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "osu! (Debug)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop/bin/Debug/osu!.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "osu! (Release)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop/bin/Release/osu!.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
}
]
}
+55 -17
View File
@@ -1,26 +1,64 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"windows": {
"command": "msbuild"
},
"linux": {
"command": "xbuild"
},
"version": "2.0.0",
"command": "msbuild",
"type": "shell",
"suppressTaskName": true,
"args": [
// Ask msbuild to generate full paths for file names.
"/property:GenerateFullPaths=true"
"/property:GenerateFullPaths=true",
"/property:DebugType=portable",
"/verbosity:minimal",
"/m" //parallel compiling support.
],
"taskSelector": "/t:",
"showOutput": "silent",
"tasks": [
"tasks": [{
"taskName": "Build (Debug)",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$msCompile"
]
},
{
"taskName": "build",
// Show the output window only if unrecognized errors occur.
"showOutput": "silent",
// Use the standard MS compiler pattern to detect errors, warnings and infos
"problemMatcher": "$msCompile"
"taskName": "Build (Release)",
"group": "build",
"args": [
"/property:Configuration=Release"
],
"problemMatcher": [
"$msCompile"
]
},
{
"taskName": "Clean (Debug)",
"args": [
"/target:Clean"
],
"problemMatcher": [
"$msCompile"
]
},
{
"taskName": "Clean (Release)",
"args": [
"/target:Clean",
"/property:Configuration=Release"
],
"problemMatcher": [
"$msCompile"
]
},
{
"taskName": "Clean All",
"dependsOn": [
"Clean (Debug)",
"Clean (Release)"
],
"problemMatcher": [
"$msCompile"
]
}
]
}
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="opentk-develop" value="https://www.myget.org/F/opentk-develop" />
</packageSources>
</configuration>
+5 -9
View File
@@ -1,10 +1,6 @@
# osu! [![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu)
# osu! [![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu) [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu) [![dev chat](https://discordapp.com/api/guilds/188630481301012481/widget.png?style=shield)](https://discord.gg/ppy)
[osu! on the web](https://osu.ppy.sh) | [dev chat](https://discord.gg/ppy)
Rhythm is just a *click* away. The future of osu! and the beginning of an open era!
Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the beginning of an open era!
# Status
@@ -12,14 +8,14 @@ This is still heavily under development and is not intended for end-user use. Th
# Requirements
- A desktop platform which can compile .NET 4.5.
- Visual Studio or MonoDevelop is recommended.
- A desktop platform which can compile .NET 4.5 (tested on macOS, linux and windows). We recommend using [Visual Studio Code](https://code.visualstudio.com/) (all platforms) or [Visual Studio Community Edition](https://www.visualstudio.com/) (windows only), both of which are free.
- Make sure you initialise and keep submodules up-to-date.
# Contributing
We welcome all contributions, but keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention on having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time, to ensure no effort is wasted.
Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://goo.gl/nFdoyI). If you're unsure of what you can help with, check out the [list](https://github.com/ppy/osu/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Abounty) of available issues with bounty.
Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://www.bountysource.com/teams/ppy). If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu-framework/issues).
Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. I welcome all feedback so we can make contributing to this project as pain-free as possible.
+25
View File
@@ -0,0 +1,25 @@
# 2017-09-14
clone_depth: 1
version: '{branch}-{build}'
image: Visual Studio 2017
configuration: Debug
cache:
- C:\ProgramData\chocolatey\bin -> appveyor.yml
- C:\ProgramData\chocolatey\lib -> appveyor.yml
- inspectcode -> appveyor.yml
- packages -> **\packages.config
install:
- cmd: git submodule update --init --recursive
- cmd: choco install resharper-clt -y
- cmd: choco install nvika -y
- cmd: appveyor DownloadFile https://github.com/peppy/CodeFileSanity/releases/download/v0.2.3/CodeFileSanity.exe
before_build:
- cmd: CodeFileSanity.exe
- cmd: nuget restore
build:
project: osu.sln
parallel: true
verbosity: minimal
after_build:
- cmd: inspectcode /o="inspectcodereport.xml" /caches-home="inspectcode" osu.sln
- cmd: NVika parsereport "inspectcodereport.xml" --treatwarningsaserrors
+12 -4
View File
@@ -1,4 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<appSettings>
<add key="StagingFolder" value="Staging" />
@@ -19,14 +23,18 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DeltaCompressionDotNet.MsDelta" publicKeyToken="46b2138a390abf55" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SharpCompress" publicKeyToken="afb0a02973931d96" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.18.1.0" newVersion="0.18.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
+5 -2
View File
@@ -1,8 +1,11 @@
using Newtonsoft.Json;
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
namespace osu.Desktop.Deploy
{
internal class GitHubObject
public class GitHubObject
{
[JsonProperty(@"id")]
public int Id;
+5 -2
View File
@@ -1,8 +1,11 @@
using Newtonsoft.Json;
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
namespace osu.Desktop.Deploy
{
internal class GitHubRelease
public class GitHubRelease
{
[JsonProperty(@"id")]
public int Id;
+25 -22
View File
@@ -1,5 +1,5 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.GitHubusercontent.com/ppy/osu-framework/master/LICENCE
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
@@ -7,7 +7,6 @@ using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using Newtonsoft.Json;
using osu.Framework.IO.Network;
using FileWebRequest = osu.Framework.IO.Network.FileWebRequest;
@@ -17,9 +16,9 @@ namespace osu.Desktop.Deploy
{
internal static class Program
{
private const string nuget_path = @"packages\NuGet.CommandLine.3.5.0\tools\NuGet.exe";
private const string squirrel_path = @"packages\squirrel.windows.1.5.2\tools\Squirrel.exe";
private const string msbuild_path = @"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe";
private const string nuget_path = @"packages\NuGet.CommandLine.4.3.0\tools\NuGet.exe";
private const string squirrel_path = @"packages\squirrel.windows.1.7.8\tools\Squirrel.exe";
private const string msbuild_path = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe";
public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"];
public static string ReleasesFolder = ConfigurationManager.AppSettings["ReleasesFolder"];
@@ -29,7 +28,7 @@ namespace osu.Desktop.Deploy
public static string SolutionName = ConfigurationManager.AppSettings["SolutionName"];
public static string ProjectName = ConfigurationManager.AppSettings["ProjectName"];
public static string NuSpecName = ConfigurationManager.AppSettings["NuSpecName"];
public static string TargetName = ConfigurationManager.AppSettings["TargetName"];
public static string TargetNames = ConfigurationManager.AppSettings["TargetName"];
public static string PackageName = ConfigurationManager.AppSettings["PackageName"];
public static string IconName = ConfigurationManager.AppSettings["IconName"];
public static string CodeSigningCertificate = ConfigurationManager.AppSettings["CodeSigningCertificate"];
@@ -40,7 +39,7 @@ namespace osu.Desktop.Deploy
/// <summary>
/// How many previous build deltas we want to keep when publishing.
/// </summary>
const int keep_delta_count = 3;
private const int keep_delta_count = 3;
private static string codeSigningCmd => string.IsNullOrEmpty(codeSigningPassword) ? "" : $"-n \"/a /f {codeSigningCertPath} /p {codeSigningPassword} /t http://timestamp.comodoca.com/authenticode\"";
@@ -53,7 +52,7 @@ namespace osu.Desktop.Deploy
private static string nupkgFilename(string ver) => $"{PackageName}.{ver}.nupkg";
private static string nupkgDistroFilename(string ver) => $"{PackageName}-{ver}-full.nupkg";
private static Stopwatch sw = new Stopwatch();
private static readonly Stopwatch sw = new Stopwatch();
private static string codeSigningPassword;
@@ -100,7 +99,8 @@ namespace osu.Desktop.Deploy
updateAssemblyInfo(version);
write("Running build process...");
runCommand(msbuild_path, $"/v:quiet /m /t:{TargetName.Replace('.', '_')} /p:OutputPath={stagingPath};Configuration=Release {SolutionName}.sln");
foreach (string targetName in TargetNames.Split(','))
runCommand(msbuild_path, $"/v:quiet /m /t:{targetName.Replace('.', '_')} /p:OutputPath={stagingPath};Targets=\"Clean;Build\";Configuration=Release {SolutionName}.sln");
write("Creating NuGet deployment package...");
runCommand(nuget_path, $"pack {NuSpecName} -Version {version} -Properties Configuration=Deploy -OutputDirectory {stagingPath} -BasePath {stagingPath}");
@@ -172,10 +172,10 @@ namespace osu.Desktop.Deploy
}
//remove excess deltas
var deltas = releaseLines.Where(l => l.Filename.Contains("-delta"));
if (deltas.Count() > keep_delta_count)
var deltas = releaseLines.Where(l => l.Filename.Contains("-delta")).ToArray();
if (deltas.Length > keep_delta_count)
{
foreach (var l in deltas.Take(deltas.Count() - keep_delta_count))
foreach (var l in deltas.Take(deltas.Length - keep_delta_count))
{
write($"- Removing old delta {l.Filename}", ConsoleColor.Yellow);
File.Delete(Path.Combine(ReleasesFolder, l.Filename));
@@ -198,7 +198,7 @@ namespace osu.Desktop.Deploy
write($"- Creating release {version}...", ConsoleColor.Yellow);
var req = new JsonWebRequest<GitHubRelease>($"{GitHubApiEndpoint}")
{
Method = HttpMethod.POST
Method = HttpMethod.POST,
};
req.AddRaw(JsonConvert.SerializeObject(new GitHubRelease
{
@@ -215,6 +215,7 @@ namespace osu.Desktop.Deploy
var upload = new WebRequest(assetUploadUrl, Path.GetFileName(a))
{
Method = HttpMethod.POST,
Timeout = 240000,
ContentType = "application/octet-stream",
};
@@ -261,7 +262,7 @@ namespace osu.Desktop.Deploy
if (!File.Exists(Path.Combine(ReleasesFolder, nupkgDistroFilename(lastRelease.Name))))
{
write("Last verion's package not found locally.", ConsoleColor.Red);
write("Last version's package not found locally.", ConsoleColor.Red);
requireDownload = true;
}
else
@@ -282,6 +283,8 @@ namespace osu.Desktop.Deploy
foreach (var a in assets)
{
if (a.Name.EndsWith(".exe")) continue;
write($"- Downloading {a.Name}...", ConsoleColor.Yellow);
new FileWebRequest(Path.Combine(ReleasesFolder, a.Name), $"{GitHubApiEndpoint}/assets/{a.Id}").AuthenticatedBlockingPerform();
}
@@ -337,12 +340,17 @@ namespace osu.Desktop.Deploy
WorkingDirectory = solutionPath,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
};
Process p = Process.Start(psi);
if (p == null) return false;
string output = p.StandardOutput.ReadToEnd();
output += p.StandardError.ReadToEnd();
if (p.ExitCode == 0) return true;
write(output);
@@ -382,8 +390,8 @@ namespace osu.Desktop.Deploy
public static void AuthenticatedBlockingPerform(this WebRequest r)
{
r.AddHeader("Authorization", $"token {GitHubAccessToken}");
r.BlockingPerform();
r.Headers.Add("Authorization", $"token {GitHubAccessToken}");
r.Perform();
}
}
@@ -393,12 +401,7 @@ namespace osu.Desktop.Deploy
{
}
protected override HttpWebRequest CreateWebRequest(string requestString = null)
{
var req = base.CreateWebRequest(requestString);
req.Accept = "application/octet-stream";
return req;
}
protected override string Accept => "application/octet-stream";
}
internal class ReleaseLine
@@ -1,7 +1,10 @@
using System.Reflection;
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// 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("osu.Desktop.Deploy")]
@@ -13,8 +16,8 @@ using System.Runtime.InteropServices;
[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
// 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)]
@@ -24,11 +27,11 @@ using System.Runtime.InteropServices;
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// 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")]
+18 -16
View File
@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Desktop.Deploy</RootNamespace>
<AssemblyName>osu.Desktop.Deploy</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
@@ -22,6 +22,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>6</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -48,10 +49,6 @@
<HintPath>$(SolutionDir)\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.PatchApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
<Private>True</Private>
@@ -68,20 +65,24 @@
<HintPath>$(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NuGet.Squirrel, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll</HintPath>
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\NuGet.Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.18.1.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SharpCompress.0.18.1\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Squirrel, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll</HintPath>
<Reference Include="Squirrel, Version=1.7.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
@@ -101,21 +102,22 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="..\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<None Include="App.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework.Desktop\osu.Framework.Desktop.csproj">
<Project>{65dc628f-a640-4111-ab35-3a5652bc1e17}</Project>
<Name>osu.Framework.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{C76BF5B3-985E-4D39-95FE-97C9C879B83A}</Project>
<Name>osu.Framework</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
+8 -3
View File
@@ -1,9 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net452" />
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="NuGet.CommandLine" version="3.5.0" targetFramework="net452" developmentDependency="true" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
<package id="NuGet.CommandLine" version="4.3.0" targetFramework="net461" developmentDependency="true" />
<package id="SharpCompress" version="0.18.1" targetFramework="net461" />
<package id="Splat" version="2.0.0" targetFramework="net452" />
<package id="squirrel.windows" version="1.5.2" targetFramework="net452" />
<package id="squirrel.windows" version="1.7.8" targetFramework="net461" />
</packages>
-32
View File
@@ -1,32 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using NUnit.Framework;
using osu.Desktop.VisualTests;
using osu.Framework.Desktop.Platform;
using osu.Game.Modes;
using osu.Game.Modes.Catch;
using osu.Game.Modes.Mania;
using osu.Game.Modes.Osu;
using osu.Game.Modes.Taiko;
namespace osu.Desktop.Tests
{
[TestFixture]
public class BenchmarkTest
{
[Test]
public void TestBenchmark()
{
using (var host = new HeadlessGameHost())
{
Ruleset.Register(new OsuRuleset());
Ruleset.Register(new TaikoRuleset());
Ruleset.Register(new ManiaRuleset());
Ruleset.Register(new CatchRuleset());
host.Run(new Benchmark());
}
}
}
}
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
-117
View File
@@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{230AC4F3-7783-49FB-9AEC-B83CDA3B9F3D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Desktop.Tests</RootNamespace>
<AssemblyName>osu.Desktop.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SQLite.Net, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="SQLiteNetExtensions">
<HintPath>$(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll</HintPath>
</Reference>
<Reference Include="SQLite.Net.Platform.Win32">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll</HintPath>
</Reference>
<Reference Include="SQLite.Net.Platform.Generic">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="BenchmarkTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework.Desktop\osu.Framework.Desktop.csproj">
<Project>{65DC628F-A640-4111-AB35-3A5652BC1E17}</Project>
<Name>osu.Framework.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{C76BF5B3-985E-4D39-95FE-97C9C879B83A}</Project>
<Name>osu.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj">
<Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project>
<Name>osu.Game.Resources</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Desktop.VisualTests\osu.Desktop.VisualTests.csproj">
<Project>{69051C69-12AE-4E7D-A3E6-460D2E282312}</Project>
<Name>osu.Desktop.VisualTests</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Catch\osu.Game.Modes.Catch.csproj">
<Project>{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}</Project>
<Name>osu.Game.Modes.Catch</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Mania\osu.Game.Modes.Mania.csproj">
<Project>{48F4582B-7687-4621-9CBE-5C24197CB536}</Project>
<Name>osu.Game.Modes.Mania</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Osu\osu.Game.Modes.Osu.csproj">
<Project>{C92A607B-1FDD-4954-9F92-03FF547D9080}</Project>
<Name>osu.Game.Modes.Osu</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Taiko\osu.Game.Modes.Taiko.csproj">
<Project>{F167E17A-7DE6-4AF5-B920-A5112296C695}</Project>
<Name>osu.Game.Modes.Taiko</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}</Project>
<Name>osu.Game</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="NUnit" version="3.5.0" targetFramework="net45" />
<package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />
</packages>
-45
View File
@@ -1,45 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Screens.Testing;
using osu.Game;
namespace osu.Desktop.VisualTests
{
public class Benchmark : OsuGameBase
{
private double timePerTest = 200;
[BackgroundDependencyLoader]
private void load()
{
Host.MaximumDrawHz = int.MaxValue;
Host.MaximumUpdateHz = int.MaxValue;
Host.MaximumInactiveHz = int.MaxValue;
}
protected override void LoadComplete()
{
base.LoadComplete();
TestBrowser f = new TestBrowser();
Add(f);
Console.WriteLine($@"{Time}: Running {f.TestCount} tests for {timePerTest}ms each...");
for (int i = 1; i < f.TestCount; i++)
{
int loadableCase = i;
Scheduler.AddDelayed(delegate
{
f.LoadTest(loadableCase);
Console.WriteLine($@"{Time}: Switching to test #{loadableCase}");
}, loadableCase * timePerTest);
}
Scheduler.AddDelayed(Host.Exit, f.TestCount * timePerTest);
}
}
}
@@ -1,29 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework;
using osu.Framework.Desktop.Platform;
using SQLite.Net;
using SQLite.Net.Interop;
using SQLite.Net.Platform.Generic;
using SQLite.Net.Platform.Win32;
namespace osu.Desktop.VisualTests.Platform
{
public class TestStorage : DesktopStorage
{
public TestStorage(string baseName) : base(baseName)
{
}
public override SQLiteConnection GetDatabase(string name)
{
ISQLitePlatform platform;
if (RuntimeInfo.IsWindows)
platform = new SQLitePlatformWin32();
else
platform = new SQLitePlatformGeneric();
return new SQLiteConnection(platform, $@":memory:");
}
}
}
-36
View File
@@ -1,36 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Desktop;
using osu.Framework.Platform;
using osu.Game.Modes;
using osu.Game.Modes.Catch;
using osu.Game.Modes.Mania;
using osu.Game.Modes.Osu;
using osu.Game.Modes.Taiko;
namespace osu.Desktop.VisualTests
{
public static class Program
{
[STAThread]
public static void Main(string[] args)
{
bool benchmark = args.Length > 0 && args[0] == @"-benchmark";
using (GameHost host = Host.GetSuitableHost(@"osu"))
{
Ruleset.Register(new OsuRuleset());
Ruleset.Register(new TaikoRuleset());
Ruleset.Register(new ManiaRuleset());
Ruleset.Register(new CatchRuleset());
if (benchmark)
host.Run(new Benchmark());
else
host.Run(new VisualTestGame());
}
}
}
}
@@ -1,93 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Screens.Testing;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Modes.Catch.UI;
using osu.Game.Modes.Mania.UI;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.Taiko.UI;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
{
class TestCaseGamefield : TestCase
{
public override string Name => @"Gamefield";
public override string Description => @"Showing hitobjects and what not.";
public override void Reset()
{
base.Reset();
List<HitObject> objects = new List<HitObject>();
int time = 500;
for (int i = 0; i < 100; i++)
{
objects.Add(new HitCircle()
{
StartTime = time,
Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)),
Scale = RNG.NextSingle(0.5f, 1.0f),
});
time += RNG.Next(50, 500);
}
Beatmap beatmap = new Beatmap
{
HitObjects = objects
};
Add(new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
//ensure we are at offset 0
Clock = new FramedClock(),
Children = new Drawable[]
{
new OsuHitRenderer
{
Beatmap = beatmap,
Scale = new Vector2(0.5f),
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft
},
new TaikoHitRenderer
{
Beatmap = beatmap,
Scale = new Vector2(0.5f),
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight
},
new CatchHitRenderer
{
Beatmap = beatmap,
Scale = new Vector2(0.5f),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
new ManiaHitRenderer
{
Beatmap = beatmap,
Scale = new Vector2(0.5f),
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight
}
}
}
});
}
}
}
@@ -1,92 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Graphics;
using OpenTK.Input;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Configuration;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.MathUtils;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
{
class TestCaseKeyCounter : TestCase
{
public override string Name => @"KeyCounter";
public override string Description => @"Tests key counter";
public override void Reset()
{
base.Reset();
KeyCounterCollection kc = new KeyCounterCollection
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
IsCounting = true,
Children = new KeyCounter[]
{
new KeyCounterKeyboard(@"Z", Key.Z),
new KeyCounterKeyboard(@"X", Key.X),
new KeyCounterMouse(@"M1", MouseButton.Left),
new KeyCounterMouse(@"M2", MouseButton.Right),
},
};
BindableInt bindable = new BindableInt { MinValue = 0, MaxValue = 200, Default = 50 };
bindable.ValueChanged += delegate { kc.FadeTime = bindable.Value; };
AddButton("Add Random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
kc.Add(new KeyCounterKeyboard(key.ToString(), key));
});
ButtonsContainer.Add(new SpriteText { Text = "FadeTime" });
ButtonsContainer.Add(new TestSliderBar<int>
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
Bindable = bindable
});
Add(kc);
}
private class TestSliderBar<T> : SliderBar<T> where T : struct
{
public Color4 Color
{
get { return Box.Colour; }
set { Box.Colour = value; }
}
public Color4 SelectionColor
{
get { return SelectionBox.Colour; }
set { SelectionBox.Colour = value; }
}
protected readonly Box SelectionBox;
protected readonly Box Box;
public TestSliderBar()
{
Children = new Drawable[]
{
Box = new Box { RelativeSizeAxes = Axes.Both },
SelectionBox = new Box { RelativeSizeAxes = Axes.Both }
};
}
protected override void UpdateValue(float value)
{
SelectionBox.ScaleTo(
new Vector2(value, 1),
300, EasingTypes.OutQuint);
}
}
}
}
@@ -1,37 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Graphics;
using osu.Framework.Timing;
using osu.Game.Overlays;
using osu.Framework.Graphics.Containers;
namespace osu.Desktop.VisualTests.Tests
{
class TestCaseMusicController : TestCase
{
public override string Name => @"Music Controller";
public override string Description => @"Tests music controller ui.";
private MusicController mc;
public TestCaseMusicController()
{
Clock = new FramedClock();
}
public override void Reset()
{
base.Reset();
Clock.ProcessFrame();
mc = new MusicController
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre
};
Add(mc);
AddToggle(@"Show", (state) => mc.State = state ? Visibility.Visible : Visibility.Hidden);
}
}
}
@@ -1,25 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Game.Overlays;
namespace osu.Desktop.VisualTests.Tests
{
class TestCaseOptions : TestCase
{
public override string Name => @"Options";
public override string Description => @"Tests the options overlay";
private OptionsOverlay options;
public override void Reset()
{
base.Reset();
Children = new[] { options = new OptionsOverlay() };
options.ToggleVisibility();
}
}
}
@@ -1,40 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Logging;
using osu.Game.Overlays.Pause;
using osu.Framework.Screens.Testing;
namespace osu.Desktop.VisualTests.Tests
{
class TestCasePauseOverlay : TestCase
{
public override string Name => @"PauseOverlay";
public override string Description => @"Tests the pause overlay";
private PauseOverlay pauseOverlay;
private int retryCount;
public override void Reset()
{
base.Reset();
Add(pauseOverlay = new PauseOverlay
{
Depth = -1,
OnResume = () => Logger.Log(@"Resume"),
OnRetry = () => Logger.Log(@"Retry"),
OnQuit = () => Logger.Log(@"Quit")
});
AddButton("Pause", pauseOverlay.Show);
AddButton("Add Retry", delegate
{
retryCount++;
pauseOverlay.Retries = retryCount;
});
retryCount = 0;
}
}
}
@@ -1,115 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using osu.Desktop.VisualTests.Platform;
using osu.Framework.Screens.Testing;
using osu.Framework.MathUtils;
using osu.Game.Database;
using osu.Game.Modes;
using osu.Game.Screens.Select;
namespace osu.Desktop.VisualTests.Tests
{
class TestCasePlaySongSelect : TestCase
{
private BeatmapDatabase db, oldDb;
private TestStorage storage;
private PlaySongSelect songSelect;
public override string Name => @"Song Select";
public override string Description => @"with fake data";
public override void Reset()
{
base.Reset();
oldDb = Dependencies.Get<BeatmapDatabase>();
if (db == null)
{
storage = new TestStorage(@"TestCasePlaySongSelect");
db = new BeatmapDatabase(storage);
Dependencies.Cache(db, true);
var sets = new List<BeatmapSetInfo>();
for (int i = 0; i < 100; i += 10)
sets.Add(createTestBeatmapSet(i));
db.Import(sets);
}
Add(songSelect = new PlaySongSelect());
AddButton(@"Sort by Artist", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Artist; });
AddButton(@"Sort by Title", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Title; });
AddButton(@"Sort by Author", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Author; });
AddButton(@"Sort by Difficulty", delegate { songSelect.Filter.Sort = FilterControl.SortMode.Difficulty; });
}
protected override void Dispose(bool isDisposing)
{
if (oldDb != null)
{
Dependencies.Cache(oldDb, true);
db = null;
}
base.Dispose(isDisposing);
}
private BeatmapSetInfo createTestBeatmapSet(int i)
{
return new BeatmapSetInfo
{
OnlineBeatmapSetID = 1234 + i,
Hash = "d8e8fca2dc0f896fd7cb4cb0031ba249",
Path = string.Empty,
Metadata = new BeatmapMetadata
{
OnlineBeatmapSetID = 1234 + i,
// Create random metadata, then we can check if sorting works based on these
Artist = "MONACA " + RNG.Next(0, 9),
Title = "Black Song " + RNG.Next(0, 9),
Author = "Some Guy " + RNG.Next(0, 9),
},
Beatmaps = new List<BeatmapInfo>(new[]
{
new BeatmapInfo
{
OnlineBeatmapID = 1234 + i,
Mode = PlayMode.Osu,
Path = "normal.osu",
Version = "Normal",
BaseDifficulty = new BaseDifficulty
{
OverallDifficulty = 3.5f,
}
},
new BeatmapInfo
{
OnlineBeatmapID = 1235 + i,
Mode = PlayMode.Osu,
Path = "hard.osu",
Version = "Hard",
BaseDifficulty = new BaseDifficulty
{
OverallDifficulty = 5,
}
},
new BeatmapInfo
{
OnlineBeatmapID = 1236 + i,
Mode = PlayMode.Osu,
Path = "insane.osu",
Version = "Insane",
BaseDifficulty = new BaseDifficulty
{
OverallDifficulty = 7,
}
},
}),
};
}
}
}
@@ -1,106 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Screens.Testing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using OpenTK;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps.IO;
using osu.Game.Database;
using osu.Game.Modes;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Screens.Play;
using OpenTK.Graphics;
namespace osu.Desktop.VisualTests.Tests
{
class TestCasePlayer : TestCase
{
private WorkingBeatmap beatmap;
public override string Name => @"Player";
public override string Description => @"Showing everything to play the game.";
[BackgroundDependencyLoader]
private void load(BeatmapDatabase db)
{
var beatmapInfo = db.Query<BeatmapInfo>().Where(b => b.Mode == PlayMode.Osu).FirstOrDefault();
if (beatmapInfo != null)
beatmap = db.GetWorkingBeatmap(beatmapInfo);
}
public override void Reset()
{
base.Reset();
if (beatmap?.Track == null)
{
var objects = new List<HitObject>();
int time = 1500;
for (int i = 0; i < 50; i++)
{
objects.Add(new HitCircle()
{
StartTime = time,
Position = new Vector2(i % 4 == 0 || i % 4 == 2 ? 0 : 512,
i % 4 < 2 ? 0 : 384),
NewCombo = i % 4 == 0
});
time += 500;
}
var decoder = new ConstructableBeatmapDecoder();
Beatmap b = new Beatmap
{
HitObjects = objects,
BeatmapInfo = new BeatmapInfo
{
Metadata = new BeatmapMetadata
{
Artist = @"Unknown",
Title = @"Sample Beatmap",
Author = @"peppy",
}
}
};
decoder.Process(b);
beatmap = new TestWorkingBeatmap(b);
}
Add(new Box
{
RelativeSizeAxes = Framework.Graphics.Axes.Both,
Colour = Color4.Black,
});
Add(new PlayerLoader(new Player
{
PreferredPlayMode = PlayMode.Osu,
Beatmap = beatmap
})
{
Beatmap = beatmap
});
}
class TestWorkingBeatmap : WorkingBeatmap
{
public TestWorkingBeatmap(Beatmap beatmap)
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
{
Beatmap = beatmap;
}
protected override ArchiveReader GetReader() => null;
}
}
}
@@ -1,177 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Screens.Testing;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Game.Graphics.UserInterface;
using osu.Game.Modes.Catch.UI;
using osu.Game.Modes.Mania.UI;
using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.Taiko.UI;
using osu.Game.Modes.UI;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Primitives;
namespace osu.Desktop.VisualTests.Tests
{
class TestCaseScoreCounter : TestCase
{
public override string Name => @"ScoreCounter";
public override string Description => @"Tests multiple counters";
public override void Reset()
{
base.Reset();
int numerator = 0, denominator = 0;
bool maniaHold = false;
ScoreCounter score = new ScoreCounter(7)
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
TextSize = 40,
Count = 0,
Margin = new MarginPadding(20),
};
Add(score);
ComboCounter standardCombo = new OsuComboCounter
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Margin = new MarginPadding(10),
Count = 0,
TextSize = 40,
};
Add(standardCombo);
CatchComboCounter catchCombo = new CatchComboCounter
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Count = 0,
TextSize = 40,
};
Add(catchCombo);
ComboCounter taikoCombo = new TaikoComboCounter
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.Centre,
Position = new Vector2(0, -160),
Count = 0,
TextSize = 40,
};
Add(taikoCombo);
ManiaComboCounter maniaCombo = new ManiaComboCounter
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Position = new Vector2(0, -80),
Count = 0,
TextSize = 40,
};
Add(maniaCombo);
PercentageCounter accuracyCombo = new PercentageCounter
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
Position = new Vector2(-20, 60),
};
Add(accuracyCombo);
StarCounter stars = new StarCounter
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Position = new Vector2(20, -160),
Count = 5,
};
Add(stars);
SpriteText starsLabel = new SpriteText
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Position = new Vector2(20, -190),
Text = stars.Count.ToString("0.00"),
};
Add(starsLabel);
AddButton(@"Reset all", delegate
{
score.Count = 0;
standardCombo.Count = 0;
taikoCombo.Count = 0;
maniaCombo.Count = 0;
catchCombo.Count = 0;
numerator = denominator = 0;
accuracyCombo.SetFraction(0, 0);
stars.Count = 0;
starsLabel.Text = stars.Count.ToString("0.00");
});
AddButton(@"Hit! :D", delegate
{
score.Count += 300 + (ulong)(300.0 * (standardCombo.Count > 0 ? standardCombo.Count - 1 : 0) / 25.0);
standardCombo.Count++;
taikoCombo.Count++;
maniaCombo.Count++;
catchCombo.CatchFruit(new Color4(
Math.Max(0.5f, RNG.NextSingle()),
Math.Max(0.5f, RNG.NextSingle()),
Math.Max(0.5f, RNG.NextSingle()),
1)
);
numerator++; denominator++;
accuracyCombo.SetFraction(numerator, denominator);
});
AddButton(@"miss...", delegate
{
standardCombo.Roll();
taikoCombo.Roll();
maniaCombo.Roll();
catchCombo.Roll();
denominator++;
accuracyCombo.SetFraction(numerator, denominator);
});
AddButton(@"mania hold", delegate
{
if (!maniaHold)
maniaCombo.HoldStart();
else
maniaCombo.HoldEnd();
maniaHold = !maniaHold;
});
AddButton(@"Alter stars", delegate
{
stars.Count = RNG.NextSingle() * (stars.StarCount + 1);
starsLabel.Text = stars.Count.ToString("0.00");
});
AddButton(@"Stop counters", delegate
{
score.StopRolling();
standardCombo.StopRolling();
catchCombo.StopRolling();
taikoCombo.StopRolling();
maniaCombo.StopRolling();
accuracyCombo.StopRolling();
stars.StopAnimation();
});
}
}
}
@@ -1,53 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Screens.Testing;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Desktop.VisualTests.Tests
{
class TestCaseTextAwesome : TestCase
{
public override string Name => @"TextAwesome";
public override string Description => @"Tests display of icons";
public override void Reset()
{
base.Reset();
FillFlowContainer flow;
Add(flow = new FillFlowContainer()
{
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.5f),
Anchor = Anchor.Centre,
Origin = Anchor.Centre
});
int i = 50;
foreach (FontAwesome fa in Enum.GetValues(typeof(FontAwesome)))
{
flow.Add(new TextAwesome
{
Icon = fa,
TextSize = 60,
Colour = new Color4(
Math.Max(0.5f, RNG.NextSingle()),
Math.Max(0.5f, RNG.NextSingle()),
Math.Max(0.5f, RNG.NextSingle()),
1)
});
if (i-- == 0) break;
}
}
}
}
@@ -1,23 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
{
class TestCaseTwoLayerButton : TestCase
{
public override string Name => @"TwoLayerButton";
public override string Description => @"Back and skip and what not";
public override void Reset()
{
base.Reset();
Add(new BackButton());
Add(new SkipButton());
}
}
}
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -1,221 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<ProjectGuid>{69051C69-12AE-4E7D-A3E6-460D2E282312}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Desktop.VisualTests</RootNamespace>
<AssemblyName>osu!</AssemblyName>
<ManifestCertificateThumbprint>3CF060CD28877D0E3112948951A64B2A7CEEC909</ManifestCertificateThumbprint>
<ManifestKeyFile>codesigning.pfx</ManifestKeyFile>
<GenerateManifests>false</GenerateManifests>
<SignManifests>false</SignManifests>
<IsWebBootstrapper>false</IsWebBootstrapper>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<StartupObject>osu.Desktop.VisualTests.Program</StartupObject>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
<SignAssembly>false</SignAssembly>
<TargetZone>LocalIntranet</TargetZone>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>2</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<ProductVersion>12.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>0</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
<Prefer32Bit>false</Prefer32Bit>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>CuttingEdge NoUpdate</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup>
<Win32Resource>
</Win32Resource>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SQLite.Net, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="SQLiteNetExtensions">
<HintPath>$(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll</HintPath>
</Reference>
<Reference Include="SQLite.Net.Platform.Win32">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll</HintPath>
</Reference>
<Reference Include="SQLite.Net.Platform.Generic">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<None Include="..\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="OpenTK.dll.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework.Desktop\osu.Framework.Desktop.csproj">
<Project>{65dc628f-a640-4111-ab35-3a5652bc1e17}</Project>
<Name>osu.Framework.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{c76bf5b3-985e-4d39-95fe-97c9c879b83a}</Project>
<Name>osu.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj">
<Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project>
<Name>osu.Game.Resources</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Osu\osu.Game.Modes.Osu.csproj">
<Project>{c92a607b-1fdd-4954-9f92-03ff547d9080}</Project>
<Name>osu.Game.Modes.Osu</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Catch\osu.Game.Modes.Catch.csproj">
<Project>{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}</Project>
<Name>osu.Game.Modes.Catch</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Mania\osu.Game.Modes.Mania.csproj">
<Project>{48f4582b-7687-4621-9cbe-5c24197cb536}</Project>
<Name>osu.Game.Modes.Mania</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Taiko\osu.Game.Modes.Taiko.csproj">
<Project>{f167e17a-7de6-4af5-b920-a5112296c695}</Project>
<Name>osu.Game.Modes.Taiko</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{0d3fbf8a-7464-4cf7-8c90-3e7886df2d4d}</Project>
<Name>osu.Game</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Benchmark.cs" />
<Compile Include="Program.cs" />
<Compile Include="Tests\TestCaseChatDisplay.cs" />
<Compile Include="Tests\TestCaseGamefield.cs" />
<Compile Include="Tests\TestCaseMusicController.cs" />
<Compile Include="Tests\TestCaseNotificationManager.cs" />
<Compile Include="Tests\TestCasePlayer.cs" />
<Compile Include="Tests\TestCaseHitObjects.cs" />
<Compile Include="Tests\TestCaseKeyCounter.cs" />
<Compile Include="Tests\TestCaseMenuButtonSystem.cs" />
<Compile Include="Tests\TestCaseScoreCounter.cs" />
<Compile Include="Tests\TestCaseTextAwesome.cs" />
<Compile Include="Tests\TestCasePlaySongSelect.cs" />
<Compile Include="Tests\TestCaseTwoLayerButton.cs" />
<Compile Include="VisualTestGame.cs" />
<Compile Include="Platform\TestStorage.cs" />
<Compile Include="Tests\TestCaseOptions.cs" />
<Compile Include="Tests\TestCasePauseOverlay.cs" />
<Compile Include="Tests\TestCaseDialogOverlay.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ProjectExtensions>
<VisualStudio>
</VisualStudio>
</ProjectExtensions>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="ppy.OpenTK" version="2.0.50727.1340" targetFramework="net45" />
<package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />
</packages>
@@ -1,52 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.IO;
using System.Linq;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
using osu.Game.Beatmaps;
using osu.Game.Database;
namespace osu.Desktop.Beatmaps.IO
{
/// <summary>
/// Reads an extracted legacy beatmap from disk.
/// </summary>
public class LegacyFilesystemReader : ArchiveReader
{
public static void Register() => AddReader<LegacyFilesystemReader>((storage, path) => Directory.Exists(path));
private string basePath { get; set; }
private Beatmap firstMap { get; set; }
public LegacyFilesystemReader(string path)
{
basePath = path;
BeatmapFilenames = Directory.GetFiles(basePath, @"*.osu").Select(f => Path.GetFileName(f)).ToArray();
if (BeatmapFilenames.Length == 0)
throw new FileNotFoundException(@"This directory contains no beatmaps");
StoryboardFilename = Directory.GetFiles(basePath, @"*.osb").Select(f => Path.GetFileName(f)).FirstOrDefault();
using (var stream = new StreamReader(GetStream(BeatmapFilenames[0])))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
firstMap = decoder.Decode(stream);
}
}
public override Stream GetStream(string name)
{
return File.OpenRead(Path.Combine(basePath, name));
}
public override BeatmapMetadata ReadMetadata()
{
return firstMap.BeatmapInfo.Metadata;
}
public override void Dispose()
{
// no-op
}
}
}
@@ -1,7 +1,3 @@
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
+85 -41
View File
@@ -1,40 +1,89 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game;
using System.Linq;
using System.Windows.Forms;
using osu.Framework.Platform;
using osu.Framework.Desktop.Platform;
using osu.Desktop.Overlays;
using System.Reflection;
using System;
using System.Drawing;
using osu.Game.Screens.Menu;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Win32;
using osu.Desktop.Overlays;
using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
using osu.Game;
using OpenTK.Input;
namespace osu.Desktop
{
class OsuGameDesktop : OsuGame
internal class OsuGameDesktop : OsuGame
{
private VersionManager versionManager;
public override bool IsDeployedBuild => versionManager.IsDeployedBuild;
public OsuGameDesktop(string[] args = null)
: base(args)
{
versionManager = new VersionManager { Depth = int.MinValue };
}
public override Storage GetStorageForStableInstall()
{
try
{
return new StableStorage();
}
catch
{
return null;
}
}
/// <summary>
/// A method of accessing an osu-stable install in a controlled fashion.
/// </summary>
private class StableStorage : DesktopStorage
{
protected override string LocateBasePath()
{
Func<string, bool> checkExists = p => Directory.Exists(Path.Combine(p, "Songs"));
string stableInstallPath;
try
{
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu"))
stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(String.Empty).ToString().Split('"')[1].Replace("osu!.exe", "");
if (checkExists(stableInstallPath))
return stableInstallPath;
}
catch
{
}
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!");
if (checkExists(stableInstallPath))
return stableInstallPath;
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu");
if (checkExists(stableInstallPath))
return stableInstallPath;
return null;
}
public StableStorage()
: base(string.Empty)
{
}
}
protected override void LoadComplete()
{
base.LoadComplete();
versionManager.LoadAsync(this);
ModeChanged += m =>
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
{
if (!versionManager.IsAlive && m is Intro)
Add(versionManager);
};
Add(v);
v.State = Visibility.Visible;
});
}
public override void SetHost(GameHost host)
@@ -43,34 +92,29 @@ namespace osu.Desktop
var desktopWindow = host.Window as DesktopGameWindow;
if (desktopWindow != null)
{
desktopWindow.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
desktopWindow.Title = @"osu!lazer";
desktopWindow.CursorState |= CursorState.Hidden;
desktopWindow.DragEnter += dragEnter;
desktopWindow.DragDrop += dragDrop;
desktopWindow.Icon = new Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico"));
desktopWindow.Title = Name;
desktopWindow.FileDrop += fileDrop;
}
}
private void dragDrop(DragEventArgs e)
private void fileDrop(object sender, FileDropEventArgs e)
{
// this method will only be executed if e.Effect in dragEnter gets set to something other that None.
var dropData = e.Data.GetData(DataFormats.FileDrop) as object[];
var filePaths = dropData.Select(f => f.ToString()).ToArray();
ImportBeatmapsAsync(filePaths);
var filePaths = new [] { e.FileName };
if (filePaths.All(f => Path.GetExtension(f) == @".osz"))
Task.Run(() => BeatmapManager.Import(filePaths));
else if (filePaths.All(f => Path.GetExtension(f) == @".osr"))
Task.Run(() =>
{
var score = ScoreStore.ReadReplayFile(filePaths.First());
Schedule(() => LoadScore(score));
});
}
private void dragEnter(DragEventArgs e)
{
// dragDrop will only be executed if e.Effect gets set to something other that None in this method.
bool isFile = e.Data.GetDataPresent(DataFormats.FileDrop);
if (isFile)
{
var paths = (e.Data.GetData(DataFormats.FileDrop) as object[]).Select(f => f.ToString()).ToArray();
if (paths.Any(p => !p.EndsWith(".osz")))
e.Effect = DragDropEffects.None;
else
e.Effect = DragDropEffects.Copy;
}
}
private static readonly string[] allowed_extensions = { @".osz", @".osr" };
}
}
@@ -1,23 +1,30 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Screens.Testing;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game;
using osu.Game.Screens.Backgrounds;
namespace osu.Desktop.VisualTests
namespace osu.Desktop
{
class VisualTestGame : OsuGameBase
internal class OsuTestBrowser : OsuGameBase
{
protected override void LoadComplete()
{
base.LoadComplete();
(new BackgroundScreenDefault() { Depth = 10 }).LoadAsync(this, AddInternal);
LoadComponentAsync(new BackgroundScreenDefault { Depth = 10 }, AddInternal);
// Have to construct this here, rather than in the constructor, because
// we depend on some dependencies to be loaded within OsuGameBase.load().
Add(new TestBrowser());
}
public override void SetHost(GameHost host)
{
base.SetHost(host);
host.Window.CursorState |= CursorState.Hidden;
}
}
}
}
+79 -44
View File
@@ -3,70 +3,62 @@
using System;
using System.Diagnostics;
using System.Net.Http;
using osu.Framework.Allocation;
using osu.Framework.Development;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Logging;
using osu.Game;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using Squirrel;
using System.Reflection;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
using System.Net.Http;
using Squirrel;
namespace osu.Desktop.Overlays
{
public class VersionManager : OverlayContainer
{
private UpdateManager updateManager;
private NotificationManager notificationManager;
AssemblyName assembly = Assembly.GetEntryAssembly().GetName();
public bool IsDeployedBuild => assembly.Version.Major > 0;
protected override bool HideOnEscape => false;
private NotificationOverlay notificationOverlay;
private OsuConfigManager config;
private OsuGameBase game;
public override bool HandleInput => false;
[BackgroundDependencyLoader]
private void load(NotificationManager notification, OsuColour colours, TextureStore textures)
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)
{
notificationManager = notification;
notificationOverlay = notification;
this.config = config;
this.game = game;
AutoSizeAxes = Axes.Both;
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
Alpha = 0;
bool isDebug = false;
Debug.Assert(isDebug = true);
string version;
if (!IsDeployedBuild)
{
version = @"local " + (isDebug ? @"debug" : @"release");
}
else
version = $@"{assembly.Version.Major}.{assembly.Version.Minor}.{assembly.Version.Build}";
Children = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Down,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Right,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
@@ -75,12 +67,12 @@ namespace osu.Desktop.Overlays
new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = $@"osu!lazer"
Text = game.Name
},
new OsuSpriteText
{
Colour = isDebug ? colours.Red : Color4.White,
Text = version
Colour = DebugUtils.IsDebug ? colours.Red : Color4.White,
Text = game.Version
},
}
},
@@ -91,7 +83,7 @@ namespace osu.Desktop.Overlays
TextSize = 12,
Colour = colours.Yellow,
Font = @"Venera",
Text = $@"Development Build"
Text = @"Development Build"
},
new Sprite
{
@@ -103,14 +95,44 @@ namespace osu.Desktop.Overlays
}
};
if (IsDeployedBuild)
if (game.IsDeployedBuild)
checkForUpdateAsync();
}
protected override void LoadComplete()
{
base.LoadComplete();
State = Visibility.Visible;
var version = game.Version;
var lastVersion = config.Get<string>(OsuSetting.Version);
if (game.IsDeployedBuild && version != lastVersion)
{
config.Set(OsuSetting.Version, version);
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
if (!string.IsNullOrEmpty(lastVersion))
Scheduler.AddDelayed(() => notificationOverlay.Post(new UpdateCompleteNotification(version)), 5000);
}
}
private class UpdateCompleteNotification : SimpleNotification
{
public UpdateCompleteNotification(string version)
{
Text = $"You are now running osu!lazer {version}.\nClick to see what's new!";
Icon = FontAwesome.fa_check_square;
Activated = delegate
{
Process.Start($"https://github.com/ppy/osu/releases/tag/v{version}");
return true;
};
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
IconBackgound.Colour = colours.BlueDark;
}
}
protected override void Dispose(bool isDisposing)
@@ -136,7 +158,7 @@ namespace osu.Desktop.Overlays
if (notification == null)
{
notification = new UpdateProgressNotification { State = ProgressNotificationState.Active };
Schedule(() => notificationManager.Post(notification));
Schedule(() => notificationOverlay.Post(notification));
}
Schedule(() =>
@@ -159,15 +181,21 @@ namespace osu.Desktop.Overlays
Schedule(() => notification.State = ProgressNotificationState.Completed);
}
catch (Exception)
catch (Exception e)
{
if (useDeltaPatching)
{
Logger.Error(e, @"delta patching failed!");
//could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959)
//try again without deltas.
checkForUpdateAsync(false, notification);
scheduleRetry = false;
}
else
{
Logger.Error(e, @"update failed!");
}
}
}
catch (HttpRequestException)
@@ -189,40 +217,47 @@ namespace osu.Desktop.Overlays
protected override void PopIn()
{
FadeIn(1000);
this.FadeIn(1000);
}
protected override void PopOut()
{
}
class UpdateProgressNotification : ProgressNotification
private class UpdateProgressNotification : ProgressNotification
{
protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification(this)
private OsuGame game;
protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification
{
Text = @"Update ready to install. Click to restart!",
Activated = () =>
{
UpdateManager.RestartApp();
UpdateManager.RestartAppWhenExited();
game.GracefullyExit();
return true;
}
};
[BackgroundDependencyLoader]
private void load(OsuColour colours)
private void load(OsuColour colours, OsuGame game)
{
IconContent.Add(new Drawable[]
this.game = game;
IconContent.AddRange(new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow)
Colour = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow)
},
new TextAwesome
new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.fa_upload,
Colour = Color4.White,
Size = new Vector2(20),
}
});
}
+13 -16
View File
@@ -3,15 +3,10 @@
using System;
using System.IO;
using osu.Desktop.Beatmaps.IO;
using osu.Framework.Desktop;
using osu.Framework.Desktop.Platform;
using System.Linq;
using osu.Framework;
using osu.Framework.Platform;
using osu.Game.IPC;
using osu.Game.Modes;
using osu.Game.Modes.Catch;
using osu.Game.Modes.Mania;
using osu.Game.Modes.Osu;
using osu.Game.Modes.Taiko;
namespace osu.Desktop
{
@@ -20,8 +15,6 @@ namespace osu.Desktop
[STAThread]
public static int Main(string[] args)
{
LegacyFilesystemReader.Register();
// Back up the cwd before DesktopGameHost changes it
var cwd = Environment.CurrentDirectory;
@@ -29,7 +22,7 @@ namespace osu.Desktop
{
if (!host.IsPrimaryInstance)
{
var importer = new BeatmapImporter(host);
var importer = new BeatmapIPCChannel(host);
// Restore the cwd so relative paths given at the command line work correctly
Directory.SetCurrentDirectory(cwd);
foreach (var file in args)
@@ -41,12 +34,16 @@ namespace osu.Desktop
}
else
{
Ruleset.Register(new OsuRuleset());
Ruleset.Register(new TaikoRuleset());
Ruleset.Register(new ManiaRuleset());
Ruleset.Register(new CatchRuleset());
switch (args.FirstOrDefault() ?? string.Empty)
{
case "--tests":
host.Run(new OsuTestBrowser());
break;
default:
host.Run(new OsuGameDesktop(args));
break;
}
host.Run(new OsuGameDesktop(args));
}
return 0;
}
+4 -4
View File
@@ -4,7 +4,7 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// 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("osu!lazer")]
@@ -16,13 +16,13 @@ using System.Runtime.InteropServices;
[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
// 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("55e28cb2-7b6c-4595-8dcc-9871d8aad7e9")]
[assembly: Guid("b0cb1d48-e4c2-4612-a347-beea7b1a71e7")]
[assembly: AssemblyVersion("0.0.0")]
[assembly: AssemblyFileVersion("0.0.0")]
+33 -8
View File
@@ -1,19 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DeltaCompressionDotNet.MsDelta" publicKeyToken="46b2138a390abf55" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
<assemblyIdentity name="SharpCompress" publicKeyToken="afb0a02973931d96" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.18.1.0" newVersion="0.18.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
</configuration>
+81 -45
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<PropertyGroup>
<ProjectGuid>{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}</ProjectGuid>
<ProjectGuid>{419659FD-72EA-4678-9EB8-B22A746CED70}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>WinExe</OutputType>
@@ -22,7 +22,8 @@
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
<SignAssembly>false</SignAssembly>
<TargetZone>LocalIntranet</TargetZone>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -56,12 +57,12 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
<Prefer32Bit>false</Prefer32Bit>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<Commandlineparameters>
</Commandlineparameters>
<LangVersion>6</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
@@ -74,7 +75,6 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
@@ -88,6 +88,20 @@
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'VisualTests|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<WarningLevel>0</WarningLevel>
<NoStdLib>true</NoStdLib>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<LangVersion>6</LangVersion>
<ErrorReport>prompt</ErrorReport>
<StartArguments>--tests</StartArguments>
</PropertyGroup>
<ItemGroup>
<Reference Include="DeltaCompressionDotNet, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1d14d6e5194e7f4a, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.dll</HintPath>
@@ -101,10 +115,6 @@
<HintPath>$(SolutionDir)\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.PatchApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
<Private>True</Private>
@@ -123,30 +133,44 @@
</Reference>
<Reference Include="mscorlib" />
<Reference Include="NuGet.Squirrel, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll</HintPath>
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\NuGet.Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.18.1.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SharpCompress.0.18.1\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4" />
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Squirrel, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll</HintPath>
<Reference Include="SQLitePCLRaw.batteries_green, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a84b7dcfb1391f7f, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_green.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.batteries_v2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8226ea5df37bcae9, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SQLitePCLRaw.bundle_green.1.1.8\lib\net45\SQLitePCLRaw.batteries_v2.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll</HintPath>
</Reference>
<Reference Include="SQLitePCLRaw.provider.e_sqlite3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9c301db686d0bd12, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SQLitePCLRaw.provider.e_sqlite3.net45.1.1.8\lib\net45\SQLitePCLRaw.provider.e_sqlite3.dll</HintPath>
</Reference>
<Reference Include="Squirrel, Version=1.7.8.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>$(SolutionDir)\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
@@ -154,6 +178,7 @@
<Link>osu.licenseheader</Link>
</None>
<None Include="app.config" />
<None Include="OpenTK.dll.config" />
<None Include="osu!.res" />
<None Include="packages.config" />
<None Include="Properties\app.manifest" />
@@ -186,10 +211,16 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework.Desktop\osu.Framework.Desktop.csproj">
<Project>{65dc628f-a640-4111-ab35-3a5652bc1e17}</Project>
<Name>osu.Framework.Desktop</Name>
</ProjectReference>
<Compile Include="OsuGameDesktop.cs" />
<Compile Include="OsuTestBrowser.cs" />
<Compile Include="Overlays\VersionManager.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="lazer.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{c76bf5b3-985e-4d39-95fe-97c9c879b83a}</Project>
<Name>osu.Framework</Name>
@@ -198,37 +229,31 @@
<Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project>
<Name>osu.Game.Resources</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Osu\osu.Game.Modes.Osu.csproj">
<Project>{c92a607b-1fdd-4954-9f92-03ff547d9080}</Project>
<Name>osu.Game.Modes.Osu</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Catch\osu.Game.Modes.Catch.csproj">
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj">
<Project>{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}</Project>
<Name>osu.Game.Modes.Catch</Name>
<Name>osu.Game.Rulesets.Catch</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Mania\osu.Game.Modes.Mania.csproj">
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj">
<Project>{48f4582b-7687-4621-9cbe-5c24197cb536}</Project>
<Name>osu.Game.Modes.Mania</Name>
<Name>osu.Game.Rulesets.Mania</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Taiko\osu.Game.Modes.Taiko.csproj">
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj">
<Project>{c92a607b-1fdd-4954-9f92-03ff547d9080}</Project>
<Name>osu.Game.Rulesets.Osu</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj">
<Project>{f167e17a-7de6-4af5-b920-a5112296c695}</Project>
<Name>osu.Game.Modes.Taiko</Name>
<Name>osu.Game.Rulesets.Taiko</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Tests\osu.Game.Tests.csproj">
<Project>{54377672-20b1-40af-8087-5cf73bf3953a}</Project>
<Name>osu.Game.Tests</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{0d3fbf8a-7464-4cf7-8c90-3e7886df2d4d}</Project>
<Project>{2a66dd92-adb1-4994-89e2-c94e04acda0d}</Project>
<Name>osu.Game</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="OsuGameDesktop.cs" />
<Compile Include="Overlays\VersionManager.cs" />
<Compile Include="Program.cs" />
<Compile Include="Beatmaps\IO\LegacyFilesystemReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="lazer.ico" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -249,4 +274,15 @@
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.linux.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.linux.targets" Condition="Exists('$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.linux.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.linux.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.linux.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.linux.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.linux.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.linux.targets'))" />
<Error Condition="!Exists('$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.osx.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.osx.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.osx.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.osx.targets'))" />
<Error Condition="!Exists('$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.v110_xp.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.v110_xp.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.v110_xp.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.v110_xp.targets'))" />
</Target>
<Import Project="$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.osx.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.osx.targets" Condition="Exists('$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.osx.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.osx.targets')" />
<Import Project="$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.v110_xp.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.v110_xp.targets" Condition="Exists('$(SolutionDir)\packages\SQLitePCLRaw.lib.e_sqlite3.v110_xp.1.1.8\build\net35\SQLitePCLRaw.lib.e_sqlite3.v110_xp.targets')" />
</Project>
+2 -1
View File
@@ -17,7 +17,8 @@
</metadata>
<files>
<file src="*.exe" target="lib\net45\" exclude="**vshost**"/>
<file src="*.dll" target="lib\net45\"/>
<file src="*.dll" target="lib\net45\"/>
<file src="*.config" target="lib\net45\"/>
<file src="x86\*.dll" target="lib\net45\x86\"/>
<file src="x64\*.dll" target="lib\net45\x64\"/>
</files>
+10 -2
View File
@@ -5,8 +5,16 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
-->
<packages>
<package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net45" />
<package id="OpenTK" version="3.0.0-git00009" targetFramework="net461" />
<package id="SharpCompress" version="0.18.1" targetFramework="net461" />
<package id="Splat" version="2.0.0" targetFramework="net45" />
<package id="squirrel.windows" version="1.5.2" targetFramework="net45" />
<package id="SQLitePCLRaw.bundle_green" version="1.1.8" targetFramework="net461" />
<package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net461" />
<package id="SQLitePCLRaw.lib.e_sqlite3.linux" version="1.1.8" targetFramework="net461" />
<package id="SQLitePCLRaw.lib.e_sqlite3.osx" version="1.1.8" targetFramework="net461" />
<package id="SQLitePCLRaw.lib.e_sqlite3.v110_xp" version="1.1.8" targetFramework="net461" />
<package id="SQLitePCLRaw.provider.e_sqlite3.net45" version="1.1.8" targetFramework="net461" />
<package id="squirrel.windows" version="1.7.8" targetFramework="net461" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="net461" />
</packages>
-29
View File
@@ -1,29 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Graphics;
using osu.Game.Modes.Catch.UI;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.UI;
using osu.Game.Beatmaps;
namespace osu.Game.Modes.Catch
{
public class CatchRuleset : Ruleset
{
public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay();
public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new CatchHitRenderer { Beatmap = beatmap };
protected override PlayMode PlayMode => PlayMode.Catch;
public override FontAwesome Icon => FontAwesome.fa_osu_fruits_o;
public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => null;
public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser();
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap);
}
}
@@ -1,40 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Beatmaps;
namespace osu.Game.Modes.Catch.Objects
{
class CatchConverter : HitObjectConverter<CatchBaseHit>
{
public override List<CatchBaseHit> Convert(Beatmap beatmap)
{
List<CatchBaseHit> output = new List<CatchBaseHit>();
foreach (HitObject i in beatmap.HitObjects)
{
CatchBaseHit h = i as CatchBaseHit;
if (h == null)
{
OsuHitObject o = i as OsuHitObject;
if (o == null) throw new HitObjectConvertException(@"Catch", i);
h = new Fruit
{
StartTime = o.StartTime,
Position = o.Position.X,
};
}
output.Add(h);
}
return output;
}
}
}
@@ -1,37 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
using OpenTK;
namespace osu.Game.Modes.Catch.Objects.Drawable
{
class DrawableFruit : Sprite
{
private CatchBaseHit h;
public DrawableFruit(CatchBaseHit h)
{
this.h = h;
Origin = Anchor.Centre;
Scale = new Vector2(0.1f);
RelativePositionAxes = Axes.Y;
Position = new Vector2(h.Position, -0.1f);
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(@"Menu/logo");
Transforms.Add(new TransformPosition { StartTime = h.StartTime - 200, EndTime = h.StartTime, StartValue = new Vector2(h.Position, -0.1f), EndValue = new Vector2(h.Position, 0.9f) });
Transforms.Add(new TransformAlpha { StartTime = h.StartTime + h.Duration + 200, EndTime = h.StartTime + h.Duration + 400, StartValue = 1, EndValue = 0 });
Expire(true);
}
}
}
@@ -1,65 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Osu.UI;
using OpenTK.Graphics;
namespace osu.Game.Modes.Catch.UI
{
/// <summary>
/// Similar to Standard, but without the 'x' and has tinted pop-ups. Used in osu!catch.
/// </summary>
public class CatchComboCounter : OsuComboCounter
{
protected override bool CanPopOutWhileRolling => true;
protected virtual double FadeOutDelay => 1000;
protected override double FadeOutDuration => 300;
protected override string FormatCount(ulong count)
{
return $@"{count:#,0}";
}
private void animateFade()
{
Show();
Delay(FadeOutDelay);
FadeOut(FadeOutDuration);
DelayReset();
}
protected override void OnCountChange(ulong currentValue, ulong newValue)
{
if (newValue != 0)
animateFade();
base.OnCountChange(currentValue, newValue);
}
protected override void OnCountRolling(ulong currentValue, ulong newValue)
{
if (!IsRolling)
{
PopOutCount.Colour = DisplayedCountSpriteText.Colour;
FadeOut(FadeOutDuration);
}
base.OnCountRolling(currentValue, newValue);
}
protected override void OnCountIncrement(ulong currentValue, ulong newValue)
{
animateFade();
base.OnCountIncrement(currentValue, newValue);
}
/// <summary>
/// Increaces counter and tints pop-out before animation.
/// </summary>
/// <param name="colour">Last grabbed fruit colour.</param>
public void CatchFruit(Color4 colour)
{
PopOutCount.Colour = colour;
Count++;
}
}
}
@@ -1,19 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Catch.Objects;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.UI;
namespace osu.Game.Modes.Catch.UI
{
public class CatchHitRenderer : HitRenderer<CatchBaseHit>
{
protected override HitObjectConverter<CatchBaseHit> Converter => new CatchConverter();
protected override Playfield CreatePlayfield() => new CatchPlayfield();
protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) => null;// new DrawableFruit(h);
}
}
-23
View File
@@ -1,23 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Modes.UI;
using OpenTK;
namespace osu.Game.Modes.Catch.UI
{
public class CatchPlayfield : Playfield
{
public CatchPlayfield()
{
RelativeSizeAxes = Axes.Y;
Size = new Vector2(512, 0.9f);
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f });
}
}
}
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="ppy.OpenTK" version="2.0.50727.1340" targetFramework="net45" />
</packages>
@@ -1,30 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Modes.Mania.Objects;
using osu.Game.Modes.Objects;
using System;
using System.Collections.Generic;
namespace osu.Game.Modes.Mania
{
public class ManiaDifficultyCalculator : DifficultyCalculator<ManiaBaseHit>
{
protected override PlayMode PlayMode => PlayMode.Mania;
private int columns;
public ManiaDifficultyCalculator(Beatmap beatmap, int columns = 5) : base(beatmap)
{
this.columns = columns;
}
protected override HitObjectConverter<ManiaBaseHit> Converter => new ManiaConverter(columns);
protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty)
{
return 0;
}
}
}
-29
View File
@@ -1,29 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Graphics;
using osu.Game.Modes.Mania.UI;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.UI;
using osu.Game.Beatmaps;
namespace osu.Game.Modes.Mania
{
public class ManiaRuleset : Ruleset
{
public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay();
public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new ManiaHitRenderer { Beatmap = beatmap };
protected override PlayMode PlayMode => PlayMode.Mania;
public override FontAwesome Icon => FontAwesome.fa_osu_mania_o;
public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => null;
public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser();
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap);
}
}
@@ -1,34 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics;
using OpenTK;
namespace osu.Game.Modes.Mania.Objects.Drawable
{
public class DrawableNote : Sprite
{
private readonly ManiaBaseHit note;
public DrawableNote(ManiaBaseHit note)
{
this.note = note;
Origin = Anchor.Centre;
Scale = new Vector2(0.1f);
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(@"Menu/logo");
Transforms.Add(new TransformPositionY() { StartTime = note.StartTime - 200, EndTime = note.StartTime, StartValue = -0.1f, EndValue = 0.9f });
Transforms.Add(new TransformAlpha() { StartTime = note.StartTime + note.Duration + 200, EndTime = note.StartTime + note.Duration + 400, StartValue = 1, EndValue = 0 });
Expire(true);
}
}
}
@@ -1,48 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Beatmaps;
namespace osu.Game.Modes.Mania.Objects
{
class ManiaConverter : HitObjectConverter<ManiaBaseHit>
{
private readonly int columns;
public ManiaConverter(int columns)
{
this.columns = columns;
}
public override List<ManiaBaseHit> Convert(Beatmap beatmap)
{
List<ManiaBaseHit> output = new List<ManiaBaseHit>();
foreach (HitObject i in beatmap.HitObjects)
{
ManiaBaseHit h = i as ManiaBaseHit;
if (h == null)
{
OsuHitObject o = i as OsuHitObject;
if (o == null) throw new HitObjectConvertException(@"Mania", i);
h = new Note
{
StartTime = o.StartTime,
Column = (int)Math.Round(o.Position.X / 512 * columns)
};
}
output.Add(h);
}
return output;
}
}
}
@@ -1,78 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Transforms;
using osu.Game.Modes.Taiko.UI;
using OpenTK.Graphics;
namespace osu.Game.Modes.Mania.UI
{
/// <summary>
/// Similar to osu!taiko, with a pop-out animation when failing (rolling). Used in osu!mania.
/// </summary>
public class ManiaComboCounter : TaikoComboCounter
{
protected ushort KeysHeld = 0;
protected Color4 OriginalColour;
protected Color4 TintColour => Color4.Orange;
protected EasingTypes TintEasing => EasingTypes.None;
protected int TintDuration => 500;
protected Color4 PopOutColor => Color4.Red;
protected override float PopOutInitialAlpha => 1.0f;
protected override double PopOutDuration => 300;
protected override void LoadComplete()
{
base.LoadComplete();
PopOutCount.Anchor = Anchor.BottomCentre;
PopOutCount.Origin = Anchor.Centre;
PopOutCount.FadeColour(PopOutColor, 0);
OriginalColour = DisplayedCountSpriteText.Colour;
}
protected override void OnCountRolling(ulong currentValue, ulong newValue)
{
if (!IsRolling && newValue < currentValue)
{
PopOutCount.Text = FormatCount(currentValue);
PopOutCount.FadeTo(PopOutInitialAlpha);
PopOutCount.ScaleTo(1.0f);
PopOutCount.FadeOut(PopOutDuration, PopOutEasing);
PopOutCount.ScaleTo(PopOutScale, PopOutDuration, PopOutEasing);
}
base.OnCountRolling(currentValue, newValue);
}
/// <summary>
/// Tints text while holding a key.
/// </summary>
/// <remarks>
/// Does not alter combo. This has to be done depending of the scoring system.
/// (i.e. v1 = each period of time; v2 = when starting and ending a key hold)
/// </remarks>
public void HoldStart()
{
if (KeysHeld == 0)
DisplayedCountSpriteText.FadeColour(TintColour, TintDuration, TintEasing);
KeysHeld++;
}
/// <summary>
/// Ends tinting.
/// </summary>
public void HoldEnd()
{
KeysHeld--;
if (KeysHeld == 0)
DisplayedCountSpriteText.FadeColour(OriginalColour, TintDuration, TintEasing);
}
}
}
@@ -1,34 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Mania.Objects;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.UI;
namespace osu.Game.Modes.Mania.UI
{
public class ManiaHitRenderer : HitRenderer<ManiaBaseHit>
{
private readonly int columns;
public ManiaHitRenderer(int columns = 5)
{
this.columns = columns;
}
protected override HitObjectConverter<ManiaBaseHit> Converter => new ManiaConverter(columns);
protected override Playfield CreatePlayfield() => new ManiaPlayfield(columns);
protected override DrawableHitObject GetVisualRepresentation(ManiaBaseHit h)
{
return null;
//return new DrawableNote(h)
//{
// Position = new Vector2((float)(h.Column + 0.5) / columns, -0.1f),
// RelativePositionAxes = Axes.Both
//};
}
}
}
-38
View File
@@ -1,38 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Modes.UI;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Modes.Mania.UI
{
public class ManiaPlayfield : Playfield
{
private readonly int columns;
public ManiaPlayfield(int columns)
{
this.columns = columns;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(columns / 20f, 1f);
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f });
for (int i = 0; i < columns; i++)
Add(new Box()
{
RelativeSizeAxes = Axes.Y,
Size = new Vector2(2, 1),
RelativePositionAxes = Axes.Both,
Position = new Vector2((float)i / columns, 0),
Alpha = 0.5f,
Colour = Color4.Black
});
}
}
}
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
@@ -1,96 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{48F4582B-7687-4621-9CBE-5C24197CB536}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Game.Modes.Mania</RootNamespace>
<AssemblyName>osu.Game.Modes.Mania</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ManiaDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableNote.cs" />
<Compile Include="Objects\HoldNote.cs" />
<Compile Include="Objects\ManiaBaseHit.cs" />
<Compile Include="Objects\ManiaConverter.cs" />
<Compile Include="Objects\Note.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\ManiaComboCounter.cs" />
<Compile Include="UI\ManiaHitRenderer.cs" />
<Compile Include="UI\ManiaPlayfield.cs" />
<Compile Include="ManiaRuleset.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{C76BF5B3-985E-4D39-95FE-97C9C879B83A}</Project>
<Name>osu.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Osu\osu.Game.Modes.Osu.csproj">
<Project>{C92A607B-1FDD-4954-9F92-03FF547D9080}</Project>
<Name>osu.Game.Modes.Osu</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Taiko\osu.Game.Modes.Taiko.csproj">
<Project>{F167E17A-7DE6-4AF5-B920-A5112296C695}</Project>
<Name>osu.Game.Modes.Taiko</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}</Project>
<Name>osu.Game</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="..\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<None Include="app.config" />
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="ppy.OpenTK" version="2.0.50727.1340" targetFramework="net45" />
</packages>
@@ -1,67 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Graphics;
namespace osu.Game.Modes.Osu.Objects.Drawables.Connections
{
public class FollowPoint : Container
{
public double StartTime;
public double EndTime;
public Vector2 EndPosition;
const float width = 8;
public FollowPoint()
{
Origin = Anchor.Centre;
Alpha = 0;
Masking = true;
AutoSizeAxes = Axes.Both;
CornerRadius = width / 2;
EdgeEffect = new EdgeEffect
{
Type = EdgeEffectType.Glow,
Colour = Color4.White.Opacity(0.2f),
Radius = 4,
};
Children = new Drawable[]
{
new Box
{
Size = new Vector2(width),
BlendingMode = BlendingMode.Additive,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Alpha = 0.5f,
},
};
}
protected override void LoadComplete()
{
base.LoadComplete();
Delay(StartTime);
FadeIn(DrawableOsuHitObject.TIME_FADEIN);
ScaleTo(1.5f);
ScaleTo(1, DrawableOsuHitObject.TIME_FADEIN, EasingTypes.Out);
MoveTo(EndPosition, DrawableOsuHitObject.TIME_FADEIN, EasingTypes.Out);
Delay(EndTime - StartTime);
FadeOut(DrawableOsuHitObject.TIME_FADEIN);
Delay(DrawableOsuHitObject.TIME_FADEIN);
Expire(true);
}
}
}
@@ -1,167 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Transforms;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
using OpenTK;
namespace osu.Game.Modes.Osu.Objects.Drawables
{
public class DrawableHitCircle : DrawableOsuHitObject, IDrawableHitObjectWithProxiedApproach
{
private OsuHitObject osuObject;
public ApproachCircle ApproachCircle;
private CirclePiece circle;
private RingPiece ring;
private FlashPiece flash;
private ExplodePiece explode;
private NumberPiece number;
private GlowPiece glow;
public DrawableHitCircle(OsuHitObject h) : base(h)
{
Origin = Anchor.Centre;
osuObject = h;
Position = osuObject.StackedPosition;
Scale = new Vector2(osuObject.Scale);
Children = new Drawable[]
{
glow = new GlowPiece
{
Colour = osuObject.Colour
},
circle = new CirclePiece
{
Colour = osuObject.Colour,
Hit = () =>
{
if (Judgement.Result.HasValue) return false;
((PositionalJudgementInfo)Judgement).PositionOffset = Vector2.Zero; //todo: set to correct value
UpdateJudgement(true);
return true;
},
},
number = new NumberPiece()
{
Text = h is Spinner ? "S" : (HitObject.ComboIndex + 1).ToString(),
},
ring = new RingPiece(),
flash = new FlashPiece(),
explode = new ExplodePiece
{
Colour = osuObject.Colour,
},
ApproachCircle = new ApproachCircle()
{
Colour = osuObject.Colour,
}
};
//may not be so correct
Size = circle.DrawSize;
}
double hit50 = 150;
double hit100 = 80;
double hit300 = 30;
protected override void CheckJudgement(bool userTriggered)
{
if (!userTriggered)
{
if (Judgement.TimeOffset > hit50)
Judgement.Result = HitResult.Miss;
return;
}
double hitOffset = Math.Abs(Judgement.TimeOffset);
OsuJudgementInfo osuJudgement = Judgement as OsuJudgementInfo;
if (hitOffset < hit50)
{
Judgement.Result = HitResult.Hit;
if (hitOffset < hit300)
osuJudgement.Score = OsuScoreResult.Hit300;
else if (hitOffset < hit100)
osuJudgement.Score = OsuScoreResult.Hit100;
else if (hitOffset < hit50)
osuJudgement.Score = OsuScoreResult.Hit50;
}
else
Judgement.Result = HitResult.Miss;
}
protected override void UpdateInitialState()
{
base.UpdateInitialState();
//sane defaults
ring.Alpha = circle.Alpha = number.Alpha = glow.Alpha = 1;
ApproachCircle.Alpha = 0;
ApproachCircle.Scale = new Vector2(4);
explode.Alpha = 0;
}
protected override void UpdatePreemptState()
{
base.UpdatePreemptState();
ApproachCircle.FadeIn(Math.Min(TIME_FADEIN * 2, TIME_PREEMPT));
ApproachCircle.ScaleTo(1.1f, TIME_PREEMPT);
}
protected override void UpdateState(ArmedState state)
{
if (!IsLoaded) return;
base.UpdateState(state);
ApproachCircle.FadeOut();
glow.Delay(osuObject.Duration);
glow.FadeOut(400);
switch (state)
{
case ArmedState.Idle:
Delay(osuObject.Duration + TIME_PREEMPT);
FadeOut(TIME_FADEOUT);
break;
case ArmedState.Miss:
FadeOut(TIME_FADEOUT / 5);
break;
case ArmedState.Hit:
const double flash_in = 40;
flash.FadeTo(0.8f, flash_in);
flash.Delay(flash_in);
flash.FadeOut(100);
explode.FadeIn(flash_in);
Delay(flash_in, true);
//after the flash, we can hide some elements that were behind it
ring.FadeOut();
circle.FadeOut();
number.FadeOut();
FadeOut(800);
ScaleTo(Scale * 1.5f, 400, EasingTypes.OutQuad);
break;
}
}
public Drawable ProxiedLayer => ApproachCircle;
}
}
@@ -1,108 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
namespace osu.Game.Modes.Osu.Objects.Drawables
{
public class DrawableOsuHitObject : DrawableHitObject
{
public const float TIME_PREEMPT = 600;
public const float TIME_FADEIN = 400;
public const float TIME_FADEOUT = 500;
public DrawableOsuHitObject(OsuHitObject hitObject)
: base(hitObject)
{
}
public override JudgementInfo CreateJudgementInfo() => new OsuJudgementInfo { MaxScore = OsuScoreResult.Hit300 };
protected override void UpdateState(ArmedState state)
{
if (!IsLoaded) return;
Flush();
UpdateInitialState();
Delay(HitObject.StartTime - Time.Current - TIME_PREEMPT + Judgement.TimeOffset, true);
UpdatePreemptState();
Delay(TIME_PREEMPT, true);
}
protected virtual void UpdatePreemptState()
{
FadeIn(TIME_FADEIN);
}
protected virtual void UpdateInitialState()
{
Alpha = 0;
}
}
public class OsuJudgementInfo : PositionalJudgementInfo
{
/// <summary>
/// The score the user achieved.
/// </summary>
public OsuScoreResult Score;
/// <summary>
/// The score which would be achievable on a perfect hit.
/// </summary>
public OsuScoreResult MaxScore = OsuScoreResult.Hit300;
public int ScoreValue => scoreToInt(Score);
public int MaxScoreValue => scoreToInt(MaxScore);
private int scoreToInt(OsuScoreResult result)
{
switch (result)
{
default:
return 0;
case OsuScoreResult.Hit50:
return 50;
case OsuScoreResult.Hit100:
return 100;
case OsuScoreResult.Hit300:
return 300;
case OsuScoreResult.SliderTick:
return 10;
}
}
public ComboResult Combo;
}
public enum ComboResult
{
[Description(@"")]
None,
[Description(@"Good")]
Good,
[Description(@"Amazing")]
Perfect
}
public enum OsuScoreResult
{
[Description(@"Miss")]
Miss,
[Description(@"50")]
Hit50,
[Description(@"100")]
Hit100,
[Description(@"300")]
Hit300,
[Description(@"10")]
SliderTick
}
}
@@ -1,185 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics.Containers;
namespace osu.Game.Modes.Osu.Objects.Drawables
{
public class DrawableSlider : DrawableOsuHitObject, IDrawableHitObjectWithProxiedApproach
{
private Slider slider;
private DrawableHitCircle initialCircle;
private List<ISliderProgress> components = new List<ISliderProgress>();
private Container<DrawableSliderTick> ticks;
SliderBody body;
SliderBall ball;
SliderBouncer bouncer1, bouncer2;
public DrawableSlider(Slider s) : base(s)
{
slider = s;
Children = new Drawable[]
{
body = new SliderBody(s)
{
Position = s.StackedPosition,
PathWidth = s.Scale * 64,
},
ticks = new Container<DrawableSliderTick>(),
bouncer1 = new SliderBouncer(s, false)
{
Position = s.Curve.PositionAt(1),
Scale = new Vector2(s.Scale),
},
bouncer2 = new SliderBouncer(s, true)
{
Position = s.StackedPosition,
Scale = new Vector2(s.Scale),
},
ball = new SliderBall(s)
{
Scale = new Vector2(s.Scale),
},
initialCircle = new DrawableHitCircle(new HitCircle
{
//todo: avoid creating this temporary HitCircle.
StartTime = s.StartTime,
Position = s.StackedPosition,
ComboIndex = s.ComboIndex,
Scale = s.Scale,
Colour = s.Colour,
Sample = s.Sample,
}),
};
components.Add(body);
components.Add(ball);
components.Add(bouncer1);
components.Add(bouncer2);
AddNested(initialCircle);
var repeatDuration = s.Curve.Length / s.Velocity;
foreach (var tick in s.Ticks)
{
var repeatStartTime = s.StartTime + tick.RepeatIndex * repeatDuration;
var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? TIME_FADEIN : TIME_FADEIN / 2);
var fadeOutTime = repeatStartTime + repeatDuration;
var drawableTick = new DrawableSliderTick(tick)
{
FadeInTime = fadeInTime,
FadeOutTime = fadeOutTime,
Position = tick.Position,
};
ticks.Add(drawableTick);
AddNested(drawableTick);
}
}
// Since the DrawableSlider itself is just a container without a size we need to
// pass all input through.
public override bool Contains(Vector2 screenSpacePos) => true;
int currentRepeat;
protected override void Update()
{
base.Update();
double progress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
int repeat = (int)(progress * slider.RepeatCount);
progress = (progress * slider.RepeatCount) % 1;
if (repeat > currentRepeat)
{
if (repeat < slider.RepeatCount && ball.Tracking)
PlaySample();
currentRepeat = repeat;
}
if (repeat % 2 == 1)
progress = 1 - progress;
bouncer2.Position = slider.Curve.PositionAt(body.SnakedEnd ?? 0);
//todo: we probably want to reconsider this before adding scoring, but it looks and feels nice.
if (initialCircle.Judgement?.Result != HitResult.Hit)
initialCircle.Position = slider.Curve.PositionAt(progress);
foreach (var c in components) c.UpdateProgress(progress, repeat);
foreach (var t in ticks.Children) t.Tracking = ball.Tracking;
}
protected override void CheckJudgement(bool userTriggered)
{
var j = Judgement as OsuJudgementInfo;
var sc = initialCircle.Judgement as OsuJudgementInfo;
if (!userTriggered && Time.Current >= HitObject.EndTime)
{
var ticksCount = ticks.Children.Count() + 1;
var ticksHit = ticks.Children.Count(t => t.Judgement.Result == HitResult.Hit);
if (sc.Result == HitResult.Hit)
ticksHit++;
var hitFraction = (double)ticksHit / ticksCount;
if (hitFraction == 1 && sc.Score == OsuScoreResult.Hit300)
j.Score = OsuScoreResult.Hit300;
else if (hitFraction >= 0.5 && sc.Score >= OsuScoreResult.Hit100)
j.Score = OsuScoreResult.Hit100;
else if (hitFraction > 0)
j.Score = OsuScoreResult.Hit50;
else
j.Score = OsuScoreResult.Miss;
j.Result = j.Score != OsuScoreResult.Miss ? HitResult.Hit : HitResult.Miss;
}
}
protected override void UpdateInitialState()
{
base.UpdateInitialState();
body.Alpha = 1;
//we need to be present to handle input events. note that we still don't get enough events (we don't get a position if the mouse hasn't moved since the slider appeared).
ball.AlwaysPresent = true;
ball.Alpha = 0;
}
protected override void UpdateState(ArmedState state)
{
base.UpdateState(state);
ball.FadeIn();
Delay(HitObject.Duration, true);
body.FadeOut(160);
ball.FadeOut(160);
FadeOut(800);
}
public Drawable ProxiedLayer => initialCircle.ApproachCircle;
}
internal interface ISliderProgress
{
void UpdateProgress(double progress, int repeat);
}
}
@@ -1,120 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes.Objects.Drawables;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Modes.Osu.Objects.Drawables
{
public class DrawableSliderTick : DrawableOsuHitObject
{
private SliderTick sliderTick;
public double FadeInTime;
public double FadeOutTime;
public bool Tracking;
public override bool RemoveWhenNotAlive => false;
public override JudgementInfo CreateJudgementInfo() => new OsuJudgementInfo { MaxScore = OsuScoreResult.SliderTick };
public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick)
{
this.sliderTick = sliderTick;
Size = new Vector2(16) * sliderTick.Scale;
Masking = true;
CornerRadius = Size.X / 2;
Origin = Anchor.Centre;
BorderThickness = 2;
BorderColour = Color4.White;
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = sliderTick.Colour,
Alpha = 0.3f,
}
};
}
private SampleChannel sample;
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
string sampleSet = (HitObject.Sample?.Set ?? SampleSet.Normal).ToString().ToLower();
sample = audio.Sample.Get($@"Gameplay/{sampleSet}-slidertick");
}
protected override void PlaySample()
{
sample?.Play();
}
protected override void CheckJudgement(bool userTriggered)
{
var j = Judgement as OsuJudgementInfo;
if (Judgement.TimeOffset >= 0)
{
j.Result = Tracking ? HitResult.Hit : HitResult.Miss;
j.Score = Tracking ? OsuScoreResult.SliderTick : OsuScoreResult.Miss;
}
}
protected override void UpdatePreemptState()
{
var animIn = Math.Min(150, sliderTick.StartTime - FadeInTime);
ScaleTo(0.5f);
ScaleTo(1.2f, animIn);
FadeIn(animIn);
Delay(animIn);
ScaleTo(1, 150, EasingTypes.Out);
Delay(-animIn);
}
protected override void UpdateState(ArmedState state)
{
if (!IsLoaded) return;
base.UpdateState(state);
switch (state)
{
case ArmedState.Idle:
Delay(FadeOutTime - sliderTick.StartTime);
FadeOut();
break;
case ArmedState.Miss:
FadeOut(160);
FadeColour(Color4.Red, 80);
break;
case ArmedState.Hit:
FadeOut(120, EasingTypes.OutQuint);
ScaleTo(Scale * 1.5f, 120, EasingTypes.OutQuint);
break;
}
}
}
}
@@ -1,158 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Transforms;
using osu.Framework.MathUtils;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Modes.Osu.Objects.Drawables
{
public class DrawableSpinner : DrawableOsuHitObject
{
private Spinner spinner;
private SpinnerDisc disc;
private SpinnerBackground background;
private Container circleContainer;
private DrawableHitCircle circle;
public DrawableSpinner(Spinner s) : base(s)
{
Origin = Anchor.Centre;
Position = s.Position;
//take up full playfield.
Size = new Vector2(512);
spinner = s;
Children = new Drawable[]
{
background = new SpinnerBackground
{
Alpha = 0,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
DiscColour = Color4.Black
},
disc = new SpinnerDisc
{
Alpha = 0,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
DiscColour = s.Colour
},
circleContainer = new Container
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Children = new []
{
circle = new DrawableHitCircle(s)
{
Interactive = false,
Position = Vector2.Zero,
Anchor = Anchor.Centre,
}
}
}
};
background.Scale = scaleToCircle;
disc.Scale = scaleToCircle;
}
public override bool Contains(Vector2 screenSpacePos) => true;
protected override void CheckJudgement(bool userTriggered)
{
if (Time.Current < HitObject.StartTime) return;
var j = Judgement as OsuJudgementInfo;
disc.ScaleTo(Interpolation.ValueAt(Math.Sqrt(Progress), scaleToCircle, Vector2.One, 0, 1), 100);
if (Progress >= 1)
disc.Complete = true;
if (!userTriggered && Time.Current >= HitObject.EndTime)
{
if (Progress >= 1)
{
j.Score = OsuScoreResult.Hit300;
j.Result = HitResult.Hit;
}
else if (Progress > .9)
{
j.Score = OsuScoreResult.Hit100;
j.Result = HitResult.Hit;
}
else if (Progress > .75)
{
j.Score = OsuScoreResult.Hit50;
j.Result = HitResult.Hit;
}
else
{
j.Score = OsuScoreResult.Miss;
if (Time.Current >= HitObject.EndTime)
j.Result = HitResult.Miss;
}
}
}
private Vector2 scaleToCircle => (circle.Scale * circle.DrawWidth / DrawWidth) * 0.95f;
private float spinsPerMinuteNeeded = 100 + (5 * 15); //TODO: read per-map OD and place it on the 5
private float rotationsNeeded => (float)(spinsPerMinuteNeeded * (spinner.EndTime - spinner.StartTime) / 60000f);
public float Progress => MathHelper.Clamp(disc.RotationAbsolute / 360 / rotationsNeeded, 0, 1);
protected override void UpdatePreemptState()
{
base.UpdatePreemptState();
circleContainer.ScaleTo(1, 400, EasingTypes.OutElastic);
background.Delay(TIME_PREEMPT - 500);
background.ScaleTo(scaleToCircle * 1.2f, 400, EasingTypes.OutQuint);
background.FadeIn(200);
background.Delay(400);
background.ScaleTo(1, 250, EasingTypes.OutQuint);
disc.Delay(TIME_PREEMPT - 50);
disc.FadeIn(200);
}
protected override void UpdateState(ArmedState state)
{
if (!IsLoaded) return;
base.UpdateState(state);
Delay(HitObject.Duration, true);
FadeOut(160);
switch (state)
{
case ArmedState.Hit:
ScaleTo(Scale * 1.2f, 320, EasingTypes.Out);
break;
case ArmedState.Miss:
ScaleTo(Scale * 0.8f, 320, EasingTypes.In);
break;
}
}
}
}
@@ -1,85 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes.Objects.Drawables;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Modes.Osu.Objects.Drawables
{
public class HitExplosion : FillFlowContainer
{
private readonly OsuJudgementInfo judgement;
private SpriteText line1;
private SpriteText line2;
public HitExplosion(OsuJudgementInfo judgement, OsuHitObject h = null)
{
this.judgement = judgement;
AutoSizeAxes = Axes.Both;
Origin = Anchor.Centre;
Direction = FillDirection.Down;
Spacing = new Vector2(0, 2);
Position = (h?.StackedEndPosition ?? Vector2.Zero) + judgement.PositionOffset;
Children = new Drawable[]
{
line1 = new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Text = judgement.Score.GetDescription(),
Font = @"Venera",
TextSize = 16,
},
line2 = new OsuSpriteText
{
Text = judgement.Combo.GetDescription(),
Font = @"Venera",
TextSize = 11,
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
if (judgement.Result == HitResult.Miss)
{
FadeInFromZero(60);
ScaleTo(1.6f);
ScaleTo(1, 100, EasingTypes.In);
MoveToOffset(new Vector2(0, 100), 800, EasingTypes.InQuint);
RotateTo(40, 800, EasingTypes.InQuint);
Delay(600);
FadeOut(200);
}
else
{
line1.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint);
line2.TransformSpacingTo(new Vector2(14, 0), 1800, EasingTypes.OutQuint);
FadeOut(500);
}
switch (judgement.Result)
{
case HitResult.Miss:
Colour = Color4.Red;
break;
}
Expire();
}
}
}
@@ -1,52 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
{
public class SliderBouncer : Container, ISliderProgress
{
private readonly Slider slider;
private readonly bool isEnd;
private TextAwesome icon;
public SliderBouncer(Slider slider, bool isEnd)
{
this.slider = slider;
this.isEnd = isEnd;
AutoSizeAxes = Axes.Both;
BlendingMode = BlendingMode.Additive;
Origin = Anchor.Centre;
Children = new Drawable[]
{
icon = new TextAwesome
{
Icon = FontAwesome.fa_eercast,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
TextSize = 48,
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
icon.RotateTo(360, 1000);
icon.Loop();
}
public void UpdateProgress(double progress, int repeat)
{
if (Time.Current < slider.StartTime)
Alpha = 0;
Alpha = repeat + 1 < slider.RepeatCount && repeat % 2 == (isEnd ? 0 : 1) ? 1 : 0;
}
}
}
@@ -1,10 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
{
public class SpinnerBackground : SpinnerDisc
{
public override bool HandleInput => false;
}
}
@@ -1,205 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Input;
using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
{
public class SpinnerDisc : CircularContainer
{
public override bool Contains(Vector2 screenSpacePos) => true;
protected Sprite Disc;
public SRGBColour DiscColour
{
get { return Disc.Colour; }
set { Disc.Colour = value; }
}
Color4 completeColour;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
completeColour = colours.YellowLight.Opacity(0.8f);
}
class SpinnerBorder : Container
{
public SpinnerBorder()
{
Origin = Anchor.Centre;
Anchor = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
layout();
}
private int lastLayoutDotCount;
private void layout()
{
int count = (int)(MathHelper.Pi * ScreenSpaceDrawQuad.Width / 9);
if (count == lastLayoutDotCount) return;
lastLayoutDotCount = count;
while (Children.Count() < count)
{
Add(new CircularContainer
{
Colour = Color4.White,
RelativePositionAxes = Axes.Both,
Origin = Anchor.Centre,
Size = new Vector2(1 / ScreenSpaceDrawQuad.Width * 2000),
Children = new[]
{
new Box
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
}
}
});
}
var size = new Vector2(1 / ScreenSpaceDrawQuad.Width * 2000);
int i = 0;
foreach (var d in Children)
{
d.Size = size;
d.Position = new Vector2(
0.5f + (float)Math.Sin((float)i / count * 2 * MathHelper.Pi) / 2,
0.5f + (float)Math.Cos((float)i / count * 2 * MathHelper.Pi) / 2
);
i++;
}
}
protected override void Update()
{
base.Update();
layout();
}
}
public SpinnerDisc()
{
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{
Disc = new Box
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Alpha = 0.2f,
},
new SpinnerBorder()
};
}
bool tracking;
public bool Tracking
{
get { return tracking; }
set
{
if (value == tracking) return;
tracking = value;
Disc.FadeTo(tracking ? 0.5f : 0.2f, 100);
}
}
bool complete;
public bool Complete
{
get { return complete; }
set
{
if (value == complete) return;
complete = value;
Disc.FadeColour(completeColour, 200);
updateCompleteTick();
}
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
Tracking = true;
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
Tracking = false;
return base.OnMouseUp(state, args);
}
protected override bool OnMouseMove(InputState state)
{
Tracking |= state.Mouse.HasMainButtonPressed;
mousePosition = state.Mouse.Position;
return base.OnMouseMove(state);
}
private Vector2 mousePosition;
private float lastAngle;
private float currentRotation;
public float RotationAbsolute;
private int completeTick;
private bool updateCompleteTick() => completeTick != (completeTick = (int)(RotationAbsolute / 360));
protected override void Update()
{
base.Update();
var thisAngle = -(float)MathHelper.RadiansToDegrees(Math.Atan2(mousePosition.X - DrawSize.X / 2, mousePosition.Y - DrawSize.Y / 2));
if (tracking)
{
if (thisAngle - lastAngle > 180)
lastAngle += 360;
else if (lastAngle - thisAngle > 180)
lastAngle -= 360;
currentRotation += thisAngle - lastAngle;
RotationAbsolute += Math.Abs(thisAngle - lastAngle);
}
lastAngle = thisAngle;
if (Complete && updateCompleteTick())
{
Disc.Flush(flushType: typeof(TransformAlpha));
Disc.FadeTo(0.75f, 30, EasingTypes.OutExpo);
Disc.Delay(30);
Disc.FadeTo(0.5f, 250, EasingTypes.OutQuint);
}
RotateTo(currentRotation, 100, EasingTypes.OutExpo);
}
}
}
@@ -1,48 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Game.Modes.Objects;
using OpenTK;
using osu.Game.Beatmaps;
namespace osu.Game.Modes.Osu.Objects
{
public abstract class OsuHitObject : HitObject
{
public Vector2 Position { get; set; }
public Vector2 StackedPosition => Position + StackOffset;
public virtual Vector2 EndPosition => Position;
public Vector2 StackedEndPosition => EndPosition + StackOffset;
public virtual int StackHeight { get; set; }
public Vector2 StackOffset => new Vector2(StackHeight * Scale * -6.4f);
public float Scale { get; set; } = 1;
public abstract HitObjectType Type { get; }
public override void SetDefaultsFromBeatmap(Beatmap beatmap)
{
base.SetDefaultsFromBeatmap(beatmap);
Scale = (1.0f - 0.7f * (beatmap.BeatmapInfo.BaseDifficulty.CircleSize - 5) / 5) / 2;
}
}
[Flags]
public enum HitObjectType
{
Circle = 1 << 0,
Slider = 1 << 1,
NewCombo = 1 << 2,
Spinner = 1 << 3,
ColourHax = 122,
Hold = 1 << 7,
SliderTick = 1 << 8,
}
}
@@ -1,201 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using System;
using System.Diagnostics;
using System.Linq;
namespace osu.Game.Modes.Osu.Objects
{
class OsuHitObjectDifficulty
{
/// <summary>
/// Factor by how much speed / aim strain decays per second.
/// </summary>
/// <remarks>
/// These values are results of tweaking a lot and taking into account general feedback.
/// Opinionated observation: Speed is easier to maintain than accurate jumps.
/// </remarks>
internal static readonly double[] DECAY_BASE = { 0.3, 0.15 };
/// <summary>
/// Pseudo threshold values to distinguish between "singles" and "streams"
/// </summary>
/// <remarks>
/// Of course the border can not be defined clearly, therefore the algorithm has a smooth transition between those values.
/// They also are based on tweaking and general feedback.
/// </remarks>
private const double stream_spacing_threshold = 110,
single_spacing_threshold = 125;
/// <summary>
/// Scaling values for weightings to keep aim and speed difficulty in balance.
/// </summary>
/// <remarks>
/// Found from testing a very large map pool (containing all ranked maps) and keeping the average values the same.
/// </remarks>
private static readonly double[] spacing_weight_scaling = { 1400, 26.25 };
/// <summary>
/// Almost the normed diameter of a circle (104 osu pixel). That is -after- position transforming.
/// </summary>
private const double almost_diameter = 90;
internal OsuHitObject BaseHitObject;
internal double[] Strains = { 1, 1 };
internal int MaxCombo = 1;
private float scalingFactor;
private float lazySliderLength;
private Vector2 startPosition;
private Vector2 endPosition;
internal OsuHitObjectDifficulty(OsuHitObject baseHitObject)
{
BaseHitObject = baseHitObject;
float circleRadius = baseHitObject.Scale * 64;
Slider slider = BaseHitObject as Slider;
if (slider != null)
MaxCombo += slider.Ticks.Count();
// We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps.
scalingFactor = (52.0f / circleRadius);
if (circleRadius < 30)
{
float smallCircleBonus = Math.Min(30.0f - circleRadius, 5.0f) / 50.0f;
scalingFactor *= 1.0f + smallCircleBonus;
}
lazySliderLength = 0;
startPosition = baseHitObject.StackedPosition;
// Calculate approximation of lazy movement on the slider
if (slider != null)
{
float sliderFollowCircleRadius = circleRadius * 3; // Not sure if this is correct, but here we do not need 100% exact values. This comes pretty darn close in my tests.
// For simplifying this step we use actual osu! coordinates and simply scale the length, that we obtain by the ScalingFactor later
Vector2 cursorPos = startPosition;
Action<Vector2> addSliderVertex = delegate (Vector2 pos)
{
Vector2 difference = pos - cursorPos;
float distance = difference.Length;
// Did we move away too far?
if (distance > sliderFollowCircleRadius)
{
// Yep, we need to move the cursor
difference.Normalize(); // Obtain the direction of difference. We do no longer need the actual difference
distance -= sliderFollowCircleRadius;
cursorPos += difference * distance; // We move the cursor just as far as needed to stay in the follow circle
lazySliderLength += distance;
}
};
// Actual computation of the first lazy curve
foreach (var tick in slider.Ticks)
addSliderVertex(tick.StackedPosition);
addSliderVertex(baseHitObject.StackedEndPosition);
lazySliderLength *= scalingFactor;
endPosition = cursorPos;
}
// We have a normal HitCircle or a spinner
else
endPosition = startPosition;
}
internal void CalculateStrains(OsuHitObjectDifficulty previousHitObject, double timeRate)
{
calculateSpecificStrain(previousHitObject, OsuDifficultyCalculator.DifficultyType.Speed, timeRate);
calculateSpecificStrain(previousHitObject, OsuDifficultyCalculator.DifficultyType.Aim, timeRate);
}
// Caution: The subjective values are strong with this one
private static double spacingWeight(double distance, OsuDifficultyCalculator.DifficultyType type)
{
switch (type)
{
case OsuDifficultyCalculator.DifficultyType.Speed:
if (distance > single_spacing_threshold)
return 2.5;
else if (distance > stream_spacing_threshold)
return 1.6 + 0.9 * (distance - stream_spacing_threshold) / (single_spacing_threshold - stream_spacing_threshold);
else if (distance > almost_diameter)
return 1.2 + 0.4 * (distance - almost_diameter) / (stream_spacing_threshold - almost_diameter);
else if (distance > almost_diameter / 2)
return 0.95 + 0.25 * (distance - (almost_diameter / 2)) / (almost_diameter / 2);
else
return 0.95;
case OsuDifficultyCalculator.DifficultyType.Aim:
return Math.Pow(distance, 0.99);
}
Debug.Assert(false, "Invalid osu difficulty hit object type.");
return 0;
}
private void calculateSpecificStrain(OsuHitObjectDifficulty previousHitObject, OsuDifficultyCalculator.DifficultyType type, double timeRate)
{
double addition = 0;
double timeElapsed = (BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime) / timeRate;
double decay = Math.Pow(DECAY_BASE[(int)type], timeElapsed / 1000);
if (BaseHitObject.Type == HitObjectType.Spinner)
{
// Do nothing for spinners
}
else if (BaseHitObject.Type == HitObjectType.Slider)
{
switch (type)
{
case OsuDifficultyCalculator.DifficultyType.Speed:
// For speed strain we treat the whole slider as a single spacing entity, since "Speed" is about how hard it is to click buttons fast.
// The spacing weight exists to differentiate between being able to easily alternate or having to single.
addition =
spacingWeight(previousHitObject.lazySliderLength +
DistanceTo(previousHitObject), type) *
spacing_weight_scaling[(int)type];
break;
case OsuDifficultyCalculator.DifficultyType.Aim:
// For Aim strain we treat each slider segment and the jump after the end of the slider as separate jumps, since movement-wise there is no difference
// to multiple jumps.
addition =
(
spacingWeight(previousHitObject.lazySliderLength, type) +
spacingWeight(DistanceTo(previousHitObject), type)
) *
spacing_weight_scaling[(int)type];
break;
}
}
else if (BaseHitObject.Type == HitObjectType.Circle)
{
addition = spacingWeight(DistanceTo(previousHitObject), type) * spacing_weight_scaling[(int)type];
}
// Scale addition by the time, that elapsed. Filter out HitObjects that are too close to be played anyway to avoid crazy values by division through close to zero.
// You will never find maps that require this amongst ranked maps.
addition /= Math.Max(timeElapsed, 50);
Strains[(int)type] = previousHitObject.Strains[(int)type] * decay + addition;
}
internal double DistanceTo(OsuHitObjectDifficulty other)
{
// Scale the distance by circle size.
return (startPosition - other.endPosition).Length * scalingFactor;
}
}
}
@@ -1,110 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Globalization;
using osu.Game.Beatmaps.Samples;
using osu.Game.Modes.Objects;
using OpenTK;
namespace osu.Game.Modes.Osu.Objects
{
public class OsuHitObjectParser : HitObjectParser
{
public override HitObject Parse(string text)
{
string[] split = text.Split(',');
var type = (HitObjectType)int.Parse(split[3]);
bool combo = type.HasFlag(HitObjectType.NewCombo);
type &= (HitObjectType)0xF;
type &= ~HitObjectType.NewCombo;
OsuHitObject result;
switch (type)
{
case HitObjectType.Circle:
result = new HitCircle
{
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1]))
};
break;
case HitObjectType.Slider:
CurveTypes curveType = CurveTypes.Catmull;
int repeatCount;
double length = 0;
List<Vector2> points = new List<Vector2>();
points.Add(new Vector2(int.Parse(split[0]), int.Parse(split[1])));
string[] pointsplit = split[5].Split('|');
for (int i = 0; i < pointsplit.Length; i++)
{
if (pointsplit[i].Length == 1)
{
switch (pointsplit[i])
{
case @"C":
curveType = CurveTypes.Catmull;
break;
case @"B":
curveType = CurveTypes.Bezier;
break;
case @"L":
curveType = CurveTypes.Linear;
break;
case @"P":
curveType = CurveTypes.PerfectCurve;
break;
}
continue;
}
string[] temp = pointsplit[i].Split(':');
Vector2 v = new Vector2(
(int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture),
(int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)
);
points.Add(v);
}
repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
if (repeatCount > 9000)
{
throw new ArgumentOutOfRangeException("wacky man");
}
if (split.Length > 7)
length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
result = new Slider
{
ControlPoints = points,
Length = length,
CurveType = curveType,
RepeatCount = repeatCount,
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1]))
};
break;
case HitObjectType.Spinner:
result = new Spinner
{
Length = Convert.ToDouble(split[5], CultureInfo.InvariantCulture) - Convert.ToDouble(split[2], CultureInfo.InvariantCulture),
Position = new Vector2(512, 384) / 2,
};
break;
default:
throw new InvalidOperationException($@"Unknown hit object type {type}");
}
result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
result.Sample = new HitSampleInfo
{
Type = (SampleType)int.Parse(split[4]),
Set = SampleSet.Soft,
};
result.NewCombo = combo;
// TODO: "addition" field
return result;
}
}
}
-124
View File
@@ -1,124 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Samples;
using osu.Game.Beatmaps.Timing;
using System;
using System.Collections.Generic;
namespace osu.Game.Modes.Osu.Objects
{
public class Slider : OsuHitObject
{
public override double EndTime => StartTime + RepeatCount * Curve.Length / Velocity;
public override Vector2 EndPosition => RepeatCount % 2 == 0 ? Position : Curve.PositionAt(1);
private int stackHeight;
public override int StackHeight
{
get { return stackHeight; }
set
{
stackHeight = value;
Curve.Offset = StackOffset;
}
}
public List<Vector2> ControlPoints
{
get { return Curve.ControlPoints; }
set { Curve.ControlPoints = value; }
}
public double Length
{
get { return Curve.Length; }
set { Curve.Length = value; }
}
public CurveTypes CurveType
{
get { return Curve.CurveType; }
set { Curve.CurveType = value; }
}
public double Velocity;
public double TickDistance;
public override void SetDefaultsFromBeatmap(Beatmap beatmap)
{
base.SetDefaultsFromBeatmap(beatmap);
var baseDifficulty = beatmap.BeatmapInfo.BaseDifficulty;
ControlPoint overridePoint;
ControlPoint timingPoint = beatmap.TimingPointAt(StartTime, out overridePoint);
var velocityAdjustment = overridePoint?.VelocityAdjustment ?? 1;
var baseVelocity = 100 * baseDifficulty.SliderMultiplier / velocityAdjustment;
Velocity = baseVelocity / timingPoint.BeatLength;
TickDistance = baseVelocity / baseDifficulty.SliderTickRate;
}
public int RepeatCount = 1;
internal readonly SliderCurve Curve = new SliderCurve();
public IEnumerable<SliderTick> Ticks
{
get
{
if (TickDistance == 0) yield break;
var length = Curve.Length;
var tickDistance = Math.Min(TickDistance, length);
var repeatDuration = length / Velocity;
var minDistanceFromEnd = Velocity * 0.01;
for (var repeat = 0; repeat < RepeatCount; repeat++)
{
var repeatStartTime = StartTime + repeat * repeatDuration;
var reversed = repeat % 2 == 1;
for (var d = tickDistance; d <= length; d += tickDistance)
{
if (d > length - minDistanceFromEnd)
break;
var distanceProgress = d / length;
var timeProgress = reversed ? 1 - distanceProgress : distanceProgress;
yield return new SliderTick
{
RepeatIndex = repeat,
StartTime = repeatStartTime + timeProgress * repeatDuration,
Position = Curve.PositionAt(distanceProgress),
StackHeight = StackHeight,
Scale = Scale,
Colour = Colour,
Sample = new HitSampleInfo
{
Type = SampleType.None,
Set = SampleSet.Soft,
},
};
}
}
}
}
public override HitObjectType Type => HitObjectType.Slider;
}
public enum CurveTypes
{
Catmull,
Bezier,
Linear,
PerfectCurve
}
}
-14
View File
@@ -1,14 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Modes.Osu.Objects
{
public class Spinner : OsuHitObject
{
public double Length;
public override double EndTime => StartTime + Length;
public override HitObjectType Type => HitObjectType.Spinner;
}
}
@@ -1,193 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Modes.Osu.Objects;
using System;
using System.Collections.Generic;
using osu.Game.Modes.Objects;
namespace osu.Game.Modes.Osu
{
public class OsuDifficultyCalculator : DifficultyCalculator<OsuHitObject>
{
private const double star_scaling_factor = 0.0675;
private const double extreme_scaling_factor = 0.5;
protected override PlayMode PlayMode => PlayMode.Osu;
/// <summary>
/// HitObjects are stored as a member variable.
/// </summary>
internal List<OsuHitObjectDifficulty> DifficultyHitObjects = new List<OsuHitObjectDifficulty>();
public OsuDifficultyCalculator(Beatmap beatmap) : base(beatmap)
{
}
protected override HitObjectConverter<OsuHitObject> Converter => new OsuHitObjectConverter();
protected override void PreprocessHitObjects()
{
foreach (var h in Objects)
if (h.Type == HitObjectType.Slider)
((Slider)h).Curve.Calculate();
}
protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty)
{
// Fill our custom DifficultyHitObject class, that carries additional information
DifficultyHitObjects.Clear();
foreach (var hitObject in Objects)
DifficultyHitObjects.Add(new OsuHitObjectDifficulty(hitObject));
// Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure.
DifficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime));
if (!CalculateStrainValues()) return 0;
double speedDifficulty = CalculateDifficulty(DifficultyType.Speed);
double aimDifficulty = CalculateDifficulty(DifficultyType.Aim);
// OverallDifficulty is not considered in this algorithm and neither is HpDrainRate. That means, that in this form the algorithm determines how hard it physically is
// to play the map, assuming, that too much of an error will not lead to a death.
// It might be desirable to include OverallDifficulty into map difficulty, but in my personal opinion it belongs more to the weighting of the actual peformance
// and is superfluous in the beatmap difficulty rating.
// If it were to be considered, then I would look at the hit window of normal HitCircles only, since Sliders and Spinners are (almost) "free" 300s and take map length
// into account as well.
// The difficulty can be scaled by any desired metric.
// In osu!tp it gets squared to account for the rapid increase in difficulty as the limit of a human is approached. (Of course it also gets scaled afterwards.)
// It would not be suitable for a star rating, therefore:
// The following is a proposal to forge a star rating from 0 to 5. It consists of taking the square root of the difficulty, since by simply scaling the easier
// 5-star maps would end up with one star.
double speedStars = Math.Sqrt(speedDifficulty) * star_scaling_factor;
double aimStars = Math.Sqrt(aimDifficulty) * star_scaling_factor;
if (categoryDifficulty != null)
{
categoryDifficulty.Add("Aim", aimStars.ToString("0.00"));
categoryDifficulty.Add("Speed", speedStars.ToString("0.00"));
double hitWindow300 = 30/*HitObjectManager.HitWindow300*/ / TimeRate;
double preEmpt = 450/*HitObjectManager.PreEmpt*/ / TimeRate;
categoryDifficulty.Add("OD", (-(hitWindow300 - 80.0) / 6.0).ToString("0.00"));
categoryDifficulty.Add("AR", (preEmpt > 1200.0 ? -(preEmpt - 1800.0) / 120.0 : -(preEmpt - 1200.0) / 150.0 + 5.0).ToString("0.00"));
int maxCombo = 0;
foreach (OsuHitObjectDifficulty hitObject in DifficultyHitObjects)
maxCombo += hitObject.MaxCombo;
categoryDifficulty.Add("Max combo", maxCombo.ToString());
}
// Again, from own observations and from the general opinion of the community a map with high speed and low aim (or vice versa) difficulty is harder,
// than a map with mediocre difficulty in both. Therefore we can not just add both difficulties together, but will introduce a scaling that favors extremes.
double starRating = speedStars + aimStars + Math.Abs(speedStars - aimStars) * extreme_scaling_factor;
// Another approach to this would be taking Speed and Aim separately to a chosen power, which again would be equivalent. This would be more convenient if
// the hit window size is to be considered as well.
// Note: The star rating is tuned extremely tight! Airman (/b/104229) and Freedom Dive (/b/126645), two of the hardest ranked maps, both score ~4.66 stars.
// Expect the easier kind of maps that officially get 5 stars to obtain around 2 by this metric. The tutorial still scores about half a star.
// Tune by yourself as you please. ;)
return starRating;
}
protected bool CalculateStrainValues()
{
// Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment.
List<OsuHitObjectDifficulty>.Enumerator hitObjectsEnumerator = DifficultyHitObjects.GetEnumerator();
if (!hitObjectsEnumerator.MoveNext()) return false;
OsuHitObjectDifficulty currentHitObject = hitObjectsEnumerator.Current;
OsuHitObjectDifficulty nextHitObject;
// First hitObject starts at strain 1. 1 is the default for strain values, so we don't need to set it here. See DifficultyHitObject.
while (hitObjectsEnumerator.MoveNext())
{
nextHitObject = hitObjectsEnumerator.Current;
nextHitObject.CalculateStrains(currentHitObject, TimeRate);
currentHitObject = nextHitObject;
}
return true;
}
/// <summary>
/// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size STRAIN_STEP.
/// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain.
/// The higher this value, the less strains there will be, indirectly giving long beatmaps an advantage.
/// </summary>
protected const double STRAIN_STEP = 400;
/// <summary>
/// The weighting of each strain value decays to this number * it's previous value
/// </summary>
protected const double DECAY_WEIGHT = 0.9;
protected double CalculateDifficulty(DifficultyType type)
{
double actualStrainStep = STRAIN_STEP * TimeRate;
// Find the highest strain value within each strain step
List<double> highestStrains = new List<double>();
double intervalEndTime = actualStrainStep;
double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval
OsuHitObjectDifficulty previousHitObject = null;
foreach (OsuHitObjectDifficulty hitObject in DifficultyHitObjects)
{
// While we are beyond the current interval push the currently available maximum to our strain list
while (hitObject.BaseHitObject.StartTime > intervalEndTime)
{
highestStrains.Add(maximumStrain);
// The maximum strain of the next interval is not zero by default! We need to take the last hitObject we encountered, take its strain and apply the decay
// until the beginning of the next interval.
if (previousHitObject == null)
{
maximumStrain = 0;
}
else
{
double decay = Math.Pow(OsuHitObjectDifficulty.DECAY_BASE[(int)type], (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000);
maximumStrain = previousHitObject.Strains[(int)type] * decay;
}
// Go to the next time interval
intervalEndTime += actualStrainStep;
}
// Obtain maximum strain
maximumStrain = Math.Max(hitObject.Strains[(int)type], maximumStrain);
previousHitObject = hitObject;
}
// Build the weighted sum over the highest strains for each interval
double difficulty = 0;
double weight = 1;
highestStrains.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain.
foreach (double strain in highestStrains)
{
difficulty += weight * strain;
weight *= DECAY_WEIGHT;
}
return difficulty;
}
// Those values are used as array indices. Be careful when changing them!
public enum DifficultyType : int
{
Speed = 0,
Aim,
};
}
}
-47
View File
@@ -1,47 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.UI;
namespace osu.Game.Modes.Osu
{
public class OsuRuleset : Ruleset
{
public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay();
public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new OsuHitRenderer { Beatmap = beatmap };
public override IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new[]
{
new BeatmapStatistic
{
Name = @"Circle count",
Content = beatmap.Beatmap.HitObjects.Count(h => h is HitCircle).ToString(),
Icon = FontAwesome.fa_dot_circle_o
},
new BeatmapStatistic
{
Name = @"Slider count",
Content = beatmap.Beatmap.HitObjects.Count(h => h is Slider).ToString(),
Icon = FontAwesome.fa_circle_o
}
};
public override FontAwesome Icon => FontAwesome.fa_osu_osu_o;
public override HitObjectParser CreateHitObjectParser() => new OsuHitObjectParser();
public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => new OsuScoreProcessor(hitObjectCount);
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap);
protected override PlayMode PlayMode => PlayMode.Osu;
}
}
-47
View File
@@ -1,47 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects.Drawables;
namespace osu.Game.Modes.Osu
{
class OsuScoreProcessor : ScoreProcessor
{
public OsuScoreProcessor(int hitObjectCount)
: base(hitObjectCount)
{
Health.Value = 1;
}
protected override void UpdateCalculations(JudgementInfo judgement)
{
if (judgement != null)
{
switch (judgement.Result)
{
case HitResult.Hit:
Combo.Value++;
Health.Value += 0.1f;
break;
case HitResult.Miss:
Combo.Value = 0;
Health.Value -= 0.2f;
break;
}
}
int score = 0;
int maxScore = 0;
foreach (OsuJudgementInfo j in Judgements)
{
score += j.ScoreValue;
maxScore += j.MaxScoreValue;
}
TotalScore.Value = score;
Accuracy.Value = (double)score / maxScore;
}
}
}
-29
View File
@@ -1,29 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.Objects.Drawables;
using osu.Game.Modes.UI;
namespace osu.Game.Modes.Osu.UI
{
public class OsuHitRenderer : HitRenderer<OsuHitObject>
{
protected override HitObjectConverter<OsuHitObject> Converter => new OsuHitObjectConverter();
protected override Playfield CreatePlayfield() => new OsuPlayfield();
protected override DrawableHitObject GetVisualRepresentation(OsuHitObject h)
{
if (h is HitCircle)
return new DrawableHitCircle(h as HitCircle);
if (h is Slider)
return new DrawableSlider(h as Slider);
if (h is Spinner)
return new DrawableSpinner(h as Spinner);
return null;
}
}
}
-88
View File
@@ -1,88 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.Objects.Drawables;
using osu.Game.Modes.Osu.Objects.Drawables.Connections;
using osu.Game.Modes.UI;
using System.Linq;
namespace osu.Game.Modes.Osu.UI
{
public class OsuPlayfield : Playfield
{
private Container approachCircles;
private Container judgementLayer;
private ConnectionRenderer<OsuHitObject> connectionLayer;
public override Vector2 Size
{
get
{
var parentSize = Parent.DrawSize;
var aspectSize = parentSize.X * 0.75f < parentSize.Y ? new Vector2(parentSize.X, parentSize.X * 0.75f) : new Vector2(parentSize.Y * 4f / 3f, parentSize.Y);
return new Vector2(aspectSize.X / parentSize.X, aspectSize.Y / parentSize.Y) * base.Size;
}
}
public OsuPlayfield()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(0.75f);
Add(new Drawable[]
{
connectionLayer = new FollowPointRenderer
{
RelativeSizeAxes = Axes.Both,
Depth = 2,
},
judgementLayer = new Container
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
},
approachCircles = new Container
{
RelativeSizeAxes = Axes.Both,
Depth = -1,
}
});
}
public override void Add(DrawableHitObject h)
{
h.Depth = (float)h.HitObject.StartTime;
IDrawableHitObjectWithProxiedApproach c = h as IDrawableHitObjectWithProxiedApproach;
if (c != null)
{
approachCircles.Add(c.ProxiedLayer.CreateProxy());
}
h.OnJudgement += judgement;
base.Add(h);
}
public override void PostProcess()
{
connectionLayer.HitObjects = HitObjects.Children
.Select(d => (OsuHitObject)d.HitObject)
.OrderBy(h => h.StartTime);
}
private void judgement(DrawableHitObject h, JudgementInfo j)
{
HitExplosion explosion = new HitExplosion((OsuJudgementInfo)j, (OsuHitObject)h.HitObject);
judgementLayer.Add(explosion);
}
}
}
-56
View File
@@ -1,56 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Modes.UI;
using OpenTK;
using OpenTK.Input;
using osu.Framework.Graphics.Primitives;
using osu.Game.Screens.Play;
namespace osu.Game.Modes.Osu.UI
{
public class OsuScoreOverlay : ScoreOverlay
{
protected override ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
TextSize = 40,
Position = new Vector2(0, 30),
Margin = new MarginPadding { Right = 5 },
};
protected override PercentageCounter CreateAccuracyCounter() => new PercentageCounter()
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Position = new Vector2(0, 65),
TextSize = 20,
Margin = new MarginPadding { Right = 5 },
};
protected override ComboCounter CreateComboCounter() => new OsuComboCounter()
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
};
protected override KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection
{
IsCounting = true,
FadeTime = 50,
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
Margin = new MarginPadding(10),
Children = new KeyCounter[]
{
new KeyCounterKeyboard(@"Z", Key.Z),
new KeyCounterKeyboard(@"X", Key.X),
new KeyCounterMouse(@"M1", MouseButton.Left),
new KeyCounterMouse(@"M2", MouseButton.Right),
}
};
}
}
-15
View File
@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup></configuration>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="ppy.OpenTK" version="2.0.50727.1340" targetFramework="net45" />
</packages>
@@ -1,37 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
using OpenTK;
namespace osu.Game.Modes.Taiko.Objects.Drawable
{
class DrawableTaikoHit : Sprite
{
private TaikoBaseHit h;
public DrawableTaikoHit(TaikoBaseHit h)
{
this.h = h;
Origin = Anchor.Centre;
Scale = new Vector2(0.2f);
RelativePositionAxes = Axes.Both;
Position = new Vector2(1.1f, 0.5f);
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Texture = textures.Get(@"Menu/logo");
Transforms.Add(new TransformPositionX { StartTime = h.StartTime - 200, EndTime = h.StartTime, StartValue = 1.1f, EndValue = 0.1f });
Transforms.Add(new TransformAlpha { StartTime = h.StartTime + h.Duration + 200, EndTime = h.StartTime + h.Duration + 400, StartValue = 1, EndValue = 0 });
Expire(true);
}
}
}
@@ -1,20 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects;
namespace osu.Game.Modes.Taiko.Objects
{
public class TaikoBaseHit : HitObject
{
public float Scale = 1;
public TaikoColour Type;
}
public enum TaikoColour
{
Red,
Blue
}
}
@@ -1,39 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Beatmaps;
namespace osu.Game.Modes.Taiko.Objects
{
class TaikoConverter : HitObjectConverter<TaikoBaseHit>
{
public override List<TaikoBaseHit> Convert(Beatmap beatmap)
{
List<TaikoBaseHit> output = new List<TaikoBaseHit>();
foreach (HitObject i in beatmap.HitObjects)
{
TaikoBaseHit h = i as TaikoBaseHit;
if (h == null)
{
OsuHitObject o = i as OsuHitObject;
if (o == null) throw new HitObjectConvertException(@"Taiko", i);
h = new TaikoBaseHit
{
StartTime = o.StartTime,
};
}
output.Add(h);
}
return output;
}
}
}
-29
View File
@@ -1,29 +0,0 @@
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
<!-- XQuartz compatibility (X11 on Mac) -->
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>
@@ -1,27 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Taiko.Objects;
using System;
using System.Collections.Generic;
namespace osu.Game.Modes.Taiko
{
public class TaikoDifficultyCalculator : DifficultyCalculator<TaikoBaseHit>
{
protected override PlayMode PlayMode => PlayMode.Taiko;
public TaikoDifficultyCalculator(Beatmap beatmap) : base(beatmap)
{
}
protected override HitObjectConverter<TaikoBaseHit> Converter => new TaikoConverter();
protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty)
{
return 0;
}
}
}
-29
View File
@@ -1,29 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Graphics;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.Taiko.UI;
using osu.Game.Modes.UI;
using osu.Game.Beatmaps;
namespace osu.Game.Modes.Taiko
{
public class TaikoRuleset : Ruleset
{
public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay();
public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new TaikoHitRenderer { Beatmap = beatmap };
protected override PlayMode PlayMode => PlayMode.Taiko;
public override FontAwesome Icon => FontAwesome.fa_osu_taiko_o;
public override ScoreProcessor CreateScoreProcessor(int hitObjectCount) => null;
public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser();
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap);
}
}
@@ -1,63 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Transforms;
using osu.Game.Modes.UI;
using OpenTK;
namespace osu.Game.Modes.Taiko.UI
{
/// <summary>
/// Allows tint and scaling animations. Used in osu!taiko.
/// </summary>
public class TaikoComboCounter : ComboCounter
{
protected virtual int AnimationDuration => 300;
protected virtual float ScaleFactor => 2;
protected virtual EasingTypes AnimationEasing => EasingTypes.None;
protected virtual bool CanAnimateWhenBackwards => false;
public TaikoComboCounter()
{
DisplayedCountSpriteText.Origin = Framework.Graphics.Anchor.BottomCentre;
DisplayedCountSpriteText.Anchor = Framework.Graphics.Anchor.BottomCentre;
}
protected virtual void TransformAnimate(ulong newValue)
{
DisplayedCountSpriteText.Text = FormatCount(newValue);
DisplayedCountSpriteText.ScaleTo(new Vector2(1, ScaleFactor));
DisplayedCountSpriteText.ScaleTo(new Vector2(1, 1), AnimationDuration, AnimationEasing);
}
protected virtual void TransformNotAnimate(ulong newValue)
{
DisplayedCountSpriteText.Text = FormatCount(newValue);
DisplayedCountSpriteText.ScaleTo(1);
}
protected override void OnDisplayedCountRolling(ulong currentValue, ulong newValue)
{
if (newValue == 0)
DisplayedCountSpriteText.FadeOut(FadeOutDuration);
else
DisplayedCountSpriteText.Show();
TransformNotAnimate(newValue);
}
protected override void OnDisplayedCountChange(ulong newValue)
{
DisplayedCountSpriteText.FadeTo(newValue == 0 ? 0 : 1);
TransformNotAnimate(newValue);
}
protected override void OnDisplayedCountIncrement(ulong newValue)
{
DisplayedCountSpriteText.Show();
TransformAnimate(newValue);
}
}
}
@@ -1,19 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.UI;
namespace osu.Game.Modes.Taiko.UI
{
public class TaikoHitRenderer : HitRenderer<TaikoBaseHit>
{
protected override HitObjectConverter<TaikoBaseHit> Converter => new TaikoConverter();
protected override Playfield CreatePlayfield() => new TaikoPlayfield();
protected override DrawableHitObject GetVisualRepresentation(TaikoBaseHit h) => null;// new DrawableTaikoHit(h);
}
}
-40
View File
@@ -1,40 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Modes.UI;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Modes.Taiko.UI
{
public class TaikoPlayfield : Playfield
{
public TaikoPlayfield()
{
RelativeSizeAxes = Axes.X;
Size = new Vector2(1, 100);
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f });
Add(new Sprite
{
Texture = textures.Get(@"Menu/logo"),
Origin = Anchor.Centre,
Scale = new Vector2(0.2f),
RelativePositionAxes = Axes.Both,
Position = new Vector2(0.1f, 0.5f),
Colour = Color4.Gray
});
}
}
}
@@ -1,89 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F167E17A-7DE6-4AF5-B920-A5112296C695}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Game.Modes.Taiko</RootNamespace>
<AssemblyName>osu.Game.Modes.Taiko</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="TaikoDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableTaikoHit.cs" />
<Compile Include="Objects\TaikoBaseHit.cs" />
<Compile Include="Objects\TaikoConverter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\TaikoComboCounter.cs" />
<Compile Include="UI\TaikoHitRenderer.cs" />
<Compile Include="UI\TaikoPlayfield.cs" />
<Compile Include="TaikoRuleset.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{C76BF5B3-985E-4D39-95FE-97C9C879B83A}</Project>
<Name>osu.Framework</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Modes.Osu\osu.Game.Modes.Osu.csproj">
<Project>{C92A607B-1FDD-4954-9F92-03FF547D9080}</Project>
<Name>osu.Game.Modes.Osu</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game\osu.Game.csproj">
<Project>{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}</Project>
<Name>osu.Game</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="ppy.OpenTK" version="2.0.50727.1340" targetFramework="net45" />
</packages>
@@ -0,0 +1,54 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using System.Collections.Generic;
using System;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Catch.Beatmaps
{
internal class CatchBeatmapConverter : BeatmapConverter<CatchBaseHit>
{
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
protected override IEnumerable<CatchBaseHit> ConvertHitObject(HitObject obj, Beatmap beatmap)
{
var curveData = obj as IHasCurve;
var positionData = obj as IHasPosition;
var comboData = obj as IHasCombo;
if (positionData == null)
yield break;
if (curveData != null)
{
yield return new JuiceStream
{
StartTime = obj.StartTime,
Samples = obj.Samples,
ControlPoints = curveData.ControlPoints,
CurveType = curveData.CurveType,
Distance = curveData.Distance,
RepeatSamples = curveData.RepeatSamples,
RepeatCount = curveData.RepeatCount,
X = positionData.X / CatchPlayfield.BASE_WIDTH,
NewCombo = comboData?.NewCombo ?? false
};
yield break;
}
yield return new Fruit
{
StartTime = obj.StartTime,
Samples = obj.Samples,
NewCombo = comboData?.NewCombo ?? false,
X = positionData.X / CatchPlayfield.BASE_WIDTH
};
}
}
}
@@ -0,0 +1,38 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
namespace osu.Game.Rulesets.Catch.Beatmaps
{
internal class CatchBeatmapProcessor : BeatmapProcessor<CatchBaseHit>
{
public override void PostProcess(Beatmap<CatchBaseHit> beatmap)
{
if (beatmap.ComboColors.Count == 0)
return;
int comboIndex = 0;
int colourIndex = 0;
CatchBaseHit lastObj = null;
foreach (var obj in beatmap.HitObjects)
{
if (obj.NewCombo)
{
if (lastObj != null) lastObj.LastInCombo = true;
comboIndex = 0;
colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
}
obj.ComboIndex = comboIndex++;
obj.ComboColour = beatmap.ComboColors[colourIndex];
lastObj = obj;
}
}
}
}
@@ -2,26 +2,23 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Modes.Catch.Objects;
using osu.Game.Modes.Objects;
using System;
using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using System.Collections.Generic;
namespace osu.Game.Modes.Catch
namespace osu.Game.Rulesets.Catch
{
public class CatchDifficultyCalculator : DifficultyCalculator<CatchBaseHit>
{
protected override PlayMode PlayMode => PlayMode.Catch;
public CatchDifficultyCalculator(Beatmap beatmap) : base(beatmap)
{
}
protected override HitObjectConverter<CatchBaseHit> Converter => new CatchConverter();
protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty)
protected override double CalculateInternal(Dictionary<string, string> categoryDifficulty)
{
return 0;
}
protected override BeatmapConverter<CatchBaseHit> CreateBeatmapConverter() => new CatchBeatmapConverter();
}
}
@@ -0,0 +1,27 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Catch
{
public class CatchInputManager : RulesetInputManager<CatchAction>
{
public CatchInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique)
{
}
}
public enum CatchAction
{
[Description("Move left")]
MoveLeft,
[Description("Move right")]
MoveRight,
[Description("Engage dash")]
Dash
}
}

Some files were not shown because too many files have changed in this diff Show More