Re-enable instruments with fallback when MIDI isn't available.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Shared.GameObjects.Components.Instruments;
|
using Content.Shared.GameObjects.Components.Instruments;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Client.Audio.Midi;
|
using Robust.Client.Audio.Midi;
|
||||||
using Robust.Shared.Audio.Midi;
|
using Robust.Shared.Audio.Midi;
|
||||||
@@ -28,6 +29,7 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
[Dependency] private readonly IGameTiming _timing;
|
[Dependency] private readonly IGameTiming _timing;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
private IMidiRenderer _renderer;
|
private IMidiRenderer _renderer;
|
||||||
private int _instrumentProgram = 1;
|
private int _instrumentProgram = 1;
|
||||||
|
|
||||||
@@ -42,8 +44,14 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public bool LoopMidi
|
public bool LoopMidi
|
||||||
{
|
{
|
||||||
get => _renderer.LoopMidi;
|
get => _renderer?.LoopMidi ?? false;
|
||||||
set => _renderer.LoopMidi = value;
|
set
|
||||||
|
{
|
||||||
|
if (_renderer != null)
|
||||||
|
{
|
||||||
|
_renderer.LoopMidi = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -53,33 +61,41 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
public int InstrumentProgram
|
public int InstrumentProgram
|
||||||
{
|
{
|
||||||
get => _instrumentProgram;
|
get => _instrumentProgram;
|
||||||
set {
|
set
|
||||||
|
{
|
||||||
_instrumentProgram = value;
|
_instrumentProgram = value;
|
||||||
|
if (_renderer != null)
|
||||||
|
{
|
||||||
_renderer.MidiProgram = _instrumentProgram;
|
_renderer.MidiProgram = _instrumentProgram;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether there's a midi song being played or not.
|
/// Whether there's a midi song being played or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool IsMidiOpen => _renderer.Status == MidiRendererStatus.File;
|
public bool IsMidiOpen => _renderer?.Status == MidiRendererStatus.File;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the midi renderer is listening for midi input or not.
|
/// Whether the midi renderer is listening for midi input or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool IsInputOpen => _renderer.Status == MidiRendererStatus.Input;
|
public bool IsInputOpen => _renderer?.Status == MidiRendererStatus.Input;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
_renderer = _midiManager.GetNewRenderer();
|
_renderer = _midiManager.GetNewRenderer();
|
||||||
|
|
||||||
|
if (_renderer != null)
|
||||||
|
{
|
||||||
_renderer.MidiProgram = _instrumentProgram;
|
_renderer.MidiProgram = _instrumentProgram;
|
||||||
_renderer.TrackingEntity = Owner;
|
_renderer.TrackingEntity = Owner;
|
||||||
_renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); };
|
_renderer.OnMidiPlayerFinished += () => { OnMidiPlaybackEnded?.Invoke(); };
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Shutdown()
|
protected override void Shutdown()
|
||||||
{
|
{
|
||||||
@@ -93,9 +109,16 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
serializer.DataField(ref _instrumentProgram, "program", 1);
|
serializer.DataField(ref _instrumentProgram, "program", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
|
||||||
|
IComponent component = null)
|
||||||
{
|
{
|
||||||
base.HandleMessage(message, netChannel, component);
|
base.HandleMessage(message, netChannel, component);
|
||||||
|
|
||||||
|
if (_renderer == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
case InstrumentMidiEventMessage midiEventMessage:
|
case InstrumentMidiEventMessage midiEventMessage:
|
||||||
@@ -107,8 +130,8 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
|
|
||||||
case InstrumentStopMidiMessage _:
|
case InstrumentStopMidiMessage _:
|
||||||
_renderer.StopAllNotes();
|
_renderer.StopAllNotes();
|
||||||
if(IsInputOpen) CloseInput();
|
if (IsInputOpen) CloseInput();
|
||||||
if(IsMidiOpen) CloseMidi();
|
if (IsMidiOpen) CloseMidi();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +139,7 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
/// <inheritdoc cref="MidiRenderer.OpenInput"/>
|
/// <inheritdoc cref="MidiRenderer.OpenInput"/>
|
||||||
public bool OpenInput()
|
public bool OpenInput()
|
||||||
{
|
{
|
||||||
if (_renderer.OpenInput())
|
if (_renderer != null && _renderer.OpenInput())
|
||||||
{
|
{
|
||||||
_renderer.OnMidiEvent += RendererOnMidiEvent;
|
_renderer.OnMidiEvent += RendererOnMidiEvent;
|
||||||
return true;
|
return true;
|
||||||
@@ -128,28 +151,37 @@ namespace Content.Client.GameObjects.Components.Instruments
|
|||||||
/// <inheritdoc cref="MidiRenderer.CloseInput"/>
|
/// <inheritdoc cref="MidiRenderer.CloseInput"/>
|
||||||
public bool CloseInput()
|
public bool CloseInput()
|
||||||
{
|
{
|
||||||
if (!_renderer.CloseInput()) return false;
|
if (_renderer == null || !_renderer.CloseInput())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_renderer.OnMidiEvent -= RendererOnMidiEvent;
|
_renderer.OnMidiEvent -= RendererOnMidiEvent;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="MidiRenderer.OpenMidi(string)"/>
|
/// <inheritdoc cref="MidiRenderer.OpenMidi(string)"/>
|
||||||
public bool OpenMidi(string filename)
|
public bool OpenMidi(string filename)
|
||||||
{
|
{
|
||||||
if (!_renderer.OpenMidi(filename)) return false;
|
if (_renderer == null || !_renderer.OpenMidi(filename))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_renderer.OnMidiEvent += RendererOnMidiEvent;
|
_renderer.OnMidiEvent += RendererOnMidiEvent;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="MidiRenderer.CloseMidi"/>
|
/// <inheritdoc cref="MidiRenderer.CloseMidi"/>
|
||||||
public bool CloseMidi()
|
public bool CloseMidi()
|
||||||
{
|
{
|
||||||
if (!_renderer.CloseMidi()) return false;
|
if (_renderer == null || !_renderer.CloseMidi())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
_renderer.OnMidiEvent -= RendererOnMidiEvent;
|
_renderer.OnMidiEvent -= RendererOnMidiEvent;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using Content.Client.GameObjects.Components.Instruments;
|
using Content.Client.GameObjects.Components.Instruments;
|
||||||
|
using Content.Client.UserInterface;
|
||||||
using Robust.Client.Audio.Midi;
|
using Robust.Client.Audio.Midi;
|
||||||
|
using Robust.Client.Graphics.Drawing;
|
||||||
using Robust.Client.Interfaces.UserInterface;
|
using Robust.Client.Interfaces.UserInterface;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
@@ -27,7 +30,7 @@ namespace Content.Client.Instruments
|
|||||||
public InstrumentMenu(InstrumentBoundUserInterface owner)
|
public InstrumentMenu(InstrumentBoundUserInterface owner)
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
Title = "Instrument";
|
Title = Loc.GetString("Instrument");
|
||||||
|
|
||||||
_owner = owner;
|
_owner = owner;
|
||||||
|
|
||||||
@@ -55,7 +58,7 @@ namespace Content.Client.Instruments
|
|||||||
|
|
||||||
midiInputButton = new Button()
|
midiInputButton = new Button()
|
||||||
{
|
{
|
||||||
Text = "MIDI Input",
|
Text = Loc.GetString("MIDI Input"),
|
||||||
TextAlign = Label.AlignMode.Center,
|
TextAlign = Label.AlignMode.Center,
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||||
SizeFlagsStretchRatio = 1,
|
SizeFlagsStretchRatio = 1,
|
||||||
@@ -73,7 +76,7 @@ namespace Content.Client.Instruments
|
|||||||
|
|
||||||
var midiFileButton = new Button()
|
var midiFileButton = new Button()
|
||||||
{
|
{
|
||||||
Text = "Open File",
|
Text = Loc.GetString("Play MIDI File"),
|
||||||
TextAlign = Label.AlignMode.Center,
|
TextAlign = Label.AlignMode.Center,
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||||
SizeFlagsStretchRatio = 1,
|
SizeFlagsStretchRatio = 1,
|
||||||
@@ -91,7 +94,7 @@ namespace Content.Client.Instruments
|
|||||||
|
|
||||||
midiLoopButton = new Button()
|
midiLoopButton = new Button()
|
||||||
{
|
{
|
||||||
Text = "Loop",
|
Text = Loc.GetString("Loop"),
|
||||||
TextAlign = Label.AlignMode.Center,
|
TextAlign = Label.AlignMode.Center,
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||||
SizeFlagsStretchRatio = 1,
|
SizeFlagsStretchRatio = 1,
|
||||||
@@ -110,7 +113,7 @@ namespace Content.Client.Instruments
|
|||||||
|
|
||||||
midiStopButton = new Button()
|
midiStopButton = new Button()
|
||||||
{
|
{
|
||||||
Text = "Stop",
|
Text = Loc.GetString("Stop"),
|
||||||
TextAlign = Label.AlignMode.Center,
|
TextAlign = Label.AlignMode.Center,
|
||||||
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
SizeFlagsHorizontal = SizeFlags.FillExpand,
|
||||||
SizeFlagsStretchRatio = 1,
|
SizeFlagsStretchRatio = 1,
|
||||||
@@ -132,6 +135,26 @@ namespace Content.Client.Instruments
|
|||||||
|
|
||||||
margin.AddChild(vBox);
|
margin.AddChild(vBox);
|
||||||
|
|
||||||
|
if (!_midiManager.IsAvailable)
|
||||||
|
{
|
||||||
|
margin.AddChild(new PanelContainer
|
||||||
|
{
|
||||||
|
MouseFilter = MouseFilterMode.Stop,
|
||||||
|
PanelOverride = new StyleBoxFlat {BackgroundColor = Color.Black.WithAlpha(0.90f)},
|
||||||
|
Children =
|
||||||
|
{
|
||||||
|
new Label
|
||||||
|
{
|
||||||
|
Align = Label.AlignMode.Center,
|
||||||
|
SizeFlagsVertical = SizeFlags.ShrinkCenter,
|
||||||
|
SizeFlagsHorizontal = SizeFlags.ShrinkCenter,
|
||||||
|
StyleClasses = {NanoStyle.StyleClassLabelBig},
|
||||||
|
Text = Loc.GetString("MIDI support is currently\nnot available on your platform.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Contents.AddChild(margin);
|
Contents.AddChild(margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +171,8 @@ namespace Content.Client.Instruments
|
|||||||
|
|
||||||
private async void MidiFileButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
|
private async void MidiFileButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
|
||||||
{
|
{
|
||||||
var filename = await _fileDialogManager.OpenFile();
|
var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi"));
|
||||||
|
var filename = await _fileDialogManager.OpenFile(filters);
|
||||||
|
|
||||||
if (filename == null) return;
|
if (filename == null) return;
|
||||||
|
|
||||||
@@ -160,7 +184,7 @@ namespace Content.Client.Instruments
|
|||||||
|
|
||||||
if (!_owner.Instrument.OpenMidi(filename)) return;
|
if (!_owner.Instrument.OpenMidi(filename)) return;
|
||||||
MidiPlaybackSetButtonsDisabled(false);
|
MidiPlaybackSetButtonsDisabled(false);
|
||||||
if(midiInputButton.Pressed)
|
if (midiInputButton.Pressed)
|
||||||
midiInputButton.Pressed = false;
|
midiInputButton.Pressed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,70 +1,70 @@
|
|||||||
# - type: entity
|
- type: entity
|
||||||
# name: BaseInstrument
|
name: BaseInstrument
|
||||||
# id: BaseInstrument
|
id: BaseInstrument
|
||||||
# abstract: true
|
abstract: true
|
||||||
# components:
|
components:
|
||||||
# - type: Instrument
|
- type: Instrument
|
||||||
# handheld: false
|
handheld: false
|
||||||
#
|
|
||||||
# - type: Clickable
|
- type: Clickable
|
||||||
# - type: InteractionOutline
|
- type: InteractionOutline
|
||||||
#
|
|
||||||
# - type: Collidable
|
- type: Collidable
|
||||||
# shapes:
|
shapes:
|
||||||
# - !type:PhysShapeAabb
|
- !type:PhysShapeAabb
|
||||||
# layer: 31
|
layer: 31
|
||||||
#
|
|
||||||
# - type: SnapGrid
|
- type: SnapGrid
|
||||||
# offset: Center
|
offset: Center
|
||||||
#
|
|
||||||
# - type: Damageable
|
- type: Damageable
|
||||||
# - type: Destructible
|
- type: Destructible
|
||||||
# thresholdvalue: 50
|
thresholdvalue: 50
|
||||||
#
|
|
||||||
# - type: UserInterface
|
- type: UserInterface
|
||||||
# interfaces:
|
interfaces:
|
||||||
# - key: enum.InstrumentUiKey.Key
|
- key: enum.InstrumentUiKey.Key
|
||||||
# type: InstrumentBoundUserInterface
|
type: InstrumentBoundUserInterface
|
||||||
#
|
|
||||||
# - type: entity
|
- type: entity
|
||||||
# name: Piano
|
name: Piano
|
||||||
# parent: BaseInstrument
|
parent: BaseInstrument
|
||||||
# id: PianoInstrument
|
id: PianoInstrument
|
||||||
# description: Play Needles Piano Now.
|
description: Play Needles Piano Now.
|
||||||
# components:
|
components:
|
||||||
# - type: Instrument
|
- type: Instrument
|
||||||
# program: 1
|
program: 1
|
||||||
# - type: Sprite
|
- type: Sprite
|
||||||
# sprite: Objects/Instruments/musician.rsi
|
sprite: Objects/Instruments/musician.rsi
|
||||||
# state: piano
|
state: piano
|
||||||
# - type: Icon
|
- type: Icon
|
||||||
# sprite: Objects/Instruments/musician.rsi
|
sprite: Objects/Instruments/musician.rsi
|
||||||
# state: piano
|
state: piano
|
||||||
#
|
|
||||||
# - type: entity
|
- type: entity
|
||||||
# name: Minimoog
|
name: Minimoog
|
||||||
# parent: BaseInstrument
|
parent: BaseInstrument
|
||||||
# id: MinimoogInstrument
|
id: MinimoogInstrument
|
||||||
# components:
|
components:
|
||||||
# - type: Instrument
|
- type: Instrument
|
||||||
# program: 7
|
program: 7
|
||||||
# - type: Sprite
|
- type: Sprite
|
||||||
# sprite: Objects/Instruments/musician.rsi
|
sprite: Objects/Instruments/musician.rsi
|
||||||
# state: minimoog
|
state: minimoog
|
||||||
# - type: Icon
|
- type: Icon
|
||||||
# sprite: Objects/Instruments/musician.rsi
|
sprite: Objects/Instruments/musician.rsi
|
||||||
# state: minimoog
|
state: minimoog
|
||||||
#
|
|
||||||
# - type: entity
|
- type: entity
|
||||||
# name: Xylophone
|
name: Xylophone
|
||||||
# parent: BaseInstrument
|
parent: BaseInstrument
|
||||||
# id: XylophoneInstrument
|
id: XylophoneInstrument
|
||||||
# components:
|
components:
|
||||||
# - type: Instrument
|
- type: Instrument
|
||||||
# program: 13
|
program: 13
|
||||||
# - type: Sprite
|
- type: Sprite
|
||||||
# sprite: Objects/Instruments/musician.rsi
|
sprite: Objects/Instruments/musician.rsi
|
||||||
# state: xylophone
|
state: xylophone
|
||||||
# - type: Icon
|
- type: Icon
|
||||||
# sprite: Objects/Instruments/musician.rsi
|
sprite: Objects/Instruments/musician.rsi
|
||||||
# state: xylophone
|
state: xylophone
|
||||||
|
|||||||
Reference in New Issue
Block a user