From cb684094beb935efe1e6cda878b07ef52f6d1657 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 17 Jan 2021 20:47:57 +0000 Subject: [PATCH] Removed unused audio utilities and audio-recording (e.g. for Chatter) --- Data/Scripts/008_Audio/001_Audio.rb | 214 ++- Data/Scripts/008_Audio/003_Audio_Utilities.rb | 1345 ----------------- .../001_BitmapCache.rb | 41 +- .../002_MessageConfig.rb | 16 + .../009_Objects and windows/010_DrawText.rb | 19 - .../009_Objects and windows/011_Messages.rb | 3 - .../001_Game data/011_Species files.rb | 13 +- .../002_Move/005_Move_Effects_000-07F.rb | 17 +- .../007_PokeBattle_DebugScene.rb | 1 - .../Scripts/013_Overworld/002_PField_Field.rb | 68 - .../016_Pokemon/007_Pokemon_Chatter.rb | 49 - .../Scripts/017_UI/012_PScreen_TrainerCard.rb | 3 - .../005_PSystem_Utilities.rb | 89 -- 13 files changed, 199 insertions(+), 1679 deletions(-) delete mode 100644 Data/Scripts/008_Audio/003_Audio_Utilities.rb delete mode 100644 Data/Scripts/016_Pokemon/007_Pokemon_Chatter.rb diff --git a/Data/Scripts/008_Audio/001_Audio.rb b/Data/Scripts/008_Audio/001_Audio.rb index 45d297356..c862e00aa 100644 --- a/Data/Scripts/008_Audio/001_Audio.rb +++ b/Data/Scripts/008_Audio/001_Audio.rb @@ -1,17 +1,3 @@ -class Thread - def Thread.exclusive - old_critical = Thread.critical - begin - Thread.critical = true - return yield - ensure - Thread.critical = old_critical - end - end -end - - - def getPlayMusic return MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER, "SOFTWARE\\Enterbrain\\RGSS","PlayMusic",true) @@ -29,7 +15,7 @@ class AudioContext def initialize init = Win32API.new("audio.dll", "AudioContextInitialize", '', 'l') - @context=init.call() + @context=init.call end def dispose @@ -59,17 +45,6 @@ def at_exit(&block) $AtExitProcs.push(Proc.new(&block)) end -##################################### -# Works around a problem with FileTest.exist -# if directory contains accent marks -if !defined?(safeExists?) - def safeExists?(f) - ret=false - File.open(f,"rb") { ret=true } rescue nil - return ret - end -end - module AudioState @@ -147,7 +122,7 @@ module AudioState def self.volume; @volume; end def self.waitingBGM=(value); - Thread.exclusive { @waitingBGM=value; } + @waitingBGM = value end def self.volume=(value); @volume=value; end @@ -171,7 +146,7 @@ def Audio_bgm_pitch end def Audio_bgm_play(name, volume, pitch, position = 0) - volume=0 if !getPlayMusic() + volume=0 if !getPlayMusic begin filename = canonicalize(RTP.getAudioPath(name)) if AudioState.meActive? @@ -196,7 +171,7 @@ def Audio_bgm_fade(ms) AudioState::AudioContextFadeOut.call(AudioState.context,ms.to_i) end -def Audio_bgm_stop() +def Audio_bgm_stop begin AudioState::AudioContextStop.call(AudioState.context) AudioState.waitingBGM=nil @@ -222,7 +197,7 @@ def Audio_bgm_set_volume(volume) end def Audio_me_play(name, volume, pitch, position = 0) - volume=0 if !getPlayMusic() + volume=0 if !getPlayMusic begin filename = canonicalize(RTP.getAudioPath(name)) if AudioState.bgmActive? @@ -246,12 +221,12 @@ def Audio_me_fade(ms) AudioState::AudioContextFadeOut.call(AudioState.meContext,ms) end -def Audio_me_stop() +def Audio_me_stop AudioState::AudioContextStop.call(AudioState.meContext) end def Audio_bgs_play(name, volume, pitch, position = 0) - volume=0 if !getPlaySound() + volume=0 if !getPlaySound begin filename = canonicalize(RTP.getAudioPath(name)) AudioState::AudioContextPlay.call(AudioState.bgsContext,filename, @@ -265,12 +240,12 @@ def Audio_bgs_fade(ms) AudioState::AudioContextFadeOut.call(AudioState.bgsContext,ms) end -def Audio_bgs_stop() +def Audio_bgs_stop AudioState::AudioContextStop.call(AudioState.bgsContext) end def Audio_se_play(name, volume, pitch, position = 0) - volume=0 if !getPlaySound() + volume=0 if !getPlaySound begin filename = canonicalize(RTP.getAudioPath(name)) AudioState::AudioContextSEPlay.call(AudioState.seContext,filename, @@ -280,7 +255,7 @@ def Audio_se_play(name, volume, pitch, position = 0) end end -def Audio_se_stop() +def Audio_se_stop AudioState::AudioContextStop.call(AudioState.seContext) end @@ -334,7 +309,7 @@ if safeExists?("audio.dll") end def self.bgm_stop - Audio_bgm_stop() + Audio_bgm_stop end def self.bgm_position @@ -350,7 +325,7 @@ if safeExists?("audio.dll") end def self.me_stop - Audio_me_stop() + Audio_me_stop end def self.bgs_play(name,volume=80,pitch=100) @@ -362,7 +337,7 @@ if safeExists?("audio.dll") end def self.bgs_stop - Audio_bgs_stop() + Audio_bgs_stop end =begin @@ -371,8 +346,169 @@ if safeExists?("audio.dll") end def self.se_stop - Audio_se_stop() + Audio_se_stop end =end end end # safeExists?("audio.dll") + + + +#=============================================================================== +# Methods that determine the duration of an audio file. +#=============================================================================== +def getOggPage(file) + fgetdw = proc { |file| + (file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0)) + } + dw = fgetdw.call(file) + return nil if dw != 0x5367674F + header = file.read(22) + bodysize = 0 + hdrbodysize = (file.read(1)[0] rescue 0) + hdrbodysize.times do + bodysize += (file.read(1)[0] rescue 0) + end + ret = [header, file.pos, bodysize, file.pos + bodysize] + return ret +end + +# internal function +def oggfiletime(file) + fgetdw = proc { |file| + (file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0)) + } + fgetw = proc { |file| + (file.eof? ? 0 : (file.read(2).unpack("v")[0] || 0)) + } + pages = [] + page = nil + loop do + page = getOggPage(file) + break if !page + pages.push(page) + file.pos = page[3] + end + return -1 if pages.length == 0 + curserial = nil + i = -1 + pcmlengths = [] + rates = [] + for page in pages + header = page[0] + serial = header[10, 4].unpack("V") + frame = header[2, 8].unpack("C*") + frameno = frame[7] + frameno = (frameno << 8) | frame[6] + frameno = (frameno << 8) | frame[5] + frameno = (frameno << 8) | frame[4] + frameno = (frameno << 8) | frame[3] + frameno = (frameno << 8) | frame[2] + frameno = (frameno << 8) | frame[1] + frameno = (frameno << 8) | frame[0] + if serial != curserial + curserial = serial + file.pos = page[1] + packtype = (file.read(1)[0] rescue 0) + string = file.read(6) + return -1 if string != "vorbis" + return -1 if packtype != 1 + i += 1 + version = fgetdw.call(file) + return -1 if version != 0 + rates[i] = fgetdw.call(file) + end + pcmlengths[i] = frameno + end + ret = 0.0 + for i in 0...pcmlengths.length + ret += pcmlengths[i].to_f / rates[i] + end + return ret +end + +# Gets the length of an audio file in seconds. Supports WAV, MP3, and OGG files. +def getPlayTime(filename) + if safeExists?(filename) + return [getPlayTime2(filename), 0].max + elsif safeExists?(filename + ".wav") + return [getPlayTime2(filename + ".wav"), 0].max + elsif safeExists?(filename + ".mp3") + return [getPlayTime2(filename + ".mp3"), 0].max + elsif safeExists?(filename + ".ogg") + return [getPlayTime2(filename + ".ogg"), 0].max + end + return 0 +end + +def getPlayTime2(filename) + return -1 if !safeExists?(filename) + time = -1 + fgetdw = proc { |file| + (file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0)) + } + fgetw = proc { |file| + (file.eof? ? 0 : (file.read(2).unpack("v")[0] || 0)) + } + File.open(filename, "rb") { |file| + file.pos = 0 + fdw = fgetdw.call(file) + if fdw == 0x46464952 # "RIFF" + filesize = fgetdw.call(file) + wave = fgetdw.call(file) + return -1 if wave != 0x45564157 # "WAVE" + fmt = fgetdw.call(file) + return -1 if fmt != 0x20746d66 # "fmt " + fmtsize = fgetdw.call(file) + format = fgetw.call(file) + channels = fgetw.call(file) + rate = fgetdw.call(file) + bytessec = fgetdw.call(file) + return -1 if bytessec == 0 + bytessample = fgetw.call(file) + bitssample = fgetw.call(file) + data = fgetdw.call(file) + return -1 if data != 0x61746164 # "data" + datasize = fgetdw.call(file) + time = (datasize*1.0)/bytessec + return time + elsif fdw == 0x5367674F # "OggS" + file.pos = 0 + time = oggfiletime(file) + return time + end + file.pos = 0 + # Find the length of an MP3 file + while true + rstr = "" + ateof = false + while !file.eof? + if (file.read(1)[0] rescue 0) == 0xFF + begin + rstr = file.read(3) + rescue + ateof = true + end + break + end + end + break if ateof || !rstr || rstr.length != 3 + if rstr[0] == 0xFB + t = rstr[1] >> 4 + next if t == 0 || t == 15 + freqs = [44100, 22050, 11025, 48000] + bitrates = [32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320] + bitrate = bitrates[t] + t = (rstr[1] >> 2) & 3 + freq = freqs[t] + t = (rstr[1] >> 1) & 1 + filesize = FileTest.size(filename) + frameLength = ((144000 * bitrate) / freq) + t + numFrames = filesize / (frameLength + 4) + time = (numFrames * 1152.0 / freq) + break + end + end + } + return time +end diff --git a/Data/Scripts/008_Audio/003_Audio_Utilities.rb b/Data/Scripts/008_Audio/003_Audio_Utilities.rb deleted file mode 100644 index 3a04edf6b..000000000 --- a/Data/Scripts/008_Audio/003_Audio_Utilities.rb +++ /dev/null @@ -1,1345 +0,0 @@ -=begin -This script contains various utility functions and classes for dealing -with audio. This is a stand-alone script. - -Audio.square(durationInMs,freq,volume,timbre,async) - Generates a square wave. -Audio.beep(durationInMs,freq,volume,timbre,async) - Alias for Audio.square -Audio.sine(durationInMs,freq,volume,timbre,async) - Generates a sine wave. -Audio.triangle(durationInMs,freq,volume,timbre,async) - Generates a triangle wave. -Audio.saw(durationInMs,freq,volume,async) - Generates a saw wave. -Audio.noise(durationInMs,volume,async) - Generates white noise. -Audio.playTone(toneFile,async) - Plays a tone in the Apple iPod alarm tone format. -Parameters: - durationInMs - duration of the sound in milliseconds. - The module Audio::NoteLength contains useful durations for tones. - If 0 or nil, the frequency is determined using the maximum duration - of the given sound envelopes. - freq - the frequency of the sound in Hz. The higher the frequency, - the higher the pitch. If 0, no sound will be generated. - The module Audio::Note contains useful frequencies for tones. - freq can also be a SoundEnvelope or an array of two element arrays, - as follows: - freq[0] - time in ms to apply the specified frequency - freq[1] - frequency to apply. In between, values will be interpolated - volume - volume of the sound, from 0 through 100 - volume can also be a SoundEnvelope. - async - specifies whether the function will return immediately - without waiting for the sound to finish (stands for asynchronous) - timbre - specifies the timbre of the tone; from 0.0 through 1.0 - timbre can also be a SoundEnvelope or an array of two element arrays, - as follows: - volume[0] - time in ms to apply the specified timbre - volume[1] - timbre to apply. In between, values will be interpolated - -WaveData - A class for holding audio data in memory. This class -is easy to serialize into the save file. - intensity() - Calculates the intensity, or loudness of the data - Returns a value from 0 through 127. - time() - Length of the data in seconds. - play() - Plays the wave data - -getPlayTime(filename) - Gets the length of an audio file in seconds. - Supports WAV, MP3, and OGG files. -getWaveData(filename) - Creates wave data from the given WAV file path. - Returns a WaveData object or an integer: 1=not found; 2=invalid format; - 3=format not supported; 4=no sound in the data (the last error is helpful - for diagnosing whether anything was recorded, since a recording device - can record even if no microphone is attached.) - -beginRecord() - Starts recording. Returns 0 if successful. -getRecorderSample() - Gets a single sample from the microphone. - The beginRecord function must have been called beforehand. -stopRecord() - Stops recording without saving the recording to a file. -endRecord(file) - Stops recording and saves the recording to a file. -=end - -if !defined?(safeExists?) - def safeExists?(f) - ret=false - File.open(f,"rb") { ret=true } rescue nil - return ret - end -end - -def pbSaveSoundData(samples, freq, filename) - samples="" if !samples - data=[ - 0x46464952,samples.length+0x2C, - 0x45564157,0x20746d66,0x10, - 0x01,0x01, # PCM,mono - freq,freq, - 1,8, # 8-bit - 0x61746164,samples.length - ].pack("VVVVVvvVVvvVV") - f=File.open(filename,"wb") - if f - f.write(data) - f.write(samples) - f.close - end -end - -# plays 8 bit mono sound data (default: 11025 Hz) -def pbPlaySoundData(samples,volume,async=false,sampleFreq=11025) - return if !samples || samples.length==0 || sampleFreq==0 - waveOutOpen = Win32API.new("winmm.dll","waveOutOpen","plplll","l") - waveOutPrepareHeader = Win32API.new("winmm.dll","waveOutPrepareHeader","lpl","l") - waveOutWrite = Win32API.new("winmm.dll","waveOutWrite","lpl","l") - waveOutSetVolume = Win32API.new("winmm.dll","waveOutSetVolume","ll","l") - waveOutClose = Win32API.new("winmm.dll","waveOutClose","l","l") - waveOutGetNumDevs = Win32API.new("winmm.dll","waveOutGetNumDevs","","l") - getStringAddress = proc { |obj| - next 0 if !obj - buffer=" "*4 - rtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i') - stringPointer=(obj.__id__*2)+12 - rtlMoveMemory_pi.call(buffer,stringPointer,4) - next buffer.unpack("L")[0] - } - saveToTemp = proc { |samples,freq| - chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - ret = nil - 999.times do - name="" - 8.times { name += chars[rand(chars.length),1] } - name = ENV["TEMP"]+"\\"+name+"_tmp.wav" - next if safeExists?(name) - pbSaveSoundData(samples,freq,name) - ret = name - break - end - next ret - } - playThenDelete = proc { |path,volume,length,_async| - next if !path || !safeExists?(path) - thread=Thread.new{ - Thread.stop - cur_path=Thread.current[:path] - cur_length=Thread.current[:length] - sleep(cur_length) - File.delete(cur_path) rescue nil - } - thread[:path]=path - thread[:length]=length - Audio.se_play(path,volume) - thread.run - sleep(length) - } - waveHdr=[getStringAddress.call(samples),samples.length,0,0,0,0,0,0].pack("V*") - # 8 bit mono sound data - waveFormat=[0x01,0x01,sampleFreq,sampleFreq,1,8,0].pack("vvVVvvv") - duration=samples.length - waveOutHandle=" "*4 - code=waveOutOpen.call(waveOutHandle,-1,waveFormat,0,0,0) - if code!=0 - timeLength=duration.to_f/sampleFreq - path=saveToTemp.call(samples,sampleFreq) - playThenDelete.call(path,volume,timeLength,async) - return - end - waveOutHandle=waveOutHandle.unpack("L")[0] - volume=(volume*65535/100) - volume=(volume << 16)|volume - waveOutSetVolume.call(waveOutHandle,volume) - code=waveOutPrepareHeader.call(waveOutHandle,waveHdr,waveHdr.length) - if code!=0 - waveOutClose.call(waveOutHandle) - return - end - thread=Thread.new{ - Thread.stop - waveOut=Thread.current[:waveOut] - waveHdr=Thread.current[:waveHeader] - waveOutUnprepareHeader=Win32API.new("winmm.dll","waveOutUnprepareHeader","lpl","l") - waveOutClose=Win32API.new("winmm.dll","waveOutClose","l","l") - loop do - sleep(1) - hdr=waveHdr.unpack("V*") - flags=hdr[4] - if (flags&1)==1 - # All done - waveOutUnprepareHeader.call(waveOut,waveHdr,waveHdr.length) - waveOutClose.call(waveOut) - break - end - end - } - thread[:waveOut]=waveOutHandle - thread[:waveHeader]=waveHdr - thread[:waveData]=@samples - if waveOutWrite.call(waveOutHandle,waveHdr,waveHdr.length)!=0 - waveOutClose.call(waveOutHandle) - return - end - thread.run - sleep(@duration/1000.0) if !async - return -end - - - -class NoteEnvelope - attr_accessor :fall - attr_accessor :max - attr_reader :envelope - - def initialize(fall=1200,maxPoint=30) - @fall=fall # time until fall to zero - @maxPoint=maxPoint # maximum point - @envelope=SoundEnvelope.new - end - - def falling(duration) - return self if duration<=0 - @envelope.changeDiscrete(0,@maxPoint) - if duration>=@fall - @envelope.change(fall,0) - @envelope.change(duration-fall,0) - else - @envelope.change(duration,@maxPoint*duration/@fall) - end - @envelope.changeDiscrete(0,0) - return self - end - - def sweeping(duration,sweepDuration) - return self if duration<=0 - return steady(duration) if sweepDuration<=0 - @envelope.changeDiscrete(0,@maxPoint) - falling=true - while duration>0 - dur=duration>sweepDuration ? sweepDuration : duration - if falling - self.falling(dur) - else - sd=sweepDuration - if sd>@fall - d=[(sweepDuration-@fall),dur].min - @envelope.change(d,0) - dur-=d - sd-=d - end - if d==sd - @envelope.change(dur,@maxPoint) - else - @envelope.change(dur,@maxPoint*(@fall-(sd-dur))/@fall) - end - end - falling=!falling - duration-=sweepDuration - end - @envelope.changeDiscrete(0,0) - return self - end - - def rest(duration) - if duration>0 - @envelope.changeDiscrete(0,0) - @envelope.changeDiscrete(duration,0) - end - return self - end - - def steady(duration) - if duration>0 - @envelope.changeDiscrete(0,@maxPoint) - @envelope.changeDiscrete(duration,@maxPoint) - @envelope.changeDiscrete(0,0) - end - return self - end -end - - - -# A class for holding audio data in memory. This class -# is easy to serialize into the save file. -class WaveData - def initialize(samplesPerSec,samples) - @freq=samplesPerSec - @samples=samples.is_a?(String) ? samples.clone : samples.pack("C*") - end - - def setSamples(samples) - @samples=samples.is_a?(String) ? samples.clone : samples - end - - def self._load(string) - data=Marshal.load(string) - ret=self.new(data[0],[]) - ret.setSamples(Zlib::Inflate.inflate(data[1])) - return ret - end - - def _dump(_depth=100) - return Marshal.dump([@freq,Zlib::Deflate.deflate(@samples)]) - end - - def intensity - distance=@samples.length/2000 - i=distance/2 - count=0 - volume=0 - while i<@samples.length - vol=(@samples[i]-128).abs - vol=127 if vol>127 - if vol>=16 - volume+=vol - count+=1 - end - i+=distance - end - return 0 if count==0 - return volume/count # from 0 through 127 - end - - def time - return @freq==0 ? 0.0 : (@samples.length)*1.0/@freq - end - - def play - # Play sound data asynchronously - pbPlaySoundData(@samples,100,true,@freq) - end - - def save(filename) - pbSaveSoundData(@samples,@freq,filename) - end -end - - - -# A class for specifying volume, frequency, and timbre envelopes. -class SoundEnvelope; include Enumerable - def initialize(env=nil) - @e=[]; - set(env) if env - end - - def self.fromToneFile(file) - envelope=self.new - File.open(file,"rb") { |f| - f.gets if !f.eof? - while !f.eof? - ln=f.gets - if ln[ /^(\d+)\s+(\d+)/ ] - envelope.addValueChange($1.to_i,$2.to_i) - end - end - } - return envelope - end - - def length; @e.length; end - def [](x); @e[x]; end - def each; @e.each { |x| yield x }; end - def clear; @e.clear; end - - def changeAbsolute(pos,volume) - return self if pos<0 - velength=@e.length - if velength>0 - @e.push([pos,volume]) - stableSort() - else - @e.push([pos,volume]) - end - return self - end - - def self.initial(value) - return self.new.change(0,value) - end - - def self.smoothVolume(duration,volume) - env=self.new - return env if duration<8 - env.change(0,0) - env.change(5,volume) - env.changeAbsolute(duration-10,volume) - env.changeAbsolute(duration-5,0) - env.changeAbsolute(duration,0) - return env - end - - # Creates a volume envelope using the given attack, decay, and - # release times and the given sustain level. - # duration - duration of the sound - # attack - attack time (in ms), or time between the start of the sound - # and the time where the sound reaches its maximum volume. - # If this value is less than 0, the sound will decay from silence to - # the sustain volume instead (see below). - # decay - decay time (in ms), or time after the attack phase until - # the time where the sound reaches its sustain volume - # sustain - sustain volume, or normal volume of sound (0-100) - # release - release time (in ms), or amount of time to fade out the - # sound when it reaches its end. The sound's duration includes its - # release time. - def self.attackDecayRelease(duration,attack,decay,sustain,release) - env=self.new - if attack<=0 - env.change(0,attack==0 ? 100 : 0) - else - env.change(attack,100) - end - env.change(decay,sustain) - env.changeAbsolute(duration-release,sustain) - if release>20 - env.changeAbsolute(duration-release-4,0) - end - env.changeAbsolute(duration,0) - return env - end - - def self.blink(value,onDuration,offDuration,totalDuration) - return self.new.addValueChanges( - value,onDuration,0,offDuration).repeat(totalDuration) - end - - def change(delta,volume) - return self if delta<0 - velength=@e.length - if velength>0 - @e.push([@e[velength-1][0]+delta,volume]) - else - @e.push([delta,volume]) - end - return self - end - - def duration - return @e.length==0 ? 0 : @e[@e.length-1][0] - end - - def value - return @e.length==0 ? 0 : @e[@e.length-1][1] - end - - def addValueChange(value,duration) - changeDiscrete(0,value) - changeDiscrete(duration,value) - return self - end - - def sweep(value1,value2,duration,sweepDuration=1000/16) - val=true - while duration>0 - dur=durationdesiredDuration - deltaNew=(newDuration-self.duration) - deltaDesired=(desiredDuration-self.duration) - newValue=deltaNew==0 ? self.value : self.value+(item[1]-self.value)*deltaDesired/deltaNew - @e.push([desiredDuration,newValue]) - break - else - @e.push([newDuration,item[1]]) - end - i+=1 - if i>=oldLength - i=0; currentDuration+=oldDuration - end - end - return self - end - - # Changes the volume, frequency, etc. abruptly without blending. - def changeDiscrete(delta,volume) - return self if delta<0 - velength=@e.length - if velength>0 - oldValue=@e[velength-1][1] - oldDelta=@e[velength-1][0] - newDelta=oldDelta+delta - newValue=oldValue - if newDelta!=oldDelta || newValue!=oldValue - @e.push([newDelta,newValue]) - oldDelta=newDelta - oldValue=newValue - end - newValue=volume - if newDelta!=oldDelta || newValue!=oldValue - @e.push([newDelta,newValue]) - end - else - @e.push([delta,volume]) - end - return self - end - - def set(value) - if value.is_a?(SoundEnvelope) || value.is_a?(Array) - @e.clear - for v in value; @e.push(v); end - end - return self - end - - private - - def stableSort - pm=1;while pm<@e.length - pl=pm; while pl>0 && @e[pl-1][0]>@e[pl][0] - tmp=@e[pl]; @e[pl]=@e[pl-1]; @e[pl-1]=tmp - pl-=1; end - pm+=1;end - end -end - - - -# internal class -class SoundEnvelopeIterator# :nodoc: - def initialize(env) - @env=env - @envIndex=0 - end - - def getValue(frame) - value=0 - if @envIndex==@env.length - value=@env[@envIndex-1][1] - elsif @envIndex==0 - value=@env[@envIndex][1] - else - lastPos=@env[@envIndex-1][0] - thisPos=@env[@envIndex][0] - if thisPos!=lastPos - lastVolume=@env[@envIndex-1][1] - thisVolume=@env[@envIndex][1] - value=(thisVolume-lastVolume)*(frame-lastPos)/(thisPos-lastPos)+lastVolume - else - value=@env[@envIndex][1] - end - end - while @envIndex+1<=@env.length && @env[@envIndex][0]==frame.to_i - @envIndex+=1 - end - return value - end -end - - - -# internal class -class WaveForm# :nodoc: - SAMPLEFREQ=11025 - - def initialize(proc,freq,duration,timbre=0.5) - @duration=duration # in ms - @volumeEnvelope=SoundEnvelope.new - @freqEnvelope=SoundEnvelope.new - @timbreEnvelope=SoundEnvelope.new - @proc=proc - @freq=freq - @timbre=timbre - if @freq.is_a?(Array) || @freq.is_a?(SoundEnvelope) - @freqEnvelope.set(@freq) - @freq=@freq.length>0 ? @freq[0][1] : 800 - end - if @timbre.is_a?(Array) || @timbre.is_a?(SoundEnvelope) - @timbreEnvelope.set(@timbre) - @timbre=@timbre.length>0 ? @timbre[0][1] : 0.5 - end - end - - def setFrequencyEnvelope(env) - if env.is_a?(Numeric) - @freqEnvelope.clear - @freqEnvelope.addValueChange(env,@duration) - else - @freqEnvelope.set(env) - end - end - - def setVolumeEnvelope(env) - if env.is_a?(Numeric) - @volumeEnvelope.clear - @volumeEnvelope.addValueChange(env,@duration) - else - @volumeEnvelope.set(env) - end - end - - def lcm(x,y) - return y if x==0; return x if y==0 - return x if x==y - if x>y - incr=x - while x%y!=0 - x+=incr - end - return x - else - incr=y - while y%x!=0 - y+=incr - end - return y - end - end - - def start - @i=0 - @volumeIterator=SoundEnvelopeIterator.new(@volumeEnvelope) - @freqIterator=SoundEnvelopeIterator.new(@freqEnvelope) - @timbreIterator=SoundEnvelopeIterator.new(@timbreEnvelope) - @sampleCount=@duration*SAMPLEFREQ/1000 - @samples=" "*@sampleCount - @exactSamplesPerPass=@freq==0 ? 1.0 : [SAMPLEFREQ.to_f/@freq,1].max - @step=1.0/@exactSamplesPerPass - @exactCounter=0 - end - - def self.frac(x) - return x-x.floor - end - - def nextSample - vol=100 - fframe=@i*1000.0/SAMPLEFREQ - if @volumeEnvelope.length>0 # Update volume - vol=@volumeIterator.getValue(fframe) - end - if @proc - if @freqEnvelope.length>0 # Update frequency - freq=@freqIterator.getValue(fframe) - if freq!=@freq # update sample buffer - @freq=freq - @exactSamplesPerPass=@freq==0 ? 1.0 : [SAMPLEFREQ.to_f/@freq,1].max - @step=1.0/@exactSamplesPerPass - end - end - if @timbreEnvelope.length>0 # Update timbre - @timbre=@timbreIterator.getValue(fframe) - end - if @freq==0 || vol==0 - @samples[@i]=0x80 - else - sample=@proc.call(@exactCounter,@timbre) - @samples[@i]=0x80+(vol*sample).round - end - else # noise - v=vol.abs.to_i*2 - @samples[@i]=0x80+(rand(v).to_i-(v/2)) - end - @i+=1 - @exactCounter+=@step - while @exactCounter>1.0; @exactCounter-=1.0; end - end - - def mixSamples(other) - for i in 0...other.sampleCount - newSamp=((@samples[i]-0x80)+(other.samples[i]-0x80))/2+0x80 - @samples[i]=newSamp - end - end - - def play(volume=100, async=false) - pbPlaySoundData(@samples,volume,async,SAMPLEFREQ) - end - - def generateSound - start - while @i<@sampleCount - nextSample - end - end - - def toWaveData - return WaveData.new(SAMPLEFREQ,@samples) - end - - def save(filename) - pbSaveSoundData(@samples,SAMPLEFREQ,filename) - end - - attr_accessor :samples,:sampleCount -end - - - -module Audio - module Note - REST = 0 - GbelowC = 196 - A = 220 - Asharp = 233 - B = 247 - C = 262 - Csharp = 277 - D = 294 - Dsharp = 311 - E = 330 - F = 349 - Fsharp = 370 - G = 392 - Gsharp = 415 - end - - module NoteLength - WHOLE = 1600 - HALF = WHOLE/2 - QUARTER = HALF/2 - EIGHTH = QUARTER/2 - SIXTEENTH = EIGHTH/2 - end - - def self.noise(durationInMs=200, volume=100, async=false) - return if durationInMs<=0 - waveForm=WaveForm.new(nil,0,durationInMs) - if volume.is_a?(Array) || volume.is_a?(SoundEnvelope) - waveForm.setVolumeEnvelope(volume) - volume=100 - end - waveForm.generateSound - waveForm.play(volume,async) - end - - # internal method - def self.envelopeDuration(env) - return 0 if !env - if env.is_a?(SoundEnvelope) || env.is_a?(Array) - return SoundEnvelope.new(env).duration - end - return 0 - end - - def self.oscillateDouble(durationInMs, freq1, freq2, volume1, volume2, - timbre1, timbre2, proc1, proc2, async=false) - return if durationInMs<0 - freq1Zero=(freq1.is_a?(Numeric) && freq1<=0) || - (freq1.is_a?(Array) && freq1.length==0) - freq2Zero=(freq2.is_a?(Numeric) && freq2<=0) || - (freq2.is_a?(Array) && freq2.length==0) - if freq1Zero && freq2Zero - Thread.sleep(durationInMs/1000.0) if !async - return - end - if durationInMs==0 || durationInMs==nil - durationInMs=[ - envelopeDuration(freq1), - envelopeDuration(freq2), - envelopeDuration(volume1), - envelopeDuration(volume2), - envelopeDuration(timbre1), - envelopeDuration(timbre2) - ].max - return if durationInMs<=0 - end - waveForm1=WaveForm.new(proc1,freq1,durationInMs,timbre1) - waveForm2=WaveForm.new(proc2,freq2,durationInMs,timbre2) - waveForm1.setVolumeEnvelope(volume1) - waveForm2.setVolumeEnvelope(volume2) - waveForm1.generateSound - waveForm2.generateSound - waveForm1.mixSamples(waveForm2) - waveForm1.play(100,async) - end - - def self.oscillate(durationInMs=200, freq=800, volume=100, timbre=0.5, async=false, &block) - return if durationInMs<0 - if (freq.is_a?(Numeric) && freq<=0) || (freq.is_a?(Array) && freq.length==0) - Thread.sleep(durationInMs/1000.0) if !async - return - end - if durationInMs==0 || durationInMs==nil - durationInMs=[ - envelopeDuration(freq), - envelopeDuration(volume), - envelopeDuration(timbre)].max - return if durationInMs<=0 - end - waveForm=WaveForm.new(block,freq,durationInMs,timbre) - if volume.is_a?(Array) || volume.is_a?(SoundEnvelope) - waveForm.setVolumeEnvelope(volume) - volume=100 - end - waveForm.generateSound - waveForm.play(volume,async) - end - - def self.frac(x) - return x-x.floor - end - - TWOPI = Math::PI*2 - @@sineProc2 = proc { |z,timbre| - x = (z1 - for i in 0...tone.length - dtmf(tone[i,1],durationInMs,volume,false) - end - end - t1=0 - t1=1209 if "14ghi7pqrs*".include?(tone) - t1=1336 if "2abc5jkl8tuv0".include?(tone) - t1=1477 if "3def6mno9wxyz#".include?(tone) - t1=1633 if "ABCD".include?(tone) - t2=0 - t2=697 if "12abc3defA".include?(tone) - t2=770 if "4ghi5jkl6mnoB".include?(tone) - t2=852 if "7pqrs8tuv9wxyzC".include?(tone) - t2=941 if "*0#D".include?(tone) - return if t1==0 || t2==0 - doubleSine(durationInMs,t1,t2,volume,volume,0.5,0.5,async) - end - - def self.beep(durationInMs=200, freq=800, volume=100, timbre=0.5, async=false) - square(durationInMs,freq,volume,timbre,async) - end - - @@triangleProc2 = proc { |z,timbre| - next (z>4 - next if t==0 || t==15 - freqs=[44100,22050,11025,48000] - bitrates=[32,40,48,56,64,80,96,112,128,160,192,224,256,320] - bitrate=bitrates[t] - t=(rstr[1]>>2)&3 - freq=freqs[t] - t=(rstr[1]>>1)&1 - filesize=FileTest.size(filename) - frameLength=((144000*bitrate)/freq)+t - numFrames=filesize/(frameLength+4) - time=(numFrames*1152.0/freq) - break - end - end - } - return time -end - -# Creates wave data from the given WAV file path -def getWaveData(filename) - fgetdw=proc { |file| - (file.eof? ? 0 : (file.read(4).unpack("V")[0] || 0)) - } - fgetw=proc { |file| - (file.eof? ? 0 : (file.read(2).unpack("v")[0] || 0)) - } - return 1 if !safeExists?(filename) # Not found - File.open(filename,"rb") { |file| - file.pos=0 - fdw=fgetdw.call(file) - if fdw==0x46464952 # "RIFF" - filesize=fgetdw.call(file) - wave=fgetdw.call(file) - if wave!=0x45564157 # "WAVE" - return 2 - end - fmt=fgetdw.call(file) - if fmt!=0x20746d66 # "fmt " - return 2 - end - fmtsize=fgetdw.call(file) - format=fgetw.call(file) - if format!=1 - return 3 # unsupported - end - channels=fgetw.call(file) # channels (1 or 2) - if channels!=1 - return 3 # unsupported - end - rate=fgetdw.call(file) # samples per second - bytessec=fgetdw.call(file) # avg bytes per second - if bytessec==0 - return 2 - end - bytessample=fgetw.call(file) # bytes per sample - bitssample=fgetw.call(file) # bits per sample (8, 16, etc.) - if bitssample!=8 && bitssample!=16 - return 3 # unsupported - end - data=fgetdw.call(file) - if data!=0x61746164 # "data" - return 2 - end - datasize=fgetdw.call(file) - data=file.read(datasize) - samples=nil - if bitssample==8 - samples=data.unpack("C*") - start=0 - for i in 0...samples.length - s=samples[i] - if s<0x70 || s>=0x90 - start=i - break - end - end - finish=start - i=samples.length-1 - while i>=start - s=samples[i] - if s<0x70 || s>=0x90 - finish=i+1 - break - end - i-=1 - end - if finish==start - return 4 # Nothing was recorded - end - start=0 - finish=samples.length - wave=WaveData.new(rate,samples[start,finish-start]) - return wave - elsif bitssample==16 - samples=data.unpack("v*") - start=0 - for i in 0...samples.length - s=samples[i] - if s>0x1000 && s<0xF000 - start=i - break - end - end - finish=start - i=samples.length-1 - while i>=start - s=samples[i] - if s<0x1000 && s<0xF000 - finish=i+1 - break - end - i-=1 - end - if finish==start - return 4 # Nothing was recorded - end - start=0 - # Convert to 8-bit samples - for i in start...finish - samples[i]=((samples[i]-0x8000)>>8)&0xFF - end - finish=samples.length - return WaveData.new(rate,samples[start,finish-start]) - end - end - } - return 2 -end - -############################### - -begin - MciSendString = Win32API.new('winmm','mciSendString','%w(p,p,l,l)','l') - MciErrorString = Win32API.new('winmm','mciGetErrorString','%w(l,p,l)','l') -rescue - MciSendString = nil - MciErrorString = nil -end - -# Starts recording. Returns 0 if successful. -def beginRecord - return 256+72 if !MciSendString - MciSendString.call("open new type waveaudio alias RECORDER buffer 4",0,0,0) - MciSendString.call("set RECORDER channels 1",0,0,0) - retval=MciSendString.call("record RECORDER",0,0,0) - if retval!=0 - MciSendString.call("close RECORDER",0,0,0) - end - return retval -end - - -# Gets a single sample from the microphone. -# The beginRecord or beginRecordUI function must have been called beforehand. -def getRecorderSample - return 0x8000 if !MciSendString - buffer="\0"*256 - ret=0 - MciSendString.call("stop RECORDER",0,0,0) - MciSendString.call("status RECORDER bitspersample",buffer,256,0) - bitspersample=buffer.to_i - MciSendString.call("status RECORDER level",buffer,256,0) - MciSendString.call("record RECORDER",0,0,0) - if bitspersample==8 - ret=buffer.to_i<<8 # max 128 - else - ret=buffer.to_i # max 0x8000 - end - return ret -end - -def stopRecord() - return if !MciSendString - MciSendString.call("stop RECORDER",0,0,0) - MciSendString.call("close RECORDER",0,0,0) -end - -def endRecord(file) - return if !MciSendString - MciSendString.call("stop RECORDER",0,0,0) - if file && file!="" - MciSendString.call("save RECORDER #{file}",0,0,0) - end - MciSendString.call("close RECORDER",0,0,0) -end - -#Audio.sine(140,SoundEnvelope.initial(6400).change(140,11400),50) diff --git a/Data/Scripts/009_Objects and windows/001_BitmapCache.rb b/Data/Scripts/009_Objects and windows/001_BitmapCache.rb index 96ecb6e61..87e24d09e 100644 --- a/Data/Scripts/009_Objects and windows/001_BitmapCache.rb +++ b/Data/Scripts/009_Objects and windows/001_BitmapCache.rb @@ -270,57 +270,24 @@ end -# A safer version of RPG::Cache, this module loads bitmaps that keep an internal -# reference count. Each call to dispose decrements the reference count and the -# bitmap is freed when the reference count reaches 0. -class Thread - def Thread.exclusive - old_thread_status = Thread.critical - begin - Thread.critical = true - return yield - ensure - Thread.critical = old_thread_status - end - end -end - - - class BitmapWrapper < Bitmap + attr_reader :refcount + @@disposedBitmaps={} @@keys={} -=begin - @@final = lambda { |id| - Thread.exclusive { - if @@disposedBitmaps[id]!=true - File.open("debug.txt","ab") { |f| - f.write("Bitmap finalized without being disposed: #{@@keys[id]}\r\n") - } - end - @@disposedBitmaps[id]=nil - } - } -=end - attr_reader :refcount def dispose return if self.disposed? @refcount-=1 - if @refcount==0 - super - #Thread.exclusive { @@disposedBitmaps[__id__]=true } - end + super if @refcount==0 end def initialize(*arg) super @refcount=1 - #Thread.exclusive { @@keys[__id__]=arg.inspect+caller(1).inspect } - #ObjectSpace.define_finalizer(self,@@final) end - def resetRef # internal + def resetRef @refcount=1 end diff --git a/Data/Scripts/009_Objects and windows/002_MessageConfig.rb b/Data/Scripts/009_Objects and windows/002_MessageConfig.rb index 22073df17..f6b3a0507 100644 --- a/Data/Scripts/009_Objects and windows/002_MessageConfig.rb +++ b/Data/Scripts/009_Objects and windows/002_MessageConfig.rb @@ -600,6 +600,22 @@ def pbFadeOutInWithUpdate(z,sprites,nofadeout=false) end end +# Similar to pbFadeOutIn, but pauses the music as it fades out. +# Requires scripts "Audio" (for bgm_pause) and "SpriteWindow" (for pbFadeOutIn). +def pbFadeOutInWithMusic(zViewport=99999) + playingBGS = $game_system.getPlayingBGS + playingBGM = $game_system.getPlayingBGM + $game_system.bgm_pause(1.0) + $game_system.bgs_pause(1.0) + pos = $game_system.bgm_position + pbFadeOutIn(zViewport) { + yield + $game_system.bgm_position = pos + $game_system.bgm_resume(playingBGM) + $game_system.bgs_resume(playingBGS) + } +end + def pbFadeOutAndHide(sprites) visiblesprites = {} numFrames = (Graphics.frame_rate*0.4).floor diff --git a/Data/Scripts/009_Objects and windows/010_DrawText.rb b/Data/Scripts/009_Objects and windows/010_DrawText.rb index 3be075bd5..4c8716b26 100644 --- a/Data/Scripts/009_Objects and windows/010_DrawText.rb +++ b/Data/Scripts/009_Objects and windows/010_DrawText.rb @@ -1081,25 +1081,6 @@ def drawFormattedTextEx(bitmap,x,y,width,text,baseColor=nil,shadowColor=nil,line drawFormattedChars(bitmap,chars) end -# Deprecated -- not to be used in new code -def coloredToFormattedText(text,baseColor=nil,shadowColor=nil) - base=!baseColor ? Color.new(12*8,12*8,12*8) : baseColor.clone - shadow=!shadowColor ? Color.new(26*8,26*8,25*8) : shadowColor.clone - text2=text.gsub(/&/,"&") - text2.gsub!(//,">") - text2.gsub!(/\\\[([A-Fa-f0-9]{8,8})\]/) { "" } - text2=""+text2 - text2.gsub!(/\\\\/,"\\") - return text2 -end - -# Deprecated -- not to be used in new code -def drawColoredTextEx(bitmap,x,y,width,text,_baseColor=nil,_shadowColor=nil) - chars=getFormattedText(bitmap,x,y,width,-1,coloredToFormattedText(text),32) - drawFormattedChars(bitmap,chars) -end - def pbDrawShadow(bitmap,x,y,width,height,string) return if !bitmap || !string pbDrawShadowText(bitmap,x,y,width,height,string,nil,bitmap.font.color) diff --git a/Data/Scripts/009_Objects and windows/011_Messages.rb b/Data/Scripts/009_Objects and windows/011_Messages.rb index 385c6c8c1..5f9bd3fd8 100644 --- a/Data/Scripts/009_Objects and windows/011_Messages.rb +++ b/Data/Scripts/009_Objects and windows/011_Messages.rb @@ -732,9 +732,6 @@ def pbMessageDisplay(msgwindow,message,letterbyletter=true,commandProc=nil) Graphics.update Input.update facewindow.update if facewindow - if $DEBUG && Input.trigger?(Input::F6) - pbRecord(unformattedText) - end if autoresume && msgwindow.waitcount==0 msgwindow.resume if msgwindow.busy? break if !msgwindow.busy? diff --git a/Data/Scripts/011_Data/001_Game data/011_Species files.rb b/Data/Scripts/011_Data/001_Game data/011_Species files.rb index 2c6653305..c505d64a7 100644 --- a/Data/Scripts/011_Data/001_Game data/011_Species files.rb +++ b/Data/Scripts/011_Data/001_Game data/011_Species files.rb @@ -225,10 +225,6 @@ module GameData def self.play_cry_from_pokemon(pkmn, volume = 90, pitch = nil) return if !pkmn || pkmn.egg? - if pkmn.respond_to?("chatter") && pkmn.chatter - pkmn.chatter.play - return - end filename = self.cry_filename_from_pokemon(pkmn) return if !filename pitch ||= 75 + (pkmn.hp * 25 / pkmn.totalhp) @@ -249,13 +245,8 @@ module GameData ret = 0.0 if species.is_a?(Pokemon) if !species.egg? - if species.respond_to?("chatter") && species.chatter - ret = species.chatter.time - pitch = 1.0 - else - filename = pbResolveAudioSE(GameData::Species.cry_filename_from_pokemon(species)) - ret = getPlayTime(filename) if filename - end + filename = pbResolveAudioSE(GameData::Species.cry_filename_from_pokemon(species)) + ret = getPlayTime(filename) if filename end else filename = pbResolveAudioSE(GameData::Species.cry_filename(species, form)) diff --git a/Data/Scripts/012_Battle/002_Move/005_Move_Effects_000-07F.rb b/Data/Scripts/012_Battle/002_Move/005_Move_Effects_000-07F.rb index b2e252a5e..a3021f4d7 100644 --- a/Data/Scripts/012_Battle/002_Move/005_Move_Effects_000-07F.rb +++ b/Data/Scripts/012_Battle/002_Move/005_Move_Effects_000-07F.rb @@ -292,22 +292,9 @@ end #=============================================================================== -# Confuses the target. Chance of causing confusion depends on the cry's volume. -# Confusion chance is 0% if user doesn't have a recorded cry. (Chatter) +# Confuses the target. (Chatter) #=============================================================================== -class PokeBattle_Move_014 < PokeBattle_ConfuseMove - def pbOnStartUse(user,targets) - @chatterChance = 0 - if user.pokemon && user.pokemon.chatter - # Intensity can be 0-127, so return value is 0-10 - @chatterChance = 10*user.pokemon.chatter.intensity/127 - end - end - - def addlEffect - return @chatterChance if MECHANICS_GENERATION <= 5 - return super - end +class PokeBattle_Move_014 < PokeBattle_Move_013 end diff --git a/Data/Scripts/012_Battle/006_Other battle types/007_PokeBattle_DebugScene.rb b/Data/Scripts/012_Battle/006_Other battle types/007_PokeBattle_DebugScene.rb index b5ce44078..f05a09b6d 100644 --- a/Data/Scripts/012_Battle/006_Other battle types/007_PokeBattle_DebugScene.rb +++ b/Data/Scripts/012_Battle/006_Other battle types/007_PokeBattle_DebugScene.rb @@ -44,7 +44,6 @@ class PokeBattle_DebugSceneNoLogging def pbItemMenu(idxBattler,firstAction); return -1; end def pbResetMoveIndex(idxBattler); end - def pbChatter(user,target); end def pbHPChanged(battler,oldHP,showAnim=false); end def pbFaintBattler(battler); end def pbEXPBar(battler,startExp,endExp,tempExp1,tempExp2); end diff --git a/Data/Scripts/013_Overworld/002_PField_Field.rb b/Data/Scripts/013_Overworld/002_PField_Field.rb index 695428586..10f608708 100644 --- a/Data/Scripts/013_Overworld/002_PField_Field.rb +++ b/Data/Scripts/013_Overworld/002_PField_Field.rb @@ -672,74 +672,6 @@ end -#=============================================================================== -# Voice recorder -#=============================================================================== -def pbRecord(text,maxtime=30.0) - text = "" if !text - textwindow = Window_UnformattedTextPokemon.newWithSize(text,0,0,Graphics.width,Graphics.height-96) - textwindow.z=99999 - if text=="" - textwindow.visible = false - end - wave = nil - msgwindow = pbCreateMessageWindow - oldvolume = Audio_bgm_get_volume() - Audio_bgm_set_volume(0) - delay = 2 - delay.times do |i| - pbMessageDisplay(msgwindow,_INTL("Recording in {1} second(s)...\nPress ESC to cancel.",delay-i),false) - Graphics.frame_rate.times do - Graphics.update - Input.update - textwindow.update - msgwindow.update - if Input.trigger?(Input::B) - Audio_bgm_set_volume(oldvolume) - pbDisposeMessageWindow(msgwindow) - textwindow.dispose - return nil - end - end - end - pbMessageDisplay(msgwindow,_INTL("NOW RECORDING\nPress ESC to stop recording."),false) - if beginRecordUI - frames = (maxtime*Graphics.frame_rate).to_i - frames.times do - Graphics.update - Input.update - textwindow.update - msgwindow.update - if Input.trigger?(Input::B) - break - end - end - tmpFile = ENV["TEMP"]+"\\record.wav" - endRecord(tmpFile) - wave = getWaveDataUI(tmpFile,true) - if wave - pbMessageDisplay(msgwindow,_INTL("PLAYING BACK..."),false) - textwindow.update - msgwindow.update - Graphics.update - Input.update - wave.play - (Graphics.frame_rate*wave.time).to_i.times do - Graphics.update - Input.update - textwindow.update - msgwindow.update - end - end - end - Audio_bgm_set_volume(oldvolume) - pbDisposeMessageWindow(msgwindow) - textwindow.dispose - return wave -end - - - #=============================================================================== # Event movement #=============================================================================== diff --git a/Data/Scripts/016_Pokemon/007_Pokemon_Chatter.rb b/Data/Scripts/016_Pokemon/007_Pokemon_Chatter.rb deleted file mode 100644 index 8c2d1c1d1..000000000 --- a/Data/Scripts/016_Pokemon/007_Pokemon_Chatter.rb +++ /dev/null @@ -1,49 +0,0 @@ -class Pokemon - attr_accessor :chatter -end - - - -def pbChatter(pokemon) - iconwindow=PictureWindow.new(GameData::Species.sprite_bitmap_from_pokemon(pokemon)) - iconwindow.x=(Graphics.width/2)-(iconwindow.width/2) - iconwindow.y=((Graphics.height-96)/2)-(iconwindow.height/2) - if pokemon.chatter - pbMessage(_INTL("It will forget the song it knows.\1")) - if !pbConfirmMessage(_INTL("Are you sure you want to change it?")) - iconwindow.dispose - return - end - end - if pbConfirmMessage(_INTL("Do you want to change its song now?")) - wave=pbRecord(nil,5) - if wave - pokemon.chatter=wave - pbMessage(_INTL("{1} learned a new song!",pokemon.name)) - end - end - iconwindow.dispose - return -end - - - -HiddenMoveHandlers::CanUseMove.add(:CHATTER,proc { |move,pkmn,showmsg| - next true -}) - -HiddenMoveHandlers::UseMove.add(:CHATTER,proc { |move,pokemon| - pbChatter(pokemon) - next true -}) - - -class PokeBattle_Scene - def pbChatter(user,_target) - GameData::Species.play_cry_from_pokemon(user.pokemon, nil, 100) if user.pokemon - Graphics.frame_rate.times do - Graphics.update - Input.update - end - end -end diff --git a/Data/Scripts/017_UI/012_PScreen_TrainerCard.rb b/Data/Scripts/017_UI/012_PScreen_TrainerCard.rb index 6c3c25a1f..b68f8383f 100644 --- a/Data/Scripts/017_UI/012_PScreen_TrainerCard.rb +++ b/Data/Scripts/017_UI/012_PScreen_TrainerCard.rb @@ -31,9 +31,6 @@ class PokemonTrainerCard_Scene @sprites["trainer"].y -= (@sprites["trainer"].bitmap.height-128) @sprites["trainer"].z = 2 pbDrawTrainerCardFront - if $PokemonGlobal.trainerRecording - $PokemonGlobal.trainerRecording.play - end pbFadeInAndShow(@sprites) { pbUpdate } end diff --git a/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb b/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb index 225d66d86..907a11fea 100644 --- a/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb +++ b/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb @@ -128,78 +128,6 @@ end -#=============================================================================== -# General-purpose utilities with dependencies -#=============================================================================== -# Similar to pbFadeOutIn, but pauses the music as it fades out. -# Requires scripts "Audio" (for bgm_pause) and "SpriteWindow" (for pbFadeOutIn). -def pbFadeOutInWithMusic(zViewport=99999) - playingBGS = $game_system.getPlayingBGS - playingBGM = $game_system.getPlayingBGM - $game_system.bgm_pause(1.0) - $game_system.bgs_pause(1.0) - pos = $game_system.bgm_position - pbFadeOutIn(zViewport) { - yield - $game_system.bgm_position = pos - $game_system.bgm_resume(playingBGM) - $game_system.bgs_resume(playingBGS) - } -end - -# Gets the wave data from a file and displays an message if an error occurs. -# Can optionally delete the wave file (this is useful if the file was a -# temporary file created by a recording). -# Requires the script AudioUtilities -# Requires the script "PokemonMessages" -def getWaveDataUI(filename,deleteFile=false) - error = getWaveData(filename) - if deleteFile - begin - File.delete(filename) - rescue Errno::EINVAL, Errno::EACCES, Errno::ENOENT - end - end - case error - when 1 - pbMessage(_INTL("The recorded data could not be found or saved.")) - when 2 - pbMessage(_INTL("The recorded data was in an invalid format.")) - when 3 - pbMessage(_INTL("The recorded data's format is not supported.")) - when 4 - pbMessage(_INTL("There was no sound in the recording. Please ensure that a microphone is attached to the computer and is ready.")) - else - return error - end - return nil -end - -# Starts recording, and displays a message if the recording failed to start. -# Returns true if successful, false otherwise -# Requires the script AudioUtilities -# Requires the script "PokemonMessages" -def beginRecordUI - code = beginRecord - case code - when 0 - return true - when 256+66 - pbMessage(_INTL("All recording devices are in use. Recording is not possible now.")) - return false - when 256+72 - pbMessage(_INTL("No supported recording device was found. Recording is not possible.")) - return false - else - buffer = "\0"*256 - MciErrorString.call(code,buffer,256) - pbMessage(_INTL("Recording failed: {1}",buffer.gsub(/\x00/,""))) - return false - end -end - - - #=============================================================================== # Constants utilities #=============================================================================== @@ -1121,20 +1049,3 @@ def pbLoadRpgxpScene(scene) pbShowObjects(visibleObjects) Graphics.transition(20) end - - - -class PokemonGlobalMetadata - attr_accessor :trainerRecording -end - - - -def pbRecordTrainer - wave = pbRecord(nil,10) - if wave - $PokemonGlobal.trainerRecording = wave - return true - end - return false -end