Controller Support Update (#511)

* Update issue template to include .riq/.zip info (#483)

Co-authored-by: patata <patataofcourse@gmail.com>

* Pull release 1 (#484)

* Squashed commit of the following:

commit 2c628a4109
Merge: 4fde418c 6246a144
Author: minenice55 <star.elementa@gmail.com>
Date:   Wed Jun 14 01:23:31 2023 +0000

    Merge pull request #473 from minenice55/easings-fix

    Enum Parsing Fix

commit 6246a144b6
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 21:21:13 2023 -0400

    fix all parsing of enums, removed the "special case" for eases

    update to latest Jukebox

commit 4fde418c33
Merge: b9043582 50bc8765
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 21:39:15 2023 +0000

    Merge pull request #469 from minenice55/jukebox-update

    Jukebox Package Update

commit b90435825a
Merge: eec3c09a 73e9efd4
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 21:39:08 2023 +0000

    Merge pull request #458 from AstrlJelly/MiscAdditions_4

    Bug Fixes + Feature Additions

commit 73e9efd4b1
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 17:38:24 2023 -0400

    add "updater" for the old marching entity

commit b8d149743a
Merge: 4291333c eec3c09a
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 17:22:01 2023 -0400

    Merge branch 'release_1' into pr/458

commit 50bc876509
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 16:55:02 2023 -0400

    let play mode start if no song file is loaded

    fix issue with loading large audio files

commit eec3c09aa8
Merge: a0d70933 990af323
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 18:32:40 2023 +0000

    Merge pull request #471 from Rapandrasmus/FixWorkingDoughCurve

    Fixed weird curve stuff on game switch in working dough

commit 990af32379
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 19:24:13 2023 +0200

    Fixed weird curve stuff on game switch in working dough

commit a0d7093345
Merge: bdef3f95 3d19e75e
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 16:09:21 2023 +0000

    Merge pull request #470 from Rapandrasmus/WorkingDoughFixes

    Fixed small balls not working in working dough

commit 3d19e75e1a
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 18:07:13 2023 +0200

    Fixed small balls not working in working dough

commit bdef3f95c3
Merge: 8954b8c2 0bfafac6
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 14:56:58 2023 +0000

    Merge pull request #467 from Rapandrasmus/WorkingDoughRework

    Working Dough rework

commit 0bfafac6fe
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 16:13:08 2023 +0200

    modernised rockers pass turn

commit d770266d81
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 16:03:08 2023 +0200

    Rhythm tweezers pass turn now works like working dough

commit 2109c99a95
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 15:51:35 2023 +0200

    gandw on balls has been added

commit 785abf8486
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 14:59:56 2023 +0200

    Proper inactive handling now

commit 0a92b7bd69
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 13:52:15 2023 +0200

    OnSpawnBall reimplemented

commit a14aacc181
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 13:37:09 2023 +0200

    new sounds

commit 8b0544246d
Author: minenice55 <star.elementa@gmail.com>
Date:   Mon Jun 12 17:18:37 2023 -0400

    update Jukebox to latest version

    fixes for inferred entity loading

commit d8ff6744c0
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 21:36:57 2023 +0200

    ball transporter anims for pass turn

commit d283624b07
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 20:38:48 2023 +0200

    working dough converted, need to fix eveerything though

commit 5b3c59eabd
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 18:36:41 2023 +0200

    Converted everything to new curves and made playerballs handle themselves input-wise

commit dee630ea45
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 14:04:32 2023 +0200

    Some new curves

commit 31e8890190
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 12:03:21 2023 +0200

    Rockers can do it too now

commit 76bf6eefa6
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 11:58:31 2023 +0200

    You can now place inputs on top of pass turn for rhythm tweezers

commit 8954b8c269
Merge: 743e954e ce3e6f2d
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 15:55:40 2023 -0400

    Merge branch 'master' into release_1

commit 743e954e05
Merge: 5af551b3 8929cd56
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 19:53:47 2023 +0000

    Merge pull request #465 from minenice55/dont_infer_track

    Don't infer the track field when importing converted v0 riq coming from unknown origin

commit 8929cd5618
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 15:52:14 2023 -0400

    don't infer track when importing a v0 riq from another program

commit 5af551b32e
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 12:12:25 2023 -0400

    make base datamodels for special entity reading (#463)

    * make base datamodels for special entity reading

    * fix crop stomp breaking when no game switch or remix end is set

    * fix save shortcut

    fix loading charts with no music

commit 4291333cb0
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 23:00:30 2023 -0400

    add updater for marching orders turn

commit 82da6da741
Merge: 52a4d2b6 411b9a3c
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 22:36:10 2023 -0400

    Merge branch 'release_1' into pr/458

commit 411b9a3cb1
Merge: b6c222a9 afc665ed
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 22:30:32 2023 -0400

    Merge branch 'master' into release_1

commit b6c222a981
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 22:27:58 2023 -0400

    editor fixes (#459)

    * ditch loading dialog

    doesn't show up when it's supposed to

    * format song offset in editor

    * remove VorbisPlugin

    * Update Editor.cs

commit 52a4d2b65c
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 16:55:10 2023 -0400

    convert float to double and all that

commit aa8f531466
Merge: 242b076f afc665ed
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 16:01:44 2023 -0400

    Merge remote-tracking branch 'upstream/master' into MiscAdditions_4

commit 242b076f09
Merge: db653d5a 2b0ced2f
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 15:21:22 2023 -0400

    Merge remote-tracking branch 'upstream/master' into MiscAdditions_4

commit db653d5a52
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 15:18:45 2023 -0400

    a lot

    * munchy monk input + mustache fixes
    * fork lifter and pajama party bopping
    * meat grinder miss bop fix
    * cloud monkey Real
    * marching orders Go! was broken
    * force march doesn't break when it's too early from a game switch
    * you can use the March! block without the marching now

commit 50a1b7bcdb
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 15:13:29 2023 -0400

    Integration of Jukebox Library (#451)

    * add Jukebox library

    todo:
    - saving / loading of new format
    - inferrence of unknown data like past versions
    - move the temporary float casts to proper use of double
    - make sound related functions take double for timing
    - inform people that the Jukebox sound player was renamed to SoundByte lol

    * make sound, input scheduling, and super curve use double precision

    * successfully load charts

    * editor works again

    v1 riqs can be saved and loaded

    * first tempo and volume markers are unmovable

    fix loading of charts' easing values

    * use gsync / freesync

    * update Jukebox refs to SoundByte

    * game events use double part 1

    Air Rally - Glee Club converted

    * don't load song if chart load fails

    * finish conversion of all minigames

    * remove editor waveform toggle

    * timeline now respects added song offset length

    clear cache files on app close
    prepped notes for dsp sync

    * update timeline length when offset changed

    * update to latest Jukebox

    * make error panel object in global game manager

    * improve conductor music scheduling

    * added error message box

    fix first game events sometimes not playing

* Squashed commit of the following:

commit 0d25221b71
Merge: 5869d212 9163085d
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 17 16:40:52 2023 +0000

    Merge pull request #478 from evdial/working-dough

    Working Dough Tweaks

commit 9163085d7a
Merge: 6592a5f2 5869d212
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 17 12:40:06 2023 -0400

    Merge branch 'release_1' into pr/478

commit 5869d212bc
Author: patata <patataofcourse@gmail.com>
Date:   Sat Jun 17 17:20:15 2023 +0200

    Update issue template to include .riq/.zip info

commit 6592a5f202
Author: ev <85412919+evdial@users.noreply.github.com>
Date:   Thu Jun 15 15:05:07 2023 -0400

    assbuns

commit 11a4c090a1
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Thu Jun 15 20:56:40 2023 +0200

    made small idle not crazy

commit 45e7d81b0f
Author: ev <85412919+evdial@users.noreply.github.com>
Date:   Thu Jun 15 14:33:57 2023 -0400

    fsd

commit 47efa3e4f3
Author: ev <85412919+evdial@users.noreply.github.com>
Date:   Thu Jun 15 14:16:38 2023 -0400

    anim

commit c6fb8880a0
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Thu Jun 15 20:13:11 2023 +0200

    Fixed stuff also scaled now yippee

commit 16ce508b03
Author: ev <85412919+evdial@users.noreply.github.com>
Date:   Thu Jun 15 13:50:10 2023 -0400

    many

commit 37b80a33c7
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 21:28:21 2023 -0400

    Squashed commit of the following: (#474)

    commit 2c628a4109
    Merge: 4fde418c 6246a144
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Wed Jun 14 01:23:31 2023 +0000

        Merge pull request #473 from minenice55/easings-fix

        Enum Parsing Fix

    commit 6246a144b6
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 21:21:13 2023 -0400

        fix all parsing of enums, removed the "special case" for eases

        update to latest Jukebox

    commit 4fde418c33
    Merge: b9043582 50bc8765
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 21:39:15 2023 +0000

        Merge pull request #469 from minenice55/jukebox-update

        Jukebox Package Update

    commit b90435825a
    Merge: eec3c09a 73e9efd4
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 21:39:08 2023 +0000

        Merge pull request #458 from AstrlJelly/MiscAdditions_4

        Bug Fixes + Feature Additions

    commit 73e9efd4b1
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 17:38:24 2023 -0400

        add "updater" for the old marching entity

    commit b8d149743a
    Merge: 4291333c eec3c09a
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 17:22:01 2023 -0400

        Merge branch 'release_1' into pr/458

    commit 50bc876509
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 16:55:02 2023 -0400

        let play mode start if no song file is loaded

        fix issue with loading large audio files

    commit eec3c09aa8
    Merge: a0d70933 990af323
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 18:32:40 2023 +0000

        Merge pull request #471 from Rapandrasmus/FixWorkingDoughCurve

        Fixed weird curve stuff on game switch in working dough

    commit 990af32379
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 19:24:13 2023 +0200

        Fixed weird curve stuff on game switch in working dough

    commit a0d7093345
    Merge: bdef3f95 3d19e75e
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 16:09:21 2023 +0000

        Merge pull request #470 from Rapandrasmus/WorkingDoughFixes

        Fixed small balls not working in working dough

    commit 3d19e75e1a
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 18:07:13 2023 +0200

        Fixed small balls not working in working dough

    commit bdef3f95c3
    Merge: 8954b8c2 0bfafac6
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Tue Jun 13 14:56:58 2023 +0000

        Merge pull request #467 from Rapandrasmus/WorkingDoughRework

        Working Dough rework

    commit 0bfafac6fe
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 16:13:08 2023 +0200

        modernised rockers pass turn

    commit d770266d81
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 16:03:08 2023 +0200

        Rhythm tweezers pass turn now works like working dough

    commit 2109c99a95
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 15:51:35 2023 +0200

        gandw on balls has been added

    commit 785abf8486
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 14:59:56 2023 +0200

        Proper inactive handling now

    commit 0a92b7bd69
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 13:52:15 2023 +0200

        OnSpawnBall reimplemented

    commit a14aacc181
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Tue Jun 13 13:37:09 2023 +0200

        new sounds

    commit 8b0544246d
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Mon Jun 12 17:18:37 2023 -0400

        update Jukebox to latest version

        fixes for inferred entity loading

    commit d8ff6744c0
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Mon Jun 12 21:36:57 2023 +0200

        ball transporter anims for pass turn

    commit d283624b07
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Mon Jun 12 20:38:48 2023 +0200

        working dough converted, need to fix eveerything though

    commit 5b3c59eabd
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Mon Jun 12 18:36:41 2023 +0200

        Converted everything to new curves and made playerballs handle themselves input-wise

    commit dee630ea45
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Mon Jun 12 14:04:32 2023 +0200

        Some new curves

    commit 31e8890190
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Mon Jun 12 12:03:21 2023 +0200

        Rockers can do it too now

    commit 76bf6eefa6
    Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
    Date:   Mon Jun 12 11:58:31 2023 +0200

        You can now place inputs on top of pass turn for rhythm tweezers

    commit 8954b8c269
    Merge: 743e954e ce3e6f2d
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sun Jun 11 15:55:40 2023 -0400

        Merge branch 'master' into release_1

    commit 743e954e05
    Merge: 5af551b3 8929cd56
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sun Jun 11 19:53:47 2023 +0000

        Merge pull request #465 from minenice55/dont_infer_track

        Don't infer the track field when importing converted v0 riq coming from unknown origin

    commit 8929cd5618
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sun Jun 11 15:52:14 2023 -0400

        don't infer track when importing a v0 riq from another program

    commit 5af551b32e
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sun Jun 11 12:12:25 2023 -0400

        make base datamodels for special entity reading (#463)

        * make base datamodels for special entity reading

        * fix crop stomp breaking when no game switch or remix end is set

        * fix save shortcut

        fix loading charts with no music

    commit 4291333cb0
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sat Jun 10 23:00:30 2023 -0400

        add updater for marching orders turn

    commit 82da6da741
    Merge: 52a4d2b6 411b9a3c
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sat Jun 10 22:36:10 2023 -0400

        Merge branch 'release_1' into pr/458

    commit 411b9a3cb1
    Merge: b6c222a9 afc665ed
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sat Jun 10 22:30:32 2023 -0400

        Merge branch 'master' into release_1

    commit b6c222a981
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sat Jun 10 22:27:58 2023 -0400

        editor fixes (#459)

        * ditch loading dialog

        doesn't show up when it's supposed to

        * format song offset in editor

        * remove VorbisPlugin

        * Update Editor.cs

    commit 52a4d2b65c
    Author: AstrlJelly <bdlawson115@gmail.com>
    Date:   Sat Jun 10 16:55:10 2023 -0400

        convert float to double and all that

    commit aa8f531466
    Merge: 242b076f afc665ed
    Author: AstrlJelly <bdlawson115@gmail.com>
    Date:   Sat Jun 10 16:01:44 2023 -0400

        Merge remote-tracking branch 'upstream/master' into MiscAdditions_4

    commit 242b076f09
    Merge: db653d5a 2b0ced2f
    Author: AstrlJelly <bdlawson115@gmail.com>
    Date:   Sat Jun 10 15:21:22 2023 -0400

        Merge remote-tracking branch 'upstream/master' into MiscAdditions_4

    commit db653d5a52
    Author: AstrlJelly <bdlawson115@gmail.com>
    Date:   Sat Jun 10 15:18:45 2023 -0400

        a lot

        * munchy monk input + mustache fixes
        * fork lifter and pajama party bopping
        * meat grinder miss bop fix
        * cloud monkey Real
        * marching orders Go! was broken
        * force march doesn't break when it's too early from a game switch
        * you can use the March! block without the marching now

    commit 50a1b7bcdb
    Author: minenice55 <star.elementa@gmail.com>
    Date:   Sat Jun 10 15:13:29 2023 -0400

        Integration of Jukebox Library (#451)

        * add Jukebox library

        todo:
        - saving / loading of new format
        - inferrence of unknown data like past versions
        - move the temporary float casts to proper use of double
        - make sound related functions take double for timing
        - inform people that the Jukebox sound player was renamed to SoundByte lol

        * make sound, input scheduling, and super curve use double precision

        * successfully load charts

        * editor works again

        v1 riqs can be saved and loaded

        * first tempo and volume markers are unmovable

        fix loading of charts' easing values

        * use gsync / freesync

        * update Jukebox refs to SoundByte

        * game events use double part 1

        Air Rally - Glee Club converted

        * don't load song if chart load fails

        * finish conversion of all minigames

        * remove editor waveform toggle

        * timeline now respects added song offset length

        clear cache files on app close
        prepped notes for dsp sync

        * update timeline length when offset changed

        * update to latest Jukebox

        * make error panel object in global game manager

        * improve conductor music scheduling

        * added error message box

        fix first game events sometimes not playing

commit 2c628a4109
Merge: 4fde418c 6246a144
Author: minenice55 <star.elementa@gmail.com>
Date:   Wed Jun 14 01:23:31 2023 +0000

    Merge pull request #473 from minenice55/easings-fix

    Enum Parsing Fix

commit 6246a144b6
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 21:21:13 2023 -0400

    fix all parsing of enums, removed the "special case" for eases

    update to latest Jukebox

commit 4fde418c33
Merge: b9043582 50bc8765
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 21:39:15 2023 +0000

    Merge pull request #469 from minenice55/jukebox-update

    Jukebox Package Update

commit b90435825a
Merge: eec3c09a 73e9efd4
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 21:39:08 2023 +0000

    Merge pull request #458 from AstrlJelly/MiscAdditions_4

    Bug Fixes + Feature Additions

commit 73e9efd4b1
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 17:38:24 2023 -0400

    add "updater" for the old marching entity

commit b8d149743a
Merge: 4291333c eec3c09a
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 17:22:01 2023 -0400

    Merge branch 'release_1' into pr/458

commit 50bc876509
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 16:55:02 2023 -0400

    let play mode start if no song file is loaded

    fix issue with loading large audio files

commit eec3c09aa8
Merge: a0d70933 990af323
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 18:32:40 2023 +0000

    Merge pull request #471 from Rapandrasmus/FixWorkingDoughCurve

    Fixed weird curve stuff on game switch in working dough

commit 990af32379
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 19:24:13 2023 +0200

    Fixed weird curve stuff on game switch in working dough

commit a0d7093345
Merge: bdef3f95 3d19e75e
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 16:09:21 2023 +0000

    Merge pull request #470 from Rapandrasmus/WorkingDoughFixes

    Fixed small balls not working in working dough

commit 3d19e75e1a
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 18:07:13 2023 +0200

    Fixed small balls not working in working dough

commit bdef3f95c3
Merge: 8954b8c2 0bfafac6
Author: minenice55 <star.elementa@gmail.com>
Date:   Tue Jun 13 14:56:58 2023 +0000

    Merge pull request #467 from Rapandrasmus/WorkingDoughRework

    Working Dough rework

commit 0bfafac6fe
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 16:13:08 2023 +0200

    modernised rockers pass turn

commit d770266d81
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 16:03:08 2023 +0200

    Rhythm tweezers pass turn now works like working dough

commit 2109c99a95
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 15:51:35 2023 +0200

    gandw on balls has been added

commit 785abf8486
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 14:59:56 2023 +0200

    Proper inactive handling now

commit 0a92b7bd69
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 13:52:15 2023 +0200

    OnSpawnBall reimplemented

commit a14aacc181
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Tue Jun 13 13:37:09 2023 +0200

    new sounds

commit 8b0544246d
Author: minenice55 <star.elementa@gmail.com>
Date:   Mon Jun 12 17:18:37 2023 -0400

    update Jukebox to latest version

    fixes for inferred entity loading

commit d8ff6744c0
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 21:36:57 2023 +0200

    ball transporter anims for pass turn

commit d283624b07
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 20:38:48 2023 +0200

    working dough converted, need to fix eveerything though

commit 5b3c59eabd
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 18:36:41 2023 +0200

    Converted everything to new curves and made playerballs handle themselves input-wise

commit dee630ea45
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 14:04:32 2023 +0200

    Some new curves

commit 31e8890190
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 12:03:21 2023 +0200

    Rockers can do it too now

commit 76bf6eefa6
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Mon Jun 12 11:58:31 2023 +0200

    You can now place inputs on top of pass turn for rhythm tweezers

commit 8954b8c269
Merge: 743e954e ce3e6f2d
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 15:55:40 2023 -0400

    Merge branch 'master' into release_1

commit 743e954e05
Merge: 5af551b3 8929cd56
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 19:53:47 2023 +0000

    Merge pull request #465 from minenice55/dont_infer_track

    Don't infer the track field when importing converted v0 riq coming from unknown origin

commit 8929cd5618
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 15:52:14 2023 -0400

    don't infer track when importing a v0 riq from another program

commit 5af551b32e
Author: minenice55 <star.elementa@gmail.com>
Date:   Sun Jun 11 12:12:25 2023 -0400

    make base datamodels for special entity reading (#463)

    * make base datamodels for special entity reading

    * fix crop stomp breaking when no game switch or remix end is set

    * fix save shortcut

    fix loading charts with no music

commit 4291333cb0
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 23:00:30 2023 -0400

    add updater for marching orders turn

commit 82da6da741
Merge: 52a4d2b6 411b9a3c
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 22:36:10 2023 -0400

    Merge branch 'release_1' into pr/458

commit 411b9a3cb1
Merge: b6c222a9 afc665ed
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 22:30:32 2023 -0400

    Merge branch 'master' into release_1

commit b6c222a981
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 22:27:58 2023 -0400

    editor fixes (#459)

    * ditch loading dialog

    doesn't show up when it's supposed to

    * format song offset in editor

    * remove VorbisPlugin

    * Update Editor.cs

commit 52a4d2b65c
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 16:55:10 2023 -0400

    convert float to double and all that

commit aa8f531466
Merge: 242b076f afc665ed
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 16:01:44 2023 -0400

    Merge remote-tracking branch 'upstream/master' into MiscAdditions_4

commit 242b076f09
Merge: db653d5a 2b0ced2f
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 15:21:22 2023 -0400

    Merge remote-tracking branch 'upstream/master' into MiscAdditions_4

commit db653d5a52
Author: AstrlJelly <bdlawson115@gmail.com>
Date:   Sat Jun 10 15:18:45 2023 -0400

    a lot

    * munchy monk input + mustache fixes
    * fork lifter and pajama party bopping
    * meat grinder miss bop fix
    * cloud monkey Real
    * marching orders Go! was broken
    * force march doesn't break when it's too early from a game switch
    * you can use the March! block without the marching now

commit 50a1b7bcdb
Author: minenice55 <star.elementa@gmail.com>
Date:   Sat Jun 10 15:13:29 2023 -0400

    Integration of Jukebox Library (#451)

    * add Jukebox library

    todo:
    - saving / loading of new format
    - inferrence of unknown data like past versions
    - move the temporary float casts to proper use of double
    - make sound related functions take double for timing
    - inform people that the Jukebox sound player was renamed to SoundByte lol

    * make sound, input scheduling, and super curve use double precision

    * successfully load charts

    * editor works again

    v1 riqs can be saved and loaded

    * first tempo and volume markers are unmovable

    fix loading of charts' easing values

    * use gsync / freesync

    * update Jukebox refs to SoundByte

    * game events use double part 1

    Air Rally - Glee Club converted

    * don't load song if chart load fails

    * finish conversion of all minigames

    * remove editor waveform toggle

    * timeline now respects added song offset length

    clear cache files on app close
    prepped notes for dsp sync

    * update timeline length when offset changed

    * update to latest Jukebox

    * make error panel object in global game manager

    * improve conductor music scheduling

    * added error message box

    fix first game events sometimes not playing

* Editor Additions (#479)

* favoriting and pick block

favoriting needs to not break after previewing (maybe make it persistent in the settings file?)
pick block needs to pick the icon, too. and preferably scroll to it as well

* final star anim + automatic icon game switching

before i make any more changes im making a checkpoint here cuz i know it works
* i want to add a way to specify which event SwitchGame() will switch to (because that's a cool feature for pick block)
* i'll have to figure out how to auto scroll to the game when the icon is selected
* the star now fully works, even between preview switches 👍

* fix the rest of the stuff

the event name gets colored correctly and hidden games are skipped over, but still loaded.
also i built mm ass buns

* tweaks + zoom and sorting

this stuff will be in the pr desc so it doesn't matter

* oop one more thing

* icons look better now :D

mipmaps to the rescue

* double date fix

* Merge pull request #486 from RHeavenStudio/actions_rework

Rework GitHub Actions and build script

* add ab meta to gitignore (#489)

* Sound Scheduling Improvements (#491)

* port conductor adjustments

* scheduled sounds prebake

* allow aiff files to be imported

add vbr mp3 warning to readme

* improve wording

* separate controller initializers

update JSL

* set initial player on joyshocks

* loaders have their own namespace

* port PlayerActionEvent IsHittable

rename timing margin values
simplify some player action event logic

* CNR API Internal Rework (#488)

* Prep stuff

* Tweezers now spawn in

* Started converting tweezers

* I hate <1 beat intervals

* Actually nvm

* fixed a bug

* You can chain intervals now, stack them if you really wanted

* Pass turn checks if crhandlerinstance exists

* Fixed hairs being deleted by onion switch

* Rockers rerewritten

* working dough rerewritten

* Revert "Merge branch 'master' into new-controller-support"

This reverts commit 2bf4c14f68a6f4f512504feb21d0ea5242e4a0fc, reversing
changes made to b9c5fd4581750de0e4aefffa9b4a2ab9564971d1.

* Squashed commit of the following:

commit 00c58d5487
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Wed Jun 28 06:51:53 2023 +0200

    CNR API Internal Rework (#488)

    * Prep stuff

    * Tweezers now spawn in

    * Started converting tweezers

    * I hate <1 beat intervals

    * Actually nvm

    * fixed a bug

    * You can chain intervals now, stack them if you really wanted

    * Pass turn checks if crhandlerinstance exists

    * Fixed hairs being deleted by onion switch

    * Rockers rerewritten

    * working dough rerewritten

* update packages for mac

* assign plugin platforms

* JSL polling via event

* JSL timestamped input

* initial prep for rebinding controls

rename some bindings
properly expose newer JSL stuff

* update JSL plugin

support for DualSense Edge (treated as DualSense)

* methods for working on controller binds

doc parts of the InputController class

* show bindings in settings menu

* CNR API Internal Rework (#488)

* Prep stuff

* Tweezers now spawn in

* Started converting tweezers

* I hate <1 beat intervals

* Actually nvm

* fixed a bug

* You can chain intervals now, stack them if you really wanted

* Pass turn checks if crhandlerinstance exists

* Fixed hairs being deleted by onion switch

* Rockers rerewritten

* working dough rerewritten

* Games fixes/reworks patch (#501)

* ghosts are scaled now

* Lockstep fully reworked

* mr. bach has been implemented

* Space dance fixes

* oops

* Tap trial rework part 1

* tap trial rework part 2

* oopsie

* Gramps Talk Update

* Space Dance Voice Offsets

* Giraffe done! (Except miss anim)

* bg is not showing up for some reason

* bg not rendering fixed + giraffe fixed

* scrolling done

* fixed space dance and space soccer bg scrolls

* fixed rockers bugs

* adjustment

* fixed el inaccuracies

* particle fix

* changed pitch and volume of monkey tap

* miss anim

* megamix face for girl

* Proper miss anim implementation

* Added force stepping event

* miss anim fix

---------

Co-authored-by: saladplainzone <chocolate2890mail@gmail.com>
Co-authored-by: ev <85412919+evdial@users.noreply.github.com>

* Revert "Merge branch 'master' into new-controller-support"

This reverts commit 3f0edd8657074fea4ff93a91b3822ba10f9e98c1, reversing
changes made to 804d7fad3b6498bc80da9646115a1d1e30254961.

* Squashed commit of the following:

commit c00b6f46c3
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Thu Jul 13 02:35:47 2023 +0200

    Games fixes/reworks patch (#501)

    * ghosts are scaled now

    * Lockstep fully reworked

    * mr. bach has been implemented

    * Space dance fixes

    * oops

    * Tap trial rework part 1

    * tap trial rework part 2

    * oopsie

    * Gramps Talk Update

    * Space Dance Voice Offsets

    * Giraffe done! (Except miss anim)

    * bg is not showing up for some reason

    * bg not rendering fixed + giraffe fixed

    * scrolling done

    * fixed space dance and space soccer bg scrolls

    * fixed rockers bugs

    * adjustment

    * fixed el inaccuracies

    * particle fix

    * changed pitch and volume of monkey tap

    * miss anim

    * megamix face for girl

    * Proper miss anim implementation

    * Added force stepping event

    * miss anim fix

    ---------

    Co-authored-by: saladplainzone <chocolate2890mail@gmail.com>
    Co-authored-by: ev <85412919+evdial@users.noreply.github.com>

commit 94d62309fb
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Wed Jul 12 18:49:32 2023 +0200

    Second Contact Rework + Small CNR API changes (#500)

    * Just need to rewrite how player text works

    * text almost fixed

    * text is now fixed

    * ellipses added

    * Removed cnr api from rockers and working dough

    * oops

commit 00c58d5487
Author: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Date:   Wed Jun 28 06:51:53 2023 +0200

    CNR API Internal Rework (#488)

    * Prep stuff

    * Tweezers now spawn in

    * Started converting tweezers

    * I hate <1 beat intervals

    * Actually nvm

    * fixed a bug

    * You can chain intervals now, stack them if you really wanted

    * Pass turn checks if crhandlerinstance exists

    * Fixed hairs being deleted by onion switch

    * Rockers rerewritten

    * working dough rerewritten

* working controller remapping

* better differentiate between physical buttons and virtual actions

fix bugs with single joy-con

* add 90hz input debouncing

* fix display issue in joycon pairing UI

* start fixing issues with split pair

todo: make the con read the paired controller as well

* saving/loading custom binds

* fix issues with joy-con pairs

fix binding reset issue with joyshocks

* apply same fix to kb

swap kb east and south action binds

* implement IsHittable in places that need it as examples

* pj party needed IsHittable as well

---------

Co-authored-by: patata <patataofcourse@gmail.com>
Co-authored-by: AstrlJelly <bdlawson115@gmail.com>
Co-authored-by: Rapandrasmus <78219215+Rapandrasmus@users.noreply.github.com>
Co-authored-by: saladplainzone <chocolate2890mail@gmail.com>
Co-authored-by: ev <85412919+evdial@users.noreply.github.com>
This commit is contained in:
minenice55 2023-07-30 22:32:11 -04:00 committed by GitHub
parent 84aad376cb
commit 154f78179e
47 changed files with 7280 additions and 1323 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,63 @@
fileFormatVersion: 2
guid: ba4f73ad56fdd254c9406111c6702f84
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude Win: 0
Exclude Win64: 0
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 1
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: x86_64
userData:
assetBundleName:
assetBundleVariant:

View file

@ -53,7 +53,7 @@ PluginImporter:
second: second:
enabled: 1 enabled: 1
settings: settings:
CPU: AnyCPU CPU: x86_64
- first: - first:
Standalone: Win Standalone: Win
second: second:

View file

@ -11,6 +11,16 @@ PluginImporter:
isExplicitlyReferenced: 0 isExplicitlyReferenced: 0
validateReferences: 1 validateReferences: 1
platformData: platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 1
Exclude Win: 0
Exclude Win64: 0
- first: - first:
Any: Any:
second: second:
@ -19,10 +29,11 @@ PluginImporter:
- first: - first:
Editor: Editor Editor: Editor
second: second:
enabled: 0 enabled: 1
settings: settings:
CPU: x86_64 CPU: x86_64
DefaultValueInitialized: true DefaultValueInitialized: true
OS: AnyOS
- first: - first:
Standalone: Linux64 Standalone: Linux64
second: second:
@ -34,11 +45,11 @@ PluginImporter:
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: x86_64 CPU: None
- first: - first:
Standalone: Win Standalone: Win
second: second:
enabled: 0 enabled: 1
settings: settings:
CPU: None CPU: None
- first: - first:

View file

@ -76,28 +76,50 @@ public static class JSL
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct MOTION_STATE { public struct MOTION_STATE {
float quatW; public float quatW;
float quatX; public float quatX;
float quatY; public float quatY;
float quatZ; public float quatZ;
float accelX; public float accelX;
float accelY; public float accelY;
float accelZ; public float accelZ;
float gravX; public float gravX;
float gravY; public float gravY;
float gravZ; public float gravZ;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct TOUCH_STATE { public struct TOUCH_STATE {
int t0Id; public int t0Id;
int t1Id; public int t1Id;
bool t0Down; public bool t0Down;
bool t1Down; public bool t1Down;
float t0X; public float t0X;
float t0Y; public float t0Y;
float t1X; public float t1X;
float t1Y; public float t1Y;
}
[StructLayout(LayoutKind.Sequential)]
public struct JSL_AUTO_CALIBRATION {
public float confidence;
public bool autoCalibrationEnabled;
public bool isSteady;
}
[StructLayout(LayoutKind.Sequential)]
public struct JSL_SETTINGS {
public int gyroSpace;
public int bodyColour;
public int lGripColour;
public int rGripColour;
public int buttonColour;
public int playerNumber;
public int controllerType;
public int splitType;
public bool isCalibrating;
public bool autoCalibrationEnabled;
public bool isConnected;
} }
public delegate void EventCallback(int handle, JOY_SHOCK_STATE state, JOY_SHOCK_STATE lastState, public delegate void EventCallback(int handle, JOY_SHOCK_STATE state, JOY_SHOCK_STATE lastState,
@ -105,12 +127,17 @@ public static class JSL
public delegate void TouchCallback(int handle, TOUCH_STATE state, TOUCH_STATE lastState, float deltaTime); public delegate void TouchCallback(int handle, TOUCH_STATE state, TOUCH_STATE lastState, float deltaTime);
public delegate void ConnectionCallback(int handle);
public delegate void DeconnectionCallback(int handle, bool isConnected);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern int JslConnectDevices(); public static extern int JslConnectDevices();
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern int JslGetConnectedDeviceHandles(int[] deviceHandleArray, int size); public static extern int JslGetConnectedDeviceHandles(int[] deviceHandleArray, int size);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern void JslDisconnectAndDisposeAll(); public static extern void JslDisconnectAndDisposeAll();
[DllImport("JoyShockLibrary")]
public static extern bool JslStillConnected(int deviceId);
[DllImport("JoyShockLibrary", CallingConvention = CallingConvention.Cdecl)] [DllImport("JoyShockLibrary", CallingConvention = CallingConvention.Cdecl)]
public static extern JOY_SHOCK_STATE JslGetSimpleState(int deviceId); public static extern JOY_SHOCK_STATE JslGetSimpleState(int deviceId);
@ -121,12 +148,17 @@ public static class JSL
[DllImport("JoyShockLibrary", CallingConvention = CallingConvention.Cdecl)] [DllImport("JoyShockLibrary", CallingConvention = CallingConvention.Cdecl)]
public static extern TOUCH_STATE JslGetTouchState(int deviceId); public static extern TOUCH_STATE JslGetTouchState(int deviceId);
[DllImport("JoyShockLibrary")]
public static extern void JslSetGyroSpace(int deviceId, int gyroSpace);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern float JslGetStickStep(int deviceId); public static extern float JslGetStickStep(int deviceId);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern float JslGetTriggerStep(int deviceId); public static extern float JslGetTriggerStep(int deviceId);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern float JslGetPollRate(int deviceId); public static extern float JslGetPollRate(int deviceId);
[DllImport("JoyShockLibrary")]
public static extern float JslGetTimeSinceLastUpdate(int deviceId);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern float JslGetTouchId(int deviceId, bool secondTouch = false); public static extern float JslGetTouchId(int deviceId, bool secondTouch = false);
@ -147,12 +179,23 @@ public static class JSL
public static extern void JslGetCalibrationOffset(int deviceId, ref float xOffset, ref float yOffset, ref float zOffset); public static extern void JslGetCalibrationOffset(int deviceId, ref float xOffset, ref float yOffset, ref float zOffset);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern void JslGetCalibrationOffset(int deviceId, float xOffset, float yOffset, float zOffset); public static extern void JslGetCalibrationOffset(int deviceId, float xOffset, float yOffset, float zOffset);
[DllImport("JoyShockLibrary")]
public static extern JSL_AUTO_CALIBRATION JslGetAutoCalibrationStatus(int deviceId);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern void JslSetCallback(EventCallback callback); public static extern void JslSetCallback(EventCallback callback);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern void JslSetTouchCallback(TouchCallback callback); public static extern void JslSetTouchCallback(TouchCallback callback);
// this function will get called for each device when it is newly connected
[DllImport("JoyShockLibrary")]
public static extern void JslSetConnectCallback(ConnectionCallback callback);
// this function will get called for each device when it is disconnected
[DllImport("JoyShockLibrary")]
public static extern void JslSetDisconnectCallback(DeconnectionCallback callback);
// super-getter for reading a whole lot of state at once
[DllImport("JoyShockLibrary")]
public static extern JSL_SETTINGS JslGetControllerInfoAndSettings(int deviceId);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]
public static extern int JslGetControllerType(int deviceId); public static extern int JslGetControllerType(int deviceId);
[DllImport("JoyShockLibrary")] [DllImport("JoyShockLibrary")]

View file

@ -70,58 +70,79 @@
#define JSOFFSET_SR 19 #define JSOFFSET_SR 19
// PS5 Player maps for the DS Player Lightbar // PS5 Player maps for the DS Player Lightbar
#define DS5_PLAYER_1 = 4 #define DS5_PLAYER_1 4
#define DS5_PLAYER_2 = 10 #define DS5_PLAYER_2 10
#define DS5_PLAYER_3 = 21 #define DS5_PLAYER_3 21
#define DS5_PLAYER_4 = 27 #define DS5_PLAYER_4 27
#define DS5_PLAYER_5 = 31 #define DS5_PLAYER_5 31
typedef struct JOY_SHOCK_STATE { typedef struct JOY_SHOCK_STATE {
int buttons; int buttons = 0;
float lTrigger; float lTrigger = 0.f;
float rTrigger; float rTrigger = 0.f;
float stickLX; float stickLX = 0.f;
float stickLY; float stickLY = 0.f;
float stickRX; float stickRX = 0.f;
float stickRY; float stickRY = 0.f;
} JOY_SHOCK_STATE; } JOY_SHOCK_STATE;
typedef struct IMU_STATE { typedef struct IMU_STATE {
float accelX; float accelX = 0.f;
float accelY; float accelY = 0.f;
float accelZ; float accelZ = 0.f;
float gyroX; float gyroX = 0.f;
float gyroY; float gyroY = 0.f;
float gyroZ; float gyroZ = 0.f;
} IMU_STATE; } IMU_STATE;
typedef struct MOTION_STATE { typedef struct MOTION_STATE {
float quatW; float quatW = 0.f;
float quatX; float quatX = 0.f;
float quatY; float quatY = 0.f;
float quatZ; float quatZ = 0.f;
float accelX; float accelX = 0.f;
float accelY; float accelY = 0.f;
float accelZ; float accelZ = 0.f;
float gravX; float gravX = 0.f;
float gravY; float gravY = 0.f;
float gravZ; float gravZ = 0.f;
} MOTION_STATE; } MOTION_STATE;
typedef struct TOUCH_STATE { typedef struct TOUCH_STATE {
int t0Id; int t0Id = 0;
int t1Id; int t1Id = 0;
bool t0Down; bool t0Down = false;
bool t1Down; bool t1Down = false;
float t0X; float t0X = 0.f;
float t0Y; float t0Y = 0.f;
float t1X; float t1X = 0.f;
float t1Y; float t1Y = 0.f;
} TOUCH_STATE; } TOUCH_STATE;
typedef struct JSL_AUTO_CALIBRATION {
float confidence = 0.f;
bool autoCalibrationEnabled = false;
bool isSteady = false;
} JSL_AUTO_CALIBRATION;
typedef struct JSL_SETTINGS {
int gyroSpace = 0;
int bodyColour = 0;
int lGripColour = 0;
int rGripColour = 0;
int buttonColour = 0;
int playerNumber = 0;
int controllerType = 0;
int splitType = 0;
bool isCalibrating = false;
bool autoCalibrationEnabled = false;
bool isConnected = false;
} JSL_SETTINGS;
extern "C" JOY_SHOCK_API int JslConnectDevices(); extern "C" JOY_SHOCK_API int JslConnectDevices();
extern "C" JOY_SHOCK_API int JslGetConnectedDeviceHandles(int* deviceHandleArray, int size); extern "C" JOY_SHOCK_API int JslGetConnectedDeviceHandles(int* deviceHandleArray, int size);
extern "C" JOY_SHOCK_API void JslDisconnectAndDisposeAll(); extern "C" JOY_SHOCK_API void JslDisconnectAndDisposeAll();
extern "C" JOY_SHOCK_API bool JslStillConnected(int deviceId);
// get buttons as bits in the following order, using North South East West to name face buttons to avoid ambiguity between Xbox and Nintendo layouts: // get buttons as bits in the following order, using North South East West to name face buttons to avoid ambiguity between Xbox and Nintendo layouts:
// 0x00001: up // 0x00001: up
@ -169,6 +190,15 @@ extern "C" JOY_SHOCK_API float JslGetGyroX(int deviceId);
extern "C" JOY_SHOCK_API float JslGetGyroY(int deviceId); extern "C" JOY_SHOCK_API float JslGetGyroY(int deviceId);
extern "C" JOY_SHOCK_API float JslGetGyroZ(int deviceId); extern "C" JOY_SHOCK_API float JslGetGyroZ(int deviceId);
// get accumulated average gyro since this function was last called or last flushed values
extern "C" JOY_SHOCK_API void JslGetAndFlushAccumulatedGyro(int deviceId, float& gyroX, float& gyroY, float& gyroZ);
// set gyro space. JslGetGyro*, JslGetAndFlushAccumulatedGyro, JslGetIMUState, and the IMU_STATEs reported in the callback functions will use one of 3 transformations:
// 0 = local space -> no transformation is done on gyro input
// 1 = world space -> gyro input is transformed based on the calculated gravity direction to account for the player's preferred controller orientation
// 2 = player space -> a simple combination of local and world space that is as adaptive as world space but is as robust as local space
extern "C" JOY_SHOCK_API void JslSetGyroSpace(int deviceId, int gyroSpace);
// get accelerometor // get accelerometor
extern "C" JOY_SHOCK_API float JslGetAccelX(int deviceId); extern "C" JOY_SHOCK_API float JslGetAccelX(int deviceId);
extern "C" JOY_SHOCK_API float JslGetAccelY(int deviceId); extern "C" JOY_SHOCK_API float JslGetAccelY(int deviceId);
@ -185,6 +215,7 @@ extern "C" JOY_SHOCK_API float JslGetTouchY(int deviceId, bool secondTouch = fal
extern "C" JOY_SHOCK_API float JslGetStickStep(int deviceId); extern "C" JOY_SHOCK_API float JslGetStickStep(int deviceId);
extern "C" JOY_SHOCK_API float JslGetTriggerStep(int deviceId); extern "C" JOY_SHOCK_API float JslGetTriggerStep(int deviceId);
extern "C" JOY_SHOCK_API float JslGetPollRate(int deviceId); extern "C" JOY_SHOCK_API float JslGetPollRate(int deviceId);
extern "C" JOY_SHOCK_API float JslGetTimeSinceLastUpdate(int deviceId);
// calibration // calibration
extern "C" JOY_SHOCK_API void JslResetContinuousCalibration(int deviceId); extern "C" JOY_SHOCK_API void JslResetContinuousCalibration(int deviceId);
@ -193,12 +224,19 @@ extern "C" JOY_SHOCK_API void JslPauseContinuousCalibration(int deviceId);
extern "C" JOY_SHOCK_API void JslSetAutomaticCalibration(int deviceId, bool enabled); extern "C" JOY_SHOCK_API void JslSetAutomaticCalibration(int deviceId, bool enabled);
extern "C" JOY_SHOCK_API void JslGetCalibrationOffset(int deviceId, float& xOffset, float& yOffset, float& zOffset); extern "C" JOY_SHOCK_API void JslGetCalibrationOffset(int deviceId, float& xOffset, float& yOffset, float& zOffset);
extern "C" JOY_SHOCK_API void JslSetCalibrationOffset(int deviceId, float xOffset, float yOffset, float zOffset); extern "C" JOY_SHOCK_API void JslSetCalibrationOffset(int deviceId, float xOffset, float yOffset, float zOffset);
extern "C" JOY_SHOCK_API JSL_AUTO_CALIBRATION JslGetAutoCalibrationStatus(int deviceId);
// this function will get called for each input event from each controller // this function will get called for each input event from each controller
extern "C" JOY_SHOCK_API void JslSetCallback(void(*callback)(int, JOY_SHOCK_STATE, JOY_SHOCK_STATE, IMU_STATE, IMU_STATE, float)); extern "C" JOY_SHOCK_API void JslSetCallback(void(*callback)(int, JOY_SHOCK_STATE, JOY_SHOCK_STATE, IMU_STATE, IMU_STATE, float));
// this function will get called for each input event, even if touch data didn't update // this function will get called for each input event, even if touch data didn't update
extern "C" JOY_SHOCK_API void JslSetTouchCallback(void(*callback)(int, TOUCH_STATE, TOUCH_STATE, float)); extern "C" JOY_SHOCK_API void JslSetTouchCallback(void(*callback)(int, TOUCH_STATE, TOUCH_STATE, float));
// this function will get called for each device when it is newly connected
extern "C" JOY_SHOCK_API void JslSetConnectCallback(void(*callback)(int));
// this function will get called for each device when it is disconnected
extern "C" JOY_SHOCK_API void JslSetDisconnectCallback(void(*callback)(int, bool));
// super-getter for reading a whole lot of state at once
extern "C" JOY_SHOCK_API JSL_SETTINGS JslGetControllerInfoAndSettings(int deviceId);
// what kind of controller is this? // what kind of controller is this?
extern "C" JOY_SHOCK_API int JslGetControllerType(int deviceId); extern "C" JOY_SHOCK_API int JslGetControllerType(int deviceId);
// is this a left, right, or full controller? // is this a left, right, or full controller?

View file

@ -1,17 +1,18 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: b8c465928f1784a3fac8dc3766f7201c guid: b8c465928f1784a3fac8dc3766f7201c
timeCreated: 1538230728
licenseType: Free
PluginImporter: PluginImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2
iconMap: {} iconMap: {}
executionOrder: {} executionOrder: {}
defineConstraints: []
isPreloaded: 0 isPreloaded: 0
isOverridable: 0 isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData: platformData:
- first: - first:
'': Any : Any
second: second:
enabled: 0 enabled: 0
settings: settings:
@ -77,7 +78,7 @@ PluginImporter:
second: second:
enabled: 1 enabled: 1
settings: settings:
CPU: x86_64 CPU: AnyCPU
- first: - first:
Standalone: LinuxUniversal Standalone: LinuxUniversal
second: second:

View file

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BuildMachineOSBuild</key> <key>BuildMachineOSBuild</key>
<string>18A391</string> <string>22D68</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
@ -31,16 +31,20 @@
<key>DTCompiler</key> <key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string> <string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key> <key>DTPlatformBuild</key>
<string>10A255</string> <string>14C18</string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>DTPlatformVersion</key> <key>DTPlatformVersion</key>
<string>GM</string> <string>13.1</string>
<key>DTSDKBuild</key> <key>DTSDKBuild</key>
<string>18A384</string> <string>22C55</string>
<key>DTSDKName</key> <key>DTSDKName</key>
<string>macosx10.14</string> <string>macosx13.1</string>
<key>DTXcode</key> <key>DTXcode</key>
<string>1000</string> <string>1420</string>
<key>DTXcodeBuild</key> <key>DTXcodeBuild</key>
<string>10A255</string> <string>14C18</string>
<key>LSMinimumSystemVersion</key>
<string>13.1</string>
</dict> </dict>
</plist> </plist>

View file

@ -0,0 +1,14 @@
fileFormatVersion: 2
<<<<<<<< HEAD:Assets/Plugins/StandaloneFileBrowser/Plugins/StandaloneFileBrowser.bundle/Contents/_CodeSignature.meta
guid: 7c3db81ca6b7837489ddd39d07d8a941
folderAsset: yes
DefaultImporter:
========
guid: e329403cfc5867042884e77dd4796d34
NativeFormatImporter:
>>>>>>>> release_1:Assets/Resources/Sprites/Games/Lockstep/Animations/Bach.controller.meta
externalObjects: {}
mainObjectFileID: 9100000
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files</key>
<dict/>
<key>files2</key>
<dict/>
<key>rules</key>
<dict>
<key>^Resources/</key>
<true/>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^version.plist$</key>
<true/>
</dict>
<key>rules2</key>
<dict>
<key>.*\.dSYM($|/)</key>
<dict>
<key>weight</key>
<real>11</real>
</dict>
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
<key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^.*</key>
<true/>
<key>^Info\.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^Resources/.*\.lproj/</key>
<dict>
<key>optional</key>
<true/>
<key>weight</key>
<real>1000</real>
</dict>
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
<key>^Resources/Base\.lproj/</key>
<dict>
<key>weight</key>
<real>1010</real>
</dict>
<key>^[^/]+$</key>
<dict>
<key>nested</key>
<true/>
<key>weight</key>
<real>10</real>
</dict>
<key>^embedded\.provisionprofile$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
<key>^version\.plist$</key>
<dict>
<key>weight</key>
<real>20</real>
</dict>
</dict>
</dict>
</plist>

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5905078a1ef7dab4fa302ee6555826c0
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -5,11 +5,14 @@ PluginImporter:
serializedVersion: 2 serializedVersion: 2
iconMap: {} iconMap: {}
executionOrder: {} executionOrder: {}
defineConstraints: []
isPreloaded: 0 isPreloaded: 0
isOverridable: 0 isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData: platformData:
- first: - first:
'': Any : Any
second: second:
enabled: 0 enabled: 0
settings: settings:
@ -61,7 +64,7 @@ PluginImporter:
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: x86_64 CPU: AnyCPU
- first: - first:
Standalone: LinuxUniversal Standalone: LinuxUniversal
second: second:

View file

@ -1,17 +1,18 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 7d459a96865cc4aaab657012c6dc4833 guid: 7d459a96865cc4aaab657012c6dc4833
timeCreated: 1491979494
licenseType: Pro
PluginImporter: PluginImporter:
externalObjects: {}
serializedVersion: 2 serializedVersion: 2
iconMap: {} iconMap: {}
executionOrder: {} executionOrder: {}
defineConstraints: []
isPreloaded: 0 isPreloaded: 0
isOverridable: 0 isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData: platformData:
data: - first:
first: : Any
'': Any
second: second:
enabled: 0 enabled: 0
settings: settings:
@ -27,113 +28,97 @@ PluginImporter:
Exclude Win: 0 Exclude Win: 0
Exclude Win64: 0 Exclude Win64: 0
Exclude iOS: 1 Exclude iOS: 1
data: - first:
first: : Editor
'': Editor
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: AnyCPU CPU: AnyCPU
OS: AnyOS OS: AnyOS
data: - first:
first:
Android: Android Android: Android
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: ARMv7 CPU: ARMv7
data: - first:
first:
Any: Any:
second: second:
enabled: 0 enabled: 0
settings: {} settings: {}
data: - first:
first:
Editor: Editor Editor: Editor
second: second:
enabled: 1 enabled: 1
settings: settings:
DefaultValueInitialized: true DefaultValueInitialized: true
data: - first:
first:
Facebook: Win Facebook: Win
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: AnyCPU CPU: AnyCPU
data: - first:
first:
Facebook: Win64 Facebook: Win64
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: AnyCPU CPU: AnyCPU
data: - first:
first:
Standalone: Linux Standalone: Linux
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: None CPU: None
data: - first:
first:
Standalone: Linux64 Standalone: Linux64
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: None CPU: None
data: - first:
first:
Standalone: LinuxUniversal Standalone: LinuxUniversal
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: None CPU: None
data: - first:
first:
Standalone: OSXIntel Standalone: OSXIntel
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: None CPU: None
data: - first:
first:
Standalone: OSXIntel64 Standalone: OSXIntel64
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: None CPU: None
data: - first:
first:
Standalone: OSXUniversal Standalone: OSXUniversal
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: None CPU: None
data: - first:
first:
Standalone: Win Standalone: Win
second: second:
enabled: 1 enabled: 1
settings: settings:
CPU: AnyCPU CPU: AnyCPU
data: - first:
first:
Standalone: Win64 Standalone: Win64
second: second:
enabled: 1 enabled: 1
settings: settings:
CPU: AnyCPU CPU: AnyCPU
data: - first:
first:
Windows Store Apps: WindowsStoreApps Windows Store Apps: WindowsStoreApps
second: second:
enabled: 0 enabled: 0
settings: settings:
CPU: AnyCPU CPU: AnyCPU
data: - first:
first:
iPhone: iOS iPhone: iOS
second: second:
enabled: 0 enabled: 0

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2,14 +2,15 @@
%TAG !u! tag:unity3d.com,2011: %TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000 --- !u!21 &2100000
Material: Material:
serializedVersion: 6 serializedVersion: 8
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: ButtonSDFMaterial m_Name: ButtonSDFMaterial
m_Shader: {fileID: 4800000, guid: 574134bcfa99f7140a2cd7986bf57c25, type: 3} m_Shader: {fileID: 4800000, guid: 574134bcfa99f7140a2cd7986bf57c25, type: 3}
m_ShaderKeywords: m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4 m_LightmapFlags: 4
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0
@ -67,6 +68,7 @@ Material:
m_Texture: {fileID: 0} m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1} m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0} m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats: m_Floats:
- _Ambient: 0.5 - _Ambient: 0.5
- _Bevel: 0.5 - _Bevel: 0.5
@ -101,7 +103,7 @@ Material:
- _Mode: 0 - _Mode: 0
- _OcclusionStrength: 1 - _OcclusionStrength: 1
- _OffBright: 0.25 - _OffBright: 0.25
- _OutSmoothness: 0.075 - _OutSmoothness: 0.025
- _OutThickness: 0.6 - _OutThickness: 0.6
- _OutlineSoftness: 0 - _OutlineSoftness: 0
- _OutlineUVSpeedX: 0 - _OutlineUVSpeedX: 0
@ -118,7 +120,7 @@ Material:
- _ScaleY: 1 - _ScaleY: 1
- _ShaderFlags: 0 - _ShaderFlags: 0
- _Sharpness: 0 - _Sharpness: 0
- _Smoothness: 0.075 - _Smoothness: 0.025
- _SmoothnessTextureChannel: 0 - _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1 - _SpecularHighlights: 1
- _SpecularPower: 2 - _SpecularPower: 2

View file

@ -2,14 +2,15 @@
%TAG !u! tag:unity3d.com,2011: %TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000 --- !u!21 &2100000
Material: Material:
serializedVersion: 6 serializedVersion: 8
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0} m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: UIControllerMaterial m_Name: UIControllerMaterial
m_Shader: {fileID: 4800000, guid: cfe42e963af2b934bb427536d4d29068, type: 3} m_Shader: {fileID: 4800000, guid: cfe42e963af2b934bb427536d4d29068, type: 3}
m_ShaderKeywords: m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4 m_LightmapFlags: 4
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0
@ -55,6 +56,7 @@ Material:
m_Texture: {fileID: 0} m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1} m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0} m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats: m_Floats:
- _BumpScale: 1 - _BumpScale: 1
- _ColorMask: 15 - _ColorMask: 15
@ -81,11 +83,11 @@ Material:
- _ZWrite: 1 - _ZWrite: 1
m_Colors: m_Colors:
- _BodyColor: {r: 0.95686275, g: 0.95686275, b: 0.95686275, a: 1} - _BodyColor: {r: 0.95686275, g: 0.95686275, b: 0.95686275, a: 1}
- _BtnColor: {r: 1, g: 1, b: 1, a: 1} - _BtnColor: {r: 0.11764706, g: 0.039215688, b: 0.039215688, a: 1}
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767} - _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
- _Color: {r: 1, g: 1, b: 1, a: 1} - _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _LGripColor: {r: 1, g: 1, b: 1, a: 1} - _LGripColor: {r: 0.18431373, g: 0.20784314, b: 0.22745098, a: 1}
- _RGripColor: {r: 1, g: 1, b: 1, a: 1} - _RGripColor: {r: 0.18431373, g: 0.20784314, b: 0.22745098, a: 1}
- _Rect: {r: 0, g: 0, b: 1, a: 1} - _Rect: {r: 0, g: 0, b: 1, a: 1}
m_BuildTextureStacks: [] m_BuildTextureStacks: []

View file

@ -235,7 +235,7 @@ namespace HeavenStudio.Games.Scripts_CropStomp
stompedBeat = cond.songPositionInBeatsAsDouble; stompedBeat = cond.songPositionInBeatsAsDouble;
landBeat = targetBeat + (float)cond.SecsToBeats(Minigame.EndTime()-1, cond.GetBpmAtBeat(targetBeat)); landBeat = targetBeat + (float)cond.SecsToBeats(Minigame.NgLateTime()-1, cond.GetBpmAtBeat(targetBeat));
if (autoTriggered) if (autoTriggered)
{ {

View file

@ -201,7 +201,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
switch (forceHand) switch (forceHand)
{ {
case 0: case 0:
if (cond.songPositionInBeatsAsDouble - lastPunchTime < 0.25f + (Minigame.LateTime() - 1f)) if (cond.songPositionInBeatsAsDouble - lastPunchTime < 0.25f + (Minigame.JustLateTime() - 1f))
{ {
lastPunchTime = double.MinValue; lastPunchTime = double.MinValue;
anim.DoScaledAnimationAsync("Straight", 0.5f); anim.DoScaledAnimationAsync("Straight", 0.5f);

View file

@ -180,8 +180,8 @@ namespace HeavenStudio.Games.Scripts_KarateMan
switch (type) switch (type)
{ {
case ItemType.ComboPot1: case ItemType.ComboPot1:
OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ComboStartJustOrNg, ComboStartThrough, ComboStartOut); OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ComboStartJustOrNg, ComboStartThrough, ComboStartOut, CanCombo);
OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, ComboStartWrongAction, ComboStartOut, ComboStartOut); OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, ComboStartWrongAction, ComboStartOut, ComboStartOut, CanHit);
path = 1; path = 1;
break; break;
case ItemType.ComboPot2: case ItemType.ComboPot2:
@ -202,28 +202,24 @@ namespace HeavenStudio.Games.Scripts_KarateMan
BeatAction.New(gameObject, new List<BeatAction.Action>() { new BeatAction.Action(startBeat + 1f, delegate { JoeComboSequence(); }) }); BeatAction.New(gameObject, new List<BeatAction.Action>() { new BeatAction.Action(startBeat + 1f, delegate { JoeComboSequence(); }) });
break; break;
case ItemType.ComboBarrel: case ItemType.ComboBarrel:
//check for button release OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_ALT_UP, ComboEndJustOrNg, ComboEndThrough, ComboEndOut, CanComboEnd);
OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_ALT_UP, ComboEndJustOrNg, ComboEndThrough, ComboEndOut);
//button presses
KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, ComboEndWrongAction, ItemOut, ItemOut);
KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ComboEndWrongActionAlt, ItemOut, ItemOut);
path = 5; path = 5;
break; break;
case ItemType.KickBarrel: case ItemType.KickBarrel:
OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, KickChargeJustOrNg, ItemThrough, ItemOut); OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, KickChargeJustOrNg, ItemThrough, ItemOut, CanCombo);
OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ItemWrongAction, ItemOut, ItemOut); OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ItemWrongAction, ItemOut, ItemOut, CanCombo);
path = 1; path = 1;
comboId = -1; comboId = -1;
break; break;
case ItemType.KickBomb: case ItemType.KickBomb:
OnHit = KarateMan.instance.ScheduleInput(startBeat, 0.75f, InputType.STANDARD_UP | InputType.DIRECTION_UP, KickJustOrNg, KickThrough, KickOut); OnHit = KarateMan.instance.ScheduleInput(startBeat, 0.75f, InputType.STANDARD_UP | InputType.DIRECTION_UP, KickJustOrNg, KickThrough, KickOut, CanKick);
CurrentCurve = ItemCurves[6]; CurrentCurve = ItemCurves[6];
curveTargetBeat = 2 * 0.75f; curveTargetBeat = 2 * 0.75f;
path = 1; path = 1;
comboId = -1; comboId = -1;
break; break;
case ItemType.KickBall: case ItemType.KickBall:
OnHit = KarateMan.instance.ScheduleInput(startBeat, 0.75f, InputType.STANDARD_UP | InputType.DIRECTION_UP, KickJustOrNg, KickThrough, KickOut); OnHit = KarateMan.instance.ScheduleInput(startBeat, 0.75f, InputType.STANDARD_UP | InputType.DIRECTION_UP, KickJustOrNg, KickThrough, KickOut, CanKick);
CurrentCurve = ItemCurves[6]; CurrentCurve = ItemCurves[6];
curveTargetBeat = 2 * 0.75f; curveTargetBeat = 2 * 0.75f;
path = 1; path = 1;
@ -237,14 +233,14 @@ namespace HeavenStudio.Games.Scripts_KarateMan
comboId = -1; comboId = -1;
break; break;
case ItemType.Bomb: case ItemType.Bomb:
OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, ItemJustOrNg, ItemThrough, ItemOut); OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, ItemJustOrNg, ItemThrough, ItemOut, CanHit);
OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ItemWrongAction, ItemOut, ItemOut); OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ItemWrongAction, ItemOut, ItemOut, CanHit);
path = 1; path = 1;
comboId = -1; comboId = -1;
break; break;
default: default:
OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, ItemJustOrNg, ItemThrough, ItemOut); OnHit = KarateMan.instance.ScheduleInput(startBeat, 1f, InputType.STANDARD_DOWN | InputType.DIRECTION_DOWN, ItemJustOrNg, ItemThrough, ItemOut, CanHit);
OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ItemWrongAction, ItemOut, ItemOut); OnHitWrongAction = KarateMan.instance.ScheduleUserInput(startBeat, 1f, InputType.STANDARD_ALT_DOWN, ItemWrongAction, ItemOut, ItemOut, CanHit);
path = 1; path = 1;
comboId = -1; comboId = -1;
break; break;
@ -726,11 +722,16 @@ namespace HeavenStudio.Games.Scripts_KarateMan
}); });
} }
public bool CanHit()
{
var joe = KarateMan.instance.Joe;
return status == FlyStatus.Fly && !(joe.inCombo || joe.inNuriLock);
}
public void ItemJustOrNg(PlayerActionEvent caller, float state) public void ItemJustOrNg(PlayerActionEvent caller, float state)
{ {
if (GameManager.instance.currentGame != "karateman") return; if (GameManager.instance.currentGame != "karateman") return;
var joe = KarateMan.instance.Joe; var joe = KarateMan.instance.Joe;
if (status == FlyStatus.Fly && !(joe.inCombo || joe.inNuriLock)) {
if (state <= -1f || state >= 1f) { if (state <= -1f || state >= 1f) {
bool straight = joe.Punch(ItemPunchHand()); bool straight = joe.Punch(ItemPunchHand());
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.songPositionInBeatsAsDouble;
@ -771,9 +772,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
KarateMan.instance.Nori.DoHit(); KarateMan.instance.Nori.DoHit();
} }
} }
OnHit.CanHit(false);
OnHitWrongAction.CanHit(false);
}
public void ItemWrongAction(PlayerActionEvent caller, float state) public void ItemWrongAction(PlayerActionEvent caller, float state)
{ {
@ -782,7 +780,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
//hitting a normal object with the alt input //hitting a normal object with the alt input
//WHEN SCORING THIS IS A MISS //WHEN SCORING THIS IS A MISS
var joe = KarateMan.instance.Joe; var joe = KarateMan.instance.Joe;
if (status == FlyStatus.Fly && !(joe.inCombo || joe.inNuriLock)) {
joe.ForceFailCombo(Conductor.instance.songPositionInBeatsAsDouble); joe.ForceFailCombo(Conductor.instance.songPositionInBeatsAsDouble);
if (state <= -1f || state >= 1f) { if (state <= -1f || state >= 1f) {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.songPositionInBeatsAsDouble;
@ -806,9 +803,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
}); });
KarateMan.instance.Nori.DoThrough(); KarateMan.instance.Nori.DoThrough();
} }
OnHit.CanHit(false);
OnHitWrongAction.CanHit(false);
}
public void ItemOut(PlayerActionEvent caller) {} public void ItemOut(PlayerActionEvent caller) {}
@ -833,11 +827,16 @@ namespace HeavenStudio.Games.Scripts_KarateMan
OnHitWrongAction.CanHit(false); OnHitWrongAction.CanHit(false);
} }
public bool CanCombo()
{
var joe = KarateMan.instance.Joe;
return status == FlyStatus.Fly && !(joe.inKick || joe.wantKick || joe.inCombo || joe.inNuriLock);
}
public void ComboStartJustOrNg(PlayerActionEvent caller, float state) public void ComboStartJustOrNg(PlayerActionEvent caller, float state)
{ {
if (GameManager.instance.currentGame != "karateman") return; if (GameManager.instance.currentGame != "karateman") return;
var joe = KarateMan.instance.Joe; var joe = KarateMan.instance.Joe;
if (status == FlyStatus.Fly && !(joe.inKick || joe.wantKick || joe.inCombo || joe.inNuriLock)) {
joe.inCombo = true; joe.inCombo = true;
joe.Punch(1); joe.Punch(1);
joe.SetComboId(comboId); joe.SetComboId(comboId);
@ -856,9 +855,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
KarateMan.instance.Nori.DoHit(); KarateMan.instance.Nori.DoHit();
} }
} }
OnHit.CanHit(false);
OnHitWrongAction.CanHit(false);
}
public void ComboStartOut(PlayerActionEvent caller) {} public void ComboStartOut(PlayerActionEvent caller) {}
public void ComboStartThrough(PlayerActionEvent caller) public void ComboStartThrough(PlayerActionEvent caller)
@ -888,7 +884,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
//hitting a combo start with the normal input //hitting a combo start with the normal input
//WHEN SCORING THIS IS A MISS //WHEN SCORING THIS IS A MISS
var joe = KarateMan.instance.Joe; var joe = KarateMan.instance.Joe;
if (status == FlyStatus.Fly && !(joe.inCombo || joe.inNuriLock)) {
bool straight = joe.Punch(ItemPunchHand()); bool straight = joe.Punch(ItemPunchHand());
if (state <= -1f || state >= 1f) { if (state <= -1f || state >= 1f) {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.songPositionInBeatsAsDouble;
@ -902,15 +897,17 @@ namespace HeavenStudio.Games.Scripts_KarateMan
} }
KarateMan.instance.Nori.DoThrough(); KarateMan.instance.Nori.DoThrough();
} }
OnHit.CanHit(false);
OnHitWrongAction.CanHit(false); public bool CanComboEnd()
{
var joe = KarateMan.instance.Joe;
return status == FlyStatus.Fly && joe.inCombo && joe.GetComboId() == comboId;
} }
public void ComboEndJustOrNg(PlayerActionEvent caller, float state) public void ComboEndJustOrNg(PlayerActionEvent caller, float state)
{ {
if (GameManager.instance.currentGame != "karateman") return; if (GameManager.instance.currentGame != "karateman") return;
var joe = KarateMan.instance.Joe; var joe = KarateMan.instance.Joe;
if (status == FlyStatus.Fly && joe.inCombo && joe.GetComboId() == comboId) {
joe.inCombo = false; joe.inCombo = false;
joe.SetComboId(-1); joe.SetComboId(-1);
joe.SetShouldComboId(-1); joe.SetShouldComboId(-1);
@ -940,8 +937,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
KarateMan.instance.Nori.DoHit(); KarateMan.instance.Nori.DoHit();
} }
} }
OnHit.CanHit(false);
}
public void ComboEndOut(PlayerActionEvent caller) { public void ComboEndOut(PlayerActionEvent caller) {
if (GameManager.instance.currentGame != "karateman") return; if (GameManager.instance.currentGame != "karateman") return;
@ -998,25 +993,11 @@ namespace HeavenStudio.Games.Scripts_KarateMan
OnHit.CanHit(false); OnHit.CanHit(false);
} }
public void ComboEndWrongAction(PlayerActionEvent caller, float state)
{
if (GameManager.instance.currentGame != "karateman") return;
if (!(KarateMan.instance.Joe.inCombo || KarateMan.instance.Joe.inNuriLock))
KarateMan.instance.Joe.Punch(1);
}
public void ComboEndWrongActionAlt(PlayerActionEvent caller, float state)
{
if (GameManager.instance.currentGame != "karateman") return;
if (KarateMan.IsComboEnable && !(KarateMan.instance.Joe.inCombo || KarateMan.instance.Joe.inNuriLock))
KarateMan.instance.Joe.ForceFailCombo(Conductor.instance.songPositionInBeatsAsDouble);
}
public void KickChargeJustOrNg(PlayerActionEvent caller, float state) public void KickChargeJustOrNg(PlayerActionEvent caller, float state)
{ {
if (GameManager.instance.currentGame != "karateman") return; if (GameManager.instance.currentGame != "karateman") return;
var joe = KarateMan.instance.Joe; var joe = KarateMan.instance.Joe;
if (status == FlyStatus.Fly && !(joe.inKick || joe.wantKick || joe.inCombo || joe.inNuriLock)) {
joe.Punch(ItemPunchHand()); joe.Punch(ItemPunchHand());
if (state <= -1f || state >= 1f) { if (state <= -1f || state >= 1f) {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.songPositionInBeatsAsDouble;
@ -1041,9 +1022,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
KarateMan.instance.Nori.DoHit(); KarateMan.instance.Nori.DoHit();
} }
} }
OnHit.CanHit(false);
OnHitWrongAction.CanHit(false);
}
public void KickChargeOut(PlayerActionEvent caller) {} public void KickChargeOut(PlayerActionEvent caller) {}
@ -1068,11 +1046,17 @@ namespace HeavenStudio.Games.Scripts_KarateMan
OnHitWrongAction.CanHit(false); OnHitWrongAction.CanHit(false);
} }
public bool CanKick()
{
var joe = KarateMan.instance.Joe;
return status == FlyStatus.Fly && joe.inKick;
}
public void KickJustOrNg(PlayerActionEvent caller, float state) public void KickJustOrNg(PlayerActionEvent caller, float state)
{ {
if (GameManager.instance.currentGame != "karateman") return; if (GameManager.instance.currentGame != "karateman") return;
var joe = KarateMan.instance.Joe; var joe = KarateMan.instance.Joe;
if (status == FlyStatus.Fly && joe.inKick) {
joe.Kick(Conductor.instance.songPositionInBeatsAsDouble); joe.Kick(Conductor.instance.songPositionInBeatsAsDouble);
if (state <= -1f || state >= 1f) { if (state <= -1f || state >= 1f) {
startBeat = Conductor.instance.songPositionInBeatsAsDouble; startBeat = Conductor.instance.songPositionInBeatsAsDouble;
@ -1105,8 +1089,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
KarateMan.instance.Nori.DoHit(); KarateMan.instance.Nori.DoHit();
} }
} }
OnHit.CanHit(false);
}
public void KickOut(PlayerActionEvent caller) {} public void KickOut(PlayerActionEvent caller) {}

View file

@ -9,7 +9,7 @@ namespace HeavenStudio.Games
{ {
public class Minigame : MonoBehaviour public class Minigame : MonoBehaviour
{ {
public static double earlyTime = 0.075f, perfectTime = 0.06f, aceEarlyTime = 0.01f, aceLateTime = 0.01f, lateTime = 0.06f, endTime = 0.075f; public static double ngEarlyTime = 0.075f, justEarlyTime = 0.06f, aceEarlyTime = 0.01f, aceLateTime = 0.01f, justLateTime = 0.06f, ngLateTime = 0.075f;
public static float rankHiThreshold = 0.8f, rankOkThreshold = 0.6f; public static float rankHiThreshold = 0.8f, rankOkThreshold = 0.6f;
[SerializeField] public SoundSequence.SequenceKeyValue[] SoundSequences; [SerializeField] public SoundSequence.SequenceKeyValue[] SoundSequences;
@ -45,7 +45,9 @@ namespace HeavenStudio.Games
InputType inputType, InputType inputType,
PlayerActionEvent.ActionEventCallbackState OnHit, PlayerActionEvent.ActionEventCallbackState OnHit,
PlayerActionEvent.ActionEventCallback OnMiss, PlayerActionEvent.ActionEventCallback OnMiss,
PlayerActionEvent.ActionEventCallback OnBlank) PlayerActionEvent.ActionEventCallback OnBlank,
PlayerActionEvent.ActionEventHittableQuery HittableQuery = null
)
{ {
GameObject evtObj = new GameObject("ActionEvent" + (startBeat+timer)); GameObject evtObj = new GameObject("ActionEvent" + (startBeat+timer));
@ -59,6 +61,7 @@ namespace HeavenStudio.Games
evt.OnHit = OnHit; evt.OnHit = OnHit;
evt.OnMiss = OnMiss; evt.OnMiss = OnMiss;
evt.OnBlank = OnBlank; evt.OnBlank = OnBlank;
evt.IsHittable = HittableQuery;
evt.OnDestroy = RemoveScheduledInput; evt.OnDestroy = RemoveScheduledInput;
@ -91,15 +94,14 @@ namespace HeavenStudio.Games
InputType inputType, InputType inputType,
PlayerActionEvent.ActionEventCallbackState OnHit, PlayerActionEvent.ActionEventCallbackState OnHit,
PlayerActionEvent.ActionEventCallback OnMiss, PlayerActionEvent.ActionEventCallback OnMiss,
PlayerActionEvent.ActionEventCallback OnBlank) PlayerActionEvent.ActionEventCallback OnBlank,
PlayerActionEvent.ActionEventHittableQuery HittableQuery = null)
{ {
PlayerActionEvent evt = ScheduleInput(startBeat, timer, inputType, OnHit, OnMiss, OnBlank); PlayerActionEvent evt = ScheduleInput(startBeat, timer, inputType, OnHit, OnMiss, OnBlank, HittableQuery);
evt.noAutoplay = true; evt.noAutoplay = true;
return evt; return evt;
} }
//Clean up method used whenever a PlayerActionEvent has finished //Clean up method used whenever a PlayerActionEvent has finished
public void RemoveScheduledInput(PlayerActionEvent evt) public void RemoveScheduledInput(PlayerActionEvent evt)
{ {
@ -151,49 +153,36 @@ namespace HeavenStudio.Games
} }
// now should fix the fast bpm problem // now should fix the fast bpm problem
public static double EarlyTime() public static double NgEarlyTime()
{ {
return 1f - earlyTime; return 1f - ngEarlyTime;
} }
public static double PerfectTime() public static double JustEarlyTime()
{ {
return 1f - perfectTime; return 1f - justEarlyTime;
} }
public static double LateTime() public static double JustLateTime()
{ {
return 1f + lateTime; return 1f + justLateTime;
} }
public static double EndTime() public static double NgLateTime()
{ {
return 1f + endTime; return 1f + ngLateTime;
} }
public static double AceStartTime() public static double AceEarlyTime()
{ {
return 1f - aceEarlyTime; return 1f - aceEarlyTime;
} }
public static double AceEndTime() public static double AceLateTime()
{ {
return 1f + aceLateTime; return 1f + aceLateTime;
} }
// DEPRECATED: scales timing windows to the BPM in an ""intelligent"" manner
// only left for historical reasons
static float ScaleTimingMargin(float f)
{
float bpm = Conductor.instance.songBpm * Conductor.instance.musicSource.pitch;
float a = bpm / 120f;
float b = (Mathf.Log(a) + 2f) * 0.5f;
float r = Mathf.Lerp(a, b, 0.25f);
return r * f;
}
public int firstEnable = 0;
public virtual void OnGameSwitch(double beat) public virtual void OnGameSwitch(double beat)
{ {
//Below is a template that can be used for handling previous entities. //Below is a template that can be used for handling previous entities.
@ -263,7 +252,7 @@ namespace HeavenStudio.Games
public void ScoreMiss(double weight = 1f) public void ScoreMiss(double weight = 1f)
{ {
GameManager.instance.ScoreInputAccuracy(0, true, EndTime(), weight, false); GameManager.instance.ScoreInputAccuracy(0, true, NgLateTime(), weight, false);
if (weight > 0) if (weight > 0)
{ {
GoForAPerfect.instance.Miss(); GoForAPerfect.instance.Miss();

View file

@ -244,9 +244,14 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
} }
// jumping cues (timings for both are the same) // jumping cues (timings for both are the same)
public bool CanJump()
{
return canJump;
}
public void ScheduleJump(double beat) public void ScheduleJump(double beat)
{ {
PajamaParty.instance.ScheduleInput(beat, 2f, InputType.STANDARD_DOWN, JumpJustOrNg, JumpThrough, JumpOut); PajamaParty.instance.ScheduleInput(beat, 2f, InputType.STANDARD_DOWN, JumpJustOrNg, JumpThrough, JumpOut, CanJump);
} }
public void JumpJustOrNg(PlayerActionEvent caller, float state) public void JumpJustOrNg(PlayerActionEvent caller, float state)
@ -284,7 +289,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
public void ScheduleThrow(double beat) public void ScheduleThrow(double beat)
{ {
PajamaParty.instance.ScheduleInput(beat, 2f, InputType.STANDARD_ALT_DOWN, ChargeJustOrNg, ThrowThrough, JumpOut); PajamaParty.instance.ScheduleInput(beat, 2f, InputType.STANDARD_ALT_DOWN, ChargeJustOrNg, ThrowThrough, JumpOut);
PajamaParty.instance.ScheduleInput(beat, 3f, InputType.STANDARD_ALT_UP, ThrowJustOrNg, ThrowThrough, JumpOut); PajamaParty.instance.ScheduleInput(beat, 3f, InputType.STANDARD_ALT_UP, ThrowJustOrNg, ThrowThrough, JumpOut, CanThrow);
} }
public void ChargeJustOrNg(PlayerActionEvent caller, float state) { public void ChargeJustOrNg(PlayerActionEvent caller, float state) {
@ -293,9 +298,12 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
SoundByte.PlayOneShotGame("pajamaParty/throw4"); SoundByte.PlayOneShotGame("pajamaParty/throw4");
} }
public void ThrowJustOrNg(PlayerActionEvent caller, float state) public bool CanThrow()
{ {
if (charging) return charging;
}
public void ThrowJustOrNg(PlayerActionEvent caller, float state)
{ {
var cond = Conductor.instance; var cond = Conductor.instance;
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
@ -310,7 +318,6 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
} }
caller.CanHit(false); caller.CanHit(false);
} }
}
public void ThrowThrough(PlayerActionEvent caller) public void ThrowThrough(PlayerActionEvent caller)
{ {
@ -325,28 +332,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
// sleep cue // sleep cue
public void StartSleepSequence(double beat, bool alt, int action) public void StartSleepSequence(double beat, bool alt, int action)
{ {
startedSleeping = true; PajamaParty.instance.ScheduleInput(beat, 4f, InputType.STANDARD_DOWN, SleepJustOrNg, SleepThrough, SleepOut, CanSleep);
if (hasJumped)
{
hasJumped = false;
PajamaParty.instance.DoBedImpact();
jumpNg = false;
}
startJumpTime = double.MinValue;
Player.transform.localPosition = new Vector3(0, 0);
Shadow.transform.localScale = new Vector3(1.65f, 1f, 1f);
Projectile.GetComponent<Animator>().Play("NoPose", -1, 0);
startThrowTime = double.MinValue;
Projectile_Root.transform.localPosition = new Vector3(0, 0);
Projectile.transform.rotation = Quaternion.Euler(0, 0, 0);
if (hasThrown)
{
Projectile.SetActive(false);
hasThrown = false;
}
PajamaParty.instance.ScheduleInput(beat, 4f, InputType.STANDARD_DOWN, SleepJustOrNg, SleepThrough, SleepOut);
var cond = Conductor.instance; var cond = Conductor.instance;
charging = false; charging = false;
@ -365,6 +351,16 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
Player.transform.localPosition = new Vector3(0, 0); Player.transform.localPosition = new Vector3(0, 0);
Shadow.transform.localScale = new Vector3(1.65f, 1f, 1f); Shadow.transform.localScale = new Vector3(1.65f, 1f, 1f);
Projectile.GetComponent<Animator>().Play("NoPose", -1, 0);
startThrowTime = double.MinValue;
Projectile_Root.transform.localPosition = new Vector3(0, 0);
Projectile.transform.rotation = Quaternion.Euler(0, 0, 0);
if (hasThrown)
{
Projectile.SetActive(false);
hasThrown = false;
}
if (action == (int) PajamaParty.SleepType.NoAwake) if (action == (int) PajamaParty.SleepType.NoAwake)
{ {
longSleep = true; longSleep = true;
@ -403,11 +399,14 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
}); });
} }
public bool CanSleep()
{
return canSleep;
}
public void SleepJustOrNg(PlayerActionEvent caller, float state) public void SleepJustOrNg(PlayerActionEvent caller, float state)
{ {
var cond = Conductor.instance; var cond = Conductor.instance;
if (canSleep)
{
caller.CanHit(false); caller.CanHit(false);
canSleep = false; canSleep = false;
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
@ -433,7 +432,6 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
longSleep = false; longSleep = false;
} }
} }
}
public void SleepThrough(PlayerActionEvent caller) public void SleepThrough(PlayerActionEvent caller)
{ {

View file

@ -18,10 +18,12 @@ namespace HeavenStudio.Games
public static bool EnableAutoplayCheat = true; public static bool EnableAutoplayCheat = true;
public delegate void ActionEventCallback(PlayerActionEvent caller); public delegate void ActionEventCallback(PlayerActionEvent caller);
public delegate void ActionEventCallbackState(PlayerActionEvent caller, float state); public delegate void ActionEventCallbackState(PlayerActionEvent caller, float state);
public delegate bool ActionEventHittableQuery();
public ActionEventCallbackState OnHit; //Function to trigger when an input has been done perfectly public ActionEventCallbackState OnHit; //Function to trigger when an input has been done perfectly
public ActionEventCallback OnMiss; //Function to trigger when an input has been missed public ActionEventCallback OnMiss; //Function to trigger when an input has been missed
public ActionEventCallback OnBlank; //Function to trigger when an input has been recorded while this is pending public ActionEventCallback OnBlank; //Function to trigger when an input has been recorded while this is pending
public ActionEventHittableQuery IsHittable; //Checks if an input can be hit. Returning false will skip button checks.
public ActionEventCallback OnDestroy; //Function to trigger whenever this event gets destroyed. /!\ Shouldn't be used for a minigame! Use OnMiss instead /!\ public ActionEventCallback OnDestroy; //Function to trigger whenever this event gets destroyed. /!\ Shouldn't be used for a minigame! Use OnMiss instead /!\
@ -55,28 +57,38 @@ namespace HeavenStudio.Games
this.OnMiss = OnMiss; this.OnMiss = OnMiss;
} }
public void setHittableQuery(ActionEventHittableQuery IsHittable)
{
this.IsHittable = IsHittable;
}
public void Enable() { enabled = true; } public void Enable() { enabled = true; }
public void Disable() { enabled = false; } public void Disable() { enabled = false; }
public void QueueDeletion() { markForDeletion = true; } public void QueueDeletion() { markForDeletion = true; }
public bool IsCorrectInput() => public bool IsCorrectInput(out double dt)
{
dt = 0;
return (
//General inputs, both down and up //General inputs, both down and up
(PlayerInput.Pressed() && inputType.HasFlag(InputType.STANDARD_DOWN)) || (PlayerInput.Pressed(out dt) && inputType.HasFlag(InputType.STANDARD_DOWN)) ||
(PlayerInput.AltPressed() && inputType.HasFlag(InputType.STANDARD_ALT_DOWN)) || (PlayerInput.AltPressed(out dt) && inputType.HasFlag(InputType.STANDARD_ALT_DOWN)) ||
(PlayerInput.GetAnyDirectionDown() && inputType.HasFlag(InputType.DIRECTION_DOWN)) || (PlayerInput.GetAnyDirectionDown(out dt) && inputType.HasFlag(InputType.DIRECTION_DOWN)) ||
(PlayerInput.PressedUp() && inputType.HasFlag(InputType.STANDARD_UP)) || (PlayerInput.PressedUp(out dt) && inputType.HasFlag(InputType.STANDARD_UP)) ||
(PlayerInput.AltPressedUp() && inputType.HasFlag(InputType.STANDARD_ALT_UP)) || (PlayerInput.AltPressedUp(out dt) && inputType.HasFlag(InputType.STANDARD_ALT_UP)) ||
(PlayerInput.GetAnyDirectionUp() && inputType.HasFlag(InputType.DIRECTION_UP)) || (PlayerInput.GetAnyDirectionUp(out dt) && inputType.HasFlag(InputType.DIRECTION_UP)) ||
//Specific directional inputs //Specific directional inputs
(PlayerInput.GetSpecificDirectionDown(PlayerInput.DOWN) && inputType.HasFlag(InputType.DIRECTION_DOWN_DOWN)) || (PlayerInput.GetSpecificDirectionDown(PlayerInput.DOWN, out dt) && inputType.HasFlag(InputType.DIRECTION_DOWN_DOWN)) ||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.UP) && inputType.HasFlag(InputType.DIRECTION_UP_DOWN)) || (PlayerInput.GetSpecificDirectionDown(PlayerInput.UP, out dt) && inputType.HasFlag(InputType.DIRECTION_UP_DOWN)) ||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.LEFT) && inputType.HasFlag(InputType.DIRECTION_LEFT_DOWN)) || (PlayerInput.GetSpecificDirectionDown(PlayerInput.LEFT, out dt) && inputType.HasFlag(InputType.DIRECTION_LEFT_DOWN)) ||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.RIGHT) && inputType.HasFlag(InputType.DIRECTION_RIGHT_DOWN)) || (PlayerInput.GetSpecificDirectionDown(PlayerInput.RIGHT, out dt) && inputType.HasFlag(InputType.DIRECTION_RIGHT_DOWN)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.DOWN) && inputType.HasFlag(InputType.DIRECTION_DOWN_UP)) || (PlayerInput.GetSpecificDirectionUp(PlayerInput.DOWN, out dt) && inputType.HasFlag(InputType.DIRECTION_DOWN_UP)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.UP) && inputType.HasFlag(InputType.DIRECTION_UP_UP)) || (PlayerInput.GetSpecificDirectionUp(PlayerInput.UP, out dt) && inputType.HasFlag(InputType.DIRECTION_UP_UP)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.LEFT) && inputType.HasFlag(InputType.DIRECTION_LEFT_UP)) || (PlayerInput.GetSpecificDirectionUp(PlayerInput.LEFT, out dt) && inputType.HasFlag(InputType.DIRECTION_LEFT_UP)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.RIGHT) && inputType.HasFlag(InputType.DIRECTION_RIGHT_UP)); (PlayerInput.GetSpecificDirectionUp(PlayerInput.RIGHT, out dt) && inputType.HasFlag(InputType.DIRECTION_RIGHT_UP))
);
}
public void CanHit(bool canHit) public void CanHit(bool canHit)
{ {
@ -105,7 +117,7 @@ namespace HeavenStudio.Games
} }
//BUGFIX: ActionEvents destroyed too early //BUGFIX: ActionEvents destroyed too early
if (normalizedTime > Minigame.EndTime()) Miss(); if (normalizedTime > Minigame.NgLateTime()) Miss();
if (lockedByEvent) if (lockedByEvent)
{ {
@ -116,11 +128,12 @@ namespace HeavenStudio.Games
return; return;
} }
if (!autoplayOnly && IsCorrectInput()) if (!autoplayOnly && (IsHittable == null || IsHittable != null && IsHittable()) && IsCorrectInput(out double dt))
{ {
normalizedTime -= dt;
if (IsExpectingInputNow()) if (IsExpectingInputNow())
{ {
double stateProg = ((normalizedTime - Minigame.PerfectTime()) / (Minigame.LateTime() - Minigame.PerfectTime()) - 0.5f) * 2; double stateProg = ((normalizedTime - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime()) - 0.5f) * 2;
Hit(stateProg, normalizedTime); Hit(stateProg, normalizedTime);
} }
else else
@ -186,8 +199,16 @@ namespace HeavenStudio.Games
public bool IsExpectingInputNow() public bool IsExpectingInputNow()
{ {
if (IsHittable != null)
{
if (!IsHittable()) return false;
}
if (!enabled) return false;
if (!isEligible) return false;
if (markForDeletion) return false;
double normalizedBeat = GetNormalizedTime(); double normalizedBeat = GetNormalizedTime();
return normalizedBeat > Minigame.EarlyTime() && normalizedBeat < Minigame.EndTime(); return normalizedBeat > Minigame.NgEarlyTime() && normalizedBeat < Minigame.NgLateTime();
} }
double GetNormalizedTime() double GetNormalizedTime()
@ -195,9 +216,9 @@ namespace HeavenStudio.Games
var cond = Conductor.instance; var cond = Conductor.instance;
double currTime = cond.songPositionAsDouble; double currTime = cond.songPositionAsDouble;
double targetTime = cond.GetSongPosFromBeat(startBeat + timer); double targetTime = cond.GetSongPosFromBeat(startBeat + timer);
double min = targetTime - 1f;
double max = targetTime + 1f; // HS timing window uses 1 as the middle point instead of 0
return 1f + (((currTime - min) / (max - min))-0.5f)*2; return 1 + (currTime - targetTime);
} }
//For the Autoplay //For the Autoplay
@ -210,7 +231,7 @@ namespace HeavenStudio.Games
else else
{ {
double normalizedBeat = GetNormalizedTime(); double normalizedBeat = GetNormalizedTime();
double stateProg = ((normalizedBeat - Minigame.PerfectTime()) / (Minigame.LateTime() - Minigame.PerfectTime()) - 0.5f) * 2; double stateProg = ((normalizedBeat - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime()) - 0.5f) * 2;
Hit(stateProg, normalizedBeat); Hit(stateProg, normalizedBeat);
} }
} }
@ -251,27 +272,27 @@ namespace HeavenStudio.Games
double TimeToAccuracy(double time) double TimeToAccuracy(double time)
{ {
if (time >= Minigame.AceStartTime() && time <= Minigame.AceEndTime()) if (time >= Minigame.AceEarlyTime() && time <= Minigame.AceLateTime())
{ {
// Ace // Ace
return 1.0; return 1.0;
} }
double state = 0; double state = 0;
if (time >= Minigame.PerfectTime() && time <= Minigame.LateTime()) if (time >= Minigame.JustEarlyTime() && time <= Minigame.JustLateTime())
{ {
// Good Hit // Good Hit
if (time > 1.0) if (time > 1.0)
{ {
// late half of timing window // late half of timing window
state = 1.0 - ((time - Minigame.AceEndTime()) / (Minigame.LateTime() - Minigame.AceEndTime())); state = 1.0 - ((time - Minigame.AceLateTime()) / (Minigame.JustLateTime() - Minigame.AceLateTime()));
state *= 1.0 - Minigame.rankHiThreshold; state *= 1.0 - Minigame.rankHiThreshold;
state += Minigame.rankHiThreshold; state += Minigame.rankHiThreshold;
} }
else else
{ {
//early half of timing window //early half of timing window
state = ((time - Minigame.PerfectTime()) / (Minigame.AceStartTime() - Minigame.PerfectTime())); state = ((time - Minigame.JustEarlyTime()) / (Minigame.AceEarlyTime() - Minigame.JustEarlyTime()));
state *= 1.0 - Minigame.rankHiThreshold; state *= 1.0 - Minigame.rankHiThreshold;
state += Minigame.rankHiThreshold; state += Minigame.rankHiThreshold;
} }
@ -281,13 +302,13 @@ namespace HeavenStudio.Games
if (time > 1.0) if (time > 1.0)
{ {
// late half of timing window // late half of timing window
state = 1.0 - ((time - Minigame.LateTime()) / (Minigame.EndTime() - Minigame.LateTime())); state = 1.0 - ((time - Minigame.JustLateTime()) / (Minigame.NgLateTime() - Minigame.JustLateTime()));
state *= Minigame.rankOkThreshold; state *= Minigame.rankOkThreshold;
} }
else else
{ {
//early half of timing window //early half of timing window
state = ((time - Minigame.PerfectTime()) / (Minigame.AceStartTime() - Minigame.PerfectTime())); state = ((time - Minigame.JustEarlyTime()) / (Minigame.AceEarlyTime() - Minigame.JustEarlyTime()));
state *= Minigame.rankOkThreshold; state *= Minigame.rankOkThreshold;
} }
} }

View file

@ -1067,4 +1067,3 @@ namespace HeavenStudio.Games
} }
} }
} }

View file

@ -343,7 +343,7 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
var cond = Conductor.instance; var cond = Conductor.instance;
ball = null; ball = null;
// queue the miss sound // queue the miss sound
MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("spaceSoccer/missNeutral", targetBeat + (float)cond.SecsToBeats(Minigame.EndTime()-1, MultiSound.Play(new MultiSound.Sound[] { new MultiSound.Sound("spaceSoccer/missNeutral", targetBeat + (float)cond.SecsToBeats(Minigame.NgLateTime()-1,
cond.GetBpmAtBeat(targetBeat)), SoundByte.GetPitchFromCents(UnityEngine.Random.Range(-75, 75), false)) }); cond.GetBpmAtBeat(targetBeat)), SoundByte.GetPitchFromCents(UnityEngine.Random.Range(-75, 75), false)) });
} }

View file

@ -33,7 +33,7 @@ namespace HeavenStudio.Games.Scripts_TrickClass
float flyPos = cond.GetPositionFromBeat(startBeat, flyBeats); float flyPos = cond.GetPositionFromBeat(startBeat, flyBeats);
transform.position = curve.GetPoint(flyPos); transform.position = curve.GetPoint(flyPos);
hitProg = game.ScheduleInput(startBeat, dodgeBeats, InputType.STANDARD_DOWN, DodgeJustOrNg, DodgeMiss, DodgeThrough); hitProg = game.ScheduleInput(startBeat, dodgeBeats, InputType.STANDARD_DOWN, DodgeJustOrNg, DodgeMiss, DodgeThrough, CanDodge);
} }
// Update is called once per frame // Update is called once per frame
@ -113,9 +113,12 @@ namespace HeavenStudio.Games.Scripts_TrickClass
startBeat += dodgeBeats; startBeat += dodgeBeats;
} }
public void DodgeJustOrNg(PlayerActionEvent caller, float state) public bool CanDodge()
{ {
if (game.playerCanDodge <= Conductor.instance.songPositionInBeatsAsDouble) return game.playerCanDodge <= Conductor.instance.songPositionInBeatsAsDouble;
}
public void DodgeJustOrNg(PlayerActionEvent caller, float state)
{ {
if (state <= -1f || state >= 1f) if (state <= -1f || state >= 1f)
{ {
@ -138,15 +141,6 @@ namespace HeavenStudio.Games.Scripts_TrickClass
}); });
} }
} }
else
{
SoundByte.PlayOneShotGame(GetDodgeSound());
DoObjMiss();
game.PlayerThrough();
caller.isEligible = false;
game.ScoreMiss();
}
}
public void DodgeMiss(PlayerActionEvent caller) public void DodgeMiss(PlayerActionEvent caller)
{ {

View file

@ -371,7 +371,7 @@ namespace HeavenStudio
void OnApplicationQuit() void OnApplicationQuit()
{ {
Debug.Log("Disconnecting JoyShocks..."); Debug.Log("Disconnecting JoyShocks...");
PlayerInput.DisconnectJoyshocks(); PlayerInput.CleanUp();
Debug.Log("Clearing RIQ Cache..."); Debug.Log("Clearing RIQ Cache...");
Jukebox.RiqFileHandler.ClearCache(); Jukebox.RiqFileHandler.ClearCache();
} }

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -6,11 +7,99 @@ using HeavenStudio.Util;
using static JSL; using static JSL;
namespace HeavenStudio.InputSystem.Loaders
{
public static class InputJoyshockInitializer
{
[LoadOrder(1)]
public static InputController[] Initialize()
{
InputJoyshock.joyshocks = new();
PlayerInput.PlayerInputCleanUp += DisposeJoyshocks;
PlayerInput.PlayerInputRefresh.Add(Refresh);
InputJoyshock.JslEventInit();
InputController[] controllers;
int jslDevicesFound = 0;
int jslDevicesConnected = 0;
int[] jslDeviceHandles;
jslDevicesFound = JslConnectDevices();
if (jslDevicesFound > 0)
{
jslDeviceHandles = new int[jslDevicesFound];
jslDevicesConnected = JslGetConnectedDeviceHandles(jslDeviceHandles, jslDevicesFound);
if (jslDevicesConnected < jslDevicesFound)
{
Debug.Log("Found " + jslDevicesFound + " JoyShocks, but only " + jslDevicesConnected + " are connected.");
}
else
{
Debug.Log("Found " + jslDevicesFound + " JoyShocks.");
Debug.Log("Connected " + jslDevicesConnected + " JoyShocks.");
}
controllers = new InputController[jslDevicesConnected];
foreach (int i in jslDeviceHandles)
{
Debug.Log("Setting up JoyShock: ( Handle " + i + ", type " + JslGetControllerType(i) + " )");
InputJoyshock joyshock = new InputJoyshock(i);
joyshock.SetPlayer(null);
joyshock.InitializeController();
controllers[i] = joyshock;
}
return controllers;
}
Debug.Log("No JoyShocks found.");
return null;
}
public static void DisposeJoyshocks()
{
foreach (InputJoyshock joyshock in InputJoyshock.joyshocks.Values)
{
joyshock.CleanUp();
}
JslDisconnectAndDisposeAll();
}
public static InputController[] Refresh()
{
InputJoyshock.joyshocks.Clear();
InputController[] controllers;
int jslDevicesFound = 0;
int jslDevicesConnected = 0;
int[] jslDeviceHandles;
jslDevicesFound = JslConnectDevices();
if (jslDevicesFound > 0)
{
jslDeviceHandles = new int[jslDevicesFound];
jslDevicesConnected = JslGetConnectedDeviceHandles(jslDeviceHandles, jslDevicesFound);
controllers = new InputController[jslDevicesConnected];
foreach (int i in jslDeviceHandles)
{
Debug.Log("Setting up JoyShock: ( Handle " + i + ", type " + JslGetControllerType(i) + " )");
InputJoyshock joyshock = new InputJoyshock(i);
joyshock.SetPlayer(null);
joyshock.InitializeController();
controllers[i] = joyshock;
}
return controllers;
}
Debug.Log("No JoyShocks found.");
return null;
}
}
}
namespace HeavenStudio.InputSystem namespace HeavenStudio.InputSystem
{ {
public class InputJoyshock : InputController public class InputJoyshock : InputController
{ {
static string[] joyShockNames = static readonly string[] joyShockNames =
{ {
"Unknown", "Unknown",
"Joy-Con (L)", "Joy-Con (L)",
@ -20,7 +109,7 @@ namespace HeavenStudio.InputSystem
"DualSense" "DualSense"
}; };
static int[] dsPlayerColours = new[] static readonly int[] dsPlayerColours = new[]
{ {
0xd41817, 0xd41817,
0x04d4fa, 0x04d4fa,
@ -31,8 +120,10 @@ namespace HeavenStudio.InputSystem
0x888888 0x888888
}; };
//TODO: see if single joy-con mappings differ from a normal pad (they don't!) static int[] defaultMappings {
int[] mappings = new[] get
{
return new[]
{ {
ButtonMaskUp, ButtonMaskUp,
ButtonMaskDown, ButtonMaskDown,
@ -45,13 +136,19 @@ namespace HeavenStudio.InputSystem
ButtonMaskL, ButtonMaskL,
ButtonMaskR, ButtonMaskR,
ButtonMaskPlus, ButtonMaskPlus,
-1
}; };
int[] mappingsSplitLeft = new[] }
}
static int[] defaultMappingsL {
get
{ {
-1, return new[]
-1, {
-1, 20,
-1, 21,
22,
23,
ButtonMaskLeft, ButtonMaskLeft,
ButtonMaskDown, ButtonMaskDown,
ButtonMaskUp, ButtonMaskUp,
@ -59,13 +156,20 @@ namespace HeavenStudio.InputSystem
ButtonMaskSL, ButtonMaskSL,
ButtonMaskSR, ButtonMaskSR,
ButtonMaskMinus, ButtonMaskMinus,
-1
}; };
int[] mappingsSplitRight = new[] }
}
static int[] defaultMappingsR {
get
{ {
-1, return new[]
-1, {
-1, 20,
-1, 21,
22,
23,
ButtonMaskE, ButtonMaskE,
ButtonMaskN, ButtonMaskN,
ButtonMaskS, ButtonMaskS,
@ -73,7 +177,109 @@ namespace HeavenStudio.InputSystem
ButtonMaskSL, ButtonMaskSL,
ButtonMaskSR, ButtonMaskSR,
ButtonMaskPlus, ButtonMaskPlus,
-1
}; };
}
}
static readonly string[] nsProButtonNames = new[]
{
"Up",
"Down",
"Left",
"Right",
"Plus",
"Minus",
"Left Stick Click",
"Right Stick Click",
"L",
"R",
"ZL",
"ZR",
"B",
"A",
"Y",
"X",
"Home",
"Capture",
};
static readonly string[] nsConButtonNames = new[]
{
"Up",
"Down",
"Left",
"Right",
"Plus",
"Minus",
"Left Stick Click",
"Right Stick Click",
"L",
"R",
"ZL",
"ZR",
"B",
"A",
"Y",
"X",
"Home",
"Capture",
"SL",
"SR",
"Stick Up",
"Stick Down",
"Stick Left",
"Stick Right",
};
static readonly string[] ps4ButtonNames = new[]
{
"Up",
"Down",
"Left",
"Right",
"Options",
"Share",
"L3",
"R3",
"L",
"R",
"L2",
"R2",
"X",
"Circle",
"Square",
"Triangle",
"PS",
"Touchpad Click",
};
static readonly string[] ps5ButtonNames = new[]
{
"Up",
"Down",
"Left",
"Right",
"Options",
"Share",
"L3",
"R3",
"L",
"R",
"L2",
"R2",
"X",
"Circle",
"Square",
"Triangle",
"PS",
"Create",
"Mic",
};
static readonly float debounceTime = 1f/90f;
public static Dictionary<int, InputJoyshock> joyshocks;
float stickDeadzone = 0.5f; float stickDeadzone = 0.5f;
@ -82,53 +288,171 @@ namespace HeavenStudio.InputSystem
int splitType; int splitType;
int lightbarColour; int lightbarColour;
string joyshockName; string joyshockName;
DateTime startTime;
//buttons, sticks, triggers //buttons, sticks, triggers
JOY_SHOCK_STATE joyBtStateCurrent, joyBtStateLast; JoyshockButtonState[] actionStates = new JoyshockButtonState[BINDS_MAX];
JoyshockButtonState[] buttonStates = new JoyshockButtonState[ButtonMaskSR + 1];
JOY_SHOCK_STATE joyBtStateCurrent;
//gyro and accelerometer //gyro and accelerometer
IMU_STATE joyImuStateCurrent, joyImuStateLast; IMU_STATE joyImuStateCurrent, joyImuStateLast;
//touchpad //touchpad
TOUCH_STATE joyTouchStateCurrent, joyTouchStateLast; TOUCH_STATE joyTouchStateCurrent, joyTouchStateLast;
// controller settings
JSL_SETTINGS joySettings;
InputJoyshock otherHalf; InputJoyshock otherHalf;
bool isPair;
public struct JoyshockButtonState
{
public double dt; // time passed since state
public bool pressed; // true if button is down
public float debounce; // timer to ignore button updates
public bool isDelta; // true if the button changed state since last frame
}
public struct TimestampedState
{
public double timestamp;
public JOY_SHOCK_STATE input;
}
protected List<TimestampedState> inputStack; // asynnc input events / polling should feed into this dict
protected List<TimestampedState> lastInputStack; // when processing input copy the inputStack to this dict
protected bool wantClearInputStack = false; // strobe from main thread to clear the input stack
protected double reportTime = 0;
public InputJoyshock(int handle) public InputJoyshock(int handle)
{ {
joyshockHandle = handle; joyshockHandle = handle;
} }
int GetButtonForSplitType(int action)
{
if (currentBindings.Pad == null) return -1;
if (action < 0 || action >= BINDS_MAX) return -1;
ControlBindings actionMap = currentBindings;
if (actionMap.Pad[action] > ButtonMaskSR) return -1;
return actionMap.Pad[action];
}
public static void JslEventInit()
{
JslSetCallback(JslEventCallback);
}
static void JslEventCallback(int handle, JOY_SHOCK_STATE state, JOY_SHOCK_STATE lastState,
IMU_STATE imuState, IMU_STATE lastImuState, float deltaTime)
{
if (joyshocks == null || !joyshocks.ContainsKey(handle)) return;
InputJoyshock js = joyshocks[handle];
if (js == null) return;
if (js.inputStack == null) return;
if (js.wantClearInputStack)
{
js.inputStack.Clear();
js.wantClearInputStack = false;
}
js.inputStack.Add(new TimestampedState
{
timestamp = (DateTime.Now - js.startTime).TotalSeconds,
input = state
});
}
public override void InitializeController() public override void InitializeController()
{ {
startTime = DateTime.Now;
inputStack = new();
lastInputStack = new();
actionStates = new JoyshockButtonState[BINDS_MAX];
buttonStates = new JoyshockButtonState[ButtonMaskSR + 1];
joyBtStateCurrent = new JOY_SHOCK_STATE(); joyBtStateCurrent = new JOY_SHOCK_STATE();
joyBtStateLast = new JOY_SHOCK_STATE();
joyImuStateCurrent = new IMU_STATE(); joyImuStateCurrent = new IMU_STATE();
joyImuStateLast = new IMU_STATE(); joyImuStateLast = new IMU_STATE();
joyTouchStateCurrent = new TOUCH_STATE(); joyTouchStateCurrent = new TOUCH_STATE();
joyTouchStateLast = new TOUCH_STATE(); joyTouchStateLast = new TOUCH_STATE();
//FUTURE: remappable controls
type = JslGetControllerType(joyshockHandle); joySettings = JslGetControllerInfoAndSettings(joyshockHandle);
type = joySettings.controllerType;
joyshockName = joyShockNames[type]; joyshockName = joyShockNames[type];
splitType = JslGetControllerSplitType(joyshockHandle); splitType = joySettings.splitType;
joyshocks.Add(joyshockHandle, this);
LoadBindings();
}
public void CleanUp()
{
JslSetPlayerNumber(joyshockHandle, 0);
JslSetLightColour(joyshockHandle, 0);
} }
public override void UpdateState() public override void UpdateState()
{ {
//buttons reportTime = (DateTime.Now - startTime).TotalSeconds;
joyBtStateLast = joyBtStateCurrent; lastInputStack.Capacity = inputStack.Count;
joyBtStateCurrent = JslGetSimpleState(joyshockHandle); lastInputStack = new(inputStack);
wantClearInputStack = true;
//gyro and accelerometer for (int i = 0; i < actionStates.Length; i++)
joyImuStateLast = joyImuStateCurrent; {
joyImuStateCurrent = JslGetIMUState(joyshockHandle); actionStates[i].isDelta = false;
actionStates[i].debounce -= Time.deltaTime;
if (actionStates[i].debounce < 0)
actionStates[i].debounce = 0;
}
for (int i = 0; i < buttonStates.Length; i++)
{
buttonStates[i].isDelta = false;
}
//touchpad foreach(TimestampedState state in lastInputStack)
joyTouchStateLast = joyTouchStateCurrent; {
joyTouchStateCurrent = JslGetTouchState(joyshockHandle); joyBtStateCurrent = state.input;
//stick direction state for (int i = 0; i < actionStates.Length; i++)
{
int bt = GetButtonForSplitType(i);
if (bt != -1)
{
bool pressed = BitwiseUtils.WantCurrent(state.input.buttons, 1 << bt);
if (pressed != actionStates[i].pressed && !actionStates[i].isDelta)
{
if (actionStates[i].debounce <= 0)
{
actionStates[i].pressed = pressed;
actionStates[i].isDelta = true;
actionStates[i].dt = reportTime - state.timestamp;
}
actionStates[i].debounce = debounceTime;
}
}
}
for (int i = 0; i < buttonStates.Length; i++)
{
bool pressed = BitwiseUtils.WantCurrent(state.input.buttons, 1 << i);
if (pressed != buttonStates[i].pressed && !buttonStates[i].isDelta)
{
buttonStates[i].pressed = pressed;
buttonStates[i].isDelta = true;
buttonStates[i].dt = reportTime - state.timestamp;
}
}
}
//stick direction state, only handled on update
//split controllers will need to be rotated to compensate //split controllers will need to be rotated to compensate
//left rotates counterclockwise, right rotates clockwise, all by 90 degrees //left rotates counterclockwise, right rotates clockwise, all by 90 degrees
float xAxis = 0f; float xAxis = 0f;
@ -164,6 +488,22 @@ namespace HeavenStudio.InputSystem
directionStateCurrent |= ((xAxis >= stickDeadzone) ? (1 << ((int) InputDirection.Right)) : 0); directionStateCurrent |= ((xAxis >= stickDeadzone) ? (1 << ((int) InputDirection.Right)) : 0);
directionStateCurrent |= ((xAxis <= -stickDeadzone) ? (1 << ((int) InputDirection.Left)) : 0); directionStateCurrent |= ((xAxis <= -stickDeadzone) ? (1 << ((int) InputDirection.Left)) : 0);
//Debug.Log("stick direction: " + directionStateCurrent + "| x axis: " + xAxis + " y axis: " + yAxis); //Debug.Log("stick direction: " + directionStateCurrent + "| x axis: " + xAxis + " y axis: " + yAxis);
lastInputStack.Clear();
}
public override void OnSelected()
{
Task.Run(() => SelectionVibrate());
}
async void SelectionVibrate()
{
JslSetRumbleFrequency(GetHandle(), 0.5f, 0.5f, 80f, 160f);
await Task.Delay(50);
JslSetRumbleFrequency(GetHandle(), 0.75f, 0.75f, 160f, 320f);
await Task.Delay(50);
JslSetRumbleFrequency(GetHandle(), 0f, 0f, 0f, 0f);
} }
public override string GetDeviceName() public override string GetDeviceName()
@ -173,6 +513,24 @@ namespace HeavenStudio.InputSystem
return joyshockName; return joyshockName;
} }
public override string[] GetButtonNames()
{
switch (type)
{
case TypeProController:
return nsProButtonNames;
case TypeDualShock4:
return ps4ButtonNames;
case TypeDualSense:
return ps5ButtonNames;
default:
if (otherHalf == null)
return nsConButtonNames;
else
return nsProButtonNames;
}
}
public override InputFeatures GetFeatures() public override InputFeatures GetFeatures()
{ {
InputFeatures features = InputFeatures.Readable_MotionSensor | InputFeatures.Extra_Rumble | InputFeatures.Style_Pad | InputFeatures.Style_Baton; InputFeatures features = InputFeatures.Readable_MotionSensor | InputFeatures.Extra_Rumble | InputFeatures.Style_Pad | InputFeatures.Style_Baton;
@ -197,83 +555,138 @@ namespace HeavenStudio.InputSystem
return features; return features;
} }
public override bool GetIsConnected()
{
return JslStillConnected(joyshockHandle);
}
public override bool GetIsPoorConnection()
{
return false;
}
public override ControlBindings GetDefaultBindings()
{
ControlBindings binds = new ControlBindings();
switch (type)
{
case TypeJoyConLeft:
if (otherHalf == null)
binds.Pad = defaultMappingsL;
else
binds.Pad = defaultMappings;
break;
case TypeJoyConRight:
if (otherHalf == null)
binds.Pad = defaultMappingsR;
else
binds.Pad = defaultMappings;
break;
case TypeProController:
binds.Pad = defaultMappings;
break;
case TypeDualShock4:
binds.Pad = defaultMappings;
break;
case TypeDualSense:
binds.Pad = defaultMappings;
break;
}
return binds;
}
public override void ResetBindings()
{
currentBindings = GetDefaultBindings();
}
public override ControlBindings GetCurrentBindings()
{
return currentBindings;
}
public override void SetCurrentBindings(ControlBindings newBinds)
{
currentBindings = newBinds;
}
public override bool GetIsActionUnbindable(int action, ControlStyles style)
{
if (otherHalf == null)
{
switch (splitType)
{
case SplitLeft:
case SplitRight:
switch (style)
{
case ControlStyles.Pad:
return action is 0 or 1 or 2 or 3;
}
break;
}
}
return false;
}
public override int GetLastButtonDown() public override int GetLastButtonDown()
{ {
return BitwiseUtils.FirstSetBit(joyBtStateCurrent.buttons & joyBtStateLast.buttons); for (int i = 0; i < buttonStates.Length; i++)
{
if (buttonStates[i].pressed && buttonStates[i].isDelta)
{
return i;
}
}
return -1;
} }
public override KeyCode GetLastKeyDown() public override int GetLastActionDown()
{ {
return KeyCode.None; for (int i = 0; i < actionStates.Length; i++)
{
if (actionStates[i].pressed && actionStates[i].isDelta)
{
return i;
}
}
if (otherHalf != null)
{
return otherHalf.GetLastActionDown();
}
return -1;
} }
public override bool GetButton(int button) public override bool GetAction(int button)
{ {
int bt = 0; if (button == -1) {return false;}
if (otherHalf == null) if (otherHalf != null)
{ {
if (splitType == SplitLeft) return actionStates[button].pressed || otherHalf.actionStates[button].pressed;
{
bt = mappingsSplitLeft[button];
} }
else if (splitType == SplitRight) return actionStates[button].pressed;
{
bt = mappingsSplitRight[button];
}
else
{
bt = mappings[button];
}
return BitwiseUtils.WantCurrent(joyBtStateCurrent.buttons, 1 << bt);
}
bt = mappings[button];
return BitwiseUtils.WantCurrent(joyBtStateCurrent.buttons, 1 << bt) || BitwiseUtils.WantCurrent(otherHalf.joyBtStateCurrent.buttons, 1 << bt);
} }
public override bool GetButtonDown(int button) public override bool GetActionDown(int button, out double dt)
{ {
int bt = 0; if (button == -1) {dt = 0; return false;}
if (otherHalf == null) if (otherHalf != null && otherHalf.GetActionDown(button, out dt))
{ {
if (splitType == SplitLeft) return true;
{
bt = mappingsSplitLeft[button];
} }
else if (splitType == SplitRight) dt = actionStates[button].dt;
{ return actionStates[button].pressed && actionStates[button].isDelta;
bt = mappingsSplitRight[button];
}
else
{
bt = mappings[button];
}
return BitwiseUtils.WantCurrentAndNotLast(joyBtStateCurrent.buttons, joyBtStateLast.buttons, 1 << bt);
}
bt = mappings[button];
return BitwiseUtils.WantCurrentAndNotLast(joyBtStateCurrent.buttons, joyBtStateLast.buttons, 1 << bt) || BitwiseUtils.WantCurrentAndNotLast(otherHalf.joyBtStateCurrent.buttons, otherHalf.joyBtStateLast.buttons, 1 << bt);
} }
public override bool GetButtonUp(int button) public override bool GetActionUp(int button, out double dt)
{ {
int bt = 0; if (button == -1) {dt = 0; return false;}
if (otherHalf == null) if (otherHalf != null && otherHalf.GetActionUp(button, out dt))
{ {
if (splitType == SplitLeft) return true;
{
bt = mappingsSplitLeft[button];
} }
else if (splitType == SplitRight) dt = actionStates[button].dt;
{ return !actionStates[button].pressed && actionStates[button].isDelta;
bt = mappingsSplitRight[button];
}
else
{
bt = mappings[button];
}
return BitwiseUtils.WantNotCurrentAndLast(joyBtStateCurrent.buttons, joyBtStateLast.buttons, 1 << bt);
}
bt = mappings[button];
return BitwiseUtils.WantNotCurrentAndLast(joyBtStateCurrent.buttons, joyBtStateLast.buttons, 1 << bt) || BitwiseUtils.WantNotCurrentAndLast(otherHalf.joyBtStateCurrent.buttons, otherHalf.joyBtStateLast.buttons, 1 << bt);
} }
public override float GetAxis(InputAxis axis) public override float GetAxis(InputAxis axis)
@ -303,74 +716,89 @@ namespace HeavenStudio.InputSystem
public override bool GetHatDirection(InputDirection direction) public override bool GetHatDirection(InputDirection direction)
{ {
//todo: check analogue stick hat direction too
int bt; int bt;
switch (direction) switch (direction)
{ {
case InputDirection.Up: case InputDirection.Up:
bt = mappings[0]; bt = 0;
break; break;
case InputDirection.Down: case InputDirection.Down:
bt = mappings[1]; bt = 1;
break; break;
case InputDirection.Left: case InputDirection.Left:
bt = mappings[2]; bt = 2;
break; break;
case InputDirection.Right: case InputDirection.Right:
bt = mappings[3]; bt = 3;
break; break;
default: default:
return false; return false;
} }
return GetButton(bt) || BitwiseUtils.WantCurrent(directionStateCurrent, 1 << (int) direction); if (otherHalf != null)
{
return GetAction(bt) || BitwiseUtils.WantCurrent(otherHalf.directionStateCurrent, 1 << (int) direction) || BitwiseUtils.WantCurrent(directionStateCurrent, 1 << (int) direction);
}
return GetAction(bt) || BitwiseUtils.WantCurrent(directionStateCurrent, 1 << (int) direction);
} }
public override bool GetHatDirectionDown(InputDirection direction) public override bool GetHatDirectionDown(InputDirection direction, out double dt)
{ {
//todo: check analogue stick hat direction too
int bt; int bt;
switch (direction) switch (direction)
{ {
case InputDirection.Up: case InputDirection.Up:
bt = mappings[0]; bt = 0;
break; break;
case InputDirection.Down: case InputDirection.Down:
bt = mappings[1]; bt = 1;
break; break;
case InputDirection.Left: case InputDirection.Left:
bt = mappings[2]; bt = 2;
break; break;
case InputDirection.Right: case InputDirection.Right:
bt = mappings[3]; bt = 3;
break; break;
default: default:
dt = 0;
return false; return false;
} }
return GetButtonDown(bt) || BitwiseUtils.WantCurrentAndNotLast(directionStateCurrent, directionStateLast, 1 << (int) direction); bool btbool = GetActionDown(bt, out dt);
if (!btbool) dt = 0;
if (otherHalf != null)
{
return btbool || BitwiseUtils.WantCurrentAndNotLast(otherHalf.directionStateCurrent, otherHalf.directionStateLast, 1 << (int)direction) || BitwiseUtils.WantCurrentAndNotLast(directionStateCurrent, directionStateLast, 1 << (int)direction);
}
return btbool || BitwiseUtils.WantCurrentAndNotLast(directionStateCurrent, directionStateLast, 1 << (int) direction);
} }
public override bool GetHatDirectionUp(InputDirection direction) public override bool GetHatDirectionUp(InputDirection direction, out double dt)
{ {
//todo: check analogue stick hat direction too
int bt; int bt;
switch (direction) switch (direction)
{ {
case InputDirection.Up: case InputDirection.Up:
bt = mappings[0]; bt = 0;
break; break;
case InputDirection.Down: case InputDirection.Down:
bt = mappings[1]; bt = 1;
break; break;
case InputDirection.Left: case InputDirection.Left:
bt = mappings[2]; bt = 2;
break; break;
case InputDirection.Right: case InputDirection.Right:
bt = mappings[3]; bt = 3;
break; break;
default: default:
dt = 0;
return false; return false;
} }
return GetButtonUp(bt) || BitwiseUtils.WantNotCurrentAndLast(directionStateCurrent, directionStateLast, 1 << (int) direction); bool btbool = GetActionUp(bt, out dt);
if (!btbool) dt = 0;
if (otherHalf != null)
{
return btbool || BitwiseUtils.WantNotCurrentAndLast(otherHalf.directionStateCurrent, otherHalf.directionStateLast, 1 << (int) direction) || BitwiseUtils.WantNotCurrentAndLast(directionStateCurrent, directionStateLast, 1 << (int) direction);
}
return btbool || BitwiseUtils.WantNotCurrentAndLast(directionStateCurrent, directionStateLast, 1 << (int) direction);
} }
public override void SetPlayer(int? playerNum) public override void SetPlayer(int? playerNum)
@ -387,9 +815,9 @@ namespace HeavenStudio.InputSystem
int ledMask = (int) this.playerNum; int ledMask = (int) this.playerNum;
if (type == TypeDualSense) if (type == TypeDualSense)
{ {
if (playerNum <= 4) if (playerNum <= 5)
{ {
ledMask = DualSensePlayerMask[(int) this.playerNum]; ledMask = DualSensePlayerMask[Math.Max((int) this.playerNum + 1, 1)];
} }
} }
JslSetPlayerNumber(joyshockHandle, ledMask); JslSetPlayerNumber(joyshockHandle, ledMask);
@ -407,32 +835,38 @@ namespace HeavenStudio.InputSystem
if (otherHalf != null) if (otherHalf != null)
{ {
// gets the colour of the right controller if is split // gets the colour of the right controller if is split
return BitwiseUtils.IntToRgb(splitType == SplitRight ? JslGetControllerColour(joyshockHandle) : JslGetControllerColour(GetOtherHalf().GetHandle())); return BitwiseUtils.IntToRgb(splitType == SplitRight ? joySettings.bodyColour : GetOtherHalf().joySettings.bodyColour);
} }
return BitwiseUtils.IntToRgb(JslGetControllerColour(joyshockHandle)); return BitwiseUtils.IntToRgb(joySettings.bodyColour);
} }
public Color GetButtonColor() public Color GetButtonColor()
{ {
return BitwiseUtils.IntToRgb(JslGetControllerButtonColour(joyshockHandle)); if (joySettings.buttonColour == 0xFFFFFF)
return GetBodyColor();
return BitwiseUtils.IntToRgb(joySettings.buttonColour);
} }
public Color GetLeftGripColor() public Color GetLeftGripColor()
{ {
if (otherHalf != null) if (otherHalf != null)
{ {
return BitwiseUtils.IntToRgb(splitType == SplitLeft ? JslGetControllerColour(joyshockHandle) : JslGetControllerColour(GetOtherHalf().GetHandle())); return BitwiseUtils.IntToRgb(splitType == SplitLeft ? joySettings.lGripColour : GetOtherHalf().joySettings.lGripColour);
} }
return BitwiseUtils.IntToRgb(JslGetControllerLeftGripColour(joyshockHandle)); if (joySettings.lGripColour == 0xFFFFFF)
return GetBodyColor();
return BitwiseUtils.IntToRgb(joySettings.lGripColour);
} }
public Color GetRightGripColor() public Color GetRightGripColor()
{ {
if (otherHalf != null) if (otherHalf != null)
{ {
return BitwiseUtils.IntToRgb(splitType == SplitRight ? JslGetControllerColour(joyshockHandle) : JslGetControllerColour(GetOtherHalf().GetHandle())); return BitwiseUtils.IntToRgb(splitType == SplitRight ? joySettings.rGripColour : GetOtherHalf().joySettings.rGripColour);
} }
return BitwiseUtils.IntToRgb(JslGetControllerRightGripColour(joyshockHandle)); if (joySettings.rGripColour == 0xFFFFFF)
return GetBodyColor();
return BitwiseUtils.IntToRgb(joySettings.rGripColour);
} }
public Color GetLightbarColour() public Color GetLightbarColour()

View file

@ -1,38 +1,74 @@
using System;
using System.Linq;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using static JSL; using static JSL;
namespace HeavenStudio.InputSystem.Loaders
{
public static class InputKeyboardInitializer
{
[LoadOrder(0)]
public static InputController[] Initialize()
{
PlayerInput.PlayerInputRefresh.Add(Refresh);
InputKeyboard keyboard = new InputKeyboard();
keyboard.SetPlayer(1);
keyboard.InitializeController();
return new InputController[] { keyboard };
}
public static InputController[] Refresh()
{
InputKeyboard keyboard = new InputKeyboard();
keyboard.SetPlayer(1);
keyboard.InitializeController();
return new InputController[] { keyboard };
}
}
}
namespace HeavenStudio.InputSystem namespace HeavenStudio.InputSystem
{ {
public class InputKeyboard : InputController public class InputKeyboard : InputController
{ {
static KeyCode[] keyCodes = (KeyCode[]) System.Enum.GetValues(typeof(UnityEngine.KeyCode)); private static readonly KeyCode[] keyCodes = Enum.GetValues(typeof(KeyCode))
.Cast<KeyCode>()
.Where(k => ((int)k < (int)KeyCode.Mouse0))
.ToArray();
//FUTURE: remappable controls static ControlBindings defaultBindings {
//KeyCode[] mappings = new KeyCode[Enum.GetNames(typeof(ButtonsPad)).Length]; get
KeyCode[] mappings = new KeyCode[]
{ {
KeyCode.W, // dpad up return new ControlBindings()
KeyCode.S, // dpad down {
KeyCode.A, // dpad left Pad = new int[]
KeyCode.D, // dpad right {
KeyCode.K, // south face button (int)KeyCode.W,
KeyCode.J, // east face button (int)KeyCode.S,
KeyCode.I, // west face button (int)KeyCode.A,
KeyCode.U, // north face button (int)KeyCode.D,
KeyCode.C, // left shoulder button (int)KeyCode.J,
KeyCode.N, // right shoulder button (int)KeyCode.K,
KeyCode.Escape, // start button (int)KeyCode.I,
(int)KeyCode.U,
(int)KeyCode.E,
(int)KeyCode.U,
(int)KeyCode.Escape,
},
}; };
}
}
InputDirection hatDirectionCurrent; InputDirection hatDirectionCurrent;
InputDirection hatDirectionLast; InputDirection hatDirectionLast;
public override void InitializeController() public override void InitializeController()
{ {
//FUTURE: remappable controls LoadBindings();
} }
public override void UpdateState() public override void UpdateState()
@ -40,43 +76,104 @@ namespace HeavenStudio.InputSystem
// Update the state of the controller // Update the state of the controller
} }
public override void OnSelected()
{
}
public override string GetDeviceName() public override string GetDeviceName()
{ {
return "Keyboard"; return "Keyboard";
} }
public override string[] GetButtonNames()
{
string[] names = new string[(int)KeyCode.Mouse0];
for (int i = 0; i < keyCodes.Length; i++)
{
names[(int)keyCodes[i]] = keyCodes[i].ToString();
}
return names;
}
public override InputFeatures GetFeatures() public override InputFeatures GetFeatures()
{ {
return InputFeatures.Readable_StringInput | InputFeatures.Style_Pad | InputFeatures.Style_Baton; return InputFeatures.Readable_StringInput | InputFeatures.Style_Pad | InputFeatures.Style_Baton;
} }
public override bool GetIsConnected()
{
return true;
}
public override bool GetIsPoorConnection()
{
return false;
}
public override ControlBindings GetDefaultBindings()
{
return defaultBindings;
}
public override void ResetBindings()
{
currentBindings = GetDefaultBindings();
}
public override ControlBindings GetCurrentBindings()
{
return currentBindings;
}
public override void SetCurrentBindings(ControlBindings newBinds)
{
currentBindings = newBinds;
}
public override bool GetIsActionUnbindable(int action, ControlStyles style)
{
return false;
}
public override int GetLastButtonDown() public override int GetLastButtonDown()
{ {
return 0; if (Input.anyKeyDown)
{
for (KeyCode i = keyCodes[1]; i <= KeyCode.Menu; i++)
{
if (Input.GetKeyDown(i))
return (int)i;
}
}
return (int)KeyCode.None;
} }
public override KeyCode GetLastKeyDown() public override int GetLastActionDown()
{ {
for(KeyCode i = keyCodes[1]; i <= KeyCode.Menu; i++) { for (int i = 0; i < BINDS_MAX; i++)
if (Input.GetKeyDown(i)) {
if (Input.GetKeyDown((KeyCode)currentBindings.Pad[i]))
return i; return i;
} }
return KeyCode.None; return -1;
} }
public override bool GetButton(int button) public override bool GetAction(int button)
{ {
return Input.GetKey(mappings[button]); return Input.GetKey((KeyCode)currentBindings.Pad[button]);
} }
public override bool GetButtonDown(int button) public override bool GetActionDown(int button, out double dt)
{ {
return Input.GetKeyDown(mappings[button]); dt = 0;
return Input.GetKeyDown((KeyCode)currentBindings.Pad[button]);
} }
public override bool GetButtonUp(int button) public override bool GetActionUp(int button, out double dt)
{ {
return Input.GetKeyUp(mappings[button]); dt = 0;
return Input.GetKeyUp((KeyCode)currentBindings.Pad[button]);
} }
public override float GetAxis(InputAxis axis) public override float GetAxis(InputAxis axis)
@ -90,47 +187,49 @@ namespace HeavenStudio.InputSystem
switch (direction) switch (direction)
{ {
case InputDirection.Up: case InputDirection.Up:
return Input.GetKey(mappings[0]); return Input.GetKey((KeyCode)currentBindings.Pad[0]);
case InputDirection.Down: case InputDirection.Down:
return Input.GetKey(mappings[1]); return Input.GetKey((KeyCode)currentBindings.Pad[1]);
case InputDirection.Left: case InputDirection.Left:
return Input.GetKey(mappings[2]); return Input.GetKey((KeyCode)currentBindings.Pad[2]);
case InputDirection.Right: case InputDirection.Right:
return Input.GetKey(mappings[3]); return Input.GetKey((KeyCode)currentBindings.Pad[3]);
default: default:
return false; return false;
} }
} }
public override bool GetHatDirectionDown(InputDirection direction) public override bool GetHatDirectionDown(InputDirection direction, out double dt)
{ {
dt = 0;
switch (direction) switch (direction)
{ {
case InputDirection.Up: case InputDirection.Up:
return Input.GetKeyDown(mappings[0]); return Input.GetKeyDown((KeyCode)currentBindings.Pad[0]);
case InputDirection.Down: case InputDirection.Down:
return Input.GetKeyDown(mappings[1]); return Input.GetKeyDown((KeyCode)currentBindings.Pad[1]);
case InputDirection.Left: case InputDirection.Left:
return Input.GetKeyDown(mappings[2]); return Input.GetKeyDown((KeyCode)currentBindings.Pad[2]);
case InputDirection.Right: case InputDirection.Right:
return Input.GetKeyDown(mappings[3]); return Input.GetKeyDown((KeyCode)currentBindings.Pad[3]);
default: default:
return false; return false;
} }
} }
public override bool GetHatDirectionUp(InputDirection direction) public override bool GetHatDirectionUp(InputDirection direction, out double dt)
{ {
dt = 0;
switch (direction) switch (direction)
{ {
case InputDirection.Up: case InputDirection.Up:
return Input.GetKeyUp(mappings[0]); return Input.GetKeyUp((KeyCode)currentBindings.Pad[0]);
case InputDirection.Down: case InputDirection.Down:
return Input.GetKeyUp(mappings[1]); return Input.GetKeyUp((KeyCode)currentBindings.Pad[1]);
case InputDirection.Left: case InputDirection.Left:
return Input.GetKeyUp(mappings[2]); return Input.GetKeyUp((KeyCode)currentBindings.Pad[2]);
case InputDirection.Right: case InputDirection.Right:
return Input.GetKeyUp(mappings[3]); return Input.GetKeyUp((KeyCode)currentBindings.Pad[3]);
default: default:
return false; return false;
} }

View file

@ -1,6 +1,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using System.IO;
namespace HeavenStudio.InputSystem namespace HeavenStudio.InputSystem
{ {
@ -10,34 +11,6 @@ namespace HeavenStudio.InputSystem
/// </summary> /// </summary>
public abstract class InputController public abstract class InputController
{ {
//Buttons and Axis used by most controllers
public enum InputButtons : int
{
ButtonPadUp = 0,
ButtonPadDown = 1,
ButtonPadLeft = 2,
ButtonPadRight = 3,
ButtonPlus = 4,
ButtonOptions = 4,
ButtonMinus = 5,
ButtonShare = 5,
ButtonLClick = 6,
ButtonRClick = 7,
ButtonL = 8,
ButtonR = 9,
ButtonZL = 10,
ButtonZR = 11,
ButtonFaceS = 12,
ButtonFaceE = 13,
ButtonFaceW = 14,
ButtonFaceN = 15,
ButtonHome = 16,
ButtonPS = 16,
ButtonCapture = 17,
ButtonTouchpadClick = 17,
ButtonSL = 18,
ButtonSR = 19,
}
public enum InputAxis : int public enum InputAxis : int
{ {
AxisLTrigger = 4, AxisLTrigger = 4,
@ -97,50 +70,65 @@ namespace HeavenStudio.InputSystem
{ {
Pad, Pad,
Baton, Baton,
Touch Touch,
Move
} }
public const int BINDS_MAX = 12; //maximum number of binds per controller
//buttons used in Heaven Studio gameplay (Pad Style) //buttons used in Heaven Studio gameplay (Pad Style)
public enum ButtonsPad : int public enum ActionsPad : int
{ {
PadUp = 0, Up = 0,
PadDown = 1, Down = 1,
PadLeft = 2, Left = 2,
PadRight = 3, Right = 3,
PadS = 4, South = 4,
PadE = 5, East = 5,
PadW = 6, West = 6,
PadN = 7, North = 7,
PadL = 8, L = 8,
PadR = 9, R = 9,
PadPause = 10, Pause = 10,
} }
//FUTURE: buttons used in Heaven Studio gameplay ("Form Baton" / WiiMote Style) //FUTURE: buttons used in Heaven Studio gameplay ("Form Baton" / WiiMote Style)
public enum ButtonsBaton : int public enum ActionsBaton : int
{ {
BatonS = 0, //-- all these... South = 0, //-- all these...
BatonE = 1, // | East = 1, // |
BatonW = 2, // | West = 2, // |
BatonN = 3, //-- North = 3, //--
BatonA = 4, // < ...map to this, but are directional Face = 4, // < ...are also equivalent to this, but with added directionality
BatonB = 5, // should never be used alone Trigger = 5, // should never be used alone, but still bindable separately (controller logic should handle confirming & timestamping face + trigger input)
Baton1 = 6, Up = 6, // Wiimote 1
Baton2 = 7, Down = 7, // Wiimote 2
BatonPause = 8, Pause = 8,
} }
//FUTURE: buttons used in Heaven Studio gameplay (Touch Style) //FUTURE: buttons used in Heaven Studio gameplay (Touch Style)
public enum ButtonsTouch : int public enum ActionsTouch : int
{ {
TouchL = 0, Tap = 0, // flicks are handled like a motion, don't have a binding
TouchR = 1, Left = 1, // also maps to tap, but with directionality (tap the left side of the panel)
TouchTap = 2, Right = 2, // also maps to tap, but with directionality (tap the right side of the panel)
TouchFlick = 3, ButtonL = 3,
TouchButtonL = 4, ButtonR = 4,
TouchButtonR = 4, Pause = 5,
} }
[System.Serializable]
public struct ControlBindings
{
public int[] Pad;
public int[] Baton;
public int[] Touch;
}
// FUTURE: Move Style needs to be implemented per-game (maybe implement checks for common actions?)
protected ControlBindings currentBindings;
protected int? playerNum; protected int? playerNum;
protected int directionStateCurrent = 0; protected int directionStateCurrent = 0;
protected int directionStateLast = 0; protected int directionStateLast = 0;
@ -148,21 +136,144 @@ namespace HeavenStudio.InputSystem
public abstract void InitializeController(); public abstract void InitializeController();
public abstract void UpdateState(); // Update the state of the controller public abstract void UpdateState(); // Update the state of the controller
public abstract void OnSelected();
public abstract string GetDeviceName(); // Get the name of the controller public abstract string GetDeviceName(); // Get the name of the controller
public abstract string[] GetButtonNames(); // Get the names of the buttons on the controller
public abstract InputFeatures GetFeatures(); // Get the features of the controller public abstract InputFeatures GetFeatures(); // Get the features of the controller
public abstract bool GetIsConnected();
public abstract bool GetIsPoorConnection();
public abstract int GetLastButtonDown(); // Get the last button down public void SaveBindings()
public abstract KeyCode GetLastKeyDown(); // Get the last key down (used for keyboards and other devices that use Keycode) {
public abstract bool GetButton(int button); // is button currently pressed? if (!Directory.Exists($"{Application.persistentDataPath}/controls"))
public abstract bool GetButtonDown(int button); // is button just pressed? Directory.CreateDirectory($"{Application.persistentDataPath}/controls");
public abstract bool GetButtonUp(int button); // is button just released? string path = $"{Application.persistentDataPath}/controls/{GetDeviceName()}.json";
public abstract float GetAxis(InputAxis axis); // Get the value of an axis string json = JsonUtility.ToJson(currentBindings);
public abstract bool GetHatDirection(InputDirection direction); // is direction active? File.WriteAllText(path, json);
public abstract bool GetHatDirectionDown(InputDirection direction); // direction just became active? }
public abstract bool GetHatDirectionUp(InputDirection direction); // direction just became inactive?
public abstract void SetPlayer(int? playerNum); // Set the player number (starts at 1, set to -1 or null for no player) public void LoadBindings()
public abstract int? GetPlayer(); // Get the player number (null if no player) {
string path = $"{Application.persistentDataPath}/controls/{GetDeviceName()}.json";
if (File.Exists(path))
{
string json = File.ReadAllText(path);
currentBindings = JsonUtility.FromJson<ControlBindings>(json);
}
else
{
ResetBindings();
}
}
/// <summary>
/// Gets the controller's default mappings
/// </summary>
/// <returns></returns>
public abstract ControlBindings GetDefaultBindings();
/// <summary>
/// Resets the controller's mappings to default
/// </summary>
public abstract void ResetBindings();
/// <summary>
/// Gets the controller's current mappings
/// </summary>
/// <returns></returns>
public abstract ControlBindings GetCurrentBindings();
/// <summary>
/// Sets the controller's current mappings
/// </summary>
/// <param name="newBinds"></param>
public abstract void SetCurrentBindings(ControlBindings newBinds);
/// <summary>
/// Whether a given action can have be rebount
/// </summary>
/// <param name="action">action to check</param>
/// <param name="style">control style to check</param>
/// <returns></returns>
public abstract bool GetIsActionUnbindable(int action, ControlStyles style);
/// <summary>
/// Gets the last pressed physical button
/// </summary>
/// <returns></returns>
public abstract int GetLastButtonDown();
/// <summary>
/// Gets the last pressed virtual action
/// </summary>
/// <returns></returns>
public abstract int GetLastActionDown();
/// <summary>
/// True if the given action is being held
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public abstract bool GetAction(int action);
/// <summary>
/// True if the action was just pressed this Update
/// </summary>
/// <param name="action"></param>
/// <param name="dt">time since the reported event, use to compensate for controller delays</param>
/// <returns></returns>
public abstract bool GetActionDown(int action, out double dt);
/// <summary>
/// True if the action was just released this Update
/// </summary>
/// <param name="action"></param>
/// <param name="dt">time since the reported event, use to compensate for controller delays</param>
/// <returns></returns>
public abstract bool GetActionUp(int action, out double dt);
/// <summary>
/// Get the value of an analogue axis
/// </summary>
/// <param name="axis"></param>
/// <returns></returns>
public abstract float GetAxis(InputAxis axis);
/// <summary>
/// True if the current direction is active
/// </summary>
/// <param name="direction"></param>
/// <returns></returns>
public abstract bool GetHatDirection(InputDirection direction);
/// <summary>
/// True if the current direction just became active this Update
/// </summary>
/// <param name="direction"></param>
/// <param name="dt">time since the reported event, use to compensate for controller delays</param>
/// <returns></returns>
public abstract bool GetHatDirectionDown(InputDirection direction, out double dt);
/// <summary>
/// True if the current direction just became inactive this Update
/// </summary>
/// <param name="direction"></param>
/// <param name="dt">time since the reported event, use to compensate for controller delays</param>
/// <returns></returns>
public abstract bool GetHatDirectionUp(InputDirection direction, out double dt);
/// <summary>
/// Sets the player number (starts at 1, set to -1 or null for no player)
/// </summary>
/// <param name="playerNum"></param>
public abstract void SetPlayer(int? playerNum);
/// <summary>
/// Gets the player number (starts at 1, -1 or null for no player)
/// </summary>
/// <returns></returns>
public abstract int? GetPlayer();
//public abstract Sprite GetDisplayIcon(); //"big icon" for the controller in the settings menu //public abstract Sprite GetDisplayIcon(); //"big icon" for the controller in the settings menu
//public abstract Sprite GetPlaybackIcon(); //"small icon" for the controller during playback //public abstract Sprite GetPlaybackIcon(); //"small icon" for the controller during playback

View file

@ -1,3 +1,7 @@
using System;
using System.Linq;
using System.Reflection;
using System.IO;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -5,6 +9,16 @@ using HeavenStudio.InputSystem;
using static JSL; using static JSL;
namespace HeavenStudio.InputSystem
{
public class LoadOrder : Attribute {
public int Order { get; set; }
public LoadOrder(int order) {
Order = order;
}
}
}
namespace HeavenStudio namespace HeavenStudio
{ {
public class PlayerInput public class PlayerInput
@ -15,63 +29,60 @@ namespace HeavenStudio
public const int DOWN = 2; public const int DOWN = 2;
public const int LEFT = 3; public const int LEFT = 3;
///////////////////////////////
////TEMPORARY JSL FUNCTIONS////
///////////////////////////////
static int jslDevicesFound = 0;
static int jslDevicesConnected = 0;
static int[] jslDeviceHandles;
static List<InputController> inputDevices; static List<InputController> inputDevices;
static InputController.ControlStyles currentControlStyle = InputController.ControlStyles.Pad;
public delegate InputController[] InputControllerInitializer();
public delegate void InputControllerDispose();
public static event InputControllerDispose PlayerInputCleanUp;
public delegate InputController[] InputControllerRefresh();
public static List<InputControllerRefresh> PlayerInputRefresh;
static List<InputControllerInitializer> loadRunners;
static void BuildLoadRunnerList() {
PlayerInputRefresh = new();
loadRunners = System.Reflection.Assembly.GetExecutingAssembly()
.GetTypes()
.Where(x => x.Namespace == "HeavenStudio.InputSystem.Loaders" && x.GetMethod("Initialize", BindingFlags.Public | BindingFlags.Static) != null)
.Select(t => (InputControllerInitializer) Delegate.CreateDelegate(
typeof(InputControllerInitializer),
null,
t.GetMethod("Initialize", BindingFlags.Public | BindingFlags.Static),
false
))
.ToList();
loadRunners.Sort((x, y) => x.Method.GetCustomAttribute<LoadOrder>().Order.CompareTo(y.Method.GetCustomAttribute<LoadOrder>().Order));
}
public static int InitInputControllers() public static int InitInputControllers()
{ {
inputDevices = new List<InputController>(); inputDevices = new List<InputController>();
//Keyboard setup
InputKeyboard keyboard = new InputKeyboard();
keyboard.SetPlayer(1);
keyboard.InitializeController();
inputDevices.Add(keyboard);
//end Keyboard setup
//JoyShock setup BuildLoadRunnerList();
Debug.Log("Flushing possible JoyShocks..."); foreach (InputControllerInitializer runner in loadRunners) {
DisconnectJoyshocks(); InputController[] controllers = runner();
if (controllers != null) {
jslDevicesFound = JslConnectDevices(); inputDevices.AddRange(controllers);
if (jslDevicesFound > 0)
{
jslDeviceHandles = new int[jslDevicesFound];
jslDevicesConnected = JslGetConnectedDeviceHandles(jslDeviceHandles, jslDevicesFound);
if (jslDevicesConnected < jslDevicesFound)
{
Debug.Log("Found " + jslDevicesFound + " JoyShocks, but only " + jslDevicesConnected + " are connected.");
}
else
{
Debug.Log("Found " + jslDevicesFound + " JoyShocks.");
Debug.Log("Connected " + jslDevicesConnected + " JoyShocks.");
}
foreach (int i in jslDeviceHandles)
{
Debug.Log("Setting up JoyShock: ( Handle " + i + ", type " + JslGetControllerType(i) + " )");
InputJoyshock joyshock = new InputJoyshock(i);
joyshock.InitializeController();
joyshock.SetPlayer(inputDevices.Count + 1);
inputDevices.Add(joyshock);
} }
} }
else
{ return inputDevices.Count;
Debug.Log("No JoyShocks found.");
} }
//end JoyShock setup
//TODO: XInput setup (boo)
//end XInput setup
public static int RefreshInputControllers()
{
inputDevices = new List<InputController>();
if (PlayerInputRefresh != null) {
foreach (InputControllerRefresh runner in PlayerInputRefresh) {
InputController[] controllers = runner();
if (controllers != null) {
inputDevices.AddRange(controllers);
}
}
}
return inputDevices.Count; return inputDevices.Count;
} }
@ -159,28 +170,15 @@ namespace HeavenStudio
} }
} }
public static void DisconnectJoyshocks() public static void CleanUp()
{ {
if (jslDeviceHandles != null && jslDevicesConnected > 0 && jslDeviceHandles.Length > 0) PlayerInputCleanUp?.Invoke();
{
foreach (InputController i in inputDevices)
{
if (typeof(InputJoyshock) == i.GetType())
{
InputJoyshock joy = (InputJoyshock)i;
joy.DisconnectJoyshock();
}
}
}
JslDisconnectAndDisposeAll();
jslDevicesFound = 0;
jslDevicesConnected = 0;
} }
// The autoplay isn't activated AND // The autoplay isn't activated AND
// The song is actually playing AND // The song is actually playing AND
// The GameManager allows you to Input // The GameManager allows you to Input
public static bool playerHasControl() public static bool PlayerHasControl()
{ {
return !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput; return !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
} }
@ -194,39 +192,63 @@ namespace HeavenStudio
public static bool Pressed(bool includeDPad = false) public static bool Pressed(bool includeDPad = false)
{ {
bool keyDown = GetInputController(1).GetButtonDown((int) InputController.ButtonsPad.PadE) || (includeDPad && GetAnyDirectionDown()); bool keyDown = GetInputController(1).GetActionDown((int) InputController.ActionsPad.East, out _) || (includeDPad && GetAnyDirectionDown());
return keyDown && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
}
public static bool Pressed(out double dt, bool includeDPad = false)
{
bool keyDown = GetInputController(1).GetActionDown((int) InputController.ActionsPad.East, out dt) || (includeDPad && GetAnyDirectionDown());
return keyDown && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput; return keyDown && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
} }
public static bool PressedUp(bool includeDPad = false) public static bool PressedUp(bool includeDPad = false)
{ {
bool keyUp = GetInputController(1).GetButtonUp((int) InputController.ButtonsPad.PadE) || (includeDPad && GetAnyDirectionUp()); bool keyUp = GetInputController(1).GetActionUp((int) InputController.ActionsPad.East, out _) || (includeDPad && GetAnyDirectionUp());
return keyUp && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
}
public static bool PressedUp(out double dt, bool includeDPad = false)
{
bool keyUp = GetInputController(1).GetActionUp((int) InputController.ActionsPad.East, out dt) || (includeDPad && GetAnyDirectionUp());
return keyUp && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput; return keyUp && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
} }
public static bool Pressing(bool includeDPad = false) public static bool Pressing(bool includeDPad = false)
{ {
bool pressing = GetInputController(1).GetButton((int) InputController.ButtonsPad.PadE) || (includeDPad && GetAnyDirection()); bool pressing = GetInputController(1).GetAction((int) InputController.ActionsPad.East) || (includeDPad && GetAnyDirection());
return pressing && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput; return pressing && !GameManager.instance.autoplay && Conductor.instance.isPlaying && GameManager.instance.canInput;
} }
public static bool AltPressed() public static bool AltPressed()
{ {
bool down = GetInputController(1).GetButtonDown((int) InputController.ButtonsPad.PadS); bool down = GetInputController(1).GetActionDown((int) InputController.ActionsPad.South, out _);
return down && playerHasControl(); return down && PlayerHasControl();
}
public static bool AltPressed(out double dt)
{
bool down = GetInputController(1).GetActionDown((int) InputController.ActionsPad.South, out dt);
return down && PlayerHasControl();
} }
public static bool AltPressedUp() public static bool AltPressedUp()
{ {
bool up = GetInputController(1).GetButtonUp((int) InputController.ButtonsPad.PadS); bool up = GetInputController(1).GetActionUp((int) InputController.ActionsPad.South, out _);
return up && playerHasControl(); return up && PlayerHasControl();
}
public static bool AltPressedUp(out double dt)
{
bool up = GetInputController(1).GetActionUp((int) InputController.ActionsPad.South, out dt);
return up && PlayerHasControl();
} }
public static bool AltPressing() public static bool AltPressing()
{ {
bool pressing = GetInputController(1).GetButton((int) InputController.ButtonsPad.PadS); bool pressing = GetInputController(1).GetAction((int) InputController.ActionsPad.South);
return pressing && playerHasControl(); return pressing && PlayerHasControl();
} }
//Directions //Directions
@ -234,23 +256,45 @@ namespace HeavenStudio
public static bool GetAnyDirectionDown() public static bool GetAnyDirectionDown()
{ {
InputController c = GetInputController(1); InputController c = GetInputController(1);
return (c.GetHatDirectionDown((InputController.InputDirection) UP) return (c.GetHatDirectionDown((InputController.InputDirection) UP, out _)
|| c.GetHatDirectionDown((InputController.InputDirection) DOWN) || c.GetHatDirectionDown((InputController.InputDirection) DOWN, out _)
|| c.GetHatDirectionDown((InputController.InputDirection) LEFT) || c.GetHatDirectionDown((InputController.InputDirection) LEFT, out _)
|| c.GetHatDirectionDown((InputController.InputDirection) RIGHT) || c.GetHatDirectionDown((InputController.InputDirection) RIGHT, out _)
) && playerHasControl(); ) && PlayerHasControl();
}
public static bool GetAnyDirectionDown(out double dt)
{
InputController c = GetInputController(1);
bool r1 = c.GetHatDirectionDown((InputController.InputDirection)UP, out double d1);
bool r2 = c.GetHatDirectionDown((InputController.InputDirection)DOWN, out double d2);
bool r3 = c.GetHatDirectionDown((InputController.InputDirection)LEFT, out double d3);
bool r4 = c.GetHatDirectionDown((InputController.InputDirection)RIGHT, out double d4);
bool r = (r1 || r2 || r3 || r4) && PlayerHasControl();
dt = Math.Max(Math.Max(Math.Max(d1, d2), d3), d4);
return r;
} }
public static bool GetAnyDirectionUp() public static bool GetAnyDirectionUp()
{ {
InputController c = GetInputController(1); InputController c = GetInputController(1);
return (c.GetHatDirectionUp((InputController.InputDirection) UP) return (c.GetHatDirectionUp((InputController.InputDirection) UP, out _)
|| c.GetHatDirectionUp((InputController.InputDirection) DOWN) || c.GetHatDirectionUp((InputController.InputDirection) DOWN, out _)
|| c.GetHatDirectionUp((InputController.InputDirection) LEFT) || c.GetHatDirectionUp((InputController.InputDirection) LEFT, out _)
|| c.GetHatDirectionUp((InputController.InputDirection) RIGHT) || c.GetHatDirectionUp((InputController.InputDirection) RIGHT, out _)
) && playerHasControl(); ) && PlayerHasControl();
}
public static bool GetAnyDirectionUp(out double dt)
{
InputController c = GetInputController(1);
bool r1 = c.GetHatDirectionUp((InputController.InputDirection)UP, out double d1);
bool r2 = c.GetHatDirectionUp((InputController.InputDirection)DOWN, out double d2);
bool r3 = c.GetHatDirectionUp((InputController.InputDirection)LEFT, out double d3);
bool r4 = c.GetHatDirectionUp((InputController.InputDirection)RIGHT, out double d4);
bool r = (r1 || r2 || r3 || r4) && PlayerHasControl();
dt = Math.Max(Math.Max(Math.Max(d1, d2), d3), d4);
return r;
} }
public static bool GetAnyDirection() public static bool GetAnyDirection()
@ -260,23 +304,32 @@ namespace HeavenStudio
|| c.GetHatDirection((InputController.InputDirection) DOWN) || c.GetHatDirection((InputController.InputDirection) DOWN)
|| c.GetHatDirection((InputController.InputDirection) LEFT) || c.GetHatDirection((InputController.InputDirection) LEFT)
|| c.GetHatDirection((InputController.InputDirection) RIGHT) || c.GetHatDirection((InputController.InputDirection) RIGHT)
) && playerHasControl(); ) && PlayerHasControl();
} }
public static bool GetSpecificDirection(int direction) public static bool GetSpecificDirection(int direction)
{ {
return GetInputController(1).GetHatDirection((InputController.InputDirection) direction) && playerHasControl(); return GetInputController(1).GetHatDirection((InputController.InputDirection) direction) && PlayerHasControl();
} }
public static bool GetSpecificDirectionDown(int direction) public static bool GetSpecificDirectionDown(int direction)
{ {
return GetInputController(1).GetHatDirectionDown((InputController.InputDirection) direction) && playerHasControl(); return GetInputController(1).GetHatDirectionDown((InputController.InputDirection) direction, out _) && PlayerHasControl();
} }
public static bool GetSpecificDirectionUp(int direction) public static bool GetSpecificDirectionUp(int direction)
{ {
return GetInputController(1).GetHatDirectionUp((InputController.InputDirection) direction) && playerHasControl(); return GetInputController(1).GetHatDirectionUp((InputController.InputDirection) direction, out _) && PlayerHasControl();
}
public static bool GetSpecificDirectionDown(int direction, out double dt)
{
return GetInputController(1).GetHatDirectionDown((InputController.InputDirection) direction, out dt) && PlayerHasControl();
}
public static bool GetSpecificDirectionUp(int direction, out double dt)
{
return GetInputController(1).GetHatDirectionUp((InputController.InputDirection) direction, out dt) && PlayerHasControl();
} }
} }
} }

View file

@ -41,13 +41,13 @@ namespace HeavenStudio.Common
{ {
if (cond.songPositionInBeatsAsDouble > starStart && state == StarState.In) if (cond.songPositionInBeatsAsDouble > starStart && state == StarState.In)
{ {
double offset = cond.SecsToBeats(Minigame.AceStartTime()-1, cond.GetBpmAtBeat(StarTargetTime)); double offset = cond.SecsToBeats(Minigame.AceEarlyTime()-1, cond.GetBpmAtBeat(StarTargetTime));
if (cond.songPositionInBeatsAsDouble <= starStart + starLength + offset) if (cond.songPositionInBeatsAsDouble <= starStart + starLength + offset)
starAnim.DoScaledAnimation("StarIn", starStart, starLength + (float)offset); starAnim.DoScaledAnimation("StarIn", starStart, starLength + (float)offset);
else else
starAnim.Play("StarIn", -1, 1f); starAnim.Play("StarIn", -1, 1f);
offset = cond.SecsToBeats(Minigame.AceEndTime()-1, cond.GetBpmAtBeat(StarTargetTime)); offset = cond.SecsToBeats(Minigame.AceLateTime()-1, cond.GetBpmAtBeat(StarTargetTime));
if (cond.songPositionInBeatsAsDouble > starStart + starLength + offset) if (cond.songPositionInBeatsAsDouble > starStart + starLength + offset)
KillStar(); KillStar();
} }
@ -94,8 +94,8 @@ namespace HeavenStudio.Common
public bool DoStarJust() public bool DoStarJust()
{ {
if (state == StarState.In && if (state == StarState.In &&
cond.songPositionInBeatsAsDouble >= StarTargetTime + cond.SecsToBeats(Minigame.AceStartTime()-1, cond.GetBpmAtBeat(StarTargetTime)) && cond.songPositionInBeatsAsDouble >= StarTargetTime + cond.SecsToBeats(Minigame.AceEarlyTime()-1, cond.GetBpmAtBeat(StarTargetTime)) &&
cond.songPositionInBeatsAsDouble <= StarTargetTime + cond.SecsToBeats(Minigame.AceEndTime()-1, cond.GetBpmAtBeat(StarTargetTime)) cond.songPositionInBeatsAsDouble <= StarTargetTime + cond.SecsToBeats(Minigame.AceLateTime()-1, cond.GetBpmAtBeat(StarTargetTime))
) )
{ {
state = StarState.Collected; state = StarState.Collected;

View file

@ -87,12 +87,12 @@ namespace HeavenStudio.Common
// SetArrowPos(time); // SetArrowPos(time);
// no Clamp() because double // no Clamp() because double
time = System.Math.Max(Minigame.EarlyTime(), System.Math.Min(Minigame.EndTime(), time)); time = System.Math.Max(Minigame.NgEarlyTime(), System.Math.Min(Minigame.NgLateTime(), time));
if (time >= Minigame.AceStartTime() && time <= Minigame.AceEndTime()) if (time >= Minigame.AceEarlyTime() && time <= Minigame.AceLateTime())
{ {
type = Rating.Just; type = Rating.Just;
frac = (float)((time - Minigame.AceStartTime()) / (Minigame.AceEndTime() - Minigame.AceStartTime())); frac = (float)((time - Minigame.AceEarlyTime()) / (Minigame.AceLateTime() - Minigame.AceEarlyTime()));
y = barJustTransform.localScale.y * frac - (barJustTransform.localScale.y * 0.5f); y = barJustTransform.localScale.y * frac - (barJustTransform.localScale.y * 0.5f);
} }
else else
@ -100,32 +100,32 @@ namespace HeavenStudio.Common
if (time > 1.0) if (time > 1.0)
{ {
// goes "down" // goes "down"
if (time <= Minigame.LateTime()) if (time <= Minigame.JustLateTime())
{ {
type = Rating.OK; type = Rating.OK;
frac = (float)((time - Minigame.AceEndTime()) / (Minigame.LateTime() - Minigame.AceEndTime())); frac = (float)((time - Minigame.AceLateTime()) / (Minigame.JustLateTime() - Minigame.AceLateTime()));
y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * frac) + barJustTransform.localScale.y; y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * frac) + barJustTransform.localScale.y;
} }
else else
{ {
type = Rating.NG; type = Rating.NG;
frac = (float)((time - Minigame.LateTime()) / (Minigame.EndTime() - Minigame.LateTime())); frac = (float)((time - Minigame.JustLateTime()) / (Minigame.NgLateTime() - Minigame.JustLateTime()));
y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * frac) + barOKTransform.localScale.y; y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * frac) + barOKTransform.localScale.y;
} }
} }
else else
{ {
// goes "up" // goes "up"
if (time >= Minigame.PerfectTime()) if (time >= Minigame.JustEarlyTime())
{ {
type = Rating.OK; type = Rating.OK;
frac = (float)((time - Minigame.PerfectTime()) / (Minigame.AceStartTime() - Minigame.PerfectTime())); frac = (float)((time - Minigame.JustEarlyTime()) / (Minigame.AceEarlyTime() - Minigame.JustEarlyTime()));
y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * -frac) - barJustTransform.localScale.y; y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * -frac) - barJustTransform.localScale.y;
} }
else else
{ {
type = Rating.NG; type = Rating.NG;
frac = (float)((time - Minigame.EarlyTime()) / (Minigame.PerfectTime() - Minigame.EarlyTime())); frac = (float)((time - Minigame.NgEarlyTime()) / (Minigame.JustEarlyTime() - Minigame.NgEarlyTime()));
y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * -frac) - barOKTransform.localScale.y; y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * -frac) - barOKTransform.localScale.y;
} }
} }

View file

@ -85,7 +85,7 @@ namespace HeavenStudio.Common
void Update() void Update()
{ {
if (isQuitting) return; if (isQuitting) return;
if (PlayerInput.GetInputController(1).GetButtonDown((int) InputController.ButtonsPad.PadPause)) if (PlayerInput.GetInputController(1).GetActionDown((int) InputController.ActionsPad.Pause, out _))
{ {
if (isPaused) if (isPaused)
{ {
@ -98,7 +98,7 @@ namespace HeavenStudio.Common
} }
else if (isPaused && canPick && !settingsDialog.IsOpen) else if (isPaused && canPick && !settingsDialog.IsOpen)
{ {
if (Input.GetKeyDown(KeyCode.UpArrow) || PlayerInput.GetInputController(1).GetButtonDown((int)InputController.ButtonsPad.PadUp)) if (Input.GetKeyDown(KeyCode.UpArrow) || PlayerInput.GetInputController(1).GetActionDown((int)InputController.ActionsPad.Up, out _))
{ {
optionSelected--; optionSelected--;
if (optionSelected < 0) if (optionSelected < 0)
@ -107,7 +107,7 @@ namespace HeavenStudio.Common
} }
ChooseOption((Options) optionSelected); ChooseOption((Options) optionSelected);
} }
else if (Input.GetKeyDown(KeyCode.DownArrow) || PlayerInput.GetInputController(1).GetButtonDown((int)InputController.ButtonsPad.PadDown)) else if (Input.GetKeyDown(KeyCode.DownArrow) || PlayerInput.GetInputController(1).GetActionDown((int)InputController.ActionsPad.Down, out _))
{ {
optionSelected++; optionSelected++;
if (optionSelected > optionHolder.transform.childCount - 1) if (optionSelected > optionHolder.transform.childCount - 1)
@ -116,7 +116,7 @@ namespace HeavenStudio.Common
} }
ChooseOption((Options) optionSelected); ChooseOption((Options) optionSelected);
} }
else if (Input.GetKeyDown(KeyCode.Return) || PlayerInput.GetInputController(1).GetButtonDown((int)InputController.ButtonsPad.PadE)) else if (Input.GetKeyDown(KeyCode.Return) || PlayerInput.GetInputController(1).GetActionDown((int)InputController.ActionsPad.East, out _))
{ {
UseOption((Options) optionSelected); UseOption((Options) optionSelected);
} }

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using TMPro; using TMPro;
using System.Threading.Tasks;
using HeavenStudio; using HeavenStudio;
using HeavenStudio.Util; using HeavenStudio.Util;
@ -20,40 +21,64 @@ namespace HeavenStudio.Editor
[SerializeField] private GameObject pairSearchItem; [SerializeField] private GameObject pairSearchItem;
[SerializeField] private GameObject autoSearchLabel; [SerializeField] private GameObject autoSearchLabel;
[SerializeField] private GameObject pairSearchLabel; [SerializeField] private GameObject pairSearchLabel;
[SerializeField] private GameObject pairSearchCancelBt;
[SerializeField] private TMP_Text pairingLabel; [SerializeField] private TMP_Text pairingLabel;
[SerializeField] private List<GameObject> controllerIcons; [SerializeField] private List<GameObject> controllerIcons;
[SerializeField] private Material controllerMat; [SerializeField] private Material controllerMat;
[SerializeField] private List<GameObject> PadBindingsMenus;
[SerializeField] private List<GameObject> BatonBindingsMenus;
[SerializeField] private List<GameObject> TouchBindingsMenus;
[SerializeField] private List<TMP_Text> PadBindingsTxt;
[SerializeField] private List<TMP_Text> BatonBindingsTxt;
[SerializeField] private List<TMP_Text> TouchBindingsTxt;
private bool isAutoSearching = false; private bool isAutoSearching = false;
private bool isPairSearching = false; private bool isPairSearching = false;
private bool pairSelectLR = false; //true = left, false = right private bool pairSelectLR = false; //true = left, false = right
private bool bindAllMode;
private int currentBindingBt;
private void Start() { private void Start() {
numConnectedLabel.text = "Connected: " + PlayerInput.GetNumControllersConnected(); numConnectedLabel.text = "Connected: " + PlayerInput.GetNumControllersConnected();
currentControllerLabel.text = "Current Controller: " + PlayerInput.GetInputController(1).GetDeviceName(); currentControllerLabel.text = "Current Controller: " + PlayerInput.GetInputController(1).GetDeviceName();
PopulateControllersDropdown(); PopulateControllersDropdown();
pairSearchItem.SetActive(false);
ShowControllerBinds(PlayerInput.GetInputController(1));
ShowControllerIcon(PlayerInput.GetInputController(1)); ShowControllerIcon(PlayerInput.GetInputController(1));
controllersDropdown.onValueChanged.AddListener(delegate
{
InputController lastController = PlayerInput.GetInputController(1);
InputController newController = PlayerInput.GetInputControllers()[controllersDropdown.value];
AssignController(newController, lastController);
});
} }
private void Update() { private void Update() {
InputController currentController = PlayerInput.GetInputController(1);
if (currentBindingBt >= 0)
{
int bt = currentController.GetLastButtonDown();
if (bt > 0)
{
InputController.ControlBindings binds = currentController.GetCurrentBindings();
binds.Pad[currentBindingBt] = bt;
currentController.SetCurrentBindings(binds);
currentControllerLabel.text = "Current Controller: " + currentController.GetDeviceName();
ShowControllerBinds(currentController);
AdvanceAutoBind(currentController);
}
return;
}
else
{
if (isAutoSearching) { if (isAutoSearching) {
var controllers = PlayerInput.GetInputControllers(); var controllers = PlayerInput.GetInputControllers();
foreach (var controller in controllers) { foreach (var newController in controllers) {
if (controller.GetLastButtonDown() > 0 || controller.GetLastKeyDown() > 0) { if (newController.GetLastButtonDown() > 0)
InputController lastController = PlayerInput.GetInputController(1); {
isAutoSearching = false; isAutoSearching = false;
autoSearchLabel.SetActive(false); autoSearchLabel.SetActive(false);
AssignController(controller, lastController); AssignController(newController, currentController);
controllersDropdown.value = PlayerInput.GetInputControllerId(1); controllersDropdown.value = PlayerInput.GetInputControllerId(1);
} }
@ -62,55 +87,89 @@ namespace HeavenStudio.Editor
else if (isPairSearching) { else if (isPairSearching) {
var controllers = PlayerInput.GetInputControllers(); var controllers = PlayerInput.GetInputControllers();
InputController.InputFeatures lrFlag = pairSelectLR ? InputController.InputFeatures.Extra_SplitControllerLeft : InputController.InputFeatures.Extra_SplitControllerRight; InputController.InputFeatures lrFlag = pairSelectLR ? InputController.InputFeatures.Extra_SplitControllerLeft : InputController.InputFeatures.Extra_SplitControllerRight;
foreach (var controller in controllers) { foreach (var pairController in controllers) {
if (controller == PlayerInput.GetInputController(1)) continue; if (pairController == currentController) continue;
InputController.InputFeatures features = controller.GetFeatures();
InputController.InputFeatures features = pairController.GetFeatures();
if (!features.HasFlag(lrFlag)) continue; if (!features.HasFlag(lrFlag)) continue;
if (controller.GetLastButtonDown() > 0 || controller.GetLastKeyDown() > 0) {
InputJoyshock con = (InputJoyshock) PlayerInput.GetInputController(1); if (pairController.GetLastButtonDown() > 0)
con.AssignOtherHalf((InputJoyshock) controller); {
(PlayerInput.GetInputController(1) as InputJoyshock)?.AssignOtherHalf((InputJoyshock) pairController);
isPairSearching = false; isPairSearching = false;
pairSearchLabel.SetActive(false); pairSearchLabel.SetActive(false);
currentControllerLabel.text = "Current Controller: " + controller.GetDeviceName(); currentControllerLabel.text = "Current Controller: " + pairController.GetDeviceName();
pairingLabel.text = "Joy-Con Pair Selected\nPairing Successful!"; pairingLabel.text = "Joy-Con Pair Selected\nPairing Successful!";
ShowControllerIcon(controller); ShowControllerIcon(pairController);
StartCoroutine(SelectionVibrate(con)); currentController.OnSelected();
StartCoroutine(SelectionVibrate((InputJoyshock) controller)); pairController.OnSelected();
} }
} }
} }
} }
}
void AdvanceAutoBind(InputController currentController)
{
if (bindAllMode)
{
currentBindingBt++;
Debug.Log("Binding: " + currentBindingBt);
while (currentController.GetIsActionUnbindable(currentBindingBt, InputController.ControlStyles.Pad) && currentBindingBt < (int)InputController.ActionsPad.Pause)
{
currentBindingBt++;
Debug.Log("Unbindable, binding: " + currentBindingBt);
}
if (currentBindingBt > (int)InputController.ActionsPad.Pause)
{
currentController.SaveBindings();
CancelBind();
return;
}
currentControllerLabel.text = $"Now Binding: {(InputController.ActionsPad) currentBindingBt}";
}
else
{
currentController.SaveBindings();
CancelBind();
}
}
void AssignController(InputController newController, InputController lastController) void AssignController(InputController newController, InputController lastController)
{ {
Debug.Log("Assigning controller: " + newController.GetDeviceName());
lastController.SetPlayer(-1); lastController.SetPlayer(-1);
newController.SetPlayer(1); newController.SetPlayer(1);
if (typeof(InputJoyshock) == lastController.GetType()) { if ((lastController as InputJoyshock) != null)
InputJoyshock con = (InputJoyshock) lastController; {
con.UnAssignOtherHalf(); (lastController as InputJoyshock)?.UnAssignOtherHalf();
} }
if (typeof(InputJoyshock) == newController.GetType()) { if ((newController as InputJoyshock) != null)
InputJoyshock con = (InputJoyshock) newController; {
StartCoroutine(SelectionVibrate(con)); newController.OnSelected();
con.UnAssignOtherHalf(); (newController as InputJoyshock)?.UnAssignOtherHalf();
} }
currentControllerLabel.text = "Current Controller: " + newController.GetDeviceName(); currentControllerLabel.text = "Current Controller: " + newController.GetDeviceName();
ShowControllerBinds(newController);
ShowControllerIcon(newController); ShowControllerIcon(newController);
InputController.InputFeatures features = newController.GetFeatures(); InputController.InputFeatures features = newController.GetFeatures();
if (features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft)) { if (features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft)) {
pairingLabel.text = "Joy-Con (L) Selected\nPress A to pair with Joy-Con (R)"; pairingLabel.text = "Joy-Con (L) Selected\nPress any button on Joy-Con (R) to pair.";
pairSelectLR = !features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft); pairSelectLR = !features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft);
pairSearchItem.SetActive(true); pairSearchItem.SetActive(true);
StartPairSearch(); StartPairSearch();
} }
else if (features.HasFlag(InputController.InputFeatures.Extra_SplitControllerRight)) { else if (features.HasFlag(InputController.InputFeatures.Extra_SplitControllerRight)) {
pairingLabel.text = "Joy-Con (R) Selected\nPress A to pair with Joy-Con (L)"; pairingLabel.text = "Joy-Con (R) Selected\nPress any button on Joy-Con (L) to pair.";
pairSelectLR = !features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft); pairSelectLR = !features.HasFlag(InputController.InputFeatures.Extra_SplitControllerLeft);
pairSearchItem.SetActive(true); pairSearchItem.SetActive(true);
@ -122,7 +181,53 @@ namespace HeavenStudio.Editor
} }
} }
public void ControllerDropdownChange()
{
CancelBind();
InputController lastController = PlayerInput.GetInputController(1);
lastController.SaveBindings();
InputController newController = PlayerInput.GetInputControllers()[controllersDropdown.value];
AssignController(newController, lastController);
}
public void StartBindSingle(int bt)
{
CancelBind();
if (PlayerInput.GetInputController(1).GetIsActionUnbindable(bt, InputController.ControlStyles.Pad))
{
return;
}
currentBindingBt = bt;
currentControllerLabel.text = $"Now Binding: {(InputController.ActionsPad) bt}";
}
public void StartBindAll()
{
CancelBind();
bindAllMode = true;
currentBindingBt = -1;
AdvanceAutoBind(PlayerInput.GetInputController(1));
}
public void CancelBind()
{
bindAllMode = false;
currentBindingBt = -1;
currentControllerLabel.text = "Current Controller: " + PlayerInput.GetInputController(1).GetDeviceName();
}
public void ResetBindings()
{
CancelBind();
InputController controller = PlayerInput.GetInputController(1);
controller.ResetBindings();
ShowControllerBinds(controller);
controller.SaveBindings();
}
public void StartAutoSearch() { public void StartAutoSearch() {
CancelBind();
if (!isPairSearching) if (!isPairSearching)
{ {
autoSearchLabel.SetActive(true); autoSearchLabel.SetActive(true);
@ -131,15 +236,19 @@ namespace HeavenStudio.Editor
} }
public void StartPairSearch() { public void StartPairSearch() {
CancelBind();
if (!isAutoSearching) { if (!isAutoSearching) {
pairSearchLabel.SetActive(true); pairSearchLabel.SetActive(true);
pairSearchCancelBt.SetActive(true);
isPairSearching = true; isPairSearching = true;
} }
} }
public void CancelPairSearch() { public void CancelPairSearch() {
CancelBind();
if (isPairSearching) { if (isPairSearching) {
pairSearchLabel.SetActive(false); pairSearchLabel.SetActive(false);
pairSearchCancelBt.SetActive(false);
isPairSearching = false; isPairSearching = false;
pairingLabel.text = "Joy-Con Selected\nPairing was cancelled."; pairingLabel.text = "Joy-Con Selected\nPairing was cancelled.";
} }
@ -147,7 +256,7 @@ namespace HeavenStudio.Editor
public void SearchAndConnectControllers() public void SearchAndConnectControllers()
{ {
int connected = PlayerInput.InitInputControllers(); int connected = PlayerInput.RefreshInputControllers();
numConnectedLabel.text = "Connected: " + connected; numConnectedLabel.text = "Connected: " + connected;
currentControllerLabel.text = "Current Controller: " + PlayerInput.GetInputController(1).GetDeviceName(); currentControllerLabel.text = "Current Controller: " + PlayerInput.GetInputController(1).GetDeviceName();
PopulateControllersDropdown(); PopulateControllersDropdown();
@ -165,12 +274,40 @@ namespace HeavenStudio.Editor
} }
controllersDropdown.ClearOptions(); controllersDropdown.ClearOptions();
controllersDropdown.AddOptions(dropDownData); controllersDropdown.AddOptions(dropDownData);
controllersDropdown.value = 0; controllersDropdown.value = PlayerInput.GetInputControllerId(1);
}
public void ShowControllerBinds(InputController controller)
{
string[] buttons = controller.GetButtonNames();
//show binds
int ac = 0;
foreach (int i in controller.GetCurrentBindings().Pad)
{
if (ac >= PadBindingsTxt.Count) break;
if (i == -1)
{
PadBindingsTxt[ac].text = "NOT BOUND";
}
else if (buttons[i] == null)
{
PadBindingsTxt[ac].text = "UNKNOWN";
}
else
{
PadBindingsTxt[ac].text = buttons[i];
}
ac++;
}
} }
public void ShowControllerIcon(InputController controller) public void ShowControllerIcon(InputController controller)
{ {
string name = controller.GetDeviceName(); string name = controller.GetDeviceName();
//show icon
foreach (var icon in controllerIcons) foreach (var icon in controllerIcons)
{ {
if (icon.name == name) if (icon.name == name)
@ -182,6 +319,7 @@ namespace HeavenStudio.Editor
icon.SetActive(false); icon.SetActive(false);
} }
} }
//setup material //setup material
Color colour; Color colour;
switch (name) switch (name)
@ -235,23 +373,14 @@ namespace HeavenStudio.Editor
} }
} }
IEnumerator SelectionVibrate(InputJoyshock controller)
{
JslSetRumbleFrequency(controller.GetHandle(), 0.4f, 0.4f, 80f, 160f);
yield return new WaitForSeconds(0.15f);
JslSetRumbleFrequency(controller.GetHandle(), 0f, 0f, 0f, 0f);
yield return new WaitForSeconds(0.05f);
JslSetRumbleFrequency(controller.GetHandle(), 0.5f, 0.5f, 160f, 320f);
yield return new WaitForSeconds(0.25f);
JslSetRumbleFrequency(controller.GetHandle(), 0f, 0f, 0f, 0f);
}
public override void OnOpenTab() public override void OnOpenTab()
{ {
CancelBind();
} }
public override void OnCloseTab() public override void OnCloseTab()
{ {
CancelBind();
} }
} }
} }