1
0
mirror of synced 2024-12-23 21:04:58 +01:00

Squashed commit of the following:

commit c99443a7d3
Author: Ashiro12138 <ashiro12138@gmail.com>
Date:   Fri Jul 26 01:29:15 2024 +1000

    Chore/add editor config (#656)

    * Create .editorconfig

    * format ENTIRE project

    * Remove unnecessary import or usings

    Sort Imports or usings
    Apply file header preferences

    * Fix build error by adding import
This commit is contained in:
0auBSQ 2024-07-26 01:07:31 +09:00
parent c47c9c9400
commit 88a15defc1
274 changed files with 62002 additions and 76846 deletions

189
.editorconfig Normal file
View File

@ -0,0 +1,189 @@
# editorconfig.org
# top-most EditorConfig file
root = true
# Default settings:
# A newline ending every file
# Use 4 spaces as indentation
[*]
insert_final_newline = true
indent_style = tab
indent_size = 4
trim_trailing_whitespace = true
[project.json]
indent_size = 2
# Generated code
[*{_AssemblyInfo.cs,.notsupported.cs}]
generated_code = true
# C# files
[*.cs]
# New line preferences
csharp_new_line_before_open_brace = none
csharp_new_line_before_else = false
csharp_new_line_before_catch = false
csharp_new_line_before_finally = false
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current
# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
# avoid this. unless absolutely necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Types: use keywords instead of BCL types, and permit var only when the type is clear
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = false:none
csharp_style_var_elsewhere = false:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# static fields should have s_ prefix
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
dotnet_naming_style.static_prefix_style.required_prefix = s_
dotnet_naming_style.static_prefix_style.capitalization = camel_case
# internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
# Code style defaults
csharp_using_directive_placement = outside_namespace:suggestion
dotnet_sort_system_directives_first = true
csharp_prefer_braces = true:silent
csharp_preserve_single_line_blocks = true:none
csharp_preserve_single_line_statements = false:none
csharp_prefer_static_local_function = true:suggestion
csharp_prefer_simple_using_statement = false:none
csharp_style_prefer_switch_expression = true:suggestion
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
csharp_prefer_simple_default_expression = true:suggestion
# Expression-bodied members
csharp_style_expression_bodied_methods = true:silent
csharp_style_expression_bodied_constructors = true:silent
csharp_style_expression_bodied_operators = true:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = true:silent
# Pattern matching
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
# Null checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Other features
csharp_style_prefer_index_operator = false:none
csharp_style_prefer_range_operator = false:none
csharp_style_pattern_local_over_anonymous_function = false:none
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = do_not_ignore
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# C++ Files
[*.{cpp,h,in}]
curly_bracket_next_line = true
indent_brace_style = Allman
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
indent_size = 2
[*.{csproj,vbproj,proj,nativeproj,locproj}]
charset = utf-8
# Xml build files
[*.builds]
indent_size = 2
# Xml files
[*.{xml,stylecop,resx,ruleset}]
indent_size = 2
# Xml config files
[*.{props,targets,config,nuspec}]
indent_size = 2
# YAML config files
[*.{yml,yaml}]
indent_size = 2
# Shell scripts
[*.sh]
end_of_line = lf
[*.{cmd,bat}]
end_of_line = crlf

View File

@ -1,22 +1,13 @@
using System; namespace FDK {
using System.Collections.Generic; public class CActivity {
using System.Text;
namespace FDK
{
public class CActivity
{
// プロパティ // プロパティ
public bool IsActivated { get; private set; } public bool IsActivated { get; private set; }
public bool IsDeActivated public bool IsDeActivated {
{ get {
get
{
return !this.IsActivated; return !this.IsActivated;
} }
set set {
{
this.IsActivated = !value; this.IsActivated = !value;
} }
} }
@ -32,8 +23,7 @@ namespace FDK
// コンストラクタ // コンストラクタ
public CActivity() public CActivity() {
{
this.IsDeActivated = true; this.IsDeActivated = true;
this.ChildActivities = new List<CActivity>(); this.ChildActivities = new List<CActivity>();
} }
@ -44,8 +34,7 @@ namespace FDK
#region [ override ] #region [ override ]
//----------------- //-----------------
public virtual void Activate() public virtual void Activate() {
{
// すでに活性化してるなら何もしない。 // すでに活性化してるなら何もしない。
if (this.IsActivated) if (this.IsActivated)
return; return;
@ -63,8 +52,7 @@ namespace FDK
// その他の初期化 // その他の初期化
this.IsFirstDraw = true; this.IsFirstDraw = true;
} }
public virtual void DeActivate() public virtual void DeActivate() {
{
// 活性化してないなら何もしない。 // 活性化してないなら何もしない。
if (this.IsDeActivated) if (this.IsDeActivated)
return; return;
@ -87,8 +75,7 @@ namespace FDK
/// <para>いつどのタイミングで呼び出されるかいつDirect3Dが再作成されるか分からないので、 /// <para>いつどのタイミングで呼び出されるかいつDirect3Dが再作成されるか分からないので、
/// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para> /// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para>
/// </summary> /// </summary>
public virtual void CreateManagedResource() public virtual void CreateManagedResource() {
{
// すべての 子Activity の Managed リソースを作成する。 // すべての 子Activity の Managed リソースを作成する。
foreach (CActivity activity in this.ChildActivities) foreach (CActivity activity in this.ChildActivities)
activity.CreateManagedResource(); activity.CreateManagedResource();
@ -101,8 +88,7 @@ namespace FDK
/// <para>いつどのタイミングで呼び出されるかいつDirect3Dが再作成またはリセットされるか分からないので、 /// <para>いつどのタイミングで呼び出されるかいつDirect3Dが再作成またはリセットされるか分からないので、
/// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para> /// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para>
/// </summary> /// </summary>
public virtual void CreateUnmanagedResource() public virtual void CreateUnmanagedResource() {
{
// すべての 子Activity の Unmanaged リソースを作成する。 // すべての 子Activity の Unmanaged リソースを作成する。
foreach (CActivity activity in this.ChildActivities) foreach (CActivity activity in this.ChildActivities)
activity.CreateUnmanagedResource(); activity.CreateUnmanagedResource();
@ -114,8 +100,7 @@ namespace FDK
/// <para>いつどのタイミングで呼び出されるかいつDirect3Dが解放またはリセットされるか分からないので、 /// <para>いつどのタイミングで呼び出されるかいつDirect3Dが解放またはリセットされるか分からないので、
/// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para> /// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para>
/// </summary> /// </summary>
public virtual void ReleaseUnmanagedResource() public virtual void ReleaseUnmanagedResource() {
{
// 活性化してないなら何もしない。 // 活性化してないなら何もしない。
if (this.IsDeActivated) if (this.IsDeActivated)
return; return;
@ -132,8 +117,7 @@ namespace FDK
/// <para>いつどのタイミングで呼び出されるかいつDirect3Dが解放されるか分からないので、 /// <para>いつどのタイミングで呼び出されるかいつDirect3Dが解放されるか分からないので、
/// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para> /// いつ何時呼び出されても問題無いようにコーディングしておくこと。</para>
/// </summary> /// </summary>
public virtual void ReleaseManagedResource() public virtual void ReleaseManagedResource() {
{
// 活性化してないなら何もしない。 // 活性化してないなら何もしない。
if (this.IsDeActivated) if (this.IsDeActivated)
return; return;
@ -148,8 +132,7 @@ namespace FDK
/// <para>このメソッドは BeginScene() の後に呼び出されるので、メソッド内でいきなり描画を行ってかまわない。</para> /// <para>このメソッドは BeginScene() の後に呼び出されるので、メソッド内でいきなり描画を行ってかまわない。</para>
/// </summary> /// </summary>
/// <returns>任意の整数。呼び出し元との整合性を合わせておくこと。</returns> /// <returns>任意の整数。呼び出し元との整合性を合わせておくこと。</returns>
public virtual int Draw() public virtual int Draw() {
{
// 活性化してないなら何もしない。 // 活性化してないなら何もしない。
if (this.IsDeActivated) if (this.IsDeActivated)
return 0; return 0;

View File

@ -1,11 +1,5 @@
using System; namespace FDK {
using System.Collections.Generic; public class CConversion {
using System.Text;
namespace FDK
{
public class CConversion
{
// プロパティ // プロパティ
public static readonly string str16進数文字 = "0123456789ABCDEFabcdef"; public static readonly string str16進数文字 = "0123456789ABCDEFabcdef";
@ -14,30 +8,24 @@ namespace FDK
// メソッド // メソッド
public static bool bONorOFF( char c ) public static bool bONorOFF(char c) {
{
return (c != '0'); return (c != '0');
} }
public static double DegreeToRadian( double angle ) public static double DegreeToRadian(double angle) {
{
return ((Math.PI * angle) / 180.0); return ((Math.PI * angle) / 180.0);
} }
public static double RadianToDegree( double angle ) public static double RadianToDegree(double angle) {
{
return (angle * 180.0 / Math.PI); return (angle * 180.0 / Math.PI);
} }
public static float DegreeToRadian( float angle ) public static float DegreeToRadian(float angle) {
{
return (float)DegreeToRadian((double)angle); return (float)DegreeToRadian((double)angle);
} }
public static float RadianToDegree( float angle ) public static float RadianToDegree(float angle) {
{
return (float)RadianToDegree((double)angle); return (float)RadianToDegree((double)angle);
} }
public static int n値を範囲内に丸めて返す( int value, int min, int max ) public static int n値を範囲内に丸めて返す(int value, int min, int max) {
{
if (value < min) if (value < min)
return min; return min;
@ -46,8 +34,7 @@ namespace FDK
return value; return value;
} }
public static int n値を文字列から取得して範囲内に丸めて返す( string text, int min, int max, int defaultValue ) public static int n値を文字列から取得して範囲内に丸めて返す(string text, int min, int max, int defaultValue) {
{
int num; int num;
if ((int.TryParse(text, out num) && (num >= min)) && (num <= max)) if ((int.TryParse(text, out num) && (num >= min)) && (num <= max))
return num; return num;
@ -55,8 +42,7 @@ namespace FDK
return defaultValue; return defaultValue;
} }
public static double db値を文字列から取得して範囲内に丸めて返す( string text, double min, double max, double defaultValue ) public static double db値を文字列から取得して範囲内に丸めて返す(string text, double min, double max, double defaultValue) {
{
double num; double num;
if ((double.TryParse(text, out num) && (num >= min)) && (num <= max)) if ((double.TryParse(text, out num) && (num >= min)) && (num <= max))
return num; return num;
@ -65,8 +51,7 @@ namespace FDK
} }
// #23568 2010.11.04 ikanick add // #23568 2010.11.04 ikanick add
public static int n値を文字列から取得して範囲内にちゃんと丸めて返す(string text, int min, int max, int defaultValue) public static int n値を文字列から取得して範囲内にちゃんと丸めて返す(string text, int min, int max, int defaultValue) {
{
// 1 と違って範囲外の場合ちゃんと丸めて返します。 // 1 と違って範囲外の場合ちゃんと丸めて返します。
int num; int num;
if (int.TryParse(text, out num)) { if (int.TryParse(text, out num)) {
@ -81,8 +66,7 @@ namespace FDK
return defaultValue; return defaultValue;
} }
// --------------------ここまで-------------------------/ // --------------------ここまで-------------------------/
public static int StringToInt( string text, int defaultValue ) public static int StringToInt(string text, int defaultValue) {
{
int num; int num;
if (!int.TryParse(text, out num)) if (!int.TryParse(text, out num))
num = defaultValue; num = defaultValue;
@ -90,8 +74,7 @@ namespace FDK
return num; return num;
} }
public static int n16進数2桁の文字列を数値に変換して返す( string strNum ) public static int n16進数2桁の文字列を数値に変換して返す(string strNum) {
{
if (strNum.Length < 2) if (strNum.Length < 2)
return -1; return -1;
@ -111,8 +94,7 @@ namespace FDK
return digit2 * 16 + digit1; return digit2 * 16 + digit1;
} }
public static int n36進数2桁の文字列を数値に変換して返す( string strNum ) public static int n36進数2桁の文字列を数値に変換して返す(string strNum) {
{
if (strNum.Length < 2) if (strNum.Length < 2)
return -1; return -1;
@ -132,10 +114,8 @@ namespace FDK
return digit2 * 36 + digit1; return digit2 * 36 + digit1;
} }
public static int n小節番号の文字列3桁を数値に変換して返す( string strNum ) public static int n小節番号の文字列3桁を数値に変換して返す(string strNum) {
{ if (strNum.Length >= 3) {
if( strNum.Length >= 3 )
{
int digit3 = str36進数文字.IndexOf(strNum[0]); int digit3 = str36進数文字.IndexOf(strNum[0]);
if (digit3 < 0) if (digit3 < 0)
return -1; return -1;
@ -154,8 +134,7 @@ namespace FDK
return -1; return -1;
} }
public static string str小節番号を文字列3桁に変換して返す( int num ) public static string str小節番号を文字列3桁に変換して返す(int num) {
{
if ((num < 0) || (num >= 3600)) // 3600 == Z99 + 1 if ((num < 0) || (num >= 3600)) // 3600 == Z99 + 1
return "000"; return "000";
@ -167,8 +146,7 @@ namespace FDK
char ch1 = str16進数文字[digit1]; char ch1 = str16進数文字[digit1];
return (ch3.ToString() + ch2.ToString() + ch1.ToString()); return (ch3.ToString() + ch2.ToString() + ch1.ToString());
} }
public static string str数値を16進数2桁に変換して返す( int num ) public static string str数値を16進数2桁に変換して返す(int num) {
{
if ((num < 0) || (num >= 0x100)) if ((num < 0) || (num >= 0x100))
return "00"; return "00";
@ -176,8 +154,7 @@ namespace FDK
char ch1 = str16進数文字[num % 0x10]; char ch1 = str16進数文字[num % 0x10];
return (ch2.ToString() + ch1.ToString()); return (ch2.ToString() + ch1.ToString());
} }
public static string str数値を36進数2桁に変換して返す( int num ) public static string str数値を36進数2桁に変換して返す(int num) {
{
if ((num < 0) || (num >= 36 * 36)) if ((num < 0) || (num >= 36 * 36))
return "00"; return "00";
@ -186,8 +163,7 @@ namespace FDK
return (ch2.ToString() + ch1.ToString()); return (ch2.ToString() + ch1.ToString());
} }
public static int[] StringToIntArray( string str ) public static int[] StringToIntArray(string str) {
{
//0,1,2 ...の形式で書かれたstringをint配列に変換する。 //0,1,2 ...の形式で書かれたstringをint配列に変換する。
//一応実装はしたものの、例外処理などはまだ完成していない。 //一応実装はしたものの、例外処理などはまだ完成していない。
//str = "0,1,2"; //str = "0,1,2";
@ -198,8 +174,7 @@ namespace FDK
List<int> listIntArray; List<int> listIntArray;
listIntArray = new List<int>(); listIntArray = new List<int>();
for( int n = 0; n < strArray.Length; n++ ) for (int n = 0; n < strArray.Length; n++) {
{
int n追加する数値 = Convert.ToInt32(strArray[n]); int n追加する数値 = Convert.ToInt32(strArray[n]);
listIntArray.Add(n追加する数値); listIntArray.Add(n追加する数値);
} }
@ -215,8 +190,7 @@ namespace FDK
/// </summary> /// </summary>
/// <param name="num"></param> /// <param name="num"></param>
/// <returns></returns> /// <returns></returns>
public static int nParsentTo255( double num ) public static int nParsentTo255(double num) {
{
return (int)(255.0 * num); return (int)(255.0 * num);
} }
@ -225,13 +199,11 @@ namespace FDK
/// </summary> /// </summary>
/// <param name="num"></param> /// <param name="num"></param>
/// <returns></returns> /// <returns></returns>
public static int n255ToParsent( int num ) public static int n255ToParsent(int num) {
{
return (int)(100.0 / num); return (int)(100.0 / num);
} }
public static Color4 n255ToColor4( int nR, int nG, int nB ) public static Color4 n255ToColor4(int nR, int nG, int nB) {
{
float fR = n255ToParsent(nR); float fR = n255ToParsent(nR);
float fG = n255ToParsent(nG); float fG = n255ToParsent(nG);
float fB = n255ToParsent(nB); float fB = n255ToParsent(nB);
@ -239,16 +211,13 @@ namespace FDK
return new Color4(fR, fG, fB, 1f); return new Color4(fR, fG, fB, 1f);
} }
public static Color4 ColorToColor4(System.Drawing.Color col) public static Color4 ColorToColor4(System.Drawing.Color col) {
{
return new Color4(col.R / 255f, col.G / 255f, col.B / 255f, col.A / 255f); return new Color4(col.R / 255f, col.G / 255f, col.B / 255f, col.A / 255f);
} }
public static int[] SeparateDigits(int num) public static int[] SeparateDigits(int num) {
{
int[] digits = new int[num.ToString().Length]; int[] digits = new int[num.ToString().Length];
for (int i = 0; i < digits.Length; i++) for (int i = 0; i < digits.Length; i++) {
{
digits[i] = num % 10; digits[i] = num % 10;
num /= 10; num /= 10;
} }
@ -259,8 +228,7 @@ namespace FDK
//----------------- //-----------------
// private コンストラクタでインスタンス生成を禁止する。 // private コンストラクタでインスタンス生成を禁止する。
private CConversion() private CConversion() {
{
} }
//----------------- //-----------------
#endregion #endregion

View File

@ -1,9 +1,4 @@
using System; namespace FDK {
using System.Collections.Generic;
using System.Text;
namespace FDK
{
/// <summary> /// <summary>
/// 一定間隔で単純増加する整数(カウント値)を扱う。 /// 一定間隔で単純増加する整数(カウント値)を扱う。
/// </summary> /// </summary>
@ -18,70 +13,56 @@ namespace FDK
/// double値を使う場合、t進行db、t進行LoopDbを使うこと。 /// double値を使う場合、t進行db、t進行LoopDbを使うこと。
/// また、double版では間隔の値はミリ秒単位ではなく、通常の秒単位になります。 /// また、double版では間隔の値はミリ秒単位ではなく、通常の秒単位になります。
/// </remarks> /// </remarks>
public class CCounter public class CCounter {
{ public bool IsStarted {
public bool IsStarted
{
get; get;
set; set;
} }
// 値プロパティ // 値プロパティ
public double BeginValue public double BeginValue {
{
get; get;
private set; private set;
} }
public double EndValue public double EndValue {
{
get; get;
set; set;
} }
public int CurrentValue public int CurrentValue {
{
get; get;
set; set;
} }
public double _Interval public double _Interval {
{ get {
get
{
return this.Interval; return this.Interval;
} }
set set {
{
this.Interval = value >= 0 ? value : value * -1; this.Interval = value >= 0 ? value : value * -1;
} }
} }
public double NowTime public double NowTime {
{
get; get;
set; set;
} }
// 状態プロパティ // 状態プロパティ
public bool IsTicked public bool IsTicked {
{
get { return (this.NowTime != -1); } get { return (this.NowTime != -1); }
} }
public bool IsStoped public bool IsStoped {
{
get { return !this.IsTicked; } get { return !this.IsTicked; }
} }
public bool IsEnded public bool IsEnded {
{
get { return (this.CurrentValue >= this.EndValue); } get { return (this.CurrentValue >= this.EndValue); }
} }
public bool IsUnEnded public bool IsUnEnded {
{
get { return !this.IsEnded; } get { return !this.IsEnded; }
} }
// コンストラクタ // コンストラクタ
public CCounter() public CCounter() {
{
this.NormalTimer = null; this.NormalTimer = null;
this.BeginValue = 0; this.BeginValue = 0;
this.EndValue = 0; this.EndValue = 0;
@ -92,15 +73,13 @@ namespace FDK
/// <summary>生成と同時に開始する。</summary> /// <summary>生成と同時に開始する。</summary>
public CCounter(double begin, double end, double interval, CTimer timer) public CCounter(double begin, double end, double interval, CTimer timer)
: this() : this() {
{
this.Start(begin, end, interval, timer); this.Start(begin, end, interval, timer);
} }
/// <summary>生成と同時に開始する。(double版)</summary> /// <summary>生成と同時に開始する。(double版)</summary>
public CCounter(double begin, double end, double interval, CSoundTimer timer) public CCounter(double begin, double end, double interval, CSoundTimer timer)
: this() : this() {
{
this.Start(begin, end, interval * 1000.0f, timer); this.Start(begin, end, interval * 1000.0f, timer);
} }
@ -114,8 +93,7 @@ namespace FDK
/// <param name="end">最後のカウント値。</param> /// <param name="end">最後のカウント値。</param>
/// <param name="interval">カウント値を1増加させるのにかける時間(ミリ秒単位)。</param> /// <param name="interval">カウント値を1増加させるのにかける時間(ミリ秒単位)。</param>
/// <param name="timer">カウントに使用するタイマ。</param> /// <param name="timer">カウントに使用するタイマ。</param>
public void Start(double begin, double end, double interval, CTimer timer) public void Start(double begin, double end, double interval, CTimer timer) {
{
this.BeginValue = begin; this.BeginValue = begin;
this.EndValue = end; this.EndValue = end;
this._Interval = interval; this._Interval = interval;
@ -132,8 +110,7 @@ namespace FDK
/// <param name="end">最後のカウント値。</param> /// <param name="end">最後のカウント値。</param>
/// <param name="interval">カウント値を1増加させるのにかける時間(秒単位)。</param> /// <param name="interval">カウント値を1増加させるのにかける時間(秒単位)。</param>
/// <param name="timer">カウントに使用するタイマ。</param> /// <param name="timer">カウントに使用するタイマ。</param>
public void Start(double begin, double end, double interval, CSoundTimer timer) public void Start(double begin, double end, double interval, CSoundTimer timer) {
{
this.BeginValue = begin; this.BeginValue = begin;
this.EndValue = end; this.EndValue = end;
this._Interval = interval; this._Interval = interval;
@ -147,16 +124,13 @@ namespace FDK
/// 前回の t進行() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。 /// 前回の t進行() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。
/// カウント値が終了値に達している場合は、それ以上増加しない(終了値を維持する)。 /// カウント値が終了値に達している場合は、それ以上増加しない(終了値を維持する)。
/// </summary> /// </summary>
public void Tick() public void Tick() {
{ if ((this.NormalTimer != null) && (this.NowTime != CTimer.UnusedNum)) {
if ((this.NormalTimer != null) && (this.NowTime != CTimer.UnusedNum))
{
long num = this.NormalTimer.NowTime; long num = this.NormalTimer.NowTime;
if (num < this.NowTime) if (num < this.NowTime)
this.NowTime = num; this.NowTime = num;
while ((num - this.NowTime) >= this.Interval) while ((num - this.NowTime) >= this.Interval) {
{
if (++this.CurrentValue > this.EndValue) if (++this.CurrentValue > this.EndValue)
this.CurrentValue = (int)this.EndValue; this.CurrentValue = (int)this.EndValue;
@ -169,16 +143,13 @@ namespace FDK
/// 前回の t進行() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。 /// 前回の t進行() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。
/// カウント値が終了値に達している場合は、それ以上増加しない(終了値を維持する)。 /// カウント値が終了値に達している場合は、それ以上増加しない(終了値を維持する)。
/// </summary> /// </summary>
public void TickDB() public void TickDB() {
{ if ((this.TimerDB != null) && (this.NowTime != CSoundTimer.UnusedNum)) {
if ((this.TimerDB != null) && (this.NowTime != CSoundTimer.UnusedNum))
{
double num = this.TimerDB.NowTime; double num = this.TimerDB.NowTime;
if (num < this.NowTime) if (num < this.NowTime)
this.NowTime = num; this.NowTime = num;
while ((num - this.NowTime) >= this.Interval) while ((num - this.NowTime) >= this.Interval) {
{
if (++this.CurrentValue > this.EndValue) if (++this.CurrentValue > this.EndValue)
this.CurrentValue = (int)this.EndValue; this.CurrentValue = (int)this.EndValue;
@ -191,16 +162,13 @@ namespace FDK
/// 前回の t進行Loop() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。 /// 前回の t進行Loop() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。
/// カウント値が終了値に達している場合は、次の増加タイミングで開始値に戻る(値がループする)。 /// カウント値が終了値に達している場合は、次の増加タイミングで開始値に戻る(値がループする)。
/// </summary> /// </summary>
public void TickLoop() public void TickLoop() {
{ if ((this.NormalTimer != null) && (this.NowTime != CTimer.UnusedNum)) {
if ((this.NormalTimer != null) && (this.NowTime != CTimer.UnusedNum))
{
long num = this.NormalTimer.NowTime; long num = this.NormalTimer.NowTime;
if (num < this.NowTime) if (num < this.NowTime)
this.NowTime = num; this.NowTime = num;
while ((num - this.NowTime) >= this.Interval) while ((num - this.NowTime) >= this.Interval) {
{
if (++this.CurrentValue > this.EndValue) if (++this.CurrentValue > this.EndValue)
this.CurrentValue = (int)this.BeginValue; this.CurrentValue = (int)this.BeginValue;
@ -213,16 +181,13 @@ namespace FDK
/// 前回の t進行Loop() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。 /// 前回の t進行Loop() の呼び出しからの経過時間をもとに、必要なだけカウント値を増加させる。
/// カウント値が終了値に達している場合は、次の増加タイミングで開始値に戻る(値がループする)。 /// カウント値が終了値に達している場合は、次の増加タイミングで開始値に戻る(値がループする)。
/// </summary> /// </summary>
public void TickLoopDB() public void TickLoopDB() {
{ if ((this.TimerDB != null) && (this.NowTime != CSoundTimer.UnusedNum)) {
if ((this.TimerDB != null) && (this.NowTime != CSoundTimer.UnusedNum))
{
double num = this.TimerDB.NowTime; double num = this.TimerDB.NowTime;
if (num < this.NowTime) if (num < this.NowTime)
this.NowTime = num; this.NowTime = num;
while ((num - this.NowTime) >= this.Interval) while ((num - this.NowTime) >= this.Interval) {
{
if (++this.CurrentValue > this.EndValue) if (++this.CurrentValue > this.EndValue)
this.CurrentValue = (int)this.BeginValue; this.CurrentValue = (int)this.BeginValue;
@ -235,13 +200,11 @@ namespace FDK
/// カウントを停止する。 /// カウントを停止する。
/// これ以降に t進行() や t進行Loop() を呼び出しても何も処理されない。 /// これ以降に t進行() や t進行Loop() を呼び出しても何も処理されない。
/// </summary> /// </summary>
public void Stop() public void Stop() {
{
this.NowTime = CTimer.UnusedNum; this.NowTime = CTimer.UnusedNum;
} }
public void ChangeInterval(double Value) public void ChangeInterval(double Value) {
{
this._Interval = Value; this._Interval = Value;
} }
@ -257,16 +220,13 @@ namespace FDK
/// </summary> /// </summary>
/// <param name="pressFlag">キーが押下されている場合は true。</param> /// <param name="pressFlag">キーが押下されている場合は true。</param>
/// <param name="keyProcess">キーが押下されている場合に実行する処理。</param> /// <param name="keyProcess">キーが押下されている場合に実行する処理。</param>
public void KeyIntervalFunc(bool pressFlag, KeyProcess keyProcess) public void KeyIntervalFunc(bool pressFlag, KeyProcess keyProcess) {
{
const int first = 0; const int first = 0;
const int second = 1; const int second = 1;
const int later = 2; const int later = 2;
if (pressFlag) if (pressFlag) {
{ switch (this.CurrentValue) {
switch (this.CurrentValue)
{
case first: case first:
keyProcess(); keyProcess();
@ -276,8 +236,7 @@ namespace FDK
case second: case second:
if ((this.NormalTimer.NowTime - this.NowTime) > 200) if ((this.NormalTimer.NowTime - this.NowTime) > 200) {
{
keyProcess(); keyProcess();
this.NowTime = this.NormalTimer.NowTime; this.NowTime = this.NormalTimer.NowTime;
this.CurrentValue = later; this.CurrentValue = later;
@ -286,16 +245,13 @@ namespace FDK
case later: case later:
if ((this.NormalTimer.NowTime - this.NowTime) > 30) if ((this.NormalTimer.NowTime - this.NowTime) > 30) {
{
keyProcess(); keyProcess();
this.NowTime = this.NormalTimer.NowTime; this.NowTime = this.NormalTimer.NowTime;
} }
return; return;
} }
} } else {
else
{
this.CurrentValue = first; this.CurrentValue = first;
} }
} }

View File

@ -1,25 +1,16 @@
using System; namespace FDK {
using System.Collections.Generic; public class CFPS {
using System.Text;
namespace FDK
{
public class CFPS
{
// プロパティ // プロパティ
public int NowFPS public int NowFPS {
{
get; get;
private set; private set;
} }
public double DeltaTime public double DeltaTime {
{
get; get;
private set; private set;
} }
public bool ChangedFPS public bool ChangedFPS {
{
get; get;
private set; private set;
} }
@ -27,8 +18,7 @@ namespace FDK
// コンストラクタ // コンストラクタ
public CFPS() public CFPS() {
{
this.NowFPS = 0; this.NowFPS = 0;
this.DeltaTime = 0; this.DeltaTime = 0;
this.FPSTimer = new CTimer(CTimer.TimerType.MultiMedia); this.FPSTimer = new CTimer(CTimer.TimerType.MultiMedia);
@ -40,16 +30,14 @@ namespace FDK
// メソッド // メソッド
public void Update() public void Update() {
{
this.FPSTimer.Update(); this.FPSTimer.Update();
this.ChangedFPS = false; this.ChangedFPS = false;
const long INTERVAL = 1000; const long INTERVAL = 1000;
this.DeltaTime = (this.FPSTimer.NowTime - this.PrevFrameTime) / 1000.0; this.DeltaTime = (this.FPSTimer.NowTime - this.PrevFrameTime) / 1000.0;
PrevFrameTime = this.FPSTimer.NowTime; PrevFrameTime = this.FPSTimer.NowTime;
while ( ( this.FPSTimer.NowTime - this.BeginTime ) >= INTERVAL ) while ((this.FPSTimer.NowTime - this.BeginTime) >= INTERVAL) {
{
this.NowFPS = this.CoreFPS; this.NowFPS = this.CoreFPS;
this.CoreFPS = 0; this.CoreFPS = 0;
this.ChangedFPS = true; this.ChangedFPS = true;

View File

@ -1,31 +1,22 @@
using System; using System.Text;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// 汎用的な .iniファイルを扱う。 /// 汎用的な .iniファイルを扱う。
/// </summary> /// </summary>
public class CIniFile public class CIniFile {
{
// プロパティ // プロパティ
public string FileName public string FileName {
{
get; get;
private set; private set;
} }
public List<CSection> Sections public List<CSection> Sections {
{
get; get;
set; set;
} }
public class CSection public class CSection {
{
public string SectionName = ""; public string SectionName = "";
public List<KeyValuePair<string, string>> Parameters = new List<KeyValuePair<string, string>>(); public List<KeyValuePair<string, string>> Parameters = new List<KeyValuePair<string, string>>();
} }
@ -33,39 +24,33 @@ namespace FDK
// コンストラクタ // コンストラクタ
public CIniFile() public CIniFile() {
{
this.FileName = ""; this.FileName = "";
this.Sections = new List<CSection>(); this.Sections = new List<CSection>();
} }
public CIniFile(string fileName) public CIniFile(string fileName)
:this() : this() {
{
this.tRead(fileName); this.tRead(fileName);
} }
// メソッド // メソッド
public void tRead( string fileName ) public void tRead(string fileName) {
{
this.FileName = fileName; this.FileName = fileName;
StreamReader sr = null; StreamReader sr = null;
CSection section = null; CSection section = null;
try try {
{
sr = new StreamReader(this.FileName, Encoding.GetEncoding("Shift_JIS")); // ファイルが存在しない場合は例外発生。 sr = new StreamReader(this.FileName, Encoding.GetEncoding("Shift_JIS")); // ファイルが存在しない場合は例外発生。
string line; string line;
while( ( line = sr.ReadLine() ) != null ) while ((line = sr.ReadLine()) != null) {
{
line = line.Replace('\t', ' ').TrimStart(new char[] { '\t', ' ' }); line = line.Replace('\t', ' ').TrimStart(new char[] { '\t', ' ' });
if (string.IsNullOrEmpty(line) || line[0] == ';') // ';'以降はコメントとして無視 if (string.IsNullOrEmpty(line) || line[0] == ';') // ';'以降はコメントとして無視
continue; continue;
if( line[ 0 ] == '[' ) if (line[0] == '[') {
{
#region [ ] #region [ ]
//----------------------------- //-----------------------------
var builder = new StringBuilder(32); var builder = new StringBuilder(32);
@ -98,35 +83,27 @@ namespace FDK
if (section != null) if (section != null)
this.Sections.Add(section); this.Sections.Add(section);
} } finally {
finally
{
if (sr != null) if (sr != null)
sr.Close(); sr.Close();
} }
} }
public void tWrite( string fileName ) public void tWrite(string fileName) {
{
this.FileName = fileName; this.FileName = fileName;
this.tWrite(); this.tWrite();
} }
public void tWrite() public void tWrite() {
{
StreamWriter sw = null; StreamWriter sw = null;
try try {
{
sw = new StreamWriter(this.FileName, false, Encoding.GetEncoding("Shift_JIS")); // オープン失敗の場合は例外発生。 sw = new StreamWriter(this.FileName, false, Encoding.GetEncoding("Shift_JIS")); // オープン失敗の場合は例外発生。
foreach( CSection section in this.Sections ) foreach (CSection section in this.Sections) {
{
sw.WriteLine("[{0}]", section.SectionName); sw.WriteLine("[{0}]", section.SectionName);
foreach (KeyValuePair<string, string> kvp in section.Parameters) foreach (KeyValuePair<string, string> kvp in section.Parameters)
sw.WriteLine("{0}={1}", kvp.Key, kvp.Value); sw.WriteLine("{0}={1}", kvp.Key, kvp.Value);
} }
} } finally {
finally
{
if (sw != null) if (sw != null)
sw.Close(); sw.Close();
} }

View File

@ -1,18 +1,11 @@
using System; namespace FDK {
using System.Collections.Generic;
using System.Text;
namespace FDK
{
/// <summary> /// <summary>
/// <para>一定の間隔で処理を行うテンプレートパターンの定義。</para> /// <para>一定の間隔で処理を行うテンプレートパターンの定義。</para>
/// <para>たとえば、t進行() で 5ms ごとに行う処理を前回のt進行()の呼び出しから 15ms 後に呼び出した場合は、処理が 3回 実行される。</para> /// <para>たとえば、t進行() で 5ms ごとに行う処理を前回のt進行()の呼び出しから 15ms 後に呼び出した場合は、処理が 3回 実行される。</para>
/// </summary> /// </summary>
public class CIntervalProcessing : IDisposable public class CIntervalProcessing : IDisposable {
{
public delegate void dgProc(); public delegate void dgProc();
public void Tick( long interval, dgProc proc ) public void Tick(long interval, dgProc proc) {
{
// タイマ更新 // タイマ更新
if (this.timer == null) if (this.timer == null)
@ -34,8 +27,7 @@ namespace FDK
// 時間内の処理を実行。 // 時間内の処理を実行。
while( ( this.timer.NowTimeMs - this.PrevTime ) >= interval ) while ((this.timer.NowTimeMs - this.PrevTime) >= interval) {
{
proc(); proc();
this.PrevTime += interval; this.PrevTime += interval;
@ -44,8 +36,7 @@ namespace FDK
#region [ IDisposable ] #region [ IDisposable ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{
timer.Dispose(); timer.Dispose();
} }
//----------------- //-----------------

View File

@ -1,25 +1,17 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.IO;
using System.Diagnostics;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ public class CJudgeTextEncoding {
public class CJudgeTextEncoding
{
/// <summary> /// <summary>
/// Hnc8様のReadJEncを使用して文字コードの判別をする。 /// Hnc8様のReadJEncを使用して文字コードの判別をする。
/// </summary> /// </summary>
public static Encoding JudgeFileEncoding(string path) public static Encoding JudgeFileEncoding(string path) {
{
if (!File.Exists(path)) return null; if (!File.Exists(path)) return null;
Encoding enc; Encoding enc;
FileInfo file = new FileInfo(path); FileInfo file = new FileInfo(path);
using (Hnx8.ReadJEnc.FileReader reader = new Hnx8.ReadJEnc.FileReader(file)) using (Hnx8.ReadJEnc.FileReader reader = new Hnx8.ReadJEnc.FileReader(file)) {
{
// 判別読み出し実行。判別結果はReadメソッドの戻り値で把握できます // 判別読み出し実行。判別結果はReadメソッドの戻り値で把握できます
Hnx8.ReadJEnc.CharCode c = reader.Read(file); Hnx8.ReadJEnc.CharCode c = reader.Read(file);
// 戻り値のNameプロパティから文字コード名を取得できます // 戻り値のNameプロパティから文字コード名を取得できます
@ -30,8 +22,7 @@ namespace TJAPlayer3
} }
Debug.Print(path + " Encoding=" + enc.CodePage); Debug.Print(path + " Encoding=" + enc.CodePage);
if (enc == null) if (enc == null) {
{
enc = Encoding.GetEncoding(932); enc = Encoding.GetEncoding(932);
} }
return enc; return enc;
@ -42,14 +33,12 @@ namespace TJAPlayer3
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
/// <returns></returns> /// <returns></returns>
public static string ReadTextFile(string path) public static string ReadTextFile(string path) {
{
if (!File.Exists(path)) return null; if (!File.Exists(path)) return null;
string str = null; string str = null;
FileInfo file = new FileInfo(path); FileInfo file = new FileInfo(path);
using (Hnx8.ReadJEnc.FileReader reader = new Hnx8.ReadJEnc.FileReader(file)) using (Hnx8.ReadJEnc.FileReader reader = new Hnx8.ReadJEnc.FileReader(file)) {
{
reader.Read(file); reader.Read(file);
str = reader.Text; str = reader.Text;
} }
@ -66,8 +55,7 @@ namespace TJAPlayer3
/// </summary> /// </summary>
/// <param name="str"></param> /// <param name="str"></param>
/// <returns></returns> /// <returns></returns>
public static string JudgeNewLine(string str) public static string JudgeNewLine(string str) {
{
if (str.Contains("\r\n")) if (str.Contains("\r\n"))
return ("\r\n"); return ("\r\n");

View File

@ -1,31 +1,19 @@
using System; namespace FDK {
using System.Collections.Generic; public class CTimer : CTimerBase {
using System.Text; public enum TimerType {
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace FDK
{
public class CTimer : CTimerBase
{
public enum TimerType
{
Unknown = -1, Unknown = -1,
PerformanceCounter = 0, PerformanceCounter = 0,
MultiMedia = 1, MultiMedia = 1,
GetTickCount = 2, GetTickCount = 2,
} }
public TimerType CurrentTimerType public TimerType CurrentTimerType {
{
get; get;
protected set; protected set;
} }
public override long SystemTimeMs public override long SystemTimeMs {
{ get {
get
{
/* /*
switch( this.eタイマ種別 ) switch( this.eタイマ種別 )
{ {
@ -53,8 +41,7 @@ namespace FDK
} }
public CTimer(TimerType timerType) public CTimer(TimerType timerType)
:base() : base() {
{
this.CurrentTimerType = timerType; this.CurrentTimerType = timerType;
/* /*
@ -87,8 +74,7 @@ namespace FDK
ReferenceCount[(int)this.CurrentTimerType]++; ReferenceCount[(int)this.CurrentTimerType]++;
} }
public override void Dispose() public override void Dispose() {
{
if (this.CurrentTimerType == TimerType.Unknown) if (this.CurrentTimerType == TimerType.Unknown)
return; return;
@ -96,8 +82,7 @@ namespace FDK
ReferenceCount[type] = Math.Max(ReferenceCount[type] - 1, 0); ReferenceCount[type] = Math.Max(ReferenceCount[type] - 1, 0);
if( ReferenceCount[ type ] == 0 ) if (ReferenceCount[type] == 0) {
{
/* /*
if( this.eタイマ種別 == E種別.MultiMedia ) if( this.eタイマ種別 == E種別.MultiMedia )
timeEndPeriod( this.timeCaps.wPeriodMin ); timeEndPeriod( this.timeCaps.wPeriodMin );
@ -113,8 +98,7 @@ namespace FDK
protected static int[] ReferenceCount = new int[3]; protected static int[] ReferenceCount = new int[3];
//protected TimeCaps timeCaps; //protected TimeCaps timeCaps;
protected bool GetSetTickCount() protected bool GetSetTickCount() {
{
this.CurrentTimerType = TimerType.GetTickCount; this.CurrentTimerType = TimerType.GetTickCount;
return true; return true;
} }

View File

@ -1,164 +1,129 @@
using System; namespace FDK {
using System.Collections.Generic;
using System.Text;
namespace FDK
{
/// <summary> /// <summary>
/// <para>タイマの抽象クラス。</para> /// <para>タイマの抽象クラス。</para>
/// <para>このクラスを継承し、override したクラスを作成することで、任意のクロックを持つタイマを作成できる。</para> /// <para>このクラスを継承し、override したクラスを作成することで、任意のクロックを持つタイマを作成できる。</para>
/// </summary> /// </summary>
public abstract class CTimerBase : IDisposable public abstract class CTimerBase : IDisposable {
{
public const long UnusedNum = -1; public const long UnusedNum = -1;
// この2つを override する。 // この2つを override する。
public abstract long SystemTimeMs public abstract long SystemTimeMs {
{
get; get;
} }
public double SystemTimeMs_Double public double SystemTimeMs_Double {
{
get; get;
set; set;
} }
public abstract void Dispose(); public abstract void Dispose();
#region [ DTXMania用にmsのつかない宣言を追加 ] #region [ DTXMania用にmsのつかない宣言を追加 ]
public long SystemTime public long SystemTime {
{
get { return SystemTimeMs; } get { return SystemTimeMs; }
} }
public long NowTime public long NowTime {
{
get { return NowTimeMs; } get { return NowTimeMs; }
set { NowTimeMs = value; } set { NowTimeMs = value; }
} }
public long PrevResetTime public long PrevResetTime {
{
get { return PrevResetTimeMs; } get { return PrevResetTimeMs; }
} }
//double //double
public double SystemTime_Double public double SystemTime_Double {
{
get { return SystemTimeMs_Double; } get { return SystemTimeMs_Double; }
} }
public double NowTime_Double public double NowTime_Double {
{
get { return NowTimeMs_Double; } get { return NowTimeMs_Double; }
set { NowTimeMs_Double = value; } set { NowTimeMs_Double = value; }
} }
public double PrevResetTime_Double public double PrevResetTime_Double {
{
get { return PrevResetTimeMs_Double; } get { return PrevResetTimeMs_Double; }
} }
#endregion #endregion
public long NowTimeMs public long NowTimeMs {
{ get {
get
{
if (this.StopCount > 0) if (this.StopCount > 0)
return (this.PauseSystemTimeMs - this.PrevResetTimeMs); return (this.PauseSystemTimeMs - this.PrevResetTimeMs);
return (this.UpdateSystemTime - this.PrevResetTimeMs); return (this.UpdateSystemTime - this.PrevResetTimeMs);
} }
set set {
{
if (this.StopCount > 0) if (this.StopCount > 0)
this.PrevResetTimeMs = this.PauseSystemTimeMs - value; this.PrevResetTimeMs = this.PauseSystemTimeMs - value;
else else
this.PrevResetTimeMs = this.UpdateSystemTime - value; this.PrevResetTimeMs = this.UpdateSystemTime - value;
} }
} }
public long RealNowTimeMs public long RealNowTimeMs {
{ get {
get
{
if (this.StopCount > 0) if (this.StopCount > 0)
return (this.PauseSystemTimeMs - this.PrevResetTimeMs); return (this.PauseSystemTimeMs - this.PrevResetTimeMs);
return (this.SystemTimeMs - this.PrevResetTimeMs); return (this.SystemTimeMs - this.PrevResetTimeMs);
} }
} }
public long PrevResetTimeMs public long PrevResetTimeMs {
{
get; get;
protected set; protected set;
} }
public double NowTimeMs_Double public double NowTimeMs_Double {
{ get {
get
{
if (this.StopCount > 0) if (this.StopCount > 0)
return (this.PauseSystemTimeMs_Double - this.PrevResetTimeMs_Double); return (this.PauseSystemTimeMs_Double - this.PrevResetTimeMs_Double);
return (this.UpdateSystemTime_Double - this.PrevResetTimeMs_Double); return (this.UpdateSystemTime_Double - this.PrevResetTimeMs_Double);
} }
set set {
{
if (this.StopCount > 0) if (this.StopCount > 0)
this.PrevResetTimeMs_Double = this.PauseSystemTimeMs_Double - value; this.PrevResetTimeMs_Double = this.PauseSystemTimeMs_Double - value;
else else
this.PrevResetTimeMs_Double = this.UpdateSystemTime_Double - value; this.PrevResetTimeMs_Double = this.UpdateSystemTime_Double - value;
} }
} }
public double RealNowTimeMs_Double public double RealNowTimeMs_Double {
{ get {
get
{
if (this.StopCount > 0) if (this.StopCount > 0)
return (this.PauseSystemTimeMs_Double - this.PrevResetTimeMs_Double); return (this.PauseSystemTimeMs_Double - this.PrevResetTimeMs_Double);
return (this.SystemTimeMs_Double - this.PrevResetTimeMs_Double); return (this.SystemTimeMs_Double - this.PrevResetTimeMs_Double);
} }
} }
public double PrevResetTimeMs_Double public double PrevResetTimeMs_Double {
{
get; get;
protected set; protected set;
} }
public bool IsUnStoped public bool IsUnStoped {
{ get {
get
{
return (this.StopCount == 0); return (this.StopCount == 0);
} }
} }
public void Reset() public void Reset() {
{
this.Update(); this.Update();
this.PrevResetTimeMs = this.UpdateSystemTime; this.PrevResetTimeMs = this.UpdateSystemTime;
this.PauseSystemTimeMs = this.UpdateSystemTime; this.PauseSystemTimeMs = this.UpdateSystemTime;
this.StopCount = 0; this.StopCount = 0;
} }
public void Pause() public void Pause() {
{ if (this.StopCount == 0) {
if( this.StopCount == 0 )
{
this.PauseSystemTimeMs = this.UpdateSystemTime; this.PauseSystemTimeMs = this.UpdateSystemTime;
this.PauseSystemTimeMs_Double = this.UpdateSystemTime_Double; this.PauseSystemTimeMs_Double = this.UpdateSystemTime_Double;
} }
this.StopCount++; this.StopCount++;
} }
public void Update() public void Update() {
{
this.UpdateSystemTime = this.SystemTimeMs; this.UpdateSystemTime = this.SystemTimeMs;
this.UpdateSystemTime_Double = this.SystemTimeMs_Double; this.UpdateSystemTime_Double = this.SystemTimeMs_Double;
} }
public void Resume() public void Resume() {
{ if (this.StopCount > 0) {
if( this.StopCount > 0 )
{
this.StopCount--; this.StopCount--;
if( this.StopCount == 0 ) if (this.StopCount == 0) {
{
this.Update(); this.Update();
this.PrevResetTimeMs += this.UpdateSystemTime - this.PauseSystemTimeMs; this.PrevResetTimeMs += this.UpdateSystemTime - this.PauseSystemTimeMs;
this.PrevResetTimeMs_Double += this.UpdateSystemTime_Double - this.PauseSystemTimeMs_Double; this.PrevResetTimeMs_Double += this.UpdateSystemTime_Double - this.PauseSystemTimeMs_Double;

View File

@ -1,98 +1,61 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
namespace FDK namespace FDK {
{ public class CTraceLogListener : TraceListener {
public class CTraceLogListener : TraceListener public CTraceLogListener(StreamWriter stream) {
{
public CTraceLogListener( StreamWriter stream )
{
this.LogStreamWriter = stream; this.LogStreamWriter = stream;
} }
public override void Flush() public override void Flush() {
{ if (this.LogStreamWriter != null) {
if( this.LogStreamWriter != null ) try {
{
try
{
this.LogStreamWriter.Flush(); this.LogStreamWriter.Flush();
} } catch (ObjectDisposedException) {
catch( ObjectDisposedException )
{
} }
} }
} }
public override void TraceEvent( TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message ) public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) {
{ if (this.LogStreamWriter != null) {
if( this.LogStreamWriter != null ) try {
{
try
{
this.LogEventType(eventType); this.LogEventType(eventType);
this.LogIndent(); this.LogIndent();
this.LogStreamWriter.WriteLine(message); this.LogStreamWriter.WriteLine(message);
} } catch (ObjectDisposedException) {
catch( ObjectDisposedException )
{
} }
} }
} }
public override void TraceEvent( TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args ) public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) {
{ if (this.LogStreamWriter != null) {
if( this.LogStreamWriter != null ) try {
{
try
{
this.LogEventType(eventType); this.LogEventType(eventType);
this.LogIndent(); this.LogIndent();
this.LogStreamWriter.WriteLine(string.Format(format, args)); this.LogStreamWriter.WriteLine(string.Format(format, args));
} } catch (ObjectDisposedException) {
catch( ObjectDisposedException )
{
} }
} }
} }
public override void Write( string message ) public override void Write(string message) {
{ if (this.LogStreamWriter != null) {
if( this.LogStreamWriter != null ) try {
{
try
{
this.LogStreamWriter.Write(message); this.LogStreamWriter.Write(message);
} } catch (ObjectDisposedException) {
catch( ObjectDisposedException )
{
} }
} }
} }
public override void WriteLine( string message ) public override void WriteLine(string message) {
{ if (this.LogStreamWriter != null) {
if( this.LogStreamWriter != null ) try {
{
try
{
this.LogStreamWriter.WriteLine(message); this.LogStreamWriter.WriteLine(message);
} } catch (ObjectDisposedException) {
catch( ObjectDisposedException )
{
} }
} }
} }
protected override void Dispose( bool disposing ) protected override void Dispose(bool disposing) {
{ if (this.LogStreamWriter != null) {
if( this.LogStreamWriter != null ) try {
{
try
{
this.LogStreamWriter.Close(); this.LogStreamWriter.Close();
} } catch {
catch
{
} }
this.LogStreamWriter = null; this.LogStreamWriter = null;
} }
@ -103,16 +66,12 @@ namespace FDK
//----------------- //-----------------
private StreamWriter LogStreamWriter; private StreamWriter LogStreamWriter;
private void LogEventType( TraceEventType eventType ) private void LogEventType(TraceEventType eventType) {
{ if (this.LogStreamWriter != null) {
if( this.LogStreamWriter != null ) try {
{
try
{
var now = DateTime.Now; var now = DateTime.Now;
this.LogStreamWriter.Write(string.Format("{0:D4}/{1:D2}/{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3} ", new object[] { now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond })); this.LogStreamWriter.Write(string.Format("{0:D4}/{1:D2}/{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3} ", new object[] { now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond }));
switch( eventType ) switch (eventType) {
{
case TraceEventType.Error: case TraceEventType.Error:
this.LogStreamWriter.Write("[ERROR] "); this.LogStreamWriter.Write("[ERROR] ");
return; return;
@ -131,23 +90,16 @@ namespace FDK
return; return;
} }
this.LogStreamWriter.Write("[INFO] "); this.LogStreamWriter.Write("[INFO] ");
} } catch (ObjectDisposedException) {
catch( ObjectDisposedException )
{
} }
} }
} }
private void LogIndent() private void LogIndent() {
{ if ((this.LogStreamWriter != null) && (base.IndentLevel > 0)) {
if( ( this.LogStreamWriter != null ) && ( base.IndentLevel > 0 ) ) try {
{
try
{
for (int i = 0; i < base.IndentLevel; i++) for (int i = 0; i < base.IndentLevel; i++)
this.LogStreamWriter.Write(" "); this.LogStreamWriter.Write(" ");
} } catch (ObjectDisposedException) {
catch( ObjectDisposedException )
{
} }
} }
} }

View File

@ -1,17 +1,10 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Text; using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace FDK namespace FDK {
{ public class CUtility {
public class CUtility
{
public static void RunCompleteGC() public static void RunCompleteGC() {
{
GC.Collect(); // アクセス不可能なオブジェクトを除去し、ファイナライぜーション実施。 GC.Collect(); // アクセス不可能なオブジェクトを除去し、ファイナライぜーション実施。
GC.WaitForPendingFinalizers(); // ファイナライゼーションが終わるまでスレッドを待機。 GC.WaitForPendingFinalizers(); // ファイナライゼーションが終わるまでスレッドを待機。
GC.Collect(); // ファイナライズされたばかりのオブジェクトに関連するメモリを開放。 GC.Collect(); // ファイナライズされたばかりのオブジェクトに関連するメモリを開放。
@ -22,24 +15,19 @@ namespace FDK
// ログ // ログ
public static void LogBlock( string name, Action method ) public static void LogBlock(string name, Action method) {
{
Trace.TraceInformation("--------------------"); Trace.TraceInformation("--------------------");
Trace.TraceInformation("開始 - " + name); Trace.TraceInformation("開始 - " + name);
Trace.Indent(); Trace.Indent();
try try {
{
method(); method();
} } finally {
finally
{
Trace.Unindent(); Trace.Unindent();
Trace.TraceInformation("終了 - " + name); Trace.TraceInformation("終了 - " + name);
Trace.TraceInformation("--------------------"); Trace.TraceInformation("--------------------");
} }
} }
public static void LogException( Exception e ) public static void LogException(Exception e) {
{
Trace.WriteLine("---例外ここから----"); Trace.WriteLine("---例外ここから----");
Trace.WriteLine(e.ToString()); Trace.WriteLine(e.ToString());
Trace.WriteLine("---例外ここまで----"); Trace.WriteLine("---例外ここまで----");
@ -48,17 +36,14 @@ namespace FDK
// IO // IO
public static string t指定した拡張子を持つファイルを検索し最初に見つけたファイルの絶対パスを返す( string strフォルダパス, List<string> extensions ) public static string t指定した拡張子を持つファイルを検索し最初に見つけたファイルの絶対パスを返す(string strフォルダパス, List<string> extensions) {
{
string[] files = Directory.GetFiles(strフォルダパス); // GetFiles() は完全パスを返す。 string[] files = Directory.GetFiles(strフォルダパス); // GetFiles() は完全パスを返す。
// ファイル順より拡張子順を優先して検索する。→ 拡張子リストの前方の拡張子ほど先に発見されるようにするため。 // ファイル順より拡張子順を優先して検索する。→ 拡張子リストの前方の拡張子ほど先に発見されるようにするため。
foreach( string ext in extensions ) foreach (string ext in extensions) {
{ foreach (string file in files) {
foreach( string file in files )
{
string fileExt = Path.GetExtension(file); string fileExt = Path.GetExtension(file);
if (fileExt.Equals(ext, StringComparison.OrdinalIgnoreCase)) if (fileExt.Equals(ext, StringComparison.OrdinalIgnoreCase))
@ -69,38 +54,30 @@ namespace FDK
return null; // なかった return null; // なかった
} }
public static void ReadXML<T>( string fileName, out T xmlObject ) public static void ReadXML<T>(string fileName, out T xmlObject) {
{
xmlObject = default(T); xmlObject = default(T);
FileStream fs = null; FileStream fs = null;
StreamReader sr = null; StreamReader sr = null;
try try {
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); // FileShare を付けとかないと、Close() 後もロックがかかる。 fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); // FileShare を付けとかないと、Close() 後もロックがかかる。
sr = new StreamReader(fs, Encoding.UTF8); sr = new StreamReader(fs, Encoding.UTF8);
var xmlsl = new System.Xml.Serialization.XmlSerializer(typeof(T)); var xmlsl = new System.Xml.Serialization.XmlSerializer(typeof(T));
xmlObject = (T)xmlsl.Deserialize(sr); xmlObject = (T)xmlsl.Deserialize(sr);
} } finally {
finally
{
if (sr != null) if (sr != null)
sr.Close(); // fr も一緒にClose()される sr.Close(); // fr も一緒にClose()される
} }
} }
public static void WriteXML<T>( string fileName, T xmlObject ) public static void WriteXML<T>(string fileName, T xmlObject) {
{
FileStream fs = null; FileStream fs = null;
StreamWriter sw = null; StreamWriter sw = null;
try try {
{
fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); // FileShare を付けとかないと、Close() 後もロックがかかる。 fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); // FileShare を付けとかないと、Close() 後もロックがかかる。
sw = new StreamWriter(fs, Encoding.UTF8); sw = new StreamWriter(fs, Encoding.UTF8);
var xmlsl = new System.Xml.Serialization.XmlSerializer(typeof(T)); var xmlsl = new System.Xml.Serialization.XmlSerializer(typeof(T));
xmlsl.Serialize(sw, xmlObject); xmlsl.Serialize(sw, xmlObject);
} } finally {
finally
{
if (sw != null) if (sw != null)
sw.Close(); // fs も一緒にClose()される sw.Close(); // fs も一緒にClose()される
} }
@ -109,25 +86,20 @@ namespace FDK
// 数学 // 数学
public static double DegreeToRadian( double angle ) public static double DegreeToRadian(double angle) {
{
return ((Math.PI * angle) / 180.0); return ((Math.PI * angle) / 180.0);
} }
public static double RadianToDegree( double angle ) public static double RadianToDegree(double angle) {
{
return (angle * 180.0 / Math.PI); return (angle * 180.0 / Math.PI);
} }
public static float DegreeToRadian( float angle ) public static float DegreeToRadian(float angle) {
{
return (float)DegreeToRadian((double)angle); return (float)DegreeToRadian((double)angle);
} }
public static float RadianToDegree( float angle ) public static float RadianToDegree(float angle) {
{
return (float)RadianToDegree((double)angle); return (float)RadianToDegree((double)angle);
} }
public static bool ToggleBoolian( ref bool bFlag ) public static bool ToggleBoolian(ref bool bFlag) {
{
if (bFlag == true) bFlag = false; if (bFlag == true) bFlag = false;
else if (bFlag == false) bFlag = true; else if (bFlag == false) bFlag = true;

View File

@ -1,28 +1,18 @@
using System; namespace FDK {
using System.Collections.Generic; public class Color4 {
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FDK
{
public class Color4
{
public float Red; public float Red;
public float Green; public float Green;
public float Blue; public float Blue;
public float Alpha; public float Alpha;
public Color4(float r, float g, float b, float a) public Color4(float r, float g, float b, float a) {
{
Red = r; Red = r;
Green = g; Green = g;
Blue = b; Blue = b;
Alpha = a; Alpha = a;
} }
public Color4(int rgba) public Color4(int rgba) {
{
Alpha = ((rgba >> 24) & 255) / 255.0f; Alpha = ((rgba >> 24) & 255) / 255.0f;
Blue = ((rgba >> 16) & 255) / 255.0f; Blue = ((rgba >> 16) & 255) / 255.0f;
Green = ((rgba >> 8) & 255) / 255.0f; Green = ((rgba >> 8) & 255) / 255.0f;

View File

@ -1,11 +1,6 @@
using System; namespace FDK.ExtensionMethods {
public static class DoubleExtensions {
namespace FDK.ExtensionMethods public static double Clamp(this double value, double min, double max) {
{
public static class DoubleExtensions
{
public static double Clamp(this double value, double min, double max)
{
return Math.Min(Math.Max(value, min), max); return Math.Min(Math.Max(value, min), max);
} }
} }

View File

@ -1,11 +1,6 @@
using System; namespace FDK.ExtensionMethods {
public static class Int32Extensions {
namespace FDK.ExtensionMethods public static int Clamp(this int value, int min, int max) {
{
public static class Int32Extensions
{
public static int Clamp(this int value, int min, int max)
{
return Math.Min(Math.Max(value, min), max); return Math.Min(Math.Max(value, min), max);
} }
} }

View File

@ -19,26 +19,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
using System; using FDK;
using System.ComponentModel; using Silk.NET.Core;
using System.Threading; using Silk.NET.GLFW;
using System.Collections.ObjectModel;
using Silk.NET.Windowing;
using Silk.NET.Maths; using Silk.NET.Maths;
using Silk.NET.OpenGLES; using Silk.NET.OpenGLES;
using Silk.NET.Windowing;
using SkiaSharp; using SkiaSharp;
using FDK;
using Silk.NET.GLFW;
using System.Runtime.InteropServices;
using Silk.NET.Core;
namespace SampleFramework namespace SampleFramework {
{
/// <summary> /// <summary>
/// Presents an easy to use wrapper for making games and samples. /// Presents an easy to use wrapper for making games and samples.
/// </summary> /// </summary>
public abstract class Game : IDisposable public abstract class Game : IDisposable {
{
public static GL Gl { get; private set; } public static GL Gl { get; private set; }
public static Silk.NET.Core.Contexts.IGLContext Context { get; private set; } public static Silk.NET.Core.Contexts.IGLContext Context { get; private set; }
@ -47,17 +40,13 @@ namespace SampleFramework
private string strIconFileName; private string strIconFileName;
protected string _Text = ""; protected string _Text = "";
protected string Text protected string Text {
{ get {
get
{
return _Text; return _Text;
} }
set set {
{
_Text = value; _Text = value;
if (Window_ != null) if (Window_ != null) {
{
Window_.Title = value; Window_.Title = value;
} }
} }
@ -68,34 +57,26 @@ namespace SampleFramework
public IWindow Window_; public IWindow Window_;
private Vector2D<int> _WindowSize; private Vector2D<int> _WindowSize;
public Vector2D<int> WindowSize public Vector2D<int> WindowSize {
{ get {
get
{
return _WindowSize; return _WindowSize;
} }
set set {
{
_WindowSize = value; _WindowSize = value;
if (Window_ != null) if (Window_ != null) {
{
Window_.Size = value; Window_.Size = value;
} }
} }
} }
private Vector2D<int> _WindowPosition; private Vector2D<int> _WindowPosition;
public Vector2D<int> WindowPosition public Vector2D<int> WindowPosition {
{ get {
get
{
return _WindowPosition; return _WindowPosition;
} }
set set {
{
_WindowPosition = value; _WindowPosition = value;
if (Window_ != null) if (Window_ != null) {
{
Window_.Position = value; Window_.Position = value;
} }
} }
@ -103,51 +84,39 @@ namespace SampleFramework
private int _Framerate; private int _Framerate;
public int Framerate public int Framerate {
{ get {
get
{
return _Framerate; return _Framerate;
} }
set set {
{
_Framerate = value; _Framerate = value;
if (Window_ != null) if (Window_ != null) {
{
UpdateWindowFramerate(VSync, value); UpdateWindowFramerate(VSync, value);
} }
} }
} }
private bool _FullScreen; private bool _FullScreen;
public bool FullScreen public bool FullScreen {
{ get {
get
{
return _FullScreen; return _FullScreen;
} }
set set {
{
_FullScreen = value; _FullScreen = value;
if (Window_ != null) if (Window_ != null) {
{
Window_.WindowState = value ? WindowState.Fullscreen : WindowState.Normal; Window_.WindowState = value ? WindowState.Fullscreen : WindowState.Normal;
} }
} }
} }
private bool _VSync; private bool _VSync;
public bool VSync public bool VSync {
{ get {
get
{
return _VSync; return _VSync;
} }
set set {
{
_VSync = value; _VSync = value;
if (Window_ != null) if (Window_ != null) {
{
UpdateWindowFramerate(value, Framerate); UpdateWindowFramerate(value, Framerate);
Window_.VSync = value; Window_.VSync = value;
} }
@ -159,21 +128,16 @@ namespace SampleFramework
private Vector2D<int> ViewPortSize = new Vector2D<int>(); private Vector2D<int> ViewPortSize = new Vector2D<int>();
private Vector2D<int> ViewPortOffset = new Vector2D<int>(); private Vector2D<int> ViewPortOffset = new Vector2D<int>();
public unsafe SKBitmap GetScreenShot() public unsafe SKBitmap GetScreenShot() {
{
int ViewportWidth = ViewPortSize.X; int ViewportWidth = ViewPortSize.X;
int ViewportHeight = ViewPortSize.Y; int ViewportHeight = ViewPortSize.Y;
fixed(uint* pixels = new uint[(uint)ViewportWidth * (uint)ViewportHeight]) fixed (uint* pixels = new uint[(uint)ViewportWidth * (uint)ViewportHeight]) {
{
Gl.ReadBuffer(GLEnum.Front); Gl.ReadBuffer(GLEnum.Front);
Gl.ReadPixels(ViewPortOffset.X, ViewPortOffset.Y, (uint)ViewportWidth, (uint)ViewportHeight, PixelFormat.Bgra, GLEnum.UnsignedByte, pixels); Gl.ReadPixels(ViewPortOffset.X, ViewPortOffset.Y, (uint)ViewportWidth, (uint)ViewportHeight, PixelFormat.Bgra, GLEnum.UnsignedByte, pixels);
fixed(uint* pixels2 = new uint[(uint)ViewportWidth * (uint)ViewportHeight]) fixed (uint* pixels2 = new uint[(uint)ViewportWidth * (uint)ViewportHeight]) {
{ for (int x = 0; x < ViewportWidth; x++) {
for(int x = 0; x < ViewportWidth; x++) for (int y = 1; y < ViewportHeight; y++) {
{
for(int y = 1; y < ViewportHeight; y++)
{
int pos = x + ((y - 1) * ViewportWidth); int pos = x + ((y - 1) * ViewportWidth);
int pos2 = x + ((ViewportHeight - y) * ViewportWidth); int pos2 = x + ((ViewportHeight - y) * ViewportWidth);
var p = pixels[pos2]; var p = pixels[pos2];
@ -188,24 +152,19 @@ namespace SampleFramework
} }
} }
public unsafe void GetScreenShotAsync(Action<SKBitmap> action) public unsafe void GetScreenShotAsync(Action<SKBitmap> action) {
{
int ViewportWidth = ViewPortSize.X; int ViewportWidth = ViewPortSize.X;
int ViewportHeight = ViewPortSize.Y; int ViewportHeight = ViewPortSize.Y;
byte[] pixels = new byte[(uint)ViewportWidth * (uint)ViewportHeight * 4]; byte[] pixels = new byte[(uint)ViewportWidth * (uint)ViewportHeight * 4];
Gl.ReadBuffer(GLEnum.Front); Gl.ReadBuffer(GLEnum.Front);
fixed(byte* pix = pixels) fixed (byte* pix = pixels) {
{
Gl.ReadPixels(ViewPortOffset.X, ViewPortOffset.Y, (uint)ViewportWidth, (uint)ViewportHeight, PixelFormat.Bgra, GLEnum.UnsignedByte, pix); Gl.ReadPixels(ViewPortOffset.X, ViewPortOffset.Y, (uint)ViewportWidth, (uint)ViewportHeight, PixelFormat.Bgra, GLEnum.UnsignedByte, pix);
} }
Task.Run(() => { Task.Run(() => {
fixed(byte* pixels2 = new byte[(uint)ViewportWidth * (uint)ViewportHeight * 4]) fixed (byte* pixels2 = new byte[(uint)ViewportWidth * (uint)ViewportHeight * 4]) {
{ for (int x = 0; x < ViewportWidth; x++) {
for(int x = 0; x < ViewportWidth; x++) for (int y = 1; y < ViewportHeight; y++) {
{
for(int y = 1; y < ViewportHeight; y++)
{
int pos = x + ((y - 1) * ViewportWidth); int pos = x + ((y - 1) * ViewportWidth);
int pos2 = x + ((ViewportHeight - y) * ViewportWidth); int pos2 = x + ((ViewportHeight - y) * ViewportWidth);
pixels2[(pos * 4) + 0] = pixels[(pos2 * 4) + 0]; pixels2[(pos * 4) + 0] = pixels[(pos2 * 4) + 0];
@ -226,10 +185,8 @@ namespace SampleFramework
public static Matrix4X4<float> Camera; public static Matrix4X4<float> Camera;
public static float ScreenAspect public static float ScreenAspect {
{ get {
get
{
return (float)GameWindowSize.Width / GameWindowSize.Height; return (float)GameWindowSize.Width / GameWindowSize.Height;
} }
} }
@ -240,15 +197,13 @@ namespace SampleFramework
/// <summary> /// <summary>
/// Initializes the <see cref="Game"/> class. /// Initializes the <see cref="Game"/> class.
/// </summary> /// </summary>
static Game() static Game() {
{
//GlfwProvider.UninitializedGLFW.Value.InitHint(InitHint.AnglePlatformType, (int)AnglePlatformType.OpenGL); //GlfwProvider.UninitializedGLFW.Value.InitHint(InitHint.AnglePlatformType, (int)AnglePlatformType.OpenGL);
//GlfwProvider.UninitializedGLFW.Value.Init(); //GlfwProvider.UninitializedGLFW.Value.Init();
//GetError(); //GetError();
} }
private RawImage GetIconData(string fileName) private RawImage GetIconData(string fileName) {
{
SKCodec codec = SKCodec.Create(fileName); SKCodec codec = SKCodec.Create(fileName);
using SKBitmap bitmap = SKBitmap.Decode(codec, new SKImageInfo(codec.Info.Width, codec.Info.Height, SKColorType.Rgba8888)); using SKBitmap bitmap = SKBitmap.Decode(codec, new SKImageInfo(codec.Info.Width, codec.Info.Height, SKColorType.Rgba8888));
return new RawImage(bitmap.Width, bitmap.Height, bitmap.GetPixelSpan().ToArray()); return new RawImage(bitmap.Width, bitmap.Height, bitmap.GetPixelSpan().ToArray());
@ -257,8 +212,7 @@ namespace SampleFramework
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Game"/> class. /// Initializes a new instance of the <see cref="Game"/> class.
/// </summary> /// </summary>
protected Game(string iconFileName) protected Game(string iconFileName) {
{
strIconFileName = iconFileName; strIconFileName = iconFileName;
MainThreadID = Thread.CurrentThread.ManagedThreadId; MainThreadID = Thread.CurrentThread.ManagedThreadId;
@ -299,16 +253,12 @@ namespace SampleFramework
Window_.FramebufferResize += Window_FramebufferResize; Window_.FramebufferResize += Window_FramebufferResize;
} }
private void UpdateWindowFramerate(bool vsync, int value) private void UpdateWindowFramerate(bool vsync, int value) {
{ if (vsync) {
if (vsync)
{
Window_.UpdatesPerSecond = 0; Window_.UpdatesPerSecond = 0;
Window_.FramesPerSecond = 0; Window_.FramesPerSecond = 0;
Context.SwapInterval(1); Context.SwapInterval(1);
} } else {
else
{
Window_.UpdatesPerSecond = value; Window_.UpdatesPerSecond = value;
Window_.FramesPerSecond = value; Window_.FramesPerSecond = value;
Context.SwapInterval(0); Context.SwapInterval(0);
@ -318,18 +268,15 @@ namespace SampleFramework
/// <summary> /// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary> /// </summary>
public void Dispose() public void Dispose() {
{
Window_.Dispose(); Window_.Dispose();
} }
public void Exit() public void Exit() {
{
Window_.Close(); Window_.Close();
} }
protected void ToggleWindowMode() protected void ToggleWindowMode() {
{
/* /*
DeviceSettings settings = base.GraphicsDeviceManager.CurrentSettings.Clone(); DeviceSettings settings = base.GraphicsDeviceManager.CurrentSettings.Clone();
if ( ( ConfigIni != null ) && ( ConfigIni.bウィンドウモード != settings.Windowed ) ) if ( ( ConfigIni != null ) && ( ConfigIni.bウィンドウモード != settings.Windowed ) )
@ -359,44 +306,36 @@ namespace SampleFramework
/// <summary> /// <summary>
/// Runs the game. /// Runs the game.
/// </summary> /// </summary>
public void Run() public void Run() {
{
Window_.Run(); Window_.Run();
} }
protected virtual void Configuration() protected virtual void Configuration() {
{
} }
protected virtual void Initialize() protected virtual void Initialize() {
{
} }
protected virtual void LoadContent() protected virtual void LoadContent() {
{
} }
protected virtual void UnloadContent() protected virtual void UnloadContent() {
{
} }
protected virtual void OnExiting() protected virtual void OnExiting() {
{
} }
protected virtual void Update() protected virtual void Update() {
{
} }
protected virtual void Draw() protected virtual void Draw() {
{
} }
@ -404,14 +343,12 @@ namespace SampleFramework
/// Releases unmanaged and - optionally - managed resources /// Releases unmanaged and - optionally - managed resources
/// </summary> /// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected internal virtual void Dispose(bool disposing) protected internal virtual void Dispose(bool disposing) {
{
} }
public void Window_Load() public void Window_Load() {
{
Window_.SetWindowIcon(new ReadOnlySpan<RawImage>(GetIconData(strIconFileName))); Window_.SetWindowIcon(new ReadOnlySpan<RawImage>(GetIconData(strIconFileName)));
Context = new AngleContext(GraphicsDeviceType_, Window_); Context = new AngleContext(GraphicsDeviceType_, Window_);
@ -432,8 +369,7 @@ namespace SampleFramework
LoadContent(); LoadContent();
} }
public void Window_Closing() public void Window_Closing() {
{
CTexture.Terminate(); CTexture.Terminate();
UnloadContent(); UnloadContent();
@ -442,20 +378,17 @@ namespace SampleFramework
Context.Dispose(); Context.Dispose();
} }
public void Window_Update(double deltaTime) public void Window_Update(double deltaTime) {
{
double fps = 1.0f / deltaTime; double fps = 1.0f / deltaTime;
TimeMs = (long)(Window_.Time * 1000); TimeMs = (long)(Window_.Time * 1000);
Update(); Update();
} }
public void Window_Render(double deltaTime) public void Window_Render(double deltaTime) {
{
Camera = Matrix4X4<float>.Identity; Camera = Matrix4X4<float>.Identity;
if (AsyncActions.Count > 0) if (AsyncActions.Count > 0) {
{
AsyncActions[0]?.Invoke(); AsyncActions[0]?.Invoke();
AsyncActions.Remove(AsyncActions[0]); AsyncActions.Remove(AsyncActions[0]);
} }
@ -468,19 +401,14 @@ namespace SampleFramework
Context.SwapBuffers(); Context.SwapBuffers();
} }
public void Window_Resize(Vector2D<int> size) public void Window_Resize(Vector2D<int> size) {
{ if (size.X > 0 && size.Y > 0) {
if (size.X > 0 && size.Y > 0)
{
float resolutionAspect = (float)GameWindowSize.Width / GameWindowSize.Height; float resolutionAspect = (float)GameWindowSize.Width / GameWindowSize.Height;
float windowAspect = (float)size.X / size.Y; float windowAspect = (float)size.X / size.Y;
if (windowAspect > resolutionAspect) if (windowAspect > resolutionAspect) {
{
ViewPortSize.X = (int)(size.Y * resolutionAspect); ViewPortSize.X = (int)(size.Y * resolutionAspect);
ViewPortSize.Y = size.Y; ViewPortSize.Y = size.Y;
} } else {
else
{
ViewPortSize.X = size.X; ViewPortSize.X = size.X;
ViewPortSize.Y = (int)(size.X / resolutionAspect); ViewPortSize.Y = (int)(size.X / resolutionAspect);
} }
@ -493,13 +421,11 @@ namespace SampleFramework
Gl.Viewport(ViewPortOffset.X, ViewPortOffset.Y, (uint)ViewPortSize.X, (uint)ViewPortSize.Y); Gl.Viewport(ViewPortOffset.X, ViewPortOffset.Y, (uint)ViewPortSize.X, (uint)ViewPortSize.Y);
} }
public void Window_Move(Vector2D<int> size) public void Window_Move(Vector2D<int> size) {
{
WindowPosition = size; WindowPosition = size;
} }
public void Window_FramebufferResize(Vector2D<int> size) public void Window_FramebufferResize(Vector2D<int> size) {
{
} }
} }
} }

View File

@ -1,9 +1,5 @@
using System; namespace SampleFramework {
public static class GameWindowSize {
namespace SampleFramework
{
public static class GameWindowSize
{
public static int Width = 1280; public static int Width = 1280;
public static int Height = 720; public static int Height = 720;
} }

View File

@ -1,53 +1,40 @@
using OpenTK.Graphics.Egl; //OpenTKさん ありがとう!
using Silk.NET.Core.Contexts; using Silk.NET.Core.Contexts;
using Silk.NET.GLFW; using Silk.NET.GLFW;
using OpenTK.Graphics.Egl; //OpenTKさん ありがとう!
using Silk.NET.Windowing; using Silk.NET.Windowing;
using Silk.NET.OpenGLES;
namespace SampleFramework; namespace SampleFramework;
public class AngleContext : IGLContext public class AngleContext : IGLContext {
{
private nint Display; private nint Display;
private nint Context; private nint Context;
private nint Surface; private nint Surface;
public AngleContext(AnglePlatformType anglePlatformType, IWindow window) public AngleContext(AnglePlatformType anglePlatformType, IWindow window) {
{
nint windowHandle; nint windowHandle;
nint display; nint display;
if (window.Native.Kind.HasFlag(NativeWindowFlags.Win32)) if (window.Native.Kind.HasFlag(NativeWindowFlags.Win32)) {
{
windowHandle = window.Native.Win32.Value.Hwnd; windowHandle = window.Native.Win32.Value.Hwnd;
display = window.Native.Win32.Value.HDC; display = window.Native.Win32.Value.HDC;
} } else if (window.Native.Kind.HasFlag(NativeWindowFlags.X11)) {
else if (window.Native.Kind.HasFlag(NativeWindowFlags.X11))
{
windowHandle = (nint)window.Native.X11.Value.Window; windowHandle = (nint)window.Native.X11.Value.Window;
// Temporary fix for the segfaults // Temporary fix for the segfaults
// Note than X11 Display number is NOT always 0, it can be 1, 2 and so on for example in cases of user switching // Note than X11 Display number is NOT always 0, it can be 1, 2 and so on for example in cases of user switching
display = 0;// Egl.GetDisplay(window.Native.X11.Value.Display); display = 0;// Egl.GetDisplay(window.Native.X11.Value.Display);
} } else if (window.Native.Kind.HasFlag(NativeWindowFlags.Cocoa)) {
else if (window.Native.Kind.HasFlag(NativeWindowFlags.Cocoa))
{
windowHandle = window.Native.Cocoa.Value; windowHandle = window.Native.Cocoa.Value;
display = 0; display = 0;
} } else if (window.Native.Kind.HasFlag(NativeWindowFlags.Wayland)) {
else if (window.Native.Kind.HasFlag(NativeWindowFlags.Wayland))
{
windowHandle = window.Native.Wayland.Value.Surface; windowHandle = window.Native.Wayland.Value.Surface;
display = window.Native.Wayland.Value.Display; display = window.Native.Wayland.Value.Display;
} } else {
else
{
throw new Exception("Window not found"); throw new Exception("Window not found");
} }
Source = window; Source = window;
int platform = 0; int platform = 0;
switch(anglePlatformType) switch (anglePlatformType) {
{
case AnglePlatformType.OpenGL: case AnglePlatformType.OpenGL:
platform = Egl.PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; platform = Egl.PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
break; break;
@ -86,8 +73,7 @@ public class AngleContext : IGLContext
Egl.BUFFER_SIZE, 0, Egl.BUFFER_SIZE, 0,
Egl.NONE Egl.NONE
}; };
unsafe unsafe {
{
Egl.ChooseConfig(Display, configAttributes, configs, configs.Length, out int num_config); Egl.ChooseConfig(Display, configAttributes, configs, configs.Length, out int num_config);
} }
@ -117,39 +103,32 @@ public class AngleContext : IGLContext
public bool IsCurrent { get; set; } = true; public bool IsCurrent { get; set; } = true;
public nint GetProcAddress(string proc, int? slot = null) public nint GetProcAddress(string proc, int? slot = null) {
{
nint addr = Egl.GetProcAddress(proc); nint addr = Egl.GetProcAddress(proc);
return addr; return addr;
} }
public bool TryGetProcAddress(string proc, out nint addr, int? slot = null) public bool TryGetProcAddress(string proc, out nint addr, int? slot = null) {
{
addr = Egl.GetProcAddress(proc); addr = Egl.GetProcAddress(proc);
return addr != 0; return addr != 0;
} }
public void SwapInterval(int interval) public void SwapInterval(int interval) {
{
Egl.SwapInterval(Display, interval); Egl.SwapInterval(Display, interval);
} }
public void SwapBuffers() public void SwapBuffers() {
{
Egl.SwapBuffers(Display, Surface); Egl.SwapBuffers(Display, Surface);
} }
public void MakeCurrent() public void MakeCurrent() {
{
Egl.MakeCurrent(Display, Surface, Surface, Context); Egl.MakeCurrent(Display, Surface, Surface, Context);
} }
public void Clear() public void Clear() {
{
} }
public void Dispose() public void Dispose() {
{
Egl.DestroyContext(Display, Context); Egl.DestroyContext(Display, Context);
Egl.DestroySurface(Display, Surface); Egl.DestroySurface(Display, Surface);
Egl.Terminate(Display); Egl.Terminate(Display);

View File

@ -23,7 +23,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// //
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
@ -31,27 +30,24 @@ using System.Runtime.InteropServices;
#pragma warning disable 1591 // Missing XML comments #pragma warning disable 1591 // Missing XML comments
namespace OpenTK.Graphics.Egl namespace OpenTK.Graphics.Egl {
{ using EGLClientBuffer = IntPtr;
using EGLNativeDisplayType = IntPtr;
using EGLNativeWindowType = IntPtr;
using EGLNativePixmapType = IntPtr;
using EGLConfig = IntPtr; using EGLConfig = IntPtr;
using EGLContext = IntPtr; using EGLContext = IntPtr;
using EGLDisplay = IntPtr; using EGLDisplay = IntPtr;
using EGLNativeDisplayType = IntPtr;
using EGLNativePixmapType = IntPtr;
using EGLNativeWindowType = IntPtr;
using EGLSurface = IntPtr; using EGLSurface = IntPtr;
using EGLClientBuffer = IntPtr;
public enum RenderApi public enum RenderApi {
{
ES = Egl.OPENGL_ES_API, ES = Egl.OPENGL_ES_API,
GL = Egl.OPENGL_API, GL = Egl.OPENGL_API,
VG = Egl.OPENVG_API VG = Egl.OPENVG_API
} }
[Flags] [Flags]
public enum RenderableFlags public enum RenderableFlags {
{
ES = Egl.OPENGL_ES_BIT, ES = Egl.OPENGL_ES_BIT,
ES2 = Egl.OPENGL_ES2_BIT, ES2 = Egl.OPENGL_ES2_BIT,
ES3 = Egl.OPENGL_ES3_BIT, ES3 = Egl.OPENGL_ES3_BIT,
@ -59,8 +55,7 @@ namespace OpenTK.Graphics.Egl
VG = Egl.OPENVG_BIT, VG = Egl.OPENVG_BIT,
} }
public enum ErrorCode public enum ErrorCode {
{
SUCCESS = 12288, SUCCESS = 12288,
NOT_INITIALIZED = 12289, NOT_INITIALIZED = 12289,
BAD_ACCESS = 12290, BAD_ACCESS = 12290,
@ -78,8 +73,7 @@ namespace OpenTK.Graphics.Egl
CONTEXT_LOST = 12302, CONTEXT_LOST = 12302,
} }
public enum SurfaceType public enum SurfaceType {
{
PBUFFER_BIT = 0x0001, PBUFFER_BIT = 0x0001,
PIXMAP_BIT = 0x0002, PIXMAP_BIT = 0x0002,
WINDOW_BIT = 0x0004, WINDOW_BIT = 0x0004,
@ -89,17 +83,13 @@ namespace OpenTK.Graphics.Egl
SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400, SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400,
} }
public class EglException : Exception public class EglException : Exception {
{ public EglException() : base() { }
public EglException() : base()
{ }
public EglException(string message) : base(message) public EglException(string message) : base(message) { }
{ }
} }
public static partial class Egl public static partial class Egl {
{
public const int CONTEXT_MAJOR_VERSION = 0x3098; public const int CONTEXT_MAJOR_VERSION = 0x3098;
public const int CONTEXT_MINOR_VERSION = 0x30FB; public const int CONTEXT_MINOR_VERSION = 0x30FB;
@ -343,11 +333,9 @@ namespace OpenTK.Graphics.Egl
[DllImportAttribute("libEGL", EntryPoint = "eglCreateContext")] [DllImportAttribute("libEGL", EntryPoint = "eglCreateContext")]
private static extern IntPtr eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list); private static extern IntPtr eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list);
public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list) public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list) {
{
IntPtr ptr = eglCreateContext(dpy, config, share_context, attrib_list); IntPtr ptr = eglCreateContext(dpy, config, share_context, attrib_list);
if (ptr == IntPtr.Zero) if (ptr == IntPtr.Zero) {
{
throw new EglException(string.Format("Failed to create EGL context, error: {0}.", Egl.GetError())); throw new EglException(string.Format("Failed to create EGL context, error: {0}.", Egl.GetError()));
} }
return ptr; return ptr;
@ -407,12 +395,9 @@ namespace OpenTK.Graphics.Egl
public static extern EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType native_pixmap, int[] attrib_list); public static extern EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType native_pixmap, int[] attrib_list);
// Returns true if Egl drivers exist on the system. // Returns true if Egl drivers exist on the system.
public static bool IsSupported public static bool IsSupported {
{ get {
get try { GetCurrentContext(); } catch (Exception) { return false; }
{
try { GetCurrentContext(); }
catch (Exception) { return false; }
return true; return true;
} }
} }

View File

@ -2,8 +2,7 @@ using Silk.NET.OpenGLES;
namespace SampleFramework; namespace SampleFramework;
public enum BlendType public enum BlendType {
{
Normal, Normal,
Add, Add,
Screen, Screen,
@ -11,12 +10,9 @@ public enum BlendType
Sub Sub
} }
public static class BlendHelper public static class BlendHelper {
{ public static void SetBlend(BlendType blendType) {
public static void SetBlend(BlendType blendType) switch (blendType) {
{
switch(blendType)
{
case BlendType.Normal: case BlendType.Normal:
Game.Gl.BlendEquation(BlendEquationModeEXT.FuncAdd); Game.Gl.BlendEquation(BlendEquationModeEXT.FuncAdd);
Game.Gl.BlendFunc(GLEnum.SrcAlpha, GLEnum.OneMinusSrcAlpha); Game.Gl.BlendFunc(GLEnum.SrcAlpha, GLEnum.OneMinusSrcAlpha);

View File

@ -2,12 +2,10 @@ using ImGuiNET;
namespace LWGFW.Graphics; namespace LWGFW.Graphics;
public class ImGUIManager : IDisposable public class ImGUIManager : IDisposable {
{
private nint Context; private nint Context;
public ImGUIManager() public ImGUIManager() {
{
Context = ImGui.CreateContext(); Context = ImGui.CreateContext();
ImGui.SetCurrentContext(Context); ImGui.SetCurrentContext(Context);
@ -19,8 +17,7 @@ public class ImGUIManager : IDisposable
ImGui.StyleColorsDark(); ImGui.StyleColorsDark();
} }
public void Dispose() public void Dispose() {
{
ImGui.DestroyContext(Context); ImGui.DestroyContext(Context);
} }
} }

View File

@ -2,10 +2,8 @@ using Silk.NET.OpenGLES;
namespace SampleFramework; namespace SampleFramework;
public static class ShaderHelper public static class ShaderHelper {
{ public static uint CreateShader(string code, ShaderType shaderType) {
public static uint CreateShader(string code, ShaderType shaderType)
{
uint vertexShader = Game.Gl.CreateShader(shaderType); uint vertexShader = Game.Gl.CreateShader(shaderType);
Game.Gl.ShaderSource(vertexShader, code); Game.Gl.ShaderSource(vertexShader, code);
@ -20,8 +18,7 @@ public static class ShaderHelper
return vertexShader; return vertexShader;
} }
public static uint CreateShaderProgram(uint vertexShader, uint fragmentShader) public static uint CreateShaderProgram(uint vertexShader, uint fragmentShader) {
{
uint program = Game.Gl.CreateProgram(); uint program = Game.Gl.CreateProgram();
Game.Gl.AttachShader(program, vertexShader); Game.Gl.AttachShader(program, vertexShader);
@ -40,8 +37,7 @@ public static class ShaderHelper
return program; return program;
} }
public static uint CreateShaderProgramFromSource(string vertexCode, string fragmentCode) public static uint CreateShaderProgramFromSource(string vertexCode, string fragmentCode) {
{
uint vertexShader = CreateShader(vertexCode, ShaderType.VertexShader); uint vertexShader = CreateShader(vertexCode, ShaderType.VertexShader);
uint fragmentShader = CreateShader(fragmentCode, ShaderType.FragmentShader); uint fragmentShader = CreateShader(fragmentCode, ShaderType.FragmentShader);

View File

@ -1,17 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Silk.NET.Input; using Silk.NET.Input;
namespace FDK namespace FDK {
{ public class CInputGamepad : IInputDevice, IDisposable {
public class CInputGamepad : IInputDevice, IDisposable
{
// コンストラクタ // コンストラクタ
public CInputGamepad(IGamepad gamepad) public CInputGamepad(IGamepad gamepad) {
{
this.CurrentType = InputDeviceType.Gamepad; this.CurrentType = InputDeviceType.Gamepad;
this.GUID = gamepad.Index.ToString(); this.GUID = gamepad.Index.ToString();
this.ID = gamepad.Index; this.ID = gamepad.Index;
@ -25,58 +18,45 @@ namespace FDK
// メソッド // メソッド
public void SetID( int nID ) public void SetID(int nID) {
{
this.ID = nID; this.ID = nID;
} }
#region [ IInputDevice ] #region [ IInputDevice ]
//----------------- //-----------------
public InputDeviceType CurrentType public InputDeviceType CurrentType {
{
get; get;
private set; private set;
} }
public string GUID public string GUID {
{
get; get;
private set; private set;
} }
public int ID public int ID {
{
get; get;
private set; private set;
} }
public List<STInputEvent> InputEvents public List<STInputEvent> InputEvents {
{
get; get;
private set; private set;
} }
public string strDeviceName public string strDeviceName {
{
get; get;
set; set;
} }
public void Polling(bool useBufferInput) public void Polling(bool useBufferInput) {
{
InputEvents.Clear(); InputEvents.Clear();
for (int i = 0; i < ButtonStates.Length; i++) for (int i = 0; i < ButtonStates.Length; i++) {
{ if (ButtonStates[i].Item1) {
if (ButtonStates[i].Item1) if (ButtonStates[i].Item2 >= 1) {
{
if (ButtonStates[i].Item2 >= 1)
{
ButtonStates[i].Item2 = 2; ButtonStates[i].Item2 = 2;
} } else {
else
{
ButtonStates[i].Item2 = 1; ButtonStates[i].Item2 = 1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = true, Pressed = true,
Released = false, Released = false,
@ -85,20 +65,14 @@ namespace FDK
} }
); );
} }
} } else {
else if (ButtonStates[i].Item2 <= -1) {
{
if (ButtonStates[i].Item2 <= -1)
{
ButtonStates[i].Item2 = -2; ButtonStates[i].Item2 = -2;
} } else {
else
{
ButtonStates[i].Item2 = -1; ButtonStates[i].Item2 = -1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = false, Pressed = false,
Released = true, Released = true,
@ -111,20 +85,16 @@ namespace FDK
} }
} }
public bool KeyPressed(int nButton) public bool KeyPressed(int nButton) {
{
return ButtonStates[nButton].Item2 == 1; return ButtonStates[nButton].Item2 == 1;
} }
public bool KeyPressing(int nButton) public bool KeyPressing(int nButton) {
{
return ButtonStates[nButton].Item2 >= 1; return ButtonStates[nButton].Item2 >= 1;
} }
public bool KeyReleased(int nButton) public bool KeyReleased(int nButton) {
{
return ButtonStates[nButton].Item2 == -1; return ButtonStates[nButton].Item2 == -1;
} }
public bool KeyReleasing(int nButton) public bool KeyReleasing(int nButton) {
{
return ButtonStates[nButton].Item2 <= -1; return ButtonStates[nButton].Item2 <= -1;
} }
//----------------- //-----------------
@ -132,12 +102,9 @@ namespace FDK
#region [ IDisposable ] #region [ IDisposable ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{ if (!this.IsDisposed) {
if(!this.IsDisposed) if (this.InputEvents != null) {
{
if (this.InputEvents != null)
{
this.InputEvents = null; this.InputEvents = null;
} }
this.IsDisposed = true; this.IsDisposed = true;
@ -154,18 +121,14 @@ namespace FDK
private (bool, int)[] ButtonStates = new (bool, int)[15]; private (bool, int)[] ButtonStates = new (bool, int)[15];
private bool IsDisposed; private bool IsDisposed;
private void Joystick_ButtonDown(IGamepad joystick, Button button) private void Joystick_ButtonDown(IGamepad joystick, Button button) {
{ if (button.Name != ButtonName.Unknown) {
if (button.Name != ButtonName.Unknown)
{
ButtonStates[(int)button.Name].Item1 = true; ButtonStates[(int)button.Name].Item1 = true;
} }
} }
private void Joystick_ButtonUp(IGamepad joystick, Button button) private void Joystick_ButtonUp(IGamepad joystick, Button button) {
{ if (button.Name != ButtonName.Unknown) {
if (button.Name != ButtonName.Unknown)
{
ButtonStates[(int)button.Name].Item1 = false; ButtonStates[(int)button.Name].Item1 = false;
} }
} }

View File

@ -1,19 +1,12 @@
using System; using Silk.NET.Input;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Silk.NET.Input;
namespace FDK namespace FDK {
{ public class CInputJoystick : IInputDevice, IDisposable {
public class CInputJoystick : IInputDevice, IDisposable
{
// コンストラクタ // コンストラクタ
private IJoystick Joystick { get; set; } private IJoystick Joystick { get; set; }
public CInputJoystick(IJoystick joystick) public CInputJoystick(IJoystick joystick) {
{
Joystick = joystick; Joystick = joystick;
this.CurrentType = InputDeviceType.Joystick; this.CurrentType = InputDeviceType.Joystick;
this.GUID = joystick.Index.ToString(); this.GUID = joystick.Index.ToString();
@ -30,41 +23,34 @@ namespace FDK
// メソッド // メソッド
public void SetID( int nID ) public void SetID(int nID) {
{
this.ID = nID; this.ID = nID;
} }
#region [ IInputDevice ] #region [ IInputDevice ]
//----------------- //-----------------
public InputDeviceType CurrentType public InputDeviceType CurrentType {
{
get; get;
private set; private set;
} }
public string GUID public string GUID {
{
get; get;
private set; private set;
} }
public int ID public int ID {
{
get; get;
private set; private set;
} }
public List<STInputEvent> InputEvents public List<STInputEvent> InputEvents {
{
get; get;
private set; private set;
} }
public string strDeviceName public string strDeviceName {
{
get; get;
set; set;
} }
public void Polling(bool useBufferInput) public void Polling(bool useBufferInput) {
{
InputEvents.Clear(); InputEvents.Clear();
// BUG: In Silk.NET, GLFW input does not fire events, so we have to poll // BUG: In Silk.NET, GLFW input does not fire events, so we have to poll
@ -75,21 +61,15 @@ namespace FDK
ButtonStates[button.Index].Item1 = button.Pressed; ButtonStates[button.Index].Item1 = button.Pressed;
} }
for (int i = 0; i < ButtonStates.Length; i++) for (int i = 0; i < ButtonStates.Length; i++) {
{ if (ButtonStates[i].Item1) {
if (ButtonStates[i].Item1) if (ButtonStates[i].Item2 >= 1) {
{
if (ButtonStates[i].Item2 >= 1)
{
ButtonStates[i].Item2 = 2; ButtonStates[i].Item2 = 2;
} } else {
else
{
ButtonStates[i].Item2 = 1; ButtonStates[i].Item2 = 1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = true, Pressed = true,
Released = false, Released = false,
@ -98,20 +78,14 @@ namespace FDK
} }
); );
} }
} } else {
else if (ButtonStates[i].Item2 <= -1) {
{
if (ButtonStates[i].Item2 <= -1)
{
ButtonStates[i].Item2 = -2; ButtonStates[i].Item2 = -2;
} } else {
else
{
ButtonStates[i].Item2 = -1; ButtonStates[i].Item2 = -1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = false, Pressed = false,
Released = true, Released = true,
@ -124,20 +98,16 @@ namespace FDK
} }
} }
public bool KeyPressed(int nButton) public bool KeyPressed(int nButton) {
{
return ButtonStates[nButton].Item2 == 1; return ButtonStates[nButton].Item2 == 1;
} }
public bool KeyPressing(int nButton) public bool KeyPressing(int nButton) {
{
return ButtonStates[nButton].Item2 >= 1; return ButtonStates[nButton].Item2 >= 1;
} }
public bool KeyReleased(int nButton) public bool KeyReleased(int nButton) {
{
return ButtonStates[nButton].Item2 == -1; return ButtonStates[nButton].Item2 == -1;
} }
public bool KeyReleasing(int nButton) public bool KeyReleasing(int nButton) {
{
return ButtonStates[nButton].Item2 <= -1; return ButtonStates[nButton].Item2 <= -1;
} }
//----------------- //-----------------
@ -145,12 +115,9 @@ namespace FDK
#region [ IDisposable ] #region [ IDisposable ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{ if (!this.IsDisposed) {
if(!this.IsDisposed) if (this.InputEvents != null) {
{
if (this.InputEvents != null)
{
this.InputEvents = null; this.InputEvents = null;
} }
this.IsDisposed = true; this.IsDisposed = true;
@ -167,29 +134,23 @@ namespace FDK
private (bool, int)[] ButtonStates = new (bool, int)[18]; private (bool, int)[] ButtonStates = new (bool, int)[18];
private bool IsDisposed; private bool IsDisposed;
private void Joystick_ButtonDown(IJoystick joystick, Button button) private void Joystick_ButtonDown(IJoystick joystick, Button button) {
{ if (button.Name != ButtonName.Unknown) {
if (button.Name != ButtonName.Unknown)
{
ButtonStates[(int)button.Name].Item1 = true; ButtonStates[(int)button.Name].Item1 = true;
} }
} }
private void Joystick_ButtonUp(IJoystick joystick, Button button) private void Joystick_ButtonUp(IJoystick joystick, Button button) {
{ if (button.Name != ButtonName.Unknown) {
if (button.Name != ButtonName.Unknown)
{
ButtonStates[(int)button.Name].Item1 = false; ButtonStates[(int)button.Name].Item1 = false;
} }
} }
private void Joystick_AxisMoved(IJoystick joystick, Axis axis) private void Joystick_AxisMoved(IJoystick joystick, Axis axis) {
{
} }
private void Joystick_HatMoved(IJoystick joystick, Hat hat) private void Joystick_HatMoved(IJoystick joystick, Hat hat) {
{
} }
//----------------- //-----------------

View File

@ -1,23 +1,15 @@
using System; using Silk.NET.Input;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Silk.NET.Input;
namespace FDK namespace FDK {
{ public class CInputKeyboard : IInputDevice, IDisposable {
public class CInputKeyboard : IInputDevice, IDisposable
{
// コンストラクタ // コンストラクタ
public CInputKeyboard(IReadOnlyList<IKeyboard> keyboards) public CInputKeyboard(IReadOnlyList<IKeyboard> keyboards) {
{
this.CurrentType = InputDeviceType.Keyboard; this.CurrentType = InputDeviceType.Keyboard;
this.GUID = ""; this.GUID = "";
this.ID = 0; this.ID = 0;
foreach (var keyboard in keyboards) foreach (var keyboard in keyboards) {
{
keyboard.KeyDown += KeyDown; keyboard.KeyDown += KeyDown;
keyboard.KeyUp += KeyUp; keyboard.KeyUp += KeyUp;
keyboard.KeyChar += KeyChar; keyboard.KeyChar += KeyChar;
@ -39,24 +31,17 @@ namespace FDK
public List<STInputEvent> InputEvents { get; private set; } public List<STInputEvent> InputEvents { get; private set; }
public string strDeviceName { get; set; } public string strDeviceName { get; set; }
public void Polling(bool useBufferInput) public void Polling(bool useBufferInput) {
{
InputEvents.Clear(); InputEvents.Clear();
for (int i = 0; i < KeyStates.Length; i++) for (int i = 0; i < KeyStates.Length; i++) {
{ if (KeyStates[i].Item1) {
if (KeyStates[i].Item1) if (KeyStates[i].Item2 >= 1) {
{
if (KeyStates[i].Item2 >= 1)
{
KeyStates[i].Item2 = 2; KeyStates[i].Item2 = 2;
} } else {
else
{
KeyStates[i].Item2 = 1; KeyStates[i].Item2 = 1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = true, Pressed = true,
Released = false, Released = false,
@ -65,19 +50,13 @@ namespace FDK
} }
); );
} }
} } else {
else if (KeyStates[i].Item2 <= -1) {
{
if (KeyStates[i].Item2 <= -1)
{
KeyStates[i].Item2 = -2; KeyStates[i].Item2 = -2;
} } else {
else
{
KeyStates[i].Item2 = -1; KeyStates[i].Item2 = -1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = false, Pressed = false,
Released = true, Released = true,
@ -92,29 +71,25 @@ namespace FDK
/// <param name="nKey"> /// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。) /// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param> /// </param>
public bool KeyPressed(int nKey) public bool KeyPressed(int nKey) {
{
return KeyStates[nKey].Item2 == 1; return KeyStates[nKey].Item2 == 1;
} }
/// <param name="nKey"> /// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。) /// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param> /// </param>
public bool KeyPressing(int nKey) public bool KeyPressing(int nKey) {
{
return KeyStates[nKey].Item2 >= 1; return KeyStates[nKey].Item2 >= 1;
} }
/// <param name="nKey"> /// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。) /// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param> /// </param>
public bool KeyReleased(int nKey) public bool KeyReleased(int nKey) {
{
return KeyStates[nKey].Item2 == -1; return KeyStates[nKey].Item2 == -1;
} }
/// <param name="nKey"> /// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。) /// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param> /// </param>
public bool KeyReleasing(int nKey) public bool KeyReleasing(int nKey) {
{
return KeyStates[nKey].Item2 <= -1; return KeyStates[nKey].Item2 <= -1;
} }
//----------------- //-----------------
@ -122,12 +97,9 @@ namespace FDK
#region [ IDisposable ] #region [ IDisposable ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{ if (!this.IsDisposed) {
if(!this.IsDisposed) if (this.InputEvents != null) {
{
if (this.InputEvents != null)
{
this.InputEvents = null; this.InputEvents = null;
} }
this.IsDisposed = true; this.IsDisposed = true;
@ -147,26 +119,21 @@ namespace FDK
//private CTimer ct; //private CTimer ct;
private void KeyDown(IKeyboard keyboard, Key key, int keyCode) private void KeyDown(IKeyboard keyboard, Key key, int keyCode) {
{ if (key != Key.Unknown) {
if (key != Key.Unknown)
{
var keyNum = DeviceConstantConverter.DIKtoKey(key); var keyNum = DeviceConstantConverter.DIKtoKey(key);
KeyStates[(int)keyNum].Item1 = true; KeyStates[(int)keyNum].Item1 = true;
} }
} }
private void KeyUp(IKeyboard keyboard, Key key, int keyCode) private void KeyUp(IKeyboard keyboard, Key key, int keyCode) {
{ if (key != Key.Unknown) {
if (key != Key.Unknown)
{
var keyNum = DeviceConstantConverter.DIKtoKey(key); var keyNum = DeviceConstantConverter.DIKtoKey(key);
KeyStates[(int)keyNum].Item1 = false; KeyStates[(int)keyNum].Item1 = false;
} }
} }
private void KeyChar(IKeyboard keyboard, char ch) private void KeyChar(IKeyboard keyboard, char ch) {
{
} }
//----------------- //-----------------

View File

@ -1,12 +1,5 @@
using System; namespace FDK {
using System.Collections.Generic; public class CInputMIDI : IInputDevice, IDisposable {
using System.Text;
using System.Diagnostics;
namespace FDK
{
public class CInputMIDI : IInputDevice, IDisposable
{
// プロパティ // プロパティ
public IntPtr MidiInPtr; public IntPtr MidiInPtr;
@ -14,8 +7,7 @@ namespace FDK
// コンストラクタ // コンストラクタ
public CInputMIDI(uint nID) public CInputMIDI(uint nID) {
{
this.MidiInPtr = IntPtr.Zero; this.MidiInPtr = IntPtr.Zero;
this.EventBuffers = new List<STInputEvent>(32); this.EventBuffers = new List<STInputEvent>(32);
this.InputEvents = new List<STInputEvent>(32); this.InputEvents = new List<STInputEvent>(32);
@ -28,8 +20,7 @@ namespace FDK
// メソッド // メソッド
public void tメッセージからMIDI信号のみ受信(uint wMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2, long n受信システム時刻) public void tメッセージからMIDI信号のみ受信(uint wMsg, IntPtr dwInstance, IntPtr dwParam1, IntPtr dwParam2, long n受信システム時刻) {
{
/* /*
if (wMsg == CWin32.MIM_DATA) if (wMsg == CWin32.MIM_DATA)
{ {
@ -71,8 +62,7 @@ namespace FDK
public List<STInputEvent> InputEvents { get; private set; } public List<STInputEvent> InputEvents { get; private set; }
public string strDeviceName { get; set; } public string strDeviceName { get; set; }
public void Polling(bool bWindowがアクティブ中) public void Polling(bool bWindowがアクティブ中) {
{
// this.list入力イベント = new List<STInputEvent>( 32 ); // this.list入力イベント = new List<STInputEvent>( 32 );
this.InputEvents.Clear(); // #xxxxx 2012.6.11 yyagi; To optimize, I removed new(); this.InputEvents.Clear(); // #xxxxx 2012.6.11 yyagi; To optimize, I removed new();
@ -81,27 +71,21 @@ namespace FDK
this.EventBuffers.Clear(); this.EventBuffers.Clear();
} }
public bool KeyPressed(int nKey) public bool KeyPressed(int nKey) {
{ foreach (STInputEvent event2 in this.InputEvents) {
foreach (STInputEvent event2 in this.InputEvents) if ((event2.nKey == nKey) && event2.Pressed) {
{
if ((event2.nKey == nKey) && event2.Pressed)
{
return true; return true;
} }
} }
return false; return false;
} }
public bool KeyPressing(int nKey) public bool KeyPressing(int nKey) {
{
return false; return false;
} }
public bool KeyReleased(int nKey) public bool KeyReleased(int nKey) {
{
return false; return false;
} }
public bool KeyReleasing(int nKey) public bool KeyReleasing(int nKey) {
{
return false; return false;
} }
//----------------- //-----------------
@ -109,14 +93,11 @@ namespace FDK
#region [ IDisposable ] #region [ IDisposable ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{ if (this.EventBuffers != null) {
if (this.EventBuffers != null)
{
this.EventBuffers = null; this.EventBuffers = null;
} }
if (this.InputEvents != null) if (this.InputEvents != null) {
{
this.InputEvents = null; this.InputEvents = null;
} }
} }

View File

@ -1,15 +1,9 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Silk.NET.Windowing;
using Silk.NET.Input; using Silk.NET.Input;
using Silk.NET.Windowing;
namespace FDK namespace FDK {
{ public class CInputManager : IDisposable {
public class CInputManager : IDisposable
{
// 定数 // 定数
public static int DefaultVolume = 110; public static int DefaultVolume = 110;
@ -17,23 +11,17 @@ namespace FDK
// プロパティ // プロパティ
public List<IInputDevice> InputDevices public List<IInputDevice> InputDevices {
{
get; get;
private set; private set;
} }
public IInputDevice Keyboard public IInputDevice Keyboard {
{ get {
get if (this._Keyboard != null) {
{
if (this._Keyboard != null)
{
return this._Keyboard; return this._Keyboard;
} }
foreach (IInputDevice device in this.InputDevices) foreach (IInputDevice device in this.InputDevices) {
{ if (device.CurrentType == InputDeviceType.Keyboard) {
if (device.CurrentType == InputDeviceType.Keyboard)
{
this._Keyboard = device; this._Keyboard = device;
return device; return device;
} }
@ -41,18 +29,13 @@ namespace FDK
return null; return null;
} }
} }
public IInputDevice Mouse public IInputDevice Mouse {
{ get {
get if (this._Mouse != null) {
{
if (this._Mouse != null)
{
return this._Mouse; return this._Mouse;
} }
foreach (IInputDevice device in this.InputDevices) foreach (IInputDevice device in this.InputDevices) {
{ if (device.CurrentType == InputDeviceType.Mouse) {
if (device.CurrentType == InputDeviceType.Mouse)
{
this._Mouse = device; this._Mouse = device;
return device; return device;
} }
@ -63,129 +46,97 @@ namespace FDK
// コンストラクタ // コンストラクタ
public CInputManager(IWindow window, bool bUseMidiIn = true) public CInputManager(IWindow window, bool bUseMidiIn = true) {
{
Initialize(window, bUseMidiIn); Initialize(window, bUseMidiIn);
} }
public void Initialize(IWindow window, bool bUseMidiIn) public void Initialize(IWindow window, bool bUseMidiIn) {
{
Context = window.CreateInput(); Context = window.CreateInput();
this.InputDevices = new List<IInputDevice>(10); this.InputDevices = new List<IInputDevice>(10);
#region [ Enumerate keyboard/mouse: exception is masked if keyboard/mouse is not connected ] #region [ Enumerate keyboard/mouse: exception is masked if keyboard/mouse is not connected ]
CInputKeyboard cinputkeyboard = null; CInputKeyboard cinputkeyboard = null;
CInputMouse cinputmouse = null; CInputMouse cinputmouse = null;
try try {
{
cinputkeyboard = new CInputKeyboard(Context.Keyboards); cinputkeyboard = new CInputKeyboard(Context.Keyboards);
cinputmouse = new CInputMouse(Context.Mice[0]); cinputmouse = new CInputMouse(Context.Mice[0]);
} catch {
} }
if (cinputkeyboard != null) {
catch
{
}
if (cinputkeyboard != null)
{
this.InputDevices.Add(cinputkeyboard); this.InputDevices.Add(cinputkeyboard);
} }
if (cinputmouse != null) if (cinputmouse != null) {
{
this.InputDevices.Add(cinputmouse); this.InputDevices.Add(cinputmouse);
} }
#endregion #endregion
#region [ Enumerate joypad ] #region [ Enumerate joypad ]
foreach (var joysticks in Context.Joysticks) foreach (var joysticks in Context.Joysticks) {
{
this.InputDevices.Add(new CInputJoystick(joysticks)); this.InputDevices.Add(new CInputJoystick(joysticks));
} }
foreach (var gamepad in Context.Gamepads) foreach (var gamepad in Context.Gamepads) {
{
this.InputDevices.Add(new CInputGamepad(gamepad)); this.InputDevices.Add(new CInputGamepad(gamepad));
} }
#endregion #endregion
Trace.TraceInformation("Found {0} Input Device{1}", InputDevices.Count, InputDevices.Count != 1 ? "s:" : ":"); Trace.TraceInformation("Found {0} Input Device{1}", InputDevices.Count, InputDevices.Count != 1 ? "s:" : ":");
for (int i = 0; i < InputDevices.Count; i++) for (int i = 0; i < InputDevices.Count; i++) {
{ try {
try
{
Trace.TraceInformation("Input Device #" + i + " (" + InputDevices[i].CurrentType.ToString() + ")"); Trace.TraceInformation("Input Device #" + i + " (" + InputDevices[i].CurrentType.ToString() + ")");
} } catch { }
catch { }
} }
} }
// メソッド // メソッド
public IInputDevice Joystick(int ID) public IInputDevice Joystick(int ID) {
{ foreach (IInputDevice device in this.InputDevices) {
foreach (IInputDevice device in this.InputDevices) if ((device.CurrentType == InputDeviceType.Joystick) && (device.ID == ID)) {
{
if ((device.CurrentType == InputDeviceType.Joystick) && (device.ID == ID))
{
return device; return device;
} }
} }
return null; return null;
} }
public IInputDevice Joystick(string GUID) public IInputDevice Joystick(string GUID) {
{ foreach (IInputDevice device in this.InputDevices) {
foreach (IInputDevice device in this.InputDevices) if ((device.CurrentType == InputDeviceType.Joystick) && device.GUID.Equals(GUID)) {
{
if ((device.CurrentType == InputDeviceType.Joystick) && device.GUID.Equals(GUID))
{
return device; return device;
} }
} }
return null; return null;
} }
public IInputDevice Gamepad(int ID) public IInputDevice Gamepad(int ID) {
{ foreach (IInputDevice device in this.InputDevices) {
foreach (IInputDevice device in this.InputDevices) if ((device.CurrentType == InputDeviceType.Gamepad) && (device.ID == ID)) {
{
if ((device.CurrentType == InputDeviceType.Gamepad) && (device.ID == ID))
{
return device; return device;
} }
} }
return null; return null;
} }
public IInputDevice Gamepad(string GUID) public IInputDevice Gamepad(string GUID) {
{ foreach (IInputDevice device in this.InputDevices) {
foreach (IInputDevice device in this.InputDevices) if ((device.CurrentType == InputDeviceType.Gamepad) && device.GUID.Equals(GUID)) {
{
if ((device.CurrentType == InputDeviceType.Gamepad) && device.GUID.Equals(GUID))
{
return device; return device;
} }
} }
return null; return null;
} }
public IInputDevice MidiIn(int ID) public IInputDevice MidiIn(int ID) {
{ foreach (IInputDevice device in this.InputDevices) {
foreach (IInputDevice device in this.InputDevices) if ((device.CurrentType == InputDeviceType.MidiIn) && (device.ID == ID)) {
{
if ((device.CurrentType == InputDeviceType.MidiIn) && (device.ID == ID))
{
return device; return device;
} }
} }
return null; return null;
} }
public void Polling(bool useBufferInput) public void Polling(bool useBufferInput) {
{ lock (this.objMidiIn排他用) {
lock (this.objMidiIn排他用)
{
// foreach( IInputDevice device in this.list入力デバイス ) // foreach( IInputDevice device in this.list入力デバイス )
for (int i = this.InputDevices.Count - 1; i >= 0; i--) // #24016 2011.1.6 yyagi: change not to use "foreach" to avoid InvalidOperation exception by Remove(). for (int i = this.InputDevices.Count - 1; i >= 0; i--) // #24016 2011.1.6 yyagi: change not to use "foreach" to avoid InvalidOperation exception by Remove().
{ {
IInputDevice device = this.InputDevices[i]; IInputDevice device = this.InputDevices[i];
try try {
{
device.Polling(useBufferInput); device.Polling(useBufferInput);
} } catch (Exception e) // #24016 2011.1.6 yyagi: catch exception for unplugging USB joystick, and remove the device object from the polling items.
catch (Exception e) // #24016 2011.1.6 yyagi: catch exception for unplugging USB joystick, and remove the device object from the polling items.
{ {
this.InputDevices.Remove(device); this.InputDevices.Remove(device);
device.Dispose(); device.Dispose();
@ -197,30 +148,22 @@ namespace FDK
#region [ IDisposableα ] #region [ IDisposableα ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{
this.Dispose(true); this.Dispose(true);
} }
public void Dispose(bool disposeManagedObjects) public void Dispose(bool disposeManagedObjects) {
{ if (!this.bDisposed済み) {
if (!this.bDisposed済み) if (disposeManagedObjects) {
{ foreach (IInputDevice device in this.InputDevices) {
if (disposeManagedObjects)
{
foreach (IInputDevice device in this.InputDevices)
{
CInputMIDI tmidi = device as CInputMIDI; CInputMIDI tmidi = device as CInputMIDI;
if (tmidi != null) if (tmidi != null) {
{
Trace.TraceInformation("MIDI In: [{0}] を停止しました。", new object[] { tmidi.ID }); Trace.TraceInformation("MIDI In: [{0}] を停止しました。", new object[] { tmidi.ID });
} }
} }
foreach (IInputDevice device2 in this.InputDevices) foreach (IInputDevice device2 in this.InputDevices) {
{
device2.Dispose(); device2.Dispose();
} }
lock (this.objMidiIn排他用) lock (this.objMidiIn排他用) {
{
this.InputDevices.Clear(); this.InputDevices.Clear();
} }
@ -229,8 +172,7 @@ namespace FDK
this.bDisposed済み = true; this.bDisposed済み = true;
} }
} }
~CInputManager() ~CInputManager() {
{
this.Dispose(false); this.Dispose(false);
GC.KeepAlive(this); GC.KeepAlive(this);
} }

View File

@ -1,14 +1,9 @@
using System; using System.Diagnostics;
using System.Numerics; using System.Numerics;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Silk.NET.Input; using Silk.NET.Input;
namespace FDK namespace FDK {
{ public class CInputMouse : IInputDevice, IDisposable {
public class CInputMouse : IInputDevice, IDisposable
{
// 定数 // 定数
public const int MouseButtonCount = 8; public const int MouseButtonCount = 8;
@ -16,18 +11,14 @@ namespace FDK
// コンストラクタ // コンストラクタ
public CInputMouse(IMouse mouse) public CInputMouse(IMouse mouse) {
{
this.CurrentType = InputDeviceType.Mouse; this.CurrentType = InputDeviceType.Mouse;
this.GUID = ""; this.GUID = "";
this.ID = 0; this.ID = 0;
try try {
{
Trace.TraceInformation(mouse.Name + " を生成しました。"); // なぜか0x00のゴミが出るので削除 Trace.TraceInformation(mouse.Name + " を生成しました。"); // なぜか0x00のゴミが出るので削除
this.strDeviceName = mouse.Name; this.strDeviceName = mouse.Name;
} } catch {
catch
{
Trace.TraceWarning("Mouse デバイスの生成に失敗しました。"); Trace.TraceWarning("Mouse デバイスの生成に失敗しました。");
throw; throw;
} }
@ -52,24 +43,17 @@ namespace FDK
public List<STInputEvent> InputEvents { get; private set; } public List<STInputEvent> InputEvents { get; private set; }
public string strDeviceName { get; set; } public string strDeviceName { get; set; }
public void Polling(bool useBufferInput) public void Polling(bool useBufferInput) {
{
InputEvents.Clear(); InputEvents.Clear();
for (int i = 0; i < MouseStates.Length; i++) for (int i = 0; i < MouseStates.Length; i++) {
{ if (MouseStates[i].Item1) {
if (MouseStates[i].Item1) if (MouseStates[i].Item2 >= 1) {
{
if (MouseStates[i].Item2 >= 1)
{
MouseStates[i].Item2 = 2; MouseStates[i].Item2 = 2;
} } else {
else
{
MouseStates[i].Item2 = 1; MouseStates[i].Item2 = 1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = true, Pressed = true,
Released = false, Released = false,
@ -78,19 +62,13 @@ namespace FDK
} }
); );
} }
} } else {
else if (MouseStates[i].Item2 <= -1) {
{
if (MouseStates[i].Item2 <= -1)
{
MouseStates[i].Item2 = -2; MouseStates[i].Item2 = -2;
} } else {
else
{
MouseStates[i].Item2 = -1; MouseStates[i].Item2 = -1;
InputEvents.Add( InputEvents.Add(
new STInputEvent() new STInputEvent() {
{
nKey = i, nKey = i,
Pressed = false, Pressed = false,
Released = true, Released = true,
@ -102,20 +80,16 @@ namespace FDK
} }
} }
} }
public bool KeyPressed(int nButton) public bool KeyPressed(int nButton) {
{
return MouseStates[nButton].Item2 == 1; return MouseStates[nButton].Item2 == 1;
} }
public bool KeyPressing(int nButton) public bool KeyPressing(int nButton) {
{
return MouseStates[nButton].Item2 >= 1; return MouseStates[nButton].Item2 >= 1;
} }
public bool KeyReleased(int nButton) public bool KeyReleased(int nButton) {
{
return MouseStates[nButton].Item2 == -1; return MouseStates[nButton].Item2 == -1;
} }
public bool KeyReleasing(int nButton) public bool KeyReleasing(int nButton) {
{
return MouseStates[nButton].Item2 <= -1; return MouseStates[nButton].Item2 <= -1;
} }
//----------------- //-----------------
@ -123,12 +97,9 @@ namespace FDK
#region [ IDisposable ] #region [ IDisposable ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{ if (!this.IsDisposed) {
if(!this.IsDisposed) if (this.InputEvents != null) {
{
if (this.InputEvents != null)
{
this.InputEvents = null; this.InputEvents = null;
} }
this.IsDisposed = true; this.IsDisposed = true;
@ -145,34 +116,27 @@ namespace FDK
private (bool, int)[] MouseStates = new (bool, int)[12]; private (bool, int)[] MouseStates = new (bool, int)[12];
private bool IsDisposed; private bool IsDisposed;
private void Mouse_Click(IMouse mouse, MouseButton mouseButton, Vector2 vector2) private void Mouse_Click(IMouse mouse, MouseButton mouseButton, Vector2 vector2) {
{
} }
private void Mouse_DoubleClick(IMouse mouse, MouseButton mouseButton, Vector2 vector2) private void Mouse_DoubleClick(IMouse mouse, MouseButton mouseButton, Vector2 vector2) {
{
} }
private void Mouse_MouseDown(IMouse mouse, MouseButton mouseButton) private void Mouse_MouseDown(IMouse mouse, MouseButton mouseButton) {
{ if (mouseButton != MouseButton.Unknown) {
if (mouseButton != MouseButton.Unknown)
{
MouseStates[(int)mouseButton].Item1 = true; MouseStates[(int)mouseButton].Item1 = true;
} }
} }
private void Mouse_MouseUp(IMouse mouse, MouseButton mouseButton) private void Mouse_MouseUp(IMouse mouse, MouseButton mouseButton) {
{ if (mouseButton != MouseButton.Unknown) {
if (mouseButton != MouseButton.Unknown)
{
MouseStates[(int)mouseButton].Item1 = false; MouseStates[(int)mouseButton].Item1 = false;
} }
} }
private void Mouse_MouseMove(IMouse mouse, Vector2 vector2) private void Mouse_MouseMove(IMouse mouse, Vector2 vector2) {
{
} }
//----------------- //-----------------

View File

@ -1,18 +1,12 @@
using System; using SlimDXKeys;
using System.Collections.Generic;
using System.Text;
using SlimDXKeys;
using SlimDXKey = SlimDXKeys.Key; using SlimDXKey = SlimDXKeys.Key;
namespace FDK namespace FDK {
{ public static class DeviceConstantConverter {
public static class DeviceConstantConverter
{
// メソッド // メソッド
public static Key DIKtoKey( Silk.NET.Input.Key key ) public static Key DIKtoKey(Silk.NET.Input.Key key) {
{
return _DIKtoKey[key]; return _DIKtoKey[key];
} }

View File

@ -1,27 +1,17 @@
using System; namespace FDK {
using System.Collections.Generic; public interface IInputDevice : IDisposable {
using System.Text;
namespace FDK
{
public interface IInputDevice : IDisposable
{
// プロパティ // プロパティ
InputDeviceType CurrentType InputDeviceType CurrentType {
{
get; get;
} }
string GUID string GUID {
{
get; get;
} }
int ID int ID {
{
get; get;
} }
List<STInputEvent> InputEvents List<STInputEvent> InputEvents {
{
get; get;
} }

View File

@ -1,13 +1,7 @@
using System; namespace FDK {
using System.Collections.Generic;
using System.Text;
namespace FDK
{
// 定数 // 定数
public enum InputDeviceType public enum InputDeviceType {
{
Keyboard, Keyboard,
Mouse, Mouse,
Joystick, Joystick,

View File

@ -1,15 +1,10 @@
using System; using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace FDK namespace FDK {
{
// 構造体 // 構造体
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct STInputEvent public struct STInputEvent {
{
public int nKey { get; set; } public int nKey { get; set; }
public bool Pressed { get; set; } public bool Pressed { get; set; }
public bool Released { get; set; } public bool Released { get; set; }

View File

@ -1,13 +1,5 @@
using System; namespace SlimDXKeys {
using System.Collections.Generic; public enum Key {
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlimDXKeys
{
public enum Key
{
D0 = 0, D0 = 0,
D1 = 1, D1 = 1,
D2 = 2, D2 = 2,
@ -154,8 +146,7 @@ namespace SlimDXKeys
Yen = 143, Yen = 143,
Unknown = 144 Unknown = 144
} }
public enum MouseObject public enum MouseObject {
{
Button1 = 0, Button1 = 0,
Button2 = 1, Button2 = 1,
Button3 = 2, Button3 = 2,

View File

@ -1,27 +1,18 @@
using System; using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.IO; using FDK.BassMixExtension;
using System.Linq;
using System.Threading;
using FDK.ExtensionMethods; using FDK.ExtensionMethods;
using ManagedBass; using ManagedBass;
using ManagedBass.Asio;
using ManagedBass.Wasapi;
using ManagedBass.Mix;
using ManagedBass.Fx; using ManagedBass.Fx;
using Silk.NET.Windowing; using ManagedBass.Mix;
using FDK.BassMixExtension;
namespace FDK namespace FDK {
{
// CSound は、サウンドデバイスが変更されたときも、インスタンスを再作成することなく、新しいデバイスで作り直せる必要がある。 // CSound は、サウンドデバイスが変更されたときも、インスタンスを再作成することなく、新しいデバイスで作り直せる必要がある。
// そのため、デバイスごとに別のクラスに分割するのではなく、1つのクラスに集約するものとする。 // そのため、デバイスごとに別のクラスに分割するのではなく、1つのクラスに集約するものとする。
public class CSound : IDisposable public class CSound : IDisposable {
{
public const int MinimumSongVol = 0; public const int MinimumSongVol = 0;
public const int MaximumSongVol = 200; // support an approximate doubling in volume. public const int MaximumSongVol = 200; // support an approximate doubling in volume.
public const int DefaultSongVol = 100; public const int DefaultSongVol = 100;
@ -49,8 +40,7 @@ namespace FDK
#region [ DTXMania用拡張 ] #region [ DTXMania用拡張 ]
public int TotalPlayTime public int TotalPlayTime {
{
get; get;
private set; private set;
} }
@ -63,55 +53,40 @@ namespace FDK
{ {
get { return false; } get { return false; }
} }
public double Frequency public double Frequency {
{ get {
get
{
return _Frequency; return _Frequency;
} }
set set {
{ if (_Frequency != value) {
if ( _Frequency != value )
{
_Frequency = value; _Frequency = value;
if ( IsBassSound ) if (IsBassSound) {
{
Bass.ChannelSetAttribute(this.hBassStream, ChannelAttribute.Frequency, (float)(_Frequency * _PlaySpeed * nオリジナルの周波数)); Bass.ChannelSetAttribute(this.hBassStream, ChannelAttribute.Frequency, (float)(_Frequency * _PlaySpeed * nオリジナルの周波数));
} }
} }
} }
} }
public double PlaySpeed public double PlaySpeed {
{ get {
get
{
return _PlaySpeed; return _PlaySpeed;
} }
set set {
{ if (_PlaySpeed != value) {
if ( _PlaySpeed != value )
{
_PlaySpeed = value; _PlaySpeed = value;
IsNormalSpeed = (_PlaySpeed == 1.000f); IsNormalSpeed = (_PlaySpeed == 1.000f);
if ( IsBassSound ) if (IsBassSound) {
{
if (_hTempoStream != 0 && !this.IsNormalSpeed) // 再生速度がx1.000のときは、TempoStreamを用いないようにして高速化する if (_hTempoStream != 0 && !this.IsNormalSpeed) // 再生速度がx1.000のときは、TempoStreamを用いないようにして高速化する
{ {
this.hBassStream = _hTempoStream; this.hBassStream = _hTempoStream;
} } else {
else
{
this.hBassStream = _hBassStream; this.hBassStream = _hBassStream;
} }
if ( SoundManager.bIsTimeStretch ) if (SoundManager.bIsTimeStretch) {
{
Bass.ChannelSetAttribute(this.hBassStream, ChannelAttribute.Tempo, (float)(PlaySpeed * 100 - 100)); Bass.ChannelSetAttribute(this.hBassStream, ChannelAttribute.Tempo, (float)(PlaySpeed * 100 - 100));
//double seconds = Bass.BASS_ChannelBytes2Seconds( this.hTempoStream, nBytes ); //double seconds = Bass.BASS_ChannelBytes2Seconds( this.hTempoStream, nBytes );
//this.n総演奏時間ms = (int) ( seconds * 1000 ); //this.n総演奏時間ms = (int) ( seconds * 1000 );
} } else {
else
{
Bass.ChannelSetAttribute(this.hBassStream, ChannelAttribute.Frequency, (float)(_Frequency * _PlaySpeed * nオリジナルの周波数)); Bass.ChannelSetAttribute(this.hBassStream, ChannelAttribute.Frequency, (float)(_Frequency * _PlaySpeed * nオリジナルの周波数));
} }
} }
@ -135,13 +110,11 @@ namespace FDK
/// for mixing in the SONGVOL value, when available. It is also used for /// for mixing in the SONGVOL value, when available. It is also used for
/// DTXViewer preview mode. /// DTXViewer preview mode.
/// </summary> /// </summary>
public void SetGain(int songVol) public void SetGain(int songVol) {
{
SetGain(LinearIntegerPercentToLufs(songVol), null); SetGain(LinearIntegerPercentToLufs(songVol), null);
} }
private static Lufs LinearIntegerPercentToLufs(int percent) private static Lufs LinearIntegerPercentToLufs(int percent) {
{
// 2018-08-27 twopointzero: We'll use the standard conversion until an appropriate curve can be selected // 2018-08-27 twopointzero: We'll use the standard conversion until an appropriate curve can be selected
return new Lufs(20.0 * Math.Log10(percent / 100.0)); return new Lufs(20.0 * Math.Log10(percent / 100.0));
} }
@ -155,18 +128,15 @@ namespace FDK
/// This method, taking a LUFS gain value and a LUFS true audio peak value, /// This method, taking a LUFS gain value and a LUFS true audio peak value,
/// is used for mixing in the loudness-metadata-base gain value, when available. /// is used for mixing in the loudness-metadata-base gain value, when available.
/// </summary> /// </summary>
public void SetGain(Lufs gain, Lufs? truePeak) public void SetGain(Lufs gain, Lufs? truePeak) {
{ if (Equals(_gain, gain)) {
if (Equals(_gain, gain))
{
return; return;
} }
_gain = gain; _gain = gain;
_truePeak = truePeak; _truePeak = truePeak;
if (SoundGroup == ESoundGroup.SongPlayback) if (SoundGroup == ESoundGroup.SongPlayback) {
{
Trace.TraceInformation($"{nameof(CSound)}.{nameof(SetGain)}: Gain: {_gain}. True Peak: {_truePeak}"); Trace.TraceInformation($"{nameof(CSound)}.{nameof(SetGain)}: Gain: {_gain}. True Peak: {_truePeak}");
} }
@ -182,20 +152,16 @@ namespace FDK
/// case right now for the song selection screen background music fade /// case right now for the song selection screen background music fade
/// in and fade out. /// in and fade out.
/// </summary> /// </summary>
public int AutomationLevel public int AutomationLevel {
{
get => _automationLevel; get => _automationLevel;
set set {
{ if (_automationLevel == value) {
if (_automationLevel == value)
{
return; return;
} }
_automationLevel = value; _automationLevel = value;
if (SoundGroup == ESoundGroup.SongPlayback) if (SoundGroup == ESoundGroup.SongPlayback) {
{
Trace.TraceInformation($"{nameof(CSound)}.{nameof(AutomationLevel)} set: {AutomationLevel}"); Trace.TraceInformation($"{nameof(CSound)}.{nameof(AutomationLevel)} set: {AutomationLevel}");
} }
@ -216,20 +182,16 @@ namespace FDK
/// ///
/// See the SoundGroupLevelController and related classes for more. /// See the SoundGroupLevelController and related classes for more.
/// </summary> /// </summary>
public int GroupLevel public int GroupLevel {
{
private get => _groupLevel; private get => _groupLevel;
set set {
{ if (_groupLevel == value) {
if (_groupLevel == value)
{
return; return;
} }
_groupLevel = value; _groupLevel = value;
if (SoundGroup == ESoundGroup.SongPlayback) if (SoundGroup == ESoundGroup.SongPlayback) {
{
Trace.TraceInformation($"{nameof(CSound)}.{nameof(GroupLevel)} set: {GroupLevel}"); Trace.TraceInformation($"{nameof(CSound)}.{nameof(GroupLevel)} set: {GroupLevel}");
} }
@ -237,8 +199,7 @@ namespace FDK
} }
} }
private void SetVolume() private void SetVolume() {
{
var automationLevel = LinearIntegerPercentToLufs(AutomationLevel); var automationLevel = LinearIntegerPercentToLufs(AutomationLevel);
var groupLevel = LinearIntegerPercentToLufs(GroupLevel); var groupLevel = LinearIntegerPercentToLufs(GroupLevel);
@ -250,8 +211,7 @@ namespace FDK
var safeTruePeakGain = _truePeak?.Negate() ?? new Lufs(0); var safeTruePeakGain = _truePeak?.Negate() ?? new Lufs(0);
var finalGain = gain.Min(safeTruePeakGain); var finalGain = gain.Min(safeTruePeakGain);
if (SoundGroup == ESoundGroup.SongPlayback) if (SoundGroup == ESoundGroup.SongPlayback) {
{
Trace.TraceInformation( Trace.TraceInformation(
$"{nameof(CSound)}.{nameof(SetVolume)}: Gain:{_gain}. Automation Level: {automationLevel}. Group Level: {groupLevel}. Summed Gain: {gain}. Safe True Peak Gain: {safeTruePeakGain}. Final Gain: {finalGain}."); $"{nameof(CSound)}.{nameof(SetVolume)}: Gain:{_gain}. Automation Level: {automationLevel}. Group Level: {groupLevel}. Summed Gain: {gain}. Safe True Peak Gain: {safeTruePeakGain}. Final Gain: {finalGain}.");
} }
@ -259,12 +219,9 @@ namespace FDK
lufs音量 = finalGain; lufs音量 = finalGain;
} }
private Lufs lufs音量 private Lufs lufs音量 {
{ set {
set if (this.IsBassSound) {
{
if (this.IsBassSound)
{
var db音量 = ((value.ToDouble() / 100.0) + 1.0).Clamp(0, 1); var db音量 = ((value.ToDouble() / 100.0) + 1.0).Clamp(0, 1);
Bass.ChannelSetAttribute(this._hBassStream, ChannelAttribute.Volume, (float)db音量); Bass.ChannelSetAttribute(this._hBassStream, ChannelAttribute.Volume, (float)db音量);
Bass.ChannelSetAttribute(this._hTempoStream, ChannelAttribute.Volume, (float)db音量); Bass.ChannelSetAttribute(this._hTempoStream, ChannelAttribute.Volume, (float)db音量);
@ -275,12 +232,9 @@ namespace FDK
/// <summary> /// <summary>
/// <para>左:-100中央:0100:右。set のみ。</para> /// <para>左:-100中央:0100:右。set のみ。</para>
/// </summary> /// </summary>
public int SoundPosition public int SoundPosition {
{ get {
get if (this.IsBassSound) {
{
if( this.IsBassSound )
{
float f位置 = 0.0f; float f位置 = 0.0f;
if (!Bass.ChannelGetAttribute(this.hBassStream, ChannelAttribute.Pan, out f位置)) if (!Bass.ChannelGetAttribute(this.hBassStream, ChannelAttribute.Pan, out f位置))
//if( BassMix.BASS_Mixer_ChannelGetEnvelopePos( this.hBassStream, BASSMIXEnvelope.BASS_MIXER_ENV_PAN, ref f位置 ) == -1 ) //if( BassMix.BASS_Mixer_ChannelGetEnvelopePos( this.hBassStream, BASSMIXEnvelope.BASS_MIXER_ENV_PAN, ref f位置 ) == -1 )
@ -289,10 +243,8 @@ namespace FDK
} }
return -9999; return -9999;
} }
set set {
{ if (this.IsBassSound) {
if( this.IsBassSound )
{
float f位置 = Math.Min(Math.Max(value, -100), 100) / 100.0f; // -100100 → -1.01.0 float f位置 = Math.Min(Math.Max(value, -100), 100) / 100.0f; // -100100 → -1.01.0
//var nodes = new BASS_MIXER_NODE[ 1 ] { new BASS_MIXER_NODE( 0, f位置 ) }; //var nodes = new BASS_MIXER_NODE[ 1 ] { new BASS_MIXER_NODE( 0, f位置 ) };
//BassMix.BASS_Mixer_ChannelSetEnvelope( this.hBassStream, BASSMIXEnvelope.BASS_MIXER_ENV_PAN, nodes ); //BassMix.BASS_Mixer_ChannelSetEnvelope( this.hBassStream, BASSMIXEnvelope.BASS_MIXER_ENV_PAN, nodes );
@ -307,17 +259,14 @@ namespace FDK
/// </summary> /// </summary>
public static readonly ObservableCollection<CSound> SoundInstances = new ObservableCollection<CSound>(); public static readonly ObservableCollection<CSound> SoundInstances = new ObservableCollection<CSound>();
public static void ShowAllCSoundFiles() public static void ShowAllCSoundFiles() {
{
int i = 0; int i = 0;
foreach ( CSound cs in SoundInstances ) foreach (CSound cs in SoundInstances) {
{
Debug.WriteLine(i++.ToString("d3") + ": " + Path.GetFileName(cs.FileName)); Debug.WriteLine(i++.ToString("d3") + ": " + Path.GetFileName(cs.FileName));
} }
} }
public CSound(ESoundGroup soundGroup) public CSound(ESoundGroup soundGroup) {
{
SoundGroup = soundGroup; SoundGroup = soundGroup;
this.SoundPosition = 0; this.SoundPosition = 0;
this._Frequency = 1.0; this._Frequency = 1.0;
@ -327,57 +276,45 @@ namespace FDK
this._hTempoStream = 0; this._hTempoStream = 0;
} }
public void CreateBassSound( string fileName, int hMixer ) public void CreateBassSound(string fileName, int hMixer) {
{
this.CurrentSoundDeviceType = ESoundDeviceType.Bass; // 作成後に設定する。(作成に失敗してると例外発出されてここは実行されない) this.CurrentSoundDeviceType = ESoundDeviceType.Bass; // 作成後に設定する。(作成に失敗してると例外発出されてここは実行されない)
this.CreateBassSound(fileName, hMixer, BassFlags.Decode); this.CreateBassSound(fileName, hMixer, BassFlags.Decode);
} }
public void CreateASIOSound( string fileName, int hMixer ) public void CreateASIOSound(string fileName, int hMixer) {
{
this.CurrentSoundDeviceType = ESoundDeviceType.ASIO; // 作成後に設定する。(作成に失敗してると例外発出されてここは実行されない) this.CurrentSoundDeviceType = ESoundDeviceType.ASIO; // 作成後に設定する。(作成に失敗してると例外発出されてここは実行されない)
this.CreateBassSound(fileName, hMixer, BassFlags.Decode); this.CreateBassSound(fileName, hMixer, BassFlags.Decode);
} }
public void CreateWASAPISound( string fileName, int hMixer, ESoundDeviceType deviceType ) public void CreateWASAPISound(string fileName, int hMixer, ESoundDeviceType deviceType) {
{
this.CurrentSoundDeviceType = deviceType; // 作成後に設定する。(作成に失敗してると例外発出されてここは実行されない) this.CurrentSoundDeviceType = deviceType; // 作成後に設定する。(作成に失敗してると例外発出されてここは実行されない)
this.CreateBassSound(fileName, hMixer, BassFlags.Decode | BassFlags.Float); this.CreateBassSound(fileName, hMixer, BassFlags.Decode | BassFlags.Float);
} }
#region [ DTXMania用の変換 ] #region [ DTXMania用の変換 ]
public void DisposeSound( CSound cs ) public void DisposeSound(CSound cs) {
{
cs.tDispose(); cs.tDispose();
} }
public void PlayStart() public void PlayStart() {
{
tSetPositonToBegin(); tSetPositonToBegin();
if (!b速度上げすぎ問題) if (!b速度上げすぎ問題)
tPlaySound(false); tPlaySound(false);
} }
public void PlayStart( bool looped ) public void PlayStart(bool looped) {
{ if (IsBassSound) {
if ( IsBassSound ) if (looped) {
{
if ( looped )
{
Bass.ChannelFlags(this.hBassStream, BassFlags.Loop, BassFlags.Loop); Bass.ChannelFlags(this.hBassStream, BassFlags.Loop, BassFlags.Loop);
} } else {
else
{
Bass.ChannelFlags(this.hBassStream, BassFlags.Default, BassFlags.Default); Bass.ChannelFlags(this.hBassStream, BassFlags.Default, BassFlags.Default);
} }
} }
tSetPositonToBegin(); tSetPositonToBegin();
tPlaySound(looped); tPlaySound(looped);
} }
public void Stop() public void Stop() {
{
tStopSound(); tStopSound();
tSetPositonToBegin(); tSetPositonToBegin();
} }
public void Pause() public void Pause() {
{
tStopSound(true); tStopSound(true);
this.PauseCount++; this.PauseCount++;
} }
@ -388,31 +325,23 @@ namespace FDK
tPlaySound(); tPlaySound();
this.PauseCount--; this.PauseCount--;
} }
public bool IsPaused public bool IsPaused {
{ get {
get if (this.IsBassSound) {
{
if ( this.IsBassSound )
{
bool ret = (!BassMixExtensions.ChannelIsPlaying(this.hBassStream)) & bool ret = (!BassMixExtensions.ChannelIsPlaying(this.hBassStream)) &
(BassMix.ChannelGetPosition(this.hBassStream) > 0); (BassMix.ChannelGetPosition(this.hBassStream) > 0);
return ret; return ret;
} } else {
else
{
return (this.PauseCount > 0); return (this.PauseCount > 0);
} }
} }
} }
public bool IsPlaying public bool IsPlaying {
{ get {
get
{
// 基本的にはBASS_ACTIVE_PLAYINGなら再生中だが、最後まで再生しきったchannelも // 基本的にはBASS_ACTIVE_PLAYINGなら再生中だが、最後まで再生しきったchannelも
// BASS_ACTIVE_PLAYINGのままになっているので、小細工が必要。 // BASS_ACTIVE_PLAYINGのままになっているので、小細工が必要。
bool ret = (BassMixExtensions.ChannelIsPlaying(this.hBassStream)); bool ret = (BassMixExtensions.ChannelIsPlaying(this.hBassStream));
if (BassMix.ChannelGetPosition(this.hBassStream) >= nBytes) if (BassMix.ChannelGetPosition(this.hBassStream) >= nBytes) {
{
ret = false; ret = false;
} }
return ret; return ret;
@ -426,13 +355,11 @@ namespace FDK
#endregion #endregion
public void tDispose() public void tDispose() {
{
tDispose(false); tDispose(false);
} }
public void tDispose( bool deleteInstance ) public void tDispose(bool deleteInstance) {
{
if (this.IsBassSound) // stream数の削減用 if (this.IsBassSound) // stream数の削減用
{ {
tRemoveSoundFromMixer(); tRemoveSoundFromMixer();
@ -443,99 +370,72 @@ namespace FDK
this.Dispose(disposeWithManaged, deleteInstance); this.Dispose(disposeWithManaged, deleteInstance);
//Debug.WriteLine( "Disposed: " + _bインスタンス削除 + " : " + Path.GetFileName( this.strファイル名 ) ); //Debug.WriteLine( "Disposed: " + _bインスタンス削除 + " : " + Path.GetFileName( this.strファイル名 ) );
} }
public void tPlaySound() public void tPlaySound() {
{
tPlaySound(false); tPlaySound(false);
} }
private void tPlaySound( bool bループする ) private void tPlaySound(bool bループする) {
{
if (this.IsBassSound) // BASSサウンド時のループ処理は、t再生を開始する()側に実装。ここでは「bループする」は未使用。 if (this.IsBassSound) // BASSサウンド時のループ処理は、t再生を開始する()側に実装。ここでは「bループする」は未使用。
{ {
//Debug.WriteLine( "再生中?: " + System.IO.Path.GetFileName(this.strファイル名) + " status=" + BassMix.BASS_Mixer_ChannelIsActive( this.hBassStream ) + " current=" + BassMix.BASS_Mixer_ChannelGetPosition( this.hBassStream ) + " nBytes=" + nBytes ); //Debug.WriteLine( "再生中?: " + System.IO.Path.GetFileName(this.strファイル名) + " status=" + BassMix.BASS_Mixer_ChannelIsActive( this.hBassStream ) + " current=" + BassMix.BASS_Mixer_ChannelGetPosition( this.hBassStream ) + " nBytes=" + nBytes );
bool b = BassMixExtensions.ChannelPlay(this.hBassStream); bool b = BassMixExtensions.ChannelPlay(this.hBassStream);
if ( !b ) if (!b) {
{
//Debug.WriteLine( "再生しようとしたが、Mixerに登録されていなかった: " + Path.GetFileName( this.strファイル名 ) + ", stream#=" + this.hBassStream + ", ErrCode=" + Bass.BASS_ErrorGetCode() ); //Debug.WriteLine( "再生しようとしたが、Mixerに登録されていなかった: " + Path.GetFileName( this.strファイル名 ) + ", stream#=" + this.hBassStream + ", ErrCode=" + Bass.BASS_ErrorGetCode() );
bool bb = AddBassSoundFromMixer(); bool bb = AddBassSoundFromMixer();
if ( !bb ) if (!bb) {
{
Debug.WriteLine("Mixerへの登録に失敗: " + Path.GetFileName(this.FileName) + ", ErrCode=" + Bass.LastError); Debug.WriteLine("Mixerへの登録に失敗: " + Path.GetFileName(this.FileName) + ", ErrCode=" + Bass.LastError);
} } else {
else
{
//Debug.WriteLine( "Mixerへの登録に成功: " + Path.GetFileName( this.strファイル名 ) + ": " + Bass.BASS_ErrorGetCode() ); //Debug.WriteLine( "Mixerへの登録に成功: " + Path.GetFileName( this.strファイル名 ) + ": " + Bass.BASS_ErrorGetCode() );
} }
//this.t再生位置を先頭に戻す(); //this.t再生位置を先頭に戻す();
bool bbb = BassMixExtensions.ChannelPlay(this.hBassStream); bool bbb = BassMixExtensions.ChannelPlay(this.hBassStream);
if (!bbb) if (!bbb) {
{
Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ", ErrCode=" + Bass.LastError); Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ", ErrCode=" + Bass.LastError);
} } else {
else
{
// Debug.WriteLine("再生成功(ミキサー追加後) : " + Path.GetFileName(this.strファイル名)); // Debug.WriteLine("再生成功(ミキサー追加後) : " + Path.GetFileName(this.strファイル名));
} }
} } else {
else
{
//Debug.WriteLine( "再生成功: " + Path.GetFileName( this.strファイル名 ) + " (" + hBassStream + ")" ); //Debug.WriteLine( "再生成功: " + Path.GetFileName( this.strファイル名 ) + " (" + hBassStream + ")" );
} }
} }
} }
public void tStopSoundAndRemoveSoundFromMixer() public void tStopSoundAndRemoveSoundFromMixer() {
{
tStopSound(false); tStopSound(false);
if ( IsBassSound ) if (IsBassSound) {
{
tRemoveSoundFromMixer(); tRemoveSoundFromMixer();
} }
} }
public void tStopSound() public void tStopSound() {
{
tStopSound(false); tStopSound(false);
} }
public void tStopSound( bool pause ) public void tStopSound(bool pause) {
{ if (this.IsBassSound) {
if( this.IsBassSound )
{
//Debug.WriteLine( "停止: " + System.IO.Path.GetFileName( this.strファイル名 ) + " status=" + BassMix.BASS_Mixer_ChannelIsActive( this.hBassStream ) + " current=" + BassMix.BASS_Mixer_ChannelGetPosition( this.hBassStream ) + " nBytes=" + nBytes ); //Debug.WriteLine( "停止: " + System.IO.Path.GetFileName( this.strファイル名 ) + " status=" + BassMix.BASS_Mixer_ChannelIsActive( this.hBassStream ) + " current=" + BassMix.BASS_Mixer_ChannelGetPosition( this.hBassStream ) + " nBytes=" + nBytes );
BassMixExtensions.ChannelPause(this.hBassStream); BassMixExtensions.ChannelPause(this.hBassStream);
if ( !pause ) if (!pause) {
{
// tBASSサウンドをミキサーから削除する(); // PAUSEと再生停止を区別できるようにすること!! // tBASSサウンドをミキサーから削除する(); // PAUSEと再生停止を区別できるようにすること!!
} }
} }
this.PauseCount = 0; this.PauseCount = 0;
} }
public void tSetPositonToBegin() public void tSetPositonToBegin() {
{ if (this.IsBassSound) {
if( this.IsBassSound )
{
BassMix.ChannelSetPosition(this.hBassStream, 0); BassMix.ChannelSetPosition(this.hBassStream, 0);
//pos = 0; //pos = 0;
} }
} }
public void tSetPositonToBegin( long positionMs ) public void tSetPositonToBegin(long positionMs) {
{ if (this.IsBassSound) {
if( this.IsBassSound )
{
bool b = true; bool b = true;
try try {
{
b = BassMix.ChannelSetPosition(this.hBassStream, Bass.ChannelSeconds2Bytes(this.hBassStream, positionMs * this.Frequency * this.PlaySpeed / 1000.0), PositionFlags.Bytes); b = BassMix.ChannelSetPosition(this.hBassStream, Bass.ChannelSeconds2Bytes(this.hBassStream, positionMs * this.Frequency * this.PlaySpeed / 1000.0), PositionFlags.Bytes);
} } catch (Exception e) {
catch( Exception e )
{
Trace.TraceError(e.ToString()); Trace.TraceError(e.ToString());
Trace.TraceInformation(Path.GetFileName(this.FileName) + ": Seek error: " + e.ToString() + ": " + positionMs + "ms"); Trace.TraceInformation(Path.GetFileName(this.FileName) + ": Seek error: " + e.ToString() + ": " + positionMs + "ms");
} } finally {
finally if (!b) {
{
if ( !b )
{
Errors be = Bass.LastError; Errors be = Bass.LastError;
Trace.TraceInformation(Path.GetFileName(this.FileName) + ": Seek error: " + be.ToString() + ": " + positionMs + "MS"); Trace.TraceInformation(Path.GetFileName(this.FileName) + ": Seek error: " + be.ToString() + ": " + positionMs + "MS");
} }
@ -551,30 +451,23 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
/// </summary> /// </summary>
/// <param name="positionByte"></param> /// <param name="positionByte"></param>
/// <param name="positionMs"></param> /// <param name="positionMs"></param>
public void tGetPlayPositon( out long positionByte, out double positionMs ) public void tGetPlayPositon(out long positionByte, out double positionMs) {
{ if (this.IsBassSound) {
if ( this.IsBassSound )
{
positionByte = BassMix.ChannelGetPosition(this.hBassStream); positionByte = BassMix.ChannelGetPosition(this.hBassStream);
positionMs = Bass.ChannelBytes2Seconds(this.hBassStream, positionByte); positionMs = Bass.ChannelBytes2Seconds(this.hBassStream, positionByte);
} } else {
else
{
positionByte = 0; positionByte = 0;
positionMs = 0.0; positionMs = 0.0;
} }
} }
public static void tResetAllSound() public static void tResetAllSound() {
{ foreach (var sound in CSound.SoundInstances) {
foreach ( var sound in CSound.SoundInstances )
{
sound.tDispose(false); sound.tDispose(false);
} }
} }
internal static void tReloadSound( ISoundDevice device ) internal static void tReloadSound(ISoundDevice device) {
{
if (CSound.SoundInstances.Count == 0) if (CSound.SoundInstances.Count == 0)
return; return;
@ -587,10 +480,8 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
// 配列に基づいて個々のサウンドを作成する。 // 配列に基づいて個々のサウンドを作成する。
for( int i = 0; i < sounds.Length; i++ ) for (int i = 0; i < sounds.Length; i++) {
{ switch (sounds[i].CurrnetCreateType) {
switch( sounds[ i ].CurrnetCreateType )
{
#region [ ] #region [ ]
case CreateType.FromFile: case CreateType.FromFile:
string strファイル名 = sounds[i].FileName; string strファイル名 = sounds[i].FileName;
@ -604,19 +495,15 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
#region [ Dispose-Finalizeパターン実装 ] #region [ Dispose-Finalizeパターン実装 ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{
this.Dispose(true, true); this.Dispose(true, true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
private void Dispose( bool deleteWithManaged, bool deleteInstance ) private void Dispose(bool deleteWithManaged, bool deleteInstance) {
{ if (this.IsBassSound) {
if( this.IsBassSound )
{
#region [ ASIO, WASAPI ] #region [ ASIO, WASAPI ]
//----------------- //-----------------
if ( _hTempoStream != 0 ) if (_hTempoStream != 0) {
{
BassMix.MixerRemoveChannel(this._hTempoStream); BassMix.MixerRemoveChannel(this._hTempoStream);
Bass.StreamFree(this._hTempoStream); Bass.StreamFree(this._hTempoStream);
} }
@ -629,8 +516,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
#endregion #endregion
} }
if( deleteWithManaged ) if (deleteWithManaged) {
{
//int freeIndex = -1; //int freeIndex = -1;
//if ( CSound.listインスタンス != null ) //if ( CSound.listインスタンス != null )
@ -644,8 +530,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
this.CurrentSoundDeviceType = ESoundDeviceType.Unknown; this.CurrentSoundDeviceType = ESoundDeviceType.Unknown;
if ( deleteInstance ) if (deleteInstance) {
{
//try //try
//{ //{
// CSound.listインスタンス.RemoveAt( freeIndex ); // CSound.listインスタンス.RemoveAt( freeIndex );
@ -655,16 +540,14 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
// Debug.WriteLine( "FAILED to remove CSound.listインスタンス: Count=" + CSound.listインスタンス.Count + ", filename=" + Path.GetFileName( this.strファイル名 ) ); // Debug.WriteLine( "FAILED to remove CSound.listインスタンス: Count=" + CSound.listインスタンス.Count + ", filename=" + Path.GetFileName( this.strファイル名 ) );
//} //}
bool b = CSound.SoundInstances.Remove(this); // これだと、Clone()したサウンドのremoveに失敗する bool b = CSound.SoundInstances.Remove(this); // これだと、Clone()したサウンドのremoveに失敗する
if ( !b ) if (!b) {
{
Debug.WriteLine("FAILED to remove CSound.listインスタンス: Count=" + CSound.SoundInstances.Count + ", filename=" + Path.GetFileName(this.FileName)); Debug.WriteLine("FAILED to remove CSound.listインスタンス: Count=" + CSound.SoundInstances.Count + ", filename=" + Path.GetFileName(this.FileName));
} }
} }
} }
} }
~CSound() ~CSound() {
{
this.Dispose(false, true); this.Dispose(false, true);
} }
//----------------- //-----------------
@ -706,10 +589,8 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
#region [ private ] #region [ private ]
//----------------- //-----------------
private bool IsBassSound private bool IsBassSound {
{ get {
get
{
return ( return (
this.CurrentSoundDeviceType == ESoundDeviceType.Bass || this.CurrentSoundDeviceType == ESoundDeviceType.Bass ||
this.CurrentSoundDeviceType == ESoundDeviceType.ASIO || this.CurrentSoundDeviceType == ESoundDeviceType.ASIO ||
@ -730,8 +611,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
private double _PlaySpeed = 1.0; private double _PlaySpeed = 1.0;
private bool IsNormalSpeed = true; private bool IsNormalSpeed = true;
public void CreateBassSound( string strファイル名, int hMixer, BassFlags flags ) public void CreateBassSound(string strファイル名, int hMixer, BassFlags flags) {
{
this.CurrnetCreateType = CreateType.FromFile; this.CurrnetCreateType = CreateType.FromFile;
this.FileName = strファイル名; this.FileName = strファイル名;
@ -747,8 +627,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
tBASSサウンドを作成する_ストリーム生成後の共通処理(hMixer); tBASSサウンドを作成する_ストリーム生成後の共通処理(hMixer);
} }
private void tBASSサウンドを作成する_ストリーム生成後の共通処理( int hMixer ) private void tBASSサウンドを作成する_ストリーム生成後の共通処理(int hMixer) {
{
SoundManager.nStreams++; SoundManager.nStreams++;
// 個々のストリームの出力をテンポ変更のストリームに入力する。テンポ変更ストリームの出力を、Mixerに出力する。 // 個々のストリームの出力をテンポ変更のストリームに入力する。テンポ変更ストリームの出力を、Mixerに出力する。
@ -756,13 +635,10 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
// if ( CSound管理.bIsTimeStretch ) // TimeStretchのON/OFFに関わりなく、テンポ変更のストリームを生成する。後からON/OFF切り替え可能とするため。 // if ( CSound管理.bIsTimeStretch ) // TimeStretchのON/OFFに関わりなく、テンポ変更のストリームを生成する。後からON/OFF切り替え可能とするため。
{ {
this._hTempoStream = BassFx.TempoCreate(this._hBassStream, BassFlags.Decode | BassFlags.FxFreeSource); this._hTempoStream = BassFx.TempoCreate(this._hBassStream, BassFlags.Decode | BassFlags.FxFreeSource);
if ( this._hTempoStream == 0 ) if (this._hTempoStream == 0) {
{
hGC.Free(); hGC.Free();
throw new Exception(string.Format("サウンドストリームの生成に失敗しました。(BASS_FX_TempoCreate)[{0}]", Bass.LastError.ToString())); throw new Exception(string.Format("サウンドストリームの生成に失敗しました。(BASS_FX_TempoCreate)[{0}]", Bass.LastError.ToString()));
} } else {
else
{
Bass.ChannelSetAttribute(this._hTempoStream, ChannelAttribute.TempoUseQuickAlgorithm, 1f); // 高速化(音の品質は少し落ちる) Bass.ChannelSetAttribute(this._hTempoStream, ChannelAttribute.TempoUseQuickAlgorithm, 1f); // 高速化(音の品質は少し落ちる)
} }
} }
@ -770,9 +646,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
if (_hTempoStream != 0 && !this.IsNormalSpeed) // 再生速度がx1.000のときは、TempoStreamを用いないようにして高速化する if (_hTempoStream != 0 && !this.IsNormalSpeed) // 再生速度がx1.000のときは、TempoStreamを用いないようにして高速化する
{ {
this.hBassStream = _hTempoStream; this.hBassStream = _hTempoStream;
} } else {
else
{
this.hBassStream = _hBassStream; this.hBassStream = _hBassStream;
} }
@ -786,8 +660,7 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
//this.pos = 0; //this.pos = 0;
this.hMixer = hMixer; this.hMixer = hMixer;
float freq = 0.0f; float freq = 0.0f;
if ( !Bass.ChannelGetAttribute( this._hBassStream, ChannelAttribute.Frequency, out freq ) ) if (!Bass.ChannelGetAttribute(this._hBassStream, ChannelAttribute.Frequency, out freq)) {
{
hGC.Free(); hGC.Free();
throw new Exception(string.Format("サウンドストリームの周波数取得に失敗しました。(BASS_ChannelGetAttribute)[{0}]", Bass.LastError.ToString())); throw new Exception(string.Format("サウンドストリームの周波数取得に失敗しました。(BASS_ChannelGetAttribute)[{0}]", Bass.LastError.ToString()));
} }
@ -831,15 +704,12 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
// mixerからの削除 // mixerからの削除
public bool tRemoveSoundFromMixer() public bool tRemoveSoundFromMixer() {
{
return RemoveBassSoundFromMixer(this.hBassStream); return RemoveBassSoundFromMixer(this.hBassStream);
} }
public bool RemoveBassSoundFromMixer( int channel ) public bool RemoveBassSoundFromMixer(int channel) {
{
bool b = BassMix.MixerRemoveChannel(channel); bool b = BassMix.MixerRemoveChannel(channel);
if ( b ) if (b) {
{
Interlocked.Decrement(ref SoundManager.nMixing); Interlocked.Decrement(ref SoundManager.nMixing);
// Debug.WriteLine( "Removed: " + Path.GetFileName( this.strファイル名 ) + " (" + channel + ")" + " MixedStreams=" + CSound管理.nMixing ); // Debug.WriteLine( "Removed: " + Path.GetFileName( this.strファイル名 ) + " (" + channel + ")" + " MixedStreams=" + CSound管理.nMixing );
} }
@ -849,10 +719,8 @@ Debug.WriteLine("更に再生に失敗: " + Path.GetFileName(this.FileName) + ",
// mixer への追加 // mixer への追加
public bool AddBassSoundFromMixer() public bool AddBassSoundFromMixer() {
{ if (BassMix.ChannelGetMixer(hBassStream) == 0) {
if ( BassMix.ChannelGetMixer( hBassStream ) == 0 )
{
BassFlags bf = BassFlags.SpeakerFront | BassFlags.MixerChanNoRampin | BassFlags.MixerChanPause; BassFlags bf = BassFlags.SpeakerFront | BassFlags.MixerChanNoRampin | BassFlags.MixerChanPause;
Interlocked.Increment(ref SoundManager.nMixing); Interlocked.Increment(ref SoundManager.nMixing);

View File

@ -1,33 +1,23 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using FDK.ExtensionMethods;
using ManagedBass; using ManagedBass;
using ManagedBass.Asio; using ManagedBass.Asio;
using ManagedBass.Mix; using ManagedBass.Mix;
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// 全ASIOデバイスを列挙する静的クラス。 /// 全ASIOデバイスを列挙する静的クラス。
/// BASS_Init()やBASS_ASIO_Init()の状態とは無関係に使用可能。 /// BASS_Init()やBASS_ASIO_Init()の状態とは無関係に使用可能。
/// </summary> /// </summary>
public static class CEnumerateAllAsioDevices public static class CEnumerateAllAsioDevices {
{ public static string[] GetAllASIODevices() {
public static string[] GetAllASIODevices() try {
{
try
{
string[] bassAsioDevName = new string[BassAsio.DeviceCount]; string[] bassAsioDevName = new string[BassAsio.DeviceCount];
for (int i = 0; i < bassAsioDevName.Length; i++) for (int i = 0; i < bassAsioDevName.Length; i++)
bassAsioDevName[i] = BassAsio.GetDeviceInfo(i).Name; bassAsioDevName[i] = BassAsio.GetDeviceInfo(i).Name;
if (bassAsioDevName.Length != 0) if (bassAsioDevName.Length != 0)
return bassAsioDevName; return bassAsioDevName;
} } catch (Exception e) {
catch(Exception e)
{
Trace.TraceWarning($"Exception occured in GetAllASIODevices ({e})"); Trace.TraceWarning($"Exception occured in GetAllASIODevices ({e})");
} }
@ -35,79 +25,62 @@ namespace FDK
} }
} }
internal class CSoundDeviceASIO : ISoundDevice internal class CSoundDeviceASIO : ISoundDevice {
{
// プロパティ // プロパティ
public ESoundDeviceType SoundDeviceType public ESoundDeviceType SoundDeviceType {
{
get; get;
protected set; protected set;
} }
public long OutputDelay public long OutputDelay {
{
get; get;
protected set; protected set;
} }
public long BufferSize public long BufferSize {
{
get; get;
protected set; protected set;
} }
public int ASIODevice public int ASIODevice {
{
get; get;
set; set;
} }
// CSoundTimer 用に公開しているプロパティ // CSoundTimer 用に公開しているプロパティ
public long ElapsedTimeMs public long ElapsedTimeMs {
{
get; get;
protected set; protected set;
} }
public long UpdateSystemTimeMs public long UpdateSystemTimeMs {
{
get; get;
protected set; protected set;
} }
public CTimer SystemTimer public CTimer SystemTimer {
{
get; get;
protected set; protected set;
} }
// マスターボリュームの制御コードは、WASAPI/ASIOで全く同じ。 // マスターボリュームの制御コードは、WASAPI/ASIOで全く同じ。
public int nMasterVolume public int nMasterVolume {
{ get {
get
{
float f音量 = 0.0f; float f音量 = 0.0f;
bool b = Bass.ChannelGetAttribute(this.hMixer, ChannelAttribute.Volume, out f音量); bool b = Bass.ChannelGetAttribute(this.hMixer, ChannelAttribute.Volume, out f音量);
if ( !b ) if (!b) {
{
Errors be = Bass.LastError; Errors be = Bass.LastError;
Trace.TraceInformation("ASIO Master Volume Get Error: " + be.ToString()); Trace.TraceInformation("ASIO Master Volume Get Error: " + be.ToString());
} } else {
else
{
//Trace.TraceInformation( "ASIO Master Volume Get Success: " + (f音量 * 100) ); //Trace.TraceInformation( "ASIO Master Volume Get Success: " + (f音量 * 100) );
} }
return (int)(f音量 * 100); return (int)(f音量 * 100);
} }
set set {
{
bool b = Bass.ChannelSetAttribute(this.hMixer, ChannelAttribute.Volume, (float)(value / 100.0)); bool b = Bass.ChannelSetAttribute(this.hMixer, ChannelAttribute.Volume, (float)(value / 100.0));
if ( !b ) if (!b) {
{
Errors be = Bass.LastError; Errors be = Bass.LastError;
Trace.TraceInformation("ASIO Master Volume Set Error: " + be.ToString()); Trace.TraceInformation("ASIO Master Volume Set Error: " + be.ToString());
} } else {
else
{
// int n = this.nMasterVolume; // int n = this.nMasterVolume;
// Trace.TraceInformation( "ASIO Master Volume Set Success: " + value ); // Trace.TraceInformation( "ASIO Master Volume Set Success: " + value );
} }
@ -116,8 +89,7 @@ namespace FDK
// メソッド // メソッド
public CSoundDeviceASIO( long bufferSize, int deviceIndex ) public CSoundDeviceASIO(long bufferSize, int deviceIndex) {
{
// 初期化。 // 初期化。
Trace.TraceInformation("BASS (ASIO) の初期化を開始します。"); Trace.TraceInformation("BASS (ASIO) の初期化を開始します。");
@ -198,15 +170,12 @@ namespace FDK
#endregion #endregion
//----------------- //-----------------
#endregion #endregion
} } else {
else
{
#region [ ASIO ] #region [ ASIO ]
//----------------- //-----------------
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
string errmes = errcode.ToString(); string errmes = errcode.ToString();
if ( errcode == Errors.OK ) if (errcode == Errors.OK) {
{
errmes = "BASS_OK; The device may be dissconnected"; errmes = "BASS_OK; The device may be dissconnected";
} }
Bass.Free(); Bass.Free();
@ -233,8 +202,7 @@ namespace FDK
} }
for (int i = 1; i < this.n出力チャンネル数; i++) // 出力チャネルを全てチャネル0とグループ化する。 for (int i = 1; i < this.n出力チャンネル数; i++) // 出力チャネルを全てチャネル0とグループ化する。
{ // チャネル1だけを0とグループ化すると、3ch以上の出力をサポートしたカードでの動作がおかしくなる { // チャネル1だけを0とグループ化すると、3ch以上の出力をサポートしたカードでの動作がおかしくなる
if ( !BassAsio.ChannelJoin( false, i, 0 ) ) if (!BassAsio.ChannelJoin(false, i, 0)) {
{
#region [ ] #region [ ]
//----------------- //-----------------
BassAsio.Free(); BassAsio.Free();
@ -264,8 +232,7 @@ namespace FDK
flag |= BassFlags.Float; flag |= BassFlags.Float;
this.hMixer = BassMix.CreateMixerStream((int)this.db周波数, this.n出力チャンネル数, flag); this.hMixer = BassMix.CreateMixerStream((int)this.db周波数, this.n出力チャンネル数, flag);
if ( this.hMixer == 0 ) if (this.hMixer == 0) {
{
Errors err = Bass.LastError; Errors err = Bass.LastError;
BassAsio.Free(); BassAsio.Free();
Bass.Free(); Bass.Free();
@ -277,8 +244,7 @@ namespace FDK
var mixerInfo = Bass.ChannelGetInfo(this.hMixer); var mixerInfo = Bass.ChannelGetInfo(this.hMixer);
int nサンプルサイズbyte = 0; int nサンプルサイズbyte = 0;
switch( this.fmtASIOチャンネルフォーマット ) switch (this.fmtASIOチャンネルフォーマット) {
{
case AsioSampleFormat.Bit16: nサンプルサイズbyte = 2; break; case AsioSampleFormat.Bit16: nサンプルサイズbyte = 2; break;
case AsioSampleFormat.Bit24: nサンプルサイズbyte = 3; break; case AsioSampleFormat.Bit24: nサンプルサイズbyte = 3; break;
case AsioSampleFormat.Bit32: nサンプルサイズbyte = 4; break; case AsioSampleFormat.Bit32: nサンプルサイズbyte = 4; break;
@ -295,8 +261,7 @@ namespace FDK
// hMixerの音量制御を反映させる。 // hMixerの音量制御を反映させる。
this.hMixer_DeviceOut = BassMix.CreateMixerStream( this.hMixer_DeviceOut = BassMix.CreateMixerStream(
(int)this.db周波数, this.n出力チャンネル数, flag); (int)this.db周波数, this.n出力チャンネル数, flag);
if ( this.hMixer_DeviceOut == 0 ) if (this.hMixer_DeviceOut == 0) {
{
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
BassAsio.Free(); BassAsio.Free();
Bass.Free(); Bass.Free();
@ -305,8 +270,7 @@ namespace FDK
} }
{ {
bool b1 = BassMix.MixerAddChannel(this.hMixer_DeviceOut, this.hMixer, BassFlags.Default); bool b1 = BassMix.MixerAddChannel(this.hMixer_DeviceOut, this.hMixer, BassFlags.Default);
if ( !b1 ) if (!b1) {
{
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
BassAsio.Free(); BassAsio.Free();
Bass.Free(); Bass.Free();
@ -327,9 +291,7 @@ namespace FDK
Bass.Free(); Bass.Free();
this.bIsBASSFree = true; this.bIsBASSFree = true;
throw new Exception("ASIO デバイス出力開始に失敗しました。" + err.ToString()); throw new Exception("ASIO デバイス出力開始に失敗しました。" + err.ToString());
} } else {
else
{
int n遅延sample = BassAsio.GetLatency(false); // この関数は BASS_ASIO_Start() 後にしか呼び出せない。 int n遅延sample = BassAsio.GetLatency(false); // この関数は BASS_ASIO_Start() 後にしか呼び出せない。
int n希望遅延sample = (int)(bufferSize * this.db周波数 / 1000.0); int n希望遅延sample = (int)(bufferSize * this.db周波数 / 1000.0);
this.BufferSize = this.OutputDelay = (long)(n遅延sample * 1000.0f / this.db周波数); this.BufferSize = this.OutputDelay = (long)(n遅延sample * 1000.0f / this.db周波数);
@ -338,15 +300,13 @@ namespace FDK
} }
#region [ tサウンドを作成する() ] #region [ tサウンドを作成する() ]
public CSound tCreateSound( string strファイル名, ESoundGroup soundGroup ) public CSound tCreateSound(string strファイル名, ESoundGroup soundGroup) {
{
var sound = new CSound(soundGroup); var sound = new CSound(soundGroup);
sound.CreateASIOSound(strファイル名, this.hMixer); sound.CreateASIOSound(strファイル名, this.hMixer);
return sound; return sound;
} }
public void tCreateSound( string strファイル名, CSound sound ) public void tCreateSound(string strファイル名, CSound sound) {
{
sound.CreateASIOSound(strファイル名, this.hMixer); sound.CreateASIOSound(strファイル名, this.hMixer);
} }
#endregion #endregion
@ -354,32 +314,26 @@ namespace FDK
#region [ Dispose-Finallizeパターン実装 ] #region [ Dispose-Finallizeパターン実装 ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{
this.Dispose(true); this.Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected void Dispose( bool bManagedDispose ) protected void Dispose(bool bManagedDispose) {
{
SoundDeviceType = ESoundDeviceType.Unknown; // まず出力停止する(Dispose中にクラス内にアクセスされることを防ぐ) SoundDeviceType = ESoundDeviceType.Unknown; // まず出力停止する(Dispose中にクラス内にアクセスされることを防ぐ)
if ( hMixer != -1 ) if (hMixer != -1) {
{
Bass.StreamFree(hMixer); Bass.StreamFree(hMixer);
} }
if ( !bIsBASSFree ) if (!bIsBASSFree) {
{
BassAsio.Free(); // システムタイマより先に呼び出すこと。tAsio処理() の中でシステムタイマを参照してるため) BassAsio.Free(); // システムタイマより先に呼び出すこと。tAsio処理() の中でシステムタイマを参照してるため)
Bass.Free(); Bass.Free();
} }
if( bManagedDispose ) if (bManagedDispose) {
{
SystemTimer.Dispose(); SystemTimer.Dispose();
SystemTimer = null; SystemTimer = null;
} }
} }
~CSoundDeviceASIO() ~CSoundDeviceASIO() {
{
this.Dispose(false); this.Dispose(false);
} }
//----------------- //-----------------
@ -396,8 +350,7 @@ namespace FDK
//protected BASSASIOFormat fmtASIOチャンネルフォーマット = BASSASIOFormat.BASS_ASIO_FORMAT_32BIT;// 16bit 固定 //protected BASSASIOFormat fmtASIOチャンネルフォーマット = BASSASIOFormat.BASS_ASIO_FORMAT_32BIT;// 16bit 固定
protected AsioProcedure tAsioProc = null; protected AsioProcedure tAsioProc = null;
protected int tAsio処理( bool input, int channel, IntPtr buffer, int length, IntPtr user ) protected int tAsio処理(bool input, int channel, IntPtr buffer, int length, IntPtr user) {
{
if (input) return 0; if (input) return 0;

View File

@ -1,48 +1,35 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using ManagedBass; using ManagedBass;
using ManagedBass.Mix; using ManagedBass.Mix;
namespace FDK namespace FDK {
{ public class CSoundDeviceBASS : ISoundDevice {
public class CSoundDeviceBASS : ISoundDevice
{
// プロパティ // プロパティ
public ESoundDeviceType SoundDeviceType public ESoundDeviceType SoundDeviceType {
{
get; get;
protected set; protected set;
} }
public long OutputDelay public long OutputDelay {
{
get; get;
protected set; protected set;
} }
public long BufferSize public long BufferSize {
{
get; get;
protected set; protected set;
} }
// CSoundTimer 用に公開しているプロパティ // CSoundTimer 用に公開しているプロパティ
public long ElapsedTimeMs public long ElapsedTimeMs {
{
get; get;
protected set; protected set;
} }
public long UpdateSystemTimeMs public long UpdateSystemTimeMs {
{
get; get;
protected set; protected set;
} }
public CTimer SystemTimer public CTimer SystemTimer {
{
get; get;
protected set; protected set;
} }
@ -50,32 +37,26 @@ namespace FDK
public float CPUUsage => (float)Bass.CPUUsage; public float CPUUsage => (float)Bass.CPUUsage;
// マスターボリュームの制御コードは、WASAPI/ASIOで全く同じ。 // マスターボリュームの制御コードは、WASAPI/ASIOで全く同じ。
public int nMasterVolume public int nMasterVolume {
{ get {
get
{
float fVolume = 0.0f; float fVolume = 0.0f;
bool b = Bass.ChannelGetAttribute(this.MixerHandle, ChannelAttribute.Volume, out fVolume); bool b = Bass.ChannelGetAttribute(this.MixerHandle, ChannelAttribute.Volume, out fVolume);
if (!b) if (!b) {
{
Errors be = Bass.LastError; Errors be = Bass.LastError;
Trace.TraceInformation("BASS Master Volume Get Error: " + be.ToString()); Trace.TraceInformation("BASS Master Volume Get Error: " + be.ToString());
} }
return (int)(fVolume * 100); return (int)(fVolume * 100);
} }
set set {
{
bool b = Bass.ChannelSetAttribute(this.MixerHandle, ChannelAttribute.Volume, (float)(value / 100.0)); bool b = Bass.ChannelSetAttribute(this.MixerHandle, ChannelAttribute.Volume, (float)(value / 100.0));
if (!b) if (!b) {
{
Errors be = Bass.LastError; Errors be = Bass.LastError;
Trace.TraceInformation("BASS Master Volume Set Error: " + be.ToString()); Trace.TraceInformation("BASS Master Volume Set Error: " + be.ToString());
} }
} }
} }
public CSoundDeviceBASS(int updatePeriod, int bufferSize) public CSoundDeviceBASS(int updatePeriod, int bufferSize) {
{
Trace.TraceInformation("Start initialization of BASS"); Trace.TraceInformation("Start initialization of BASS");
this.SoundDeviceType = ESoundDeviceType.Unknown; this.SoundDeviceType = ESoundDeviceType.Unknown;
this.OutputDelay = 0; this.OutputDelay = 0;
@ -92,12 +73,10 @@ namespace FDK
if (!Bass.Init(-1, freq, DeviceInitFlags.Default)) if (!Bass.Init(-1, freq, DeviceInitFlags.Default))
throw new Exception(string.Format("BASS の初期化に失敗しました。(BASS_Init)[{0}]", Bass.LastError.ToString())); throw new Exception(string.Format("BASS の初期化に失敗しました。(BASS_Init)[{0}]", Bass.LastError.ToString()));
if (!Bass.Configure(Configuration.UpdatePeriod, updatePeriod)) if (!Bass.Configure(Configuration.UpdatePeriod, updatePeriod)) {
{
Trace.TraceWarning($"BASS_SetConfig({nameof(Configuration.UpdatePeriod)}) に失敗しました。[{Bass.LastError}]"); Trace.TraceWarning($"BASS_SetConfig({nameof(Configuration.UpdatePeriod)}) に失敗しました。[{Bass.LastError}]");
} }
if (!Bass.Configure(Configuration.UpdateThreads, 1)) if (!Bass.Configure(Configuration.UpdateThreads, 1)) {
{
Trace.TraceWarning($"BASS_SetConfig({nameof(Configuration.UpdateThreads)}) に失敗しました。[{Bass.LastError}]"); Trace.TraceWarning($"BASS_SetConfig({nameof(Configuration.UpdateThreads)}) に失敗しました。[{Bass.LastError}]");
} }
@ -110,8 +89,7 @@ namespace FDK
var flag = BassFlags.MixerNonStop | BassFlags.Decode; // デコードのみ=発声しない。 var flag = BassFlags.MixerNonStop | BassFlags.Decode; // デコードのみ=発声しない。
this.MixerHandle = BassMix.CreateMixerStream(freq, 2, flag); this.MixerHandle = BassMix.CreateMixerStream(freq, 2, flag);
if (this.MixerHandle == 0) if (this.MixerHandle == 0) {
{
Errors err = Bass.LastError; Errors err = Bass.LastError;
Bass.Free(); Bass.Free();
this.IsBASSSoundFree = true; this.IsBASSSoundFree = true;
@ -133,8 +111,7 @@ namespace FDK
// hMixerの音量制御を反映させる。 // hMixerの音量制御を反映させる。
Mixer_DeviceOut = BassMix.CreateMixerStream( Mixer_DeviceOut = BassMix.CreateMixerStream(
freq, 2, flag); freq, 2, flag);
if (this.Mixer_DeviceOut == 0) if (this.Mixer_DeviceOut == 0) {
{
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
Bass.Free(); Bass.Free();
this.IsBASSSoundFree = true; this.IsBASSSoundFree = true;
@ -142,8 +119,7 @@ namespace FDK
} }
{ {
bool b1 = BassMix.MixerAddChannel(this.Mixer_DeviceOut, this.MixerHandle, BassFlags.Default); bool b1 = BassMix.MixerAddChannel(this.Mixer_DeviceOut, this.MixerHandle, BassFlags.Default);
if (!b1) if (!b1) {
{
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
Bass.Free(); Bass.Free();
this.IsBASSSoundFree = true; this.IsBASSSoundFree = true;
@ -161,9 +137,7 @@ namespace FDK
Bass.Free(); Bass.Free();
this.IsBASSSoundFree = true; this.IsBASSSoundFree = true;
throw new Exception("BASS デバイス出力開始に失敗しました。" + err.ToString()); throw new Exception("BASS デバイス出力開始に失敗しました。" + err.ToString());
} } else {
else
{
Bass.GetInfo(out var info); Bass.GetInfo(out var info);
this.BufferSize = this.OutputDelay = info.Latency + bufferSize;//求め方があっているのだろうか… this.BufferSize = this.OutputDelay = info.Latency + bufferSize;//求め方があっているのだろうか…
@ -176,15 +150,13 @@ namespace FDK
} }
#region [ tCreateSound() ] #region [ tCreateSound() ]
public CSound tCreateSound(string strFilename, ESoundGroup soundGroup) public CSound tCreateSound(string strFilename, ESoundGroup soundGroup) {
{
var sound = new CSound(soundGroup); var sound = new CSound(soundGroup);
sound.CreateBassSound(strFilename, this.MixerHandle); sound.CreateBassSound(strFilename, this.MixerHandle);
return sound; return sound;
} }
public void tCreateSound(string strFilename, CSound sound) public void tCreateSound(string strFilename, CSound sound) {
{
sound.CreateBassSound(strFilename, this.MixerHandle); sound.CreateBassSound(strFilename, this.MixerHandle);
} }
#endregion #endregion
@ -192,43 +164,35 @@ namespace FDK
#region [ Dispose-Finallizeパターン実装 ] #region [ Dispose-Finallizeパターン実装 ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{
this.Dispose(true); this.Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected void Dispose(bool bManagedDispose) protected void Dispose(bool bManagedDispose) {
{
this.SoundDeviceType = ESoundDeviceType.Unknown; // まず出力停止する(Dispose中にクラス内にアクセスされることを防ぐ) this.SoundDeviceType = ESoundDeviceType.Unknown; // まず出力停止する(Dispose中にクラス内にアクセスされることを防ぐ)
if (MainStreamHandle != -1) if (MainStreamHandle != -1) {
{
Bass.StreamFree(this.MainStreamHandle); Bass.StreamFree(this.MainStreamHandle);
} }
if (MixerHandle != -1) if (MixerHandle != -1) {
{
Bass.StreamFree(this.MixerHandle); Bass.StreamFree(this.MixerHandle);
} }
if (!this.IsBASSSoundFree) if (!this.IsBASSSoundFree) {
{
Bass.Stop(); Bass.Stop();
Bass.Free();// システムタイマより先に呼び出すこと。Stream処理() の中でシステムタイマを参照してるため) Bass.Free();// システムタイマより先に呼び出すこと。Stream処理() の中でシステムタイマを参照してるため)
} }
if (bManagedDispose) if (bManagedDispose) {
{
SystemTimer.Dispose(); SystemTimer.Dispose();
this.SystemTimer = null; this.SystemTimer = null;
} }
} }
~CSoundDeviceBASS() ~CSoundDeviceBASS() {
{
this.Dispose(false); this.Dispose(false);
} }
//----------------- //-----------------
#endregion #endregion
public int StreamProc(int handle, IntPtr buffer, int length, IntPtr user) public int StreamProc(int handle, IntPtr buffer, int length, IntPtr user) {
{
// BASSミキサからの出力データをそのまま ASIO buffer へ丸投げ。 // BASSミキサからの出力データをそのまま ASIO buffer へ丸投げ。
int num = Bass.ChannelGetData(this.Mixer_DeviceOut, buffer, length); // num = 実際に転送した長さ int num = Bass.ChannelGetData(this.Mixer_DeviceOut, buffer, length); // num = 実際に転送した長さ

View File

@ -1,76 +1,59 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using ManagedBass; using ManagedBass;
using ManagedBass.Wasapi;
using ManagedBass.Mix; using ManagedBass.Mix;
using ManagedBass.Wasapi;
namespace FDK namespace FDK {
{ internal class CSoundDeviceWASAPI : ISoundDevice {
internal class CSoundDeviceWASAPI : ISoundDevice
{
// プロパティ // プロパティ
public ESoundDeviceType SoundDeviceType public ESoundDeviceType SoundDeviceType {
{
get; get;
protected set; protected set;
} }
public long OutputDelay public long OutputDelay {
{
get; get;
protected set; protected set;
} }
public long BufferSize public long BufferSize {
{
get; get;
protected set; protected set;
} }
// CSoundTimer 用に公開しているプロパティ // CSoundTimer 用に公開しているプロパティ
public long ElapsedTimeMs public long ElapsedTimeMs {
{
get; get;
protected set; protected set;
} }
public long UpdateSystemTimeMs public long UpdateSystemTimeMs {
{
get; get;
protected set; protected set;
} }
public CTimer SystemTimer public CTimer SystemTimer {
{
get; get;
protected set; protected set;
} }
public enum EWASAPIMode { Exclusion, Share } public enum EWASAPIMode { Exclusion, Share }
public int nMasterVolume public int nMasterVolume {
{ get {
get
{
float volume = 0.0f; float volume = 0.0f;
//if ( BassMix.BASS_Mixer_ChannelGetEnvelopePos( this.hMixer, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, ref f音量 ) == -1 ) //if ( BassMix.BASS_Mixer_ChannelGetEnvelopePos( this.hMixer, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, ref f音量 ) == -1 )
// return 100; // return 100;
//bool b = Bass.BASS_ChannelGetAttribute( this.hMixer, BASSAttribute.BASS_ATTRIB_VOL, ref f音量 ); //bool b = Bass.BASS_ChannelGetAttribute( this.hMixer, BASSAttribute.BASS_ATTRIB_VOL, ref f音量 );
bool b = Bass.ChannelGetAttribute(this.hMixer, ChannelAttribute.Volume, out volume); bool b = Bass.ChannelGetAttribute(this.hMixer, ChannelAttribute.Volume, out volume);
if ( !b ) if (!b) {
{
Errors be = Bass.LastError; Errors be = Bass.LastError;
Trace.TraceInformation("WASAPI Master Volume Get Error: " + be.ToString()); Trace.TraceInformation("WASAPI Master Volume Get Error: " + be.ToString());
} } else {
else
{
Trace.TraceInformation("WASAPI Master Volume Get Success: " + (volume * 100)); Trace.TraceInformation("WASAPI Master Volume Get Success: " + (volume * 100));
} }
return (int)(volume * 100); return (int)(volume * 100);
} }
set set {
{
// bool b = Bass.BASS_SetVolume( value / 100.0f ); // bool b = Bass.BASS_SetVolume( value / 100.0f );
// →Exclusiveモード時は無効 // →Exclusiveモード時は無効
@ -88,13 +71,10 @@ namespace FDK
//var nodes = new BASS_MIXER_NODE[ 1 ] { new BASS_MIXER_NODE( 0, (float) value ) }; //var nodes = new BASS_MIXER_NODE[ 1 ] { new BASS_MIXER_NODE( 0, (float) value ) };
//bool b = BassMix.BASS_Mixer_ChannelSetEnvelope( this.hMixer, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, nodes ); //bool b = BassMix.BASS_Mixer_ChannelSetEnvelope( this.hMixer, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, nodes );
//bool b = Bass.BASS_ChannelSetAttribute( this.hMixer, BASSAttribute.BASS_ATTRIB_VOL, value / 100.0f ); //bool b = Bass.BASS_ChannelSetAttribute( this.hMixer, BASSAttribute.BASS_ATTRIB_VOL, value / 100.0f );
if ( !b ) if (!b) {
{
Errors be = Bass.LastError; Errors be = Bass.LastError;
Trace.TraceInformation("WASAPI Master Volume Set Error: " + be.ToString()); Trace.TraceInformation("WASAPI Master Volume Set Error: " + be.ToString());
} } else {
else
{
// int n = this.nMasterVolume; // int n = this.nMasterVolume;
// Trace.TraceInformation( "WASAPI Master Volume Set Success: " + value ); // Trace.TraceInformation( "WASAPI Master Volume Set Success: " + value );
@ -109,8 +89,7 @@ namespace FDK
/// <param name="mode"></param> /// <param name="mode"></param>
/// <param name="bufferSize">(未使用; 本メソッド内で自動設定する)</param> /// <param name="bufferSize">(未使用; 本メソッド内で自動設定する)</param>
/// <param name="interval">(未使用; 本メソッド内で自動設定する)</param> /// <param name="interval">(未使用; 本メソッド内で自動設定する)</param>
public CSoundDeviceWASAPI( EWASAPIMode mode, long bufferSize, long interval ) public CSoundDeviceWASAPI(EWASAPIMode mode, long bufferSize, long interval) {
{
// 初期化。 // 初期化。
Trace.TraceInformation("BASS (WASAPI) の初期化を開始します。"); Trace.TraceInformation("BASS (WASAPI) の初期化を開始します。");
@ -150,12 +129,10 @@ namespace FDK
int a; int a;
string strDefaultSoundDeviceName = null; string strDefaultSoundDeviceName = null;
DeviceInfo[] bassDevInfos = new DeviceInfo[Bass.DeviceCount]; DeviceInfo[] bassDevInfos = new DeviceInfo[Bass.DeviceCount];
for(int j = 0; j < bassDevInfos.Length; j++) for (int j = 0; j < bassDevInfos.Length; j++) {
{
bassDevInfos[j] = Bass.GetDeviceInfo(j); bassDevInfos[j] = Bass.GetDeviceInfo(j);
} }
for (a = 0; a < bassDevInfos.GetLength(0); a++) for (a = 0; a < bassDevInfos.GetLength(0); a++) {
{
{ {
Trace.TraceInformation("Sound Device #{0}: {1}: IsDefault={2}, isEnabled={3}", Trace.TraceInformation("Sound Device #{0}: {1}: IsDefault={2}, isEnabled={3}",
a, a,
@ -163,8 +140,7 @@ namespace FDK
bassDevInfos[a].IsDefault, bassDevInfos[a].IsDefault,
bassDevInfos[a].IsEnabled bassDevInfos[a].IsEnabled
); );
if (bassDevInfos[a].IsDefault) if (bassDevInfos[a].IsDefault) {
{
// これはOS標準のdefault device。後でWASAPIのdefault deviceと比較する。 // これはOS標準のdefault device。後でWASAPIのdefault deviceと比較する。
strDefaultSoundDeviceName = bassDevInfos[a].Name; strDefaultSoundDeviceName = bassDevInfos[a].Name;
} }
@ -185,8 +161,7 @@ namespace FDK
#region [ WASAPIデバイスを検索しmsを設定できる最小値にする ] #region [ WASAPIデバイスを検索しmsを設定できる最小値にする ]
int nDevNo = -1; int nDevNo = -1;
WasapiDeviceInfo deviceInfo; WasapiDeviceInfo deviceInfo;
for (int n = 0; BassWasapi.GetDeviceInfo(n, out deviceInfo); n++) for (int n = 0; BassWasapi.GetDeviceInfo(n, out deviceInfo); n++) {
{
// #37940 2018.2.15: BASS_DEVICEINFOとBASS_WASAPI_DEVICEINFOで、IsDefaultとなっているデバイスが異なる場合がある。 // #37940 2018.2.15: BASS_DEVICEINFOとBASS_WASAPI_DEVICEINFOで、IsDefaultとなっているデバイスが異なる場合がある。
// (WASAPIでIsDefaultとなっているデバイスが正しくない場合がある) // (WASAPIでIsDefaultとなっているデバイスが正しくない場合がある)
// そのため、BASS_DEVICEでIsDefaultとなっているものを探し、それと同じ名前のWASAPIデバイスを使用する。 // そのため、BASS_DEVICEでIsDefaultとなっているものを探し、それと同じ名前のWASAPIデバイスを使用する。
@ -195,8 +170,7 @@ namespace FDK
// (具体的には、defperiod, minperiod, mixchans, mixfreqがすべて0のデバイスは使用不可のため // (具体的には、defperiod, minperiod, mixchans, mixfreqがすべて0のデバイスは使用不可のため
// これらが0でないものを選択する) // これらが0でないものを選択する)
//if ( deviceInfo.IsDefault ) //if ( deviceInfo.IsDefault )
if (deviceInfo.Name == strDefaultSoundDeviceName && deviceInfo.MixFrequency > 0) if (deviceInfo.Name == strDefaultSoundDeviceName && deviceInfo.MixFrequency > 0) {
{
nDevNo = n; nDevNo = n;
#region [ ] #region [ ]
Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, minperiod={4}s, mixchans={5}, mixfreq={6}", Trace.TraceInformation("WASAPI Device #{0}: {1}: IsDefault={2}, defPeriod={3}s, minperiod={4}s, mixchans={5}, mixfreq={6}",
@ -207,8 +181,7 @@ namespace FDK
break; break;
} }
} }
if (nDevNo != -1) if (nDevNo != -1) {
{
Trace.TraceInformation("Start Bass_Init(device=0(fixed value: no sound), deviceInfo.mixfreq=" + deviceInfo.MixFrequency + ", BASS_DEVICE_DEFAULT, Zero)"); Trace.TraceInformation("Start Bass_Init(device=0(fixed value: no sound), deviceInfo.mixfreq=" + deviceInfo.MixFrequency + ", BASS_DEVICE_DEFAULT, Zero)");
if (!Bass.Init(0, deviceInfo.MixFrequency, DeviceInitFlags.Default, IntPtr.Zero)) // device = 0:"no device": BASS からはデバイスへアクセスさせない。アクセスは BASSWASAPI アドオンから行う。 if (!Bass.Init(0, deviceInfo.MixFrequency, DeviceInitFlags.Default, IntPtr.Zero)) // device = 0:"no device": BASS からはデバイスへアクセスさせない。アクセスは BASSWASAPI アドオンから行う。
throw new Exception(string.Format("BASS (WASAPI{0}) の初期化に失敗しました。(BASS_Init)[{1}]", mode.ToString(), Bass.LastError.ToString())); throw new Exception(string.Format("BASS (WASAPI{0}) の初期化に失敗しました。(BASS_Init)[{1}]", mode.ToString(), Bass.LastError.ToString()));
@ -224,9 +197,7 @@ namespace FDK
//{ //{
// n希望バッファサイズms = n更新間隔ms + 1; // 2013.4.25 #31237 yyagi; バッファサイズ設定の完全自動化。更新間隔バッファサイズにするとBASS_ERROR_UNKNOWNになるので+1する。 // n希望バッファサイズms = n更新間隔ms + 1; // 2013.4.25 #31237 yyagi; バッファサイズ設定の完全自動化。更新間隔バッファサイズにするとBASS_ERROR_UNKNOWNになるので+1する。
//} //}
} } else {
else
{
Trace.TraceError("Error: Default WASAPI Device is not found."); Trace.TraceError("Error: Default WASAPI Device is not found.");
} }
#endregion #endregion
@ -235,10 +206,8 @@ namespace FDK
var flags = (mode == EWASAPIMode.Exclusion) ? WasapiInitFlags.AutoFormat | WasapiInitFlags.Exclusive : WasapiInitFlags.Shared | WasapiInitFlags.AutoFormat; var flags = (mode == EWASAPIMode.Exclusion) ? WasapiInitFlags.AutoFormat | WasapiInitFlags.Exclusive : WasapiInitFlags.Shared | WasapiInitFlags.AutoFormat;
//var flags = ( mode == Eデバイスモード.排他 ) ? BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT | BASSWASAPIInit.BASS_WASAPI_EVENT | BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE : BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT | BASSWASAPIInit.BASS_WASAPI_EVENT; //var flags = ( mode == Eデバイスモード.排他 ) ? BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT | BASSWASAPIInit.BASS_WASAPI_EVENT | BASSWASAPIInit.BASS_WASAPI_EXCLUSIVE : BASSWASAPIInit.BASS_WASAPI_AUTOFORMAT | BASSWASAPIInit.BASS_WASAPI_EVENT;
if ( BassWasapi.Init( nデバイス, n周波数, nチャンネル数, flags, ( bufferSize / 1000.0f ), ( interval / 1000.0f ), this.tWasapiProc, IntPtr.Zero ) ) if (BassWasapi.Init(nデバイス, n周波数, nチャンネル数, flags, (bufferSize / 1000.0f), (interval / 1000.0f), this.tWasapiProc, IntPtr.Zero)) {
{ if (mode == EWASAPIMode.Exclusion) {
if( mode == EWASAPIMode.Exclusion )
{
#region [ ] #region [ ]
//----------------- //-----------------
this.SoundDeviceType = ESoundDeviceType.ExclusiveWASAPI; this.SoundDeviceType = ESoundDeviceType.ExclusiveWASAPI;
@ -272,9 +241,7 @@ namespace FDK
this.bIsBASSFree = false; this.bIsBASSFree = false;
//----------------- //-----------------
#endregion #endregion
} } else {
else
{
#region [ ] #region [ ]
//----------------- //-----------------
this.SoundDeviceType = ESoundDeviceType.SharedWASAPI; this.SoundDeviceType = ESoundDeviceType.SharedWASAPI;
@ -315,8 +282,7 @@ namespace FDK
// #endregion // #endregion
//} //}
#endregion #endregion
else else {
{
#region [ ] #region [ ]
//----------------- //-----------------
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
@ -335,8 +301,7 @@ namespace FDK
info.Frequency, info.Frequency,
info.Channels, info.Channels,
BassFlags.MixerNonStop | BassFlags.Float | BassFlags.Decode); // デコードのみ発声しない。WASAPIに出力されるだけ。 BassFlags.MixerNonStop | BassFlags.Float | BassFlags.Decode); // デコードのみ発声しない。WASAPIに出力されるだけ。
if ( this.hMixer == 0 ) if (this.hMixer == 0) {
{
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
BassWasapi.Free(); BassWasapi.Free();
Bass.Free(); Bass.Free();
@ -361,8 +326,7 @@ namespace FDK
info.Frequency, info.Frequency,
info.Channels, info.Channels,
BassFlags.MixerNonStop | BassFlags.Float | BassFlags.Decode); // デコードのみ発声しない。WASAPIに出力されるだけ。 BassFlags.MixerNonStop | BassFlags.Float | BassFlags.Decode); // デコードのみ発声しない。WASAPIに出力されるだけ。
if ( this.hMixer_DeviceOut == 0 ) if (this.hMixer_DeviceOut == 0) {
{
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
BassWasapi.Free(); BassWasapi.Free();
Bass.Free(); Bass.Free();
@ -372,8 +336,7 @@ namespace FDK
{ {
bool b1 = BassMix.MixerAddChannel(this.hMixer_DeviceOut, this.hMixer, BassFlags.Default); bool b1 = BassMix.MixerAddChannel(this.hMixer_DeviceOut, this.hMixer, BassFlags.Default);
if ( !b1 ) if (!b1) {
{
Errors errcode = Bass.LastError; Errors errcode = Bass.LastError;
BassWasapi.Free(); BassWasapi.Free();
Bass.Free(); Bass.Free();
@ -388,46 +351,38 @@ namespace FDK
BassWasapi.Start(); BassWasapi.Start();
} }
#region [ tサウンドを作成する() ] #region [ tサウンドを作成する() ]
public CSound tCreateSound( string strファイル名, ESoundGroup soundGroup ) public CSound tCreateSound(string strファイル名, ESoundGroup soundGroup) {
{
var sound = new CSound(soundGroup); var sound = new CSound(soundGroup);
sound.CreateWASAPISound(strファイル名, this.hMixer, this.SoundDeviceType); sound.CreateWASAPISound(strファイル名, this.hMixer, this.SoundDeviceType);
return sound; return sound;
} }
public void tCreateSound( string strファイル名, CSound sound ) public void tCreateSound(string strファイル名, CSound sound) {
{
sound.CreateWASAPISound(strファイル名, this.hMixer, this.SoundDeviceType); sound.CreateWASAPISound(strファイル名, this.hMixer, this.SoundDeviceType);
} }
#endregion #endregion
#region [ Dispose-Finallizeパターン実装 ] #region [ Dispose-Finallizeパターン実装 ]
//----------------- //-----------------
public void Dispose() public void Dispose() {
{
this.Dispose(true); this.Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected void Dispose( bool bManagedDispose ) protected void Dispose(bool bManagedDispose) {
{
SoundDeviceType = ESoundDeviceType.Unknown; // まず出力停止する(Dispose中にクラス内にアクセスされることを防ぐ) SoundDeviceType = ESoundDeviceType.Unknown; // まず出力停止する(Dispose中にクラス内にアクセスされることを防ぐ)
if ( hMixer != -1 ) if (hMixer != -1) {
{
Bass.StreamFree(hMixer); Bass.StreamFree(hMixer);
} }
if ( !bIsBASSFree ) if (!bIsBASSFree) {
{
BassWasapi.Free(); // システムタイマより先に呼び出すこと。tWasapi処理() の中でシステムタイマを参照してるため) BassWasapi.Free(); // システムタイマより先に呼び出すこと。tWasapi処理() の中でシステムタイマを参照してるため)
Bass.Free(); Bass.Free();
} }
if( bManagedDispose ) if (bManagedDispose) {
{
SystemTimer.Dispose(); SystemTimer.Dispose();
SystemTimer = null; SystemTimer = null;
} }
} }
~CSoundDeviceWASAPI() ~CSoundDeviceWASAPI() {
{
this.Dispose(false); this.Dispose(false);
} }
//----------------- //-----------------
@ -437,8 +392,7 @@ namespace FDK
protected int hMixer_DeviceOut = -1; protected int hMixer_DeviceOut = -1;
protected WasapiProcedure tWasapiProc = null; protected WasapiProcedure tWasapiProc = null;
protected int tWASAPI処理( IntPtr buffer, int length, IntPtr user ) protected int tWASAPI処理(IntPtr buffer, int length, IntPtr user) {
{
// BASSミキサからの出力データをそのまま WASAPI buffer へ丸投げ。 // BASSミキサからの出力データをそのまま WASAPI buffer へ丸投げ。
int num = Bass.ChannelGetData(this.hMixer_DeviceOut, buffer, length); // num = 実際に転送した長さ int num = Bass.ChannelGetData(this.hMixer_DeviceOut, buffer, length); // num = 実際に転送した長さ

View File

@ -1,23 +1,13 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace FDK namespace FDK {
{ public class CSoundTimer : CTimerBase {
public class CSoundTimer : CTimerBase public override long SystemTimeMs {
{ get {
public override long SystemTimeMs
{
get
{
if (this.Device.SoundDeviceType == ESoundDeviceType.Bass || if (this.Device.SoundDeviceType == ESoundDeviceType.Bass ||
this.Device.SoundDeviceType == ESoundDeviceType.ExclusiveWASAPI || this.Device.SoundDeviceType == ESoundDeviceType.ExclusiveWASAPI ||
this.Device.SoundDeviceType == ESoundDeviceType.SharedWASAPI || this.Device.SoundDeviceType == ESoundDeviceType.SharedWASAPI ||
this.Device.SoundDeviceType == ESoundDeviceType.ASIO ) this.Device.SoundDeviceType == ESoundDeviceType.ASIO) {
{
// BASS 系の ISoundDevice.n経過時間ms はオーディオバッファの更新間隔ずつでしか更新されないため、単にこれを返すだけではとびとびの値になる。 // BASS 系の ISoundDevice.n経過時間ms はオーディオバッファの更新間隔ずつでしか更新されないため、単にこれを返すだけではとびとびの値になる。
// そこで、更新間隔の最中に呼ばれた場合は、システムタイマを使って補間する。 // そこで、更新間隔の最中に呼ばれた場合は、システムタイマを使って補間する。
// この場合の経過時間との誤差は更新間隔以内に収まるので問題ないと判断する。 // この場合の経過時間との誤差は更新間隔以内に収まるので問題ないと判断する。
@ -39,16 +29,12 @@ namespace FDK
// 補正部分をゼロにして、n経過時間msだけを返すようにする。 // 補正部分をゼロにして、n経過時間msだけを返すようにする。
// こうすることで、演奏タイマが動作を始めても、破綻しなくなる。 // こうすることで、演奏タイマが動作を始めても、破綻しなくなる。
return this.Device.ElapsedTimeMs; return this.Device.ElapsedTimeMs;
} } else {
else
{
if (FDK.SoundManager.bUseOSTimer) if (FDK.SoundManager.bUseOSTimer)
//if ( true ) //if ( true )
{ {
return ctDInputTimer.SystemTimeMs; // 仮にCSoundTimerをCTimer相当の動作にしてみた return ctDInputTimer.SystemTimeMs; // 仮にCSoundTimerをCTimer相当の動作にしてみた
} } else {
else
{
return this.Device.ElapsedTimeMs return this.Device.ElapsedTimeMs
+ (this.Device.SystemTimer.SystemTimeMs - this.Device.UpdateSystemTimeMs); + (this.Device.SystemTimer.SystemTimeMs - this.Device.UpdateSystemTimeMs);
} }
@ -58,8 +44,7 @@ namespace FDK
} }
} }
internal CSoundTimer( ISoundDevice device ) internal CSoundTimer(ISoundDevice device) {
{
this.Device = device; this.Device = device;
TimerCallback timerDelegate = new TimerCallback(SnapTimers); // CSoundTimerをシステム時刻に変換するために、 TimerCallback timerDelegate = new TimerCallback(SnapTimers); // CSoundTimerをシステム時刻に変換するために、
@ -69,13 +54,11 @@ namespace FDK
private void SnapTimers(object o) // 1秒に1回呼び出され、2つのタイマー間の現在値をそれぞれ保持する。 private void SnapTimers(object o) // 1秒に1回呼び出され、2つのタイマー間の現在値をそれぞれ保持する。
{ {
try try {
{
this.nDInputTimerCounter = this.ctDInputTimer.SystemTimeMs; this.nDInputTimerCounter = this.ctDInputTimer.SystemTimeMs;
this.nSoundTimerCounter = this.SystemTimeMs; this.nSoundTimerCounter = this.SystemTimeMs;
//Debug.WriteLine( "BaseCounter: " + nDInputTimerCounter + ", " + nSoundTimerCounter ); //Debug.WriteLine( "BaseCounter: " + nDInputTimerCounter + ", " + nSoundTimerCounter );
} } catch (Exception e)
catch (Exception e)
// サウンド設定変更時に、timer.Dispose()した後、timerが実際に停止する前にここに来てしまう場合があり // サウンド設定変更時に、timer.Dispose()した後、timerが実際に停止する前にここに来てしまう場合があり
// その際にNullReferenceExceptionが発生する // その際にNullReferenceExceptionが発生する
// timerが実際に停止したことを検出してから次の設定をすべきだが、実装が難しいため、 // timerが実際に停止したことを検出してから次の設定をすべきだが、実装が難しいため、
@ -85,26 +68,22 @@ namespace FDK
Trace.TraceInformation("FDK: CSoundTimer.SnapTimers(): 例外発生しましたが、継続します。"); Trace.TraceInformation("FDK: CSoundTimer.SnapTimers(): 例外発生しましたが、継続します。");
} }
} }
public long nサウンドタイマーのシステム時刻msへの変換( long nDInputのタイムスタンプ ) public long nサウンドタイマーのシステム時刻msへの変換(long nDInputのタイムスタンプ) {
{
return nDInputのタイムスタンプ - this.nDInputTimerCounter + this.nSoundTimerCounter; // Timer違いによる時差を補正する return nDInputのタイムスタンプ - this.nDInputTimerCounter + this.nSoundTimerCounter; // Timer違いによる時差を補正する
} }
public override void Dispose() public override void Dispose() {
{
// 特になし; ISoundDevice の解放は呼び出し元で行うこと。 // 特になし; ISoundDevice の解放は呼び出し元で行うこと。
//sendinputスレッド削除 //sendinputスレッド削除
if ( timer != null ) if (timer != null) {
{
timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);
// ここで、実際にtimerが停止したことを確認するコードを追加すべきだが、やり方わからず。 // ここで、実際にtimerが停止したことを確認するコードを追加すべきだが、やり方わからず。
// 代替策として、SnapTimers()中で、例外発生を破棄している。 // 代替策として、SnapTimers()中で、例外発生を破棄している。
timer.Dispose(); timer.Dispose();
timer = null; timer = null;
} }
if ( ct != null ) if (ct != null) {
{
ct.Pause(); ct.Pause();
ct.Dispose(); ct.Dispose();
ct = null; ct = null;

View File

@ -1,11 +1,5 @@
using System; namespace FDK {
using System.Collections.Generic; public enum ESoundDeviceType {
using System.Text;
namespace FDK
{
public enum ESoundDeviceType
{
Bass, Bass,
ExclusiveWASAPI, ExclusiveWASAPI,
SharedWASAPI, SharedWASAPI,

View File

@ -1,7 +1,5 @@
namespace FDK namespace FDK {
{ public enum ESoundGroup {
public enum ESoundGroup
{
SoundEffect = 1, SoundEffect = 1,
Voice = 2, Voice = 2,
SongPreview = 3, SongPreview = 3,

View File

@ -1,25 +1,17 @@
using System; using ManagedBass;
using System.Collections.Generic;
using System.Text;
using ManagedBass;
using ManagedBass.Mix; using ManagedBass.Mix;
namespace FDK.BassMixExtension namespace FDK.BassMixExtension {
{ public static class BassMixExtensions {
public static class BassMixExtensions public static bool ChannelPlay(int hHandle) {
{
public static bool ChannelPlay(int hHandle)
{
return BassMix.ChannelRemoveFlag(hHandle, BassFlags.MixerChanPause); return BassMix.ChannelRemoveFlag(hHandle, BassFlags.MixerChanPause);
} }
public static bool ChannelPause(int hHandle) public static bool ChannelPause(int hHandle) {
{
return BassMix.ChannelAddFlag(hHandle, BassFlags.MixerChanPause); return BassMix.ChannelAddFlag(hHandle, BassFlags.MixerChanPause);
} }
public static bool ChannelIsPlaying(int hHandle) public static bool ChannelIsPlaying(int hHandle) {
{
return !BassMix.ChannelHasFlag(hHandle, BassFlags.MixerChanPause); return !BassMix.ChannelHasFlag(hHandle, BassFlags.MixerChanPause);
} }
} }

View File

@ -1,12 +1,5 @@
using System; namespace FDK {
using System.Collections.Generic; internal interface ISoundDevice : IDisposable {
using System.Text;
using System.Diagnostics;
namespace FDK
{
internal interface ISoundDevice : IDisposable
{
ESoundDeviceType SoundDeviceType { get; } ESoundDeviceType SoundDeviceType { get; }
int nMasterVolume { get; set; } int nMasterVolume { get; set; }
long OutputDelay { get; } long OutputDelay { get; }

View File

@ -1,20 +1,15 @@
using System; namespace FDK {
namespace FDK
{
/// <summary> /// <summary>
/// The LoudnessMetadata structure is used to carry, and assist with /// The LoudnessMetadata structure is used to carry, and assist with
/// calculations related to, integrated loudness and true peak /// calculations related to, integrated loudness and true peak
/// loudness. /// loudness.
/// </summary> /// </summary>
[Serializable] [Serializable]
public struct LoudnessMetadata public struct LoudnessMetadata {
{
public readonly Lufs Integrated; public readonly Lufs Integrated;
public readonly Lufs? TruePeak; public readonly Lufs? TruePeak;
public LoudnessMetadata(Lufs integrated, Lufs? truePeak) public LoudnessMetadata(Lufs integrated, Lufs? truePeak) {
{
Integrated = integrated; Integrated = integrated;
TruePeak = truePeak; TruePeak = truePeak;
} }

View File

@ -1,14 +1,8 @@
using System; using System.ComponentModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml.XPath; using System.Xml.XPath;
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// The LoudnessMetadataScanner plays two roles: /// The LoudnessMetadataScanner plays two roles:
/// 1. Scanning of song audio files using BS1770GAIN (http://bs1770gain.sourceforge.net/) /// 1. Scanning of song audio files using BS1770GAIN (http://bs1770gain.sourceforge.net/)
@ -26,8 +20,7 @@ namespace FDK
/// SongGainController for combination with a configured target loudness, resulting in a /// SongGainController for combination with a configured target loudness, resulting in a
/// gain value assigned to the sound object just before playback begins. /// gain value assigned to the sound object just before playback begins.
/// </summary> /// </summary>
public static class LoudnessMetadataScanner public static class LoudnessMetadataScanner {
{
private const string Bs1770GainExeFileName = "bs1770gain.exe"; private const string Bs1770GainExeFileName = "bs1770gain.exe";
private static readonly Stack<string> Jobs = new Stack<string>(); private static readonly Stack<string> Jobs = new Stack<string>();
@ -37,23 +30,19 @@ namespace FDK
private static Thread ScanningThread; private static Thread ScanningThread;
private static Semaphore Semaphore; private static Semaphore Semaphore;
public static void StartBackgroundScanning() public static void StartBackgroundScanning() {
{
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(StartBackgroundScanning)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(StartBackgroundScanning)}";
if (!IsBs1770GainAvailable()) if (!IsBs1770GainAvailable()) {
{
Trace.TraceInformation($"{tracePrefix}: BS1770GAIN is not available. A background scanning thread will not be started."); Trace.TraceInformation($"{tracePrefix}: BS1770GAIN is not available. A background scanning thread will not be started.");
return; return;
} }
Trace.TraceInformation($"{tracePrefix}: BS1770GAIN is available. Starting background scanning thread..."); Trace.TraceInformation($"{tracePrefix}: BS1770GAIN is available. Starting background scanning thread...");
lock (LockObject) lock (LockObject) {
{
Semaphore = new Semaphore(Jobs.Count, int.MaxValue); Semaphore = new Semaphore(Jobs.Count, int.MaxValue);
ScanningThread = new Thread(Scan) ScanningThread = new Thread(Scan) {
{
IsBackground = true, IsBackground = true,
Name = "LoudnessMetadataScanner background scanning thread.", Name = "LoudnessMetadataScanner background scanning thread.",
Priority = ThreadPriority.Lowest Priority = ThreadPriority.Lowest
@ -64,12 +53,10 @@ namespace FDK
Trace.TraceInformation($"{tracePrefix}: Background scanning thread started."); Trace.TraceInformation($"{tracePrefix}: Background scanning thread started.");
} }
public static void StopBackgroundScanning(bool joinImmediately) public static void StopBackgroundScanning(bool joinImmediately) {
{
var scanningThread = ScanningThread; var scanningThread = ScanningThread;
if (scanningThread == null) if (scanningThread == null) {
{
return; return;
} }
@ -77,36 +64,29 @@ namespace FDK
Trace.TraceInformation($"{tracePrefix}: Stopping background scanning thread..."); Trace.TraceInformation($"{tracePrefix}: Stopping background scanning thread...");
lock (LockObject) lock (LockObject) {
{
ScanningThread = null; ScanningThread = null;
Semaphore.Release(); Semaphore.Release();
Semaphore = null; Semaphore = null;
} }
if (joinImmediately) if (joinImmediately) {
{
scanningThread.Join(); scanningThread.Join();
} }
Trace.TraceInformation($"{tracePrefix}: Background scanning thread stopped."); Trace.TraceInformation($"{tracePrefix}: Background scanning thread stopped.");
} }
public static LoudnessMetadata? LoadForAudioPath(string absoluteBgmPath) public static LoudnessMetadata? LoadForAudioPath(string absoluteBgmPath) {
{ try {
try
{
var loudnessMetadataPath = GetLoudnessMetadataPath(absoluteBgmPath); var loudnessMetadataPath = GetLoudnessMetadataPath(absoluteBgmPath);
if (File.Exists(loudnessMetadataPath)) if (File.Exists(loudnessMetadataPath)) {
{
return LoadFromMetadataPath(loudnessMetadataPath); return LoadFromMetadataPath(loudnessMetadataPath);
} }
SubmitForBackgroundScanning(absoluteBgmPath); SubmitForBackgroundScanning(absoluteBgmPath);
} } catch (Exception e) {
catch (Exception e)
{
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadForAudioPath)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadForAudioPath)}";
Trace.TraceError($"{tracePrefix}: Encountered an exception while attempting to load {absoluteBgmPath}"); Trace.TraceError($"{tracePrefix}: Encountered an exception while attempting to load {absoluteBgmPath}");
Trace.TraceError(e.ToString()); Trace.TraceError(e.ToString());
@ -115,22 +95,17 @@ namespace FDK
return null; return null;
} }
private static string GetLoudnessMetadataPath(string absoluteBgmPath) private static string GetLoudnessMetadataPath(string absoluteBgmPath) {
{
return Path.Combine( return Path.Combine(
Path.GetDirectoryName(absoluteBgmPath), Path.GetDirectoryName(absoluteBgmPath),
Path.GetFileNameWithoutExtension(absoluteBgmPath) + ".bs1770gain.xml"); Path.GetFileNameWithoutExtension(absoluteBgmPath) + ".bs1770gain.xml");
} }
private static LoudnessMetadata? LoadFromMetadataPath(string loudnessMetadataPath) private static LoudnessMetadata? LoadFromMetadataPath(string loudnessMetadataPath) {
{
XPathDocument xPathDocument; XPathDocument xPathDocument;
try try {
{
xPathDocument = new XPathDocument(loudnessMetadataPath); xPathDocument = new XPathDocument(loudnessMetadataPath);
} } catch (IOException) {
catch (IOException)
{
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadFromMetadataPath)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadFromMetadataPath)}";
Trace.TraceWarning($"{tracePrefix}: Encountered IOException while attempting to read {loudnessMetadataPath}. This can occur when attempting to load while scanning the same file. Returning null..."); Trace.TraceWarning($"{tracePrefix}: Encountered IOException while attempting to read {loudnessMetadataPath}. This can occur when attempting to load while scanning the same file. Returning null...");
return null; return null;
@ -142,8 +117,7 @@ namespace FDK
var integratedLufsNode = trackNavigator?.SelectSingleNode(@"integrated/@lufs"); var integratedLufsNode = trackNavigator?.SelectSingleNode(@"integrated/@lufs");
var truePeakTpfsNode = trackNavigator?.SelectSingleNode(@"true-peak/@tpfs"); var truePeakTpfsNode = trackNavigator?.SelectSingleNode(@"true-peak/@tpfs");
if (trackNavigator == null || integratedLufsNode == null || truePeakTpfsNode == null) if (trackNavigator == null || integratedLufsNode == null || truePeakTpfsNode == null) {
{
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadFromMetadataPath)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadFromMetadataPath)}";
Trace.TraceWarning($"{tracePrefix}: Encountered incorrect xml element structure while parsing {loudnessMetadataPath}. Returning null..."); Trace.TraceWarning($"{tracePrefix}: Encountered incorrect xml element structure while parsing {loudnessMetadataPath}. Returning null...");
return null; return null;
@ -152,8 +126,7 @@ namespace FDK
var integrated = integratedLufsNode.ValueAsDouble; var integrated = integratedLufsNode.ValueAsDouble;
var truePeak = truePeakTpfsNode.ValueAsDouble; var truePeak = truePeakTpfsNode.ValueAsDouble;
if (integrated <= -70.0 || truePeak >= 12.04) if (integrated <= -70.0 || truePeak >= 12.04) {
{
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadFromMetadataPath)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(LoadFromMetadataPath)}";
Trace.TraceWarning($"{tracePrefix}: Encountered evidence of extreme clipping while parsing {loudnessMetadataPath}. Returning null..."); Trace.TraceWarning($"{tracePrefix}: Encountered evidence of extreme clipping while parsing {loudnessMetadataPath}. Returning null...");
return null; return null;
@ -162,10 +135,8 @@ namespace FDK
return new LoudnessMetadata(new Lufs(integrated), new Lufs(truePeak)); return new LoudnessMetadata(new Lufs(integrated), new Lufs(truePeak));
} }
private static void SubmitForBackgroundScanning(string absoluteBgmPath) private static void SubmitForBackgroundScanning(string absoluteBgmPath) {
{ lock (LockObject) {
lock (LockObject)
{
// Quite often, the loading process will cause the same job to be submitted many times. // Quite often, the loading process will cause the same job to be submitted many times.
// As such, we'll do a quick check as when this happens an equivalent job will often // As such, we'll do a quick check as when this happens an equivalent job will often
// already be at the top of the stack and we need not add it again. // already be at the top of the stack and we need not add it again.
@ -178,26 +149,21 @@ namespace FDK
// scrolling through songs and previewing them. Their current interests should drive // scrolling through songs and previewing them. Their current interests should drive
// scanning priorities, and it is for this reason that a stack is used instead of a queue. // scanning priorities, and it is for this reason that a stack is used instead of a queue.
var semaphore = Semaphore; var semaphore = Semaphore;
if (semaphore != null && (Jobs.Count == 0 || Jobs.Peek() != absoluteBgmPath)) if (semaphore != null && (Jobs.Count == 0 || Jobs.Peek() != absoluteBgmPath)) {
{
Jobs.Push(absoluteBgmPath); Jobs.Push(absoluteBgmPath);
semaphore.Release(); semaphore.Release();
} }
} }
} }
private static void Scan() private static void Scan() {
{ try {
try while (true) {
{
while (true)
{
RaiseScanningStateChanged(false); RaiseScanningStateChanged(false);
Semaphore?.WaitOne(); Semaphore?.WaitOne();
if (ScanningThread == null) if (ScanningThread == null) {
{
return; return;
} }
@ -205,26 +171,22 @@ namespace FDK
int jobCount; int jobCount;
string absoluteBgmPath; string absoluteBgmPath;
lock (LockObject) lock (LockObject) {
{
jobCount = Jobs.Count; jobCount = Jobs.Count;
absoluteBgmPath = Jobs.Pop(); absoluteBgmPath = Jobs.Pop();
} }
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(Scan)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(Scan)}";
try try {
{ if (!File.Exists(absoluteBgmPath)) {
if (!File.Exists(absoluteBgmPath))
{
Trace.TraceWarning($"{tracePrefix}: Scanning jobs outstanding: {jobCount - 1}. Missing audio file. Skipping {absoluteBgmPath}..."); Trace.TraceWarning($"{tracePrefix}: Scanning jobs outstanding: {jobCount - 1}. Missing audio file. Skipping {absoluteBgmPath}...");
continue; continue;
} }
var loudnessMetadataPath = GetLoudnessMetadataPath(absoluteBgmPath); var loudnessMetadataPath = GetLoudnessMetadataPath(absoluteBgmPath);
if (File.Exists(loudnessMetadataPath)) if (File.Exists(loudnessMetadataPath)) {
{
Trace.TraceWarning($"{tracePrefix}: Scanning jobs outstanding: {jobCount - 1}. Pre-existing metadata. Skipping {absoluteBgmPath}..."); Trace.TraceWarning($"{tracePrefix}: Scanning jobs outstanding: {jobCount - 1}. Pre-existing metadata. Skipping {absoluteBgmPath}...");
continue; continue;
} }
@ -238,41 +200,30 @@ namespace FDK
var seconds = stopwatch.Elapsed.TotalSeconds; var seconds = stopwatch.Elapsed.TotalSeconds;
RecentFileScanDurations.Enqueue(seconds); RecentFileScanDurations.Enqueue(seconds);
while (RecentFileScanDurations.Count > 20) while (RecentFileScanDurations.Count > 20) {
{
RecentFileScanDurations.Dequeue(); RecentFileScanDurations.Dequeue();
} }
var averageSeconds = RecentFileScanDurations.Average(); var averageSeconds = RecentFileScanDurations.Average();
Trace.TraceInformation($"{tracePrefix}: Scanned in {seconds}s. Estimated remaining: {(int)(averageSeconds * (jobCount - 1))}s."); Trace.TraceInformation($"{tracePrefix}: Scanned in {seconds}s. Estimated remaining: {(int)(averageSeconds * (jobCount - 1))}s.");
} } catch (Exception e) {
catch (Exception e)
{
Trace.TraceError($"{tracePrefix}: Encountered an exception while attempting to scan {absoluteBgmPath}"); Trace.TraceError($"{tracePrefix}: Encountered an exception while attempting to scan {absoluteBgmPath}");
Trace.TraceError(e.ToString()); Trace.TraceError(e.ToString());
} }
} }
} } catch (Exception e) {
catch (Exception e)
{
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(Scan)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(Scan)}";
Trace.TraceError($"{tracePrefix}: caught an exception at the level of the thread method. The background scanning thread will now terminate."); Trace.TraceError($"{tracePrefix}: caught an exception at the level of the thread method. The background scanning thread will now terminate.");
Trace.TraceError(e.ToString()); Trace.TraceError(e.ToString());
} }
} }
private static bool IsBs1770GainAvailable() private static bool IsBs1770GainAvailable() {
{ try {
try
{
Execute(null, Bs1770GainExeFileName, "-h"); Execute(null, Bs1770GainExeFileName, "-h");
return true; return true;
} } catch (Win32Exception) {
catch (Win32Exception)
{
return false; return false;
} } catch (Exception e) {
catch (Exception e)
{
var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(IsBs1770GainAvailable)}"; var tracePrefix = $"{nameof(LoudnessMetadataScanner)}.{nameof(IsBs1770GainAvailable)}";
Trace.TraceError($"{tracePrefix}: Encountered an exception. Returning false..."); Trace.TraceError($"{tracePrefix}: Encountered an exception. Returning false...");
Trace.TraceError(e.ToString()); Trace.TraceError(e.ToString());
@ -282,10 +233,8 @@ namespace FDK
} }
private static string Execute( private static string Execute(
string workingDirectory, string fileName, string arguments, bool shouldFailOnStdErrDataReceived = false) string workingDirectory, string fileName, string arguments, bool shouldFailOnStdErrDataReceived = false) {
{ var processStartInfo = new ProcessStartInfo(fileName, arguments) {
var processStartInfo = new ProcessStartInfo(fileName, arguments)
{
CreateNoWindow = true, CreateNoWindow = true,
RedirectStandardError = true, RedirectStandardError = true,
RedirectStandardOutput = true, RedirectStandardOutput = true,
@ -295,22 +244,17 @@ namespace FDK
var stdoutWriter = new StringWriter(); var stdoutWriter = new StringWriter();
var stderrWriter = new StringWriter(); var stderrWriter = new StringWriter();
using (var process = Process.Start(processStartInfo)) using (var process = Process.Start(processStartInfo)) {
{ process.OutputDataReceived += (s, e) => {
process.OutputDataReceived += (s, e) => if (e.Data != null) {
{
if (e.Data != null)
{
stdoutWriter.Write(e.Data); stdoutWriter.Write(e.Data);
stdoutWriter.Write(Environment.NewLine); stdoutWriter.Write(Environment.NewLine);
} }
}; };
var errorDataReceived = false; var errorDataReceived = false;
process.ErrorDataReceived += (s, e) => process.ErrorDataReceived += (s, e) => {
{ if (e.Data != null) {
if (e.Data != null)
{
errorDataReceived = true; errorDataReceived = true;
stderrWriter.Write(e.Data); stderrWriter.Write(e.Data);
stderrWriter.Write(Environment.NewLine); stderrWriter.Write(Environment.NewLine);
@ -321,11 +265,9 @@ namespace FDK
process.BeginErrorReadLine(); process.BeginErrorReadLine();
process.WaitForExit(); process.WaitForExit();
if ((shouldFailOnStdErrDataReceived && errorDataReceived) || process.ExitCode != 0) if ((shouldFailOnStdErrDataReceived && errorDataReceived) || process.ExitCode != 0) {
{
var stderr = stderrWriter.ToString(); var stderr = stderrWriter.ToString();
if (string.IsNullOrEmpty(stderr)) if (string.IsNullOrEmpty(stderr)) {
{
stderr = stdoutWriter.ToString(); stderr = stdoutWriter.ToString();
} }
@ -337,15 +279,12 @@ namespace FDK
} }
} }
private static void RaiseScanningStateChanged(bool isActivelyScanning) private static void RaiseScanningStateChanged(bool isActivelyScanning) {
{
ScanningStateChanged?.Invoke(null, new ScanningStateChangedEventArgs(isActivelyScanning)); ScanningStateChanged?.Invoke(null, new ScanningStateChangedEventArgs(isActivelyScanning));
} }
public class ScanningStateChangedEventArgs : EventArgs public class ScanningStateChangedEventArgs : EventArgs {
{ public ScanningStateChangedEventArgs(bool isActivelyScanning) {
public ScanningStateChangedEventArgs(bool isActivelyScanning)
{
IsActivelyScanning = isActivelyScanning; IsActivelyScanning = isActivelyScanning;
} }

View File

@ -1,46 +1,36 @@
using System; namespace FDK {
namespace FDK
{
/// <summary> /// <summary>
/// The Lufs structure is used to carry, and assist with calculations related to, /// The Lufs structure is used to carry, and assist with calculations related to,
/// Loudness Units relative to Full Scale. LUFS are measured in absolute scale /// Loudness Units relative to Full Scale. LUFS are measured in absolute scale
/// and whole values represent one decibel. /// and whole values represent one decibel.
/// </summary> /// </summary>
[Serializable] [Serializable]
public struct Lufs public struct Lufs {
{
private readonly double _value; private readonly double _value;
public Lufs(double value) public Lufs(double value) {
{
_value = value; _value = value;
} }
public double ToDouble() => _value; public double ToDouble() => _value;
public Lufs Min(Lufs lufs) public Lufs Min(Lufs lufs) {
{
return new Lufs(Math.Min(_value, lufs._value)); return new Lufs(Math.Min(_value, lufs._value));
} }
public Lufs Negate() public Lufs Negate() {
{
return new Lufs(-_value); return new Lufs(-_value);
} }
public override string ToString() public override string ToString() {
{
return _value.ToString(); return _value.ToString();
} }
public static Lufs operator- (Lufs left, Lufs right) public static Lufs operator -(Lufs left, Lufs right) {
{
return new Lufs(left._value - right._value); return new Lufs(left._value - right._value);
} }
public static Lufs operator+ (Lufs left, Lufs right) public static Lufs operator +(Lufs left, Lufs right) {
{
return new Lufs(left._value + right._value); return new Lufs(left._value + right._value);
} }
} }

View File

@ -1,5 +1,4 @@
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// SongGainController provides a central place through which song preview /// SongGainController provides a central place through which song preview
/// and song playback attempt to apply BS1770GAIN-based loudness metadata /// and song playback attempt to apply BS1770GAIN-based loudness metadata
@ -9,22 +8,17 @@
/// song (preview) CSound object, SongGainController can override the Gain /// song (preview) CSound object, SongGainController can override the Gain
/// value based on configuration or other information. /// value based on configuration or other information.
/// </summary> /// </summary>
public sealed class SongGainController public sealed class SongGainController {
{
public bool ApplyLoudnessMetadata { private get; set; } public bool ApplyLoudnessMetadata { private get; set; }
public Lufs TargetLoudness { private get; set; } public Lufs TargetLoudness { private get; set; }
public bool ApplySongVol { private get; set; } public bool ApplySongVol { private get; set; }
public void Set(int songVol, LoudnessMetadata? songLoudnessMetadata, CSound sound) public void Set(int songVol, LoudnessMetadata? songLoudnessMetadata, CSound sound) {
{ if (ApplyLoudnessMetadata && songLoudnessMetadata.HasValue) {
if (ApplyLoudnessMetadata && songLoudnessMetadata.HasValue)
{
var gain = TargetLoudness - songLoudnessMetadata.Value.Integrated; var gain = TargetLoudness - songLoudnessMetadata.Value.Integrated;
sound.SetGain(gain, songLoudnessMetadata.Value.TruePeak); sound.SetGain(gain, songLoudnessMetadata.Value.TruePeak);
} } else {
else
{
sound.SetGain(ApplySongVol ? songVol : CSound.DefaultSongVol); sound.SetGain(ApplySongVol ? songVol : CSound.DefaultSongVol);
} }
} }

View File

@ -1,11 +1,8 @@
using System; using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using FDK.ExtensionMethods; using FDK.ExtensionMethods;
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// SoundGroupLevelController holds the current sound level value for each /// SoundGroupLevelController holds the current sound level value for each
/// of the unique sound groups, along with an increment by which they can /// of the unique sound groups, along with an increment by which they can
@ -33,10 +30,8 @@ namespace FDK
/// all existing sound objects group levels by iterating that same /// all existing sound objects group levels by iterating that same
/// observable collection. /// observable collection.
/// </summary> /// </summary>
public sealed class SoundGroupLevelController public sealed class SoundGroupLevelController {
{ private readonly Dictionary<ESoundGroup, int> _levelBySoundGroup = new Dictionary<ESoundGroup, int> {
private readonly Dictionary<ESoundGroup, int> _levelBySoundGroup = new Dictionary<ESoundGroup, int>
{
[ESoundGroup.SoundEffect] = CSound.MaximumGroupLevel, [ESoundGroup.SoundEffect] = CSound.MaximumGroupLevel,
[ESoundGroup.Voice] = CSound.MaximumGroupLevel, [ESoundGroup.Voice] = CSound.MaximumGroupLevel,
[ESoundGroup.SongPreview] = CSound.MaximumGroupLevel, [ESoundGroup.SongPreview] = CSound.MaximumGroupLevel,
@ -48,28 +43,23 @@ namespace FDK
private int _keyboardSoundLevelIncrement; private int _keyboardSoundLevelIncrement;
public SoundGroupLevelController(ObservableCollection<CSound> sounds) public SoundGroupLevelController(ObservableCollection<CSound> sounds) {
{
_sounds = sounds; _sounds = sounds;
_sounds.CollectionChanged += SoundsOnCollectionChanged; _sounds.CollectionChanged += SoundsOnCollectionChanged;
} }
public void SetLevel(ESoundGroup soundGroup, int level) public void SetLevel(ESoundGroup soundGroup, int level) {
{
var clampedLevel = level.Clamp(CSound.MinimumGroupLevel, CSound.MaximumGroupLevel); var clampedLevel = level.Clamp(CSound.MinimumGroupLevel, CSound.MaximumGroupLevel);
if (_levelBySoundGroup[soundGroup] == clampedLevel) if (_levelBySoundGroup[soundGroup] == clampedLevel) {
{
return; return;
} }
_levelBySoundGroup[soundGroup] = clampedLevel; _levelBySoundGroup[soundGroup] = clampedLevel;
foreach (var sound in _sounds) foreach (var sound in _sounds) {
{ if (sound.SoundGroup == soundGroup) {
if (sound.SoundGroup == soundGroup)
{
SetLevel(sound); SetLevel(sound);
} }
} }
@ -77,13 +67,11 @@ namespace FDK
RaiseLevelChanged(soundGroup, clampedLevel); RaiseLevelChanged(soundGroup, clampedLevel);
} }
public void SetKeyboardSoundLevelIncrement(int keyboardSoundLevelIncrement) public void SetKeyboardSoundLevelIncrement(int keyboardSoundLevelIncrement) {
{
_keyboardSoundLevelIncrement = keyboardSoundLevelIncrement; _keyboardSoundLevelIncrement = keyboardSoundLevelIncrement;
} }
public void AdjustLevel(ESoundGroup soundGroup, bool isAdjustmentPositive) public void AdjustLevel(ESoundGroup soundGroup, bool isAdjustmentPositive) {
{
var adjustmentIncrement = isAdjustmentPositive var adjustmentIncrement = isAdjustmentPositive
? _keyboardSoundLevelIncrement ? _keyboardSoundLevelIncrement
: -_keyboardSoundLevelIncrement; : -_keyboardSoundLevelIncrement;
@ -91,34 +79,27 @@ namespace FDK
SetLevel(soundGroup, _levelBySoundGroup[soundGroup] + adjustmentIncrement); SetLevel(soundGroup, _levelBySoundGroup[soundGroup] + adjustmentIncrement);
} }
private void SetLevel(CSound sound) private void SetLevel(CSound sound) {
{
sound.GroupLevel = _levelBySoundGroup[sound.SoundGroup]; sound.GroupLevel = _levelBySoundGroup[sound.SoundGroup];
} }
private void SoundsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) private void SoundsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
{ switch (e.Action) {
switch (e.Action)
{
case NotifyCollectionChangedAction.Add: case NotifyCollectionChangedAction.Add:
case NotifyCollectionChangedAction.Replace: case NotifyCollectionChangedAction.Replace:
foreach (CSound sound in e.NewItems) foreach (CSound sound in e.NewItems) {
{
SetLevel(sound); SetLevel(sound);
} }
break; break;
} }
} }
private void RaiseLevelChanged(ESoundGroup soundGroup, int level) private void RaiseLevelChanged(ESoundGroup soundGroup, int level) {
{
LevelChanged?.Invoke(this, new LevelChangedEventArgs(soundGroup, level)); LevelChanged?.Invoke(this, new LevelChangedEventArgs(soundGroup, level));
} }
public class LevelChangedEventArgs : EventArgs public class LevelChangedEventArgs : EventArgs {
{ public LevelChangedEventArgs(ESoundGroup soundGroup, int level) {
public LevelChangedEventArgs(ESoundGroup soundGroup, int level)
{
SoundGroup = soundGroup; SoundGroup = soundGroup;
Level = level; Level = level;
} }

View File

@ -1,30 +1,15 @@
using System;
using System.Collections.ObjectModel;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Linq;
using System.Threading;
using FDK.ExtensionMethods;
using ManagedBass; using ManagedBass;
using ManagedBass.Asio;
using ManagedBass.Wasapi;
using ManagedBass.Mix;
using ManagedBass.Fx;
using Silk.NET.Windowing; using Silk.NET.Windowing;
using FDK.BassMixExtension;
namespace FDK namespace FDK {
{
public class SoundManager // : CSound public class SoundManager // : CSound
{ {
private static ISoundDevice SoundDevice private static ISoundDevice SoundDevice {
{
get; set; get; set;
} }
private static ESoundDeviceType SoundDeviceType private static ESoundDeviceType SoundDeviceType {
{
get; set; get; set;
} }
public static CSoundTimer PlayTimer = null; public static CSoundTimer PlayTimer = null;
@ -40,10 +25,8 @@ namespace FDK
private static IWindow Window_; private static IWindow Window_;
private static int _nMasterVolume; private static int _nMasterVolume;
public int nMasterVolume public int nMasterVolume {
{ get {
get
{
return _nMasterVolume; return _nMasterVolume;
} }
//get //get
@ -90,8 +73,7 @@ namespace FDK
// BassMix.BASS_Mixer_ChannelSetEnvelope( SoundDevice.hMixer, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, nodes ); // BassMix.BASS_Mixer_ChannelSetEnvelope( SoundDevice.hMixer, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, nodes );
// } // }
//} //}
set set {
{
SoundDevice.nMasterVolume = value; SoundDevice.nMasterVolume = value;
_nMasterVolume = value; _nMasterVolume = value;
} }
@ -105,13 +87,11 @@ namespace FDK
//public static bool bIsMP3DecodeByWindowsCodec = false; //public static bool bIsMP3DecodeByWindowsCodec = false;
public static int nMixing = 0; public static int nMixing = 0;
public int GetMixingStreams() public int GetMixingStreams() {
{
return nMixing; return nMixing;
} }
public static int nStreams = 0; public static int nStreams = 0;
public int GetStreams() public int GetStreams() {
{
return nStreams; return nStreams;
} }
#region [ WASAPI/ASIO/DirectSound設定値 ] #region [ WASAPI/ASIO/DirectSound設定値 ]
@ -120,12 +100,10 @@ namespace FDK
/// <para>0以下の値を指定すると、この数値はWASAPI初期化時に自動設定する。正数を指定すると、その値を設定しようと試みる。</para> /// <para>0以下の値を指定すると、この数値はWASAPI初期化時に自動設定する。正数を指定すると、その値を設定しようと試みる。</para>
/// </summary> /// </summary>
public static int SoundDelayExclusiveWASAPI = 0; // SSTでは、50ms public static int SoundDelayExclusiveWASAPI = 0; // SSTでは、50ms
public int GetSoundExclusiveWASAPI() public int GetSoundExclusiveWASAPI() {
{
return SoundDelayExclusiveWASAPI; return SoundDelayExclusiveWASAPI;
} }
public void SetSoundDelayExclusiveWASAPI( int value ) public void SetSoundDelayExclusiveWASAPI(int value) {
{
SoundDelayExclusiveWASAPI = value; SoundDelayExclusiveWASAPI = value;
} }
/// <summary> /// <summary>
@ -158,21 +136,17 @@ namespace FDK
/// <para>ASIO 出力におけるバッファサイズ。</para> /// <para>ASIO 出力におけるバッファサイズ。</para>
/// </summary> /// </summary>
public static int SoundDelayASIO = 0; // 0にすると、デバイスの設定値をそのまま使う。 public static int SoundDelayASIO = 0; // 0にすると、デバイスの設定値をそのまま使う。
public int GetSoundDelayASIO() public int GetSoundDelayASIO() {
{
return SoundDelayASIO; return SoundDelayASIO;
} }
public void SetSoundDelayASIO(int value) public void SetSoundDelayASIO(int value) {
{
SoundDelayASIO = value; SoundDelayASIO = value;
} }
public static int ASIODevice = 0; public static int ASIODevice = 0;
public int GetASIODevice() public int GetASIODevice() {
{
return ASIODevice; return ASIODevice;
} }
public void SetASIODevice(int value) public void SetASIODevice(int value) {
{
ASIODevice = value; ASIODevice = value;
} }
/// <summary> /// <summary>
@ -180,14 +154,10 @@ namespace FDK
/// </summary> /// </summary>
public static int SoundDelayDirectSound = 100; public static int SoundDelayDirectSound = 100;
public long GetSoundDelay() public long GetSoundDelay() {
{ if (SoundDevice != null) {
if ( SoundDevice != null )
{
return SoundDevice.BufferSize; return SoundDevice.BufferSize;
} } else {
else
{
return -1; return -1;
} }
} }
@ -203,15 +173,13 @@ namespace FDK
/// <param name="nSoundDelayExclusiveWASAPI"></param> /// <param name="nSoundDelayExclusiveWASAPI"></param>
/// <param name="nSoundDelayASIO"></param> /// <param name="nSoundDelayASIO"></param>
/// <param name="nASIODevice"></param> /// <param name="nASIODevice"></param>
public SoundManager( IWindow window, ESoundDeviceType soundDeviceType, int nSoundDelayBASS, int nSoundDelayExclusiveWASAPI, int nSoundDelayASIO, int nASIODevice, bool _bUseOSTimer ) public SoundManager(IWindow window, ESoundDeviceType soundDeviceType, int nSoundDelayBASS, int nSoundDelayExclusiveWASAPI, int nSoundDelayASIO, int nASIODevice, bool _bUseOSTimer) {
{
Window_ = window; Window_ = window;
SoundDevice = null; SoundDevice = null;
//bUseOSTimer = false; //bUseOSTimer = false;
tInitialize(soundDeviceType, nSoundDelayBASS, nSoundDelayExclusiveWASAPI, nSoundDelayASIO, nASIODevice, _bUseOSTimer); tInitialize(soundDeviceType, nSoundDelayBASS, nSoundDelayExclusiveWASAPI, nSoundDelayASIO, nASIODevice, _bUseOSTimer);
} }
public void Dispose() public void Dispose() {
{
t終了(); t終了();
} }
@ -220,21 +188,18 @@ namespace FDK
// t初期化( ESoundDeviceType.DirectSound, 0, 0, 0 ); // t初期化( ESoundDeviceType.DirectSound, 0, 0, 0 );
//} //}
public void tInitialize( ESoundDeviceType soundDeviceType, int _nSoundDelayBASS, int _nSoundDelayExclusiveWASAPI, int _nSoundDelayASIO, int _nASIODevice, IntPtr handle ) public void tInitialize(ESoundDeviceType soundDeviceType, int _nSoundDelayBASS, int _nSoundDelayExclusiveWASAPI, int _nSoundDelayASIO, int _nASIODevice, IntPtr handle) {
{
//if ( !bInitialized ) //if ( !bInitialized )
{ {
tInitialize(soundDeviceType, _nSoundDelayBASS, _nSoundDelayExclusiveWASAPI, _nSoundDelayASIO, _nASIODevice); tInitialize(soundDeviceType, _nSoundDelayBASS, _nSoundDelayExclusiveWASAPI, _nSoundDelayASIO, _nASIODevice);
//bInitialized = true; //bInitialized = true;
} }
} }
public void tInitialize( ESoundDeviceType soundDeviceType, int _nSoundDelayBASS, int _nSoundDelayExclusiveWASAPI, int _nSoundDelayASIO, int _nASIODevice ) public void tInitialize(ESoundDeviceType soundDeviceType, int _nSoundDelayBASS, int _nSoundDelayExclusiveWASAPI, int _nSoundDelayASIO, int _nASIODevice) {
{
tInitialize(soundDeviceType, _nSoundDelayBASS, _nSoundDelayExclusiveWASAPI, _nSoundDelayASIO, _nASIODevice, false); tInitialize(soundDeviceType, _nSoundDelayBASS, _nSoundDelayExclusiveWASAPI, _nSoundDelayASIO, _nASIODevice, false);
} }
public void tInitialize( ESoundDeviceType soundDeviceType, int _nSoundDelayBASS, int _nSoundDelayExclusiveWASAPI, int _nSoundDelayASIO, int _nASIODevice, bool _bUseOSTimer ) public void tInitialize(ESoundDeviceType soundDeviceType, int _nSoundDelayBASS, int _nSoundDelayExclusiveWASAPI, int _nSoundDelayASIO, int _nASIODevice, bool _bUseOSTimer) {
{
//SoundDevice = null; // 後で再初期化することがあるので、null初期化はコンストラクタに回す //SoundDevice = null; // 後で再初期化することがあるので、null初期化はコンストラクタに回す
PlayTimer = null; // Global.Bass 依存(つまりユーザ依存) PlayTimer = null; // Global.Bass 依存(つまりユーザ依存)
nMixing = 0; nMixing = 0;
@ -256,8 +221,7 @@ namespace FDK
}; };
int initialDevice; int initialDevice;
switch ( soundDeviceType ) switch (soundDeviceType) {
{
case ESoundDeviceType.Bass: case ESoundDeviceType.Bass:
initialDevice = 0; initialDevice = 0;
break; break;
@ -274,19 +238,14 @@ namespace FDK
initialDevice = 4; initialDevice = 4;
break; break;
} }
for ( SoundDeviceType = ESoundDeviceTypes[ initialDevice ]; ; SoundDeviceType = ESoundDeviceTypes[ ++initialDevice ] ) for (SoundDeviceType = ESoundDeviceTypes[initialDevice]; ; SoundDeviceType = ESoundDeviceTypes[++initialDevice]) {
{ try {
try
{
tReloadSoundDeviceAndSound(); tReloadSoundDeviceAndSound();
break; break;
} } catch (Exception e) {
catch ( Exception e )
{
Trace.TraceError(e.ToString()); Trace.TraceError(e.ToString());
Trace.TraceError("例外が発生しましたが処理を継続します。 (2609806d-23e8-45c2-9389-b427e80915bc)"); Trace.TraceError("例外が発生しましたが処理を継続します。 (2609806d-23e8-45c2-9389-b427e80915bc)");
if ( ESoundDeviceTypes[ initialDevice ] == ESoundDeviceType.Unknown ) if (ESoundDeviceTypes[initialDevice] == ESoundDeviceType.Unknown) {
{
Trace.TraceError(string.Format("サウンドデバイスの初期化に失敗しました。")); Trace.TraceError(string.Format("サウンドデバイスの初期化に失敗しました。"));
break; break;
} }
@ -295,8 +254,7 @@ namespace FDK
if (soundDeviceType == ESoundDeviceType.Bass if (soundDeviceType == ESoundDeviceType.Bass
|| soundDeviceType == ESoundDeviceType.ExclusiveWASAPI || soundDeviceType == ESoundDeviceType.ExclusiveWASAPI
|| soundDeviceType == ESoundDeviceType.SharedWASAPI || soundDeviceType == ESoundDeviceType.SharedWASAPI
|| soundDeviceType == ESoundDeviceType.ASIO ) || soundDeviceType == ESoundDeviceType.ASIO) {
{
//Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATETHREADS, 4 ); //Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATETHREADS, 4 );
//Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0 ); //Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0 );
@ -305,8 +263,7 @@ namespace FDK
} }
} }
public void tDisableUpdateBufferAutomatically() public void tDisableUpdateBufferAutomatically() {
{
//Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATETHREADS, 0 ); //Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATETHREADS, 0 );
//Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0 ); //Bass.BASS_SetConfig( BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0 );
@ -315,19 +272,16 @@ namespace FDK
} }
public static void t終了() public static void t終了() {
{
SoundDevice.Dispose(); SoundDevice.Dispose();
PlayTimer.Dispose(); // Global.Bass を解放した後に解放すること。Global.Bass で参照されているため) PlayTimer.Dispose(); // Global.Bass を解放した後に解放すること。Global.Bass で参照されているため)
} }
public static void tReloadSoundDeviceAndSound() public static void tReloadSoundDeviceAndSound() {
{
#region [ ] #region [ ]
//----------------- //-----------------
if ( SoundDevice != null ) if (SoundDevice != null) {
{
// すでに生成済みのサウンドがあれば初期状態に戻す。 // すでに生成済みのサウンドがあれば初期状態に戻す。
CSound.tResetAllSound(); // リソースは解放するが、CSoundのインスタンスは残す。 CSound.tResetAllSound(); // リソースは解放するが、CSoundのインスタンスは残す。
@ -343,8 +297,7 @@ namespace FDK
#region [ ] #region [ ]
//----------------- //-----------------
switch ( SoundDeviceType ) switch (SoundDeviceType) {
{
case ESoundDeviceType.Bass: case ESoundDeviceType.Bass:
SoundDevice = new CSoundDeviceBASS(SoundDelayBASS, SoundUpdatePeriodBASS); SoundDevice = new CSoundDeviceBASS(SoundDelayBASS, SoundUpdatePeriodBASS);
break; break;
@ -376,16 +329,13 @@ namespace FDK
CSound.tReloadSound(SoundDevice); // すでに生成済みのサウンドがあれば作り直す。 CSound.tReloadSound(SoundDevice); // すでに生成済みのサウンドがあれば作り直す。
} }
public CSound tCreateSound( string filename, ESoundGroup soundGroup ) public CSound tCreateSound(string filename, ESoundGroup soundGroup) {
{ if (!File.Exists(filename)) {
if( !File.Exists( filename ) )
{
Trace.TraceWarning($"[i18n] File does not exist: {filename}"); Trace.TraceWarning($"[i18n] File does not exist: {filename}");
return null; return null;
} }
if ( SoundDeviceType == ESoundDeviceType.Unknown ) if (SoundDeviceType == ESoundDeviceType.Unknown) {
{
throw new Exception(string.Format("未対応の SoundDeviceType です。[{0}]", SoundDeviceType.ToString())); throw new Exception(string.Format("未対応の SoundDeviceType です。[{0}]", SoundDeviceType.ToString()));
} }
return SoundDevice.tCreateSound(filename, soundGroup); return SoundDevice.tCreateSound(filename, soundGroup);
@ -393,15 +343,12 @@ namespace FDK
private static DateTime lastUpdateTime = DateTime.MinValue; private static DateTime lastUpdateTime = DateTime.MinValue;
public void tDisposeSound( CSound csound ) public void tDisposeSound(CSound csound) {
{
csound?.tDispose(true); // インスタンスは存続→破棄にする。 csound?.tDispose(true); // インスタンスは存続→破棄にする。
} }
public string GetCurrentSoundDeviceType() public string GetCurrentSoundDeviceType() {
{ switch (SoundDeviceType) {
switch ( SoundDeviceType )
{
case ESoundDeviceType.Bass: case ESoundDeviceType.Bass:
return "Bass"; return "Bass";
case ESoundDeviceType.ExclusiveWASAPI: case ESoundDeviceType.ExclusiveWASAPI:
@ -415,23 +362,19 @@ namespace FDK
} }
} }
public void AddMixer( CSound cs, double db再生速度, bool _b演奏終了後も再生が続くチップである ) public void AddMixer(CSound cs, double db再生速度, bool _b演奏終了後も再生が続くチップである) {
{
cs.b演奏終了後も再生が続くチップである = _b演奏終了後も再生が続くチップである; cs.b演奏終了後も再生が続くチップである = _b演奏終了後も再生が続くチップである;
cs.PlaySpeed = db再生速度; cs.PlaySpeed = db再生速度;
cs.AddBassSoundFromMixer(); cs.AddBassSoundFromMixer();
} }
public void AddMixer( CSound cs, double db再生速度 ) public void AddMixer(CSound cs, double db再生速度) {
{
cs.PlaySpeed = db再生速度; cs.PlaySpeed = db再生速度;
cs.AddBassSoundFromMixer(); cs.AddBassSoundFromMixer();
} }
public void AddMixer( CSound cs ) public void AddMixer(CSound cs) {
{
cs.AddBassSoundFromMixer(); cs.AddBassSoundFromMixer();
} }
public void RemoveMixer( CSound cs ) public void RemoveMixer(CSound cs) {
{
cs.tRemoveSoundFromMixer(); cs.tRemoveSoundFromMixer();
} }
} }

View File

@ -1,15 +1,8 @@
using System; using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.IO;
using SkiaSharp; using SkiaSharp;
namespace FDK namespace FDK {
{ public static class BitmapUtil {
public static class BitmapUtil
{
// 定数 // 定数
public const uint DIB_PAL_COLORS = 1; public const uint DIB_PAL_COLORS = 1;
@ -19,8 +12,7 @@ namespace FDK
// 構造体 // 構造体
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BITMAPFILEHEADER public struct BITMAPFILEHEADER {
{
public ushort bfType; public ushort bfType;
public uint bfSize; public uint bfSize;
public ushort bfReserved1; public ushort bfReserved1;
@ -29,8 +21,7 @@ namespace FDK
} }
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BITMAPINFOHEADER public struct BITMAPINFOHEADER {
{
public const int BI_RGB = 0; public const int BI_RGB = 0;
public uint biSize構造体のサイズ; public uint biSize構造体のサイズ;
public int biWidthビットマップの幅dot; public int biWidthビットマップの幅dot;
@ -48,8 +39,7 @@ namespace FDK
// メソッド // メソッド
public static unsafe SKBitmap ToBitmap( IntPtr pBITMAPINFOHEADER ) public static unsafe SKBitmap ToBitmap(IntPtr pBITMAPINFOHEADER) {
{
BITMAPFILEHEADER bitmapfileheader; BITMAPFILEHEADER bitmapfileheader;
BITMAPINFOHEADER* bitmapinfoheaderPtr = (BITMAPINFOHEADER*)pBITMAPINFOHEADER; BITMAPINFOHEADER* bitmapinfoheaderPtr = (BITMAPINFOHEADER*)pBITMAPINFOHEADER;
bitmapfileheader.bfType = 0x4d42; bitmapfileheader.bfType = 0x4d42;

View File

@ -1,59 +1,44 @@
using System; using System.Drawing;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using FFmpeg.AutoGen; using FFmpeg.AutoGen;
namespace FDK namespace FDK {
{ public class CDecodedFrame : IDisposable {
public class CDecodedFrame : IDisposable public CDecodedFrame(Size texsize) {
{
public CDecodedFrame(Size texsize)
{
this.Using = false; this.Using = false;
this.TexSize = texsize; this.TexSize = texsize;
this.TexPointer = Marshal.AllocHGlobal(texsize.Width * TexSize.Height * 4); this.TexPointer = Marshal.AllocHGlobal(texsize.Width * TexSize.Height * 4);
} }
public bool Using public bool Using {
{
get; get;
private set; private set;
} }
public double Time public double Time {
{
get; get;
private set; private set;
} }
public IntPtr TexPointer public IntPtr TexPointer {
{
get; get;
private set; private set;
} }
public Size TexSize public Size TexSize {
{
get; get;
private set; private set;
} }
public unsafe CDecodedFrame UpdateFrame(double time, AVFrame* frame) public unsafe CDecodedFrame UpdateFrame(double time, AVFrame* frame) {
{
this.Time = time; this.Time = time;
Buffer.MemoryCopy(frame->data[0], (void*)this.TexPointer, frame->linesize[0] * frame->height, frame->linesize[0] * frame->height); Buffer.MemoryCopy(frame->data[0], (void*)this.TexPointer, frame->linesize[0] * frame->height, frame->linesize[0] * frame->height);
this.Using = true; this.Using = true;
return this; return this;
} }
public void RemoveFrame() public void RemoveFrame() {
{
this.Using = false; this.Using = false;
} }
public void Dispose() public void Dispose() {
{
this.Using = false; this.Using = false;
Marshal.FreeHGlobal(this.TexPointer); Marshal.FreeHGlobal(this.TexPointer);
} }

View File

@ -1,20 +1,13 @@
using System; using System.Drawing;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using FFmpeg.AutoGen; using FFmpeg.AutoGen;
namespace FDK namespace FDK {
{ public unsafe class CFrameConverter : IDisposable {
public unsafe class CFrameConverter : IDisposable public CFrameConverter(Size FrameSize, AVPixelFormat pix_fmt) {
{
public CFrameConverter(Size FrameSize, AVPixelFormat pix_fmt)
{
this.FrameSize = FrameSize; this.FrameSize = FrameSize;
if (pix_fmt != CVPxfmt) if (pix_fmt != CVPxfmt) {
{
convert_context = ffmpeg.sws_getContext( convert_context = ffmpeg.sws_getContext(
FrameSize.Width, FrameSize.Width,
FrameSize.Height, FrameSize.Height,
@ -33,10 +26,8 @@ namespace FDK
ffmpeg.av_image_fill_arrays(ref _dstData, ref _dstLinesize, (byte*)_convertedFrameBufferPtr, CVPxfmt, FrameSize.Width, FrameSize.Height, 1); ffmpeg.av_image_fill_arrays(ref _dstData, ref _dstLinesize, (byte*)_convertedFrameBufferPtr, CVPxfmt, FrameSize.Width, FrameSize.Height, 1);
} }
public AVFrame* Convert(AVFrame* framep) public AVFrame* Convert(AVFrame* framep) {
{ if (this.IsConvert) {
if (this.IsConvert)
{
ffmpeg.sws_scale(convert_context, framep->data, framep->linesize, 0, framep->height, _dstData, _dstLinesize); ffmpeg.sws_scale(convert_context, framep->data, framep->linesize, 0, framep->height, _dstData, _dstLinesize);
AVFrame* tmp = ffmpeg.av_frame_alloc(); AVFrame* tmp = ffmpeg.av_frame_alloc();
@ -51,15 +42,12 @@ namespace FDK
ffmpeg.av_frame_unref(framep); ffmpeg.av_frame_unref(framep);
return tmp; return tmp;
} } else {
else
{
return framep; return framep;
} }
} }
public void Dispose() public void Dispose() {
{
Marshal.FreeHGlobal(_convertedFrameBufferPtr); Marshal.FreeHGlobal(_convertedFrameBufferPtr);
ffmpeg.sws_freeContext(convert_context); ffmpeg.sws_freeContext(convert_context);
} }

View File

@ -1,18 +1,6 @@
using System; using Rectangle = System.Drawing.Rectangle;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Diagnostics;
using Silk.NET.Maths;
using Rectangle = System.Drawing.Rectangle; namespace FDK {
using Point = System.Drawing.Point;
using Color = System.Drawing.Color;
namespace FDK
{
/// <summary> /// <summary>
/// 縦長_横長の画像を自動で折りたたんでテクスチャ化するCTexture。 /// 縦長_横長の画像を自動で折りたたんでテクスチャ化するCTexture。
/// 例えば、768x30 のテクスチャファイルが入力されたら、 /// 例えば、768x30 のテクスチャファイルが入力されたら、
@ -20,8 +8,7 @@ namespace FDK
/// 必要に応じて、正方形テクスチャにもする。 /// 必要に応じて、正方形テクスチャにもする。
/// また、t2D描画は、その折り返しを加味して実行する。 /// また、t2D描画は、その折り返しを加味して実行する。
/// </summary> /// </summary>
public class CTextureAf : CTexture, IDisposable public class CTextureAf : CTexture, IDisposable {
{
/// <summary> /// <summary>
/// <para>画像ファイルからテクスチャを生成する。</para> /// <para>画像ファイルからテクスチャを生成する。</para>
@ -36,16 +23,14 @@ namespace FDK
/// <param name="b黒を透過する">画像の黒0xFFFFFFFFを透過させるなら true。</param> /// <param name="b黒を透過する">画像の黒0xFFFFFFFFを透過させるなら true。</param>
/// <param name="pool">テクスチャの管理方法。</param> /// <param name="pool">テクスチャの管理方法。</param>
/// <exception cref="CTextureCreateFailedException">テクスチャの作成に失敗しました。</exception> /// <exception cref="CTextureCreateFailedException">テクスチャの作成に失敗しました。</exception>
public CTextureAf( string strファイル名, bool b黒を透過する ) public CTextureAf(string strファイル名, bool b黒を透過する) {
{
MakeTexture(strファイル名, b黒を透過する); MakeTexture(strファイル名, b黒を透過する);
} }
public new void MakeTexture( string strファイル名, bool b黒を透過する ) public new void MakeTexture(string strファイル名, bool b黒を透過する) {
{
if (!File.Exists(strファイル名)) // #27122 2012.1.13 from: ImageInformation では FileNotFound 例外は返ってこないので、ここで自分でチェックする。わかりやすいログのために。 if (!File.Exists(strファイル名)) // #27122 2012.1.13 from: ImageInformation では FileNotFound 例外は返ってこないので、ここで自分でチェックする。わかりやすいログのために。
throw new FileNotFoundException(string.Format("ファイルが存在しません。\n[{0}]", strファイル名)); throw new FileNotFoundException(string.Format("ファイルが存在しません。\n[{0}]", strファイル名));
@ -60,22 +45,19 @@ namespace FDK
/// <param name="height"></param> /// <param name="height"></param>
/// <param name="foldtimes"></param> /// <param name="foldtimes"></param>
/// <returns></returns> /// <returns></returns>
private bool GetFoldedTextureSize( ref int width, ref int height, out int foldtimes ) private bool GetFoldedTextureSize(ref int width, ref int height, out int foldtimes) {
{
int orgWidth = width, orgHeight = height; int orgWidth = width, orgHeight = height;
#region [ widthが2 ] #region [ widthが2 ]
int pow = 1; int pow = 1;
while ( orgWidth >= pow ) while (orgWidth >= pow) {
{
pow *= 2; pow *= 2;
} }
pow /= 2; pow /= 2;
#endregion #endregion
#region [ 22 ] #region [ 22 ]
foldtimes = (orgWidth == pow) ? 0 : 1; // 2のべき乗からの溢れがあれば、まずその溢れ分で1回折り畳む foldtimes = (orgWidth == pow) ? 0 : 1; // 2のべき乗からの溢れがあれば、まずその溢れ分で1回折り畳む
if ( foldtimes != 0 ) if (foldtimes != 0) {
{
//Debug.WriteLine( "powちょうどではないので、溢れあり。まずは1回折りたたむ。" ); //Debug.WriteLine( "powちょうどではないので、溢れあり。まずは1回折りたたむ。" );
// 試しに、widthをpowに切り詰め、1回折り返してみる。 // 試しに、widthをpowに切り詰め、1回折り返してみる。
// width>heightを維持しているなら、テクスチャサイズはより最適な状態になったということになる。 // width>heightを維持しているなら、テクスチャサイズはより最適な状態になったということになる。
@ -88,8 +70,7 @@ namespace FDK
#region [ width > height ] #region [ width > height ]
width = pow; width = pow;
height = orgHeight * 2; // 初期値1回折りたたんだ状態 height = orgHeight * 2; // 初期値1回折りたたんだ状態
do do {
{
width /= 2; width /= 2;
foldtimes = (orgWidth / width) + ((orgWidth % width > 0) ? 1 : 0) - 1; foldtimes = (orgWidth / width) + ((orgWidth % width > 0) ? 1 : 0) - 1;
height = orgHeight * (foldtimes + 1); height = orgHeight * (foldtimes + 1);
@ -110,22 +91,17 @@ namespace FDK
/// <param name="device">Direct3D9 デバイス。</param> /// <param name="device">Direct3D9 デバイス。</param>
/// <param name="x">描画位置(テクスチャの左上位置の X 座標[dot])。</param> /// <param name="x">描画位置(テクスチャの左上位置の X 座標[dot])。</param>
/// <param name="y">描画位置(テクスチャの左上位置の Y 座標[dot])。</param> /// <param name="y">描画位置(テクスチャの左上位置の Y 座標[dot])。</param>
public new void t2D描画( int x, int y ) public new void t2D描画(int x, int y) {
{
#if TEST_FOLDTEXTURE #if TEST_FOLDTEXTURE
base.t2D描画( x, y, 1f, rc全画像 ); base.t2D描画( x, y, 1f, rc全画像 );
#else #else
for ( int n = 0; n <= _foldtimes; n++ ) for (int n = 0; n <= _foldtimes; n++) {
{
Rectangle r; Rectangle r;
if ( b横長のテクスチャである ) if (b横長のテクスチャである) {
{
int currentHeight = n * _orgHeight; int currentHeight = n * _orgHeight;
r = new Rectangle(0, currentHeight, this.rc全画像.Width, _orgHeight); r = new Rectangle(0, currentHeight, this.rc全画像.Width, _orgHeight);
base.t2D描画(x + n * this.rc全画像.Width, y, 1f, r); base.t2D描画(x + n * this.rc全画像.Width, y, 1f, r);
} } else {
else
{
int currentWidth = n * _orgWidth; int currentWidth = n * _orgWidth;
r = new Rectangle(currentWidth, 0, _orgWidth, this.rc全画像.Height); r = new Rectangle(currentWidth, 0, _orgWidth, this.rc全画像.Height);
base.t2D描画(x, y + n * this.rc全画像.Height, 1f, r); base.t2D描画(x, y + n * this.rc全画像.Height, 1f, r);
@ -133,15 +109,12 @@ namespace FDK
} }
#endif #endif
} }
public new void t2D描画( int x, int y, Rectangle rc ) public new void t2D描画(int x, int y, Rectangle rc) {
{
Rectangle r; Rectangle r;
if ( b横長のテクスチャである ) if (b横長のテクスチャである) {
{
int beginFold = rc.X / this.rc全画像.Width; int beginFold = rc.X / this.rc全画像.Width;
int endFold = (rc.X + rc.Width) / rc全画像.Width; int endFold = (rc.X + rc.Width) / rc全画像.Width;
for ( int i = beginFold; i <= endFold; i++ ) for (int i = beginFold; i <= endFold; i++) {
{
if (i > _foldtimes) break; if (i > _foldtimes) break;
int newRcY = i * _orgHeight + rc.Y; int newRcY = i * _orgHeight + rc.Y;
@ -156,13 +129,10 @@ namespace FDK
x += deltaX; x += deltaX;
rc.Width = newWidth; rc.Width = newWidth;
} }
} } else {
else
{
int beginFold = rc.Y / this.rc全画像.Height; int beginFold = rc.Y / this.rc全画像.Height;
int endFold = (rc.Y + rc.Height) / rc全画像.Height; int endFold = (rc.Y + rc.Height) / rc全画像.Height;
for ( int i = beginFold; i <= endFold; i++ ) for (int i = beginFold; i <= endFold; i++) {
{
if (i > _foldtimes) break; if (i > _foldtimes) break;
int newRcX = i * _orgWidth + rc.X; int newRcX = i * _orgWidth + rc.X;
@ -180,12 +150,10 @@ namespace FDK
} }
} }
public new void t2D描画( float x, float y ) public new void t2D描画(float x, float y) {
{
t2D描画((int)x, (int)y); t2D描画((int)x, (int)y);
} }
public void t2D描画( float x, float y, Rectangle rc ) public void t2D描画(float x, float y, Rectangle rc) {
{
t2D描画((int)x, (int)y, rc); t2D描画((int)x, (int)y, rc);
} }

View File

@ -1,29 +1,20 @@
using System; using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// テクスチャの作成に失敗しました。 /// テクスチャの作成に失敗しました。
/// </summary> /// </summary>
public class CTextureCreateFailedException : Exception public class CTextureCreateFailedException : Exception {
{ public CTextureCreateFailedException() {
public CTextureCreateFailedException()
{
} }
public CTextureCreateFailedException(string message) public CTextureCreateFailedException(string message)
: base( message ) : base(message) {
{
} }
public CTextureCreateFailedException(SerializationInfo info, StreamingContext context) public CTextureCreateFailedException(SerializationInfo info, StreamingContext context)
: base( info, context ) : base(info, context) {
{
} }
public CTextureCreateFailedException(string message, Exception innerException) public CTextureCreateFailedException(string message, Exception innerException)
: base( message, innerException ) : base(message, innerException) {
{
} }
} }
} }

View File

@ -1,35 +1,21 @@
using System; using System.Collections.Concurrent;
using System.IO;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFmpeg.AutoGen; using FFmpeg.AutoGen;
using System.Threading;
using Size = System.Drawing.Size; using Size = System.Drawing.Size;
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// ビデオのデコードをするクラス /// ビデオのデコードをするクラス
/// ファイル名・nullのCTextureをもらえれば、勝手に、CTextureに映像を格納して返す。 /// ファイル名・nullのCTextureをもらえれば、勝手に、CTextureに映像を格納して返す。
/// 演奏とは別のタイマーを使用しているので、ずれる可能性がある。 /// 演奏とは別のタイマーを使用しているので、ずれる可能性がある。
/// </summary> /// </summary>
public unsafe class CVideoDecoder : IDisposable public unsafe class CVideoDecoder : IDisposable {
{ public CVideoDecoder(string filename) {
public CVideoDecoder(string filename)
{
if (!File.Exists(filename)) if (!File.Exists(filename))
throw new FileNotFoundException(filename + " not found..."); throw new FileNotFoundException(filename + " not found...");
format_context = ffmpeg.avformat_alloc_context(); format_context = ffmpeg.avformat_alloc_context();
fixed (AVFormatContext** format_contexttmp = &format_context) fixed (AVFormatContext** format_contexttmp = &format_context) {
{
if (ffmpeg.avformat_open_input(format_contexttmp, filename, null, null) != 0) if (ffmpeg.avformat_open_input(format_contexttmp, filename, null, null) != 0)
throw new FileLoadException("avformat_open_input failed\n"); throw new FileLoadException("avformat_open_input failed\n");
@ -37,10 +23,8 @@ namespace FDK
throw new FileLoadException("avformat_find_stream_info failed\n"); throw new FileLoadException("avformat_find_stream_info failed\n");
// find audio stream // find audio stream
for (int i = 0; i < (int)format_context->nb_streams; i++) for (int i = 0; i < (int)format_context->nb_streams; i++) {
{ if (format_context->streams[i]->codecpar->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO) {
if (format_context->streams[i]->codecpar->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
{
video_stream = format_context->streams[i]; video_stream = format_context->streams[i];
break; break;
} }
@ -76,8 +60,7 @@ namespace FDK
} }
} }
public void Dispose() public void Dispose() {
{
bDrawing = false; bDrawing = false;
close = true; close = true;
cts?.Cancel(); cts?.Cancel();
@ -88,8 +71,7 @@ namespace FDK
if (ffmpeg.avcodec_close(codec_context) < 0) if (ffmpeg.avcodec_close(codec_context) < 0)
Trace.TraceError("codec context close error."); Trace.TraceError("codec context close error.");
video_stream = null; video_stream = null;
fixed (AVFormatContext** format_contexttmp = &format_context) fixed (AVFormatContext** format_contexttmp = &format_context) {
{
ffmpeg.avformat_close_input(format_contexttmp); ffmpeg.avformat_close_input(format_contexttmp);
} }
if (lastTexture != null) if (lastTexture != null)
@ -98,8 +80,7 @@ namespace FDK
frame.Dispose(); frame.Dispose();
} }
public void Start() public void Start() {
{
CTimer.Reset(); CTimer.Reset();
CTimer.Resume(); CTimer.Resume();
this.bPlaying = true; this.bPlaying = true;
@ -107,40 +88,31 @@ namespace FDK
} }
public void PauseControl() public void PauseControl() {
{ if (this.bPlaying) {
if (this.bPlaying)
{
CTimer.Pause(); CTimer.Pause();
this.bPlaying = false; this.bPlaying = false;
} } else {
else
{
CTimer.Resume(); CTimer.Resume();
this.bPlaying = true; this.bPlaying = true;
} }
} }
public void Stop() public void Stop() {
{
CTimer.Pause(); CTimer.Pause();
this.bPlaying = false; this.bPlaying = false;
bDrawing = false; bDrawing = false;
} }
public void InitRead() public void InitRead() {
{ if (!bqueueinitialized) {
if (!bqueueinitialized)
{
this.Seek(0); this.Seek(0);
bqueueinitialized = true; bqueueinitialized = true;
} } else
else
Trace.TraceError("The class has already been initialized.\n"); Trace.TraceError("The class has already been initialized.\n");
} }
public void Seek(long timestampms) public void Seek(long timestampms) {
{
cts?.Cancel(); cts?.Cancel();
while (DS != DecodingState.Stopped) ; while (DS != DecodingState.Stopped) ;
if (ffmpeg.av_seek_frame(format_context, video_stream->index, timestampms, ffmpeg.AVSEEK_FLAG_BACKWARD) < 0) if (ffmpeg.av_seek_frame(format_context, video_stream->index, timestampms, ffmpeg.AVSEEK_FLAG_BACKWARD) < 0)
@ -156,21 +128,16 @@ namespace FDK
lastTexture = new CTexture(FrameSize.Width, FrameSize.Height); lastTexture = new CTexture(FrameSize.Width, FrameSize.Height);
} }
public void GetNowFrame(ref CTexture Texture) public void GetNowFrame(ref CTexture Texture) {
{ if (this.bPlaying && decodedframes.Count != 0) {
if (this.bPlaying && decodedframes.Count != 0)
{
CTimer.Update(); CTimer.Update();
if (decodedframes.TryPeek(out CDecodedFrame frame)) if (decodedframes.TryPeek(out CDecodedFrame frame)) {
{ while (frame.Time <= (CTimer.NowTimeMs * _dbPlaySpeed)) {
while (frame.Time <= (CTimer.NowTimeMs * _dbPlaySpeed))
{
if (decodedframes.TryDequeue(out CDecodedFrame cdecodedframe)) { if (decodedframes.TryDequeue(out CDecodedFrame cdecodedframe)) {
if (decodedframes.Count != 0) if (decodedframes.Count != 0)
if (decodedframes.TryPeek(out frame)) if (decodedframes.TryPeek(out frame))
if (frame.Time <= (CTimer.NowTimeMs * _dbPlaySpeed)) if (frame.Time <= (CTimer.NowTimeMs * _dbPlaySpeed)) {
{
cdecodedframe.RemoveFrame(); cdecodedframe.RemoveFrame();
continue; continue;
} }
@ -197,24 +164,19 @@ namespace FDK
} }
private void EnqueueFrames() private void EnqueueFrames() {
{ if (DS != DecodingState.Running && !close) {
if (DS != DecodingState.Running && !close)
{
cts = new CancellationTokenSource(); cts = new CancellationTokenSource();
Task.Factory.StartNew(() => EnqueueOneFrame()); Task.Factory.StartNew(() => EnqueueOneFrame());
} }
} }
private void EnqueueOneFrame() private void EnqueueOneFrame() {
{
DS = DecodingState.Running; DS = DecodingState.Running;
AVFrame* frame = ffmpeg.av_frame_alloc(); AVFrame* frame = ffmpeg.av_frame_alloc();
AVPacket* packet = ffmpeg.av_packet_alloc(); AVPacket* packet = ffmpeg.av_packet_alloc();
try try {
{ while (true) {
while (true)
{
if (cts.IsCancellationRequested || close) if (cts.IsCancellationRequested || close)
return; return;
@ -223,14 +185,10 @@ namespace FDK
{ {
int error = ffmpeg.av_read_frame(format_context, packet); int error = ffmpeg.av_read_frame(format_context, packet);
if (error >= 0) if (error >= 0) {
{ if (packet->stream_index == video_stream->index) {
if (packet->stream_index == video_stream->index) if (ffmpeg.avcodec_send_packet(codec_context, packet) >= 0) {
{ if (ffmpeg.avcodec_receive_frame(codec_context, frame) == 0) {
if (ffmpeg.avcodec_send_packet(codec_context, packet) >= 0)
{
if (ffmpeg.avcodec_receive_frame(codec_context, frame) == 0)
{
AVFrame* outframe = null; AVFrame* outframe = null;
outframe = frameconv.Convert(frame); outframe = frameconv.Convert(frame);
@ -246,26 +204,18 @@ namespace FDK
//2020/10/27 Mr-Ojii packetが解放されない周回があった問題を修正。 //2020/10/27 Mr-Ojii packetが解放されない周回があった問題を修正。
ffmpeg.av_packet_unref(packet); ffmpeg.av_packet_unref(packet);
} } else if (error == ffmpeg.AVERROR_EOF) {
else if (error == ffmpeg.AVERROR_EOF)
{
return; return;
} }
} } else {
else
{
//ポーズ中に無限ループに入り、CPU使用率が異常に高くなってしまうため、1ms待つ。 //ポーズ中に無限ループに入り、CPU使用率が異常に高くなってしまうため、1ms待つ。
//ネットを調べると、await Task.Delay()を使えというお話が出てくるが、unsafeなので、使えない //ネットを調べると、await Task.Delay()を使えというお話が出てくるが、unsafeなので、使えない
Thread.Sleep(1); Thread.Sleep(1);
} }
} }
} } catch (Exception e) {
catch (Exception e)
{
Trace.TraceError(e.ToString()); Trace.TraceError(e.ToString());
} } finally {
finally
{
ffmpeg.av_packet_free(&packet); ffmpeg.av_packet_free(&packet);
ffmpeg.av_frame_unref(frame); ffmpeg.av_frame_unref(frame);
ffmpeg.av_free(frame); ffmpeg.av_free(frame);
@ -273,42 +223,32 @@ namespace FDK
} }
} }
public CDecodedFrame PickUnusedDcodedFrame() public CDecodedFrame PickUnusedDcodedFrame() {
{
for (int i = 0; i < framelist.Length; i++) { for (int i = 0; i < framelist.Length; i++) {
if (framelist[i].Using == false) if (framelist[i].Using == false) {
{
return framelist[i]; return framelist[i];
} }
} }
return null; return null;
} }
public Size FrameSize public Size FrameSize {
{
get; get;
private set; private set;
} }
public double Duration public double Duration {
{
get; get;
private set; private set;
} }
public double dbPlaySpeed public double dbPlaySpeed {
{ get {
get
{
return this._dbPlaySpeed; return this._dbPlaySpeed;
} }
set set {
{ if (value > 0) {
if (value > 0)
{
this._dbPlaySpeed = value; this._dbPlaySpeed = value;
} } else {
else
{
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
} }
@ -325,8 +265,7 @@ namespace FDK
private CancellationTokenSource cts; private CancellationTokenSource cts;
private CDecodedFrame[] framelist = new CDecodedFrame[6]; private CDecodedFrame[] framelist = new CDecodedFrame[6];
private DecodingState DS = DecodingState.Stopped; private DecodingState DS = DecodingState.Stopped;
private enum DecodingState private enum DecodingState {
{
Stopped, Stopped,
Running Running
} }

View File

@ -1,31 +1,24 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Diagnostics;
using SkiaSharp; using SkiaSharp;
using Color = System.Drawing.Color; using Color = System.Drawing.Color;
namespace FDK namespace FDK {
{
/// <summary> /// <summary>
/// 高速描画版のCFontRendererクラス。 /// 高速描画版のCFontRendererクラス。
/// といっても、一度レンダリングした結果をキャッシュして使いまわしているだけ。 /// といっても、一度レンダリングした結果をキャッシュして使いまわしているだけ。
/// </summary> /// </summary>
public class CCachedFontRenderer : CFontRenderer public class CCachedFontRenderer : CFontRenderer {
{
#region [ ] #region [ ]
public CCachedFontRenderer( string fontpath, int pt, CFontRenderer.FontStyle style ) public CCachedFontRenderer(string fontpath, int pt, CFontRenderer.FontStyle style) {
{
Initialize(fontpath, pt, style); Initialize(fontpath, pt, style);
} }
public CCachedFontRenderer( string fontpath, int pt ) public CCachedFontRenderer(string fontpath, int pt) {
{
Initialize(fontpath, pt, CFontRenderer.FontStyle.Regular); Initialize(fontpath, pt, CFontRenderer.FontStyle.Regular);
} }
#endregion #endregion
#region [ ] #region [ ]
protected new void Initialize( string fontpath, int pt, CFontRenderer.FontStyle style ) protected new void Initialize(string fontpath, int pt, CFontRenderer.FontStyle style) {
{
this.bDisposed_CCachedFontRenderer = false; this.bDisposed_CCachedFontRenderer = false;
this.listFontCache = new List<FontCache>(); this.listFontCache = new List<FontCache>();
base.Initialize(fontpath, pt, style); base.Initialize(fontpath, pt, style);
@ -41,8 +34,7 @@ namespace FDK
/// <param name="fontColor">描画色</param> /// <param name="fontColor">描画色</param>
/// <param name="edgeColor">縁取色</param> /// <param name="edgeColor">縁取色</param>
/// <returns>描画済テクスチャ</returns> /// <returns>描画済テクスチャ</returns>
public new SKBitmap DrawText( string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false) public new SKBitmap DrawText(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText(drawstr, DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter); return DrawText(drawstr, DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter);
} }
@ -53,8 +45,7 @@ namespace FDK
/// <param name="fontColor">描画色</param> /// <param name="fontColor">描画色</param>
/// <param name="edgeColor">縁取色</param> /// <param name="edgeColor">縁取色</param>
/// <returns>描画済テクスチャ</returns> /// <returns>描画済テクスチャ</returns>
public SKBitmap DrawText( string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, DrawMode dMode, int edge_Ratio, bool keepCenter = false) public SKBitmap DrawText(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, DrawMode dMode, int edge_Ratio, bool keepCenter = false) {
{
return DrawText(drawstr, dMode, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter); return DrawText(drawstr, dMode, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter);
} }
@ -67,8 +58,7 @@ namespace FDK
/// <param name="gradationTopColor">グラデーション 上側の色</param> /// <param name="gradationTopColor">グラデーション 上側の色</param>
/// <param name="gradationBottomColor">グラデーション 下側の色</param> /// <param name="gradationBottomColor">グラデーション 下側の色</param>
/// <returns>描画済テクスチャ</returns> /// <returns>描画済テクスチャ</returns>
public new SKBitmap DrawText( string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false ) public new SKBitmap DrawText(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText(drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter); return DrawText(drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter);
} }
@ -81,19 +71,16 @@ namespace FDK
/// <param name="gradationTopColor">グラデーション 上側の色</param> /// <param name="gradationTopColor">グラデーション 上側の色</param>
/// <param name="gradationBottomColor">グラデーション 下側の色</param> /// <param name="gradationBottomColor">グラデーション 下側の色</param>
/// <returns>描画済テクスチャ</returns> /// <returns>描画済テクスチャ</returns>
public new SKBitmap DrawText_V( string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false ) public new SKBitmap DrawText_V(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText_V(drawstr, DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.Black, Color.Black, edge_Ratio, keepCenter); return DrawText_V(drawstr, DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.Black, Color.Black, edge_Ratio, keepCenter);
} }
#endregion #endregion
protected new SKBitmap DrawText( string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false ) protected new SKBitmap DrawText(string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false) {
{
#region [ /? (?) ] #region [ /? (?) ]
int index = listFontCache.FindIndex( int index = listFontCache.FindIndex(
delegate( FontCache fontcache ) delegate (FontCache fontcache) {
{
return ( return (
drawstr == fontcache.drawstr && drawstr == fontcache.drawstr &&
drawmode == fontcache.drawmode && drawmode == fontcache.drawmode &&
@ -108,8 +95,7 @@ namespace FDK
} }
); );
#endregion #endregion
if ( index < 0 ) if (index < 0) {
{
// キャッシュにヒットせず。 // キャッシュにヒットせず。
#region [ ] #region [ ]
FontCache fc = new FontCache(); FontCache fc = new FontCache();
@ -127,11 +113,9 @@ namespace FDK
Debug.WriteLine(drawstr + ": Cacheにヒットせず。(cachesize=" + listFontCache.Count + ")"); Debug.WriteLine(drawstr + ": Cacheにヒットせず。(cachesize=" + listFontCache.Count + ")");
#endregion #endregion
#region [ ] #region [ ]
if ( listFontCache.Count > MAXCACHESIZE ) if (listFontCache.Count > MAXCACHESIZE) {
{
Debug.WriteLine("Cache溢れ。" + listFontCache[0].drawstr + " を解放します。"); Debug.WriteLine("Cache溢れ。" + listFontCache[0].drawstr + " を解放します。");
if ( listFontCache[ 0 ].bmp != null ) if (listFontCache[0].bmp != null) {
{
listFontCache[0].bmp.Dispose(); listFontCache[0].bmp.Dispose();
} }
listFontCache.RemoveAt(0); listFontCache.RemoveAt(0);
@ -140,9 +124,7 @@ namespace FDK
// 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。 // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。
return listFontCache[listFontCache.Count - 1].bmp.Copy(); return listFontCache[listFontCache.Count - 1].bmp.Copy();
} } else {
else
{
Debug.WriteLine(drawstr + ": Cacheにヒット!! index=" + index); Debug.WriteLine(drawstr + ": Cacheにヒット!! index=" + index);
#region [ ] #region [ ]
// 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。 // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。
@ -151,12 +133,10 @@ namespace FDK
} }
} }
protected new SKBitmap DrawText_V(string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false) protected new SKBitmap DrawText_V(string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false) {
{
#region [ /? (?) ] #region [ /? (?) ]
int index = listFontCache.FindIndex( int index = listFontCache.FindIndex(
delegate (FontCache fontcache) delegate (FontCache fontcache) {
{
return ( return (
drawstr == fontcache.drawstr && drawstr == fontcache.drawstr &&
drawmode == fontcache.drawmode && drawmode == fontcache.drawmode &&
@ -171,8 +151,7 @@ namespace FDK
} }
); );
#endregion #endregion
if ( index < 0 ) if (index < 0) {
{
// キャッシュにヒットせず。 // キャッシュにヒットせず。
#region [ ] #region [ ]
FontCache fc = new FontCache(); FontCache fc = new FontCache();
@ -189,11 +168,9 @@ namespace FDK
Debug.WriteLine(drawstr + ": Cacheにヒットせず。(cachesize=" + listFontCache.Count + ")"); Debug.WriteLine(drawstr + ": Cacheにヒットせず。(cachesize=" + listFontCache.Count + ")");
#endregion #endregion
#region [ ] #region [ ]
if ( listFontCache.Count > MAXCACHESIZE ) if (listFontCache.Count > MAXCACHESIZE) {
{
Debug.WriteLine("Cache溢れ。" + listFontCache[0].drawstr + " を解放します。"); Debug.WriteLine("Cache溢れ。" + listFontCache[0].drawstr + " を解放します。");
if ( listFontCache[ 0 ].bmp != null ) if (listFontCache[0].bmp != null) {
{
listFontCache[0].bmp.Dispose(); listFontCache[0].bmp.Dispose();
} }
listFontCache.RemoveAt(0); listFontCache.RemoveAt(0);
@ -202,9 +179,7 @@ namespace FDK
// 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。 // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。
return listFontCache[listFontCache.Count - 1].bmp.Copy(); return listFontCache[listFontCache.Count - 1].bmp.Copy();
} } else {
else
{
Debug.WriteLine(drawstr + ": Cacheにヒット!! index=" + index); Debug.WriteLine(drawstr + ": Cacheにヒット!! index=" + index);
#region [ ] #region [ ]
// 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。 // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。
@ -215,18 +190,13 @@ namespace FDK
#region [ IDisposable ] #region [ IDisposable ]
//----------------- //-----------------
public new void Dispose() public new void Dispose() {
{ if (!this.bDisposed_CCachedFontRenderer) {
if (!this.bDisposed_CCachedFontRenderer) if (listFontCache != null) {
{
if (listFontCache != null)
{
//Debug.WriteLine( "Disposing CCachedFontRenderer()" ); //Debug.WriteLine( "Disposing CCachedFontRenderer()" );
#region [ ] #region [ ]
foreach (FontCache bc in listFontCache) foreach (FontCache bc in listFontCache) {
{ if (bc.bmp != null) {
if (bc.bmp != null)
{
bc.bmp.Dispose(); bc.bmp.Dispose();
} }
} }
@ -248,8 +218,7 @@ namespace FDK
/// </summary> /// </summary>
private const int MAXCACHESIZE = 256; private const int MAXCACHESIZE = 256;
private struct FontCache private struct FontCache {
{
// public Font font; // public Font font;
public string drawstr; public string drawstr;
public DrawMode drawmode; public DrawMode drawmode;

View File

@ -1,40 +1,31 @@
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SkiaSharp; using SkiaSharp;
using Color = System.Drawing.Color; using Color = System.Drawing.Color;
namespace FDK namespace FDK {
{
public class CFontRenderer : IDisposable public class CFontRenderer : IDisposable {
{
#region[static系] #region[static系]
public static void SetTextCorrectionX_Chara_List_Vertical(string[] list) public static void SetTextCorrectionX_Chara_List_Vertical(string[] list) {
{
if (list != null) if (list != null)
CorrectionX_Chara_List_Vertical = list.Where(c => c != null).ToArray(); CorrectionX_Chara_List_Vertical = list.Where(c => c != null).ToArray();
} }
public static void SetTextCorrectionX_Chara_List_Value_Vertical(int[] list) public static void SetTextCorrectionX_Chara_List_Value_Vertical(int[] list) {
{
if (list != null) if (list != null)
CorrectionX_Chara_List_Value_Vertical = list; CorrectionX_Chara_List_Value_Vertical = list;
} }
public static void SetTextCorrectionY_Chara_List_Vertical(string[] list) public static void SetTextCorrectionY_Chara_List_Vertical(string[] list) {
{
if (list != null) if (list != null)
CorrectionY_Chara_List_Vertical = list.Where(c => c != null).ToArray(); CorrectionY_Chara_List_Vertical = list.Where(c => c != null).ToArray();
} }
public static void SetTextCorrectionY_Chara_List_Value_Vertical(int[] list) public static void SetTextCorrectionY_Chara_List_Value_Vertical(int[] list) {
{
if (list != null) if (list != null)
CorrectionY_Chara_List_Value_Vertical = list; CorrectionY_Chara_List_Value_Vertical = list;
} }
public static void SetRotate_Chara_List_Vertical(string[] list) public static void SetRotate_Chara_List_Vertical(string[] list) {
{
if (list != null) if (list != null)
Rotate_Chara_List_Vertical = list.Where(c => c != null).ToArray(); Rotate_Chara_List_Vertical = list.Where(c => c != null).ToArray();
} }
@ -49,16 +40,14 @@ namespace FDK
[Flags] [Flags]
public enum DrawMode public enum DrawMode {
{
Normal = 0, Normal = 0,
Edge, Edge,
Gradation Gradation
} }
[Flags] [Flags]
public enum FontStyle public enum FontStyle {
{
Regular = 0, Regular = 0,
Bold, Bold,
Italic, Italic,
@ -66,10 +55,8 @@ namespace FDK
Strikeout Strikeout
} }
public static string DefaultFontName public static string DefaultFontName {
{ get {
get
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return "MS UI Gothic"; return "MS UI Gothic";
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
@ -79,100 +66,78 @@ namespace FDK
} }
} }
public static bool FontExists(string fontpath) public static bool FontExists(string fontpath) {
{
return SKFontManager.Default.FontFamilies.Contains(fontpath) || File.Exists(fontpath); return SKFontManager.Default.FontFamilies.Contains(fontpath) || File.Exists(fontpath);
} }
#region [ ] #region [ ]
public CFontRenderer(string fontpath, int pt, FontStyle style) public CFontRenderer(string fontpath, int pt, FontStyle style) {
{
Initialize(fontpath, pt, style); Initialize(fontpath, pt, style);
} }
public CFontRenderer(string fontpath, int pt) public CFontRenderer(string fontpath, int pt) {
{
Initialize(fontpath, pt, FontStyle.Regular); Initialize(fontpath, pt, FontStyle.Regular);
} }
public CFontRenderer() public CFontRenderer() {
{
//throw new ArgumentException("CFontRenderer: 引数があるコンストラクタを使用してください。"); //throw new ArgumentException("CFontRenderer: 引数があるコンストラクタを使用してください。");
} }
#endregion #endregion
protected void Initialize(string fontpath, int pt, FontStyle style) protected void Initialize(string fontpath, int pt, FontStyle style) {
{ try {
try
{
this.textRenderer = new CSkiaSharpTextRenderer(fontpath, pt, style); this.textRenderer = new CSkiaSharpTextRenderer(fontpath, pt, style);
return; return;
} } catch (Exception e) {
catch(Exception e)
{
Trace.TraceWarning("SkiaSharpでのフォント生成に失敗しました。" + e.ToString()); Trace.TraceWarning("SkiaSharpでのフォント生成に失敗しました。" + e.ToString());
this.textRenderer?.Dispose(); this.textRenderer?.Dispose();
} }
try try {
{
this.textRenderer = new CSkiaSharpTextRenderer(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"FDK.mplus-1p-medium.ttf"), pt, style); this.textRenderer = new CSkiaSharpTextRenderer(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"FDK.mplus-1p-medium.ttf"), pt, style);
} } catch (Exception e) {
catch (Exception e)
{
Trace.TraceWarning("ビルトインフォントを使用してのフォント生成に失敗しました。" + e.ToString()); Trace.TraceWarning("ビルトインフォントを使用してのフォント生成に失敗しました。" + e.ToString());
this.textRenderer?.Dispose(); this.textRenderer?.Dispose();
throw; throw;
} }
} }
public SKBitmap DrawText(string drawstr, Color fontColor, bool keepCenter = false) public SKBitmap DrawText(string drawstr, Color fontColor, bool keepCenter = false) {
{
return DrawText(drawstr, CFontRenderer.DrawMode.Normal, fontColor, Color.White, null, Color.White, Color.White, 0, keepCenter); return DrawText(drawstr, CFontRenderer.DrawMode.Normal, fontColor, Color.White, null, Color.White, Color.White, 0, keepCenter);
} }
public SKBitmap DrawText(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false) public SKBitmap DrawText(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText(drawstr, CFontRenderer.DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter); return DrawText(drawstr, CFontRenderer.DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter);
} }
public SKBitmap DrawText(string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) public SKBitmap DrawText(string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText(drawstr, CFontRenderer.DrawMode.Gradation, fontColor, Color.White, null, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter); return DrawText(drawstr, CFontRenderer.DrawMode.Gradation, fontColor, Color.White, null, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter);
} }
public SKBitmap DrawText(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) public SKBitmap DrawText(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText(drawstr, CFontRenderer.DrawMode.Edge | CFontRenderer.DrawMode.Gradation, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter); return DrawText(drawstr, CFontRenderer.DrawMode.Edge | CFontRenderer.DrawMode.Gradation, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter);
} }
protected SKBitmap DrawText(string drawstr, CFontRenderer.DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false) protected SKBitmap DrawText(string drawstr, CFontRenderer.DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false) {
{
//横書きに対してのCorrectionは廃止 //横書きに対してのCorrectionは廃止
return this.textRenderer.DrawText(drawstr, drawmode, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradationBottomColor, edge_Ratio, keepCenter); return this.textRenderer.DrawText(drawstr, drawmode, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradationBottomColor, edge_Ratio, keepCenter);
} }
public SKBitmap DrawText_V(string drawstr, Color fontColor, bool keepCenter = false) public SKBitmap DrawText_V(string drawstr, Color fontColor, bool keepCenter = false) {
{
return DrawText_V(drawstr, CFontRenderer.DrawMode.Normal, fontColor, Color.White, null, Color.White, Color.White, 0, keepCenter); return DrawText_V(drawstr, CFontRenderer.DrawMode.Normal, fontColor, Color.White, null, Color.White, Color.White, 0, keepCenter);
} }
public SKBitmap DrawText_V(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false) public SKBitmap DrawText_V(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText_V(drawstr, CFontRenderer.DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter); return DrawText_V(drawstr, CFontRenderer.DrawMode.Edge, fontColor, edgeColor, secondEdgeColor, Color.White, Color.White, edge_Ratio, keepCenter);
} }
public SKBitmap DrawText_V(string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) public SKBitmap DrawText_V(string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText_V(drawstr, CFontRenderer.DrawMode.Gradation, fontColor, Color.White, null, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter); return DrawText_V(drawstr, CFontRenderer.DrawMode.Gradation, fontColor, Color.White, null, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter);
} }
public SKBitmap DrawText_V(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) public SKBitmap DrawText_V(string drawstr, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradataionBottomColor, int edge_Ratio, bool keepCenter = false) {
{
return DrawText_V(drawstr, CFontRenderer.DrawMode.Edge | CFontRenderer.DrawMode.Gradation, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter); return DrawText_V(drawstr, CFontRenderer.DrawMode.Edge | CFontRenderer.DrawMode.Gradation, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradataionBottomColor, edge_Ratio, keepCenter);
} }
protected SKBitmap DrawText_V(string drawstr, CFontRenderer.DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false) protected SKBitmap DrawText_V(string drawstr, CFontRenderer.DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter = false) {
{ if (string.IsNullOrEmpty(drawstr)) {
if (string.IsNullOrEmpty(drawstr))
{
//nullか""だったら、1x1を返す //nullか""だったら、1x1を返す
return new SKBitmap(1, 1); return new SKBitmap(1, 1);
} }
@ -187,15 +152,12 @@ namespace FDK
//レンダリング,大きさ計測 //レンダリング,大きさ計測
int nWidth = 0; int nWidth = 0;
int nHeight = 0; int nHeight = 0;
for (int i = 0; i < strImageList.Length; i++) for (int i = 0; i < strImageList.Length; i++) {
{
strImageList[i] = this.textRenderer.DrawText(strList[i], drawmode, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradationBottomColor, edge_Ratio, false); strImageList[i] = this.textRenderer.DrawText(strList[i], drawmode, fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradationBottomColor, edge_Ratio, false);
//回転する文字 //回転する文字
if(Rotate_Chara_List_Vertical.Contains(strList[i])) if (Rotate_Chara_List_Vertical.Contains(strList[i])) {
{ using (var surface = new SKCanvas(strImageList[i])) {
using (var surface = new SKCanvas(strImageList[i]))
{
surface.RotateDegrees(90, strImageList[i].Width / 2, strImageList[i].Height / 2); surface.RotateDegrees(90, strImageList[i].Width / 2, strImageList[i].Height / 2);
surface.DrawBitmap(strImageList[i], 0, 0); surface.DrawBitmap(strImageList[i], 0, 0);
} }
@ -212,44 +174,29 @@ namespace FDK
//1文字ずつ描画したやつを全体キャンバスに描画していく //1文字ずつ描画したやつを全体キャンバスに描画していく
int nowHeightPos = 0; int nowHeightPos = 0;
for (int i = 0; i < strImageList.Length; i++) for (int i = 0; i < strImageList.Length; i++) {
{
int Correction_X = 0, Correction_Y = 0; int Correction_X = 0, Correction_Y = 0;
if (CorrectionX_Chara_List_Vertical != null && CorrectionX_Chara_List_Value_Vertical != null) if (CorrectionX_Chara_List_Vertical != null && CorrectionX_Chara_List_Value_Vertical != null) {
{
int Xindex = Array.IndexOf(CorrectionX_Chara_List_Vertical, strList[i]); int Xindex = Array.IndexOf(CorrectionX_Chara_List_Vertical, strList[i]);
if (-1 < Xindex && Xindex < CorrectionX_Chara_List_Value_Vertical.Length && CorrectionX_Chara_List_Vertical.Contains(strList[i])) if (-1 < Xindex && Xindex < CorrectionX_Chara_List_Value_Vertical.Length && CorrectionX_Chara_List_Vertical.Contains(strList[i])) {
{
Correction_X = CorrectionX_Chara_List_Value_Vertical[Xindex]; Correction_X = CorrectionX_Chara_List_Value_Vertical[Xindex];
} } else {
else if (-1 < Xindex && CorrectionX_Chara_List_Value_Vertical.Length <= Xindex && CorrectionX_Chara_List_Vertical.Contains(strList[i])) {
{
if (-1 < Xindex && CorrectionX_Chara_List_Value_Vertical.Length <= Xindex && CorrectionX_Chara_List_Vertical.Contains(strList[i]))
{
Correction_X = CorrectionX_Chara_List_Value_Vertical[0]; Correction_X = CorrectionX_Chara_List_Value_Vertical[0];
} } else {
else
{
Correction_X = 0; Correction_X = 0;
} }
} }
} }
if (CorrectionY_Chara_List_Vertical != null && CorrectionY_Chara_List_Value_Vertical != null) if (CorrectionY_Chara_List_Vertical != null && CorrectionY_Chara_List_Value_Vertical != null) {
{
int Yindex = Array.IndexOf(CorrectionY_Chara_List_Vertical, strList[i]); int Yindex = Array.IndexOf(CorrectionY_Chara_List_Vertical, strList[i]);
if (-1 < Yindex && Yindex < CorrectionY_Chara_List_Value_Vertical.Length && CorrectionY_Chara_List_Vertical.Contains(strList[i])) if (-1 < Yindex && Yindex < CorrectionY_Chara_List_Value_Vertical.Length && CorrectionY_Chara_List_Vertical.Contains(strList[i])) {
{
Correction_Y = CorrectionY_Chara_List_Value_Vertical[Yindex]; Correction_Y = CorrectionY_Chara_List_Value_Vertical[Yindex];
} } else {
else if (-1 < Yindex && CorrectionY_Chara_List_Value_Vertical.Length <= Yindex && CorrectionY_Chara_List_Vertical.Contains(strList[i])) {
{
if (-1 < Yindex && CorrectionY_Chara_List_Value_Vertical.Length <= Yindex && CorrectionY_Chara_List_Vertical.Contains(strList[i]))
{
Correction_Y = CorrectionY_Chara_List_Value_Vertical[0]; Correction_Y = CorrectionY_Chara_List_Value_Vertical[0];
} } else {
else
{
Correction_Y = 0; Correction_Y = 0;
} }
} }
@ -259,8 +206,7 @@ namespace FDK
} }
//1文字ずつ描画したやつの解放 //1文字ずつ描画したやつの解放
for (int i = 0; i < strImageList.Length; i++) for (int i = 0; i < strImageList.Length; i++) {
{
strImageList[i].Dispose(); strImageList[i].Dispose();
} }
@ -270,8 +216,7 @@ namespace FDK
return SKBitmap.FromImage(image); return SKBitmap.FromImage(image);
} }
public void Dispose() public void Dispose() {
{
this.textRenderer.Dispose(); this.textRenderer.Dispose();
} }

View File

@ -1,40 +1,24 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SkiaSharp;
using System.Text.RegularExpressions;
using Color = System.Drawing.Color;
using Rectangle = System.Drawing.Rectangle;
using System.Drawing; using System.Drawing;
using static FDK.CSkiaSharpTextRenderer; using System.Text.RegularExpressions;
using SkiaSharp;
using Color = System.Drawing.Color;
namespace FDK namespace FDK {
{ internal class CSkiaSharpTextRenderer : ITextRenderer {
internal class CSkiaSharpTextRenderer : ITextRenderer
{
//https://monobook.org/wiki/SkiaSharp%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E6%8F%8F%E7%94%BB%E3%81%99%E3%82%8B //https://monobook.org/wiki/SkiaSharp%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E6%8F%8F%E7%94%BB%E3%81%99%E3%82%8B
public CSkiaSharpTextRenderer(string fontpath, int pt) public CSkiaSharpTextRenderer(string fontpath, int pt) {
{
Initialize(fontpath, pt, CFontRenderer.FontStyle.Regular); Initialize(fontpath, pt, CFontRenderer.FontStyle.Regular);
} }
public CSkiaSharpTextRenderer(string fontpath, int pt, CFontRenderer.FontStyle style) public CSkiaSharpTextRenderer(string fontpath, int pt, CFontRenderer.FontStyle style) {
{
Initialize(fontpath, pt, style); Initialize(fontpath, pt, style);
} }
public CSkiaSharpTextRenderer(Stream fontstream, int pt, CFontRenderer.FontStyle style) public CSkiaSharpTextRenderer(Stream fontstream, int pt, CFontRenderer.FontStyle style) {
{
Initialize(fontstream, pt, style); Initialize(fontstream, pt, style);
} }
protected void Initialize(Stream fontstream, int pt, CFontRenderer.FontStyle style) protected void Initialize(Stream fontstream, int pt, CFontRenderer.FontStyle style) {
{
paint = new SKPaint(); paint = new SKPaint();
//stream・filepathから生成した場合に、style設定をどうすればいいのかがわからない //stream・filepathから生成した場合に、style設定をどうすればいいのかがわからない
@ -44,28 +28,23 @@ namespace FDK
paint.IsAntialias = true; paint.IsAntialias = true;
} }
protected void Initialize(string fontpath, int pt, CFontRenderer.FontStyle style) protected void Initialize(string fontpath, int pt, CFontRenderer.FontStyle style) {
{
paint = new SKPaint(); paint = new SKPaint();
SKFontStyleWeight weight = SKFontStyleWeight.Normal; SKFontStyleWeight weight = SKFontStyleWeight.Normal;
SKFontStyleWidth width = SKFontStyleWidth.Normal; SKFontStyleWidth width = SKFontStyleWidth.Normal;
SKFontStyleSlant slant = SKFontStyleSlant.Upright; SKFontStyleSlant slant = SKFontStyleSlant.Upright;
if (style.HasFlag(CFontRenderer.FontStyle.Bold)) if (style.HasFlag(CFontRenderer.FontStyle.Bold)) {
{
weight = SKFontStyleWeight.Bold; weight = SKFontStyleWeight.Bold;
} }
if (style.HasFlag(CFontRenderer.FontStyle.Italic)) if (style.HasFlag(CFontRenderer.FontStyle.Italic)) {
{
slant = SKFontStyleSlant.Italic; slant = SKFontStyleSlant.Italic;
} }
if (style.HasFlag(CFontRenderer.FontStyle.Strikeout)) if (style.HasFlag(CFontRenderer.FontStyle.Strikeout)) {
{
paint.Style = SKPaintStyle.Stroke; paint.Style = SKPaintStyle.Stroke;
} }
if (style.HasFlag(CFontRenderer.FontStyle.Underline)) if (style.HasFlag(CFontRenderer.FontStyle.Underline)) {
{
//???? //????
//paint.FontMetrics.UnderlinePosition; //paint.FontMetrics.UnderlinePosition;
} }
@ -84,8 +63,7 @@ namespace FDK
paint.IsAntialias = true; paint.IsAntialias = true;
} }
internal struct SStringToken internal struct SStringToken {
{
public string s; public string s;
public Color TextColor; public Color TextColor;
public bool UseGradiant; public bool UseGradiant;
@ -99,13 +77,11 @@ namespace FDK
private const string TagRegex = @"<(/?)([gc](?:\.#[0-9a-fA-F]{6})*?)>"; private const string TagRegex = @"<(/?)([gc](?:\.#[0-9a-fA-F]{6})*?)>";
private string Purify(string input) private string Purify(string input) {
{
return Regex.Replace(input, TagRegex, ""); return Regex.Replace(input, TagRegex, "");
} }
private List<SStringToken> Tokenize(string input, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor) private List<SStringToken> Tokenize(string input, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor) {
{
List<SStringToken> tokens = new List<SStringToken>(); List<SStringToken> tokens = new List<SStringToken>();
Stack<string> tags = new Stack<string>(); Stack<string> tags = new Stack<string>();
Stack<SStringToken> tokenStack = new Stack<SStringToken>(); Stack<SStringToken> tokenStack = new Stack<SStringToken>();
@ -114,16 +90,13 @@ namespace FDK
var tagRegex = new Regex(TagRegex); var tagRegex = new Regex(TagRegex);
var matches = tagRegex.Matches(input); var matches = tagRegex.Matches(input);
foreach (Match match in matches) foreach (Match match in matches) {
{
int pos = match.Index; int pos = match.Index;
string text = input.Substring(lastPos, pos - lastPos); string text = input.Substring(lastPos, pos - lastPos);
// First // First
if (text.Length > 0) if (text.Length > 0) {
{ SStringToken token = new SStringToken {
SStringToken token = new SStringToken
{
s = text, s = text,
UseGradiant = tokenStack.Count > 0 && tokenStack.Peek().UseGradiant, UseGradiant = tokenStack.Count > 0 && tokenStack.Peek().UseGradiant,
GradiantTop = (tokenStack.Count == 0) ? gradationTopColor : tokenStack.Peek().GradiantTop, GradiantTop = (tokenStack.Count == 0) ? gradationTopColor : tokenStack.Peek().GradiantTop,
@ -137,16 +110,12 @@ namespace FDK
lastPos = pos + match.Length; lastPos = pos + match.Length;
if (match.Groups[1].Value == "/") if (match.Groups[1].Value == "/") {
{
if (tags.Count > 0) tags.Pop(); if (tags.Count > 0) tags.Pop();
if (tokenStack.Count > 0) tokenStack.Pop(); if (tokenStack.Count > 0) tokenStack.Pop();
} } else {
else
{
tags.Push(match.Groups[2].Value); tags.Push(match.Groups[2].Value);
SStringToken newToken = new SStringToken SStringToken newToken = new SStringToken {
{
UseGradiant = tokenStack.Count > 0 ? tokenStack.Peek().UseGradiant : false, UseGradiant = tokenStack.Count > 0 ? tokenStack.Peek().UseGradiant : false,
GradiantTop = (tokenStack.Count == 0) ? gradationTopColor : tokenStack.Peek().GradiantTop, GradiantTop = (tokenStack.Count == 0) ? gradationTopColor : tokenStack.Peek().GradiantTop,
GradiantBottom = (tokenStack.Count == 0) ? gradationBottomColor : tokenStack.Peek().GradiantBottom, GradiantBottom = (tokenStack.Count == 0) ? gradationBottomColor : tokenStack.Peek().GradiantBottom,
@ -157,28 +126,21 @@ namespace FDK
string[] _varSplit = match.Groups[2].Value.Split("."); string[] _varSplit = match.Groups[2].Value.Split(".");
if (_varSplit.Length > 0) if (_varSplit.Length > 0) {
{ switch (_varSplit[0]) {
switch (_varSplit[0]) case "g": {
{ if (_varSplit.Length > 2) {
case "g":
{
if (_varSplit.Length > 2)
{
newToken.UseGradiant = true; newToken.UseGradiant = true;
newToken.GradiantTop = ColorTranslator.FromHtml(_varSplit[1]); newToken.GradiantTop = ColorTranslator.FromHtml(_varSplit[1]);
newToken.GradiantBottom = ColorTranslator.FromHtml(_varSplit[2]); newToken.GradiantBottom = ColorTranslator.FromHtml(_varSplit[2]);
} }
break; break;
} }
case "c": case "c": {
{ if (_varSplit.Length > 1) {
if (_varSplit.Length > 1)
{
newToken.TextColor = ColorTranslator.FromHtml(_varSplit[1]); newToken.TextColor = ColorTranslator.FromHtml(_varSplit[1]);
} }
if (_varSplit.Length > 2) if (_varSplit.Length > 2) {
{
newToken.UseOutline = true; newToken.UseOutline = true;
newToken.OutlineColor = ColorTranslator.FromHtml(_varSplit[2]); newToken.OutlineColor = ColorTranslator.FromHtml(_varSplit[2]);
} }
@ -193,10 +155,8 @@ namespace FDK
} }
// Last // Last
if (lastPos < input.Length) if (lastPos < input.Length) {
{ SStringToken token = new SStringToken {
SStringToken token = new SStringToken
{
s = input.Substring(lastPos), s = input.Substring(lastPos),
UseGradiant = tokenStack.Count > 0 && tokenStack.Peek().UseGradiant, UseGradiant = tokenStack.Count > 0 && tokenStack.Peek().UseGradiant,
GradiantTop = (tokenStack.Count == 0) ? gradationTopColor : tokenStack.Peek().GradiantTop, GradiantTop = (tokenStack.Count == 0) ? gradationTopColor : tokenStack.Peek().GradiantTop,
@ -211,10 +171,8 @@ namespace FDK
return tokens; return tokens;
} }
public SKBitmap DrawText(string drawstr, CFontRenderer.DrawMode drawMode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter) public SKBitmap DrawText(string drawstr, CFontRenderer.DrawMode drawMode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter) {
{ if (string.IsNullOrEmpty(drawstr)) {
if (string.IsNullOrEmpty(drawstr))
{
//nullか""だったら、1x1を返す //nullか""だったら、1x1を返す
return new SKBitmap(1, 1); return new SKBitmap(1, 1);
} }
@ -222,8 +180,7 @@ namespace FDK
string[] strs = drawstr.Split("\n"); string[] strs = drawstr.Split("\n");
List<SStringToken>[] tokens = new List<SStringToken>[strs.Length]; List<SStringToken>[] tokens = new List<SStringToken>[strs.Length];
for (int i = 0; i < strs.Length; i++) for (int i = 0; i < strs.Length; i++) {
{
tokens[i] = Tokenize(strs[i], fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradationBottomColor); tokens[i] = Tokenize(strs[i], fontColor, edgeColor, secondEdgeColor, gradationTopColor, gradationBottomColor);
} }
@ -241,17 +198,14 @@ namespace FDK
int x_offset = 0; int x_offset = 0;
foreach (SStringToken tok in tokens[i]) foreach (SStringToken tok in tokens[i]) {
{
int token_width = (int)Math.Ceiling(paint.MeasureText(tok.s, ref bounds)); int token_width = (int)Math.Ceiling(paint.MeasureText(tok.s, ref bounds));
if (drawMode.HasFlag(CFontRenderer.DrawMode.Edge) || tok.UseOutline) if (drawMode.HasFlag(CFontRenderer.DrawMode.Edge) || tok.UseOutline) {
{
SKPath path = paint.GetTextPath(tok.s, 25 + x_offset, -paint.FontMetrics.Ascent + 25); SKPath path = paint.GetTextPath(tok.s, 25 + x_offset, -paint.FontMetrics.Ascent + 25);
if (secondEdgeColor != null) if (secondEdgeColor != null) {
{
SKPaint secondEdgePaint = new SKPaint(); SKPaint secondEdgePaint = new SKPaint();
secondEdgePaint.StrokeWidth = paint.TextSize * 8 / edge_Ratio; secondEdgePaint.StrokeWidth = paint.TextSize * 8 / edge_Ratio;
secondEdgePaint.StrokeJoin = SKStrokeJoin.Round; secondEdgePaint.StrokeJoin = SKStrokeJoin.Round;
@ -270,8 +224,7 @@ namespace FDK
canvas.DrawPath(path, edgePaint); canvas.DrawPath(path, edgePaint);
} }
if (tok.UseGradiant) if (tok.UseGradiant) {
{
//https://docs.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/graphics/skiasharp/effects/shaders/linear-gradient //https://docs.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/graphics/skiasharp/effects/shaders/linear-gradient
paint.Shader = SKShader.CreateLinearGradient( paint.Shader = SKShader.CreateLinearGradient(
new SKPoint(0, 25), new SKPoint(0, 25),
@ -282,9 +235,7 @@ namespace FDK
new float[] { 0, 1 }, new float[] { 0, 1 },
SKShaderTileMode.Clamp); SKShaderTileMode.Clamp);
paint.Color = new SKColor(0xffffffff); paint.Color = new SKColor(0xffffffff);
} } else {
else
{
paint.Shader = null; paint.Shader = null;
paint.Color = new SKColor(tok.TextColor.R, tok.TextColor.G, tok.TextColor.B); paint.Color = new SKColor(tok.TextColor.R, tok.TextColor.G, tok.TextColor.B);
} }
@ -304,8 +255,7 @@ namespace FDK
int ret_width = 0; int ret_width = 0;
int ret_height = 0; int ret_height = 0;
for(int i = 0; i < images.Length; i++) for (int i = 0; i < images.Length; i++) {
{
ret_width = Math.Max(ret_width, images[i].Width); ret_width = Math.Max(ret_width, images[i].Width);
ret_height += images[i].Height - 25; ret_height += images[i].Height - 25;
} }
@ -322,14 +272,10 @@ namespace FDK
int height_i = -25; int height_i = -25;
for (int i = 0; i < images.Length; i++) for (int i = 0; i < images.Length; i++) {
{ if (keepCenter) {
if (keepCenter)
{
skCanvas.DrawBitmap(images[i], new SKPoint((ret_width / 2) - (images[i].Width / 2.0f), height_i)); skCanvas.DrawBitmap(images[i], new SKPoint((ret_width / 2) - (images[i].Width / 2.0f), height_i));
} } else {
else
{
skCanvas.DrawBitmap(images[i], new SKPoint(0, height_i)); skCanvas.DrawBitmap(images[i], new SKPoint(0, height_i));
} }
height_i += images[i].Height - 50; height_i += images[i].Height - 50;
@ -343,8 +289,7 @@ namespace FDK
return SKBitmap.FromImage(image); return SKBitmap.FromImage(image);
} }
public void Dispose() public void Dispose() {
{
paint.Dispose(); paint.Dispose();
} }

View File

@ -1,11 +1,8 @@
using System;
using SkiaSharp; using SkiaSharp;
using Color = System.Drawing.Color; using Color = System.Drawing.Color;
namespace FDK namespace FDK {
{ internal interface ITextRenderer : IDisposable {
internal interface ITextRenderer : IDisposable
{
SKBitmap DrawText(string drawstr, CFontRenderer.DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter); SKBitmap DrawText(string drawstr, CFontRenderer.DrawMode drawmode, Color fontColor, Color edgeColor, Color? secondEdgeColor, Color gradationTopColor, Color gradationBottomColor, int edge_Ratio, bool keepCenter);
} }
} }

View File

@ -1,16 +1,8 @@
using System; using FDK;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TJAPlayer3;
using FDK;
namespace TJAPlayer3.Animations namespace TJAPlayer3.Animations {
{ class Animator : IAnimatable {
class Animator : IAnimatable public Animator(int startValue, int endValue, int tickInterval, bool isLoop) {
{
public Animator(int startValue, int endValue, int tickInterval, bool isLoop)
{
Type = CounterType.Normal; Type = CounterType.Normal;
StartValue = startValue; StartValue = startValue;
EndValue = endValue; EndValue = endValue;
@ -18,8 +10,7 @@ namespace TJAPlayer3.Animations
IsLoop = isLoop; IsLoop = isLoop;
Counter = new CCounter(); Counter = new CCounter();
} }
public Animator(double startValue, double endValue, double tickInterval, bool isLoop) public Animator(double startValue, double endValue, double tickInterval, bool isLoop) {
{
Type = CounterType.Double; Type = CounterType.Double;
StartValue = startValue; StartValue = startValue;
EndValue = endValue; EndValue = endValue;
@ -27,11 +18,9 @@ namespace TJAPlayer3.Animations
IsLoop = isLoop; IsLoop = isLoop;
Counter = new CCounter(); Counter = new CCounter();
} }
public void Start() public void Start() {
{
if (Counter == null) throw new NullReferenceException(); if (Counter == null) throw new NullReferenceException();
switch (Type) switch (Type) {
{
case CounterType.Normal: case CounterType.Normal:
Counter.Start((int)StartValue, (int)EndValue, (int)TickInterval, TJAPlayer3.Timer); Counter.Start((int)StartValue, (int)EndValue, (int)TickInterval, TJAPlayer3.Timer);
break; break;
@ -42,22 +31,18 @@ namespace TJAPlayer3.Animations
break; break;
} }
} }
public void Stop() public void Stop() {
{
if (Counter == null) throw new NullReferenceException(); if (Counter == null) throw new NullReferenceException();
Counter.Stop(); Counter.Stop();
} }
public void Reset() public void Reset() {
{
if (Counter == null) throw new NullReferenceException(); if (Counter == null) throw new NullReferenceException();
Start(); Start();
} }
public void Tick() public void Tick() {
{
if (Counter == null) throw new NullReferenceException(); if (Counter == null) throw new NullReferenceException();
switch (Type) switch (Type) {
{
case CounterType.Normal: case CounterType.Normal:
if (IsLoop) Counter.TickLoop(); else Counter.Tick(); if (IsLoop) Counter.TickLoop(); else Counter.Tick();
if (!IsLoop && Counter.IsEnded) Stop(); if (!IsLoop && Counter.IsEnded) Stop();
@ -71,48 +56,40 @@ namespace TJAPlayer3.Animations
} }
} }
public virtual object GetAnimation() public virtual object GetAnimation() {
{
throw new NotImplementedException(); throw new NotImplementedException();
} }
// プロパティ // プロパティ
public CCounter Counter public CCounter Counter {
{
get; get;
private set; private set;
} }
public CounterType Type public CounterType Type {
{
get; get;
private set; private set;
} }
public object StartValue public object StartValue {
{
get; get;
private set; private set;
} }
public object EndValue public object EndValue {
{
get; get;
private set; private set;
} }
public object TickInterval public object TickInterval {
{
get; get;
private set; private set;
} }
public bool IsLoop public bool IsLoop {
{
get; get;
private set; private set;
} }
} }
enum CounterType enum CounterType {
{
Normal, Normal,
Double Double
} }

View File

@ -1,31 +1,22 @@
using System; namespace TJAPlayer3.Animations {
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TJAPlayer3.Animations
{
/// <summary> /// <summary>
/// イーズインを行うクラス。 /// イーズインを行うクラス。
/// </summary> /// </summary>
class EaseIn : Animator class EaseIn : Animator {
{
/// <summary> /// <summary>
/// イーズインを初期化します。 /// イーズインを初期化します。
/// </summary> /// </summary>
/// <param name="startPoint">始点。</param> /// <param name="startPoint">始点。</param>
/// <param name="endPoint">終点。</param> /// <param name="endPoint">終点。</param>
/// <param name="timeMs">イージングにかける時間。</param> /// <param name="timeMs">イージングにかける時間。</param>
public EaseIn(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) public EaseIn(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) {
{
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Sa = EndPoint - StartPoint; Sa = EndPoint - StartPoint;
TimeMs = timeMs; TimeMs = timeMs;
} }
public override object GetAnimation() public override object GetAnimation() {
{
var persent = Counter.CurrentValue / (double)TimeMs; var persent = Counter.CurrentValue / (double)TimeMs;
return ((double)Sa * persent * persent * persent) + StartPoint; return ((double)Sa * persent * persent * persent) + StartPoint;
} }

View File

@ -1,38 +1,26 @@
using System; namespace TJAPlayer3.Animations {
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TJAPlayer3.Animations
{
/// <summary> /// <summary>
/// イーズイン・アウトを行うクラス。 /// イーズイン・アウトを行うクラス。
/// </summary> /// </summary>
class EaseInOut : Animator class EaseInOut : Animator {
{
/// <summary> /// <summary>
/// イーズイン・アウトを初期化します。 /// イーズイン・アウトを初期化します。
/// </summary> /// </summary>
/// <param name="startPoint">始点。</param> /// <param name="startPoint">始点。</param>
/// <param name="endPoint">終点。</param> /// <param name="endPoint">終点。</param>
/// <param name="timeMs">イージングにかける時間。</param> /// <param name="timeMs">イージングにかける時間。</param>
public EaseInOut(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) public EaseInOut(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) {
{
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Sa = EndPoint - StartPoint; Sa = EndPoint - StartPoint;
TimeMs = timeMs; TimeMs = timeMs;
} }
public override object GetAnimation() public override object GetAnimation() {
{
var persent = Counter.CurrentValue / (double)TimeMs * 2.0; var persent = Counter.CurrentValue / (double)TimeMs * 2.0;
if (persent < 1) if (persent < 1) {
{
return ((double)Sa / 2.0 * persent * persent * persent) + StartPoint; return ((double)Sa / 2.0 * persent * persent * persent) + StartPoint;
} } else {
else
{
persent -= 2; persent -= 2;
return ((double)Sa / 2.0 * ((persent * persent * persent) + 2)) + StartPoint; return ((double)Sa / 2.0 * ((persent * persent * persent) + 2)) + StartPoint;
} }

View File

@ -1,31 +1,22 @@
using System; namespace TJAPlayer3.Animations {
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TJAPlayer3.Animations
{
/// <summary> /// <summary>
/// イーズアウトを行うクラス。 /// イーズアウトを行うクラス。
/// </summary> /// </summary>
class EaseOut : Animator class EaseOut : Animator {
{
/// <summary> /// <summary>
/// イーズアウトを初期化します。 /// イーズアウトを初期化します。
/// </summary> /// </summary>
/// <param name="startPoint">始点。</param> /// <param name="startPoint">始点。</param>
/// <param name="endPoint">終点。</param> /// <param name="endPoint">終点。</param>
/// <param name="timeMs">イージングにかける時間。</param> /// <param name="timeMs">イージングにかける時間。</param>
public EaseOut(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) public EaseOut(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) {
{
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Sa = EndPoint - StartPoint; Sa = EndPoint - StartPoint;
TimeMs = timeMs; TimeMs = timeMs;
} }
public override object GetAnimation() public override object GetAnimation() {
{
var persent = Counter.CurrentValue / (double)TimeMs; var persent = Counter.CurrentValue / (double)TimeMs;
persent -= 1; persent -= 1;
return (double)Sa * (persent * persent * persent + 1) + StartPoint; return (double)Sa * (persent * persent * persent + 1) + StartPoint;

View File

@ -1,21 +1,13 @@
using System; namespace TJAPlayer3.Animations {
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TJAPlayer3.Animations
{
/// <summary> /// <summary>
/// フェードインを行うクラス。 /// フェードインを行うクラス。
/// </summary> /// </summary>
internal class FadeIn : Animator internal class FadeIn : Animator {
{
/// <summary> /// <summary>
/// フェードインを初期化します。 /// フェードインを初期化します。
/// </summary> /// </summary>
/// <param name="timems">フェードインに掛ける秒数(ミリ秒)</param> /// <param name="timems">フェードインに掛ける秒数(ミリ秒)</param>
public FadeIn(int timems) : base(0, timems - 1, 1, false) public FadeIn(int timems) : base(0, timems - 1, 1, false) {
{
TimeMs = timems; TimeMs = timems;
} }
@ -23,8 +15,7 @@ namespace TJAPlayer3.Animations
/// フェードインの不透明度を255段階で返します。 /// フェードインの不透明度を255段階で返します。
/// </summary> /// </summary>
/// <returns>不透明度。</returns> /// <returns>不透明度。</returns>
public override object GetAnimation() public override object GetAnimation() {
{
var opacity = base.Counter.CurrentValue * 255 / TimeMs; var opacity = base.Counter.CurrentValue * 255 / TimeMs;
return opacity; return opacity;
} }

View File

@ -1,21 +1,13 @@
using System; namespace TJAPlayer3.Animations {
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TJAPlayer3.Animations
{
/// <summary> /// <summary>
/// フェードアウトを行うクラス。 /// フェードアウトを行うクラス。
/// </summary> /// </summary>
internal class FadeOut : Animator internal class FadeOut : Animator {
{
/// <summary> /// <summary>
/// フェードアウトを初期化します。 /// フェードアウトを初期化します。
/// </summary> /// </summary>
/// <param name="timems">フェードアウトに掛ける秒数(ミリ秒)</param> /// <param name="timems">フェードアウトに掛ける秒数(ミリ秒)</param>
public FadeOut(int timems) : base(0, timems - 1, 1, false) public FadeOut(int timems) : base(0, timems - 1, 1, false) {
{
TimeMs = timems; TimeMs = timems;
} }
@ -23,8 +15,7 @@ namespace TJAPlayer3.Animations
/// フェードアウトの不透明度を255段階で返します。 /// フェードアウトの不透明度を255段階で返します。
/// </summary> /// </summary>
/// <returns>不透明度。</returns> /// <returns>不透明度。</returns>
public override object GetAnimation() public override object GetAnimation() {
{
var opacity = (TimeMs - base.Counter.CurrentValue) * 255 / TimeMs; var opacity = (TimeMs - base.Counter.CurrentValue) * 255 / TimeMs;
return opacity; return opacity;
} }

View File

@ -1,15 +1,8 @@
using System; namespace TJAPlayer3.Animations {
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TJAPlayer3.Animations
{
/// <summary> /// <summary>
/// アニメーション インターフェイス。 /// アニメーション インターフェイス。
/// </summary> /// </summary>
interface IAnimatable interface IAnimatable {
{
/// <summary> /// <summary>
/// アニメーションを開始します。 /// アニメーションを開始します。
/// </summary> /// </summary>

View File

@ -1,31 +1,22 @@
using System; namespace TJAPlayer3.Animations {
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TJAPlayer3.Animations
{
/// <summary> /// <summary>
/// リニア移動を行うクラス。 /// リニア移動を行うクラス。
/// </summary> /// </summary>
class Linear : Animator class Linear : Animator {
{
/// <summary> /// <summary>
/// リニア移動を初期化します。 /// リニア移動を初期化します。
/// </summary> /// </summary>
/// <param name="startPoint">始点。</param> /// <param name="startPoint">始点。</param>
/// <param name="endPoint">終点。</param> /// <param name="endPoint">終点。</param>
/// <param name="timeMs">移動にかける時間。</param> /// <param name="timeMs">移動にかける時間。</param>
public Linear(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) public Linear(int startPoint, int endPoint, int timeMs) : base(0, timeMs, 1, false) {
{
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Sa = EndPoint - StartPoint; Sa = EndPoint - StartPoint;
TimeMs = timeMs; TimeMs = timeMs;
} }
public override object GetAnimation() public override object GetAnimation() {
{
var persent = Counter.CurrentValue / (double)TimeMs; var persent = Counter.CurrentValue / (double)TimeMs;
return (Sa * persent) + StartPoint; return (Sa * persent) + StartPoint;
} }

View File

@ -1,14 +1,7 @@
using System; using FDK;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ class CMenuCharacter {
class CMenuCharacter
{
private static CCounter[] ctCharacterNormal = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterNormal = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
private static CCounter[] ctCharacterSelect = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterSelect = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
private static CCounter[] ctCharacterStart = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterStart = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
@ -16,8 +9,7 @@ namespace TJAPlayer3
private static CCounter[] ctCharacterEntry = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterEntry = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
private static CCounter[] ctCharacterEntryNormal = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterEntryNormal = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
public enum ECharacterAnimation public enum ECharacterAnimation {
{
// Song select // Song select
NORMAL, NORMAL,
START, START,
@ -29,46 +21,37 @@ namespace TJAPlayer3
} }
private static bool _usesSubstituteTexture(int player, ECharacterAnimation eca) private static bool _usesSubstituteTexture(int player, ECharacterAnimation eca) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) {
{ switch (eca) {
switch (eca) case (ECharacterAnimation.NORMAL): {
{
case (ECharacterAnimation.NORMAL):
{
if (TJAPlayer3.Tx.Characters_Menu_Loop[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Loop[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterAnimation.START): case (ECharacterAnimation.START): {
{
if (TJAPlayer3.Tx.Characters_Menu_Start[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Start[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterAnimation.SELECT): case (ECharacterAnimation.SELECT): {
{
if (TJAPlayer3.Tx.Characters_Menu_Select[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Select[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterAnimation.WAIT): case (ECharacterAnimation.WAIT): {
{
if (TJAPlayer3.Tx.Characters_Menu_Wait[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Wait[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterAnimation.ENTRY): case (ECharacterAnimation.ENTRY): {
{
if (TJAPlayer3.Tx.Characters_Title_Entry[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Title_Entry[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterAnimation.ENTRY_NORMAL): case (ECharacterAnimation.ENTRY_NORMAL): {
{
if (TJAPlayer3.Tx.Characters_Title_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Title_Normal[_charaId].Length > 0)
return false; return false;
break; break;
@ -79,40 +62,33 @@ namespace TJAPlayer3
return true; return true;
} }
public static CTexture[] _getReferenceArray(int player, ECharacterAnimation eca) public static CTexture[] _getReferenceArray(int player, ECharacterAnimation eca) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) {
{ switch (eca) {
switch (eca) case (ECharacterAnimation.NORMAL): {
{
case (ECharacterAnimation.NORMAL):
{
if (TJAPlayer3.Tx.Characters_Menu_Loop[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Loop[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Menu_Loop[_charaId]; return TJAPlayer3.Tx.Characters_Menu_Loop[_charaId];
if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Normal[_charaId]; return TJAPlayer3.Tx.Characters_Normal[_charaId];
break; break;
} }
case (ECharacterAnimation.START): case (ECharacterAnimation.START): {
{
if (TJAPlayer3.Tx.Characters_Menu_Start[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Start[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Menu_Start[_charaId]; return TJAPlayer3.Tx.Characters_Menu_Start[_charaId];
if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_10Combo[_charaId]; return TJAPlayer3.Tx.Characters_10Combo[_charaId];
break; break;
} }
case (ECharacterAnimation.SELECT): case (ECharacterAnimation.SELECT): {
{
if (TJAPlayer3.Tx.Characters_Menu_Select[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Select[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Menu_Select[_charaId]; return TJAPlayer3.Tx.Characters_Menu_Select[_charaId];
if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_10Combo[_charaId]; return TJAPlayer3.Tx.Characters_10Combo[_charaId];
break; break;
} }
case (ECharacterAnimation.WAIT): case (ECharacterAnimation.WAIT): {
{
if (TJAPlayer3.Tx.Characters_Menu_Wait[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Wait[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Menu_Wait[_charaId]; return TJAPlayer3.Tx.Characters_Menu_Wait[_charaId];
if (TJAPlayer3.Tx.Characters_Menu_Loop[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Menu_Loop[_charaId].Length > 0)
@ -121,16 +97,14 @@ namespace TJAPlayer3
return TJAPlayer3.Tx.Characters_GoGoTime[_charaId]; return TJAPlayer3.Tx.Characters_GoGoTime[_charaId];
break; break;
} }
case (ECharacterAnimation.ENTRY): case (ECharacterAnimation.ENTRY): {
{
if (TJAPlayer3.Tx.Characters_Title_Entry[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Title_Entry[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Title_Entry[_charaId]; return TJAPlayer3.Tx.Characters_Title_Entry[_charaId];
if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_10Combo[_charaId]; return TJAPlayer3.Tx.Characters_10Combo[_charaId];
break; break;
} }
case (ECharacterAnimation.ENTRY_NORMAL): case (ECharacterAnimation.ENTRY_NORMAL): {
{
if (TJAPlayer3.Tx.Characters_Title_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Title_Normal[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Title_Normal[_charaId]; return TJAPlayer3.Tx.Characters_Title_Normal[_charaId];
if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0)
@ -144,108 +118,84 @@ namespace TJAPlayer3
return null; return null;
} }
public static CCounter[] _getReferenceCounter(ECharacterAnimation eca) public static CCounter[] _getReferenceCounter(ECharacterAnimation eca) {
{ switch (eca) {
switch (eca) case (ECharacterAnimation.NORMAL): {
{
case (ECharacterAnimation.NORMAL):
{
return ctCharacterNormal; return ctCharacterNormal;
} }
case (ECharacterAnimation.START): case (ECharacterAnimation.START): {
{
return ctCharacterStart; return ctCharacterStart;
} }
case (ECharacterAnimation.SELECT): case (ECharacterAnimation.SELECT): {
{
return ctCharacterSelect; return ctCharacterSelect;
} }
case (ECharacterAnimation.WAIT): case (ECharacterAnimation.WAIT): {
{
return ctCharacterWait; return ctCharacterWait;
} }
case (ECharacterAnimation.ENTRY): case (ECharacterAnimation.ENTRY): {
{
return ctCharacterEntry; return ctCharacterEntry;
} }
case (ECharacterAnimation.ENTRY_NORMAL): case (ECharacterAnimation.ENTRY_NORMAL): {
{
return ctCharacterEntryNormal; return ctCharacterEntryNormal;
} }
} }
return null; return null;
} }
public static int _getReferenceAnimationDuration(int player, ECharacterAnimation eca) public static int _getReferenceAnimationDuration(int player, ECharacterAnimation eca) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
switch (eca) switch (eca) {
{ case (ECharacterAnimation.NORMAL): {
case (ECharacterAnimation.NORMAL):
{
return TJAPlayer3.Skin.Characters_Menu_Loop_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Menu_Loop_AnimationDuration[_charaId];
} }
case (ECharacterAnimation.START): case (ECharacterAnimation.START): {
{
return TJAPlayer3.Skin.Characters_Menu_Start_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Menu_Start_AnimationDuration[_charaId];
} }
case (ECharacterAnimation.SELECT): case (ECharacterAnimation.SELECT): {
{
return TJAPlayer3.Skin.Characters_Menu_Select_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Menu_Select_AnimationDuration[_charaId];
} }
case (ECharacterAnimation.WAIT): case (ECharacterAnimation.WAIT): {
{
return TJAPlayer3.Skin.Characters_Menu_Wait_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Menu_Wait_AnimationDuration[_charaId];
} }
case (ECharacterAnimation.ENTRY): case (ECharacterAnimation.ENTRY): {
{
return TJAPlayer3.Skin.Characters_Title_Entry_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Title_Entry_AnimationDuration[_charaId];
} }
case (ECharacterAnimation.ENTRY_NORMAL): case (ECharacterAnimation.ENTRY_NORMAL): {
{
return TJAPlayer3.Skin.Characters_Title_Normal_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Title_Normal_AnimationDuration[_charaId];
} }
} }
return 1000; return 1000;
} }
public static void tDisableCounter(ECharacterAnimation eca) public static void tDisableCounter(ECharacterAnimation eca) {
{ switch (eca) {
switch (eca) case (ECharacterAnimation.NORMAL): {
{
case (ECharacterAnimation.NORMAL):
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterNormal[i] = new CCounter(); ctCharacterNormal[i] = new CCounter();
break; break;
} }
case (ECharacterAnimation.START): case (ECharacterAnimation.START): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterStart[i] = new CCounter(); ctCharacterStart[i] = new CCounter();
break; break;
} }
case (ECharacterAnimation.SELECT): case (ECharacterAnimation.SELECT): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterSelect[i] = new CCounter(); ctCharacterSelect[i] = new CCounter();
break; break;
} }
case (ECharacterAnimation.WAIT): case (ECharacterAnimation.WAIT): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterWait[i] = new CCounter(); ctCharacterWait[i] = new CCounter();
break; break;
} }
case (ECharacterAnimation.ENTRY): case (ECharacterAnimation.ENTRY): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterEntry[i] = new CCounter(); ctCharacterEntry[i] = new CCounter();
break; break;
} }
case (ECharacterAnimation.ENTRY_NORMAL): case (ECharacterAnimation.ENTRY_NORMAL): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterEntryNormal[i] = new CCounter(); ctCharacterEntryNormal[i] = new CCounter();
break; break;
@ -255,35 +205,29 @@ namespace TJAPlayer3
} }
public static void tMenuResetTimer(int player, ECharacterAnimation eca) public static void tMenuResetTimer(int player, ECharacterAnimation eca) {
{
CTexture[] _ref = _getReferenceArray(player, eca); CTexture[] _ref = _getReferenceArray(player, eca);
CCounter[] _ctref = _getReferenceCounter(eca); CCounter[] _ctref = _getReferenceCounter(eca);
int _animeref = _getReferenceAnimationDuration(player, eca); int _animeref = _getReferenceAnimationDuration(player, eca);
if (_ref != null && _ref.Length > 0 && _ctref != null) if (_ref != null && _ref.Length > 0 && _ctref != null) {
{
_ctref[player] = new CCounter(0, _ref.Length - 1, _animeref / (float)_ref.Length, TJAPlayer3.Timer); _ctref[player] = new CCounter(0, _ref.Length - 1, _animeref / (float)_ref.Length, TJAPlayer3.Timer);
} }
} }
public static void tMenuResetTimer(ECharacterAnimation eca) public static void tMenuResetTimer(ECharacterAnimation eca) {
{ for (int i = 0; i < 5; i++) {
for (int i = 0; i < 5; i++)
{
tMenuResetTimer(i, eca); tMenuResetTimer(i, eca);
} }
} }
public static void tMenuDisplayCharacter(int player, int x, int y, ECharacterAnimation eca, int opacity = 255) public static void tMenuDisplayCharacter(int player, int x, int y, ECharacterAnimation eca, int opacity = 255) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
CTexture[] _ref = _getReferenceArray(player, eca); CTexture[] _ref = _getReferenceArray(player, eca);
CCounter[] _ctref = _getReferenceCounter(eca); CCounter[] _ctref = _getReferenceCounter(eca);
bool _substitute = _usesSubstituteTexture(player, eca); bool _substitute = _usesSubstituteTexture(player, eca);
if (_ctref[player] != null && _ref != null && _ctref[player].CurrentValue < _ref.Length) if (_ctref[player] != null && _ref != null && _ctref[player].CurrentValue < _ref.Length) {
{
if (eca == ECharacterAnimation.NORMAL if (eca == ECharacterAnimation.NORMAL
|| eca == ECharacterAnimation.WAIT || eca == ECharacterAnimation.WAIT
|| eca == ECharacterAnimation.ENTRY || eca == ECharacterAnimation.ENTRY
@ -311,8 +255,7 @@ namespace TJAPlayer3
float _x = x; float _x = x;
float _y = y; float _y = y;
if (player % 2 == 0) if (player % 2 == 0) {
{
//_ref[_ctref[player].n現在の値].t2D描画(x, y); //_ref[_ctref[player].n現在の値].t2D描画(x, y);
//_ref[_ctref[player].n現在の値].t2D中心基準描画(x + 150, y + 156); //_ref[_ctref[player].n現在の値].t2D中心基準描画(x + 150, y + 156);
@ -323,9 +266,7 @@ namespace TJAPlayer3
} } else {
else
{
//_ref[_ctref[player].n現在の値].t2D左右反転描画(x, y); //_ref[_ctref[player].n現在の値].t2D左右反転描画(x, y);
//_ref[_ctref[player].n現在の値].t2D中心基準描画Mirrored(x + 150, y + 156); //_ref[_ctref[player].n現在の値].t2D中心基準描画Mirrored(x + 150, y + 156);

View File

@ -1,22 +1,14 @@
using System; using FDK;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ class CResultCharacter {
class CResultCharacter
{
private static CCounter[] ctCharacterNormal = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterNormal = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
private static CCounter[] ctCharacterClear = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterClear = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
private static CCounter[] ctCharacterFailed = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterFailed = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
private static CCounter[] ctCharacterFailedIn = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() }; private static CCounter[] ctCharacterFailedIn = new CCounter[5] { new CCounter(), new CCounter(), new CCounter(), new CCounter(), new CCounter() };
public enum ECharacterResult public enum ECharacterResult {
{
// Song select // Song select
NORMAL, NORMAL,
CLEAR, CLEAR,
@ -24,8 +16,7 @@ namespace TJAPlayer3
FAILED_IN, FAILED_IN,
} }
public static bool tIsCounterProcessing(int player, ECharacterResult eca) public static bool tIsCounterProcessing(int player, ECharacterResult eca) {
{
CCounter[] _ctref = _getReferenceCounter(eca); CCounter[] _ctref = _getReferenceCounter(eca);
if (_ctref[player] != null) if (_ctref[player] != null)
@ -33,8 +24,7 @@ namespace TJAPlayer3
return false; return false;
} }
public static bool tIsCounterEnded(int player, ECharacterResult eca) public static bool tIsCounterEnded(int player, ECharacterResult eca) {
{
CCounter[] _ctref = _getReferenceCounter(eca); CCounter[] _ctref = _getReferenceCounter(eca);
if (_ctref[player] != null) if (_ctref[player] != null)
@ -42,34 +32,27 @@ namespace TJAPlayer3
return false; return false;
} }
private static bool _usesSubstituteTexture(int player, ECharacterResult eca) private static bool _usesSubstituteTexture(int player, ECharacterResult eca) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) {
{ switch (eca) {
switch (eca) case (ECharacterResult.NORMAL): {
{
case (ECharacterResult.NORMAL):
{
if (TJAPlayer3.Tx.Characters_Result_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Normal[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterResult.CLEAR): case (ECharacterResult.CLEAR): {
{
if (TJAPlayer3.Tx.Characters_Result_Clear[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Clear[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterResult.FAILED): case (ECharacterResult.FAILED): {
{
if (TJAPlayer3.Tx.Characters_Result_Failed[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Failed[_charaId].Length > 0)
return false; return false;
break; break;
} }
case (ECharacterResult.FAILED_IN): case (ECharacterResult.FAILED_IN): {
{
if (TJAPlayer3.Tx.Characters_Result_Failed_In[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Failed_In[_charaId].Length > 0)
return false; return false;
break; break;
@ -80,40 +63,33 @@ namespace TJAPlayer3
return true; return true;
} }
public static CTexture[] _getReferenceArray(int player, ECharacterResult eca) public static CTexture[] _getReferenceArray(int player, ECharacterResult eca) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) if (_charaId >= 0 && _charaId < TJAPlayer3.Skin.Characters_Ptn) {
{ switch (eca) {
switch (eca) case (ECharacterResult.NORMAL): {
{
case (ECharacterResult.NORMAL):
{
if (TJAPlayer3.Tx.Characters_Result_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Normal[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Result_Normal[_charaId]; return TJAPlayer3.Tx.Characters_Result_Normal[_charaId];
if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Normal[_charaId]; return TJAPlayer3.Tx.Characters_Normal[_charaId];
break; break;
} }
case (ECharacterResult.CLEAR): case (ECharacterResult.CLEAR): {
{
if (TJAPlayer3.Tx.Characters_Result_Clear[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Clear[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Result_Clear[_charaId]; return TJAPlayer3.Tx.Characters_Result_Clear[_charaId];
if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_10Combo[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_10Combo[_charaId]; return TJAPlayer3.Tx.Characters_10Combo[_charaId];
break; break;
} }
case (ECharacterResult.FAILED): case (ECharacterResult.FAILED): {
{
if (TJAPlayer3.Tx.Characters_Result_Failed[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Failed[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Result_Failed[_charaId]; return TJAPlayer3.Tx.Characters_Result_Failed[_charaId];
if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Normal[_charaId]; return TJAPlayer3.Tx.Characters_Normal[_charaId];
break; break;
} }
case (ECharacterResult.FAILED_IN): case (ECharacterResult.FAILED_IN): {
{
if (TJAPlayer3.Tx.Characters_Result_Failed_In[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Result_Failed_In[_charaId].Length > 0)
return TJAPlayer3.Tx.Characters_Result_Failed_In[_charaId]; return TJAPlayer3.Tx.Characters_Result_Failed_In[_charaId];
if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0) if (TJAPlayer3.Tx.Characters_Normal[_charaId].Length > 0)
@ -127,80 +103,62 @@ namespace TJAPlayer3
return null; return null;
} }
public static CCounter[] _getReferenceCounter(ECharacterResult eca) public static CCounter[] _getReferenceCounter(ECharacterResult eca) {
{ switch (eca) {
switch (eca) case (ECharacterResult.NORMAL): {
{
case (ECharacterResult.NORMAL):
{
return ctCharacterNormal; return ctCharacterNormal;
} }
case (ECharacterResult.CLEAR): case (ECharacterResult.CLEAR): {
{
return ctCharacterClear; return ctCharacterClear;
} }
case (ECharacterResult.FAILED): case (ECharacterResult.FAILED): {
{
return ctCharacterFailed; return ctCharacterFailed;
} }
case (ECharacterResult.FAILED_IN): case (ECharacterResult.FAILED_IN): {
{
return ctCharacterFailedIn; return ctCharacterFailedIn;
} }
} }
return null; return null;
} }
public static int _getReferenceAnimationDuration(int player, ECharacterResult eca) public static int _getReferenceAnimationDuration(int player, ECharacterResult eca) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
switch (eca) switch (eca) {
{ case (ECharacterResult.NORMAL): {
case (ECharacterResult.NORMAL):
{
return TJAPlayer3.Skin.Characters_Result_Normal_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Result_Normal_AnimationDuration[_charaId];
} }
case (ECharacterResult.CLEAR): case (ECharacterResult.CLEAR): {
{
return TJAPlayer3.Skin.Characters_Result_Clear_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Result_Clear_AnimationDuration[_charaId];
} }
case (ECharacterResult.FAILED): case (ECharacterResult.FAILED): {
{
return TJAPlayer3.Skin.Characters_Result_Failed_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Result_Failed_AnimationDuration[_charaId];
} }
case (ECharacterResult.FAILED_IN): case (ECharacterResult.FAILED_IN): {
{
return TJAPlayer3.Skin.Characters_Result_Failed_In_AnimationDuration[_charaId]; return TJAPlayer3.Skin.Characters_Result_Failed_In_AnimationDuration[_charaId];
} }
} }
return 1000; return 1000;
} }
public static void tDisableCounter(ECharacterResult eca) public static void tDisableCounter(ECharacterResult eca) {
{ switch (eca) {
switch (eca) case (ECharacterResult.NORMAL): {
{
case (ECharacterResult.NORMAL):
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterNormal[i] = new CCounter(); ctCharacterNormal[i] = new CCounter();
break; break;
} }
case (ECharacterResult.CLEAR): case (ECharacterResult.CLEAR): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterClear[i] = new CCounter(); ctCharacterClear[i] = new CCounter();
break; break;
} }
case (ECharacterResult.FAILED): case (ECharacterResult.FAILED): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterFailed[i] = new CCounter(); ctCharacterFailed[i] = new CCounter();
break; break;
} }
case (ECharacterResult.FAILED_IN): case (ECharacterResult.FAILED_IN): {
{
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
ctCharacterFailedIn[i] = new CCounter(); ctCharacterFailedIn[i] = new CCounter();
break; break;
@ -210,35 +168,29 @@ namespace TJAPlayer3
} }
public static void tMenuResetTimer(int player, ECharacterResult eca) public static void tMenuResetTimer(int player, ECharacterResult eca) {
{
CTexture[] _ref = _getReferenceArray(player, eca); CTexture[] _ref = _getReferenceArray(player, eca);
CCounter[] _ctref = _getReferenceCounter(eca); CCounter[] _ctref = _getReferenceCounter(eca);
int _animeref = _getReferenceAnimationDuration(player, eca); int _animeref = _getReferenceAnimationDuration(player, eca);
if (_ref != null && _ref.Length > 0 && _ctref != null) if (_ref != null && _ref.Length > 0 && _ctref != null) {
{
_ctref[player] = new CCounter(0, _ref.Length - 1, _animeref / (float)_ref.Length, TJAPlayer3.Timer); _ctref[player] = new CCounter(0, _ref.Length - 1, _animeref / (float)_ref.Length, TJAPlayer3.Timer);
} }
} }
public static void tMenuResetTimer(ECharacterResult eca) public static void tMenuResetTimer(ECharacterResult eca) {
{ for (int i = 0; i < 5; i++) {
for (int i = 0; i < 5; i++)
{
tMenuResetTimer(i, eca); tMenuResetTimer(i, eca);
} }
} }
public static void tMenuDisplayCharacter(int player, int x, int y, ECharacterResult eca, int pos = 0, int opacity = 255) public static void tMenuDisplayCharacter(int player, int x, int y, ECharacterResult eca, int pos = 0, int opacity = 255) {
{
int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character; int _charaId = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(player)].data.Character;
CTexture[] _ref = _getReferenceArray(player, eca); CTexture[] _ref = _getReferenceArray(player, eca);
CCounter[] _ctref = _getReferenceCounter(eca); CCounter[] _ctref = _getReferenceCounter(eca);
bool _substitute = _usesSubstituteTexture(player, eca); bool _substitute = _usesSubstituteTexture(player, eca);
if (_ctref[player] != null && _ref != null && _ctref[player].CurrentValue < _ref.Length) if (_ctref[player] != null && _ref != null && _ctref[player].CurrentValue < _ref.Length) {
{
if (eca == ECharacterResult.NORMAL if (eca == ECharacterResult.NORMAL
|| eca == ECharacterResult.CLEAR || eca == ECharacterResult.CLEAR
|| eca == ECharacterResult.FAILED) || eca == ECharacterResult.FAILED)
@ -268,15 +220,12 @@ namespace TJAPlayer3
_tex.vcScaleRatio.X *= resolutionRatioX; _tex.vcScaleRatio.X *= resolutionRatioX;
_tex.vcScaleRatio.Y *= resolutionRatioY; _tex.vcScaleRatio.Y *= resolutionRatioY;
if (pos % 2 == 0 || TJAPlayer3.ConfigIni.nPlayerCount > 2) if (pos % 2 == 0 || TJAPlayer3.ConfigIni.nPlayerCount > 2) {
{
_tex.t2D拡大率考慮下中心基準描画( _tex.t2D拡大率考慮下中心基準描画(
_x, _x,
_y _y
); );
} } else {
else
{
_tex.t2D拡大率考慮下中心基準描画Mirrored( _tex.t2D拡大率考慮下中心基準描画Mirrored(
_x, _x,
_y _y

View File

@ -1,41 +1,28 @@
using TJAPlayer3; using FDK;
using FDK;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using Silk.NET.Maths; using Silk.NET.Maths;
using Rectangle = System.Drawing.Rectangle; using Rectangle = System.Drawing.Rectangle;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ class PuchiChara : CActivity {
class PuchiChara : CActivity public PuchiChara() {
{
public PuchiChara()
{
base.IsDeActivated = true; base.IsDeActivated = true;
} }
public override void Activate() public override void Activate() {
{
Counter = new CCounter(0, TJAPlayer3.Skin.Game_PuchiChara[2] - 1, TJAPlayer3.Skin.Game_PuchiChara_Timer * 0.5f, TJAPlayer3.Timer); Counter = new CCounter(0, TJAPlayer3.Skin.Game_PuchiChara[2] - 1, TJAPlayer3.Skin.Game_PuchiChara_Timer * 0.5f, TJAPlayer3.Timer);
SineCounter = new CCounter(0, 360, TJAPlayer3.Skin.Game_PuchiChara_SineTimer, SoundManager.PlayTimer); SineCounter = new CCounter(0, 360, TJAPlayer3.Skin.Game_PuchiChara_SineTimer, SoundManager.PlayTimer);
SineCounterIdle = new CCounter(1, 360, (float)TJAPlayer3.Skin.Game_PuchiChara_SineTimer * 2f, TJAPlayer3.Timer); SineCounterIdle = new CCounter(1, 360, (float)TJAPlayer3.Skin.Game_PuchiChara_SineTimer * 2f, TJAPlayer3.Timer);
this.inGame = false; this.inGame = false;
base.Activate(); base.Activate();
} }
public override void DeActivate() public override void DeActivate() {
{
Counter = null; Counter = null;
SineCounter = null; SineCounter = null;
SineCounterIdle = null; SineCounterIdle = null;
base.DeActivate(); base.DeActivate();
} }
public static int tGetPuchiCharaIndexByName(int p) public static int tGetPuchiCharaIndexByName(int p) {
{
var _pc = TJAPlayer3.SaveFileInstances[p].data.PuchiChara; var _pc = TJAPlayer3.SaveFileInstances[p].data.PuchiChara;
var _pcs = TJAPlayer3.Skin.Puchicharas_Name; var _pcs = TJAPlayer3.Skin.Puchicharas_Name;
int puriChar = 0; int puriChar = 0;
@ -45,15 +32,13 @@ namespace TJAPlayer3
return puriChar; return puriChar;
} }
public void ChangeBPM(double bpm) public void ChangeBPM(double bpm) {
{
Counter = new CCounter(0, TJAPlayer3.Skin.Game_PuchiChara[2] - 1, (int)(TJAPlayer3.Skin.Game_PuchiChara_Timer * bpm / TJAPlayer3.Skin.Game_PuchiChara[2]), TJAPlayer3.Timer); Counter = new CCounter(0, TJAPlayer3.Skin.Game_PuchiChara[2] - 1, (int)(TJAPlayer3.Skin.Game_PuchiChara_Timer * bpm / TJAPlayer3.Skin.Game_PuchiChara[2]), TJAPlayer3.Timer);
SineCounter = new CCounter(1, 360, TJAPlayer3.Skin.Game_PuchiChara_SineTimer * bpm / 180, SoundManager.PlayTimer); SineCounter = new CCounter(1, 360, TJAPlayer3.Skin.Game_PuchiChara_SineTimer * bpm / 180, SoundManager.PlayTimer);
this.inGame = true; this.inGame = true;
} }
public void IdleAnimation() public void IdleAnimation() {
{
this.inGame = false; this.inGame = false;
} }
@ -64,8 +49,7 @@ namespace TJAPlayer3
/// <param name="y">Y座標(中央)</param> /// <param name="y">Y座標(中央)</param>
/// <param name="alpha">不透明度</param> /// <param name="alpha">不透明度</param>
/// <returns></returns> /// <returns></returns>
public int On進行描画(int x, int y, bool isGrowing, int alpha = 255, bool isBalloon = false, int player = 0, float scale = 1.0f) public int On進行描画(int x, int y, bool isGrowing, int alpha = 255, bool isBalloon = false, int player = 0, float scale = 1.0f) {
{
if (!TJAPlayer3.ConfigIni.ShowPuchiChara) return base.Draw(); if (!TJAPlayer3.ConfigIni.ShowPuchiChara) return base.Draw();
if (Counter == null || SineCounter == null || TJAPlayer3.Tx.Puchichara == null) return base.Draw(); if (Counter == null || SineCounter == null || TJAPlayer3.Tx.Puchichara == null) return base.Draw();
Counter.TickLoop(); Counter.TickLoop();
@ -98,8 +82,7 @@ namespace TJAPlayer3
var chara = TJAPlayer3.Tx.Puchichara[puriChar].tx; var chara = TJAPlayer3.Tx.Puchichara[puriChar].tx;
//TJAPlayer3.Tx.PuchiChara[puriChar]; //TJAPlayer3.Tx.PuchiChara[puriChar];
if (chara != null) if (chara != null) {
{
float puchiScale = TJAPlayer3.Skin.Resolution[1] / 720.0f; float puchiScale = TJAPlayer3.Skin.Resolution[1] / 720.0f;
chara.vcScaleRatio = new Vector3D<float>((isBalloon ? TJAPlayer3.Skin.Game_PuchiChara_Scale[1] * puchiScale : TJAPlayer3.Skin.Game_PuchiChara_Scale[0] * puchiScale)); chara.vcScaleRatio = new Vector3D<float>((isBalloon ? TJAPlayer3.Skin.Game_PuchiChara_Scale[1] * puchiScale : TJAPlayer3.Skin.Game_PuchiChara_Scale[0] * puchiScale));

View File

@ -1,17 +1,7 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; internal class BestPlayRecords {
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace TJAPlayer3 public enum EClearStatus {
{
internal class BestPlayRecords
{
public enum EClearStatus
{
NONE = 0, NONE = 0,
ASSISTED_CLEAR = 1, ASSISTED_CLEAR = 1,
CLEAR = 2, CLEAR = 2,
@ -20,8 +10,7 @@ namespace TJAPlayer3
TOTAL = 5 TOTAL = 5
} }
public enum EDanClearStatus public enum EDanClearStatus {
{
NONE = 0, NONE = 0,
ASSISTED_CLEAR_RED = 1, ASSISTED_CLEAR_RED = 1,
ASSISTED_CLEAR_GOLD = 2, ASSISTED_CLEAR_GOLD = 2,
@ -34,8 +23,7 @@ namespace TJAPlayer3
TOTAL = 9 TOTAL = 9
} }
public enum ETowerClearStatus public enum ETowerClearStatus {
{
NONE = 0, NONE = 0,
ASSISTED_CLEAR = 1, ASSISTED_CLEAR = 1,
PROGRESS_10 = 2, PROGRESS_10 = 2,
@ -48,8 +36,7 @@ namespace TJAPlayer3
TOTAL = 9 TOTAL = 9
} }
public class CSongSelectTableEntry public class CSongSelectTableEntry {
{
public int ScoreRankDifficulty = 0; public int ScoreRankDifficulty = 0;
public int ScoreRank = -1; public int ScoreRank = -1;
public int ClearStatusDifficulty = 0; public int ClearStatusDifficulty = 0;
@ -60,8 +47,7 @@ namespace TJAPlayer3
public int[] HighScore = new int[(int)Difficulty.Total] { 0, 0, 0, 0, 0, 0, 0 }; public int[] HighScore = new int[(int)Difficulty.Total] { 0, 0, 0, 0, 0, 0, 0 };
} }
public class CBestPlayRecord public class CBestPlayRecord {
{
public string ChartUniqueId = "none"; public string ChartUniqueId = "none";
public string ChartGenre = "none"; public string ChartGenre = "none";
public string Charter = "none"; public string Charter = "none";
@ -90,8 +76,7 @@ namespace TJAPlayer3
public Int64 HighScoreBoomCount = 0; public Int64 HighScoreBoomCount = 0;
} }
public class CBestPlayStats public class CBestPlayStats {
{
public int DistinctPlays = 0; public int DistinctPlays = 0;
public int DistinctClears = 0; public int DistinctClears = 0;
public int DistinctFCs = 0; public int DistinctFCs = 0;
@ -119,8 +104,7 @@ namespace TJAPlayer3
public Dictionary<string, int> CharterFCs = new Dictionary<string, int>(); public Dictionary<string, int> CharterFCs = new Dictionary<string, int>();
public Dictionary<string, int> CharterPerfects = new Dictionary<string, int>(); public Dictionary<string, int> CharterPerfects = new Dictionary<string, int>();
public CBestPlayStats() public CBestPlayStats() {
{
// 0 : Not clear, 1 : Assisted clear, 2 : Clear, 3 : FC, 4 : Perfect // 0 : Not clear, 1 : Assisted clear, 2 : Clear, 3 : FC, 4 : Perfect
ClearStatuses[0] = new int[(int)EClearStatus.TOTAL] { 0, 0, 0, 0, 0 }; ClearStatuses[0] = new int[(int)EClearStatus.TOTAL] { 0, 0, 0, 0, 0 };
ClearStatuses[1] = new int[(int)EClearStatus.TOTAL] { 0, 0, 0, 0, 0 }; ClearStatuses[1] = new int[(int)EClearStatus.TOTAL] { 0, 0, 0, 0, 0 };
@ -139,8 +123,7 @@ namespace TJAPlayer3
} }
} }
static private void InitOrAddDict<T>(Dictionary<T, int> dict, T entry) where T : notnull static private void InitOrAddDict<T>(Dictionary<T, int> dict, T entry) where T : notnull {
{
if (!dict.ContainsKey(entry)) if (!dict.ContainsKey(entry))
dict[entry] = 0; dict[entry] = 0;
dict[entry]++; dict[entry]++;
@ -149,24 +132,20 @@ namespace TJAPlayer3
static public CBestPlayStats tGenerateBestPlayStats( static public CBestPlayStats tGenerateBestPlayStats(
Dictionary<string, CBestPlayRecord>.ValueCollection uniqueChartBestPlays, Dictionary<string, CBestPlayRecord>.ValueCollection uniqueChartBestPlays,
Dictionary<string, CBestPlayRecord>.ValueCollection uniqueSongBestPlays Dictionary<string, CBestPlayRecord>.ValueCollection uniqueSongBestPlays
) ) {
{
CBestPlayStats stats = new CBestPlayStats(); CBestPlayStats stats = new CBestPlayStats();
// Individual charts // Individual charts
foreach (CBestPlayRecord record in uniqueChartBestPlays) foreach (CBestPlayRecord record in uniqueChartBestPlays) {
{
Int64 roundedDifficulty = Math.Max((int)Difficulty.Easy, Math.Min((int)Difficulty.Total - 1, record.ChartDifficulty)); Int64 roundedDifficulty = Math.Max((int)Difficulty.Easy, Math.Min((int)Difficulty.Total - 1, record.ChartDifficulty));
if (roundedDifficulty <= (int)Difficulty.Edit) if (roundedDifficulty <= (int)Difficulty.Edit) {
{
string[] ChartersArr = record.Charter.SplitByCommas(); string[] ChartersArr = record.Charter.SplitByCommas();
Int64 roundedScoreRank = Math.Max(0, Math.Min(7, record.ScoreRank + 1)); Int64 roundedScoreRank = Math.Max(0, Math.Min(7, record.ScoreRank + 1));
Int64 roundedClearStatus = Math.Max((int)EClearStatus.NONE, Math.Min((int)EClearStatus.PERFECT, record.ClearStatus + 1)); Int64 roundedClearStatus = Math.Max((int)EClearStatus.NONE, Math.Min((int)EClearStatus.PERFECT, record.ClearStatus + 1));
stats.ScoreRanks[roundedDifficulty][roundedScoreRank]++; stats.ScoreRanks[roundedDifficulty][roundedScoreRank]++;
stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++; stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++;
foreach (string Charter in ChartersArr) foreach (string Charter in ChartersArr) {
{
InitOrAddDict(stats.CharterPlays, Charter); InitOrAddDict(stats.CharterPlays, Charter);
if (roundedClearStatus >= (int)EClearStatus.CLEAR) InitOrAddDict(stats.CharterClears, Charter); if (roundedClearStatus >= (int)EClearStatus.CLEAR) InitOrAddDict(stats.CharterClears, Charter);
if (roundedClearStatus >= (int)EClearStatus.FC) InitOrAddDict(stats.CharterFCs, Charter); if (roundedClearStatus >= (int)EClearStatus.FC) InitOrAddDict(stats.CharterFCs, Charter);
@ -184,15 +163,11 @@ namespace TJAPlayer3
if (roundedClearStatus >= (int)EClearStatus.CLEAR) stats.DistinctClears++; if (roundedClearStatus >= (int)EClearStatus.CLEAR) stats.DistinctClears++;
if (roundedClearStatus >= (int)EClearStatus.FC) stats.DistinctFCs++; if (roundedClearStatus >= (int)EClearStatus.FC) stats.DistinctFCs++;
if (roundedClearStatus == (int)EClearStatus.PERFECT) stats.DistinctPerfects++; if (roundedClearStatus == (int)EClearStatus.PERFECT) stats.DistinctPerfects++;
} } else if (roundedDifficulty == (int)Difficulty.Tower) {
else if (roundedDifficulty == (int)Difficulty.Tower)
{
Int64 roundedClearStatus = Math.Clamp(record.ClearStatus + 1, (int)ETowerClearStatus.NONE, (int)ETowerClearStatus.TOTAL); Int64 roundedClearStatus = Math.Clamp(record.ClearStatus + 1, (int)ETowerClearStatus.NONE, (int)ETowerClearStatus.TOTAL);
stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++; stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++;
} } else if (roundedDifficulty == (int)Difficulty.Dan) {
else if (roundedDifficulty == (int)Difficulty.Dan)
{
Int64 roundedClearStatus = Math.Clamp(record.ClearStatus + 1, (int)EDanClearStatus.NONE, (int)EDanClearStatus.TOTAL); Int64 roundedClearStatus = Math.Clamp(record.ClearStatus + 1, (int)EDanClearStatus.NONE, (int)EDanClearStatus.TOTAL);
stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++; stats.ClearStatuses[roundedDifficulty][roundedClearStatus]++;
@ -200,12 +175,10 @@ namespace TJAPlayer3
} }
// Individual songs // Individual songs
foreach (CBestPlayRecord record in uniqueSongBestPlays) foreach (CBestPlayRecord record in uniqueSongBestPlays) {
{
Int64 roundedDifficulty = Math.Max((int)Difficulty.Easy, Math.Min((int)Difficulty.Total - 1, record.ChartDifficulty)); Int64 roundedDifficulty = Math.Max((int)Difficulty.Easy, Math.Min((int)Difficulty.Total - 1, record.ChartDifficulty));
if (roundedDifficulty <= (int)Difficulty.Edit) if (roundedDifficulty <= (int)Difficulty.Edit) {
{
Int64 roundedClearStatus = Math.Max((int)EClearStatus.NONE, Math.Min((int)EClearStatus.PERFECT, record.ClearStatus + 1)); Int64 roundedClearStatus = Math.Max((int)EClearStatus.NONE, Math.Min((int)EClearStatus.PERFECT, record.ClearStatus + 1));
InitOrAddDict(stats.SongGenrePlays, record.ChartGenre); InitOrAddDict(stats.SongGenrePlays, record.ChartGenre);

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +1,18 @@
using System; using System.Security.Cryptography;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ internal class CCrypto {
internal class CCrypto
{
internal static readonly char[] chars = internal static readonly char[] chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray(); "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
public static string GetUniqueKey(int size) public static string GetUniqueKey(int size) {
{
byte[] data = new byte[4 * size]; byte[] data = new byte[4 * size];
using (var crypto = RandomNumberGenerator.Create()) using (var crypto = RandomNumberGenerator.Create()) {
{
crypto.GetBytes(data); crypto.GetBytes(data);
} }
StringBuilder result = new StringBuilder(size); StringBuilder result = new StringBuilder(size);
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++) {
{
var rnd = BitConverter.ToUInt32(data, i * 4); var rnd = BitConverter.ToUInt32(data, i * 4);
var idx = rnd % chars.Length; var idx = rnd % chars.Length;

View File

@ -1,23 +1,18 @@
using System; using System.Text;
using System.Collections.Generic;
using System.Text;
namespace TJAPlayer3 namespace TJAPlayer3 {
{
/// <summary> /// <summary>
/// <para>DTXMania のバージョン。</para> /// <para>DTXMania のバージョン。</para>
/// <para>例1"078b" → 整数部=078, 小数部=2000000 ('英字'+'yymmdd') </para> /// <para>例1"078b" → 整数部=078, 小数部=2000000 ('英字'+'yymmdd') </para>
/// <para>例2"078a(100124)" → 整数部=078, 小数部=1100124 ('英字'+'yymmdd')</para> /// <para>例2"078a(100124)" → 整数部=078, 小数部=1100124 ('英字'+'yymmdd')</para>
/// </summary> /// </summary>
public class CDTXVersion public class CDTXVersion {
{
// プロパティ // プロパティ
/// <summary> /// <summary>
/// <para>バージョンが未知のときに true になる。</para> /// <para>バージョンが未知のときに true になる。</para>
/// </summary> /// </summary>
public bool Unknown public bool Unknown {
{
get; get;
private set; private set;
} }
@ -40,79 +35,62 @@ namespace TJAPlayer3
// コンストラクタ // コンストラクタ
public CDTXVersion() public CDTXVersion() {
{
this.n整数部 = 0; this.n整数部 = 0;
this.n小数部 = 0; this.n小数部 = 0;
this.Unknown = true; this.Unknown = true;
} }
public CDTXVersion( int n整数部 ) public CDTXVersion(int n整数部) {
{
this.n整数部 = n整数部; this.n整数部 = n整数部;
this.n小数部 = 0; this.n小数部 = 0;
this.Unknown = false; this.Unknown = false;
} }
public CDTXVersion( string Version ) public CDTXVersion(string Version) {
{
this.n整数部 = 0; this.n整数部 = 0;
this.n小数部 = 0; this.n小数部 = 0;
this.Unknown = true; this.Unknown = true;
if( Version.ToLower().Equals( "unknown" ) ) if (Version.ToLower().Equals("unknown")) {
{
this.Unknown = true; this.Unknown = true;
} } else {
else
{
int num = 0; int num = 0;
int length = Version.Length; int length = Version.Length;
if( ( num < length ) && char.IsDigit( Version[ num ] ) ) if ((num < length) && char.IsDigit(Version[num])) {
{
// 整数部 取得 // 整数部 取得
while( ( num < length ) && char.IsDigit( Version[ num ] ) ) while ((num < length) && char.IsDigit(Version[num])) {
{
this.n整数部 = (this.n整数部 * 10) + CDTXVersion.DIG10.IndexOf(Version[num++]); this.n整数部 = (this.n整数部 * 10) + CDTXVersion.DIG10.IndexOf(Version[num++]);
} }
// 小数部(1)英字部分 取得 // 小数部(1)英字部分 取得
while( ( num < length ) && ( ( Version[ num ] == ' ' ) || ( Version[ num ] == '(' ) ) ) while ((num < length) && ((Version[num] == ' ') || (Version[num] == '('))) {
{
num++; num++;
} }
if( ( num < length ) && ( CDTXVersion.DIG36.IndexOf( Version[ num ] ) >= 10 ) ) if ((num < length) && (CDTXVersion.DIG36.IndexOf(Version[num]) >= 10)) {
{
this.n小数部 = CDTXVersion.DIG36.IndexOf(Version[num++]) - 10; this.n小数部 = CDTXVersion.DIG36.IndexOf(Version[num++]) - 10;
if( this.n小数部 >= 0x1a ) if (this.n小数部 >= 0x1a) {
{
this.n小数部 -= 0x1a; this.n小数部 -= 0x1a;
} }
this.n小数部++; this.n小数部++;
} }
// 小数部(2)日付部分(yymmdd) 取得 // 小数部(2)日付部分(yymmdd) 取得
while( ( num < length ) && ( ( Version[ num ] == ' ' ) || ( Version[ num ] == '(' ) ) ) while ((num < length) && ((Version[num] == ' ') || (Version[num] == '('))) {
{
num++; num++;
} }
for( int i = 0; i < 6; i++ ) for (int i = 0; i < 6; i++) {
{
this.n小数部 *= 10; this.n小数部 *= 10;
if( ( num < length ) && char.IsDigit( Version[ num ] ) ) if ((num < length) && char.IsDigit(Version[num])) {
{
this.n小数部 += CDTXVersion.DIG10.IndexOf(Version[num]); this.n小数部 += CDTXVersion.DIG10.IndexOf(Version[num]);
} }
num++; num++;
} }
this.Unknown = false; this.Unknown = false;
} } else {
else
{
this.Unknown = true; this.Unknown = true;
} }
} }
} }
public CDTXVersion( int n整数部, int n小数部 ) public CDTXVersion(int n整数部, int n小数部) {
{
this.n整数部 = n整数部; this.n整数部 = n整数部;
this.n小数部 = n小数部; this.n小数部 = n小数部;
this.Unknown = false; this.Unknown = false;
@ -121,24 +99,21 @@ namespace TJAPlayer3
// メソッド // メソッド
public string toString() public string toString() {
{
var result = new StringBuilder(32); var result = new StringBuilder(32);
// 整数部 // 整数部
result.Append(this.n整数部.ToString("000")); result.Append(this.n整数部.ToString("000"));
// 英字部分(あれば) // 英字部分(あれば)
if( this.n小数部 >= 1000000 ) if (this.n小数部 >= 1000000) {
{
int n英字 = Math.Min(this.n小数部 / 1000000, 26); // 126 int n英字 = Math.Min(this.n小数部 / 1000000, 26); // 126
result.Append(CDTXVersion.DIG36[10 + (n英字 - 1)]); result.Append(CDTXVersion.DIG36[10 + (n英字 - 1)]);
} }
// 日付部分(あれば) // 日付部分(あれば)
int n日付 = this.n小数部 % 1000000; int n日付 = this.n小数部 % 1000000;
if( n日付 > 0 ) if (n日付 > 0) {
{
result.Append('('); result.Append('(');
result.Append(n日付.ToString("000000")); result.Append(n日付.ToString("000000"));
result.Append(')'); result.Append(')');
@ -147,47 +122,37 @@ namespace TJAPlayer3
return result.ToString(); return result.ToString();
} }
public static bool operator ==( CDTXVersion x, CDTXVersion y ) public static bool operator ==(CDTXVersion x, CDTXVersion y) {
{
return (((x.n整数部 == y.n整数部) && (x.n小数部 == y.n小数部)) && (x.Unknown == y.Unknown)); return (((x.n整数部 == y.n整数部) && (x.n小数部 == y.n小数部)) && (x.Unknown == y.Unknown));
} }
public static bool operator >( CDTXVersion x, CDTXVersion y ) public static bool operator >(CDTXVersion x, CDTXVersion y) {
{
return ((x.n整数部 > y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 > y.n小数部))); return ((x.n整数部 > y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 > y.n小数部)));
} }
public static bool operator >=( CDTXVersion x, CDTXVersion y ) public static bool operator >=(CDTXVersion x, CDTXVersion y) {
{
return ((x.n整数部 > y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 >= y.n小数部))); return ((x.n整数部 > y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 >= y.n小数部)));
} }
public static bool operator !=( CDTXVersion x, CDTXVersion y ) public static bool operator !=(CDTXVersion x, CDTXVersion y) {
{ if ((x.n整数部 == y.n整数部) && (x.n小数部 == y.n小数部)) {
if( ( x.n整数部 == y.n整数部 ) && ( x.n小数部 == y.n小数部 ) )
{
return (x.Unknown != y.Unknown); return (x.Unknown != y.Unknown);
} }
return true; return true;
} }
public static bool operator <( CDTXVersion x, CDTXVersion y ) public static bool operator <(CDTXVersion x, CDTXVersion y) {
{
return ((x.n整数部 < y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 < y.n小数部))); return ((x.n整数部 < y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 < y.n小数部)));
} }
public static bool operator <=( CDTXVersion x, CDTXVersion y ) public static bool operator <=(CDTXVersion x, CDTXVersion y) {
{
return ((x.n整数部 < y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 <= y.n小数部))); return ((x.n整数部 < y.n整数部) || ((x.n整数部 == y.n整数部) && (x.n小数部 <= y.n小数部)));
} }
public override bool Equals(object obj) // 2011.1.3 yyagi: warningを無くすために追加 public override bool Equals(object obj) // 2011.1.3 yyagi: warningを無くすために追加
{ {
if (obj == null) if (obj == null) {
{
return false; return false;
} }
if (this.GetType() != obj.GetType()) if (this.GetType() != obj.GetType()) {
{
return false; return false;
} }
CDTXVersion objCDTXVersion = (CDTXVersion)obj; CDTXVersion objCDTXVersion = (CDTXVersion)obj;
if (!int.Equals(this.n整数部, objCDTXVersion.n整数部) || !int.Equals(this.n小数部, objCDTXVersion.n小数部)) if (!int.Equals(this.n整数部, objCDTXVersion.n整数部) || !int.Equals(this.n小数部, objCDTXVersion.n小数部)) {
{
return false; return false;
} }
return true; return true;

View File

@ -1,24 +1,13 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; class CHitSounds {
using System.Linq; public CHitSounds(string path) {
using System.Text;
using System.Threading.Tasks;
namespace TJAPlayer3
{
class CHitSounds
{
public CHitSounds(string path)
{
tLoadFile(path); tLoadFile(path);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++) {
{
tReloadHitSounds(TJAPlayer3.ConfigIni.nHitSounds[i], i); tReloadHitSounds(TJAPlayer3.ConfigIni.nHitSounds[i], i);
} }
} }
public bool tReloadHitSounds(int id, int player) public bool tReloadHitSounds(int id, int player) {
{
if (id >= names.Length || id >= data.Length) if (id >= names.Length || id >= data.Length)
return false; return false;
@ -46,8 +35,7 @@ namespace TJAPlayer3
#region [private] #region [private]
private class HitSoundsData private class HitSoundsData {
{
public string name; public string name;
public string path; public string path;
public string format; public string format;
@ -55,14 +43,12 @@ namespace TJAPlayer3
private HitSoundsData[] data; private HitSoundsData[] data;
private void tLoadFile(string path) private void tLoadFile(string path) {
{
data = ConfigManager.GetConfig<List<HitSoundsData>>(path).ToArray(); data = ConfigManager.GetConfig<List<HitSoundsData>>(path).ToArray();
names = new string[data.Length]; names = new string[data.Length];
for (int i = 0; i < data.Length; i++) for (int i = 0; i < data.Length; i++) {
{
names[i] = data[i].name; names[i] = data[i].name;
} }
} }

View File

@ -1,26 +1,19 @@
using System; using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using FDK; using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ public class CPad {
public class CPad
{
// プロパティ // プロパティ
internal STHIT st検知したデバイス; internal STHIT st検知したデバイス;
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct STHIT internal struct STHIT {
{
public bool Keyboard; public bool Keyboard;
public bool MIDIIN; public bool MIDIIN;
public bool Joypad; public bool Joypad;
public bool Gamepad; public bool Gamepad;
public bool Mouse; public bool Mouse;
public void Clear() public void Clear() {
{
this.Keyboard = false; this.Keyboard = false;
this.MIDIIN = false; this.MIDIIN = false;
this.Joypad = false; this.Joypad = false;
@ -31,8 +24,7 @@ namespace TJAPlayer3
// コンストラクタ // コンストラクタ
internal CPad( CConfigIni configIni, CInputManager mgrInput ) internal CPad(CConfigIni configIni, CInputManager mgrInput) {
{
this.rConfigIni = configIni; this.rConfigIni = configIni;
this.rInput管理 = mgrInput; this.rInput管理 = mgrInput;
this.st検知したデバイス.Clear(); this.st検知したデバイス.Clear();
@ -41,57 +33,46 @@ namespace TJAPlayer3
// メソッド // メソッド
public List<STInputEvent> GetEvents( EInstrumentPad part, EPad pad ) public List<STInputEvent> GetEvents(EInstrumentPad part, EPad pad) {
{
CConfigIni.CKeyAssign.STKEYASSIGN[] stkeyassignArray = this.rConfigIni.KeyAssign[(int)part][(int)pad]; CConfigIni.CKeyAssign.STKEYASSIGN[] stkeyassignArray = this.rConfigIni.KeyAssign[(int)part][(int)pad];
List<STInputEvent> list = new List<STInputEvent>(); List<STInputEvent> list = new List<STInputEvent>();
// すべての入力デバイスについて… // すべての入力デバイスについて…
foreach( IInputDevice device in this.rInput管理.InputDevices ) foreach (IInputDevice device in this.rInput管理.InputDevices) {
{ if ((device.InputEvents != null) && (device.InputEvents.Count != 0)) {
if( ( device.InputEvents != null ) && ( device.InputEvents.Count != 0 ) ) foreach (STInputEvent event2 in device.InputEvents) {
{ for (int i = 0; i < stkeyassignArray.Length; i++) {
foreach( STInputEvent event2 in device.InputEvents ) switch (stkeyassignArray[i].) {
{
for( int i = 0; i < stkeyassignArray.Length; i++ )
{
switch( stkeyassignArray[ i ]. )
{
case EInputDevice.Keyboard: case EInputDevice.Keyboard:
if( ( device.CurrentType == InputDeviceType.Keyboard ) && ( event2.nKey == stkeyassignArray[ i ]. ) ) if ((device.CurrentType == InputDeviceType.Keyboard) && (event2.nKey == stkeyassignArray[i].)) {
{
list.Add(event2); list.Add(event2);
this.st検知したデバイス.Keyboard = true; this.st検知したデバイス.Keyboard = true;
} }
break; break;
case EInputDevice.MIDIInput: case EInputDevice.MIDIInput:
if( ( ( device.CurrentType == InputDeviceType.MidiIn ) && ( device.ID == stkeyassignArray[ i ].ID ) ) && ( event2.nKey == stkeyassignArray[ i ]. ) ) if (((device.CurrentType == InputDeviceType.MidiIn) && (device.ID == stkeyassignArray[i].ID)) && (event2.nKey == stkeyassignArray[i].)) {
{
list.Add(event2); list.Add(event2);
this.st検知したデバイス.MIDIIN = true; this.st検知したデバイス.MIDIIN = true;
} }
break; break;
case EInputDevice.Joypad: case EInputDevice.Joypad:
if( ( ( device.CurrentType == InputDeviceType.Joystick ) && ( device.ID == stkeyassignArray[ i ].ID ) ) && ( event2.nKey == stkeyassignArray[ i ]. ) ) if (((device.CurrentType == InputDeviceType.Joystick) && (device.ID == stkeyassignArray[i].ID)) && (event2.nKey == stkeyassignArray[i].)) {
{
list.Add(event2); list.Add(event2);
this.st検知したデバイス.Joypad = true; this.st検知したデバイス.Joypad = true;
} }
break; break;
case EInputDevice.Gamepad: case EInputDevice.Gamepad:
if( ( ( device.CurrentType == InputDeviceType.Gamepad ) && ( device.ID == stkeyassignArray[ i ].ID ) ) && ( event2.nKey == stkeyassignArray[ i ]. ) ) if (((device.CurrentType == InputDeviceType.Gamepad) && (device.ID == stkeyassignArray[i].ID)) && (event2.nKey == stkeyassignArray[i].)) {
{
list.Add(event2); list.Add(event2);
this.st検知したデバイス.Gamepad = true; this.st検知したデバイス.Gamepad = true;
} }
break; break;
case EInputDevice.Mouse: case EInputDevice.Mouse:
if( ( device.CurrentType == InputDeviceType.Mouse ) && ( event2.nKey == stkeyassignArray[ i ]. ) ) if ((device.CurrentType == InputDeviceType.Mouse) && (event2.nKey == stkeyassignArray[i].)) {
{
list.Add(event2); list.Add(event2);
this.st検知したデバイス.Mouse = true; this.st検知したデバイス.Mouse = true;
} }
@ -104,16 +85,12 @@ namespace TJAPlayer3
} }
return list; return list;
} }
public bool bPressed( EInstrumentPad part, EPad pad ) public bool bPressed(EInstrumentPad part, EPad pad) {
{ if (part != EInstrumentPad.UNKNOWN) {
if( part != EInstrumentPad.UNKNOWN )
{
CConfigIni.CKeyAssign.STKEYASSIGN[] stkeyassignArray = this.rConfigIni.KeyAssign[(int)part][(int)pad]; CConfigIni.CKeyAssign.STKEYASSIGN[] stkeyassignArray = this.rConfigIni.KeyAssign[(int)part][(int)pad];
for( int i = 0; i < stkeyassignArray.Length; i++ ) for (int i = 0; i < stkeyassignArray.Length; i++) {
{ switch (stkeyassignArray[i].) {
switch( stkeyassignArray[ i ]. )
{
case EInputDevice.Keyboard: case EInputDevice.Keyboard:
if (!this.rInput管理.Keyboard.KeyPressed(stkeyassignArray[i].)) if (!this.rInput管理.Keyboard.KeyPressed(stkeyassignArray[i].))
break; break;
@ -121,8 +98,7 @@ namespace TJAPlayer3
this.st検知したデバイス.Keyboard = true; this.st検知したデバイス.Keyboard = true;
return true; return true;
case EInputDevice.MIDIInput: case EInputDevice.MIDIInput: {
{
IInputDevice device2 = this.rInput管理.MidiIn(stkeyassignArray[i].ID); IInputDevice device2 = this.rInput管理.MidiIn(stkeyassignArray[i].ID);
if ((device2 == null) || !device2.KeyPressed(stkeyassignArray[i].)) if ((device2 == null) || !device2.KeyPressed(stkeyassignArray[i].))
break; break;
@ -130,8 +106,7 @@ namespace TJAPlayer3
this.st検知したデバイス.MIDIIN = true; this.st検知したデバイス.MIDIIN = true;
return true; return true;
} }
case EInputDevice.Joypad: case EInputDevice.Joypad: {
{
if (!this.rConfigIni.dicJoystick.ContainsKey(stkeyassignArray[i].ID)) if (!this.rConfigIni.dicJoystick.ContainsKey(stkeyassignArray[i].ID))
break; break;
@ -142,8 +117,7 @@ namespace TJAPlayer3
this.st検知したデバイス.Joypad = true; this.st検知したデバイス.Joypad = true;
return true; return true;
} }
case EInputDevice.Gamepad: case EInputDevice.Gamepad: {
{
if (!this.rConfigIni.dicJoystick.ContainsKey(stkeyassignArray[i].ID)) if (!this.rConfigIni.dicJoystick.ContainsKey(stkeyassignArray[i].ID))
break; break;
@ -165,71 +139,55 @@ namespace TJAPlayer3
} }
return false; return false;
} }
public bool bPressedDGB( EPad pad ) public bool bPressedDGB(EPad pad) {
{ if (!this.bPressed(EInstrumentPad.DRUMS, pad) && !this.bPressed(EInstrumentPad.GUITAR, pad)) {
if( !this.bPressed( EInstrumentPad.DRUMS, pad ) && !this.bPressed( EInstrumentPad.GUITAR, pad ) )
{
return this.bPressed(EInstrumentPad.BASS, pad); return this.bPressed(EInstrumentPad.BASS, pad);
} }
return true; return true;
} }
public bool bPressedGB( EPad pad ) public bool bPressedGB(EPad pad) {
{ if (!this.bPressed(EInstrumentPad.GUITAR, pad)) {
if( !this.bPressed( EInstrumentPad.GUITAR, pad ) )
{
return this.bPressed(EInstrumentPad.BASS, pad); return this.bPressed(EInstrumentPad.BASS, pad);
} }
return true; return true;
} }
public bool b押されている( EInstrumentPad part, EPad pad ) public bool b押されている(EInstrumentPad part, EPad pad) {
{ if (part != EInstrumentPad.UNKNOWN) {
if( part != EInstrumentPad.UNKNOWN )
{
CConfigIni.CKeyAssign.STKEYASSIGN[] stkeyassignArray = this.rConfigIni.KeyAssign[(int)part][(int)pad]; CConfigIni.CKeyAssign.STKEYASSIGN[] stkeyassignArray = this.rConfigIni.KeyAssign[(int)part][(int)pad];
for( int i = 0; i < stkeyassignArray.Length; i++ ) for (int i = 0; i < stkeyassignArray.Length; i++) {
{ switch (stkeyassignArray[i].) {
switch( stkeyassignArray[ i ]. )
{
case EInputDevice.Keyboard: case EInputDevice.Keyboard:
if( !this.rInput管理.Keyboard.KeyPressing( stkeyassignArray[ i ]. ) ) if (!this.rInput管理.Keyboard.KeyPressing(stkeyassignArray[i].)) {
{
break; break;
} }
this.st検知したデバイス.Keyboard = true; this.st検知したデバイス.Keyboard = true;
return true; return true;
case EInputDevice.Joypad: case EInputDevice.Joypad: {
{ if (!this.rConfigIni.dicJoystick.ContainsKey(stkeyassignArray[i].ID)) {
if( !this.rConfigIni.dicJoystick.ContainsKey( stkeyassignArray[ i ].ID ) )
{
break; break;
} }
IInputDevice device = this.rInput管理.Joystick(stkeyassignArray[i].ID); IInputDevice device = this.rInput管理.Joystick(stkeyassignArray[i].ID);
if( ( device == null ) || !device.KeyPressing( stkeyassignArray[ i ]. ) ) if ((device == null) || !device.KeyPressing(stkeyassignArray[i].)) {
{
break; break;
} }
this.st検知したデバイス.Joypad = true; this.st検知したデバイス.Joypad = true;
return true; return true;
} }
case EInputDevice.Gamepad: case EInputDevice.Gamepad: {
{ if (!this.rConfigIni.dicJoystick.ContainsKey(stkeyassignArray[i].ID)) {
if( !this.rConfigIni.dicJoystick.ContainsKey( stkeyassignArray[ i ].ID ) )
{
break; break;
} }
IInputDevice device = this.rInput管理.Gamepad(stkeyassignArray[i].ID); IInputDevice device = this.rInput管理.Gamepad(stkeyassignArray[i].ID);
if( ( device == null ) || !device.KeyPressing( stkeyassignArray[ i ]. ) ) if ((device == null) || !device.KeyPressing(stkeyassignArray[i].)) {
{
break; break;
} }
this.st検知したデバイス.Gamepad = true; this.st検知したデバイス.Gamepad = true;
return true; return true;
} }
case EInputDevice.Mouse: case EInputDevice.Mouse:
if( !this.rInput管理.Mouse.KeyPressing( stkeyassignArray[ i ]. ) ) if (!this.rInput管理.Mouse.KeyPressing(stkeyassignArray[i].)) {
{
break; break;
} }
this.st検知したデバイス.Mouse = true; this.st検知したデバイス.Mouse = true;
@ -239,10 +197,8 @@ namespace TJAPlayer3
} }
return false; return false;
} }
public bool b押されているGB( EPad pad ) public bool b押されているGB(EPad pad) {
{ if (!this.b押されている(EInstrumentPad.GUITAR, pad)) {
if( !this.b押されている( EInstrumentPad.GUITAR, pad ) )
{
return this.b押されている(EInstrumentPad.BASS, pad); return this.b押されている(EInstrumentPad.BASS, pad);
} }
return true; return true;

View File

@ -1,22 +1,10 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; class CSavableT<T> where T : new() {
using System.Linq; public virtual string _fn {
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace TJAPlayer3
{
class CSavableT<T> where T : new()
{
public virtual string _fn
{
get; get;
protected set; protected set;
} }
public void tDBInitSavable() public void tDBInitSavable() {
{
if (!File.Exists(_fn)) if (!File.Exists(_fn))
tSaveFile(); tSaveFile();
@ -27,13 +15,11 @@ namespace TJAPlayer3
#region [private] #region [private]
private void tSaveFile() private void tSaveFile() {
{
ConfigManager.SaveConfig(data, _fn); ConfigManager.SaveConfig(data, _fn);
} }
private void tLoadFile() private void tLoadFile() {
{
data = ConfigManager.GetConfig<T>(_fn); data = ConfigManager.GetConfig<T>(_fn);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,7 @@
using System; using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ internal class CSongDict {
internal class CSongDict
{
private static Dictionary<string, CSongListNode> nodes = new Dictionary<string, CSongListNode>(); private static Dictionary<string, CSongListNode> nodes = new Dictionary<string, CSongListNode>();
private static HashSet<string> urls = new HashSet<string>(); private static HashSet<string> urls = new HashSet<string>();
@ -21,64 +14,54 @@ namespace TJAPlayer3
new CActSelect曲リスト.CScorePad[(int)Difficulty.Edit + 2] { new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad() } new CActSelect曲リスト.CScorePad[(int)Difficulty.Edit + 2] { new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad(), new CActSelect曲リスト.CScorePad() }
}; };
public static int tGetNodesCount() public static int tGetNodesCount() {
{
return nodes.Count(); return nodes.Count();
} }
public static string[] tGetNodesByGenreName(string genreName) public static string[] tGetNodesByGenreName(string genreName) {
{
return nodes.Where(_nd => _nd.Value.strジャンル == genreName).Select(_nd => _nd.Key).ToArray(); return nodes.Where(_nd => _nd.Value.strジャンル == genreName).Select(_nd => _nd.Key).ToArray();
} }
#region [General song dict methods] #region [General song dict methods]
public static CSongListNode tGetNodeFromID(string id) public static CSongListNode tGetNodeFromID(string id) {
{
if (nodes.ContainsKey(id)) if (nodes.ContainsKey(id))
return nodes[id].Clone(); return nodes[id].Clone();
return null; return null;
} }
public static void tAddSongNode(CSongUniqueID sid, CSongListNode node) public static void tAddSongNode(CSongUniqueID sid, CSongListNode node) {
{
if (sid != null && sid.data.id != null && sid.data.id != "" && !nodes.ContainsKey(sid.data.id)) if (sid != null && sid.data.id != null && sid.data.id != "" && !nodes.ContainsKey(sid.data.id))
nodes.Add(sid.data.id, node.Clone()); nodes.Add(sid.data.id, node.Clone());
tAddSongUrl(sid); tAddSongUrl(sid);
} }
public static bool tContainsSongUrl(string url) public static bool tContainsSongUrl(string url) {
{
return urls.Contains(url); return urls.Contains(url);
} }
public static void tAddSongUrl(CSongUniqueID sid) public static void tAddSongUrl(CSongUniqueID sid) {
{
var url = sid.data.url; var url = sid.data.url;
if (url != null && url != "" && !urls.Contains(url)) if (url != null && url != "" && !urls.Contains(url))
urls.Add(url); urls.Add(url);
} }
public static void tRemoveSongUrl(CSongUniqueID sid) public static void tRemoveSongUrl(CSongUniqueID sid) {
{
var url = sid.data.url; var url = sid.data.url;
if (url != null && url != "" && urls.Contains(url)) if (url != null && url != "" && urls.Contains(url))
urls.Remove(url); urls.Remove(url);
} }
public static void tRemoveSongNode(CSongUniqueID sid) public static void tRemoveSongNode(CSongUniqueID sid) {
{ if (sid != null && nodes.ContainsKey(sid.data.id)) {
if (sid != null && nodes.ContainsKey(sid.data.id))
{
tRemoveSongUrl(sid); tRemoveSongUrl(sid);
nodes.Remove(sid.data.id); nodes.Remove(sid.data.id);
} }
} }
public static void tClearSongNodes() public static void tClearSongNodes() {
{
nodes.Clear(); nodes.Clear();
urls.Clear(); urls.Clear();
} }
@ -88,8 +71,7 @@ namespace TJAPlayer3
#region [Extra methods] #region [Extra methods]
// Generate a back button // Generate a back button
public static CSongListNode tGenerateBackButton(CSongListNode parent, string path = "/", List<string> listStrBoxDef = null) public static CSongListNode tGenerateBackButton(CSongListNode parent, string path = "/", List<string> listStrBoxDef = null) {
{
CSongListNode itemBack = new CSongListNode(); CSongListNode itemBack = new CSongListNode();
itemBack.eード種別 = CSongListNode.ENodeType.BACKBOX; itemBack.eード種別 = CSongListNode.ENodeType.BACKBOX;
@ -113,8 +95,7 @@ namespace TJAPlayer3
"" : parent.rParentNode.strSkinPath; "" : parent.rParentNode.strSkinPath;
// I guess this is used to count the number of box.def instances and only at startup, which makes using it here pretty weird // I guess this is used to count the number of box.def instances and only at startup, which makes using it here pretty weird
if (listStrBoxDef != null && itemBack.strSkinPath != "" && !listStrBoxDef.Contains(itemBack.strSkinPath)) if (listStrBoxDef != null && itemBack.strSkinPath != "" && !listStrBoxDef.Contains(itemBack.strSkinPath)) {
{
listStrBoxDef.Add(itemBack.strSkinPath); listStrBoxDef.Add(itemBack.strSkinPath);
} }
@ -129,8 +110,7 @@ namespace TJAPlayer3
return (itemBack); return (itemBack);
} }
public static CSongListNode tGenerateRandomButton(CSongListNode parent, string path = "/") public static CSongListNode tGenerateRandomButton(CSongListNode parent, string path = "/") {
{
CSongListNode itemRandom = new CSongListNode(); CSongListNode itemRandom = new CSongListNode();
itemRandom.eード種別 = CSongListNode.ENodeType.RANDOM; itemRandom.eード種別 = CSongListNode.ENodeType.RANDOM;
@ -148,15 +128,13 @@ namespace TJAPlayer3
} }
// Reset the position of all back buttons, also adds a random button at the end // Reset the position of all back buttons, also adds a random button at the end
public static List<CSongListNode> tReinsertBackButtons(CSongListNode parent, List<CSongListNode> songList, string path = "/", List<string> listStrBoxDef = null) public static List<CSongListNode> tReinsertBackButtons(CSongListNode parent, List<CSongListNode> songList, string path = "/", List<string> listStrBoxDef = null) {
{
// Remove all the existing back boxes currently existing // Remove all the existing back boxes currently existing
songList.RemoveAll(e => e.eード種別 == CSongListNode.ENodeType.BACKBOX || e.eード種別 == CSongListNode.ENodeType.RANDOM); songList.RemoveAll(e => e.eード種別 == CSongListNode.ENodeType.BACKBOX || e.eード種別 == CSongListNode.ENodeType.RANDOM);
int songCount = songList.Count; int songCount = songList.Count;
for (int index = 0; index < (songCount / 7) + 1; index++) for (int index = 0; index < (songCount / 7) + 1; index++) {
{
var backBox = tGenerateBackButton(parent, path, listStrBoxDef); var backBox = tGenerateBackButton(parent, path, listStrBoxDef);
songList.Insert(Math.Min(index * (7 + 1), songList.Count), backBox); songList.Insert(Math.Min(index * (7 + 1), songList.Count), backBox);
} }
@ -169,10 +147,8 @@ namespace TJAPlayer3
} }
private static CSongListNode tReadaptChildNote(CSongListNode parent, CSongListNode node) private static CSongListNode tReadaptChildNote(CSongListNode parent, CSongListNode node) {
{ if (node != null) {
if (node != null)
{
node.rParentNode = parent; node.rParentNode = parent;
node.isChangedBgType = parent.isChangedBgType; node.isChangedBgType = parent.isChangedBgType;
node.isChangedBgColor = parent.isChangedBgColor; node.isChangedBgColor = parent.isChangedBgColor;
@ -192,15 +168,12 @@ namespace TJAPlayer3
} }
// Generate the favorite folder content // Generate the favorite folder content
public static List<CSongListNode> tFetchFavoriteFolder(CSongListNode parent) public static List<CSongListNode> tFetchFavoriteFolder(CSongListNode parent) {
{
List<CSongListNode> childList = new List<CSongListNode>(); List<CSongListNode> childList = new List<CSongListNode>();
foreach (string id in TJAPlayer3.Favorites.data.favorites[TJAPlayer3.SaveFile]) foreach (string id in TJAPlayer3.Favorites.data.favorites[TJAPlayer3.SaveFile]) {
{
var node = tReadaptChildNote(parent, tGetNodeFromID(id)); var node = tReadaptChildNote(parent, tGetNodeFromID(id));
if (node != null) if (node != null) {
{
childList.Add(node); childList.Add(node);
} }
@ -216,15 +189,12 @@ namespace TJAPlayer3
} }
// Generate recently played songs folder // Generate recently played songs folder
public static List<CSongListNode> tFetchRecentlyPlayedSongsFolder(CSongListNode parent) public static List<CSongListNode> tFetchRecentlyPlayedSongsFolder(CSongListNode parent) {
{
List<CSongListNode> childList = new List<CSongListNode>(); List<CSongListNode> childList = new List<CSongListNode>();
foreach (string id in TJAPlayer3.RecentlyPlayedSongs.data.recentlyplayedsongs[TJAPlayer3.SaveFile].Reverse()) foreach (string id in TJAPlayer3.RecentlyPlayedSongs.data.recentlyplayedsongs[TJAPlayer3.SaveFile].Reverse()) {
{
var node = tReadaptChildNote(parent, tGetNodeFromID(id)); var node = tReadaptChildNote(parent, tGetNodeFromID(id));
if (node != null) if (node != null) {
{
childList.Add(node); childList.Add(node);
} }
@ -240,27 +210,23 @@ namespace TJAPlayer3
} }
// 13 includes any higher difficulty // 13 includes any higher difficulty
private static bool tLevelMatches(int check, int level) private static bool tLevelMatches(int check, int level) {
{
if (level == 13) if (level == 13)
return check >= level; return check >= level;
return check == level; return check == level;
} }
// Generate search by difficulty folder // Generate search by difficulty folder
public static List<CSongListNode> tFetchSongsByDifficulty(CSongListNode parent, int difficulty = (int)Difficulty.Oni, int level = 8) public static List<CSongListNode> tFetchSongsByDifficulty(CSongListNode parent, int difficulty = (int)Difficulty.Oni, int level = 8) {
{
List<CSongListNode> childList = new List<CSongListNode>(); List<CSongListNode> childList = new List<CSongListNode>();
foreach (CSongListNode nodeT in nodes.Values) foreach (CSongListNode nodeT in nodes.Values) {
{
var score = nodeT.nLevel; var score = nodeT.nLevel;
if (tLevelMatches(score[difficulty], level) if (tLevelMatches(score[difficulty], level)
|| (difficulty == (int)Difficulty.Oni && tLevelMatches(score[(int)Difficulty.Edit], level))) // Oni includes Ura || (difficulty == (int)Difficulty.Oni && tLevelMatches(score[(int)Difficulty.Edit], level))) // Oni includes Ura
{ {
var node = tReadaptChildNote(parent, nodeT); var node = tReadaptChildNote(parent, nodeT);
if (node != null) if (node != null) {
{
childList.Add(node); childList.Add(node);
} }
} }
@ -279,24 +245,18 @@ namespace TJAPlayer3
#region [Score tables methods] #region [Score tables methods]
public static void tRefreshScoreTables() public static void tRefreshScoreTables() {
{ for (int pl = 0; pl < 5; pl++) {
for (int pl = 0; pl < 5; pl++)
{
CActSelect曲リスト.CScorePad[] SPArrRef = ScorePads[pl]; CActSelect曲リスト.CScorePad[] SPArrRef = ScorePads[pl];
var BestPlayStats = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(pl)].data.bestPlaysStats; var BestPlayStats = TJAPlayer3.SaveFileInstances[TJAPlayer3.GetActualPlayer(pl)].data.bestPlaysStats;
for (int s = 0; s <= (int)Difficulty.Edit + 1; s++) for (int s = 0; s <= (int)Difficulty.Edit + 1; s++) {
{
CActSelect曲リスト.CScorePad SPRef = SPArrRef[s]; CActSelect曲リスト.CScorePad SPRef = SPArrRef[s];
if (s <= (int)Difficulty.Edit) if (s <= (int)Difficulty.Edit) {
{
SPRef.ScoreRankCount = BestPlayStats.ScoreRanks[s].Skip(1).ToArray(); ; SPRef.ScoreRankCount = BestPlayStats.ScoreRanks[s].Skip(1).ToArray(); ;
SPRef.CrownCount = BestPlayStats.ClearStatuses[s].Skip(1).ToArray(); ; SPRef.CrownCount = BestPlayStats.ClearStatuses[s].Skip(1).ToArray(); ;
} } else {
else
{
SPRef.ScoreRankCount = BestPlayStats.ScoreRanks[(int)Difficulty.Oni].Skip(1).Zip(BestPlayStats.ScoreRanks[(int)Difficulty.Edit].Skip(1).ToArray(), (x, y) => x + y).ToArray(); SPRef.ScoreRankCount = BestPlayStats.ScoreRanks[(int)Difficulty.Oni].Skip(1).Zip(BestPlayStats.ScoreRanks[(int)Difficulty.Edit].Skip(1).ToArray(), (x, y) => x + y).ToArray();
SPRef.CrownCount = BestPlayStats.ClearStatuses[(int)Difficulty.Oni].Skip(1).Zip(BestPlayStats.ClearStatuses[(int)Difficulty.Edit].Skip(1).ToArray(), (x, y) => x + y).ToArray(); SPRef.CrownCount = BestPlayStats.ClearStatuses[(int)Difficulty.Oni].Skip(1).Zip(BestPlayStats.ClearStatuses[(int)Difficulty.Edit].Skip(1).ToArray(), (x, y) => x + y).ToArray();
} }

View File

@ -1,17 +1,11 @@
using System; using System.Drawing;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using FDK; using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ internal class CTextConsole : CActivity {
internal class CTextConsole : CActivity
{
// 定数 // 定数
public enum EFontType public enum EFontType {
{
White, White,
Cyan, Cyan,
Gray, Gray,
@ -22,30 +16,20 @@ namespace TJAPlayer3
// メソッド // メソッド
public void tPrint( int x, int y, EFontType font, string strAlphanumericString ) public void tPrint(int x, int y, EFontType font, string strAlphanumericString) {
{ if (!base.IsDeActivated && !string.IsNullOrEmpty(strAlphanumericString)) {
if( !base.IsDeActivated && !string.IsNullOrEmpty( strAlphanumericString ) )
{
int BOL = x; int BOL = x;
for( int i = 0; i < strAlphanumericString.Length; i++ ) for (int i = 0; i < strAlphanumericString.Length; i++) {
{
char ch = strAlphanumericString[i]; char ch = strAlphanumericString[i];
if( ch == '\n' ) if (ch == '\n') {
{
x = BOL; x = BOL;
y += nFontHeight; y += nFontHeight;
} } else {
else
{
int index = str表記可能文字.IndexOf(ch); int index = str表記可能文字.IndexOf(ch);
if( index < 0 ) if (index < 0) {
{
x += nFontWidth; x += nFontWidth;
} } else {
else if (this.txフォント8x16[(int)((int)font / (int)EFontType.WhiteSlim)] != null) {
{
if( this.txフォント8x16[ (int) ( (int) font / (int) EFontType.WhiteSlim ) ] != null )
{
this.txフォント8x16[(int)((int)font / (int)EFontType.WhiteSlim)].t2D描画(x, y, this.rc文字の矩形領域[(int)((int)font % (int)EFontType.WhiteSlim), index]); this.txフォント8x16[(int)((int)font / (int)EFontType.WhiteSlim)].t2D描画(x, y, this.rc文字の矩形領域[(int)((int)font % (int)EFontType.WhiteSlim), index]);
} }
x += nFontWidth; x += nFontWidth;
@ -58,21 +42,17 @@ namespace TJAPlayer3
// CActivity 実装 // CActivity 実装
public override void Activate() public override void Activate() {
{
base.Activate(); base.Activate();
} }
public override void DeActivate() public override void DeActivate() {
{
if (this.rc文字の矩形領域 != null) if (this.rc文字の矩形領域 != null)
this.rc文字の矩形領域 = null; this.rc文字の矩形領域 = null;
base.DeActivate(); base.DeActivate();
} }
public override void CreateManagedResource() public override void CreateManagedResource() {
{ if (!base.IsDeActivated) {
if( !base.IsDeActivated )
{
this.txフォント8x16[0] = TJAPlayer3.Tx.TxC(@"Console_Font.png"); this.txフォント8x16[0] = TJAPlayer3.Tx.TxC(@"Console_Font.png");
this.txフォント8x16[1] = TJAPlayer3.Tx.TxC(@"Console_Font_Small.png"); this.txフォント8x16[1] = TJAPlayer3.Tx.TxC(@"Console_Font_Small.png");
@ -80,10 +60,8 @@ namespace TJAPlayer3
nFontHeight = this.txフォント8x16[0].szTextureSize.Height / 16; nFontHeight = this.txフォント8x16[0].szTextureSize.Height / 16;
this.rc文字の矩形領域 = new Rectangle[3, str表記可能文字.Length]; this.rc文字の矩形領域 = new Rectangle[3, str表記可能文字.Length];
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++) {
{ for (int j = 0; j < str表記可能文字.Length; j++) {
for (int j = 0; j < str表記可能文字.Length; j++)
{
int regionX = nFontWidth * 16, regionY = nFontHeight * 8; int regionX = nFontWidth * 16, regionY = nFontHeight * 8;
this.rc文字の矩形領域[i, j].X = ((i / 2) * regionX) + ((j % 16) * nFontWidth); this.rc文字の矩形領域[i, j].X = ((i / 2) * regionX) + ((j % 16) * nFontWidth);
this.rc文字の矩形領域[i, j].Y = ((i % 2) * regionY) + ((j / 16) * nFontHeight); this.rc文字の矩形領域[i, j].Y = ((i % 2) * regionY) + ((j / 16) * nFontHeight);
@ -95,14 +73,10 @@ namespace TJAPlayer3
base.CreateManagedResource(); base.CreateManagedResource();
} }
} }
public override void ReleaseManagedResource() public override void ReleaseManagedResource() {
{ if (!base.IsDeActivated) {
if( !base.IsDeActivated ) for (int i = 0; i < 2; i++) {
{ if (this.txフォント8x16[i] != null) {
for( int i = 0; i < 2; i++ )
{
if( this.txフォント8x16[ i ] != null )
{
this.txフォント8x16[i].Dispose(); this.txフォント8x16[i].Dispose();
this.txフォント8x16[i] = null; this.txフォント8x16[i] = null;
} }

View File

@ -1,13 +1,5 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; class CVersionList {
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TJAPlayer3
{
class CVersionList
{
public static string[] VersionList = { public static string[] VersionList = {
"0.1.0", "0.1.0",
"0.2.0", "0.2.0",

View File

@ -1,7 +1,6 @@
using FDK; using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{
/// <summary> /// <summary>
/// The ConfigIniToSongGainControllerBinder allows for SONGVOL and/or other /// The ConfigIniToSongGainControllerBinder allows for SONGVOL and/or other
/// properties related to the Gain levels applied to song preview and /// properties related to the Gain levels applied to song preview and
@ -10,18 +9,14 @@ namespace TJAPlayer3
/// ConfigIni or SongGainController having awareness of one another. /// ConfigIni or SongGainController having awareness of one another.
/// See those classes properties, methods, and events for more details. /// See those classes properties, methods, and events for more details.
/// </summary> /// </summary>
internal static class ConfigIniToSongGainControllerBinder internal static class ConfigIniToSongGainControllerBinder {
{ internal static void Bind(CConfigIni configIni, SongGainController songGainController) {
internal static void Bind(CConfigIni configIni, SongGainController songGainController)
{
songGainController.ApplyLoudnessMetadata = configIni.ApplyLoudnessMetadata; songGainController.ApplyLoudnessMetadata = configIni.ApplyLoudnessMetadata;
songGainController.TargetLoudness = new Lufs(configIni.TargetLoudness); songGainController.TargetLoudness = new Lufs(configIni.TargetLoudness);
songGainController.ApplySongVol = configIni.ApplySongVol; songGainController.ApplySongVol = configIni.ApplySongVol;
configIni.PropertyChanged += (sender, args) => configIni.PropertyChanged += (sender, args) => {
{ switch (args.PropertyName) {
switch (args.PropertyName)
{
case nameof(CConfigIni.ApplyLoudnessMetadata): case nameof(CConfigIni.ApplyLoudnessMetadata):
songGainController.ApplyLoudnessMetadata = configIni.ApplyLoudnessMetadata; songGainController.ApplyLoudnessMetadata = configIni.ApplyLoudnessMetadata;
break; break;

View File

@ -1,8 +1,6 @@
using System; using FDK;
using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{
/// <summary> /// <summary>
/// The ConfigIniToSoundGroupLevelControllerBinder allows for updated sound /// The ConfigIniToSoundGroupLevelControllerBinder allows for updated sound
/// group level values, and keyboard sound level adjustment increment /// group level values, and keyboard sound level adjustment increment
@ -10,20 +8,16 @@ namespace TJAPlayer3
/// without either of those two classes being aware of one another. /// without either of those two classes being aware of one another.
/// See those classes properties, methods, and events for more details. /// See those classes properties, methods, and events for more details.
/// </summary> /// </summary>
internal static class ConfigIniToSoundGroupLevelControllerBinder internal static class ConfigIniToSoundGroupLevelControllerBinder {
{ internal static void Bind(CConfigIni configIni, SoundGroupLevelController soundGroupLevelController) {
internal static void Bind(CConfigIni configIni, SoundGroupLevelController soundGroupLevelController)
{
soundGroupLevelController.SetLevel(ESoundGroup.SoundEffect, configIni.SoundEffectLevel); soundGroupLevelController.SetLevel(ESoundGroup.SoundEffect, configIni.SoundEffectLevel);
soundGroupLevelController.SetLevel(ESoundGroup.Voice, configIni.VoiceLevel); soundGroupLevelController.SetLevel(ESoundGroup.Voice, configIni.VoiceLevel);
soundGroupLevelController.SetLevel(ESoundGroup.SongPreview, configIni.SongPreviewLevel); soundGroupLevelController.SetLevel(ESoundGroup.SongPreview, configIni.SongPreviewLevel);
soundGroupLevelController.SetLevel(ESoundGroup.SongPlayback, configIni.SongPlaybackLevel); soundGroupLevelController.SetLevel(ESoundGroup.SongPlayback, configIni.SongPlaybackLevel);
soundGroupLevelController.SetKeyboardSoundLevelIncrement(configIni.KeyboardSoundLevelIncrement); soundGroupLevelController.SetKeyboardSoundLevelIncrement(configIni.KeyboardSoundLevelIncrement);
configIni.PropertyChanged += (sender, args) => configIni.PropertyChanged += (sender, args) => {
{ switch (args.PropertyName) {
switch (args.PropertyName)
{
case nameof(CConfigIni.SoundEffectLevel): case nameof(CConfigIni.SoundEffectLevel):
soundGroupLevelController.SetLevel(ESoundGroup.SoundEffect, configIni.SoundEffectLevel); soundGroupLevelController.SetLevel(ESoundGroup.SoundEffect, configIni.SoundEffectLevel);
break; break;
@ -42,10 +36,8 @@ namespace TJAPlayer3
} }
}; };
soundGroupLevelController.LevelChanged += (sender, args) => soundGroupLevelController.LevelChanged += (sender, args) => {
{ switch (args.SoundGroup) {
switch (args.SoundGroup)
{
case ESoundGroup.SoundEffect: case ESoundGroup.SoundEffect:
configIni.SoundEffectLevel = args.Level; configIni.SoundEffectLevel = args.Level;
break; break;

View File

@ -1,19 +1,14 @@
using System.IO; using System.Text;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace TJAPlayer3 namespace TJAPlayer3 {
{
/// <summary> /// <summary>
/// 設定ファイル入出力クラス。 /// 設定ファイル入出力クラス。
/// </summary> /// </summary>
public static class ConfigManager public static class ConfigManager {
{
private static readonly JsonSerializerSettings Settings = private static readonly JsonSerializerSettings Settings =
new JsonSerializerSettings() new JsonSerializerSettings() {
{
ObjectCreationHandling = ObjectCreationHandling.Auto, ObjectCreationHandling = ObjectCreationHandling.Auto,
DefaultValueHandling = DefaultValueHandling.Include, DefaultValueHandling = DefaultValueHandling.Include,
// ContractResolver = new CamelCasePropertyNamesContractResolver(), // ContractResolver = new CamelCasePropertyNamesContractResolver(),
@ -28,16 +23,13 @@ namespace TJAPlayer3
/// <typeparam name="T">シリアライズしたクラス。</typeparam> /// <typeparam name="T">シリアライズしたクラス。</typeparam>
/// <param name="filePath">ファイル名。</param> /// <param name="filePath">ファイル名。</param>
/// <returns>デシリアライズ結果。</returns> /// <returns>デシリアライズ結果。</returns>
public static T GetConfig<T>(string filePath) where T : new() public static T GetConfig<T>(string filePath) where T : new() {
{
var json = ""; var json = "";
if (!System.IO.File.Exists(filePath)) if (!System.IO.File.Exists(filePath)) {
{
// ファイルが存在しないので // ファイルが存在しないので
SaveConfig(new T(), filePath); SaveConfig(new T(), filePath);
} }
using (var stream = new System.IO.StreamReader(filePath, Encoding.UTF8)) using (var stream = new System.IO.StreamReader(filePath, Encoding.UTF8)) {
{
json = stream.ReadToEnd(); json = stream.ReadToEnd();
} }
return JsonConvert.DeserializeObject<T>(json, Settings); return JsonConvert.DeserializeObject<T>(json, Settings);
@ -48,11 +40,9 @@ namespace TJAPlayer3
/// </summary> /// </summary>
/// <param name="obj">シリアライズするインスタンス。</param> /// <param name="obj">シリアライズするインスタンス。</param>
/// <param name="filePath">ファイル名。</param> /// <param name="filePath">ファイル名。</param>
public static void SaveConfig(object obj, string filePath) public static void SaveConfig(object obj, string filePath) {
{
(new FileInfo(filePath)).Directory.Create(); (new FileInfo(filePath)).Directory.Create();
using (var stream = new System.IO.StreamWriter(filePath, false, Encoding.UTF8)) using (var stream = new System.IO.StreamWriter(filePath, false, Encoding.UTF8)) {
{
stream.Write(JsonConvert.SerializeObject(obj, Formatting.None, Settings)); stream.Write(JsonConvert.SerializeObject(obj, Formatting.None, Settings));
} }
} }

View File

@ -1,16 +1,11 @@
using System; using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace TJAPlayer3 namespace TJAPlayer3 {
{
/// <summary> /// <summary>
/// 難易度。 /// 難易度。
/// </summary> /// </summary>
public enum Difficulty public enum Difficulty {
{
Easy, Easy,
Normal, Normal,
Hard, Hard,
@ -21,21 +16,18 @@ namespace TJAPlayer3
Total Total
} }
public enum EScrollMode public enum EScrollMode {
{
Normal, Normal,
BMSCROLL, BMSCROLL,
HBSCROLL HBSCROLL
} }
public enum EGame public enum EGame {
{
OFF = 0, OFF = 0,
= 1, = 1,
= 2 = 2
} }
public enum E難易度表示タイプ public enum E難易度表示タイプ {
{
OFF = 0, OFF = 0,
n曲目に表示 = 1, n曲目に表示 = 1,
mtaikoに画像で表示 = 2, mtaikoに画像で表示 = 2,
@ -226,8 +218,7 @@ namespace TJAPlayer3
RBlue2P = 64, RBlue2P = 64,
UNKNOWN = 4096 UNKNOWN = 4096
} }
public enum ERandomMode public enum ERandomMode {
{
OFF, OFF,
RANDOM, RANDOM,
MIRROR, MIRROR,
@ -235,16 +226,14 @@ namespace TJAPlayer3
MIRRORRANDOM MIRRORRANDOM
} }
public enum EFunMods public enum EFunMods {
{
NONE, NONE,
AVALANCHE, AVALANCHE,
MINESWEEPER, MINESWEEPER,
TOTAL, TOTAL,
} }
public enum EGameType public enum EGameType {
{
TAIKO = 0, TAIKO = 0,
KONGA = 1, KONGA = 1,
} }
@ -267,8 +256,7 @@ namespace TJAPlayer3
UNKNOWN = EInstrumentPad.UNKNOWN UNKNOWN = EInstrumentPad.UNKNOWN
} }
internal enum EInputDevice internal enum EInputDevice {
{
Keyboard = 0, Keyboard = 0,
MIDIInput = 1, MIDIInput = 1,
Joypad = 2, Joypad = 2,
@ -276,8 +264,7 @@ namespace TJAPlayer3
Gamepad = 4, Gamepad = 4,
Unknown = -1 Unknown = -1
} }
public enum ENoteJudge public enum ENoteJudge {
{
Perfect = 0, Perfect = 0,
Great = 1, Great = 1,
Good = 2, Good = 2,
@ -288,22 +275,19 @@ namespace TJAPlayer3
ADLIB = 7, ADLIB = 7,
Mine = 8, Mine = 8,
} }
internal enum E判定文字表示位置 internal enum E判定文字表示位置 {
{
OFF, OFF,
, ,
, ,
} }
internal enum EFIFOモード internal enum EFIFOモード {
{
, ,
} }
internal enum E演奏画面の戻り値 internal enum E演奏画面の戻り値 {
{
, ,
, ,
, ,
@ -311,15 +295,13 @@ namespace TJAPlayer3
_再演奏, _再演奏,
} }
internal enum E曲読込画面の戻り値 internal enum E曲読込画面の戻り値 {
{
= 0, = 0,
, ,
} }
public enum ENoteState public enum ENoteState {
{
none, none,
wait, wait,
perfect, perfect,
@ -327,8 +309,7 @@ namespace TJAPlayer3
bad bad
} }
public enum E連打State public enum E連打State {
{
none, none,
roll, roll,
rollB, rollB,
@ -336,8 +317,7 @@ namespace TJAPlayer3
potato potato
} }
public enum EStealthMode public enum EStealthMode {
{
OFF = 0, OFF = 0,
DORON = 1, DORON = 1,
STEALTH = 2 STEALTH = 2
@ -346,8 +326,7 @@ namespace TJAPlayer3
/// <summary> /// <summary>
/// 透明チップの種類 /// 透明チップの種類
/// </summary> /// </summary>
public enum EInvisible public enum EInvisible {
{
OFF, // チップを透明化しない OFF, // チップを透明化しない
SEMI, // Poor/Miss時だけ、一時的に透明解除する SEMI, // Poor/Miss時だけ、一時的に透明解除する
FULL // チップを常に透明化する FULL // チップを常に透明化する
@ -366,12 +345,9 @@ namespace TJAPlayer3
public T Bass; public T Bass;
public T Taiko; public T Taiko;
public T Unknown; public T Unknown;
public T this[ int index ] public T this[int index] {
{ get {
get switch (index) {
{
switch( index )
{
case (int)EInstrumentPad.DRUMS: case (int)EInstrumentPad.DRUMS:
return this.Drums; return this.Drums;
@ -389,10 +365,8 @@ namespace TJAPlayer3
} }
throw new IndexOutOfRangeException(); throw new IndexOutOfRangeException();
} }
set set {
{ switch (index) {
switch( index )
{
case (int)EInstrumentPad.DRUMS: case (int)EInstrumentPad.DRUMS:
this.Drums = value; this.Drums = value;
return; return;
@ -418,28 +392,24 @@ namespace TJAPlayer3
} }
} }
public enum EReturnValue : int public enum EReturnValue : int {
{
Continuation, Continuation,
ReturnToTitle, ReturnToTitle,
SongChoosen SongChoosen
} }
#region[Ver.K追加] #region[Ver.K追加]
public enum Eレーンタイプ public enum Eレーンタイプ {
{
TypeA, TypeA,
TypeB, TypeB,
TypeC, TypeC,
TypeD TypeD
} }
public enum Eミラー public enum Eミラー {
{
TypeA, TypeA,
TypeB TypeB
} }
public enum EClipDispType public enum EClipDispType {
{
= 1, = 1,
= 2, = 2,
= 3, = 3,

View File

@ -1,16 +1,8 @@
using System; using FDK;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TJAPlayer3;
using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ class Easing {
class Easing public int EaseIn(CCounter counter, float startPoint, float endPoint, CalcType type) {
{
public int EaseIn(CCounter counter, float startPoint, float endPoint, CalcType type)
{
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Sa = EndPoint - StartPoint; Sa = EndPoint - StartPoint;
@ -18,8 +10,7 @@ namespace TJAPlayer3
Type = type; Type = type;
CounterValue = counter.CurrentValue; CounterValue = counter.CurrentValue;
switch (Type) switch (Type) {
{
case CalcType.Quadratic: //Quadratic case CalcType.Quadratic: //Quadratic
CounterValue /= TimeMs; CounterValue /= TimeMs;
Value = Sa * CounterValue * CounterValue + StartPoint; Value = Sa * CounterValue * CounterValue + StartPoint;
@ -53,8 +44,7 @@ namespace TJAPlayer3
return (int)Value; return (int)Value;
} }
public int EaseOut(CCounter counter, float startPoint, float endPoint, CalcType type) public int EaseOut(CCounter counter, float startPoint, float endPoint, CalcType type) {
{
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Sa = EndPoint - StartPoint; Sa = EndPoint - StartPoint;
@ -62,8 +52,7 @@ namespace TJAPlayer3
Type = type; Type = type;
CounterValue = counter.CurrentValue; CounterValue = counter.CurrentValue;
switch (Type) switch (Type) {
{
case CalcType.Quadratic: //Quadratic case CalcType.Quadratic: //Quadratic
CounterValue /= TimeMs; CounterValue /= TimeMs;
Value = -Sa * CounterValue * (CounterValue - 2) + StartPoint; Value = -Sa * CounterValue * (CounterValue - 2) + StartPoint;
@ -102,8 +91,7 @@ namespace TJAPlayer3
return (int)Value; return (int)Value;
} }
public float EaseInOut(CCounter counter, float startPoint, float endPoint, CalcType type) public float EaseInOut(CCounter counter, float startPoint, float endPoint, CalcType type) {
{
StartPoint = startPoint; StartPoint = startPoint;
EndPoint = endPoint; EndPoint = endPoint;
Sa = EndPoint - StartPoint; Sa = EndPoint - StartPoint;
@ -111,12 +99,10 @@ namespace TJAPlayer3
Type = type; Type = type;
CounterValue = counter.CurrentValue; CounterValue = counter.CurrentValue;
switch (Type) switch (Type) {
{
case CalcType.Quadratic: //Quadratic case CalcType.Quadratic: //Quadratic
CounterValue /= TimeMs / 2; CounterValue /= TimeMs / 2;
if (CounterValue < 1) if (CounterValue < 1) {
{
Value = Sa / 2 * CounterValue * CounterValue + StartPoint; Value = Sa / 2 * CounterValue * CounterValue + StartPoint;
break; break;
} }
@ -125,8 +111,7 @@ namespace TJAPlayer3
break; break;
case CalcType.Cubic: //Cubic case CalcType.Cubic: //Cubic
CounterValue /= TimeMs / 2; CounterValue /= TimeMs / 2;
if (CounterValue < 1) if (CounterValue < 1) {
{
Value = Sa / 2 * CounterValue * CounterValue * CounterValue + StartPoint; Value = Sa / 2 * CounterValue * CounterValue * CounterValue + StartPoint;
break; break;
} }
@ -135,8 +120,7 @@ namespace TJAPlayer3
break; break;
case CalcType.Quartic: //Quartic case CalcType.Quartic: //Quartic
CounterValue /= TimeMs / 2; CounterValue /= TimeMs / 2;
if (CounterValue < 1) if (CounterValue < 1) {
{
Value = Sa / 2 * CounterValue * CounterValue * CounterValue * CounterValue + StartPoint; Value = Sa / 2 * CounterValue * CounterValue * CounterValue * CounterValue + StartPoint;
break; break;
} }
@ -146,8 +130,7 @@ namespace TJAPlayer3
case CalcType.Quintic: //Quintic case CalcType.Quintic: //Quintic
CounterValue /= TimeMs; CounterValue /= TimeMs;
CounterValue /= TimeMs / 2; CounterValue /= TimeMs / 2;
if (CounterValue < 1) if (CounterValue < 1) {
{
Value = Sa / 2 * CounterValue * CounterValue * CounterValue * CounterValue * CounterValue + StartPoint; Value = Sa / 2 * CounterValue * CounterValue * CounterValue * CounterValue * CounterValue + StartPoint;
break; break;
} }
@ -159,8 +142,7 @@ namespace TJAPlayer3
break; break;
case CalcType.Exponential: //Exponential case CalcType.Exponential: //Exponential
CounterValue /= TimeMs / 2; CounterValue /= TimeMs / 2;
if (CounterValue < 1) if (CounterValue < 1) {
{
Value = Sa / 2 * Math.Pow(2, 10 * (CounterValue - 1)) + StartPoint; Value = Sa / 2 * Math.Pow(2, 10 * (CounterValue - 1)) + StartPoint;
break; break;
} }
@ -169,8 +151,7 @@ namespace TJAPlayer3
break; break;
case CalcType.Circular: //Circular case CalcType.Circular: //Circular
CounterValue /= TimeMs / 2; CounterValue /= TimeMs / 2;
if (CounterValue < 1) if (CounterValue < 1) {
{
Value = -Sa / 2 * (Math.Sqrt(1 - CounterValue * CounterValue) - 1) + StartPoint; Value = -Sa / 2 * (Math.Sqrt(1 - CounterValue * CounterValue) - 1) + StartPoint;
break; break;
} }
@ -193,8 +174,7 @@ namespace TJAPlayer3
private CalcType Type; private CalcType Type;
private double CounterValue; private double CounterValue;
private double Value; private double Value;
public enum CalcType public enum CalcType {
{
Quadratic, Quadratic,
Cubic, Cubic,
Quartic, Quartic,

View File

@ -1,15 +1,5 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; internal class Favorites {
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TJAPlayer3
{
internal class Favorites
{
public void tFavorites() { public void tFavorites() {
if (!File.Exists("Favorite.json")) if (!File.Exists("Favorite.json"))
tSaveFile(); tSaveFile();
@ -19,8 +9,7 @@ namespace TJAPlayer3
#region [Auxiliary methods] #region [Auxiliary methods]
public void tToggleFavorite(string chartID) public void tToggleFavorite(string chartID) {
{
if (tIsFavorite(chartID)) if (tIsFavorite(chartID))
data.favorites[TJAPlayer3.SaveFile].Remove(chartID); data.favorites[TJAPlayer3.SaveFile].Remove(chartID);
else else
@ -29,16 +18,14 @@ namespace TJAPlayer3
tSaveFile(); tSaveFile();
} }
public bool tIsFavorite(string chartID) public bool tIsFavorite(string chartID) {
{
return (data.favorites[TJAPlayer3.SaveFile].Contains(chartID)); return (data.favorites[TJAPlayer3.SaveFile].Contains(chartID));
} }
#endregion #endregion
public class Data public class Data {
{
public HashSet<string>[] favorites = new HashSet<string>[2] { new HashSet<string>(), new HashSet<string>() }; public HashSet<string>[] favorites = new HashSet<string>[2] { new HashSet<string>(), new HashSet<string>() };
} }
@ -46,13 +33,11 @@ namespace TJAPlayer3
#region [private] #region [private]
private void tSaveFile() private void tSaveFile() {
{
ConfigManager.SaveConfig(data, "Favorite.json"); ConfigManager.SaveConfig(data, "Favorite.json");
} }
private void tLoadFile() private void tLoadFile() {
{
data = ConfigManager.GetConfig<Data>(@"Favorite.json"); data = ConfigManager.GetConfig<Data>(@"Favorite.json");
} }

View File

@ -1,7 +1,6 @@
using FDK; using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{
/// <summary> /// <summary>
/// KeyboardSoundGroupLevelControlHandler is called by the song selection /// KeyboardSoundGroupLevelControlHandler is called by the song selection
/// and song play stages when handling keyboard input. By delegating to /// and song play stages when handling keyboard input. By delegating to
@ -18,14 +17,12 @@ namespace TJAPlayer3
/// configuration is updated. See ConfigIniToSoundGroupLevelControllerBinder /// configuration is updated. See ConfigIniToSoundGroupLevelControllerBinder
/// for more details on the latter. /// for more details on the latter.
/// </summary> /// </summary>
internal static class KeyboardSoundGroupLevelControlHandler internal static class KeyboardSoundGroupLevelControlHandler {
{
internal static void Handle( internal static void Handle(
IInputDevice keyboard, IInputDevice keyboard,
SoundGroupLevelController soundGroupLevelController, SoundGroupLevelController soundGroupLevelController,
CSkin skin, CSkin skin,
bool isSongPreview) bool isSongPreview) {
{
bool isAdjustmentPositive = TJAPlayer3.ConfigIni.KeyAssign.KeyIsPressed(TJAPlayer3.ConfigIni.KeyAssign.System.SongVolIncrease); bool isAdjustmentPositive = TJAPlayer3.ConfigIni.KeyAssign.KeyIsPressed(TJAPlayer3.ConfigIni.KeyAssign.System.SongVolIncrease);
bool isAdjustmentNegative = TJAPlayer3.ConfigIni.KeyAssign.KeyIsPressed(TJAPlayer3.ConfigIni.KeyAssign.System.SongVolDecrease); bool isAdjustmentNegative = TJAPlayer3.ConfigIni.KeyAssign.KeyIsPressed(TJAPlayer3.ConfigIni.KeyAssign.System.SongVolDecrease);
@ -35,19 +32,14 @@ namespace TJAPlayer3
CSkin.CSystemSound = null; CSkin.CSystemSound = null;
if (keyboard.KeyPressing((int)SlimDXKeys.Key.LeftControl) || if (keyboard.KeyPressing((int)SlimDXKeys.Key.LeftControl) ||
keyboard.KeyPressing((int)SlimDXKeys.Key.RightControl)) keyboard.KeyPressing((int)SlimDXKeys.Key.RightControl)) {
{
soundGroup = ESoundGroup.SoundEffect; soundGroup = ESoundGroup.SoundEffect;
= skin.soundDecideSFX; = skin.soundDecideSFX;
} } else if (keyboard.KeyPressing((int)SlimDXKeys.Key.LeftShift) ||
else if (keyboard.KeyPressing((int)SlimDXKeys.Key.LeftShift) || keyboard.KeyPressing((int)SlimDXKeys.Key.RightShift)) {
keyboard.KeyPressing((int)SlimDXKeys.Key.RightShift))
{
soundGroup = ESoundGroup.Voice; soundGroup = ESoundGroup.Voice;
= skin.soundゲーム開始音; = skin.soundゲーム開始音;
} } else {
else
{
soundGroup = ESoundGroup.SongPlayback; soundGroup = ESoundGroup.SongPlayback;
} }

View File

@ -1,29 +1,19 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FDK; using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ internal class LogNotification {
internal class LogNotification
{
private static Queue<CLogNotification> Notifications = new Queue<CLogNotification>(); private static Queue<CLogNotification> Notifications = new Queue<CLogNotification>();
public enum ENotificationType public enum ENotificationType {
{
EINFO, EINFO,
ESUCCESS, ESUCCESS,
EWARNING, EWARNING,
EERROR, EERROR,
} }
public class CLogNotification public class CLogNotification {
{ public CLogNotification(ENotificationType nt, string msg) {
public CLogNotification(ENotificationType nt, string msg)
{
NotificationType = nt; NotificationType = nt;
Message = msg; Message = msg;
} }
@ -34,32 +24,27 @@ namespace TJAPlayer3
} }
public static void PopError(string message) public static void PopError(string message) {
{
Notifications.Enqueue(new CLogNotification(ENotificationType.EERROR, message)); Notifications.Enqueue(new CLogNotification(ENotificationType.EERROR, message));
Trace.TraceError("<Runtime Error>: " + message); Trace.TraceError("<Runtime Error>: " + message);
} }
public static void PopWarning(string message) public static void PopWarning(string message) {
{
Notifications.Enqueue(new CLogNotification(ENotificationType.EWARNING, message)); Notifications.Enqueue(new CLogNotification(ENotificationType.EWARNING, message));
Trace.TraceWarning("<Runtime Warning>: " + message); Trace.TraceWarning("<Runtime Warning>: " + message);
} }
public static void PopSuccess(string message) public static void PopSuccess(string message) {
{
Notifications.Enqueue(new CLogNotification(ENotificationType.ESUCCESS, message)); Notifications.Enqueue(new CLogNotification(ENotificationType.ESUCCESS, message));
Trace.TraceInformation("<Runtime Success>: " + message); Trace.TraceInformation("<Runtime Success>: " + message);
} }
public static void PopInfo(string message) public static void PopInfo(string message) {
{
Notifications.Enqueue(new CLogNotification(ENotificationType.EINFO, message)); Notifications.Enqueue(new CLogNotification(ENotificationType.EINFO, message));
Trace.TraceInformation("<Runtime Info>: " + message); Trace.TraceInformation("<Runtime Info>: " + message);
} }
public static void Display() public static void Display() {
{
while (Notifications.Count > 0 && Notifications.Peek().LifeTime.IsEnded) Notifications.Dequeue(); while (Notifications.Count > 0 && Notifications.Peek().LifeTime.IsEnded) Notifications.Dequeue();
// Add an optimized method to display the notifications here // Add an optimized method to display the notifications here
} }

View File

@ -1,18 +1,10 @@
using System; using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FDK; using FDK;
using System.Drawing;
using static TJAPlayer3.CActSelect曲リスト; using static TJAPlayer3.CActSelect曲リスト;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ internal class Modal {
internal class Modal public Modal(EModalType mt, int ra, params object[] re) {
{
public Modal(EModalType mt, int ra, params object[] re)
{
modalType = mt; modalType = mt;
rarity = ra; rarity = ra;
reference = re; reference = re;
@ -20,8 +12,7 @@ namespace TJAPlayer3
// TODO: Add an int (?) or string to find the Puchichara/Character/Song asset to display it // TODO: Add an int (?) or string to find the Puchichara/Character/Song asset to display it
} }
public void tSetupModal() public void tSetupModal() {
{
CTexture[] arrRef; CTexture[] arrRef;
if (modalFormat == EModalFormat.Half) if (modalFormat == EModalFormat.Half)
@ -35,8 +26,7 @@ namespace TJAPlayer3
if (modalType == EModalType.Coin) if (modalType == EModalType.Coin)
_box = arrRef[arrRef.Length - 1]; _box = arrRef[arrRef.Length - 1];
else else {
{
int usedTex = Math.Max(0, Math.Min(arrRef.Length - 2, rarity)); int usedTex = Math.Max(0, Math.Min(arrRef.Length - 2, rarity));
_box = arrRef[usedTex]; _box = arrRef[usedTex];
} }
@ -64,10 +54,8 @@ namespace TJAPlayer3
_isSet = true; _isSet = true;
} }
public void tDisplayModal() public void tDisplayModal() {
{ if (_isSet == true) {
if (_isSet == true)
{
_box?.t2D描画(_boxRect.Width * (player % 2), _boxRect.Height * (player / 2), _boxRect); _box?.t2D描画(_boxRect.Width * (player % 2), _boxRect.Height * (player / 2), _boxRect);
int[] title_x; int[] title_x;
@ -77,8 +65,7 @@ namespace TJAPlayer3
int moveX; int moveX;
int moveY; int moveY;
if (modalFormat == EModalFormat.Full) if (modalFormat == EModalFormat.Full) {
{
title_x = new int[] { TJAPlayer3.Skin.Modal_Title_Full[0] }; title_x = new int[] { TJAPlayer3.Skin.Modal_Title_Full[0] };
title_y = new int[] { TJAPlayer3.Skin.Modal_Title_Full[1] }; title_y = new int[] { TJAPlayer3.Skin.Modal_Title_Full[1] };
@ -87,9 +74,7 @@ namespace TJAPlayer3
moveX = TJAPlayer3.Skin.Modal_Text_Full_Move[0]; moveX = TJAPlayer3.Skin.Modal_Text_Full_Move[0];
moveY = TJAPlayer3.Skin.Modal_Text_Full_Move[1]; moveY = TJAPlayer3.Skin.Modal_Text_Full_Move[1];
} } else if (modalFormat == EModalFormat.Half) {
else if (modalFormat == EModalFormat.Half)
{
title_x = TJAPlayer3.Skin.Modal_Title_Half_X; title_x = TJAPlayer3.Skin.Modal_Title_Half_X;
title_y = TJAPlayer3.Skin.Modal_Title_Half_Y; title_y = TJAPlayer3.Skin.Modal_Title_Half_Y;
@ -98,9 +83,7 @@ namespace TJAPlayer3
moveX = TJAPlayer3.Skin.Modal_Text_Half_Move[0]; moveX = TJAPlayer3.Skin.Modal_Text_Half_Move[0];
moveY = TJAPlayer3.Skin.Modal_Text_Half_Move[1]; moveY = TJAPlayer3.Skin.Modal_Text_Half_Move[1];
} } else if (modalFormat == EModalFormat.Half_4P) {
else if (modalFormat == EModalFormat.Half_4P)
{
title_x = TJAPlayer3.Skin.Modal_Title_Half_X_4P; title_x = TJAPlayer3.Skin.Modal_Title_Half_X_4P;
title_y = TJAPlayer3.Skin.Modal_Title_Half_Y_4P; title_y = TJAPlayer3.Skin.Modal_Title_Half_Y_4P;
@ -109,8 +92,7 @@ namespace TJAPlayer3
moveX = TJAPlayer3.Skin.Modal_Text_Half_Move_4P[0]; moveX = TJAPlayer3.Skin.Modal_Text_Half_Move_4P[0];
moveY = TJAPlayer3.Skin.Modal_Text_Half_Move_4P[1]; moveY = TJAPlayer3.Skin.Modal_Text_Half_Move_4P[1];
} } else// 5P
else// 5P
{ {
title_x = TJAPlayer3.Skin.Modal_Title_Half_X_5P; title_x = TJAPlayer3.Skin.Modal_Title_Half_X_5P;
title_y = TJAPlayer3.Skin.Modal_Title_Half_Y_5P; title_y = TJAPlayer3.Skin.Modal_Title_Half_Y_5P;
@ -149,16 +131,14 @@ namespace TJAPlayer3
} }
} }
public void tPlayModalSfx() public void tPlayModalSfx() {
{
if (modalType == EModalType.Coin) if (modalType == EModalType.Coin)
TJAPlayer3.Skin.soundModal[TJAPlayer3.Skin.soundModal.Length - 1].tPlay(); TJAPlayer3.Skin.soundModal[TJAPlayer3.Skin.soundModal.Length - 1].tPlay();
else else
TJAPlayer3.Skin.soundModal[Math.Max(0, Math.Min(TJAPlayer3.Skin.soundModal.Length - 2, rarity))].tPlay(); TJAPlayer3.Skin.soundModal[Math.Max(0, Math.Min(TJAPlayer3.Skin.soundModal.Length - 2, rarity))].tPlay();
} }
public static void tInitModalFonts() public static void tInitModalFonts() {
{
if (_pfModalContentHalf != null if (_pfModalContentHalf != null
&& _pfModalTitleHalf != null && _pfModalTitleHalf != null
&& _pfModalContentFull != null && _pfModalContentFull != null
@ -173,8 +153,7 @@ namespace TJAPlayer3
#region [Enum definitions] #region [Enum definitions]
public enum EModalType public enum EModalType {
{
Coin = 0, Coin = 0,
Character = 1, Character = 1,
Puchichara = 2, Puchichara = 2,
@ -184,8 +163,7 @@ namespace TJAPlayer3
} }
// Full : 1P standard modal, Half : Splitted screen modal // Full : 1P standard modal, Half : Splitted screen modal
public enum EModalFormat public enum EModalFormat {
{
Full, Full,
Half, Half,
Half_4P, Half_4P,
@ -211,19 +189,16 @@ namespace TJAPlayer3
#region [private] #region [private]
// Check if the text is vertically centered or slightly up (to let enough space for the unlocked unit texture) // Check if the text is vertically centered or slightly up (to let enough space for the unlocked unit texture)
private bool tTextCentered() private bool tTextCentered() {
{
if (modalType == EModalType.Coin) if (modalType == EModalType.Coin)
return true; return true;
return false; return false;
} }
// Generate the modal title and content text textures // Generate the modal title and content text textures
private void tGenerateTextures() private void tGenerateTextures() {
{
string modalKey = "MODAL_TITLE_COIN"; string modalKey = "MODAL_TITLE_COIN";
switch (modalType) switch (modalType) {
{
case EModalType.Character: case EModalType.Character:
modalKey = "MODAL_TITLE_CHARA"; modalKey = "MODAL_TITLE_CHARA";
break; break;
@ -248,8 +223,7 @@ namespace TJAPlayer3
string content = ""; string content = "";
if (modalType == EModalType.Coin) if (modalType == EModalType.Coin) {
{
content = CLangManager.LangInstance.GetString("MODAL_MESSAGE_COIN", reference[0].ToString(), TJAPlayer3.SaveFileInstances[player].data.Medals.ToString()); content = CLangManager.LangInstance.GetString("MODAL_MESSAGE_COIN", reference[0].ToString(), TJAPlayer3.SaveFileInstances[player].data.Medals.ToString());
//content = String.Format("+{0} {1} ({2}: {3})", //content = String.Format("+{0} {1} ({2}: {3})",
// (int)reference[0], // (int)reference[0],
@ -257,21 +231,13 @@ namespace TJAPlayer3
// CLangManager.LangInstance.GetString(307), // CLangManager.LangInstance.GetString(307),
// TJAPlayer3.SaveFileInstances[player].data.Medals // TJAPlayer3.SaveFileInstances[player].data.Medals
// ); // );
} } else if (modalType == EModalType.Title) {
else if (modalType == EModalType.Title)
{
content = ((string)reference[0]).RemoveTags(); content = ((string)reference[0]).RemoveTags();
} } else if (modalType == EModalType.Character) {
else if (modalType == EModalType.Character)
{
content = ((string)reference[0]).RemoveTags(); content = ((string)reference[0]).RemoveTags();
} } else if (modalType == EModalType.Puchichara) {
else if (modalType == EModalType.Puchichara)
{
content = ((string)reference[0]).RemoveTags(); content = ((string)reference[0]).RemoveTags();
} } else if (modalType == EModalType.Song) {
else if (modalType == EModalType.Song)
{
content = ((string)reference[0]).RemoveTags(); content = ((string)reference[0]).RemoveTags();
} }

View File

@ -1,22 +1,12 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; internal class ModalQueue {
using System.Linq; public ModalQueue(Modal.EModalFormat mf) {
using System.Text;
using System.Threading.Tasks;
namespace TJAPlayer3
{
internal class ModalQueue
{
public ModalQueue(Modal.EModalFormat mf)
{
_modalQueues = new Queue<Modal>[] { new Queue<Modal>(), new Queue<Modal>(), new Queue<Modal>(), new Queue<Modal>(), new Queue<Modal>() }; _modalQueues = new Queue<Modal>[] { new Queue<Modal>(), new Queue<Modal>(), new Queue<Modal>(), new Queue<Modal>(), new Queue<Modal>() };
_modalFormat = mf; _modalFormat = mf;
} }
// Add two modals (one per player) at the same time // Add two modals (one per player) at the same time
public void tAddModal(Modal mp1, Modal mp2, Modal mp3, Modal mp4, Modal mp5) public void tAddModal(Modal mp1, Modal mp2, Modal mp3, Modal mp4, Modal mp5) {
{
mp1.modalFormat = _modalFormat; mp1.modalFormat = _modalFormat;
mp2.modalFormat = _modalFormat; mp2.modalFormat = _modalFormat;
mp3.modalFormat = _modalFormat; mp3.modalFormat = _modalFormat;
@ -46,8 +36,7 @@ namespace TJAPlayer3
} }
// Add a single modal // Add a single modal
public void tAddModal(Modal mp, int player) public void tAddModal(Modal mp, int player) {
{
mp.modalFormat = _modalFormat; mp.modalFormat = _modalFormat;
mp.player = player; mp.player = player;
mp.tSetupModal(); mp.tSetupModal();
@ -56,23 +45,20 @@ namespace TJAPlayer3
_modalQueues[player].Enqueue(mp); _modalQueues[player].Enqueue(mp);
} }
public Modal tPopModal(int player) public Modal tPopModal(int player) {
{
if (!tIsQueueEmpty(player)) if (!tIsQueueEmpty(player))
return _modalQueues[player].Dequeue(); return _modalQueues[player].Dequeue();
return null; return null;
} }
public bool tIsQueueEmpty(int player) public bool tIsQueueEmpty(int player) {
{
if (player < 0 || player >= TJAPlayer3.ConfigIni.nPlayerCount) if (player < 0 || player >= TJAPlayer3.ConfigIni.nPlayerCount)
return true; return true;
return _modalQueues[player].Count < 1; return _modalQueues[player].Count < 1;
} }
public bool tAreBothQueuesEmpty() public bool tAreBothQueuesEmpty() {
{
return tIsQueueEmpty(0) && tIsQueueEmpty(1) && tIsQueueEmpty(2) && tIsQueueEmpty(3) && tIsQueueEmpty(4); return tIsQueueEmpty(0) && tIsQueueEmpty(1) && tIsQueueEmpty(2) && tIsQueueEmpty(3) && tIsQueueEmpty(4);
} }

View File

@ -1,17 +1,8 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ class NamePlateConfig {
class NamePlateConfig public void tNamePlateConfig() {
{
public void tNamePlateConfig()
{
// Deprecated, only converts to new format // Deprecated, only converts to new format
/* /*
if (!File.Exists("NamePlate.json")) if (!File.Exists("NamePlate.json"))
@ -23,13 +14,11 @@ namespace TJAPlayer3
#region [Medals] #region [Medals]
public void tEarnCoins(int[] amounts) public void tEarnCoins(int[] amounts) {
{
if (amounts.Length < 2) if (amounts.Length < 2)
return; return;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++) {
{
int p = TJAPlayer3.GetActualPlayer(i); int p = TJAPlayer3.GetActualPlayer(i);
data.Medals[p] += amounts[i]; data.Medals[p] += amounts[i];
@ -38,8 +27,7 @@ namespace TJAPlayer3
} }
// Return false if the current amount of coins is to low // Return false if the current amount of coins is to low
public bool tSpendCoins(int amount, int player) public bool tSpendCoins(int amount, int player) {
{
if (player > 1 || player < 0) if (player > 1 || player < 0)
return false; return false;
@ -57,8 +45,7 @@ namespace TJAPlayer3
#region [Dan titles] #region [Dan titles]
public bool tUpdateDanTitle(string title, bool isGold, int clearStatus, int player) public bool tUpdateDanTitle(string title, bool isGold, int clearStatus, int player) {
{
bool changed = false; bool changed = false;
bool iG = isGold; bool iG = isGold;
@ -67,8 +54,7 @@ namespace TJAPlayer3
if (TJAPlayer3.NamePlateConfig.data.DanTitles[player] == null) if (TJAPlayer3.NamePlateConfig.data.DanTitles[player] == null)
TJAPlayer3.NamePlateConfig.data.DanTitles[player] = new Dictionary<string, SaveFile.CDanTitle>(); TJAPlayer3.NamePlateConfig.data.DanTitles[player] = new Dictionary<string, SaveFile.CDanTitle>();
if (TJAPlayer3.NamePlateConfig.data.DanTitles[player].ContainsKey(title)) if (TJAPlayer3.NamePlateConfig.data.DanTitles[player].ContainsKey(title)) {
{
if (TJAPlayer3.NamePlateConfig.data.DanTitles[player][title].clearStatus > cs) if (TJAPlayer3.NamePlateConfig.data.DanTitles[player][title].clearStatus > cs)
cs = TJAPlayer3.NamePlateConfig.data.DanTitles[player][title].clearStatus; cs = TJAPlayer3.NamePlateConfig.data.DanTitles[player][title].clearStatus;
if (TJAPlayer3.NamePlateConfig.data.DanTitles[player][title].isGold) if (TJAPlayer3.NamePlateConfig.data.DanTitles[player][title].isGold)
@ -78,8 +64,7 @@ namespace TJAPlayer3
// Automatically set the dan to nameplate if new // Automatically set the dan to nameplate if new
// Add a function within the NamePlate.cs file to update the title texture // Add a function within the NamePlate.cs file to update the title texture
if (!TJAPlayer3.NamePlateConfig.data.DanTitles[player].ContainsKey(title) || cs != clearStatus || iG != isGold) if (!TJAPlayer3.NamePlateConfig.data.DanTitles[player].ContainsKey(title) || cs != clearStatus || iG != isGold) {
{
changed = true; changed = true;
/* /*
TJAPlayer3.NamePlateConfig.data.Dan[player] = title; TJAPlayer3.NamePlateConfig.data.Dan[player] = title;
@ -102,10 +87,8 @@ namespace TJAPlayer3
#region [Auxilliary classes] #region [Auxilliary classes]
public class CDanTitle public class CDanTitle {
{ public CDanTitle(bool iG, int cs) {
public CDanTitle(bool iG, int cs)
{
isGold = iG; isGold = iG;
clearStatus = cs; clearStatus = cs;
} }
@ -117,10 +100,8 @@ namespace TJAPlayer3
public int clearStatus; public int clearStatus;
} }
public class CNamePlateTitle public class CNamePlateTitle {
{ public CNamePlateTitle(int type) {
public CNamePlateTitle(int type)
{
iType = type; iType = type;
} }
@ -132,8 +113,7 @@ namespace TJAPlayer3
#region [Heya] #region [Heya]
public void tReindexCharacter(int p, string[] characterNamesList) public void tReindexCharacter(int p, string[] characterNamesList) {
{
string character = this.data.CharacterName[p]; string character = this.data.CharacterName[p];
if (characterNamesList.Contains(character)) if (characterNamesList.Contains(character))
@ -141,20 +121,17 @@ namespace TJAPlayer3
} }
public void tUpdateCharacterName(int p, string newChara) public void tUpdateCharacterName(int p, string newChara) {
{
this.data.CharacterName[p] = newChara; this.data.CharacterName[p] = newChara;
} }
public void tApplyHeyaChanges() public void tApplyHeyaChanges() {
{
this.tSaveFile(); this.tSaveFile();
} }
#endregion #endregion
public class Data public class Data {
{
[JsonProperty("name")] [JsonProperty("name")]
public string[] Name = { "プレイヤー1", "プレイヤー2", "プレイヤー3", "プレイヤー4", "プレイヤー5" }; public string[] Name = { "プレイヤー1", "プレイヤー2", "プレイヤー3", "プレイヤー4", "プレイヤー5" };
@ -207,13 +184,11 @@ namespace TJAPlayer3
#region [private] #region [private]
private void tSaveFile() private void tSaveFile() {
{
ConfigManager.SaveConfig(data, "NamePlate.json"); ConfigManager.SaveConfig(data, "NamePlate.json");
} }
private void tLoadFile() private void tLoadFile() {
{
//data = ConfigManager.GetConfig<Data>(@"NamePlate.json"); //data = ConfigManager.GetConfig<Data>(@"NamePlate.json");
if (!File.Exists("NamePlate.json")) if (!File.Exists("NamePlate.json"))
@ -221,8 +196,7 @@ namespace TJAPlayer3
var _data = ConfigManager.GetConfig<Data>(@"NamePlate.json"); var _data = ConfigManager.GetConfig<Data>(@"NamePlate.json");
for (int i = 0; i < _data.Name.Length; i++) for (int i = 0; i < _data.Name.Length; i++) {
{
var _sf = new SaveFile(); var _sf = new SaveFile();
_sf.tSaveFile((i + 1) + "P"); _sf.tSaveFile((i + 1) + "P");
_sf.data.Name = _data.Name[i]; _sf.data.Name = _data.Name[i];

View File

@ -1,49 +1,35 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
using System.IO;
using FDK;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ internal class Program {
internal class Program
{
#region [ DLL存在チェック ] #region [ DLL存在チェック ]
//----------------------------- //-----------------------------
private static Mutex mutex二重起動防止用; private static Mutex mutex二重起動防止用;
private static bool tDLLの存在チェック( string strDll名, string str存在しないときに表示するエラー文字列jp, string str存在しないときに表示するエラー文字列en, bool bLoadDllCheck ) private static bool tDLLの存在チェック(string strDll名, string str存在しないときに表示するエラー文字列jp, string str存在しないときに表示するエラー文字列en, bool bLoadDllCheck) {
{
string str存在しないときに表示するエラー文字列 = (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "ja") ? string str存在しないときに表示するエラー文字列 = (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "ja") ?
str存在しないときに表示するエラー文字列jp : str存在しないときに表示するエラー文字列en; str存在しないときに表示するエラー文字列jp : str存在しないときに表示するエラー文字列en;
if ( bLoadDllCheck ) if (bLoadDllCheck) {
{
IntPtr hModule = LoadLibrary(strDll名); // 実際にLoadDll()してチェックする IntPtr hModule = LoadLibrary(strDll名); // 実際にLoadDll()してチェックする
if ( hModule == IntPtr.Zero ) if (hModule == IntPtr.Zero) {
{
//MessageBox.Show( str存在しないときに表示するエラー文字列, "DTXMania runtime error", MessageBoxButtons.OK, MessageBoxIcon.Hand ); //MessageBox.Show( str存在しないときに表示するエラー文字列, "DTXMania runtime error", MessageBoxButtons.OK, MessageBoxIcon.Hand );
return false; return false;
} }
FreeLibrary(hModule); FreeLibrary(hModule);
} } else { // 単純にファイルの存在有無をチェックするだけ (プロジェクトで「参照」していたり、アンマネージドなDLLが暗黙リンクされるものはこちら)
else
{ // 単純にファイルの存在有無をチェックするだけ (プロジェクトで「参照」していたり、アンマネージドなDLLが暗黙リンクされるものはこちら)
string path = Path.Combine(System.IO.Directory.GetCurrentDirectory(), strDll名); string path = Path.Combine(System.IO.Directory.GetCurrentDirectory(), strDll名);
if ( !File.Exists( path ) ) if (!File.Exists(path)) {
{
//MessageBox.Show( str存在しないときに表示するエラー文字列, "DTXMania runtime error", MessageBoxButtons.OK, MessageBoxIcon.Hand ); //MessageBox.Show( str存在しないときに表示するエラー文字列, "DTXMania runtime error", MessageBoxButtons.OK, MessageBoxIcon.Hand );
return false; return false;
} }
} }
return true; return true;
} }
private static bool tDLLの存在チェック( string strDll名, string str存在しないときに表示するエラー文字列jp, string str存在しないときに表示するエラー文字列en ) private static bool tDLLの存在チェック(string strDll名, string str存在しないときに表示するエラー文字列jp, string str存在しないときに表示するエラー文字列en) {
{
return true; return true;
//return tDLLの存在チェック( strDll名, str存在しないときに表示するエラー文字列jp, str存在しないときに表示するエラー文字列en, false ); //return tDLLの存在チェック( strDll名, str存在しないときに表示するエラー文字列jp, str存在しないときに表示するエラー文字列en, false );
} }
@ -59,14 +45,12 @@ namespace TJAPlayer3
#endregion #endregion
[STAThread] [STAThread]
static void Main() static void Main() {
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
mutex二重起動防止用 = new Mutex(false, "DTXManiaMutex"); mutex二重起動防止用 = new Mutex(false, "DTXManiaMutex");
if ( mutex二重起動防止用.WaitOne( 0, false ) ) if (mutex二重起動防止用.WaitOne(0, false)) {
{
string newLine = Environment.NewLine; string newLine = Environment.NewLine;
bool bDLLnotfound = false; bool bDLLnotfound = false;
@ -96,8 +80,7 @@ namespace TJAPlayer3
string platform = ""; string platform = "";
switch (RuntimeInformation.ProcessArchitecture) switch (RuntimeInformation.ProcessArchitecture) {
{
case Architecture.X64: case Architecture.X64:
platform = "x64"; platform = "x64";
break; break;
@ -118,8 +101,7 @@ namespace TJAPlayer3
DirectoryInfo info = new DirectoryInfo(AppContext.BaseDirectory + @"Libs/" + osplatform + "-" + platform + "/"); DirectoryInfo info = new DirectoryInfo(AppContext.BaseDirectory + @"Libs/" + osplatform + "-" + platform + "/");
//実行ファイルの階層にライブラリをコピー //実行ファイルの階層にライブラリをコピー
foreach (FileInfo fileinfo in info.GetFiles()) foreach (FileInfo fileinfo in info.GetFiles()) {
{
fileinfo.CopyTo(AppContext.BaseDirectory + fileinfo.Name, true); fileinfo.CopyTo(AppContext.BaseDirectory + fileinfo.Name, true);
} }
@ -154,8 +136,7 @@ namespace TJAPlayer3
mutex二重起動防止用 = null; mutex二重起動防止用 = null;
// END #24615 2011.03.09 from // END #24615 2011.03.09 from
} } else // DTXManiaが既に起動中
else // DTXManiaが既に起動中
{ {
// → 引数が0個の時はそのまま終了 // → 引数が0個の時はそのまま終了
@ -173,12 +154,10 @@ namespace TJAPlayer3
Process target = null; Process target = null;
//IntPtr hWnd = FindWindow( null, "DTXMania .NET style release " + CDTXMania.VERSION ); //IntPtr hWnd = FindWindow( null, "DTXMania .NET style release " + CDTXMania.VERSION );
foreach ( Process p in running ) foreach (Process p in running) {
{
if (p.Id != current.Id) // プロセス名は同じでかつ、プロセスIDが自分自身とは異なるものを探す if (p.Id != current.Id) // プロセス名は同じでかつ、プロセスIDが自分自身とは異なるものを探す
{ {
if ( p.MainModule.FileName == current.MainModule.FileName && p.MainWindowHandle != IntPtr.Zero ) if (p.MainModule.FileName == current.MainModule.FileName && p.MainWindowHandle != IntPtr.Zero) {
{
target = p; target = p;
break; break;
} }
@ -187,20 +166,14 @@ namespace TJAPlayer3
#endregion #endregion
#region [ DTXManiaがいれば ] #region [ DTXManiaがいれば ]
if ( target != null ) if (target != null) {
{
string[] commandLineArgs = Environment.GetCommandLineArgs(); string[] commandLineArgs = Environment.GetCommandLineArgs();
if ( commandLineArgs != null && commandLineArgs.Length > 1 ) if (commandLineArgs != null && commandLineArgs.Length > 1) {
{
string arg = null; string arg = null;
for ( int j = 1; j < commandLineArgs.Length; j++ ) for (int j = 1; j < commandLineArgs.Length; j++) {
{ if (j == 1) {
if ( j == 1 )
{
arg += commandLineArgs[j]; arg += commandLineArgs[j];
} } else {
else
{
arg += " " + "\"" + commandLineArgs[j] + "\""; arg += " " + "\"" + commandLineArgs[j] + "\"";
} }
} }
@ -208,8 +181,7 @@ namespace TJAPlayer3
break; break;
} }
#endregion #endregion
else else {
{
Trace.TraceInformation("メッセージ送信先のプロセスが見つからず。5回リトライします。"); Trace.TraceInformation("メッセージ送信先のプロセスが見つからず。5回リトライします。");
Thread.Sleep(200); Thread.Sleep(200);
} }

View File

@ -1,15 +1,5 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; internal class RecentlyPlayedSongs {
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TJAPlayer3
{
internal class RecentlyPlayedSongs
{
public void tRecentlyPlayedSongs() { public void tRecentlyPlayedSongs() {
if (!File.Exists("RecentlyPlayedSongs.json")) if (!File.Exists("RecentlyPlayedSongs.json"))
tSaveFile(); tSaveFile();
@ -19,8 +9,7 @@ namespace TJAPlayer3
#region [Auxiliary methods] #region [Auxiliary methods]
public void tAddChart(string chartID) public void tAddChart(string chartID) {
{
if (!data.recentlyplayedsongs[TJAPlayer3.SaveFile].Contains(chartID)) if (!data.recentlyplayedsongs[TJAPlayer3.SaveFile].Contains(chartID))
data.recentlyplayedsongs[TJAPlayer3.SaveFile].Enqueue(chartID); data.recentlyplayedsongs[TJAPlayer3.SaveFile].Enqueue(chartID);
@ -32,8 +21,7 @@ namespace TJAPlayer3
#endregion #endregion
public class Data public class Data {
{
public Queue<string>[] recentlyplayedsongs = new Queue<string>[2] { new Queue<string>(), new Queue<string>() }; public Queue<string>[] recentlyplayedsongs = new Queue<string>[2] { new Queue<string>(), new Queue<string>() };
} }
@ -41,13 +29,11 @@ namespace TJAPlayer3
#region [private] #region [private]
private void tSaveFile() private void tSaveFile() {
{
ConfigManager.SaveConfig(data, "RecentlyPlayedSongs.json"); ConfigManager.SaveConfig(data, "RecentlyPlayedSongs.json");
} }
private void tLoadFile() private void tLoadFile() {
{
data = ConfigManager.GetConfig<Data>(@"RecentlyPlayedSongs.json"); data = ConfigManager.GetConfig<Data>(@"RecentlyPlayedSongs.json");
} }

View File

@ -1,24 +1,13 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ internal class SaveFile {
internal class SaveFile
{
public void tSaveFile(string filename) public void tSaveFile(string filename) {
{
path = @$"Saves{Path.DirectorySeparatorChar}" + filename + @".json"; path = @$"Saves{Path.DirectorySeparatorChar}" + filename + @".json";
name = filename; name = filename;
if (!File.Exists(path)) if (!File.Exists(path)) {
{
this.data.Name = filename; this.data.Name = filename;
tSaveFile(); tSaveFile();
} }
@ -28,14 +17,12 @@ namespace TJAPlayer3
tInitSaveFile(); tInitSaveFile();
} }
public void tInitSaveFile() public void tInitSaveFile() {
{
data.bestPlays = DBSaves.GetBestPlaysAsDict(data.SaveId); data.bestPlays = DBSaves.GetBestPlaysAsDict(data.SaveId);
data.tFactorizeBestPlays(); data.tFactorizeBestPlays();
} }
public void tLoadUnlockables() public void tLoadUnlockables() {
{
data.UnlockedCharacters = DBSaves.FetchStringUnlockedAsset(data.SaveId, "unlocked_characters"); data.UnlockedCharacters = DBSaves.FetchStringUnlockedAsset(data.SaveId, "unlocked_characters");
data.UnlockedPuchicharas = DBSaves.FetchStringUnlockedAsset(data.SaveId, "unlocked_puchicharas"); data.UnlockedPuchicharas = DBSaves.FetchStringUnlockedAsset(data.SaveId, "unlocked_puchicharas");
data.UnlockedSongs = DBSaves.FetchStringUnlockedAsset(data.SaveId, "unlocked_songs"); data.UnlockedSongs = DBSaves.FetchStringUnlockedAsset(data.SaveId, "unlocked_songs");
@ -46,8 +33,7 @@ namespace TJAPlayer3
#region [Medals and PlayCount] #region [Medals and PlayCount]
public void tEarnCoins(int amount) public void tEarnCoins(int amount) {
{
data.Medals += amount; data.Medals += amount;
data.TotalEarnedMedals += amount; data.TotalEarnedMedals += amount;
@ -59,8 +45,7 @@ namespace TJAPlayer3
} }
// Return false if the current amount of coins is to low // Return false if the current amount of coins is to low
public bool tSpendCoins(int amount) public bool tSpendCoins(int amount) {
{
if (data.Medals < amount) if (data.Medals < amount)
return false; return false;
@ -71,8 +56,7 @@ namespace TJAPlayer3
return true; return true;
} }
public void tRegisterAIBattleModePlay(bool IsWon) public void tRegisterAIBattleModePlay(bool IsWon) {
{
data.AIBattleModePlaycount++; data.AIBattleModePlaycount++;
if (IsWon) data.AIBattleModeWins++; if (IsWon) data.AIBattleModeWins++;
DBSaves.RegisterAIBattleModePlay(data.SaveId, IsWon); DBSaves.RegisterAIBattleModePlay(data.SaveId, IsWon);
@ -82,8 +66,7 @@ namespace TJAPlayer3
#region [Dan titles] #region [Dan titles]
public bool tUpdateDanTitle(string title, bool isGold, int clearStatus) public bool tUpdateDanTitle(string title, bool isGold, int clearStatus) {
{
bool changed = false; bool changed = false;
bool iG = isGold; bool iG = isGold;
@ -92,8 +75,7 @@ namespace TJAPlayer3
if (this.data.DanTitles == null) if (this.data.DanTitles == null)
this.data.DanTitles = new Dictionary<string, CDanTitle>(); this.data.DanTitles = new Dictionary<string, CDanTitle>();
if (this.data.DanTitles.ContainsKey(title)) if (this.data.DanTitles.ContainsKey(title)) {
{
if (this.data.DanTitles[title].clearStatus > cs) if (this.data.DanTitles[title].clearStatus > cs)
cs = this.data.DanTitles[title].clearStatus; cs = this.data.DanTitles[title].clearStatus;
if (this.data.DanTitles[title].isGold) if (this.data.DanTitles[title].isGold)
@ -103,8 +85,7 @@ namespace TJAPlayer3
// Automatically set the dan to nameplate if new // Automatically set the dan to nameplate if new
// Add a function within the NamePlate.cs file to update the title texture // Add a function within the NamePlate.cs file to update the title texture
if (!this.data.DanTitles.ContainsKey(title) || cs != clearStatus || iG != isGold) if (!this.data.DanTitles.ContainsKey(title) || cs != clearStatus || iG != isGold) {
{
DBSaves.RegisterDanTitle(data.SaveId, title, clearStatus, isGold); DBSaves.RegisterDanTitle(data.SaveId, title, clearStatus, isGold);
changed = true; changed = true;
/* /*
@ -128,16 +109,13 @@ namespace TJAPlayer3
#region [Auxilliary classes] #region [Auxilliary classes]
public class CDanTitle public class CDanTitle {
{ public CDanTitle(bool iG, int cs) {
public CDanTitle(bool iG, int cs)
{
isGold = iG; isGold = iG;
clearStatus = cs; clearStatus = cs;
} }
public CDanTitle() public CDanTitle() {
{
isGold = false; isGold = false;
clearStatus = 0; clearStatus = 0;
} }
@ -149,10 +127,8 @@ namespace TJAPlayer3
public int clearStatus; public int clearStatus;
} }
public class CNamePlateTitle public class CNamePlateTitle {
{ public CNamePlateTitle(int type) {
public CNamePlateTitle(int type)
{
iType = type; iType = type;
cld = new CLocalizationData(); cld = new CLocalizationData();
} }
@ -164,10 +140,8 @@ namespace TJAPlayer3
public CLocalizationData cld; public CLocalizationData cld;
} }
public class CPassStatus public class CPassStatus {
{ public CPassStatus() {
public CPassStatus()
{
d = new int[5] { -1, -1, -1, -1, -1 }; d = new int[5] { -1, -1, -1, -1, -1 };
} }
@ -178,8 +152,7 @@ namespace TJAPlayer3
#region [Heya] #region [Heya]
public void tReindexCharacter(string[] characterNamesList) public void tReindexCharacter(string[] characterNamesList) {
{
string character = this.data.CharacterName; string character = this.data.CharacterName;
if (characterNamesList.Contains(character)) if (characterNamesList.Contains(character))
@ -187,21 +160,18 @@ namespace TJAPlayer3
} }
public void tUpdateCharacterName(string newChara) public void tUpdateCharacterName(string newChara) {
{
this.data.CharacterName = newChara; this.data.CharacterName = newChara;
} }
public void tApplyHeyaChanges() public void tApplyHeyaChanges() {
{
DBSaves.ApplyChangesFromMyRoom(this); DBSaves.ApplyChangesFromMyRoom(this);
//this.tSaveFile(); //this.tSaveFile();
} }
#endregion #endregion
public class Data public class Data {
{
[JsonProperty("saveId")] [JsonProperty("saveId")]
public Int64 SaveId = 0; public Int64 SaveId = 0;
@ -232,6 +202,7 @@ namespace TJAPlayer3
[JsonProperty("puchiChara")] [JsonProperty("puchiChara")]
public string PuchiChara = "0"; public string PuchiChara = "0";
[JsonProperty("medals")] [JsonProperty("medals")]
public Int64 Medals = 0; public Int64 Medals = 0;
@ -293,29 +264,22 @@ namespace TJAPlayer3
[JsonIgnore] [JsonIgnore]
public BestPlayRecords.CBestPlayStats bestPlaysStats = new BestPlayRecords.CBestPlayStats(); public BestPlayRecords.CBestPlayStats bestPlaysStats = new BestPlayRecords.CBestPlayStats();
public BestPlayRecords.CSongSelectTableEntry tGetSongSelectTableEntry(string uniqueId) public BestPlayRecords.CSongSelectTableEntry tGetSongSelectTableEntry(string uniqueId) {
{
if (songSelectTableEntries.ContainsKey(uniqueId)) return songSelectTableEntries[uniqueId]; if (songSelectTableEntries.ContainsKey(uniqueId)) return songSelectTableEntries[uniqueId];
return new BestPlayRecords.CSongSelectTableEntry(); return new BestPlayRecords.CSongSelectTableEntry();
} }
#region [Factorize best plays] #region [Factorize best plays]
public void tFactorizeBestPlays() public void tFactorizeBestPlays() {
{
bestPlaysDistinctCharts = new Dictionary<string, BestPlayRecords.CBestPlayRecord>(); bestPlaysDistinctCharts = new Dictionary<string, BestPlayRecords.CBestPlayRecord>();
foreach (BestPlayRecords.CBestPlayRecord bestPlay in bestPlays.Values) foreach (BestPlayRecords.CBestPlayRecord bestPlay in bestPlays.Values) {
{
string key = bestPlay.ChartUniqueId + bestPlay.ChartDifficulty.ToString(); string key = bestPlay.ChartUniqueId + bestPlay.ChartDifficulty.ToString();
if (!bestPlaysDistinctCharts.ContainsKey(key)) if (!bestPlaysDistinctCharts.ContainsKey(key)) {
{
bestPlaysDistinctCharts[key] = bestPlay.Copy(); bestPlaysDistinctCharts[key] = bestPlay.Copy();
} } else {
else if (bestPlay.HighScore > bestPlaysDistinctCharts[key].HighScore) {
{
if (bestPlay.HighScore > bestPlaysDistinctCharts[key].HighScore)
{
bestPlaysDistinctCharts[key].HighScore = bestPlay.HighScore; bestPlaysDistinctCharts[key].HighScore = bestPlay.HighScore;
bestPlaysDistinctCharts[key].HighScoreGoodCount = bestPlay.HighScoreGoodCount; bestPlaysDistinctCharts[key].HighScoreGoodCount = bestPlay.HighScoreGoodCount;
bestPlaysDistinctCharts[key].HighScoreOkCount = bestPlay.HighScoreOkCount; bestPlaysDistinctCharts[key].HighScoreOkCount = bestPlay.HighScoreOkCount;
@ -333,17 +297,12 @@ namespace TJAPlayer3
bestPlaysDistinctSongs = new Dictionary<string, BestPlayRecords.CBestPlayRecord>(); bestPlaysDistinctSongs = new Dictionary<string, BestPlayRecords.CBestPlayRecord>();
songSelectTableEntries = new Dictionary<string, BestPlayRecords.CSongSelectTableEntry>(); songSelectTableEntries = new Dictionary<string, BestPlayRecords.CSongSelectTableEntry>();
foreach (BestPlayRecords.CBestPlayRecord bestPlay in bestPlaysDistinctCharts.Values) foreach (BestPlayRecords.CBestPlayRecord bestPlay in bestPlaysDistinctCharts.Values) {
{
string key = bestPlay.ChartUniqueId; string key = bestPlay.ChartUniqueId;
if (!bestPlaysDistinctSongs.ContainsKey(key)) if (!bestPlaysDistinctSongs.ContainsKey(key)) {
{
bestPlaysDistinctSongs[key] = bestPlay.Copy(); bestPlaysDistinctSongs[key] = bestPlay.Copy();
} } else {
else if (bestPlay.HighScore > bestPlaysDistinctSongs[key].HighScore) {
{
if (bestPlay.HighScore > bestPlaysDistinctSongs[key].HighScore)
{
bestPlaysDistinctSongs[key].HighScore = bestPlay.HighScore; bestPlaysDistinctSongs[key].HighScore = bestPlay.HighScore;
bestPlaysDistinctSongs[key].HighScoreGoodCount = bestPlay.HighScoreGoodCount; bestPlaysDistinctSongs[key].HighScoreGoodCount = bestPlay.HighScoreGoodCount;
bestPlaysDistinctSongs[key].HighScoreOkCount = bestPlay.HighScoreOkCount; bestPlaysDistinctSongs[key].HighScoreOkCount = bestPlay.HighScoreOkCount;
@ -358,17 +317,14 @@ namespace TJAPlayer3
} }
// Entries to replace score.GPInfo on the song select menus // Entries to replace score.GPInfo on the song select menus
if (!songSelectTableEntries.ContainsKey(key)) if (!songSelectTableEntries.ContainsKey(key)) {
{
songSelectTableEntries[key] = new BestPlayRecords.CSongSelectTableEntry(); songSelectTableEntries[key] = new BestPlayRecords.CSongSelectTableEntry();
} }
if (bestPlay.ChartDifficulty > songSelectTableEntries[key].ScoreRankDifficulty && bestPlay.ScoreRank >= 0) if (bestPlay.ChartDifficulty > songSelectTableEntries[key].ScoreRankDifficulty && bestPlay.ScoreRank >= 0) {
{
songSelectTableEntries[key].ScoreRankDifficulty = (int)bestPlay.ChartDifficulty; songSelectTableEntries[key].ScoreRankDifficulty = (int)bestPlay.ChartDifficulty;
songSelectTableEntries[key].ScoreRank = (int)bestPlay.ScoreRank; songSelectTableEntries[key].ScoreRank = (int)bestPlay.ScoreRank;
} }
if (bestPlay.ChartDifficulty > songSelectTableEntries[key].ClearStatusDifficulty && bestPlay.ClearStatus >= 0) if (bestPlay.ChartDifficulty > songSelectTableEntries[key].ClearStatusDifficulty && bestPlay.ClearStatus >= 0) {
{
songSelectTableEntries[key].ClearStatusDifficulty = (int)bestPlay.ChartDifficulty; songSelectTableEntries[key].ClearStatusDifficulty = (int)bestPlay.ChartDifficulty;
songSelectTableEntries[key].ClearStatus = (int)bestPlay.ClearStatus; songSelectTableEntries[key].ClearStatus = (int)bestPlay.ClearStatus;
} }
@ -390,13 +346,11 @@ namespace TJAPlayer3
#region [private] #region [private]
private void tSaveFile() private void tSaveFile() {
{
ConfigManager.SaveConfig(data, path); ConfigManager.SaveConfig(data, path);
} }
private void tLoadFile() private void tLoadFile() {
{
data = ConfigManager.GetConfig<Data>(path); data = ConfigManager.GetConfig<Data>(path);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,4 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; internal class CGimmickValue {
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TJAPlayer3
{
internal class CGimmickValue
{
} }
} }

View File

@ -1,25 +1,16 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace TJAPlayer3 namespace TJAPlayer3 {
{
[Serializable] [Serializable]
internal class CLocalizationData internal class CLocalizationData {
{
[JsonProperty("strings")] [JsonProperty("strings")]
private Dictionary<string, string> Strings = new Dictionary<string, string>(); private Dictionary<string, string> Strings = new Dictionary<string, string>();
public CLocalizationData() public CLocalizationData() {
{
Strings = new Dictionary<string, string>(); Strings = new Dictionary<string, string>();
} }
public string GetString(string defaultsDefault) public string GetString(string defaultsDefault) {
{
string _lang = CLangManager.fetchLang(); string _lang = CLangManager.fetchLang();
if (Strings.ContainsKey(_lang)) if (Strings.ContainsKey(_lang))
return Strings[_lang]; return Strings[_lang];
@ -28,8 +19,7 @@ namespace TJAPlayer3
return defaultsDefault; return defaultsDefault;
} }
public void SetString(string langcode, string str) public void SetString(string langcode, string str) {
{
Strings[langcode] = str; Strings[langcode] = str;
} }
} }

View File

@ -1,15 +1,5 @@
using System; namespace TJAPlayer3 {
using System.Collections.Generic; class CSongReplay {
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using static SevenZip.Compression.LZMA.SevenZipHelper;
namespace TJAPlayer3
{
class CSongReplay
{
/* Game version used for the replay /* Game version used for the replay
* 521 = 0.5.2.1 * 521 = 0.5.2.1
* 530 = 0.5.3 * 530 = 0.5.3
@ -35,8 +25,7 @@ namespace TJAPlayer3
* - 8 (256) : Safe (Bad => Ok) * - 8 (256) : Safe (Bad => Ok)
*/ */
[Flags] [Flags]
public enum EModFlag public enum EModFlag {
{
None = 0, None = 0,
Mirror = 1 << 0, Mirror = 1 << 0,
Random = 1 << 1, Random = 1 << 1,
@ -49,40 +38,33 @@ namespace TJAPlayer3
Safe = 1 << 8 Safe = 1 << 8
} }
public CSongReplay() public CSongReplay() {
{
replayFolder = ""; replayFolder = "";
storedPlayer = 0; storedPlayer = 0;
} }
public CSongReplay(string ChartPath, int player) public CSongReplay(string ChartPath, int player) {
{
string _chartFolder = Path.GetDirectoryName(ChartPath); string _chartFolder = Path.GetDirectoryName(ChartPath);
replayFolder = Path.Combine(_chartFolder, REPLAY_FOLDER_NAME); replayFolder = Path.Combine(_chartFolder, REPLAY_FOLDER_NAME);
try try {
{
Directory.CreateDirectory(replayFolder); Directory.CreateDirectory(replayFolder);
Console.WriteLine("Folder Path: " + replayFolder); Console.WriteLine("Folder Path: " + replayFolder);
} } catch (Exception ex) {
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message); Console.WriteLine("An error occurred: " + ex.Message);
} }
storedPlayer = player; storedPlayer = player;
} }
public void tRegisterInput(double timestamp, byte keypress) public void tRegisterInput(double timestamp, byte keypress) {
{
allInputs.Add(Tuple.Create(timestamp, keypress)); allInputs.Add(Tuple.Create(timestamp, keypress));
} }
#region [Dan methods] #region [Dan methods]
public void tDanRegisterSongCount(int songCount) public void tDanRegisterSongCount(int songCount) {
{
DanSongCount = songCount; DanSongCount = songCount;
IndividualGoodCount = new int[songCount]; IndividualGoodCount = new int[songCount];
IndividualOkCount = new int[songCount]; IndividualOkCount = new int[songCount];
@ -94,8 +76,7 @@ namespace TJAPlayer3
IndividualScore = new int[songCount]; IndividualScore = new int[songCount];
} }
public void tDanInputSongResults(int songNo) public void tDanInputSongResults(int songNo) {
{
if (songNo >= DanSongCount) return; if (songNo >= DanSongCount) return;
if (songNo < 0) return; if (songNo < 0) return;
IndividualGoodCount[songNo] = TJAPlayer3.stage演奏ドラム画面.n良[songNo]; IndividualGoodCount[songNo] = TJAPlayer3.stage演奏ドラム画面.n良[songNo];
@ -114,12 +95,10 @@ namespace TJAPlayer3
#region [Load methods] #region [Load methods]
private List<Tuple<double, byte>> ConvertByteArrayToTupleList(byte[] byteArray) private List<Tuple<double, byte>> ConvertByteArrayToTupleList(byte[] byteArray) {
{
List<Tuple<double, byte>> tupleList = new List<Tuple<double, byte>>(); List<Tuple<double, byte>> tupleList = new List<Tuple<double, byte>>();
for (int i = 0; i < byteArray.Length; i += sizeof(double) + sizeof(byte)) for (int i = 0; i < byteArray.Length; i += sizeof(double) + sizeof(byte)) {
{
double doubleValue = BitConverter.ToDouble(byteArray, i); double doubleValue = BitConverter.ToDouble(byteArray, i);
byte byteValue = byteArray[i + sizeof(double)]; byte byteValue = byteArray[i + sizeof(double)];
tupleList.Add(Tuple.Create(doubleValue, byteValue)); tupleList.Add(Tuple.Create(doubleValue, byteValue));
@ -128,14 +107,10 @@ namespace TJAPlayer3
return tupleList; return tupleList;
} }
public void tLoadReplayFile(string optkrFilePath) public void tLoadReplayFile(string optkrFilePath) {
{ try {
try using (FileStream fileStream = new FileStream(optkrFilePath, FileMode.Open)) {
{ using (BinaryReader reader = new BinaryReader(fileStream)) {
using (FileStream fileStream = new FileStream(optkrFilePath, FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(fileStream))
{
GameMode = reader.ReadByte(); GameMode = reader.ReadByte();
GameVersion = reader.ReadInt32(); GameVersion = reader.ReadInt32();
ChartChecksum = reader.ReadString(); ChartChecksum = reader.ReadString();
@ -152,8 +127,7 @@ namespace TJAPlayer3
ReachedFloor = reader.ReadInt32(); ReachedFloor = reader.ReadInt32();
RemainingLives = reader.ReadInt32(); RemainingLives = reader.ReadInt32();
DanSongCount = reader.ReadInt32(); DanSongCount = reader.ReadInt32();
for (int i = 0; i < DanSongCount; i++) for (int i = 0; i < DanSongCount; i++) {
{
IndividualGoodCount[i] = reader.ReadInt32(); IndividualGoodCount[i] = reader.ReadInt32();
IndividualOkCount[i] = reader.ReadInt32(); IndividualOkCount[i] = reader.ReadInt32();
IndividualBadCount[i] = reader.ReadInt32(); IndividualBadCount[i] = reader.ReadInt32();
@ -182,9 +156,7 @@ namespace TJAPlayer3
OnlineScoreID = reader.ReadInt64(); OnlineScoreID = reader.ReadInt64();
} }
} }
} } catch (Exception ex) {
catch (Exception ex)
{
} }
} }
@ -193,12 +165,10 @@ namespace TJAPlayer3
#region [Save methods] #region [Save methods]
private byte[] ConvertTupleListToByteArray(List<Tuple<double, byte>> tupleList) private byte[] ConvertTupleListToByteArray(List<Tuple<double, byte>> tupleList) {
{
List<byte> byteArray = new List<byte>(); List<byte> byteArray = new List<byte>();
foreach (var tuple in tupleList) foreach (var tuple in tupleList) {
{
byte[] doubleBytes = BitConverter.GetBytes(tuple.Item1); byte[] doubleBytes = BitConverter.GetBytes(tuple.Item1);
byteArray.AddRange(doubleBytes); byteArray.AddRange(doubleBytes);
byteArray.Add(tuple.Item2); byteArray.Add(tuple.Item2);
@ -207,16 +177,12 @@ namespace TJAPlayer3
return byteArray.ToArray(); return byteArray.ToArray();
} }
public void tSaveReplayFile() public void tSaveReplayFile() {
{
string _path = replayFolder + @"/Replay_" + ChartUniqueID + @"_" + PlayerName + @"_" + Timestamp.ToString() + @".optkr"; string _path = replayFolder + @"/Replay_" + ChartUniqueID + @"_" + PlayerName + @"_" + Timestamp.ToString() + @".optkr";
try try {
{ using (FileStream fileStream = new FileStream(_path, FileMode.Create)) {
using (FileStream fileStream = new FileStream(_path, FileMode.Create)) using (BinaryWriter writer = new BinaryWriter(fileStream)) {
{
using (BinaryWriter writer = new BinaryWriter(fileStream))
{
writer.Write(GameMode); writer.Write(GameMode);
writer.Write(GameVersion); writer.Write(GameVersion);
writer.Write(ChartChecksum); writer.Write(ChartChecksum);
@ -233,8 +199,7 @@ namespace TJAPlayer3
writer.Write(ReachedFloor); writer.Write(ReachedFloor);
writer.Write(RemainingLives); writer.Write(RemainingLives);
writer.Write(DanSongCount); writer.Write(DanSongCount);
for (int i = 0; i < DanSongCount; i++) for (int i = 0; i < DanSongCount; i++) {
{
writer.Write(IndividualGoodCount[i]); writer.Write(IndividualGoodCount[i]);
writer.Write(IndividualOkCount[i]); writer.Write(IndividualOkCount[i]);
writer.Write(IndividualBadCount[i]); writer.Write(IndividualBadCount[i]);
@ -261,21 +226,17 @@ namespace TJAPlayer3
writer.Write(OnlineScoreID); writer.Write(OnlineScoreID);
} }
} }
} } catch (Exception ex) {
catch (Exception ex)
{
} }
} }
public void tResultsRegisterReplayInformations(int Coins, int Clear, int SRank) public void tResultsRegisterReplayInformations(int Coins, int Clear, int SRank) {
{
// Actual player (Used for saved informations) // Actual player (Used for saved informations)
int actualPlayer = TJAPlayer3.GetActualPlayer(storedPlayer); int actualPlayer = TJAPlayer3.GetActualPlayer(storedPlayer);
// Game mode // Game mode
switch (TJAPlayer3.stageSongSelect.nChoosenSongDifficulty[0]) switch (TJAPlayer3.stageSongSelect.nChoosenSongDifficulty[0]) {
{
case (int)Difficulty.Dan: case (int)Difficulty.Dan:
GameMode = 1; GameMode = 1;
break; break;
@ -303,8 +264,7 @@ namespace TJAPlayer3
Score = TJAPlayer3.stage演奏ドラム画面.CChartScore[storedPlayer].nScore; Score = TJAPlayer3.stage演奏ドラム画面.CChartScore[storedPlayer].nScore;
CoinValue = (short)Coins; CoinValue = (short)Coins;
// Tower parameters // Tower parameters
if (GameMode == 2) if (GameMode == 2) {
{
ReachedFloor = CFloorManagement.LastRegisteredFloor; ReachedFloor = CFloorManagement.LastRegisteredFloor;
RemainingLives = CFloorManagement.CurrentNumberOfLives; RemainingLives = CFloorManagement.CurrentNumberOfLives;
} }

View File

@ -1,32 +1,21 @@
using System; using FDK;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FDK;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ class CVisualLogManager {
class CVisualLogManager public enum ELogCardType {
{
public enum ELogCardType
{
LogInfo, LogInfo,
LogWarning, LogWarning,
LogError LogError
} }
class LogCard class LogCard {
{ public LogCard(ELogCardType type, string message) {
public LogCard(ELogCardType type, string message)
{
lct = type; lct = type;
msg = message; msg = message;
timeSinceCreation = new CCounter(0, 10000, 1, TJAPlayer3.Timer); timeSinceCreation = new CCounter(0, 10000, 1, TJAPlayer3.Timer);
} }
public void Display(int screenPosition) public void Display(int screenPosition) {
{
timeSinceCreation.Tick(); timeSinceCreation.Tick();
// Display stuff here // Display stuff here
@ -37,8 +26,7 @@ namespace TJAPlayer3
TJAPlayer3.actTextConsole.tPrint(x, y, CTextConsole.EFontType.Cyan, msg); TJAPlayer3.actTextConsole.tPrint(x, y, CTextConsole.EFontType.Cyan, msg);
} }
public bool IsExpired() public bool IsExpired() {
{
return timeSinceCreation.IsEnded; return timeSinceCreation.IsEnded;
} }
@ -47,13 +35,11 @@ namespace TJAPlayer3
private string msg; private string msg;
} }
public void PushCard(ELogCardType lct, string msg) public void PushCard(ELogCardType lct, string msg) {
{
cards.Add(new LogCard(lct, msg)); cards.Add(new LogCard(lct, msg));
} }
public void Display() public void Display() {
{
for (int i = 0; i < cards.Count; i++) for (int i = 0; i < cards.Count; i++)
cards[i].Display(i); cards[i].Display(i);
cards.RemoveAll(card => card.IsExpired()); cards.RemoveAll(card => card.IsExpired());

View File

@ -1,28 +1,20 @@
using System.Collections.Generic; using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json;
namespace TJAPlayer3 namespace TJAPlayer3 {
{ class DBCDN : CSavableT<Dictionary<string, DBCDN.CDNData>> {
class DBCDN : CSavableT<Dictionary<string, DBCDN.CDNData>> public DBCDN() {
{
public DBCDN()
{
_fn = @$"{TJAPlayer3.strEXEのあるフォルダ}Databases{Path.DirectorySeparatorChar}CDN.json"; _fn = @$"{TJAPlayer3.strEXEのあるフォルダ}Databases{Path.DirectorySeparatorChar}CDN.json";
base.tDBInitSavable(); base.tDBInitSavable();
} }
#region [Auxiliary classes] #region [Auxiliary classes]
public class CDNHooks public class CDNHooks {
{
public string id = "id"; public string id = "id";
public Dictionary<string, string> title = new Dictionary<string, string>() public Dictionary<string, string> title = new Dictionary<string, string>() {
{
["default"] = "title", ["default"] = "title",
}; };
public Dictionary<string, string> subtitle = new Dictionary<string, string>() public Dictionary<string, string> subtitle = new Dictionary<string, string>() {
{
["default"] = "subtitle", ["default"] = "subtitle",
}; };
public string[] difficulties = { "easy", "normal", "hard", "extreme", "extra", "tower", "dan" }; public string[] difficulties = { "easy", "normal", "hard", "extreme", "extra", "tower", "dan" };
@ -30,28 +22,24 @@ namespace TJAPlayer3
public string updateDate = "updateDate"; public string updateDate = "updateDate";
public string creationDate = "creationDate"; public string creationDate = "creationDate";
public string uploadDate = "uploadDate"; public string uploadDate = "uploadDate";
public Dictionary<string, string> md5 = new Dictionary<string, string>() public Dictionary<string, string> md5 = new Dictionary<string, string>() {
{
["default"] = "md5", ["default"] = "md5",
}; };
public string genre = "genre"; public string genre = "genre";
public Dictionary<string, string> genreSub = new Dictionary<string, string>() public Dictionary<string, string> genreSub = new Dictionary<string, string>() {
{
["default"] = "name", ["default"] = "name",
}; };
public string charter = "charter"; public string charter = "charter";
} }
public class CDNData public class CDNData {
{
[JsonProperty("baseUrl")] [JsonProperty("baseUrl")]
public string BaseUrl; public string BaseUrl;
[JsonProperty("download")] [JsonProperty("download")]
public Dictionary<string, string> Download = new Dictionary<string, string>() public Dictionary<string, string> Download = new Dictionary<string, string>() {
{
["default"] = "download/", ["default"] = "download/",
}; };

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