#==============================================================================
# ** Bitmap Marshal序列 NRGU Ver
#==============================================================================
class Font
def marshal_dump
end
def marshal_load(obj)
end
end
class Bitmap
def _dump(limit)
data = "\0" * width * height * 4
process_pixel { |pixels| pixels.save_data(data) }
[width, height, Zlib::Deflate.deflate(data)].pack("LLa*")
end
def self._load(str)
w, h, zdata = str.unpack("LLa*")
data = Zlib::Inflate.inflate(zdata)
bmp = self.new(w, h)
bmp.process_pixel { |pixels| pixels.load_data(data) }
return bmp
end
end
#==============================================================================
# ** [RGU] [RGSS1/2/3] 画面分离
#------------------------------------------------------------------------------
# 将游戏画面分离以允许在画面外绘制图像
# Graphics.real_width real_height 为游戏的真实分辨率
# * 此脚本仅限使用RGU的游戏使用
#==============================================================================
module Admenri
# 游戏画面分辨率
SCREEN_WIDTH = 544
SCREEN_HEIGHT = 416
# 窗口分辨率
WINDOW_WIDTH = 900
WINDOW_HEIGHT = 416
end
Graphics.resize_screen(Admenri::WINDOW_WIDTH, Admenri::WINDOW_HEIGHT)
Graphics.resize_window(Admenri::WINDOW_WIDTH, Admenri::WINDOW_HEIGHT)
class << Graphics
alias real_width width
def width
Admenri::SCREEN_WIDTH
end
alias real_height height
def height
Admenri::SCREEN_HEIGHT
end
end
class Viewport
alias ori_initialize initialize
def initialize(*args)
if args.size == 0
ori_initialize(0, 0, Graphics.width, Graphics.height)
else
ori_initialize(*args)
end
end
end
Graphics.set_drawable_offset((Admenri::WINDOW_WIDTH - Admenri::SCREEN_WIDTH) / 2,
(Admenri::WINDOW_HEIGHT - Admenri::SCREEN_HEIGHT) / 2)
#encoding:utf-8
#==============================================================================
# ■ VirtualButton 虚拟触控按钮
#------------------------------------------------------------------------------
# 作者:
# 基础版本:Admenri
# 改良优化:雨之沉默
# 时间: 2024-04-26
#------------------------------------------------------------------------------
# 用于实现适配移动端虚拟按键的触控。此脚本借鉴Admenri的基础脚本截图并进行改良,
# 部分写法参考了Lanziss的虚拟按键脚本。按键代码请参考RGU附录SDL_scancode.h文档,
# 如果使用画面分离脚本,请将此脚本置于其下面。使用请保留此信息。
#==============================================================================
$xyscript ||= {}
$xyscript[:mobile_device] = (RGU::PLATFORM != "Windows") # 触控功能开关。
$view_px = defined?(Graphics.real_width) ? ((Graphics.real_width - Graphics.width) / 2) : 0
$view_py = defined?(Graphics.real_height) ? ((Graphics.real_height - Graphics.height) / 2) : 0
$vbview_width = defined?(Graphics.real_width) ? Graphics.real_width : Graphics.width
$vbview_height = defined?(Graphics.real_height) ? Graphics.real_height : Graphics.height
$vpad_viewport = Viewport.new(-$view_px, -$view_py, $vbview_width, $vbview_height)
$vpad_viewport.z = 65535
module SILENCE_DEFINE
BUTTON_SIZE = 8 # 按键大小,这个值越大,按键越小
BUTTON_POS = 25 # 按键间隔,这个值越大,空隙越小
end
if $xyscript[:mobile_device]
w, h = $vbview_width, $vbview_height
button_size = h / SILENCE_DEFINE::BUTTON_SIZE
kd = h / SILENCE_DEFINE::BUTTON_POS
$vpad_area = {
# 定义方式
# 按键代码 => ["显示名", 矩形,索引值(请从上往下顺序书写),false(触控时高亮显示)],
82 => ["↑", Rect.new(kd * 1 + button_size * 1, h - kd * 5 - button_size * 2, button_size, button_size) ,0, false], # 第一行
80 => ["←", Rect.new(kd * 1 + button_size * 0, h - kd * 5 - button_size * 1, button_size, button_size) ,1, false], # 第二行
79 => ["→", Rect.new(kd * 1 + button_size * 2, h - kd * 5 - button_size * 1, button_size, button_size) ,2, false], # 第二行
81 => ["↓", Rect.new(kd * 1 + button_size * 1, h - kd * 5 - button_size * 0, button_size, button_size) ,3, false], # 第三行
40 => ["Enter", Rect.new(w - kd * 1 - button_size * 1, h - kd * 2 - button_size * 1, button_size, button_size) ,4, false], # 第三行
41 => ["Esc", Rect.new(w - kd * 2 - button_size * 2, h - kd * 2 - button_size * 1, button_size, button_size) ,5, false], # 第三行
7 => ["D", Rect.new(w - kd * 1 - button_size * 1, h - kd * 3 - button_size * 2, button_size, button_size) ,6, false], # 第二行
22 => ["S", Rect.new(w - kd * 2 - button_size * 2, h - kd * 3 - button_size * 2, button_size, button_size) ,7, false], # 第二行
4 => ["A", Rect.new(w - kd * 3 - button_size * 3, h - kd * 3 - button_size * 2, button_size, button_size) ,8, false], # 第二行
26 => ["W", Rect.new(w - kd * 1 - button_size * 1, h - kd * 4 - button_size * 3, button_size, button_size) ,9, false], # 第一行
20 => ["Q", Rect.new(w - kd * 2 - button_size * 2, h - kd * 4 - button_size * 3, button_size, button_size) ,10, false], # 第一行
}
$touch_spr = []
$vpad_area.each do |k, i|
spr = Sprite.new($vpad_viewport)
spr.bitmap = Bitmap.new(button_size, button_size)
spr.bitmap.font.size = 16
spr.bitmap.font.shadow = false
spr.bitmap.fill_rect(0, 0, spr.width, spr.height, Color.new(192,192,192,120))
spr.bitmap.draw_text(0, 0, spr.width, spr.height, i[0], 1)
spr.x = i[1].x
spr.y = i[1].y
spr.opacity = 160
spr.z = 5000
$touch_spr << spr
end
end
#==============================================================================
# ■ Input
#------------------------------------------------------------------------------
# 输入相关
#==============================================================================
class << Input
#--------------------------------------------------------------------------
# ● 判断虚拟按键
#--------------------------------------------------------------------------
def vpad_in_rect(x,y,r)
return x >= r.x && y >= r.y && x <= r.x + r.width && y <= r.y + r.height
end
#--------------------------------------------------------------------------
# ● 刷新(基础)
#--------------------------------------------------------------------------
alias silence_touch_define_input_update update
def update
silence_touch_define_input_update
return unless $xyscript[:mobile_device]
Touch.max_fingers.times do |i|
$vpad_area.each do |k, r|
if vpad_in_rect(Touch.finger_x(i), Touch.finger_y(i), r[1])
r[3] = true
end
$touch_spr[r[2]].opacity = r[3] ? 255 : 160 unless $touch_spr[r[2]].disposed?
Input.emulate(k, r[3])
end
end
$vpad_area.each do |k, r|
r[3] = false
end
end
end
#==============================================================================
# ** AV1视频播放器 (C) 2024 Admenri.
#------------------------------------------------------------------------------
# 替代RGSS3的Theora播放器
# 例:Graphics.play_movie("output_video.webm")
#==============================================================================
class << Graphics
def play_movie(filename)
aom = AOMDecoder.new
aom.load_video(filename)
info = aom.video_info
frame = Bitmap.new(Graphics.width, Graphics.height)
spr = Sprite.new
spr.z = 0xffffff
spr.bitmap = frame
aom.set_state(0)
loop do
aom.update
aom.render(frame)
Graphics.update
Input.update
break if aom.get_state == 3
end
end
end
# -*- ruby -*-
# frozen_string_literal: true
class Win32API
DLL = {}
TYPEMAP = { '0' => Fiddle::Types::VOID, 'S' => Fiddle::Types::VOIDP, 'I' => Fiddle::Types::LONG }
POINTER_TYPE = Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG ? 'q*' : 'l!*'
WIN32_TYPES = 'VPpNnLlIi'
DL_TYPES = '0SSI'
def initialize(dllname, func, import, export = '0')
@proto = [import].join.tr(WIN32_TYPES, DL_TYPES).sub(/^(.)0*$/, '\1')
import = @proto.chars.map { |win_type| TYPEMAP[win_type.tr(WIN32_TYPES, DL_TYPES)] }
export = TYPEMAP[export.tr(WIN32_TYPES, DL_TYPES)]
handle = DLL[dllname] ||=
begin
Fiddle::Handle.new(dllname)
rescue Fiddle::DLError
raise unless File.extname(dllname).empty?
Fiddle::Handle.new(dllname + '.dll')
end
@func = Fiddle::Function.new(handle[func], import, export)
rescue Fiddle::DLError => e
raise LoadError, e.message, e.backtrace
end
def call(*args)
import = @proto.split('')
args.each_with_index do |x, i|
args, = [x == 0 ? nil : x].pack('p').unpack(POINTER_TYPE) if import == 'S'
args, = [x].pack('I').unpack('i') if import == 'I'
end
ret, = @func.call(*args)
ret || 0
end
alias Call call
end
#==============================================================================
# ** Pack scripts to iseq (C) 2024 Admenri.
#------------------------------------------------------------------------------
# 适用于加密脚本文本,仅支持Ruby2.5.0及以上的Runtime
# 警告:输出的脚本不可逆,请做好脚本备份
#==============================================================================
# 要转换成字节码的脚本文件
input_scripts = "Scripts.rvdata2"
scripts_list = load_data(input_scripts)
iseq_list = []
scripts_list.each do |item|
script_text = Zlib::Inflate.inflate(item[2].force_encoding("utf-8"))
script_iseq = RubyVM::InstructionSequence.compile(script_text)
iseq_list << script_iseq.to_binary
end
save_data(iseq_list, input_scripts + ".iseq")
#==============================================================================
# ** Load iseq scripts (C) 2024 Admenri.
#------------------------------------------------------------------------------
# 读取字节码Ruby脚本,仅支持Ruby2.5.0及以上的Runtime
#==============================================================================
iseq_file = "Scripts.rvdata2.iseq"
iseq_list = load_data(iseq_file)
iseq_list.each do |iseq|
iseq = RubyVM::InstructionSequence.load_from_binary(iseq)
iseq.eval
end