So I'm using a script to alter the resolution of one of my games to be 853x480. A 16:9 equivalent to 640x480. However it seems that Plane is bound to 640x480, so I go looking for Plane rewrites.
All the version I've found make my planes either "jumpy" or too fast. I use a timer to slow down the fog effect on my title screen (update_fog1 if @fogup == 3), but this makes the panning clearly pausing between updates. Removing it makes them pan far too fast.
I am currently using this rewrite by Selwyn
PHP Code:
<?php #==============================================================================
# ■ SG::Plane
#------------------------------------------------------------------------------
# by Selwyn
#============================================================================== module SG; end
class SG::Plane
attr_reader :ox, :oy #--------------------------------------------------------------------------
# ● initialize
#-------------------------------------------------------------------------- def initialize(viewport = nil)
@sprite = Sprite.new(viewport)
@max_width = 853 @max_height = 480 @bitmap = nil @ox = 0 @oy = 0
end #--------------------------------------------------------------------------
# ● z, zoom_x, zoom_y, opacity, blend_type, color, tone
#z=, zoom_x=, zoom_y=, opacity=, blend_type=, color=, tone=
#-------------------------------------------------------------------------- def method_missing(symbol, *args)
@sprite.method(symbol).call(*args) end #--------------------------------------------------------------------------
# ● bitmap=
#-------------------------------------------------------------------------- def bitmap=(bitmap)
@bitmap = bitmap
refresh
end #--------------------------------------------------------------------------
# ● ox=
#-------------------------------------------------------------------------- def ox=(ox) w = @sprite.viewport != nil ? @sprite.viewport.rect.width : @max_width @ox = ox % w @sprite.ox = @ox
end #--------------------------------------------------------------------------
# ● oy=
#-------------------------------------------------------------------------- def oy=(oy) h = @sprite.viewport != nil ? @sprite.viewport.rect.height : @max_height @oy = oy % h @sprite.oy = @oy
end #--------------------------------------------------------------------------
# ● refresh
#-------------------------------------------------------------------------- def refresh return if @bitmap.nil? w = @sprite.viewport != nil ? @sprite.viewport.rect.width : @max_width
h = @sprite.viewport != nil ? @sprite.viewport.rect.height : @max_height if @sprite.bitmap != nil @sprite.bitmap.dispose
end @sprite.bitmap = Bitmap.new(w * 2, h * 2)
max_x = w / @bitmap.width
max_y = h / @bitmap.height for x in 0..max_x for y in 0..max_y @sprite.bitmap.blt(x * @bitmap.width, y * @bitmap.height,
@bitmap, Rect.new(0, 0, @bitmap.width, @bitmap.height)) end
end for i in 1...4
x = i % 2 * w
y = i / 2 * h @sprite.bitmap.blt(x, y, @sprite.bitmap, Rect.new(0, 0, w, h)) end
end
end
This is what I am using to change my resolution. Strangely enough it fixes fogs in maps on it's own, but I have no idea how it's doing that, because I can't copy that over to my title screen.
PHP Code:
<?php class << Graphics
def width ; return 853; end # Configurez ici la largeur de l'�cran def height; return 480; end # Configurez ici la hauteur de l'�cran Fullscreen_Start = false # Configurez ici si le jeu d�marre en mode plein �cran (true) ou pas (false)
FindWindow = Win32API.new("user32", "FindWindow", "pp", "l") CreateWindowEx = Win32API.new("user32", "CreateWindowEx", "lpplllllllll", "l") UpdateWindow = Win32API.new("user32", "UpdateWindow", "l", "l") ShowWindow = Win32API.new("user32", "ShowWindow", "ll", "l") SetWindowLong = Win32API.new("user32", "SetWindowLong", "lll", "l") SetWindowPos = Win32API.new("user32", "SetWindowPos", "lllllll", "l") GetSystemMetrics = Win32API.new("user32", "GetSystemMetrics", "l", "l") GetDC = Win32API.new("user32", "GetDC", "l", "l") FillRect = Win32API.new("user32", "FillRect", "lpl", "l") #SetKeyState = Win32API.new("user32", "keybd_event", "llll", "") CreateSolidBrush = Win32API.new("gdi32", "CreateSolidBrush", "l", "l") SetResolution = Win32API.new("Display", "SetResolution", "lll", "l") Screenshot = Win32API.new("Screenshot", "Screenshot", "llllpll", "") Resolutions = [[], []] Resolutions[0].push([ 320, 240]) Resolutions[0].push([ 640, 480]) Resolutions[0].push([ 768, 576]) Resolutions[0].push([ 800, 600]) Resolutions[0].push([1024, 768]) Resolutions[0].push([1152, 864]) Resolutions[0].push([1280, 960]) Resolutions[0].push([1280, 1024]) Resolutions[0].push([1400, 1050]) Resolutions[0].push([1600, 1200]) Resolutions[0].push([2048, 1536]) Resolutions[0].push([2560, 1920]) Resolutions[0].push([2560, 2048]) Resolutions[1].push([ 320, 200]) Resolutions[1].push([ 800, 480]) Resolutions[1].push([ 854, 480]) Resolutions[1].push([ 960, 600]) Resolutions[1].push([1088, 612]) Resolutions[1].push([1280, 720]) Resolutions[1].push([1280, 768]) Resolutions[1].push([1280, 800]) Resolutions[1].push([1360, 768]) Resolutions[1].push([1440, 900]) Resolutions[1].push([1680, 1050]) Resolutions[1].push([1920, 1080]) Resolutions[1].push([1920, 1200]) Resolutions[1].push([2560, 1440]) Resolutions[1].push([2560, 1600]) Transition = Sprite.new Transition.z = 0xFFFF
First_Start = !defined?(First_Start)
if First_Start
open("Game.ini") {|file| file.read[/Title=(.*?)\n/]} WindowHandle = FindWindow.call("RGSS Player", $1) BackWindowHandle = CreateWindowEx.call(0x08000000, "Static", "", 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0) FillRectArgs = [GetDC.call(BackWindowHandle), [0,0,0xFFFF,0xFFFF].pack("l4"), CreateSolidBrush.call(0)]
@@fullscreen, @@client_resolution = nil
alias :zeus81_rcu_graphics_freeze :freeze
alias :zeus81_rcu_graphics_transition :transition
alias :zeus81_rcu_graphics_update :update
end
def update
zeus81_rcu_graphics_update #set_key_state(164, false) change_mode if Input.trigger?(Input::F5) end
def freeze if width <= 640 and height <= 480; zeus81_rcu_graphics_freeze else Screenshot.call(0, 0, width, height, "TempData.rxdata", WindowHandle, 0) Transition.bitmap = Bitmap.new("TempData.rxdata") File.delete("TempData.rxdata") end
end
def transition(d=8, f="", v=40)
if width <= 640 and height <= 480; zeus81_rcu_graphics_transition(d, f, v)
else d.times {|i| Transition.opacity = 256 - i*256/d; update} Transition.bitmap.dispose if Transition.bitmap
Transition.bitmap, Transition.opacity = nil, 255
end
end
def fullscreen?; return @@fullscreen; end
def change_mode; set_resolution(!@@fullscreen); end
def fullscreen_mode; set_resolution(true) unless @@fullscreen == true; end
def windowed_mode; set_resolution(false) unless @@fullscreen == false; end private #def set_key_state(k, b); SetKeyState.call(k, 0, (b ? 0 : 2), 0); end def get_resolution; return GetSystemMetrics.call(0), GetSystemMetrics.call(1); end
def set_resolution(fullscreen)
@@client_resolution = get_resolution unless @@fullscreen == true @@fullscreen = fullscreen
w, h, z, f = width, height, -1, 64 if @@fullscreen
ShowWindow.call(BackWindowHandle, 3) SetWindowLong.call(WindowHandle, -16, 0x14000000) ratio = @@client_resolution[0] / @@client_resolution[1].to_f for res in Resolutions[ratio < 1.5 ? 0 : 1] next unless res[0] >= width and res[1] >= height
SetResolution.call(res[0], res[1], 4)
break if res == get_resolution
end else ShowWindow.call(BackWindowHandle, 0) SetWindowLong.call(WindowHandle, -16, 0x14CA0000) SetResolution.call(@@client_resolution[0], @@client_resolution[1], 0) w += (GetSystemMetrics.call(5)+2) * 2
h += (GetSystemMetrics.call(6)+2) * 2 + GetSystemMetrics.call(4) z = f = 0
end
x, y = get_resolution
x, y = [(x-w)/2, 0].max, [(y-h)/2, 0].max
SetWindowPos.call(WindowHandle, z, x, y, w, h, f) UpdateWindow.call(BackWindowHandle) FillRect.call(*FillRectArgs) end
Fullscreen_Start ? Graphics.fullscreen_mode : Graphics.windowed_mode if First_Start
end
class RPG::Weather
def update return if @type == 0 for i in 1..@max
sprite = @sprites[i]
break if sprite == nil case @type
when 1; sprite.x -= 2; sprite.y += 16; sprite.opacity -= 8
when 2; sprite.x -= 8; sprite.y += 16; sprite.opacity -= 12
when 3; sprite.x -= 2; sprite.y += 8; sprite.opacity -= 8
end
x, y = sprite.x - @ox, sprite.y - @oy if sprite.opacity < 64 or x < -50 or x > Graphics.width+110 or y < -300 or y > Graphics.height+20
sprite.x, sprite.y = rand(Graphics.width+160)- 50+@ox, rand(Graphics.height+220)-200+@oy
sprite.opacity = 255
end
end
end
end
class Game_Map
def scroll_right(distance); self.display_x += distance; end
def scroll_left(distance) ; self.display_x -= distance; end
def scroll_down(distance) ; self.display_y += distance; end
def scroll_up(distance) ; self.display_y -= distance; end
def display_x=(x); @display_x = middle(0, x, width*128-Graphics.width*4) if @display_x != x and width*32 > Graphics.width; end
def display_y=(y); @display_y = middle(0, y, height*128-Graphics.height*4) if @display_y != y and height*32 > Graphics.height; end
def middle(min, x, max); return (x > min ? x < max ? x : max : min); end
end
class Game_Event
def visible; return !@event.name.include?("[INVISIBLE]"); end
end
class Game_Player
CENTER_X, CENTER_Y = (Graphics.width/2-16)*4, (Graphics.height/2-16)*4
def center(x, y); $game_map.display_x, $game_map.display_y = x*128-CENTER_X, y*128-CENTER_Y; end
end
class Sprite_Character
attr_accessor :animation_viewport, :clones
def initialize(a, b); super(a); @character, @clones = b, []; end
alias :zeus81_rcu_sprite_character_update :update
def update; zeus81_rcu_sprite_character_update; @clones.each {|c| c.update}; end
def dispose; super; @clones.each {|c| c.dispose}; end
def flash(a, b); super; @clones.each {|c| c.flash(a, b)}; end
def bitmap=(a); (super; @clones.each {|c| c.bitmap=a}) if bitmap != a; end
def visible=(a); (super; @clones.each {|c| c.visible=a}) if visible != a; end
def opacity=(a); (super; @clones.each {|c| c.opacity=a}) if opacity != a; end
def src_rect=(a); super; @clones.each {|c| c.src_rect=a}; end
def ox=(a); (super; @clones.each {|c| c.ox=a}) if ox != a; end
def oy=(a); (super; @clones.each {|c| c.oy=a}) if oy != a; end
def x=(a); (super; @clones.each {|c| c.x=a-c.viewport.rect.x+viewport.rect.x}) if x != a; end
def y=(a); (super; @clones.each {|c| c.y=a-c.viewport.rect.y+viewport.rect.y}) if y != a; end
def z=(a); (super; @clones.each {|c| c.z=a-c.viewport.rect.y+viewport.rect.y}) if z != a; end
def blend_type=(a); (super; @clones.each {|c| c.blend_type=a}) if blend_type != a; end
def bush_depth=(a); (super; @clones.each {|c| c.bush_depth=a}) if bush_depth != a; end
def animation(animation, hit) dispose_animation @_animation = animation return if @_animation == nil @_animation_hit, @_animation_duration = hit, @_animation.frame_max
bitmap = RPG::Cache.animation(@_animation.animation_name, @_animation.animation_hue)
if @@_reference_count.include?(bitmap); @@_reference_count[bitmap] += 1 else; @@_reference_count[bitmap] = 1
end @_animation_sprites = []
if @_animation.position != 3 or not @@_animations.include?(@_animation) 16.times do sprite = ::Sprite.new(@animation_viewport) sprite.bitmap, sprite.visible = bitmap, false @_animation_sprites.push(sprite) end @@_animations.push(@_animation) unless @@_animations.include?(@_animation) end
update_animation
end
end
class Spriteset_Map
def initialize @tilemaps, @panoramas, @fogs, @character_sprites, @picture_sprites = [], [], [], [], [] r = Rect.new(0, 0, [$game_map.width*32, Graphics.width].min, [$game_map.height*32, Graphics.height].min) r.x, r.y = (Graphics.width-r.width)/2, (Graphics.height-r.height)/2
iw, ih = (r.width/640.0).ceil, (r.height/480.0).ceil for i in 0...iw*ih
x, y = i%iw*640, i/iw*480
w, h = [r.width-x, r.width, 640].min, [r.height-y, r.height, 480].min
v = Viewport.new(r.x+x, r.y+y, w, h)
@tilemaps.push(Tilemap.new(v))
@tilemaps[-1].tileset = RPG::Cache.tileset($game_map.tileset_name) 7.times {|j| @tilemaps[-1].autotiles[j] = RPG::Cache.autotile($game_map.autotile_names[j])}
@tilemaps[-1].map_data, @tilemaps[-1].priorities = $game_map.data, $game_map.priorities @panoramas.push(Plane.new(v))
@fogs.push(Plane.new(v))
@panoramas[-1].z, @fogs[-1].z = -1000, 3000 if i == 0
$game_map.events.each_value {|e| @character_sprites.push(Sprite_Character.new(v, e)) if e.visible}
@character_sprites.push(Sprite_Character.new(v, $game_player))
else; @character_sprites.each {|s| s.clones.push(Sprite.new(v))} end
end @viewport1, @viewport2, @viewport3 = Viewport.new(r), Viewport.new(r), Viewport.new(r)
@viewport2.z, @viewport3.z = 200, 5000 @weather = RPG::Weather.new(@viewport1)
@character_sprites.each {|s| s.animation_viewport=@viewport1; s.update}
(1..50).each {|i| @picture_sprites.push(Sprite_Picture.new(@viewport2, $game_screen.pictures[i]))}
@timer_sprite = Sprite_Timer.new update
end
def dispose @tilemaps[0].tileset.dispose
7.times {|i| @tilemaps[0].autotiles[i].dispose}
@tilemaps.each {|tilemap| tilemap.viewport.dispose; tilemap.dispose}
@panoramas.each {|panorama| panorama.dispose}
@fogs.each {|fog| fog.dispose}
@character_sprites.each {|sprite| sprite.dispose}
@weather.dispose @picture_sprites.each {|sprite| sprite.dispose}
@timer_sprite.dispose @viewport1.dispose @viewport2.dispose @viewport3.dispose
end
def update if @panorama_name != $game_map.panorama_name or @panorama_hue != $game_map.panorama_hue @panorama_name, @panorama_hue = $game_map.panorama_name, $game_map.panorama_hue @panoramas[0].bitmap.dispose if @panoramas[0].bitmap @panoramas[0].bitmap = (@panorama_name == "" ? nil : RPG::Cache.panorama(@panorama_name, @panorama_hue))
@panoramas.each {|panorama| panorama.bitmap = @panoramas[0].bitmap} Graphics.frame_reset
end if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue @fog_name, @fog_hue = $game_map.fog_name, $game_map.fog_hue @fogs[0].bitmap.dispose if @fogs[0].bitmap @fogs[0].bitmap = (@fog_name == "" ? nil : RPG::Cache.fog(@fog_name, @fog_hue))
@fogs.each {|fog| fog.bitmap = @fogs[0].bitmap} Graphics.frame_reset
end @viewport1.tone, @viewport1.ox, @viewport3.color = $game_screen.tone, $game_screen.shake, $game_screen.flash_color @viewport1.update @viewport3.update
ox, oy = $game_map.display_x/4, $game_map.display_y/4 for i in 0...@tilemaps.size
tilemap = @tilemaps[i] tilemap.viewport.tone, tilemap.viewport.ox = @viewport1.tone, @viewport1.ox
tilemap.viewport.update
tilemap.ox = ox+tilemap.viewport.rect.x-@viewport1.rect.x
tilemap.oy = oy+tilemap.viewport.rect.y-@viewport1.rect.y
tilemap.update
panorama = @panoramas[i] panorama.ox, panorama.oy = tilemap.ox/2, tilemap.oy/2 if panorama.bitmap
fog = @fogs[i]
if fog.bitmap
fog.ox, fog.oy = tilemap.ox+$game_map.fog_ox, tilemap.oy+$game_map.fog_oy
fog.zoom_x, fog.zoom_y = $game_map.fog_zoom/100.0, $game_map.fog_zoom/100.0
fog.opacity, fog.blend_type, fog.tone = $game_map.fog_opacity, $game_map.fog_blend_type, $game_map.fog_tone
end
end @character_sprites.each {|sprite| sprite.update}
@weather.type, @weather.max = $game_screen.weather_type, $game_screen.weather_max @weather.ox, @weather.oy = ox, oy @weather.update @picture_sprites.each {|sprite| sprite.update}
@timer_sprite.update
end
end
There are a few other errors with Selwyn's rewrite. I, too, use it in my Resolution kit, however I have modified it a bit to fix several errors, mainly with how the bitmap is tiled across the sprite. Here is my modified version of Selwyn's script:
Content Hidden
Code:
#==============================================================================
# – SG::Plane
#------------------------------------------------------------------------------
# originally by Selwyn
# edited and remastered by Draycos Goldaryn
#------------------------------------------------------------------------------
# This is a replacement for the Plane class. Planes are special sprites that
# tile bitmap patterns across the entire screen, and are used to display
# panoramas and fog.
#==============================================================================
module SG
class Plane
attr_reader :ox, :oy
#--------------------------------------------------------------------------
# — initialize
#--------------------------------------------------------------------------
def initialize(viewport = nil)
@sprite = Sprite.new(viewport) # The special Sprite
@max_width = 640 # The maximum viewable width
@max_height = 480 # The maximum viewable height
@bitmap = nil # The Bitmap to be tiled across the Plane
@ox = 0 # The Plane's starting x coordinate
@oy = 0 # The Plane's starting y coordinate
end
#--------------------------------------------------------------------------
# — z, zoom_x, zoom_y, opacity, blend_type, color, tone
# z=, zoom_x=, zoom_y=, opacity=, blend_type=, color=, tone=
#--------------------------------------------------------------------------
def method_missing(symbol, *args)
@sprite.method(symbol).call(*args)
end
#--------------------------------------------------------------------------
# — bitmap=
#--------------------------------------------------------------------------
def bitmap=(bitmap)
@bitmap = bitmap
refresh
end
#--------------------------------------------------------------------------
# — ox=
#--------------------------------------------------------------------------
def ox=(ox)
# If the bitmap hasn't been defined, don't do anything.
return if @bitmap.nil?
w = (@sprite.bitmap.width / 2)
# If there is no change, don't do anything.
if @ox == ox or @ox == ox % w
return
end
# Otherwise, scroll the Plane horizontally
@ox = ox % w
@sprite.ox = @ox
end
#--------------------------------------------------------------------------
# — oy=
#--------------------------------------------------------------------------
def oy=(oy)
# If the bitmap hasn't been defined, don't do anything.
return if @bitmap.nil?
h = (@sprite.bitmap.height / 2)
# If there is no change, don't do anything.
if @oy == oy or @oy == oy % h
return
end
# Otherwise, scroll the Plane vertically
@oy = oy % h
@sprite.oy = @oy
end
#--------------------------------------------------------------------------
# — refresh
#--------------------------------------------------------------------------
def refresh
# If there was already a bitmap made, get rid of it.
if @sprite.bitmap != nil
@sprite.bitmap.dispose
end
# If the bitmap hasn't been defined, don't do anything.
return if @bitmap.nil?
# Set the maximum viewable area
w = @sprite.viewport != nil ? @sprite.viewport.rect.width : @max_width
h = @sprite.viewport != nil ? @sprite.viewport.rect.height : @max_height
# Set the size of the Sprite.Bitmap. it should be greater than 4x the
# viewable area for proper scrolling
bw,bh = @bitmap.width,@bitmap.height
until bw > w * 2
bw += @bitmap.width
end
until bh > h * 2
bh += @bitmap.height
end
@sprite.bitmap = Bitmap.new(bw * 2, bh * 2)
# Now that the size is set, find out how many times the bitmap will fit
max_x = @sprite.bitmap.width / @bitmap.width
max_y = @sprite.bitmap.height / @bitmap.height
# Go ahead and tile the bitmap till it fills the Sprite
for x in 0..max_x
for y in 0..max_y
@sprite.bitmap.blt(x * @bitmap.width, y * @bitmap.height,
@bitmap, Rect.new(0, 0, @bitmap.width, @bitmap.height))
end
end
end
end
end
This should work with different resolutions.
As for your scrolling issue on the title screen. it's most likely how you are calling the plane class. If this doesn't fix the error, please post the script you use to scrol a plane on the title screen and I'll see what I can do to fix it for you.