#==============================================================================
# ** 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