#==============================================================================
# ** The AVI Player
#
#    by DerVVulfman
#    version 1.3
#    02-28-2010
#    Full SDK 2.2 Compatible (Does not need or require SDK 2.2)
#
#
#  INTRODUCTION:
#
#  Let me for once be quick. ^_^
#
#  This system can play .avi files  with little to no flicker  on playback for
#  both RPGMaker XP and RPGMaker VX projects.  And as far as  playback in both
#  fullscreen and window modes?  No problem.  This system works in both modes.
#  The system will not, nor does not need,  to change the window to fullscreen
#  in order to play any .avi file.
#
#  Oh,  and since  it's written as a lone 'module' and not  as a class,  it is
#  VERY easy to use.
#
#
#
#
#  EVENT & SCRIPT CALLS:
#  A series of calls used (using the call script command) or in your scripts:
#                         Video.load * Video.play
#         Video.start * Video.duration * Video.audio * Video.window
#                               Video.reset
#         . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
#
#  * Video.load(filename)
#          The Video.load command is non-optional.  With it, you may load
#          the file stored in your 'Video' folder.  The .avi extension is
#          optional for .avi files, so you may load "demo.avi" or "demo".
#
#  * Video.play(reset)
#          The Video.play command is non-optional.  With it, you will run
#          the video file established by the Video.load command.   If the
#          optional 'reset' value is set to true, the video playback will
#          reset itself to a default 'fit in window' setting.
#
#  * Video.start(time in frames)
#          (OPTIONAL CALL)
#          The Video.start command  can control where  you wish  to begin
#          playback of the video file established by the Video.load comm-
#          and.   By default, a video starts playback at the beginning of
#          the file, but this can allow playback to start near the middle
#          of a file if you wish.  By caling Video.start  without setting
#          any start position,  you can reset the start  of the playback
#          feature back to it's default 'at the beginning' setting.
#
#  * Video.duration(time in frames)
#          The Video.duration command  can set for you where you wish the
#          video file to stop playing.  This is a useful feature for game
#          designers if they want a video to end playback before the act-
#          ual video itself ends.  By calling Video.duration without set-
#          ting any duration, you reset the system to play the full dura-
#          tion of the video file.
#
#  * Video.audio(volume)
#          (OPTIONAL CALL)
#          The Video.audio command  can adjust the volume  of the movie's
#          playback.  However, take care.   Altering the volume here will
#          also change the volume  of other audio playback in the system.
#          Valid values are from 0 to 1000, with 100 as the default.  The
#          volume value is optional and defaulted to 100.
#
#  * Video.window(true)
#    Video.window(left, top, width, height)
#          (OPTIONAL CALL)
#          The Video.window command  determines if you choose to fill the
#          entire gaming window  with the video  or choose to display the
#          video within a defined window  on the screen.   Merely set the
#          parameters to  'true'  if you want the video stretched to fill
#          the gaming window.  Likewise, the default values mimic the di-
#          mensions of the gaming window.
#
#  * Video.reset
#          (OPTIONAL CALL)
#          The Video.reset command restores values  back to their default
#          states.   Anything changed with the start, duration, audio and
#          window  commands  will be returned  to their  original startup
#          values.  A useful call to be sure.
#
#
#
#
#  VIDEO CONSIDERATIONS:
#
#  First off, please create a new folder  called Video in your project's root
#  directory.  It is here that your .avi files should be stored.
#
#  To ensure good playback quality, it the following .avi encoding specifica-
#  tions are recommended: Xvid + MP3 CBR (it is very important to keep a con-
#  stant bit rate for the audio, else it won't play it)
#
#  And finally, video resolution can be up to either 640x480 for RPGMaker XP
#  or 544×416 for RPGMaker VX.
#
#
#
#
#  AUDIO CONSIDERATIONS:
#
#  As stated when discussing the Video.audio option,  any and all changes to
#  the volume of a movie  will affect the playback of any other audio in the
#  game.  As such, setting a movie to play at 50  (or 50% volume)  will also
#  change the audio of all other effects in your game until you play another
#  video with an increased audio setting.
#
#
#
#
#  RECOMMENDED/REQUIRED:
#
#  If using this script on an RPGMaker XP project, the use of Zeriab's No Hang
#  script is recommended,  or like systems that prevents scripts from hanging.
#
#
#
#
#  CREDITS AND THANKS:
#
#  Soundspawn for creating the first AVI Player of course.  And for a little
#  bit of sarcasm... Enterbrain for LEAVING THE SUCKER OUT.   Aw, come on...
#  The previous versions of the RPGMaker series had them!!!
#
#
#
#
#  TERMS AND CONDITIONS:
#
#  Ya wanna use it?  Go ahead.  Just give both me and Soundspawn due credit.
#  Use anyone else's script to prevent hanging... give 'em credit too, okay?
#
#
#===============================================================================
#==============================================================================
# ** Video
#
#  This module controls .avi video playback functions.
#==============================================================================
module Video
#  = = = = = = = = C O N F I G U R A B L E S = = = = = = =
# Depending on XP or VX system (544x416 with RPGMaker VX)
V_MAXWIDTH  = 640 # (or 544 if for RMVX)
V_MAXHEIGHT = 480 # (or 416 if for RMVX)
# The Video Escape Button
VIDEO_ESCAPE  = Input::B
#=============================================================================
# * Set Video
#     video  : filename of video
#=============================================================================
def self.load(video)
# Reset invalid flag
@invalid = nil
# Determine that directory exists, set invalid flag to true
begin; Dir.open("./Video"); rescue Errno::ENOENT; @invalid = true; end
# Optional default extension of .avi
video = video + ".avi" if FileTest.exist?("./Video/#{video}.avi")
# Determine that video exists
@invalid = true unless FileTest.exist?("./Video/#{video}")
# Load only valid video
@movie = "./Video/#{video}" unless @invalid == true
end
#=============================================================================
# * Set Start
#     start  : start in frames to begin video playback (default = nil)
#=============================================================================
def self.start(start=nil)
@start = start
end
#=============================================================================
# * Set Duration
#     duration  : duration in frames to play the video (default = nil)
#=============================================================================
def self.duration(duration=nil)
@duration = duration
end
#=============================================================================
# * Set Audio
#     volume  : volume playback (1 to 1000, with 100 default)
#=============================================================================
def self.audio(volume=100)
@volume = volume
end
#=============================================================================
# * Set Window
#     left    : left position of video (or 'true' if fit in window)
#     top     : right position of video
#     width   : width of video window
#     height  : height of video window
#=============================================================================
def self.window(left=0, top=0, width=V_MAXWIDTH, height=V_MAXHEIGHT)
# If fit in game window
if left == true
@left = 0 ; @top = 0 ; @width = V_MAXWIDTH ; @height = V_MAXHEIGHT
# Or use user-defined settings
else
@left = left ; @top = top ; @width = width ; @height = height
end
end
#=============================================================================
# * Reset All
#=============================================================================
def self.reset
start
duration
audio
window
end
#=============================================================================
# * Play Video
#=============================================================================
def self.play(reset_after_play = false)
# Exit if no valid video
return if @invalid == true
# Windows API Handles
readini   = Win32API.new 'kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l'
wnd       = Win32API.new('user32','FindWindowEx','%w(l,l,p,p)','L')
@mplayer  = Win32API.new('winmm','mciSendString','%w(p,p,l,l)','V')
# Detect Parameters of Current Game Window
@detector = Win32API.new('user32','GetSystemMetrics','%w(l)','L')
# Load Video File & Attach to Game Window
@mplayer.call("open #{@movie} alias FILM style child parent " +
handle.to_s, 0, 0, 0)
# Prepare the Video
self.prepare(reset_after_play)
# Play Video
info  = " " * 255
info2 = " " * 255
info3 = " " * 255
play_message = "play FILM window"
play_message += " from " + @start.to_s if @start != nil
@mplayer.call(play_message, 0, 0, 0)
loop do
sleep(1.0 / 24)
Input.update
@mplayer.call("status FILM mode", info, 255, 0)
@mplayer.call("status FILM position", info2, 255, 0)
state = info.unpack("a*")[0].gsub!("\000","")
if @duration != nil
break if info2.to_i >= @duration
end
# Exit on end or Key control
unless VIDEO_ESCAPE == nil
break if Input.repeat?(VIDEO_ESCAPE) or state.to_s == "stopped"
else
break if state.to_s == "stopped"
end
end
# Reset Audio and Close Video
@mplayer.call("close FILM", 0, 0, 0)
Input.update
end
#
# * Game Window Handle
#
def self.handle
game_name = "\0" * 256
readini=Win32API.new('kernel32', 'GetPrivateProfileStringA', 'pppplp', 'l')
readini.call('Game', 'Title', '', game_name, 255, ".\\Game.ini")
return Win32API.new('user32', 'FindWindowEx', 'llpp', 'l').call(0, 0, nil,
game_name.delete!("\0"))
end
#=============================================================================
# * Video Prepare
#=============================================================================
def self.prepare(reset)
# Set defaults
l = 0 ; t = 0; w = V_MAXWIDTH ; h = V_MAXHEIGHT ; v = 100 ; s = nil ; d = nil
# Load options if available
l = @left   if @left   != nil ; t = @top      if @top    != nil
w = @width  if @width  != nil ; h = @height   if @height != nil
v = @volume if @volume != nil ; d = @duration if @duration != nil
s = @start  if @start  != nil
# Prepare
@mplayer.call("put FILM window at #{l} #{t} #{w} #{h}", 0, 0, 0)
@mplayer.call("setaudio FILM volume to #{v}", @status, 0, 0)
# If the called values reset after the movie plays
@left, @top, @width, @height, @volume, @start, @duration = nil, nil, nil, nil, nil, nil, nil if reset
end
end