Go Back   The PokéCommunity Forums > Creative Discussions > Game Development > Pokémon Essentials
Reload this Page Your suggestions for Essentials

Notices
For all updates, view the main page.

Pokémon Essentials All questions and discussion about Pokémon Essentials, the Pokémon game kit for RPG Maker XP, go in here. Also contains links to the latest downloads and the Essentials Wiki.



Reply
 
Thread Tools
  #226    
Old March 11th, 2015 (12:49 AM). Edited March 11th, 2015 by KillerMapper.
KillerMapper's Avatar
KillerMapper KillerMapper is offline
Helix Follower
 
Join Date: Sep 2014
Location: Paris
Gender: Male
Posts: 151
I also forgot to say that we can't copy the code if it includes emotes (: + S will do for example).

Better use CODE tag (or disable smilies in the post), like this:

Code:
#==============================================================================
# ** FModEx
#------------------------------------------------------------------------------
#  FMOD Ex binding by Kevin Gadd ([email protected])
#==============================================================================
unless $FMODEX
  $FMODEX=true
module FModEx
  #--------------------------------------------------------------------------
  # * Constants
  #--------------------------------------------------------------------------
  # FMOD_INITFLAGS flags
  FMOD_INIT_NORMAL = 0
  # FMOD_RESULT flags
  FMOD_OK = 0
  FMOD_ERR_CHANNEL_STOLEN = 11
  FMOD_ERR_FILE_NOT_FOUND = 23
  FMOD_ERR_INVALID_HANDLE = 36
  # FMOD_MODE flags
  FMOD_DEFAULT = 0
  FMOD_LOOP_OFF = 1
  FMOD_LOOP_NORMAL = 2
  FMOD_LOOP_BIDI = 4
  FMOD_LOOP_BITMASK = 7
  FMOD_2D = 8
  FMOD_3D = 16
  FMOD_HARDWARE = 32
  FMOD_SOFTWARE = 64
  FMOD_CREATESTREAM = 128
  FMOD_CREATESAMPLE = 256
  FMOD_OPENUSER = 512
  FMOD_OPENMEMORY = 1024
  FMOD_OPENRAW = 2048
   FMOD_OPENONLY = 4096
   FMOD_OPENMEMORY_POINT = 0x10000000
  FMOD_ACCURATETIME = 8192
  FMOD_MPEGSEARCH = 16384
  FMOD_NONBLOCKING = 32768
  FMOD_UNIQUE = 65536
  # The default mode that the script uses
  FMOD_DEFAULT_SOFTWARWE = FMOD_LOOP_OFF | FMOD_2D | FMOD_SOFTWARE
  FMOD_TEST = FMOD_OPENMEMORY | FMOD_SOFTWARE
  # FMOD_CHANNELINDEX flags
  FMOD_CHANNEL_FREE = -1
  FMOD_CHANNEL_REUSE = -2
  # FMOD_TIMEUNIT_flags
  FMOD_TIMEUNIT_MS = 1
  FMOD_TIMEUNIT_PCM = 2
  # The default time unit the script uses
  FMOD_DEFAULT_UNIT = FMOD_TIMEUNIT_MS
  # Types supported by FMOD Ex
  FMOD_FILE_TYPES = ['ogg', 'aac', 'wma', 'mp3', 'wav', 'it', 'xm', 'mod', 's3m', 'mid', 'midi']
  
  #============================================================================
  # ** DLL
  #----------------------------------------------------------------------------
  #  A class that manages importing functions from the DLL
  #============================================================================
  
  class DLL
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #--------------------------------------------------------------------------
    attr_accessor :filename           # DLL file name for instance    
    attr_accessor :functions          # hash of functions imported (by name)
         
    Functions = {}
    Sys_C='System_Create'
    W32_LL = Win32API.new('kernel32.dll', 'LoadLibrary', 'p', 'l')
    FN='fmodex.dll'
    F='f'
    L='l'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     filename  : Name of the DLL
    #--------------------------------------------------------------------------
    def initialize(filename = FN)
      @filename = filename
      @handle = 0            # Handle to the DLL
      # Load specified library into the address space of game process
      
      @handle = W32_LL.call(filename)
      unless Functions[Sys_C]
      # System functions:
        self.import(Sys_C, 'p')
        self.import('System_Init', 'llll')
        self.import('System_Close', 'l')
        self.import('System_Release', 'l')
        self.import('System_CreateSound', 'lplpp')
        self.import('System_CreateStream', 'lplpp')
        self.import('System_PlaySound', 'llllp')
        # Sound functions:
        self.import('Sound_Release', 'l')
        self.import('Sound_GetMode', 'lp')
        self.import('Sound_SetMode', 'll')
        self.import('Sound_SetLoopPoints', 'lllll')
        self.import('Sound_GetLength', 'lpl')
        # Channel functions:
        self.import('Channel_Stop', 'l')
        self.import('Channel_IsPlaying', 'lp')
        self.import('Channel_GetPaused', 'lp')
        self.import('Channel_SetPaused', 'll')
        self.import('Channel_GetVolume', 'lp')
        self.import('Channel_SetVolume', 'll')
        self.import('Channel_GetPan', 'lp')
        self.import('Channel_SetPan', 'll')
        self.import('Channel_GetFrequency', 'lp')
        self.import('Channel_SetFrequency', 'll')
        self.import('Channel_GetPosition', 'lpl')
        self.import('Channel_SetPosition', 'lll')
      end
    end
    #--------------------------------------------------------------------------
    # * Create a Win32API Object And Add it to Hashtable
    #     name      : Function name
    #     args      : Argument types (p = pointer, l = int, v = void)
    #     returnType: Type of value returned by function
    #--------------------------------------------------------------------------
    def import(name, args = '', returnType = L)
      Functions[name] = Win32API.new(@filename, 'FMOD_' + name, args, returnType)
    end
    #--------------------------------------------------------------------------
    # * Get Function by Name
    #     key       : Function name
    #--------------------------------------------------------------------------
    def [](key)
      return Functions[key]
    end
    #--------------------------------------------------------------------------
    # * Call a Function With Passed Arguments
    #     name      : Function name
    #     args      : Argument to function
    #--------------------------------------------------------------------------
    def invoke(name, *args)
      fn = Functions[name]
      raise "function not imported: #{name}" if fn.nil?
      result = fn.call(*args)
      unless result == FMOD_OK or result == FMOD_ERR_CHANNEL_STOLEN or
        result == FMOD_ERR_FILE_NOT_FOUND
        if result==36
          Audio.se_clean unless $FMOD_CLEANING
        else
          print "FMOD Ex returned error #{result}.\n"
        end
      end
      return result
    end
    #--------------------------------------------------------------------------
    # * Store Float as Binary Int Because Floats Can't be Passed Directly
    #     f         : Float to convert
    #--------------------------------------------------------------------------
    def convertFloat(f)
      # First pack the float in a string as a native binary float
      temp = [f].pack(F)
      # Then unpack the native binary float as an integer
      return unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Unpack Binary Data to Integer
    #     s         : String containing binary data
    #--------------------------------------------------------------------------
    def unpackInt(s)
      return s.unpack(L)[0]
    end
    #--------------------------------------------------------------------------
    # * Unpack Binary Data to Float
    #     s         : String containing binary data
    #--------------------------------------------------------------------------
    def unpackFloat(s)
      return s.unpack(F)[0]
    end
    #--------------------------------------------------------------------------
    # * Unpack Binary Data to Boolean
    #     s         : String containing binary data
    #--------------------------------------------------------------------------
    def unpackBool(s)
      return s.unpack(L)[0] != 0
    end
  end

  #============================================================================
  # ** System
  #----------------------------------------------------------------------------
  #  A class that manages an instance of FMOD::System
  #============================================================================
  
  class System
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #-------------------------------------------------------------------------- 
    attr_accessor :fmod               # Instance of DLL class (fmodex.dll)
    attr_accessor :handle             # Handle (pointer) to System object
    attr_accessor :maxChannels        # Maximum number of channels
    System_Create='System_Create'
    System_Init='System_Init'
    System_CreateSound='System_CreateSound'
    UX="U*"
    CX="C*"
    System_CreateStream='System_CreateStream'
    System_Close='System_Close'
    System_Release='System_Release'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     fmod            : An instance of DLL class
    #     maxChannels     : Maximum number of used channels
    #     flags           : FMOD_INITFLAGS
    #     extraDriverData : Driver specific data
    #--------------------------------------------------------------------------
    def initialize(theDLL, maxChannels = 32, flags = FMOD_INIT_NORMAL, extraDriverData = 0)
      @fmod = theDLL
      @maxChannels = maxChannels
      # Create and initialize FMOD::System
      temp = 0.chr * 4
      @fmod.invoke(System_Create, temp)
      @handle = @fmod.unpackInt(temp)
      @fmod.invoke(System_Init, @handle, maxChannels, flags, extraDriverData)
    end
    #--------------------------------------------------------------------------
    # * Create FMOD::Sound (fully loaded into memory by default)
    #     filename        : Name of file to open
    #     mode            : FMOD_MODE flags
    #--------------------------------------------------------------------------
    def createSound(filename, mode = FMOD_DEFAULT_SOFTWARWE,struc=0)
      # Create sound and return it
      temp = 0.chr * 4
      result = @fmod.invoke(System_CreateSound, @handle, filename, mode, struc, temp)
      if result == FMOD_ERR_FILE_NOT_FOUND
        result2 = @fmod.invoke(System_CreateSound, @handle, filename.unpack(UX).pack(CX), mode, 0, temp)
        raise "File not found: \"#{filename}\"" if result2 == FMOD_ERR_FILE_NOT_FOUND
      end
      newSound = Sound.new(self, @fmod.unpackInt(temp))
      return newSound
    end
    #--------------------------------------------------------------------------
    # * Create Streamed FMOD::Sound (chunks loaded on demand)
    #     filename        : Name of file to open
    #     mode            : FMOD_MODE flags
    #--------------------------------------------------------------------------
    def createStream(filename, mode = FMOD_DEFAULT_SOFTWARWE,struc=0)
      # Create sound and return it
      temp = 0.chr * 4
      result = @fmod.invoke(System_CreateStream, @handle, filename, mode, struc, temp)
      if result == FMOD_ERR_FILE_NOT_FOUND
        result2 = @fmod.invoke(System_CreateStream, @handle, filename.unpack(UX).pack(CX), mode, 0, temp)
        raise "File not found: \"#{filename}\"" if result2 == FMOD_ERR_FILE_NOT_FOUND
      end
      newSound = Sound.new(self, @fmod.unpackInt(temp))
      return newSound
    end
    #--------------------------------------------------------------------------
    # * Close And Release System
    #--------------------------------------------------------------------------
    def dispose
      if (@handle > 0)
        @fmod.invoke(System_Close, @handle)
        @fmod.invoke(System_Release, @handle)
        @handle = 0
      end
      @fmod = nil
    end
  end

  #============================================================================
  # ** Sound
  #----------------------------------------------------------------------------
  #  A class that manages an instance of FMOD::Sound
  #============================================================================
  
  class Sound
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #-------------------------------------------------------------------------- 
    attr_accessor :system             # System that created this Sound
    attr_accessor :fmod               # Instance of DLL class (fmodex.dll)
    attr_accessor :handle             # Handle (pointer) to Sound object
    
    System_PlaySound='System_PlaySound'
    Sound_GetMode='Sound_GetMode'
    Sound_SetMode='Sound_SetMode'
    Sound_GetLength='Sound_GetLength'
    Sound_SetLoopPoints='Sound_SetLoopPoints'
    Sound_Release='Sound_Release'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     theSystem       : The System that created this Sound object
    #     handle          : Handle to the FMOD::Sound object
    #--------------------------------------------------------------------------
    def initialize(theSystem, theHandle)
      @system = theSystem
      @fmod = theSystem.fmod
      @handle = theHandle
    end
    #--------------------------------------------------------------------------
    # * Play Sound
    #     paused          : Start paused?
    #     channel         : Channel allocated to sound (nil for automatic)
    #--------------------------------------------------------------------------
    def play(paused = false, channel = nil)
      # If channel wasn't specified, let FMOD pick a free one,
      # otherwise use the passed channel (id from 0 to maxChannels)
      unless channel
        temp = 0.chr * 4
      else
        temp = [channel].pack('l')
      end
      @fmod.invoke(System_PlaySound, @system.handle, 
                (channel == nil) ? FMOD_CHANNEL_FREE : FMOD_CHANNEL_REUSE, 
                @handle,
                (paused == true) ? 1 : 0, 
                temp)
      theChannel = @fmod.unpackInt(temp)
      # Create a Channel object based on returned channel
      newChannel = Channel.new(self, theChannel)
      return newChannel
    end
    #--------------------------------------------------------------------------
    # * Get FMOD_MODE Bits
    #--------------------------------------------------------------------------
    def mode
      temp = 0.chr * 4
      @fmod.invoke(Sound_GetMode, @handle, temp)
      return @fmod.unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Set FMOD_MODE Bits
    #--------------------------------------------------------------------------
    def mode=(newMode)
      @fmod.invoke(Sound_SetMode, @handle, newMode)
    end
    #--------------------------------------------------------------------------
    # * Get FMOD_LOOP_MODE
    #--------------------------------------------------------------------------  
    def loopMode
      temp = 0.chr * 4
      @fmod.invoke(Sound_GetMode, @handle, temp)
      return @fmod.unpackInt(temp) & FMOD_LOOP_BITMASK
    end
    #--------------------------------------------------------------------------
    # * Set FMOD_LOOP_MODE
    #--------------------------------------------------------------------------  
    def loopMode=(newMode)
      @fmod.invoke(Sound_SetMode, @handle, (self.mode & ~FMOD_LOOP_BITMASK) | newMode)
    end
    #--------------------------------------------------------------------------
    # * Return Sound Length
    #-------------------------------------------------------------------------- 
    def length(unit = FMOD_DEFAULT_UNIT)
      temp = 0.chr * 4
      @fmod.invoke(Sound_GetLength, @handle, temp, unit)
      return @fmod.unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Loop Points
    #     first           : Loop start point in milliseconds
    #     second          : Loop end point in milliseconds
    #     unit            : FMOD_TIMEUNIT for points
    #--------------------------------------------------------------------------    
    def setLoopPoints(first, second, unit = FMOD_DEFAULT_UNIT)
      @fmod.invoke(Sound_SetLoopPoints, @handle, first, unit, second, unit)
    end
    #--------------------------------------------------------------------------
    # * Release Sound
    #-------------------------------------------------------------------------- 
    def dispose
      if (@handle > 0)
        @fmod.invoke(Sound_Release, @handle)
        @handle = 0
      end
      @fmod = nil
      @system = nil
    end
  end

  #============================================================================
  # ** Channel
  #----------------------------------------------------------------------------
  #  A class that represents an FMOD::Channel
  #============================================================================
  
  class Channel
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #-------------------------------------------------------------------------- 
    attr_accessor :system             # System that created the Sound
    attr_accessor :sound              # Sound using the Channel
    attr_accessor :fmod               # Instance of DLL class (fmodex.dll)
    attr_accessor :handle             # Handle (pointer) to Sound object
    
    
    Channel_Stop='Channel_Stop'
    Channel_IsPlaying='Channel_IsPlaying'
    Channel_GetVolume='Channel_GetVolume'
    Channel_SetVolume='Channel_SetVolume'
    Channel_GetPan='Channel_GetPan'
    Channel_SetPan='Channel_SetPan'
    Channel_GetFrequency='Channel_GetFrequency'
    Channel_SetFrequency='Channel_SetFrequency'
    Channel_GetPaused='Channel_GetPaused'
    Channel_SetPaused='Channel_SetPaused'
    Channel_GetPosition='Channel_GetPosition'
    Channel_SetPosition='Channel_SetPosition'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     theSound        : The Sound using this Channel object
    #     handle          : Handle to the FMOD::Channel object
    #--------------------------------------------------------------------------
    def initialize(theSound, theHandle)
      @sound = theSound
      @system = theSound.system
      @fmod = theSound.system.fmod
      @handle = theHandle
    end
    #--------------------------------------------------------------------------
    # * Stop Channel and Make it Available for Other Sounds
    #--------------------------------------------------------------------------
    def stop
      @fmod.invoke(Channel_Stop, @handle)
    end
    #--------------------------------------------------------------------------
    # * Is the Channel Handle Valid?
    #--------------------------------------------------------------------------
    def valid?
      temp = 0.chr * 4
      begin
        result = @fmod.invoke(Channel_IsPlaying, @handle, temp)
      rescue
        if (result == FMOD_ERR_INVALID_HANDLE)
          return false
        else
          raise
        end
      end
      # If we get here then it's valid
      return true
    end
    #--------------------------------------------------------------------------
    # * Is the Channel Playing?
    #--------------------------------------------------------------------------
    def playing?
      temp = 0.chr * 4
      @fmod.invoke(Channel_IsPlaying, @handle, temp)
      return @fmod.unpackBool(temp)
    end
    #--------------------------------------------------------------------------
    # * Get Channel Volume Level (0.0 -> 1.0)
    #--------------------------------------------------------------------------
    def volume
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetVolume, @handle, temp)
      return @fmod.unpackFloat(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Channel Volume Level (0.0 -> 1.0)
    #--------------------------------------------------------------------------
    def volume=(newVolume)
      @fmod.invoke(Channel_SetVolume, @handle, @fmod.convertFloat(newVolume))
    end
    #--------------------------------------------------------------------------
    # * Get Channel Pan Position (-1.0 -> 1.0)
    #--------------------------------------------------------------------------
    def pan
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetPan, @handle, temp)
      return @fmod.unpackFloat(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Channel Pan Position (-1.0 -> 1.0)
    #--------------------------------------------------------------------------
    def pan=(newPan)
      @fmod.invoke(Channel_SetPan, @handle, @fmod.convertFloat(newPan))
    end
    #--------------------------------------------------------------------------
    # * Get Channel Frequency in HZ (Speed/Pitch)
    #--------------------------------------------------------------------------
    def frequency
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetFrequency, @handle, temp)
      return @fmod.unpackFloat(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Channel Frequency in HZ (Speed/Pitch)
    #--------------------------------------------------------------------------
    def frequency=(newFrequency)
      @fmod.invoke(Channel_SetFrequency, @handle, @fmod.convertFloat(newFrequency))
    end
    #--------------------------------------------------------------------------
    # * Is Channel Paused?
    #--------------------------------------------------------------------------
    def paused
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetPaused, @handle, temp)
      return @fmod.unpackBool(temp)
    end
    #--------------------------------------------------------------------------
    # * Pause Channel
    #--------------------------------------------------------------------------
    def paused=(newPaused)
      @fmod.invoke(Channel_SetPaused, @handle, (newPaused == true) ? 1 : 0)
    end
    #--------------------------------------------------------------------------
    # * Get Current Playback Position
    #     unit            : FMOD_TIMEUNIT to return position in
    #--------------------------------------------------------------------------   
    def position(unit = FMOD_DEFAULT_UNIT)
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetPosition, @handle, temp, unit)
      return @fmod.unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Current Playback Position
    #     newPosition     : New playback position
    #     unit            : FMOD_TIMEUNIT to use when setting position
    #--------------------------------------------------------------------------    
    def position=(newPosition, unit = FMOD_DEFAULT_UNIT)
      @fmod.invoke(Channel_SetPosition, @handle, newPosition, unit)
    end
    #--------------------------------------------------------------------------
    # * Dispose of Channel
    #--------------------------------------------------------------------------  
    def dispose
      @handle = 0
      @sound = nil
      @system = nil
      @fmod = nil
    end
  end
  
end

#==============================================================================
# ** FMod
#------------------------------------------------------------------------------
#  A higher level module to access FMOD Ex
#==============================================================================

module Audio
  SLP_TIME=0.01
  #============================================================================
  # ** SoundFile
  #----------------------------------------------------------------------------
  #  Represents a Sound file (BGM, BGS, SE, etc.) and associated Channel
  #============================================================================
  
  class SoundFile
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #--------------------------------------------------------------------------
    attr_accessor :name                     # File name
    attr_accessor :sound                    # FModEx::Sound object
    attr_accessor :channel                  # Channel playing sound
    attr_accessor :volume                   # Volume in RPG::AudioFile format
    attr_accessor :pitch                    # Pitch in RPG::AudioFile format
    attr_accessor :looping                  # Sound loops
    attr_accessor :streaming                # Sound is streamed
    attr_accessor :length                   # Sound length in milliseconds
    #--------------------------------------------------------------------------
    # * Object Initialization
    #--------------------------------------------------------------------------
    def initialize(name, sound, channel, volume, pitch, looping, streaming, length)
      @name = name
      @sound = sound
      @channel = channel
      @volume = volume
      @pitch = pitch
      @looping = looping
      @streaming = streaming
      @length = length
    end
  end
  #--------------------------------------------------------------------------
  # * Instance Variables
  #--------------------------------------------------------------------------
  @fmod_dll = FModEx::DLL.new               # The FMOD Ex DLL
  @fmod = FModEx::System.new(@fmod_dll)     # The global System object
  @fmod_se = []                             # Array of Sound Effects
  @rtp_folder = nil                         # Name of RTP folder
  #--------------------------------------------------------------------------
  # * Get Path of RTP Folder From Registry
  #-------------------------------------------------------------------------- 
  def self.getRTPFolder
    if @rtp_folder
      return @rtp_folder
    end
    open_key = Win32API.new('advapi32.dll', 'RegOpenKeyExA', 'LPLLP', 'L')
    query_value = Win32API.new('advapi32.dll', 'RegQueryValueExA', 'LPLPPP', 'L')
    close_key = Win32API.new('advapi32', 'RegCloseKey', 'L', 'L')
    key = 0.chr * 4
    # Open a HKEY_LOCAL_MACHINE with KEY_READ attribute and save handle in key
    open_key.call(0x80000002, 'Software\Enterbrain\RGSS\RTP', 0, 0x20019, key)
    key = @fmod_dll.unpackInt(key)
    type = 0.chr * 4
    size = 0.chr * 4
    # Query to get string size
    query_value.call(key, 'Standard', 0, type, 0, size)
    data = ' ' * @fmod_dll.unpackInt(size)
    # Query the string value itself using size
    query_value.call(key, 'Standard', 0, type, data, size)
    @rtp_folder = data.chop
    close_key.call(key)
    # Make sure the directory ends with a backslash
    @rtp_folder += "\\" if @rtp_folder[-1].chr != "\\"
    return @rtp_folder
  end
  #--------------------------------------------------------------------------
  # * Return Proper File Name (With Extensions)
  #     name            : Name of the file
  #     extensions      : Extensions to add to file name
  #-------------------------------------------------------------------------- 
  def self.checkExtensions(name, extensions)
    if FileTest.exist?(name)
      return name
    end
    # Add extension if needed
    extensions.each do |ext|
      if FileTest.exist?(name + '.' + ext)
        return name + '.' + ext
      end
    end
    # File doesn't exist
    return name
  end
  #--------------------------------------------------------------------------
  # * Get Valid File Name
  #     name            : Name of the file
  #-------------------------------------------------------------------------- 
  def self.selectBGMFilename(name)
    name = name.gsub("/", "\\")
    # See if file exists in game folder
    localname = self.checkExtensions(name, FModEx::FMOD_FILE_TYPES)
    # See if file exists in RTP
    commonname = self.checkExtensions(getRTPFolder + name, FModEx::FMOD_FILE_TYPES)
    if FileTest.exist?(localname)
      return localname
    end
    if FileTest.exist?(commonname)
      return commonname
    end
    # An invalid name was provided
    return name
  end
  #--------------------------------------------------------------------------
  # * Play a Sound File Then Return it
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the sound loop?
  #     streaming       : Stream sound or load whole thing to memory?
  #-------------------------------------------------------------------------- 
  def self.play(name, volume, pitch, position, looping, streaming)
    # Get a valid file name
    filename = self.selectBGMFilename(name)
    # Create Sound or Stream and set initial values
    sound = streaming ? @fmod.createStream(filename) : @fmod.createSound(filename)
    sound.loopMode = looping ? FModEx::FMOD_LOOP_NORMAL : FModEx::FMOD_LOOP_OFF
    channel = sound.play
    volume = volume * 1.0
    pitch = pitch * 1.0
    file_length = sound.length(FModEx::FMOD_DEFAULT_UNIT)
    sound_file = SoundFile.new(filename, sound, channel, volume, 
                                pitch, looping, streaming, file_length)
    sound_file.channel.volume = volume / 100.0
    sound_file.channel.frequency = sound_file.channel.frequency * pitch / 100
    sound_file.channel.position = position
    return sound_file
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of Sound File
  #-------------------------------------------------------------------------- 
  def self.stop(sound_file)
    unless sound_file and sound_file.channel
      return
    end
    # Stop channel, then clear variables and dispose of bgm
    sound_file.channel.stop
    sound_file.channel = nil
    sound_file.sound.dispose
  end
  #--------------------------------------------------------------------------
  # * Return Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.get_length(sound_file, unit = FModEx::FMOD_DEFAULT_UNIT)
    return sound_file.length#(unit)
  end
  #--------------------------------------------------------------------------
  # * Check if Another Sound File is Playing
  #-------------------------------------------------------------------------- 
  def self.already_playing?(sound_file, name, position = 0)
    # Get a valid file name
    filename = self.selectBGMFilename(name)
    if (sound_file)
      # If the same sound file is already playing don't play it again
      if (sound_file.name == filename and position == 0)
        return true
      end
      # If another sound file is playing, stop it
      if sound_file.channel
        self.stop(sound_file)
      end
    end
    # No sound file is playing or it was already stopped
    return false
  end
  #--------------------------------------------------------------------------
  # * Check if Sound File is Playing
  #--------------------------------------------------------------------------  
  def self.playing?(sound_file)
    unless sound_file and sound_file.channel
      return false
    end
    return sound_file.channel.playing?
  end
  #--------------------------------------------------------------------------
  # * Get Current Sound File Playing Position
  #-------------------------------------------------------------------------- 
  def self.get_position(sound_file)
    unless sound_file and sound_file.channel
      return 0
    end
    return sound_file.channel.position
  end
  #--------------------------------------------------------------------------
  # * Seek to a New Sound File Playing Position
  #-------------------------------------------------------------------------- 
  def self.set_position(sound_file, new_pos)
    unless sound_file and sound_file.channel
      return
    end
    sound_file.channel.position = new_pos
  end
  #--------------------------------------------------------------------------
  # * Get Current Sound File Volume
  #-------------------------------------------------------------------------- 
  def self.get_volume(sound_file)
    unless sound_file
      return 0
    end
    return sound_file.volume
  end
  #--------------------------------------------------------------------------
  # * Set Sound File Volume
  #-------------------------------------------------------------------------- 
  def self.set_volume(sound_file, volume)
    unless sound_file and sound_file.channel
      return
    end
    sound_file.volume = volume * 1.0
    sound_file.channel.volume = volume / 100.0
  end
  #--------------------------------------------------------------------------
  # * Set Loop Points
  #     first           : Loop start point in milliseconds
  #     second          : Loop end point in milliseconds (-1 for file end)
  #     unit            : FMOD_TIMEUNIT for points
  #-------------------------------------------------------------------------- 
  def self.set_loop_points(sound_file, first, second, unit = FModEx::FMOD_DEFAULT_UNIT)
    unless sound_file and sound_file.channel
      return
    end
    # If second is -1 then set loop end to the file end
    if second == -1
      second = sound_file.length - 1
    end
    # Set loop points and reflush stream buffer
    sound_file.channel.sound.setLoopPoints(first, second, unit)
    sound_file.channel.position = sound_file.channel.position
    return sound_file
  end
  #--------------------------------------------------------------------------
  # * Play ME
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the BGM loop?
  #-------------------------------------------------------------------------- 
  def self.me_play(name, volume=100, pitch=100, position = 0, looping = false)
    return if self.already_playing?(@fmod_me, name, position) and Audio.me_playing?
    # Now play the new BGM as a stream
    @fmod_me = self.play(name, volume, pitch, position, false, true)
    Thread.new do
      if @fmod_bgm
        paused=@fmod_bgm.channel.paused
        @fmod_bgm.channel.paused=true
      else
        paused=false
      end
      loop do
        unless @fmod_me
          break
        end
        unless Audio.me_playing?
          break
        end
        sleep(SLP_TIME)
      end
      if @fmod_bgm
        @fmod_bgm.channel.paused=paused
      end
    end
    return @fmod_me
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of ME
  #-------------------------------------------------------------------------- 
  def self.me_stop
    self.stop(@fmod_me)
    @fmod_me = nil
  end
  #--------------------------------------------------------------------------
  # * Return ME Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.me_length(sound_file)
    self.get_length(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Check if a ME is Playing
  #--------------------------------------------------------------------------  
  def self.me_playing?
    return self.playing?(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Get Current ME Playing Position
  #-------------------------------------------------------------------------- 
  def self.me_position
    return self.get_position(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Seek to New ME Playing Position
  #-------------------------------------------------------------------------- 
  def self.me_position=(new_pos)
    self.set_position(@fmod_bgm, new_pos)
  end
  #--------------------------------------------------------------------------
  # * Get Current ME Volume
  #-------------------------------------------------------------------------- 
  def self.me_volume
    return self.get_volume(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Set ME Volume
  #-------------------------------------------------------------------------- 
  def self.me_volume=(volume)
    self.set_volume(@fmod_me, volume)
  end
  #--------------------------------------------------------------------------
  # * Set ME fade
  #-------------------------------------------------------------------------- 
  def self.me_fade(time)
    return unless @fmod_me and Audio.me_playing? and !@fading_me
    @fading_me=true
    Thread.new do
      vol=Audio.me_volume
      cnt=(time/1000.0/SLP_TIME).to_i
      cnt.times do |i|
        Audio.me_volume=(vol-(vol*i/cnt))
        sleep SLP_TIME
      end
      Audio.me_stop
      @fading_me=false
    end
  end
  
  
  #--------------------------------------------------------------------------
  # * Play BGM (or ME)
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the BGM loop?
  #-------------------------------------------------------------------------- 
  def self.bgm_play(name, volume=100, pitch=100, position = 0, looping = true)
    return if self.already_playing?(@fmod_bgm, name, position)
    # Now play the new BGM as a stream
    @fmod_bgm = self.play(name, volume, pitch, position, looping, true)
    if @fmod_me and Audio.me_playing?
      @fmod_bgm.channel.paused=true
    end
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of BGM
  #-------------------------------------------------------------------------- 
  def self.bgm_stop
    self.stop(@fmod_bgm)
    @fmod_bgm = nil
  end
  #--------------------------------------------------------------------------
  # * Return BGM Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.bgm_length(sound_file)
    self.get_length(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Check if a BGM is Playing
  #--------------------------------------------------------------------------  
  def self.bgm_playing?
    return self.playing?(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGM Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgm_position
    return self.get_position(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Seek to New BGM Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgm_position=(new_pos)
    self.set_position(@fmod_bgm, new_pos)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGM Volume
  #-------------------------------------------------------------------------- 
  def self.bgm_volume
    return self.get_volume(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Set BGM Volume
  #-------------------------------------------------------------------------- 
  def self.bgm_volume=(volume)
    self.set_volume(@fmod_bgm, volume)
  end
  #--------------------------------------------------------------------------
  # * Set Loop Points
  #     first           : Loop start point in milliseconds
  #     second          : Loop end point in milliseconds
  #     unit            : FMOD_TIMEUNIT for points
  #-------------------------------------------------------------------------- 
  def self.bgm_set_loop_points(first, second, unit = FModEx::FMOD_DEFAULT_UNIT)
    @fmod_bgm = self.set_loop_points(@fmod_bgm, first, second, unit)
  end
  #--------------------------------------------------------------------------
  # * Set BGM fade
  #-------------------------------------------------------------------------- 
  def self.bgm_fade(time)
    return unless @fmod_bgm and Audio.bgm_playing? and !@fading_bgm
    @fading_bgm=true
    Thread.new do
      vol=Audio.bgm_volume
      cnt=(time/1000.0/SLP_TIME).to_i
      cnt.times do |i|
        Audio.bgm_volume=(vol-(vol*i/cnt))
        sleep SLP_TIME
      end
      Audio.bgm_stop
      @fading_bgm=false
    end
  end
  
  
  #--------------------------------------------------------------------------
  # * Play BGS
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the BGS loop?
  #-------------------------------------------------------------------------- 
  def self.bgs_play(name, volume=100, pitch=100, position = 0, looping = true)
    return if self.already_playing?(@fmod_bgs, name, position)
    # Now play the new BGS as a stream
    @fmod_bgs = self.play(name, volume, pitch, position, looping, true)
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of BGS
  #-------------------------------------------------------------------------- 
  def self.bgs_stop
    self.stop(@fmod_bgs)
    @fmod_bgs = nil
  end
  #--------------------------------------------------------------------------
  # * Return BGS Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.bgm_length(sound_file)
    self.get_length(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Check if a BGS is Playing
  #--------------------------------------------------------------------------  
  def self.bgs_playing?
    return self.playing?(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGS Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgs_position
    return self.get_position(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Seek to New BGS Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgs_position=(new_pos)
    self.set_position(@fmod_bgs, new_pos)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGS Volume
  #-------------------------------------------------------------------------- 
  def self.bgs_volume
    return self.get_volume(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Set BGS Volume
  #-------------------------------------------------------------------------- 
  def self.bgs_volume=(volume)
    self.set_volume(@fmod_bgs, volume)
  end
  #--------------------------------------------------------------------------
  # * Set Loop Points
  #     first           : Loop start point in milliseconds
  #     second          : Loop end point in milliseconds
  #     unit            : FMOD_TIMEUNIT for points
  #-------------------------------------------------------------------------- 
  def self.bgs_set_loop_points(first, second, unit = FModEx::FMOD_DEFAULT_UNIT)
    @fmod_bgs = self.set_loop_points(@fmod_bgs, first, second, unit)
  end
  #--------------------------------------------------------------------------
  # * Set BGS fade
  #-------------------------------------------------------------------------- 
  def self.bgs_fade(time)
    return unless @fmod_bgs and Audio.bgs_playing? and !@fading_bgs
    @fading_bgs=true
    Thread.new do
      vol=Audio.bgs_volume
      cnt=(time/1000.0/SLP_TIME).to_i
      cnt.times do |i|
        Audio.bgs_volume=(vol-(vol*i/cnt))
        sleep SLP_TIME
      end
      Audio.me_stop
      @fading_bgs=false
    end
  end
  
  #--------------------------------------------------------------------------
  # * Play SE
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #-------------------------------------------------------------------------- 
  def self.se_play(name, volume=100, pitch=100)
    if @fmod_se.size > @fmod.maxChannels
      #msgbox_p 0
      se = @fmod_se.shift
      #msgbox_p se
      self.stop(se)  if self.playing?(se)
    end
    # Load SE into memory and play it
    @fmod_se << self.play(name, volume, pitch, 0, false, false)
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of all SEs
  #-------------------------------------------------------------------------- 
  def self.se_stop
    for se in @fmod_se
      self.stop(se) if self.playing?(se)
    end
    @fmod_se.clear
  end
  #--------------------------------------------------------------------------
  # * Get Rid of Non-Playing SEs
  #--------------------------------------------------------------------------  
      def self.se_clean
      $FMOD_CLEANING=true
    for se in @fmod_se
      unless self.playing?(se)
        self.stop(se)
        @fmod_se.delete(se)
      end
      end
      $FMOD_CLEANING=false   
  end
  #--------------------------------------------------------------------------
  # * Check if There's Some SE in SE Array
  #--------------------------------------------------------------------------  
  def self.se_list_empty?
    return @fmod_se.empty?
  end
  #--------------------------------------------------------------------------
  # * Dispose of Everything
  #--------------------------------------------------------------------------  
  def self.dispose
    self.bgm_stop
    self.bgs_stop
    self.se_stop
    @fmod.dispose
  end
end
end
module FMod
  include Audio
end
I tried the script, but as excepted it doesn't work. The game launches, but all the BGM except the looped one fade out immediately after a map transition. Sometimes it's only the looped music which fades out and the other not. And the loop doesn't work. There is probably something to do with Essential to get it working. But it's probably FMod incompatibility.

Edit: I did something wrong... If I put the loop script under the FMod script in the script editor, it makes the loop working. But non-looped BGM still fades out immediately after playing.

Edit 2: after some researches I noticed this: if I load my game in a place with looped music, only this music will work, other will quickly fade out (looped or not). Battle themes will be fine though. The problem is probably related to the loading game script...

Edit 3: ok the problem isn't with the game loading, but with map transitions. Because when we change the map, Essentials fades out the previous BGM and plays the next BGM. When installing the FMod script, the next BGM immediately starts and fade outs. Probably some incompatibility here... But I don't know how to fix this. For now I disabled the fade by replacing the pbClueBGM by pbBGMPlay in autoplayAsCue, in Game_Map_ section.
__________________
Praise Helix.
Reply With Quote
  #227    
Old March 11th, 2015 (09:05 AM).
KaiserYoshi's Avatar
KaiserYoshi KaiserYoshi is offline
 
Join Date: Nov 2014
Location: France - Nord
Gender: Male
Posts: 6
Scripts updated :

Code:
#=======================================================================
# ■ Loop data of music
#
# Contains the data indicating the start and the end of a
# loop for the indicated music.
# Compatible with all versions of RMXP and PSP
# Requires FModEx and fmodex.dll file to the project root
#=======================================================================
# ■ HOW TO USE ?
# Modify LOOP_TABLE by adding an entry of the following form :
# [ "Audio/xxx/File_name", debut, fin ]
# - The chain is simply the path of the file
# (Without the extension!)
# - debut : Point de début de la boucle, en millisecondes
# - fin : Point de fin de la boucle, en millisecondes
#
# When you read an in-game music, this script will automatically
# search corresponding data loop.
#-----------------------------------------------------------------------
# ■ NOTES
# - It is not necessary to add a file to the table if 
# the file haven't loop, or if the loop covers the entire file.
# - Add in preferably BGMs or BGSs
# - Use Audacity (or others) and your ears for get the 
# start and end values.
# - Important : Avoid accents in files name.
#=======================================================================

module Audio

LOOP_TABLE = [

# [ "Audio/xxx/File_name", debut, fin ]
# Add here


# Note: Think add a comma after each "]"
# (Except for the last line and the "]" below).
]

# Do not change the next lines only if you know what you are doing

def self.find_in_loop_table(file)
for i in 0...LOOP_TABLE.size
if LOOP_TABLE[i][0] == file
return i
end
end
return nil
end

def self.bgm_play(name, volume=100, pitch=100, position = 0, looping = true)
return if self.already_playing?(@fmod_bgm, name, position)
@fmod_bgm = self.play(name, volume, pitch, position, looping, true)
if @fmod_me and Audio.me_playing?
@fmod_bgm.channel.paused=true
end
i = self.find_in_loop_table(name)
unless i == nil
#print("Found | #{LOOP_TABLE[i][1].to_s} -> #{LOOP_TABLE[i][2].to_s}")
self.bgm_set_loop_points(LOOP_TABLE[i][1], LOOP_TABLE[i][2])
end
end

def self.bgs_play(name, volume=100, pitch=100, position = 0, looping = true)
return if self.already_playing?(@fmod_bgs, name, position)
@fmod_bgs = self.play(name, volume, pitch, position, looping, true)
i = self.find_in_loop_table(name)
unless i == nil
self.bgs_set_loop_points(LOOP_TABLE[i][1], LOOP_TABLE[i][2])
end
end

end
and

Code:
# Copyright (c) 2005, Kevin Gadd
#==============================================================================
# ** FModEx
#------------------------------------------------------------------------------
#  FMOD Ex binding by Kevin Gadd ([email protected])
#==============================================================================
unless $FMODEX
  $FMODEX=true
module FModEx
  #--------------------------------------------------------------------------
  # * Constants
  #--------------------------------------------------------------------------
  # FMOD_INITFLAGS flags
  FMOD_INIT_NORMAL = 0
  # FMOD_RESULT flags
  FMOD_OK = 0
  FMOD_ERR_CHANNEL_STOLEN = 11
  FMOD_ERR_FILE_NOT_FOUND = 23
  FMOD_ERR_INVALID_HANDLE = 36
  # FMOD_MODE flags
  FMOD_DEFAULT = 0
  FMOD_LOOP_OFF = 1
  FMOD_LOOP_NORMAL = 2
  FMOD_LOOP_BIDI = 4
  FMOD_LOOP_BITMASK = 7
  FMOD_2D = 8
  FMOD_3D = 16
  FMOD_HARDWARE = 32
  FMOD_SOFTWARE = 64
  FMOD_CREATESTREAM = 128
  FMOD_CREATESAMPLE = 256
  FMOD_OPENUSER = 512
  FMOD_OPENMEMORY = 1024
  FMOD_OPENRAW = 2048
   FMOD_OPENONLY = 4096
   FMOD_OPENMEMORY_POINT = 0x10000000
  FMOD_ACCURATETIME = 8192
  FMOD_MPEGSEARCH = 16384
  FMOD_NONBLOCKING = 32768
  FMOD_UNIQUE = 65536
  # The default mode that the script uses
  FMOD_DEFAULT_SOFTWARWE = FMOD_LOOP_OFF | FMOD_2D | FMOD_SOFTWARE
  FMOD_TEST = FMOD_OPENMEMORY | FMOD_SOFTWARE
  # FMOD_CHANNELINDEX flags
  FMOD_CHANNEL_FREE = -1
  FMOD_CHANNEL_REUSE = -2
  # FMOD_TIMEUNIT_flags
  FMOD_TIMEUNIT_MS = 1
  FMOD_TIMEUNIT_PCM = 2
  # The default time unit the script uses
  FMOD_DEFAULT_UNIT = FMOD_TIMEUNIT_MS
  # Types supported by FMOD Ex
  FMOD_FILE_TYPES = ['ogg', 'aac', 'wma', 'mp3', 'wav', 'it', 'xm', 'mod', 's3m', 'mid', 'midi']
  
  #============================================================================
  # ** DLL
  #----------------------------------------------------------------------------
  #  A class that manages importing functions from the DLL
  #============================================================================
  
  class DLL
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #--------------------------------------------------------------------------
    attr_accessor :filename           # DLL file name for instance    
    attr_accessor :functions          # hash of functions imported (by name)
         
    Functions = {}
    Sys_C='System_Create'
    W32_LL = Win32API.new('kernel32.dll', 'LoadLibrary', 'p', 'l')
    FN='fmodex.dll'
    F='f'
    L='l'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     filename  : Name of the DLL
    #--------------------------------------------------------------------------
    def initialize(filename = FN)
      @filename = filename
      @handle = 0            # Handle to the DLL
      # Load specified library into the address space of game process
      
      @handle = W32_LL.call(filename)
      unless Functions[Sys_C]
      # System functions:
        self.import(Sys_C, 'p')
        self.import('System_Init', 'llll')
        self.import('System_Close', 'l')
        self.import('System_Release', 'l')
        self.import('System_CreateSound', 'lplpp')
        self.import('System_CreateStream', 'lplpp')
        self.import('System_PlaySound', 'llllp')
        # Sound functions:
        self.import('Sound_Release', 'l')
        self.import('Sound_GetMode', 'lp')
        self.import('Sound_SetMode', 'll')
        self.import('Sound_SetLoopPoints', 'lllll')
        self.import('Sound_GetLength', 'lpl')
        # Channel functions:
        self.import('Channel_Stop', 'l')
        self.import('Channel_IsPlaying', 'lp')
        self.import('Channel_GetPaused', 'lp')
        self.import('Channel_SetPaused', 'll')
        self.import('Channel_GetVolume', 'lp')
        self.import('Channel_SetVolume', 'll')
        self.import('Channel_GetPan', 'lp')
        self.import('Channel_SetPan', 'll')
        self.import('Channel_GetFrequency', 'lp')
        self.import('Channel_SetFrequency', 'll')
        self.import('Channel_GetPosition', 'lpl')
        self.import('Channel_SetPosition', 'lll')
      end
    end
    #--------------------------------------------------------------------------
    # * Create a Win32API Object And Add it to Hashtable
    #     name      : Function name
    #     args      : Argument types (p = pointer, l = int, v = void)
    #     returnType: Type of value returned by function
    #--------------------------------------------------------------------------
    def import(name, args = '', returnType = L)
      Functions[name] = Win32API.new(@filename, 'FMOD_' + name, args, returnType)
    end
    #--------------------------------------------------------------------------
    # * Get Function by Name
    #     key       : Function name
    #--------------------------------------------------------------------------
    def [](key)
      return Functions[key]
    end
    #--------------------------------------------------------------------------
    # * Call a Function With Passed Arguments
    #     name      : Function name
    #     args      : Argument to function
    #--------------------------------------------------------------------------
    def invoke(name, *args)
      fn = Functions[name]
      raise "function not imported: #{name}" if fn.nil?
      result = fn.call(*args)
      unless result == FMOD_OK or result == FMOD_ERR_CHANNEL_STOLEN or
        result == FMOD_ERR_FILE_NOT_FOUND
        if result==36
          Audio.se_clean unless $FMOD_CLEANING
        else
          print "FMOD Ex returned error #{result}.\n"
        end
      end
      return result
    end
    #--------------------------------------------------------------------------
    # * Store Float as Binary Int Because Floats Can't be Passed Directly
    #     f         : Float to convert
    #--------------------------------------------------------------------------
    def convertFloat(f)
      # First pack the float in a string as a native binary float
      temp = [f].pack(F)
      # Then unpack the native binary float as an integer
      return unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Unpack Binary Data to Integer
    #     s         : String containing binary data
    #--------------------------------------------------------------------------
    def unpackInt(s)
      return s.unpack(L)[0]
    end
    #--------------------------------------------------------------------------
    # * Unpack Binary Data to Float
    #     s         : String containing binary data
    #--------------------------------------------------------------------------
    def unpackFloat(s)
      return s.unpack(F)[0]
    end
    #--------------------------------------------------------------------------
    # * Unpack Binary Data to Boolean
    #     s         : String containing binary data
    #--------------------------------------------------------------------------
    def unpackBool(s)
      return s.unpack(L)[0] != 0
    end
  end

  #============================================================================
  # ** System
  #----------------------------------------------------------------------------
  #  A class that manages an instance of FMOD::System
  #============================================================================
  
  class System
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #-------------------------------------------------------------------------- 
    attr_accessor :fmod               # Instance of DLL class (fmodex.dll)
    attr_accessor :handle             # Handle (pointer) to System object
    attr_accessor :maxChannels        # Maximum number of channels
    System_Create='System_Create'
    System_Init='System_Init'
    System_CreateSound='System_CreateSound'
    UX="U*"
    CX="C*"
    System_CreateStream='System_CreateStream'
    System_Close='System_Close'
    System_Release='System_Release'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     fmod            : An instance of DLL class
    #     maxChannels     : Maximum number of used channels
    #     flags           : FMOD_INITFLAGS
    #     extraDriverData : Driver specific data
    #--------------------------------------------------------------------------
    def initialize(theDLL, maxChannels = 32, flags = FMOD_INIT_NORMAL, extraDriverData = 0)
      @fmod = theDLL
      @maxChannels = maxChannels
      # Create and initialize FMOD::System
      temp = 0.chr * 4
      @fmod.invoke(System_Create, temp)
      @handle = @fmod.unpackInt(temp)
      @fmod.invoke(System_Init, @handle, maxChannels, flags, extraDriverData)
    end
    #--------------------------------------------------------------------------
    # * Create FMOD::Sound (fully loaded into memory by default)
    #     filename        : Name of file to open
    #     mode            : FMOD_MODE flags
    #--------------------------------------------------------------------------
    def createSound(filename, mode = FMOD_DEFAULT_SOFTWARWE,struc=0)
      # Create sound and return it
      temp = 0.chr * 4
      result = @fmod.invoke(System_CreateSound, @handle, filename, mode, struc, temp)
      if result == FMOD_ERR_FILE_NOT_FOUND
        result2 = @fmod.invoke(System_CreateSound, @handle, filename.unpack(UX).pack(CX), mode, 0, temp)
        raise "File not found: \"#{filename}\"" if result2 == FMOD_ERR_FILE_NOT_FOUND
      end
      newSound = Sound.new(self, @fmod.unpackInt(temp))
      return newSound
    end
    #--------------------------------------------------------------------------
    # * Create Streamed FMOD::Sound (chunks loaded on demand)
    #     filename        : Name of file to open
    #     mode            : FMOD_MODE flags
    #--------------------------------------------------------------------------
    def createStream(filename, mode = FMOD_DEFAULT_SOFTWARWE,struc=0)
      # Create sound and return it
      temp = 0.chr * 4
      result = @fmod.invoke(System_CreateStream, @handle, filename, mode, struc, temp)
      if result == FMOD_ERR_FILE_NOT_FOUND
        result2 = @fmod.invoke(System_CreateStream, @handle, filename.unpack(UX).pack(CX), mode, 0, temp)
        raise "File not found: \"#{filename}\"" if result2 == FMOD_ERR_FILE_NOT_FOUND
      end
      newSound = Sound.new(self, @fmod.unpackInt(temp))
      return newSound
    end
    #--------------------------------------------------------------------------
    # * Close And Release System
    #--------------------------------------------------------------------------
    def dispose
      if (@handle > 0)
        @fmod.invoke(System_Close, @handle)
        @fmod.invoke(System_Release, @handle)
        @handle = 0
      end
      @fmod = nil
    end
  end

  #============================================================================
  # ** Sound
  #----------------------------------------------------------------------------
  #  A class that manages an instance of FMOD::Sound
  #============================================================================
  
  class Sound
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #-------------------------------------------------------------------------- 
    attr_accessor :system             # System that created this Sound
    attr_accessor :fmod               # Instance of DLL class (fmodex.dll)
    attr_accessor :handle             # Handle (pointer) to Sound object
    
    System_PlaySound='System_PlaySound'
    Sound_GetMode='Sound_GetMode'
    Sound_SetMode='Sound_SetMode'
    Sound_GetLength='Sound_GetLength'
    Sound_SetLoopPoints='Sound_SetLoopPoints'
    Sound_Release='Sound_Release'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     theSystem       : The System that created this Sound object
    #     handle          : Handle to the FMOD::Sound object
    #--------------------------------------------------------------------------
    def initialize(theSystem, theHandle)
      @system = theSystem
      @fmod = theSystem.fmod
      @handle = theHandle
    end
    #--------------------------------------------------------------------------
    # * Play Sound
    #     paused          : Start paused?
    #     channel         : Channel allocated to sound (nil for automatic)
    #--------------------------------------------------------------------------
    def play(paused = false, channel = nil)
      # If channel wasn't specified, let FMOD pick a free one,
      # otherwise use the passed channel (id from 0 to maxChannels)
      unless channel
        temp = 0.chr * 4
      else
        temp = [channel].pack('l')
      end
      @fmod.invoke(System_PlaySound, @system.handle, 
                (channel == nil) ? FMOD_CHANNEL_FREE : FMOD_CHANNEL_REUSE, 
                @handle,
                (paused == true) ? 1 : 0, 
                temp)
      theChannel = @fmod.unpackInt(temp)
      # Create a Channel object based on returned channel
      newChannel = Channel.new(self, theChannel)
      return newChannel
    end
    #--------------------------------------------------------------------------
    # * Get FMOD_MODE Bits
    #--------------------------------------------------------------------------
    def mode
      temp = 0.chr * 4
      @fmod.invoke(Sound_GetMode, @handle, temp)
      return @fmod.unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Set FMOD_MODE Bits
    #--------------------------------------------------------------------------
    def mode=(newMode)
      @fmod.invoke(Sound_SetMode, @handle, newMode)
    end
    #--------------------------------------------------------------------------
    # * Get FMOD_LOOP_MODE
    #--------------------------------------------------------------------------  
    def loopMode
      temp = 0.chr * 4
      @fmod.invoke(Sound_GetMode, @handle, temp)
      return @fmod.unpackInt(temp) & FMOD_LOOP_BITMASK
    end
    #--------------------------------------------------------------------------
    # * Set FMOD_LOOP_MODE
    #--------------------------------------------------------------------------  
    def loopMode=(newMode)
      @fmod.invoke(Sound_SetMode, @handle, (self.mode & ~FMOD_LOOP_BITMASK) | newMode)
    end
    #--------------------------------------------------------------------------
    # * Return Sound Length
    #-------------------------------------------------------------------------- 
    def length(unit = FMOD_DEFAULT_UNIT)
      temp = 0.chr * 4
      @fmod.invoke(Sound_GetLength, @handle, temp, unit)
      return @fmod.unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Loop Points
    #     first           : Loop start point in milliseconds
    #     second          : Loop end point in milliseconds
    #     unit            : FMOD_TIMEUNIT for points
    #--------------------------------------------------------------------------    
    def setLoopPoints(first, second, unit = FMOD_DEFAULT_UNIT)
      @fmod.invoke(Sound_SetLoopPoints, @handle, first, unit, second, unit)
    end
    #--------------------------------------------------------------------------
    # * Release Sound
    #-------------------------------------------------------------------------- 
    def dispose
      if (@handle > 0)
        @fmod.invoke(Sound_Release, @handle)
        @handle = 0
      end
      @fmod = nil
      @system = nil
    end
  end

  #============================================================================
  # ** Channel
  #----------------------------------------------------------------------------
  #  A class that represents an FMOD::Channel
  #============================================================================
  
  class Channel
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #-------------------------------------------------------------------------- 
    attr_accessor :system             # System that created the Sound
    attr_accessor :sound              # Sound using the Channel
    attr_accessor :fmod               # Instance of DLL class (fmodex.dll)
    attr_accessor :handle             # Handle (pointer) to Sound object
    
    
    Channel_Stop='Channel_Stop'
    Channel_IsPlaying='Channel_IsPlaying'
    Channel_GetVolume='Channel_GetVolume'
    Channel_SetVolume='Channel_SetVolume'
    Channel_GetPan='Channel_GetPan'
    Channel_SetPan='Channel_SetPan'
    Channel_GetFrequency='Channel_GetFrequency'
    Channel_SetFrequency='Channel_SetFrequency'
    Channel_GetPaused='Channel_GetPaused'
    Channel_SetPaused='Channel_SetPaused'
    Channel_GetPosition='Channel_GetPosition'
    Channel_SetPosition='Channel_SetPosition'
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     theSound        : The Sound using this Channel object
    #     handle          : Handle to the FMOD::Channel object
    #--------------------------------------------------------------------------
    def initialize(theSound, theHandle)
      @sound = theSound
      @system = theSound.system
      @fmod = theSound.system.fmod
      @handle = theHandle
    end
    #--------------------------------------------------------------------------
    # * Stop Channel and Make it Available for Other Sounds
    #--------------------------------------------------------------------------
    def stop
      @fmod.invoke(Channel_Stop, @handle)
    end
    #--------------------------------------------------------------------------
    # * Is the Channel Handle Valid?
    #--------------------------------------------------------------------------
    def valid?
      temp = 0.chr * 4
      begin
        result = @fmod.invoke(Channel_IsPlaying, @handle, temp)
      rescue
        if (result == FMOD_ERR_INVALID_HANDLE)
          return false
        else
          raise
        end
      end
      # If we get here then it's valid
      return true
    end
    #--------------------------------------------------------------------------
    # * Is the Channel Playing?
    #--------------------------------------------------------------------------
    def playing?
      temp = 0.chr * 4
      @fmod.invoke(Channel_IsPlaying, @handle, temp)
      return @fmod.unpackBool(temp)
    end
    #--------------------------------------------------------------------------
    # * Get Channel Volume Level (0.0 -> 1.0)
    #--------------------------------------------------------------------------
    def volume
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetVolume, @handle, temp)
      return @fmod.unpackFloat(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Channel Volume Level (0.0 -> 1.0)
    #--------------------------------------------------------------------------
    def volume=(newVolume)
      @fmod.invoke(Channel_SetVolume, @handle, @fmod.convertFloat(newVolume))
    end
    #--------------------------------------------------------------------------
    # * Get Channel Pan Position (-1.0 -> 1.0)
    #--------------------------------------------------------------------------
    def pan
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetPan, @handle, temp)
      return @fmod.unpackFloat(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Channel Pan Position (-1.0 -> 1.0)
    #--------------------------------------------------------------------------
    def pan=(newPan)
      @fmod.invoke(Channel_SetPan, @handle, @fmod.convertFloat(newPan))
    end
    #--------------------------------------------------------------------------
    # * Get Channel Frequency in HZ (Speed/Pitch)
    #--------------------------------------------------------------------------
    def frequency
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetFrequency, @handle, temp)
      return @fmod.unpackFloat(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Channel Frequency in HZ (Speed/Pitch)
    #--------------------------------------------------------------------------
    def frequency=(newFrequency)
      @fmod.invoke(Channel_SetFrequency, @handle, @fmod.convertFloat(newFrequency))
    end
    #--------------------------------------------------------------------------
    # * Is Channel Paused?
    #--------------------------------------------------------------------------
    def paused
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetPaused, @handle, temp)
      return @fmod.unpackBool(temp)
    end
    #--------------------------------------------------------------------------
    # * Pause Channel
    #--------------------------------------------------------------------------
    def paused=(newPaused)
      @fmod.invoke(Channel_SetPaused, @handle, (newPaused == true) ? 1 : 0)
    end
    #--------------------------------------------------------------------------
    # * Get Current Playback Position
    #     unit            : FMOD_TIMEUNIT to return position in
    #--------------------------------------------------------------------------   
    def position(unit = FMOD_DEFAULT_UNIT)
      temp = 0.chr * 4
      @fmod.invoke(Channel_GetPosition, @handle, temp, unit)
      return @fmod.unpackInt(temp)
    end
    #--------------------------------------------------------------------------
    # * Set Current Playback Position
    #     newPosition     : New playback position
    #     unit            : FMOD_TIMEUNIT to use when setting position
    #--------------------------------------------------------------------------    
    def position=(newPosition, unit = FMOD_DEFAULT_UNIT)
      @fmod.invoke(Channel_SetPosition, @handle, newPosition, unit)
    end
    #--------------------------------------------------------------------------
    # * Dispose of Channel
    #--------------------------------------------------------------------------  
    def dispose
      @handle = 0
      @sound = nil
      @system = nil
      @fmod = nil
    end
  end
  
end

#==============================================================================
# ** FMod
#------------------------------------------------------------------------------
#  A higher level module to access FMOD Ex
#==============================================================================

module Audio
  SLP_TIME=0.01
  #============================================================================
  # ** SoundFile
  #----------------------------------------------------------------------------
  #  Represents a Sound file (BGM, BGS, SE, etc.) and associated Channel
  #============================================================================
  
  class SoundFile
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #--------------------------------------------------------------------------
    attr_accessor :name                     # File name
    attr_accessor :sound                    # FModEx::Sound object
    attr_accessor :channel                  # Channel playing sound
    attr_accessor :volume                   # Volume in RPG::AudioFile format
    attr_accessor :pitch                    # Pitch in RPG::AudioFile format
    attr_accessor :looping                  # Sound loops
    attr_accessor :streaming                # Sound is streamed
    attr_accessor :length                   # Sound length in milliseconds
    #--------------------------------------------------------------------------
    # * Object Initialization
    #--------------------------------------------------------------------------
    def initialize(name, sound, channel, volume, pitch, looping, streaming, length)
      @name = name
      @sound = sound
      @channel = channel
      @volume = volume
      @pitch = pitch
      @looping = looping
      @streaming = streaming
      @length = length
    end
  end
  #--------------------------------------------------------------------------
  # * Instance Variables
  #--------------------------------------------------------------------------
  @fmod_dll = FModEx::DLL.new               # The FMOD Ex DLL
  @fmod = FModEx::System.new(@fmod_dll)     # The global System object
  @fmod_se = []                             # Array of Sound Effects
  @rtp_folder = nil                         # Name of RTP folder
  #--------------------------------------------------------------------------
  # * Get Path of RTP Folder From Registry
  #-------------------------------------------------------------------------- 
  def self.getRTPFolder
    if @rtp_folder
      return @rtp_folder
    end
    open_key = Win32API.new('advapi32.dll', 'RegOpenKeyExA', 'LPLLP', 'L')
    query_value = Win32API.new('advapi32.dll', 'RegQueryValueExA', 'LPLPPP', 'L')
    close_key = Win32API.new('advapi32', 'RegCloseKey', 'L', 'L')
    key = 0.chr * 4
    # Open a HKEY_LOCAL_MACHINE with KEY_READ attribute and save handle in key
    open_key.call(0x80000002, 'Software\Enterbrain\RGSS\RTP', 0, 0x20019, key)
    key = @fmod_dll.unpackInt(key)
    type = 0.chr * 4
    size = 0.chr * 4
    # Query to get string size
    query_value.call(key, 'Standard', 0, type, 0, size)
    data = ' ' * @fmod_dll.unpackInt(size)
    # Query the string value itself using size
    query_value.call(key, 'Standard', 0, type, data, size)
    @rtp_folder = data.chop
    close_key.call(key)
    # Make sure the directory ends with a backslash
    @rtp_folder += "\\" if @rtp_folder[-1].chr != "\\"
    return @rtp_folder
  end
  #--------------------------------------------------------------------------
  # * Return Proper File Name (With Extensions)
  #     name            : Name of the file
  #     extensions      : Extensions to add to file name
  #-------------------------------------------------------------------------- 
  def self.checkExtensions(name, extensions)
    if FileTest.exist?(name)
      return name
    end
    # Add extension if needed
    extensions.each do |ext|
      if FileTest.exist?(name + '.' + ext)
        return name + '.' + ext
      end
    end
    # File doesn't exist
    return name
  end
  #--------------------------------------------------------------------------
  # * Get Valid File Name
  #     name            : Name of the file
  #-------------------------------------------------------------------------- 
  def self.selectBGMFilename(name)
    name = name.gsub("/", "\\")
    # See if file exists in game folder
    localname = self.checkExtensions(name, FModEx::FMOD_FILE_TYPES)
    # See if file exists in RTP
    commonname = self.checkExtensions(getRTPFolder + name, FModEx::FMOD_FILE_TYPES)
    if FileTest.exist?(localname)
      return localname
    end
    if FileTest.exist?(commonname)
      return commonname
    end
    # An invalid name was provided
    return name
  end
  #--------------------------------------------------------------------------
  # * Play a Sound File Then Return it
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the sound loop?
  #     streaming       : Stream sound or load whole thing to memory?
  #-------------------------------------------------------------------------- 
  def self.play(name, volume, pitch, position, looping, streaming)
    # Get a valid file name
    filename = self.selectBGMFilename(name)
    # Create Sound or Stream and set initial values
    sound = streaming ? @fmod.createStream(filename) : @fmod.createSound(filename)
    sound.loopMode = looping ? FModEx::FMOD_LOOP_NORMAL : FModEx::FMOD_LOOP_OFF
    channel = sound.play
    volume = volume * 1.0
    pitch = pitch * 1.0
    file_length = sound.length(FModEx::FMOD_DEFAULT_UNIT)
    sound_file = SoundFile.new(filename, sound, channel, volume, 
                                pitch, looping, streaming, file_length)
    sound_file.channel.volume = volume / 100.0
    sound_file.channel.frequency = sound_file.channel.frequency * pitch / 100
    sound_file.channel.position = position
    return sound_file
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of Sound File
  #-------------------------------------------------------------------------- 
  def self.stop(sound_file)
    unless sound_file and sound_file.channel
      return
    end
    # Stop channel, then clear variables and dispose of bgm
    sound_file.channel.stop
    sound_file.channel = nil
    sound_file.sound.dispose
  end
  #--------------------------------------------------------------------------
  # * Return Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.get_length(sound_file, unit = FModEx::FMOD_DEFAULT_UNIT)
    return sound_file.length#(unit)
  end
  #--------------------------------------------------------------------------
  # * Check if Another Sound File is Playing
  #-------------------------------------------------------------------------- 
  def self.already_playing?(sound_file, name, position = 0)
    # Get a valid file name
    filename = self.selectBGMFilename(name)
    if (sound_file)
      # If the same sound file is already playing don't play it again
      if (sound_file.name == filename and position == 0)
        return true
      end
      # If another sound file is playing, stop it
      if sound_file.channel
        self.stop(sound_file)
      end
    end
    # No sound file is playing or it was already stopped
    return false
  end
  #--------------------------------------------------------------------------
  # * Check if Sound File is Playing
  #--------------------------------------------------------------------------  
  def self.playing?(sound_file)
    unless sound_file and sound_file.channel
      return false
    end
    return sound_file.channel.playing?
  end
  #--------------------------------------------------------------------------
  # * Get Current Sound File Playing Position
  #-------------------------------------------------------------------------- 
  def self.get_position(sound_file)
    unless sound_file and sound_file.channel
      return 0
    end
    return sound_file.channel.position
  end
  #--------------------------------------------------------------------------
  # * Seek to a New Sound File Playing Position
  #-------------------------------------------------------------------------- 
  def self.set_position(sound_file, new_pos)
    unless sound_file and sound_file.channel
      return
    end
    sound_file.channel.position = new_pos
  end
  #--------------------------------------------------------------------------
  # * Get Current Sound File Volume
  #-------------------------------------------------------------------------- 
  def self.get_volume(sound_file)
    unless sound_file
      return 0
    end
    return sound_file.volume
  end
  #--------------------------------------------------------------------------
  # * Set Sound File Volume
  #-------------------------------------------------------------------------- 
  def self.set_volume(sound_file, volume)
    unless sound_file and sound_file.channel
      return
    end
    sound_file.volume = volume * 1.0
    sound_file.channel.volume = volume / 100.0
  end
  #--------------------------------------------------------------------------
  # * Set Loop Points
  #     first           : Loop start point in milliseconds
  #     second          : Loop end point in milliseconds (-1 for file end)
  #     unit            : FMOD_TIMEUNIT for points
  #-------------------------------------------------------------------------- 
  def self.set_loop_points(sound_file, first, second, unit = FModEx::FMOD_DEFAULT_UNIT)
    unless sound_file and sound_file.channel
      return
    end
    # If second is -1 then set loop end to the file end
    if second == -1
      second = sound_file.length - 1
    end
    # Set loop points and reflush stream buffer
    sound_file.channel.sound.setLoopPoints(first, second, unit)
    sound_file.channel.position = sound_file.channel.position
    return sound_file
  end
  #--------------------------------------------------------------------------
  # * Play ME
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the BGM loop?
  #-------------------------------------------------------------------------- 
  def self.me_play(name, volume=100, pitch=100, position = 0, looping = false)
    return if self.already_playing?(@fmod_me, name, position) and Audio.me_playing?
    # Now play the new BGM as a stream
    @fmod_me = self.play(name, volume, pitch, position, false, true)
    Thread.new do
      if @fmod_bgm
        paused=@fmod_bgm.channel.paused
        @fmod_bgm.channel.paused=true
      else
        paused=false
      end
      loop do
        unless @fmod_me
          break
        end
        unless Audio.me_playing?
          break
        end
        sleep(SLP_TIME)
      end
      if @fmod_bgm
        @fmod_bgm.channel.paused=paused
      end
    end
    return @fmod_me
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of ME
  #-------------------------------------------------------------------------- 
  def self.me_stop
    self.stop(@fmod_me)
    @fmod_me = nil
  end
  #--------------------------------------------------------------------------
  # * Return ME Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.me_length(sound_file)
    self.get_length(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Check if a ME is Playing
  #--------------------------------------------------------------------------  
  def self.me_playing?
    return self.playing?(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Get Current ME Playing Position
  #-------------------------------------------------------------------------- 
  def self.me_position
    return self.get_position(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Seek to New ME Playing Position
  #-------------------------------------------------------------------------- 
  def self.me_position=(new_pos)
    self.set_position(@fmod_bgm, new_pos)
  end
  #--------------------------------------------------------------------------
  # * Get Current ME Volume
  #-------------------------------------------------------------------------- 
  def self.me_volume
    return self.get_volume(@fmod_me)
  end
  #--------------------------------------------------------------------------
  # * Set ME Volume
  #-------------------------------------------------------------------------- 
  def self.me_volume=(volume)
    self.set_volume(@fmod_me, volume)
  end
  #--------------------------------------------------------------------------
  # * Set ME fade
  #-------------------------------------------------------------------------- 
  def self.me_fade(time)
    return unless @fmod_me and Audio.me_playing? and !@fading_me
    @fading_me=true
    Thread.new do
      vol=Audio.me_volume
      cnt=(time/1000.0/SLP_TIME).to_i
      cnt.times do |i|
        Audio.me_volume=(vol-(vol*i/cnt))
        sleep SLP_TIME
      end
      Audio.me_stop
      @fading_me=false
    end
  end
  
  
  #--------------------------------------------------------------------------
  # * Play BGM (or ME)
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the BGM loop?
  #-------------------------------------------------------------------------- 
  def self.bgm_play(name, volume=100, pitch=100, position = 0, looping = true)
    return if self.already_playing?(@fmod_bgm, name, position)
    # Now play the new BGM as a stream
    @fmod_bgm = self.play(name, volume, pitch, position, looping, true)
    if @fmod_me and Audio.me_playing?
      @fmod_bgm.channel.paused=true
    end
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of BGM
  #-------------------------------------------------------------------------- 
  def self.bgm_stop
    self.stop(@fmod_bgm)
    @fmod_bgm = nil
  end
  #--------------------------------------------------------------------------
  # * Return BGM Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.bgm_length(sound_file)
    self.get_length(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Check if a BGM is Playing
  #--------------------------------------------------------------------------  
  def self.bgm_playing?
    return self.playing?(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGM Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgm_position
    return self.get_position(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Seek to New BGM Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgm_position=(new_pos)
    self.set_position(@fmod_bgm, new_pos)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGM Volume
  #-------------------------------------------------------------------------- 
  def self.bgm_volume
    return self.get_volume(@fmod_bgm)
  end
  #--------------------------------------------------------------------------
  # * Set BGM Volume
  #-------------------------------------------------------------------------- 
  def self.bgm_volume=(volume)
    self.set_volume(@fmod_bgm, volume)
  end
  #--------------------------------------------------------------------------
  # * Set Loop Points
  #     first           : Loop start point in milliseconds
  #     second          : Loop end point in milliseconds
  #     unit            : FMOD_TIMEUNIT for points
  #-------------------------------------------------------------------------- 
  def self.bgm_set_loop_points(first, second, unit = FModEx::FMOD_DEFAULT_UNIT)
    @fmod_bgm = self.set_loop_points(@fmod_bgm, first, second, unit)
  end
  #--------------------------------------------------------------------------
  # * Set BGM fade
  #-------------------------------------------------------------------------- 
  def self.bgm_fade(time)
    return unless @fmod_bgm and Audio.bgm_playing? and !@fading_bgm
    @fading_bgm=true
    Thread.new do
      vol=Audio.bgm_volume
      cnt=(time/1000.0/SLP_TIME).to_i
      cnt.times do |i|
        Audio.bgm_volume=(vol-(vol*i/cnt))
        sleep SLP_TIME
      end
      Audio.bgm_stop
      @fading_bgm=false
    end
  end
  
  
  #--------------------------------------------------------------------------
  # * Play BGS
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #     position        : Starting position in milliseconds
  #     looping         : Does the BGS loop?
  #-------------------------------------------------------------------------- 
  def self.bgs_play(name, volume=100, pitch=100, position = 0, looping = true)
    return if self.already_playing?(@fmod_bgs, name, position)
    # Now play the new BGS as a stream
    @fmod_bgs = self.play(name, volume, pitch, position, looping, true)
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of BGS
  #-------------------------------------------------------------------------- 
  def self.bgs_stop
    self.stop(@fmod_bgs)
    @fmod_bgs = nil
  end
  #--------------------------------------------------------------------------
  # * Return BGS Length in Milliseconds
  #-------------------------------------------------------------------------- 
  def self.bgm_length(sound_file)
    self.get_length(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Check if a BGS is Playing
  #--------------------------------------------------------------------------  
  def self.bgs_playing?
    return self.playing?(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGS Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgs_position
    return self.get_position(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Seek to New BGS Playing Position
  #-------------------------------------------------------------------------- 
  def self.bgs_position=(new_pos)
    self.set_position(@fmod_bgs, new_pos)
  end
  #--------------------------------------------------------------------------
  # * Get Current BGS Volume
  #-------------------------------------------------------------------------- 
  def self.bgs_volume
    return self.get_volume(@fmod_bgs)
  end
  #--------------------------------------------------------------------------
  # * Set BGS Volume
  #-------------------------------------------------------------------------- 
  def self.bgs_volume=(volume)
    self.set_volume(@fmod_bgs, volume)
  end
  #--------------------------------------------------------------------------
  # * Set Loop Points
  #     first           : Loop start point in milliseconds
  #     second          : Loop end point in milliseconds
  #     unit            : FMOD_TIMEUNIT for points
  #-------------------------------------------------------------------------- 
  def self.bgs_set_loop_points(first, second, unit = FModEx::FMOD_DEFAULT_UNIT)
    @fmod_bgs = self.set_loop_points(@fmod_bgs, first, second, unit)
  end
  #--------------------------------------------------------------------------
  # * Set BGS fade
  #-------------------------------------------------------------------------- 
  def self.bgs_fade(time)
    return unless @fmod_bgs and Audio.bgs_playing? and !@fading_bgs
    @fading_bgs=true
    Thread.new do
      vol=Audio.bgs_volume
      cnt=(time/1000.0/SLP_TIME).to_i
      cnt.times do |i|
        Audio.bgs_volume=(vol-(vol*i/cnt))
        sleep SLP_TIME
      end
      Audio.me_stop
      @fading_bgs=false
    end
  end
  
  #--------------------------------------------------------------------------
  # * Play SE
  #     name            : Name of the file
  #     volume          : Channel volume
  #     pitch           : Channel frequency
  #-------------------------------------------------------------------------- 
  def self.se_play(name, volume=100, pitch=100)
    if @fmod_se.size > @fmod.maxChannels
      #msgbox_p 0
      se = @fmod_se.shift
      #msgbox_p se
      self.stop(se)  if self.playing?(se)
    end
    # Load SE into memory and play it
    @fmod_se << self.play(name, volume, pitch, 0, false, false)
  end
  #--------------------------------------------------------------------------
  # * Stop and Dispose of all SEs
  #-------------------------------------------------------------------------- 
  def self.se_stop
    for se in @fmod_se
      self.stop(se) if self.playing?(se)
    end
    @fmod_se.clear
  end
  #--------------------------------------------------------------------------
  # * Get Rid of Non-Playing SEs
  #--------------------------------------------------------------------------  
      def self.se_clean
      $FMOD_CLEANING=true
    for se in @fmod_se
      unless self.playing?(se)
        self.stop(se)
        @fmod_se.delete(se)
      end
      end
      $FMOD_CLEANING=false   
  end
  #--------------------------------------------------------------------------
  # * Check if There's Some SE in SE Array
  #--------------------------------------------------------------------------  
  def self.se_list_empty?
    return @fmod_se.empty?
  end
  #--------------------------------------------------------------------------
  # * Dispose of Everything
  #--------------------------------------------------------------------------  
  def self.dispose
    self.bgm_stop
    self.bgs_stop
    self.se_stop
    @fmod.dispose
  end
end
end
module FMod
  include Audio
end
And thanks for the feedback. Regards KaiserYoshi
Reply With Quote
  #228    
Old May 4th, 2015 (10:01 AM).
MRFlame MRFlame is offline
 
Join Date: Jun 2010
Gender: Male
Posts: 19
Implement a autobattle feature that is started with a key press and disabled when the key is pressed again.
__________________
Reply With Quote
  #229    
Old May 13th, 2015 (10:13 AM).
rigbycwts's Avatar
rigbycwts rigbycwts is offline
Hmm, hmm.
 
Join Date: Mar 2013
Gender: Male
Nature: Timid
Posts: 55
Online battles would be nice, and I have a feeling that this script I found while searching can be modified to be used in Essentials.
__________________
Coming soon: Pokemon Collective and Mercantile Versions.

Surprise me.
Reply With Quote
  #230    
Old May 17th, 2015 (05:08 PM).
FL's Avatar
FL FL is offline
Pokémon Island Creator
 
Join Date: Sep 2010
Gender: Male
Posts: 1,455
  1. http://kleinstudio.deviantart.com/art/UPDATE-Footprints-add-on-for-Essentials-528319698
  2. http://www.pokecommunity.com/showthread.php?t=344506 since your old TODO lists a starter selection scene.
  3. http://www.pokecommunity.com/showthread.php?t=343653 is requested enough and isn't hard to be made.
  4. This kind of bridge: http://pokemonessentials.wikia.com/wiki/Forum:Board_Walks at example maps.
  5. Make this small change on elevator script for making more easier for changing the floors total: http://pokemonessentials.wikia.com/wiki/Forum:Elevators
  6. Setting the EV max (510 and 255) into constants, instead of these values scattered through the scripts.
__________________
Reply With Quote
  #231    
Old May 21st, 2015 (08:54 PM). Edited 3 Weeks Ago by Rot8er_Cone/.
Rot8er_Cone/ Rot8er_Cone/ is offline
 
Join Date: May 2015
Gender: Male
Posts: 39
Hello, I'm Rot8er_ConeX. I think my phone may have glitched when I made this account and thought I held down X instead of just pressing it. Odd that we can have slashes in our names here.

Anyway, I digress. I'd like to suggest the ability to have a pokemon with three or more types. I personally will be using it to make triple-typed pokemon, but others would be more likely to use it to make the moves Forest's Curse and Trick-or-Treat work properly on dual-typed pokemon.

I admit I edited the suggestions page on the wiki first, but I think I read something that said "feel free to edit to add suggestions, just don't expect them to be implemented quickly"
Reply With Quote
Reply
Quick Reply

Sponsored Links
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are UTC -8. The time now is 03:18 PM.