116 lines
4.3 KiB
C#
116 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using System.Xml.Linq;
|
|
using Microsoft.Xna.Framework;
|
|
|
|
namespace Barotrauma.Items.Components
|
|
{
|
|
class OscillatorComponent : ItemComponent
|
|
{
|
|
public enum WaveType
|
|
{
|
|
Pulse,
|
|
Sawtooth,
|
|
Sine,
|
|
Square,
|
|
Triangle,
|
|
}
|
|
|
|
private float frequency;
|
|
|
|
private float phase;
|
|
|
|
[InGameEditable, Serialize(WaveType.Pulse, IsPropertySaveable.Yes, description: "What kind of a signal the item outputs." +
|
|
" Pulse: periodically sends out a signal of 1." +
|
|
" Sawtooth: sends out a periodic wave that increases linearly from 0 to 1." +
|
|
" Sine: sends out a sine wave oscillating between -1 and 1." +
|
|
" Square: sends out a signal that alternates between 0 and 1." +
|
|
" Triangle: sends out a wave that alternates between increasing linearly from -1 to 1 and decreasing from 1 to -1.",
|
|
alwaysUseInstanceValues: true)]
|
|
public WaveType OutputType
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
[InGameEditable(DecimalCount = 2), Serialize(1.0f, IsPropertySaveable.Yes, description: "How fast the signal oscillates, or how fast the pulses are sent (in Hz).", alwaysUseInstanceValues: true)]
|
|
public float Frequency
|
|
{
|
|
get { return frequency; }
|
|
set
|
|
{
|
|
//capped to 240 Hz (= 4 signals per frame) to prevent players
|
|
//from wrecking the performance by setting the value too high
|
|
frequency = MathHelper.Clamp(value, 0.0f, 240.0f);
|
|
}
|
|
}
|
|
|
|
public OscillatorComponent(Item item, ContentXElement element) :
|
|
base(item, element)
|
|
{
|
|
IsActive = true;
|
|
}
|
|
|
|
public override void Update(float deltaTime, Camera cam)
|
|
{
|
|
switch (OutputType)
|
|
{
|
|
case WaveType.Pulse:
|
|
if (frequency <= 0.0f) return;
|
|
|
|
phase += deltaTime;
|
|
float pulseInterval = 1.0f / frequency;
|
|
while (phase >= pulseInterval)
|
|
{
|
|
item.SendSignal("1", "signal_out");
|
|
phase -= pulseInterval;
|
|
}
|
|
break;
|
|
case WaveType.Sawtooth:
|
|
phase = (phase + deltaTime * frequency) % 1.0f;
|
|
item.SendSignal(phase.ToString(CultureInfo.InvariantCulture), "signal_out");
|
|
break;
|
|
case WaveType.Square:
|
|
phase = (phase + deltaTime * frequency) % 1.0f;
|
|
item.SendSignal(phase < 0.5f ? "0" : "1", "signal_out");
|
|
break;
|
|
case WaveType.Sine:
|
|
phase = (phase + deltaTime * frequency) % 1.0f;
|
|
item.SendSignal(Math.Sin(phase * MathHelper.TwoPi).ToString(CultureInfo.InvariantCulture), "signal_out");
|
|
break;
|
|
case WaveType.Triangle:
|
|
phase = (phase + deltaTime * frequency) % 1.0f;
|
|
float output = 4.0f * MathF.Abs(MathUtils.PositiveModulo(phase - 0.25f, 1.0f) - 0.5f) - 1.0f;
|
|
item.SendSignal(output.ToString(CultureInfo.InvariantCulture), "signal_out");
|
|
break;
|
|
}
|
|
}
|
|
|
|
public override void ReceiveSignal(Signal signal, Connection connection)
|
|
{
|
|
switch (connection.Name)
|
|
{
|
|
case "set_frequency":
|
|
case "frequency_in":
|
|
float newFrequency;
|
|
if (float.TryParse(signal.value, NumberStyles.Float, CultureInfo.InvariantCulture, out newFrequency))
|
|
{
|
|
Frequency = newFrequency;
|
|
}
|
|
IsActive = true;
|
|
break;
|
|
case "set_outputtype":
|
|
case "set_wavetype":
|
|
WaveType newOutputType;
|
|
if (Enum.TryParse(signal.value, out newOutputType))
|
|
{
|
|
OutputType = newOutputType;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|