赞 | 68 |
VIP | 0 |
好人卡 | 0 |
积分 | 65 |
经验 | 0 |
最后登录 | 2023-7-2 |
在线时间 | 119 小时 |
Lv4.逐梦者
- 梦石
- 0
- 星屑
- 6483
- 在线时间
- 119 小时
- 注册时间
- 2020-1-8
- 帖子
- 234
|
#=begin # fmod很强,API很多,但我对音频不了解,也不太关注,通常玩游戏都是静音的 # 所以只写了很基(简)本(陋)的功能 # 文件格式为官方原文的网页翻译 # - 支持内置超过 20 种音频格式 # FMOD Core API 具有本机/内置代码,以支持许多开箱即用的文件格式。 # 默认支持 WAV、MP3 和 Ogg Vorbis,但也支持更多模糊格式,如 AIFF、FLAC 等。 # 包括使用实时音序器实时回放的音序格式。MIDI/MOD/S3M/XM/IT 就是这些例子。 # 尽管F12不会直接报错,但内存泄漏了,具体屏蔽F12方法论坛搜索 module FmodLite # fmodLite.dll依赖的dll # 方法1:预先手动LoadLibrary,fmod.dll可存放目录自由 Win32API.new('kernel32', 'LoadLibrary', 'P', 'L').call("fmod.dll") # 方法2:fmod.dll与Game.exe同目录,可注释上一行代码 #————————————————————————————————— # 适用于BGM/BGS,和 RMXP Audio 一样,窗口非激活也继续播放音频 # bug:API并没有太多的参数检查 # 基本:首先创建系统 # 创建单元(每个都是独立的,该音频持续期间保留该单元字符串) # api操作该单元 # 需手动结束该单元 # 最后释放系统(基本就是结束游戏了) #————————————————————————————————— dll = "fmodLite.dll" # 【系统相关】 # ◆创建系统 # 参数1:系统指针,至少4字节字符串; # 参数2:Fmod的范围[0, 4095],可以理解为同时播放的单元数目; Init = Win32API.new(dll, 'fmod_init', 'PL', 'L') # ◆释放系统 Close = Win32API.new(dll, 'fmod_close', 'V', 'V') # 【单元相关】 # ◆创建并播放 # 参数1:音频文件名; # 参数2:节拍,100为正常; # 参数3:音量,100为正常; # 参数4:播放位置,单位毫秒,如果需要“音量淡入”,设为负值(0写为-1); # 参数5:循环标志,0不循环,非0循环; # 参数6:单元指针,个人定义的结构,至少12字节字符串; Play = Win32API.new(dll, 'fmod_play', 'PLLLLP', 'L') # ◆结束 # 参数1:单元指针,传其字符串即可; Stop = Win32API.new(dll, 'fmod_stop', 'P', 'L') # ◆淡出 # 参数1:单元指针,传其字符串即可; # 参数2:淡出时间,单位毫秒; Fade = Win32API.new(dll, 'fmod_fade', 'PL', 'L') # ◆获取播放的时间位置,单位毫秒 # 参数1:单元指针,传其字符串即可; Pos = Win32API.new(dll, 'fmod_pos', 'P', 'L') # 创建fmod_system PPSys = "\0" * 4 Init.call(PPSys, 32) PPSys.freeze #———————— # 读取RTP目录 #———————— ini, section, rtp_flag = "Game.ini", "[Game]", "RTP" get_section, rtps = false, [] File.open(ini).each_line do |line| line.chop! next if line.empty? if line == section get_section = true next end next if get_section == false rtps << line.split("=")[1] if line.include?(rtp_flag) end rtps.uniq! RTP = [] rtps.each do |i| if i != nil if i == "Standard" dll = "Advapi32.dll" regOpenKeyExA = Win32API.new(dll, 'RegOpenKeyExA', 'LPLLP', 'L') regCloseKey = Win32API.new(dll, 'RegCloseKey', 'L', 'L') regQueryValueExA = Win32API.new(dll, 'RegQueryValueExA', 'LPLLPP', 'L') sub_key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\RPGXP.exe" buf = "\0" * 4 # HKEY_LOCAL_MACHINE = 0x8000_0002 # KEY_READ = 0x20019 regOpenKeyExA.call(0x8000_0002, sub_key, 0, 0x20019, buf) hKey = buf.unpack('L')[0] regQueryValueExA.call(hKey, nil, 0, 0, nil, buf) path = "\0" * buf.unpack('L')[0] regQueryValueExA.call(hKey, nil, 0, 0, path, buf) regCloseKey.call(hKey) RTP << (File.dirname(path.chop!).gsub("\\", "/") << "/RGSS/Standard") else RTP << i if File.directory?(i) end end end module_function # filename 是指相对路径 如 "Audio/BGM/abc" # 编辑器保存的音乐文件名没有扩展名……( ̄_ ̄|||) def find_rtp_file(filename) RTP.each do |path| name = Dir["#{File.join(path, filename)}.**"][0] return name if name != nil end return end def get_file(filename) name = Dir["#{filename}.**"][0] name ||= find_rtp_file(filename) end end END {FmodLite::Close.call()} # 简单示例,这部分就自由发挥吧 class << Audio @@bgm = "\0" * 12 @@bgm_file_name = "" def bgm_play(filename, volume = 100, pitch = 100, pos = 0, loop = 1) if filename == @@bgm_file_name return else self.bgm_stop end if (name = FmodLite.get_file(filename)) == nil self.bgm_stop return end @@bgm_file_name = filename FmodLite::Play.call(name, volume, pitch, pos, loop, @@bgm) end def bgm_stop return if @@bgm_file_name.empty? FmodLite::Stop.call(@@bgm) @@bgm_file_name = "" end def bgm_fade(ms) return if @@bgm_file_name.empty? FmodLite::Fade.call(@@bgm, ms) end def bgm_pos return if @@bgm_file_name.empty? FmodLite::Pos.call(@@bgm) end end #=end
#=begin
# fmod很强,API很多,但我对音频不了解,也不太关注,通常玩游戏都是静音的
# 所以只写了很基(简)本(陋)的功能
# 文件格式为官方原文的网页翻译
# - 支持内置超过 20 种音频格式
# FMOD Core API 具有本机/内置代码,以支持许多开箱即用的文件格式。
# 默认支持 WAV、MP3 和 Ogg Vorbis,但也支持更多模糊格式,如 AIFF、FLAC 等。
# 包括使用实时音序器实时回放的音序格式。MIDI/MOD/S3M/XM/IT 就是这些例子。
# 尽管F12不会直接报错,但内存泄漏了,具体屏蔽F12方法论坛搜索
module FmodLite
# fmodLite.dll依赖的dll
# 方法1:预先手动LoadLibrary,fmod.dll可存放目录自由
Win32API.new('kernel32', 'LoadLibrary', 'P', 'L').call("fmod.dll")
# 方法2:fmod.dll与Game.exe同目录,可注释上一行代码
#—————————————————————————————————
# 适用于BGM/BGS,和 RMXP Audio 一样,窗口非激活也继续播放音频
# bug:API并没有太多的参数检查
# 基本:首先创建系统
# 创建单元(每个都是独立的,该音频持续期间保留该单元字符串)
# api操作该单元
# 需手动结束该单元
# 最后释放系统(基本就是结束游戏了)
#—————————————————————————————————
dll = "fmodLite.dll"
# 【系统相关】
# ◆创建系统
# 参数1:系统指针,至少4字节字符串;
# 参数2:Fmod的范围[0, 4095],可以理解为同时播放的单元数目;
Init = Win32API.new(dll, 'fmod_init', 'PL', 'L')
# ◆释放系统
Close = Win32API.new(dll, 'fmod_close', 'V', 'V')
# 【单元相关】
# ◆创建并播放
# 参数1:音频文件名;
# 参数2:节拍,100为正常;
# 参数3:音量,100为正常;
# 参数4:播放位置,单位毫秒,如果需要“音量淡入”,设为负值(0写为-1);
# 参数5:循环标志,0不循环,非0循环;
# 参数6:单元指针,个人定义的结构,至少12字节字符串;
Play = Win32API.new(dll, 'fmod_play', 'PLLLLP', 'L')
# ◆结束
# 参数1:单元指针,传其字符串即可;
Stop = Win32API.new(dll, 'fmod_stop', 'P', 'L')
# ◆淡出
# 参数1:单元指针,传其字符串即可;
# 参数2:淡出时间,单位毫秒;
Fade = Win32API.new(dll, 'fmod_fade', 'PL', 'L')
# ◆获取播放的时间位置,单位毫秒
# 参数1:单元指针,传其字符串即可;
Pos = Win32API.new(dll, 'fmod_pos', 'P', 'L')
# 创建fmod_system
PPSys = "\0" * 4
Init.call(PPSys, 32)
PPSys.freeze
#————————
# 读取RTP目录
#————————
ini, section, rtp_flag = "Game.ini", "[Game]", "RTP"
get_section, rtps = false, []
File.open(ini).each_line do |line|
line.chop!
next if line.empty?
if line == section
get_section = true
next
end
next if get_section == false
rtps << line.split("=")[1] if line.include?(rtp_flag)
end
rtps.uniq!
RTP = []
rtps.each do |i|
if i != nil
if i == "Standard"
dll = "Advapi32.dll"
regOpenKeyExA = Win32API.new(dll, 'RegOpenKeyExA', 'LPLLP', 'L')
regCloseKey = Win32API.new(dll, 'RegCloseKey', 'L', 'L')
regQueryValueExA = Win32API.new(dll, 'RegQueryValueExA', 'LPLLPP', 'L')
sub_key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\RPGXP.exe"
buf = "\0" * 4
# HKEY_LOCAL_MACHINE = 0x8000_0002
# KEY_READ = 0x20019
regOpenKeyExA.call(0x8000_0002, sub_key, 0, 0x20019, buf)
hKey = buf.unpack('L')[0]
regQueryValueExA.call(hKey, nil, 0, 0, nil, buf)
path = "\0" * buf.unpack('L')[0]
regQueryValueExA.call(hKey, nil, 0, 0, path, buf)
regCloseKey.call(hKey)
RTP << (File.dirname(path.chop!).gsub("\\", "/") << "/RGSS/Standard")
else
RTP << i if File.directory?(i)
end
end
end
module_function
# filename 是指相对路径 如 "Audio/BGM/abc"
# 编辑器保存的音乐文件名没有扩展名……( ̄_ ̄|||)
def find_rtp_file(filename)
RTP.each do |path|
name = Dir["#{File.join(path, filename)}.**"][0]
return name if name != nil
end
return
end
def get_file(filename)
name = Dir["#{filename}.**"][0]
name ||= find_rtp_file(filename)
end
end
END {FmodLite::Close.call()}
# 简单示例,这部分就自由发挥吧
class << Audio
@@bgm = "\0" * 12
@@bgm_file_name = ""
def bgm_play(filename, volume = 100, pitch = 100, pos = 0, loop = 1)
if filename == @@bgm_file_name
return
else
self.bgm_stop
end
if (name = FmodLite.get_file(filename)) == nil
self.bgm_stop
return
end
@@bgm_file_name = filename
FmodLite::Play.call(name, volume, pitch, pos, loop, @@bgm)
end
def bgm_stop
return if @@bgm_file_name.empty?
FmodLite::Stop.call(@@bgm)
@@bgm_file_name = ""
end
def bgm_fade(ms)
return if @@bgm_file_name.empty?
FmodLite::Fade.call(@@bgm, ms)
end
def bgm_pos
return if @@bgm_file_name.empty?
FmodLite::Pos.call(@@bgm)
end
end
#=end
|
-
-
dll.zip
711.58 KB, 下载次数: 8
fmod.dll和fmodLite.dll
评分
-
查看全部评分
|