Skip to content

Commit b085081

Browse files
committed
Handle NBS "layer lock" value properly
Implements the undocumented layer solo flag
1 parent 289163f commit b085081

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ org.gradle.configuration-cache=true
55
java_version=8
66
maven_group=net.raphimc
77
maven_name=NoteBlockLib
8-
maven_version=3.0.1-SNAPSHOT
8+
maven_version=3.1.0-SNAPSHOT

src/main/java/net/raphimc/noteblocklib/format/nbs/NbsIo.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,18 @@ public static NbsSong readSong(final InputStream is, final String fileName) thro
113113
final NbsLayer layer = layers.computeIfAbsent(i, k -> new NbsLayer());
114114
layer.setName(readString(dis));
115115
if (song.getVersion() >= 4) {
116-
layer.setLocked(dis.readBoolean());
116+
final byte lockedByte = dis.readByte();
117+
switch (lockedByte) {
118+
case 0:
119+
layer.setStatus(NbsLayer.Status.NONE);
120+
break;
121+
case 1:
122+
layer.setStatus(NbsLayer.Status.LOCKED);
123+
break;
124+
case 2:
125+
layer.setStatus(NbsLayer.Status.SOLO);
126+
break;
127+
}
117128
}
118129
layer.setVolume(dis.readByte());
119130
if (song.getVersion() >= 2) {
@@ -141,6 +152,7 @@ public static NbsSong readSong(final InputStream is, final String fileName) thro
141152
}
142153

143154
song.getTempoEvents().set(0, song.getTempo() / 100F);
155+
final boolean hasSoloLayers = layers.values().stream().anyMatch(layer -> layer.getStatus() == NbsLayer.Status.SOLO);
144156
for (NbsLayer layer : layers.values()) {
145157
for (Map.Entry<Integer, NbsNote> noteEntry : layer.getNotes().entrySet()) {
146158
final NbsNote nbsNote = noteEntry.getValue();
@@ -172,7 +184,9 @@ public static NbsSong readSong(final InputStream is, final String fileName) thro
172184
}
173185
}
174186

175-
if (layer.isLocked()) { // Locked layers are muted
187+
if (layer.getStatus() == NbsLayer.Status.LOCKED) { // Locked layers are muted
188+
note.setVolume(0F);
189+
} else if (hasSoloLayers && layer.getStatus() != NbsLayer.Status.SOLO) { // Non-solo layers are muted if there are solo layers
176190
note.setVolume(0F);
177191
}
178192

@@ -261,7 +275,17 @@ public static void writeSong(final NbsSong song, final OutputStream os) throws I
261275
final NbsLayer layer = song.getLayers().get(i);
262276
writeString(dos, layer.getNameOr(""));
263277
if (song.getVersion() >= 4) {
264-
dos.writeBoolean(layer.isLocked());
278+
switch (layer.getStatus()) {
279+
case NONE:
280+
dos.writeByte(0);
281+
break;
282+
case LOCKED:
283+
dos.writeByte(1);
284+
break;
285+
case SOLO:
286+
dos.writeByte(2);
287+
break;
288+
}
265289
}
266290
dos.writeByte(layer.getVolume());
267291
if (song.getVersion() >= 2) {

src/main/java/net/raphimc/noteblocklib/format/nbs/model/NbsLayer.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@ public class NbsLayer {
4747
/**
4848
* @since v4
4949
*/
50-
private boolean locked;
50+
private Status status;
5151

5252
public NbsLayer() {
5353
this.volume = 100;
5454
this.panning = NbsDefinitions.CENTER_PANNING;
55+
this.status = Status.NONE;
5556
}
5657

5758
/**
@@ -71,8 +72,8 @@ public String getName() {
7172
}
7273

7374
/**
74-
* @return The name of the layer.
7575
* @param fallback The fallback value if the layer name is not set.
76+
* @return The name of the layer.
7677
* @since v0
7778
*/
7879
public String getNameOr(final String fallback) {
@@ -130,20 +131,20 @@ public NbsLayer setPanning(final short panning) {
130131
}
131132

132133
/**
133-
* @return Whether this layer has been marked as locked.
134+
* @return The status of this layer (none, locked or solo).
134135
* @since v4
135136
*/
136-
public boolean isLocked() {
137-
return this.locked;
137+
public Status getStatus() {
138+
return this.status;
138139
}
139140

140141
/**
141-
* @param locked Whether this layer should be marked as locked.
142+
* @param status The status of this layer (none, locked or solo).
142143
* @return this
143144
* @since v4
144145
*/
145-
public NbsLayer setLocked(final boolean locked) {
146-
this.locked = locked;
146+
public NbsLayer setStatus(final Status status) {
147+
this.status = status;
147148
return this;
148149
}
149150

@@ -152,7 +153,7 @@ public NbsLayer copy() {
152153
copyLayer.setName(this.name);
153154
copyLayer.setVolume(this.volume);
154155
copyLayer.setPanning(this.panning);
155-
copyLayer.setLocked(this.locked);
156+
copyLayer.setStatus(this.status);
156157
final Map<Integer, NbsNote> notes = this.getNotes();
157158
final Map<Integer, NbsNote> copyNotes = copyLayer.getNotes();
158159
for (final Map.Entry<Integer, NbsNote> entry : notes.entrySet()) {
@@ -161,4 +162,13 @@ public NbsLayer copy() {
161162
return copyLayer;
162163
}
163164

165+
public enum Status {
166+
167+
NONE,
168+
LOCKED,
169+
SOLO,
170+
171+
}
172+
173+
164174
}

0 commit comments

Comments
 (0)