[XP] Windowskin Creator

Started by ThallionDarkshine, November 23, 2012, 10:22:19 pm

Previous topic - Next topic

ThallionDarkshine

November 23, 2012, 10:22:19 pm Last Edit: February 11, 2013, 04:54:50 pm by ThallionDarkshine
Windowskin Creator
Authors: ThallionDarkshine
Version: 1.0
Type: Options Menu
Key Term: Menu Add-on



Introduction

This script allows users to customize their own windowskins using the windowskins included in the windowskins folder. They can use parts of the existing windowskins to customize their own windowskin. Also allows them to change some font settings such as bold, italic, size, and normal_color, system_color, critical_color, etc. And once they are done creating their windowskins, they can save them.


Features


  • Allow users to create custom windowskins.

  • Allow users to recolor their windowskins.

  • Choose whether or not to use the RTP windowskins.

  • Allow users to save their windowskins.

  • Allow users to customize font properties.




Screenshots

Spoiler: ShowHide





Demo

No demo yet.


Script

Spoiler: ShowHide

module Windowskin_Config
 USE_RTP = false
end

class Scene_Windowskin
 def initialize
   @old_wskin = $game_system.config.windowskin_bitmap.clone
   @windowskins = []
   @bitmaps = []
   @inds = $game_system.config.wskin_inds.clone
   @names = $game_system.config.wskin_names.clone
   @props = $game_system.config.wskin_props.clone
   @old_font = Font.new
   @old_font.color = $game_system.config.normal_color
   @font = [$game_system.config.font_size, Font.default_bold, Font.default_italic]
   @normal_color, @system_color, @disabled_color, @crisis_color, @knockout_color = $game_system.config.normal_color.clone, $game_system.config.system_color.clone, $game_system.config.disabled_color.clone, $game_system.config.crisis_color.clone, $game_system.config.knockout_color.clone
   @windowskins.push('None')
   @bitmaps.push(Bitmap.new(192, 128))
   paths = []
   ini = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'PPPPLP', 'L')
   library = "\0" * 256
   ini.call('Game', 'Library', '', @library, 256, '.\\Game.ini')
   library.delete!("\0")
   getpath = Win32API.new(library, 'RGSSGetRTPPath', 'l', 'p')
   (1..3).each { |i| tmp = getpath.call(i);paths.push(tmp) unless tmp == '' } if Windowskin_Config::USE_RTP
   paths.push('')
   paths.each { |path|
     Dir[path + (path == '' ? '' : '/') + 'Graphics/Windowskins/*.{png,jpg,gif}'].each { |i|
       @windowskins.push(File.basename(i, '.*'))
       @bitmaps.push(RPG::Cache.windowskin(@windowskins.last))
     }
   }
 end
 
 def main
   # Create Main Command Window
   #  - This window displays windowskin options for designing and recoloring
   #   windowskins.
   s = ['Window Background', 'Window Frame', 'Scroll Arrows', 'Selection Bar', 'Pause Graphic', 'Battle Arrows']
   @command_window = Window_Command.new(256, s)
   @command_window.active = false
   # Create Windowskins Command Window
   #  - This window displays a list of all the windowskins for designing a
   #   windowskin.
   s = @windowskins.clone
   @wcommand_window = Window_Command.new(256, s)
   @wcommand_window.height = 256
   @wcommand_window.y = 224
   @wcommand_window.visible = @wcommand_window.active = false
   # Create Initial Command Window
   #  - This window displays the main choices.
   s = ['Windowskin Creation', 'Windowskin Recolors', 'Font Options', 'Save Config', 'Load Config', 'Exit']
   @scommand_window = Window_Command.new(288, s)
   @scommand_window.x = 176
   @scommand_window.y = 128
   @scommand_window.z = 1000
   # Create Recolor Command Window
   #  - This window displays recolor options such as hue and saturation.
   s = Array.new(3) { '' }
   @rcommand_window = Window_Command.new(256, s)
   @rcommand_window.height = 256
   @rcommand_window.y = 224
   @rcommand_window.active = @rcommand_window.visible = false
   # Create Font Command Window
   #  - This window displays options for changing font options.
   s = ['Font', 'Normal Color', 'System Color', 'Disabled Color', 'Crisis Color', 'Knockout Color']
   @fcommand_window = Window_Command.new(256, s)
   @fcommand_window.active = @fcommand_window.visible = false
   # Create Font Command Window
   #  - This window displays options for changing default font options.
   s = Array.new(4) { '' }
   @fcommand_window2 = Window_Command.new(256, s)
   @fcommand_window2.height = 256
   @fcommand_window2.y = 224
   @fcommand_window2.active = @fcommand_window2.visible = false
   # Create Color Command Window
   #  - This window displays options for choosing colors.
   s = Array.new(4) { '' }
   @ccommand_window = Window_Command.new(256, s)
   @ccommand_window.height = 256
   @ccommand_window.y = 224
   @ccommand_window.active = @ccommand_window.visible = false
   # Create Load Command Window
   #  - This window displays options for loading configurations.
   s = $data_configs.keys
   s = [''] if s.empty?
   @lcommand_window = Window_Command.new(288, s)
   @lcommand_window.height = 224
   @lcommand_window.x = 176
   @lcommand_window.y = 128
   @lcommand_window.z = 1000
   @lcommand_window.active = @lcommand_window.visible = false
   # Create Viewport
   #  - This dims the windows in the background.
   @viewport = Viewport.new(0, 0, 640, 480)
   @viewport.z = 999
   @viewport.tone = Tone.new(-70, -70, -70, 100)
   # Create 1st Windowskin Preview Window
   #  - This window displays the current chosen option while recoloring and
   #   designing windowskins.
   @preview_window = Window_WindowskinPreview.new(0)
   @preview_window.x = 256
   # Create 2nd Windowskin Preview Window
   #  - This window displays a preview of new windowskin options.
   @preview_window2 = Window_WindowskinPreview.new(1)
   @preview_window2.x = 256
   @preview_window2.y = 224
   @preview_window2.height = 256
   @preview_window2.visible = false
   # Create 1st Font Preview Window
   #  - This window displays the current chosen options while customizing fonts.
   font = Font.new
   font.color = @preview_window.normal_color
   @fpreview_window = Window_FontPreview.new(font, $game_system.config.font_size)
   @fpreview_window.x = 256
   @fpreview_window.visible = false
   # Create 2nd Font Preview Window
   #  - This window displays a preview of new font options.
   @fpreview_window2 = Window_FontPreview.new(font, $game_system.config.font_size)
   @fpreview_window2.x = 256
   @fpreview_window2.y = 224
   @fpreview_window2.height = 256
   @fpreview_window2.visible = false
   # Create Dummy Window
   #  - This window displays a preview of what the new windowskin would look like.
   @dummy_window = Window_Base.new(0, 224, 640, 256)
   @dummy_window.contents = Bitmap.new(642, 258)
   @dummy_window.contents.font.color = @normal_color.clone
   @dummy_window.contents.draw_text(Rect.new(1, 1, 640, 32), "This is an example window to demonstrate the windowskin you have", 0)
   @dummy_window.contents.draw_text(Rect.new(1, 33, 640, 32), "created.", 0)
   @contents = @dummy_window.contents.clone
   @dummy_window.cursor_rect.set(0, 64, 608, 64)
   @dummy_window.pause = true
   @dummy_window.ox = @dummy_window.oy = 1
   # Create Text Window
   #  - This window allows the user to choose a name for their config.
   @text_window = Window_Text.new(192, 208, 256, 64)
   @text_window.z = 1000
   @text_window.multi_line = false
   @text_window.active = @text_window.visible = false
   # Execute Transition
   Graphics.transition
   # Main loop
   loop do
     # Update game screen
     Graphics.update
     # Update input information
     Input.update
     # Frame update
     update
     # Abort loop if screen is changed
     if $scene != self
       break
     end
   end
   # Prepare for transition
   Graphics.freeze
   $game_system.config.wskin_inds = @inds.clone
   $game_system.config.wskin_names = @names.clone
   $game_system.config.wskin_props = @props.clone.map { |i| i.clone if i.is_a?(Array) }
   $game_system.config.normal_color, $game_system.config.system_color, $game_system.config.disabled_color, $game_system.config.crisis_color, $game_system.config.knockout_color = @normal_color.clone, @system_color.clone, @disabled_color.clone, @crisis_color.clone, @knockout_color.clone
   # Dispose of windows
   @command_window.dispose
   @wcommand_window.dispose
   @scommand_window.dispose
   @rcommand_window.dispose
   @fcommand_window.dispose
   @fcommand_window2.dispose
   @ccommand_window.dispose
   @lcommand_window.dispose
   @viewport.dispose
   @preview_window.dispose
   @preview_window2.dispose
   @fpreview_window.dispose
   @fpreview_window2.dispose
   @dummy_window.dispose
   @text_window.dispose
 end
 
 def update
   if @command_window.active
     update_command
   elsif @wcommand_window.active
     update_chooser
   elsif @scommand_window.active
     update_scommand
   elsif @rcommand_window.active
     update_recolor
   elsif @fcommand_window.active
     update_text
   elsif @fcommand_window2.active
     update_font
   elsif @ccommand_window.active
     update_color
   elsif @text_window.active
     update_save
   elsif @lcommand_window.active
     update_load
   end
 end
 
 def update_command
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     Graphics.freeze
     @viewport.tone = Tone.new(-70, -70, -70, 100)
     @scommand_window.visible = @scommand_window.active = true
     if @mode == 1
       s = @command_window.commands.clone
       s.shift
       @command_window.dispose
       @command_window = Window_Command.new(256, s)
       @command_window.windowskin = @old_wskin
       @command_window.contents.font = @old_font
       @command_window.refresh
     end
     @command_window.active = false
     Graphics.transition
   end
   @command_window.update
   @dummy_window.update
   if Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     Graphics.freeze
     case @mode
     when 0:
       @command_window.active = @dummy_window.active = @dummy_window.visible = false
       @wcommand_window.visible = @preview_window2.visible = @wcommand_window.active = @preview_window2.active = true
       @preview_window.set(1, @command_window.index)
       @wcommand_window.index = @inds[@command_window.index]
       @preview_window2.set(1, @command_window.index, @windowskins[@wcommand_window.index])
     when 1:
       @command_window.active = @dummy_window.active = @dummy_window.visible = false
       @rcommand_window.visible = @preview_window2.visible = @rcommand_window.active = @preview_window2.active = true
       @preview_window.set(1, (@command_window.index == 0 ? 6 : @command_window.index - 1), (@command_window.index == 0 ? '' : @names[@command_window.index - 1]))
       @preview_window.set_props(@props[@command_window.index])
       @saved_props = @props[@command_window.index]
       @preview_window2.set(1, (@command_window.index == 0 ? 6 : @command_window.index - 1), (@command_window.index == 0 ? '' : @names[@command_window.index - 1]))
       refresh_props
     end
     Graphics.transition
   end
 end
 
 def update_scommand
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     $scene = Scene_Map.new
   end
   if Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se) unless @scommand_window.index == 5
     Graphics.freeze
     case @scommand_window.index
     when 0:
       @mode = 0
       @viewport.tone = Tone.new(0, 0, 0)
       @scommand_window.visible = @scommand_window.active = false
       @command_window.active = true
     when 1:
       @mode = 1
       @viewport.tone = Tone.new(0, 0, 0)
       @scommand_window.visible = @scommand_window.active = false
       s = @command_window.commands.clone
       s.unshift('Windowskin')
       @command_window.dispose
       @command_window = Window_Command.new(256, s)
       @command_window.height -= 32
       @command_window.windowskin = @old_wskin
       @command_window.refresh
     when 2:
       @viewport.tone = Tone.new(0, 0, 0)
       @scommand_window.visible = @scommand_window.active = @command_window.visible = @preview_window.visible = @preview_window2.visible = false
       @fcommand_window.visible = @fcommand_window.active = @fpreview_window.visible = true
       @fpreview_window.set()
       refresh_font
     when 3:
       @scommand_window.visible = @scommand_window.active = false
       @text_window.active = @text_window.visible = true
       @text_window.text = ''
       @text_window.refresh
     when 4:
       @scommand_window.visible = @scommand_window.active = false
       @lcommand_window.visible = @lcommand_window.active = true
       if $data_configs.keys.empty?
         @lcommand_window.cursor_rect.empty
         @lcommand_window.contents = Bitmap.new(256, 192)
         @lcommand_window.contents.draw_text(@lcommand_window.contents.rect, 'No Configs Available to Load', 1)
       end
     when 5:
       $game_system.se_play($data_system.cancel_se)
       $scene = Scene_Map.new
     end
     Graphics.transition
   end
   @scommand_window.update
 end
 
 def update_load
   @lcommand_window.update unless $data_configs.keys.empty?
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     Graphics.freeze
     @scommand_window.visible = @scommand_window.active = true
     @lcommand_window.visible = @lcommand_window.active = false
     Graphics.transition
   end
   
   if Input.trigger?(Input::C) and !$data_configs.keys.empty?
     $game_system.se_play($data_system.decision_se)
     $game_system.config = $data_configs[$data_configs.keys[@lcommand_window.index]]
     $game_system.config.font_bold = $game_system.config.font_bold
     $game_system.config.font_italic = $game_system.config.font_italic
     $scene = Scene_Windowskin.new
   end
 end
 
 def update_save
   @text_window.update
   if Input.trigger?(Input::Key['Esc'])
     $game_system.se_play($data_system.cancel_se)
     Graphics.freeze
     @scommand_window.visible = @scommand_window.active = true
     @text_window.active = @text_window.visible = false
     @text_window.text = ''
     Graphics.transition
   end
   if Input.trigger?(Input::Key['Enter'])
     text = @text_window.text.clone
     if text.length == 0
       $game_system.se_play($data_system.buzzer_se)
     else
       $game_system.se_play($data_system.decision_se)
       $data_configs[text] = $game_system.config.clone
       $data_configs[text].name = text
       $data_skins[text] = [$game_system.config.windowskin_bitmap.clone, $game_system.config.rwskin_bitmap.clone]
       $game_system.config.name = text
       file = File.open("Configs/Configs.rxdata", "w")
       Marshal.dump($data_configs, file)
       $data_skins.each { |key, val|
         next if key == 'default'
         val[0].make_png(key, 'Configs/')
         val[1].make_png('r_'+key, 'Configs/')
       }
       s = $data_configs.keys
       @lcommand_window.dispose
       @lcommand_window = Window_Command.new(288, s)
       @lcommand_window.height = 224
       @lcommand_window.x = 176
       @lcommand_window.y = 128
       @lcommand_window.z = 1000
       @lcommand_window.active = @lcommand_window.visible = false
       @lcommand_window.windowskin = @old_wskin
       @lcommand_window.contents.font = @old_font
       @lcommand_window.refresh
       Graphics.freeze
       @scommand_window.visible = @scommand_window.active = true
       @text_window.active = @text_window.visible = false
       @text_window.text = ''
       Graphics.transition
     #  if text.index(/\.rxdata/) == -1
     #    text += '.rxdata'
     #  end
     #  file = File.open('Configs/' + text, 'w')
     #  Marshal.dump($game_system.config, file)
     end
   end
 end
 
 def update_chooser
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     Graphics.freeze
     @command_window.active = @dummy_window.active = @dummy_window.visible = true
     @wcommand_window.visible = @preview_window2.visible = @wcommand_window.active = @preview_window2.active = false
     @preview_window.set(0)
     recreate_dummy
     Graphics.transition
   end
   if Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     Graphics.freeze
     @inds[@command_window.index] = @wcommand_window.index
     @names[@command_window.index] = @windowskins[@wcommand_window.index]
     source = @bitmaps[@wcommand_window.index].clone
     bitmap = $game_system.config.rwskin_bitmap
     case @command_window.index
     when 0:
       bitmap.fill_rect(Rect.new(0, 0, 128, 128), Color.new(0, 0, 0, 0))
       bitmap.blt(0, 0, source, Rect.new(0, 0, 128, 128))
     when 1:
       bitmap.fill_rect(Rect.new(128, 0, 64, 16), Color.new(0, 0, 0, 0))
       bitmap.fill_rect(Rect.new(128, 16, 16, 32), Color.new(0, 0, 0, 0))
       bitmap.fill_rect(Rect.new(176, 16, 16, 32), Color.new(0, 0, 0, 0))
       bitmap.fill_rect(Rect.new(128, 48, 64, 16), Color.new(0, 0, 0, 0))
       bitmap.blt(128, 0, source, Rect.new(128, 0, 64, 16))
       bitmap.blt(128, 16, source, Rect.new(128, 16, 16, 32))
       bitmap.blt(176, 16, source, Rect.new(176, 16, 16, 32))
       bitmap.blt(128, 48, source, Rect.new(128, 48, 64, 16))
     when 2:
       bitmap.fill_rect(Rect.new(144, 16, 32, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(144, 16, source, Rect.new(144, 16, 32, 32))
     when 3:
       bitmap.fill_rect(Rect.new(128, 64, 32, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(128, 64, source, Rect.new(128, 64, 32, 32))
     when 4:
       bitmap.fill_rect(Rect.new(160, 64, 32, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(160, 64, source, Rect.new(160, 64, 32, 32))
     when 5:
       bitmap.fill_rect(Rect.new(128, 96, 64, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(128, 96, source, Rect.new(128, 96, 64, 32))
     end
     refresh_wskin
     @preview_window.set(1, @command_window.index)
     Graphics.transition
   end
   ind = @wcommand_window.index
   @wcommand_window.update
   if @wcommand_window.index != ind
     @preview_window2.set(1, @command_window.index, @windowskins[@wcommand_window.index])
   end
 end
 
 def update_text
   @fcommand_window.update
   if Input.trigger?(Input::C)
     Graphics.freeze
     case @fcommand_window.index
     when 0:
       @fcommand_window.active = @dummy_window.visible = false
       @fcommand_window2.active = @fcommand_window2.visible = @fpreview_window2.visible = true
     else
       @fcommand_window.active = @dummy_window.visible = false
       @ccommand_window.active = @ccommand_window.visible = @fpreview_window2.visible = true
       refresh_color
       @fpreview_window.font.color = @fpreview_window2.font.color.clone
       @fpreview_window.refresh
     end
     Graphics.transition
   end
   if Input.trigger?(Input::B)
     Graphics.freeze
     @viewport.tone = Tone.new(-70, -70, -70, 100)
     @scommand_window.visible = @scommand_window.active = @command_window.visible = @preview_window.visible = true
     @fcommand_window.visible = @fcommand_window.active = @fpreview_window.visible = false
     Graphics.transition
   end
 end
 
 def update_font
   @fcommand_window2.update
   if Input.repeat?(Input::LEFT)
     case @fcommand_window2.index
     when 0:
       @font[0] = [@font[0] - 1, 50].max
     when 1:
       @font[1] = !@font[1]
     when 2:
       @font[2] = !@font[2]
     end
     refresh_font
   end
   if Input.repeat?(Input::RIGHT)
     case @fcommand_window2.index
     when 0:
       @font[0] = [@font[0] + 1, 150].min
     when 1:
       @font[1] = !@font[1]
     when 2:
       @font[2] = !@font[2]
     end
     refresh_font
   end
   if Input.trigger?(Input::C) and @fcommand_window2.index == 3
     $game_system.config.font_size, $game_system.config.font_bold, $game_system.config.font_italic = *@font
     @fpreview_window.set()
   end
   if Input.trigger?(Input::B)
     @font = @fpreview_window.props.clone
     Graphics.freeze
     refresh_font
     @fcommand_window.active = true
     @fcommand_window2.active = @fcommand_window2.visible = @fpreview_window2.visible = false
     recreate_dummy
     Graphics.transition
   end
 end
 
 def update_color
   @ccommand_window.update
   if Input.repeat?(Input::LEFT)
     case @fcommand_window.index
     when 1:
       color = @normal_color
     when 2:
       color = @system_color
     when 3:
       color = @disabled_color
     when 4:
       color = @crisis_color
     when 5:
       color = @knockout_color
     end
     case @ccommand_window.index
     when 0:
       color.red = [color.red - 1, 0].max
     when 1:
       color.green = [color.green - 1, 0].max
     when 2:
       color.blue = [color.blue - 1, 0].max
     end
     refresh_color
   end
   if Input.repeat?(Input::RIGHT)
     case @fcommand_window.index
     when 1:
       color = @normal_color
     when 2:
       color = @system_color
     when 3:
       color = @disabled_color
     when 4:
       color = @crisis_color
     when 5:
       color = @knockout_color
     end
     case @ccommand_window.index
     when 0:
       color.red = [color.red + 1, 255].min
     when 1:
       color.green = [color.green + 1, 255].min
     when 2:
       color.blue = [color.blue + 1, 255].min
     end
     refresh_color
   end
   if Input.trigger?(Input::C) and @ccommand_window.index == 3
     font = Font.new
     case @fcommand_window.index
     when 1:
       font.color = @normal_color.clone
     when 2:
       font.color = @system_color.clone
     when 3:
       font.color = @disabled_color.clone
     when 4:
       font.color = @crisis_color.clone
     when 5:
       font.color = @knockout_color.clone
     end
     @fpreview_window.set(font, 100.0)
   end
   if Input.trigger?(Input::B)
     color = @fpreview_window.props[3].clone
     case @fcommand_window.index
     when 1:
       @normal_color = color
     when 2:
       @system_color = color
     when 3:
       @disabled_color = color
     when 4:
       @crisis_color = color
     when 5:
       @knockout_color = color
     end
     Graphics.freeze
     refresh_color
     @fpreview_window.set()
     @fcommand_window.active = true
     @ccommand_window.active = @ccommand_window.visible = @fpreview_window2.visible = false
     recreate_dummy
     Graphics.transition
   end
 end
 
 def update_recolor
   @rcommand_window.update
   if Input.repeat?(Input::LEFT)
     props = @props[@command_window.index]
     case @rcommand_window.index
     when 0:
       props[0] = [props[0] - 1, 0].max
     when 1:
       props[1] = [props[1] - 1, 0].max
     end
     refresh_props unless @rcommand_window.index == 2
   end
   if Input.repeat?(Input::RIGHT)
     props = @props[@command_window.index]
     case @rcommand_window.index
     when 0:
       props[0] = [props[0] + 1, 360].min
     when 1:
       props[1] = [props[1] + 1, 100].min
     end
     refresh_props unless @rcommand_window.index == 2
   end
   if Input.trigger?(Input::C) and @rcommand_window.index == 2
     bitmap = $game_system.config.rwskin_bitmap
     source = @preview_window2.bitmap
     case @command_window.index
     when 1:
       bitmap.fill_rect(Rect.new(0, 0, 128, 128), Color.new(0, 0, 0, 0))
       bitmap.blt(0, 0, source, source.rect)
     when 2:
       bitmap.fill_rect(Rect.new(128, 0, 64, 16), Color.new(0, 0, 0, 0))
       bitmap.fill_rect(Rect.new(128, 16, 16, 32), Color.new(0, 0, 0, 0))
       bitmap.fill_rect(Rect.new(176, 16, 16, 32), Color.new(0, 0, 0, 0))
       bitmap.fill_rect(Rect.new(128, 48, 64, 16), Color.new(0, 0, 0, 0))
       bitmap.blt(128, 0, source, Rect.new(0, 0, 64, 16))
       bitmap.blt(128, 16, source, Rect.new(0, 16, 16, 32))
       bitmap.blt(176, 16, source, Rect.new(48, 16, 16, 32))
       bitmap.blt(128, 48, source, Rect.new(0, 48, 64, 16))
     when 3:
       bitmap.fill_rect(Rect.new(144, 16, 32, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(144, 16, source, source.rect)
     when 4:
       bitmap.fill_rect(Rect.new(128, 64, 32, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(128, 64, source, source.rect)
     when 5:
       bitmap.fill_rect(Rect.new(160, 64, 32, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(160, 64, source, source.rect)
     when 6:
       bitmap.fill_rect(Rect.new(128, 96, 64, 32), Color.new(0, 0, 0, 0))
       bitmap.blt(128, 96, source, source.rect)
     end
     refresh_wskin
     @preview_window.set((@command_window.index == 0 ? 0 : 1), (@command_window.index == 0 ? 6 : @command_window.index - 1))
     #@preview_window.set_props([0, 100])#@props[@command_window.index])
     @saved_props = @props[@command_window.index]
   end
   if Input.trigger?(Input::B)
     @props[@command_window.index] = @saved_props
     @command_window.active = true
     recreate_dummy
     @rcommand_window.visible = @preview_window2.visible = @rcommand_window.active = @preview_window2.active = false
     @preview_window.set(0)
   end
 end
 
 def refresh_font
   @fcommand_window2.commands = ['Font Size: ' + @font[0].to_s + '%', 'Font Bold: ' + @font[1].to_s, 'Font Italic: ' + @font[2].to_s]
   @fcommand_window2.commands.push('Save Changes')
   @fcommand_window2.refresh
   font = Font.new(false)
   font.bold = @font[1]
   font.italic = @font[2]
   @fpreview_window2.set(font, @font[0])
 end
 
 def refresh_color
   color = Color.new(0, 0, 0)
   case @fcommand_window.index
   when 1:
     color = @normal_color.clone
   when 2:
     color = @system_color.clone
   when 3:
     color = @disabled_color.clone
   when 4:
     color = @crisis_color.clone
   when 5:
     color = @knockout_color.clone
   end
   @ccommand_window.commands = ['Red: ' + color.red.to_s, 'Green: ' + color.green.to_s, 'Blue: ' + color.blue.to_s]
   @ccommand_window.commands.push('Save Changes')
   @ccommand_window.refresh
   font = Font.new(false)
   font.color = color.clone
   @fpreview_window2.set(font, $game_system.config.font_size)
 end
 
 def refresh_props
   props = @props[@command_window.index]
   @rcommand_window.commands = ['Hue: ' + props[0].to_s, 'Gray: ' + props[1].to_s]
   @rcommand_window.commands.push('Save Changes')
   @rcommand_window.refresh
   @preview_window2.set_props(props)
 end
 
 def refresh_wskin
   $game_system.config.windowskin_bitmap = $game_system.config.rwskin_bitmap.clone
   $game_system.config.windowskin_bitmap.hue_change(@props[0][0])
   grayscale = Win32API.new('rgss_addon', 'grayscale', 'li', 'b')
   grayscale.call($game_system.config.windowskin_bitmap.__id__, 100 - @props[0][1])
 end
 
 def recreate_dummy
   @dummy_window.dispose
   @dummy_window = Window_Base.new(0, 224, 640, 256)
   @dummy_window.contents = Bitmap.new(@contents.width, @contents.height)
   @dummy_window.contents.font.color = @normal_color.clone
   @dummy_window.contents.draw_text(Rect.new(1, 1, 640, 32), "This is an example window to demonstrate the windowskin you have", 0)
   @dummy_window.contents.draw_text(Rect.new(1, 33, 640, 32), "created.", 0)
   @dummy_window.cursor_rect.set(0, 64, 608, 64)
   @dummy_window.pause = true
   @dummy_window.ox = @dummy_window.oy = 1
 end
end

class Window_WindowskinPreview < Window_Base
 attr_reader :bitmap, :real_bitmap, :props
 
 def initialize(type, subtype = 0)
   super(0, 0, 384, 224)
   self.contents = Bitmap.new(width - 32, height - 32)
   @props = [0, 100]
   @type = type
   @subtype = subtype if @type == 1
   @bitmap = (type == 0 ? $game_system.config.windowskin_bitmap.clone : $game_system.config.rwskin_bitmap.clone)
   if @type == 1
     case @subtype
     when 0:
       bitmap = Bitmap.new(128, 128)
       bitmap.blt(0, 0, @bitmap, Rect.new(0, 0, 128, 128))
     when 1:
       bitmap = Bitmap.new(64, 64)
       bitmap.blt(0, 0, @bitmap, Rect.new(128, 0, 64, 16))
       bitmap.blt(0, 16, @bitmap, Rect.new(128, 16, 16, 32))
       bitmap.blt(48, 16, @bitmap, Rect.new(176, 16, 16, 32))
       bitmap.blt(0, 48, @bitmap, Rect.new(128, 48, 64, 16))
     when 2:
       bitmap = Bitmap.new(32, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(144, 16, 32, 32))
     when 3:
       bitmap = Bitmap.new(32, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(128, 64, 32, 32))
     when 4:
       bitmap = Bitmap.new(32, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(160, 64, 32, 32))
     when 5:
       bitmap = Bitmap.new(64, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(128, 96, 64, 32))
     when 6:
       bitmap = @bitmap
     end
     @bitmap = bitmap.clone
   end
   refresh
 end
 
 def update
   super()
 end
 
 def refresh
   self.contents.clear
   x, y = (self.contents.width - @bitmap.width) / 2, (self.contents.height - @bitmap.height) / 2
   self.contents.fill_rect(Rect.new(x - 1, y - 1, @bitmap.width + 2, @bitmap.height + 2), Color.new(0, 0, 0))
   self.contents.blt(x, y, @bitmap, @bitmap.rect)
 end
 
 def set(type, subtype = 0, name = '')
   @type = type
   @subtype = subtype if @type == 1
   @props = [0, 100]
   @bitmap = (name == '' ? (type == 0 ? $game_system.config.windowskin_bitmap.clone : $game_system.config.rwskin_bitmap.clone) : (name == 'None' ? Bitmap.new(192, 128) : RPG::Cache.windowskin(name).clone))
   if @type == 1
     case @subtype
     when 0:
       bitmap = Bitmap.new(128, 128)
       bitmap.blt(0, 0, @bitmap, Rect.new(0, 0, 128, 128))
     when 1:
       bitmap = Bitmap.new(64, 64)
       bitmap.blt(0, 0, @bitmap, Rect.new(128, 0, 64, 16))
       bitmap.blt(0, 16, @bitmap, Rect.new(128, 16, 16, 32))
       bitmap.blt(48, 16, @bitmap, Rect.new(176, 16, 16, 32))
       bitmap.blt(0, 48, @bitmap, Rect.new(128, 48, 64, 16))
     when 2:
       bitmap = Bitmap.new(32, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(144, 16, 32, 32))
     when 3:
       bitmap = Bitmap.new(32, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(128, 64, 32, 32))
     when 4:
       bitmap = Bitmap.new(32, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(160, 64, 32, 32))
     when 5:
       bitmap = Bitmap.new(64, 32)
       bitmap.blt(0, 0, @bitmap, Rect.new(128, 96, 64, 32))
     when 6:
       bitmap = @bitmap
     end
     @real_bitmap = bitmap.clone
     @bitmap = @real_bitmap.clone
   end
   refresh
 end
 
 def set_props(props)
   @props = props.clone
   grayscale = Win32API.new('rgss_addon', 'grayscale', 'li', 'b')
   @bitmap = @real_bitmap.clone
   @bitmap.hue_change(props[0])
   grayscale.call(@bitmap.__id__, 100 - props[1])
   refresh
 end
end

class Window_FontPreview < Window_Base
 attr_accessor :font
 attr_reader :props
 
 def initialize(font, size)
   super(0, 0, 384, 224)
   self.contents = Bitmap.new(width - 32, height - 32)
   @font = font.clone
   @real_size = @font.size
   @font.real_size = @real_size * size / 100
   @props = [size, font.bold, font.italic, font.color]
   refresh
 end
 
 def set(*args)
   @args = args
   if args.empty?
     font = Font.new
     font.color = $scene.instance_variable_get(:@normal_color).clone
     font.real_size = font.size
     size = $game_system.config.font_size
   else
     font = args[0]
     size = args[1]
   end
   @font = font.clone
   @real_size = @font.size
   @font.real_size = @real_size * size / $game_system.config.font_size
   @props = [size, font.bold, font.italic, font.color]
   refresh
 end
 
 def refresh
   self.contents.clear
   self.contents.font = @font
   self.contents.font.real_size = @font.size.to_f
   self.contents.draw_text(Rect.new(0, 0, self.contents.width, 32), 'This is example text created to')
   self.contents.draw_text(Rect.new(0, 32, self.contents.width, 32), 'demonstrate your chosen font.')
   self.contents.draw_text(Rect.new(0, 64, self.contents.width, 32), 'More Text')
 end
end

class Game_System
 attr_accessor :config
 
 alias tdks_wskin_init initialize
 def initialize
   tdks_wskin_init
   @config = Game_Wskin_Config.new    
   $data_configs = {}
   if FileTest.exists?("Configs/Configs.rxdata")
     $data_configs = Marshal.load(File.open("Configs/Configs.rxdata"))
   end
   $data_skins = {}
   $data_configs.keys.each { |i|
     $data_skins[i] = [RPG::Cache.load_bitmap("Configs/", i).clone, RPG::Cache.load_bitmap("Configs/", "r_" + i).clone]
   }
   $data_skins["default"] = Array.new(2) { RPG::Cache.windowskin($data_system.windowskin_name) }
 end
end

class Game_Wskin_Config
 attr_accessor :wskin_inds, :wskin_props, :wskin_names
 attr_accessor :normal_color, :system_color, :disabled_color, :crisis_color, :knockout_color
 attr_accessor :font_size
 attr_accessor :name
 attr_reader   :font_bold, :font_italic
 
 def initialize
   @name = 'default'
   #@windowskin_bitmap = RPG::Cache.windowskin($data_system.windowskin_name).clone
   #@rwskin_bitmap = @windowskin_bitmap.clone
   paths = []
   windowskins = []
   ini = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'PPPPLP', 'L')
   library = "\0" * 256
   ini.call('Game', 'Library', '', @library, 256, '.\\Game.ini')
   library.delete!("\0")
   getpath = Win32API.new(library, 'RGSSGetRTPPath', 'l', 'p')
   (1..3).each { |i| tmp = getpath.call(i);paths.push(tmp) unless tmp == '' } if Windowskin_Config::USE_RTP
   paths.push('')
   paths.each { |path|
     Dir[path + (path == '' ? '' : '/') + 'Graphics/Windowskins/*.{png,jpg,gif}'].each { |i|
       windowskins.push(File.basename(i, '.*'))
     }
   }
   ind = windowskins.index($data_system.windowskin_name) + 1
   @wskin_inds = Array.new(6) { ind }
   @wskin_names = Array.new(6) { $data_system.windowskin_name }
   @wskin_props = Array.new(7) { [0, 100].clone }
   @normal_color = Color.new(255, 255, 255, 255)
   @system_color = Color.new(192, 224, 255, 255)
   @disabled_color = Color.new(255, 255, 255, 128)
   @crisis_color = Color.new(255, 255, 64, 255)
   @knockout_color = Color.new(255, 64, 0)
   @font_size = 100
   @font_bold = false
   @font_italic = false
 end
 
 def rwskin_bitmap
   $data_skins[@name][1]
 end
 def windowskin_bitmap
   $data_skins[@name][0]
 end
 
 def rwskin_bitmap=(val)
   $data_skins[@name][1] = val
 end
 def windowskin_bitmap=(val)
   $data_skins[@name][0] = val
 end
 
 def font_bold=(val)
   @font_bold = Font.default_bold = val
 end
 def font_italic=(val)
   @font_italic = Font.default_italic = val
 end
end

class Window_Base
 alias tdks_wskin_init initialize
 def initialize(*args)
   tdks_wskin_init(*args)
   self.windowskin = $game_system.config.windowskin_bitmap.clone
 end
 
 def normal_color
   return $game_system.config.normal_color
 end
 
 def disabled_color
   return $game_system.config.disabled_color
 end
 
 def system_color
   return $game_system.config.system_color
 end
 
 def crisis_color
   return $game_system.config.crisis_color
 end
 
 def knockout_color
   return $game_system.config.knockout_color
 end
end

class Arrow_Base
 alias tdks_wskin_init initialize
 def initialize(*args)
   tdks_wskin_init(*args)
   self.bitmap = $game_system.config.windowskin_bitmap.clone
 end
end

class Game_Map
 alias tdks_wskin_updt update
 def update
   if Input.trigger?(Input::F7)
     $game_system.se_play($data_system.decision_se)
     $scene = Scene_Windowskin.new
   end
   tdks_wskin_updt
 end
end

class Window_Command
 attr_accessor :commands
end

class Font
 alias tdks_wskin_init initialize
 def initialize(*args)
   tdks_wskin_init(*args)
   @real_size = (args.length > 1 ? args[2] : Font.default_size)
   if args.length == 1 and args[0] == false
     self.name = Font.default_name
     self.real_size = @real_size
   else
     self.size = @real_size
   end
 end
 
 alias tdks_wskin_size size
 def size
   return @real_size
 end
 
 def real_size
   return tdks_wskin_size
 end
 
 alias tdks_wskin_size= size=
 def size=(val)
   val = Font.default_size if val == nil
   @real_size = val
   val = [val * $game_system.config.font_size / 100, 96].min if $game_system != nil
   self.tdks_wskin_size=(val)
 end
 
 def real_size=(val)
   val = [val, 96].min
   @real_size = val
   self.tdks_wskin_size=(val)
 end
 
 def inspect
   str = super()
   str = str[0...str.length - 1]
   props = [:name, :size, :bold, :italic, :color, :real_size]
   props.each { |i| str += ' ' + i.to_s + ' = ';str += ' ' + eval("self.#{i.to_s}").inspect }
   str
 end
end

#==============================================================================
# module Input
#==============================================================================

module Input
 
 #----------------------------------------------------------------------------
 # Simple ASCII table
 #----------------------------------------------------------------------------
 Key = {'A' => 65, 'B' => 66, 'C' => 67, 'D' => 68, 'E' => 69, 'F' => 70,
        'G' => 71, 'H' => 72, 'I' => 73, 'J' => 74, 'K' => 75, 'L' => 76,
        'M' => 77, 'N' => 78, 'O' => 79, 'P' => 80, 'Q' => 81, 'R' => 82,
        'S' => 83, 'T' => 84, 'U' => 85, 'V' => 86, 'W' => 87, 'X' => 88,
        'Y' => 89, 'Z' => 90,
        '0' => 48, '1' => 49, '2' => 50, '3' => 51, '4' => 52, '5' => 53,
        '6' => 54, '7' => 55, '8' => 56, '9' => 57,
        'NumberPad 0' => 45, 'NumberPad 1' => 35, 'NumberPad 2' => 40,
        'NumberPad 3' => 34, 'NumberPad 4' => 37, 'NumberPad 5' => 12,
        'NumberPad 6' => 39, 'NumberPad 7' => 36, 'NumberPad 8' => 38,
        'NumberPad 9' => 33,
        'F1' => 112, 'F2' => 113, 'F3' => 114, 'F4' => 115, 'F5' => 116,
        'F6' => 117, 'F7' => 118, 'F8' => 119, 'F9' => 120, 'F10' => 121,
        'F11' => 122, 'F12' => 123,
        ';' => 186, '=' => 187, ',' => 188, '-' => 189, '.' => 190, '/' => 220,
        '\\' => 191, '\'' => 222, '[' => 219, ']' => 221, '`' => 192,
        'Backspace' => 8, 'Tab' => 9, 'Enter' => 13, 'Shift' => 16,
        'Left Shift' => 160, 'Right Shift' => 161, 'Left Ctrl' => 162,
        'Right Ctrl' => 163, 'Left Alt' => 164, 'Right Alt' => 165,
        'Ctrl' => 17, 'Alt' => 18, 'Esc' => 27, 'Space' => 32, 'Page Up' => 33,
        'Page Down' => 34, 'End' => 35, 'Home' => 36, 'Insert' => 45,
        'Delete' => 46, 'Arrow Left' => 37, 'Arrow Up' => 38,
        'Arrow Right' => 39, 'Arrow Down' => 40,
        'Mouse Left' => 1, 'Mouse Right' => 2, 'Mouse Middle' => 4,
        'Mouse 4' => 5, 'Mouse 5' => 6}
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 UP = [Key['Arrow Up']]
 LEFT = [Key['Arrow Left']]
 DOWN = [Key['Arrow Down']]
 RIGHT = [Key['Arrow Right']]
 A = [Key['Shift']]
 B = [Key['Esc'], Key['NumberPad 0'], Key['X']]
 C = [Key['Space'], Key['Enter'], Key['C']]
 X = [Key['A']]
 Y = [Key['S']]
 Z = [Key['D']]
 L = [Key['Q'], Key['Page Down']]
 R = [Key['W'], Key['Page Up']]
 F5 = [Key['F5']]
 F6 = [Key['F6']]
 F7 = [Key['F7']]
 F8 = [Key['F8']]
 F9 = [Key['F9']]
 SHIFT = [Key['Shift']]
 CTRL = [Key['Ctrl']]
 ALT = [Key['Alt']]
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 # All keys
 KEY_COUNT = 256
 ALL_KEYS = (0...KEY_COUNT).to_a
 # Win32 API calls
 GetKeyboardState = Win32API.new('user32', 'GetKeyboardState', 'P', 'I')
 GetKeyboardLayout = Win32API.new('user32', 'GetKeyboardLayout', 'L', 'L')
 MapVirtualKeyEx = Win32API.new('user32', 'MapVirtualKeyEx', 'IIL', 'I')
 ToUnicodeEx = Win32API.new('user32', 'ToUnicodeEx', 'LLPPILL', 'L')
 # some other constants
 DOWN_STATE_MASK = 0x80
 DEAD_KEY_MASK = 0x80000000
 # data
 @state = "\0" * KEY_COUNT
 @triggered = Array.new(KEY_COUNT, false)
 @pressed = Array.new(KEY_COUNT, false)
 @released = Array.new(KEY_COUNT, false)
 @repeatedKey = -1
 @repeatedCount = 0
 #----------------------------------------------------------------------------
 # update
 #  Updates input.
 #----------------------------------------------------------------------------
 def self.update
   # get current language layout
   @language_layout = GetKeyboardLayout.call(0)
   # get new keyboard state
   GetKeyboardState.call(@state)
   # this special code is used because Ruby 1.9.x does not return a char
   # when using String#[] but another String
   key = 0
   @state.each_byte {|byte|
       # if pressed state
       if (byte & DOWN_STATE_MASK) == DOWN_STATE_MASK
         # not released anymore
         @released[key] = false
         # if not pressed yet
         if !@pressed[key]
           # pressed and triggered
           @pressed[key] = true
           @triggered[key] = true
           @repeatedKey = key
           @repeatedCount = 0
         else
           # not triggered anymore
           @triggered[key] = false
         end
         # update of repeat counter
         if key == @repeatedKey
           @repeatedCount < 17 ? @repeatedCount += 1 : @repeatedCount = 15
         end
       # not released yet
       elsif !@released[key]
         # if still pressed
         if @pressed[key]
           # not triggered, pressed or repeated, but released
           @triggered[key] = false
           @pressed[key] = false
           @released[key] = true
           if key == @repeatedKey
             @repeatedKey = -1
             @repeatedCount = 0
           end
         end
       else
         # not released anymore
         @released[key] = false
       end
       key += 1}
 end
 #----------------------------------------------------------------------------
 # dir4
 #  4 direction check.
 #----------------------------------------------------------------------------
 def self.dir4
   return 2 if self.press?(DOWN)
   return 4 if self.press?(LEFT)
   return 6 if self.press?(RIGHT)
   return 8 if self.press?(UP)
   return 0
 end
 #----------------------------------------------------------------------------
 # dir8
 #  8 direction check.
 #----------------------------------------------------------------------------
 def self.dir8
   down = self.press?(DOWN)
   left = self.press?(LEFT)
   return 1 if down && left
   right = self.press?(RIGHT)
   return 3 if down && right
   up = self.press?(UP)
   return 7 if up && left
   return 9 if up && right
   return 2 if down
   return 4 if left
   return 6 if right
   return 8 if up
   return 0
 end
 #----------------------------------------------------------------------------
 # trigger?
 #  Test if key was triggered once.
 #----------------------------------------------------------------------------
 def self.trigger?(keys)
   keys = [keys] unless keys.is_a?(Array)
   return keys.any? {|key| @triggered[key]}
 end
 #----------------------------------------------------------------------------
 # press?
 #  Test if key is being pressed.
 #----------------------------------------------------------------------------
 def self.press?(keys)
   keys = [keys] unless keys.is_a?(Array)
   return keys.any? {|key| @pressed[key]}
 end
 #----------------------------------------------------------------------------
 # repeat?
 #  Test if key is being pressed for repeating.
 #----------------------------------------------------------------------------
 def self.repeat?(keys)
   keys = [keys] unless keys.is_a?(Array)
   return (@repeatedKey >= 0 && keys.include?(@repeatedKey) &&
       (@repeatedCount == 1 || @repeatedCount == 16))
 end
 #----------------------------------------------------------------------------
 # release?
 #  Test if key was released.
 #----------------------------------------------------------------------------
 def self.release?(keys)
   keys = [keys] unless keys.is_a?(Array)
   return keys.any? {|key| @released[key]}
 end
 #----------------------------------------------------------------------------
 # get_character
 #  vk - virtual key
 #  Gets the character from keyboard input using the input locale identifier
 #  (formerly called keyboard layout handles).
 #----------------------------------------------------------------------------
 def self.get_character(vk)
   # get corresponding character from virtual key
   c = MapVirtualKeyEx.call(vk, 2, @language_layout)
   # stop if character is non-printable and not a dead key
   return '' if c < 32 && (c & DEAD_KEY_MASK != DEAD_KEY_MASK)
   # get scan code
   vsc = MapVirtualKeyEx.call(vk, 0, @language_layout)
   # result string is never longer than 4 bytes (Unicode)
   result = "\0" * 4
   # get input string from Win32 API
   length = ToUnicodeEx.call(vk, vsc, @state, result, 4, 0, @language_layout)
   return (length == 0 ? '' : result)
 end
 #----------------------------------------------------------------------------
 # get_input_string
 #  Gets the string that was entered using the keyboard over the input locale
 #  identifier (formerly called keyboard layout handles).
 #----------------------------------------------------------------------------
 def self.get_input_string
   result = ''
   # check every key
   ALL_KEYS.each {|key|
       # if repeated
       if self.repeat?(key)
         # get character from keyboard state
         c = self.get_character(key)
         # add character if there is a character
         result += c if c != ''
       end}
   # empty if result is empty
   return '' if result == ''
   # convert string from Unicode to UTF-8
   return self.unicode_to_utf8(result)
 end
 #----------------------------------------------------------------------------
 # unicode_to_utf8
 #  string - string in Unicode format
 #  Converts a string from Unicode format to UTF-8 format as RGSS does not
 #  support Unicode.
 #----------------------------------------------------------------------------
 def self.unicode_to_utf8(string)
   result = ''
   # L* format means a bunch of 4-byte wide-chars
   string.unpack('L*').each {|c|
       # characters under 0x80 are 1 byte characters
       if c < 0x0080
         result += c.chr
       # other characters under 0x800 are 2 byte characters
       elsif c < 0x0800
         result += (0xC0 | (c >> 6)).chr
         result += (0x80 | (c & 0x3F)).chr
       # other characters under 0x10000 are 3 byte characters
       elsif c < 0x10000
         result += (0xE0 | (c >> 12)).chr
         result += (0x80 | ((c >> 6) & 0x3F)).chr
         result += (0x80 | (c & 0x3F)).chr
       # other characters under 0x200000 are 4 byte characters
       elsif c < 0x200000
         result += (0xF0 | (c >> 18)).chr
         result += (0x80 | ((c >> 12) & 0x3F)).chr
         result += (0x80 | ((c >> 6) & 0x3F)).chr
         result += (0x80 | (c & 0x3F)).chr
       # other characters under 0x4000000 are 5 byte characters
       elsif c < 0x4000000
         result += (0xF8 | (c >> 24)).chr
         result += (0x80 | ((c >> 18) & 0x3F)).chr
         result += (0x80 | ((c >> 12) & 0x3F)).chr
         result += (0x80 | ((c >> 6) & 0x3F)).chr
         result += (0x80 | (c & 0x3F)).chr
       # other characters under 0x80000000 are 6 byte characters
       elsif c < 0x80000000
         result += (0xFC | (c >> 30)).chr
         result += (0x80 | ((c >> 24) & 0x3F)).chr
         result += (0x80 | ((c >> 18) & 0x3F)).chr
         result += (0x80 | ((c >> 12) & 0x3F)).chr
         result += (0x80 | ((c >> 6) & 0x3F)).chr
         result += (0x80 | (c & 0x3F)).chr
       end}
   return result
 end

end

class Window_Text < Window_Base
 attr_accessor :multi_line, :text
 
 def initialize(*args)
   super(*args)
   self.contents = Bitmap.new(width - 32, height - 32)
   
   @dual_keys = ['`','1','2','3','4','5','6','7','8','9','0','A','B','C','D','E',
                 'F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U',
                 'V','W','X','Y','Z','-','=','[',']','\\',';','\'',',','.','/']
   @single_keys = ['NumberPad 0','NumberPad 1','NumberPad 2','NumberPad 3',
                   'NumberPad 4','NumberPad 5','NumberPad 6','NumberPad 7',
                   'NumberPad 8','NumberPad 9','Space','Tab']
   @multi_keys = ['Enter']
   @chars1 = ['`','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f',
              'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w',
              'x','y','z','-','=','[',']','/',';','\'',',','.','\\']
   @chars2 = ['~','!','@','#','$','%','^','&','*','(',')','A','B','C','D','E','F',
              'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W',
              'X','Y','Z','_','+','{','}','?',':','"','<','>','|']
   @chars = ['0','1','2','3','4','5','6','7','8','9',' ','\t']
   @multi_chars = ['\n']
   
   @multi_line = true
   @text = ""
   @cursor = true
 end
 
 def update
   @dual_keys.each_with_index { |i, ind|
     if Input.repeat?(Input::Key[i])
       @text += (Input.press?(Input::Key['Shift']) ? @chars2[ind] : @chars1[ind])
     end
   }
   @single_keys.each_with_index { |i, ind|
     if Input.repeat?(Input::Key[i])
       @text += @chars[ind]
     end
   }
   if @multi_line
     @multi_keys.each_with_index { |i, ind|
       if Input.repeat?(Input::Key[i])
         @text += @multi_chars[ind]
       end
     }
   end
   if Input.repeat?(Input::Key['Backspace'])
     @text = @text.split('')
     tmp = @text.pop()
     if (tmp == 'n' or tmp == 't') and @text[@text.length - 1] == '\\'
       @text.pop()
     end
     @text = @text.join('')
   end
   @cursor = !@cursor if Graphics.frame_count % 20 == 0
   refresh
 end
 
 def refresh
   self.contents.clear
   
   tmp = @text.gsub(/((?:\\n)+)\z/, '')
   y_mod = $1 ? $1.length / 2 : 0
   x_pos = y_mod > 0
   lns = tmp.gsub(/\\t/,'    ').split(/\\n/)
   y = 0
   x = 0
   lns.each_with_index { |ln, ind|
     rect = self.contents.text_size(ln)
     rect.height = self.contents.text_size('a').height
     rect.width += 1 unless ln.index(/[vVAwf\/\\]\z/).nil?
     rect.y = y
     self.contents.draw_text(rect, ln)
     y += rect.height
     x = rect.width
   }
   height = self.contents.text_size('a').height
   y -= height unless lns.last.nil?
   y += y_mod * height
   x = (x_pos ? 0 : x + 1)
   self.contents.fill_rect(Rect.new(x, y, 2, height), Color.new(0, 0, 0)) if @cursor
 end
end

module Zlib
 class Png_File < GzipWriter
   #--------------------------------------------------------------------------
   # ● 主处理
   #--------------------------------------------------------------------------
   def make_png(bitmap_Fx,mode)
     @mode = mode
     @bitmap_Fx = bitmap_Fx
     self.write(make_header)
     self.write(make_ihdr)
     self.write(make_idat)
     self.write(make_iend)
   end
   #--------------------------------------------------------------------------
   # ● PNG文件头数据块
   #--------------------------------------------------------------------------
   def make_header
     return [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a].pack("C*")
   end
   #--------------------------------------------------------------------------
   # ● PNG文件情报头数据块(IHDR)
   #--------------------------------------------------------------------------
   def make_ihdr
     ih_size = [13].pack("N")
     ih_sign = "IHDR"
     ih_width = [@bitmap_Fx.width].pack("N")
     ih_height = [@bitmap_Fx.height].pack("N")
     ih_bit_depth = [8].pack("C")
     ih_color_type = [6].pack("C")
     ih_compression_method = [0].pack("C")
     ih_filter_method = [0].pack("C")
     ih_interlace_method = [0].pack("C")
     string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type +
              ih_compression_method + ih_filter_method + ih_interlace_method
     ih_crc = [Zlib.crc32(string)].pack("N")
     return ih_size + string + ih_crc
   end
   #--------------------------------------------------------------------------
   # ● 生成图像数据(IDAT)
   #--------------------------------------------------------------------------
   def make_idat
     header = "\x49\x44\x41\x54"
     case @mode # 请54~
     when 1
       data = make_bitmap_data#1
     else
       data = make_bitmap_data
     end
     data = Zlib::Deflate.deflate(data, 8)
     crc = [Zlib.crc32(header + data)].pack("N")
     size = [data.length].pack("N")
     return size + header + data + crc
   end
   #--------------------------------------------------------------------------
   # ● 从Bitmap对象中生成图像数据 mode 1(请54~)
   #--------------------------------------------------------------------------
   def make_bitmap_data1
     w = @bitmap_Fx.width
     h = @bitmap_Fx.height
     data = []
     for y in 0...h
       data.push(0)
       for x in 0...w
         color = @bitmap_Fx.get_pixel(x, y)
         red = color.red
         green = color.green
         blue = color.blue
         alpha = color.alpha
         data.push(red)
         data.push(green)
         data.push(blue)
         data.push(alpha)
       end
     end
     return data.pack("C*")
   end
   #--------------------------------------------------------------------------
   # ● 从Bitmap对象中生成图像数据 mode 0
   #--------------------------------------------------------------------------
   def make_bitmap_data
     gz = Zlib::GzipWriter.open('hoge.gz')
     t_Fx = 0
     w = @bitmap_Fx.width
     h = @bitmap_Fx.height
     data = []
     for y in 0...h
       data.push(0)
       for x in 0...w
         t_Fx += 1
         if t_Fx % 10000 == 0
           Graphics.update
         end
         if t_Fx % 100000 == 0
           s = data.pack("C*")
           gz.write(s)
           data.clear
           #GC.start
         end
         color = @bitmap_Fx.get_pixel(x, y)
         red = color.red
         green = color.green
         blue = color.blue
         alpha = color.alpha
         data.push(red)
         data.push(green)
         data.push(blue)
         data.push(alpha)
       end
     end
     s = data.pack("C*")
     gz.write(s)
     gz.close    
     data.clear
     gz = Zlib::GzipReader.open('hoge.gz')
     data = gz.read
     gz.close
     File.delete('hoge.gz')
     return data
   end
   #--------------------------------------------------------------------------
   # ● PNG文件尾数据块(IEND)
   #--------------------------------------------------------------------------
   def make_iend
     ie_size = [0].pack("N")
     ie_sign = "IEND"
     ie_crc = [Zlib.crc32(ie_sign)].pack("N")
     return ie_size + ie_sign + ie_crc
   end
 end
end
#==============================================================================
# ■ Bitmap
#------------------------------------------------------------------------------
#  关联到Bitmap。
#==============================================================================
class Bitmap
 #--------------------------------------------------------------------------
 # ● 关联
 #--------------------------------------------------------------------------
 def make_png(name="like", path="",mode=0)
   make_dir(path) if path != ""
   Zlib::Png_File.open("temp.gz") {|gz|
     gz.make_png(self,mode)
   }
   Zlib::GzipReader.open("temp.gz") {|gz|
     $read = gz.read
   }
   name += ".png" if name.index(/.png\Z/).nil?
   f = File.open(path + name,"wb")
   f.write($read)
   f.close
   File.delete('temp.gz')
   end
 #--------------------------------------------------------------------------
 # ● 生成保存路径
 #--------------------------------------------------------------------------
 def make_dir(path)
   dir = path.split("/")
   for i in 0...dir.size
     unless dir == "."
       add_dir = dir[0..i].join("/")
       begin
         Dir.mkdir(add_dir)
       rescue
       end
     end
   end
 end
end



Instructions

Just put the windowskins you want users to be able to customize from in the windowskins folder. Press F7 to bring up the windowskin customization menu.


Compatibility

No issues known.


Credits and Thanks


  • ThallionDarkshine




Author's Notes

Also, you'll need this dll for the script to work.

G_G

You might want to try to include some sort of rescue call, not everybody will have RGSS104E. Some still have RGSS102E. Anyways, nice job on this. *moves to database*

ThallionDarkshine

Yeah, do you know if it's possible to read the game.ini file to find what dll to use?

G_G

    @ini = Win32API.new('kernel32', 'GetPrivateProfileStringA', 'PPPPLP', 'L')
    @library = "\0" * 256
    @ini.call('Game', 'Library', '', @library, 256, '.\\Game.ini')
    @library.delete!("\0")
    @rtp_path = Win32API.new(@library, 'RGSSGetRTPPath', 'L', 'L')
    @path_with_rtp = Win32API.new(@library, 'RGSSGetPathWithRTP', 'L', 'P')


Give credits to ForeverZer0, it's from his script. It reads the library from the ini, then creates the functions for receiving the RTPs.

ThallionDarkshine

I've been meaning to update this but I could never find the time. And at last, here's version 1.0. Users now have many options when they open the windowskin creator. They can mix-and-match parts of windowskins to create their own, recolor windowskin parts or the entire windowskin, customize font properties, or save or load any previous configuration. I also fixed a massive bug in the script that would cause errors upon saving the game.