Remove Win32API calls & upgrade to modern Ruby (#96)

* Win32API removal + Ruby 3 updates
* Update binaries to match mkxp-z 2.1
This commit is contained in:
Roza
2021-02-25 17:09:59 -05:00
committed by GitHub
parent 87285a2a1f
commit 1f2309c4d2
36 changed files with 445 additions and 2224 deletions

View File

@@ -393,3 +393,8 @@ module Settings
"Power Clear" "Power Clear"
] ]
end end
module Essentials
VERSION = "18.1.dev"
ERROR_TEXT = ""
end

View File

@@ -1,8 +1,4 @@
$MKXP = !!defined?(System) $VERBOSE = nil
def mkxp?
return $MKXP
end
def pbSetWindowText(string) def pbSetWindowText(string)
System.set_window_title(string || System.game_title) System.set_window_title(string || System.game_title)

View File

@@ -0,0 +1,85 @@
#############################
#
# HTTP utility functions
#
#############################
def pbPostData(url, postdata, filename=nil, depth=0)
if url[/^http:\/\/([^\/]+)(.*)$/]
host = $1
path = $2
path = "/" if path.length==0
userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14"
body = postdata.map { |key, value|
keyString = key.to_s
valueString = value.to_s
keyString.gsub!(/[^a-zA-Z0-9_\.\-]/n) { |s| sprintf('%%%02x', s[0]) }
valueString.gsub!(/[^a-zA-Z0-9_\.\-]/n) { |s| sprintf('%%%02x', s[0]) }
next "#{keyString}=#{valueString}"
}.join('&')
ret = HTTPLite.post_body(
url,
body,
"application/x-www-form-urlencoded",
{
"Host" => host, # might not be necessary
"Proxy-Connection" => "Close",
"Content-Length" => body.bytesize.to_s,
"Pragma" => "no-cache",
"User-Agent" => userAgent
}
) rescue ""
return ret if !ret.is_a?(Hash)
return "" if ret[:status] != 200
return ret[:body] if !filename
File.open(filename, "wb"){|f|f.write(ret[:body])}
return ""
end
return ""
end
def pbDownloadData(url, filename = nil, authorization = nil, depth = 0, &block)
headers = {
"Proxy-Connection" => "Close",
"Pragma" => "no-cache",
"User-Agent" => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14"
}
headers["authorization"] = authorization if authorization
ret = HTTPLite.get(url, headers) rescue ""
return ret if !ret.is_a?(Hash)
return "" if ret[:status] != 200
return ret[:body] if !filename
File.open(filename, "wb"){|f|f.write(ret[:body])}
return ""
end
def pbDownloadToString(url)
begin
data = pbDownloadData(url)
return data
rescue
return ""
end
end
def pbDownloadToFile(url, file)
begin
pbDownloadData(url,file)
rescue
end
end
def pbPostToString(url, postdata)
begin
data = pbPostData(url, postdata)
return data
rescue
return ""
end
end
def pbPostToFile(url, postdata, file)
begin
pbPostData(url, postdata,file)
rescue
end
end

View File

@@ -1,44 +0,0 @@
class Win32API
@@RGSSWINDOW = nil
@@GetCurrentThreadId = Win32API.new('kernel32', 'GetCurrentThreadId', '%w()', 'l')
@@GetWindowThreadProcessId = Win32API.new('user32', 'GetWindowThreadProcessId', '%w(l p)', 'l')
@@FindWindowEx = Win32API.new('user32', 'FindWindowEx', '%w(l l p p)', 'l')
# Added by Peter O. as a more reliable way to get the RGSS window
def Win32API.pbFindRgssWindow
return @@RGSSWINDOW if @@RGSSWINDOW
processid = [0].pack('l')
threadid = @@GetCurrentThreadId.call
nextwindow = 0
loop do
nextwindow = @@FindWindowEx.call(0,nextwindow,"RGSS Player",0)
if nextwindow!=0
wndthreadid = @@GetWindowThreadProcessId.call(nextwindow,processid)
if wndthreadid==threadid
@@RGSSWINDOW = nextwindow
return @@RGSSWINDOW
end
end
break if nextwindow==0
end
raise "Can't find RGSS player window"
end
# Returns the size of the window. Used in detecting the mouse position.
def Win32API.client_size
hWnd = pbFindRgssWindow
rect = [0,0,0,0].pack('l4')
Win32API.new('user32','GetClientRect',%w(l p),'i').call(hWnd,rect)
width,height = rect.unpack('l4')[2..3]
return width,height
end
end
# Well done for finding this place.
# DO NOT EDIT THESE
module Essentials
VERSION = "18.1.dev"
ERROR_TEXT = ""
end

View File

@@ -0,0 +1,54 @@
# To use the console, use the executable explicitly built
# with the console enabled on Windows. On Linux and macOS,
# just launch the executable directly from a terminal.
module Console
def self.setup_console
return unless $DEBUG
echo "#{System.game_title} Output Window\n"
echo "-------------------------------\n"
echo "If you are seeing this window, you are running\n"
echo "#{System.game_title} in Debug Mode. This means\n"
echo "that you're either playing a Debug Version, or\n"
echo "you are playing from within RPG Maker XP.\n"
echo "\n"
echo "Closing this window will close the game. If \n"
echo "you want to get rid of this window, run the\n"
echo "program from the Shell, or download a Release\n"
echo "version.\n"
echo "\n"
echo "Gameplay will be paused while the console has\n"
echo "focus. To resume playing, switch to the Game\n"
echo "Window.\n"
echo "-------------------------------\n"
echo "Debug Output:\n"
echo "-------------------------------\n\n"
end
def self.readInput
return gets.strip
end
def self.readInput2
return self.readInput
end
def self.get_input
echo self.readInput2
end
end
module Kernel
def echo(string)
unless $DEBUG
return
end
printf(string.is_a?(String) ? string : string.inspect)
end
def echoln(string)
echo(string)
echo("\r\n")
end
end

View File

@@ -1,699 +0,0 @@
module Win32
def copymem(len)
buf = "\0" * len
Win32API.new("kernel32", "RtlMoveMemory", "ppl", "").call(buf, self, len)
buf
end
end
# Extends the numeric class.
class Numeric
include Win32
end
# Extends the string class.
class String
include Win32
end
module Winsock
DLL = "ws2_32"
#-----------------------------------------------------------------------------
# * Accept Connection
#-----------------------------------------------------------------------------
def self.accept(*args)
Win32API.new(DLL, "accept", "ppl", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Bind
#-----------------------------------------------------------------------------
def self.bind(*args)
Win32API.new(DLL, "bind", "ppl", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Close Socket
#-----------------------------------------------------------------------------
def self.closesocket(*args)
Win32API.new(DLL, "closesocket", "p", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Connect
#-----------------------------------------------------------------------------
def self.connect(*args)
Win32API.new(DLL, "connect", "ppl", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Get host (Using Adress)
#-----------------------------------------------------------------------------
def self.gethostbyaddr(*args)
Win32API.new(DLL, "gethostbyaddr", "pll", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Get host (Using Name)
#-----------------------------------------------------------------------------
def self.gethostbyname(*args)
Win32API.new(DLL, "gethostbyname", "p", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Get host's Name
#-----------------------------------------------------------------------------
def self.gethostname(*args)
Win32API.new(DLL, "gethostname", "pl", "").call(*args)
end
#-----------------------------------------------------------------------------
# * Get Server (Using Name)
#-----------------------------------------------------------------------------
def self.getservbyname(*args)
Win32API.new(DLL, "getservbyname", "pp", "p").call(*args)
end
#-----------------------------------------------------------------------------
# * Convert Host Long To Network Long
#-----------------------------------------------------------------------------
def self.htonl(*args)
Win32API.new(DLL, "htonl", "l", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Convert Host Short To Network Short
#-----------------------------------------------------------------------------
def self.htons(*args)
Win32API.new(DLL, "htons", "l", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Inet Adress
#-----------------------------------------------------------------------------
def self.inet_addr(*args)
Win32API.new(DLL, "inet_addr", "p", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Inet N To A
#-----------------------------------------------------------------------------
def self.inet_ntoa(*args)
Win32API.new(DLL, "inet_ntoa", "l", "p").call(*args)
end
#-----------------------------------------------------------------------------
# * Listen
#-----------------------------------------------------------------------------
def self.listen(*args)
Win32API.new(DLL, "listen", "pl", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Recieve
#-----------------------------------------------------------------------------
def self.recv(*args)
Win32API.new(DLL, "recv", "ppll", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Select
#-----------------------------------------------------------------------------
def self.select(*args)
Win32API.new(DLL, "select", "lpppp", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Send
#-----------------------------------------------------------------------------
def self.send(*args)
Win32API.new(DLL, "send", "ppll", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Set Socket Options
#-----------------------------------------------------------------------------
def self.setsockopt(*args)
Win32API.new(DLL, "setsockopt", "pllpl", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Shutdown
#-----------------------------------------------------------------------------
def self.shutdown(*args)
Win32API.new(DLL, "shutdown", "pl", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Socket
#-----------------------------------------------------------------------------
def self.socket(*args)
Win32API.new(DLL, "socket", "lll", "l").call(*args)
end
#-----------------------------------------------------------------------------
# * Get Last Error
#-----------------------------------------------------------------------------
def self.WSAGetLastError(*args)
Win32API.new(DLL, "WSAGetLastError", "", "l").call(*args)
end
end
if !Object.const_defined?(:Socket) # for compatibility
#===============================================================================
# ** Socket - Creates and manages sockets.
#-------------------------------------------------------------------------------
# Author Ruby
# Version 1.8.1
#===============================================================================
class Socket
#-----------------------------------------------------------------------------
# * Constants
#-----------------------------------------------------------------------------
AF_UNSPEC = 0
AF_UNIX = 1
AF_INET = 2
AF_IPX = 6
AF_APPLETALK = 16
PF_UNSPEC = 0
PF_UNIX = 1
PF_INET = 2
PF_IPX = 6
PF_APPLETALK = 16
SOCK_STREAM = 1
SOCK_DGRAM = 2
SOCK_RAW = 3
SOCK_RDM = 4
SOCK_SEQPACKET = 5
IPPROTO_IP = 0
IPPROTO_ICMP = 1
IPPROTO_IGMP = 2
IPPROTO_GGP = 3
IPPROTO_TCP = 6
IPPROTO_PUP = 12
IPPROTO_UDP = 17
IPPROTO_IDP = 22
IPPROTO_ND = 77
IPPROTO_RAW = 255
IPPROTO_MAX = 256
SOL_SOCKET = 65535
SO_DEBUG = 1
SO_REUSEADDR = 4
SO_KEEPALIVE = 8
SO_DONTROUTE = 16
SO_BROADCAST = 32
SO_LINGER = 128
SO_OOBINLINE = 256
SO_RCVLOWAT = 4100
SO_SNDTIMEO = 4101
SO_RCVTIMEO = 4102
SO_ERROR = 4103
SO_TYPE = 4104
SO_SNDBUF = 4097
SO_RCVBUF = 4098
SO_SNDLOWAT = 4099
TCP_NODELAY = 1
MSG_OOB = 1
MSG_PEEK = 2
MSG_DONTROUTE = 4
IP_OPTIONS = 1
IP_DEFAULT_MULTICAST_LOOP = 1
IP_DEFAULT_MULTICAST_TTL = 1
IP_MULTICAST_IF = 2
IP_MULTICAST_TTL = 3
IP_MULTICAST_LOOP = 4
IP_ADD_MEMBERSHIP = 5
IP_DROP_MEMBERSHIP = 6
IP_TTL = 7
IP_TOS = 8
IP_MAX_MEMBERSHIPS = 20
EAI_ADDRFAMILY = 1
EAI_AGAIN = 2
EAI_BADFLAGS = 3
EAI_FAIL = 4
EAI_FAMILY = 5
EAI_MEMORY = 6
EAI_NODATA = 7
EAI_NONAME = 8
EAI_SERVICE = 9
EAI_SOCKTYPE = 10
EAI_SYSTEM = 11
EAI_BADHINTS = 12
EAI_PROTOCOL = 13
EAI_MAX = 14
AI_PASSIVE = 1
AI_CANONNAME = 2
AI_NUMERICHOST = 4
AI_MASK = 7
AI_ALL = 256
AI_V4MAPPED_CFG = 512
AI_ADDRCONFIG = 1024
AI_DEFAULT = 1536
AI_V4MAPPED = 2048
#--------------------------------------------------------------------------
# * Returns the associated IP address for the given hostname.
#--------------------------------------------------------------------------
def self.getaddress(host)
gethostbyname(host)[3].unpack("C4").join(".")
end
#--------------------------------------------------------------------------
# * Returns the associated IP address for the given hostname.
#--------------------------------------------------------------------------
def self.getservice(serv)
case serv
when Numeric
return serv
when String
return getservbyname(serv)
else
raise "Please use an integer or string for services."
end
end
#--------------------------------------------------------------------------
# * Returns information about the given hostname.
#--------------------------------------------------------------------------
def self.gethostbyname(name)
raise SocketError::ENOASSOCHOST if (ptr = Winsock.gethostbyname(name)) == 0
host = ptr.copymem(16).unpack("iissi")
[host[0].copymem(64).split("\0")[0], [], host[2], host[4].copymem(4).unpack("l")[0].copymem(4)]
end
#--------------------------------------------------------------------------
# * Returns the user's hostname.
#--------------------------------------------------------------------------
def self.gethostname
buf = "\0" * 256
Winsock.gethostname(buf, 256)
buf.strip
end
#--------------------------------------------------------------------------
# * Returns information about the given service.
#--------------------------------------------------------------------------
def self.getservbyname(name)
case name
when /echo/i
return 7
when /daytime/i
return 13
when /ftp/i
return 21
when /telnet/i
return 23
when /smtp/i
return 25
when /time/i
return 37
when /http/i
return 80
when /pop/i
return 110
else
#Network.testing? != 0 ? (Network.testresult(true)) : (raise "Service not recognized.")
#return if Network.testing? == 2
end
end
#--------------------------------------------------------------------------
# * Creates an INET-sockaddr struct.
#--------------------------------------------------------------------------
def self.sockaddr_in(port, host)
begin
[AF_INET, getservice(port)].pack("sn") + gethostbyname(host)[3] + [].pack("x8")
rescue
#Network.testing? != 0 ? (Network.testresult(true)): (nil)
#return if Network.testing? == 2
rescue Hangup
#Network.testing? != 0 ? (Network.testresult(true)): (nil)
#return if Network.testing? == 2
end
end
#--------------------------------------------------------------------------
# * Creates a new socket and connects it to the given host and port.
#--------------------------------------------------------------------------
def self.open(*args)
socket = new(*args)
if block_given?
begin
yield socket
ensure
socket.close
end
end
nil
end
#--------------------------------------------------------------------------
# * Creates a new socket.
#--------------------------------------------------------------------------
def initialize(domain, type, protocol)
SocketError.check if (@fd = Winsock.socket(domain, type, protocol)) == -1
@fd
end
#--------------------------------------------------------------------------
# * Accepts incoming connections.
#--------------------------------------------------------------------------
def accept(flags = 0)
buf = "\0" * 16
SocketError.check if Winsock.accept(@fd, buf, flags) == -1
buf
end
#--------------------------------------------------------------------------
# * Binds a socket to the given sockaddr.
#--------------------------------------------------------------------------
def bind(sockaddr)
SocketError.check if (ret = Winsock.bind(@fd, sockaddr, sockaddr.size)) == -1
ret
end
#--------------------------------------------------------------------------
# * Closes a socket.
#--------------------------------------------------------------------------
def close
SocketError.check if (ret = Winsock.closesocket(@fd)) == -1
ret
end
#--------------------------------------------------------------------------
# * Connects a socket to the given sockaddr.
#--------------------------------------------------------------------------
def connect(sockaddr)
#return if Network.testing? == 2
SocketError.check if (ret = Winsock.connect(@fd, sockaddr, sockaddr.size)) == -1
ret
end
#--------------------------------------------------------------------------
# * Listens for incoming connections.
#--------------------------------------------------------------------------
def listen(backlog)
SocketError.check if (ret = Winsock.listen(@fd, backlog)) == -1
ret
end
#--------------------------------------------------------------------------
# * Checks waiting data's status.
#--------------------------------------------------------------------------
def select(timeout) # timeout in seconds
SocketError.check if (ret = Winsock.select(1, [1, @fd].pack("ll"), 0, 0, [timeout.to_i,
(timeout * 1000000).to_i].pack("ll"))) == -1
ret
end
#--------------------------------------------------------------------------
# * Checks if data is waiting.
#--------------------------------------------------------------------------
def ready?
not select(0) == 0
end
#--------------------------------------------------------------------------
# * Reads data from socket.
#--------------------------------------------------------------------------
def read(len)
buf = "\0" * len
Win32API.new("msvcrt", "_read", "lpl", "l").call(@fd, buf, len)
buf
end
#--------------------------------------------------------------------------
# * Returns received data.
#--------------------------------------------------------------------------
def recv(len, flags = 0)
retString=""
remainLen=len
while remainLen > 0
buf = "\0" * remainLen
retval=Winsock.recv(@fd, buf, buf.size, flags)
SocketError.check if retval == -1
# Note: Return value may not equal requested length
remainLen-=retval
retString+=buf[0,retval]
end
return retString
end
#--------------------------------------------------------------------------
# * Sends data to a host.
#--------------------------------------------------------------------------
def send(data, flags = 0)
SocketError.check if (ret = Winsock.send(@fd, data, data.size, flags)) == -1
ret
end
#--------------------------------------------------------------------------
# * Recieves file from a socket
# size : file size
# scene : update scene boolean
#--------------------------------------------------------------------------
def recv_file(size,scene=false,file="")
data = []
size.times do |i|
if scene == true
$scene.recv_update(size,i,file) if i%((size/1000)+1)== 0
else
Graphics.update if i%1024 == 0
end
data << recv(1)
end
return data
end
def recvTimeout
if select(10)==0
raise Hangup.new("Timeout")
end
return recv(1)
end
#--------------------------------------------------------------------------
# * Gets
#--------------------------------------------------------------------------
def gets
# Create buffer
message = ""
# Loop Until "end of line"
count=0
while true
x=select(0.05)
if x==0
count+=1
Graphics.update if count%10==0
raise Errno::ETIMEOUT if count>200
next
end
ch = recv(1)
break if ch == "\n"
message += ch
end
# Return recieved data
return message
end
#--------------------------------------------------------------------------
# * Writes data to socket.
#--------------------------------------------------------------------------
def write(data)
Win32API.new("msvcrt", "_write", "lpl", "l").call(@fd, data, 1)
end
end
#===============================================================================
# ** TCPSocket - Creates and manages TCP sockets.
#-------------------------------------------------------------------------------
# Author Ruby
# Version 1.8.1
#===============================================================================
#-------------------------------------------------------------------------------
# Begin SDK Enabled Check
#-------------------------------------------------------------------------------
class TCPSocket < Socket
#--------------------------------------------------------------------------
# * Creates a new socket and connects it to the given host and port.
#--------------------------------------------------------------------------
def self.open(*args)
socket = new(*args)
if block_given?
begin
yield socket
ensure
socket.close
end
end
nil
end
#--------------------------------------------------------------------------
# * Creates a new socket and connects it to the given host and port.
#--------------------------------------------------------------------------
def initialize(host, port)
super(AF_INET, SOCK_STREAM, IPPROTO_TCP)
connect(Socket.sockaddr_in(port, host))
end
end
#==============================================================================
# ** SocketError
#------------------------------------------------------------------------------
# Default exception class for sockets.
#==============================================================================
class SocketError < StandardError
ENOASSOCHOST = "getaddrinfo: no address associated with hostname."
def self.check
errno = Winsock.WSAGetLastError
#if not Network.testing? == 1
raise Errno.const_get(Errno.constants.detect { |c| Errno.const_get(c).new.errno == errno })
#else
# errno != 0 ? (Network.testresult(true)) : (Network.testresult(false))
#end
end
end
end # !Object.const_defined?(:Socket)
#############################
#
# HTTP utility functions
#
#############################
def pbPostData(url, postdata, filename=nil, depth=0)
if url[/^http:\/\/([^\/]+)(.*)$/]
host = $1
path = $2
path = "/" if path.length==0
userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14"
body = postdata.map { |key, value|
keyString = key.to_s
valueString = value.to_s
keyString.gsub!(/[^a-zA-Z0-9_\.\-]/n) { |s| sprintf('%%%02x', s[0]) }
valueString.gsub!(/[^a-zA-Z0-9_\.\-]/n) { |s| sprintf('%%%02x', s[0]) }
next "#{keyString}=#{valueString}"
}.join('&')
request = "POST #{path} HTTP/1.1\r\n"
request += "Host: #{host}\r\n"
request += "Proxy-Connection: Close\r\n"
request += "Content-Length: #{body.length}\r\n"
request += "Pragma: no-cache\r\n"
request += "User-Agent: #{userAgent}\r\n"
request += "Content-Type: application/x-www-form-urlencoded\r\n"
request += "\r\n"
request += body
return pbHttpRequest(host, request, filename, depth)
end
return ""
end
def pbDownloadData(url, filename = nil, authorization = nil, depth = 0, &block)
raise "Redirection level too deep" if depth > 10
if url[/^(([^:\/?#]+):(?=\/\/))?(\/\/)?((([^:]+)(?::([^@]+)?)?@)?([^@\/?#:]*)(?::(\d+)?)?)?([^?#]*)(\?([^#]*))?(#(.*))?/]
host = $8
path = $10
parameters = $11
port = $9 ? $9.to_i : 80
path = "/" if path.length == 0
userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.14) Gecko/2009082707 Firefox/3.0.14"
request = "GET #{path}#{parameters} HTTP/1.1\r\n"
request += "User-Agent: #{userAgent}\r\n"
request += "Pragma: no-cache\r\n"
request += "Host: #{host}\r\n"
request += "Proxy-Connection: Close\r\n"
request += "Authorization: #{authorization}\r\n" if authorization
request += "\r\n"
return pbHttpRequest(host, request, filename, depth, port, &block)
end
return ""
end
def pbHttpRequest(host, request, filename = nil, depth = 0, port = nil)
raise "Redirection level too deep" if depth>10
socket = ::TCPSocket.new(host, 80)
time = Time.now.to_i
begin
socket.send(request)
result = socket.gets
data = ""
# Get the HTTP result
if result[/^HTTP\/1\.[01] (\d+).*/]
errorcode = $1.to_i
raise "HTTP Error #{errorcode}" if errorcode>=400 && errorcode<500
headers = {}
# Get the response headers
while true
result = socket.gets.sub(/\r$/,"")
break if result==""
if result[/^([^:]+):\s*(.*)/]
headers[$1] = $2
end
end
length = -1
chunked = false
if headers["Content-Length"]
length = headers["Content-Length"].to_i
end
if headers["Transfer-Encoding"]=="chunked"
chunked = true
end
if headers["Location"] && errorcode>=300 && errorcode<400
socket.close rescue socket = nil
return pbDownloadData(headers["Location"],filename,nil,depth+1)
end
if chunked
# Chunked content
while true
lengthline = socket.gets.sub(/\r$/,"")
length = lengthline.to_i(16)
break if length==0
while Time.now.to_i-time>=5 || socket.select(10)==0
time = Time.now.to_i
Graphics.update
end
data += socket.recv(length)
socket.gets
end
elsif length==-1
# No content length specified
while true
break if socket.select(500)==0
while Time.now.to_i-time>=5 || socket.select(10)==0
time = Time.now.to_i
Graphics.update
end
data += socket.recv(1)
end
else
# Content length specified
while length>0
chunk = [length,4096].min
while Time.now.to_i-time>=5 || socket.select(10)==0
time = Time.now.to_i
Graphics.update
end
data += socket.recv(chunk)
length -= chunk
end
end
end
return data if !filename
File.open(filename,"wb") { |f| f.write(data) }
ensure
socket.close rescue socket = nil
end
return ""
end
def pbDownloadToString(url)
begin
data = pbDownloadData(url)
return data
rescue
return ""
end
end
def pbDownloadToFile(url, file)
begin
pbDownloadData(url,file)
rescue
end
end
def pbPostToString(url, postdata)
begin
data = pbPostData(url, postdata)
return data
rescue
return ""
end
end
def pbPostToFile(url, postdata, file)
begin
pbPostData(url, postdata,file)
rescue
end
end

View File

@@ -1,157 +0,0 @@
module Console
attr_reader :bufferHandle
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
FILE_SHARE_READ = 0x00000001
FILE_SHARE_WRITE = 0x00000002
CONSOLE_TEXTMODE_BUFFER = 0x00000001
def Console::AllocConsole
return @apiAllocConsole.call
end
def Console::CreateConsoleScreenBuffer(dwDesiredAccess,dwShareMode,dwFlags)
return @apiCreateConsoleScreenBuffer.call(dwDesiredAccess,dwShareMode,nil,dwFlags,nil)
end
def Console::WriteConsole(lpBuffer)
hFile = @bufferHandle
return if !hFile
return @apiWriteConsole.call(hFile,lpBuffer,lpBuffer.size,0,0)
end
def Console::ReadConsole(lpBuffer)
hFile = @bufferHandle
return @apiReadConsole.call(hFile,lpBuffer,lpBuffer.size,0,0)
end
def Console::SetConsoleActiveScreenBuffer(hScreenBuffer)
return @apiSetConsoleActiveScreenBuffer.call(hScreenBuffer)
end
def Console::SetConsoleScreenBufferSize(hScreenBuffer,x,y)
return @apiSetConsoleScreenBufferSize.call(hScreenBuffer,[x,y].pack("vv"))
end
def Console::SetConsoleTitle(title)
return @apiSetConsoleTitle.call(title)
end
def self.setup_console
return unless $DEBUG
@apiAllocConsole = Win32API.new("kernel32","AllocConsole","","l")
@apiCreateConsoleScreenBuffer = Win32API.new("kernel32","CreateConsoleScreenBuffer","nnpnp","l")
@apiSetConsoleActiveScreenBuffer = Win32API.new("kernel32","SetConsoleActiveScreenBuffer","l","s")
@apiWriteConsole = Win32API.new("kernel32","WriteConsole","lpnnn","S")
@apiReadConsole = Win32API.new("kernel32","ReadConsole","lpnnn","S")
@apiSetConsoleScreenBufferSize = Win32API.new("kernel32","SetConsoleScreenBufferSize","lp","S")
@apiSetConsoleTitle = Win32API.new("kernel32","SetConsoleTitle","p","s")
access = (GENERIC_READ | GENERIC_WRITE)
sharemode = (FILE_SHARE_READ | FILE_SHARE_WRITE)
AllocConsole()
@bufferHandle = CreateConsoleScreenBuffer(access,sharemode,CONSOLE_TEXTMODE_BUFFER)
f = File.open("Game.ini")
lines = f.readlines()
s = lines[3]
len = s.size
title = (s[6,len - 7])
SetConsoleScreenBufferSize(@bufferHandle,100,2000)
SetConsoleTitle("Debug Console -- #{title}")
echo "#{title} Output Window\n"
echo "-------------------------------\n"
echo "If you are seeing this window, you are running\n"
echo "#{title} in Debug Mode. This means\n"
echo "that you're either playing a Debug Version, or\n"
echo "you are playing from within RPG Maker XP.\n"
echo "\n"
echo "Closing this window will close the game. If \n"
echo "you want to get rid of this window, run the\n"
echo "program from the Shell, or download a Release\n"
echo "version.\n"
echo "\n"
echo "Gameplay will be paused while the console has\n"
echo "focus. To resume playing, switch to the Game\n"
echo "Window.\n"
echo "-------------------------------\n"
echo "Debug Output:\n"
echo "-------------------------------\n\n"
SetConsoleActiveScreenBuffer(@bufferHandle)
end
def self.readInput
length=20
buffer=0.chr*length
eventsread=0.chr*4
done=false
input=""
while !done
echo("waiting for input")
begin
@apiReadConsole.call(@bufferHandle,buffer,1,eventsread)
rescue Hangup
return
end
offset=0
events=eventsread.unpack("V")
echo("got input [eventsread #{events}")
events[0].length.times do
keyevent=buffer[offset,20]
keyevent=keyevent.unpack("vCvvvvV")
if keyevent[0]==1 && keyevent[1]>0
input+=keyevent[4].chr
if keyevent[4].chr=="\n"
done=true
break
end
end
offset+=20
end
end
return input
end
def self.readInput2
buffer=0.chr
done=false
input=""
eventsread=0.chr*4
while !done
if ReadConsole(buffer)==0
getlast = Win32API.new("kernel32","GetLastError","","n")
echo(sprintf("failed (%d)\r\n",getlast.call()))
break
end
events=eventsread.unpack("V")
if events[0]>0
echo("got input [eventsread #{events}][buffer #{buffer}]\r\n")
key=buffer[0,events[0]]
input+=key
if key=="\n"
break
end
Graphics.update
end
end
return input
end
def self.get_input
echo self.readInput2
end
end
module Kernel
def echo(string)
unless $DEBUG
return
end
Console::WriteConsole(string.is_a?(String) ? string : string.inspect)
end
def echoln(string)
echo(string)
echo("\r\n")
end
end

View File

@@ -5,14 +5,15 @@ class Reset < Exception
end end
def pbGetExceptionMessage(e,_script="") def pbGetExceptionMessage(e,_script="")
emessage = e.message emessage = e.message.dup
emessage.force_encoding(Encoding::UTF_8)
if e.is_a?(Hangup) if e.is_a?(Hangup)
emessage = "The script is taking too long. The game will restart." emessage = "The script is taking too long. The game will restart."
elsif e.is_a?(Errno::ENOENT) elsif e.is_a?(Errno::ENOENT)
filename = emessage.sub("No such file or directory - ", "") filename = emessage.sub("No such file or directory - ", "")
emessage = "File #{filename} not found." emessage = "File #{filename} not found."
end end
emessage.gsub!(/Section(\d+)/) { $RGSS_SCRIPTS[$1.to_i][1] } emessage.gsub!(/Section(\d+)/) { $RGSS_SCRIPTS[$1.to_i][1] } rescue nil
return emessage return emessage
end end
@@ -30,7 +31,7 @@ def pbPrintException(e)
maxlength = ($INTERNAL) ? 25 : 10 maxlength = ($INTERNAL) ? 25 : 10
e.backtrace[0,maxlength].each { |i| btrace += "#{i}\r\n" } e.backtrace[0,maxlength].each { |i| btrace += "#{i}\r\n" }
end end
btrace.gsub!(/Section(\d+)/) { $RGSS_SCRIPTS[$1.to_i][1] } btrace.gsub!(/Section(\d+)/) { $RGSS_SCRIPTS[$1.to_i][1] } rescue nil
message = "[Pokémon Essentials version #{Essentials::VERSION}]\r\n" message = "[Pokémon Essentials version #{Essentials::VERSION}]\r\n"
message += "#{Essentials::ERROR_TEXT}" # For third party scripts to add to message += "#{Essentials::ERROR_TEXT}" # For third party scripts to add to
message += "Exception: #{e.class}\r\n" message += "Exception: #{e.class}\r\n"
@@ -41,12 +42,22 @@ def pbPrintException(e)
errorlog = RTP.getSaveFileName("errorlog.txt") errorlog = RTP.getSaveFileName("errorlog.txt")
end end
File.open(errorlog,"ab") { |f| f.write(premessage); f.write(message) } File.open(errorlog,"ab") { |f| f.write(premessage); f.write(message) }
errorlogline = errorlog.sub("/", "\\") errorlogline = errorlog
errorlogline.sub!(Dir.pwd + "\\", "") errorlogline.sub!(Dir.pwd + "/", "")
errorlogline.sub!(pbGetUserName, "USERNAME") errorlogline.sub!(pbGetUserName, "USERNAME")
errorlogline = "\r\n" + errorlogline if errorlogline.length > 20 errorlogline = "\r\n" + errorlogline if errorlogline.length > 20
errorlogline.gsub!("/", "\\") errorlogline.gsub!("/", "\\") if System.platform[/Windows/]
print("#{message}\r\nThis exception was logged in #{errorlogline}.\r\nPress Ctrl+C to copy this message to the clipboard.")
print("#{message}\r\nThis exception was logged in #{errorlogline}.\r\nHold Ctrl after closing this message to copy it to the clipboard.")
# Give a ~500ms coyote time to start holding Control
(0.5 / (1.0 / Graphics.frame_rate)).ceil.times{
Graphics.update
Input.update
if Input.press?(Input::CTRL)
Input.clipboard = message
break
end
}
end end
def pbCriticalCode def pbCriticalCode

View File

@@ -122,7 +122,7 @@
module PluginManager module PluginManager
# Win32API MessageBox function for custom errors. # Win32API MessageBox function for custom errors.
MBOX = Win32API.new('user32', 'MessageBox', ['I','P','P','I'], 'I') # MBOX = Win32API.new('user32', 'MessageBox', ['I','P','P','I'], 'I')
# Holds all registered plugin data. # Holds all registered plugin data.
@@Plugins = {} @@Plugins = {}
@@ -307,7 +307,8 @@ module PluginManager
def self.error(msg) def self.error(msg)
Graphics.update Graphics.update
t = Thread.new do t = Thread.new do
MBOX.call(Win32API.pbFindRgssWindow, msg, "Plugin Error", 0x10) #MBOX.call(Win32API.pbFindRgssWindow, msg, "Plugin Error", 0x10)
p "Plugin Error:\n#{msg}"
Thread.exit Thread.exit
end end
while t.status while t.status

View File

@@ -1,3 +1,104 @@
#=======================================================================
# This module is a little fix that works around PC hardware limitations.
# Since Essentials isn't working with software rendering anymore, it now
# has to deal with the limits of the GPU. For the most part this is no
# big deal, but people do have some really big tilesets.
#
# The fix is simple enough: If your tileset is too big, a new
# bitmap will be constructed with all the excess pixels sent to the
# image's right side. This basically means that you now have a limit
# far higher than you should ever actually need.
#
# Hardware limit -> max tileset length:
# 1024px -> 4096px
# 2048px -> 16384px (enough to get the normal limit)
# 4096px -> 65536px (enough to load pretty much any tileset)
# 8192px -> 262144px
# 16384px -> 1048576px (what most people have at this point)
# ~Roza/Zoroark
#=======================================================================
module TileWrap
TILESET_WIDTH = 0x100
# Looks useless, but covers weird numbers given to mkxp.json or a funky driver
MAX_TEX_SIZE = (Bitmap.max_size / 1024) * 1024
MAX_TEX_SIZE_BOOSTED = MAX_TEX_SIZE**2/TILESET_WIDTH
def self.clamp(val, min, max)
val = max if val > max
val = min if val < min
return val
end
def self.wrapTileset(originalbmp)
width = originalbmp.width
height = originalbmp.height
if width == TILESET_WIDTH && originalbmp.mega?
columns = (height / MAX_TEX_SIZE.to_f).ceil
if columns * TILESET_WIDTH > MAX_TEX_SIZE
raise "Tilemap is too long!\n\nSIZE: #{originalbmp.height}px\nHARDWARE LIMIT: #{MAX_TEX_SIZE}px\nBOOSTED LIMIT: #{MAX_TEX_SIZE_BOOSTED}px"
end
bmp = Bitmap.new(TILESET_WIDTH*columns, MAX_TEX_SIZE)
remainder = height % MAX_TEX_SIZE
columns.times{|col|
srcrect = Rect.new(0, col * MAX_TEX_SIZE, width, (col + 1 == columns) ? remainder : MAX_TEX_SIZE)
bmp.blt(col*TILESET_WIDTH, 0, originalbmp, srcrect)
}
return bmp
end
return originalbmp
end
def self.getWrappedRect(src_rect)
ret = Rect.new(0,0,0,0)
col = (src_rect.y / MAX_TEX_SIZE.to_f).floor
ret.x = col * TILESET_WIDTH + clamp(src_rect.x,0,TILESET_WIDTH)
ret.y = src_rect.y % MAX_TEX_SIZE
ret.width = clamp(src_rect.width, 0, TILESET_WIDTH - src_rect.x)
ret.height = clamp(src_rect.height, 0, MAX_TEX_SIZE)
return ret
end
def self.blitWrappedPixels(destX, destY, dest, src, srcrect)
if (srcrect.y + srcrect.width < MAX_TEX_SIZE)
# Save the processing power
dest.blt(destX, destY, src, srcrect)
return
end
merge = (srcrect.y % MAX_TEX_SIZE) > ((srcrect.y + srcrect.height) % MAX_TEX_SIZE)
srcrect_mod = getWrappedRect(srcrect)
if !merge
dest.blt(destX, destY, src, srcrect_mod)
else
#FIXME won't work on heights longer than two columns, but nobody should need
# more than 32k pixels high at once anyway
side = {:a => MAX_TEX_SIZE - srcrect_mod.y, :b => srcrect_mod.height - (MAX_TEX_SIZE - srcrect_mod.y)}
dest.blt(destX, destY, src, Rect.new(srcrect_mod.x, srcrect_mod.y, srcrect_mod.width, side[:a]))
dest.blt(destX, destY + side[:a], src, Rect.new(srcrect_mod.x + TILESET_WIDTH, 0, srcrect_mod.width, side[:b]))
end
end
def self.stretchBlitWrappedPixels(destrect, dest, src, srcrect)
if (srcrect.y + srcrect.width < MAX_TEX_SIZE)
# Save the processing power
dest.stretch_blt(destrect, src, srcrect)
return
end
# Does a regular blit to a non-megasurface, then stretch_blts that to
# the destination. Yes it is slow
tmp = Bitmap.new(srcrect.width, srcrect.height)
blitWrappedPixels(0,0,tmp,src,srcrect)
dest.stretch_blt(destrect, tmp, Rect.new(0,0,srcrect.width,srcrect.height))
end
end
#=============================================================================== #===============================================================================
# #
#=============================================================================== #===============================================================================
@@ -126,6 +227,7 @@ class CustomTilemap
@firsttimeflash = true @firsttimeflash = true
@fullyrefreshed = false @fullyrefreshed = false
@fullyrefreshedautos = false @fullyrefreshedautos = false
@shouldWrap = false
end end
def dispose def dispose
@@ -212,7 +314,14 @@ class CustomTilemap
end end
def tileset=(value) def tileset=(value)
@tileset = value if value.mega?
@tileset = TileWrap::wrapTileset(value)
@shouldWrap = true
value.dispose
else
@tileset = value
@shouldWrap = false
end
@tilesetChanged = true @tilesetChanged = true
end end
@@ -348,14 +457,16 @@ class CustomTilemap
bitmap = Bitmap.new(@tileWidth,@tileHeight) bitmap = Bitmap.new(@tileWidth,@tileHeight)
rect = Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight, rect = Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
@tileSrcWidth,@tileSrcHeight) @tileSrcWidth,@tileSrcHeight)
bitmap.stretch_blt(Rect.new(0,0,@tileWidth,@tileHeight),@tileset,rect) TileWrap::stretchBlitWrappedPixels(Rect.new(0,0,@tileWidth,@tileHeight), bitmap, @tileset, rect)
@regularTileInfo[id] = bitmap @regularTileInfo[id] = bitmap
end end
sprite.bitmap = bitmap if sprite.bitmap!=bitmap sprite.bitmap = bitmap if sprite.bitmap!=bitmap
else else
sprite.bitmap = @tileset if sprite.bitmap!=@tileset sprite.bitmap = @tileset if sprite.bitmap!=@tileset
sprite.src_rect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight, rect = Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
@tileSrcWidth,@tileSrcHeight) @tileSrcWidth,@tileSrcHeight)
rect = TileWrap::getWrappedRect(rect) if @shouldWrap
sprite.src_rect = rect
end end
end end
@@ -641,9 +752,9 @@ class CustomTilemap
xpos = (x * twidth) - @oxLayer0 xpos = (x * twidth) - @oxLayer0
ypos = (y * theight) - @oyLayer0 ypos = (y * theight) - @oyLayer0
if @diffsizes if @diffsizes
bitmap.stretch_blt(Rect.new(xpos, ypos, twidth, theight), @tileset, temprect) TileWrap::stretchBlitWrappedPixels(Rect.new(xpos, ypos, twidth, theight), bitmap, @tileset, temprect)
else else
bitmap.blt(xpos, ypos, @tileset, temprect) TileWrap::blitWrappedPixels(xpos,ypos, bitmap, @tileset, temprect)
end end
else # Autotiles else # Autotiles
tilebitmap = @autotileInfo[id] tilebitmap = @autotileInfo[id]
@@ -693,9 +804,9 @@ class CustomTilemap
((id - 384) >> 3) * @tileSrcHeight, ((id - 384) >> 3) * @tileSrcHeight,
@tileSrcWidth, @tileSrcHeight) @tileSrcWidth, @tileSrcHeight)
if @diffsizes if @diffsizes
bitmap.stretch_blt(Rect.new(xpos, ypos, twidth, theight), @tileset, temprect) TileWrap::stretchBlitWrappedPixels(Rect.new(xpos, ypos, twidth, theight), bitmap, @tileset, temprect)
else else
bitmap.blt(xpos, ypos, @tileset, temprect) TileWrap::blitWrappedPixels(xpos,ypos, bitmap, @tileset, temprect)
end end
else # Autotiles else # Autotiles
tilebitmap = @autotileInfo[id] tilebitmap = @autotileInfo[id]
@@ -754,9 +865,9 @@ class CustomTilemap
((id - 384) >> 3) * @tileSrcHeight, ((id - 384) >> 3) * @tileSrcHeight,
@tileSrcWidth, @tileSrcHeight) @tileSrcWidth, @tileSrcHeight)
if @diffsizes if @diffsizes
bitmap.stretch_blt(Rect.new(xpos, ypos, twidth, theight), @tileset, tmprect) TileWrap::stretchBlitWrappedPixels(Rect.new(xpos, ypos, twidth, theight), bitmap, @tileset, tmprect)
else else
bitmap.blt(xpos, ypos, @tileset, tmprect) TileWrap::blitWrappedPixels(xpos,ypos, bitmap, @tileset, tmprect)
end end
else # Autotiles else # Autotiles
frames = @framecount[id / 48 - 1] frames = @framecount[id / 48 - 1]

View File

@@ -75,81 +75,6 @@ def pbBitmapName(x)
return (ret) ? ret : x return (ret) ? ret : x
end end
def getUnicodeString(addr)
return "" if addr==0
rtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
ret = ""
data = "xx"
index = (addr.is_a?(String)) ? 0 : addr
loop do
if addr.is_a?(String)
data = addr[index,2]
else
rtlMoveMemory_pi.call(data, index, 2)
end
codepoint = data.unpack("v")[0]
break if codepoint==0
index += 2
if codepoint<=0x7F
ret += codepoint.chr
elsif codepoint<=0x7FF
ret += (0xC0|((codepoint>>6)&0x1F)).chr
ret += (0x80|(codepoint &0x3F)).chr
elsif codepoint<=0xFFFF
ret += (0xE0|((codepoint>>12)&0x0F)).chr
ret += (0x80|((codepoint>>6)&0x3F)).chr
ret += (0x80|(codepoint &0x3F)).chr
elsif codepoint<=0x10FFFF
ret += (0xF0|((codepoint>>18)&0x07)).chr
ret += (0x80|((codepoint>>12)&0x3F)).chr
ret += (0x80|((codepoint>>6)&0x3F)).chr
ret += (0x80|(codepoint &0x3F)).chr
end
end
return ret
end
def getUnicodeStringFromAnsi(addr)
return "" if addr==0
rtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
ret = ""
data = "x"
index = (addr.is_a?(String)) ? 0 : addr
loop do
if addr.is_a?(String)
data = addr[index,1]
else
rtlMoveMemory_pi.call(data, index, 1)
end
index += 1
codepoint = data.unpack("C")[0]
break if codepoint==0 || !codepoint
break if codepoint==0
if codepoint<=0x7F
ret += codepoint.chr
else
ret += (0xC0|((codepoint>>6)&0x1F)).chr
ret += (0x80|(codepoint &0x3F)).chr
end
end
return ret
end
def getKnownFolder(guid)
packedGuid = guid.pack("VvvC*")
shGetKnownFolderPath = Win32API.new("shell32.dll","SHGetKnownFolderPath","pllp","i") rescue nil
coTaskMemFree = Win32API.new("ole32.dll","CoTaskMemFree","i","") rescue nil
return "" if !shGetKnownFolderPath || !coTaskMemFree
path = "\0"*4
ret = shGetKnownFolderPath.call(packedGuid,0,0,path)
path = path.unpack("V")[0]
ret = getUnicodeString(path)
coTaskMemFree.call(path)
return ret
end
module RTP module RTP
@rtpPaths = nil @rtpPaths = nil
@@ -202,121 +127,31 @@ module RTP
end end
end end
# Gets all RGSS search paths # Gets all RGSS search paths.
# This function basically does nothing now, because
# the passage of time and introduction of MKXP make
# it useless, but leaving it for compatibility
# reasons
def self.eachPath def self.eachPath
# XXX: Use "." instead of Dir.pwd because of problems retrieving files if # XXX: Use "." instead of Dir.pwd because of problems retrieving files if
# the current directory contains an accent mark # the current directory contains an accent mark
yield ".".gsub(/[\/\\]/,"/").gsub(/[\/\\]$/,"")+"/" yield ".".gsub(/[\/\\]/,"/").gsub(/[\/\\]$/,"")+"/"
if !@rtpPaths
tmp = Sprite.new
isRgss2 = tmp.respond_to?("wave_amp")
tmp.dispose
@rtpPaths = []
if isRgss2
rtp = getGameIniValue("Game","RTP")
if rtp!=""
rtp = MiniRegistry.get(MiniRegistry::HKEY_LOCAL_MACHINE,
"SOFTWARE\\Enterbrain\\RGSS2\\RTP",rtp,nil)
if rtp && safeIsDirectory?(rtp)
@rtpPaths.push(rtp.sub(/[\/\\]$/,"")+"/")
end
end
else
%w( RTP1 RTP2 RTP3 ).each { |v|
rtp = getGameIniValue("Game",v)
if rtp!=""
rtp = MiniRegistry.get(MiniRegistry::HKEY_LOCAL_MACHINE,
"SOFTWARE\\Enterbrain\\RGSS\\RTP",rtp,nil)
if rtp && safeIsDirectory?(rtp)
@rtpPaths.push(rtp.sub(/[\/\\]$/,"")+"/")
end
end
}
end
end
@rtpPaths.each { |x| yield x }
end end
private private
@@folder = nil
def self.getGameIniValue(section,key)
val = "\0"*256
gps = Win32API.new('kernel32', 'GetPrivateProfileString',%w(p p p p l p), 'l')
gps.call(section, key, "", val, 256, ".\\Game.ini")
val.delete!("\0")
return val
end
def self.isDirWritable(dir)
return false if !dir || dir==""
loop do
name = dir.gsub(/[\/\\]$/,"")+"/writetest"
12.times do
name += sprintf("%02X",rand(256))
end
name += ".tmp"
if !safeExists?(name)
retval = false
begin
File.open(name,"wb") { retval = true }
rescue Errno::EINVAL, Errno::EACCES, Errno::ENOENT
ensure
File.delete(name) rescue nil
end
return retval
end
end
end
def self.ensureGameDir(dir)
title = RTP.getGameIniValue("Game","Title")
title = "RGSS Game" if title==""
title = title.gsub(/[^\w ]/,"_")
newdir = dir.gsub(/[\/\\]$/,"")+"/"
# Convert to UTF-8 because of ANSI function
newdir += getUnicodeStringFromAnsi(title)
Dir.mkdir(newdir) rescue nil
ret = safeIsDirectory?(newdir) ? newdir : dir
return ret
end
def self.getSaveFileName(fileName) def self.getSaveFileName(fileName)
return getSaveFolder().gsub(/[\/\\]$/,"")+"/"+fileName File.join(getSaveFolder, fileName)
end end
def self.getSaveFolder def self.getSaveFolder
if !@@folder # MKXP makes sure that this folder has been created
# XXX: Use "." instead of Dir.pwd because of problems retrieving files if # once it starts. The location differs depending on
# the current directory contains an accent mark # the operating system:
pwd = "." # Windows: %APPDATA%
# Get the known folder path for saved games # Linux: $HOME/.local/share
savedGames = getKnownFolder([ # macOS (unsandboxed): $HOME/Library/Application Support
0x4c5c32ff,0xbb9d,0x43b0,0xb5,0xb4,0x2d,0x72,0xe5,0x4e,0xaa,0xa4]) System.data_directory
if savedGames && savedGames!="" && isDirWritable(savedGames)
pwd = ensureGameDir(savedGames)
end
if isDirWritable(pwd)
@@folder = pwd
else
appdata = ENV["LOCALAPPDATA"]
if isDirWritable(appdata)
appdata = ensureGameDir(appdata)
else
appdata = ENV["APPDATA"]
if isDirWritable(appdata)
appdata = ensureGameDir(appdata)
elsif isDirWritable(pwd)
appdata = pwd
else
appdata = "."
end
end
@@folder = appdata
end
end
return @@folder
end end
end end
@@ -339,6 +174,9 @@ end
# Used to determine whether a data file exists (rather than a graphics or # Used to determine whether a data file exists (rather than a graphics or
# audio file). Doesn't check RTP, but does check encrypted archives. # audio file). Doesn't check RTP, but does check encrypted archives.
# Note: pbGetFileChar checks anything added in MKXP's RTP setting,
# and matching mount points added through System.mount
def pbRgssExists?(filename) def pbRgssExists?(filename)
filename = canonicalize(filename) filename = canonicalize(filename)
if safeExists?("./Game.rgssad") || safeExists?("./Game.rgss2a") if safeExists?("./Game.rgssad") || safeExists?("./Game.rgss2a")
@@ -350,6 +188,9 @@ end
# Opens an IO, even if the file is in an encrypted archive. # Opens an IO, even if the file is in an encrypted archive.
# Doesn't check RTP for the file. # Doesn't check RTP for the file.
# Note: load_data checks anything added in MKXP's RTP setting,
# and matching mount points added through System.mount
def pbRgssOpen(file,mode=nil) def pbRgssOpen(file,mode=nil)
#File.open("debug.txt","ab") { |fw| fw.write([file,mode,Time.now.to_f].inspect+"\r\n") } #File.open("debug.txt","ab") { |fw| fw.write([file,mode,Time.now.to_f].inspect+"\r\n") }
if !safeExists?("./Game.rgssad") && !safeExists?("./Game.rgss2a") if !safeExists?("./Game.rgssad") && !safeExists?("./Game.rgss2a")
@@ -362,11 +203,7 @@ def pbRgssOpen(file,mode=nil)
end end
file = canonicalize(file) file = canonicalize(file)
Marshal.neverload = true Marshal.neverload = true
begin str = load_data(file, true)
str = load_data(file)
ensure
Marshal.neverload = false
end
if block_given? if block_given?
StringInput.open(str) { |f| yield f } StringInput.open(str) { |f| yield f }
return nil return nil
@@ -383,18 +220,15 @@ def pbGetFileChar(file)
return nil if !safeExists?(file) return nil if !safeExists?(file)
begin begin
File.open(file,"rb") { |f| return f.read(1) } # read one byte File.open(file,"rb") { |f| return f.read(1) } # read one byte
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR
return nil return nil
end end
end end
Marshal.neverload = true
str = nil str = nil
begin begin
str = load_data(file) str = load_data(file, true)
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR, RGSSError, MKXPError
str = nil str = nil
ensure
Marshal.neverload = false
end end
return str return str
end end
@@ -406,6 +240,9 @@ end
# Gets the contents of a file. Doesn't check RTP, but does check # Gets the contents of a file. Doesn't check RTP, but does check
# encrypted archives. # encrypted archives.
# Note: load_data will check anything added in MKXP's RTP setting,
# and matching mount points added through System.mount
def pbGetFileString(file) def pbGetFileString(file)
file = canonicalize(file) file = canonicalize(file)
if !(safeExists?("./Game.rgssad") || safeExists?("./Game.rgss2a")) if !(safeExists?("./Game.rgssad") || safeExists?("./Game.rgss2a"))
@@ -416,14 +253,11 @@ def pbGetFileString(file)
return nil return nil
end end
end end
Marshal.neverload = true
str = nil str = nil
begin begin
str = load_data(file) str = load_data(file, true)
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError, MKXPError
str = nil str = nil
ensure
Marshal.neverload = false
end end
return str return str
end end
@@ -433,77 +267,6 @@ end
#=============================================================================== #===============================================================================
# #
#=============================================================================== #===============================================================================
module MiniRegistry
HKEY_CLASSES_ROOT = 0x80000000
HKEY_CURRENT_USER = 0x80000001
HKEY_LOCAL_MACHINE = 0x80000002
HKEY_USERS = 0x80000003
FormatMessageA = Win32API.new("kernel32","FormatMessageA","LPLLPLP","L")
RegOpenKeyExA = Win32API.new("advapi32","RegOpenKeyExA","LPLLP","L")
RegCloseKey = Win32API.new("advapi32","RegCloseKey","L","L")
RegQueryValueExA = Win32API.new("advapi32","RegQueryValueExA","LPLPPP","L")
def self.open(hkey,subkey,bit64=false)
key = 0.chr*4
flag = bit64 ? 0x20119 : 0x20019
rg = RegOpenKeyExA.call(hkey, subkey, 0, flag, key)
return nil if rg!=0
key = key.unpack("V")[0]
if block_given?
begin
yield(key)
ensure
check(RegCloseKey.call(key))
end
else
return key
end
end
def self.close(hkey); check(RegCloseKey.call(hkey)) if hkey; end
def self.get(hkey,subkey,name,defaultValue=nil,bit64=false)
self.open(hkey,subkey,bit64) { |key|
return self.read(key,name) rescue defaultValue
}
return defaultValue
end
def self.read(hkey,name)
hkey = 0 if !hkey
type = 0.chr*4
size = 0.chr*4
check(RegQueryValueExA.call(hkey,name,0,type,0,size))
data = " "*size.unpack("V")[0]
check(RegQueryValueExA.call(hkey,name,0,type,data,size))
type = type.unpack("V")[0]
data = data[0,size.unpack("V")[0]]
case type
when 1 then return data.chop # REG_SZ
when 2 then return data.gsub(/%([^%]+)%/) { ENV[$1] || $& } # REG_EXPAND_SZ
when 3 then return data # REG_BINARY
when 4 then return data.unpack("V")[0] # REG_DWORD
when 5 then return data.unpack("V")[0] # REG_DWORD_BIG_ENDIAN
when 11 # REG_QWORD
data.unpack("VV")
return (data[1]<<32|data[0])
end
raise "Type #{type} not supported."
end
private
def self.check(code)
if code!=0
msg = "\0"*1024
len = FormatMessageA.call(0x1200, 0, code, 0, msg, 1024, 0)
raise msg[0, len].tr("\r", '').chomp
end
end
end
class StringInput class StringInput
include Enumerable include Enumerable
@@ -624,44 +387,3 @@ class StringInput
alias sysread read alias sysread read
end end
module ::Marshal
class << self
if !@oldloadAliased
alias oldload load
@oldloadAliased = true
end
@@neverload = false
def neverload
return @@neverload
end
def neverload=(value)
@@neverload = value
end
def load(port,*arg)
if @@neverload
if port.is_a?(IO)
return port.read
end
return port
end
oldpos = port.pos if port.is_a?(IO)
begin
oldload(port,*arg)
rescue
p [$!.class,$!.message,$!.backtrace]
if port.is_a?(IO)
port.pos = oldpos
return port.read
end
return port
end
end
end
end

View File

@@ -190,7 +190,7 @@ def pbEachIntlSection(file)
sectionname=nil sectionname=nil
lastsection=[] lastsection=[]
file.each_line { |line| file.each_line { |line|
if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF
line=line[3,line.length-3] line=line[3,line.length-3]
end end
if !line[/^\#/] && !line[/^\s*$/] if !line[/^\#/] && !line[/^\s*$/]

View File

@@ -1,34 +1,3 @@
def getPlayMusic
return MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
"SOFTWARE\\Enterbrain\\RGSS","PlayMusic",true)
end
def getPlaySound
return MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
"SOFTWARE\\Enterbrain\\RGSS","PlaySound",true)
end
class AudioContext
attr_reader :context
def initialize
init = Win32API.new("audio.dll", "AudioContextInitialize", '', 'l')
@context=init.call
end
def dispose
if @context!=0
init = Win32API.new("audio.dll", "AudioContextFree", 'l', '')
init.call(context)
@context=0
end
end
end
##################################### #####################################
# Needed because RGSS doesn't call at_exit procs on exit # Needed because RGSS doesn't call at_exit procs on exit
# Exit is not called when game is reset (using F12) # Exit is not called when game is reset (using F12)
@@ -45,315 +14,6 @@ def at_exit(&block)
$AtExitProcs.push(Proc.new(&block)) $AtExitProcs.push(Proc.new(&block))
end end
module AudioState
w32_LL = Win32API.new("kernel32.dll", "LoadLibrary", 'p', 'l') # :nodoc:
w32_FL = Win32API.new("kernel32.dll", "FreeLibrary", 'p', 'l')# :nodoc:
if safeExists?("audio.dll")
@handle = w32_LL.call("audio.dll")
at_exit { w32_FL.call(@handle) }
AudioContextIsActive = Win32API.new("audio.dll","AudioContextIsActive","l","l")# :nodoc:
AudioContextPlay = Win32API.new("audio.dll","AudioContextPlay","lpllll","")# :nodoc:
AudioContextStop = Win32API.new("audio.dll","AudioContextStop","l","")# :nodoc:
AudioContextFadeOut = Win32API.new("audio.dll","AudioContextFadeOut","ll","")# :nodoc:
AudioContextGetPosition = Win32API.new("audio.dll","AudioContextGetPosition","l","l")# :nodoc:
AudioContextFadeIn = Win32API.new("audio.dll","AudioContextFadeIn","ll","")# :nodoc:
AudioContextSetVolume = Win32API.new("audio.dll","AudioContextSetVolume","ll","")# :nodoc:
AudioContextSEPlay = Win32API.new("audio.dll","AudioContextSEPlay","lplll","")# :nodoc:
if !@MEContext
@MEContext=AudioContext.new
at_exit { @MEContext.dispose }
end
if !@BGMContext
@BGMContext=AudioContext.new
at_exit { @BGMContext.dispose }
end
if !@BGSContext
@BGSContext=AudioContext.new
at_exit { @BGSContext.dispose }
end
if !@SEContext
@SEContext=AudioContext.new
at_exit { @SEContext.dispose }
end
else
AudioContextIsActive = nil # :nodoc:
AudioContextPlay = nil # :nodoc:
AudioContextStop = nil # :nodoc:
AudioContextFadeOut = nil # :nodoc:
AudioContextGetPosition = nil # :nodoc:
AudioContextFadeIn = nil # :nodoc:
AudioContextSetVolume = nil # :nodoc:
AudioContextSEPlay = nil # :nodoc:
end
@channel = nil
@bgm = nil
@name = ""
@pitch = 100
@bgmVolume = 100.0
@meVolume = 100.0
@bgsVolume = 100.0
@seVolume = 100.0
def self.setWaitingBGM(bgm,volume,pitch,position)
@waitingBGM=[bgm,volume,pitch,position]
end
def self.bgmActive?
return !@BGMContext ? false : (AudioContextIsActive.call(@BGMContext.context)!=0)
end
def self.meActive?
return !@MEContext ? false : (AudioContextIsActive.call(@MEContext.context)!=0)
end
def self.waitingBGM; @waitingBGM; end
def self.context; @BGMContext ? @BGMContext.context : nil; end
def self.meContext; @MEContext ? @MEContext.context : nil; end
def self.bgsContext; @BGSContext ? @BGSContext.context : nil; end
def self.seContext; @SEContext ? @SEContext.context : nil; end
def self.system; @system; end
def self.bgm; @bgm; end
def self.name; @name; end
def self.pitch; @pitch; end
def self.volume; @volume; end
def self.waitingBGM=(value);
@waitingBGM = value
end
def self.volume=(value); @volume=value; end
def self.bgm=(value); @bgm=value; end
def self.name=(value); @name=value; end
def self.pitch=(value); @pitch=value; end
end
def Audio_bgm_playing?
AudioState.channel!=nil
end
def Audio_bgm_name
AudioState.name
end
def Audio_bgm_pitch
AudioState.pitch
end
def Audio_bgm_play(name, volume, pitch, position = 0)
volume=0 if !getPlayMusic
begin
filename = canonicalize(RTP.getAudioPath(name))
if AudioState.meActive?
AudioState.setWaitingBGM(filename,volume,pitch,position)
return
end
AudioState::AudioContextPlay.call(AudioState.context,filename,volume,pitch,position,1)
AudioState.name=filename
AudioState.volume=volume
AudioState.pitch=pitch
rescue Hangup
rescue
p $!.message,$!.backtrace
end
end
def Audio_bgm_fadein(ms)
AudioState::AudioContextFadeIn.call(AudioState.context,ms.to_i)
end
def Audio_bgm_fade(ms)
AudioState::AudioContextFadeOut.call(AudioState.context,ms.to_i)
end
def Audio_bgm_stop
begin
AudioState::AudioContextStop.call(AudioState.context)
AudioState.waitingBGM=nil
AudioState.name = ""
rescue
p $!.message,$!.backtrace
end
end
def Audio_bgm_get_position
return AudioState::AudioContextGetPosition.call(AudioState.context)
end
def Audio_bgm_get_volume
return 0 if !AudioState.bgmActive?
return AudioState.volume
end
def Audio_bgm_set_volume(volume)
return if !AudioState.bgmActive?
AudioState.volume = volume * 1.0
AudioState::AudioContextSetVolume.call(AudioState.context,volume.to_i)
end
def Audio_me_play(name, volume, pitch, position = 0)
volume=0 if !getPlayMusic
begin
filename = canonicalize(RTP.getAudioPath(name))
if AudioState.bgmActive?
bgmPosition=Audio_bgm_get_position
AudioState.setWaitingBGM(
AudioState.name,
AudioState.volume,
AudioState.pitch,
bgmPosition
)
AudioState::AudioContextStop.call(AudioState.context)
end
AudioState::AudioContextPlay.call(AudioState.meContext,filename,
volume,pitch,position,0)
rescue
p $!.message,$!.backtrace
end
end
def Audio_me_fade(ms)
AudioState::AudioContextFadeOut.call(AudioState.meContext,ms)
end
def Audio_me_stop
AudioState::AudioContextStop.call(AudioState.meContext)
end
def Audio_bgs_play(name, volume, pitch, position = 0)
volume=0 if !getPlaySound
begin
filename = canonicalize(RTP.getAudioPath(name))
AudioState::AudioContextPlay.call(AudioState.bgsContext,filename,
volume,pitch,position,0)
rescue
p $!.message,$!.backtrace
end
end
def Audio_bgs_fade(ms)
AudioState::AudioContextFadeOut.call(AudioState.bgsContext,ms)
end
def Audio_bgs_stop
AudioState::AudioContextStop.call(AudioState.bgsContext)
end
def Audio_se_play(name, volume, pitch, position = 0)
volume=0 if !getPlaySound
begin
filename = canonicalize(RTP.getAudioPath(name))
AudioState::AudioContextSEPlay.call(AudioState.seContext,filename,
volume,pitch,position)
rescue
p $!.message,$!.backtrace
end
end
def Audio_se_stop
AudioState::AudioContextStop.call(AudioState.seContext)
end
####################################################
if safeExists?("audio.dll")
module Graphics
if !defined?(audiomodule_update)
class << self
alias audiomodule_update update
end
end
def self.update
Audio.update
audiomodule_update
end
end
module Audio
@@musicstate = nil
@@soundstate = nil
def self.update
return if Graphics.frame_count%10!=0
if AudioState.waitingBGM && !AudioState.meActive?
waitbgm=AudioState.waitingBGM
AudioState.waitingBGM=nil
bgm_play(waitbgm[0],waitbgm[1],waitbgm[2],waitbgm[3])
end
end
def self.bgm_play(name,volume=80,pitch=100,position=nil)
begin
if position==nil || position==0
Audio_bgm_play(name,volume,pitch,0)
else
Audio_bgm_play(name,volume,pitch,position)
Audio_bgm_fadein(500)
end
rescue Hangup
bgm_play(name,volume,pitch,position)
end
end
def self.bgm_fade(ms)
Audio_bgm_fade(ms)
end
def self.bgm_stop
Audio_bgm_stop
end
def self.bgm_position
return Audio_bgm_get_position
end
def self.me_play(name,volume=80,pitch=100)
Audio_me_play(name,volume,pitch,0)
end
def self.me_fade(ms)
Audio_me_fade(ms)
end
def self.me_stop
Audio_me_stop
end
def self.bgs_play(name,volume=80,pitch=100)
Audio_bgs_play(name,volume,pitch,0)
end
def self.bgs_fade(ms)
Audio_bgs_fade(ms)
end
def self.bgs_stop
Audio_bgs_stop
end
=begin
def self.se_play(name,volume=80,pitch=100)
Audio_se_play(name,volume,pitch,0)
end
def self.se_stop
Audio_se_stop
end
=end
end
end # safeExists?("audio.dll")
#=============================================================================== #===============================================================================
# Methods that determine the duration of an audio file. # Methods that determine the duration of an audio file.
#=============================================================================== #===============================================================================

View File

@@ -1,3 +1,7 @@
# Disabling animated GIF stuff because gif.dll is awful,
# but leaving the code here just in case someone wants
# to make Linux and macOS versions of it for some reason
=begin
module GifLibrary module GifLibrary
@@loadlib = Win32API.new("Kernel32.dll","LoadLibrary",'p','') @@loadlib = Win32API.new("Kernel32.dll","LoadLibrary",'p','')
if safeExists?("gif.dll") if safeExists?("gif.dll")
@@ -22,6 +26,7 @@ module GifLibrary
return ret return ret
end end
end end
=end
@@ -201,12 +206,13 @@ class GifBitmap
end end
end end
end end
if bitmap && filestring && filestring[0]==0x47 && if bitmap && filestring && filestring[0].ord==0x47 &&
bitmap.width==32 && bitmap.height==32 bitmap.width==32 && bitmap.height==32
#File.open("debug.txt","ab") { |f| f.puts("rejecting bitmap") } #File.open("debug.txt","ab") { |f| f.puts("rejecting bitmap") }
bitmap.dispose bitmap.dispose
bitmap=nil bitmap=nil
end end
# Note: MKXP can open .gif files just fine, first frame only
if bitmap if bitmap
#File.open("debug.txt","ab") { |f| f.puts("reusing bitmap") } #File.open("debug.txt","ab") { |f| f.puts("reusing bitmap") }
# Have a regular non-animated bitmap # Have a regular non-animated bitmap
@@ -217,6 +223,7 @@ class GifBitmap
else else
tmpBase=File.basename(file)+"_tmp_" tmpBase=File.basename(file)+"_tmp_"
filestring=pbGetFileString(filestrName) if filestring filestring=pbGetFileString(filestrName) if filestring
=begin
Dir.chdir(ENV["TEMP"]) { # navigate to temp folder since game might be on a CD-ROM Dir.chdir(ENV["TEMP"]) { # navigate to temp folder since game might be on a CD-ROM
if filestring && filestring[0]==0x47 && GifLibrary::PngDll if filestring && filestring[0]==0x47 && GifLibrary::PngDll
result=GifLibrary::GifToPngFilesInMemory.call(filestring, result=GifLibrary::GifToPngFilesInMemory.call(filestring,
@@ -244,6 +251,7 @@ class GifBitmap
end end
end end
} }
=end
if @gifbitmaps.length==0 if @gifbitmaps.length==0
@gifbitmaps=[BitmapWrapper.new(32,32)] @gifbitmaps=[BitmapWrapper.new(32,32)]
@gifdelays=[1] @gifdelays=[1]

View File

@@ -40,7 +40,7 @@ class LargePlane < Plane
@__bitmap=nil @__bitmap=nil
@__disposed=true @__disposed=true
end end
super #super
end end
def ox; @__ox; end def ox; @__ox; end

View File

@@ -565,88 +565,39 @@ class Window_MultilineTextEntry < SpriteWindow_Base
self.refresh if ((@frame%10)==0) self.refresh if ((@frame%10)==0)
return if !self.active return if !self.active
# Moving cursor # Moving cursor
if Input.repeat?(Input::UP) if Input.triggerex?(:UP) || Input.repeatex?(:UP)
moveCursor(-1,0) moveCursor(-1,0)
return return
elsif Input.repeat?(Input::DOWN) elsif Input.triggerex?(:DOWN) || Input.repeatex?(:DOWN)
moveCursor(1,0) moveCursor(1,0)
return return
elsif Input.repeat?(Input::LEFT) elsif Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
moveCursor(0,-1) moveCursor(0,-1)
return return
elsif Input.repeat?(Input::RIGHT) elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT)
moveCursor(0,1) moveCursor(0,1)
return return
end end
if !@peekMessage if Input.press?(Input::CTRL) && Input.triggerex?(:HOME)
@peekMessage = Win32API.new("user32.dll","PeekMessage","pliii","i") rescue nil
end
if @peekMessage
msg=[0,0,0,0,0,0,0].pack("V*")
retval=@peekMessage.call(msg,0,0x102,0x102,1)
if retval!=0
p "WM_CHAR #{msg[2]}"
end
end
if Input.press?(Input::CTRL) && Input.trigger?(Input::HOME)
# Move cursor to beginning # Move cursor to beginning
@cursorLine=0 @cursorLine=0
@cursorColumn=0 @cursorColumn=0
updateCursorPos(true) updateCursorPos(true)
return return
elsif Input.press?(Input::CTRL) && Input.trigger?(Input::ENDKEY) elsif Input.press?(Input::CTRL) && Input.triggerex?(:END)
# Move cursor to end # Move cursor to end
@cursorLine=getTotalLines()-1 @cursorLine=getTotalLines()-1
@cursorColumn=getColumnsInLine(@cursorLine) @cursorColumn=getColumnsInLine(@cursorLine)
updateCursorPos(true) updateCursorPos(true)
return return
elsif Input.repeat?(Input::ENTER) elsif Input.triggerex?(:RETURN) || Input.repeatex?(:RETURN)
self.insert("\n") self.insert("\n")
return return
elsif Input.repeat?(Input::BACKSPACE) # Backspace elsif Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE) # Backspace
self.delete self.delete
return return
end end
# Letter keys Input.gets.each_char{|c|insert(c)}
for i in 65..90
if Input.repeatex?(i)
shift=(Input.press?(Input::SHIFT)) ? 0x41 : 0x61
insert((shift+i-65).chr)
return
end
end
# Number keys
shifted=")!@\#$%^&*("
unshifted="0123456789"
for i in 48..57
if Input.repeatex?(i)
insert((Input.press?(Input::SHIFT)) ? shifted[i-48].chr : unshifted[i-48].chr)
return
end
end
keys=[
[32," "," "],
[106,"*","*"],
[107,"+","+"],
[109,"-","-"],
[111,"/","/"],
[186,";",":"],
[187,"=","+"],
[188,",","<"],
[189,"-","_"],
[190,".",">"],
[191,"/","?"],
[219,"[","{"],
[220,"\\","|"],
[221,"]","}"],
[222,"'","\""]
]
for i in keys
if Input.repeatex?(i[0])
insert((Input.press?(Input::SHIFT)) ? i[2] : i[1])
return
end
end
end end
def refresh def refresh
@@ -719,97 +670,27 @@ class Window_TextEntry_Keyboard < Window_TextEntry
self.refresh if ((@frame%10)==0) self.refresh if ((@frame%10)==0)
return if !self.active return if !self.active
# Moving cursor # Moving cursor
if Input.repeat?(Input::LEFT) if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
if @helper.cursor > 0 if @helper.cursor > 0
@helper.cursor-=1 @helper.cursor-=1
@frame=0 @frame=0
self.refresh self.refresh
end end
return return
elsif Input.repeat?(Input::RIGHT) elsif Input.triggerex?(:LEFT) || Input.repeatex?(:RIGHT)
if @helper.cursor < self.text.scan(/./m).length if @helper.cursor < self.text.scan(/./m).length
@helper.cursor+=1 @helper.cursor+=1
@frame=0 @frame=0
self.refresh self.refresh
end end
return return
elsif Input.repeat?(Input::BACKSPACE) elsif Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE)
self.delete if @helper.cursor>0 self.delete if @helper.cursor>0
return return
elsif Input.trigger?(Input::ENTER) || Input.trigger?(Input::ESC) elsif Input.triggerex?(:RETURN) || Input.triggerex?(:ESCAPE)
return return
end end
if !@toUnicode Input.gets.each_char{|c|insert(c)}
@toUnicode = Win32API.new("user32.dll","ToUnicode","iippii","i") rescue nil
@mapVirtualKey = Win32API.new("user32.dll","MapVirtualKey","ii","i") rescue nil
@getKeyboardState = Win32API.new("user32.dll","GetKeyboardState","p","i") rescue nil
end
if @getKeyboardState
kbs = "\0"*256
@getKeyboardState.call(kbs)
kbcount = 0
for i in 3...256
next if !Input.triggerex?(i)
vsc = @mapVirtualKey.call(i,0)
buf = "\0"*8
ret = @toUnicode.call(i,vsc,kbs,buf,4,0)
next if ret<=0
b = buf.unpack("v*")
for j in 0...ret
if buf[j]<=0x7F
insert(buf[j].chr)
elsif buf[j]<=0x7FF
insert((0xC0|((buf[j]>>6)&0x1F)).chr+(0x80|(buf[j]&0x3F)).chr)
else
str = (0xE0|((buf[j]>>12)&0x0F)).chr
str += (0x80|((buf[j]>>6)&0x3F)).chr
str += (0x80|(buf[j]&0x3F)).chr
insert(str)
end
kbcount += 1
end
end
return if kbcount>0
end
# Letter keys
for i in 65..90
if Input.repeatex?(i)
shift=(Input.press?(Input::SHIFT)) ? 0x41 : 0x61
insert((shift+i-65).chr)
return
end
end
# Number keys
shifted = ")!@\#$%^&*("
unshifted = "0123456789"
for i in 48..57
if Input.repeatex?(i)
insert((Input.press?(Input::SHIFT)) ? shifted[i-48].chr : unshifted[i-48].chr)
return
end
end
keys = [
[32," "," "],
[106,"*","*"],
[107,"+","+"],
[109,"-","-"],
[111,"/","/"],
[186,";",":"],
[187,"=","+"],
[188,",","<"],
[189,"-","_"],
[190,".",">"],
[191,"/","?"],
[219,"[","{"],
[221,"]","}"],
[222,"'","\""]
]
for i in keys
if Input.repeatex?(i[0])
insert((Input.press?(Input::SHIFT)) ? i[2] : i[1])
return
end
end
end end
end end
@@ -832,7 +713,7 @@ class PokemonEntryScene
if USEKEYBOARD if USEKEYBOARD
@sprites["entry"]=Window_TextEntry_Keyboard.new(initialText, @sprites["entry"]=Window_TextEntry_Keyboard.new(initialText,
0,0,400-112,96,helptext,true) 0,0,400-112,96,helptext,true)
$fullInputUpdate = true Input.text_input = true
else else
@sprites["entry"]=Window_TextEntry.new(initialText,0,0,400,96,helptext,true) @sprites["entry"]=Window_TextEntry.new(initialText,0,0,400,96,helptext,true)
end end
@@ -932,10 +813,10 @@ class PokemonEntryScene
loop do loop do
Graphics.update Graphics.update
Input.update Input.update
if Input.trigger?(Input::ESC) && @minlength==0 if Input.triggerex?(:ESCAPE) && @minlength==0
ret="" ret=""
break break
elsif Input.trigger?(Input::ENTER) && @sprites["entry"].text.length>=@minlength elsif Input.triggerex?(:RETURN) && @sprites["entry"].text.length>=@minlength
ret=@sprites["entry"].text ret=@sprites["entry"].text
break break
end end
@@ -997,10 +878,10 @@ class PokemonEntryScene
end end
def pbEndScene def pbEndScene
$fullInputUpdate = false
pbFadeOutAndHide(@sprites) pbFadeOutAndHide(@sprites)
pbDisposeSpriteHash(@sprites) pbDisposeSpriteHash(@sprites)
@viewport.dispose @viewport.dispose
Input.text_input = false if USEKEYBOARD
end end
end end
@@ -1553,14 +1434,14 @@ def pbFreeText(msgwindow,currenttext,passwordbox,maxlength,width=240)
pbPositionNearMsgWindow(window,msgwindow,:right) pbPositionNearMsgWindow(window,msgwindow,:right)
window.text=currenttext window.text=currenttext
window.passwordChar="*" if passwordbox window.passwordChar="*" if passwordbox
$fullInputUpdate = true Input.text_input = true
loop do loop do
Graphics.update Graphics.update
Input.update Input.update
if Input.trigger?(Input::ESC) if Input.triggerex?(:ESCAPE)
ret=currenttext ret=currenttext
break break
elsif Input.trigger?(Input::ENTER) elsif Input.triggerex?(:RETURN)
ret=window.text ret=window.text
break break
end end
@@ -1568,7 +1449,7 @@ def pbFreeText(msgwindow,currenttext,passwordbox,maxlength,width=240)
msgwindow.update if msgwindow msgwindow.update if msgwindow
yield if block_given? yield if block_given?
end end
$fullInputUpdate = false Input.text_input = false
window.dispose window.dispose
Input.update Input.update
return ret return ret

View File

@@ -1,52 +0,0 @@
#===============================================================================
# ** Scene_Movie class, created by SoundSpawn, fixed by Popper.
#-------------------------------------------------------------------------------
# Instruction
# 1) Movies must be in a new folder called "Movies" in your directory.
# 2) If you call this script from an event, e.g.
# Call Script: $scene = Scene_Movie.new("INTRO")
# 3) Have fun playing movies with this script!
#===============================================================================
class Scene_Movie
def initialize(movie)
@movie_name = RTP.getPath("Movies\\"+movie+".avi").gsub(/\//,"\\")
end
def main
@temp = Win32API.pbFindRgssWindow.to_s
movie = Win32API.new('winmm','mciSendString','%w(p,p,l,l)','V')
movie.call("open \""+@movie_name+
"\" alias FILE style 1073741824 parent " + @temp.to_s,0,0,0)
@message = Win32API.new('user32','SendMessage','%w(l,l,l,l)','V')
@detector = Win32API.new('user32','GetSystemMetrics','%w(l)','L')
@width = @detector.call(0)
if @width == 640
#fullscreen
Graphics.update
sleep(0.1)
Graphics.update
sleep(0.1)
Graphics.update
sleep(0.1)
#fullscreen
end
status = " " * 255
movie.call("play FILE",0,0,0)
loop do
sleep(0.1)
@message.call(@temp.to_i,11,0,0)
Graphics.update
@message.call(@temp.to_i,11,1,0)
Input.update
movie.call("status FILE mode",status,255,0)
true_status = status.unpack("aaaa")
break if true_status.to_s != "play"
if Input.trigger?(Input::B)
movie.call("close FILE",0,0,0)
$scene = Scene_Map.new
break
end
end
$scene = Scene_Map.new
end
end

View File

@@ -211,23 +211,14 @@ end
def pbBatteryLow? def pbBatteryLow?
power="\0"*12 pstate = System.power_state
begin # If it's not discharging, it doesn't matter if it's low
sps=Win32API.new('kernel32.dll','GetSystemPowerStatus','p','l') return false if !pstate[:discharging]
rescue # Check for less than 10m, priority over the percentage
return false # Some laptops (Chromebooks, Macbooks) have very long lifetimes
end return true if pstate[:seconds] && pstate[:seconds] <= 600
if sps.call(power)==1 # Check for <=15%
status=power.unpack("CCCCVV") return true if pstate[:percent] && pstate[:percent] <= 15
# AC line presence
return false if status[0]!=0 # Not plugged in or unknown
# Battery Flag
return true if status[1]==4 # Critical (<5%)
# Battery Life Percent
return true if status[2]<3 # Less than 3 percent
# Battery Life Time
return true if status[4]>0 && status[4]<300 # Less than 5 minutes and unplugged
end
return false return false
end end

View File

@@ -482,7 +482,7 @@ class PokemonPokedex_Scene
wt1 = (params[6]<0) ? 0 : (params[6]>=@weightCommands.length) ? 9999 : @weightCommands[params[6]] wt1 = (params[6]<0) ? 0 : (params[6]>=@weightCommands.length) ? 9999 : @weightCommands[params[6]]
wt2 = (params[7]<0) ? 9999 : (params[7]>=@weightCommands.length) ? 0 : @weightCommands[params[7]] wt2 = (params[7]<0) ? 9999 : (params[7]>=@weightCommands.length) ? 0 : @weightCommands[params[7]]
hwoffset = false hwoffset = false
if pbGetCountry==0xF4 # If the user is in the United States if System.user_language[3..4]=="US" # If the user is in the United States
ht1 = (params[4]>=@heightCommands.length) ? 99*12 : (ht1/0.254).round ht1 = (params[4]>=@heightCommands.length) ? 99*12 : (ht1/0.254).round
ht2 = (params[5]<0) ? 99*12 : (ht2/0.254).round ht2 = (params[5]<0) ? 99*12 : (ht2/0.254).round
wt1 = (params[6]>=@weightCommands.length) ? 99990 : (wt1/0.254).round wt1 = (params[6]>=@weightCommands.length) ? 99990 : (wt1/0.254).round
@@ -571,7 +571,7 @@ class PokemonPokedex_Scene
ht1 = (sel[0]<0) ? 0 : (sel[0]>=@heightCommands.length) ? 999 : @heightCommands[sel[0]] ht1 = (sel[0]<0) ? 0 : (sel[0]>=@heightCommands.length) ? 999 : @heightCommands[sel[0]]
ht2 = (sel[1]<0) ? 999 : (sel[1]>=@heightCommands.length) ? 0 : @heightCommands[sel[1]] ht2 = (sel[1]<0) ? 999 : (sel[1]>=@heightCommands.length) ? 0 : @heightCommands[sel[1]]
hwoffset = false hwoffset = false
if pbGetCountry==0xF4 # If the user is in the United States if System.user_language[3..4]=="US" # If the user is in the United States
ht1 = (sel[0]>=@heightCommands.length) ? 99*12 : (ht1/0.254).round ht1 = (sel[0]>=@heightCommands.length) ? 99*12 : (ht1/0.254).round
ht2 = (sel[1]<0) ? 99*12 : (ht2/0.254).round ht2 = (sel[1]<0) ? 99*12 : (ht2/0.254).round
txt1 = sprintf("%d'%02d''",ht1/12,ht1%12) txt1 = sprintf("%d'%02d''",ht1/12,ht1%12)
@@ -588,7 +588,7 @@ class PokemonPokedex_Scene
wt1 = (sel[0]<0) ? 0 : (sel[0]>=@weightCommands.length) ? 9999 : @weightCommands[sel[0]] wt1 = (sel[0]<0) ? 0 : (sel[0]>=@weightCommands.length) ? 9999 : @weightCommands[sel[0]]
wt2 = (sel[1]<0) ? 9999 : (sel[1]>=@weightCommands.length) ? 0 : @weightCommands[sel[1]] wt2 = (sel[1]<0) ? 9999 : (sel[1]>=@weightCommands.length) ? 0 : @weightCommands[sel[1]]
hwoffset = false hwoffset = false
if pbGetCountry==0xF4 # If the user is in the United States if System.user_language[3..4]=="US" # If the user is in the United States
wt1 = (sel[0]>=@weightCommands.length) ? 99990 : (wt1/0.254).round wt1 = (sel[0]>=@weightCommands.length) ? 99990 : (wt1/0.254).round
wt2 = (sel[1]<0) ? 99990 : (wt2/0.254).round wt2 = (sel[1]<0) ? 99990 : (wt2/0.254).round
txt1 = sprintf("%.1f",wt1/10.0) txt1 = sprintf("%.1f",wt1/10.0)

View File

@@ -1,294 +1,9 @@
def pbSameThread(wnd)
return false if wnd==0
processid = [0].pack('l')
getCurrentThreadId = Win32API.new('kernel32','GetCurrentThreadId', '%w()','l')
getWindowThreadProcessId = Win32API.new('user32','GetWindowThreadProcessId', '%w(l p)','l')
threadid = getCurrentThreadId.call
wndthreadid = getWindowThreadProcessId.call(wnd,processid)
return (wndthreadid==threadid)
end
module Input
DOWN = 2
LEFT = 4
RIGHT = 6
UP = 8
TAB = 9
A = 11
B = 12
C = 13
X = 14
Y = 15
Z = 16
L = 17
R = 18
ENTER = 19
ESC = 20
SHIFT = 21
CTRL = 22
ALT = 23
BACKSPACE = 24
DELETE = 25
HOME = 26
ENDKEY = 27
F5 = F = 28
ONLYF5 = 29
F6 = 30
F7 = 31
F8 = 32
F9 = 33
LeftMouseKey = 1
RightMouseKey = 2
# GetAsyncKeyState or GetKeyState will work here
@GetKeyState = Win32API.new("user32","GetAsyncKeyState","i","i")
@GetForegroundWindow = Win32API.new("user32","GetForegroundWindow","","i")
# All key states to check
CheckKeyStates = [0x01,0x02,0x08,0x09,0x0D,0x10,0x11,0x12,0x1B,0x20,0x21,0x22,
0x23,0x24,0x25,0x26,0x27,0x28,0x2E,0x30,0x31,0x32,0x33,0x34,
0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,
0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x6A,0x6B,0x6D,0x6F,0x74,
0x75,0x76,0x77,0x78,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xDB,0xDC,
0xDD,0xDE] # 74 in total
# Returns whether a key is being pressed
def self.getstate(key)
return (@GetKeyState.call(key)&0x8000)>0
end
def self.updateKeyState(i)
gfw = pbSameThread(@GetForegroundWindow.call())
if !@stateUpdated[i]
newstate = self.getstate(i) && gfw
@keystate[i] = 0 if !@keystate[i]
@triggerstate[i] = (newstate && @keystate[i]==0)
@releasestate[i] = (!newstate && @keystate[i]>0)
@keystate[i] = (newstate) ? @keystate[i]+1 : 0
@stateUpdated[i] = true
end
end
def self.update
# $fullInputUpdate is true during keyboard text entry
toCheck = ($fullInputUpdate) ? 0...256 : CheckKeyStates
if @keystate
for i in toCheck
# just noting that the state should be updated
# instead of thunking to Win32 256 times
@stateUpdated[i] = false
# If there is a repeat count, update anyway
# (will normally apply only to a very few keys)
updateKeyState(i) if !@keystate[i] || @keystate[i]>0
end
else
@stateUpdated = []
@keystate = []
@triggerstate = []
@releasestate = []
for i in toCheck
@stateUpdated[i] = true
@keystate[i] = (self.getstate(i)) ? 1 : 0
@triggerstate[i] = false
@releasestate[i] = false
end
end
end
def self.buttonToKey(button)
case button
when Input::DOWN then return [0x28] # Down
when Input::LEFT then return [0x25] # Left
when Input::RIGHT then return [0x27] # Right
when Input::UP then return [0x26] # Up
when Input::TAB then return [0x09] # Tab
when Input::A then return [0x5A, 0x57, 0x59, 0x10] # Z, W, Y, Shift
when Input::B then return [0x58, 0x1B] # X, ESC
when Input::C then return [0x43, 0x0D, 0x20] # C, ENTER, Space
# when Input::X then return [0x41] # A
# when Input::Y then return [0x53] # S
# when Input::Z then return [0x44] # D
when Input::L then return [0x41, 0x51, 0x21] # A, Q, Page Up
when Input::R then return [0x53, 0x22] # S, Page Down
when Input::ENTER then return [0x0D] # ENTER
when Input::ESC then return [0x1B] # ESC
when Input::SHIFT then return [0x10] # Shift
when Input::CTRL then return [0x11] # Ctrl
when Input::ALT then return [0x12] # Alt
when Input::BACKSPACE then return [0x08] # Backspace
when Input::DELETE then return [0x2E] # Delete
when Input::HOME then return [0x24] # Home
when Input::ENDKEY then return [0x23] # End
when Input::F5 then return [0x46, 0x74, 0x09] # F, F5, Tab
when Input::ONLYF5 then return [0x74] # F5
when Input::F6 then return [0x75] # F6
when Input::F7 then return [0x76] # F7
when Input::F8 then return [0x77] # F8
when Input::F9 then return [0x78] # F9
end
return []
end
def self.dir4
button = 0
repeatcount = 0
return 0 if self.press?(Input::DOWN) && self.press?(Input::UP)
return 0 if self.press?(Input::LEFT) && self.press?(Input::RIGHT)
for b in [Input::DOWN,Input::LEFT,Input::RIGHT,Input::UP]
rc = self.count(b)
if rc>0 && (repeatcount==0 || rc<repeatcount)
button = b
repeatcount = rc
end
end
return button
end
def self.dir8
buttons = []
for b in [Input::DOWN,Input::LEFT,Input::RIGHT,Input::UP]
rc = self.count(b)
buttons.push([b,rc]) if rc>0
end
if buttons.length==0
return 0
elsif buttons.length==1
return buttons[0][0]
elsif buttons.length==2
# since buttons sorted by button, no need to sort here
return 0 if (buttons[0][0]==Input::DOWN && buttons[1][0]==Input::UP)
return 0 if (buttons[0][0]==Input::LEFT && buttons[1][0]==Input::RIGHT)
end
buttons.sort! { |a,b| a[1]<=>b[1] }
updown = 0
leftright = 0
for b in buttons
updown = b[0] if updown==0 && (b[0]==Input::UP || b[0]==Input::DOWN)
leftright = b[0] if leftright==0 && (b[0]==Input::LEFT || b[0]==Input::RIGHT)
end
if updown==Input::DOWN
return 1 if leftright==Input::LEFT
return 3 if leftright==Input::RIGHT
return 2
elsif updown==Input::UP
return 7 if leftright==Input::LEFT
return 9 if leftright==Input::RIGHT
return 8
else
return 4 if leftright==Input::LEFT
return 6 if leftright==Input::RIGHT
return 0
end
end
def self.count(button)
for btn in self.buttonToKey(button)
c = self.repeatcount(btn)
return c if c>0
end
return 0
end
def self.release?(button)
rc = 0
for btn in self.buttonToKey(button)
c = self.repeatcount(btn)
return false if c>0
rc += 1 if self.releaseex?(btn)
end
return rc>0
end
def self.trigger?(button)
return self.buttonToKey(button).any? { |item| self.triggerex?(item) }
end
def self.repeat?(button)
return self.buttonToKey(button).any? { |item| self.repeatex?(item) }
end
def self.press?(button)
return self.count(button)>0
end
def self.triggerex?(key)
return false if !@triggerstate
updateKeyState(key)
return @triggerstate[key]
end
def self.repeatex?(key)
return false if !@keystate
updateKeyState(key)
return @keystate[key]==1 || (@keystate[key]>Graphics.frame_rate/2 && (@keystate[key]&1)==0)
end
def self.releaseex?(key)
return false if !@releasestate
updateKeyState(key)
return @releasestate[key]
end
def self.repeatcount(key)
return 0 if !@keystate
updateKeyState(key)
return @keystate[key]
end
def self.pressex?(key)
return self.repeatcount(key)>0
end
end
# Requires Win32API
module Mouse module Mouse
gsm = Win32API.new('user32','GetSystemMetrics','i','i')
@GetCursorPos = Win32API.new('user32','GetCursorPos','p','i')
@SetCapture = Win32API.new('user32','SetCapture','p','i')
@ReleaseCapture = Win32API.new('user32','ReleaseCapture','','i')
module_function module_function
def screen_to_client(x, y)
return nil unless x and y
screenToClient = Win32API.new('user32','ScreenToClient',%w(l p),'i')
pos = [x, y].pack('ll')
return pos.unpack('ll') if screenToClient.call(Win32API.pbFindRgssWindow,pos)!=0
return nil
end
def getMouseGlobalPos
pos = [0, 0].pack('ll')
return (@GetCursorPos.call(pos)!=0) ? pos.unpack('ll') : [nil,nil]
end
# Returns the position of the mouse relative to the game window. # Returns the position of the mouse relative to the game window.
def getMousePos(catch_anywhere=false) def getMousePos(catch_anywhere=false)
x, y = screen_to_client(*getMouseGlobalPos) return nil unless System.mouse_in_window || catch_anywhere
return nil unless x and y return Input.mouse_x, Input.mouse_y
width, height = Win32API.client_size
if catch_anywhere or (x>=0 and y>=0 and x<width and y<height)
return x, y
end
return nil
end end
# Unused
def setCapture
@SetCapture.call(Win32API.pbFindRgssWindow)
end
# Unused
def releaseCapture
@ReleaseCapture.call
end
# Unused
def del
return if @oldcursor==nil
@SetClassLong.call(Win32API.pbFindRgssWindow,-12,@oldcursor)
@oldcursor = nil
end
end end

View File

@@ -48,35 +48,16 @@ def pbEachCombination(array,num)
end while _pbNextComb(currentComb,array.length) end while _pbNextComb(currentComb,array.length)
end end
# Returns a country ID
# http://msdn.microsoft.com/en-us/library/dd374073%28VS.85%29.aspx?
def pbGetCountry()
getUserGeoID = Win32API.new("kernel32","GetUserGeoID","l","i") rescue nil
return getUserGeoID.call(16) if getUserGeoID
return 0
end
# Returns a language ID # Returns a language ID
def pbGetLanguage() def pbGetLanguage()
getUserDefaultLangID = Win32API.new("kernel32","GetUserDefaultLangID","","i") rescue nil case System.user_language[0..1]
ret = 0 when "ja" then return 1 # Japanese
ret = getUserDefaultLangID.call()&0x3FF if getUserDefaultLangID when "en" then return 2 # English
if ret==0 # Unknown when "fr" then return 3 # French
ret = MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER, when "it" then return 4 # Italian
"Control Panel\\Desktop\\ResourceLocale","",0) when "de" then return 5 # German
ret = MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER, when "es" then return 7 # Spanish
"Control Panel\\International","Locale","0").to_i(16) if ret==0 when "ko" then return 8 # Korean
ret = ret&0x3FF
return 0 if ret==0 # Unknown
end
case ret
when 0x11 then return 1 # Japanese
when 0x09 then return 2 # English
when 0x0C then return 3 # French
when 0x10 then return 4 # Italian
when 0x07 then return 5 # German
when 0x0A then return 7 # Spanish
when 0x12 then return 8 # Korean
end end
return 2 # Use 'English' by default return 2 # Use 'English' by default
end end
@@ -131,7 +112,7 @@ end
def getConstantName(mod,value) def getConstantName(mod,value)
mod = Object.const_get(mod) if mod.is_a?(Symbol) mod = Object.const_get(mod) if mod.is_a?(Symbol)
for c in mod.constants for c in mod.constants
return c if mod.const_get(c.to_sym)==value return c if mod.const_get(c.to_sym).to_s==value
end end
raise _INTL("Value {1} not defined by a constant in {2}",value,mod.name) raise _INTL("Value {1} not defined by a constant in {2}",value,mod.name)
end end
@@ -139,7 +120,7 @@ end
def getConstantNameOrValue(mod,value) def getConstantNameOrValue(mod,value)
mod = Object.const_get(mod) if mod.is_a?(Symbol) mod = Object.const_get(mod) if mod.is_a?(Symbol)
for c in mod.constants for c in mod.constants
return c if mod.const_get(c.to_sym)==value return c if mod.const_get(c.to_sym).to_s==value
end end
return value.inspect return value.inspect
end end
@@ -276,28 +257,13 @@ def pbSuggestTrainerName(gender)
userName[0,1] = userName[0,1].upcase userName[0,1] = userName[0,1].upcase
return userName return userName
end end
owner = MiniRegistry.get(MiniRegistry::HKEY_LOCAL_MACHINE, return System.user_name.capitalize
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOwner","") # Unreachable
owner = owner.gsub(/\s+.*$/,"") #return getRandomNameEx(gender, nil, 1, Settings::MAX_PLAYER_NAME_SIZE)
if owner.length>0 && owner.length<7
owner[0,1] = owner[0,1].upcase
return owner
end
return getRandomNameEx(gender, nil, 1, Settings::MAX_PLAYER_NAME_SIZE)
end end
def pbGetUserName def pbGetUserName
buffersize = 100 return System.user_name
getUserName=Win32API.new('advapi32.dll','GetUserName','pp','i')
10.times do
size = [buffersize].pack("V")
buffer = "\0"*buffersize
if getUserName.call(buffer,size)!=0
return buffer.gsub(/\0/,"")
end
buffersize += 200
end
return ""
end end
def getRandomNameEx(type,variable,upper,maxLength=100) def getRandomNameEx(type,variable,upper,maxLength=100)

View File

@@ -141,7 +141,7 @@ def pbTrackPopupMenu(commands)
menuwindow.update menuwindow.update
hit=menuwindow.hittest hit=menuwindow.hittest
menuwindow.index=hit if hit>=0 menuwindow.index=hit if hit>=0
if Input.triggerex?(Input::LeftMouseKey) || Input.triggerex?(Input::RightMouseKey) # Left or right button if Input.trigger?(Input::MOUSELEFT) || Input.trigger?(Input::MOUSELEFT) # Left or right button
menuwindow.dispose menuwindow.dispose
return hit return hit
end end
@@ -251,7 +251,7 @@ class AnimationWindow < SpriteWrapper
def update def update
mousepos=Mouse::getMousePos mousepos=Mouse::getMousePos
@changed=false @changed=false
return if !Input.repeatex?(Input::LeftMouseKey) return if !Input.repeat?(Input::MOUSELEFT)
return if !mousepos return if !mousepos
return if !self.animbitmap return if !self.animbitmap
arrowwidth=@arrows.bitmap.width/2 arrowwidth=@arrows.bitmap.width/2
@@ -276,7 +276,7 @@ class AnimationWindow < SpriteWrapper
end end
# Left arrow # Left arrow
if left.contains(mousepos[0],mousepos[1]) if left.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>30 if Input.count(Input::MOUSELEFT)>30
@start-=3 @start-=3
else else
@start-=1 @start-=1
@@ -286,7 +286,7 @@ class AnimationWindow < SpriteWrapper
end end
# Right arrow # Right arrow
if right.contains(mousepos[0],mousepos[1]) if right.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>30 if Input.count(Input::MOUSELEFT)>30
@start+=3 @start+=3
else else
@start+=1 @start+=1
@@ -800,7 +800,7 @@ class AnimationCanvas < Sprite
cel=currentCel cel=currentCel
mousepos=Mouse::getMousePos mousepos=Mouse::getMousePos
if mousepos && pbSpriteHitTest(self,mousepos[0],mousepos[1],false,true) if mousepos && pbSpriteHitTest(self,mousepos[0],mousepos[1],false,true)
if Input.triggerex?(Input::LeftMouseKey) # Left mouse button if Input.trigger?(Input::MOUSELEFT) # Left mouse button
selectedcel=-1 selectedcel=-1
usealpha=(Input.press?(Input::ALT)) ? true : false usealpha=(Input.press?(Input::ALT)) ? true : false
for j in 0...PBAnimation::MAX_SPRITES for j in 0...PBAnimation::MAX_SPRITES
@@ -827,7 +827,8 @@ class AnimationCanvas < Sprite
end end
end end
currentFrame=getCurrentFrame currentFrame=getCurrentFrame
if currentFrame && !@selecting && Input.repeat?(Input::TAB) if currentFrame && !@selecting &&
(Input.triggerex?(:TAB) || Input.repeatex?(:TAB))
currentFrame.length.times { currentFrame.length.times {
@currentcel+=1 @currentcel+=1
@currentcel=0 if @currentcel>=currentFrame.length @currentcel=0 if @currentcel>=currentFrame.length
@@ -841,42 +842,42 @@ class AnimationCanvas < Sprite
cel[AnimFrame::Y]=mousepos[1]-BORDERSIZE+@selectOffsetY cel[AnimFrame::Y]=mousepos[1]-BORDERSIZE+@selectOffsetY
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if !Input.getstate(Input::LeftMouseKey) && @selecting if !Input.press?(Input::MOUSELEFT) && @selecting
@selecting=false @selecting=false
end end
if cel if cel
if Input.repeat?(Input::DELETE) && self.deletable?(@currentcel) if (Input.triggerex?(:DELETE) || Input.repeatex?(:DELETE)) && self.deletable?(@currentcel)
@animation[@currentframe][@currentcel]=nil @animation[@currentframe][@currentcel]=nil
@dirty[@currentcel]=true @dirty[@currentcel]=true
return return
end end
if Input.repeatex?(0x50) # "P" for properties if Input.triggerex?(0x50) || Input.repeatex?(0x50) # "P" for properties
pbCellProperties(self) pbCellProperties(self)
@dirty[@currentcel]=true @dirty[@currentcel]=true
return return
end end
if Input.repeatex?(0x4C) # "L" for lock if Input.triggerex?(0x4C) || Input.repeatex?(0x4C) # "L" for lock
cel[AnimFrame::LOCKED]=(cel[AnimFrame::LOCKED]==0) ? 1 : 0 cel[AnimFrame::LOCKED]=(cel[AnimFrame::LOCKED]==0) ? 1 : 0
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if Input.repeatex?(0x52) # "R" for rotate right if Input.triggerex?(0x52) || Input.repeatex?(0x52) # "R" for rotate right
cel[AnimFrame::ANGLE]+=10 cel[AnimFrame::ANGLE]+=10
cel[AnimFrame::ANGLE]%=360 cel[AnimFrame::ANGLE]%=360
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if Input.repeatex?(0x45) # "E" for rotate left if Input.triggerex?(0x45) || Input.repeatex?(0x45) # "E" for rotate left
cel[AnimFrame::ANGLE]-=10 cel[AnimFrame::ANGLE]-=10
cel[AnimFrame::ANGLE]%=360 cel[AnimFrame::ANGLE]%=360
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if Input.repeatex?(0x6B) # "+" for zoom in if Input.triggerex?(0x6B) || Input.repeatex?(0x6B) # "+" for zoom in
cel[AnimFrame::ZOOMX]+=10 cel[AnimFrame::ZOOMX]+=10
cel[AnimFrame::ZOOMX]=1000 if cel[AnimFrame::ZOOMX]>1000 cel[AnimFrame::ZOOMX]=1000 if cel[AnimFrame::ZOOMX]>1000
cel[AnimFrame::ZOOMY]+=10 cel[AnimFrame::ZOOMY]+=10
cel[AnimFrame::ZOOMY]=1000 if cel[AnimFrame::ZOOMY]>1000 cel[AnimFrame::ZOOMY]=1000 if cel[AnimFrame::ZOOMY]>1000
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if Input.repeatex?(0x6D) # "-" for zoom in if Input.triggerex?(0x6D) || Input.repeatex?(0x6D) # "-" for zoom in
cel[AnimFrame::ZOOMX]-=10 cel[AnimFrame::ZOOMX]-=10
cel[AnimFrame::ZOOMX]=10 if cel[AnimFrame::ZOOMX]<10 cel[AnimFrame::ZOOMX]=10 if cel[AnimFrame::ZOOMX]<10
cel[AnimFrame::ZOOMY]-=10 cel[AnimFrame::ZOOMY]-=10
@@ -884,22 +885,22 @@ class AnimationCanvas < Sprite
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if !self.locked?(@currentcel) if !self.locked?(@currentcel)
if Input.repeat?(Input::UP) if Input.trigger?(Input::UP) || Input.repeat?(Input::UP)
increment=(Input.press?(Input::ALT)) ? 1 : 8 increment=(Input.press?(Input::ALT)) ? 1 : 8
cel[AnimFrame::Y]-=increment cel[AnimFrame::Y]-=increment
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if Input.repeat?(Input::DOWN) if Input.trigger?(Input::DOWN) ||Input.repeat?(Input::DOWN)
increment=(Input.press?(Input::ALT)) ? 1 : 8 increment=(Input.press?(Input::ALT)) ? 1 : 8
cel[AnimFrame::Y]+=increment cel[AnimFrame::Y]+=increment
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if Input.repeat?(Input::LEFT) if Input.trigger?(Input::LEFT) || Input.repeat?(Input::LEFT)
increment=(Input.press?(Input::ALT)) ? 1 : 8 increment=(Input.press?(Input::ALT)) ? 1 : 8
cel[AnimFrame::X]-=increment cel[AnimFrame::X]-=increment
@dirty[@currentcel]=true @dirty[@currentcel]=true
end end
if Input.repeat?(Input::RIGHT) if Input.trigger?(Input::RIGHT) || Input.repeat?(Input::RIGHT)
increment=(Input.press?(Input::ALT)) ? 1 : 8 increment=(Input.press?(Input::ALT)) ? 1 : 8
cel[AnimFrame::X]+=increment cel[AnimFrame::X]+=increment
@dirty[@currentcel]=true @dirty[@currentcel]=true

View File

@@ -125,12 +125,12 @@ class Button < UIControl
return if !mousepos return if !mousepos
rect=Rect.new(self.x+1,self.y+1,self.width-2,self.height-2) rect=Rect.new(self.x+1,self.y+1,self.width-2,self.height-2)
rect=toAbsoluteRect(rect) rect=toAbsoluteRect(rect)
if Input.triggerex?(Input::LeftMouseKey) && if Input.trigger?(Input::MOUSELEFT) &&
rect.contains(mousepos[0],mousepos[1]) && !@captured rect.contains(mousepos[0],mousepos[1]) && !@captured
@captured=true @captured=true
self.invalidate self.invalidate
end end
if Input.releaseex?(Input::LeftMouseKey) && @captured if Input.release?(Input::MOUSELEFT) && @captured
self.changed=true if rect.contains(mousepos[0],mousepos[1]) self.changed=true if rect.contains(mousepos[0],mousepos[1])
@captured=false @captured=false
self.invalidate self.invalidate
@@ -263,7 +263,7 @@ class TextField < UIControl
self.changed=false self.changed=false
self.invalidate if ((@frame%10)==0) self.invalidate if ((@frame%10)==0)
# Moving cursor # Moving cursor
if Input.repeat?(Input::LEFT) if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
if @cursor > 0 if @cursor > 0
@cursor-=1 @cursor-=1
@frame=0 @frame=0
@@ -271,7 +271,7 @@ class TextField < UIControl
end end
return return
end end
if Input.repeat?(Input::RIGHT) if Input.triggerex?(:LEFT) || Input.repeatex?(:RIGHT)
if @cursor < self.text.scan(/./m).length if @cursor < self.text.scan(/./m).length
@cursor+=1 @cursor+=1
@frame=0 @frame=0
@@ -280,50 +280,13 @@ class TextField < UIControl
return return
end end
# Backspace # Backspace
if Input.repeat?(Input::BACKSPACE) || Input.repeat?(Input::DELETE) if Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE) ||
Input.triggerex?(:DELETE) || Input.repeatex?(:DELETE)
self.delete if @cursor > 0 self.delete if @cursor > 0
return return
end end
# Letter keys # Letter & Number keys
for i in 65..90 Input.gets.each_char{|c|insert(c)}
if Input.repeatex?(i)
shift=(Input.press?(Input::SHIFT)) ? 0x41 : 0x61
insert((shift+i-65).chr)
return
end
end
# Number keys
shifted=")!@\#$%^&*("
unshifted="0123456789"
for i in 48..57
if Input.repeatex?(i)
insert((Input.press?(Input::SHIFT)) ? shifted[i-48].chr : unshifted[i-48].chr)
return
end
end
keys=[
[32," "," "],
[106,"*","*"],
[107,"+","+"],
[109,"-","-"],
[111,"/","/"],
[186,";",":"],
[187,"=","+"],
[188,",","<"],
[189,"-","_"],
[190,".",">"],
[191,"/","?"],
[219,"[","{"],
[220,"\\","|"],
[221,"]","}"],
[222,"\"","'"]
]
for i in keys
if Input.repeatex?(i[0])
insert((Input.press?(Input::SHIFT)) ? i[2] : i[1])
return
end
end
end end
def refresh def refresh
@@ -428,17 +391,17 @@ class Slider < UIControl
self.curvalue=self.minvalue self.curvalue=self.minvalue
end end
return false if self.disabled return false if self.disabled
return false if !Input.repeatex?(Input::LeftMouseKey) return false if !Input.repeat?(Input::MOUSELEFT)
return false if !mousepos return false if !mousepos
left=toAbsoluteRect(@leftarrow) left=toAbsoluteRect(@leftarrow)
right=toAbsoluteRect(@rightarrow) right=toAbsoluteRect(@rightarrow)
oldvalue=self.curvalue oldvalue=self.curvalue
# Left arrow # Left arrow
if left.contains(mousepos[0],mousepos[1]) if left.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100 if Input.count(Input::MOUSELEFT)>100
self.curvalue-=10 self.curvalue-=10
self.curvalue=self.curvalue.floor self.curvalue=self.curvalue.floor
elsif Input.repeatcount(Input::LeftMouseKey)>50 elsif Input.count(Input::MOUSELEFT)>50
self.curvalue-=5 self.curvalue-=5
self.curvalue=self.curvalue.floor self.curvalue=self.curvalue.floor
else else
@@ -450,10 +413,10 @@ class Slider < UIControl
end end
#Right arrow #Right arrow
if right.contains(mousepos[0],mousepos[1]) if right.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100 if Input.count(Input::MOUSELEFT)>100
self.curvalue+=10 self.curvalue+=10
self.curvalue=self.curvalue.floor self.curvalue=self.curvalue.floor
elsif Input.repeatcount(Input::LeftMouseKey)>50 elsif Input.count(Input::MOUSELEFT)>50
self.curvalue+=5 self.curvalue+=5
self.curvalue=self.curvalue.floor self.curvalue=self.curvalue.floor
else else
@@ -676,16 +639,16 @@ class TextSlider < UIControl
self.curvalue=self.minvalue self.curvalue=self.minvalue
end end
return false if self.disabled return false if self.disabled
return false if !Input.repeatex?(Input::LeftMouseKey) return false if !Input.repeat?(Input::MOUSELEFT)
return false if !mousepos return false if !mousepos
left=toAbsoluteRect(@leftarrow) left=toAbsoluteRect(@leftarrow)
right=toAbsoluteRect(@rightarrow) right=toAbsoluteRect(@rightarrow)
oldvalue=self.curvalue oldvalue=self.curvalue
# Left arrow # Left arrow
if left.contains(mousepos[0],mousepos[1]) if left.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100 if Input.count(Input::MOUSELEFT)>100
self.curvalue-=10 self.curvalue-=10
elsif Input.repeatcount(Input::LeftMouseKey)>50 elsif Input.count(Input::MOUSELEFT)>50
self.curvalue-=5 self.curvalue-=5
else else
self.curvalue-=1 self.curvalue-=1
@@ -695,9 +658,9 @@ class TextSlider < UIControl
end end
# Right arrow # Right arrow
if right.contains(mousepos[0],mousepos[1]) if right.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100 if Input.count(Input::MOUSELEFT)>100
self.curvalue+=10 self.curvalue+=10
elsif Input.repeatcount(Input::LeftMouseKey)>50 elsif Input.count(Input::MOUSELEFT)>50
self.curvalue+=5 self.curvalue+=5
else else
self.curvalue+=1 self.curvalue+=1

View File

@@ -20,7 +20,7 @@ class ControlPointSprite < SpriteWrapper
end end
def mouseover def mouseover
if Input.repeatcount(Input::LeftMouseKey)==0 || !@dragging if Input.count(Input::MOUSELEFT)==0 || !@dragging
@dragging=false @dragging=false
return return
end end
@@ -292,7 +292,7 @@ def pbDefinePath(canvas)
if Input.trigger?(Input::B) if Input.trigger?(Input::B)
break break
end end
if Input.triggerex?(Input::LeftMouseKey) if Input.trigger?(Input::MOUSELEFT)
for j in 0...4 for j in 0...4
next if !curve[j].hittest? next if !curve[j].hittest?
if j==1||j==2 if j==1||j==2
@@ -370,11 +370,11 @@ def pbDefinePath(canvas)
loop do loop do
Graphics.update Graphics.update
Input.update Input.update
if Input.trigger?(Input::ESC) if Input.triggerex?(:ESCAPE)
canceled=true canceled=true
break break
end end
if Input.triggerex?(Input::LeftMouseKey) if Input.trigger?(Input::MOUSELEFT)
break break
end end
mousepos=Mouse::getMousePos(true) mousepos=Mouse::getMousePos(true)
@@ -389,7 +389,7 @@ def pbDefinePath(canvas)
window.text = (mousepos) ? sprintf("(%d,%d)",mousepos[0],mousepos[1]) : "(??,??)" window.text = (mousepos) ? sprintf("(%d,%d)",mousepos[0],mousepos[1]) : "(??,??)"
Graphics.update Graphics.update
Input.update Input.update
if Input.trigger?(Input::ESC) || Input.repeatcount(Input::LeftMouseKey)==0 if Input.triggerex?(:ESCAPE) || Input.count(Input::MOUSELEFT)==0
break break
end end
end end

View File

@@ -26,7 +26,7 @@ end
################################################################################ ################################################################################
def pbSelectAnim(canvas,animwin) def pbSelectAnim(canvas,animwin)
animfiles=[] animfiles=[]
pbRgssChdir(".\\Graphics\\Animations\\") { pbRgssChdir(File.join("Graphics", "Animations")) {
animfiles.concat(Dir.glob("*.png")) animfiles.concat(Dir.glob("*.png"))
} }
cmdwin=pbListWindow(animfiles,320) cmdwin=pbListWindow(animfiles,320)
@@ -91,6 +91,7 @@ def pbAnimName(animation,cmdwin)
window=ControlWindow.new(320,128,320,32*4) window=ControlWindow.new(320,128,320,32*4)
window.z=99999 window.z=99999
window.addControl(TextField.new(_INTL("New Name:"),animation.name)) window.addControl(TextField.new(_INTL("New Name:"),animation.name))
Input.text_input = true
okbutton=window.addButton(_INTL("OK")) okbutton=window.addButton(_INTL("OK"))
cancelbutton=window.addButton(_INTL("Cancel")) cancelbutton=window.addButton(_INTL("Cancel"))
window.opacity=224 window.opacity=224
@@ -98,16 +99,17 @@ def pbAnimName(animation,cmdwin)
Graphics.update Graphics.update
Input.update Input.update
window.update window.update
if window.changed?(okbutton) || Input.trigger?(Input::ENTER) if window.changed?(okbutton) || Input.triggerex?(:RETURN)
cmdwin.commands[cmdwin.index]=_INTL("{1} {2}",cmdwin.index,window.controls[0].text) cmdwin.commands[cmdwin.index]=_INTL("{1} {2}",cmdwin.index,window.controls[0].text)
animation.name=window.controls[0].text animation.name=window.controls[0].text
break break
end end
if window.changed?(cancelbutton) || Input.trigger?(Input::ESC) if window.changed?(cancelbutton) || Input.triggerex?(:ESCAPE)
break break
end end
end end
window.dispose window.dispose
Input.text_input = false
return return
end end
@@ -512,7 +514,7 @@ def pbSelectSE(canvas,audio)
displayname=(filename!="") ? filename : _INTL("<user's cry>") displayname=(filename!="") ? filename : _INTL("<user's cry>")
animfiles=[] animfiles=[]
ret=false ret=false
pbRgssChdir(".\\Audio\\SE\\Anim\\") { pbRgssChdir(File.join("Audio", "SE", "Anim")) {
animfiles.concat(Dir.glob("*.wav")) animfiles.concat(Dir.glob("*.wav"))
animfiles.concat(Dir.glob("*.mp3")) animfiles.concat(Dir.glob("*.mp3"))
animfiles.concat(Dir.glob("*.ogg")) animfiles.concat(Dir.glob("*.ogg"))
@@ -579,7 +581,7 @@ def pbSelectBG(canvas,timing)
animfiles=[] animfiles=[]
animfiles[cmdErase=animfiles.length]=_INTL("[Erase background graphic]") animfiles[cmdErase=animfiles.length]=_INTL("[Erase background graphic]")
ret=false ret=false
pbRgssChdir(".\\Graphics\\Animations\\") { pbRgssChdir(File.join("Graphics", "Animations")) {
animfiles.concat(Dir.glob("*.bmp")) animfiles.concat(Dir.glob("*.bmp"))
animfiles.concat(Dir.glob("*.png")) animfiles.concat(Dir.glob("*.png"))
animfiles.concat(Dir.glob("*.jpg")) animfiles.concat(Dir.glob("*.jpg"))
@@ -1020,10 +1022,10 @@ def animationEditorMain(animation)
break break
end end
end end
if Input.trigger?(Input::ONLYF5) if Input.triggerex?(:F5)
pbAnimEditorHelpWindow pbAnimEditorHelpWindow
next next
elsif Input.triggerex?(Input::RightMouseKey) && sliderwin.hittest?(0) # Right mouse button elsif Input.trigger?(Input::MOUSERIGHT) && sliderwin.hittest?(0) # Right mouse button
commands=[ commands=[
_INTL("Copy Frame"), _INTL("Copy Frame"),
_INTL("Paste Frame"), _INTL("Paste Frame"),
@@ -1058,7 +1060,7 @@ def animationEditorMain(animation)
sliderwin.invalidate sliderwin.invalidate
end end
next next
elsif Input.triggerex?(Input::RightMouseKey) # Right mouse button elsif Input.trigger?(Input::MOUSERIGHT) # Right mouse button
mousepos=Mouse::getMousePos mousepos=Mouse::getMousePos
mousepos=[0,0] if !mousepos mousepos=[0,0] if !mousepos
commands=[ commands=[

View File

@@ -19,7 +19,7 @@ class MapSprite
end end
def getXY def getXY
return nil if !Input.triggerex?(Input::LeftMouseKey) return nil if !Input.trigger?(Input::MOUSELEFT)
mouse = Mouse::getMousePos(true) mouse = Mouse::getMousePos(true)
return nil if !mouse return nil if !mouse
if mouse[0]<@sprite.x || mouse[0]>=@sprite.x+@sprite.bitmap.width if mouse[0]<@sprite.x || mouse[0]>=@sprite.x+@sprite.bitmap.width
@@ -118,7 +118,7 @@ class RegionMapSprite
end end
def getXY def getXY
return nil if !Input.triggerex?(Input::LeftMouseKey) return nil if !Input.trigger?(Input::MOUSELEFT)
mouse=Mouse::getMousePos(true) mouse=Mouse::getMousePos(true)
return nil if !mouse return nil if !mouse
if mouse[0]<@sprite.x||mouse[0]>=@sprite.x+@sprite.bitmap.width if mouse[0]<@sprite.x||mouse[0]>=@sprite.x+@sprite.bitmap.width
@@ -480,13 +480,13 @@ class MapScreenScene
mousepos=Mouse::getMousePos mousepos=Mouse::getMousePos
if mousepos if mousepos
hitmap=hittest(mousepos[0],mousepos[1]) hitmap=hittest(mousepos[0],mousepos[1])
if Input.triggerex?(Input::LeftMouseKey) if Input.trigger?(Input::MOUSELEFT)
onClick(hitmap,mousepos[0],mousepos[1]) onClick(hitmap,mousepos[0],mousepos[1])
elsif Input.triggerex?(Input::RightMouseKey) elsif Input.trigger?(Input::MOUSERIGHT)
onRightClick(hitmap,mousepos[0],mousepos[1]) onRightClick(hitmap,mousepos[0],mousepos[1])
elsif Input.releaseex?(Input::LeftMouseKey) elsif Input.release?(Input::MOUSELEFT)
onMouseUp(hitmap) onMouseUp(hitmap)
elsif Input.releaseex?(Input::RightMouseKey) elsif Input.release?(Input::MOUSERIGHT)
onRightMouseUp(hitmap) onRightMouseUp(hitmap)
else else
if @lasthitmap!=hitmap if @lasthitmap!=hitmap
@@ -520,14 +520,14 @@ class MapScreenScene
i[1].x -= 4 if i i[1].x -= 4 if i
end end
end end
if Input.triggerex?("A"[0]) if Input.triggerex?(:A)
id=chooseMapScreen(_INTL("Add Map"),@currentmap) id=chooseMapScreen(_INTL("Add Map"),@currentmap)
if id>0 if id>0
addSprite(id) addSprite(id)
setTopSprite(id) setTopSprite(id)
@mapconns=generateConnectionData @mapconns=generateConnectionData
end end
elsif Input.triggerex?("S"[0]) elsif Input.triggerex?(:S)
id=chooseMapScreen(_INTL("Go to Map"),@currentmap) id=chooseMapScreen(_INTL("Go to Map"),@currentmap)
if id>0 if id>0
@mapconns=generateConnectionData @mapconns=generateConnectionData
@@ -538,7 +538,7 @@ class MapScreenScene
putSprite(id) putSprite(id)
@currentmap=id @currentmap=id
end end
elsif Input.trigger?(Input::DELETE) elsif Input.triggerex?(:DELETE)
if @mapsprites.keys.length>1 && @selmapid>=0 if @mapsprites.keys.length>1 && @selmapid>=0
@mapsprites[@selmapid].bitmap.dispose @mapsprites[@selmapid].bitmap.dispose
@mapsprites[@selmapid].dispose @mapsprites[@selmapid].dispose

View File

@@ -98,7 +98,7 @@ module Compiler
sectionname = nil sectionname = nil
lastsection = {} lastsection = {}
f.each_line { |line| f.each_line { |line|
if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF
line = line[3,line.length-3] line = line[3,line.length-3]
end end
if !line[/^\#/] && !line[/^\s*$/] if !line[/^\#/] && !line[/^\s*$/]
@@ -149,7 +149,7 @@ module Compiler
sectionname = nil sectionname = nil
lastsection = [] lastsection = []
f.each_line { |line| f.each_line { |line|
if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF
line = line[3,line.length-3] line = line[3,line.length-3]
end end
if !line[/^\#/] && !line[/^\s*$/] if !line[/^\#/] && !line[/^\s*$/]
@@ -175,7 +175,7 @@ module Compiler
def pbEachCommentedLine(f) def pbEachCommentedLine(f)
lineno = 1 lineno = 1
f.each_line { |line| f.each_line { |line|
if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF
line = line[3,line.length-3] line = line[3,line.length-3]
end end
yield line, lineno if !line[/^\#/] && !line[/^\s*$/] yield line, lineno if !line[/^\#/] && !line[/^\s*$/]
@@ -189,7 +189,7 @@ module Compiler
FileLineData.file = filename FileLineData.file = filename
lineno = 1 lineno = 1
f.each_line { |line| f.each_line { |line|
if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF
line = line[3,line.length-3] line = line[3,line.length-3]
end end
if !line[/^\#/] && !line[/^\s*$/] if !line[/^\#/] && !line[/^\s*$/]
@@ -205,7 +205,7 @@ module Compiler
def pbEachPreppedLine(f) def pbEachPreppedLine(f)
lineno = 1 lineno = 1
f.each_line { |line| f.each_line { |line|
if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF
line = line[3,line.length-3] line = line[3,line.length-3]
end end
line = prepline(line) line = prepline(line)
@@ -220,7 +220,7 @@ module Compiler
FileLineData.file = filename FileLineData.file = filename
lineno = 1 lineno = 1
f.each_line { |line| f.each_line { |line|
if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF if lineno==1 && line[0].ord==0xEF && line[1].ord==0xBB && line[2].ord==0xBF
line = line[3,line.length-3] line = line[3,line.length-3]
end end
line = prepline(line) line = prepline(line)
@@ -324,7 +324,7 @@ module Compiler
end end
return enumer.const_get(ret.to_sym) return enumer.const_get(ret.to_sym)
elsif enumer.is_a?(Symbol) || enumer.is_a?(String) elsif enumer.is_a?(Symbol) || enumer.is_a?(String)
if GameData.const_defined?(enumer.to_sym) if !Kernel.const_defined?(enumer.to_sym) && GameData.const_defined?(enumer.to_sym)
enumer = GameData.const_get(enumer.to_sym) enumer = GameData.const_get(enumer.to_sym)
begin begin
if ret == "" || !enumer.exists?(ret.to_sym) if ret == "" || !enumer.exists?(ret.to_sym)
@@ -730,6 +730,7 @@ module Compiler
convert_files convert_files
end end
pbSetWindowText(nil) pbSetWindowText(nil)
System.reload_cache
end end
def main def main

BIN
Game.exe

Binary file not shown.

Binary file not shown.

BIN
gif.dll

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
x64-msvcrt-ruby300.dll Normal file

Binary file not shown.

BIN
zlib1.dll Normal file

Binary file not shown.