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"
]
end
module Essentials
VERSION = "18.1.dev"
ERROR_TEXT = ""
end

View File

@@ -1,8 +1,4 @@
$MKXP = !!defined?(System)
def mkxp?
return $MKXP
end
$VERBOSE = nil
def pbSetWindowText(string)
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
def pbGetExceptionMessage(e,_script="")
emessage = e.message
emessage = e.message.dup
emessage.force_encoding(Encoding::UTF_8)
if e.is_a?(Hangup)
emessage = "The script is taking too long. The game will restart."
elsif e.is_a?(Errno::ENOENT)
filename = emessage.sub("No such file or directory - ", "")
emessage = "File #{filename} not found."
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
end
@@ -30,7 +31,7 @@ def pbPrintException(e)
maxlength = ($INTERNAL) ? 25 : 10
e.backtrace[0,maxlength].each { |i| btrace += "#{i}\r\n" }
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 += "#{Essentials::ERROR_TEXT}" # For third party scripts to add to
message += "Exception: #{e.class}\r\n"
@@ -41,12 +42,22 @@ def pbPrintException(e)
errorlog = RTP.getSaveFileName("errorlog.txt")
end
File.open(errorlog,"ab") { |f| f.write(premessage); f.write(message) }
errorlogline = errorlog.sub("/", "\\")
errorlogline.sub!(Dir.pwd + "\\", "")
errorlogline = errorlog
errorlogline.sub!(Dir.pwd + "/", "")
errorlogline.sub!(pbGetUserName, "USERNAME")
errorlogline = "\r\n" + errorlogline if errorlogline.length > 20
errorlogline.gsub!("/", "\\")
print("#{message}\r\nThis exception was logged in #{errorlogline}.\r\nPress Ctrl+C to copy this message to the clipboard.")
errorlogline.gsub!("/", "\\") if System.platform[/Windows/]
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
def pbCriticalCode

View File

@@ -122,7 +122,7 @@
module PluginManager
# 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.
@@Plugins = {}
@@ -307,7 +307,8 @@ module PluginManager
def self.error(msg)
Graphics.update
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
end
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
@fullyrefreshed = false
@fullyrefreshedautos = false
@shouldWrap = false
end
def dispose
@@ -212,7 +314,14 @@ class CustomTilemap
end
def tileset=(value)
@tileset = value
if value.mega?
@tileset = TileWrap::wrapTileset(value)
@shouldWrap = true
value.dispose
else
@tileset = value
@shouldWrap = false
end
@tilesetChanged = true
end
@@ -348,14 +457,16 @@ class CustomTilemap
bitmap = Bitmap.new(@tileWidth,@tileHeight)
rect = Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@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
end
sprite.bitmap = bitmap if sprite.bitmap!=bitmap
else
sprite.bitmap = @tileset if sprite.bitmap!=@tileset
sprite.src_rect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
@tileSrcWidth,@tileSrcHeight)
rect = Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
@tileSrcWidth,@tileSrcHeight)
rect = TileWrap::getWrappedRect(rect) if @shouldWrap
sprite.src_rect = rect
end
end
@@ -641,9 +752,9 @@ class CustomTilemap
xpos = (x * twidth) - @oxLayer0
ypos = (y * theight) - @oyLayer0
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
bitmap.blt(xpos, ypos, @tileset, temprect)
TileWrap::blitWrappedPixels(xpos,ypos, bitmap, @tileset, temprect)
end
else # Autotiles
tilebitmap = @autotileInfo[id]
@@ -693,9 +804,9 @@ class CustomTilemap
((id - 384) >> 3) * @tileSrcHeight,
@tileSrcWidth, @tileSrcHeight)
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
bitmap.blt(xpos, ypos, @tileset, temprect)
TileWrap::blitWrappedPixels(xpos,ypos, bitmap, @tileset, temprect)
end
else # Autotiles
tilebitmap = @autotileInfo[id]
@@ -754,9 +865,9 @@ class CustomTilemap
((id - 384) >> 3) * @tileSrcHeight,
@tileSrcWidth, @tileSrcHeight)
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
bitmap.blt(xpos, ypos, @tileset, tmprect)
TileWrap::blitWrappedPixels(xpos,ypos, bitmap, @tileset, tmprect)
end
else # Autotiles
frames = @framecount[id / 48 - 1]

View File

@@ -75,81 +75,6 @@ def pbBitmapName(x)
return (ret) ? ret : x
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
@rtpPaths = nil
@@ -202,121 +127,31 @@ module RTP
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
# XXX: Use "." instead of Dir.pwd because of problems retrieving files if
# the current directory contains an accent mark
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
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)
return getSaveFolder().gsub(/[\/\\]$/,"")+"/"+fileName
File.join(getSaveFolder, fileName)
end
def self.getSaveFolder
if !@@folder
# XXX: Use "." instead of Dir.pwd because of problems retrieving files if
# the current directory contains an accent mark
pwd = "."
# Get the known folder path for saved games
savedGames = getKnownFolder([
0x4c5c32ff,0xbb9d,0x43b0,0xb5,0xb4,0x2d,0x72,0xe5,0x4e,0xaa,0xa4])
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
# MKXP makes sure that this folder has been created
# once it starts. The location differs depending on
# the operating system:
# Windows: %APPDATA%
# Linux: $HOME/.local/share
# macOS (unsandboxed): $HOME/Library/Application Support
System.data_directory
end
end
@@ -339,6 +174,9 @@ end
# Used to determine whether a data file exists (rather than a graphics or
# 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)
filename = canonicalize(filename)
if safeExists?("./Game.rgssad") || safeExists?("./Game.rgss2a")
@@ -350,6 +188,9 @@ end
# Opens an IO, even if the file is in an encrypted archive.
# 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)
#File.open("debug.txt","ab") { |fw| fw.write([file,mode,Time.now.to_f].inspect+"\r\n") }
if !safeExists?("./Game.rgssad") && !safeExists?("./Game.rgss2a")
@@ -362,11 +203,7 @@ def pbRgssOpen(file,mode=nil)
end
file = canonicalize(file)
Marshal.neverload = true
begin
str = load_data(file)
ensure
Marshal.neverload = false
end
str = load_data(file, true)
if block_given?
StringInput.open(str) { |f| yield f }
return nil
@@ -383,18 +220,15 @@ def pbGetFileChar(file)
return nil if !safeExists?(file)
begin
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
end
end
Marshal.neverload = true
str = nil
begin
str = load_data(file)
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError
str = load_data(file, true)
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, Errno::EISDIR, RGSSError, MKXPError
str = nil
ensure
Marshal.neverload = false
end
return str
end
@@ -406,6 +240,9 @@ end
# Gets the contents of a file. Doesn't check RTP, but does check
# 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)
file = canonicalize(file)
if !(safeExists?("./Game.rgssad") || safeExists?("./Game.rgss2a"))
@@ -416,14 +253,11 @@ def pbGetFileString(file)
return nil
end
end
Marshal.neverload = true
str = nil
begin
str = load_data(file)
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError
str = load_data(file, true)
rescue Errno::ENOENT, Errno::EINVAL, Errno::EACCES, RGSSError, MKXPError
str = nil
ensure
Marshal.neverload = false
end
return str
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
include Enumerable
@@ -624,44 +387,3 @@ class StringInput
alias sysread read
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
lastsection=[]
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]
end
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
# Exit is not called when game is reset (using F12)
@@ -45,315 +14,6 @@ def at_exit(&block)
$AtExitProcs.push(Proc.new(&block))
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.
#===============================================================================

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
@@loadlib = Win32API.new("Kernel32.dll","LoadLibrary",'p','')
if safeExists?("gif.dll")
@@ -22,6 +26,7 @@ module GifLibrary
return ret
end
end
=end
@@ -201,12 +206,13 @@ class GifBitmap
end
end
end
if bitmap && filestring && filestring[0]==0x47 &&
if bitmap && filestring && filestring[0].ord==0x47 &&
bitmap.width==32 && bitmap.height==32
#File.open("debug.txt","ab") { |f| f.puts("rejecting bitmap") }
bitmap.dispose
bitmap=nil
end
# Note: MKXP can open .gif files just fine, first frame only
if bitmap
#File.open("debug.txt","ab") { |f| f.puts("reusing bitmap") }
# Have a regular non-animated bitmap
@@ -217,6 +223,7 @@ class GifBitmap
else
tmpBase=File.basename(file)+"_tmp_"
filestring=pbGetFileString(filestrName) if filestring
=begin
Dir.chdir(ENV["TEMP"]) { # navigate to temp folder since game might be on a CD-ROM
if filestring && filestring[0]==0x47 && GifLibrary::PngDll
result=GifLibrary::GifToPngFilesInMemory.call(filestring,
@@ -244,6 +251,7 @@ class GifBitmap
end
end
}
=end
if @gifbitmaps.length==0
@gifbitmaps=[BitmapWrapper.new(32,32)]
@gifdelays=[1]

View File

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

View File

@@ -565,88 +565,39 @@ class Window_MultilineTextEntry < SpriteWindow_Base
self.refresh if ((@frame%10)==0)
return if !self.active
# Moving cursor
if Input.repeat?(Input::UP)
if Input.triggerex?(:UP) || Input.repeatex?(:UP)
moveCursor(-1,0)
return
elsif Input.repeat?(Input::DOWN)
elsif Input.triggerex?(:DOWN) || Input.repeatex?(:DOWN)
moveCursor(1,0)
return
elsif Input.repeat?(Input::LEFT)
elsif Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
moveCursor(0,-1)
return
elsif Input.repeat?(Input::RIGHT)
elsif Input.triggerex?(:RIGHT) || Input.repeatex?(:RIGHT)
moveCursor(0,1)
return
end
if !@peekMessage
@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)
if Input.press?(Input::CTRL) && Input.triggerex?(:HOME)
# Move cursor to beginning
@cursorLine=0
@cursorColumn=0
updateCursorPos(true)
return
elsif Input.press?(Input::CTRL) && Input.trigger?(Input::ENDKEY)
elsif Input.press?(Input::CTRL) && Input.triggerex?(:END)
# Move cursor to end
@cursorLine=getTotalLines()-1
@cursorColumn=getColumnsInLine(@cursorLine)
updateCursorPos(true)
return
elsif Input.repeat?(Input::ENTER)
elsif Input.triggerex?(:RETURN) || Input.repeatex?(:RETURN)
self.insert("\n")
return
elsif Input.repeat?(Input::BACKSPACE) # Backspace
elsif Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE) # Backspace
self.delete
return
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,"[","{"],
[220,"\\","|"],
[221,"]","}"],
[222,"'","\""]
]
for i in keys
if Input.repeatex?(i[0])
insert((Input.press?(Input::SHIFT)) ? i[2] : i[1])
return
end
end
Input.gets.each_char{|c|insert(c)}
end
def refresh
@@ -719,97 +670,27 @@ class Window_TextEntry_Keyboard < Window_TextEntry
self.refresh if ((@frame%10)==0)
return if !self.active
# Moving cursor
if Input.repeat?(Input::LEFT)
if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
if @helper.cursor > 0
@helper.cursor-=1
@frame=0
self.refresh
end
return
elsif Input.repeat?(Input::RIGHT)
elsif Input.triggerex?(:LEFT) || Input.repeatex?(:RIGHT)
if @helper.cursor < self.text.scan(/./m).length
@helper.cursor+=1
@frame=0
self.refresh
end
return
elsif Input.repeat?(Input::BACKSPACE)
elsif Input.triggerex?(:BACKSPACE) || Input.repeatex?(:BACKSPACE)
self.delete if @helper.cursor>0
return
elsif Input.trigger?(Input::ENTER) || Input.trigger?(Input::ESC)
elsif Input.triggerex?(:RETURN) || Input.triggerex?(:ESCAPE)
return
end
if !@toUnicode
@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
Input.gets.each_char{|c|insert(c)}
end
end
@@ -832,7 +713,7 @@ class PokemonEntryScene
if USEKEYBOARD
@sprites["entry"]=Window_TextEntry_Keyboard.new(initialText,
0,0,400-112,96,helptext,true)
$fullInputUpdate = true
Input.text_input = true
else
@sprites["entry"]=Window_TextEntry.new(initialText,0,0,400,96,helptext,true)
end
@@ -932,10 +813,10 @@ class PokemonEntryScene
loop do
Graphics.update
Input.update
if Input.trigger?(Input::ESC) && @minlength==0
if Input.triggerex?(:ESCAPE) && @minlength==0
ret=""
break
elsif Input.trigger?(Input::ENTER) && @sprites["entry"].text.length>=@minlength
elsif Input.triggerex?(:RETURN) && @sprites["entry"].text.length>=@minlength
ret=@sprites["entry"].text
break
end
@@ -997,10 +878,10 @@ class PokemonEntryScene
end
def pbEndScene
$fullInputUpdate = false
pbFadeOutAndHide(@sprites)
pbDisposeSpriteHash(@sprites)
@viewport.dispose
Input.text_input = false if USEKEYBOARD
end
end
@@ -1553,14 +1434,14 @@ def pbFreeText(msgwindow,currenttext,passwordbox,maxlength,width=240)
pbPositionNearMsgWindow(window,msgwindow,:right)
window.text=currenttext
window.passwordChar="*" if passwordbox
$fullInputUpdate = true
Input.text_input = true
loop do
Graphics.update
Input.update
if Input.trigger?(Input::ESC)
if Input.triggerex?(:ESCAPE)
ret=currenttext
break
elsif Input.trigger?(Input::ENTER)
elsif Input.triggerex?(:RETURN)
ret=window.text
break
end
@@ -1568,7 +1449,7 @@ def pbFreeText(msgwindow,currenttext,passwordbox,maxlength,width=240)
msgwindow.update if msgwindow
yield if block_given?
end
$fullInputUpdate = false
Input.text_input = false
window.dispose
Input.update
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?
power="\0"*12
begin
sps=Win32API.new('kernel32.dll','GetSystemPowerStatus','p','l')
rescue
return false
end
if sps.call(power)==1
status=power.unpack("CCCCVV")
# 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
pstate = System.power_state
# If it's not discharging, it doesn't matter if it's low
return false if !pstate[:discharging]
# Check for less than 10m, priority over the percentage
# Some laptops (Chromebooks, Macbooks) have very long lifetimes
return true if pstate[:seconds] && pstate[:seconds] <= 600
# Check for <=15%
return true if pstate[:percent] && pstate[:percent] <= 15
return false
end

View File

@@ -482,7 +482,7 @@ class PokemonPokedex_Scene
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]]
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
ht2 = (params[5]<0) ? 99*12 : (ht2/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]]
ht2 = (sel[1]<0) ? 999 : (sel[1]>=@heightCommands.length) ? 0 : @heightCommands[sel[1]]
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
ht2 = (sel[1]<0) ? 99*12 : (ht2/0.254).round
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]]
wt2 = (sel[1]<0) ? 9999 : (sel[1]>=@weightCommands.length) ? 0 : @weightCommands[sel[1]]
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
wt2 = (sel[1]<0) ? 99990 : (wt2/0.254).round
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
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
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.
def getMousePos(catch_anywhere=false)
x, y = screen_to_client(*getMouseGlobalPos)
return nil unless x and 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
return nil unless System.mouse_in_window || catch_anywhere
return Input.mouse_x, Input.mouse_y
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

View File

@@ -48,35 +48,16 @@ def pbEachCombination(array,num)
end while _pbNextComb(currentComb,array.length)
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
def pbGetLanguage()
getUserDefaultLangID = Win32API.new("kernel32","GetUserDefaultLangID","","i") rescue nil
ret = 0
ret = getUserDefaultLangID.call()&0x3FF if getUserDefaultLangID
if ret==0 # Unknown
ret = MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
"Control Panel\\Desktop\\ResourceLocale","",0)
ret = MiniRegistry.get(MiniRegistry::HKEY_CURRENT_USER,
"Control Panel\\International","Locale","0").to_i(16) if ret==0
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
case System.user_language[0..1]
when "ja" then return 1 # Japanese
when "en" then return 2 # English
when "fr" then return 3 # French
when "it" then return 4 # Italian
when "de" then return 5 # German
when "es" then return 7 # Spanish
when "ko" then return 8 # Korean
end
return 2 # Use 'English' by default
end
@@ -131,7 +112,7 @@ end
def getConstantName(mod,value)
mod = Object.const_get(mod) if mod.is_a?(Symbol)
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
raise _INTL("Value {1} not defined by a constant in {2}",value,mod.name)
end
@@ -139,7 +120,7 @@ end
def getConstantNameOrValue(mod,value)
mod = Object.const_get(mod) if mod.is_a?(Symbol)
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
return value.inspect
end
@@ -276,28 +257,13 @@ def pbSuggestTrainerName(gender)
userName[0,1] = userName[0,1].upcase
return userName
end
owner = MiniRegistry.get(MiniRegistry::HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOwner","")
owner = owner.gsub(/\s+.*$/,"")
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)
return System.user_name.capitalize
# Unreachable
#return getRandomNameEx(gender, nil, 1, Settings::MAX_PLAYER_NAME_SIZE)
end
def pbGetUserName
buffersize = 100
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 ""
return System.user_name
end
def getRandomNameEx(type,variable,upper,maxLength=100)

View File

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

View File

@@ -125,12 +125,12 @@ class Button < UIControl
return if !mousepos
rect=Rect.new(self.x+1,self.y+1,self.width-2,self.height-2)
rect=toAbsoluteRect(rect)
if Input.triggerex?(Input::LeftMouseKey) &&
if Input.trigger?(Input::MOUSELEFT) &&
rect.contains(mousepos[0],mousepos[1]) && !@captured
@captured=true
self.invalidate
end
if Input.releaseex?(Input::LeftMouseKey) && @captured
if Input.release?(Input::MOUSELEFT) && @captured
self.changed=true if rect.contains(mousepos[0],mousepos[1])
@captured=false
self.invalidate
@@ -263,7 +263,7 @@ class TextField < UIControl
self.changed=false
self.invalidate if ((@frame%10)==0)
# Moving cursor
if Input.repeat?(Input::LEFT)
if Input.triggerex?(:LEFT) || Input.repeatex?(:LEFT)
if @cursor > 0
@cursor-=1
@frame=0
@@ -271,7 +271,7 @@ class TextField < UIControl
end
return
end
if Input.repeat?(Input::RIGHT)
if Input.triggerex?(:LEFT) || Input.repeatex?(:RIGHT)
if @cursor < self.text.scan(/./m).length
@cursor+=1
@frame=0
@@ -280,50 +280,13 @@ class TextField < UIControl
return
end
# 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
return
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,"[","{"],
[220,"\\","|"],
[221,"]","}"],
[222,"\"","'"]
]
for i in keys
if Input.repeatex?(i[0])
insert((Input.press?(Input::SHIFT)) ? i[2] : i[1])
return
end
end
# Letter & Number keys
Input.gets.each_char{|c|insert(c)}
end
def refresh
@@ -428,17 +391,17 @@ class Slider < UIControl
self.curvalue=self.minvalue
end
return false if self.disabled
return false if !Input.repeatex?(Input::LeftMouseKey)
return false if !Input.repeat?(Input::MOUSELEFT)
return false if !mousepos
left=toAbsoluteRect(@leftarrow)
right=toAbsoluteRect(@rightarrow)
oldvalue=self.curvalue
# Left arrow
if left.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100
if Input.count(Input::MOUSELEFT)>100
self.curvalue-=10
self.curvalue=self.curvalue.floor
elsif Input.repeatcount(Input::LeftMouseKey)>50
elsif Input.count(Input::MOUSELEFT)>50
self.curvalue-=5
self.curvalue=self.curvalue.floor
else
@@ -450,10 +413,10 @@ class Slider < UIControl
end
#Right arrow
if right.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100
if Input.count(Input::MOUSELEFT)>100
self.curvalue+=10
self.curvalue=self.curvalue.floor
elsif Input.repeatcount(Input::LeftMouseKey)>50
elsif Input.count(Input::MOUSELEFT)>50
self.curvalue+=5
self.curvalue=self.curvalue.floor
else
@@ -676,16 +639,16 @@ class TextSlider < UIControl
self.curvalue=self.minvalue
end
return false if self.disabled
return false if !Input.repeatex?(Input::LeftMouseKey)
return false if !Input.repeat?(Input::MOUSELEFT)
return false if !mousepos
left=toAbsoluteRect(@leftarrow)
right=toAbsoluteRect(@rightarrow)
oldvalue=self.curvalue
# Left arrow
if left.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100
if Input.count(Input::MOUSELEFT)>100
self.curvalue-=10
elsif Input.repeatcount(Input::LeftMouseKey)>50
elsif Input.count(Input::MOUSELEFT)>50
self.curvalue-=5
else
self.curvalue-=1
@@ -695,9 +658,9 @@ class TextSlider < UIControl
end
# Right arrow
if right.contains(mousepos[0],mousepos[1])
if Input.repeatcount(Input::LeftMouseKey)>100
if Input.count(Input::MOUSELEFT)>100
self.curvalue+=10
elsif Input.repeatcount(Input::LeftMouseKey)>50
elsif Input.count(Input::MOUSELEFT)>50
self.curvalue+=5
else
self.curvalue+=1

View File

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

View File

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

View File

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

View File

@@ -98,7 +98,7 @@ module Compiler
sectionname = nil
lastsection = {}
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]
end
if !line[/^\#/] && !line[/^\s*$/]
@@ -149,7 +149,7 @@ module Compiler
sectionname = nil
lastsection = []
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]
end
if !line[/^\#/] && !line[/^\s*$/]
@@ -175,7 +175,7 @@ module Compiler
def pbEachCommentedLine(f)
lineno = 1
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]
end
yield line, lineno if !line[/^\#/] && !line[/^\s*$/]
@@ -189,7 +189,7 @@ module Compiler
FileLineData.file = filename
lineno = 1
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]
end
if !line[/^\#/] && !line[/^\s*$/]
@@ -205,7 +205,7 @@ module Compiler
def pbEachPreppedLine(f)
lineno = 1
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]
end
line = prepline(line)
@@ -220,7 +220,7 @@ module Compiler
FileLineData.file = filename
lineno = 1
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]
end
line = prepline(line)
@@ -324,7 +324,7 @@ module Compiler
end
return enumer.const_get(ret.to_sym)
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)
begin
if ret == "" || !enumer.exists?(ret.to_sym)
@@ -730,6 +730,7 @@ module Compiler
convert_files
end
pbSetWindowText(nil)
System.reload_cache
end
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.