#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
# Screen Module
# Author: ForeverZer0
# Version: 1.0
# Date: 3.10.2012
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#
# Introduction:
# This is a static module for creating some various effects on the actual
# RGSS Player window instead of the game screen.
#
# Features:
# - Move screen
# - Vibrate screen
# - Get name of game
# - Possible more to come
#
# Instructions:
# - Use the following script calls:
#
# Screen.move(X, Y[, HANDLE])
# - Moves the screen to the given location
# X : The x-coordinate on the screen to move to
# Y : The y-coordinate on the screen to move to
# HANDLE : Optional argument to choose the window to move. If omitted
# the game window will be used
#
# Screen.shake(POWER, SPEED, DURATION[, HANDLE])
# - Shakes the window, using same formula as RGSS, but with vertical shake
# POWER : The amount of pixels the window can move
# SPEED : The speed to apply the shake
# DURATION : The number of frames to shake the window for
# HANDLE : Optional argument to choose the window to move. If omitted
# the game window will be used
#
# Screen.name
# - Gets the name of the game found in the Game.ini file
#
# Screen.shaking?
# - Returns true/false if window is shaking
#
# Compatibility:
# No compatibility issues with other scripts. Some effects either won't work
# or appear strange when game is full screen mode. (Alt + Enter)
#
# Credits/Thanks:
# - ForeverZer0, for the script
#
#+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
#==============================================================================
# ** Screen
#------------------------------------------------------------------------------
# This module performs calls the the underlying Windows API for commands
# to the external window(s) on the platform
#==============================================================================
module Screen
# Defines the calls to the Windows API
MoveWindow = Win32API.new('user32', 'MoveWindow', 'LLLLL', 'I')
GetWindowRect = Win32API.new('user32','GetWindowRect', 'LP', 'I')
FindWindow = Win32API.new('user32', 'FindWindow', 'PP', 'I')
GetPrivateProfileString = Win32API.new('kernel32',
'GetPrivateProfileString','PPPPLP', 'L')
#--------------------------------------------------------------------------
# Initialize the module
#--------------------------------------------------------------------------
def self.init
# Find the handle for the RMXP window and store it
@title = "\0" * 256
GetPrivateProfileString.call('Game', 'Title', '', @title, 256, '.\\Game.ini')
@title.delete!("\0")
@hwnd = FindWindow.call('RGSS Player', @title)
@shaking = false
end
#--------------------------------------------------------------------------
# Get the name of the game
#--------------------------------------------------------------------------
def name
return @title
end
#--------------------------------------------------------------------------
# Start shaking
# power : The strength of the shake
# speed : The speed of the movement
# duration : The number of frames the shake lasts
#--------------------------------------------------------------------------
def self.shake(power, speed, duration, handle = @hwnd)
# If screen is already shaking, end method, else set flag
return if @shaking
@shaking = true
# Calculate milliseconds of a game frame
delay = 1.0 / Graphics.frame_rate
# Represents the upper-left and bottom-right corners of a RECT structure
x1, y1, x2, y2 = self.window_rect
width, height = x2 - x1, y2 - y1
# Set initial values for the shake process
shake_x, shake_y = 0, 0
direction_x = direction_y = 1
power_y = (power * 8) / 7
# Process movement on an asynchronous thread
Thread.new do
# Loop until duration reaches 0
while duration > 0
# Calcluate the movement on the x-axis
if duration >= 1 || shake_x != x1
delta = (power * speed * direction_x) / 10.0
if duration <= 1 && shake_x * (shake_x + delta) < 0
shake_x = x1
else
shake_x += delta
end
direction_x = -1 if shake_x > power * 2
direction_x = 1 if shake_x < - power * 2
end
# Calcluate the movement on the y-axis
if duration >= 1 || shake_y != y1
delta = (power_y * (speed + 1) * direction_y) / 10.0
if duration <= 1 && shake_y * (shake_y + delta) < 0
shake_y = y1
else
shake_y += delta
end
direction_y = -1 if shake_y > power_y * 1.5
direction_y = 1 if shake_y < -power_y * 1.5
end
# Decrement the duration, move the window, and delay the thread
duration -= 1
MoveWindow.call(@hwnd, x1 + shake_x, y1 + shake_y, width, height)
sleep(delay)
end
# Ensure window is back in its original place and disable flag
MoveWindow.call(@hwnd, x1, y1, width, height)
@shaking = false
end
end
#--------------------------------------------------------------------------
# Is screen shaking?
#--------------------------------------------------------------------------
def self.shaking?
return @shaking
end
#--------------------------------------------------------------------------
# Get a handle's RECT structure
# handle : The window handle to get the RECT of
#--------------------------------------------------------------------------
def self.window_rect(handle = @hwnd)
rect = [0, 0, 0, 0].pack('l4')
GetWindowRect.call(handle, rect)
return rect.unpack('l4')
end
#--------------------------------------------------------------------------
# Moves a window to the specified coordinates
# x : The screen coordinate on the horizontal axis
# y : The screen coordinate on the vertical axis
# handle : A handle for a window
#--------------------------------------------------------------------------
def self.move_window(x, y, handle = @hwnd)
x1, y1, x2, y2 = self.window_rect
MoveWindow(handle, x, y, x2 - x1, y2 - y1)
end
end
Screen.init