Code:
#==============================================================================
#
# Mouse Script v1 created by: cybersam
# edited by: MagicMagor
# KD
#
#==============================================================================
# Hier handelt es sich um das Mouse-Script von Cybersam und MagicMagor
#
#------------------------------------------------------------------------------
module Mouse
MOUSE_LEFT = 0x01 # left mouse button
MOUSE_RIGHT = 0x02 # right mouse button
MOUSE_MIDDLE = 0x04 # middle mouse button
MSB = 1<<15
@getCursorPos = Win32API.new('user32', 'GetCursorPos', 'p', 'i')
@getWindowRect = Win32API.new('user32', 'GetWindowRect', ['p', 'p'], 'i')
@scr2cli = Win32API.new('user32', 'ScreenToClient', %w(l p), 'i')
@client_rect = Win32API.new('user32', 'GetClientRect', %w(l p), 'i')
@readini = Win32API.new('kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l')
@findwindow = Win32API.new('user32', 'FindWindow', %w(p p), 'l')
@getKeyState = Win32API.new("user32","GetAsyncKeyState",['i'],'i')
class Cursor < Sprite
ORIGIN_X = 0
ORIGIN_Y = 0
CURSOR_BITMAP = "cursor"
def initialize
@cursor_viewport = Viewport.new(0,0,640, 480)
@cursor_viewport.z = 9999
super(@cursor_viewport)
self.bitmap = RPG::Cache.picture(CURSOR_BITMAP)
self.visible = false
self.ox = ORIGIN_X
self.oy = ORIGIN_Y
end
def show
self.visible = true
end
def hide
self.visible = false
end
def set(x,y)
self.x, self.y = x,y
end
end
class MouseKey
def initialize
inf = 1.0/0.0
@released_since = -inf # time of last release
@pressed_since = -inf # time of last press down
@hold = false # current status
@double_click_intervall = inf # duration between the last two releases
end
def last_release
@released_since
end
def last_press
@pressed_since
end
def down?
@hold
end
def clicked?
@released_since == Mouse.update_counter
end
def clicked_since? time, intervall=40
@released_since >= Mouse.update_counter-time && @released_since - @pressed_since <= intervall
end
def pressed?
@hold
end
def pressed_since? time
@hold && @released_since < @pressed_since && @pressed_since >= Mouse.update_counter - time
end
def double_clicked? time=0, intervall=10
clicked_since?(time) && @double_click_intervall <= intervall
end
def update counter, status
return if status == @hold # nothing changes
@hold = status
if status
@pressed_since = counter
else
@double_click_intervall = counter - @released_since
@released_since = counter
end
end
end
class << self
attr_reader :cursor, :x, :y, :left, :middle, :right, :update_counter
#---------------------------------------------------------------------------
# Initialisierung der Maus. Wird zu Spielbeginn aufgerufen
#---------------------------------------------------------------------------
def init
@handle = getHandle()
@cursor = Cursor.new()
@update_counter = 0
@left = MouseKey.new
@middle = MouseKey.new
@right = MouseKey.new
@moving = false
@x = 0
@y = 0
end
def update
@update_counter += 1
update_pos
update_buttons
end
def clicked?
left.clicked? || middle.clicked? || right.clicked?
end
def logical_x
@x + @cursor.ox
end
def logical_y
@y + @cursor.oy
end
def moved?
@moving
end
private
def update_pos
x,y = screenToClient(*get_pos)
@moving = (x != @x) || (y != @y)
@cursor.set(x,y)
@x = x
@y = y
end
def update_buttons
left.update @update_counter, key_down?(MOUSE_LEFT)
middle.update @update_counter, key_down?(MOUSE_MIDDLE)
right.update @update_counter, key_down?(MOUSE_RIGHT)
end
#---------------------------------------------------------------------------
# Checks if key is pressed down.
#---------------------------------------------------------------------------
def key_down?(key)
(@getKeyState.call(key) & MSB) == MSB
end
#---------------------------------------------------------------------------
# Gets mouse position from OS.
#---------------------------------------------------------------------------
def get_pos
pos = [0, 0].pack('ll')
if @getCursorPos.call(pos) != 0
return pos.unpack('ll')
else
[0,0]
end
end
#---------------------------------------------------------------------------
# Gets the client size from OS.
#---------------------------------------------------------------------------
def clientSize()
rect = [0, 0, 0, 0].pack('l4')
@client_rect.call(@handle, rect)
right, bottom = rect.unpack('l4')[2..3]
return right, bottom
end
#---------------------------------------------------------------------------
# Transforms screen-coordinates in client-coordinates.
#---------------------------------------------------------------------------
def screenToClient(x, y)
pos = [x, y].pack('ll')
if @scr2cli.call(@handle, pos) != 0
return pos.unpack('ll')
else
[0,0]
end
end
#---------------------------------------------------------------------------
# Gets the windows handle from OS.
#---------------------------------------------------------------------------
def getHandle()
gameName = "\0" * 256
@readini.call('Game', 'Title', '', gameName, 255, ".\\Game.ini")
gameName.delete!("\0")
if ($DEBUG)
# Only one RGSS Player should be open
result = @findwindow.call('RGSS Player', 0)
else
result = @findwindow.call('RGSS Player', gameName)
end
return result
end
end
end
class << Input
alias update_mouse update
def update
update_mouse
Mouse.update
end
end
Mouse.init
Mouse.cursor.show