mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2026-01-06 19:22:38 +01:00
Add iron note block
This commit is contained in:
parent
d04ecf156d
commit
bcb617815d
@ -1 +1 @@
|
||||
Subproject commit 62e45f6c5dd19ddfbdbc0d4239529b91a011059b
|
||||
Subproject commit 5d6dee430d6cd04f466d876f10f109b3a3d1057b
|
||||
BIN
sprites/nodes/IronNoteBlock.png
Normal file
BIN
sprites/nodes/IronNoteBlock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 407 B |
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@ -1,5 +1,5 @@
|
||||
BackgroundPattern 0 0 304 304
|
||||
BarSegment 476 105 16 4
|
||||
BarSegment 493 105 16 4
|
||||
ComputerMotherboard 305 0 79 70
|
||||
Empty 9 316 1 1
|
||||
EmptySlot 441 147 18 18
|
||||
@ -8,7 +8,7 @@ KnobCenter 436 0 50 50
|
||||
KnobLimits 305 71 50 50
|
||||
ShadowBorder 0 305 1 24
|
||||
ShadowCorner 424 122 24 24
|
||||
TabArrow 441 105 8 14
|
||||
TabArrow 458 105 8 14
|
||||
buttons/BottomDrawerClose 460 147 18 18
|
||||
buttons/BottomDrawerOpen 479 147 18 18
|
||||
buttons/PowerOff 424 180 18 18
|
||||
@ -102,11 +102,12 @@ nodes/ComputerOnOverlay 441 88 16 16
|
||||
nodes/DiskDrive 458 88 16 16
|
||||
nodes/DiskDriveActivity 475 88 16 16
|
||||
nodes/DiskDriveFloppy 492 88 16 16
|
||||
nodes/NewNode 356 105 16 16
|
||||
nodes/NoteBlock 373 105 16 16
|
||||
nodes/Relay 390 105 16 16
|
||||
nodes/Screen 407 105 16 16
|
||||
nodes/ScreenOnOverlay 424 105 16 16
|
||||
nodes/IronNoteBlock 356 105 16 16
|
||||
nodes/NewNode 373 105 16 16
|
||||
nodes/NoteBlock 390 105 16 16
|
||||
nodes/Relay 407 105 16 16
|
||||
nodes/Screen 424 105 16 16
|
||||
nodes/ScreenOnOverlay 441 105 16 16
|
||||
panel/BorderB 8 305 4 4
|
||||
panel/BorderL 63 305 4 2
|
||||
panel/BorderR 13 305 4 4
|
||||
@ -116,13 +117,13 @@ panel/CornerBR 28 305 4 4
|
||||
panel/CornerTL 33 305 4 4
|
||||
panel/CornerTR 38 305 4 4
|
||||
panel/Fill 6 316 2 2
|
||||
particles/Note 468 105 7 10
|
||||
particles/Note 485 105 7 10
|
||||
screen/BorderB 5 305 2 8
|
||||
screen/BorderT 2 305 2 10
|
||||
screen/CornerBL 365 236 8 8
|
||||
screen/CornerBR 374 236 8 8
|
||||
screen/CornerTL 450 105 8 10
|
||||
screen/CornerTR 459 105 8 10
|
||||
screen/CornerTL 467 105 8 10
|
||||
screen/CornerTR 476 105 8 10
|
||||
window/BorderDark 2 316 1 4
|
||||
window/BorderLight 4 316 1 4
|
||||
window/CloseButton 383 236 7 6
|
||||
|
||||
@ -3,7 +3,7 @@ package ocelot.desktop
|
||||
import buildinfo.BuildInfo
|
||||
import li.flor.nativejfilechooser.NativeJFileChooser
|
||||
import ocelot.desktop.audio._
|
||||
import ocelot.desktop.node.nodes.NoteBlockNode
|
||||
import ocelot.desktop.node.nodes.{IronNoteBlockNode, NoteBlockNode}
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.swing.SplashScreen
|
||||
import ocelot.desktop.ui.widget._
|
||||
@ -384,10 +384,14 @@ object OcelotDesktop extends Logging {
|
||||
}
|
||||
|
||||
EventBus.subscribe[NoteBlockTriggerEvent] { event =>
|
||||
SoundSource.fromBuffer(SoundBuffers.NoteBlock(event.instrument), SoundCategory.Beep, pitch = NoteBlockNode.pitches(event.pitch)).play()
|
||||
UiHandler.root.workspaceView.nodes.find(_.entity.node.address == event.address).get
|
||||
.asInstanceOf[NoteBlockNode]
|
||||
.addParticle(event.pitch)
|
||||
SoundSource.fromBuffer(SoundBuffers.NoteBlock(event.instrument), SoundCategory.Beep,
|
||||
pitch = NoteBlockNode.Pitches(event.pitch), volume = event.volume.toFloat.min(1f).max(0f)).play()
|
||||
val node = UiHandler.root.workspaceView.nodes.find(_.entity.node.address == event.address).get
|
||||
node match {
|
||||
case nb: NoteBlockNode => nb.addParticle(event.pitch)
|
||||
case nb: IronNoteBlockNode => nb.addParticle(event.pitch)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
val soundFloppyAccess = SoundBuffers.MachineFloppyAccess.map(buffer => SoundSource.fromBuffer(buffer, SoundCategory.Environment))
|
||||
|
||||
@ -78,7 +78,7 @@ object Audio extends Logging {
|
||||
AL10.alSourcef(sourceId, AL10.AL_PITCH, source.pitch)
|
||||
AL10.alSource3f(sourceId, AL10.AL_POSITION, 0f, 0f, 0f)
|
||||
AL10.alSourcei(sourceId, AL10.AL_LOOPING, if (source.looping) AL10.AL_TRUE else AL10.AL_FALSE)
|
||||
AL10.alSourcef(sourceId, AL10.AL_GAIN, SoundCategory.getSettingsValue(source.soundCategory) * Settings.get.volumeMaster)
|
||||
AL10.alSourcef(sourceId, AL10.AL_GAIN, source.volume * SoundCategory.getSettingsValue(source.soundCategory) * Settings.get.volumeMaster)
|
||||
AL10.alSourcePlay(sourceId)
|
||||
|
||||
val state = SourceState(sourceId, associatedBufferId = if (isAssociated) bufferId else -1, SoundSource.Status.Playing)
|
||||
@ -105,7 +105,7 @@ object Audio extends Logging {
|
||||
if (isDisabled) return
|
||||
|
||||
sources.filterInPlace { case (source, state) =>
|
||||
AL10.alSourcef(state.sourceId, AL10.AL_GAIN, SoundCategory.getSettingsValue(source.soundCategory) * Settings.get.volumeMaster)
|
||||
AL10.alSourcef(state.sourceId, AL10.AL_GAIN, source.volume * SoundCategory.getSettingsValue(source.soundCategory) * Settings.get.volumeMaster)
|
||||
AL10.alGetSourcei(state.sourceId, AL10.AL_SOURCE_STATE) match {
|
||||
case AL10.AL_PLAYING =>
|
||||
state.status = SoundSource.Status.Playing
|
||||
|
||||
@ -5,7 +5,8 @@ import java.time.Duration
|
||||
class SoundSource(val kind: SoundSource.Kind,
|
||||
val soundCategory: SoundCategory.Value,
|
||||
val looping: Boolean,
|
||||
val pitch: Float) {
|
||||
val pitch: Float,
|
||||
val volume: Float) {
|
||||
|
||||
def duration: Duration = {
|
||||
val seconds = kind match {
|
||||
@ -55,13 +56,13 @@ object SoundSource {
|
||||
case class KindSoundSamples(samples: SoundSamples) extends Kind
|
||||
|
||||
def fromBuffer(buffer: SoundBuffer, soundCategory: SoundCategory.Value,
|
||||
looping: Boolean = false, pitch: Float = 1f): SoundSource = {
|
||||
new SoundSource(SoundSource.KindSoundBuffer(buffer), soundCategory, looping, pitch)
|
||||
looping: Boolean = false, pitch: Float = 1f, volume: Float = 1f): SoundSource = {
|
||||
new SoundSource(SoundSource.KindSoundBuffer(buffer), soundCategory, looping, pitch, volume)
|
||||
}
|
||||
|
||||
def fromSamples(samples: SoundSamples, soundCategory: SoundCategory.Value,
|
||||
looping: Boolean = false, pitch: Float = 1f): SoundSource = {
|
||||
new SoundSource(SoundSource.KindSoundSamples(samples), soundCategory, looping, pitch)
|
||||
looping: Boolean = false, pitch: Float = 1f, volume: Float = 1f): SoundSource = {
|
||||
new SoundSource(SoundSource.KindSoundSamples(samples), soundCategory, looping, pitch, volume)
|
||||
}
|
||||
|
||||
object Status extends Enumeration {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package ocelot.desktop.node
|
||||
|
||||
import ocelot.desktop.node.nodes._
|
||||
import totoro.ocelot.brain.entity.{Cable, Case, FloppyDiskDrive, NoteBlock, Relay, Screen}
|
||||
import totoro.ocelot.brain.entity.{Cable, Case, FloppyDiskDrive, IronNoteBlock, NoteBlock, Relay, Screen}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
@ -39,4 +39,8 @@ object NodeRegistry {
|
||||
register(NodeType("NoteBlock", "nodes/NoteBlock", -1, () => {
|
||||
new NoteBlockNode(new NoteBlock)
|
||||
}))
|
||||
|
||||
register(NodeType("IronNoteBlock", "nodes/IronNoteBlock", -1, () => {
|
||||
new IronNoteBlockNode(new IronNoteBlock)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package ocelot.desktop.node.nodes
|
||||
|
||||
import totoro.ocelot.brain.entity.IronNoteBlock
|
||||
|
||||
class IronNoteBlockNode(val ironNoteBlock: IronNoteBlock) extends NoteBlockNodeBase(ironNoteBlock) {
|
||||
override def icon: String = "nodes/IronNoteBlock"
|
||||
}
|
||||
@ -1,25 +1,16 @@
|
||||
package ocelot.desktop.node.nodes
|
||||
|
||||
import ocelot.desktop.geometry.{Size2D, Vector2D}
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
import ocelot.desktop.node.Node
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry, ContextMenuSubmenu}
|
||||
import ocelot.desktop.{ColorScheme, OcelotDesktop}
|
||||
import totoro.ocelot.brain.entity.NoteBlock
|
||||
import totoro.ocelot.brain.entity.traits.Environment
|
||||
import totoro.ocelot.brain.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class NoteBlockNode(val noteBlock: NoteBlock) extends Node(noteBlock) {
|
||||
class NoteBlockNode(val noteBlock: NoteBlock) extends NoteBlockNodeBase(noteBlock) {
|
||||
override def icon: String = "nodes/NoteBlock"
|
||||
|
||||
override def setupContextMenu(menu: ContextMenu): Unit = {
|
||||
menu.addEntry(new ContextMenuSubmenu("Instrument") {
|
||||
{
|
||||
val maxLen = NoteBlockNode.instruments.map(_._2.length).max
|
||||
for ((instrument, name) <- NoteBlockNode.instruments) {
|
||||
val maxLen = NoteBlockNode.Instruments.map(_._2.length).max
|
||||
for ((instrument, name) <- NoteBlockNode.Instruments) {
|
||||
val dot = if (noteBlock.instrument == instrument) '•' else ' '
|
||||
addEntry(new ContextMenuEntry(name.padTo(maxLen, ' ') + dot, () => noteBlock.instrument = instrument))
|
||||
}
|
||||
@ -29,31 +20,14 @@ class NoteBlockNode(val noteBlock: NoteBlock) extends Node(noteBlock) {
|
||||
menu.addSeparator()
|
||||
super.setupContextMenu(menu)
|
||||
}
|
||||
|
||||
private val particles = mutable.ArrayBuffer[(Float, Int)]()
|
||||
|
||||
def addParticle(pitch: Int): Unit = {
|
||||
synchronized {
|
||||
particles += ((0f, pitch))
|
||||
}
|
||||
}
|
||||
|
||||
override def drawParticles(g: Graphics): Unit = synchronized {
|
||||
for ((time, pitch) <- particles.reverseIterator) {
|
||||
val col = ColorScheme("Note" + pitch).withAlpha(1 - (2 * time - 1).min(1).max(0))
|
||||
g.sprite("particles/Note", position + Vector2D(pitch / 24f * 40f + 5, height / 2 - 10 - 100 * time), Size2D(14, 20), col)
|
||||
}
|
||||
particles.mapInPlace { case (t, p) => (t + 1.2f * UiHandler.dt, p) }
|
||||
particles.filterInPlace(_._1 <= 1f)
|
||||
}
|
||||
}
|
||||
|
||||
object NoteBlockNode {
|
||||
val pitches = List(
|
||||
val Pitches: Seq[Float] = List(
|
||||
0.500000f, 0.529732f, 0.561231f, 0.594604f, 0.629961f, 0.667420f, 0.707107f, 0.749154f, 0.793701f, 0.840896f, 0.890899f, 0.943874f,
|
||||
1.059463f, 1.122462f, 1.189207f, 1.259921f, 1.334840f, 1.414214f, 1.498307f, 1.587401f, 1.681793f, 1.781797f, 1.887749f, 2.000000f)
|
||||
|
||||
val instruments = List(
|
||||
private val Instruments = List(
|
||||
("bass", "Bass (Wood)"),
|
||||
("snare", "Snare Drum (Sand)"),
|
||||
("hat", "Hi-hat (Glass)"),
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package ocelot.desktop.node.nodes
|
||||
|
||||
import ocelot.desktop.ColorScheme
|
||||
import ocelot.desktop.geometry.{Size2D, Vector2D}
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
import ocelot.desktop.node.Node
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import totoro.ocelot.brain.entity.traits.{Entity, Environment}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
abstract class NoteBlockNodeBase(entity: Entity with Environment) extends Node(entity) {
|
||||
private val particles = mutable.ArrayBuffer[(Float, Int)]()
|
||||
|
||||
def addParticle(pitch: Int): Unit = {
|
||||
synchronized {
|
||||
particles += ((0f, pitch))
|
||||
}
|
||||
}
|
||||
|
||||
override def drawParticles(g: Graphics): Unit = synchronized {
|
||||
for ((time, pitch) <- particles.reverseIterator) {
|
||||
val col = ColorScheme("Note" + pitch).withAlpha(1 - (2 * time - 1).min(1).max(0))
|
||||
g.sprite("particles/Note", position + Vector2D(pitch / 24f * 40f + 5, height / 2 - 10 - 100 * time), Size2D(14, 20), col)
|
||||
}
|
||||
particles.mapInPlace { case (t, p) => (t + 1.2f * UiHandler.dt, p) }
|
||||
particles.filterInPlace(_._1 <= 1f)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user