(Not Biged781's) Improved RGSS Window class
Purpose
First off, I did not write most of this code. I have tweaked it, made it more readable and a little more efficient, but this was written by a guy named "Peter O" at this site. I found this when looking around for the RGSS source code. I needed to edit the RGSS Window class (not the Window_Base class, the hidden Window class) so that I could change the way windowskins work. Well, I found this, and with a little editing it is working perfectly. Any scripter can look through the source to see what has been added, but the coolest thing imo is the tiled window option.
The most powerful aspect of this code is that it shows you all of the source for the previously hidden "Window" RGSS/2 class.
I have not found any compatibility issues yet, let me know of any bugs. This will also work in RMXP.
Configuration / Use
Just place it in the Materials section. this should go above any other script in that section because it alters the base class for all windows.
Since this was the reason for it in the first place, here is all you have to do to set it to tiled mode;
CODE
window.stretch = false
Screenshots
While this example is ugly, this script will allow you do do something like this below. You can use any type of tile that you like.

Script
CODE
class WindowCursorRect < Rect
#--------------------------------------------------------------------
# * intialize
#--------------------------------------------------------------------
def initialize(window)
@window=window
@x=0
@y=0
@width=0
@height=0
end
attr_reader :x,:y,:width,:height
#--------------------------------------------------------------------
# * empty
#--------------------------------------------------------------------
def empty
needupdate=@x!=0 || @y!=0 || @width!=0 || @height!=0
if needupdate
@x=0
@y=0
@width=0
@height=0
@window.width=@window.width
end
end
#--------------------------------------------------------------------
# * isEmpty
#--------------------------------------------------------------------
def isEmpty?
return @x==0 && @y==0 && @width==0 && @height==0
end
#--------------------------------------------------------------------
# * set
#--------------------------------------------------------------------
def set(x,y,width,height)
needupdate=@x!=x || @y!=y || @width!=width || @height!=height
if needupdate
@x=x
@y=y
@width=width
@height=height
@window.width=@window.width
end
end
#--------------------------------------------------------------------
# * height=
#--------------------------------------------------------------------
def height=(value)
@height=value; @window.width=@window.width
end
#--------------------------------------------------------------------
# * width=
#--------------------------------------------------------------------
def width=(value)
@width=value; @window.width=@window.width
end
#--------------------------------------------------------------------
# * x=
#--------------------------------------------------------------------
def x=(value)
@x=value; @window.width=@window.width
end
#--------------------------------------------------------------------
# * y=
#--------------------------------------------------------------------
def y=(value)
@y=value; @window.width=@window.width
end
end
#----------------------------------------------------------------------
# * Window Class
#----------------------------------------------------------------------
class Window
attr_reader :tone
attr_reader :color
attr_reader :blend_type
attr_reader :contents_blend_type
attr_reader :viewport
attr_reader :contents
attr_reader :ox
attr_reader :oy
attr_reader :x
attr_reader :y
attr_reader :z
attr_reader :width
attr_reader :active
attr_reader :pause
attr_reader :height
attr_reader :opacity
attr_reader :back_opacity
attr_reader :contents_opacity
attr_reader :visible
attr_reader :cursor_rect
attr_reader :openness
#--------------------------------------------------------------------
# * windowskin
#--------------------------------------------------------------------
def windowskin
return @_windowskin
end
#--------------------------------------------------------------------
# * intialize
#--------------------------------------------------------------------
def initialize(viewport=nil)
@sprites={}
@spritekeys=
[
"back",
"corner0","side0","scroll0",
"corner1","side1","scroll1",
"corner2","side2","scroll2",
"corner3","side3","scroll3",
"cursor","contents","pause"
]
@sidebitmaps=[nil,nil,nil,nil]
@cursorbitmap=nil
@bgbitmap=nil
@viewport=viewport
@spritekeys.each { |key| @sprites[key]=Sprite.new(@viewport) }
@disposed=false
@tone=Tone.new(0,0,0)
@color=Color.new(0,0,0,0)
@blankcontents=Bitmap.new(1,1) # RGSS2 requires this
@contents=@blankcontents
@_windowskin=nil
@rpgvx=false
@x=0
@y=0
@width=0
@openness=255
@height=0
@ox=0
@oy=0
@z=0
@stretch=true
@visible=true
@active=true
@blend_type=0
@contents_blend_type=0
@opacity=255
@back_opacity=255
@contents_opacity=255
@cursor_rect=WindowCursorRect.new(self)
@cursorblink=0
@cursoropacity=255
@pause=false
@pauseopacity=255
@pauseframe=0
privRefresh(true)
end
#--------------------------------------------------------------------
# * dispose
#--------------------------------------------------------------------
def dispose
if !self.disposed?
for i in @sprites
i[1].dispose if i[1]
@sprites[i[0]]=nil
end
for i in 0...@sidebitmaps.length
@sidebitmaps[i].dispose if @sidebitmaps[i]
@sidebitmaps[i]=nil
end
@blankcontents.dispose
@cursorbitmap.dispose if @cursorbitmap
@backbitmap.dispose if @backbitmap
@sprites.clear
@sidebitmaps.clear
@_windowskin=nil
@_contents=nil
@disposed=true
end
end
#--------------------------------------------------------------------
# * openness=
#--------------------------------------------------------------------
def openness=(value)
@openness=value
@openness=0 if @openness<0
@openness=255 if @openness>255
privRefresh
end
#--------------------------------------------------------------------
# * strecth=
#--------------------------------------------------------------------
def stretch=(value)
@stretch=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * visible=
#--------------------------------------------------------------------
def visible=(value)
@visible=value
privRefresh
end
#--------------------------------------------------------------------
# * viewposrt=
#--------------------------------------------------------------------
def viewport=(value)
@viewport=value
for i in @spritekeys
@sprites[i].dispose
if @sprites[i].is_a?(Sprite)
@sprites[i] = Sprite.new(@viewport)
elsif @sprites[i].is_a?(Plane)
@sprites[i] = Plane.new(@viewport)
else
@sprites[i] = nil
end
end
privRefresh(true)
end
#--------------------------------------------------------------------
# * z=
#--------------------------------------------------------------------
def z=(value)
@z=value
privRefresh
end
#--------------------------------------------------------------------
# * disposed?
#--------------------------------------------------------------------
def disposed?
return @disposed
end
#--------------------------------------------------------------------
# * contents=
#--------------------------------------------------------------------
def contents=(value)
@contents=value
privRefresh
end
#--------------------------------------------------------------------
# * windowskin=
#--------------------------------------------------------------------
def windowskin=(value)
@_windowskin=value
if value && value.is_a?(Bitmap) && !value.disposed? && value.width==128
@rpgvx=true
else
@rpgvx=false
end
privRefresh(true)
end
#--------------------------------------------------------------------
# * ox=
#--------------------------------------------------------------------
def ox=(value)
@ox=value
privRefresh
end
#--------------------------------------------------------------------
# * active=
#--------------------------------------------------------------------
def active=(value)
@active=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * cursor_rect=
#--------------------------------------------------------------------
def cursor_rect=(value)
if !value
@cursor_rect.empty
else
@cursor_rect.set(value.x,value.y,value.width,value.height)
end
end
#--------------------------------------------------------------------
# * oy=
#--------------------------------------------------------------------
def oy=(value)
@oy=value
privRefresh
end
#--------------------------------------------------------------------
# * width=
#--------------------------------------------------------------------
def width=(value)
@width=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * height=
#--------------------------------------------------------------------
def height=(value)
@height=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * pause=
#--------------------------------------------------------------------
def pause=(value)
@pause=value
@pauseopacity=0 if !value
privRefresh
end
#--------------------------------------------------------------------
# * x=
#--------------------------------------------------------------------
def x=(value)
@x=value
privRefresh
end
#--------------------------------------------------------------------
# * y=
#--------------------------------------------------------------------
def y=(value)
@y=value
privRefresh
end
#--------------------------------------------------------------------
# * opacity=
#--------------------------------------------------------------------
def opacity=(value)
@opacity=value
@opacity=0 if @opacity<0
@opacity=255 if @opacity>255
privRefresh
end
#--------------------------------------------------------------------
# * back_opacity=
#--------------------------------------------------------------------
def back_opacity=(value)
@back_opacity=value
@back_opacity=0 if @back_opacity<0
@back_opacity=255 if @back_opacity>255
privRefresh
end
#--------------------------------------------------------------------
# * contents_opacity=
#--------------------------------------------------------------------
def contents_opacity=(value)
@contents_opacity=value
@contents_opacity=0 if @contents_opacity<0
@contents_opacity=255 if @contents_opacity>255
privRefresh
end
#--------------------------------------------------------------------
# * tone=
#--------------------------------------------------------------------
def tone=(value)
@tone=value
privRefresh
end
#--------------------------------------------------------------------
# * color=
#--------------------------------------------------------------------
def color=(value)
@color=value
privRefresh
end
#--------------------------------------------------------------------
# * blend_type=
#--------------------------------------------------------------------
def blend_type=(value)
@blend_type=value
privRefresh
end
#--------------------------------------------------------------------
# * flash
#--------------------------------------------------------------------
def flash(color,duration)
return if disposed?
@sprites.each {|sprite| sprite[1].flash(color,duration)}
end
def update
return if disposed?
mustchange=false
if @active
if @cursorblink==0
@cursoropacity-=8
@cursorblink = 1 if @cursoropacity<=128
else
@cursoropacity+=8
@cursorblink=0 if @cursoropacity>=255
end
mustchange=true if !@cursor_rect.isEmpty?
else
mustchange=true if @cursoropacity!=128
@cursoropacity=128
end
if @pause
@pauseframe=(Graphics.frame_count / 8) % 4
@pauseopacity=[@pauseopacity+64,255].min
mustchange=true
end
privRefresh if mustchange
for i in @sprites
i[1].update
end
end
#------------------ Private Methods ------------------#
private
#--------------------------------------------------------------------
# * ensureBitmap
#--------------------------------------------------------------------
def ensureBitmap(bitmap,dwidth,dheight)
if !bitmap||bitmap.disposed?||bitmap.width<dwidth||bitmap.height<dheight
bitmap.dispose if bitmap
bitmap=Bitmap.new([1,dwidth].max,[1,dheight].max)
end
return bitmap
end
#--------------------------------------------------------------------
# * tileBitmap
#--------------------------------------------------------------------
def tileBitmap(dstbitmap,dstrect,srcbitmap,srcrect)
return if !srcbitmap || srcbitmap.disposed?
left=dstrect.x
top=dstrect.y
y=0;loop do break unless y<dstrect.height
x=0;loop do break unless x<dstrect.width
dstbitmap.blt(x+left,y+top,srcbitmap,srcrect)
x+=srcrect.width
end
y+=srcrect.height
end
end
#--------------------------------------------------------------------
# * privRefresh
#--------------------------------------------------------------------
def privRefresh(changeBitmap=false)
return if self.disposed?
backopac = self.back_opacity * self.opacity / 255
contopac = self.contents_opacity
cursoropac = @cursoropacity * contopac / 255
@sprites["contents"].bitmap = @contents
unless @_windowskin.nil? || @_windowskin.disposed?
for i in 0...4
@sprites["corner#{i}"].bitmap = @_windowskin
@sprites["corner#{i}"].opacity = @opacity
@sprites["corner#{i}"].tone = @tone
@sprites["corner#{i}"].color = @color
@sprites["corner#{i}"].blend_type = @blend_type
@sprites["corner#{i}"].visible = @visible
@sprites["side#{i}"].opacity = @opacity
@sprites["side#{i}"].tone = @tone
@sprites["side#{i}"].color = @color
@sprites["side#{i}"].blend_type = @blend_type
@sprites["side#{i}"].visible = @visible
@sprites["scroll#{i}"].bitmap = @_windowskin
@sprites["scroll#{i}"].opacity = @opacity
@sprites["scroll#{i}"].tone = @tone
@sprites["scroll#{i}"].blend_type = @blend_type
@sprites["scroll#{i}"].color = @color
@sprites["scroll#{i}"].visible = @visible
end
@sprites["pause"].bitmap = @_windowskin
for key in ["back", "cursor", "pause", "contents"]
@sprites[key].color = @color
@sprites[key].tone = @tone
@sprites[key].blend_type = @blend_type
end
@sprites["contents"].blend_type = @contents_blend_type
@sprites["contents"].opacity = contopac
@sprites["contents"].visible = @visible && (@openness == 255)
@sprites["cursor"].opacity = cursoropac
@sprites["cursor"].visible = @visible && (@openness == 255)
@sprites["pause"].visible = @visible && @pause
@sprites["pause"].opacity = @pauseopacity
@sprites["back"].opacity = backopac
@sprites["back"].visible = @visible
hascontents = (!@contents.nil? && !@contents.disposed?)
@sprites["scroll0"].visible = @visible && hascontents && @oy > 0
@sprites["scroll1"].visible = @visible && hascontents && @ox > 0
@sprites["scroll2"].visible = @visible && hascontents && (@contents.width - @ox) > @width - 32
@sprites["scroll3"].visible = @visible && hascontents && (@contents.height - @oy) > @height - 32
else
for i in 0...4
@sprites["corner#{i}"].visible = false
@sprites["side#{i}"].visible = false
@sprites["scroll#{i}"].visible = false
end
@sprites["contents"].visible = @visible && @openness==255
@sprites["contents"].color = @color
@sprites["contents"].tone = @tone
@sprites["contents"].blend_type = @contents_blend_type
@sprites["contents"].opacity = contopac
@sprites["back"].visible = false
@sprites["pause"].visible = false
@sprites["cursor"].visible = false
end
@sprites.each { |sprite| sprite[1].z = @z }
if @rpgvx
@sprites["cursor"].z = @z # For Compatibility
@sprites["contents"].z = @z # For Compatibility
@sprites["pause"].z = @z # For Compatibility
trimX = 64
backRect = Rect.new(0,0,64,64)
blindsRect = Rect.new(0,64,64,64)
else
@sprites["cursor"].z = @z + 1 # For Compatibility
@sprites["contents"].z = @z + 2 # For Compatibility
@sprites["pause"].z = @z + 2 # For Compatibility
trimX = 128
backRect = Rect.new(0,0,128,128)
blindsRect = nil
end
trimY = 0
@sprites["corner0"].src_rect.set(trimX, trimY + 0, 16, 16);
@sprites["corner1"].src_rect.set(trimX + 48, trimY + 0, 16, 16);
@sprites["corner2"].src_rect.set(trimX, trimY + 48, 16, 16);
@sprites["corner3"].src_rect.set(trimX + 48, trimY + 48, 16, 16);
@sprites["scroll0"].src_rect.set(trimX + 24, trimY + 16, 16, 8) # up
@sprites["scroll3"].src_rect.set(trimX + 24, trimY + 40, 16, 8) # down
@sprites["scroll1"].src_rect.set(trimX + 16, trimY + 24, 8, 16) # left
@sprites["scroll2"].src_rect.set(trimX + 40, trimY + 24, 8, 16) # right
cursorX=trimX
cursorY=trimY + 64
sideRects= [ Rect.new(trimX + 16, trimY + 0, 32, 16),
Rect.new(trimX, trimY + 16, 16, 32),
Rect.new(trimX + 48, trimY + 16, 16, 32),
Rect.new(trimX + 16, trimY + 48, 32, 16) ]
if (@width > 32) && (@height > 32)
@sprites["contents"].src_rect.set(@ox, @oy, @width - 32, @height - 32)
else
@sprites["contents"].src_rect.set(0,0,0,0)
end
pauseRects=[ trimX + 32, trimY + 64,
trimX + 48, trimY + 64,
trimX + 32, trimY + 80,
trimX + 48, trimY + 80, ]
pauseWidth = 16
pauseHeight = 16
@sprites["pause"].src_rect.set( pauseRects[@pauseframe*2],
pauseRects[@pauseframe*2+1],
pauseWidth,pauseHeight )
@sprites["pause"].x = @x + (@width / 2) - (pauseWidth / 2)
@sprites["pause"].y = @y + @height - 16 # 16 refers to skin margin
@sprites["contents"].x = @x + 16
@sprites["contents"].y = @y + 16
@sprites["corner0"].x = @x
@sprites["corner0"].y = @y
@sprites["corner1"].x = @x + @width - 16
@sprites["corner1"].y = @y
@sprites["corner2"].x = @x
@sprites["corner2"].y = @y + @height - 16
@sprites["corner3"].x = @x + @width - 16
@sprites["corner3"].y = @y + @height - 16
@sprites["side0"].x = @x + 16
@sprites["side0"].y = @y
@sprites["side1"].x = @x
@sprites["side1"].y = @y + 16
@sprites["side2"].x = @x + @width - 16
@sprites["side2"].y = @y + 16
@sprites["side3"].x = @x + 16
@sprites["side3"].y = @y + @height - 16
@sprites["scroll0"].x = @x + @width / 2 - 8
@sprites["scroll0"].y = @y + 8
@sprites["scroll1"].x = @x + 8
@sprites["scroll1"].y = @y + @height / 2 - 8
@sprites["scroll2"].x = @x + @width - 16
@sprites["scroll2"].y = @y + @height / 2 - 8
@sprites["scroll3"].x = @x + @width / 2 - 8
@sprites["scroll3"].y = @y + @height - 16
@sprites["back"].x = @x + 2
@sprites["back"].y = @y + 2
@sprites["cursor"].x = @x + 16 + @cursor_rect.x
@sprites["cursor"].y = @y + 16 + @cursor_rect.y
if changeBitmap && !@_windowskin.nil? && !@_windowskin.disposed?
width = @cursor_rect.width
height = @cursor_rect.height
if (width > 0) && (height > 0)
cursorrects=[
# sides
Rect.new(cursorX+2, cursorY+0, 28, 2),
Rect.new(cursorX+0, cursorY+2, 2, 28),
Rect.new(cursorX+30, cursorY+2, 2, 28),
Rect.new(cursorX+2, cursorY+30, 28, 2),
# corners
Rect.new(cursorX+0, cursorY+0, 2, 2),
Rect.new(cursorX+30, cursorY+0, 2, 2),
Rect.new(cursorX+0, cursorY+30, 2, 2),
Rect.new(cursorX+30, cursorY+30, 2, 2),
# back
Rect.new(cursorX+2, cursorY+2, 28, 28)
]
margin = 2
fullmargin = 4
@cursorbitmap = ensureBitmap(@cursorbitmap, width, height)
@cursorbitmap.clear
@sprites["cursor"].bitmap = @cursorbitmap
@sprites["cursor"].src_rect.set(0, 0, width, height)
rect = Rect.new(margin, margin, width - fullmargin, height - fullmargin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[8])
@cursorbitmap.blt(0, 0, @_windowskin, cursorrects[4]) # top left
@cursorbitmap.blt(width-margin, 0, @_windowskin, cursorrects[5]) # top right
@cursorbitmap.blt(0, height-margin, @_windowskin, cursorrects[6])# bottom right
@cursorbitmap.blt(width-margin, height-margin, @_windowskin, cursorrects[7]) # bottom left
rect = Rect.new(margin, 0, width - fullmargin, margin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[0])
rect = Rect.new(0, margin, margin, height - fullmargin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[1])
rect = Rect.new(width - margin, margin, margin, height - fullmargin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[2])
rect = Rect.new(margin, height-margin, width - fullmargin, margin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[3])
else
@sprites["cursor"].visible = false
@sprites["cursor"].src_rect.set(0, 0, 0, 0)
end
for i in 0..3
dwidth = (i == 0 || i == 3) ? @width-32 : 16
dheight = (i == 0 || i == 3) ? 16 : @height - 32
@sidebitmaps[i] = ensureBitmap(@sidebitmaps[i], dwidth, dheight)
@sprites["side#{i}"].bitmap = @sidebitmaps[i]
@sprites["side#{i}"].src_rect.set(0, 0, dwidth, dheight)
@sidebitmaps[i].clear
if (sideRects[i].width > 0) && (sideRects[i].height > 0)
@sidebitmaps[i].stretch_blt( @sprites["side#{i}"].src_rect,
@_windowskin,sideRects[i] )
end
end
backwidth = @width-4
backheight = @height-4
if (backwidth > 0) && (backheight > 0)
@backbitmap = ensureBitmap(@backbitmap, backwidth, backheight)
@sprites["back"].bitmap = @backbitmap
@sprites["back"].src_rect.set(0, 0, backwidth, backheight)
@backbitmap.clear
if @stretch
@backbitmap.stretch_blt(@sprites["back"].src_rect, @_windowskin,backRect)
else
tileBitmap(@backbitmap,@sprites["back"].src_rect, @_windowskin,backRect)
end
if blindsRect
tileBitmap(@backbitmap,@sprites["back"].src_rect, @_windowskin,blindsRect)
end
else
@sprites["back"].visible = false
@sprites["back"].src_rect.set(0,0,0,0)
end
end
if @openness != 255
opn = @openness/255.0
for key in @spritekeys
sprite = @sprites[key]
ratio = (@height <= 0) ? 0 : (sprite.y - @y) * 1.0 / @height
sprite.zoom_y = opn
sprite.oy = 0
sprite.y = (@y + (@height / 2.0) + (@height * ratio * opn) - (@height / 2 * opn)).floor
oldbitmap = sprite.bitmap
oldsrcrect = sprite.src_rect.clone
end
else
for key in @spritekeys
sprite = @sprites[key]
sprite.zoom_y = 1.0
end
end
# Ensure z order
i = 0
for key in @spritekeys
sprite = @sprites[key]
y = sprite.y
sprite.y = i
sprite.oy = (sprite.zoom_y <= 0) ? 0 : (i - y) / sprite.zoom_y
end
end
end
#--------------------------------------------------------------------
# * intialize
#--------------------------------------------------------------------
def initialize(window)
@window=window
@x=0
@y=0
@width=0
@height=0
end
attr_reader :x,:y,:width,:height
#--------------------------------------------------------------------
# * empty
#--------------------------------------------------------------------
def empty
needupdate=@x!=0 || @y!=0 || @width!=0 || @height!=0
if needupdate
@x=0
@y=0
@width=0
@height=0
@window.width=@window.width
end
end
#--------------------------------------------------------------------
# * isEmpty
#--------------------------------------------------------------------
def isEmpty?
return @x==0 && @y==0 && @width==0 && @height==0
end
#--------------------------------------------------------------------
# * set
#--------------------------------------------------------------------
def set(x,y,width,height)
needupdate=@x!=x || @y!=y || @width!=width || @height!=height
if needupdate
@x=x
@y=y
@width=width
@height=height
@window.width=@window.width
end
end
#--------------------------------------------------------------------
# * height=
#--------------------------------------------------------------------
def height=(value)
@height=value; @window.width=@window.width
end
#--------------------------------------------------------------------
# * width=
#--------------------------------------------------------------------
def width=(value)
@width=value; @window.width=@window.width
end
#--------------------------------------------------------------------
# * x=
#--------------------------------------------------------------------
def x=(value)
@x=value; @window.width=@window.width
end
#--------------------------------------------------------------------
# * y=
#--------------------------------------------------------------------
def y=(value)
@y=value; @window.width=@window.width
end
end
#----------------------------------------------------------------------
# * Window Class
#----------------------------------------------------------------------
class Window
attr_reader :tone
attr_reader :color
attr_reader :blend_type
attr_reader :contents_blend_type
attr_reader :viewport
attr_reader :contents
attr_reader :ox
attr_reader :oy
attr_reader :x
attr_reader :y
attr_reader :z
attr_reader :width
attr_reader :active
attr_reader :pause
attr_reader :height
attr_reader :opacity
attr_reader :back_opacity
attr_reader :contents_opacity
attr_reader :visible
attr_reader :cursor_rect
attr_reader :openness
#--------------------------------------------------------------------
# * windowskin
#--------------------------------------------------------------------
def windowskin
return @_windowskin
end
#--------------------------------------------------------------------
# * intialize
#--------------------------------------------------------------------
def initialize(viewport=nil)
@sprites={}
@spritekeys=
[
"back",
"corner0","side0","scroll0",
"corner1","side1","scroll1",
"corner2","side2","scroll2",
"corner3","side3","scroll3",
"cursor","contents","pause"
]
@sidebitmaps=[nil,nil,nil,nil]
@cursorbitmap=nil
@bgbitmap=nil
@viewport=viewport
@spritekeys.each { |key| @sprites[key]=Sprite.new(@viewport) }
@disposed=false
@tone=Tone.new(0,0,0)
@color=Color.new(0,0,0,0)
@blankcontents=Bitmap.new(1,1) # RGSS2 requires this
@contents=@blankcontents
@_windowskin=nil
@rpgvx=false
@x=0
@y=0
@width=0
@openness=255
@height=0
@ox=0
@oy=0
@z=0
@stretch=true
@visible=true
@active=true
@blend_type=0
@contents_blend_type=0
@opacity=255
@back_opacity=255
@contents_opacity=255
@cursor_rect=WindowCursorRect.new(self)
@cursorblink=0
@cursoropacity=255
@pause=false
@pauseopacity=255
@pauseframe=0
privRefresh(true)
end
#--------------------------------------------------------------------
# * dispose
#--------------------------------------------------------------------
def dispose
if !self.disposed?
for i in @sprites
i[1].dispose if i[1]
@sprites[i[0]]=nil
end
for i in 0...@sidebitmaps.length
@sidebitmaps[i].dispose if @sidebitmaps[i]
@sidebitmaps[i]=nil
end
@blankcontents.dispose
@cursorbitmap.dispose if @cursorbitmap
@backbitmap.dispose if @backbitmap
@sprites.clear
@sidebitmaps.clear
@_windowskin=nil
@_contents=nil
@disposed=true
end
end
#--------------------------------------------------------------------
# * openness=
#--------------------------------------------------------------------
def openness=(value)
@openness=value
@openness=0 if @openness<0
@openness=255 if @openness>255
privRefresh
end
#--------------------------------------------------------------------
# * strecth=
#--------------------------------------------------------------------
def stretch=(value)
@stretch=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * visible=
#--------------------------------------------------------------------
def visible=(value)
@visible=value
privRefresh
end
#--------------------------------------------------------------------
# * viewposrt=
#--------------------------------------------------------------------
def viewport=(value)
@viewport=value
for i in @spritekeys
@sprites[i].dispose
if @sprites[i].is_a?(Sprite)
@sprites[i] = Sprite.new(@viewport)
elsif @sprites[i].is_a?(Plane)
@sprites[i] = Plane.new(@viewport)
else
@sprites[i] = nil
end
end
privRefresh(true)
end
#--------------------------------------------------------------------
# * z=
#--------------------------------------------------------------------
def z=(value)
@z=value
privRefresh
end
#--------------------------------------------------------------------
# * disposed?
#--------------------------------------------------------------------
def disposed?
return @disposed
end
#--------------------------------------------------------------------
# * contents=
#--------------------------------------------------------------------
def contents=(value)
@contents=value
privRefresh
end
#--------------------------------------------------------------------
# * windowskin=
#--------------------------------------------------------------------
def windowskin=(value)
@_windowskin=value
if value && value.is_a?(Bitmap) && !value.disposed? && value.width==128
@rpgvx=true
else
@rpgvx=false
end
privRefresh(true)
end
#--------------------------------------------------------------------
# * ox=
#--------------------------------------------------------------------
def ox=(value)
@ox=value
privRefresh
end
#--------------------------------------------------------------------
# * active=
#--------------------------------------------------------------------
def active=(value)
@active=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * cursor_rect=
#--------------------------------------------------------------------
def cursor_rect=(value)
if !value
@cursor_rect.empty
else
@cursor_rect.set(value.x,value.y,value.width,value.height)
end
end
#--------------------------------------------------------------------
# * oy=
#--------------------------------------------------------------------
def oy=(value)
@oy=value
privRefresh
end
#--------------------------------------------------------------------
# * width=
#--------------------------------------------------------------------
def width=(value)
@width=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * height=
#--------------------------------------------------------------------
def height=(value)
@height=value
privRefresh(true)
end
#--------------------------------------------------------------------
# * pause=
#--------------------------------------------------------------------
def pause=(value)
@pause=value
@pauseopacity=0 if !value
privRefresh
end
#--------------------------------------------------------------------
# * x=
#--------------------------------------------------------------------
def x=(value)
@x=value
privRefresh
end
#--------------------------------------------------------------------
# * y=
#--------------------------------------------------------------------
def y=(value)
@y=value
privRefresh
end
#--------------------------------------------------------------------
# * opacity=
#--------------------------------------------------------------------
def opacity=(value)
@opacity=value
@opacity=0 if @opacity<0
@opacity=255 if @opacity>255
privRefresh
end
#--------------------------------------------------------------------
# * back_opacity=
#--------------------------------------------------------------------
def back_opacity=(value)
@back_opacity=value
@back_opacity=0 if @back_opacity<0
@back_opacity=255 if @back_opacity>255
privRefresh
end
#--------------------------------------------------------------------
# * contents_opacity=
#--------------------------------------------------------------------
def contents_opacity=(value)
@contents_opacity=value
@contents_opacity=0 if @contents_opacity<0
@contents_opacity=255 if @contents_opacity>255
privRefresh
end
#--------------------------------------------------------------------
# * tone=
#--------------------------------------------------------------------
def tone=(value)
@tone=value
privRefresh
end
#--------------------------------------------------------------------
# * color=
#--------------------------------------------------------------------
def color=(value)
@color=value
privRefresh
end
#--------------------------------------------------------------------
# * blend_type=
#--------------------------------------------------------------------
def blend_type=(value)
@blend_type=value
privRefresh
end
#--------------------------------------------------------------------
# * flash
#--------------------------------------------------------------------
def flash(color,duration)
return if disposed?
@sprites.each {|sprite| sprite[1].flash(color,duration)}
end
def update
return if disposed?
mustchange=false
if @active
if @cursorblink==0
@cursoropacity-=8
@cursorblink = 1 if @cursoropacity<=128
else
@cursoropacity+=8
@cursorblink=0 if @cursoropacity>=255
end
mustchange=true if !@cursor_rect.isEmpty?
else
mustchange=true if @cursoropacity!=128
@cursoropacity=128
end
if @pause
@pauseframe=(Graphics.frame_count / 8) % 4
@pauseopacity=[@pauseopacity+64,255].min
mustchange=true
end
privRefresh if mustchange
for i in @sprites
i[1].update
end
end
#------------------ Private Methods ------------------#
private
#--------------------------------------------------------------------
# * ensureBitmap
#--------------------------------------------------------------------
def ensureBitmap(bitmap,dwidth,dheight)
if !bitmap||bitmap.disposed?||bitmap.width<dwidth||bitmap.height<dheight
bitmap.dispose if bitmap
bitmap=Bitmap.new([1,dwidth].max,[1,dheight].max)
end
return bitmap
end
#--------------------------------------------------------------------
# * tileBitmap
#--------------------------------------------------------------------
def tileBitmap(dstbitmap,dstrect,srcbitmap,srcrect)
return if !srcbitmap || srcbitmap.disposed?
left=dstrect.x
top=dstrect.y
y=0;loop do break unless y<dstrect.height
x=0;loop do break unless x<dstrect.width
dstbitmap.blt(x+left,y+top,srcbitmap,srcrect)
x+=srcrect.width
end
y+=srcrect.height
end
end
#--------------------------------------------------------------------
# * privRefresh
#--------------------------------------------------------------------
def privRefresh(changeBitmap=false)
return if self.disposed?
backopac = self.back_opacity * self.opacity / 255
contopac = self.contents_opacity
cursoropac = @cursoropacity * contopac / 255
@sprites["contents"].bitmap = @contents
unless @_windowskin.nil? || @_windowskin.disposed?
for i in 0...4
@sprites["corner#{i}"].bitmap = @_windowskin
@sprites["corner#{i}"].opacity = @opacity
@sprites["corner#{i}"].tone = @tone
@sprites["corner#{i}"].color = @color
@sprites["corner#{i}"].blend_type = @blend_type
@sprites["corner#{i}"].visible = @visible
@sprites["side#{i}"].opacity = @opacity
@sprites["side#{i}"].tone = @tone
@sprites["side#{i}"].color = @color
@sprites["side#{i}"].blend_type = @blend_type
@sprites["side#{i}"].visible = @visible
@sprites["scroll#{i}"].bitmap = @_windowskin
@sprites["scroll#{i}"].opacity = @opacity
@sprites["scroll#{i}"].tone = @tone
@sprites["scroll#{i}"].blend_type = @blend_type
@sprites["scroll#{i}"].color = @color
@sprites["scroll#{i}"].visible = @visible
end
@sprites["pause"].bitmap = @_windowskin
for key in ["back", "cursor", "pause", "contents"]
@sprites[key].color = @color
@sprites[key].tone = @tone
@sprites[key].blend_type = @blend_type
end
@sprites["contents"].blend_type = @contents_blend_type
@sprites["contents"].opacity = contopac
@sprites["contents"].visible = @visible && (@openness == 255)
@sprites["cursor"].opacity = cursoropac
@sprites["cursor"].visible = @visible && (@openness == 255)
@sprites["pause"].visible = @visible && @pause
@sprites["pause"].opacity = @pauseopacity
@sprites["back"].opacity = backopac
@sprites["back"].visible = @visible
hascontents = (!@contents.nil? && !@contents.disposed?)
@sprites["scroll0"].visible = @visible && hascontents && @oy > 0
@sprites["scroll1"].visible = @visible && hascontents && @ox > 0
@sprites["scroll2"].visible = @visible && hascontents && (@contents.width - @ox) > @width - 32
@sprites["scroll3"].visible = @visible && hascontents && (@contents.height - @oy) > @height - 32
else
for i in 0...4
@sprites["corner#{i}"].visible = false
@sprites["side#{i}"].visible = false
@sprites["scroll#{i}"].visible = false
end
@sprites["contents"].visible = @visible && @openness==255
@sprites["contents"].color = @color
@sprites["contents"].tone = @tone
@sprites["contents"].blend_type = @contents_blend_type
@sprites["contents"].opacity = contopac
@sprites["back"].visible = false
@sprites["pause"].visible = false
@sprites["cursor"].visible = false
end
@sprites.each { |sprite| sprite[1].z = @z }
if @rpgvx
@sprites["cursor"].z = @z # For Compatibility
@sprites["contents"].z = @z # For Compatibility
@sprites["pause"].z = @z # For Compatibility
trimX = 64
backRect = Rect.new(0,0,64,64)
blindsRect = Rect.new(0,64,64,64)
else
@sprites["cursor"].z = @z + 1 # For Compatibility
@sprites["contents"].z = @z + 2 # For Compatibility
@sprites["pause"].z = @z + 2 # For Compatibility
trimX = 128
backRect = Rect.new(0,0,128,128)
blindsRect = nil
end
trimY = 0
@sprites["corner0"].src_rect.set(trimX, trimY + 0, 16, 16);
@sprites["corner1"].src_rect.set(trimX + 48, trimY + 0, 16, 16);
@sprites["corner2"].src_rect.set(trimX, trimY + 48, 16, 16);
@sprites["corner3"].src_rect.set(trimX + 48, trimY + 48, 16, 16);
@sprites["scroll0"].src_rect.set(trimX + 24, trimY + 16, 16, 8) # up
@sprites["scroll3"].src_rect.set(trimX + 24, trimY + 40, 16, 8) # down
@sprites["scroll1"].src_rect.set(trimX + 16, trimY + 24, 8, 16) # left
@sprites["scroll2"].src_rect.set(trimX + 40, trimY + 24, 8, 16) # right
cursorX=trimX
cursorY=trimY + 64
sideRects= [ Rect.new(trimX + 16, trimY + 0, 32, 16),
Rect.new(trimX, trimY + 16, 16, 32),
Rect.new(trimX + 48, trimY + 16, 16, 32),
Rect.new(trimX + 16, trimY + 48, 32, 16) ]
if (@width > 32) && (@height > 32)
@sprites["contents"].src_rect.set(@ox, @oy, @width - 32, @height - 32)
else
@sprites["contents"].src_rect.set(0,0,0,0)
end
pauseRects=[ trimX + 32, trimY + 64,
trimX + 48, trimY + 64,
trimX + 32, trimY + 80,
trimX + 48, trimY + 80, ]
pauseWidth = 16
pauseHeight = 16
@sprites["pause"].src_rect.set( pauseRects[@pauseframe*2],
pauseRects[@pauseframe*2+1],
pauseWidth,pauseHeight )
@sprites["pause"].x = @x + (@width / 2) - (pauseWidth / 2)
@sprites["pause"].y = @y + @height - 16 # 16 refers to skin margin
@sprites["contents"].x = @x + 16
@sprites["contents"].y = @y + 16
@sprites["corner0"].x = @x
@sprites["corner0"].y = @y
@sprites["corner1"].x = @x + @width - 16
@sprites["corner1"].y = @y
@sprites["corner2"].x = @x
@sprites["corner2"].y = @y + @height - 16
@sprites["corner3"].x = @x + @width - 16
@sprites["corner3"].y = @y + @height - 16
@sprites["side0"].x = @x + 16
@sprites["side0"].y = @y
@sprites["side1"].x = @x
@sprites["side1"].y = @y + 16
@sprites["side2"].x = @x + @width - 16
@sprites["side2"].y = @y + 16
@sprites["side3"].x = @x + 16
@sprites["side3"].y = @y + @height - 16
@sprites["scroll0"].x = @x + @width / 2 - 8
@sprites["scroll0"].y = @y + 8
@sprites["scroll1"].x = @x + 8
@sprites["scroll1"].y = @y + @height / 2 - 8
@sprites["scroll2"].x = @x + @width - 16
@sprites["scroll2"].y = @y + @height / 2 - 8
@sprites["scroll3"].x = @x + @width / 2 - 8
@sprites["scroll3"].y = @y + @height - 16
@sprites["back"].x = @x + 2
@sprites["back"].y = @y + 2
@sprites["cursor"].x = @x + 16 + @cursor_rect.x
@sprites["cursor"].y = @y + 16 + @cursor_rect.y
if changeBitmap && !@_windowskin.nil? && !@_windowskin.disposed?
width = @cursor_rect.width
height = @cursor_rect.height
if (width > 0) && (height > 0)
cursorrects=[
# sides
Rect.new(cursorX+2, cursorY+0, 28, 2),
Rect.new(cursorX+0, cursorY+2, 2, 28),
Rect.new(cursorX+30, cursorY+2, 2, 28),
Rect.new(cursorX+2, cursorY+30, 28, 2),
# corners
Rect.new(cursorX+0, cursorY+0, 2, 2),
Rect.new(cursorX+30, cursorY+0, 2, 2),
Rect.new(cursorX+0, cursorY+30, 2, 2),
Rect.new(cursorX+30, cursorY+30, 2, 2),
# back
Rect.new(cursorX+2, cursorY+2, 28, 28)
]
margin = 2
fullmargin = 4
@cursorbitmap = ensureBitmap(@cursorbitmap, width, height)
@cursorbitmap.clear
@sprites["cursor"].bitmap = @cursorbitmap
@sprites["cursor"].src_rect.set(0, 0, width, height)
rect = Rect.new(margin, margin, width - fullmargin, height - fullmargin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[8])
@cursorbitmap.blt(0, 0, @_windowskin, cursorrects[4]) # top left
@cursorbitmap.blt(width-margin, 0, @_windowskin, cursorrects[5]) # top right
@cursorbitmap.blt(0, height-margin, @_windowskin, cursorrects[6])# bottom right
@cursorbitmap.blt(width-margin, height-margin, @_windowskin, cursorrects[7]) # bottom left
rect = Rect.new(margin, 0, width - fullmargin, margin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[0])
rect = Rect.new(0, margin, margin, height - fullmargin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[1])
rect = Rect.new(width - margin, margin, margin, height - fullmargin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[2])
rect = Rect.new(margin, height-margin, width - fullmargin, margin)
@cursorbitmap.stretch_blt(rect, @_windowskin, cursorrects[3])
else
@sprites["cursor"].visible = false
@sprites["cursor"].src_rect.set(0, 0, 0, 0)
end
for i in 0..3
dwidth = (i == 0 || i == 3) ? @width-32 : 16
dheight = (i == 0 || i == 3) ? 16 : @height - 32
@sidebitmaps[i] = ensureBitmap(@sidebitmaps[i], dwidth, dheight)
@sprites["side#{i}"].bitmap = @sidebitmaps[i]
@sprites["side#{i}"].src_rect.set(0, 0, dwidth, dheight)
@sidebitmaps[i].clear
if (sideRects[i].width > 0) && (sideRects[i].height > 0)
@sidebitmaps[i].stretch_blt( @sprites["side#{i}"].src_rect,
@_windowskin,sideRects[i] )
end
end
backwidth = @width-4
backheight = @height-4
if (backwidth > 0) && (backheight > 0)
@backbitmap = ensureBitmap(@backbitmap, backwidth, backheight)
@sprites["back"].bitmap = @backbitmap
@sprites["back"].src_rect.set(0, 0, backwidth, backheight)
@backbitmap.clear
if @stretch
@backbitmap.stretch_blt(@sprites["back"].src_rect, @_windowskin,backRect)
else
tileBitmap(@backbitmap,@sprites["back"].src_rect, @_windowskin,backRect)
end
if blindsRect
tileBitmap(@backbitmap,@sprites["back"].src_rect, @_windowskin,blindsRect)
end
else
@sprites["back"].visible = false
@sprites["back"].src_rect.set(0,0,0,0)
end
end
if @openness != 255
opn = @openness/255.0
for key in @spritekeys
sprite = @sprites[key]
ratio = (@height <= 0) ? 0 : (sprite.y - @y) * 1.0 / @height
sprite.zoom_y = opn
sprite.oy = 0
sprite.y = (@y + (@height / 2.0) + (@height * ratio * opn) - (@height / 2 * opn)).floor
oldbitmap = sprite.bitmap
oldsrcrect = sprite.src_rect.clone
end
else
for key in @spritekeys
sprite = @sprites[key]
sprite.zoom_y = 1.0
end
end
# Ensure z order
i = 0
for key in @spritekeys
sprite = @sprites[key]
y = sprite.y
sprite.y = i
sprite.oy = (sprite.zoom_y <= 0) ? 0 : (i - y) / sprite.zoom_y
end
end
end

