Skip to content

Commit

Permalink
Add SFX items & Character voice font/text timer preview/editing (#293)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonko0493 authored Jun 26, 2023
1 parent 7f28815 commit 340cee2
Show file tree
Hide file tree
Showing 25 changed files with 489 additions and 62 deletions.
2 changes: 1 addition & 1 deletion azure-pipelines-official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ parameters:
type: string
default: 'Latest nightly build. **Note that this is likely to have bugs and we recommend you use a regular release instead!**'

name: 0.2.pre.$(Rev:r)
name: 0.3.pre.$(Rev:r)

variables:
- name: Version
Expand Down
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<Project>

<PropertyGroup Condition="'$(SLVersion)' == ''">
<SLVersion>0.2.local</SLVersion>
<SLAssemblyVersion>0.2.9999.9999</SLAssemblyVersion>
<SLVersion>0.3.local</SLVersion>
<SLAssemblyVersion>0.3.9999.9999</SLAssemblyVersion>
</PropertyGroup>

</Project>
1 change: 1 addition & 0 deletions src/SerialLoops.Gtk/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public static void Main(string[] args)
{
var platform = new Eto.GtkSharp.Platform();
platform.Add<SoundPlayer.ISoundPlayer>(() => new SoundPlayerHandler());
platform.Add<SfxMixer.ISfxMixer>(() => new SfxMixerHandler());

new Application(platform).Run(new MainForm());
}
Expand Down
20 changes: 20 additions & 0 deletions src/SerialLoops.Gtk/SfxMixerHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Eto.GtkSharp.Forms;
using Gtk;
using NAudio.Wave;
using SerialLoops.Utility;

namespace SerialLoops.Gtk
{
public class SfxMixerHandler : GtkControl<Button, SfxMixer, SfxMixer.ICallback>, SfxMixer.ISfxMixer
{
private ALWavePlayer _player;

public IWavePlayer Player => _player;

public SfxMixerHandler()
{
Control = new Button();
_player = new(new(), 16384);
}
}
}
7 changes: 6 additions & 1 deletion src/SerialLoops.Lib/Items/ItemDescription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public enum ItemType
Puzzle,
Scenario,
Script,
Sfx,
SFX,
System_Texture,
Topic,
Transition,
Expand Down Expand Up @@ -112,6 +112,11 @@ public List<ItemDescription> GetReferencesTo(Project project)
(((TopicItem)i).HiddenMainTopic?.EventIndex ?? -1) == script.Event.Index)));
references.AddRange(project.Items.Where(i => i.Type == ItemType.Script && ((ScriptItem)i).Event.ConditionalsSection.Objects.Contains(Name)));
return references;
case ItemType.SFX:
SfxItem sfx = (SfxItem)this;
references.AddRange(project.Items.Where(i => sfx.ScriptUses.Select(s => s.ScriptName).Contains(i.Name)));
references.AddRange(project.Items.Where(c => c.Type == ItemType.Character && ((CharacterItem)c).MessageInfo.VoiceFont == sfx.Index));
return references;
case ItemType.Topic:
TopicItem topic = (TopicItem)this;
return project.Items.Where(i => topic.ScriptUses.Select(s => s.ScriptName).Contains(i.Name)).ToList();
Expand Down
40 changes: 40 additions & 0 deletions src/SerialLoops.Lib/Items/SfxItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using HaruhiChokuretsuLib.Archive.Data;
using HaruhiChokuretsuLib.Archive.Event;
using HaruhiChokuretsuLib.Audio.SDAT.SoundArchiveComponents;
using HaruhiChokuretsuLib.Util;
using System.Collections.Generic;
using System.Linq;

namespace SerialLoops.Lib.Items
{
public class SfxItem : Item
{
public short Index { get; set; }
public SfxEntry Entry { get; set; }
public string AssociatedBank { get; private set; }
public List<string> AssociatedGroups { get; set; }
public (string ScriptName, ScriptCommandInvocation command)[] ScriptUses { get; set; }

public SfxItem(SfxEntry entry, string name, short index, Project project) : base(name, ItemType.SFX)
{
Entry = entry;
Index = index;
AssociatedBank = project.Snd.SequenceArchives[entry.SequenceArchive].File.Sequences[entry.Index].Bank.Name;
AssociatedGroups = project.Snd.Groups.Where(g => g.Entries.Any(e => e.LoadBank && ((BankInfo)e.Entry).Name.Equals(AssociatedBank))).Select(g => g.Name).ToList();
PopulateScriptUses(project);
}

public override void Refresh(Project project, ILogger log)
{
PopulateScriptUses(project);
}

public void PopulateScriptUses(Project project)
{
ScriptUses = project.Evt.Files.SelectMany(e =>
e.ScriptSections.SelectMany(sec =>
sec.Objects.Where(c => c.Command.Mnemonic == EventFile.CommandVerb.SND_PLAY.ToString()).Select(c => (e.Name[0..^1], c))))
.Where(t => t.c.Parameters[0] == Index).ToArray();
}
}
}
57 changes: 52 additions & 5 deletions src/SerialLoops.Lib/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using HaruhiChokuretsuLib.Archive.Data;
using HaruhiChokuretsuLib.Archive.Event;
using HaruhiChokuretsuLib.Archive.Graphics;
using HaruhiChokuretsuLib.Audio.SDAT;
using HaruhiChokuretsuLib.Font;
using HaruhiChokuretsuLib.Util;
using HaruhiChokuretsuLib.Util.Exceptions;
Expand Down Expand Up @@ -50,6 +51,8 @@ public class Project
public ArchiveFile<GraphicsFile> Grp { get; set; }
[JsonIgnore]
public ArchiveFile<EventFile> Evt { get; set; }
[JsonIgnore]
public SoundArchive Snd { get; set; }

[JsonIgnore]
public FontReplacementDictionary FontReplacement { get; set; } = new();
Expand All @@ -69,6 +72,8 @@ public class Project
[JsonIgnore]
public ScenarioStruct Scenario { get; set; }
[JsonIgnore]
public SoundDSFile SoundDS { get; set; }
[JsonIgnore]
public EventFile TopicFile { get; set; }
[JsonIgnore]
public MessageFile UiText { get; set; }
Expand Down Expand Up @@ -178,7 +183,7 @@ public void LoadProjectSettings(ILogger log, IProgressTracker tracker)

public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker)
{
tracker.Focus("dat.bin", 3);
tracker.Focus("dat.bin", 4);
try
{
Dat = ArchiveFile<DataFile>.FromFile(Path.Combine(IterativeDirectory, "original", "archives", "dat.bin"), log, false);
Expand Down Expand Up @@ -259,6 +264,18 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker)
}
tracker.Finished++;

tracker.CurrentlyLoading = "snd.bin";
try
{
Snd = new(Path.Combine(IterativeDirectory, "original", "archives", "snd.bin"));
}
catch (Exception ex)
{
log.LogException("Error occurred while loading snd.bin", ex);
return new(LoadProjectState.FAILED);
}
tracker.Finished++;

string charactersFile = LangCode switch
{
"ja" => "DefaultCharacters.ja.json",
Expand Down Expand Up @@ -403,10 +420,18 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker)
}
catch (Exception ex)
{
log.LogException($"Failed to background items", ex);
log.LogException("Failed to background items", ex);
return new(LoadProjectState.FAILED);
}

try
{
SoundDS = Dat.Files.First(s => s.Name == "SND_DSS").CastTo<SoundDSFile>();
}
catch (Exception ex)
{
log.LogException("Failed to load DS sound file.", ex);
}
try
{
if (VoiceMapIsV06OrHigher())
Expand All @@ -416,13 +441,13 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker)
}
catch (Exception ex)
{
log.LogException($"Failed to load voice map", ex);
log.LogException("Failed to load voice map", ex);
return new(LoadProjectState.FAILED);
}

try
{
string[] bgmFiles = Directory.GetFiles(Path.Combine(IterativeDirectory, "rom", "data", "bgm")).OrderBy(s => s).ToArray();
string[] bgmFiles = SoundDS.BgmSection.Where(bgm => bgm is not null).Select(bgm => Path.Combine(IterativeDirectory, "rom", "data", bgm)).ToArray(); /*Directory.GetFiles(Path.Combine(IterativeDirectory, "rom", "data", "bgm")).OrderBy(s => s).ToArray();*/
tracker.Focus("BGM Tracks", bgmFiles.Length);
for (int i = 0; i < bgmFiles.Length; i++)
{
Expand All @@ -438,7 +463,7 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker)

try
{
string[] voiceFiles = Directory.GetFiles(Path.Combine(IterativeDirectory, "rom", "data", "vce")).OrderBy(s => s).ToArray();
string[] voiceFiles = SoundDS.VoiceSection.Where(vce => vce is not null).Select(vce => Path.Combine(IterativeDirectory, "rom", "data", vce)).ToArray(); /*Directory.GetFiles(Path.Combine(IterativeDirectory, "rom", "data", "vce")).OrderBy(s => s).ToArray();*/
tracker.Focus("Voiced Lines", voiceFiles.Length);
for (int i = 0; i < voiceFiles.Length; i++)
{
Expand All @@ -452,6 +477,28 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker)
return new(LoadProjectState.FAILED);
}

try
{
tracker.Focus("Sound Effects", SoundDS.SfxSection.Count);
for (short i = 0; i < SoundDS.SfxSection.Count; i++)
{
if (SoundDS.SfxSection[i].Index < Snd.SequenceArchives[SoundDS.SfxSection[i].SequenceArchive].File.Sequences.Count)
{
string name = Snd.SequenceArchives[SoundDS.SfxSection[i].SequenceArchive].File.Sequences[SoundDS.SfxSection[i].Index].Name;
if (!name.Equals("SE_DUMMY"))
{
Items.Add(new SfxItem(SoundDS.SfxSection[i], name, i, this));
}
}
tracker.Finished++;
}
}
catch (Exception ex)
{
log.LogException("Failed to load sound effects", ex);
return new(LoadProjectState.FAILED);
}

try
{
tracker.Focus("Character Sprites", 1);
Expand Down
11 changes: 6 additions & 5 deletions src/SerialLoops.Lib/Script/Parameters/SfxScriptParameter.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
using HaruhiChokuretsuLib.Archive.Event;
using SerialLoops.Lib.Items;

namespace SerialLoops.Lib.Script.Parameters
{
public class SfxScriptParameter : ScriptParameter
{
public short SfxIndex { get; set; }
public override short[] GetValues(object obj = null) => new short[] { SfxIndex };
public SfxItem Sfx { get; set; }
public override short[] GetValues(object obj = null) => new short[] { Sfx.Index };

public SfxScriptParameter(string name, short sfxIndex) : base(name, ParameterType.SFX)
public SfxScriptParameter(string name, SfxItem sfx) : base(name, ParameterType.SFX)
{
SfxIndex = sfxIndex;
Sfx = sfx;
}

public override SfxScriptParameter Clone(Project project, EventFile eventFile)
{
return new(Name, SfxIndex);
return new(Name, Sfx);
}
}
}
2 changes: 1 addition & 1 deletion src/SerialLoops.Lib/Script/ScriptItemCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ private static List<ScriptParameter> GetScriptParameters(ScriptCommandInvocation
switch (i)
{
case 0:
parameters.Add(new SfxScriptParameter("Sound", parameter));
parameters.Add(new SfxScriptParameter("Sound", (SfxItem)project.Items.First(s => s.Type == ItemDescription.ItemType.SFX && ((SfxItem)s).Index == parameter)));
break;
case 1:
parameters.Add(new SfxModeScriptParameter("Mode", parameter));
Expand Down
2 changes: 1 addition & 1 deletion src/SerialLoops.Lib/SerialLoops.Lib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageReference Include="BunLabs.NAudio.Flac" Version="2.0.1" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2.3" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.macOS" Version="2.8.2.3" />
<PackageReference Include="HaruhiChokuretsuLib" Version="0.31.1" />
<PackageReference Include="HaruhiChokuretsuLib" Version="0.32.0" />
<PackageReference Include="NAudio.Vorbis" Version="1.5.0" />
<PackageReference Include="NitroPacker.Core" Version="2.2.5" />
<PackageReference Include="NLayer" Version="1.14.0" />
Expand Down
1 change: 1 addition & 0 deletions src/SerialLoops.Mac/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public static void Main(string[] args)
{
var platform = new Eto.Mac.Platform();
platform.Add<SoundPlayer.ISoundPlayer>(() => new SoundPlayerHandler());
platform.Add<SfxMixer.ISfxMixer>(() => new SfxMixerHandler());

Eto.Style.Add<Eto.Mac.Forms.ApplicationHandler>(null, handler =>
{
Expand Down
20 changes: 20 additions & 0 deletions src/SerialLoops.Mac/SfxMixerHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Eto.Mac.Forms.Controls;
using MonoMac.AppKit;
using NAudio.Wave;
using SerialLoops.Utility;

namespace SerialLoops.Mac
{
public class SfxMixerHandler : MacControl<NSControl, SfxMixer, SfxMixer.ICallback>, SfxMixer.ISfxMixer
{
private ALWavePlayer _player;

public IWavePlayer Player => _player;

public SfxMixerHandler()
{
Control = new NSControl();
_player = new(new(), 16384);
}
}
}
2 changes: 1 addition & 1 deletion src/SerialLoops.Wpf/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Eto.Wpf;
using Eto.Wpf.Forms.Controls;
using Eto.Wpf.Forms.ToolBar;
using SerialLoops.Utility;
using System;
Expand All @@ -15,6 +14,7 @@ public static void Main(string[] args)
{
var platform = new Platform();
platform.Add<SoundPlayer.ISoundPlayer>(() => new SoundPlayerHandler());
platform.Add<SfxMixer.ISfxMixer>(() => new SfxMixerHandler());

// Windows toolbar styling
Eto.Style.Add<ToolBarHandler>("sl-toolbar", toolbar =>
Expand Down
20 changes: 20 additions & 0 deletions src/SerialLoops.Wpf/SfxMixerHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Eto.Wpf.Forms;
using NAudio.Wave;
using SerialLoops.Utility;
using System.Windows.Controls;

namespace SerialLoops.Wpf
{
public class SfxMixerHandler : WpfControl<Control, SfxMixer, SfxMixer.ICallback>, SfxMixer.ISfxMixer
{
private WaveOut _player;

public IWavePlayer Player => _player;

public SfxMixerHandler()
{
Control = new Control();
_player = new() { DesiredLatency = 100 };
}
}
}
8 changes: 7 additions & 1 deletion src/SerialLoops/Controls/EditorTabsPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private DocumentPage CreateTab(ItemDescription item, Project project, ILogger lo
return new BackgroundMusicEditor(
(BackgroundMusicItem)project.Items.First(i => i.Name == item.Name), project, log);
case ItemDescription.ItemType.Character:
return new CharacterEditor((CharacterItem)project.Items.First(i => i.Name == item.Name), project, log);
return new CharacterEditor((CharacterItem)project.Items.First(i => i.Name == item.Name), project, this, log);
case ItemDescription.ItemType.Character_Sprite:
return new CharacterSpriteEditor(
(CharacterSpriteItem)project.Items.First(i => i.Name == item.Name), project, log);
Expand All @@ -100,6 +100,8 @@ private DocumentPage CreateTab(ItemDescription item, Project project, ILogger lo
return new ScenarioEditor((ScenarioItem)project.Items.First(i => i.Name == item.Name), log, project, this);
case ItemDescription.ItemType.Script:
return new ScriptEditor((ScriptItem)project.Items.First(i => i.Name == item.Name), log, project, this);
case ItemDescription.ItemType.SFX:
return new SfxEditor((SfxItem)project.Items.First(i => i.Name == item.Name), project, log);
case ItemDescription.ItemType.System_Texture:
return new SystemTextureEditor((SystemTextureItem)project.Items.First(i => i.Name == item.Name), project, log);
case ItemDescription.ItemType.Topic:
Expand All @@ -122,6 +124,10 @@ private void Tabs_PageClosed(object sender, DocumentPageEventArgs e)
{
((VoicedLineEditor)e.Page).VcePlayer.Stop();
}
else if (e.Page.GetType() == typeof(SfxEditor))
{
((SfxEditor)e.Page).Player.Dispose();
}

if (Tabs.SelectedPage is null)
{
Expand Down
Loading

0 comments on commit 340cee2

Please sign in to comment.