KSoundFontMenu
#1
KSoundFontMenu

HiddenChest Exclusive!
XP + VX + ACE Related

by Kyonides

This scriptlet allows you to actually play a specific MIDI melody AND change the current synthesizer's SoundFont! Shocked

All of these scripts will only work by running the HiddenChest binary executable.

There are certain consideration to take in consideration before using it:
  • The MIDI file should be playing BEFORE you proceed to call Setup.choose_soundfont(index)
    Otherwise the change would be ignored by the internal system.
  • Some scenes might take advantage of setting the current soundfont again, no filename change involved here, to make sure it will be using the selected soundfont.
    Yet, it is not mandatory because this apparent issue could have been caused by using some soundfonts with similar sound sets.
  • The change may take a couple of seconds to take effect.
    That is why I added the "Processing New SF..." label to the KSoundFont module. Laughing

Extra Step

Add the following lines to your Game.ini file:

Code:
SoundFontWin=C:/Audio/SF2/GMGSx.sf2
SoundFontLnx=/home/user/Maker/GMGSx.sf2
SoundFontPathWin=C:/Music/SF2
SoundFontPathLnx=/home/user/Music/SF2

These lines will allow the HiddenChest engine find your custom SoundFonts on both Windows & Linux! Shocked
Keep in mind that HiddenChest has always been a cross-platform engine. Winking


Script Calls

Open the KSoundFont::Menu Scene depending on your RM Editor:
Code:
$scene = KSoundFont::Menu.new
SceneManager(KSoundFont::Menu)

Select Your Favorite SoundFont - All Versions:
Code:
Game.choose_soundfont(index)

Getting and Saving the Index of Your Favorite SoundFont
Code:
$game_system.soundfont_index
$game_system.soundfont_index = Number

Getting a SoundFont (Full Path) Based on its Current Position:
Code:
Game.soundfonts[index]

Default SoundFont (if it Exists):
Code:
System::SOUNDFONT

Default SoundFont Directory (It Should Exist if you ever pretend to add 2+ SoundFonts):
Code:
System::SOUNDFONT_DIR


Scripts Section

Script For RMXP Editor
Code:
# * KSoundFontMenu XP * #
#   Scripter : Kyonides Arkanthes
#   2024-06-03
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI
#       synthetizer might ignore your request at that specific point.
#       Calling the same method at the beginning of KSoundFont::Menu ensures it
#       will always play the MIDI using the chosen soundfont.
# * Script Call * #
# $scene = KSoundFont::Menu.new
module KSoundFont
  START_SF = [0]
  TITLE = "Select a SoundFont"
  THIS_SOUNDFONT = "Current SoundFont"
  DELAY_MESSAGE = "Processing New SF..."
  NO_SOUNDFONT = "No SoundFont"
  TRANSPARENT = Color.new(0, 0, 0, 0)
class PathsWindow < Window_Command
  def initialize(w, paths)
    @paths = paths
    commands = paths.map {|fn| fn.split(/[\/|\\]/)[-1].sub(".sf2", "") }
    super(w, commands)
  end
  def path
    @paths[@index]
  end
  def name
    @commands[@index]
  end
end
class SmallInfoWindow < Window_Base
  def initialize(wx, wy, w, h)
    super
    self.contents = Bitmap.new(w - 32, h - 32)
    contents.font.color = system_color
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)
    contents.font.color = normal_color
  end
  def set_text(text)
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)
    contents.draw_text(0, 32, width - 32, 32, text, 1)
  end
end
class Menu
  def main
    @timer = 0
    pos = $game_system.soundfont_index
    Game.choose_soundfont(pos)
    soundfonts = Game.soundfonts
    gs_indexes = $game_system.soundfont_indexes
    if gs_indexes.any?
      @indexes = gs_indexes.sort
      if @indexes.size < soundfonts.size
        soundfonts = @indexes.map{|n| soundfonts[n] }
      end
    end
    @total = soundfonts.size
    @full_list = Game.soundfonts.size == @total
    soundfont = soundfonts[pos]
    dialog_box soundfont
    if soundfonts.any?
      soundfont = soundfont.split(/[\/|\\]/)[-1].sub(".sf2", "")
    else
      soundfont = NO_SOUNDFONT
    end
    @help_window = Window_Help.new
    @help_window.set_text(TITLE, 1)
    @command_window = PathsWindow.new(192, soundfonts)
    @command_window.y = 64
    @command_window.index = pos
    @info_window = SmallInfoWindow.new(192, @command_window.y, 240, 96)
    @info_window.set_text(soundfont)
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      break if $scene != self
    end
    Graphics.freeze
    @info_window.dispose
    @command_window.dispose
    @help_window.dispose
  end
  def update
    if @timer > 0
      @timer -= 1
      if @timer == 0
        @info_window.set_text(@command_window.name)
      end
      return
    end
    @command_window.update
    if Input.trigger?(Input::B) or Input.double_right_click?
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Map.new
      return
    elsif Input.trigger?(Input::C) or Input.double_left_click?
      if @total < 2
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      n = @command_window.index
      n = @indexes[n] unless @full_list
      $game_system.soundfont_index = n
      @info_window.set_text(DELAY_MESSAGE)
      @timer = Graphics.frame_rate * 2
    elsif Input.trigger?(Input::SHIFT)
      $game_system.se_play($data_system.cursor_se)
      Graphics.screenshot
    end
  end
end
end
class Game_System
  alias :kyon_soundfont_menu_gm_sys_init :initialize
  def initialize
    kyon_soundfont_menu_gm_sys_init
    self.soundfont_index = find_soundfont_index
    @soundfont_indexes = KSoundFont::START_SF.dup
  end
  def find_soundfont_index
    Game.soundfont_index || 0
  end
  def soundfont_index
    @soundfont_index ||= find_soundfont_index
  end
  def soundfont_index=(n)
    Game.choose_soundfont(n)
    @soundfont_index = n
  end
  def soundfont_indexes
    @soundfont_indexes ||= []
  end
end
class Scene_Load
  alias :kyon_soundfont_menu_scn_ld_rsd :read_save_data
  def read_save_data(file)
    kyon_soundfont_menu_scn_ld_rsd(file)
    $game_system.bgm_play($game_system.playing_bgm)
    Game.choose_soundfont($game_system.soundfont_index)
  end
end

Script for RMVX Editor
Code:
# * KSoundFontMenu VX * #
#   Scripter : Kyonides Arkanthes
#   2024-06-03
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI
#       synthetizer might ignore your request at that specific point.
#       Calling the same method at the beginning of KSoundFont::Menu ensures it
#       will always play the MIDI using the chosen soundfont.
# * Script Call * #
# $scene = KSoundFont::Menu.new
module KSoundFont
  START_SF = [0]
  TITLE = "Select a SoundFont"
  THIS_SOUNDFONT = "Current SoundFont"
  DELAY_MESSAGE = "Processing New SF..."
  NO_SOUNDFONT = "No SoundFont"
  TRANSPARENT = Color.new(0, 0, 0, 0)
class PathsWindow < Window_Command
  def initialize(w, paths)
    @paths = paths
    commands = paths.map {|fn| fn.split(/[\/|\\]/)[-1].sub(".sf2", "") }
    super(w, commands)
  end
  def path
    @paths[@index]
  end
  def name
    @commands[@index]
  end
end
class SmallInfoWindow < Window_Base
  def initialize(wx, wy, w, h)
    super
    self.contents = Bitmap.new(w - 32, h - 32)
    contents.font.color = system_color
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)
    contents.font.color = normal_color
  end
  def set_text(text)
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)
    contents.draw_text(0, 32, width - 32, 32, text, 1)
  end
end
class Menu
  def main
    @timer = 0
    pos = $game_system.soundfont_index
    Game.choose_soundfont(pos)
    soundfonts = Game.soundfonts
    gs_indexes = $game_system.soundfont_indexes
    if gs_indexes.any?
      @indexes = gs_indexes.sort
      if @indexes.size < soundfonts.size
        soundfonts = @indexes.map{|n| soundfonts[n] }
      end
    end
    @total = soundfonts.size
    @full_list = Game.soundfonts.size == @total
    soundfont = soundfonts[pos]
    if soundfonts.any?
      soundfont = soundfont.split(/[\/|\\]/)[-1].sub(".sf2", "")
    else
      soundfont = NO_SOUNDFONT
    end
    @help_window = Window_Help.new
    @help_window.set_text(TITLE, 1)
    hwy = @help_window.height
    @command_window = PathsWindow.new(192, soundfonts)
    @command_window.y = hwy
    @command_window.index = pos
    @info_window = SmallInfoWindow.new(192, hwy, 240, 96)
    @info_window.set_text(soundfont)
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      break if $scene != self
    end
    Graphics.freeze
    @info_window.dispose
    @command_window.dispose
    @help_window.dispose
  end
  def update
    if @timer > 0
      @timer -= 1
      if @timer == 0
        @info_window.set_text(@command_window.name)
      end
      return
    end
    @command_window.update
    if Input.trigger?(Input::B) or Input.double_right_click?
      Sound.play_cancel
      $scene = Scene_Map.new
      return
    elsif Input.trigger?(Input::C) or Input.double_left_click?
      return Sound.play_buzzer if @total < 2
      Sound.play_decision
      n = @command_window.index
      n = @indexes[n] unless @full_list
      $game_system.soundfont_index = n
      @info_window.set_text(DELAY_MESSAGE)
      @timer = Graphics.frame_rate * 2
    elsif Input.trigger?(Input::SHIFT)
      Sound.play_cursor
      Graphics.screenshot
    end
  end
end
end
class Game_System
  alias :kyon_soundfont_menu_gm_sys_init :initialize
  def initialize
    kyon_soundfont_menu_gm_sys_init
    self.soundfont_index = find_soundfont_index
    @soundfont_indexes = KSoundFont::START_SF.dup
  end
  def find_soundfont_index
    Game.soundfont_index || 0
  end
  def soundfont_index
    @soundfont_index ||= find_soundfont_index
  end
  def soundfont_index=(n)
    Game.choose_soundfont(n)
    @soundfont_index = n
  end
  def soundfont_indexes
    @soundfont_indexes ||= []
  end
end
class Scene_File
  alias :kyon_soundfont_menu_scn_fl_rsd :read_save_data
  def read_save_data(file)
    kyon_soundfont_menu_scn_fl_rsd(file)
    @last_bgm.play
    Game.choose_soundfont($game_system.soundfont_index)
  end
end

Script for RMVX ACE Editor
Code:
# * KSoundFontMenu ACE * #
#   Scripter : Kyonides Arkanthes
#   2024-06-03
# Note: It seems like the MIDI file should be playing BEFORE you proceed to call
#       Game.choose_soundfont while loading a save game. Otherwise, the MIDI
#       synthetizer might ignore your request at that specific point.
#       Calling the same method at the beginning of KSoundFont::Menu ensures it
#       will always play the MIDI using the chosen soundfont.
# * Script Call * #
# SceneManager(KSoundFont::Menu)
module KSoundFont
  START_SF = [0]
  TITLE = "Select a SoundFont"
  THIS_SOUNDFONT = "Current SoundFont"
  DELAY_MESSAGE = "Processing New SF..."
  NO_SOUNDFONT = "No SoundFont"
  TRANSPARENT = Color.new(0, 0, 0, 0)
class HelpWindow < Window_Help
  def set_text(text, align)
    return if text == @text and align == @align
    @text = text
    @align = align
    refresh
  end
  def refresh
    contents.clear
    draw_text(contents.rect, @text, @align)
  end
end
class PathsWindow < Window_Selectable
  def initialize(w, paths)
    @paths = paths
    @commands = paths.map {|fn| fn.split(/[\/|\\]/)[-1].sub(".sf2", "") }
    @item_max = @commands.size
    h = @item_max * line_height + line_height
    super(0, 0, w, h)
    return if @item_max == 0
    refresh
    self.active = true
  end
  def draw_all_items
    @item_max.times do |n|
      rect = @area[n] ||= item_rect_for_text(n)
      draw_text(rect, @commands[n])
    end
  end
  def process_handling
   
  end
  def path
    @paths[@index]
  end
  def name
    @commands[@index]
  end
  attr_reader :item_max
end
class SmallInfoWindow < Window_Base
  def initialize(wx, wy, w, h)
    super
    self.contents = Bitmap.new(w - 32, h - 32)
    contents.font.color = system_color
    contents.draw_text(0, 0, w - 32, 32, THIS_SOUNDFONT, 1)
    contents.font.color = normal_color
  end
  def set_text(text)
    contents.fill_rect(0, 32, width - 32, 32, TRANSPARENT)
    contents.draw_text(0, 32, width - 32, 32, text, 1)
  end
end
class Menu < Scene_Base
  def start
    super
    @timer = 0
    pos = $game_system.soundfont_index
    Game.choose_soundfont(pos)
    soundfonts = Game.soundfonts
    gs_indexes = $game_system.soundfont_indexes
    if gs_indexes.any?
      @indexes = gs_indexes.sort
      if @indexes.size < soundfonts.size
        soundfonts = @indexes.map{|n| soundfonts[n] }
      end
    end
    @total = soundfonts.size
    @full_list = Game.soundfonts.size == @total
    soundfont = soundfonts[pos]
    if soundfonts.any?
      soundfont = soundfont.split(/[\/|\\]/)[-1].sub(".sf2", "")
    else
      soundfont = NO_SOUNDFONT
    end
    @help_window = HelpWindow.new
    @help_window.set_text(TITLE, 1)
    hwy = @help_window.height
    @command_window = PathsWindow.new(192, soundfonts)
    @command_window.y = hwy
    @command_window.index = pos
    @info_window = SmallInfoWindow.new(192, hwy, 240, 96)
    @info_window.set_text(soundfont)
  end
  def update
    Graphics.update
    Input.update
    if @timer > 0
      @timer -= 1
      if @timer == 0
        @info_window.set_text(@command_window.name)
      end
      return
    end
    @command_window.update
    if Input.trigger?(:B) or Input.double_right_click?
      Sound.play_cancel
      SceneManager.return
      return
    elsif Input.trigger?(:C) or Input.double_left_click?
      return Sound.play_buzzer if @total < 2
      Sound.play_ok
      n = @command_window.index
      n = @indexes[n] unless @full_list
      $game_system.soundfont_index = n
      @info_window.set_text(DELAY_MESSAGE)
      @timer = Graphics.frame_rate * 2
    elsif Input.trigger?(:SHIFT)
      Sound.play_cursor
      Graphics.screenshot
    end
  end
end
end
class Game_System
  alias :kyon_soundfont_menu_gm_sys_init :initialize
  alias :kyon_soundfont_menu_gm_sys_on_after_load :on_after_load
  def initialize
    kyon_soundfont_menu_gm_sys_init
    self.soundfont_index = find_soundfont_index
    @soundfont_indexes = KSoundFont::START_SF.dup
  end
  def find_soundfont_index
    Game.soundfont_index || 0
  end
  def soundfont_index
    @soundfont_index ||= find_soundfont_index
  end
  def soundfont_index=(n)
    Game.choose_soundfont(n)
    @soundfont_index = n
  end
  def soundfont_indexes
    @soundfont_indexes ||= []
  end
  def on_after_load
    kyon_soundfont_menu_gm_sys_on_after_load
    Game.choose_soundfont($game_system.soundfont_index)
  end
end

Screenshots

3 Snapshots

Terms & Conditions

Free for any kind of game running on the HiddenChest engine. Winking
Due credit is mandatory.
Don't post the contents of this topic anywhere else!
You better paste a link to this thread and make them come here instead.
That's it! Tongue sticking out


Attached Files
.jpg   ksoundfont_vx001.jpg (Size: 40.18 KB / Downloads: 22)
.jpg   ksoundfont_ace001.jpg (Size: 32.63 KB / Downloads: 4)
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply }
#2
Small But Important Update

Because HiddenChest version 1.1.71 has been released for both Windows & Linux, I was in dire need of updating these scripts to replace all the old references to the deprecated Setup module. All of its methods have now been merged with the Game module's.

I have also edited the first post to reflect all of these changes.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply }
#3
Small Update

I've updated all of my scripts to make sure it will find the soundfonts as first intended. The problem was caused by not clearly defining the condition that would split the list or the default soundfont or even the last selected one.

There's also a need to tell you that you'd need to upgrade HiddenChest to version 1.1.76 or later because that's the first release that finally included a fix involving finding the SoundFontPath on both Windows & Linux.
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply }




Users browsing this thread: 4 Guest(s)