75 Commits
Author SHA1 Message Date
Goatgarien 837dc018bd 2.1.7 2023-02-16 20:17:21 -08:00
Goatgarien 1705898b5a pos offset fix (hopefully) 2023-02-16 20:12:49 -08:00
Goatgarien 704e205e94 hold note bugs 2023-02-16 20:10:33 -08:00
Goatgarien 772a79ffad ninja fix 2023-02-16 06:06:29 -08:00
Goatgarien 27497c92ba update startup min size 2023-02-16 05:54:34 -08:00
Goatgarien 076e86b643 2.1.6 2023-02-16 05:51:55 -08:00
Goatgarien d9a72132a0 Enforce minimum note sizes 2023-02-16 05:40:58 -08:00
Goatgarien 23883e46b6 Funny version number update 2023-02-16 01:10:42 -08:00
Goatgarien bfa9f8f791 Save volume between launches 2023-02-16 01:06:40 -08:00
Goatgarien e695203087 I should chart instead of messing with this 2023-02-16 00:58:03 -08:00
Goatgarien 85d3f63c50 Fixed note scaling to use time instead of measures 2023-02-15 06:54:56 -08:00
Goatgarien 89db842aa2 Fixed hispeed stuff
Hispeed setting now mostly matches wacca hispeed.
hispeed gimmicks also show up in visual
hispeed setting also saves between launches
2023-02-15 06:37:25 -08:00
Goatgarien 679ca8c130 formula error 2023-02-15 02:53:56 -08:00
Goatgarien 8f67e6498c Fixed Gimmick Window initial start measure if numerator is higher than previous gimmicks denominator 2023-02-15 01:50:00 -08:00
Goatgarien 51231b2e2e Fixed GetQuantization to not assume everything is 16th notes 2023-02-15 00:36:04 -08:00
Goatgarien b56900d6c7 Show gimmicks in circle view with option to disable
Options should actually save between launches now aswell
2023-02-14 21:42:34 -08:00
Goatgarien 64b1be61c9 Jump to nearest note/gimmick at current time 2023-02-14 20:24:04 -08:00
Goatgarien d5106d3030 oop. removed unused code lol 2023-02-05 23:35:00 -08:00
Goatgarien 84a1248234 Fixed issues around deleting the final 2 segments of a hold. 2023-02-05 23:15:48 -08:00
Goatgarien a6be9e759a Fixed undo/redo issues on holds 2023-02-05 20:42:07 -08:00
Ray cd29218fc8 fix: prevent use of hold button while inserting a hold (#15) 2023-02-04 15:43:38 -05:00
veroxzik 8d0b39774e fix: crash on empty lines in *.mer 2022-12-05 20:53:16 -05:00
Zsolt Zitting 971285d0aa fix: incorrect UI scaling 2022-11-22 19:19:43 -07:00
veroxzik b725ff2f00 fix: End of chart note behavior
Notes cannot be placed after an 'end of chart' note.
'End of chart' notes cannot be placed before other notes or multiple times.
2022-11-19 18:38:17 -05:00
Raymonf 230b77fb4a feature: add option for selection of last inserted note 2022-11-16 13:52:45 -07:00
Raymonf 110a87afff fix: explicitly store and search for last note 2022-11-16 13:52:45 -07:00
Raymonf c02af77870 ux: update selected note upon insertion of new object 2022-11-16 13:52:45 -07:00
Zsolt Zitting 0ebb186d60 Update mask brush to be semi-transparent instead of solid color. 2022-11-15 23:31:54 -07:00
Zsolt Zitting f6235bfbb6 Compensate for missing lower time sig number in chart files. 2022-11-15 23:31:54 -07:00
Zsolt Zitting 1b2178ffdf Update GitHub Actions versions
this should change literally nothing about the project itself.
2022-11-15 16:15:52 -07:00
Zsolt Zitting c2ca4862c5 Uncheck End hold box when Hold End note placed. 2022-11-14 00:26:01 -07:00
Zsolt Zitting 399b925cb9 End of Chart note improvements, misc fixes. 2022-11-14 00:17:21 -07:00
Zsolt Zitting 0691c7135d Change play button key to Space, and allowed it to be rebinded. 2022-11-13 19:12:03 -07:00
Zsolt Zitting e455065915 Change slide button icons. 2022-11-13 17:05:08 -07:00
Zsolt Zitting d7cc20d96f Fixed the rendering of MaskRemove notes. 2022-11-13 16:02:33 -07:00
Zsolt Zitting 0156e36bfc Add playback speed adjustment slider. 2022-11-13 15:59:24 -07:00
veroxzik 92e4122499 Note button hotkeys are now user settable. 2022-11-12 22:39:37 -05:00
veroxzik 8731159e32 Fix crash when deleting Hold Start note. 2022-11-12 21:27:51 -05:00
veroxzik 5cdbc48b7a Add the icon back
Thanks IPIhypster!
2022-11-12 19:57:28 -05:00
veroxzik 535cb9cbdc Allow selection of *.wav
Plus other minor changes.
2022-11-12 19:43:21 -05:00
veroxzik 23a6d01cac Fix crashing when deleting a Hold Joint prior to ending the hold. 2022-11-08 13:50:12 -05:00
Farex-GHandveroxzik dc7e6dc275 mainform: circleview: Move some circleView logic into circleView class (#10)
* mainform: circleview: Split and decouple some elements

This moves circleview rendering and mouse updating into the circleView class.
The goal of this is to start to decouple circleView from needing direct
access to GUI elements, and to also help remove some non-GUI logic from
MainForm.

Most of the logic is left untouched. There are some small changes, mostly
with the if statements when checking if we need to pay attention to certain
mouse movement, but the underlying behavior is left as-is.

* Fixing a single tab like a madman.

Co-authored-by: veroxzik <43590004+veroxzik@users.noreply.github.com>
2022-11-04 22:53:17 -04:00
veroxzik 2f5247989f Squashed commit of the following:
commit b8246693780550a28c6dd45701291918795d0809
Author: veroxzik <43590004+veroxzik@users.noreply.github.com>
Date:   Wed Nov 2 21:31:00 2022 -0400

    Deleting a hold end will turn the previous joint into the end.

commit 597510e605b8687fb004d55245e1c10edf3c8ab6
Author: veroxzik <43590004+veroxzik@users.noreply.github.com>
Date:   Tue Nov 1 23:01:15 2022 -0400

    Fix undo/redo for RemoveHold operations.

commit 40936e13d4bcb66ae24573c5860b79714ee38b32
Author: veroxzik <43590004+veroxzik@users.noreply.github.com>
Date:   Sun Oct 30 17:33:21 2022 -0400

    Fix undo/redo for InsertHold operations.
2022-11-02 21:31:56 -04:00
Goatgarien 8fc7f6550e Play button is now disabled out until you select a song :) 2022-09-17 00:12:24 -07:00
Goatgarien afc86e9c46 Changed version to 2.0.0 instead of 1.0.0 2022-09-11 02:34:54 -07:00
Goatgarien ee44c908e7 Only allow ProcessCmdKey to click the button if button is enabled 2022-09-11 01:32:13 -07:00
Goatgarien f4ef160668 fixed volume slider 2022-09-11 01:22:20 -07:00
Goatgarien 0c43c85d63 Merge pull request #9 from Farex-GH/feat/playback
Minor playback changes
2022-09-11 01:10:54 -07:00
Goatgarien a056082027 Force you to finish hold once started logic and prevents next segment from being before previous segment in time. Currently breaks when undo/redo while in the middle of making a hold 2022-09-11 01:04:27 -07:00
Farex-GH 641074edf2 mainform: playback: Move volume track position to mouse position on click
Allows for smoother volume control
2022-09-11 00:57:22 -07:00
Farex-GH 34ef4c594c mainform: playback: Move song track position to mouse position on click
Allows for smoother track seeking when the song is paused.
For now, we keep the current behavior of disabling all track seeking while the song is playing.
2022-09-11 00:56:47 -07:00
Farex-GH 3dfdec27c6 mainform: playback: Check if there's a song before updating song trackbar
This avoids a null pointer dereference due to updating the song's play position before the user picks a song to edit.
2022-09-11 00:40:28 -07:00
Farex-GH 3ffec77d01 mainform: volume: Add hotkey
Adds using shift+up and shift+down to raise and lower the current song volume, respectively.
2022-09-11 00:28:39 -07:00
Farex-GH 5ff2ae2fd8 mainform: playback: Remove ticks on song trackbar
The ticks aren't really helpful on the trackbar, and end up just causing visual clutter when a song is loaded.
2022-09-11 00:25:45 -07:00
Farex-GH c59d034f48 mainform: playback: Add volume control 2022-09-11 00:24:38 -07:00
veroxzik a7f1d6ca48 Force resize method on startup to set circleView. 2022-09-10 08:22:40 -04:00
Goatgarien 6f865cb34e Update readme and discord bot test? 2022-09-10 02:39:51 -07:00
Goatgarien bd950e4720 Update about box 2022-09-10 02:09:11 -07:00
Goatgarien b01bb90e6c fixed initial launch circlePanel size
also amde it update on hispeed change
2022-09-10 01:42:30 -07:00
Goatgarien ddfd154412 fixed it not building for me 2022-09-10 01:02:58 -07:00
veroxzik 4d1fdf9bde Fix build validation script. 2022-09-09 20:57:16 -04:00
Goatgarien 31c1f1043f Sync Zoids C# port final 2022-09-09 03:50:04 -07:00
Goatgarien b27ea27e7f sync 2022-09-09 03:45:35 -07:00
Goatgarien bf6be18d69 trying to sync up with Zoids port 2022-09-09 03:35:27 -07:00
Goatgarien 9997e57d3b project created 2022-09-09 02:56:46 -07:00
Goatgarien ab44197e0d gitignore and gitattributes 2022-09-09 02:51:04 -07:00
Goatgarien 60ff39e1b7 Delete BAKKA-Sharp.sln 2022-09-09 02:43:23 -07:00
Goatgarien 7662088225 Delete lib directory 2022-09-09 02:43:16 -07:00
Goatgarien 687846c04d Delete BAKKA-Sharp directory 2022-09-09 02:43:08 -07:00
Goatgarien d4ebe976fc Zoids C# Ports 2022-09-09 02:35:35 -07:00
Goatgarien 0f49f0f277 Zoids C# port 2022-09-09 02:30:22 -07:00
Goatgarien 28d05cf2d7 Delete BAKKA Editor.sln 2022-09-09 02:28:17 -07:00
Goatgarien 01199f7133 Delete .gitignore 2022-09-09 02:28:11 -07:00
Goatgarien 8ecd0b6df0 Delete .gitattributes 2022-09-09 02:28:06 -07:00
Goatgarien 9e48bd9f97 Delete BAKKA Editor directory 2022-09-09 02:28:00 -07:00
45 changed files with 8778 additions and 11687 deletions
+37
View File
@@ -0,0 +1,37 @@
name: build-validation
on:
push:
pull_request:
branches: [ main ]
paths:
- '**.cs'
- '**.csproj'
env:
DOTNET_VERSION: '6.x'
jobs:
build:
name: build-windows
runs-on: [ windows-latest ]
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Publish artifacts
uses: actions/upload-artifact@v1
with:
name: build
path: BAKKA-Editor\bin\Release\net6.0-windows\
-31
View File
@@ -1,31 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32126.315
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BAKKA Editor", "BAKKA Editor\BAKKA Editor.vcxproj", "{459EC852-D323-45B0-8A85-D6F4B030F5A4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x64.ActiveCfg = Debug|x64
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x64.Build.0 = Debug|x64
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x86.ActiveCfg = Debug|Win32
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Debug|x86.Build.0 = Debug|Win32
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x64.ActiveCfg = Release|x64
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x64.Build.0 = Release|x64
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x86.ActiveCfg = Release|Win32
{459EC852-D323-45B0-8A85-D6F4B030F5A4}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {469EEAFF-2D80-4D14-A10D-95AE6CB493DA}
EndGlobalSection
EndGlobal
-71
View File
@@ -1,71 +0,0 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "exeIcon.ico"
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
-176
View File
@@ -1,176 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{459EC852-D323-45B0-8A85-D6F4B030F5A4}</ProjectGuid>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<Keyword>ManagedCProj</Keyword>
<RootNamespace>BAKKAEditor</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CLRSupport>true</CLRSupport>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies />
<SubSystem>Windows</SubSystem>
<EntryPointSymbol>main</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link />
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Windows</SubSystem>
<EntryPointSymbol>main</EntryPointSymbol>
</Link>
<Manifest>
<EnableDpiAwareness>false</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<AdditionalDependencies />
<EntryPointSymbol>main</EntryPointSymbol>
<SubSystem>Windows</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link />
<Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Windows</SubSystem>
<EntryPointSymbol>main</EntryPointSymbol>
</Link>
<Manifest>
<EnableDpiAwareness>false</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<Reference Include="irrKlang.NET4">
<HintPath>irrKlang-64bit-1.6.0\lib\dotnet-4-64\irrKlang.NET4.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Forms.DataVisualization" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="MyForm.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Chart.h" />
<ClInclude Include="MyForm.h">
<FileType>CppForm</FileType>
</ClInclude>
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MyForm.en-US.resx">
<DependentUpon>MyForm.h</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MyForm.resx">
<DependentUpon>MyForm.h</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="BAKKA Editor.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="exeIcon.ico" />
</ItemGroup>
<ItemGroup>
<None Include="..\README.md" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-48
View File
@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="MyForm.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="MyForm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Chart.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="BAKKA Editor.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="exeIcon.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<None Include="..\README.md">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>
-86
View File
@@ -1,86 +0,0 @@
#pragma once
#include <iostream>
#include <iterator>
#include <list>
enum NoteType {
TouchNoBonus = 1,
TouchBonus = 2,
SnapRedNoBonus = 3,
SnapBlueNoBonus = 4,
SlideOrangeNoBonus = 5,
SlideOrangeBonus = 6,
SlideGreenNoBonus = 7,
SlideGreenBonus = 8,
HoldStartNoBonus = 9,
HoldJoint = 10,
HoldEnd = 11,
MaskAdd = 12,
MaskRemove = 13,
EndOfChart = 14,
//MaskSameTime = 15,
Chain = 16,
//MaskLane = 17,
//TutorialTag = 18,
//BarLine = 19,
TouchBonusFlair = 20,
SnapRedBonusFlair = 21,
SnapBlueBonusFlair = 22,
SlideOrangeBonusFlair = 23,
SlideGreenBonusFlair = 24,
HoldStartBonusFlair = 25,
ChainBonusFlair = 26,
};
struct NotesNode {
int measure;
int beat;
NoteType noteType;
int position;
int size;
int holdChange;
int BGType;
std::list<NotesNode>::iterator nextNode;
std::list<NotesNode>::iterator prevNode;
};
enum GimmickType {
NoGimmick = 1,
BpmChange = 2,
TimeSignatureChange = 3,
//Stop = 4, //No clue what this does
HiSpeedChange = 5,
ReverseStart = 6,
ReverseEnd = 7,
ReverseNoteEnd = 8,
StopStart = 9,
StopEnd = 10,
};
struct PreChartNode {
int measure;
int beat;
GimmickType type;
double BPM; //2
int beatDiv1; //3
int beatDiv2; //3
double hiSpeed; //5
//6-10 have no extra info
};
struct Chart {
std::list<NotesNode> Notes;
std::list<PreChartNode> PreChart;
double offset;
double movieOffset;
std::string songFileName;
};
struct Operation {
int operationType; //1=insert, 2=delete, 3=edit
int objectType; //1=Note, 2=Gimmick
std::list<NotesNode> oldNote; //only used for edit
std::list<PreChartNode> oldGimmick; //only used for edit
std::list<NotesNode> Note;
std::list<PreChartNode> Gimmick;
};
-14
View File
@@ -1,14 +0,0 @@
#include "MyForm.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]
void main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
BAKKAEditor::MyForm form;
Application::Run(% form);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,780 +0,0 @@
irrKlang 1.6
- stopped support for .NET 1.1, please use the versions for .NET 2 or .NET 4 instead,
or an older version of irrKlang if you still need .NET 1 support
- irrKlang for .NET 4 now needs version 4.5 at miminum
- there is now a new function stopAllSoundsOfSoundSource() to stop all sounds of a specific sound source
- irrKlang.NET for .NET 4 now also has a strong name (it is now a signed assembly)
- irrklang for gcc now supports gcc 5.1
- irrKlang 1.5 for windows was depending on the MSVC runtime dll, this is now
no longer the case with irrKlang 1.6
- fixed a bug causing duplicated DirectSound buffers to share the playbackSpeed sometimes, causing
some sounds to have a wrong frequency when played.
- fixed update() problem in single threaded mode
if you run irrKlang in single threaded mode, you can now call irrKlang::update as often and
fast as you want. This was supposed to be called only about once every second prevousliy, and
could cause irrklang to stall previously if called too often.
- added support for Visual Studio 2017
------------------------------------------------------------------------
irrKlang 1.5
- Added support for unicode file names.
irrKlang now uses UTF8 internally on all operating systems. If you are running it on Windows, and want to use
wchar_t types, you can use the irrKlang provided function makeUTF8fromUTF16string() to convert your wchar_t* string to
a char* string.
In the .NET version of irrKlang, the API hasn't changed, but irrklang now supports unicode
file names there automatically as well.
- Added 64 bit support.
There is now a separate irrKlang SDK for 64 bit builds
- Added support for playing back 24 bit flac files
- Uses less resources on linux now: PCM handles are now closed as soon as possible, freeing resources much earlier.
------------------------------------------------------------------------
irrKlang 1.4.1
- irrKlang now loads the alsa lib from the correct directory on previously unsupported linux systems.
------------------------------------------------------------------------
irrKlang 1.4.0
- Fixed a potential crash in the windows version, when using DirectSound8
- Improved speed of the Windows version of irrKlang by about 20%
- irrKlang now also works with newer Linux distributions (like Ubuntu 12),
which moved the ALSA lib file into a new directory.
- Cleared up some inconsistencies in the documentation
- Removed a very small memory leak in Linux and Mac OS X
---------------------------------------------------------------------
irrKlang 1.3.0b
- Added support for .NET framework 4.
- Fixed a problem with audio recording: GUIDs were not correctly
decoded for some devices, causing manual device selection to fail
on Windows.
---------------------------------------------------------------------
irrKlang 1.3.0
- There is now the possibility to capture the mixed output audio data
from irrKlang, using the ISoundMixedOutputReceiver interface.
Can be used to store the sound output as .wav file or for creating
an Oscillograph and similar.
- The movement speed of 3d sound listeners has been ignored in previous
releases for 3d sound doppler effects, this has been corrected now.
- irrKlang now also runs on 64 bit linux systems. It previously
looked for the alsa lib in /usr/lib/libasound.so, but on 64 bit
system this is located in /usr/lib32/libasound.so. This is fixed now.
---------------------------------------------------------------------
irrKlang 1.2.0
- Added .flac file playback support. Implemented as plugin, ikpFlac.dll.
- Fixed a bug causing the volume of 3D sounds not to be set correctly
when using DirectSound8 and playing more than one 3D sound of the
same file at the same time.
- File formats with unknown extensions are now loaded by Plugins only
if they could not be loaded by the internal decoders.
- Several API documentation updates and improvements.
- C++ documentation now has search functionality
- Replaced .chm documentation files now with plain .html files
-----------------------------------------------------------------------
irrKlang 1.1.3c
- [This update only changes the implementation, the interfaces all remain the
same, so only the irrKlang.dll file needs to be replaced since version 1.1.3.]
- Fixed a bug causing irrKlang to crash when playing looped, streamed sounds in 3D
under special circumstances.
-----------------------------------------------------------------------
irrKlang 1.1.3b
- [This update only changes the implementation, the interfaces all remain the
same, so only the irrKlang.dll file needs to be replaced since version 1.1.3.]
- Small bug fix for the DirectSound drivers: Looped streamed sounds sometimes
restarted with a small pause (~10 ms) in between.
- The ISound and ISoundSource classes in irrKlang.NET now implement the
IDisposable interface, so it is now easily possible to free their resources
manually.
- The .NET version now uses less memory (earlier unmanaged resource disposal).
-----------------------------------------------------------------------
irrKlang 1.1.3
- Added support for multichannel audio recording. When starting audio recording using
startRecordingBufferedAudio() or startRecordingCustomHandledAudio(),
set the new last parameter to the amount of channels you want to record audio data.
- Reduced latency of the Linux version (ALSA).
- Improved Mac OS X performance (CoreAudio), irrKlang now performs better on computers
with slow hardware.
- Added two VisualBasic.NET examples
- ForcedStreamingThreshold property of ISound now also available in
the .NET verion of irrKlang.
- IAudioRecoder::IsRecording now returns the correct value in the .NET
version of irrKlang.
- IAudioRecorder now correctly returns a SampleFormat data with a lenght of 0 if
nothing has been recorded before.
- In irrKlang.NET, IAudioRecorder.RecordedAudioData does not throw an
OutOfMemoryException anymore if nothing has been recorded yet.
- ISoundSource::getForcedStreamingForceThreshold has been renamed to
ISoundSource::getForcedStreamingThreshold
-----------------------------------------------------------------------
irrKlang 1.1.2b
- Added support for (external) multichannel sound hardware on MacOSX.
-----------------------------------------------------------------------
irrKlang 1.1.2
- Added support to play back 24 bit wave files.
- The DirectSound drivers now use more aggressive sound buffer sharing,
causing irrKlang to use a lot less memory and also speeding it up a lot
when playing a lot of big sounds.
- There is now a way to access the internal used audio interfaces (ALSA, DirectSound,
DirectSound8, WinMM, CoreAudio) using ISoundEngine::getInternalAudioInterface().
- There are now two .NET versions of irrKlang available, one for the .NET CLR 1.1
and one for .NET CLR 2.0 (.NET Framework 2, 3 and 3.5). Of course, you can still
use every version with every project, this is mainly to reduce the size of installers.
See details in readme.txt
- It is now possible in the .NET version to access the decoded sample audio data of
non-streamed sounds using ISound.SampleData
- It is now possible in the .NET version to access the recorded audio data directly
using IAudioRecorder.RecordedAudioData
- Fixed a bug in the .NET version of the method EnableCompressorSoundEffect()
which totally skrewed up its parameters.
- Fixed a bug causing the AudioRecorder only to work for one recording session
in DirectSound.
- Fixed a bug causing the irrklang DirectSound driver to start playing the sound when
it changing its 'looped' flag when the sound is paused.
- There is now a new example for C# available which shows how to use irrKlang with
Windows.Forms.
- The forced streaming treshold has been adjusted to 2MB
- Fixed some documentation mistakes in ISoundEngine::addSoundSourceFromPCMData
-----------------------------------------------------------------------
irrKlang 1.1.0
- Several speed optimizations and memory usage improvments.
- It is now possible to directly access the decoded PCM sample data of
every loaded sound source.
Use ISoundSource::getSampleData() for this.
- Fixed a bug causing the UserData object and other resources not to be garbage
collected when using ISoundStopEventReceiver in the .NET version of irrKlang.
- Fixed a bug causing the sudden end of sound loops under very rare circumstances.
- The 'Could not init COM' warning was senseless and has been removed.
-----------------------------------------------------------------------
irrKlang 1.0.4
- irrKlang is now able to record audio. Use createIrrKlangAudioRecorder() to create an
audio recorder object. It currently only works in Windows and with DirectSound (subject to change).
- A new method ISoundEngine::addSoundSourceFromPCMData() now adds to possibility to use sound
source from pure PCM data.
- The three method overloads of addSoundSource() have now been renamed to
addSoundSourceFromFile(), addSoundSourceFromMemoryFile(), and addSoundSourceAlias().
-----------------------------------------------------------------------
irrKlang 1.0.3
- irrKlang now supports Power PCs (PPC). All features and file formats except
Module playback (.mod, .it, .xm, .s3m) are now supported on this platform.
- There is now a function to enumerate available audio devices. Select a device ID from this list to
let irrKlang use a specific audio device. You can create this list using
irrklang::ISoundDeviceList* list = createSoundDeviceList();
or in .NET (C#):
IrrKlang.ISoundDeviceList list = new IrrKlang.ISoundDeviceList();
- The sound stop event receiver now has an additional parameter, describing the reason why the
sound has been stopped. The signature of the method is now
virtual void OnSoundStopped(ISound* sound, E_STOP_EVENT_CAUSE reason, void* userData) = 0;
or in .NET (C#):
public void OnSoundStopped(IrrKlang.ISound sound, IrrKlang.StopEventCause reason, object userData);
- irrKlang.NET is now a signed assembly to work around some security hassle Microsoft introduced on Vista.
- On newer linux versions (such as Ubuntu 7.10), irrKlang sometimes would play sound too fast or with
a lot of noise, this is repaired now.
- The Linux version of irrKlang shared object file is now named
libirrKlang.so instead of previously irrKlang.so
- ALSA driver latency highly improved
- IrrKlang.NET now supports retrieving the audio format of a sound, using ISoundSource::AudioFormat.
- IrrKlang can now optionally be told which sound device to use for sound output. In addition using
this feature, it is now possible to define an ALSA device name to be used for alsa output when calling
createIrrKlangDevice().
- irrKlang ignored the new flag ESEO_PRINT_DEBUG_INFO_TO_STDOUT on unix based operation systems,
this is fixed now.
-----------------------------------------------------------------------
irrKlang 1.0.2
- Breaking interface changes:
- All interfaces are now located in one single, new namespace named 'irrklang'.
- vector3df is now named vec3df
- IReadFile is now named IFileReader
- IReferenceCounted is now named IRefCounted and IVirtualReferenceCounted now IVirtualRefCounted
- primitive types now have the prefix ik_
- all header files have now the prefix ik_
- IFileFactory::createAndOpenFile() is now named createFileReader().
These changes where necessary to simplify and clean up the interface, as well as to make irrklang independent
of future changes of the Irrlicht Engine.
- It is now possible to change the play position of a sound using ISound::setPlayPosition().
- Software devices such as ALSA, WinMM and CoreAudio also support teh setPlaybackSpeed() functionality now.
- Max values of 3D sound now behave differently: They won't mute the sound anymore when
the max distance is reached. This should not affect if you set your 3D sound min/max values
correctly before: The audible radius of a sound is only influenced by the minimum value,
the maximum should be set to a extremely high value usually (such as 1mio) which is the
default. If the maximum value is set to a small value, the sound won't attenuate anymore
after this distance and stay audible from then on.
In short: In nearly all cases, it is not necessary to change the max value of the sound
if not in linear rolloff mode. Details can be found in the documentation.
- It is now possible to retrieve the audio format of sound sources. Informations
like channel count (mono/stereo), frame count, sample rate, etc are possible to
be retrieved using ISoundSource::getAudioFormat()
- The internals of irrKlang has been refactored: irrKlang.dll/.so/.dylib files are now smaller, use
an improved thread locking mechanism and should run a bit faster.
- irrKlang now supports a RollOff factor for 3D sounds. Use ISoundEngine::setRolloffFactor() for this.
- it is now possible to get the name of the used sound driver by calling ISoundEngine::getDriverName();
- irrKlang now only prints status messages to stdout if ESEO_PRINT_DEBUG_INFO_TO_STDOUT was set when
creating the device (which is the default).
- There is a new example application included in the SDK: A music player.
- ISound::getPlayPosition() didn't return 100% accurate positions in all cases, this is fixed now.
- irrKlang won't touch files anymore for preloading when streaming was specified.
- ISoundSource::getIsSeekingSupported() now returns if the sound supports seeking using
ISound::setPlayPosition().
- Fixed a problem with 3D sounds: On some sound boards on windows operating systems older than Vista,
the 3D sound would not stop at the maximum 3D distance when using DirectSound.
- Using ISoundEngine::setDefault3DSoundMaxDistance() had a small bug, which caused the max distance
not to work in all cases, this is fixed now.
-----------------------------------------------------------------------
irrKlang 1.0.1
- Removed the deprecated header ESoundEffects.h
- Fixed a rarely happening bug causing irrKlang to crash when stopping streamed sounds in the software devices
at disadvantageous times.
- Fixed a rarely happening bug which could have caused a deadlock when stopping a huge
amount of streamed at the same time sounds.
- Documentation fixes
-----------------------------------------------------------------------
irrKlang 1.0
- Added ISound::setIsLooped(), to make it possible to change the loop mode of sounds during runtime.
- It is now possible to preload sounds when using the addSoundSource() method, by
setting the parameter 'preload' to true. If this flag is set to false (which is default)
the sound engine will not try to load the sound file when calling this method,
but only when play() is called with this sound source as parameter.
- Plugins can now be loaded manually from a custom path using ISoundEngine::loadPlugins();
- The listener position is now set to a default value when starting up irrKlang.
Previously, when playing 3D sounds without changing or setting the listener position at all,
3D sounds would sound differently based on the chosen audio driver.
- Fixed a bug of the Linux version of irrKlang, causing ALSA to crash on
some very few systems (known as the '!snd_interval_empty(i)'-problem).
- Resampling mono sounds in all devices except directSound (it was ok there already)
now uses only half the memory as before.
- To reduce name clashes with the windows headers for people not using namespaces,
the Interface IUnknown has been renamed to IRefCounted.
- IrrKlang can now be used easily together with the latest 6 versions of
Irrlicht (header compatibility).
- Fixed a small bug in the .NET version which could return 'false' instead of 'true' under
special circumstances when calling isCurrentlyPlaying() (Microsoft compiler bug).
- The documentation has been updated and extended with lots of examples.
- Examples now also include project files for visual studio 6.0
-----------------------------------------------------------------------
irrKlang 1.0-RC1
- irrKlang now supports MacOSX, using CoreAudio.
There is a new sound output driver enumeration literal, named ESOD_CORE_AUDIO, which
will be chosen automaticly when using ESOD_AUTO_DETECT on MacOsX.
Please note that irrKlang is a universal binary for both x86 and ppc, but
only x86 hardware is supported yet, altough some few features might work with the
ppc irrKlang version.
- This version is release candiate 1 for version 1.0. There are now known bugs in irrKlang
currently, and if no major bugs will be found, version 1.0 will be released after some time.
We are already working on new user requested features which will be integrated after the
1.0 release.
- irrKlang.NET is now able to override the file access just like the C++ version. There is
a tutorial in examples.net\CSharp.04.OverrideFileAccess demonstrating this.
Use IFileFactory with ISoundEngine::addFileFactory for this.
- Added a method to irrKlang.NET, making it possible to add System::IO::Streams as sound
sources. Note that the stream is totally read into memory when adding the sound source.
If you want irrKlang to dynamically open and close custom file streams without loading
everything into memory, use the addFileFactory with your own IFileFactory implementation.
- Documentation improvements for the .NET version.
-----------------------------------------------------------------------
irrKlang 0.9.1
- License change: All of the irrKlang Pro features (except static linking and signed assembly)
are now available for non-commercial use too. Please take a closer look at the new
license and the website for details.
The license was changed because of lots of user requests, so that free and open
source projects are now able to use irrKlang pro's features as well. To compensate this,
this means that irrKlang is no more free for commercial use.
- Mp3 files with ID3 v2 or later tags in it have not been played correctly in irrKlang, this is
fixed now.
- It is now possible to add sound source aliases for an existing sound source.
This is useful if you want to play multiple sounds but each sound isn't necessarily one single file.
Also useful if you want to or play the same sound using different names, volumes or min and max 3D distances.
Use the now existing third overload of ISoundEngine::addSoundSource() which takes another
sound source as parameter for this.
- added ISound::PlayLength property to irrKlang.NET to retrieve the length of sounds in milliseconds.
- irrKlang.NET now needs a lower amount of memory every time a sound is played and also
frees the memory used by these sounds earlier.
- irrKlang.NET now supports sound sources just as the irrKlang C++ version does,
which means better access and possibility to influence sounds.
- irrKlang.NET now also supports default 3D min and max distances.
- irrKlang.NET now supports playing sounds directly from custom memory areas,
byte arrays (byte[]). Use ISoundEngine.addSoundSource(yourMemoryArray, someName) for this.
- Using irrKlang.NET, streamed sound files have not been closed on some systems. This is fixed now.
- It is now possible to set the wanted stream mode for sound sources using
ISoundSource::setStreamMode().
- Reduced the file size of the irrKlang library again a bit.
- There are two new tutorials for irrKlang.NET in C# available now.
-----------------------------------------------------------------------
irrKlang 0.9
- irrKlang is now available in two editions:
- irrKlang which is still free, also for commercial use
- irrKlang Pro, for a small license fee (see details on http://ambiera.com)
Some of the new features added in this version are only available in
irrKlang Pro (see website for details). The 'pro' features can be accessed
and tested with the free version as well, but the audio engine will start playing
additional sounds (female voice saying 'irrKlang pro') from time to time once
a pro feature has been used.
- irrKlang now supports DirectSound8 as additional sound output driver.
Note that the E_SOUND_OUTPUT_DRIVER enumeration has a new member now:
ESOD_DIRECT_SOUND_8. The ESOD_DIRECT_SOUND is still available.
- Doppler effects are now supported (with the DirectSound drivers at least).
Use ISound::setVelocity to set a sounds velocity, ISoundEngine::setListenerPosition()
to set the listeners velocity and ISoundEngine::setDopplerEffectParameters() to
adjust two parameters influencing the doppler effects intensity.
- There are now sound stop events: Events which are called when a sound has finished
playback. Use the new interface ISoundStopEventReciever for this.
The interface has only one method to be implemented by the user: OnSoundStopped().
Implement this interface and set it via ISound::setSoundStopEventReciever().
The sound stop event is guaranteed to be called when a sound or sound stream is finished,
either because the sound reached its playback end, its sound source was removed,
ISoundEngine::stopAllSounds() has been called or the whole engine was deleted.
- Sound effects are now usable when using the ESOD_DIRECT_SOUND_8
driver (default). Available sound effects are:
- Chorus
- Compressor
- Distortion
- Echo
- Flanger
- Gargle
- 3DL2Reverb
- ParamEq
- WavesReverb
Those effects can be accessed via ISound::getSoundEffectControl(), if the
'enableSoundEffects' flag was set to true when starting the sound with
play2D() or play3D().
- There is now the option to change the play back speed and the frequency
of a sound. Use ISound::setPlaybackSpeed() for this.
- It is now possible to set a default volume for every sound source via
ISoundSource::setDefaultVolume().
- There is now a statically linkable version of irrKlang available (currently
windows and irrKlang pro only).
Just #Define IRRKLANG_STATIC in your project settings or before including the
irrKlang headers to use the static lib version of irrKlang.
Note that you need to use multi threaded runtime libraries in your project
when using irrKlang as static lib, other wise you will get linker errors
(like "__getmbcp already defined in LIBC.lib(mbctype.obj)") or random crashes.
In Visual Studio, this setting can be found in
Project Settings -> C++ -> Code Generation -> Runtime Library.
- Memory sound sources are now copied by default, so the memory block can be discarded after
calling ISoundEngine::addSoundSource(). There is a new parameter 'copyMemory' which
can be set to false to make the engine use the old, non memory copying behavior.
- ISoundEngine::getSoundSource() now has a second parameter making it possible
to only retrieve a already added sound source without loading it.
- There is a new example available showing how to use sound effects.
- Refactored a lot of internal code, reducing the file size of the
irrKlang binaries.
- Fixed a possible synchronization problem (possible crash)
-----------------------------------------------------------------------
irrKlang 0.8.1
- There was a serious bug in the WAV file reader which read over the end of files,
when streamed, causing a short 'click' sound. Fixed now.
- 8 Bit sound streams don't produce a click when stopped anymore.
- Audio stream readers which report a wrong amount of frames in the stream now
don't get clipped before playing the end of the sound anymore.
-----------------------------------------------------------------------
irrKlang 0.8
- There are now two ways to set default min and max distances for 3D sounds:
ISoundEngine::setDefault3DSoundMinDistance(), ISoundEngine::setDefault3DSoundMaxDistance
for global min/max control, as well as
ISoundSource::setDefaultMinDistance(), ISoundSource::setDefaultMaxDistance().
to influence the default min/max value based on the sound source.
- Some documentation updates
- The short 'click'/'pop' sound which sometimes has been played on streamed, non looped sounds
when using the DirectSound device is now removed.
- The ALSA driver now also works with sound hardware not supporting power of two buffer sizes.
- License change: irrKlang.so file may also be redistributed.
-----------------------------------------------------------------------
irrKlang 0.7
- Added possibility to remove sound sources (selective or all at once).
See ISoundEngine::removeSoundSource() (two overloads) and
ISoundEngine::removeAllSoundSources().
- There is now the possibility to get the length of any sound source or playing sound.
See ISound::getPlayLength() and ISoundSource::getPlayLength().
- Resources of finished played sounds are now freed much earlier, causing smaller memory usage.
- When stream playback is paused, the play position returned by ISound::getPlayPosition()
won't advance forward anymore in DirectSound, this was a bug which is now fixed.
- Fixed a bug which caused ISound::isFinished() to be returned incorrect values when
using the DirectSound driver.
- Fixed a bug causing a wrong value being reported using getPlayPosition() when playing
very long streams using the WinMM or the ALSA driver.
-----------------------------------------------------------------------
irrKlang 0.6
- There are some new supported file formats: MOD, XM, IT and S3M. Implemented using the
excellent Dynamic Universal Music Bibliotheque.
- irrKlang now is available for .NET languages (C#, VisualBasic.NET,
IronPhyton, Boo, Delphi.NET etc).
See /bin/dotnet for the binary, and /examples.net for some examples.
- irrKlang now chooses sound drivers in a more intelligent way when running in
driver auto detect mode (ESOD_AUTO_DETECT).
For example when DirectSound is available but fails starting up (for whatever reason),
irrKlang will select the winMM driver instead of not playing any sound.
- It is now possible to influence or disable the threshold where irrKlang desides
to stream a file regardless of the user specified setting.
Use ISoundSource::setForcedStreamingThreshold for this.
- irrKlang is now compatible with Irrlicht 1.3, the IFileReader interface has been
updated. Meaning you can use the same IFileReader interfaces between those two
engines and for example make irrKlang read files using Irrlicht's file system.
- irrKlang now needs even less memory when playing a lot of short soundfiles at the same time,
achieved through a nicer internal (de)allocation scheme.
- When using software 3d sound (using winMM or ALSA), the left and right speaker were swapped.
This is fixed now.
- Failed COM initialization is now only a warning, and irrKlang will not abort with an error.
- Under some circumstances (bad windows scheduling, cpu intensive applications etc) it could
happen that looped, streamed sound filed played via DirectSound in irrKlang would play
strange noises after the first repeat. This has been corrected now.
- On some hardware under Linux, irrKlang wasn't able to set the wanted buffer size,
this has been improved now.
- Removed a bug causing visual studio 2005 projects not to compile when using irrKlang without
a WIN32 define.
-----------------------------------------------------------------------
irrKlang 0.5
- Linux is now supported as platform. irrKlang uses ALSA as output target here by default.
- irrKlang now supports winMM as output driver next to DirectSound in Windows.
- added a new method to pause/unpause all sounds:
ISoundEngine::setAllSoundsPaused( bool bPaused = true )
- The flag ESEO_LOAD_PLUGINS now correctly prevents loading of plugins if
not set. This was not working before.
- ISoundEngine::stopAllSounds() didn't work with the DirectSound output driver correctly,
this has been corrected now.
- irrKlang can now be used as static lib. Just #Define IRRKLANG_STATIC in your project
settings or before including the irrKlang headers to use the static lib version
of irrKlang. Note that you need to use multi threaded runtime libraries in your project
when using irrKlang as static lib, other wise you will get linker errors
(like "__getmbcp already defined in LIBC.lib(mbctype.obj)") or random crashes.
In Visual Studio, this setting can be found in
Project Settings -> C++ -> Code Generation -> Runtime Library.
(If the static library isn't released in this package it may come as separate archive)
-----------------------------------------------------------------------
irrKlang 0.4
- Added support for the GCC compiler
- Added the possibility to load sounds directly from memory.
For this, two overloaded methods to the ISoundEngine interface have been added:
ISoundSource* addSoundSource(void* memory, ik_s32 sizeInBytes, const ik_c8* soundName);
ISoundSource* addSoundSource(const ik_c8* fileName, E_STREAM_MODE mode=SM_AUTO_DETECT);
- Added possibility to override file access easily.
- Added two tutorials: MemoryPlayback and OverrideFileAccess.
- Added support for the Code::Blocks IDE
- Removed streamMode parameter from getSoundSource(). If you needed this, please use
addSoundSource() now instead.
- Sounds are now loaded correctly independent of their file extension.
- irrKlang no longer crashes if more than one instance of it is created.
-----------------------------------------------------------------------
irrKlang 0.3
- Added the option to play mp3 files. This functionality is available as plugin and
works when the file ikpMP3.dll is available. Simply remove it if you don't want
or need mp3 support for your software. Please note that if you are using mp3
files in your application, you might need to pay a license fee to Thompson for
their patent (This is nothing irrKlang specific, every application needs to do
this today if Thompson wants it to.)
The ikpMP3.dll decoder is available as full source in the \plugins directory
and licensed under the LGPL.
- Added plugin support. Create a .dll which starts with ikp (for IrrKlangPlugin)
including a function looking like this:
__declspec(dllexport) void __stdcall irrKlangPluginInit(
ISoundEngine* engine, const char* version) { // your code here }
irrKlang will load the dll and invoke that function. There is an example plugin
with full source code in the \plugins directory which enhances irrKlang
to decode mp3 files.
- IrrKlang now supports 3D buffers (enabled by default). Previously, they have been
emulated. By not specifying the ESEO_USE_3D_BUFFERS flag when calling
createIrrKlangDevice(), irrKlang will not use 3D buffers.
- Added the possibility to write debug info to any windows debugger supporting
OutputDebugString() (like VisualStudio). This is pretty useful if your application
does not capture any console output. Use ESEO_PRINT_DEBUG_INFO_TO_DEBUGGER to
enable this feature when calling createIrrKlangDevice().
- irrKlang now supports multiple rolloff models. 3D sounds are now played back with
a logarithmic rolloff by default. In previous versions, irrKlang used a linear rolloff
model. Use ESEO_LINEAR_ROLLOFF when calling createIrrKlangDevice() to switch
to the linear rolloff model.
- The createIrrKlangDevice() function now accepts several options as flags. Note that
the C++ compiler automaticly converts bools to this flags so if you used a previous
version of the engine you might want to check if your parameters are correctly set.
- Added the method ISound::getPlayPosition() which returns the current play position of
the sound in milliseconds.
- Fixed a possible crash when stopping a streamed sound manually at the same time
it also stopped automaticly.
- Fixed playback of looped streamed sounds causing artifacts under several circumstances.
-----------------------------------------------------------------------
irrKlang 0.2
- Fixed 3d positioning of sounds
- Fixed a bug in ik_ISound.h causing irrKlang header not to compile with some strict compiler settings.
- Added some internal performance improvements
-----------------------------------------------------------------------
irrKlang 0.1
Initial release.
Although this is the first release, irrKlang already has some features:
- Support for .WAV and .OGG files (MP3, FLAC, SPEEX support planned and
coming soon)
- Buffered and streamed audio playback
- Seamless 2D and 3D audio: It is possible to play short simple stereo
sounds as well multiple large streamed sound files in 3D space at the
same time for example.
- High level autodetection: The engine can do everything for you. Just
tell it to play a sound file, and it will load, cache and/or stream
sound data for you automaticly, depending on what is best for
performance and memory usage. But if you want to specify how the engine
should handle this, you can specify this as well.
- Extendable: Possibility to write own file format readers/decoders to
extend the engine with it.
- Multi/Singlethreaded modes: The engine can run both multithreaded or
singlethreaded in the same thread as your application, to make it
possible to debug your application easier for example.
- Low level audio output manipulation: Before starting to play a sound
or even during it is already playing, it is possible of course to alter
any aspect of it like panning, volume and 3d position.
- Fast 3D audio on low end hardware: Because some low end audio hardware
is not able to play 3D sounds without significant performance loss or
some don't support 3d audio buffers at all, irrEdit has a high
performance 3d sound buffer emulator built-in, causing a sound
experience nearly as it was a real 3d sound buffer.
- Separate music and sound control: As most applications want to
separate between sound and music playback, the engine offers to control
them separately, like for example via a master volume control. No need
to manage alls your playing sounds just to change the volume of all
sounds. (The control of the 'music' part in the API is not available in
version 0.1 yet, but can be used via normal sounds already)
- Full playback control: Play any sound and forget about it if you want.
Then later, you can query at any time which sound is currently playing
and influene this if you want.
@@ -1,191 +0,0 @@
==========================================================================
The irrKlang SDK version 1.6
==========================================================================
Welcome the irrKlang SDK.
Content of this file:
1. Directory structure overview
2. How to start
3. Release Notes
4. .NET version dependencies
5. License
6. Contact
==========================================================================
1. Directory structure overview
==========================================================================
You will find some directories after decompressing the archive in which
came the SDK. These are:
\bin The compiled library irrKlang.DLL and some compiled demo
and example applications, just start them to see
irrKlang in action.
\doc Documentation of the Irrlicht Engine.
\examples Examples and tutorials showing how to use the native engine
engine using C++.
\example.net Examples written for the .NET version of irrKlang, in C# and
VisualBasic.NET
\include Header files to include when using the engine.
\lib Lib to link with your programs when using the engine.
\media Sound data for the demo applications and
examples.
\plugins Source and documentation of the irrKlang plugins.
==========================================================================
2. How to start
==========================================================================
To see the engine in action in Windows, just go to the \bin\Win32
directories, and start some applications.
To start developing own applications and games with the engine take
a look at the 01.HelloWorld example in the \examples directory.
Windows Users:
There are Visual Studio as well as CodeBlocks projects for the examples.
Linux users:
Just go into the /examples directory and run 'make' for every
example you want to try out. You can run the examples directly from the
directory they are created in. Some examples may print some special
hints after a successful make and might help you starting them up
by typing in 'make run'.
Mac users:
There is a XCode project for each example available in
the corresponding example directory. To run the precompiled example
applications from bin\macos-gcc, doubleclick the run_0x_xxxxx.command
files from the finder (this will change the working directory to
bin\macos-gcc) or start them directly from a terminal.
==========================================================================
3. Release Notes
==========================================================================
Informations about changes in this new version of the engine can be
found in changes.txt.
Please note that the included sound files are copyright
by their authors and not included in the irrKlang engine license.
==========================================================================
4. .NET version dependencies
==========================================================================
There are four versions of irrKlang.NET available. They have the same
functionality and can be used from the same .NET projects.
The difference are only their dependencies and target platforms:
irrKlang.NET2.0 in bin\dotnet-2.0:
Compiled for .NET common language runtime version 2.0, depends on
the modudles MSVCR80.DLL and MSVCM80.DLL. (32 bit)
One method to redistribute these is using the visual studio 2005
redistributeable (vcredist_x86)
irrKlang.NET4 in bin\dotnet-4:
Compiled for .NET common language runtime version 4.5, depends on
VCRUNTIME140.dll. (32 bit)
One method to redistribute this is using the visual studio 2017
redistributeable (vcredist_x86)
irrKlang.NET4 in bin\dotnet-4-64: (only in the 64 bit irrKlang SDK)
64 bit version, Compiled for .NET common language runtime version 4.5,
depends on VCRUNTIME140.dll. (64 bit)
One method to redistribute this is using the visual studio 2017
redistributeable (vcredist 64 bit)
==========================================================================
5. License
==========================================================================
irrKlang's source codes, documentation and binaries contained within the
distributed archive are copyright © Nikolaus Gebhardt / Ambiera 2001-2018.
The contents of the irrKlang distribution archive may not be redistributed,
reproduced, modified, transmitted, broadcast, published or adapted in any
way, shape or form, without the prior written consent of the owner,
Nikolaus Gebhardt.
The irrKlang.dll, irrKlang.so and libirrklang.dylib files may be
redistributed without the authors prior permission in non-commercial
products, and must remain unmodified except for compressing the file.
For the included plugins which can be found in the \plugins
directory, different licenses may be applied, as specified in the
actual plugin directory.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
irrKlang may include Xiph.org Foundation code (Ogg Vorbis and FLAC).
It's license is the following:
Copyright (c) 2002, Xiph.org Foundation
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of the Xiph.org Foundation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
irrKlang may include code from the
Dynamic Universal Music Bibliotheque, Version 0.9.3
Copyright (C) 2001-2005 Ben Davis, Robert J Ohannessian and Julien Cugniere
==========================================================================
6. Contact
==========================================================================
If you have problems, questions or suggestions, please visit the
official homepage of the irrKlang Engine:
http://www.ambiera.com/irrklang
You will find forums, bugtrackers, patches, tutorials, and other stuff
which will help you out.
If want to contact the author of the engine, please send an email to
Nikolaus Gebhardt:
office@ambiera.com
-16
View File
@@ -1,16 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by BAKKA Editor.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Binary file not shown.
+25
View File
@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32825.248
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BAKKA-Editor", "BAKKA-Editor\BAKKA-Editor.csproj", "{76336598-B2BE-4F67-B3D6-821F6A0E302F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76336598-B2BE-4F67-B3D6-821F6A0E302F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {35C7C2C6-E927-465D-B4B5-46787DDAE60F}
EndGlobalSection
EndGlobal
+57
View File
@@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<RootNamespace>BAKKA_Editor</RootNamespace>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<Version>$(VersionPrefix)2.1.7</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>2.1.7</FileVersion>
<Company>Goatgarien</Company>
<Copyright>2022</Copyright>
<StartupObject>BAKKA_Editor.Program</StartupObject>
<ApplicationIcon>icon.ico</ApplicationIcon>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<Content Include="icon.ico" />
</ItemGroup>
<ItemGroup>
<None Include="..\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Tomlyn" Version="0.15.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="irrKlang.NET4">
<HintPath>..\lib\irrKlang.NET4.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
+300
View File
@@ -0,0 +1,300 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor
{
internal class Chart
{
public List<Note> Notes { get; set; }
public List<Gimmick> Gimmicks { get; set; }
/// <summary>
/// Offset in seconds.
/// </summary>
public double Offset { get; set; }
/// <summary>
/// Movie offset in seconds
/// </summary>
public double MovieOffset { get; set; }
String SongFileName { get; set; }
List<Gimmick> TimeEvents { get; set; }
public bool HasInitEvents
{
get
{
return TimeEvents != null &&
TimeEvents.Count > 0 &&
Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.BpmChange) >= 1 &&
Gimmicks.Count(x => x.Measure == 0 && x.GimmickType == GimmickType.TimeSignatureChange) >= 1;
}
}
public bool IsSaved { get; set; }
public Chart()
{
Notes = new();
Gimmicks = new();
Offset = 0;
MovieOffset = 0;
SongFileName = "";
IsSaved = true;
}
public bool ParseFile(string filename)
{
var file = File.ReadAllLines(filename);
int index = 0;
do
{
var line = file[index];
var path = Utils.GetTag(line, "#MUSIC_FILE_PATH ");
if (path != null)
SongFileName = path;
var offset = Utils.GetTag(line, "#OFFSET");
if (offset != null)
Offset = Convert.ToDouble(offset);
offset = Utils.GetTag(line, "#MOVIEOFFSET");
if (offset != null)
MovieOffset = Convert.ToDouble(offset);
if (line.Contains("#BODY"))
{
index++;
break;
}
} while(++index < file.Length);
int lineNum;
Gimmick gimmickTemp;
Note noteTemp;
Dictionary<int, Note> notesByLine = new();
Dictionary<int, int> refByLine = new();
for (int i = index; i < file.Length; i++)
{
if (String.IsNullOrWhiteSpace(file[i]))
continue;
var parsed = file[i].Split(new string[] {" "}, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
NoteBase temp = new();
temp.BeatInfo = new BeatInfo(Convert.ToInt32(parsed[0]), Convert.ToInt32(parsed[1]));
temp.GimmickType = (GimmickType)Convert.ToInt32(parsed[2]);
switch (temp.GimmickType)
{
case GimmickType.NoGimmick:
noteTemp = new Note(temp.BeatInfo);
noteTemp.NoteType = (NoteType)Convert.ToInt32(parsed[3]);
lineNum = Convert.ToInt32(parsed[4]);
noteTemp.Position = Convert.ToInt32(parsed[5]);
noteTemp.Size = Convert.ToInt32(parsed[6]);
noteTemp.HoldChange = Convert.ToBoolean(Convert.ToInt32(parsed[7]));
if (noteTemp.NoteType == NoteType.MaskAdd || noteTemp.NoteType == NoteType.MaskRemove)
{
noteTemp.MaskFill = (MaskType)Convert.ToInt32(parsed[8]);
}
else if (noteTemp.NoteType == NoteType.HoldStartNoBonus ||
noteTemp.NoteType == NoteType.HoldJoint ||
noteTemp.NoteType == NoteType.HoldStartBonusFlair)
{
refByLine[lineNum] = Convert.ToInt32(parsed[8]);
}
Notes.Add(noteTemp);
notesByLine[lineNum] = Notes.Last();
break;
case GimmickType.BpmChange:
gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType);
gimmickTemp.BPM = Convert.ToDouble(parsed[3]);
Gimmicks.Add(gimmickTemp);
break;
case GimmickType.TimeSignatureChange:
gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType);
gimmickTemp.TimeSig = new TimeSignature() { Upper = Convert.ToInt32(parsed[3]), Lower = parsed.Length == 5 ? Convert.ToInt32(parsed[4]) : 4 };
Gimmicks.Add(gimmickTemp);
break;
case GimmickType.HiSpeedChange:
gimmickTemp = new Gimmick(temp.BeatInfo, temp.GimmickType);
gimmickTemp.HiSpeed = Convert.ToDouble(parsed[3]);
Gimmicks.Add(gimmickTemp);
break;
case GimmickType.ReverseStart:
case GimmickType.ReverseMiddle:
case GimmickType.ReverseEnd:
case GimmickType.StopStart:
case GimmickType.StopEnd:
default:
Gimmicks.Add(new Gimmick(temp.BeatInfo, temp.GimmickType));
break;
}
}
// Generate hold references
for (int i = 0; i < Notes.Count; i++)
{
if (refByLine.ContainsKey(i))
{
Notes[i].NextNote = notesByLine[refByLine[i]];
Notes[i].NextNote.PrevNote = Notes[i];
}
}
RecalcTime();
IsSaved = true;
return true;
}
public bool WriteFile(string filename, bool setSave = true)
{
using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create), new UTF8Encoding(false)))
{
// LF line ending
sw.NewLine = "\n";
sw.WriteLine("#MUSIC_SCORE_ID 0");
sw.WriteLine("#MUSIC_SCORE_VERSION 0");
sw.WriteLine("#GAME_VERSION ");
sw.WriteLine($"#MUSIC_FILE_PATH {SongFileName}");
sw.WriteLine($"#OFFSET {Offset:F6}");
sw.WriteLine($"#MOVIEOFFSET {MovieOffset:F6}");
sw.WriteLine("#BODY");
foreach (var gimmick in Gimmicks)
{
sw.Write($"{gimmick.BeatInfo.Measure,4:F0}{gimmick.BeatInfo.Beat,5:F0}{((int)gimmick.GimmickType),5:F0}");
switch (gimmick.GimmickType)
{
case GimmickType.BpmChange:
sw.WriteLine($" {gimmick.BPM:F6}");
break;
case GimmickType.TimeSignatureChange:
sw.WriteLine($"{gimmick.TimeSig.Upper,5:F0}{gimmick.TimeSig.Lower,5:F0}");
break;
case GimmickType.HiSpeedChange:
sw.WriteLine($" {gimmick.HiSpeed:F6}");
break;
default:
sw.WriteLine("");
break;
}
}
foreach (var note in Notes)
{
sw.Write($"{note.BeatInfo.Measure,4:F0}{note.BeatInfo.Beat,5:F0}{((int)note.GimmickType),5:F0}{(int)note.NoteType,5:F0}");
sw.Write($"{Notes.IndexOf(note),5:F0}{note.Position,5:F0}{note.Size,5:F0}{Convert.ToInt32(note.HoldChange),5:F0}");
if (note.IsMask)
sw.Write($"{(int)note.MaskFill,5:F0}");
if (note.NextNote != null)
sw.Write($"{Notes.IndexOf(note.NextNote),5:F0}");
sw.WriteLine("");
}
}
IsSaved = setSave;
return true;
}
public void RecalcTime()
{
Gimmicks = Gimmicks.OrderBy(x => x.Measure).ToList();
var timeSig = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.TimeSignatureChange && x.Measure == 0.0f);
var bpm = Gimmicks.FirstOrDefault(x => x.GimmickType == GimmickType.BpmChange && x.Measure == 0.0f);
if (timeSig == null || bpm == null)
return; // Cannot calculate times without either starting value
TimeEvents = new();
for (int i = 0; i < Gimmicks.Count; i++)
{
var evt = TimeEvents.FirstOrDefault(x => x.BeatInfo.MeasureDecimal == Gimmicks[i].BeatInfo.MeasureDecimal);
if (Gimmicks[i].GimmickType == GimmickType.BpmChange)
{
if (evt == null)
{
TimeEvents.Add(new Gimmick()
{
BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo),
BPM = Gimmicks[i].BPM,
TimeSig = new TimeSignature(timeSig.TimeSig)
});
}
else
{
evt.BPM = Gimmicks[i].BPM;
}
bpm = Gimmicks[i];
}
if (Gimmicks[i].GimmickType == GimmickType.TimeSignatureChange)
{
if (evt == null)
{
TimeEvents.Add(new Gimmick()
{
BeatInfo = new BeatInfo(Gimmicks[i].BeatInfo),
BPM = bpm.BPM,
TimeSig = new TimeSignature(Gimmicks[i].TimeSig)
});
}
else
{
evt.TimeSig = new TimeSignature(Gimmicks[i].TimeSig);
}
timeSig = Gimmicks[i];
}
}
// Run through all time events and generate valid start times
TimeEvents[0].StartTime = Offset * 1000.0;
for (int i = 1; i < TimeEvents.Count; i++)
{
TimeEvents[i].StartTime = ((TimeEvents[i].Measure - TimeEvents[i - 1].Measure) * (4.0f * TimeEvents[i - 1].TimeSig.Ratio * (60000.0 / TimeEvents[i - 1].BPM))) + TimeEvents[i - 1].StartTime;
}
}
/*
((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) * measure = time
time / ((60000.0 / evt.BPM) * 4.0 * evt.TimeSig.Ratio) = measure
*/
/// <summary>
/// Translate clock time to beats
/// </summary>
/// <param name="time">Current timestamp in ms</param>
/// <returns></returns>
public BeatInfo GetBeat(float time)
{
if (TimeEvents == null || TimeEvents.Count == 0)
return new BeatInfo(-1, 0);
var evt = TimeEvents.Where(x => time >= x.StartTime).LastOrDefault();
if (evt == null)
evt = TimeEvents[0];
return new BeatInfo((float)((time - evt.StartTime) / ((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) + evt.Measure));
}
/// <summary>
/// Translate measures into clock time
/// </summary>
/// <param name="beat"></param>
/// <returns></returns>
public int GetTime(BeatInfo beat)
{
if (TimeEvents == null || TimeEvents.Count == 0)
return 0;
var evt = TimeEvents.Where(x => beat.MeasureDecimal >= x.Measure).LastOrDefault();
if (evt == null)
evt = TimeEvents[0];
return (int)(((60000.0 / evt.BPM) * 4.0f * evt.TimeSig.Ratio) * (beat.MeasureDecimal - evt.Measure) + evt.StartTime);
}
}
}
+578
View File
@@ -0,0 +1,578 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Drawing2D;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;
using System.ComponentModel;
namespace BAKKA_Editor
{
internal class CircleView
{
public SizeF PanelSize { get; private set; }
public RectangleF DrawRect { get; private set; }
public PointF TopCorner { get; private set; }
public PointF CenterPoint { get; private set; }
public float Radius { get; private set; }
public float CurrentMeasure { get; set; }
public float Hispeed { get; set; } = 1.5f;
// Pens and Brushes
public Pen BasePen { get; set; }
public Pen BeatPen { get; set; }
public Pen TickMinorPen { get; set; }
public Pen TickMediumPen { get; set; }
public Pen TickMajorPen { get; set; }
public SolidBrush HoldBrush { get; set; } = new SolidBrush(Color.FromArgb(170, Color.Yellow));
public SolidBrush MaskBrush { get; set; } = new SolidBrush(Color.FromArgb(90, Color.Black));
public SolidBrush BackgroundBrush { get; set; }
public Pen HighlightPen { get; set; }
public Pen FlairPen { get; set; }
private int CursorTransparency = 110;
private int SelectTransparency = 110;
private int FlairTransparency = 75;
// Graphics.
BufferedGraphicsContext gfxContext = BufferedGraphicsManager.Current;
BufferedGraphics bufGraphics;
// Mouse information. Public so other GUI elements can be updated with their values.
public int mouseDownPos = -1;
public Point mouseDownPt;
public int lastMousePos = -1;
public bool rolloverPos = false;
public bool rolloverNeg = false;
public CircleView(SizeF size)
{
Update(size);
}
public void Update(SizeF size)
{
PanelSize = size;
float basePenWidth = PanelSize.Width * 4.0f / 600.0f;
TopCorner = new PointF(basePenWidth * 4, basePenWidth * 4);
DrawRect = new RectangleF(
TopCorner.X,
TopCorner.Y,
PanelSize.Width - basePenWidth * 8,
PanelSize.Height - basePenWidth * 8);
Radius = DrawRect.Width / 2.0f;
CenterPoint = new PointF(TopCorner.X + Radius, TopCorner.Y + Radius);
// Pens
BasePen = new Pen(Color.Black, basePenWidth);
BeatPen = new Pen(Color.White, PanelSize.Width * 1.0f / 600.0f);
TickMinorPen = new Pen(Color.Black, PanelSize.Width * 2.0f / 600.0f);
TickMediumPen = new Pen(Color.Black, PanelSize.Width * 4.0f / 600.0f);
TickMajorPen = new Pen(Color.Black, PanelSize.Width * 7.0f / 600.0f);
HighlightPen = new Pen(Color.FromArgb(SelectTransparency, Color.LightPink), PanelSize.Width * 8.0f / 600.0f);
FlairPen = new Pen(Color.FromArgb(FlairTransparency, Color.Yellow), PanelSize.Width * 8.0f / 600.0f);
}
private float GetTotalMeasureShowNotes(Chart chart)
{
//Convert hispeed to frames
float displayFrames = 73.0f - ((Hispeed - 1.5f) * 10.0f);
//Account for hispeed gimmick
List<Gimmick> HispeedChanges = new List<Gimmick>();
Gimmick InitialSpeed = chart.Gimmicks.Where(x => x.GimmickType == GimmickType.HiSpeedChange && CurrentMeasure > x.Measure).LastOrDefault();
//Add initial hispeed to list
if (InitialSpeed == null)
{
InitialSpeed = new Gimmick();
InitialSpeed.HiSpeed = 1.0;
}
HispeedChanges.Add(InitialSpeed);
//add all hispeed changes to list that happen within the current total time to show notes
float tempTotalTime = ((displayFrames / 60.0f) * 1000.0f);
float currentTime = chart.GetTime(new BeatInfo(CurrentMeasure));
float tempEndTime = currentTime + tempTotalTime;
HispeedChanges.AddRange(chart.Gimmicks.Where(
x => x.Measure >= CurrentMeasure
&& chart.GetTime(new BeatInfo(x.Measure)) < tempEndTime
&& x.GimmickType == GimmickType.HiSpeedChange).ToList());
if (HispeedChanges.Count > 1)
{
for (int i = 0; i < HispeedChanges.Count; i++)
{
float timeDiff;
float itemTime;
float modifiedTime;
if (chart.GetTime(HispeedChanges[i].BeatInfo) <= (tempTotalTime + currentTime))
{
if (i == 0)
itemTime = currentTime;
else
itemTime = chart.GetTime(HispeedChanges[i].BeatInfo);
if (i != HispeedChanges.Count - 1)
{
float tempTestITimeDiff = (currentTime + tempTotalTime) - itemTime;
float tempTestIModifiedTime = (tempTestITimeDiff) / (float)(HispeedChanges[i].HiSpeed);
if ((currentTime + tempTotalTime - tempTestITimeDiff + tempTestIModifiedTime) < chart.GetTime(HispeedChanges[i + 1].BeatInfo))
{
timeDiff = (currentTime + tempTotalTime) - itemTime;
modifiedTime = timeDiff / (float)HispeedChanges[i].HiSpeed;
}
else
{
timeDiff = chart.GetTime(HispeedChanges[i + 1].BeatInfo) - itemTime;
modifiedTime = timeDiff / (float)HispeedChanges[i].HiSpeed;
}
}
else
{
timeDiff = (currentTime + tempTotalTime) - itemTime;
modifiedTime = timeDiff / (float)HispeedChanges[i].HiSpeed;
}
tempTotalTime = tempTotalTime - timeDiff + modifiedTime;
}
}
}
else
{
tempTotalTime /= (float)HispeedChanges[0].HiSpeed;
}
//convert total time to total measure
tempEndTime = currentTime + tempTotalTime;
BeatInfo EndMeasure = chart.GetBeat(tempEndTime);
return EndMeasure.MeasureDecimal - CurrentMeasure;
}
private float GetNoteScaleFromMeasure(Chart chart, float objectTime)
{
// Scale from 0-1
float objectTimeAsTime = chart.GetTime(new BeatInfo(objectTime));
float currentTime = chart.GetTime(new BeatInfo(CurrentMeasure));
float EndTimeShowNotes = chart.GetTime(new BeatInfo(CurrentMeasure + GetTotalMeasureShowNotes(chart)));
float notescaleInit;
var LatestHispeedChange = chart.Gimmicks.Where(x => x.GimmickType == GimmickType.HiSpeedChange && CurrentMeasure >= x.Measure).LastOrDefault();
if (LatestHispeedChange != null && LatestHispeedChange.HiSpeed < 0.0)
{
//Reverse
notescaleInit = (objectTimeAsTime - currentTime) / (EndTimeShowNotes - currentTime);
}
else
{
//Normal
notescaleInit = 1 - ((objectTimeAsTime - currentTime) / (EndTimeShowNotes - currentTime));
}
//Scale math
notescaleInit = 0.001f + (float)Math.Pow(notescaleInit, 3.0f) - (0.501f * (float)Math.Pow(notescaleInit, 2.0f)) + (0.5f * notescaleInit);
return notescaleInit;
}
private ArcInfo GetScaledRect(Chart chart, float objectTime)
{
ArcInfo info = new();
info.NoteScale = GetNoteScaleFromMeasure(chart, objectTime);
float scaledRectSize = DrawRect.Width * info.NoteScale;
float scaledRadius = scaledRectSize / 2.0f;
info.Rect = new RectangleF(
new PointF(
CenterPoint.X - scaledRadius,
CenterPoint.Y - scaledRadius),
new SizeF(scaledRectSize, scaledRectSize));
return info;
}
private ArcInfo GetArcInfo(Chart chart, Note note)
{
ArcInfo info = GetScaledRect(chart, note.Measure);
info.StartAngle = -note.Position * 6;
info.ArcLength = -note.Size * 6;
if(info.ArcLength != -360)
{
info.StartAngle -= 2;
info.ArcLength += 4;
}
return info;
}
// Updates the mouse down position within the circle, and returns the new position.
public void UpdateMouseDown(float xCen, float yCen, Point mousePt)
{
float theta = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI);
if (theta < 0)
theta += 360.0f;
// Left click moves the cursor
mouseDownPos = (int)(theta / 6.0f);
mouseDownPt = mousePt;
lastMousePos = -1;
rolloverPos = false;
rolloverNeg = false;
}
public void UpdateMouseUp()
{
if (mouseDownPos <= -1)
{
return;
}
// Reset position and point.
mouseDownPos = -1;
mouseDownPt = new Point();
}
// Updates the mouse position and returns the new position in degrees.
public int UpdateMouseMove(float xCen, float yCen)
{
float thetaCalc = (float)(Math.Atan2(yCen, xCen) * 180.0f / Math.PI);
if (thetaCalc < 0)
thetaCalc += 360.0f;
int theta = (int)(thetaCalc / 6.0f);
int delta = theta - lastMousePos;
// Handle rollover
if (delta == -59)
{
if (rolloverNeg)
rolloverNeg = false;
else
rolloverPos = true;
}
else if (delta == 59)
{
if (rolloverPos)
rolloverPos = false;
else
rolloverNeg = true;
}
lastMousePos = theta;
return theta;
}
public void DrawBackground(int width, int height, Color color)
{
Rectangle panelRect = new Rectangle(0, 0, width, height);
// Set drawing mode
bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
// Remember background color
BackgroundBrush = new SolidBrush(color);
// Draw background
bufGraphics.Graphics.FillRectangle(BackgroundBrush, panelRect);
}
public void DrawMasks(Chart chart)
{
var masks = chart.Notes.Where(
x => x.Measure <= CurrentMeasure
&& x.IsMask).ToList();
foreach (var mask in masks)
{
if (mask.NoteType == NoteType.MaskAdd)
{
// Check if there's a MaskRemove that counters the MaskAdd (unless the MaskAdd is later)
var rem = masks.FirstOrDefault(x => x.NoteType == NoteType.MaskRemove &&
x.Position == mask.Position && x.Size == mask.Size);
if (rem == null || rem.Measure < mask.Measure)
bufGraphics.Graphics.FillPie(MaskBrush, DrawRect.ToInt(), -mask.Position * 6.0f, -mask.Size * 6.0f);
}
else if (mask.NoteType == NoteType.MaskRemove) // Explicitly draw MaskRemove for edge cases
{
bufGraphics.Graphics.FillPie(BackgroundBrush, DrawRect.ToInt(), -mask.Position * 6.0f, -mask.Size * 6.0f);
}
}
}
public void DrawCircle(Chart chart)
{
// Switch drawing modes
bufGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// Draw measure circle
for (float meas = (float)Math.Ceiling(CurrentMeasure); (meas - CurrentMeasure) < GetTotalMeasureShowNotes(chart); meas += 1.0f)
{
var info = GetScaledRect(chart, meas);
if (info.Rect.Width >= 1)
{
bufGraphics.Graphics.DrawEllipse(BeatPen, info.Rect);
}
}
// Draw base circle
bufGraphics.Graphics.DrawEllipse(TickMediumPen, DrawRect);
}
public void DrawDegreeLines()
{
for (int i = 0; i < 360; i += 6)
{
PointF startPoint = new PointF(
(float)(Radius * Math.Cos(Utils.DegToRad(i))) + CenterPoint.X,
(float)(Radius * Math.Sin(Utils.DegToRad(i))) + CenterPoint.Y);
float tickLength = PanelSize.Width * 10.0f / 285.0f;
float innerRad = Radius - tickLength;
Pen activePen;
if (i % 90 == 0)
{
innerRad = Radius - (tickLength * 3.5f);
activePen = TickMajorPen;
}
else if (i % 30 == 0)
{
innerRad = Radius - (tickLength * 2.5f);
activePen = TickMediumPen;
}
else
{
activePen = TickMinorPen;
}
PointF endPoint = new PointF(
(float)(innerRad * Math.Cos(Utils.DegToRad(i))) + CenterPoint.X,
(float)(innerRad * Math.Sin(Utils.DegToRad(i))) + CenterPoint.Y);
bufGraphics.Graphics.DrawLine(activePen, startPoint, endPoint);
}
}
public void DrawGimmicks(Chart chart, bool showGimmicks, int selectedGimmickIndex)
{
if (showGimmicks)
{
List<Gimmick> drawGimmicks = chart.Gimmicks.Where(
x => x.Measure >= CurrentMeasure
&& x.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart))).ToList();
foreach (var gimmick in drawGimmicks)
{
var info = GetScaledRect(chart, gimmick.Measure);
if (info.Rect.Width >= 1)
{
bufGraphics.Graphics.DrawEllipse(GetPen(gimmick), info.Rect);
}
}
}
}
public void DrawHolds(Chart chart, bool highlightSelectedNote, int selectedNoteIndex)
{
ArcInfo currentInfo = GetScaledRect(chart, CurrentMeasure);
ArcInfo endInfo = GetScaledRect(chart, CurrentMeasure + GetTotalMeasureShowNotes(chart));
// First, draw holes that start before the viewpoint and have nodes that end after
List<Note> holdNotes = chart.Notes.Where(
x => x.Measure < CurrentMeasure
&& x.NextNote != null
&& x.NextNote.Measure > (CurrentMeasure + GetTotalMeasureShowNotes(chart))
&& x.IsHold).ToList();
foreach (var note in holdNotes)
{
ArcInfo info = GetArcInfo(chart, note);
ArcInfo nextInfo = GetArcInfo(chart, (Note)note.NextNote);
//GraphicsPath path = new GraphicsPath();
//path.AddArc(endInfo.Rect, info.StartAngle, info.ArcLength);
//path.AddArc(currentInfo.Rect, info.StartAngle + info.ArcLength, -info.ArcLength);
//bufGraphics.Graphics.FillPath(HoldBrush, path);
float ratio = (currentInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width);
float startNoteAngle = nextInfo.StartAngle;
float endNoteAngle = info.StartAngle;
if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
{
startNoteAngle -= 360;
}
else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
{
endNoteAngle -= 360;
}
float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle;
float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) +
(startNoteAngle - nextInfo.ArcLength);
float arcLength = startAngle - endAngle;
float ratio2 = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width);
float startNoteAngle2 = nextInfo.StartAngle;
float endNoteAngle2 = info.StartAngle;
if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
{
startNoteAngle2 -= 360;
}
else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
{
endNoteAngle2 -= 360;
}
float startAngle2 = ratio2 * (endNoteAngle2 - startNoteAngle2) + startNoteAngle2;
float endAngle2 = ratio2 * ((endNoteAngle2 - info.ArcLength) - (startNoteAngle2 - nextInfo.ArcLength)) +
(startNoteAngle2 - nextInfo.ArcLength);
float arcLength2 = startAngle2 - endAngle2;
GraphicsPath path = new GraphicsPath();
path.AddArc(currentInfo.Rect, startAngle, arcLength);
path.AddArc(endInfo.Rect, startAngle2 + arcLength2, -arcLength2);
bufGraphics.Graphics.FillPath(HoldBrush, path);
}
// Second, draw all the notes on-screen
holdNotes = chart.Notes.Where(
x => x.Measure >= CurrentMeasure
&& x.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart))
&& x.IsHold).ToList();
foreach (var note in holdNotes)
{
ArcInfo info = GetArcInfo(chart, note);
// If the previous note is off-screen, this case handles that
if (note.PrevNote != null && note.PrevNote.Measure < CurrentMeasure)
{
ArcInfo prevInfo = GetArcInfo(chart, (Note)note.PrevNote);
float ratio = (currentInfo.Rect.Width - info.Rect.Width) / (prevInfo.Rect.Width - info.Rect.Width);
float startNoteAngle = info.StartAngle;
float endNoteAngle = prevInfo.StartAngle;
if (info.StartAngle > prevInfo.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180))
{
startNoteAngle -= 360;
}
else if (prevInfo.StartAngle > info.StartAngle && (Math.Abs(info.StartAngle - prevInfo.StartAngle) > 180))
{
endNoteAngle -= 360;
}
float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle;
float endAngle = ratio * ((endNoteAngle - prevInfo.ArcLength) - (startNoteAngle - info.ArcLength)) +
(startNoteAngle - info.ArcLength);
float arcLength = startAngle - endAngle;
GraphicsPath path = new GraphicsPath();
path.AddArc(info.Rect, info.StartAngle, info.ArcLength);
path.AddArc(currentInfo.Rect, startAngle + arcLength, -arcLength);
bufGraphics.Graphics.FillPath(HoldBrush, path);
}
// If the next note is on-screen, this case handles that
if (note.NextNote != null && note.NextNote.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart)))
{
ArcInfo nextInfo = GetArcInfo(chart, (Note)note.NextNote);
GraphicsPath path = new GraphicsPath();
path.AddArc(info.Rect, info.StartAngle, info.ArcLength);
path.AddArc(nextInfo.Rect, nextInfo.StartAngle + nextInfo.ArcLength, -nextInfo.ArcLength);
bufGraphics.Graphics.FillPath(HoldBrush, path);
}
// If the next note is off-screen, this case handles that
if (note.NextNote != null && note.NextNote.Measure > (CurrentMeasure + GetTotalMeasureShowNotes(chart)))
{
ArcInfo nextInfo = GetArcInfo(chart, (Note)note.NextNote);
float ratio = (endInfo.Rect.Width - nextInfo.Rect.Width) / (info.Rect.Width - nextInfo.Rect.Width);
float startNoteAngle = nextInfo.StartAngle;
float endNoteAngle = info.StartAngle;
if (nextInfo.StartAngle > info.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
{
startNoteAngle -= 360;
}
else if (info.StartAngle > nextInfo.StartAngle && (Math.Abs(nextInfo.StartAngle - info.StartAngle) > 180))
{
endNoteAngle -= 360;
}
float startAngle = ratio * (endNoteAngle - startNoteAngle) + startNoteAngle;
float endAngle = ratio * ((endNoteAngle - info.ArcLength) - (startNoteAngle - nextInfo.ArcLength)) +
(startNoteAngle - nextInfo.ArcLength);
float arcLength = startAngle - endAngle;
GraphicsPath path = new GraphicsPath();
path.AddArc(endInfo.Rect, startAngle, arcLength);
path.AddArc(info.Rect, info.StartAngle + info.ArcLength, -info.ArcLength);
bufGraphics.Graphics.FillPath(HoldBrush, path);
}
// Draw note
if (info.Rect.Width >= 1)
{
bufGraphics.Graphics.DrawArc(GetPen(note), info.Rect, info.StartAngle, info.ArcLength);
// Draw bonus
if (note.IsFlair)
bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
// Plot highlighted
if (highlightSelectedNote)
{
if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex])
{
bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
}
}
}
}
}
public void DrawNotes(Chart chart, bool highlightSelectedNote, int selectedNoteIndex)
{
List<Note> drawNotes = chart.Notes.Where(
x => x.Measure >= CurrentMeasure
&& x.Measure <= (CurrentMeasure + GetTotalMeasureShowNotes(chart))
&& !x.IsHold && !x.IsMask).ToList();
foreach (var note in drawNotes)
{
ArcInfo info = GetArcInfo(chart, note);
if (info.Rect.Width >= 1)
{
bufGraphics.Graphics.DrawArc(GetPen(note, info.NoteScale), info.Rect, info.StartAngle, info.ArcLength);
if (note.IsFlair)
{
bufGraphics.Graphics.DrawArc(FlairPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
}
// Plot highlighted
if (highlightSelectedNote)
{
if (selectedNoteIndex != -1 && note == chart.Notes[selectedNoteIndex])
{
bufGraphics.Graphics.DrawArc(HighlightPen, info.Rect, info.StartAngle + 2, info.ArcLength - 4);
}
}
}
}
}
public void DrawCursor(NoteType noteType, float startAngle, float sweepAngle)
{
bufGraphics.Graphics.DrawArc(
GetPen(noteType),
DrawRect,
-(float)startAngle * 6.0f,
-(float)sweepAngle * 6.0f);
}
public void Render(Graphics graphics)
{
bufGraphics.Render(graphics);
}
public void SetBufferedGraphicsContext(int width, int height, Graphics graphics)
{
gfxContext.MaximumBuffer = new Size(width + 1, height + 1);
bufGraphics = gfxContext.Allocate(graphics, new Rectangle(0, 0, width, height));
}
public Pen GetPen(Note note, float noteScale = 1.0f)
{
return new Pen(note.Color, PanelSize.Width * 8.0f * noteScale / 600.0f);
}
public Pen GetPen(NoteType noteType)
{
return new Pen(Color.FromArgb(CursorTransparency, Utils.NoteTypeToColor(noteType)), PanelSize.Width * 24.0f / 600.0f);
}
public Pen GetPen(Gimmick gimmick)
{
return new Pen(Utils.GimmickTypeToColor(gimmick.GimmickType), PanelSize.Width * 1.0f / 600.0f);
}
}
internal struct ArcInfo
{
public float StartAngle;
public float ArcLength;
public RectangleF Rect;
public float NoteScale;
}
}
Binary file not shown.
+72
View File
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor
{
internal enum NoteType
{
TouchNoBonus = 1,
TouchBonus = 2,
SnapRedNoBonus = 3,
SnapBlueNoBonus = 4,
SlideOrangeNoBonus = 5,
SlideOrangeBonus = 6,
SlideGreenNoBonus = 7,
SlideGreenBonus = 8,
HoldStartNoBonus = 9,
HoldJoint = 10,
HoldEnd = 11,
MaskAdd = 12,
MaskRemove = 13,
EndOfChart = 14,
// MaskSameTime = 15,
Chain = 16,
// MaskLane = 17,
// TutorialTag = 18,
// BarLine = 19,
TouchBonusFlair = 20,
SnapRedBonusFlair = 21,
SnapBlueBonusFlair = 22,
SlideOrangeBonusFlair = 23,
SlideGreenBonusFlair = 24,
HoldStartBonusFlair = 25,
ChainBonusFlair = 26,
}
internal enum GimmickType
{
NoGimmick = 1,
BpmChange = 2,
TimeSignatureChange = 3,
// Stop = 4,
HiSpeedChange = 5,
ReverseStart = 6,
ReverseMiddle = 7,
ReverseEnd = 8,
StopStart = 9,
StopEnd = 10,
};
internal enum MaskType
{
Clockwise = 0,
CounterClockwise = 1,
Center = 2
}
internal enum BonusType
{
NoBonus = 0,
Bonus = 1,
Flair = 2
}
internal enum OperationDirection
{
Undo,
Redo
}
}
+585
View File
@@ -0,0 +1,585 @@
namespace BAKKA_Editor
{
partial class GimmickForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.revEnd2Beat2Numeric = new System.Windows.Forms.NumericUpDown();
this.label18 = new System.Windows.Forms.Label();
this.revEnd2Beat1Numeric = new System.Windows.Forms.NumericUpDown();
this.revEnd2MeasureNumeric = new System.Windows.Forms.NumericUpDown();
this.label19 = new System.Windows.Forms.Label();
this.revEnd1Beat2Numeric = new System.Windows.Forms.NumericUpDown();
this.label16 = new System.Windows.Forms.Label();
this.revEnd1Beat1Numeric = new System.Windows.Forms.NumericUpDown();
this.revEnd1MeasureNumeric = new System.Windows.Forms.NumericUpDown();
this.label17 = new System.Windows.Forms.Label();
this.stopEndBeat2Numeric = new System.Windows.Forms.NumericUpDown();
this.label10 = new System.Windows.Forms.Label();
this.stopEndBeat1Numeric = new System.Windows.Forms.NumericUpDown();
this.stopEndMeasureNumeric = new System.Windows.Forms.NumericUpDown();
this.label11 = new System.Windows.Forms.Label();
this.hiSpeedNumeric = new System.Windows.Forms.NumericUpDown();
this.label12 = new System.Windows.Forms.Label();
this.label13 = new System.Windows.Forms.Label();
this.label14 = new System.Windows.Forms.Label();
this.timeSig2Numeric = new System.Windows.Forms.NumericUpDown();
this.timeSig1Numeric = new System.Windows.Forms.NumericUpDown();
this.gimmickBpmNumeric = new System.Windows.Forms.NumericUpDown();
this.label15 = new System.Windows.Forms.Label();
this.insertGimmickButton = new System.Windows.Forms.Button();
this.startBeat2Numeric = new System.Windows.Forms.NumericUpDown();
this.label1 = new System.Windows.Forms.Label();
this.startBeat1Numeric = new System.Windows.Forms.NumericUpDown();
this.startMeasureNumeric = new System.Windows.Forms.NumericUpDown();
this.label2 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat2Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat1Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd2MeasureNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat2Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat1Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd1MeasureNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat2Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat1Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.stopEndMeasureNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.hiSpeedNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.timeSig2Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.timeSig1Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.gimmickBpmNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.startBeat2Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.startBeat1Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.startMeasureNumeric)).BeginInit();
this.SuspendLayout();
//
// revEnd2Beat2Numeric
//
this.revEnd2Beat2Numeric.Location = new System.Drawing.Point(219, 206);
this.revEnd2Beat2Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.revEnd2Beat2Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.revEnd2Beat2Numeric.Name = "revEnd2Beat2Numeric";
this.revEnd2Beat2Numeric.Size = new System.Drawing.Size(42, 23);
this.revEnd2Beat2Numeric.TabIndex = 38;
this.revEnd2Beat2Numeric.Value = new decimal(new int[] {
16,
0,
0,
0});
//
// label18
//
this.label18.AutoSize = true;
this.label18.Location = new System.Drawing.Point(8, 208);
this.label18.Name = "label18";
this.label18.Size = new System.Drawing.Size(61, 15);
this.label18.TabIndex = 40;
this.label18.Text = "Rev End 2:";
//
// revEnd2Beat1Numeric
//
this.revEnd2Beat1Numeric.Location = new System.Drawing.Point(168, 206);
this.revEnd2Beat1Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.revEnd2Beat1Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
-2147483648});
this.revEnd2Beat1Numeric.Name = "revEnd2Beat1Numeric";
this.revEnd2Beat1Numeric.Size = new System.Drawing.Size(38, 23);
this.revEnd2Beat1Numeric.TabIndex = 37;
this.revEnd2Beat1Numeric.ValueChanged += new System.EventHandler(this.revEnd2Beat1Numeric_ValueChanged);
//
// revEnd2MeasureNumeric
//
this.revEnd2MeasureNumeric.Location = new System.Drawing.Point(75, 206);
this.revEnd2MeasureNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.revEnd2MeasureNumeric.Name = "revEnd2MeasureNumeric";
this.revEnd2MeasureNumeric.Size = new System.Drawing.Size(87, 23);
this.revEnd2MeasureNumeric.TabIndex = 36;
this.revEnd2MeasureNumeric.ValueChanged += new System.EventHandler(this.revEnd2MeasureNumeric_ValueChanged);
//
// label19
//
this.label19.AutoSize = true;
this.label19.Location = new System.Drawing.Point(207, 208);
this.label19.Name = "label19";
this.label19.Size = new System.Drawing.Size(12, 15);
this.label19.TabIndex = 39;
this.label19.Text = "/";
//
// revEnd1Beat2Numeric
//
this.revEnd1Beat2Numeric.Location = new System.Drawing.Point(219, 177);
this.revEnd1Beat2Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.revEnd1Beat2Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.revEnd1Beat2Numeric.Name = "revEnd1Beat2Numeric";
this.revEnd1Beat2Numeric.Size = new System.Drawing.Size(42, 23);
this.revEnd1Beat2Numeric.TabIndex = 33;
this.revEnd1Beat2Numeric.Value = new decimal(new int[] {
16,
0,
0,
0});
//
// label16
//
this.label16.AutoSize = true;
this.label16.Location = new System.Drawing.Point(8, 179);
this.label16.Name = "label16";
this.label16.Size = new System.Drawing.Size(61, 15);
this.label16.TabIndex = 35;
this.label16.Text = "Rev End 1:";
//
// revEnd1Beat1Numeric
//
this.revEnd1Beat1Numeric.Location = new System.Drawing.Point(168, 177);
this.revEnd1Beat1Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.revEnd1Beat1Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
-2147483648});
this.revEnd1Beat1Numeric.Name = "revEnd1Beat1Numeric";
this.revEnd1Beat1Numeric.Size = new System.Drawing.Size(38, 23);
this.revEnd1Beat1Numeric.TabIndex = 32;
this.revEnd1Beat1Numeric.ValueChanged += new System.EventHandler(this.revEnd1Beat1Numeric_ValueChanged);
//
// revEnd1MeasureNumeric
//
this.revEnd1MeasureNumeric.Location = new System.Drawing.Point(75, 177);
this.revEnd1MeasureNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.revEnd1MeasureNumeric.Name = "revEnd1MeasureNumeric";
this.revEnd1MeasureNumeric.Size = new System.Drawing.Size(87, 23);
this.revEnd1MeasureNumeric.TabIndex = 31;
this.revEnd1MeasureNumeric.ValueChanged += new System.EventHandler(this.revEnd1MeasureNumeric_ValueChanged);
//
// label17
//
this.label17.AutoSize = true;
this.label17.Location = new System.Drawing.Point(207, 179);
this.label17.Name = "label17";
this.label17.Size = new System.Drawing.Size(12, 15);
this.label17.TabIndex = 34;
this.label17.Text = "/";
//
// stopEndBeat2Numeric
//
this.stopEndBeat2Numeric.Location = new System.Drawing.Point(219, 148);
this.stopEndBeat2Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.stopEndBeat2Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.stopEndBeat2Numeric.Name = "stopEndBeat2Numeric";
this.stopEndBeat2Numeric.Size = new System.Drawing.Size(42, 23);
this.stopEndBeat2Numeric.TabIndex = 13;
this.stopEndBeat2Numeric.Value = new decimal(new int[] {
16,
0,
0,
0});
//
// label10
//
this.label10.AutoSize = true;
this.label10.Location = new System.Drawing.Point(12, 150);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(57, 15);
this.label10.TabIndex = 29;
this.label10.Text = "Stop End:";
//
// stopEndBeat1Numeric
//
this.stopEndBeat1Numeric.Location = new System.Drawing.Point(168, 148);
this.stopEndBeat1Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.stopEndBeat1Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
-2147483648});
this.stopEndBeat1Numeric.Name = "stopEndBeat1Numeric";
this.stopEndBeat1Numeric.Size = new System.Drawing.Size(38, 23);
this.stopEndBeat1Numeric.TabIndex = 12;
this.stopEndBeat1Numeric.ValueChanged += new System.EventHandler(this.stopEndBeat1Numeric_ValueChanged);
//
// stopEndMeasureNumeric
//
this.stopEndMeasureNumeric.Location = new System.Drawing.Point(75, 148);
this.stopEndMeasureNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.stopEndMeasureNumeric.Name = "stopEndMeasureNumeric";
this.stopEndMeasureNumeric.Size = new System.Drawing.Size(87, 23);
this.stopEndMeasureNumeric.TabIndex = 11;
this.stopEndMeasureNumeric.ValueChanged += new System.EventHandler(this.stopEndMeasureNumeric_ValueChanged);
//
// label11
//
this.label11.AutoSize = true;
this.label11.Location = new System.Drawing.Point(10, 121);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(59, 15);
this.label11.TabIndex = 27;
this.label11.Text = "Hi-Speed:";
//
// hiSpeedNumeric
//
this.hiSpeedNumeric.DecimalPlaces = 6;
this.hiSpeedNumeric.Location = new System.Drawing.Point(75, 119);
this.hiSpeedNumeric.Minimum = new decimal(new int[] {
100,
0,
0,
-2147483648});
this.hiSpeedNumeric.Name = "hiSpeedNumeric";
this.hiSpeedNumeric.Size = new System.Drawing.Size(186, 23);
this.hiSpeedNumeric.TabIndex = 26;
this.hiSpeedNumeric.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// label12
//
this.label12.AutoSize = true;
this.label12.Location = new System.Drawing.Point(14, 92);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(55, 15);
this.label12.TabIndex = 25;
this.label12.Text = "Time Sig:";
//
// label13
//
this.label13.AutoSize = true;
this.label13.Location = new System.Drawing.Point(140, 92);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(12, 15);
this.label13.TabIndex = 13;
this.label13.Text = "/";
//
// label14
//
this.label14.AutoSize = true;
this.label14.Location = new System.Drawing.Point(34, 63);
this.label14.Name = "label14";
this.label14.Size = new System.Drawing.Size(35, 15);
this.label14.TabIndex = 24;
this.label14.Text = "BPM:";
//
// timeSig2Numeric
//
this.timeSig2Numeric.Location = new System.Drawing.Point(158, 90);
this.timeSig2Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.timeSig2Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.timeSig2Numeric.Name = "timeSig2Numeric";
this.timeSig2Numeric.Size = new System.Drawing.Size(103, 23);
this.timeSig2Numeric.TabIndex = 12;
this.timeSig2Numeric.Value = new decimal(new int[] {
4,
0,
0,
0});
//
// timeSig1Numeric
//
this.timeSig1Numeric.Location = new System.Drawing.Point(75, 90);
this.timeSig1Numeric.Maximum = new decimal(new int[] {
191,
0,
0,
0});
this.timeSig1Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.timeSig1Numeric.Name = "timeSig1Numeric";
this.timeSig1Numeric.Size = new System.Drawing.Size(59, 23);
this.timeSig1Numeric.TabIndex = 11;
this.timeSig1Numeric.Value = new decimal(new int[] {
4,
0,
0,
0});
//
// gimmickBpmNumeric
//
this.gimmickBpmNumeric.DecimalPlaces = 6;
this.gimmickBpmNumeric.Location = new System.Drawing.Point(75, 61);
this.gimmickBpmNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.gimmickBpmNumeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.gimmickBpmNumeric.Name = "gimmickBpmNumeric";
this.gimmickBpmNumeric.Size = new System.Drawing.Size(186, 23);
this.gimmickBpmNumeric.TabIndex = 23;
this.gimmickBpmNumeric.Value = new decimal(new int[] {
120,
0,
0,
0});
//
// label15
//
this.label15.AutoSize = true;
this.label15.Location = new System.Drawing.Point(207, 150);
this.label15.Name = "label15";
this.label15.Size = new System.Drawing.Size(12, 15);
this.label15.TabIndex = 14;
this.label15.Text = "/";
//
// insertGimmickButton
//
this.insertGimmickButton.Font = new System.Drawing.Font("Segoe UI", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.insertGimmickButton.Location = new System.Drawing.Point(12, 248);
this.insertGimmickButton.Name = "insertGimmickButton";
this.insertGimmickButton.Size = new System.Drawing.Size(253, 40);
this.insertGimmickButton.TabIndex = 33;
this.insertGimmickButton.Text = "Insert Gimmick";
this.insertGimmickButton.UseVisualStyleBackColor = true;
this.insertGimmickButton.Click += new System.EventHandler(this.insertGimmickButton_Click);
//
// startBeat2Numeric
//
this.startBeat2Numeric.Location = new System.Drawing.Point(219, 12);
this.startBeat2Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.startBeat2Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.startBeat2Numeric.Name = "startBeat2Numeric";
this.startBeat2Numeric.Size = new System.Drawing.Size(42, 23);
this.startBeat2Numeric.TabIndex = 43;
this.startBeat2Numeric.Value = new decimal(new int[] {
16,
0,
0,
0});
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(34, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(34, 15);
this.label1.TabIndex = 45;
this.label1.Text = "Start:";
//
// startBeat1Numeric
//
this.startBeat1Numeric.Location = new System.Drawing.Point(168, 12);
this.startBeat1Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.startBeat1Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
-2147483648});
this.startBeat1Numeric.Name = "startBeat1Numeric";
this.startBeat1Numeric.Size = new System.Drawing.Size(38, 23);
this.startBeat1Numeric.TabIndex = 42;
this.startBeat1Numeric.ValueChanged += new System.EventHandler(this.startBeat1Numeric_ValueChanged);
//
// startMeasureNumeric
//
this.startMeasureNumeric.Location = new System.Drawing.Point(75, 12);
this.startMeasureNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.startMeasureNumeric.Name = "startMeasureNumeric";
this.startMeasureNumeric.Size = new System.Drawing.Size(87, 23);
this.startMeasureNumeric.TabIndex = 41;
this.startMeasureNumeric.ValueChanged += new System.EventHandler(this.startMeasureNumeric_ValueChanged);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(207, 14);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(12, 15);
this.label2.TabIndex = 44;
this.label2.Text = "/";
//
// GimmickForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(281, 303);
this.Controls.Add(this.startBeat2Numeric);
this.Controls.Add(this.label1);
this.Controls.Add(this.startBeat1Numeric);
this.Controls.Add(this.startMeasureNumeric);
this.Controls.Add(this.label2);
this.Controls.Add(this.revEnd2Beat2Numeric);
this.Controls.Add(this.insertGimmickButton);
this.Controls.Add(this.label18);
this.Controls.Add(this.revEnd2Beat1Numeric);
this.Controls.Add(this.gimmickBpmNumeric);
this.Controls.Add(this.revEnd2MeasureNumeric);
this.Controls.Add(this.label15);
this.Controls.Add(this.label19);
this.Controls.Add(this.timeSig1Numeric);
this.Controls.Add(this.revEnd1Beat2Numeric);
this.Controls.Add(this.timeSig2Numeric);
this.Controls.Add(this.label16);
this.Controls.Add(this.label14);
this.Controls.Add(this.revEnd1Beat1Numeric);
this.Controls.Add(this.label13);
this.Controls.Add(this.revEnd1MeasureNumeric);
this.Controls.Add(this.label12);
this.Controls.Add(this.label17);
this.Controls.Add(this.hiSpeedNumeric);
this.Controls.Add(this.stopEndBeat2Numeric);
this.Controls.Add(this.label11);
this.Controls.Add(this.label10);
this.Controls.Add(this.stopEndMeasureNumeric);
this.Controls.Add(this.stopEndBeat1Numeric);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "GimmickForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Gimmick Settings";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.GimmickForm_FormClosing);
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat2Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd2Beat1Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd2MeasureNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat2Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd1Beat1Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.revEnd1MeasureNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat2Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.stopEndBeat1Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.stopEndMeasureNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.hiSpeedNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.timeSig2Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.timeSig1Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.gimmickBpmNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.startBeat2Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.startBeat1Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.startMeasureNumeric)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private NumericUpDown revEnd2Beat2Numeric;
private Label label18;
private NumericUpDown revEnd2Beat1Numeric;
private NumericUpDown revEnd2MeasureNumeric;
private Label label19;
private NumericUpDown revEnd1Beat2Numeric;
private Label label16;
private NumericUpDown revEnd1Beat1Numeric;
private NumericUpDown revEnd1MeasureNumeric;
private Label label17;
private NumericUpDown stopEndBeat2Numeric;
private Label label10;
private NumericUpDown stopEndBeat1Numeric;
private NumericUpDown stopEndMeasureNumeric;
private Label label11;
private NumericUpDown hiSpeedNumeric;
private Label label12;
private Label label13;
private Label label14;
private NumericUpDown timeSig2Numeric;
private NumericUpDown timeSig1Numeric;
private NumericUpDown gimmickBpmNumeric;
private Label label15;
private Button insertGimmickButton;
private NumericUpDown startBeat2Numeric;
private Label label1;
private NumericUpDown startBeat1Numeric;
private NumericUpDown startMeasureNumeric;
private Label label2;
}
}
+394
View File
@@ -0,0 +1,394 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BAKKA_Editor
{
public partial class GimmickForm : Form
{
private Gimmick gimmick;
public bool InsertGimmick { get; private set; }
internal List<Gimmick> Gimmicks { get; private set; }
float StartMeasure { get { return (float)startMeasureNumeric.Value + (float)startBeat1Numeric.Value / (float)startBeat2Numeric.Value; } }
float StopEndMeasure { get { return (float)stopEndMeasureNumeric.Value + (float)stopEndBeat1Numeric.Value / (float)stopEndBeat2Numeric.Value; } }
float RevEnd1Measure { get { return (float)revEnd1MeasureNumeric.Value + (float)revEnd1Beat1Numeric.Value / (float)revEnd1Beat2Numeric.Value; } }
float RevEnd2Measure { get { return (float)revEnd2MeasureNumeric.Value + (float)revEnd2Beat1Numeric.Value / (float)revEnd2Beat2Numeric.Value; } }
public enum FormReason
{
New,
Edit
};
public GimmickForm()
{
InitializeComponent();
}
internal DialogResult Show(
Gimmick baseGimmick, FormReason reason, Gimmick? gim1 = null, Gimmick? gim2 = null)
{
var quant = Utils.GetQuantization(baseGimmick.BeatInfo.Beat, 12);
gimmick = new Gimmick();
gimmick.BeatInfo = new BeatInfo(baseGimmick.BeatInfo);
gimmick.GimmickType = baseGimmick.GimmickType;
switch (gimmick.GimmickType)
{
case GimmickType.BpmChange:
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
startBeat2Numeric.Value = quant.Item2;
startBeat1Numeric.Value = quant.Item1;
if (reason == FormReason.Edit)
gimmickBpmNumeric.Value = (decimal)baseGimmick.BPM;
break;
case GimmickType.TimeSignatureChange:
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
startBeat2Numeric.Value = quant.Item2;
startBeat1Numeric.Value = quant.Item1;
if (reason == FormReason.Edit)
{
timeSig1Numeric.Value = baseGimmick.TimeSig.Upper;
timeSig2Numeric.Value = baseGimmick.TimeSig.Lower;
}
break;
case GimmickType.HiSpeedChange:
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
startBeat2Numeric.Value = quant.Item2;
startBeat1Numeric.Value = quant.Item1;
if (reason == FormReason.Edit)
hiSpeedNumeric.Value = (decimal)baseGimmick.HiSpeed;
break;
case GimmickType.ReverseStart:
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
startBeat2Numeric.Value = quant.Item2;
startBeat1Numeric.Value = quant.Item1;
if (reason == FormReason.Edit && gim1 != null && gim2 != null)
{
var quantMid1 = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
var quantEnd1 = Utils.GetQuantization(gim2.BeatInfo.Beat, 12);
revEnd1MeasureNumeric.Value = gim1.BeatInfo.Measure;
revEnd1Beat2Numeric.Value = quantMid1.Item2;
revEnd1Beat1Numeric.Value = quantMid1.Item1;
revEnd2MeasureNumeric.Value = gim2.BeatInfo.Measure;
revEnd2Beat2Numeric.Value = quantEnd1.Item2;
revEnd2Beat1Numeric.Value = quantEnd1.Item1;
}
break;
case GimmickType.ReverseMiddle:
var quantStart2 = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
var quantEnd2 = Utils.GetQuantization(gim2.BeatInfo.Beat, 12);
startMeasureNumeric.Value = gim1.BeatInfo.Measure;
startBeat2Numeric.Value = quantStart2.Item2;
startBeat1Numeric.Value = quantStart2.Item1;
revEnd1MeasureNumeric.Value = gimmick.BeatInfo.Measure;
revEnd1Beat2Numeric.Value = quant.Item2;
revEnd1Beat1Numeric.Value = quant.Item1;
revEnd2MeasureNumeric.Value = gim2.BeatInfo.Measure;
revEnd2Beat2Numeric.Value = quantEnd2.Item2;
revEnd2Beat1Numeric.Value = quantEnd2.Item1;
break;
case GimmickType.ReverseEnd:
var quantStart3 = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
var quantMid3 = Utils.GetQuantization(gim2.BeatInfo.Beat, 12);
startMeasureNumeric.Value = gim1.BeatInfo.Measure;
startBeat2Numeric.Value = quantStart3.Item2;
startBeat1Numeric.Value = quantStart3.Item1;
revEnd1MeasureNumeric.Value = gim2.BeatInfo.Measure;
revEnd1Beat2Numeric.Value = quantMid3.Item2;
revEnd1Beat1Numeric.Value = quantMid3.Item1;
revEnd2MeasureNumeric.Value = gimmick.BeatInfo.Measure;
revEnd2Beat2Numeric.Value = quant.Item2;
revEnd2Beat1Numeric.Value = quant.Item1;
break;
case GimmickType.StopStart:
startMeasureNumeric.Value = gimmick.BeatInfo.Measure;
startBeat2Numeric.Value = quant.Item2;
startBeat1Numeric.Value = quant.Item1;
if (reason == FormReason.Edit)
{
var stopEnd = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
stopEndMeasureNumeric.Value = gim1.BeatInfo.Measure;
stopEndBeat2Numeric.Value = stopEnd.Item2;
stopEndBeat1Numeric.Value = stopEnd.Item1;
}
break;
case GimmickType.StopEnd:
var stopStart = Utils.GetQuantization(gim1.BeatInfo.Beat, 12);
startMeasureNumeric.Value = gim1.BeatInfo.Measure;
startBeat2Numeric.Value = stopStart.Item2;
startBeat1Numeric.Value = stopStart.Item1;
stopEndMeasureNumeric.Value = gimmick.BeatInfo.Measure;
stopEndBeat2Numeric.Value = quant.Item2;
stopEndBeat1Numeric.Value = quant.Item1;
break;
default:
break;
}
gimmickBpmNumeric.Enabled = gimmick.GimmickType == GimmickType.BpmChange;
timeSig1Numeric.Enabled = gimmick.GimmickType == GimmickType.TimeSignatureChange;
timeSig2Numeric.Enabled = gimmick.GimmickType == GimmickType.TimeSignatureChange;
hiSpeedNumeric.Enabled = gimmick.GimmickType == GimmickType.HiSpeedChange;
stopEndMeasureNumeric.Enabled = gimmick.IsStop;
stopEndBeat1Numeric.Enabled = gimmick.IsStop;
stopEndBeat2Numeric.Enabled = gimmick.IsStop;
revEnd1MeasureNumeric.Enabled = gimmick.IsReverse;
revEnd1Beat1Numeric.Enabled = gimmick.IsReverse;
revEnd1Beat2Numeric.Enabled = gimmick.IsReverse;
revEnd2MeasureNumeric.Enabled = gimmick.IsReverse;
revEnd2Beat1Numeric.Enabled = gimmick.IsReverse;
revEnd2Beat2Numeric.Enabled = gimmick.IsReverse;
Gimmicks = new List<Gimmick>();
InsertGimmick = false;
switch (reason)
{
case FormReason.New:
insertGimmickButton.Text = "Insert Gimmick";
break;
case FormReason.Edit:
insertGimmickButton.Text = "Edit Gimmick";
break;
default:
break;
}
return ShowDialog();
}
private void GimmickForm_FormClosing(object sender, FormClosingEventArgs e)
{
}
private void insertGimmickButton_Click(object sender, EventArgs e)
{
switch (gimmick.GimmickType)
{
case GimmickType.BpmChange:
gimmick.BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value);
gimmick.BPM = (double)gimmickBpmNumeric.Value;
Gimmicks.Add(gimmick);
break;
case GimmickType.TimeSignatureChange:
gimmick.BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value);
gimmick.TimeSig.Upper = (int)timeSig1Numeric.Value;
gimmick.TimeSig.Lower = (int)timeSig2Numeric.Value;
Gimmicks.Add(gimmick);
break;
case GimmickType.HiSpeedChange:
gimmick.BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value);
gimmick.HiSpeed = (double)hiSpeedNumeric.Value;
Gimmicks.Add(gimmick);
break;
case GimmickType.ReverseStart:
case GimmickType.ReverseMiddle:
case GimmickType.ReverseEnd:
Gimmicks.Add(new Gimmick()
{
BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value),
GimmickType = GimmickType.ReverseStart
});
Gimmicks.Add(new Gimmick()
{
BeatInfo = new BeatInfo((int)revEnd1MeasureNumeric.Value, (int)revEnd1Beat1Numeric.Value * 1920 / (int)revEnd1Beat2Numeric.Value),
GimmickType = GimmickType.ReverseMiddle
});
Gimmicks.Add(new Gimmick()
{
BeatInfo = new BeatInfo((int)revEnd2MeasureNumeric.Value, (int)revEnd2Beat1Numeric.Value * 1920 / (int)revEnd2Beat2Numeric.Value),
GimmickType = GimmickType.ReverseEnd
});
break;
case GimmickType.StopStart:
case GimmickType.StopEnd:
Gimmicks.Add(new Gimmick()
{
BeatInfo = new BeatInfo((int)startMeasureNumeric.Value, (int)startBeat1Numeric.Value * 1920 / (int)startBeat2Numeric.Value),
GimmickType = GimmickType.StopStart
});
Gimmicks.Add(new Gimmick()
{
BeatInfo = new BeatInfo((int)stopEndMeasureNumeric.Value, (int)stopEndBeat1Numeric.Value * 1920 / (int)stopEndBeat2Numeric.Value),
GimmickType = GimmickType.StopEnd
});
break;
default:
break;
}
DialogResult = DialogResult.OK;
}
private void startMeasureNumeric_ValueChanged(object sender, EventArgs e)
{
if (stopEndMeasureNumeric.Enabled && StopEndMeasure < StartMeasure)
{
stopEndMeasureNumeric.Value = startMeasureNumeric.Value + 1;
}
if (revEnd1MeasureNumeric.Enabled && RevEnd1Measure < StartMeasure)
{
revEnd1MeasureNumeric.Value = startMeasureNumeric.Value + 1;
}
}
private void startBeat1Numeric_ValueChanged(object sender, EventArgs e)
{
if (startBeat1Numeric.Value >= startBeat2Numeric.Value)
{
startMeasureNumeric.Value++;
startBeat1Numeric.Value = 0;
}
else if (startBeat1Numeric.Value < 0)
{
if (startMeasureNumeric.Value > 0)
{
startMeasureNumeric.Value--;
startBeat1Numeric.Value = startBeat2Numeric.Value - 1;
}
else if (startMeasureNumeric.Value == 0)
{
startBeat1Numeric.Value = 0;
}
}
}
private void stopEndMeasureNumeric_ValueChanged(object sender, EventArgs e)
{
if (StopEndMeasure < StartMeasure)
{
stopEndMeasureNumeric.Value = startMeasureNumeric.Value;
stopEndBeat1Numeric.Value = startBeat1Numeric.Value;
stopEndBeat2Numeric.Value = startBeat2Numeric.Value;
return;
}
}
private void stopEndBeat1Numeric_ValueChanged(object sender, EventArgs e)
{
if (StopEndMeasure < StartMeasure)
{
stopEndMeasureNumeric.Value = startMeasureNumeric.Value;
stopEndBeat1Numeric.Value = startBeat1Numeric.Value;
stopEndBeat2Numeric.Value = startBeat2Numeric.Value;
return;
}
if (stopEndBeat1Numeric.Value >= stopEndBeat2Numeric.Value)
{
stopEndMeasureNumeric.Value++;
stopEndBeat1Numeric.Value = 0;
}
else if (stopEndBeat1Numeric.Value < 0)
{
if (stopEndMeasureNumeric.Value > 0)
{
stopEndMeasureNumeric.Value--;
stopEndBeat1Numeric.Value = stopEndBeat2Numeric.Value - 1;
}
else if (stopEndMeasureNumeric.Value == 0)
{
stopEndBeat1Numeric.Value = 0;
}
}
}
private void revEnd1MeasureNumeric_ValueChanged(object sender, EventArgs e)
{
if (RevEnd1Measure < StartMeasure)
{
revEnd1MeasureNumeric.Value = startMeasureNumeric.Value;
revEnd1Beat1Numeric.Value = startBeat1Numeric.Value;
revEnd1Beat2Numeric.Value = startBeat2Numeric.Value;
}
if (RevEnd2Measure < RevEnd1Measure)
{
revEnd2MeasureNumeric.Value = revEnd1MeasureNumeric.Value;
revEnd2Beat1Numeric.Value = revEnd1Beat1Numeric.Value;
revEnd2Beat2Numeric.Value = revEnd1Beat2Numeric.Value;
}
}
private void revEnd1Beat1Numeric_ValueChanged(object sender, EventArgs e)
{
if (RevEnd1Measure < StartMeasure)
{
revEnd1MeasureNumeric.Value = startMeasureNumeric.Value;
revEnd1Beat1Numeric.Value = startBeat1Numeric.Value;
revEnd1Beat2Numeric.Value = startBeat2Numeric.Value;
return;
}
if (revEnd1Beat1Numeric.Value >= revEnd1Beat2Numeric.Value)
{
revEnd1MeasureNumeric.Value++;
revEnd1Beat1Numeric.Value = 0;
}
else if (revEnd1Beat1Numeric.Value < 0)
{
if (revEnd1MeasureNumeric.Value > 0)
{
revEnd1MeasureNumeric.Value--;
revEnd1Beat1Numeric.Value = revEnd1Beat2Numeric.Value - 1;
}
else if (revEnd1MeasureNumeric.Value == 0)
{
revEnd1Beat1Numeric.Value = 0;
}
}
}
private void revEnd2MeasureNumeric_ValueChanged(object sender, EventArgs e)
{
if (RevEnd2Measure < RevEnd1Measure)
{
revEnd2MeasureNumeric.Value = revEnd1MeasureNumeric.Value;
revEnd2Beat1Numeric.Value = revEnd1Beat1Numeric.Value;
revEnd2Beat2Numeric.Value = revEnd1Beat2Numeric.Value;
return;
}
}
private void revEnd2Beat1Numeric_ValueChanged(object sender, EventArgs e)
{
if (RevEnd2Measure < RevEnd1Measure)
{
revEnd2MeasureNumeric.Value = revEnd1MeasureNumeric.Value;
revEnd2Beat1Numeric.Value = revEnd1Beat1Numeric.Value;
revEnd2Beat2Numeric.Value = revEnd1Beat2Numeric.Value;
return;
}
if (revEnd2Beat1Numeric.Value >= revEnd2Beat2Numeric.Value)
{
revEnd2MeasureNumeric.Value++;
revEnd2Beat1Numeric.Value = 0;
}
else if (revEnd2Beat1Numeric.Value < 0)
{
if (revEnd2MeasureNumeric.Value > 0)
{
revEnd2MeasureNumeric.Value--;
revEnd2Beat1Numeric.Value = revEnd2Beat2Numeric.Value - 1;
}
else if (revEnd2MeasureNumeric.Value == 0)
{
revEnd2Beat1Numeric.Value = 0;
}
}
}
}
}
+60
View File
@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+246
View File
@@ -0,0 +1,246 @@
namespace BAKKA_Editor
{
partial class InitChartSettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.initSaveSettingsButton = new System.Windows.Forms.Button();
this.label9 = new System.Windows.Forms.Label();
this.initMovieOffsetNumeric = new System.Windows.Forms.NumericUpDown();
this.label8 = new System.Windows.Forms.Label();
this.initOffsetNumeric = new System.Windows.Forms.NumericUpDown();
this.label7 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.initTimeSig2Numeric = new System.Windows.Forms.NumericUpDown();
this.initTimeSig1Numeric = new System.Windows.Forms.NumericUpDown();
this.initBpmNumeric = new System.Windows.Forms.NumericUpDown();
((System.ComponentModel.ISupportInitialize)(this.initMovieOffsetNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.initOffsetNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.initTimeSig2Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.initTimeSig1Numeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.initBpmNumeric)).BeginInit();
this.SuspendLayout();
//
// initSaveSettingsButton
//
this.initSaveSettingsButton.Location = new System.Drawing.Point(12, 128);
this.initSaveSettingsButton.Name = "initSaveSettingsButton";
this.initSaveSettingsButton.Size = new System.Drawing.Size(218, 23);
this.initSaveSettingsButton.TabIndex = 30;
this.initSaveSettingsButton.Text = "Save Settings";
this.initSaveSettingsButton.UseVisualStyleBackColor = true;
this.initSaveSettingsButton.Click += new System.EventHandler(this.initSaveSettingsButton_Click);
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(46, 101);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(78, 15);
this.label9.TabIndex = 29;
this.label9.Text = "Movie Offset:";
//
// initMovieOffsetNumeric
//
this.initMovieOffsetNumeric.DecimalPlaces = 6;
this.initMovieOffsetNumeric.Location = new System.Drawing.Point(130, 99);
this.initMovieOffsetNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.initMovieOffsetNumeric.Name = "initMovieOffsetNumeric";
this.initMovieOffsetNumeric.Size = new System.Drawing.Size(100, 23);
this.initMovieOffsetNumeric.TabIndex = 28;
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(82, 74);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(42, 15);
this.label8.TabIndex = 27;
this.label8.Text = "Offset:";
//
// initOffsetNumeric
//
this.initOffsetNumeric.DecimalPlaces = 6;
this.initOffsetNumeric.Location = new System.Drawing.Point(130, 70);
this.initOffsetNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.initOffsetNumeric.Minimum = new decimal(new int[] {
9999,
0,
0,
-2147483648});
this.initOffsetNumeric.Name = "initOffsetNumeric";
this.initOffsetNumeric.Size = new System.Drawing.Size(100, 23);
this.initOffsetNumeric.TabIndex = 26;
//
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(35, 43);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(89, 15);
this.label7.TabIndex = 25;
this.label7.Text = "Time Signature:";
//
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(174, 43);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(12, 15);
this.label6.TabIndex = 13;
this.label6.Text = "/";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(89, 14);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(35, 15);
this.label5.TabIndex = 24;
this.label5.Text = "BPM:";
//
// initTimeSig2Numeric
//
this.initTimeSig2Numeric.Location = new System.Drawing.Point(192, 41);
this.initTimeSig2Numeric.Maximum = new decimal(new int[] {
1920,
0,
0,
0});
this.initTimeSig2Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.initTimeSig2Numeric.Name = "initTimeSig2Numeric";
this.initTimeSig2Numeric.Size = new System.Drawing.Size(38, 23);
this.initTimeSig2Numeric.TabIndex = 12;
this.initTimeSig2Numeric.Value = new decimal(new int[] {
4,
0,
0,
0});
//
// initTimeSig1Numeric
//
this.initTimeSig1Numeric.Location = new System.Drawing.Point(130, 41);
this.initTimeSig1Numeric.Maximum = new decimal(new int[] {
191,
0,
0,
0});
this.initTimeSig1Numeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.initTimeSig1Numeric.Name = "initTimeSig1Numeric";
this.initTimeSig1Numeric.Size = new System.Drawing.Size(38, 23);
this.initTimeSig1Numeric.TabIndex = 11;
this.initTimeSig1Numeric.Value = new decimal(new int[] {
4,
0,
0,
0});
//
// initBpmNumeric
//
this.initBpmNumeric.DecimalPlaces = 6;
this.initBpmNumeric.Location = new System.Drawing.Point(130, 12);
this.initBpmNumeric.Maximum = new decimal(new int[] {
9999,
0,
0,
0});
this.initBpmNumeric.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.initBpmNumeric.Name = "initBpmNumeric";
this.initBpmNumeric.Size = new System.Drawing.Size(100, 23);
this.initBpmNumeric.TabIndex = 23;
this.initBpmNumeric.Value = new decimal(new int[] {
120,
0,
0,
0});
//
// InitChartSettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(242, 164);
this.Controls.Add(this.initSaveSettingsButton);
this.Controls.Add(this.label9);
this.Controls.Add(this.initBpmNumeric);
this.Controls.Add(this.initMovieOffsetNumeric);
this.Controls.Add(this.initTimeSig1Numeric);
this.Controls.Add(this.label8);
this.Controls.Add(this.initTimeSig2Numeric);
this.Controls.Add(this.initOffsetNumeric);
this.Controls.Add(this.label5);
this.Controls.Add(this.label7);
this.Controls.Add(this.label6);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "InitChartSettingsForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Initial Chart Settings";
((System.ComponentModel.ISupportInitialize)(this.initMovieOffsetNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.initOffsetNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.initTimeSig2Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.initTimeSig1Numeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.initBpmNumeric)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Button initSaveSettingsButton;
private Label label9;
private NumericUpDown initMovieOffsetNumeric;
private Label label8;
private NumericUpDown initOffsetNumeric;
private Label label7;
private Label label6;
private Label label5;
private NumericUpDown initTimeSig2Numeric;
private NumericUpDown initTimeSig1Numeric;
private NumericUpDown initBpmNumeric;
}
}
+40
View File
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BAKKA_Editor
{
public partial class InitChartSettingsForm : Form
{
public double Bpm { get { return (double)initBpmNumeric.Value; } }
public int TimeSigUpper { get { return (int)initTimeSig1Numeric.Value; } }
public int TimeSigLower { get { return (int)initTimeSig2Numeric.Value; } }
public double Offset { get { return (double)initOffsetNumeric.Value; } }
public double MovieOffset { get { return (double)initMovieOffsetNumeric.Value; } }
public InitChartSettingsForm()
{
InitializeComponent();
}
public void SetValues(double bpm, int timeSigUpper, int timeSigLower, double offset, double movieOffset)
{
initBpmNumeric.Value = (decimal)bpm;
initTimeSig1Numeric.Value = timeSigUpper;
initTimeSig2Numeric.Value = timeSigLower;
initOffsetNumeric.Value = (decimal)offset;
initMovieOffsetNumeric.Value = (decimal)movieOffset;
}
private void initSaveSettingsButton_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
}
}
+60
View File
@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+1581
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+229
View File
@@ -0,0 +1,229 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor
{
internal class BeatInfo
{
public int Measure;
public int Beat;
public BeatInfo(int measure, int beat)
{
Measure = measure;
Beat = beat;
}
public BeatInfo(float measure)
{
Measure = (int)Math.Floor(measure);
Beat = (int)((measure - (float)Measure) * 1920.0f);
}
public BeatInfo(BeatInfo info)
{
Measure = info.Measure;
Beat = info.Beat;
}
public float MeasureDecimal { get { return (float)Measure + (float)Beat / 1920.0f; } }
}
internal class TimeSignature
{
public int Upper;
public int Lower;
public double Ratio { get { return (double)Upper / (double)Lower; } }
public TimeSignature()
{
Upper = 4;
Lower = 4;
}
public TimeSignature(TimeSignature sig)
{
Upper = sig.Upper;
Lower = sig.Lower;
}
}
internal class NoteBase
{
public BeatInfo BeatInfo { get; set; } = new BeatInfo(-1, 0);
public GimmickType GimmickType { get; set; } = GimmickType.NoGimmick;
public float Measure { get { return BeatInfo.MeasureDecimal; } }
}
internal class Note : NoteBase
{
public NoteType NoteType { get; set; } = NoteType.TouchNoBonus;
public int Position { get; set; }
public int Size { get; set; }
[System.ComponentModel.Browsable(false)]
public bool HoldChange { get; set; }
[System.ComponentModel.Browsable(false)]
public MaskType MaskFill { get; set; }
[System.ComponentModel.Browsable(false)]
public Note NextNote { get; set; }
[System.ComponentModel.Browsable(false)]
public Note PrevNote { get; set; }
[System.ComponentModel.Browsable(false)]
public bool IsHold
{
get
{
switch (NoteType)
{
case NoteType.HoldStartNoBonus:
case NoteType.HoldJoint:
case NoteType.HoldEnd:
case NoteType.HoldStartBonusFlair:
return true;
default:
return false;
}
}
}
[System.ComponentModel.Browsable(false)]
public bool IsMask
{
get
{
switch (NoteType)
{
case NoteType.MaskAdd:
case NoteType.MaskRemove:
return true;
default:
return false;
}
}
}
[System.ComponentModel.Browsable(false)]
public bool IsBonus
{
get
{
switch (NoteType)
{
case NoteType.TouchBonus:
case NoteType.SlideOrangeBonus:
case NoteType.SlideGreenBonus:
return true;
default:
return false; ;
}
}
}
[System.ComponentModel.Browsable(false)]
public bool IsFlair
{
get
{
switch (NoteType)
{
case NoteType.TouchBonusFlair:
case NoteType.SnapRedBonusFlair:
case NoteType.SnapBlueBonusFlair:
case NoteType.SlideOrangeBonusFlair:
case NoteType.SlideGreenBonusFlair:
case NoteType.HoldStartBonusFlair:
case NoteType.ChainBonusFlair:
return true;
default:
return false;
}
}
}
[System.ComponentModel.Browsable(false)]
public Color Color
{
get
{
return Utils.NoteTypeToColor(NoteType);
}
}
public Note() { }
public Note(BeatInfo info)
{
BeatInfo = info;
GimmickType = GimmickType.NoGimmick;
}
public Note(Note baseNote) : this(baseNote.BeatInfo)
{
Position = baseNote.Position;
Size = baseNote.Size;
NoteType = baseNote.NoteType;
}
}
internal class Gimmick : NoteBase
{
public double BPM { get; set; }
public TimeSignature TimeSig { get; set; } = new();
public double HiSpeed { get; set; }
public double StartTime { get; set; }
public bool IsReverse
{
get
{
switch (GimmickType)
{
case GimmickType.ReverseStart:
case GimmickType.ReverseMiddle:
case GimmickType.ReverseEnd:
return true;
default:
return false;
}
}
}
public bool IsStop
{
get
{
switch (GimmickType)
{
case GimmickType.StopStart:
case GimmickType.StopEnd:
return true;
default:
return false;
}
}
}
public Gimmick() { }
public Gimmick(BeatInfo info, GimmickType type)
{
BeatInfo = info;
GimmickType = type;
}
public Gimmick(Gimmick baseGimmick) : this(baseGimmick.BeatInfo, baseGimmick.GimmickType)
{
switch (GimmickType)
{
case GimmickType.BpmChange:
HiSpeed = baseGimmick.HiSpeed;
break;
case GimmickType.TimeSignatureChange:
TimeSig = new TimeSignature(baseGimmick.TimeSig);
break;
case GimmickType.HiSpeedChange:
HiSpeed = baseGimmick.HiSpeed;
break;
}
}
}
}
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor.Operations
{
internal class CompositeOperation : IOperation
{
public string Description { get; }
protected IEnumerable<IOperation> Operations { get; }
public CompositeOperation(string description, IEnumerable<IOperation> operations)
{
Description = description;
Operations = operations;
}
public void Redo()
{
foreach (var op in Operations)
{
op.Redo();
}
}
public void Undo()
{
foreach (var op in Operations)
{
op.Undo();
}
}
}
}
+111
View File
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor.Operations
{
internal abstract class GimmickOperation : IOperation
{
protected Gimmick Gimmick { get; }
protected Chart Chart { get; }
public abstract string Description { get; }
public GimmickOperation(Chart chart, Gimmick item)
{
Chart = chart;
Gimmick = item;
}
public abstract void Redo();
public abstract void Undo();
}
internal class InsertGimmick : GimmickOperation
{
public override string Description => "Insert gimmick";
public InsertGimmick(Chart chart, Gimmick item) : base(chart, item)
{ }
public override void Redo()
{
Chart.Gimmicks.Add(Gimmick);
}
public override void Undo()
{
Chart.Gimmicks.Remove(Gimmick);
}
}
internal class RemoveGimmick : GimmickOperation
{
public override string Description => "Remove gimmick";
public RemoveGimmick(Chart chart, Gimmick item) : base(chart, item)
{ }
public override void Redo()
{
Chart.Gimmicks.Remove(Gimmick);
}
public override void Undo()
{
Chart.Gimmicks.Add(Gimmick);
}
}
internal class EditGimmick : IOperation
{
public string Description => "Edit gimmick";
protected Gimmick Base { get; }
protected Gimmick OldGimmick { get; }
protected Gimmick NewGimmick { get; }
public EditGimmick(Gimmick baseGimmick, Gimmick newGimmick)
{
Base = baseGimmick;
OldGimmick = new Gimmick(baseGimmick);
NewGimmick = new Gimmick(newGimmick);
}
public void Redo()
{
Base.BeatInfo = new BeatInfo(NewGimmick.BeatInfo);
switch (Base.GimmickType)
{
case GimmickType.BpmChange:
Base.BPM = NewGimmick.BPM;
break;
case GimmickType.TimeSignatureChange:
Base.TimeSig = new TimeSignature(NewGimmick.TimeSig);
break;
case GimmickType.HiSpeedChange:
Base.HiSpeed = NewGimmick.HiSpeed;
break;
}
}
public void Undo()
{
Base.BeatInfo = new BeatInfo(OldGimmick.BeatInfo);
switch (Base.GimmickType)
{
case GimmickType.BpmChange:
Base.BPM = OldGimmick.BPM;
break;
case GimmickType.TimeSignatureChange:
Base.TimeSig = new TimeSignature(OldGimmick.TimeSig);
break;
case GimmickType.HiSpeedChange:
Base.HiSpeed = OldGimmick.HiSpeed;
break;
}
}
}
}
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor.Operations
{
internal interface IOperation
{
string Description { get; }
void Undo();
void Redo();
}
}
+203
View File
@@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor.Operations
{
internal abstract class NoteOperation : IOperation
{
public Note Note { get; }
protected Chart Chart { get; }
public abstract string Description { get; }
public NoteOperation(Chart chart, Note item)
{
Chart = chart;
Note = item;
// Force End of Chart note to be the correct position and size
if (Note.NoteType == NoteType.EndOfChart)
{
Note.Position = 0;
Note.Size = 60;
}
}
public abstract void Redo();
public abstract void Undo();
}
internal class InsertNote : NoteOperation
{
public override string Description => "Insert note";
public InsertNote(Chart chart, Note item) : base(chart, item)
{ }
public override void Redo()
{
Chart.Notes.Add(Note);
}
public override void Undo()
{
Chart.Notes.Remove(Note);
}
}
internal class RemoveNote : NoteOperation
{
public override string Description => "Remove note";
public RemoveNote(Chart chart, Note item) : base(chart, item)
{ }
public override void Redo()
{
Chart.Notes.Remove(Note);
}
public override void Undo()
{
Chart.Notes.Add(Note);
}
}
internal class EditNote : IOperation
{
public string Description => "Edit note";
protected Note Base { get; }
protected Note OldNote { get; }
protected Note NewNote { get; }
public EditNote(Note baseNote, Note newNote)
{
Base = baseNote;
OldNote = new Note(baseNote);
NewNote = new Note(newNote);
}
public void Redo()
{
Base.BeatInfo = new BeatInfo(NewNote.BeatInfo);
Base.Position = NewNote.Position;
Base.Size = NewNote.Size;
}
public void Undo()
{
Base.BeatInfo = new BeatInfo(OldNote.BeatInfo);
Base.Position = OldNote.Position;
Base.Size = OldNote.Size;
}
}
internal class InsertHoldNote : NoteOperation
{
public override string Description => "Insert hold note";
private Note prevNote;
public InsertHoldNote(Chart chart, Note item) : base(chart, item)
{
prevNote = item.PrevNote;
}
public override void Redo()
{
if (Note.PrevNote != null)
Note.PrevNote.NextNote = Note;
Chart.Notes.Add(Note);
}
public override void Undo()
{
if (Note.PrevNote != null)
Note.PrevNote.NextNote = null;
Chart.Notes.Remove(Note);
}
}
internal class RemoveHoldNote : NoteOperation
{
public override string Description => "Remove hold note";
private Note prevNote;
private NoteType prevNoteType;
private Note nextNote;
private NoteType nextNoteType;
public RemoveHoldNote(Chart chart, Note item) : base(chart, item)
{
prevNote = item.PrevNote;
if (prevNote != null)
prevNoteType = prevNote.NoteType;
nextNote = item.NextNote;
if (nextNote != null)
nextNoteType = nextNote.NoteType;
}
public override void Redo()
{
switch (Note.NoteType)
{
case NoteType.HoldStartNoBonus:
case NoteType.HoldStartBonusFlair:
if (nextNote != null)
{
nextNote.PrevNote = null;
if (nextNote.NoteType == NoteType.HoldJoint)
nextNote.NoteType = Note.NoteType;
}
break;
case NoteType.HoldJoint:
prevNote.NextNote = nextNote;
if (nextNote != null)
nextNote.PrevNote = prevNote;
break;
case NoteType.HoldEnd:
if (prevNote != null)
{
prevNote.NextNote = null;
prevNote.NoteType = NoteType.HoldEnd;
}
break;
default:
break;
}
Chart.Notes.Remove(Note);
}
public override void Undo()
{
switch (Note.NoteType)
{
case NoteType.HoldStartNoBonus:
case NoteType.HoldStartBonusFlair:
if (nextNote != null)
{
nextNote.PrevNote = Note;
nextNote.NoteType = nextNoteType;
}
break;
case NoteType.HoldJoint:
prevNote.NextNote = Note;
if (nextNote != null)
nextNote.PrevNote = Note;
break;
case NoteType.HoldEnd:
if (prevNote != null)
{
prevNote.NextNote = Note;
prevNote.NoteType = prevNoteType;
}
break;
default:
break;
}
Chart.Notes.Add(Note);
}
}
}
@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor.Operations
{
internal class OperationManager
{
public event EventHandler? OperationHistoryChanged;
public event EventHandler? ChangesCommitted;
protected Stack<IOperation> UndoStack { get; } = new Stack<IOperation>();
protected Stack<IOperation> RedoStack { get; } = new Stack<IOperation>();
private IOperation? LastCommittedOperation { get; set; } = null;
public IEnumerable<string> UndoOperationsDescription
{
get { return UndoStack.Select(p => p.Description); }
}
public IEnumerable<string> RedoOperationsDescription
{
get { return RedoStack.Select(p => p.Description); }
}
public bool CanUndo { get { return UndoStack.Count > 0; } }
public bool CanRedo { get { return RedoStack.Count > 0; } }
public void Push(IOperation op)
{
UndoStack.Push(op);
RedoStack.Clear();
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
}
public void InvokeAndPush(IOperation op)
{
op.Redo();
Push(op);
}
public IOperation Undo()
{
IOperation op = UndoStack.Pop();
op.Undo();
var type = op.GetType();
RedoStack.Push(op);
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
return op;
}
public IOperation Redo()
{
IOperation op = RedoStack.Pop();
op.Redo();
UndoStack.Push(op);
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
return op;
}
public void Clear()
{
UndoStack.Clear();
RedoStack.Clear();
LastCommittedOperation = null;
OperationHistoryChanged?.Invoke(this, EventArgs.Empty);
}
}
}
+17
View File
@@ -0,0 +1,17 @@
namespace BAKKA_Editor
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
}
+63
View File
@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace BAKKA_Editor.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BAKKA_Editor.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
@@ -117,26 +117,4 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="newToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>114, 22</value>
</data>
<data name="openToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>114, 22</value>
</data>
<data name="saveToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>114, 22</value>
</data>
<data name="saveAsToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>114, 22</value>
</data>
<data name="exitToolStripMenuItem.Size" type="System.Drawing.Size, System.Drawing">
<value>114, 22</value>
</data>
<data name="BonusBox.Location" type="System.Drawing.Point, System.Drawing">
<value>12, 48</value>
</data>
<data name="NoteTypesButtons.Size" type="System.Drawing.Size, System.Drawing">
<value>666, 74</value>
</data>
</root>
@@ -0,0 +1,7 @@
{
"profiles": {
"BAKKA-Editor": {
"commandName": "Project"
}
}
}
+46
View File
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor
{
internal class UserSettings
{
public ViewSettings ViewSettings { get; set; } = new();
public SaveSettings SaveSettings { get; set; } = new();
public HotkeySettings HotkeySettings { get; set; } = new();
}
internal class ViewSettings
{
public bool ShowCursor { get; set; } = true;
public bool ShowCursorDuringPlayback { get; set; } = false;
public bool HighlightViewedNote { get; set; } = true;
public bool SelectLastInsertedNote { get; set; } = true;
public bool ShowGimmicks { get; set; } = true;
public float HispeedSetting { get; set; } = 1.5f;
public int Volume { get; set; } = 100;
}
internal class SaveSettings
{
/// <summary>
/// How frequently autosave occurs (in minutes)
/// </summary>
public int AutoSaveInterval { get; set; } = 1;
}
internal class HotkeySettings
{
public int TouchHotkey { get; set; } = Convert.ToInt32(Keys.D1);
public int SlideLeftHotkey { get; set; } = Convert.ToInt32(Keys.D2);
public int SlideRightHotkey { get; set; } = Convert.ToInt32(Keys.D3);
public int SnapUpHotkey { get; set; } = Convert.ToInt32(Keys.D4);
public int SnapDownHotkey { get; set; } = Convert.ToInt32(Keys.D5);
public int ChainHotkey { get; set; } = Convert.ToInt32(Keys.D6);
public int HoldHotkey { get; set; } = Convert.ToInt32(Keys.D7);
public int PlayHotkey { get; set; } = Convert.ToInt32(Keys.Space);
}
}
+242
View File
@@ -0,0 +1,242 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BAKKA_Editor
{
internal static class Utils
{
internal static string? GetTag(string input, string tag)
{
if (input.Contains(tag))
{
return input.Substring(input.IndexOf(tag) + tag.Length);
}
return null;
}
internal static double DegToRad(double deg)
{
return deg * Math.PI / 180.0f;
}
internal static Color NoteTypeToColor(NoteType type)
{
switch (type)
{
case NoteType.TouchNoBonus:
case NoteType.TouchBonus:
case NoteType.TouchBonusFlair:
return Color.Fuchsia;
case NoteType.SnapRedNoBonus:
case NoteType.SnapRedBonusFlair:
return Color.Red;
case NoteType.SnapBlueNoBonus:
case NoteType.SnapBlueBonusFlair:
return Color.Aqua;
case NoteType.SlideOrangeNoBonus:
case NoteType.SlideOrangeBonus:
case NoteType.SlideOrangeBonusFlair:
return Color.FromArgb(255, 128, 0);
case NoteType.SlideGreenNoBonus:
case NoteType.SlideGreenBonus:
case NoteType.SlideGreenBonusFlair:
return Color.LimeGreen;
case NoteType.HoldStartNoBonus:
case NoteType.HoldJoint:
case NoteType.HoldEnd:
case NoteType.HoldStartBonusFlair:
return Color.Yellow;
case NoteType.Chain:
case NoteType.ChainBonusFlair:
return Color.FromArgb(204, 190, 45);
case NoteType.EndOfChart:
return Color.Black;
default:
return Color.Transparent;
}
}
internal static Color GimmickTypeToColor(GimmickType type)
{
switch (type)
{
case GimmickType.NoGimmick:
return Color.Transparent;
case GimmickType.BpmChange:
return Color.FromArgb(200, 0, 255, 255);
case GimmickType.TimeSignatureChange:
return Color.FromArgb(200, 160, 255, 160);
case GimmickType.HiSpeedChange:
return Color.FromArgb(200, 0, 255, 0);
case GimmickType.ReverseStart:
case GimmickType.ReverseMiddle:
case GimmickType.ReverseEnd:
return Color.FromArgb(200, 255, 255, 0);
case GimmickType.StopStart:
case GimmickType.StopEnd:
return Color.FromArgb(200, 255, 0, 0);
default:
return Color.Transparent;
}
}
internal static void InvokeIfRequired(this Control control, MethodInvoker action)
{
if (control.InvokeRequired)
{
control.Invoke(action);
}
else
{
action();
}
}
internal static Rectangle ToInt(this RectangleF rect)
{
return new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
}
internal static int FindGCD(int a, int b)
{
if (b == 0)
return a;
return FindGCD(b, a & b);
}
internal static string ToLabel(this NoteType type)
{
switch (type)
{
case NoteType.TouchNoBonus:
return "Touch";
case NoteType.TouchBonus:
return "Touch [Bonus]";
case NoteType.SnapRedNoBonus:
return "Snap (R)";
case NoteType.SnapBlueNoBonus:
return "Snap (B)";
case NoteType.SlideOrangeNoBonus:
return "Slide (O)";
case NoteType.SlideOrangeBonus:
return "Slide (O) [Bonus]";
case NoteType.SlideGreenNoBonus:
return "Slide (G)";
case NoteType.SlideGreenBonus:
return "Slide (G) [Bonus]";
case NoteType.HoldStartNoBonus:
return "Hold Start";
case NoteType.HoldJoint:
return "Hold Joint";
case NoteType.HoldEnd:
return "Hold End";
case NoteType.MaskAdd:
return "Mask Add";
case NoteType.MaskRemove:
return "Mask Remove";
case NoteType.EndOfChart:
return "End of Chart";
case NoteType.Chain:
return "Chain";
case NoteType.TouchBonusFlair:
return "Touch [R Note]";
case NoteType.SnapRedBonusFlair:
return "Snap (R) [R Note]";
case NoteType.SnapBlueBonusFlair:
return "Snap (B) [R Note]";
case NoteType.SlideOrangeBonusFlair:
return "Slide (O) [R Note]";
case NoteType.SlideGreenBonusFlair:
return "Slide (G) [R Note]";
case NoteType.HoldStartBonusFlair:
return "Hold Start [R Note]";
case NoteType.ChainBonusFlair:
return "Chain [R Note]";
default:
return "Undefined Note Type";
}
}
internal static string ToLabel(this GimmickType type)
{
switch (type)
{
case GimmickType.BpmChange:
return "BPM Change";
case GimmickType.TimeSignatureChange:
return "Time Signature Change";
case GimmickType.HiSpeedChange:
return "Hi-Speed Change";
case GimmickType.ReverseStart:
return "Reverse Start";
case GimmickType.ReverseMiddle:
return "Reverse Middle";
case GimmickType.ReverseEnd:
return "Reverse Stop";
case GimmickType.StopStart:
return "Stop Start";
case GimmickType.StopEnd:
return "Stop End";
default:
return "Undefined Gimmick";
}
}
internal static bool HasDecimal(double num)
{
return Math.Ceiling(num) == Math.Floor(num);
}
internal static Tuple<int, int> GetQuantization(int val, int min)
{
int numerator = val;
int denominator = 1920;
int gcd = GetGcd(numerator, denominator);
numerator /= gcd;
denominator /= gcd;
while (denominator < min)
{
numerator *= 2;
denominator *= 2;
}
return Tuple.Create(numerator, denominator);
}
private static int GetGcd(int a, int b)
{
if (b == 0)
return a;
return GetGcd(b, (int)a % (int)b);
}
internal static float GetDist(Point a, Point b)
{
return (float)Math.Sqrt(Math.Pow(a.X - b.X, 2) + Math.Pow(a.Y - b.Y, 2));
}
internal static string KeyIntToString(int key)
{
// Gets the key name from the keycode
string val = ((Keys)key).ToString();
// Converts digit keycode into number instead of key name
if (key >= 48 && key <= 57)
{
val = $"{key - 48}";
}
return val;
}
internal static void AppendHotkey(this Button button, int key)
{
button.Text += $" ({KeyIntToString(key)})";
}
}
}

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

+3 -2
View File
@@ -1,4 +1,5 @@
# BAKKA-Editor
# BAKKA Editor
A Marvelously simple and scuffed editor.
Find me on discord for any issues @Goatgarien or submit them on the issues tab
Find me on discord for any issues @Goatgarien in https://discord.gg/hDZtQ2tVcW
or submit them on the issues tab.