# 前提 ユニバーサルマウス
# ユニバーサルマウスより下
# フルスクリーン時に切り替え無効にした。
# タイトル名によっては.encode('SHIFT_JIS')に失敗するのでハンドルはユニバーサルマウスのものを参照
# 保存先をINIファイルに変更
#******************************************************************************
#
# * エセフルスクリーン
#
# --------------------------------------------------------------------------
# バージョン : 1.0.2
# 対 応 : RPGツクールVX : RGSS2
# 制 作 者 : CACAO
# 配 布 元 : http://cacaosoft.webcrow.jp/
# --------------------------------------------------------------------------
# == 概 要 ==
#
# : ウィンドウのサイズを変更する機能を追加します。
#
# --------------------------------------------------------------------------
# == 使用方法 ==
#
# ★ WLIB::SetGameWindowSize(width, height)
# ウィンドウを中央に移動し、指定されたサイズに変更します。
# 引数が負数、もしくはデスクトップより大きい場合はフルサイズで表示されます。
# 処理が失敗すると false を返します。
#
#
#******************************************************************************
#==============================================================================
# ◆ ユーザー設定
#==============================================================================
module WND_SIZE
#--------------------------------------------------------------------------
# ◇ サイズ変更キー
#--------------------------------------------------------------------------
# nil .. サイズ変更を行わない
#--------------------------------------------------------------------------
INPUT_KEY = :F5
#--------------------------------------------------------------------------
# ◇ サイズリスト
#--------------------------------------------------------------------------
# [ [横幅, 縦幅], ... ] のような二次元配列で設定します。
# 幅を 0 にするとデスクトップサイズになります。
#--------------------------------------------------------------------------
SIZE_LIST = [ [1280,704],[1540,847],[1800,990],[1920,1056],[2560,1408],[3840,2112],[1220,671],[1200,660],[1160,638],[1120,616],[960,528],[780,429],[640,352] ]
#--------------------------------------------------------------------------
# ◇ セーブファイル
#--------------------------------------------------------------------------
# ウィンドウサイズの状況を保存するファイル名を設定します。
# nil にすると、サイズを保存しません。
#--------------------------------------------------------------------------
FILE_SAVE = nil#"System/wndsz.rvdata2"
#--------------------------------------------------------------------------
# ◇ 構成設定ファイル
#--------------------------------------------------------------------------
# セクション名 [Graphics] キー Width=横幅 Height=縦幅 を読み込みます。
# nil にすると、サイズを保存しません。
#--------------------------------------------------------------------------
FILE_INI = "./Game.ini"
end
#/////////////////////////////////////////////////////////////////////////////#
# #
# 下記のスクリプトを変更する必要はありません。 #
# #
#/////////////////////////////////////////////////////////////////////////////#
module WLIB
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
# SystemMetrics
SM_CYCAPTION = 0x04 # タイトルバーの高さ
SM_CXDLGFRAME = 0x07 # 枠の幅
SM_CYDLGFRAME = 0x08 # 枠の高さ
# SetWindowPos
SWP_NOSIZE = 0x01 # サイズ変更なし
SWP_NOMOVE = 0x02 # 位置変更なし
SWP_NOZORDER = 0x04 # 並び変更なし
#--------------------------------------------------------------------------
# ● Win32API
#--------------------------------------------------------------------------
@@FindWindow =
Win32API.new('user32', 'FindWindow', 'pp', 'l')
@@GetDesktopWindow =
Win32API.new('user32', 'GetDesktopWindow', 'v', 'l')
@@SetWindowPos =
Win32API.new('user32', 'SetWindowPos', 'lliiiii', 'i')
@@GetClientRect =
Win32API.new('user32', 'GetClientRect', 'lp', 'i')
@@GetWindowRect =
Win32API.new('user32', 'GetWindowRect', 'lp', 'i')
@@GetWindowLong =
Win32API.new('user32', 'GetWindowLong', 'li', 'l')
@@GetSystemMetrics =
Win32API.new('user32', 'GetSystemMetrics', 'i', 'i')
@@SystemParametersInfo =
Win32API.new('user32', 'SystemParametersInfo', 'iipi', 'i')
#--------------------------------------------------------------------------
# ● ウィンドウの情報
#--------------------------------------------------------------------------
# GAME_TITLE = load_data("Data/System.rvdata2").game_title.encode('SHIFT_JIS')
# GAME_HANDLE = @@FindWindow.call("RGSS Player", GAME_TITLE)
GAME_HANDLE = InputMouse::WindowHandle # ユニバーサルマウスの結果を参照
if GAME_HANDLE == 0
GAME_HANDLE = @@FindWindow.call('RGSS Player', nil)
end
if GAME_HANDLE == 0
GAME_HANDLE = Win32API.new('user32', 'GetForegroundWindow', 'v', 'l').call
end
GAME_STYLE = @@GetWindowLong.call(GAME_HANDLE, -16)
GAME_EXSTYLE = @@GetWindowLong.call(GAME_HANDLE, -20)
HDSK = @@GetDesktopWindow.call
module_function
#--------------------------------------------------------------------------
# ● GetWindowRect
#--------------------------------------------------------------------------
def GetWindowRect(hwnd)
r = [0,0,0,0].pack('l4')
if @@GetWindowRect.call(hwnd, r) != 0
result = Rect.new(*r.unpack('l4'))
result.width -= result.x
result.height -= result.y
else
result = nil
end
return result
end
#--------------------------------------------------------------------------
# ● GetClientRect
#--------------------------------------------------------------------------
def GetClientRect(hwnd)
r = [0,0,0,0].pack('l4')
if @@GetClientRect.call(hwnd, r) != 0
result = Rect.new(*r.unpack('l4'))
else
result = nil
end
return result
end
#--------------------------------------------------------------------------
# ● GetSystemMetrics
#--------------------------------------------------------------------------
def GetSystemMetrics(index)
@@GetSystemMetrics.call(index)
end
#--------------------------------------------------------------------------
# ● SetWindowPos
#--------------------------------------------------------------------------
def SetWindowPos(hwnd, x, y, width, height, z, flag)
@@SetWindowPos.call(hwnd, z, x, y, width, height, flag) != 0
end
#--------------------------------------------------------------------------
# ● ウィンドウのサイズを取得
#--------------------------------------------------------------------------
def GetGameWindowRect
GetWindowRect(GAME_HANDLE)
end
#--------------------------------------------------------------------------
# ● ウィンドウのクライアントサイズを取得
#--------------------------------------------------------------------------
def GetGameClientRect
GetClientRect(GAME_HANDLE)
end
#--------------------------------------------------------------------------
# ● デスクトップのサイズを取得
#--------------------------------------------------------------------------
def GetDesktopRect
r = [0,0,0,0].pack('l4')
if @@SystemParametersInfo.call(0x30, 0, r, 0) != 0
result = Rect.new(*r.unpack('l4'))
result.width -= result.x
result.height -= result.y
else
result = nil
end
return result
end
#--------------------------------------------------------------------------
# ● ウィンドウのフレームサイズを取得
#--------------------------------------------------------------------------
def GetFrameSize
return [
GetSystemMetrics(SM_CYCAPTION), # タイトルバー
GetSystemMetrics(SM_CXDLGFRAME), # 左右フレーム
GetSystemMetrics(SM_CYDLGFRAME) # 上下フレーム
]
end
#--------------------------------------------------------------------------
# ● ウィンドウの位置を変更
#--------------------------------------------------------------------------
def MoveGameWindow(x, y)
SetWindowPos(GAME_HANDLE, x, y, 0, 0, 0, SWP_NOSIZE|SWP_NOZORDER)
end
#--------------------------------------------------------------------------
# ● ウィンドウの位置を中央へ
#--------------------------------------------------------------------------
def MoveGameWindowCenter
dr = GetDesktopRect()
wr = GetGameWindowRect()
x = (dr.width - wr.width) / 2
y = (dr.height - wr.height) / 2
SetWindowPos(GAME_HANDLE, x, y, 0, 0, 0, SWP_NOSIZE|SWP_NOZORDER)
end
#--------------------------------------------------------------------------
# ● ウィンドウのサイズを変更
#--------------------------------------------------------------------------
def SetGameWindowSize(width, height)
# 各領域の取得
dr = GetDesktopRect() # Rect デスクトップ
wr = GetGameWindowRect() # Rect ウィンドウ
cr = GetGameClientRect() # Rect クライアント
return false unless dr && wr && cr
# フレームサイズの取得
frame = GetFrameSize()
ft = frame[0] + frame[2] # タイトルバーの縦幅
fl = frame[1] # 左フレームの横幅
fs = frame[1] * 2 # 左右フレームの横幅
fb = frame[2] # 下フレームの縦幅
if width <= 0 || height <= 0 || width >= dr.width || height >= dr.height
w = dr.width + fs
h = dr.height + ft + fb
SetWindowPos(GAME_HANDLE, -fl, -ft, w, h, 0, SWP_NOZORDER)
else
w = width + fs
h = height + ft + fb
SetWindowPos(GAME_HANDLE, 0, 0, w, h, 0, SWP_NOMOVE|SWP_NOZORDER)
MoveGameWindowCenter()
end
end
#--------------------------------------------------------------------------
# ○ 画面サイズの変更を知らせるスプライトに表示する内容を取得
#--------------------------------------------------------------------------
def GetWindowSizeName
wh = WND_SIZE::SIZE_LIST[Scene_Base.screen_mode]
return "화면 크기(#{wh[0]}x#{wh[1]}):#{wh[0] * 100 / Graphics.width}%"
end
end
module Graphics
#--------------------------------------------------------------------------
# ● alias
#--------------------------------------------------------------------------
class << self
unless $!
alias :__Sprite_WindowSize__snap_to_bitmap :snap_to_bitmap
end
end
#--------------------------------------------------------------------------
# ● 現在の画面のビットマップを取得
#--------------------------------------------------------------------------
def self.snap_to_bitmap
sprite = Scene_Base.sprite_window_size
if sprite && !sprite.disposed?
temp = sprite.visible
sprite.visible = false
end
bitmap = __Sprite_WindowSize__snap_to_bitmap
sprite.visible = temp if sprite && !sprite.disposed?
return bitmap
end
end
#==============================================================================
# ■ Sprite_WindowSize
#------------------------------------------------------------------------------
# 画面サイズの変更を知らせるスプライトです。
#==============================================================================
class Sprite_WindowSize < Sprite
#--------------------------------------------------------------------------
# ○ オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
super
wh = WND_SIZE::SIZE_LIST[Scene_Base.screen_mode]
@name = "화면 크기(#{wh[0]}x#{wh[1]}):100%"
@name2 = "크기 변경 [F5] Key"
@count = 1000
self.z = 9998
self.visible = false
self.opacity = 255
create_bitmap
end
#--------------------------------------------------------------------------
# ○ ビットマップの生成
#--------------------------------------------------------------------------
def create_bitmap
self.bitmap = Bitmap.new(700, 120) if !self.bitmap || self.bitmap.disposed?
self.bitmap.clear
self.bitmap.font.size = 72
h = self.bitmap.font.size
self.bitmap.draw_text(0, 0, self.bitmap.width, h, @name, 2)
self.bitmap.font.size = 36
self.bitmap.draw_text(0, h, self.bitmap.width, self.bitmap.height - h, @name2, 2)
end
#--------------------------------------------------------------------------
# ○ 解放
#--------------------------------------------------------------------------
def dispose
unless self.bitmap && !self.bitmap.disposed?
self.bitmap.dispose
self.bitmap = nil
end
super
end
#--------------------------------------------------------------------------
# ○ フレーム更新
#--------------------------------------------------------------------------
def update
super
update_bitmap
self.x = Graphics.width - self.width - 12
self.visible = @count < 180
@count += 1
self.visible = false if InputMouse.fullscreen?
end
#--------------------------------------------------------------------------
# ○ ビットマップの更新
#--------------------------------------------------------------------------
def update_bitmap
unless @name == WLIB.GetWindowSizeName
@name = WLIB.GetWindowSizeName
create_bitmap
@count = 0
end
end
end
class Scene_Base
#--------------------------------------------------------------------------
# ●
#--------------------------------------------------------------------------
@@screen_mode = 0
@@sprite_window_size = nil
#--------------------------------------------------------------------------
# ●
#--------------------------------------------------------------------------
def self.sprite_window_size
@@sprite_window_size
end
#--------------------------------------------------------------------------
# ●
#--------------------------------------------------------------------------
def self.screen_mode=(index)
@@screen_mode = index % WND_SIZE::SIZE_LIST.size
end
#--------------------------------------------------------------------------
# ●
#--------------------------------------------------------------------------
def self.screen_mode
@@screen_mode
end
#--------------------------------------------------------------------------
# ○ フレーム更新
#--------------------------------------------------------------------------
alias _cao_update_wndsize update
def update
_cao_update_wndsize
if Input.trigger?(WND_SIZE::INPUT_KEY) && WLIB::GAME_HANDLE != 0
if !InputMouse.fullscreen? # 変更点
Scene_Base.screen_mode += 1
if WLIB::SetGameWindowSize(*WND_SIZE::SIZE_LIST[@@screen_mode])
WND_SIZE.save_size # 変更点
else
Sound.play_buzzer
end
end
end
if !@@sprite_window_size || @@sprite_window_size.disposed?
@@sprite_window_size = Sprite_WindowSize.new
end
@@sprite_window_size.update
end
end
module WND_SIZE
#--------------------------------------------------------------------------
# ○ API
#--------------------------------------------------------------------------
GetPrivateProfileInt = Win32API.new('kernel32', 'GetPrivateProfileInt', %w(p p i p), 'i')
WritePrivateProfileString = Win32API.new('kernel32', 'WritePrivateProfileString', %w(p p p p), 'i')
class Ini
def self.load(section, key)
result = WND_SIZE::GetPrivateProfileInt.call(section, key, -1, WND_SIZE::FILE_INI).to_i
return result >= 0 ? result : nil
end
def self.save(section, key, value)
WND_SIZE::WritePrivateProfileString.call(section, key, value.to_i.to_s, WND_SIZE::FILE_INI) != 0
end
end
#--------------------------------------------------------------------------
# ○ セーブ処理
#--------------------------------------------------------------------------
def self.save_size
if WND_SIZE::FILE_SAVE
save_data(Scene_Base.screen_mode, WND_SIZE::FILE_SAVE)
elsif WND_SIZE::FILE_INI
WND_SIZE::Ini.save('Graphics', 'Width', WND_SIZE::SIZE_LIST[Scene_Base.screen_mode][0])
WND_SIZE::Ini.save('Graphics', 'Height', WND_SIZE::SIZE_LIST[Scene_Base.screen_mode][1])
end
end
#--------------------------------------------------------------------------
# ● 大きいサイズを除去
#--------------------------------------------------------------------------
def self.remove_large_window
# 変更点
w = Graphics.monitor_width
h = Graphics.monitor_height
WND_SIZE::SIZE_LIST.reject! do |wsz|
next false if WND_SIZE::SIZE_LIST[0] == wsz # 初期値は絶対に除外しない
next wsz.size != 2 || w < wsz[0] || h < wsz[1]
end
# dr = WLIB::GetDesktopRect()
# WND_SIZE::SIZE_LIST.reject! do |wsz|
# wsz.size != 2 || dr.width < wsz[0] || dr.height < wsz[1]
# end
if WND_SIZE::SIZE_LIST.empty?
WND_SIZE::SIZE_LIST << [Graphics.width, Graphics.height]
end
end
#--------------------------------------------------------------------------
# ● 初期サイズの設定
#--------------------------------------------------------------------------
def self.init_window_size
if WND_SIZE::FILE_SAVE && File.file?(WND_SIZE::FILE_SAVE)
# 前回のサイズを復元
Scene_Base.screen_mode = load_data(WND_SIZE::FILE_SAVE)
WLIB::SetGameWindowSize(*WND_SIZE::SIZE_LIST[Scene_Base.screen_mode])
elsif WND_SIZE::FILE_INI
w = WND_SIZE::Ini.load('Graphics', 'Width') || WND_SIZE::SIZE_LIST[0][0]
h = WND_SIZE::Ini.load('Graphics', 'Height') || WND_SIZE::SIZE_LIST[0][1]
mode = WND_SIZE::SIZE_LIST.index([w, h]) || 0
Scene_Base.screen_mode = mode
WLIB::SetGameWindowSize(*WND_SIZE::SIZE_LIST[Scene_Base.screen_mode])
# 構成設定からサイズを読み込む (サイズを記録していない場合のみ)
# width = IniFile.read(WND_SIZE::FILE_INI, "Window", "WIDTH", "")
# height = IniFile.read(WND_SIZE::FILE_INI, "Window", "HEIGHT", "")
# if width != "" && height != ""
# WLIB::SetGameWindowSize(width.to_i, height.to_i)
# end
end
end
end
WND_SIZE.remove_large_window
WND_SIZE.init_window_size
#==============================================================================
# ★ RGSS3-Extension
# LNX25_ゲーム画面倍率切替 - 멀티 모니터 대응 개선판
# 게임 중 F5 키로 화면 배율 전환 + 현재 모니터 기준 중앙 정렬
#
# version : 1.02 (개선판)
# author : ももまる + Grok 수정
#==============================================================================
module LNX25
MAX_SCREEN_ZOOM = 0 # 0: 자동, 1 이상: 최대 배율 제한
RESIZE_KEY = :F5
end
$lnx_include = {} if $lnx_include == nil
$lnx_include[:lnx25] = 102
p "OK:LNX25_ウィンドウサイズ変更 (Multi-Monitor Support)"
#==============================================================================
# ■ Graphics
#==============================================================================
module Graphics
@screen_zoom = 1
def self.screen_zoom
@screen_zoom
end
def self.screen_zoom=(rate)
max = LNX25::MAX_SCREEN_ZOOM == 0 ? self.max_screen_zoom : LNX25::MAX_SCREEN_ZOOM - 1
if rate - 1 > max.truncate
rate = 1
end
self.rgssplayer_resize(rate)
@screen_zoom = rate
end
#--------------------------------------------------------------------------
# ● 창 프레임 크기 (기존 그대로)
#--------------------------------------------------------------------------
def self.window_frame_size
get_sm = Win32API.new("user32", "GetSystemMetrics", "i", "i")
frame_width = get_sm.call(7) * 2
frame_height = get_sm.call(8) * 2
caption_height = get_sm.call(4)
[frame_width, frame_height, caption_height]
end
#--------------------------------------------------------------------------
# ● 현재 창이 속한 모니터의 Workarea 가져오기 (개선 핵심)
#--------------------------------------------------------------------------
def self.current_monitor_workarea
# 창 핸들 얻기
find_window = Win32API.new("user32", "FindWindow", "pp", "i")
hwnd = find_window.call("RGSS Player", 0)
# 현재 창 RECT 얻기
get_rect = Win32API.new("user32", "GetWindowRect", "lp", "i")
rect = " " * 4
get_rect.call(hwnd, rect)
left, top, right, bottom = rect.unpack('l4')
# MonitorFromRect 호출 (RECT가 속한 모니터 찾기)
monitor_from_rect = Win32API.new("user32", "MonitorFromRect", "pi", "i")
hmonitor = monitor_from_rect.call(rect, 2) # MONITOR_DEFAULTTONEAREST = 2
# GetMonitorInfo 호출
get_monitor_info = Win32API.new("user32", "GetMonitorInfoA", "lp", "i")
mi = [40, 0, 0, 0, 0, 0, 0, 0, 0, 0].pack('l*') + "\0" * 32 # MONITORINFO 구조체 (cbSize=40)
get_monitor_info.call(hmonitor, mi)
# rcWork 부분 추출 (offset 20부터 16바이트)
work_left, work_top, work_right, work_bottom = mi[20, 16].unpack('l4')
# workarea 너비, 높이, 좌상단 좌표 반환
[work_left, work_top, work_right - work_left, work_bottom - work_top]
end
#--------------------------------------------------------------------------
# ● 윈도우 리사이즈 (멀티 모니터 대응)
#--------------------------------------------------------------------------
def self.rgssplayer_resize(rate)
wfs = self.window_frame_size
rate = [rate, self.max_screen_zoom].min
new_width = (self.width * rate).to_i + wfs[0]
new_height = (self.height * rate).to_i + wfs[1] + wfs[2]
# 현재 모니터의 workarea 가져오기
work = current_monitor_workarea
work_x, work_y, work_w, work_h = work
# 해당 모니터 중앙에 위치 계산
x = work_x + (work_w - new_width) / 2
y = work_y + (work_h - new_height) / 2
# 창 이동
move_w = Win32API.new("user32", "MoveWindow", "liiiil", "l")
h = Win32API.new("user32", "FindWindow", "pp", "i").call("RGSS Player", 0)
move_w.call(h, x, y, new_width, new_height, 1)
end
#--------------------------------------------------------------------------
# ● 최대 배율 계산 (전체 가상 스크린 기준으로 유지 - 기존 로직 활용)
#--------------------------------------------------------------------------
def self.max_screen_zoom
wfs = self.window_frame_size
# 전체 가상 스크린 크기 (멀티 모니터 전체)
sm = Win32API.new("user32", "GetSystemMetrics", "i", "i")
virt_w = sm.call(78) # SM_CXVIRTUALSCREEN
virt_h = sm.call(79) # SM_CYVIRTUALSCREEN
max_zoom_w = [virt_w.to_f / self.width - wfs[0].to_f / self.width, 1].max
max_zoom_h = [virt_h.to_f / self.height - (wfs[1] + wfs[2]).to_f / self.height, 1].max
[max_zoom_w, max_zoom_h].min
end
# display_workarea는 더 이상 사용하지 않음 (호환성을 위해 남겨둠)
def self.display_workarea
current_monitor_workarea
end
end
class << Graphics
alias :lnx25_update :update
def update
lnx25_update
if Input.trigger?(LNX25::RESIZE_KEY)
self.screen_zoom += 1
end
end
end
화면 크기 변경 스크립트 교체, 폰트에 글리프 하나 추가
번역 상태로 보아 자주 나올 거 같아서 폰트에 추가했음
