dynamic resolution

This commit is contained in:
Issac332 2026-07-14 18:03:52 +03:00
parent 1ddacce66e
commit 319e17d711
18 changed files with 152 additions and 39 deletions

View file

@ -173,9 +173,10 @@ RB_METHOD(graphicsResizeScreen){
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
int width, height; int width, height;
rb_get_args(argc, argv, "ii", &width, &height RB_ARG_END); bool emitSignal = true;
rb_get_args(argc, argv, "ii|b", &width, &height, &emitSignal RB_ARG_END);
shState->graphics().resizeScreen(width, height); shState->graphics().resizeScreen(width, height, emitSignal);
return Qnil; return Qnil;
} }
@ -218,6 +219,11 @@ static VALUE graphicsWindowMoved(VALUE self){
RUBY_CONNECTION RUBY_CONNECTION
conn->connection = shState->windowSignals.moved.Connect([conn](int x, int y){ conn->connection = shState->windowSignals.moved.Connect([conn](int x, int y){
shState->rubyDispatcher().invoke([conn, x, y]{ shState->rubyDispatcher().invoke([conn, x, y]{
if (NIL_P(conn->proc)){
Debug() << "Unable to call non-existent proc! (Graphics.window_moved connection, disconnecting)";
conn->connection.Disconnect();
return;
}
rb_funcall(conn->proc, rb_intern("call"), 2, INT2NUM(x), INT2NUM(y)); rb_funcall(conn->proc, rb_intern("call"), 2, INT2NUM(x), INT2NUM(y));
}); });
}); });
@ -228,12 +234,32 @@ static VALUE graphicsWindowResized(VALUE self){
RUBY_CONNECTION RUBY_CONNECTION
conn->connection = shState->windowSignals.resized.Connect([conn](int w, int h){ conn->connection = shState->windowSignals.resized.Connect([conn](int w, int h){
shState->rubyDispatcher().invoke([conn, w, h]{ shState->rubyDispatcher().invoke([conn, w, h]{
if (NIL_P(conn->proc)){
Debug() << "Unable to call non-existent proc! (Graphics.window_resized connection, disconnecting)";
conn->connection.Disconnect();
return;
}
rb_funcall(conn->proc, rb_intern("call"), 2, INT2NUM(w), INT2NUM(h)); rb_funcall(conn->proc, rb_intern("call"), 2, INT2NUM(w), INT2NUM(h));
}); });
}); });
return TypedData_Wrap_Struct(rb_cRubyConnection, &rubyConnection_type, conn); return TypedData_Wrap_Struct(rb_cRubyConnection, &rubyConnection_type, conn);
} }
static VALUE graphicsViewportResized(VALUE self){
RUBY_CONNECTION
conn->connection = shState->graphicsSignals.resized.Connect([conn](int w, int h){
//shState->rubyDispatcher().invoke([conn, w, h]{
if (NIL_P(conn->proc)){
Debug() << "Unable to call non-existent proc! (Graphics.viewport_resized connection, disconnecting)";
conn->connection.Disconnect();
return;
}
rb_funcall(conn->proc, rb_intern("call"), 2, INT2NUM(w), INT2NUM(h));
//});
});
return TypedData_Wrap_Struct(rb_cRubyConnection, &rubyConnection_type, conn);
}
void graphicsBindingInit(){ void graphicsBindingInit(){
VALUE module = rb_define_module("Graphics"); VALUE module = rb_define_module("Graphics");
@ -241,6 +267,7 @@ void graphicsBindingInit(){
rb_define_module_function(module, "window_moved", RUBY_METHOD_FUNC(graphicsWindowMoved), 0); rb_define_module_function(module, "window_moved", RUBY_METHOD_FUNC(graphicsWindowMoved), 0);
rb_define_module_function(module, "window_resized", RUBY_METHOD_FUNC(graphicsWindowResized), 0); rb_define_module_function(module, "window_resized", RUBY_METHOD_FUNC(graphicsWindowResized), 0);
rb_define_module_function(module, "viewport_resized", RUBY_METHOD_FUNC(graphicsViewportResized), 0);
// Functions // Functions
_rb_define_module_function(module, "x", graphicsPosX); _rb_define_module_function(module, "x", graphicsPosX);

View file

@ -92,6 +92,13 @@ RB_METHOD(oneshotCRC32){
return UINT2NUM(result.checksum()); return UINT2NUM(result.checksum());
} }
static VALUE oneshotSetObscuredUpdating(VALUE self, VALUE rb_bool){
bool value;
rb_bool_arg(rb_bool, &value);
shState->oneshot().setObscuredUpdating(value);
return Qnil;
}
void oneshotBindingInit(){ void oneshotBindingInit(){
VALUE module = rb_define_module("Oneshot"); VALUE module = rb_define_module("Oneshot");
VALUE msg = rb_define_module_under(module, "Msg"); VALUE msg = rb_define_module_under(module, "Msg");
@ -122,4 +129,6 @@ void oneshotBindingInit(){
_rb_define_module_function(module, "exiting", oneshotExiting); _rb_define_module_function(module, "exiting", oneshotExiting);
_rb_define_module_function(module, "shake", oneshotShake); _rb_define_module_function(module, "shake", oneshotShake);
_rb_define_module_function(module, "crc32", oneshotCRC32); _rb_define_module_function(module, "crc32", oneshotCRC32);
rb_define_module_function(module, "obscured_updating=", RUBY_METHOD_FUNC(oneshotSetObscuredUpdating), 1);
} }

View file

@ -62,4 +62,6 @@ SecurityManager can detect Flatpak and Snap now
Added 3:2 support Added 3:2 support
Modloader settings Modloader settings
supported gamepads can now change LED color based on map supported gamepads can now change LED color based on map
sigc is wrapped in signal.h, added the ability to move window from ruby sigc is wrapped in signal.h, added the ability to move window from ruby
main viewport resize, main window resize and move signals bindings for ruby
Dynamic resolution support (WIP)

View file

@ -37,7 +37,6 @@ class Window_Settings
@selection_sprite.bitmap.fill_rect(Rect.new(0, 0, PARAMETER_WIDTH + 16, PARAMETER_HEIGHT), Color.new(255, 255, 255, 64)) @selection_sprite.bitmap.fill_rect(Rect.new(0, 0, PARAMETER_WIDTH + 16, PARAMETER_HEIGHT), Color.new(255, 255, 255, 64))
@selection_sprite.x = @x - 8 @selection_sprite.x = @x - 8
@selection_sprite.y = @offset @selection_sprite.y = @offset
@selection_sprite.opacity = 0
@selection_sprite.blend_type = 1 @selection_sprite.blend_type = 1
@selection_sprite.z = 1 @selection_sprite.z = 1
@ -82,6 +81,8 @@ class Window_Settings
@screen_panels.each do |screen_panel| @screen_panels.each do |screen_panel|
screen_panel.dispose screen_panel.dispose
end end
@switch_panels_hint_left.dispose
@switch_panels_hint_right.dispose
end end
# registering # registering

View file

@ -16,7 +16,7 @@ class DynamicLight
# end # end
#end #end
@update_connection = Graphics.window_resized do |w, h| @update_connection = Graphics.viewport_resized do |w, h|
@debug_sprite.bitmap.rect.width = w; @debug_sprite.bitmap.rect.width = w;
@debug_sprite.bitmap.rect.height = h; @debug_sprite.bitmap.rect.height = h;
#@debug_sprite.bitmap.dispose #@debug_sprite.bitmap.dispose

View file

@ -9,11 +9,11 @@
class Game_Player < Game_Character class Game_Player < Game_Character
attr_reader :move_speed attr_reader :move_speed
#-------------------------------------------------------------------------- def initialize
# * Invariables @center_x = ((Graphics.width / 2) - 16) * 4 # Center screen x-coordinate * 4
#-------------------------------------------------------------------------- @center_y = ((Graphics.height / 2) - 16) * 4 # Center screen y-coordinate * 4
CENTER_X = ((Graphics.width / 2) - 16) * 4 # Center screen x-coordinate * 4 super
CENTER_Y = ((Graphics.height / 2) - 16) * 4 # Center screen y-coordinate * 4 end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Passable Determinants # * Passable Determinants
# x : x-coordinate # x : x-coordinate
@ -41,8 +41,8 @@ class Game_Player < Game_Character
def center(x, y) def center(x, y)
max_x = ($game_map.width - (Graphics.width / 32)) * 128 max_x = ($game_map.width - (Graphics.width / 32)) * 128
max_y = ($game_map.height - (Graphics.height / 28)) * 128 max_y = ($game_map.height - (Graphics.height / 28)) * 128
$game_map.display_x = [0, [x * 128 - CENTER_X, max_x].min].max $game_map.display_x = [0, [x * 128 - @center_x, max_x].min].max
$game_map.display_y = [0, [y * 128 - CENTER_Y, max_y].min].max $game_map.display_y = [0, [y * 128 - @center_y, max_y].min].max
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# * Move to Designated Position # * Move to Designated Position
@ -164,6 +164,16 @@ class Game_Player < Game_Character
# * Frame Update # * Frame Update
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def update def update
old_center_x = @center_x
old_center_y = @center_y
@center_x = ((Graphics.width / 2) - 16) * 4 # Center screen x-coordinate * 4
@center_y = ((Graphics.height / 2) - 16) * 4 # Center screen y-coordinate * 4
if (@center_x != old_center_x)
$game_map.display_x = @real_x - @center_x
end
if (@center_y != old_center_y)
$game_map.display_y = @real_y - @center_y
end
# Remember whether or not moving in local variables # Remember whether or not moving in local variables
last_moving = moving? last_moving = moving?
# If moving, event running, move route forcing, and message window # If moving, event running, move route forcing, and message window
@ -217,25 +227,25 @@ class Game_Player < Game_Character
if !$game_switches[100] if !$game_switches[100]
# If character moves down and is positioned lower than the center # If character moves down and is positioned lower than the center
# of the screen # of the screen
if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y if @real_y > last_real_y and @real_y - $game_map.display_y > @center_y
# Scroll map down # Scroll map down
$game_map.scroll_down(@real_y - last_real_y) $game_map.scroll_down(@real_y - last_real_y)
end end
# If character moves left and is positioned more let on-screen than # If character moves left and is positioned more let on-screen than
# center # center
if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X if @real_x < last_real_x and @real_x - $game_map.display_x < @center_x
# Scroll map left # Scroll map left
$game_map.scroll_left(last_real_x - @real_x) $game_map.scroll_left(last_real_x - @real_x)
end end
# If character moves right and is positioned more right on-screen than # If character moves right and is positioned more right on-screen than
# center # center
if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X if @real_x > last_real_x and @real_x - $game_map.display_x > @center_x
# Scroll map right # Scroll map right
$game_map.scroll_right(@real_x - last_real_x) $game_map.scroll_right(@real_x - last_real_x)
end end
# If character moves up and is positioned higher than the center # If character moves up and is positioned higher than the center
# of the screen # of the screen
if @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y if @real_y < last_real_y and @real_y - $game_map.display_y < @center_y
# Scroll map up # Scroll map up
$game_map.scroll_up(last_real_y - @real_y) $game_map.scroll_up(last_real_y - @real_y)
end end

View file

@ -6,9 +6,11 @@ def film_puzzle_begin
filmsprite.z = 9999 filmsprite.z = 9999
filmsprite.obscured = true filmsprite.obscured = true
$game_temp.filmsprite = filmsprite $game_temp.filmsprite = filmsprite
Oneshot.obscured_updating = true
end end
def film_puzzle_end def film_puzzle_end
Oneshot.obscured_updating = false
$game_temp.filmsprite.dispose if $game_temp.filmsprite $game_temp.filmsprite.dispose if $game_temp.filmsprite
$game_temp.filmsprite = nil $game_temp.filmsprite = nil
end end

View file

@ -19,7 +19,7 @@ class Spriteset_Map
@viewport_lights = Viewport.new(0, 0, Graphics.width, Graphics.height) @viewport_lights = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport_flash = Viewport.new(0, 0, Graphics.width, Graphics.height) @viewport_flash = Viewport.new(0, 0, Graphics.width, Graphics.height)
@update_connection = Graphics.window_resized do |w, h| @update_connection = Graphics.viewport_resized do |w, h|
@viewport.rect.width = w @viewport.rect.width = w
@viewport.rect.height = h @viewport.rect.height = h

View file

@ -15,6 +15,12 @@ class Window_Help < Window_Base
self.visible = false self.visible = false
self.back_opacity = 230 self.back_opacity = 230
self.z = 9998 self.z = 9998
@update_connection = Graphics.viewport_resized do |w, h|
self.x = Graphics.width / 2 - 304
self.y = Graphics.height > 600 ? Graphics.height / 2 - 160 : 16
end
RPG::Mod.exec_hooks("hooks/Window_Help/init", binding) RPG::Mod.exec_hooks("hooks/Window_Help/init", binding)
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
@ -31,4 +37,9 @@ class Window_Help < Window_Base
@align = align @align = align
@actor = nil @actor = nil
end end
def dispose
super
@update_connection.disconnect
end
end end

View file

@ -20,6 +20,10 @@ class Window_Item < Window_Selectable
self.z = 9998 self.z = 9998
self.visible = false self.visible = false
self.active = false self.active = false
@update_connection = Graphics.viewport_resized do |w, h|
self.x = w / 2 - 304
self.y = h > 600 ? h / 2 - 80 : 96
end
@fade_in = false @fade_in = false
@fade_out = false @fade_out = false
@ -230,5 +234,6 @@ class Window_Item < Window_Selectable
def dispose def dispose
super super
@help_window.dispose @help_window.dispose
@update_connection.disconnect
end end
end end

View file

@ -2,6 +2,10 @@
class Window_MainMenu < Window_Selectable class Window_MainMenu < Window_Selectable
def initialize def initialize
super(Graphics.width / 2 - 304, 16, 608, 64) super(Graphics.width / 2 - 304, 16, 608, 64)
@update_connection = Graphics.viewport_resized do |w, h|
self.x = w / 2 - 304
end
# Set up menu options # Set up menu options
@commands = Array.new @commands = Array.new
@ -158,4 +162,9 @@ class Window_MainMenu < Window_Selectable
return return
end end
end end
def dispose
super
@update_connection.disconnect
end
end end

View file

@ -18,7 +18,7 @@ class Window_Message < Window_Selectable
self.z = 9999 self.z = 9999
self.back_opacity = 210 self.back_opacity = 210
@update_connection = Graphics.window_resized do |w, h| @update_connection = Graphics.viewport_resized do |w, h|
self.x = Graphics.width / 2 - 304 self.x = Graphics.width / 2 - 304
case $game_system.message_position case $game_system.message_position
when 0 # up when 0 # up
@ -60,6 +60,7 @@ class Window_Message < Window_Selectable
# * Dispose # * Dispose
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def dispose def dispose
@update_connection.disconnect
terminate_message terminate_message
$game_temp.message_window_showing = false $game_temp.message_window_showing = false
if @input_number_window != nil if @input_number_window != nil

View file

@ -21,6 +21,39 @@ class Window_Settings
@title.opacity = 0 @title.opacity = 0
Language.register_text_sprite(self.class.name + "_title", @title) Language.register_text_sprite(self.class.name + "_title", @title)
@resized = false
@update_connection = Graphics.viewport_resized do |w, h|
if self.visible
@viewport.rect.width = w
@viewport.rect.height = h
@bg.bitmap.dispose
@bg.bitmap = Bitmap.new(w, h)
@bg.bitmap.fill_rect(0, 0, w, h, Color.new(0, 0, 0, 196))
@title.x = (w - @title.bitmap.width) / 2
init_content
else
@resized = true
end
end
init_content
@left_hold_timer = 0
@right_hold_timer = 0
@up_hold_timer = 0
@down_hold_timer = 0
@visible = self.visible = false
RPG::Mod.exec_hooks("hooks/Window_Settings/init", binding)
end
def init_content
if (@content)
@content.dispose
end
@content = SettingsContent.new(@viewport, TITLE_TOP_MARGIN + TITLE_MARGIN + 100) @content = SettingsContent.new(@viewport, TITLE_TOP_MARGIN + TITLE_MARGIN + 100)
DATA.each_with_index do |(screen_title, parameters_info), screen_index| DATA.each_with_index do |(screen_title, parameters_info), screen_index|
@ -66,21 +99,13 @@ class Window_Settings
end end
end end
@content.redraw_all @content.redraw_all
@left_hold_timer = 0
@right_hold_timer = 0
@up_hold_timer = 0
@down_hold_timer = 0
@visible = self.visible = false
RPG::Mod.exec_hooks("hooks/Window_Settings/init", binding)
end end
def dispose def dispose
@bg.dispose @bg.dispose
@title.dispose @title.dispose
@content.dispose @content.dispose
@update_connection.disconnect
end end
def open def open
@ -102,6 +127,17 @@ class Window_Settings
end end
def update def update
if @resized
@viewport.rect.width = Graphics.width
@viewport.rect.height = Graphics.height
@bg.bitmap.dispose
@bg.bitmap = Bitmap.new(Graphics.width, Graphics.height)
@bg.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, Color.new(0, 0, 0, 196))
@title.x = (Graphics.width - @title.bitmap.width) / 2
init_content
@resized = false
end
if Input.key_press?(Input.key_from_name("F1")) if Input.key_press?(Input.key_from_name("F1"))
if Oneshot.msgbox(Oneshot::Msg::YESNO, tr("Are you sure you want to reset the control settings?")) if Oneshot.msgbox(Oneshot::Msg::YESNO, tr("Are you sure you want to reset the control settings?"))
Settings.reset_controls! Settings.reset_controls!

View file

@ -645,8 +645,6 @@ void Graphics::update(bool limitFps){
return; return;
} }
shState->oneshot().update();
p->checkResize(); p->checkResize();
p->redrawScreen(); p->redrawScreen();
p->scPos = shState->rtData().ethread->getWindowPosition(); p->scPos = shState->rtData().ethread->getWindowPosition();
@ -888,7 +886,7 @@ void Graphics::moveScreen(int x, int y){
shState->eThread().requestWindowMove(x, y); shState->eThread().requestWindowMove(x, y);
} }
void Graphics::resizeScreen(int width, int height){ void Graphics::resizeScreen(int width, int height, bool emitSignal){
width = clamp(width, 1, 65000); width = clamp(width, 1, 65000);
height = clamp(height, 1, 65000); height = clamp(height, 1, 65000);
@ -908,6 +906,8 @@ void Graphics::resizeScreen(int width, int height){
glState.scissorBox.set(IntRect(0, 0, width, height)); glState.scissorBox.set(IntRect(0, 0, width, height));
shState->eThread().requestWindowResize(width, height); shState->eThread().requestWindowResize(width, height);
if (emitSignal)
shState->graphicsSignals.resized.Emit(width, height);
} }
DEF_ATTR_RD_SIMPLE(Graphics, Brightness, int, p->brightness) DEF_ATTR_RD_SIMPLE(Graphics, Brightness, int, p->brightness)

View file

@ -53,7 +53,7 @@ public:
int y() const; int y() const;
int width() const; int width() const;
int height() const; int height() const;
void resizeScreen(int width, int height); void resizeScreen(int width, int height, bool emitSignal = true);
void moveScreen(int x, int y); void moveScreen(int x, int y);
void reset(); void reset();

View file

@ -360,11 +360,6 @@ Oneshot::~Oneshot()
delete p; delete p;
} }
void Oneshot::update()
{
p->obscuredNeedToUpdate = true;
}
const std::string &Oneshot::os() const const std::string &Oneshot::os() const
{ {
return p->os; return p->os;
@ -589,11 +584,16 @@ std::string Oneshot::textinput(const char *prompt, int char_limit, const char *f
return threadData.inputText; return threadData.inputText;
} }
void Oneshot::setObscuredUpdating(bool enabled){
p->obscuredNeedToUpdate = enabled;
}
void Oneshot::updateObscured(int winX, int winY) void Oneshot::updateObscured(int winX, int winY)
{ {
SDL_LockMutex(p->winMutex);
p->winX = winX; p->winX = winX;
p->winY = winY; p->winY = winY;
SDL_UnlockMutex(p->winMutex);
if (!p->obscuredNeedToUpdate) return; if (!p->obscuredNeedToUpdate) return;
// Map of unobscured pixels in this frame // Map of unobscured pixels in this frame

View file

@ -42,8 +42,6 @@ public:
GRADIENT_VERTICAL, GRADIENT_VERTICAL,
}; };
void update();
//Accessors //Accessors
const std::string &os() const; const std::string &os() const;
const std::string &lang() const; const std::string &lang() const;
@ -61,6 +59,7 @@ public:
void setYesNo(const char *yes, const char *no); void setYesNo(const char *yes, const char *no);
void setExiting(bool exiting); void setExiting(bool exiting);
void setAllowExit(bool allowExit); void setAllowExit(bool allowExit);
void setObscuredUpdating(bool enabled);
void updateObscured(int winX, int winY); void updateObscured(int winX, int winY);
void resetObscured(); void resetObscured();

View file

@ -64,6 +64,7 @@ struct WindowSignals{
struct GraphicsSignals{ struct GraphicsSignals{
Signal<void> prepareDraw; Signal<void> prepareDraw;
Signal<void(int, int)> resized;
}; };
struct SharedState{ struct SharedState{